66
77namespace ur_controllers
88{
9- ForceTorqueStateController::ForceTorqueStateController () : controller_interface::ControllerInterface()
9+ ForceTorqueStateController::ForceTorqueStateController ()
10+ : controller_interface::ControllerInterface(), wrench_state_publisher_(nullptr )
1011{
1112}
1213
@@ -18,6 +19,20 @@ controller_interface::return_type ForceTorqueStateController::init(const std::st
1819 return ret;
1920 }
2021
22+ try
23+ {
24+ auto node = get_node ();
25+ node->declare_parameter <std::vector<std::string>>(" state_interface_names" , {});
26+ node->declare_parameter <std::string>(" sensor_name" , " " );
27+ node->declare_parameter <std::string>(" topic_name" , " " );
28+ node->declare_parameter <std::string>(" frame_id" , " " );
29+ }
30+ catch (const std::exception& e)
31+ {
32+ fprintf (stderr, " Exception thrown during init stage with message: %s \n " , e.what ());
33+ return controller_interface::return_type::ERROR;
34+ }
35+
2136 return controller_interface::return_type::SUCCESS;
2237}
2338
@@ -32,13 +47,11 @@ controller_interface::InterfaceConfiguration ForceTorqueStateController::state_i
3247{
3348 controller_interface::InterfaceConfiguration config;
3449 config.type = controller_interface::interface_configuration_type::INDIVIDUAL;
35- // TODO solve this hardcoded naming
36- config.names .emplace_back (" tcp_fts_sensor/fx" );
37- config.names .emplace_back (" tcp_fts_sensor/fy" );
38- config.names .emplace_back (" tcp_fts_sensor/fz" );
39- config.names .emplace_back (" tcp_fts_sensor/tx" );
40- config.names .emplace_back (" tcp_fts_sensor/ty" );
41- config.names .emplace_back (" tcp_fts_sensor/tz" );
50+ for (const auto & si : fts_params_.state_interfaces_names_ )
51+ {
52+ config.names .push_back (fts_params_.sensor_name_ + " /" + si);
53+ }
54+
4255 return config;
4356}
4457
@@ -47,49 +60,38 @@ controller_interface::return_type ur_controllers::ForceTorqueStateController::up
4760 geometry_msgs::msg::Vector3 fVec ;
4861 geometry_msgs::msg::Vector3 tVec;
4962
50- // TODO remove these hardcoded names and create better string filtering within state_interfaces_
51- for (const auto & state_interface : state_interfaces_)
52- {
53- if (state_interface.get_interface_name () == " fx" )
54- {
55- fVec .set__x (state_interface.get_value ());
56- continue ;
57- }
58-
59- if (state_interface.get_interface_name () == " fy" )
60- {
61- fVec .set__y (state_interface.get_value ());
62- continue ;
63- }
63+ if (state_interfaces_.size () != fts_params_.state_interfaces_names_ .size ())
64+ return controller_interface::return_type::ERROR;
6465
65- if (state_interface.get_interface_name () == " fz" )
66- {
67- fVec .set__z (state_interface.get_value ());
68- continue ;
69- }
70-
71- if (state_interface.get_interface_name () == " tx" )
72- {
73- tVec.set__x (state_interface.get_value ());
74- continue ;
75- }
76-
77- if (state_interface.get_interface_name () == " ty" )
78- {
79- tVec.set__y (state_interface.get_value ());
80- continue ;
81- }
82-
83- if (state_interface.get_interface_name () == " tz" )
66+ for (auto index = 0ul ; index < state_interfaces_.size (); ++index)
67+ {
68+ switch (index)
8469 {
85- tVec.set__z (state_interface.get_value ());
86- continue ;
70+ case 0 :
71+ fVec .set__x (state_interfaces_[index].get_value ());
72+ break ;
73+ case 1 :
74+ fVec .set__y (state_interfaces_[index].get_value ());
75+ break ;
76+ case 2 :
77+ fVec .set__z (state_interfaces_[index].get_value ());
78+ break ;
79+ case 3 :
80+ tVec.set__x (state_interfaces_[index].get_value ());
81+ break ;
82+ case 4 :
83+ tVec.set__y (state_interfaces_[index].get_value ());
84+ break ;
85+ case 5 :
86+ tVec.set__z (state_interfaces_[index].get_value ());
87+ break ;
88+ default :
89+ break ;
8790 }
8891 }
8992
90- // TODO set frame_id as parameter --> it includes tf listener within controller
9193 wrench_state_msg_.header .stamp = get_node ()->get_clock ()->now ();
92- wrench_state_msg_.header .frame_id = " tool0 " ;
94+ wrench_state_msg_.header .frame_id = fts_params_. frame_id ;
9395
9496 // update wrench state message
9597 wrench_state_msg_.wrench .set__force (fVec );
@@ -104,29 +106,52 @@ controller_interface::return_type ur_controllers::ForceTorqueStateController::up
104106rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
105107ForceTorqueStateController::on_configure (const rclcpp_lifecycle::State& /* previous_state*/ )
106108{
109+ fts_params_.state_interfaces_names_ = node_->get_parameter (" state_interface_names" ).as_string_array ();
110+
111+ if (fts_params_.state_interfaces_names_ .empty ())
112+ {
113+ RCLCPP_ERROR (get_node ()->get_logger (), " 'state_interface_names' parameter was empty" );
114+ return CallbackReturn::ERROR;
115+ }
116+
117+ fts_params_.sensor_name_ = node_->get_parameter (" sensor_name" ).as_string ();
118+ if (fts_params_.sensor_name_ .empty ())
119+ {
120+ RCLCPP_ERROR (get_node ()->get_logger (), " 'sensor_name' parameter was empty" );
121+ return CallbackReturn::ERROR;
122+ }
123+
124+ fts_params_.topic_name = node_->get_parameter (" topic_name" ).as_string ();
125+ if (fts_params_.topic_name .empty ())
126+ {
127+ RCLCPP_ERROR (get_node ()->get_logger (), " 'topic_name' parameter was empty" );
128+ return CallbackReturn::ERROR;
129+ }
130+
131+ fts_params_.frame_id = node_->get_parameter (" frame_id" ).as_string ();
132+ if (fts_params_.frame_id .empty ())
133+ {
134+ RCLCPP_ERROR (get_node ()->get_logger (), " 'frame_id' parameter was empty" );
135+ return CallbackReturn::ERROR;
136+ }
137+
107138 try
108139 {
109- // TODO make topic name a parameter
110- wrench_state_publisher_ =
111- get_node ()-> create_publisher <geometry_msgs::msg::WrenchStamped>( " ft_data " , rclcpp::SystemDefaultsQoS ());
140+ // register ft sensor data publisher
141+ wrench_state_publisher_ = get_node ()-> create_publisher <geometry_msgs::msg::WrenchStamped>(
142+ fts_params_. topic_name , rclcpp::SystemDefaultsQoS ());
112143 }
113144 catch (...)
114145 {
115146 return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
116147 }
148+
117149 return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
118150}
119151
120152rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn
121153ForceTorqueStateController::on_activate (const rclcpp_lifecycle::State& /* previous_state*/ )
122154{
123- if (!init_sensor_data ())
124- {
125- return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR;
126- }
127-
128- init_sensor_state_msg ();
129-
130155 return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
131156}
132157
@@ -136,43 +161,6 @@ ForceTorqueStateController::on_deactivate(const rclcpp_lifecycle::State& /*previ
136161 return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::SUCCESS;
137162}
138163
139- template <typename T>
140- bool has_any_key (const std::unordered_map<std::string, T>& map, const std::vector<std::string>& keys)
141- {
142- bool found_key = false ;
143- for (const auto & key_item : map)
144- {
145- const auto & key = key_item.first ;
146- if (std::find (keys.cbegin (), keys.cend (), key) != keys.cend ())
147- {
148- found_key = true ;
149- break ;
150- }
151- }
152- return found_key;
153- }
154-
155- bool ForceTorqueStateController::init_sensor_data ()
156- {
157- bool has_fts_sensor = false ;
158- // loop in reverse order, this maintains the order of values at retrieval time
159- for (auto si = state_interfaces_.crbegin (); si != state_interfaces_.crend (); si++)
160- {
161- // TODO remove hardcoded naming
162- if (si->get_name () == " tcp_fts_sensor" )
163- {
164- has_fts_sensor = true ;
165- axis_val_names_.push_back (si->get_interface_name ());
166- }
167- }
168- return has_fts_sensor;
169- }
170-
171- void ForceTorqueStateController::init_sensor_state_msg ()
172- {
173- // default initialization for wrenchstamped state message
174- }
175-
176164} // namespace ur_controllers
177165
178166#include " pluginlib/class_list_macros.hpp"
0 commit comments