Skip to the content
PCBKitNew board
2 layers111.5 × 102 mmWall e, the printed circuit board in 3D

A tiny robot with IMU (MPU5060) and an ultrasonic sensor (HC-SR04), running on micro-ROS, communicating over UDP.

Size
111.5 × 102 mm
Copper layers
2
Thickness
1.6 mm
Parts
12
Nets
65
Pads
153
Tracks, vias
337, 0
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
3 Apr 2026
Updated
11 May 2026

Overview

Wall e is an open-source printed circuit board by c-lydia, from the c-lydia/ESP-ROS2 repository on GitHub, published under the Apache-2.0 licence. It is a 2-layer board of 111.5 × 102 mm with 12 parts on 65 nets, routed with 337 tracks and 0 vias.

It is built around the ESP32-WROOM-32, HC-SR04 and MPU-6050. Its parts include 7 ICs and 4 connectors. It belongs with the robots and motor control and sensors and measurement boards and the ESP32 boards of this library.

Main components

3

README

README.md

ESP-ROS2

License ROS2 micro-ROS FreeRTOS Python C++ C ESP-IDF Arduino Docker Docker Compose NVIDIA GPU CUDA PyTorch YOLO ONNX Runtime TensorRT KiCad STEP Docs venv Stars Forks Watchers Release Issues Visitors

micro-ROS workspace for ESP32 (FreeRTOS + ESP-IDF) with ROS 2 Humble, including both the Wall-E control stack and the Gassify gas-robot stack.

For a user-focused setup and operation guide, see user_manual.md.

This repository includes:

  • ESP32 firmware app: firmware/custom/esp32_controller
  • micro-ROS firmware workspace: firmware/mcu_ws
  • Host ROS 2 workspace: src, build, install
  • micro-ROS agent container (UDP 9999)
  • Gas robot ROS 2 workspace: gas_robot_ws/src
  • Gassify system model: gassify_model.md

Documentation Map

Gassify Stack Overview

The Gassify part of this repository focuses on gas-robot modeling and robot description assets alongside the existing Wall-E stack.

  • ROS 2 package set location: gas_robot_ws/src
  • Robot description package: gas_robot_ws/src/gas_robot_description
  • URDF/Xacro model includes a dedicated gas sensor link (gas_sensor_link) in:
    • gas_robot_ws/src/gas_robot_description/gas_robot_description/src/description/gas_robot.urdf.xacro
  • Full mathematical and control model reference: gassify_model.md

The Sphinx site includes the same high-level concepts and firmware details in a published format.

Prerequisites

  • Docker
  • Docker Compose
  • USB access for flashing (device usually /dev/ttyUSB0)

Optional for CUDA/GPU workflows:

  • NVIDIA GPU driver on host
  • NVIDIA Container Toolkit on host (nvidia-container-toolkit)

Quick Start

From the repository root:

  1. Start workspace and agent
bash
docker compose up -d

GPU/CUDA-enabled start (keeps default pipeline unchanged when not used):

bash
docker compose -f docker-compose.yaml -f docker-compose.gpu.yaml up --build -d

GPU image includes an object-detection-ready Python stack in this mode:

  • CUDA-enabled PyTorch (torch, torchvision, torchaudio)
  • ultralytics (YOLO)
  • opencv-python-headless
  • onnx and onnxruntime-gpu==1.18.1 (pinned)
  • pycocotools
  • tensorrt==8.6.1 (pinned)

To override TensorRT version, change TENSORRT_PIP_SPEC in docker/docker-compose.gpu.yaml. To override ONNX Runtime GPU version, change ONNXRUNTIME_GPU_PIP_SPEC in docker/docker-compose.gpu.yaml.

Quick GPU check inside container:

bash
docker exec -it micro_ros_workspace bash -lc "nvidia-smi"

Quick Python GPU/object-detection check:

bash
docker exec -it micro_ros_workspace bash -lc "python3 -c 'import torch, ultralytics, cv2; print(torch.__version__); print(torch.cuda.is_available()); print(ultralytics.__version__); print(cv2.__version__)'"

Quick TensorRT check:

bash
docker exec -it micro_ros_workspace bash -lc "python3 -c 'import tensorrt as trt; print(trt.__version__)'"
  1. Enter workspace container
bash
docker exec -it micro_ros_workspace bash
  1. Build host ROS 2 workspace (if needed)
bash
cd /micro_ros_ws
colcon build
  1. Source the environment
bash
source /opt/ros/humble/setup.bash
source /micro_ros_ws/install/setup.bash

If you launch RViz or Gazebo GUI from the container and see Authorization required, but no authorization protocol specified, run xhost +si:localuser:root on the host before starting the container. This workspace uses X11 forwarding, and the container runs as root by default.

Launch and Visualization Updates (2026-04-17)

  • wall_e.launch.py now generates robot_description using the Python xacro API (xacro.process_file(...).toxml()) instead of shelling out to the xacro executable.
  • gazebo_ros remains optional at launch time. If unavailable, launch continues with a clear log message.
  • Rear wheel TF visibility in RViz is now guaranteed even when joint_state_publisher is disabled:
    • rear wheel static TF publishers are started by default
    • they are automatically disabled when use_joint_state_publisher:=true
  • Fresh containers should include runtime ROS GUI/model dependencies from Dockerfile (ros-humble-xacro, ros-humble-rviz2, ros-humble-gazebo-ros-pkgs, ros-humble-joint-state-publisher).

If your currently running container was created before these package updates, rebuild it:

bash
docker compose up --build -d

KiCad In Docker

KiCad is available in the workspace container and the PCB project is mounted at:

bash
/micro_ros_ws/pcb/wall_e_pcb_v1.0
  1. Verify KiCad CLI:
bash
docker exec micro_ros_workspace kicad-cli version
  1. Run DRC report:
bash
docker exec micro_ros_workspace kicad-cli pcb drc /micro_ros_ws/pcb/wall_e_pcb_v1.0/wall_e.kicad_pcb
  1. Export Gerbers:
bash
docker exec micro_ros_workspace kicad-cli pcb export gerbers /micro_ros_ws/pcb/wall_e_pcb_v1.0/wall_e.kicad_pcb --output /micro_ros_ws/pcb/wall_e_pcb_v1.0/gerbers
  1. Launch KiCad GUI from container (host X11):
bash
xhost +si:localuser:root
docker exec -it micro_ros_workspace kicad

Build ESP32 Firmware

Inside the workspace container:

  1. Configure firmware app and transport
bash
ros2 run micro_ros_setup configure_firmware.sh esp32_controller -t udp -i 192.168.1.2 -p 8888
  1. Build firmware
bash
ros2 run micro_ros_setup build_firmware.sh
  1. Firmware output files
bash
firmware/freertos_apps/microros_esp32_extensions/build/esp32_controller.bin
firmware/freertos_apps/microros_esp32_extensions/build/esp32_controller.elf

Flash ESP32 Firmware

Inside the workspace container (requires serial device access):

  1. Flash
bash
ros2 run micro_ros_setup flash_firmware.sh

If your board is not /dev/ttyUSB0, update docker-compose.yaml device mapping or run a custom docker command with the correct --device mapping.

Monitor ESP32 Logs (ESP-IDF)

Inside the workspace container:

bash
cd /micro_ros_ws/firmware/freertos_apps/microros_esp32_extensions
source /micro_ros_ws/firmware/toolchain/esp-idf/export.sh
idf.py -p /dev/ttyUSB0 monitor

You can also build then monitor:

bash
idf.py build
idf.py -p /dev/ttyUSB0 monitor

Run In Wokwi (Simulation)

Wokwi does not use /dev/ttyUSB0. It loads your firmware .bin/.elf directly.

  1. Ensure wokwi.toml points to the generated firmware files:
toml
[wokwi]
version = 1
firmware = "firmware/freertos_apps/microros_esp32_extensions/build/esp32_controller.bin"
elf = "firmware/freertos_apps/microros_esp32_extensions/build/esp32_controller.elf"
  1. Build firmware before starting simulator:
bash
docker exec micro_ros_workspace bash -lc "cd /micro_ros_ws/firmware/freertos_apps/microros_esp32_extensions && source /micro_ros_ws/firmware/toolchain/esp-idf/export.sh && idf.py build"
  1. Start Wokwi from VS Code command palette: Wokwi: Start Simulator.

  2. Read logs in VS Code Output panel, Wokwi channel (or Wokwi Terminal, depending on extension version).

If logs still do not appear, stop simulation, reload VS Code window, and start simulator again.

WiFi Provisioning System

Both ESP32 controller apps (motor-enabled and sensor-only) include a browser-based WiFi provisioning system for easy credential setup without source code editing.

How It Works

  1. First Boot (No Credentials)

    • Device starts WiFi access point: ESP32-Setup (open, no password)
    • HTTP provisioning server launches on http://192.168.4.1/
  2. User Setup

    • Connect laptop/phone to ESP32-Setup network
    • Open browser to http://192.168.4.1/
    • Enter WiFi SSID and password via form
    • Device saves credentials to NVS flash (persistent)
  3. Subsequent Boots

    • Device reads stored credentials from NVS
    • Connects to configured WiFi in normal station mode
    • Proceeds with ROS 2 and sensor initialization

Credential Storage

  • Location: NVS flash partition, namespace "wifi_creds"
  • Persistence: Survives power cycles and resets
  • Fallback: Kconfig symbols CONFIG_ESP_WIFI_SSID / CONFIG_ESP_WIFI_PASSWORD (for build-time defaults)

Architecture

The provisioning system includes:

  • nvs_read_wifi_creds(): Load SSID/password from flash
  • nvs_write_wifi_creds(): Save credentials after form submission
  • SoftAP initialization for open access point
  • Simple HTML form with POST handler for credential entry
  • Automatic server shutdown after successful provisioning

Applicable Apps

  • firmware/custom/esp32_controller/: Motor + sensor controller with full provisioning
  • firmware/freertos_apps/apps/esp32_controller/: Sensor-only reference variant (provisioning included)

Run micro-ROS Agent

The compose service starts this automatically:

bash
microros/micro-ros-agent:humble udp4 --port 9999

You can check logs with:

bash
docker logs -f micro_ros_agent

Sensor Processing Pipeline (Host)

The firmware publishes raw sensor topics:

  • /imu/data (sensor_msgs/msg/Imu)
  • /range/data (sensor_msgs/msg/Range)

Host-side ROS 2 nodes can process these into cleaner and fused signals:

  • wall_e_ws/src/feedback/feedback/imu_filter.py
    • Input: /imu/data
    • Output: /imu/filter
  • wall_e_ws/src/feedback/feedback/ultrasonic_filter.py
    • Input: /range/data
    • Output: /range/filter
  • wall_e_ws/src/feedback/feedback/sensor_fusion.py
    • Inputs: /imu/filter, /range/filter
    • Outputs: /fusion/height, /fusion/vertical_velocity, /fusion/debug

PCB and Speed Sensing

The board design lives in pcb/wall_e_pcb_v1.0.

The current schematic includes the ESP32 module, motor driver stages, the MPU6050, the HC-SR04 range sensor, and paired hall-effect sensors for wheel-speed or rotation feedback.

Use the KiCad project as the source of truth for connector pinouts, board placement, and DRC/GERBER work before changing firmware wiring assumptions.

This keeps firmware responsibilities focused on sensor I/O and control while allowing filter tuning on the host.

Control and Localization Pipeline (Host)

Current host-side runtime flow:

  • control/gamepad_node
    • Publishes /gamepad
  • control/robot_control_node
    • Inputs: /gamepad, /range/filter, /imu/filter, /odom
    • Outputs: /cmd_vel, /servo_cmd
    • Supports manual mode and cascaded closed-loop mode:
      • outer P/PD position-to-speed setpoint
      • inner PI speed tracking loop
    • Also maps a gamepad axis to /servo_cmd (std_msgs/msg/Float32, angle in degrees)
  • localization/odometry_node
    • Inputs: /cmd_vel, /imu/filter, /range/filter, /fusion/height, /fusion/vertical_velocity
    • Output: /odom
  • localization/inverse_kinematic_node
    • Input: /cmd_vel
    • Output: /motor_cmd (4-wheel command array)

System Architecture Diagram

Wall-E system architecture

Flow summary:

  • esp32_controller publishes raw IMU and range data to ROS 2.
  • imu_filter and ultrasonic_filter produce cleaner feedback streams.
  • sensor_fusion combines filtered streams for downstream state estimation.
  • odometry_node estimates vehicle state and publishes /odom.
  • robot_control_node generates /cmd_vel using gamepad + safety + PI hold.
  • robot_control_node also publishes /servo_cmd from gamepad axis input (with configurable limits/default).
  • In closed-loop mode, PI acts on speed error (not direct position error).
  • inverse_kinematic_node converts /cmd_vel into /motor_cmd for firmware actuation.

Useful Commands

  • Rebuild host workspace
bash
docker exec -it micro_ros_workspace bash -lc "cd /micro_ros_ws && colcon build"
  • Rebuild firmware
bash
docker exec -it micro_ros_workspace bash -lc "source /opt/ros/humble/setup.bash && source /micro_ros_ws/install/setup.bash && ros2 run micro_ros_setup build_firmware.sh"

Latest Firmware Debug Notes (2026-04-10)

  • Confirmed firmware path in use is firmware/custom/esp32_controller.

  • MPU startup now includes gyro bias calibration (200 samples). Keep robot still at boot for best drift reduction.

  • Ultrasonic timeout message Ultrasonic timeout(wait high) means no rising edge was seen on ECHO.

  • After wiring/level correction, ultrasonic produced valid pulse widths around 344-401 us (~0.059-0.069 m in test setup).

  • Reboot right after Starting ROS node setup... was traced to watchdog interaction in startup; the firmware now logs watchdog delete/add status around ROS init.

  • NVS open for read failed: 0x1102 is expected when WiFi credentials are not yet stored in namespace wifi_creds.

  • Stop everything

bash
docker compose down

Troubleshooting

  • Package micro_ros_setup not found Source both setup files:
bash
source /opt/ros/humble/setup.bash
source /micro_ros_ws/install/setup.bash
  • Launch error: file not found: [Errno 2] No such file or directory: 'xacro' Install xacro in the running container (or rebuild image after pulling latest Dockerfile updates):
bash
apt-get update && apt-get install -y ros-humble-xacro
  • Launch/CLI says Package not found for rviz2 or gazebo_ros Your container is missing GUI/simulation runtime packages. Rebuild with the updated image:
bash
docker compose up --build -d
  • RViz RobotModel shows No transform from rear_left_wheel or rear_right_wheel This is now handled in the launch file by publishing rear-wheel static transforms when joint_state_publisher is off. If you still see it, restart launch and verify you are using the updated wall_e.launch.py.

  • Docker compose fails on /dev/ttyUSB0 Your host may expose a different serial device. Adjust docker-compose.yaml accordingly.

  • Build fails with Git safe.directory for esp-idf Run in container:

bash
git config --global --add safe.directory /micro_ros_ws/firmware/toolchain/esp-idf
  • ESP-IDF monitor fails with Device or resource busy: '/dev/ttyUSB0' Another process is already using the serial port. Close any existing screen, idf.py monitor, or other serial tool and retry. To find the owner:
bash
fuser -v /dev/ttyUSB0
lsof /dev/ttyUSB0
  • make menuconfig fails with python: No such file or directory Install Python alias in the container:
bash
apt-get update && apt-get install -y python-is-python3
  • ESP-IDF Python dependency warnings (pkg_resources, setuptools) For ESP-IDF v4.1, pin setuptools in the IDF virtualenv:
bash
VENV=/root/.espressif/python_env/idf4.1_py3.10_env
$VENV/bin/python -m pip install --upgrade pip
$VENV/bin/python -m pip install "setuptools<81" wheel
  • Runtime crash: assertion "netif" failed in esp_netif_create_default_wifi_sta Cause: duplicate default STA netif creation. Fix applied in:

    • firmware/freertos_apps/apps/esp32_controller/app.c
    • firmware/custom/esp32_controller/app.c

    If this reappears after syncing app sources, ensure Wi-Fi init runs once and esp_netif_create_default_wifi_sta() is not called multiple times.

  • Wi-Fi behavior on mobile hotspots If connection is unstable, force hotspot to 2.4 GHz WPA2 and disable battery-saving/idle sleep on the phone.

  • Wokwi simulator starts but no logs are visible Usually caused by stale build artifacts or viewing the wrong panel. Rebuild firmware, restart simulation, and check VS Code Output -> Wokwi.

Project Layout

  • src: ROS 2 packages
  • firmware/custom/esp32_controller: app source
  • firmware/freertos_apps/microros_esp32_extensions: generated ESP-IDF project
  • firmware/mcu_ws: micro-ROS cross-compiled workspace
  • docs: Sphinx documentation

References (Books and Research Papers)

  • Mahony, R., Hamel, T., and Pflimlin, J.-M. (2008). Nonlinear Complementary Filters on the Special Orthogonal Group. IEEE Transactions on Automatic Control, 53(5), 1203-1218.
  • Madgwick, S. O. H. (2010). An efficient orientation filter for inertial and inertial/magnetic sensor arrays. University of Bristol, Technical Report.
  • Thrun, S., Burgard, W., and Fox, D. (2005). Probabilistic Robotics. MIT Press.
  • Siciliano, B., Sciavicco, L., Villani, L., and Oriolo, G. (2009). Robotics: Modelling, Planning and Control. Springer.
  • Astrom, K. J., and Murray, R. M. (2008). Feedback Systems: An Introduction for Scientists and Engineers. Princeton University Press.

Parts

12
QtyValueFootprintReferences
4Screw_Terminal_01x02TerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1,5-2-5.08_1x02_P5.08mm_HorizontalJ1, J2, J5, J6
2TB6612FNGPackage_SO:SSOP-24_5.3x8.2mm_P0.65mmU2, U3
2~Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalU6, U8
1ESP32-WROOM-32RF_Module:ESP32-WROOM-32U1
1HC-SR04Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_VerticalU4
1MPU-6050Sensor_Motion:InvenSense_QFN-24_4x4mm_P0.5mmU5
1Motor_ServoConnector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_VerticalM1

Questions

How big is the Wall e PCB?

It measures 111.5 × 102 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Wall e use?

12 parts, built around the ESP32-WROOM-32, HC-SR04 and MPU-6050. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Wall e KiCad files?

From the c-lydia/ESP-ROS2 repository on GitHub, at the commit this page was made from: the board is pcb/wall_e_pcb_v1.0/wall_e.kicad_pcb and its schematic pcb/wall_e_pcb_v1.0/wall_e.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Wall e design in my own project?

Its repository publishes it under the Apache-2.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 2 layers99.5 × 99.5 mmSchematicKiCadProyect, the printed circuit board in 3D

    SchematicKiCadProyect

    dduarteCE/Robot-vacuum

    Embedded Linux robotic vacuum system built with Yocto on Raspberry Pi 4, featuring autonomous navigation, audio playback, and remote control through a web interface.

    42 parts1MIT
  • 2 layers95.8 × 90.7 mmSAM, the printed circuit board in 3D

    SAM

    dvmbnks/SAM-ROBOT-CONTROLLER

    This versatile printed circuit board is designed to seamlessly integrate and control various robot parts, providing a centralized hub for efficient and precise robotics operation.

    27 parts
  • 2 layers300 × 300 mmNew file, the printed circuit board in 3D

    New file

    takeyamayuki/RCJ_Kanto_Soccer2017_Board

    Board data of Team NTK that participated in the RoboCup Junior 2017 Kanto Tournament

    158 partsMIT
  • 2 layers109.2 × 86.4 mmÖntözőberendezés, the printed circuit board in 3D

    Öntözőberendezés

    CITROMOSEPER/4-zone-irrigation-system-2026-TDK-Project

    Négyzónás, ESP32-alapú adatvezérelt öntözőrendszer: érzékelők és időjárás-előrejelzés alapján dönt a vízadagról, három üzemmóddal, telefonos webes felülettel és biztonsági réteggel. TDK-projekt, Óbudai Egyetem, 2026.

    59 parts1MIT
  • 2 layersSensor fusion module, the printed circuit board in 3D

    Sensor fusion module

    Faizul6/sensor-fusion-module

    A miniaturized multi-sensor module that combines distance, motion, vibration, and light sensing into a single environment-awareness output — designed and documented like a real inspection-robot sensor module…

    6 parts
  • 2 layers90 × 94 mmESP32 Radar System, the printed circuit board in 3D

    ESP32 Radar System

    yagiz-bas/ESP32-Smart-Target-Detection-System

    A compact ESP32-based target detection and alarm system using an HC-SR04 ultrasonic sensor, an SG90 servo, an SSD1306 OLED display, a buzzer, and a red LED.

    7 parts