Skip to content

Navigation Menu

Sign in
Sign up

Repository files navigation

SparkCar_ROS2_WS

SparkCar ROS 2 workspace for the SparkCar robot platform. This repository groups the Hunter SE chassis driver, Livox MID360 perception/localization stack, Nav2 bringup, Hybrid A* planner demo, and map conversion tools.

The README style follows the lightweight structure commonly used by AgileX/Hunter ROS repositories: packages, communication setup, build, launch, and safety notes.

Contents

Packages

SparkCar_ROS2_WS
+-- HunterSE_Driver
| +-- src
| +-- hunter_base # Hunter SE / Hunter 2 chassis ROS 2 node
| +-- hunter_msgs # Hunter status and command messages
| +-- ugv_sdk # Weston Robot / AgileX UGV SDK
+-- SparkCar_Perception
| +-- src # Livox MID360 and FAST-LIO2 related source tree
| +-- install # Installed perception packages: livox_ros_driver2, localizer, pgo, interface, etc.
+-- SparkCar_Navigation
| +-- src
| +-- sparkcar_nav_bringup
| | +-- launch # Nav2 launch files
| | +-- behavior_trees # Hunter SE Nav2 behavior trees
| | +-- config # Nav2 parameters and waypoints
| | +-- maps # Default map
| | +-- src # twist_to_ackermann and obstacle_cloud_filter nodes
| +-- hybrid_astar_planner
| +-- launch # Hybrid A* demo launch
| +-- config # Planner parameters
| +-- rviz # RViz config
+-- SparkCar_Tools
| +-- install/pcd2pgm # PCD to occupancy grid map conversion tool
+-- scripts
 +-- ControlCommand.sh # Mapping helper script
 +-- hunter_ros2_test.sh # Hunter SE Nav2 navigation helper script
 +-- nav2_test.sh # Older navigation helper script
 +-- process.md # Mapping workflow notes

Environment

Recommended runtime environment:

  • Ubuntu 22.04
  • ROS 2 Humble
  • SocketCAN enabled CAN adapter for Hunter SE chassis
  • Livox MID360 lidar
  • Micro XRCE-DDS Agent if the lower controller uses serial XRCE-DDS

Install common ROS dependencies:

sudo apt update
sudo apt install -y \
 python3-colcon-common-extensions \
 ros-humble-rclcpp \
 ros-humble-geometry-msgs \
 ros-humble-nav-msgs \
 ros-humble-sensor-msgs \
 ros-humble-ackermann-msgs \
 ros-humble-tf2 \
 ros-humble-tf2-ros \
 ros-humble-tf2-geometry-msgs \
 ros-humble-navigation2 \
 ros-humble-nav2-bringup \
 ros-humble-nav2-map-server \
 ros-humble-rviz2 \
 libasio-dev \
 libeigen3-dev \
 libgoogle-glog-dev

CAN Interface Setup

Hunter chassis communication uses SocketCAN. The default launch parameter is port_name:=can0.

Bring up CAN at 500 kbit/s:

sudo ip link set can0 down
sudo ip link set can0 type can bitrate 500000
sudo ip link set can0 up

Check CAN traffic:

candump can0

Build

This repository is organized as several ROS 2 workspaces. Build each workspace from its own directory.

Build Hunter SE driver:

cd /home/jiaverso/Desktop/SparkCar_ROS2_WS/HunterSE_Driver
source /opt/ros/humble/setup.bash
colcon build --symlink-install

Build navigation packages:

cd /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Navigation
source /opt/ros/humble/setup.bash
colcon build --symlink-install

If perception/tools source packages are present on the target machine, build them the same way:

cd /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Perception
source /opt/ros/humble/setup.bash
colcon build --symlink-install
cd /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Tools
source /opt/ros/humble/setup.bash
colcon build --symlink-install

Source installed workspaces after build:

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/HunterSE_Driver/install/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Perception/install/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Tools/install/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Navigation/install/setup.bash

Basic Usage

Start Hunter SE Chassis

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/HunterSE_Driver/install/setup.bash
ros2 launch hunter_base hunter_base.launch.py port_name:=can0 robot_model:=hunter_se

Common launch arguments:

  • port_name: CAN interface, default can0
  • robot_model: hunter_se or hunter2, default hunter2
  • odom_frame: odometry frame, default odom
  • base_frame: base frame, default base_link
  • odom_topic_name: odometry topic, default odom

The chassis node subscribes to /cmd_vel, publishes odometry on the configured odometry topic, publishes TF from odom_frame to base_frame, and publishes chassis status on /hunter_status.

Send a simple test command:

ros2 topic pub /cmd_vel geometry_msgs/msg/Twist \
 "{linear: {x: 0.2}, angular: {z: 0.0}}" -r 10

Stop the robot:

ros2 topic pub /cmd_vel geometry_msgs/msg/Twist \
 "{linear: {x: 0.0}, angular: {z: 0.0}}" -1

Start Livox MID360

Start the Livox MID360 driver before mapping or localization:

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Perception/install/setup.bash
ros2 launch livox_ros_driver2 msg_MID360_launch.py

Check lidar and IMU topics:

ros2 topic hz /livox/lidar
ros2 topic hz /livox/imu

Expected raw sensor topics:

  • /livox/lidar
  • /livox/imu

PGO Mapping And Save PCD

Run the mapping helper:

cd /home/jiaverso/Desktop/SparkCar_ROS2_WS
bash scripts/ControlCommand.sh

Manual mapping sequence:

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Perception/install/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Tools/install/setup.bash
# Terminal 1: start lidar
ros2 launch livox_ros_driver2 msg_MID360_launch.py
# Terminal 2: start PGO mapping
ros2 launch pgo pgo_launch.py

pgo_launch.py starts both FAST-LIO2 and the PGO node:

livox_ros_driver2 -> /livox/lidar, /livox/imu
FAST-LIO2 -> /fastlio2/lio_odom, /fastlio2/body_cloud
PGO -> optimized map and /pgo/save_maps service

Current mapping frames:

FAST-LIO2 odom frame: lio
FAST-LIO2 body frame: body
PGO TF: map -> lio
Fast-LIO2 odometry topic: /fastlio2/lio_odom
Fast-LIO2 body cloud topic: /fastlio2/body_cloud

Optional rosbag recording during mapping:

mkdir -p ~/Desktop/bags
ros2 bag record \
 /livox/lidar \
 /livox/imu \
 /fastlio2/lio_odom \
 /fastlio2/body_cloud \
 -o ~/Desktop/bags/mapping_001

Save PGO map:

mkdir -p ~/Desktop/Save_Map
ros2 service call /pgo/save_maps interface/srv/SaveMaps \
 "{file_path: '$HOME/Desktop/Save_Map', save_patches: true}"

The PGO service saves the merged map as:

~/Desktop/Save_Map/main.pcd

Each save overwrites main.pcd, so no extra copy or rename step is needed.

If save_patches: true is used, PGO also saves patch files under:

~/Desktop/Save_Map/patches/

Convert PCD To PGM For Nav2

pcd2pgm converts a .pcd point cloud map into a 2D occupancy grid and publishes it on /map. Then map_saver_cli saves the Nav2 .pgm and .yaml map files.

The default pcd2pgm config currently reads:

~/Desktop/Save_Map/main.pcd

The source config is:

pcd2pgm:
 ros__parameters:
 pcd_file: /home/jiaverso/Desktop/Save_Map/main.pcd

Rebuild or use the installed config that matches your runtime environment. Then run:

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Tools/install/setup.bash
ros2 launch pcd2pgm pcd2pgm_launch.py \
 params_file:=/home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Tools/src/pcd2pgm/config/pcd2pgm.yaml

In another terminal, save the published /map as main.pgm and main.yaml:

source /opt/ros/humble/setup.bash
mkdir -p /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Navigation/src/sparkcar_nav_bringup/maps
ros2 run nav2_map_server map_saver_cli \
 -f /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Navigation/src/sparkcar_nav_bringup/maps/main

This creates:

SparkCar_Navigation/src/sparkcar_nav_bringup/maps/main.pgm
SparkCar_Navigation/src/sparkcar_nav_bringup/maps/main.yaml

Confirm that main.yaml points to main.pgm:

image: main.pgm
resolution: 0.05
origin: [...]

Start FAST-LIO2 Localizer And Nav2

Run the navigation helper:

cd /home/jiaverso/Desktop/SparkCar_ROS2_WS
bash scripts/hunter_ros2_test.sh

Manual navigation sequence:

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Perception/install/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Navigation/install/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/HunterSE_Driver/install/setup.bash
# Terminal 1: start Hunter SE chassis
ros2 launch hunter_base hunter_base.launch.py \
 port_name:=can0 \
 robot_model:=hunter_se \
 odom_frame:=odom \
 base_frame:=body \
 odom_topic_name:=odom
# Terminal 2: start Livox MID360
ros2 launch livox_ros_driver2 msg_MID360_launch.py
# Terminal 3: start FAST-LIO2 localizer
ros2 launch localizer localizer_launch.py use_rviz:=false
# Terminal 4: start Nav2 obstacle cloud filter
ros2 run sparkcar_nav_bringup obstacle_cloud_filter
# Terminal 5: start Nav2
ros2 launch sparkcar_nav_bringup nav_bringup.launch.py

localizer_launch.py starts:

fastlio2/lio_node
localizer/localizer_node
optional localizer RViz when `use_rviz:=true`

nav_bringup.launch.py starts:

map_server
planner_server
controller_server
smoother_server
behavior_server
bt_navigator
lifecycle_manager_navigation
rviz2

Current navigation topic and TF usage:

Hunter wheel odometry: /odom
Nav2 odometry input: /odom
Fast-LIO2 body cloud: /fastlio2/body_cloud
Filtered obstacle cloud: /nav2/obstacle_cloud
Nav2 local costmap obstacle input: /nav2/obstacle_cloud
Expected TF chain: map -> odom -> body

The helper script waits for map -> body before starting Nav2. If it times out, check that the Hunter driver is publishing odom -> body and the localizer is publishing map -> odom.

If needed, start Micro XRCE-DDS Agent:

sudo MicroXRCEAgent serial --dev /dev/ttyUSB1 -b 115200 -v 6

Disable RViz:

ros2 launch sparkcar_nav_bringup nav_bringup.launch.py use_rviz:=false

Nav2 Velocity Output

Nav2 computes velocity commands from the planned path and publishes:

/cmd_vel

Check output:

ros2 topic echo /cmd_vel
ros2 topic hz /cmd_vel

If using the Hunter SE ROS2 driver directly, hunter_base subscribes to /cmd_vel, so the control chain is:

Nav2 controller_server -> /cmd_vel -> hunter_base -> CAN -> Hunter SE

In this case, do not run twist_to_ackermann unless a separate lower-level controller is explicitly subscribing to /ackermann_cmd.

Twist To Ackermann Converter

The converter subscribes to /cmd_vel and publishes /ackermann_cmd.

ros2 run sparkcar_nav_bringup twist_to_ackermann

Use this only when the lower-level controller expects ackermann_msgs/msg/AckermannDrive on /ackermann_cmd.

Parameters:

  • wheelbase: default 0.60
  • max_steering_angle: default 0.52
  • min_speed_for_steering: default 0.05
  • cmd_vel_topic: default /cmd_vel
  • ackermann_topic: default /ackermann_cmd

Hybrid A* Demo

source /opt/ros/humble/setup.bash
source /home/jiaverso/Desktop/SparkCar_ROS2_WS/SparkCar_Navigation/install/setup.bash
ros2 launch hybrid_astar_planner hybrid_astar_test.py

Useful Topics And Checks

ros2 topic list
ros2 topic echo /hunter_status
ros2 topic echo /odom
ros2 topic echo /cmd_vel
ros2 topic echo /ackermann_cmd
ros2 topic echo /fastlio2/body_cloud
ros2 topic echo /nav2/obstacle_cloud
ros2 topic echo /plan
ros2 lifecycle get /map_server
ros2 lifecycle get /planner_server
ros2 lifecycle get /controller_server
ros2 lifecycle get /bt_navigator
ros2 run tf2_ros tf2_echo map body

Safety Notes

  • Always lift the robot wheels or keep the robot in an open area for the first motion test.
  • Verify the CAN interface and emergency stop before sending /cmd_vel.
  • Start with low linear speed, for example 0.1 to 0.2 m/s.
  • Keep a terminal ready to publish zero velocity or stop the launch process.
  • Confirm TF frames and map alignment before enabling autonomous navigation.

License

This repository contains code from multiple components. See LICENSE and package-level license files for details.

About

存放 SparkCar_Robot ROS 仓库

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /