Skip to content

Smokey8979/Anibot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ€– Anibot β€” ROS2 Autonomous Navigation Robot

Anibot Demo

License ROS2 Jazzy RPi5 Nav2 SLAM Status Last Commit

⚠️ Active development β€” BETA. Architecture and params may change.

Anibot is a compact ROS2 differential drive robot built around a Raspberry Pi 5, capable of autonomous navigation, real-time SLAM mapping, and sensor-fused odometry using wheel encoders and LiDAR. It runs the full Nav2 stack with a calibrated EKF for reliable localization.


πŸ“‹ Table of Contents


πŸš€ Overview

Anibot implements a complete mobile robotics stack on affordable hardware:

  • Autonomous navigation with Nav2 (DWB controller)
  • SLAM mapping with slam_toolbox (lifelong mode)
  • Sensor-fused odometry β€” wheel encoders + LiDAR via EKF (robot_localization)
  • AMCL localization on saved maps
  • Docker-based RViz for remote visualization from a laptop
  • Arduino Mega motor controller with quadrature encoder tracking at 20 Hz

🧠 System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Raspberry Pi 5                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ RPLIDAR A1 │──▢│  /scan topic │──▢│  slam_toolbox β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                             β”‚            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚Arduino Mega│──▢│ /odom (wheel)│──▢│ robot_local.  β”‚  β”‚
β”‚  β”‚Cytron MDD3Aβ”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚ (EKF fusion)  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚       β–²                                      β”‚           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ /cmd_vel   │◀──│     Nav2     │◀──│  /odom_fused  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚ SSH / ROS2 Domain 42
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  Laptop (Docker)  β”‚
                β”‚  RViz2 + Nav2 UI  β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”§ Hardware

Component Model Notes
Compute Raspberry Pi 5 Ubuntu 24.04, ROS2 Jazzy
Microcontroller Arduino Mega 2560 Motor control + encoder reading
Motor Driver Cytron MDD3A Dual channel, PWM control
LiDAR RPLIDAR A1M8 360Β° scan, ~6m range
Drive Differential Drive 2WD with caster
Encoders Quadrature (Γ—4) 28 PPR per motor, gear ratio 19.2:1

Arduino Pin Mapping:

Signal Pin
M1A (Right Motor) 9
M1B (Right Motor) 10
M2A (Left Motor) 5
M2B (Left Motor) 6
ENC_L_A 2 (INT)
ENC_L_B 3 (INT)
ENC_R_A 18 (INT)
ENC_R_B 19 (INT)

πŸ’Ύ Software Stack

Layer Technology
OS Ubuntu 24.04 LTS (RPi5)
Middleware ROS2 Jazzy
Navigation Nav2 (DWB Local Planner)
Mapping slam_toolbox (lifelong)
Localization AMCL + EKF (robot_localization)
Sensor Fusion robot_localization (wheel odom + laser odom)
Visualization RViz2 (via Docker on laptop)
Serial Comm Python pyserial @ 115200 baud

πŸ”€ Odometry & Sensor Fusion

Anibot fuses wheel odometry and laser odometry using an Extended Kalman Filter (EKF) via the robot_localization package.

/odom          (wheel encoders)  ──┐
                                    β”œβ”€β”€β–Ά EKF ──▢ /odometry/filtered
/laser_odom    (LiDAR scan match) β”€β”€β”˜
  • Wheel odom provides high-frequency velocity estimates (20 Hz) but drifts over time
  • Laser odom corrects long-term drift using scan matching
  • EKF output /odometry/filtered is fed to Nav2 as the primary odometry source

πŸ§ͺ Fusion testing in progress β€” actively tuning EKF covariance matrices and validating against ground truth.


βš™οΈ Calibrated Parameters

These values are calibrated through physical testing (360Β° spin test, straight-line test):

# Wheel & Drive
wheel_radius:       0.041 m
wheel_base:         0.355 m     # Calibrated β€” 360Β° spin, 1.1Β° residual error
encoder_ppr:        28          # Γ— 4 quadrature = 112 counts/rev
gear_ratio:         19.2

# Scale correction (motor asymmetry compensation)
left_scale:         0.82
right_scale:        1.00
swap_motors:        true        # Physical L/R wiring swap β€” corrected in software

# PWM limits
max_pwm:            150
pwm_min:            70          # Deadband β€” below this motor stalls
max_linear_speed:   0.20 m/s

# Nav2 controller
desired_linear_vel: 0.18 m/s
rotate_angular_vel: 0.42 rad/s
xy_goal_tolerance:  0.20 m
yaw_goal_tolerance: 0.25 rad

# AMCL
particles_min:      1000
particles_max:      5000
z_hit:              0.95
max_beams:          180

πŸ“¦ Workspace Structure

anibot_ws/
β”œβ”€β”€ src/
β”‚   └── interface/          # Main ROS2 package
β”‚       β”œβ”€β”€ interface/       # Python nodes
β”‚       β”‚   β”œβ”€β”€ odometery.py     # Wheel odometry node
β”‚       β”‚   └── ...
β”‚       β”œβ”€β”€ launch/
β”‚       β”‚   β”œβ”€β”€ anibot_full.launch.py    # Nav2 full launch
β”‚       β”‚   └── slam_full.launch.py     # SLAM launch
β”‚       β”œβ”€β”€ config/          # Nav2, EKF, AMCL params
β”‚       β”œβ”€β”€ maps/            # Saved maps (.yaml + .pgm)
β”‚       └── CMakeLists.txt
β”œβ”€β”€ assets/                  # Demo GIFs, images
β”œβ”€β”€ anibot_setup.sh          # One-shot dependency installer
β”œβ”€β”€ docker_jazzy.sh          # RViz2 Docker launcher (laptop)
β”œβ”€β”€ .gitignore
└── README.md

βš™οΈ Setup & Usage

1. Install Dependencies

chmod +x anibot_setup.sh
./anibot_setup.sh

2. Build Workspace

cd ~/anibot_ws
colcon build --symlink-install
source install/setup.bash

3. Launch SLAM (Mapping)

ros2 launch interface slam_full.launch.py

4. Save Map

ros2 run nav2_map_server map_saver_cli -f ~/maps/my_map \
  --ros-args -p save_map_timeout:=10.0

5. Launch Autonomous Navigation

ros2 launch interface anibot_full.launch.py map:=$HOME/maps/my_map.yaml

6. Teleoperation

ros2 run teleop_twist_keyboard teleop_twist_keyboard \
  --ros-args -p speed:=0.21 -p turn:=0.43

7. RViz2 on Laptop (Docker)

# On laptop β€” sets up ROS2 Domain 42, software OpenGL
./docker_jazzy.sh

Make sure ROS_DOMAIN_ID=42 is set on both RPi and laptop.


✨ Features & Status

Feature Status
Differential drive control βœ… Working
Quadrature encoder odometry βœ… Working
RPLIDAR A1M8 integration βœ… Working
SLAM mapping (slam_toolbox) βœ… Working
Autonomous navigation (Nav2) βœ… Working
Map saving & reloading βœ… Working
Teleoperation βœ… Working
Docker RViz (laptop) βœ… Working
Wheel + Laser odom EKF fusion πŸ§ͺ Testing
IMU integration πŸ”œ Planned
Autonomous docking πŸ”œ Planned
Web monitoring dashboard πŸ”œ Planned

πŸ—ΊοΈ Roadmap

  • Basic diff drive + encoder odometry
  • LiDAR scan integration
  • SLAM mapping
  • Nav2 autonomous navigation
  • Docker RViz remote visualization
  • Sensor fusion: Wheel odom + Laser odom (EKF) ← in progress
  • IMU integration (MPU6050 or similar)
  • Full 3-source EKF (wheel + laser + IMU)
  • Dynamic obstacle avoidance tuning
  • Web-based robot monitoring dashboard
  • Autonomous charging dock return
  • Multi-floor mapping

πŸ› Known Issues & Fixes

Issue Fix Applied
Left motor runs faster than right left_scale=0.82 software compensation
Motors physically wired L/R swapped swap_motors=True in odometry node
SLAM node crashes in ROS2 Jazzy lifecycle_manager + bond_timeout: 0.0
Motors stall at low PWM PWM_MIN=70 deadband enforced
Arduino resets mid-session causing odom jump Triple reset on startup + clean encoder state
joint_state_publisher missing causing TF errors Added to launch file
AMCL not converging Set 2D Pose Estimate manually in RViz first
Wheel base drift in turns Calibrated to 0.355m via 360Β° spin test

🀝 Contributing

Currently a solo project β€” contributions not open yet. Once the sensor fusion and IMU integration are stable, I'll open issues for community input. Feel free to fork and experiment!


πŸ“¬ Contact

Omkarthik Dhudu


⭐ Acknowledgements


Built with too much coffee and not enough sleep β˜•