rs_path.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /*******************************************************************************
  2. * Software License Agreement (BSD License)
  3. *
  4. * Copyright (c) 2022 Zhang Zhimeng
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted provided that the following conditions are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. *
  13. * 2. Redistributions in binary form must reproduce the above copyright notice,
  14. * this list of conditions and the following disclaimer in the documentation
  15. * and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  18. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  20. * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  22. * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  23. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
  25. * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. ******************************************************************************/
  27. #ifndef HYBRID_A_STAR_RS_PATH_HPP_COMBINE
  28. #define HYBRID_A_STAR_RS_PATH_HPP_COMBINE
  29. #include "combine_planning/rs_path.h"
  30. #include <vector>
  31. #include <Eigen/Core>
  32. #include <glog/logging.h>
  33. namespace combine_planning_ns
  34. {
  35. double turning_radius_;
  36. void setTurningRadius(double R)
  37. {
  38. turning_radius_ = R;
  39. }
  40. // P 371: TABLE 1
  41. const RSPath::RSPathSegmentType RSPath::RS_path_segment_type[18][5] = {
  42. {L, R, L, N, N},
  43. {R, L, R, N, N},
  44. {L, R, L, R, N},
  45. {R, L, R, L, N},
  46. {L, R, S, L, N},
  47. {R, L, S, R, N},
  48. {L, S, R, L, N},
  49. {R, S, L, R, N},
  50. {L, R, S, R, N},
  51. {R, L, S, L, N},
  52. {R, S, R, L, N},
  53. {L, S, L, R, N},
  54. {L, S, R, N, N},
  55. {R, S, L, N, N},
  56. {L, S, L, N, N},
  57. {R, S, R, N, N},
  58. {L, R, S, L, R},
  59. {R, L, S, R, L}};
  60. // RSPath::RSPath(double turning_radius) : turning_radius_(turning_radius) {}
  61. double RSPath::Mod2Pi(double x)
  62. {
  63. double v = fmod(x, 2 * M_PI);
  64. if (v < -M_PI)
  65. {
  66. v += 2.0 * M_PI;
  67. }
  68. else if (v > M_PI)
  69. {
  70. v -= 2.0 * M_PI;
  71. }
  72. return v;
  73. }
  74. void RSPath::Polar(double x, double y, double &r, double &theta)
  75. {
  76. r = std::sqrt(x * x + y * y);
  77. theta = std::atan2(y, x);
  78. }
  79. void RSPath::TauOmega(double u, double v, double xi, double eta, double phi, double &tau, double &omega)
  80. {
  81. double delta = Mod2Pi(u - v);
  82. double A = std::sin(u) - std::sin(delta);
  83. double B = std::cos(u) - std::cos(delta) - 1.0;
  84. double t1 = std::atan2(eta * A - xi * B, xi * A + eta * B);
  85. double t2 = 2.0 * (std::cos(delta) - std::cos(v) - std::cos(u)) + 3.0;
  86. tau = (t2 < 0.0) ? Mod2Pi(t1 + M_PI) : Mod2Pi(t1);
  87. omega = Mod2Pi(tau - u + v - phi);
  88. }
  89. bool RSPath::LpSpLp(double x, double y, double phi, double &t, double &u, double &v)
  90. {
  91. Polar(x - std::sin(phi), y - 1.0 + std::cos(phi), u, t);
  92. if (t >= 0.0)
  93. {
  94. v = Mod2Pi(phi - t);
  95. if (v >= 0.0)
  96. {
  97. return true;
  98. }
  99. }
  100. return false;
  101. }
  102. bool RSPath::LpSpRp(double x, double y, double phi, double &t, double &u, double &v)
  103. {
  104. double t1, u1;
  105. Polar(x + std::sin(phi), y - 1 - std::cos(phi), u1, t1);
  106. u1 = std::pow(u1, 2);
  107. if (u1 < 4.0)
  108. {
  109. return false;
  110. }
  111. double theta;
  112. u = std::sqrt(u1 - 4.0);
  113. theta = std::atan2(2.0, u);
  114. t = Mod2Pi(t1 + theta);
  115. v = Mod2Pi(t - phi);
  116. return true;
  117. }
  118. RSPath::RSPathData RSPath::GetRSPath(const double x_0, const double y_0, const double yaw_0,
  119. const double x_1, const double y_1, const double yaw_1)
  120. {
  121. // translation
  122. double dx = x_1 - x_0;
  123. double dy = y_1 - y_0;
  124. // rotate
  125. double c = std::cos(yaw_0); // 2d rotation matrix
  126. double s = std::sin(yaw_0);
  127. double x = c * dx + s * dy;
  128. double y = -s * dx + c * dy;
  129. double phi = yaw_1 - yaw_0;
  130. return GetRSPath(x / turning_radius_, y / turning_radius_, phi);
  131. }
  132. RSPath::RSPathData RSPath::GetRSPath(const double x, const double y, const double phi)
  133. {
  134. RSPathData path;
  135. CSC(x, y, phi, path);
  136. CCC(x, y, phi, path);
  137. CCCC(x, y, phi, path);
  138. CCSC(x, y, phi, path);
  139. CCSCC(x, y, phi, path);
  140. return path;
  141. }
  142. double RSPath::Distance(const double x_0, const double y_0, const double yaw_0,
  143. const double x_1, const double y_1, const double yaw_1)
  144. {
  145. return turning_radius_ * GetRSPath(x_0, y_0, yaw_0, x_1, y_1, yaw_1).Length();
  146. }
  147. void RSPath::CSC(double x, double y, double phi, RSPathData &path)
  148. {
  149. double t, u, v, length_min = path.Length(), L;
  150. if (LpSpLp(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  151. {
  152. path = RSPathData(RS_path_segment_type[14], t, u, v);
  153. length_min = L;
  154. }
  155. if (LpSpLp(-x, y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  156. {
  157. path = RSPathData(RS_path_segment_type[14], -t, -u, -v);
  158. length_min = L;
  159. }
  160. if (LpSpLp(x, -y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  161. {
  162. path = RSPathData(RS_path_segment_type[15], t, u, v);
  163. length_min = L;
  164. }
  165. if (LpSpLp(-x, -y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  166. {
  167. path = RSPathData(RS_path_segment_type[15], -t, -u, -v);
  168. length_min = L;
  169. }
  170. if (LpSpRp(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  171. {
  172. path = RSPathData(RS_path_segment_type[12], t, u, v);
  173. length_min = L;
  174. }
  175. if (LpSpRp(-x, y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  176. {
  177. path = RSPathData(RS_path_segment_type[12], -t, -u, -v);
  178. length_min = L;
  179. }
  180. if (LpSpRp(x, -y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  181. {
  182. path = RSPathData(RS_path_segment_type[13], t, u, v);
  183. length_min = L;
  184. }
  185. if (LpSpRp(-x, -y, phi, t, u, v) && length_min > std::fabs(t) + std::fabs(u) + std::fabs(v))
  186. {
  187. path = RSPathData(RS_path_segment_type[13], -t, -u, -v);
  188. }
  189. }
  190. bool RSPath::LpRmL(double x, double y, double phi, double &t, double &u, double &v)
  191. {
  192. double xi = x - std::sin(phi);
  193. double eta = y - 1.0 + std::cos(phi);
  194. double u1, theta;
  195. Polar(xi, eta, u1, theta);
  196. if (u1 > 4.0)
  197. {
  198. return false;
  199. }
  200. u = -2.0 * std::asin(0.25 * u1);
  201. t = Mod2Pi(theta + 0.5 * u + M_PI);
  202. v = Mod2Pi(phi - t + u);
  203. return true;
  204. }
  205. void RSPath::CCC(double x, double y, double phi, RSPathData &path)
  206. {
  207. double t, u, v, L;
  208. double length_min = path.Length();
  209. if (LpRmL(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  210. {
  211. path = RSPathData(RS_path_segment_type[0], t, u, v);
  212. length_min = L;
  213. }
  214. if (LpRmL(-x, y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  215. {
  216. path = RSPathData(RS_path_segment_type[0], -t, -u, -v);
  217. length_min = L;
  218. }
  219. if (LpRmL(x, -y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  220. {
  221. path = RSPathData(RS_path_segment_type[1], t, u, v);
  222. length_min = L;
  223. }
  224. if (LpRmL(-x, -y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  225. {
  226. path = RSPathData(RS_path_segment_type[1], -t, -u, -v);
  227. length_min = L;
  228. }
  229. double xb = x * std::cos(phi) + y * std::sin(phi);
  230. double yb = x * std::sin(phi) - y * std::cos(phi);
  231. if (LpRmL(xb, yb, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  232. {
  233. path = RSPathData(RS_path_segment_type[0], v, u, t);
  234. length_min = L;
  235. }
  236. if (LpRmL(-xb, yb, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  237. {
  238. path = RSPathData(RS_path_segment_type[0], -v, -u, -t);
  239. length_min = L;
  240. }
  241. if (LpRmL(xb, -yb, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  242. {
  243. path = RSPathData(RS_path_segment_type[1], v, u, t);
  244. length_min = L;
  245. }
  246. if (LpRmL(-xb, -yb, phi, t, u, v) && length_min > std::fabs(t) + std::fabs(u) + std::fabs(v))
  247. {
  248. path = RSPathData(RS_path_segment_type[1], -v, -u, -t);
  249. }
  250. }
  251. bool RSPath::LpRupLumRm(double x, double y, double phi, double &t, double &u, double &v)
  252. {
  253. double xi = x + std::sin(phi);
  254. double eta = y - 1.0 - std::cos(phi);
  255. double rho = 0.25 * (2.0 + std::sqrt(xi * xi + eta * eta));
  256. if (rho > 1.0)
  257. {
  258. return false;
  259. }
  260. u = std::acos(rho);
  261. TauOmega(u, -u, xi, eta, phi, t, v);
  262. return true;
  263. }
  264. bool RSPath::LpRumLumRp(double x, double y, double phi, double &t, double &u, double &v)
  265. {
  266. double xi = x + std::sin(phi);
  267. double eta = y - 1.0 - std::cos(phi);
  268. double rho = (20.0 - xi * xi - eta * eta) / 16.0;
  269. if (rho >= 0.0 && rho <= 1.0)
  270. {
  271. u = -std::acos(rho);
  272. if (u >= -M_PI_2)
  273. {
  274. TauOmega(u, u, xi, eta, phi, t, v);
  275. return true;
  276. }
  277. }
  278. return false;
  279. }
  280. void RSPath::CCCC(double x, double y, double phi, RSPathData &path)
  281. {
  282. double t, u, v, L;
  283. double length_min = path.Length();
  284. if (LpRupLumRm(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  285. {
  286. path = RSPathData(RS_path_segment_type[2], t, u, -u, v);
  287. length_min = L;
  288. }
  289. if (LpRupLumRm(-x, y, -phi, t, u, v) &&
  290. length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  291. {
  292. path = RSPathData(RS_path_segment_type[2], -t, -u, u, -v);
  293. length_min = L;
  294. }
  295. if (LpRupLumRm(x, -y, -phi, t, u, v) &&
  296. length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  297. {
  298. path = RSPathData(RS_path_segment_type[3], t, u, -u, v);
  299. length_min = L;
  300. }
  301. if (LpRupLumRm(-x, -y, phi, t, u, v) &&
  302. length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  303. {
  304. path = RSPathData(RS_path_segment_type[3], -t, -u, u, -v);
  305. length_min = L;
  306. }
  307. if (LpRumLumRp(x, y, phi, t, u, v) &&
  308. length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  309. {
  310. path = RSPathData(RS_path_segment_type[2], t, u, u, v);
  311. length_min = L;
  312. }
  313. if (LpRumLumRp(-x, y, -phi, t, u, v) &&
  314. length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  315. {
  316. path = RSPathData(RS_path_segment_type[2], -t, -u, -u, -v);
  317. length_min = L;
  318. }
  319. if (LpRumLumRp(x, -y, -phi, t, u, v) &&
  320. length_min > (L = std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v)))
  321. {
  322. path = RSPathData(RS_path_segment_type[3], t, u, u, v);
  323. length_min = L;
  324. }
  325. if (LpRumLumRp(-x, -y, phi, t, u, v) && length_min > std::fabs(t) + 2.0 * std::fabs(u) + std::fabs(v))
  326. {
  327. path = RSPathData(RS_path_segment_type[3], -t, -u, -u, -v);
  328. }
  329. }
  330. bool RSPath::LpRmSmLm(double x, double y, double phi, double &t, double &u, double &v)
  331. {
  332. double xi = x - std::sin(phi);
  333. double eta = y - 1.0 + std::cos(phi);
  334. double rho, theta;
  335. Polar(xi, eta, rho, theta);
  336. if (rho < 2.0)
  337. {
  338. return false;
  339. }
  340. double r = std::sqrt(rho * rho - 4.0);
  341. u = 2.0 - r;
  342. t = Mod2Pi(theta + std::atan2(r, -2.0));
  343. v = Mod2Pi(phi - M_PI_2 - t);
  344. return true;
  345. }
  346. bool RSPath::LpRmSmRm(double x, double y, double phi, double &t, double &u, double &v)
  347. {
  348. double xi = x + std::sin(phi);
  349. double eta = y - 1.0 - std::cos(phi);
  350. double rho, theta;
  351. Polar(-eta, xi, rho, theta);
  352. if (rho < 2.0)
  353. {
  354. return false;
  355. }
  356. t = theta;
  357. u = 2.0 - rho;
  358. v = Mod2Pi(t + M_PI_2 - phi);
  359. return true;
  360. }
  361. void RSPath::CCSC(double x, double y, double phi, RSPathData &path)
  362. {
  363. double t, u, v, L;
  364. double length_min = path.Length() - M_PI_2;
  365. if (LpRmSmLm(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  366. {
  367. path = RSPathData(RS_path_segment_type[4], t, -M_PI_2, u, v);
  368. length_min = L;
  369. }
  370. if (LpRmSmLm(-x, y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  371. {
  372. path = RSPathData(RS_path_segment_type[4], -t, M_PI_2, -u, -v);
  373. length_min = L;
  374. }
  375. if (LpRmSmLm(x, -y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  376. {
  377. path = RSPathData(RS_path_segment_type[5], t, -M_PI_2, u, v);
  378. length_min = L;
  379. }
  380. if (LpRmSmLm(-x, -y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  381. {
  382. path = RSPathData(RS_path_segment_type[5], -t, M_PI_2, -u, -v);
  383. length_min = L;
  384. }
  385. if (LpRmSmRm(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  386. {
  387. path = RSPathData(RS_path_segment_type[8], t, -M_PI_2, u, v);
  388. length_min = L;
  389. }
  390. if (LpRmSmRm(-x, y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  391. {
  392. path = RSPathData(RS_path_segment_type[8], -t, M_PI_2, -u, -v);
  393. length_min = L;
  394. }
  395. if (LpRmSmRm(x, -y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  396. {
  397. path = RSPathData(RS_path_segment_type[9], t, -M_PI_2, u, v);
  398. length_min = L;
  399. }
  400. if (LpRmSmRm(-x, -y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  401. {
  402. path = RSPathData(RS_path_segment_type[9], -t, M_PI_2, -u, -v);
  403. length_min = L;
  404. }
  405. double xb = x * std::cos(phi) + y * std::sin(phi);
  406. double yb = x * std::sin(phi) - y * std::cos(phi);
  407. if (LpRmSmLm(xb, yb, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  408. {
  409. path = RSPathData(RS_path_segment_type[6], v, u, -M_PI_2, t);
  410. length_min = L;
  411. }
  412. if (LpRmSmLm(-xb, yb, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  413. {
  414. path = RSPathData(RS_path_segment_type[6], -v, -u, M_PI_2, -t);
  415. length_min = L;
  416. }
  417. if (LpRmSmLm(xb, -yb, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  418. {
  419. path = RSPathData(RS_path_segment_type[7], v, u, -M_PI_2, t);
  420. length_min = L;
  421. }
  422. if (LpRmSmLm(-xb, -yb, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  423. {
  424. path = RSPathData(RS_path_segment_type[7], -v, -u, M_PI_2, -t);
  425. length_min = L;
  426. }
  427. if (LpRmSmRm(xb, yb, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  428. {
  429. path = RSPathData(RS_path_segment_type[10], v, u, -M_PI_2, t);
  430. length_min = L;
  431. }
  432. if (LpRmSmRm(-xb, yb, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  433. {
  434. path = RSPathData(RS_path_segment_type[10], -v, -u, M_PI_2, -t);
  435. length_min = L;
  436. }
  437. if (LpRmSmRm(xb, -yb, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  438. {
  439. path = RSPathData(RS_path_segment_type[11], v, u, -M_PI_2, t);
  440. length_min = L;
  441. }
  442. if (LpRmSmRm(-xb, -yb, phi, t, u, v) && length_min > std::fabs(t) + std::fabs(u) + std::fabs(v))
  443. {
  444. path = RSPathData(RS_path_segment_type[11], -v, -u, M_PI_2, -t);
  445. }
  446. }
  447. bool RSPath::LpRmSLmRp(double x, double y, double phi, double &t, double &u, double &v)
  448. {
  449. double xi = x + std::sin(phi);
  450. double eta = y - 1.0 - std::cos(phi);
  451. double rho, theta;
  452. Polar(xi, eta, rho, theta);
  453. if (rho >= 2.0)
  454. {
  455. u = 4.0 - std::sqrt(rho * rho - 4.0);
  456. if (u <= 0.0)
  457. {
  458. t = Mod2Pi(std::atan2((4.0 - u) * xi - 2.0 * eta, -2.0 * xi + (u - 4.0) * eta));
  459. v = Mod2Pi(t - phi);
  460. return true;
  461. }
  462. }
  463. return false;
  464. }
  465. void RSPath::CCSCC(double x, double y, double phi, RSPathData &path)
  466. {
  467. double t, u, v, L;
  468. double length_min = path.Length() - M_PI;
  469. if (LpRmSLmRp(x, y, phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  470. {
  471. path = RSPathData(RS_path_segment_type[16], t, -M_PI_2, u, -M_PI_2, v);
  472. length_min = L;
  473. }
  474. if (LpRmSLmRp(-x, y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  475. {
  476. path = RSPathData(RS_path_segment_type[16], -t, M_PI_2, -u, M_PI_2, -v);
  477. length_min = L;
  478. }
  479. if (LpRmSLmRp(x, -y, -phi, t, u, v) && length_min > (L = std::fabs(t) + std::fabs(u) + std::fabs(v)))
  480. {
  481. path = RSPathData(RS_path_segment_type[17], t, -M_PI_2, u, -M_PI_2, v);
  482. length_min = L;
  483. }
  484. if (LpRmSLmRp(-x, -y, phi, t, u, v) && length_min > std::fabs(t) + std::fabs(u) + std::fabs(v))
  485. {
  486. path = RSPathData(RS_path_segment_type[17], -t, M_PI_2, -u, M_PI_2, -v);
  487. }
  488. }
  489. TypeVectorVecd<3> RSPath::GetRSPath(const Eigen::Vector3d &start_state, const Eigen::Vector3d &goal_state,
  490. const double step_size, double &length)
  491. {
  492. RSPathData rs_path = GetRSPath(start_state.x(), start_state.y(), start_state.z(),
  493. goal_state.x(), goal_state.y(), goal_state.z());
  494. length = rs_path.Length() * turning_radius_;
  495. // Debug info
  496. // std::cout << "rs length: " << rs_path.Length() << " | "
  497. // << rs_path.length_[0] << " " << rs_path.length_[1] << " "
  498. // << rs_path.length_[2] << " " << rs_path.length_[3] << " "
  499. // << rs_path.length_[4] << std::endl;
  500. // std::cout << "type: "
  501. // << rs_path.type_[0] << " " << rs_path.type_[1] << " "
  502. // << rs_path.type_[2] << " " << rs_path.type_[3] << " "
  503. // << rs_path.type_[4] << std::endl;
  504. const double path_length = rs_path.Length() * turning_radius_;
  505. const auto interpolation_number = static_cast<unsigned int>(path_length / step_size);
  506. double phi;
  507. TypeVectorVecd<3> path_poses;
  508. for (unsigned int i = 0; i <= interpolation_number; ++i)
  509. {
  510. double v;
  511. double t = i * 1.0 / interpolation_number;
  512. double seg = t * rs_path.Length();
  513. Eigen::Vector3d temp_pose(0.0, 0.0, start_state.z());
  514. for (unsigned int j = 0; j < 5u && seg > 0; ++j)
  515. {
  516. if (rs_path.length_[j] < 0.0)
  517. {
  518. v = std::max(-seg, rs_path.length_[j]);
  519. seg += v;
  520. }
  521. else
  522. {
  523. v = std::min(seg, rs_path.length_[j]);
  524. seg -= v;
  525. }
  526. phi = temp_pose.z();
  527. switch (rs_path.type_[j])
  528. {
  529. case L:
  530. temp_pose.x() = std::sin(phi + v) - std::sin(phi) + temp_pose.x();
  531. temp_pose.y() = -std::cos(phi + v) + std::cos(phi) + temp_pose.y();
  532. temp_pose.z() = phi + v;
  533. break;
  534. case R:
  535. temp_pose.x() = -std::sin(phi - v) + std::sin(phi) + temp_pose.x();
  536. temp_pose.y() = std::cos(phi - v) - std::cos(phi) + temp_pose.y();
  537. temp_pose.z() = phi - v;
  538. break;
  539. case S:
  540. temp_pose.x() = v * std::cos(phi) + temp_pose.x();
  541. temp_pose.y() = v * std::sin(phi) + temp_pose.y();
  542. temp_pose.z() = phi;
  543. break;
  544. case N:
  545. break;
  546. }
  547. }
  548. Eigen::Vector3d pose;
  549. pose.block<2, 1>(0, 0) = temp_pose.block<2, 1>(0, 0) * turning_radius_ + start_state.block<2, 1>(0, 0);
  550. pose.z() = temp_pose.z();
  551. path_poses.emplace_back(pose);
  552. }
  553. return path_poses;
  554. }
  555. };
  556. #endif // HYBRID_A_STAR_RS_PATH_H