@@ -866,21 +866,51 @@ hardware_interface::return_type URPositionHardwareInterface::prepare_command_mod
866866 const std::vector<std::string>& start_interfaces, const std::vector<std::string>& stop_interfaces)
867867{
868868 hardware_interface::return_type ret_val = hardware_interface::return_type::OK;
869- start_modes_.clear ();
869+
870+ start_modes_ = std::vector<std::string>(info_.joints .size (), " UNDEFINED" );
870871 stop_modes_.clear ();
872+ std::vector<std::string> control_modes (info_.joints .size ());
871873 const std::string tf_prefix = info_.hardware_parameters .at (" tf_prefix" );
874+
875+ // Assess current state
876+ for (auto i = 0u ; i < info_.joints .size (); i++) {
877+ if (position_controller_running_) {
878+ control_modes[i] = hardware_interface::HW_IF_POSITION;
879+ }
880+ if (velocity_controller_running_) {
881+ control_modes[i] = hardware_interface::HW_IF_VELOCITY;
882+ }
883+ if (passthrough_trajectory_controller_running_) {
884+ control_modes[i] = PASSTHROUGH_GPIO;
885+ }
886+ }
887+
888+ if (!std::all_of (start_modes_.begin () + 1 , start_modes_.end (),
889+ [&](const std::string& other) { return other == start_modes_[0 ]; })) {
890+ RCLCPP_ERROR (get_logger (), " Start modes of all joints have to be the same." );
891+ return hardware_interface::return_type::ERROR;
892+ }
893+
872894 // Starting interfaces
873- // add start interface per joint in tmp var for later check
895+ // If a joint has been reserved already, raise an error.
896+ // Modes that are not directly mapped to a single joint such as force_mode reserve all joints.
874897 for (const auto & key : start_interfaces) {
875898 for (auto i = 0u ; i < info_.joints .size (); i++) {
876899 if (key == info_.joints [i].name + " /" + hardware_interface::HW_IF_POSITION) {
877- start_modes_.push_back (hardware_interface::HW_IF_POSITION);
878- }
879- if (key == info_.joints [i].name + " /" + hardware_interface::HW_IF_VELOCITY) {
880- start_modes_.push_back (hardware_interface::HW_IF_VELOCITY);
881- }
882- if (key == tf_prefix + PASSTHROUGH_GPIO + " /setpoint_positions_" + std::to_string (i)) {
883- start_modes_.push_back (PASSTHROUGH_GPIO);
900+ if (start_modes_[i] != " UNDEFINED" ) {
901+ return hardware_interface::return_type::ERROR;
902+ }
903+ start_modes_[i] = hardware_interface::HW_IF_POSITION;
904+ } else if (key == info_.joints [i].name + " /" + hardware_interface::HW_IF_VELOCITY) {
905+ if (start_modes_[i] != " UNDEFINED" ) {
906+ return hardware_interface::return_type::ERROR;
907+ }
908+ start_modes_[i] = hardware_interface::HW_IF_VELOCITY;
909+ } else if (key == tf_prefix + PASSTHROUGH_GPIO + " /setpoint_positions_" + std::to_string (i)) {
910+ if (start_modes_[i] != " UNDEFINED" ) {
911+ return hardware_interface::return_type::ERROR;
912+ }
913+ start_modes_[i] = PASSTHROUGH_GPIO;
884914 }
885915 }
886916 }
@@ -891,65 +921,55 @@ hardware_interface::return_type URPositionHardwareInterface::prepare_command_mod
891921 for (auto i = 0u ; i < info_.joints .size (); i++) {
892922 if (key == info_.joints [i].name + " /" + hardware_interface::HW_IF_POSITION) {
893923 stop_modes_.push_back (StoppingInterface::STOP_POSITION);
924+ if (control_modes[i] == hardware_interface::HW_IF_POSITION) {
925+ control_modes[i] = " UNDEFINED" ;
926+ }
894927 }
895928 if (key == info_.joints [i].name + " /" + hardware_interface::HW_IF_VELOCITY) {
896929 stop_modes_.push_back (StoppingInterface::STOP_VELOCITY);
930+ if (control_modes[i] == hardware_interface::HW_IF_VELOCITY) {
931+ control_modes[i] = " UNDEFINED" ;
932+ }
897933 }
898934 if (key == tf_prefix + PASSTHROUGH_GPIO + " /setpoint_positions_" + std::to_string (i)) {
899935 stop_modes_.push_back (StoppingInterface::STOP_PASSTHROUGH);
936+ if (control_modes[i] == PASSTHROUGH_GPIO) {
937+ control_modes[i] = " UNDEFINED" ;
938+ }
900939 }
901940 }
902941 }
903942
904- // set new mode to all interfaces at the same time
905- if (start_modes_.size () != 0 && start_modes_.size () != 6 ) {
906- RCLCPP_ERROR (get_logger (), " Either none or all joint interfaces must be started at once." );
943+ // Do not start conflicting controllers
944+ if (std::any_of (start_modes_.begin (), start_modes_.end (),
945+ [this ](auto & item) { return (item == PASSTHROUGH_GPIO); }) &&
946+ (std::any_of (start_modes_.begin (), start_modes_.end (),
947+ [](auto & item) {
948+ return (item == hardware_interface::HW_IF_VELOCITY || item == hardware_interface::HW_IF_POSITION);
949+ }) ||
950+ std::any_of (control_modes.begin (), control_modes.end (), [this ](auto & item) {
951+ return (item == hardware_interface::HW_IF_VELOCITY || item == hardware_interface::HW_IF_POSITION ||
952+ item == PASSTHROUGH_GPIO);
953+ }))) {
907954 ret_val = hardware_interface::return_type::ERROR;
908955 }
909-
910- if (position_controller_running_ &&
911- std::none_of (stop_modes_. begin (), stop_modes_. end (),
912- []( auto item) { return item == StoppingInterface::STOP_POSITION; }) &&
913- std::any_of (start_modes_. begin (), start_modes_. end (), [this ](auto & item) {
914- return (item == hardware_interface::HW_IF_VELOCITY || item == PASSTHROUGH_GPIO);
915- })) {
916- RCLCPP_ERROR ( get_logger (), " Start of velocity or passthrough interface requested while there is the position "
917- " interface running. " );
956+ if ( std::any_of (start_modes_. begin (), start_modes_. end (),
957+ []( auto & item) { return (item == hardware_interface::HW_IF_POSITION); }) &&
958+ ( std::any_of (
959+ start_modes_. begin (), start_modes_. end (),
960+ [this ](auto & item) { return (item == hardware_interface::HW_IF_VELOCITY || item == PASSTHROUGH_GPIO); }) ||
961+ std::any_of (control_modes. begin (), control_modes. end (), [ this ]( auto & item) {
962+ return (item == hardware_interface::HW_IF_VELOCITY || item == hardware_interface::HW_IF_POSITION ||
963+ item == PASSTHROUGH_GPIO);
964+ }))) {
918965 ret_val = hardware_interface::return_type::ERROR;
919966 }
920-
921- if (velocity_controller_running_ &&
922- std::none_of (stop_modes_.begin (), stop_modes_.end (),
923- [](auto item) { return item == StoppingInterface::STOP_VELOCITY; }) &&
967+ if (std::any_of (start_modes_.begin (), start_modes_.end (),
968+ [](auto & item) { return (item == hardware_interface::HW_IF_VELOCITY); }) &&
924969 std::any_of (start_modes_.begin (), start_modes_.end (), [this ](auto & item) {
925- return (item == hardware_interface::HW_IF_POSITION || item == PASSTHROUGH_GPIO);
926- })) {
927- RCLCPP_ERROR (get_logger (), " Start of position or passthrough interface requested while there is the velocity "
928- " interface running." );
929- ret_val = hardware_interface::return_type::ERROR;
930- }
931-
932- if (passthrough_trajectory_controller_running_ &&
933- std::none_of (stop_modes_.begin (), stop_modes_.end (),
934- [](auto item) { return item == StoppingInterface::STOP_PASSTHROUGH; }) &&
935- std::any_of (start_modes_.begin (), start_modes_.end (), [](auto & item) {
936- return (item == hardware_interface::HW_IF_VELOCITY || item == hardware_interface::HW_IF_POSITION);
970+ return (item == hardware_interface::HW_IF_VELOCITY || item == hardware_interface::HW_IF_POSITION ||
971+ item == PASSTHROUGH_GPIO);
937972 })) {
938- RCLCPP_ERROR (get_logger (), " Start of position or velocity interface requested while there is the passthrough "
939- " interface running." );
940- ret_val = hardware_interface::return_type::ERROR;
941- }
942-
943- // all start interfaces must be the same - can't mix position and velocity control
944- if (start_modes_.size () != 0 && !std::equal (start_modes_.begin () + 1 , start_modes_.end (), start_modes_.begin ())) {
945- RCLCPP_ERROR (get_logger (), " Can't mix different control domains for joint control." );
946- ret_val = hardware_interface::return_type::ERROR;
947- }
948-
949- // stop all interfaces at the same time
950- if (stop_modes_.size () != 0 &&
951- (stop_modes_.size () != 6 || !std::equal (stop_modes_.begin () + 1 , stop_modes_.end (), stop_modes_.begin ()))) {
952- RCLCPP_ERROR (get_logger (), " Either none or all joint interfaces must be stopped at once." );
953973 ret_val = hardware_interface::return_type::ERROR;
954974 }
955975
0 commit comments