├── .clang-format ├── .dir-locals.el ├── .github ├── ISSUE_TEMPLATE │ ├── new_feature.yaml │ └── ros2_bug.yaml ├── dependabot.yml ├── dockerursim │ ├── .vol │ │ ├── default.installation │ │ ├── default.variables │ │ └── programs.UR5 │ ├── Dockerfile │ ├── build_and_run_docker_ursim.sh │ ├── safety.conf.UR5 │ └── ursim │ │ └── run ├── mergify.yml ├── release.yml └── workflows │ ├── check_links.yml │ ├── ci-format.yml │ ├── coverage-build.yml │ ├── foxy-binary-build.yml │ ├── galactic-binary-build.yml │ ├── humble-binary-main.yml │ ├── humble-binary-testing.yml │ ├── humble-semi-binary-main.yml │ ├── iron-binary-main.yml │ ├── issue-states.yml │ ├── jazzy-binary-main.yml │ ├── jazzy-binary-testing.yml │ ├── jazzy-semi-binary-main.yml │ ├── kilted-binary-main.yml │ ├── kilted-binary-testing.yml │ ├── kilted-semi-binary-main.yml │ ├── reusable_ici.yml │ ├── rolling-binary-main.yml │ ├── rolling-binary-testing.yml │ ├── rolling-semi-binary-main.yml │ └── update-ci.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Universal_Robots_ROS2_Driver.jazzy.repos ├── Universal_Robots_ROS2_Driver.kilted.repos ├── Universal_Robots_ROS2_Driver.rolling.repos ├── ci_status.md ├── ur ├── CHANGELOG.rst ├── CMakeLists.txt └── package.xml ├── ur_calibration ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.md ├── doc │ ├── algorithm.rst │ ├── calibration_example.png │ ├── calibration_example_corrected.png │ ├── calibration_uncorrected.png │ ├── conf.py │ ├── index.rst │ └── usage.rst ├── include │ └── ur_calibration │ │ ├── calibration.hpp │ │ └── calibration_consumer.hpp ├── launch │ └── calibration_correction.launch.py ├── package.xml ├── src │ ├── calibration.cpp │ ├── calibration_consumer.cpp │ └── calibration_correction.cpp └── test │ └── calibration_test.cpp ├── ur_controllers ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.md ├── controller_plugins.xml ├── doc │ ├── index.rst │ ├── traj_with_speed_scaling.png │ └── traj_without_speed_scaling.png ├── include │ └── ur_controllers │ │ ├── force_mode_controller.hpp │ │ ├── freedrive_mode_controller.hpp │ │ ├── gpio_controller.hpp │ │ ├── passthrough_trajectory_controller.hpp │ │ ├── scaled_joint_trajectory_controller.hpp │ │ ├── speed_scaling_state_broadcaster.hpp │ │ ├── tool_contact_controller.hpp │ │ └── ur_configuration_controller.hpp ├── package.xml ├── src │ ├── force_mode_controller.cpp │ ├── force_mode_controller_parameters.yaml │ ├── freedrive_mode_controller.cpp │ ├── freedrive_mode_controller_parameters.yaml │ ├── gpio_controller.cpp │ ├── gpio_controller_parameters.yaml │ ├── passthrough_trajectory_controller.cpp │ ├── passthrough_trajectory_controller_parameters.yaml │ ├── scaled_joint_trajectory_controller.cpp │ ├── scaled_joint_trajectory_controller_parameters.yaml │ ├── speed_scaling_state_broadcaster.cpp │ ├── speed_scaling_state_broadcaster_parameters.yaml │ ├── tool_contact_controller.cpp │ ├── tool_contact_controller_parameters.yaml │ ├── ur_configuration_controller.cpp │ └── ur_configuration_controller_parameters.yaml └── test │ ├── force_mode_controller_params.yaml │ ├── freedrive_mode_controller_params.yaml │ ├── test_load_force_mode_controller.cpp │ └── test_load_freedrive_mode_controller.cpp ├── ur_dashboard_msgs ├── CHANGELOG.rst ├── CMakeLists.txt ├── action │ └── SetMode.action ├── msg │ ├── ProgramState.msg │ ├── RobotMode.msg │ └── SafetyMode.msg ├── package.xml └── srv │ ├── AddToLog.srv │ ├── GetLoadedProgram.srv │ ├── GetProgramState.srv │ ├── GetRobotMode.srv │ ├── GetSafetyMode.srv │ ├── IsProgramRunning.srv │ ├── IsProgramSaved.srv │ ├── Load.srv │ ├── Popup.srv │ └── RawRequest.srv ├── ur_moveit_config ├── CHANGELOG.rst ├── CMakeLists.txt ├── config │ ├── chomp_planning.yaml │ ├── joint_limits.yaml │ ├── kinematics.yaml │ ├── moveit.rviz │ ├── moveit_controllers.yaml │ ├── ompl_planning.yaml │ ├── pilz_cartesian_limits.yaml │ ├── pilz_industrial_motion_planner_planning.yaml │ └── ur_servo.yaml ├── doc │ ├── index.rst │ └── migration │ │ └── jazzy.rst ├── launch │ └── ur_moveit.launch.py ├── package.xml └── srdf │ ├── ur.srdf.xacro │ └── ur_macro.srdf.xacro └── ur_robot_driver ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.md ├── config ├── test_goal_publishers_config.yaml ├── test_velocity_goal_publishers_config.yaml ├── ur10_update_rate.yaml ├── ur10e_update_rate.yaml ├── ur15_update_rate.yaml ├── ur16e_update_rate.yaml ├── ur20_update_rate.yaml ├── ur30_update_rate.yaml ├── ur3_update_rate.yaml ├── ur3e_update_rate.yaml ├── ur5_update_rate.yaml ├── ur5e_update_rate.yaml └── ur_controllers.yaml ├── doc ├── architecture_coarse.svg ├── conf.py ├── controller_stopper.rst ├── dashboard_client.rst ├── features.rst ├── hardware_interface_parameters.rst ├── index.rst ├── installation │ ├── initial_setup_images │ │ ├── cb3_01_welcome.png │ │ ├── cb3_05_urcaps_installed.png │ │ ├── cb3_07_installation_excontrol.png │ │ ├── cb3_10_prog_structure_urcaps.png │ │ ├── cb3_11_program_view_excontrol.png │ │ ├── es_01_welcome.png │ │ ├── es_05_urcaps_installed.png │ │ ├── es_07_installation_excontrol.png │ │ ├── es_10_prog_structure_urcaps.png │ │ ├── es_11_program_view_excontrol.png │ │ ├── family_photo.png │ │ ├── remote_control.png │ │ ├── services_polyscope5.png │ │ └── services_polyscopex.jpg │ ├── installation.rst │ ├── robot_setup.rst │ └── toc.rst ├── make.bat ├── migration │ └── jazzy.rst ├── operation_modes.rst ├── overview.rst ├── resources │ ├── 2021-10_ROS_World_2021_Making_a_robot_ROS2_powered.pdf │ ├── README.md │ ├── play_button.svg │ └── ros2_control_ur_driver.drawio ├── robot_state_helper.rst ├── setup_tool_communication.rst └── usage │ ├── controllers.rst │ ├── move.rst │ ├── script_code.rst │ ├── simulation.rst │ ├── startup.rst │ └── toc.rst ├── examples ├── examples.py └── force_mode.py ├── hardware_interface_plugin.xml ├── include └── ur_robot_driver │ ├── controller_stopper.hpp │ ├── dashboard_client_ros.hpp │ ├── hardware_interface.hpp │ ├── robot_state_helper.hpp │ └── urcl_log_handler.hpp ├── launch ├── test_forward_velocity_controller.launch.py ├── test_joint_trajectory_controller.launch.py ├── test_scaled_joint_trajectory_controller.launch.py ├── ur10.launch.py ├── ur10e.launch.py ├── ur12e.launch.py ├── ur15.launch.py ├── ur16e.launch.py ├── ur20.launch.py ├── ur3.launch.py ├── ur30.launch.py ├── ur3e.launch.py ├── ur5.launch.py ├── ur5e.launch.py ├── ur7e.launch.py ├── ur_control.launch.py ├── ur_dashboard_client.launch.py └── ur_rsp.launch.py ├── package.xml ├── resources ├── externalcontrol-1.0.5.urcap ├── rs485-1.0.urcap ├── rtde_input_recipe.txt └── rtde_output_recipe.txt ├── scripts ├── example_move.py ├── start_ursim.sh ├── tool_communication.py ├── wait_dashboard_server.sh └── wait_for_robot_description ├── src ├── controller_stopper.cpp ├── controller_stopper_node.cpp ├── dashboard_client_node.cpp ├── dashboard_client_ros.cpp ├── hardware_interface.cpp ├── robot_state_helper.cpp ├── robot_state_helper_node.cpp ├── urcl_log_handler.cpp └── urscript_interface.cpp ├── test ├── dashboard_client.py ├── example_move.py ├── integration_test_controller_switch.py ├── integration_test_force_mode.py ├── integration_test_tool_contact.py ├── launch_args.py ├── robot_driver.py ├── test_common.py └── urscript_interface.py ├── ur_robot_driver └── __init__.py └── urdf ├── ur.ros2_control.xacro └── ur.urdf.xacro /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: Google 3 | AccessModifierOffset: -2 4 | ConstructorInitializerIndentWidth: 2 5 | AlignEscapedNewlinesLeft: false 6 | AlignTrailingComments: true 7 | AllowAllParametersOfDeclarationOnNextLine: false 8 | AllowShortIfStatementsOnASingleLine: false 9 | AllowShortLoopsOnASingleLine: false 10 | AllowShortFunctionsOnASingleLine: None 11 | AlwaysBreakTemplateDeclarations: true 12 | AlwaysBreakBeforeMultilineStrings: false 13 | BreakBeforeBinaryOperators: false 14 | BreakBeforeTernaryOperators: false 15 | BreakConstructorInitializersBeforeComma: true 16 | BinPackParameters: true 17 | ColumnLimit: 120 18 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 19 | DerivePointerBinding: false 20 | PointerBindsToType: true 21 | ExperimentalAutoDetectBinPacking: false 22 | IndentCaseLabels: true 23 | MaxEmptyLinesToKeep: 1 24 | NamespaceIndentation: None 25 | ObjCSpaceBeforeProtocolList: true 26 | PenaltyBreakBeforeFirstCallParameter: 19 27 | PenaltyBreakComment: 60 28 | PenaltyBreakString: 1 29 | PenaltyBreakFirstLessLess: 1000 30 | PenaltyExcessCharacter: 1000 31 | PenaltyReturnTypeOnItsOwnLine: 90 32 | SpacesBeforeTrailingComments: 2 33 | Cpp11BracedListStyle: false 34 | Standard: Auto 35 | IndentWidth: 2 36 | TabWidth: 2 37 | UseTab: Never 38 | IndentFunctionDeclarationAfterType: false 39 | SpacesInParentheses: false 40 | SpacesInAngles: false 41 | SpaceInEmptyParentheses: false 42 | SpacesInCStyleCastParentheses: false 43 | SpaceAfterControlStatementKeyword: true 44 | SpaceBeforeAssignmentOperators: true 45 | ContinuationIndentWidth: 4 46 | SortIncludes: false 47 | SpaceAfterCStyleCast: false 48 | 49 | # Configure each individual brace in BraceWrapping 50 | BreakBeforeBraces: Custom 51 | 52 | # Control of individual brace wrapping cases 53 | BraceWrapping: 54 | AfterCaseLabel: 'true' 55 | AfterClass: 'true' 56 | AfterControlStatement: Never 57 | AfterEnum : 'true' 58 | AfterFunction : 'true' 59 | AfterNamespace : 'true' 60 | AfterStruct : 'true' 61 | AfterUnion : 'true' 62 | BeforeCatch : 'false' 63 | BeforeElse : 'false' 64 | IndentBraces : 'false' 65 | ... 66 | -------------------------------------------------------------------------------- /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ( 2 | (nil . ()) 3 | ;; Silence `ament_lint_cmake` errors 4 | (cmake-mode . ( 5 | ;; Tab found; please use spaces [whitespace/tabs] 6 | (indent-tabs-mode . nil) 7 | ;; Lines should be <= 80 characters long [linelength] 8 | (fill-column . 80) 9 | ;; Line ends in whitespace [whitespace/eol] 10 | (show-trailing-whitespace . t) 11 | )) 12 | ) 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new_feature.yaml: -------------------------------------------------------------------------------- 1 | name: New feature 2 | description: New feature to be suggested 3 | title: "[FEATURE NAME]" 4 | labels: ["enhancement"] 5 | 6 | body: 7 | - type: textarea 8 | id: description 9 | attributes: 10 | label: Feature summary 11 | value: | 12 | *Short introduction to the feature and why it should be implemented* 13 | 14 | *Followed by a longer description* 15 | 16 | ### Related issues 17 | *Links to related issues internal or external to this repo* 18 | 19 | ### Tasks 20 | *To complete this issue involves* 21 | - [ ] Implement the feature 22 | - [ ] Make documentation 23 | - [ ] Make Unit test 24 | - [ ] Make example 25 | - [ ] Test on real hardware 26 | 27 | validations: 28 | required: true 29 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Update actions in workflows weekly 2 | 3 | version: 2 4 | 5 | updates: 6 | - package-ecosystem: "github-actions" 7 | directory: "/" 8 | schedule: 9 | interval: "weekly" 10 | -------------------------------------------------------------------------------- /.github/dockerursim/.vol/default.installation: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/.github/dockerursim/.vol/default.installation -------------------------------------------------------------------------------- /.github/dockerursim/.vol/default.variables: -------------------------------------------------------------------------------- 1 | # 2 | #Thu May 28 16:20:13 BST 2020 3 | -------------------------------------------------------------------------------- /.github/dockerursim/.vol/programs.UR5: -------------------------------------------------------------------------------- 1 | /ursim/programs.UR5 2 | -------------------------------------------------------------------------------- /.github/dockerursim/build_and_run_docker_ursim.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 4 | 5 | docker network create --subnet=192.168.0.0/16 static_test_net 6 | 7 | docker build ${DIR} -t mydockerursim 8 | docker volume create dockerursim 9 | docker run --name="mydockerursim" -d \ 10 | -e ROBOT_MODEL=UR5 \ 11 | --net static_test_net \ 12 | --ip 192.168.56.101 \ 13 | -p 8080:8080 \ 14 | -p 29999:29999 \ 15 | -p 30001-30004:30001-30004 \ 16 | -v "${DIR}/.vol":/ursim/programs \ 17 | -v dockursim:/ursim \ 18 | --privileged \ 19 | --cpus=1 \ 20 | mydockerursim 21 | -------------------------------------------------------------------------------- /.github/dockerursim/safety.conf.UR5: -------------------------------------------------------------------------------- 1 | # Beware: This file is auto-generated from PolyScope. 2 | # NOTE: The SafetyParameters section is protected by a CRC checksum, please use the supplied tool 3 | 4 | ## SafetyParameters ## 5 | [NormalModeSafetyLimits] 6 | maxTcpSpeed = 1.5 7 | maxForce = 150.0 8 | maxElbowSpeed = 1.5 9 | maxElbowForce = 150.0 10 | maxStoppingDistance = 0.5 11 | maxStoppingTime = 0.4 12 | maxPower = 300.0 13 | maxMomentum = 25.0 14 | maxJointSpeed = [3.3415926, 3.3415926, 3.3415926, 3.3415926, 3.3415926, 3.3415926] 15 | minJointPosition = [6.2308254, 6.2308254, 6.2308254, 6.2308254, 6.2308254, 6.2308254] 16 | maxJointPosition = [0.05235988, 0.05235988, 0.05235988, 0.05235988, 0.05235988, 0.05235988] 17 | minJointRevolutions = [-2, -2, -2, -2, -2, -2] 18 | maxJointRevolutions = [1, 1, 1, 1, 1, 1] 19 | plane0 = [0.0, 0.0, 0.0, 0.0, 0] 20 | plane1 = [0.0, 0.0, 0.0, 0.0, 0] 21 | plane2 = [0.0, 0.0, 0.0, 0.0, 0] 22 | plane3 = [0.0, 0.0, 0.0, 0.0, 0] 23 | plane4 = [0.0, 0.0, 0.0, 0.0, 0] 24 | plane5 = [0.0, 0.0, 0.0, 0.0, 0] 25 | plane6 = [0.0, 0.0, 0.0, 0.0, 0] 26 | plane7 = [0.0, 0.0, 0.0, 0.0, 0] 27 | tcpOrientationVector = [0.0, 0.0, 1.0] 28 | maximumTcpOrientationDeviation = 6.2831855 29 | 30 | [ReducedModeSafetyLimits] 31 | maxTcpSpeed = 0.75 32 | maxForce = 120.0 33 | maxElbowSpeed = 0.75 34 | maxElbowForce = 120.0 35 | maxStoppingDistance = 0.3 36 | maxStoppingTime = 0.3 37 | maxPower = 200.0 38 | maxMomentum = 10.0 39 | maxJointSpeed = [3.3415926, 3.3415926, 3.3415926, 3.3415926, 3.3415926, 3.3415926] 40 | minJointPosition = [6.2308254, 6.2308254, 6.2308254, 6.2308254, 6.2308254, 6.2308254] 41 | maxJointPosition = [0.05235988, 0.05235988, 0.05235988, 0.05235988, 0.05235988, 0.05235988] 42 | minJointRevolutions = [-2, -2, -2, -2, -2, -2] 43 | maxJointRevolutions = [1, 1, 1, 1, 1, 1] 44 | plane0 = [0.0, 0.0, 0.0, 0.0, 0] 45 | plane1 = [0.0, 0.0, 0.0, 0.0, 0] 46 | plane2 = [0.0, 0.0, 0.0, 0.0, 0] 47 | plane3 = [0.0, 0.0, 0.0, 0.0, 0] 48 | plane4 = [0.0, 0.0, 0.0, 0.0, 0] 49 | plane5 = [0.0, 0.0, 0.0, 0.0, 0] 50 | plane6 = [0.0, 0.0, 0.0, 0.0, 0] 51 | plane7 = [0.0, 0.0, 0.0, 0.0, 0] 52 | tcpOrientationVector = [0.0, 0.0, 1.0] 53 | maximumTcpOrientationDeviation = 6.2831855 54 | 55 | [MiscConfiguration] 56 | teach_pendant = 1 57 | euromap67 = 0 58 | 59 | [SafetyIOConfiguration] 60 | emergencyStopInputA = 255 61 | emergencyStopInputB = 255 62 | reducedModeInputA = 255 63 | reducedModeInputB = 255 64 | safeguardStopResetInputA = 0 65 | safeguardStopResetInputB = 1 66 | threePositionEnablingInputA = 255 67 | threePositionEnablingInputB = 255 68 | operationalModeInputA = 255 69 | operationalModeInputB = 255 70 | systemEmergencyStopOutputA = 255 71 | systemEmergencyStopOutputB = 255 72 | robotMovingOutputA = 255 73 | robotMovingOutputB = 255 74 | robotNotStoppingOutputA = 255 75 | robotNotStoppingOutputB = 255 76 | reducedModeOutputA = 255 77 | reducedModeOutputB = 255 78 | notReducedModeOutputA = 255 79 | notReducedModeOutputB = 255 80 | 81 | [ReducedModeTriggerPlanes] 82 | plane0 = [0.0, 0.0, 0.0, 0.0, 0] 83 | plane1 = [0.0, 0.0, 0.0, 0.0, 0] 84 | plane2 = [0.0, 0.0, 0.0, 0.0, 0] 85 | plane3 = [0.0, 0.0, 0.0, 0.0, 0] 86 | plane4 = [0.0, 0.0, 0.0, 0.0, 0] 87 | plane5 = [0.0, 0.0, 0.0, 0.0, 0] 88 | plane6 = [0.0, 0.0, 0.0, 0.0, 0] 89 | plane7 = [0.0, 0.0, 0.0, 0.0, 0] 90 | 91 | [WorkpieceConfiguration] 92 | toolSpheres = [[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]] 93 | toolDirectionInclination = 0.0 94 | toolDirectionAzimuth = 0.0 95 | 96 | 97 | ## SafetyParameters ## 98 | [Checksum] 99 | safetyParameters = 3478627865 100 | majorVersion = 5 101 | minorVersion = 0 102 | -------------------------------------------------------------------------------- /.github/dockerursim/ursim/run: -------------------------------------------------------------------------------- 1 | #!/bin/execlineb -P 2 | 3 | s6-envdir -fn -- /var/run/s6/container_environment 4 | importas -i ROBOT_MODEL ROBOT_MODEL 5 | 6 | # Redirect stderr to stdout. 7 | fdmove -c 2 1 8 | 9 | # Wait until openbox is running 10 | if { s6-svwait -t 10000 -U /var/run/s6/services/openbox/ } 11 | 12 | # Set env 13 | s6-env DISPLAY=:1 14 | 15 | # Execute URSim 16 | /ursim/start-ursim.sh ${ROBOT_MODEL} 17 | -------------------------------------------------------------------------------- /.github/mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: Backport to humble branch 3 | conditions: 4 | - base=main 5 | - label=backport-humble 6 | actions: 7 | backport: 8 | branches: 9 | - humble 10 | labels: 11 | - humble 12 | 13 | - name: Backport to iron branch 14 | conditions: 15 | - base=main 16 | - label=backport-iron 17 | actions: 18 | backport: 19 | branches: 20 | - iron 21 | labels: 22 | - iron 23 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | changelog: 3 | exclude: 4 | labels: 5 | - release 6 | categories: 7 | - title: Bugfixes 8 | labels: 9 | - bugfix 10 | - title: New features 11 | labels: 12 | - enhancement 13 | - title: Documentation 14 | labels: 15 | - documentation 16 | - title: CI/ Repo / Packages 17 | labels: 18 | - CI 19 | - package 20 | - dependencies 21 | - title: Other 22 | labels: 23 | - "*" 24 | -------------------------------------------------------------------------------- /.github/workflows/check_links.yml: -------------------------------------------------------------------------------- 1 | name: Check Links 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | 9 | jobs: 10 | check_links: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - name: Restore lychee cache 15 | id: restore-cache 16 | uses: actions/cache/restore@v4 17 | with: 18 | path: .lycheecache 19 | key: cache-lychee-${{ github.run_id }}-${{ github.run_attempt }} 20 | restore-keys: cache-lychee- 21 | - name: Link Checker 22 | id: lychee 23 | uses: lycheeverse/lychee-action@v2 24 | with: 25 | fail: true 26 | args: > 27 | --verbose 28 | --no-progress 29 | --cache 30 | --cache-exclude-status 429 31 | --max-cache-age 2d 32 | --exclude '^http://192\.168\.56\.101' 33 | --max-concurrency 1 34 | './**/*.md' './**/*.html' './**/*.rst' './**/*.cpp' './**/*.h' './**/*.py' 35 | - name: Save lychee cache 36 | uses: actions/cache/save@v4 37 | if: always() 38 | with: 39 | path: .lycheecache 40 | key: ${{ steps.restore-cache.outputs.cache-primary-key }} 41 | -------------------------------------------------------------------------------- /.github/workflows/ci-format.yml: -------------------------------------------------------------------------------- 1 | # This is a format job. Pre-commit has a first-party GitHub action, so we use 2 | # that: https://github.com/pre-commit/action 3 | 4 | name: Format 5 | 6 | on: 7 | workflow_dispatch: 8 | pull_request: 9 | push: 10 | branches: 11 | - main 12 | 13 | jobs: 14 | pre-commit: 15 | name: Format 16 | runs-on: ubuntu-22.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: actions/setup-python@v5 20 | with: 21 | python-version: 3.10.4 22 | - name: Install system hooks 23 | run: sudo apt-get install clang-format-14 cppcheck 24 | - uses: pre-commit/action@v3.0.1 25 | with: 26 | extra_args: --all-files --hook-stage manual 27 | -------------------------------------------------------------------------------- /.github/workflows/coverage-build.yml: -------------------------------------------------------------------------------- 1 | name: Coverage Build 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | coverage: 9 | name: coverage build 10 | runs-on: ubuntu-22.04 11 | container: 12 | image: ubuntu:noble 13 | strategy: 14 | fail-fast: false 15 | env: 16 | ROS_DISTRO: rolling 17 | ros_version: 2 18 | steps: 19 | - uses: ros-tooling/setup-ros@v0.7 20 | with: 21 | required-ros-distributions: ${{ env.ROS_DISTRO }} 22 | use-ros2-testing: true 23 | - uses: actions/checkout@v4 24 | - uses: ros-tooling/action-ros-ci@v0.4 25 | with: 26 | target-ros2-distro: ${{ env.ROS_DISTRO }} 27 | # build all packages listed in the meta package 28 | package-name: 29 | ur_calibration 30 | ur_controllers 31 | ur_robot_driver 32 | colcon-defaults: | 33 | { 34 | "build": { 35 | "mixin": ["coverage-gcc", "coverage-pytest"] 36 | }, 37 | "test": { 38 | "mixin": ["coverage-pytest"] 39 | } 40 | } 41 | colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml 42 | skip-tests: false 43 | - uses: codecov/codecov-action@v5 44 | with: 45 | fail_ci_if_error: true 46 | file: ros_ws/lcov/total_coverage.info 47 | flags: unittests 48 | name: codecov-umbrella 49 | token: ${{ secrets.CODECOV_TOKEN }} 50 | - uses: actions/upload-artifact@v4 51 | with: 52 | name: colcon-logs-${{ matrix.os }} 53 | path: ros_ws/log 54 | -------------------------------------------------------------------------------- /.github/workflows/foxy-binary-build.yml: -------------------------------------------------------------------------------- 1 | name: Foxy Binary Build 2 | on: 3 | schedule: 4 | # Run every morning to detect flakiness and broken dependencies 5 | - cron: '58 11 * * *' 6 | 7 | jobs: 8 | foxy_binary: 9 | name: foxy binary build 10 | runs-on: ubuntu-latest 11 | strategy: 12 | max-parallel: 1 13 | matrix: 14 | env: 15 | - {ROS_DISTRO: foxy, ROS_REPO: main} 16 | - {ROS_DISTRO: foxy, ROS_REPO: testing} 17 | env: 18 | DOCKER_RUN_OPTS: --network static_test_net 19 | BEFORE_INIT: 'apt-get update -qq && apt-get install -y iproute2 iputils-ping && ip addr && ping -c5 192.168.56.101' 20 | IMMEDIATE_TEST_OUTPUT: true 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | ref: foxy 25 | - name: start ursim 26 | run: | 27 | .github/dockerursim/build_and_run_docker_ursim.sh 28 | - uses: 'ros-industrial/industrial_ci@master' 29 | env: ${{matrix.env}} 30 | -------------------------------------------------------------------------------- /.github/workflows/galactic-binary-build.yml: -------------------------------------------------------------------------------- 1 | name: Galactic Binary Build 2 | on: 3 | schedule: 4 | # Run every morning to detect flakiness and broken dependencies 5 | - cron: '03 4 * * *' 6 | 7 | jobs: 8 | galactic_binary: 9 | name: galactic binary build 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | ROS_DISTRO: [galactic] 15 | ROS_REPO: [main, testing] 16 | env: 17 | NOT_TEST_BUILD: true 18 | NOT_TEST_DOWNSTREAM: true 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | ref: galactic 23 | - uses: 'ros-industrial/industrial_ci@master' 24 | env: 25 | ROS_DISTRO: ${{ matrix.ROS_DISTRO }} 26 | ROS_REPO: ${{ matrix.ROS_REPO }} 27 | -------------------------------------------------------------------------------- /.github/workflows/humble-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Humble Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # Run every morning to detect flakiness and broken dependencies 6 | - cron: '03 5 * * *' 7 | 8 | jobs: 9 | humble_binary_main: 10 | uses: ./.github/workflows/reusable_ici.yml 11 | with: 12 | ros_distro: humble 13 | ros_repo: main 14 | ref_for_scheduled_build: humble 15 | -------------------------------------------------------------------------------- /.github/workflows/humble-binary-testing.yml: -------------------------------------------------------------------------------- 1 | name: Humble Binary Build Testing 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # Run every morning to detect flakiness and broken dependencies 6 | - cron: '03 5 * * *' 7 | 8 | 9 | jobs: 10 | humble_binary_testing: 11 | uses: ./.github/workflows/reusable_ici.yml 12 | with: 13 | ros_distro: humble 14 | ros_repo: testing 15 | ref_for_scheduled_build: humble 16 | -------------------------------------------------------------------------------- /.github/workflows/humble-semi-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Humble Semi Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # Run every morning to detect flakiness and broken dependencies 6 | - cron: '03 5 * * *' 7 | 8 | 9 | jobs: 10 | humble_semi_main: 11 | uses: ./.github/workflows/reusable_ici.yml 12 | with: 13 | ros_distro: humble 14 | ros_repo: main 15 | upstream_workspace: Universal_Robots_ROS2_Driver.humble.repos 16 | ref_for_scheduled_build: humble 17 | -------------------------------------------------------------------------------- /.github/workflows/iron-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Iron Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - iron 7 | push: 8 | branches: 9 | - iron 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 5 * * *' 13 | 14 | jobs: 15 | iron_binary_main: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: iron 19 | ros_repo: main 20 | ref_for_scheduled_build: iron 21 | -------------------------------------------------------------------------------- /.github/workflows/issue-states.yml: -------------------------------------------------------------------------------- 1 | name: 'Set issue state' 2 | 3 | on: 4 | project_card: 5 | types: [created, edited, moved] 6 | 7 | jobs: 8 | set-state: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: dessant/issue-states@v3 12 | with: 13 | github-token: ${{ github.token }} 14 | open-issue-columns: 'To do, In progress, Under Review' 15 | closed-issue-columns: 'Done' 16 | -------------------------------------------------------------------------------- /.github/workflows/jazzy-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Jazzy Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # Run every morning to detect flakiness and broken dependencies 6 | - cron: '13 4 * * *' 7 | 8 | jobs: 9 | jazzy_binary_main: 10 | uses: ./.github/workflows/reusable_ici.yml 11 | with: 12 | ros_distro: jazzy 13 | ros_repo: main 14 | ref_for_scheduled_build: jazzy 15 | -------------------------------------------------------------------------------- /.github/workflows/jazzy-binary-testing.yml: -------------------------------------------------------------------------------- 1 | name: Jazzy Binary Build Testing 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # Run every morning to detect flakiness and broken dependencies 6 | - cron: '13 4 * * *' 7 | 8 | jobs: 9 | jazzy_binary_testing: 10 | uses: ./.github/workflows/reusable_ici.yml 11 | with: 12 | ros_distro: jazzy 13 | ros_repo: testing 14 | ref_for_scheduled_build: jazzy 15 | -------------------------------------------------------------------------------- /.github/workflows/jazzy-semi-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Jazzy Semi Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # Run every morning to detect flakiness and broken dependencies 6 | - cron: '13 4 * * *' 7 | 8 | jobs: 9 | jazzy_semi_main: 10 | uses: ./.github/workflows/reusable_ici.yml 11 | with: 12 | ros_distro: jazzy 13 | ros_repo: main 14 | upstream_workspace: Universal_Robots_ROS2_Driver.jazzy.repos 15 | ref_for_scheduled_build: jazzy 16 | -------------------------------------------------------------------------------- /.github/workflows/kilted-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Kilted Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 4 * * *' 13 | 14 | jobs: 15 | kilted_binary_main: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: kilted 19 | ros_repo: main 20 | ref_for_scheduled_build: main 21 | -------------------------------------------------------------------------------- /.github/workflows/kilted-binary-testing.yml: -------------------------------------------------------------------------------- 1 | name: Kilted Binary Build Testing 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 4 * * *' 13 | 14 | jobs: 15 | kilted_binary_testing: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: kilted 19 | ros_repo: testing 20 | ref_for_scheduled_build: main 21 | -------------------------------------------------------------------------------- /.github/workflows/kilted-semi-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Kilted Semi Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 4 * * *' 13 | 14 | jobs: 15 | kilted_semi_main: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: kilted 19 | ros_repo: main 20 | upstream_workspace: Universal_Robots_ROS2_Driver.kilted.repos 21 | ref_for_scheduled_build: main 22 | -------------------------------------------------------------------------------- /.github/workflows/reusable_ici.yml: -------------------------------------------------------------------------------- 1 | name: Reusable industrial_ci workflow 2 | # original author: Denis Štogl 3 | 4 | on: 5 | workflow_call: 6 | inputs: 7 | ref_for_scheduled_build: 8 | description: 'Reference on which the repo should be checkout for scheduled build. Usually is this name of a branch or a tag.' 9 | default: '' 10 | required: false 11 | type: string 12 | 13 | upstream_workspace: 14 | description: 'UPSTREAM_WORKSPACE variable for industrial_ci. Usually path to local .repos file.' 15 | required: false 16 | default: '' 17 | type: string 18 | ros_distro: 19 | description: 'ROS_DISTRO variable for industrial_ci' 20 | required: true 21 | type: string 22 | ros_repo: 23 | description: 'ROS_REPO to run for industrial_ci. Possible values: "main", "testing"' 24 | default: 'main' 25 | required: false 26 | type: string 27 | before_install_upstream_dependencies: 28 | description: 'BEFORE_INSTALL_UPSTREAM_DEPENDENCIES variable for industrial_ci' 29 | default: '' 30 | required: false 31 | type: string 32 | ccache_dir: 33 | description: 'CCache dir that should be used. Relative to github.workspace' 34 | default: '.ccache' 35 | required: false 36 | type: string 37 | 38 | jobs: 39 | reusable_ici: 40 | name: ${{ inputs.ros_distro }} ${{ inputs.ros_repo }} 41 | runs-on: ubuntu-latest 42 | env: 43 | DOCKER_RUN_OPTS: '-v /var/run/docker.sock:/var/run/docker.sock --network ursim_net' 44 | CCACHE_DIR: ${{ github.workspace }}/${{ inputs.ccache_dir }} 45 | CACHE_PREFIX: ${{ inputs.ros_distro }}-${{ inputs.upstream_workspace }}-${{ inputs.ros_repo }} 46 | steps: 47 | - name: Checkout ${{ github.ref_name }} since build is not scheduled 48 | if: ${{ github.event_name != 'schedule' }} 49 | uses: actions/checkout@v4 50 | - name: Checkout ${{ inputs.ref_for_scheduled_build }} on scheduled build 51 | if: ${{ github.event_name == 'schedule' }} 52 | uses: actions/checkout@v4 53 | with: 54 | ref: ${{ inputs.ref_for_scheduled_build }} 55 | - run: docker network create --subnet=192.168.56.0/24 ursim_net 56 | if: ${{ !env.ACT }} 57 | - name: Cache ccache 58 | uses: actions/cache@v4 59 | with: 60 | path: ${{ env.CCACHE_DIR }} 61 | key: ccache-${{ env.CACHE_PREFIX }}-${{ github.sha }}-${{ github.run_id }} 62 | restore-keys: | 63 | ccache-${{ env.CACHE_PREFIX }}-${{ github.sha }} 64 | ccache-${{ env.CACHE_PREFIX }} 65 | - uses: 'ros-industrial/industrial_ci@master' 66 | env: 67 | UPSTREAM_WORKSPACE: ${{ inputs.upstream_workspace }} 68 | ROS_DISTRO: ${{ inputs.ros_distro }} 69 | ROS_REPO: ${{ inputs.ros_repo }} 70 | CMAKE_ARGS: -DUR_ROBOT_DRIVER_BUILD_INTEGRATION_TESTS=ON 71 | ADDITIONAL_DEBS: docker.io netcat-openbsd # Needed for integration tests 72 | -------------------------------------------------------------------------------- /.github/workflows/rolling-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Rolling Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 4 * * *' 13 | 14 | jobs: 15 | rolling_binary_main: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: rolling 19 | ros_repo: main 20 | ref_for_scheduled_build: main 21 | -------------------------------------------------------------------------------- /.github/workflows/rolling-binary-testing.yml: -------------------------------------------------------------------------------- 1 | name: Rolling Binary Build Testing 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 4 * * *' 13 | 14 | jobs: 15 | rolling_binary_testing: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: rolling 19 | ros_repo: testing 20 | ref_for_scheduled_build: main 21 | -------------------------------------------------------------------------------- /.github/workflows/rolling-semi-binary-main.yml: -------------------------------------------------------------------------------- 1 | name: Rolling Semi Binary Build Main 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | schedule: 11 | # Run every morning to detect flakiness and broken dependencies 12 | - cron: '13 4 * * *' 13 | 14 | jobs: 15 | rolling_semi_main: 16 | uses: ./.github/workflows/reusable_ici.yml 17 | with: 18 | ros_distro: rolling 19 | ros_repo: main 20 | upstream_workspace: Universal_Robots_ROS2_Driver.rolling.repos 21 | ref_for_scheduled_build: main 22 | -------------------------------------------------------------------------------- /.github/workflows/update-ci.yml: -------------------------------------------------------------------------------- 1 | # Auto-update CI tools regularly 2 | 3 | name: CI auto-update 4 | 5 | on: 6 | schedule: 7 | # Run weekly 8 | - cron: '23 5 * * 0' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | ci_auto_update: 13 | name: CI auto-update 14 | runs-on: ubuntu-latest 15 | steps: 16 | # Setup pre-commit 17 | - uses: actions/checkout@v4 18 | - uses: actions/setup-python@v5 19 | with: 20 | python-version: 3.10.4 21 | - name: Install pre-commit 22 | run: pip install pre-commit 23 | 24 | # Run update 25 | - name: Run pre-commit autoupdate 26 | run: pre-commit autoupdate 27 | 28 | # Create pull request 29 | - name: Create pull-request 30 | id: cpr 31 | uses: peter-evans/create-pull-request@v7 32 | with: 33 | branch: update-ci/pre-commit-autoupdate 34 | delete-branch: true 35 | title: Auto-update pre-commit hooks 36 | committer: github-actions[bot] 37 | author: github-actions[bot] 38 | commit-message: Auto-update pre-commit hooks 39 | labels: CI 40 | - name: Check outputs 41 | if: ${{ steps.cpr.pull-request-number }} 42 | run: echo "Opened pull request ${{ steps.cpr.outputs.pull-request-number }} - ${{ steps.cpr.outputs.pull-request-url }}" 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | Makefile 4 | cmake_install.cmake 5 | install_manifest.txt 6 | *~ 7 | .idea 8 | .directory 9 | .vscode 10 | .moveit_ci/ 11 | docs_output 12 | docs_build 13 | cross_reference 14 | ur_robot_driver/doc/generated 15 | .lycheecache 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | Thank you for your interest in contributing to `Universal_Robots_ROS2_Driver`. 3 | Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 12 | 13 | When filing an issue, please check [existing open][issues], or [recently closed][closed-issues], issues to make sure 14 | somebody else hasn't already reported the issue. 15 | Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. 25 | Before sending us a pull request, please ensure that: 26 | 27 | 1. You are working against the latest source on the *master* branch. 28 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 29 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 30 | 31 | To send us a pull request, please: 32 | 33 | 1. Fork the repository. 34 | 2. Modify the source; please focus on the specific change you are contributing. 35 | If you also reformat all the code, it will be hard for us to focus on your change. 36 | 3. Ensure local tests pass. 37 | 4. Commit to your fork using clear commit messages. 38 | 5. Send a pull request, answering any default questions in the pull request interface. 39 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 40 | 41 | GitHub provides additional documentation on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 42 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 43 | 44 | 45 | ## Licensing 46 | Any contribution that you make to this repository will 47 | be under the 3-Clause BSD License, as dictated by that 48 | [license](https://opensource.org/licenses/BSD-3-Clause). 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions are met: 3 | 4 | * Redistributions of source code must retain the above copyright 5 | notice, this list of conditions and the following disclaimer. 6 | 7 | * Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | 11 | * Neither the name of the copyright holder nor the names of its 12 | contributors may be used to endorse or promote products derived from 13 | this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Universal_Robots_ROS2_Driver.jazzy.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | Universal_Robots_Client_Library: 3 | type: git 4 | url: https://github.com/UniversalRobots/Universal_Robots_Client_Library.git 5 | version: master 6 | Universal_Robots_ROS2_Description: 7 | type: git 8 | url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Description.git 9 | version: jazzy 10 | ur_msgs: 11 | type: git 12 | url: https://github.com/ros-industrial/ur_msgs.git 13 | version: humble-devel 14 | ros2_control: 15 | type: git 16 | url: https://github.com/ros-controls/ros2_control.git 17 | version: master 18 | ros2_controllers: 19 | type: git 20 | url: https://github.com/ros-controls/ros2_controllers 21 | version: jazzy 22 | kinematics_interface: 23 | type: git 24 | url: https://github.com/ros-controls/kinematics_interface.git 25 | version: jazzy 26 | control_msgs: 27 | type: git 28 | url: https://github.com/ros-controls/control_msgs.git 29 | version: jazzy 30 | control_toolbox: 31 | type: git 32 | url: https://github.com/ros-controls/control_toolbox.git 33 | version: jazzy 34 | realtime_tools: 35 | type: git 36 | url: https://github.com/ros-controls/realtime_tools.git 37 | version: jazzy 38 | moveit2: 39 | type: git 40 | url: https://github.com/moveit/moveit2.git 41 | version: main 42 | moveit_msgs: 43 | type: git 44 | url: https://github.com/moveit/moveit_msgs.git 45 | version: ros2 46 | srdfdom: 47 | type: git 48 | url: https://github.com/moveit/srdfdom.git 49 | version: ros2 50 | -------------------------------------------------------------------------------- /Universal_Robots_ROS2_Driver.kilted.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | Universal_Robots_Client_Library: 3 | type: git 4 | url: https://github.com/UniversalRobots/Universal_Robots_Client_Library.git 5 | version: master 6 | Universal_Robots_ROS2_Description: 7 | type: git 8 | url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Description.git 9 | version: rolling 10 | ur_msgs: 11 | type: git 12 | url: https://github.com/ros-industrial/ur_msgs.git 13 | version: humble-devel 14 | ros2_control: 15 | type: git 16 | url: https://github.com/ros-controls/ros2_control.git 17 | version: master 18 | ros2_controllers: 19 | type: git 20 | url: https://github.com/ros-controls/ros2_controllers 21 | version: master 22 | kinematics_interface: 23 | type: git 24 | url: https://github.com/ros-controls/kinematics_interface.git 25 | version: master 26 | control_msgs: 27 | type: git 28 | url: https://github.com/ros-controls/control_msgs.git 29 | version: master 30 | control_toolbox: 31 | type: git 32 | url: https://github.com/ros-controls/control_toolbox.git 33 | version: ros2-master 34 | realtime_tools: 35 | type: git 36 | url: https://github.com/ros-controls/realtime_tools.git 37 | version: master 38 | moveit2: 39 | type: git 40 | url: https://github.com/moveit/moveit2.git 41 | version: main 42 | moveit_msgs: 43 | type: git 44 | url: https://github.com/moveit/moveit_msgs.git 45 | version: ros2 46 | srdfdom: 47 | type: git 48 | url: https://github.com/moveit/srdfdom.git 49 | version: ros2 50 | -------------------------------------------------------------------------------- /Universal_Robots_ROS2_Driver.rolling.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | Universal_Robots_Client_Library: 3 | type: git 4 | url: https://github.com/UniversalRobots/Universal_Robots_Client_Library.git 5 | version: master 6 | Universal_Robots_ROS2_Description: 7 | type: git 8 | url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Description.git 9 | version: rolling 10 | ur_msgs: 11 | type: git 12 | url: https://github.com/ros-industrial/ur_msgs.git 13 | version: humble-devel 14 | ros2_control: 15 | type: git 16 | url: https://github.com/ros-controls/ros2_control.git 17 | version: master 18 | ros2_controllers: 19 | type: git 20 | url: https://github.com/ros-controls/ros2_controllers 21 | version: master 22 | kinematics_interface: 23 | type: git 24 | url: https://github.com/ros-controls/kinematics_interface.git 25 | version: master 26 | control_msgs: 27 | type: git 28 | url: https://github.com/ros-controls/control_msgs.git 29 | version: master 30 | control_toolbox: 31 | type: git 32 | url: https://github.com/ros-controls/control_toolbox.git 33 | version: ros2-master 34 | realtime_tools: 35 | type: git 36 | url: https://github.com/ros-controls/realtime_tools.git 37 | version: master 38 | moveit2: 39 | type: git 40 | url: https://github.com/moveit/moveit2.git 41 | version: main 42 | moveit_msgs: 43 | type: git 44 | url: https://github.com/moveit/moveit_msgs.git 45 | version: ros2 46 | srdfdom: 47 | type: git 48 | url: https://github.com/moveit/srdfdom.git 49 | version: ros2 50 | -------------------------------------------------------------------------------- /ur/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package ur 3 | ^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 4.0.1 (2025-05-28) 6 | ------------------ 7 | 8 | 4.0.0 (2025-05-20) 9 | ------------------ 10 | 11 | 3.2.1 (2025-04-11) 12 | ------------------ 13 | 14 | 3.2.0 (2025-04-10) 15 | ------------------ 16 | 17 | 3.1.1 (2025-03-17) 18 | ------------------ 19 | 20 | 3.1.0 (2025-03-05) 21 | ------------------ 22 | 23 | 3.0.2 (2025-01-21) 24 | ------------------ 25 | 26 | 3.0.1 (2024-12-30) 27 | ------------------ 28 | 29 | 3.0.0 (2024-12-18) 30 | ------------------ 31 | * Update package maintainers (`#1203 `_) 32 | * Contributors: Felix Exner 33 | 34 | 2.4.13 (2024-10-28) 35 | ------------------- 36 | 37 | 2.4.12 (2024-10-14) 38 | ------------------- 39 | 40 | 2.4.11 (2024-10-10) 41 | ------------------- 42 | 43 | 2.4.10 (2024-09-11) 44 | ------------------- 45 | * Update maintainers team (`#1088 `_) 46 | * Contributors: Vincenzo Di Pentima 47 | 48 | 2.4.9 (2024-08-09) 49 | ------------------ 50 | 51 | 2.4.8 (2024-07-01) 52 | ------------------ 53 | 54 | 2.4.7 (2024-06-19) 55 | ------------------ 56 | 57 | 2.4.6 (2024-06-17) 58 | ------------------ 59 | 60 | 2.4.5 (2024-05-16) 61 | ------------------ 62 | 63 | 2.4.4 (2024-04-04) 64 | ------------------ 65 | 66 | 2.4.3 (2024-02-02) 67 | ------------------ 68 | 69 | 2.4.2 (2023-11-23) 70 | ------------------ 71 | 72 | 2.4.1 (2023-09-21) 73 | ------------------ 74 | 75 | 2.4.0 (2023-08-28) 76 | ------------------ 77 | 78 | 2.3.2 (2023-06-02) 79 | ------------------ 80 | 81 | 2.3.1 (2023-03-16) 82 | ------------------ 83 | 84 | 2.3.0 (2023-03-02) 85 | ------------------ 86 | 87 | 2.2.4 (2022-10-07) 88 | ------------------ 89 | 90 | 2.2.3 (2022-07-27) 91 | ------------------ 92 | 93 | 2.2.2 (2022-07-19) 94 | ------------------ 95 | 96 | 2.2.1 (2022-06-27) 97 | ------------------ 98 | 99 | 2.2.0 (2022-06-20) 100 | ------------------ 101 | * wip 102 | * Rework bringup (`#403 `_) 103 | * Copy all bringup files to ur_robot_driver 104 | * Update documentation to use launchfiles from ur_robot_driver 105 | * Add deprecation warnings for ur_bringup 106 | * Add ``ur`` metapackage 107 | * Added deprecation warning to toplevel README 108 | * Added meta package to CI checks 109 | * Contributors: Felix Exner 110 | 111 | * Rework bringup (`#403 `_) 112 | * Contributors: Felix Exner 113 | 114 | 0.0.3 (2020-10-29) 115 | ------------------ 116 | -------------------------------------------------------------------------------- /ur/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(ur) 3 | 4 | 5 | find_package(ament_cmake REQUIRED) 6 | 7 | if(BUILD_TESTING) 8 | find_package(ament_lint_auto REQUIRED) 9 | set(ament_cmake_copyright_FOUND TRUE) 10 | set(ament_cmake_cpplint_FOUND TRUE) 11 | ament_lint_auto_find_test_dependencies() 12 | endif() 13 | 14 | ament_package() 15 | -------------------------------------------------------------------------------- /ur/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ur 5 | 4.0.1 6 | Metapackage for universal robots 7 | Felix Exner 8 | Rune Søe-Knudsen 9 | Universal Robots A/S 10 | BSD-3-Clause 11 | 12 | ament_cmake 13 | 14 | ur_calibration 15 | ur_controllers 16 | ur_dashboard_msgs 17 | ur_moveit_config 18 | ur_robot_driver 19 | 20 | ament_lint_auto 21 | ament_lint_common 22 | 23 | 24 | ament_cmake 25 | 26 | 27 | -------------------------------------------------------------------------------- /ur_calibration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(ur_calibration) 3 | 4 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 5 | add_compile_options(-Wall -Wextra -Wpedantic) 6 | endif() 7 | 8 | add_compile_options(-Wno-unused-parameter) 9 | 10 | if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) 11 | message("${PROJECT_NAME}: You did not request a specific build type: selecting 'RelWithDebInfo'.") 12 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 13 | endif() 14 | 15 | find_package(ament_cmake REQUIRED) 16 | find_package(rclcpp REQUIRED) 17 | find_package(ur_robot_driver REQUIRED) 18 | find_package(sensor_msgs REQUIRED) 19 | find_package(tf2_ros REQUIRED) 20 | 21 | find_package(Eigen3 REQUIRED) 22 | find_package(yaml_cpp_vendor REQUIRED) 23 | find_package(ur_client_library REQUIRED) 24 | 25 | ########### 26 | ## Build ## 27 | ########### 28 | 29 | add_library(calibration 30 | src/calibration.cpp 31 | src/calibration_consumer.cpp 32 | ) 33 | target_include_directories(calibration 34 | PUBLIC 35 | include 36 | ) 37 | target_link_libraries(calibration 38 | ur_client_library::urcl 39 | Eigen3::Eigen 40 | yaml-cpp 41 | rclcpp::rclcpp 42 | ur_robot_driver::ur_robot_driver_log_handler 43 | ) 44 | 45 | add_executable(calibration_correction 46 | src/calibration_correction.cpp 47 | ) 48 | target_include_directories(calibration_correction 49 | PRIVATE 50 | include 51 | ) 52 | target_link_libraries(calibration_correction 53 | ${sensor_msgs_TARGETS} 54 | tf2_ros::tf2_ros 55 | calibration 56 | ) 57 | 58 | install(TARGETS calibration_correction 59 | RUNTIME DESTINATION lib/${PROJECT_NAME} 60 | ) 61 | 62 | install(DIRECTORY include/ 63 | DESTINATION include 64 | ) 65 | 66 | install(DIRECTORY launch 67 | DESTINATION share/${PROJECT_NAME} 68 | ) 69 | 70 | ## Add gtest based cpp test target and link libraries 71 | if(BUILD_TESTING) 72 | find_package(ament_cmake_gmock REQUIRED) 73 | 74 | # Get the first item (it will be the build space version of the build path). 75 | list(GET ament_index_build_path 0 ament_index_build_path) 76 | if(WIN32) 77 | # On Windows prevent CMake errors and prevent it being evaluated as a list. 78 | string(REPLACE "\\" "/" ament_index_build_path "${ament_index_build_path}") 79 | endif() 80 | 81 | ament_add_gmock( 82 | calibration_test 83 | test/calibration_test.cpp 84 | ) 85 | target_link_libraries(calibration_test 86 | calibration 87 | ) 88 | endif() 89 | 90 | ament_export_include_directories( 91 | include 92 | ) 93 | ament_export_dependencies( 94 | ur_robot_driver 95 | rclcpp 96 | ) 97 | ament_package() 98 | -------------------------------------------------------------------------------- /ur_calibration/README.md: -------------------------------------------------------------------------------- 1 | # ur_calibration 2 | 3 | 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. 4 | 5 | Each UR robot is calibrated inside the factory giving exact forward and inverse kinematics. To also 6 | make use of this in ROS, you first have to extract the calibration information from the robot. 7 | 8 | Though this step is not necessary, to control the robot using this driver, it is highly recommended 9 | to do so, as end effector positions might be off in the magnitude of centimeters. 10 | 11 | For details please see [doc/index.rst](doc/index.rst) 12 | -------------------------------------------------------------------------------- /ur_calibration/doc/calibration_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_calibration/doc/calibration_example.png -------------------------------------------------------------------------------- /ur_calibration/doc/calibration_example_corrected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_calibration/doc/calibration_example_corrected.png -------------------------------------------------------------------------------- /ur_calibration/doc/calibration_uncorrected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_calibration/doc/calibration_uncorrected.png -------------------------------------------------------------------------------- /ur_calibration/doc/conf.py: -------------------------------------------------------------------------------- 1 | project = "ur_calibration" 2 | copyright = "2022, Universal Robots A/S" 3 | author = "Felix Exner" 4 | 5 | # The short X.Y version 6 | version = "" 7 | # The full version, including alpha/beta/rc tags 8 | release = "" 9 | 10 | # -- General configuration --------------------------------------------------- 11 | 12 | # If your documentation needs a minimal Sphinx version, state it here. 13 | # 14 | # needs_sphinx = '1.0' 15 | 16 | # Add any Sphinx extension module names here, as strings. They can be 17 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 18 | # ones. 19 | extensions = [] 20 | 21 | # Add any paths that contain templates here, relative to this directory. 22 | templates_path = ["_templates"] 23 | 24 | # The suffix(es) of source filenames. 25 | # You can specify multiple suffix as a list of string: 26 | # 27 | source_suffix = [".rst"] 28 | 29 | # The master toctree document. 30 | master_doc = "index" 31 | 32 | numfig = True 33 | 34 | # The language for content autogenerated by Sphinx. Refer to documentation 35 | # for a list of supported languages. 36 | # 37 | # This is also used if you do content translation via gettext catalogs. 38 | # Usually you set "language" from the command line for these cases. 39 | language = None 40 | 41 | # List of patterns, relative to source directory, that match files and 42 | # directories to ignore when looking for source files. 43 | # This pattern also affects html_static_path and html_extra_path. 44 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 45 | 46 | # The name of the Pygments (syntax highlighting) style to use. 47 | pygments_style = None 48 | 49 | 50 | # -- Options for HTML output ------------------------------------------------- 51 | 52 | # The theme to use for HTML and HTML Help pages. See the documentation for 53 | # a list of builtin themes. 54 | # 55 | html_theme = "alabaster" 56 | 57 | # Theme options are theme-specific and customize the look and feel of a theme 58 | # further. For a list of options available for each theme, see the 59 | # documentation. 60 | # 61 | # html_theme_options = {} 62 | 63 | # Add any paths that contain custom static files (such as style sheets) here, 64 | # relative to this directory. They are copied after the builtin static files, 65 | # so a file named "default.css" will overwrite the builtin "default.css". 66 | html_static_path = ["_static"] 67 | 68 | # Custom sidebar templates, must be a dictionary that maps document names 69 | # to template names. 70 | # 71 | # The default sidebars (for documents that don't match any pattern) are 72 | # defined by theme itself. Builtin themes are using these templates by 73 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 74 | # 'searchbox.html']``. 75 | # 76 | # html_sidebars = {} 77 | 78 | 79 | # -- Options for HTMLHelp output --------------------------------------------- 80 | 81 | # Output file base name for HTML help builder. 82 | htmlhelp_basename = "ur_calibration_doc" 83 | 84 | 85 | # -- Options for LaTeX output ------------------------------------------------ 86 | -------------------------------------------------------------------------------- /ur_calibration/doc/index.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_calibration/doc/index.rst 2 | 3 | .. _ur_calibration: 4 | 5 | ur_calibration 6 | ============== 7 | 8 | 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. 9 | 10 | Each UR robot is calibrated inside the factory giving exact forward and inverse kinematics. To also 11 | make use of this in ROS, you first have to extract the calibration information from the robot. 12 | 13 | Though this step is not necessary, to control the robot using this driver, it is highly recommended 14 | to do so, as end effector positions might be off in the magnitude of centimeters. 15 | 16 | .. toctree:: 17 | :maxdepth: 2 18 | 19 | usage 20 | algorithm 21 | -------------------------------------------------------------------------------- /ur_calibration/doc/usage.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_calibration/doc/usage.rst 2 | 3 | Usage 4 | ===== 5 | 6 | To use the calibration correction this package provides a launchfile that extracts calibration 7 | information directly from a robot, calculates the URDF correction and saves it into a .yaml file: 8 | 9 | .. code-block:: bash 10 | 11 | $ ros2 launch ur_calibration calibration_correction.launch.py \ 12 | robot_ip:= target_filename:="${HOME}/my_robot_calibration.yaml" 13 | 14 | For the parameter ``robot_ip`` insert the IP address on which the ROS pc can reach the robot. As 15 | ``target_filename`` provide an absolute path where the result will be saved to. 16 | 17 | With that, you can launch your specific robot with the correct calibration using 18 | 19 | .. code-block:: bash 20 | 21 | $ ros2 launch ur_robot_driver ur_control.launch.py \ 22 | ur_type:=ur5e \ 23 | robot_ip:=192.168.56.101 \ 24 | kinematics_params_file:="${HOME}/my_robot_calibration.yaml" 25 | 26 | Adapt the robot model matching to your robot. 27 | 28 | Ideally, you would create a package for your custom workcell, as explained in `the custom workcell 29 | tutorial 30 | `_. 31 | -------------------------------------------------------------------------------- /ur_calibration/include/ur_calibration/calibration_consumer.hpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Created on behalf of Universal Robots A/S 3 | // Copyright 2019 FZI Forschungszentrum Informatik 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright 12 | // notice, this list of conditions and the following disclaimer in the 13 | // documentation and/or other materials provided with the distribution. 14 | // 15 | // * Neither the name of the {copyright_holder} nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | // POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // -- END LICENSE BLOCK ------------------------------------------------ 32 | 33 | //---------------------------------------------------------------------- 34 | /*!\file 35 | * 36 | * \author Felix Exner exner@fzi.de 37 | * \date 2019-05-28 38 | * \author Lovro Ivanov lovro.ivanov@gmail.com 39 | * \date 2021-09-22 40 | * 41 | */ 42 | //---------------------------------------------------------------------- 43 | 44 | #ifndef UR_CALIBRATION__CALIBRATION_CONSUMER_HPP_ 45 | #define UR_CALIBRATION__CALIBRATION_CONSUMER_HPP_ 46 | 47 | #include 48 | 49 | #include "ur_client_library/comm/pipeline.h" 50 | #include "ur_client_library/primary/robot_state/kinematics_info.h" 51 | 52 | #include "ur_calibration/calibration.hpp" 53 | 54 | namespace ur_calibration 55 | { 56 | class CalibrationConsumer : public urcl::comm::IConsumer 57 | { 58 | public: 59 | CalibrationConsumer(); 60 | virtual ~CalibrationConsumer() = default; 61 | 62 | virtual bool consume(std::shared_ptr product); 63 | 64 | bool isCalibrated() const 65 | { 66 | return calibrated_; 67 | } 68 | 69 | YAML::Node getCalibrationParameters() const; 70 | 71 | private: 72 | bool calibrated_; 73 | YAML::Node calibration_parameters_; 74 | }; 75 | } // namespace ur_calibration 76 | #endif // UR_CALIBRATION__CALIBRATION_CONSUMER_HPP_ 77 | -------------------------------------------------------------------------------- /ur_calibration/launch/calibration_correction.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 PickNik, Inc. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # 9 | # * Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 13 | # * Neither the name of the {copyright_holder} nor the names of its 14 | # contributors may be used to endorse or promote products derived from 15 | # this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # 30 | # Author: Lovro Ivanov 31 | 32 | from launch import LaunchDescription 33 | from launch.actions import DeclareLaunchArgument 34 | from launch.substitutions import LaunchConfiguration 35 | from launch_ros.actions import Node 36 | 37 | 38 | def generate_launch_description(): 39 | declared_arguments = [] 40 | declared_arguments.append( 41 | DeclareLaunchArgument( 42 | "robot_ip", description="The IP address at which the robot is reachable." 43 | ) 44 | ) 45 | declared_arguments.append( 46 | DeclareLaunchArgument( 47 | "target_filename", 48 | default_value="robot_calibration.yaml", 49 | description="The extracted calibration information " 50 | "will be written to this target file.", 51 | ) 52 | ) 53 | 54 | # Initialize Arguments 55 | robot_ip = LaunchConfiguration("robot_ip") 56 | output_filename = LaunchConfiguration("target_filename") 57 | 58 | calibration_correction = Node( 59 | package="ur_calibration", 60 | executable="calibration_correction", 61 | parameters=[{"robot_ip": robot_ip}, {"output_filename": output_filename}], 62 | output="screen", 63 | ) 64 | 65 | nodes_to_start = [ 66 | calibration_correction, 67 | ] 68 | 69 | return LaunchDescription(declared_arguments + nodes_to_start) 70 | -------------------------------------------------------------------------------- /ur_calibration/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ur_calibration 4 | 4.0.1 5 | Package for extracting the factory calibration from a UR robot and change it such that it can be used by ur_description to gain a correct URDF 6 | 7 | Felix Exner 8 | Rune Søe-Knudsen 9 | Universal Robots A/S 10 | 11 | BSD-3-Clause 12 | 13 | Robert Wilbrandt 14 | Lovro Ivanov 15 | 16 | ament_cmake 17 | 18 | rclcpp 19 | ur_client_library 20 | ur_robot_driver 21 | 22 | eigen 23 | yaml_cpp_vendor 24 | 25 | ament_cmake_gmock 26 | ament_cmake_gtest 27 | ament_lint_auto 28 | ament_lint_common 29 | 30 | 31 | ament_cmake 32 | 33 | 34 | -------------------------------------------------------------------------------- /ur_calibration/src/calibration_consumer.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Created on behalf of Universal Robots A/S 3 | // Copyright 2019 FZI Forschungszentrum Informatik 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // 11 | // * Redistributions in binary form must reproduce the above copyright 12 | // notice, this list of conditions and the following disclaimer in the 13 | // documentation and/or other materials provided with the distribution. 14 | // 15 | // * Neither the name of the {copyright_holder} nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | // POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // -- END LICENSE BLOCK ------------------------------------------------ 32 | 33 | //---------------------------------------------------------------------- 34 | /*!\file 35 | * 36 | * \author Felix Exner exner@fzi.de 37 | * \date 2019-05-28 38 | * \author Lovro Ivanov lovro.ivanov@gmail.com 39 | * \date 2021-09-22 40 | * 41 | */ 42 | //---------------------------------------------------------------------- 43 | 44 | #include "ur_calibration/calibration_consumer.hpp" 45 | 46 | #include 47 | 48 | namespace ur_calibration 49 | { 50 | CalibrationConsumer::CalibrationConsumer() : calibrated_(false) 51 | { 52 | } 53 | 54 | bool CalibrationConsumer::consume(std::shared_ptr product) 55 | { 56 | auto kin_info = std::dynamic_pointer_cast(product); 57 | if (kin_info != nullptr) { 58 | RCLCPP_INFO(rclcpp::get_logger("ur_calibration"), "%s", product->toString().c_str()); 59 | DHRobot my_robot; 60 | for (size_t i = 0; i < kin_info->dh_a_.size(); ++i) { 61 | my_robot.segments_.push_back( 62 | DHSegment(kin_info->dh_d_[i], kin_info->dh_a_[i], kin_info->dh_theta_[i], kin_info->dh_alpha_[i])); 63 | } 64 | Calibration calibration(my_robot); 65 | calibration.correctChain(); 66 | 67 | calibration_parameters_ = calibration.toYaml(); 68 | calibration_parameters_["kinematics"]["hash"] = kin_info->toHash(); 69 | calibrated_ = true; 70 | } 71 | return true; 72 | } 73 | 74 | YAML::Node CalibrationConsumer::getCalibrationParameters() const 75 | { 76 | if (!calibrated_) { 77 | throw(std::runtime_error("Cannot get calibration, as no calibration data received yet")); 78 | } 79 | return calibration_parameters_; 80 | } 81 | } // namespace ur_calibration 82 | -------------------------------------------------------------------------------- /ur_controllers/README.md: -------------------------------------------------------------------------------- 1 | # ur_controllers 2 | 3 | This package contains controllers and hardware interface for `ros2_control` that are special to the UR 4 | robot family. Currently this contains 5 | 6 | * A **speed_scaling_interface** to read the value of the current speed scaling into controllers. 7 | * A **scaled_joint_command_interface** that provides access to joint values and commands in 8 | combination with the speed scaling value. 9 | * A **speed_scaling_state_controller** that publishes the current execution speed as reported by 10 | the robot to a topic interface. Values are floating points between 0 and 1. 11 | * A **scaled_joint_trajectory_controller** that is similar to the *joint_trajectory_controller*, 12 | but it uses the speed scaling reported by the robot to reduce progress in the trajectory. 13 | 14 | For more details please see [doc/index.rst](doc/index.rst) 15 | -------------------------------------------------------------------------------- /ur_controllers/controller_plugins.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | This controller publishes the readings of all available speed scaling factors. 5 | 6 | 7 | 8 | 9 | Scaled position-based joint trajectory controller. 10 | 11 | 12 | 13 | 14 | This controller publishes the Tool IO. 15 | 16 | 17 | 18 | 19 | Controller to use UR's force_mode. 20 | 21 | 22 | 23 | 24 | This controller handles the activation of the freedrive mode. 25 | 26 | 27 | 28 | 29 | This controller forwards a joint-based trajectory to the robot controller for interpolation. 30 | 31 | 32 | 33 | 34 | Controller used to get and change the configuration of the robot 35 | 36 | 37 | 38 | 39 | Controller to use the tool contact functionality of the robot. 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ur_controllers/doc/traj_with_speed_scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_controllers/doc/traj_with_speed_scaling.png -------------------------------------------------------------------------------- /ur_controllers/doc/traj_without_speed_scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_controllers/doc/traj_without_speed_scaling.png -------------------------------------------------------------------------------- /ur_controllers/include/ur_controllers/scaled_joint_trajectory_controller.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019, FZI Forschungszentrum Informatik 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Marvin Große Besselmann grosse@fzi.de 33 | * \date 2021-02-18 34 | * 35 | */ 36 | //---------------------------------------------------------------------- 37 | #ifndef UR_CONTROLLERS__SCALED_JOINT_TRAJECTORY_CONTROLLER_HPP_ 38 | #define UR_CONTROLLERS__SCALED_JOINT_TRAJECTORY_CONTROLLER_HPP_ 39 | 40 | #include 41 | #include 42 | #include 43 | #include "joint_trajectory_controller/joint_trajectory_controller.hpp" 44 | #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" 45 | #include "rclcpp/time.hpp" 46 | #include "rclcpp/duration.hpp" 47 | #include "ur_controllers/scaled_joint_trajectory_controller_parameters.hpp" 48 | 49 | namespace ur_controllers 50 | { 51 | class ScaledJointTrajectoryController : public joint_trajectory_controller::JointTrajectoryController 52 | { 53 | public: 54 | ScaledJointTrajectoryController() = default; 55 | ~ScaledJointTrajectoryController() override = default; 56 | 57 | controller_interface::InterfaceConfiguration state_interface_configuration() const override; 58 | 59 | controller_interface::CallbackReturn on_activate(const rclcpp_lifecycle::State& state) override; 60 | 61 | controller_interface::return_type update(const rclcpp::Time& time, const rclcpp::Duration& period) override; 62 | 63 | CallbackReturn on_init() override; 64 | 65 | private: 66 | std::atomic scaling_factor_{ 1.0 }; 67 | 68 | std::optional> scaling_state_interface_ = 69 | std::nullopt; 70 | 71 | std::shared_ptr scaled_param_listener_; 72 | scaled_joint_trajectory_controller::Params scaled_params_; 73 | 74 | // Private methods copied from Upstream JTC 75 | void update_pids(); 76 | 77 | /** 78 | * @brief Assigns the values from a trajectory point interface to a joint interface. 79 | * 80 | * @tparam T The type of the joint interface. 81 | * @param[out] joint_interface The reference_wrapper to assign the values to 82 | * @param[in] trajectory_point_interface Containing the values to assign. 83 | * @todo: Use auto in parameter declaration with c++20 84 | */ 85 | template 86 | bool assign_interface_from_point(const T& joint_interface, const std::vector& trajectory_point_interface) 87 | { 88 | bool success = true; 89 | for (size_t index = 0; index < num_cmd_joints_; ++index) { 90 | success &= joint_interface[index].get().set_value(trajectory_point_interface[map_cmd_to_joints_[index]]); 91 | } 92 | return success; 93 | } 94 | }; 95 | } // namespace ur_controllers 96 | 97 | #endif // UR_CONTROLLERS__SCALED_JOINT_TRAJECTORY_CONTROLLER_HPP_ 98 | -------------------------------------------------------------------------------- /ur_controllers/include/ur_controllers/speed_scaling_state_broadcaster.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019, FZI Forschungszentrum Informatik 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Marvin Große Besselmann grosse@fzi.de 33 | * \date 2021-02-10 34 | * 35 | */ 36 | //---------------------------------------------------------------------- 37 | 38 | #ifndef UR_CONTROLLERS__SPEED_SCALING_STATE_BROADCASTER_HPP_ 39 | #define UR_CONTROLLERS__SPEED_SCALING_STATE_BROADCASTER_HPP_ 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | #include "controller_interface/controller_interface.hpp" 46 | #include "rclcpp_lifecycle/lifecycle_publisher.hpp" 47 | #include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp" 48 | #include "rclcpp/time.hpp" 49 | #include "rclcpp/duration.hpp" 50 | #include "std_msgs/msg/float64.hpp" 51 | #include "ur_controllers/speed_scaling_state_broadcaster_parameters.hpp" 52 | 53 | namespace ur_controllers 54 | { 55 | class SpeedScalingStateBroadcaster : public controller_interface::ControllerInterface 56 | { 57 | public: 58 | SpeedScalingStateBroadcaster(); 59 | 60 | controller_interface::InterfaceConfiguration command_interface_configuration() const override; 61 | 62 | controller_interface::InterfaceConfiguration state_interface_configuration() const override; 63 | 64 | controller_interface::return_type update(const rclcpp::Time& time, const rclcpp::Duration& period) override; 65 | 66 | controller_interface::CallbackReturn on_configure(const rclcpp_lifecycle::State& previous_state) override; 67 | 68 | controller_interface::CallbackReturn on_activate(const rclcpp_lifecycle::State& previous_state) override; 69 | 70 | controller_interface::CallbackReturn on_deactivate(const rclcpp_lifecycle::State& previous_state) override; 71 | 72 | controller_interface::CallbackReturn on_init() override; 73 | 74 | protected: 75 | std::vector sensor_names_; 76 | double publish_rate_; 77 | 78 | std::shared_ptr> speed_scaling_state_publisher_; 79 | std_msgs::msg::Float64 speed_scaling_state_msg_; 80 | 81 | // Parameters from ROS for SpeedScalingStateBroadcaster 82 | std::shared_ptr param_listener_; 83 | speed_scaling_state_broadcaster::Params params_; 84 | }; 85 | } // namespace ur_controllers 86 | #endif // UR_CONTROLLERS__SPEED_SCALING_STATE_BROADCASTER_HPP_ 87 | -------------------------------------------------------------------------------- /ur_controllers/include/ur_controllers/ur_configuration_controller.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Jacob Larsen jala@universal-robots.com 33 | * \date 2024-07-11 34 | * 35 | * 36 | * 37 | * 38 | */ 39 | //---------------------------------------------------------------------- 40 | 41 | #ifndef UR_CONTROLLERS__UR_CONFIGURATION_CONTROLLER_HPP_ 42 | #define UR_CONTROLLERS__UR_CONFIGURATION_CONTROLLER_HPP_ 43 | 44 | #include 45 | 46 | #include 47 | #include 48 | 49 | #include "ur_msgs/srv/get_robot_software_version.hpp" 50 | #include "ur_controllers/ur_configuration_controller_parameters.hpp" 51 | 52 | namespace ur_controllers 53 | { 54 | 55 | // Struct to hold version information 56 | struct VersionInformation 57 | { 58 | uint32_t major = 0, minor = 0, build = 0, bugfix = 0; 59 | }; 60 | 61 | // Enum for indexing into state interfaces. 62 | enum StateInterfaces 63 | { 64 | ROBOT_VERSION_MAJOR = 0, 65 | ROBOT_VERSION_MINOR = 1, 66 | ROBOT_VERSION_BUILD = 2, 67 | ROBOT_VERSION_BUGFIX = 3, 68 | }; 69 | 70 | class URConfigurationController : public controller_interface::ControllerInterface 71 | { 72 | public: 73 | controller_interface::InterfaceConfiguration command_interface_configuration() const override; 74 | 75 | controller_interface::InterfaceConfiguration state_interface_configuration() const override; 76 | 77 | controller_interface::return_type update(const rclcpp::Time& time, const rclcpp::Duration& period) override; 78 | 79 | CallbackReturn on_configure(const rclcpp_lifecycle::State& previous_state) override; 80 | 81 | CallbackReturn on_activate(const rclcpp_lifecycle::State& previous_state) override; 82 | 83 | CallbackReturn on_deactivate(const rclcpp_lifecycle::State& previous_state) override; 84 | 85 | CallbackReturn on_init() override; 86 | 87 | private: 88 | realtime_tools::RealtimeBox> robot_software_version_{ 89 | std::make_shared() 90 | }; 91 | 92 | rclcpp::Service::SharedPtr get_robot_software_version_srv_; 93 | 94 | bool getRobotSoftwareVersion(ur_msgs::srv::GetRobotSoftwareVersion::Request::SharedPtr req, 95 | ur_msgs::srv::GetRobotSoftwareVersion::Response::SharedPtr resp); 96 | 97 | std::shared_ptr param_listener_; 98 | ur_configuration_controller::Params params_; 99 | }; 100 | } // namespace ur_controllers 101 | 102 | #endif // UR_CONTROLLERS__UR_CONFIGURATION_CONTROLLER_HPP_ 103 | -------------------------------------------------------------------------------- /ur_controllers/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ur_controllers 5 | 4.0.1 6 | Provides controllers that use the speed scaling interface of Universal Robots. 7 | 8 | Felix Exner 9 | Rune Søe-Knudsen 10 | Universal Robots A/S 11 | 12 | BSD-3-Clause 13 | 14 | https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/issues 15 | https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver 16 | 17 | Denis Stogl 18 | Robert Wilbrandt 19 | Marvin Große Besselmann 20 | Lovro Ivanov 21 | Andy Zelenak 22 | Vincenzo Di Pentima 23 | 24 | ament_cmake 25 | 26 | angles 27 | controller_interface 28 | generate_parameter_library 29 | geometry_msgs 30 | hardware_interface 31 | joint_trajectory_controller 32 | lifecycle_msgs 33 | pluginlib 34 | rclcpp_lifecycle 35 | rcutils 36 | realtime_tools 37 | std_msgs 38 | std_srvs 39 | tf2_geometry_msgs 40 | tf2_ros 41 | ur_dashboard_msgs 42 | ur_msgs 43 | control_msgs 44 | trajectory_msgs 45 | action_msgs 46 | 47 | controller_manager 48 | ros2_control_test_assets 49 | hardware_interface_testing 50 | 51 | 52 | ament_cmake 53 | 54 | 55 | -------------------------------------------------------------------------------- /ur_controllers/src/force_mode_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | force_mode_controller: 3 | tf_prefix: { 4 | type: string, 5 | default_value: "", 6 | description: "Urdf prefix of the corresponding arm" 7 | } 8 | check_io_successful_retries: { 9 | type: int, 10 | default_value: 10, 11 | description: "Amount of retries for checking if setting force_mode was successful" 12 | } 13 | -------------------------------------------------------------------------------- /ur_controllers/src/freedrive_mode_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | freedrive_mode_controller: 3 | tf_prefix: { 4 | type: string, 5 | default_value: "", 6 | description: "Urdf prefix of the corresponding arm" 7 | } 8 | inactive_timeout: { 9 | type: int, 10 | default_value: 1, 11 | description: "Time interval (in seconds) of message inactivity after which freedrive is deactivated" 12 | } 13 | check_io_successful_retries: { 14 | type: int, 15 | default_value: 10, 16 | description: "Amount of retries for checking if setting force_mode was successful" 17 | } 18 | -------------------------------------------------------------------------------- /ur_controllers/src/gpio_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | gpio_controller: 2 | tf_prefix: { 3 | type: string, 4 | default_value: "", 5 | description: "Urdf prefix of the corresponding arm" 6 | } 7 | check_io_successfull_retries: { 8 | type: int, 9 | default_value: 10, 10 | description: "Amount of retries for checking if the selected gpio was set successfully" 11 | } 12 | -------------------------------------------------------------------------------- /ur_controllers/src/passthrough_trajectory_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | passthrough_trajectory_controller: 3 | speed_scaling_interface_name: { 4 | type: string, 5 | default_value: "speed_scaling/speed_scaling_factor", 6 | description: "Fully qualified name of the speed scaling interface name" 7 | } 8 | tf_prefix: { 9 | type: string, 10 | default_value: "", 11 | description: "Urdf prefix of the corresponding arm" 12 | } 13 | joints: { 14 | type: string_array, 15 | default_value: [], 16 | description: "Joint names to claim and listen to", 17 | read_only: true, 18 | validation: { 19 | unique<>: null, 20 | } 21 | } 22 | state_interfaces: { 23 | type: string_array, 24 | default_value: [], 25 | description: "State interfaces provided by the hardware for all joints.", 26 | read_only: true, 27 | validation: { 28 | unique<>: null, 29 | subset_of<>: [["position", "velocity", "acceleration"]], 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ur_controllers/src/scaled_joint_trajectory_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | scaled_joint_trajectory_controller: 2 | speed_scaling_interface_name: { 3 | type: string, 4 | default_value: "speed_scaling/speed_scaling_factor", 5 | description: "Fully qualified name of the speed scaling interface name" 6 | } 7 | -------------------------------------------------------------------------------- /ur_controllers/src/speed_scaling_state_broadcaster_parameters.yaml: -------------------------------------------------------------------------------- 1 | speed_scaling_state_broadcaster: 2 | tf_prefix: { 3 | type: string, 4 | default_value: "", 5 | description: "Urdf prefix of the corresponding arm" 6 | } 7 | state_publish_rate: { 8 | type: double, 9 | default_value: 100.0, 10 | description: "Rate at which the speedscaling state will be published." 11 | } 12 | -------------------------------------------------------------------------------- /ur_controllers/src/tool_contact_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | tool_contact_controller: 2 | tf_prefix: { 3 | type: string, 4 | default_value: "", 5 | description: "Urdf prefix of the corresponding arm" 6 | } 7 | action_monitor_rate: { 8 | type: double, 9 | default_value: 20.0, 10 | description: "The rate at which the action should be monitored in Hz." 11 | } 12 | -------------------------------------------------------------------------------- /ur_controllers/src/ur_configuration_controller_parameters.yaml: -------------------------------------------------------------------------------- 1 | ur_configuration_controller: 2 | tf_prefix: { 3 | type: string, 4 | default_value: "", 5 | description: "URDF prefix of the corresponding arm" 6 | } 7 | -------------------------------------------------------------------------------- /ur_controllers/test/force_mode_controller_params.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | force_mode_controller: 3 | ros__parameters: 4 | tf_prefix: "" 5 | damping: 0.025 6 | gain_scaling: 0.5 7 | check_io_successful_retries: 10 8 | -------------------------------------------------------------------------------- /ur_controllers/test/freedrive_mode_controller_params.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | freedrive_mode_controller: 3 | ros__parameters: 4 | tf_prefix: "" 5 | inactive_timeout: 10 6 | -------------------------------------------------------------------------------- /ur_controllers/test/test_load_force_mode_controller.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #include 30 | #include "controller_manager/controller_manager.hpp" 31 | #include "rclcpp/executor.hpp" 32 | #include "rclcpp/executors/single_threaded_executor.hpp" 33 | #include "rclcpp/utilities.hpp" 34 | #include "ros2_control_test_assets/descriptions.hpp" 35 | 36 | TEST(TestLoadForceModeController, load_controller) 37 | { 38 | std::shared_ptr executor = std::make_shared(); 39 | 40 | controller_manager::ControllerManager cm{ executor, ros2_control_test_assets::minimal_robot_urdf, true, 41 | "test_controller_manager" }; 42 | 43 | const std::string test_file_path = std::string{ TEST_FILES_DIRECTORY } + "/force_mode_controller_params.yaml"; 44 | cm.set_parameter({ "test_force_mode_controller.params_file", test_file_path }); 45 | 46 | cm.set_parameter({ "test_force_mode_controller.type", "ur_controllers/ForceModeController" }); 47 | 48 | ASSERT_NE(cm.load_controller("test_force_mode_controller"), nullptr); 49 | } 50 | 51 | int main(int argc, char* argv[]) 52 | { 53 | ::testing::InitGoogleMock(&argc, argv); 54 | rclcpp::init(argc, argv); 55 | 56 | int result = RUN_ALL_TESTS(); 57 | rclcpp::shutdown(); 58 | 59 | return result; 60 | } 61 | -------------------------------------------------------------------------------- /ur_controllers/test/test_load_freedrive_mode_controller.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024, Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #include 30 | #include "controller_manager/controller_manager.hpp" 31 | #include "rclcpp/executor.hpp" 32 | #include "rclcpp/executors/single_threaded_executor.hpp" 33 | #include "rclcpp/utilities.hpp" 34 | #include "ros2_control_test_assets/descriptions.hpp" 35 | 36 | TEST(TestLoadFreedriveModeController, load_controller) 37 | { 38 | std::shared_ptr executor = std::make_shared(); 39 | 40 | controller_manager::ControllerManager cm{ executor, ros2_control_test_assets::minimal_robot_urdf, true, 41 | "test_controller_manager" }; 42 | 43 | const std::string test_file_path = std::string{ TEST_FILES_DIRECTORY } + "/freedrive_mode_controller_params.yaml"; 44 | cm.set_parameter({ "test_freedrive_mode_controller.params_file", test_file_path }); 45 | 46 | cm.set_parameter({ "test_freedrive_mode_controller.type", "ur_controllers/FreedriveModeController" }); 47 | 48 | ASSERT_NE(cm.load_controller("test_freedrive_mode_controller"), nullptr); 49 | } 50 | 51 | int main(int argc, char* argv[]) 52 | { 53 | ::testing::InitGoogleMock(&argc, argv); 54 | rclcpp::init(argc, argv); 55 | 56 | int result = RUN_ALL_TESTS(); 57 | rclcpp::shutdown(); 58 | 59 | return result; 60 | } 61 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package ur_dashboard_msgs 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 4.0.1 (2025-05-28) 6 | ------------------ 7 | 8 | 4.0.0 (2025-05-20) 9 | ------------------ 10 | 11 | 3.2.1 (2025-04-11) 12 | ------------------ 13 | 14 | 3.2.0 (2025-04-10) 15 | ------------------ 16 | 17 | 3.1.1 (2025-03-17) 18 | ------------------ 19 | 20 | 3.1.0 (2025-03-05) 21 | ------------------ 22 | * Port robot_state_helper to ROS2 (`#933 `_) 23 | * Contributors: Felix Durchdewald 24 | 25 | 3.0.2 (2025-01-21) 26 | ------------------ 27 | 28 | 3.0.1 (2024-12-30) 29 | ------------------ 30 | 31 | 3.0.0 (2024-12-18) 32 | ------------------ 33 | * Update package maintainers (`#1203 `_) 34 | * Contributors: Felix Exner 35 | 36 | 2.4.13 (2024-10-28) 37 | ------------------- 38 | 39 | 2.4.12 (2024-10-14) 40 | ------------------- 41 | 42 | 2.4.11 (2024-10-10) 43 | ------------------- 44 | 45 | 2.4.10 (2024-09-11) 46 | ------------------- 47 | * Update maintainers team (`#1088 `_) 48 | * Contributors: Vincenzo Di Pentima 49 | 50 | 2.4.9 (2024-08-09) 51 | ------------------ 52 | 53 | 2.4.8 (2024-07-01) 54 | ------------------ 55 | 56 | 2.4.7 (2024-06-19) 57 | ------------------ 58 | 59 | 2.4.6 (2024-06-17) 60 | ------------------ 61 | 62 | 2.4.5 (2024-05-16) 63 | ------------------ 64 | 65 | 2.4.4 (2024-04-04) 66 | ------------------ 67 | 68 | 2.4.3 (2024-02-02) 69 | ------------------ 70 | 71 | 2.4.2 (2023-11-23) 72 | ------------------ 73 | 74 | 2.4.1 (2023-09-21) 75 | ------------------ 76 | 77 | 2.4.0 (2023-08-28) 78 | ------------------ 79 | 80 | 2.3.2 (2023-06-02) 81 | ------------------ 82 | 83 | 2.3.1 (2023-03-16) 84 | ------------------ 85 | 86 | 2.3.0 (2023-03-02) 87 | ------------------ 88 | 89 | 2.2.4 (2022-10-07) 90 | ------------------ 91 | 92 | 2.2.3 (2022-07-27) 93 | ------------------ 94 | 95 | 2.2.2 (2022-07-19) 96 | ------------------ 97 | * Made sure all past maintainers are listed as authors (`#429 `_) 98 | * Contributors: Felix Exner 99 | 100 | 2.2.1 (2022-06-27) 101 | ------------------ 102 | 103 | 2.2.0 (2022-06-20) 104 | ------------------ 105 | * Updated package maintainers 106 | * Update license to BSD-3-Clause (`#277 `_) 107 | * Review CI by correcting the configurations (`#71 `_) 108 | * Use GitHub Actions, use pre-commit formatting (`#56 `_) 109 | * Add XML schema to all ``package.xml`` files 110 | * Compile ur_dashboard_msgs for ROS2 111 | * Contributors: AndyZe, Denis Štogl, Felix Exner, John Morris, livanov93 112 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(ur_dashboard_msgs) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | find_package(rosidl_default_generators REQUIRED) 6 | find_package(action_msgs REQUIRED) 7 | find_package(builtin_interfaces REQUIRED) 8 | 9 | set(msg_files 10 | msg/ProgramState.msg 11 | msg/RobotMode.msg 12 | msg/SafetyMode.msg 13 | ) 14 | 15 | set(srv_files 16 | srv/AddToLog.srv 17 | srv/GetLoadedProgram.srv 18 | srv/GetProgramState.srv 19 | srv/GetRobotMode.srv 20 | srv/GetSafetyMode.srv 21 | srv/IsProgramRunning.srv 22 | srv/IsProgramSaved.srv 23 | srv/Load.srv 24 | srv/Popup.srv 25 | srv/RawRequest.srv 26 | ) 27 | 28 | set(action_files 29 | action/SetMode.action 30 | ) 31 | 32 | rosidl_generate_interfaces(${PROJECT_NAME} 33 | ${msg_files} 34 | ${srv_files} 35 | ${action_files} 36 | DEPENDENCIES 37 | action_msgs 38 | builtin_interfaces 39 | ) 40 | 41 | ament_export_dependencies(rosidl_default_runtime) 42 | 43 | ament_package() 44 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/action/SetMode.action: -------------------------------------------------------------------------------- 1 | # This action is for setting the robot into a desired mode (e.g. RUNNING) and safety mode into a 2 | # non-critical state (e.g. NORMAL or REDUCED), for example after a safety incident happened. 3 | 4 | # Target modes can be one of 5 | # - 3: ROBOT_MODE_POWER_OFF 6 | # - 5: ROBOT_MODE_IDLE 7 | # - 7: ROBOT_MODE_RUNNING 8 | int8 target_robot_mode 9 | 10 | # Stop program execution before restoring the target mode. Can be used together with 'play_program'. 11 | bool stop_program 12 | 13 | # Play the currently loaded program after target mode is reached.# 14 | # NOTE: Requesting mode RUNNING in combination with this will make the robot continue the motion it 15 | # was doing before. This might probably lead into the same problem (protective stop, EM-Stop due to 16 | # faulty motion, etc.) If you want to be safe, set the 'stop_program' flag below and manually play 17 | # the program after robot state is returned to normal. 18 | # This flag will only be used when requesting mode RUNNING 19 | bool play_program 20 | 21 | --- 22 | # result 23 | bool success 24 | string message 25 | --- 26 | # feedback 27 | int8 current_robot_mode 28 | int8 current_safety_mode 29 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/msg/ProgramState.msg: -------------------------------------------------------------------------------- 1 | string STOPPED=STOPPED 2 | string PLAYING=PLAYING 3 | string PAUSED=PAUSED 4 | 5 | string state 6 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/msg/RobotMode.msg: -------------------------------------------------------------------------------- 1 | int8 NO_CONTROLLER=-1 2 | int8 DISCONNECTED=0 3 | int8 CONFIRM_SAFETY=1 4 | int8 BOOTING=2 5 | int8 POWER_OFF=3 6 | int8 POWER_ON=4 7 | int8 IDLE=5 8 | int8 BACKDRIVE=6 9 | int8 RUNNING=7 10 | int8 UPDATING_FIRMWARE=8 11 | 12 | int8 mode 13 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/msg/SafetyMode.msg: -------------------------------------------------------------------------------- 1 | uint8 NORMAL=1 2 | uint8 REDUCED=2 3 | uint8 PROTECTIVE_STOP=3 4 | uint8 RECOVERY=4 5 | uint8 SAFEGUARD_STOP=5 6 | uint8 SYSTEM_EMERGENCY_STOP=6 7 | uint8 ROBOT_EMERGENCY_STOP=7 8 | uint8 VIOLATION=8 9 | uint8 FAULT=9 10 | uint8 VALIDATE_JOINT_ID=10 11 | uint8 UNDEFINED_SAFETY_MODE=11 12 | uint8 AUTOMATIC_MODE_SAFEGUARD_STOP=12 13 | uint8 SYSTEM_THREE_POSITION_ENABLING_STOP=13 14 | 15 | uint8 mode 16 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ur_dashboard_msgs 5 | 4.0.1 6 | Messages around the UR Dashboard server. 7 | 8 | Felix Exner 9 | Rune Søe-Knudsen 10 | Universal Robots A/S 11 | 12 | BSD-3-Clause 13 | 14 | https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/issues 15 | https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver 16 | 17 | Robert Wilbrandt 18 | Denis Stogl 19 | Lovro Ivanov 20 | Andy Zelenak 21 | 22 | ament_cmake 23 | 24 | rosidl_default_generators 25 | 26 | action_msgs 27 | 28 | rosidl_default_runtime 29 | 30 | rosidl_interface_packages 31 | 32 | 33 | ament_cmake 34 | 35 | 36 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/AddToLog.srv: -------------------------------------------------------------------------------- 1 | string message 2 | --- 3 | string answer 4 | bool success 5 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/GetLoadedProgram.srv: -------------------------------------------------------------------------------- 1 | --- 2 | string answer 3 | string program_name 4 | bool success 5 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/GetProgramState.srv: -------------------------------------------------------------------------------- 1 | --- 2 | ProgramState state 3 | string program_name 4 | string answer 5 | bool success 6 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/GetRobotMode.srv: -------------------------------------------------------------------------------- 1 | --- 2 | RobotMode robot_mode 3 | string answer 4 | bool success 5 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/GetSafetyMode.srv: -------------------------------------------------------------------------------- 1 | --- 2 | SafetyMode safety_mode 3 | string answer 4 | bool success 5 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/IsProgramRunning.srv: -------------------------------------------------------------------------------- 1 | --- 2 | string answer 3 | bool program_running # is a program running? 4 | bool success # Did the dashboard server call succeed? 5 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/IsProgramSaved.srv: -------------------------------------------------------------------------------- 1 | --- 2 | string answer 3 | string program_name 4 | bool program_saved # is the current program saved? 5 | bool success # Did the dashboard server call succeed? 6 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/Load.srv: -------------------------------------------------------------------------------- 1 | # Service to load programs or installations 2 | string filename 3 | --- 4 | string answer 5 | bool success 6 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/Popup.srv: -------------------------------------------------------------------------------- 1 | string message 2 | --- 3 | string answer 4 | bool success 5 | -------------------------------------------------------------------------------- /ur_dashboard_msgs/srv/RawRequest.srv: -------------------------------------------------------------------------------- 1 | # This service is there to support any dashboard query not explicitly supported 2 | string query 3 | --- 4 | string answer 5 | -------------------------------------------------------------------------------- /ur_moveit_config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(ur_moveit_config) 3 | 4 | find_package(ament_cmake REQUIRED) 5 | 6 | ament_package() 7 | 8 | install( 9 | DIRECTORY config launch srdf 10 | DESTINATION share/${PROJECT_NAME} 11 | ) 12 | -------------------------------------------------------------------------------- /ur_moveit_config/config/chomp_planning.yaml: -------------------------------------------------------------------------------- 1 | planning_plugins: 2 | - chomp_interface/CHOMPPlanner 3 | enable_failure_recovery: true 4 | # The order of the elements in the adapter corresponds to the order they are processed by the motion planning pipeline. 5 | request_adapters: 6 | - default_planning_request_adapters/ResolveConstraintFrames 7 | - default_planning_request_adapters/ValidateWorkspaceBounds 8 | - default_planning_request_adapters/CheckStartStateBounds 9 | - default_planning_request_adapters/CheckStartStateCollision 10 | response_adapters: 11 | - default_planning_response_adapters/AddTimeOptimalParameterization 12 | - default_planning_response_adapters/ValidateSolution 13 | - default_planning_response_adapters/DisplayMotionPath 14 | 15 | ridge_factor: 0.01 16 | -------------------------------------------------------------------------------- /ur_moveit_config/config/joint_limits.yaml: -------------------------------------------------------------------------------- 1 | # These limits are used by MoveIt and augment/override the definitions in ur_description. 2 | # 3 | # While the robot does not inherently have any limits on joint accelerations (only on torques), 4 | # MoveIt needs them for time parametrization. They were chosen conservatively to work in most use 5 | # cases. For specific applications, higher values might lead to better execution performance. 6 | 7 | joint_limits: 8 | shoulder_pan_joint: 9 | has_acceleration_limits: true 10 | max_acceleration: 5.0 11 | shoulder_lift_joint: 12 | has_acceleration_limits: true 13 | max_acceleration: 5.0 14 | elbow_joint: 15 | has_acceleration_limits: true 16 | max_acceleration: 5.0 17 | wrist_1_joint: 18 | has_acceleration_limits: true 19 | max_acceleration: 5.0 20 | wrist_2_joint: 21 | has_acceleration_limits: true 22 | max_acceleration: 5.0 23 | wrist_3_joint: 24 | has_acceleration_limits: true 25 | max_acceleration: 5.0 26 | -------------------------------------------------------------------------------- /ur_moveit_config/config/kinematics.yaml: -------------------------------------------------------------------------------- 1 | ur_manipulator: 2 | kinematics_solver: kdl_kinematics_plugin/KDLKinematicsPlugin 3 | kinematics_solver_search_resolution: 0.0050000000000000001 4 | kinematics_solver_timeout: 0.0050000000000000001 5 | -------------------------------------------------------------------------------- /ur_moveit_config/config/moveit_controllers.yaml: -------------------------------------------------------------------------------- 1 | # MoveIt uses this configuration for controller management 2 | moveit_controller_manager: moveit_simple_controller_manager/MoveItSimpleControllerManager 3 | 4 | trajectory_execution: 5 | allowed_execution_duration_scaling: 1.2 6 | allowed_goal_duration_margin: 0.5 7 | allowed_start_tolerance: 0.01 8 | execution_duration_monitoring: false # May lead to unexpectedly aborted goals with scaled JTC 9 | 10 | moveit_simple_controller_manager: 11 | controller_names: 12 | - scaled_joint_trajectory_controller 13 | - joint_trajectory_controller 14 | 15 | scaled_joint_trajectory_controller: 16 | action_ns: follow_joint_trajectory 17 | type: FollowJointTrajectory 18 | default: true 19 | joints: 20 | - shoulder_pan_joint 21 | - shoulder_lift_joint 22 | - elbow_joint 23 | - wrist_1_joint 24 | - wrist_2_joint 25 | - wrist_3_joint 26 | 27 | 28 | joint_trajectory_controller: 29 | action_ns: follow_joint_trajectory 30 | type: FollowJointTrajectory 31 | default: false 32 | joints: 33 | - shoulder_pan_joint 34 | - shoulder_lift_joint 35 | - elbow_joint 36 | - wrist_1_joint 37 | - wrist_2_joint 38 | - wrist_3_joint 39 | -------------------------------------------------------------------------------- /ur_moveit_config/config/ompl_planning.yaml: -------------------------------------------------------------------------------- 1 | planning_plugins: 2 | - ompl_interface/OMPLPlanner 3 | # The order of the elements in the adapter corresponds to the order they are processed by the motion planning pipeline. 4 | request_adapters: 5 | - default_planning_request_adapters/ResolveConstraintFrames 6 | - default_planning_request_adapters/ValidateWorkspaceBounds 7 | - default_planning_request_adapters/CheckStartStateBounds 8 | - default_planning_request_adapters/CheckStartStateCollision 9 | response_adapters: 10 | - default_planning_response_adapters/AddTimeOptimalParameterization 11 | - default_planning_response_adapters/ValidateSolution 12 | - default_planning_response_adapters/DisplayMotionPath 13 | -------------------------------------------------------------------------------- /ur_moveit_config/config/pilz_cartesian_limits.yaml: -------------------------------------------------------------------------------- 1 | # Limits for the Pilz planner 2 | cartesian_limits: 3 | max_trans_vel: 1.0 4 | max_trans_acc: 2.25 5 | max_trans_dec: -5.0 6 | max_rot_vel: 1.57 7 | -------------------------------------------------------------------------------- /ur_moveit_config/config/pilz_industrial_motion_planner_planning.yaml: -------------------------------------------------------------------------------- 1 | planning_plugins: 2 | - pilz_industrial_motion_planner/CommandPlanner 3 | default_planner_config: PTP 4 | request_adapters: 5 | - default_planning_request_adapters/ResolveConstraintFrames 6 | - default_planning_request_adapters/ValidateWorkspaceBounds 7 | - default_planning_request_adapters/CheckStartStateBounds 8 | - default_planning_request_adapters/CheckStartStateCollision 9 | response_adapters: 10 | - default_planning_response_adapters/ValidateSolution 11 | - default_planning_response_adapters/DisplayMotionPath 12 | capabilities: >- 13 | pilz_industrial_motion_planner/MoveGroupSequenceAction 14 | pilz_industrial_motion_planner/MoveGroupSequenceService 15 | -------------------------------------------------------------------------------- /ur_moveit_config/doc/index.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_moveit_config/doc/index.rst 2 | 3 | .. _ur_moveit_config: 4 | 5 | ================ 6 | ur_moveit_config 7 | ================ 8 | 9 | This package contains an **example** MoveIt! configuration for Universal Robots arms. Since the 10 | default description contains only the arm, this MoveIt! configuration package also only contains the 11 | arm without any objects around it. 12 | 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 13 | *scenario_moveit_config* package from that description as explained in the :ref:`Custom workcell 14 | tutorial `. 15 | 16 | Usage 17 | ----- 18 | 19 | With a running driver (real hardware, URSim or mocked hardware), simply start the MoveIt! 20 | interaction using 21 | 22 | .. code-block:: 23 | 24 | ros2 launch ur_moveit_config ur_moveit.launch.py ur_type:=ur5e launch_rviz:=true 25 | 26 | Now you should be able to use the MoveIt Plugin in rviz2 to plan and execute trajectories with the 27 | robot as explained `here `_. 28 | 29 | .. note:: 30 | The MoveIt configuration provided here has Trajectory Execution Monitoring (TEM) *disabled*, as the 31 | Scaled Joint Trajectory Controller may cause trajectories to be executed at a lower velocity 32 | than they were originally planned by MoveIt. MoveIt's TEM however is not aware of this 33 | deliberate slow-down due to scaling and will in most cases unnecessarily (and unexpectedly) 34 | abort goals. 35 | 36 | Until this incompatibility is resolved, the default value for ``execution_duration_monitoring`` 37 | is set to ``false``. Users who wish to temporarily (re)enable TEM at runtime (for use with 38 | other, non-scaling controllers) can do so using the ROS 2 parameter services supported by 39 | MoveIt. 40 | 41 | .. literalinclude:: ../config/moveit_controllers.yaml 42 | :language: yaml 43 | :start-at: trajectory_execution: 44 | :end-at: execution_duration_monitoring 45 | :caption: moveit_controllers.yaml 46 | -------------------------------------------------------------------------------- /ur_moveit_config/doc/migration/jazzy.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_moveit_config/doc/migration/jazzy.rst 2 | 3 | ur_moveit_config 4 | ^^^^^^^^^^^^^^^^ 5 | 6 | Restructuring for moveit_configs_builder compatibility 7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | 9 | Many config files have been either renamed or rewritten in order to allow this package to use the moveit_configs_builder. In this way, it becomes a good basic example for packages of this kind: from this perspective, aiming for simplicity and not for completeness, it consequently avoids the implementation of all the possible features offered by the configs builder, e.g. the multiple IK solutions available, which are left to the users to be explored. 10 | 11 | Robot description and semantic description updates 12 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 | 14 | Differently from before, the package allows to load the description from the robot_state_publisher's topic, also adding a "lazy" starting possibility of the move_group. In fact, the launcher waits 10 seconds for the description topic to be available, giving the user enough time to launch the robot_state_publisher. 15 | 16 | In addition to that, now the launcher also allows the move_group to publish the semantic description. Enabled by the argument ``publish_robot_description_semantic``, it improves the reusability of the launch file: including the ``ur_moveit.launch.py`` in a custom launch file and then launching the MoveGroupInterface, allows users to do avoid manual definition for the srdf, since the MoveGroupInterface will pull such info from the move_group node. 17 | 18 | 19 | Removed tf_prefix support 20 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 21 | 22 | Switching to the moveit_configs_builder doesn't allow the ``tf_prefix`` option to work anymore, hence motivating its removal from this package. 23 | This is due to the presence of config files containing information about joints, like ``joint_limits.yaml``: since they can't handle argument substitution during loading inside the configs builder, the ``tf_prefix`` can't be specified for them. 24 | If necessary, this is left to be handled by the user through a definition for it in a custom moveit_config package. 25 | -------------------------------------------------------------------------------- /ur_moveit_config/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ur_moveit_config 5 | 4.0.1 6 | 7 | An example package with MoveIt2 configurations for UR robots. 8 | 9 | Felix Exner 10 | Rune Søe-Knudsen 11 | Universal Robots A/S 12 | 13 | Apache2.0 14 | 15 | Robert Wilbrandt 16 | Denis Stogl 17 | Lovro Ivanov 18 | Andy Zelenak 19 | Vincenzo Di Pentima 20 | 21 | ament_cmake 22 | 23 | 24 | moveit_configs_utils 25 | moveit_kinematics 26 | moveit_planners 27 | moveit_planners_chomp 28 | moveit_ros_move_group 29 | moveit_ros_visualization 30 | moveit_servo 31 | moveit_simple_controller_manager 32 | ur_description 33 | warehouse_ros_sqlite 34 | xacro 35 | 36 | 37 | ament_cmake 38 | 39 | 40 | -------------------------------------------------------------------------------- /ur_moveit_config/srdf/ur.srdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ur_moveit_config/srdf/ur_macro.srdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /ur_robot_driver/README.md: -------------------------------------------------------------------------------- 1 | # ur_robot_driver 2 | 3 | This package contains the actual driver for UR robots. It is part of the *universal_robots_driver* 4 | repository and requires other packages from that repository. Also, see the [main repository's 5 | README](../README.md) for information on how to install and startup this driver. 6 | 7 | 8 | ## Technical details 9 | The following image shows a very coarse overview of the driver's architecture. 10 | 11 | ![Architecture overview](doc/architecture_coarse.svg "Architecture overview") 12 | 13 | Upon connection to the primary interface the robot sends version and calibration information which 14 | is consumed by the *calibration_check*. If the calibration reported by the robot doesn't match the 15 | one configured (See [calibration guide](../ur_calibration/README.md)) an error will be printed to Roslog. 16 | 17 | Real-time data from the robot is read through the RTDE interface. This is done automatically as soon 18 | as a connection to the robot could be established. Thus joint states and IO data will be immediately 19 | available. 20 | 21 | To actually control the robot, a program node from the **External Control** URCap must be running on 22 | the robot interpreting commands sent from an external source. When this program is not running, no 23 | controllers moving the robot around will be available. Please see the [initial setup 24 | guide](doc/installation/robot_setup.rst) on how to install and start this on the robot. 25 | 26 | The URScript that will be running on the robot is requested by the **External Control** program node 27 | from the remote ROS PC. The robot *ur_control.launch* file has a parameter called `urscript_file` to 28 | select a different program than the default one that will be sent as a response to a program 29 | request. 30 | 31 | **Custom script snippets** can be sent to the robot on a topic basis. By default, they will 32 | interrupt other programs (such as the one controlling the robot). For a certain subset of functions, 33 | it is however possible to send them as secondary programs. See [UR 34 | documentation](https://www.universal-robots.com/articles/ur/programming/secondary-program/) 35 | on details. 36 |
37 | **Note to e-Series users:** 38 | The robot won't accept script code from a remote source unless the robot is put into 39 | *remote_control-mode*. However, if put into *remote_control-mode*, the program containing the 40 | **External Control** program node can't be started from the panel. 41 | For this purpose, please use the **dashboard** services to load, start and stop the main program 42 | running on the robot. See the [Dashboard client documentation](doc/dashboard_client.rst) for details on the 43 | dashboard services. 44 | 45 | For using the **tool communication interface** on e-Series robots, a `socat` script is prepared to 46 | forward the robot's tool communication interface to a local device on the ROS PC. See [the tool 47 | communication setup guide](doc/setup_tool_communication.rst) for details. 48 | 49 | This driver is using [`ros2_control`](https://control.ros.org) for any control statements. 50 | Therefore, it can be used with all position-based controllers available in `ros2_control`. However, we 51 | recommend using the controllers from the `ur_controllers` package. See it's 52 | [documentation](../ur_controllers/README.md) for details. **Note: Speed scaling support will only be 53 | available using the controllers from `ur_controllers`** 54 | 55 | ## A note about modes 56 | The term **mode** is used in different meanings inside this driver. See [Operation 57 | Modes](doc/operation_modes.rst) for details. 58 | 59 | ## controller_stopper 60 | A small helper node that stops and restarts ROS controllers based on a boolean status topic. When 61 | the status goes to `false`, all running controllers except a set of predefined 62 | *consistent_controllers* gets stopped. If status returns to `true` the stopped controllers are 63 | restarted. This is done by Subscribing to a robot's running state topic. Ideally this topic is 64 | latched and only publishes on changes. However, this node only reacts on state changes, so a state 65 | published each cycle would also be fine. 66 | -------------------------------------------------------------------------------- /ur_robot_driver/config/test_goal_publishers_config.yaml: -------------------------------------------------------------------------------- 1 | publisher_scaled_joint_trajectory_controller: 2 | ros__parameters: 3 | 4 | controller_name: "scaled_joint_trajectory_controller" 5 | wait_sec_between_publish: 6 6 | 7 | goal_names: ["pos1", "pos2", "pos3", "pos4"] 8 | pos1: 9 | positions: [0.785, -1.57, 0.785, 0.785, 0.785, 0.785] 10 | pos2: 11 | positions: [0.0, -1.57, 0.0, 0.0, 0.0, 0.0] 12 | pos3: 13 | positions: [0.0, -1.57, 0.0, 0.0, -0.785, 0.0] 14 | pos4: 15 | positions: [0.0, -1.57, 0.0, 0.0, 0.0, 0.0] 16 | 17 | joints: 18 | - shoulder_pan_joint 19 | - shoulder_lift_joint 20 | - elbow_joint 21 | - wrist_1_joint 22 | - wrist_2_joint 23 | - wrist_3_joint 24 | 25 | starting_point_limits: 26 | shoulder_pan_joint: [-0.1,0.1] 27 | shoulder_lift_joint: [-1.6,-1.5] 28 | elbow_joint: [-0.1,0.1] 29 | wrist_1_joint: [-1.6,-1.5] 30 | wrist_2_joint: [-0.1,0.1] 31 | wrist_3_joint: [-0.1,0.1] 32 | 33 | publisher_joint_trajectory_controller: 34 | ros__parameters: 35 | 36 | controller_name: "joint_trajectory_controller" 37 | wait_sec_between_publish: 6 38 | 39 | goal_names: ["pos1", "pos2", "pos3", "pos4"] 40 | pos1: 41 | positions: [0.785, -1.57, 0.785, 0.785, 0.785, 0.785] 42 | pos2: 43 | positions: [0.0, -1.57, 0.0, 0.0, 0.0, 0.0] 44 | pos3: 45 | positions: [0.0, -1.57, 0.0, 0.0, -0.785, 0.0] 46 | pos4: 47 | positions: [0.0, -1.57, 0.0, 0.0, 0.0, 0.0] 48 | 49 | joints: 50 | - shoulder_pan_joint 51 | - shoulder_lift_joint 52 | - elbow_joint 53 | - wrist_1_joint 54 | - wrist_2_joint 55 | - wrist_3_joint 56 | 57 | starting_point_limits: 58 | shoulder_pan_joint: [-0.1,0.1] 59 | shoulder_lift_joint: [-1.6,-1.5] 60 | elbow_joint: [-0.1,0.1] 61 | wrist_1_joint: [-1.6,-1.5] 62 | wrist_2_joint: [-0.1,0.1] 63 | wrist_3_joint: [-0.1,0.1] 64 | -------------------------------------------------------------------------------- /ur_robot_driver/config/test_velocity_goal_publishers_config.yaml: -------------------------------------------------------------------------------- 1 | publisher_forward_velocity_controller: 2 | ros__parameters: 3 | 4 | publish_topic: "forward_velocity_controller/commands" 5 | wait_sec_between_publish: 5 6 | 7 | goal_names: ["vel1", "vel2", "vel3"] 8 | vel1: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5] 9 | vel2: [0.0, 0.0, 0.0, 0.0, 0.0, -0.5] 10 | vel3: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 11 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur10_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 125 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur10e_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur15_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur16e_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur20_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur30_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur3_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 125 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur3e_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur5_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 125 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/config/ur5e_update_rate.yaml: -------------------------------------------------------------------------------- 1 | controller_manager: 2 | ros__parameters: 3 | update_rate: 500 # Hz 4 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/controller_stopper.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/controller_stopper.rst 2 | 3 | .. _controller_stopper: 4 | 5 | Controller stopper 6 | ================== 7 | 8 | As explained in the section :ref:`robot_startup_program`, the robot needs to run a program in order 9 | to receive motion commands from the ROS driver. When the program is not running, commands sent to 10 | the robot will have no effect. 11 | 12 | To make that transparent, the ``controller_stopper`` node mirrors that state in the ROS 13 | controller's state. It listens to the ``/io_and_status_controller/robot_program_running`` topic and 14 | deactivates all motion controllers (or any controller not explicitly marked as "consistent", see 15 | below)when the program is not running. 16 | 17 | Once the program is running again, any previously active motion controller will be activated again. 18 | 19 | This way, when sending commands to an inactive controller the caller should be transparently 20 | informed, that the controller cannot accept commands at the moment. 21 | 22 | In the same way, any running action on the ROS controller will be aborted, as the controller gets 23 | deactivated by the controller_stopper. 24 | 25 | Parameters 26 | ---------- 27 | 28 | - ``~consistent_controllers`` (list of strings, default: ``[]``) 29 | 30 | A list of controller names that should not be stopped when the program is not running. Any 31 | controller that doesn't require the robot program to be running should be in that list. 32 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/features.rst: -------------------------------------------------------------------------------- 1 | .. role:: raw-html-m2r(raw) 2 | :format: html 3 | 4 | 5 | Feature list and roadmap 6 | ------------------------ 7 | 8 | .. list-table:: 9 | :header-rows: 1 10 | 11 | * - Feature 12 | - ROS2 Driver 13 | * - joint-position-based control 14 | - yes 15 | * - scaled joint-position-based control 16 | - yes (:ref:`scaled_jtc`) 17 | * - joint-velocity-based control 18 | - yes\ :raw-html-m2r:`1` 19 | * - Cartesian position-based control 20 | - no 21 | * - Cartesian twist-based control 22 | - no 23 | * - Trajectory forwarding for execution on robot 24 | - yes (:ref:`passthrough_trajectory_controller`) 25 | * - reporting of tcp wrench 26 | - yes 27 | * - pausing of programs 28 | - yes 29 | * - continue trajectories after EM-Stop resume 30 | - yes 31 | * - continue trajectories after protective stop 32 | - yes 33 | * - panel interaction in between possible 34 | - yes 35 | * - get and set IO states 36 | - yes (:ref:`io_and_status_controller`) 37 | * - use `tool communication forwarder `_ on e-series 38 | - yes (:ref:`setup-tool-communication`) 39 | * - use the driver without a teach pendant necessary 40 | - yes 41 | * - support of CB1 and CB2 robots 42 | - no 43 | * - trajectory extrapolation on robot on missing packages 44 | - yes 45 | * - use ROS as drop-in for TP-programs 46 | - yes 47 | * - headless mode 48 | - yes (:ref:`headless_mode`) 49 | * - extract calibration from robot 50 | - yes (:ref:`ur_calibration`) 51 | * - send custom script commands to robot 52 | - yes (:ref:`io_and_status_controller`) 53 | * - Reconnect on a disconnected robot 54 | - yes 55 | * - Freedrive Mode 56 | - yes (:ref:`freedrive_mode_controller`) 57 | * - Tool Contact mode 58 | - yes (:ref:`tool_contact_controller`) 59 | * - Force Mode 60 | - yes (:ref:`force_mode_controller`) 61 | 62 | :raw-html-m2r:`1` Velocity-based joint control is implemented in the driver, the velocity-based joint trajectory controller would need tweaking of the gain parameters for each model. 63 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/index.rst: -------------------------------------------------------------------------------- 1 | .. ur_robot_driver documentation master file, created by 2 | sphinx-quickstart on Fri Apr 8 13:58:02 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root ``toctree`` directive. 5 | 6 | .. _ur_robot_driver: 7 | 8 | ur_robot_driver 9 | =============== 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: Contents: 14 | 15 | overview 16 | installation/toc 17 | usage/toc 18 | operation_modes 19 | setup_tool_communication 20 | hardware_interface_parameters 21 | dashboard_client 22 | robot_state_helper 23 | controller_stopper 24 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/cb3_01_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/cb3_01_welcome.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/cb3_05_urcaps_installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/cb3_05_urcaps_installed.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/cb3_07_installation_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/cb3_07_installation_excontrol.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/cb3_10_prog_structure_urcaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/cb3_10_prog_structure_urcaps.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/cb3_11_program_view_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/cb3_11_program_view_excontrol.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/es_01_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/es_01_welcome.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/es_05_urcaps_installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/es_05_urcaps_installed.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/es_07_installation_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/es_07_installation_excontrol.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/es_10_prog_structure_urcaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/es_10_prog_structure_urcaps.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/es_11_program_view_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/es_11_program_view_excontrol.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/family_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/family_photo.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/remote_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/remote_control.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/services_polyscope5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/services_polyscope5.png -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/initial_setup_images/services_polyscopex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/installation/initial_setup_images/services_polyscopex.jpg -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/installation.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/installation/installation.rst 2 | 3 | Installation of the ur_robot_driver 4 | =================================== 5 | 6 | You can either install this driver from binary packages as shown above or build it from source. We 7 | recommend a binary package installation unless you want to join development and submit changes. 8 | 9 | .. note:: 10 | 11 | Controlling the robot using ROS raises the requirement for strict cycle times. To achieve this, 12 | we strongly recommend to use a lowlatency or even ``PREEMPT_RT``-patched kernel. See 13 | :ref:`real time setup` for details on setting this up. 14 | 15 | For the same reason we encourage users to use a direct network connection between the ROS pc and 16 | the robot controller without a switch. 17 | 18 | Install from binary packages 19 | ---------------------------- 20 | 21 | 1. `Install ROS2 `_. This 22 | branch supports only ROS2 Rolling. For other ROS2 versions, please see the respective branches. 23 | 2. Install the driver using 24 | 25 | .. code-block:: bash 26 | 27 | sudo apt-get install ros-${ROS_DISTRO}-ur 28 | 29 | 30 | Build from source 31 | ----------------- 32 | 33 | Before building from source please make sure that you actually need to do that. Building from source 34 | might require some special treatment, especially when it comes to dependency management. 35 | Dependencies might change from time to time. Upstream packages (such as the library) might change 36 | their features / API which require changes in this repo. Therefore, this repo's source builds might 37 | require upstream repositories to be present in a certain version as otherwise builds might fail. 38 | Starting from scratch following exactly the steps below should always work, but simply pulling and 39 | building might fail occasionally. 40 | 41 | 1. `Install ROS2 `_. This 42 | branch supports only ROS2 Rolling. For other ROS2 versions, please see the respective branches. 43 | 44 | Once installed, please make sure to actually `source ROS2 `_ before proceeding. 45 | 46 | 3. Make sure that ``colcon``, its extensions and ``vcs`` are installed: 47 | 48 | .. code-block:: bash 49 | 50 | sudo apt install python3-colcon-common-extensions python3-vcstool 51 | 52 | 53 | 4. Create a new ROS2 workspace: 54 | 55 | .. code-block:: bash 56 | 57 | export COLCON_WS=~/workspace/ros_ur_driver 58 | mkdir -p $COLCON_WS/src 59 | 60 | 5. Clone relevant packages (replace ```` with ``humble``, ``iron`` or ``main`` for rolling), install dependencies, compile, and source the workspace by using: 61 | 62 | .. code-block:: bash 63 | 64 | cd $COLCON_WS 65 | git clone -b https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver.git src/Universal_Robots_ROS2_Driver 66 | vcs import src --skip-existing --input src/Universal_Robots_ROS2_Driver/Universal_Robots_ROS2_Driver-not-released.${ROS_DISTRO}.repos 67 | rosdep update 68 | rosdep install --ignore-src --from-paths src -y 69 | colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release 70 | source install/setup.bash 71 | 72 | 6. When consecutive pulls lead to build errors it is possible that you'll have to build an upstream 73 | package from source, as well. See the [detailed build status](ci_status.md). When the binary builds are red, but 74 | the semi-binary builds are green, you need to build the upstream dependencies from source. The 75 | easiest way to achieve this, is using the repos file: 76 | 77 | .. code-block:: bash 78 | 79 | cd $COLCON_WS 80 | vcs import src --skip-existing --input src/Universal_Robots_ROS2_Driver/Universal_Robots_ROS2_Driver.${ROS_DISTRO}.repos 81 | rosdep update 82 | rosdep install --ignore-src --from-paths src -y 83 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/robot_setup.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/installation/robot_setup.rst 2 | 3 | Setting up a UR robot for ur_robot_driver 4 | ========================================= 5 | 6 | Prepare robot and network connection 7 | ------------------------------------ 8 | 9 | Before you can use the ``ur_robot_driver`` you need to prepare the robot and the network 10 | connection as described in the :ref:`robot_setup` and :ref:`network_setup` section of the UR Client Library documentation. 11 | 12 | Prepare the ROS PC 13 | ------------------ 14 | 15 | For using the driver make sure it is installed (either by the debian package or built from source 16 | inside a colcon workspace). 17 | 18 | .. _calibration_extraction: 19 | 20 | Extract calibration information 21 | ------------------------------- 22 | 23 | Each UR robot is calibrated inside the factory giving exact forward and inverse kinematics. To also 24 | make use of this in ROS, you first have to extract the calibration information from the robot. 25 | 26 | Though this step is not necessary to control the robot using this driver, it is highly recommended 27 | to do so, as otherwise endeffector positions might be off in the magnitude of centimeters. 28 | 29 | For this, there exists a helper script: 30 | 31 | .. code:: bash 32 | 33 | $ ros2 launch ur_calibration calibration_correction.launch.py \ 34 | robot_ip:= target_filename:="${HOME}/my_robot_calibration.yaml" 35 | 36 | .. note:: 37 | The robot must be powered on (can be idle) before executing this script. 38 | 39 | 40 | For the parameter ``robot_ip`` insert the IP address on which the ROS pc can reach the robot. As 41 | ``target_filename`` provide an absolute path where the result will be saved to. 42 | 43 | See :ref:`ur_robot_driver_startup` for instructions on using the extracted calibration information. 44 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/installation/toc.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/installation/toc.rst 2 | 3 | ############ 4 | Installation 5 | ############ 6 | 7 | This chapter explains how to install the ``ur_robot_driver`` 8 | 9 | 10 | .. toctree:: 11 | :maxdepth: 4 12 | :caption: Contents: 13 | 14 | installation 15 | robot_setup 16 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.https://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/migration/jazzy.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/migration/jazzy.rst 2 | 3 | ur_robot_driver 4 | ^^^^^^^^^^^^^^^ 5 | 6 | keep_alive_count -> robot_receive_timeout 7 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | 9 | Doing real-time control with a robot requires the control pc to conform to certain timing 10 | constraints. For this ``keep_alive_count`` was used to estimate the tolerance that was given to the 11 | ROS controller in terms of multiples of 20 ms. Now the timeout is directly configured using the 12 | ``robot_receive_timeout`` parameter of the hardware interface. 13 | 14 | 15 | ros2_control xacro tag moved to driver package 16 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17 | 18 | The description package no longer adds the ``ros2_control`` tag to the robot's URDF. This is done 19 | in the driver now. Therefore, there is a ``urdf`` folder containing the macro for generating a 20 | ``ros2_control`` tag and a ready-to-use xacro file for a UR robot with a ``ros2_control`` tag. 21 | 22 | If you want to create your own controlled robot, you should mimic that structure, as done e.g. in 23 | the `custom_workcell_tutorial`_. 24 | 25 | .. _custom_workcell_tutorial: https://github.com/UniversalRobots/Universal_Robots_ROS2_Tutorials/blob/main/my_robot_cell/my_robot_cell_control/urdf/my_robot_cell_controlled.urdf.xacro 26 | 27 | robot_description is now distributed by the robot_state_publisher 28 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 29 | 30 | The ``robot_description`` isn't propagated to all interested parties as a parameter. Instead, only 31 | the ``robot_state_publisher`` is provided with the parameter, republishing it on the 32 | ``robot_description`` topic. 33 | 34 | Therefore, there is a new launchfile ``ur_rsp.launch.py`` which takes care about loading the 35 | description and starting the ``robot_state_publisher``. If you create a description that needs 36 | other parameters than the packaged one, you can write your own ``rsp`` launch file and pass that as 37 | ``description_launchfile`` argument to ``ur_control.launch.py``. 38 | 39 | Enforce absolute paths in launchfiles 40 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41 | 42 | All launchfiles now expect an absolute path for files that should be used to alter the launch 43 | process (e.g. description file, controllers file). Before it was expecting e.g. a 44 | ``description_package`` and a ``description_file`` argument with a relative path to the package. 45 | 46 | The default files have not been changed, so unless you specified your custom package / file 47 | combinations, you will need to update that to an absolute path. 48 | 49 | Absolute paths can still be generated dynamically using a package + relative path structure inside 50 | other launchfiles or by using ``ros2 pkg prefix`` on the command line. For example, you can do 51 | 52 | .. code-block:: console 53 | 54 | $ ros2 launch ur_robot_driver ur_control.launch.py ur_type:=ur20 robot_ip:=192.168.56.101 \ 55 | kinematics_params_file:=$(ros2 pkg prefix my_robot_cell_control)/share/my_robot_cell_control/config/my_robot_calibration.yaml 56 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/overview.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/overview.rst 2 | 3 | Overview 4 | ======== 5 | 6 | This driver collaborates closely with other ROS packages: 7 | 8 | ``ur_calibration`` 9 | Package containing the calibration extraction program that will extract parameters for correctly 10 | parametrizing the URDF with calibration data from the specific robot. 11 | ``ur_controllers`` 12 | Controllers specifically made for UR manipulators. 13 | ``ur_dashboard_msgs`` 14 | Message packages used for the `dashboard `_ communication. 15 | ``ur_moveit_config`` 16 | MoveIt! configuration for a plain robot. This is good as a starting point, but for a real 17 | application you would rather create your own MoveIt! configuration package containing your actual 18 | robot environment. 19 | ``ur_description`` (`separate repository `_) 20 | URDF description for UR manipulators 21 | 22 | .. include:: features.rst 23 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/resources/2021-10_ROS_World_2021_Making_a_robot_ROS2_powered.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/doc/resources/2021-10_ROS_World_2021_Making_a_robot_ROS2_powered.pdf -------------------------------------------------------------------------------- /ur_robot_driver/doc/resources/README.md: -------------------------------------------------------------------------------- 1 | # Resources about the ROS 2 Universal Robot driver 2 | 3 | The files in this folder are available for use under BSD-3-Clause license. 4 | 5 | 6 | ## Diagrams and images 7 | 8 | - [ros2_control diagrams](ros2_control_ur_driver.drawio) - `.drawio` file, Author: [Dr.-Ing. Denis Stogl](mailto:denis@stoglrobotics.de) (PickNik Robotics) 9 | 10 | 11 | ## 2021-10 ROS World presentation 12 | 13 | [Presentation: Making a robot ROS 2 powered - a case study using the UR manipulators](2021-10_ROS_World_2021_Making_a_robot_ROS2_powered.pdf) 14 | 15 | **Summary:** 16 | 17 | With the release of ros2_control and MoveIt 2, ROS 2 Foxy finally has all the “ingredients” needed to power a robot with similar features as in ROS 1. We present the driver for Universal Robot’s manipulators as a real-world example of how robots can be run using ROS 2. We show how to realize multi-interface support for position and velocity commands in the driver and how to support scaling controllers while respecting factors set on the teach pendant. Finally, we show how this real-world example influences development of ros2_control to support non-joint related inputs and outputs in its real-time control loop. 18 | 19 | **Presenter:** *Dr.-Ing. Denis Štogl* 20 | 21 | **Authors:** 22 | - Dr.-Ing. Denis Štogl (PickNik Inc.) 23 | - Dr. Nathan Brooks (PickNik Inc.) 24 | - Lovro Ivanov (PickNik Inc.) 25 | - Dr. Andy Zelenak (PickNik Inc.) 26 | - Rune Søe-Knudsen (Universal Robots A/S) 27 | 28 | #### [Video] Presentation recording 29 | [![Recording](https://i.vimeocdn.com/video/1309381824-05663ce76ceac80f043bc50addcc7c4874da323145c0df0df_640)](https://vimeo.com/649651707) 30 | 31 | 32 | #### [Video] MoveIt2 Demo 33 | [![Video: MoveIt2 Demo](https://img.youtube.com/vi/d_cVXoZZ52w/0.jpg)](https://www.youtube.com/watch?v=d_cVXoZZ52w) 34 | 35 | This video shows free-space trajectory planning around a modeled collision scene object using the MoveIt2 MotionPlanning widget for Rviz2. 36 | 37 | #### [Video] Scaled Joint Trajectory Controller Demo 38 | [![Video: Scaled Joint Trajectory Controller Demo](https://img.youtube.com/vi/dHaxBpMGbw0/0.jpg)](https://www.youtube.com/watch?v=dHaxBpMGbw0) 39 | 40 | This video demonstrates the following features: 41 | - [[0:00](https://www.youtube.com/watch?v=dHaxBpMGbw0&t=0s)] - Previewing a plan with MoveIt2 MotionPlanning widget for Rviz2 42 | - [[0:05](https://www.youtube.com/watch?v=dHaxBpMGbw0&t=5s)] - Executing a plan with MoveIt2 MotionPlanning widget for Rviz2 43 | - [[0:09](https://www.youtube.com/watch?v=dHaxBpMGbw0&t=9s)] - Pendant speed scaling of a simulated MoveIt trajectory 44 | - [[0:18](https://www.youtube.com/watch?v=dHaxBpMGbw0&t=18s)] - Pendant speed scaling of an executed MoveIt trajectory 45 | - [[0:22](https://www.youtube.com/watch?v=dHaxBpMGbw0&t=22s)] - Online pendant speed scaling during trajectory execution 46 | - [[0:26](https://www.youtube.com/watch?v=dHaxBpMGbw0&t=26s)] - Resuming trajectory execution from E-stop 47 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/resources/play_button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 36 | 38 | 43 | 49 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/robot_state_helper.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/robot_state_helper.rst 2 | 3 | .. _robot_state_helper: 4 | 5 | Robot state helper 6 | ================== 7 | After switching on the robot, it has to be manually started, the brakes have to be released and a 8 | program has to be started in order to make the robot ready to use. This is usually done using the 9 | robot's teach pendant. 10 | 11 | Whenever the robot encounters an error, manual intervention is required to resolve the issue. For 12 | example, if the robot goes into a protective stop, the error has to be acknowledged and the robot 13 | program has to be unpaused. 14 | 15 | When the robot is in :ref:`remote_control_mode `, most interaction with the robot can be done 16 | without using the teach pendant, many of that through the :ref:`dashboard client 17 | `. 18 | 19 | The ROS driver provides a helper node that can be used to automate some of these tasks. The 20 | ``robot_state_helper`` node can be used to start the robot, release the brakes, and (re-)start the 21 | program through an action call. It is started by default and provides a 22 | `dashboard_msgs/action/SetMode 23 | `_ action. 24 | 25 | For example, to make the robot ready to be used by the ROS driver, call 26 | 27 | .. code-block:: console 28 | 29 | $ 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}" 30 | 31 | The ``target_robot_mode`` can be one of the following: 32 | 33 | .. table:: target_robot_mode 34 | :widths: auto 35 | 36 | ===== ===== 37 | index meaning 38 | ===== ===== 39 | 3 POWER_OFF -- Robot is powered off 40 | 5 IDLE -- Robot is powered on, but brakes are engaged 41 | 7 RUNNING -- Robot is powered on, brakes are released, ready to run a program 42 | ===== ===== 43 | 44 | .. note:: 45 | 46 | When the ROBOT_STATE is in ``RUNNING``, that is equivalent to the robot showing the green dot in 47 | the lower left corner of the teach pendant (On PolyScope 5). The program state is independent of 48 | that and shows with the text next to that button. 49 | 50 | The ``stop_program`` flag is used to stop the currently running program before changing the robot 51 | state. In combination with the :ref:`controller_stopper`, this will deactivate any motion 52 | controller and therefore stop any ROS action being active on those controllers. 53 | 54 | .. warning:: 55 | A robot's protective stop or emergency stop is only pausing the running program. If the program 56 | is resumed after the P-Stop or EM-Stop is released, the robot will continue executing what it 57 | has been doing. Therefore, it is advised to stop and re-start the program when recovering from a 58 | fault. 59 | 60 | The ``play_program`` flag is used to start the program after the robot state has been set. This has 61 | the same effects as explained in :ref:`continuation_after_interruptions`. 62 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/setup_tool_communication.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/setup_tool_communication.rst 2 | 3 | .. _setup-tool-communication: 4 | 5 | Setting up the tool communication on an e-Series robot 6 | ====================================================== 7 | 8 | .. note:: 9 | Currently, there seems to be issues with having the tool communication setup from this guide and 10 | the "Robotiq Grippers" URCap running in parallel. If you are planning to use the "Robotiq 11 | Grippers" URCap then currently please refrain from installing the rs485 URCap. 12 | 13 | See 14 | `this issue `_ 15 | for details and the current state. 16 | 17 | The Universal Robots e-Series provides an rs485 based interface at the tool flange that can be used 18 | to attach an rs485-based device to the robot's tcp without the need to wire a separate cable along 19 | the robot. 20 | 21 | This driver enables forwarding this tool communication interface to an external machine for example 22 | to start a device's ROS driver on a remote PC. 23 | 24 | This document will guide you through installing the URCap needed for this and setting up your ROS 25 | launch files to utilize the robot's tool communication. 26 | 27 | Robot setup 28 | ----------- 29 | 30 | For setting up the robot, please install the **rs485-1.0.urcap** found in the **resources** folder. 31 | Installing a URCap is explained in the :ref:`setup guide ` for the **external-control** URCap. 32 | 33 | After installing the URCap the robot will expose its tool communication device to the network. 34 | 35 | Setup the ROS side 36 | ------------------ 37 | 38 | In order to use the tool communication in ROS, simply pass the correct parameters to the bringup 39 | launch files: 40 | 41 | .. code-block:: bash 42 | 43 | $ ros2 launch ur_robot_driver ur_control.launch.py ur_type:=ur5e robot_ip:=yyy.yyy.yyy.yyy use_tool_communication:=true use_mock_hardware:=false launch_rviz:=false 44 | # remember that your user needs to have the rights to write that file handle to /tmp/ttyUR 45 | 46 | Following parameters can be set `ur.ros2_control.xacro `_\ : 47 | 48 | 49 | * ``tool_voltage`` 50 | * ``tool_parity`` 51 | * ``tool_baud_rate`` 52 | * ``tool_stop_bits`` 53 | * ``tool_rx_idle_chars`` 54 | * ``tool_tx_idle_chars`` 55 | * ``tool_device_name`` 56 | * ``tool_tcp_port`` 57 | 58 | The ``tool_device_name`` is an arbitrary name for the device file at which the device will be 59 | accessible in the local file system. Most ROS drivers for rs485 devices accept an argument to 60 | specify the device file path. With the example above you could run the ``rs485_node`` from the package 61 | ``imaginary_drivers`` using the following command: 62 | 63 | .. code-block:: bash 64 | 65 | $ ros2 run imaginary_drivers rs485_node --ros-args -p device:=/tmp/ttyUR 66 | 67 | You can basically choose any device name, but your user has to have the correct rights to actually 68 | create a new file handle inside this directory. Therefore, we didn't use the ``/dev`` folder in the 69 | example, as users usually don't have the access rights to create new files there. 70 | 71 | For all the other tool parameters seen above, please refer to the Universal Robots user manual. 72 | 73 | More information can be found at `Universal_Robots_ToolComm_Forwarder_URCap `_. 74 | The convenience script for ``socat`` call is `here `_ for ROS2 driver and can be run by: 75 | 76 | .. code-block:: bash 77 | 78 | $ ros2 run ur_robot_driver tool_communication.py --ros-args -p robot_ip:=192.168.56.101 -p device_name:=/tmp/ttyUR 79 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/usage/script_code.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/usage/script_code.rst 2 | 3 | Sending URScript code to the robot 4 | ================================== 5 | 6 | .. _script_command_interface_ros2: 7 | 8 | Custom URScript commands 9 | ------------------------ 10 | 11 | The driver's package contains a ``urscript_interface`` node that allows sending URScript snippets 12 | directly to the robot when the robot is in remote control mode. 13 | 14 | It gets started in the driver's launchfiles by default. To use it, simply 15 | publish a message to its interface: 16 | 17 | .. code-block:: bash 18 | 19 | # simple popup 20 | ros2 topic pub /urscript_interface/script_command std_msgs/msg/String '{data: popup("hello")}' --once 21 | 22 | Be aware, that running a program on this interface (meaning publishing script code to that interface) stops any running program on the robot. 23 | Thus, the motion-interpreting program that is started by the driver gets stopped and has to be 24 | restarted again. Depending whether you use :ref:`headless_mode` or not, you'll have to call the 25 | ``resend_program`` service or press the ``play`` button on the teach panel to start the 26 | external control URCap program again. 27 | 28 | .. note:: 29 | On E-series robots or newer the robot needs to be in *remote control mode* in order to execute custom URScript commands. 30 | Currently, there is no feedback on the code's correctness. If the code sent to the 31 | robot is incorrect, it will silently not get executed. Make sure that you send valid URScript code! 32 | 33 | Multi-line programs 34 | ^^^^^^^^^^^^^^^^^^^ 35 | 36 | When you want to define multi-line programs, make sure to check that newlines are correctly 37 | interpreted from your message. For this purpose the driver prints the program as it is being sent to 38 | the robot. When sending a multi-line program from the command line, you can use an empty line 39 | between each statement: 40 | 41 | .. code-block:: bash 42 | 43 | ros2 topic pub --once /urscript_interface/script_command std_msgs/msg/String '{data: 44 | "def my_prog(): 45 | 46 | set_digital_out(1, True) 47 | 48 | movej(p[0.2, 0.3, 0.8, 0, 0, 3.14], a=1.2, v=0.25, r=0) 49 | 50 | textmsg(\"motion finished\") 51 | 52 | end"}' 53 | 54 | Non-interrupting programs 55 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 56 | 57 | To prevent interrupting the main program, you can send certain commands as `secondary programs 58 | `_. 59 | 60 | .. code-block:: bash 61 | 62 | ros2 topic pub --once /urscript_interface/script_command std_msgs/msg/String '{data: 63 | "sec my_prog(): 64 | 65 | textmsg(\"This is a log message\") 66 | 67 | end"}' 68 | -------------------------------------------------------------------------------- /ur_robot_driver/doc/usage/simulation.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/doc/usage/simulation.rst 2 | 3 | Simulation 4 | ========== 5 | 6 | Apart from being used with a real robot, the ROS driver can be used with ros2_control's mock hardware or the URSim simulator (which is equivalent from the driver's perspective). 7 | 8 | Additionally, the robot can be simulated using 9 | `Gazebo Classic `_ or 10 | `GZ Sim `_ but that's 11 | outside of this driver's scope. 12 | 13 | .. _usage_with_official_ur_simulator: 14 | 15 | Usage with official UR simulator 16 | -------------------------------- 17 | 18 | The easiest way to use URSim is the `Docker 19 | image `_ provided by Universal Robots (See 20 | `this link `_ for a CB3-series image). 21 | 22 | To start it, we've prepared a script: 23 | 24 | .. code-block:: bash 25 | 26 | ros2 run ur_client_library start_ursim.sh -m 27 | 28 | With this, we can spin up a driver using 29 | 30 | .. code-block:: bash 31 | 32 | ros2 launch ur_robot_driver ur_control.launch.py ur_type:= robot_ip:=192.168.56.101 launch_rviz:=true 33 | 34 | You can view the polyscope GUI by opening ``_. 35 | 36 | When we now move the robot in Polyscope, the robot's RViz visualization should move accordingly. 37 | 38 | For details on the Docker image, please see the more detailed guide :ref:`here `. 39 | 40 | Mock hardware 41 | ------------- 42 | 43 | The package can simulate hardware with the ros2_control ``MockSystem``. This emulator enables an 44 | environment for testing of "piping" of hardware and controllers, as well as testing robot's 45 | descriptions. For more details see `ros2_control documentation 46 | `_ 47 | for more details. 48 | 49 | .. note:: 50 | Some driver functionalities currently don't work with mock hardware: 51 | 52 | * The TCP pose broadcaster does not work. 53 | * The passthrough trajectory controller does not function when calling the follow joint trajectory action. 54 | * The force mode controller also does not respond when trying to start force mode. 55 | * The GPIO controller cannot verify that it has changed the state of an I/O pin, so it will report a failure when trying to set an I/O pin. 56 | -------------------------------------------------------------------------------- /ur_robot_driver/hardware_interface_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | ROS2 Control System Driver for the Universal Robots series. 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ur_robot_driver/include/ur_robot_driver/controller_stopper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019, FZI Forschungszentrum Informatik, Created on behalf of Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Felix Exner exner@fzi.de 33 | * \date 2019-06-12 34 | * 35 | * \author Mads Holm Peters 36 | * \date 2022-02-25 37 | * 38 | */ 39 | //---------------------------------------------------------------------- 40 | #ifndef UR_ROBOT_DRIVER__CONTROLLER_STOPPER_HPP_ 41 | #define UR_ROBOT_DRIVER__CONTROLLER_STOPPER_HPP_ 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | #include "rclcpp/rclcpp.hpp" 48 | #include "controller_manager_msgs/srv/list_controllers.hpp" 49 | #include "controller_manager_msgs/srv/switch_controller.hpp" 50 | #include "std_msgs/msg/bool.hpp" 51 | 52 | class ControllerStopper 53 | { 54 | public: 55 | ControllerStopper() = delete; 56 | ControllerStopper(const rclcpp::Node::SharedPtr& node, bool stop_controllers_on_startup); 57 | virtual ~ControllerStopper() = default; 58 | 59 | private: 60 | void robotRunningCallback(const std_msgs::msg::Bool::ConstSharedPtr msg); 61 | 62 | /*! 63 | * \brief Queries running stoppable controllers and the controllers are stopped. 64 | * 65 | * Queries the controller manager for running controllers and compares the result with the 66 | * consistent_controllers_. The remaining running controllers are stored in stopped_controllers_ 67 | * and stopped afterwards. 68 | */ 69 | void findAndStopControllers(); 70 | 71 | /*! 72 | * \brief Starts the controllers stored in stopped_controllers_. 73 | * 74 | */ 75 | void startControllers(); 76 | 77 | std::shared_ptr node_; 78 | rclcpp::Client::SharedPtr controller_manager_srv_; 79 | rclcpp::Client::SharedPtr controller_list_srv_; 80 | 81 | rclcpp::Subscription::SharedPtr robot_running_sub_; 82 | 83 | std::vector consistent_controllers_; 84 | std::vector stopped_controllers_; 85 | 86 | bool stop_controllers_on_startup_; 87 | bool robot_running_; 88 | }; 89 | #endif // UR_ROBOT_DRIVER__CONTROLLER_STOPPER_HPP_ 90 | -------------------------------------------------------------------------------- /ur_robot_driver/launch/test_forward_velocity_controller.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 PickNik, Inc. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # 9 | # * Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 13 | # * Neither the name of the {copyright_holder} nor the names of its 14 | # contributors may be used to endorse or promote products derived from 15 | # this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # 30 | # Author: Lovro Ivanov 31 | # 32 | # Description: After a robot has been loaded, this will execute a series of trajectories. 33 | 34 | from launch import LaunchDescription 35 | from launch.substitutions import PathJoinSubstitution 36 | from launch_ros.actions import Node 37 | from launch_ros.substitutions import FindPackageShare 38 | 39 | 40 | def generate_launch_description(): 41 | velocity_config = PathJoinSubstitution( 42 | [FindPackageShare("ur_robot_driver"), "config", "test_velocity_goal_publishers_config.yaml"] 43 | ) 44 | 45 | return LaunchDescription( 46 | [ 47 | Node( 48 | package="ros2_controllers_test_nodes", 49 | executable="publisher_forward_position_controller", 50 | name="publisher_forward_velocity_controller", 51 | parameters=[velocity_config], 52 | output="screen", 53 | ) 54 | ] 55 | ) 56 | -------------------------------------------------------------------------------- /ur_robot_driver/launch/test_joint_trajectory_controller.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 PickNik, Inc. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # 9 | # * Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 13 | # * Neither the name of the {copyright_holder} nor the names of its 14 | # contributors may be used to endorse or promote products derived from 15 | # this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # 30 | # Author: Denis Stogl 31 | # 32 | # Description: After a robot has been loaded, this will execute a series of trajectories. 33 | 34 | from launch import LaunchDescription 35 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 36 | from launch.actions import DeclareLaunchArgument 37 | from launch_ros.actions import Node 38 | from launch_ros.substitutions import FindPackageShare 39 | 40 | 41 | def generate_launch_description(): 42 | position_goals = PathJoinSubstitution( 43 | [ 44 | FindPackageShare("ur_robot_driver"), 45 | "config", 46 | "test_goal_publishers_config.yaml", 47 | ] 48 | ) 49 | 50 | check_starting_point = LaunchConfiguration("check_starting_point") 51 | 52 | return LaunchDescription( 53 | [ 54 | DeclareLaunchArgument( 55 | "check_starting_point", 56 | default_value="true", 57 | description="Verify that the robot is at a preconfigured pose in order to avoid large unexpected motions.", 58 | ), 59 | Node( 60 | package="ros2_controllers_test_nodes", 61 | executable="publisher_joint_trajectory_controller", 62 | name="publisher_joint_trajectory_controller", 63 | parameters=[ 64 | position_goals, 65 | { 66 | "check_starting_point": check_starting_point, 67 | }, 68 | ], 69 | output="screen", 70 | ), 71 | ] 72 | ) 73 | -------------------------------------------------------------------------------- /ur_robot_driver/launch/test_scaled_joint_trajectory_controller.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 PickNik, Inc. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # 9 | # * Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 13 | # * Neither the name of the {copyright_holder} nor the names of its 14 | # contributors may be used to endorse or promote products derived from 15 | # this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | 29 | # 30 | # Author: Denis Stogl 31 | # 32 | # Description: After a robot has been loaded, this will execute a series of trajectories. 33 | 34 | from launch import LaunchDescription 35 | from launch.substitutions import LaunchConfiguration, PathJoinSubstitution 36 | from launch.actions import DeclareLaunchArgument 37 | from launch_ros.actions import Node 38 | from launch_ros.substitutions import FindPackageShare 39 | 40 | 41 | def generate_launch_description(): 42 | position_goals = PathJoinSubstitution( 43 | [ 44 | FindPackageShare("ur_robot_driver"), 45 | "config", 46 | "test_goal_publishers_config.yaml", 47 | ] 48 | ) 49 | 50 | check_starting_point = LaunchConfiguration("check_starting_point") 51 | 52 | return LaunchDescription( 53 | [ 54 | DeclareLaunchArgument( 55 | "check_starting_point", 56 | default_value="true", 57 | description="Verify that the robot is at a preconfigured pose in order to avoid large unexpected motions.", 58 | ), 59 | Node( 60 | package="ros2_controllers_test_nodes", 61 | executable="publisher_joint_trajectory_controller", 62 | name="publisher_scaled_joint_trajectory_controller", 63 | parameters=[ 64 | position_goals, 65 | { 66 | "check_starting_point": check_starting_point, 67 | }, 68 | ], 69 | output="screen", 70 | ), 71 | ] 72 | ) 73 | -------------------------------------------------------------------------------- /ur_robot_driver/launch/ur_dashboard_client.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021, PickNik, Inc. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # 6 | # * Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # 9 | # * Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 13 | # * Neither the name of the {copyright_holder} nor the names of its 14 | # contributors may be used to endorse or promote products derived from 15 | # this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | from launch import LaunchDescription 31 | from launch.actions import DeclareLaunchArgument 32 | from launch.substitutions import LaunchConfiguration 33 | from launch_ros.actions import Node 34 | 35 | 36 | def generate_launch_description(): 37 | # Declare arguments 38 | declared_arguments = [] 39 | declared_arguments.append( 40 | DeclareLaunchArgument( 41 | "robot_ip", 42 | description="IP address by which the robot can be reached.", 43 | ) 44 | ) 45 | 46 | # Initialize Arguments 47 | robot_ip = LaunchConfiguration("robot_ip") 48 | 49 | dashboard_client_node = Node( 50 | package="ur_robot_driver", 51 | executable="dashboard_client", 52 | name="dashboard_client", 53 | output="screen", 54 | emulate_tty=True, 55 | parameters=[{"robot_ip": robot_ip}], 56 | ) 57 | 58 | return LaunchDescription(declared_arguments + [dashboard_client_node]) 59 | -------------------------------------------------------------------------------- /ur_robot_driver/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ur_robot_driver 5 | 4.0.1 6 | The new driver for Universal Robots UR3, UR5 and UR10 robots with CB3 controllers and the e-series. 7 | 8 | Felix Exner 9 | Rune Søe-Knudsen 10 | Universal Robots A/S 11 | 12 | BSD-3-Clause 13 | 14 | https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/issues 15 | https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver 16 | 17 | Denis Stogl 18 | Robert Wilbrandt 19 | Marvin Große Besselmann 20 | Lovro Ivanov 21 | Andy Zelenak 22 | Vincenzo Di Pentima 23 | Thomas Timm Andersen 24 | Simon Rasmussen 25 | Felix Exner 26 | Lea Steffen 27 | Tristan Schnell 28 | 29 | ament_cmake 30 | ament_cmake_python 31 | 32 | backward_ros 33 | controller_manager 34 | controller_manager_msgs 35 | geometry_msgs 36 | hardware_interface 37 | pluginlib 38 | rclcpp 39 | rclcpp_lifecycle 40 | rclpy 41 | std_msgs 42 | std_srvs 43 | tf2_geometry_msgs 44 | ur_client_library 45 | ur_controllers 46 | ur_dashboard_msgs 47 | ur_description 48 | ur_msgs 49 | 50 | force_torque_sensor_broadcaster 51 | joint_state_broadcaster 52 | joint_state_publisher 53 | joint_trajectory_controller 54 | launch 55 | launch_ros 56 | pose_broadcaster 57 | position_controllers 58 | robot_state_publisher 59 | ros2_controllers_test_nodes 60 | rviz2 61 | socat 62 | urdf 63 | velocity_controllers 64 | xacro 65 | 66 | launch_testing_ament_cmake 67 | 68 | 69 | ament_cmake 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /ur_robot_driver/resources/externalcontrol-1.0.5.urcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/resources/externalcontrol-1.0.5.urcap -------------------------------------------------------------------------------- /ur_robot_driver/resources/rs485-1.0.urcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/resources/rs485-1.0.urcap -------------------------------------------------------------------------------- /ur_robot_driver/resources/rtde_input_recipe.txt: -------------------------------------------------------------------------------- 1 | speed_slider_mask 2 | speed_slider_fraction 3 | standard_digital_output_mask 4 | standard_digital_output 5 | configurable_digital_output_mask 6 | configurable_digital_output 7 | tool_digital_output_mask 8 | tool_digital_output 9 | standard_analog_output_mask 10 | standard_analog_output_type 11 | standard_analog_output_0 12 | standard_analog_output_1 13 | -------------------------------------------------------------------------------- /ur_robot_driver/resources/rtde_output_recipe.txt: -------------------------------------------------------------------------------- 1 | timestamp 2 | actual_q 3 | actual_qd 4 | speed_scaling 5 | target_speed_fraction 6 | runtime_state 7 | actual_TCP_force 8 | actual_TCP_pose 9 | target_TCP_pose 10 | actual_digital_input_bits 11 | actual_digital_output_bits 12 | standard_analog_input0 13 | standard_analog_input1 14 | standard_analog_output0 15 | standard_analog_output1 16 | analog_io_types 17 | tool_mode 18 | tool_analog_input_types 19 | tool_analog_input0 20 | tool_analog_input1 21 | tool_output_voltage 22 | tool_output_current 23 | tool_temperature 24 | robot_mode 25 | safety_mode 26 | robot_status_bits 27 | safety_status_bits 28 | actual_current 29 | tcp_offset 30 | -------------------------------------------------------------------------------- /ur_robot_driver/scripts/start_ursim.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # copyright 2022 Universal Robots A/S 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 8 | # * Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # * Neither the name of the {copyright_holder} nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | # POSSIBILITY OF SUCH DAMAGE. 30 | 31 | ORANGE='\033[0;33m' 32 | NC='\033[0m' # No Color 33 | 34 | URSIM_CMD="ros2 run ur_client_library start_ursim.sh" 35 | 36 | echo -e "${ORANGE} DEPRECATION WARNING: The script starting URSim was moved to the ur_client_library package. This script here does still work, but will be removed with ROS Jazzy. Please use `${URSIM_CMD}` to start URSim in future." 37 | $URSIM_CMD 38 | -------------------------------------------------------------------------------- /ur_robot_driver/scripts/tool_communication.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2021 PickNik, Inc. 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the {copyright_holder} nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | # POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | """Small helper script to start the tool communication interface.""" 32 | 33 | import subprocess 34 | 35 | import rclpy.logging 36 | from rclpy.node import Node 37 | 38 | 39 | class UrToolCommunication(Node): 40 | """Starts socat.""" 41 | 42 | def __init__(self): 43 | super().__init__("ur_tool_communication") 44 | # IP address of the robot 45 | self.declare_parameter("robot_ip", "192.168.56.101") 46 | robot_ip = self.get_parameter("robot_ip").get_parameter_value().string_value 47 | self.get_logger().info(robot_ip) 48 | # Port on which the remote pc (robot) publishes the interface 49 | self.declare_parameter("tcp_port", 54321) 50 | tcp_port = self.get_parameter_or("tcp_port", 54321).get_parameter_value().integer_value 51 | # By default, socat will create a pty in /dev/pts/N with n being an increasing number. 52 | # Additionally, a symlink at the given location will be created. Use an absolute path here. 53 | self.declare_parameter("device_name", "/tmp/ttyUR") 54 | local_device = self.get_parameter("device_name").get_parameter_value().string_value 55 | 56 | self.get_logger().info("Remote device is available at '" + local_device + "'") 57 | 58 | cfg_params = ["pty"] 59 | cfg_params.append("link=" + local_device) 60 | cfg_params.append("raw") 61 | cfg_params.append("ignoreeof") 62 | cfg_params.append("waitslave") 63 | 64 | cmd = ["socat"] 65 | cmd.append(",".join(cfg_params)) 66 | cmd.append(":".join(["tcp", robot_ip, str(tcp_port)])) 67 | 68 | self.get_logger().info("Starting socat with following command:\n" + " ".join(cmd)) 69 | subprocess.call(cmd) 70 | 71 | 72 | def main(): 73 | rclpy.init() 74 | node = UrToolCommunication() 75 | rclpy.spin(node) 76 | 77 | 78 | if __name__ == "__main__": 79 | main() 80 | -------------------------------------------------------------------------------- /ur_robot_driver/scripts/wait_dashboard_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | netcat -z 192.168.56.101 29999 4 | while [ $? -eq 1 ] 5 | do 6 | echo "Dashboard server not accepting connections..." 7 | sleep 3 8 | netcat -z 192.168.56.101 29999 9 | done 10 | echo "Dashboard server connections are possible." 11 | sleep 5 12 | -------------------------------------------------------------------------------- /ur_robot_driver/scripts/wait_for_robot_description: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2024 FZI Forschungszentrum Informatik 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the {copyright_holder} nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | # POSSIBILITY OF SUCH DAMAGE. 29 | 30 | import rclpy 31 | from rclpy.node import Node 32 | 33 | from std_msgs.msg import String 34 | 35 | from rclpy.task import Future 36 | from rclpy.qos import QoSProfile, QoSDurabilityPolicy 37 | 38 | 39 | class DescriptionSubscriber(Node): 40 | 41 | def __init__(self): 42 | super().__init__("wait_for_robot_description") 43 | self.topic = "robot_description" 44 | qos_profile = QoSProfile( 45 | depth=1, 46 | durability=QoSDurabilityPolicy.TRANSIENT_LOCAL, 47 | ) 48 | self.subscription = self.create_subscription( 49 | String, self.topic, self.desc_callback, qos_profile=qos_profile 50 | ) 51 | self.future = Future() 52 | 53 | self.get_logger().info(f"Waiting for message on {self.resolve_topic_name(self.topic)}.") 54 | 55 | def desc_callback(self, msg): 56 | self.get_logger().info( 57 | f"Received message on {self.resolve_topic_name(self.topic)}. Shutting down." 58 | ) 59 | self.future.set_result(True) 60 | 61 | 62 | def main(args=None): 63 | rclpy.init(args=args) 64 | 65 | sub = DescriptionSubscriber() 66 | 67 | rclpy.spin_until_future_complete(sub, sub.future) 68 | 69 | sub.destroy_node() 70 | rclpy.shutdown() 71 | 72 | 73 | if __name__ == "__main__": 74 | main() 75 | -------------------------------------------------------------------------------- /ur_robot_driver/src/controller_stopper_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019, FZI Forschungszentrum Informatik, Created on behalf of Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Felix Exner exner@fzi.de 33 | * \date 2019-06-12 34 | * 35 | * \author Mads Holm Peters 36 | * \date 2022-02-25 37 | * 38 | */ 39 | //---------------------------------------------------------------------- 40 | 41 | #include "rclcpp/rclcpp.hpp" 42 | #include "ur_robot_driver/controller_stopper.hpp" 43 | 44 | int main(int argc, char** argv) 45 | { 46 | rclcpp::init(argc, argv); 47 | rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared("controller_stopper_node"); 48 | 49 | bool headless_mode = node->declare_parameter("headless_mode", false); 50 | node->get_parameter("headless_mode", headless_mode); 51 | bool joint_controller_active = node->declare_parameter("joint_controller_active", true); 52 | node->get_parameter("joint_controller_active", joint_controller_active); 53 | 54 | // If headless mode is not active, but the joint controllers are we should stop the joint controllers during startup 55 | // of the node 56 | bool stop_controllers_on_startup = false; 57 | if (joint_controller_active == true && headless_mode == false) { 58 | stop_controllers_on_startup = true; 59 | } 60 | 61 | ControllerStopper stopper(node, stop_controllers_on_startup); 62 | 63 | rclcpp::spin(node); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /ur_robot_driver/src/dashboard_client_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019, FZI Forschungszentrum Informatik 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Felix Exner exner@fzi.de 33 | * \date 2019-10-21 34 | * 35 | */ 36 | //---------------------------------------------------------------------- 37 | 38 | #include "ur_robot_driver/dashboard_client_ros.hpp" 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | #include "ur_robot_driver/urcl_log_handler.hpp" 45 | 46 | int main(int argc, char** argv) 47 | { 48 | rclcpp::init(argc, argv); 49 | rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared("ur_dashboard_client"); 50 | 51 | // The IP address under which the robot is reachable. 52 | std::string robot_ip = node->declare_parameter("robot_ip", "192.168.56.101"); 53 | node->get_parameter("robot_ip", robot_ip); 54 | 55 | ur_robot_driver::registerUrclLogHandler(""); // Set empty tf_prefix at the moment 56 | 57 | std::shared_ptr client; 58 | try { 59 | client = std::make_shared(node, robot_ip); 60 | } catch (const urcl::UrException& e) { 61 | RCLCPP_WARN(rclcpp::get_logger("Dashboard_Client"), 62 | "%s This warning is expected on a PolyScopeX robot. If you don't want to see this warning, " 63 | "please don't start the dashboard client. Exiting dashboard client now.", 64 | e.what()); 65 | return 0; 66 | } 67 | 68 | rclcpp::spin(node); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /ur_robot_driver/src/robot_state_helper_node.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024, FZI Forschungszentrum Informatik, Created on behalf of Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | #include "ur_robot_driver/robot_state_helper.hpp" 30 | #include "ur_robot_driver/urcl_log_handler.hpp" 31 | 32 | int main(int argc, char** argv) 33 | { 34 | rclcpp::init(argc, argv); 35 | rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared("robot_state_helper"); 36 | ur_robot_driver::registerUrclLogHandler(""); // Set empty tf_prefix at the moment 37 | std::shared_ptr robot_state_helper; 38 | try { 39 | robot_state_helper = std::make_shared(node); 40 | } catch (const urcl::UrException& e) { 41 | RCLCPP_ERROR(rclcpp::get_logger("robot_state_helper"), "%s", e.what()); 42 | } 43 | 44 | rclcpp::executors::MultiThreadedExecutor executor; 45 | executor.add_node(node); 46 | executor.spin(); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /ur_robot_driver/src/urscript_interface.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2023, FZI Forschungszentrum Informatik, Created on behalf of Universal Robots A/S 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // 9 | // * Redistributions in binary form must reproduce the above copyright 10 | // notice, this list of conditions and the following disclaimer in the 11 | // documentation and/or other materials provided with the distribution. 12 | // 13 | // * Neither the name of the {copyright_holder} nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | // POSSIBILITY OF SUCH DAMAGE. 28 | 29 | //---------------------------------------------------------------------- 30 | /*!\file 31 | * 32 | * \author Felix Exner exner@fzi.de 33 | * \date 2023-06-20 34 | * 35 | */ 36 | //---------------------------------------------------------------------- 37 | 38 | #include 39 | #include 40 | 41 | #include 42 | 43 | #include 44 | #include 45 | 46 | class URScriptInterface : public rclcpp::Node 47 | { 48 | public: 49 | URScriptInterface() 50 | : Node("urscript_interface") 51 | , m_script_sub(this->create_subscription( 52 | "~/script_command", 1, [this](const std_msgs::msg::String::SharedPtr msg) { 53 | auto program_with_newline = msg->data + '\n'; 54 | 55 | RCLCPP_INFO_STREAM(this->get_logger(), program_with_newline); 56 | 57 | size_t len = program_with_newline.size(); 58 | const auto* data = reinterpret_cast(program_with_newline.c_str()); 59 | size_t written; 60 | 61 | if (m_secondary_stream->write(data, len, written)) { 62 | URCL_LOG_INFO("Sent program to robot:\n%s", program_with_newline.c_str()); 63 | return true; 64 | } 65 | URCL_LOG_ERROR("Could not send program to robot"); 66 | return false; 67 | })) 68 | { 69 | this->declare_parameter("robot_ip", rclcpp::PARAMETER_STRING); 70 | m_secondary_stream = std::make_unique>( 71 | this->get_parameter("robot_ip").as_string(), urcl::primary_interface::UR_SECONDARY_PORT); 72 | m_secondary_stream->connect(); 73 | 74 | auto program_with_newline = std::string("textmsg(\"urscript_interface connected\")\n"); 75 | size_t len = program_with_newline.size(); 76 | const auto* data = reinterpret_cast(program_with_newline.c_str()); 77 | size_t written; 78 | m_secondary_stream->write(data, len, written); 79 | } 80 | 81 | private: 82 | rclcpp::Subscription::SharedPtr m_script_sub; 83 | std::unique_ptr> m_secondary_stream; 84 | }; 85 | 86 | int main(int argc, char** argv) 87 | { 88 | rclcpp::init(argc, argv); 89 | rclcpp::spin(std::make_unique()); 90 | rclcpp::shutdown(); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /ur_robot_driver/test/dashboard_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2019, FZI Forschungszentrum Informatik 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the {copyright_holder} nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | # POSSIBILITY OF SUCH DAMAGE. 29 | import os 30 | import sys 31 | import time 32 | import unittest 33 | 34 | import pytest 35 | import rclpy 36 | from rclpy.node import Node 37 | from ur_dashboard_msgs.msg import RobotMode 38 | 39 | sys.path.append(os.path.dirname(__file__)) 40 | from test_common import DashboardInterface, generate_dashboard_test_description # noqa: E402 41 | 42 | 43 | @pytest.mark.launch_test 44 | def generate_test_description(): 45 | return generate_dashboard_test_description() 46 | 47 | 48 | class DashboardClientTest(unittest.TestCase): 49 | @classmethod 50 | def setUpClass(cls): 51 | # Initialize the ROS context 52 | rclpy.init() 53 | cls.node = Node("dashboard_client_test") 54 | cls.init_robot(cls) 55 | 56 | @classmethod 57 | def tearDownClass(cls): 58 | # Shutdown the ROS context 59 | cls.node.destroy_node() 60 | rclpy.shutdown() 61 | 62 | def init_robot(self): 63 | self._dashboard_interface = DashboardInterface(self.node) 64 | 65 | def test_switch_on(self): 66 | """Test power on a robot.""" 67 | # Wait until the robot is booted completely 68 | end_time = time.time() + 10 69 | mode = RobotMode.DISCONNECTED 70 | while mode != RobotMode.POWER_OFF and time.time() < end_time: 71 | time.sleep(0.1) 72 | result = self._dashboard_interface.get_robot_mode() 73 | self.assertTrue(result.success) 74 | mode = result.robot_mode.mode 75 | 76 | # Power on robot 77 | self.assertTrue(self._dashboard_interface.power_on().success) 78 | 79 | # Wait until robot mode changes 80 | end_time = time.time() + 10 81 | mode = RobotMode.DISCONNECTED 82 | while mode not in (RobotMode.IDLE, RobotMode.RUNNING) and time.time() < end_time: 83 | time.sleep(0.1) 84 | result = self._dashboard_interface.get_robot_mode() 85 | self.assertTrue(result.success) 86 | mode = result.robot_mode.mode 87 | 88 | self.assertIn(mode, (RobotMode.IDLE, RobotMode.RUNNING)) 89 | 90 | # Release robot brakes 91 | self.assertTrue(self._dashboard_interface.brake_release().success) 92 | 93 | # Wait until robot mode is RUNNING 94 | end_time = time.time() + 10 95 | mode = RobotMode.DISCONNECTED 96 | while mode != RobotMode.RUNNING and time.time() < end_time: 97 | time.sleep(0.1) 98 | result = self._dashboard_interface.get_robot_mode() 99 | self.assertTrue(result.success) 100 | mode = result.robot_mode.mode 101 | 102 | self.assertEqual(mode, RobotMode.RUNNING) 103 | -------------------------------------------------------------------------------- /ur_robot_driver/test/example_move.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright 2019, FZI Forschungszentrum Informatik 3 | # 4 | # Redistribution and use in source and binary forms, with or without 5 | # modification, are permitted provided that the following conditions are met: 6 | # 7 | # * Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 10 | # * Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # * Neither the name of the {copyright_holder} nor the names of its 15 | # contributors may be used to endorse or promote products derived from 16 | # this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | # POSSIBILITY OF SUCH DAMAGE. 29 | 30 | import os 31 | import subprocess 32 | import sys 33 | import time 34 | import unittest 35 | 36 | import rclpy 37 | from rclpy.node import Node as ROSNode 38 | 39 | sys.path.append(os.path.dirname(__file__)) 40 | from test_common import ( # noqa: E402 41 | generate_driver_test_description, 42 | DashboardInterface, 43 | IoStatusInterface, 44 | ) 45 | 46 | 47 | def generate_test_description(): 48 | ld = generate_driver_test_description() 49 | return ld 50 | 51 | 52 | class ExampleMoveTest(unittest.TestCase): 53 | @classmethod 54 | def setUpClass(cls): 55 | # Initialize the ROS context 56 | rclpy.init() 57 | cls.node = ROSNode("example_move_test") 58 | time.sleep(1) 59 | cls.init_robot(cls) 60 | 61 | @classmethod 62 | def tearDownClass(cls): 63 | # Shutdown the ROS context 64 | cls.node.destroy_node() 65 | rclpy.shutdown() 66 | 67 | def init_robot(self): 68 | self._dashboard_interface = DashboardInterface(self.node) 69 | self._io_status_controller_interface = IoStatusInterface(self.node) 70 | 71 | def setUp(self): 72 | self._dashboard_interface.start_robot() 73 | time.sleep(1) 74 | self.assertTrue(self._io_status_controller_interface.resend_robot_program().success) 75 | 76 | def test_example_move(self): 77 | cmd = ["ros2", "run", "ur_robot_driver", "example_move.py"] 78 | subprocess.check_output(cmd) 79 | -------------------------------------------------------------------------------- /ur_robot_driver/ur_robot_driver/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_ROS2_Driver/6a3be3f14918c4df9f3a934f04061116b1a9d221/ur_robot_driver/ur_robot_driver/__init__.py --------------------------------------------------------------------------------