Simulink中如何获取所需变量对应的时间,并实时传输给其他模块

本文介绍了如何在Simulink中获取所需变量对应的时间,并实时传输给其他模块。通过添加Clock和Scope模块,可以显示并获取仿真时间。在满足特定条件时,如信号的上升沿或下降沿,可以利用Triggered Subsystem记录时间点,并用于计算参考轨迹。文章还提供了MATLAB Function模块的实现方法,以记录变量从0突变为正或负的仿真时间点。

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

假设需要将时间信息传输给一个显示器模块,可以按照以下步骤进行操作:

  1. 在模型中添加“Clock”模块,将其输出与MATLAB函数“simulinktime”模块进行连接。

  2. 在模型中添加一个Scope模块,将其输入与Clock模块的输出进行连接。

  3. 运行模型,Scope模块将显示当前的仿真时间。

  4. 将Scope模块替换为显示器模块,并将Clock模块的输出与显示器模块的输入进行连接。

  5. 运行模型,可以看到显示器模块实时显示当前的仿真时间。

需要注意的是,Simulink中获取时间信息的方法并不唯一,具体方法要根据实际情况选择。同时,需要确保时间信息的传输是实时的,以保证模型的准确性和稳定性。

例如:

小于1的时候满足条件,输出时间点信息;当大于1以后,不满足逻辑条件,不再变化输出值。

把计数器放进触发子系统里面,用某变量的下降沿作为触发条件,就能记录

所用到的模块:Simulink使能(Enable)、触发(Triggered)模块及其子系统

Simulink使能(Enable)、触发(Triggered)模块及其子系统的应用_FL17171314的博客-CSDN博客为了在线进行期望轨迹的生成,检测到机器人所受接触力的阈值,那么触发此阈值所对应的时间值t0需要得到,我们就可以在线根据 qr= abs(sin(t0)+0.02)进行更新这样一个期望的轨迹,当然也可以sin(t0)+0.02 (sin(t0)>0), sin(t0)- 0.02 (sin(t0)< 0).例如,在一个较大的模型中,可以将一些不经常使用或计算量较大的子系统放在使能或触发模块中,以减少整个模型的计算量和仿真时间,提高仿真效率和精度。这种模块适用于需要在特定时间或事件触发时才执行的情况。https://blog.csdn.net/weixin_51367832/article/details/130678311?spm=1001.2014.3001.5502

 IF tauext 0,

     record (仅状态发生突变的一瞬间当前时间ts

即,0突变到某一阈值tau0的时候记录ts,不满足该条件的不记录。

记录到ts后,可求出参考轨迹,例如sints± 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信号触发机制来实现。以下是实现的步骤:

  1. 在Simulink模型中添加一个MATLAB Function模块,并打开该模块进行编辑。

  2. 在输入和输出参数部分定义所需的输入和输出变量。例如,如果你想记录从0突变为正的时间点,你可以将时间变量作为输入,将记录时间点的变量作为输出。

  3. 在MATLAB Function模块的编辑器中,编写MATLAB代码来实现记录突变时间点的逻辑。你可以使用条件语句和变量来检测突变并记录时间点。

  4. 在模块的设置中,将Sample Time设置为-1,以确保该模块只在触发时运行。这样可以确保仅在发生突变时记录时间点。

  5. 连接MATLAB Function模块与其他模块或信号。

  6. 运行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】

页面重载开启https://www.ilovematlab.cn/thread-316602-1-1.html

【2】simulink中如何记录条件被触发时的时间? - 知乎离线没啥意义了吧,而且也更容易实现,所以肯定问的是在simulink中实时计算的问题。根据你的要求,搭建了…https://www.zhihu.com/question/52826420/answer/142461973

【3】Share Data Store Between Instances of a Reusable Algorithm- MATLAB & Simulink- MathWorks 中国To reuse an algorithm, instead of copying and pasting the blocks, you can encapsulate them in a separate model file.https://ww2.mathworks.cn/help/simulink/slref/sharing-local-data-stores-across-multiple-instances-of-a-model.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值