select_tool.cpp 40 KB

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