├── .clang-format ├── .clang-tidy ├── .github ├── ISSUE_TEMPLATE │ ├── new_feature.yaml │ └── ros_bug.yaml ├── codecov.yml ├── dependabot.yml └── workflows │ ├── check_links.yml │ ├── ci.yml │ ├── industrial-ci.yml │ ├── pre-commit.yml │ ├── prerelease.yml │ ├── sphinx_build.yml │ └── win-build.yml ├── .gitignore ├── .markdownlint.yaml ├── .pre-commit-config.yaml ├── .rosdoc_ignore_patterns ├── .simplecov ├── 3rdparty └── endian │ └── endian.h ├── CHANGELOG.rst ├── CMakeLists.txt ├── Gemfile ├── LICENSE_apache_2_0 ├── README.md ├── colcon.pkg ├── doc ├── _static │ ├── css │ │ └── ur_theme.css │ └── images │ │ ├── icon.svg │ │ └── ur_logo.svg ├── api_reference.rst ├── architecture.rst ├── architecture │ ├── dashboard_client.rst │ ├── instruction_executor.rst │ ├── reverse_interface.rst │ ├── rtde_client.rst │ ├── script_command_interface.rst │ ├── script_reader.rst │ ├── script_sender.rst │ ├── trajectory_point_interface.rst │ └── ur_driver.rst ├── conf.py ├── examples.rst ├── examples │ ├── dashboard_client.rst │ ├── force_mode.rst │ ├── freedrive.rst │ ├── instruction_executor.rst │ ├── primary_pipeline.rst │ ├── primary_pipeline_calibration.rst │ ├── rtde_client.rst │ ├── script_sender.rst │ ├── spline_example.rst │ ├── tool_contact_example.rst │ ├── trajectory_point_interface.rst │ └── ur_driver.rst ├── images │ ├── 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 │ │ ├── px_01_welcome.png │ │ ├── px_05_urcaps_installed.png │ │ ├── px_07_installation_excontrol.png │ │ ├── px_10_prog_structure_urcaps.png │ │ ├── px_11_program_view_excontrol.png │ │ ├── remote_control.png │ │ ├── services_polyscope5.png │ │ └── services_polyscopex.png │ ├── trajectory_interface.drawio │ ├── trajectory_interface.svg │ ├── urcl_architecture.drawio │ └── urcl_architecture.svg ├── index.rst ├── installation.rst ├── migration_notes.rst ├── polyscope_compatibility.rst ├── real_time.rst ├── resources │ ├── family_photo.png │ ├── fzi-logo_transparenz.png │ └── ur_logo.jpg ├── setup.rst └── setup │ ├── network_setup.rst │ ├── robot_setup.rst │ └── ursim_docker.rst ├── doc_requirements.txt ├── examples ├── CMakeLists.txt ├── dashboard_example.cpp ├── force_mode_example.cpp ├── freedrive_example.cpp ├── full_driver.cpp ├── instruction_executor.cpp ├── primary_pipeline.cpp ├── primary_pipeline_calibration.cpp ├── resources │ ├── rtde_input_recipe.txt │ └── rtde_output_recipe.txt ├── rtde_client.cpp ├── script_sender.cpp ├── spline_example.cpp ├── tool_contact_example.cpp └── trajectory_point_interface.cpp ├── include └── ur_client_library │ ├── comm │ ├── bin_parser.h │ ├── control_mode.h │ ├── package.h │ ├── package_serializer.h │ ├── parser.h │ ├── pipeline.h │ ├── producer.h │ ├── shell_consumer.h │ ├── socket_t.h │ ├── stream.h │ ├── tcp_server.h │ └── tcp_socket.h │ ├── control │ ├── motion_primitives.h │ ├── reverse_interface.h │ ├── script_command_interface.h │ ├── script_reader.h │ ├── script_sender.h │ └── trajectory_point_interface.h │ ├── default_log_handler.h │ ├── example_robot_wrapper.h │ ├── exceptions.h │ ├── helpers.h │ ├── log.h │ ├── primary │ ├── .clang-tidy │ ├── abstract_primary_consumer.h │ ├── package_header.h │ ├── primary_client.h │ ├── primary_consumer.h │ ├── primary_package.h │ ├── primary_parser.h │ ├── robot_message.h │ ├── robot_message │ │ ├── error_code_message.h │ │ └── version_message.h │ ├── robot_state.h │ └── robot_state │ │ ├── configuration_data.h │ │ ├── kinematics_info.h │ │ └── robot_mode_data.h │ ├── queue │ ├── .clang-tidy │ ├── LICENSE.md │ ├── atomicops.h │ └── readerwriterqueue.h │ ├── rtde │ ├── .clang-tidy │ ├── control_package_pause.h │ ├── control_package_setup_inputs.h │ ├── control_package_setup_outputs.h │ ├── control_package_start.h │ ├── data_package.h │ ├── get_urcontrol_version.h │ ├── package_header.h │ ├── request_protocol_version.h │ ├── rtde_client.h │ ├── rtde_package.h │ ├── rtde_parser.h │ ├── rtde_writer.h │ └── text_message.h │ ├── types.h │ └── ur │ ├── calibration_checker.h │ ├── dashboard_client.h │ ├── datatypes.h │ ├── instruction_executor.h │ ├── robot_receive_timeout.h │ ├── tool_communication.h │ ├── ur_driver.h │ └── version_information.h ├── package.xml ├── resources └── external_control.urscript ├── rosdoc.yaml ├── run_examples.sh ├── scripts └── start_ursim.sh ├── src ├── comm │ ├── tcp_server.cpp │ └── tcp_socket.cpp ├── control │ ├── motion_primitives.cpp │ ├── reverse_interface.cpp │ ├── script_command_interface.cpp │ ├── script_reader.cpp │ ├── script_sender.cpp │ └── trajectory_point_interface.cpp ├── default_log_handler.cpp ├── example_robot_wrapper.cpp ├── helpers.cpp ├── log.cpp ├── primary │ ├── primary_client.cpp │ ├── primary_package.cpp │ ├── robot_message.cpp │ ├── robot_message │ │ ├── error_code_message.cpp │ │ └── version_message.cpp │ ├── robot_state.cpp │ └── robot_state │ │ ├── configuration_data.cpp │ │ ├── kinematics_info.cpp │ │ └── robot_mode_data.cpp ├── rtde │ ├── control_package_pause.cpp │ ├── control_package_setup_inputs.cpp │ ├── control_package_setup_outputs.cpp │ ├── control_package_start.cpp │ ├── data_package.cpp │ ├── get_urcontrol_version.cpp │ ├── request_protocol_version.cpp │ ├── rtde_client.cpp │ ├── rtde_package.cpp │ ├── rtde_writer.cpp │ └── text_message.cpp └── ur │ ├── calibration_checker.cpp │ ├── dashboard_client.cpp │ ├── instruction_executor.cpp │ ├── robot_receive_timeout.cpp │ ├── tool_communication.cpp │ ├── ur_driver.cpp │ └── version_information.cpp ├── tests ├── CMakeLists.txt ├── resources │ ├── dockerursim │ │ └── programs │ │ │ ├── cb3 │ │ │ ├── default.installation │ │ │ ├── default.variables │ │ │ ├── external_control.urp │ │ │ ├── programs.UR5 │ │ │ └── wait_program.urp │ │ │ └── e-series │ │ │ ├── default.installation │ │ │ ├── default.variables │ │ │ ├── external_control.urp │ │ │ ├── programs.UR5 │ │ │ └── wait_program.urp │ ├── empty.txt │ ├── example_urscript_feature.urscript │ ├── example_urscript_main.urscript │ ├── exhaustive_rtde_output_recipe.txt │ ├── rtde_input_recipe.txt │ ├── rtde_output_recipe.txt │ ├── rtde_output_recipe_spline.txt │ └── rtde_output_recipe_without_timestamp.txt ├── test_bin_parser.cpp ├── test_control_mode.cpp ├── test_dashboard_client.cpp ├── test_deprecated_ur_driver_construction.cpp ├── test_helpers.cpp ├── test_instruction_executor.cpp ├── test_package_serializer.cpp ├── test_pipeline.cpp ├── test_primary_client.cpp ├── test_primary_parser.cpp ├── test_producer.cpp ├── test_reverse_interface.cpp ├── test_robot_receive_timeout.cpp ├── test_rtde_client.cpp ├── test_rtde_control_package_pause.cpp ├── test_rtde_control_package_setup_inputs.cpp ├── test_rtde_control_package_setup_outputs.cpp ├── test_rtde_control_package_start.cpp ├── test_rtde_data_package.cpp ├── test_rtde_get_urcontrol_version.cpp ├── test_rtde_parser.cpp ├── test_rtde_request_protocol_version.cpp ├── test_rtde_writer.cpp ├── test_script_command_interface.cpp ├── test_script_reader.cpp ├── test_script_sender.cpp ├── test_spline_interpolation.cpp ├── test_start_ursim.bats ├── test_stream.cpp ├── test_tcp_server.cpp ├── test_tcp_socket.cpp ├── test_trajectory_point_interface.cpp ├── test_ur_driver.cpp ├── test_utils.h └── test_version_information.cpp └── ur_client_libraryConfig.cmake /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: -2 3 | AlignEscapedNewlinesLeft: false 4 | AlignTrailingComments: true 5 | AllowAllParametersOfDeclarationOnNextLine: false 6 | AllowShortFunctionsOnASingleLine: None 7 | AllowShortIfStatementsOnASingleLine: false 8 | AllowShortLoopsOnASingleLine: false 9 | AlwaysBreakBeforeMultilineStrings: false 10 | AlwaysBreakTemplateDeclarations: true 11 | BasedOnStyle: Google 12 | BinPackParameters: true 13 | 14 | BraceWrapping: # Control of individual brace wrapping cases 15 | AfterCaseLabel: 'true' 16 | AfterClass: 'true' 17 | AfterControlStatement: 'true' 18 | AfterEnum: 'true' 19 | AfterFunction: 'true' 20 | AfterNamespace: 'true' 21 | AfterStruct: 'true' 22 | AfterUnion: 'true' 23 | BeforeCatch: 'true' 24 | BeforeElse: 'true' 25 | IndentBraces: 'false' 26 | 27 | BreakBeforeBinaryOperators: false 28 | BreakBeforeTernaryOperators: false 29 | BreakConstructorInitializersBeforeComma: true 30 | BreakBeforeBraces: Custom # Configure each individual brace in BraceWrapping 31 | 32 | ColumnLimit: 120 33 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 34 | ConstructorInitializerIndentWidth: 2 35 | ContinuationIndentWidth: 4 36 | Cpp11BracedListStyle: false 37 | DerivePointerBinding: false 38 | ExperimentalAutoDetectBinPacking: false 39 | IndentCaseLabels: true 40 | IndentFunctionDeclarationAfterType: false 41 | IndentPPDirectives: AfterHash 42 | IndentWidth: 2 43 | MaxEmptyLinesToKeep: 1 44 | NamespaceIndentation: None 45 | ObjCSpaceBeforeProtocolList: true 46 | PenaltyBreakBeforeFirstCallParameter: 19 47 | PenaltyBreakComment: 60 48 | PenaltyBreakFirstLessLess: 1000 49 | PenaltyBreakString: 1 50 | PenaltyExcessCharacter: 1000 51 | PenaltyReturnTypeOnItsOwnLine: 90 52 | PointerBindsToType: true 53 | SortIncludes: false 54 | SpaceAfterCStyleCast: false 55 | SpaceAfterControlStatementKeyword: true 56 | SpaceBeforeAssignmentOperators: true 57 | SpaceInEmptyParentheses: false 58 | SpacesBeforeTrailingComments: 2 59 | SpacesInAngles: false 60 | SpacesInCStyleCastParentheses: false 61 | SpacesInParentheses: false 62 | Standard: Auto 63 | TabWidth: 2 64 | UseTab: Never 65 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,readability-identifier-naming' 2 | CheckOptions: 3 | - { key: readability-identifier-naming.NamespaceCase, value: lower_case } 4 | - { key: readability-identifier-naming.ClassCase, value: CamelCase } 5 | - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ } 6 | - { key: readability-identifier-naming.PublicMemberSuffix, value: "" } 7 | - { key: readability-identifier-naming.StructCase, value: CamelCase } 8 | - { key: readability-identifier-naming.FunctionCase, value: camelBack } 9 | - { key: readability-identifier-naming.VariableCase, value: lower_case } 10 | - { key: readability-identifier-naming.GlobalVariablePrefix, value: g_ } 11 | - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } 12 | -------------------------------------------------------------------------------- /.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/codecov.yml: -------------------------------------------------------------------------------- 1 | #To validate before committing: 'curl -X POST --data-binary @codecov.yml https://codecov.io/validate' 2 | 3 | codecov: 4 | strict_yaml_branch: default # only use the latest YAML on stated branch 5 | 6 | ignore: 7 | - "examples/*" # ignore examples 8 | - "tests/*" # ignore unit tests -------------------------------------------------------------------------------- /.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/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, 403, 404, 502' 31 | --max-cache-age 2d 32 | --exclude '^http://192\.168\.56\.101' 33 | --exclude 'kernel\.org\/pub\/linux\/kernel' 34 | --exclude 'releases/download/v\$%7BURCAP_VERSION%7D/externalcontrol-\$%7BURCAP_VERSION%7D\.jar' 35 | --exclude '^http://rosin-project\.eu' 36 | --exclude '2013181\/gdb-causes-sem-wait-to-fail-with-eintr-error' 37 | --max-concurrency 1 38 | './**/*.md' './**/*.html' './**/*.rst' './**/*.cpp' './**/*.h' './**/*.py' 39 | - name: Save lychee cache 40 | uses: actions/cache/save@v4 41 | if: always() 42 | with: 43 | path: .lycheecache 44 | key: ${{ steps.restore-cache.outputs.cache-primary-key }} 45 | -------------------------------------------------------------------------------- /.github/workflows/industrial-ci.yml: -------------------------------------------------------------------------------- 1 | name: ROS industrial ci 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | industrial_ci: 11 | name: ${{matrix.ROS_DISTRO.NAME}}, ${{matrix.ROS_REPO}} 12 | runs-on: ubuntu-latest 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | ROS_DISTRO: 17 | - NAME: noetic 18 | DOWNSTREAM_WORKSPACE: "github:UniversalRobots/Universal_Robots_ROS_Driver#master" 19 | - NAME: humble 20 | DOWNSTREAM_WORKSPACE: "github:UniversalRobots/Universal_Robots_ROS2_Driver#humble" 21 | - NAME: jazzy 22 | DOWNSTREAM_WORKSPACE: "github:UniversalRobots/Universal_Robots_ROS2_Driver#jazzy" 23 | - NAME: kilted 24 | DOWNSTREAM_WORKSPACE: "github:UniversalRobots/Universal_Robots_ROS2_Driver#main" 25 | - NAME: rolling 26 | DOWNSTREAM_WORKSPACE: "github:UniversalRobots/Universal_Robots_ROS2_Driver#main" 27 | ROS_REPO: 28 | - main 29 | - testing 30 | env: 31 | DOCKER_RUN_OPTS: '-v /var/run/docker.sock:/var/run/docker.sock --network ursim_net' 32 | steps: 33 | - uses: actions/checkout@v4 34 | - run: docker network create --subnet=192.168.56.0/24 ursim_net 35 | if: ${{ !env.ACT }} 36 | - uses: 'ros-industrial/industrial_ci@master' 37 | env: 38 | IMMEDIATE_TEST_OUTPUT: true 39 | DOWNSTREAM_CMAKE_ARGS: -DUR_ROBOT_DRIVER_BUILD_INTEGRATION_TESTS=ON 40 | ADDITIONAL_DEBS: docker.io netcat-openbsd # Needed for integration tests 41 | DOWNSTREAM_WORKSPACE: ${{matrix.ROS_DISTRO.DOWNSTREAM_WORKSPACE}} 42 | ROS_DISTRO: ${{matrix.ROS_DISTRO.NAME}} 43 | ROS_REPO: ${{matrix.ROS_REPO}} 44 | CLANG_TIDY: pedantic 45 | CLANG_TIDY_ARGS: '--extra-arg=-std=c++17' # needed for Humble 46 | -------------------------------------------------------------------------------- /.github/workflows/pre-commit.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: pre-commit 5 | 6 | on: 7 | workflow_dispatch: 8 | pull_request: 9 | push: 10 | branches: 11 | - master 12 | 13 | jobs: 14 | pre-commit: 15 | name: pre-commit 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 | - uses: pre-commit/action@v3.0.1 23 | with: 24 | extra_args: --all-files --hook-stage manual 25 | 26 | -------------------------------------------------------------------------------- /.github/workflows/prerelease.yml: -------------------------------------------------------------------------------- 1 | name: ROS prerelease test 2 | on: 3 | pull_request: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | prerelease_test: 9 | runs-on: ubuntu-latest 10 | 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | include: 15 | - ROS_DISTRO: melodic 16 | OS_VERSION: bionic 17 | - ROS_DISTRO: noetic 18 | OS_VERSION: focal 19 | - ROS_DISTRO: humble 20 | OS_VERSION: jammy 21 | - ROS_DISTRO: iron 22 | OS_VERSION: jammy 23 | - ROS_DISTRO: jazzy 24 | OS_VERSION: noble 25 | - ROS_DISTRO: rolling 26 | OS_VERSION: noble 27 | 28 | steps: 29 | - uses: actions/checkout@v4 30 | - run: sudo apt-get install -y python3-pip 31 | - run: sudo pip3 install empy==3.3.4 # Added as bloom not yet support empy v4 32 | - run: sudo pip3 install bloom rosdep 33 | - run: sudo rosdep init 34 | - run: rosdep update --rosdistro=${{ matrix.ROS_DISTRO }} 35 | - run: bloom-generate rosdebian --ros-distro ${{ matrix.ROS_DISTRO }} --os-name ubuntu --os-version ${{ matrix.OS_VERSION }} 36 | -------------------------------------------------------------------------------- /.github/workflows/sphinx_build.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Build documentation" 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | schedule: 10 | - cron: '38 2 * * *' 11 | 12 | jobs: 13 | docs: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: write 17 | concurrency: 18 | group: ${{ github.workflow }}-${{ github.ref }} 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: actions/setup-python@v5 22 | with: 23 | cache: 'pip' 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip 27 | pip install -r doc_requirements.txt 28 | - name: Build documentation 29 | run: | 30 | sphinx-build -W -b html doc _doc_build 31 | -------------------------------------------------------------------------------- /.github/workflows/win-build.yml: -------------------------------------------------------------------------------- 1 | name: Windows build and tests 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | win-build: 11 | timeout-minutes: 30 12 | runs-on: windows-2022 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: configure 17 | run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1 18 | #run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1 -DINTEGRATION_TESTS=1 19 | - name: build 20 | run: cmake --build build --config Debug 21 | - name: test 22 | run: cd build && ctest --output-on-failure -C Debug 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeCache.txt 2 | CMakeFiles 3 | Makefile 4 | cmake_install.cmake 5 | install_manifest.txt 6 | *~ 7 | .idea 8 | .directory 9 | .vscode 10 | build/ -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | MD013: 3 | line_length: 100 4 | MD033: 5 | allowed_elements: [img, a] 6 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/mirrors-clang-format 3 | rev: 'v19.1.5' 4 | hooks: 5 | - id: clang-format 6 | - repo: https://github.com/DavidAnson/markdownlint-cli2 7 | rev: v0.13.0 8 | hooks: 9 | - id: markdownlint-cli2 10 | exclude: "include/ur_client_library/queue/LICENSE.md" 11 | - repo: https://github.com/sphinx-contrib/sphinx-lint 12 | rev: v0.9.1 13 | hooks: 14 | - id: sphinx-lint 15 | -------------------------------------------------------------------------------- /.rosdoc_ignore_patterns: -------------------------------------------------------------------------------- 1 | To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u" 2 | warning: Tag 'TCL_SUBST' at line [0-9]+ of file '[a-zA-Z0-9_/]+' has become obsolete. 3 | warning: Tag 'COLS_IN_ALPHA_INDEX' at line 986 of file '[a-zA-Z0-9_/]+' has become obsolete. 4 | warning: Tag 'PERL_PATH' at line [0-9]+ of file '[a-zA-Z0-9_/]+' has become obsolete. 5 | warning: Tag 'MSCGEN_PATH' at line [0-9]+ of file '[a-zA-Z0-9_/]+' has become obsolete. 6 | warning: argument 'a4wide' for option PAPER_TYPE is not a valid enum value 7 | Using the default: a4! 8 | warning: tag INCLUDE_PATH: include path '\$INCLUDE_PATH' does not exist 9 | warning: source '\$INCLUDE_PATH' is not a readable file or directory... skipping. 10 | warning: source \$INCLUDE_PATH is not a readable file or directory... skipping. 11 | ^$ 12 | -------------------------------------------------------------------------------- /.simplecov: -------------------------------------------------------------------------------- 1 | require 'simplecov' 2 | require 'simplecov-cobertura' 3 | 4 | SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter 5 | -------------------------------------------------------------------------------- /3rdparty/endian/endian.h: -------------------------------------------------------------------------------- 1 | // 2 | // endian.h 3 | // 4 | // https://gist.github.com/panzi/6856583 5 | // 6 | // I, Mathias Panzenböck, place this file hereby into the public domain. Use 7 | // it at your own risk for whatever you like. In case there are 8 | // jurisdictions that don't support putting things in the public domain you 9 | // can also consider it to be "dual licensed" under the BSD, MIT and Apache 10 | // licenses, if you want to. This code is trivial anyway. Consider it an 11 | // example on how to get the endian conversion functions on different 12 | // platforms. 13 | 14 | #ifndef PORTABLE_ENDIAN_H__ 15 | #define PORTABLE_ENDIAN_H__ 16 | 17 | // Byte order 18 | #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__CYGWIN__) 19 | # include 20 | #elif defined(__APPLE__) 21 | # include 22 | 23 | # define htobe16(x) OSSwapHostToBigInt16(x) 24 | # define htole16(x) OSSwapHostToLittleInt16(x) 25 | # define be16toh(x) OSSwapBigToHostInt16(x) 26 | # define le16toh(x) OSSwapLittleToHostInt16(x) 27 | 28 | # define htobe32(x) OSSwapHostToBigInt32(x) 29 | # define htole32(x) OSSwapHostToLittleInt32(x) 30 | # define be32toh(x) OSSwapBigToHostInt32(x) 31 | # define le32toh(x) OSSwapLittleToHostInt32(x) 32 | 33 | # define htobe64(x) OSSwapHostToBigInt64(x) 34 | # define htole64(x) OSSwapHostToLittleInt64(x) 35 | # define be64toh(x) OSSwapBigToHostInt64(x) 36 | # define le64toh(x) OSSwapLittleToHostInt64(x) 37 | 38 | # define __BYTE_ORDER BYTE_ORDER 39 | # define __BIG_ENDIAN BIG_ENDIAN 40 | # define __LITTLE_ENDIAN LITTLE_ENDIAN 41 | # define __PDP_ENDIAN PDP_ENDIAN 42 | #elif defined(__OpenBSD__) 43 | # include 44 | #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) 45 | # include 46 | 47 | # define be16toh(x) betoh16(x) 48 | # define le16toh(x) letoh16(x) 49 | 50 | # define be32toh(x) betoh32(x) 51 | # define le32toh(x) letoh32(x) 52 | 53 | # define be64toh(x) betoh64(x) 54 | # define le64toh(x) letoh64(x) 55 | #elif defined(_WIN32) 56 | # include 57 | # if BYTE_ORDER == LITTLE_ENDIAN 58 | # if defined(_MSC_VER) 59 | # define htobe16(x) _byteswap_ushort(x) 60 | # define htole16(x) (x) 61 | # define be16toh(x) _byteswap_ushort(x) 62 | # define le16toh(x) (x) 63 | 64 | # define htobe32(x) _byteswap_ulong(x) 65 | # define htole32(x) (x) 66 | # define be32toh(x) _byteswap_ulong(x) 67 | # define le32toh(x) (x) 68 | 69 | # define htobe64(x) _byteswap_uint64(x) 70 | # define htole64(x) (x) 71 | # define be64toh(x) _byteswap_uint64(x) 72 | # define le64toh(x) (x) 73 | # elif defined(__GNUC__) || defined(__clang__) 74 | # define htobe16(x) __builtin_bswap16(x) 75 | # define htole16(x) (x) 76 | # define be16toh(x) __builtin_bswap16(x) 77 | # define le16toh(x) (x) 78 | 79 | # define htobe32(x) __builtin_bswap32(x) 80 | # define htole32(x) (x) 81 | # define be32toh(x) __builtin_bswap32(x) 82 | # define le32toh(x) (x) 83 | 84 | # define htobe64(x) __builtin_bswap64(x) 85 | # define htole64(x) (x) 86 | # define be64toh(x) __builtin_bswap64(x) 87 | # define le64toh(x) (x) 88 | # else 89 | # error Compiler is not supported 90 | # endif 91 | # else 92 | # error Byte order is not supported 93 | # endif 94 | 95 | # define __BYTE_ORDER BYTE_ORDER 96 | # define __BIG_ENDIAN BIG_ENDIAN 97 | # define __LITTLE_ENDIAN LITTLE_ENDIAN 98 | # define __PDP_ENDIAN PDP_ENDIAN 99 | #else 100 | # error Platform is not supported 101 | #endif 102 | 103 | #endif // PORTABLE_ENDIAN_H__ 104 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # Used vor bashcov coverage tool for the shell script 2 | # frozen_string_literal: true 3 | 4 | source 'https://rubygems.org' 5 | 6 | gem 'bashcov' 7 | gem 'simplecov' 8 | gem 'simplecov-cobertura' 9 | -------------------------------------------------------------------------------- /colcon.pkg: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": [ 3 | "share/ur_client_library/hook/ament_prefix_path.dsv", 4 | "share/ur_client_library/hook/ros_package_path.dsv", 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /doc/_static/images/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /doc/api_reference.rst: -------------------------------------------------------------------------------- 1 | C++ API Reference 2 | ================= 3 | 4 | There is a generated API documentation as a part of the ROS package documentation: 5 | 6 | https://docs.ros.org/en/rolling/p/ur_client_library/generated/index.html 7 | 8 | It is generated directly from the source code using Doxygen. Though the documentation is hosted 9 | inside the ROS documentation structure, it is not a ROS-specific API. The API is the same for all 10 | platforms. 11 | -------------------------------------------------------------------------------- /doc/architecture.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture.rst 2 | 3 | Library architecture 4 | ==================== 5 | 6 | This library implements the bare communication protocols used to communicate with the robot, as 7 | well as a couple of standalone modules to directly use subsets of the library's functionality: 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | architecture/dashboard_client 13 | architecture/reverse_interface 14 | architecture/rtde_client 15 | architecture/script_command_interface 16 | architecture/script_reader 17 | architecture/script_sender 18 | architecture/trajectory_point_interface 19 | architecture/ur_driver 20 | architecture/instruction_executor 21 | 22 | 23 | Dataflow overview with UrDriver 24 | ------------------------------- 25 | 26 | The image below shows a rough architecture overview that should help developers to use the different 27 | modules present in this library. Note that this is an incomplete view on the classes involved. 28 | 29 | .. image:: images/urcl_architecture.svg 30 | :width: 1200 31 | :alt: architecture overview 32 | -------------------------------------------------------------------------------- /doc/architecture/dashboard_client.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture/dashboard_client.rst 2 | 3 | .. _dashboard_client: 4 | 5 | DashboardClient 6 | =============== 7 | 8 | The ``DashboardClient`` wraps the calls on the `Dashboard server `_ 9 | directly into C++ functions. 10 | 11 | After connecting to the dashboard server by using the ``connect()`` function, dashboard calls can be 12 | sent using the ``sendAndReceive()`` function. Answers from the dashboard server will be returned as 13 | string from this function. If no answer is received, a ``UrException`` is thrown. 14 | 15 | Some functions are also wrapped into ``command...()`` functions such as 16 | ``commandCloseSafetyPopup()``. These functions are blocking and will wait for the necessary action 17 | being done. This can involve querying another call to the dashboard server until the action is 18 | done. For example, ``commandPowerOn()`` will block until the robot reports "Robotmode: RUNNING" or 19 | the given timeout is reached. 20 | 21 | The `dashboard_example.cpp `_ shows how to use this class: 22 | 23 | .. literalinclude:: ../../examples/dashboard_example.cpp 24 | :language: c++ 25 | :caption: examples/dashboard_example.cpp 26 | :linenos: 27 | :lineno-match: 28 | :start-at: std::make_unique 29 | :end-at: my_dashboard->commandCloseSafetyPopup(); 30 | -------------------------------------------------------------------------------- /doc/architecture/instruction_executor.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture/instruction_executor.rst 2 | 3 | .. _instruction_executor: 4 | 5 | Instruction Executor 6 | ==================== 7 | 8 | The Instruction Executor is a convenience wrapper to make common robot instructions such as point 9 | to point motions easily accessible. Currently, it supports the following instructions: 10 | 11 | * Execute MoveJ point to point motions 12 | * Execute MoveL point to point motions 13 | * Execute MoveP point to point motions 14 | * Execute MoveC circular motions 15 | * Execute OptimoveJ point to point motions (For PolyScope 5.21 / PolyScope 10.8 and later) 16 | * Execute OptimoveL point to point motions (For PolyScope 5.21 / PolyScope 10.8 and later) 17 | * Execute sequences consisting of the motion primitives above 18 | 19 | The Instruction Executor uses the :ref:`trajectory_point_interface` and the 20 | :ref:`reverse_interface` 21 | for sending motion instructions to the robot. Hence, it requires a :ref:`ur_driver` object. 22 | 23 | .. note:: 24 | The ``InstructionExecutor`` simply forwards the trajectory points to the robot. Execution 25 | is done using respective URScript functions such as `movej 26 | `_ 27 | or `movel 28 | `_. 29 | Therefore, all parameters and restrictions of these functions apply. For example, velocity and 30 | acceleration parameters will be ignored if there is a time > 0 given. 31 | 32 | As a minimal working example, please see the :ref:`instruction_executor_example`. 33 | -------------------------------------------------------------------------------- /doc/architecture/rtde_client.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture/rtde_client.rst 2 | 3 | .. _rtde_client: 4 | 5 | RTDEClient 6 | ========== 7 | 8 | The Real Time Data Exchange Client, ``RTDEClient``, class serves as a standalone 9 | `RTDE `_ 10 | client. To use the RTDE-Client, you'll have to initialize and start it separately: 11 | 12 | .. code-block:: c++ 13 | 14 | rtde_interface::RTDEClient my_client(ROBOT_IP, notifier, OUTPUT_RECIPE, INPUT_RECIPE); 15 | my_client.init(); 16 | my_client.start(); 17 | while (true) 18 | { 19 | std::unique_ptr data_pkg = my_client.getDataPackage(READ_TIMEOUT); 20 | if (data_pkg) 21 | { 22 | std::cout << data_pkg->toString() << std::endl; 23 | } 24 | } 25 | 26 | Upon construction, two recipe files have to be given, one for the RTDE inputs, one for the RTDE 27 | outputs. Please refer to the `RTDE 28 | guide `_ 29 | on which elements are available. 30 | 31 | Inside the ``RTDEclient`` data is received in a separate thread, parsed by the ``RTDEParser`` and 32 | added to a pipeline queue. 33 | 34 | Right after calling ``my_client.start()``, it should be made sure to read the buffer from the 35 | ``RTDEClient`` by calling ``getDataPackage()`` frequently. The Client's queue can only contain a 36 | restricted number of items at a time, so a ``Pipeline producer overflowed!`` error will be raised 37 | if the buffer isn't read frequently enough. 38 | 39 | For writing data to the RTDE interface, use the ``RTDEWriter`` member of the ``RTDEClient``. It can be 40 | retrieved by calling ``getWriter()`` method. The ``RTDEWriter`` provides convenience methods to write 41 | all data available at the RTDE interface. Make sure that the required keys are configured inside the 42 | input recipe, as otherwise the send-methods will return ``false`` if the data field is not setup in 43 | the recipe. 44 | 45 | An example of a standalone RTDE-client can be found in the ``examples`` subfolder. To run it make 46 | sure to 47 | 48 | * have an instance of a robot controller / URSim running at the configured IP address (or adapt the 49 | address to your needs) 50 | * run it from the package's main folder, as for simplicity reasons it doesn't use any sophisticated 51 | method to locate the required files. 52 | 53 | .. note:: 54 | The ``URDriver`` class creates a ``RTDEClient`` during initialization using the provided 55 | recipes and utilizing the robot model's maximum frequency. If you would like to use a different 56 | frequency, please use the ``resetRTDEClient()`` method after the ``UrDriver`` object has been 57 | created. 58 | 59 | RTDEWriter 60 | ---------- 61 | 62 | The ``RTDEWriter`` class provides an interface to write data to the RTDE interface. Data fields that 63 | should be written have to be defined inside the ``INPUT_RECIPE`` as noted above. 64 | 65 | The class offers specific methods for every RTDE input possible to write. 66 | 67 | Data is sent asynchronously to the RTDE interface. 68 | 69 | -------------------------------------------------------------------------------- /doc/architecture/script_sender.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture/script_sender.rst 2 | 3 | .. _script_sender: 4 | 5 | ScriptSender 6 | ============ 7 | 8 | The ``ScriptSender`` class opens a tcp socket listens for "*request_program*" request. Upon such a 9 | request, a predefined URScript code is sent to the caller. The script code itself has to be passed 10 | to the ``ScriptSender``'s constructor. 11 | 12 | Use this class in conjunction with the `External Control URCap 13 | `_ which will make the 14 | corresponding request when starting a program on the robot that contains the **External Control** 15 | program node. In order to work properly, make sure that the IP address and script sender port are 16 | configured correctly on the robot. 17 | 18 | An example of how to use the ``ScriptSender`` class can be found in the :ref:`script_sender_example`. 19 | 20 | .. note:: 21 | PolyScope X users cannot use the URCap linked above. There is a development version of a URCapX 22 | available at https://github.com/UniversalRobots/Universal_Robots_ExternalControl_URCapX. 23 | -------------------------------------------------------------------------------- /doc/architecture/trajectory_point_interface.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture/trajectory_point_interface.rst 2 | 3 | .. _trajectory_point_interface: 4 | 5 | Trajectory Point Interface 6 | ========================== 7 | 8 | The ``TrajectoryPointInterface`` allows sending trajectory points to the robot. It is intended to 9 | be used in conjunction with the :ref:`reverse_interface` during trajectory forwarding. 10 | 11 | Communication regarding trajectory point execution would usually look like this: 12 | 13 | .. figure:: ../images/trajectory_interface.svg 14 | :width: 1200 15 | :alt: Trajectory interface 16 | 17 | Basically, the ``TrajectoryPointInterface`` transfers the trajectory points from the external 18 | control PC to the robot for execution. Execution isn't started, before a start command is sent via 19 | the ``ReverseInterface``. Once trajectory execution is done (either successful, failed or canceled 20 | externally), the robot will send a response back to the control PC via the trajectory socket. 21 | 22 | .. note:: 23 | The ``TrajectoryPointInterface`` simply forwards the trajectory points to the robot. Execution 24 | is done using respective URScript functions such as `movej 25 | `_ 26 | or `movel 27 | `_. 28 | Therefore, all parameters and restrictions of these functions apply. For example, velocity and 29 | acceleration parameters will be ignored if there is a time > 0 given. 30 | 31 | 32 | Communication protocol 33 | ---------------------- 34 | 35 | The ``TrajectoryPointInterface``'s "trajectory_socket" on the robot is expecting 32 bit integer 36 | representations in 21 datafields. The data fields have the following meaning: 37 | 38 | .. table:: trajectory_socket message format 39 | :widths: auto 40 | 41 | ===== ===== 42 | index meaning 43 | ===== ===== 44 | 0-5 trajectory point positions (Multiplied by ``MULT_JOINTSTATE``) 45 | 6-11 trajectory point velocities (Multiplied by ``MULT_JOINTSTATE``). For MOVEC, this contains the "via pose". 46 | 12-17 trajectory point accelerations (Multiplied by ``MULT_JOINTSTATE``). 47 | 48 | For MOVEC: 49 | 50 | - 12: velocity (Multiplied by ``MULT_JOINTSTATE``) 51 | - 13: acceleration (Multiplied by ``MULT_JOINTSTATE``) 52 | - 14: mode (Multiplied by ``MULT_JOINTSTATE``) 53 | 54 | 18 trajectory point type 55 | 56 | - 0: MOVEJ 57 | - 1: MOVEL 58 | - 2: MOVEP 59 | - 3: MOVEC 60 | - 51: SPLINE) 61 | 62 | 19 trajectory point time (in seconds, multiplied by ``MULT_TIME``) 63 | 20 depending on trajectory point type 64 | 65 | - MOVEJ, MOVEL, MOVEP and MOVEC: point blend radius (in meters, multiplied by ``MULT_TIME``) 66 | - SPLINE: spline type (1: CUBIC, 2: QUINTIC) 67 | ===== ===== 68 | 69 | where 70 | 71 | - ``MULT_JOINTSTATE``: 1000000 72 | - ``MULT_TIME``: 1000 73 | -------------------------------------------------------------------------------- /doc/architecture/ur_driver.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/architecture/ur_driver.rst 2 | 3 | .. _ur_driver: 4 | 5 | UrDriver 6 | ======== 7 | 8 | The ``UrDriver`` class is the core of this library. It creates an interface to the robot containing 9 | all components from this library. 10 | 11 | When creating an instance of the ``UrDriver`` class, the created object will contain 12 | 13 | - a :ref:`DashboardClient ` 14 | - a :ref:`ReverseInterface ` 15 | - an :ref:`RTDEClient ` 16 | - a :ref:`ScriptCommandInterface ` 17 | - a :ref:`ScriptSender ` 18 | - a :ref:`TrajectoryPointInterface `. 19 | - a rudimentary client to the robot's primary interface 20 | - a couple of helper functions 21 | 22 | As this page is not meant to be a full-blown API documentation, not every public method will be 23 | explained here. For a full list of public methods, please inspect class definition in the 24 | `ur_client_library/ur/ur_driver.h 25 | `_ 26 | header file. 27 | 28 | Many functions from the individual components are directly wrapped in the ``UrDriver`` class, for 29 | example there is ``UrDriver::startForceMode(...)`` which is a wrapper around the 30 | ``ScriptCommandInterface::startForceMode(...)`` function. 31 | 32 | As an example on how to use this class, please see the `full_driver.cpp `_ example. 33 | 34 | Public helper functions 35 | ----------------------- 36 | 37 | ``checkCalibration(const std::string checksum)`` 38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 39 | 40 | This function opens a connection to the primary interface where it will receive a calibration 41 | information as the first message. The checksum from this calibration info is compared to the one 42 | given to this function. Connection to the primary interface is dropped afterwards. 43 | 44 | ``sendScript(const std::string& program)`` 45 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 46 | 47 | This function sends given URScript code directly to the primary interface. The 48 | ``sendRobotProgram()`` function is a special case that will send the script code given in the 49 | ``RTDEClient`` constructor. 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /doc/examples.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples.rst 2 | 3 | Usage examples 4 | ============== 5 | 6 | This library contains a number of examples how this library can be used. You can use them as a 7 | starting point for your own applications. 8 | 9 | All examples take a robot's IP address as a first argument and some of them take a maximum run 10 | duration (in seconds) as second argument. If the second argument is omitted, some of the examples 11 | may be running forever until manually stopped. 12 | 13 | .. note:: Most of these examples use the driver's headless mode. Therefore, on an e-Series (PolyScope 5) robot, the robot has to be 14 | in *remote control mode* to work. 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | examples/dashboard_client 20 | examples/force_mode 21 | examples/freedrive 22 | examples/instruction_executor 23 | examples/primary_pipeline 24 | examples/primary_pipeline_calibration 25 | examples/rtde_client 26 | examples/script_sender 27 | examples/spline_example 28 | examples/tool_contact_example 29 | examples/trajectory_point_interface 30 | examples/ur_driver 31 | -------------------------------------------------------------------------------- /doc/examples/dashboard_client.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/dashboard_client.rst 2 | 3 | Dashboard client example 4 | ======================== 5 | 6 | This example shows how to use the builtin `Dashboard server `_ to communicate with a robot. 7 | 8 | .. note:: 9 | 10 | The Dashboard Server is only available on CB3 and e-Series robots. It is not available on 11 | PolyScope X. 12 | 13 | 14 | The `dashboard_example.cpp `_ shows how to use this class: 15 | 16 | .. note:: For the following example to work on an e-Series (PolyScope 5) robot, the robot has to be 17 | in *remote control mode*. 18 | 19 | .. literalinclude:: ../../examples/dashboard_example.cpp 20 | :language: c++ 21 | :caption: examples/dashboard_example.cpp 22 | :linenos: 23 | :lineno-match: 24 | :start-at: std::make_unique 25 | :end-at: my_dashboard->commandCloseSafetyPopup(); 26 | 27 | At first, a ``DashboardClient`` object is created with the IP address of the robot. Then, the 28 | client is connected to the robot. After that, the client sends a command to the robot and receives 29 | the answer. 30 | 31 | Some commands support getting the response from the robot. For example, the 32 | ``commandPolyScopeVersion()`` function: 33 | 34 | .. literalinclude:: ../../examples/dashboard_example.cpp 35 | :language: c++ 36 | :caption: examples/dashboard_example.cpp 37 | :linenos: 38 | :lineno-match: 39 | :start-at: // Get the PolyScope version 40 | :end-at: URCL_LOG_INFO(version.c_str()); 41 | 42 | 43 | The ``DashboardClient`` can easily be used to cycle through the robot's states, for example for 44 | initialization: 45 | 46 | .. literalinclude:: ../../examples/dashboard_example.cpp 47 | :language: c++ 48 | :caption: examples/dashboard_example.cpp 49 | :linenos: 50 | :lineno-match: 51 | :start-at: // Power it on 52 | :end-at: // Load existing program 53 | 54 | All commands are blocking and will wait for the necessary action being done. The dashboard server's 55 | response will be compared with an expected response. For example, when calling 56 | ``commandPowerOn(timeout)``, it is checked that the dashboard server is answering ``"Powering on"`` and 57 | then it is queried until the robot reports ``"Robotmode: IDLE"`` or until the timeout is reached. 58 | The example contains more commands that follow the same scheme. 59 | 60 | 61 | If you want to send a query / command to the dashboard server and only want to receive the 62 | response, you can use the ``sendAndReceive()`` function: 63 | 64 | .. literalinclude:: ../../examples/dashboard_example.cpp 65 | :language: c++ 66 | :caption: examples/dashboard_example.cpp 67 | :linenos: 68 | :lineno-match: 69 | :start-at: // Make a raw request and save the response 70 | :end-at: URCL_LOG_INFO("Program state: %s", program_state.c_str()); 71 | 72 | For checking the response against an expected regular expression use ``sendRequest()``: 73 | 74 | .. literalinclude:: ../../examples/dashboard_example.cpp 75 | :language: c++ 76 | :caption: examples/dashboard_example.cpp 77 | :linenos: 78 | :lineno-match: 79 | :start-at: // The response can be checked with a regular expression 80 | :end-at: URCL_LOG_INFO("Power off command success: %d", success); 81 | 82 | 83 | -------------------------------------------------------------------------------- /doc/examples/force_mode.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/force_mode.rst 2 | 3 | Force Mode example 4 | ================== 5 | 6 | The ``ur_client_library`` supports leveraging the robot's force mode directly. An example on how to 7 | use it can be found in `force_mode_example.cpp `_. 8 | 9 | In order to utilize force mode, we'll have to create and initialize a driver object 10 | first. We use the ``ExampleRobotWrapper`` class for this example. That starts a :ref:`ur_driver` 11 | and a :ref:`dashboard_client` to communicate with the robot: 12 | 13 | .. literalinclude:: ../../examples/force_mode_example.cpp 14 | :language: c++ 15 | :caption: examples/force_mode_example.cpp 16 | :linenos: 17 | :lineno-match: 18 | :start-at: bool headless_mode = true; 19 | :end-at: // End of initialization 20 | 21 | Start force mode 22 | ---------------- 23 | 24 | After that, we can start force mode by calling the ``startForceMode()`` function: 25 | 26 | .. literalinclude:: ../../examples/force_mode_example.cpp 27 | :language: c++ 28 | :caption: examples/force_mode_example.cpp 29 | :linenos: 30 | :lineno-match: 31 | :start-at: // Start force mode 32 | :end-at: if (!success) 33 | 34 | All parameters for the force mode are included into the ``startForceMode()`` function call. If you 35 | want to change the parameters, e.g. change the forces applied, you can simply call 36 | ``startForceMode()`` again with the new parameters. 37 | 38 | .. note:: 39 | CB3 robots don't support specifying force_mode's ``gain_scaling``, so there are two different 40 | functions available. 41 | 42 | Once force mode is started successfully, we'll have to send keepalive messages to the robot in 43 | order to keep the communication active: 44 | 45 | .. literalinclude:: ../../examples/force_mode_example.cpp 46 | :language: c++ 47 | :caption: examples/force_mode_example.cpp 48 | :linenos: 49 | :lineno-match: 50 | :start-at: std::chrono::duration time_done(0); 51 | :end-at: URCL_LOG_INFO("Timeout reached."); 52 | 53 | Stop force mode 54 | --------------- 55 | 56 | Once finished, force_mode can be stopped by calling ``endForceMode()``. 57 | 58 | .. literalinclude:: ../../examples/force_mode_example.cpp 59 | :language: c++ 60 | :caption: examples/force_mode_example.cpp 61 | :linenos: 62 | :lineno-match: 63 | :start-at: endForceMode() 64 | :end-at: endForceMode() 65 | -------------------------------------------------------------------------------- /doc/examples/freedrive.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/freedrive.rst 2 | 3 | Freedrive Mode example 4 | ====================== 5 | 6 | `Freedrive 7 | `_ 8 | allows the robot arm to be manually pulled into desired positions and/or poses. The joints move 9 | with little resistance because the brakes are released. 10 | 11 | An example to utilize the freedrive mode can be found in the `freedrive_example.cpp `_. 12 | 13 | .. note:: For the following example to work on an e-Series (PolyScope 5) robot, the robot has to be 14 | in *remote control mode*. 15 | 16 | At first, we create a ``ExampleRobotWrapper`` object in order to initialize communication with the 17 | robot. 18 | 19 | .. literalinclude:: ../../examples/freedrive_example.cpp 20 | :language: c++ 21 | :caption: examples/freedrive_example.cpp 22 | :linenos: 23 | :lineno-match: 24 | :start-at: bool headless_mode = true; 25 | :end-before: URCL_LOG_INFO("Starting freedrive mode"); 26 | 27 | 28 | Start freedrive mode 29 | -------------------- 30 | 31 | The ``UrDriver`` provides a method to start freedrive mode directly: 32 | 33 | .. literalinclude:: ../../examples/freedrive_example.cpp 34 | :language: c++ 35 | :caption: examples/freedrive_example.cpp 36 | :linenos: 37 | :lineno-match: 38 | :start-at: URCL_LOG_INFO("Starting freedrive mode"); 39 | :end-at: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_START); 40 | 41 | As it is potentially dangerous to leave the robot in freedrive mode, the robot program expect 42 | frequent keepalive messages to verify that the remote connection is still available and freedrive 43 | mode is being expected to be active. 44 | 45 | Freedrive mode will be active from this point on until it is either stopped, or no keepalive 46 | message is received by the robot anymore. 47 | 48 | Therefore, we have to make sure to send regular keepalive messages to the robot. The following 49 | section will keep freedrive mode active for a period of time defined in ``seconds_to_run``. 50 | 51 | .. literalinclude:: ../../examples/freedrive_example.cpp 52 | :language: c++ 53 | :caption: examples/freedrive_example.cpp 54 | :linenos: 55 | :lineno-match: 56 | :start-at: std::chrono::duration time_done(0); 57 | :end-before: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_STOP); 58 | 59 | Stop freedrive Mode 60 | ------------------- 61 | 62 | To stop freedrive mode either stop sending keepalive signals or request deactivating it explicitly: 63 | 64 | .. literalinclude:: ../../examples/freedrive_example.cpp 65 | :language: c++ 66 | :caption: examples/freedrive_example.cpp 67 | :linenos: 68 | :lineno-match: 69 | :start-at: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_STOP); 70 | :end-at: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_STOP); 71 | -------------------------------------------------------------------------------- /doc/examples/instruction_executor.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/instruction_executor.rst 2 | 3 | .. _instruction_executor_example: 4 | 5 | Instruction Executor example 6 | ============================ 7 | 8 | This example shows how to use the :ref:`instruction_executor` class. It can be used for easily 9 | executing a sequence of instructions such as motions on the robot using the built-in URScript functions. 10 | 11 | The `instruction_executor.cpp `_ shows how to use this class: 12 | 13 | .. note:: For the instruciton executor to work there has to be an established connection to the 14 | :ref:`reverse_interface`. That means, the respective program has to be running on the robot. The 15 | example below will do that automatically, if the connected robot is in *remote_control* mode. 16 | 17 | 18 | .. literalinclude:: ../../examples/instruction_executor.cpp 19 | :language: c++ 20 | :caption: examples/instruction_executor.cpp 21 | :linenos: 22 | :lineno-match: 23 | :start-at: bool headless_mode = true; 24 | :end-at: auto instruction_executor = std::make_shared(g_my_robot->getUrDriver()); 25 | 26 | At first, a ``InstructionExecutor`` object is created with the URDriver object as it needs that 27 | for communication with the robot. 28 | 29 | Currently, the ``InstructionExecutor`` can either be used to run sequences of motions or single motions. 30 | 31 | Execute a sequence of motions 32 | ----------------------------- 33 | 34 | To run a sequence of motions, create an 35 | ``std::vector>`` and pass it to the 36 | ``executeMotion`` function: 37 | 38 | .. literalinclude:: ../../examples/instruction_executor.cpp 39 | :language: c++ 40 | :caption: examples/instruction_executor.cpp 41 | :linenos: 42 | :lineno-match: 43 | :start-at: // Trajectory definition 44 | :end-at: instruction_executor->executeMotion(motion_sequence); 45 | 46 | Each element in the motion sequence can be a different motion type. In the example, there are two 47 | ``MoveJ`` motions, a ``MoveL`` motion, a ``MoveP`` motion, a ``OptimiveJ`` motion and a 48 | ``OptimoveL`` motion. The primitives' parameters are directly forwarded to the underlying script 49 | functions, so the parameter descriptions for them apply, as well. Particularly, you may want to 50 | choose between either a time-based execution or an acceleration / velocity parametrization 51 | for some move functions. The latter will be ignored if a time > 0 is given. 52 | 53 | Please refer to the script manual for details. 54 | 55 | Execute a single motion 56 | ----------------------- 57 | 58 | To run a single motion, the ``InstructionExecutor`` provides the methods ``moveJ(...)`` and 59 | ``moveL(...)``: 60 | 61 | .. literalinclude:: ../../examples/instruction_executor.cpp 62 | :language: c++ 63 | :caption: examples/instruction_executor.cpp 64 | :linenos: 65 | :lineno-match: 66 | :start-at: double goal_time_sec = 2.0; 67 | :end-before: g_my_robot->getUrDriver()->stopControl(); 68 | 69 | Again, time parametrization has priority over acceleration / velocity parameters. 70 | -------------------------------------------------------------------------------- /doc/examples/primary_pipeline.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/primary_pipeline.rst 2 | 3 | .. _primary_pipeline_example: 4 | 5 | Primary Pipeline example 6 | ======================== 7 | 8 | This example shows how to use the ``Pipeline`` class for the robot's `primary interface 9 | `_. 10 | It reads all packages coming in from the robot't primary interface and prints their contents. 11 | 12 | At the current time parsing primary interface data is very limited, so this example will print the 13 | raw binary data for most package types. The example serves to demonstrate the basic control flow 14 | used for reading data from the robot. 15 | 16 | In this library, a "pipeline" uses a producer / consumer architecture. A producer is reading data 17 | from a *stream*, parses that data and puts it into a *queue*. A consumer reads data from the queue 18 | and can do whatever its purpose is. 19 | 20 | Producer setup 21 | -------------- 22 | 23 | To setup the producer, we need to create a stream, a parser and create a producer with those: 24 | 25 | .. literalinclude:: ../../examples/primary_pipeline.cpp 26 | :language: c++ 27 | :caption: examples/primary_pipeline.cpp 28 | :linenos: 29 | :lineno-match: 30 | :start-at: // First of all, we need a stream 31 | :end-at: prod.setupProducer(); 32 | 33 | Consumer setup 34 | -------------- 35 | 36 | The consumer can be any consumer that is able to consume data produced by the producer, in this 37 | case ``urcl::primary_interface::PrimaryPackage``. Here, we use a ``ShellExecutor`` that will try to 38 | print each package's content to the shell output: 39 | 40 | .. literalinclude:: ../../examples/primary_pipeline.cpp 41 | :language: c++ 42 | :caption: examples/primary_pipeline.cpp 43 | :linenos: 44 | :lineno-match: 45 | :start-at: // The shell consumer 46 | :end-at: auto consumer = std::make_unique 47 | 48 | Assemble the pipeline 49 | --------------------- 50 | 51 | Finally, we need to assemble the pipeline by connecting the producer to the consumer: 52 | 53 | .. literalinclude:: ../../examples/primary_pipeline.cpp 54 | :language: c++ 55 | :caption: examples/primary_pipeline.cpp 56 | :linenos: 57 | :lineno-match: 58 | :start-after: auto consumer = std::make_unique 59 | :end-at: pipeline.run() 60 | 61 | You can setup a custom notifier that can handle start and stop events of the pipeline. In this 62 | example we use the basic ``INotifier`` which doesn't do anything. 63 | 64 | With all that, we can create the ``pipeline`` by passing the producer, consumer, a name and the 65 | notifier to it's constructor. 66 | 67 | From this point on, the producer will read the data coming on from the stream and that data will be 68 | processed by the consumer. We keep the example program alive for a while to see some data: 69 | 70 | .. literalinclude:: ../../examples/primary_pipeline.cpp 71 | :language: c++ 72 | :caption: examples/primary_pipeline.cpp 73 | :linenos: 74 | :lineno-match: 75 | :start-at: do 76 | :end-at: return 0 77 | 78 | 79 | -------------------------------------------------------------------------------- /doc/examples/primary_pipeline_calibration.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/primary_pipeline_calibration.rst 2 | 3 | .. _primary_pipeline_calibration_example: 4 | 5 | Primary Pipeline Calibration example 6 | ==================================== 7 | 8 | This example is very similar to the :ref:`primary_pipeline_example`. However, it uses a 9 | specialized consumer that will analyze the calibration data sent from the robot instead of the 10 | ``ShellConsumer``. 11 | 12 | Consumer setup 13 | -------------- 14 | 15 | This example uses a specialized type of consumer that stores data about the received robot 16 | calibration. 17 | 18 | .. literalinclude:: ../../examples/primary_pipeline_calibration.cpp 19 | :language: c++ 20 | :caption: examples/primary_pipeline_calibration.cpp 21 | :linenos: 22 | :lineno-match: 23 | :start-at: class CalibrationConsumer 24 | :end-at: }; 25 | 26 | Since the producer is reading every package from the primary interface, the consumer has to be able 27 | to consume any primary package. 28 | 29 | Assemble the pipeline 30 | --------------------- 31 | 32 | The rest of the pipeline setup is the same as in the other pipeline example, just that we create a 33 | ``CalibrationConsumer`` instead of a ``ShellConsumer``: 34 | 35 | .. literalinclude:: ../../examples/primary_pipeline_calibration.cpp 36 | :language: c++ 37 | :caption: examples/primary_pipeline_calibration.cpp 38 | :linenos: 39 | :lineno-match: 40 | :start-at: // The calibration consumer 41 | :end-at: calib_pipeline.run() 42 | 43 | Again, product handling will be happening in the background, so in the rest of the program we wait 44 | until the calibration consumer received and processed data and then print information about that: 45 | 46 | .. literalinclude:: ../../examples/primary_pipeline_calibration.cpp 47 | :language: c++ 48 | :caption: examples/primary_pipeline_calibration.cpp 49 | :linenos: 50 | :lineno-match: 51 | :start-at: while (!calib_consumer 52 | :end-at: return 0 53 | -------------------------------------------------------------------------------- /doc/examples/script_sender.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/script_sender.rst 2 | 3 | .. _script_sender_example: 4 | 5 | Script Sender example 6 | ===================== 7 | 8 | The following example creates a ``ScriptSender`` listening on port ``12345`` and sends the script 9 | ``textmsg("Hello, World!")`` when requested. A fully compilable example can be found in `script_sender.cpp `_ 10 | 11 | .. literalinclude:: ../../examples/script_sender.cpp 12 | :language: c++ 13 | :caption: examples/script_sender.cpp 14 | :linenos: 15 | :lineno-match: 16 | :start-at: constexpr uint32_t PORT 17 | -------------------------------------------------------------------------------- /doc/examples/spline_example.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/spline_example.rst 2 | 3 | .. _spline_example: 4 | 5 | Spline Interpolation example 6 | ============================ 7 | 8 | The URScript code inside `external_control.urscript 9 | `_ implements trajectory execution based upon spline interpolation of a given sequence of waypoints. 10 | 11 | Depending on the waypoint parametrization, either cubic splines (positions, velocities, times) or 12 | quintic splines (positions, velocities, accelerations, times) will be used. 13 | 14 | The example in `spline_example.cpp `_ shows how to use the :ref:`trajectory_point_interface` to execute trajectories using this spline interpolation. 15 | -------------------------------------------------------------------------------- /doc/examples/tool_contact_example.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/tool_contact_example.rst 2 | 3 | .. _tool_contact_example: 4 | 5 | Tool Contact example 6 | ==================== 7 | 8 | Univeral Robots' **tool contact mode** allows detecting collisions between the robot's tool and the 9 | environment and interrupting motions when that happens. This example demonstrates how to use the 10 | tool contact mode to detect collisions and stop the robot. 11 | 12 | As a basic concept, we will move the robot linearly in the negative z axis until the tool hits 13 | something or the program's timeout is hit. 14 | 15 | At first, we create a initialize a driver as usual: 16 | 17 | .. literalinclude:: ../../examples/tool_contact_example.cpp 18 | :language: c++ 19 | :caption: examples/tool_contact_example.cpp 20 | :linenos: 21 | :lineno-match: 22 | :start-at: bool headless_mode = true; 23 | :end-before: g_my_robot->getUrDriver()->registerToolContactResultCallback 24 | 25 | We use a small helper function to make sure that the reverse interface is active and connected 26 | before proceeding. 27 | 28 | When a tool contact is detected, a callback will be triggered. For that we define a function to 29 | handle this event: 30 | 31 | .. literalinclude:: ../../examples/tool_contact_example.cpp 32 | :language: c++ 33 | :caption: examples/tool_contact_example.cpp 34 | :linenos: 35 | :lineno-match: 36 | :start-at: void handleToolContactResult(control::ToolContactResult result) 37 | :end-at: } 38 | 39 | 40 | 41 | This function is registered as a callback to the driver and then tool_contact mode is enabled: 42 | 43 | .. literalinclude:: ../../examples/tool_contact_example.cpp 44 | :language: c++ 45 | :caption: examples/tool_contact_example.cpp 46 | :linenos: 47 | :lineno-match: 48 | :start-at: g_my_robot->getUrDriver()->registerToolContactResultCallback(&handleToolContactResult); 49 | :end-at: g_my_robot->getUrDriver()->startToolContact() 50 | 51 | Once everything is initialized, we can start a control loop commanding the robot to move in the 52 | negative z direction until the program timeout is hit or a tool contact is detected: 53 | 54 | .. literalinclude:: ../../examples/tool_contact_example.cpp 55 | :language: c++ 56 | :caption: examples/tool_contact_example.cpp 57 | :linenos: 58 | :lineno-match: 59 | :start-at: // This will move the robot 60 | :end-at: return 0; 61 | -------------------------------------------------------------------------------- /doc/examples/ur_driver.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/ur_driver.rst 2 | 3 | .. _example-driver: 4 | 5 | Example driver 6 | ============== 7 | In the ``examples`` subfolder you will find a minimal example of a running driver. It starts an 8 | instance of the ``UrDriver`` class and prints the RTDE values read from the controller. To run it make 9 | sure to 10 | 11 | * have an instance of a robot controller / URSim running at the configured IP address (or adapt the 12 | address to your needs) 13 | * run it from the package's main folder (the one where the README.md file is stored), as for 14 | simplicity reasons it doesn't use any sophisticated method to locate the required files. 15 | 16 | This page will walk you through the `full_driver.cpp 17 | `_ 18 | example. 19 | 20 | Initialization 21 | -------------- 22 | 23 | At first, we create a ``ExampleRobotWrapper`` object giving it the robot's IP address, script file and RTDE 24 | recipes. 25 | 26 | .. literalinclude:: ../../examples/full_driver.cpp 27 | :language: c++ 28 | :caption: examples/full_driver.cpp 29 | :linenos: 30 | :lineno-match: 31 | :start-at: bool headless_mode = true; 32 | :end-at: // --------------- INITIALIZATION END ------------------- 33 | 34 | Robot control loop 35 | ------------------ 36 | 37 | This example reads the robot's joint positions, increments / decrements the 5th axis and sends that 38 | back as a joint command for the next cycle. This way, the robot will move its wrist first until a 39 | positive limit and then back to 0. 40 | 41 | To read the joint data, the driver's RTDE client is used: 42 | 43 | 44 | .. literalinclude:: ../../examples/full_driver.cpp 45 | :language: c++ 46 | :caption: examples/full_driver.cpp 47 | :linenos: 48 | :lineno-match: 49 | :start-at: // Once RTDE communication is started 50 | :end-before: // Open loop control 51 | 52 | The first read operation will initialize the target buffer with the current robot position. Next, 53 | the target joint configuration is calculated: 54 | 55 | 56 | .. literalinclude:: ../../examples/full_driver.cpp 57 | :language: c++ 58 | :caption: examples/full_driver.cpp 59 | :linenos: 60 | :lineno-match: 61 | :start-at: // Open loop control 62 | :end-at: joint_target[5] += increment 63 | 64 | To send the control command, the robot's :ref:`reverse_interface` is used via the 65 | ``writeJointCommand()`` function: 66 | 67 | .. literalinclude:: ../../examples/full_driver.cpp 68 | :language: c++ 69 | :caption: examples/full_driver.cpp 70 | :linenos: 71 | :lineno-match: 72 | :start-at: // Setting the RobotReceiveTimeout 73 | :end-before: URCL_LOG_DEBUG("data_pkg:\n%s", data_pkg->toString().c_str()); 74 | -------------------------------------------------------------------------------- /doc/images/initial_setup_images/cb3_01_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/cb3_01_welcome.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/cb3_05_urcaps_installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/cb3_05_urcaps_installed.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/cb3_07_installation_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/cb3_07_installation_excontrol.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/cb3_10_prog_structure_urcaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/cb3_10_prog_structure_urcaps.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/cb3_11_program_view_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/cb3_11_program_view_excontrol.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/es_01_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/es_01_welcome.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/es_05_urcaps_installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/es_05_urcaps_installed.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/es_07_installation_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/es_07_installation_excontrol.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/es_10_prog_structure_urcaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/es_10_prog_structure_urcaps.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/es_11_program_view_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/es_11_program_view_excontrol.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/family_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/family_photo.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/px_01_welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/px_01_welcome.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/px_05_urcaps_installed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/px_05_urcaps_installed.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/px_07_installation_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/px_07_installation_excontrol.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/px_10_prog_structure_urcaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/px_10_prog_structure_urcaps.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/px_11_program_view_excontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/px_11_program_view_excontrol.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/remote_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/remote_control.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/services_polyscope5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/services_polyscope5.png -------------------------------------------------------------------------------- /doc/images/initial_setup_images/services_polyscopex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/images/initial_setup_images/services_polyscopex.png -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/index.rst 2 | 3 | .. _ur_client_library: 4 | 5 | ur_client_library 6 | ================= 7 | 8 | This documentation should help you to get started with the UR Client Library. The UR Client Library 9 | is a C++ library that allows you to control a UR robot from a remote computer. The library is open-source and 10 | can be found on `GitHub `_. 11 | 12 | .. toctree:: 13 | :maxdepth: 4 14 | :caption: Contents: 15 | 16 | installation 17 | setup 18 | polyscope_compatibility 19 | architecture 20 | examples 21 | real_time 22 | migration_notes 23 | api_reference 24 | -------------------------------------------------------------------------------- /doc/migration_notes.rst: -------------------------------------------------------------------------------- 1 | Migration notes 2 | =============== 3 | 4 | This document contains notes on the migration of the ur_client_library between major versions. 5 | 6 | It contains only breaking changes. 7 | 8 | Migrating from 1.x.x to 2.x.x 9 | ----------------------------- 10 | 11 | - In the ``urcl::ExampleRobotWrapper`` class the ``ur_driver_``, ``dashboard_client`` and 12 | ``primary_client`` members are now private. Use ``getUrDriver()``, ``getDashboardClient()`` and 13 | ``getPrimaryClient()`` to access them. 14 | 15 | - In ``urcl::comm::ControlModeTypes`` two member functions have been renamed: 16 | 17 | - ``is_control_mode_realtime`` -> ``isControlModeRealtime`` 18 | - ``is_control_mode_non_realtime`` -> ``isControlModeNonRealtime`` 19 | 20 | - In ``urcl::RobotReceiveTimeout`` the ``timeout_`` member is now private. Use 21 | ``getAsMilliseconds()`` to access it. 22 | 23 | - In ``urcl::UrDriverConfiguration`` two members have been renamed: 24 | 25 | - ``rtde_initialization_attempts_`` -> ``rtde_initialization_attempts`` 26 | - ``rtde_initialization_timeout_`` -> ``rtde_initialization_timeout`` 27 | -------------------------------------------------------------------------------- /doc/polyscope_compatibility.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/polyscope_compatibility.rst 2 | 3 | |polyscope| version compatibility 4 | ================================= 5 | 6 | The table below shows breaking changes in the library compared to |polyscope| versions. Compatibility 7 | is listed for CB3 robots (versions 3.x.y) and e-Series robots (versions 5.x.y) respectively. 8 | 9 | It might be possible to use the library in a more recent version than the compatible versions listed 10 | below, but that might either require some manual modifications or not using a subset of features. 11 | For that reason the breaking changes are also listed inside the table. Please note that choosing a 12 | higher library version than recommended happens on your own risk and will not be supported. 13 | 14 | If your |polyscope| version is less than the minimum required version for the latest library version, 15 | we suggest to upgrade your robot's software. Please refer to the robot's user manual how to update 16 | your robot. 17 | 18 | If you don't want to update your robot you can either use the release version as listed in the 19 | table below or checkout the latest tag before the breaking changes were introduced. 20 | 21 | .. list-table:: 22 | :header-rows: 1 23 | 24 | * - |polyscope| version 25 | - Max. release 26 | - Latest tag 27 | - Breaking changes 28 | * - < 3.12.3 / 5.5.1 29 | - 1.1.0 30 | - `polyscope_compat_break_1 `_ 31 | - `tcp_offset in RTDE interface `_ 32 | * - < 3.14.3 / 5.9.4 33 | - 1.3.1 34 | - `polyscope_compat_break_2 `_ 35 | - `Use of scalar product in urscript `_ 36 | 37 | .. note:: 38 | |polyscope| X doesn't support all features supported by this library for |polyscope| 5. 39 | Currently, the following components are known not to be supported: 40 | 41 | - Dashboard client -- |polyscope| X doesn't have a dashboard server. 42 | - Using external control on |polyscope| X requires another URCapX for making external control 43 | work. This is currently in the process of being created. 44 | See `Universal Robots External Control URCapX `_ 45 | 46 | .. |polyscope| replace:: PolyScope 47 | -------------------------------------------------------------------------------- /doc/resources/family_photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/resources/family_photo.png -------------------------------------------------------------------------------- /doc/resources/fzi-logo_transparenz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/resources/fzi-logo_transparenz.png -------------------------------------------------------------------------------- /doc/resources/ur_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/doc/resources/ur_logo.jpg -------------------------------------------------------------------------------- /doc/setup.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/setup.rst 2 | 3 | Setup a robot 4 | ============= 5 | 6 | The robot has to be prepared, to enable communication between the robot and the client library. 7 | This documentation will guide you through the necessary steps. 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | setup/robot_setup 13 | setup/network_setup 14 | setup/ursim_docker.rst 15 | -------------------------------------------------------------------------------- /doc/setup/network_setup.rst: -------------------------------------------------------------------------------- 1 | :github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/setup/network_setup.rst 2 | 3 | .. _network_setup: 4 | 5 | Network setup 6 | ============= 7 | 8 | Robot setup 9 | ----------- 10 | 11 | There are many possible ways to connect a UR robot. This section describes a good example using static IP addresses and a direct connection from the PC to the Robot to minimize latency introduced by network hardware. Though a good network switch usually works fine, as well. 12 | 13 | 14 | #. 15 | Connect the UR control box directly to the remote PC with an ethernet cable. 16 | 17 | #. 18 | Open the network settings from the UR teach pendant (Setup Robot -> Network) and enter these settings: 19 | 20 | .. code-block:: 21 | 22 | IP address: 192.168.56.101 23 | Subnet mask: 255.255.255.0 24 | Default gateway: 192.168.56.1 25 | Preferred DNS server: 192.168.56.1 26 | Alternative DNS server: 0.0.0.0 27 | 28 | Remote PC setup 29 | --------------- 30 | 31 | #. On the remote PC, turn off all network devices except the "wired connection", e.g. turn off 32 | wifi. You can skip this step if you are certain that no other active connection is using the 33 | same IP range. 34 | 35 | #. Open Network Settings and create a new Wired connection with these settings. You may want to name this new connection ``UR`` or something similar: 36 | 37 | .. code-block:: 38 | 39 | IPv4 40 | Manual 41 | Address: 192.168.56.1 42 | Netmask: 255.255.255.0 43 | 44 | #. Verify the connection from the PC with e.g. ping. You should see something like this: 45 | 46 | .. code-block:: console 47 | 48 | $ ping 192.168.56.101 49 | PING 192.168.56.101 (192.168.56.101) 56(84) bytes of data. 50 | 64 bytes from 192.168.56.101: icmp_seq=1 ttl=64 time=0.037 ms 51 | 64 bytes from 192.168.56.101: icmp_seq=2 ttl=64 time=0.043 ms 52 | 64 bytes from 192.168.56.101: icmp_seq=3 ttl=64 time=0.047 ms 53 | -------------------------------------------------------------------------------- /doc_requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx-copybutton 3 | sphinx-tabs 4 | sphinx_rtd_theme 5 | catkin-pkg 6 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14.0) 2 | project(ur_driver_examples) 3 | 4 | # find_package(ur_client_library REQUIRED) 5 | 6 | 7 | add_executable(driver_example 8 | full_driver.cpp) 9 | target_link_libraries(driver_example ur_client_library::urcl) 10 | 11 | add_executable(primary_pipeline_example 12 | primary_pipeline.cpp) 13 | target_link_libraries(primary_pipeline_example ur_client_library::urcl) 14 | 15 | add_executable(primary_pipeline_calibration_example 16 | primary_pipeline_calibration.cpp) 17 | target_link_libraries(primary_pipeline_calibration_example ur_client_library::urcl) 18 | 19 | add_executable(rtde_client_example 20 | rtde_client.cpp) 21 | target_link_libraries(rtde_client_example ur_client_library::urcl) 22 | 23 | add_executable(dashboard_example 24 | dashboard_example.cpp) 25 | target_link_libraries(dashboard_example ur_client_library::urcl) 26 | 27 | add_executable(spline_example 28 | spline_example.cpp) 29 | target_link_libraries(spline_example ur_client_library::urcl) 30 | 31 | add_executable(tool_contact_example 32 | tool_contact_example.cpp) 33 | target_link_libraries(tool_contact_example ur_client_library::urcl) 34 | 35 | add_executable(freedrive_example 36 | freedrive_example.cpp) 37 | target_link_libraries(freedrive_example ur_client_library::urcl) 38 | 39 | add_executable(force_mode_example 40 | force_mode_example.cpp) 41 | target_link_libraries(force_mode_example ur_client_library::urcl) 42 | 43 | add_executable(script_sender_example 44 | script_sender.cpp) 45 | target_link_libraries(script_sender_example ur_client_library::urcl) 46 | 47 | add_executable(trajectory_point_interface_example 48 | trajectory_point_interface.cpp) 49 | target_link_libraries(trajectory_point_interface_example ur_client_library::urcl) 50 | 51 | add_executable(instruction_executor 52 | instruction_executor.cpp) 53 | target_link_libraries(instruction_executor ur_client_library::urcl) 54 | -------------------------------------------------------------------------------- /examples/primary_pipeline.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2020 FZI Forschungszentrum Informatik 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | // -- END LICENSE BLOCK ------------------------------------------------ 18 | 19 | //---------------------------------------------------------------------- 20 | /*!\file 21 | * 22 | * \author Felix Exner mauch@fzi.de 23 | * \date 2020-09-11 24 | * 25 | */ 26 | //---------------------------------------------------------------------- 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace urcl; 34 | 35 | // In a real-world example it would be better to get those values from command line parameters / a better configuration 36 | // system such as Boost.Program_options 37 | const std::string DEFAULT_ROBOT_IP = "192.168.56.101"; 38 | 39 | int main(int argc, char* argv[]) 40 | { 41 | // Set the loglevel to info get print out the DH parameters 42 | urcl::setLogLevel(urcl::LogLevel::INFO); 43 | 44 | // Parse the ip arguments if given 45 | std::string robot_ip = DEFAULT_ROBOT_IP; 46 | if (argc > 1) 47 | { 48 | robot_ip = std::string(argv[1]); 49 | } 50 | 51 | // Parse how many seconds to run 52 | int second_to_run = -1; 53 | if (argc > 2) 54 | { 55 | second_to_run = std::stoi(argv[2]); 56 | } 57 | 58 | // First of all, we need a stream that connects to the robot's primary interface 59 | comm::URStream primary_stream(robot_ip, urcl::primary_interface::UR_PRIMARY_PORT); 60 | 61 | // This will parse the primary packages 62 | primary_interface::PrimaryParser parser; 63 | 64 | // The producer needs both, the stream and the parser to fully work 65 | comm::URProducer prod(primary_stream, parser); 66 | 67 | // Connect to the stream 68 | prod.setupProducer(); 69 | 70 | // The shell consumer will print the package contents to the shell 71 | auto consumer = std::make_unique>(); 72 | 73 | // The notifer will be called at some points during connection setup / loss. This isn't fully 74 | // implemented atm. 75 | comm::INotifier notifier; 76 | 77 | // Now that we have all components, we can create and start the pipeline to run it all. 78 | comm::Pipeline pipeline(prod, consumer.get(), "Pipeline", notifier); 79 | pipeline.run(); 80 | 81 | // Package contents will be printed while not being interrupted 82 | // Note: Packages for which the parsing isn't implemented, will only get their raw bytes printed. 83 | do 84 | { 85 | std::this_thread::sleep_for(std::chrono::seconds(second_to_run)); 86 | } while (second_to_run < 0); 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /examples/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 | -------------------------------------------------------------------------------- /examples/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 | actual_digital_input_bits 10 | actual_digital_output_bits 11 | standard_analog_input0 12 | standard_analog_input1 13 | standard_analog_output0 14 | standard_analog_output1 15 | analog_io_types 16 | tool_mode 17 | tool_analog_input_types 18 | tool_analog_input0 19 | tool_analog_input1 20 | tool_output_voltage 21 | tool_output_current 22 | tool_temperature 23 | robot_mode 24 | safety_mode 25 | robot_status_bits 26 | safety_status_bits 27 | actual_current 28 | tcp_offset 29 | -------------------------------------------------------------------------------- /examples/script_sender.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2024 Universal Robots A/S 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // -- END LICENSE BLOCK ------------------------------------------------ 16 | 17 | //---------------------------------------------------------------------- 18 | /*!\file 19 | * 20 | * \author Felix Exner feex@universal-robots.com 21 | * \date 2024-12-04 22 | * 23 | */ 24 | //---------------------------------------------------------------------- 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | constexpr uint32_t PORT = 12345; 34 | 35 | int main(int argc, char* argv[]) 36 | { 37 | // Parse how may seconds to run 38 | int second_to_run = -1; 39 | if (argc > 2) 40 | { 41 | second_to_run = std::stoi(argv[2]); 42 | } 43 | urcl::control::ScriptSender sender(PORT, "textmsg(\"Hello, World!\")"); 44 | 45 | std::stringstream ss; 46 | ss << "Waiting for incoming requests on port " << PORT; 47 | if (second_to_run > 0) 48 | { 49 | ss << " for " << second_to_run << " seconds"; 50 | } 51 | else 52 | { 53 | ss << " indefinitely"; 54 | } 55 | 56 | std::cout << ss.str() << std::endl; 57 | 58 | const auto start_time = std::chrono::system_clock::now(); 59 | while (second_to_run < 0 || std::chrono::system_clock::now() - start_time < std::chrono::seconds(second_to_run)) 60 | { 61 | std::this_thread::sleep_for(std::chrono::milliseconds(500)); 62 | } 63 | std::cout << "Timeout reached" << std::endl; 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /include/ur_client_library/comm/package.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-08 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | #ifndef UR_CLIENT_LIBRARY_PACKAGE_H_INCLUDED 29 | #define UR_CLIENT_LIBRARY_PACKAGE_H_INCLUDED 30 | 31 | #include "ur_client_library/comm/bin_parser.h" 32 | 33 | namespace urcl 34 | { 35 | namespace comm 36 | { 37 | /*! 38 | * \brief The URPackage a parent class. From that two implementations are inherited, 39 | * one for the primary, one for the rtde interface (primary_interface::primaryPackage; 40 | * rtde_interface::rtdePackage). The URPackage makes use of the template HeaderT. 41 | */ 42 | template 43 | class URPackage 44 | { 45 | public: 46 | /*! 47 | * \brief Creates a new URPackage object. 48 | */ 49 | 50 | URPackage() = default; 51 | virtual ~URPackage() = default; 52 | 53 | /*! 54 | * \brief Sets the attributes of the package by parsing a serialized representation of the 55 | * package. 56 | * 57 | * \param bp A parser containing a serialized version of the package 58 | * 59 | * \returns True, if the package was parsed successfully, false otherwise 60 | */ 61 | virtual bool parseWith(BinParser& bp) = 0; 62 | 63 | /*! 64 | * \brief Produces a human readable representation of the package object. 65 | * 66 | * \returns A string representing the object 67 | */ 68 | virtual std::string toString() const = 0; 69 | 70 | using HeaderType = HeaderT; 71 | 72 | private: 73 | HeaderT header_; 74 | }; 75 | } // namespace comm 76 | } // namespace urcl 77 | #endif // ifndef UR_CLIENT_LIBRARY_PACKAGE_H_INCLUDED 78 | -------------------------------------------------------------------------------- /include/ur_client_library/comm/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, FZI Forschungszentrum Informatik (refactor) 3 | * 4 | * Copyright 2017, 2018 Simon Rasmussen (refactor) 5 | * 6 | * Copyright 2015, 2016 Thomas Timm Andersen (original version) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #pragma once 22 | #include 23 | #include "ur_client_library/comm/bin_parser.h" 24 | #include "ur_client_library/comm/package.h" 25 | 26 | namespace urcl 27 | { 28 | namespace comm 29 | { 30 | /*! 31 | * \brief The parser is a general paser. The namsepace rtde_interface and primary_interface both 32 | * iclude classes which inherit from it (rtdeParser and primaryParser). 33 | * The parser functionality also embodies a factory function taking in an uint8. 34 | */ 35 | template 36 | class Parser 37 | 38 | { 39 | public: 40 | Parser() = default; 41 | virtual ~Parser() = default; 42 | 43 | /*! 44 | * \brief Declares the parse function. 45 | * 46 | * \param bp Instance of class binaryParser 47 | * \param results A unique pointer 48 | */ 49 | virtual bool parse(BinParser& bp, std::vector>& results) = 0; 50 | 51 | private: 52 | typename T::HeaderType header_; 53 | // URProducer producer_; 54 | }; 55 | 56 | } // namespace comm 57 | } // namespace urcl 58 | -------------------------------------------------------------------------------- /include/ur_client_library/comm/shell_consumer.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_SHELL_CONSUMER_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_SHELL_CONSUMER_H_INCLUDED 31 | 32 | #include "ur_client_library/log.h" 33 | #include "ur_client_library/comm/pipeline.h" 34 | #include "ur_client_library/comm/package.h" 35 | 36 | namespace urcl 37 | { 38 | namespace comm 39 | { 40 | /*! 41 | * \brief The ShellConsumer class is a simple consumer that writes a readable representation to 42 | * the logging info channel. 43 | * 44 | * @tparam HeaderT Header type of the packages to consume 45 | */ 46 | template 47 | class ShellConsumer : public IConsumer 48 | { 49 | public: 50 | ShellConsumer() = default; 51 | virtual ~ShellConsumer() = default; 52 | 53 | /*! 54 | * \brief Consumes a package, writing a human readable representation to the logging. 55 | * 56 | * \param product The package to consume 57 | * 58 | * \returns True if the output was successful 59 | */ 60 | virtual bool consume(std::shared_ptr product) 61 | { 62 | URCL_LOG_INFO("%s", product->toString().c_str()); 63 | return true; 64 | } 65 | 66 | private: 67 | /* data */ 68 | }; 69 | } // namespace comm 70 | } // namespace urcl 71 | #endif // ifndef UR_CLIENT_LIBRARY_SHELL_CONSUMER_H_INCLUDED 72 | -------------------------------------------------------------------------------- /include/ur_client_library/comm/socket_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024, RoboDK Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #ifdef _WIN32 20 | 21 | # define NOMINMAX 22 | # define WIN32_LEAN_AND_MEAN 23 | # include 24 | # include 25 | 26 | # ifndef TCP_QUICKACK 27 | # define TCP_QUICKACK 12 28 | # endif 29 | 30 | # ifdef ERROR 31 | # undef ERROR 32 | # endif // ERROR 33 | 34 | typedef SOCKET socket_t; 35 | typedef SSIZE_T ssize_t; 36 | 37 | static inline int ur_setsockopt(socket_t s, int level, int optname, const void* optval, unsigned int optlen) 38 | { 39 | return ::setsockopt(s, level, optname, reinterpret_cast(optval), static_cast(optlen)); 40 | } 41 | 42 | static inline int ur_close(socket_t s) 43 | { 44 | return ::closesocket(s); 45 | } 46 | 47 | #else // _WIN32 48 | 49 | # include 50 | # include 51 | # include 52 | # include 53 | # include 54 | # include 55 | # include 56 | 57 | typedef int socket_t; 58 | 59 | # ifndef INVALID_SOCKET 60 | # define INVALID_SOCKET (-1) 61 | # endif 62 | 63 | # define ur_setsockopt setsockopt 64 | # define ur_close close 65 | 66 | #endif // _WIN32 67 | -------------------------------------------------------------------------------- /include/ur_client_library/control/script_sender.h: -------------------------------------------------------------------------------- 1 | 2 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 3 | 4 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 5 | // Copyright 2019 FZI Forschungszentrum Informatik 6 | // Created on behalf of Universal Robots A/S 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // -- END LICENSE BLOCK ------------------------------------------------ 20 | 21 | //---------------------------------------------------------------------- 22 | /*!\file 23 | * 24 | * \author Tristan Schnell schnell@fzi.de 25 | * \date 2019-05-22 26 | * 27 | */ 28 | //---------------------------------------------------------------------- 29 | 30 | #ifndef UR_CLIENT_LIBRARY_SCRIPT_SENDER_H_INCLUDED 31 | #define UR_CLIENT_LIBRARY_SCRIPT_SENDER_H_INCLUDED 32 | 33 | #include 34 | #include 35 | 36 | #include "ur_client_library/comm/tcp_server.h" 37 | #include "ur_client_library/log.h" 38 | 39 | namespace urcl 40 | { 41 | namespace control 42 | { 43 | /*! 44 | * \brief The ScriptSender class starts a TCPServer for a robot to connect to and waits for a 45 | * request to receive a program. This program is then delivered to the requesting robot. 46 | */ 47 | class ScriptSender 48 | { 49 | public: 50 | ScriptSender() = delete; 51 | /*! 52 | * \brief Creates a ScriptSender object, including a new TCPServer 53 | * 54 | * \param port Port to start the server on 55 | * \param program Program to send to the robot upon request 56 | */ 57 | ScriptSender(uint32_t port, const std::string& program); 58 | 59 | private: 60 | comm::TCPServer server_; 61 | std::thread script_thread_; 62 | std::string program_; 63 | 64 | const std::string PROGRAM_REQUEST_ = std::string("request_program\n"); 65 | 66 | void connectionCallback(const socket_t filedescriptor); 67 | 68 | void disconnectionCallback(const socket_t filedescriptor); 69 | 70 | void messageCallback(const socket_t filedescriptor, char* buffer); 71 | 72 | void sendProgram(const socket_t filedescriptor); 73 | }; 74 | 75 | } // namespace control 76 | } // namespace urcl 77 | 78 | #endif // UR_CLIENT_LIBRARY_SCRIPT_SENDER_H_INCLUDED 79 | -------------------------------------------------------------------------------- /include/ur_client_library/default_log_handler.h: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2021 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #pragma once 32 | 33 | #include "ur_client_library/log.h" 34 | 35 | namespace urcl 36 | { 37 | /*! 38 | * \brief LogHandler object for default handling of logging messages. 39 | * This class is used when no other LogHandler is registered 40 | */ 41 | class DefaultLogHandler : public LogHandler 42 | { 43 | public: 44 | /*! 45 | * \brief Construct a new DefaultLogHandler object 46 | */ 47 | DefaultLogHandler(); 48 | 49 | /*! 50 | * \brief Function to log a message 51 | * 52 | * \param file The log message comes from this file 53 | * \param line The log message comes from this line 54 | * \param loglevel Indicates the severity of the log message 55 | * \param log Log message 56 | */ 57 | void log(const char* file, int line, LogLevel loglevel, const char* log) override; 58 | }; 59 | 60 | } // namespace urcl 61 | -------------------------------------------------------------------------------- /include/ur_client_library/helpers.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2022 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2022-12-15 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_HELPERS_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_HELPERS_H_INCLUDED 31 | 32 | #include 33 | #include 34 | #include 35 | #ifdef _WIN32 36 | 37 | # define NOMINMAX 38 | # define WIN32_LEAN_AND_MEAN 39 | # include 40 | 41 | # ifdef ERROR 42 | # undef ERROR 43 | # endif // ERROR 44 | 45 | # define SCHED_FIFO (1) 46 | 47 | typedef HANDLE pthread_t; 48 | 49 | static inline pthread_t pthread_self() 50 | { 51 | return ::GetCurrentThread(); 52 | } 53 | 54 | static inline int sched_get_priority_max(int policy) 55 | { 56 | (void)policy; 57 | return THREAD_PRIORITY_TIME_CRITICAL; 58 | } 59 | 60 | #else // _WIN32 61 | 62 | # include 63 | 64 | #endif // _WIN32 65 | 66 | namespace urcl 67 | { 68 | bool setFiFoScheduling(pthread_t& thread, const int priority); 69 | 70 | /*! 71 | * \brief Wait for a condition to be true. 72 | * 73 | * This function will wait for a condition to be true. The condition is checked in intervals of \p check_interval. 74 | * If the condition is not met after \p timeout, the function will throw a urcl::TimeoutException. 75 | * 76 | * \param condition The condition to be checked. 77 | * \param timeout The maximum time to wait for the condition to be true. 78 | * \param check_interval The interval in which the condition is checked. 79 | */ 80 | void waitFor(std::function condition, const std::chrono::milliseconds timeout, 81 | const std::chrono::milliseconds check_interval = std::chrono::milliseconds(50)); 82 | 83 | /*! 84 | * \brief Parses a boolean value from a string. 85 | * 86 | * The string can be one of 87 | * - true, True, TRUE 88 | * - on, On, ON 89 | * - yes, Yes, YES 90 | * - 1 91 | * - false, False, FALSE 92 | * - off, Off, OFF 93 | * - no, No, NO 94 | * - 0 95 | * 96 | * \param str string to be parsed 97 | * \throws urcl::UrException If the string doesn't match one of the options 98 | * \return The boolean representation of the string 99 | */ 100 | bool parseBoolean(const std::string& str); 101 | 102 | } // namespace urcl 103 | #endif // ifndef UR_CLIENT_LIBRARY_HELPERS_H_INCLUDED 104 | -------------------------------------------------------------------------------- /include/ur_client_library/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017, 2018 Simon Rasmussen (refactor) 3 | * 4 | * Copyright 2015, 2016 Thomas Timm Andersen (original version) 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #pragma once 20 | #include 21 | #include 22 | 23 | #define URCL_LOG_DEBUG(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::DEBUG, __VA_ARGS__) 24 | #define URCL_LOG_WARN(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::WARN, __VA_ARGS__) 25 | #define URCL_LOG_INFO(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::INFO, __VA_ARGS__) 26 | #define URCL_LOG_ERROR(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::ERROR, __VA_ARGS__) 27 | #define URCL_LOG_FATAL(...) urcl::log(__FILE__, __LINE__, urcl::LogLevel::FATAL, __VA_ARGS__) 28 | 29 | namespace urcl 30 | { 31 | /*! 32 | * \brief Different log levels 33 | */ 34 | enum class LogLevel 35 | { 36 | DEBUG = 0, 37 | INFO, 38 | WARN, 39 | ERROR, 40 | FATAL, 41 | NONE 42 | }; 43 | 44 | /*! 45 | * \brief Inherit from this class to change the behavior when logging messages. 46 | */ 47 | class LogHandler 48 | { 49 | public: 50 | virtual ~LogHandler() = default; 51 | /*! 52 | * \brief Function to log a message 53 | * 54 | * \param file The log message comes from this file 55 | * \param line The log message comes from this line 56 | * \param loglevel Indicates the severity of the log message 57 | * \param log Log message 58 | */ 59 | virtual void log(const char* file, int line, LogLevel loglevel, const char* log) = 0; 60 | }; 61 | 62 | /*! 63 | * \brief Register a new LogHandler object, for handling log messages. 64 | * 65 | * \param loghandler Pointer to the new object 66 | */ 67 | void registerLogHandler(std::unique_ptr loghandler); 68 | 69 | /*! 70 | * \brief Unregister current log handler, this will enable default log handler. 71 | */ 72 | void unregisterLogHandler(); 73 | 74 | /*! 75 | * \brief Set log level this will disable messages with lower log level. 76 | * 77 | * \param level desired log level 78 | */ 79 | void setLogLevel(LogLevel level); 80 | 81 | /*! 82 | * \brief Log a message, this is used internally by the macros to unpack the log message. 83 | * Use the macros instead of this function directly. 84 | * 85 | * \param file The log message comes from this file 86 | * \param line The log message comes from this line 87 | * \param level Severity of the log message 88 | * \param fmt Format string 89 | */ 90 | void log(const char* file, int line, LogLevel level, const char* fmt, ...); 91 | 92 | } // namespace urcl 93 | -------------------------------------------------------------------------------- /include/ur_client_library/primary/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,readability-identifier-naming' 2 | CheckOptions: 3 | - { key: readability-identifier-naming.NamespaceCase, value: lower_case } 4 | - { key: readability-identifier-naming.ClassCase, value: CamelCase } 5 | - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ } 6 | - { key: readability-identifier-naming.StructCase, value: CamelCase } 7 | - { key: readability-identifier-naming.FunctionCase, value: camelBack } 8 | - { key: readability-identifier-naming.VariableCase, value: lower_case } 9 | - { key: readability-identifier-naming.GlobalVariablePrefix, value: g_ } 10 | - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } 11 | -------------------------------------------------------------------------------- /include/ur_client_library/primary/abstract_primary_consumer.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | // 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2020 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2020-04-30 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_ROBOT_DRIVER_ABSTRACT_PRIMARY_CONSUMER_H_INCLUDED 30 | #define UR_ROBOT_DRIVER_ABSTRACT_PRIMARY_CONSUMER_H_INCLUDED 31 | 32 | #include "ur_client_library/log.h" 33 | #include "ur_client_library/comm/pipeline.h" 34 | #include "ur_client_library/primary/robot_message/version_message.h" 35 | #include "ur_client_library/primary/robot_message/error_code_message.h" 36 | #include "ur_client_library/primary/robot_state/kinematics_info.h" 37 | #include "ur_client_library/primary/robot_state/robot_mode_data.h" 38 | #include "ur_client_library/primary/robot_state/configuration_data.h" 39 | 40 | namespace urcl 41 | { 42 | namespace primary_interface 43 | { 44 | /*! 45 | * \brief Base consumer for primary packages 46 | * 47 | * Primary interface consumers can inherit from this class in order to implement the visitor 48 | * pattern for consuming primary packages. 49 | */ 50 | class AbstractPrimaryConsumer : public comm::IConsumer 51 | { 52 | public: 53 | AbstractPrimaryConsumer() = default; 54 | virtual ~AbstractPrimaryConsumer() = default; 55 | 56 | /*! 57 | * \brief This consume method is usually being called by the Pipeline structure. We don't 58 | * necessarily need to know the specific package type here, as the packages themselves will take 59 | * care to be consumed with the correct function (visitor pattern). 60 | * 61 | * \param product package as it is received from the robot 62 | * 63 | * \returns true on successful consuming 64 | */ 65 | virtual bool consume(std::shared_ptr product) final 66 | { 67 | if (product != nullptr) 68 | { 69 | return product->consumeWith(*this); 70 | } 71 | return false; 72 | } 73 | 74 | // To be implemented in specific consumers 75 | virtual bool consume(RobotMessage& pkg) = 0; 76 | virtual bool consume(RobotState& pkg) = 0; 77 | virtual bool consume(VersionMessage& pkg) = 0; 78 | virtual bool consume(KinematicsInfo& pkg) = 0; 79 | virtual bool consume(ErrorCodeMessage& pkg) = 0; 80 | virtual bool consume(RobotModeData& pkg) = 0; 81 | virtual bool consume(ConfigurationData& pkg) = 0; 82 | 83 | private: 84 | /* data */ 85 | }; 86 | } // namespace primary_interface 87 | } // namespace urcl 88 | 89 | #endif // ifndef UR_ROBOT_DRIVER_ABSTRACT_PRIMARY_CONSUMER_H_INCLUDED 90 | -------------------------------------------------------------------------------- /include/ur_client_library/primary/package_header.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \author Lea Steffen steffen@fzi.de 25 | * \date 2019-04-01 26 | * 27 | */ 28 | //---------------------------------------------------------------------- 29 | 30 | #ifndef UR_CLIENT_LIBRARY_PRIMARY_INTERFACE_H_INCLUDED 31 | #define UR_CLIENT_LIBRARY_PRIMARY_INTERFACE_H_INCLUDED 32 | 33 | #include 34 | #include 35 | #include 36 | #include "ur_client_library/types.h" 37 | 38 | namespace urcl 39 | { 40 | namespace primary_interface 41 | { 42 | static const int UR_PRIMARY_PORT = 30001; 43 | static const int UR_SECONDARY_PORT = 30002; 44 | /*! 45 | * \brief Possible RobotPackage types 46 | */ 47 | enum class RobotPackageType : int8_t 48 | { 49 | DISCONNECT = -1, 50 | ROBOT_STATE = 16, 51 | ROBOT_MESSAGE = 20, 52 | HMC_MESSAGE = 22, 53 | MODBUS_INFO_MESSAGE = 5, 54 | SAFETY_SETUP_BROADCAST_MESSAGE = 23, 55 | SAFETY_COMPLIANCE_TOLERANCES_MESSAGE = 24, 56 | PROGRAM_STATE_MESSAGE = 25 57 | }; 58 | 59 | /*! 60 | * \brief This class represents the header for primary packages. 61 | */ 62 | class PackageHeader 63 | { 64 | public: 65 | PackageHeader() = default; 66 | virtual ~PackageHeader() = default; 67 | 68 | using _package_size_type = int32_t; 69 | 70 | /*! 71 | * \brief Reads a buffer, interpreting the next bytes as the size of the contained package. 72 | * 73 | * \param buf The given byte stream containing a serialized package 74 | * 75 | * \returns The size of the given serialized package 76 | */ 77 | static size_t getPackageLength(uint8_t* buf) 78 | { 79 | return be32toh(*(reinterpret_cast<_package_size_type*>(buf))); 80 | } 81 | }; 82 | } // namespace primary_interface 83 | } // namespace urcl 84 | 85 | #endif // ifndef UR_CLIENT_LIBRARY_PRIMARY_INTERFACE_H_INCLUDED 86 | -------------------------------------------------------------------------------- /include/ur_client_library/primary/primary_package.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Lea Steffen steffen@fzi.de 24 | * \date 2019-04-01 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_PRIMARY_PACKAGE_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_PRIMARY_PACKAGE_H_INCLUDED 31 | 32 | #include "ur_client_library/primary/package_header.h" 33 | #include "ur_client_library/comm/package.h" 34 | 35 | namespace urcl 36 | { 37 | namespace primary_interface 38 | { 39 | class AbstractPrimaryConsumer; 40 | 41 | /*! 42 | * \brief The PrimaryPackage is solely an abstraction level. 43 | * It inherits form the URPackage and is also a parent class for primary_interface::RobotMessage, 44 | * primary_interface::RobotState 45 | */ 46 | class PrimaryPackage : public comm::URPackage 47 | { 48 | public: 49 | /*! 50 | * \brief Creates a new PrimaryPackage object. 51 | */ 52 | PrimaryPackage() : buffer_length_(0) 53 | { 54 | } 55 | virtual ~PrimaryPackage() = default; 56 | 57 | /*! 58 | * \brief Sets the attributes of the package by parsing a serialized representation of the 59 | * package. 60 | * 61 | * \param bp A parser containing a serialized version of the package 62 | * 63 | * \returns True, if the package was parsed successfully, false otherwise 64 | */ 65 | virtual bool parseWith(comm::BinParser& bp); 66 | 67 | /*! 68 | * \brief Consume this package with a specific consumer. This should be overwritten in inherited 69 | * packages 70 | * 71 | * \param consumer Placeholder for the consumer calling this 72 | * 73 | * \returns true on success 74 | */ 75 | virtual bool consumeWith(AbstractPrimaryConsumer& consumer) = 0; 76 | 77 | /*! 78 | * \brief Produces a human readable representation of the package object. 79 | * 80 | * \returns A string representing the object 81 | */ 82 | virtual std::string toString() const; 83 | 84 | protected: 85 | std::unique_ptr buffer_; 86 | size_t buffer_length_; 87 | }; 88 | 89 | } // namespace primary_interface 90 | } // namespace urcl 91 | 92 | #endif /* UR_CLIENT_LIBRARY_PRIMARY_PACKAGE_H_INCLUDED */ 93 | -------------------------------------------------------------------------------- /include/ur_client_library/primary/robot_message/version_message.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-08 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_VERSION_MESSAGE_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_VERSION_MESSAGE_H_INCLUDED 31 | 32 | #include "ur_client_library/primary/robot_message.h" 33 | 34 | namespace urcl 35 | { 36 | namespace primary_interface 37 | { 38 | /*! 39 | * \brief The VersionMessage class handles the version messages sent via the primary UR interface. 40 | */ 41 | class VersionMessage : public RobotMessage 42 | { 43 | public: 44 | VersionMessage() = delete; 45 | /*! 46 | * \brief Creates a new VersionMessage object to be filled from a package. 47 | * 48 | * \param timestamp Timestamp of the package 49 | * \param source The package's source 50 | */ 51 | VersionMessage(uint64_t timestamp, uint8_t source) : RobotMessage(timestamp, source) 52 | { 53 | } 54 | virtual ~VersionMessage() = default; 55 | 56 | /*! 57 | * \brief Sets the attributes of the package by parsing a serialized representation of the 58 | * package. 59 | * 60 | * \param bp A parser containing a serialized version of the package 61 | * 62 | * \returns True, if the package was parsed successfully, false otherwise 63 | */ 64 | virtual bool parseWith(comm::BinParser& bp); 65 | 66 | /*! 67 | * \brief Consume this package with a specific consumer. 68 | * 69 | * \param consumer Placeholder for the consumer calling this 70 | * 71 | * \returns true on success 72 | */ 73 | virtual bool consumeWith(AbstractPrimaryConsumer& consumer); 74 | 75 | /*! 76 | * \brief Produces a human readable representation of the package object. 77 | * 78 | * \returns A string representing the object 79 | */ 80 | virtual std::string toString() const; 81 | 82 | int8_t project_name_length_; 83 | std::string project_name_; 84 | uint8_t major_version_; 85 | uint8_t minor_version_; 86 | int32_t svn_version_; 87 | int32_t build_number_; 88 | std::string build_date_; 89 | }; 90 | } // namespace primary_interface 91 | } // namespace urcl 92 | 93 | #endif // ifndef UR_CLIENT_LIBRARY_VERSION_MESSAGE_H_INCLUDED 94 | -------------------------------------------------------------------------------- /include/ur_client_library/primary/robot_state.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Lea Steffen steffen@fzi.de 24 | * \date 2019-04-01 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_ROBOT_STATE_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_ROBOT_STATE_H_INCLUDED 31 | 32 | #include "ur_client_library/primary/primary_package.h" 33 | #include "ur_client_library/primary/package_header.h" 34 | 35 | namespace urcl 36 | { 37 | namespace primary_interface 38 | { 39 | /*! 40 | * \brief Possible RobotState types 41 | */ 42 | enum class RobotStateType : uint8_t 43 | { 44 | ROBOT_MODE_DATA = 0, 45 | JOINT_DATA = 1, 46 | TOOL_DATA = 2, 47 | MASTERBOARD_DATA = 3, 48 | CARTESIAN_INFO = 4, 49 | KINEMATICS_INFO = 5, 50 | CONFIGURATION_DATA = 6, 51 | FORCE_MODE_DATA = 7, 52 | ADDITIONAL_INFO = 8, 53 | CALIBRATION_DATA = 9 54 | }; 55 | 56 | /*! 57 | * \brief Base class for a RobotState data packages will be used directly. 58 | */ 59 | class RobotState : public PrimaryPackage 60 | { 61 | public: 62 | RobotState() = delete; 63 | /*! 64 | * \brief Creates a new RobotState object, setting the type of state message. 65 | * 66 | * \param type The type of state message 67 | */ 68 | RobotState(const RobotStateType type) : state_type_(type) 69 | { 70 | } 71 | virtual ~RobotState() = default; 72 | 73 | /*! 74 | * \brief Sets the attributes of the package by parsing a serialized representation of the 75 | * package. 76 | * 77 | * \param bp A parser containing a serialized version of the package 78 | * 79 | * \returns True, if the package was parsed successfully, false otherwise 80 | */ 81 | virtual bool parseWith(comm::BinParser& bp); 82 | 83 | /*! 84 | * \brief Consume this specific package with a specific consumer. 85 | * 86 | * \param consumer Placeholder for the consumer calling this 87 | * 88 | * \returns true on success 89 | */ 90 | virtual bool consumeWith(AbstractPrimaryConsumer& consumer); 91 | 92 | /*! 93 | * \brief Produces a human readable representation of the package object. 94 | * 95 | * \returns A string representing the object 96 | */ 97 | virtual std::string toString() const; 98 | 99 | private: 100 | RobotStateType state_type_; 101 | }; 102 | 103 | } // namespace primary_interface 104 | } // namespace urcl 105 | 106 | #endif /* UR_CLIENT_LIBRARY_ROBOT_STATE_H_INCLUDED */ 107 | -------------------------------------------------------------------------------- /include/ur_client_library/queue/.clang-tidy: -------------------------------------------------------------------------------- 1 | # Disable all checks in this folder. 2 | Checks: '-*' 3 | -------------------------------------------------------------------------------- /include/ur_client_library/queue/LICENSE.md: -------------------------------------------------------------------------------- 1 | This license applies to all the code in this folder except that written by third parties, namely 2 | Jeff Preshing's semaphore implementation (used in the blocking queue) which has a zlib license 3 | (embedded in atomicops.h). 4 | 5 | Simplified BSD License: 6 | 7 | Copyright (c) 2013-2015, Cameron Desrochers 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without modification, 11 | are permitted provided that the following conditions are met: 12 | 13 | - Redistributions of source code must retain the above copyright notice, this list of 14 | conditions and the following disclaimer. 15 | - Redistributions in binary form must reproduce the above copyright notice, this list of 16 | conditions and the following disclaimer in the documentation and/or other materials 17 | provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 24 | OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 26 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*,readability-identifier-naming' 2 | CheckOptions: 3 | - { key: readability-identifier-naming.NamespaceCase, value: lower_case } 4 | - { key: readability-identifier-naming.ClassCase, value: CamelCase } 5 | - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ } 6 | - { key: readability-identifier-naming.StructCase, value: CamelCase } 7 | - { key: readability-identifier-naming.FunctionCase, value: camelBack } 8 | - { key: readability-identifier-naming.VariableCase, value: lower_case } 9 | - { key: readability-identifier-naming.GlobalVariablePrefix, value: g_ } 10 | - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } 11 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/control_package_pause.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_CONTROL_PACKAGE_PAUSE_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_CONTROL_PACKAGE_PAUSE_H_INCLUDED 31 | 32 | #include "ur_client_library/rtde/rtde_package.h" 33 | 34 | namespace urcl 35 | { 36 | namespace rtde_interface 37 | { 38 | /*! 39 | * \brief This class handles the robot's response to a requested stop in RTDE data package 40 | * communication. 41 | */ 42 | class ControlPackagePause : public RTDEPackage 43 | { 44 | public: 45 | /*! 46 | * \brief Creates a new ControlPackagePause object. 47 | */ 48 | ControlPackagePause() : RTDEPackage(PackageType::RTDE_CONTROL_PACKAGE_PAUSE) 49 | { 50 | } 51 | virtual ~ControlPackagePause() = default; 52 | 53 | /*! 54 | * \brief Sets the attributes of the package by parsing a serialized representation of the 55 | * package. 56 | * 57 | * \param bp A parser containing a serialized version of the package 58 | * 59 | * \returns True, if the package was parsed successfully, false otherwise 60 | */ 61 | virtual bool parseWith(comm::BinParser& bp); 62 | /*! 63 | * \brief Produces a human readable representation of the package object. 64 | * 65 | * \returns A string representing the object 66 | */ 67 | virtual std::string toString() const; 68 | 69 | uint8_t accepted_; 70 | }; 71 | 72 | /*! 73 | * \brief This class is used to request a stop in RTDE data package communication. 74 | */ 75 | class ControlPackagePauseRequest : public RTDEPackage 76 | { 77 | public: 78 | /*! 79 | * \brief Creates a new ControlPackagePauseRequest object. 80 | */ 81 | ControlPackagePauseRequest() : RTDEPackage(PackageType::RTDE_CONTROL_PACKAGE_PAUSE) 82 | { 83 | } 84 | virtual ~ControlPackagePauseRequest() = default; 85 | 86 | /*! 87 | * \brief Generates a serialized package. 88 | * 89 | * \param buffer Buffer to fill with the serialization 90 | * 91 | * \returns The total size of the serialized package 92 | */ 93 | static size_t generateSerializedRequest(uint8_t* buffer); 94 | 95 | private: 96 | static const uint16_t PAYLOAD_SIZE = 0; 97 | }; 98 | 99 | } // namespace rtde_interface 100 | } // namespace urcl 101 | 102 | #endif // UR_CLIENT_LIBRARY_CONTROL_PACKAGE_PAUSE_H_INCLUDED 103 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/control_package_start.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_CONTROL_PACKAGE_START_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_CONTROL_PACKAGE_START_H_INCLUDED 31 | 32 | #include "ur_client_library/rtde/rtde_package.h" 33 | 34 | namespace urcl 35 | { 36 | namespace rtde_interface 37 | { 38 | /*! 39 | * \brief This class handles the robot's response to a requested start in RTDE data package 40 | * communication. 41 | */ 42 | class ControlPackageStart : public RTDEPackage 43 | { 44 | public: 45 | /*! 46 | * \brief Creates a new ControlPackageStart object. 47 | */ 48 | ControlPackageStart() : RTDEPackage(PackageType::RTDE_CONTROL_PACKAGE_START) 49 | { 50 | } 51 | virtual ~ControlPackageStart() = default; 52 | 53 | /*! 54 | * \brief Sets the attributes of the package by parsing a serialized representation of the 55 | * package. 56 | * 57 | * \param bp A parser containing a serialized version of the package 58 | * 59 | * \returns True, if the package was parsed successfully, false otherwise 60 | */ 61 | virtual bool parseWith(comm::BinParser& bp); 62 | /*! 63 | * \brief Produces a human readable representation of the package object. 64 | * 65 | * \returns A string representing the object 66 | */ 67 | virtual std::string toString() const; 68 | 69 | uint8_t accepted_; 70 | }; 71 | 72 | /*! 73 | * \brief This class is used to request a stop in RTDE data package communication. 74 | */ 75 | class ControlPackageStartRequest : public RTDEPackage 76 | { 77 | public: 78 | /*! 79 | * \brief Creates a new ControlPackageStartRequest object. 80 | */ 81 | ControlPackageStartRequest() : RTDEPackage(PackageType::RTDE_CONTROL_PACKAGE_START) 82 | { 83 | } 84 | virtual ~ControlPackageStartRequest() = default; 85 | 86 | /*! 87 | * \brief Generates a serialized package. 88 | * 89 | * \param buffer Buffer to fill with the serialization 90 | * 91 | * \returns The total size of the serialized package 92 | */ 93 | static size_t generateSerializedRequest(uint8_t* buffer); 94 | 95 | private: 96 | static const uint16_t PAYLOAD_SIZE = 0; 97 | }; 98 | 99 | } // namespace rtde_interface 100 | } // namespace urcl 101 | 102 | #endif // UR_CLIENT_LIBRARY_CONTROL_PACKAGE_START_H_INCLUDED 103 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/get_urcontrol_version.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_GET_URCONTROL_VERSION_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_GET_URCONTROL_VERSION_H_INCLUDED 31 | 32 | #include "ur_client_library/rtde/rtde_package.h" 33 | #include "ur_client_library/ur/version_information.h" 34 | 35 | namespace urcl 36 | { 37 | namespace rtde_interface 38 | { 39 | /*! 40 | * \brief This class handles the package detailing the UR control version sent by the robot. 41 | */ 42 | class GetUrcontrolVersion : public RTDEPackage 43 | { 44 | public: 45 | /*! 46 | * \brief Creates a new GetUrcontrolVersion object. 47 | */ 48 | GetUrcontrolVersion() : RTDEPackage(PackageType::RTDE_GET_URCONTROL_VERSION) 49 | { 50 | } 51 | virtual ~GetUrcontrolVersion() = default; 52 | 53 | /*! 54 | * \brief Sets the attributes of the package by parsing a serialized representation of the 55 | * package. 56 | * 57 | * \param bp A parser containing a serialized version of the package 58 | * 59 | * \returns True, if the package was parsed successfully, false otherwise 60 | */ 61 | virtual bool parseWith(comm::BinParser& bp); 62 | /*! 63 | * \brief Produces a human readable representation of the package object. 64 | * 65 | * \returns A string representing the object 66 | */ 67 | virtual std::string toString() const; 68 | 69 | VersionInformation version_information_; 70 | }; 71 | 72 | /*! 73 | * \brief This class is used to request the used UR control version from the robot. 74 | */ 75 | class GetUrcontrolVersionRequest : public RTDEPackage 76 | { 77 | public: 78 | /*! 79 | * \brief Creates a new GetUrcontrolVersionRequest object. 80 | */ 81 | GetUrcontrolVersionRequest() : RTDEPackage(PackageType::RTDE_GET_URCONTROL_VERSION) 82 | { 83 | } 84 | virtual ~GetUrcontrolVersionRequest() = default; 85 | 86 | /*! 87 | * \brief Generates a serialized package. 88 | * 89 | * \param buffer Buffer to fill with the serialization 90 | * 91 | * \returns The total size of the serialized package 92 | */ 93 | static size_t generateSerializedRequest(uint8_t* buffer); 94 | 95 | private: 96 | static const uint16_t PAYLOAD_SIZE = 0; 97 | }; 98 | 99 | } // namespace rtde_interface 100 | } // namespace urcl 101 | 102 | #endif // UR_CLIENT_LIBRARY_GET_URCONTROL_VERSION_H_INCLUDED 103 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/package_header.h: -------------------------------------------------------------------------------- 1 | 2 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 3 | 4 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 5 | // Copyright 2019 FZI Forschungszentrum Informatik 6 | // Created on behalf of Universal Robots A/S 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // -- END LICENSE BLOCK ------------------------------------------------ 20 | 21 | //---------------------------------------------------------------------- 22 | /*!\file 23 | * 24 | * \author Lea Steffen steffen@fzi.de 25 | * \date 2019-04-01 26 | * 27 | */ 28 | //---------------------------------------------------------------------- 29 | 30 | #ifndef UR_CLIENT_LIBRARY_RTDE__HEADER_H_INCLUDED 31 | #define UR_CLIENT_LIBRARY_RTDE__HEADER_H_INCLUDED 32 | 33 | #include 34 | #include 35 | #include "ur_client_library/types.h" 36 | #include "ur_client_library/comm/package_serializer.h" 37 | 38 | namespace urcl 39 | { 40 | namespace rtde_interface 41 | { 42 | /*! 43 | * \brief Possible package types 44 | */ 45 | enum class PackageType : uint8_t 46 | { 47 | RTDE_REQUEST_PROTOCOL_VERSION = 86, // ascii V 48 | RTDE_GET_URCONTROL_VERSION = 118, // ascii v 49 | RTDE_TEXT_MESSAGE = 77, // ascii M 50 | RTDE_DATA_PACKAGE = 85, // ascii U 51 | RTDE_CONTROL_PACKAGE_SETUP_OUTPUTS = 79, // ascii O 52 | RTDE_CONTROL_PACKAGE_SETUP_INPUTS = 73, // ascii I 53 | RTDE_CONTROL_PACKAGE_START = 83, // ascii S 54 | RTDE_CONTROL_PACKAGE_PAUSE = 80 // ascii P 55 | }; 56 | 57 | /*! 58 | * \brief This class represents the header for RTDE packages. 59 | */ 60 | class PackageHeader 61 | { 62 | public: 63 | PackageHeader() = default; 64 | virtual ~PackageHeader() = default; 65 | using _package_size_type = uint16_t; 66 | 67 | /*! 68 | * \brief Reads a buffer, interpreting the next bytes as the size of the contained package. 69 | * 70 | * \param buf The given byte stream containing a serialized package 71 | * 72 | * \returns The size of the given serialized package 73 | */ 74 | static size_t getPackageLength(uint8_t* buf) 75 | { 76 | return be16toh(*(reinterpret_cast<_package_size_type*>(buf))); 77 | } 78 | 79 | /*! 80 | * \brief Creates a serialization of a header based on given values. 81 | * 82 | * \param buffer The buffer to write the serialization to 83 | * \param package_type The type of the package 84 | * \param payload_length The length of the package's payload 85 | * 86 | * \returns 87 | */ 88 | static size_t serializeHeader(uint8_t* buffer, PackageType package_type, uint16_t payload_length) 89 | { 90 | uint16_t header_size = sizeof(_package_size_type) + sizeof(PackageType); 91 | uint16_t size = header_size + payload_length; 92 | comm::PackageSerializer::serialize(buffer, size); 93 | comm::PackageSerializer::serialize(buffer + sizeof(size), package_type); 94 | return header_size; 95 | } 96 | }; 97 | 98 | } // namespace rtde_interface 99 | } // namespace urcl 100 | 101 | #endif // #ifndef UR_CLIENT_LIBRARY_RTDE__HEADER_H_INCLUDED 102 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/rtde_package.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Lea Steffen steffen@fzi.de 24 | * \date 2019-04-01 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_RTDE_PACKAGE_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_RTDE_PACKAGE_H_INCLUDED 31 | 32 | #include "ur_client_library/rtde/package_header.h" 33 | #include "ur_client_library/comm/package.h" 34 | 35 | namespace urcl 36 | { 37 | namespace rtde_interface 38 | { 39 | /*! 40 | * brief The RTDEPackage is solely an abstraction level. 41 | * It inherits form the URPackage and is also a parent class for rtde_interface::TextMessage. 42 | */ 43 | class RTDEPackage : public comm::URPackage 44 | { 45 | public: 46 | /*! 47 | * \brief Creates a new RTDEPackage object. 48 | */ 49 | RTDEPackage() = delete; 50 | RTDEPackage(const PackageType type) : type_(type) 51 | { 52 | } 53 | virtual ~RTDEPackage() = default; 54 | 55 | /*! 56 | * \brief Sets the attributes of the package by parsing a serialized representation of the 57 | * package. 58 | * 59 | * \param bp A parser containing a serialized version of the package 60 | * 61 | * \returns True, if the package was parsed successfully, false otherwise 62 | */ 63 | virtual bool parseWith(comm::BinParser& bp); 64 | /*! 65 | * \brief Produces a human readable representation of the package object. 66 | * 67 | * \returns A string representing the object 68 | */ 69 | virtual std::string toString() const; 70 | 71 | protected: 72 | std::unique_ptr buffer_; 73 | size_t buffer_length_; 74 | PackageType type_; 75 | }; 76 | 77 | } // namespace rtde_interface 78 | } // namespace urcl 79 | 80 | #endif // UR_CLIENT_LIBRARY_RTDE_PACKAGE_H_INCLUDED 81 | -------------------------------------------------------------------------------- /include/ur_client_library/rtde/text_message.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Lea Steffen steffen@fzi.de 24 | * \date 2019-04-01 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_TEXT_MESSAGE_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_TEXT_MESSAGE_H_INCLUDED 31 | 32 | #include "ur_client_library/rtde/rtde_package.h" 33 | 34 | namespace urcl 35 | { 36 | namespace rtde_interface 37 | { 38 | /*! 39 | * \brief This class handles RTDE text messages sent by the robot. 40 | */ 41 | class TextMessage : public RTDEPackage 42 | { 43 | public: 44 | /*! 45 | * \brief Creates a new TextMessage object. 46 | * 47 | * \param protocol_version Protocol version used for the RTDE communication 48 | */ 49 | TextMessage(uint16_t protocol_version) 50 | : RTDEPackage(PackageType::RTDE_TEXT_MESSAGE), protocol_version_(protocol_version) 51 | { 52 | } 53 | virtual ~TextMessage() = default; 54 | 55 | /*! 56 | * \brief Sets the attributes of the package by parsing a serialized representation of the 57 | * package. 58 | * 59 | * \param bp A parser containing a serialized version of the package 60 | * 61 | * \returns True, if the package was parsed successfully, false otherwise 62 | */ 63 | virtual bool parseWith(comm::BinParser& bp); 64 | /*! 65 | * \brief Produces a human readable representation of the package object. 66 | * 67 | * \returns A string representing the object 68 | */ 69 | virtual std::string toString() const; 70 | 71 | uint8_t message_length_; 72 | std::string message_; 73 | uint8_t source_length_; 74 | std::string source_; 75 | uint8_t warning_level_; 76 | 77 | uint8_t message_type_; 78 | 79 | uint16_t protocol_version_; 80 | }; 81 | 82 | } // namespace rtde_interface 83 | } // namespace urcl 84 | 85 | #endif // UR_CLIENT_LIBRARY_TEXT_MESSAGE_H_INCLUDED 86 | -------------------------------------------------------------------------------- /include/ur_client_library/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, FZI Forschungszentrum Informatik (refactor) 3 | * 4 | * Copyright 2017, 2018 Simon Rasmussen (refactor) 5 | * 6 | * Copyright 2015, 2016 Thomas Timm Andersen (original version) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace urcl 28 | { 29 | using vector3d_t = std::array; 30 | using vector6d_t = std::array; 31 | using vector6int32_t = std::array; 32 | using vector6uint32_t = std::array; 33 | 34 | struct Pose 35 | { 36 | Pose() : x(0.0), y(0.0), z(0.0), rx(0.0), ry(0.0), rz(0.0) 37 | { 38 | } 39 | Pose(const double x, const double y, const double z, const double rx, const double ry, const double rz) 40 | : x(x), y(y), z(z), rx(rx), ry(ry), rz(rz) 41 | { 42 | } 43 | double x; 44 | double y; 45 | double z; 46 | double rx; 47 | double ry; 48 | double rz; 49 | 50 | bool operator==(const Pose& other) const 51 | { 52 | return x == other.x && y == other.y && z == other.z && rx == other.rx && ry == other.ry && rz == other.rz; 53 | } 54 | }; 55 | 56 | template 57 | std::ostream& operator<<(std::ostream& out, const std::array& item) 58 | { 59 | out << "["; 60 | for (size_t i = 0; i < item.size(); ++i) 61 | { 62 | out << item[i]; 63 | if (i != item.size() - 1) 64 | { 65 | out << ", "; 66 | } 67 | } 68 | out << "]"; 69 | return out; 70 | } 71 | 72 | /*! 73 | * \brief Converts an enum type to its underlying type 74 | * 75 | * \param e Enum value that should be converted 76 | * 77 | * \returns Enum value converted to underlying type 78 | */ 79 | template 80 | constexpr typename std::underlying_type::type toUnderlying(const E e) noexcept 81 | { 82 | return static_cast::type>(e); 83 | } 84 | } // namespace urcl -------------------------------------------------------------------------------- /include/ur_client_library/ur/version_information.h: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-06-11 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #ifndef UR_CLIENT_LIBRARY_UR_VERSION_INFORMATION_H_INCLUDED 30 | #define UR_CLIENT_LIBRARY_UR_VERSION_INFORMATION_H_INCLUDED 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | namespace urcl 38 | { 39 | /*! 40 | * \brief Struct containing a robot's version information 41 | */ 42 | class VersionInformation 43 | { 44 | public: 45 | VersionInformation(); 46 | ~VersionInformation() = default; 47 | 48 | /*! 49 | * \brief Parses a version string into a VersionInformation object 50 | * 51 | * \param str Version string such as "5.12.0.1101319" 52 | * 53 | * \returns A parsed VersionInformation object 54 | */ 55 | static VersionInformation fromString(const std::string& str); 56 | 57 | /*! 58 | * \brief Generates a string representation of the version information such as "5.12.0.1101319" 59 | */ 60 | std::string toString() const; 61 | 62 | bool isESeries() const; 63 | 64 | friend bool operator==(const VersionInformation& v1, const VersionInformation& v2); 65 | friend bool operator!=(const VersionInformation& v1, const VersionInformation& v2); 66 | friend bool operator<(const VersionInformation& v1, const VersionInformation& v2); 67 | friend bool operator<=(const VersionInformation& v1, const VersionInformation& v2); 68 | friend bool operator>(const VersionInformation& v1, const VersionInformation& v2); 69 | friend bool operator>=(const VersionInformation& v1, const VersionInformation& v2); 70 | 71 | friend std::ostream& operator<<(std::ostream& os, const VersionInformation& version_info) 72 | { 73 | os << version_info.major << "." << version_info.minor << "." << version_info.bugfix << "-" << version_info.build; 74 | return os; 75 | } 76 | uint32_t major; ///< Major version number 77 | uint32_t minor; ///< Minor version number 78 | uint32_t bugfix; ///< Bugfix version number 79 | uint32_t build; ///< Build number 80 | }; 81 | 82 | std::vector splitString(std::string input, const std::string& delimiter = "."); 83 | } // namespace urcl 84 | 85 | #endif // ifndef UR_CLIENT_LIBRARY_UR_VERSION_INFORMATION_H_INCLUDED -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ur_client_library 5 | 2.1.0 6 | Standalone C++ library for accessing Universal Robots interfaces. This has been forked off the ur_robot_driver. 7 | Thomas Timm Andersen 8 | Simon Rasmussen 9 | Felix Exner 10 | Lea Steffen 11 | Tristan Schnell 12 | 13 | Felix Exner 14 | Rune Søe-Knudsen 15 | Universal Robots A/S 16 | 17 | Apache-2.0 18 | BSD-2-Clause 19 | Zlib 20 | 21 | http://wiki.ros.org/ur_client_library 22 | https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues 23 | https://github.com/UniversalRobots/Universal_Robots_Client_Library 24 | 25 | cmake 26 | 27 | catkin 28 | ament_cmake 29 | 30 | 31 | cmake 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /rosdoc.yaml: -------------------------------------------------------------------------------- 1 | - builder: sphinx 2 | sphinx_root_dir: doc 3 | - builder: doxygen 4 | name: C++ API 5 | output_dir: c++ 6 | file_patterns: '*.c *.cpp *.h *.cc *.hh *.dox *.md' 7 | use_mdfile_as_mainpage: README.md 8 | -------------------------------------------------------------------------------- /run_examples.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | folder_path="build/examples" 4 | 5 | # Check if the folder exists 6 | if [ ! -d "$folder_path" ]; then 7 | echo "Folder '$folder_path' not found." 8 | exit 1 9 | fi 10 | 11 | # Iterate over all executables in the folder 12 | for file in $folder_path/*; do 13 | echo $file 14 | # Check if the file is executable 15 | if [[ -f "$file" && -x "$file" ]]; then 16 | printf "\n#### Executing '$file'\n" 17 | # Execute the file 18 | ./"$file" $@ 19 | # Check the exit status 20 | exit_status=$? 21 | if [[ $exit_status -ne 0 ]]; then 22 | echo "Execution of '$file' failed with exit status $exit_status." 23 | exit 1 24 | fi 25 | # Delay for 10 seconds to avoid too fast reconnects 26 | echo "Sleep 10" 27 | sleep 10 28 | fi 29 | done 30 | -------------------------------------------------------------------------------- /src/control/script_sender.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2021 FZI Forschungszentrum Informatik 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | // -- END LICENSE BLOCK ------------------------------------------------ 18 | 19 | //---------------------------------------------------------------------- 20 | /*!\file 21 | * 22 | * \author Felix Exner exner@fzi.de 23 | * \date 2021-06-01 24 | * 25 | */ 26 | //---------------------------------------------------------------------- 27 | 28 | #include 29 | 30 | namespace urcl 31 | { 32 | namespace control 33 | { 34 | ScriptSender::ScriptSender(uint32_t port, const std::string& program) 35 | : server_(port), script_thread_(), program_(program) 36 | { 37 | server_.setMessageCallback( 38 | std::bind(&ScriptSender::messageCallback, this, std::placeholders::_1, std::placeholders::_2)); 39 | server_.setConnectCallback(std::bind(&ScriptSender::connectionCallback, this, std::placeholders::_1)); 40 | server_.setDisconnectCallback(std::bind(&ScriptSender::disconnectionCallback, this, std::placeholders::_1)); 41 | server_.start(); 42 | } 43 | 44 | void ScriptSender::connectionCallback(const socket_t filedescriptor) 45 | { 46 | URCL_LOG_DEBUG("New client connected at FD %d.", filedescriptor); 47 | } 48 | 49 | void ScriptSender::disconnectionCallback(const socket_t filedescriptor) 50 | { 51 | URCL_LOG_DEBUG("Client at FD %d disconnected.", filedescriptor); 52 | } 53 | 54 | void ScriptSender::messageCallback(const socket_t filedescriptor, char* buffer) 55 | { 56 | if (std::string(buffer) == PROGRAM_REQUEST_) 57 | { 58 | URCL_LOG_INFO("Robot requested program"); 59 | sendProgram(filedescriptor); 60 | } 61 | } 62 | 63 | void ScriptSender::sendProgram(const socket_t filedescriptor) 64 | { 65 | // urscripts (snippets) must end with a newline, or otherwise the controller's runtime will 66 | // not execute them. To avoid problems, we always just append a newline here, even if 67 | // there may already be one. 68 | const std::string send_string = program_ + "\n"; 69 | size_t len = send_string.size(); 70 | const uint8_t* data = reinterpret_cast(send_string.c_str()); 71 | size_t written; 72 | 73 | if (server_.write(filedescriptor, data, len, written)) 74 | { 75 | URCL_LOG_INFO("Sent program to robot"); 76 | } 77 | else 78 | { 79 | URCL_LOG_ERROR("Could not send program to robot"); 80 | } 81 | } 82 | 83 | } // namespace control 84 | } // namespace urcl -------------------------------------------------------------------------------- /src/default_log_handler.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2021 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #include "ur_client_library/default_log_handler.h" 32 | #include 33 | #include 34 | #include 35 | 36 | namespace urcl 37 | { 38 | 39 | DefaultLogHandler::DefaultLogHandler() = default; 40 | 41 | void DefaultLogHandler::log(const char* file, int line, LogLevel loglevel, const char* log) 42 | { 43 | auto timestamp = std::chrono::duration(std::chrono::system_clock::now().time_since_epoch()); 44 | 45 | switch (loglevel) 46 | { 47 | case LogLevel::INFO: 48 | printf("[%f] %s%s %i: %s \n", timestamp.count(), "INFO ", file, line, log); 49 | break; 50 | case LogLevel::DEBUG: 51 | printf("\033[36m[%f] %s%s %i: %s \033[0m\n", timestamp.count(), "DEBUG ", file, line, log); 52 | break; 53 | case LogLevel::WARN: 54 | printf("\033[33m[%f] %s%s %i: %s \033[0m\n", timestamp.count(), "WARN ", file, line, log); 55 | break; 56 | case LogLevel::ERROR: 57 | printf("\033[31m[%f] %s%s %i: %s \033[0m\n", timestamp.count(), "ERROR ", file, line, log); 58 | break; 59 | case LogLevel::FATAL: 60 | printf("\033[31m[%f] %s%s %i: %s \033[0m\n", timestamp.count(), "FATAL ", file, line, log); 61 | break; 62 | default: 63 | break; 64 | } 65 | } 66 | 67 | } // namespace urcl 68 | -------------------------------------------------------------------------------- /src/primary/primary_package.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/primary/primary_package.h" 30 | #include "ur_client_library/primary/abstract_primary_consumer.h" 31 | 32 | namespace urcl 33 | { 34 | namespace primary_interface 35 | { 36 | bool PrimaryPackage::parseWith(comm::BinParser& bp) 37 | { 38 | bp.rawData(buffer_, buffer_length_); 39 | return true; 40 | } 41 | 42 | std::string PrimaryPackage::toString() const 43 | { 44 | std::stringstream ss; 45 | ss << "Raw byte stream: "; 46 | for (size_t i = 0; i < buffer_length_; ++i) 47 | { 48 | uint8_t* buf = buffer_.get(); 49 | ss << std::hex << static_cast(buf[i]) << " "; 50 | } 51 | ss << std::endl; 52 | return ss.str(); 53 | } 54 | 55 | } // namespace primary_interface 56 | } // namespace urcl 57 | -------------------------------------------------------------------------------- /src/primary/robot_message.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik (ur_robot_driver) 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | #include "ur_client_library/primary/robot_message.h" 29 | #include "ur_client_library/primary/abstract_primary_consumer.h" 30 | 31 | namespace urcl 32 | { 33 | namespace primary_interface 34 | { 35 | bool RobotMessage::parseWith(comm::BinParser& bp) 36 | { 37 | return true; 38 | } 39 | 40 | bool RobotMessage::consumeWith(AbstractPrimaryConsumer& consumer) 41 | { 42 | return consumer.consume(*this); 43 | } 44 | 45 | std::string RobotMessage::toString() const 46 | { 47 | std::stringstream ss; 48 | ss << "timestamp: " << timestamp_ << std::endl; 49 | ss << "source: " << static_cast(source_) << std::endl; 50 | ss << "message_type: " << static_cast(message_type_) << std::endl; 51 | 52 | return ss.str(); 53 | } 54 | 55 | } // namespace primary_interface 56 | } // namespace urcl 57 | -------------------------------------------------------------------------------- /src/primary/robot_message/error_code_message.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2020 FZI Forschungszentrum Informatik 3 | // Created on behalf of Universal Robots A/S 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // -- END LICENSE BLOCK ------------------------------------------------ 17 | 18 | //---------------------------------------------------------------------- 19 | /*!\file 20 | * 21 | * \author Felix Exner exner@fzi.de 22 | * \date 2020-04-30 23 | * 24 | */ 25 | //---------------------------------------------------------------------- 26 | 27 | #include "ur_client_library/primary/robot_message/error_code_message.h" 28 | #include "ur_client_library/primary/abstract_primary_consumer.h" 29 | 30 | namespace urcl 31 | { 32 | namespace primary_interface 33 | { 34 | bool ErrorCodeMessage::parseWith(comm::BinParser& bp) 35 | { 36 | bp.parse(message_code_); 37 | bp.parse(message_argument_); 38 | int32_t report_level; 39 | bp.parse(report_level); 40 | report_level_ = static_cast(report_level); 41 | bp.parse(data_type_); 42 | bp.parse(data_); 43 | bp.parseRemainder(text_); 44 | 45 | return true; // not really possible to check dynamic size packets 46 | } 47 | 48 | bool ErrorCodeMessage::consumeWith(AbstractPrimaryConsumer& consumer) 49 | { 50 | return consumer.consume(*this); 51 | } 52 | 53 | std::string ErrorCodeMessage::toString() const 54 | { 55 | std::stringstream ss; 56 | ss << "C" << message_code_ << "A" << message_argument_; 57 | return ss.str(); 58 | } 59 | 60 | } // namespace primary_interface 61 | } // namespace urcl 62 | -------------------------------------------------------------------------------- /src/primary/robot_message/version_message.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik (ur_robot_driver) 5 | // Copyright 2017, 2018 Simon Rasmussen (refactor) 6 | // 7 | // Copyright 2015, 2016 Thomas Timm Andersen (original version) 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | // -- END LICENSE BLOCK ------------------------------------------------ 21 | 22 | //---------------------------------------------------------------------- 23 | /*!\file 24 | * 25 | * \author Felix Exner exner@fzi.de 26 | * \date 2019-04-08 27 | * 28 | */ 29 | //---------------------------------------------------------------------- 30 | 31 | #include "ur_client_library/log.h" 32 | #include "ur_client_library/primary/robot_message/version_message.h" 33 | #include "ur_client_library/primary/abstract_primary_consumer.h" 34 | 35 | namespace urcl 36 | { 37 | namespace primary_interface 38 | { 39 | bool VersionMessage::parseWith(comm::BinParser& bp) 40 | { 41 | bp.parse(project_name_length_); 42 | bp.parse(project_name_, project_name_length_); 43 | bp.parse(major_version_); 44 | bp.parse(minor_version_); 45 | bp.parse(svn_version_); 46 | bp.parse(build_number_); 47 | bp.parseRemainder(build_date_); 48 | 49 | return true; // not really possible to check dynamic size packets 50 | } 51 | 52 | bool VersionMessage ::consumeWith(AbstractPrimaryConsumer& consumer) 53 | { 54 | return consumer.consume(*this); 55 | } 56 | 57 | std::string VersionMessage::toString() const 58 | { 59 | std::stringstream ss; 60 | ss << "project name: " << project_name_ << std::endl; 61 | ss << "version: " << unsigned(major_version_) << "." << unsigned(minor_version_) << "." << svn_version_ << std::endl; 62 | ss << "build date: " << build_date_; 63 | 64 | return ss.str(); 65 | } 66 | } // namespace primary_interface 67 | } // namespace urcl 68 | -------------------------------------------------------------------------------- /src/primary/robot_state.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2020 FZI Forschungszentrum Informatik (ur_robot_driver) 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2020-04-30 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | #include 29 | 30 | #include "ur_client_library/primary/robot_state.h" 31 | #include "ur_client_library/primary/abstract_primary_consumer.h" 32 | 33 | namespace urcl 34 | { 35 | namespace primary_interface 36 | { 37 | bool RobotState::parseWith(comm::BinParser& bp) 38 | { 39 | return PrimaryPackage::parseWith(bp); 40 | } 41 | 42 | bool RobotState::consumeWith(AbstractPrimaryConsumer& consumer) 43 | { 44 | return consumer.consume(*this); 45 | } 46 | 47 | std::string RobotState::toString() const 48 | { 49 | std::stringstream ss; 50 | ss << "Type: " << static_cast(state_type_) << std::endl; 51 | ss << PrimaryPackage::toString(); 52 | return ss.str(); 53 | } 54 | 55 | } // namespace primary_interface 56 | } // namespace urcl 57 | -------------------------------------------------------------------------------- /src/primary/robot_state/kinematics_info.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-08 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/log.h" 30 | #include "ur_client_library/primary/robot_state/kinematics_info.h" 31 | #include "ur_client_library/primary/abstract_primary_consumer.h" 32 | 33 | #include 34 | 35 | namespace urcl 36 | { 37 | namespace primary_interface 38 | { 39 | bool KinematicsInfo::parseWith(comm::BinParser& bp) 40 | { 41 | bp.parse(checksum_); 42 | bp.parse(dh_theta_); 43 | bp.parse(dh_a_); 44 | bp.parse(dh_d_); 45 | bp.parse(dh_alpha_); 46 | bp.parse(calibration_status_); 47 | 48 | return true; 49 | } 50 | 51 | bool KinematicsInfo ::consumeWith(AbstractPrimaryConsumer& consumer) 52 | { 53 | return consumer.consume(*this); 54 | } 55 | 56 | std::string KinematicsInfo::toString() const 57 | { 58 | std::stringstream os; 59 | os << "checksum: ["; 60 | for (size_t i = 0; i < checksum_.size(); ++i) 61 | { 62 | os << checksum_[i] << " "; 63 | } 64 | os << "]" << std::endl; 65 | os << "dh_theta: ["; 66 | for (size_t i = 0; i < dh_theta_.size(); ++i) 67 | { 68 | os << std::setprecision(15) << dh_theta_[i] << " "; 69 | } 70 | os << "]" << std::endl; 71 | 72 | os << "dh_a: ["; 73 | for (size_t i = 0; i < dh_a_.size(); ++i) 74 | { 75 | os << std::setprecision(15) << dh_a_[i] << " "; 76 | } 77 | os << "]" << std::endl; 78 | 79 | os << "dh_d: ["; 80 | for (size_t i = 0; i < dh_d_.size(); ++i) 81 | { 82 | os << std::setprecision(15) << dh_d_[i] << " "; 83 | } 84 | os << "]" << std::endl; 85 | 86 | os << "dh_alpha: ["; 87 | for (size_t i = 0; i < dh_alpha_.size(); ++i) 88 | { 89 | os << std::setprecision(15) << dh_alpha_[i] << " "; 90 | } 91 | os << "]" << std::endl; 92 | 93 | os << "calibration_status: " << calibration_status_ << std::endl; 94 | 95 | return os.str(); 96 | } 97 | 98 | std::string KinematicsInfo::toHash() const 99 | { 100 | std::stringstream ss; 101 | for (size_t i = 0; i < 6; ++i) 102 | { 103 | ss << dh_theta_[i]; 104 | ss << dh_d_[i]; 105 | ss << dh_a_[i]; 106 | ss << dh_alpha_[i]; 107 | } 108 | std::hash hash_fn; 109 | return "calib_" + std::to_string(hash_fn(ss.str())); 110 | } 111 | } // namespace primary_interface 112 | } // namespace urcl 113 | -------------------------------------------------------------------------------- /src/rtde/control_package_pause.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/rtde/control_package_pause.h" 30 | 31 | namespace urcl 32 | { 33 | namespace rtde_interface 34 | { 35 | bool ControlPackagePause::parseWith(comm::BinParser& bp) 36 | { 37 | bp.parse(accepted_); 38 | 39 | return true; 40 | } 41 | std::string ControlPackagePause::toString() const 42 | { 43 | std::stringstream ss; 44 | ss << "accepted: " << static_cast(accepted_); 45 | 46 | return ss.str(); 47 | } 48 | 49 | size_t ControlPackagePauseRequest::generateSerializedRequest(uint8_t* buffer) 50 | { 51 | return PackageHeader::serializeHeader(buffer, PackageType::RTDE_CONTROL_PACKAGE_PAUSE, PAYLOAD_SIZE); 52 | } 53 | 54 | } // namespace rtde_interface 55 | } // namespace urcl 56 | -------------------------------------------------------------------------------- /src/rtde/control_package_setup_inputs.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/rtde/control_package_setup_inputs.h" 30 | 31 | namespace urcl 32 | { 33 | namespace rtde_interface 34 | { 35 | bool ControlPackageSetupInputs::parseWith(comm::BinParser& bp) 36 | { 37 | bp.parse(input_recipe_id_); 38 | bp.parseRemainder(variable_types_); 39 | 40 | return true; 41 | } 42 | std::string ControlPackageSetupInputs::toString() const 43 | { 44 | std::stringstream ss; 45 | ss << "input recipe id: " << static_cast(input_recipe_id_) << std::endl; 46 | ss << "variable types: " << variable_types_; 47 | 48 | return ss.str(); 49 | } 50 | 51 | size_t ControlPackageSetupInputsRequest::generateSerializedRequest(uint8_t* buffer, 52 | std::vector variable_names) 53 | { 54 | if (variable_names.size() == 0) 55 | { 56 | return 0; 57 | } 58 | std::string variables; 59 | for (const auto& piece : variable_names) 60 | variables += (piece + ","); 61 | variables.pop_back(); 62 | uint16_t payload_size = variables.size(); 63 | 64 | size_t size = 0; 65 | size += PackageHeader::serializeHeader(buffer, PACKAGE_TYPE, payload_size); 66 | size += comm::PackageSerializer::serialize(buffer + size, variables); 67 | 68 | return size; 69 | } 70 | } // namespace rtde_interface 71 | } // namespace urcl 72 | -------------------------------------------------------------------------------- /src/rtde/control_package_start.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/rtde/control_package_start.h" 30 | 31 | namespace urcl 32 | { 33 | namespace rtde_interface 34 | { 35 | bool ControlPackageStart::parseWith(comm::BinParser& bp) 36 | { 37 | bp.parse(accepted_); 38 | 39 | return true; 40 | } 41 | std::string ControlPackageStart::toString() const 42 | { 43 | std::stringstream ss; 44 | ss << "accepted: " << static_cast(accepted_); 45 | 46 | return ss.str(); 47 | } 48 | 49 | size_t ControlPackageStartRequest::generateSerializedRequest(uint8_t* buffer) 50 | { 51 | return PackageHeader::serializeHeader(buffer, PackageType::RTDE_CONTROL_PACKAGE_START, PAYLOAD_SIZE); 52 | } 53 | } // namespace rtde_interface 54 | } // namespace urcl 55 | -------------------------------------------------------------------------------- /src/rtde/get_urcontrol_version.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/rtde/get_urcontrol_version.h" 30 | 31 | namespace urcl 32 | { 33 | namespace rtde_interface 34 | { 35 | bool GetUrcontrolVersion::parseWith(comm::BinParser& bp) 36 | { 37 | bp.parse(version_information_.major); 38 | bp.parse(version_information_.minor); 39 | bp.parse(version_information_.bugfix); 40 | bp.parse(version_information_.build); 41 | 42 | return true; 43 | } 44 | std::string GetUrcontrolVersion::toString() const 45 | { 46 | std::stringstream ss; 47 | ss << "version: " << version_information_.major << "."; 48 | ss << version_information_.minor << "." << version_information_.bugfix << "." << version_information_.build; 49 | 50 | return ss.str(); 51 | } 52 | 53 | size_t GetUrcontrolVersionRequest::generateSerializedRequest(uint8_t* buffer) 54 | { 55 | return PackageHeader::serializeHeader(buffer, PackageType::RTDE_GET_URCONTROL_VERSION, PAYLOAD_SIZE); 56 | } 57 | } // namespace rtde_interface 58 | } // namespace urcl 59 | -------------------------------------------------------------------------------- /src/rtde/request_protocol_version.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/rtde/request_protocol_version.h" 30 | 31 | namespace urcl 32 | { 33 | namespace rtde_interface 34 | { 35 | bool RequestProtocolVersion::parseWith(comm::BinParser& bp) 36 | { 37 | bp.parse(accepted_); 38 | 39 | return true; 40 | } 41 | std::string RequestProtocolVersion::toString() const 42 | { 43 | std::stringstream ss; 44 | ss << "accepted: " << static_cast(accepted_); 45 | return ss.str(); 46 | } 47 | 48 | size_t RequestProtocolVersionRequest::generateSerializedRequest(uint8_t* buffer, uint16_t version) 49 | { 50 | size_t size = 0; 51 | size += PackageHeader::serializeHeader(buffer, PackageType::RTDE_REQUEST_PROTOCOL_VERSION, PAYLOAD_SIZE); 52 | 53 | size += comm::PackageSerializer::serialize(buffer + size, version); 54 | 55 | return size; 56 | } 57 | } // namespace rtde_interface 58 | } // namespace urcl 59 | -------------------------------------------------------------------------------- /src/rtde/rtde_package.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-04-10 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | #include "ur_client_library/rtde/rtde_package.h" 29 | 30 | namespace urcl 31 | { 32 | namespace rtde_interface 33 | { 34 | bool RTDEPackage::parseWith(comm::BinParser& bp) 35 | { 36 | bp.rawData(buffer_, buffer_length_); 37 | return true; 38 | } 39 | 40 | std::string rtde_interface::RTDEPackage::toString() const 41 | { 42 | std::stringstream ss; 43 | ss << "Type: " << static_cast(type_) << std::endl; 44 | ss << "Raw byte stream: "; 45 | for (size_t i = 0; i < buffer_length_; ++i) 46 | { 47 | uint8_t* buf = buffer_.get(); 48 | ss << std::hex << static_cast(buf[i]) << " "; 49 | } 50 | ss << std::endl; 51 | return ss.str(); 52 | } 53 | } // namespace rtde_interface 54 | } // namespace urcl 55 | -------------------------------------------------------------------------------- /src/rtde/text_message.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Tristan Schnell schnell@fzi.de 24 | * \date 2019-04-09 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/rtde/text_message.h" 30 | 31 | namespace urcl 32 | { 33 | namespace rtde_interface 34 | { 35 | bool TextMessage::parseWith(comm::BinParser& bp) 36 | { 37 | if (protocol_version_ == 2) 38 | { 39 | bp.parse(message_length_); 40 | bp.parse(message_, message_length_); 41 | bp.parse(source_length_); 42 | bp.parse(source_, source_length_); 43 | bp.parse(warning_level_); 44 | } 45 | else if (protocol_version_ == 1) 46 | { 47 | bp.parse(message_type_); 48 | bp.parseRemainder(message_); 49 | } 50 | 51 | return true; 52 | } 53 | std::string TextMessage::toString() const 54 | { 55 | std::stringstream ss; 56 | ss << "message: " << message_ << std::endl; 57 | ss << "source: " << source_ << std::endl; 58 | ss << "warning level: " << static_cast(warning_level_); 59 | 60 | return ss.str(); 61 | } 62 | } // namespace rtde_interface 63 | } // namespace urcl 64 | -------------------------------------------------------------------------------- /src/ur/calibration_checker.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-06-14 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include 30 | 31 | namespace urcl 32 | { 33 | CalibrationChecker::CalibrationChecker(const std::string& expected_hash) 34 | : expected_hash_(expected_hash), checked_(false), matches_(false) 35 | { 36 | } 37 | bool CalibrationChecker::consume(std::shared_ptr product) 38 | { 39 | auto kin_info = std::dynamic_pointer_cast(product); 40 | if (kin_info != nullptr) 41 | { 42 | // URCL_LOG_INFO("%s", product->toString().c_str()); 43 | // 44 | matches_ = kin_info->toHash() == expected_hash_; 45 | 46 | checked_ = true; 47 | } 48 | 49 | return true; 50 | } 51 | } // namespace urcl 52 | -------------------------------------------------------------------------------- /src/ur/tool_communication.cpp: -------------------------------------------------------------------------------- 1 | // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 2 | 3 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 4 | // Copyright 2019 FZI Forschungszentrum Informatik 5 | // Created on behalf of Universal Robots A/S 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // -- END LICENSE BLOCK ------------------------------------------------ 19 | 20 | //---------------------------------------------------------------------- 21 | /*!\file 22 | * 23 | * \author Felix Exner exner@fzi.de 24 | * \date 2019-06-06 25 | * 26 | */ 27 | //---------------------------------------------------------------------- 28 | 29 | #include "ur_client_library/ur/tool_communication.h" 30 | 31 | namespace urcl 32 | { 33 | ToolCommSetup::ToolCommSetup() 34 | : tool_voltage_(ToolVoltage::OFF) 35 | , parity_(Parity::ODD) 36 | , baud_rate_(9600) 37 | , stop_bits_(1, 2) 38 | , rx_idle_chars_(1.0, 40.0) 39 | , tx_idle_chars_(0.0, 40.0) 40 | { 41 | } 42 | 43 | void ToolCommSetup::setBaudRate(const uint32_t baud_rate) 44 | { 45 | if (baud_rates_allowed_.find(baud_rate) != baud_rates_allowed_.end()) 46 | { 47 | baud_rate_ = baud_rate; 48 | } 49 | else 50 | { 51 | throw std::runtime_error("Provided baud rate is not allowed"); 52 | } 53 | } 54 | } // namespace urcl 55 | -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/cb3/default.installation: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/dockerursim/programs/cb3/default.installation -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/cb3/default.variables: -------------------------------------------------------------------------------- 1 | # 2 | #Thu Oct 20 15:39:24 CEST 2022 3 | -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/cb3/external_control.urp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/dockerursim/programs/cb3/external_control.urp -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/cb3/programs.UR5: -------------------------------------------------------------------------------- 1 | /ursim/programs.UR5 -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/cb3/wait_program.urp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/dockerursim/programs/cb3/wait_program.urp -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/e-series/default.installation: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/dockerursim/programs/e-series/default.installation -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/e-series/default.variables: -------------------------------------------------------------------------------- 1 | # 2 | #Thu May 28 16:20:13 BST 2020 3 | -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/e-series/external_control.urp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/dockerursim/programs/e-series/external_control.urp -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/e-series/programs.UR5: -------------------------------------------------------------------------------- 1 | /ursim/programs.UR5 -------------------------------------------------------------------------------- /tests/resources/dockerursim/programs/e-series/wait_program.urp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/dockerursim/programs/e-series/wait_program.urp -------------------------------------------------------------------------------- /tests/resources/empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversalRobots/Universal_Robots_Client_Library/289c747850e2bd0c6262a39310b2ae56593baee6/tests/resources/empty.txt -------------------------------------------------------------------------------- /tests/resources/example_urscript_feature.urscript: -------------------------------------------------------------------------------- 1 | textmsg("{{ feature_name }} is a very cool feature!") -------------------------------------------------------------------------------- /tests/resources/example_urscript_main.urscript: -------------------------------------------------------------------------------- 1 | {% if SOFTWARE_VERSION >= v5.23.0 %} 2 | {% include "example_urscript_feature.urscript" %} 3 | {% else %} 4 | popup("The cool new feature is not supported on Software version 5.23.0") 5 | {% endif %} 6 | -------------------------------------------------------------------------------- /tests/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 | -------------------------------------------------------------------------------- /tests/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 | actual_digital_input_bits 10 | actual_digital_output_bits 11 | standard_analog_input0 12 | standard_analog_input1 13 | standard_analog_output0 14 | standard_analog_output1 15 | analog_io_types 16 | tool_mode 17 | tool_analog_input_types 18 | tool_analog_input0 19 | tool_analog_input1 20 | tool_output_voltage 21 | tool_output_current 22 | tool_temperature 23 | robot_mode 24 | safety_mode 25 | robot_status_bits 26 | safety_status_bits 27 | actual_current 28 | tcp_offset 29 | -------------------------------------------------------------------------------- /tests/resources/rtde_output_recipe_spline.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 | actual_digital_input_bits 10 | actual_digital_output_bits 11 | standard_analog_input0 12 | standard_analog_input1 13 | standard_analog_output0 14 | standard_analog_output1 15 | analog_io_types 16 | tool_mode 17 | tool_analog_input_types 18 | tool_analog_input0 19 | tool_analog_input1 20 | tool_output_voltage 21 | tool_output_current 22 | tool_temperature 23 | robot_mode 24 | safety_mode 25 | robot_status_bits 26 | safety_status_bits 27 | actual_current 28 | tcp_offset 29 | output_double_register_1 30 | target_q 31 | target_qd 32 | target_qdd 33 | -------------------------------------------------------------------------------- /tests/resources/rtde_output_recipe_without_timestamp.txt: -------------------------------------------------------------------------------- 1 | actual_q 2 | actual_qd 3 | speed_scaling 4 | target_speed_fraction 5 | runtime_state 6 | actual_TCP_force 7 | actual_TCP_pose 8 | actual_digital_input_bits 9 | actual_digital_output_bits 10 | standard_analog_input0 11 | standard_analog_input1 12 | standard_analog_output0 13 | standard_analog_output1 14 | analog_io_types 15 | tool_mode 16 | tool_analog_input_types 17 | tool_analog_input0 18 | tool_analog_input1 19 | tool_output_voltage 20 | tool_output_current 21 | tool_temperature 22 | robot_mode 23 | safety_mode 24 | robot_status_bits 25 | safety_status_bits 26 | actual_current 27 | tcp_offset 28 | -------------------------------------------------------------------------------- /tests/test_helpers.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2025 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | using namespace urcl; 37 | 38 | TEST(TestHelpers, test_parse_boolean) 39 | { 40 | EXPECT_TRUE(parseBoolean("true")); 41 | EXPECT_TRUE(parseBoolean("True")); 42 | EXPECT_TRUE(parseBoolean("TRUE")); 43 | EXPECT_TRUE(parseBoolean("on")); 44 | EXPECT_TRUE(parseBoolean("On")); 45 | EXPECT_TRUE(parseBoolean("ON")); 46 | EXPECT_TRUE(parseBoolean("yes")); 47 | EXPECT_TRUE(parseBoolean("Yes")); 48 | EXPECT_TRUE(parseBoolean("YES")); 49 | EXPECT_TRUE(parseBoolean("1")); 50 | EXPECT_FALSE(parseBoolean("false")); 51 | EXPECT_FALSE(parseBoolean("False")); 52 | EXPECT_FALSE(parseBoolean("FALSE")); 53 | EXPECT_FALSE(parseBoolean("off")); 54 | EXPECT_FALSE(parseBoolean("Off")); 55 | EXPECT_FALSE(parseBoolean("OFF")); 56 | EXPECT_FALSE(parseBoolean("no")); 57 | EXPECT_FALSE(parseBoolean("No")); 58 | EXPECT_FALSE(parseBoolean("NO")); 59 | EXPECT_FALSE(parseBoolean("0")); 60 | EXPECT_THROW(parseBoolean("notabool"), urcl::UrException); 61 | } 62 | -------------------------------------------------------------------------------- /tests/test_package_serializer.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2022 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #include 32 | #include 33 | 34 | using namespace urcl; 35 | 36 | TEST(package_serializer, serialize_string) 37 | { 38 | uint8_t buffer[4096]; 39 | std::string message = "serialized string"; 40 | size_t expected_size = message.size(); 41 | size_t actual_size = comm::PackageSerializer::serialize(buffer, message); 42 | 43 | EXPECT_EQ(expected_size, actual_size); 44 | 45 | uint8_t expected_buffer[] = { 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 46 | 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67 }; 47 | for (unsigned int i = 0; i < actual_size; ++i) 48 | { 49 | EXPECT_EQ(expected_buffer[i], buffer[i]); 50 | } 51 | } 52 | 53 | TEST(package_serializer, serialize_double) 54 | { 55 | uint8_t buffer[sizeof(double)]; 56 | size_t expected_size = sizeof(double); 57 | size_t actual_size = comm::PackageSerializer::serialize(buffer, 2.341); 58 | 59 | EXPECT_EQ(expected_size, actual_size); 60 | 61 | uint8_t expected_buffer[] = { 0x40, 0x02, 0xba, 0x5e, 0x35, 0x3f, 0x7c, 0xee }; 62 | for (unsigned int i = 0; i < actual_size; ++i) 63 | { 64 | EXPECT_EQ(expected_buffer[i], buffer[i]); 65 | } 66 | } 67 | 68 | TEST(package_serializer, serialize_int32) 69 | { 70 | uint8_t buffer[sizeof(int32_t)]; 71 | size_t expected_size = sizeof(int32_t); 72 | size_t actual_size = comm::PackageSerializer::serialize(buffer, 2341); 73 | 74 | EXPECT_EQ(expected_size, actual_size); 75 | 76 | uint8_t expected_buffer[] = { 0x00, 0x00, 0x09, 0x25 }; 77 | for (unsigned int i = 0; i < actual_size; ++i) 78 | { 79 | EXPECT_EQ(expected_buffer[i], buffer[i]); 80 | } 81 | } 82 | 83 | int main(int argc, char* argv[]) 84 | { 85 | ::testing::InitGoogleTest(&argc, argv); 86 | 87 | return RUN_ALL_TESTS(); 88 | } 89 | -------------------------------------------------------------------------------- /tests/test_rtde_control_package_pause.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2022 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #include 32 | #include 33 | 34 | using namespace urcl; 35 | 36 | TEST(rtde_control_package_pause, generate_serialized_pause_request) 37 | { 38 | uint8_t buffer[4096]; 39 | size_t expected_size = 3; 40 | size_t actual_size = rtde_interface::ControlPackagePauseRequest::generateSerializedRequest(buffer); 41 | 42 | EXPECT_EQ(expected_size, actual_size); 43 | 44 | uint8_t expected[] = { 0x00, 0x03, 0x50 }; 45 | for (unsigned int i = 0; i < actual_size; ++i) 46 | { 47 | EXPECT_EQ(expected[i], buffer[i]); 48 | } 49 | } 50 | 51 | TEST(rtde_control_package_pause, parse_accepted_pause_request) 52 | { 53 | rtde_interface::ControlPackagePause pause_package; 54 | 55 | uint8_t pause_answer[] = { 0x01 }; 56 | comm::BinParser bp(pause_answer, sizeof(pause_answer)); 57 | 58 | EXPECT_TRUE(pause_package.parseWith(bp)); 59 | 60 | uint8_t expected_answer = 1; 61 | uint8_t actual_answer = pause_package.accepted_; 62 | 63 | EXPECT_EQ(expected_answer, actual_answer); 64 | } 65 | 66 | int main(int argc, char* argv[]) 67 | { 68 | ::testing::InitGoogleTest(&argc, argv); 69 | 70 | return RUN_ALL_TESTS(); 71 | } -------------------------------------------------------------------------------- /tests/test_rtde_control_package_start.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2022 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #include 32 | #include 33 | 34 | using namespace urcl; 35 | 36 | TEST(rtde_control_package_start, generate_serialized_start_request) 37 | { 38 | uint8_t buffer[4096]; 39 | size_t expected_size = 3; 40 | size_t actual_size = rtde_interface::ControlPackageStartRequest::generateSerializedRequest(buffer); 41 | 42 | EXPECT_EQ(expected_size, actual_size); 43 | 44 | uint8_t expected[] = { 0x00, 0x03, 0x53 }; 45 | for (unsigned int i = 0; i < actual_size; ++i) 46 | { 47 | EXPECT_EQ(expected[i], buffer[i]); 48 | } 49 | } 50 | 51 | TEST(rtde_control_package_start, parse_accepted_start_request) 52 | { 53 | rtde_interface::ControlPackageStart start_package; 54 | 55 | uint8_t start_answer[] = { 0x01 }; 56 | comm::BinParser bp(start_answer, sizeof(start_answer)); 57 | 58 | EXPECT_TRUE(start_package.parseWith(bp)); 59 | 60 | uint8_t expected_answer = 1; 61 | uint8_t actual_answer = start_package.accepted_; 62 | 63 | EXPECT_EQ(expected_answer, actual_answer); 64 | } 65 | 66 | TEST(rtde_control_package_start, parse_not_accepted_start_request) 67 | { 68 | rtde_interface::ControlPackageStart start_package; 69 | 70 | uint8_t start_answer[] = { 0x00 }; 71 | comm::BinParser bp(start_answer, sizeof(start_answer)); 72 | 73 | EXPECT_TRUE(start_package.parseWith(bp)); 74 | 75 | uint8_t expected_answer = 0; 76 | uint8_t actual_answer = start_package.accepted_; 77 | 78 | EXPECT_EQ(expected_answer, actual_answer); 79 | } 80 | 81 | int main(int argc, char* argv[]) 82 | { 83 | ::testing::InitGoogleTest(&argc, argv); 84 | 85 | return RUN_ALL_TESTS(); 86 | } 87 | -------------------------------------------------------------------------------- /tests/test_rtde_get_urcontrol_version.cpp: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright 2022 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #include 32 | #include 33 | 34 | using namespace urcl; 35 | 36 | TEST(rtde_get_urcontrol_version, generate_serialized_get_urcontrol_version_request) 37 | { 38 | uint8_t buffer[4096]; 39 | size_t expected_size = 3; 40 | size_t actual_size = rtde_interface::GetUrcontrolVersionRequest::generateSerializedRequest(buffer); 41 | 42 | EXPECT_EQ(expected_size, actual_size); 43 | 44 | uint8_t expected[] = { 0x00, 0x03, 0x76 }; 45 | for (unsigned int i = 0; i < actual_size; ++i) 46 | { 47 | EXPECT_EQ(expected[i], buffer[i]); 48 | } 49 | } 50 | 51 | TEST(rtde_get_urcontrol_version, parse_get_urcontrol_version) 52 | { 53 | uint8_t urcontrol_version_answer[] = { 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 54 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }; 55 | comm::BinParser bp(urcontrol_version_answer, sizeof(urcontrol_version_answer)); 56 | rtde_interface::GetUrcontrolVersion ur_control_version; 57 | 58 | EXPECT_TRUE(ur_control_version.parseWith(bp)); 59 | 60 | VersionInformation expected_version_information; 61 | expected_version_information.major = 5; 62 | expected_version_information.minor = 12; 63 | expected_version_information.bugfix = 2; 64 | expected_version_information.build = 0; 65 | 66 | EXPECT_EQ(expected_version_information.major, ur_control_version.version_information_.major); 67 | EXPECT_EQ(expected_version_information.minor, ur_control_version.version_information_.minor); 68 | EXPECT_EQ(expected_version_information.bugfix, ur_control_version.version_information_.bugfix); 69 | EXPECT_EQ(expected_version_information.build, ur_control_version.version_information_.build); 70 | } 71 | 72 | int main(int argc, char* argv[]) 73 | { 74 | ::testing::InitGoogleTest(&argc, argv); 75 | 76 | return RUN_ALL_TESTS(); 77 | } 78 | -------------------------------------------------------------------------------- /tests/test_utils.h: -------------------------------------------------------------------------------- 1 | // -- BEGIN LICENSE BLOCK ---------------------------------------------- 2 | // Copyright © 2025 Universal Robots A/S 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 | // -- END LICENSE BLOCK ------------------------------------------------ 30 | 31 | #pragma once 32 | 33 | #include 34 | 35 | bool robotVersionLessThan(const std::string& robot_ip, const std::string& robot_version) 36 | { 37 | urcl::comm::INotifier notifier; 38 | urcl::primary_interface::PrimaryClient primary_client(robot_ip, notifier); 39 | primary_client.start(); 40 | auto version_information = primary_client.getRobotVersion(); 41 | return *version_information < urcl::VersionInformation::fromString(robot_version); 42 | } 43 | -------------------------------------------------------------------------------- /ur_client_libraryConfig.cmake: -------------------------------------------------------------------------------- 1 | include(CMakeFindDependencyMacro) 2 | 3 | if(NOT TARGET ur_client_library::urcl) 4 | include("${CMAKE_CURRENT_LIST_DIR}/urclTargets.cmake") 5 | endif() 6 | 7 | # This is for catkin compatibility. Better use target_link_libraries( ur_client_library::ur_client_library) 8 | set(ur_client_library_LIBRARIES ur_client_library::urcl) 9 | get_target_property(ur_client_library_INCLUDE_DIRS ur_client_library::urcl INTERFACE_INCLUDE_DIRECTORIES) 10 | 11 | --------------------------------------------------------------------------------