Motion commands
Send linear, joint, and circular motion commands with configurable speed, termination type, and acceleration via RMI.
RMI lets you send TP-equivalent motion instructions to the robot. Each call to SendTpInstruction() returns an RmiInstructionResponse that tracks the instruction through its execution lifecycle.
Linear motion
Move the robot in a straight line to a Cartesian target:
robot.Connect(parameters);robot.Rmi.Initialize();// Linear motion to a Cartesian target (tool 1, frame 0)var move = new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 100,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, tool: 1, frame: 0)};robot.Rmi.SendTpInstruction(move).WaitForCompletion();// Incremental linear motion (delta from current position)var inc = new LinearRelativeTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 50,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(0, 0, -50, 0, 0, 0, 1, 0)};robot.Rmi.SendTpInstruction(inc).WaitForCompletion();// Linear motion with joint-angle target representationvar jrep = new LinearMotionJRepTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 80,TermType = RmiTerminationType.Fine,Joints = new JointsPosition(10, -20, 30, 0, 60, 0)};robot.Rmi.SendTpInstruction(jrep).WaitForCompletion();// CNT blending: chain motions without stoppingvar p1 = new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 200,TermType = RmiTerminationType.Cnt,TermValue = 100,Target = new CartesianPositionWithUserFrame(600, 0, 400, 0, 90, 0, 1, 0)};var p2 = new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 200,TermType = RmiTerminationType.Fine, // last motion must be Fine (or NoBlend = true)Target = new CartesianPositionWithUserFrame(700, 0, 350, 0, 90, 0, 1, 0)};robot.Rmi.SendTpInstruction(p1);robot.Rmi.SendTpInstruction(p2).WaitForCompletion();robot.Rmi.Abort();robot.Disconnect();
Speed types for linear motion
RmiLinearSpeedType | Description |
|---|---|
MmSec | Millimeters per second. |
InchMin | Inches per minute (0.1 in/min units). |
Time | Duration in 0.1-second steps. |
MSec | Duration in milliseconds. |
Termination types
RmiTerminationType | Description |
|---|---|
Fine | Stop precisely at the target. |
Cnt | Continuous blending with the next motion (value 1-100). The last motion sent must be Fine unless NoBlend = true. |
Cr | Corner region (requires Advanced Constant Path option). |
Joint motion
Move using joint interpolation (Cartesian target or joint-angle target):
robot.Connect(parameters);robot.Rmi.Initialize();// Joint motion with Cartesian target, percent speedvar cart = new JointMotionTpInstruction{SpeedType = RmiJointSpeedType.Percent,Speed = 10,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, tool: 1, frame: 0)};robot.Rmi.SendTpInstruction(cart).WaitForCompletion();// Joint motion with joint-angle target representationvar jrep = new JointMotionJRepTpInstruction{SpeedType = RmiJointSpeedType.Percent,Speed = 5,TermType = RmiTerminationType.Fine,Joints = new JointsPosition(10, -20, 30, 0, 60, 0)};robot.Rmi.SendTpInstruction(jrep).WaitForCompletion();// Incremental joint motion (joint-angle delta)var relJrep = new JointRelativeJRepTpInstruction{SpeedType = RmiJointSpeedType.Percent,Speed = 5,TermType = RmiTerminationType.Fine,Joints = new JointsPosition(0, 0, 0, 0, 5, 0) // rotate J5 by 5 degrees};robot.Rmi.SendTpInstruction(relJrep).WaitForCompletion();robot.Rmi.Abort();robot.Disconnect();
Speed types for joint motion
RmiJointSpeedType | Description |
|---|---|
Percent | Percentage of maximum joint speed (1-100). |
Time | Duration in 0.1-second steps. |
MSec | Duration in milliseconds. |
Circular motion
Circular motion requires a via point and a destination:
robot.Connect(parameters);robot.Rmi.Initialize();// Circular motion: define a via-point and a destinationvar arc = new CircularMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 80,TermType = RmiTerminationType.Fine,Via = new CartesianPositionWithUserFrame(600, 100, 350, 0, 90, 0, tool: 1, frame: 0),Target = new CartesianPositionWithUserFrame(700, 0, 300, 0, 90, 0, tool: 1, frame: 0)};robot.Rmi.SendTpInstruction(arc).WaitForCompletion();// Incremental circular motion (via and target are deltas)var arcRel = new CircularRelativeTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 60,TermType = RmiTerminationType.Fine,Via = new CartesianPositionWithUserFrame(50, 50, 0, 0, 0, 0, 1, 0),Target = new CartesianPositionWithUserFrame(100, 0, 0, 0, 0, 0, 1, 0)};robot.Rmi.SendTpInstruction(arcRel).WaitForCompletion();robot.Rmi.Abort();robot.Disconnect();
Spline motion
Spline motion requires firmware MajorVersion >= 7 (V9.40P/54 or later). The controller needs at least one more spline instruction after the first to start executing the segment.
robot.Connect(parameters);robot.Rmi.Initialize();// Spline motion requires MajorVersion >= 7 (firmware V9.40P/54 or later).// The controller will not execute the first spline segment until it receives// a second instruction (motion or non-motion) after the last spline point.robot.Rmi.SendTpInstruction(new SplineMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 200,TermType = RmiTerminationType.Cnt,TermValue = 100,Target = new CartesianPositionWithUserFrame(500, 100, 300, 0, 90, 0, 1, 0)});robot.Rmi.SendTpInstruction(new SplineMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 200,TermType = RmiTerminationType.Cnt,TermValue = 100,Target = new CartesianPositionWithUserFrame(550, 200, 320, 0, 90, 0, 1, 0)});robot.Rmi.SendTpInstruction(new SplineMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 200,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(600, 100, 300, 0, 90, 0, 1, 0)});// Send a non-spline instruction to flush the spline buffer and trigger executionrobot.Rmi.SendTpInstruction(new WaitTimeTpInstruction { Seconds = 0.1 }).WaitForCompletion();// Spline with joint-angle representationrobot.Rmi.SendTpInstruction(new SplineMotionJRepTpInstruction{SpeedType = RmiJointSpeedType.Percent,Speed = 50,TermType = RmiTerminationType.Cnt,TermValue = 100,Joints = new JointsPosition(10, -20, 30, 0, 60, 0)});robot.Rmi.SendTpInstruction(new SplineMotionJRepTpInstruction{SpeedType = RmiJointSpeedType.Percent,Speed = 50,TermType = RmiTerminationType.Fine,Joints = new JointsPosition(15, -15, 35, 5, 55, 5)});robot.Rmi.SendTpInstruction(new WaitTimeTpInstruction { Seconds = 0.1 }).WaitForCompletion();robot.Rmi.Abort();robot.Disconnect();
Relative (incremental) motions
All motion types have incremental variants. The position is a delta from the current robot position:
| Absolute | Incremental |
|---|---|
LinearMotionTpInstruction | LinearRelativeTpInstruction |
JointMotionTpInstruction | JointRelativeTpInstruction |
CircularMotionTpInstruction | CircularRelativeTpInstruction |
LinearMotionJRepTpInstruction | LinearRelativeJRepTpInstruction |
JointMotionJRepTpInstruction | JointRelativeJRepTpInstruction |
Motion options
Most instruction classes expose optional motion modifiers:
| Property | Type | Description |
|---|---|---|
Acc | byte? | Acceleration override (20-100 %). |
OffsetPrNumber | short? | Offset position register number. |
ToolOffsetPrNumber | short? | Tool offset PR number (MajorVersion >= 4). |
VisionPrNumber | short? | Vision offset register number. |
WristJoint | bool | Enable wrist-joint mode (linear and circular only). |
Mrot | bool | MROT option - requires WristJoint and R640 option. |
NoBlend | bool | Allow CNT motion to execute without waiting for the next instruction (MajorVersion >= 5). |
Alim | int? | Acceleration limit in mm/s² (MajorVersion >= 5, R921 option). |
AlimReg | short? | Register-based acceleration limit (MajorVersion >= 5, R921 option). |
LcbType | string | Local Condition Block type: "TB", "TA", or "DB". |
LcbValue | short? | LCB value (ms for TA/TB, 0.01 mm for DB). |
PortType | RmiPortType? | Output port type (DOUT or ROUT) triggered by LCB. |
PortNumber | short? | LCB output port number. |
PortValue | RmiOnOff? | LCB output port value (ON or OFF). |
Non-motion instructions
Insert wait conditions, frame changes, and program calls between motions:
robot.Connect(parameters);robot.Rmi.Initialize();// Wait for digital input DI[1] to turn ON before continuingrobot.Rmi.SendTpInstruction(new WaitDinTpInstruction{PortNumber = 1,Value = RmiOnOff.ON});// Wait 0.5 secondsrobot.Rmi.SendTpInstruction(new WaitTimeTpInstruction { Seconds = 0.5 });// Switch to UFRAME 2 for the next motionsrobot.Rmi.SendTpInstruction(new SetUFrameTpInstruction { FrameNumber = 2 });// Switch to UTOOL 3robot.Rmi.SendTpInstruction(new SetUToolTpInstruction { ToolNumber = 3 });// Activate payload schedule 1robot.Rmi.SendTpInstruction(new SetPayloadTpInstruction { ScheduleNumber = 1 });// Call a TP program (requires MajorVersion >= 4)robot.Rmi.SendTpInstruction(new CallProgramTpInstruction { ProgramName = "GRIPPER_OPEN" }).WaitForCompletion();robot.Rmi.Abort();robot.Disconnect();
Tracking instruction status
robot.Connect(parameters);robot.Rmi.Initialize();// Send several instructions. Each returns immediately.for (int i = 0; i < 5; i++){var instr = new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 100,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(500 + i * 20, 200, 300, 0, 90, 0, 1, 0)};RmiInstructionResponse r = robot.Rmi.SendTpInstruction(instr);// Subscribe to status changesr.StatusChanged += status =>Console.WriteLine($" Seq {r.SequenceId}: {status}");}// Wait for all instructions to completeforeach (RmiInstructionResponse r in robot.Rmi.Instructions)r.WaitForCompletion();// Print final resultsforeach (RmiInstructionResponse r in robot.Rmi.Instructions){if (r.Status == RmiInstructionStatus.Error)Console.WriteLine($" Seq {r.SequenceId} failed: {r.ErrorText}");elseConsole.WriteLine($" Seq {r.SequenceId} completed OK");}// Remove completed instructions from the tracking listrobot.Rmi.ClearCompletedInstructions();robot.Rmi.Abort();robot.Disconnect();
Complete example
using System;using UnderAutomation.Fanuc;using UnderAutomation.Fanuc.Common;using UnderAutomation.Fanuc.Rmi.Data;using UnderAutomation.Fanuc.Rmi.TpInstructions;public class RmiMotion{static void Main(){FanucRobot robot = new FanucRobot();ConnectionParameters parameters = new ConnectionParameters("192.168.0.1");parameters.Rmi.Enable = true;robot.Connect(parameters);// Check statusRmiControllerStatusResponse status = robot.Rmi.GetStatus();if (status.TPEnabled){Console.WriteLine("Turn off the teach pendant before proceeding.");return;}if (!status.ServoReady){Console.WriteLine("Servos are not ready.");return;}// Initialize RMI_MOVErobot.Rmi.Initialize();// Set speed overriderobot.Rmi.SetOverride(80);// Move to a start positionrobot.Rmi.SendTpInstruction(new JointMotionJRepTpInstruction{SpeedType = RmiJointSpeedType.Percent,Speed = 10,TermType = RmiTerminationType.Fine,Joints = new JointsPosition(0, 0, 0, 0, 0, 0)}).WaitForCompletion();// Approachrobot.Rmi.SendTpInstruction(new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 200,TermType = RmiTerminationType.Cnt,TermValue = 50,Target = new CartesianPositionWithUserFrame(500, 200, 350, 0, 90, 0, 1, 0)});// Descend to pick positionrobot.Rmi.SendTpInstruction(new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 50,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, 1, 0)}).WaitForCompletion();// Activate gripperrobot.Rmi.SendTpInstruction(new CallProgramTpInstruction { ProgramName = "GRIP_ON" }).WaitForCompletion();// Retractrobot.Rmi.SendTpInstruction(new LinearMotionTpInstruction{SpeedType = RmiLinearSpeedType.MmSec,Speed = 100,TermType = RmiTerminationType.Fine,Target = new CartesianPositionWithUserFrame(500, 200, 400, 0, 90, 0, 1, 0)}).WaitForCompletion();// Check HOLD stateif (robot.Rmi.IsInHoldState){Console.WriteLine("Controller in HOLD. Calling Reset...");robot.Rmi.Reset();}robot.Rmi.Abort();robot.Disconnect();}}
API reference
Instruction for a linear motion (L in TP), Cartesian target representation. Pass to SendTpInstruction(RmiInstructionBase).
| Member | Type | Description |
|---|---|---|
LinearMotionTpInstruction() Constructor | ||
Alim Property | int? | Acceleration limit value. null uses the controller default. Requires MajorVersion >= 5 and the R921 option. |
AlimReg Property | short? | Acceleration limit register number. null disables register-based limit. Requires MajorVersion >= 5 and the R921 option. |
Mrot Property | bool | When true, enables coordinated motion (MROT). |
NoBlend Property | bool | When true, disables blending with the next instruction. Requires MajorVersion >= 5. |
SpeedType Property | RmiLinearSpeedType | Speed unit (mm/s, inch/min, or time). |
WristJoint Property | bool | When true, enables wrist-joint mode for this motion. |
Instruction for a joint motion (J in TP), Cartesian target representation. Pass to SendTpInstruction(RmiInstructionBase).
| Member | Type | Description |
|---|---|---|
JointMotionTpInstruction() Constructor | ||
Mrot Property | bool | When true, enables coordinated motion (MROT). |
NoBlend Property | bool | When true, disables blending with the next instruction. |
SpeedType Property | RmiJointSpeedType | Speed unit (percent override or time). |
Instruction for a joint motion (J in TP), joint-angle representation, full options. Pass to SendTpInstruction(RmiInstructionBase).
| Member | Type | Description |
|---|---|---|
JointMotionJRepTpInstruction() Constructor | ||
Mrot Property | bool | When true, enables coordinated motion (MROT). |
NoBlend Property | bool | When true, disables blending with the next instruction. |
SpeedType Property | RmiJointSpeedType | Speed unit (percent override or time). |
Instruction for a circular motion (C in TP), Cartesian target representation. Pass to SendTpInstruction(RmiInstructionBase).
| Member | Type | Description |
|---|---|---|
CircularMotionTpInstruction() Constructor | ||
Mrot Property | bool | When true, enables coordinated motion (MROT). |
NoBlend Property | bool | When true, disables blending with the next instruction. |
SpeedType Property | RmiLinearSpeedType | Speed unit (mm/s, inch/min, or time). |
Via Property | CartesianPositionWithUserFrame | Via-point Cartesian position that defines the arc. |
WristJoint Property | bool | When true, enables wrist-joint mode for this motion. |
Instruction for a spline motion with a Cartesian target. Pass to SendTpInstruction(RmiInstructionBase). Requires MajorVersion >= 7.
| Member | Type | Description |
|---|---|---|
SplineMotionTpInstruction() Constructor | ||
SpeedType Property | RmiLinearSpeedType | Speed unit (mm/s, inch/min, or time). |
Extends MotionTpInstructionBase with the full set of optional motion modifiers shared by all non-simplified instruction types.
| Member | Type | Description |
|---|---|---|
FullMotionTpInstructionBase() Constructor | ||
Acc Property | byte? | Optional acceleration override (1-100 %). null uses the controller default. |
LcbType Property | string | Lock-and-continue (LCB) condition type string. null disables LCB. |
LcbValue Property | short? | Lock-and-continue (LCB) condition value. Required when LcbType is set. |
OffsetPrNumber Property | short? | Offset position register number. null disables offset. |
PortNumber Property | short? | Digital output port number. Required when PortType is set. |
PortType Property | RmiPortType? | Digital output port type to trigger at the end of this motion. null disables output. |
PortValue Property | RmiOnOff? | Digital output port value. Required when PortType is set. |
ToolOffsetPrNumber Property | short? | Tool-offset position register number. null disables tool offset. Requires MajorVersion >= 4. |
VisionPrNumber Property | short? | Vision offset position register number. null disables vision offset. |
Response returned immediately when a motion instruction is queued. The Status property and ErrorId are updated in the background as the controller processes the instruction. Use WaitForCompletion(int) to block until the instruction reaches a terminal state.
| Member | Type | Description |
|---|---|---|
RmiInstructionResponse() Constructor | ||
Instruction Property read only | RmiInstructionBase | Sent instruction |
SequenceId Property read only | int | Sequence identifier assigned to this instruction. 0 until the instruction has been dispatched to the controller. |
Status Property read only | RmiInstructionStatus | Current execution state of the instruction. |
StatusChanged Event | Action<RmiInstructionStatus> | Fired each time Status changes. The argument is the new status value. This event may be raised from a background thread. |
Equals(object) Method | bool | |
GetHashCode() Method | int | |
ToString() Method | string | |
WaitForCompletion(int) Method | bool | Blocks the calling thread until the instruction reaches a terminal state ( Completed or Error), or until timeoutMs milliseconds have elapsed. Pass -1 (or omit) to wait indefinitely.
|