Skip to content

Commit 408318b

Browse files
mergify[bot]Felix Durchdewaldurfeex
authored
Port robot_state_helper to ROS2 (backport of #933) (#1286)
--------- Co-authored-by: Felix Durchdewald <[email protected]> Co-authored-by: Felix Exner <[email protected]>
1 parent 738bd8d commit 408318b

File tree

10 files changed

+813
-4
lines changed

10 files changed

+813
-4
lines changed

ur_dashboard_msgs/action/SetMode.action

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# This action is for setting the robot into a desired mode (e.g. RUNNING) and safety mode into a
22
# non-critical state (e.g. NORMAL or REDUCED), for example after a safety incident happened.
33

4-
# goal
4+
# Target modes can be one of
5+
# - 3: ROBOT_MODE_POWER_OFF
6+
# - 5: ROBOT_MODE_IDLE
7+
# - 7: ROBOT_MODE_RUNNING
58
int8 target_robot_mode
69

710
# Stop program execution before restoring the target mode. Can be used together with 'play_program'.

ur_robot_driver/CMakeLists.txt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ add_library(ur_robot_driver_plugin
5858
src/dashboard_client_ros.cpp
5959
src/hardware_interface.cpp
6060
src/urcl_log_handler.cpp
61+
src/robot_state_helper.cpp
6162
)
6263
target_link_libraries(
6364
ur_robot_driver_plugin
@@ -83,7 +84,7 @@ add_executable(dashboard_client
8384
src/dashboard_client_node.cpp
8485
src/urcl_log_handler.cpp
8586
)
86-
target_link_libraries(dashboard_client ${catkin_LIBRARIES} ur_client_library::urcl)
87+
target_link_libraries(dashboard_client ur_client_library::urcl)
8788
ament_target_dependencies(dashboard_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${THIS_PACKAGE_INCLUDE_DEPENDS})
8889

8990
#
@@ -106,13 +107,23 @@ add_executable(controller_stopper_node
106107
)
107108
ament_target_dependencies(controller_stopper_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${THIS_PACKAGE_INCLUDE_DEPENDS})
108109

110+
#
111+
# robot_state_helper
112+
#
113+
add_executable(robot_state_helper
114+
src/robot_state_helper.cpp
115+
src/robot_state_helper_node.cpp
116+
)
117+
target_link_libraries(robot_state_helper ur_client_library::urcl)
118+
ament_target_dependencies(robot_state_helper ${${PROJECT_NAME}_EXPORTED_TARGETS} ${THIS_PACKAGE_INCLUDE_DEPENDS})
119+
109120
add_executable(urscript_interface
110121
src/urscript_interface.cpp
111122
)
112123
ament_target_dependencies(urscript_interface ${${PROJECT_NAME}_EXPORTED_TARGETS} ${THIS_PACKAGE_INCLUDE_DEPENDS})
113124

114125
install(
115-
TARGETS dashboard_client ur_ros2_control_node controller_stopper_node urscript_interface
126+
TARGETS dashboard_client ur_ros2_control_node controller_stopper_node urscript_interface robot_state_helper
116127
DESTINATION lib/${PROJECT_NAME}
117128
)
118129

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
.. _controller_stopper:
2+
3+
Controller stopper
4+
==================
5+
6+
As explained in the section :ref:`robot_startup_program`, the robot needs to run a program in order
7+
to receive motion commands from the ROS driver. When the program is not running, commands sent to
8+
the robot will have no effect.
9+
10+
To make that transparent, the ``controller_stopper`` node mirrors that state in the ROS
11+
controller's state. It listens to the ``/io_and_status_controller/robot_program_running`` topic and
12+
deactivates all motion controllers (or any controller not explicitly marked as "consistent", see
13+
below)when the program is not running.
14+
15+
Once the program is running again, any previously active motion controller will be activated again.
16+
17+
This way, when sending commands to an inactive controller the caller should be transparently
18+
informed, that the controller cannot accept commands at the moment.
19+
20+
In the same way, any running action on the ROS controller will be aborted, as the controller gets
21+
deactivated by the controller_stopper.
22+
23+
Parameters
24+
----------
25+
26+
- ``~consistent_controllers`` (list of strings, default: ``[]``)
27+
28+
A list of controller names that should not be stopped when the program is not running. Any
29+
controller that doesn't require the robot program to be running should be in that list.

ur_robot_driver/doc/index.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ Welcome to ur_robot_driver's documentation!
1616
setup_tool_communication
1717
ROS_INTERFACE
1818
generated/index
19-
19+
robot_state_helper
20+
controller_stopper
2021

2122

2223
Indices and tables
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
.. _robot_state_helper:
2+
3+
Robot state helper
4+
==================
5+
After switching on the robot, it has to be manually started, the brakes have to be released and a
6+
program has to be started in order to make the robot ready to use. This is usually done using the
7+
robot's teach pendant.
8+
9+
Whenever the robot encounters an error, manual intervention is required to resolve the issue. For
10+
example, if the robot goes into a protective stop, the error has to be acknowledged and the robot
11+
program has to be unpaused.
12+
13+
When the robot is in :ref:`remote_control_mode <operation_modes>`, most interaction with the robot can be done
14+
without using the teach pendant, many of that through the :ref:`dashboard client
15+
<dashboard_client_ros2>`.
16+
17+
The ROS driver provides a helper node that can be used to automate some of these tasks. The
18+
``robot_state_helper`` node can be used to start the robot, release the brakes, and (re-)start the
19+
program through an action call. It is started by default and provides a
20+
`dashboard_msgs/action/SetMode
21+
<https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_dashboard_msgs/action/SetMode.action>`_ action.
22+
23+
For example, to make the robot ready to be used by the ROS driver, call
24+
25+
.. code-block:: console
26+
27+
$ ros2 action send_goal /ur_robot_state_helper/set_mode ur_dashboard_msgs/action/SetMode "{ target_robot_mode: 7, stop_program: true, play_program: true}"
28+
29+
The ``target_robot_mode`` can be one of the following:
30+
31+
.. table:: target_robot_mode
32+
:widths: auto
33+
34+
===== =====
35+
index meaning
36+
===== =====
37+
3 POWER_OFF -- Robot is powered off
38+
5 IDLE -- Robot is powered on, but brakes are engaged
39+
7 RUNNING -- Robot is powered on, brakes are released, ready to run a program
40+
===== =====
41+
42+
.. note::
43+
44+
When the ROBOT_STATE is in ``RUNNING``, that is equivalent to the robot showing the green dot in
45+
the lower left corner of the teach pendant (On PolyScope 5). The program state is independent of
46+
that and shows with the text next to that button.
47+
48+
The ``stop_program`` flag is used to stop the currently running program before changing the robot
49+
state. In combination with the :ref:`controller_stopper`, this will deactivate any motion
50+
controller and therefore stop any ROS action being active on those controllers.
51+
52+
.. warning::
53+
A robot's protective stop or emergency stop is only pausing the running program. If the program
54+
is resumed after the P-Stop or EM-Stop is released, the robot will continue executing what it
55+
has been doing. Therefore, it is advised to stop and re-start the program when recovering from a
56+
fault.
57+
58+
The ``play_program`` flag is used to start the program after the robot state has been set. This has
59+
the same effects as explained in :ref:`continuation_after_interruptions`.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
.. _ur_robot_driver_startup:
2+
3+
Startup the driver
4+
==================
5+
6+
Prepare the robot
7+
-----------------
8+
9+
If you want to use a real robot, or a URSim simulator, with this driver, you need to prepare it,
10+
first. Make sure that you complete all steps from the :ref:`setup instructions<robot_setup>`,
11+
installed the External Control URCap and created a program as explained
12+
:ref:`here<install_urcap>`.
13+
14+
Launch files
15+
------------
16+
17+
For starting the driver it is recommended to start the ``ur_control.launch.py`` launchfile from the
18+
``ur_robot_driver`` package. It starts the driver, a set of controllers and a couple of helper
19+
nodes for UR robots. The only required arguments are the ``ur_type`` and ``robot_ip`` parameters.
20+
21+
.. code-block:: console
22+
23+
$ ros2 launch ur_robot_driver ur_control.launch.py ur_type:=ur5e robot_ip:=192.168.56.101
24+
25+
Allowed ``ur_type`` strings: ``ur3``, ``ur3e``, ``ur5``, ``ur5e``, ``ur10``, ``ur10e``, ``ur16e``,
26+
``ur20``, ``ur30``.
27+
28+
Other important arguments are:
29+
30+
31+
* ``kinematics_params_file`` (default: *None*) - Path to the calibration file extracted from the robot, as described in :ref:`calibration_extraction`.
32+
* ``use_mock_hardware`` (default: *false* ) - Use simple hardware emulator from ros2_control. Useful for testing launch files, descriptions, etc.
33+
* ``headless_mode`` (default: *false*) - Start driver in :ref:`headless_mode`.
34+
* ``launch_rviz`` (default: *true*) - Start RViz together with the driver.
35+
* ``initial_joint_controller`` (default: *scaled_joint_trajectory_controller*) - Use this if you
36+
want to start the robot with another controller.
37+
38+
.. note::
39+
When the driver is started, you can list all loaded controllers using the ``ros2 control
40+
list_controllers`` command. For this, the package ``ros2controlcli`` must be installed (``sudo
41+
apt-get install ros-${ROS_DISTRO}-ros2controlcli``).
42+
43+
44+
For all other arguments, please see
45+
46+
47+
.. code-block:: console
48+
49+
$ ros2 launch ur_robot_driver ur_control.launch.py --show-args
50+
51+
Also, there are predefined launch files for all supported types of UR robots.
52+
53+
.. _robot_startup_program:
54+
55+
Finish startup on the robot
56+
---------------------------
57+
58+
Unless :ref:`headless_mode` is used, you will now have to start the *External Control URCap* program on
59+
the robot that you have created earlier.
60+
61+
Depending on the :ref:`robot control mode<operation_modes>` do the following:
62+
63+
* In *local control mode*, load the program on the robot and press the "Play" button |play_button| on the teach pendant.
64+
* In *remote control mode* load and start the program using the following dashboard calls:
65+
66+
.. code-block:: console
67+
68+
$ ros2 service call /dashboard_client/load_program ur_dashboard_msgs/srv/Load "filename: my_robot_program.urp"``
69+
$ ros2 service call /dashboard_client/play std_srvs/srv/Trigger {}
70+
71+
* When the driver is started with ``headless_mode:=true`` nothing is needed. The driver is running
72+
already.
73+
74+
75+
.. _verify_calibration:
76+
77+
Verify calibration info is being used correctly
78+
-----------------------------------------------
79+
80+
81+
If you passed a path to an extracted calibration via the *kinematics_params_file*
82+
parameter, ensure that the loaded calibration matches that of the robot by inspecting the console
83+
output after launching the ``ur_robot_driver``. If the calibration does not match, you will see an error:
84+
85+
.. code-block::
86+
87+
[INFO] [1694437690.406932381] [URPositionHardwareInterface]: Calibration checksum: 'calib_xxxxxxxxxxxxxxxxxxx'
88+
[ERROR] [1694437690.516957265] [URPositionHardwareInterface]: The calibration parameters of the connected robot don't match the ones from the given kinematics config file.
89+
90+
With the correct calibration you should see:
91+
92+
.. code-block::
93+
94+
[INFO] [1694437690.406932381] [URPositionHardwareInterface]: Calibration checksum: 'calib_xxxxxxxxxxxxxxxxxxx'
95+
[INFO] [1694437690.516957265] [URPositionHardwareInterface]: Calibration checked successfully.
96+
97+
Alternatively, search for the term *checksum* in the console output after launching the driver.
98+
Verify that the printed checksum matches that on the final line of your extracted calibration file.
99+
100+
101+
.. _continuation_after_interruptions:
102+
103+
Continuation after interruptions
104+
--------------------------------
105+
106+
107+
Whenever the *External Control URCap* program gets interrupted, it has to be unpaused / restarted.
108+
109+
If that happens, you will see the output ``Connection to reverse interface dropped.``
110+
111+
This can happen, e,g, when
112+
113+
* The running program is actively stopped.
114+
* The robot goes into a protective stop / EM stop. (The program will be paused, then)
115+
* The communication is stopped, since the external source did not receive a command in time.
116+
* There was another script sent for execution e.g.
117+
118+
* Script code was sent to the robot via its primary interface
119+
* Robot motion is performed using the Teach pendant
120+
121+
Depending on the operation mode, perform one of the following steps:
122+
123+
* In *local control mode*, simply press the "Play" button |play_button| on the teach pendant.
124+
* In *remote control mode* start the program using the following dashboard call:
125+
126+
.. code-block:: console
127+
128+
$ ros2 service call /dashboard_client/play std_srvs/srv/Trigger {}
129+
130+
* When the driver is started with ``headless_mode:=true`` perform the following service call:
131+
132+
.. code-block:: console
133+
134+
$ ros2 service call /io_and_status_controller/resend_robot_program std_srvs/srv/Trigger {}
135+
136+
137+
138+
139+
140+
.. |play_button| image:: ../resources/play_button.svg
141+
:height: 20px
142+
:width: 20px

0 commit comments

Comments
 (0)