- Ubuntu 24.04 LTS
- ROS Version: ROS2 Jazzy
The following ROS packages are required for this project:
- Scout Driver (scout_ros2, ugv_sdk)
- Fixposition Vision-RTK2 Driver (fixposition_driver)
- Fixposition Nav2 Tutorial (nav2_tutorial)
To obtain them, simply execute the following command at the root of the repository:
git submodule update --init --recursiveThe user can also compile the provided Docker container in the .devcontainer folder to test this tutorial. To achieve this, the following commands can be used:
docker compose -f .devcontainer/docker-compose.yaml build
docker compose -f .devcontainer/docker-compose.yaml up -d
docker compose -f ~/dev/nav2_tutorial/.devcontainer/docker-compose.yaml exec vrtk bashAlternatively, the user can compile it directly using the Dev Containers extension in VSCode.
To check the status of the different services, you can run the following commands:
docker compose logs vrtkTo use the ROS driver with the Scout robot, the following changes must be applied:
-
Enable the following messages in the I/O configuration page of the sensor:
- FP_A-ODOMETRY
- FP_A-ODOMENU
- FP_A-ODOMSH
- FP_A-LLH
- FP_A-EOE_FUSION
- FP_A-TF_VRTKCAM
- FP_A-TF_POIVRTK
- FP_A-TF_ECEFENU0
- FP_A-TF_POIPOISH
- FP_A-TF_POIIMUH
-
In the configuration file of the ROS driver (src/fixposition_driver/fixposition_driver_ros2/launch/config.yaml), change the 'nav2_mode' to 'true' and 'qos_type' to 'default_long'.
-
Run the setup_ros_ws bash script to set up the fixposition driver accordingly.
-
(Optional) Configure wheelspeed measurements by setting up the following configuration:
converter:
enabled: true
topic_type: "Odometry" # Supported types: nav_msgs/{Twist, TwistWithCov, Odometry}
input_topic: "/odom" # Input topic name
scale_factor: 1000.0 # To convert from the original unit of measurement to mm/s (note: this must be a float!)
use_x: true # Transmit the x axis of the input velocity
use_y: false # Transmit the y axis of the input velocity
use_z: false # Transmit the z axis of the input velocityBuild the ROS2 workspace.
source /opt/ros/jazzy/setup.bash
colcon build --symlink-install --cmake-args -DBUILD_TESTING=OFFsource install/setup.bashTo communicate with the Scout robot, you must use the provided USB-to-CAN adapter. Then, run the following commands to start the connection:
sudo modprobe gs_usb can-utils
sudo ip link set can0 up type can bitrate 500000
candump can0Alternatively, the user can also directly execute the provided script setup-can.sh:
sudo ./scripts/setup-can.shExample output from the can0 port:
can0 311 [8] 00 00 25 C6 FF FF F0 A4
can0 251 [8] 00 00 00 00 00 00 00 00
can0 252 [8] 00 00 00 00 00 00 00 00
can0 253 [8] 00 00 00 00 00 00 00 00
can0 254 [8] 00 00 00 00 00 00 00 00
can0 241 [8] AA 00 00 00 00 00 00 ED
can0 221 [8] 00 00 00 00 00 00 00 00
can0 311 [8] 00 00 25 C6 FF FF F0 A4
...Note: To automatically establish the connection to the Agilex, you can edit the /etc/modules file as such:
# /etc/modules: kernel modules to load at boot time.
gs_usb
can-utilsIn addition, in case the error messsage 'RTNETLINK answers: Device or resource busy' appears, please run the following command:
sudo ip link set can0 downIn terminal 1, run these commands to start the base node for the Scout robot:
source /opt/ros/jazzy/setup.bash && source install/setup.bash
ros2 launch scout_base scout_mini_base.launch.pyIn terminal 2, run these commands to start the keyboard-based controller:
source /opt/ros/jazzy/setup.bash
ros2 run teleop_twist_keyboard teleop_twist_keyboardThis package provides two ROS 2 nodes for recording GPS waypoints to a YAML file, based on GNSS and odometry data:
| Script | Logging Mode | Trigger | Ideal Use Case |
|---|---|---|---|
gps_keylogger.py |
Manual | Keyboard 'f' |
Sparse or event-based recording |
gps_periodic_logger.py |
Automated (periodic) | Time interval | Continuous route logging |
Both scripts subscribe to:
/fixposition/odometry_llhβsensor_msgs/NavSatFix/fixposition/odometry_enuβnav_msgs/Odometry
Logged waypoints are stored in a YAML file under the waypoints: key. Each entry includes:
waypoints:
- latitude: 47.123456
longitude: 8.654321
altitude: 520.4
yaw: 1.57
logged_at: "2025-06-30T15:47:12.003918"ros2 run nav2_tutorial gps_keylogger [optional_output.yaml]- Press
'f'to log a waypoint - Press
'q'to quit and save
Waypoints are saved immediately and safely to disk.
ros2 run nav2_tutorial gps_periodic_logger [optional_output.yaml] -i 0.2- Logs waypoints automatically every 0.2s (default)
- Press
'q'to stop recording - Uses buffered writing to reduce I/O overhead
- Filters out insignificant movement (less than 1β―cm).
If no output path is specified, the log will be written to:
nav2_tutorial/src/nav2_tutorial/trajectories/gps_waypoints_<timestamp>.yaml
To quickly visualize GPS waypoint logs, use the visualize_gps script:
ros2 run nav2_tutorial visualize_gps path/to/gps_waypoints.yaml # simple 2D plot
ros2 run nav2_tutorial visualize_gps path/to/gps_waypoints.yaml --map # map overlay (if supported)geopandascontextilyshapely
This will display your trajectory as a line over OpenStreetMap tiles (Mapnik style) using Web Mercator projection.
Launch the ROS nodes in the following order:
ros2 launch scout_base scout_mini_base.launch.py
ros2 launch nav2_tutorial fp_driver_node.launch config:=fp_driver_config.yaml
ros2 launch nav2_tutorial gps_waypoint_follower.launch.pyNote: You can use the all_nodes.launch.py file to achieve this. For navigation, this repository provides three waypoint following methods: Precise, Smooth, and Interactive. We can only choose one method each time we execute it.
- Smooth GPS Waypoint Follower (Recommended):
The
smooth_wp_followerscript streams all the logged points from a YAML file and divides them in segments, pre-computing a smooth trajectory for the robot to follow. This ensure constant speed throughout the waypoint following task.
ros2 run nav2_tutorial smooth_wp_follower <optional: /path/to/file> <optional: --last> <optional: --reverse>- Precise GPS Waypoint Follower:
The
precise_wp_followerscript streams all the logged points from a YAML file and makes the robot follow them point-by-point, stopping at every waypoint when the accuracy threshold is met. Note: Avoid combining this method with the periodic logger at high rates. Logging too frequently creates waypoints that are very close together, which can cause the robot to stop and start excessively at each point, leading to unstable behavior.
ros2 run nav2_tutorial precise_wp_follower <optional: /path/to/file> <optional: --last> <optional: --reverse>- Interactive GPS Waypoint Follower:
The
interactive_wp_followerscript listens to the mapviz topic for the next waypoint objective.
ros2 run nav2_tutorial interactive_wp_followerFor launching the graphical interface, you can run the following command (note that this only works on x86/amd64 devices):
ros2 launch nav2_tutorial mapviz.launch.pyOr alternatively use the --mapviz flag on the gps_waypoint_follower.launch.py script.
To analyze the trajectories performed by the robot and determine if any issues have occured, the user can perform a recording of all topics by running ros2 bag record --all. Then, launch RViz2 with the provided configuration file to easily visualize the debug topics containing the waypoint coordinates, the global and local plans, the costmaps, among other things: ros2 run rviz2 rviz2 -d /home/dev/ros_ws/src/nav2_tutorial/config/nav2_plan_viz.rviz.
In addition, this repository provides an interactive dashboard to control all of these processes. It can be started as follows:
ros2 run nav2_tutorial dashboardWe suggest employing tmux for controlling the robot via SSH, as intermittent disconnections may kill the running process. Next you'll find some basic steps to get familiar with tmux:
To install tmux on your device, please run the following commands:
sudo apt update && apt install tmuxAfter you SSH into the device (using a terminal or VSCode's Remote-SSH), start a new tmux session as:
tmux new -s mysessionwhere "mysession" is simply the name given to this tmux session. Note that the prompt will change slightly once inside the tmux session. Inside, you can interact with it as a normal terminal and run any process.
At any point, the user can "detach" from tmux and the process will keep running in the background. To do this, please press: 'Ctrl + b' (release both) then press 'd'. This detaches from the session and brings you back to the normal shell while the program continues running.
If the SSH connection drops or you log in again later, list running tmux sessions as:
tmux lsThe user will be prompted with something like:
mysession: 1 windows (created Thu Jul 3 14:32:51 2025) [80x24]To reattach to the tmux session, simply use:
tmux attach -t mysessionYouβre now back inside the process, exactly where you left off.
This project uses a set of bash scripts to manage the Docker ROS2 environment. Hereβs what each script does:
-
Purpose: Builds the Docker image using the
builderservice. -
What it does:
- Stops any running containers.
- Rebuilds the Docker image from the Dockerfile.
-
Usage:
bash scripts/build-container.sh
-
Purpose: Starts the
runnercontainer and optionally attaches to its shell. -
What it does:
- Starts the
runnercontainer in detached mode (keepsall_nodes.launch.pyrunning). - Drops you into a shell inside the container automatically.
- Starts the
-
Usage:
bash scripts/start-container.sh
This will:
- Start
all_nodes.launch.py(if not already running). - Attach you to a shell inside the container.
- Start
-
Purpose: Restarts the
runnercontainer cleanly. -
What it does:
- Stops the
runnercontainer. - Starts it again, automatically relaunching
all_nodes.launch.py. - Attaches to a shell in the container after restart.
- Stops the
-
Usage:
bash scripts/restart-container.sh
-
Purpose: Streams logs from the
runnercontainer. -
What it does:
- Shows all output from
all_nodes.launch.pyand other processes in the container.
- Shows all output from
-
Usage:
bash scripts/logs-container.sh
-
The
runnercontainer is designed to persist and automatically restart on system reboot. -
To get a shell inside the container without restarting it:
docker compose exec runner bash