Skip to content

b-Tomas/skid-drive-robot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

skid-drive-robot

ROS2 4-wheel diff drive robot.

Started as a university project for a microcontrolers-related subject. The tiny piece of code that has anything to do with the subject is present in ros2_ws/src/skid_drive_firmware and it is just an excuse for building this robot.

Note

This is still a work in progress. Future improvements include sensor fusion and SLAM, as well as replacing the microcontroller and motors with a closed PID loop.

Setup

Prerequisites

  • ROS2 Jazzy installed natively on workstation and the robot. Using a VM for development is a good alternative
  • Some hardware (TODO: description)
  • Docker and Docker Compose (optional, for development only)

Initial Setup

  1. Clone the repository:

    git clone git@github.com:b-Tomas/skid-drive-robot.git
    cd skid-drive-robot
  2. Initialize and update git submodules:

    git submodule update --init --recursive
  3. (Optional) Build the Docker images for development:

    docker compose -f docker/compose.yaml build

Building the ROS2 Workspace

Initial Setup (One-time)

Before building the workspace for the first time, you need to set up rosdep to install system dependencies:

  1. Initialize rosdep (if not already done):

    sudo rosdep init
  2. Update rosdep database:

    rosdep update

On Workstation

You can use either Docker or native ROS2 installation on your workstation.

Option A: Using Docker (optional)

  1. Start the development container:

    ./docker/start-dev.sh
  2. Inside the container, install system dependencies:

    cd /ros2_ws
    rosdep install --from-paths src --ignore-src -r -y
  3. Build the workspace:

    colcon build --symlink-install
  4. Source the installation:

    source install/setup.bash

Option B: Using Native ROS2 Installation

  1. Install system dependencies:

    cd ros2_ws
    rosdep install --from-paths src --ignore-src -r -y
  2. Build the workspace:

    colcon build --symlink-install
  3. Source the installation:

    source install/setup.bash

Tip

You need to source install/setup.bash in each new shell session to use the built packages. Alternatively, you can add it to your ~/.bashrc for automatic sourcing.

On Robot

Since the Raspberry Pi on the robot uses a different architecture (ARM) than the workstation (x86_64), packages must be built on the robot itself and cannot just be transferred using sync.sh.

With ROS2 installed natively on the robot:

  1. Sync source code from workstation to robot:

    ./sync.sh
  2. On the robot, install system dependencies:

    cd ros2_ws
    rosdep install --from-paths src --ignore-src -r -y
  3. Build the workspace:

    # The extra environment variable and sequential setting was the combination of
    # parameters that prevented my RPi 3b from hanging
    MAKEFLAGS="-j 1" colcon build --symlink-install --executor sequential
  4. Source the installation:

    source install/setup.bash

Tip

You need to source install/setup.bash in each new shell session to use the built packages. Alternatively, you can add it to your ~/.bashrc for automatic sourcing.

Usage

Development (Workstation)

Using Docker: Run ./docker/start-dev.sh to start the dev container with GUI support.

Using Native ROS2:

Source your workspace:

source ros2_ws/install/setup.bash  # if the workspace is built

Note

The docker setup is to be improved. This container was enough to run some simple ROS2 commands for quickstarting packages.

In the end I resorted to an Ubuntu Desktop VM with native ROS.

Launching the RPLidar A1M8

First set up the udev rules for the RPLidar A1M8:

cd ros2_ws/src/sllidar_ros2/
source scripts/create_udev_rules.sh

To launch the RPLidar A1M8, run:

ros2 launch skid_drive_bringup rplidar_a1m8.launch.py

You can override parameters:

ros2 launch skid_drive_bringup rplidar_a1m8.launch.py serial_port:=/dev/ttyUSB0

Launching the Phone IMU Bridge

The phone IMU bridge node publishes IMU data from a phone to ROS2 topics via WebSocket.

To launch the phone IMU bridge, run:

ros2 run phone_imu_bridge imu_server_node

The node will:

  • Start a WebSocket server on 0.0.0.0:5000
  • Publish IMU data to the /phone_imu topic (sensor_msgs/msg/Imu)
  • Use frame ID phone_imu_link

See the phone-imu-ros2 submodule for more details.

Launching Static Transforms

To set up the transform tree linking all robot frames:

ros2 launch skid_drive_bringup static_transforms.launch.py

This publishes static transforms from base_link to:

  • laser (lidar frame)

You can customize the laser position/orientation:

ros2 launch skid_drive_bringup static_transforms.launch.py \
  laser_x:=0.1 laser_y:=0.0 laser_z:=0.2 \
  laser_roll:=0.0 laser_pitch:=0.0 laser_yaw:=0.0

Launching RViz Visualization

To visualize lidar and IMU data in RViz:

ros2 launch skid_drive_bringup rviz.launch.py

This will launch RViz2 with a pre-configured visualization that includes:

  • LaserScan display for lidar data (/scan topic)
  • TF display showing coordinate frames (including IMU orientation)
  • Grid for reference

This assumes the following are running:

  • Static transforms (static_transforms.launch.py)
  • Lidar node (rplidar_a1m8.launch.py)
  • Phone IMU bridge (phone_imu_bridge.launch.py)

Running the Motor Control Node

The motor control node listens to cmd_vel and uses software PWM to achieve variable speed control, even though the hardware only supports discrete on/off states.

To start the motor control node:

ros2 run skid_drive_control skid_drive_control_node

To specify the serial port and other parameters:

ros2 run skid_drive_control skid_drive_control_node --ros-args \
  -p port:=/dev/ttyUSB0 \
  -p pwm_frequency:=50.0 \
  -p max_velocity:=1.0

Parameters

  • port (string, default: /dev/ttyS0): Serial port for motor controller
  • baudrate (int, default: 9600): Serial baud rate
  • timeout (float, default: 0.5): Serial read timeout
  • pwm_frequency (float, default: 50.0): Software PWM frequency in Hz
  • max_velocity (float, default: 1.0): Maximum velocity for normalization

Teleoperation

Keyboard Control

To control the robot using keyboard (recommended method):

ros2 run teleop_twist_keyboard teleop_twist_keyboard

Instructions will appear in the console.

Joystick Control

TODO

Running the Serial Test Script

To test serial communication with the motor controller:

ros2 run skid_drive_firmware serial_test.py

This script allows you to manually control the motors via serial commands:

  • J: Turn left
  • K: Move forward
  • L: Move backward
  • ;: Turn right
  • Space: Stop all motors
  • Enter: Exit

Project Structure

skid-drive-robot/
├── README.md
├── LICENSE
├── ros2_ws/
│   ├── src/
│   │   ├── skid_drive_description/ (TODO)
│   │   ├── skid_drive_bringup/
│   │   ├── skid_drive_hardware/ (TODO)
│   │   ├── skid_drive_controller/ (TODO)
│   │   ├── skid_drive_control/
│   │   ├── skid_drive_firmware/
│   │   ├── phone-imu-ros2/ (git submodule)
│   │   └── sllidar_ros2/  (git submodule)
└── docs/

Dependencies

  • ROS2 Jazzy
  • sllidar_ros2 (included as git submodule)
  • phone-imu-ros2 (included as git submodule)
  • python3-serial (for serial communication with motor controller)

All system dependencies are declared in the package package.xml files and can be installed automatically using rosdep install.

About

ROS2 4-wheel skid-steer drive robot

Resources

License

Stars

Watchers

Forks