# How to command stage to move

Before a task starts image acquisition, the stage should move to its target pose first. The control of this movement could be done by an external motion controller before it calls the task(motion guided) or done by the vision system which commands the stage to move before image acquisition starts(vision guided). This topic will walk through how the vision system commands the stage to move and waits until the movement is done before starting image acquisition.

## Where to command stage to move

Every image acquisition block inside a calibration or feature finding task have one corresponding call back function which allows user to customize before or after image acquisition. These acquisition callback functions can be found in Scripting/User Scripts/AlignPlus/Callbacks category, named as <Task Name>Callback.

For example, the image acquisition callback function for a hand-eye calibration task "HECalib0" is "HECalib0Callback". The content of HECalib0Callback script is implemented by configuration wizard during application generation. It performs in three different acquisition states: InitializingAcquistion, ReadyToAcquire, and FinishedAquisition.

### InitializingAcquistion

HECalib0Callback is first called with InitializingAcquisition state. In this state, the target pose of stage is extracted from Command, and sent to "Stage0Move" script. The specific code inside "Stage0Move" to command the stage to move needs to be implemented by an engineer according to specific stage type and communication protocol.

The stage move script lies under Scripting/User Scripts/AlignPlus/StageMotion.

### ReadyToAcquire

After the movement is done and before the camera starts to acquire image, HECalib0Callback is called again with ReadyToAcquire state. In this state, the vision system can acquire the stage's current pose through "Stage0GetPosition" script. "Stage0GetPosition" script here is also empty and requires an engineer to implement according to specific stage type and communication protocol.

### FinishedAcquisition

After image acquisition is done, HECalib0Callback will be called with FinishedAcquisition state, where user can add some other custom actions if needed.

## How to wait stage move done

After the vision system send out stage move command, it needs to wait until the move is done before continuing image acquisition. A simple way to hold current vision task thread while waiting for the stage move done signal in another thread is to use a ManualResetEvent object. Here is the diagram that shows how a ManualResetEvent object works in controlling work flow between two threads.

In InitlizingAcqusition state of a vision task, after stage move command is sent, the ManualResetEvent object will block current vision task thread (without freezing the program) by calling WaitOne() event. After the requested stage finishes moving in the handshake thread, the same ManualResetEvent object will call a Set() event, through which the suspended vision task thread will be released, and continue to run the next line which makes ManualResetEvent object be Reset(). What follows is for the vision thread to continue image acquisition.

Below are the steps of adding and using a ManualResetEvent object.

1. Add "System.Threading.dll" to project references and "System.Threading" to space names in System/Settings/Scripts.

2. Create a tag named HECalib.MoveDoneEvent as ManualResetEvent object.

3. Initialize the tag in OnStartup script.

   $HECalib.MoveDoneEvent = new ManualResetEvent(false);

4. In InitializingAcquisition state of an image acquisition callback, set the tag to start a waiting event (it will return false if it is timed out).

   $HECalib.MoveDoneEvent.WaitOne($SystemData.HECalib.Timeout);

5. In the handshake thread, once the vision system receives the stage's move done signal, set the event.

   $HECalib.MoveDoneEvent.Set();

6. Back to InitializingAcquisition state of image acquisition callback, reset the event.

   $HECalib.MoveDoneEvent.Reset();