UnderAutomation
Eine Frage?

[email protected]

Kontakt
UnderAutomation
⌘Q
This page is only available in English.

Frames, I/O & status

Manage user frames and tools, read/write I/O, read positions, set speed override, and get controller status via RMI.

RMI provides access to controller status, user frames and tools, digital and generic I/O, position reading, registers, system variables, payload, and TCP speed.

Controller status

GetStatus() returns the full controller state. Use it before Initialize() to verify the controller is ready.

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Basic status: servo, TP mode, RMI running, override
RmiControllerStatusResponse status = robot.Rmi.GetStatus();
Console.WriteLine("Servo ready: " + status.ServoReady);
Console.WriteLine("TP enabled: " + status.TPEnabled);
Console.WriteLine("RMI running: " + status.RmiMotionStatus);
Console.WriteLine("Program state: " + status.ProgramStatus);
Console.WriteLine("Override: " + status.SpeedOverride + "%");
Console.WriteLine("UFrame count: " + status.NumberUFrame);
Console.WriteLine("UTool count: " + status.NumberUTool);
// Extended status: drive power, control mode, speed clamp
RmiExtendedControllerStatusResponse ext = robot.Rmi.GetExtendedStatus();
Console.WriteLine("Drives on: " + ext.DrivesPowered);
Console.WriteLine("In motion: " + ext.InMotion);
// Read last controller error (up to 5 at once)
RmiControllerErrorTextResponse errors = robot.Rmi.ReadError(count: 3);
foreach (string entry in errors.ErrorDataEntries)
Console.WriteLine("Error: " + entry);
// HOLD state
Console.WriteLine("In HOLD: " + robot.Rmi.IsInHoldState);
robot.Disconnect();
}
Click to see the full code

Admin commands

robot.Connect(parameters);
robot.Rmi.Initialize();
// Set speed override (1-100 %)
robot.Rmi.SetOverride(50);
// Pause and resume the motion program
robot.Rmi.Pause();
robot.Rmi.Continue();
// Reset controller errors and exit the HOLD state
robot.Rmi.Reset();
// Resynchronize the sequence ID counter
robot.Rmi.AutoSetNextSequenceId();
// Get/set current UFRAME and UTOOL numbers
var ut = robot.Rmi.GetUFrameUTool();
System.Console.WriteLine("Frame: " + ut.Frame + ", Tool: " + ut.Tool);
robot.Rmi.SetUFrameUTool(uframe: 1, utool: 2);
// Abort the RMI_MOVE program
robot.Rmi.Abort();
robot.Disconnect();
}
Click to see the full code

Position reading

Read the current robot position and TCP speed. On firmware MajorVersion >= 6, the position reflects actual encoder counts.

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Read current Cartesian position.
// On MajorVersion >= 6, returns actual encoder position.
RmiCartesianPositionResponse cart = robot.Rmi.ReadCartesianPosition();
Console.WriteLine($"X={cart.Position.X:F1} Y={cart.Position.Y:F1} Z={cart.Position.Z:F1}");
Console.WriteLine($"W={cart.Position.W:F1} P={cart.Position.P:F1} R={cart.Position.R:F1}");
Console.WriteLine($"Tool={cart.Position.Tool} Frame={cart.Position.Frame}");
Console.WriteLine($"Timestamp={cart.TimeTag}");
// Read current joint angles
RmiJointAnglesSampleResponse joints = robot.Rmi.ReadJointAngles();
Console.WriteLine($"J1={joints.JointAngle.J1:F2} J2={joints.JointAngle.J2:F2} J3={joints.JointAngle.J3:F2}");
Console.WriteLine($"J4={joints.JointAngle.J4:F2} J5={joints.JointAngle.J5:F2} J6={joints.JointAngle.J6:F2}");
// Read TCP speed (mm/s)
RmiTcpSpeedResponse speed = robot.Rmi.ReadTcpSpeed();
Console.WriteLine($"TCP speed={speed.Speed:F2} mm/s");
robot.Disconnect();
}
Click to see the full code

User frames and tools

Read and write user frames (UFrame) and tools (UTool):

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Read UFRAME 1
RmiIndexedFrameResponse uf = robot.Rmi.ReadUFrame(1);
Console.WriteLine($"UFrame 1: X={uf.Frame.X:F1} Y={uf.Frame.Y:F1} Z={uf.Frame.Z:F1}");
// Write UFRAME 1
robot.Rmi.WriteUFrame(1, new XYZWPRPosition { X = 100, Y = 0, Z = 0, W = 0, P = 0, R = 0 });
// Read UTOOL 1
RmiIndexedFrameResponse ut = robot.Rmi.ReadUTool(1);
Console.WriteLine($"UTool 1: X={ut.Frame.X:F1} Y={ut.Frame.Y:F1} Z={ut.Frame.Z:F1}");
// Write UTOOL 1
robot.Rmi.WriteUTool(1, new XYZWPRPosition { X = 0, Y = 0, Z = 200, W = 0, P = 0, R = 0 });
// Get current UFRAME and UTOOL numbers
RmiUFrameUToolNumbersResponse current = robot.Rmi.GetUFrameUTool();
Console.WriteLine($"Active UFRAME={current.Frame} UTOOL={current.Tool}");
// Set the active UFRAME and UTOOL
robot.Rmi.SetUFrameUTool(uframe: 1, utool: 2);
robot.Disconnect();
}
Click to see the full code

Digital I/O

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Read digital input DI[2]
RmiDigitalInputValueResponse din = robot.Rmi.ReadDIN(2);
Console.WriteLine($"DI[2] = {din.PortValue}");
// Write digital output DO[1]
robot.Rmi.WriteDOUT(1, RmiOnOff.ON);
robot.Rmi.WriteDOUT(1, RmiOnOff.OFF);
robot.Disconnect();
}
Click to see the full code

Generic I/O ports

ReadIOPort and WriteIOPort work with any port type (DI, DO, AI, AO, GO, RO, FLAG, RI, UI, UO):

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Read any IO port type: DI, DO, AI, AO, GO, RO, FLAG, RI, UI, UO
RmiIoPortValueResponse di = robot.Rmi.ReadIOPort(RmiIoPortType.DI, 1);
Console.WriteLine($"DI[1] = {di.Value}");
RmiIoPortValueResponse ai = robot.Rmi.ReadIOPort(RmiIoPortType.AI, 1);
Console.WriteLine($"AI[1] = {ai.Value}");
RmiIoPortValueResponse flag = robot.Rmi.ReadIOPort(RmiIoPortType.FLAG, 5);
Console.WriteLine($"FLAG[5] = {flag.Value}");
// Write AO[1] = 2.5
robot.Rmi.WriteIOPort(RmiIoPortType.AO, 1, 2.5);
// Write GO[1] = 7
robot.Rmi.WriteIOPort(RmiIoPortType.GO, 1, 7);
// Write FLAG[5] = 1
robot.Rmi.WriteIOPort(RmiIoPortType.FLAG, 5, 1);
robot.Disconnect();
}
Click to see the full code

Position registers

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Read position register PR[1]
RmiPositionRegisterDataResponse pr = robot.Rmi.ReadPositionRegister(1);
Console.WriteLine($"PR[1]: X={pr.CartesianPosition.X:F1} Y={pr.CartesianPosition.Y:F1} Z={pr.CartesianPosition.Z:F1}");
// Write position register PR[2] with a Cartesian value
robot.Rmi.WritePositionRegisterCartesian(2,
new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, tool: 1, frame: 0));
robot.Disconnect();
}
Click to see the full code

Numeric registers and system variables

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Read numeric register R[1]
RmiNumericRegisterValueResponse r1 = robot.Rmi.ReadNumericRegister(1);
Console.WriteLine($"R[1] IsInteger={r1.Value.IsInteger} Value={r1.Value.RealValue}");
// Write integer value to R[1]
robot.Rmi.WriteNumericRegisterAsInteger(1, 42);
// Write float value to R[2]
robot.Rmi.WriteNumericRegisterAsDouble(2, 3.14);
// Read system variable $MCR.$GENOVERRIDE (include the leading $)
RmiVariableValueResponse var = robot.Rmi.ReadVariable("$MCR.$GENOVERRIDE");
Console.WriteLine($"Speed override = {var.RealValue}");
// Write system variable
robot.Rmi.WriteVariableAsInteger("$MCR.$GENOVERRIDE", 80);
robot.Disconnect();
}
Click to see the full code

Payload

Define payload mass, center of gravity, and inertia for a schedule. You can also send a SetPayloadTpInstruction as a motion-sequence instruction.

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Define payload for schedule 1: 5 kg, center of gravity offset 0.1 m in Z
robot.Rmi.SetPayloadValue(
scheduleNumber: 1,
massKg: 5.0f,
cgXm: 0f, cgYm: 0f, cgZm: 0.1f);
// Include inertia values
robot.Rmi.SetPayloadValue(
scheduleNumber: 2,
massKg: 3.0f,
cgXm: 0.05f, cgYm: 0f, cgZm: 0.08f,
inertiaXkgm2: 0.002f, inertiaYkgm2: 0.002f, inertiaZkgm2: 0.001f);
// Define payload compensation
robot.Rmi.SetPayloadCompensation(
scheduleNumber: 1,
massKg: 1.0f,
cgXm: 0f, cgYm: 0f, cgZm: 0.05f,
inertiaXkgm2: 0.001f, inertiaYkgm2: 0.001f, inertiaZkgm2: 0.0005f);
// Activate schedule 1 immediately (command, not a TP instruction)
robot.Rmi.SetPayloadSchedule(1);
robot.Disconnect();
}
Click to see the full code

Position recording

The RMI Position Record menu (UTILITIES on the teach pendant) lets an operator jog the robot to a position and press Record. The controller sends the position back to the connected remote device as a packet. Subscribe to RecordedCartesianPositionReceived or RecordedJointPositionReceived to receive these positions.

The position ID is assigned by the controller and increments with each recorded position. Use it to correlate incoming positions with your application data.

parameters.Rmi.Enable = true;
robot.Connect(parameters);
// Subscribe before connecting to the RMI session.
// The controller fires these events when the operator uses the
// RMI Position Record menu on the teach pendant (UTILITIES > RMI Position Record)
// and presses the Record key.
robot.Rmi.RecordedCartesianPositionReceived += (RmiRecordedCartesianPosition rec) =>
{
Console.WriteLine($"Recorded Cartesian pos {rec.PositionId}:");
Console.WriteLine($" X={rec.Position.X:F1} Y={rec.Position.Y:F1} Z={rec.Position.Z:F1}");
Console.WriteLine($" W={rec.Position.W:F1} P={rec.Position.P:F1} R={rec.Position.R:F1}");
Console.WriteLine($" Tool={rec.Position.Tool} Frame={rec.Position.Frame}");
};
robot.Rmi.RecordedJointPositionReceived += (RmiRecordedJointPosition rec) =>
{
Console.WriteLine($"Recorded joint pos {rec.PositionId}:");
Console.WriteLine($" J1={rec.Joints.J1:F2} J2={rec.Joints.J2:F2} J3={rec.Joints.J3:F2}");
Console.WriteLine($" J4={rec.Joints.J4:F2} J5={rec.Joints.J5:F2} J6={rec.Joints.J6:F2}");
};
// Keep the application alive while the operator records positions
Console.WriteLine("Waiting for positions. Press ENTER to exit.");
Click to see the full code

Complete example

using System;
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Common;
using UnderAutomation.Fanuc.Rmi.Data;
using UnderAutomation.Fanuc.Rmi.TpInstructions;
public class RmiFramesIo
{
static void Main()
{
FanucRobot robot = new FanucRobot();
ConnectionParameters parameters = new ConnectionParameters("192.168.0.1");
parameters.Rmi.Enable = true;
robot.Connect(parameters);
Console.WriteLine("Protocol version: " + robot.Rmi.MajorVersion + "." + robot.Rmi.MinorVersion);
// Verify the controller is ready
var status = robot.Rmi.GetStatus();
if (!status.ServoReady || status.TPEnabled)
{
Console.WriteLine("Controller not ready for RMI.");
return;
}
// Read current position before moving
var pos = robot.Rmi.ReadCartesianPosition();
Console.WriteLine($"Start: X={pos.Position.X:F1} Y={pos.Position.Y:F1} Z={pos.Position.Z:F1}");
// Read UFrame 1
var uf = robot.Rmi.ReadUFrame(1);
Console.WriteLine($"UFrame 1 origin: X={uf.Frame.X:F1}");
// Read DI[1]
var din = robot.Rmi.ReadDIN(1);
Console.WriteLine($"DI[1] = {din.PortValue}");
// Read R[1]
var r1 = robot.Rmi.ReadNumericRegister(1);
Console.WriteLine($"R[1] = {r1.Value.RealValue}");
// Initialize and send some motion
robot.Rmi.Initialize();
robot.Rmi.SetOverride(50);
robot.Rmi.SendTpInstruction(new LinearMotionTpInstruction
{
SpeedType = RmiLinearSpeedType.MmSec,
Speed = 100,
TermType = RmiTerminationType.Fine,
Target = new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, 1, 0)
}).WaitForCompletion();
// Write DO[1] ON
robot.Rmi.WriteDOUT(1, RmiOnOff.ON);
// Read TCP speed
var tcp = robot.Rmi.ReadTcpSpeed();
Console.WriteLine($"TCP speed: {tcp.Speed:F1} mm/s");
robot.Rmi.Abort();
robot.Disconnect();
}
}

API reference

Class
RmiControllerStatusResponseinherits RmiResponseBase
C#Python

Status snapshot returned by FRC_GetStatus.

MemberTypeDescription
RmiControllerStatusResponse()
Constructor
CheckSequenceId
Property
read only
bool
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.
NextSequenceId
Property
int?
The next valid sequence ID. This key is only valid if the system variable $RMI_CFG.$Chk_seqID = TRUE
NumberUFrame
Property
byte
Number of user frames available in the robot controller
NumberUTool
Property
byte
Number of user tools available in the robot controller
ProgramStatus
Property
TaskStatus
RMI_MOVE program status
RmiMotionStatus
Property
bool
The Remote Motion Interface is running
ServoReady
Property
bool
The robot controller is ready for motion
SingleStepMode
Property
bool
Single step mode
SpeedOverride
Property
byte
The current speed override setting (1–100).
TPEnabled
Property
bool
Teach Pendant Enabled (Switch on position ON) The Remote Motion interface only works when the teach pendant is disabled
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiExtendedControllerStatusResponseinherits RmiResponseBase
C#Python

Extended controller status returned by FRC_GetExtStatus.

MemberTypeDescription
RmiExtendedControllerStatusResponse()
Constructor
ControlMode
Property
string
Active control mode string (e.g. "AUTO"), or null when unavailable.
DrivesPowered
Property
bool
Whether the servo drives are powered on.
ErrorCode
Property
string
Last reported error code text, or null when no error is active.
GenOverride
Property
int
General speed override percentage.
InMotion
Property
bool
Whether the robot is currently executing a motion.
SpeedClampLimit
Property
double?
Speed clamp limit in mm/s, or null when not configured.
ToString()
Method
string
Class
RmiUFrameUToolNumbersResponseinherits RmiResponseBase
C#Python

Current UFRAME and UTOOL numbers, optionally scoped to a motion group.

MemberTypeDescription
RmiUFrameUToolNumbersResponse()
Constructor
Frame
Property
byte
Current user frame number.
Group
Property
byte?
Motion group number, or null when not applicable.
Tool
Property
byte
Current user tool number.
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiIndexedFrameResponseinherits RmiResponseBase
C#Python

Cartesian frame data paired with an index (UFRAME or UTOOL number).

MemberTypeDescription
RmiIndexedFrameResponse()
Constructor
Frame
Property
XYZWPRPosition
Frame data.
Index
Property
byte
Index (UFRAME or UTOOL number).
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiDigitalInputValueResponseinherits RmiResponseBase
C#Python

Result of reading a digital input.

MemberTypeDescription
RmiDigitalInputValueResponse()
Constructor
PortNumber
Property
short
Port number.
PortValue
Property
RmiOnOff
Port value
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiIoPortValueResponseinherits RmiResponseBase
C#Python

Result of reading a generic IO port.

MemberTypeDescription
RmiIoPortValueResponse()
Constructor
PortNumber
Property
int
Port number.
PortType
Property
RmiIoPortType
Port type (DI, DO, AI, AO, GO, etc.).
Value
Property
double
Current port value.
ToString()
Method
string
Class
RmiCartesianPositionResponseinherits RmiTimedResponse
C#Python

Result of reading the current Cartesian position.

MemberTypeDescription
RmiCartesianPositionResponse()
Constructor
Position
Property
CartesianPositionWithUserFrame
Current TCP position including configuration and active frame/tool numbers.
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiJointAnglesSampleResponseinherits RmiTimedResponse
C#Python

Result of reading the current joint angles.

MemberTypeDescription
RmiJointAnglesSampleResponse()
Constructor
JointAngle
Property
JointsPosition
Joint angle set in degrees.
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiPositionRegisterDataResponseinherits RmiResponseBase
C#Python

Position register data paired with its register number.

MemberTypeDescription
RmiPositionRegisterDataResponse()
Constructor
CartesianPosition
Property
CartesianPositionWithUserFrame
Position register value.
RegisterNumber
Property
short
Register number
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiNumericRegisterValueResponseinherits RmiResponseBase
C#Python

Result of reading a numeric register.

MemberTypeDescription
RmiNumericRegisterValueResponse()
Constructor
RegisterNumber
Property
int
Register number.
Value
Property
NumericRegister
Register value.
ToString()
Method
string
Class
RmiVariableValueResponseinherits RmiResponseBase
C#Python

Result of reading a system variable.

MemberTypeDescription
RmiVariableValueResponse()
Constructor
IntegerValue
Property
int
Gets or sets the value as an integer. Internally stored as a double.
IsInteger
Property
bool
Whether the variable holds a floating-point value.
Name
Property
string
Variable name, including the leading $ character.
RealValue
Property
double
Gets or sets the value as a double-precision floating-point number.
ToString()
Method
string
Class
RmiTcpSpeedResponseinherits RmiTimedResponse
C#Python

Result of reading TCP speed.

MemberTypeDescription
RmiTcpSpeedResponse()
Constructor
Speed
Property
double
Current tool center point speed in mm/s.
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
RmiSetPayloadParameters
C#Python

Parameters for defining payload mass, center of gravity, and optionally inertia for a payload schedule. Used by SetPayloadValue(RmiSetPayloadParameters). All positional values are in meters; mass in kg; inertia in kg·m².

MemberTypeDescription
RmiSetPayloadParameters()
Constructor
CgXm
Property
float
Center-of-gravity X offset in meters.
CgYm
Property
float
Center-of-gravity Y offset in meters.
CgZm
Property
float
Center-of-gravity Z offset in meters.
Group
Property
byte?
Optional motion group number. null uses the active group.
InertiaXkgm2
Property
float?
Inertia around the X axis in kg·m². null omits this field from the command.
InertiaYkgm2
Property
float?
Inertia around the Y axis in kg·m². null omits this field from the command.
InertiaZkgm2
Property
float?
Inertia around the Z axis in kg·m². null omits this field from the command.
MassKg
Property
float
Payload mass in kilograms.
ScheduleNumber
Property
byte
Payload schedule number to configure.
Class
RmiSetPayloadCompensationParameters
C#Python

Parameters for defining payload compensation for a payload schedule. Used by SetPayloadCompensation(RmiSetPayloadCompensationParameters). All positional values are in meters; mass in kg; inertia in kg·m².

MemberTypeDescription
RmiSetPayloadCompensationParameters()
Constructor
CgXm
Property
float
Center-of-gravity X offset in meters.
CgYm
Property
float
Center-of-gravity Y offset in meters.
CgZm
Property
float
Center-of-gravity Z offset in meters.
Group
Property
byte?
Optional motion group number. null uses the active group.
InertiaXkgm2
Property
float
Inertia around the X axis in kg·m².
InertiaYkgm2
Property
float
Inertia around the Y axis in kg·m².
InertiaZkgm2
Property
float
Inertia around the Z axis in kg·m².
MassKg
Property
float
Payload mass in kilograms.
ScheduleNumber
Property
byte
Payload schedule number to configure.
Class
RmiRecordedCartesianPosition
C#Python

Cartesian position received from the controller via the RMI Position Record menu (TouchUp).

MemberTypeDescription
RmiRecordedCartesianPosition()
Constructor
Position
Property
CartesianPositionWithUserFrame
Recorded Cartesian position including arm configuration and active frame/tool numbers.
PositionId
Property
ushort
Position identifier assigned by the controller.
ToString()
Method
string
Class
RmiRecordedJointPosition
C#Python

Joint position received from the controller via the RMI Position Record menu (TouchUp).

MemberTypeDescription
RmiRecordedJointPosition()
Constructor
Joints
Property
JointsPosition
Recorded joint angles in degrees.
PositionId
Property
ushort
Position identifier assigned by the controller.
ToString()
Method
string

Integrieren Sie Roboter von Universal Robots, Fanuc, Yaskawa, ABB oder Staubli ganz einfach in Ihre .NET-, Python-, LabVIEW- oder Matlab-Anwendungen

UnderAutomation
KontaktLegal

© All rights reserved.