假设需要将时间信息传输给一个显示器模块,可以按照以下步骤进行操作:
-
在模型中添加“Clock”模块,将其输出与MATLAB函数“simulinktime”模块进行连接。
-
在模型中添加一个Scope模块,将其输入与Clock模块的输出进行连接。
-
运行模型,Scope模块将显示当前的仿真时间。
-
将Scope模块替换为显示器模块,并将Clock模块的输出与显示器模块的输入进行连接。
-
运行模型,可以看到显示器模块实时显示当前的仿真时间。
需要注意的是,Simulink中获取时间信息的方法并不唯一,具体方法要根据实际情况选择。同时,需要确保时间信息的传输是实时的,以保证模型的准确性和稳定性。
例如:
小于1的时候满足条件,输出时间点信息;当大于1以后,不满足逻辑条件,不再变化输出值。
把计数器放进触发子系统里面,用某变量的下降沿作为触发条件,就能记录
所用到的模块:Simulink使能(Enable)、触发(Triggered)模块及其子系统
IF tauext ≠ 0,
record (仅状态发生突变的一瞬间当前时间ts)
即,从0突变到某一阈值tau0的时候记录ts,不满足该条件的不记录。
记录到ts后,可求出参考轨迹,例如sin(ts)± 0.02;(当tauext>阈值tau0时运算为正,否则为负)
如果 tauext 不等于 0,那么记录一个时间戳 ts,这个时间戳是指当 tauext 第一次从 0 突变到某个非零值时的时间。
记录到时间戳后,可以根据这个时间戳来计算参考轨迹。例如,sin(ts) ± 0.02,其中的正负号取决于 tauext 和 tau0 的大小关系。如果 tauext 大于 tau0,那么运算为正,否则为负。
关于如何在 Simulink 中实现这个功能,可以使用 Triggered Subsystem 模块来实现。将 tauext 作为输入信号,将输出信号连接到 Triggered Subsystem 模块,然后在模块内部设置触发条件为 tauext 第一次从 0 突变到非零值。在触发条件满足的时候,将当前时间戳记录下来,并计算参考轨迹输出到下游模块。
上升沿和下降沿通常是指信号的变化方向。在数字电路和信号处理中,上升沿和下降沿通常用于描述信号的变化过程。
上升沿指信号从低电平(或低电压)变为高电平(或高电压)的瞬间,下降沿指信号从高电平(或高电压)变为低电平(或低电压)的瞬间。
以下是一个信号示例,展示了上升沿和下降沿:
_______
| |
| |
_______| |_______
↑ ↓
上升沿 下降沿
其中,上升沿发生在信号从低电平变为高电平的瞬间,下降沿发生在信号从高电平变为低电平的瞬间。
-
“
上升沿
” - 当控制信号从负值或零值上升至正值时,触发子系统的执行。 -
“
下降沿
” - 当控制信号从正值或零值下降至负值时,触发子系统的执行。 -
“
任一沿
” - 通过上升或下降控制信号触发子系统的执行。
MATLAB函数实现触发上升沿和下降沿,并记录状态发生突变时的时间ts,并根据阈值tau0计算参考轨迹sin(ts)±0.02的代码:
function [ts, ref_traj] = triggered_diffusion(tauext, tau0)
% tauext: 外部输入信号
% tau0: 阈值
% ts: 记录状态发生突变时的时间
% ref_traj: 根据阈值计算的参考轨迹
persistent prev_tauext % 记录上一时刻的输入信号
persistent prev_ts % 记录上一次状态发生突变的时间
persistent flag % 标记当前状态是否处于突变中
if isempty(prev_ts) % 初始化
prev_ts = 0;
flag = false;
end
if tauext ~= prev_tauext % 检测到状态发生突变
if flag % 处于突变中
ts = prev_ts; % 维持之前的时间
else % 处于非突变状态
ts = now; % 记录当前时间
flag = true; % 标记进入突变状态
end
else % 状态未发生突变
ts = prev_ts; % 维持之前的时间
flag = false; % 标记状态不在突变中
end
prev_tauext = tauext; % 更新输入信号的历史记录
prev_ts = ts; % 更新状态发生突变的时间
if tauext > tau0 % 根据阈值计算参考轨迹
ref_traj = sin(ts) + 0.02;
else
ref_traj = sin(ts) - 0.02;
end
end
这个函数使用了MATLAB中的persistent
关键字,可以在多次调用函数时保存变量的历史值。函数内部检测输入信号的变化,一旦发现输入信号从0到非零值的上升沿或从非零值到0的下降沿,记录当前时间作为状态发生突变的时间,并保存为prev_ts
。如果状态未发生突变,则将上一个状态发生突变的时间prev_ts
保持不变。最后根据阈值tau0计算参考轨迹sin(ts)±0.02,并返回时间ts和参考轨迹ref_traj。
Data Store Write
——————————————————————————————————
2023.05.16
Simulink如何记录变量从0突变为正或负的当前仿真时间点/值。
在Simulink中记录变量从0突变为正或负的当前仿真时间点/值,可以使用MATLAB Function模块结合Simulink信号触发机制来实现。以下是实现的步骤:
-
在Simulink模型中添加一个MATLAB Function模块,并打开该模块进行编辑。
-
在输入和输出参数部分定义所需的输入和输出变量。例如,如果你想记录从0突变为正的时间点,你可以将时间变量作为输入,将记录时间点的变量作为输出。
-
在MATLAB Function模块的编辑器中,编写MATLAB代码来实现记录突变时间点的逻辑。你可以使用条件语句和变量来检测突变并记录时间点。
-
在模块的设置中,将Sample Time设置为-1,以确保该模块只在触发时运行。这样可以确保仅在发生突变时记录时间点。
-
连接MATLAB Function模块与其他模块或信号。
-
运行Simulink模型,并观察记录的时间点是否符合预期。
以下是一个示例MATLAB Function模块代码,用于记录变量从0突变为正的当前仿真时间点:
function record_time = fcn(input_time, input_variable)
persistent previous_variable;
persistent record_time;
if isempty(previous_variable)
previous_variable = input_variable;
record_time = [];
end
if previous_variable == 0 && input_variable > 0
record_time = [record_time, input_time];
end
previous_variable = input_variable;
end
function [ts_up, ts_down] = recordTriggerTime(tauext, t)
ts_up = 0; % Time point of the rising edge
ts_down = 0; % Time point of the falling edge
prev_tauext = 0; % Previous contact force value
is_up_recorded = false; % Flag to indicate if rising edge is recorded
is_down_recorded = false; % Flag to indicate if falling edge is recorded
for i = 1:length(tauext)
% Detect rising edge and record the time point
if prev_tauext == 0 && tauext(i) > 0
ts_up = t(i);
is_up_recorded = true; % Exit the loop after the first rising edge
end
% Detect falling edge and record the time point
if prev_tauext == 0 && tauext(i) < 0
ts_down = t(i);
is_down_recorded = true; % Exit the loop after the first rising edge
end
% Exit the loop if both rising and falling edges are recorded
if is_up_recorded && is_down_recorded
break;
end
prev_tauext = tauext(i); % Update the previous contact force value
end
end
function [ts_up, ts_down] = recordTriggerTime(tauext, t)
ts_up = 0; % Time point of the rising edge
ts_down = 0; % Time point of the falling edge
prev_tauext = 0; % Previous contact force value
trigger_detected = false; % Flag to indicate if a trigger has been detected
for i = 1:length(tauext)
% Detect rising edge and record the time point
if ~trigger_detected && prev_tauext == 0 && tauext(i) > 0
ts_up = t(i);
trigger_detected = true;
end
% Detect falling edge and record the time point
if ~trigger_detected && prev_tauext == 0 && tauext(i) < 0
ts_down = t(i);
trigger_detected = true;
end
if trigger_detected
break; % Exit the loop after the first trigger is detected
end
prev_tauext = tauext(i); % Update the previous contact force value
end
end
% if tauext == 0
% qr = qr_a;
% elseif tauext > tau0
% qr = qr_p;
% if qr > qr_a
% qr = qr_a;
% else
% qr = qr_p;
% end
% elseif tauext < -tau0
% qr = -qr_p;
% if qr < qr_a
% qr = qr_a;
% else
% qr = -qr_p;
% end
% else
% qr = qr_a;
% end
function [ts_up, ts_down] = recordTriggerTime(tauext, t)
ts_up = 0; % Time point of the rising edge
ts_down = 0; % Time point of the falling edge
prev_tauext = 0; % Previous contact force value
i = 1;
while i <= length(tauext)
% Detect rising edge and record the time point
if prev_tauext == 0 && tauext(i) > 0
ts_up = t(i);
break; % Exit the loop after the first rising edge
end
% Detect falling edge and record the time point
if prev_tauext == 0 && tauext(i) < 0
ts_down = t(i);
break; % Exit the loop after the first falling edge
end
prev_tauext = tauext(i); % Update the previous contact force value
i = i + 1; % Increment the index
end
end
function [ts_up, ts_down] = recordTriggerTime(tauext, t)
ts_up = 0; % Time point of the rising edge
ts_down = 0; % Time point of the falling edge
prev_tauext = tauext(1); % Previous contact force value
i = 2;
while i <= length(tauext)
% Detect rising edge and record the time point
if prev_tauext == 0 && tauext(i) > 0
ts_up = t(i);
break; % Exit the loop after the first rising edge
end
% Detect falling edge and record the time point
if prev_tauext == 0 && tauext(i) < 0
ts_down = t(i);
break; % Exit the loop after the first falling edge
end
prev_tauext = tauext(i-1); % Update the previous contact force value
i = i + 1;
end
end
function [ts_up, ts_down] = recordTriggerTime(tauext, t)
ts_up = 0; % Time point of the rising edge
ts_down = 0; % Time point of the falling edge
prev_tauext = 0; % Previous contact force value
for i = 1:length(tauext)
% Detect rising edge and record the time point
if prev_tauext == 0
if tauext(i) > 0
ts_up = t(i);ts_down = 0;
elseif tauext(i) < 0
ts_down = t(i);ts_up = 0;
break; % Exit the loop after the first rising edge
else
ts_up = 0; ts_down = 0;
end
end
prev_tauext = tauext(i); % Update the previous contact force value
end
end
用S函数代替就可以解决问题!
————————————————————
% 在线扩散参考轨迹生成
if t == ts_up
qr_p=sin(ts_up)+epsilon;
end
if t==ts_down
qr_p=abs(sin(ts_down)-epsilon);
end
% 参数设置
ts0 = 0.35; % 碰撞时间
amplitude = 1; % 振幅
frequency = 1; % 频率
phase_shift = pi-2*ts0; % 相位移动
% 时间范围
t = linspace(0, 5*pi, 100); % 0到2π之间等间隔采样100个点
% 正弦轨迹
trajectory = amplitude * sin(frequency*t);
% 绘制正弦轨迹
figure;
plot(t, trajectory, 'b', 'LineWidth', 2);hold on;
% 高频周期短的轨迹 % shifted_trajectory = 0.5*amplitude * sin(3*frequency*t + phase_shift);
plot(t, sin(ts0)* ones(size(t)), 'LineWidth', 2);hold on;
plot(t, -sin(ts0)* ones(size(t)), 'LineWidth', 2);hold on;
% 相位向左移动的轨迹
shifted_trajectory = amplitude * sin(frequency*t + phase_shift);
plot(t, shifted_trajectory, 'r--', 'LineWidth', 2);hold on;
xlabel('Time');ylabel('Amplitude');grid on;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 参数设置
ts0 = [1, 3, 5, 7, 9, 11]; % 触发状态事件的时间
amplitude = 1; % 振幅
frequency = 1; % 频率
% 时间范围
t = linspace(0, 5*pi, 100); % 0到2π之间等间隔采样100个点
% 正弦轨迹
trajectory = amplitude * sin(frequency * t);
% 绘制正弦轨迹
figure;
plot(t, trajectory, 'b', 'LineWidth', 2);
hold on;
% 每次触发状态后移动正弦轨迹
for i = 1:length(ts0)
if i > 1
% 计算相位移动量
phase_shift = pi - 2 * (ts0(i) - ts0(i-1));
else
phase_shift = pi - 2 * ts0(i);
end
% 更新相位向右移动的轨迹
shifted_trajectory = amplitude * sin(frequency * t + phase_shift);
plot(t, shifted_trajectory, 'r--', 'LineWidth', 2);
end
% 设置图形参数
xlabel('时间');
ylabel('轨迹');
legend('初始正弦轨迹', '触发后移动的轨迹');
title('机器人轨迹生成');
hold off;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 时间范围
t = linspace(0, 5*pi, 100); % 0到2π之间等间隔采样100个点
t0=1;t1=3;t2=5;t3=7;t4=7;
if (t>=0) && (t<t0)
qr = sin(t);
elseif (t>=t0) && (t<t1)
qr = sin(2*t0-t);
elseif (t>=t1) && (t<t2)
qr = sin(2*t1-t);
elseif (t>=t2) && (t<t3)
qr = sin(2*t2-t);
elseif (t>=t3) && (t<t4)
qr = sin(2*t3-t);
else
qr = 0;
end
qrs0 = sin(2*t0-t);
qrs1 = sin(2*t0-(2*t1-t));
qrs2 = sin(2*t0-(2*t0-(2*t1-t)));
qrs3 = sin(2*t3-t);
qrs4 = sin(2*t4-t);
plot(t, qr, 'b', 'LineWidth', 2);hold on;
plot(t, qrs0, 'LineWidth', 2);hold on;
plot(t, qrs1, 'LineWidth', 2);hold on;
plot(t, qrs2, 'LineWidth', 2);hold on;
plot(t, qrs3, 'LineWidth', 2);hold on;
plot(t, qrs4, 'LineWidth', 2);hold on;
参考文献:
【1】