@@ -92,82 +92,64 @@ hardware_interface::CallbackReturn VescHardware::on_init(
9292 const auto & joint = info_.joints [0 ];
9393
9494 // Initialize list of supported interfaces
95- state_interfaces_ = {{hardware_interface::HW_IF_POSITION , " position" , false },
96- {hardware_interface::HW_IF_VELOCITY , " velocity" , false },
97- {" servo" , " servo" , false }};
98-
99- command_interfaces_ = {
100- {hardware_interface::HW_IF_POSITION , " position" , false },
101- {hardware_interface::HW_IF_VELOCITY , " velocity" , false },
102- {" servo" , " servo" , false }};
95+ populate_state_definitions ();
96+ populate_command_definitions ();
10397
10498 // Check which state interfaces are requested
10599 for (const auto & state_interface : joint.state_interfaces ) {
106- bool found = false ;
107- for (auto & supported_interface : state_interfaces_) {
108- if (state_interface.name == supported_interface.name ) {
109- if (supported_interface.requested ) {
110- RCLCPP_FATAL (
111- get_logger (),
112- " Duplicate state interface '%s' requested for joint '%s'" ,
113- state_interface.name .c_str (), joint.name .c_str ());
114- return hardware_interface::CallbackReturn::ERROR ;
115- }
116- supported_interface.requested = true ;
117- found = true ;
118- RCLCPP_INFO (get_logger (), " State interface '%s' requested" ,
119- state_interface.name .c_str ());
120- break ;
121- }
122- }
123- if (!found) {
100+ auto it = state_interfaces_.find (state_interface.name );
101+ if (it == state_interfaces_.end ()) {
124102 RCLCPP_FATAL (get_logger (),
125103 " Unsupported state interface '%s' requested for joint '%s'" ,
126104 state_interface.name .c_str (), joint.name .c_str ());
127105 return hardware_interface::CallbackReturn::ERROR ;
128106 }
107+ if (it->second .requested ) {
108+ RCLCPP_FATAL (
109+ get_logger (),
110+ " Duplicate state interface '%s' requested for joint '%s'" ,
111+ state_interface.name .c_str (), joint.name .c_str ());
112+ return hardware_interface::CallbackReturn::ERROR ;
113+ }
114+ it->second .requested = true ;
115+ RCLCPP_INFO (get_logger (), " State interface '%s' requested" ,
116+ state_interface.name .c_str ());
129117 }
130118
131119 // Check which command interfaces are requested
132120 for (const auto & command_interface : joint.command_interfaces ) {
133- bool found = false ;
134- for (auto & supported_interface : command_interfaces_) {
135- if (command_interface.name == supported_interface.name ) {
136- if (supported_interface.requested ) {
137- RCLCPP_FATAL (
138- get_logger (),
139- " Duplicate command interface '%s' requested for joint '%s'" ,
140- command_interface.name .c_str (), joint.name .c_str ());
141- return hardware_interface::CallbackReturn::ERROR ;
142- }
143- supported_interface.requested = true ;
144- found = true ;
145- RCLCPP_INFO (get_logger (), " Command interface '%s' requested" ,
146- command_interface.name .c_str ());
147- break ;
148- }
149- }
150- if (!found) {
121+ auto it = command_interfaces_.find (command_interface.name );
122+ if (it == command_interfaces_.end ()) {
151123 RCLCPP_FATAL (
152124 get_logger (),
153125 " Unsupported command interface '%s' requested for joint '%s'" ,
154126 command_interface.name .c_str (), joint.name .c_str ());
155127 return hardware_interface::CallbackReturn::ERROR ;
156128 }
129+ if (it->second .requested ) {
130+ RCLCPP_FATAL (
131+ get_logger (),
132+ " Duplicate command interface '%s' requested for joint '%s'" ,
133+ command_interface.name .c_str (), joint.name .c_str ());
134+ return hardware_interface::CallbackReturn::ERROR ;
135+ }
136+ it->second .requested = true ;
137+ RCLCPP_INFO (get_logger (), " Command interface '%s' requested" ,
138+ command_interface.name .c_str ());
157139 }
158140
159141 // Check that at least one interface is requested
160142 bool has_state_interface = false ;
161- for (const auto & iface : state_interfaces_) {
162- if (iface .requested ) {
143+ for (const auto & [name, data] : state_interfaces_) {
144+ if (data .requested ) {
163145 has_state_interface = true ;
164146 break ;
165147 }
166148 }
167149
168150 bool has_command_interface = false ;
169- for (const auto & iface : command_interfaces_) {
170- if (iface .requested ) {
151+ for (const auto & [name, data] : command_interfaces_) {
152+ if (data .requested ) {
171153 has_command_interface = true ;
172154 break ;
173155 }
@@ -186,8 +168,6 @@ hardware_interface::CallbackReturn VescHardware::on_init(
186168 // Initialize state and command storage
187169 hw_state_position_ = 0.0 ;
188170 hw_state_velocity_ = 0.0 ;
189- hw_command_position_ = 0.0 ;
190- hw_command_velocity_ = 0.0 ;
191171 hw_command_servo_ = 0.0 ;
192172
193173 return hardware_interface::CallbackReturn::SUCCESS ;
@@ -200,15 +180,15 @@ VescHardware::on_configure(const rclcpp_lifecycle::State & /*previous_state*/)
200180
201181 // Log which interfaces are active
202182 RCLCPP_INFO (get_logger (), " Active state interfaces:" );
203- for (const auto & iface : state_interfaces_) {
204- if (iface .requested ) {
205- RCLCPP_INFO (get_logger (), " - %s" , iface. type .c_str ());
183+ for (const auto & [name, data] : state_interfaces_) {
184+ if (data .requested ) {
185+ RCLCPP_INFO (get_logger (), " - %s" , name .c_str ());
206186 }
207187 }
208188 RCLCPP_INFO (get_logger (), " Active command interfaces:" );
209- for (const auto & iface : command_interfaces_) {
210- if (iface .requested ) {
211- RCLCPP_INFO (get_logger (), " - %s" , iface. type .c_str ());
189+ for (const auto & [name, data] : command_interfaces_) {
190+ if (data .requested ) {
191+ RCLCPP_INFO (get_logger (), " - %s" , name .c_str ());
212192 }
213193 }
214194
@@ -289,14 +269,9 @@ VescHardware::read(
289269 // (These are updated asynchronously by vescPacketCallback)
290270 for (const auto &[name, descr] : joint_state_interfaces_) {
291271 std::string interface_type = name.substr (name.find_last_of (" /" ) + 1 );
292-
293- if (interface_type == hardware_interface::HW_IF_POSITION ) {
294- set_state (name, hw_state_position_.load (std::memory_order_relaxed));
295- } else if (interface_type == hardware_interface::HW_IF_VELOCITY ) {
296- set_state (name, hw_state_velocity_.load (std::memory_order_relaxed));
297- } else if (interface_type == " servo" ) {
298- // Servo state mirrors command because the VESC cannot read servo position
299- set_state (name, hw_command_servo_);
272+ auto it = state_interfaces_.find (interface_type);
273+ if (it != state_interfaces_.end () && it->second .get_value ) {
274+ set_state (name, it->second .get_value ());
300275 }
301276 }
302277
@@ -317,22 +292,9 @@ VescHardware::write(
317292 for (const auto &[name, descr] : joint_command_interfaces_) {
318293 // Extract interface type from full name "motor_joint/velocity"
319294 std::string interface_type = name.substr (name.find_last_of (" /" ) + 1 );
320-
321- if (interface_type == hardware_interface::HW_IF_POSITION ) {
322- hw_command_position_ = get_command (name);
323- double vesc_position = convertMechanicalRadToDeg (hw_command_position_);
324- vesc_interface_->setPosition (vesc_position);
325- } else if (interface_type == hardware_interface::HW_IF_VELOCITY ) {
326- hw_command_velocity_ = get_command (name);
327- double vesc_erpm = convertMechanicalRadSecToERPM (hw_command_velocity_);
328- vesc_interface_->setSpeed (vesc_erpm);
329- } else if (interface_type == " servo" ) {
330- hw_command_servo_ = get_command (name);
331- vesc_interface_->setServo (hw_command_servo_);
332- } else {
333- RCLCPP_WARN_THROTTLE (get_logger (), *get_clock (), 1000 ,
334- " Unknown command interface type: %s" ,
335- interface_type.c_str ());
295+ auto it = command_interfaces_.find (interface_type);
296+ if (it != command_interfaces_.end () && it->second .set_command ) {
297+ it->second .set_command (get_command (name));
336298 }
337299 }
338300
@@ -368,6 +330,47 @@ double VescHardware::convertMechanicalRadSecToERPM(
368330 return erpm;
369331}
370332
333+ void VescHardware::populate_state_definitions ()
334+ {
335+ state_interfaces_[hardware_interface::HW_IF_POSITION ] = {
336+ false ,
337+ [this ]() {return hw_state_position_.load (std::memory_order_relaxed);}
338+ };
339+ state_interfaces_[hardware_interface::HW_IF_VELOCITY ] = {
340+ false ,
341+ [this ]() {return hw_state_velocity_.load (std::memory_order_relaxed);}
342+ };
343+ state_interfaces_[" servo" ] = {
344+ false ,
345+ [this ]() {return hw_command_servo_;}
346+ };
347+ }
348+
349+ void VescHardware::populate_command_definitions ()
350+ {
351+ command_interfaces_[hardware_interface::HW_IF_POSITION ] = {
352+ false ,
353+ [this ](double value) {
354+ double vesc_position = convertMechanicalRadToDeg (value);
355+ vesc_interface_->setPosition (vesc_position);
356+ }
357+ };
358+ command_interfaces_[hardware_interface::HW_IF_VELOCITY ] = {
359+ false ,
360+ [this ](double value) {
361+ double vesc_erpm = convertMechanicalRadSecToERPM (value);
362+ vesc_interface_->setSpeed (vesc_erpm);
363+ }
364+ };
365+ command_interfaces_[" servo" ] = {
366+ false ,
367+ [this ](double value) {
368+ hw_command_servo_ = value;
369+ vesc_interface_->setServo (hw_command_servo_);
370+ }
371+ };
372+ }
373+
371374void VescHardware::processValuesPacket (
372375 const vesc_driver::VescPacketValues *values_packet)
373376{
0 commit comments