曲线生成 | 图解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= pspg 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=[00αθ]T,goal=[d0βθ]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((ygys)/(xgxs)),接下来的推导均基于转换坐标系 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 [xyϕ]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 [xyϕ]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 [xyϕ]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 [xyϕ]T=[xsin(ϕ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(ϕ)ycos(ϕ+l)+cos(ϕ)ϕ+l]TRl+(x,y,ϕ)=[xsin(ϕ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 transformation
  gx -= 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 motion
  DubinsMode 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 transformation
  Eigen::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_pose
	gx, gy, gyaw = goal_pose
	
	# coordinate transformation
	gx, gy = gx - sx, gy - sy
	theta = self.mod2pi(math.atan2(gy, gx))
	dist = math.hypot(gx, gy) * self.max_curv
	alpha = self.mod2pi(syaw - theta)
	beta = self.mod2pi(gyaw - theta)
	
	# select the best motion
	planners = [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:
			continue
		cost = (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 transformation
	rot = 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, :] + sx
	y_list = converted_xy[1, :] + sy
	yaw_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 transformation
    gx = 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 motion
    planners = ["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)
            continue
        end
        cost = (abs(segs(1)) + abs(segs(2)) + abs(segs(3)));
        if best_cost > cost
            best_segs = segs;
            best_mode = mode;
            best_cost = cost;
        end
    end
            
    % interpolation
    ...

    % coordinate transformation
    rot = [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深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/427080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows10 安装Neo4j流程

1、下载并安装ava运行环境 官网链接&#xff08;需要注册Oracle账号&#xff09;&#xff1a;https://www.oracle.com/java/technologies/downloads/ 根据自己Neo4j版本确认需要的JDK版本 百度网盘链接&#xff1a; 链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/…

怎么倒放视频?3个倒放方法分享给你

怎么倒放视频&#xff1f;倒放视频不仅有趣且充满创意&#xff0c;而且还能创造出一种令人惊叹的视觉效果&#xff0c;将观众带入一个全新的时空维度。通过将动作和事件倒放&#xff0c;我们可以观察到平时难以察觉的细节&#xff0c;理解事物运行的逆向逻辑。这种独特的编辑手…

Pycharm无法粘贴外部文本问题

Pycharm无法粘贴外部文本问题 百度找了好多是因为安装了vim&#xff0c;最后发现是因为pycharm粘贴框存在了很多内容导致 操作方法&#xff1a; 1、清理所有缓存的复制内容 ctrlshiftV 可以看到编译器所有缓存下来的复制文本 2、ctrlA然后delete 解决&#xff1a;此时再复…

最短路径(2.19)

目录 1.网络延迟时间 弗洛伊德算法 迪杰斯特拉算法 2. K 站中转内最便宜的航班 3.从第一个节点出发到最后一个节点的受限路径数 4.到达目的地的方案数 1.网络延迟时间 有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的…

数据结构与算法----复习Part 12 (字符串初步)

本系列是算法通关手册LeeCode的学习笔记 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 目录 一&#xff0c;字符串&#xff08;String&#xff09; 二&#xff0c;字符串的比较 三&#xff0c;字符串的存储…

AI算法的调优流程

AI算法的调优是提高模型性能和效率的关键步骤之一。以上流程是一个通用的AI算法调优流程&#xff0c;具体应用时可能需要根据问题类型、数据特征和业务需求进行调整和扩展。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 确定性能…

回归预测 | Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测&#xff08;完整…

2024第二届化学工程、材料与能源科学国际会议(ICCEMES2024)

2024第二届化学工程、材料与能源科学国际会议(ICCEMES2024) 一、【会议简介】 2024第二届化学工程、材料与能源科学国际会议(ICCEMES2024)将于2024年在美丽的三亚市举行。本次会议旨在汇聚全球化学工程、材料与能源科学领域的专家学者&#xff0c;共同探讨和交流相关领域的最…

第二篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas金融数据分析

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas 在金融数据分析中的常见用途和功能介绍二、金融数据清洗和准备示例代码三、金融数据索引和选择示例代码四、金融数据时间序列分析示例代码五、金融数据可视化示例代码六、金融数…

易语言源代码5000例

仅供学习研究交流使用 加群下载

MySQL8安装切换密码验证方式

一、MySQL8中新增了一种密码验证方式&#xff1a;caching_sha2_password&#xff0c;如果安装时选择了如下方式&#xff1a; 则数据库使用新的caching_sha2_password密码验证方式。 二、如果安装时选择了caching_sha2_password验证方式&#xff0c;而安装后想发回传统的mysql_…

医学大数据|统计基础|医学统计学(笔记):开学说明与目录

开始学习统计基础&#xff0c;参考教材&#xff1a;医学统计学第五版 点点关注一切来学习吧 责任编辑&#xff1a;医学大数据刘刘老师&#xff1a;头部医疗大数据公司医学科学部研究员 邮箱&#xff1a;897282268qq.com 久菜盒子工作室 我们是&#xff1a;985硕博/美国全奖…

【EI会议征稿通知】第四届能源工程、新能源材料与器件国际学术会议(NEMD 2024)

第四届能源工程、新能源材料与器件国际学术会议&#xff08;NEMD 2024&#xff09; 2024 4th International Academic Conference on Energy Engineering, new energy materials and devices 第四届能源工程、新能源材料与器件国际学术会议&#xff08;NEMD 2024&#xff09…

免费在线Axure终于找到了,赶紧试试!

Axure作为一种功能强大的原型设计工具&#xff0c;一直受到设计师的青睐。然而&#xff0c;其高昂的价格可能成为一个门槛&#xff0c;限制了一些设计师的选择。但别担心&#xff0c;现在有一个免费的Axure在线工具即时设计&#xff0c;功能更齐全&#xff0c;性价比更高&#…

用BIO实现tomcat

一、前言 本课程的难度较高&#xff0c;需要将Servlet原理和IO课程全部学完。 二、当前项目使用方式 (1).自定义servlet 自定义servlet需要实现WebServlet并且实现name和urlMapping 重启进行访问 http://localhost:8090/myServlet (2).自定义html 重启进行访问 http://loc…

幂等性设计

目录 前言 幂等性设计 幂等性设计处理流程 HTTP 幂等性 消息队列幂等性 基于kafka 前言 幂等性设计&#xff0c;就是说&#xff0c;一次和多次请求某一个资源应该具有同样的副作用。为什么我们要有幂等性操作&#xff1f;说白了&#xff0c;就两点&#xff1a;1、网络的…

Vue-03

Vue指令 v-bind 作用&#xff1a;动态设置html的标签属性&#xff08;src url title…&#xff09; 语法&#xff1a;v-bind:属性名"表达式" 举例代码如下&#xff1a; 实现效果如下&#xff1a; 案例&#xff1a;图片切换 实现代码如下&#xff1a; 实现的效果…

072:vue+cesium 实现下雪效果

第072个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中实现下雪效果,这里使用着色器来实现实例特效。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共120行)着色代码实现心得:专栏目标示例效果

基于springboot+vue的健身房管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

JavaScript基础1之变量的var、const、let和数据类型的原始类型、对象类型、内存空间、拷贝

JavaScript基础 变量var关键字var声明的作用域var 定义多个变量变量提升 let关键字暂时性死区let不是Windows的属性 const关键字 数据类型原始类型对象类型内存空间拷贝拷贝原始类型拷贝引用数据类型比较 变量 ECMAScript变量&#xff1a;松散类型的 >变量可以保存任何类型…