我正在学习 PsychToolBox 并参考本教程。http://peterscarfe.com/movingdotgriddemo.html
有这条线:
vbl = Screen('Flip', window, vbl + (waitframes - 0.5) * ifi);
我无法弄清楚。有人可以向我解释一下吗?尤其是那 vbl + (waitframes - 0.5) * ifi)
部分。谢谢!
我正在学习 PsychToolBox 并参考本教程。http://peterscarfe.com/movingdotgriddemo.html
有这条线:
vbl = Screen('Flip', window, vbl + (waitframes - 0.5) * ifi);
我无法弄清楚。有人可以向我解释一下吗?尤其是那 vbl + (waitframes - 0.5) * ifi)
部分。谢谢!
LHS(左侧)上的 vbl 是一个变量,其中存储了屏幕“翻转”的时间。
RHS 是来自 PTB 的命令,告诉窗口翻转 - Screen('Flip',window) - vbl + (waitframes - 0.5)*ifi 是翻转指令中的一个附加参数,告诉计算机等待该时刻翻转屏幕。即屏幕('翻转',窗口,何时)
在这种情况下,屏幕将在前一个翻转(vbl + ...)位之后翻转(等待帧 - 0.5)*ifi 秒。因为 ifi 是帧间间隔(屏幕连续刷新之间的时间),我们可以简单地说 vbl + ifi,它会在每次刷新时翻转屏幕,但是,我们在那里添加 (waitframes - 0.5) 乘数,这样我们可以指定在再次翻转屏幕之前我们应该等待多少次刷新。我从来没有真正理解过 -0.5 部分的逻辑,所以我很想看看是否有人能回答这个问题。
无论如何,在它翻转屏幕之后,它会保存屏幕翻转的时间,以便下一个翻转命令可以使用该时间戳作为指定下一次翻转应该发生的时间的基础 (vbl+(waitframes-0.5)*ifi
亚历克斯所说的一切都是正确的;我只是为 -0.5 添加一个解释(我没有足够的声誉来评论他的答案)
回顾一下:在每个循环/帧上,您翻转屏幕缓冲区并在vbl
变量中获取翻转时间。在下一个循环中,您根据最后一个翻转来计时下一次翻转,即vbl + [some number of seconds]
。因此,您的代码行既使用vbl
函数调用中的先前值,又将其设置为函数返回的新值。vbl
滚动更新。vbl
是“垂直消隐”时间,可以非常准确地估计显示器实际刷新的时间*,因此将帧与此对齐是个好主意。
问题是距离最后一个 vbl 多远才能进行下一次翻转。正如亚历克斯所说,ifi
是刷新之间的时间,或1/[your monitor refresh rate in Hz]
. 让我们暂时忽略waitframes
并假设您想在每次显示器刷新时翻转,即waitframes = 1
.
然后您的代码行简化为
vbl = Screen('Flip', window, vbl + ifi/2);
所以我们要求在下次刷新之前翻转半个 ifi。为什么不只是要求在下一次刷新时翻转,即vbl + ifi
?因为该总和是浮点计算,可能包含小的舍入误差。Screen('Flip')
只能在下一次显示器刷新时交换屏幕缓冲区,那么如果该总和中的错误略微超调会发生什么?然后,您只要求稍微超出您实际想要的显示器刷新的翻转时间,而 PTB 必须等待几乎整个 ifi 才能真正翻转**。
因此,我们要求在所需的显示器刷新之前有一段翻转时间(小于 ifi) -ifi/2
是合理的。我们实际上是在说“在之后尽快进行下一次翻转vbl+ifi/2
”,知道Screen('Flip')
在刷新之前实际上无法做到这一点,并且知道我们有ifi/2
余地来吸收计时计算中的微小误差。
的算术waitframes
留给读者作为练习。
*假设 PTB 设置正确以与您的硬件配合使用 - 请注意那些警告消息!
**更糟糕的是,这可能不会出现在 PTB 的错误中,例如丢帧计数,因为 PTB 已经实现了您的要求:在您指定时间的下一次显示器刷新时翻转缓冲区。在这种情况下,您知道您的实验滞后并呈现不合时宜的刺激的唯一方法就是您在运行时碰巧发现它!