From 979251001af3112c2b27065f15686258856988ec Mon Sep 17 00:00:00 2001 From: Jacob Larsen Date: Fri, 10 Oct 2025 11:43:15 +0000 Subject: [PATCH 1/7] Generate exhaustive rtde output list at build time --- tests/CMakeLists.txt | 14 ++++++++++++ tests/resources/generate_rtde_outputs.py | 29 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/resources/generate_rtde_outputs.py diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 67d2b159d..5ee70345c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,7 +21,19 @@ option(INTEGRATION_TESTS "Build the integration tests that require a running rob if (INTEGRATION_TESTS) # Integration tests require a robot reachable at 192.168.56.101. Therefore, they have to be # activated separately. + + find_package(Python3 COMPONENTS Interpreter REQUIRED) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/resources/exhaustive_rtde_output_recipe.txt + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/resources/generate_rtde_outputs.py + BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/resources/exhaustive_rtde_output_recipe.txt + ) + + add_custom_target(generate_outputs ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/resources/exhaustive_rtde_output_recipe.txt) + add_executable(rtde_tests test_rtde_client.cpp) + add_dependencies(rtde_tests generate_outputs) target_link_libraries(rtde_tests PRIVATE ur_client_library::urcl GTest::gtest_main) gtest_add_tests(TARGET rtde_tests WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} @@ -111,6 +123,8 @@ target_link_libraries(primary_parser_tests PRIVATE ur_client_library::urcl GTest gtest_add_tests(TARGET primary_parser_tests ) + + add_executable(rtde_data_package_tests test_rtde_data_package.cpp) target_link_libraries(rtde_data_package_tests PRIVATE ur_client_library::urcl GTest::gtest_main) gtest_add_tests(TARGET rtde_data_package_tests diff --git a/tests/resources/generate_rtde_outputs.py b/tests/resources/generate_rtde_outputs.py new file mode 100644 index 000000000..739d10ef2 --- /dev/null +++ b/tests/resources/generate_rtde_outputs.py @@ -0,0 +1,29 @@ +import pathlib + +URCL_PATH = pathlib.Path(__file__).parent.parent.parent.resolve() + +PKG_PATH = [i for i in pathlib.Path(URCL_PATH.as_posix()).glob("**/data_package.cpp")] + +assert len(PKG_PATH) == 1 + +PKG_PATH = PKG_PATH[0].resolve() + +OUTPUT_PATH = pathlib.Path(__file__).parent.resolve().as_posix() + "/exhaustive_rtde_output_recipe.txt" + +with open(PKG_PATH) as pkg_file: + save_outputs = False + outputs = [] + while True: + line = pkg_file.readline() + if not line: + break + if "// INPUT / OUTPUT" in line: + save_outputs = True + if save_outputs: + if "//" not in line and len(line) > 1: + outputs.append(line.split('"')[1] + "\n") + if "// NOT IN OFFICIAL DOCS" in line: + break + + with open(OUTPUT_PATH, "w") as output_file: + output_file.writelines(outputs) From 3f8263eec57843e3e4c591702d45ddf50861d867 Mon Sep 17 00:00:00 2001 From: Jacob Larsen Date: Fri, 10 Oct 2025 14:05:32 +0000 Subject: [PATCH 2/7] Edit ci and fail test if not using latest ursim --- .github/workflows/ci.yml | 2 ++ tests/CMakeLists.txt | 9 +-------- tests/test_rtde_client.cpp | 12 +++++++++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc089d329..0add63eea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: run: mkdir -p test_artifacts - name: test run: cd build && ctest --output-on-failure --output-junit junit.xml + env: + URSIM_VERSION: ${{matrix.env.URSIM_VERSION}} - name: Upload test results to Codecov if: ${{ !cancelled() }} uses: codecov/test-results-action@v1 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5ee70345c..4ba47c9a7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,14 +24,7 @@ if (INTEGRATION_TESTS) find_package(Python3 COMPONENTS Interpreter REQUIRED) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/resources/exhaustive_rtde_output_recipe.txt - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/resources/generate_rtde_outputs.py - BYPRODUCTS ${CMAKE_CURRENT_SOURCE_DIR}/resources/exhaustive_rtde_output_recipe.txt - ) - - add_custom_target(generate_outputs ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/resources/exhaustive_rtde_output_recipe.txt) - + add_custom_target(generate_outputs ALL COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/resources/generate_rtde_outputs.py) add_executable(rtde_tests test_rtde_client.cpp) add_dependencies(rtde_tests generate_outputs) target_link_libraries(rtde_tests PRIVATE ur_client_library::urcl GTest::gtest_main) diff --git a/tests/test_rtde_client.cpp b/tests/test_rtde_client.cpp index cd87c2355..5ed769583 100644 --- a/tests/test_rtde_client.cpp +++ b/tests/test_rtde_client.cpp @@ -377,9 +377,19 @@ TEST_F(RTDEClientTest, check_all_rtde_output_variables_exist) { client_->init(); + VersionInformation version = client_->getVersion(); + const char* env_var = std::getenv("URSIM_VERSION"); + std::string env(env_var); + + if (env != "latest") + { + std::cout << "Incorrect URSIM version, it should be the latest version, version is: " << env << std::endl; + GTEST_FAIL(); + } + // Ignore unknown output variables to account for variables not available in old urcontrol versions. client_.reset(new rtde_interface::RTDEClient(g_ROBOT_IP, notifier_, exhaustive_output_recipe_file_, - input_recipe_file_, 0.0, true)); + input_recipe_file_, 0.0, false)); EXPECT_TRUE(client_->init()); client_->start(); From 3bbb7e4ae0c059783cf8525b1c07cad2a2852157 Mon Sep 17 00:00:00 2001 From: Jacob Larsen Date: Fri, 10 Oct 2025 14:11:59 +0000 Subject: [PATCH 3/7] Test should not fail, it should skip --- tests/test_rtde_client.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_rtde_client.cpp b/tests/test_rtde_client.cpp index 5ed769583..2e1a83961 100644 --- a/tests/test_rtde_client.cpp +++ b/tests/test_rtde_client.cpp @@ -383,8 +383,8 @@ TEST_F(RTDEClientTest, check_all_rtde_output_variables_exist) if (env != "latest") { - std::cout << "Incorrect URSIM version, it should be the latest version, version is: " << env << std::endl; - GTEST_FAIL(); + std::cout << "Not using the latest URSIM version, skipping test." << std::endl; + GTEST_SKIP(); } // Ignore unknown output variables to account for variables not available in old urcontrol versions. From 4c5dde4779a024eff2de51334422c5dd21c92b56 Mon Sep 17 00:00:00 2001 From: Jacob Larsen Date: Mon, 13 Oct 2025 13:19:32 +0000 Subject: [PATCH 4/7] Generate list of outputs from website --- tests/resources/generate_rtde_outputs.py | 52 +++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/tests/resources/generate_rtde_outputs.py b/tests/resources/generate_rtde_outputs.py index 739d10ef2..cf4f527b9 100644 --- a/tests/resources/generate_rtde_outputs.py +++ b/tests/resources/generate_rtde_outputs.py @@ -1,5 +1,36 @@ -import pathlib +# -- BEGIN LICENSE BLOCK ---------------------------------------------- +# Copyright 2025 Universal Robots A/S +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of the {copyright_holder} nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# -- END LICENSE BLOCK ------------------------------------------------ +import pathlib +import pandas as pd +import re URCL_PATH = pathlib.Path(__file__).parent.parent.parent.resolve() PKG_PATH = [i for i in pathlib.Path(URCL_PATH.as_posix()).glob("**/data_package.cpp")] @@ -9,6 +40,7 @@ PKG_PATH = PKG_PATH[0].resolve() OUTPUT_PATH = pathlib.Path(__file__).parent.resolve().as_posix() + "/exhaustive_rtde_output_recipe.txt" +WEB_OUTPUT_PATH = pathlib.Path(__file__).parent.resolve().as_posix() + "/docs_rtde_output_recipe.txt" with open(PKG_PATH) as pkg_file: save_outputs = False @@ -27,3 +59,21 @@ with open(OUTPUT_PATH, "w") as output_file: output_file.writelines(outputs) + +# Get outputs from official docs +page = pd.read_html("https://docs.universal-robots.com/tutorials/communication-protocol-tutorials/rtde-guide.html") +table = page[1] +outputs = [] +for _, row in table.iterrows(): + name = row["Name"] + if "X" in name: + numbers = re.findall(r'\d+', row["Comment"]) + amount = int(numbers[0]) + base_addr = int(numbers[1]) + for i in range(amount): + outputs.append(name[:-1]+str(base_addr+i) + "\n") + else: + outputs.append(name + "\n") + +with open(WEB_OUTPUT_PATH, "w") as web_output_file: + web_output_file.writelines(outputs) From 9db3034d2872712a14cd744f88fc92662dea8824 Mon Sep 17 00:00:00 2001 From: Jacob Larsen Date: Mon, 13 Oct 2025 13:19:51 +0000 Subject: [PATCH 5/7] Install necessary pip packages in CI --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0add63eea..6e059e777 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,6 +40,8 @@ jobs: ROBOT_MODEL: ${{matrix.env.ROBOT_MODEL}} URSIM_VERSION: ${{matrix.env.URSIM_VERSION}} PROGRAM_FOLDER: ${{matrix.env.PROGRAM_FOLDER}} + - name: install-pips + run: pip install pandas lxml - name: configure run: mkdir build && cd build && cmake .. -DBUILDING_TESTS=1 -DINTEGRATION_TESTS=1 -DWITH_ASAN=ON env: From 905d5fe26d1b7aae6a98464321b48ef5953b9376 Mon Sep 17 00:00:00 2001 From: Jacob Larsen Date: Mon, 13 Oct 2025 14:29:09 +0000 Subject: [PATCH 6/7] Make test to compare outputs to docs Compares the online documentation fields to the list generated from the dict in the repo. Does not actually interact with RTDE, so should be robot-version agnostic. --- tests/test_rtde_client.cpp | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_rtde_client.cpp b/tests/test_rtde_client.cpp index 2e1a83961..66f7d36cc 100644 --- a/tests/test_rtde_client.cpp +++ b/tests/test_rtde_client.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "ur_client_library/exceptions.h" #include @@ -59,6 +60,7 @@ class RTDEClientTest : public ::testing::Test std::string output_recipe_file_ = "resources/rtde_output_recipe.txt"; std::string exhaustive_output_recipe_file_ = "resources/exhaustive_rtde_output_recipe.txt"; + std::string docs_output_recipe_file_ = "resources/docs_rtde_output_recipe.txt"; std::string input_recipe_file_ = "resources/rtde_input_recipe.txt"; comm::INotifier notifier_; std::unique_ptr client_; @@ -410,6 +412,51 @@ TEST_F(RTDEClientTest, check_all_rtde_output_variables_exist) client_->pause(); } +TEST_F(RTDEClientTest, check_rtde_data_fields_match_docs) +{ + std::ifstream docs_file(docs_output_recipe_file_); + std::ifstream pkg_file(exhaustive_output_recipe_file_); + std::vector docs_outputs; + std::string line; + while (std::getline(docs_file, line)) + { + docs_outputs.push_back(line); + } + std::vector pkg_outputs; + while (std::getline(pkg_file, line)) + { + pkg_outputs.push_back(line); + } + std::sort(docs_outputs.begin(), docs_outputs.end()); + std::sort(pkg_outputs.begin(), pkg_outputs.end()); + if (!std::is_permutation(docs_outputs.begin(), docs_outputs.end(), pkg_outputs.begin(), pkg_outputs.end())) + { + std::cout << "Data package output fields do not match output fields in documentation" << std::endl; + std::unordered_map diff; + std::cout << "Differences: " << std::endl; + for (auto name : docs_outputs) + { + diff[name] += 1; + } + for (auto name : pkg_outputs) + { + diff[name] -= 1; + } + for (auto elem : diff) + { + if (elem.second > 0) + { + std::cout << elem.first << " exists in documentation, but not in data package dict." << std::endl; + } + if (elem.second < 0) + { + std::cout << elem.first << " exists in data package dict, but not in documentation." << std::endl; + } + } + GTEST_FAIL(); + } +} + TEST_F(RTDEClientTest, check_unknown_rtde_output_variable) { client_->init(); From f9764377f2cdd561b7243d8d41870374a73cfc96 Mon Sep 17 00:00:00 2001 From: Felix Exner Date: Tue, 14 Oct 2025 17:16:48 +0200 Subject: [PATCH 7/7] Check whether URSIM_VERSION env var is actually set --- .gitignore | 3 +- .../exhaustive_rtde_output_recipe.txt | 380 +++++++++--------- tests/test_rtde_client.cpp | 17 +- 3 files changed, 203 insertions(+), 197 deletions(-) diff --git a/.gitignore b/.gitignore index 32f3e4f11..696674064 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ install_manifest.txt .idea .directory .vscode -build/ \ No newline at end of file +build/ +tests/resources/docs_rtde_output_recipe.txt diff --git a/tests/resources/exhaustive_rtde_output_recipe.txt b/tests/resources/exhaustive_rtde_output_recipe.txt index e0df0aa2a..ea3d5c7ef 100644 --- a/tests/resources/exhaustive_rtde_output_recipe.txt +++ b/tests/resources/exhaustive_rtde_output_recipe.txt @@ -1,3 +1,165 @@ +input_bit_registers0_to_31 +input_bit_registers32_to_63 +input_bit_register_64 +input_bit_register_65 +input_bit_register_66 +input_bit_register_67 +input_bit_register_68 +input_bit_register_69 +input_bit_register_70 +input_bit_register_71 +input_bit_register_72 +input_bit_register_73 +input_bit_register_74 +input_bit_register_75 +input_bit_register_76 +input_bit_register_77 +input_bit_register_78 +input_bit_register_79 +input_bit_register_80 +input_bit_register_81 +input_bit_register_82 +input_bit_register_83 +input_bit_register_84 +input_bit_register_85 +input_bit_register_86 +input_bit_register_87 +input_bit_register_88 +input_bit_register_89 +input_bit_register_90 +input_bit_register_91 +input_bit_register_92 +input_bit_register_93 +input_bit_register_94 +input_bit_register_95 +input_bit_register_96 +input_bit_register_97 +input_bit_register_98 +input_bit_register_99 +input_bit_register_100 +input_bit_register_101 +input_bit_register_102 +input_bit_register_103 +input_bit_register_104 +input_bit_register_105 +input_bit_register_106 +input_bit_register_107 +input_bit_register_108 +input_bit_register_109 +input_bit_register_110 +input_bit_register_111 +input_bit_register_112 +input_bit_register_113 +input_bit_register_114 +input_bit_register_115 +input_bit_register_116 +input_bit_register_117 +input_bit_register_118 +input_bit_register_119 +input_bit_register_120 +input_bit_register_121 +input_bit_register_122 +input_bit_register_123 +input_bit_register_124 +input_bit_register_125 +input_bit_register_126 +input_bit_register_127 +input_int_register_0 +input_int_register_1 +input_int_register_2 +input_int_register_3 +input_int_register_4 +input_int_register_5 +input_int_register_6 +input_int_register_7 +input_int_register_8 +input_int_register_9 +input_int_register_10 +input_int_register_11 +input_int_register_12 +input_int_register_13 +input_int_register_14 +input_int_register_15 +input_int_register_16 +input_int_register_17 +input_int_register_18 +input_int_register_19 +input_int_register_20 +input_int_register_21 +input_int_register_22 +input_int_register_23 +input_int_register_24 +input_int_register_25 +input_int_register_26 +input_int_register_27 +input_int_register_28 +input_int_register_29 +input_int_register_30 +input_int_register_31 +input_int_register_32 +input_int_register_33 +input_int_register_34 +input_int_register_35 +input_int_register_36 +input_int_register_37 +input_int_register_38 +input_int_register_39 +input_int_register_40 +input_int_register_41 +input_int_register_42 +input_int_register_43 +input_int_register_44 +input_int_register_45 +input_int_register_46 +input_int_register_47 +input_double_register_0 +input_double_register_1 +input_double_register_2 +input_double_register_3 +input_double_register_4 +input_double_register_5 +input_double_register_6 +input_double_register_7 +input_double_register_8 +input_double_register_9 +input_double_register_10 +input_double_register_11 +input_double_register_12 +input_double_register_13 +input_double_register_14 +input_double_register_15 +input_double_register_16 +input_double_register_17 +input_double_register_18 +input_double_register_19 +input_double_register_20 +input_double_register_21 +input_double_register_22 +input_double_register_23 +input_double_register_24 +input_double_register_25 +input_double_register_26 +input_double_register_27 +input_double_register_28 +input_double_register_29 +input_double_register_30 +input_double_register_31 +input_double_register_32 +input_double_register_33 +input_double_register_34 +input_double_register_35 +input_double_register_36 +input_double_register_37 +input_double_register_38 +input_double_register_39 +input_double_register_40 +input_double_register_41 +input_double_register_42 +input_double_register_43 +input_double_register_44 +input_double_register_45 +input_double_register_46 +input_double_register_47 timestamp target_q target_qd @@ -48,34 +210,6 @@ standard_analog_input1 standard_analog_output0 standard_analog_output1 io_current -actual_robot_energy_consumed -actual_robot_braking_energy_dissipated -encoder0_raw -encoder1_raw -euromap67_input_bits -euromap67_output_bits -euromap67_24V_voltage -euromap67_24V_current -tool_mode -tool_analog_input_types -tool_analog_input0 -tool_analog_input1 -tool_output_voltage -tool_output_current -tool_temperature -tool_output_mode -tool_digital_output0_mode -tool_digital_output1_mode -tcp_force_scalar -joint_position_deviation_ratio -collision_detection_ratio -ft_raw_wrench -wrench_calc_from_currents -payload -payload_cog -payload_inertia -script_control_line -time_scale_source output_bit_registers0_to_31 output_bit_registers32_to_63 output_bit_register_64 @@ -238,165 +372,31 @@ output_double_register_44 output_double_register_45 output_double_register_46 output_double_register_47 -input_bit_registers0_to_31 -input_bit_registers32_to_63 -input_bit_register_64 -input_bit_register_65 -input_bit_register_66 -input_bit_register_67 -input_bit_register_68 -input_bit_register_69 -input_bit_register_70 -input_bit_register_71 -input_bit_register_72 -input_bit_register_73 -input_bit_register_74 -input_bit_register_75 -input_bit_register_76 -input_bit_register_77 -input_bit_register_78 -input_bit_register_79 -input_bit_register_80 -input_bit_register_81 -input_bit_register_82 -input_bit_register_83 -input_bit_register_84 -input_bit_register_85 -input_bit_register_86 -input_bit_register_87 -input_bit_register_88 -input_bit_register_89 -input_bit_register_90 -input_bit_register_91 -input_bit_register_92 -input_bit_register_93 -input_bit_register_94 -input_bit_register_95 -input_bit_register_96 -input_bit_register_97 -input_bit_register_98 -input_bit_register_99 -input_bit_register_100 -input_bit_register_101 -input_bit_register_102 -input_bit_register_103 -input_bit_register_104 -input_bit_register_105 -input_bit_register_106 -input_bit_register_107 -input_bit_register_108 -input_bit_register_109 -input_bit_register_110 -input_bit_register_111 -input_bit_register_112 -input_bit_register_113 -input_bit_register_114 -input_bit_register_115 -input_bit_register_116 -input_bit_register_117 -input_bit_register_118 -input_bit_register_119 -input_bit_register_120 -input_bit_register_121 -input_bit_register_122 -input_bit_register_123 -input_bit_register_124 -input_bit_register_125 -input_bit_register_126 -input_bit_register_127 -input_int_register_0 -input_int_register_1 -input_int_register_2 -input_int_register_3 -input_int_register_4 -input_int_register_5 -input_int_register_6 -input_int_register_7 -input_int_register_8 -input_int_register_9 -input_int_register_10 -input_int_register_11 -input_int_register_12 -input_int_register_13 -input_int_register_14 -input_int_register_15 -input_int_register_16 -input_int_register_17 -input_int_register_18 -input_int_register_19 -input_int_register_20 -input_int_register_21 -input_int_register_22 -input_int_register_23 -input_int_register_24 -input_int_register_25 -input_int_register_26 -input_int_register_27 -input_int_register_28 -input_int_register_29 -input_int_register_30 -input_int_register_31 -input_int_register_32 -input_int_register_33 -input_int_register_34 -input_int_register_35 -input_int_register_36 -input_int_register_37 -input_int_register_38 -input_int_register_39 -input_int_register_40 -input_int_register_41 -input_int_register_42 -input_int_register_43 -input_int_register_44 -input_int_register_45 -input_int_register_46 -input_int_register_47 -input_double_register_0 -input_double_register_1 -input_double_register_2 -input_double_register_3 -input_double_register_4 -input_double_register_5 -input_double_register_6 -input_double_register_7 -input_double_register_8 -input_double_register_9 -input_double_register_10 -input_double_register_11 -input_double_register_12 -input_double_register_13 -input_double_register_14 -input_double_register_15 -input_double_register_16 -input_double_register_17 -input_double_register_18 -input_double_register_19 -input_double_register_20 -input_double_register_21 -input_double_register_22 -input_double_register_23 -input_double_register_24 -input_double_register_25 -input_double_register_26 -input_double_register_27 -input_double_register_28 -input_double_register_29 -input_double_register_30 -input_double_register_31 -input_double_register_32 -input_double_register_33 -input_double_register_34 -input_double_register_35 -input_double_register_36 -input_double_register_37 -input_double_register_38 -input_double_register_39 -input_double_register_40 -input_double_register_41 -input_double_register_42 -input_double_register_43 -input_double_register_44 -input_double_register_45 -input_double_register_46 -input_double_register_47 +actual_robot_energy_consumed +actual_robot_braking_energy_dissipated +encoder0_raw +encoder1_raw +euromap67_input_bits +euromap67_output_bits +euromap67_24V_voltage +euromap67_24V_current +tool_mode +tool_analog_input_types +tool_analog_input0 +tool_analog_input1 +tool_output_voltage +tool_output_current +tool_temperature +tool_output_mode +tool_digital_output0_mode +tool_digital_output1_mode +tcp_force_scalar +joint_position_deviation_ratio +collision_detection_ratio +ft_raw_wrench +wrench_calc_from_currents +payload +payload_cog +payload_inertia +script_control_line +time_scale_source diff --git a/tests/test_rtde_client.cpp b/tests/test_rtde_client.cpp index 66f7d36cc..0280682b4 100644 --- a/tests/test_rtde_client.cpp +++ b/tests/test_rtde_client.cpp @@ -377,18 +377,23 @@ TEST_F(RTDEClientTest, connect_non_running_robot) TEST_F(RTDEClientTest, check_all_rtde_output_variables_exist) { - client_->init(); - - VersionInformation version = client_->getVersion(); const char* env_var = std::getenv("URSIM_VERSION"); - std::string env(env_var); + if (env_var == nullptr) + { + std::cout << "No URSIM_VERSION environment variable set, skipping test." << std::endl; + GTEST_SKIP(); + } + const std::string env_ursim_version(env_var); - if (env != "latest") + if (env_ursim_version != "latest") { - std::cout << "Not using the latest URSIM version, skipping test." << std::endl; + std::cout << "Not using the latest URSIM version, skipping test. URSIM_VERSION is set to '" << env_ursim_version + << "'" << std::endl; GTEST_SKIP(); } + client_->init(); + // Ignore unknown output variables to account for variables not available in old urcontrol versions. client_.reset(new rtde_interface::RTDEClient(g_ROBOT_IP, notifier_, exhaustive_output_recipe_file_, input_recipe_file_, 0.0, false));