loc_tool.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #include <vector>
  2. #include <log.h>
  3. #include <ant.h>
  4. #include <loc_tool.h>
  5. #include <message.h>
  6. #include "loc_common.h"
  7. // pdoa三维定位
  8. std::vector<point> loc_tool_pdoa_3_base::calc_location(std::vector<loc_message>& loc)
  9. {
  10. return std::vector<point>();
  11. }
  12. int loc_tool_pdoa_3_base::index()
  13. {
  14. return 8;
  15. }
  16. // pdoa二维定位
  17. std::vector<point> loc_tool_pdoa_2_base::calc_location(std::vector<loc_message>& loc)
  18. {
  19. if( 1 > loc.size())
  20. {
  21. logn_info(3, "[pdoa] loc_tool_pdoa_2_base::calc_location, the nums of location data is less than 2");
  22. return std::vector<point>();
  23. }
  24. logn_info(3, "[pdoa] loc_tool_pdoa_2_base::calc_location, loc.size=%d", loc.size());
  25. std::vector<pdoa_msg_ptr> vps;
  26. for(auto it = loc.begin(); it != loc.end(); ++it)
  27. {
  28. double d = (*it).m_num_ticks*15.65*2.996*1e-4;
  29. double angle = (*it).m_sit->m_ant[(*it).m_ant_id].m_angle;
  30. double x = (*it).m_sit->m_ant[(*it).m_ant_id].x;
  31. double y = (*it).m_sit->m_ant[(*it).m_ant_id].y;
  32. double p = (*it).get_pdoa(0);
  33. logn_info(3, "[pdoa] calc_position's param, d=%.2f, tof=%ld, angle=%.2f, x=%.2f, y=%.2f, pdoa=%.4f, m_scale=%.2f", d, (*it).m_num_ticks , angle, x, y, p, (*it).m_sit->m_scale);
  34. pdoa_param pp(p, d, angle, x, y);
  35. if(!cal_position_pdoa(vps, pp)){
  36. break;
  37. }
  38. }
  39. if(2 > vps.size()){
  40. logn_info(3, "[pdoa] solutions too less, size=%d", vps.size());
  41. return std::vector<point>();
  42. }
  43. for(auto it = vps.cbegin();it != vps.cend(); ++it){
  44. logn_info(3, "[pdoa] possible solution: x=%.4f, y=%.4f", (*it)->x, (*it)->y);
  45. }
  46. pdoa_msg_ptr p_msg;
  47. std::size_t count = vps.size();
  48. if(count <= 0){
  49. return std::vector<point>();
  50. }
  51. for(std::size_t i = 0; i < count; ++i){
  52. if(vps[i]->y > 0){
  53. p_msg = vps[i];
  54. p_msg->x /= loc[0].m_sit->m_scale;
  55. p_msg->y /= loc[0].m_sit->m_scale;
  56. }
  57. }
  58. double _angle = 3.1415926*p_msg->angle/180.0;
  59. double x = p_msg->x_ant + p_msg->x*cos(_angle) - p_msg->y*sin(_angle);
  60. double y = p_msg->y_ant + p_msg->x*sin(_angle) + p_msg->y*cos(_angle);
  61. logn_info(3, "[pdoa] save,card_id=%d, x=%.4f, y=%.4f, ant_x=%.4f, ant_y=%.4f, angle = %.3f, site_angle=%.3f", loc[0].m_card_id, x, y, p_msg->x_ant, p_msg->y_ant, _angle, p_msg->angle);
  62. std::vector<point> vp;
  63. vp.push_back(point(x, y));
  64. return vp;
  65. }
  66. int loc_tool_pdoa_2_base::index()
  67. {
  68. return 7;
  69. }
  70. /*
  71. * 计算pdoa定位坐标,并将定位结果保存在vps内
  72. *
  73. */
  74. bool loc_tool_pdoa_2_base::cal_position_pdoa(std::vector<pdoa_msg_ptr>& vps, const pdoa_param& pa)
  75. {
  76. float b = 0.075;
  77. float d = 0.5*b;
  78. float p = pa.pdoa*b / (2.0*3.1415926);
  79. logn_info(3,"[pdoa] before adjust, p = %.4f, pdoa=%.4f", p, pa.pdoa);
  80. p = -2919.8*pow(p, 4.0) - 88.74*pow(p, 3.0) + 5.6182*p*p + 1.1041*p - 0.00079884;
  81. //p = -0.0222*pow(p, 4.0) + 0.0328*pow(p, 3.0) + 0.0729*p*p + 0.854*p + 0.0111;
  82. //p *= 0.01;
  83. float alpha = p / d;
  84. if(fabs(alpha) > 1.0){
  85. logn_info(3, "[pdoa] p>d, alpha=%.4f, p=%.4f, d=%.4f", alpha, p , d);
  86. return false;
  87. }
  88. //double x = (d*d + 2*pa.r*p - p*p) / (2*d);
  89. //double y = (pa.r - 0.5*p)*sqrt(1.0 - (p/d)*(p/d));
  90. double angle = acos(alpha)*180/3.14;
  91. logn_info(3, "[pdoa] angle=%.2f, distance=%.2f", angle, pa.r);
  92. double x = d / 2.0 + alpha*(pa.r - p / 2.0);
  93. double y = (pa.r - 0.5*p)*sqrt(1.0 - alpha*alpha);
  94. logn_info(3, "[pdoa] param, distance=%.4f, p=%.4f, d=%.4f, x=%.4f, y=%.4f, p/d=%.4f", pa.r, p, d, x, y, alpha);
  95. vps.push_back(std::make_shared<pdoa_message>(x, y, pa.a, pa.r, pa.ax, pa.ay, pa.pdoa, angle));
  96. vps.push_back(std::make_shared<pdoa_message>(x, -y, pa.a, pa.r, pa.ax, pa.ay, pa.pdoa, angle));
  97. return true;
  98. }
  99. // pdoa一维定位
  100. std::vector<point> loc_tool_pdoa_1_base::calc_location(std::vector<loc_message>& loc)
  101. {
  102. //logn_info(3, "[pdoa] loc_tool_pdoa_1_base::calc_location, card_id=%d, loc.size=%d", loc[0].m_card_id, loc.size());
  103. int32_t last_ct = -1;
  104. std::vector<point> vc;
  105. std::vector<loc_message> lm;
  106. for(auto rit = loc.rbegin(); rit != loc.rend(); ++rit){
  107. if(rit->m_sit->is_path_empty() || rit->m_num_ticks <= 0){
  108. continue;
  109. }
  110. if(-1 == last_ct){
  111. last_ct = rit->m_card_ct;
  112. }
  113. double dist_tof = rit->m_num_ticks*15.65*2.996*1e-4/rit->m_sit->m_scale;
  114. auto v = rit->m_sit->solving_pdoa(rit->m_ant_id, dist_tof);
  115. lm.insert(lm.begin(), *rit);
  116. vc.insert(std::end(vc), std::begin(v), std::end(v));
  117. }
  118. loc.swap(lm);
  119. return std::move(vc);
  120. }
  121. int loc_tool_pdoa_1_base::index()
  122. {
  123. return 6;
  124. }
  125. // tdoa三维定位
  126. std::vector<point> loc_tool_tdoa_3_base::calc_location(std::vector<loc_message>& loc)
  127. {
  128. return std::vector<point>();
  129. }
  130. int loc_tool_tdoa_3_base::index()
  131. {
  132. return 5;
  133. }
  134. // tdoa二维定位
  135. std::vector<point> loc_tool_tdoa_2_base::calc_location(std::vector<loc_message>& locm)
  136. {
  137. if(locm.size() < 3){
  138. return std::vector<point>();
  139. }
  140. std::vector<point> sol; // 解的列表,返回值
  141. sol.resize(0);
  142. std::vector<algo_solution> _algo_sol;
  143. _algo_sol.resize(0);
  144. std::vector<double> vtk; // 保存ki
  145. std::vector<double> vtd; // 保存di
  146. std::vector<point> vtc; // 保存xi,1 yi,1
  147. std::vector<point> vtp; // 保存三角形的顶点坐标
  148. std::vector<int> vts;
  149. vtk.resize(0);
  150. vtd.resize(0);
  151. vtc.resize(0);
  152. vtp.resize(0);
  153. vts.resize(0);
  154. // 保存卡数据中第一条的分站坐标和插值时间
  155. point fp;
  156. unsigned long long fts = 0;
  157. double _height_offset = 0.0;
  158. loc_message datas[3];
  159. for(auto iter0 = locm.begin(); iter0 != locm.end(); ++iter0)
  160. {
  161. for(auto iter1 = iter0 + 1; iter1 != locm.end(); ++iter1)
  162. {
  163. for(auto iter2 = iter1 + 1; iter2 != locm.end(); ++iter2)
  164. {
  165. vtk.clear();
  166. vtd.clear();
  167. vtc.clear();
  168. vts.clear();
  169. vtp.clear();
  170. datas[0] = *(iter0);
  171. datas[1] = *(iter1);
  172. datas[2] = *(iter2);
  173. for(int i = 0; i < 3; ++i)
  174. {
  175. double k = 0.0;
  176. k = pow(datas[i].m_sit->x, 2) + pow(datas[i].m_sit->y, 2);
  177. vtk.push_back(k);
  178. if(i == 0)
  179. {
  180. fts = datas[i].m_num_ticks;
  181. fp.x = datas[i].m_sit->x;
  182. fp.y = datas[i].m_sit->y;
  183. vtd.push_back(0.0);
  184. }else{
  185. long long diff_time = datas[i].m_num_ticks - fts;
  186. double d = diff_time* DWT_TIME_UNITS * SPEED_OF_LIGHT;
  187. if(d > 0){
  188. vts.push_back(1);
  189. }else{
  190. vts.push_back(-1);
  191. }
  192. vtd.push_back(d);
  193. }
  194. vtc.push_back(point(datas[i].m_sit->x - fp.x, datas[i].m_sit->y - fp.y));
  195. vtp.push_back(point(datas[i].m_sit->x, datas[i].m_sit->y));
  196. }
  197. double a[4] = {0};
  198. double dt = vtd[1]*vtc[2].y - vtd[2]*vtc[1].y;
  199. if(dt < 1E-5 || fabs(vtd[1]) < 1E-5){
  200. continue;
  201. }
  202. a[0] = (vtd[2]*vtc[1].x - vtd[1]*vtc[2].x)/dt;
  203. a[1] = (-1)*((vtk[1] - vtk[0] - pow(vtd[1],2))*vtd[2] - (vtk[2] - vtk[0] - pow(vtd[2], 2))*vtd[1])*0.5 / dt;
  204. a[2] = 0.5*(vtk[1] - vtk[0] - pow(vtd[1],2) - 2*vtc[1].y*a[1]) / vtd[1];
  205. a[3] = -1*(vtc[1].x + vtc[1].y*a[0]) / vtd[1];
  206. double A = 0.0, B = 0.0, C = 0.0;
  207. A = pow(a[3], 2) - 1 - pow(a[0], 2);
  208. B = 2*(a[2]*a[3] + fp.x + a[0]*(fp.y - a[1]));
  209. C = pow(a[2], 2) - pow(fp.x, 2) - pow(fp.y - a[1], 2) - pow(_height_offset, 2);
  210. std::vector<point> _vp;
  211. double delta = pow(B, 2) - 4*A*C;
  212. if(delta > 0){
  213. point p;
  214. p.x = ((-1.0)*B + sqrt(delta))/(2.0*A);
  215. p.y = a[0]*p.x + a[1];
  216. _vp.push_back(p);
  217. p.x = ((-1)*B - sqrt(delta))/(2.0*A);
  218. p.y = a[0]*p.x + a[1];
  219. _vp.push_back(p);
  220. }else{
  221. continue;
  222. }
  223. int idx = -1;
  224. for(std::size_t i = 0; i < _vp.size(); ++i)
  225. {
  226. bool cond[2] = {false};
  227. // 对两个解进行判断,需要同时满足两个条件:
  228. // 1.解到点1和点2的距离差的方向性和之前的参数相同
  229. // 2.解到点1和点3的距离差的方向性和之前的参数相同
  230. double d1 = sqrt(pow(vtp[1].x - _vp[i].x, 2) + pow(vtp[1].y - _vp[i].y, 2)) - sqrt(pow(vtp[0].x - _vp[i].x, 2) + pow(vtp[0].y - _vp[i].y, 2));
  231. double d2 = sqrt(pow(vtp[2].x - _vp[i].x, 2) + pow(vtp[2].y - _vp[i].y, 2)) - sqrt(pow(vtp[0].x - _vp[i].x, 2) + pow(vtp[0].y - _vp[i].y, 2));
  232. if((d1 < 0 && vts[0] == -1) || (d1 > 0 && vts[0] == 1))
  233. {
  234. cond[0] = true;
  235. }
  236. if((d2 < 0 && vts[1] == -1) || (d2 > 0 && vts[1] == 1))
  237. {
  238. cond[1] = true;
  239. }
  240. if(cond[0] && cond[1]){
  241. idx = i;
  242. }
  243. }
  244. // 判断求出的解是否在基站构成的三角形内
  245. if(idx != -1){
  246. if(is_in_triangle(vtp, _vp[idx]))
  247. {
  248. //sol.push_back(_vp[idx]);
  249. algo_solution _as;
  250. _as.m_pos = std::make_shared<point>(_vp[idx]);
  251. _as.m_triangle = std::make_shared<triangle>();
  252. site_point _sp(point(datas[0].m_sit->x, datas[0].m_sit->y));
  253. _sp.m_site_id = datas[0].m_sit->m_id;
  254. _as.m_triangle->m_vertex.push_back(std::move(_sp));
  255. site_point _sp1(point(datas[1].m_sit->x, datas[1].m_sit->y));
  256. _sp1.m_site_id = datas[1].m_sit->m_id;
  257. _as.m_triangle->m_vertex.push_back(std::move(_sp1));
  258. site_point _sp2(point(datas[2].m_sit->x, datas[2].m_sit->y));
  259. _sp2.m_site_id = datas[2].m_sit->m_id;
  260. _as.m_triangle->m_vertex.push_back(std::move(_sp2));
  261. _algo_sol.push_back(_as);
  262. }else{
  263. sol.push_back(_vp[idx]);
  264. }
  265. }
  266. }
  267. }
  268. }
  269. // 如果有多于1个的解,
  270. // 需要计算该解到其对应三角形质心的距离,
  271. // 然后根据这个距离排序,选择距离最小的解
  272. if(_algo_sol.size() > 1)
  273. {
  274. double min_distance = 99999999999.0;
  275. point _p;
  276. for(auto it = _algo_sol.cbegin(); it != _algo_sol.cend(); ++it)
  277. {
  278. double d = (*it).m_triangle->get_distance(*((*it).m_pos));
  279. if(d < min_distance){
  280. min_distance = d;
  281. _p = *((*it).m_pos);
  282. sol.push_back(*((*it).m_pos));
  283. }
  284. }
  285. }else if(_algo_sol.size() == 1){
  286. sol.push_back(*(_algo_sol[0].m_pos));
  287. }
  288. return sol;
  289. }
  290. int loc_tool_tdoa_2_base::index()
  291. {
  292. return 4;
  293. }
  294. bool loc_tool_tdoa_2_base::is_in_triangle(const std::vector<point>& vps, const point& p)
  295. {
  296. double sabc = 0.0, sadb = 0.0, sbdc = 0.0, sadc = 0.0;
  297. sabc = get_triangle_area(vps[0], vps[1], vps[2]);
  298. sadb = get_triangle_area(vps[0], p, vps[1]);
  299. sbdc = get_triangle_area(vps[1], p, vps[2]);
  300. sadc = get_triangle_area(vps[0], p, vps[2]);
  301. double sum = sadb + sbdc + sadc;
  302. if((sabc - sum) > 1E-5 && (sabc - sum) < 1E-5){
  303. return true;
  304. }else{
  305. return false;
  306. }
  307. return false;
  308. }
  309. double loc_tool_tdoa_2_base::get_triangle_area(const point& p0,const point& p1, const point& p2)
  310. {
  311. return abs((p1.x - p0.x)*(p2.y - p1.y) - (p1.y - p0.y)*(p2.x - p1.x))/2.0;
  312. }
  313. // tdoa一维定位
  314. std::vector<point> loc_tool_tdoa_1_base::calc_location(std::vector<loc_message>& locm)
  315. {
  316. return std::vector<point>();
  317. }
  318. int loc_tool_tdoa_1_base::index()
  319. {
  320. return 3;
  321. }
  322. // tof三维定位
  323. std::vector<point> loc_tool_tof_3_base::calc_location(std::vector<loc_message>&locm)
  324. {
  325. return std::vector<point>();
  326. }
  327. int loc_tool_tof_3_base::index()
  328. {
  329. return 2;
  330. }
  331. // tof二维定位
  332. std::vector<point> loc_tool_tof_2_base::calc_location(std::vector<loc_message>&locm)
  333. {
  334. return std::vector<point>();
  335. }
  336. int loc_tool_tof_2_base::index()
  337. {
  338. return 1;
  339. }
  340. // tof一维定位
  341. std::vector<point> loc_tool_tof_1_base::calc_location(std::vector<loc_message>&locm)
  342. {
  343. int32_t last_ct = -1;
  344. std::vector<point> vec;
  345. std::vector<loc_message> lm;
  346. for(auto rit = locm.rbegin();rit != locm.rend();rit++)
  347. {
  348. if(rit->m_sit->is_path_empty() || rit->m_num_ticks == 0)
  349. continue;
  350. if(last_ct == -1)
  351. last_ct = rit->m_card_ct;
  352. else if(last_ct != rit->m_card_ct)
  353. continue;
  354. double dist_tof=rit->m_num_ticks*15.65*2.996*1e-4/rit->m_sit->m_scale;
  355. auto v = rit->m_sit->solving(rit->m_ant_id, dist_tof);
  356. lm.insert(lm.begin(),*rit);
  357. vec.insert(std::end(vec),std::begin(v),std::end(v));
  358. }
  359. locm.swap(lm);
  360. return std::move(vec);
  361. }
  362. int loc_tool_tof_1_base::index()
  363. {
  364. return 0;
  365. }
  366. loc_tool_main::loc_tool_main()
  367. {
  368. set_tool(new loc_tool_tof_1_base());
  369. set_tool(new loc_tool_tof_2_base());
  370. set_tool(new loc_tool_tof_3_base());
  371. set_tool(new loc_tool_tdoa_1_base());
  372. set_tool(new loc_tool_tdoa_2_base());
  373. set_tool(new loc_tool_tdoa_3_base());
  374. set_tool(new loc_tool_pdoa_1_base());
  375. set_tool(new loc_tool_pdoa_2_base());
  376. set_tool(new loc_tool_pdoa_3_base());
  377. }
  378. loc_tool_main::~loc_tool_main()
  379. {
  380. for(auto&tool:g_tool)
  381. delete tool;
  382. }
  383. void loc_tool_main::set_tool(loc_tool*tool)
  384. {
  385. int index = tool->index();
  386. if(g_tool[index])
  387. {
  388. delete g_tool[index];
  389. g_tool[index]=0;
  390. }
  391. g_tool[index] = tool;
  392. }
  393. std::vector<point> loc_tool_main::calc_location(std::vector<loc_message>&locm)
  394. {
  395. if(locm.empty())
  396. {
  397. return {};
  398. }
  399. int tool_index = locm[0].tool_index();
  400. /*int i = 1, len = locm.size();
  401. for(; i < len; ++i)
  402. {
  403. if(tool_index != locm[i].tool_index())
  404. break;
  405. }*/
  406. uint8_t type = tool_index>>4;
  407. uint8_t dim = tool_index & 0x03;
  408. tool_index = type*3 + dim - 1;
  409. log_info("[algo] loc_tool, tool_index=%d, loc_type=%d, dimension=%d", tool_index, type, dim);
  410. // 调用对应的算法进行定位计算
  411. //if(i==len)
  412. {
  413. return std::move(g_tool[tool_index]->calc_location(locm));
  414. }
  415. //包含至少两种定位方式的基站,目前只考虑两种
  416. /*std::vector<loc_message> locm1,locm2;
  417. locm1.assign(locm.begin(),locm.begin()+i);
  418. for(;i<len;i++)
  419. {
  420. if(tool_index!=locm[i].tool_index())
  421. locm2.push_back(locm[i]);
  422. else
  423. locm1.push_back(locm[i]);
  424. }
  425. bool flag = false;
  426. if(locm2[0].tool_index() > tool_index)
  427. flag = true;
  428. std::vector<point> rc;
  429. if(flag && (locm2[0].m_sit->config().best_msg_cnt<=(int)locm2.size()))
  430. {
  431. int index=locm2[0].tool_index();
  432. rc = std::move(g_tool[index]->calc_location(locm2));
  433. locm.swap(locm2);
  434. }
  435. else if(locm1[0].m_sit->config().best_msg_cnt<=(int)locm1.size())
  436. {
  437. rc = std::move(g_tool[tool_index]->calc_location(locm1));
  438. locm.swap(locm1);
  439. }
  440. return std::move(rc);*/
  441. }
  442. loc_tool* loc_tool_main::g_tool[9]={0,0,0,0,0,0,0,0,0};