Universal_Robots_ROS_Driver icon indicating copy to clipboard operation
Universal_Robots_ROS_Driver copied to clipboard

Rtde recipe publishing

Open t-schnell opened this issue 6 years ago • 23 comments

Implements automatic publishing of requested RTDE data to ROS topics.

t-schnell avatar Nov 12 '19 13:11 t-schnell

A high-level comment: publishing raw std_msgs is considered bad practice. Low semantic value and increased potential for (inadvertent) misuse.

Best practice suggests correctly typed topics should be used wherever possible.

Could the rationale for publishing these raw values be clarified, perhaps here in this issue or in some other place?

gavanderhoorn avatar Nov 14 '19 09:11 gavanderhoorn

A high-level comment: publishing raw std_msgs is considered bad practice. Low semantic value and increased potential for (inadvertent) misuse.

Best practice suggests correctly typed topics should be used wherever possible.

Could the rationale for publishing these raw values be clarified, perhaps here in this issue or in some other place?

The idea is that if users are interested in getting additional data from the RTDE interface they can do so without code modifications, but by only specifying them in the recipe. Publishing raw data is the only option that we see without explicitly preparing a publisher for each possible RTDE data field and instanciating them on-demand. We consider this more of an easy-access power-functionality instead of something out of the box.

fmauch avatar Nov 14 '19 10:11 fmauch

We consider this more of an easy-access power-functionality instead of something out of the box.

Unfortunately I expect this -- ie: raw values from RTDE recipies -- to become the default way people will start interacting with the driver over a ROS API.

As I believe one of the goals of this driver is to be an example of how to properly integrate a UR in a ROS environment, it would be nice if we could avoid including anti-patterns in it.

gavanderhoorn avatar Nov 14 '19 10:11 gavanderhoorn

We consider this more of an easy-access power-functionality instead of something out of the box.

Unfortunately I expect this -- ie: raw values from RTDE recipies -- to become the default way people will start interacting with the driver over a ROS API.

As I believe one of the goals of this driver is to be an example of how to properly integrate a UR in a ROS environment, it would be nice if we could avoid including anti-patterns in it.

You are probably right... Thanks for never letting me get away with laziness :-)

We'll take that into consideration and improve this PR.

fmauch avatar Nov 14 '19 10:11 fmauch

You are probably right... Thanks for never letting me get away with laziness :-)

That was not my intention, I don't want to be a gatekeeper here.

It's easy for me to write "this is not a nice solution", but it would be nice if I could provide alternatives then.

Perhaps an issue where the requirements and constraints could be listed could be used to drive some discussion?

Dynamic message generation would be possible, as would .msg generation based on RTDE recipies. At the very least we should probably try to use appropriate messages from geometry_msgs for certain types of data (ie: Vector3 and friends).

gavanderhoorn avatar Nov 14 '19 10:11 gavanderhoorn

You are probably right... Thanks for never letting me get away with laziness :-)

That was not my intention, I don't want to be a gatekeeper here.

I meant that in a positive way. The main reason we implemented it this was was laziness on implementing this for each message field. This dropped out of an internal requirement rather than belonging to the original plan.

At the very least we should probably try to use appropriate messages from geometry_msgs for certain types of data (ie: Vector3 and friends).

We've been discussing a bit and also came to this conclusion. We would leave simple datatypes as is, e.g. actual_main_voltage (double), use geometry_msgs where feasible and custom messages for things such as runtime_state, robot_status_bits, etc. where the integer representation has a certain meaning.

fmauch avatar Nov 14 '19 11:11 fmauch

So, we took the time to have a closer look at all the published data from RTDE:

rtde_to_ros_datatypes.xlsx

Any thoughts on this?

fmauch avatar Nov 18 '19 16:11 fmauch

Markdown version:

RTDE datatypes to ROS
Name UR-Datatype Comment Versioning ROS Datatype Comment Comment 2
timestamp DOUBLE Time elapsed since the controller was started [s] Introduced in version std_msgs/Time
target_q VECTOR6D Target joint positions custom_msg rtde_msgs/JointPosition
target_qd VECTOR6D Target joint velocities custom_msg rtde_msgs/JointVelocity
target_qdd VECTOR6D Target joint accelerations custom_msg rtde_msgs/JointAccelerations
target_current VECTOR6D Target joint currents custom_msg rtde_msgs/JointCurrents
target_moment VECTOR6D Target joint moments (torques) custom_msg rtde_msgs/JointTorques
actual_q VECTOR6D Actual joint positions custom_msg rtde_msgs/JointPosition
actual_qd VECTOR6D Actual joint velocities custom_msg rtde_msgs/JointVelocity
actual_current VECTOR6D Actual joint currents custom_msg rtde_msgs/JointAccelerations
joint_control_output VECTOR6D Joint control currents custom_msg rtde_msgs/JointCurrents
actual_TCP_pose VECTOR6D Actual Cartesian coordinates of the tool: (x,y,z,rx,ry,rz), where rx, ry and rz is a rotation vector representation of the tool orientation geometry_msgs/Pose
actual_TCP_speed VECTOR6D Actual speed of the tool given in Cartesian coordinates geometry_msgs/Twist
actual_TCP_force VECTOR6D Generalized forces in the TCP geometry_msgs/Wrench Already published through ROS Control
target_TCP_pose VECTOR6D Target Cartesian coordinates of the tool: (x,y,z,rx,ry,rz), where rx, ry and rz is a rotation vector representation of the tool orientation geometry_msgs/Pose
target_TCP_speed VECTOR6D Target speed of the tool given in Cartesian coordinates geometry_msgs/Twist
actual_digital_input_bits UINT64 Current state of the digital inputs. 0-7: Standard, 8-15: Configurable, 16-17: Tool ur_msgs/IOStates already published
joint_temperatures VECTOR6D Temperature of each joint in degrees Celsius custom_msg rtde_msgs/JointTemperatures Use sensor_msgs/Temperature as underlying type
actual_execution_time DOUBLE Controller real-time thread execution time std_msgs/Time
robot_mode INT32 Robot mode Please see Remote Control Via TCP/IP - 16496 ur_dashboards_msgs/RobotMode -> Should be moved to ur_msgs
joint_mode VECTOR6INT32 Joint control modes Please see Remote Control Via TCP/IP - 16496 custom_msg -> should be established inside ur_msgs
safety_mode INT32 Safety mode Please see Remote Control Via TCP/IP - 16496 ur_dashboard_msgs/SafetyMode -> Should be moved to ur_msgs
safety_status INT32 Safety ststus 3.10.0/5.4.0 custom_msg -> should be established inside ur_msgs
actual_tool_accelerometer VECTOR3D Tool x, y and z accelerometer values geometry_msgs/Vector3
speed_scaling DOUBLE Speed scaling of the trajectory limiter std_msgs/Float64
target_speed_fraction DOUBLE Target speed fraction std_msgs/Float64
actual_momentum DOUBLE Norm of Cartesian linear momentum std_msgs/Float64
actual_main_voltage DOUBLE Safety Control Board: Main voltage std_msgs/Float64
actual_robot_voltage DOUBLE Safety Control Board: Robot voltage (48V) std_msgs/Float64
actual_robot_current DOUBLE Safety Control Board: Robot current std_msgs/Float64
actual_joint_voltage VECTOR6D Actual joint voltages custom_msg rtde_msgs/JointVoltages
actual_digital_output_bits UINT64 Current state of the digital outputs. 0-7: Standard, 8-15: Configurable, 16-17: Tool ur_msgs/IOStates already published
runtime_state UINT32 Program state custom_msg -> should be established inside ur_msgs
elbow_position VECTOR3D Position of robot elbow in Cartesian Base Coordinates 3.5.0/5.0.0 geometry_msgs/Vector3
elbow_velocity VECTOR3D Velocity of robot elbow in Cartesian Base Coordinates 3.5.0/5.0.0 geometry_msgs/Vector3
robot_status_bits UINT32 Bits 0-3: Is power on | Is program running | Is teach button pressed | Is power button pressed custom_msg -> should be established inside ur_msgs
safety_status_bits UINT32 Bits 0-10: Is normal mode | Is reduced mode | | Is protective stopped | Is recovery mode | Is safeguard stopped | Is system emergency stopped | Is robot emergency stopped | Is emergency stopped | Is violation | Is fault | Is stopped due to safety custom_msg -> should be established inside ur_msgs
analog_io_types UINT32 Bits 0-3: analog input 0 | analog input 1 | analog output 0 | analog output 1, {0=current[A], 1=voltage[V]} ur_msgs/IOStates already published
standard_analog_input0 DOUBLE Standard analog input 0 [A or V] ur_msgs/IOStates already published
standard_analog_input1 DOUBLE Standard analog input 1 [A or V] ur_msgs/IOStates already published
standard_analog_output0 DOUBLE Standard analog output 0 [A or V] ur_msgs/IOStates already published
standard_analog_output1 DOUBLE Standard analog output 1 [A or V] ur_msgs/IOStates already published
io_current DOUBLE I/O current [A] std_msgs/Float64
euromap67_input_bits UINT32 Euromap67 input bits custom_msg Array of ur_msgs/Digital Not optimal but merging these into one common message would break the name?factory?msg pipeline
euromap67_output_bits UINT32 Euromap67 output bits custom_msg Array of ur_msgs/Digital
euromap67_24V_voltage DOUBLE Euromap 24V voltage [V] std_msgs/Float64
euromap67_24V_current DOUBLE Euromap 24V current [A] std_msgs/Float64
tool_mode UINT32 Tool mode Please see Remote Control Via TCP/IP - 16496 ur_msgs/ToolData already published
tool_analog_input_types UINT32 Output domain {0=current[A], 1=voltage[V]} Bits 0-1: tool_analog_input_0 | tool_analog_input_1 ur_msgs/ToolData already published
tool_analog_input0 DOUBLE Tool analog input 0 [A or V] ur_msgs/ToolData already published
tool_analog_input1 DOUBLE Tool analog input 1 [A or V] ur_msgs/ToolData already published
tool_output_voltage INT32 Tool output voltage [V] ur_msgs/ToolData already published
tool_output_current DOUBLE Tool current [A] ur_msgs/ToolData already published
tool_temperature DOUBLE Tool temperature in degrees Celsius ur_msgs/ToolData already published
tcp_force_scalar DOUBLE TCP force scalar [N] std_msgs/Float64
output_bit_registers0_to_31 UINT32 General purpose bits custom_msg Array of ur_msgs/Digital Not optimal but merging these into one common message would break the name?factory?msg pipeline
output_bit_registers32_to_63 UINT32 General purpose bits custom_msg Array of ur_msgs/Digital
output_bit_register_X BOOL 64 general purpose bits X: [64..127] - The upper range of the boolean output registers can be used by external RTDE clients (i.e URCAPS). 3.9.0 / 5.3.0 std_msgs/Bool
output_int_register_X INT32 48 general purpose integer registers X: [0..23] - The lower range of the integer output registers is reserved for FieldBus/PLC interface usage. X: [24..47] - The upper range of the integer output registers can be used by external RTDE clients (i.e URCAPS). [0..23] 3.4.0 [24..47] 3.9.0 / 5.3.0 std_msgs/Int32
output_double_register_X DOUBLE 48 general purpose double registers X: [0..23] - The lower range of the double output registers is reserved for FieldBus/PLC interface usage. X: [24..47] - The upper range of the double output registers can be used by external RTDE clients (i.e URCAPS). [0..23] 3.4.0 [24..47] 3.9.0 / 5.3.0 std_msgs/Float64
input_bit_registers0_to_31 UINT32 General purpose bits This range of the boolean output registers is reserved for FieldBus/PLC interface usage. 3.4.0 custom_msg Array of ur_msgs/Digital Not optimal but merging these into one common message would break the name?factory?msg pipeline
input_bit_registers32_to_63 UINT32 General purpose bits This range of the boolean output registers is reserved for FieldBus/PLC interface usage. 3.4.0 custom_msg Array of ur_msgs/Digital
input_bit_register_x BOOL 64 general purpose bits X: [64..127] - The upper range of the boolean output registers can be used by external RTDE clients (i.e URCAPS). 3.9.0 / 5.3.0 std_msgs/Bool
input_int_register_x[0 .. 48] INT32 48 general purpose integer registers X: [0..23] - The lower range of the integer input registers is reserved for FieldBus/PLC interface usage. X: [24..47] - The upper range of the integer input registers can be used by external RTDE clients (i.e URCAPS). [0..23] 3.4.0 [24..47] 3.9.0 / 5.3.0 std_msgs/Int32
input_double_register_x[0 .. 48] DOUBLE 48 general purpose double registers X: [0..23] - The lower range of the double input registers is reserved for FieldBus/PLC interface usage. X: [24..47] - The upper range of the double input registers can be used by external RTDE clients (i.e URCAPS). [0..23] 3.4.0 [24..47] 3.9.0 / 5.3.0 std_msgs/Float64
tool_output_mode UINT8 The current output mode 5.2.0 custom_msg -> should be established inside ur_msgs
tool_digital_output0_mode UINT8 The current mode of digital output 0 5.2.0 custom_msg -> should be established inside ur_msgs
tool_digital_output1_mode UINT8 The current mode of digital output 1 5.2.0 custom_msg -> should be established inside ur_msgs
input_bit_registers0_to_31 UINT32 General purpose bits (input read back) 3.4.0 custom_msg Array of ur_msgs/Digital Not optimal but merging these into one common message would break the name?factory?msg pipeline
input_bit_registers32_to_63 UINT32 General purpose bits (input read back) 3.4.0 custom_msg Array of ur_msgs/Digital
input_int_register_X INT32 24 general purpose integer registers (input read back) X: [0..23] 3.4.0 custom_msg Array of ur_msgs/Digital
input_double_register_X DOUBLE 24 general purpose double registers (input read back) X: [0..23] custom_msg double

gavanderhoorn avatar Nov 18 '19 17:11 gavanderhoorn

Some first comments:

  1. publish fields like target_q, target_qd and target_moment in a sensor_msgs/JointState on a target_joint_states topic (similar to ros-industrial/ur_modern_driver#341)
  2. same for actual fields
  3. the qdd and current would require a custom message unfortunately.
  4. it might be nice to general the "target" fields to all be published inside a target namespace
  5. all Pose publishers could also be published as TF frames instead. That would make using the data for transforms easier (see also ros-controls/ros_control#372)
  6. re: joint_temperatures: ur_modern_driver also publishes these, but uses plain sensor_msgs/Temperature (fixed in ros-industrial/ur_modern_driver#320). RViz can render Temperature messages in-situ if a valid TF frame is set for frame_id in the Header. Perhaps not using a custom message here would be better.
  7. re: actual_execution_time: is this not more of a period? I haven't checked the documentation, but if it is, a std_msgs/Duration may be better. An actual "time" time may be published using sensor_msgs/TimeReference.
  8. re: output_bit_registers0_to_31: not sure I would publish those as arrays of ur_msgs/Digital. That is going to be a lot of elements in that array. Perhaps leaving them as uint32 fields? Or a uint32[]?

gavanderhoorn avatar Nov 18 '19 18:11 gavanderhoorn

Thank you for your input.

Some first comments:

  1. publish fields like target_q, target_qd and target_moment in a sensor_msgs/JointState on a target_joint_states topic (similar to ros-industrial/ur_modern_driver#341)

From our point of view, this goes against the idea of this PR which is providing an easy interface to request single RTDE fields. Requesting one of the above will require requesting all the others, as well.

  1. same for actual fields

The actual fields are already published through the joint_state controller and are thereby planned to be excluded from separate publishing.

  1. the qdd and current would require a custom message unfortunately.

Yes, as we suggested. But I guess that comment was mainly referring to 1. and 2.

  1. it might be nice to general the "target" fields to all be published inside a target namespace

Same reasoning as 1.

  1. all Pose publishers could also be published as TF frames instead. That would make using the data for transforms easier (see also ros-controls/ros_control#372)

Yes, we could easily publish TF frames, as well. However, I also like the idea of putting this into a separate ros controller...

  1. re: joint_temperatures: ur_modern_driver also publishes these, but uses plain sensor_msgs/Temperature (fixed in ros-industrial/ur_modern_driver#320). RViz can render Temperature messages in-situ if a valid TF frame is set for frame_id in the Header. Perhaps not using a custom message here would be better.

I agree, that would be a better solution.

  1. re: actual_execution_time: is this not more of a period? I haven't checked the documentation, but if it is, a std_msgs/Duration may be better. An actual "time" time may be published using sensor_msgs/TimeReference.

Both suggestions sound superior. We'll do some more investigation and pick the appropriate one from those.

  1. re: output_bit_registers0_to_31: not sure I would publish those as arrays of ur_msgs/Digital. That is going to be a lot of elements in that array. Perhaps leaving them as uint32 fields? Or a uint32[]?

Not sure, if I understand that correctly. Why would there be a lot of elements? It should be exactly 32. Publishing a plain uint32 seems a bit against the statement from https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/pull/35#issuecomment-553805534, right? Using a uint32[] message also seems a bit counter-intuitive to me, as there are actually boolean values being represented. We could also go for a bool[] message.

fmauch avatar Nov 28 '19 13:11 fmauch

Initial rework towards new structure/message types is done, should be critically looked over though - some questions about specific data fields remain and I have added them as comments directly in the code.

t-schnell avatar Dec 20 '19 14:12 t-schnell

A side question: Is this PR related to #67? Are all RTDE field hard wired to some robot parameters? Or can the ur programmer set/modify RTDE values (i.e. in the programming or installation tab) of some fields?

lorenz-halt avatar Jan 30 '20 13:01 lorenz-halt

There is a typo in data_field_publisher.cpp (target_movement should be target_moment).

macsmitty avatar Apr 01 '20 14:04 macsmitty

Hi,

  1. I am missing timestamps in the "data" Topics, e.g. if I get temperatures or Joint angles. I have found the seperate Topic "timestamps" but this does not help. I think the discussion About Heritage from Standard message-types is started and I want only to say that I think it is important to use Standard types to make the timestamps available. My collegue has written a patch for that that I am just testing.
  2. Is it possible to get the correct timestamps from the UR? It Looks that the data is read without timestamps from the UR. This is really a pity.

best regards Oliver

orat avatar May 12 '20 13:05 orat

Hi,

  1. I am missing timestamps in the "data" Topics, e.g. if I get temperatures or Joint angles. I have found the seperate Topic "timestamps" but this does not help. I think the discussion About Heritage from Standard message-types is started and I want only to say that I think it is important to use Standard types to make the timestamps available. My collegue has written a patch for that that I am just testing.
  2. Is it possible to get the correct timestamps from the UR? It Looks that the data is read without timestamps from the UR. This is really a pity.

best regards Oliver

This issue is exactly the (main) reason why this isn't merged, yet.

fmauch avatar May 12 '20 13:05 fmauch

Is this still under development? We want to have the actual TCP position data and this PR seems to be what we want.

xiaohuits avatar Jul 08 '20 22:07 xiaohuits

I am just reading the TCP via the topic /ur_hardware_interface/rtde_data/target_TCP_pose. I get a standard messagetype with the position vector and the quaternion describing the orientation. This works fine. But there is no timestamp available. I also tried to change the sample rate without luck. Only streaming with 500Hz works for me.

orat avatar Jul 09 '20 14:07 orat

Is this still under development? We want to have the actual TCP position data and this PR seems to be what we want.

The actual TCP pose is already available inside the tf system as as tool0_controller.

And yes, this is still on my ToDo-List, it just always gets too much over-prioritized :-(

fmauch avatar Jul 10 '20 12:07 fmauch

Hello everyone and thank you for your contribution. I am new in ROS and currently involved in a project with an UR3e. I have couple of questions I would be super grateful if you´d help me clarify:

  1. I would like to know, after installing this branch of the package, How do the RTDE variables can be seen/printed and what are the specific names of the topics to which these variables are being sent or saved to?

  2. Also, I would like to know how does this differ from: https://github.com/t-schnell/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/resources/rtde_output_recipe.txt And how would it be possible to print or access the RTDE information stated in this last .txt?

Thanks so much in advance for your time and help!

RisMmi avatar Jan 26 '21 11:01 RisMmi

Hello everyone and thank you for your contribution. I am new in ROS and currently involved in a project with an UR3e. I have couple of questions I would be super grateful if you´d help me clarify:

  1. I would like to know, after installing this branch of the package, How do the RTDE variables can be seen/printed and what are the specific names of the topics to which these variables are being sent or saved to?
  2. Also, I would like to know how does this differ from: https://github.com/t-schnell/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/resources/rtde_output_recipe.txt And how would it be possible to print or access the RTDE information stated in this last .txt?

Thanks so much in advance for your time and help!

When using this branch adding variables to rtde_output_recipe.txt will automatically publish this data on rtde_data/<variable_name>.

fmauch avatar Jan 27 '21 10:01 fmauch

Hello everyone and thank you for your contribution. I am new in ROS and currently involved in a project with an UR3e. I have couple of questions I would be super grateful if you´d help me clarify:

  1. I would like to know, after installing this branch of the package, How do the RTDE variables can be seen/printed and what are the specific names of the topics to which these variables are being sent or saved to?
  2. Also, I would like to know how does this differ from: https://github.com/t-schnell/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/resources/rtde_output_recipe.txt And how would it be possible to print or access the RTDE information stated in this last .txt?

Thanks so much in advance for your time and help!

When using this branch adding variables to rtde_output_recipe.txt will automatically publish this data on rtde_data/<variable_name>.

@fmauch Thank you so much for your response. What about the variables that are already specified in rtde_output_recipe.txt inside the official package, Can I access to them somehow (either through topics or by printing them in the terminal) without using this branch? Thanks again!

RisMmi avatar Jan 27 '21 15:01 RisMmi

@RisMmi Most data is available through running controllers. You can try running rosnode info /ur_hardware_interface to see all topics published by the driver.

fmauch avatar Jan 27 '21 21:01 fmauch

This PR hasn't made any progress for quite some time and will be closed soon. Please comment if it is still relevant.

github-actions[bot] avatar May 31 '23 22:05 github-actions[bot]