diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 08ab61463..7fd90483f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,10 +9,48 @@ on: - cron: '38 2 * * *' jobs: - build: + ubuntu_build: + name: ubuntu_build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Install build-tools + run: sudo apt-get update && sudo apt-get install -y build-essential cmake python3-pandas python3-lxml + - name: configure + run: > + mkdir build && + cd build && + cmake .. + -DBUILDING_TESTS=1 + -DINTEGRATION_TESTS=1 + -DWITH_ASAN=ON + -DPRIMARY_CLIENT_STRICT_PARSING_=ON + -DCMAKE_COMPILE_WARNING_AS_ERROR=ON + -DCHECK_RTDE_DOCS_RECIPE=ON + env: + CXXFLAGS: -g -O2 -fprofile-arcs -ftest-coverage + CFLAGS: -g -O2 -fprofile-arcs -ftest-coverage + LDFLAGS: -fprofile-arcs -ftest-coverage + - name: build + id: build + run: cmake --build build --config Debug + - name: Archive CMake build directory + if: steps.build.outcome == 'success' + run: tar -czf build.tar.gz build + - name: Upload CMake build archive + if: steps.build.outcome == 'success' + uses: actions/upload-artifact@v7 + with: + path: build.tar.gz + if-no-files-found: error + retention-days: 5 + archive: false + + run_tests: timeout-minutes: 60 runs-on: ubuntu-latest - name: build (${{matrix.env.URSIM_VERSION}}-${{matrix.env.ROBOT_MODEL}}) + name: run_tests (${{matrix.env.URSIM_VERSION}}-${{matrix.env.ROBOT_MODEL}}) + needs: ubuntu_build strategy: fail-fast: false matrix: @@ -46,8 +84,6 @@ 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 - id: check_polyscopex run: | if [[ "${{matrix.env.URSIM_VERSION}}" == "10."* ]]; then @@ -57,29 +93,21 @@ jobs: fi - name: setup chrome uses: browser-actions/setup-chrome@v2 - - name: configure - run: > - mkdir build && - cd build && - cmake .. - -DBUILDING_TESTS=1 - -DINTEGRATION_TESTS=1 - -DWITH_ASAN=ON - -DPRIMARY_CLIENT_STRICT_PARSING=ON - -DCMAKE_COMPILE_WARNING_AS_ERROR=ON - -DCHECK_RTDE_DOCS_RECIPE=ON - env: - CXXFLAGS: -g -O2 -fprofile-arcs -ftest-coverage - CFLAGS: -g -O2 -fprofile-arcs -ftest-coverage - LDFLAGS: -fprofile-arcs -ftest-coverage - - name: build - id: build - run: cmake --build build --config Debug + - name: Download CMake build archive + uses: actions/download-artifact@v8 + with: + name: build.tar.gz + - name: Extract CMake build directory + run: tar -xzf build.tar.gz - name: Create folder for test artifacts run: mkdir -p test_artifacts - name: Access PolyScope if: ${{ steps.check_polyscopex.outputs.is_polyscopex == 'true' }} run: chrome --no-sandbox --disable-settuid-sandbox --headless=new 192.168.56.101 & + - name: Install Python dependencies + run: sudo apt-get update && sudo apt-get install -y python3-pandas python3-lxml + - name: Generate rtde outputs lists + run: python3 tests/resources/generate_rtde_outputs.py - name: test run: cd build && ctest --output-on-failure --output-junit junit.xml env: @@ -96,13 +124,10 @@ jobs: - name: run examples run: ./run_examples.sh "192.168.56.101" 1 - name: install gcovr - if: ${{ !cancelled() && steps.build.outcome == 'success' }} run: sudo apt-get install -y gcovr - name: gcovr - if: ${{ !cancelled() && steps.build.outcome == 'success' }} run: cd build && gcovr -r .. --xml coverage.xml --gcov-ignore-parse-errors negative_hits.warn_once_per_file --exclude "../3rdparty" - name: Upload coverage reports to Codecov with GitHub Action - if: ${{ !cancelled() && steps.build.outcome == 'success' }} uses: codecov/codecov-action@v6 with: fail_ci_if_error: true @@ -150,6 +175,155 @@ jobs: if-no-files-found: warn retention-days: 10 + robot_model_check: + timeout-minutes: 60 + runs-on: ubuntu-latest + needs: ubuntu_build + name: check_model (${{matrix.env.URSIM_VERSION}}-${{matrix.env.ROBOT_MODEL}}) + strategy: + fail-fast: false + matrix: + env: + - ROBOT_MODEL: 'ur3' + URSIM_VERSION: '3.14.3' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/cb3' + - ROBOT_MODEL: 'ur5' + URSIM_VERSION: '3.15.8' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/cb3' + - ROBOT_MODEL: 'ur10' + URSIM_VERSION: '3.15.8' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/cb3' + - ROBOT_MODEL: 'ur3e' + URSIM_VERSION: '5.9.4' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur5e' + URSIM_VERSION: '5.12.8' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur7e' + URSIM_VERSION: '5.22.2' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur10e' + URSIM_VERSION: '5.15.2' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur12e' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur16e' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur8long' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur15' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur18' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur20' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur30' + URSIM_VERSION: '5.25.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/e-series' + - ROBOT_MODEL: 'ur3e' + URSIM_VERSION: '10.11.0' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur5e' + URSIM_VERSION: '10.11.0' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur7e' + URSIM_VERSION: '10.11.0' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur10e' + URSIM_VERSION: '10.11.0' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur12e' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur16e' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur8long' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur15' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur18' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur20' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + - ROBOT_MODEL: 'ur30' + URSIM_VERSION: '10.12.1' + PROGRAM_FOLDER: 'tests/resources/dockerursim/programs/polyscopex' + + steps: + - uses: actions/checkout@v6 + - name: start ursim + run: | + scripts/start_ursim.sh -m $ROBOT_MODEL -v $URSIM_VERSION -p $PROGRAM_FOLDER -d -f DISABLED + env: + DOCKER_RUN_OPTS: --network ursim_net + ROBOT_MODEL: ${{matrix.env.ROBOT_MODEL}} + URSIM_VERSION: ${{matrix.env.URSIM_VERSION}} + PROGRAM_FOLDER: ${{matrix.env.PROGRAM_FOLDER}} + - name: Download CMake build archive + uses: actions/download-artifact@v8 + with: + name: build.tar.gz + env: + DOCKER_RUN_OPTS: --network ursim_net + ROBOT_MODEL: ${{matrix.env.ROBOT_MODEL}} + URSIM_VERSION: ${{matrix.env.URSIM_VERSION}} + PROGRAM_FOLDER: ${{matrix.env.PROGRAM_FOLDER}} + - name: Extract CMake build directory + run: tar -xzf build.tar.gz + - name: inspect build folder + run: ls -la build && ls -la build/tests + - name: test robot type + run: cd build && ctest -R PrimaryClientTest.test_robot_type --verbose --output-junit junit.xml + env: + URSIM_VERSION: ${{matrix.env.URSIM_VERSION}} + ROBOT_MODEL: ${{matrix.env.ROBOT_MODEL}} + - name: install gcovr + run: sudo apt-get install -y gcovr + - name: gcovr + run: cd build && gcovr -r .. --xml coverage.xml --gcov-ignore-parse-errors negative_hits.warn_once_per_file --exclude "../3rdparty" + - name: Upload coverage reports to Codecov with GitHub Action + uses: codecov/codecov-action@v6 + with: + fail_ci_if_error: true + files: build/coverage.xml + flags: check_version_${{ matrix.env.ROBOT_MODEL }}-${{ matrix.env.URSIM_VERSION }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Generate URSim log files + if: ${{ always() && steps.check_polyscopex.outputs.is_polyscopex == 'false' }} + run: | + nc -q 1 192.168.56.101 29999 <& values) */ RobotSeries robotSeriesFromTypeAndVersion(const RobotType type, const VersionInformation& version); +RobotType robotTypeFromString(const std::string& robot_type_str); + } // namespace urcl #endif // ifndef UR_CLIENT_LIBRARY_HELPERS_H_INCLUDED diff --git a/scripts/start_ursim.sh b/scripts/start_ursim.sh index 776b6044a..022d45fdb 100755 --- a/scripts/start_ursim.sh +++ b/scripts/start_ursim.sh @@ -129,7 +129,13 @@ strip_robot_model() if [[ "$robot_model" = @(ur3e|ur5e|ur10e|ur16e) ]]; then ROBOT_MODEL=$(echo "${ROBOT_MODEL:0:$((${#ROBOT_MODEL}-1))}") elif [[ "$robot_model" = @(ur7e|ur12e) ]]; then - ROBOT_MODEL=$(echo "${ROBOT_MODEL:0:$((${#ROBOT_MODEL}-1))}e") + # PolyScope X uses UR7e and UR12e, but PolyScope 5 uses UR7 and UR12. So we + # need to strip the "e" for PolyScope 5 + if [[ "$robot_series" == "polyscopex" ]]; then + ROBOT_MODEL=$(echo "${ROBOT_MODEL:0:$((${#ROBOT_MODEL}-1))}e") + else + ROBOT_MODEL=$(echo "${ROBOT_MODEL:0:$((${#ROBOT_MODEL}-1))}") + fi fi fi } diff --git a/src/helpers.cpp b/src/helpers.cpp index f39bf0b76..3ca05c28c 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -203,4 +203,69 @@ RobotSeries robotSeriesFromTypeAndVersion(const RobotType type, const VersionInf return RobotSeries::UNDEFINED; } +RobotType robotTypeFromString(const std::string& robot_type_str) +{ + if (robot_type_str == "ur3") + { + return RobotType::UR3; + } + else if (robot_type_str == "ur3e") + { + return RobotType::UR3; + } + else if (robot_type_str == "ur5") + { + return RobotType::UR5; + } + else if (robot_type_str == "ur5e") + { + return RobotType::UR5; + } + else if (robot_type_str == "ur7e") + { // UR7e reports as UR5 + return RobotType::UR5; + } + else if (robot_type_str == "ur10") + { + return RobotType::UR10; + } + else if (robot_type_str == "ur10e") + { + return RobotType::UR10; + } + else if (robot_type_str == "ur12e") + { // UR12e reports as UR10 + return RobotType::UR10; + } + else if (robot_type_str == "ur16e") + { + return RobotType::UR16; + } + else if (robot_type_str == "ur15") + { + return RobotType::UR15; + } + else if (robot_type_str == "ur18") + { + return RobotType::UR18; + } + else if (robot_type_str == "ur20") + { + return RobotType::UR20; + } + else if (robot_type_str == "ur30") + { + return RobotType::UR30; + } + else if (robot_type_str == "ur8long") + { + return RobotType::UR8LONG; + } + else + { + return RobotType::UR5; + throw std::invalid_argument("Unknown robot type: " + robot_type_str); + } +} + } // namespace urcl diff --git a/tests/test_primary_client.cpp b/tests/test_primary_client.cpp index 1b99eafa0..3da94db3f 100644 --- a/tests/test_primary_client.cpp +++ b/tests/test_primary_client.cpp @@ -267,6 +267,27 @@ TEST_F(PrimaryClientTest, test_configuration_data) EXPECT_NE(client_->getRobotType(), RobotType::UNDEFINED); } +TEST_F(PrimaryClientTest, test_robot_type) +{ + if (std::getenv("ROBOT_MODEL") == nullptr) + { + GTEST_SKIP() << "ROBOT_MODEL environment variable not set. Skipping test."; + } + EXPECT_NO_THROW(client_->start()); + + // Wait until we have received configuration data so that the robot type is known. + auto start_time = std::chrono::system_clock::now(); + const auto timeout = std::chrono::seconds(10); + while (client_->getConfigurationData() == nullptr && std::chrono::system_clock::now() - start_time < timeout) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + ASSERT_NE(client_->getConfigurationData(), nullptr); + const std::string robot_model_env = std::getenv("ROBOT_MODEL"); + const RobotType expected_series_from_env = robotTypeFromString(robot_model_env); + EXPECT_EQ(client_->getRobotType(), expected_series_from_env); +} + TEST_F(PrimaryClientTest, test_kinematics_info) { EXPECT_NO_THROW(client_->start()); diff --git a/tests/test_start_ursim.bats b/tests/test_start_ursim.bats index 7feead249..ff4f32007 100644 --- a/tests/test_start_ursim.bats +++ b/tests/test_start_ursim.bats @@ -415,10 +415,18 @@ setup() { strip_robot_model ur7e e-series echo "Robot model is: $ROBOT_MODEL" + [ "$ROBOT_MODEL" = "UR7" ] + + strip_robot_model ur7e polyscopex + echo "Robot model is: $ROBOT_MODEL" [ "$ROBOT_MODEL" = "UR7e" ] strip_robot_model ur12e e-series echo "Robot model is: $ROBOT_MODEL" + [ "$ROBOT_MODEL" = "UR12" ] + + strip_robot_model ur12e polyscopex + echo "Robot model is: $ROBOT_MODEL" [ "$ROBOT_MODEL" = "UR12e" ] }