Handling manual motions for a MotoLogix system.
Whenever you need to adjust a position, teach a user frame, calibrate a tool or move the robot for maintenance some manual motions are required.
Features:
- Jog axis (joints)
- Jog TCP (cartesian motion)
- Inching axis
- Inching TCP
- Jog to point (point-to-point or linear)
- Handles the switching of
MLX.JoggingMode. - Activates the selected Tool and User Frame for cartesian jog motions.
State machines:
nSmManualMotion- handling the manual motionnSmSettings- update settings for cartesian motion
Usage
Usually you only need one instance of this module – even if you have multiple MotoLogix systems and/or motion devices. By using a selector on the HMI you map the manual motion module to the desired system and motion device.
If you want to be able to perform manual motions simultaneous on multiple MotoLogix systems and/or motion devices you would need to create additional instances.
Create the (global) variable for the interface data. This is also used for connecting buttons or an HMI.
stManualMotion : MceManualMotionIO; // data for manual motion of MotoLogix motion devices
Create the instance:
fbManualMotion : MceManualMotion;
Map all relevant inputs (see MceManualMotionIO)
to your HMI and/or other programs:
// this is just a portion of the relevant signals
GVL.stManualMotion.nMlxNumber := ...;
GVL.stManualMotion.nRobotNumber := ...;
GVL.stManualMotion.nOperatingMode := ...;
GVL.stManualMotion.bSystemReady := ...;
GVL.stManualMotion.bInchingMode := ...;
GVL.stManualMotion.aJogRobotAxisNeg := ...;
GVL.stManualMotion.aJogRobotAxisPos := ...;
GVL.stManualMotion.nJogType := ...;
GVL.stManualMotion.nCoordFrame := ...;
GVL.stManualMotion.bMoveTo := ...;
GVL.stManualMotion.aTargetPosition := ...;
GVL.stManualMotion.aTargetType := ...;
Call the instance:
// function call
fbManualMotion(
io := GVL.stManualMotion,
UserFrames := GVL.stUserFrames[<robot selection>],
MLX := GVL.stMLX[<mlx selection>]);
Map all relevant outputs (see MceManualMotionIO)
to your HMI and/or other programs:
// this is just a portion of the relevant signals
... := GVL.stManualMotion.bIdle;
... := GVL.stManualMotion.bBusy;
... := GVL.stManualMotion.bDone;
... := GVL.stManualMotion.bError;
... := GVL.stManualMotion.aJogRobotAxisNegIndicator;
... := GVL.stManualMotion.aJogRobotAxisPosIndicator;
Jogging to a target position does not insure that the TCP speed is limited to
250 mm/s.
This is because standard motion commands MLxRobotMoveAxisAbsolute and
MLxRobotMoveLinearAbsolute are used.
For an experience similar to the teach pendant when moving the robot to a target
position, a speed factor is applied to the nSpeed input.
These factors are hardcoded in the function block.
For example, for a linear motion (nJogType = 1) and nSpeed = 20, the speed
passed to the motion command is 2% (10% of 20%).
nJogType value | Speed factor |
|---|---|
| 0 | 3% |
| 1 | 10% |
Acceleration and deceleration default values has been selected to mimic the robot behavior when using the teach pendant.
| Parameter | Value |
|---|---|
nAcc | 40% |
nDec | 80% |
Version history
1.0.1
Changes
- state machine stuck when an alarm occurs
- doing linear manual motion in a user frame (only relevant for Rockwell)
show full history
1.0.0
Changes
- jog to point function
- requires
MceManualMotionIOdata type version0.2.0 - mode selection input
nOperatingModerenamedbEnableManualMode
0.2.0
Changes
- avoid abruptly interrupted command when
bSystemReadyturnsFalse
0.1.0
Changes
- initial version
Overview
| kind | name | type | default | comment |
|---|---|---|---|---|
| in_out | io | MceManualMotionIO | interface data | |
| in_out | userFrames | MceUserFrames | collection of user frames for this robot | |
| in_out | MLX | MLxData | MotoLogix shared memory variable |
Details
Interface data for this function.
Check the data type for more information.
userFrames
MceUserFramesCollection of user frames for this robot.
Check the data type for more information.
MLX
MLxDataThe MotoLogix variable which acts as the shared memory for a MotoLogix system.
Check the YaskawaMLx library for more information.
Source code
Declarations
(*Handling the manual motion.*)
FUNCTION_BLOCK MceManualMotion
(*
* -----------------------------------------------------------------------------
* Name : MceManualMotion
* Version : 1.0.1
* Date : 2025-06-06
* Author : Rioual
* Family : YaskawaMce
* Organisation : github.com/YaskawaEurope/mlx-examples
*
* -----------------------------------------------------------------------------
* Handling the manual motion.
* -----------------------------------------------------------------------------
*)
VAR_IN_OUT
io : MceManualMotionIO; (*interface data*)
userFrames : MceUserFrames; (*collection of user frames for this robot*)
MLX : MLxData; (*MotoLogix shared memory variable*)
END_VAR
VAR
bJogPressed : BOOL; (*some jog button pressed*)
bRunJog : BOOL; (*run jog commands*)
bUseRotSpeed : BOOL; (*use rotational speed*)
aDirections : ARRAY [0..5] OF SINT; (*jog motion per axis (0=standstill, 1=positive dir, -1=negative dir)*)
bOsrRunJog : BOOL; (*rising edge*)
bTcpSettingsNeedUpdate : BOOL; (*settings for TCP jog need to be updated*)
bMlxNumberChanged : BOOL; (*value has changed*)
bJogTypeChanged : BOOL; (*value has changed*)
bRobotNumberChanged : BOOL; (*value has changed*)
bCoordFrameChanged : BOOL; (*value has changed*)
bToolChanged : BOOL; (*value has changed*)
bUserFrameChanged : BOOL; (*value has changed*)
bUpdateSettingsDone : BOOL; (*update settings: done*)
bUpdateSettings : BOOL; (*start update settings*)
aOneShots : ARRAY [0..0] OF BOOL; (*bits for creating one shot signals*)
nCoordFrameSelected : USINT; (*selected value*)
nUserFrameSelected : USINT; (*selected value*)
nToolSelected : USINT; (*selected value*)
nMlxNumberSelected : USINT; (*selected value*)
nRobotNumberSelected : USINT; (*selected value*)
nJogTypeSelected : USINT; (*selected value*)
i : DINT; (*index for FOR loops*)
fbJogAxis : MLxRobotJogAxes;
fbJogTcp : MLxRobotJogTCP;
fbSelectTool : MLxRobotSelectTool;
fbSetUserFrame : MLxRobotSetUserFrame;
fbMoveAxisRel : MLxRobotMoveAxisRelative;
fbMoveLinRel : MLxRobotMoveLinearRelative;
fbMoveAxisAbsolute : MLxRobotMoveAxisAbsolute;
fbMoveLinearAbsolute : MLxRobotMoveLinearAbsolute;
fbStop : MLxStop;
fbIdleTime : TON;
fbCoastTime : TON;
stTargetPoint : MLxAppDataTeachPoint;
END_VAR
VAR CONSTANT
JOGTYPE_AXIS : USINT := 0; (*jog type: axis*)
JOGTYPE_TCP : USINT := 1; (*jog type: TCP*)
INCHING_DIST_AXIS : REAL := 0.1; (*inching distance for axis jog [deg]*)
INCHING_DIST_TCP : REAL := 0.1; (*inching distance for cartesian jog [mm or deg]*)
INCHING_SPEED : REAL := 10; (*inching speed [% rated]*)
JOG_TO_BF : SINT := 0; (*BlendFactor for jog to point [-1 to 8]*)
INCHING_BF : SINT := -1; (*BlendFactor for inching [-1 to 8]*)
INCHING_ACC_DEC : REAL := 80; (*acceleration/deceleration for inching [% rated]*)
END_VAR
Logic
// -----------------------------------------------------------------------------
// init
// -----------------------------------------------------------------------------
io.bError := FALSE;
fbSelectTool.Enable := FALSE;
fbSetUserFrame.Enable := FALSE;
fbJogAxis.Enable := FALSE;
fbJogTcp.Enable := FALSE;
fbMoveAxisRel.Enable := FALSE;
fbMoveLinRel.Enable := FALSE;
fbMoveAxisAbsolute.Enable := FALSE;
fbMoveLinearAbsolute.Enable := FALSE;
fbStop.Enable := FALSE;
fbIdleTime.IN := FALSE;
fbCoastTime.IN := FALSE;
MEMUtils.MemSet(
pbyBuffer := ADR(fbJogAxis.Directions),
byValue := 0,
dwSize := SIZEOF(fbJogAxis.Directions));
MEMUtils.MemSet(
pbyBuffer := ADR(fbJogTcp.Directions),
byValue := 0,
dwSize := SIZEOF(fbJogTcp.Directions));
MEMUtils.MemSet(
pbyBuffer := ADR(fbMoveAxisRel.DeltaPosition),
byValue := 0,
dwSize := SIZEOF(fbMoveAxisRel.DeltaPosition));
MEMUtils.MemSet(
pbyBuffer := ADR(fbMoveLinRel.DeltaPosition),
byValue := 0,
dwSize := SIZEOF(fbMoveLinRel.DeltaPosition));
// -----------------------------------------------------------------------------
// common
// -----------------------------------------------------------------------------
// set jogging mode as default
MLX.JoggingMode := io.bEnableManualMode;
// jog speed
io.fSpeed := LIMIT(0.1, io.fSpeed, 100);
// detect changes
bMlxNumberChanged := (io.nMlxNumber <> nMlxNumberSelected);
bRobotNumberChanged := (io.nRobotNumber <> nRobotNumberSelected);
bJogTypeChanged := (io.nJogType <> nJogTypeSelected);
bCoordFrameChanged := (io.nCoordFrame <> nCoordFrameSelected);
bToolChanged := (io.nTool <> nToolSelected);
bUserFrameChanged := (io.nUserFrame <> nUserFrameSelected);
IF bMlxNumberChanged OR
bRobotNumberChanged OR
bToolChanged OR
bUserFrameChanged THEN
bTcpSettingsNeedUpdate := TRUE;
END_IF;
// -----------------------------------------------------------------------------
// jog buttons to directions pos: 1, neg: -1
// -----------------------------------------------------------------------------
bJogPressed := FALSE;
bRunJog := FALSE;
bUseRotSpeed := FALSE;
FOR i := 0 TO 5 DO
aDirections[i] := 0;
IF io.aJogRobotAxisPos[i] OR io.aJogRobotAxisNeg[i] THEN
bJogPressed := TRUE;
END_IF;
IF io.aJogRobotAxisPos[i] AND NOT io.aJogRobotAxisNeg[i] THEN
aDirections[i] := 1;
bRunJog := TRUE;
IF (nJogTypeSelected = JOGTYPE_TCP) AND (i >= 3) THEN // TCP rotation?
bUseRotSpeed := TRUE;
END_IF;
ELSIF NOT io.aJogRobotAxisPos[i] AND io.aJogRobotAxisNeg[i] THEN
aDirections[i] := -1;
bRunJog := TRUE;
IF (nJogTypeSelected = JOGTYPE_TCP) AND (i >= 3) THEN // TCP rotation?
bUseRotSpeed := TRUE;
END_IF;
END_IF;
END_FOR;
//block other axis when rotating the TCP
IF bUseRotSpeed THEN
aDirections[0] := 0;
aDirections[1] := 0;
aDirections[2] := 0;
END_IF;
bOsrRunJog := bRunJog AND NOT aOneShots[0];
aOneShots[0] := bRunJog;
// -----------------------------------------------------------------------------
// state machine 1: manual motion
// -----------------------------------------------------------------------------
CASE io.nSmManualMotion OF
// -------------------------------------
// idle, not ready for jog
// -------------------------------------
0:
IF io.bSystemReady AND io.bEnableManualMode THEN
io.nErrorCode := 0;
bTcpSettingsNeedUpdate := TRUE;
io.nSmManualMotion := 10;
END_IF;
// -------------------------------------
// ready for jog
// -------------------------------------
10:
nMlxNumberSelected := io.nMlxNumber;
nRobotNumberSelected := io.nRobotNumber;
nJogTypeSelected := io.nJogType;
nCoordFrameSelected := io.nCoordFrame;
IF bOsrRunJog OR io.bMoveTo THEN
io.nSmManualMotion := 11;
END_IF;
IF NOT io.bEnableManualMode OR NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// jog selection
// -------------------------------------
11:
nMlxNumberSelected := io.nMlxNumber;
nRobotNumberSelected := io.nRobotNumber;
nJogTypeSelected := io.nJogType;
nCoordFrameSelected := io.nCoordFrame;
IF bRunJog THEN
// jog axis
IF (nJogTypeSelected = JOGTYPE_AXIS) THEN
IF (io.bInchingMode) THEN
io.nSmManualMotion := 25;
ELSE
io.nSmManualMotion := 20;
END_IF;
END_IF;
// jog cartesian
IF (nJogTypeSelected = JOGTYPE_TCP) THEN
IF bTcpSettingsNeedUpdate THEN
io.nSmManualMotion := 15;
ELSE
IF (io.bInchingMode) THEN
io.nSmManualMotion := 35;
ELSE
io.nSmManualMotion := 30;
END_IF;
END_IF;
END_IF;
ELSIF io.bMoveTo THEN
IF bTcpSettingsNeedUpdate THEN
io.nSmManualMotion := 15;
ELSE
io.nSmManualMotion := 40;
END_IF;
ELSE
io.nSmManualMotion := 10;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// update TCP settings
// -------------------------------------
15:
IF bUpdateSettingsDone THEN
IF (io.bInchingMode) THEN
io.nSmManualMotion := 35;
ELSIF io.bMoveTo THEN
io.nSmManualMotion := 40;
ELSE
io.nSmManualMotion := 30;
END_IF;
END_IF;
IF bRobotNumberChanged OR bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// jog axis with MLxRobotJogAxes
// -------------------------------------
20:
FOR i := 0 TO 5 DO
fbJogAxis.Directions[i] := aDirections[i];
END_FOR;
fbJogAxis.Enable := TRUE;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF (fbJogAxis.Sts_EN AND fbJogAxis.Sts_ER) OR (fbJogAxis.Sts_EN AND fbJogAxis.Sts_DN AND bRobotNumberChanged) OR bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSIF fbJogAxis.Sts_EN AND fbJogAxis.Sts_DN THEN
io.nSmManualMotion := 21;
END_IF;
// -------------------------------------
// jog axis - idle time
// -------------------------------------
21:
fbIdleTime.IN := TRUE;
fbCoastTime.IN := TRUE;
IF fbIdletime.Q THEN
IF NOT bRunJog OR
NOT io.bEnableManualMode OR
bJogTypeChanged THEN
io.nSmManualMotion := 22;
ELSE
io.nSmManualMotion := 11;
END_IF;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// jog axis - coasting
// -------------------------------------
22:
fbCoastTime.IN := TRUE;
IF fbCoastTime.Q THEN
io.nSmManualMotion := 50;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// inch axis with MLxRobotMoveAxisRelative
// -------------------------------------
25:
FOR i := 0 TO 5 DO
fbMoveAxisRel.DeltaPosition[i] :=
(INCHING_DIST_AXIS * SINT_TO_REAL(aDirections[i]));
END_FOR;
MLX.JoggingMode := FALSE;
fbMoveAxisRel.Enable := TRUE;
IF fbMoveAxisRel.Sts_EN AND fbMoveAxisRel.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF fbMoveAxisRel.Sts_ER OR bRobotNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSIF fbMoveAxisRel.Sts_PC THEN
io.nSmManualMotion := 50;
END_IF;
END_IF;
IF bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
END_IF;
// -------------------------------------
// jog TCP with MLxRobotJogTCP
// -------------------------------------
30:
FOR i := 0 TO 5 DO
fbJogTcp.Directions[i] := aDirections[i];
END_FOR;
fbJogTcp.Enable := TRUE;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF (fbJogTcp.Sts_EN AND fbJogTcp.Sts_ER) OR (fbJogTcp.Sts_EN AND fbJogTcp.Sts_DN AND bRobotNumberChanged) OR bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSIF fbJogTcp.Sts_EN AND fbJogTcp.Sts_DN THEN
io.nSmManualMotion := 31;
END_IF;
// -------------------------------------
// jog TCP - idle time
// -------------------------------------
31:
fbIdleTime.IN := TRUE;
fbCoastTime.IN := TRUE;
IF fbIdletime.Q THEN
IF NOT bRunJog OR
NOT io.bEnableManualMode OR
bJogTypeChanged OR
bCoordFrameChanged OR
bToolChanged THEN
io.nSmManualMotion := 32;
ELSE
io.nSmManualMotion := 11;
END_IF;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// jog TCP - coasting
// -------------------------------------
32:
fbCoastTime.IN := TRUE;
IF fbCoastTime.Q THEN
io.nSmManualMotion := 50;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// inch TCP with MLxRobotMoveLinearRelative
// -------------------------------------
35:
FOR i := 0 TO 5 DO
fbMoveLinRel.DeltaPosition.TCPPosition[i] :=
(INCHING_DIST_TCP * SINT_TO_REAL(aDirections[i]));
END_FOR;
MLX.JoggingMode := FALSE;
fbMoveLinRel.Enable := TRUE;
IF fbMoveLinRel.Sts_EN AND fbMoveLinRel.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF fbMoveLinRel.Sts_ER OR bRobotNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSIF fbMoveLinRel.Sts_PC THEN
io.nSmManualMotion := 50;
END_IF;
END_IF;
IF bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
END_IF;
// -------------------------------------
// jog to point - copy target data
// -------------------------------------
40:
IF io.bTargetType THEN
MEMUtils.MemCpy(pbyDest := ADR(stTargetPoint.TCPPosition.TCPPosition),
pbySrc := ADR(io.aTargetPosition),
dwSize := SIZEOF(io.aTargetPosition));
ELSE
MEMUtils.MemCpy(pbyDest := ADR(stTargetPoint.AxisPosition),
pbySrc := ADR(io.aTargetPosition),
dwSize := SIZEOF(io.aTargetPosition));
END_IF;
IF (nJogTypeSelected = JOGTYPE_TCP) THEN
io.nSmManualMotion := 42;
ELSE
io.nSmManualMotion := 41;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// jog to point - move axis
// -------------------------------------
41:
MLX.JoggingMode := FALSE;
fbMoveAxisAbsolute.Enable := TRUE;
IF fbMoveAxisAbsolute.Sts_EN AND fbMoveAxisAbsolute.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF fbMoveAxisAbsolute.Sts_ER OR bRobotNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSIF NOT io.bMoveTo THEN
io.nSmManualMotion := 45;
ELSIF fbMoveAxisAbsolute.Sts_PC THEN
io.nSmManualMotion := 50;
END_IF;
END_IF;
IF bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
END_IF;
// -------------------------------------
// jog to point - move linear
// -------------------------------------
42:
MLX.JoggingMode := FALSE;
fbMoveLinearAbsolute.Enable := TRUE;
IF fbMoveLinearAbsolute.Sts_EN AND fbMoveLinearAbsolute.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF fbMoveLinearAbsolute.Sts_ER OR bRobotNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSIF NOT io.bMoveTo THEN
io.nSmManualMotion := 45;
ELSIF fbMoveLinearAbsolute.Sts_PC THEN
io.nSmManualMotion := 50;
END_IF;
END_IF;
IF bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
END_IF;
// -------------------------------------
// jog to point - stop motion
// -------------------------------------
45:
fbStop.Enable := TRUE;
IF fbStop.Sts_EN AND fbStop.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
ELSIF fbMoveLinearAbsolute.Sts_ER OR bRobotNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
ELSE
io.nSmManualMotion := 46;
END_IF;
END_IF;
IF bMlxNumberChanged THEN
io.nErrorCode := 1000 + io.nSmManualMotion;
io.nSmManualMotion := 99;
END_IF;
// -------------------------------------
// jog to point - coasting
// -------------------------------------
46:
fbCoastTime.IN := TRUE;
IF fbCoastTime.Q THEN
io.nSmManualMotion := 50;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// done
// -------------------------------------
50:
IF NOT bJogPressed AND NOT io.bMoveTo THEN
IF io.bSystemReady AND io.bEnableManualMode THEN
io.nSmManualMotion := 10;
ELSE
io.nSmManualMotion := 0;
END_IF;
END_IF;
IF NOT io.bSystemReady THEN
io.nSmManualMotion := 0;
END_IF;
// -------------------------------------
// state machine error
// -------------------------------------
99:
io.bError := TRUE;
IF NOT bRunJog THEN
io.nSmManualMotion := 0;
END_IF;
ELSE
io.nSmManualMotion := 0;
END_CASE;
// -----------------------------------------------------------------------------
// reset
// -----------------------------------------------------------------------------
IF NOT MLX.Signals.MLXGatewayConnected THEN
io.nSmManualMotion := 0;
END_IF;
// -----------------------------------------------------------------------------
// outputs
// -----------------------------------------------------------------------------
io.bIdle := (io.nSmManualMotion = 0) OR (io.nSmManualMotion = 10);
bUpdateSettings := (io.nSmManualMotion = 15);
io.bDone := (io.nSmManualMotion = 50);
io.bBusy := (io.nSmManualMotion > 10) AND (io.nSmManualMotion < 50);
io.bCoasting := (io.nSmManualMotion = 22) OR (io.nSmManualMotion = 32) OR (io.nSmManualMotion = 46);
FOR i := 0 TO 5 DO
IF io.bBusy THEN
io.aJogRobotAxisNegIndicator[i] := io.aJogRobotAxisNeg[i];
io.aJogRobotAxisPosIndicator[i] := io.aJogRobotAxisPos[i];
ELSE
io.aJogRobotAxisNegIndicator[i] := FALSE;
io.aJogRobotAxisPosIndicator[i] := FALSE;
END_IF;
END_FOR;
IF io.bBusy THEN
io.bMoveToIndicator := io.bMoveTo;
ELSE
io.bMoveToIndicator := FALSE;
END_IF;
// -----------------------------------------------------------------------------
// state machine 2: settings
// -----------------------------------------------------------------------------
CASE io.nSmSettings OF
// -------------------------------------
// idle
// -------------------------------------
0:
IF bUpdateSettings OR
(bTcpSettingsNeedUpdate AND io.bSystemReady AND io.bEnableManualMode AND io.bIdle) THEN
io.nErrorCode := 0;
io.nSmSettings := 10;
END_IF;
// -------------------------------------
// select tool
// -------------------------------------
10:
// init
MEMUtils.MemSet(
pbyBuffer := ADR(fbSelectTool.ToolData),
byValue := 0,
dwSize := SIZEOF(fbSelectTool.ToolData));
fbSelectTool.RobotNumber := io.nRobotNumber;
fbSelectTool.ToolNumber := io.nTool;
fbSelectTool.Enable := TRUE;
IF fbSelectTool.Sts_EN AND fbSelectTool.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmSettings := 0;
ELSIF fbSelectTool.Sts_ER THEN
io.nErrorCode := 2000 + io.nSmSettings;
io.nSmSettings := 99;
ELSE
nToolSelected := io.nTool;
io.nSmSettings := 20;
END_IF;
END_IF;
// -------------------------------------
// set user frame
// -------------------------------------
20:
// init
MEMUtils.MemSet(
pbyBuffer := ADR(fbSetUserFrame.UserFrameData),
byValue := 0,
dwSize := SIZEOF(fbSetUserFrame.UserFrameData));
fbSetUserFrame.UserFrameData.CoordFrame :=
userFrames.aFrames[io.nUserFrame].aVector;
fbSetUserFrame.RobotNumber := io.nRobotNumber;
fbSetUserFrame.UserFrameNumber := io.nUserFrame;
fbSetUserFrame.Enable := TRUE;
IF fbSetUserFrame.Sts_EN AND fbSetUserFrame.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmSettings := 0;
ELSIF fbSetUserFrame.Sts_ER THEN
io.nErrorCode := 2000 + io.nSmSettings;
io.nSmSettings := 99;
ELSE
nUserFrameSelected := io.nUserFrame;
io.nSmSettings := 30;
END_IF;
END_IF;
// -------------------------------------
// zero-distance motion with MLxRobotMoveAxisRelative (updates actual position)
// -------------------------------------
30:
// init
MEMUtils.MemSet(
pbyBuffer := ADR(fbMoveAxisRel.DeltaPosition),
byValue := 0,
dwSize := SIZEOF(fbMoveAxisRel.DeltaPosition));
MLX.JoggingMode := FALSE;
fbMoveAxisRel.Enable := TRUE;
IF fbMoveAxisRel.Sts_EN AND fbMoveAxisRel.Sts_DN THEN
IF NOT io.bSystemReady THEN
io.nSmSettings := 0;
ELSIF fbMoveAxisRel.Sts_ER THEN
io.nErrorCode := 2000 + io.nSmSettings;
io.nSmSettings := 99;
ELSIF fbMoveAxisRel.Sts_PC THEN
nUserFrameSelected := io.nUserFrame;
io.nSmSettings := 50;
END_IF;
END_IF;
// -------------------------------------
// done
// -------------------------------------
50:
bTcpSettingsNeedUpdate := FALSE;
IF NOT bUpdateSettings OR NOT io.bSystemReady THEN
io.nSmSettings := 0;
END_IF;
// -------------------------------------
// state machine error
// -------------------------------------
99:
io.bError := TRUE;
io.nSmSettings := 0;
ELSE
io.nSmSettings := 0;
END_CASE;
// -----------------------------------------------------------------------------
// reset
// -----------------------------------------------------------------------------
IF NOT MLX.Signals.MLXGatewayConnected THEN
io.nSmSettings := 0;
END_IF;
// -----------------------------------------------------------------------------
// outputs
// -----------------------------------------------------------------------------
bUpdateSettingsDone := (io.nSmSettings = 50);
// -----------------------------------------------------------------------------
// FB calls
// -----------------------------------------------------------------------------
fbIdleTime(PT:=io.tIdleTime);
fbCoastTime(PT:=io.tCoastTime);
fbSelectTool( MLX := MLX );
fbSetUserFrame( MLX := MLX );
fbStop( MLX := MLX );
fbJogAxis(
RobotNumber := nRobotNumberSelected,
Speed := io.fSpeed,
MLX:= MLX);
fbJogTcp(
RobotNumber := nRobotNumberSelected,
Speed := io.fSpeed,
UseRotationalSpeed := bUseRotSpeed,
SpeedUnits := 0,
CoordFrame := nCoordFrameSelected,
MLX := MLX);
fbMoveAxisRel(
RobotNumber := nRobotNumberSelected,
BlendFactor := INCHING_BF,
BlendType := 0,
Speed := INCHING_SPEED,
Acceleration := INCHING_ACC_DEC,
Deceleration := INCHING_ACC_DEC,
MLX := MLX);
fbMoveLinRel(
RobotNumber := nRobotNumberSelected,
BlendFactor := INCHING_BF,
BlendType := 0,
Speed := INCHING_SPEED,
UseRotationalSpeed := bUseRotSpeed,
SpeedUnits := 0,
Acceleration := INCHING_ACC_DEC,
Deceleration := INCHING_ACC_DEC,
CoordFrame := nCoordFrameSelected,
MLX := MLX);
fbMoveAxisAbsolute(
RobotNumber := nRobotNumberSelected,
TargetPosition := stTargetPoint,
TargetType := io.bTargetType,
BlendFactor := JOG_TO_BF,
BlendType := 0,
Speed := io.fSpeed * 0.03,
Acceleration := io.nAcc,
Deceleration := io.nDec,
MLX := MLX
);
fbMoveLinearAbsolute(
RobotNumber := nRobotNumberSelected,
TargetPosition := stTargetPoint,
TargetType := io.bTargetType,
BlendFactor := JOG_TO_BF,
BlendType := 0,
Speed := io.fSpeed * 0.1,
UseRotationalSpeed := io.bUseRotationalSpeed,
SpeedUnits := 0,
Acceleration := io.nAcc,
Deceleration := io.nDec,
MLX := MLX);
Implementation
fbManualMotion : ARRAY[0..0] OF MceManualMotion;
fbManualMotion[0]( io := dummy, userFrames := dummy, MLX := dummy );