Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ros2-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ jobs:
matrix:
config:
- {
ros_distro: "humble"
ros_distro: "jazzy"
}
- {
ros_distro: "kilted"
}
runs-on: ubuntu-latest
container:
Expand Down
5 changes: 0 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ repos:
- id: check-json
exclude: ^\.clang-format$

- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v16.0.3
hooks:
- id: clang-format

- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
Expand Down
109 changes: 94 additions & 15 deletions vesc_driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,117 @@ elseif("${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}" STREQUAL "98")
set(CMAKE_CXX_STANDARD 14)
endif()

find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(Threads)
# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(vesc_msgs REQUIRED)
find_package(serial_driver REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(Threads REQUIRED)

###########
## Build ##
###########

# node library
ament_auto_add_library(${PROJECT_NAME} SHARED
src/vesc_driver.cpp
# Core library (no ROS dependencies)
add_library(${PROJECT_NAME}_lib SHARED
src/vesc_interface.cpp
src/vesc_packet.cpp
src/vesc_packet_factory.cpp
src/vesc_device_uuid_lookup.cpp
)
target_link_libraries(${PROJECT_NAME}
target_include_directories(${PROJECT_NAME}_lib PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}>
)
target_link_libraries(${PROJECT_NAME}_lib
${CMAKE_THREAD_LIBS_INIT}
)
ament_target_dependencies(${PROJECT_NAME}_lib
serial_driver
)

# ROS node library
add_library(${PROJECT_NAME} SHARED
src/vesc_driver.cpp
)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}>
)
target_link_libraries(${PROJECT_NAME}
${PROJECT_NAME}_lib
)
ament_target_dependencies(${PROJECT_NAME}
rclcpp
rclcpp_components
std_msgs
geometry_msgs
vesc_msgs
sensor_msgs
)
rclcpp_components_register_node(${PROJECT_NAME}
PLUGIN vesc_driver::VescDriver
EXECUTABLE ${PROJECT_NAME}_node
)

ament_auto_add_executable(
vesc_device_namer
# Device namer executable
add_executable(vesc_device_namer
src/vesc_device_namer.cpp
src/vesc_device_uuid_lookup.cpp
)
target_link_libraries(vesc_device_namer
${PROJECT_NAME}_lib
)

#############
## Install ##
#############

# Install headers
install(
DIRECTORY include/
DESTINATION include/${PROJECT_NAME}
)

# Install libraries
install(TARGETS ${PROJECT_NAME}_lib ${PROJECT_NAME}
EXPORT export_${PROJECT_NAME}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)

# Install executables
install(TARGETS vesc_device_namer
DESTINATION lib/${PROJECT_NAME}
)

# Install launch and config files
install(
DIRECTORY launch params
DESTINATION share/${PROJECT_NAME}
)

#############
## Exports ##
#############

ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_dependencies(
rclcpp
rclcpp_components
std_msgs
geometry_msgs
vesc_msgs
serial_driver
sensor_msgs
)

#############
Expand All @@ -49,8 +132,4 @@ if(BUILD_TESTING)
ament_lint_auto_find_test_dependencies()
endif()

ament_auto_package(
INSTALL_TO_SHARE
launch
params
)
ament_package()
2 changes: 1 addition & 1 deletion vesc_driver/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<author email="josh.whitley@autoware.org">Joshua Whitley</author>
<author email="hxue@ucsd.edu">Haoru Xue</author>

<buildtool_depend>ament_cmake_auto</buildtool_depend>
<buildtool_depend>ament_cmake</buildtool_depend>

<depend>asio_cmake_module</depend>
<depend>rclcpp</depend>
Expand Down
64 changes: 64 additions & 0 deletions vesc_hardware/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.8)
project(vesc_hardware)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(hardware_interface REQUIRED)
find_package(pluginlib REQUIRED)
find_package(rclcpp_lifecycle REQUIRED)
find_package(vesc_driver REQUIRED)

## COMPILE
add_library(
vesc_hardware
SHARED
src/vesc_hardware.cpp
)
target_include_directories(vesc_hardware PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_link_libraries(vesc_hardware PUBLIC
hardware_interface::hardware_interface
pluginlib::pluginlib
rclcpp::rclcpp
rclcpp_lifecycle::rclcpp_lifecycle
vesc_driver::vesc_driver
)

# Export hardware plugins
pluginlib_export_plugin_description_file(hardware_interface vesc_hardware.xml)

# INSTALL
install(
DIRECTORY include
DESTINATION include
)
install(TARGETS vesc_hardware
EXPORT export_vesc_hardware
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)

## EXPORTS
ament_export_targets(export_vesc_hardware HAS_LIBRARY_TARGET)
ament_export_dependencies(
hardware_interface
pluginlib
rclcpp
rclcpp_lifecycle
vesc_driver
)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
endif()

ament_package()
103 changes: 103 additions & 0 deletions vesc_hardware/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# vesc_hardware

ROS 2 hardware interface component for VESC (Vedder Electronic Speed Controller) motor controllers, compatible with the `ros2_control` framework.

## Overview

This package provides a hardware interface plugin that allows VESC motor controllers to be used seamlessly with `ros2_control`. It handles communication with the VESC, converts between VESC units (degrees, ERPM) and standard ROS units (radians, radians/second), and supports both position and velocity control modes.

## Hardware Parameters

The following parameters must be configured in your robot's URDF/XACRO file within the `<hardware>` tag:

### Required Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `device` | string | Serial port device path for VESC communication (e.g., `/dev/ttyACM0`, `/dev/ttyUSB0`) |

### Optional Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `gear_ratio` | double | `1.0` | Gear ratio between motor and output shaft. For a reduction gearbox with ratio N:1, set this to N. Used to convert between motor position/velocity and mechanical output. |
| `pole_pairs` | int | `1` | Number of motor pole pairs. Used to convert between ERPM (Electrical RPM) and mechanical RPM. For a motor with P poles, pole_pairs = P/2. |

## Supported Interfaces

The hardware component supports a single joint with the following interfaces:

### State Interfaces

- `position` - Joint position in radians (mechanical output)
- `velocity` - Joint velocity in radians/second (mechanical output)

### Command Interfaces

- `position` - Position command in radians (mechanical output)
- `velocity` - Velocity command in radians/second (mechanical output)

**Note:** At least one state interface and one command interface must be specified in the URDF.

## URDF Configuration Example

### Basic Configuration (Direct Drive Motor)

```xml
<ros2_control name="vesc_system" type="system">
<hardware>
<plugin>vesc_hardware/VescHardware</plugin>
<param name="device">/dev/ttyACM0</param>
</hardware>

<joint name="wheel_joint">
<command_interface name="velocity"/>
<state_interface name="position"/>
<state_interface name="velocity"/>
</joint>
</ros2_control>
```

### Advanced Configuration (Geared Motor)

```xml
<ros2_control name="vesc_system" type="system">
<hardware>
<plugin>vesc_hardware/VescHardware</plugin>
<param name="device">/dev/ttyACM0</param>
<param name="gear_ratio">14.0</param> <!-- 14:1 reduction gearbox -->
<param name="pole_pairs">7</param> <!-- 14-pole motor -->
</hardware>

<joint name="wheel_joint">
<command_interface name="velocity"/>
<state_interface name="position"/>
<state_interface name="velocity"/>
</joint>
</ros2_control>
```

### Position Control Example

```xml
<ros2_control name="vesc_system" type="system">
<hardware>
<plugin>vesc_hardware/VescHardware</plugin>
<param name="device">/dev/ttyACM0</param>
<param name="gear_ratio">50.0</param> <!-- High reduction for position control -->
<param name="pole_pairs">7</param>
</hardware>

<joint name="actuator_joint">
<command_interface name="position"/>
<state_interface name="position"/>
<state_interface name="velocity"/>
</joint>
</ros2_control>
```

## License

Copyright 2024 Ekumen, Inc.

This software is licensed under the BSD 3-Clause License. See the LICENSE file for details.
Loading
Loading