UnderAutomation
質問ですか?

[email protected]

お問い合わせ
UnderAutomation
⌘Q
Fanuc SDK documentation
Diagnostics & variables
Documentation home

RMI overview

RMI (Remote Motion Interface) is a TCP-based protocol for sending motion commands, managing frames, and controlling the robot remotely.

RMI (Remote Motion Interface) is a TCP-based protocol that lets you send TP-equivalent motion instructions and administrative commands to a Fanuc controller in real time.

Robot requirements

  • Option R912 (Remote Motion Interface) must be loaded on the controller.
  • The bootstrap port is 16001 (TCP).
  • Before calling Initialize(), the teach pendant must be disabled and the controller must be in AUTO mode.
  • Do not leave the RMI_MOVE TP program selected on the teach pendant before calling Initialize().

How it works

  1. Connect to the controller on the bootstrap port (16001). The controller assigns a working port for the session.
  2. Call Initialize() to create the RMI_MOVE TP program and start it.
  3. Send motion or non-motion instructions via SendTpInstruction(). Each call returns an RmiInstructionResponse you can track.
  4. The client manages the 8-slot controller buffer automatically. Instructions beyond that limit are held locally and sent as soon as a slot is free.
  5. When done, call Abort() or Disconnect(). Always end your session with one of those; otherwise the controller keeps RMI_MOVE selected and other TP programs cannot run.

Quick example

// Initialize the RMI_MOVE program on the controller.
// TP must be disabled and the controller must be in AUTO mode.
robot.Rmi.Initialize();
// Linear motion at 100 mm/s to a Cartesian target (tool 1, frame 0)
var instr = new LinearMotionTpInstruction
{
SpeedType = RmiLinearSpeedType.MmSec,
Speed = 100,
TermType = RmiTerminationType.Fine,
Target = new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, tool: 1, frame: 0)
};
RmiInstructionResponse r = robot.Rmi.SendTpInstruction(instr);
// Wait for the controller to confirm the motion completed
r.WaitForCompletion();
if (r.Status == RmiInstructionStatus.Error)
System.Console.WriteLine("Error: " + r.ErrorText);
// Abort when done — always end the session with Abort() or Disconnect()
robot.Rmi.Abort();
robot.Disconnect();

Connection

// Enable RMI and connect. The bootstrap port is 16001.
// The controller assigns a working port automatically.
ConnectionParameters parameters = new ConnectionParameters("192.168.0.1");
parameters.Rmi.Enable = true;
robot.Connect(parameters);
System.Console.WriteLine("Connected: " + robot.Rmi.Connected);
System.Console.WriteLine("Protocol version: " + robot.Rmi.MajorVersion + "." + robot.Rmi.MinorVersion);
System.Console.WriteLine("Working port: " + robot.Rmi.WorkingPort);
// Subscribe to events before sending instructions
robot.Rmi.SystemFaultReceived += seqId =>
System.Console.WriteLine("System fault on sequence " + seqId);
robot.Rmi.ConnectionTerminated += () =>
System.Console.WriteLine("Controller closed the RMI session");
robot.Rmi.RecordedCartesianPositionReceived += pos =>
System.Console.WriteLine("Recorded position " + pos.PositionId);
robot.Disconnect();

Initialize and status

Call Initialize() after connecting. Check the controller state with GetStatus() first if needed.

// Check controller state before initializing
RmiControllerStatusResponse status = robot.Rmi.GetStatus();
System.Console.WriteLine("Servo ready: " + status.ServoReady);
System.Console.WriteLine("TP enabled: " + status.TPEnabled);
System.Console.WriteLine("RMI running: " + status.RmiMotionStatus);
// Initialize: creates and starts the RMI_MOVE TP program.
// Will throw if TP is enabled or servos are off.
robot.Rmi.Initialize();
// For multi-group controllers, specify a group mask (bit N = group N+1)
// robot.Rmi.Initialize(groupMask: 0b00000011); // groups 1 and 2
// Enable real-time singularity avoidance (requires MajorVersion >= 6, R792 option)
// robot.Rmi.Initialize(rtsa: true);
// Set palletizing motion mode (requires MajorVersion >= 7)
// robot.Rmi.Initialize(pltzMode: RmiPltzMode.ZeroDown);
System.Console.WriteLine("RMI initialized");
// The controller checks sequence IDs by default.
// AutoSetNextSequenceId() resynchronizes the counter if needed.
robot.Rmi.AutoSetNextSequenceId();
robot.Rmi.Abort();
robot.Disconnect();

Instruction pipeline

SendTpInstruction() returns an RmiInstructionResponse immediately. The instruction goes through several states:

StatusMeaning
LocalQueuedHeld in the client buffer, not yet sent (controller buffer full).
ControllerQueuedSent to the controller, waiting its turn.
ExecutingThe robot is currently executing this instruction.
CompletedDone without error.
ErrorFailed. Check ErrorId and ErrorText.

Call WaitForCompletion() to block until the instruction reaches a terminal state.

Next steps

  • Motion commands: linear, joint, circular, spline motions and non-motion instructions.
  • Frames, I/O & status: frame management, I/O, position reading, registers.

API reference

Members of Rmi.RmiClient :
public class RmiClient : RmiClientBase, IDisposable {
// Creates a new instance of the RMI client.
public RmiClient()
// Connect to the FANUC controller using the RMI protocol.
public void Connect(string ip, int port = 16001, int readTimeoutMs = 2000)
}
Members of Rmi.Internal.RmiClientBase :
public abstract class RmiClientBase : IDisposable {
// Creates a new instance of the RMI client.
public RmiClientBase()
// Abort the running motion program. Note that a Reset() will be called automatically if the controller is in the HOLD state.
public void Abort()
// Calls internally <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.GetStatus" data-throw-if-not-resolved="false"></xref> and set <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.LastSequenceId" data-throw-if-not-resolved="false"></xref> only if $RMI_CFG.$Chk_seqID = FALSE. It also set <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.CheckSequenceId" data-throw-if-not-resolved="false"></xref> to $RMI_CFG.$Chk_seqID.
public RmiControllerStatusResponse AutoSetNextSequenceId()
// Indicates whether the controller checks for consecutive sequence IDs in motion instructions ($RMI_CFG.$Chk_seqID). Modified by <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.AutoSetNextSequenceId" data-throw-if-not-resolved="false"></xref>.
public bool CheckSequenceId { get; set; }
// Removes all instructions with a terminal status (<xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Completed" data-throw-if-not-resolved="false"></xref>
// or <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Error" data-throw-if-not-resolved="false"></xref>) from the tracked instruction list.
// Instructions that are still pending or in progress are not affected.
public void ClearCompletedInstructions()
// Cancels and removes all instructions that are still in the local client buffer
// (<xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.LocalQueued" data-throw-if-not-resolved="false"></xref>). These instructions have not been sent
// to the controller yet. Each cancelled instruction is marked with an error so that any
// thread blocked on <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionResponse.WaitForCompletion(System.Int32)" data-throw-if-not-resolved="false"></xref> is unblocked.
// Instructions already sent to the controller are not affected.
public void ClearLocalQueuedInstructions()
// Connect to the controller: perform the bootstrap handshake on the given port,
// obtain the working port, then switch to it for all subsequent commands.
protected void ConnectInternal(string host, int port, int readTimeoutMs = 2000)
// Indicates that the client is currently connected to the controller working port.
public bool Connected { get; }
// Fired when the controller closes the session (e.g. communication idle timeout).
// The client is automatically disconnected after this event fires.
public event Action ConnectionTerminated
// Resume a paused motion program.
public void Continue()
// Disconnect from the controller by sending the disconnect command on the working port.
// Safe to call even when already disconnected.
public void Disconnect()
// Disconnect from the controller and release resources.
public void Dispose()
// Get extended controller status including drive power state and speed clamp.
public RmiExtendedControllerStatusResponse GetExtendedStatus()
// Get the current controller and RMI motion status.
public RmiControllerStatusResponse GetStatus()
// Get the current UFRAME and UTOOL numbers.
public RmiUFrameUToolNumbersResponse GetUFrameUTool(byte? group = null)
// Initialize RMI and start the motion program. Must be called before sending any motion instructions.
// It also Resets <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.LastSequenceId" data-throw-if-not-resolved="false"></xref> and empty the instruction buffer <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Instructions" data-throw-if-not-resolved="false"></xref>
public void Initialize(byte? groupMask = null, bool? rtsa = null, RmiPltzMode? pltzMode = null)
// All instructions submitted since the last <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Initialize(System.Nullable%7bSystem.Byte%7d%2cSystem.Nullable%7bSystem.Boolean%7d%2cSystem.Nullable%7bUnderAutomation.Fanuc.Rmi.Data.RmiPltzMode%7d)" data-throw-if-not-resolved="false"></xref> or explicit clear,
// in submission order. Includes instructions in all states: <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.LocalQueued" data-throw-if-not-resolved="false"></xref>,
// <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.ControllerQueued" data-throw-if-not-resolved="false"></xref>, <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Executing" data-throw-if-not-resolved="false"></xref>,
// <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Completed" data-throw-if-not-resolved="false"></xref> and <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Error" data-throw-if-not-resolved="false"></xref>.
// Returns a snapshot array; the array is not updated after it is returned.
public RmiInstructionResponse[] Instructions { get; }
// Indicates that the controller has entered the HOLD state and will not accept new TP instructions
// until <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Reset" data-throw-if-not-resolved="false"></xref> is called.
//
// <p>
// The HOLD state is entered in two situations:
// </p>
// <ul><li>
// An invalid sequence ID was detected (error RMIT-029, error code 2556957). RMI checks that sequence IDs are
// consecutive. If a gap is found, RMI rejects the instruction and enters HOLD. The controller continues
// executing the TP instructions already queued but blocks all new ones. Use <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.AutoSetNextSequenceId" data-throw-if-not-resolved="false"></xref>
// to recover the correct sequence ID, then call <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Reset" data-throw-if-not-resolved="false"></xref> before resuming.
// </li><li>
// An invalid motion instruction was received (error RMIT-024, error code 2556952), for example a motion
// option that is not loaded on the controller. RMI returns an error for that instruction, puts the
// controller in HOLD, and continues executing any instructions already in the TP program queue. Call
// <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Reset" data-throw-if-not-resolved="false"></xref> once the problem is corrected, then resume sending instructions.
// </li></ul>
// <p>
// All instructions sent while in the HOLD state are ignored by the controller and returned with an error code.
// This flag is cleared automatically when <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Reset" data-throw-if-not-resolved="false"></xref> succeeds.
// </p>
public bool IsInHoldState { get; }
// Sequence ID used for the last instruction sent to the controller. Reset to 0 by <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.Initialize(System.Nullable%7bSystem.Byte%7d%2cSystem.Nullable%7bSystem.Boolean%7d%2cSystem.Nullable%7bUnderAutomation.Fanuc.Rmi.Data.RmiPltzMode%7d)" data-throw-if-not-resolved="false"></xref>.. Modified by <xref href="UnderAutomation.Fanuc.Rmi.Internal.RmiClientBase.AutoSetNextSequenceId" data-throw-if-not-resolved="false"></xref>.
public int LastSequenceId { get; }
// Controller protocol major version reported during the connection handshake.
public short MajorVersion { get; }
// Controller protocol minor version reported during the connection handshake.
public short MinorVersion { get; }
// Pause the running motion program.
public void Pause()
// Read current Cartesian TCP position.
public RmiCartesianPositionResponse ReadCartesianPosition(byte? group = null)
// Read a digital input port value.
public RmiDigitalInputValueResponse ReadDIN(short portNumber)
// Read the most recent controller error text. Up to 5 consecutive errors can be requested.
public RmiControllerErrorTextResponse ReadError(byte? count = null)
// Read a generic IO port (DI, DO, AI, AO, GO, RO, FLAG, RI, UI, UO).
public RmiIoPortValueResponse ReadIOPort(RmiIoPortType portType, int portNumber)
// Read current joint angles.
public RmiJointAnglesSampleResponse ReadJointAngles(byte? group = null)
// Read a numeric register
public RmiNumericRegisterValueResponse ReadNumericRegister(int number)
// Read a position register
public RmiPositionRegisterDataResponse ReadPositionRegister(short number, byte? group = null)
// Read the current TCP speed in mm/s.
public RmiTcpSpeedResponse ReadTcpSpeed()
// RMI connection parameters used during Connect().
public int ReadTimeoutMs { get; }
// Read the UFRAME at the given index.
public RmiIndexedFrameResponse ReadUFrame(byte number, byte? group = null)
// Read the UTOOL at the given index.
public RmiIndexedFrameResponse ReadUTool(byte number, byte? group = null)
// Read a system variable by name (name must include the leading <code>$</code> character).
public RmiVariableValueResponse ReadVariable(string name)
// Fired when the controller sends a Cartesian position via the RMI Position Record menu.
public event Action<RmiRecordedCartesianPosition> RecordedCartesianPositionReceived
// Fired when the controller sends a joint position via the RMI Position Record menu.
public event Action<RmiRecordedJointPosition> RecordedJointPositionReceived
// Reset controller errors and exit the HOLD state.
public void Reset()
// Serializes the instruction to the RMI wire format and queues it on the controller.
// Returns an <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionResponse" data-throw-if-not-resolved="false"></xref> that tracks execution.
public RmiInstructionResponse SendTpInstruction(RmiInstructionBase instruction)
// Set the program speed override (1–100 %).
public void SetOverride(byte value)
// Define payload compensation parameters for a payload schedule.
public void SetPayloadCompensation(byte scheduleNumber, float massKg, float cgXm, float cgYm, float cgZm, float inertiaXkgm2, float inertiaYkgm2, float inertiaZkgm2, byte? group = null)
// Define payload compensation parameters for a payload schedule.
public void SetPayloadCompensation(RmiSetPayloadCompensationParameters p)
// Immediately apply a payload schedule to the active group (command, not an instruction).
public void SetPayloadSchedule(byte scheduleNumber, byte? group = null)
// Define payload mass, center of gravity, and optionally inertia for a payload schedule.
public void SetPayloadValue(byte scheduleNumber, float massKg, float cgXm, float cgYm, float cgZm, float? inertiaXkgm2 = null, float? inertiaYkgm2 = null, float? inertiaZkgm2 = null, byte? group = null)
// Define payload mass, center of gravity, and optionally inertia for a payload schedule.
public void SetPayloadValue(RmiSetPayloadParameters p)
// Set the current UFRAME and UTOOL numbers.
public void SetUFrameUTool(byte uframe, byte utool, byte? group = null)
// Fired when the controller reports a system fault on a given sequence.
// The argument is the SequenceID of the faulted instruction (0 when unknown).
public event Action<int> SystemFaultReceived
// Fired when an unknown packet is received from the controller.
public event Action<RmiResponseBase> UnknownPacketReceived
// Working port returned by the controller; all commands use this port after connection.
public int WorkingPort { get; }
// Write a digital output port value.
public void WriteDOUT(short portNumber, RmiOnOff value)
// Write a generic IO port (AO, GO, DO, RO, FLAG).
public void WriteIOPort(RmiIoPortType portType, int portNumber, double value)
// Write a float value to a numeric register
public void WriteNumericRegisterAsDouble(int number, double value)
// Write an integer value to a numeric register
public void WriteNumericRegisterAsInteger(int number, int value)
// Write a Cartesian position register
public void WritePositionRegisterCartesian(short number, CartesianPositionWithUserFrame target, byte? group = null)
// Write the UFRAME at the given index.
public void WriteUFrame(byte number, XYZWPRPosition position, byte? group = null)
// Write the UTOOL at the given index.
public void WriteUTool(byte number, XYZWPRPosition position, byte? group = null)
// Write a float value to a system variable (name must include the leading <code>$</code>).
public void WriteVariableAsDouble(string name, double value)
// Write an integer value to a system variable (name must include the leading <code>$</code>).
public void WriteVariableAsInteger(string name, int value)
}
Members of Rmi.Data.RmiInstructionResponse :
public class RmiInstructionResponse : RmiResponseBase {
public RmiInstructionResponse()
public override bool Equals(object obj)
public override int GetHashCode()
// Sent instruction
public RmiInstructionBase Instruction { get; }
// Sequence identifier assigned to this instruction. 0 until the instruction has been dispatched to the controller.
public int SequenceId { get; }
// Current execution state of the instruction.
public RmiInstructionStatus Status { get; }
// Fired each time <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionResponse.Status" data-throw-if-not-resolved="false"></xref> changes. The argument is the new status value.
// This event may be raised from a background thread.
public event Action<RmiInstructionStatus> StatusChanged
public override string ToString()
// Blocks the calling thread until the instruction reaches a terminal state
// (<xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Completed" data-throw-if-not-resolved="false"></xref> or <xref href="UnderAutomation.Fanuc.Rmi.Data.RmiInstructionStatus.Error" data-throw-if-not-resolved="false"></xref>),
// or until <code class="paramref">timeoutMs</code> milliseconds have elapsed.
// Pass -1 (or omit) to wait indefinitely.
public bool WaitForCompletion(int timeoutMs = -1)
}
Members of Rmi.Data.RmiControllerStatusResponse :
public class RmiControllerStatusResponse : RmiResponseBase {
public RmiControllerStatusResponse()
// Indicates the value of $RMI_CFG.$Chk_seqID, which is the configuration value that determines whether the controller checks valid incremented sequence IDs on incoming instructions.
public bool CheckSequenceId { get; }
public override bool Equals(object obj)
public override int GetHashCode()
// The next valid sequence ID. This key is only valid if the system variable $RMI_CFG.$Chk_seqID = TRUE
public int? NextSequenceId { get; set; }
// Number of user frames available in the robot controller
public byte NumberUFrame { get; set; }
// Number of user tools available in the robot controller
public byte NumberUTool { get; set; }
// RMI_MOVE program status
public TaskStatus ProgramStatus { get; set; }
// The Remote Motion Interface is running
public bool RmiMotionStatus { get; set; }
// The robot controller is ready for motion
public bool ServoReady { get; set; }
// Single step mode
public bool SingleStepMode { get; set; }
// The current speed override setting (1–100).
public byte SpeedOverride { get; set; }
// Teach Pendant Enabled (Switch on position ON) The Remote Motion interface only works when the teach pendant is disabled
public bool TPEnabled { get; set; }
public override string ToString()
}
View as Markdown

Universal Robots、Fanuc、Yaskawa、ABB、Staubli ロボットを .NET、Python、LabVIEW、または Matlab アプリケーションに簡単に統合

UnderAutomation
お問い合わせLegal

© All rights reserved.