123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- #ifndef module_traffic_light_manager_h
- #define module_traffic_light_manager_h
- #include <thread>
- #include <functional>
- #include "module_traffic_light.h"
- #include "module_traffic_light_rule.h"
- #include "db_api/CDBCommon.h"
- #include "geo_hash.h"
- #include "log.h"
- #include "websocket/sio/sio_client.h"
- #include "common_tool.h"
- #include "crc.h"
- #include "protocol.h"
- #include "websocket/wsTimerThread.h"
- // 红绿灯管理
- struct traffic_light_manager{
- private:
- ~traffic_light_manager()
- {
- stop();
- }
- public:
- static traffic_light_manager* instance();
- // 从数据库加载数据
- void init_light_from_db(int lid = 0);
- void init_light_group_from_db(int gid = 0);
- void init_light_group_path();
- void init_map(int id = 0);
- // 初始化回调信息
- void init(const int& lgc);
- // 开启
- void start();
- // 关闭
- void stop();
- // 运行
- void run();
- // 信息处理
- void put(const light_message& msg);
- // 重新加载红绿灯信息
- void handle_reload(const int& gid, const int& lid);
- int reload_light(const int& lid);
- int reload_group(const int& gid);
- // 手动控制红绿灯信息
- void manual_ctrl(sio::message::ptr const& data);
- void set_manual(light_message& msg);
- void cancel_manual(light_message& msg);
- void handle_manual(const int& gid, const int& ld, const std::string& name, const int& lc);
- // 卡数据
- void handle_position(pos_data& p);
- traffic_light_ptr get(const int& id)
- {
- return find_light(id);
- }
- //查找红绿灯
- traffic_light_ptr find_light(const int k)
- {
- hashmap_light::iterator it = m_unmap_lights.find(k);
- if(it != m_unmap_lights.end())
- {
- return it->second;
- }
-
- return nullptr;
- }
- // 查找红绿灯组
- traffic_light_group_ptr find_group(const int k)
- {
- hashmap_group::iterator it = m_unmap_groups.find(k);
- if(it != m_unmap_groups.end())
- {
- return it->second;
- }
- return nullptr;
- }
- std::vector<traffic_light_group_ptr> find_stream_groups(traffic_light_group_ptr, const move_stream& stream);
- // 更新红绿灯数据
- void update_light(const int& key, traffic_light_ptr ptl);
- // 更新红绿灯组数据
- void update_group(const int& key, traffic_light_group_ptr ptlg);
- // 查找附近的车
- std::vector<uint64_t> find_nearby_vehicle(const point& p,const int& dist, const uint64_t& card_id)
- {
- return m_geo_list.find_near(p.x, p.y, dist, card_id);
- }
- pos_data* get_position(const uint64_t& cid)
- {
- std::map<uint64_t, pos_data>::iterator it = m_map_card.find(cid);
- if(it == m_map_card.end())
- {
- log_error("[traffic_light] 找不到卡,card_id=%lld", cid);
- return nullptr;
- }
- return &(it->second);
- }
- void update(int x, int y, uint64_t cid)
- {
- m_geo_list.update(x, y, cid);
- }
- void vtlg_insert(const uint64_t& cid, traffic_light_group_ptr& group)
- {
- std::lock_guard<std::mutex> lg(m_vtlg_mutex);
- auto it = m_vehicle_traffic_groups.find(cid);
- if(it == m_vehicle_traffic_groups.end()){
- m_vehicle_traffic_groups.insert(std::make_pair(cid, std::list<traffic_light_group_ptr>()));
- it = m_vehicle_traffic_groups.find(cid);
- }
- if(it->second.size() >= m_light_group_ctrl_num){
- auto itg = it->second.front();
- itg->reset();
- it->second.pop_front();
- }
- it->second.push_back(group);
- }
- void vtlg_erase(const uint64_t& cid, traffic_light_group_ptr& group)
- {
- std::lock_guard<std::mutex> lg(m_vtlg_mutex);
- auto it = m_vehicle_traffic_groups.find(cid);
- if(it != m_vehicle_traffic_groups.end()){
- for(auto it_g = it->second.begin(); it_g != it->second.end();++it_g){
- if((*it_g)->m_group_id == group->m_group_id){
- group->reset();
- it->second.erase(it_g);
- break;
- }
- }
- }
- }
- bool vtlg_exist(const uint64_t& cid, const int& gid)
- {
- auto it = m_vehicle_traffic_groups.find(cid);
- if(it == m_vehicle_traffic_groups.end()){
- return false;
- }
- for(auto it_g = it->second.begin(); it_g != it->second.end();++it_g){
- if((*it_g)->m_group_id == gid){
- return true;
- }
- }
- return false;
- }
- bool vtlg_exist(const int& gid)
- {
- bool ret = false;
- for(auto it : m_vehicle_traffic_groups)
- {
- if(vtlg_exist(it.first, gid)){
- ret = true;
- break;
- }
- }
- return ret;
- }
- int vtlg_size(const uint64_t& cid)
- {
- auto it = m_vehicle_traffic_groups.find(cid);
- if(it == m_vehicle_traffic_groups.end()){
- return 0;
- }
- return it->second.size();
- }
- bool send_light_data(const int& light_id, const int& dev_type, const int& shape, const int cmd_type = 0){
- std::vector<char> msg;
- uint16_t cmd = THIRD_PARTY_CHAR_LIGHT_SETUP_STATE;
- if(1 == cmd_type){
- cmd = THIRD_PARTY_CHAR_LIGHT_REQ_STATE;
- }
- tool_other::memcpy_int<uint16_t>(msg, cmd);
- tool_other::memcpy_int<uint32_t>(msg, light_id);
- // 设备类型
- msg.push_back(dev_type);
- msg.push_back(static_cast<char>(shape));
- int16_t len = msg.size() + 2;
- int16_t crc = do_crc_1(msg, 0);
- auto it = msg.begin();
- msg.insert(it, len&0xff);
- it = msg.begin();
- msg.insert(it, (len>>8)&0xff);
- tool_other::memcpy_int<int16_t>(msg, crc);
- auto light_ptr = get(light_id);
- log_info("[light_info] ctrl light, light_id=%d, message's length=%d, light_ptr exist=%s", light_id, msg.size(), (light_ptr==nullptr)?"empty":"yes");
- std::vector<char> m = msg;
- output_message(std::move(m), light_id);
- if(light_ptr && light_ptr->m_clt){
- light_ptr->m_clt->send(std::move(msg));
- }
- return true;
- }
- /*
- * @brief 采集收到红绿灯心跳数据,将心跳数据发送给红绿灯设备
- *
- * @param
- * const char* data 发送给红绿灯设备的心跳数据
- * const int len 心跳数据长度
- * const int light_id 红绿灯灯号
- *
- * @return
- * false 发送失败
- * true 发送成功
- * @note
- * @warning
- * @bug
- * */
- bool send_heart_data(const char* data, const int len, const int light_id)
- {
- auto light_ptr = get(light_id);
- if(light_ptr == nullptr){
- log_error("[light_info] 未找到%d红绿灯", light_id);
- return false;
- }
- std::vector<char> m;
- for(int i = 0;i < len; i++){
- m.push_back(data[i]);
- }
- //m.insert(m.begin(), std::begin(data), std::end(data));
- if(light_ptr->m_clt){
- std::vector<char> md = m;
- output_message(std::move(md), light_id);
- light_ptr->m_clt->send(std::move(m));
- }
- return true;
- }
- /*
- * @brief
- * 输出红绿灯的16进制数据
- * @param
- * std::vector<char>&& msg 红绿灯数据
- * int light_id 灯号
- * @return
- * 无
- * @note
- * @warning
- * @bug
- * */
- void output_message(std::vector<char>&& msg, int light_id)
- {
- std::string s("红绿灯控制的数据帧,灯号=");
- s.append(std::to_string(light_id));
- s.append(":");
- char a[4] = {0};
- for(std::vector<char>::size_type i = 0;i < msg.size(); ++i){
- sprintf(a, "%02X ", static_cast<unsigned char>(msg[i]));
- s.append(std::string(a));
- }
- log_info("%s", s.c_str());
- }
- void output_upstreamidx()
- {
- std::string msg = "红绿灯上行排序顺序(灯组id, 排序索引):";
- for(auto it : m_map_groups){
- char buf[20] = {0};
- sprintf(buf, "(%d,%d)", it.second->m_group_id, it.first);
- msg.append(std::string(buf));
- }
- log_info("%s", msg.c_str());
- }
- int remove_light(const int& id);
- int remove_light_group(const int& id);
- void set_scale(const double& scale)
- {
- m_map_scale = scale;
- }
- double get_scale()
- {
- return m_map_scale;
- }
- std::string get_light_state();
- bool on_path(const std::vector<pos_data>& vtp, const point& p);
- void visit_light_status();
- private:
- bool m_stop;
- double m_map_scale = 0.0;
- unsigned int m_light_group_ctrl_num{0}; // 控制红绿灯组数
- std::list<light_message> m_list_data;
- std::mutex m_mutex;
- std::mutex m_vtlg_mutex;
- std::condition_variable m_condition;
- std::unique_ptr<std::thread> m_thread_light;
- std::unique_ptr<crossing_rule> m_crossing_rule; // 路口规则
- std::unique_ptr<avoidance_rule> m_avoidance_rule; // 避让规则
- geo_list m_geo_list;
- hashmap_light m_unmap_lights;
- hashmap_group m_unmap_groups;
- map_group m_map_groups;
- std::map<uint64_t, pos_data> m_map_card;
- std::map<int, std::vector<line_v>> m_map_path;
- std::map<uint64_t, std::list<traffic_light_group_ptr>> m_vehicle_traffic_groups;
- sys::jsonBuilder m_jsBuilder;//json构造器类
- };
- #endif
|