当前位置: 首页 > news >正文

轨迹优化 | 基于边界值问题(BVP)的无约束路径平滑(附ROS C++/Python仿真)

目录

  • 0 专栏介绍
  • 1 边界值问题建模
  • 2 算法仿真
    • 2.1 ROS C++仿真
    • 2.2 Python仿真

0 专栏介绍

🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战,包括:曲线生成、碰撞检测、安全走廊、优化建模(QP、SQP、NMPC、iLQR等)、轨迹优化(梯度法、曲线法等),每个算法都包含代码实现加深理解

🚀详情:运动规划实战进阶:轨迹优化篇


1 边界值问题建模

在轨迹优化 | 基于边界中间值问题(BIVP)的路径平滑求解器(附C++/Python仿真)中,我们介绍过边界中间值问题(Boundary Intermediate Value Problem, BIVP)的形式:

min⁡∫t0tkv(t)TWv(t)+ρ(tk−t0)s.t.z[ri−1](i−1)(ti)=z^i,1⩽i<k,ri⩽sz[s−1](s−1)(t0)=z^0,z[s−1](s−1)(tk)=z^k\begin{aligned} \min & \int_{t_0}^{t_k} \boldsymbol{v}(t)^T \boldsymbol{W} \boldsymbol{v}(t) + \rho(t_k - t_0) \\ \text{s.t.} & \ z_{[r_i-1]}^{(i-1)}(t_i) = \widehat{z}_i, \ 1 \leqslant i < k, \ r_i \leqslant s \\ & \ z_{[s-1]}^{(s-1)}(t_0) = \widehat{z}_0, \ z_{[s-1]}^{(s-1)}(t_k) = \widehat{z}_k \end{aligned} mins.t.t0tkv(t)TWv(t)+ρ(tkt0) z[ri1](i1)(ti)=zi, 1i<k, ris z[s1](s1)(t0)=z0, z[s1](s1)(tk)=zk

其中定义z[s−1](t)≜(zT,z˙T,⋯,z(s−1)T)Tz^{[s-1]}(t) \triangleq (z^T, \dot{z}^T, \cdots, z^{(s-1)^T})^Tz[s1](t)(zT,z˙T,,z(s1)T)Tv(t)≜z(s)(t)\boldsymbol{v}(t) \triangleq z^{(s)}(t)v(t)z(s)(t)

将BIVP的中间值约束移除将得到更特殊的边界值问题(Boundary Value Problem, BVP):

min⁡z(t),T∫t0Tv(t)TWv(t)+ρTs.t.z[s−1](0)=zˉ0,z[s−1](T)=zˉT\underset{\boldsymbol{z}\left( t \right) ,T}{\min}\int_{t_0}^T{\boldsymbol{v}\left( t \right) ^T\boldsymbol{Wv}\left( t \right)}+\rho T\,\,\\\mathrm{s}.\mathrm{t}. \boldsymbol{z}^{\left[ s-1 \right]}\left( 0 \right) =\boldsymbol{\bar{z}}_0, \boldsymbol{z}^{\left[ s-1 \right]}\left( T \right) =\boldsymbol{\bar{z}}_Tz(t),Tmint0Tv(t)TWv(t)+ρTs.t.z[s1](0)=zˉ0,z[s1](T)=zˉT

其仍然满足BIVP的最优性原理,即最优解z∗(t):[t0,tk]→Rnz^*(t): [t_0, t_k] \to \mathbb{R}^nz(t):[t0,tk]Rn的充要条件为:

  • z∗z^*z 的第iii段轨迹是 2s−12s - 12s1 次多项式;
  • 边界条件与中间点条件成立;
  • z∗z^*zt=tit = t_it=ti 处满足 rˉi−1\bar{r}_i - 1rˉi1 次连续可微,其中 rˉi=2s−ri\bar{r}_i = 2s - r_irˉi=2sri

所以最优解满足无中间值条件的约束方程

[F0Ek]P1=[D0Dk]\left[ \begin{array}{c} \boldsymbol{F}_0\\ \boldsymbol{E}_k\\\end{array} \right] \boldsymbol{P}_1=\left[ \begin{array}{c} \boldsymbol{D}_0\\ \boldsymbol{D}_k\\\end{array} \right] [F0Ek]P1=[D0Dk]

对于BVP问题来说,可以更进一步写出矩阵的结构。对于单个微分平坦维度有

d=AF(T)p\boldsymbol{d}=\boldsymbol{A}_F\left( T \right) \boldsymbol{p}d=AF(T)p

其中p=[p0p1⋯pn]T∈R2s\boldsymbol{p}=\left[ \begin{matrix} p_0& p_1& \cdots& p_n\\\end{matrix} \right] ^T\in \mathbb{R} ^{2s}p=[p0p1pn]TR2sd=[z0⋯z0(s−1)zT⋯zT(s−1)]∈R2s\boldsymbol{d}=\left[ \begin{matrix} z_0& \cdots& z_{0}^{\left( s-1 \right)}& z_T& \cdots& z_{T}^{\left( s-1 \right)}\\\end{matrix} \right] \in \mathbb{R} ^{2s}d=[z0z0(s1)zTzT(s1)]R2s

AF(t)=[EOF(t)G(t)]\boldsymbol{A}_F\left( t \right) =\left[ \begin{matrix} \boldsymbol{E}& \boldsymbol{O}\\ \boldsymbol{F}\left( t \right)& \boldsymbol{G}\left( t \right)\\\end{matrix} \right] AF(t)=[EF(t)OG(t)]

各分块矩阵形式为

Eij={(i−1)!ifi=j0ifi≠j,Fij(t)={(j−1)!(j−i)!tj−iifi⩽j0ifi>j,Gij(t)=(s+j−1)!(s+j−i)!ts+j−i\begin{aligned}\boldsymbol{E}_{ij}&=\begin{cases} \left( i-1 \right) ! \ \ \ \ \mathrm{if} i=j\\ 0 \ \ \ \ \ \ \mathrm{if} i\ne j\\\end{cases}, \\ \boldsymbol{F}_{ij}\left( t \right) &=\begin{cases} \frac{\left( j-1 \right) !}{\left( j-i \right) !}t^{j-i}\,\,\ \ \ \ \ \mathrm{if}\ i\leqslant j\\ 0 \ \ \ \ \ \mathrm{if}\ i>j\\\end{cases}, \\\boldsymbol{G}_{ij}\left( t \right) &=\frac{\left( s+j-1 \right) !}{\left( s+j-i \right) !}t^{s+j-i}\end{aligned}EijFij(t)Gij(t)={(i1)!    ifi=j0      ifi=j,={(ji)!(j1)!tji     if ij0     if i>j,=(s+ji)!(s+j1)!ts+ji

为了避免大规模矩阵求逆,在应用中也可以直接采用逆矩阵版本

p=AB(T)d\boldsymbol{p}=\boldsymbol{A}_B\left( T \right) \boldsymbol{d}p=AB(T)d

其中

AB(t)=[UOV(t)W(t)]\boldsymbol{A}_B\left( t \right) =\left[ \begin{matrix} \boldsymbol{U}& \boldsymbol{O}\\ \boldsymbol{V}\left( t \right)& \boldsymbol{W}\left( t \right)\\\end{matrix} \right] AB(t)=[UV(t)OW(t)]

各分块矩阵形式为

Uij={1(i−1)!ifi=j0ifi≠j,Vij(t)=∑k=0s−max⁡{i,j}(−1)k(si+k)(2s−j−k−1s−1)(j−1)!(−1)its+i−jWij(t)=∑k=0s−max⁡{i,j}(s−k−1i−1)(2s−j−k−1s−1)(j−1)!(−1)i+jts+i−j\begin{aligned}\boldsymbol{U}_{ij}&=\begin{cases} \frac{1}{\left( i-1 \right) !}\,\, \mathrm{if} i=j\\ 0 \mathrm{if} i\ne j\\\end{cases}, \\\boldsymbol{V}_{ij}\left( t \right) &=\frac{\sum_{k=0}^{s-\max \left\{ i,j \right\}}{\left( -1 \right) ^k\left( \begin{array}{c} s\\ i+k\\\end{array} \right) \left( \begin{array}{c} 2s-j-k-1\\ s-1\\\end{array} \right)}}{\left( j-1 \right) !\left( -1 \right) ^it^{s+i-j}}\\\\\boldsymbol{W}_{ij}\left( t \right) &=\frac{\sum_{k=0}^{s-\max \left\{ i,j \right\}}{\left( \begin{array}{c} s-k-1\\ i-1\\\end{array} \right) \left( \begin{array}{c} 2s-j-k-1\\ s-1\\\end{array} \right)}}{\left( j-1 \right) !\left( -1 \right) ^{i+j}t^{s+i-j}}\end{aligned}UijVij(t)Wij(t)={(i1)!1ifi=j0ifi=j,=(j1)!(1)its+ijk=0smax{i,j}(1)k(si+k)(2sjk1s1)=(j1)!(1)i+jts+ijk=0smax{i,j}(sk1i1)(2sjk1s1)

对平坦变量的各个维度应用上述公式即可求解BVP最优轨迹

2 算法仿真

2.1 ROS C++仿真

参考轨迹优化 | 基于边界中间值问题(BIVP)的路径平滑求解器(附C++/Python仿真)特化一个用于路径平滑的BIVP求解器

struct WaypointProblem
{static constexpr size_t problem_dim = 2;         // x, ystatic constexpr size_t boundary_order = 2;      // position, velocity, acclerationstatic constexpr size_t intermediate_order = 0;  // position
};template <>
struct rmp::common::math::ProblemTraits<WaypointProblem>
{static constexpr size_t problem_dim = WaypointProblem::problem_dim;static constexpr size_t boundary_order = WaypointProblem::boundary_order;static constexpr size_t intermediate_order = WaypointProblem::intermediate_order;
};using Solver = rmp::common::math::BIVPSolver<WaypointProblem>;

接着根据路径点约束设置求解器参数并求解即可

bool BIVPOptimizer::optimize(const Points3d& waypoints)
{solver_->reset();setBoundaryConstraints(waypoints.front(), waypoints.back());setIntermediateConstraints(waypoints);setTimeAllocation(waypoints);solution_ = std::move(solver_->solve());return true;
}

请添加图片描述

2.2 Python仿真

核心代码如下所示:

def optimize(self, waypoints: List[Point3d]) -> None:solver_params = SolverParameters(problem_dim=2,  # x, yboundary_constraint_order=2,  # position, velocity, acclerationintermediate_constraint_order=0,  # position)self.solver = BIVPSolver(solver_params)# boundarystart_boundary = [SecondOrderBVPState(x=waypoints[0].x(), dx=0.0, ddx=0.0),  # xSecondOrderBVPState(x=waypoints[0].y(), dx=0.0, ddx=0.0),  # y]goal_boundary = [SecondOrderBVPState(x=waypoints[-1].x(), dx=0.0, ddx=0.0),  # xSecondOrderBVPState(x=waypoints[-1].y(), dx=0.0, ddx=0.0),  # y]self.solver.setBoundaryConstraints(start_boundary, goal_boundary)# intermediateintermediate_constraints = []for i in range(1, len(waypoints) - 1):constraints = [ZeroOrderBVPState(x=waypoints[i].x()), ZeroOrderBVPState(x=waypoints[i].y())]  # positionintermediate_constraints.append(constraints)self.solver.setIntermediateConstraints(intermediate_constraints)# time allocationtime_allocation = [self.duration_per_segment] * (len(waypoints) - 1)self.solver.setTimeAllocation(time_allocation)# solveself.solution = self.solver.solve()

在这里插入图片描述

完整工程代码请联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇
http://www.dtcms.com/a/336824.html

相关文章:

  • 第二章:C语言数据类型和变量
  • PyTorch数据处理工具箱详解|深入理解torchvision与torch.utils.data
  • Gemini CLI 系统配置小结
  • ±2cm精度破壁者:有鹿机器人如何重写清洁行业规则?
  • java自动化更新
  • Git+Jenkins 基本使用
  • Win11安装WSL、Docker Desktop
  • MySQL集群、分布式
  • 如何生成结婚登记档案目录套打文件
  • 上下文切换及线程操作相关内容
  • Zephyr 中 BT_GATT_SERVICE_DEFINE 使用详解
  • 信创产业:从技术突围到生态重构的强国之路
  • 云计算- KubeVirt 实操指南:VM 创建 、存储挂载、快照、VMI全流程 | 容器到虚拟机(镜像转换/资源调度)
  • Python之Django框架开发Web应用,并部署到服务器
  • 【LeetCode题解】LeetCode 74. 搜索二维矩阵
  • Gartner发布2025年AI与网络安全成熟度曲线:用AI增强网络安全计划的27项技术与创新
  • 作业标准化:制造企业的效率基石与品质保障
  • 2025 年世界职业院校技能大赛汽车制造与维修赛道高职组资讯整合
  • 线程生命周期:pthread_detach 和 pthread_join 区别梳理
  • 个人笔记SpringMVC
  • 宁波市第八届网络安全大赛初赛(REVERSE-Writeup)
  • 2025 年世界职业院校技能大赛汽车制造与维修赛道高职组比赛通知
  • 航空装备先进加工工艺与制造技术论坛——2025成都航空装备展
  • Python 作用域 (scope) 与闭包 (closure)
  • 【网络运维】Playbook项目实战:基于 Ansible Playbook 一键部署 LNMP 架构服务器
  • Java中抽象类与接口的区别
  • 【LeetCode 热题 100】198. 打家劫舍——(解法二)自底向上
  • dc_shell (六)
  • OpenCV---特征检测算法(ORB,Oriented FAST and Rotated BRIEF)
  • AI 对话高效输入指令攻略(五):AI+PicDoc文生图表工具:解锁高效图表创作新范式