Python 机器人运动学与轨迹规划代码解释¶
1. 概述¶
该 Python 脚本旨在实现一个特定类型并联机器人(基于提供的运动学公式推测)的正向和逆向运动学计算,并根据给定的 MATLAB 代码逻辑,生成一个圆形轨迹,并规划沿该轨迹的 S 曲线速度轮廓。最终,它会计算轨迹上每个点的关节变量,并提供可视化结果,包括运动曲线图和机器人姿态动画。
该脚本的主要目的是将一个 MATLAB 实现的轨迹规划任务转换为 Python 代码。
2. 导入库¶
脚本首先导入了必要的 Python 库:
NumPy (
np
): 用于高效的数值计算,特别是数组和矩阵操作。SymPy (
sp
): 用于符号数学计算,主要在正向运动学中定义和求解方程组。math: 提供基本的数学函数。
Matplotlib (
plt
): 用于数据可视化,包括绘制 2D 曲线图和 3D 机器人模型及轨迹。time: 用于在动画中添加暂停。
import numpy as np
import sympy as sp
import math
import matplotlib.pyplot as plt
import time
sp.init_printing(use_unicode=True) # 启用 SymPy 的美观打印
3. 机器人参数 (get_robot_params
)¶
这个函数定义并返回一个包含机器人几何尺寸参数的字典。这些参数是运动学计算的基础。
\(a_{11}, a_{22}, a_{33}\): 移动平台上连接点到平台中心的距离。
\(b_{11}, b_{22}, b_{33}\): 固定平台上连接点到平台中心的距离。
\(e\): 中心柱的固定(不可伸缩)部分的长度。
def get_robot_params():
return {
'a11': 135.0, 'a22': 135.0, 'a33': 135.0,
'b11': 570.0, 'b22': 320.0, 'b33': 320.0,
'e': 345.0
}
4. 位置逆解 (inverse_kinematics
)¶
逆运动学(IK)解决的问题是:给定末端执行器(移动平台中心)期望的笛卡尔坐标 \(x_p, y_p, z_p\),计算出机器人需要达到的关节变量。
输入:
\(x_p, y_p, z_p\): 目标位置 (float)。
params
: 包含机器人尺寸的字典。
输出: 一个包含计算结果的字典:
\(q_1, q_2, q_3\): 计算得到的驱动杆“长度”(float)。注意: 根据代码中的公式,这可能不是物理连杆 \(B_i\) 到 \(A'_i\) 的直线距离,而是基于特定投影或定义的长度。
\(q_4\): 中心柱的可变长度 (float),即 \(||r_p|| - e\)。
\(\theta_1, \theta_2\): 描述移动平台姿态的角度 (rad)。
\(r_p\): 末端位置向量 \(\begin{bmatrix} x_p \\ y_p \\ z_p \end{bmatrix}\) (NumPy 数组)。
\(R_4\): 移动平台的旋转矩阵 (3x3 NumPy 数组),描述了平台坐标系相对于固定坐标系的姿态。
\(w_4\): 中心柱方向的单位向量 (3x1 NumPy 数组),即 \(r_p / ||r_p||\)。
error
: 错误信息字符串,如果无法求解则非空。
计算步骤:
计算 \(r_p\) 及其模长 \(||r_p||\)。
检查目标点是否在固定中心柱长度 \(e\) 范围内,如果是则不可达。
计算中心柱可变长度 \(q_4 = ||r_p|| - e\)。
根据 \(x_p\) 和 \(||r_p||\) 计算 \(\theta_2 = \arcsin(x_p / ||r_p||)\)。
根据 \(y_p, z_p, ||r_p||, \theta_2\) 计算 \(\theta_1 = \operatorname{arctan2}(-y_p / (||r_p||\cos\theta_2), z_p / (||r_p||\cos\theta_2))\),并处理 \(\cos\theta_2 \approx 0\) 的情况。
使用 \(\theta_1, \theta_2\) 构建旋转矩阵 \(R_4\)。
计算固定平台和移动平台的连接点向量 (\(b_i\) 和 \(a_i = R_4 a_{i0}\))。
计算中心柱方向向量 \(w_4\)。
根据代码中给出的特定公式计算 \(q_1, q_2, q_3\): $\( q_i = || r_p - b_i + a_i - e w_4 || \)\( 这对应于从 \)B_i\( 指向 \)A’_i\((移动平台连接点在固定坐标系中的绝对位置)的向量,再减去固定中心柱向量 \)e w_4$ 后的模长。
5. 位置正解 (Forward Kinematics - FK)¶
正运动学解决的问题是:给定驱动关节的输入值 \(q_1, q_2, q_3\)(根据 IK 中的定义),计算末端执行器的位置 \(x_p, y_p, z_p\) 和姿态 \(\theta_1, \theta_2\)。这通常比逆解更复杂,因为它涉及到求解非线性方程组。
5.1 符号设置与数值函数生成 (define_symbolic_fk
)¶
此函数使用 SymPy 库来建立正解所需的数学模型。
输入:
params
: 机器人参数。\(q_{1,in}, q_{2,in}, q_{3,in}\): 输入的驱动杆计算长度。
输出:
Func_sym
: 包含三个符号约束方程 \(F, G, H\) 的 SymPy 矩阵。这些方程基于机器人的闭环几何约束,将已知的 \(q_{1,in}, q_{2,in}, q_{3,in}\) 与未知的 \(q_4, \theta_1, \theta_2\) 联系起来。其形式为 \(|| L_i ||^2 - q_{i,in}^2 = 0\),其中 \(L_i = q_4 w_4 + a_i - b_i\)。代码中直接使用了展开后的简化形式(经验证与 \(||L_i||^2\) 定义一致)。J_sym
: \(F, G, H\) 相对于未知变量 \(X = [q_4, \theta_1, \theta_2]^T\) 的符号雅可比矩阵 \(J = \frac{\partial(F,G,H)}{\partial X}\)。num_func
,num_jac
: 通过sp.lambdify
将符号方程和雅可比矩阵转换为快速求值的 NumPy 函数。X_sym
: 包含符号变量 \([q_4, \theta_1, \theta_2]^T\) 的 SymPy 矩阵。
5.2 牛顿迭代求解器 (forward_kinematics
)¶
此函数使用牛顿-拉弗森(Newton-Raphson)迭代法来数值求解由 define_symbolic_fk
建立的非线性方程组 \(Func(X) = 0\)。
输入:
\(q_{1,in}, q_{2,in}, q_{3,in}\): 输入的驱动杆计算长度。
params
: 机器人参数。initial_guess
: 对未知变量 \([q_4, \theta_1, \theta_2]\) 的初始猜测值。max_iter
,tolerance
: 最大迭代次数和收敛容差。
输出: 一个包含结果的字典:
\(x_{p,fk}, y_{p,fk}, z_{p,fk}\): 计算得到的末端位置。
\(q_{4,k}, \theta_{1,k}, \theta_{2,k}\): 计算得到的最终 \(q_4, \theta_1, \theta_2\) 值。
iterations
: 实际迭代次数。final_error_norm
: 最终的方程误差范数 \(||Func(X_k)||\)。converged
: 是否收敛 (bool)。error
: 错误信息。
计算步骤:
获取数值计算函数
num_func
和num_jac
。从初始猜测 \(X_0\) 开始迭代。
在第 \(k\) 次迭代: a. 计算当前 \(X_k\) 下的函数值 \(F_k = Func(X_k)\)。 b. 检查误差 \(||F_k||\) 是否小于容差,如果是则停止迭代。 c. 计算当前 \(X_k\) 下的雅可比矩阵 \(J_k = J(X_k)\)。 d. 求解线性方程组 \(J_k \Delta X = -F_k\) 得到步长 \(\Delta X\)。如果 \(J_k\) 奇异则报错。 e. 更新解:\(X_{k+1} = X_k + \Delta X\)。
如果达到最大迭代次数仍未收敛,则报告失败。
如果收敛,使用最终得到的 \(q_4, \theta_1, \theta_2\) 计算末端位置:\(r_p = (e + q_4) w_4\),其中 \(w_4\) 由 \(\theta_1, \theta_2\) 确定。
6. 可视化函数 (plot_robot
)¶
该函数使用 Matplotlib 在 3D 坐标系中绘制机器人的当前姿态。
输入:
ax
: Matplotlib 的 3D 坐标轴对象。\(r_p\): 当前末端位置向量。
\(R_4\): 当前移动平台的旋转矩阵。
params
: 机器人参数。title
: 图表标题。
绘制内容:
计算所有关键点(原点 O, 固定平台连接点 \(B_i\), 移动平台连接点 \(A'_i\), 末端点 P, 中心柱顶端 E)在固定坐标系中的坐标。
绘制固定平台(灰色虚线三角形 \(B_1B_2B_3\))。
绘制移动平台(蓝色实线三角形 \(A'_1A'_2A'_3\))。
绘制物理驱动杆(红色实线 \(B_iA'_i\))。
绘制中心柱(绿色线段 OE 和 EP,分别代表固定部分和可变部分)。
标记原点 O 和末端点 P。
设置坐标轴标签、标题、图例和大致范围,并尝试设置等比例轴。
7. S 曲线速度轮廓生成 (s_velocity_motion
)¶
此函数用于生成沿路径的运动轮廓,即规划位移 \(s(t)\)、速度 \(v(t)\) 和加速度 \(a(t)\)。
重要: 这个函数的实现严格复制了提供的 MATLAB 代码 Svelocity_motion
的逻辑,包括其独特的(可能非标准的)参数计算方法和分段函数公式。
输入:
vmax
: 路径上的最大速度。TA
: 加速(或减速)阶段的总时间(用于推导 \(a_{max}\) 和 \(j_e\))。sall
: 要移动的总路径长度。ts
: 时间步长。
输出:
ac
,vc
,sc
: 包含加速度、速度、位移值的 NumPy 数组。time_vec
: 对应的时间点数组。params
: 包含中间计算参数(如 \(T_1..T_5, j_e, a_{max}, t_1..t_5\) 等)的字典。
计算逻辑:
根据
vmax
和TA
计算 \(a_{max} = vmax / TA\)。根据 MATLAB 代码逻辑设置 \(T_1 = T_2 = T_4 = T_5 = TA\)。
计算加加速度(Jerk) \(j_e = a_{max} / T_1\)。
根据 MATLAB 代码中的特定公式计算匀速阶段时间 \(T_3 = (sall - 2 j_e T_1^3) / vmax\)。如果 \(T_3 < 0\),则打印警告并将 \(T_3\) 设为 0。
计算各阶段的时间边界 \(t_1, t_2, t_3, t_4, t_5\)。
生成时间向量
time_vec
。初始化
ac
,vc
,sc
数组。遍历时间向量中的每个时间点 \(t\),根据 \(t\) 所处的阶段(由 \(t_1..t_5\) 界定),应用 MATLAB 代码片段中给出的分段公式计算瞬时的 \(a(t), v(t), s(t)\)。
函数结束时会检查最终位移是否接近
sall
,并报告最终速度(根据 MATLAB 代码,最终速度可能不为零)。
8. 主程序 (if __name__ == "__main__":
)¶
这是脚本的执行入口。
流程:
参数设置: 获取机器人参数,并设置轨迹参数(圆半径 \(r\), \(v_{max}\), \(T_A\), \(t_s\), 总路径长度 \(s_{all}\), Z 高度
z_level
, Y 偏移y_offset
)。这些参数与 MATLAB 代码中的注释/值一致。生成运动轮廓: 调用
s_velocity_motion
函数得到 \(s(t), v(t), a(t)\) 曲线,并绘制这些曲线。计算轨迹点和关节值 (IK 循环): a. 遍历由运动轮廓生成的时间点。 b. 对每个时间点
ntt
: i. 计算当前沿圆弧的位移 \(s_{current} = sc[ntt]\)。 ii. 计算对应的圆弧角度 \(\alpha = s_{current} / r - \pi/2\)。 iii. 计算目标笛卡尔位置 \((x_p, y_p, z_p) = (r\cos\alpha, r\sin\alpha + y_{offset}, z_{level})\)。 iv. 计算目标笛卡尔速度 \((v_{xp}, v_{yp}, v_{zp})\),使用链式法则,基于 \(v(t)\)。 v. 计算目标笛卡尔加速度 \((a_{xp}, a_{yp}, a_{zp})\),考虑切向加速度 \(a(t)\) 和向心加速度 \(v(t)^2 / r\)。 vi. 调用inverse_kinematics
函数计算该笛卡尔点对应的关节变量 \((q_1..q_4, \theta_1, \theta_2)\) 和机器人姿态 \((R_4, r_p)\)。 vii. 存储计算结果,并处理可能的 IK 错误。计算关节速度: 使用有限差分法(中心差分、前向/后向差分)根据计算出的关节位置序列 \(q_1(t), q_2(t), q_3(t)\) 估算关节速度 \(v_{q1}(t), v_{q2}(t), v_{q3}(t)\)。
绘图: a. 绘制期望的 3D 笛卡尔轨迹(圆形)。 b. 绘制关节空间轨迹(关节位置 \(q_i\) vs 时间,关节速度 \(v_{qi}\) vs 时间)。
动画: a. 创建一个 3D 绘图窗口。 b. 遍历计算出的机器人姿态序列。 c. 在每一帧,调用
plot_robot
绘制机器人在该时刻的姿态。 d. 绘制已经过的轨迹路径。 e. 暂停一小段时间,然后更新到下一帧,形成动画效果。
9. 总结¶
该脚本成功地将 MATLAB 中的特定机器人运动学模型和轨迹规划逻辑转换为了 Python 实现。它利用 NumPy 进行数值计算,SymPy 处理正解中的符号方程,Matplotlib 进行结果可视化。核心在于 inverse_kinematics
、forward_kinematics
和 s_velocity_motion
函数,以及将它们串联起来计算并展示圆形轨迹的主程序逻辑。需要注意的是 s_velocity_motion
函数是为了精确复制源 MATLAB 代码的行为而编写的,其内部参数推导可能与标准的运动规划理论有所不同。