1
0

select_tool.h 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. #ifndef __SELECT_TOOL__H
  2. #define __SELECT_TOOL__H
  3. #include <mutex>
  4. #include "loc_point.h"
  5. #include "line.h"
  6. #include <memory>
  7. #include "ant.h"
  8. #include "card_path.h"
  9. #include "loc_message.h"
  10. #include <zexception.h>
  11. //#include "optimize_tool.h"
  12. struct solpoint:point
  13. {
  14. solpoint()
  15. :m_score(100)
  16. {
  17. }
  18. double m_score;
  19. bool operator<(const solpoint&p)const
  20. {
  21. return m_score<p.m_score;
  22. }
  23. void set_sol(const point&p,double score=100)
  24. {
  25. set(p);
  26. this->m_score=score;
  27. }
  28. double score()const
  29. {
  30. return m_score;
  31. }
  32. };
  33. struct push_data_point:point
  34. {
  35. push_data_point()
  36. :ct(0)
  37. ,valid(false)
  38. ,stop_cnt(0)
  39. {
  40. }
  41. point dstp;
  42. int ct;
  43. bool valid; // if valid
  44. int stop_cnt; // if calculate speed
  45. loc_point lp;
  46. };
  47. class select_point_object;
  48. struct select_tool
  49. {
  50. std::mutex m_mtx;
  51. zlist<push_data_point,16> m_push_list;
  52. select_point_object *m_spo=nullptr;
  53. virtual loc_point select_solution(const std::vector<point> p,const std::vector<loc_message>&lm)=0;
  54. push_data_point getDpt()
  55. {
  56. push_data_point dpt;
  57. std::lock_guard<std::mutex> lock(m_mtx);
  58. if (m_push_list.empty()) //empty
  59. {
  60. return dpt;
  61. }
  62. else if(m_push_list.size()==1) //size=1
  63. {
  64. dpt = m_push_list[0];
  65. m_push_list[0].valid=false;
  66. if(m_push_list[0].stop_cnt>5)m_push_list[0].stop_cnt=5;
  67. if(m_push_list[0].stop_cnt>0)m_push_list[0].stop_cnt--;
  68. }
  69. else{ //size>1
  70. dpt = m_push_list[0];
  71. m_push_list.skip(1);
  72. }
  73. return dpt;
  74. }
  75. virtual ~select_tool();
  76. };
  77. //--------------person------solution one--------
  78. struct select_tool_person_1:select_tool
  79. {
  80. virtual loc_point select_solution(const std::vector<point> p,const std::vector<loc_message>&lm);
  81. ~select_tool_person_1()
  82. {
  83. }
  84. };
  85. struct select_tool_person_2:select_tool
  86. {
  87. virtual loc_point select_solution(const std::vector<point> p,const std::vector<loc_message>&lm)
  88. {
  89. loc_point lp;
  90. return lp;
  91. }
  92. };
  93. //----------------------car----------
  94. struct select_tool_car_1:select_tool
  95. {
  96. virtual loc_point select_solution(const std::vector<point> p,const std::vector<loc_message>&lm);
  97. };
  98. //---------------------drivingfaceCar
  99. struct select_tool_drivingface_car_1:select_tool
  100. {
  101. virtual loc_point select_solution(const std::vector<point> p,const std::vector<loc_message>&lm)
  102. {
  103. loc_point lp;
  104. return lp;
  105. }
  106. };
  107. //----------------------------------------
  108. struct select_point_object
  109. {
  110. select_tool * m_owner;
  111. public:
  112. select_point_object(select_tool * owner)
  113. :m_owner(owner)
  114. ,m_ct(-10)
  115. {
  116. att_initiate();
  117. }
  118. // 上次ct号
  119. int last_ct()
  120. {
  121. return m_ct;
  122. }
  123. public:
  124. const static int max_histime=60; //±£Áô×îºó60sµÄÊý¾Ý
  125. zlist<loc_point,128> m_d;
  126. line m_line;
  127. int m_ct = -10; // 计数号
  128. fit_batch m_fitk,m_fita;
  129. fit_result m_cur_fit; // 最新拟合结果
  130. loc_point* m_begin; // 起始点
  131. loc_point* m_last; // 结束点
  132. //static opt_tool_main m_opt_tool;
  133. public:
  134. int find_last(int start);
  135. int find_first(int start);
  136. void save_k();
  137. void att_initiate();
  138. void remove_history();
  139. bool make_line();
  140. point select_solution0(std::vector<point> &vp,const double scale);
  141. bool select_solution(const std::vector<point> &vp,const site*sit,loc_point &p);
  142. loc_point select_solution_impl(const std::vector<point> p,const std::vector<loc_message>&lm);
  143. bool select_pdoa_solution_impl(const std::vector<point> p, const std::vector<loc_message>& lm, loc_point& lp);
  144. bool select_pdoa_solution(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point&lp, const float& pdoa);
  145. bool select_pdoa_solution2(const std::vector<point> vp, const std::vector<loc_message>& lm, loc_point&lp, const float& pdoa);
  146. bool select_pdoa_1d_solution(const std::vector<point> p, const std::vector<loc_message>& lm, loc_point& lp);
  147. bool select_pdoa_2d_solution(const std::vector<point> p, const std::vector<loc_message>& lm, loc_point& lp);
  148. bool select_pdoa_3d_solution(const std::vector<point> p, const std::vector<loc_message>& lm, loc_point& lp);
  149. bool select_pdoa_1d_solution_original(const std::vector<point> p, const std::vector<loc_message>& lm, loc_point& lp);
  150. fit_result* best_fit_raw(int num_point=0,int start=0,int end=-1);
  151. bool filter_by_acc(loc_point&c,std::array<solpoint,4>&v,double a);
  152. bool filter_by_fit(loc_point & c,const std::vector<point> & vp,const double scale);
  153. void select_one_ant(loc_point &c,const std::vector<point> & vp);
  154. int select_max_solution(const float& lhs, const float& rhs, std::vector<point> vp, loc_point& lp);
  155. int select_min_solution(const float& lhs, const float& rhs, std::vector<point> vp, loc_point& lp);
  156. float get_pdoa(const double poa[], const double& offset);
  157. double get_speed(const loc_point& p, const point& lp, const double& offset);
  158. double get_distance(const int& rid, const int& lrid);
  159. private:
  160. int get_algo_index(const int& idx);
  161. public:
  162. virtual void select_solution1(loc_point &c,const std::vector<point> &vp,const double scale)=0;
  163. virtual fit_result * get_best_fit()=0;
  164. virtual double getA(const fit_result * fit,const double scale,const double dt)=0;
  165. virtual void reset_fit(double d)=0;
  166. virtual bool revise_by_history(point & pt, const site*sit, int64_t m_time)=0;
  167. virtual ~select_point_object(){}
  168. };
  169. /*
  170. * 人员定位坐标过滤类
  171. *
  172. * */
  173. struct person_point_filter:select_point_object
  174. {
  175. person_point_filter(select_tool * owner)
  176. :select_point_object(owner)
  177. ,m_filter_man_count(0)
  178. {}
  179. int m_filter_man_count=0; // 过滤计数
  180. // 重置拟合
  181. virtual void reset_fit(double d)
  182. {
  183. if(d>1)
  184. m_filter_man_count++;
  185. else
  186. m_filter_man_count = 0;
  187. if(m_filter_man_count==3)
  188. {
  189. m_fitk.reset_data();
  190. m_fita.reset_data();
  191. m_cur_fit.reset();
  192. m_begin = m_last = nullptr;
  193. m_filter_man_count = 0;
  194. }
  195. }
  196. virtual void select_solution1(loc_point &c,const std::vector<point> &vp,const double scale)
  197. {
  198. if(filter_by_fit(c,vp,scale))
  199. {
  200. c.inc_cl(40);
  201. }
  202. else if(c.cl()>0 && vp.size()==2)
  203. {
  204. c[0]=vp[0];
  205. c[1]=vp[1];
  206. c.inc_cl(10);
  207. }
  208. else
  209. {
  210. select_one_ant(c,vp);
  211. }
  212. loc_point &refc=m_d(1);
  213. if(c.m_type==4 && c.cl()<=20 && refc.is_same_site(c) && refc.time_off(c)<5 ){
  214. logn_info(3,"{test}first point:site=%d,card=%d,(%f,%f) else:(%f,%f),cred:%d,size:%d",c.m_sid,c.m_cid,c[0].x,c[0].y,c[1].x,c[1].y,c.cl(),vp.size());
  215. if(const auto & site_ptr=sit_list::instance()->get(c.m_sid)){
  216. double d1=0,d2=0,d3=0;
  217. d1=refc.m_dist1;
  218. d2=site_ptr->dist_direct(c[0]);
  219. d3=site_ptr->dist_direct(c[1]);
  220. if(d1*d2<0 && d1*d3>0){
  221. logn_info(3,"{test}first point:site=%d,card=%d,(%f,%f) else:(%f,%f),cred:%d,size:%d",c.m_sid,c.m_cid,c[0].x,c[0].y,c[1].x,c[1].y,c.cl(),vp.size());
  222. point t=c[0];
  223. c[0]=c[1];
  224. c[1]=t;
  225. c.set_cl(0);
  226. }
  227. else if(d1*d2<0 && d1*d3<0)
  228. c[0].set(refc);
  229. }
  230. }
  231. }
  232. virtual fit_result * get_best_fit()
  233. {
  234. return best_fit_raw(4,4);
  235. }
  236. virtual double getA(const fit_result * fit,const double scale,const double dt)
  237. {
  238. double a=2.5;
  239. if(fabs(fit->k)<2/(3.6*scale) && fabs(fit->k)>0.5/(3.6*scale) && dt<10)
  240. {
  241. a=0.3;
  242. }
  243. return a;
  244. }
  245. virtual bool revise_by_history(point & pt, const site*sit, int64_t timestamp)
  246. {
  247. if(!card_path::inst().is_at_path(pt)) //if point not on the path
  248. return false;
  249. point dstp = sit->get_dstp(pt);
  250. if(dstp.empty())
  251. {
  252. log_warn("person.dstp empty,");
  253. }
  254. push_data_point dp;
  255. dp.dstp.set(dstp);
  256. dp.ct = m_d(0).m_ct;
  257. dp.valid = true;
  258. dp.stop_cnt = 5;
  259. dp.lp = m_d(0);
  260. dp.set(pt);
  261. { //don't delete the braces
  262. std::lock_guard<std::mutex> lock(m_owner->m_mtx);
  263. m_owner->m_push_list.clear();
  264. m_owner->m_push_list.push(dp);
  265. //dp.lp.debug_out("person");
  266. }
  267. return true;
  268. }
  269. };
  270. struct car_point_filter:select_point_object
  271. {
  272. car_point_filter(select_tool * owner)
  273. :select_point_object(owner)
  274. ,m_last_fit_valid(false)
  275. ,m_last_fit_k(0)
  276. ,m_last_fit_kb(0)
  277. ,m_last_fit_ka(0)
  278. ,m_last_fit_xo(0)
  279. ,m_last_fit_yo(0)
  280. ,m_last_fit_md_x(0)
  281. ,m_last_fit_md_y(0)
  282. ,m_last_fit_time_sec(0)
  283. ,m_last_fit_nearest_time_sec(0)
  284. ,m_last_time_sec(0)
  285. ,m_if_turning(false)
  286. {}
  287. bool m_last_fit_valid = false;
  288. double m_last_fit_k ;
  289. double m_last_fit_kb;
  290. double m_last_fit_ka;
  291. double m_last_fit_xo ;
  292. double m_last_fit_yo;
  293. double m_last_fit_md_x;
  294. double m_last_fit_md_y;
  295. double m_last_fit_time_sec; //x(0) of latest valid fit
  296. double m_last_fit_nearest_time_sec;
  297. double m_last_time_sec=0;
  298. bool m_if_turning=false;
  299. point m_turning_pt;
  300. point m_turning_ept;
  301. double m_simple_rec_kx,m_simple_rec_ky;
  302. const double m_fit_differ=4;
  303. const double m_pos_differ=8;
  304. virtual void reset_fit(double d){}
  305. virtual void select_solution1(loc_point &c,const std::vector<point> &vp,const double scale)
  306. {
  307. //two ants.
  308. if(c.cl()>0 && vp.size()==2)//m_card->smoothFlag() )
  309. {
  310. c[0]=vp[0];
  311. c[1]=vp[1];
  312. c.inc_cl(50);
  313. }
  314. else if(filter_by_fit(c,vp,scale))
  315. {
  316. c.inc_cl(40);
  317. }
  318. else
  319. {
  320. select_one_ant(c,vp);
  321. }
  322. }
  323. const fit_result* best_fit()const
  324. {
  325. if(m_cur_fit.k==0 && m_cur_fit.ke==0)
  326. return nullptr;
  327. return &m_cur_fit;
  328. }
  329. virtual fit_result * get_best_fit()
  330. {
  331. return best_fit_raw(5);
  332. }
  333. virtual double getA(const fit_result * fit,const double scale,const double dt)
  334. {
  335. double a=2.5;
  336. if(fabs(fit->k)<10/(3.6*scale) && fabs(fit->k)>1/(3.6*scale) && dt<20)
  337. {
  338. a=1;
  339. }
  340. if(fabs(fit->k)<=1/(3.6*scale) && dt<20)
  341. {
  342. a=-1;
  343. }
  344. return a;
  345. }
  346. void reset_turning()
  347. {
  348. m_if_turning=false;
  349. m_turning_pt.set(0,0);
  350. m_turning_ept.set(0,0);
  351. }
  352. void generate_list(point &pt, const site*sit, bool is_whole_list)
  353. {
  354. if(is_whole_list)
  355. {
  356. put_loc_point(pt, sit, m_d(0).m_ct, m_d(0));
  357. }
  358. else
  359. {
  360. put_single_loc_point(pt, sit, m_d(0).m_ct, m_d(0));
  361. }
  362. }
  363. void turning_mapping(point &rpt,const site*sit)
  364. {
  365. if(!m_if_turning)return;
  366. point sit_location; //projection
  367. sit_location = sit->get_dstp(m_turning_pt);
  368. if(sit_location.empty())
  369. {
  370. log_error("%d get_dstp point error.....",sit->m_id);
  371. }
  372. double dist1=sit_location.dist(rpt);
  373. double dist2=sit_location.dist(m_turning_pt);
  374. double dist3=m_turning_pt.dist(rpt); // dist1 is supposed to be = dist2+dist3
  375. if(dist1<=dist2 || dist1<=dist3)
  376. {
  377. if(dist2-dist1>3||dist1<=dist3)
  378. {
  379. //printf("reset turning\n");
  380. reset_turning(); // may encounter problems
  381. }
  382. return;
  383. }
  384. if(dist3>10)dist3=10; // turning distance no more than 10
  385. double turning_x,turning_y;
  386. double dist4=m_turning_pt.dist(m_turning_ept);
  387. turning_x=m_turning_pt.x + dist3 * (m_turning_ept.x - m_turning_pt.x) / dist4;
  388. turning_y=m_turning_pt.y + dist3 * (m_turning_ept.y - m_turning_pt.y) / dist4;
  389. rpt.set(turning_x,turning_y);
  390. }
  391. void put_single_loc_point(point &pt, const site*sit, int ct, loc_point &lp)
  392. {
  393. point rpt;
  394. rpt.set(pt);
  395. turning_mapping(rpt,sit);
  396. if(!card_path::inst().is_at_path(rpt)) //if point not on the path
  397. {
  398. lp.debug_out();
  399. return;
  400. }
  401. point dstp; //projection
  402. if(!m_if_turning)
  403. {
  404. //dstp.set(sit->x,sit->y);
  405. dstp = sit->get_dstp(pt);
  406. if(dstp.empty())
  407. {
  408. log_error("error.here....here.");
  409. }
  410. }
  411. else
  412. {
  413. dstp.set(m_turning_pt);
  414. }
  415. push_data_point dp;
  416. dp.dstp.set(dstp);
  417. dp.ct=ct;
  418. dp.valid=true;
  419. dp.stop_cnt=5;
  420. dp.lp=lp;
  421. dp.set(rpt);
  422. { //don't delete the braces
  423. std::lock_guard<std::mutex> lock(m_owner->m_mtx);
  424. m_owner->m_push_list.clear();
  425. m_owner->m_push_list.push(dp);
  426. //dp.lp.debug_out("single point .");
  427. }
  428. }
  429. /* 根据历史数据估计定位点
  430. *
  431. * param
  432. * const site* sit 分站
  433. * double m_time_sec 秒数
  434. * return
  435. *
  436. *
  437. */
  438. double estimate_point_by_history(const site*sit, double m_time_sec)
  439. {
  440. double estimate_dist = m_last_fit_k * (m_time_sec-m_last_fit_xo) + m_last_fit_kb + m_last_fit_yo;
  441. point pt(m_last_fit_md_x + estimate_dist * m_simple_rec_kx, m_last_fit_md_y + estimate_dist * m_simple_rec_ky);
  442. int fidx = find_first(0);
  443. if(fidx >= 0)
  444. {
  445. loc_point& f = m_d[fidx];
  446. estimate_dist = f.loc_dist(pt);
  447. }
  448. else
  449. estimate_dist = 0;
  450. return estimate_dist;
  451. }
  452. /*
  453. * 转换距离为坐标点
  454. * */
  455. point convert_dist_to_pt(double dist, const site*sit)
  456. {
  457. int fidx = find_first(0);
  458. if(fidx < 0)
  459. return point(0, 0);
  460. loc_point& f = m_d[fidx];
  461. return point(f.m_sol[0].x + dist * m_simple_rec_kx, f.m_sol[0].y + dist * m_simple_rec_ky);
  462. }
  463. void put_loc_point(point &pt, const site*sit, int ct, loc_point &lp)
  464. {
  465. point rpt;
  466. rpt.set(pt);
  467. turning_mapping(rpt,sit);
  468. if(!card_path::inst().is_at_path(pt)) //if point not on the path
  469. {
  470. lp.debug_out();
  471. return;
  472. }
  473. point dstp; //projection
  474. if(!m_if_turning)
  475. {
  476. dstp = sit->get_dstp(pt);
  477. if(dstp.empty())
  478. log_error("dstp.empty()..");
  479. }
  480. else
  481. {
  482. dstp.set(m_turning_pt);
  483. }
  484. int size = 0;
  485. push_data_point dp[13];
  486. dp[size].dstp.set(dstp);
  487. dp[size].ct=ct;
  488. dp[size].valid=true;
  489. dp[size].stop_cnt=5;
  490. dp[size].lp=lp;
  491. dp[size].set(rpt);
  492. double missing_time = m_d(0).m_time/1000.;
  493. size++;
  494. for(;size<13;size++)
  495. {
  496. dp[size].dstp.set(dstp);
  497. dp[size].ct = ct;
  498. dp[size].valid=true;
  499. dp[size].stop_cnt=5;
  500. double mt = missing_time + size;
  501. double missing_dist = estimate_point_by_history(sit, mt);
  502. point missing_point = convert_dist_to_pt(missing_dist, sit);
  503. if(!card_path::inst().is_at_path(missing_point)) //if point not on the path
  504. {
  505. break;
  506. }
  507. turning_mapping(missing_point,sit); //turning
  508. dp[size].set(missing_point);
  509. dp[size].lp.set(missing_point);
  510. dp[size].lp.m_time=(int64_t)(missing_time * 1000);
  511. dp[size].lp.m_sid = sit->m_id;
  512. }
  513. {
  514. std::lock_guard<std::mutex> lock(m_owner->m_mtx);
  515. m_owner->m_push_list.clear();
  516. for(int i=0;i<size;i++)
  517. {
  518. m_owner->m_push_list.push(dp[i]);
  519. }
  520. }
  521. }
  522. /*
  523. * 转换点为距离
  524. * */
  525. double convert_pt_to_dist(point &pt, const site* sit)
  526. {
  527. double dist = 0;
  528. int fidx = find_first(0);
  529. if(fidx>=0)
  530. {
  531. loc_point&f=m_d[fidx];
  532. dist = f.loc_dist(pt);
  533. if(dist!=0)
  534. {
  535. m_simple_rec_kx = (pt.x - f.m_sol[0].x) / dist;
  536. m_simple_rec_ky = (pt.y - f.m_sol[0].y) / dist;
  537. }
  538. }
  539. if(fidx<0 || dist==0)
  540. {
  541. m_simple_rec_kx = 0;
  542. m_simple_rec_ky = 0;
  543. }
  544. return dist;
  545. }
  546. virtual bool revise_by_history(point & pt, const site*sit, int64_t timestamp)
  547. {
  548. bool flag =false;
  549. if(m_line.empty() || !m_line.contain(m_d(0),0.1))
  550. {
  551. m_last_fit_valid = false;
  552. m_last_fit_time_sec = 0;
  553. m_last_fit_k = 0;
  554. m_last_fit_kb = 0;
  555. m_last_fit_ka = 0;
  556. m_last_fit_xo = 0;
  557. m_last_fit_yo = 0;
  558. m_last_fit_nearest_time_sec = 0;
  559. m_last_time_sec = 0;
  560. reset_turning();
  561. generate_list(pt, sit, false);
  562. return true;
  563. }
  564. // convert pt to distance
  565. double dist = convert_pt_to_dist(pt, sit);
  566. double m_time_sec = timestamp / 1000.; //second
  567. if(m_time_sec - m_last_fit_time_sec > 60)m_last_fit_valid = false;
  568. // update acc
  569. //m_accumulate_acc = m_d(0).m_acc;
  570. // choose data by fit
  571. const fit_result*fit=best_fit();
  572. bool if_change_fit=false;
  573. if(fit!=nullptr && fit->ke<=1 && m_time_sec - m_fitk.x(0) <= 15 && fabs(fit->k) < m_pos_differ)
  574. {
  575. // put m_acccumulate_acc into consideration
  576. // fit->k - m_last_fit_k < m_accumulate_acc
  577. if(m_last_fit_valid == true && m_last_fit_k * fit->k > -0.6)
  578. {
  579. //if point is too near the sit: do not not judge the backwards
  580. double est1 = estimate_point_by_history(sit, m_last_fit_time_sec);
  581. double est2 = fit->k * (m_time_sec-fit->xo) + fit->kb + fit->yo;
  582. if(fabs(est1-est2)< (m_time_sec - m_last_fit_time_sec) * 5) // large jump is not allowed
  583. if_change_fit=true;
  584. }
  585. else if(m_last_fit_valid==false)
  586. if_change_fit=true;
  587. }
  588. if(if_change_fit)
  589. {
  590. m_last_fit_valid = true;
  591. m_last_fit_time_sec = m_fitk.x(0);
  592. m_last_fit_k = fit->k;
  593. m_last_fit_kb = fit->kb;
  594. m_last_fit_ka = fit->ka;
  595. m_last_fit_xo = fit->xo;
  596. m_last_fit_yo = fit->yo;
  597. m_last_fit_nearest_time_sec = m_fitk.x(0);
  598. int fidx=find_first(0);
  599. if(fidx<0)
  600. {
  601. m_last_fit_md_x = 0;
  602. m_last_fit_md_y = 0;
  603. }
  604. else{
  605. loc_point&f=m_d[fidx];
  606. m_last_fit_md_x = f.m_sol[0].x;
  607. m_last_fit_md_y = f.m_sol[0].y;
  608. }
  609. }
  610. // revise
  611. double estimate_dist = estimate_point_by_history(sit, m_time_sec);
  612. if(m_last_fit_valid && m_time_sec - m_last_fit_time_sec < 20)
  613. {
  614. if(fabs(m_last_fit_k) > 0.5 && fabs(estimate_dist-dist)>m_fit_differ)
  615. dist=estimate_dist;
  616. else if(fabs(m_last_fit_k) <= 0.5 && fabs(estimate_dist-dist)>m_fit_differ * 2)
  617. dist=estimate_dist;
  618. else flag = true;
  619. }
  620. else m_last_fit_nearest_time_sec = m_time_sec;
  621. m_last_time_sec = m_time_sec;
  622. // convert the estimated dist to pt
  623. point mpt = convert_dist_to_pt(dist, sit);
  624. // judging turning
  625. detect_turning(mpt, sit);
  626. // create the list
  627. //if(m_accumulate_acc<-10)generate(mpt, sit,false); generate single point
  628. if(m_last_fit_valid && timestamp/1000. - m_last_fit_time_sec < 20 && fabs(m_last_fit_k) > 0.5)
  629. generate_list(mpt, sit, true); //generate the whole list
  630. else
  631. generate_list(mpt, sit, false); //generate single point
  632. //turning map
  633. turning_mapping(mpt, sit);
  634. pt = mpt;
  635. return flag;
  636. }
  637. // 检测掉头或转弯
  638. void detect_turning(point &mpt, const site*sit)
  639. {
  640. if(m_if_turning)return;
  641. double detect_area = 4;
  642. double detect_angle = 15; //15
  643. double detect_para = 0.25; //0.25
  644. // check angle
  645. double angle=-m_d(0).m_rav; // right+ left-
  646. if(fabs(angle)>180)
  647. return; // invalid data
  648. if(fabs(angle)<detect_angle || !m_last_fit_valid || fabs(m_last_fit_k)<0.01)
  649. return;
  650. // find turning point
  651. std::vector<line_v> turning_list=card_path::inst().find_possible_path(mpt, detect_area);;
  652. //angle1
  653. int fidx = find_first(0);
  654. if(fidx<0)
  655. return;
  656. double dist = m_d[fidx].loc_dist(mpt);
  657. point pt1;
  658. pt1.set(m_d[fidx].m_sol[0]);
  659. double angle1;
  660. if(m_last_fit_k * dist>0)
  661. angle1 = calc_turning_angle(pt1, mpt);
  662. else
  663. angle1 = calc_turning_angle(mpt, pt1);
  664. if(angle1<0)
  665. return;
  666. //finding
  667. for(unsigned int i=0;i<turning_list.size();i++)
  668. {
  669. line_v &l=turning_list[i];
  670. // get map angle
  671. double angle2 = calc_turning_angle(l.v[0], l.v[1]);
  672. double delta = angle1-angle2;
  673. if(delta>180)
  674. delta=delta-360;
  675. if(delta<-180)
  676. delta=delta+360;
  677. if(fabs(delta)<5)continue;
  678. if(fabs(delta)>175)continue;
  679. // turning angle must be correct
  680. if(angle*delta>0 && fabs(angle)>fabs(delta)*detect_para)
  681. {
  682. log_info("turning:(%.5f,%.5f)(%.5f,%.5f)(%.5f,%.5f),a1:%f,a2:%f,delta:%f,angle:%f\n",
  683. pt1.x,pt1.y,l.v[0].x,l.v[0].y,l.v[1].x,l.v[1].y,angle1,angle2,delta,angle);
  684. m_if_turning=true;
  685. m_turning_pt.set(l.v[0]);
  686. m_turning_ept.set(l.v[1]);
  687. break;
  688. }
  689. }
  690. }
  691. // 计算掉头角度
  692. double calc_turning_angle(point &a, point &b)
  693. {
  694. if(fabs(a.x-b.x)<0.001)
  695. {
  696. if(fabs(a.y-b.y)<0.001)return -1;
  697. return b.y>a.y?90:270;
  698. }
  699. double angle=std::atan((b.y-a.y)/(b.x-a.x))*180/3.1415926;
  700. if(a.x>b.x)angle=angle+180;
  701. if(angle<0)angle=angle+360;
  702. return angle;
  703. }
  704. };
  705. //---------------------smooth
  706. struct smooth_tool
  707. {
  708. std::unique_ptr<select_tool>& m_st; // 选择工具类
  709. bool smooth_initial_setting; // 平滑初始化状态
  710. double smooth_speed; // 平滑速度
  711. double smooth_speed_presentation;
  712. int smooth_speed_presentation_cnt;
  713. point smooth_last_position; // 上一个平滑位置
  714. double smooth_last_time_sec; // 上一个平滑时间
  715. point smooth_last_true_position; // 上一个真实位置
  716. line smooth_line; // 平滑线
  717. bool smooth_line_reset=false; //if line reset
  718. bool smooth_halt_condition; //if halting
  719. int smooth_halt_count; //halting count
  720. point smooth_halt_position; //position while begin halting
  721. point smooth_halt_position_plus;
  722. point smooth_halt_position_minus;
  723. smooth_tool()=default;
  724. smooth_tool(std::unique_ptr<select_tool>&st)
  725. :m_st(st)
  726. ,smooth_initial_setting(false)
  727. ,smooth_speed(0)
  728. ,smooth_speed_presentation(0)
  729. ,smooth_speed_presentation_cnt(0)
  730. ,smooth_last_time_sec(0)
  731. ,smooth_halt_condition(0)
  732. ,smooth_halt_count(0)
  733. {}
  734. void smooth_set_loc_point(double t, int ct, const site*sit, loc_point *lp)
  735. {
  736. point pt;
  737. if(smooth_halt_condition)
  738. pt.set(smooth_halt_position);
  739. else
  740. pt.set(smooth_last_position);
  741. lp->m_dist2 = sit->dist_direct(pt);
  742. lp->m_smooth_x = pt.x;
  743. lp->m_smooth_y = pt.y;
  744. lp->m_time = (int64_t)(t*1000);
  745. lp->m_ct = ct;
  746. if(smooth_halt_condition)
  747. {
  748. lp->m_speed=0;
  749. lp->m_stat=0;
  750. }
  751. else
  752. {
  753. lp->m_speed = smooth_speed_presentation * (3.6*sit->m_scale) ; //(m/s) to (km/h)
  754. if(smooth_speed < 0)
  755. lp->m_speed = -lp->m_speed;
  756. if(std::isnan(lp->m_speed))
  757. lp->m_speed=0;
  758. lp->m_stat=1;
  759. }
  760. }
  761. void smooth_reset()
  762. {
  763. smooth_initial_setting = false;
  764. smooth_speed = 0; //smoothed speed
  765. smooth_speed_presentation_cnt = 0;
  766. smooth_last_position = point(0,0); //last position of smoothed point
  767. smooth_last_true_position = point(0,0); //last position of true point
  768. smooth_last_time_sec = 0; //last time second
  769. smooth_halt_condition = false;
  770. smooth_halt_count = 0;
  771. }
  772. bool smooth_initiate(point &pt, double t, const site*sit)
  773. {
  774. smooth_initial_setting=true;
  775. smooth_speed=0;
  776. smooth_speed_presentation_cnt=0;
  777. smooth_last_position = pt;
  778. smooth_last_true_position = pt;
  779. smooth_last_time_sec = t;
  780. smooth_halt_condition=false;
  781. smooth_halt_count=0;
  782. smooth_halt_position=pt;
  783. smooth_halt_position_plus=pt;
  784. smooth_halt_position_minus=pt;
  785. return true;
  786. }
  787. virtual void set(point &pt,loc_point &lp)=0;
  788. loc_point smooth_strategy()
  789. {
  790. loc_point lp;
  791. push_data_point dpt = m_st->getDpt();
  792. if(dpt.empty())
  793. return lp;
  794. point pt;
  795. pt.set(dpt);
  796. double current_t = time(NULL);
  797. const auto & sit = sit_list::instance()->get(dpt.lp.m_sid);
  798. if(dpt.valid)
  799. {
  800. smooth_dist(pt, current_t, dpt.ct, sit.get(), dpt.dstp, &lp);
  801. set(pt,lp);
  802. dpt.lp.m_dist2 = lp.m_dist2;
  803. dpt.lp.m_time = lp.m_time;
  804. dpt.lp.m_ct = lp.m_ct;
  805. dpt.lp.set(lp);
  806. dpt.lp.m_dist = sit->dist_direct(dpt);
  807. dpt.lp.m_speed = lp.m_speed;
  808. dpt.lp.m_stat = lp.m_stat;
  809. dpt.lp.debug_out("get_point");
  810. }
  811. else
  812. {
  813. smooth_set_loc_point(current_t, dpt.ct, sit.get(), &lp);
  814. if(dpt.stop_cnt<=0)
  815. {
  816. lp.m_speed = 0;
  817. lp.m_stat = 0;
  818. }
  819. set(pt, lp);
  820. }
  821. return lp;
  822. }
  823. virtual void smooth_dist(point &pt, double t, int ct, const site*sit, point dstp, loc_point *m_lp = nullptr)=0;
  824. virtual ~smooth_tool(){}
  825. };
  826. struct smooth_tool_person_1:smooth_tool
  827. {
  828. smooth_tool_person_1(std::unique_ptr<select_tool>&m)
  829. :smooth_tool(m)
  830. {}
  831. virtual void set(point &pt,loc_point &lp)
  832. {
  833. lp.set(pt);
  834. }
  835. void smooth_dist(point &pt, double t, int ct, const site*sit, point dstp, loc_point *m_lp = nullptr)
  836. {
  837. if(smooth_line.empty() || !smooth_line.contain(pt,0.1))
  838. {
  839. if(!smooth_line_reset)
  840. {
  841. smooth_reset();
  842. smooth_line_reset=true;
  843. }
  844. else
  845. {
  846. std::vector<point> path=card_path::inst().find_path(smooth_last_true_position, pt);
  847. if(!path.empty() && smooth_last_true_position.dist(path[0])>200)
  848. path.clear();
  849. if(path.empty())
  850. {
  851. smooth_line.set(smooth_last_true_position, pt);
  852. smooth_line_reset=false;
  853. }
  854. else
  855. {
  856. smooth_reset();
  857. }
  858. }
  859. }
  860. else
  861. smooth_line_reset=false;
  862. if(!smooth_initial_setting)
  863. {
  864. smooth_initiate(pt, t, sit);
  865. }
  866. else
  867. {
  868. double current_dist = dstp.dist_direct(pt);
  869. double last_true_position = dstp.dist_direct(smooth_last_true_position);
  870. double max_span = 100;
  871. if(fabs(current_dist-last_true_position)<max_span && t - smooth_last_time_sec < 10)
  872. {
  873. double new_speed = (current_dist-last_true_position) / (t - smooth_last_time_sec);
  874. double speed_differ = fabs(new_speed-smooth_speed);
  875. if(speed_differ>1)new_speed=smooth_speed +1*(new_speed>smooth_speed?1:-1);
  876. smooth_speed = smooth_speed * 0.4 + new_speed * 0.6;
  877. smooth_last_true_position = pt;
  878. smooth_last_position = pt;
  879. smooth_last_time_sec = t;
  880. if(fabs(smooth_speed_presentation)<1e-6 || std::isnan(smooth_speed_presentation))
  881. {
  882. smooth_speed_presentation=fabs(smooth_speed);
  883. }
  884. else
  885. smooth_speed_presentation = smooth_speed_presentation * 0.4 + fabs(smooth_speed) * 0.6;
  886. if(fabs(smooth_speed)<0.1)smooth_speed_presentation=0;
  887. }
  888. else
  889. {
  890. smooth_reset();
  891. smooth_initiate(pt, t, sit);
  892. }
  893. }
  894. if(m_lp != nullptr)//m_time,m_ct,x,y,m_speed,m_stat
  895. {
  896. smooth_set_loc_point(t, ct, sit, m_lp);
  897. }
  898. }
  899. };
  900. struct smooth_tool_car_1:smooth_tool
  901. {
  902. smooth_tool_car_1(std::unique_ptr<select_tool>&m)
  903. :smooth_tool(m)
  904. {}
  905. virtual void set(point &pt,loc_point &lp)
  906. {
  907. lp.set(lp.m_smooth_x,lp.m_smooth_y);
  908. }
  909. void smooth_dist(point &pt, double t, int ct, const site*sit, point dstp, loc_point *m_lp = nullptr)
  910. {
  911. point init_pt(pt.x, pt.y);
  912. if(smooth_line.empty() || !smooth_line.contain(pt,0.1) || smooth_halt_count>6)
  913. {
  914. if(!smooth_line_reset)
  915. {
  916. if(!smooth_line.empty() && !smooth_line.contain(pt,0.1) && !smooth_last_true_position.empty())
  917. {
  918. std::vector<point> path=card_path::inst().find_path(smooth_last_true_position, pt);
  919. if(!path.empty() && smooth_last_true_position.dist(path[0])>200)
  920. path.clear();
  921. log_info("generating critical point in smooth(car):(%.2f,%.2f)->(%.2f,%.2f)\n",
  922. smooth_last_true_position.x, smooth_last_true_position.y, pt.x, pt.y);
  923. if(!path.empty())
  924. {
  925. point critical_point=path[0];
  926. log_info("critical point generated in smooth(car):pt=(%.2f,%.2f),(%.2f,%.2f)->(%.2f,%.2f)\n",
  927. critical_point.x, critical_point.y, smooth_last_true_position.x, smooth_last_true_position.y,
  928. pt.x, pt.y);
  929. init_pt.set(critical_point);
  930. }
  931. }
  932. smooth_reset();
  933. smooth_line_reset=true;
  934. }
  935. else
  936. {
  937. std::vector<point> path=card_path::inst().find_path(smooth_last_true_position, pt);
  938. if(!path.empty() && smooth_last_true_position.dist(path[0])>200)
  939. path.clear();
  940. if(path.empty())
  941. {
  942. smooth_line.set(smooth_last_true_position, pt);
  943. smooth_line_reset=false;
  944. }
  945. else
  946. {
  947. smooth_reset();
  948. }
  949. }
  950. }
  951. else
  952. smooth_line_reset=false;
  953. if(!smooth_initial_setting)
  954. {
  955. smooth_initiate(init_pt, t, sit);
  956. }
  957. else
  958. {
  959. double current_dist = dstp.dist_direct(pt);
  960. double last_position = dstp.dist_direct(smooth_last_position);
  961. double last_true_position = dstp.dist_direct(smooth_last_true_position);
  962. double rec_kx=0;
  963. double rec_ky=0;
  964. if(current_dist!=0)
  965. {
  966. rec_kx = (pt.x - dstp.x)/current_dist;
  967. rec_ky = (pt.y - dstp.y)/current_dist;
  968. }
  969. double next_dist = last_position + smooth_speed * (t-smooth_last_time_sec);
  970. double max_span = 200;
  971. if(fabs(next_dist-current_dist)<max_span && t - smooth_last_time_sec < 10)
  972. {
  973. double new_speed = (current_dist-last_true_position) / (t - smooth_last_time_sec);
  974. // judge halting
  975. if(fabs(new_speed)<0.1)smooth_halt_count++;
  976. else{
  977. smooth_halt_count=0;
  978. }
  979. if(!smooth_halt_condition && smooth_halt_count>=3 && fabs(smooth_speed) < 0.2)
  980. {
  981. smooth_halt_condition=true;
  982. smooth_halt_position=smooth_last_position;
  983. smooth_halt_position_plus=pt;
  984. smooth_halt_position_minus=pt;
  985. }
  986. // handle speed
  987. if(smooth_halt_condition)
  988. {
  989. double halt_position = dstp.dist_direct(smooth_halt_position);
  990. double halt_position_plus = dstp.dist_direct(smooth_halt_position_plus);
  991. double halt_position_minus = dstp.dist_direct(smooth_halt_position_minus);
  992. if(halt_position_plus<current_dist)halt_position_plus=current_dist;
  993. if(halt_position_minus>current_dist)halt_position_minus=current_dist;
  994. smooth_halt_position_plus = point(dstp.x + halt_position_plus * rec_kx, dstp.y + halt_position_plus * rec_ky);
  995. smooth_halt_position_minus = point(dstp.x + halt_position_minus * rec_kx, dstp.y + halt_position_minus * rec_ky);
  996. if(fabs(halt_position_plus - halt_position_minus)>1)
  997. {
  998. smooth_halt_condition=false;
  999. last_position = halt_position;
  1000. smooth_speed = 0;
  1001. }
  1002. }
  1003. else
  1004. {
  1005. if(fabs(smooth_speed)<1e-6 || std::isnan(smooth_speed))
  1006. {
  1007. smooth_speed=new_speed;
  1008. if(smooth_speed>2.5)smooth_speed=2.5;
  1009. if(smooth_speed<-2.5)smooth_speed=-2.5;
  1010. }
  1011. else
  1012. {
  1013. double speed_differ = fabs(new_speed-smooth_speed);
  1014. if(speed_differ>1)
  1015. new_speed=smooth_speed +1*(new_speed>smooth_speed?1:-1);
  1016. smooth_speed = smooth_speed * 0.4 + new_speed * 0.6;
  1017. }
  1018. if(fabs(smooth_speed_presentation)<1e-6 || std::isnan(smooth_speed_presentation))
  1019. {
  1020. smooth_speed_presentation=fabs(smooth_speed);
  1021. }
  1022. else
  1023. smooth_speed_presentation = smooth_speed_presentation * 0.4 + fabs(smooth_speed) * 0.6;
  1024. // must obey speed direction
  1025. if(smooth_speed * (current_dist-last_position) > 0)
  1026. {
  1027. last_position = last_position+smooth_speed*(t-smooth_last_time_sec);
  1028. if(smooth_speed * (current_dist-last_position) < 0)
  1029. {
  1030. last_position = current_dist;
  1031. }
  1032. smooth_speed_presentation_cnt=0;
  1033. }
  1034. else
  1035. {
  1036. if(smooth_speed_presentation_cnt<3)
  1037. smooth_speed_presentation_cnt++;
  1038. else
  1039. smooth_speed_presentation=0;
  1040. }
  1041. if(fabs(smooth_speed)<0.1)smooth_speed_presentation=0;
  1042. double revise_para = 0.2;
  1043. if(fabs(smooth_speed) < 0.01 || smooth_speed * (current_dist-last_position) < 0)
  1044. revise_para=0;
  1045. last_position=last_position+(current_dist-last_position)*revise_para;
  1046. }
  1047. smooth_last_position = point(dstp.x + last_position * rec_kx, dstp.y + last_position * rec_ky);
  1048. smooth_last_true_position = pt;
  1049. smooth_last_time_sec = t;
  1050. }
  1051. else
  1052. {
  1053. smooth_reset();
  1054. smooth_initiate(pt, t, sit);
  1055. }
  1056. }
  1057. if(m_lp != nullptr)//m_time,m_ct,x,y,m_speed,m_stat
  1058. {
  1059. smooth_set_loc_point(t, ct, sit, m_lp);
  1060. }
  1061. }
  1062. };
  1063. struct smooth_tool_drivingface_car_1:smooth_tool
  1064. {
  1065. smooth_tool_drivingface_car_1(std::unique_ptr<select_tool>&m)
  1066. :smooth_tool(m)
  1067. {}
  1068. virtual void set(point&p,loc_point&lp){}
  1069. virtual void smooth_dist(point &pt, double t, int ct, const site*sit, point dstp, loc_point *m_lp = nullptr){}
  1070. };
  1071. //---------------------------------
  1072. DEF_EXCEPTION (no_tool);
  1073. struct select_tool_manage
  1074. {
  1075. void create_tool(const std::string &s,std::unique_ptr <select_tool> &set,std::unique_ptr <smooth_tool> &smt)
  1076. {
  1077. if(!s.compare(std::string{"PS_1"}))
  1078. {
  1079. set.reset(new select_tool_person_1());
  1080. smt.reset(new smooth_tool_person_1(set));
  1081. }
  1082. else if(!s.compare(std::string{"PS_2"}))
  1083. {
  1084. set.reset(new select_tool_person_2());
  1085. smt.reset(new smooth_tool_person_1(set));
  1086. }
  1087. else if(!s.compare(std::string{"CS_1"}))
  1088. {
  1089. set.reset(new select_tool_car_1());
  1090. smt.reset(new smooth_tool_car_1(set));
  1091. }
  1092. else if(!s.compare(std::string{"WS_1"}))
  1093. {
  1094. set.reset(new select_tool_person_1());
  1095. smt.reset(new smooth_tool_person_1(set));
  1096. }
  1097. else
  1098. {
  1099. THROW_EXCEPTION(no_tool,"未定义%s的策略,需要在config.ini中定义",s.c_str());
  1100. }
  1101. }
  1102. static select_tool_manage * instance();
  1103. };
  1104. #endif