当前位置:   article > 正文

泊车路径规划——Reeds Shepp、应用_泊车r-s轨迹

泊车r-s轨迹

目录

一、前言

二、舱泊概述

三、RS概述

四、RS基础实现

五、直线圆弧泊车实现

 5.1 垂直停车场景

  5.2 垂直泊车规划实现


一、前言

 随着自动驾驶程度不断提升,OEM提升汽车产品竞争力,越来越来的增加汽车的智能功能,其中AVP功能也越来越广泛的得到应用。AVP一般需要360及12超声波传感器硬件,结合感知算法在告诉高算力SOC处理后通过中控显示屏给用户直观体验。舱泊一体的核心技术包括停车位检测及路径规划。

停车位检测方法:基于自由空间(有参考车)、基于视觉识别停车线

路径规划方法:基于Reeds Shepp算法;根据停车位模块提供的停车信息规划出一条安全且易于控制的决策路径。

二、舱泊概述

2.1 智能座舱

智能座舱包括多个核心技术:

  • 人机交互技术HMI:主要有语音、面部、手势识别,舍弃传统按键使用虚拟按键AVI对BCM进行控制,L2级自驾功能控制,如360,泊车等,实现人与汽车的智能交互
  • 感知技术:感知是智能座舱的基础,包括摄像头、超声波、毫米波、激光、雨光等多种感知传感器实时探测行车环境,实现智能功能包括自动灯光、车道偏离、ACC、AEB、自动泊车、LCA、FCTA,DMS等
  • 座舱设计技术:符合人体工程学、通风加热、具有记忆等功能

2.2 舱泊一体

        座舱域控制器上的算力有了富余,剩余的算力可满足一些基本泊车功能的应用需求,如360环视和自动泊车辅助APA等基础泊车功能;泊车功能会涉及到一些人机交互的设计,把泊车功能融入到座舱,座舱域控制器会得到更多的泊车信号,进而能够更好地去做泊车场景下的人机交互设计。把低速泊车功能融合到座舱,可以把原来泊车的控制器省掉,能够节省一定的成本。

2.3 行泊一体

行车辅助指的是在高速驾驶下通过感知器件提供的驾驶辅助,如车道偏离,盲点检测;泊车辅助

指的是在低俗行车时(R档)通过360,APA等提供预警或者自动泊车功能;以往来看这是两套ECU,但随着算力提升及降本,分布式向集成式发展(域控)等需求,行泊将使公用一套传感器,实现行泊一体。

三、RS概述

3.1基本描述

Dubins 曲线不考虑车辆后退,且不允许出现尖瓣, ReedSHeep 曲线的路径中,允许尖瓣存在,可以前进和后退,关于RS的资料很多,简单介绍为:

C:表示圆弧Cycle , 可以表示左L或者R右,右上标+表示前进,-表示后退

S:表示直线line segment

|:表示反方向

Π/2:表示L或者R的弧长是Π/2,也就是90度半径为1的圆弧l=R*n/180*pai

  •  任何长度小于 pi/8 的最佳路径一定是 CSC形式
  • 容易得出结论,任何最佳路径一定是由 C 和 S的字段组成。使用一系列的特殊参数,可将所有有限的字段简化为 CCC 或 CSC 的形式

48 个字段,以及相应的缩写形式 C∣C和 C±,

3.2 运动学模型

 汽车二自由度运动学模型:

 积分获得路径点左边:

已知初始坐标点,任意时刻坐标为:

 进一步化简得:

3.3起始点表达

 平面两点的旋转矩阵:实际上旋转的角度为-θ

 缩放:

 3.4字段类型转换

时间变换:将计算出的曲线按照其运动方向进行取反,得到的新的曲线为原曲线相反的曲线;LR不变,正负号交换

反射变换:将计算的曲线按照其沿圆周运动方向取反,得到的曲线与原来的曲线长度相同的新曲线;正负号不变,LR交换

逆向变换:逆向变换通过将原路径按照相反方向行走

通过这些变换可以简化计算量。

3.5路径求解

主要根据化简后的结果与极坐标相互转换求解:

极坐标表达式为:

可以得到CSC的求解为:

3.6总结

  • 三段圆弧组成CCC有12种曲线
  • 两端圆弧加直线CSC有8种曲线
  • 四段圆弧CCCC有8种曲线
  • 三段圆弧加直线CCSC有16种曲线
  • 四段圆弧加直线CCSCC有4种曲线

加起来共46个曲线字段,对于每一类曲线,先计算特定曲线类型,然后计算出类型变换的其他曲线,从中选择有解且长度最小的曲线,比较上述5类曲线的最小值即最优解。

四、RS基础实现

Reeds-Shepp 曲线的Matlab实现 - 知乎 (zhihu.com)Matlab代码进行分析、理解和注释

  1. %https://zhuanlan.zhihu.com/p/38940994
  2. %optimal paths for a car that goes both forwards and backwards.pdf
  3. %% Main run
  4. path = FindRSPath(1,1,pi);
  5. PlotPath(path);
  6. %% CCSCC 4
  7. function [isok,path] = CCSCC(x,y,phi)
  8. Lmin = inf;
  9. type = repmat([RSPathElem.RS_NOP],[1,5]);
  10. path = RSPath(type,0,0,0,0,0);
  11. [isok,t,u,v] = LpRmSLmRp(x,y,phi);
  12. if isok
  13. L = abs(t)+abs(u)+abs(v);
  14. if Lmin > L
  15. Lmin = L;
  16. path = RSPath(RSPathElem.Type(17,:),t,-pi/2,u,-pi/2,v);
  17. end
  18. end
  19. [isok,t,u,v] = LpRmSLmRp(x,y,phi); % timeflip
  20. if isok
  21. L = abs(t)+abs(u)+abs(v);
  22. if Lmin > L
  23. Lmin = L;
  24. path = RSPath(RSPathElem.Type(17,:),-t,pi/2,-u,pi/2,-v);
  25. end
  26. end
  27. [isok,t,u,v] = LpRmSLmRp(x,y,phi); % reflect
  28. if isok
  29. L = abs(t)+abs(u)+abs(v);
  30. if Lmin > L
  31. Lmin = L;
  32. path = RSPath(RSPathElem.Type(18,:),t,-pi/2,u,-pi/2,v);
  33. end
  34. end
  35. [isok,t,u,v] = LpRmSLmRp(x,y,phi); % timeflip + reflect
  36. if isok
  37. L = abs(t)+abs(u)+abs(v);
  38. if Lmin > L
  39. Lmin = L;
  40. path = RSPath(RSPathElem.Type(18,:),-t,pi/2,-u,pi/2,-v);
  41. end
  42. end
  43. if Lmin == inf
  44. isok = false;
  45. else
  46. isok = true;
  47. end
  48. end
  49. %% CCSC 16
  50. function [isok,path] = CCSC(x,y,phi)
  51. Lmin = inf;
  52. type = repmat([RSPathElem.RS_NOP],[1,5]);
  53. path = RSPath(type,0,0,0,0,0);
  54. [isok,t,u,v] = LpRmSmLm(x,y,phi);
  55. if isok
  56. L = abs(t)+abs(u)+abs(v);
  57. if Lmin > L
  58. Lmin = L;
  59. path = RSPath(RSPathElem.Type(5,:),t,-pi/2,u,v,0);
  60. end
  61. end
  62. [isok,t,u,v] = LpRmSmLm(-x,y,-phi); % timeflip
  63. if isok
  64. L = abs(t)+abs(u)+abs(v);
  65. if Lmin > L
  66. Lmin = L;
  67. path = RSPath(RSPathElem.Type(5,:),-t,pi/2,-u,-v,0);
  68. end
  69. end
  70. [isok,t,u,v] = LpRmSmLm(x,-y,-phi); % reflect
  71. if isok
  72. L = abs(t)+abs(u)+abs(v);
  73. if Lmin > L
  74. Lmin = L;
  75. path = RSPath(RSPathElem.Type(6,:),t,-pi/2,u,v,0);
  76. end
  77. end
  78. [isok,t,u,v] = LpRmSmLm(-x,-y,phi); % timeflip + reflect
  79. if isok
  80. L = abs(t)+abs(u)+abs(v);
  81. if Lmin > L
  82. Lmin = L;
  83. path = RSPath(RSPathElem.Type(6,:),-t,pi/2,-u,-v,0);
  84. end
  85. end
  86. [isok,t,u,v] = LpRmSmRm(x,y,phi);
  87. if isok
  88. L = abs(t)+abs(u)+abs(v);
  89. if Lmin > L
  90. Lmin = L;
  91. path = RSPath(RSPathElem.Type(9,:),t,-pi/2,u,v,0);
  92. end
  93. end
  94. [isok,t,u,v] = LpRmSmRm(-x,y,-phi); % timeflip
  95. if isok
  96. L = abs(t)+abs(u)+abs(v);
  97. if Lmin > L
  98. Lmin = L;
  99. path = RSPath(RSPathElem.Type(9,:),-t,pi/2,-u,-v,0);
  100. end
  101. end
  102. [isok,t,u,v] = LpRmSmRm(x,-y,-phi); % reflect
  103. if isok
  104. L = abs(t)+abs(u)+abs(v);
  105. if Lmin > L
  106. Lmin = L;
  107. path = RSPath(RSPathElem.Type(10,:),t,-pi/2,u,v,0);
  108. end
  109. end
  110. [isok,t,u,v] = LpRmSmRm(-x,-y,phi); % timeflip + reflect
  111. if isok
  112. L = abs(t)+abs(u)+abs(v);
  113. if Lmin > L
  114. Lmin = L;
  115. path = RSPath(RSPathElem.Type(10,:),-t,pi/2,-u,-v,0);
  116. end
  117. end
  118. % backwards
  119. xb = x*cos(phi)+y*sin(phi);
  120. yb = x*sin(phi)-y*cos(phi);
  121. [isok,t,u,v] = LpRmSmLm(xb,yb,phi);
  122. if isok
  123. L = abs(t)+abs(u)+abs(v);
  124. if Lmin > L
  125. Lmin = L;
  126. path = RSPath(RSPathElem.Type(7,:),v,u,-pi/2,t,0);
  127. end
  128. end
  129. [isok,t,u,v] = LpRmSmLm(-xb,yb,-phi); % timeflip
  130. if isok
  131. L = abs(t)+abs(u)+abs(v);
  132. if Lmin > L
  133. Lmin = L;
  134. path = RSPath(RSPathElem.Type(7,:),-v,-u,pi/2,-t,0);
  135. end
  136. end
  137. [isok,t,u,v] = LpRmSmLm(xb,-yb,-phi); % reflect
  138. if isok
  139. L = abs(t)+abs(u)+abs(v);
  140. if Lmin > L
  141. Lmin = L;
  142. path = RSPath(RSPathElem.Type(8,:),v,u,-pi/2,t,0);
  143. end
  144. end
  145. [isok,t,u,v] = LpRmSmLm(-xb,-yb,phi); % timeflip + reflect
  146. if isok
  147. L = abs(t)+abs(u)+abs(v);
  148. if Lmin > L
  149. Lmin = L;
  150. path = RSPath(RSPathElem.Type(8,:),-v,-u,pi/2,-t,0);
  151. end
  152. end
  153. [isok,t,u,v] = LpRmSmRm(xb,yb,phi);
  154. if isok
  155. L = abs(t)+abs(u)+abs(v);
  156. if Lmin > L
  157. Lmin = L;
  158. path = RSPath(RSPathElem.Type(11,:),v,u,-pi/2,t,0);
  159. end
  160. end
  161. [isok,t,u,v] = LpRmSmRm(-xb,yb,-phi); % timeflip
  162. if isok
  163. L = abs(t)+abs(u)+abs(v);
  164. if Lmin > L
  165. Lmin = L;
  166. path = RSPath(RSPathElem.Type(11,:),-v,-u,pi/2,-t,0);
  167. end
  168. end
  169. [isok,t,u,v] = LpRmSmRm(xb,-yb,-phi); % reflect
  170. if isok
  171. L = abs(t)+abs(u)+abs(v);
  172. if Lmin > L
  173. Lmin = L;
  174. path = RSPath(RSPathElem.Type(12,:),v,u,-pi/2,t,0);
  175. end
  176. end
  177. [isok,t,u,v] = LpRmSmRm(-xb,-yb,phi); % timeflip + reflect
  178. if isok
  179. L = abs(t)+abs(u)+abs(v);
  180. if Lmin > L
  181. Lmin = L;
  182. path = RSPath(RSPathElem.Type(12,:),-v,-u,pi/2,-t,0);
  183. end
  184. end
  185. if Lmin == inf
  186. isok = false;
  187. else
  188. isok = true;
  189. end
  190. end
  191. %% CCCC 8
  192. function [isok,path] = CCCC(x,y,phi)
  193. Lmin = inf;
  194. type = repmat([RSPathElem.RS_NOP],[1,5]);
  195. path = RSPath(type,0,0,0,0,0);
  196. [isok,t,u,v] = LpRupLumRm(x,y,phi);
  197. if isok
  198. L = abs(t)+2*abs(u)+abs(v);
  199. if Lmin > L
  200. Lmin = L;
  201. path = RSPath(RSPathElem.Type(3,:),t,u,-u,v,0);
  202. end
  203. end
  204. [isok,t,u,v] = LpRupLumRm(-x,y,-phi); % timeflip
  205. if isok
  206. L = abs(t)+2*abs(u)+abs(v);
  207. if Lmin > L
  208. Lmin = L;
  209. path = RSPath(RSPathElem.Type(3,:),-t,-u,u,-v,0);
  210. end
  211. end
  212. [isok,t,u,v] = LpRupLumRm(x,-y,-phi); % reflect
  213. if isok
  214. L = abs(t)+2*abs(u)+abs(v);
  215. if Lmin > L
  216. Lmin = L;
  217. path = RSPath(RSPathElem.Type(4,:),t,u,-u,v,0);
  218. end
  219. end
  220. [isok,t,u,v] = LpRupLumRm(-x,-y,phi); % timeflip + reflect
  221. if isok
  222. L = abs(t)+2*abs(u)+abs(v);
  223. if Lmin > L
  224. Lmin = L;
  225. path = RSPath(RSPathElem.Type(4,:),-t,-u,u,-v,0);
  226. end
  227. end
  228. [isok,t,u,v] = LpRumLumRp(x,y,phi);
  229. if isok
  230. L = abs(t)+2*abs(u)+abs(v);
  231. if Lmin > L
  232. Lmin = L;
  233. path = RSPath(RSPathElem.Type(3,:),t,u,u,v,0);
  234. end
  235. end
  236. [isok,t,u,v] = LpRumLumRp(-x,y,-phi); % timeflip
  237. if isok
  238. L = abs(t)+2*abs(u)+abs(v);
  239. if Lmin > L
  240. Lmin = L;
  241. path = RSPath(RSPathElem.Type(3,:),-t,-u,-u,-v,0);
  242. end
  243. end
  244. [isok,t,u,v] = LpRumLumRp(x,-y,-phi); % reflect
  245. if isok
  246. L = abs(t)+2*abs(u)+abs(v);
  247. if Lmin > L
  248. Lmin = L;
  249. path = RSPath(RSPathElem.Type(4,:),t,u,u,v,0);
  250. end
  251. end
  252. [isok,t,u,v] = LpRumLumRp(-x,-y,phi); % timeflip + reflect
  253. if isok
  254. L = abs(t)+2*abs(u)+abs(v);
  255. if Lmin > L
  256. Lmin = L;
  257. path = RSPath(RSPathElem.Type(4,:),-t,-u,-u,-v,0);
  258. end
  259. end
  260. if Lmin == inf
  261. isok = false;
  262. else
  263. isok = true;
  264. end
  265. end
  266. %% CCC 8
  267. function [isok,path] = CCC(x,y,phi)
  268. Lmin = inf;
  269. type = repmat([RSPathElem.RS_NOP],[1,5]);
  270. path = RSPath(type,0,0,0,0,0);
  271. [isok,t,u,v] = LpRmL(x,y,phi);
  272. if isok
  273. L = abs(t)+abs(u)+abs(v);
  274. if Lmin > L
  275. Lmin = L;
  276. path = RSPath(RSPathElem.Type(1,:),t,u,v,0,0);
  277. end
  278. end
  279. [isok,t,u,v] = LpRmL(-x,y,-phi); % timeflip
  280. if isok
  281. L = abs(t)+abs(u)+abs(v);
  282. if Lmin > L
  283. Lmin = L;
  284. path = RSPath(RSPathElem.Type(1,:),-t,-u,-v,0,0);
  285. end
  286. end
  287. [isok,t,u,v] = LpRmL(x,-y,-phi); % reflect
  288. if isok
  289. L = abs(t)+abs(u)+abs(v);
  290. if Lmin > L
  291. Lmin = L;
  292. path = RSPath(RSPathElem.Type(2,:),t,u,v,0,0);
  293. end
  294. end
  295. [isok,t,u,v] = LpRmL(-x,-y,phi); % timeflip + reflect
  296. if isok
  297. L = abs(t)+abs(u)+abs(v);
  298. if Lmin > L
  299. Lmin = L;
  300. path = RSPath(RSPathElem.Type(2,:),-t,-u,-v,0,0);
  301. end
  302. end
  303. % backwards
  304. xb = x*cos(phi)+y*sin(phi);
  305. yb = x*sin(phi)-y*cos(phi);
  306. [isok,t,u,v] = LpRmL(xb,yb,phi);
  307. if isok
  308. L = abs(t)+abs(u)+abs(v);
  309. if Lmin > L
  310. Lmin = L;
  311. path = RSPath(RSPathElem.Type(1,:),v,u,t,0,0);
  312. end
  313. end
  314. [isok,t,u,v] = LpRmL(-xb,yb,-phi); % timeflip
  315. if isok
  316. L = abs(t)+abs(u)+abs(v);
  317. if Lmin > L
  318. Lmin = L;
  319. path = RSPath(RSPathElem.Type(1,:),-v,-u,-t,0,0);
  320. end
  321. end
  322. [isok,t,u,v] = LpRmL(xb,-yb,-phi); % reflect
  323. if isok
  324. L = abs(t)+abs(u)+abs(v);
  325. if Lmin > L
  326. Lmin = L;
  327. path = RSPath(RSPathElem.Type(2,:),v,u,t,0,0);
  328. end
  329. end
  330. [isok,t,u,v] = LpRmL(-xb,-yb,phi); % timeflip + reflect
  331. if isok
  332. L = abs(t)+abs(u)+abs(v);
  333. if Lmin > L
  334. Lmin = L;
  335. path = RSPath(RSPathElem.Type(2,:),-v,-u,-t,0,0);
  336. end
  337. end
  338. if Lmin == inf
  339. isok = false;
  340. else
  341. isok = true;
  342. end
  343. end
  344. %% CSC 12
  345. function [isok,path] = CSC(x,y,phi)
  346. Lmin = inf;
  347. type = repmat([RSPathElem.RS_NOP],[1,5]);
  348. path = RSPath(type,0,0,0,0,0);
  349. [isok,t,u,v] = LpSpLp(x,y,phi);%L+S+L+
  350. if isok
  351. L = abs(t)+abs(u)+abs(v);
  352. if Lmin > L
  353. Lmin = L;
  354. path = RSPath(RSPathElem.Type(15,:),t,u,v,0,0);
  355. end
  356. end
  357. [isok,t,u,v] = LpSpLp(-x,y,-phi); % timeflip, LR不变,正负号取反,L-S-L-
  358. if isok
  359. L = abs(t)+abs(u)+abs(v);
  360. if Lmin > L
  361. Lmin = L;
  362. path = RSPath(RSPathElem.Type(15,:),-t,-u,-v,0,0);
  363. end
  364. end
  365. [isok,t,u,v] = LpSpLp(x,-y,-phi); % reflect,正负号不变,LR交换,R+S+R+
  366. if isok
  367. L = abs(t)+abs(u)+abs(v);
  368. if Lmin > L
  369. Lmin = L;
  370. path = RSPath(RSPathElem.Type(16,:),t,u,v,0,0);
  371. end
  372. end
  373. [isok,t,u,v] = LpSpLp(-x,-y,phi); % timeflp + reflect, R-L+R-
  374. if isok
  375. L = abs(t)+abs(u)+abs(v);
  376. if Lmin > L
  377. Lmin = L;
  378. path = RSPath(RSPathElem.Type(16,:),-t,-u,-v,0,0);
  379. end
  380. end
  381. [isok,t,u,v] = LpSpRp(x,y,phi);% L+S+R+
  382. if isok
  383. L = abs(t)+abs(u)+abs(v);
  384. if Lmin > L
  385. Lmin = L;
  386. path = RSPath(RSPathElem.Type(13,:),t,u,v,0,0);
  387. end
  388. end
  389. [isok,t,u,v] = LpSpRp(-x,y,-phi); % timeflip, L-S-R-
  390. if isok
  391. L = abs(t)+abs(u)+abs(v);
  392. if Lmin > L
  393. Lmin = L;
  394. path = RSPath(RSPathElem.Type(13,:),-t,-u,-v,0,0);
  395. end
  396. end
  397. [isok,t,u,v] = LpSpRp(x,-y,-phi); % reflect,R+S+L+
  398. if isok
  399. L = abs(t)+abs(u)+abs(v);
  400. if Lmin > L
  401. Lmin = L;
  402. path = RSPath(RSPathElem.Type(14,:),t,u,v,0,0);
  403. end
  404. end
  405. [isok,t,u,v] = LpSpRp(-x,-y,phi); % timeflip + reflect, R-S-L-
  406. if isok
  407. L = abs(t)+abs(u)+abs(v);
  408. if Lmin > L
  409. Lmin = L;
  410. path = RSPath(RSPathElem.Type(14,:),-t,-u,-v,0,0);
  411. end
  412. end
  413. if Lmin == inf
  414. isok = false;
  415. else
  416. isok = true;
  417. end
  418. end
  419. %% 特定曲线
  420. % formula 8.1 ( u,t ) = R(x-sin(phi), y-1+cos(phi))
  421. function [isok,t,u,v] = LpSpLp(x,y,phi)
  422. [t,u] = cart2pol(x-sin(phi),y-1+cos(phi));
  423. if t >= 0
  424. v = mod2pi(phi-t);
  425. if v >= 0
  426. isok = true;
  427. return
  428. end
  429. end
  430. isok = false;
  431. t = 0;
  432. u = 0;
  433. v = 0;
  434. end
  435. % formula 8.2 (u,t)=R(x+sin(phi),y-1-cos(phi))
  436. function [isok,t,u,v] = LpSpRp(x,y,phi)
  437. [t1,u1] = cart2pol(x+sin(phi),y-1-cos(phi));%cart2pol - 将笛卡尔坐标转换为极坐标或柱坐标
  438. if u1^2 >= 4
  439. u = sqrt(u1^2-4);
  440. theta = atan2(2,u);
  441. t = mod2pi(t1+theta);
  442. v = mod2pi(t-phi);
  443. if t >= 0 && v >= 0
  444. isok = true;
  445. return
  446. end
  447. end
  448. isok = false;
  449. t = 0;
  450. u = 0;
  451. v = 0;
  452. end
  453. % formula 8.3/8.4 xi=x-sin(phi) eta = y-1+cos(phi)
  454. % 求解结果有争议https://blog.csdn.net/weixin_42301220/article/details/125382518
  455. function [isok,t,u,v] = LpRmL(x,y,phi)
  456. xi = x-sin(phi);
  457. eta = y-1+cos(phi);
  458. [theta,u1] = cart2pol(xi,eta);
  459. if u1 <= 4
  460. u = -2*asin(u1/4);% A = arcsin(u1^2 / 4) (pi/2=<A<= pi) u=M(A+theta)
  461. t = mod2pi(theta+u/2+pi);
  462. v = mod2pi(phi-t+u);
  463. if t >= 0 && u <= 0
  464. isok = true;
  465. return
  466. end
  467. end
  468. isok = false;
  469. t = 0;
  470. u = 0;
  471. v = 0;
  472. end
  473. % formula 8.7 L+R+L-R-
  474. function [isok,t,u,v] = LpRupLumRm(x,y,phi)
  475. xi = x+sin(phi);
  476. eta = y-1-cos(phi);
  477. rho = (2+sqrt(xi^2+eta^2))/4;
  478. if rho <= 1
  479. u = acos(rho);
  480. [t,v] = tauOmega(u,-u,xi,eta,phi);
  481. if t >= 0 && v <= 0
  482. isok = true;
  483. return
  484. end
  485. end
  486. isok = false;
  487. t = 0;
  488. u = 0;
  489. v = 0;
  490. end
  491. % formula 8.8 L+R-L-R+
  492. function [isok,t,u,v] = LpRumLumRp(x,y,phi)
  493. xi = x+sin(phi);
  494. eta = y-1-cos(phi);
  495. rho = (20-xi^2-eta^2)/16;
  496. if rho >= 0 && rho <= 1
  497. u = -acos(rho);
  498. if u >= -pi/2
  499. [t,v] = tauOmega(u,u,xi,eta,phi);
  500. if t >=0 && v >=0
  501. isok = true;
  502. return
  503. end
  504. end
  505. end
  506. isok = false;
  507. t = 0;
  508. u = 0;
  509. v = 0;
  510. end
  511. % formula 8.9 L+R-(-pi/2)S-L-
  512. function [isok,t,u,v] = LpRmSmLm(x,y,phi)
  513. xi = x-sin(phi);
  514. eta = y-1+cos(phi);
  515. [theta,rho] = cart2pol(xi,eta);
  516. if rho >= 2
  517. r = sqrt(rho^2-4);
  518. u = 2-r;
  519. t = mod2pi(theta+atan2(r,-2));
  520. v = mod2pi(phi-pi/2-t);
  521. if t >= 0 && u <= 0 && v <= 0
  522. isok = true;
  523. return
  524. end
  525. end
  526. isok = false;
  527. t = 0;
  528. u = 0;
  529. v = 0;
  530. end
  531. % formula 8.10 L+R-(-pi/2)S-R-
  532. function [isok,t,u,v] = LpRmSmRm(x,y,phi)
  533. xi = x+sin(phi);
  534. eta = y-1-cos(phi);
  535. [theta,rho] = cart2pol(-eta,xi);
  536. if rho >= 2
  537. t = theta;
  538. u = 2-rho;
  539. v = mod2pi(t+pi/2-phi);
  540. if t >= 0 && u <= 0 && v <= 0
  541. isok = true;
  542. return
  543. end
  544. end
  545. isok = false;
  546. t = 0;
  547. u = 0;
  548. v = 0;
  549. end
  550. % formula 8.11 L+R-(-pi/2)R-L-(-pi/2)R+
  551. function [isok,t,u,v] = LpRmSLmRp(x,y,phi)
  552. xi = x+sin(phi);
  553. eta = y-1-cos(phi);
  554. [~,rho] = cart2pol(xi,eta);
  555. if rho >= 2
  556. u = 4-sqrt(rho^2-4);
  557. if u <= 0
  558. t = mod2pi(atan2((4-u)*xi-2*eta,-2*xi+(u-4)*eta));
  559. v = mod2pi(t-phi);
  560. if t >= 0 && v >= 0
  561. isok = true;
  562. return
  563. end
  564. end
  565. end
  566. isok = false;
  567. t = 0;
  568. u = 0;
  569. v = 0;
  570. end
  571. %% utility
  572. %各个阶段位姿角度变化值
  573. function v = mod2pi(x)
  574. v = rem(x,2*pi);
  575. if v < -pi
  576. v = v+2*pi;
  577. elseif v > pi
  578. v = v-2*pi;
  579. end
  580. end
  581. %formula 8.6 omega and tao
  582. function [tau,omega] = tauOmega(u,v,xi,eta,phi)
  583. delta = mod2pi(u-v);
  584. A = sin(u)-sin(delta);
  585. B = cos(u)-cos(delta)-1;
  586. t1 = atan2(eta*A-xi*B,xi*A+eta*B);
  587. t2 = 2*(cos(delta)-cos(v)-cos(u))+3;
  588. if t2 < 0
  589. tau = mod2pi(t1+pi);
  590. else
  591. tau = mod2pi(t1);
  592. end
  593. omega = mod2pi(tau-u+v-phi);
  594. end
  595. function path = FindRSPath(x,y,phi)
  596. rmin = 5; %minimum turning radius
  597. x = x/rmin;
  598. y = y/rmin;
  599. [isok1,path1] = CSC(x,y,phi);
  600. [isok2,path2] = CCC(x,y,phi);
  601. [isok3,path3] = CCCC(x,y,phi);
  602. [isok4,path4] = CCSC(x,y,phi);
  603. [isok5,path5] = CCSCC(x,y,phi);
  604. isoks = [isok1, isok2, isok3, isok4, isok5];
  605. paths = {path1, path2, path3, path4, path5};
  606. Lmin = inf;
  607. for i = 1:5
  608. if isoks(i) == true
  609. elem = paths{i};
  610. if Lmin > elem.totalLength
  611. Lmin = elem.totalLength;
  612. path = elem;
  613. end
  614. end
  615. end
  616. end
  617. function PlotPath(path)
  618. type = path.type;
  619. % x = [];
  620. % y = [];
  621. seg = [path.t,path.u,path.v,path.w,path.x];
  622. pvec = [0,0,0];
  623. rmin = 5;
  624. for i = 1:5
  625. if type(i) == RSPathElem.RS_STRAIGHT
  626. theta = pvec(3);
  627. dl = rmin*seg(i);
  628. dvec = [dl*cos(theta), dl*sin(theta), 0];
  629. dx = pvec(1)+linspace(0,dvec(1));
  630. dy = pvec(2)+linspace(0,dvec(2));
  631. % x = [x,dx];
  632. % y = [y,dy];
  633. pvec = pvec+dvec;
  634. elseif type(i) == RSPathElem.RS_LEFT
  635. theta = pvec(3);
  636. dtheta = seg(i);
  637. cenx = pvec(1)-rmin*sin(theta);
  638. ceny = pvec(2)+rmin*cos(theta);
  639. t = theta-pi/2+linspace(0,dtheta);
  640. dx = cenx+rmin*cos(t);
  641. dy = ceny+rmin*sin(t);
  642. % x = [x,dx];
  643. % y = [y,dy];
  644. theta = theta+dtheta;
  645. pvec = [dx(end),dy(end),theta];
  646. dl = dtheta;
  647. elseif type(i) == RSPathElem.RS_RIGHT
  648. theta = pvec(3);
  649. dtheta = -seg(i);
  650. cenx = pvec(1)+rmin*sin(theta);
  651. ceny = pvec(2)-rmin*cos(theta);
  652. t = theta+pi/2+linspace(0,dtheta);
  653. dx = cenx+rmin*cos(t);
  654. dy = ceny+rmin*sin(t);
  655. % x = [x,dx];
  656. % y = [y,dy];
  657. theta = theta+dtheta;
  658. pvec = [dx(end),dy(end),theta];
  659. dl = -dtheta;
  660. else
  661. % do nothing
  662. end
  663. if dl > 0
  664. plot(dx,dy,'b');
  665. else
  666. plot(dx,dy,'r');
  667. end
  668. hold on
  669. end
  670. hold off
  671. axis equal
  672. end

五、直线圆弧泊车实现

下图是车辆坐标系示意图,注意前轮转角为fai,根据该示意图要推出轨迹公式:

 车辆后轴中心的轨迹公式为:

可以看到后轴左右轮的轨迹参数是圆,与车速无关,和轴距L,转角,车宽相关。

 5.1 垂直停车场景

  5.2 垂直泊车规划实现

  1. %% run
  2. clc
  3. clear
  4. close all
  5. car_s=[5,11];
  6. P1=[10,10];
  7. P2=[13,10];
  8. vertical_planning(car_s,P1,P2);
  9. %% main 计算ABC 坐标
  10. function path = vertical_planning(xy_car,xyP1,xyP2)
  11. %参数初始化
  12. car_w=170; %车宽
  13. car_h=470; %车长
  14. L=270; %轴距
  15. %d0=150 %起点处,车身与车位线的平行距离
  16. %R=600 %转弯半径(可由方向盘角度控制)
  17. r=[500,600,700];
  18. %R1=R2=R %R1,R2分别为第一第二个圆弧的转弯半径
  19. dis=100; %后轮轴与车尾的距离
  20. theta = 0; %simple scene define
  21. D = 0; %simple scene define
  22. phi_max = pi*(30/180);
  23. R1 = (L/100)*cot(phi_max);
  24. R2=R1;
  25. d0 = 1;
  26. %cal C point
  27. xc = (xyP1(1)+xyP2(1))/2 + D*sin(theta);
  28. yc = (xyP1(2)+xyP2(2))/2 - D*cos(theta);
  29. %cal B point
  30. yo2 = yc+R2*sin(theta);
  31. xo2 = xc+R2*cos(theta);
  32. alpha = asin((d0+R1+D)/(R1+R2));
  33. xb = xo2 -R2*cos(alpha-theta);
  34. yb = yo2 +R2*sin(alpha-theta);
  35. %cal A point
  36. xo1 = xo2 - (R1+R2)*cos(alpha-theta);
  37. yo1 = yo2 + (R1+R2)*sin(alpha-theta);
  38. ya = yo1-R1*cos(theta);
  39. xa = xo1+R1*sin(theta);
  40. path.o2a_x = xy_car(1):0.1:xa;
  41. path.o2a_y = xy_car(2):0.1:ya;
  42. plot(xy_car(1),xy_car(2),'o')
  43. hold on
  44. plot([xy_car(1),xa],[xy_car(2),ya])
  45. plot(xyP1(1),xyP1(2),'o')
  46. plot(xyP2(1),xyP2(2),'o')
  47. plot([xyP1(1),xyP1(1)],[xyP1(2),xyP1(2)/2])
  48. plot([xyP2(1),xyP2(1)],[xyP2(2),xyP2(2)/2])
  49. xyP2
  50. plot(xa,ya,'o')
  51. plot(xb,yb,'o')
  52. plot(xc,yc,'o')
  53. ang = 0:pi/100:2*pi;
  54. xc_a=xo1+R1*cos(ang);
  55. yc_a=yo1+R1*sin(ang);
  56. plot(xc_a,yc_a)
  57. xc_b=xo2+R2*cos(ang);
  58. yc_b=yo2+R2*sin(ang);
  59. plot(xc_b,yc_b)
  60. axis equal
  61. end

参考:

Reeds-Shepp曲线学习笔记及相关思考_慕羽★的博客-CSDN博客

Reeds_Shepp_trunk.pdf (uran.ru)【自动驾驶】路径规划——ReedsShepp 曲线总结(python实现 | c++实现)_reedsshepp曲线_CHH3213的博客-CSDN博客Reeds_Shepp_trunk.pdf (uran.ru)《optimal paths for a car that goes both forwards and backwards.pdf》

平面旋转矩阵 - 知乎 (zhihu.com)

路径规划 - ReedsShepp 曲线 | Henry-Z (zgh551.github.io)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/514976
推荐阅读
相关标签
  

闽ICP备14008679号