SNPX
On this page :
SNPX is a protocol that allows you to fast read and write data on the robot (registers, variables, alarms, IOs, etc.)
Overview
SNPX (Also known as RobotIF, Robot Interface, or SRTP) allows for quick reading and writing of data on the robot, including:
- Registers (Position, number, and string)
- Variables
- Signals (UI, UO, GI, GO, ...)
- Clear and read alarms
- Read the status programs
TCP port Robot IF Server (by default 60008) should be accessible on your controller.
Differences with official Fanuc Robot Interface
Fanuc also provides a Robot Interface client implementation (FRRJIF.DLL) and here are the main differences:
UnderAutomation.Fanuc.dll | FRRJIF.DLL | |
---|---|---|
Editor | UnderAutomation | Fanuc Ltd. |
Technology | 100% managed .NET assembly | native ActiveX / COM |
Portability | No dependencies, the DLL can be moved | Requires installation with a setup program, especially for license management |
Read/write command execution time | 2 ms | 30 ms |
Pricing and conditions | Pay once at an affordable price, forever, with no recurring charges No matter :
|
Contact Fanuc to find out your terms of use |
Robot options
To enable SNPX on your robot, you need one of the following option :
- If R650 FRA params is selected (Option "FANUC America Corp." in "Advanced" tab of ROBOGUIDE "Worcell creation wizard - Step 7 Robot options"), R553 "HMI Device SNPX" is needed.
- If R651 FRL params is selected (Option "FANUC Ltd." in this "Advanced" tab), no option is needed.
Performances
SNPX is a fast protocol, allowing you to read and write data in less than 2 ms.
Benchmarks show that regardless of the amount of data transported in a command, it takes the same amount of time to execute. For example, you can read 80 position registers or write a variable in a few milliseconds.
This protocol is obviously not real-time or deterministic; execution time depends on the CPU load of your robot controller, network load, and computer performance.
When used on a robot simulated with ROBOGUIDE, execution times of less than 1 ms can even be achieved.
Features
Read current position
Here's how to read the current position of the main robot arm or another group driven by the controller.
Note: The current position is that of the current tool.
World current position
Method CurrentPosition.ReadWorldPosition
returns the current position of the robot in the world coordinate system.
using UnderAutomation.Fanuc;using UnderAutomation.Fanuc.Common;public class SnpxCurrentWorldPosition{static void Main(){// Create a new Fanuc robot instanceFanucRobot robot = new FanucRobot();// Set connection parametersConnectionParameters parameters = new ConnectionParameters("192.168.0.1");parameters.Snpx.Enable = true;// Connect to the robotrobot.Connect(parameters);/**/// Read a current world positionPosition worldPosition = robot.Snpx.CurrentPosition.ReadWorldPosition();// Access the Cartesian positiondouble x = worldPosition.CartesianPosition.X;// Access the user tool at this cartesian positionshort usertTool = worldPosition.UserTool;// Access the joint positionsdouble j1 = worldPosition.JointsPosition.J1;// Read a current world position of group 2Position worldPositionG2 = robot.Snpx.CurrentPosition.ReadWorldPosition(2);/**/}}
User frame current position
Method CurrentPosition.ReadUserFramePosition
returns the current position of the robot in the specified user frame.
Note: if you use user frame 15, the selected user frame in the pendant is used.
using UnderAutomation.Fanuc;using UnderAutomation.Fanuc.Common;public class SnpxCurrentUserFramePosition{static void Main(){// Create a new Fanuc robot instanceFanucRobot robot = new FanucRobot();// Set connection parametersConnectionParameters parameters = new ConnectionParameters("192.168.0.1");parameters.Snpx.Enable = true;// Connect to the robotrobot.Connect(parameters);/**/// Read user frame 2 positionPosition userFrame = robot.Snpx.CurrentPosition.ReadUserFramePosition(1);// Access the Cartesian positiondouble x = userFrame.CartesianPosition.X;// Access the user tool at this cartesian positionshort usertTool = userFrame.UserTool;// Access the user frame idshort usertFrame = userFrame.UserFrame;// Access the joint positionsdouble j1 = userFrame.JointsPosition.J1;// Read a current world position of group 2Position userFrameG2 = robot.Snpx.CurrentPosition.ReadWorldPosition(2);/**/}}
Read/write IOs, registers and Variables
You can read and write position registers, numeric registers, string registers, and system variables.
Intermediate objects (NumericRegisters, PositionRegisters, ..., SDI, SO, ..., PositionSystemVariables, ...) contain Read
and Write
methods that take the ID or name of the data to be read or written as a parameter.
Note 1: For position-type objects, two additional methods are available to specifically write the position in joint or Cartesian coordinates.
Note 2: you can read and write Karel program variables by using the variable name $[KarelProgram]KarelVariable
.
using UnderAutomation.Fanuc;using UnderAutomation.Fanuc.Common;public class Snpx{static void Main(){// Create a new Fanuc robot instanceFanucRobot robot = new FanucRobot();// Set connection parametersConnectionParameters parameters = new ConnectionParameters("192.168.0.1");parameters.Snpx.Enable = true;// Connect to the robotrobot.Connect(parameters);/**/// Read a registerPosition posReg1 = robot.Snpx.PositionRegisters.Read(1);float numReg5 = robot.Snpx.NumericRegisters.Read(5);string strReg10 = robot.Snpx.StringRegisters.Read(10);// Write a registerposReg1.CartesianPosition.X = 100;robot.Snpx.PositionRegisters.Write(1, posReg1);robot.Snpx.NumericRegisters.Write(2, 123.45f);robot.Snpx.StringRegisters.Write(3, "Hello, world!");// Read a variableint rmtMaster = robot.Snpx.IntegerSystemVariables.Read("$RMT_MASTER");string lastAlm = robot.Snpx.StringSystemVariables.Read("$ALM_IF.$LAST_ALM");Position cellFloor = robot.Snpx.PositionSystemVariables.Read("$CELL_FLOOR");// Write a system variablerobot.Snpx.IntegerSystemVariables.Write("$RMT_MASTER", 1);robot.Snpx.StringSystemVariables.Write("$ALM_IF.$LAST_ALM", "No alarms");robot.Snpx.PositionSystemVariables.Write("$CELL_FLOOR", cellFloor);// Write a Karel program variablerobot.Snpx.IntegerSystemVariables.Write("$[KarelProgram]KarelVariable", 1);// Read and Write I/O (SDI,SDO,RDI,RDO,UI,UO,SI,SO,WI,WO,WSI,PMC_K,PMC_R)robot.Snpx.RDO.Write(1, true);ushort ai5 = robot.Snpx.AI.Read(5);// Read and Write analogs (AI,AO,GI,GO,PMC_D)robot.Snpx.AO.Write(2, 5);ushort ao3 = robot.Snpx.AO.Read(3);// Clear alarmsrobot.Snpx.ClearAlarms();/**/}}
Read in batch
To improve the read speed of a group of registers or variables, you can create a custom assignment to read this set in a single command rather than one read command per register.
For each type of register or variable, a CreateBatchAssignment
method allows you to create this custom assignment by specifying the list of variables or registers to read, or the range of data to read (start index and size).
Then, a Read()
method on the returned object triggers the batch reading of this data.
// Create a batch read assignmentprivate NumericRegistersBatchAssignment _NumericRegistersBatchAssignment;public void Setup(){_NumericRegistersBatchAssignment = _robot.Snpx.NumericRegisters.CreateBatchAssignment(NumericRegisterStartIndex, BlockSize);}public void ReadNumericRegisters(){float[] values = _NumericRegistersBatchAssignment.Read();}
Acknowledge alarms
You can acknowledge alarms by using the ClearAlarms
method.
Check if SNPX is available
By FTP, you can check if SNPX is available on the robot controller by checking the installed features.
// Get all installed featuresFeatures features = _robot.Ftp.GetSummaryDiagnostic().Features;// Check if SNPX is availablebool isSnpxAvailable = features.HasSnpx;
Demonstration
You can take a look at the Winforms Desktop project source which implements all these features. I can be downloaded here.
API reference
Snpx Client
Members of Snpx.SnpxClient :public class SnpxClient : SnpxClientBase {public SnpxClient()public void Connect(string ip, int port = 60008)}
public class SnpxClientBase {// Analog Inputspublic NumericIO AI { get; }// Analog Outputspublic NumericIO AO { get; }public void ClearAlarms()public void ClearAssignments()protected void ConnectInternal(string ip, int port = 60008)public bool Connected { get; }// List of all digital signal accessors (SDI, SDO, RDI, RDO, ...)public DigitalSignals[] DigitalSignals { get; }public void Disconnect()// Group Inputspublic NumericIO GI { get; }// Group Outputspublic NumericIO GO { get; }public Assignment[] GetAssignments()// Integer variablespublic IntegerSystemVariables IntegerSystemVariables { get; }public string Ip { get; }// List of all Numeric IOs accessors (GI, GO, AI, AO, ...)public NumericIO[] NumericIOs { get; }// Number registerspublic NumericRegisters NumericRegisters { get; }// Programmable Machine Controller Datapublic NumericIO PMC_D { get; }// Programmable Machine Controller Constantspublic DigitalSignals PMC_K { get; }// Programmable Machine Controller Relayspublic DigitalSignals PMC_R { get; }// Position registerspublic PositionRegisters PositionRegisters { get; }// Position variablespublic PositionSystemVariables PositionSystemVariables { get; }// Remote Digital Inputspublic DigitalSignals RDI { get; }// Remote Digital Outputspublic DigitalSignals RDO { get; }// Safety Digital Inputspublic DigitalSignals SDI { get; }// Safety Digital Outputspublic DigitalSignals SDO { get; }// System Inputspublic DigitalSignals SI { get; }// System Outputspublic DigitalSignals SO { get; }// String registerspublic StringRegisters StringRegisters { get; }// String variablespublic StringSystemVariables StringSystemVariables { get; }// User Inputspublic DigitalSignals UI { get; }// User Outputspublic DigitalSignals UO { get; }// Weld Inputspublic DigitalSignals WI { get; }// Weld Outputspublic DigitalSignals WO { get; }// Weld System Inputspublic DigitalSignals WSI { get; }}
Inputs and Outputs
Members of Snpx.Internal.DigitalSignals :public class DigitalSignals : SnpxElements<bool, int> {public override bool Read(int index)public bool[] Read(int firstIndex, ushort count)public SegmentName SegmentName { get; }public SegmentOffset SegmentOffset { get; }public SegmentSelector SegmentSelector { get; }public void Write(int index, bool value)public void Write(int firstIndex, bool[] values)}
public class NumericIO : SnpxElements<ushort, int> {public override ushort Read(int index)public ushort[] Read(int firstIndex, ushort count)public SegmentName SegmentName { get; }public SegmentOffset SegmentOffset { get; }public SegmentSelector SegmentSelector { get; }public void Write(int index, ushort value)public void Write(int firstIndex, ushort[] values)}
Registers
Members of Snpx.Internal.NumericRegisters :public class NumericRegisters : SnpxWritableAssignableElements<float, int> {protected override int AssignmentSize { get; }protected override string GetAssignmentName(int index)protected override string GetAssignmentTarget(int index)protected override float ReadFromClient(int offset)protected override void WriteInClient(int offset, float value)}
public class PositionRegisters : SnpxWritableAssignableElements<Position, int> {protected override int AssignmentSize { get; }protected override string GetAssignmentName(int index)protected override string GetAssignmentTarget(int index)protected override Position ReadFromClient(int offset)protected override void WriteInClient(int offset, Position value)}
Position
Members of Common.Position :public class Position {public Position()public ExtendedCartesianPosition CartesianPosition { get; set; }public JointsPosition JointsPosition { get; set; }public short UserFrame { get; set; }public short UserTool { get; set; }}
public class JointsPosition {public JointsPosition()// Joint 1 in degreespublic double J1 { get; set; }// Joint 2 in degreespublic double J2 { get; set; }// Joint 3 in degreespublic double J3 { get; set; }// Joint 4 in degreespublic double J4 { get; set; }// Joint 5 in degreespublic double J5 { get; set; }// Joint 6 in degreespublic double J6 { get; set; }// Joint 7 in degreespublic double J7 { get; set; }// Joint 8 in degreespublic double J8 { get; set; }// Joint 9 in degreespublic double J9 { get; set; }public override string ToString()// Numeric values for each jointspublic double[] Values { get; }}
public class ExtendedCartesianPosition : CartesianPosition {public ExtendedCartesianPosition()public double E1 { get; set; }public double E2 { get; set; }public double E3 { get; set; }public short T4 { get; set; }public short T5 { get; set; }public short T6 { get; set; }}
public class CartesianPosition : XYZPosition {public CartesianPosition()// Position configurationpublic Configuration Configuration { get; }// P rotation in degreespublic double P { get; set; }// R rotation in degreespublic double R { get; set; }// W rotation in degreespublic double W { get; set; }}
public class XYZPosition {public XYZPosition()// X coordinate in meterspublic double X { get; set; }// Y coordinate in meterspublic double Y { get; set; }// Z coordinate in meterspublic double Z { get; set; }}
Variables
Members of Snpx.Internal.PositionSystemVariables :public class PositionSystemVariables : SnpxWritableAssignableElements<Position, string> {protected override int AssignmentSize { get; }protected override string GetAssignmentName(string index)protected override string GetAssignmentTarget(string index)protected override Position ReadFromClient(int offset)protected override void WriteInClient(int offset, Position value)}
public class StringRegisters : SnpxWritableAssignableElements<string, int> {protected override int AssignmentSize { get; }protected override string GetAssignmentName(int index)protected override string GetAssignmentTarget(int index)protected override string ReadFromClient(int offset)protected override void WriteInClient(int offset, string value)}
public class StringSystemVariables : SnpxWritableAssignableElements<string, string> {protected override int AssignmentSize { get; }protected override string GetAssignmentName(string index)protected override string GetAssignmentTarget(string index)protected override string ReadFromClient(int offset)protected override void WriteInClient(int offset, string value)}