#ifndef module_traffic_light_manager_h #define module_traffic_light_manager_h #include #include #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 "tool_byte.h" #include "crc.h" #include "protocol.h" // 红绿灯管理 struct traffic_light_manager{ 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(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 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 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::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 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())); 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 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& type, const int& shape){ std::vector msg; uint16_t cmd = THIRD_PARTY_CHAR_LIGHT_SETUP_STATE; tool_byte::memcpy_int(msg, cmd); tool_byte::memcpy_int(msg, light_id); msg.push_back(0x05); msg.push_back(static_cast(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_byte::memcpy_int(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 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; } void output_message(std::vector&& msg, int light_id) { std::string s("红绿灯控制的数据帧,灯号="); s.append(std::to_string(light_id)); s.append(":"); char a[4] = {0}; for(std::vector::size_type i = 0;i < msg.size(); ++i){ sprintf(a, "%02X ", static_cast(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); private: bool m_stop; unsigned int m_light_group_ctrl_num{0}; // 控制红绿灯组数 std::list m_list_data; std::mutex m_mutex; std::mutex m_vtlg_mutex; std::condition_variable m_condition; std::unique_ptr m_thread_light; std::unique_ptr m_crossing_rule; // 路口规则 std::unique_ptr 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 m_map_card; std::map> m_vehicle_traffic_groups; }; #endif