曲線生成 | 圖解Dubins曲線生成原理(附ROS C++/Python/Matlab仿真)

目錄

  • 0 專欄介紹
  • 1 什么是Dubins曲線?
  • 2 Dubins曲線原理
    • 2.1 坐標變換
    • 2.2 單步運動公式
    • 2.3 曲線模式
  • 3 Dubins曲線生成算法
  • 4 仿真實現
    • 4.1 ROS C++實現
    • 4.2 Python實現
    • 4.3 Matlab實現

0 專欄介紹

🔥附C++/Python/Matlab全套代碼🔥課程設計、畢業設計、創新競賽必備!詳細介紹全局規劃(圖搜索、采樣法、智能算法等);局部規劃(DWA、APF等);曲線優化(貝塞爾曲線、B樣條曲線等)。

🚀詳情:圖解自動駕駛中的運動規劃(Motion Planning),附幾十種規劃算法


1 什么是Dubins曲線?

Dubins曲線是指由美國數學家 Lester Dubins 在20世紀50年代提出的一種特殊類型的最短路徑曲線。這種曲線通常用于描述在給定轉彎半徑下的無人機、汽車或船只等載具的最短路徑,其特點是起始點和終點處的切線方向和曲率都是已知的。

在這里插入圖片描述

Dubins曲線包括直線段和最大轉彎半徑下的圓弧組成,通過合適的組合可以實現從一個姿態到另一個姿態的最短路徑規劃。這種曲線在航空、航海、自動駕駛等領域具有廣泛的應用,能夠有效地規劃航行路徑,減少能量消耗并提高效率。

2 Dubins曲線原理

2.1 坐標變換

如圖所示,在全局坐標系 x O y xOy xOy中,設機器人起始位姿、終止位姿、最小轉彎半徑分別為 ( x s , y s , α ) \left( x_s,y_s,\alpha \right) (xs?,ys?,α) ( x g , y g , β ) \left( x_g,y_g,\beta \right) (xg?,yg?,β) R R R,則以 p s = ( x s , y s ) \boldsymbol{p}_s=\left( x_s,y_s \right) ps?=(xs?,ys?)為新坐標系原點, p s \boldsymbol{p}_s ps?指向 p g = ( x g , y g ) \boldsymbol{p}_g=\left( x_g,y_g \right) pg?=(xg?,yg?)方向為 x ′ x' x軸,垂直方向為 y ′ y' y軸建立新坐標系 x ′ O ′ y ′ x'O'y' xOy

在這里插入圖片描述

根據比例關系 d / D = r / R {{d}/{D}}={{r}/{R}} d/D=r/R,其中 D = ∥ p s ? p g ∥ 2 D=\left\| \boldsymbol{p}_s-\boldsymbol{p}_g \right\| _2 D= ?ps??pg? ?2?。為了便于后續推導,不妨歸一化最小轉彎半徑,即令 r = 1 r=1 r=1。所以在坐標系 x ′ O ′ y ′ x'O'y' xOy中,通常取起點、終點間距為 d = D / R d={{D}/{R}} d=D/R,從而起始位姿、終止位姿、最小轉彎半徑分別轉換為

s t a r t = [ 0 0 α ? θ ] T , g o a l = [ d 0 β ? θ ] T , r = 1 \mathrm{start}=\left[ \begin{matrix} 0& 0& \alpha -\theta\\\end{matrix} \right] ^T, \mathrm{goal}=\left[ \begin{matrix} d& 0& \beta -\theta\\\end{matrix} \right] ^T, r=1 start=[0?0?α?θ?]T,goal=[d?0?β?θ?]T,r=1

其中 θ = a r c tan ? ( ( y g ? y s ) / ( x g ? x s ) ) \theta =\mathrm{arc}\tan \left( {{\left( y_g-y_s \right)}/{\left( x_g-x_s \right)}} \right) θ=arctan((yg??ys?)/(xg??xs?)),接下來的推導均基于轉換坐標系 x ′ O ′ y ′ x'O'y' xOy

2.2 單步運動公式

對于直行運動,設沿直線行進距離為 l l l,則

[ x ? y ? ? ? ] T = [ x + l cos ? ? y + l sin ? ? ? ] T \left[ \begin{matrix} x^*& y^*& \phi ^*\\\end{matrix} \right] ^T=\left[ \begin{matrix} x+l\cos \phi& y+l\sin \phi& \phi\\\end{matrix} \right] ^T [x??y?????]T=[x+lcos??y+lsin????]T

對于轉彎運動,假設轉向角為 ψ \psi ψ,則由弧長公式可得

l = ψ r = r = 1 ψ l=\psi r\xlongequal{r=1}\psi l=ψrr=1 ψ

因此設沿圓弧行進距離為 l l l,以左轉為例,由幾何關系易得

[ x ? y ? ? ? ] T = [ x + r sin ? ( ? + ψ ) ? r sin ? ( ? ) y + r cos ? ( ? + ψ ) + r cos ? ( ? ) ? + ψ ] T \left[ \begin{matrix} x^*& y^*& \phi ^*\\\end{matrix} \right] ^T=\left[ \begin{matrix} x+r\sin \left( \phi +\psi \right) -r\sin \left( \phi \right)& y+r\cos \left( \phi +\psi \right) +r\cos \left( \phi \right)& \phi +\psi\\\end{matrix} \right] ^T [x??y?????]T=[x+rsin(?+ψ)?rsin(?)?y+rcos(?+ψ)+rcos(?)??+ψ?]T

代入 r = 1 r=1 r=1 ψ = l \psi=l ψ=l可得

[ x ? y ? ? ? ] T = [ x + sin ? ( ? + l ) ? sin ? ( ? ) y + cos ? ( ? + l ) + cos ? ( ? ) ? + l ] T \left[ \begin{matrix} x^*& y^*& \phi ^*\\\end{matrix} \right] ^T=\left[ \begin{matrix} x+\sin \left( \phi +l \right) -\sin \left( \phi \right)& y+\cos \left( \phi +l \right) +\cos \left( \phi \right)& \phi +l\\\end{matrix} \right] ^T [x??y?????]T=[x+sin(?+l)?sin(?)?y+cos(?+l)+cos(?)??+l?]T

同理,對于右轉而言,有

[ x ? y ? ? ? ] T = [ x ? sin ? ( ? ? l ) + sin ? ( ? ) y + cos ? ( ? + l ) ? cos ? ( ? ) ? ? l ] T \left[ \begin{matrix} x^*& y^*& \phi ^*\\\end{matrix} \right] ^T=\left[ \begin{matrix} x-\sin \left( \phi -l \right) +\sin \left( \phi \right)& y+\cos \left( \phi +l \right) -\cos \left( \phi \right)& \phi -l\\\end{matrix} \right] ^T [x??y?????]T=[x?sin(??l)+sin(?)?y+cos(?+l)?cos(?)???l?]T

綜上所述,可得單步運動映射

{ L l + ( x , y , ? ) = [ x + sin ? ( ? + l ) ? sin ? ( ? ) y ? cos ? ( ? + l ) + cos ? ( ? ) ? + l ] T R l + ( x , y , ? ) = [ x ? sin ? ( ? ? l ) + sin ? ( ? ) y + cos ? ( ? ? l ) ? cos ? ( ? ) ? ? l ] T S l + ( x , y , ? ) = [ x + l cos ? ? y + l sin ? ? ? ] T \begin{cases} L_{l}^{+}\left( x,y,\phi \right) =\left[ \begin{matrix} x+\sin \left( \phi +l \right) -\sin \left( \phi \right)& y-\cos \left( \phi +l \right) +\cos \left( \phi \right)& \phi +l\\\end{matrix} \right] ^T\\ R_{l}^{+}\left( x,y,\phi \right) =\left[ \begin{matrix} x-\sin \left( \phi -l \right) +\sin \left( \phi \right)& y+\cos \left( \phi -l \right) -\cos \left( \phi \right)& \phi -l\\\end{matrix} \right] ^T\\ S_{l}^{+}\left( x,y,\phi \right) =\left[ \begin{matrix} x+l\cos \phi& y+l\sin \phi& \phi\\\end{matrix} \right] ^T\\\end{cases} ? ? ??Ll+?(x,y,?)=[x+sin(?+l)?sin(?)?y?cos(?+l)+cos(?)??+l?]TRl+?(x,y,?)=[x?sin(??l)+sin(?)?y+cos(??l)?cos(?)???l?]TSl+?(x,y,?)=[x+lcos??y+lsin????]T?

2.3 曲線模式

Dubins曲線假設物體只能向前,通過組合左轉、右轉、直行可得六種運動模式

{ L S L , R S R , R S L , L S R , R L R , L R L } \left\{ LSL, RSR, RSL, LSR, RLR, LRL \right\} {LSL,RSR,RSL,LSR,RLR,LRL}

可以總結這六種運動模式的解析解為

在這里插入圖片描述
在這里插入圖片描述

3 Dubins曲線生成算法

Dubins曲線路徑生成算法流程如表所示

在這里插入圖片描述

4 仿真實現

4.1 ROS C++實現

核心代碼如下所示

Points2d Dubins::generation(Pose2d start, Pose2d goal)
{Points2d path;double sx, sy, syaw;double gx, gy, gyaw;std::tie(sx, sy, syaw) = start;std::tie(gx, gy, gyaw) = goal;// coordinate transformationgx -= sx;gy -= sy;double theta = helper::mod2pi(atan2(gy, gx));double dist = hypot(gx, gy) * max_curv_;double alpha = helper::mod2pi(syaw - theta);double beta = helper::mod2pi(gyaw - theta);// select the best motionDubinsMode best_mode;double best_cost = DUBINS_MAX;DubinsLength length;DubinsLength best_length = { DUBINS_NONE, DUBINS_NONE, DUBINS_NONE };DubinsMode mode;for (const auto solver : dubins_solvers){(this->*solver)(alpha, beta, dist, length, mode);_update(length, mode, best_length, best_mode, best_cost);}if (best_cost == DUBINS_MAX)return path;// interpolation...// coordinate transformationEigen::AngleAxisd r_vec(theta, Eigen::Vector3d(0, 0, 1));Eigen::Matrix3d R = r_vec.toRotationMatrix();Eigen::MatrixXd P = Eigen::MatrixXd::Ones(3, path_x.size());for (size_t i = 0; i < path_x.size(); i++){P(0, i) = path_x[i];P(1, i) = path_y[i];}P = R * P;for (size_t i = 0; i < path_x.size(); i++)path.push_back({ P(0, i) + sx, P(1, i) + sy });return path;
}

4.2 Python實現

核心代碼如下所示

def generation(self, start_pose: tuple, goal_pose: tuple):sx, sy, syaw = start_posegx, gy, gyaw = goal_pose# coordinate transformationgx, gy = gx - sx, gy - sytheta = self.mod2pi(math.atan2(gy, gx))dist = math.hypot(gx, gy) * self.max_curvalpha = self.mod2pi(syaw - theta)beta = self.mod2pi(gyaw - theta)# select the best motionplanners = [self.LSL, self.RSR, self.LSR, self.RSL, self.RLR, self.LRL]best_t, best_p, best_q, best_mode, best_cost = None, None, None, None, float("inf")for planner in planners:t, p, q, mode = planner(alpha, beta, dist)if t is None:continuecost = (abs(t) + abs(p) + abs(q))if best_cost > cost:best_t, best_p, best_q, best_mode, best_cost = t, p, q, mode, cost# interpolation...# coordinate transformationrot = Rot.from_euler('z', theta).as_matrix()[0:2, 0:2]converted_xy = rot @ np.stack([x_list, y_list])x_list = converted_xy[0, :] + sxy_list = converted_xy[1, :] + syyaw_list = [self.pi2pi(i_yaw + theta) for i_yaw in yaw_list]return best_cost, best_mode, x_list, y_list, yaw_list

在這里插入圖片描述

4.3 Matlab實現

核心代碼如下所示

function [x_list, y_list, yaw_list] = generation(start_pose, goal_pose, param)sx = start_pose(1); sy = start_pose(2); syaw = start_pose(3);gx = goal_pose(1); gy = goal_pose(2); gyaw = goal_pose(3);% coordinate transformationgx = gx - sx; gy = gy - sy;theta = mod2pi(atan2(gy, gx));dist = hypot(gx, gy) * param.max_curv;alpha = mod2pi(syaw - theta);beta = mod2pi(gyaw - theta);% select the best motionplanners = ["LSL", "RSR", "LSR", "RSL", "RLR", "LRL"];best_cost = inf;best_segs = [];best_mode = [];for i=1:length(planners)planner = str2func(planners(i));[segs, mode] = planner(alpha, beta, dist);if isempty(segs)continueendcost = (abs(segs(1)) + abs(segs(2)) + abs(segs(3)));if best_cost > costbest_segs = segs;best_mode = mode;best_cost = cost;endend% interpolation...% coordinate transformationrot = [cos(theta), -sin(theta); sin(theta), cos(theta)];converted_xy = rot * [x_list; y_list];x_list = converted_xy(1, :) + sx;y_list = converted_xy(2, :) + sy;for j=1:length(yaw_list)yaw_list(j) = pi2pi(yaw_list(j) + theta);end
end

在這里插入圖片描述

完整工程代碼請聯系下方博主名片獲取


🔥 更多精彩專欄

  • 《ROS從入門到精通》
  • 《Pytorch深度學習實戰》
  • 《機器學習強基計劃》
  • 《運動規劃實戰精講》

👇源碼獲取 · 技術交流 · 抱團學習 · 咨詢分享 請聯系👇

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718464.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718464.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718464.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言:轉移表的實現

Hello,寶子們&#xff01;今天我們來模擬實現一下我們生活中的應用最頻繁的工具&#xff1a;計算器&#xff0c;實現計算器有三種方式。 廢話不多說&#xff0c;直接上代碼&#xff0c;計算器的一般實現&#xff1a; #include <stdio.h> int add(int a, int b)//加法函數…

Foxmail快捷鍵設置問題

當快捷鍵設置錯誤時不會生效&#xff0c;原來的快捷鍵仍有效&#xff0c;即使禁用快捷鍵功能&#xff0c;原先快捷鍵仍有效。正確的快捷鍵&#xff1a; 1. 不能是空&#xff08;NULL&#xff09; 2. 應該設置按鍵值只有一個的鍵盤按鈕。

力扣字符串篇

以下解題思路來自代碼隨想錄以及官方題解。 文章目錄 344.反轉字符串541.反轉字符串||151.反轉字符串中的單詞28.找出字符串中第一個匹配項的下標459.重復的字符串 344.反轉字符串 編寫一個函數&#xff0c;其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 s 的形式給…

怎樣查詢到pycharm終端中執行過的命令?

pycharm終端中記錄了曾經運行過的命令&#xff0c;怎樣才能查詢到全部曾經運行過的命令呢&#xff1f; 怎樣查詢到pycharm終端中執行過的命令&#xff1f;

【動態規劃專欄】

動態規劃基礎知識 概念 動態規劃&#xff08;Dynamic Programming&#xff0c;DP&#xff09;&#xff1a;用來解決最優化問題的算法思想。 動態規劃是分治思想的延伸&#xff0c;通俗一點來說就是大事化小&#xff0c;小事化無的藝術。 一般來說&#xff0c;…

【CSS】初學輕松學會使用Flex布局

目錄 什么是Flex布局如何開始使用Flex布局Flex容器的屬性Flex項目的屬性舉個例子 什么是Flex布局 Flex布局是一種基于盒子模型的布局方式&#xff0c;它讓我們可以輕松地控制容器內的元素在主軸和交叉軸上的排列方式。通過設置不同的Flex屬性&#xff0c;我們可以實現各種不同…

探索Hadoop的三種運行模式:單機模式、偽分布式模式和完全分布式模式

目錄 前言一、 單機模式二、 偽分布式模式三、 完全分布式模式&#xff08;重點&#xff09;3.1 準備工作3.2 配置集群3.2.1 配置core-site.xml 文件3.2.2 配置hdfs-site.xml 文件3.2.3 配置yarn-site.xml 文件3.2.4 配置mapred-site.xml 文件 3.3 啟動集群3.3.1 配置workers3.…

【百度】商業AIGC組_AIGC Java研發工程師(J70353)

北京市技術4人2024-02-28 工作職責&#xff1a; 負責商業AIGC平臺方向的工程架構設計及研發&#xff0c;致力于為廣告業務提供內容生成、內容知識化、內容多模態等中臺化服務&#xff0c;并將內容能力打通廣告檢索系統&#xff0c;于廣告的觸發、創意、模型和機制等聯動&#…

RK3568 android11 調試陀螺儀模塊 MPU6500

一&#xff0c;MPU6500功能介紹 1.簡介 MPU6500是一款由TDK生產的運動/慣性傳感器&#xff0c;屬于慣性測量設備&#xff08;IMU&#xff09;的一種。MPU6500集成了3軸加速度計、3軸陀螺儀和一個板載數字運動處理器&#xff08;DMP&#xff09;&#xff0c;能夠提供6軸的運動…

Matlab|基于Logistic函數負荷需求響應

目錄 1 基于Logistic函數的負荷轉移率模型 2 程序示例 3 效果圖 4 下載鏈接 負荷需求響應模型種類較多&#xff0c;有電價型和激勵型等類型&#xff0c;本次和大家分享一個基于Logistic函數的負荷轉移率模型&#xff0c;該模型屬于電價型&#xff0c;由于該方法使用的較少&a…

mysql 性能調優參數配置文件

########################################################################### ## my.cnf for MySQL 8.0.x # ## 本配置參考 https://imysql.com/my-cnf-wizard.html # ## 注意&#xff1a; …

python爬蟲之app爬取-charles的使用

專欄系列:http://t.csdnimg.cn/WfCSx 前言 前面介紹的都是爬取 Web 網頁的內容。隨著移動互聯網的發展,越來越多的企業并沒有提供 Web 網頁端的服務,而是直接開發了 App,更多更全的信息都是通過 App 來展示的。那么針對 App 我們可以爬取嗎?當然可以。 App 的爬取相比 …

FM AM WM DAB是啥

技術描述頻率范圍優點缺點調頻調制&#xff08;FM&#xff09;在FM廣播中&#xff0c;音頻信號的頻率被調制以匹配載波信號的變化&#xff0c;而載波信號的振幅保持不變。FM廣播通常具有較高的音質&#xff0c;并且在一定范圍內提供清晰的音頻。88 MHz 至 108 MHz- 高音質 - 清…

[linux] matplotlib plt畫training dynamics指標曲線時,標記每個點的值

plt畫折線圖時&#xff0c;plt.annotate標記折線圖的點的數值。 def plot_ret(*ret_dicts):plt.figure(figsize(10, 5))for ret_dict in ret_dicts:print(ret_dict["iters"])plt.plot([iter*4/1000 for iter in ret_dict["iters"]], ret_dict["ret&q…

億道信息發布兩款升級款全加固筆記本電腦

2022年5月19日&#xff0c;加固手持終端。加固平板電腦、加固筆記本電腦專業設計商和制造商&#xff0c;以及加固型移動計算機軟硬件整體定制解決方案提供商億道信息&#xff0c;宣布對其兩款廣受歡迎的加固筆記本電腦產品EM-X14U和EM-X15U進行重大升級。新發布的兩款升級款全加…

下載element-ui 資源,圖標 element-icons.woff,element-icons.ttf 無法解碼文件字體

css下載地址&#xff1a;https://unpkg.com/element-ui2.15.14/lib/theme-chalk/index.css js下載地址&#xff1a;https://unpkg.com/element-ui2.15.14/lib/index.js 圖標及文字文件下載地址&#xff1a; element-icons.woff:&#xff1a; ? https://unpkg.com/element-…

《TCP/IP詳解 卷一》第10章 UDP 和 IP 分片

目錄 10.1 引言 10.2 UDP 頭部 10.3 UDP校驗和 10.4 例子 10.5 UDP 和 IPv6 10.6 UDP-Lite 10.7 IP分片 10.7.1 例子&#xff1a;IPV4 UDP分片 10.7.2 重組超時 10.8 采用UDP的路徑MTU發現 10.9 IP分片和ARP/ND之間的交互 10.10 最大UDP數據報長度 10.11 UDP服務器…

【java、微服務、nacos】nacos學習筆記

Nacos服務分級存儲模型 ① 一級是服務&#xff0c;例如userservice ②二級是集群&#xff0c;例如杭州或上海 ③ 三級是實例&#xff0c;例如杭州機房的某臺部署了userservice的服務器 配置實例集群屬性 改變服務的yml文件 spring:cloud:nacos:discovery:cluster-name: H…

Docker將本地的鏡像上傳到私有倉庫

使用register鏡像創建私有倉庫 [rootopenEuler-node1 ~]# docker run --restartalways -d -p 5000:5000 -v /opt/data/regostry:/var/lib/registry registry:2[rootopenEuler-node1 ~]# docker images REPOSITORY TAG IMAGE…

Day 60 | 動態規劃 647. 回文子串 、 516.最長回文子序列 、動態規劃總結篇

647. 回文子串 題目 文章講解 視頻講解 class Solution {public int countSubstrings(String s) {char[] chars s.toCharArray();int len chars.length;boolean[][] dp new boolean[len][len];int result 0;for (int i len - 1; i > 0; i--) {for (int j i; j < l…