module_traffic_light.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. double dist = p->dist_direct(point(x, y));
  75. if(dist * updown_dist() > 0){
  76. ms = move_stream::up_stream;
  77. }else if(dist * updown_dist() < 0){
  78. ms = move_stream::down_stream;
  79. }
  80. log_info("[traffic_light] cid=%d, stream=%d, dist_of_card_group=%.3f, updown=%.3f", p->m_card_id, ms, dist, updown_dist());
  81. return ms;
  82. }
  83. bool traffic_light_group::is_different(const int& ld, const int& lc, const int& lcr)
  84. {
  85. bool ret = false;
  86. get_turn();
  87. if(get_priority() <= priority_avoidance)
  88. {
  89. for(auto it = m_vt_lights.begin(); it != m_vt_lights.end(); ++it)
  90. {
  91. if((*it)->m_light_id == ld)
  92. {
  93. if((*it)->m_state != lc)
  94. {
  95. ret = true;
  96. break;
  97. }
  98. }else{
  99. if((*it)->m_state != lcr)
  100. {
  101. ret = true;
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. if(ret){
  108. set_avoidance(ld, lc, lcr);
  109. }
  110. release_turn();
  111. return ret;
  112. }
  113. // 向指定灯下发灯的状态
  114. void traffic_light_group::send_cmd_light(traffic_light_ptr& ptl)
  115. {
  116. if(nullptr == ptl){
  117. return;
  118. }
  119. YA::light_state ls(m_group_id, ptl->m_light_id, ptl->m_state, ((m_card_id == 0)?"":tool_byte::to_cardid(2,m_card_id)));
  120. swsTimerThrd.upt_light_state(ls);
  121. traffic_light_manager::instance()->send_light_data(ptl->m_light_id, DT_LIGHT, ptl->m_state);
  122. }
  123. void traffic_light_group::set_path(const std::vector<line_v>& vl)
  124. {
  125. if(vl.empty()){
  126. return;
  127. }
  128. const auto& find_line = [](const point& pt, int first, std::vector<line_v>& vl_){
  129. for(auto it = vl_.begin();it != vl_.end(); ++it){
  130. if(it->v[first].dist(pt) < 1){
  131. return it;
  132. }
  133. if(it->v[first?0:1].dist(pt) < 1){
  134. point p = it->v[0];
  135. it->v[0] = it->v[1];
  136. it->v[1] = p;
  137. return it;
  138. }
  139. }
  140. return vl_.end();
  141. };
  142. std::vector<line_v> vl_(vl.begin()+1, vl.end());
  143. std::vector<line_v> target(vl.begin(), vl.begin()+1);
  144. for(;;){
  145. auto it = find_line(target.back().v[1], 0, vl_);
  146. if(it == vl_.end()){
  147. break;
  148. }
  149. target.insert(target.end(), it, it+1);
  150. vl_.erase(it);
  151. }
  152. for(;;){
  153. auto it = find_line(target.front().v[0], 1, vl_);
  154. if(it == vl_.end()){
  155. break;
  156. }
  157. target.insert(target.begin(), it, it+1);
  158. vl_.erase(it);
  159. }
  160. for(int i = 0, c = target.size();i < c;++i){
  161. log_info("[traffic_light] path-id=%d, line=%s", i, target[i].to_string().c_str());
  162. }
  163. std::vector<line_v> vline(target);
  164. vline.reserve(vline.size()+2);
  165. // 找到距离红绿灯组最近的端点
  166. auto min_it = vline.begin();
  167. double dist = 10;
  168. for(auto it = vline.begin(); it != vline.end(); ++it){
  169. double d = it->as_line().dist(*this);
  170. if(d < dist){
  171. dist = d;
  172. min_it = it;
  173. }
  174. }
  175. if(min_it == vline.end()){
  176. return;
  177. }
  178. if(abs(min_it->v[0].dist(*this)-dist) < 1){
  179. set_path(vline, min_it);
  180. }else if(abs(min_it->v[1].dist(*this) - dist) < 1){
  181. set_path(vl, min_it+1);
  182. }else{
  183. point p = min_it->projection(*this);
  184. vline.insert(min_it+1, line_v(p, min_it->v[1]));
  185. min_it->set_point(1, p);
  186. if(min_it->v[0].z){
  187. double slope = min_it->v[0].z;
  188. double len_a = min_it->v[0].dist((min_it+1)->v[1]);
  189. double len_0 = slope*min_it->length()/len_a;
  190. double len_1 = slope-len_0;
  191. min_it->v[0].z = min_it->v[1].z = len_0;
  192. (min_it+1)->v[0].z = (min_it+1)->v[1].z = len_1;
  193. }
  194. set_path(vline, min_it+1);
  195. }
  196. }
  197. void traffic_light_group::set_path(const std::vector<line_v>& vl, std::vector<line_v>::const_iterator itm)
  198. {
  199. auto it = itm;
  200. for(int i=0;i<2&&it!=vl.end();++it,++i){
  201. m_path[0][i] = *it;
  202. }
  203. it = itm-1;
  204. for(int i=0;i<2&&it>=vl.begin();--it,++i){
  205. m_path[1][i] = *it;
  206. m_path[1][i].swap_point();
  207. }
  208. for(int i=0;i<2;i++){
  209. point p = m_path[i][0].line::projection(*this);
  210. m_path[i][0].set_point(0, p);
  211. }
  212. for(const auto& p: m_path){
  213. log_info("[traffic_light] light group's path: %s", p.to_str().c_str());
  214. }
  215. }
  216. /*
  217. *
  218. * param
  219. * name user's name
  220. * ld light id
  221. * lc ligth color
  222. * */
  223. void traffic_light_group::set_manual_ctrl(const std::string& name, const int& ld, const int& lc)
  224. {
  225. get_turn();
  226. m_ctrl_name = name;
  227. m_time_stamp = time(NULL);
  228. set_priority(priority_manual_ctrl);
  229. m_card_id = 0;
  230. auto ptl = std::find_if(m_vt_lights.begin(), m_vt_lights.end(),[=](traffic_light_ptr lp){
  231. if(lp->m_light_id == ld)
  232. {
  233. return true;
  234. }else{
  235. return false;
  236. }
  237. });
  238. if(ptl != m_vt_lights.end()){
  239. (*ptl)->set_state(lc);
  240. }
  241. release_turn();
  242. }
  243. /*
  244. * 计算上行与下行灯之间的距离,带方向
  245. * */
  246. double traffic_light_group::updown_dist()
  247. {
  248. point up;
  249. point down;
  250. for(auto it : m_vt_lights){
  251. switch(it->m_stream){
  252. case 1:
  253. //上行
  254. up = point(it->x, it->y, it->z);
  255. break;
  256. case 2:
  257. // 下行
  258. down = point(it->x, it->y, it->z);
  259. break;
  260. default:
  261. break;
  262. }
  263. }
  264. if(up.empty()||down.empty()){
  265. 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"));
  266. return 0;
  267. }
  268. return up.dist_direct(down);
  269. }