Complete ROS 4WD Robot Guide — From Ubuntu to Xbox Controller

Complete ROS 4WD Robot Guide

From Ubuntu Installation to Keyboard & Xbox Controller Teleoperation

This is a crystal-clear, beginner-safe, end-to-end robotics guide. Follow every step in order and you will build a fully drivable ROS robot using a Raspberry Pi.


ROADMAP — WHAT YOU WILL BUILD

  1. Install Ubuntu 20.04 on Raspberry Pi
  2. Install & verify ROS Noetic
  3. Wire & test motors (without ROS)
  4. Create ROS motor driver node
  5. Keyboard teleoperation
  6. Xbox wireless controller teleoperation

DAY 1 — Ubuntu & ROS Noetic Setup

1. Enable SSH

sudo systemctl enable ssh
sudo systemctl start ssh
sudo systemctl status ssh

2. Update System

sudo apt update
sudo apt upgrade -y

3. Install ROS Noetic

sudo apt install software-properties-common -y
sudo add-apt-repository universe
sudo apt update
sudo apt install ros-noetic-desktop-full -y

4. Setup ROS Environment

echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc

5. Verify ROS

roscore

DAY 2 — Motor Wiring & Standalone Testing (NO ROS)

GPIO Mapping (Example: L298N)

  • ENA → GPIO18
  • IN1 → GPIO17
  • IN2 → GPIO27
  • ENB → GPIO13
  • IN3 → GPIO22
  • IN4 → GPIO23

Motor Test Script (motor_test.py)

#!/usr/bin/env python3
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

ENA, IN1, IN2 = 18, 17, 27
ENB, IN3, IN4 = 13, 22, 23

GPIO.setup([ENA, IN1, IN2, ENB, IN3, IN4], GPIO.OUT)

print("Moving Forward")
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)

time.sleep(2)
GPIO.cleanup()

Run Test

python3 motor_test.py

DAY 3 — ROS Motor Driver Node

Create ROS Package

cd ~/catkin_ws/src
catkin_create_pkg my_4wd_robot rospy geometry_msgs
cd ~/catkin_ws
catkin_make
source devel/setup.bash

Motor Driver Node (motor_driver_node.py)

#!/usr/bin/env python3
import rospy
from geometry_msgs.msg import Twist
import RPi.GPIO as GPIO

ENA, IN1, IN2 = 18, 17, 27
ENB, IN3, IN4 = 13, 22, 23

GPIO.setmode(GPIO.BCM)
GPIO.setup([ENA, IN1, IN2, ENB, IN3, IN4], GPIO.OUT)

def cmd_vel_callback(msg):
    lin = msg.linear.x
    ang = msg.angular.z

    if lin > 0:
        GPIO.output(IN1, GPIO.HIGH)
        GPIO.output(IN2, GPIO.LOW)
        GPIO.output(IN3, GPIO.HIGH)
        GPIO.output(IN4, GPIO.LOW)
    elif lin < 0:
        GPIO.output(IN1, GPIO.LOW)
        GPIO.output(IN2, GPIO.HIGH)
        GPIO.output(IN3, GPIO.LOW)
        GPIO.output(IN4, GPIO.HIGH)
    elif ang > 0:
        GPIO.output(IN1, GPIO.LOW)
        GPIO.output(IN2, GPIO.HIGH)
        GPIO.output(IN3, GPIO.HIGH)
        GPIO.output(IN4, GPIO.LOW)
    elif ang < 0:
        GPIO.output(IN1, GPIO.HIGH)
        GPIO.output(IN2, GPIO.LOW)
        GPIO.output(IN3, GPIO.LOW)
        GPIO.output(IN4, GPIO.HIGH)
    else:
        GPIO.output(IN1, GPIO.LOW)
        GPIO.output(IN2, GPIO.LOW)
        GPIO.output(IN3, GPIO.LOW)
        GPIO.output(IN4, GPIO.LOW)

rospy.init_node("motor_driver")
rospy.Subscriber("/cmd_vel", Twist, cmd_vel_callback)
rospy.spin()

Make Executable

chmod +x motor_driver_node.py

DAY 4 — Keyboard Teleoperation

Install Teleop Package

sudo apt install ros-noetic-teleop-twist-keyboard -y

Run Nodes (Correct Order)

# Terminal 1
roscore
# Terminal 2
rosrun my_4wd_robot motor_driver_node.py
# Terminal 3
rosrun teleop_twist_keyboard teleop_twist_keyboard.py

Keyboard Controls

  • W → Forward
  • S → Backward
  • A → Left
  • D → Right
  • X → Stop

DAY 5 — Xbox Wireless Controller (Bluetooth)

Pair Controller

bluetoothctl
power on
agent on
default-agent
scan on
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
connect XX:XX:XX:XX:XX:XX
quit

Verify Controller

ls /dev/input/js0
jstest /dev/input/js0

Headless pygame Fix

import os
os.environ["SDL_VIDEODRIVER"] = "dummy"

Run Xbox Teleop

rosrun xbox_teleop xbox_teleop_node.py

FINAL RESULT

  • ROS fully working
  • Motors respond correctly
  • Keyboard control stable
  • Xbox wireless control smooth

The robot now drives like butter.


NEXT UPGRADES

  • Deadman safety button
  • Speed modes
  • Launch files
  • Auto-start on boot

This guide documents a real debugging journey — not a copy-paste tutorial.

Comments