Skip to content

Commit 811bc81

Browse files
committed
Add raw vesc status publisher
1 parent f8ed9ee commit 811bc81

8 files changed

Lines changed: 190 additions & 2 deletions

File tree

vesc_hardware/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ find_package(rclcpp REQUIRED)
1111
find_package(hardware_interface REQUIRED)
1212
find_package(pluginlib REQUIRED)
1313
find_package(rclcpp_lifecycle REQUIRED)
14+
find_package(realtime_tools REQUIRED)
1415
find_package(vesc_driver REQUIRED)
16+
find_package(vesc_hardware_msgs REQUIRED)
1517

1618
## COMPILE
1719
add_library(
@@ -28,7 +30,9 @@ target_link_libraries(vesc_hardware PUBLIC
2830
pluginlib::pluginlib
2931
rclcpp::rclcpp
3032
rclcpp_lifecycle::rclcpp_lifecycle
33+
realtime_tools::realtime_tools
3134
vesc_driver::vesc_driver
35+
${vesc_hardware_msgs_TARGETS}
3236
)
3337

3438
# Export hardware plugins
@@ -53,7 +57,9 @@ ament_export_dependencies(
5357
pluginlib
5458
rclcpp
5559
rclcpp_lifecycle
60+
realtime_tools
5661
vesc_driver
62+
vesc_hardware_msgs
5763
)
5864

5965
if(BUILD_TESTING)

vesc_hardware/include/vesc_hardware/vesc_hardware.hpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
#include "rclcpp/macros.hpp"
4343
#include "rclcpp_lifecycle/node_interfaces/lifecycle_node_interface.hpp"
4444
#include "rclcpp_lifecycle/state.hpp"
45+
#include "realtime_tools/realtime_publisher.hpp"
4546
#include "vesc_driver/vesc_interface.hpp"
47+
#include "vesc_hardware_msgs/msg/vesc_hardware_values.hpp"
4648

4749
namespace vesc_hardware
4850
{
@@ -144,6 +146,7 @@ class VescHardware : public hardware_interface::SystemInterface {
144146

145147
// VESC packet processing
146148
void processValuesPacket(const vesc_driver::VescPacketValues *values_packet);
149+
void publishVescState(const vesc_driver::VescPacketValues & values_packet);
147150

148151
// Conversion functions for VESC values to mechanical values (for reading
149152
// state)
@@ -174,8 +177,9 @@ class VescHardware : public hardware_interface::SystemInterface {
174177

175178
// Hardware parameters
176179
std::string device_;
177-
double gear_ratio_; // Gear ratio between motor and output (default: 1.0)
178-
int pole_pairs_; // Motor pole pairs (default: 1)
180+
double gear_ratio_; // Gear ratio between motor and output
181+
int pole_pairs_; // Motor pole pairs
182+
bool publish_raw_state_; // Whether to publish raw VESC telemetry
179183

180184
// State storage (atomic for thread-safe access from callback)
181185
std::atomic<double> hw_state_position_;
@@ -190,6 +194,12 @@ class VescHardware : public hardware_interface::SystemInterface {
190194

191195
// VESC interface
192196
std::unique_ptr<vesc_driver::VescInterface> vesc_interface_;
197+
198+
// Publisher for hardware values
199+
std::shared_ptr<rclcpp::Publisher<vesc_hardware_msgs::msg::VescHardwareValues>>
200+
hardware_values_publisher_;
201+
std::shared_ptr<realtime_tools::RealtimePublisher<vesc_hardware_msgs::msg::VescHardwareValues>>
202+
realtime_hardware_values_publisher_;
193203
};
194204

195205
} // namespace vesc_hardware

vesc_hardware/package.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
<depend>hardware_interface</depend>
1515
<depend>pluginlib</depend>
1616
<depend>rclcpp_lifecycle</depend>
17+
<depend>realtime_tools</depend>
1718
<depend>vesc_driver</depend>
19+
<depend>vesc_hardware_msgs</depend>
1820

1921
<test_depend>ament_lint_auto</test_depend>
2022
<test_depend>ament_lint_common</test_depend>

vesc_hardware/src/vesc_hardware.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

395472
void VescHardware::vescPacketCallback(

vesc_hardware_msgs/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
project(vesc_hardware_msgs)
3+
4+
find_package(ament_cmake_auto REQUIRED)
5+
ament_auto_find_build_dependencies()
6+
7+
rosidl_generate_interfaces(vesc_hardware_msgs
8+
"msg/VescHardwareValues.msg"
9+
"msg/VescHardwareValuesStamped.msg"
10+
DEPENDENCIES
11+
builtin_interfaces
12+
std_msgs
13+
)
14+
15+
if(BUILD_TESTING)
16+
find_package(ament_lint_auto REQUIRED)
17+
ament_lint_auto_find_test_dependencies()
18+
endif()
19+
20+
ament_auto_package()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# VESC hardware interface telemetry values
2+
# Mirrors the VescPacketValues structure from vesc_driver
3+
4+
# Temperature measurements (degrees Celsius)
5+
float64 temp_fet # FET temperature
6+
float64 temp_motor # Motor temperature
7+
float64 temp_mos1 # MOSFET 1 temperature
8+
float64 temp_mos2 # MOSFET 2 temperature
9+
float64 temp_mos3 # MOSFET 3 temperature
10+
11+
# Current measurements (amperes)
12+
float64 avg_motor_current # Average motor current
13+
float64 avg_input_current # Average input current
14+
float64 avg_id # Average D-axis current
15+
float64 avg_iq # Average Q-axis current
16+
17+
# Voltage measurements (volts)
18+
float64 v_in # Input voltage
19+
float64 avg_vd # Average D-axis voltage
20+
float64 avg_vq # Average Q-axis voltage
21+
22+
# Duty cycle and speed
23+
float64 duty_cycle_now # Current duty cycle (0.0 to 1.0)
24+
float64 rpm # Motor electrical speed (RPM)
25+
26+
# Energy and charge tracking
27+
float64 amp_hours # Charge drawn (ampere-hours)
28+
float64 amp_hours_charged # Charge regenerated (ampere-hours)
29+
float64 watt_hours # Energy drawn (watt-hours)
30+
float64 watt_hours_charged # Energy regenerated (watt-hours)
31+
32+
# Position and distance tracking
33+
int32 tachometer # Net tachometer count
34+
int32 tachometer_abs # Absolute tachometer count
35+
float64 pid_pos_now # Current PID position (degrees)
36+
37+
# Status
38+
int32 fault_code # Fault code (0 = no fault)
39+
int32 controller_id # VESC controller ID
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Stamped version of VescHardwareValues
2+
3+
std_msgs/Header header
4+
VescHardwareValues values

vesc_hardware_msgs/package.xml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>vesc_hardware_msgs</name>
5+
<version>1.1.0</version>
6+
<description>
7+
ROS message definitions for VESC hardware interface telemetry.
8+
</description>
9+
<maintainer email="joebetz@seas.upenn.edu">Johannes Betz</maintainer>
10+
<license>BSD</license>
11+
<url type="website">http://ros.org/wiki/vesc_hardware_msgs</url>
12+
<url type="repository">https://github.com/f1tenth/vesc</url>
13+
<url type="bugtracker">https://github.com/f1tenth/vesc/issues</url>
14+
15+
<buildtool_depend>ament_cmake_auto</buildtool_depend>
16+
17+
<build_depend>rosidl_default_generators</build_depend>
18+
<depend>builtin_interfaces</depend>
19+
<depend>std_msgs</depend>
20+
<exec_depend>rosidl_default_runtime</exec_depend>
21+
22+
<test_depend>ament_lint_auto</test_depend>
23+
<test_depend>ament_lint_common</test_depend>
24+
25+
<member_of_group>rosidl_interface_packages</member_of_group>
26+
27+
<export>
28+
<build_type>ament_cmake</build_type>
29+
</export>
30+
</package>

0 commit comments

Comments
 (0)