ant.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <math.h>
  4. #include "ant.h"
  5. #include "event.h"
  6. #include "area.h"
  7. #include "websocket/wsTimerThread.h"
  8. #include "sys_setting.h"
  9. #include <numeric>
  10. int site::index()const
  11. {
  12. //return m_algo+(m_num_dims<<1);
  13. return (m_algo<<4) + m_num_dims;
  14. }
  15. site::site(int id)
  16. :m_algo(0)
  17. ,m_num_dims(0)
  18. ,m_id(id)
  19. ,m_path_empty(true)
  20. {
  21. //m_time = time(0);
  22. for(uint32_t i=0;i<m_timeoff_count.size();i++)
  23. m_timeoff_count[i]=0;
  24. }
  25. const algo_config&site::config()const
  26. {
  27. return g_config[index()];
  28. }
  29. void ant::set_path(const std::vector<line_v>& v_line, std::vector<line_v>::const_iterator itm)
  30. {
  31. auto it = itm;
  32. for(int i = 0; i < 2 && it != v_line.end(); ++it,++i)
  33. m_path[0][i]=*it;
  34. it=itm-1;
  35. for(int i=0;i<2 && it>=v_line.begin();--it,++i)
  36. {
  37. m_path[1][i]=*it;
  38. m_path[1][i].swap_point();
  39. }
  40. for(int i=0;i<2;i++)
  41. {
  42. point _p=m_path[i][0].line::projection(*this);
  43. m_path[i][0].set_point(0,_p);
  44. }
  45. for(const auto&p:m_path)
  46. {
  47. log_info("site-path: %s",p.to_str().c_str());
  48. }
  49. }
  50. void ant::set_path(const std::vector<line_v>&v_line_)
  51. {
  52. std::vector<line_v> vl(v_line_);
  53. vl.reserve(vl.size()+2);
  54. //找到距离天线最近的端点
  55. auto min_it = vl.begin();
  56. double dist = 10;
  57. for(auto it = vl.begin(); it != vl.end(); it++)
  58. {
  59. double d = it->as_line().dist(*this);
  60. if(d < dist)
  61. {
  62. dist = d;
  63. min_it = it;
  64. }
  65. }
  66. if(min_it==vl.end())
  67. {
  68. log_error("分站路径距离分站太远site_id=%d",m_id);
  69. return;
  70. }
  71. if(abs(min_it->v[0].dist(*this) - dist) < 1)
  72. {
  73. set_path(vl, min_it);
  74. }
  75. else if(abs(min_it->v[1].dist(*this) - dist) < 1)
  76. {
  77. set_path(vl, min_it+1);
  78. }
  79. else
  80. {
  81. point proj=min_it->projection(*this);
  82. vl.insert(min_it+1,line_v(proj,min_it->v[1]));
  83. min_it->set_point(1,proj);
  84. if(min_it->v[0].z)//slope ..555
  85. {
  86. double slope=min_it->v[0].z;
  87. double len_a=min_it->v[0].dist((min_it+1)->v[1]);
  88. double len_0=slope*min_it->length()/len_a;
  89. double len_1=slope-len_0;
  90. min_it->v[0].z=min_it->v[1].z=len_0;
  91. (min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
  92. }
  93. set_path(vl,min_it+1);
  94. }
  95. }
  96. /*
  97. * @brief 天线相位是否异常
  98. * @param 无
  99. * @return 相位异常返回true,否则返回false
  100. * @note
  101. * @warning
  102. * @bug
  103. * */
  104. bool ant::phase_error()
  105. {
  106. if(m_cache_poa.size()<5){
  107. return false;
  108. }
  109. double sum = std::accumulate(m_cache_poa.begin(), m_cache_poa.end(), 0.0);
  110. return (sum < 1E-4?true:false);
  111. }
  112. void site::set_path(const std::vector<line_v>&v_line)
  113. {
  114. if(v_line.empty())
  115. return;
  116. const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
  117. for(auto it=vl.begin();it!=vl.end();it++)
  118. {
  119. if(it->v[first].dist(pt)<1)
  120. return it;
  121. if(it->v[first?0:1].dist(pt)<1)
  122. {
  123. point p=it->v[0];
  124. it->v[0]=it->v[1];
  125. it->v[1]=p;
  126. return it;
  127. }
  128. }
  129. return vl.end();
  130. };
  131. //构造一个首尾相连的结构
  132. std::vector<line_v> vl(v_line.begin()+1,v_line.end());
  133. std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
  134. #if 0
  135. target[0][0].z=target[0][1].z=slope[0];
  136. for(int i=0,c=vl.size();i<c;i++)
  137. vl[i][0].z=vl[i][1].z=slope[i+1];
  138. #endif
  139. for(;;)
  140. {
  141. auto it=find_line(target.back().v[1],0,vl);
  142. if(it==vl.end())
  143. break;
  144. target.insert(target.end(),it,it+1);
  145. vl.erase(it);
  146. }
  147. for(;;)
  148. {
  149. auto it=find_line(target.front().v[0],1,vl);
  150. if(it==vl.end())
  151. break;
  152. target.insert(target.begin(),it,it+1);
  153. vl.erase(it);
  154. }
  155. log_info("初始化分站路径:site_id=%d",m_id);
  156. for(int i=0,c=target.size();i<c;i++)
  157. {
  158. log_info("path-id=%d,line=%s",i,target[i].to_string().c_str());
  159. }
  160. for(int i = 0,c = m_ant.size(); i < c; i++)
  161. {
  162. if(m_ant[i].empty())
  163. {
  164. log_error("分站未设置天线坐标 site_id=%d,ant_index=%d", m_id, i);
  165. continue;
  166. }
  167. m_ant[i].set_path(target);
  168. }
  169. m_path_empty= !m_ant[0][0].valid() && !m_ant[0][1].valid() ;
  170. }
  171. double site::get_site_dist(const int& sid)
  172. {
  173. auto it_site = sit_list::instance()->get(sid);
  174. if(it_site){
  175. return this->dist(*it_site);
  176. }else{
  177. return 0.0;
  178. }
  179. }
  180. std::vector<point> ant::getsol(const double &dist) const
  181. {
  182. std::vector<point> v;
  183. for(const auto & p : m_path)
  184. {
  185. if(!p.valid())
  186. continue;
  187. point pt;
  188. double d = dist;
  189. //logn_info(3, "[pdoa] dist=%.2f, line.length()=%.2f, %s", dist, p.m_line[0].length(), p.to_str().c_str());
  190. if(dist <= p.m_line[0].length())
  191. {
  192. d += d*p.m_line[0][0].z;
  193. pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
  194. }
  195. else if(p.m_line[1].length()>0)
  196. {
  197. d -= p.m_line[0].length()*(1-d*p.m_line[0][1].z);
  198. d += d*p.m_line[1][0].z;
  199. pt = point(p.m_line[1][0].x+d*p.m_line[1].cos(),p.m_line[1][0].y+d*p.m_line[1].sin());
  200. }
  201. else
  202. {
  203. continue;
  204. }
  205. v.push_back(pt);
  206. }
  207. return std::move(v);
  208. }
  209. bool visit_site_status::visit(std::shared_ptr<site> s)
  210. {
  211. time_t now = time(0);
  212. int diff = now - s->m_time;
  213. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_ERROR, s->m_id, READER_TIMEOUT, diff, diff>READER_TIMEOUT);
  214. // 定位基站长时间无定位告警
  215. /*if(s->m_loc_time > 0 && s->m_device_type_id == DEVICE_TYPE::LOCATE_SITE)
  216. {
  217. int diff = now - s->m_loc_time;
  218. log_info("site_no_position: site_id=%d, diff=%d, loc_time=%ld", s->m_id, diff, s->m_loc_time);
  219. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_LONG_TIME_NO_POSITION, s->m_id, CYaSetting::m_sys_setting.site_no_position_time, diff, diff>CYaSetting::m_sys_setting.site_no_position_time);
  220. }*/
  221. // 定位基站天线poa异常告警
  222. if(s->m_device_type_id == DEVICE_TYPE::LOCATE_SITE){
  223. if(s->m_ant[0].phase_error()&&s->m_ant[1].phase_error()){
  224. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_ANTENNA_PHASE_ABNORMAL, s->m_id, 0, 3, true);
  225. }else if(s->m_ant[0].phase_error()|| s->m_ant[1].phase_error()){
  226. if(s->m_ant[0].phase_error()){
  227. // 如果1天线相位值错误
  228. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_ANTENNA_PHASE_ABNORMAL, s->m_id, 0, 1, true);
  229. }else if(s->m_ant[1].phase_error()){
  230. // 如果2天线相位值错误
  231. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_ANTENNA_PHASE_ABNORMAL, s->m_id, 0, 2, true);
  232. }
  233. }else{
  234. // 如果都没错误,告警消失
  235. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_ANTENNA_PHASE_ABNORMAL, s->m_id, 0, 0, false);
  236. }
  237. }
  238. // 更新设备状态
  239. int state = (diff > READER_TIMEOUT ? 1 : 0);
  240. //log_info("[device_state] rid=%d, diff=%d, timeout=%d, state=%d, now=%lld, rtime=%lld", s->m_id, diff, READER_TIMEOUT, state, now, s->m_time);
  241. sys::device_state ds(s->m_id, s->m_device_type_id, state, now);
  242. swsTimerThrd.upt_device_state(ds);
  243. return true;
  244. }
  245. void site::create_area()
  246. {
  247. m_area=std::make_shared<area>(-m_id,0,0,m_scale,m_map_id,1<<7);
  248. }
  249. void site::clear_event()
  250. {
  251. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_ERROR, id(), READER_TIMEOUT, 0, false);
  252. event_tool::instance()->handle_event(OT_DEVICE_READER, ET_READER_POWER_BY_BATTERY, id(), 0, 0, false);
  253. }
  254. /*
  255. 处理分站供电状态,交流供电时,ac_down=false,直流供电时,ac_down=true
  256. 目前只有大分站实现了这个功能,并且井下安装时是否接入了该电信号也不确定
  257. ,所以需要有张表定义某个ID是否需要告警
  258. */
  259. void site::on_power_status(bool ac_down)//电源状态
  260. {
  261. if(!m_power_check_enable || ac_down == m_power_ac_down)
  262. {
  263. return;
  264. }
  265. m_power_ac_down=ac_down;
  266. event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_POWER_BY_BATTERY,id(),tool_time::now_to_seconds(),ac_down,m_power_ac_down);
  267. log_info("[event warning: reader power supply by battery] reader_id: Power %d->%d.",id(),!m_power_ac_down,m_power_ac_down);
  268. }
  269. algo_config site::g_config[]=
  270. {
  271. { "tof-1", 1, 2, 0.1, 1 },
  272. { "tdoa-1", 2, 2, 0.1, 1 },
  273. { "tof-2", 2, 3, 0.1, 1 },
  274. { "tdoa-2", 3, 3, 0.1, 1 },
  275. { "tof-3", 3, 4, 0.1, 1 },
  276. { "tdoa-3", 4, 4, 0.1, 1 }
  277. };
  278. /*
  279. #ifdef _TEST
  280. int main()
  281. {
  282. log_init("./log.ini");
  283. //sit_list *sl = sit_list::instance();
  284. sit_list::instance()->load("data_reader_antenna.txt","path_tof.txt");
  285. sit_list::instance()->get(209)->solving(0,100);
  286. sit_list::instance()->get(209)->solving(1,100.5);
  287. //std_info("---%d",(*sl)[209].m_ant[0].m_path.size());
  288. //std_info("---%d",(*sl)[209][0].size());
  289. //std_info("---%s",(*sl)[209][0][0][0].to_string().c_str());
  290. }
  291. #endif
  292. */