diff --git a/test/control_manager/CMakeLists.txt b/test/control_manager/CMakeLists.txt
index 17b34a5..cfcfeef 100644
--- a/test/control_manager/CMakeLists.txt
+++ b/test/control_manager/CMakeLists.txt
@@ -5,3 +5,5 @@ add_subdirectory(eland_control_error)
add_subdirectory(eland_innovation)
add_subdirectory(failsafe_control_error)
+
+add_subdirectory(eland_service)
diff --git a/test/control_manager/eland_service/CMakeLists.txt b/test/control_manager/eland_service/CMakeLists.txt
new file mode 100644
index 0000000..bf8f985
--- /dev/null
+++ b/test/control_manager/eland_service/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_service/eland_service.test b/test/control_manager/eland_service/eland_service.test
new file mode 100644
index 0000000..604b743
--- /dev/null
+++ b/test/control_manager/eland_service/eland_service.test
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/control_manager/eland_service/test.cpp b/test/control_manager/eland_service/test.cpp
new file mode 100644
index 0000000..9baa23f
--- /dev/null
+++ b/test/control_manager/eland_service/test.cpp
@@ -0,0 +1,119 @@
+#include
+
+#include
+
+/* class Tester //{ */
+
+class Tester : public mrs_uav_testing::TestGeneric {
+
+public:
+ bool test();
+
+ Tester();
+
+ mrs_lib::ServiceClientHandler sch_eland_;
+
+ std::tuple eland();
+};
+
+Tester::Tester() {
+
+ sch_eland_ = mrs_lib::ServiceClientHandler(nh_, "/" + _uav_name_ + "/control_manager/eland");
+}
+
+std::tuple Tester::eland() {
+
+ {
+ std_srvs::Trigger srv;
+
+ {
+ bool service_call = sch_eland_.call(srv);
+
+ if (!service_call || !srv.response.success) {
+ return {false, "offboard service call failed"};
+ }
+ }
+ }
+
+ return {true, "service called"};
+}
+
+//}
+
+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;
+ }
+ }
+
+ // | ---------------------- trigger eland --------------------- |
+
+ {
+ auto [success, message] = eland();
+
+ if (!success) {
+ ROS_ERROR("[%s]: eland call failed with message: '%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;
+ }
+
+ sleep(0.01);
+ }
+
+ // | -------------------- wait for landing -------------------- |
+
+ while (true) {
+
+ if (!ros::ok()) {
+ return false;
+ }
+
+ if (!this->isOutputEnabled()) {
+ return true;
+ }
+
+ sleep(0.01);
+ }
+
+ 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();
+}