Autonomous scale-model vehicle control stack with lane-keeping based on ROS and Deep Learning
Team Leader: Bui Minh Cuong (Michael)
For the Vietnamese version of this document, please see README_VN.md.
| Scale Model Autonomous Car | Development Workspace |
![]() |
![]() |
Note
This project is open-source and no longer intended for commercial use. It serves as an academic and research reference for developing scale-model autonomous vehicles using Robot Operating System (ROS) and Deep Learning models on embedded platforms (Raspberry Pi & Arduino/Nucleo).
This repository contains the autonomous driving stack developed for the Bosch Future Mobility Challenge (BFMC) 2024 & 2025, currently ranked Top 15 in the world.
In 2024, due to unforeseen visa complications, the team from Vietnam was unable to travel to Romania for the physical finals. In response, we chose to release our complete codebase as open-source for the research community and robotics enthusiasts worldwide.
Furthermore, scale-model autonomous vehicles based on this platform were successfully commercialized for research institutes and educational purposes, generating approximately $4,000 USD in revenue.
graph TD
%% Sensors to Input Nodes
Cam[Camera Module] -->|Raw Video| CamNode[cameraNODE.py / Open CV]
IMU_HW[BNO055 IMU via I2C] -->|Raw Orientation| IMUNode[imuNODE.py]
Sonar_HW[Ultrasonic Sensors] -->|Echo Distance| SonarNode[sonarNODE.py / latead]
GPS_HW[GPS Receiver] -->|Coordinates| GPSNode[gpstrackerNODE.py]
%% Input Nodes to ROS topics
CamNode -->|/camera/image_raw| ImageTopic[ROS: image_raw]
IMUNode -->|/automobile/IMU| IMUTopic[ROS: imu]
SonarNode -->|/automobile/sonar| SonarTopic[ROS: sonar]
GPSNode -->|/automobile/localisation| LocalTopic[ROS: localisation]
%% Brain/Decision Loop
ImageTopic -->|OpenCV Frame| MainCar[main_car.py / Autonomous Loop]
IMUTopic -->|State Feedback| MainCar
SonarTopic -->|Obstacle Dist| MainCar
LocalTopic -->|GPS Pos| MainCar
%% Deep Learning Models in Main Car
ONNX_Lane[lane_keeper_small.onnx] -->|e2, e3 errors| MainCar
ONNX_Sign[sign_classifier.onnx] -->|Traffic Sign Class| MainCar
ONNX_TL[trafficlight_classifier_small.onnx] -->|Light State| MainCar
ONNX_Obs[pedestrian_classifier_small.onnx] -->|Obstacle Class| MainCar
%% Decision to Output
MainCar -->|Target Speed & Steer| Controller[controller3.py / Pure Pursuit / PID]
Controller -->|Control Commands| DriveTopic[ROS: control cmd]
%% Output to MCU
DriveTopic -->|Serial Protocol| SerialNode[serialNODE.py]
SerialNode -->|USB Serial /dev/ttyACM0| MCU[Arduino / Nucleo MCU]
MCU -->|PWM Signals| Actuators[Motors & Steering Servo]
To run the vehicle successfully, establish all sensor and microcontroller connections according to the schematic below:
The system was tested on the official BFMC track layout with a local GPS localization map, lane markings, and traffic signs:
| Physical Track | Localization Map |
![]() |
![]() |
Autopilot_and_FSD/
βββ .catkin_workspace # ROS catkin configuration file
βββ LICENSE # License terms
βββ README.md # English system documentation (this file)
βββ README_VN.md # Vietnamese system documentation
βββ network_conf_auto.bash # Network configuration script
βββ assets/ # Images and diagrams
βββ src/
βββ action/ # High-level motion planning and maneuvers
β βββ src/action/ # Maneuver implementations (overtaking, parking, etc.)
βββ control/ # Low-level control interfaces and drivers
β βββ src/control/ # Car data and state machine interfaces
βββ input/ # Sensor interface nodes (Camera, IMU, GPS, Sonar, V2V)
βββ output/ # MCU communication and serial interfaces (C++ / Python)
βββ perception/ # Lane detection and computer vision package placeholders
βββ rosserial_python/ # ROS standard rosserial communication protocol package
βββ utils/ # Launch scripts, custom message/service definitions, requirements
β βββ launch/ # Launch configurations (*.launch)
β βββ msg/ # Custom message types (*.msg)
β βββ srv/ # Custom service types (*.srv)
β βββ requirements.txt # Python dependency file
βββ tests/
βββ lane_keeping_6_cv_camera/ # Main autonomous driving and lane-keeping demo
βββ models/ # Pre-trained ONNX and PyTorch weights
βββ main_car.py # Main execution loop
βββ detection.py # Deep learning inference pipeline (ONNX Runtime)
βββ controller3.py # Steering (Pure Pursuit) and speed controller
βββ maneuvers.py # Local maneuver planner
βββ automobile_data.py # ROS topic I/O manager
Download Raspberry Pi OS (Desktop or Lite version) from Raspberry Pi Software. Mount the image file to your SD card using Balena Etcher.
Create a wpa_supplicant.conf file at the root of the SD card (boot partition) to automatically connect to Wi-Fi on boot:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=VN
network={
ssid="YOUR_WIFI_SSID"
psk="YOUR_WIFI_PASSWORD"
}Create empty files named ssh, i2c, and camera in the boot partition of the SD card to enable these interfaces automatically.
# Add ROS Debian repository
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu buster main" > /etc/apt/sources.list.d/ros-noetic.list'
# Add official ROS key
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
# Update package lists
sudo apt-get update && sudo apt-get upgrade -y
# Install build dependencies
sudo apt-get install -y python-rosdep python-rosinstall-generator python-wstool python-rosinstall build-essential cmake python3-pip libopencv-dev python3-opencv
# Initialize rosdep
sudo rosdep init
rosdep updatemkdir -p ~/ros_catkin_ws
cd ~/ros_catkin_ws
# Generate ROS Lite packages list
rosinstall_generator ros_comm sensor_msgs cv_bridge --rosdistro noetic --deps --wet-only --tar > noetic-ros_comm-wet.rosinstall
wstool init src noetic-ros_comm-wet.rosinstall
# Optional: Increase swap space to 1GB to prevent compiler out-of-memory
sudoedit /etc/dphys-swapfile # Change CONF_SWAPSIZE=100 to CONF_SWAPSIZE=1024
sudo dphys-swapfile swapoff && sudo dphys-swapfile setup && sudo dphys-swapfile swapon
# Build and install ROS
sudo src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/noetic -j1 -DPYTHON_EXECUTABLE=/usr/bin/python3echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrcInstall the required Python packages using the requirements.txt located under src/utils/:
# Install system packages
sudo apt install -y libatlas-base-dev
# Install Python requirements
cd ~/Autopilot_and_FSD
pip3 install -r src/utils/requirements.txt
pip3 install numpy --upgradeFollow the Raspberry Pi setup from the RTIMULib repository to configure I2C for the BNO055 IMU sensor.
Use catkin_make to compile the entire ROS workspace:
cd ~/Autopilot_and_FSD
catkin_make
source devel/setup.bashRun the remote car launch configuration to start the sensors and controller interface:
roslaunch utils run_automobile_remote.launchOpen a new terminal, navigate to the demo directory, and execute the autonomous driving script:
cd ~/Autopilot_and_FSD/src/tests/lane_keeping_6_cv_camera
python3 main_car.pyModels are deployed as .onnx files in the folder src/tests/lane_keeping_6_cv_camera/models/:
| Model Name | Format | Task |
|---|---|---|
lane_keeper_small.onnx |
ONNX | Estimates lateral offset ( |
stop_line_estimator.onnx |
ONNX | Estimates the distance from the vehicle to the upcoming stop line. |
local_path_estimator.onnx |
ONNX | Estimates a sequence of local path waypoints to guide vehicle navigation. |
sign_classifier.onnx |
ONNX | Identifies 9 traffic sign classes: park, closed_road, highway_exit, highway_enter, stop, roundabout, priority, cross_walk, one_way. |
trafficlight_classifier_small.onnx |
ONNX | Detects and classifies the state of traffic lights (Green, Yellow, Red). |
pedestrian_classifier_small.onnx |
ONNX | Classifies frontal obstacles (pedestrian, roadblock, other vehicles). |
All copyrights belong to Duong Minh Ngoc Phat Corporation. Contact us for more details.
Copyright Β© 2024 Duong Minh Ngoc Phat Corporation. All Rights Reserved.




