ROS2 and Micro-ROS Version 2

Created: 2025-11-29 21:10:37 | Last updated: 2025-11-30 00:44:02 | Status: Public

MicroROS Robot Expansion Board - Complete Setup Guide

Overview

This guide covers setting up a MicroROS control board (ESP32-S3) with ROS2 Humble on Raspberry Pi 5. The board manages motors, IMU, lidar, and servos, connecting to ROS2 via a micro-ROS agent.


Table of Contents

  1. Hardware Overview
  2. RPI 5: Install ROS2 Humble
  3. RPI 5: Install micro-ROS Agent
  4. ESP32: Setup Development Environment
  5. ESP32: Install micro-ROS Components
  6. Configure & Flash the Board
  7. Hardware Connections
  8. Test the System
  9. Robot Bringup & Advanced Features
  10. Quick Reference
  11. Essential Documents Reference

Hardware Overview

MicroROS Control Board (ESP32-S3)

  • Core: ESP32-S3-WROOM-1U-N4R2 (4MB Flash, 2MB PSRAM)
  • Motors: 4x encoder motor interfaces (M1-M4)
  • Sensors: ICM42670P 6-axis IMU, MS200 lidar interface
  • Servos: 2x PWM servo (S1, S2)
  • Power: Type-C PD output for RPI 5 (5.1V/5A)
  • Communication: WiFi, Bluetooth, Serial (UART0/UART1)

GPIO Pin Map (Key Assignments)

Function GPIO Notes
Motor M1 PWM 4, 5 Encoder: 6, 7
Motor M2 PWM 15, 16 Encoder: 47, 48
Motor M3 PWM 9, 10 Encoder: 11, 12
Motor M4 PWM 13, 14 Encoder: 1, 2
Servo S1 8 Range: -90° to 90°
Servo S2 21 Range: -90° to 20°
IMU I2C 39 (SCL), 40 (SDA) ICM42670P
Lidar UART1 17 (TX), 18 (RX) MS200 230400 baud
Type-C Serial 43 (TX), 44 (RX) 115200 baud
Buzzer 46 Active buzzer
MCU LED 45 Status indicator

RPI 5: Install ROS2 Humble

1. Set Locale to UTF-8

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale  # Verify

2. Add ROS2 Repository

sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl gnupg lsb-release -y

sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
  -o /usr/share/keyrings/ros-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
  http://packages.ros.org/ros2/ubuntu $(source /etc/os-release && echo $UBUNTU_CODENAME) main" \
  | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

3. Install ROS2 Humble

sudo apt update
sudo apt upgrade
sudo apt install ros-humble-desktop python3-argcomplete python3-colcon-common-extensions

# Auto-source on login
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

4. Verify Installation

# Test with talker/listener
ros2 run demo_nodes_cpp talker
# In another terminal:
ros2 run demo_nodes_cpp listener

RPI 5: Install micro-ROS Agent

# Install Docker
sudo apt install docker.io
sudo usermod -aG docker $USER
# Log out and back in for group changes

# Run WiFi agent (UDP on port 8090)
docker run -it --rm --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4

# Run Serial agent (alternative)
docker run -it --rm -v /dev:/dev --privileged --net=host \
  microros/micro-ros-agent:humble serial --dev /dev/ttyUSB0 -b 921600 -v4

Exit agent: Ctrl+C (don’t just close terminal or Docker runs in background)

Option B: Build from Source

# Install dependencies
sudo apt install python3-rosdep
sudo rosdep init
rosdep update

# Create workspace
mkdir -p ~/uros_ws/src
cd ~/uros_ws
git clone -b humble https://github.com/micro-ROS/micro_ros_setup.git src/micro_ros_setup

# Install packages and build
rosdep install --from-paths src --ignore-src -y
colcon build
source install/local_setup.bash

# Build agent
ros2 run micro_ros_setup create_agent_ws.sh
ros2 run micro_ros_setup build_agent.sh

# Run agent (source first each time)
source ~/uros_ws/install/local_setup.sh
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8090 -v4

ESP32: Setup Development Environment

1. Install Dependencies

sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv \
  cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0

2. Download ESP-IDF v5.1.2

mkdir -p ~/esp
cd ~/esp
git clone -b v5.1.2 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32s3

3. Activate ESP-IDF (Required Every Terminal Session)

source ~/esp/esp-idf/export.sh

Add to ~/.bashrc for convenience (optional):

alias get_idf='source ~/esp/esp-idf/export.sh'

4. Configure Basic Project Settings

Create a test project or use hello_world:

cd ~/esp/esp-idf/examples/get-started/hello_world
idf.py set-target esp32s3
idf.py menuconfig

Key Settings in menuconfig:
- Serial flasher config → Flash size: 4MB, check “Detect flash size when flashing bootloader”
- Component config → ESP PSRAM → Enable “Support for external, SPI-connected RAM”
- Component config → ESP System Settings → CPU frequency240MHz
- Component config → FreeROS → Kernel → configTICK_RATE_HZ1000
- Partition Table → Select “Single factory app (large), no OTA”

Save: Press S, then Q to quit

5. Test Compilation

idf.py build
idf.py flash monitor  # Connect board via USB first
# Exit monitor: Ctrl+]

ESP32: Install micro-ROS Components

1. Download micro-ROS Component

mkdir -p ~/esp/Samples/extra_components
cd ~/esp/Samples/extra_components
git clone -b humble https://github.com/micro-ROS/micro_ros_espidf_component.git
cd micro_ros_espidf_component

2. Install Python Dependencies

source ~/esp/esp-idf/export.sh  # Ensure ESP-IDF active
pip3 install catkin_pkg lark-parser empy colcon-common-extensions

3. CRITICAL: Configure micro-ROS Limits

Edit ~/esp/Samples/extra_components/micro_ros_espidf_component/colcon.meta:

"rmw_microxrcedds": {
  "cmake-args": [
    "-DRMW_UXRCE_XML_BUFFER_LENGTH=400",
    "-DRMW_UXRCE_TRANSPORT=udp",
    "-DRMW_UXRCE_MAX_NODES=1",
    "-DRMW_UXRCE_MAX_PUBLISHERS=3",
    "-DRMW_UXRCE_MAX_SUBSCRIPTIONS=3",
    "-DRMW_UXRCE_MAX_SERVICES=1",
    "-DRMW_UXRCE_MAX_CLIENTS=1",
    "-DRMW_UXRCE_MAX_HISTORY=3"
  ]
}

Adjust these based on your needs:
- Factory firmware uses: 3 publishers (imu, odom, scan), 3 subscribers (cmd_vel, beep, servos)
- Don’t over-allocate - ESP32 has limited RAM

4. Compile micro-ROS Library

cd ~/esp/Samples/extra_components/micro_ros_espidf_component/examples/int32_publisher
source ~/esp/esp-idf/export.sh
idf.py set-target esp32s3
# Wait for auto-download and compilation (takes several minutes)
# Look for "Configuring done" and "Generating done"

5. Verify Library Built

ls ~/esp/Samples/extra_components/micro_ros_espidf_component/*.a
# Should see: libmicroros.a

6. Clean micro-ROS Cache (if you change colcon.meta)

cd ~/esp/Samples/extra_components/micro_ros_espidf_component/examples/int32_publisher
idf.py clean-microros
# Then rebuild: idf.py set-target esp32s3

Configure & Flash the Board

1. Create Your Project (or Use Factory Firmware)

Option A: Start from Example

cd ~/esp/Samples
cp -r extra_components/micro_ros_espidf_component/examples/int32_publisher my_robot
cd my_robot

Option B: Use Factory-Style Firmware
Use the twist_subscriber and odom_publisher examples as templates.

2. Configure Project CMakeLists.txt

Add to root CMakeLists.txt:

set(EXTRA_COMPONENT_DIRS "~/esp/Samples/extra_components")

3. Configure WiFi and Agent Settings

cd ~/esp/Samples/my_robot  # or your project folder
source ~/esp/esp-idf/export.sh
idf.py menuconfig

Navigate to:
- micro-ROS Settings → WiFi Configuration
- WiFi SSID: Your network name
- WiFi Password: Your password
- micro-ROS Settings
- micro-ROS Agent IP: RPI 5 IP address (e.g., 192.168.1.100)
- micro-ROS Agent Port: 8090
- micro-ROS example-app settings
- Ros domain id: 20 (or match your ROS_DOMAIN_ID)
- Ros namespace: Leave empty (or use namespace prefix)

Save: Press S, then Q

4. Build and Flash

idf.py build
idf.py flash monitor

# Exit monitor: Ctrl+]

5. Alternative: Configuration via Serial Script

If using factory firmware, configure via config_robot.py:

# Edit script with your WiFi/IP settings
python3 config_robot.py
# Press reset button on board within 5 seconds of boot

Hardware Connections

Motor Connections (310 Encoder Motors)

Motor Board Interface Cable Color Code
Left Front (M1) Motor1 port White shell → Board, Black shell → Motor
Left Rear (M2) Motor2 port White shell → Board, Black shell → Motor
Right Front (M3) Motor3 port White shell → Board, Black shell → Motor
Right Rear (M4) Motor4 port White shell → Board, Black shell → Motor

Motor Port Pinout (e.g., M1):
- M1+/M1-: Motor power
- GND/VCC: Encoder power (3.3V)
- H1A/H1B: Encoder pulse signals

MS200 Lidar

  • Anti-reverse connector - plug directly into lidar port
  • Auto-configured: UART1 (GPIO17 TX, GPIO18 RX) @ 230400 baud

PWM Servos (Optional)

  • S1 (bottom port): GPIO8, range -90° to 90°
  • S2 (top port): GPIO21, range -90° to 20° (gimbal limited)
  • Pinout: Brown=GND, Red=5V, Yellow=Signal

ESP32 WiFi Camera (Optional)

  • Connect to custom GPIO ports
  • Creates AP: Yahboom-ESP32_WIFI (no password)
  • Stream: http://192.168.4.1:81/stream

Power

  • Battery: 7.4V LiPo via T-connector
  • RPI 5: Type-C PD (5.1V/5A) from board
  • Main switch: Controls all power

Test the System

1. Start Agent on RPI 5

# Set ROS_DOMAIN_ID to match board
export ROS_DOMAIN_ID=20

# Run agent
docker run -it --rm --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4

2. Power On Board

  • Turn on main switch
  • Watch serial monitor (if connected): Should see WiFi connection → Agent connection
  • Agent terminal should show: Node creation, publishers/subscribers registered

3. Verify Node Connection (RPI 5)

# List nodes (should see /YB_Car_Node or your node name)
ros2 node list

# Check node details
ros2 node info /YB_Car_Node

# List all topics
ros2 topic list

4. Test Published Topics

Lidar:

ros2 topic echo /scan
ros2 topic hz /scan  # Should be ~11Hz

IMU:

ros2 topic echo /imu
ros2 topic hz /imu  # Should be ~20Hz

Odometry (raw encoder):

ros2 topic echo /odom_raw
ros2 topic hz /odom_raw  # Should be ~20Hz

5. Test Subscribed Topics (Control)

Move robot forward (0.5 m/s):

ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist \
  "{linear: {x: 0.5, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}"

Rotate in place (1.5 rad/s):

ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist \
  "{linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.5}}"

Stop:

ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist \
  "{linear: {x: 0.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}"

Buzzer (on/off):

ros2 topic pub --once /beep std_msgs/msg/UInt16 "data: 1"  # On
ros2 topic pub --once /beep std_msgs/msg/UInt16 "data: 0"  # Off
ros2 topic pub --once /beep std_msgs/msg/UInt16 "data: 300"  # Beep 300ms

Servos:

ros2 topic pub --once /servo_s1 std_msgs/msg/Int32 "data: 30"   # S1 to 30°
ros2 topic pub --once /servo_s2 std_msgs/msg/Int32 "data: -60"  # S2 to -60°

Robot Bringup & Advanced Features

1. Install Required Packages

sudo apt install ros-humble-robot-localization ros-humble-imu-filter-madgwick \
  ros-humble-tf2-tools ros-humble-rqt-tf-tree

2. Full Bringup Launch (Sensor Fusion)

This fuses IMU + odometry and publishes TF tree:

# Ensure agent is running first
ros2 launch yahboomcar_bringup yahboomcar_bringup_launch.py

What this does:
- Filters IMU data (imu_filter_madgwick)
- Fuses IMU + odom → /odom (EKF fusion)
- Publishes TF: odom → base_footprint → base_link → imu_frame
- Loads robot URDF model

3. Visualize in RViz

rviz2
# In RViz:
# - Set Fixed Frame: "base_link"
# - Add → TF
# - Add → LaserScan → Topic: /scan
# - Add → RobotModel

4. View TF Tree

ros2 run rqt_tf_tree rqt_tf_tree
# Or:
ros2 run tf2_ros view_frames
# Generates frames.pdf

5. Keyboard Control (Optional)

ros2 run yahboomcar_ctrl yahboom_keyboard
# Use i/j/k/l for movement, q/z for speed

6. Joystick Control (Optional)

# Terminal 1:
ros2 run yahboomcar_ctrl yahboom_joy

# Terminal 2:
ros2 run joy joy_node

Quick Reference

ESP-IDF Commands

# Activate environment (every new terminal)
source ~/esp/esp-idf/export.sh

# Configure project
idf.py menuconfig

# Set target chip
idf.py set-target esp32s3

# Build only
idf.py build

# Flash only
idf.py flash

# Flash and monitor
idf.py flash monitor

# Monitor only
idf.py monitor

# Exit monitor
Ctrl+]

# Clean micro-ROS (after changing colcon.meta)
idf.py clean-microros

# Full clean
idf.py fullclean

micro-ROS Agent Commands

# Docker WiFi agent
docker run -it --rm --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4

# Docker Serial agent
docker run -it --rm -v /dev:/dev --privileged --net=host \
  microros/micro-ros-agent:humble serial --dev /dev/ttyUSB0 -b 921600 -v4

# Source-built agent
source ~/uros_ws/install/local_setup.sh
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8090 -v4

# Exit agent
Ctrl+C

ROS2 Topic Quick Reference

Topic Type Rate Direction Purpose
/cmd_vel Twist - Subscribe Robot speed control
/scan LaserScan 11Hz Publish MS200 lidar data
/imu Imu 20Hz Publish Filtered IMU data
/odom_raw Odometry 20Hz Publish Raw encoder odometry
/odom Odometry 20Hz Publish Fused IMU+odom (after bringup)
/beep UInt16 - Subscribe Buzzer control (0/1/ms)
/servo_s1 Int32 - Subscribe Servo 1 angle (-90 to 90)
/servo_s2 Int32 - Subscribe Servo 2 angle (-90 to 20)

Kinematics Parameters

From robot_kinematics_analysis.md:
- W (wheelbase width): Distance between left/right wheels
- L (wheelbase length): Distance between front/rear wheels
- A = W/2, B = L/2
- ROBOT_APB = A + B (used in code)

Speed equations:

V_m1 = V_x - V_z * (A+B)  // Left front
V_m2 = V_x - V_z * (A+B)  // Left rear
V_m3 = V_x + V_z * (A+B)  // Right front
V_m4 = V_x + V_z * (A+B)  // Right rear

Network Configuration

# On RPI 5, match board's ROS_DOMAIN_ID
export ROS_DOMAIN_ID=20
# Add to ~/.bashrc to persist

# Check RPI 5 IP
ip addr show

# Both devices must be on same LAN
# For VM: use "Bridge mode" networking

Troubleshooting

Problem Solution
Agent won’t connect Check: WiFi SSID/password, agent IP, port 8090, ROS_DOMAIN_ID match
No /YB_Car_Node Press reset on board, restart agent, check serial monitor
“Service not ready” Agent not running or wrong IP/port
Motors don’t move Check battery voltage (7.4V), motor connections, /cmd_vel topic
Compilation fails Re-run source ~/esp/esp-idf/export.sh, check ESP-IDF version (5.1.2)
“libmicroros.a not found” Build int32_publisher example first, verify EXTRA_COMPONENT_DIRS path
Serial port busy Stop agent if using /dev/ttyUSB0, close other serial monitors
Multiple nodes in ros2 node list Ctrl+C agent, reset board, restart agent cleanly
IMU/Lidar no data Check hardware connections, verify topics with ros2 topic list

Essential Documents Reference

From Your Text Dump - Priority Reading Order

MUST READ (in this order):
1. brief-introduction-of-microros-control-board.md - Hardware specs, GPIO pins
2. 3.-microros-control-board-configuration.md - Board config script
3. set-up-esp32-idf-development-environment.md - ESP-IDF install
4. install-esp32-microros-components.md - Critical: micro-ROS build process
5. install-and-start-microros-agent.md - Agent setup on RPI 5

Hardware Integration Examples:
6. subscribe-speed-control-topics.md - /cmd_vel subscriber, motor control
7. release-speed-topic.md - Odometry publisher
8. publish-lidar-data-topics.md - MS200 lidar integration
9. release-imu-data-topic.md - IMU publisher

Testing & Verification:
10. 1.-robot-information-release.md - Factory firmware topics, ROS2 CLI testing

Optional (for custom features):
- subscribe-pwm-servo-topics.md - Servo control
- subscribe-buzzer-topics.md - Buzzer control
- robot-kinematics-analysis.md - 4-wheel drive equations
- 4.-robot-state-estimation.md - Sensor fusion (EKF)
- customized-transmission-method.md - Serial transport vs UDP

Skip for now:
- ROS2 tutorial docs (1.introduction-to-ros2.md through 23.ros2-tf2-coordinate-transformation.md) - Generic ROS2 info
- ESP32 hardware examples (led.md, beep.md, encoder.md, etc.) - Low-level testing only
- Calibration docs - Do after basic system works


Next Steps

  1. Basic Testing: Verify all topics publish/subscribe correctly
  2. Calibration: Run calibrate_linear.py and calibrate_angular.py for accuracy
  3. Mapping: Install ros-humble-slam-toolbox or ros-humble-cartographer
  4. Navigation: Install ros-humble-navigation2
  5. Vision: Add camera (ESP32 WiFi or USB camera on RPI 5)

License & Support

  • ESP-IDF: Apache 2.0
  • micro-ROS: Apache 2.0
  • ROS2: Apache 2.0

Board-specific issues: Refer to Yahboom documentation
ROS2/micro-ROS issues: Check official repos and forums


Version: 1.0 | Last Updated: 2025-01-29