loc_tool.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. #include <vector>
  2. #include <map>
  3. #include <log.h>
  4. #include <ant.h>
  5. #include <loc_tool.h>
  6. #include <message.h>
  7. #include "loc_common.h"
  8. #include <Eigen/Core>
  9. #include <Eigen/Dense>
  10. #include "ya_setting.h"
  11. #include "../server/common_tool.h"
  12. #include "../server/websocket/ws_common.h"
  13. #include "../server/tool_time.h"
  14. #include "../server/websocket/wsTimerThread.h"
  15. #include "../server/db/db_tool.h"
  16. // pdoa三维定位
  17. std::vector<point> loc_tool_pdoa_3_base::calc_location(std::vector<loc_message>& loc)
  18. {
  19. return std::vector<point>();
  20. }
  21. int loc_tool_pdoa_3_base::index()
  22. {
  23. return 8;
  24. }
  25. // pdoa二维定位
  26. std::vector<point> loc_tool_pdoa_2_base::calc_location(std::vector<loc_message>& loc)
  27. {
  28. if( 1 > loc.size())
  29. {
  30. logn_info(3, "[pdoa] loc_tool_pdoa_2_base::calc_location, the nums of location data is less than 2");
  31. return std::vector<point>();
  32. }
  33. logn_info(3, "[pdoa] loc_tool_pdoa_2_base::calc_location, loc.size=%d", loc.size());
  34. std::vector<pdoa_msg_ptr> vps;
  35. for(auto it = loc.begin(); it != loc.end(); ++it)
  36. {
  37. double d = (*it).m_num_ticks*15.65*2.996*1e-4;
  38. double angle = (*it).m_sit->m_ant[(*it).m_ant_id].m_angle;
  39. double x = (*it).m_sit->m_ant[(*it).m_ant_id].x;
  40. double y = (*it).m_sit->m_ant[(*it).m_ant_id].y;
  41. double p = (*it).get_pdoa(0);
  42. 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);
  43. pdoa_param pp(p, d, angle, x, y);
  44. if(!cal_position_pdoa(vps, pp)){
  45. break;
  46. }
  47. }
  48. if(2 > vps.size()){
  49. logn_info(3, "[pdoa] solutions too less, size=%d", vps.size());
  50. return std::vector<point>();
  51. }
  52. for(auto it = vps.cbegin();it != vps.cend(); ++it){
  53. logn_info(3, "[pdoa] possible solution: x=%.4f, y=%.4f", (*it)->x, (*it)->y);
  54. }
  55. pdoa_msg_ptr p_msg;
  56. std::size_t count = vps.size();
  57. if(count <= 0){
  58. return std::vector<point>();
  59. }
  60. for(std::size_t i = 0; i < count; ++i){
  61. if(vps[i]->y > 0){
  62. p_msg = vps[i];
  63. p_msg->x /= loc[0].m_sit->m_scale;
  64. p_msg->y /= loc[0].m_sit->m_scale;
  65. }
  66. }
  67. double _angle = 3.1415926*p_msg->angle/180.0;
  68. double x = p_msg->x_ant + p_msg->x*cos(_angle) - p_msg->y*sin(_angle);
  69. double y = p_msg->y_ant + p_msg->x*sin(_angle) + p_msg->y*cos(_angle);
  70. 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);
  71. std::vector<point> vp;
  72. vp.push_back(point(x, y));
  73. return vp;
  74. }
  75. int loc_tool_pdoa_2_base::index()
  76. {
  77. return 7;
  78. }
  79. /*
  80. * 计算pdoa定位坐标,并将定位结果保存在vps内
  81. *
  82. */
  83. bool loc_tool_pdoa_2_base::cal_position_pdoa(std::vector<pdoa_msg_ptr>& vps, const pdoa_param& pa)
  84. {
  85. float b = 0.075;
  86. float d = 0.5*b;
  87. float p = pa.pdoa*b / (2.0*3.1415926);
  88. logn_info(3,"[pdoa] before adjust, p = %.4f, pdoa=%.4f", p, pa.pdoa);
  89. p = -2919.8*pow(p, 4.0) - 88.74*pow(p, 3.0) + 5.6182*p*p + 1.1041*p - 0.00079884;
  90. //p = -0.0222*pow(p, 4.0) + 0.0328*pow(p, 3.0) + 0.0729*p*p + 0.854*p + 0.0111;
  91. //p *= 0.01;
  92. float alpha = p / d;
  93. if(fabs(alpha) > 1.0){
  94. logn_info(3, "[pdoa] p>d, alpha=%.4f, p=%.4f, d=%.4f", alpha, p , d);
  95. return false;
  96. }
  97. //double x = (d*d + 2*pa.r*p - p*p) / (2*d);
  98. //double y = (pa.r - 0.5*p)*sqrt(1.0 - (p/d)*(p/d));
  99. double angle = acos(alpha)*180/3.14;
  100. logn_info(3, "[pdoa] angle=%.2f, distance=%.2f", angle, pa.r);
  101. double x = d / 2.0 + alpha*(pa.r - p / 2.0);
  102. double y = (pa.r - 0.5*p)*sqrt(1.0 - alpha*alpha);
  103. 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);
  104. vps.push_back(std::make_shared<pdoa_message>(x, y, pa.a, pa.r, pa.ax, pa.ay, pa.pdoa, angle));
  105. vps.push_back(std::make_shared<pdoa_message>(x, -y, pa.a, pa.r, pa.ax, pa.ay, pa.pdoa, angle));
  106. return true;
  107. }
  108. // pdoa一维定位
  109. std::vector<point> loc_tool_pdoa_1_base::calc_location(std::vector<loc_message>& loc)
  110. {
  111. //logn_info(3, "[pdoa] loc_tool_pdoa_1_base::calc_location, card_id=%d, loc.size=%d", loc[0].m_card_id, loc.size());
  112. int32_t last_ct = -1;
  113. std::vector<point> vc;
  114. std::vector<loc_message> lm;
  115. for(auto rit = loc.rbegin(); rit != loc.rend(); ++rit){
  116. if(rit->m_sit->is_path_empty() || rit->m_num_ticks <= 0){
  117. continue;
  118. }
  119. if(-1 == last_ct){
  120. last_ct = rit->m_card_ct;
  121. }
  122. double dist_tof = rit->m_num_ticks*15.65*2.996*1e-4/rit->m_sit->m_scale;
  123. auto v = rit->m_sit->solving_pdoa(rit->m_ant_id, dist_tof);
  124. lm.insert(lm.begin(), *rit);
  125. vc.insert(std::end(vc), std::begin(v), std::end(v));
  126. }
  127. loc.swap(lm);
  128. return std::move(vc);
  129. }
  130. int loc_tool_pdoa_1_base::index()
  131. {
  132. return 6;
  133. }
  134. // tdoa三维定位
  135. std::vector<point> loc_tool_tdoa_3_base::calc_location(std::vector<loc_message>& loc)
  136. {
  137. return std::vector<point>();
  138. }
  139. int loc_tool_tdoa_3_base::index()
  140. {
  141. return 5;
  142. }
  143. // tdoa二维定位
  144. std::vector<point> loc_tool_tdoa_2_base::calc_location(std::vector<loc_message>& locm)
  145. {
  146. if(locm.size() < 3){
  147. return std::vector<point>();
  148. }
  149. std::vector<point> sol; // 解的列表,返回值
  150. sol.resize(0);
  151. std::vector<algo_solution> _algo_sol;
  152. _algo_sol.resize(0);
  153. std::vector<double> vtk; // 保存ki
  154. std::vector<double> vtd; // 保存di
  155. std::vector<point> vtc; // 保存xi,1 yi,1
  156. std::vector<point> vtp; // 保存三角形的顶点坐标
  157. std::vector<int> vts;
  158. vtk.resize(0);
  159. vtd.resize(0);
  160. vtc.resize(0);
  161. vtp.resize(0);
  162. vts.resize(0);
  163. // 保存卡数据中第一条的分站坐标和插值时间
  164. point fp;
  165. unsigned long long fts = 0;
  166. double _height_offset = 0.0;
  167. if (true)
  168. {
  169. //按时间戳进行排序
  170. std::multimap< uint64_t, loc_message> map_sort_msg;
  171. for (auto iter = locm.begin(); iter != locm.end(); ++iter)
  172. {
  173. map_sort_msg.insert(std::make_pair(iter->m_num_ticks, *iter));
  174. }
  175. locm.clear();
  176. for (auto iter = map_sort_msg.begin(); iter != map_sort_msg.end(); ++iter)
  177. {
  178. locm.push_back(iter->second);
  179. }
  180. }
  181. loc_message datas[3];
  182. for(auto iter0 = locm.begin(); iter0 != locm.end(); ++iter0)
  183. {
  184. for(auto iter1 = iter0 + 1; iter1 != locm.end(); ++iter1)
  185. {
  186. for(auto iter2 = iter1 + 1; iter2 != locm.end(); ++iter2)
  187. {
  188. vtk.clear();
  189. vtd.clear();
  190. vtc.clear();
  191. vts.clear();
  192. vtp.clear();
  193. datas[0] = *(iter0);
  194. datas[1] = *(iter1);
  195. datas[2] = *(iter2);
  196. bool hasInvalidValue = false;
  197. for (int i = 0; i < 3; ++i)
  198. {
  199. if (datas[i].m_num_ticks == LONGLONG_MAX)
  200. {
  201. hasInvalidValue = true;
  202. }
  203. }
  204. if (hasInvalidValue)
  205. {
  206. continue;
  207. }
  208. bool bContinue = false;
  209. for(int i = 0; i < 3; ++i)
  210. {
  211. double k = 0.0;
  212. k = pow(datas[i].m_sit->x, 2) + pow(datas[i].m_sit->y, 2);
  213. vtk.push_back(k);
  214. if(i == 0)
  215. {
  216. fts = datas[i].m_num_ticks;
  217. fp.x = datas[i].m_sit->x;
  218. fp.y = datas[i].m_sit->y;
  219. vtd.push_back(0.0);
  220. }else{
  221. long long diff_time = datas[i].m_num_ticks - fts;
  222. double d = diff_time* DWT_TIME_UNITS * SPEED_OF_LIGHT;
  223. if(d > 0){
  224. vts.push_back(1);
  225. }else{
  226. vts.push_back(-1);
  227. }
  228. vtd.push_back(d);
  229. }
  230. vtc.push_back(point(datas[i].m_sit->x - fp.x, datas[i].m_sit->y - fp.y));
  231. vtp.push_back(point(datas[i].m_sit->x, datas[i].m_sit->y));
  232. }
  233. double a[4] = {0};
  234. double dt = vtd[1]*vtc[2].y - vtd[2]*vtc[1].y;
  235. if (fabs(dt) < 1E-5 || fabs(vtd[1]) < 1E-5) {
  236. continue;
  237. }
  238. a[0] = (vtd[2]*vtc[1].x - vtd[1]*vtc[2].x)/dt;
  239. 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;
  240. a[2] = 0.5*(vtk[1] - vtk[0] - pow(vtd[1],2) - 2*vtc[1].y*a[1]) / vtd[1];
  241. a[3] = -1*(vtc[1].x + vtc[1].y*a[0]) / vtd[1];
  242. double A = 0.0, B = 0.0, C = 0.0;
  243. A = pow(a[3], 2) - 1 - pow(a[0], 2);
  244. B = 2*(a[2]*a[3] + fp.x + a[0]*(fp.y - a[1]));
  245. C = pow(a[2], 2) - pow(fp.x, 2) - pow(fp.y - a[1], 2) - pow(_height_offset, 2);
  246. std::vector<point> _vp;
  247. double delta = pow(B, 2) - 4*A*C;
  248. if(delta > 0){
  249. point p;
  250. p.x = ((-1.0)*B + sqrt(delta))/(2.0*A);
  251. p.y = a[0]*p.x + a[1];
  252. _vp.push_back(p);
  253. p.x = ((-1)*B - sqrt(delta))/(2.0*A);
  254. p.y = a[0]*p.x + a[1];
  255. _vp.push_back(p);
  256. }else{
  257. continue;
  258. }
  259. int idx = -1;
  260. for(std::size_t i = 0; i < _vp.size(); ++i)
  261. {
  262. bool cond[2] = { false };
  263. // 对两个解进行判断,需要同时满足两个条件:
  264. // 1.解到点1和点2的距离差的方向性和之前的参数相同
  265. // 2.解到点1和点3的距离差的方向性和之前的参数相同
  266. 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));
  267. 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));
  268. if((d1 < 0 && vts[0] == -1) || (d1 > 0 && vts[0] == 1))
  269. {
  270. cond[0] = true;
  271. }
  272. if((d2 < 0 && vts[1] == -1) || (d2 > 0 && vts[1] == 1))
  273. {
  274. cond[1] = true;
  275. }
  276. if(cond[0] && cond[1]){
  277. idx = i;
  278. }
  279. }
  280. // 判断求出的解是否在基站构成的三角形内
  281. if(idx != -1){
  282. if(is_in_triangle(vtp, _vp[idx]))
  283. {
  284. _vp[idx].site1 = datas[0].m_sit->id();
  285. _vp[idx].site2 = datas[1].m_sit->id();
  286. _vp[idx].site3 = datas[2].m_sit->id();
  287. sol.push_back(_vp[idx]);
  288. algo_solution _as;
  289. _as.m_pos = std::make_shared<point>(_vp[idx]);
  290. _as.m_triangle = std::make_shared<triangle>();
  291. site_point _sp(point(datas[0].m_sit->x, datas[0].m_sit->y));
  292. _sp.m_site_id = datas[0].m_sit->m_id;
  293. _as.m_triangle->m_vertex.push_back(std::move(_sp));
  294. site_point _sp1(point(datas[1].m_sit->x, datas[1].m_sit->y));
  295. _sp1.m_site_id = datas[1].m_sit->m_id;
  296. _as.m_triangle->m_vertex.push_back(std::move(_sp1));
  297. site_point _sp2(point(datas[2].m_sit->x, datas[2].m_sit->y));
  298. _sp2.m_site_id = datas[2].m_sit->m_id;
  299. _as.m_triangle->m_vertex.push_back(std::move(_sp2));
  300. _algo_sol.push_back(_as);
  301. }
  302. else{
  303. _vp[idx].site1 = datas[0].m_sit->id();
  304. _vp[idx].site2 = datas[1].m_sit->id();
  305. _vp[idx].site3 = datas[2].m_sit->id();
  306. sol.push_back(_vp[idx]);
  307. }
  308. }
  309. else
  310. {
  311. if (_vp.size() > 0)
  312. {
  313. _vp[0].site1 = datas[0].m_sit->id();
  314. _vp[0].site2 = datas[1].m_sit->id();
  315. _vp[0].site3 = datas[2].m_sit->id();
  316. sol.push_back(_vp[0]);
  317. }
  318. }
  319. }
  320. }
  321. }
  322. bool bSelect = true;
  323. /*if (CYaSetting::m_sys_setting.mp_sid_solution.find(4) != CYaSetting::m_sys_setting.mp_sid_solution.end())
  324. {
  325. int nSolution = CYaSetting::m_sys_setting.mp_sid_solution[4];
  326. if (nSolution != 0)
  327. {
  328. bSelect = false;
  329. }
  330. }*/
  331. if (bSelect)
  332. {
  333. // 如果有多于1个的解,
  334. // 需要计算该解到其对应三角形质心的距离,
  335. // 然后根据这个距离排序,选择距离最小的解
  336. if (_algo_sol.size() > 1)
  337. {
  338. double min_distance = 99999999999.0;
  339. point _p;
  340. for (auto it = _algo_sol.cbegin(); it != _algo_sol.cend(); ++it)
  341. {
  342. double d = (*it).m_triangle->get_distance(*((*it).m_pos));
  343. if (d < min_distance) {
  344. min_distance = d;
  345. _p = *((*it).m_pos);
  346. sol.clear();
  347. sol.push_back(*((*it).m_pos));
  348. }
  349. }
  350. }
  351. else if (_algo_sol.size() == 1) {
  352. sol.clear();
  353. sol.push_back(*(_algo_sol[0].m_pos));
  354. }
  355. }
  356. return sol;
  357. }
  358. int loc_tool_tdoa_2_base::index()
  359. {
  360. return 4;
  361. }
  362. bool loc_tool_tdoa_2_base::is_in_triangle(const std::vector<point>& vps, const point& p)
  363. {
  364. double sabc = 0.0, sadb = 0.0, sbdc = 0.0, sadc = 0.0;
  365. sabc = get_triangle_area(vps[0], vps[1], vps[2]);
  366. sadb = get_triangle_area(vps[0], p, vps[1]);
  367. sbdc = get_triangle_area(vps[1], p, vps[2]);
  368. sadc = get_triangle_area(vps[0], p, vps[2]);
  369. double sum = sadb + sbdc + sadc;
  370. if((sabc - sum) > -1E-5 && (sabc - sum) < 1E-5){
  371. return true;
  372. }else{
  373. return false;
  374. }
  375. return false;
  376. }
  377. double loc_tool_tdoa_2_base::get_triangle_area(const point& p0,const point& p1, const point& p2)
  378. {
  379. return std::abs((p1.x - p0.x)*(p2.y - p1.y) - (p1.y - p0.y)*(p2.x - p1.x))/2.0;
  380. }
  381. // tdoa一维定位
  382. std::vector<point> loc_tool_tdoa_1_base::calc_location(std::vector<loc_message>& locm)
  383. {
  384. return std::vector<point>();
  385. }
  386. int loc_tool_tdoa_1_base::index()
  387. {
  388. return 3;
  389. }
  390. // tof 三基站三维定位
  391. std::vector<point> loc_tool_tof_3_base::calc_location(std::vector<loc_message>&locm)
  392. {
  393. std::vector<point> vtp;
  394. std::vector< sys::tof_data_oneAntenna> vec_td;
  395. std::string now = tool_time::to_str_ex(tool_time::now_to_ms());
  396. int index = 0;
  397. sys::tof_data_oneAntenna td;
  398. for (auto iter = locm.begin(); iter != locm.end(); iter++, index++)
  399. {
  400. // 更新数据到发送线程
  401. //if (iter->m_sit->m_id != 169)
  402. {
  403. td.map_site_id_dist[iter->m_sit->m_id] = iter->m_num_ticks*15.65*2.996*1e-4 + iter->m_sit->m_tof_dist_offset;
  404. }
  405. td.cid = tool_other::type_id_to_str(iter->m_card_type, iter->m_card_id);
  406. td.cur_time = now;
  407. }
  408. vec_td.push_back(td);
  409. //swsTimerThrd.upt_tof_data_oneAntenna(vec_td);
  410. // if (false)
  411. // {
  412. // // 数据入库
  413. // char sql[1024] = { 0 };
  414. // snprintf(sql,
  415. // 1024,
  416. // "insert into his_raw_data_card_tof_multi_site(card_id, distance1, site_id1, distance2, site_id2, distance3, site_id3, cur_time) values('%s', %.2f, %d, %.2f, %d, %.2f, %d, '%s')",
  417. // td.cid.c_str(),
  418. // td.dist1,
  419. // td.sid1,
  420. // td.dist2,
  421. // td.sid2,
  422. // td.dist3,
  423. // td.sid3,
  424. // now.c_str()
  425. // );
  426. // db_tool::PushAsync(sql);
  427. // log_info("[sql] %s", sql);
  428. // }
  429. std::vector<point> vts;
  430. std::vector<double> vtd;
  431. for(size_t i = 0;i < locm.size();++i){
  432. double dist = locm[i].m_num_ticks*15.65*2.996*1e-4;
  433. log_info("dist_%d:%.2f", i, dist);
  434. vtd.push_back(dist);
  435. vts.push_back(point(locm[i].m_sit->x, locm[i].m_sit->y, locm[i].m_sit->z));
  436. log_info("site_%d:x:%.2f,y:%.2f,z:%.2f", i, locm[i].m_sit->x, locm[i].m_sit->y, locm[i].m_sit->z);
  437. }
  438. // 准备A矩阵的元素值
  439. double X10 = 2*(vts[1].x - vts[0].x);
  440. double X20 = 2*(vts[2].x - vts[0].x);
  441. double Y10 = 2*(vts[1].y - vts[0].y);
  442. double Y20 = 2*(vts[2].y - vts[0].y);
  443. double Z10 = 2*(vts[1].z - vts[0].z);
  444. double Z20 = 2*(vts[2].z - vts[0].z);
  445. // 准备B矩阵元素值
  446. double R0 = vts[0].value();
  447. double R1 = vts[1].value();
  448. double R2 = vts[2].value();
  449. double B10 = vtd[0]*vtd[0] - vtd[1]*vtd[1] + R1 - R0;
  450. double B20 = vtd[0]*vtd[0] - vtd[2]*vtd[2] + R2 - R0;
  451. // 构造A矩阵和B矩阵
  452. Eigen::Matrix<double, 2, 3> A;
  453. A << X10, Y10, Z10,
  454. X20, Y20, Z20;
  455. Eigen::Matrix<double, 2, 1> B;
  456. B << B10,
  457. B20;
  458. Eigen::Vector3d X = A.colPivHouseholderQr().solve(B);
  459. double x = 0.0, y = 0.0;
  460. x = X[0];
  461. y = X[1];
  462. // 将x,y代入园方程求解z坐标 ax*x + b*x + c = 0
  463. double a = 1;
  464. double b = -2* vts[0].z;
  465. double c = vts[0].z * vts[0].z - vtd[0]*vtd[0] + (x - vts[0].x)*(x - vts[0].x) + (y - vts[0].y)*(y - vts[0].y);
  466. double z0 = (-1*b + sqrt(b*b - 4*a*c))/(2*a);
  467. double z1 = (-1*b - sqrt(b*b - 4*a*c))/(2*a);
  468. vtp.push_back(point(x, y, z0));
  469. vtp.push_back(point(x, y, z1));
  470. return std::move(vtp);
  471. }
  472. int loc_tool_tof_3_base::index()
  473. {
  474. return 2;
  475. }
  476. // tof二维定位
  477. std::vector<point> loc_tool_tof_2_base::calc_location(std::vector<loc_message>&locm)
  478. {
  479. std::vector<point> vtp;
  480. std::vector< sys::tof_data_oneAntenna> vec_td;
  481. std::string now = tool_time::to_str_ex(tool_time::now_to_ms());
  482. int index = 0;
  483. sys::tof_data_oneAntenna td;
  484. for (auto iter = locm.begin(); iter != locm.end(); iter++, index++)
  485. {
  486. // 更新数据到发送线程
  487. //if (iter->m_sit->m_id != 169)
  488. {
  489. td.map_site_id_dist[iter->m_sit->m_id] = iter->m_num_ticks*15.65*2.996*1e-4 + iter->m_sit->m_tof_dist_offset;
  490. }
  491. td.cid = tool_other::type_id_to_str(iter->m_card_type, iter->m_card_id);
  492. td.cur_time = now;
  493. }
  494. vec_td.push_back(td);
  495. swsTimerThrd.upt_tof_data_oneAntenna(vec_td);
  496. // if (false)
  497. // {
  498. // // 数据入库
  499. // char sql[1024] = { 0 };
  500. // snprintf(sql,
  501. // 1024,
  502. // "insert into his_raw_data_card_tof_multi_site(card_id, distance1, site_id1, distance2, site_id2, distance3, site_id3, cur_time) values('%s', %.2f, %d, %.2f, %d, %.2f, %d, '%s')",
  503. // td.cid.c_str(),
  504. // td.dist1,
  505. // td.sid1,
  506. // td.dist2,
  507. // td.sid2,
  508. // td.dist3,
  509. // td.sid3,
  510. // now.c_str()
  511. // );
  512. // db_tool::PushAsync(sql);
  513. // log_info("[sql] %s", sql);
  514. // }
  515. std::vector<point> vts;
  516. std::vector<double> vtd;
  517. for (size_t i = 0; i < locm.size(); ++i) {
  518. double dist = locm[i].m_num_ticks*15.65*2.996*1e-4;
  519. log_info("dist_%d:%.2f", i, dist);
  520. vtd.push_back(dist);
  521. vts.push_back(point(locm[i].m_sit->x, locm[i].m_sit->y, locm[i].m_sit->z));
  522. log_info("site_%d:x:%.2f,y:%.2f,z:%.2f", i, locm[i].m_sit->x, locm[i].m_sit->y, locm[i].m_sit->z);
  523. }
  524. return std::vector<point>();
  525. }
  526. int loc_tool_tof_2_base::index()
  527. {
  528. return 1;
  529. }
  530. // tof一维定位
  531. std::vector<point> loc_tool_tof_1_base::calc_location(std::vector<loc_message>&locm)
  532. {
  533. int32_t last_ct = -1;
  534. std::vector<point> vec;
  535. std::vector<loc_message> lm;
  536. std::string now = tool_time::to_str_ex(tool_time::now_to_ms());
  537. std::unordered_map <std::string, sys::tof_data> map_tof_data;
  538. for(auto rit = locm.rbegin();rit != locm.rend();rit++)
  539. {
  540. auto cid = tool_other::type_id_to_str(rit->m_card_type, rit->m_card_id);
  541. if(rit->m_sit->is_path_empty() || rit->m_num_ticks == 0)
  542. continue;
  543. if(last_ct == -1)
  544. last_ct = rit->m_card_ct;
  545. else if(last_ct != rit->m_card_ct)
  546. continue;
  547. double dist_tof = rit->m_num_ticks*15.65*2.996*1e-4;
  548. map_tof_data[cid].cid = cid;
  549. map_tof_data[cid].sid = rit->m_sit->m_id;
  550. map_tof_data[cid].cur_time = now;
  551. map_tof_data[cid].ant_dist[rit->m_ant_id] = dist_tof;
  552. if (map_tof_data[cid].ant_dist[0] != 0 &&
  553. map_tof_data[cid].ant_dist[1] != 0)
  554. {
  555. rit->m_sit->count_ant_dist(map_tof_data[cid].ant_dist[0], map_tof_data[cid].ant_dist[1]);
  556. }
  557. map_tof_data[cid].ant_diff = floor(rit->m_sit->m_ant_dist*10.0 + 0.5) / 10.0;
  558. auto v = rit->m_sit->solving(rit->m_ant_id, dist_tof);
  559. lm.insert(lm.begin(),*rit);
  560. vec.insert(std::end(vec),std::begin(v),std::end(v));
  561. // if (map_tof_data[cid].sid == 100)
  562. // {
  563. // return std::move(vec);
  564. // }
  565. }
  566. for (auto map_iter = map_tof_data.begin(); map_iter != map_tof_data.end(); map_iter++)
  567. {
  568. //swsTimerThrd.upt_tof_data(map_iter->second);
  569. if (map_iter->second.ant_dist[0] > map_iter->second.ant_dist[1] &&
  570. map_iter->second.ant_dist[0] + map_iter->second.ant_dist[1] > 2.5)
  571. {
  572. log_info("sended=%f", (map_iter->second.ant_dist[0] + map_iter->second.ant_dist[1]) / 2);
  573. }
  574. else if (map_iter->second.ant_dist[0] < map_iter->second.ant_dist[1] &&
  575. map_iter->second.ant_dist[0] + map_iter->second.ant_dist[1] > 2.2)
  576. {
  577. log_info("sended=%f", (map_iter->second.ant_dist[0] + map_iter->second.ant_dist[1]) / (-2));
  578. }
  579. else
  580. {
  581. log_info("sended=%f", (map_iter->second.ant_dist[0] - map_iter->second.ant_dist[1]) / 2);
  582. }
  583. std::vector< sys::tof_data_oneAntenna> vec_td;
  584. std::string now = tool_time::to_str_ex(tool_time::now_to_ms());
  585. sys::tof_data_oneAntenna td;
  586. // 更新数据到发送线程
  587. td.map_site_id_dist[map_iter->second.sid * 10 + 1] = map_iter->second.ant_dist[0];
  588. td.map_site_id_dist[map_iter->second.sid * 10 + 2] = map_iter->second.ant_dist[1];
  589. auto site_ptr1 = sit_list::instance()->get(map_iter->second.sid * 10 + 1);
  590. auto site_ptr2 = sit_list::instance()->get(map_iter->second.sid * 10 + 2);
  591. if (nullptr == site_ptr1 || nullptr == site_ptr2)
  592. {
  593. log_warn("[tof] 分站信息缺失");
  594. break;
  595. }
  596. double x1 = site_ptr1->x;
  597. double y1 = site_ptr1->y;
  598. double x2 = site_ptr2->x;
  599. double y2 = site_ptr2->y;
  600. double d1 = map_iter->second.ant_dist[0];
  601. double d2 = map_iter->second.ant_dist[1];
  602. double d = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
  603. double sin_a = (y2 - y1) / d;
  604. double cos_a = (x2 - x1) / d;
  605. int direction = 1;
  606. if (d2 > d&&d1 < d2)
  607. {
  608. direction = -1;
  609. }
  610. if (direction == -1)
  611. {
  612. double angle = asin(sin_a) * 180 / 3.1415 + site_ptr1->m_tof_dist_offset;
  613. sin_a = sin(angle*3.1415 / 180);
  614. cos_a = cos(angle*3.1415 / 180);
  615. }
  616. //else
  617. //{
  618. // double angle = asin(sin_a) * 180 / 3.1415 + site_ptr2->m_tof_dist_offset;
  619. // sin_a = sin(angle*3.1415 / 180);
  620. // cos_a = cos(angle*3.1415 / 180);
  621. //}
  622. log_info("zmg1x1=%f, y1=%f, cos_a=%f, sin_a=%f, d1=%f, direction=%d", (x1 + x2) / 2, (y1 + y2) / 2, cos_a, sin_a, d1, direction);
  623. double x = (x1+x2)/2 + cos_a * d1*direction;
  624. double y = (y1+y2)/2 + sin_a * d1*direction;
  625. td.x = x;
  626. td.y = y;
  627. // td.map_site_id_dist[]
  628. // td.dist1 = map_iter->second.ant_dist[0];
  629. // td.sid1 = map_iter->second.sid * 10 + 1;
  630. // td.dist2 = map_iter->second.ant_dist[1];
  631. // td.sid2 = map_iter->second.sid * 10 + 2;
  632. // td.dist3 = map_iter->second.ant_dist[1];
  633. // td.sid3 = 0;
  634. // td.dist4 = map_iter->second.ant_dist[1];
  635. // td.sid4 = 0;
  636. td.cid = map_iter->second.cid;
  637. td.cur_time = now;
  638. //zmg
  639. //if (td.cid == "0010000001002"|| td.cid == "0010000001004")
  640. {
  641. vec_td.push_back(td);
  642. // static int count = 0;
  643. // count++;
  644. // if (count >= 10)
  645. // {
  646. // swsTimerThrd.upt_tof_data_oneAntenna(vec_td);
  647. // count = 0;
  648. // }
  649. //static std::map<int, std::vector<int>> map_direction;
  650. //
  651. //auto directions = map_direction.find(td.cid);
  652. //
  653. //for (std::vector<int> iterDir = directions->second.begin();iterDir!= directions->second.end();iterDir++)
  654. //{
  655. //}
  656. swsTimerThrd.upt_tof_data_oneAntenna(vec_td);
  657. // // 数据入库
  658. // char sql[1024] = { 0 };
  659. // snprintf(sql,
  660. // 1024,
  661. // "insert into his_raw_data_card_tof_two_antenna(card_id, distance1, distance2, distanceAntennas, reader_id, cur_time) values('%s', %.2f, %.2f, %.2f, %d, '%s')",
  662. // td.cid.c_str(),
  663. // td.dist1,
  664. // td.dist2,
  665. // floor(locm.rbegin()->m_sit->m_ant_dist*10.0 + 0.5) / 10.0,
  666. // locm.rbegin()->m_sit->m_id,
  667. // now.c_str()
  668. // );
  669. // db_tool::PushAsync(sql);
  670. // log_info("[sql] %s", sql);
  671. }
  672. // if (false)
  673. // if (td.dist1 != 0 && td.dist2 != 0 && td.dist3 != 0 && td.dist4 != 0 && td.cid == "0010000001004")
  674. // {
  675. // double v = 0.15;
  676. // static double dis = 10;
  677. //
  678. // static bool down = true;
  679. //
  680. // if (dis < -10)
  681. // {
  682. // down = false;
  683. // }
  684. // else if (dis > 10)
  685. // {
  686. // down = true;
  687. // }
  688. //
  689. // if (down)
  690. // {
  691. // dis -= v;
  692. // }
  693. // else
  694. // {
  695. // dis += v;
  696. // }
  697. // unsigned seed;
  698. // seed = time(0);
  699. // srand(seed);
  700. // auto r = rand() % 20;
  701. // double d = (r - 10) / 100.0;
  702. // td.dist1 = fabs(dis - 1.05) + d;
  703. // td.dist2 = fabs(dis + 1.05) + d;
  704. // td.dist3 = td.dist2;
  705. // td.dist4 = td.dist2;
  706. // r = rand() % 20;
  707. // d = (r - 10) / 100.0;
  708. // vec_td.push_back(td);
  709. // swsTimerThrd.upt_tof_data_oneAntenna(vec_td);
  710. //
  711. // // 数据入库
  712. // char sql[1024] = { 0 };
  713. // snprintf(sql,
  714. // 1024,
  715. // "insert into his_raw_data_card_tof_two_antenna(card_id, distance1, distance2, distanceAntennas, reader_id, cur_time) values('%s', %.2f, %.2f, %.2f, %d, '%s')",
  716. // td.cid.c_str(),
  717. // td.dist1,
  718. // td.dist2,
  719. // floor(locm.rbegin()->m_sit->m_ant_dist*10.0 + 0.5) / 10.0,
  720. // locm.rbegin()->m_sit->m_id,
  721. // now.c_str()
  722. // );
  723. // db_tool::PushAsync(sql);
  724. // log_info("[sql] %s", sql);
  725. // }
  726. }
  727. locm.swap(lm);
  728. return std::move(vec);
  729. }
  730. int loc_tool_tof_1_base::index()
  731. {
  732. return 0;
  733. }
  734. loc_tool_main::loc_tool_main()
  735. {
  736. set_tool(new loc_tool_tof_1_base());
  737. set_tool(new loc_tool_tof_2_base());
  738. set_tool(new loc_tool_tof_3_base());
  739. set_tool(new loc_tool_tdoa_1_base());
  740. set_tool(new loc_tool_tdoa_2_base());
  741. set_tool(new loc_tool_tdoa_3_base());
  742. set_tool(new loc_tool_pdoa_1_base());
  743. set_tool(new loc_tool_pdoa_2_base());
  744. set_tool(new loc_tool_pdoa_3_base());
  745. }
  746. loc_tool_main::~loc_tool_main()
  747. {
  748. for(auto&tool:g_tool)
  749. delete tool;
  750. }
  751. void loc_tool_main::set_tool(loc_tool*tool)
  752. {
  753. int index = tool->index();
  754. if(g_tool[index])
  755. {
  756. delete g_tool[index];
  757. g_tool[index]=0;
  758. }
  759. g_tool[index] = tool;
  760. }
  761. std::vector<point> loc_tool_main::calc_location(std::vector<loc_message>&locm)
  762. {
  763. if(locm.empty())
  764. {
  765. return {};
  766. }
  767. int tool_index = locm[0].tool_index();
  768. /*int i = 1, len = locm.size();
  769. for(; i < len; ++i)
  770. {
  771. if(tool_index != locm[i].tool_index())
  772. break;
  773. }*/
  774. uint8_t type = tool_index>>4;
  775. uint8_t dim = tool_index & 0x03;
  776. tool_index = type*3 + dim - 1;
  777. log_info("[algo] loc_tool, tool_index=%d, loc_type=%d, dimension=%d", tool_index, type, dim);
  778. // 调用对应的算法进行定位计算
  779. //if(i==len)
  780. {
  781. return std::move(g_tool[tool_index]->calc_location(locm));
  782. }
  783. //包含至少两种定位方式的基站,目前只考虑两种
  784. /*std::vector<loc_message> locm1,locm2;
  785. locm1.assign(locm.begin(),locm.begin()+i);
  786. for(;i<len;i++)
  787. {
  788. if(tool_index!=locm[i].tool_index())
  789. locm2.push_back(locm[i]);
  790. else
  791. locm1.push_back(locm[i]);
  792. }
  793. bool flag = false;
  794. if(locm2[0].tool_index() > tool_index)
  795. flag = true;
  796. std::vector<point> rc;
  797. if(flag && (locm2[0].m_sit->config().best_msg_cnt<=(int)locm2.size()))
  798. {
  799. int index=locm2[0].tool_index();
  800. rc = std::move(g_tool[index]->calc_location(locm2));
  801. locm.swap(locm2);
  802. }
  803. else if(locm1[0].m_sit->config().best_msg_cnt<=(int)locm1.size())
  804. {
  805. rc = std::move(g_tool[tool_index]->calc_location(locm1));
  806. locm.swap(locm1);
  807. }
  808. return std::move(rc);*/
  809. }
  810. loc_tool* loc_tool_main::g_tool[9]={0,0,0,0,0,0,0,0,0};