我已经使用Zaber控制台编写了一个脚本来控制Zaber设备,该设备在循环中执行几个步骤。如何在循环中间暂停它并继续它而不必回到开始?
我可以想出四个选项来支持这一点。
- 让脚本在启动时以某种方式检测当前状态,并确定应该从例程的哪个部分开始。根据您的例程,您可能能够读取当前位置来判断您所处的步骤。如果不能,您也可以使用用户内存或将当前状态写入文本文件。其中一个示例脚本显示了如何写入文本文件
- 除了你的主脚本外,还要写一个暂停脚本和一个简历脚本。主脚本会注意到其他两个脚本的响应。我将在下面举一个例子
- 不要使用单独的脚本来暂停和恢复,而是使用Zaber操纵杆并对按钮进行编程以发送暂停和恢复命令。下面的例子也涵盖了这一点
- 将脚本转换为在BackgroundWorker中运行主例程的插件。然后,您可以在控制类中保持状态,并添加"暂停/恢复"按钮
下面是一个使用单独脚本暂停和恢复例程的示例。它还介绍了如何使用操纵手柄按钮。
原始程序
首先,我创建了这个简单的例程。
/* C# example of how to pause and resume a Zaber Console script.
* This script is the original routine without the pause and resume logic.
* It moves to position zero, then makes four moves of 10000 microsteps each
* and goes back to zero. This loops forever.
*/
#template(simple)
while (true)
{
for (var i = 0; i < 5; i++)
{
var position = i*10000;
Output.WriteLine("moving to {0}", position);
Conversation.Request(Command.MoveAbsolute, position);
}
}
暂停
这是暂停例程的脚本。
/* C# example of how to pause and resume a Zaber Console script.
* This script pauses the main routine by sending a Stop command. Running this
* script twice will stop the routine.
*/
#template(simple)
Conversation.Request(Command.Stop);
stop命令将在主脚本中导致错误,但我们将更改主脚本以捕捉该错误并添加暂停/恢复逻辑。
简历
这是恢复例程的脚本。
/* C# example of how to pause and resume a Zaber Console script.
* This script resumes the main routine by sending an EchoData command with a
* magic number.
*/
#template(simple)
const int RESUME_NUMBER = 42;// Matches the main routine.
Conversation.Request(Command.EchoData, RESUME_NUMBER);
例程加暂停逻辑
暂停和恢复脚本非常琐碎;真正的工作是让主脚本侦听来自stop命令的错误和要恢复的幻数。这是添加了所有内容的例程的新版本。在"脚本编辑器"主窗口中运行此脚本,然后在主窗口的"脚本"选项卡中的网格中运行另外两个脚本。
/* C# example of how to pause and resume a Zaber Console script.
* This script is the main routine that moves to position zero, then makes four
* moves of 10000 microsteps each and goes back to zero. This loops forever.
* To pause the routine, run the Pause.cs script. To resume the routine, run
* the Resume.cs script. Running the pause script twice will stop the routine.
*/
#template(methods)
/* We switched to the methods template so we can put the move with pause and
* resume into a helper method.
*/
public override void Run()
{
while ( ! IsCanceled)
{
for (var i = 0; i < 5 && ! IsCanceled; i++)
{
var position = i*10000;
MoveTo(position);
}
}
}
/* This wraps the pause and resume logic around a simple MoveAbsolute command.
* If your resume logic is more complicated, you can put more commands inside
* the try/catch block, or use the return value of this function to tell the
* main routine what to do next.
* When this method returns, either the move has successfully completed, or
* IsCanceled is true.
*/
private void MoveTo(int position)
{
bool isComplete = false;
while ( ! isComplete && ! IsCanceled)
{
try
{
Output.WriteLine("moving to {0}", position);
Conversation.Request(Command.MoveAbsolute, position);
isComplete = true;
}
catch (RequestReplacedException ex)
{
Pause();
}
catch (RequestCollectionException ex)
{
/* If you are running against device number zero
* or some other alias, you get a slightly
* different exception.
*/
Pause();
}
}
}
/* Just wait for responses from your device. If a response is an EchoData
* command with the magic number, then this method will return. If the response
* is a Stop command, then IsCanceled is set to true and this method will
* return. All other responses are ignored.
*/
private void Pause()
{
Output.WriteLine("paused");
/* Let the device finish processing the current stop command before
* you start listening, otherwise you sometimes see the stop command
* again.
*/
Sleep(100);
const int RESUME_NUMBER = 42;// Matches the resume script.
var listener = new DeviceListener(Conversation.Device);
bool isPaused = ! IsCanceled;// Don't pause if already canceled.
while (isPaused)
{
var response = listener.NextResponse();// wait
if (response.Command == Command.EchoData &&
response.Data == RESUME_NUMBER)
{
isPaused = false;
Output.WriteLine("resumed");
}
else if (response.Command == Command.Stop)
{
isPaused = false;
IsCanceled = true;
Output.WriteLine("stopped");
}
}
}
操纵手柄
如果你有一个Zaber操纵杆,点击几个操纵杆按钮比在Zaber控制台中运行暂停和恢复脚本更方便。操纵杆上按钮1的默认命令是"停止",因此您已经处理好了暂停。如果您对其他按钮之一进行编程以发送Echo Data 42,则可以恢复您的脚本。上面的最后一个脚本将运行带有暂停和恢复逻辑的例程,无论您是使用单独的脚本发送暂停和恢复命令,还是使用操纵杆按钮发送命令。