@@ -2551,3 +2551,130 @@ TEST_F(TestControllerManagerSrvs, switch_controller_controllers_taking_long_time
25512551 EXPECT_EQ (old_counter_2 + 1 , test_controller_2->internal_counter );
25522552 EXPECT_EQ (old_counter_3 + 1 , test_controller_3->internal_counter );
25532553}
2554+
2555+ TEST_F (TestControllerManagerSrvs, switch_controller_test_two_controllers_using_same_interface)
2556+ {
2557+ // create server client and request
2558+ rclcpp::executors::SingleThreadedExecutor srv_executor;
2559+ rclcpp::Node::SharedPtr srv_node = std::make_shared<rclcpp::Node>(" srv_client" );
2560+ srv_executor.add_node (srv_node);
2561+ rclcpp::Client<ListControllers>::SharedPtr client =
2562+ srv_node->create_client <ListControllers>(" test_controller_manager/list_controllers" );
2563+ auto request = std::make_shared<ListControllers::Request>();
2564+
2565+ // create set of controllers
2566+ static constexpr char TEST_CONTROLLER_1[] = " test_controller_1" ;
2567+ static constexpr char TEST_CONTROLLER_2[] = " test_controller_2" ;
2568+
2569+ // create non-chained controller
2570+ auto test_controller_1 = std::make_shared<TestController>();
2571+ controller_interface::InterfaceConfiguration cmd_cfg = {
2572+ controller_interface::interface_configuration_type::INDIVIDUAL,
2573+ {" joint1/position" , " joint1/max_velocity" }};
2574+ controller_interface::InterfaceConfiguration state_cfg = {
2575+ controller_interface::interface_configuration_type::INDIVIDUAL,
2576+ {" joint1/position" , " joint1/velocity" }};
2577+ test_controller_1->set_command_interface_configuration (cmd_cfg);
2578+ test_controller_1->set_state_interface_configuration (state_cfg);
2579+
2580+ auto test_controller_2 = std::make_shared<TestController>();
2581+ cmd_cfg = {
2582+ controller_interface::interface_configuration_type::INDIVIDUAL,
2583+ {" joint1/position" , " joint2/velocity" }};
2584+ state_cfg = {
2585+ controller_interface::interface_configuration_type::INDIVIDUAL,
2586+ {" joint1/position" , " joint2/velocity" }};
2587+ test_controller_2->set_command_interface_configuration (cmd_cfg);
2588+ test_controller_2->set_state_interface_configuration (state_cfg);
2589+
2590+ // add controllers
2591+ cm_->add_controller (
2592+ test_controller_1, TEST_CONTROLLER_1, test_controller::TEST_CONTROLLER_CLASS_NAME);
2593+ cm_->add_controller (
2594+ test_controller_2, TEST_CONTROLLER_2, test_controller::TEST_CONTROLLER_CLASS_NAME);
2595+
2596+ // get controller list before configure
2597+ auto result = call_service_and_wait (*client, request, srv_executor);
2598+ // check chainable controller
2599+ ASSERT_EQ (2u , result->controller .size ());
2600+ ASSERT_EQ (result->controller [0 ].name , TEST_CONTROLLER_1);
2601+ ASSERT_EQ (result->controller [1 ].name , TEST_CONTROLLER_2);
2602+
2603+ // configure controllers
2604+ for (const auto & controller : {TEST_CONTROLLER_1, TEST_CONTROLLER_2})
2605+ {
2606+ cm_->configure_controller (controller);
2607+ }
2608+
2609+ // get controller list after configure
2610+ result = call_service_and_wait (*client, request, srv_executor);
2611+ ASSERT_EQ (2u , result->controller .size ());
2612+
2613+ // reordered controllers
2614+ ASSERT_EQ (result->controller [0 ].name , TEST_CONTROLLER_2);
2615+ ASSERT_EQ (result->controller [1 ].name , TEST_CONTROLLER_1);
2616+
2617+ // Check individual activation and they should work fine
2618+ auto res = cm_->switch_controller (
2619+ {TEST_CONTROLLER_1}, {}, controller_manager_msgs::srv::SwitchController::Request::STRICT, true ,
2620+ rclcpp::Duration (0 , 0 ));
2621+ ASSERT_EQ (res, controller_interface::return_type::OK);
2622+
2623+ ASSERT_EQ (
2624+ lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE,
2625+ test_controller_1->get_lifecycle_state ().id ());
2626+ ASSERT_EQ (
2627+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2628+ test_controller_2->get_lifecycle_state ().id ());
2629+
2630+ res = cm_->switch_controller (
2631+ {}, {TEST_CONTROLLER_1}, controller_manager_msgs::srv::SwitchController::Request::STRICT, true ,
2632+ rclcpp::Duration (0 , 0 ));
2633+ ASSERT_EQ (res, controller_interface::return_type::OK);
2634+
2635+ ASSERT_EQ (
2636+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2637+ test_controller_1->get_lifecycle_state ().id ());
2638+ ASSERT_EQ (
2639+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2640+ test_controller_2->get_lifecycle_state ().id ());
2641+
2642+ // Now test activating controller_2
2643+ res = cm_->switch_controller (
2644+ {TEST_CONTROLLER_2}, {}, controller_manager_msgs::srv::SwitchController::Request::STRICT, true ,
2645+ rclcpp::Duration (0 , 0 ));
2646+ ASSERT_EQ (res, controller_interface::return_type::OK);
2647+
2648+ ASSERT_EQ (
2649+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2650+ test_controller_1->get_lifecycle_state ().id ());
2651+ ASSERT_EQ (
2652+ lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE,
2653+ test_controller_2->get_lifecycle_state ().id ());
2654+
2655+ res = cm_->switch_controller (
2656+ {}, {TEST_CONTROLLER_2}, controller_manager_msgs::srv::SwitchController::Request::STRICT, true ,
2657+ rclcpp::Duration (0 , 0 ));
2658+ ASSERT_EQ (res, controller_interface::return_type::OK);
2659+
2660+ ASSERT_EQ (
2661+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2662+ test_controller_1->get_lifecycle_state ().id ());
2663+ ASSERT_EQ (
2664+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2665+ test_controller_2->get_lifecycle_state ().id ());
2666+
2667+ // Now try activating both the controllers at once, it should fail as they are using same
2668+ // interface
2669+ res = cm_->switch_controller (
2670+ {TEST_CONTROLLER_1, TEST_CONTROLLER_2}, {},
2671+ controller_manager_msgs::srv::SwitchController::Request::STRICT, false , rclcpp::Duration (0 , 0 ));
2672+ ASSERT_EQ (res, controller_interface::return_type::ERROR);
2673+
2674+ ASSERT_EQ (
2675+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2676+ test_controller_1->get_lifecycle_state ().id ());
2677+ ASSERT_EQ (
2678+ lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE,
2679+ test_controller_2->get_lifecycle_state ().id ());
2680+ }
0 commit comments