Steps:
- On PC, install Raspberry Pi Imager
- Choose:
- OS → Ubuntu Server 24.04 LTS (64-bit)
- Device → Raspberry Pi 5
- Flash to SD card
- Insert SD card → power on Pi 5
- Login:
- user:
ubuntu - password:
ubuntu(change when prompted)
- user:
Verify:
lsb_release -a
uname -msudo apt update && sudo apt upgrade -y
sudo apt install -y curl gnupg lsb-release software-properties-common
sudo add-apt-repository universe
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
-o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=arm64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/ros2.list
sudo apt update
sudo apt install -y ros-jazzy-ros-base python3-colcon-common-extensionsVerify:
printenv ROS_DISTROsudo apt update
sudo apt install -y curl gnupg lsb-release
sudo curl -fsSL https://packages.osrfoundation.org/gazebo.gpg \
-o /usr/share/keyrings/gazebo-archive-keyring.gpg
echo "deb [arch=arm64 signed-by=/usr/share/keyrings/gazebo-archive-keyring.gpg] \
http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/gazebo-stable.list
sudo apt update
sudo apt install -y gz-harmonicVerify:
gz sim --version- ROS2 JAZZY: https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html
- GAZEBO HARMONIC: https://gazebosim.org/docs/harmonic/install_ubuntu
- ROS–Gazebo bridge:
sudo apt install ros-jazzy-ros-gz-sim ros-jazzy-ros-gz-bridge ros-jazzy-ros-gz - PYTHON:
sudo apt install python3-colcon-common-extensions ros-jazzy-joint-state-publisher ros-jazzy-joint-state-publisher-gui - TOOL:
sudo apt install liburdfdom-tools
ls /dev/ttyUSB*
ls /dev/ttyACM*sudo apt install -y python3-serialcd ~/pi_li_amr
source /opt/ros/jazzy/setup.bash
colcon build --symlink-install
source install/setup.bash
clear- Raspberry Pi Pi 5
- Raspberry Pi RP2040 board
- BTS7960 motor drivers ×2
- XL4015 buck Convertor
- XY-3606 Buck Convertor
- GB37 12V encoded geared motors ×2
- YDLIDAR G2 LiDAR
- 12V 5A adapter
- USB cable ×2 (Pi ↔ RP2040, Pi ↔ LiDAR)
- 4WD Chassis
- Caster Wheel
- SpacersHardware Connection Tree
12V 5A Adapter
│
┌───────────┴───────────┐
│ │
XL4015 #1 (12V) XL4015 #2 (5V)
│ │
│ RP2040
│ │
│ USB Serial
│ │
│ Raspberry Pi 5
│
┌───────┴───────────────┐
│ │
BTS7960 #1 BTS7960 #2
│ │
Left Motor Right Motor
- POWER
12V Adapter
└── XL4015 #1 (set to 12V)
├── OUT+ → BTS7960 #1 B+
├── OUT+ → BTS7960 #2 B+
├── OUT− → BTS7960 #1 B−
└── OUT− → BTS7960 #2 B−
12V Adapter
└── XL4015 #2 (set to 5V)
├── OUT+ → RP2040 5V
└── OUT− → RP2040 GND- MOTOR DRIVERS
| BTS7960 #1
| ------- | ----------- |
| RPWM → GPIO 5 | RP2040 GPIO |
| LPWM → GPIO 6 | RP2040 GPIO |
| R_EN → GPIO 7 | RP2040 GPIO |
| L_EN → GPIO 8 | RP2040 GPIO |
| M+ → Red | Motor #1 |
| M− → White | Motor #1 |
| BTS7960 #2
| ------- | ----------- |
| RPWM → GPIO 9 | RP2040 GPIO |
| LPWM → GPIO 10 | RP2040 GPIO |
| R_EN → GPIO 11 | RP2040 GPIO |
| L_EN → GPIO 12 | RP2040 GPIO |
| M+ → Red | Motor #2 |
| M− → White | Motor #2 |- ENCODED MOTORS
| Wire
| ----------- | ---------- |
| Green → GPIO 1 | RP2040 GPIO |
| Yellow → GPIO 2 | RP2040 GPIO |
| Blue → 5V | RP2040 GPIO |
| Black → GND | RP2040 GPIO |
| Red → M+ | BTS7960 #1 |
| White → M- | BTS7960 #1 |
| Wire
| ----------- | ---------- |
| Green → GPIO 3 | RP2040 GPIO |
| Yellow → GPIO 4 | RP2040 GPIO |
| Blue → 5V | RP2040 GPIO |
| Black → GND | RP2040 GPIO |
| Red → M+ | BTS7960 #2 |
| White → M- | BTS7960 #2 |CHASSIS BUILDING
📁 Code ➡️ Keyboard.ino
case 'B': // Back
analogWrite(RPWM1, spd); analogWrite(LPWM1, 0);
analogWrite(RPWM2, spd); analogWrite(LPWM2, 0);
break;
case 'F': // Front
analogWrite(RPWM1, 0); analogWrite(LPWM1, spd);
analogWrite(RPWM2, 0); analogWrite(LPWM2, spd);
break;
case 'G': // left
analogWrite(RPWM1, 0); analogWrite(LPWM1, spd);
analogWrite(RPWM2, spd); analogWrite(LPWM2, 0);
break;
case 'H': // right
analogWrite(RPWM1, spd); analogWrite(LPWM1, 0);
analogWrite(RPWM2, 0); analogWrite(LPWM2, spd);
break;
case 'S': // stop
stopMotors();
break;
- Create Workspace
mkdir -p ~/pi_li_amr/src
cd ~/pi_li_amr
colcon build- Create Package
cd ~/pi_li_amr/src
ros2 pkg create robot_bringup --build-type ament_python --dependencies rclpy nav_msgs geometry_msgs tf2_ros
cd ~/pi_li_amr
colcon build
source install/setup.bash- Create File
📁 Code ➡️
Keyboard.ino
touch ~/pi_li_amr/src/robot_bringup/robot_bringup/odom_node.py
chmod +x ~/pi_li_amr/src/robot_bringup/robot_bringup/odom_node.py- Add the file to setup.py
- BUILD
- Terminal 1: ros2 run robot_bringup odom_node
- Terminal 2: ros2 run tf2_tools view_frames
odom → base_link
📁 Code ➡️ Keyboard.ino
- Create a file
touch ~/pi_li_amr/src/robot_bringup/robot_bringup/move_robot.py
chmod +x ~/pi_li_amr/src/robot_bringup/robot_bringup/move_robot.py- Add the file to setup.py
- BUILD
- Terminal 1: ros2 run robot_bringup move_robot
- Terminal 2:
source ~/pi_li_amr/install/setup.bash
ros2 topic pub /cmd_vel geometry_msgs/Twist "{linear: {x: 0.3}, angular: {z: 0.0}}"- Create a file
touch ~/pi_li_amr/src/robot_bringup/robot_bringup/serial_node.py
chmod +x ~/pi_li_amr/src/robot_bringup/robot_bringup/serial_node.py- Add the file to setup.py
- Add Code
- 📁 Code ➡️
Serial Node
- 📁 Code ➡️
- Update Arduino Code
- 📁 Code ➡️
ENCODERS.ino
- 📁 Code ➡️
- BUILD
- Terminal 1: ros2 run robot_bringup serial_node
- Clone ydlidar_ros2_driver into our workspace
sudo apt update
sudo apt install -y git cmake build-essential libusb-1.0-0-dev
cd ~/pi_li_amr/src
git clone https://github.com/YDLIDAR/ydlidar_ros2_driver.git
cd ~/pi_li_amr/src/ydlidar_ros2_driver
git checkout humble- Keep only these files
G2.yaml
ydlidar_launch.py- BUILD
- Terminal 1: ros2 launch ydlidar_ros2_driver ydlidar_launch.py
- Create a folder
mkdir ~/pi_li_amr/src/launch
touch ~/pi_li_amr/src/launch/slam.launch.py- Add Code
- 📁 Code ➡️
Serial Node
- 📁 Code ➡️
- Add the file to setup.py in data_file
- BUILD
- Terminal 1: ros2 run robot_bringup serial_node
- Terminal 2: ros2 launch ydlidar_ros2_driver ydlidar_launch.py
- Terminal 3: ros2 launch robot_bringup slam.launch.py
- Terminal 4:
ros2 lifecycle set /slam_toolbox configure
ros2 lifecycle set /slam_toolbox activate- Terminal 5: rviz2
Fixed Frame: map
Add → Map
Add → LaserScan
Add → TF- Update Code in ARDUINO IDE 📁 Code ➡️
navigation.ino📁 Code ➡️Navigation Node - Create a file
touch ~/pi_li_amr/src/robot_bringup/robot_bringup/navigation_node.py
chmod +x ~/pi_li_amr/src/robot_bringup/robot_bringup/navigation_node.py📁 Code ➡️ Nav Params
- Create a file
mkdir -p ~/pi_li_amr/src/robot_bringup/config
nano ~/pi_li_amr/src/robot_bringup/config/nav2.yaml📁 Code ➡️ Navigation Launch
- Create a file
mkdir -p ~/pi_li_amr/src/robot_bringup/launch
nano ~/pi_li_amr/src/robot_bringup/launch/navigation.launch.py- Add the files to setup.py in data_file
- BUILD
- Terminal 1: ros2 run robot_bringup navigation_node
- Terminal 2: ros2 launch ydlidar_ros2_driver ydlidar_launch.py
- Terminal 3: ros2 launch robot_bringup slam.launch.py
- Terminal 4:
ros2 lifecycle set /slam_toolbox configure
ros2 lifecycle set /slam_toolbox activate
























