Quick Start Guide
This guide will walk you through creating your first HID device integration with ROS 2 in just a few minutes.
For a complete end-to-end tutorial from cloning the repository to creating a custom device, see the Complete Tutorial.
Overview
The HID ROS 2 workflow consists of three main steps:
Define your device schema in YAML
Build your package (code generation happens automatically)
Launch your device integration
Step 1: Create a Package
Create a new ROS 2 package for your HID device:
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake my_hid_device \
--dependencies rclcpp hardware_interface controller_manager
Step 2: Define Your Device Schema
Create a schema directory and YAML file:
cd my_hid_device
mkdir schema
Create schema/hid_device.yaml:
# Device identification
device_name: "my_sensor"
vendor_id: "0x046d" # Your device's USB VID
product_id: "0xc07e" # Your device's USB PID
# Report IDs
input_report_id: 2 # Device -> Computer
output_report_id: 1 # Computer -> Device (optional)
# ROS 2 configuration
sensor_name: "hid_sensor"
frame_id: "sensor_frame"
update_rate: 250 # Hz
# Data fields - this defines your HID report structure
fields:
- name: "position_x"
type: "float32"
description: "X position in meters"
- name: "position_y"
type: "float32"
description: "Y position in meters"
- name: "velocity"
type: "int16"
description: "Velocity in mm/s"
- name: "button"
type: "uint8"
description: "Button state (0 or 1)"
Step 3: Configure CMake
Edit CMakeLists.txt to add code generation:
cmake_minimum_required(VERSION 3.16)
project(my_hid_device)
# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(hardware_interface REQUIRED)
find_package(controller_manager REQUIRED)
find_package(hid_descriptor_generator REQUIRED)
# Include the code generator
include("${hid_descriptor_generator_DIR}/hid_generate.cmake")
# Generate all files from schema
hid_generate(
SCHEMA_FILE "schema/hid_device.yaml"
)
# Install schema
install(DIRECTORY schema
DESTINATION share/${PROJECT_NAME}
)
ament_package()
Step 4: Build
Build your package:
cd ~/ros2_ws
colcon build --packages-select my_hid_device
source install/setup.bash
The build process automatically generates:
✓ HID descriptor C header for firmware (
include/my_hid_device/hid_descriptor.h)✓ URDF with state interfaces (
urdf/hid_robot.urdf.xacro)✓ Controller configuration (
config/controllers.yaml)✓ Launch file (
launch/hid.launch.py)
Step 5: Verify Generated Files
Check what was generated:
find install/my_hid_device -type f
You should see:
install/my_hid_device/
├── include/my_hid_device/hid_descriptor.h
├── share/my_hid_device/
│ ├── urdf/hid_robot.urdf.xacro
│ ├── config/controllers.yaml
│ ├── launch/hid.launch.py
│ └── schema/hid_device.yaml
Step 6: Prepare Your Firmware
Use the generated header in your microcontroller firmware:
#include "my_hid_device/hid_descriptor.h"
// USB HID descriptor
const uint8_t* hid_desc = hid_report_descriptor;
uint16_t hid_desc_len = HID_REPORT_DESCRIPTOR_SIZE;
// Your report structure (matches YAML schema)
typedef struct __attribute__((packed)) {
uint8_t report_id; // Must be HID_INPUT_REPORT_ID (2)
float position_x;
float position_y;
int16_t velocity;
uint8_t button;
} SensorReport;
// In your main loop
void send_sensor_data(void) {
SensorReport report = {
.report_id = HID_INPUT_REPORT_ID,
.position_x = get_x_position(),
.position_y = get_y_position(),
.velocity = get_velocity(),
.button = read_button()
};
hid_send((uint8_t*)&report, sizeof(report));
}
Step 7: Launch Your Device
Connect your HID device and launch:
ros2 launch my_hid_device hid.launch.py
You should see:
[INFO] [controller_manager]: Loading controller 'hid_generic_broadcaster'
[INFO] [controller_manager]: Configured and activated 'hid_generic_broadcaster'
[INFO] [hid_hardware]: Successfully opened HID device 046d:c07e
[INFO] [hid_hardware]: Device connected and ready
Step 8: Monitor Data
Check available interfaces:
ros2 control list_hardware_interfaces
Output:
command interfaces
state interfaces
hid_sensor/position_x [available] [claimed]
hid_sensor/position_y [available] [claimed]
hid_sensor/velocity [available] [claimed]
hid_sensor/button [available] [claimed]
Monitor the published data:
ros2 topic echo /hid_sensor_states
Debugging Your Device
List Connected HID Devices
ros2 run hid_tools inspect_device --list
Monitor Raw USB Reports
ros2 run hid_tools inspect_device --vid 0x046d --pid 0xc07e
This shows you exactly what your device is sending.
Validate Your Schema
ros2 run hid_tools validate_schema schema/hid_device.yaml --strict
Next Steps
Now that you have a working integration:
Customize Controllers: See Controllers Guide
Add Bidirectional Communication: See Schema Reference for output reports
Create Custom Controllers: See Custom Controllers
Integrate with Your Robot: Use the state interfaces in your robot’s control system
Common Issues
Device Not Found
Check device is connected and has correct VID/PID:
lsusb
ros2 run hid_tools inspect_device --list
Permission Denied
Set up udev rules (see Installation).
Wrong Data Values
Use inspect_device to compare raw USB data with ROS 2 topics:
# Terminal 1: Raw USB data
ros2 run hid_tools inspect_device --vid 0x046d --pid 0xc07e
# Terminal 2: ROS 2 topic
ros2 topic echo /hid_sensor_states
Build Errors
Ensure code generator is built first:
colcon build --packages-select hid_descriptor_generator
colcon build --packages-select my_hid_device
Complete Example
See the examples/dummy_pose_device package for a complete working example with:
Full YAML schema
Simulated HID device
Custom controller
Launch files