select_tool.h 30 KB

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