From f5b9bd4ec3d2fb5c27389d38dc5f6aeeb910c735 Mon Sep 17 00:00:00 2001 From: "Felix Exner (fexner)" Date: Fri, 17 May 2024 09:31:50 +0200 Subject: [PATCH] Restructure documentation for full stack documentation (#984) * Remove indices and tables from the ur_robot_driver index * Move ur_controllers documentation to doc folder * Move ur_calibration documentation to rst so it can be re-used * Rework calibration tutorial to refer to the workcell example * Migrate all docs to rst * Add rst doc for ur_moveit_config Co-authored-by: Vincenzo Di Pentima --- ur_calibration/README.md | 69 +--- ur_calibration/doc/index.rst | 45 +++ ur_controllers/README.md | 64 +--- ur_controllers/doc/index.rst | 99 ++++++ ur_moveit_config/doc/index.rst | 25 ++ ur_robot_driver/README.md | 8 +- ur_robot_driver/doc/ROS_INTERFACE.md | 213 ------------ ur_robot_driver/doc/ROS_INTERFACE.rst | 264 +++++++++++++++ ur_robot_driver/doc/index.rst | 12 +- ur_robot_driver/doc/installation/real_time.md | 282 ---------------- .../doc/installation/real_time.rst | 311 ++++++++++++++++++ ur_robot_driver/doc/usage.rst | 17 +- 12 files changed, 754 insertions(+), 655 deletions(-) create mode 100644 ur_calibration/doc/index.rst create mode 100644 ur_controllers/doc/index.rst create mode 100644 ur_moveit_config/doc/index.rst delete mode 100644 ur_robot_driver/doc/ROS_INTERFACE.md create mode 100644 ur_robot_driver/doc/ROS_INTERFACE.rst delete mode 100644 ur_robot_driver/doc/installation/real_time.md create mode 100644 ur_robot_driver/doc/installation/real_time.rst diff --git a/ur_calibration/README.md b/ur_calibration/README.md index 06567be28..70646842a 100644 --- a/ur_calibration/README.md +++ b/ur_calibration/README.md @@ -8,71 +8,4 @@ make use of this in ROS, you first have to extract the calibration information f Though this step is not necessary, to control the robot using this driver, it is highly recommended to do so, as end effector positions might be off in the magnitude of centimeters. -## Nodes -### calibration_correction -This node extracts calibration information directly from a robot, calculates the URDF correction and -saves it into a .yaml file. - -In the launch folder of the ur_calibration package is a helper script: - -```bash -$ ros2 launch ur_calibration calibration_correction.launch.py \ -robot_ip:= target_filename:="${HOME}/my_robot_calibration.yaml" -``` - -For the parameter `robot_ip` insert the IP address on which the ROS pc can reach the robot. As -`target_filename` provide an absolute path where the result will be saved to. - -## Creating a calibration / launch package for all local robots -When dealing with multiple robots in one organization it might make sense to store calibration data -into a package dedicated to that purpose only. To do so, create a new package (if it doesn't already -exist) - -```bash -# Replace your actual colcon_ws folder -$ cd /src -$ ros2 pkg create _ur_launch --build-type ament_cmake --dependencies ur_client_library \ ---description "Package containing calibrations and launch files for our UR robots." -# Create a skeleton package -$ mkdir -p _ur_launch/etc -$ mkdir -p _ur_launch/launch -$ echo 'install(DIRECTORY etc launch DESTINATION share/${PROJECT_NAME})' >> _ur_launch/CMakeLists.txt -$ colcon build --packages-select _ur_launch -``` - -We can use the new package to store the calibration data in that package. We recommend naming each -robot individually, e.g. *ex-ur10-1*. - -```bash -$ ros2 launch ur_calibration calibration_correction.launch.py \ -robot_ip:= \ -target_filename:="$(ros2 pkg prefix _ur_launch)/share/_ur_launch/etc/ex-ur10-1_calibration.yaml" -``` - -To make life easier, we create a launchfile for this particular robot. We base it upon the -respective launchfile in the driver: - -```bash -# Replace your actual colcon_ws folder -$ cd /src/_ur_launch/launch -$ cp $(ros2 pkg prefix ur_robot_driver)/share/ur_robot_driver/launch/ur_control.launch.py ex-ur10-1.launch.py -``` - -Next, modify the parameter section of the new launchfile to match your actual calibration: - -```py -kinematics_params = PathJoinSubstitution( - [FindPackageShare("_ur_launch"), "etc", "", "ex-ur10-1_calibration.yaml"] - ) - -``` - -Then, anybody cloning this repository can startup the robot simply by launching - -```bash -# Replace your actual colcon_ws folder -$ cd -$ colcon build --packages-select _ur_launch -$ ros2 launch _ur_launch ex-ur10-1.launch.py -robot_ip:=xxx.yyy.zzz.www ur_type:=ur5e use_mock_hardware:=false launch_rviz:=true -``` +For details please see [doc/index.rst](doc/index.rst) diff --git a/ur_calibration/doc/index.rst b/ur_calibration/doc/index.rst new file mode 100644 index 000000000..d8056e35a --- /dev/null +++ b/ur_calibration/doc/index.rst @@ -0,0 +1,45 @@ + +ur_calibration +============== + +Package for extracting the factory calibration from a UR robot and changing it to be used by ``ur_description`` to gain a correct URDF model. + +Each UR robot is calibrated inside the factory giving exact forward and inverse kinematics. To also +make use of this in ROS, you first have to extract the calibration information from the robot. + +Though this step is not necessary, to control the robot using this driver, it is highly recommended +to do so, as end effector positions might be off in the magnitude of centimeters. + +Nodes +----- + +calibration_correction +^^^^^^^^^^^^^^^^^^^^^^ + +This node extracts calibration information directly from a robot, calculates the URDF correction and +saves it into a .yaml file. + +In the launch folder of the ur_calibration package is a helper script: + +.. code-block:: bash + + $ ros2 launch ur_calibration calibration_correction.launch.py \ + robot_ip:= target_filename:="${HOME}/my_robot_calibration.yaml" + +For the parameter ``robot_ip`` insert the IP address on which the ROS pc can reach the robot. As +``target_filename`` provide an absolute path where the result will be saved to. + +With that, you can launch your specific robot with the correct calibration using + +.. code-block:: bash + + $ ros2 launch ur_robot_driver ur_control.launch.py \ + ur_type:=ur5e \ + robot_ip:=192.168.56.101 \ + kinematics_params_file:="${HOME}/my_robot_calibration.yaml" + +Adapt the robot model matching to your robot. + +Ideally, you would create a package for your custom workcell, as explained in `the custom workcell +tutorial +`_. diff --git a/ur_controllers/README.md b/ur_controllers/README.md index c6599dcd0..b5f4adc34 100644 --- a/ur_controllers/README.md +++ b/ur_controllers/README.md @@ -11,66 +11,4 @@ robot family. Currently this contains * A **scaled_joint_trajectory_controller** that is similar to the *joint_trajectory_controller*, but it uses the speed scaling reported by the robot to reduce progress in the trajectory. -## About this package -This package contains controllers not being available in the default `ros_control` set. They are -created to support more features offered by the UR robot family. Any of these controllers are -example implementations for certain features and are intended to be generalized and merged -into the default `ros_control` controller set at some future point. - -## Controller description -This packages offers a couple of specific controllers that will be explained in the following -sections. -### ur_controllers/SpeedScalingStateBroadcaster -This controller publishes the current actual execution speed as reported by the robot. Values are -floating points between 0 and 1. - -In the [`ur_robot_driver`](../ur_robot_driver) this is calculated by multiplying the two [RTDE](https://www.universal-robots.com/articles/ur/real-time-data-exchange-rtde-guide/) data -fields `speed_scaling` (which should be equal to the value shown by the speed slider position on the -teach pendant) and `target_speed_fraction` (Which is the fraction to which execution gets slowed -down by the controller). -### position_controllers/ScaledJointTrajectoryController and velocity_controllers/ScaledJointTrajectoryController -These controllers work similar to the well-known -[`joint_trajectory_controller`](http://wiki.ros.org/joint_trajectory_controller). - -However, they are extended to handle the robot's execution speed specifically. Because the default -`joint_trajectory_controller` would interpolate the trajectory with the configured time constraints (ie: always assume maximum velocity and acceleration supported by the robot), -this could lead to significant path deviation due to multiple reasons: - - The speed slider on the robot might not be at 100%, so motion commands sent from ROS would - effectively get scaled down resulting in a slower execution. - - The robot could scale down motions based on configured safety limits resulting in a slower motion - than expected and therefore not reaching the desired target in a control cycle. - - Motions might not be executed at all, e.g. because the robot is E-stopped or in a protective stop - - Motion commands sent to the robot might not be interpreted, e.g. because there is no - [`external_control`](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver#prepare-the-robot) - program node running on the robot controller. - - The program interpreting motion commands could be paused. - -The following plot illustrates the problem: -![Trajectory execution with default trajectory controller](doc/traj_without_speed_scaling.png -"Trajectory execution with default trajectory controller") - -The graph shows a trajectory with one joint being moved to a target point and back to its starting -point. As the joint's speed is limited to a very low setting on the teach pendant, speed scaling -(black line) activates and limits the joint speed (green line). As a result, the target -trajectory (light blue) doesn't get executed by the robot, but instead the pink trajectory is executed. -The vertical distance between the light blue line and the pink line is the path error in each -control cycle. We can see that the path deviation gets above 300 degrees at some point and the -target point at -6 radians never gets reached. - -All of the cases mentioned above are addressed by the scaled trajectory versions. Trajectory execution -can be transparently scaled down using the speed slider on the teach pendant without leading to -additional path deviations. Pausing the program or hitting the E-stop effectively leads to -`speed_scaling` being 0 meaning the trajectory will not be continued until the program is continued. -This way, trajectory executions can be explicitly paused and continued. - -With the scaled version of the trajectory controller the example motion shown in the previous diagram becomes: -![Trajectory execution with scaled_joint_trajectory_controller](doc/traj_with_speed_scaling.png -"Trajectory execution with scaled_joint_trajectory_controller") - -The deviation between trajectory interpolation on the ROS side and actual robot execution stays minimal and the -robot reaches the intermediate setpoint instead of returning "too early" as in the example above. - -Under the hood this is implemented by proceeding the trajectory not by a full time step but only by -the fraction determined by the current speed scaling. If speed scaling is currently at 50% then -interpolation of the current control cycle will start half a time step after the beginning of the -previous control cycle. +For more details please see [doc/index.rst](doc/index.rst) diff --git a/ur_controllers/doc/index.rst b/ur_controllers/doc/index.rst new file mode 100644 index 000000000..6d7828462 --- /dev/null +++ b/ur_controllers/doc/index.rst @@ -0,0 +1,99 @@ +ur_controllers +============== + +This package contains controllers and hardware interface for ``ros_control`` that are special to the UR +robot family. Currently this contains: + + +* A **speed_scaling_interface** to read the value of the current speed scaling into controllers. +* A **scaled_joint_command_interface** that provides access to joint values and commands in + combination with the speed scaling value. +* A **speed_scaling_state_controller** that publishes the current execution speed as reported by + the robot to a topic interface. Values are floating points between 0 and 1. +* A **scaled_joint_trajectory_controller** that is similar to the *joint_trajectory_controller*\ , + but it uses the speed scaling reported by the robot to reduce progress in the trajectory. + +About this package +------------------ + +This package contains controllers not being available in the default ``ros_control`` set. They are +created to support more features offered by the UR robot family. Any of these controllers are +example implementations for certain features and are intended to be generalized and merged +into the default ``ros_control`` controller set at some future point. + +Controller description +---------------------- + +This packages offers a couple of specific controllers that will be explained in the following +sections. + +ur_controllers/SpeedScalingStateBroadcaster +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This controller publishes the current actual execution speed as reported by the robot. Values are +floating points between 0 and 1. + +In the `ur_robot_driver +`_ +this is calculated by multiplying the two `RTDE +`_ data +fields ``speed_scaling`` (which should be equal to the value shown by the speed slider position on the +teach pendant) and ``target_speed_fraction`` (Which is the fraction to which execution gets slowed +down by the controller). + +position_controllers/ScaledJointTrajectoryController and velocity_controllers/ScaledJointTrajectoryController +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +These controllers work similar to the well-known +`joint_trajectory_controller `_. + +However, they are extended to handle the robot's execution speed specifically. Because the default +``joint_trajectory_controller`` would interpolate the trajectory with the configured time constraints (ie: always assume maximum velocity and acceleration supported by the robot), +this could lead to significant path deviation due to multiple reasons: + + +* The speed slider on the robot might not be at 100%, so motion commands sent from ROS would + effectively get scaled down resulting in a slower execution. +* The robot could scale down motions based on configured safety limits resulting in a slower motion + than expected and therefore not reaching the desired target in a control cycle. +* Motions might not be executed at all, e.g. because the robot is E-stopped or in a protective stop +* Motion commands sent to the robot might not be interpreted, e.g. because there is no + `external_control `_ + program node running on the robot controller. +* The program interpreting motion commands could be paused. + +The following plot illustrates the problem: + +.. image:: traj_without_speed_scaling.png + :target: traj_without_speed_scaling.png + :alt: Trajectory execution with default trajectory controller + + +The graph shows a trajectory with one joint being moved to a target point and back to its starting +point. As the joint's speed is limited to a very low setting on the teach pendant, speed scaling +(black line) activates and limits the joint speed (green line). As a result, the target +trajectory (light blue) doesn't get executed by the robot, but instead the pink trajectory is executed. +The vertical distance between the light blue line and the pink line is the path error in each +control cycle. We can see that the path deviation gets above 300 degrees at some point and the +target point at -6 radians never gets reached. + +All of the cases mentioned above are addressed by the scaled trajectory versions. Trajectory execution +can be transparently scaled down using the speed slider on the teach pendant without leading to +additional path deviations. Pausing the program or hitting the E-stop effectively leads to +``speed_scaling`` being 0 meaning the trajectory will not be continued until the program is continued. +This way, trajectory executions can be explicitly paused and continued. + +With the scaled version of the trajectory controller the example motion shown in the previous diagram becomes: + +.. image:: traj_with_speed_scaling.png + :target: traj_with_speed_scaling.png + :alt: Trajectory execution with scaled_joint_trajectory_controller + + +The deviation between trajectory interpolation on the ROS side and actual robot execution stays minimal and the +robot reaches the intermediate setpoint instead of returning "too early" as in the example above. + +Under the hood this is implemented by proceeding the trajectory not by a full time step but only by +the fraction determined by the current speed scaling. If speed scaling is currently at 50% then +interpolation of the current control cycle will start half a time step after the beginning of the +previous control cycle. diff --git a/ur_moveit_config/doc/index.rst b/ur_moveit_config/doc/index.rst new file mode 100644 index 000000000..d23eefa9b --- /dev/null +++ b/ur_moveit_config/doc/index.rst @@ -0,0 +1,25 @@ +.. _ur_moveit_config: + +================ +ur_moveit_config +================ + +This package contains an **example** MoveIt! configuration for Universal Robots arms. Since the +default description contains only the arm, this MoveIt! configuration package also only contains the +arm without any objects around it. +In a real-world scenario it is recommended to create a robot_description modelling the robot with its surroundings (e.g. table where it is mounted on, objects in its environment, etc.) and to generate a +*scenario_moveit_config* package from that description as explained in the :ref:`Custom workcell +tutorial `. + +Usage +----- + +With a running driver (real hardware, URSim or mocked hardware), simply start the MoveIt! +interaction using + +.. code-block:: + + ros2 launch ur_moveit_config ur_moveit.launch.py ur_type:=ur5e launch_rviz:=true + +Now you should be able to use the MoveIt Plugin in rviz2 to plan and execute trajectories with the +robot as explained `here `_. diff --git a/ur_robot_driver/README.md b/ur_robot_driver/README.md index 4f520eb63..8c7a3582f 100644 --- a/ur_robot_driver/README.md +++ b/ur_robot_driver/README.md @@ -5,7 +5,7 @@ repository and requires other packages from that repository. Also, see the [main README](../README.md) for information on how to install and startup this driver. ## ROS-API -The ROS API is documented in a [standalone document](doc/ROS_INTERFACE.md). +The ROS API is documented in a [standalone document](doc/ROS_INTERFACE.rst). ## Technical details The following image shows a very coarse overview of the driver's architecture. @@ -41,7 +41,7 @@ The robot won't accept script code from a remote source unless the robot is put *remote_control-mode*. However, if put into *remote_control-mode*, the program containing the **External Control** program node can't be started from the panel. For this purpose, please use the **dashboard** services to load, start and stop the main program -running on the robot. See the [ROS-API documentation](doc/ROS_INTERFACE.md) for details on the +running on the robot. See the [ROS-API documentation](doc/ROS_INTERFACE.rst) for details on the dashboard services. For using the **tool communication interface** on e-Series robots, a `socat` script is prepared to @@ -75,12 +75,12 @@ The **remote control mode** is needed for many aspects of this driver such as ### Headless mode Inside this driver, there's the **headless** mode, which can be either enabled or not. When the -[headless mode](./doc/ROS_INTERFACE.md#headless_mode-default-false) is activated, required script +[headless mode](./doc/ROS_INTERFACE.rst#headless_mode-default-false) is activated, required script code for external control will be sent to the robot directly when the driver starts. As soon as other script code is sent to the robot either by sending it directly through this driver or by pressing any motion-related button on the teach pendant, the script will be overwritten by this action and has to be restarted by using the -[resend_robot_program](./doc/ROS_INTERFACE.md#resend_robot_program-std_srvstrigger) service. If this +[resend_robot_program](./doc/ROS_INTERFACE.rst#resend_robot_program-std_srvstrigger) service. If this is necessary, you will see the output `Connection to robot dropped, waiting for new connection.` from the driver. Note that pressing "play" on the TP won't start the external control again, but whatever program is currently loaded on the controller. This mode doesn't require the "External diff --git a/ur_robot_driver/doc/ROS_INTERFACE.md b/ur_robot_driver/doc/ROS_INTERFACE.md deleted file mode 100644 index 829302e0a..000000000 --- a/ur_robot_driver/doc/ROS_INTERFACE.md +++ /dev/null @@ -1,213 +0,0 @@ -**NOTE**: This documentation is obsolete and does not cover in full the current state of driver. - -# ROS interface - -The new driver for Universal Robots UR3, UR5 and UR10 robots with CB3 controllers and the e-series. - -## Nodes - -### ur_ros2_control_node - -This is the actual driver node containing the ROS2-Control stack. Interfaces documented here refer to the robot's hardware interface. Controller-specific API elements might be present for the individual controllers outside of this package. - -#### Parameters -Note that parameters are passed through the ros2_control xacro definition. - -##### headless_mode - -Start robot in headless mode. This does not require the 'External Control' URCap to be running on the robot, but this will send the URScript to the robot directly. On e-Series robots this requires the robot to run in 'remote-control' mode. - -##### input_recipe_filename (Required) - -Path to the file containing the recipe used for requesting RTDE inputs. - -##### kinematics/hash (Required) - -Hash of the calibration reported by the robot. This is used for validating the robot description is using the correct calibration. If the robot's calibration doesn't match this hash, an error will be printed. You can use the robot as usual, however Cartesian poses of the endeffector might be inaccurate. See the "ur_calibration" package on help how to generate your own hash matching your actual robot. - -##### non_blocking_read (default: "false") - -Enables non_blocking_read mode. Disables error generated when read returns without any data, sets -the read timeout to zero, and synchronizes read/write operations. This is a leftover from the ROS1 -driver and we currently see no real application where it would make sense to enable this. - -##### output_recipe_filename (Required) - -Path to the file containing the recipe used for requesting RTDE outputs. - -##### reverse_port (Required) - -Port that will be opened to communicate between the driver and the robot controller. - -##### robot_ip (Required) - -The robot's IP address. - -##### script_filename (Required) - -Path to the urscript code that will be sent to the robot. - -##### script_sender_port (Required) - -The driver will offer an interface to receive the program's URScript on this port. - -##### servoj_gain (Required) - -Specify the gain for the underlying servoj command. This will be used whenever position control is -active. A higher value will lead to sharper motions, but might also introduce -higher jerks and vibrations. - -Range: [100 - 3000] - -##### servoj_lookahead_time (Required) - -Specify lookahead_time parameter of underlying servoj command. This will be used whenever position -control is active. A higher value will result in smoother trajectories, but will also introduce a -higher delay between the commands sent from ROS and the motion being executed on the robot. - -Unit: seconds, range: [0.03 - 0.2] - - - -##### tool_baud_rate (Required) - -Baud rate used for tool communication. Will be set as soon as the UR-Program on the robot is started. See UR documentation for valid baud rates. Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. - -##### tool_parity (Required) - -Parity used for tool communication. Will be set as soon as the UR-Program on the robot is started. Can be 0 (None), 1 (odd) and 2 (even). Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. - -##### tool_rx_idle_chars (Required) - -Number of idle chars for the RX unit used for tool communication. Will be set as soon as the UR-Program on the robot is started. Valid values: min=1.0, max=40.0 Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. - -##### tool_stop_bits (Required) - -Number of stop bits used for tool communication. Will be set as soon as the UR-Program on the robot is started. Can be 1 or 2. Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. - -##### tool_tx_idle_chars (Required) - -Number of idle chars for the TX unit used for tool communication. Will be set as soon as the UR-Program on the robot is started. Valid values: min=0.0, max=40.0 Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. - -##### tool_voltage (Required) - -Tool voltage that will be set as soon as the UR-Program on the robot is started. Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. - -##### use_tool_communication (Required) - -Should the tool's RS485 interface be forwarded to the ROS machine? This is only available on e-Series models. Setting this parameter to TRUE requires multiple other parameters to be set,as well. - - -### dashboard_client - -#### Advertised Services - -##### add_to_log ([ur_dashboard_msgs/AddToLog](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/AddToLog.html)) - -Service to add a message to the robot's log - -##### brake_release ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Service to release the brakes. If the robot is currently powered off, it will get powered on on the fly. - -##### clear_operational_mode ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -If this service is called the operational mode can again be changed from PolyScope, and the user password is enabled. - -##### close_popup ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Close a (non-safety) popup on the teach pendant. - -##### close_safety_popup ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Close a safety popup on the teach pendant. - -##### connect ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Service to reconnect to the dashboard server - -##### get_loaded_program ([ur_dashboard_msgs/GetLoadedProgram](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/GetLoadedProgram.html)) - -Load a robot installation from a file - -##### get_robot_mode ([ur_dashboard_msgs/GetRobotMode](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/GetRobotMode.html)) - -Service to query the current robot mode - -##### get_safety_mode ([ur_dashboard_msgs/GetSafetyMode](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/GetSafetyMode.html)) - -Service to query the current safety mode - -##### load_installation ([ur_dashboard_msgs/Load](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/Load.html)) - -Load a robot installation from a file - -##### load_program ([ur_dashboard_msgs/Load](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/Load.html)) - -Load a robot program from a file - -##### pause ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Pause a running program. - -##### play ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Start execution of a previously loaded program - -##### popup ([ur_dashboard_msgs/Popup](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/Popup.html)) - -Service to show a popup on the UR Teach pendant. - -##### power_off ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Power off the robot motors - -##### power_on ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Power on the robot motors. To fully start the robot, call 'brake_release' afterwards. - -##### program_running ([ur_dashboard_msgs/IsProgramRunning](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/IsProgramRunning.html)) - -Query whether there is currently a program running - -##### program_saved ([ur_dashboard_msgs/IsProgramSaved](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/IsProgramSaved.html)) - -Query whether the current program is saved - -##### program_state ([ur_dashboard_msgs/GetProgramState](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/GetProgramState.html)) - -Service to query the current program state - -##### quit ([ur_dashboard_msgs/GetLoadedProgram](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/GetLoadedProgram.html)) - -Disconnect from the dashboard service. - -##### raw_request ([ur_dashboard_msgs/RawRequest](http://docs.ros.org/api/ur_dashboard_msgs/html/srv/RawRequest.html)) - -General purpose service to send arbitrary messages to the dashboard server - -##### restart_safety ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Used when robot gets a safety fault or violation to restart the safety. After safety has been rebooted the robot will be in Power Off. NOTE: You should always ensure it is okay to restart the system. It is highly recommended to check the error log before using this command (either via PolyScope or e.g. ssh connection). - -##### shutdown ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Shutdown the robot controller - -##### stop ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Stop program execution on the robot - -##### unlock_protective_stop ([std_srvs/Trigger](http://docs.ros.org/api/std_srvs/html/srv/Trigger.html)) - -Dismiss a protective stop to continue robot movements. NOTE: It is the responsibility of the user to ensure the cause of the protective stop is resolved before calling this service. - -#### Parameters - -##### receive_timeout (Required) - -Timeout after which a call to the dashboard server will be considered failure if no answer has been received. - -##### robot_ip (Required) - -The IP address under which the robot is reachable. diff --git a/ur_robot_driver/doc/ROS_INTERFACE.rst b/ur_robot_driver/doc/ROS_INTERFACE.rst new file mode 100644 index 000000000..0f7a4f373 --- /dev/null +++ b/ur_robot_driver/doc/ROS_INTERFACE.rst @@ -0,0 +1,264 @@ + +**NOTE**\ : This documentation is obsolete and does not cover in full the current state of driver. + +ROS interface +============= + +The new driver for Universal Robots UR3, UR5 and UR10 robots with CB3 controllers and the e-series. + +Nodes +----- + +ur_ros2_control_node +^^^^^^^^^^^^^^^^^^^^ + +This is the actual driver node containing the ROS2-Control stack. Interfaces documented here refer to the robot's hardware interface. Controller-specific API elements might be present for the individual controllers outside of this package. + +Parameters +~~~~~~~~~~ + +Note that parameters are passed through the ros2_control xacro definition. + +headless_mode +""""""""""""" + +Start robot in headless mode. This does not require the 'External Control' URCap to be running on the robot, but this will send the URScript to the robot directly. On e-Series robots this requires the robot to run in 'remote-control' mode. + +input_recipe_filename (Required) +"""""""""""""""""""""""""""""""" + +Path to the file containing the recipe used for requesting RTDE inputs. + +kinematics/hash (Required) +"""""""""""""""""""""""""" + +Hash of the calibration reported by the robot. This is used for validating the robot description is using the correct calibration. If the robot's calibration doesn't match this hash, an error will be printed. You can use the robot as usual, however Cartesian poses of the endeffector might be inaccurate. See the "ur_calibration" package on help how to generate your own hash matching your actual robot. + +non_blocking_read (default: "false") +"""""""""""""""""""""""""""""""""""" + +Enables non_blocking_read mode. Disables error generated when read returns without any data, sets +the read timeout to zero, and synchronizes read/write operations. This is a leftover from the ROS1 +driver and we currently see no real application where it would make sense to enable this. + +output_recipe_filename (Required) +""""""""""""""""""""""""""""""""" + +Path to the file containing the recipe used for requesting RTDE outputs. + +reverse_port (Required) +""""""""""""""""""""""" + +Port that will be opened to communicate between the driver and the robot controller. + +robot_ip (Required) +""""""""""""""""""" + +The robot's IP address. + +script_filename (Required) +"""""""""""""""""""""""""" + +Path to the urscript code that will be sent to the robot. + +script_sender_port (Required) +""""""""""""""""""""""""""""" + +The driver will offer an interface to receive the program's URScript on this port. + +servoj_gain (Required) +"""""""""""""""""""""" + +Specify the gain for the underlying servoj command. This will be used whenever position control is +active. A higher value will lead to sharper motions, but might also introduce +higher jerks and vibrations. + +Range: [100 - 3000] + +servoj_lookahead_time (Required) +"""""""""""""""""""""""""""""""" + +Specify lookahead_time parameter of underlying servoj command. This will be used whenever position +control is active. A higher value will result in smoother trajectories, but will also introduce a +higher delay between the commands sent from ROS and the motion being executed on the robot. + +Unit: seconds, range: [0.03 - 0.2] + +tool_baud_rate (Required) +""""""""""""""""""""""""" + +Baud rate used for tool communication. Will be set as soon as the UR-Program on the robot is started. See UR documentation for valid baud rates. Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. + +tool_parity (Required) +"""""""""""""""""""""" + +Parity used for tool communication. Will be set as soon as the UR-Program on the robot is started. Can be 0 (None), 1 (odd) and 2 (even). Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. + +tool_rx_idle_chars (Required) +""""""""""""""""""""""""""""" + +Number of idle chars for the RX unit used for tool communication. Will be set as soon as the UR-Program on the robot is started. Valid values: min=1.0, max=40.0 Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. + +tool_stop_bits (Required) +""""""""""""""""""""""""" + +Number of stop bits used for tool communication. Will be set as soon as the UR-Program on the robot is started. Can be 1 or 2. Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. + +tool_tx_idle_chars (Required) +""""""""""""""""""""""""""""" + +Number of idle chars for the TX unit used for tool communication. Will be set as soon as the UR-Program on the robot is started. Valid values: min=0.0, max=40.0 Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. + +tool_voltage (Required) +""""""""""""""""""""""" + +Tool voltage that will be set as soon as the UR-Program on the robot is started. Note: This parameter is only evaluated, when the parameter "use_tool_communication" is set to TRUE. Then, this parameter is required. + +use_tool_communication (Required) +""""""""""""""""""""""""""""""""" + +Should the tool's RS485 interface be forwarded to the ROS machine? This is only available on e-Series models. Setting this parameter to TRUE requires multiple other parameters to be set as well. + +dashboard_client +^^^^^^^^^^^^^^^^ + +Advertised Services +~~~~~~~~~~~~~~~~~~~ + +add_to_log (\ `ur_dashboard_msgs/AddToLog `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to add a message to the robot's log + +brake_release (\ `std_srvs/Trigger `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to release the brakes. If the robot is currently powered off, it will get powered on on the fly. + +clear_operational_mode (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +If this service is called the operational mode can again be changed from PolyScope, and the user password is enabled. + +close_popup (\ `std_srvs/Trigger `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Close a (non-safety) popup on the teach pendant. + +close_safety_popup (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Close a safety popup on the teach pendant. + +connect (\ `std_srvs/Trigger `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to reconnect to the dashboard server + +get_loaded_program (\ `ur_dashboard_msgs/GetLoadedProgram `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Load a robot installation from a file + +get_robot_mode (\ `ur_dashboard_msgs/GetRobotMode `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to query the current robot mode + +get_safety_mode (\ `ur_dashboard_msgs/GetSafetyMode `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to query the current safety mode + +load_installation (\ `ur_dashboard_msgs/Load `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Load a robot installation from a file + +load_program (\ `ur_dashboard_msgs/Load `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Load a robot program from a file + +pause (\ `std_srvs/Trigger `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Pause a running program. + +play (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Start execution of a previously loaded program + +popup (\ `ur_dashboard_msgs/Popup `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to show a popup on the UR Teach pendant. + +power_off (\ `std_srvs/Trigger `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Power off the robot motors + +power_on (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Power on the robot motors. To fully start the robot, call 'brake_release' afterwards. + +program_running (\ `ur_dashboard_msgs/IsProgramRunning `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Query whether there is currently a program running + +program_saved (\ `ur_dashboard_msgs/IsProgramSaved `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Query whether the current program is saved + +program_state (\ `ur_dashboard_msgs/GetProgramState `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Service to query the current program state + +quit (\ `ur_dashboard_msgs/GetLoadedProgram `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Disconnect from the dashboard service. + +raw_request (\ `ur_dashboard_msgs/RawRequest `_\ ) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +General purpose service to send arbitrary messages to the dashboard server + +restart_safety (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Used when robot gets a safety fault or violation to restart the safety. After safety has been rebooted the robot will be in Power Off. NOTE: You should always ensure it is okay to restart the system. It is highly recommended to check the error log before using this command (either via PolyScope or e.g. ssh connection). + +shutdown (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Shutdown the robot controller + +stop (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Stop program execution on the robot + +unlock_protective_stop (\ `std_srvs/Trigger `_\ ) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Dismiss a protective stop to continue robot movements. NOTE: It is the responsibility of the user to ensure the cause of the protective stop is resolved before calling this service. + +Parameters +~~~~~~~~~~ + +receive_timeout (Required) +"""""""""""""""""""""""""" + +Timeout after which a call to the dashboard server will be considered failure if no answer has been received. + +robot_ip (Required) +""""""""""""""""""" + +The IP address under which the robot is reachable. diff --git a/ur_robot_driver/doc/index.rst b/ur_robot_driver/doc/index.rst index bf536ad81..bef2baf74 100644 --- a/ur_robot_driver/doc/index.rst +++ b/ur_robot_driver/doc/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root ``toctree`` directive. -Welcome to ur_robot_driver's documentation! -=========================================== +ur_robot_driver +=============== .. toctree:: :maxdepth: 2 @@ -15,11 +15,3 @@ Welcome to ur_robot_driver's documentation! usage setup_tool_communication ROS_INTERFACE - generated/index - - - -Indices and tables -================== - -* :ref:`genindex` diff --git a/ur_robot_driver/doc/installation/real_time.md b/ur_robot_driver/doc/installation/real_time.md deleted file mode 100644 index e55a9e638..000000000 --- a/ur_robot_driver/doc/installation/real_time.md +++ /dev/null @@ -1,282 +0,0 @@ -# Setting up Ubuntu with a PREEMPT_RT kernel -In order to run the `universal_robot_driver`, we highly recommend to setup a ubuntu system with -real-time capabilities. Especially with a robot from the e-Series the higher control frequency -might lead to non-smooth trajectory execution if not run using a real-time-enabled system. - -You might still be able to control the robot using a non-real-time system. This is, however, not recommended. - -To get real-time support into a ubuntu system, the following steps have to be performed: - 1. Get the sources of a real-time kernel - 2. Compile the real-time kernel - 3. Setup user privileges to execute real-time tasks - -This guide will help you setup your system with a real-time kernel. - -## Preparing -To build the kernel, you will need a couple of tools available on your system. You can install them -using - -``` bash -$ sudo apt-get install build-essential bc ca-certificates gnupg2 libssl-dev wget gawk flex bison -``` - -Before you download the sources of a real-time-enabled kernel, check the kernel version that is currently installed: - -```bash -$ uname -r -4.15.0-62-generic -``` - -To continue with this tutorial, please create a temporary folder and navigate into it. You should -have sufficient space (around 25GB) there, as the extracted kernel sources take much space. After -the new kernel is installed, you can delete this folder again. - -In this example we will use a temporary folder inside our home folder: - -```bash -$ mkdir -p ${HOME}/rt_kernel_build -$ cd ${HOME}/rt_kernel_build -``` - -All future commands are expected to be run inside this folder. If the folder is different, the `$` -sign will be prefixed with a path relative to the above folder. - -## Getting the sources for a real-time kernel -To build a real-time kernel, we first need to get the kernel sources and the real-time patch. - -First, we must decide on the kernel version that we want to use. Above, we -determined that our system has a 4.15 kernel installed. However, real-time -patches exist only for selected kernel versions. Those can be found on the -[linuxfoundation wiki](https://wiki.linuxfoundation.org/realtime/preempt_rt_versions). - -In this example, we will select a 4.14 kernel. Select a kernel version close to the -one installed on your system. - -Go ahead and download the kernel sources, patch sources and their signature files: - -```bash -$ wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.139-rt66.patch.xz -$ wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.139-rt66.patch.sign -$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.139.tar.xz -$ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.139.tar.sign -``` - -To unzip the downloaded files do -```bash -$ xz -dk patch-4.14.139-rt66.patch.xz -$ xz -d linux-4.14.139.tar.xz -``` - -### Verification -Technically, you can skip this section, it is however highly recommended to verify the file -integrity of such a core component of your system! - -To verify file integrity, you must first import public keys by the kernel developers and the patch -author. For the kernel sources use (as suggested on -[kernel.org](https://www.kernel.org/signature.html)) - -```bash -$ gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org -``` - -and for the patch search for a key of the author listed on -[linuxfoundation wiki](https://wiki.linuxfoundation.org/realtime/preempt_rt_versions). - -```bash -$ gpg2 --keyserver hkp://keys.gnupg.net --search-keys zanussi -gpg: data source: http://51.38.91.189:11371 -(1) German Daniel Zanussi - 4096 bit RSA key 0x537F98A9D92CEAC8, created: 2019-07-24, expires: 2023-07-24 -(2) Michael Zanussi - 4096 bit RSA key 0x7C7F76A2C1E3D9EB, created: 2019-05-08 -(3) Tom Zanussi - Tom Zanussi - Tom Zanussi - 4096 bit RSA key 0xDE09826778A38521, created: 2017-12-15 -(4) Riccardo Zanussi - 2048 bit RSA key 0xD299A06261D919C3, created: 2014-08-27, expires: 2018-08-27 (expired) -(5) Zanussi Gianni - 1024 bit DSA key 0x78B89CB020D1836C, created: 2004-04-06 -(6) Michael Zanussi - Michael Zanussi - Michael Zanussi - Michael Zanussi - 1024 bit DSA key 0xB3E952DCAC653064, created: 2000-09-05 -(7) Michael Zanussi - 1024 bit DSA key 0xEB10BBD9BA749318, created: 1999-05-31 -(8) Michael B. Zanussi - 1024 bit DSA key 0x39EE4EAD7BBB1E43, created: 1998-07-16 -Keys 1-8 of 8 for "zanussi". Enter number(s), N)ext, or Q)uit > 3 -``` - -Now we can verify the downloaded sources: -```bash -$ gpg2 --verify linux-4.14.139.tar.sign -gpg: assuming signed data in 'linux-4.14.139.tar' -gpg: Signature made Fr 16 Aug 2019 10:15:17 CEST -gpg: using RSA key 647F28654894E3BD457199BE38DBBDC86092693E -gpg: Good signature from "Greg Kroah-Hartman " [unknown] -gpg: WARNING: This key is not certified with a trusted signature! -gpg: There is no indication that the signature belongs to the owner. -Primary key fingerprint: 647F 2865 4894 E3BD 4571 99BE 38DB BDC8 6092 693E - -$ gpg2 --verify patch-4.14.139-rt66.patch.sign -gpg: assuming signed data in 'patch-4.14.139-rt66.patch' -gpg: Signature made Fr 23 Aug 2019 21:09:20 CEST -gpg: using RSA key 0x0129F38552C38DF1 -gpg: Good signature from "Tom Zanussi " [unknown] -gpg: aka "Tom Zanussi " [unknown] -gpg: aka "Tom Zanussi " [unknown] -gpg: WARNING: This key is not certified with a trusted signature! -gpg: There is no indication that the signature belongs to the owner. -Primary key fingerprint: 5BDF C45C 2ECC 5387 D50C E5EF DE09 8267 78A3 8521 - Subkey fingerprint: ACF8 5F98 16A8 D5F0 96AE 1FD2 0129 F385 52C3 8DF1 -``` - -## Compilation -Before we can compile the sources, we have to extract the tar archive and apply the patch - -```bash -$ tar xf linux-4.14.139.tar -$ cd linux-4.14.139 -linux-4.14.139$ xzcat ../patch-4.14.139-rt66.patch.xz | patch -p1 -``` - -Now to configure your kernel, just type -```bash -linux-4.14.139$ make oldconfig -``` - -This will ask for kernel options. For everything else then the `Preemption Model` use the default -value (just press Enter) or adapt to your preferences. For the preemption model select `Fully Preemptible Kernel`: - -```bash -Preemption Model - 1. No Forced Preemption (Server) (PREEMPT_NONE) -> 2. Voluntary Kernel Preemption (Desktop) (PREEMPT_VOLUNTARY) - 3. Preemptible Kernel (Low-Latency Desktop) (PREEMPT__LL) (NEW) - 4. Preemptible Kernel (Basic RT) (PREEMPT_RTB) (NEW) - 5. Fully Preemptible Kernel (RT) (PREEMPT_RT_FULL) (NEW) -choice[1-5]: 5 -``` - -Now you can build the kernel. This will take some time... - -```bash -linux-4.14.139$ make -j `getconf _NPROCESSORS_ONLN` deb-pkg -``` - -After building, install the `linux-headers` and `linux-image` packages in the parent folder (only -the ones without the `-dbg` in the name) - -```bash -linux-4.14.139$ sudo apt install ../linux-headers-4.14.139-rt66_*.deb ../linux-image-4.14.139-rt66_*.deb -``` - -## Setup user privileges to use real-time scheduling -To be able to schedule threads with user privileges (what the driver will do) you'll have to change -the user's limits by changing `/etc/security/limits.conf` (See [the manpage](https://manpages.ubuntu.com/manpages/bionic/man5/limits.conf.5.html) for details) - -We recommend to setup a group for real-time users instead of writing a fixed username into the config -file: - -```bash -$ sudo groupadd realtime -$ sudo usermod -aG realtime $(whoami) -``` - -Then, make sure `/etc/security/limits.conf` contains -``` -@realtime soft rtprio 99 -@realtime soft priority 99 -@realtime soft memlock 102400 -@realtime hard rtprio 99 -@realtime hard priority 99 -@realtime hard memlock 102400 -``` - -Note: You will have to log out and log back in (Not only close your terminal window) for these -changes to take effect. No need to do this now, as we will reboot later on, anyway. - -## Setup GRUB to always boot the real-time kernel -To make the new kernel the default kernel that the system will boot into every time, you'll have to -change the grub config file inside `/etc/default/grub`. - -Note: This works for ubuntu, but might not be working for other linux systems. It might be necessary -to use another menuentry name there. - -But first, let's find out the name of the entry that we will want to make the default. You can list -all available kernels using - -```bash -$ awk -F\' '/menuentry |submenu / {print $1 $2}' /boot/grub/grub.cfg - -menuentry Ubuntu -submenu Advanced options for Ubuntu - menuentry Ubuntu, with Linux 4.15.0-62-generic - menuentry Ubuntu, with Linux 4.15.0-62-generic (recovery mode) - menuentry Ubuntu, with Linux 4.15.0-60-generic - menuentry Ubuntu, with Linux 4.15.0-60-generic (recovery mode) - menuentry Ubuntu, with Linux 4.15.0-58-generic - menuentry Ubuntu, with Linux 4.15.0-58-generic (recovery mode) - menuentry Ubuntu, with Linux 4.14.139-rt66 - menuentry Ubuntu, with Linux 4.14.139-rt66 (recovery mode) -menuentry Memory test (memtest86+) -menuentry Memory test (memtest86+, serial console 115200) -menuentry Windows 7 (on /dev/sdc2) -menuentry Windows 7 (on /dev/sdc3) -``` - -From the output above, we'll need to generate a string with the pattern `"submenu_name>entry_name"`. In our case this would be - -``` -"Advanced options for Ubuntu>Ubuntu, with Linux 4.14.139-rt66" -``` -**The double quotes and no spaces around the `>` are important!** - -With this, we can setup the default grub entry and then update the grub menu entries. Don't forget this last step! - -```bash -$ sudo sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 4.14.139-rt66"/' /etc/default/grub -$ sudo update-grub -``` - -## Reboot the PC -After having performed the above mentioned steps, reboot the PC. It should boot into the correct -kernel automatically. - -## Check for preemption capabilities -Make sure that the kernel does indeed support real-time scheduling: - -```bash -$ uname -v | cut -d" " -f1-4 -#1 SMP PREEMPT RT -``` - -## Optional: Disable CPU speed scaling -Many modern CPUs support changing their clock frequency dynamically depending on the currently -requested computation resources. In some cases this can lead to small interruptions in execution. -While the real-time scheduled controller thread should be unaffected by this, any external -components such as a visual servoing system might be interrupted for a short period on scaling -changes. - -To check and modify the power saving mode, install cpufrequtils: -```bash -$ sudo apt install cpufrequtils -``` - -Run `cpufreq-info` to check available "governors" and the current CPU Frequency (`current CPU -frequency is XXX MHZ`). In the following we will set the governor to "performance". - -```bash -$ sudo systemctl disable ondemand -$ sudo systemctl enable cpufrequtils -$ sudo sh -c 'echo "GOVERNOR=performance" > /etc/default/cpufrequtils' -$ sudo systemctl daemon-reload && sudo systemctl restart cpufrequtils -``` - -This disables the `ondemand` CPU scaling daemon, creates a `cpufrequtils` config file and restarts -the `cpufrequtils` service. Check with `cpufreq-info`. - -For further information about governors, please see the [kernel -documentation](https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt). diff --git a/ur_robot_driver/doc/installation/real_time.rst b/ur_robot_driver/doc/installation/real_time.rst new file mode 100644 index 000000000..2bb5b7869 --- /dev/null +++ b/ur_robot_driver/doc/installation/real_time.rst @@ -0,0 +1,311 @@ + +Setting up Ubuntu with a PREEMPT_RT kernel +========================================== + +In order to run the ``universal_robot_driver``\ , we highly recommend to setup a ubuntu system with +real-time capabilities. Especially with a robot from the e-Series the higher control frequency +might lead to non-smooth trajectory execution if not run using a real-time-enabled system. + +You might still be able to control the robot using a non-real-time system. This is, however, not recommended. + +To get real-time support into a ubuntu system, the following steps have to be performed: + + +#. Get the sources of a real-time kernel +#. Compile the real-time kernel +#. Setup user privileges to execute real-time tasks + +This guide will help you setup your system with a real-time kernel. + +Preparing +--------- + +To build the kernel, you will need a couple of tools available on your system. You can install them +using + +.. code-block:: bash + + $ sudo apt-get install build-essential bc ca-certificates gnupg2 libssl-dev wget gawk flex bison + +Before you download the sources of a real-time-enabled kernel, check the kernel version that is currently installed: + +.. code-block:: bash + + $ uname -r + 4.15.0-62-generic + +To continue with this tutorial, please create a temporary folder and navigate into it. You should +have sufficient space (around 25GB) there, as the extracted kernel sources take much space. After +the new kernel is installed, you can delete this folder again. + +In this example we will use a temporary folder inside our home folder: + +.. code-block:: bash + + $ mkdir -p ${HOME}/rt_kernel_build + $ cd ${HOME}/rt_kernel_build + +All future commands are expected to be run inside this folder. If the folder is different, the ``$`` +sign will be prefixed with a path relative to the above folder. + +Getting the sources for a real-time kernel +------------------------------------------ + +To build a real-time kernel, we first need to get the kernel sources and the real-time patch. + +First, we must decide on the kernel version that we want to use. Above, we +determined that our system has a 4.15 kernel installed. However, real-time +patches exist only for selected kernel versions. Those can be found on the +`linuxfoundation wiki `_. + +In this example, we will select a 4.14 kernel. Select a kernel version close to the +one installed on your system. + +Go ahead and download the kernel sources, patch sources and their signature files: + +.. code-block:: bash + + $ wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.139-rt66.patch.xz + $ wget https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.139-rt66.patch.sign + $ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.139.tar.xz + $ wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.139.tar.sign + +To unzip the downloaded files do + +.. code-block:: bash + + $ xz -dk patch-4.14.139-rt66.patch.xz + $ xz -d linux-4.14.139.tar.xz + +Verification +^^^^^^^^^^^^ + +Technically, you can skip this section, it is however highly recommended to verify the file +integrity of such a core component of your system! + +To verify file integrity, you must first import public keys by the kernel developers and the patch +author. For the kernel sources use (as suggested on +`kernel.org `_\ ) + +.. code-block:: bash + + $ gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org + +and for the patch search for a key of the author listed on +`linuxfoundation wiki `_. + +.. code-block:: bash + + $ gpg2 --keyserver hkp://keys.gnupg.net --search-keys zanussi + gpg: data source: http://51.38.91.189:11371 + (1) German Daniel Zanussi + 4096 bit RSA key 0x537F98A9D92CEAC8, created: 2019-07-24, expires: 2023-07-24 + (2) Michael Zanussi + 4096 bit RSA key 0x7C7F76A2C1E3D9EB, created: 2019-05-08 + (3) Tom Zanussi + Tom Zanussi + Tom Zanussi + 4096 bit RSA key 0xDE09826778A38521, created: 2017-12-15 + (4) Riccardo Zanussi + 2048 bit RSA key 0xD299A06261D919C3, created: 2014-08-27, expires: 2018-08-27 (expired) + (5) Zanussi Gianni + 1024 bit DSA key 0x78B89CB020D1836C, created: 2004-04-06 + (6) Michael Zanussi + Michael Zanussi + Michael Zanussi + Michael Zanussi + 1024 bit DSA key 0xB3E952DCAC653064, created: 2000-09-05 + (7) Michael Zanussi + 1024 bit DSA key 0xEB10BBD9BA749318, created: 1999-05-31 + (8) Michael B. Zanussi + 1024 bit DSA key 0x39EE4EAD7BBB1E43, created: 1998-07-16 + Keys 1-8 of 8 for "zanussi". Enter number(s), N)ext, or Q)uit > 3 + +Now we can verify the downloaded sources: + +.. code-block:: bash + + $ gpg2 --verify linux-4.14.139.tar.sign + gpg: assuming signed data in 'linux-4.14.139.tar' + gpg: Signature made Fr 16 Aug 2019 10:15:17 CEST + gpg: using RSA key 647F28654894E3BD457199BE38DBBDC86092693E + gpg: Good signature from "Greg Kroah-Hartman " [unknown] + gpg: WARNING: This key is not certified with a trusted signature! + gpg: There is no indication that the signature belongs to the owner. + Primary key fingerprint: 647F 2865 4894 E3BD 4571 99BE 38DB BDC8 6092 693E + + $ gpg2 --verify patch-4.14.139-rt66.patch.sign + gpg: assuming signed data in 'patch-4.14.139-rt66.patch' + gpg: Signature made Fr 23 Aug 2019 21:09:20 CEST + gpg: using RSA key 0x0129F38552C38DF1 + gpg: Good signature from "Tom Zanussi " [unknown] + gpg: aka "Tom Zanussi " [unknown] + gpg: aka "Tom Zanussi " [unknown] + gpg: WARNING: This key is not certified with a trusted signature! + gpg: There is no indication that the signature belongs to the owner. + Primary key fingerprint: 5BDF C45C 2ECC 5387 D50C E5EF DE09 8267 78A3 8521 + Subkey fingerprint: ACF8 5F98 16A8 D5F0 96AE 1FD2 0129 F385 52C3 8DF1 + +Compilation +----------- + +Before we can compile the sources, we have to extract the tar archive and apply the patch + +.. code-block:: bash + + $ tar xf linux-4.14.139.tar + $ cd linux-4.14.139 + linux-4.14.139$ xzcat ../patch-4.14.139-rt66.patch.xz | patch -p1 + +Now to configure your kernel, just type + +.. code-block:: bash + + linux-4.14.139$ make oldconfig + +This will ask for kernel options. For everything else then the ``Preemption Model`` use the default +value (just press Enter) or adapt to your preferences. For the preemption model select ``Fully Preemptible Kernel``\ : + +.. code-block:: bash + + Preemption Model + 1. No Forced Preemption (Server) (PREEMPT_NONE) + > 2. Voluntary Kernel Preemption (Desktop) (PREEMPT_VOLUNTARY) + 3. Preemptible Kernel (Low-Latency Desktop) (PREEMPT__LL) (NEW) + 4. Preemptible Kernel (Basic RT) (PREEMPT_RTB) (NEW) + 5. Fully Preemptible Kernel (RT) (PREEMPT_RT_FULL) (NEW) + choice[1-5]: 5 + +Now you can build the kernel. This will take some time... + +.. code-block:: bash + + linux-4.14.139$ make -j $(getconf _NPROCESSORS_ONLN) deb-pkg + +After building, install the ``linux-headers`` and ``linux-image`` packages in the parent folder (only +the ones without the ``-dbg`` in the name) + +.. code-block:: bash + + linux-4.14.139$ sudo apt install ../linux-headers-4.14.139-rt66_*.deb ../linux-image-4.14.139-rt66_*.deb + +Setup user privileges to use real-time scheduling +------------------------------------------------- + +To be able to schedule threads with user privileges (what the driver will do) you'll have to change +the user's limits by changing ``/etc/security/limits.conf`` (See `the manpage `_ for details) + +We recommend to setup a group for real-time users instead of writing a fixed username into the config +file: + +.. code-block:: bash + + $ sudo groupadd realtime + $ sudo usermod -aG realtime $(whoami) + +Then, make sure ``/etc/security/limits.conf`` contains + +.. code-block:: + + @realtime soft rtprio 99 + @realtime soft priority 99 + @realtime soft memlock 102400 + @realtime hard rtprio 99 + @realtime hard priority 99 + @realtime hard memlock 102400 + +Note: You will have to log out and log back in (Not only close your terminal window) for these +changes to take effect. No need to do this now, as we will reboot later on, anyway. + +Setup GRUB to always boot the real-time kernel +---------------------------------------------- + +To make the new kernel the default kernel that the system will boot into every time, you'll have to +change the grub config file inside ``/etc/default/grub``. + +Note: This works for ubuntu, but might not be working for other linux systems. It might be necessary +to use another menuentry name there. + +But first, let's find out the name of the entry that we will want to make the default. You can list +all available kernels using + +.. code-block:: bash + + $ awk -F\' '/menuentry |submenu / {print $1 $2}' /boot/grub/grub.cfg + + menuentry Ubuntu + submenu Advanced options for Ubuntu + menuentry Ubuntu, with Linux 4.15.0-62-generic + menuentry Ubuntu, with Linux 4.15.0-62-generic (recovery mode) + menuentry Ubuntu, with Linux 4.15.0-60-generic + menuentry Ubuntu, with Linux 4.15.0-60-generic (recovery mode) + menuentry Ubuntu, with Linux 4.15.0-58-generic + menuentry Ubuntu, with Linux 4.15.0-58-generic (recovery mode) + menuentry Ubuntu, with Linux 4.14.139-rt66 + menuentry Ubuntu, with Linux 4.14.139-rt66 (recovery mode) + menuentry Memory test (memtest86+) + menuentry Memory test (memtest86+, serial console 115200) + menuentry Windows 7 (on /dev/sdc2) + menuentry Windows 7 (on /dev/sdc3) + +From the output above, we'll need to generate a string with the pattern ``"submenu_name>entry_name"``. In our case this would be + +.. code-block:: + + "Advanced options for Ubuntu>Ubuntu, with Linux 4.14.139-rt66" + +**The double quotes and no spaces around the ``>`` are important!** + +With this, we can setup the default grub entry and then update the grub menu entries. Don't forget this last step! + +.. code-block:: bash + + $ sudo sed -i 's/^GRUB_DEFAULT=.*/GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 4.14.139-rt66"/' /etc/default/grub + $ sudo update-grub + +Reboot the PC +------------- + +After having performed the above mentioned steps, reboot the PC. It should boot into the correct +kernel automatically. + +Check for preemption capabilities +--------------------------------- + +Make sure that the kernel does indeed support real-time scheduling: + +.. code-block:: bash + + $ uname -v | cut -d" " -f1-4 + #1 SMP PREEMPT RT + +Optional: Disable CPU speed scaling +----------------------------------- + +Many modern CPUs support changing their clock frequency dynamically depending on the currently +requested computation resources. In some cases this can lead to small interruptions in execution. +While the real-time scheduled controller thread should be unaffected by this, any external +components such as a visual servoing system might be interrupted for a short period on scaling +changes. + +To check and modify the power saving mode, install cpufrequtils: + +.. code-block:: bash + + $ sudo apt install cpufrequtils + +Run ``cpufreq-info`` to check available "governors" and the current CPU Frequency (\ ``current CPU +frequency is XXX MHZ``\ ). In the following we will set the governor to "performance". + +.. code-block:: bash + + $ sudo systemctl disable ondemand + $ sudo systemctl enable cpufrequtils + $ sudo sh -c 'echo "GOVERNOR=performance" > /etc/default/cpufrequtils' + $ sudo systemctl daemon-reload && sudo systemctl restart cpufrequtils + +This disables the ``ondemand`` CPU scaling daemon, creates a ``cpufrequtils`` config file and restarts +the ``cpufrequtils`` service. Check with ``cpufreq-info``. + +For further information about governors, please see the `kernel +documentation `_. diff --git a/ur_robot_driver/doc/usage.rst b/ur_robot_driver/doc/usage.rst index 1a3acd329..6e23697ae 100644 --- a/ur_robot_driver/doc/usage.rst +++ b/ur_robot_driver/doc/usage.rst @@ -178,11 +178,8 @@ Using MoveIt `MoveIt! `_ support is built-in into this driver already. -Real robot / URSim -^^^^^^^^^^^^^^^^^^ - To test the driver with the example MoveIt-setup, first start the driver as described -`above <#start-hardware-simulator-or-mockup>`_. +`above <#start-hardware-simulator-or-mockup>`_ and then start the MoveIt! nodes using .. code-block:: @@ -191,17 +188,7 @@ To test the driver with the example MoveIt-setup, first start the driver as desc Now you should be able to use the MoveIt Plugin in rviz2 to plan and execute trajectories with the robot as explained `here `_. -Mock hardware -^^^^^^^^^^^^^ - -Currently, the ``scaled_joint_trajectory_controller`` does not work with ros2_control mock_hardware. There is an -`upstream Merge-Request `_ pending to fix that. Until this is merged and released, you'll have to fallback to the ``joint_trajectory_controller`` by passing ``initial_controller:=joint_trajectory_controller`` to the driver's startup. Also, you'll have to tell MoveIt! that you're using mock_hardware as it then has to map to the other controller: - -.. code-block:: - - ros2 launch ur_robot_driver ur_control.launch.py ur_type:=ur5e robot_ip:=yyy.yyy.yyy.yyy use_mock_hardware:=true launch_rviz:=false initial_joint_controller:=joint_trajectory_controller - # and in another shell - ros2 launch ur_moveit_config ur_moveit.launch.py ur_type:=ur5e launch_rviz:=true use_mock_hardware:=true +For more details, please see :ref:`ur_moveit_config`. Robot frames ------------