1
0

module_traffic_light.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #include <algorithm>
  2. #include "module_traffic_light.h"
  3. #include "module_traffic_light_manager.h"
  4. #include "websocket/wsTimerThread.h"
  5. void traffic_light_group::reset()
  6. {
  7. m_time_stamp = 0;
  8. m_ctrl_name = "";
  9. m_card_id = 0;
  10. m_stream_state = move_stream::unknown;
  11. set_status(false);
  12. set_priority(priority_init);
  13. log_info("[traffic_light] reset light group, gid=%d", m_group_id);
  14. for(auto it = m_vt_lights.begin();it != m_vt_lights.end(); ++it){
  15. auto tl = traffic_light_manager::instance()->find_light((*it)->m_light_id);
  16. if(tl != nullptr){
  17. tl->set_state();
  18. send_cmd_light(tl);
  19. }
  20. }
  21. }
  22. void traffic_light_group::insert(traffic_light_ptr ptl)
  23. {
  24. if(exist(ptl->m_light_id)){
  25. return;
  26. }
  27. ptl->m_direct_distance = this->dist_direct(*ptl);
  28. line tmp(*this, *ptl);
  29. ptl->m_line_group = tmp;
  30. m_vt_lights.push_back(ptl);
  31. if(1 == ptl->m_special){
  32. m_special = 1;
  33. }
  34. }
  35. bool traffic_light_group::exist(const int& lid)
  36. {
  37. if(m_vt_lights.size() == 0){
  38. return false;
  39. }
  40. bool exist = false;
  41. for(size_t i = 0; i < m_vt_lights.size(); ++i){
  42. if(m_vt_lights[i]->m_light_id == lid){
  43. exist = true;
  44. break;
  45. }
  46. }
  47. return exist;
  48. }
  49. bool traffic_light_group::is_at_path(point p)
  50. {
  51. return true;
  52. }
  53. // 设置灯组内所有灯的形状,指定灯ld的形状为lc,其他灯的形状为lcr
  54. void traffic_light_group::set_light(const int& ld, const int& lc, const int& lcr)
  55. {
  56. log_info("[traffic_light] set light group status, total_lights=%d, light_id=%d, status=%d, reverse_status=%d", m_vt_lights.size(), ld, lc, lcr);
  57. for(auto it = m_vt_lights.begin(); it != m_vt_lights.end(); ++it){
  58. if((*it)->m_light_id == ld){
  59. (*it)->set_state(lc);
  60. send_cmd_light(*it);
  61. }else{
  62. (*it)->set_state(lcr);
  63. send_cmd_light(*it);
  64. }
  65. }
  66. }
  67. move_stream traffic_light_group::get_stream(const int& cid)
  68. {
  69. move_stream ms = move_stream::unknown;
  70. pos_data* p = traffic_light_manager::instance()->get_position(cid);
  71. if(nullptr == p){
  72. return ms;
  73. }
  74. if(size()<2){
  75. return ms;
  76. }
  77. double dist = p->dist_direct(point(x, y)) * traffic_light_manager::instance()->get_scale();
  78. if(dist * updown_dist() > 0){
  79. ms = move_stream::up_stream;
  80. }else if(dist * updown_dist() < 0){
  81. ms = move_stream::down_stream;
  82. }
  83. log_info("[traffic_light] cid=%d, stream=%d, dist_of_card_group=%.3f, updown=%.3f", p->m_card_id, ms, dist, updown_dist());
  84. return ms;
  85. }
  86. bool traffic_light_group::is_different(const int& ld, const int& lc, const int& lcr)
  87. {
  88. bool ret = false;
  89. get_turn();
  90. if(get_priority() <= priority_avoidance)
  91. {
  92. for(auto it = m_vt_lights.begin(); it != m_vt_lights.end(); ++it)
  93. {
  94. if((*it)->m_light_id == ld)
  95. {
  96. if((*it)->m_state != lc)
  97. {
  98. ret = true;
  99. break;
  100. }
  101. }else{
  102. if((*it)->m_state != lcr)
  103. {
  104. ret = true;
  105. break;
  106. }
  107. }
  108. }
  109. }
  110. if(ret){
  111. set_avoidance(ld, lc, lcr);
  112. }
  113. release_turn();
  114. return ret;
  115. }
  116. // 向指定灯下发灯的状态
  117. void traffic_light_group::send_cmd_light(traffic_light_ptr& ptl)
  118. {
  119. if(nullptr == ptl){
  120. return;
  121. }
  122. sys::light_state ls(m_group_id, ptl->m_light_id, ptl->m_state, ((m_card_id == 0)?"":tool_other::to_cid(2, m_card_id)));
  123. swsTimerThrd.upt_light_state(ls);
  124. traffic_light_manager::instance()->send_light_data(ptl->m_light_id, DT_LIGHT, ptl->m_state);
  125. }
  126. void traffic_light_group::set_path(const std::vector<line_v>& vl)
  127. {
  128. if(vl.empty()){
  129. return;
  130. }
  131. const auto& find_line = [](const point& pt, int first, std::vector<line_v>& vl_){
  132. for(auto it = vl_.begin();it != vl_.end(); ++it){
  133. if(it->v[first].dist(pt) < 1){
  134. return it;
  135. }
  136. if(it->v[first?0:1].dist(pt) < 1){
  137. point p = it->v[0];
  138. it->v[0] = it->v[1];
  139. it->v[1] = p;
  140. return it;
  141. }
  142. }
  143. return vl_.end();
  144. };
  145. std::vector<line_v> vl_(vl.begin()+1, vl.end());
  146. std::vector<line_v> target(vl.begin(), vl.begin()+1);
  147. for(;;){
  148. auto it = find_line(target.back().v[1], 0, vl_);
  149. if(it == vl_.end()){
  150. break;
  151. }
  152. target.insert(target.end(), it, it+1);
  153. vl_.erase(it);
  154. }
  155. for(;;){
  156. auto it = find_line(target.front().v[0], 1, vl_);
  157. if(it == vl_.end()){
  158. break;
  159. }
  160. target.insert(target.begin(), it, it+1);
  161. vl_.erase(it);
  162. }
  163. for(int i = 0, c = target.size();i < c;++i){
  164. log_info("[traffic_light] path-id=%d, line=%s", i, target[i].to_string().c_str());
  165. }
  166. std::vector<line_v> vline(target);
  167. vline.reserve(vline.size()+2);
  168. // 找到距离红绿灯组最近的端点
  169. auto min_it = vline.begin();
  170. double dist = 10;
  171. for(auto it = vline.begin(); it != vline.end(); ++it){
  172. double d = it->as_line().dist(*this);
  173. if(d < dist){
  174. dist = d;
  175. min_it = it;
  176. }
  177. }
  178. if(min_it == vline.end()){
  179. return;
  180. }
  181. if(abs(min_it->v[0].dist(*this)-dist) < 1){
  182. set_path(vline, min_it);
  183. }else if(abs(min_it->v[1].dist(*this) - dist) < 1){
  184. set_path(vl, min_it+1);
  185. }else{
  186. point p = min_it->projection(*this);
  187. vline.insert(min_it+1, line_v(p, min_it->v[1]));
  188. min_it->set_point(1, p);
  189. if(min_it->v[0].z){
  190. double slope = min_it->v[0].z;
  191. double len_a = min_it->v[0].dist((min_it+1)->v[1]);
  192. double len_0 = slope*min_it->length()/len_a;
  193. double len_1 = slope-len_0;
  194. min_it->v[0].z = min_it->v[1].z = len_0;
  195. (min_it+1)->v[0].z = (min_it+1)->v[1].z = len_1;
  196. }
  197. set_path(vline, min_it+1);
  198. }
  199. }
  200. void traffic_light_group::set_path(const std::vector<line_v>& vl, std::vector<line_v>::const_iterator itm)
  201. {
  202. auto it = itm;
  203. for(int i=0;i<2&&it!=vl.end();++it,++i){
  204. m_path[0][i] = *it;
  205. }
  206. it = itm-1;
  207. for(int i=0;i<2&&it>=vl.begin();--it,++i){
  208. m_path[1][i] = *it;
  209. m_path[1][i].swap_point();
  210. }
  211. for(int i=0;i<2;i++){
  212. point p = m_path[i][0].line::projection(*this);
  213. m_path[i][0].set_point(0, p);
  214. }
  215. for(const auto& p: m_path){
  216. log_info("[traffic_light] light group's path: %s", p.to_str().c_str());
  217. }
  218. }
  219. /*
  220. *
  221. * param
  222. * name user's name
  223. * ld light id
  224. * lc ligth color
  225. * */
  226. void traffic_light_group::set_manual_ctrl(const std::string& name, const int& ld, const int& lc)
  227. {
  228. get_turn();
  229. m_ctrl_name = name;
  230. m_time_stamp = time(NULL);
  231. set_priority(priority_manual_ctrl);
  232. m_card_id = 0;
  233. auto ptl = std::find_if(m_vt_lights.begin(), m_vt_lights.end(),[=](traffic_light_ptr lp){
  234. if(lp->m_light_id == ld)
  235. {
  236. return true;
  237. }else{
  238. return false;
  239. }
  240. });
  241. if(ptl != m_vt_lights.end()){
  242. (*ptl)->set_state(lc);
  243. }
  244. release_turn();
  245. }
  246. /*
  247. * 计算上行与下行灯之间的距离,带方向
  248. * */
  249. double traffic_light_group::updown_dist()
  250. {
  251. point up;
  252. point down;
  253. for(auto it : m_vt_lights){
  254. switch(it->m_stream){
  255. case 1:
  256. //上行
  257. up = point(it->x, it->y, it->z);
  258. break;
  259. case 2:
  260. // 下行
  261. down = point(it->x, it->y, it->z);
  262. break;
  263. default:
  264. break;
  265. }
  266. }
  267. if(up.empty()||down.empty()){
  268. log_info("[traffic_light] the %d's light group, up_light empty=%s, down_light empty=%s", m_group_id, (up.empty()?"true":false), (down.empty()?"true":"false"));
  269. return 0;
  270. }
  271. return up.dist_direct(down);
  272. }