ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

梯形速度曲线全解析:从原理公式到MCU实现与调参技巧

梯形速度曲线全解析:从原理公式到MCU实现与调参技巧 1. 为什么电机控制绕不开“速度曲线”这道坎做运动控制、机器人、CNC、自动化设备的朋友对“速度曲线规划”这个词肯定不陌生。简单说它解决的是这样一个问题电机从一个位置A运动到位置B中间这段路怎么走速度怎么变才能在“快、准、稳”三者之间找到平衡点。如果不做任何规划直接给电机发一个阶跃速度指令比如让它瞬间从0转到3000转电机会怎样轻则丢步、过冲重则机构振动、撞击限位甚至烧毁驱动器。因为机械系统有惯性电气系统有响应延迟物理世界不允许速度突变。这就好比开车你不可能一脚把车速从0踩到120轮胎会打滑人也受不了那个加速度。梯形速度曲线是最基础、最常用的一种速度规划方案。它的速度-时间图像像一个等腰梯形加速段、匀速段、减速段。名字很直白形状也直观但真正把它用明白里面涉及的参数计算、边界判断、离散化实现、加速度不连续带来的冲击问题每一个细节都值得抠一抠。这篇文章我会把梯形速度曲线从原理到代码实现、从参数计算到实际调参经验完整拆开讲一遍。适合刚入门运动控制的工程师也适合已经写了几年规划代码但没仔细想过“为什么这么写”的老手。2. 先说清楚梯形速度曲线到底在优化什么2.1 物理约束下的“最快路径”任何运动控制系统都要先回答一个数学问题在加速度、减速度、最大速度都受限的条件下从起点到终点怎么走时间最短梯形速度曲线就是这个问题的最优解。为什么因为在匀加速、匀速、匀减速这三种运动模式下时间最短的路径只能由它们组合而成。这个结论可以从最优控制理论里的“Bang-Bang控制”推导出来当加速度受限时最优策略就是要么以最大加速度加速要么以最大减速度减速要么匀速不存在“慢慢加速”这种中间状态。把边界条件列一下最大速度 ( v_{max} )由电机额定转速、机械结构承受能力决定最大加速度 ( a_{acc} )由电机扭矩、负载惯量决定最大减速度 ( a_{dec} )通常不等于加速度因为制动能力和加速能力不一定一样尤其是竖直轴要考虑重力这三组参数就是整个规划的“天花板”。梯形曲线做的事情就是在这些约束内找一个时间最优的运动方案。2.2 三个关键参数距离、速度、加减速度实际工程中我们通常已知的是起始位置 ( q_0 )目标位置 ( q_1 )规划周期 ( T_s )比如1ms、125us然后我们要根据用户设定的 ( v_{max} )、( a_{acc} )、( a_{dec} ) 来生成一条从 ( q_0 ) 到 ( q_1 ) 的轨迹。这里有个工程上必须注意的点用户设定的 ( v_{max} ) 不一定是实际能达到的速度。如果两点之间的距离很短可能刚加速到一半就要开始减速了根本到不了 ( v_{max} )。这种时候梯形退化成了三角形——只有加速段和减速段没有匀速段。代码里必须要处理这种情况否则计算出来的匀速段时间是负数就出bug了。判断条件很简单按照设定的加速度从0加速到 ( v_{max} ) 再减速到0所需要的距离是[ s_{need} \frac{v_{max}^2}{2a_{acc}} \frac{v_{max}^2}{2a_{dec}} ]如果 ( s_{need} ) 大于实际位移距离 ( s |q_1 - q_0| )说明跑不满最大速度此时实际峰值速度要按下面的公式反算[ v_{peak} \sqrt{\frac{2s \cdot a_{acc} \cdot a_{dec}}{a_{acc} a_{dec}}} ]这个公式是梯形规划里最容易漏掉的地方。很多初写代码的人只算了正常梯形的情况没考虑短距离结果距离一短匀速段时间算成负数轨迹形态直接崩了。3. 梯形规划的完整推导从公式到代码3.1 分情况讨论完整梯形和退化三角形把情况分清楚代码就好写了。情况A能跑满最大速度完整梯形此时轨迹分成三个阶段加速段从0到 ( v_{max} )耗时 ( t_{acc} v_{max} / a_{acc} )位移 ( s_{acc} v_{max}^2 / (2a_{acc}) )匀速段以 ( v_{max} ) 运行耗时 ( t_{c} (s - s_{acc} - s_{dec}) / v_{max} )减速段从 ( v_{max} ) 到0耗时 ( t_{dec} v_{max} / a_{dec} )位移 ( s_{dec} v_{max}^2 / (2a_{dec}) )总时间[ t_{total} t_{acc} t_c t_{dec} ]情况B跑不满最大速度三角形此时只有两个阶段加速段从0到 ( v_{peak} )耗时 ( t_{acc} v_{peak} / a_{acc} )减速段从 ( v_{peak} ) 到0耗时 ( t_{dec} v_{peak} / a_{dec} )没有匀速段。( v_{peak} ) 用前面那个公式反算。3.2 规划的核心时间轴上的三个关键节点一旦知道 ( v_{peak} )、( t_{acc} )、( t_{dec} )、( t_{total} )整条轨迹就完全确定了。剩下的事情就是把它离散化。假设当前时刻为 ( t )位置为 ( q(t) )速度为 ( v(t) )那么如果 ( t t_{acc} )处于加速段[ v(t) a_{acc} \cdot t ][ q(t) q_0 \frac{1}{2} a_{acc} t^2 ]如果 ( t_{acc} \le t t_{acc} t_c )处于匀速段[ v(t) v_{peak} ][ q(t) q_0 s_{acc} v_{peak} (t - t_{acc}) ]如果 ( t \ge t_{acc} t_c )处于减速段[ v(t) v_{peak} - a_{dec} (t - t_{acc} - t_c) ][ q(t) q_0 s_{acc} v_{peak} \cdot t_c v_{peak}(t - t_{acc} - t_c) - \frac{1}{2} a_{dec} (t - t_{acc} - t_c)^2 ]代码写出来是这个样子import math class TrapezoidProfile: def __init__(self, q0, q1, v_max, a_acc, a_dec, ts): self.q0 q0 self.q1 q1 self.v_max v_max self.a_acc a_acc self.a_dec a_dec self.ts ts self.s q1 - q0 self.sign 1.0 if self.s 0 else -1.0 self.s abs(self.s) # 计算跑满最大速度所需距离 s_need (v_max * v_max) / (2.0 * a_acc) (v_max * v_max) / (2.0 * a_dec) if self.s s_need: self.v_peak v_max self.t_acc v_max / a_acc self.t_dec v_max / a_dec self.s_acc v_max * v_max / (2.0 * a_acc) self.s_dec v_max * v_max / (2.0 * a_dec) self.t_c (self.s - self.s_acc - self.s_dec) / v_max else: # 三角形跑不满最大速度 self.v_peak math.sqrt(2.0 * self.s * a_acc * a_dec / (a_acc a_dec)) self.t_acc self.v_peak / a_acc self.t_dec self.v_peak / a_dec self.s_acc self.v_peak * self.v_peak / (2.0 * a_acc) self.s_dec self.v_peak * self.v_peak / (2.0 * a_dec) self.t_c 0.0 self.t_total self.t_acc self.t_c self.t_dec self.current_t 0.0 def reset(self): self.current_t 0.0 def step(self): t self.current_t self.current_t self.ts if t 0: q self.q0 v 0.0 elif t self.t_acc: q self.q0 self.sign * (0.5 * self.a_acc * t * t) v self.sign * self.a_acc * t elif t self.t_acc self.t_c: q self.q0 self.sign * (self.s_acc self.v_peak * (t - self.t_acc)) v self.sign * self.v_peak elif t self.t_total: dt t - self.t_acc - self.t_c q self.q0 self.sign * (self.s_acc self.v_peak * self.t_c self.v_peak * dt - 0.5 * self.a_dec * dt * dt) v self.sign * (self.v_peak - self.a_dec * dt) else: q self.q1 v 0.0 return q, v3.3 为什么在轨迹末端要做“位置闭合”上面的代码里最后一个 ( else ) 分支直接把位置拉到了 ( q_1 )速度置0。这个设计有什么讲究理论上只要前面的浮点计算都精确减速段结束时刻的位置就是 ( q_1 )。但实际上浮点数有误差采样周期 ( T_s ) 也不一定能量除总时间最后一个周期的时间步长往往不是整数倍。这会导致一个结果程序运行到最后位置停在 ( q_1 ) 附近但差了一点点速度也不完全是0。如果不做闭合控制器就会拿着这个“差一点”的位置误差继续修正产生末端抖动。尤其是点位运动场景每一次都停在 ( q_1 \pm \epsilon ) 的位置累计误差就会显现出来。所以在工程实现里必须把“轨迹结束”做一次显式处理当前时间超过 ( t_{total} )位置强制等于 ( q_1 )速度强制为0规划器状态置为“完成”后续不再输出新的运动指令这段逻辑看起来简单但少了它系统稳定性会差一个档次。4. 梯形曲线的“硬伤”加速度突变4.1 为什么梯形曲线会有冲击梯形曲线虽然实现简单但它有一个天然的缺陷加速度在四个时刻点会发生跳变。具体是这四个点( t0 ) 时刻加速度从0突变到 ( a_{acc} )( tt_{acc} ) 时刻加速度从 ( a_{acc} ) 突变到0( tt_{acc}t_c ) 时刻加速度从0突变到 ( -a_{dec} )( tt_{total} ) 时刻加速度从 ( -a_{dec} ) 突变到0加速度突变意味着什么意味着力的突变。力的突变意味着机械结构会受到冲击也就是所谓的“柔性冲击”。实际设备上这是什么表现龙门架式的设备启停瞬间会“咯噔”一下皮带传动机构会有明显的顿挫感高速轻载场景下末端会振动甚至激起机械共振减速机齿轮磨损会加快拿一根悬臂梁来说你用手快速推一下它会晃动。电机动起来也一样加速度突变相当于给机械结构一个脉冲激励结构会以自己的固有频率振动起来然后慢慢衰减。这就是为什么有些设备低速走没问题一高速走就抖。4.2 S型曲线为什么能解决这个问题S型速度曲线的思路是不让加速度突变而是让加速度自身也平滑地变化。也就是说引入第三个约束——加加速度jerk也就是加速度的变化率单位是 ( m/s^3 )。S型曲线在梯形曲线的转折点处用一段斜坡把加速度的突变“抹平”。这样施加在机械结构上的力变化是连续的冲击自然就小了。但S型曲线也不是没有代价规划算法复杂得多需要解七段分段方程计算量大对控制周期短的场合比如125us增加负担参数多了调起来更麻烦所以实际工程里很多场合仍然优先用梯形曲线。比如点对点定位要求不高、速度不快的场景低速重载系统刚度大、冲击不明显的场景计算资源有限的嵌入式MCU对实时性要求极高、规划周期极短的场合一句话不是所有场景都值得上S型梯形曲线用对了地方依然是最经济的选择。这个选择逻辑后面在实战部分我会再展开讲。5. 工程实战梯形规划在MCU上的完整实现思路5.1 离散时间下的位置更新别忽略“步长”的影响在MCU上做梯形规划和Python里边仿真边看曲线完全是两种体验。嵌入式环境里我们通常用一个定时器中断按固定的控制周期执行规划器。每个周期做三件事读取当前规划时间调用规划器计算当前位置和速度把位置/速度指令发给位置环或速度环代码结构大概是这样typedef struct { float q0; float q1; float v_max; float a_acc; float a_dec; float ts; float v_peak; float t_acc; float t_dec; float t_c; float t_total; float s_acc; float s_dec; float t_current; float sign; uint8_t is_finished; } TrapezoidProfile; void trapezoid_init(TrapezoidProfile* prof, float q0, float q1, float v_max, float a_acc, float a_dec, float ts) { prof-q0 q0; prof-q1 q1; prof-v_max v_max; prof-a_acc a_acc; prof-a_dec a_dec; prof-ts ts; prof-t_current 0.0f; prof-is_finished 0; float s q1 - q0; prof-sign (s 0.0f) ? 1.0f : -1.0f; s fabsf(s); float s_need (v_max * v_max) / (2.0f * a_acc) (v_max * v_max) / (2.0f * a_dec); if (s s_need) { prof-v_peak v_max; prof-t_acc v_max / a_acc; prof-t_dec v_max / a_dec; prof-s_acc v_max * v_max / (2.0f * a_acc); prof-s_dec v_max * v_max / (2.0f * a_dec); prof-t_c (s - prof-s_acc - prof-s_dec) / v_max; } else { prof-v_peak sqrtf(2.0f * s * a_acc * a_dec / (a_acc a_dec)); prof-t_acc prof-v_peak / a_acc; prof-t_dec prof-v_peak / a_dec; prof-s_acc prof-v_peak * prof-v_peak / (2.0f * a_acc); prof-s_dec prof-v_peak * prof-v_peak / (2.0f * a_dec); prof-t_c 0.0f; } prof-t_total prof-t_acc prof-t_c prof-t_dec; } void trapezoid_plan(TrapezoidProfile* prof, float* pos_cmd, float* vel_cmd) { if (prof-is_finished) { *pos_cmd prof-q1; *vel_cmd 0.0f; return; } float t prof-t_current; prof-t_current prof-ts; float q 0.0f, v 0.0f; if (t prof-t_acc) { q 0.5f * prof-a_acc * t * t; v prof-a_acc * t; } else if (t prof-t_acc prof-t_c) { q prof-s_acc prof-v_peak * (t - prof-t_acc); v prof-v_peak; } else if (t prof-t_total) { float dt t - prof-t_acc - prof-t_c; q prof-s_acc prof-v_peak * prof-t_c prof-v_peak * dt - 0.5f * prof-a_dec * dt * dt; v prof-v_peak - prof-a_dec * dt; } else { q prof-s_acc prof-v_peak * prof-t_c prof-s_dec; v 0.0f; prof-is_finished 1; } *pos_cmd prof-q0 prof-sign * q; *vel_cmd prof-sign * v; }这里有几个工程细节值得拿出来单独讲。第一个细节单位换算。很多入行不久的同学把位置单位搞混。电机的位置有几种表示方式脉冲数、编码器计数、转数、毫米、弧度。规划器内部最好统一用一种单位推荐用“用户单位”做规划在跟驱动器交互时才做换算。比如你上位机用mm做单位那么下发位置指令时要转换成脉冲数( pulses mm \times \text{pulses_per_mm} )读反馈位置时要反向换算速度和加速度的单位也随之成套转换单位不统一是运动控制领域最常见、也最隐蔽的bug来源。因为数值上可能差了几百倍但程序不报错只在运行效果上表现出诡异的行为——比如走位忽快忽慢、距离越长误差越大。第二个细节浮点运算与定点优化。很多MCU没有硬件浮点单元FPU比如一些低成本的Cortex-M0芯片。这时候直接拿float做规划每一次乘除都要调用软件浮点库性能开销不小。解决方案有两种把加速度、速度、位置全部换成Q格式定点数比如Q24、Q16用整数运算模拟小数加高主频或换带FPU的芯片我的经验是如果控制周期在1ms以上用整数运算完全够用如果控制周期在125us左右建议直接上带FPU的MCU省下的开发调试时间远比省几块钱芯片成本值。5.2 在线修改目标位置梯形曲线规划的“中途换点”实际设备调试过程中经常遇到需要在运动过程中修改目标位置的情况。典型场景视觉定位系统发现目标偏移要求机械手中途转向新的目标点安全光幕触发机器需要立即停下或临时更改目标流水线上游来料位置变化夹具需要动态调整到位点最简单的做法是先停到当前位置再用新的目标重新规划。这个方案稳妥但损失效率。更高级的做法是“在线重规划”从当前时刻的速度 ( v_{now} )、位置 ( q_{now} ) 出发以它们作为新的初始条件重新规划到新的目标点。在线重规划的数学本质是要处理“初速度不为0”的梯形规划。这就涉及到梯形规划的另一种通用形式——带初速度的版本。假设当前速度为 ( v_0 )目标速度为 ( v_10 )距离剩余 ( s_{rem} q_{new} - q_{now} )。如果要先加速到 ( v_{max} ) 再减速那么所需距离是[ s_{need} \frac{v_{max}^2 - v_0^2}{2a_{acc}} \frac{v_{max}^2}{2a_{dec}} ]如果 ( s_{rem} s_{need} )说明到不了 ( v_{max} )需要计算一个转折速度 ( v_{turn} )它满足[ s_{rem} \frac{v_{turn}^2 - v_0^2}{2a_{acc}} \frac{v_{turn}^2}{2a_{dec}} ]解这个方程[ v_{turn} \sqrt{\frac{2a_{acc}a_{dec}s_{rem} a_{dec}v_0^2}{a_{acc} a_{dec}}} ]这个公式在在线重规划里非常关键。它要同时满足两个条件既能从 ( v_0 ) 加速到 ( v_{turn} )或直接减速又能从 ( v_{turn} ) 减速到0且总距离刚好等于 ( s_{rem} )。还要注意方向问题如果 ( v_0 ) 的方向和 ( s_{rem} ) 的方向相反说明电机动着往错误的方向跑此时要先减速到0再反向加速。这相当于把轨迹拆成两段先走一个“减速停”轨迹再走一个“从0开始”的梯形轨迹。工程上一般会直接设一个标志位让逻辑变成“先停稳再动”避免处理复杂的反向重规划。5.3 抖动抑制一个简单但有效的“末端整形”梯形曲线的末端有个物理现象减速到0的瞬间如果指令速度恰好为0但实际机械末端还在因为惯性微幅振荡那么位置环会一直试图修正表现为末端“嗡嗡”抖动。处理方法之一是在轨迹末端做“软着陆”。具体做法在距离目标点还剩最后一段距离 ( s_{land} ) 时不再按梯形曲线减速而是切换成低通滤波后的位置指令或者改用指数衰减速度曲线[ v(t) v_{enter} \cdot e^{-(t-t_{enter})/\tau} ]这里的 ( v_{enter} ) 是进入软着陆段时的速度( \tau ) 是时间常数一般取10~30ms需要根据机构刚性实测调整。软着陆的意义在于速度连续衰减且衰减速率逐渐减小不会像梯形曲线那样在结束点产生加速度阶跃。这个方法不改变梯形规划的框架只在末端加了一个整形环节实现成本很低但对末端振动的抑制效果非常明显。我在两个项目上用过这个方案一台高速贴片机的Z轴贴装前末段改用软着陆后贴装压力波动从原来的15%降到了5%以内一台桌面型三轴点胶机XY轴改成软着陆后点胶轨迹起点和终点的顿挫痕迹明显消失值得说明的是软着陆会略微增加总运动时间但通常在几十毫秒以内对节拍影响不大。如果你做的是高速高精度设备这个时间成本换来的稳定性提升完全值得。6. 调参实战加速度、速度到底怎么给6.1 先算负载惯量再定加速度很多新手拿到一台设备第一件事就是拍脑袋设加速度设大了电机报警过流设小了节拍拖慢反复试错浪费时间。实际上加速度的选择有迹可循。核心依据是牛顿第二定律的旋转形式[ T_{motor} J_{total} \cdot \alpha T_{load} ]其中( J_{total} ) 是折算到电机轴上的总惯量电机转子惯量负载折算惯量( \alpha ) 是角加速度( T_{load} ) 是负载力矩摩擦力矩、重力矩等。如果电机额定扭矩是 ( T_{rated} )那么允许的最大角加速度不能超过[ \alpha_{max} \frac{T_{rated} - T_{load}}{J_{total}} ]这个 ( \alpha_{max} ) 换算成直线加速度还要乘上丝杠导程或齿轮减速比。换句话说加速度的上限由“电机能输出的净力矩”除以“系统总惯量”决定。我见过不少现场问题都是给加速度太猛驱动器一直工作在过流保护边缘偶尔报一次过流报警线体就停一次。这种问题不是梯形规划本身的错而是参数没匹配上物理系统。建议调参步骤先测系统总惯量可以用加减速法给定恒定力矩测角加速度反推惯量算出一个理论最大加速度取理论值的50%~70%作为规划加速度留出扭矩裕量用示波器或驱动器自带监控观察实际电流如果电流接近额定值说明加速度给大了6.2 梯形规划里加速度和减速要不要分开设置答案是要而且强烈建议分开。原因很简单加速时电机输出正向力矩与运动方向相同减速时电机需要输出反向力矩。如果机械系统存在摩擦、重力等恒定的负载力矩这在竖直轴里特别明显那么加速时实际需要的力矩是 ( T_{acc} J\alpha T_{friction} T_{gravity} )减速时实际需要的力矩是 ( T_{dec} J\alpha_{dec} - T_{friction} - T_{gravity} )如果设同样的加减速度加速段可能已经接近电机峰值扭矩减速段则比较轻松。反过来在竖直下行的场景里重力会帮助加速但减速时电机要额外抵抗重力减速难度反而更大。所以稳妥的做法是先按相同值调试如果某一段出现电流过大或振动明显就把对应段的加/减速度调小。很多运动控制器包括一些国产点位控制卡都支持分开设定加减速度就是这个原因。6.3 参数整定的“黄金法则”先小后大先短后长实际操作中参数整定有个很实用的顺序法则。第一步用很小的速度比如最大速度的10%和很小的加速度比如理论最大值的20%跑一遍完整的点到点运动。确认方向正确、没有异响、没有任何报警。第二步逐步提高最大速度观察电机电流、运行声音和停止时的过冲量。正常情况速度提高后只应该看到运动时间缩短不应该看到过冲增大——如果过冲增大说明加速度跟不上加减速段实际偏短需要同时增大加速度。第三步逐步增大加速度观察启动瞬间和停止瞬间的机械振动。一旦发现“咯噔”声或末端余振就回调一点找到临界值再留20%~30%裕量。这个法则能让你在半小时内完成一台新设备的梯形规划参数确认而不是靠猜。7. 梯形曲线的一种实用变体非对称加减速7.1 为什么有时候必须用非对称前面提到竖直轴场景里重力的影响导致加减速能力不对称。再举一个常见例子皮带传输的载物台带负载前进时摩擦大返回空载时摩擦小。如果加减速度参数共用一套要么前进段力矩不够要么返回段振动明显。解决办法是定义两组参数一组用于“正方向加速/反方向减速”另一组用于“正方向减速/反方向加速”。形状上这就变成一个非对称的梯形——左边的斜率和右边的斜率不一样。实现上这改动不大只是把原来的 ( a_{acc} ) 和 ( a_{dec} ) 分别替换成两个方向的对应值。但要注意边界判断公式也要跟着换正方向运动( q_1 q_0 )加速段用 ( a_{acc_fwd} )减速段用 ( a_{dec_fwd} )反方向运动( q_1 q_0 )加速段用 ( a_{acc_rev} )减速段用 ( a_{dec_rev} )这个变量对应关系极易搞混。我的建议是在命名上就区分清楚float a_acc_fwd; // 正向运动的加速度 float a_dec_fwd; // 正向运动的减速度 float a_acc_rev; // 反向运动的加速度数值为正方向由sign处理 float a_dec_rev; // 反向运动的减速度数值为正方向由sign处理7.2 实现差异两套判断逻辑非对称的实现变化集中在初始化阶段的位置判断。核心是先把运动方向定下来再选对应的加减速度组合重新计算轨迹参数。其他阶段的计算逻辑完全一样因为公式里用的是已经选好的 ( a_{acc} ) 和 ( a_{dec} )。这个变体工程量不大但对特定设备的运行效果提升明显。尤其是竖直轴如果不用非对称参数要么往上走加速度不足显得“肉”要么往下走减速刹不住产生过冲。搞过Z轴的朋友应该深有体会。8. 如果梯形曲线已经无法满足何时换S型曲线8.1 梯形和S型的适用边界很多工程师会有个误区S型曲线一定比梯形好。实际不是这样。梯形曲线的优势是计算简单、响应快、总时间最短。在相同 ( v_{max} )、( a_{max} ) 约束下任何平滑程度更高的曲线比如S型总时间都会更长因为它们要用一部分加速度能力去平滑过渡。什么时候必须用S型末端定位精度要求极高且机械结构阻尼小的场景比如半导体贴片设备负载是易碎品或液体冲击会导致损坏或飞溅的场景丝杠、导轨间隙较大加速度突变会产生反弹的场景速度高且负载惯量大加速度突变会激发结构共振的场景什么时候用梯形就够了定位精度在0.1mm级别即可的设备机构刚性好比如重型铸铁底座的工作台运动速度低加速度本身设置得不大控制周期短、运算资源有限S型可能拖累实时性说句实在话很多中小型自动化设备梯形曲线调好了完全够用。与其急着上S型不如把梯形曲线的末端整形、加减速分段、方向区分这些细节做到位。实际效果差距并没有想象那么大。8.2 从梯形平滑改造五次多项式过渡如果你实在不想整体迁移到S型又需要降低冲击有一个折中方案用五次多项式对梯形曲线的转折点做局部过渡。思路是这样的在速度转折点附近取一个时间窗口 ( [t_1, t_2] )窗口内用五次多项式连接转折前后的速度曲线。五次多项式的好处是两端的位置、速度、加速度都可以精确匹配也就是说连接处不会有跳变。但这个方法实现起来有个麻烦需要知道前后曲线的精确表达式还要在过渡窗口内解五次多项式的系数。窗口长度选多少、在哪个位置切都要调试。代码复杂度其实比直接上S型低不了多少。所以我的建议是如果只是轻微改善冲击可以用如果目标是把振动明显降下来还是正经用S型。9. 复盘梯形速度曲线做得好不好看这几个细节写了这么多最后把梯形速度曲线规划中最容易出问题的点汇总一下。第一边界条件是否全覆盖。距离短到跑不满 ( v_{max} ) 时是否走了三角形分支初始和结束速度是否都为0加减速度是否按方向分开设置这些边界条件没处理干净程序在极端工况下就会表现异常。第二单位制是否统一。位置、速度、加速度、时间四者的单位一定要成套。最稳妥的做法是全程用标准单位m、m/s、m/s²、s做规划只在接口层做换算。千万别在规划器内部混用mm和脉冲。第三末端是否做了位置闭合。轨迹结束时位置、速度必须精确设定为目标值和0不能依赖浮点误差自然收敛。第四采样步长是否合理。采样周期 ( T_s ) 必须远小于轨迹总时间 ( t_{total} )一般要求 ( t_{total} / T_s 50 )否则离散化误差会很明显。如果你发现轨迹走完位置偏差较大先看一下是不是 ( T_s ) 太粗糙而不是急着怀疑算法本身。第五有没有给振动留裕量。理论算出来的最大加速度装到设备上至少要打七折。机械系统的实际刚度、间隙、阻尼在线性仿真里都算不出来现场实测才是准的。梯形速度曲线是一把趁手的工具但不是万能钥匙。搞懂它的原理知道每个参数的作用以及参数变化对轨迹形态的影响再结合现场实测慢慢调你基本就能驾驭大多数点位运动控制场景。等哪天遇到梯形曲线确实解决不了的问题再上S型也不迟。最后再分享一个小技巧调试阶段把规划器的位置指令、实际反馈位置、速度指令三条曲线同时录下来观察。如果位置指令和反馈位置贴合良好说明规划器工作正常问题大概率在机构或者伺服参数如果连指令本身就不平滑那就先回头检查规划器的参数和逻辑别急着动伺服增益。这个排查顺序能帮你少走不少弯路。
返回列表