Skip to content

RuGG12/Autonomous-Mobile-Robot-Perception-Navigation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Autonomous Mobile Robot Perception & Navigation

ROS 2 License C++17

Production-grade ROS 2 navigation stack for Husarion ROSbot XL with Ouster OS1 3D LiDAR. Features high-performance C++ perception nodes, 2D/3D SLAM integration, and automated stability validation.


Key Features

Feature Implementation
Ouster OS1 Time Sync C++ timestamp_fixer_node - Zero-copy PointCloud2 processing
2D/3D Mapping SLAM Toolbox (2D) + Octomap Server (3D) running in parallel
Velocity Control C++ velocity_scaler_node - Configurable gain for motor tuning
Stability Validation C++ waypoint_looper_node - Automated waypoint loops with metrics
TF Bridge C++ odometry_bridge_node - Optional odom→base_link broadcast

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           LAPTOP (Navigation Station)                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ timestamp_fixer β”‚β†’ β”‚ pointcloud_to_  β”‚β†’ β”‚     SLAM Toolbox        β”‚  β”‚
β”‚  β”‚   (C++ Node)    β”‚  β”‚   laserscan     β”‚  β”‚   (2D Map + Localize)   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚           β”‚                                                              β”‚
β”‚           ↓                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ octomap_server  β”‚  β”‚     Nav2        β”‚β†’ β”‚   velocity_scaler       β”‚  β”‚
β”‚  β”‚  (3D Mapping)   β”‚  β”‚ (Path Planning) β”‚  β”‚     (C++ Node)          β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”˜
                                                                        β”‚
                              WiFi / ROS 2 DDS                          β”‚
                                                                        ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        HUSARION ROSBOT XL                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Ouster OS1     β”‚  β”‚ robot_localizationβ”‚ β”‚    Motor Drivers       β”‚  β”‚
β”‚  β”‚  (via Jetson)   β”‚  β”‚     (EKF)        β”‚  β”‚  ← /cmd_vel            β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Hardware Requirements

Component Model Purpose
Robot Platform Husarion ROSbot XL Mobile base with motor control
3D LiDAR Ouster OS1-64 360Β° point cloud perception
Coprocessor NVIDIA Jetson Ouster driver host
Workstation Ubuntu 22.04 Laptop Navigation, SLAM, visualization

See hardware_bom.md for detailed bill of materials.


Software Prerequisites

  • OS: Ubuntu 22.04 (Jammy)
  • ROS 2: Humble Hawksbill
  • C++ Standard: C++17
  • Python: 3.10+

Installation

1. Install ROS 2 Dependencies

sudo apt update
sudo apt install -y \
  ros-humble-navigation2 \
  ros-humble-nav2-bringup \
  ros-humble-slam-toolbox \
  ros-humble-pointcloud-to-laserscan \
  ros-humble-robot-localization \
  ros-humble-tf2-ros \
  ros-humble-octomap-server

2. Install Clearpath Packages

Follow the Clearpath Robotics Documentation for base configuration tools.

3. Clone and Build

# Clone repository
cd ~/ros2_ws/src
git clone https://github.com/RuGG12/Autonomous-Mobile-Robot-Perception-Navigation.git

# Install dependencies
cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -r -y

# Build (C++ and Python hybrid package)
colcon build --packages-select inspector --symlink-install
source install/setup.bash

Usage

Launch Full Navigation Stack

# Terminal 1: LiDAR Pipeline (C++ timestamp sync + 3D→2D conversion)
ros2 launch inspector lidar_converter.launch.py

# Terminal 2: Navigation + SLAM (C++ velocity scaler + Nav2 + SLAM Toolbox)
ros2 launch inspector clearpath_standard_demo.launch.py

Launch 3D Mapping (Optional)

# Runs Octomap server parallel to 2D SLAM
ros2 launch inspector 3d_mapping.launch.py

Run Stability Validation

# Automated waypoint loop testing with metrics logging
ros2 launch inspector waypoint_validation.launch.py loop_count:=10

# Check results
cat stability_log.txt

Package Structure

inspector/
β”œβ”€β”€ src/                              # C++ Source Files
β”‚   β”œβ”€β”€ timestamp_fixer_node.cpp      # PointCloud2 timestamp sync
β”‚   β”œβ”€β”€ velocity_scaler_node.cpp      # Velocity gain control
β”‚   β”œβ”€β”€ odometry_bridge_node.cpp      # Odomβ†’TF bridge
β”‚   └── waypoint_looper_node.cpp      # Stability validation
β”œβ”€β”€ launch/                           # Launch Files
β”‚   β”œβ”€β”€ lidar_converter.launch.py     # LiDAR pipeline
β”‚   β”œβ”€β”€ clearpath_standard_demo.launch.py  # Full nav stack
β”‚   β”œβ”€β”€ 3d_mapping.launch.py          # Octomap integration
β”‚   └── waypoint_validation.launch.py # Stability testing
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ nav2_params.yaml              # Navigation parameters
β”‚   └── waypoints.yaml                # Test waypoint coordinates
β”œβ”€β”€ CMakeLists.txt                    # C++ build configuration
└── package.xml                       # Package manifest

C++ Node Details

timestamp_fixer_node

Purpose: Fixes Ouster OS1 hardware clock mismatch (boot time ~700s vs system wall time)

ros2 run inspector timestamp_fixer_node \
  --ros-args -p input_topic:=/ouster/points -p output_topic:=/ouster/points_fixed

Features:

  • Zero-copy UniquePtr callback for high throughput
  • SensorDataQoS for reliable sensor data
  • Multi-threaded executor

velocity_scaler_node

Purpose: Applies configurable gain to velocity commands for motor response tuning

ros2 run inspector velocity_scaler_node \
  --ros-args -p scale_factor:=1.5

Parameters:

  • scale_factor (double, default: 1.5) - Velocity multiplier
  • input_topic (string, default: /cmd_vel_inspector)
  • output_topic (string, default: /cmd_vel)

odometry_bridge_node

Purpose: Broadcasts odom β†’ base_link TF from odometry messages

ros2 run inspector odometry_bridge_node \
  --ros-args -p publish_tf:=false

⚠️ Note: Set publish_tf:=false (default) when robot_localization EKF is running to prevent TF tree conflicts.


waypoint_looper_node

Purpose: Validates navigation stability via repeated waypoint loops

ros2 run inspector waypoint_looper_node \
  --ros-args --params-file config/waypoints.yaml

Output: Logs success/failure metrics to stability_log.txt:

Loop 1 | WP 0 | (0.00, 0.00) | SUCCESS | 2.34s
Loop 1 | WP 1 | (2.00, 0.00) | SUCCESS | 3.12s
...
SUMMARY:
Total Loops: 10 | Success Rate: 97.5%

Configuration

Navigation Tuning

Edit config/nav2_params.yaml:

  • Speed limits, acceleration
  • Costmap resolution and inflation
  • Goal tolerances

Waypoint Testing

Edit config/waypoints.yaml:

waypoint_looper:
  ros__parameters:
    waypoints:
      x: [0.0, 2.0, 2.0, 0.0]
      y: [0.0, 0.0, 2.0, 2.0]
      yaw: [0.0, 0.0, 1.57, 3.14]
    loop_count: 10

LiDAR Mounting

Update static transform in launch/lidar_converter.launch.py:

arguments=['x', 'y', 'z', 'roll', 'pitch', 'yaw', 'base_link', 'os_sensor']

Network Configuration

All devices must be on the same network with matching ROS_DOMAIN_ID:

# On all devices
export ROS_DOMAIN_ID=0

Troubleshooting

Issue Solution
TF lookup errors Ensure lidar_converter.launch.py is running first
Robot shaking in RViz Set publish_tf:=false on odometry_bridge (EKF conflict)
No point cloud Check Ouster driver on Jetson: ros2 topic echo /ouster/points
Navigation fails Verify /scan topic: ros2 topic hz /scan

License

This project is licensed under the MIT License - see LICENSE for details.


Author

Rugved Raote
rugvedraote@gmail.com

About

ROS 2 package for real-time 3D-to-2D SLAM and navigation on the Husarion ROSbot XL with an Ouster OS1 LiDAR.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors