永磁同步电机七段式s曲线
- 一、前言
- 二、理论分析
- 三、7段式s曲线加减速关系图
- 四、matlab代码
- 代码结果
- 五、simulink七段式s曲线
- 整体框图
- simulink结果
- s-function内嵌代码
- 六、使用双闭环FOC控制-----simulink仿真示意
一、前言
S形:加加速(T1)→>匀加速(T2)→减加速(T3)→>匀速(T4 )>加减速(T5)>匀减速(T6)-→>减减速(T7)
二、理论分析
1、这个是7阶段的加速度
加速度是𝑎max,J是加加速度,𝜏𝑘(𝑘 = 1,2,… ,7)是每个区间时间坐标,𝑡𝑘(k = 0,1,2… ,7)是每区间转折点时刻,𝑇𝑘(𝑘 = 1,2,…. ,7)是每个区间的连续工作时间;
2、这个是7阶段的速度
3、这个是7阶段的位置
三、7段式s曲线加减速关系图
四、matlab代码
% 定义参数
q0 = 0;
q1 = 200;
vmax =15;
amax = 10;
v0 = 0;
v1 = 0;
jmax = 10;
count = 0;
% 计算Ta、Td、Tj1、Tj2、Tv、alima、alimd等参数,他们就是时间点
if (vmax - v0) * jmax < amax^2
if v0 > vmax
Tj1 = 0;
Ta = 0;
alima = 0;
else
Tj1 = ((vmax - v0) / jmax)^0.5;
Ta = 2 * Tj1;
alima = Tj1 * jmax;
end
else
Tj1 = amax / jmax;
Ta = Tj1 + (vmax - v0) / amax;
alima = amax;
end
if (vmax - v1) * jmax < amax^2
Tj2 = ((vmax - v1) / jmax)^0.5;
Td = 2 * Tj2;
alimd = Tj2 * jmax;
else
Tj2 = amax / jmax;
Td = Tj2 + (vmax - v1) / amax;
alimd = amax;
end
Tv = (q1 - q0) / vmax - Ta / 2 * (1 + v0 / vmax) - Td / 2 * (1 + v1 / vmax);
% 动态调整参数,确保轨迹满足条件
if Tv <= 0
Tv = 0;
amax_org = amax;
while Ta < 2 * Tj1 || Td < 2 * Tj2
count = count + 1;
amax = amax - amax_org * 0.1;
alima = amax;
alimd = amax;
delta = (amax^4) / (jmax^2) + 2 * (v0^2 + v1^2) + amax * (4 * (q1 - q0) - 2 * amax / jmax * (v0 + v1));
Tj1 = amax / jmax;
Ta = (amax^2 / jmax - 2 * v0 + delta^0.5) / (2 * amax);
Tj2 = amax / jmax;
Td = (amax^2 / jmax - 2 * v1 + delta^0.5) / (2 * amax);
end
end
% 计算轨迹
p = [];
vc = [];
ac = [];
jc = [];
if Tv > 0
vlim = vmax;
T = Tv + Ta + Td;
else
Tv = 0;
vlim = v0 + (Ta - Tj1) * alima;
T = Tv + Ta + Td;
end
for t = 0:0.1:T
if t >= 0 && t < Tj1
% 段1:加加速度段
q = q0 + v0 * t + jmax * t^3 / 6;
p = [p q];
v = v0 + jmax * t^2 / 2;
vc = [vc v];
a = jmax * t;
ac = [ac a];
jc = [jc jmax];
elseif t >= Tj1 && t < (Ta - Tj1)
% 段2:匀加速度段
q = q0 + v0 * t + alima / 6 * (3 * t^2 - 3 * Tj1 * t + Tj1^2);
p = [p q];
v = v0 + alima * (t - Tj1 / 2);
vc = [vc v];
a = alima;
ac = [ac a];
jc = [jc 0];
elseif t >= (Ta - Tj1) && t < Ta
% 段3:减加速度段
q = q0 + (vlim + v0) * Ta / 2 - vlim * (Ta - t) + jmax * (Ta - t)^3 / 6;
p = [p q];
v = vlim - jmax * (Ta - t)^2 / 2;
vc = [vc v];
a = jmax * (Ta - t);
ac = [ac a];
jc = [jc -jmax];
elseif t >= Ta && t < (Ta + Tv)
% 段4:匀速段
q = q0 + (vlim + v0) * Ta / 2 + vlim * (t - Ta);
p = [p q];
v = vlim;
vc = [vc v];
a = 0;
ac = [ac 0];
jc = [jc 0];
elseif t >= (T - Td) && t < (T - Td + Tj2)
% 段5:加减速度段
q = q1 - (vlim + v1) * Td / 2 + vlim * (t - T + Td) - jmax * (t - T + Td)^3 / 6;
p = [p q];
v = vlim - jmax * (t - T + Td)^2 / 2;
vc = [vc v];
a = -jmax * (t - T + Td);
ac = [ac a];
jc = [jc -jmax];
elseif t >= (T - Td + Tj2) && t < (T - Tj2)
% 段6:匀减速度段
q = q1 - (vlim + v1) * Td / 2 + vlim * (t - T + Td) - alimd / 6 * (3 * (t - T + Td)^2 - 3 * Tj2 * (t - T + Td) + Tj2^2);
p = [p q];
v = vlim - alimd * (t - T + Td - Tj2 / 2);
vc = [vc v];
a = -alimd;
ac = [ac a];
jc = [jc 0];
elseif t >= (T - Tj2) && t < T
% 段7:减减速度段
q = q1 - v1 * (T - t) - jmax * (T - t)^3 / 6;
p = [p q];
v = v1 + jmax * (T - t)^2 / 2;
vc = [vc v];
a = -jmax * (T - t);
ac = [ac a];
jc = [jc jmax];
end
end
% 绘制位置曲线
subplot(4, 1, 1);
plot(0:0.1:T, p, 'LineWidth', 2);
xlabel('时间 (秒)');
ylabel('位置');
title('位置随时间变化');
% 绘制速度曲线
subplot(4, 1, 2);
plot(0:0.1:T, vc, 'LineWidth', 2);
xlabel('时间 (秒)');
ylabel('速度');
title('速度随时间变化');
% 绘制加速度曲线
subplot(4, 1, 3);
plot(0:0.1:T, ac, 'LineWidth', 2);
xlabel('时间 (秒)');
ylabel('加速度');
title('加速度随时间变化');
% 绘制加加速度曲线
subplot(4, 1, 4);
plot(0:0.1:T, jc, 'LineWidth', 2);
xlabel('时间 (秒)');
ylabel('加加速度');
title('加加速度随时间变化');
代码结果
五、simulink七段式s曲线
有小伙伴想在永磁同步电机或者其他电机的simulink仿真上使用,所以我在此修改,得到下面的结果。
整体框图
simulink结果
从0到400rpm,在从400rpm到0
s-function内嵌代码
有一个事情非常重要
最大加速度和最大加加速度越大,目标位置越小,可以使采样时间变小
这就说明你想关注 最大速度和采样时间就得注意这一点,增大或者减小最大速度就得变其他两个,而采样时间是使你的simulink仿真时间变短
下面这个函数名字是fun,所以你的simulink中s-function的名字也要设置一致
function [sys,x0,str,ts,simStateCompliance] = fun(t,x,u,flag)
switch flag,
case 0,
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
case 1,
sys=mdlDerivatives(t,x,u);
case 2,
sys=mdlUpdate(t,x,u);
case 3,
sys=mdlOutputs(t,x,u);
case 4,
sys=mdlGetTimeOfNextVarHit(t,x,u);
case 9,
sys=mdlTerminate(t,x,u);
otherwise
DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
end
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 1;
sizes.NumInputs = 1;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
x0 = [];
str = [];
ts = [0 0];
simStateCompliance = 'UnknownSimState';
function sys=mdlDerivatives(t,x,u)
sys = [];
function sys=mdlUpdate(t,x,u)
sys = [];
function sys=mdlOutputs(t,x,u)
% 定义参数
q0 = 0; % 初始位置
q1 = 500; % 目标位置
vmax = 400; % 最大速度
amax = 5000; % 最大加速度
v0 = 0; % 初始速度
v1 = 0; % 最终速度
jmax = 5000; % 最大加加速度
count = 0; % 计数器
%% 最大加速度越大,目标位置越小,可以使采样时间变小
%%
% 计算Ta、Td、Tj1、Tj2、Tv、alima、alimd等参数
if (vmax - v0) * jmax < amax^2
if v0 > vmax
Tj1 = 0;
Ta = 0;
alima = 0;
else
Tj1 = ((vmax - v0) / jmax)^0.5;
Ta = 2 * Tj1;
alima = Tj1 * jmax;
end
else
Tj1 = amax / jmax;
Ta = Tj1 + (vmax - v0) / amax;
alima = amax;
end
if (vmax - v1) * jmax < amax^2
Tj2 = ((vmax - v1) / jmax)^0.5;
Td = 2 * Tj2;
alimd = Tj2 * jmax;
else
Tj2 = amax / jmax;
Td = Tj2 + (vmax - v1) / amax;
alimd = amax;
end
Tv = (q1 - q0) / vmax - Ta / 2 * (1 + v0 / vmax) - Td / 2 * (1 + v1 / vmax);
% 动态调整参数,确保轨迹满足条件
if Tv <= 0
Tv = 0;
amax_org = amax;
while Ta < 2 * Tj1 || Td < 2 * Tj2
count = count + 1;
amax = amax - amax_org * 0.1;
alima = amax;
alimd = amax;
delta = (amax^4) / (jmax^2) + 2 * (v0^2 + v1^2) + amax * (4 * (q1 - q0) - 2 * amax / jmax * (v0 + v1));
Tj1 = amax / jmax;
Ta = (amax^2 / jmax - 2 * v0 + delta^0.5) / (2 * amax);
Tj2 = amax / jmax;
Td = (amax^2 / jmax - 2 * v1 + delta^0.5) / (2 * amax);
end
end
% 计算轨迹
p = []; % 位置数据
vc = []; % 速度数据
ac = []; % 加速度数据
jc = []; % 加加速度数据
if Tv > 0
vlim = vmax;
T = Tv + Ta + Td;
else
Tv = 0;
vlim = v0 + (Ta - Tj1) * alima;
T = Tv + Ta + Td;
end
if u >= 0 && u < Tj1
% 段1:加加速度段
sys = v0 + jmax * u^2 / 2;
elseif u >= Tj1 && u < (Ta - Tj1)
% 段2:匀加速度段
sys = v0 + alima * (u - Tj1 / 2);
elseif u >= (Ta - Tj1) && u < Ta
% 段3:减加速度段
sys = vlim - jmax * (Ta - u)^2 / 2;
elseif u >= Ta && u < (Ta + Tv)
% 段4:匀速段
sys = vlim;
elseif u >= (T - Td) && u < (T - Td + Tj2)
% 段5:加减速度段
sys = vlim - jmax * (u - T + Td)^2 / 2;
elseif u >= (T - Td + Tj2) && u < (T - Tj2)
% 段6:匀减速度段
sys = vlim - alimd * (u - T + Td - Tj2 / 2);
elseif u >= (T - Tj2) && u < T
% 段7:减减速度段
sys = v1 + jmax * (T - u)^2 / 2;
else
sys = 1;
end
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];
六、使用双闭环FOC控制-----simulink仿真示意
输出得到转速图,如下所示: