Step-by-Step Guide to Building a Low-Cost Autonomous Delivery Robot with Open-Source AI
Why does a delivery robot matter today? Cities are getting crowded, labor costs are rising, and people want fast, contact‑free service. A small robot that can zip packages from a store to a doorstep can cut traffic, lower emissions, and give local makers a chance to experiment with real‑world AI. Below is a hands‑on plan that I have used in my own workshop and in a few university labs. All the parts are cheap, the software is free, and the result is a robot that can navigate a hallway or a campus path on its own.
What You Need – Parts List
Mechanical chassis
- Two 12 V DC geared wheels (12 mm diameter works well)
- One caster wheel for balance
- Aluminum extrusion frame (2020 profile, 4 ft total length)
- 3D‑printed mounts for sensors (PLA is fine)
Electronics
- Raspberry Pi 4 (4 GB) – the brain
- Arduino Nano – handles low‑level motor control
- Motor driver board (L298N or similar)
- 12 V Li‑ion battery pack (10 Ah)
- Power distribution board (optional but tidy)
Sensors
- 2× 2‑D LiDAR units (e.g., RPLIDAR A1) for mapping
- 1× Pi Camera v2 for visual detection
- 2× ultrasonic range finders for obstacle avoidance at low speed
Software
- ROS Noetic (Robot Operating System) – runs on the Pi
- Open‑source navigation stack (move_base, gmapping)
- Tiny‑YOLO or MobileNet for simple object detection
- Python 3 for glue code
All of these items can be bought for under $250 if you shop on discount sites or reuse parts from old toys.
Step 1 – Build the Physical Base
Start with the aluminum extrusion. Cut four pieces to form a rectangle about 30 cm long and 20 cm wide. Use the corner brackets that come with the profile to lock them together. Attach the two driven wheels to the front corners and the caster to the rear. The caster lets the robot turn smoothly without extra steering code.
Next, mount the motor driver on the frame. Connect the motor leads to the driver, then wire the driver to the Arduino Nano. The Arduino will receive speed commands from the Pi over a simple serial link and drive the wheels with PWM (pulse‑width modulation). I like to keep the Arduino code tiny – just a loop that reads two bytes (left and right speed) and sets the motor outputs.
Step 2 – Wire the Power System
The 12 V battery feeds the motor driver directly. For the Pi and Arduino, step the voltage down to 5 V using a buck converter. Keep all grounds common – a single ground point avoids strange voltage offsets that can cause the robot to jitter.
Add a power switch that cuts the battery before you plug in the Pi. This protects the SD card from sudden power loss, a problem I learned the hard way when a prototype rolled off a table.
Step 3 – Install the Operating System and ROS
Flash Raspberry Pi OS (Lite) onto a 32 GB micro‑SD card. After the first boot, run:
sudo apt update
sudo apt install ros-noetic-ros-base
Follow the ROS installation guide to set up the environment variables. I keep a small script called setup_ros.sh that sources the ROS setup file and adds my workspace to the path. This makes it easy to start new nodes later.
Step 4 – Connect Sensors
Mount the LiDAR on the front of the robot, angled slightly downward so it can see the floor and nearby obstacles. Connect it to the Pi via USB. The Pi Camera goes on the top plate, looking straight ahead. The ultrasonic sensors attach to the side brackets and hook up to the Arduino’s analog pins.
In ROS, each sensor publishes a topic:
/scanfor LiDAR data/camera/image_rawfor camera frames/ultrasonic_leftand/ultrasonic_rightfor range readings
You can verify they work with rostopic echo /scan and rosrun rqt_image_view rqt_image_view.
Step 5 – Build the Mapping and Navigation Stack
First, let the robot drive around a small area (a hallway or a lab bench) while the LiDAR records data. Run the gmapping node to create a 2‑D occupancy grid map. Save the map with rosrun map_server map_saver -f my_map.
Now launch move_base, which combines the map, the robot’s pose, and a planner that decides how to get from point A to point B. The default configuration works for most indoor spaces, but you may need to tune the inflation_radius (how close the robot can get to walls) and the max_vel_x (top speed). I keep these values in a YAML file called my_params.yaml for easy tweaking.
Step 6 – Add Simple Object Detection
For a delivery robot, you might want to recognize a mailbox or a drop‑off spot. Install Tiny‑YOLO, a lightweight neural network that runs on the Pi’s CPU in real time. Train it on a few dozen pictures of your target objects – the process takes less than an hour on a laptop.
Create a ROS node that grabs frames from /camera/image_raw, runs them through Tiny‑YOLO, and publishes a detection message. When the robot sees a “mailbox” label with confidence above 0.7, it can stop and wait for a human to place a package.
Step 7 – Write the High‑Level Control Script
Now you have all the pieces: motor driver, sensor streams, map, and detection. Write a Python script that does the following:
- Load the saved map.
- Accept a delivery destination (x, y) from the command line.
- Send a navigation goal to
move_base. - While moving, monitor the ultrasonic sensors; if an object is closer than 10 cm, send a stop command.
- When the camera node reports a mailbox detection, halt, flash an LED, and wait 10 seconds before continuing.
The script uses ROS services move_base/goal and move_base/cancel. It also publishes speed commands to the Arduino over serial. Keep the loop rate at 10 Hz – fast enough for smooth motion but gentle on the Pi’s CPU.
Step 8 – Test, Tune, and Deploy
Start with a short run: set the goal a few meters away, watch the robot plot a path on RViz (the ROS visualizer), and observe how it reacts to obstacles. If it drifts too close to walls, increase the inflation radius. If it stalls often, raise the max velocity a bit.
Once the basic navigation is reliable, add a small payload – a box of books or a coffee mug. Test the robot on a real delivery route: from a kitchen counter to a front door. You’ll notice that the LiDAR helps it avoid chairs, while the ultrasonic sensors catch low‑lying obstacles like a dropped towel.
Tips and Tricks from My Lab
- Reuse old parts: I once salvaged a toy car’s motor and it worked fine with a driver board. It saved $15.
- Cable management matters: A tidy bundle of wires prevents the robot from tripping over its own cords when it turns sharply.
- Keep the software modular: Each sensor runs in its own ROS node. If a sensor fails, the rest of the system keeps running.
- Document everything: I keep a simple markdown log of each change. When a bug appears, the log tells me exactly what was altered last.
Where to Go From Here
Now you have a functional delivery robot that runs on open‑source AI. You can expand it by adding GPS for outdoor work, a speech interface for voice commands, or a small gripper to pick up parcels automatically. The beauty of open‑source is that the community will already have many of these modules ready to plug in.
If you enjoy tinkering, consider joining the Robo Frontier community on the Logzly site. Sharing your builds helps everyone move the frontier of low‑cost automation forward.
- → How to Choose the Right Linear Motion Actuator for Your DIY Robotics Project @precisionmotionhub
- → Choosing the Right Precision Bearings for DIY Robotics: A Practical Engineer's Guide @sphericalwashers
- → DIY Low‑Cost Universal Joint for Your Robotics Kit @jointmechanics
- → How to Build a Self‑Balancing Robot with Arduino and Free Sensors @arduinoinnovator
- → Step-by-Step Guide to Building a Safe, Portable Electromagnet for Hobby Robotics @magnetcrafts