Minimum Snap轨迹规划详解(2)corridor与时间分配

本文深入探讨了Snap轨迹规划中的corridor概念,如何构建和约束corridor以确保轨迹在允许的通道内。同时,文章讨论了时间分配的重要性,包括初始分配、可行性检查和corridor对时间分配的影响。通过对中间点的处理和归一化时间参数的使用,实现了更平滑的轨迹规划。
摘要由CSDN通过智能技术生成

在上一篇文章中,我们得到的轨迹并不是很好,与路径差别有点大,我们期望规划出的轨迹跟路径大致重合,而且不希望有打结的现象,而且希望轨迹中的速度和加速度不超过最大限幅值。为了解决这些问题有两种思路:

  • 思路一:把这些”期望“加入到优化问题中。
  • 思路二:调整时间分配,来避免这些问题。

1.corridor

1.1 corridor是什么?

为了限制轨迹的形状,引入了corridor的概念,corridor可以理解为可行通道,如下图,规划出的轨迹必须在corridor内。直观的思路是:如果能把corridor当作约束加入到QP问题中,那么解得的轨迹自然就在corridor内了。
corridor示意图

1.2 corridor约束怎么加?

很容易想到,把之前的等式约束 Ap=d 改成不等式约束 Apd1 Apd2 然而,不管是等式约束还是不等式约束,都是针对一个特定的时刻,而实际希望的是对所有时刻 t[0,T] ,都需要在corridor中。
一个简单粗暴的思路:在路径上多采样一些中间点,每个中间点都加corridor约束。尽管这种方法理论上只能保证采样点在corridor中,但实际过程中,如果corridor大小和采样步长设置得合理,而且不Fix waypoints,能work的比较好。这里不fix 中间点的位置,是为了去掉中间点的强约束,尽量避免轨迹打结,实际中,我们也是不一样要求轨迹完全经过中间点,只要在那附近(corridor)内就行。

1.3 构造corridor不等式约束

为了方便构造,对于每一个采样点 pt ,我们施加一个矩形的corridor,即

xminptxxmax, yminptyymax

这里用矩形corridor是因为斜线corridor(平行四边形)不好构造,而且我们只需要大致在corridor里面就好,没有必要非弄一个严格的斜线corridor。对于每个采样点,设矩形corridor的边长为 2r ,增加两个位置不等式约束:
[1,ti,t2i,...,tni]pp(ti)+r[1,ti,t2i,...,t
### Minimum Snap 的基本概念 Minimum Snap 是一种用于轨迹规划的技术,旨在最小化加速度变化率(即“抖动”),从而实现平滑的运动路径。这种方法特别适用于无人机和其他自动化设备,在这些应用中,平稳而高效的飞行路径至关重要。 #### 关键特点 - **平滑性**:通过优化高阶导数来减少不必要的振动和能量消耗。 - **效率**:相比传统的线性或抛物线插值方法,能够提供更加节能且快速响应的路径规划方案[^1]。 ### Minimum Snap 入门教程 #### 安装依赖库 要开始使用 Minimum Snap 进行编程实践,首先需要安装一些必要的 Python 库: ```bash pip install numpy scipy matplotlib ``` #### 创建简单的二维空间中的 Minimum Snap 轨迹 下面是一个创建简单二维平面内从起点到终点之间遵循 minimum snap 准则的轨迹的例子: ```python import numpy as np from scipy.optimize import minimize def min_snap_cost_function(params, waypoints): """定义目标函数""" t = params[:len(waypoints)-1] p = params[len(waypoints)-1:] cost = 0 for i in range(len(t)): dt = (t[i+1]-t[i]) if i < len(t)-1 else 1e-6 # 计算位置差分 dp = waypoints[i+1] - waypoints[i] # 构建多项式系数矩阵 A 和 B A = [[dt**j / factorial(j) for j in range(8)]] b = [dp[k]/factorial(k+1)*(-1)**k for k in range(2)] try: invA = np.linalg.inv(A) z = np.dot(invA,b) jerk_squared_sum = sum([z[j]**2 * dt**(7-j)/(factorial(7-j)) for j in range(8)]) cost += jerk_squared_sum except Exception as e: pass return cost def generate_trajectory(waypoints): initial_guess = list(np.ones((len(waypoints),))) + list(sum([[wp]*8 for wp in waypoints], [])) res = minimize(min_snap_cost_function, initial_guess, args=(waypoints,), method='Powell') optimized_params = res.x times = optimized_params[:len(waypoints)-1] positions = [] velocities = [] prev_time = 0. for idx, time_step in enumerate(times[:-1]): current_position = waypoints[idx] next_position = waypoints[idx+1] duration = time_step-prev_time velocity_change = (next_position-current_position)/duration positions.append(current_position) velocities.append(velocity_change) prev_time = time_step return {'positions': positions, 'velocities': velocities} if __name__ == "__main__": waypoints = [(0., 0.), (5., 3.), (-2., 9.)] # Example Way Points trajectory_data = generate_trajectory(waypoints) print("Positions:", trajectory_data['positions']) print("Velocities:", trajectory_data['velocities']) ``` 这段代码展示了如何基于给定的关键点计算满足 minimum snap 条件下的最优时间间隔以及对应的位置和速度序列。注意这里简化了很多细节以便于理解核心原理;实际工程实践中还需要考虑更多因素如物理约束、安全边界等[^2]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值