Micro-ROS là gì?
Micro-ROS đưa ROS 2 xuống thế giới microcontroller. Thay vì phải chạy ROS 2 trên Linux, bạn có thể tạo ROS 2 node trực tiếp trên ESP32, STM32, hoặc Arduino — những vi điều khiển chỉ có vài trăm KB RAM.
Micro-ROS sử dụng DDS-XRCE (DDS for eXtremely Resource Constrained Environments) — phiên bản rút gọn của DDS middleware mà ROS 2 dùng. Một micro-ROS agent chạy trên máy Linux làm cầu nối giữa microcontroller và hệ thống ROS 2.
Kiến trúc
┌──────────────────┐ Serial/WiFi/USB ┌─────────────────┐
│ Microcontroller │ ◄──────────────────────► │ micro-ROS │
│ (ESP32/STM32) │ DDS-XRCE │ Agent (Linux) │
│ micro-ROS client│ │ │
└──────────────────┘ └────────┬────────┘
│ DDS
┌────────▼────────┐
│ ROS 2 System │
│ (Nav2, MoveIt) │
└─────────────────┘
Cài đặt micro-ROS cho ESP32
1. Cài micro-ROS Agent
# Tạo ROS 2 workspace
mkdir -p ~/microros_ws/src && cd ~/microros_ws/src
git clone -b humble https://github.com/micro-ROS/micro_ros_setup.git
cd ~/microros_ws
colcon build
source install/setup.bash
# Tạo agent
ros2 run micro_ros_setup create_agent_ws.sh
ros2 run micro_ros_setup build_agent.sh
2. Firmware ESP32 với PlatformIO
; platformio.ini
[env:esp32]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
https://github.com/micro-ROS/micro_ros_platformio
board_microros_transport = wifi
3. Code ESP32 — Publish sensor data
#include <micro_ros_arduino.h>
#include <rcl/rcl.h>
#include <rclc/rclc.h>
#include <sensor_msgs/msg/imu.h>
rcl_publisher_t imu_publisher;
sensor_msgs__msg__Imu imu_msg;
rclc_executor_t executor;
rcl_timer_t timer;
void timer_callback(rcl_timer_t *timer, int64_t last_call_time) {
// Đọc IMU (ví dụ MPU6050)
imu_msg.linear_acceleration.x = read_accel_x();
imu_msg.linear_acceleration.y = read_accel_y();
imu_msg.linear_acceleration.z = read_accel_z();
imu_msg.angular_velocity.x = read_gyro_x();
imu_msg.angular_velocity.y = read_gyro_y();
imu_msg.angular_velocity.z = read_gyro_z();
// Publish lên topic /imu/data
rcl_publish(&imu_publisher, &imu_msg, NULL);
}
void setup() {
// Kết nối WiFi tới agent
set_microros_wifi_transports("WIFI_SSID", "WIFI_PASS", "192.168.1.100", 8888);
rcl_allocator_t allocator = rcl_get_default_allocator();
rclc_support_t support;
rclc_support_init(&support, 0, NULL, &allocator);
rcl_node_t node;
rclc_node_init_default(&node, "esp32_imu", "", &support);
// Tạo publisher cho IMU data
rclc_publisher_init_default(
&imu_publisher, &node,
ROSIDL_GET_MSG_TYPE_SUPPORT(sensor_msgs, msg, Imu),
"/imu/data"
);
// Timer 100Hz
rclc_timer_init_default(&timer, &support, RCL_MS_TO_NS(10), timer_callback);
rclc_executor_init(&executor, &support.context, 1, &allocator);
rclc_executor_add_timer(&executor, &timer);
}
void loop() {
rclc_executor_spin_some(&executor, RCL_MS_TO_NS(10));
}
Subscribe lệnh điều khiển từ ROS 2
rcl_subscription_t cmd_subscriber;
geometry_msgs__msg__Twist cmd_msg;
void cmd_callback(const void *msgin) {
const geometry_msgs__msg__Twist *msg = (const geometry_msgs__msg__Twist *)msgin;
float linear = msg->linear.x; // m/s
float angular = msg->angular.z; // rad/s
// Chuyển thành PWM cho motor
int left_pwm = (int)((linear - angular * WHEEL_BASE / 2) * PWM_SCALE);
int right_pwm = (int)((linear + angular * WHEEL_BASE / 2) * PWM_SCALE);
set_motors(left_pwm, right_pwm);
}
Chạy Agent và kết nối
# Chạy agent qua WiFi (UDP)
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888
# Hoặc qua Serial
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0
# Kiểm tra topic từ ESP32
ros2 topic list
ros2 topic echo /imu/data
MCU nào phù hợp?
| MCU | RAM | Flash | WiFi | Giá | Đánh giá |
|---|---|---|---|---|---|
| ESP32 | 520KB | 4MB | Có | ~80K VNĐ | Tốt nhất cho prototype, WiFi tích hợp |
| STM32F4 | 192KB | 1MB | Không | ~120K VNĐ | Real-time tốt hơn, FreeRTOS |
| STM32H7 | 1MB | 2MB | Không | ~250K VNĐ | Hiệu năng cao, nhiều peripheral |
| Teensy 4.1 | 1MB | 8MB | Không | ~700K VNĐ | Clock 600MHz, USB host |
Lưu ý quan trọng
- Kết nối WiFi không ổn định — dùng Serial/USB cho ứng dụng safety-critical
- Memory giới hạn — mỗi publisher/subscriber tiêu tốn ~2-5KB RAM, tính toán cẩn thận
- Không có callback queue —
spin_somephải được gọi thường xuyên, tránh blocking code - QoS phải match: QoS trên micro-ROS node phải tương thích với ROS 2 node bên Linux
Micro-ROS là cầu nối quan trọng giữa thế giới embedded và ROS 2, cho phép bạn xây dựng hệ thống robot hoàn chỉnh từ sensor ở tầng thấp nhất đến navigation với Nav2 ở tầng cao nhất, tất cả trong cùng một hệ sinh thái. Với Python và serial communication, bạn cũng có thể giao tiếp với microcontroller mà không cần micro-ROS.