cons_planner.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. #include "cons_planner/cons_planner.h"
  2. namespace cons {
  3. static common::Path __Comp(common::Point& s, common::Point& e) // 补全路径
  4. {
  5. common::Path comp;
  6. float x = e.x - s.x;
  7. float y = e.y - s.y;
  8. float step_x = fabs(x) / __rlu;
  9. float step_y = fabs(y) / __rlu;
  10. float n = std::max(step_x, step_y);
  11. float dx = x / n;
  12. float dy = y / n;
  13. common::Point p = s;
  14. comp.push_back(p);
  15. for (int i = 0;i < n;i++) {
  16. p.x += dx;
  17. p.y += dy;
  18. comp.push_back(p);
  19. }
  20. return comp;
  21. }
  22. void consPlanner::setPath(common::Path& path)
  23. {
  24. reset();
  25. common::Path compent;
  26. // 稠密化路径
  27. for (int i = 0;i < path.size() - 1;i++) {
  28. if (common::dist(path[i], path[i + 1]) > 2.0 * __rlu) {
  29. common::Path tmp = __Comp(path[i], path[i + 1]);
  30. compent.insert(compent.end(), tmp.begin(), tmp.end());
  31. }
  32. else {
  33. compent.push_back(path[i]);
  34. }
  35. }
  36. compent.push_back(path.back());
  37. compent.back().head = compent.front().head;
  38. common::Path dis;
  39. // 离散路径
  40. for (int i = 0;i < compent.size();i++) {
  41. if (!dis.empty() && i != compent.size() - 1) {
  42. if (common::dist(dis.back(), compent[i]) < __rlu ||
  43. common::dist(compent[i], compent.back()) < __rlu
  44. ) {
  45. continue;
  46. }
  47. }
  48. dis.push_back(compent[i]);
  49. }
  50. path_ = std::move(dis);
  51. LOG(INFO)<<"size: "<<path.size()<<" path_ size: "<<path_.size();
  52. }
  53. void consPlanner::reset()
  54. {
  55. i_ = 0;
  56. path_.clear();
  57. step_ = common::NavStep::STANDBY; // 待命状态
  58. }
  59. void consPlanner::destroy()
  60. {
  61. return;
  62. }
  63. common::NavState consPlanner::computeVelocity(common::Point& sta_pose, common::Twist& cmd)
  64. {
  65. if (!__pathCheck()) return common::NavState::DONE;
  66. float maxmal_next;
  67. Index min_nex = (Index)(config_.minmal_next / __rlu);
  68. Index back_i = path_.size();
  69. Index i = i_;
  70. maxmal_next = std::max(config_.maxmal_next, config_.max_linear);
  71. maxmal_next = std::max(maxmal_next, __rlu);
  72. common::Path path = __exten(path_, (Index)(maxmal_next / __rlu) + 1);
  73. conti: NULL;
  74. {
  75. i_ = __nib(sta_pose, i, path_, config_.max_linear); // 找路径上的最近点
  76. sta_pose.head = path_[i_].head; // * (M_PI / 180.0);
  77. Index max_nex = (Index)(maxmal_next / __rlu);
  78. Index set = i_ + max_nex; // 引导点
  79. bool closr =
  80. (common::dist(path_[i_], path_.back()) < 0.21) ||
  81. ((path_.size() - i_) < 10); // 接近终点
  82. if (closr) {
  83. if (__isArrv(sta_pose)) {
  84. return common::NavState::DONE;
  85. }
  86. }
  87. // 旋转调整处理
  88. {
  89. common::Point base = path[i_]; // i_一定小于path size
  90. common::Point tip = path[i_ + 1];
  91. base.theta = sta_pose.theta + sta_pose.head;
  92. base.theta = common::norm(base.theta);
  93. switch(step_) {
  94. case common::NavStep::STANDBY:
  95. step_ = common::NavStep::TANGENT;
  96. return common::NavState::ROTATE;
  97. break;
  98. case common::NavStep::TANGENT: // 切线调整
  99. /*需要改进*/
  100. if (__rotaTangent(base, tip, cmd) == common::NavState::DONE) {
  101. step_ = common::NavStep::TRACK;
  102. }
  103. return common::NavState::ROTATE;
  104. break;
  105. // case common::NavStep::ANGLE:
  106. // common::Point base = sta_pose;
  107. // common::Point tip = path_.back();
  108. // base.theta = sta_pose.theta + sta_pose.head;
  109. // base.theta = common::norm(base.theta);
  110. // if (__rotaAngle(base.theta, tip.theta, cmd) == common::NavState::DONE) {
  111. // step_ = common::NavStep::COMPLETE;
  112. // }
  113. // return common::NavState::ROTATE;
  114. // break;
  115. // case common::NavStep::COMPLETE:
  116. // reset();
  117. // return common::NavState::DONE;
  118. // break;
  119. case common::NavStep::TRACK:
  120. NULL;
  121. break;
  122. default:
  123. reset();
  124. return common::NavState::DONE;
  125. break;
  126. }
  127. }
  128. float goto_angle = 1e10;
  129. closr = (common::lineL(path_, (int)i_, (int)path_.size()) < config_.close_ad);
  130. // for (int i = (i_ + 1);i < set;i++) {
  131. for (int i = set;i > (i_ + min_nex - 1);i--) {
  132. float angle = __pathTangent(path, i) - __c(sta_pose, path[i]);
  133. angle = fabs(common::norm(angle));
  134. if (angle < goto_angle) {
  135. goto_angle = angle;
  136. set = i;
  137. }
  138. }
  139. if (set > path_.size() - 1 && (i_ + min_nex - 1) < path_.size()) { // 终点牵引
  140. set = path_.size() - 1;
  141. }
  142. float liner = common::dist(sta_pose, path_.back()) * config_.linear_slow_p;
  143. float comp = 0; // 角速度补偿量
  144. {
  145. common::Point goal = path[set];
  146. goal.theta = common::norm(__pathTangent(path, set) + M_PI);
  147. goal.head = 0;
  148. float boto = common::norm(__c(goal, sta_pose) + M_PI);
  149. float keep = common::norm(boto - sta_pose.head - sta_pose.theta);
  150. comp = fabs(keep) < config_.max_angular ? keep :
  151. (keep < 0 ? -config_.max_angular : config_.max_angular);
  152. if (closr) { // 接近终点
  153. if (fabs(keep) > config_.toler_theta) {
  154. comp = fabs(keep) < config_.max_angular ? keep :
  155. (keep < 0 ? -config_.max_angular : config_.max_angular);
  156. }
  157. float ld = common::PLD(path[i_], path[i_ + 1], sta_pose);
  158. if (ld > hypot(config_.toler_x, config_.toler_y)) {
  159. liner *= exp(-10.0 * ld);
  160. }
  161. liner = liner < 0.05 ? 0.05 : liner;
  162. }
  163. else {
  164. if (fabs(keep) > config_.toler_follow_theta ||
  165. fabs(keep) > 0.85) { // 跟随容忍角度误差
  166. cmd.x = 0;
  167. cmd.angular = fabs(keep) < config_.max_angular ? keep :
  168. (keep < 0 ? -config_.max_angular : config_.max_angular);
  169. return common::NavState::ROTATE;
  170. }
  171. }
  172. }
  173. liner = std::min(liner, maxmal_next);
  174. liner = std::min(liner, common::dist(path[i_], path[set]));
  175. // liner = std::min(liner, common::dist(path_[i_], path_.back()));
  176. liner = std::min(liner, common::dist(sta_pose, path[set]));
  177. liner = std::min(liner, config_.max_linear);
  178. liner = std::min(liner, path_[i_].max_linear);
  179. Index locli = set < ((int)path_.size() - 1) ? set : ((int)path_.size() - 1);
  180. local_path_ = __getPah(sta_pose, path[locli], __rlu); // 计算局部路径
  181. common::NavState sd = __cal(sta_pose, path[set], cmd, liner);
  182. comp = fabs(comp) < 0.1 ? comp : (comp > 0 ? 0.1 : -0.1); // 最大补偿10°/s
  183. cmd.angular += comp * 0.1;
  184. // cmd.x *= exp(-10.0 * fabs(comp));
  185. return sd;
  186. }
  187. return common::NavState::ING;
  188. }
  189. common::NavState consPlanner::computeVelocityCommands(common::Point& sta_pose, common::Twist& cmd)
  190. {
  191. return computeVelocity(sta_pose, cmd);
  192. }
  193. /**
  194. * 在path_上截取a长度,起始点i_
  195. */
  196. common::Path consPlanner::interPath(float a)
  197. {
  198. common::Path path;
  199. for (int i = i_;i < (int)path_.size() - 1;i++) {
  200. a -= common::dist(path_[i + 1], path_[i]);
  201. if (a < 0) {
  202. break;
  203. }
  204. path.push_back(path_[i]);
  205. }
  206. return path;
  207. }
  208. common::Config consPlanner::getConfig()
  209. {
  210. return config_;
  211. }
  212. void consPlanner::setConfig(common::Config& conf)
  213. {
  214. config_ = conf;
  215. if (config_.angular_slow_p > 1.0) config_.angular_slow_p = 1.0;
  216. if (config_.linear_slow_p > 1.0) config_.linear_slow_p = 1.0;
  217. }
  218. common::Path consPlanner::getLocalPath()
  219. {
  220. return local_path_;
  221. }
  222. common::Path consPlanner::getGlobalPath()
  223. {
  224. return path_;
  225. }
  226. Index consPlanner::__nib(common::Point& p, Index ci, common::Path& path, float range)
  227. {
  228. Index ni = ci;
  229. float ns = 1e10;
  230. for (Index i = ci;i < path.size();i++) {
  231. float ds = common::dist(p, path[i]);
  232. if (ds < ns) {
  233. ns = ds;
  234. ni = i;
  235. }
  236. if (i != 0) {
  237. range -= common::dist(path[i], path[i - 1]);
  238. }
  239. if (range < 0.0) {
  240. break;
  241. }
  242. }
  243. return ni;
  244. }
  245. common::Path consPlanner::__exten(common::Path& path, Index i)
  246. {
  247. common::Path tp = path;
  248. if (path.size() < 2) return tp;
  249. Index i2 = path.size() - 2;
  250. float x = path.back().x - path[i2].x;
  251. float y = path.back().y - path[i2].y;
  252. float step_x = fabs(x) / __rlu;
  253. float step_y = fabs(y) / __rlu;
  254. float s = std::max(step_x, step_y);
  255. float dx = x / s;
  256. float dy = y / s;
  257. common::Point p = tp.back();
  258. for (int m = i;m > -1;m--) {
  259. p.x += dx;
  260. p.y += dy;
  261. tp.push_back(p);
  262. }
  263. return tp;
  264. }
  265. bool consPlanner::__isArrv(common::Point p)
  266. {
  267. if (path_.size() < 2) return true;
  268. Index i2 = path_.size() - 2;
  269. float x = path_.back().x - path_[i2].x;
  270. float y = path_.back().y - path_[i2].y;
  271. float a = atan2(y, x); // 点的切线方向为到达方向
  272. float cr_x = p.x - path_.back().x;
  273. float cr_y = p.y - path_.back().y;
  274. float cr_ex = cr_x * cos(-a) - cr_y * sin(-a);
  275. float cr_ey = cr_x * sin(-a) + cr_y * cos(-a);
  276. if (cr_ex > 0 ||
  277. (fabs(cr_ex) < config_.toler_x && fabs(cr_ey) < config_.toler_y)) {
  278. return true;
  279. }
  280. return false;
  281. }
  282. common::Path consPlanner::__getPah(const common::Point& start, const common::Point& end, const float rlu)
  283. {
  284. common::Path path;
  285. if (rlu < 1e-3) {
  286. return path;
  287. }
  288. float angle = common::norm(start.theta + start.head); // config_.for_angle);
  289. const float x = (end.x - start.x) * cos(-angle) - (end.y - start.y) * sin(-angle);
  290. const float y = (end.x - start.x) * sin(-angle) + (end.y - start.y) * cos(-angle);
  291. const float kangle = atan2(y, x);
  292. const float l = hypot(x, y);
  293. const float r = 0.5 * l / sin(kangle);
  294. const float step_rad = rlu / r;
  295. const float step_cl = fabs(r * sin(step_rad * 0.5) * 2.f);
  296. float dx = 0.f, dy = 0.f, dangle = 0.f;
  297. int c = 0;
  298. common::Point path_element = start;
  299. while (1) {
  300. dangle += step_rad;
  301. dx += step_cl * cos(dangle);
  302. dy += step_cl * sin(dangle);
  303. path_element.x = start.x +
  304. dx * cos(-angle) + dy * sin(-angle); // trans footprint to map
  305. path_element.y = start.y +
  306. dy * cos(-angle) - dx * sin(-angle);
  307. path_element.theta = common::norm(angle + dangle);
  308. path.push_back(path_element);
  309. if (hypot(path_element.x - end.x, path_element.y - end.y) < rlu) {
  310. path.push_back(end);
  311. break;
  312. }
  313. c++;
  314. if (c > 1000) break;
  315. }
  316. return path;
  317. }
  318. common::NavState consPlanner::__cal(common::Point& start, common::Point& goal, common::Twist& twist, float linear)
  319. {
  320. float a = start.theta + start.head;
  321. float x = (goal.x - start.x) * cos(-a) - (goal.y - start.y) * sin(-a);
  322. float y = (goal.x - start.x) * sin(-a) + (goal.y - start.y) * cos(-a);
  323. float l = x * x + y * y;
  324. float theta = 2.0 * y;
  325. float at = fabs(theta) / config_.max_angular;
  326. float lt = l / std::min(config_.max_linear, linear);
  327. float t = std::max(at, lt);
  328. float dir = (fabs(start.head) > M_PI_2) ? -1.0 : 1.0;
  329. if (t < 1e-5) {
  330. twist = common::Twist();
  331. return common::NavState::TOO_CLOSE;
  332. }
  333. twist.x = l / t * dir;
  334. twist.angular = theta / t;// * dir;
  335. return common::NavState::ING;
  336. }
  337. /**
  338. * 从start到goal的圆弧角
  339. */
  340. float consPlanner::__c(common::Point& start, common::Point& goal)
  341. {
  342. float a = start.theta + start.head;
  343. float x = (goal.x - start.x) * cos(-a) - (goal.y - start.y) * sin(-a);
  344. float y = (goal.x - start.x) * sin(-a) + (goal.y - start.y) * cos(-a);
  345. float l = x * x + y * y;
  346. // float theta = 2.0 * y;
  347. float theta = 2.0 * asin(y / sqrt(l));
  348. if (x < 0) {
  349. theta = (theta > 0) ? (theta - M_PI) : (theta + M_PI);
  350. }
  351. return common::norm(a + theta);
  352. }
  353. common::NavState consPlanner::__rotaTangent(common::Point& base, common::Point& tip, common::Twist& twist)
  354. {
  355. float x = tip.x - base.x;
  356. float y = tip.y - base.y;
  357. float e = common::norm(atan2(y, x) - base.theta);
  358. float rotate = e * config_.linear_slow_p;
  359. if (fabs(e) < config_.toler_start_theta) {
  360. return common::NavState::DONE;
  361. }
  362. twist.x = 0;
  363. twist.angular = fabs(rotate) < config_.max_angular ? rotate :
  364. (rotate < 0 ? -config_.max_angular : config_.max_angular);
  365. return common::NavState::ROTATE;
  366. }
  367. common::NavState consPlanner::__rotaAngle(float base, float tip, common::Twist& twist)
  368. {
  369. float e = tip - base;
  370. float rotate = e * config_.linear_slow_p;
  371. if (fabs(e) < config_.toler_theta) {
  372. return common::NavState::DONE;
  373. }
  374. twist.x = 0;
  375. twist.angular = fabs(rotate) < config_.max_angular ? rotate :
  376. (rotate < 0 ? -config_.max_angular : config_.max_angular);
  377. return common::NavState::ROTATE;
  378. }
  379. float consPlanner::__maxmalDist(common::Path& pt1, common::Path& pt2)
  380. {
  381. float di = 0;
  382. for (common::Point& p1 : pt1) {
  383. float minmal = 1e10;
  384. for (common::Point& p2 : pt2) {
  385. minmal = std::min(minmal, common::dist(p2, p1));
  386. }
  387. di = std::max(minmal, di);
  388. }
  389. return di;
  390. }
  391. float consPlanner::__pathTangent(common::Path& path, Index i)
  392. {
  393. float x = path[i + 1].x - path[i].x;
  394. float y = path[i + 1].y - path[i].y;
  395. return atan2(y, x);
  396. }
  397. bool consPlanner::__pathCheck()
  398. {
  399. if (path_.size() < 2 ||
  400. i_ >= path_.size() ||
  401. false
  402. ) {
  403. return false;
  404. }
  405. return true;
  406. }
  407. }