采用梯形速度规划生成S形速度规划曲线(附代码)

本文介绍了一种将梯形速度规划转换为更平滑的S形速度曲线的方法,通过卷积平滑和滑动平滑滤波实现,适用于工业自动化控制,提升运动控制精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题描述

  梯形速度规划是最快也是最简单的速度规划方法。由于其速度连续但不平滑,加速度可控但会跳变,加加速度不可控,通常会引起受控对象震动,控制效果较差。S形速度规划由于其速度连续且平滑,加速度可控且连续,加加速度可控,控制效果好,广泛用于工业现场。但是,S形速度规划算法较复杂,在某些条件下,需要迭代计算进行规划,计算时间稍长。那么,有没有这样的方法:采用简单的梯形速度规划方法得到位置曲线,再通过一些方法,生成平滑的S形位置曲线?有的!本文提供了两种方法,效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、MATLAB代码

  计算两列数据的卷积:

%{
Function: my_conv
Description: 计算两列数据的卷积
Input: 数据列u,数据列v
Output: 数据列w
Author: Marc Pony(marc_pony@163.com)
Date: 2020.04.06
%}
function w = my_conv(u, v)
m = length(u);
n = length(v);
count = m + n - 1;
w = zeros(count, 1);
for k = 1 : count
    w(k) = 0.0;
    startIndex = max([1, k - n + 1]);
    endIndex = min([k, m]);
    for j = startIndex : endIndex
        w(k) = w(k) + u(j) * v(k - j + 1);
    end
end
end

  梯形速度规划:

%{
Function: trapezoidal_velocity_planning
Description: 梯形速度规划
Input: 运动参数motionParams
Output: 规划好了的运动参数motionParams,状态变量sta(1表示成功,0表示失败)
Author: Marc Pony(marc_pony@163.com)
Date: 2020.04.06
%}
function [motionParams, sta] = trapezoidal_velocity_planning(motionParams)
sta = 1;
if (motionParams.vs < motionParams.ve)
    if (motionParams.L + eps < (motionParams.ve * motionParams.ve - motionParams.vs * motionParams.vs) / (2.0 * motionParams.acc))
        sta = 0;
        return;
    end
elseif (motionParams.vs > motionParams.ve)
    if (motionParams.L + eps < (motionParams.vs * motionParams.vs - motionParams.ve * motionParams.ve) / (2.0 * motionParams.dec))
        sta = 0;
        return;
    end
else
    %to do nothing
end

motionParams.vm = sqrt((2.0 * motionParams.acc * motionParams.dec * motionParams.L + motionParams.dec * motionParams.vs * motionParams.vs + motionParams.acc * motionParams.ve * motionParams.ve) / (motionParams.acc + motionParams.dec));
if (motionParams.vm > motionParams.vc)
    motionParams.vm = motionParams.vc;
end

motionParams.T1 = (motionParams.vm - motionParams.vs) / motionParams.acc;
motionParams.T3 = (motionParams.vm - motionParams.ve) / motionParams.dec;

motionParams.L1 = 0.5 * (motionParams.vm + motionParams.vs) * motionParams.T1;
motionParams.L3 = 0.5 * (motionParams.vm + motionParams.ve) * motionParams.T3;
motionParams.L2 = motionParams.L - motionParams.L1 - motionParams.L3;
motionParams.T2 = motionParams.L2 / motionParams.vm;

motionParams.t1 = motionParams.T1;
motionParams.t2 = motionParams.t1 + motionParams.T2;
motionParams.t3 = motionParams.t2 + motionParams.T3;
motionParams.totalT = motionParams.t3;

motionParams.s1 = motionParams.L1;
motionParams.s2 = motionParams.s1 + motionParams.L2;
motionParams.s3 = motionParams.s2 + motionParams.L3;
end

  梯形速度规划的主轴插补:

%{
Function: main_axis_interpolation_for_trapezoidal_velocity
Description: 梯形速度规划的主轴插补
Input: 已经规划好了的运动参数motionParams
Output: 主轴位置pos(mm)、主轴速度vel(mm/s)、主轴加速度acc(mm/s^2)
Author: Marc Pony(marc_pony@163.com)
Date: 2020.04.06
%}
function [pos, vel, acc] = main_axis_interpolation_for_trapezoidal_velocity(motionParams)
if (motionParams.t < motionParams.t1)
    pos = motionParams.vs * motionParams.t + 0.5 * motionParams.acc * motionParams.t * motionParams.t;
    vel = motionParams.vs + motionParams.acc * motionParams.t;
    acc = motionParams.acc;
elseif (motionParams.t < motionParams.t2)
    pos = motionParams.L1 + (motionParams.t - motionParams.t1) * motionParams.vm;
    vel = motionParams.vm;
    acc = 0.0;
elseif (motionParams.t < motionParams.t3)
    pos = motionParams.L1 + motionParams.L2 + motionParams.vm * (motionParams.t - motionParams.t2) - 0.5 * motionParams.dec * (motionParams.t - motionParams.t2) * (motionParams.t - motionParams.t2);
    vel = motionParams.vm - motionParams.dec *(motionParams.t - motionParams.t2);
    acc = -motionParams.dec;
else
    motionParams.t = motionParams.totalT;
    pos = motionParams.L;
    vel = motionParams.ve;
    acc = -motionParams.dec;
end

end

  采用梯形速度规划生成S形速度曲线(卷积平滑方法和滑动平滑滤波方法):

clc;
clear;
close all;

%% 输入参数
motionParams = struct();
motionParams.dt = 0.001;  %s
motionParams.L = 100;     %mm
motionParams.vs = 0;      %mm/s
motionParams.ve = 0;      %mm/s
motionParams.vc = 100;    %mm/s
motionParams.acc = 1000;  %mm/s^2
motionParams.dec = 1500;  %mm/s^2
smoothFactor = 50; %平滑因子,用于衡量加加速度,非负整数,时间增加smoothFactor*插补周期

%% 梯形速度规划
[motionParams, sta] = trapezoidal_velocity_planning(motionParams);
if sta == 0
    error('当前运动参数下无法规划!');
end

%% 梯形速度插补
count = ceil(motionParams.totalT / motionParams.dt) + 1;
time = zeros(count, 1);
pos = zeros(count, 1);
vel = zeros(count, 1);
acc = zeros(count, 1);
vel(1) = motionParams.vs;
acc(1) = motionParams.acc;
motionParams.t = 0.0;
for i = 2 : count
    motionParams.t = motionParams.t + motionParams.dt;
    [pos(i), vel(i), acc(i)] = main_axis_interpolation_for_trapezoidal_velocity(motionParams);
    time(i) = motionParams.t;
end

%% 方法1:卷积平滑
newPos1 = [pos ; ones(smoothFactor, 1) * pos(end)];
temp = ones(smoothFactor, 1) / smoothFactor;
smoothNewPos1 = my_conv(newPos1, temp);
smoothNewPos1 = smoothNewPos1(1 : length(newPos1));
smoothNewVel1 = diff(smoothNewPos1) / motionParams.dt;
smoothNewAcc1 = diff(smoothNewVel1) / motionParams.dt;

%% 方法2:滑动平滑滤波
newPos2 = [ones(smoothFactor, 1) * pos(1); pos; ones(smoothFactor, 1) * pos(end)];
count = length(pos) + smoothFactor;
smoothNewPos2 = zeros(count, 1);
for i = 1 : count
    smoothNewPos2(i) = mean(newPos2(i : i + smoothFactor));
end
smoothNewVel2 = diff(smoothNewPos2) / motionParams.dt;
smoothNewAcc2 = diff(smoothNewVel2) / motionParams.dt;

%% 绘图验证结果
figure(1);
plot(pos, 'r');
hold on
plot(smoothNewPos1, 'g--');
plot(smoothNewPos2, 'b:');
legend('梯形速度规划', '卷积平滑', '滑动平滑滤波')
grid;
title('位置曲线 [mm]');

figure(2);
plot(vel, 'r');
hold on
plot(smoothNewVel1, 'g--');
plot(smoothNewVel2, 'b:');
legend('梯形速度规划', '卷积平滑', '滑动平滑滤波')
grid;
title('速度曲线 [mm/sec]');

figure(3);
plot(acc, 'r');
hold on
plot(smoothNewAcc1, 'g--');
plot(smoothNewAcc2, 'b:');
legend('梯形速度规划', '卷积平滑', '滑动平滑滤波')
grid;
title('加速度曲线 [mm/sec^2]');

三、总结

  采用梯形速度规划,采用卷积平滑方法和滑动平滑滤波方法均可以很容易生成S形速度曲线。卷积平滑方法不适用于在线插补,滑动平滑滤波方法则适用。两种方法有个缺点是:不适用于起始速度vs和结束速度ve不为0的情况。

<think>好的,我现在需要比较速度规划与PID控制的差异和应用场景。首先,我得弄清楚这两个概念各自的定义和基本原理。速度规划,听起来像是预先规划系统的速度变化曲线,可能用在需要精确控制运动轨迹的场景,比如机械臂或数控机床。而PID控制是一种反馈控制方法,通过比例、积分、微分三个环节来调整系统输出,使其接近设定值。常见于需要实时调节的场合,比如恒温控制或者电机转速控制。接下来,我应该从它们的原理入手,分析它们的区别。速度规划可能更注重前馈控制,提前生成理想的速度曲线,系统按照这个规划执行。而PID是反馈控制,根据当前的误差进行调整,属于闭环控制。这可能导致响应速度和抗干扰能力的不同。然后要考虑应用场景的不同。速度规划可能适用于运动轨迹复杂、需要高精度定位的情况,比如3D打印或者机器人路径规划。而PID控制适用于需要持续稳定维持某个状态的系统,比如无人机的高度保持或者汽车的巡航控制。还需要比较它们的优缺点。速度规划可能在规划不当的情况下导致系统响应不灵活,而PID的参数整定如果不好,可能会引起振荡或响应慢。另外,速度规划可能需要更多的计算资源来生成和调整轨迹,而PID计算量相对较小,实时性更好。 用户可能还想知道两者是否可以结合使用。比如在机器人控制中,先用速度规划生成理想轨迹,再用PID控制来实时调整,消除误差。这种组合可能会提升整体性能。最后,要确保回答结构清晰,分点说明区别和应用场景,并给出实际例子帮助理解。同时,检查是否有遗漏的关键点,比如动态响应、系统复杂度、抗干扰能力等。可能还需要提到一些数学公式,比如PID的控制方程,或者速度规划中的插值算法,用LaTeX格式正确表示。</think>### 速度规划与PID控制的区别及应用场景对比 #### 一、基本原理差异 1. **速度规划** 速度规划通过预先生成目标速度曲线(如梯形、S曲线)控制运动过程,核心是**前馈控制**。其数学描述通常涉及时间$t$与速度$v(t)$的关系,例如S速度曲线的加速度分段函数: $$ a(t) = \begin{cases} J \cdot t & \text{加速段} \\ 0 & \text{匀速段} \\ -J \cdot t & \text{减速段} \end{cases} $$ 其中$J$为加加速度(jerk),用于平滑运动[^1]。 2. **PID控制** PID通过实时误差反馈调整输出,核心是**闭环控制**。其输出公式为: $$ u(t) = K_p e(t) + K_i \int_0^t e(\tau)d\tau + K_d \frac{de(t)}{dt} $$ 其中$K_p$、$K_i$、$K_d$分别为比例、积分、微分系数[^2]。 --- #### 二、性能特点对比 | **维度** | **速度规划** | **PID控制** | |----------------|---------------------------------------|--------------------------------------| | 动态响应 | 依赖预计算,响应延迟低 | 依赖实时误差,响应速度中等 | | 抗干扰能力 | 弱(无闭环修正) | 强(闭环自动调节) | | 计算复杂度 | 高(需轨迹插值、参数优化) | 低(仅需误差计算) | | 适用场景 | 轨迹精度要求高的开环系统 | 需稳定输出的闭环系统 | --- #### 三、典应用场景 1. **速度规划** - **数控机床加工**:需严格遵循预设速度曲线避免机械冲击 - **3D打印路径控制**:保证打印头匀速运动提升表面质量 - **机械臂轨迹跟踪**:通过S曲线规划实现平滑启停[^3] 2. **PID控制** - **电机转速调节**:通过编码器反馈实时调整PWM占空比 - **恒温控制系统**:根据温度偏差动态调节加热功率 - **无人机悬停控制**:结合姿态传感器实现位置微调[^4] --- #### 四、融合应用案例 在**工业机器人**中,常采用**混合控制架构**: 1. 上层用速度规划生成理想轨迹 2. 下层用PID实现关节力矩闭环控制 3. 通过前馈补偿(如摩擦力模)提升跟踪精度[^5] 例如机械臂抓取作业时: ```python # 伪代码示例 trajectory = generate_s_curve(start, end) # 速度规划层 while not reach_end: target_vel = trajectory.get_current_vel() actual_vel = encoder.read() pid_output = pid.update(target_vel - actual_vel) # PID控制层 motor.set_speed(pid_output) ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值