![]() |
![]() |
![]() |
This repository contains the perception firmware from my weeding robot dissertation.
It demonstrates a lightweight way to integrate a 2D LiDAR + IMU into a ROS 2 architecture using only:
- a microcontroller (ESP32), and
- a computer running ROS 2 (laptop/desktop)
…without needing a higher-level onboard computer (e.g., Raspberry Pi) to interface sensors directly.
✅ Outputs to ROS 2:
scan(sensor_msgs/LaserScan)imu/data(sensor_msgs/Imu)
Related repos (same dissertation project):
- Delta / End Effector node: https://github.com/busayojee/weedbotDeltaNode
- Drive base node: https://github.com/busayojee/weedbotDriveNode
If you’re building a robot with ROS2 and you need to bring sensors into ROS2 but only have a microcontroller (ESP32) near the sensors, this pattern works well:
ESP32 (sensor I/O) → micro-ROS (XRCE-DDS) → Wi‑Fi UDP → ROS 2 host
The ESP32 handles:
- UART + motor control for RPLIDAR A1
- I2C for BNO08x IMU
- Packaging data into ROS 2 message types (
LaserScan,Imu) - Streaming to the ROS 2 host through
micro_ros_agent
Your computer handles:
- SLAM / localization / fusion / navigation (e.g., SLAM Toolbox, Nav2, robot_localization)
Data flow
- ESP32 reads LiDAR over UART and batches scan samples.
- ESP32 reads IMU over I2C (rotation vector + gyro).
- ESP32 publishes ROS 2 messages via micro-ROS over Wi‑Fi UDP.
- A ROS 2 computer runs
micro_ros_agentand receives the topics.
This keeps sensor wiring short and lets you place sensors on a robot platform without running USB cables back to a laptop.
- ESP32 (tested with PlatformIO
esp32dev) - RPLIDAR A1 (UART + motor enable pin)
- Adafruit BNO08x IMU (I2C)
- Node name:
esp32_lidar_imu - Namespace:
""(empty)
scan→sensor_msgs/LaserScanimu/data→sensor_msgs/Imu
- IMU:
imu_link - LiDAR:
laser_frame
LIDAR_RX_PIN = 21LIDAR_TX_PIN = 22LIDAR_MOTOR_PIN = 2
I2C_SDA_PIN = 19I2C_SCL_PIN = 18
src/
main.cpp # entry point
lib/
node/ # app orchestration
ros/ # micro-ROS context (node, pubs, timer, executor)
sensors/ # BNO08x + LiDAR wrappers (More sensors could be added)
include/
weedbot_config.h # user-editable config
Copy/paste into platformio.ini:
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
build_flags = -I include
monitor_speed = 115200
board_microros_transport = wifi
lib_deps =
https://github.com/micro-ROS/micro_ros_platformio
mirs240x/micro_ros_arduino@^2.0.7-humble
https://github.com/sjamthe/ESP32RPLidar.git
https://github.com/micro-ROS/micro_ros_arduino.git
adafruit/Adafruit BusIO@^1.17.1
hideakitai/MPU9250@^0.4.8
adafruit/Adafruit BNO08x@^1.2.5Edit: include/weedbot_config.h
Key values:
- Wi‑Fi:
WIFI_SSID,WIFI_PWD - Agent:
AGENT_IP,AGENT_PORT - Topics:
TOPIC_SCAN,TOPIC_IMU - Frames:
LASER_FRAME_ID,IMU_FRAME_ID - IMU publish period:
IMU_PERIOD_MS = 100(10 Hz) - BNO08x report intervals:
BNO_ROTATION_VECTOR_US = 5000(200 Hz)BNO_GYRO_CAL_US = 10000(100 Hz)
- LiDAR batching:
LIDAR_SCANS_PER_PUBLISH = 5MAX_BATCH_MEASUREMENTS = 1200
- Agent ping:
AGENT_PING_EVERY_MS = 20000
pio run -t uploadStart the micro-ROS agent:
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888Verify topics:
ros2 topic list
ros2 topic echo /scan
ros2 topic echo /imu/dataYou can adapt this repo if you:
- want to integrate LiDAR + IMU into ROS 2 using only a microcontroller + PC,
- need a pattern for micro-ROS sensor bridging, or
- want to extend the node with additional sensors (GPS, encoders, ToF, cameras via separate nodes, etc.).
Typical follow-on integrations:
robot_localization(EKF) consuming/imu/data- SLAM Toolbox consuming
/scan - TF tree setup linking
laser_frameandimu_linkinto your base frames
If you add timestamps or additional ROS messages later, keep the time sync behavior from the perception stack. The agent time ensures consistent stamps for logging and coordination.
This perception firmware is part of the dissertation project Control and Navigation of a Weeding Robot, together with the four wheel differential drive, removal, and higher level autonomy. If you have any question regarding this driver please do not hesitate to reach out.



