ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

并联式四足机器人竞技方案:从运动学建模到步态控制的完整实现

并联式四足机器人竞技方案:从运动学建模到步态控制的完整实现 简介这是湖北工业大学竞技机器人项目中的并联式四足机器人完整方案面向机器人竞赛、机电一体化及嵌入式开发者。每条腿由两个电机驱动四条腿共八电机通过运动控制实现行进步态三足支撑、小跑步态两拍步态、溜蹄步态与疾驰步态四种由慢到快的步态切换并配套源码与文档说明。资源共855个文件压缩包约95.88MB包含C语言源码392个.c与169个.h及Keil工程文件uvprojx/uvoptx覆盖STM32控制逻辑另有SolidWorks三维模型118个.sldprt与28个.sldasm、STEP/DWG机械图以及运动学配置与仿真文件.icf、.s等便于结构查看与二次开发。目前已有92人学习下载适合高校学生作为课设、毕设或竞赛项目参考。下载后可联系作者远程教学代码均经测试运行成功可直接编译调试也可在原有基础上修改以扩展其他步态或功能。1. 并联式四足机器人竞技机器人项目里最容易被低估的底盘方案高校竞技机器人赛场上四足机器人一直是个“看起来热闹、做起来头疼”的方向。多数队伍起步选型时脑子里默认的是一条腿三个舵机、仿生遛狗姿态的串联结构图纸好画、资料好找、调起来也直观。可一旦进入擂台对抗、越障负重、高速冲刺这类竞技场景串联腿的刚度短板马上暴露关节间隙被冲击放大、末端抖动收不住、负载一上去电机就过热。于是有小部分队伍会反着来把每条腿做成并联机构——三个驱动支链同时支撑一个足端整条腿像一个微型 Stewart 平台。标题里这个「并联式的四足机器人」项目往深了说就是这套思路用闭环结构的刚度换串联结构的灵活性用控制复杂度换强对抗下的稳定性。这篇文会把并联四足从选型到运动学、从步态到代码组织完整捋一遍核心目标是让看过标题想复现的人能拿着自己的源码和文档把逻辑闭环跑通。适合正在做竞技机器人、想换结构方案或者纯粹想把并联机构落地到足式平台上的工程师和学生队伍。2. 为什么竞技场景要放弃串联腿并联拓扑的刚度、承载与控制代价2.1 串联腿与并联腿在足式机器人上的本质差异四足机器人最常见的串联腿是从髋关节到膝关节再到踝关节的链式结构每个关节都是一个主动旋转自由度。它的优点是工作空间大、运动学直观、每条腿的关节坐标直接对应身体坐标逆解是几个三角函数就能算完的事缺点是结构刚度依赖关节减速器和壳体本身的刚性竞技时的横向冲击会顺着连杆传到电机轴上齿轮间隙一旦被反向冲击打出来足端定位精度立刻恶化。并联式四足腿的思路完全不同。以每条腿的三个驱动支链为例足端平台通过三条独立的驱动链连接到机身髋部三个驱动器共同决定足端的三个自由度通常是两转动加一移动或者三平移视具体拓扑而定。结构是闭链载荷由多条支链分摊同样的输出力需求下可以用更小的电机碰撞冲击大部分被结构吸收而不是怼进减速器。代价是运动学关系高度耦合逆解还能用几何关系硬解正解基本没有解析解必须在控制器里跑数值迭代工作空间也远比串联腿小足端伸缩行程和摆腿幅度都受限。表格对比一下两种结构在竞技场景里的表现对比项串联腿并联腿足端工作空间大摆腿幅度容易做大小行程受支链摆角限制结构刚度低关节间隙影响大高闭链分摊载荷抗冲击能力差冲击直接作用在减速器上好结构件先承受冲击运动学逆解解析解适合高频控制解析解或迭代解计算量大正解解析式传感器融合方便数值迭代依赖初值电机需求大扭矩电机重量成本高小扭矩电机靠结构补力控制周期可跑到 1kHz 以上通常 200Hz~500Hz受迭代耗时限制竞技擂台赛这种场景抗冲击和结构刚度排在灵活性前面并联拓扑的优势就放大了。但优势和代价是同一枚硬币的两面做选型时得先想清楚自己的赛项到底是要大步幅奔跑还是要负重/对抗下的稳定支撑。前者串联更省事后者才有必要上并联。2.2 竞技机器人里并联四足的功率密度和稳定性收益竞技机器人对功率密度的要求比仿生表演机器人高得多。并联腿让三个驱动器可以分散布置在机身侧边腿本身变成轻量化连杆组机身重心更集中转动惯量更小。这让机器人在受到侧向撞击时不容易翻倒落地时的能量也更容易通过闭链结构传递到整个机身而不是局部关节。实际做样机验证时建议用一个简单的刚度测试来量化收益把机器人四足落地后按在机身侧面施加 50N 的横向推力用激光位移计测机身侧倾角并联腿方案的侧倾角通常只有同重量级串联腿方案的三分之一左右。数据好看是一方面更重要的是电机电流——同样的推地动作并联腿单电机峰值电流能低 20%~40%对电池和电调的压力小很多。这里提醒一下并联腿不是玄学它只是把原本需要关节去扛的力转移到了结构件上。材质选用上3D 打印的 PLA 顶多是用作原型验证竞技机器人至少得上碳纤维管加铝合金端头否则闭链结构会把应力集中到节点处比串联腿更容易在连接件处断裂。3. 从运动学建模到最小实现并联式单腿的代码级落地3.1 并联腿拓扑选取三支链六自由度方案在三自由度足端的简化并联腿的拓扑种类很多真正在四足机器人上能实用的其实不多。最常见的两种一种是每条腿用三根 PRR 支链P 为移动副、R 为转动副三个滑块沿机身侧面导轨移动驱动足端在三个方向平动另一种是每条腿用两个旋转驱动加一个线性驱动组成平面闭链。前一种刚度更均匀驱动布置容易后一种结构紧凑但工作空间奇怪做竞技机器人优先考虑前者。这里给一个容易抄作业的方案每条腿由三个推杆电机构成推杆的底座固定在机身的髋部法兰上推杆末端通过球铰连接到足端法兰。足端自由度是三个方向的平移足端姿态由结构本身限制。这种结构的好处是推杆电机自带位置反馈省掉外置编码器的机械设计支链和足端的连接只用球铰或虎克铰加工和装配约束少运动学模型退化为三根空间直线求解逆解甚至不需要迭代。但要注意足端三个平移自由度的并联腿摆腿时的姿态是固定的迈步只能平移、不能抬脚转踝。竞技机器人不太依赖脚踝姿态这个代价可以接受。如果需要足端姿态变化就得用六自由度并联平台加更多驱动四足承载 24 个驱动器成本和重量基本不可控。3.2 逆解公式推导三推杆长度与足端坐标的几何映射三支链并联腿的逆解本质上是给定足端目标位置反求每个推杆的长度。推杆底座的球铰中心在机身坐标系中的坐标是已知常数由机械设计决定足端法兰的球铰中心坐标是随足端位置平移的两球铰中心的距离就是推杆当前长度。设足端目标位置为P [px, py, pz]^T三个底座球铰中心在机身坐标系下的坐标为Bi足端法兰上的三个球铰中心为Ei那么足端在目标位置时第i个球铰中心在机身坐标系的位置是Ei P Ri其中Ri是足端法兰上球铰中心相对于足端原点的固定偏移。推杆长度直接由空间两点距离公式得到import numpy as np # 底座三个球铰中心坐标机身坐标系单位 mm B np.array([ [ 50.0, 0.0, 0.0], [-25.0, 43.3, 0.0], [-25.0,-43.3, 0.0] ]) # 足端法兰上三个球铰中心相对足端原点的偏移 R np.array([ [ 30.0, 0.0, 0.0], [-15.0, 26.0, 0.0], [-15.0,-26.0, 0.0] ]) def leg_inverse_kinematics(target_pos): 并联腿逆解输入足端目标位置输出三推杆长度 返回 (长度列表, 是否在可行范围内) lengths [] for i in range(3): # 足端处于目标位置时法兰球铰中心 目标位置 相对偏移 E target_pos R[i] # 推杆长度 底座球铰到法兰球铰的欧氏距离 l np.linalg.norm(E - B[i]) lengths.append(l) return lengths # 举例足端从零位下沉 20mm 再前伸 30mm target np.array([30.0, 0.0, -20.0]) lengths leg_inverse_kinematics(target) print(推杆长度(mm):, lengths)逆解代码的核心逻辑是把空间几何问题拆成两个向量相减再取模长没有任何复杂的三角函数。B数组是机械设计出的常量如果底座的三个球铰不在同一个圆上或者夹角不是 120 度只需要替换这些坐标即可。R数组是足端法兰的球铰布局通常情况下三个球铰也在同一圆上、相隔 120 度和B的布局保持一致这样推杆在零位时三条腿长度一致标定省事。这段代码里真正需要验证的是数值边界当足端目标位置靠近工作空间边缘时某个推杆可能超出电机行程。所以逆解之后必须加一个行程检查把三个算出来的长度和推杆电机的物理行程比较超出就直接丢弃这组目标值否则控制器会带着电机往限位硬顶轻则丢步重则烧驱动。3.3 正解数值迭代竞技中传感器失效状态下怎么估算足端位置竞技机器人连续对抗中足端触地传感器和 IMU 都可能被撞坏或丢失数据此时如果只有推杆长度反馈要估算足端位置就得解正解。正解没有解析式常规做法是高斯-牛顿迭代给定一个足端位置初值计算出对应的三推杆长度和实际测量到的推杆长度做差然后沿误差下降方向修正足端位置反复迭代直到误差小于阈值。def leg_forward_kinematics(measured_lengths, init_guess, max_iter50, tol1e-6): 并联腿正解已知三推杆长度用高斯-牛顿迭代求足端位置 返回 (足端位置, 迭代次数) p np.array(init_guess, dtypefloat) for i in range(max_iter): # 当前猜测位置对应的一组推杆长度 current_lengths np.array(leg_inverse_kinematics(p)) # 残差测量值减计算值 error measured_lengths - current_lengths if np.linalg.norm(error) tol: return p, i # 数值雅可比分别对 px, py, pz 求偏导 J np.zeros((3, 3)) delta 1e-6 for j in range(3): p_plus p.copy() p_plus[j] delta l_plus np.array(leg_inverse_kinematics(p_plus)) J[:, j] (l_plus - current_lengths) / delta # 高斯-牛顿步J^T J dx J^T error dx, _, _, _ np.linalg.lstsq(J, error, rcondNone) p dx return p, max_iter高斯-牛顿迭代的收敛性依赖初值质量。竞技场景下相邻控制周期足端位置变化不大上一帧的正解结果直接作为下一帧的初值即可但如果发生剧烈碰撞导致足端突跳迭代容易发散。我一般会加一个防御逻辑如果np.linalg.norm(dx)超过一个物理上不可能的距离上限比如单帧 30mm就丢弃该帧正解结果用上一帧数值替代。正解运算量不大在 Cortex-M7 级别的单片机上 500Hz 周期内跑 20 次迭代没什么压力但在廉价 M3 上就要适当放宽收敛阈值。3.4 从理论到首条腿动起来最小硬件清单与上电调试顺序并联腿理论建模再完整最终要让腿动起来硬件链路必须先跑通。最小系统清单包括三路推杆电机带位置反馈行程 50~80mm推力不低于 50N六自由度力/位置传感器安装在足端与法兰之间竞技场景建议必配一个内部定时器周期不低于 500Hz 的 MCU 或树莓派加实时核推杆电机驱动器支持位置闭环模式通讯方式用 CAN 或 RS485 均可外部稳压电源电压和电流余量至少 30%。上电调试顺序有讲究。第一步先做电机单体行程扫描给每路推杆发送 0%、25%、50%、75%、100% 位置指令确认实际反馈行程和代码里的行程常量一致。第二步是把三个推杆拆离机身手动摆出一个大致姿态用尺子量出推杆长度喂给正解函数看输出的足端位置和实际摆放是否一致这一步直接验证运动学代码的正确性。第三步才把推杆装回机身让足端在低速度模式下目标速度设为最大速度的 10%走一个竖直往复确认三个电机同步。最后在足端挂一个 3kg 配重重复竖直往复观察电机电流和位置跟踪误差误差超过 2mm 就说明结构刚性不足或控制增益太低。建议调试时记录一个最容易被忽略的量电机在匀速段的位置跟踪误差。竞技场景的冲击容易让位置环的积分项饱和积分一旦饱和碰撞结束后的恢复响应会明显滞后。解决办法是把位置环改成 PD前馈前馈速度由运动学求导给出积分项做个限幅限幅值设为额定推力的 30%。4. 整机步态规划与竞技对抗并联腿的 Trot 步态怎么移植和控制4.1 并联腿步态规划的特殊性足端轨迹不能照搬串联腿串联四足的步态规划通常把足端轨迹设计成贝塞尔曲线或摆线保证触地阶段水平速度为零、腾空阶段有一定离地高度。这套数学工具在并联腿上仍然适用但有一个物理约束不能忽略并联腿的足端垂直力是靠推杆轴向力合成的足端在一个方向的大力会同时影响另外两个方向的力分配。串联腿的足端轨迹可以指哪打哪并联腿的足端轨迹则要考虑推杆力饱和后的实际响应。一个实用的做法是在足端轨迹生成阶段加一步“可达成性检查”对每个轨迹点做正解可行性校验检查推杆长度是否在电气行程的 90% 以内以及推杆伸出速度是否超过电机最大速度的 80%。超出就主动压缩该方向的轨迹幅度。这样牺牲一点步幅换来每个控制周期都是可执行的不会因为某一帧轨迹在奇异点附近导致整条腿锁定。Trot 步态对角小跑在并联式四足上依然是对角腿成对动作。两条对角腿的推杆长度变化需要同步所以在步态状态机里四个腿共 12 个推杆要按腿分组同步发布指令。我的做法是把四条腿分别建模为独立的并联腿对象每个对象包含本腿的三路推杆位置再由步态调度器把同一时刻四条腿的目标足端坐标批量化计算一次性生成 12 路推杆指令。4.2 步态调度器的状态机实现支撑相与摆动相的最小可跑代码class TrotGaitScheduler: 对角步态调度器支撑/摆动相切换输出四腿目标位置 腿部编号0左前, 1右前, 2左后, 3右后 对角配对(0,3) 和 (1,2) def __init__(self, phase_duration0.25, step_height30.0, step_length40.0): self.phase_duration phase_duration self.step_height step_height self.step_length step_length self.time 0.0 self.period phase_duration * 2 def update(self, dt, body_shift): 每控制周期调用一次dt为周期秒数返回四腿足端目标位置 self.time dt phase (self.time % self.period) / self.period # 0~1 一个周期 targets [] for leg_id in range(4): # 对角腿相位相同另一对相位相差 0.5 if leg_id in (0, 3): leg_phase phase else: leg_phase (phase 0.5) % 1.0 if leg_phase 0.5: # 摆动相抬腿前摆 t leg_phase / 0.5 z self._swing_curve(t) x body_shift self.step_length * (t - 0.5) targets.append([x, 0.0, z]) else: # 支撑相贴地后扫 t (leg_phase - 0.5) / 0.5 x body_shift - self.step_length * (0.5 - t * 0.5) targets.append([x, 0.0, 0.0]) return targets def _swing_curve(self, t): 摆动相抬腿高度曲线中间高两端低 return self.step_height * np.sin(np.pi * t)调度器的状态划分是相位思想而不是硬切换摆动相从触地瞬间开始计时支撑相从落地瞬间开始计时两条对角腿互为对方的补集。步态周期period是单腿一个完整支撑加摆动的时间phase_duration是单相持续时间默认各 0.25 秒对应 2Hz 的步频竞技机器人可以把这个值压到 0.15 秒左右推杆速度需求会明显上升要确认电机跟得上。step_length太大时支撑相后扫阶段推杆会有明显的速度尖峰建议逐步加每次增加不超过上一轮步长的 20%。4.3 竞技场景力控足端接触力估计与简单阻抗控制竞技对抗时单纯的位置控制不够用。机器人撞到对方或被推时位置偏差会累积步态会乱。常见做法是给足端加力控外环通过推杆电机的电流估计足端接触力再叠加一个阻抗模型调整足端目标位置让腿表现出“弹性”而不是“刚性”。简化版阻抗控制公式为F_contact K_imp * (P_desired - P_current) D_imp * (V_desired - V_current)控制周期内把接触力误差映射成一个足端位置的修正量叠加到步态规划的目标位置上。实现时把修正量限制在正负 8mm 内防止阻抗修正把足端推离工作空间边缘。class ImpedanceLegController: 单腿阻抗控制根据接触力修正足端目标位置 K_imp 是刚度系数D_imp 是阻尼系数 def __init__(self, k_imp800.0, d_imp3.0, max_correction8.0): self.k_imp k_imp self.d_imp d_imp self.max_correction max_correction self.prev_contact_force 0.0 def compute(self, desired_pos, current_pos, contact_force, dt): force_error contact_force - 0.0 # 位置修正按力误差比例调整阻尼项用一阶差分近似速度 correction force_error / self.k_imp correction (contact_force - self.prev_contact_force) / (self.k_imp * dt) * self.d_imp # 限制修正量 correction max(-self.max_correction, min(self.max_correction, correction)) self.prev_contact_force contact_force return desired_pos np.array([0.0, 0.0, correction])阻抗控制的参数标定方法是先把K_imp设为刚度下限机器人在平地慢走不震荡再逐步加大直到机体出现高频抖动回退 30% 作为工作点。D_imp调的力度要小于刚度系数主要用来抑制碰撞后的残余震荡。接触力估计最简单的来源是三路推杆电机的输出力估计值乘以支链方向向量累加不需要额外传感器但前提是电机的电流环带宽足够至少 2kHz。竞技对抗中足端冲击力会在几毫秒内到峰值位置型控制器如果控制周期只有 1ms电压余量不足会导致推杆内电流环饱和力估计失真。5. 源码工程组织与文档化竞技机器人项目怎么交付别人能接着跑5.1 源码目录结构底层驱动、运动学库、步态算法、工具链分层竞技机器人项目源码最容易犯的错是把所有代码堆在一个 main 文件里改动一处牵一发动全身。拿到这种项目几乎不可能不看文档二次重构就能比赛。规范化的目录结构通常是这样分层quadruped_parallel/ ├── doc/ │ ├── hardware_bom.md # 硬件清单与采购说明 │ ├── calibration_guide.md # 推杆行程标定流程 │ └── gait_tuning_notes.md # 步态调参记录模板 ├── firmware/ │ ├── hal/ # 硬件抽象电机驱动、CAN通信、定时器 │ ├── kinematics/ # 正逆解、雅可比、行程检查 │ ├── gait/ # 步态状态机、足端轨迹生成 │ ├── control/ # 位置环PD、阻抗控制、力估计 │ └── main.c # 主循环定时器中断里调用各模块 ├── sim/ │ ├── leg_sim.py # 单腿仿真脚本验证运动学 │ └── gait_sim.py # 整机步态数据记录器 ├── tools/ │ ├── plot_trajectory.py # 轨迹可视化 │ └── parameter_scan.py # 参数扫描调优 └── README.md # 项目构建与快速复现指南hal层是唯一允许直接调用硬件寄存器的模块上层代码全部走接口调用。kinematics层是纯数学库不依赖任何硬件头文件方便在 PC 上单独测试。步态和控制在 kinematic 之上相互之间不直接耦合步态只管足端目标位置控制只负责把足端位置变成推杆指令。这个结构下如果赛后想换另一种步态只需要新增gait目录下的策略文件不用碰底层。5.2 文档说明的关键内容标定数据、调参记录和复现步骤题目里强调“文档说明”说明这份源码的价值不只在于能跑还在于别人拿到后能复现。文档至少要包含三类信息第一类是机械和电气参数表。每个推杆的行程、推杆底座球铰中心坐标、足端法兰偏移、电机减速比、编码器分辨率、CAN ID 对应关系全都列成表格。没有这些数据运动学代码里的B和R数组就是一堆拍脑袋的数字任何做二次开发的队伍都无从下手。第二类是标定记录。每个推杆的位置反馈原始值和实际行程毫米值的映射关系是线性还是多项式拟合零位偏置是多少工作空间边界实测是多少。标定记录必须注明标定日期和环境温度因为推杆的丝杠热胀冷缩会对毫米级精度产生影响。第三类是调参记录。步态周期、步长、抬腿高度、阻抗刚度、阻尼系数每次改了什么、效果如何、为什么改按时间记录。竞技机器人几乎没有一次调好的这份记录能避免队伍在同一个参数上反复横跳。一个容易被忽略的文档点是依赖清单上位机仿真脚本依赖 Python 版本和 numpy 版本下位机固件依赖的编译工具链都必须写清楚。很多项目换一台电脑就编译不过往往是依赖管理没写全。5.3 离线仿真验证不依赖实物的运动学自检流程实机调试前必须用离线仿真验证代码正确性至少能筛掉 80% 的低级错误。仿真流程分两层第一层是单腿逆解再正解的闭环验证随机生成 10000 个工作空间内的足端目标位置逆解得到推杆长度再把推杆长度喂给正解计算正解结果和原始目标位置的误差。如果误差超过 1mm说明正解迭代写错了或迭代次数不够。# 单腿运动学闭环验证10000 组随机点 python tools/kinematics_validate.py --iterations 10000 --tolerance 1.0第二层是步态轨迹离线检查把步态调度器生成的整机足端轨迹全部过一遍逆解与行程检查如果某帧某个推杆长度超出行程直接报错并输出是哪个腿、哪个推杆、超出多少。这一步能提前发现步态参数设置中工作空间不足的问题否则实机上等于是把机器人往结构极限上撞。仿真通过后再上实机先做单腿悬空测试再做整机四点支撑测试最后才走步态。每一步的通过标准都要明确悬空测试看运动学跟踪误差小于 2mm四点支撑看各腿推杆位置稳定无漂移整机步态看机身水平姿态误差小于 3 度。只有前一步达到标准才可以进入下一步跳过任何一环都会让后面的问题定位变得模糊。5.4 排查链路并联腿起跳/摔倒后的恢复处理技巧并联四足竞技中最容易出的故障是摔倒后推杆位置乱掉。因为摔倒时足端受到的外力会强行改变推杆位置电机的编码器还能读到位置但已经不在正常步态的相位里。恢复流程是一个固定序列先把足端抬到最高并收拢也就是将推杆全部缩到最短这个位置姿态最高、最不容易和地面干涉。然后重新标定零位再按步态相位归零进入待机状态。还有一类问题是高速奔跑时推杆行程走满但机器人没有明显前进。这往往是支撑相足端轨迹后扫速度和机身前进速度不匹配引起打滑。检查方法是把支撑相轨迹的目标速度调出来和机身实测速度对比如果差 30% 以上优先减小步长而不是增加步频步长缩小到打滑消失后再逐步加速。竞技对抗中的冲击也常导致推杆端部的球铰松动表现为特定姿态下出现周期性异响和重复位置误差这类机械问题不是代码能兜住的文档的硬件维护章节里建议写明每个比赛日后检查球铰紧固力矩的条目。本文还有配套的精品资源点击获取
返回列表