Explaining the MotoLogix SystemState and its transitions using system commands.
The MLX.SystemState
variable
informs about the actual state of the MotoLogix system.
Below table lists the defined states:
value | name |
---|---|
0 | Initializing |
1 | EnablingToIdle |
2 | EnablingToHeld |
3 | Idle |
4 | Running |
5 | Holding |
6 | Held |
7 | Aborting |
8 | ServosOffAborted |
9 | StoppingToIdle |
10 | StoppingToServosOff |
11 | StoppingToServosOffHeld |
12 | ServosOffReady |
13 | ServosOffHeld |
14 | FatalFault |
State transitions
The following MotoLogix system commands are used for changing the SystemState:
Function blocks | |
---|---|
MLxAbort | Stop all axes and disable servo drives. Does not clear the motion buffer. |
MLxEnable | Enable the servo drives. |
MLxHold | Pause all axes. Motion can be resumed later. |
MLxReset | Reset alarms and clear the motion buffer. |
MLxResetAndHold | Reset alarms. Does not clear the motion buffer. |
MLxRestart | Resume buffered motions. Used to resume motion after MLxHold. |
MLxStop | Stop all axes and clear the motion buffer. Does not disable the servo drives. |
Below diagram lists the possible transitions and responsible system commands.
()
.SystemState vs. servo power
Below diagram shows the relation between the SystemState and the power of the servo drives:
MLxEnable
enables the servo drives.- Any robot alarm or Estop or
MLxAbort
disables the servo drives.
SystemState vs. motion buffer
Below diagram shows the relation between the SystemState and the motion buffer:
- Any motion command adds to the motion buffer
MLxStop
orMLxReset
clears the motion buffer
Code example
It is advised to use a state machine to handle the MotoLogix SystemState. This makes it easy to create a robust program which can easely be reused without having to think about all the states and transitions.
Below state diagram below shows a state machine with following features:
- A
Start
signal (push button) to enable the system – also used to pause/resume the motion. - A
Stop
signal (push button) to disable the system. - Abort in case of a command error.
- Always start with an empty motion queue – never rely on old data in the robot controller.
SystemReady
status signal which can be used in the application code.
stateDiagram-v2
state "(S00) idle" as S00
state "(S01) MLxReset" as S01
S01 : reset alarms
S01 : + motion queue
state "(S02) MLxEnable" as S02
S02 : enable
S02 : servo drives
state "(S05) waiting" as S05
S05 : wait for Step
state "(S10) system ready" as S10
S10 : ready for
S10 : motion commands
state "(S11) MLxHold" as S11
S11 : pause buffered
S11 : motion
state "(S12) hold active" as S12
S12 : wait for Step
state "(S13) MLxRestart" as S13
S13 : continue buffered
S13 : motion
state "(S20) MLxAbort" as S20
S20 : disable
S20 : servo drives
S00 --> S01 : RE_Start
S01 --> S02 : Sts_DN
S02 --> S05 : Sts_DN
S05 --> S10 : RE_Start
S10 --> S11 : RE_Start AND {RUNNING}
note right of S12
Hold can also be initiated by the pendant button.
This is detected by (MLX.SystemState = HELD).
end note
S10 --> S12 : {HELD}
S11 --> S12 : Sts_DN
S12 --> S13 : RE_Start
S12 --> S20 : RE_Stop
S13 --> S10 : Sts_DN
S10 --> S20 : RE_Stop
S05 --> S20 : RE_Stop
S20 --> S00 : Sts_DN OR Sts_ER
note right of S20
A Sts_ER of any of the System
Commands will also lead to S20.
end note
Variable declaration
FUNCTION_BLOCK ExtStartStop (*Start-stop logic*)
VAR_INPUT
Start : BOOL; (*start/hold/restart*)
Stop : BOOL; (*stop/abort*)
BasicConditionsOk : BOOL; (*basic conditions for running the system (e.g. Estop, REMOTE etc.)*)
END_VAR
VAR_IN_OUT
MLX : MLxData; (*MLx data*)
END_VAR
VAR_OUTPUT
Status : INT; (*Status of the state machine*)
SystemReady : BOOL; (*System ready for operation*)
WaitingForUser : BOOL; (*System waiting for a user action (e.g. pushing a button)*)
END_VAR
VAR
FB_Abort : MLxAbort;
FB_Enable : MLxEnable;
FB_Reset : MLxReset;
FB_Hold : MLxHold;
FB_Restart : MLxRestart;
state : INT;
RE_Start : BOOL; (*rising edge*)
RE_Stop : BOOL; (*rising edge*)
ONS : ARRAY[0..1] OF BOOL;
END_VAR
Logic
// --------------------------------------------------------------------------
// common
// --------------------------------------------------------------------------
FB_Reset.Enable := FALSE;
FB_Enable.Enable := FALSE;
FB_Abort.Enable := FALSE;
FB_Hold.Enable := FALSE;
FB_Restart.Enable := FALSE;
FB_SetGlobalParameter.Enable := FALSE;
RE_Start := Start AND NOT ONS[0];
ONS[0] := Start;
RE_Stop := Stop AND NOT ONS[1];
ONS[1] := Stop;
// --------------------------------------------------------------------------
// State machine: system start/stop
// --------------------------------------------------------------------------
CASE state OF
// -------------------------------------
// state 0 - idle
// -------------------------------------
0:
IF RE_Start AND BasicConditionsOk THEN
state := 1;
END_IF;
// -------------------------------------
// state 1 - reset system
// -------------------------------------
1:
FB_Reset.Enable := TRUE;
IF FB_Reset.Sts_EN AND FB_Reset.Sts_DN THEN
IF FB_Reset.Sts_ER THEN
state := 20;
ELSE
state := 2;
END_IF;
END_IF;
// -------------------------------------
// state 2 - enable system
// -------------------------------------
2:
FB_Enable.Enable := TRUE;
IF FB_Enable.Sts_EN AND FB_Enable.Sts_DN THEN
IF FB_Enable.Sts_ER THEN
state := 20;
ELSE
state := 5;
END_IF;
END_IF;
// -------------------------------------
// state 5 - waiting
// -------------------------------------
5:
IF RE_Start THEN
state := 10;
END_IF;
IF RE_Stop OR NOT BasicConditionsOk THEN
state := 20;
END_IF;
// -------------------------------------
// state 10 - system ready
// remains in this state during normal operation
// -------------------------------------
10:
// Hold initiated by start button
IF RE_Start AND (mlx.SystemState = 4) THEN
state := 11;
END_IF;
// Hold initiated by pendant button
IF (mlx.SystemState = 6) THEN
state := 12;
END_IF;
IF RE_Stop OR NOT BasicConditionsOk THEN
state := 20;
END_IF;
// -------------------------------------
// state 11 - hold (pause buffered motion)
// -------------------------------------
11:
FB_Hold.Enable := TRUE;
IF FB_Hold.Sts_EN AND FB_Hold.Sts_DN THEN
IF FB_Hold.Sts_ER THEN
state := 20;
ELSE
state := 12;
END_IF;
END_IF;
// -------------------------------------
// state 12 - hold active
// -------------------------------------
12:
// Restart initiated by start button
IF RE_Start THEN
state := 13;
END_IF;
IF RE_Stop OR NOT BasicConditionsOk THEN
state := 20;
END_IF;
// -------------------------------------
// state 13 - restart (continue buffered motion)
// -------------------------------------
13:
FB_Restart.Enable := TRUE;
IF FB_Restart.Sts_EN AND FB_Restart.Sts_DN THEN
IF FB_Restart.Sts_ER THEN
state := 20;
ELSE
state := 10;
END_IF;
END_IF;
// -------------------------------------
// state 20 - abort
// -------------------------------------
20:
FB_Abort.Enable := TRUE;
IF FB_Abort.Sts_EN AND (FB_Abort.Sts_DN OR FB_Abort.Sts_ER) THEN
state := 0;
END_IF;
END_CASE;
// -------------------------------------
// force state 0
// -------------------------------------
IF NOT MLX.Signals.MLXGatewayConnected THEN
state := 0;
END_IF;
// -----------------------------------------------------------------------------
// outputs
// -----------------------------------------------------------------------------
SystemReady := (state >= 10) AND (state <= 19);
WaitingForUser := (state = 5) OR (state = 12);
Status := state;
// -----------------------------------------------------------------------------
// FB calls
// -----------------------------------------------------------------------------
FB_Abort(MLX:= MLX);
FB_Enable(MLX:= MLX);
FB_Reset(MLX:= MLX);
FB_Hold(MLX:= MLX);
FB_Restart(MLX:= MLX);