Universal Robots+

Reading/Writing Profinet I/O registers in an URCap Installation Node

Hello,

I am trying to create an installation node that can shows several registers of the Profinet IO interface.

I am struggling to use the API IO, IO model, to get the values of the registers.

Basically, this function for reading/writing the profinet IO should have similar functions as the polyscope script:

  • read_input_boolean_register(address)
  • read_input_float_register(address)
  • read_input_integer_register(address)
  • read_output_boolean_register(address)
  • read_output_float_register(address)
  • read_output_integer_register(address)
  • write_output_boolean_register(address, value)
  • write_output_float_register(address, value)
  • write_output_integer_register(address, value)

Does anybody here have any experience reading/writing Profinet IO from a URCap?

Thanks in advance,

Regards,

Fernando

I have ever created urcap for reading/writing ethernet/ip.
How to read/write is the same for profinet I/O.

For reading I use RTDE client and for writing I use real time client(port 30003)

Hi Fuji,

Thanks for your answer, is it possible to get this URCap (and code?)

I am aware it is possible to read using RTDE. However, I am trying to get some example in Java Swing (without using a python code or C if possible)

I wonder, if is there any example already or if somebody has experience using the IO API model. I can’t find any example, and I don’t understand what the package com.ur.urcap.api.domain.io is actually for, if not for reading IO from the robot.

Regards,

Fernando

I have found this example code from UR.
Ill attach it here but you should be able to google robot real time reader java UR and find it aswell.

/**

  • Robot Realtime Reader

  • This class handles the realtime reading from the robot when the URCap needs it.
    */

//Used for reading from RealTime Client
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

// Used to map joint mode codes to a descriptive string
import java.util.HashMap;
import java.util.Map;

public class RobotRealtimeReader {

// IP address to read from
private final String TCP_IP;
// Port for real time client
private final int TCP_port;


/*****
 * Creates a new RealTime reader
 * Default Constructor
 * Uses localhost (127.0.0.1) and port 30003
 */
public RobotRealtimeReader() {
    this.TCP_IP = "127.0.0.1";
    this.TCP_port = 30003;
}

// Initialize a new array for storing received data from realtime interface
private double[] RealtimeMessage;

// Public method that reads a snapshot from real time client interface

/**
 * Reads data from the socket.
 */
public void readNow(){
    readSocket();
}

// Internal method that actually reads the data

/**
 * Reads data from the socket.
 */
private void readSocket(){
    try{
        // Create a new Socket Client
        Socket rt = new Socket(TCP_IP, TCP_port);
        if (rt.isConnected()){
            //logHandler.writeLog("RobotRealTimeReader", "Connected to UR Realtime Client");
        }

        // Create stream for data
        DataInputStream in;
        in = new DataInputStream(rt.getInputStream());

        // Read the integer available in stream
        int length = in.readInt();
        //logHandler.writeLog("RobotRealTimeReader", "Length is "+length);

        // Initialize size of RealtimeMessage be using received length
        RealtimeMessage = new double[length];
        // Add length integer to output array
        RealtimeMessage[0] = length;

        // Calculate how much data is available from the length
        int data_available = (length-4)/8;
        //logHandler.writeLog("RobotRealTimeReader", "There are "+data_available+" doubles available");

        // Loop over reading the available data
        int i = 1;
        while (i <= data_available){
            RealtimeMessage[i] = in.readDouble();
            //logHandler.writeLog("RobotRealTimeReader", "Index "+i+" is "+RealtimeMessage[i]);
            i++;
        }

        // Perform housekeeping
        in.close();
        rt.close();
        //logHandler.writeLog("RobotRealTimeReader", "Disconnected from UR Realtime Client");
    }
    catch (IOException e){
        //logHandler.writeLog("RobotRealTimeReader", e.toString());
    }
}

/**
 * Creating enum to map start index and lengths of data entries
 * According to specification of RealTimeClient in Excel sheet
 */
private enum RTinfo {
    // name			(index in plot, number of doubles)
    q_target		(2, 6),
    qd_target		(8, 6),
    qdd_target		(14, 6),
    q_actual		(32, 6),
    qd_actual		(38, 6),
    TCP_actual		(56, 6),
    TCPd_actual		(62, 6),
    TCP_force		(68, 6),
    TCP_target		(74, 6),
    TCPd_target		(80, 6),
    temp_joint		(87, 6),
    robotmode		(95, 1),
    jointmode		(96, 6),
    safetymode		(102, 1),
    tcp_accel		(109, 3),
    speedscaling	(118, 1),
    prgstate		(132, 1);
    // More data points could be added if desired, by following above example and according to specification.

    private final int index;
    private final int count;
    RTinfo(int index, int count){
        this.index = index;
        this.count = count;
    }
    private int index() {return index;}
    private int count() {return count;}
}

/**
 * Get the actual joint poisition.
 * @return double[]
 */

public double[] getActualJointPose(){
    double[] val = new double[RTinfo.q_actual.count()];
    int i = 0;
    while (i < RTinfo.q_actual.count()){
        val[i] = RealtimeMessage[RTinfo.q_actual.index()+i];
        ++i;
    }
    return val;
}

/**
 * Get the actual TCP pose.
 * @return double[]
 */

public double[] getActualTcpPose(){
    double[] val = new double[RTinfo.TCP_actual.count()];
    int i = 0;
    while (i < RTinfo.TCP_actual.count()){
        val[i] = RealtimeMessage[RTinfo.TCP_actual.index()+i];
        ++i;
    }
    return val;
}

/**
 * Get the program state.
 * @return double[]
 */

public double[] getPrgState(){
    double[] val = new double[RTinfo.prgstate.count()];
    int i = 0;
    while (i < RTinfo.prgstate.count()){
        val[i] = RealtimeMessage[RTinfo.prgstate.index()+i];
        ++i;
    }
    return val;
}

/**
 * Get the joint temperatures.
 * @return double[]
 */

public double[] getJointTemperatures(){
    double[] val = new double[RTinfo.temp_joint.count()];
    int i = 0;
    while (i < RTinfo.temp_joint.count()){
        val[i] = RealtimeMessage[RTinfo.temp_joint.index()+i];
        ++i;
    }
    return val;
}

/**
 * Get the robot mode.
 * @return double[]
 */

public double[] getRobotMode(){
    double[] val = new double[RTinfo.robotmode.count()];
    int i = 0;
    while (i < RTinfo.robotmode.count()){
        val[i] = RealtimeMessage[RTinfo.robotmode.index()+i];
        ++i;
    }
    return val;
}

/**
 * Get the safety mode.
 * @return double[]
 */

public double[] getSafetyMode() {
    double[] val = new double[RTinfo.safetymode.count()];
    int i = 0;
    while (i < RTinfo.safetymode.count()){
        val[i] = RealtimeMessage[RTinfo.safetymode.index()+i];
        ++i;
    }
    return val;
}

/**
 * Get joint status.
 * @return String
 */

public String[] getJointStatus(){
    // Create a map binding message code to state message
    // According to Excel sheet client interface specification
    Map<Double, String> jointStates = new HashMap<Double, String>();
    jointStates.put((double) 236, "SHUTTING_DOWN");
    jointStates.put((double) 237, "DUAL_CALIB_MODE");
    jointStates.put((double) 238, "BACKDRIVE");
    jointStates.put((double) 239, "POWER_OFF");
    jointStates.put((double) 245, "NOT_RESPONDING");
    jointStates.put((double) 246, "MOTOR_INIT");
    jointStates.put((double) 247, "BOOTING");
    jointStates.put((double) 248, "DUAL_CALIB_ERROR");
    jointStates.put((double) 249, "BOOTLOADER");
    jointStates.put((double) 250, "CALIBRATION_MODE");
    jointStates.put((double) 252, "FAULT");
    jointStates.put((double) 253, "RUNNING");
    jointStates.put((double) 255, "IDLE");

    String[] val = new String[RTinfo.jointmode.count()];
    int i = 0;
    while (i < RTinfo.jointmode.count()){
        // Read the code for given joint
        double code = RealtimeMessage[RTinfo.jointmode.index()+i];

        // Check if the key is known in the map
        if(jointStates.containsKey(code)){
            // Read corresponding message
            val[i] = jointStates.get(code);
        }
        else{
            // If unknown code, show "unknown"
            val[i] = "UNKNOWN_CODE";
        }
        ++i;
    }
    return val;
}

/**
 * Get the speed scale.
 * @return double
 */

public double getSpeedScaling(){
    double scaling = RealtimeMessage[RTinfo.speedscaling.index()];
    return scaling * 100; // Converted to percent
}

}

From the URCap developers at Airgate (www.airgate.dk)