Usage
Director
Actions are controlled by a Director, that will tell them to Execute, Abort, and keep track of their status. Its recommended only 1 Director per a Namespace.
Director setup
A Director is of Atn_typ. The Director should be declared in the Master task and does not need to be global. This task will be handle direcotor actions such as: Aborts, and running actions. Director should be called cyclically using the function atnCyclic.
If the project has multiple directors you may also want to define the Namespace used by the Director. If no Namespace is provided, Director will fall back on the default Namespace.
strcpy(director.in.par.namespace, ""); // Leave Namespace default
atnCyclic( &director );
memset(&director.in.cmd, 0, sizeof(director.in.cmd));
Calling Actions
Actions can be called using the atnRunAction function or using the AtnRunAction function block. When an action is called any Module registered to that action in the Directors Namespace will be executed. The following examples command a MoveAxis command passing in axisIndex as a parameter. Status is of AtnApiStatus_typ.
// Function version
if(start) {
atnRunAction( &director, "MoveAxis", &axisIndex, sizeof(axisIndex), &status );
}
if(status.done){
// Success
}
else if(status.error){
// Handle error
}
//Function Block version
if(start) {
strcpy(moveAxis.action, "MoveAxis");
moveAxis.execute = 1;
}
moveAxis.director = &director;
AtnRunAction( &moveAxis );
moveAxis.execute = 0;
if(moveAxis.done){
// Success
}
else if(moveAxis.error){
// Handle error
}
Module
Modules are behaviors registered to actions. When an action is ran, all the modules registered with that action are set to EXECUTE. Similarly an action is done when all registered modules report done. A Module will always have a variable of AtnAPI_typ associated with it. A Module can also have a parameter of any type associated with it.
Register
A Module can be registed using one of the following functions:
- atnRegisterActionPV - Registers module from PV name
- atnRegisterActionPVLocal - Registers module from PV name declared in current task
- atnRegisterAction - Registers module from pointer
Modules will only be registered in the Namespace provided in the register function. Modules can be registered to multiple Namespaces at the same time. In doing so it is possible for Director’s to be blocked by a Module that is already busy. More information on blocking is provided in Handling Actions section.
Note: Action names are case insensitive and can only be ATN_ACTION_NAME_LEN characters long and will be truncated.
Example below shows registering Module moveAxis with action “MoveAxis” in the default Namespace using the 3 different methods. Note: moveAxis accepts a parameter linked with the local variable axisIndex.
atnRegisterActionPV( "", "MoveAxis", "Task:moveAxis", "Task:axisIndex");
atnRegisterActionPVLocal( "", "MovePin", "moveAxis", "axisIndex");
atnRegisterAction( "", "MovePin", &moveAxis, &axisIndex, sizeof(axisIndex) );
Handling Actions
Below is an example implementation of a moveAxis Module registered above. The behavior criteria for this Modules is:
- Move axis provided in the parameters to postion 0
- If move is aborted by another command, move on as normal
- If axis errors, respond error
- If Module is aborted, stop the move
- If Module is blocking, continue blocking
strcpy(moveAxis.moduleName, "move axis");
switch (moveAxis.state) {
case ATN_EXECUTE:
// Do stuff
moveAbsolute.Axis = gMotorNcm[axisIndex];
moveAbsolute.Execute = 1;
moveAbsolute.Position = 0;
strcpy(moveAxis.moduleStatus, "Moving");
if( moveAbsolute.Done ){
// When done doing stuff, respond done
moveAxis.response = moveAxis.state;
}
else if( moveAbsolute.CommandAborted ) {
moveAxis.response = moveAxis.state;
}
else if( moveAbsolute.Error ) {
moveAxis.response = ATN_ERROR;
}
break;
case ATN_ABORT:
// Stop doing stuff
halt.Axis = gMotorNcm[axisIndex];
halt.Execute = 1;
strcpy(moveAxis.moduleStatus, "Stopping");
if( halt.Done ){
moveAxis.response = moveAxis.state;
}
else if( halt.CommandAborted ) {
moveAxis.response = moveAxis.state;
}
else if( halt.Error ) {
moveAxis.response = ATN_ERROR;
}
break;
default:
moveAxis.response = moveAxis.state;
break;
}
Namespace
Namespaces allow separate action lists for Directors to use. This is useful when either: multiple Directors are present in a project, or the Director’s available actions change with depending on some condition. Namespaces are created as needed a do not need to be initialized in most cases. By default only MAI_ATN_ACTIONS + 1 Modules can be registered to a namespace at a time. To increase this amount see atnSetActionList. Namespaces case insensitive and can only be ATN_NAMESPACE_LEN characters long and will be truncated.
Below example expands the size available of the default Namespace to 200 actions.
// Variables declared in the var file:
// AtnActionData_typ myActions[200]
atnSetActionList("", &myActions, sizeof(myActions)/sizeof(myActions[0]))