module_traffic_light_manager.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #ifndef module_traffic_light_manager_h
  2. #define module_traffic_light_manager_h
  3. #include <thread>
  4. #include <functional>
  5. #include "module_traffic_light.h"
  6. #include "module_traffic_light_rule.h"
  7. #include "db_api/CDBCommon.h"
  8. #include "geo_hash.h"
  9. #include "log.h"
  10. #include "websocket/sio/sio_client.h"
  11. #include "tool_byte.h"
  12. #include "crc.h"
  13. #include "protocol.h"
  14. // 红绿灯管理
  15. struct traffic_light_manager{
  16. static traffic_light_manager* instance();
  17. // 从数据库加载数据
  18. void init_light_from_db(int lid = 0);
  19. void init_light_group_from_db(int gid = 0);
  20. void init_light_group_path();
  21. // 初始化回调信息
  22. void init(const int& lgc);
  23. // 开启
  24. void start();
  25. // 关闭
  26. void stop();
  27. // 运行
  28. void run();
  29. // 信息处理
  30. void put(const light_message& msg);
  31. // 重新加载红绿灯信息
  32. void handle_reload(const int& gid, const int& lid);
  33. int reload_light(const int& lid);
  34. int reload_group(const int& gid);
  35. // 手动控制红绿灯信息
  36. void manual_ctrl(sio::message::ptr const& data);
  37. void set_manual(light_message& msg);
  38. void cancel_manual(light_message& msg);
  39. void handle_manual(const int& gid, const int& ld, const std::string& name, const int& lc);
  40. // 卡数据
  41. void handle_position(pos_data& p);
  42. traffic_light_ptr get(const int& id)
  43. {
  44. return find_light(id);
  45. }
  46. //查找红绿灯
  47. traffic_light_ptr find_light(const int k)
  48. {
  49. hashmap_light::iterator it = m_unmap_lights.find(k);
  50. if(it != m_unmap_lights.end())
  51. {
  52. return it->second;
  53. }
  54. return nullptr;
  55. }
  56. // 查找红绿灯组
  57. traffic_light_group_ptr find_group(const int k)
  58. {
  59. hashmap_group::iterator it = m_unmap_groups.find(k);
  60. if(it != m_unmap_groups.end())
  61. {
  62. return it->second;
  63. }
  64. return nullptr;
  65. }
  66. std::vector<traffic_light_group_ptr> find_stream_groups(traffic_light_group_ptr, const move_stream& stream);
  67. // 更新红绿灯数据
  68. void update_light(const int& key, traffic_light_ptr ptl);
  69. // 更新红绿灯组数据
  70. void update_group(const int& key, traffic_light_group_ptr ptlg);
  71. // 查找附近的车
  72. std::vector<uint64_t> find_nearby_vehicle(const point& p,const int& dist, const uint64_t& card_id)
  73. {
  74. return m_geo_list.find_near(p.x, p.y, dist, card_id);
  75. }
  76. pos_data* get_position(const uint64_t& cid)
  77. {
  78. std::map<uint64_t, pos_data>::iterator it = m_map_card.find(cid);
  79. if(it == m_map_card.end())
  80. {
  81. log_error("[traffic_light] 找不到卡,card_id=%lld", cid);
  82. return nullptr;
  83. }
  84. return &(it->second);
  85. }
  86. void update(int x, int y, uint64_t cid)
  87. {
  88. m_geo_list.update(x, y, cid);
  89. }
  90. void vtlg_insert(const uint64_t& cid, traffic_light_group_ptr& group)
  91. {
  92. std::lock_guard<std::mutex> lg(m_vtlg_mutex);
  93. auto it = m_vehicle_traffic_groups.find(cid);
  94. if(it == m_vehicle_traffic_groups.end()){
  95. m_vehicle_traffic_groups.insert(std::make_pair(cid, std::list<traffic_light_group_ptr>()));
  96. it = m_vehicle_traffic_groups.find(cid);
  97. }
  98. if(it->second.size() >= m_light_group_ctrl_num){
  99. auto itg = it->second.front();
  100. itg->reset();
  101. it->second.pop_front();
  102. }
  103. it->second.push_back(group);
  104. }
  105. void vtlg_erase(const uint64_t& cid, traffic_light_group_ptr& group)
  106. {
  107. std::lock_guard<std::mutex> lg(m_vtlg_mutex);
  108. auto it = m_vehicle_traffic_groups.find(cid);
  109. if(it != m_vehicle_traffic_groups.end()){
  110. for(auto it_g = it->second.begin(); it_g != it->second.end();++it_g){
  111. if((*it_g)->m_group_id == group->m_group_id){
  112. group->reset();
  113. it->second.erase(it_g);
  114. break;
  115. }
  116. }
  117. }
  118. }
  119. bool vtlg_exist(const uint64_t& cid, const int& gid)
  120. {
  121. auto it = m_vehicle_traffic_groups.find(cid);
  122. if(it == m_vehicle_traffic_groups.end()){
  123. return false;
  124. }
  125. for(auto it_g = it->second.begin(); it_g != it->second.end();++it_g){
  126. if((*it_g)->m_group_id == gid){
  127. return true;
  128. }
  129. }
  130. return false;
  131. }
  132. bool vtlg_exist(const int& gid)
  133. {
  134. bool ret = false;
  135. for(auto it : m_vehicle_traffic_groups)
  136. {
  137. if(vtlg_exist(it.first, gid)){
  138. ret = true;
  139. break;
  140. }
  141. }
  142. return ret;
  143. }
  144. int vtlg_size(const uint64_t& cid)
  145. {
  146. auto it = m_vehicle_traffic_groups.find(cid);
  147. if(it == m_vehicle_traffic_groups.end()){
  148. return 0;
  149. }
  150. return it->second.size();
  151. }
  152. bool send_light_data(const int& light_id, const int& type, const int& shape){
  153. std::vector<char> msg;
  154. uint16_t cmd = THIRD_PARTY_CHAR_LIGHT_SETUP_STATE;
  155. tool_byte::memcpy_int<uint16_t>(msg, cmd);
  156. tool_byte::memcpy_int<uint32_t>(msg, light_id);
  157. msg.push_back(0x05);
  158. msg.push_back(static_cast<char>(shape));
  159. int16_t len = msg.size() + 2;
  160. int16_t crc = do_crc_1(msg, 0);
  161. auto it = msg.begin();
  162. msg.insert(it, len&0xff);
  163. it = msg.begin();
  164. msg.insert(it, (len>>8)&0xff);
  165. tool_byte::memcpy_int<int16_t>(msg, crc);
  166. auto light_ptr = get(light_id);
  167. 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");
  168. std::vector<char> m = msg;
  169. output_message(std::move(m), light_id);
  170. if(light_ptr && light_ptr->m_clt){
  171. light_ptr->m_clt->send(std::move(msg));
  172. }
  173. return true;
  174. }
  175. void output_message(std::vector<char>&& msg, int light_id)
  176. {
  177. std::string s("红绿灯控制的数据帧,灯号=");
  178. s.append(std::to_string(light_id));
  179. s.append(":");
  180. char a[4] = {0};
  181. for(std::vector<char>::size_type i = 0;i < msg.size(); ++i){
  182. sprintf(a, "%02X ", static_cast<unsigned char>(msg[i]));
  183. s.append(std::string(a));
  184. }
  185. log_info("%s", s.c_str());
  186. }
  187. void output_upstreamidx()
  188. {
  189. std::string msg = "红绿灯上行排序顺序(灯组id, 排序索引):";
  190. for(auto it : m_map_groups){
  191. char buf[20] = {0};
  192. sprintf(buf, "(%d,%d)", it.second->m_group_id, it.first);
  193. msg.append(std::string(buf));
  194. }
  195. log_info("%s", msg.c_str());
  196. }
  197. int remove_light(const int& id);
  198. int remove_light_group(const int& id);
  199. private:
  200. bool m_stop;
  201. unsigned int m_light_group_ctrl_num{0}; // 控制红绿灯组数
  202. std::list<light_message> m_list_data;
  203. std::mutex m_mutex;
  204. std::mutex m_vtlg_mutex;
  205. std::condition_variable m_condition;
  206. std::unique_ptr<std::thread> m_thread_light;
  207. std::unique_ptr<crossing_rule> m_crossing_rule; // 路口规则
  208. std::unique_ptr<avoidance_rule> m_avoidance_rule; // 避让规则
  209. geo_list m_geo_list;
  210. hashmap_light m_unmap_lights;
  211. hashmap_group m_unmap_groups;
  212. map_group m_map_groups;
  213. std::map<uint64_t, pos_data> m_map_card;
  214. std::map<uint64_t, std::list<traffic_light_group_ptr>> m_vehicle_traffic_groups;
  215. };
  216. #endif