Skip to content
Svastits edited this page Aug 27, 2026 · 5 revisions

KSS and iiQKA.OS2 drivers (RSI)

This guide provides instructions for setting up and using the RSI-based ROS 2 driver for KUKA robots running on KUKA System Software (KSS) and iiQKA.OS2.

The driver supports three configurations on both KSS and iiQKA.OS2:

  • rsi_only: Uses only the RSI channel.
  • eki_rsi: Uses EKI for non-real-time startup/status handling and RSI for cyclic control.
  • mxa_rsi: Uses mxAutomation for non-real-time startup/status handling and RSI for cyclic control.

The integration of EKI and mxA not only helps the initiation of external control but also unlocks additional capabilities via ROS 2 controllers.

Test setups

The following tables contain the exact versions used for testing the driver.

KSS tested configurations

Controller Robot KSS Version EthernetKRL Version RSI Version
KR C4 OPS 8.6.11 3.1.4 4.1.3
KR C5 OPS 8.7.5 3.2.5 5.0.2
KR C5 KR 120 R2700-2 Dummy 8.7.5 3.2.5 5.0.2
KR C5 KR 6 R900-2 8.7.5 3.2.5 5.0.2

iiQKA.OS2 tested configurations

Controller Robot iiQKA.OS2 Version RSI Version
KR C5 OPS 9.1.0 6.1.2
KR C5 KR 16 R1610-2 9.1.0 6.1.2
KR C5 micro-2 LBR iisy 3 R760 9.3.0 6.3.0

Client-side setup

It is recommended to run the driver on a real-time capable client machine. Detailed instructions for setting up the PREEMPT_RT path are available on the Realtime wiki page.

To be able to connect to RSI running on the controller, a fixed IP in the subnet of the RSI interface is required on the Linux machine.

Controller-side setup (OS-specific)

To set up the controller with WorkVisual/iiQWorks.Sim, a Windows machine is also required with a fixed IP in the subnet of the KLI interface for transferring the project.

KSS setup

Use the SDK setup guide for all KSS controller-side steps (network, file deployment, wrappers):

Setups for all three versions (rsi_only, eki_rsi, mxa_rsi) are available in this file.

iiQKA.OS2 setup (RSI 6.x)

Use the SDK setup guide for all iiQKA.OS2 controller-side steps (network, file deployment, wrappers):

Setups for all three versions (rsi_only, eki_rsi, mxa_rsi) are available in this file.

Driver configuration

Startup configuration

The following configuration files are available in the config directory of the package:

  • driver_config.yaml: contains runtime parameters of the robot_manager node
  • ros2_controller_config.yaml: contains the controller types for every controller name. Should be only modified if a different controller is to be used.
  • configuration files for specific controllers, for further information, see the documentation of the given controller

Runtime parameters

The parameters in the driver configuration file can be changed during runtime using the parameter interface of the robot_manager node:

  • position_controller_name: The name of the controller (string) that controls the position interface of the robot. It can't be changed in active state.
  • cycle_time: The cycle time of RSI communication either 1 (4ms) or 2 (12ms). It can't be changed in active state.

I/O configuration

KSS and iiQKA.OS2 support inputs and outputs for real-time usage through RSI. The I/Os are defined from the robot controller's point of view: an input can only have state interfaces in ROS Control, while an output can have both state and command interfaces.

RSI groups the I/Os into three categories:

  • BOOL: The I/Os act as two-state signals and can be set to true or false.
  • DOUBLE: The I/Os can store decimal numbers represented in floating-point format.
  • LONG: The I/Os can store whole numbers using a 64-bit integer representation.

Generally, only a few constraints are imposed on naming the I/Os:

  • The names of the I/Os must be unique keys.
  • The names must be unique across both the state and command interfaces.
  • Since outputs can have both state and command interfaces, if these interfaces are configured with the same name, they are considered connected. In this case, the system will handle them by first reading the state of the output, then writing to it via the command interface.

Controller-side configuration

Example GPIO configuration files are available in the kuka_external_control_sdk/krc_setup directory for both operating systems:

File KSS iiQKA.OS2
RSI context kss/Config/User/Common/SensorInterface/rsi_gpio_joint_pos.rsix iiqka_os2/RobotSensorInterface/Context/rsi_gpio_joint_pos.rsix
Ethernet config kss/Config/User/Common/SensorInterface/rsi_gpio_ethernet.xml iiqka_os2/RobotSensorInterface/Ethernet_configuration/rsi_gpio_ethernet.xml
Example program kss/KRC/R1/Program/rsi_gpio_example.src iiqka_os2/Program/RSI/rsi_gpio_example.src

RSI context file (rsi_gpio_joint_pos.rsix):

  • Provides an example of how to set up the different I/Os. For detailed instructions, refer to the RSI manual on KUKA Xpert.
  • The file can be edited via RSI Visual in WorkVisual (KSS) or iiQWorks.App Builder (iiQKA.OS2).
  • All I/Os should be connected to the inputs or outputs of the Ethernet RSI object.

Ethernet configuration file (rsi_gpio_ethernet.xml):

  • The <SEND> object contains all parameters that are sent to the client.

  • The <RECEIVE> object contains all the parameters that are received from the client.

  • Each I/O element requires the following common parameters:

    • TAG: Contains the aforementioned unique key. The tag format is: Prefix.UniqueKey. The provided examples use GPIO as the prefix (e.g., GPIO.OUTPUT_01), but this can be customized via the rsi_xml_config_file launch argument (see RSI XML message configuration).
    • TYPE: The type can be one of the following: BOOL, DOUBLE, or LONG.
    • INDX: This must match the configuration of the I/O object in RSI Visual for the Ethernet object. This is the only parameter that connects the XML file entries to those in the .rsix file.
  • Elements in the <RECEIVE> object support one additional parameter:

    • HOLDON: Sets the behavior of the output when packets are missed:
      • 0: The output is reset.
      • 1: The most recent valid value remains at the output.
  • A sample configuration for one I/O element:

    <ELEMENT TAG="GPIO.OUTPUT_01" TYPE="DOUBLE" INDX="1" HOLDON="1" />

Client side I/O configuration

To configure the client side, two configuration files need to be completed:

  1. The kuka_rsi_driver/config/gpio_config.xacro file is an extension to the robot's URDF and contains a <gpio> tag as part of the ROS Control parameters.
    • The GPIO object must be called gpio.
    • The state and command interfaces must be configured according to the example provided in the file.
    • For each interface, several additional parameters are available:
      • name: The previously mentioned unique key.
      • data_type: The data type of the interface. Must be one of the three supported by RSI: BOOL, DOUBLE, or LONG.
      • limits: Enables additional limit checking (defaults to true).
      • min: Minimum value for limit checking. (If not used or used incorrectly, limits is set to false.)
      • max: Maximum value for limit checking. (If not used or used incorrectly, limits is set to false.)
      • initial_value: Initial value of the interface. The value must be in a number format for every data type. Mostly useful for outputs without a state interface, as this value is otherwise overridden during the first cycle.
  • To set up the provided example, uncomment the constructed interfaces in the gpio_config.xacro config file.

  • An example with both state and command interfaces with all parameters:

    <command_interface name="OUTPUT_01" data_type="DOUBLE">
      <limits enable="true"/>
      <param name="min">0.0</param>
      <param name="max">100.0</param>
    </command_interface>
    <state_interface name="OUTPUT_01" data_type="DOUBLE">
      <limits enable="true"/>
      <param name="min">0.0</param>
      <param name="max">100.0</param>
      <param name="initial_value">50.0</param>
    </state_interface>
  1. The kuka_rsi_driver/config/gpio_controller_config.yaml file defines the configuration for the I/O controller.
    • For I/O control, the GpioCommandController from ROS Control is used.
    • The controller requires a configuration file that describes the available state and command interfaces.
    • The gpios field contains a list of available GPIO interface groups. Currently, only one group is supported, and it must be named gpio.
    • Additionally, the file contains lists of available state and command interfaces:
      • These must be listed in groups, as explained in the linked controller documentation.
      • Ensure that the interface names match those defined earlier.

RSI XML message configuration

By default, the driver uses the default RSI XML element names inherited from the kuka-external-control-sdk (RIst, AIPos, AK, EK, etc.) and the provided rsi_ethernet.xml is already aligned with these defaults. If your RSI context file uses different XML element or attribute names (for example when adding a custom RSIX context), you can configure the driver to match by providing a YAML file.

YAML configuration file

An annotated example is provided at kuka_rsi_driver/config/rsi_xml_config_example.yaml. Copy and adapt it to match your setup:

rsi_xml_config:
  motion_state:                    # XML elements received from the KRC
    cartesian:
      xml_element: "RIst"
    joints:
      positions:                   # required: one position entry per joint, in URDF order
        - joint_identifier: "joint_1"
          xml_element: "AIPos"
          xml_attribute: "A1"
        # ... repeat for each joint
      velocities:                  # optional: one velocity entry per joint
        - joint_identifier: "joint_1"
          xml_element: "AIVel"
          xml_attribute: "A1"
        # ... repeat for each joint
      torques:                     # optional: one torque entry per joint
        - joint_identifier: "joint_1"
          xml_element: "AITor"
          xml_attribute: "A1"
        # ... repeat for each joint
    gpio:                          # omit if no GPIO state interfaces
      xml_element: "GPIO"
      xml_attributes: ["01", "02"]
  control_signal:                  # XML elements sent to the KRC
    joints:
      xml_element: "AK"
    velocities:                    # optional, disabled by default
      enabled: true
      xml_element: "VK"
    torques:                       # optional, disabled by default
      enabled: true
      xml_element: "TK"
    ext_joints:                    # omit if no external axes
      xml_element: "EK"
      xml_attributes: ["E1"]
    ext_velocities:                # optional external velocity mapping
      xml_element: "EVK"
      xml_attributes: ["E1"]
    ext_torques:                   # optional external torque mapping
      xml_element: "ETK"
      xml_attributes: ["E1"]
    gpio:                          # omit if no GPIO command interfaces
      xml_element: "GPIO"

Delay (<Delay D="..."/>) and IPOC (<IPOC>...</IPOC>) are always parsed/sent as fixed RSI built-ins and are not configurable from this YAML mapping.

Joint positions are always required in motion-state mapping (motion_state.joints.positions). Velocity and torque mappings (motion_state.joints.velocities, motion_state.joints.torques) are optional and can be enabled independently.

Velocity and torque transmission are disabled by default for outgoing control signals. To include them in outgoing RSI messages, add control_signal.velocities / control_signal.torques (and optionally ext_velocities / ext_torques for external axes).

Pass the absolute path to this file using the rsi_xml_config_file launch argument (see Launch arguments).

Note

If rsi_xml_config_file is not set, the driver uses the SDK defaults. For a standard setup with the provided rsi_ethernet.xml and rsi_joint_pos.rsix files, no custom YAML file is needed. The kuka_rsi_simulator can use the same file via its rsi_xml_config_file launch argument.

Generating the KRC ethernet configuration file

Instead of manually editing rsi_ethernet.xml, the generate_krc_rsi_config script can generate it automatically from the same YAML file:

ros2 run kuka_rsi_driver generate_krc_rsi_config.py \
    --config /path/to/rsi_xml_config.yaml \
    --client-ip <ROS_PC_IP> \
    --client-port 59152 \
    --output rsi_ethernet.xml
Argument Description Default
--config Path to the YAML config file (required)
--client-ip IP address of the ROS PC as seen from the KRC (required)
--client-port UDP port the driver listens on 59152
--output Output file path rsi_ethernet.xml

Upload the generated file to the controller as described in Update and upload configuration files.

Note

In the SEND section, motion-state groups that use the default KRC element names are emitted using the KRC built-in shortcuts (RIstDEF_RIst, AIPosDEF_AIPos, EIPosDEF_EIPos), and Delay is always emitted as DEF_Delay after all configurable SEND fields. Groups that use custom element/attribute names are expanded into individual, explicitly-indexed <ELEMENT> entries so the generated file matches your YAML exactly. Such custom SEND element names require a matching custom RSIX context configured on the KRC side.

Note

Automatic detection of the number of internal and external axes relies on the default RSI position element names (AIPos for internal axes and EIPos for external axes). If custom position element names are used, axis types can no longer be inferred reliably from the RSI XML configuration. In such cases, the configuration for all internal and external axes must be specified explicitly, or the default naming convention should be preserved.

Note

If torque or velocity command/state interfaces are not configured in the provided YAML file, they will still be exported to ROS 2 Control. However, their state values will remain at the default value (NaN) and will not be updated with measurements from the robot. Likewise, commands written to these interfaces will not be forwarded to the robot.

Note

A configuration is considered custom whenever it does not use the default RSI names, or when it includes values beyond joint positions (AIPos) and cartesian positions (RIst). In these cases, the corresponding RSI context must be created and maintained by the user. We cannot provide a prebuilt RSI context for every possible custom use case.

Usage

Starting the driver

  1. To start the driver, two launch files are available, with and without rviz. To launch (without rviz), run:

    ros2 launch kuka_rsi_driver startup.launch.py
    • This starts the 3 core components of every driver (described in the Non-real-time interface section of the project overview) and the following controllers:
      • joint_state_broadcaster (no configuration file, all state interfaces are published)
      • joint_trajectory_controller (configuration file)
    • There is no need to set the Client IP, since the driver automatically listens on the 0.0.0.0 address.
    • After successful startup, the robot_manager node has to be activated to start the cyclic communication with the robot controller, see further steps (before this only a collapsed robot is visible in rviz):
  2. Configure and activate all components of the driver:

    ros2 lifecycle set robot_manager configure
    ros2 lifecycle set robot_manager activate
    • The hardware interface is now waiting for the robot controller to connect, the timeout for this is currently 10 seconds
  3. Start external control according to your driver_version:

  • rsi_only: start the RSI program manually on the controller and execute RSI_MOVECORR().
    • in T1, a warning (!!! Attention - Sensor correction goes active !!!) should be visible after reaching RSI_MOVECORR(), which should be confirmed to start this step
  • eki_rsi or mxa_rsi: RSI program is automatically selected and started

On successful activation the brakes of the robot will be released and external control is started. To test moving the robot, the rqt_joint_trajectory_controller is not recommended, use the launch file in the moveit_example package instead (found in examples repo, usage is described in the Additional packages section of the project overview).

Launch arguments

Both launch files support the following arguments:

  • client_port: port of the client machine (default: 59152)
  • controller_ip: The IP address of the KUKA Line Interface (KLI) - not used for rsi_only setup
  • mxa_client_port: port of the client machine where mxAutomation packets are received (default: 1337)
  • robot_model and robot_family: defines which robot to use. The available options for the valid model and family combinations can be found in the readme of the kuka_robot_descriptions repository.
  • mode: if set to 'mock', the KukaMockHardwareInterface will be used instead of the KukaRSIHardwareInterface. This enables trying out the driver without actual hardware.
  • use_gpio: if set to false the usage of I/Os are disabled (defaults to true).
  • namespace: adds a namespace to all nodes and controllers of the driver, and modifies the prefix argument of the robot description macro to namespace_
  • x, y, z: define the position of base_link relative to the world frame in meters (default: [0, 0, 0])
  • roll, pitch, yaw: define the orientation of base_link relative to the world frame in radians (default: [0, 0, 0])
  • roundtrip_time: The roundtrip time (in microseconds) to be enforced by the KUKA mock hardware interface, (defaults to 4000 us, only used if mode is set to 'mock')
  • controller_config_dir: the directory that contains all controller configuration files (defaults to kuka_rsi_driver/config). The driver expects the following file names in this directory:
    • ros2_controller_config_rsi_only.yaml (used when driver_version:=rsi_only)
    • ros2_controller_config_extended.yaml (used when driver_version:=eki_rsi or driver_version:=mxa_rsi)
    • joint_trajectory_controller_config.yaml (or joint_trajectory_controller_config_6_axis_kl.yaml if use_external_axis is set to true)
    • kuka_event_broadcaster_config.yaml
    • gpio_controller_config.yaml (used only if use_gpio:=true)
    • kuka_control_mode_handler_config.yaml (used only if driver_version:=eki_rsi or mxa_rsi)
    • kuka_kss_message_handler_config.yaml (used only if driver_version:=eki_rsi or mxa_rsi)
  • use_external_axis: if set to true, enables KL (linear track) composition using the kuka_resources/urdf/robot_with_external_axis_template.urdf.xacro template (defaults to false)
  • kl_model: the KL model to use when use_external_axis is enabled (default: kl100_2)
  • kl_support_package: the ROS package providing the KL description (default: kuka_kl_support)
  • kl_prefix: the prefix applied to KL joints and links (default: rail_). When changed, rail_ must be replaced manually with the new value in kuka_rsi_driver/config/joint_trajectory_controller_config_6_axis_kl.yaml and in any other configuration files that reference KL joint names (e.g. RViz, MoveIt, or Gazebo config files). The effective external-axis prefix will eventually be namespace_ + kl_prefix.
  • kl_ros2_control_macro_file: path to the ros2_control xacro macro file for the KL unit (default: kl_ros2_control_macro.xacro). Override this to use a third-party rail package that provides its own ros2_control macro entry point.
  • kl_ros2_control_joints_macro: name of the ros2_control joints macro within kl_ros2_control_macro_file (default: kuka_kl_ros2_control_joints). Override together with kl_ros2_control_macro_file for third-party rail packages.
  • kl_srdf_macro_file: path to the SRDF xacro macro file for the KL unit (default: kl_macro.xacro). Override for third-party rail packages that provide their own SRDF macro.
  • kl_srdf_adjacent_links_macro: name of the adjacent links macro within kl_srdf_macro_file, used to suppress collision checking between the rail and robot links (default: kl_srdf_adjacent_links). Override together with kl_srdf_macro_file for third-party rail packages.
  • driver_version: configures which driver to use. Possible values are rsi_only, eki_rsi and mxa_rsi (defaults to rsi_only)
  • verify_robot_model: If set to true and driver_version is set to eki_rsi or mxa_rsi, the driver will verify that the robot model specified in the launch arguments matches the configuration reported by the controller. If set to false, the reported configuration won't be checked (defaults to true).
  • rsi_xml_config_file: Absolute path to an RSI XML config YAML file. When set, configures the XML element and attribute names used in RSI messages to match the provided file. Leave empty to use the SDK defaults (defaults to empty string). See RSI XML message configuration for details.
  • rt_core: CPU core index for taskset pinning of the realtime control thread. (default: -1 = do not pin)
  • rt_prio: The realtime priority of the thread that runs the control loop [0-99] (default: 70)
  • non_rt_cores: Comma-separated CPU core indices for taskset pinning of non-RT threads (e.g. '2,3,4'). Leave empty to disable pinning. (defaults to empty string)
  • lock_memory: Whether to lock memory of the control loop with mlockall to avoid paging (defaults to true)
  • enable_rsi_monitoring: If set to true, starts an additional non-invasive UDP port monitor node that passively monitors RSI communication and reports communication statistics when the driver is stopped (defaults to false).

Note

The rt_core and rt_prio, parameters are not applied to asynchronous hardware interfaces. For async hardware configuration, use the async_thread_priority and async_affinity xacro arguments instead.

The startup_with_rviz.launch.py additionally contains one argument:

  • rviz_config: the location of the rviz configuration file (defaults to kuka_resources/config/view_6_axis_urdf.rviz)

Details about the mode parameter can be viewed in the kuka_robot_descriptions README.

When enable_rsi_monitoring:=true is used, the UDP port monitor uses Scapy to passively sniff traffic on client_port (the RSI port), auto-detects the peer sender port from the first sent RSI packet, and correlates packets by <IPOC> value. Summary statistics are calculated only from matching receive/set packet pairs. Running rsi_monitor_node requires root privileges (or equivalent packet-capture capabilities such as CAP_NET_RAW/CAP_NET_ADMIN).

Dual-arm launch

It is also possible to start a dual-arm setup with a single launch file:

ros2 launch kuka_rsi_driver dual_arm_startup.launch.py

The driver has to be configured and activated the same way, as for a single arm. The same launch arguments are also available for this, the names prefixed with robot1_ and robot2_ (e.g. robot1_family).

Stopping external control

To stop external control, all components have to be deactivated with ros2 lifecycle set robot_manager deactivate

BEWARE, that this is a non-realtime process including lifecycle management, so the connection is not terminated immediately, in cases where an abrupt stop is needed, the safety stop of the Teach Pendant should be used!

Simulation

To try out the driver with an open-loop simulation, the driver and the kuka_rsi_simulator must be started, (before activation only a "collapsed" robot will be visible in rviz):

ros2 launch kuka_rsi_driver startup_with_rviz.launch.py
ros2 launch kuka_rsi_simulator kuka_rsi_simulator.launch.py

To run the simulator with a custom RSI XML mapping, pass the same config file used by the driver:

ros2 launch kuka_rsi_simulator kuka_rsi_simulator.launch.py \
    rsi_xml_config_file:=/absolute/path/to/rsi_xml_config.yaml

If rsi_xml_config_file is left empty, the simulator uses the same defaults as the driver.

After all components have started successfully, the system needs to be configured and activated to start the simulation. The robot will be visible in rviz after activation:

ros2 lifecycle set robot_manager configure
ros2 lifecycle set robot_manager activate

External axes configuration

Both KSS and the RSI option package support adding external axes to the robot. We provide an example that integrates a single linear axis. This example, together with the structure and documentation, should help users implement their own external‑axis configurations.

Controller-side configuration

Context

The Config/User/Common/SensorInterface/rsi_ext_axis_example.rsix contains an example setup with one linear external axis.

Compared to the original context the following changes were required:

  • Add the AxisCorrExt object.
  • Connect Ethernet object's Out8 output to the first input of AxisCorrExt.
  • Update the LowerLimE1 and UpperLimE1 parameters of AxisCorrExt.
  • Update the MaxE1 parameter of the AxisCorrMon object.

To create a new custom context:

  • Connect the next OutX output of the Ethernet object to the corresponding CorrEX input of AxisCorrExt for each external axis.
  • Adjust limits (MaxEX, LowerLimX, UpperLimX) accordingly.

Ethernet configuration

The configuration file referenced by the Ethernet object must also be updated. See the example in: Config/User/Common/SensorInterface/rsi_ext_axis_ethernet.xml.

The only difference from the original configuration is an additional line in the RECEIVE block:

<ELEMENT TAG="EK.E1" TYPE="DOUBLE" INDX="8" HOLDON="1" />

This allows RSI to parse data from the driver.

Important

Use a consistent naming convention for external-axis values (TAG="EK.EX"), incrementing X for each axis. Ensure INDX values also increase sequentially.

Important

When using GPIOs, list external axes before adding GPIO message configuration. The correct order is: internal axes → external axes → GPIOs.

Program

To adapt the KRL program for the external-axis example:

  • KSS: update the RSI context name in KRC/R1/Program/RSI/rsi_joint_pos_4ms.src or KRC/R1/Program/RSI/rsi_joint_pos_12ms.src to rsi_ext_axis_example.
  • iiQKA.OS2: update the CONTEXT_NAME variable in Program/RSI/rsi_joint_pos.dat to rsi_ext_axis_example.

For custom setups, use the name of the corresponding context file.

Client-side configuration

See the kuka_robot_descriptions README for all client-side configuration steps. The relevant launch arguments for enabling KL composition are described in the Launch arguments section (use_external_axis, kl_model, kl_prefix, and the third-party integration parameters).

Note

The driver supports only revolute and prismatic external joints.

Known issues and limitations

  • When using the RSI-only driver, controller-side errors do not deactivate the driver.
  • Cartesian position control mode is not yet supported.