module_traffic_light_manager.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. #include "module_traffic_light_manager.h"
  2. #include "db_api/CDBSingletonDefine.h"
  3. #include <db_api/CDBResultSet.h>
  4. #include "websocket/constdef.h"
  5. #include "websocket/wsTimerThread.h"
  6. traffic_light_manager* traffic_light_manager::instance()
  7. {
  8. static traffic_light_manager tlm;
  9. return &tlm;
  10. }
  11. /*
  12. * 加载红绿灯基础信息
  13. * */
  14. void traffic_light_manager::init_light_from_db(int lid)
  15. {
  16. 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, stream_state from dat_light";
  17. if(0 == lid){
  18. sql += ";";
  19. }else{
  20. sql += " where light_id = " + std::to_string(lid);
  21. sql += ";";
  22. }
  23. std::string err = "";
  24. YADB::CDBResultSet res;
  25. sDBConnPool.Query(sql.c_str(), res, err);
  26. int count = res.GetRecordCount(err);
  27. if(count < 1){
  28. log_error("增加或修改失败,error:%s", sql.c_str());
  29. return;
  30. }
  31. while(res.GetNextRecod(err)){
  32. int light_id = 0;
  33. res.GetField("light_id", light_id, err);
  34. int group_id = 0;
  35. res.GetField("lights_group_id", group_id, err);
  36. std::string ip = "";
  37. res.GetField("ip", ip, err);
  38. double x = 0.0, y = 0.0, z = 0.0;
  39. res.GetField("x", x, err);
  40. res.GetField("y", y, err);
  41. res.GetField("z", z, err);
  42. int site_id = 0, state = 0, port = 0, phy_light_id = 0, phy_direction = 0, special = 0, stream = 0;
  43. res.GetField("reader_id", site_id, err);
  44. res.GetField("state", state, err);
  45. res.GetField("port", port, err);
  46. res.GetField("physics_light_id", phy_light_id, err);
  47. res.GetField("physics_light_direction", phy_direction, err);
  48. res.GetField("special_flag", special, err);
  49. res.GetField("stream_state", stream, err);
  50. traffic_light_ptr pl = find_light(light_id);
  51. if(nullptr == pl){
  52. pl = std::make_shared<traffic_light>(x, y, z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
  53. m_unmap_lights.insert(std::make_pair(light_id, pl));
  54. }else{
  55. pl->update(x, y , z, light_id, group_id, ip, state, port, phy_light_id, phy_direction, special, stream);
  56. }
  57. // 将红绿灯分配到对应组中
  58. auto it_group = m_unmap_groups.find(pl->m_group_id);
  59. if(it_group != m_unmap_groups.end())
  60. {
  61. it_group->second->m_vt_lights.push_back(pl);
  62. }
  63. }
  64. logn_info(2, "sql:%s",sql.c_str());
  65. }
  66. /*
  67. * 加载红绿灯组基础信息
  68. * */
  69. void traffic_light_manager::init_light_group_from_db(int gid)
  70. {
  71. std::string sql = "select lights_group_id, x, y, z, scope, map_id, area_id, manual_control_time, light_auto_interval, up_stream_idx from dat_lights_group";
  72. if(gid > 0){
  73. sql += " where lights_group_id = " + std::to_string(gid);
  74. }
  75. sql += ";";
  76. std::string err = "";
  77. YADB::CDBResultSet res;
  78. sDBConnPool.Query(sql.c_str(), res, err);
  79. int count = res.GetRecordCount(err);
  80. if(count < 1){
  81. log_error("增加或修改失败,数据库中找不到:sql=%s", sql.c_str());
  82. return;
  83. }
  84. while(res.GetNextRecod(err)){
  85. int group_id = 0;
  86. res.GetField("lights_group_id", group_id, err);
  87. double x = 0.0, y = 0.0, z = 0.0, scope = 0.0;
  88. res.GetField("x", x, err);
  89. res.GetField("y", y, err);
  90. res.GetField("z", z, err);
  91. res.GetField("scope", scope, err);
  92. int map_id = 0, area_id = 0;
  93. res.GetField("map_id", map_id, err);
  94. res.GetField("area_id", area_id, err);
  95. int ai = 0;
  96. res.GetField("light_auto_interval", ai, err);
  97. int usi = 0;
  98. res.GetField("up_stream_idx", usi, err);
  99. traffic_light_group_ptr pg = find_group(group_id);
  100. if(nullptr == pg){
  101. pg = std::make_shared<traffic_light_group>(x, y, z, group_id, scope, ai, map_id, area_id);
  102. m_unmap_groups.insert(std::make_pair(group_id, pg));
  103. }else{
  104. pg->update(x, y, z, group_id, scope, ai, map_id, area_id);
  105. }
  106. pg->set_up_stream_idx(usi);
  107. auto ppg = m_map_groups.find(usi);
  108. if(ppg == m_map_groups.end()){
  109. m_map_groups.insert(std::make_pair(usi, pg));
  110. }
  111. }
  112. logn_info(2, "sql:%s",sql.c_str());
  113. output_upstreamidx();
  114. }
  115. void traffic_light_manager::init_light_group_path()
  116. {
  117. std::string sql = "select reader_id, tof_flag, b_x, b_y, b_z, e_x, e_y, e_z, spacing_ratio from dat_reader_path_tof_n;";
  118. std::map<int, std::vector<line_v>> map_path;
  119. std::string error;
  120. YADB::CDBResultSet res;
  121. sDBConnPool.Query(sql.c_str(), res, error);
  122. int count = res.GetRecordCount(error);
  123. log_info("init_light_group_path, the record count=%d\n", count);
  124. while(res.GetNextRecod(error)){
  125. int reader_id = 0;
  126. res.GetField("reader_id", reader_id, error);
  127. int pid=0;
  128. res.GetField("tof_flag", pid, error);
  129. double b_x = 0;
  130. res.GetField("b_x", b_x, error);
  131. double b_y = 0;
  132. res.GetField("b_y", b_y, error);
  133. double b_z = 0;
  134. res.GetField("b_z", b_z, error);
  135. double e_x = 0;
  136. res.GetField("e_x", e_x, error);
  137. double e_y = 0;
  138. res.GetField("e_y", e_y, error);
  139. double e_z = 0;
  140. res.GetField("e_z", e_z, error);
  141. double spacing_ratio = 0;
  142. res.GetField("spacing_ratio", spacing_ratio, error);
  143. log_info("[traffic_light] src-path: site=%d, x0=%.2f, y0=%.2f, x1=%.2f, y1=%.2f", reader_id, b_x, b_y, e_x, e_y);
  144. point p1(b_x, -b_y, spacing_ratio);
  145. point p2(e_x, -e_y, spacing_ratio);
  146. map_path.insert(std::make_pair(reader_id, std::vector<line_v>()));
  147. map_path.find(reader_id)->second.push_back(line_v(p1, p2));
  148. }
  149. for(auto itg : m_unmap_groups){
  150. for(auto itp : map_path){
  151. bool tag = false;
  152. for(size_t i = 0;i < itp.second.size();i++){
  153. if(itp.second[i].contain(point(itg.second->x, itg.second->y),1)){
  154. tag = true;
  155. }
  156. }
  157. if(tag){
  158. itg.second->set_path(itp.second);
  159. }
  160. }
  161. }
  162. }
  163. void traffic_light_manager::init(const int& lgc)
  164. {
  165. // 1.先获得红绿灯组数据
  166. init_light_group_from_db();
  167. init_light_group_path();
  168. // 2.再获得红绿灯数据
  169. init_light_from_db();
  170. for(hashmap_light::iterator it_light = m_unmap_lights.begin(); it_light != m_unmap_lights.end(); ++it_light){
  171. if(it_light->second->m_group_id >0){
  172. hashmap_group::iterator it_group = m_unmap_groups.find(it_light->second->m_group_id);
  173. if(it_group != m_unmap_groups.end()){
  174. it_group->second->insert(it_light->second);
  175. }
  176. }
  177. }
  178. for(auto it : m_unmap_groups){
  179. log_info("[traffic_light] gid=%d, size=%d", it.first, it.second->m_vt_lights.size());
  180. }
  181. m_light_group_ctrl_num = lgc;
  182. }
  183. void traffic_light_manager::start()
  184. {
  185. log_info("[traffic_light] start traffic light service, light_group's size=%d", m_unmap_groups.size());
  186. m_stop = false;
  187. m_crossing_rule = std::unique_ptr<crossing_rule>(new crossing_rule);
  188. if(nullptr == m_crossing_rule){
  189. log_info("[traffic_light] create crossing rule failed");
  190. return;
  191. }else{
  192. for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
  193. {
  194. m_crossing_rule->put(it->second);
  195. }
  196. }
  197. m_avoidance_rule = std::unique_ptr<avoidance_rule>(new avoidance_rule);
  198. if(nullptr == m_avoidance_rule){
  199. log_info("[traffic_light] create avoidance rule failed");
  200. return;
  201. }else{
  202. for(auto it = m_unmap_groups.begin(); it != m_unmap_groups.end(); ++it)
  203. {
  204. log_info("[traffic_light] insert light group into area, area_id=%d", it->second->m_area_id);
  205. m_avoidance_rule->put(it->second);
  206. }
  207. }
  208. log_info("[traffic_light] rule's map size, crossing=%d, avoidance=%d", m_crossing_rule->size(), m_avoidance_rule->size());
  209. m_thread_light.reset(new std::thread(std::bind(&traffic_light_manager::run, this)));
  210. }
  211. void traffic_light_manager::stop()
  212. {
  213. log_info("[traffic_light] stop traffic light service");
  214. m_stop = true;
  215. m_thread_light->join();
  216. }
  217. void traffic_light_manager::put(const light_message& msg)
  218. {
  219. std::unique_lock<std::mutex> lock(m_mutex);
  220. m_list_data.push_back(msg);
  221. lock.unlock();
  222. m_condition.notify_all();
  223. }
  224. void traffic_light_manager::run()
  225. {
  226. while(!m_stop){
  227. std::list<light_message> tmp_data;
  228. tmp_data.clear();
  229. {
  230. std::unique_lock<std::mutex> lock(m_mutex);
  231. while(m_list_data.empty()){
  232. m_condition.wait(lock);
  233. }
  234. if(m_list_data.size() > 0){
  235. m_list_data.swap(tmp_data);
  236. }
  237. lock.unlock();
  238. }
  239. for(std::list<light_message>::iterator it = tmp_data.begin(); it != tmp_data.end(); ++it){
  240. switch(it->m_cmd){
  241. case cmd_reload:
  242. log_info("[traffic_light] cmd=%d, gid=%d, lid=%d",it->m_cmd, it->m_group_id, it->m_light_id);
  243. handle_reload(it->m_group_id, it->m_light_id);
  244. break;
  245. case cmd_manual_ctrl:
  246. 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_state);
  247. handle_manual(it->m_group_id,it->m_light_id, it->m_ctrl_name, it->m_light_state);
  248. break;
  249. case cmd_card_data:
  250. 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);
  251. handle_position(it->m_pos);
  252. break;
  253. default:
  254. log_warn("[traffic_light] message cmd error, cmd=%d", it->m_cmd);
  255. break;
  256. }
  257. }
  258. }
  259. log_info("[traffic_light] working thread is exit. m_stop=%d", m_stop);
  260. }
  261. // 红绿灯及灯组基础数据更新
  262. void traffic_light_manager::handle_reload(const int& gid, const int& lid)
  263. {
  264. if(lid > 0){
  265. init_light_from_db(lid);
  266. }
  267. if(gid > 0){
  268. init_light_group_from_db(gid);
  269. }
  270. }
  271. // 红绿灯基础数据更新
  272. int traffic_light_manager::reload_light(const int& lid)
  273. {
  274. init_light_from_db(lid);
  275. return 0;
  276. }
  277. // 灯组基础数据更新
  278. int traffic_light_manager::reload_group(const int& gid)
  279. {
  280. init_light_group_from_db(gid);
  281. return 0;
  282. }
  283. std::vector<traffic_light_group_ptr> traffic_light_manager::find_stream_groups(traffic_light_group_ptr ptr_group, const move_stream& stream)
  284. {
  285. std::vector<traffic_light_group_ptr> vt_group;
  286. switch(stream){
  287. case move_stream::up_stream:
  288. {
  289. auto itg = m_map_groups.end();
  290. for(auto it = m_map_groups.begin(); it != m_map_groups.end(); ++it){
  291. if(it->second->m_group_id == ptr_group->m_group_id){
  292. itg = it;
  293. }
  294. }
  295. auto ite = itg;
  296. std::advance(ite, m_light_group_ctrl_num);
  297. std::for_each(itg, ite, [&vt_group](std::pair<int, traffic_light_group_ptr> p){
  298. if(p.second != nullptr){
  299. vt_group.push_back(p.second);
  300. }
  301. });
  302. }
  303. break;
  304. case move_stream::down_stream:
  305. {
  306. auto itg = m_map_groups.rend();
  307. for(auto it = m_map_groups.rbegin(); it != m_map_groups.rend(); ++it){
  308. if(it->second->m_group_id == ptr_group->m_group_id){
  309. itg = it;
  310. }
  311. }
  312. auto ite = itg;
  313. std::advance(ite, m_light_group_ctrl_num);
  314. std::for_each(itg, ite, [&vt_group](std::pair<int, traffic_light_group_ptr> p){
  315. if(p.second != nullptr){
  316. vt_group.push_back(p.second);
  317. }
  318. });
  319. }
  320. break;
  321. default:
  322. break;
  323. }
  324. return std::move(vt_group);
  325. }
  326. // 处理web端发起的手工控制
  327. void traffic_light_manager::manual_ctrl(sio::message::ptr const& data)
  328. {
  329. std::map<std::string, sio::message::ptr> mp = data->get_map()[JSON_ROOT_KEY_DATA]->get_map();
  330. log_info("[traffic_light] map's size=%d", mp.size());
  331. light_message lm;
  332. lm.m_group_id = mp["group_id"]->get_int();
  333. lm.m_light_id = mp["light_id"]->get_int();
  334. lm.m_light_state = mp["light_color"]->get_int();
  335. lm.m_ctrl_name = mp["ctrl_name"]->get_string();
  336. int ctrl = mp["control"]->get_int();
  337. // 如果手工控制,否则取消手工控制
  338. (ctrl == 1)?set_manual(lm):cancel_manual(lm);
  339. /*for(auto it = vtc.begin(); it != vtc.end(); ++it)
  340. {
  341. light_message lm;
  342. lm.m_group_id = (*it)->get_map()["group_id"]->get_int();
  343. lm.m_light_id = (*it)["light_id"]->get_int();
  344. lm.m_light_state = (*it)["light_color"]->get_int();
  345. lm.m_ctrl_name = (*it)["ctrl_name"]->get_string();
  346. int ctrl = (*it)["control"]->get_int();
  347. // 如果手工控制,否则取消手工控制
  348. (ctrl == 1)?set_manual(lm):cancel_manual(lm);
  349. }
  350. std::string rd = data->get_map()[JSON_ROOT_KEY_DATA]->get_string();
  351. log_info("[traffic light] recv web msg: %s", rd.c_str());
  352. */
  353. }
  354. void traffic_light_manager::handle_manual(const int& gid, const int& ld, const std::string& name, const int& lc)
  355. {
  356. traffic_light_group_ptr pg = find_group(gid);
  357. if(nullptr != pg){
  358. pg->set_manual_ctrl(name, ld, lc);
  359. }
  360. }
  361. // 红绿灯处理模块入口
  362. void traffic_light_manager::handle_position(pos_data& p)
  363. {
  364. if(p.m_type == 3 || p.m_type == 1){
  365. std::map<uint64_t, pos_data>::iterator it = m_map_card.find(p.m_card_id);
  366. if(it != m_map_card.end()){
  367. m_map_card.erase(it);
  368. }
  369. }else if(p.m_type == 2){
  370. update(p.x, p.y, p.m_card_id);
  371. m_map_card[p.m_card_id] = p;
  372. // 路口规则
  373. if(nullptr != m_crossing_rule){
  374. m_crossing_rule->handle_rule(p);
  375. }
  376. if(!p.m_bigger && nullptr != m_avoidance_rule){
  377. m_avoidance_rule->handle_rule(p);
  378. }
  379. }
  380. }
  381. // 手工控制红绿灯
  382. void traffic_light_manager::set_manual(light_message& msg)
  383. {
  384. auto g = m_unmap_groups.find(msg.m_group_id);
  385. if(g != m_unmap_groups.end()){
  386. int state = ((msg.m_light_state == 8)?9:8);
  387. for(auto it : g->second->m_vt_lights){
  388. if(it->m_light_id == msg.m_light_id){
  389. send_light_data(msg.m_light_id, 0, msg.m_light_state);
  390. }else{
  391. send_light_data(msg.m_light_id, 0, state);
  392. }
  393. }
  394. log_info("[traffic_light] manual ctrl's group info, group_id=%d, light %d's shape is %d, other's shape is %d", msg.m_group_id, msg.m_light_id, msg.m_light_state, state);
  395. }
  396. }
  397. // 取消手工控制
  398. void traffic_light_manager::cancel_manual(light_message& msg)
  399. {
  400. auto g = m_unmap_groups.find(msg.m_group_id);
  401. if(g != m_unmap_groups.end()){
  402. g->second->get_turn();
  403. g->second->reset();
  404. g->second->release_turn();
  405. for(auto it_light : g->second->m_vt_lights){
  406. send_light_data(it_light->m_light_id, 0, it_light->m_state);
  407. }
  408. log_info("[traffic_light] %s cancel manual control %d's light group of %d light", msg.m_ctrl_name.c_str(), msg.m_group_id, msg.m_light_id);
  409. }
  410. }
  411. int traffic_light_manager::remove_light(const int& id)
  412. {
  413. std::lock_guard<std::mutex> lg(m_mutex);
  414. auto it = m_unmap_lights.find(id);
  415. if(it != m_unmap_lights.end()){
  416. m_unmap_lights.erase(it);
  417. }
  418. log_info("[meta_data_change] remove light, lid=%d", id);
  419. return 0;
  420. }
  421. int traffic_light_manager::remove_light_group(const int& id)
  422. {
  423. std::lock_guard<std::mutex> lg(m_mutex);
  424. auto it = m_unmap_groups.find(id);
  425. if(it != m_unmap_groups.end()){
  426. m_unmap_groups.erase(it);
  427. }
  428. log_info("[meta_data_change] remove light group, gid=%d", id);
  429. return 0;
  430. }