【问题标题】:Execute for loop with time随时间执行for循环
【发布时间】:2014-07-27 01:01:12
【问题描述】:

我有一个这样的 for 循环

for t = 0: 1: 60
    // my code
end

我想在第 1、第 2、第 3、...、第 60 秒内执行我的代码。这个怎么做?另外,我怎样才能在任意时间运行我的代码?例如在第 1 秒、第 3 秒和第 10 秒?

【问题讨论】:

  • 检查timer。或者,如果你想让它更简单,pause
  • 告诉 Matlab 更新绘图后不要忘记drawnow
  • @user96402 如果是这种情况,您可以使用getframe 录制电影,然后以 1 fps 播放...
  • @user-96402:是的。如果您想绘制动画,则不需要使用for 循环。获取帧并以指定的帧速率播放它们就足够了。
  • +1 纳坦的建议。以下是该方法的一些示例:stackoverflow.com/a/11054155/97160

标签: matlab for-loop timer


【解决方案1】:

轮询不好,但是 Matlab 默认是单线程的,所以...

对于第一种情况:

tic;
for t = 1:60
    while toc < t, pause(0.01); end;
    % your code
end;

对于第二种情况:

tic;
for t = [1,3,10]
    while toc < t, pause(0.01); end;
    % your code
end;

pause 呼叫是在Amro 对忙等待的明智观察后添加的。 0.01 秒听起来像是计时精度和旋转“数量”之间的良好折衷......

【讨论】:

  • 您可能想在 while 循环中稍作停顿以减少 busy-waiting
  • @Amro 整洁​​!如果您觉得如此,请继续在代码中进行修改。 :-)
  • 还有一件事(我保证最后一条评论!):您还可以使用显式 tic/toc 指标(如:tval = tic;toc(tval)),以防万一“代码”正在使用它自己的 tic/toc 计时器。
【解决方案2】:

您可以使用timer 对象。这是一个打印从110 的数字的示例,连续数字之间有1 秒。计时器启动,并在达到预定义的执行次数时自行停止:

n = 1;
timerFcn = 'disp(n), n=n+1; if n>10, stop(t), end'; %// timer's callback
t = timer('TimerFcn' ,timerFcn, 'period', 1, 'ExecutionMode', 'fixedRate');
start(t) %// start the timer. Note that it will stop itself (within the callback)

一个更好的版本,感谢@Amro:将执行次数直接指定为计时器的属性。完成后不要忘记停止计时器。但不要过早停止它,否则它不会执行预期的次数!

n = 1;
timerFcn = 'disp(n), n=n+1;'; %// this will be the timer's callback
t = timer('TimerFcn', timerFcn, 'period', 1, 'ExecutionMode', 'fixedRate', ...
    'TasksToExecute', 10);
start(t) %// start the timer.
%// do stuff. *This should last long enough* to avoid stopping the timer too soon
stop(t)

【讨论】:

  • 你可以改为设置t.TasksToExecute = 10。计时器函数只是在每个时间间隔执行的代码。
  • @Amro 不错!这是我在 Matlab 中第一次使用timer。我错过了那个属性。谢谢;我已经更新了答案
【解决方案3】:

虽然pause 在大多数情况下已经足够好,但如果您想要更高的准确度,请使用java.lang.Thread.sleep

例如,下面的代码将显示您计算机时钟的分钟和秒,准确地在秒(功能时钟精确到〜1微秒),您可以添加您的代码而不是disp 命令,java.lang.Thread.sleep 只是为了说明它的准确性(解释见代码后)

while true
    c=clock;
    if mod(c(6),1)<1e-6
        disp([c(5) c(6)])
        java.lang.Thread.sleep(100);  % Note: sleep() accepts [mSecs] duration
    end
end

要查看准确性差异,您可以将上面的内容替换为 java.lang.Thread.sleep(999);pause(0.999),看看您有时如何跳过迭代。

欲了解更多信息,请参阅here

编辑:

您可以使用tic\ toc 而不是clock,这可能更准确,因为它们花费的时间更少...

【讨论】:

    【解决方案4】:

    您可以做的是使用pause 命令并在pause 中输入您希望代码的秒数。一旦你这样做了,你就可以执行你想要的代码。举个例子:

    times = 1:60;
    for t = [times(1), diff(times)]
        pause(t); % // Pause for t seconds
        %// Place your code here...
        ...
        ...
    end
    

    正如@CST-Link 所指出的,我们不应该考虑经过的时间,这就是为什么我们会考虑您想要启动循环的相邻时间的差异,以便我们可以尽快启动您的代码.

    另外,如果您想要任意时间,请将所有时间放在一个数组中,然后遍历该数组。

    times = [1 3 10];
    for t = [times(1), diff(times)]
        pause(t); %// Pause for t seconds
        %// Place your code here...
        ...
        ...
    end 
    

    【讨论】:

    • @LuisMendo:啊哈哈没问题。只是意味着我们在同一个波长上
    • 实际上,代码应该暂停diff(times)的值而不是times的值。因为不应考虑经过的时间... :-) 我可以更改您帖子中的代码吗?
    • @CST-Link:啊哈,当然可以。是的,请随意。获得您的 +2 代表 :)
    • @rayryeng 希望您会同意我的更改,感谢您的机会。 :-)
    • @CST-Link:已接受。感谢您的建议!
    猜你喜欢
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多