Guide to Achieving Real-Time SLAM on an Akermann-Steering RC Car Conversion with Jetson Nano and LiDAR

Achieving Real‑Time SLAM on an Akermann‑Steering RC Car Conversion with Jetson Nano & LiDAR

Step‑by‑step tutorial for robotics hobbyists and developers

Introduction

Real‑time Simultaneous Localization and Mapping (SLAM) transforms a simple RC car into an autonomous explorer. This guide walks you through converting an Akermann‑steering RC car into a fully‑featured robot that runs SLAM on a NVIDIA Jetson Nano with a 360° LiDAR sensor. By the end of the tutorial you have a live map, pose estimation, and a responsive control loop running at 15 Hz+ on the edge.

Hardware Overview

Jetson Nano

Jetson Nano

Quad‑core ARM CPU, 128 CUDA cores, 4 GB LPDDR4 – ideal for GPU‑accelerated SLAM.

2D LiDAR

2D LiDAR (e.g., RPLIDAR A2)

360° scanning, up to 12 m range, 10 Hz rotation – provides dense point clouds for SLAM.

Akermann Steering RC Car

Akermann‑Steering RC Car

Independent wheel steering gives true Ackermann geometry, crucial for accurate odometry.

Software Stack

Layer Tool / Package Why?
Operating System Ubuntu 20.04 (JetPack 4.6) Optimized drivers for CUDA & hardware.
Middleware ROS 2 Foxylime (Humble Hawksbill) Real‑time communication, modular nodes.
SLAM Engine Cartographer (GPU‑accelerated) or LIO‑SAM Proven 2‑D/3‑D accuracy and good Jetson support.
Visualization RViz2 + Web‑based dashboard (React + socket.io) Live map view on laptop or tablet.

Step 1 – Setting Up Jetson Nano

  1. Flash JetPack 4.6 onto a 16 GB micro‑SD card (use NVIDIA SDK Manager).
  2. Boot the Nano, run sudo apt update && sudo apt upgrade -y.
  3. Install ROS 2 Humble:
    # Add the ROS 2 apt repository
    sudo apt install curl -y
    curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key | sudo apt-key add -
    sudo sh -c 'echo "deb http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2.list'
    sudo apt update
    # Install the full desktop package
    sudo apt install ros-humble-desktop -y
    
    # Source automatically
    echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
    source ~/.bashrc
  4. Enable the Jetson's UART for LiDAR communication:
    sudo systemctl stop serial-getty@ttyTHS1.service
    sudo systemctl disable serial-getty@ttyTHS1.service

Step 2 – LiDAR Integration

We use the rplidar_ros package for most 2‑D scanners. Replace rplidar with your device’s driver if needed.

2.1 Install the driver

cd ~/ros2_ws/src
git clone https://github.com/ros2/rplidar_ros.git -b humble
cd ..
colcon build --symlink-install
source install/setup.bash

2.2 Launch the LiDAR node

ros2 launch rplidar_ros rplidar.launch.py serial_port:=/dev/ttyTHS1 serial_baudrate:=115200
Tip: Verify the scan with ros2 topic echo /scan – you should see an array of range values.

Step 3 – Choosing a SLAM Algorithm

For 2‑D mapping the Jetson Nano handles Cartographer comfortably, but if you need 3‑D lidar‑inertial fusion, LIO‑SAM offers GPU‑accelerated performance.

3.1 Install Cartographer ROS2

sudo apt install ros-humble-cartographer ros-humble-cartographer-ros

3.2 Create a Cartographer config for the RC car

Copy the 2‑D example and edit the sensor topics.

cd ~/ros2_ws/src/cartographer_ros/cartographer_ros/configuration_files
cp my_robot_2d.lua my_akermann_car.lua

# Edit my_akermann_car.lua (excerpt)
TRAJECTORY_BUILDER_2D.use_imu_data = false
TRAJECTORY_BUILDER_2D.laser_scan_sensor = "scan"
POSE_GRAPH.optimize_every_n_nodes = 35

3.3 Launch the SLAM node

ros2 launch cartographer_ros cartographer.launch.py \
  configuration_directory:=$(pwd)/../configuration_files \
  configuration_basename:=my_akermann_car.lua \
  use_sim_time:=false

Step 4 – Calibration & Tuning

Accurate SLAM depends on precise wheel odometry and LiDAR‑to‑baseframe transforms.

4.1 Compute wheel radius & steering offset

  1. Mark a reference point on the wheel.
  2. Rotate the wheel exactly one full turn.
  3. Measure linear distance d traveled – radius r = d / (2π).

4.2 Publish odometry

# odom_publisher.cpp (excerpt)
rclcpp::Publisher::SharedPtr odom_pub_;
double wheel_radius = 0.032; // meters (measured)

void publish_odom()
{
  auto msg = nav_msgs::msg::Odometry();
  msg.header.stamp = now();
  msg.header.frame_id = "odom";
  msg.child_frame_id = "base_link";

  // Simple differential kinematics for Akermann car
  double v = wheel_radius * (left_wheel_rpm + right_wheel_rpm) / 2.0;
  double steering_angle = steering_servo_angle * (M_PI/180.0);
  double omega = v * tan(steering_angle) / L; // L = wheelbase

  // Update pose (integrate)
  // … (use a EKF or simple pose integration)

  odom_pub_->publish(msg);
}

4.3 TF tree verification

ros2 run tf2_ros tf2_echo /base_link /laser

Check that the laser origin aligns with the physical sensor—adjust the static_transform_publisher parameters if needed.

Ready to Start?

Become Part of the ICT Club Community

Many learners are already building the technology skills that improve their daily work performance. Your journey starts today.