select_tool.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  1. #include "select_tool.h"
  2. #include "ant.h"
  3. #include "card_path.h"
  4. #include "log.h"
  5. #include "card.h"
  6. #include "loc_common.h"
  7. //opt_tool_main select_point_object::m_opt_tool;
  8. void select_point_object::att_initiate()
  9. {
  10. m_fitk.add_tool(30,5,5);
  11. m_fitk.add_tool(30,5,6);
  12. m_fitk.add_tool(30,10,10);
  13. m_fitk.add_tool(30,10,15);
  14. m_fitk.add_tool(20,5,6);
  15. m_fitk.add_tool(30,4,6);
  16. m_fitk.add_tool(40,4,6);
  17. m_fita.add_tool(15,5,5);
  18. m_begin=m_last=0;
  19. }
  20. //
  21. int select_point_object::select_max_solution(const float& lhs, const float& rhs, const std::vector<point> vp, loc_point& lp)
  22. {
  23. if(lhs > rhs){
  24. lp.set(vp[0]);
  25. return 0;
  26. }else{
  27. lp.set(vp[1]);
  28. return 1;
  29. }
  30. }
  31. //
  32. int select_point_object::select_min_solution(const float& lhs, const float& rhs, const std::vector<point> vp, loc_point& lp)
  33. {
  34. if(lhs < rhs){
  35. lp.set(vp[0]);
  36. return 0;
  37. }else{
  38. lp.set(vp[1]);
  39. return 1;
  40. }
  41. }
  42. loc_point select_point_object::select_solution_impl(const std::vector<point> vp,const std::vector<loc_message>&lm)
  43. {
  44. bool flag = false;
  45. loc_point lp;
  46. //如果1维pdoa定位
  47. logn_info(3, "select_solution_impl status, dims=%d, loc_type=%d, vp's size=%d", lm[0].m_sit->m_num_dims, lm[0].m_loc_type, vp.size());
  48. switch(lm[0].m_loc_type){
  49. case LDT_TOF:
  50. if(vp.size()==4)
  51. {
  52. m_d.grow().reset().set_source(lm[0],lm[1]);
  53. flag = true;
  54. }
  55. if(vp.size()==2 && lm[0].m_card_ct - last_ct() == 1)
  56. {
  57. m_d.grow().reset().set_source(lm[0]);
  58. flag = true;
  59. }
  60. if(flag)
  61. {
  62. if(!select_solution(vp,lm[0].m_sit.get(),lp))
  63. {
  64. m_cur_fit.reset();
  65. }
  66. }
  67. break;
  68. case LDT_PDOA:
  69. select_pdoa_solution_impl(vp, lm, lp);
  70. break;
  71. }
  72. m_ct = lm[0].m_card_ct;
  73. return lp;
  74. }
  75. bool select_point_object::select_pdoa_solution_impl(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point& lp)
  76. {
  77. switch(get_algo_index(lm[0].tool_index())){
  78. case 6:
  79. if(lm[0].m_sync_ct){
  80. return select_pdoa_1d_solution_original(vp, lm, lp);
  81. }else{
  82. return select_pdoa_1d_solution(vp, lm, lp);
  83. }
  84. break;
  85. case 7:
  86. return select_pdoa_2d_solution(vp, lm, lp);
  87. break;
  88. case 8:
  89. return select_pdoa_3d_solution(vp, lm, lp);
  90. break;
  91. }
  92. return false;
  93. }
  94. /*
  95. * 当下井方向选解策略
  96. *
  97. * */
  98. bool select_point_object::select_pdoa_solution(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point&lp, const float& pdoa)
  99. {
  100. if(1 == vp.size())
  101. {
  102. bool dir = (pdoa > EPS);
  103. logn_info(3,"[pdoa] card_id=%d, ct=%d, vp0x=%.4f, vp0y=%.4f", lm[0].m_card_id, lm[0].m_card_ct, vp[0].x, vp[0].y);
  104. if(lm[0].m_sit->m_ant[0].x == lm[0].m_sit->m_ant[1].x)
  105. {
  106. if(0 == lm[0].m_sit->m_pdoa_direction){
  107. if(dir){
  108. if(vp[0].x > lm[0].m_sit->m_ant[0].x){
  109. lp.set(vp[0]);
  110. lp.m_useless = true;
  111. }else{
  112. logn_warn(3, "[pdoa] solution is not correct, card_id=%d", lm[0].m_card_id);
  113. lp.m_useless = false;
  114. }
  115. }else{
  116. if(vp[0].x < lm[0].m_sit->m_ant[0].x){
  117. lp.set(vp[0]);
  118. lp.m_useless = true;
  119. }else{
  120. logn_warn(3, "[pdoa] solution is not correct, card_id=%d", lm[0].m_card_id);
  121. lp.m_useless = false;
  122. }
  123. }
  124. }else{
  125. if(dir){
  126. if(vp[0].x < lm[0].m_sit->m_ant[0].x){
  127. lp.set(vp[0]);
  128. lp.m_useless = true;
  129. }else{
  130. lp.m_useless = false;
  131. }
  132. }else{
  133. if(vp[0].x > lm[0].m_sit->m_ant[0].x){
  134. lp.set(vp[0]);
  135. lp.m_useless = true;
  136. }else{
  137. lp.m_useless = false;
  138. }
  139. }
  140. }
  141. }else{
  142. logn_info(3, "[pdoa] select one solution, card_id=%d", lm[0].m_card_id);
  143. if(dir){
  144. }
  145. }
  146. return lp.m_useless;
  147. }else if(2 == vp.size()){
  148. // select one solution from two solution by reader and phase direction
  149. logn_info(3, "[pdoa] select one solution from 2, card_id=%d, ct=%d, site_dir=%d, vp0x=%.4f, vp0y=%.4f, vp1x=%.4f, vp1y=%.4f", lm[0].m_card_id, lm[0].m_card_ct, lm[0].m_sit->m_pdoa_direction, vp[0].x, vp[0].y, vp[1].x, vp[1].y);
  150. bool dir = (pdoa > EPS);
  151. int max = -1, min = -1;
  152. if(0 == lm[0].m_sit->m_pdoa_direction)
  153. {
  154. if(lm[0].m_sit->m_ant[0].x == lm[0].m_sit->m_ant[1].x){
  155. dir?(max = select_max_solution(vp[0].x, vp[1].x, vp, lp)):(min = select_min_solution(vp[0].x, vp[1].x, vp, lp));
  156. }else if(lm[0].m_sit->m_ant[0].y == lm[0].m_sit->m_ant[1].y){
  157. dir?(max = select_max_solution(vp[0].x, vp[1].x, vp, lp)):(min = select_min_solution(vp[0].x, vp[1].x, vp, lp));
  158. }else if((lm[0].m_sit->m_ant[0].x != lm[0].m_sit->m_ant[1].x) && (lm[0].m_sit->m_ant[0].y != lm[0].m_sit->m_ant[1].y)){
  159. dir?(max = select_max_solution(vp[0].x, vp[1].x, vp, lp)):(min = select_min_solution(vp[0].x, vp[1].x, vp, lp));
  160. }
  161. }else{
  162. if(lm[0].m_sit->m_ant[0].x == lm[0].m_sit->m_ant[1].x){
  163. // 分站天线在竖直巷道
  164. dir?(min = select_min_solution(vp[0].y, vp[1].y, vp, lp)):(max = select_max_solution(vp[0].y, vp[1].y, vp, lp));
  165. }else if(lm[0].m_sit->m_ant[0].y == lm[0].m_sit->m_ant[1].y){
  166. // 分站天线在水平巷道
  167. dir?(min = select_min_solution(vp[0].x, vp[1].x, vp, lp)):(max = select_max_solution(vp[0].x, vp[1].x, vp, lp));
  168. }else if((lm[0].m_sit->m_ant[0].x != lm[0].m_sit->m_ant[1].x) && (lm[0].m_sit->m_ant[0].y != lm[0].m_sit->m_ant[1].y)){
  169. dir?(min = select_min_solution(vp[0].x, vp[1].x, vp, lp)):(max = select_max_solution(vp[0].x, vp[1].x, vp, lp));
  170. }
  171. }
  172. logn_info(3, "[pdoa] card_id=%d, cur_pdoa=%.2f, dir=%s site_dir=%d, min=%d, max=%d", lm[0].m_card_id, pdoa, (dir?"true":"false"), lm[0].m_sit->m_pdoa_direction, min, max);
  173. }
  174. return true;
  175. }
  176. // 当出井方向切换分站选解
  177. bool select_point_object::select_pdoa_solution2(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point&lp, const float& pdoa)
  178. {
  179. if(1 == vp.size())
  180. {
  181. bool dir = (pdoa > EPS);
  182. logn_info(3,"[pdoa] card_id=%d, ct=%d, vp0x=%.4f, vp0y=%.4f", lm[0].m_card_id, lm[0].m_card_ct, vp[0].x, vp[0].y);
  183. if(lm[0].m_sit->m_ant[0].x == lm[0].m_sit->m_ant[1].x)
  184. {
  185. if(0 == lm[0].m_sit->m_pdoa_direction){
  186. if(dir){
  187. if(vp[0].x > lm[0].m_sit->m_ant[0].x){
  188. lp.set(vp[0]);
  189. lp.m_useless = true;
  190. }else{
  191. logn_warn(3, "[pdoa] solution is not correct, card_id=%d", lm[0].m_card_id);
  192. lp.m_useless = false;
  193. }
  194. }else{
  195. if(vp[0].x < lm[0].m_sit->m_ant[0].x){
  196. lp.set(vp[0]);
  197. lp.m_useless = true;
  198. }else{
  199. logn_warn(3, "[pdoa] solution is not correct, card_id=%d", lm[0].m_card_id);
  200. lp.m_useless = false;
  201. }
  202. }
  203. }else{
  204. if(dir){
  205. if(vp[0].x < lm[0].m_sit->m_ant[0].x){
  206. lp.set(vp[0]);
  207. lp.m_useless = true;
  208. }else{
  209. lp.m_useless = false;
  210. }
  211. }else{
  212. if(vp[0].x > lm[0].m_sit->m_ant[0].x){
  213. lp.set(vp[0]);
  214. lp.m_useless = true;
  215. }else{
  216. lp.m_useless = false;
  217. }
  218. }
  219. }
  220. }else{
  221. logn_info(3, "[pdoa] select one solution, card_id=%d", lm[0].m_card_id);
  222. if(dir){
  223. }
  224. }
  225. return lp.m_useless;
  226. }else if(2 == vp.size()){
  227. // select one solution from two solution by reader and phase direction
  228. logn_info(3, "[pdoa] select one solution from 2, card_id=%d, ct=%d, site_dir=%d, vp0x=%.4f, vp0y=%.4f, vp1x=%.4f, vp1y=%.4f", lm[0].m_card_id, lm[0].m_card_ct, lm[0].m_sit->m_pdoa_direction, vp[0].x, vp[0].y, vp[1].x, vp[1].y);
  229. bool dir = (pdoa > EPS);
  230. int max = -1, min = -1;
  231. if(lm[0].m_sit->m_ant[0].x == lm[0].m_sit->m_ant[1].x){
  232. dir?(max = select_max_solution(vp[0].y, vp[1].y, vp, lp)):(min = select_min_solution(vp[0].y, vp[1].y, vp, lp));
  233. }else if(lm[0].m_sit->m_ant[0].y == lm[0].m_sit->m_ant[1].y){
  234. dir?(max = select_max_solution(vp[0].y, vp[1].y, vp, lp)):(min = select_min_solution(vp[0].y, vp[1].y, vp, lp));
  235. }else if((lm[0].m_sit->m_ant[0].x != lm[0].m_sit->m_ant[1].x) && (lm[0].m_sit->m_ant[0].y != lm[0].m_sit->m_ant[1].y)){
  236. dir?(max = select_max_solution(vp[0].y, vp[1].y, vp, lp)):(min = select_min_solution(vp[0].y, vp[1].y, vp, lp));
  237. }
  238. logn_info(3, "[pdoa] card_id=%d, cur_pdoa=%.2f, dir=%s site_dir=%d, min=%d, max=%d", lm[0].m_card_id, pdoa, (dir?"true":"false"), lm[0].m_sit->m_pdoa_direction, min, max);
  239. }
  240. return true;
  241. }
  242. /*bool select_point_object::select_pdoa_1d_solution(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point& lp)
  243. {
  244. uint64_t id = lm[0].m_card_type;
  245. id = ((id<<32) | lm[0].m_card_id);
  246. auto card = card_list::instance()->get(id);
  247. double dist_tof = lm[0].m_num_ticks * 15.65 * 2.996 * 1e-4;
  248. if((card->m_buff_size != 100 || dist_tof < SAFE) && fabs(lm[0].m_poa[1] - 10.0) < 1E-4){
  249. return false;
  250. }
  251. int idx = lm[0].tool_index();
  252. uint8_t type = idx>>4;
  253. uint8_t dim = idx&0x03;
  254. idx = type*3 + dim - 1;
  255. if(card->m_buff_size == 100 && dist_tof > SAFE && fabs(lm[0].m_poa[1] - 10.0) < 1E-4){
  256. lp.x = card->m_last_point.x;
  257. lp.y = card->m_last_point.y;
  258. double diff_time = (lm[0].m_loc_time - card->m_last_recv_time)*1.0/1000.0;
  259. double speed = get_speed(lp, card->m_last_point, diff_time) * lm[0].m_sit->m_scale;
  260. if(speed > 15.0){
  261. lp.m_useless = false;
  262. return false;
  263. }
  264. lp.m_useless = true;
  265. logn_info(3, "[pdoa] solution info: card_id=%d, ct=%d, useless=%d, locate_x=%.4f, locate_y=%.4f, speed=%.3f, opt=true", lm[0].m_card_id, lm[0].m_card_ct, lp.m_useless, lp.x, lp.y, speed);
  266. card->m_last_pdoa_diff = card->m_pdoa_diff;
  267. card->m_last_ct = lm[0].m_card_ct;
  268. card->m_last_dist = dist_tof;
  269. card->m_cb_point.push_back(lp);
  270. card->m_last_site_id = lm[0].m_sit->m_id;
  271. card->m_last_site_dir = lm[0].m_sit->m_pdoa_direction;
  272. card->m_last_recv_time = lm[0].m_loc_time;
  273. card->m_last_point.x = lp.x;
  274. card->m_last_point.y = lp.y;
  275. lp.m_speed = card->m_speed = 0;
  276. return true;
  277. }
  278. card->m_pdoa_diff = get_pdoa(lm[0].m_poa, lm[0].m_sit->m_pdoa_offset);
  279. logn_info(3, "[pdoa] card_id=%d, pdoa=%.3f, poa[0]=%.3f, poa[1]=%.3f, poa[2]=%.3f, offset=%.4f, dist=%.3f", id, card->m_pdoa_diff, lm[0].m_poa[0], lm[0].m_poa[1], lm[0].m_poa[2], lm[0].m_sit->m_pdoa_offset, dist_tof);
  280. // after a long time,there is not recvied data, then reset pdoa list
  281. if(((card->m_last_dist < SAFE && dist_tof >= SAFE) || (lm[0].m_loc_time - card->m_last_recv_time > 30*1000)) && card->m_buff_size == 100){
  282. logn_info(3, "[pdoa] reset pdoa buffer, card_id=%d, cur_dist=%.3f, cur_time=%lld, last_dist=%.3f, last_time=%lld", lm[0].m_card_id, dist_tof, lm[0].m_loc_time, card->m_last_dist, card->m_last_recv_time);
  283. card->clear();
  284. }
  285. //first adjust, first 5 frame, not output located point
  286. uint16_t ct = lm[0].m_card_ct;
  287. if(card->m_buff_size < 5){
  288. card->m_cb_pdoa.push_back(card->m_pdoa_diff);
  289. ++card->m_buff_size;
  290. card->m_cb_tof.push_back(dist_tof);
  291. card->m_last_ct = ct;
  292. card->m_last_dist = dist_tof;
  293. card->m_last_recv_time = lm[0].m_loc_time;
  294. return false;
  295. }
  296. // choose 3 poa's direction as the card's direction
  297. if(5 == card->m_buff_size){
  298. card->m_buff_size = 100;
  299. int positive = 0;
  300. for(int i = 0;i < 5; ++i){
  301. if(card->m_cb_pdoa[i] > 0){
  302. ++positive;
  303. }
  304. }
  305. if(positive >= 3){
  306. for(int i = 0; i < 5; ++i){
  307. if(card->m_cb_pdoa[i] < 0){
  308. card->m_cb_pdoa[i] = -1.0*card->m_cb_pdoa[i];
  309. }
  310. }
  311. }else{
  312. for(int i = 0;i < 5;++i){
  313. if(card->m_cb_pdoa[i] > 0){
  314. card->m_cb_pdoa[i] = -1.0*card->m_cb_pdoa[i];
  315. }
  316. }
  317. }
  318. }
  319. // tof filter
  320. int ct_offset = -1;
  321. float offset = 0.0f;
  322. ct_offset = ct - card->m_last_ct;
  323. offset = card->m_cb_tof[4] - dist_tof;
  324. if(1 == ct_offset)
  325. {
  326. if(offset < 0){
  327. offset = -1.0*offset;
  328. }
  329. // need call opt way
  330. if(offset > 15){
  331. // illeglal tof
  332. logn_info(3, "[pdoa] the distance's is bigger than 15, card_id=%d, ct=%d, cur_dist=%.3f, last_ct=%d, last_dist=%.3f", lm[0].m_card_id, lm[0].m_card_ct, dist_tof, card->m_last_ct, card->m_cb_tof[4]);
  333. return false;
  334. }
  335. }
  336. card->m_last_dist = dist_tof;
  337. //card->m_cb_tof.push_back(dist_tof);
  338. logn_info(3, "[pdoa] normal, card_id=%d, ct=%d, cur_dist=%.3f, last_ct=%d, last_dist=%.3f", lm[0].m_card_id, lm[0].m_card_ct, dist_tof, card->m_last_ct, card->m_cb_tof[4]);
  339. //pdoa meadian filter
  340. std::array<float, 5> pdoa = {0};
  341. for(int i = 0; i < 5; ++i){
  342. pdoa[i] = card->m_cb_pdoa[i];
  343. }
  344. std::sort(pdoa.begin(), pdoa.end());
  345. float meadian_pdoa = pdoa[2];
  346. logn_info(3, "[pdoa] card_id=%d, ct=%d, before pdoa filter: meadian_pdoa=%.4f, cur_pdoa=%.4f, last_pdoa=%.4f, pdoa[0]=%.4f, pdoa[1]=%.4f, pdoa[2]=%.4f, pdoa[3]=%.4f, pdoa[4]=%.4f", lm[0].m_card_id, lm[0].m_card_ct, meadian_pdoa, card->m_pdoa_diff, card->m_last_pdoa_diff, card->m_cb_pdoa[0], card->m_cb_pdoa[1], card->m_cb_pdoa[2], card->m_cb_pdoa[3], card->m_cb_pdoa[4]);
  347. float cur_pdoa = card->m_pdoa_diff;
  348. bool change = false;
  349. if(lm[0].m_loc_time - card->m_last_recv_time < 30*1000){
  350. if(card->m_last_site_id !=0 && card->m_last_site_id != lm[0].m_sit->m_id){
  351. // pdoa change from site A to site B
  352. if(card->m_last_site_dir == 0 && lm[0].m_sit->m_pdoa_direction == 0){
  353. change = true;
  354. }else if(card->m_last_site_dir == 0 && lm[0].m_sit->m_pdoa_direction == 1){
  355. // keep same direction
  356. }else if(card->m_last_site_dir == 1 && lm[0].m_sit->m_pdoa_direction == 0){
  357. // keep same direction
  358. }else if(card->m_last_site_dir == 1 && lm[0].m_sit->m_pdoa_direction == 1){
  359. change = true;
  360. }
  361. if(change){
  362. for(int i = 0;i < 5; ++i){
  363. card->m_cb_pdoa[i] *= -1.0;
  364. }
  365. }
  366. // 下面逻辑判断当前pdoa值是否有异常,如有异常就改变方向
  367. int same_direction = 0;
  368. for(int i = 0;i < 5;++i){
  369. if(card->m_cb_pdoa[i] * cur_pdoa > 0){
  370. same_direction++;
  371. }
  372. }
  373. if(same_direction < 3){
  374. cur_pdoa*=-1;
  375. }
  376. logn_info(3, "[pdoa] card_id=%d, change site from %d to %d, pdoa change status=%d", lm[0].m_card_id, card->m_last_site_id, lm[0].m_sit->m_id, (change?1:0));
  377. card->m_cb_pdoa.push_back(cur_pdoa);
  378. card->m_cb_tof.push_back(dist_tof);
  379. // 定位退出
  380. if(!save_pdoa_1d(card, vp, lm, lp, cur_pdoa)){
  381. return false;
  382. }
  383. return true
  384. }
  385. }
  386. // 5 meter away filter, abnormal poa
  387. //bool is_opposite = false;
  388. if(dist_tof > SAFE)
  389. {
  390. int same_direction = 0;
  391. for(int i = 0;i< 5;++i){
  392. if(card->m_cb_pdoa[i] * cur_pdoa > 0){
  393. same_direction++;
  394. }
  395. }
  396. if(same_direction < 3){
  397. logn_info(3, "[pdoa] at 5m away, the pdoa is opposite, card_id=%d, ct=%d, old_pdoa=%.3f", lm[0].m_card_id, lm[0].m_card_ct, cur_pdoa);
  398. float last_k = 0.0f, curr_k = 0.0f, llast_k = 0.0f;
  399. llast_k = card->m_cb_tof[3] - card->m_cb_tof[2];
  400. last_k = card->m_cb_tof[4] - card->m_cb_tof[3];
  401. curr_k = dist_tof - card->m_cb_tof[4];
  402. if(curr_k > 0 && last_k < 0 && llast_k < 0)
  403. {
  404. // find the site
  405. logn_info(3, "[pdoa] card has cross the site, card_id=%d, ct=%d", lm[0].m_card_id, lm[0].m_card_ct);
  406. // 缓存切换方向
  407. }else{
  408. card->m_cb_pdoa.push_back(cur_pdoa);
  409. card->m_cb_tof.push_back(cur_tof);
  410. // 定位退出
  411. if(!save_pdoa_1d(card, vp, lm, lp, cur_pdoa)){
  412. return false;
  413. }
  414. return true
  415. }
  416. }
  417. }else{
  418. // judge the position of site
  419. logn_info(3, "[pdoa] 5m in, card_id=%d, ct=%d, distance=%.4f", lm[0].m_card_id, lm[0].m_card_ct, dist_tof);
  420. float last_k = 0.0f, curr_k = 0.0f, llast_k = 0.0f;
  421. llast_k = card->m_cb_tof[3] - card->m_cb_tof[2];
  422. last_k = card->m_cb_tof[4] - card->m_cb_tof[3];
  423. curr_k = dist_tof - card->m_cb_tof[4];
  424. if(curr_k > 0 && last_k < 0 && llast_k < 0)
  425. {
  426. // find the site
  427. logn_info(3, "[pdoa] card has cross the site, card_id=%d, ct=%d", lm[0].m_card_id, lm[0].m_card_ct);
  428. for(int i = 0; i < 5;++i)
  429. {
  430. card->m_cb_pdoa[i] = 100;
  431. }
  432. //如果当前值方向和中值方向相同了,认为切了方向,因为距离信息当前方向和中值方向应该不同
  433. if(((0.0 - card->m_pdoa_diff) < EPS) == ((0.0 - meadian_pdoa) < EPS))
  434. {
  435. card->m_pdoa_diff = -card->m_pdoa_diff;
  436. }
  437. }
  438. }
  439. logn_info(3, "[pdoa] after pdoa filter, card_id=%d, ct=%d, current_pf=%.4f, last_pf=%.4f, cb[0]=%.4f, cb[1]= %.4f, cb[2]=%.4f, cb[3]=%.4f, cb[4]=%.4f, meadian=%.4f, tof[0]=%.4f, tof[1]=%.4f, tof[2]=%.4f, tof[3]=%.4f, tof[4]=%.4f", lm[0].m_card_id, lm[0].m_card_ct, card->m_pdoa_diff, card->m_last_pdoa_diff, card->m_cb_pdoa[0], card->m_cb_pdoa[1], card->m_cb_pdoa[2], card->m_cb_pdoa[3], card->m_cb_pdoa[4], meadian_pdoa, card->m_cb_tof[0], card->m_cb_tof[1], card->m_cb_tof[2], card->m_cb_tof[3], card->m_cb_tof[4]);
  440. card->m_cb_tof.push_back(dist_tof);
  441. card->m_cb_pdoa.push_back(card->m_pdoa_diff);
  442. if(!save_pdoa_1d(card, vp, lm, lp, cur_pdoa)){
  443. return false;
  444. }
  445. return true;
  446. }*/
  447. /*
  448. * 选择一维定位的解,不采用任何优化方法
  449. *
  450. * 参数
  451. * const std::vector<point> vp 可能定位解
  452. * const std::vector<loc_message>& lm 定位原始数据集
  453. * loc_point& lp 保存最终定位解
  454. *
  455. * 返回值
  456. * true表示成功选解,false表示选解失败
  457. *
  458. * */
  459. bool select_point_object::select_pdoa_1d_solution_original(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point& lp)
  460. {
  461. uint64_t id = lm[0].m_card_type;
  462. id = ((id<<32)|lm[0].m_card_id);
  463. auto card= card_list::instance()->get(id);
  464. double dist = lm[0].m_num_ticks * 15.65 * 2.996 * 1e-4;
  465. double pdoa = get_pdoa(lm[0].m_poa, lm[0].m_sit->m_pdoa_offset);
  466. logn_info(3, "[pdoa_o] card_id=%d, pdoa=%.2f, dist=%.2f, vp0x=%.2f, vp0y=%.2f, vp1x=%.2f, vp2y=%.2f", lm[0].m_card_id, pdoa, dist, vp[0].x, vp[0].y, vp[1].x, vp[1].y);
  467. double dt = (lm[0].m_loc_time - card->m_last_recv_time)*1.0/1000.0;
  468. double speed = fabs(dist - card->m_last_dist)/dt;
  469. if(!select_pdoa_solution2(vp, lm, lp, pdoa)){
  470. return false;
  471. }
  472. logn_info(3, "[pdoa_o] card_id=%d, ct=%d, useless=%d, x=%.4f, y=%.4f, speed=%.3f, d=%.2f", lm[0].m_card_id, lm[0].m_card_ct, 1, lp.x, lp.y, speed);
  473. lp.m_useless = true;
  474. card->m_last_pdoa_diff = pdoa;
  475. card->m_last_ct = lm[0].m_card_ct;
  476. card->m_last_dist = dist;
  477. card->m_last_site_id = lm[0].m_sit->m_id;
  478. card->m_last_site_dir = lm[0].m_sit->m_pdoa_direction;
  479. card->m_last_point.x = lp.x;
  480. card->m_last_point.y = lp.y;
  481. lp.m_speed = card->m_speed = speed;
  482. card->m_cb_point.push_back(lp);
  483. card->m_vtp_dist.push_back(dist);
  484. return true;
  485. }
  486. /*
  487. * 选择一维定位的解
  488. *
  489. * 参数
  490. * const std::vector<point> vp 可能定位解
  491. * const std::vector<loc_message>& lm 定位原始数据集
  492. * loc_point& lp 保存最终定位解
  493. *
  494. * 返回值
  495. * true表示成功选解,false表示选解失败
  496. *
  497. * */
  498. bool select_point_object::select_pdoa_1d_solution(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point& lp)
  499. {
  500. uint64_t id = lm[0].m_card_type;
  501. id = ((id<<32) | lm[0].m_card_id);
  502. auto card = card_list::instance()->get(id);
  503. double dist = lm[0].m_num_ticks * 15.65 * 2.996 * 1e-4;
  504. int idx = lm[0].tool_index();
  505. uint8_t type = idx>>4;
  506. uint8_t dim = idx&0x03;
  507. idx = type*3 + dim - 1;
  508. double pdoa = get_pdoa(lm[0].m_poa, lm[0].m_sit->m_pdoa_offset);
  509. logn_info(3, "[pdoa] card_id=%d, pdoa=%.2f, dist=%.2f, vp0x=%.2f, vp0y=%.2f, vp1x=%.2f, vp1y=%.2f", lm[0].m_card_id, pdoa, dist, vp[0].x, vp[0].y, vp[1].x, vp[1].y);
  510. double dt = (lm[0].m_loc_time - card->m_last_recv_time)*1.0/1000.0;
  511. double speed = fabs(dist - card->m_last_dist)/dt;
  512. if(card->m_last_recv_time > 0 && fabs(dt) > 30.0)
  513. {
  514. // 直接定位
  515. logn_info(3, "[pdoa] card_id=%d, pdoa=%.2f, dt=%.2f, speed=%.2f, last_time=%llu", lm[0].m_card_id, pdoa, dt, speed, card->m_last_recv_time);
  516. card->m_last_recv_time = lm[0].m_loc_time;
  517. return false;
  518. }
  519. card->m_last_recv_time = lm[0].m_loc_time;
  520. int n = card->m_vtp_dist.size();
  521. bool change_site = false;
  522. bool over_site = false;
  523. //切换基站,默认取正值
  524. if(lm[0].m_sit->m_id != card->m_last_site_id){
  525. // 切换基站要考虑两种情况
  526. // 1)入井方向的切换
  527. if(card->m_cb_stream_idx[0] < lm[0].m_sit->m_down_stream_idx){
  528. if(lm[0].m_sit->m_pdoa_direction == 0){
  529. pdoa *= (pdoa > 0?1:-1);
  530. }else{
  531. pdoa *= (pdoa < 0?-1:1);
  532. }
  533. }else{
  534. // 2)出井方向的切换
  535. if(lm[0].m_sit->m_pdoa_direction == 0){
  536. pdoa *= (pdoa < 0?1:-1);
  537. }else{
  538. pdoa *= (pdoa > 0?-1:1);
  539. }
  540. }
  541. if(!select_pdoa_solution2(vp, lm, lp, pdoa)){
  542. return false;
  543. }
  544. card->m_cb_stream_idx.push_back(lm[0].m_sit->m_down_stream_idx);
  545. card->m_last_site_id = lm[0].m_sit->m_id;
  546. card->m_vtp_dist.clear();
  547. card->m_vtp_dist.resize(0);
  548. change_site = true;
  549. card->m_over_site = false;
  550. logn_info(3, "[pdoa] change site, card_id=%d, last_site=%d, last_dist=%.2f, cur_site=%d, cur_dist=%.2f", lm[0].m_card_id, card->m_last_site_id, card->m_last_dist, lm[0].m_sit->m_id, dist);
  551. }else if(!card->m_over_site && n >= 3){
  552. // 过分站逻辑
  553. if(!select_pdoa_solution2(vp, lm, lp, pdoa)){
  554. return false;
  555. }
  556. //double dd = dist - card->m_last_dist;
  557. double d = lp.dist(card->m_last_point)*lm[0].m_sit->m_scale;
  558. logn_info(3, "[pdoa] origin info, card_id=%d, ox=%.2f, oy=%.2f, lx=%.2f, ly=%.2f, d=%.2f, dt=%.2f", lm[0].m_card_id, lp.x, lp.y, card->m_last_point.x, card->m_last_point.y, d, dt);
  559. // 如果选出的解是正确解,即距离和测距距离相等
  560. double k1 = (card->m_vtp_dist[n-2] - card->m_vtp_dist[n-1])/dt;
  561. double k2 = (card->m_vtp_dist[n-1] - dist)/dt;
  562. logn_info(3, "[pdoa] card_id=%d, k1=%.2f, k2=%.2f, d=%.2f", lm[0].m_card_id, k1, k2, d);
  563. if(((k1 > 1 && k2 < -1) || (k1 < -1 && k2 > 1)) ||(k1*k2 < 0 && fabs(d - dist - card->m_last_dist) < 2.0)){
  564. over_site = true;
  565. card->m_over_site = true;
  566. //过基站还要分以下两种情况:
  567. //1)入井时的从正到负
  568. //2)出井时的从负到正
  569. logn_info(3, "[pdoa] card_id=%d, cur_idx=%d, last_idx=%d", lm[0].m_card_id, card->m_cb_stream_idx[0], card->m_cb_stream_idx[1]);
  570. if(card->m_cb_stream_idx[1] > card->m_cb_stream_idx[0]){
  571. //1)入井时的从正到负
  572. pdoa *= (pdoa>0?-1:1);
  573. /*if(lm[0].m_sit->m_pdoa_direction == 0){
  574. pdoa *= (pdoa<0?-1:1);
  575. }else{
  576. pdoa *= (pdoa>0?1:-1);
  577. }*/
  578. }else{
  579. //2)出井时的从负到正
  580. pdoa *= (pdoa<0?-1:1);
  581. /*if(lm[0].m_sit->m_pdoa_direction == 0){
  582. pdoa *= (pdoa<0?-1:1);
  583. }else{
  584. pdoa *= (pdoa>0?-1:1);
  585. }*/
  586. }
  587. if(!select_pdoa_solution2(vp, lm, lp, pdoa)){
  588. return false;
  589. }
  590. }
  591. }
  592. // 如果没有切换基站且没有过基站
  593. if(!change_site && !over_site){
  594. if(!select_pdoa_solution2(vp, lm, lp, pdoa)){
  595. return false;
  596. }
  597. double d = lp.dist(card->m_last_point)*lm[0].m_sit->m_scale;
  598. logn_info(3, "[pdoa] select solution, card_id=%d, x=%.2f, y =%.2f, last_x=%.2f, last_y=%.2f, d=%.2f, pd=%.2f, dt=%.2f", lm[0].m_card_id, lp.x, lp.y, card->m_last_point.x, card->m_last_point.y, dist, d, dt);
  599. if(fabs(d - fabs(dist - card->m_last_dist)) > 2.0){
  600. if(!card->m_last_point.empty()&&(lm[0].m_sit->m_id == card->m_last_site_id)){
  601. int idx = 0;
  602. double min = 999999.0;
  603. for(size_t i = 0;i < vp.size();++i){
  604. double d = vp[i].dist(card->m_last_point)*lm[0].m_sit->m_scale;
  605. if(fabs(d - speed*dt) < min){
  606. idx = i;
  607. min = fabs(d - speed*dt);
  608. }
  609. }
  610. lp.set(vp[idx]);
  611. }
  612. }
  613. d = lp.dist(card->m_last_point)*lm[0].m_sit->m_scale;
  614. /*if(fabs(d-dist) > 0.5 && !card->m_last_point.empty()){
  615. logn_info(3, "[pdoa] card_id=%d, d=%.2f, dist=%.2f, lp.x=%.2f, lp.y=%.2f , solution is not correct!", lm[0].m_card_id, d, dist, lp.x, lp.y);
  616. return false;
  617. }*/
  618. logn_info(3, "[pdoa] unilateral processing, card_id=%d", lm[0].m_card_id);
  619. }
  620. lp.m_useless = true;
  621. logn_info(3, "[pdoa] card_id=%d, ct=%d, pdoa=%.2f, dd=%.2f, dt=%.2f", lm[0].m_card_id, lm[0].m_card_ct, pdoa, dt*speed, dt);
  622. logn_info(3, "[pdoa] solution info: card_id=%d, ct=%d, useless=%d, locate_x=%.4f, locate_y=%.4f, speed=%.3f, d=%.2f", lm[0].m_card_id, lm[0].m_card_ct, lp.m_useless, lp.x, lp.y, speed, dt*speed);
  623. card->m_last_pdoa_diff = pdoa;
  624. card->m_last_ct = lm[0].m_card_ct;
  625. card->m_last_dist = dist;
  626. card->m_last_site_id = lm[0].m_sit->m_id;
  627. card->m_last_site_dir = lm[0].m_sit->m_pdoa_direction;
  628. card->m_last_point.x = lp.x;
  629. card->m_last_point.y = lp.y;
  630. lp.m_speed = card->m_speed = speed;
  631. card->m_cb_point.push_back(lp);
  632. card->m_vtp_dist.push_back(dist);
  633. return true;
  634. }
  635. bool select_point_object::select_pdoa_2d_solution(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point& lp)
  636. {
  637. logn_info(3, "[pdoa] begin select 2d solution, vp's size=%d", vp.size());
  638. int i = 1;
  639. for(auto it = vp.cbegin(); it != vp.cend();++it){
  640. logn_info(3, "[pdoa] useless %d : card_id=%d, x=%.4f, y=%.4f", i, lm[0].m_card_id,(*it).x, (*it).y);
  641. ++i;
  642. }
  643. if(1 == vp.size()){
  644. lp.x = vp[0].x;
  645. lp.y = vp[0].y;
  646. lp.m_useless = true;
  647. }
  648. uint64_t id = lm[0].m_card_type;
  649. id = ((id<<32) | lm[0].m_card_id);
  650. auto card = card_list::instance()->get(id);
  651. card->m_last_point.x = lp.x;
  652. card->m_last_point.y = lp.y;
  653. return true;
  654. }
  655. bool select_point_object::select_pdoa_3d_solution(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point& lp)
  656. {
  657. return true;
  658. }
  659. int select_point_object::get_algo_index(const int& idx)
  660. {
  661. uint8_t index = 0;
  662. uint8_t type = idx>>4;
  663. uint8_t dim = idx & 0x03;
  664. index = type*3 + dim - 1;
  665. log_info("[pdoa] algo=%d", index);
  666. return index;
  667. }
  668. double select_point_object::get_speed(const loc_point& p, const point& lp, const double& offset)
  669. {
  670. double speed = -1.0;
  671. if(!(p.x <= EPS && p.y <= EPS)){
  672. speed = sqrt(pow(p.x - lp.x, 2) + pow(p.y - lp.y, 2))/offset;
  673. }
  674. logn_info(3, "[pdoa] calc_speed, p.x=%.3f, p.y=%.3f, lp.x=%.3f, lp.y=%.3f, diff_time=%lld", p.x, p.y, lp.x, lp.y, offset);
  675. return speed;
  676. }
  677. double select_point_object::get_distance(const int& rid, const int& lrid)
  678. {
  679. double d = 0.0;
  680. /*auto cs = sit_list()->instance()->get(rid);
  681. auto ls = sit_list()->instance()->get(lrid);
  682. if(cs&&ls){
  683. d = cs.dist(ls);
  684. log_info("[pdoa] get distance from current site %d to last site %d", rid, lrid);
  685. }*/
  686. return d;
  687. }
  688. float select_point_object::get_pdoa(const double poa[], const double& offset)
  689. {
  690. if(poa == nullptr){
  691. return -10.0;
  692. }
  693. float poa1 = poa[0];
  694. float poa2 = poa[1];
  695. //float poa3 = poa[2];
  696. float pdoa = poa2 - poa1 - offset;
  697. while(pdoa >= TPI){
  698. pdoa -= TPI;
  699. }
  700. while(pdoa < 0){
  701. pdoa += TPI;
  702. }
  703. pdoa -= PI;
  704. return pdoa;
  705. }
  706. int select_point_object::find_last(int start)
  707. {
  708. for(int i=start,len=m_d.size();i<len;i++)
  709. {
  710. if(m_d(i).cl()>0)
  711. return i;
  712. }
  713. return -1;
  714. }
  715. int select_point_object::find_first(int start)
  716. {
  717. for(int i=start,len=m_d.size();i<len;i++)
  718. {
  719. if(m_d[i].cl()>0)
  720. return i;
  721. }
  722. return -1;
  723. }
  724. /*
  725. * 拟合过滤
  726. *
  727. * param
  728. * loc_point& c 最终保存点
  729. * const std::vector<point>& vp 可能解
  730. * const double scale 比例尺
  731. *
  732. * return
  733. *
  734. *
  735. * */
  736. bool select_point_object::filter_by_fit(loc_point & c,const std::vector<point> & vp,const double scale)
  737. {
  738. fit_result * fit = get_best_fit();
  739. if(fit==nullptr || m_begin==nullptr || fit->ke>2)
  740. return false;
  741. loc_point &f = *m_begin;
  742. std::array<solpoint,4> v;
  743. int cnt = vp.size();
  744. for(int i=0;i<cnt;i++)
  745. {
  746. v[i].set_sol(vp[i],fabs(fit->testk(c.m_time/1000.,f.dist_direct(vp[i]))));
  747. }
  748. std::sort(&v[0],&v[0]+cnt);
  749. double a = getA(fit,scale,v[1].score()-v[0].score());
  750. if(a<0)
  751. return false;
  752. if(!filter_by_acc(c,v,a))
  753. {
  754. c.set_cl(0);
  755. return true; //false?
  756. }
  757. reset_fit(vp[0].dist(v[0]));
  758. c[0]=v[0];
  759. c[1]=v[1];
  760. return true;
  761. }
  762. /*
  763. * 加速度过滤
  764. *
  765. * param
  766. * loc_point& c
  767. * std::array<solpoint, 4>& v
  768. * double e
  769. *
  770. * return
  771. *
  772. * */
  773. bool select_point_object::filter_by_acc(loc_point&c,std::array<solpoint,4>&v,double a)
  774. {
  775. if(!m_last->is_same_site(c))
  776. return true;
  777. double td=m_last->time_off(c);
  778. if(v[0].score()>a*td*td)
  779. return false;
  780. return true;
  781. }
  782. /*
  783. *
  784. * */
  785. void select_point_object::select_one_ant(loc_point &c,const std::vector<point> & vp)
  786. {
  787. int last=find_last(1);
  788. if(last>0)
  789. {
  790. loc_point&p=m_d(last);
  791. int cnt=vp.size();
  792. std::array<solpoint,4> res;
  793. //find the shortest dis
  794. for(int i=0;i<cnt;i++)
  795. res[i].set_sol(vp[i],vp[i].dist(p[0]));
  796. std::sort(&res[0],&res[0]+cnt);
  797. c[1].set(res[1]);
  798. c[0].set(res[0]);
  799. c.inc_cl(5);
  800. }
  801. }
  802. point select_point_object::select_solution0(std::vector<point> &tvp,const double scale)
  803. {
  804. loc_point&c=m_d(0);
  805. if(m_d.size()==1)
  806. {
  807. //first point ,only accpet two ants good data.
  808. if(c.cl()>0 && tvp.size()<4)
  809. {
  810. c[1]=tvp[1];
  811. return c[0]=tvp[0];
  812. }
  813. m_d.skip(1);
  814. return point(0,0);
  815. }
  816. select_solution1(c,tvp,scale);
  817. return c[0];
  818. }
  819. bool select_point_object::select_solution(const std::vector<point> &vp,const site*sit,loc_point &p)
  820. {
  821. remove_history();
  822. std::vector<point> tvp(vp.begin(),vp.end());
  823. if(vp.size()==4)
  824. {
  825. int c = 0;
  826. std::array<solpoint,4> res;
  827. for(int i=0;i<2;i++)
  828. {
  829. int x = i+2;
  830. double d=vp[i].dist(vp[x]);
  831. if(d<sit->ant_dist()*3)
  832. {
  833. res[c++].set_sol(vp[i].middle(vp[x]),d);
  834. }
  835. else
  836. {
  837. res[c++].set_sol(vp[i]);
  838. res[c++].set_sol(vp[x]);
  839. }
  840. }
  841. std::sort(&res[0],&res[0]+c);
  842. tvp.clear();
  843. for(int i=0;i<c;i++)
  844. tvp.push_back(res[i]);
  845. m_d(0).inc_cl(10);
  846. }
  847. point pt = select_solution0(tvp,sit->m_scale);
  848. if(pt.empty() || m_d.empty())
  849. return false;
  850. m_d(0).set(pt);
  851. if(!m_d(0).empty())
  852. m_d(0).m_dist=sit->dist_direct(pt);
  853. else
  854. {
  855. m_d(0).set_cl(0);
  856. if(m_last) m_d(0).m_dist=0.01*m_last->m_dist>0?1:-1;
  857. }
  858. m_d(0).m_dist1 = sit->dist_direct(pt);
  859. bool fg = revise_by_history(pt,sit,m_d(0).m_time);
  860. if(!fg)
  861. {
  862. log_warn("out of site path:t=%ld,sit=%d,card_id=%d,ct=%d,tof1=%d,tof2=%d,pt=(%f,%f)\n", m_d(0).m_time, m_d(0).m_sid,m_d(0).m_cid,m_d(0).m_ct, m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
  863. return false;
  864. }
  865. if(!card_path::inst().is_at_path(pt))
  866. {
  867. m_d(0).set_cl(0);
  868. log_warn("out of path:t=%ld,sit=%d,card_id=%d,ct=%d,tof1=%d,tof2=%d,pt=(%f,%f)\n", m_d(0).m_time, m_d(0).m_sid,m_d(0).m_cid,m_d(0).m_ct, m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
  869. return false;
  870. }
  871. m_last=&m_d(0);
  872. if(m_line.empty() && m_d.size()>=2 && !make_line())
  873. return false;
  874. if(!m_line.contain(m_d(0),0.01) || (m_begin && !m_line.contain(m_begin->m_sol[0], 0.01)))
  875. {
  876. m_fitk.reset_data();
  877. m_fita.reset_data();
  878. m_begin=m_last=nullptr;
  879. int i0=find_last(1);
  880. if(i0==-1)
  881. return false;
  882. std::vector<point> path=card_path::inst().find_path(m_d(i0),m_d(0));
  883. m_d.skip(m_d.size()-i0);
  884. if(path.empty())
  885. {
  886. m_line.clear();
  887. return false;
  888. }
  889. m_line.set(path.back(),m_d(0));
  890. }
  891. if(!m_begin)
  892. {
  893. int idx=find_first(0);
  894. if(idx>=0) m_begin=&m_d[idx];
  895. }
  896. if(!m_last)
  897. {
  898. int idx=find_last(0);
  899. if(idx>=0) m_last=&m_d(idx);
  900. }
  901. if(m_begin && m_d(0).cl())
  902. {
  903. int lastID1=find_last(1);
  904. int lastID2=-1;
  905. if(lastID1!=-1)
  906. lastID2=find_last(lastID1+1);
  907. if(lastID2!=-1)
  908. {
  909. double t0=m_last->m_time/1000., t1=m_d(lastID1).m_time/1000., t2=m_d(lastID2).m_time/1000.;
  910. double d0=m_begin->loc_dist(*m_last), d1=m_begin->loc_dist(m_d(lastID1)), d2=m_begin->loc_dist(m_d(lastID2));
  911. double k1=(d1-d0)/(t1-t0), k2=(d2-d1)/(t2-t1);
  912. if(t0-t1<5 && t1-t2<5 && fabs(k2-k1)<0.5)
  913. {
  914. double tbegin = t0-3;
  915. while(tbegin<t1+0.5)
  916. tbegin=tbegin+1;
  917. double tk=(d0-d1)/(t0-t1), tb=d1-tk*t1; //d1+(d0-d1)/(t0-t1)*(t-t1)
  918. for(double ti=tbegin;ti<t0;ti=ti+1)
  919. {
  920. m_fitk.add(ti, tk*ti+tb);
  921. }
  922. }
  923. }
  924. m_fitk.add(m_last->m_time/1000.,m_begin->loc_dist(*m_last));
  925. if(m_d.size()>1)
  926. {
  927. int pre=find_last(1);
  928. if(pre>0)
  929. {
  930. m_fita.add(m_d(0).m_time/1000.,m_begin->loc_dist(m_d(0))-m_begin->loc_dist(m_d(pre)));
  931. }
  932. }
  933. }
  934. p.set(pt);
  935. save_k();
  936. p.m_useless=fg;
  937. return true;
  938. }
  939. bool select_point_object::make_line()
  940. {
  941. int i0=-1,i1=-1;
  942. if(-1==(i0=find_last(0)))
  943. return false;
  944. if(-1==(i1=find_last(i0+1)))
  945. return false;
  946. m_line.set(m_d(i0),m_d(i1));
  947. return true;
  948. }
  949. void select_point_object::remove_history()
  950. {
  951. loc_point&b=m_d(0);
  952. if(m_d.size()>120 || (m_d.size()>2 && m_d(1).time_off(b)>max_histime))
  953. {
  954. m_d.skip_if([&b,this](loc_point&p){
  955. return p.time_off(b)>max_histime;
  956. });
  957. m_fitk.reset_data();
  958. m_fita.reset_data();
  959. m_cur_fit.reset();
  960. m_begin=m_last=nullptr;
  961. int idx=find_first(0);
  962. if(idx<0)
  963. return;
  964. m_begin=&m_d[idx];
  965. idx=find_last(1);
  966. m_last=&m_d(idx);
  967. double dist=0,dist2=0;
  968. for(int len=std::min(15,m_d.size()-1),i=len;i>0;i--)
  969. {
  970. if(!m_d(i).cl())
  971. continue;
  972. int lastID1=find_last(i+1);
  973. int lastID2=-1;
  974. if(lastID1!=-1)
  975. lastID2=find_last(lastID1+1);
  976. if(lastID2!=-1)
  977. {
  978. double t0=m_d(i).m_time/1000., t1=m_d(lastID1).m_time/1000., t2=m_d(lastID2).m_time/1000.;
  979. double d0=m_begin->loc_dist(m_d(i)[0]), d1=m_begin->loc_dist(m_d(lastID1)[0]),
  980. d2=m_begin->loc_dist(m_d(lastID2)[0]);
  981. double k1=(d1-d0)/(t1-t0), k2=(d2-d1)/(t2-t1);
  982. if(t0-t1<5 && t1-t2<5 && fabs(k2-k1)<0.5)
  983. {
  984. double tbegin = t0-3;
  985. while(tbegin<t1+0.5)
  986. tbegin=tbegin+1;
  987. double tk=(d0-d1)/(t0-t1), tb=d1-tk*t1; //d1+(d0-d1)/(t0-t1)*(t-t1)
  988. for(double ti=tbegin;ti<t0;ti=ti+1)
  989. {
  990. m_fitk.add(ti, tk*ti+tb);
  991. }
  992. }
  993. }
  994. dist=m_begin->loc_dist(m_d(i)[0]);
  995. m_fitk.add(m_d(i).m_time/1000.,dist);
  996. if(i==len)
  997. continue;
  998. m_fita.add(m_d(i).m_time/1000.,dist-dist2);
  999. dist2=dist;
  1000. }
  1001. save_k();
  1002. }
  1003. }
  1004. void select_point_object::save_k()
  1005. {
  1006. const fit_result*fk=best_fit_raw(0,4);
  1007. if(!fk)
  1008. {
  1009. m_cur_fit.reset();
  1010. return;
  1011. }
  1012. m_cur_fit=*fk;
  1013. fit_result&r=m_cur_fit;
  1014. card_fit*fa=&m_fita[0];
  1015. if(fa->is_valid() && fa->ke<0.1 && fk->k*fa->k<0)
  1016. {
  1017. double dk=fa->k*fa->num_point;
  1018. r.ka=fa->k;
  1019. if((fk->k+dk)*fk->k<0)
  1020. r.k=0;
  1021. else
  1022. r.k+=dk;
  1023. double y=fk->k*m_fitk(0).x+fk->kb;
  1024. r.kb=y-m_fitk(0).x*r.k;
  1025. }
  1026. }
  1027. fit_result* select_point_object::best_fit_raw(int num_point,int start,int last)
  1028. {
  1029. card_fit*fit = nullptr;
  1030. start = std::max(start,0);
  1031. last = std::min(last,m_fitk.tool_size());
  1032. if(last == -1)
  1033. last = m_fitk.tool_size();
  1034. for(int i = start; i < last; i++)
  1035. {
  1036. if(!m_fitk[i].is_valid())
  1037. continue;
  1038. if(m_fitk[i].num_point < num_point)
  1039. continue;
  1040. if(fit == nullptr)
  1041. {
  1042. fit = &m_fitk[i];
  1043. continue;
  1044. }
  1045. if(fit->ke > m_fitk[i].ke)
  1046. {
  1047. fit = &m_fitk[i];
  1048. }
  1049. }
  1050. return fit;
  1051. }
  1052. select_tool::~select_tool()
  1053. {
  1054. if(m_spo !=nullptr)
  1055. delete m_spo;
  1056. }
  1057. loc_point select_tool_person_1::select_solution(const std::vector<point> vp,const std::vector<loc_message>&lm)
  1058. {
  1059. loc_point lp;
  1060. //select point.
  1061. uint8_t idx = 0;
  1062. uint8_t type = lm[0].tool_index()>>4;
  1063. uint8_t dim = lm[0].tool_index() & 0x03;
  1064. idx = type*3 + dim - 1;
  1065. //logn_info(3, "[pdoa] card_id=%d, idx=%d, dim=%d", lm[0].m_card_id, idx, dim);
  1066. if(idx == 0)
  1067. {
  1068. if(m_spo==nullptr)
  1069. m_spo = new person_point_filter(this);
  1070. lp=m_spo->select_solution_impl(vp,lm);
  1071. }
  1072. else if (idx == 2)
  1073. {
  1074. //for now..
  1075. //m_spo = new person_point_filter();
  1076. //lp=m_spo->select_solution_impl(vp,lm);
  1077. }else if(6 == idx){
  1078. // pdoa一维定位
  1079. //logn_info(3, "[pdoa] person, select_solution 1d, tool_index=%d", idx);
  1080. if(nullptr == m_spo){
  1081. m_spo= new person_point_filter(this);
  1082. }
  1083. lp = m_spo->select_solution_impl(vp, lm);
  1084. }else if(7 == idx){
  1085. // logn_info(3, "[pdoa] person, select_solution 2d, tool_index=%d", idx);
  1086. // pdoa二维定位
  1087. if(nullptr == m_spo){
  1088. m_spo = new person_point_filter(this);
  1089. }
  1090. lp = m_spo->select_solution_impl(vp, lm);
  1091. }else if(3 == idx){
  1092. }else if(4 == idx){
  1093. }else if(5 == idx){
  1094. }
  1095. else
  1096. {}
  1097. return lp;
  1098. }
  1099. loc_point select_tool_car_1::select_solution(const std::vector<point> vp,const std::vector<loc_message>&lm)
  1100. {
  1101. loc_point lp;
  1102. //select point.
  1103. uint8_t idx = 0;
  1104. uint8_t type = lm[0].tool_index()>>4;
  1105. uint8_t dim = lm[0].tool_index() & 0x03;
  1106. idx = type*3 + dim - 1;
  1107. if(idx == 0)
  1108. {
  1109. if(m_spo==nullptr)
  1110. m_spo = new car_point_filter(this);
  1111. lp=m_spo->select_solution_impl(vp,lm);
  1112. }
  1113. else if (idx == 2)
  1114. {
  1115. //for now..
  1116. //m_spo = new car_point_filter();
  1117. //lp=m_spo->select_solution_impl(vp,lm);
  1118. }else if(6 == idx){
  1119. // pdoa一维定位
  1120. if(nullptr == m_spo){
  1121. m_spo = new car_point_filter(this);
  1122. }
  1123. lp = m_spo->select_solution_impl(vp, lm);
  1124. }else if(7 == idx){
  1125. // pdoa二维定位
  1126. if(nullptr == m_spo)
  1127. {
  1128. m_spo = new car_point_filter(this);
  1129. }
  1130. lp = m_spo->select_solution_impl(vp, lm);
  1131. }else if(3 == idx){
  1132. }else if(4 == idx){
  1133. }else if(5 == idx){
  1134. }
  1135. else
  1136. {}
  1137. return lp;
  1138. }
  1139. select_tool_manage * select_tool_manage::instance()
  1140. {
  1141. static select_tool_manage stm;
  1142. return &stm;
  1143. }