AutoNav-ROS: Autonomous Mobile Robot Navigation
Building production-grade autonomous navigation from scratch—differential drive kinematics, SLAM mapping, and PID control on Jetson Nano hardware running ROS Melodic.
ShareThe Challenge
When you write rosrun teleop_twist_keyboard teleop_twist_keyboard.py and watch a robot obediently follow your commands, it feels like magic. But what's actually happening between your keypress and the motor spinning? How does the robot know where it is? How does it build a map of an unknown environment?
This project strips away the abstractions. No navigation stacks, no pre-built controllers—just raw ROS nodes, differential drive mathematics, and an RPLidar sweeping 360 degrees at 10Hz. The goal: build autonomous navigation capabilities from first principles on real hardware.
System Architecture
The system runs on NVIDIA Jetson Nano (4GB, quad-core ARM Cortex-A57), providing just enough compute for real-time SLAM while maintaining a tight control loop at 50Hz. The hardware stack centers on a Yahboom ROSMASTER X1 differential drive platform with:
- RPLidar A3: 360° laser scanner providing 16,000 samples/second at 0.2° angular resolution, detecting obstacles up to 25 meters
- STM32 Motor Controller: Hardware-level PID control for wheel velocities, interfacing via UART at 115200 baud
- MPU6050 IMU: 6-DOF accelerometer/gyroscope for orientation tracking and odometry correction
- Wheel Encoders: Quadrature encoders (1024 PPR) providing 0.1mm positional resolution
Differential Drive Kinematics
At the heart of mobile robotics lies the kinematic model—the mathematical relationship between wheel velocities and robot motion. For a differential drive system, forward kinematics compute robot velocity from wheel speeds:
v = (v_left + v_right) / 2
ω = (v_right - v_left) / wheelbase
The inverse problem—computing required wheel velocities for a desired robot motion—is equally critical for path following. I implemented these transformations in a custom ROS node that subscribes to /cmd_vel (geometry_msgs/Twist) and publishes motor commands at 50Hz, ensuring smooth trajectories even during aggressive maneuvers.
The real challenge emerges in odometry integration. Dead reckoning accumulates error quadratically with distance—wheel slip on carpet, encoder discretization, and IMU drift compound over time. The solution: sensor fusion with particle filters, estimating pose by combining wheel odometry, IMU data, and laser scan matching against known landmarks.
SLAM: Building Maps from Uncertainty
Simultaneous Localization and Mapping (SLAM) solves the chicken-and-egg problem: you need a map to localize, but you need to know your location to build a map. The gmapping algorithm uses a Rao-Blackwellized particle filter to maintain multiple hypotheses of robot trajectory, updating probability distributions as new laser scans arrive.
Each particle represents a possible world state—a robot pose and corresponding map. As the robot moves, particles that align well with sensor observations gain weight, while inconsistent hypotheses die off. The result: a 2D occupancy grid where each cell stores probability [0, 1] of containing an obstacle.
Practical challenges emerged immediately. RPLidar A3 produces dense scans (16K points/rotation), overwhelming the particle filter. Downsampling to 720 rays (0.5° resolution) reduced computation by 95% while retaining sufficient detail for corridor navigation. Tuning particle count (30) balanced accuracy against real-time performance—too few particles and the filter diverges in symmetric environments; too many and latency kills the control loop.
PID Navigation: Closing the Loop
With pose estimation and mapping solved, the final piece is control—steering the robot to desired waypoints. A cascaded PID (Proportional-Integral-Derivative) controller minimizes both position error and heading error simultaneously:
- Proportional term: Provides control effort proportional to current error (distance to goal)
- Integral term: Accumulates past error, eliminating steady-state bias from motor asymmetry
- Derivative term: Damps oscillations by predicting error trajectory, preventing overshoot
Tuning PID gains required systematic experimentation. Starting with Ziegler-Nichols, I empirically adjusted coefficients: K_p = 1.2, K_i = 0.05, K_d = 0.8 for the distance controller; K_p = 2.5, K_i = 0, K_d = 0.3 for heading. Anti-windup clamping prevented integral term saturation during long-duration errors (e.g., blocked paths).
The system achieves ±5cm position accuracy in controlled environments, degrading to ±15cm with wheel slip on low-friction surfaces. Typical goal-seeking time: 8 seconds for 3-meter straight-line paths, 15 seconds for 90° turns with position hold.
From Gazebo to Reality
Simulation accelerates development but introduces a dangerous trap: algorithms that work perfectly in Gazebo often fail catastrophically on real hardware. Reasons:
- Perfect sensors: Simulated LiDAR has no noise, no multi-path reflections, no minimum range limitations
- Instantaneous actuation: Motors respond immediately in simulation; real motors have inertia, backlash, and voltage sag
- Infinite compute: Simulation runs faster than real-time; hardware must meet hard real-time deadlines
- Frictionless motion: Gazebo's default physics ignore carpet texture, floor tilt, and cable drag
Bridging the sim-to-real gap required sensor noise injection, motor delay modeling, and aggressive computational optimization. I replaced floating-point math with fixed-point where possible, vectorized matrix operations with NumPy, and implemented predictive control to compensate for 40ms actuator lag.
Results & Impact
The final system successfully demonstrates autonomous navigation in constrained indoor environments. Key achievements:
- Real-time Performance: SLAM updates at 10Hz, odometry at 50Hz, control loop at 50Hz—all on Jetson Nano
- Robust Mapping: Successfully maps 20m × 15m office space with <5% error vs. ground truth floor plan
- Autonomous Goals: Navigates to user-specified waypoints with 95% success rate in obstacle-free paths
- Dynamic Obstacles: Reactively stops when LiDAR detects obstacles within 0.5m safety radius
This project serves as course material for ECG711 (Embedded Systems for Automation), providing students with hands-on experience in robotics middleware, sensor integration, and control theory. The modular architecture allows incremental learning—students progress from differential drive simulation to full SLAM deployment over a semester.
Technical Resources
Full source code, ROS launch files, and hardware calibration scripts are available on GitHub:
Key components include:
differential_drive_sim.py— Kinematic model and Gazebo integrationpid_navigator.py— Waypoint controller with tuned PID gainsslam_mapping.launch— Complete SLAM pipeline with gmapping configurationhardware_calibration.py— Encoder calibration and IMU offset correction