module_traffic_light_manager.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include "module_traffic_light_manager.h"
  2. #include "db_api/CDBSingletonDefine.h"
  3. #include <db_api/CDBResultSet.h>
  4. traffic_light_manager* traffic_light_manager::instance()
  5. {
  6. static traffic_light_manager tlm;
  7. return &tlm;
  8. }
  9. void traffic_light_manager::init_light_from_db(int lid)
  10. {
  11. std::string sql = "select light_id, lights_group_id, ip, x, y ,z, reader_id, state, port, physics_light_id, physics_light_direction, special_flag from dat_light";
  12. if(0 == lid){
  13. sql += ";";
  14. }else{
  15. sql += " where light_id = " + std::to_string(lid);
  16. sql += ";";
  17. }
  18. std::string err = "";
  19. YADB::CDBResultSet res;
  20. sDBConnPool.Query(sql.c_str(), res, err);
  21. int count = res.GetRecordCount(err);
  22. if(count < 1){
  23. log_error("增加或修改失败,error:%s", sql.c_str());
  24. return;
  25. }
  26. while(res.GetNextRecod(err)){
  27. int light_id = 0;
  28. res.GetField("light_id", light_id, err);
  29. int group_id = 0;
  30. res.GetField("lights_group_id", group_id, err);
  31. std::string ip = "";
  32. res.GetField("ip", ip, err);
  33. double x = 0.0, y = 0.0, z = 0.0;
  34. res.GetField("x", x, err);
  35. res.GetField("y", y, err);
  36. res.GetField("z", z, err);
  37. int site_id = 0, state = 0, port = 0, phy_light_id = 0, phy_direction = 0, special = 0;
  38. res.GetField("reader_id", site_id, err);
  39. res.GetField("state", state, err);
  40. res.GetField("port", port, err);
  41. res.GetField("physics_light_id", phy_light_id, err);
  42. res.GetField("physics_light_direction", phy_direction, err);
  43. res.GetField("special_flag", special, err);
  44. traffic_light_ptr pl = find_light(light_id);
  45. if(nullptr == pl){
  46. pl = std::make_shared<traffic_light>(x, y, z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special);
  47. m_unmap_lights.insert(std::make_pair(light_id, pl));
  48. }else{
  49. pl->update(x, y , z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special);
  50. }
  51. // 将红绿灯分配到对应组中
  52. auto it_group = m_unmap_groups.find(pl->m_group_id);
  53. if(it_group != m_unmap_groups.end())
  54. {
  55. it_group->second->m_vt_lights.push_back(pl);
  56. }
  57. }
  58. logn_info(2, "sql:%s",sql.c_str());
  59. }
  60. void traffic_light_manager::init_light_group_from_db(int gid)
  61. {
  62. std::string sql = "select lights_group_id, x, y, z, scope, map_id, area_id, manual_control_time, light_auto_interval from dat_lights_group";
  63. if(gid > 0){
  64. sql += " where lights_group_id = " + std::to_string(gid);
  65. }
  66. sql += ";";
  67. std::string err = "";
  68. YADB::CDBResultSet res;
  69. sDBConnPool.Query(sql.c_str(), res, err);
  70. int count = res.GetRecordCount(err);
  71. if(count < 1){
  72. log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
  73. return;
  74. }
  75. while(res.GetNextRecod(err)){
  76. int group_id = 0;
  77. res.GetField("lights_group_id", group_id, err);
  78. double x = 0.0, y = 0.0, z = 0.0, scope = 0.0;
  79. res.GetField("x", x, err);
  80. res.GetField("y", y, err);
  81. res.GetField("z", z, err);
  82. res.GetField("scope", scope, err);
  83. int map_id = 0, area_id = 0;
  84. res.GetField("map_id", map_id, err);
  85. res.GetField("area_id", area_id, err);
  86. int ai = 0;
  87. res.GetField("light_auto_interval", ai, err);
  88. traffic_light_group_ptr pg = find_group(group_id);
  89. if(nullptr == pg){
  90. pg = std::make_shared<traffic_light_group>(x, y, z, group_id, scope, ai, map_id, area_id);
  91. m_unmap_groups.insert(std::make_pair(group_id, pg));
  92. }else{
  93. pg->update(x, y, z, group_id, scope, ai, map_id, area_id);
  94. }
  95. }
  96. logn_info(2, "sql:%s",sql.c_str());
  97. }
  98. void traffic_light_manager::init(const traffic_send_callback& tcb)
  99. {
  100. // 1.先获得红绿灯组数据
  101. init_light_group_from_db();
  102. // 2.再获得红绿灯数据
  103. init_light_from_db();
  104. for(hashmap_light::iterator it_light = m_unmap_lights.begin(); it_light != m_unmap_lights.end(); ++it_light){
  105. if(it_light->second->m_group_id >0){
  106. hashmap_group::iterator it_group = m_unmap_groups.find(it_light->second->m_group_id);
  107. if(it_group != m_unmap_groups.end()){
  108. it_group->second->insert(it_light->second);
  109. }
  110. }
  111. }
  112. set_send_callback(tcb);
  113. }
  114. void traffic_light_manager::start()
  115. {
  116. log_info("[traffic_light] start traffic light service, light_group's size=%d", m_unmap_groups.size());
  117. m_stop = false;
  118. m_crossing_rule = std::unique_ptr<crossing_rule>(new crossing_rule);
  119. if(nullptr == m_crossing_rule){
  120. log_info("[traffic_light] create crossing rule failed");
  121. return;
  122. }else{
  123. for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
  124. {
  125. m_crossing_rule->put(it->second);
  126. }
  127. }
  128. m_avoidance_rule = std::unique_ptr<avoidance_rule>(new avoidance_rule);
  129. if(nullptr == m_avoidance_rule){
  130. log_info("[traffic_light] create avoidance rule failed");
  131. return;
  132. }else{
  133. for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
  134. {
  135. log_info("[traffic_light] insert light group into area, area_id=%d", it->second->m_area_id);
  136. m_avoidance_rule->put(it->second);
  137. }
  138. }
  139. log_info("[traffic_light] rule's map size, crossing=%d, avoidance=%d", m_crossing_rule->size(), m_avoidance_rule->size());
  140. m_thread_light.reset(new std::thread(std::bind(&traffic_light_manager::run, this)));
  141. }
  142. void traffic_light_manager::stop()
  143. {
  144. log_info("[traffic_light] stop traffic light service");
  145. m_stop = true;
  146. m_thread_light->join();
  147. }
  148. void traffic_light_manager::put(const light_message& msg)
  149. {
  150. std::unique_lock<std::mutex> lock(m_mutex);
  151. m_list_data.push_back(msg);
  152. lock.unlock();
  153. m_condition.notify_all();
  154. }
  155. void traffic_light_manager::run()
  156. {
  157. while(!m_stop){
  158. std::list<light_message> tmp_data;
  159. tmp_data.clear();
  160. //log_info("[traffic_light] working... m_stop=%d", m_stop);
  161. {
  162. std::unique_lock<std::mutex> lock(m_mutex);
  163. while(m_list_data.empty()){
  164. m_condition.wait(lock);
  165. }
  166. if(m_list_data.size() > 0){
  167. m_list_data.swap(tmp_data);
  168. }
  169. lock.unlock();
  170. }
  171. for(std::list<light_message>::iterator it = tmp_data.begin(); it != tmp_data.end(); ++it){
  172. switch(it->m_cmd){
  173. case cmd_reload:
  174. log_info("[traffic_light] cmd=%d, gid=%d, lid=%d",it->m_cmd, it->m_group_id, it->m_light_id);
  175. handle_reload(it->m_group_id, it->m_light_id);
  176. break;
  177. case cmd_manual_ctrl:
  178. log_info("[traffic_light] cmd=%d, gid=%d, lid=%d, name=%s, lc=%d", it->m_cmd, it->m_group_id, it->m_light_id, it->m_ctrl_name.c_str(), it->m_light_status);
  179. handle_manual(it->m_group_id,it->m_light_id, it->m_ctrl_name, it->m_light_status);
  180. break;
  181. case cmd_card_data:
  182. log_info("[traffic_light] cmd=%d, cid=%d, ctype=%d, bigger=%d, aid=%d, speed=%.2f", it->m_cmd, it->m_pos.m_card_id, it->m_pos.m_type, it->m_pos.m_bigger, it->m_pos.m_area_id, it->m_pos.m_speed);
  183. handle_position(it->m_pos);
  184. break;
  185. default:
  186. log_warn("[traffic_light] message cmd error, cmd=%d", it->m_cmd);
  187. break;
  188. }
  189. }
  190. //log_info("[traffic_light] working thread one loop, m_stop=%d", m_stop);
  191. }
  192. log_info("[traffic_light] working thread is exit. m_stop=%d", m_stop);
  193. }
  194. void traffic_light_manager::handle_reload(const int& gid, const int& lid)
  195. {
  196. if(lid > 0){
  197. init_light_from_db(lid);
  198. }
  199. if(gid > 0){
  200. init_light_group_from_db(gid);
  201. }
  202. }
  203. int traffic_light_manager::reload_light(const int& lid)
  204. {
  205. init_light_from_db(lid);
  206. return 0;
  207. }
  208. int traffic_light_manager::reload_group(const int& gid)
  209. {
  210. init_light_group_from_db(gid);
  211. return 0;
  212. }
  213. void traffic_light_manager::handle_manual(const int& gid, const int& ld, const std::string& name, const int& lc)
  214. {
  215. traffic_light_group_ptr pg = find_group(gid);
  216. if(nullptr != pg){
  217. pg->set_manual_ctrl(name, ld, lc);
  218. }
  219. }
  220. void traffic_light_manager::handle_position(pos_data& p)
  221. {
  222. if(p.m_type == 3 || p.m_type == 1){
  223. std::map<uint64_t, pos_data>::iterator it = m_map_card.find(p.m_card_id);
  224. if(it != m_map_card.end()){
  225. m_map_card.erase(it);
  226. }
  227. }else if(p.m_type == 2){
  228. //log_info("[traffic_light] call handle rule");
  229. update(p.x, p.y, p.m_card_id);
  230. m_map_card[p.m_card_id] = p;
  231. // 路口规则
  232. if(nullptr != m_crossing_rule){
  233. // maybe error
  234. //m_crossing_rule->handle_rule(p);
  235. }
  236. if(!p.m_bigger && nullptr != m_avoidance_rule){
  237. m_avoidance_rule->handle_rule(p);
  238. }
  239. }
  240. }