Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions ur_rtde_client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
cmake_minimum_required(VERSION 3.16)
project(ur_rtde_client)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(example_interfaces REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(builtin_interfaces REQUIRED)
find_package(ur_client_library REQUIRED)
find_package(yaml-cpp REQUIRED)
find_package(ament_index_cpp REQUIRED)
find_package(tf2 REQUIRED)
find_package(tf2_ros REQUIRED)
find_package(tf2_geometry_msgs REQUIRED)
find_package(ur_dashboard_msgs REQUIRED)

add_library(${PROJECT_NAME}_lib
src/publisher.cpp
src/rtde_manager.cpp
src/converter.cpp
)
target_include_directories(${PROJECT_NAME}_lib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(${PROJECT_NAME}_lib PUBLIC
rclcpp::rclcpp
tf2::tf2
tf2_ros::tf2_ros
tf2_geometry_msgs::tf2_geometry_msgs
${example_interfaces_TARGETS}
${geometry_msgs_TARGETS}
${sensor_msgs_TARGETS}
${builtin_interfaces_TARGETS}
${ur_dashboard_msgs_TARGETS}
sensor_msgs::sensor_msgs_library
ur_client_library::urcl
yaml-cpp
)

add_executable(rtde_client_node
src/rtde_client_node.cpp
)
target_link_libraries(rtde_client_node PUBLIC
${PROJECT_NAME}_lib
ament_index_cpp::ament_index_cpp
rclcpp::rclcpp
)

install(TARGETS ${PROJECT_NAME}_lib rtde_client_node
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION lib/${PROJECT_NAME}
)
install(DIRECTORY include/
DESTINATION include
Comment on lines +58 to +59
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't provide a library in this package, there is not really a point in installing the headers.

)
install(DIRECTORY launch
DESTINATION share/${PROJECT_NAME}
)
install(DIRECTORY config
DESTINATION share/${PROJECT_NAME}
)

ament_package()
28 changes: 28 additions & 0 deletions ur_rtde_client/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License

Copyright (c) 2026, Sergi Romero
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright (c) 2026, Sergi Romero
Copyright (c) 2026, Universal Robots A/S


Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3 changes: 3 additions & 0 deletions ur_rtde_client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# ur_rtde_client

A ROS 2 package providing a real-time RTDE client for Universal Robots manipulators. It reads robot state fields (e.g. robot mode, safety status, timestamps) via UR’s RTDE protocol and publishes them as ROS 2 topics.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, a short usage example would be great to add here.

194 changes: 194 additions & 0 deletions ur_rtde_client/config/rtde_map.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
rtde_variables:
DOUBLE_to_Float64:
rtde_type: "DOUBLE"
output_type: "example_interfaces/Float64"
variables:
- "speed_scaling"
- "target_speed_fraction"
- "actual_momentum"
- "actual_main_voltage"
- "actual_robot_voltage"
- "actual_robot_current"
- "standard_analog_input0"
- "standard_analog_input1"
- "standard_analog_output0"
- "standard_analog_output1"
- "io_current"
- "input_double_register_<0-47>"
- "output_double_register_<0-47>"
- "actual_robot_energy_consumed"
- "actual_robot_braking_energy_dissipated"
- "euromap67_24V_voltage"
- "euromap67_24V_current"
- "tool_analog_input0"
- "tool_analog_input1"
- "tool_output_current"
- "tcp_force_scalar"
- "joint_position_deviation_ratio"
- "collision_detection_ratio"
- "payload"

INT32_to_INT32:
rtde_type: "INT32"
output_type: "example_interfaces/Int32"
variables:
- "input_int_register_<0-47>"
- "output_int_register_<0-47>"
- "encoder0_raw"
- "encoder1_raw"
- "tool_output_voltage"
- "time_scale_source"

BOOL_to_BOOL:
rtde_type: "BOOL"
output_type: "example_interfaces/Bool"
variables:
- "input_bit_register_<64-127>"
- "output_bit_register_<64-127>"

VECTOR6INT_to_Int32MultiArray:
rtde_type: "VECTOR6INT"
output_type: "example_interfaces/Int32MultiArray"
variables:
- "joint_mode"

VECTOR3D_to_GeometryMsgVector3:
rtde_type: "VECTOR3D"
output_type: "geometry_msgs/Vector3Stamped"
variables:
- "target_gravity"

VECTOR6D_to_GeometryMsgTwist:
rtde_type: "VECTOR6D"
output_type: "geometry_msgs/TwistStamped"
variables:
- "actual_TCP_speed"
- "target_TCP_speed"

VECTOR6D_to_GeometryMsgWrench:
rtde_type: "VECTOR6D"
output_type: "geometry_msgs/WrenchStamped"
variables:
- "actual_TCP_force"
- "ft_raw_wrench"
- "wrench_calc_from_currents"

VECTOR6D_to_GeometryMsgAccel:
rtde_type: "VECTOR6D"
output_type: "geometry_msgs/AccelStamped"
variables:
- "actual_TCP_acceleration"
- "target_TCP_acceleration"
- "actual_tool_accelerometer"

VECTOR6D_to_GeometryMsgPose:
rtde_type: "VECTOR6D"
output_type: "geometry_msgs/PoseStamped"
variables:
- "actual_TCP_pose"
- "target_TCP_pose"
- "tcp_offset"

VECTOR3D_to_GeometryMsgTwist:
rtde_type: "VECTOR3D"
output_type: "geometry_msgs/TwistStamped"
variables:
- "elbow_velocity"

VECTOR3D_to_GeometryMsgPoint:
rtde_type: "VECTOR3D"
output_type: "geometry_msgs/PointStamped"
variables:
- "elbow_position"
- "payload_cog"

VECTOR6D_to_GeometryMsgInertia:
rtde_type: "VECTOR6D"
output_type: "geometry_msgs/InertiaStamped"
variables:
- "payload_inertia"

DOUBLE_to_Temperature:
rtde_type: "DOUBLE"
output_type: "sensor_msgs/Temperature"
variables:
- "tool_temperature"

VECTOR6D_to_Float64MultiArray:
rtde_type: "VECTOR6D"
output_type: "example_interfaces/Float64MultiArray"
variables:
- "target_q"
- "target_qd"
- "target_qdd"
- "target_current"
- "target_moment"
- "actual_q"
- "actual_qd"
- "actual_current"
- "actual_current_window"
- "actual_current_as_torque"
- "joint_control_output"
- "joint_temperatures"
- "actual_joint_voltage"
- "target_base_acceleration"

DOUBLE_to_BuiltinInterfaces:
rtde_type: "DOUBLE"
output_type: "builtin_interfaces/Time"
variables:
- "timestamp"
- "actual_execution_time"
- "target_execution_time"

UINT64_to_ByteMultiArray:
rtde_type: "UINT64"
output_type: "example_interfaces/ByteMultiArray"
variables:
- "actual_digital_input_bits"
- "actual_configurable_digital_input_bits"
- "actual_digital_output_bits"
- "actual_configurable_digital_output_bits"

UINT32_to_ByteMultiArray:
rtde_type: "UINT32"
output_type: "example_interfaces/ByteMultiArray"
variables:
- "robot_status_bits"
- "safety_status_bits"
- "analog_io_types"
- "input_bit_registers0_to_31"
- "input_bit_registers32_to_63"
- "output_bit_registers0_to_31"
- "output_bit_registers32_to_63"
- "euromap67_input_bits"
- "euromap67_output_bits"
- "tool_analog_input_types"

UINT32_to_UINT32:
rtde_type: "UINT32"
output_type: "example_interfaces/UInt32"
variables:
- "runtime_state"
- "tool_mode"
- "script_control_line"

UINT8_to_UINT8:
rtde_type: "UINT8"
output_type: "example_interfaces/UInt8"
variables:
- "tool_output_mode"
- "tool_digital_output0_mode"
- "tool_digital_output1_mode"

INT32_to_ROBOT_MODE:
rtde_type: "INT32"
output_type: "ur_dashboard_msgs/RobotMode"
variables:
- "robot_mode"

INT32_to_SAFETY_MODE:
rtde_type: "INT32"
output_type: "ur_dashboard_msgs/SafetyMode"
variables:
- "safety_mode"
Loading