暂停并恢复Zaber控制台脚本



我已经使用Zaber控制台编写了一个脚本来控制Zaber设备,该设备在循环中执行几个步骤。如何在循环中间暂停它并继续它而不必回到开始?

我可以想出四个选项来支持这一点。

  1. 让脚本在启动时以某种方式检测当前状态,并确定应该从例程的哪个部分开始。根据您的例程,您可能能够读取当前位置来判断您所处的步骤。如果不能,您也可以使用用户内存或将当前状态写入文本文件。其中一个示例脚本显示了如何写入文本文件
  2. 除了你的主脚本外,还要写一个暂停脚本和一个简历脚本。主脚本会注意到其他两个脚本的响应。我将在下面举一个例子
  3. 不要使用单独的脚本来暂停和恢复,而是使用Zaber操纵杆并对按钮进行编程以发送暂停和恢复命令。下面的例子也涵盖了这一点
  4. 将脚本转换为在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,则可以恢复您的脚本。上面的最后一个脚本将运行带有暂停和恢复逻辑的例程,无论您是使用单独的脚本发送暂停和恢复命令,还是使用操纵杆按钮发送命令。

最新更新