From bdb0c1724d38632a28243b44646c6e83b15462b3 Mon Sep 17 00:00:00 2001 From: Tomas Baca Date: Wed, 6 Dec 2023 10:03:17 +0100 Subject: [PATCH 1/6] added todos --- src/control_manager/control_manager.cpp | 37 +++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/control_manager/control_manager.cpp b/src/control_manager/control_manager.cpp index b141c1d2..6e3319a3 100644 --- a/src/control_manager/control_manager.cpp +++ b/src/control_manager/control_manager.cpp @@ -2869,16 +2869,10 @@ void ControlManager::timerEland(const ros::TimerEvent& event) { return; } - double throttle = 0; - - if (std::holds_alternative(last_control_output.control_output.value())) { - throttle = std::get(last_control_output.control_output.value()).throttle; - } else if (std::holds_alternative(last_control_output.control_output.value())) { - throttle = std::get(last_control_output.control_output.value()).throttle; - } else if (std::holds_alternative(last_control_output.control_output.value())) { - throttle = std::get(last_control_output.control_output.value()).throttle; - } else { - ROS_ERROR_THROTTLE(1.0, "[ControlManager]: TODO: implement eland timer for this control mode"); + auto throttle = extractThrottle(last_control_output); + + if (!throttle) { + ROS_ERROR_THROTTLE(1.0, "[ControlManager]: TODO: implement landing detection mechanism for the current control modality"); return; } @@ -2888,6 +2882,14 @@ void ControlManager::timerEland(const ros::TimerEvent& event) { } else if (current_state_landing_ == LANDING_STATE) { + // -------------------------------------------------------------- + // | TODO | + // This section needs work. The throttle landing detection | + // mechanism should be extracted and other mechanisms, such | + // as velocity-based detection should be used for high | + // modalities | + // -------------------------------------------------------------- + if (!last_control_output.control_output) { ROS_WARN_THROTTLE(1.0, "[ControlManager]: timerEland: last_control_output has not been initialized, returning"); ROS_WARN_THROTTLE(1.0, "[ControlManager]: tip: the RC eland is probably triggered"); @@ -2895,7 +2897,7 @@ void ControlManager::timerEland(const ros::TimerEvent& event) { } // recalculate the mass based on the throttle - throttle_mass_estimate_ = mrs_lib::quadratic_throttle_model::throttleToForce(common_handlers_->throttle_model, throttle) / common_handlers_->g; + throttle_mass_estimate_ = mrs_lib::quadratic_throttle_model::throttleToForce(common_handlers_->throttle_model, throttle.value()) / common_handlers_->g; ROS_INFO_THROTTLE(1.0, "[ControlManager]: landing: initial mass: %.2f throttle_mass_estimate: %.2f", landing_uav_mass_, throttle_mass_estimate_); // condition for automatic motor turn off @@ -2977,6 +2979,14 @@ void ControlManager::timerFailsafe(const ros::TimerEvent& event) { return; } + // -------------------------------------------------------------- + // | TODO | + // This section needs work. The throttle landing detection | + // mechanism should be extracted and other mechanisms, such | + // as velocity-based detection should be used for high | + // modalities | + // -------------------------------------------------------------- + double throttle_mass_estimate_ = mrs_lib::quadratic_throttle_model::throttleToForce(common_handlers_->throttle_model, throttle.value()) / common_handlers_->g; ROS_INFO_THROTTLE(1.0, "[ControlManager]: failsafe: initial mass: %.2f throttle_mass_estimate: %.2f", landing_uav_mass_, throttle_mass_estimate_); @@ -7259,6 +7269,7 @@ std::tuple ControlManager::eland(void) { /* failsafe() //{ */ std::tuple ControlManager::failsafe(void) { + // copy member variables auto last_control_output = mrs_lib::get_mutexed(mutex_last_control_output_, last_control_output_); auto last_tracker_cmd = mrs_lib::get_mutexed(mutex_last_tracker_cmd_, last_tracker_cmd_); @@ -7288,6 +7299,10 @@ std::tuple ControlManager::failsafe(void) { return std::tuple(true, "RC emergency handoff is ON, disabling output"); } + if (getLowestOuput(_hw_api_inputs_) == POSITION) { + return eland(); + } + if (_parachute_enabled_) { auto [success, message] = deployParachute(); From e475cf2afe6c34e27fdcaa8179db38e47a31a79e Mon Sep 17 00:00:00 2001 From: Tomas Baca Date: Thu, 7 Dec 2023 16:48:30 +0100 Subject: [PATCH 2/6] wip tests --- CMakeLists.txt | 1 + package.xml | 3 + test/CMakeLists.txt | 126 +--------- test/all_tests.sh | 43 ++-- test/control_manager/CMakeLists.txt | 1 + .../goto_service/CMakeLists.txt | 21 ++ .../control_manager_goto_service.test | 7 - .../goto_service/goto_service.test | 30 +++ .../goto_service/goto_service_test.cpp | 230 ------------------ test/control_manager/goto_service/test.cpp | 62 +++++ test/coverage.sh | 9 +- .../x500_in_mid_air/config/custom_config.yaml | 16 -- .../config/network_config.yaml | 15 -- .../x500_in_mid_air/config/simulator.yaml | 20 -- .../x500_in_mid_air/config/world_config.yaml | 34 --- .../launch/mrs_uav_system.launch | 30 --- test/single_test.sh | 27 -- 17 files changed, 143 insertions(+), 532 deletions(-) create mode 100644 test/control_manager/CMakeLists.txt create mode 100644 test/control_manager/goto_service/CMakeLists.txt delete mode 100644 test/control_manager/goto_service/control_manager_goto_service.test create mode 100644 test/control_manager/goto_service/goto_service.test delete mode 100644 test/control_manager/goto_service/goto_service_test.cpp create mode 100644 test/control_manager/goto_service/test.cpp delete mode 100644 test/sessions/x500_in_mid_air/config/custom_config.yaml delete mode 100644 test/sessions/x500_in_mid_air/config/network_config.yaml delete mode 100644 test/sessions/x500_in_mid_air/config/simulator.yaml delete mode 100644 test/sessions/x500_in_mid_air/config/world_config.yaml delete mode 100644 test/sessions/x500_in_mid_air/launch/mrs_uav_system.launch delete mode 100755 test/single_test.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index b0cbd00a..b60cac98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ set(CATKIN_DEPENDENCIES tf2 tf2_ros tf2_geometry_msgs + mrs_uav_testing ) find_package(catkin REQUIRED COMPONENTS diff --git a/package.xml b/package.xml index d045fa7f..cf6ad0b3 100644 --- a/package.xml +++ b/package.xml @@ -26,6 +26,9 @@ tf2_ros tf2_geometry_msgs rostest + mrs_uav_testing + + mrs_uav_gazebo_simulation diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index aadf38fc..1d41968f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,127 +1,3 @@ find_package(rostest REQUIRED) -# takeoff test - -add_rostest_gtest(MrsUavManagers_UavManagerTakeoffTest - uav_manager/takeoff/uav_manager_takeoff.test - uav_manager/takeoff/takeoff_test.cpp - ) - -target_link_libraries( - MrsUavManagers_UavManagerTakeoffTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_UavManagerTakeoffTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) - -# landing test - -add_rostest_gtest(MrsUavManagers_UavManagerLandingTest - uav_manager/landing/uav_manager_landing.test - uav_manager/landing/landing_test.cpp - ) - -target_link_libraries( - MrsUavManagers_UavManagerLandingTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_UavManagerLandingTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) - -# goto service test - -add_rostest_gtest(MrsUavManagers_ControlManagerGotoServiceTest - control_manager/goto_service/control_manager_goto_service.test - control_manager/goto_service/goto_service_test.cpp - ) - -target_link_libraries( - MrsUavManagers_ControlManagerGotoServiceTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_ControlManagerGotoServiceTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) - -# eland innovation test - -add_rostest_gtest(MrsUavManagers_ControlManagerElandInnovationTest - control_manager/eland_innovation/control_manager_eland_innovation.test - control_manager/eland_innovation/eland_innovation_test.cpp - ) - -target_link_libraries( - MrsUavManagers_ControlManagerElandInnovationTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_ControlManagerElandInnovationTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) - -# eland controlerror test - -add_rostest_gtest(MrsUavManagers_ControlManagerElandControlErrorTest - control_manager/eland_control_error/control_manager_eland_control_error.test - control_manager/eland_control_error/eland_control_error_test.cpp - ) - -target_link_libraries( - MrsUavManagers_ControlManagerElandControlErrorTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_ControlManagerElandControlErrorTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) - -# failsafe controlerror test - -add_rostest_gtest(MrsUavManagers_ControlManagerFailsafeControlErrorTest - control_manager/failsafe_control_error/control_manager_failsafe_control_error.test - control_manager/failsafe_control_error/failsafe_control_error_test.cpp - ) - -target_link_libraries( - MrsUavManagers_ControlManagerFailsafeControlErrorTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_ControlManagerFailsafeControlErrorTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) - -# eland service test - -add_rostest_gtest(MrsUavManagers_ControlManagerElandServiceTest - control_manager/eland_service/control_manager_eland_service.test - control_manager/eland_service/eland_service_test.cpp - ) - -target_link_libraries( - MrsUavManagers_ControlManagerElandServiceTest - ${catkin_LIBRARIES} - ) - -add_dependencies( - MrsUavManagers_ControlManagerElandServiceTest - ${${PROJECT_NAME}_EXPORTED_TARGETS} - ${catkin_EXPORTED_TARGETS} - ) +add_subdirectory(control_manager) diff --git a/test/all_tests.sh b/test/all_tests.sh index 8a3e2f24..6614ec31 100755 --- a/test/all_tests.sh +++ b/test/all_tests.sh @@ -5,31 +5,30 @@ set -e trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG trap 'echo "$0: \"${last_command}\" command failed with exit code $?"' ERR -PACKAGE="mrs_uav_managers" -VERBOSE=1 - -[ "$VERBOSE" = "0" ] && TEXT_OUTPUT="" -[ "$VERBOSE" = "1" ] && TEXT_OUTPUT="-t" - -# build the package -catkin build $PACKAGE # it has to be fully built normally before building with --catkin-make-args tests -catkin build $PACKAGE --no-deps --catkin-make-args tests - -TEST_FILES=$(find . -name "*.test" -type f -printf "%f\n") +ORIGINAL_PATH=`pwd` + +while [ ! -e ".catkin_tools" ]; do + cd .. + if [[ `pwd` == "/" ]]; then + # we reached the root and didn't find the build/COLCON_IGNORE file - that's a fail! + echo "$0: could not find the root of the current workspace". + return 1 + fi +done -for TEST_FILE in `echo $TEST_FILES`; do +cd build - echo "$0: running test '$TEST_FILE'" +OLD_FILES=$(find . -name "*.gcda") - # folder for test results - TEST_RESULT_PATH=$(realpath /tmp/$RANDOM) - mkdir -p $TEST_RESULT_PATH +for FILE in $OLD_FILES; do + echo "$0: removing old coverage file '$FILE'" + rm $FILE +done - # run the test - rostest $PACKAGE $TEST_FILE $TEXT_OUTPUT --results-filename=$PACKAGE.test --results-base-dir="$TEST_RESULT_PATH" +cd $ORIGINAL_PATH - # evaluate the test results - echo test result path is $TEST_RESULT_PATH - catkin_test_results "$TEST_RESULT_PATH" +# build the package +catkin build --this # it has to be fully built normally before building with --catkin-make-args tests +catkin build --this --no-deps --catkin-make-args tests -done +catkin test --this -i -p 1 -s diff --git a/test/control_manager/CMakeLists.txt b/test/control_manager/CMakeLists.txt new file mode 100644 index 00000000..fe61b74b --- /dev/null +++ b/test/control_manager/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(goto_service) diff --git a/test/control_manager/goto_service/CMakeLists.txt b/test/control_manager/goto_service/CMakeLists.txt new file mode 100644 index 00000000..d92d0d9e --- /dev/null +++ b/test/control_manager/goto_service/CMakeLists.txt @@ -0,0 +1,21 @@ +get_filename_component(TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + +catkin_add_executable_with_gtest(test_${TEST_NAME} + test.cpp + ) + +target_link_libraries(test_${TEST_NAME} + ${catkin_LIBRARIES} + ) + +add_dependencies(test_${TEST_NAME} + ${${PROJECT_NAME}_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} + ) + +add_rostest(${TEST_NAME}.test + ARGS + test_path:=${CMAKE_CURRENT_SOURCE_DIR} + package_name:=${PROJECT_NAME} + test_name:=${TEST_NAME} + ) diff --git a/test/control_manager/goto_service/control_manager_goto_service.test b/test/control_manager/goto_service/control_manager_goto_service.test deleted file mode 100644 index f4689207..00000000 --- a/test/control_manager/goto_service/control_manager_goto_service.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/control_manager/goto_service/goto_service.test b/test/control_manager/goto_service/goto_service.test new file mode 100644 index 00000000..ff8c59fe --- /dev/null +++ b/test/control_manager/goto_service/goto_service.test @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/control_manager/goto_service/goto_service_test.cpp b/test/control_manager/goto_service/goto_service_test.cpp deleted file mode 100644 index 5122700a..00000000 --- a/test/control_manager/goto_service/goto_service_test.cpp +++ /dev/null @@ -1,230 +0,0 @@ -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#define POS_JUMP_SIZE 3.0 - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_midair_; - - mrs_lib::ServiceClientHandler sch_goto_; -}; - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_midair_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/midair_activation"); - - sch_goto_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/control_manager/goto"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the drone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- midair activation ------------------- | - - ROS_INFO("[%s]: activating the drone 'in mid air'", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_midair_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: midair activation service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- sleep before the action ---------------- | - - ros::Duration(1.0).sleep(); - - // | ------------------------ test goto ----------------------- | - - mrs_msgs::Vec4 goto_cmd; - - { - goto_cmd.request.goal[0] = -10; - goto_cmd.request.goal[1] = -20; - goto_cmd.request.goal[2] = 5.5; - goto_cmd.request.goal[3] = 2.2; - - ROS_INFO("[%s]: calling goto", ros::this_node::getName().c_str()); - - { - bool service_call = sch_goto_.call(goto_cmd); - - if (!service_call || !goto_cmd.response.success) { - ROS_ERROR("[%s]: goto service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ------------------ check for the result ------------------ | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for goto", ros::this_node::getName().c_str()); - - auto diag = sh_estim_manager_diag_.getMsg(); - - auto hdg = mrs_lib::AttitudeConverter(diag->pose.orientation).getHeading(); - - auto flying_normally = sh_control_manager_diag_.getMsg()->flying_normally; - - if (std::abs(goto_cmd.request.goal[0] - diag->pose.position.x) < 1e-1 && std::abs(goto_cmd.request.goal[1] - diag->pose.position.y) < 1e-1 && - std::abs(goto_cmd.request.goal[2] - diag->pose.position.z) < 1e-1 && std::abs(goto_cmd.request.goal[3] - hdg) < 1e-1 && flying_normally) { - - ROS_INFO("[%s]: finished", ros::this_node::getName().c_str()); - - return true; - } - - ros::Duration(0.01).sleep(); - } - - return false; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, goto_service) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "goto_service_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/control_manager/goto_service/test.cpp b/test/control_manager/goto_service/test.cpp new file mode 100644 index 00000000..c463a94b --- /dev/null +++ b/test/control_manager/goto_service/test.cpp @@ -0,0 +1,62 @@ +#include + +#include + +class Tester : public mrs_uav_testing::TestGeneric { + +public: + bool test(); +}; + +bool Tester::test() { + + { + auto [success, message] = activateMidAir(); + + if (!success) { + ROS_ERROR("[%s]: midair activation failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + { + auto [success, message] = this->gotoAbs(0, 0, 2.0, 0); + + if (!success) { + ROS_ERROR("[%s]: goto failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + this->sleep(5.0); + + if (this->isFlyingNormally()) { + return true; + } else { + ROS_ERROR("[%s]: not flying normally", ros::this_node::getName().c_str()); + return false; + } +} + + +TEST(TESTSuite, test) { + + Tester tester; + + bool result = tester.test(); + + if (result) { + GTEST_SUCCEED(); + } else { + GTEST_FAIL(); + } +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { + + ros::init(argc, argv, "test"); + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/coverage.sh b/test/coverage.sh index 38093c5f..9e75c239 100755 --- a/test/coverage.sh +++ b/test/coverage.sh @@ -1,10 +1,5 @@ #!/bin/bash -PACKAGE_NAME=mrs_uav_managers - -# find the build folder of the current workspace -roscd $PACKAGE_NAME - while [ ! -e ".catkin_tools" ]; do cd .. if [[ `pwd` == "/" ]]; then @@ -14,11 +9,13 @@ while [ ! -e ".catkin_tools" ]; do fi done +WORKSPACE_NAME=${PWD##*/} + cd build lcov --capture --directory . --output-file coverage.info lcov --remove coverage.info "*/test/*" --output-file coverage.info.removed -lcov --extract coverage.info.removed "*/*workspace/*" --output-file coverage.info.cleaned +lcov --extract coverage.info.removed "*/${WORKSPACE_NAME}/src/*" --output-file coverage.info.cleaned genhtml -o coverage_html coverage.info.cleaned | tee /tmp/genhtml.log COVERAGE_PCT=`cat /tmp/genhtml.log | tail -n 1 | awk '{print $2}'` diff --git a/test/sessions/x500_in_mid_air/config/custom_config.yaml b/test/sessions/x500_in_mid_air/config/custom_config.yaml deleted file mode 100644 index 9f6bbb87..00000000 --- a/test/sessions/x500_in_mid_air/config/custom_config.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# GET ALL PARAMETERS USABLE FOR CUSTOM CONFIG BY RUNNING: -## -------------------------------------------------------------- -## | rosrun mrs_uav_core get_public_params.py # -## -------------------------------------------------------------- - -mrs_uav_managers: - - estimation_manager: - - # loaded state estimator plugins - state_estimators: [ - "gps_baro", - ] - - initial_state_estimator: "gps_baro" # will be used as the first state estimator - agl_height_estimator: "garmin_agl" # only slightly filtered height for checking min height (not used in control feedback) diff --git a/test/sessions/x500_in_mid_air/config/network_config.yaml b/test/sessions/x500_in_mid_air/config/network_config.yaml deleted file mode 100644 index 08f370d6..00000000 --- a/test/sessions/x500_in_mid_air/config/network_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# 1. This list is used by NimbroNetwork for mutual communication of the UAVs -# The names of the robots have to match hostnames described in /etc/hosts. -# -# 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. -# The names should match the true "UAV_NAMES" (the topic prefixes). -# -# network_config:=~/config/network_config.yaml -# -# to the core.launch and nimbro.launch. - -network: - - robot_names: [ - uav1, - ] diff --git a/test/sessions/x500_in_mid_air/config/simulator.yaml b/test/sessions/x500_in_mid_air/config/simulator.yaml deleted file mode 100644 index 196c2e8d..00000000 --- a/test/sessions/x500_in_mid_air/config/simulator.yaml +++ /dev/null @@ -1,20 +0,0 @@ -simulation_rate: 250.0 -clock_rate: 250.0 -realtime_factor: 1.0 - -iterate_without_input: true - -individual_takeoff_platform: - enabled: true - -uav_names: [ - "uav1", -] - -uav1: - type: "x500" - spawn: - x: 10.0 - y: 15.0 - z: 2.0 - heading: 0 diff --git a/test/sessions/x500_in_mid_air/config/world_config.yaml b/test/sessions/x500_in_mid_air/config/world_config.yaml deleted file mode 100644 index 9b550677..00000000 --- a/test/sessions/x500_in_mid_air/config/world_config.yaml +++ /dev/null @@ -1,34 +0,0 @@ -world_origin: - - units: "LATLON" # {"UTM, "LATLON"} - - origin_x: 47.397743 - origin_y: 8.545594 - -safety_area: - - enabled: true - - horizontal: - - # the frame of reference in which the points are expressed - frame_name: "world_origin" - - # polygon - # - # x, y [m] for any frame_name except latlon_origin - # x = latitude, y = longitude [deg] for frame_name=="latlon_origin" - points: [ - -50, -50, - 50, -50, - 50, 50, - -50, 50, - ] - - vertical: - - # the frame of reference in which the max&min z is expressed - frame_name: "world_origin" - - max_z: 15.0 - min_z: 0.5 diff --git a/test/sessions/x500_in_mid_air/launch/mrs_uav_system.launch b/test/sessions/x500_in_mid_air/launch/mrs_uav_system.launch deleted file mode 100644 index 83567506..00000000 --- a/test/sessions/x500_in_mid_air/launch/mrs_uav_system.launch +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/single_test.sh b/test/single_test.sh deleted file mode 100755 index 4505f41c..00000000 --- a/test/single_test.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -set -e - -trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG -trap 'echo "$0: \"${last_command}\" command failed with exit code $?"' ERR - -PACKAGE="mrs_uav_managers" -VERBOSE=1 - -[ "$VERBOSE" = "0" ] && TEXT_OUTPUT="" -[ "$VERBOSE" = "1" ] && TEXT_OUTPUT="-t" - -# build the package -catkin build $PACKAGE # it has to be fully built normally before building with --catkin-make-args tests -catkin build $PACKAGE --no-deps --catkin-make-args tests - -# folder for test results -TEST_RESULT_PATH=$(realpath /tmp/$RANDOM) -mkdir -p $TEST_RESULT_PATH - -# run the test -rostest $PACKAGE control_manager_eland_control_error.test $TEXT_OUTPUT --results-filename=$PACKAGE.test --results-base-dir="$TEST_RESULT_PATH" - -# evaluate the test results -echo test result path is $TEST_RESULT_PATH -catkin_test_results "$TEST_RESULT_PATH" From 5467b0d0f83152d4c8c57ed1e97458cd2f709e70 Mon Sep 17 00:00:00 2001 From: Tomas Baca Date: Sat, 9 Dec 2023 09:14:58 +0100 Subject: [PATCH 3/6] conditioned coverage flags --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b60cac98..346f8320 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") +if(COVERAGE) + message(WARNING "building with --coverage, the performance might be limited") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") +endif() + set(LIBRARIES MrsUavManagers_GainManager MrsUavManagers_ConstraintManager @@ -164,9 +170,6 @@ target_link_libraries(MrsUavManagers_TransformManager if(CATKIN_ENABLE_TESTING) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") - add_subdirectory(test) endif() From 35a74342627d35eeee6788a5e4f6ba0bb57c7205 Mon Sep 17 00:00:00 2001 From: Tomas Baca Date: Sat, 9 Dec 2023 09:21:07 +0100 Subject: [PATCH 4/6] updated flags --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 346f8320..06d83d04 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,8 @@ find_package(catkin REQUIRED COMPONENTS set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") +add_definitions(-Wall) +add_definitions(-Wextra) if(COVERAGE) message(WARNING "building with --coverage, the performance might be limited") From 0c3eb1750717b5d91a6ef3281eafbb2ec4f82840 Mon Sep 17 00:00:00 2001 From: Tomas Baca Date: Mon, 11 Dec 2023 15:32:40 +0100 Subject: [PATCH 5/6] updated tests --- test/CMakeLists.txt | 2 + test/control_manager/CMakeLists.txt | 6 + .../eland_control_error/CMakeLists.txt | 16 ++ .../config/custom_config.yaml | 4 +- .../config/network_config.yaml | 15 -- .../eland_control_error/config/simulator.yaml | 20 -- .../config/world_config.yaml | 34 --- .../control_manager_eland_control_error.test | 7 - .../eland_control_error.test | 36 +++ .../eland_control_error_test.cpp | 224 ----------------- .../launch/mrs_uav_system.launch | 30 --- .../eland_control_error/test.cpp | 81 ++++++ .../eland_innovation/CMakeLists.txt | 16 ++ .../config/network_config.yaml | 15 -- .../eland_innovation/config/simulator.yaml | 20 -- .../control_manager_eland_innovation.test | 7 - .../eland_innovation/eland_innovation.test | 37 +++ .../eland_innovation_test.cpp | 235 ------------------ .../launch/mrs_uav_system.launch | 30 --- .../control_manager/eland_innovation/test.cpp | 108 ++++++++ .../control_manager_eland_service.test | 7 - .../eland_service/eland_service_test.cpp | 222 ----------------- .../failsafe_control_error/CMakeLists.txt | 16 ++ .../config/custom_config.yaml | 6 +- .../config/network_config.yaml | 15 -- .../config/simulator.yaml | 20 -- .../config/world_config.yaml | 34 --- ...ontrol_manager_failsafe_control_error.test | 7 - .../failsafe_control_error.test | 36 +++ .../failsafe_control_error_test.cpp | 224 ----------------- .../launch/mrs_uav_system.launch | 30 --- .../failsafe_control_error/test.cpp | 81 ++++++ .../goto_service/CMakeLists.txt | 7 +- .../goto_service/goto_service.test | 17 +- test/uav_manager/CMakeLists.txt | 3 + test/uav_manager/landing/CMakeLists.txt | 16 ++ test/uav_manager/landing/landing.test | 35 +++ test/uav_manager/landing/landing_test.cpp | 217 ---------------- test/uav_manager/landing/test.cpp | 100 ++++++++ .../landing/uav_manager_landing.test | 7 - test/uav_manager/takeoff/CMakeLists.txt | 16 ++ .../takeoff/config/custom_config.yaml | 16 -- .../takeoff/config/mrs_simulator.yaml | 3 + .../takeoff/config/network_config.yaml | 15 -- .../uav_manager/takeoff/config/simulator.yaml | 20 -- .../takeoff/config/world_config.yaml | 34 --- .../takeoff/launch/mrs_uav_system.launch | 35 --- test/uav_manager/takeoff/takeoff.test | 36 +++ test/uav_manager/takeoff/takeoff_test.cpp | 189 -------------- test/uav_manager/takeoff/test.cpp | 51 ++++ .../takeoff/uav_manager_takeoff.test | 7 - 51 files changed, 712 insertions(+), 1753 deletions(-) create mode 100644 test/control_manager/eland_control_error/CMakeLists.txt delete mode 100644 test/control_manager/eland_control_error/config/network_config.yaml delete mode 100644 test/control_manager/eland_control_error/config/simulator.yaml delete mode 100644 test/control_manager/eland_control_error/config/world_config.yaml delete mode 100644 test/control_manager/eland_control_error/control_manager_eland_control_error.test create mode 100644 test/control_manager/eland_control_error/eland_control_error.test delete mode 100644 test/control_manager/eland_control_error/eland_control_error_test.cpp delete mode 100644 test/control_manager/eland_control_error/launch/mrs_uav_system.launch create mode 100644 test/control_manager/eland_control_error/test.cpp create mode 100644 test/control_manager/eland_innovation/CMakeLists.txt delete mode 100644 test/control_manager/eland_innovation/config/network_config.yaml delete mode 100644 test/control_manager/eland_innovation/config/simulator.yaml delete mode 100644 test/control_manager/eland_innovation/control_manager_eland_innovation.test create mode 100644 test/control_manager/eland_innovation/eland_innovation.test delete mode 100644 test/control_manager/eland_innovation/eland_innovation_test.cpp delete mode 100644 test/control_manager/eland_innovation/launch/mrs_uav_system.launch create mode 100644 test/control_manager/eland_innovation/test.cpp delete mode 100644 test/control_manager/eland_service/control_manager_eland_service.test delete mode 100644 test/control_manager/eland_service/eland_service_test.cpp create mode 100644 test/control_manager/failsafe_control_error/CMakeLists.txt delete mode 100644 test/control_manager/failsafe_control_error/config/network_config.yaml delete mode 100644 test/control_manager/failsafe_control_error/config/simulator.yaml delete mode 100644 test/control_manager/failsafe_control_error/config/world_config.yaml delete mode 100644 test/control_manager/failsafe_control_error/control_manager_failsafe_control_error.test create mode 100644 test/control_manager/failsafe_control_error/failsafe_control_error.test delete mode 100644 test/control_manager/failsafe_control_error/failsafe_control_error_test.cpp delete mode 100644 test/control_manager/failsafe_control_error/launch/mrs_uav_system.launch create mode 100644 test/control_manager/failsafe_control_error/test.cpp create mode 100644 test/uav_manager/CMakeLists.txt create mode 100644 test/uav_manager/landing/CMakeLists.txt create mode 100644 test/uav_manager/landing/landing.test delete mode 100644 test/uav_manager/landing/landing_test.cpp create mode 100644 test/uav_manager/landing/test.cpp delete mode 100644 test/uav_manager/landing/uav_manager_landing.test create mode 100644 test/uav_manager/takeoff/CMakeLists.txt delete mode 100644 test/uav_manager/takeoff/config/custom_config.yaml create mode 100644 test/uav_manager/takeoff/config/mrs_simulator.yaml delete mode 100644 test/uav_manager/takeoff/config/network_config.yaml delete mode 100644 test/uav_manager/takeoff/config/simulator.yaml delete mode 100644 test/uav_manager/takeoff/config/world_config.yaml delete mode 100644 test/uav_manager/takeoff/launch/mrs_uav_system.launch create mode 100644 test/uav_manager/takeoff/takeoff.test delete mode 100644 test/uav_manager/takeoff/takeoff_test.cpp create mode 100644 test/uav_manager/takeoff/test.cpp delete mode 100644 test/uav_manager/takeoff/uav_manager_takeoff.test diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1d41968f..c3782ba4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,5 @@ find_package(rostest REQUIRED) add_subdirectory(control_manager) + +add_subdirectory(uav_manager) diff --git a/test/control_manager/CMakeLists.txt b/test/control_manager/CMakeLists.txt index fe61b74b..17b34a55 100644 --- a/test/control_manager/CMakeLists.txt +++ b/test/control_manager/CMakeLists.txt @@ -1 +1,7 @@ add_subdirectory(goto_service) + +add_subdirectory(eland_control_error) + +add_subdirectory(eland_innovation) + +add_subdirectory(failsafe_control_error) diff --git a/test/control_manager/eland_control_error/CMakeLists.txt b/test/control_manager/eland_control_error/CMakeLists.txt new file mode 100644 index 00000000..bf8f9853 --- /dev/null +++ b/test/control_manager/eland_control_error/CMakeLists.txt @@ -0,0 +1,16 @@ +get_filename_component(TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + +catkin_add_executable_with_gtest(test_${TEST_NAME} + test.cpp + ) + +target_link_libraries(test_${TEST_NAME} + ${catkin_LIBRARIES} + ) + +add_dependencies(test_${TEST_NAME} + ${${PROJECT_NAME}_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} + ) + +add_rostest(${TEST_NAME}.test) diff --git a/test/control_manager/eland_control_error/config/custom_config.yaml b/test/control_manager/eland_control_error/config/custom_config.yaml index 3b685fac..c7d83d50 100644 --- a/test/control_manager/eland_control_error/config/custom_config.yaml +++ b/test/control_manager/eland_control_error/config/custom_config.yaml @@ -9,10 +9,10 @@ mrs_uav_managers: # loaded state estimator plugins state_estimators: [ - "passthrough", + "gps_baro", ] - initial_state_estimator: "passthrough" # will be used as the first state estimator + initial_state_estimator: "gps_baro" # will be used as the first state estimator agl_height_estimator: "" # only slightly filtered height for checking min height (not used in control feedback) control_manager: diff --git a/test/control_manager/eland_control_error/config/network_config.yaml b/test/control_manager/eland_control_error/config/network_config.yaml deleted file mode 100644 index 08f370d6..00000000 --- a/test/control_manager/eland_control_error/config/network_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# 1. This list is used by NimbroNetwork for mutual communication of the UAVs -# The names of the robots have to match hostnames described in /etc/hosts. -# -# 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. -# The names should match the true "UAV_NAMES" (the topic prefixes). -# -# network_config:=~/config/network_config.yaml -# -# to the core.launch and nimbro.launch. - -network: - - robot_names: [ - uav1, - ] diff --git a/test/control_manager/eland_control_error/config/simulator.yaml b/test/control_manager/eland_control_error/config/simulator.yaml deleted file mode 100644 index 7bdd82f3..00000000 --- a/test/control_manager/eland_control_error/config/simulator.yaml +++ /dev/null @@ -1,20 +0,0 @@ -simulation_rate: 250.0 -clock_rate: 250.0 -realtime_factor: 1.0 - -iterate_without_input: true - -individual_takeoff_platform: - enabled: true - -uav_names: [ - "uav1", -] - -uav1: - type: "x500" - spawn: - x: 5.0 - y: 5.0 - z: 2.0 - heading: 0 diff --git a/test/control_manager/eland_control_error/config/world_config.yaml b/test/control_manager/eland_control_error/config/world_config.yaml deleted file mode 100644 index 00e01eef..00000000 --- a/test/control_manager/eland_control_error/config/world_config.yaml +++ /dev/null @@ -1,34 +0,0 @@ -world_origin: - - units: "LATLON" # {"UTM, "LATLON"} - - origin_x: 47.397743 - origin_y: 8.545594 - -safety_area: - - enabled: false - - horizontal: - - # the frame of reference in which the points are expressed - frame_name: "world_origin" - - # polygon - # - # x, y [m] for any frame_name except latlon_origin - # x = latitude, y = longitude [deg] for frame_name=="latlon_origin" - points: [ - -50, -50, - 50, -50, - 50, 50, - -50, 50, - ] - - vertical: - - # the frame of reference in which the max&min z is expressed - frame_name: "world_origin" - - max_z: 15.0 - min_z: 0.5 diff --git a/test/control_manager/eland_control_error/control_manager_eland_control_error.test b/test/control_manager/eland_control_error/control_manager_eland_control_error.test deleted file mode 100644 index 9cddd763..00000000 --- a/test/control_manager/eland_control_error/control_manager_eland_control_error.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/control_manager/eland_control_error/eland_control_error.test b/test/control_manager/eland_control_error/eland_control_error.test new file mode 100644 index 00000000..c17dfb02 --- /dev/null +++ b/test/control_manager/eland_control_error/eland_control_error.test @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/control_manager/eland_control_error/eland_control_error_test.cpp b/test/control_manager/eland_control_error/eland_control_error_test.cpp deleted file mode 100644 index d1d7cdd9..00000000 --- a/test/control_manager/eland_control_error/eland_control_error_test.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_midair_; - - mrs_lib::ServiceClientHandler sch_goto_; -}; - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_midair_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/midair_activation"); - - sch_goto_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/control_manager/goto_relative"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the drone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- midair activation ------------------- | - - ROS_INFO("[%s]: activating the drone 'in mid air'", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_midair_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: midair activation service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- sleep before the action ---------------- | - - ros::Duration(1.0).sleep(); - - // | -------------------------- goto -------------------------- | - - { - mrs_msgs::Vec4 goto_cmd; - - goto_cmd.request.goal[0] = 5.0; - - ROS_INFO("[%s]: calling goto", ros::this_node::getName().c_str()); - - { - bool service_call = sch_goto_.call(goto_cmd); - - if (!service_call || !goto_cmd.response.success) { - ROS_ERROR("[%s]: goto service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------- wait for emergency controller ------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for EmergencyController", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->active_controller == "EmergencyController") { - break; - } - } - - // | -------------------- wait for landing -------------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for landing", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->output_enabled == false) { - break; - } - } - - return true; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, eland_control_error) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "eland_control_error_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/control_manager/eland_control_error/launch/mrs_uav_system.launch b/test/control_manager/eland_control_error/launch/mrs_uav_system.launch deleted file mode 100644 index 1811aa12..00000000 --- a/test/control_manager/eland_control_error/launch/mrs_uav_system.launch +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/control_manager/eland_control_error/test.cpp b/test/control_manager/eland_control_error/test.cpp new file mode 100644 index 00000000..d6338b36 --- /dev/null +++ b/test/control_manager/eland_control_error/test.cpp @@ -0,0 +1,81 @@ +#include + +#include + +class Tester : public mrs_uav_testing::TestGeneric { + +public: + bool test(); +}; + +bool Tester::test() { + + { + auto [success, message] = activateMidAir(); + + if (!success) { + ROS_ERROR("[%s]: midair activation failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + { + auto [success, message] = this->gotoRel(2, 2, 2, 0); + + if (success) { + ROS_ERROR("[%s]: goto succeeded, that should not happen in this case: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + // | -------------- wait for the eland to trigger ------------- | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!isFlyingNormally() && getActiveController() == "EmergencyController" && getActiveTracker() == "LandoffTracker") { + break; + } + } + + // | -------------------- wait for landing -------------------- | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!this->isOutputEnabled()) { + return true; + } + } + + return false; +} + + +TEST(TESTSuite, test) { + + Tester tester; + + bool result = tester.test(); + + if (result) { + GTEST_SUCCEED(); + } else { + GTEST_FAIL(); + } +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { + + ros::init(argc, argv, "test"); + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/control_manager/eland_innovation/CMakeLists.txt b/test/control_manager/eland_innovation/CMakeLists.txt new file mode 100644 index 00000000..bf8f9853 --- /dev/null +++ b/test/control_manager/eland_innovation/CMakeLists.txt @@ -0,0 +1,16 @@ +get_filename_component(TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + +catkin_add_executable_with_gtest(test_${TEST_NAME} + test.cpp + ) + +target_link_libraries(test_${TEST_NAME} + ${catkin_LIBRARIES} + ) + +add_dependencies(test_${TEST_NAME} + ${${PROJECT_NAME}_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} + ) + +add_rostest(${TEST_NAME}.test) diff --git a/test/control_manager/eland_innovation/config/network_config.yaml b/test/control_manager/eland_innovation/config/network_config.yaml deleted file mode 100644 index 08f370d6..00000000 --- a/test/control_manager/eland_innovation/config/network_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# 1. This list is used by NimbroNetwork for mutual communication of the UAVs -# The names of the robots have to match hostnames described in /etc/hosts. -# -# 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. -# The names should match the true "UAV_NAMES" (the topic prefixes). -# -# network_config:=~/config/network_config.yaml -# -# to the core.launch and nimbro.launch. - -network: - - robot_names: [ - uav1, - ] diff --git a/test/control_manager/eland_innovation/config/simulator.yaml b/test/control_manager/eland_innovation/config/simulator.yaml deleted file mode 100644 index 7bdd82f3..00000000 --- a/test/control_manager/eland_innovation/config/simulator.yaml +++ /dev/null @@ -1,20 +0,0 @@ -simulation_rate: 250.0 -clock_rate: 250.0 -realtime_factor: 1.0 - -iterate_without_input: true - -individual_takeoff_platform: - enabled: true - -uav_names: [ - "uav1", -] - -uav1: - type: "x500" - spawn: - x: 5.0 - y: 5.0 - z: 2.0 - heading: 0 diff --git a/test/control_manager/eland_innovation/control_manager_eland_innovation.test b/test/control_manager/eland_innovation/control_manager_eland_innovation.test deleted file mode 100644 index 3c85ed37..00000000 --- a/test/control_manager/eland_innovation/control_manager_eland_innovation.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/control_manager/eland_innovation/eland_innovation.test b/test/control_manager/eland_innovation/eland_innovation.test new file mode 100644 index 00000000..54865e18 --- /dev/null +++ b/test/control_manager/eland_innovation/eland_innovation.test @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/control_manager/eland_innovation/eland_innovation_test.cpp b/test/control_manager/eland_innovation/eland_innovation_test.cpp deleted file mode 100644 index e066b952..00000000 --- a/test/control_manager/eland_innovation/eland_innovation_test.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#define POS_JUMP_SIZE 3.0 - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - mrs_lib::SubscribeHandler sh_hw_api_odom_; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_midair_; - - mrs_lib::PublisherHandler ph_odometry_; - - void callbackOdometry(const nav_msgs::Odometry::ConstPtr msg); - - std::atomic odom_jumped_ = false; -}; - -//} - -/* callbackOdometry() //{ */ - -void Tester::callbackOdometry(const nav_msgs::Odometry::ConstPtr msg) { - - nav_msgs::Odometry odom_out = *msg; - - if (odom_jumped_) { - odom_out.pose.pose.position.x += POS_JUMP_SIZE; - } - - ph_odometry_.publish(odom_out); -} - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - sh_hw_api_odom_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/hw_api/odometry_unchanged", &Tester::callbackOdometry, this); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_midair_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/midair_activation"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); - - // | ----------------------- publishers ----------------------- | - - ph_odometry_ = mrs_lib::PublisherHandler(nh_, "/" + uav_name + "/hw_api/odometry"); - - ROS_INFO("[%s]: publishers initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the drone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- midair activation ------------------- | - - ROS_INFO("[%s]: activating the drone 'in mid air'", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_midair_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: midair activation service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- sleep before the action ---------------- | - - ros::Duration(1.0).sleep(); - - // | ------------------- make odometry jump ------------------- | - - odom_jumped_ = true; - - // | -------------- wait for emergency controller ------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for EmergencyController", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->active_controller == "EmergencyController") { - break; - } - } - - // | -------------------- wait for landing -------------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for landing", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->output_enabled == false) { - break; - } - } - - return true; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, eland_innovation) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "eland_innovation_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/control_manager/eland_innovation/launch/mrs_uav_system.launch b/test/control_manager/eland_innovation/launch/mrs_uav_system.launch deleted file mode 100644 index 675fe202..00000000 --- a/test/control_manager/eland_innovation/launch/mrs_uav_system.launch +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/control_manager/eland_innovation/test.cpp b/test/control_manager/eland_innovation/test.cpp new file mode 100644 index 00000000..940caecb --- /dev/null +++ b/test/control_manager/eland_innovation/test.cpp @@ -0,0 +1,108 @@ +#include + +#include + +#include + +#define POS_JUMP_SIZE 3.0 + +class Tester : public mrs_uav_testing::TestGeneric { + +public: + bool test(); + + Tester(); + + mrs_lib::SubscribeHandler sh_hw_api_odom_; + + mrs_lib::PublisherHandler ph_odometry_; + + void callbackOdometry(const nav_msgs::Odometry::ConstPtr msg); + + std::atomic odom_jumped_ = false; +}; + +Tester::Tester() : mrs_uav_testing::TestGeneric() { + + sh_hw_api_odom_ = mrs_lib::SubscribeHandler(shopts_, "/" + _uav_name_ + "/hw_api/odometry_unchanged", &Tester::callbackOdometry, this); + + ph_odometry_ = mrs_lib::PublisherHandler(nh_, "/" + _uav_name_ + "/hw_api/odometry"); +} + +void Tester::callbackOdometry(const nav_msgs::Odometry::ConstPtr msg) { + + nav_msgs::Odometry odom_out = *msg; + + if (odom_jumped_) { + odom_out.pose.pose.position.x += POS_JUMP_SIZE; + } + + ph_odometry_.publish(odom_out); +} + +bool Tester::test() { + + { + auto [success, message] = activateMidAir(); + + if (!success) { + ROS_ERROR("[%s]: midair activation failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + sleep(1.0); + + odom_jumped_ = true; + + // | -------------- wait for the eland to trigger ------------- | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!isFlyingNormally() && getActiveController() == "EmergencyController" && getActiveTracker() == "LandoffTracker") { + break; + } + } + + // | -------------------- wait for landing -------------------- | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!this->isOutputEnabled()) { + return true; + } + } + + return false; +} + + +TEST(TESTSuite, test) { + + Tester tester; + + bool result = tester.test(); + + if (result) { + GTEST_SUCCEED(); + } else { + GTEST_FAIL(); + } +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { + + ros::init(argc, argv, "test"); + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/control_manager/eland_service/control_manager_eland_service.test b/test/control_manager/eland_service/control_manager_eland_service.test deleted file mode 100644 index c114f7b1..00000000 --- a/test/control_manager/eland_service/control_manager_eland_service.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/control_manager/eland_service/eland_service_test.cpp b/test/control_manager/eland_service/eland_service_test.cpp deleted file mode 100644 index f00afaaf..00000000 --- a/test/control_manager/eland_service/eland_service_test.cpp +++ /dev/null @@ -1,222 +0,0 @@ -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#define POS_JUMP_SIZE 3.0 - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_midair_; - - mrs_lib::ServiceClientHandler sch_eland_; -}; - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_midair_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/midair_activation"); - - sch_eland_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/control_manager/eland"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the edrone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- midair activation ------------------- | - - ROS_INFO("[%s]: activating the drone 'in mid air'", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_midair_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: midair activation service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- sleep before the action ---------------- | - - ros::Duration(1.0).sleep(); - - // | ----------------- call the eland service ----------------- | - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_eland_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: eland service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------- wait for emergency controller ------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for EmergencyController", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->active_controller == "EmergencyController") { - break; - } - } - - // | -------------------- wait for landing -------------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for landing", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->output_enabled == false) { - break; - } - } - - return true; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, eland_service) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "eland_service_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/control_manager/failsafe_control_error/CMakeLists.txt b/test/control_manager/failsafe_control_error/CMakeLists.txt new file mode 100644 index 00000000..bf8f9853 --- /dev/null +++ b/test/control_manager/failsafe_control_error/CMakeLists.txt @@ -0,0 +1,16 @@ +get_filename_component(TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + +catkin_add_executable_with_gtest(test_${TEST_NAME} + test.cpp + ) + +target_link_libraries(test_${TEST_NAME} + ${catkin_LIBRARIES} + ) + +add_dependencies(test_${TEST_NAME} + ${${PROJECT_NAME}_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} + ) + +add_rostest(${TEST_NAME}.test) diff --git a/test/control_manager/failsafe_control_error/config/custom_config.yaml b/test/control_manager/failsafe_control_error/config/custom_config.yaml index 7f4d9f91..185f2c96 100644 --- a/test/control_manager/failsafe_control_error/config/custom_config.yaml +++ b/test/control_manager/failsafe_control_error/config/custom_config.yaml @@ -9,15 +9,15 @@ mrs_uav_managers: # loaded state estimator plugins state_estimators: [ - "passthrough", + "gps_baro", ] - initial_state_estimator: "passthrough" # will be used as the first state estimator + initial_state_estimator: "gps_baro" # will be used as the first state estimator agl_height_estimator: "" # only slightly filtered height for checking min height (not used in control feedback) control_manager: MpcController: eland_threshold: 0.0 # [m], position error triggering eland - failsafe_threshold: 0.1 # [m], position error triggering failsafe land + failsafe_threshold: 0.2 # [m], position error triggering failsafe land odometry_innovation_threshold: 0.0 # [m], position odometry innovation threshold diff --git a/test/control_manager/failsafe_control_error/config/network_config.yaml b/test/control_manager/failsafe_control_error/config/network_config.yaml deleted file mode 100644 index 08f370d6..00000000 --- a/test/control_manager/failsafe_control_error/config/network_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# 1. This list is used by NimbroNetwork for mutual communication of the UAVs -# The names of the robots have to match hostnames described in /etc/hosts. -# -# 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. -# The names should match the true "UAV_NAMES" (the topic prefixes). -# -# network_config:=~/config/network_config.yaml -# -# to the core.launch and nimbro.launch. - -network: - - robot_names: [ - uav1, - ] diff --git a/test/control_manager/failsafe_control_error/config/simulator.yaml b/test/control_manager/failsafe_control_error/config/simulator.yaml deleted file mode 100644 index 7bdd82f3..00000000 --- a/test/control_manager/failsafe_control_error/config/simulator.yaml +++ /dev/null @@ -1,20 +0,0 @@ -simulation_rate: 250.0 -clock_rate: 250.0 -realtime_factor: 1.0 - -iterate_without_input: true - -individual_takeoff_platform: - enabled: true - -uav_names: [ - "uav1", -] - -uav1: - type: "x500" - spawn: - x: 5.0 - y: 5.0 - z: 2.0 - heading: 0 diff --git a/test/control_manager/failsafe_control_error/config/world_config.yaml b/test/control_manager/failsafe_control_error/config/world_config.yaml deleted file mode 100644 index 00e01eef..00000000 --- a/test/control_manager/failsafe_control_error/config/world_config.yaml +++ /dev/null @@ -1,34 +0,0 @@ -world_origin: - - units: "LATLON" # {"UTM, "LATLON"} - - origin_x: 47.397743 - origin_y: 8.545594 - -safety_area: - - enabled: false - - horizontal: - - # the frame of reference in which the points are expressed - frame_name: "world_origin" - - # polygon - # - # x, y [m] for any frame_name except latlon_origin - # x = latitude, y = longitude [deg] for frame_name=="latlon_origin" - points: [ - -50, -50, - 50, -50, - 50, 50, - -50, 50, - ] - - vertical: - - # the frame of reference in which the max&min z is expressed - frame_name: "world_origin" - - max_z: 15.0 - min_z: 0.5 diff --git a/test/control_manager/failsafe_control_error/control_manager_failsafe_control_error.test b/test/control_manager/failsafe_control_error/control_manager_failsafe_control_error.test deleted file mode 100644 index aa4ac32c..00000000 --- a/test/control_manager/failsafe_control_error/control_manager_failsafe_control_error.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/control_manager/failsafe_control_error/failsafe_control_error.test b/test/control_manager/failsafe_control_error/failsafe_control_error.test new file mode 100644 index 00000000..c17dfb02 --- /dev/null +++ b/test/control_manager/failsafe_control_error/failsafe_control_error.test @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/control_manager/failsafe_control_error/failsafe_control_error_test.cpp b/test/control_manager/failsafe_control_error/failsafe_control_error_test.cpp deleted file mode 100644 index dbc35f85..00000000 --- a/test/control_manager/failsafe_control_error/failsafe_control_error_test.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_midair_; - - mrs_lib::ServiceClientHandler sch_goto_; -}; - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_midair_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/midair_activation"); - - sch_goto_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/control_manager/goto_relative"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the drone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- midair activation ------------------- | - - ROS_INFO("[%s]: activating the drone 'in mid air'", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_midair_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: midair activation service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- sleep before the action ---------------- | - - ros::Duration(1.0).sleep(); - - // | -------------------------- goto -------------------------- | - - { - mrs_msgs::Vec4 goto_cmd; - - goto_cmd.request.goal[0] = 5.0; - - ROS_INFO("[%s]: calling goto", ros::this_node::getName().c_str()); - - { - bool service_call = sch_goto_.call(goto_cmd); - - if (!service_call || !goto_cmd.response.success) { - ROS_ERROR("[%s]: goto service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ------------- waiting for failsafe controller ------------ | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for FailsafeController", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->active_controller == "FailsafeController") { - break; - } - } - - // | -------------------- wait for landing -------------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for landing", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->output_enabled == false) { - break; - } - } - - return true; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, failsafe_control_error) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "failsafe_control_error_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/control_manager/failsafe_control_error/launch/mrs_uav_system.launch b/test/control_manager/failsafe_control_error/launch/mrs_uav_system.launch deleted file mode 100644 index f8354f47..00000000 --- a/test/control_manager/failsafe_control_error/launch/mrs_uav_system.launch +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/control_manager/failsafe_control_error/test.cpp b/test/control_manager/failsafe_control_error/test.cpp new file mode 100644 index 00000000..7843b7a7 --- /dev/null +++ b/test/control_manager/failsafe_control_error/test.cpp @@ -0,0 +1,81 @@ +#include + +#include + +class Tester : public mrs_uav_testing::TestGeneric { + +public: + bool test(); +}; + +bool Tester::test() { + + { + auto [success, message] = activateMidAir(); + + if (!success) { + ROS_ERROR("[%s]: midair activation failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + { + auto [success, message] = this->gotoRel(2, 2, 2, 0); + + if (success) { + ROS_ERROR("[%s]: goto succeeded, that should not happen in this case: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + // | ------------ wait for the failsafe to trigger ------------ | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!isFlyingNormally() && getActiveController() == "FailsafeController") { + break; + } + } + + // | -------------------- wait for landing -------------------- | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!this->isOutputEnabled()) { + return true; + } + } + + return false; +} + + +TEST(TESTSuite, test) { + + Tester tester; + + bool result = tester.test(); + + if (result) { + GTEST_SUCCEED(); + } else { + GTEST_FAIL(); + } +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { + + ros::init(argc, argv, "test"); + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/control_manager/goto_service/CMakeLists.txt b/test/control_manager/goto_service/CMakeLists.txt index d92d0d9e..bf8f9853 100644 --- a/test/control_manager/goto_service/CMakeLists.txt +++ b/test/control_manager/goto_service/CMakeLists.txt @@ -13,9 +13,4 @@ add_dependencies(test_${TEST_NAME} ${catkin_EXPORTED_TARGETS} ) -add_rostest(${TEST_NAME}.test - ARGS - test_path:=${CMAKE_CURRENT_SOURCE_DIR} - package_name:=${PROJECT_NAME} - test_name:=${TEST_NAME} - ) +add_rostest(${TEST_NAME}.test) diff --git a/test/control_manager/goto_service/goto_service.test b/test/control_manager/goto_service/goto_service.test index ff8c59fe..604b7439 100644 --- a/test/control_manager/goto_service/goto_service.test +++ b/test/control_manager/goto_service/goto_service.test @@ -1,12 +1,17 @@ + + - - - - + + + + + + + @@ -22,8 +27,8 @@ - - + + diff --git a/test/uav_manager/CMakeLists.txt b/test/uav_manager/CMakeLists.txt new file mode 100644 index 00000000..5c1fda7a --- /dev/null +++ b/test/uav_manager/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(takeoff) + +add_subdirectory(landing) diff --git a/test/uav_manager/landing/CMakeLists.txt b/test/uav_manager/landing/CMakeLists.txt new file mode 100644 index 00000000..bf8f9853 --- /dev/null +++ b/test/uav_manager/landing/CMakeLists.txt @@ -0,0 +1,16 @@ +get_filename_component(TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + +catkin_add_executable_with_gtest(test_${TEST_NAME} + test.cpp + ) + +target_link_libraries(test_${TEST_NAME} + ${catkin_LIBRARIES} + ) + +add_dependencies(test_${TEST_NAME} + ${${PROJECT_NAME}_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} + ) + +add_rostest(${TEST_NAME}.test) diff --git a/test/uav_manager/landing/landing.test b/test/uav_manager/landing/landing.test new file mode 100644 index 00000000..604b7439 --- /dev/null +++ b/test/uav_manager/landing/landing.test @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/uav_manager/landing/landing_test.cpp b/test/uav_manager/landing/landing_test.cpp deleted file mode 100644 index 33c41f78..00000000 --- a/test/uav_manager/landing/landing_test.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_midair_; - - mrs_lib::ServiceClientHandler sch_land_; -}; - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_midair_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/midair_activation"); - - sch_land_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/uav_manager/land"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the edrone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- midair activation ------------------- | - - ROS_INFO("[%s]: activating the drone 'in mid air'", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_midair_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: midair activation service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- sleep before the action ---------------- | - - ros::Duration(1.0).sleep(); - - // | ---------------------- call landing ---------------------- | - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_land_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: land service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | ----------------- wait for LandoffTracker ---------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for LandoffTracker", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->active_tracker == "LandoffTracker") { - ROS_INFO("[%s]: LandoffTracker detected", ros::this_node::getName().c_str()); - break; - } - } - - // | -------------------- wait for landing -------------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for landing", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->output_enabled == false) { - ROS_INFO("[%s]: landing detected", ros::this_node::getName().c_str()); - return true; - } - } - - return false; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, landing) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "landing_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/uav_manager/landing/test.cpp b/test/uav_manager/landing/test.cpp new file mode 100644 index 00000000..ccc13a57 --- /dev/null +++ b/test/uav_manager/landing/test.cpp @@ -0,0 +1,100 @@ +#include + +#include + +#include + +#define POS_JUMP_SIZE 3.0 + +class Tester : public mrs_uav_testing::TestGeneric { + +public: + bool test(); + + Tester(); + + mrs_lib::ServiceClientHandler sch_land_; +}; + +Tester::Tester() : mrs_uav_testing::TestGeneric() { + + sch_land_ = mrs_lib::ServiceClientHandler(nh_, "/" + _uav_name_ + "/uav_manager/land"); +} + +bool Tester::test() { + + { + auto [success, message] = activateMidAir(); + + if (!success) { + ROS_ERROR("[%s]: midair activation failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + } + + sleep(1.0); + + // | -------------- wait for the eland to trigger ------------- | + + { + std_srvs::Trigger srv; + + { + bool service_call = sch_land_.call(srv); + + if (!service_call || !srv.response.success) { + ROS_ERROR("[%s]: land service call failed", ros::this_node::getName().c_str()); + return false; + } + } + } + + sleep(0.5); + + // | -------------------- wait for landing -------------------- | + + while (true) { + + if (!ros::ok()) { + return false; + } + + if (!isOutputEnabled()) { + + return true; + + } else { + + // TODO this is not the right way to check if the landing actually happens as planned + if (getActiveTracker() != "LandoffTracker" && getActiveTracker() != "NullTracker") { + ROS_ERROR("[%s]: not landing anymore", ros::this_node::getName().c_str()); + return false; + } + } + } + + return false; +} + + +TEST(TESTSuite, test) { + + Tester tester; + + bool result = tester.test(); + + if (result) { + GTEST_SUCCEED(); + } else { + GTEST_FAIL(); + } +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { + + ros::init(argc, argv, "test"); + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/uav_manager/landing/uav_manager_landing.test b/test/uav_manager/landing/uav_manager_landing.test deleted file mode 100644 index 34ed5bfd..00000000 --- a/test/uav_manager/landing/uav_manager_landing.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/test/uav_manager/takeoff/CMakeLists.txt b/test/uav_manager/takeoff/CMakeLists.txt new file mode 100644 index 00000000..bf8f9853 --- /dev/null +++ b/test/uav_manager/takeoff/CMakeLists.txt @@ -0,0 +1,16 @@ +get_filename_component(TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME) + +catkin_add_executable_with_gtest(test_${TEST_NAME} + test.cpp + ) + +target_link_libraries(test_${TEST_NAME} + ${catkin_LIBRARIES} + ) + +add_dependencies(test_${TEST_NAME} + ${${PROJECT_NAME}_EXPORTED_TARGETS} + ${catkin_EXPORTED_TARGETS} + ) + +add_rostest(${TEST_NAME}.test) diff --git a/test/uav_manager/takeoff/config/custom_config.yaml b/test/uav_manager/takeoff/config/custom_config.yaml deleted file mode 100644 index 9f6bbb87..00000000 --- a/test/uav_manager/takeoff/config/custom_config.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# GET ALL PARAMETERS USABLE FOR CUSTOM CONFIG BY RUNNING: -## -------------------------------------------------------------- -## | rosrun mrs_uav_core get_public_params.py # -## -------------------------------------------------------------- - -mrs_uav_managers: - - estimation_manager: - - # loaded state estimator plugins - state_estimators: [ - "gps_baro", - ] - - initial_state_estimator: "gps_baro" # will be used as the first state estimator - agl_height_estimator: "garmin_agl" # only slightly filtered height for checking min height (not used in control feedback) diff --git a/test/uav_manager/takeoff/config/mrs_simulator.yaml b/test/uav_manager/takeoff/config/mrs_simulator.yaml new file mode 100644 index 00000000..7704c54b --- /dev/null +++ b/test/uav_manager/takeoff/config/mrs_simulator.yaml @@ -0,0 +1,3 @@ +# turning off for the takeoff test +individual_takeoff_platform: + enabled: false diff --git a/test/uav_manager/takeoff/config/network_config.yaml b/test/uav_manager/takeoff/config/network_config.yaml deleted file mode 100644 index 08f370d6..00000000 --- a/test/uav_manager/takeoff/config/network_config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# 1. This list is used by NimbroNetwork for mutual communication of the UAVs -# The names of the robots have to match hostnames described in /etc/hosts. -# -# 2. This list is used by MpcTracker for mutual collision avoidance of the UAVs. -# The names should match the true "UAV_NAMES" (the topic prefixes). -# -# network_config:=~/config/network_config.yaml -# -# to the core.launch and nimbro.launch. - -network: - - robot_names: [ - uav1, - ] diff --git a/test/uav_manager/takeoff/config/simulator.yaml b/test/uav_manager/takeoff/config/simulator.yaml deleted file mode 100644 index c8f10602..00000000 --- a/test/uav_manager/takeoff/config/simulator.yaml +++ /dev/null @@ -1,20 +0,0 @@ -simulation_rate: 250.0 -clock_rate: 250.0 -realtime_factor: 1.0 - -iterate_without_input: true - -individual_takeoff_platform: - enabled: false - -uav_names: [ - "uav1", -] - -uav1: - type: "x500" - spawn: - x: 10.0 - y: 15.0 - z: 2.0 - heading: 0 diff --git a/test/uav_manager/takeoff/config/world_config.yaml b/test/uav_manager/takeoff/config/world_config.yaml deleted file mode 100644 index 9b550677..00000000 --- a/test/uav_manager/takeoff/config/world_config.yaml +++ /dev/null @@ -1,34 +0,0 @@ -world_origin: - - units: "LATLON" # {"UTM, "LATLON"} - - origin_x: 47.397743 - origin_y: 8.545594 - -safety_area: - - enabled: true - - horizontal: - - # the frame of reference in which the points are expressed - frame_name: "world_origin" - - # polygon - # - # x, y [m] for any frame_name except latlon_origin - # x = latitude, y = longitude [deg] for frame_name=="latlon_origin" - points: [ - -50, -50, - 50, -50, - 50, 50, - -50, 50, - ] - - vertical: - - # the frame of reference in which the max&min z is expressed - frame_name: "world_origin" - - max_z: 15.0 - min_z: 0.5 diff --git a/test/uav_manager/takeoff/launch/mrs_uav_system.launch b/test/uav_manager/takeoff/launch/mrs_uav_system.launch deleted file mode 100644 index 4f0adef8..00000000 --- a/test/uav_manager/takeoff/launch/mrs_uav_system.launch +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/uav_manager/takeoff/takeoff.test b/test/uav_manager/takeoff/takeoff.test new file mode 100644 index 00000000..4d31f7f3 --- /dev/null +++ b/test/uav_manager/takeoff/takeoff.test @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/uav_manager/takeoff/takeoff_test.cpp b/test/uav_manager/takeoff/takeoff_test.cpp deleted file mode 100644 index 5b740db4..00000000 --- a/test/uav_manager/takeoff/takeoff_test.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include - -/* class Tester //{ */ - -class Tester { - -public: - Tester(); - - bool test(); - -private: - ros::NodeHandle nh_; - std::shared_ptr spinner_; - - mrs_lib::SubscribeHandler sh_control_manager_diag_; - mrs_lib::SubscribeHandler sh_estim_manager_diag_; - mrs_lib::SubscribeHandler sh_can_takeoff; - - mrs_lib::ServiceClientHandler sch_arming_; - mrs_lib::ServiceClientHandler sch_offboard_; - - mrs_lib::ServiceClientHandler sch_land_; -}; - -//} - -/* Tester() //{ */ - -Tester::Tester() { - - // | ------------------ initialize test node ------------------ | - - nh_ = ros::NodeHandle("~"); - - ROS_INFO("[%s]: ROS node initialized", ros::this_node::getName().c_str()); - - ros::Time::waitForValid(); - - spinner_ = std::make_shared(4); - spinner_->start(); - - std::string uav_name = "uav1"; - - // | ----------------------- subscribers ---------------------- | - - mrs_lib::SubscribeHandlerOptions shopts; - shopts.nh = nh_; - shopts.node_name = "Test"; - shopts.no_message_timeout = mrs_lib::no_timeout; - shopts.threadsafe = true; - shopts.autostart = true; - shopts.queue_size = 10; - shopts.transport_hints = ros::TransportHints().tcpNoDelay(); - - sh_control_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/control_manager/diagnostics"); - sh_estim_manager_diag_ = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/estimation_manager/diagnostics"); - sh_can_takeoff = mrs_lib::SubscribeHandler(shopts, "/" + uav_name + "/automatic_start/can_takeoff"); - - ROS_INFO("[%s]: subscribers initialized", ros::this_node::getName().c_str()); - - // | --------------------- service clients -------------------- | - - sch_arming_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/arming"); - sch_offboard_ = mrs_lib::ServiceClientHandler(nh_, "/" + uav_name + "/hw_api/offboard"); - - ROS_INFO("[%s]: service client initialized", ros::this_node::getName().c_str()); -} - -//} - -/* test() //{ */ - -bool Tester::test() { - - // | ---------------- wait for ready to takeoff --------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the MRS UAV System", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.hasMsg() && sh_estim_manager_diag_.hasMsg()) { - break; - } - - ros::Duration(0.01).sleep(); - } - - ROS_INFO("[%s]: MRS UAV System is ready", ros::this_node::getName().c_str()); - - ros::Duration(1.0).sleep(); - - // | ---------------------- arm the drone --------------------- | - - ROS_INFO("[%s]: arming the edrone", ros::this_node::getName().c_str()); - - { - std_srvs::SetBool arming; - arming.request.data = true; - - { - bool service_call = sch_arming_.call(arming); - - if (!service_call || !arming.response.success) { - ROS_ERROR("[%s]: arming service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------------------- wait -------------------------- | - - ros::Duration(0.2).sleep(); - - // | -------------------- trigger offboard -------------------- | - - ROS_INFO("[%s]: triggering offboard", ros::this_node::getName().c_str()); - - { - std_srvs::Trigger trigger; - - { - bool service_call = sch_offboard_.call(trigger); - - if (!service_call || !trigger.response.success) { - ROS_ERROR("[%s]: offboard service call failed", ros::this_node::getName().c_str()); - return false; - } - } - } - - // | -------------- wait for the takeoff finished ------------- | - - while (ros::ok()) { - - ROS_INFO_THROTTLE(1.0, "[%s]: waiting for the takeoff to finish", ros::this_node::getName().c_str()); - - if (sh_control_manager_diag_.getMsg()->flying_normally) { - - ROS_INFO("[%s]: finished", ros::this_node::getName().c_str()); - - return true; - } - - ros::Duration(0.01).sleep(); - } - - return false; -} - -//} - -std::shared_ptr tester_; - -TEST(TESTSuite, takeoff) { - - bool result = tester_->test(); - - if (result) { - GTEST_SUCCEED(); - } else { - GTEST_FAIL(); - } -} - -int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { - - ros::init(argc, argv, "takeoff_test"); - - tester_ = std::make_shared(); - - testing::InitGoogleTest(&argc, argv); - - Tester tester; - - return RUN_ALL_TESTS(); -} diff --git a/test/uav_manager/takeoff/test.cpp b/test/uav_manager/takeoff/test.cpp new file mode 100644 index 00000000..13b85997 --- /dev/null +++ b/test/uav_manager/takeoff/test.cpp @@ -0,0 +1,51 @@ +#include + +#include + +class Tester : public mrs_uav_testing::TestGeneric { + +public: + bool test(); +}; + +bool Tester::test() { + + auto [success, message] = takeoff(); + + if (!success) { + ROS_ERROR("[%s]: takeoff failed with message: '%s'", ros::this_node::getName().c_str(), message.c_str()); + return false; + } + + this->sleep(5.0); + + if (this->isFlyingNormally()) { + return true; + } else { + ROS_ERROR("[%s]: not flying normally", ros::this_node::getName().c_str()); + return false; + } +} + + +TEST(TESTSuite, test) { + + Tester tester; + + bool result = tester.test(); + + if (result) { + GTEST_SUCCEED(); + } else { + GTEST_FAIL(); + } +} + +int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) { + + ros::init(argc, argv, "test"); + + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} diff --git a/test/uav_manager/takeoff/uav_manager_takeoff.test b/test/uav_manager/takeoff/uav_manager_takeoff.test deleted file mode 100644 index 3d55db90..00000000 --- a/test/uav_manager/takeoff/uav_manager_takeoff.test +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - From 098f90915439de19ab6d5339004d05d1f967130c Mon Sep 17 00:00:00 2001 From: Tomas Baca Date: Wed, 13 Dec 2023 07:59:49 +0100 Subject: [PATCH 6/6] updated tests --- test/control_manager/eland_innovation/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/control_manager/eland_innovation/test.cpp b/test/control_manager/eland_innovation/test.cpp index 940caecb..41af3c13 100644 --- a/test/control_manager/eland_innovation/test.cpp +++ b/test/control_manager/eland_innovation/test.cpp @@ -4,7 +4,7 @@ #include -#define POS_JUMP_SIZE 3.0 +#define POS_JUMP_SIZE 4.0 class Tester : public mrs_uav_testing::TestGeneric {