select_tool.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #include "select_tool.h"
  2. #include "ant.h"
  3. #include "card_path.h"
  4. #include "log.h"
  5. void select_point_object::att_initiate()
  6. {
  7. m_fitk.add_tool(30,5,5);
  8. m_fitk.add_tool(30,5,6);
  9. m_fitk.add_tool(30,10,10);
  10. m_fitk.add_tool(30,10,15);
  11. m_fitk.add_tool(20,5,6);
  12. m_fitk.add_tool(30,4,6);
  13. m_fitk.add_tool(40,4,6);
  14. m_fita.add_tool(15,5,5);
  15. m_begin=m_last=0;
  16. }
  17. loc_point select_point_object::select_solution_impl(const std::vector<point> vp,const std::vector<loc_message>&lm)
  18. {
  19. bool flag=false;
  20. loc_point lp;
  21. if(vp.size()==4)
  22. {
  23. m_d.grow().reset().set_source(lm[0],lm[1]);
  24. flag = true;
  25. }
  26. if(vp.size()==2 && lm[0].m_card_ct - last_ct() == 1)
  27. {
  28. m_d.grow().reset().set_source(lm[0]);
  29. flag = true;
  30. }
  31. if(flag)
  32. {
  33. if(!select_solution(vp,lm[0].m_sit.get(),lp))
  34. {
  35. m_cur_fit.reset();
  36. return lp;
  37. }
  38. }
  39. m_ct = lm[0].m_card_ct;
  40. return lp;
  41. }
  42. int select_point_object::find_last(int start)
  43. {
  44. for(int i=start,len=m_d.size();i<len;i++)
  45. {
  46. if(m_d(i).cl()>0)
  47. return i;
  48. }
  49. return -1;
  50. }
  51. int select_point_object::find_first(int start)
  52. {
  53. for(int i=start,len=m_d.size();i<len;i++)
  54. {
  55. if(m_d[i].cl()>0)
  56. return i;
  57. }
  58. return -1;
  59. }
  60. bool select_point_object::filter_by_fit(loc_point & c,const std::vector<point> & vp,const double scale)
  61. {
  62. fit_result * fit = get_best_fit();
  63. if(fit==nullptr || m_begin==nullptr || fit->ke>2)
  64. return false;
  65. loc_point &f = *m_begin;
  66. std::array<solpoint,4> v;
  67. int cnt = vp.size();
  68. for(int i=0;i<cnt;i++)
  69. {
  70. v[i].set_sol(vp[i],fabs(fit->testk(c.m_time/1000.,f.dist_direct(vp[i]))));
  71. }
  72. std::sort(&v[0],&v[0]+cnt);
  73. double a = getA(fit,scale,v[1].score()-v[0].score());
  74. if(a<0)
  75. return false;
  76. if(!filter_by_acc(c,v,a))
  77. {
  78. c.set_cl(0);
  79. return true; //false?
  80. }
  81. reset_fit(vp[0].dist(v[0]));
  82. c[0]=v[0];
  83. c[1]=v[1];
  84. return true;
  85. }
  86. bool select_point_object::filter_by_acc(loc_point&c,std::array<solpoint,4>&v,double a)
  87. {
  88. if(!m_last->is_same_site(c))
  89. return true;
  90. double td=m_last->time_off(c);
  91. if(v[0].score()>a*td*td)
  92. return false;
  93. return true;
  94. }
  95. void select_point_object::select_one_ant(loc_point &c,const std::vector<point> & vp)
  96. {
  97. int last=find_last(1);
  98. if(last>0)
  99. {
  100. loc_point&p=m_d(last);
  101. int cnt=vp.size();
  102. std::array<solpoint,4> res;
  103. //find the shortest dis
  104. for(int i=0;i<cnt;i++)
  105. res[i].set_sol(vp[i],vp[i].dist(p[0]));
  106. std::sort(&res[0],&res[0]+cnt);
  107. c[1].set(res[1]);
  108. c[0].set(res[0]);
  109. c.inc_cl(5);
  110. }
  111. }
  112. point select_point_object::select_solution0(std::vector<point> &tvp,const double scale)
  113. {
  114. //log_info("lemon test 2 :cardid:%d sit:%f sitid:%d",m_d(0).m_cid,scale,m_d(0).m_sid);
  115. loc_point&c=m_d(0);
  116. if(m_d.size()==1)
  117. {
  118. //first point ,only accpet two ants good data.
  119. if(c.cl()>0 && tvp.size()<4)
  120. {
  121. c[1]=tvp[1];
  122. return c[0]=tvp[0];
  123. }
  124. m_d.skip(1);
  125. return point(0,0);
  126. }
  127. select_solution1(c,tvp,scale);
  128. return c[0];
  129. }
  130. bool select_point_object::select_solution(const std::vector<point> &vp,const site*sit,loc_point &p)
  131. {
  132. //log_info("lemon test 1 :cardid:%d sit:%d sitid:%d",m_d(0).m_cid,sit->m_id,m_d(0).m_sid);
  133. remove_history();
  134. std::vector<point> tvp(vp.begin(),vp.end());
  135. if(vp.size()==4)
  136. {
  137. int c=0;
  138. std::array<solpoint,4> res;
  139. for(int i=0;i<2;i++)
  140. {
  141. int x = i+2;
  142. double d=vp[i].dist(vp[x]);
  143. if(d<sit->ant_dist()*3)
  144. {
  145. res[c++].set_sol(vp[i].middle(vp[x]),d);
  146. }
  147. else
  148. {
  149. res[c++].set_sol(vp[i]);
  150. res[c++].set_sol(vp[x]);
  151. }
  152. }
  153. std::sort(&res[0],&res[0]+c);
  154. tvp.clear();
  155. for(int i=0;i<c;i++)
  156. tvp.push_back(res[i]);
  157. m_d(0).inc_cl(10);
  158. }
  159. point pt = select_solution0(tvp,sit->m_scale);
  160. if(pt.empty() || m_d.empty())
  161. return false;
  162. m_d(0).set(pt);
  163. if(!m_d(0).empty())
  164. m_d(0).m_dist=sit->dist_direct(pt);
  165. else
  166. {
  167. m_d(0).set_cl(0);
  168. if(m_last) m_d(0).m_dist=0.01*m_last->m_dist>0?1:-1;
  169. }
  170. //
  171. //std_info("revise_by_history:::%llu",m_d(0).m_time);
  172. bool fg=revise_by_history(pt,sit,m_d(0).m_time);
  173. if(!fg)
  174. {
  175. 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);
  176. }
  177. if(!card_path::inst().is_at_path(pt))
  178. {
  179. m_d(0).set_cl(0);
  180. 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);
  181. return false;
  182. }
  183. m_last=&m_d(0);
  184. if(m_line.empty() && m_d.size()>=2 && !make_line())
  185. return false;
  186. if(!m_line.contain(m_d(0),0.01) || (m_begin && !m_line.contain(m_begin->m_sol[0], 0.01)))
  187. {
  188. m_fitk.reset_data();
  189. m_fita.reset_data();
  190. m_begin=m_last=nullptr;
  191. int i0=find_last(1);
  192. if(i0==-1)
  193. return false;
  194. std::vector<point> path=card_path::inst().find_path(m_d(i0),m_d(0));
  195. m_d.skip(m_d.size()-i0);
  196. if(path.empty())
  197. {
  198. m_line.clear();
  199. return false;
  200. }
  201. m_line.set(path.back(),m_d(0));
  202. }
  203. if(!m_begin)
  204. {
  205. int idx=find_first(0);
  206. if(idx>=0) m_begin=&m_d[idx];
  207. }
  208. if(!m_last)
  209. {
  210. int idx=find_last(0);
  211. if(idx>=0) m_last=&m_d(idx);
  212. }
  213. if(m_begin && m_d(0).cl())
  214. {
  215. //implemented by li
  216. int lastID1=find_last(1);
  217. int lastID2=-1;
  218. if(lastID1!=-1)
  219. lastID2=find_last(lastID1+1);
  220. if(lastID2!=-1)
  221. {
  222. double t0=m_last->m_time/1000., t1=m_d(lastID1).m_time/1000., t2=m_d(lastID2).m_time/1000.;
  223. double d0=m_begin->loc_dist(*m_last), d1=m_begin->loc_dist(m_d(lastID1)), d2=m_begin->loc_dist(m_d(lastID2));
  224. double k1=(d1-d0)/(t1-t0), k2=(d2-d1)/(t2-t1);
  225. if(t0-t1<5 && t1-t2<5 && fabs(k2-k1)<0.5)
  226. {
  227. double tbegin = t0-3;
  228. while(tbegin<t1+0.5)
  229. tbegin=tbegin+1;
  230. double tk=(d0-d1)/(t0-t1), tb=d1-tk*t1; //d1+(d0-d1)/(t0-t1)*(t-t1)
  231. for(double ti=tbegin;ti<t0;ti=ti+1)
  232. {
  233. //std_info("add ..seelct");
  234. m_fitk.add(ti, tk*ti+tb);
  235. }
  236. }
  237. }
  238. m_fitk.add(m_last->m_time/1000.,m_begin->loc_dist(*m_last));
  239. if(m_d.size()>1)
  240. {
  241. int pre=find_last(1);
  242. if(pre>0)
  243. {
  244. m_fita.add(m_d(0).m_time/1000.,m_begin->loc_dist(m_d(0))-m_begin->loc_dist(m_d(pre)));
  245. }
  246. }
  247. }
  248. p.set(pt);
  249. save_k();
  250. p.m_useless=fg;
  251. return true;
  252. }
  253. bool select_point_object::make_line()
  254. {
  255. int i0=-1,i1=-1;
  256. if(-1==(i0=find_last(0)))
  257. return false;
  258. if(-1==(i1=find_last(i0+1)))
  259. return false;
  260. m_line.set(m_d(i0),m_d(i1));
  261. return true;
  262. }
  263. void select_point_object::remove_history()
  264. {
  265. loc_point&b=m_d(0);
  266. if(m_d.size()>120 || (m_d.size()>2 && m_d(1).time_off(b)>max_histime))
  267. {
  268. m_d.skip_if([&b,this](loc_point&p){ return p.time_off(b)>max_histime;});
  269. m_fitk.reset_data();
  270. m_fita.reset_data();
  271. m_cur_fit.reset();
  272. m_begin=m_last=nullptr;
  273. int idx=find_first(0);
  274. if(idx<0)
  275. return;
  276. m_begin=&m_d[idx];
  277. idx=find_last(1);
  278. m_last=&m_d(idx);
  279. double dist=0,dist2=0;
  280. for(int len=std::min(15,m_d.size()-1),i=len;i>0;i--)
  281. {
  282. if(!m_d(i).cl())
  283. continue;
  284. int lastID1=find_last(i+1);
  285. int lastID2=-1;
  286. if(lastID1!=-1)
  287. lastID2=find_last(lastID1+1);
  288. if(lastID2!=-1)
  289. {
  290. double t0=m_d(i).m_time/1000., t1=m_d(lastID1).m_time/1000., t2=m_d(lastID2).m_time/1000.;
  291. double d0=m_begin->loc_dist(m_d(i)[0]), d1=m_begin->loc_dist(m_d(lastID1)[0]),
  292. d2=m_begin->loc_dist(m_d(lastID2)[0]);
  293. double k1=(d1-d0)/(t1-t0), k2=(d2-d1)/(t2-t1);
  294. if(t0-t1<5 && t1-t2<5 && fabs(k2-k1)<0.5)
  295. {
  296. double tbegin = t0-3;
  297. while(tbegin<t1+0.5)
  298. tbegin=tbegin+1;
  299. double tk=(d0-d1)/(t0-t1), tb=d1-tk*t1; //d1+(d0-d1)/(t0-t1)*(t-t1)
  300. for(double ti=tbegin;ti<t0;ti=ti+1)
  301. {
  302. //std_info("add remove..");
  303. m_fitk.add(ti, tk*ti+tb);
  304. }
  305. }
  306. }
  307. dist=m_begin->loc_dist(m_d(i)[0]);
  308. //std_info("add remove..");
  309. m_fitk.add(m_d(i).m_time/1000.,dist);
  310. if(i==len)
  311. continue;
  312. m_fita.add(m_d(i).m_time/1000.,dist-dist2);
  313. dist2=dist;
  314. }
  315. save_k();
  316. }
  317. }
  318. void select_point_object::save_k()
  319. {
  320. const fit_result*fk=best_fit_raw(0,4);
  321. if(!fk)
  322. {
  323. m_cur_fit.reset();
  324. return;
  325. }
  326. m_cur_fit=*fk;
  327. fit_result&r=m_cur_fit;
  328. card_fit*fa=&m_fita[0];
  329. if(fa->is_valid() && fa->ke<0.1 && fk->k*fa->k<0)
  330. {
  331. double dk=fa->k*fa->num_point;
  332. r.ka=fa->k;
  333. if((fk->k+dk)*fk->k<0)
  334. r.k=0;
  335. else
  336. r.k+=dk;
  337. double y=fk->k*m_fitk(0).x+fk->kb;
  338. r.kb=y-m_fitk(0).x*r.k;
  339. }
  340. }
  341. fit_result* select_point_object::best_fit_raw(int num_point,int start,int last)
  342. {
  343. card_fit*fit=nullptr;
  344. start=std::max(start,0);
  345. last =std::min(last,m_fitk.tool_size());
  346. if(last==-1)
  347. last=m_fitk.tool_size();
  348. //std_info("best_fit_raw :%d:%d",start,last);
  349. for(int i=start;i<last;i++)
  350. {
  351. if(!m_fitk[i].is_valid())
  352. continue;
  353. if(m_fitk[i].num_point<num_point)
  354. continue;
  355. if(fit==nullptr)
  356. {
  357. fit=&m_fitk[i];
  358. continue;
  359. }
  360. if(fit->ke>m_fitk[i].ke)
  361. {
  362. fit=&m_fitk[i];
  363. }
  364. }
  365. return fit;
  366. }
  367. select_tool::~select_tool()
  368. {
  369. if(m_spo !=nullptr)
  370. delete m_spo;
  371. }
  372. loc_point select_tool_person_1::select_solution(const std::vector<point> vp,const std::vector<loc_message>&lm)
  373. {
  374. loc_point lp;
  375. //select point.
  376. if(lm[0].tool_index() == 0)
  377. {
  378. if(m_spo==nullptr)
  379. m_spo = new person_point_filter(this);
  380. lp=m_spo->select_solution_impl(vp,lm);
  381. }
  382. else if (lm[0].tool_index() == 2)
  383. {
  384. //for now..
  385. //m_spo = new person_point_filter();
  386. lp=m_spo->select_solution_impl(vp,lm);
  387. }
  388. else
  389. {}
  390. return lp;
  391. }
  392. loc_point select_tool_car_1::select_solution(const std::vector<point> vp,const std::vector<loc_message>&lm)
  393. {
  394. loc_point lp;
  395. //select point.
  396. if(lm[0].tool_index() == 0)
  397. {
  398. if(m_spo==nullptr)
  399. m_spo = new car_point_filter(this);
  400. lp=m_spo->select_solution_impl(vp,lm);
  401. }
  402. else if (lm[0].tool_index() == 2)
  403. {
  404. //for now..
  405. //m_spo = new car_point_filter();
  406. lp=m_spo->select_solution_impl(vp,lm);
  407. }
  408. else
  409. {}
  410. return lp;
  411. }
  412. select_tool_manage * select_tool_manage::instance()
  413. {
  414. static select_tool_manage stm;
  415. return &stm;
  416. }