@@ -83,9 +83,19 @@ hardware_interface::CallbackReturn VescHardware::on_init(
8383 pole_pairs_ = 1 ;
8484 }
8585
86+ // Read optional publish_raw_state parameter (default: false)
87+ auto it_publish_raw_state = info_.hardware_parameters .find (" publish_raw_state" );
88+ if (it_publish_raw_state != info_.hardware_parameters .end ()) {
89+ publish_raw_state_ = (it_publish_raw_state->second == " true" ||
90+ it_publish_raw_state->second == " 1" );
91+ } else {
92+ publish_raw_state_ = false ;
93+ }
94+
8695 RCLCPP_INFO (get_logger (), " Configured device: %s" , device_.c_str ());
8796 RCLCPP_INFO (get_logger (), " Gear ratio: %.2f, Pole pairs: %d" , gear_ratio_,
8897 pole_pairs_);
98+ RCLCPP_INFO (get_logger (), " Publish raw state: %s" , publish_raw_state_ ? " true" : " false" );
8999
90100 // Validate interfaces
91101 if (info_.joints .size () != 1 ) {
@@ -175,6 +185,19 @@ hardware_interface::CallbackReturn VescHardware::on_init(
175185 hw_state_velocity_ = 0.0 ;
176186 hw_command_servo_ = 0.0 ;
177187
188+ // Create publisher for hardware values (only if enabled)
189+ if (publish_raw_state_) {
190+ hardware_values_publisher_ =
191+ get_node ()->create_publisher <vesc_hardware_msgs::msg::VescHardwareValues>(
192+ " ~/hardware_values" , 10 );
193+
194+ // Create realtime publisher wrapper
195+ realtime_hardware_values_publisher_ =
196+ std::make_shared<realtime_tools::RealtimePublisher<
197+ vesc_hardware_msgs::msg::VescHardwareValues>>(
198+ hardware_values_publisher_);
199+ }
200+
178201 return hardware_interface::CallbackReturn::SUCCESS ;
179202}
180203
@@ -390,6 +413,60 @@ void VescHardware::processValuesPacket(
390413 double mechanical_velocity =
391414 convertERPMtoMechanicalRadSec (values_packet->rpm ());
392415 hw_state_velocity_.store (mechanical_velocity, std::memory_order_relaxed);
416+
417+ // Publish telemetry data
418+ publishVescState (*values_packet);
419+ }
420+
421+ void VescHardware::publishVescState (
422+ const vesc_driver::VescPacketValues & values_packet)
423+ {
424+ if (!realtime_hardware_values_publisher_) {
425+ return ;
426+ }
427+
428+ if (realtime_hardware_values_publisher_->trylock ()) {
429+ auto & msg = realtime_hardware_values_publisher_->msg_ ;
430+
431+ // Temperature measurements
432+ msg.temp_fet = values_packet.temp_fet ();
433+ msg.temp_motor = values_packet.temp_motor ();
434+ msg.temp_mos1 = values_packet.temp_mos1 ();
435+ msg.temp_mos2 = values_packet.temp_mos2 ();
436+ msg.temp_mos3 = values_packet.temp_mos3 ();
437+
438+ // Current measurements
439+ msg.avg_motor_current = values_packet.avg_motor_current ();
440+ msg.avg_input_current = values_packet.avg_input_current ();
441+ msg.avg_id = values_packet.avg_id ();
442+ msg.avg_iq = values_packet.avg_iq ();
443+
444+ // Voltage measurements
445+ msg.v_in = values_packet.v_in ();
446+ msg.avg_vd = values_packet.avg_vd ();
447+ msg.avg_vq = values_packet.avg_vq ();
448+
449+ // Duty cycle and speed
450+ msg.duty_cycle_now = values_packet.duty_cycle_now ();
451+ msg.rpm = values_packet.rpm ();
452+
453+ // Energy and charge tracking
454+ msg.amp_hours = values_packet.amp_hours ();
455+ msg.amp_hours_charged = values_packet.amp_hours_charged ();
456+ msg.watt_hours = values_packet.watt_hours ();
457+ msg.watt_hours_charged = values_packet.watt_hours_charged ();
458+
459+ // Position and distance tracking
460+ msg.tachometer = values_packet.tachometer ();
461+ msg.tachometer_abs = values_packet.tachometer_abs ();
462+ msg.pid_pos_now = values_packet.pid_pos_now ();
463+
464+ // Status
465+ msg.fault_code = values_packet.fault_code ();
466+ msg.controller_id = values_packet.controller_id ();
467+
468+ realtime_hardware_values_publisher_->unlockAndPublish ();
469+ }
393470}
394471
395472void VescHardware::vescPacketCallback (
0 commit comments