Releases: underautomation/Fanuc.NET
Release list
v6.2.0.0
More robot models in ArmKinematicModels
The following models have been added to the ArmKinematicModels enum:
ARCMate100iDDC,ARCMate100iDFG,ARCMate100iD16SB441ARCMate120iDFGCR35iB,CR7iAL_2CRX3iA,CRX5iA,CRX20iAL,CRX30iA,CRX10iALPaintLR10iA10,LRMate1011AFoodClean,LRMate200iD7WEM710iC20L,M710iD50M,M710iD70M800iB60,M8006020B,M81019020B,M81027027BM900iB700E,M910400F37B,M950iA500,M950iA500SE,M950500F28AM1000iA,M1000550F46A,M410800F32CR2000iC190S,R2000iC190SSE,R2000iC270FSER2000125F31E,R2000210F31E,R2000300F27E,R2000180F27E
Note: do not rely on the implicit integer values of
ArmKinematicModelsmembers. The enum is sorted alphabetically and new models may be inserted at any position in future releases, shifting the integer values of existing members. Always use the named members, not their numeric equivalents.
CRX inverse kinematics: analytical solver, no seed required
The CRX cobot inverse kinematics solver has been rewritten using a closed-form geometric approach. It now computes all valid joint solutions for a given Cartesian pose without requiring a seed position.
The seedJoints parameter has been removed from CrxKinematicsUtils.InverseKinematics. If your code was passing a seed, remove that argument.
The solver is now around 3x faster. The includeDuals parameter remains available to control whether dual solutions are included.
var dh = DhParameters.FromArmKinematicModel(ArmKinematicModels.CRX10iA);
var target = new CartesianPosition { X = 400, Y = 250, Z = 650, W = 0, P = 90, R = 0 };
// All solutions are returned, no seed needed
JointsPosition[] solutions = KinematicsUtils.InverseKinematics(target, dh);
// Or call the CRX-specific method directly
JointsPosition[] solutions = CrxKinematicsUtils.InverseKinematics(target, dh, includeDuals: true);v6.1.0.0
Bug fixes
- Fixed a missing namespace declaration on
FtpExistsBehavior, which caused the type to be inaccessible when referenced from outside the assembly. - Fixed incorrect namespace references in RMI motion instruction classes, which prevented motion instructions from working correctly.
v6.0.0.0
RMI: complete API rewrite
The RMI client has been redesigned from scratch. The previous method-per-instruction API is replaced by an instruction object model that is easier to extend and closer to how the controller actually works.
Instruction pipeline
Each call to SendTpInstruction now returns an RmiInstructionResponse that you can poll or block on:
RmiInstructionResponse r = robot.Rmi.SendTpInstruction(new LinearMotionTpInstruction
{
SpeedType = RmiLinearSpeedType.MmSec,
Speed = 100,
TermType = RmiTerminationType.Fine,
Target = new CartesianPositionWithUserFrame(500, 200, 300, 0, 90, 0, 1, 0)
});
// Wait for the controller to confirm execution
r.WaitForCompletion();
Console.WriteLine(r.Status); // Completed or ErrorThe client manages the 8-slot controller buffer automatically. Instructions that exceed the limit are held in a local queue and sent as soon as a slot becomes free.
New instruction classes
All instruction types now have dedicated classes:
| Class | TP equivalent |
|---|---|
LinearMotionTpInstruction |
L P[] mm/sec FINE |
LinearRelativeTpInstruction |
L P[] mm/sec FINE INC |
JointMotionTpInstruction |
J P[] % FINE |
JointRelativeTpInstruction |
J P[] % FINE INC |
CircularMotionTpInstruction |
C P[] P[] mm/sec FINE |
CircularRelativeTpInstruction |
C P[] P[] mm/sec FINE INC |
LinearMotionJRepTpInstruction |
L P[] mm/sec FINE (joint-angle target) |
LinearRelativeJRepTpInstruction |
incremental, joint-angle target |
JointMotionJRepTpInstruction |
J P[] % FINE (joint-angle target) |
JointRelativeJRepTpInstruction |
incremental, joint-angle target |
SplineMotionTpInstruction |
S P[] mm/sec CNT (requires MajorVersion >= 7) |
SplineMotionJRepTpInstruction |
spline, joint-angle target |
WaitDinTpInstruction |
WAIT DI[n] = ON/OFF |
WaitTimeTpInstruction |
WAIT t(sec) |
SetUFrameTpInstruction |
UFRAME_NUM = n |
SetUToolTpInstruction |
UTOOL_NUM = n |
SetPayloadTpInstruction |
PAYLOAD[n] |
CallProgramTpInstruction |
CALL program |
New admin methods
Initialize(groupMask, rtsa, pltzMode): starts RMI_MOVE with optional multi-group, singularity avoidance, and palletizing header support.AutoSetNextSequenceId(): readsGetStatus()and re-synchronizes the local sequence counter when the controller checks sequence IDs.GetExtendedStatus(): returns drive state, control mode, and speed clamp.ReadNumericRegister/WriteNumericRegisterAsInteger/WriteNumericRegisterAsDouble: read and write numeric registers (R[]).ReadVariable/WriteVariableAsInteger/WriteVariableAsDouble: read and write system variables.SetPayloadValue(...): define payload mass and center of gravity for a schedule.SetPayloadCompensation(...): define payload compensation.SetPayloadSchedule(scheduleNumber): activate a payload schedule immediately (command, not instruction).ReadIOPort/WriteIOPort: read and write any IO port type (DI, DO, AI, AO, GO, RO, FLAG, RI, UI, UO).ClearCompletedInstructions()/ClearLocalQueuedInstructions(): manage the tracked instruction list.
New events
ConnectionTerminated: fired when the controller closes the session.SystemFaultReceived: fired on a controller fault; argument is the faulted sequence ID.RecordedCartesianPositionReceived/RecordedJointPositionReceived: fired when the RMI Position Record menu sends a position.
Hold state detection
IsInHoldState is now a property. The client sets it automatically when the controller returns status "HOLD" or error "invalid sequence ID". Call Reset() to exit the hold state.
FTP: FtpExistsBehavior on upload methods
UploadFileToController now accepts a FtpExistsBehavior parameter:
robot.Ftp.DirectFileHandling.UploadFileToController(
@"C:\Programs\MyPrg.tp",
"md:/MyPrg.tp",
existsBehavior: FtpExistsBehavior.Skip);| Value | Behavior |
|---|---|
NoCheck |
Skip existence check. Use only when the file is guaranteed not to exist. |
Skip |
Do nothing if the file already exists. |
Overwrite |
Replace the file (default). |
Append |
Resume a partial upload by checking the current file size. |
AppendNoCheck |
Append without checking whether the file exists first. |
CGTP: fix file download on some controllers
Fixed a bug where downloading files via CGTP could fail or return incomplete data on controllers that close the HTTP connection before sending the end-of-response marker. The response body is now fully buffered before the connection is released.
v5.5.0.0
CGTP: write position into a TP program
CgtpClient has a new SetProgramPosition method. It writes a Cartesian or joint position to a given position index (P[n]) inside a TP program. Only the first motion group is supported via CGTP.
// Cartesian position
var position = new Position(
userFrame: 0,
userTool: 1,
jointsPosition: null,
cartesianPosition: new ExtendedCartesianPosition(500, 200, 300, 0, 90, 0, 0, 0, 0)
);
robot.Cgtp.SetProgramPosition("MY_PROG", 1, position);
// Joint position
var jointPosition = new Position(
userFrame: 0,
userTool: 1,
jointsPosition: new JointsPosition { J1 = 0, J2 = 0, J3 = 0, J4 = 0, J5 = -90, J6 = 0 },
cartesianPosition: null
);
robot.Cgtp.SetProgramPosition("MY_PROG", 2, jointPosition);FTP connection timeout
The FtpConnectParameters class has a new FtpTimeoutMs property. It controls the connection, read, and data transfer timeouts for all FTP operations. The default is 30,000 ms (30 seconds).
parameters.Ftp.Enable = true;
parameters.Ftp.FtpTimeoutMs = 10000; // 10 secondsCGTP: record current position into a program
CgtpClient has a new SetProgramPositionToCurrentCartesianPosition method. It writes the robot's current Cartesian position to a given position index inside a TP program and returns the recorded position.
CartesianPosition pos = robot.Cgtp.SetProgramPositionToCurrentCartesianPosition("MY_PROG", 1);
Console.WriteLine($"Recorded: X={pos.X}, Y={pos.Y}, Z={pos.Z}");v5.4.0.0
CGTP Source Code Editing and Program Listing
New CGTP methods for editing TP program source code directly on the controller, and listing programs. These features require firmware V9.10+ (source editing) or standard CGTP support (listing).
List programs
Retrieve all TP or Karel programs on the controller, filtered by type and sub-type.
// List all TP programs (all sub-types)
string[] tpPrograms = robot.Cgtp.ListTpPrograms();
// List programs with a specific type and sub-type
string[] macros = robot.Cgtp.ListPrograms(CgtpProgramType.Tp, CgtpProgramSubType.Macro);Source code editing
Insert, replace, or delete lines in a TP program on the controller.
// Insert a new line before line 3
robot.Cgtp.InsertSourceLine("MY_PROGRAM", "L P[5] 100mm/sec FINE", 3);
// Replace line 5
robot.Cgtp.ReplaceSourceLine("MY_PROGRAM", "J P[1] 50% FINE", 5);
// Delete 2 lines starting at line 4
robot.Cgtp.DeleteSourceLines("MY_PROGRAM", 4, 2);v5.3.0.0
CGTP : new features
- Added
WritePositionRegisterAsCartesianandWritePositionRegisterAsJointto write position registers in Cartesian and Joint representations
SNPX : new features
- SNPX is now thread safe, allowing multiple threads to access the same instance without conflicts. This enhancement improves performance and reliability in multi-threaded applications.
v5.2.0.0
Kinematics via CGTP
- New
InvertKinematicsmethod: compute inverse kinematics on the controller, converting a Cartesian position to joint angles. - New
ForwardKinematicsmethod: compute forward kinematics on the controller, converting joint angles to a Cartesian position. - Both methods execute the computation on the controller itself, ensuring results match the robot's actual kinematic model.
Batch variable read/write via CGTP
- New
ReadBatchVariables(CgtpBatchVariables)method: read multiple variables from the controller in a single request. - New
WriteBatchVariables(CgtpBatchVariables)method: write multiple variables to the controller in a single request. - New
CgtpBatchVariablescollection (implementsIList<ICgtpBatchVariable>) with convenience methods to add variables:AddNumericRegister(index),AddNumericRegisterAsInteger(index, value),AddNumericRegisterAsReal(index, value)for numeric registers R[].AddStringRegister(index),AddStringRegisterWithValue(index, value)for string registers SR[].AddPositionRegister(index),AddPositionRegisterAsCartesian(index, ...),AddPositionRegisterAsJoint(index, ...)for position registers PR[].AddVariable(name, program)for any named variable.
- New typed variable classes:
CgtpNumericRegister,CgtpStringRegister,CgtpPositionRegister,CgtpVariable, all implementingICgtpBatchVariable. CgtpVariableexposes typed getters/setters:IntegerValue,RealValue,BooleanValue,StringValue,CartesianPositionValue,JointPositionValue,VectorValue,ConfigurationValue,StructureValue.CgtpVariable.StructureValuereturns a tree ofCgtpStructureFieldfor structured variables (FIELD/ARRAY nodes).- After a batch read, each variable exposes
Exists,IsUninitialized, andIsReadOnlystatus properties. CgtpBatchReadResult.Versionreturns the controller firmware version from the response.
File access and decoding via CGTP
- New
CgtpFileClientaccessible viaCgtpClient.Http: download and decode controller files over HTTP, without FTP. CgtpClient.Httpinherits fromFileClientBase: all shared file-reading methods are available (GetSummaryDiagnostic(),GetAllErrorsList(),GetCurrentPosition(),GetIOState(),GetSafetyStatus(),GetProgramStates(),GetVariablesFromFile(),KnownVariableFiles).BasePathproperty (default"MD") controls the root path used for file downloads.DownloadAsBytes(fileName),DownloadAsString(fileName), andDownloadAsStream(fileName)to download raw files from the controller. HTML responses containing a<PRE>block are automatically unwrapped; binary files are returned as-is.ListVariables()returnsCgtpAsciiFileItem[]listing all variable files (binary and ASCII) from the controller.ListTpPrograms()returnsCgtpAsciiFileItem[]listing all TP program files (binary and ASCII) from the controller.ListDiagnosticFiles()returnsCgtpFileItem[]listing all diagnostic and error log files from the controller.ListOtherFiles()returnsCgtpFileItem[]listing all other files from the controller.- New data models:
CgtpFileItem(withFileandCommentproperties) andCgtpAsciiFileItem(addsAsciiFilefor the ASCII format variant).
Handle comments and user alarms via CGTP
- Bulk read of numeric registers with comments and values via
ReadNumericRegistersWithComment(). - Bulk read of string registers with comments and values via
ReadStringRegistersWithComment(). - Bulk read of user alarm definitions (comment and severity) via
ReadUserAlarms(). - New unified
GetComments(CgtpCommentType type)method to read all comments for any element type: numeric registers, position registers, string registers, user alarms, flags, and all I/O types (DI, DO, RI, RO, GI, GO, AI, AO). - New
GetIoComments(CgtpCommentIoType type)method to read paired input/output comments for a given I/O type (Robot, Digital, Group, Analog). SetComment(CgtpCommentType type, int index, string comment)to write the comment of any register or I/O port.WriteNumericRegisterAsDouble()andWriteNumericRegisterAsInteger()to write numeric register values with explicit type control.WriteStringRegister()to write a string register value.SetUserAlarmSeverity()to set the severity level of a user alarm.- New enums
CgtpCommentTypeandCgtpCommentIoTypefor strongly-typed comment operations. - New data models:
StringRegisterWithComment,UserAlarmDefinition,IOComments. - HTTP Basic authentication support: new
LoginandPasswordproperties onCgtpConnectParametersBasefor controllers that require credentials. - CGTP also works on the standard HTTP port 80 by setting
CgtpConnectParameters.Port = 80.
New KCL client over CGTP
- New
CgtpKclClientclass accessible viaCgtpClient.Kcl: execute KCL commands over the CGTP Web Server (HTTP), without a Telnet connection. - Full KCL command set available:
Abort,AbortAll,ClearAll,ClearProgram,ClearVars,Continue,Hold,Pause,Reset,Run,SetPort,SetVariable,GetCurrentPose,GetVariable,Simulate,Unsimulate,UnsimulateAll,SendCustomCommand,GetTaskInformation,AddBreakpoint,RemoveBreakpoint,RemoveAllBreakpoints,GetBreakpoints,StepOn,StepOff. - New
SendCustomCommandUnsafe()method to send any custom KCL command via the Comet CPKCL endpoint. - New abstract
KclClientBasebase class inUnderAutomation.Fanuc.Common.Kclshared betweenTelnetClientBaseandCgtpKclClient, ensuring a unified KCL API across both protocols. CgtpClient.Kclis never null and always uses the language configured onCgtpClient.
New Telnet Feature
- New event
StringDataReceivedonTelnetClientBaseto receive decoded string data from the controller, in addition to raw byte data. This is useful for handling text-based responses from any connected KCL client (CGTP, Telnet, ...) in a unified way.
Shared file reading foundation (FTP)
- File reading, parsing, and variable decoding logic has been extracted from the FTP client into a shared foundation in
UnderAutomation.Fanuc.Common.Files, laying the groundwork for future protocol-agnostic file access. - New
FileClientBaseabstract base class inUnderAutomation.Fanuc.Common.Files: centralizes methods such asGetSummaryDiagnostic(),GetAllErrorsList(),GetCurrentPosition(),GetIOState(),GetSafetyStatus(),GetProgramStates(),GetVariablesFromFile(), and theKnownVariableFilesproperty. FtpClientBasenow inherits fromFileClientBase: all file-reading methods remain available on the FTP client with the same signatures.FtpKnownVariableFileshas been replaced by the sharedKnownVariableFilesclass inUnderAutomation.Fanuc.Common.Files.FanucFileReadersstatic helper (reading.va,.dg,.lsfiles) moved toUnderAutomation.Fanuc.Common.Files.- New
FanucFileReaders.ReadFile(string path)static method to read and auto-detect any supported Fanuc file from disk. - New
ParseResult()method in KCLGetVariableResultclass to decode and get a structured representation of the variable (value, type, scope, ...).
Breaking changes
CgtpClient.Connect()signature changed: now accepts optionalloginandpasswordparameters.- Namespace migration for shared KCL types:
Result,BaseResult,KCLPorts,KclClientBase, and all KCL result classes (ProgramCommandResult,RunResult,SetVariableResult,GetVariableResult,SetPortResult,SimulateResult,UnsimulateResult,GetCurrentPoseResult,TaskInformationResult,BreakpointsResult, etc.) moved fromUnderAutomation.Fanuc.TelnettoUnderAutomation.Fanuc.Common.Kcl. - Telnet-specific event types (
RawDataReceivedEventArgs,TpCoordinates,MessageReceivedEventArgs,KclClientErrorEventArgs,CommandSentEventArgs,KclCommandReceived) remain inUnderAutomation.Fanuc.Telnet. - Namespace migration for shared position models: moved from
UnderAutomation.Fanuc.Ftp.VariablestoUnderAutomation.Fanuc.Common. - Affected types:
CartesianPositionVariable,JointPositionVariable,PositionRegister,VectorVariable. - Namespace migration for file reading and variable decoding:
- Diagnosis types (
SummaryDiagnosis,CurrentPosition,IOState,SafetyStatus,ProgramStates,GroupPosition,Feature, etc.) moved fromUnderAutomation.Fanuc.Ftp.DiagnosistoUnderAutomation.Fanuc.Common.Files.Diagnosis. - Error list types (
ErrorList,ErrallSectionItem,ErrallSectionParser) moved fromUnderAutomation.Fanuc.Ftp.Files.ListtoUnderAutomation.Fanuc.Common.Files.List. - Variable types (
GenericVariableFile,GenericVariable,GenericField,GenericValue,ValueKind,ArrayElement,VariableFile,VariableFileList, etc.) moved fromUnderAutomation.Fanuc.Ftp.VariablestoUnderAutomation.Fanuc.Common.Files.Variables. - All autogenerated variable file readers and type definitions moved from
UnderAutomation.Fanuc.Ftp.AutogeneratedtoUnderAutomation.Fanuc.Common.Files.Variables.Autogenerated. - File infrastructure types (
FanucFileReaders,FileParser,FileReader,IFileReader,IFanucContent) moved fromUnderAutomation.Fanuc.Ftp/UnderAutomation.Fanuc.Ftp.InternaltoUnderAutomation.Fanuc.Common.Files.
- Diagnosis types (
TelnetClientBasenow inherits fromKclClientBase: all KCL methods remain available on the Telnet client with the same signatures.- CGTP enum/type naming has been aligned for clarity in public APIs (for example IoPortType and ProgramSubType naming in CGTP).
Improved
- Improved robustness of value parsing for position and register data.
- Improved CGTP error reporting with clearer messages in common failure scenarios.
v5.1.0.0
SNPX: Flag Comments Support
Added support for reading and writing Flag comments through SNPX.
CGTP: New Capabilities and Improvements
- Enabled CGTP I/O operations in
CgtpClientBase:- Read I/O values
- Write I/O values
- Read I/O simulation status
- Simulate/unsimulate I/O
- Read current Cartesian position (X, Y, Z, W, P, R coordinates and configuration) of a motion group
- Read current joint angles (J1-J6) of a motion group
SNPX: Null-Terminated String Handling Fix
Improved string decoding by trimming trailing null terminators (\0) across SNPX string-related reads.
This prevents issues with null-terminated strings in scenarios such as:
- String registers
- Comments (including batch reads)
- String system variables
v5.0.0.0
New CGTP Protocol Support
A new CGTP Web Server client has been added, providing access to the HTTP-based RPC interface available on FANUC controllers (default port: 3080).
This lightweight, firewall-friendly protocol complements the existing SNPX, RMI, Telnet, and FTP connections and is enabled by default when connecting.
Feature:
- Create, delete, rename programs
- Read and write program attributes: comment, owner, stack size, write-protection, ignore-pause flag, and sub-type
- Run, abort, and pause programs
- Select a program and set the cursor to a specific line
- Change the active TP program
- Read and write system and program variables by name
- List files on the controller (
MD:or other devices) - Read file contents as text
A CgtpClient class is available for direct use without a FanucRobot instance.
Connection Parameters Changes
- Telnet and FTP are now disabled by default, enable them explicitly via
ConnectionParameters.Telnet.EnableandConnectionParameters.Ftp.Enable - CGTP is enabled by default, disable via
ConnectionParameters.Cgtp.Enable = false
SNPX Fixes
- Null terminators (
\0) are now correctly trimmed from string values returned when reading string registers and string variables
SNPX String Registers Simplification
StringRegistersSpanhas been removed from the public SDK API because it made SNPX usage harder to understand.- Use
StringRegistersfor string register read/write. - Important:
StringRegisters.StringLengthis static. Set it once before any string register read/write, and do not change it while the SDK is running. - Default value remains
80.
Examples:
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Snpx.Internal;
var robot = new FanucRobot();
robot.Connect("192.168.0.10");
// Configure once before any SR[] read/write.
StringRegisters.StringLength = 100; // default size is 80
// Write and read a string register.
robot.Snpx.StringRegisters.Write(1, "HELLO FANUC");
string value = robot.Snpx.StringRegisters.Read(1);v4.8.0.0
SNPX : Comments and Simulation Status
New feature : Comments
New Comments accessor allows reading and writing comments of registers, position registers, string registers and I/O signals via SNPX.
// Read the comment of R[1] (default 16 characters)
string comment = robot.Snpx.Comments.Read(CommentType.Register, 1);
// Read the comment of DI[3] with a custom length
string diComment = robot.Snpx.Comments.Read(CommentType.DI, 3);
// Write a comment to PR[5]
robot.Snpx.Comments.Write(CommentType.PositionRegister, 5, "My position");Supported types: Register, PositionRegister, StringRegister, DI, DO, RI, RO, UI, UO, SI, SO, WI, WO, WSI, WSO, GI, GO, AI, AO.
New feature : Simulation Status
New SimulationStatus accessor allows reading and writing the simulation state of I/O signals via SNPX.
// Check if DI[1] is simulated
bool isSimulated = robot.Snpx.SimulationStatus.Read(SimulationType.DI, 1);
// Enable simulation on RO[2]
robot.Snpx.SimulationStatus.Write(SimulationType.RO, 2, true);
// Disable simulation on GI[5]
robot.Snpx.SimulationStatus.Write(SimulationType.GI, 5, false);Supported types: DI, DO, RI, RO, WI, WO, WSI, WSO, GI, GO, AI, AO.
Telnet : Fix premature response finalization on non-English controllers
Fixed an issue where Telnet KCL commands (e.g. GetVariable, SetVariable) could fail on non-English controllers (Chinese, Japanese...) due to intermediate VT100 display-update frames being incorrectly interpreted as the end of a response.
On some controllers, status bar refresh frames (containing only ANSI escape sequences) arrive before the actual command response data. These empty frames were causing the result to be finalized prematurely, leading to missing or empty values.
A new mechanism now allows multi-frame results (GetVariableResult, SetVariableResult, BreakpointsResult) to defer finalization until meaningful data has actually been received.
SNPX : String registers span and fixes
New feature : String registers span
New StringRegistersSpan accessor allows reading and writing substrings of string registers (SR[]) with control over start index and length.
// Read 10 characters starting at position 4 from SR[1]
string value = robot.Snpx.StringRegistersSpan.Read(registerIndex: 1, stringLength: 10, stringStartIndex: 4);
// Write a substring into SR[2]
robot.Snpx.StringRegistersSpan.Write(registerIndex: 2, value: "Hello", stringLength: 10, stringStartIndex: 0);Fix for writing empty strings
Allow SNPX to write empty strings to string variables and string registers. String encoding now uses fixed-length byte buffers, preventing issues with empty or odd-length strings.
Fix missing assignable elements
NumericRegistersInt16, NumericRegistersInt32, StringRegistersSpan and Flags are now correctly included in SNPX assignable elements, ensuring ClearAssignments() and GetAssignments() cover all element types.