ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

用Python复算蔡自兴《机器人学》课后题:DH参数与运动学验证

用Python复算蔡自兴《机器人学》课后题:DH参数与运动学验证 简介蔡自兴《机器人学》教材配套的课后练习题答案文档面向高校机器人、自动化及相关专业学生也适合考研复习与工程人员自学梳理核心概念。内容从坐标系变换切入系统覆盖旋转矩阵、平移矩阵、机械手运动学、连杆参数、变换矩阵应用、微分变换等知识点解答过程给出旋转矩阵推导、齐次变换顺序左乘/右乘、3自由度机械手运动方程式求解等完整思路并通过楔形物体重摆放、多关节机械手等典型例题对比不同坐标系建立方法下的参数表与变换序列。压缩包内含1个doc文件约592KB排版清晰便于按题复习或打印精读文档中保留矩阵运算与坐标变换步骤亦可作为课程作业或考研刷题的自检参考。当前已有843人学习下载配合教材逐章学习能有效巩固机器人学核心概念与解题方法。1. 从一道符号推导题看《机器人学》课后练习的门道蔡自兴版《机器人学》是国内机械、控制类专业用得最广的教材之一课后题不像高数那样套公式就能算完很多题要自己设变量、建坐标系、写矩阵最后甚至没有唯一答案。比如一道典型的“用 DH 参数求正运动学”题目同一个机械臂坐标系画法不同生产出来的变换矩阵就不一样但最终末端位姿必须一致。这就是“对答案”最麻烦的地方你翻遍网络文库找到的答案往往用的是另一套坐标系中间步骤跟自己写的不一样结论却可能殊途同归。这篇博文不是提供现成答案而是把这类课后续做对、做快、能验证的路径梳理清楚适合正在啃这本教材的学生也适合带毕设、需要快速帮学生查错的青年教师。2. 拆解蔡自兴《机器人学》课后题的三条主线2.1 坐标变换和 DH 参数所有题目的地基教材前几章的核心是齐次变换矩阵课后频繁出现的题型是“已知两坐标系相对位姿求某点在新坐标系下的坐标”。这类题的关键是分清左乘和右乘绕固定坐标系转动时矩阵左乘绕动坐标系转动时矩阵右乘。很多错误答案不是计算错而是乘序反了。DH 参数Denavit-Hartenberg是另一类高频考题。你需要从题目给出的机械臂结构图里读出四个参数连杆长度a_i、连杆转角alpha_i、连杆偏距d_i、关节角theta_i。常见的坑在于alpha_i的方向教材约定逆时针为正但同一张图换个视角看正负号就容易写反。我的建议是每道题先画出坐标轴再列 DH 表最后才写矩阵顺序不要乱。2.1.1 列 DH 参数表的标准步骤拿到题目给的机械臂简图后按以下步骤操作从基座开始依次给每个关节标号直到末端工具坐标系。确定每个关节的z轴方向旋转关节沿转动轴线移动关节沿移动方向。相邻两个z轴的公垂线方向定为x轴alpha_i是从z_{i-1}转到z_i的角度。a_i是公垂线的长度d_i是沿着z_{i-1}方向测量的两个公垂线交点间距离。我用一个具体例子说明。假设题目给了一个两连杆平面机械臂两个旋转关节杆长分别是L1和L2。DH 表可以写成关节 itheta_id_ia_ialpha_i1q10L102q20L20这里d_i全为 0因为平面机械臂所有关节都在同一平面内没有偏距。alpha_i也为 0因为没有相邻轴的扭转。2.1.2 从 DH 表到末端位姿的矩阵连乘写出每个关节的变换矩阵然后依次相乘。标准公式是T_i Rot(z, theta_i) * Trans(z, d_i) * Trans(x, a_i) * Rot(x, alpha_i)展开后的矩阵长这样建议自己手推一遍比直接套公式记得牢| cos(theta) -sin(theta)*cos(alpha) sin(theta)*sin(alpha) a*cos(theta) | | sin(theta) cos(theta)*cos(alpha) -cos(theta)*sin(alpha) a*sin(theta) | | 0 sin(alpha) cos(alpha) d | | 0 0 0 1 |末端位姿就是T T1 * T2 * ... * Tn。做题时最容易错的是矩阵乘法顺序和三角函数正负号建议每一步都保留符号不要急着代数值。很多参考答案直接给出数值结果你只能靠这个矩阵去核对自己的推导过程。2.2 运动学正解与逆解课后题的大头正解是把关节角度映射到末端位姿逆解则反过来。教材里关于逆解的题目比正解多得多因为逆解没有固定套路要分情况讨论。常见出题方式是“给定末端位置求各关节角度”这时你先判断机械臂的自由度是否够用再决定用代数法还是几何法。代数的核心是消元利用sin^2 cos^2 1消去一个变量或者对矩阵方程左乘逆矩阵把某个关节角单独分离出来。几何法则是在二维平面里画出三角形利用余弦定理直接求出角度。两种方法算出来的结果可能有多组解这就是所谓的“多解性”。课后答案一般只给一组但你需要把另外几组也写出来才算真正理解了逆运动学的本质。2.2.1 一个两连杆机械臂逆解的代数推导以两连杆平面臂为例给定末端位置(x, y)求q1和q2。先写正解公式x L1*cos(q1) L2*cos(q1 q2) y L1*sin(q1) L2*sin(q1 q2)把x和y平方和相加得到x^2 y^2 L1^2 L2^2 2*L1*L2*cos(q2)所以cos(q2) (x^2 y^2 - L1^2 - L2^2) / (2*L1*L2)注意这里要求x^2 y^2在|L1-L2|和L1L2之间否则无解这就是工作空间边界。q2有正负两解对应“肘上”和“肘下”两种姿态。q1用atan2求解q1 atan2(y, x) - atan2(L2*sin(q2), L1 L2*cos(q2))这个推导过程在蔡自兴教材里有类似例题但在网上找到的答案往往省略了中间消元步骤直接给出q1、q2的表达式。你如果只看答案很难知道这里的atan2参数是怎么凑出来的。2.3 雅可比矩阵与动力学从几何到力学的跳板后半册的课后题开始出现速度传递、静力传递和拉格朗日方程。雅可比矩阵的题目通常是“给定关节速度求末端速度”这本质上是线性代数的线性映射。有些题还要求你判断奇异位形也就是让雅可比矩阵行列式等于零的关节角度。这类题的计算量不大但需要你熟悉矩阵求导的规则。动力学题更抽象。拉格朗日法需要写出系统的动能和势能然后对广义坐标求导。教材习题里经常出现的“二连杆机械臂的动能表达式”很多学生在这里翻车因为他们忘了角速度是矢量合成不能简单把两个关节的角速度相加。这里建议把所有连杆的速度都先换算到基坐标系下再写能量表达式虽然步骤多但不容易漏项。3. 用 Python 在本地复算蔡自兴课后题的最小方案3.1 用 numpy 实现 DH 矩阵验证你手算的正解手算容易错尤其是矩阵乘法涉及十几个sin和cos项时。写一段简单的 Python 脚本把 DH 参数输进去直接输出末端位姿矩阵用来对答案非常方便。下面是一个最小实现import numpy as np def dh_transform(theta, d, a, alpha): 根据 DH 参数返回 4x4 齐次变换矩阵 theta, d, a, alpha 均为弧度制 st np.sin(theta) ct np.cos(theta) sa np.sin(alpha) ca np.cos(alpha) return np.array([ [ct, -st * ca, st * sa, a * ct], [st, ct * ca, -ct * sa, a * st], [0, sa, ca, d], [0, 0, 0, 1] ]) # 两连杆机械臂q130度q245度L11L20.8 T1 dh_transform(np.deg2rad(30), 0, 1.0, 0) T2 dh_transform(np.deg2rad(45), 0, 0.8, 0) T T1 T2 print(T)这段代码里的运算符在 numpy 里等价于矩阵乘法。np.deg2rad把角度转成弧度避免手算时混淆单位。输出的第四列前三行就是末端位置(x, y, z)第三列前三行是末端z轴在基坐标系里的方向余弦这些数字可以和你手算的答案逐项比对。3.2 逆运动学数值验证用 scipy 求非线性方程组教材课后题给的逆解解析式虽然能用但当机械臂超过三个自由度时手推解析解极其痛苦。你完全可以用scipy.optimize.fsolve数值求解逆运动学用来反向验证正解代码的正确性。思路是定义一个误差函数输入关节角输出末端位姿与目标位姿的误差然后让 fsolve 把这个误差压到零附近from scipy.optimize import fsolve def forward_kinematics(q, L11.0, L20.8): 两连杆正解返回 x, y x L1 * np.cos(q[0]) L2 * np.cos(q[0] q[1]) y L1 * np.sin(q[0]) L2 * np.sin(q[0] q[1]) return x, y def target_error(q, target_x, target_y): x, y forward_kinematics(q) return [x - target_x, y - target_y] # 目标是正解 q(30°, 50°) 产生的位姿 target_x, target_y forward_kinematics([np.deg2rad(30), np.deg2rad(50)]) # 从另一个初值出发搜索 initial_guess [0.1, 0.1] solution fsolve(target_error, initial_guess, args(target_x, target_y)) print(数值解:, np.rad2deg(solution))如果结果收敛到 30 度和 50 度说明正解函数没写错。如果收敛到另一组解比如负角度这也是正常的逆运动学本身多解。fsolve 的初值选择很敏感建议从多个初值点出发把能收敛到的所有解都列出来再对照教材答案看哪些是合理姿态。3.3 用矩阵求导验算雅可比矩阵速度雅可比题目的标准做法是对正解表达式逐个求偏导。如果你不想手算可以用有限差分法近似验证。假设你已经写出了正解函数那么雅可比矩阵的第i行第j列可以用以下公式估算def jacobian_num(f, q, delta1e-6): 数值雅可比f 是正解函数返回 n 维向量 n len(q) m len(f(q)) J np.zeros((m, n)) for j in range(n): q_plus q.copy() q_minus q.copy() q_plus[j] delta q_minus[j] - delta J[:, j] (f(q_plus) - f(q_minus)) / (2 * delta) return J # 验证前文的两连杆正解在某个构型下的雅可比 q_test np.array([0.5, 0.8]) J jacobian_num(forward_kinematics, q_test) print(数值雅可比:\n, J)这个脚本的价值不在算题而在排查。如果你手推的雅可比矩阵和数值结果差很多大概率是链式法则漏了一项或者某个cos(q1q2)被错误地当成cos(q1)处理了。4. 与参考答案对不上的时候先查这几个环节4.1 坐标系定义不一致导致的“答案错误”网上流传的蔡自兴课后答案最常见的差异是坐标系的z轴朝外还是朝里。教材第 2 版和第 3 版的图例有变化部分题目在文中的图示和习题册的图示方向相反。如果你发现答案里的a2符号跟你算的差一个负号十有八九是alpha角的旋转方向画反了。建议以教材正文例题的坐标系画法为基准不要用习题册后面的示意图直接套参数。4.2 单位制和角度制混用课后答案文档里经常出现sin(30)和sin(pi/6)混用的情况。如果是数值结果答案步长通常是弧度制但题目本身用角度描述。你手算时如果先用角度制求值再代入代码里的弧度制函数结果会差一个pi/180的系数。我在第 3 章的代码里统一用deg2rad做转换就是为了避免这类隐性问题。4.2.1 用符号计算结果比对中间步骤如果你拿到一份答案只写了最终矩阵没有中间过程可以用sympy做符号推导把每一步矩阵连乘展开成多项式再代入具体角度跟答案的数值比较。符号计算的额外好处是你还能直接得出sin(q1)和cos(q1)的表达式和网上的答案去比变量名是否一致import sympy as sp q1, q2 sp.symbols(q1 q2) L1, L2 sp.symbols(L1 L2) # 直接写坐标表达式 x L1 * sp.cos(q1) L2 * sp.cos(q1 q2) y L1 * sp.sin(q1) L2 * sp.sin(q1 q2) # 用符号求导得到雅可比 J sp.Matrix([[sp.diff(x, q1), sp.diff(x, q2)], [sp.diff(y, q1), sp.diff(y, q2)]]) sp.simplify(J)这段代码输出的雅可比矩阵是符号形式你能直接看到哪些项是-L2*sin(q1q2)哪些是-L2*sin(q1q2)避免网传答案里打印错误对判断造成干扰。4.3 逆解的多解与边界解漏选一道课后题如果要求“求所有可能的关节角”答案往往只列了主解把“肘上”和“肘下”的另外一组漏了。判断自己是否算全的方法是看sin(q2)的正负q2 0和q2 0对应两种构型q1也随之变化。还有一个边界是当x^2 y^2 (L1L2)^2时机械臂完全伸直q2 0这时两组解退化成一组的唯一解。这类细节不会体现在简单的对照答案里但对理解机器人工作空间很有帮助值得专门留意。5. 用轨迹规划课后题反过来检验你的运动学代码5.1 关节空间与笛卡尔空间的插值差异教材后面的轨迹规划章节经常出现“给定两点求关节角插值”的题。这类题目看起来只是简单的线性插值但能有效检验你对正逆运动学的综合理解。关节空间插值是在q空间做线性变化Cartesian 空间插值是在末端坐标里做线性变化两者的中间状态完全不同。我通常建议在课后练习时把两条轨迹都用代码画出来感受差别这比背定义更直观import matplotlib.pyplot as plt q_start np.array([0.3, 0.5]) q_end np.array([0.8, 0.2]) # 关节空间插值 time_steps np.linspace(0, 1, 50) traj_joint [q_start * (1 - t) q_end * t for t in time_steps] traj_cart [forward_kinematics(q) for q in traj_joint] x_coords [point[0] for point in traj_cart] y_coords [point[1] for point in traj_cart] plt.plot(x_coords, y_coords, labelJoint-space) plt.legend() plt.show()没必要把两段轨迹的插值代码都贴出来但建议你在本地跑一下观察笛卡尔空间插值是否经过一条直线还是出现了弧度路径。这个现象能直接回答“为何机器人运动轨迹一般不采用笛卡尔插值”这类问答题。5.2 用课后题为你的毕设机器人建立验证流程如果正在做机械臂相关的毕业设计建议把第 3 章和第 4 章的方法串起来形成一套通用思路从题目里提取 DH 参数写正解函数用 fsolve 验证逆解再用数值雅可比核对速度推导。这套流程不依赖具体平台用 MATLAB 也可以改写成等价脚本。核心习惯是先写一个forward_kinematics(q)函数之后的逆解和雅可比都围着它转最后无论手算结果如何都以代码输出为准去排查教材答案的印刷错误。5.3 手动构造一个带偏移量的例子彻底弄清d_i的作用课后题里的机械臂为了简化计算通常把所有d_i设为零。但真实工业机器人几乎每个关节都有偏距。你可以在完成教材习题之后故意把某个d_i改成例如 0.2 米然后用第 3 章代码重新算一遍正解观察末端位置的变化规律。这个练习有助于在面试中快速回答“DH 参数中d和a对位姿的影响分别是什么”这类常见追问也不会被网上答案带偏你的理解。本文还有配套的精品资源点击获取
返回列表