1. 项目概述与核心思路
在机器人或自动化设备的设计中,实现垂直方向的往复或跳跃运动,弹簧通常是首选的储能和释放元件。它们结构简单、响应快,但同时也带来了非线性刚度、疲劳寿命和精确控制难度等问题。这次,我想挑战一个不同的思路:完全摒弃弹簧,仅依靠电机、传动机构和精密的运动控制,来实现类似跳跃的垂直驱动。这个项目的核心,就是构建一个基于齿条齿轮传动的“无弹簧跳跃腿”。
我选择ODrive S1作为电机控制器,驱动一颗MK8325s无刷电机,通过一个3D打印的齿轮带动齿条做直线运动。整个系统的“大脑”是一块Arduino Uno,它负责发送运动指令,并处理来自限位开关的反馈,实现位置控制和简单的跳跃序列。这个项目非常适合对机器人运动控制、机电一体化集成以及从CAD设计到实物调试全流程感兴趣的工程师、学生或爱好者。它不仅是一个机械装置,更是一个完整的运动控制实践案例,涵盖了硬件选型、机械设计、固件配置、嵌入式编程和系统调试等多个环节。
2. 核心硬件选型与设计考量
2.1 为什么选择ODrive与齿条齿轮?
在项目启动时,驱动方案和传动机构的选择是首要决策点。
电机与控制器(ODrive S1 + MK8325s):实现高动态性能的直线运动,需要一个能提供大扭矩、高响应速度且控制精度的驱动系统。普通的有刷直流电机或步进电机在需要快速启停和力控的场景下往往力不从心。无刷直流电机(BLDC)具有高功率密度和效率,但需要复杂的驱动电路。ODrive S1是一个开源的高性能无刷电机控制器,它集成了FOC控制算法,能提供极其平滑的扭矩控制、精确的位置和速度环,并且通信接口丰富。MK8325s电机与S1套件匹配,省去了参数匹配的麻烦。选择它们,意味着我们获得了接近工业级的运动控制能力,为后续实现复杂的跳跃轨迹(如正弦波、梯形速度曲线)打下了基础。
传动机构(齿条与齿轮):将旋转运动转化为直线运动,常见的有丝杠、皮带、连杆和齿条齿轮等。丝杠精度高但速度慢;皮带速度快但可能有弹性变形;连杆机构设计复杂。齿条齿轮机构在这类中小行程、中高速度与力的直线运动中表现均衡。它的优点在于:
- 传动效率高:齿轮啮合直接,能量损失小。
- 响应迅速:刚性传动,没有明显的滞后。
- 结构简单可靠:设计、加工和安装相对直观。
- 行程易于扩展:通过拼接齿条段,可以轻松增加运动范围。
对于跳跃动作,我们需要机构能快速将电机的旋转动能转化为腿部的直线动能,并在“触地”和“腾空”阶段实现快速的位置切换,齿条齿轮的刚性传动特性正好符合这一要求。
2.2 机械结构设计要点
整个机械结构围绕“稳定、顺滑、可调”三个目标展开。
1. 垂直导向与支撑框架: 跳跃腿的核心运动是垂直方向的,因此必须有一个刚性的导向结构来约束齿条,防止其在运动过程中发生偏摆或卡滞。我使用了1.5英寸x1.5英寸的80/20铝型材作为主立柱。这种型材标准、易获取,且四面都有T型槽,便于安装附件。为此,我专门设计并3D打印了一个滑动支架。这个支架的内腔尺寸需要与铝型材外廓保持极小的间隙(建议单边0.2-0.3mm),既要保证滑动顺滑,又要尽可能减少晃动。支架上预留了安装孔,用于固定齿条安装座。
2. 齿条齿轮的设计与加固:
- 齿轮:直接使用了McMaster-Carr的标准齿轮模型进行适配。关键是与电机轴的连接设计,我采用了紧定螺钉的抱紧方式,并设计了防转的D型孔或键槽,确保在高扭矩下不会打滑。
- 齿条:受限于3D打印机的成型尺寸,我将齿条设计为6英寸长的模块化分段。每段齿条的端部设计了内嵌六角螺母的槽,并使用一个独立的连接件和螺丝将两段齿条紧固连接。这种设计不仅解决了打印尺寸问题,还保证了多段齿条拼接后的齿距精度和整体直线度,这是齿轮平稳啮合、避免异响和磨损的关键。
- 齿条安装座(Rack Holder):这是最容易出问题的部分。当齿轮驱动齿条时,会产生一个使齿条背离齿轮的趋势力(类似于“推开”的力)。如果齿条安装座刚度不足,就会发生弹性变形,导致齿轮与齿条啮合间隙变大甚至脱齿。为此,我在齿条安装座的背面(远离齿轮的一侧)增加了加强筋,并将其设计成与滑动支架牢固连接的整体结构,有效抵抗了弯曲力矩。
3. “足部”与安全设计: 足部是直接与“地面”(测试台面)接触的部分。我采用了一个巧妙的“机械保险丝”设计:足部通过一根3/16英寸的定位销(Dowel Pin)与齿条末端实现紧配合连接。当电机发生意外堵转或受到巨大冲击时(例如调试时程序错误导致高速撞向硬物),这个紧配合连接会首先滑脱或使定位销弯曲,从而保护价格更贵的齿条、齿轮和电机轴免受损坏。这是一种低成本、高可靠性的过载保护机制。
4. 限位开关的布置: 我安装了两个限位开关:
- 上限位开关:安装在齿条安装座的顶部。当滑动支架上升到最高点时,会触发此开关,防止机构“冲顶”,保护机械结构。
- 下限位开关:安装在“足部”的底部。当足部接触地面时,此开关被触发。它有两个重要作用:一是作为“零位”或“归零”传感器,二是可以用于检测跳跃周期中足部与地面的接触事件,为更复杂的控制算法提供输入。
注意:限位开关建议选择机械式滚轮杠杆型,其抗干扰能力强于光电式。安装时,确保触发杆的运动方向与齿条的运动方向有合适的角度,避免垂直撞击导致开关损坏。
3. 电子系统搭建与ODrive配置
3.1 ODrive S1硬件连接与初始配置
ODrive的配置是项目成功的基础,需要耐心和细致。
硬件连接:
- 电机与编码器:按照S1 M8325s套件指南,连接电机的三相线和编码器线。这里需要特别注意,MK8325s电机自带热敏电阻(两根细黑线)。必须将套件线束中的对应导线焊接至这两根线,并插入S1 IO连接器的第13(Thermistor+)和14(Thermistor-)脚。启用温度保护可以防止电机在长时间大电流下过热烧毁。
- 电源:使用一个稳定的24V-48V直流电源为ODrive供电。确保电源功率足够(峰值电流需满足电机需求),并注意电源极性。
- 与Arduino通信:ODrive通过UART(串口)与Arduino通信。需要连接ODrive的UART接口(TX, RX, GND)到Arduino的软件串口引脚(例如Pin 10为RX, Pin 11为TX)。同时,将ODrive的GND与Arduino的GND相连,共地至关重要。
软件配置(使用ODrive Tool GUI):
- 通过USB将ODrive连接至电脑,运行ODrive Tool。
- 电机配置:在
Motor选项卡中,设置电机类型(MOTOR_TYPE_HIGH_CURRENT)、极对数(对于MK8325s,通常是7对极)、电阻和电感(可从电机手册或使用ODrive的测量功能获取)。 - 编码器配置:在
Encoder选项卡中,配置为ENCODER_MODE_HALL(如果使用霍尔传感器)或ENCODER_MODE_INCREMENTAL(如果使用ABI编码器)。运行编码器偏移校准。 - 控制器配置:在
Controller选项卡中,设置位置环、速度环、电流环的PID增益。初期可以使用默认值,后续根据实际响应调整。带宽(Bandwidth)参数很关键,它决定了系统响应速度,设置过高容易震荡,过低则响应迟钝。对于跳跃这种动态运动,需要较高的带宽。 - 接口使能:最关键的一步,在
Interfaces选项卡中,务必勾选UART。只有这样,Arduino才能通过串口命令控制ODrive。
3.2 Arduino与限位开关集成
Arduino作为上位机,负责逻辑控制和与ODrive的通信。
电路连接:
- 限位开关通常有三根线:COM(公共端)、NO(常开)、NC(常闭)。我使用常开(NO)模式。将开关的COM端接Arduino的5V,NO端接Arduino的数字输入引脚(如Pin 7),并在该引脚与GND之间连接一个10kΩ的下拉电阻。这样,开关未触发时,引脚被拉低(LOW);触发时,引脚被高电平(HIGH)。
- 将两个限位开关分别连接到两个数字引脚。
代码库准备: 在Arduino IDE中,安装两个库:
- ODriveArduino库:用于通过UART与ODrive通信,发送位置、速度等指令。
- ezButton库:这个库简化了按钮(包括限位开关)的读取,内置了去抖动功能,非常实用。
布线整理:由于整个机构是运动的,我将Arduino Uno用双面泡沫胶固定在滑动支架的背面,并用扎带将所有线缆捆扎整齐,固定在铝型材上。这样做避免了线缆在运动中被拉扯、缠绕或磨损,是保证长期可靠运行的重要细节。
4. 控制逻辑与跳跃序列实现
4.1 建立绝对位置参考系(Homing Sequence)
在开环控制中,电机只知道它相对于上电初始位置转了多少角度。但对于“跳跃腿”来说,我们需要知道齿条的绝对物理位置,比如哪里是最高点,哪里是地面。这就是“归零”或“寻零”序列的目的。
ODrive支持设置“自定义用户参考系”。基本思路是:让电机缓慢向一个方向(如下降方向)运动,直到触发下限位开关(足部触地)。将这个触发点的位置定义为坐标零点(position = 0)。然后,让电机向反方向运动一段安全距离,脱离限位开关。
在ODrive Tool中配置时,需要设置axis.config.startup_encoder_offset_calibration为False,并配置axis.config.absolute_offset来实现。更简单的方法是通过Arduino代码实现软件归零,这也是我采用的方法:
- 状态0(归零状态):电机以较低速度向“下”运动。
- 持续检查下限位开关状态。
- 一旦开关被触发,立即让电机停止,并在ODrive中执行
odrive.SetPosition(0),将此位置设为绝对零点。 - 然后,电机以低速向“上”运动一小段距离(例如5mm),使足部离开地面,开关复位。此时,系统就知道了地面的位置(Z=0)。
实操心得:归零速度一定要慢,建议在0.05 m/s以下。速度太快会导致机构以较大动能撞击限位开关或地面,产生噪音、磨损,甚至因过冲导致定位不准。归零操作应在每次系统上电后执行一次,以确保坐标系一致。
4.2 实现基础跳跃运动
跳跃的本质是让足部快速蹬地,使整体机构获得向上的加速度。在我们的系统中,就是控制齿条快速向下运动(蹬地),然后收回。
我通过一个简单的状态机来实现这个逻辑:
- STATE 0: 归零序列(如上所述)。
- STATE 1: 上升至预设高度。归零完成后,自动进入此状态。电机运动到一个预设的安全高度位置(例如
position = 0.1m),这个位置应确保足部完全离地,并低于上限位开关。 - STATE 2: 跳跃循环。在此状态下,程序在两个位置间往复运动:
- 从高处(
position_high)快速运动至地面附近(position_low,略高于0点,如0.005m)。这个阶段模拟“下蹲蓄力”和“蹬地”。 - 在
position_low点不停止,立即以最大加速度反向,快速冲向position_high。这个从low到high的急速上升阶段,就是模拟“蹬地发力”过程。 - 到达
position_high后,短暂停留(delay_high),然后再次下降,开始下一个循环。
- 从高处(
关键参数调试:
position_low:越接近0(地面),蹬地越充分,但太近可能实际触地,产生冲击。需微调。position_high:决定“下蹲”深度。影响蹬地行程和力量。- 从
high到low的速度曲线:可以使用梯形速度规划,下降段可以较快。 - 从
low到high的加速度和最大速度:这是产生“跳跃感”的核心。需要将ODrive控制器的速度环和位置环带宽调高,并设置较高的电流限值,让电机能爆发出最大扭矩,实现急速反向冲刺。在代码中,就是设置一个非常大的odrive.SetVelocity()目标值,让电机以最大能力加速。 delay_high:在最高点的停留时间。如果停留时间足够长,机构会在重力作用下有下落趋势,当再次快速下降蹬地时,会与下落的趋势叠加,产生更好的效果。我通过调整这个延时,观察到了足部轻微离地的现象。
// 伪代码逻辑示例 switch(state) { case 2: // 跳跃循环 // 快速下降至低位(蹬地准备) odrive.SetPosition(position_low); waitUntilPositionReached(); // 立即急速上升至高位(蹬地发力) odrive.SetVelocity(very_high_speed); // 设置为一个很大的负值(根据方向定义) delay(short_pulse_time); // 给一个极短的脉冲时间 odrive.SetVelocity(0); // 停止速度指令,让位置环接手稳定在高位 waitUntilPositionReached(position_high); delay(delay_high); // 在高位停留 break; }4.3 利用限位开关增强鲁棒性
最初的跳跃循环是开环的,假设地面高度不变。但在真实跳跃中,地面是参考系。我们可以用下限位开关来使系统适应性强。
改进思路:在STATE 2的循环中,将“下降至低位”这一步,改为“下降直到触发下限位开关”。一旦开关触发,立即记录此时刻,并瞬间切换到全力向上冲刺状态。这样,无论机构的初始高度如何,或者地面是否有微小不平,每次蹬地的起始点都是实际的地面接触点,更加可靠。这需要将限位开关的中断功能与高速运动指令紧密配合,对代码的实时性要求较高。
5. 调试经验、常见问题与优化方向
5.1 机械装配与调试陷阱
齿条齿轮啮合异响或卡滞:
- 问题:运动时噪音大,或有周期性顿挫感。
- 排查:首先检查齿条各段连接处是否平直,齿距是否均匀。用手推动齿条,感觉是否有紧涩点。检查齿轮轴与电机轴是否完全同心,不同心会导致啮合间隙周期性变化。
- 解决:调整齿条安装座与滑动支架的连接螺丝,微调齿条的角度。在齿条背面与安装座之间垫薄片(如铝箔胶带)进行“铲背”调整。确保齿轮与齿条的齿隙适中,通常留0.1-0.2mm的侧隙,可通过千分表测量。
滑动支架阻力大或晃动:
- 问题:电机负载重,或齿条运动时左右摇摆。
- 排查:检查3D打印的滑动支架内壁是否光滑,有无打印瘤阻碍。检查与铝型材的间隙。
- 解决:对支架内壁进行打磨。如果间隙过大导致晃动,可以在铝型材的摩擦面粘贴特氟龙胶带或安装直线轴承衬套,既能减小间隙又能降低摩擦。
“机械保险丝”过松或过紧:
- 问题:足部在正常运动时就脱落,或者该脱落时却不脱落,导致传动部件受损。
- 解决:定位销与孔的配合是紧配合(Press Fit)。可以通过尝试不同直径的销钉,或轻微扩孔/缩孔(用砂纸打磨或涂抹胶水)来调整松紧度。理想的松紧度是:用手无法轻易拔下,但用工具(如钳子垫布)可以施加中等力度取下。
5.2 电气与控制调试问题
ODrive报错(如Axis Error):
- 问题:上电或运行时,ODrive Tool显示错误,电机不转。
- 常见原因:
- 供电不足:电机启动或换向时电流陡增,导致电源电压被拉低,触发欠压保护。检查电源额定电流是否足够(MK8325s峰值电流可达数十安培),电源线是否够粗。
- 编码器接线错误:霍尔线序或ABI编码器线接反,导致ODrive无法识别电机位置。
- PID增益不当:增益太高会引起振荡,触发过流或跟踪误差过大保护。
- 解决:逐一检查。从低电流限值、低增益开始测试。使用ODrive Tool的“电机校准”和“编码器校准”向导。
跳跃动作无力,没有“爆发感”:
- 问题:机构只是缓慢地上下运动,没有快速蹬地的效果。
- 排查:
- ODrive电流/扭矩限值:检查
axis.config.motor.current_lim和axis.config.controller.torque_lim是否设置得足够高。跳跃需要瞬间大扭矩。 - 速度/加速度限制:检查
axis.config.controller.vel_limit和axis.config.controller.accel_limit是否过低。 - 电源输出能力:用万用表监控电机发力瞬间的电源电压。如果电压骤降,说明电源或导线无法提供瞬时大电流。
- 机械阻力:如前述,机械装配太紧会消耗大量扭矩。
- ODrive电流/扭矩限值:检查
- 解决:在机械顺滑的前提下,逐步提高ODrive的电流和扭矩限值,同时观察电机和驱动器温度。确保使用响应快、输出能力强的开关电源。
限位开关误触发或不触发:
- 问题:机构未到位就触发,或到位了不触发。
- 排查:检查开关安装是否牢固,触发杠杆是否被其他部件意外碰到。用Arduino串口监视器实时打印开关引脚的电平状态,观察其是否稳定。
- 解决:确保开关触发方向正确。在代码中增加去抖动延时(
ezButton库已处理)。对于关键的安全限位(如上限位),可以采用“双开关串联”的冗余设计以提高可靠性。
5.3 未来优化方向
- 引入力/力矩传感器:目前是纯位置控制。在足部安装一个单轴力传感器,可以测量蹬地力。结合力控算法(如阻抗控制),可以实现更柔顺的触地、更高效的起跳,甚至实现主动缓冲。
- 实现真正的动态跳跃:当前方案更多是“快速往复运动”,离真正的动态连续跳跃还有距离。下一步可以尝试在STATE 2中,当足部离地后(可通过惯性测量单元IMU或视觉判断),让电机在机构空中阶段快速回位,为下一次触地做准备,形成连贯的跳跃周期。
- 多腿协同与平衡:将单腿扩展为双足或四足。需要研究步态规划,并解决多ODrive之间的同步通信问题(如使用CAN总线)。
- 能量回收:在足部下落阶段,电机处于发电状态。可以探索让ODrive将再生制动产生的能量回馈到电源总线,提高系统能效。
- 更先进的轨迹规划:用正弦波、多项式或优化算法生成更符合跳跃动力学的电机位置/速度轨迹,而不是简单的两点移动,以期获得更优的跳跃高度和能量效率。
这个无弹簧跳跃腿项目,从一个反常规的想法开始,贯穿了机械设计、电子工程和软件控制的完整流程。它深刻地展示了,通过精密的现代运动控制技术,我们可以用“硬”传动和“软”算法,模拟甚至超越传统弹性元件才能实现的功能。调试过程中遇到的每一个机械异响、每一次电机报错、对跳跃效果每一分毫的调整,都是对系统理解的加深。