Guide to Building an Indoor Delivery Rover: ROS2 Humble on a 4WD Acrylic Smart Chassis with Raspberry Pi 5
Building an Indoor Delivery Rover: ROS 2 Humble on a 4WD Acrylic Smart Chassis with Raspberry Pi 5
This step‑by‑step tutorial shows you how to turn a 4‑wheel‑drive acrylic smart chassis into a fully‑functional indoor delivery robot powered by ROS 2 Humble Hawksbill and a Raspberry Pi 5. We cover hardware assembly, wiring, software installation, ROS 2 node development, and real‑world testing—all written in present tense for easy follow‑along.
1️⃣ Parts & Tools
| Item | Quantity | Notes |
|---|---|---|
| Acrylic Smart Chassis (4WD, 300 mm × 300 mm) | 1 | Includes motor mounts & caster |
| DC Gear Motors (12 V, 30 RPM) | 4 | Compatible with motor driver board |
| Motor Driver (DRV8833 Dual H‑Bridge) | 1 | Handles up to 1.5 A per channel |
| Raspberry Pi 5 (4 GB) with 32 GB microSD | 1 | Latest SBC, 2.4 GHz/5 GHz Wi‑Fi |
| Power Distribution Board (5 V / 12 V buck‑boost) | 1 | Provides stable 5 V for Pi & sensors |
| Li‑Po Battery (2S 7.4 V, 4000 mAh) | 1 | Mounted on chassis rear |
| Jumper Wires, Heat‑Shrink, Screwdriver Set | – | Essential for wiring |
| Optional Sensors (Lidar, IMU, Camera) | – | Add later for navigation |
2️⃣ Chassis Assembly & Wiring
Mount the Motors
Secure each motor into the pre‑drilled holes using M3×8 mm screws. Align the motor shafts toward the chassis center to keep the robot balanced.
Attach the Motor Driver
Place the DRV8833 board on the chassis mounting plate. Connect each motor’s two wires to the driver’s A1/A2 and B1/B2 terminals. Remember to keep the polarity consistent for forward motion.
Power Distribution
Connect the Li‑Po battery to the 12 V input of the distribution board. From the board, feed 12 V to the motor driver and 5 V to the Raspberry Pi 5 via the buck‑converter module.
Run the wiring neatly along the chassis channels. Use heat‑shrink tubing on all exposed solder joints to avoid short circuits. Finally, mount the Raspberry Pi 5 on the top side of the chassis using the included standoff kit.
Tip: Verify motor polarity before plugging the battery in. A quick test of ros2 topic echo /cmd_vel (once ROS is up) tells you if the wheels spin in the expected direction.
3️⃣ Raspberry Pi 5 & ROS 2 Installation
3.1 Flash Ubuntu 22.04 (Jammy)
ROS 2 Humble officially supports Ubuntu 22.04. Use Balena Etcher to flash the .img file onto the 32 GB microSD.
# Download Ubuntu Server
wget https://cdimage.ubuntu.com/releases/22.04/release/ubuntu-22.04-live-server-arm64.iso
# Burn with Etcher (GUI) or dd (CLI)
sudo dd if=ubuntu-22.04-live-server-arm64.iso of=/dev/sdX bs=4M status=progress conv=fsync
3.2 First‑Boot Configuration
- Log in with the default
ubuntuuser (passwordubuntu). - When prompted, change the password.
- Run
sudo apt update && sudo apt upgrade -yto bring the system up‑to‑date. - Enable SSH:
sudo systemctl enable ssh && sudo systemctl start ssh.
3.3 Install ROS 2 Humble
Follow the official ROS 2 installation steps, trimmed for Raspberry Pi 5.
# Setup sources
sudo apt update && sudo apt install -y curl gnupg lsb-release
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=arm64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
# Install ROS 2 packages
sudo apt update
sudo apt install -y ros-humble-ros-base ros-humble-rclcpp ros-humble-geometry-msgs
# Source the setup script automatically
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc
3.4 Install Additional Packages
For motor control we use the ros2_control and ros2_controllers packages.
sudo apt install -y ros-humble-ros2-control ros-humble-ros2-controllers
Optional: ros-humble-rplidar-ros for later SLAM integration.
4️⃣ Writing ROS 2 Nodes for Mobility
4.1 Create a Workspace
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build
source install/setup.bash
4.2 Motor Driver Python Node
This node subscribes to /cmd_vel (geometry_msgs/Twist) and converts linear/angular velocity into PWM signals for the DRV8833 board using the pigpio library.
# ~/ros2_ws/src/rover_motor/rover_motor/motor_node.py
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
import pigpio
class MotorNode(Node):
def __init__(self):
super().__init__('motor_node')
self.sub = self.create_subscription(Twist, 'cmd_vel', self.cmd_callback, 10)
# GPIO pins (BCM numbering)
self.IN1 = 17 # Motor A forward
self.IN2 = 27 # Motor A reverse
self.IN3 = 22 # Motor B forward
self.IN4 = 23 # Motor B reverse
self.PWM_FREQ = 20000 # 20 kHz PWM
self.pi = pigpio.pi()
for pin in [self.IN1, self.IN2, self.IN3, self.IN4]:
self.pi.set_mode(pin, pigpio.OUTPUT)
self.max_pwm = 255 # 8‑bit duty cycle
def cmd_callback(self, msg):
# Simple differential drive conversion
linear = msg.linear.x # m/s
angular = msg.angular.z # rad/s
wheel_base = 0.15 # meters (distance between wheels)
wheel_radius = 0.035 # meters
# Desired wheel speeds (rad/s)
v_left = (linear - angular * wheel_base / 2.0) / wheel_radius
v_right = (linear + angular * wheel_base / 2.0) / wheel_radius
# Convert to PWM (clamp to [-max_pwm, max_pwm])
left_pwm = int(max(min(v_left * 20, self.max_pwm), -self.max_pwm))
right_pwm = int(max(min(v_right * 20, self.max_pwm), -self.max_pwm))
self.set_motor(self.IN1, self.IN2, left_pwm)
self.set_motor(self.IN3, self.IN4, right_pwm)
def set_motor(self, pin_fwd, pin_rev, pwm):
if pwm > 0:
self.pi.set_PWM_dutycycle(pin_fwd, pwm)
self.pi.set_PWM_dutycycle(pin_rev, 0)
elif pwm < 0:
self.pi.set_PWM_dutycycle(pin_fwd, 0)
self.pi.set_PWM_dutycycle(pin_rev, -pwm)
else:
self.pi.set_PWM_dutycycle(pin_fwd, 0)
self.pi.set_PWM_dutycycle(pin_rev, 0)
def main(args=None):
rclpy.init(args=args)
Comments
Post a Comment