Autonomous Wheeled Mobile Robot (WMR)
Overview
An omnidirectional Autonomous Wheeled Mobile Robot (WMR) built as a major final-year engineering project. Programmed in bare-metal C++ on the Raspberry Pi Pico W (RP2040) using the Pico SDK, the system operates on a dual-core architecture to prevent execution latency between communication tasks and the hardware control loop.
The robot features holonomic locomotion using Mecanum wheels in an X-configuration, driven by four high-torque geared DC motors with Hall-effect encoder feedback. It utilizes Time-of-Flight (ToF) distance sensing for obstacle avoidance, an 8-channel infrared reflectance sensor array for line-following, and is controlled remotely via a low-latency custom WebSocket server.
A custom Kotlin-based companion Android application built with Jetpack Compose provides manual teleoperation (buttons, joystick, and tilt modes), real-time parameter tuning (PID gains and limits), and live telemetry dashboard logging.
Locomotion & Kinematics
Mecanum Drive Configuration
To achieve full holonomic movement, the robot utilizes a **four-wheel Mecanum drive in an X-configuration**. This configuration grants three degrees of freedom (), allowing the chassis to translate laterally, move longitudinally, and rotate concurrently.
By aligning the wheels symmetrically, the diagonal rollers generate independent force vectors that resolve into holonomic translation. This omnidirectional capability helps the robot perform fine spatial adjustments while tracking line guide curves or navigating through tight environments.
Mecanum Kinematics Model
Inverse kinematics maps target robot velocities () into individual wheel angular speeds. Calculations run at 100Hz on Core 1 based on wheel radius , longitudinal wheelbase , and track width .
Custom Mechanical Assembly
Chassis Plate CAD Model
The custom square base plate chassis was designed inside SolidWorks to balance center of mass, weight distribution, and sensor clearance. It defines precise coordinates for brackets, boards, and wheel slots.
Laser Cut DXF Design
The SolidWorks chassis layout was exported to a 2D DXF vector drawing containing dimension cuts and mounting holes. This file was then used to laser cut the physical base shape from a 3mm thick acrylic sheet, securing assembly tolerances.
Motor - Geared Wheel Coupler
Bridging the 3mm N20 motor D-shaft to the hexagonal hub of the 80mm Mecanum wheels posed a mechanical interfacing challenge. Standard parts did not accommodate the small motor shaft diameter with the larger wheel hub size.
Custom coupling adapters were modeled and 3D printed with 100% infill in PETG to maximize shear and torsional strength. The section view details how the hex-profile key locks directly into the wheel center to prevent rotational slip during acceleration.
Coupler 3D Model
Isometric view of the custom 3D printed coupler model before assembly into the Mecanum wheel hexagonal center hub.
Wheel Assembly Exploded View
Exploded assembly CAD drawing showing the mounting stack: the N20 motor chassis bracket, output D-shaft, 3D printed coupler, wheel slot clearance, and Mecanum wheel hub.
Assembled ToF Mount
To mount the four VL53L0X Time-of-Flight sensors orthogonally at each boundary of the chassis plate (front, rear, left, right), custom L-brackets were designed and 3D printed.
ToF Mount Exploded View
These mounts keep the sensor boards secured at a consistent height and provide mechanical protection from collisions, while maintaining an unblocked field of view for the laser ranging sensors.
Obstacle Detection ToF
The VL53L0X Time-of-Flight (ToF) sensor measures distances in millimeters by emitting pulsed infrared laser beams and measuring the time taken for the light to bounce back. Operating at 3.3V, it offers a 3cm to 2m ranging distance with ±3% accuracy. It was selected over ultrasonic sensors for its high directional accuracy and compact footprint, and multiple units are sequentially addressed on the I2C0 bus on boot.
Orientation: MPU9250 IMU
The MPU9250 is a 9-axis MotionTracking sensor containing a 3-axis gyroscope, 3-axis accelerometer, and an internal AK8963 3-axis magnetometer. Running over I2C at 3.3V, it provides raw angular rates and acceleration measurements. The yaw calculation is used for heading estimation and coordinate rotation to enable the holonomic tilt drive and field-centric control modes.
Line Following: QTR-8RC
The QTR-8RC is an 8-channel reflective infrared sensor array designed for high-resolution line tracking. It operates at 3.3V–5.0V with a 100mA current draw. Rather than outputting analog voltages, it uses a digital capacitor-decay mechanism: the Pico W charges the sensor line and measures the decay time via digital input pins, indicating surface reflectivity with high resolution.
Actuators
Closed-Loop Geared Propulsion
Propulsion is driven by four high-torque geared micro N20 motors rated at 6V with a metal spur gearbox (1:30 gear ratio), achieving 300 RPM output speed. They provide sufficient torque for holonomic translation and high rotational speeds.
The encoder feedback is processed via dedicated hardware interrupts to calculate current wheel velocities, enabling closed-loop speed control through PID velocity tuning.
Encoder Connection Schematic
Each motor has a built-in Hall-effect encoder outputting 7 pulses per revolution (PPR) at the motor shaft, resulting in 210 PPR (or ~280 PPR depending on quadrature transition modes) at the output shaft. Pinout lines include motor power (M1, M2), sensor power (VCC, GND), and quadrature Phase A/B channels routed to Core 1 interrupts.
System Control & Logic Expanders
Dual-Core Control & GPIO Expansion
A Raspberry Pi Pico W board coordinates all system actions, utilizing the RP2040 chip's dual-core capability. To handle the high quantity of digital signals needed for motor control, direction, and encoders, an MCP23017 GPIO expander module was integrated.
Communicating over I2C, the MCP23017 manages slow-changing digital outputs (such as motor direction toggles and status lines), saving the Pico W's native GPIO pins for timing-sensitive encoder interrupts.
MCP23017 Expander Module
The MCP23017 is a 16-bit general-purpose I/O expander operating over I2C (up to 400kHz). It handles slow-changing digital outputs (such as motor direction toggles and status lines), saving the Pico W's native GPIO pins for timing-sensitive encoder interrupts.
Drivers & Multiplexers
Motor drive current is handled by the TB6612FNG Dual Driver module (*left*), delivering 1.2A continuous (3.2A peak) current per channel with ~90% efficiency. Sequential addressing and line control for the ToF sensors are handled through the I2C Multiplexer module (*right*).
Power Architecture
Regulation & Charging Safety
The power system is designed around two Samsung 18650 Li-ion cells (*right*) providing 3500mAh nominal capacity and high discharge curves. A 2S 20A BMS board (*left*) safeguards the cells from overcharge, over-discharge, and short circuits. An adjustable MP1584 buck converter (*second from left*) steps down the battery pack voltage to 5.0V with up to 3A output and 92% efficiency, powering logic modules with low voltage ripple.
Dual-Core Firmware & Control Loops
Real-Time Communication Isolation
The firmware splits tasks between the RP2040 chip's two cores. Core 0 manages Wi-Fi SoftAP networking and the WebSocket server, communicating with the Android app.
Core 1 runs a real-time 100Hz control loop handling kinematics, encoders, PID, and safety filters. Cores communicate using thread-safe shared RAM with a snap-shot mechanism, preventing networking delays from blocking the control loop.
Line Following Controller
PID control evaluates guide track deviation from IR data. To avoid steering oscillations on sharp turns, a derivative-on-measurement filter is used. If lost, the robot spins in place in the direction of the last known error.
Wall Following Controller
Wall following uses ToF range scans and runs on a Proportional (P-only) loop. Forward speed is reduced to accommodate the slower ToF update rate (20Hz) and prevent chassis oscillations.
Android Companion App
Kotlin & Jetpack Compose Teleoperation Client
A custom-designed Android app, written in Kotlin with Jetpack Compose, acts as the robot control dashboard. The app establishes a WebSocket connection over the robot's local Wi-Fi SoftAP (exposing a server at `192.168.4.1:80`).
The dashboard integrates a multi-tab interface: Control (buttons/joysticks/tilt), Meters (decay timings and speed), Telemetry (proximity radar HUD and speed curves), and Config (limit thresholds and motor speed loop coefficients).
Manual Inputs Mode
Manual control screens support virtual joysticks and tilt drives, streaming motion command vectors with low latency to Core 0.
Real-Time Configuration
Closed-loop PID coefficients (Kp, Ki, Kd) can be adjusted via slider inputs and uploaded live to adapt the robot dynamics to different surfaces.
Subsystem Budget & Sourcing
Cost Distribution and Material Sourcing
The total project cost was kept within **LKR 29,050**, utilizing standard microcontrollers and modular sensors to manage development budget constraints.
Actuators (the four micro N20 encoder motors and wheels) comprised the largest subsystem cost at **49.9%** of the budget, while control components (Pico W and I2C accessories) were kept to **13.4%**. Power modules (comprising Samsung 18650 batteries, charger circuits, and converters) accounted for **10.7%**, with structural acrylic materials and local fabrication costing the remaining portion.
Source Repositories
Pico W Firmware
The C++ Pico W firmware repository containing peripheral drivers, dual-core coordination logic, Shared RAM interfaces, and PID control structures.
Dependencies / Tech Stack
Modules & Components
Android Controller Application
The Kotlin companion application containing Compose screens, WebSocket network binding manager, and Moshi payload serializers.