Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 64 additions & 67 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,83 +1,80 @@
# Dockerfile
# Accept BASE_IMAGE as a build argument with a default value
ARG BASE_IMAGE=osrf/ros:iron-desktop
ARG BASE_IMAGE=ros:jazzy-perception
FROM ${BASE_IMAGE}

# Set environment variable to prevent interactive prompts during package installation
ENV DEBIAN_FRONTEND noninteractive
ENV QT_X11_NO_MITSHM 1
ENV TERM xterm-256color
# Remove the default "ubuntu" user so that UID 1000 is free.
RUN userdel -r ubuntu || true

# Install APT packages including Python and pip
RUN apt-get update && apt-get install -y \
# Ubuntu essentials
apt-utils \
wget \
unzip \
git-all \
# Python essentials
# python3 \
# python3-pip \
# python3-venv \
# python3-tk \
# Libraries for X11 visualization
libx11-dev \
libxrender1 \
libxext6 \
libfontconfig1 \
# Other dependencies
libglib2.0-0 \
# Agilex dependencies
libasio-dev \
kmod \
iproute2 \
can-utils \
net-tools \
ros-iron-xacro \
# Nav2 dependencies
ros-iron-navigation2 \
ros-iron-nav2-bringup \
ros-iron-mapviz \
ros-iron-mapviz-plugins \
ros-iron-tile-map \
# Remove cached data
&& rm -rf /var/lib/apt/lists/*
# Set environment variables to avoid interactive prompts and to configure terminal behavior.
ENV DEBIAN_FRONTEND=noninteractive
ENV QT_X11_NO_MITSHM=1
ENV TERM=xterm-256color

# # Upgrade pip to the latest version (optional but recommended)
# # RUN pip3 install --upgrade pip --break-system-packages
# Install common APT packages, then conditionally install Mapviz on x86.
RUN apt update && \
apt install -y \
libasio-dev \
apt-utils \
nano \
wget \
unzip \
git-all \
libx11-dev \
libxrender1 \
libxext6 \
libfontconfig1 \
libglib2.0-0 \
kmod \
iproute2 \
can-utils \
net-tools \
python3-tk \
ros-jazzy-xacro \
ros-jazzy-navigation2 \
ros-jazzy-nav2-bringup \
ros-jazzy-teleop-twist-keyboard \
sudo && \
\
# Detect device architecture.
arch="$(dpkg --print-architecture)" && \
echo "Detected architecture: ${arch}" && \
if [ "${arch}" = "amd64" ]; then \
echo "Installing Mapviz packages on x86…" && \
apt install -y \
ros-jazzy-mapviz \
ros-jazzy-mapviz-plugins \
ros-jazzy-tile-map ; \
else \
echo "Skipping Mapviz packages on ${arch}" ; \
fi && \
\
# Clean up apt cache.
rm -rf /var/lib/apt/lists/*

# # Install Python packages
# RUN pip3 install --no-cache-dir --break-system-packages \
# scikit-learn \
# opencv-python \
# matplotlib \
# pandas \
# ipython \
# tqdm

# Add Build Arguments for UID and GID
ARG USER_NAME=ubuntu
# Build arguments for the new user.
ARG USER_NAME=dev
ARG USER_ID=1000
ARG GROUP_ID=1000

# Create a group with the same GID as the host
RUN groupadd --gid ${GROUP_ID} ${USER_NAME} || echo "Group ${USER_NAME} already exists"

# Create a user with the specified UID and GID
RUN useradd --uid ${USER_ID} --gid ${GROUP_ID} --shell /bin/bash --create-home ${USER_NAME}

# **Add passwordless sudo for devuser**
RUN echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USER_NAME} && \
# Create a new group and user with the specified UID/GID, and grant passwordless sudo.
RUN groupadd --gid ${GROUP_ID} ${USER_NAME} || echo "Group ${USER_NAME} already exists" && \
useradd --uid ${USER_ID} --gid ${GROUP_ID} --shell /bin/bash --create-home ${USER_NAME} && \
echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USER_NAME} && \
chmod 0440 /etc/sudoers.d/${USER_NAME}

# Switch to the non-root user
# As root, add global shell configuration for color support to /etc/bash.bashrc.
USER root
RUN echo "alias ls='ls --color=auto'" >> /etc/bash.bashrc && \
echo "export PS1='\[\e[0;32m\]\u@\h:\w\$ \[\e[m\]'" >> /etc/bash.bashrc

# Switch to the new "dev" user.
USER ${USER_NAME}

# Make sure new shells source ROS setup
RUN echo "source /opt/ros/iron/setup.bash" >> /home/${USER_NAME}/.bashrc
# Add the ROS environment setup to the dev user's .bashrc.
RUN echo "source /opt/ros/jazzy/setup.bash" >> /home/${USER_NAME}/.bashrc

# Add /home/${USER_NAME}/.local/bin to PATH
# Ensure the user's local bin is in PATH.
ENV PATH=/home/${USER_NAME}/.local/bin:${PATH}

# Set DISPLAY variable
ENV DISPLAY=:0
# Set DISPLAY for X11 forwarding.
ENV DISPLAY=:0
27 changes: 14 additions & 13 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// .devcontainer/devcontainer.json
{
"name": "ROS2 Dev Container",
"dockerComposeFile": ["../.devcontainer/docker-compose.yaml"],
"service": "app",
"workspaceFolder": "/home/dev/",
"extensions": [
"ms-python.python",
"ms-toolsai.jupyter"
],
"settings": {
"python.pythonPath": "/usr/bin/python3"
},
"remoteUser": "ubuntu"
}
"name": "ROS2 Dev Container",
"dockerComposeFile": ["../.devcontainer/docker-compose.yaml"],
"service": "app",
"workspaceFolder": "/home/dev/ros_ws",
"extensions": [
"ms-python.python",
"ms-toolsai.jupyter"
],
"settings": {
"python.pythonPath": "/usr/bin/python3"
},
"remoteUser": "dev",
"updateRemoteUserUID": false
}
8 changes: 4 additions & 4 deletions .devcontainer/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ services:
context: .
dockerfile: Dockerfile
args:
USER_NAME: "${USER_NAME}"
USER_NAME: "dev"
USER_ID: "${HOST_UID}"
GROUP_ID: "${HOST_GID}"
BASE_IMAGE: "osrf/ros:iron-desktop"
BASE_IMAGE: "ros:jazzy-perception"
container_name: ros2_dev_container
volumes:
- ..:/home/dev/
- ..:/home/dev/ros_ws
- /tmp/.X11-unix:/tmp/.X11-unix # Mount X11 socket
working_dir: /home/dev/
working_dir: /home/dev/ros_ws
environment:
- DISPLAY=${DISPLAY} # Pass the DISPLAY variable
# - NVIDIA_VISIBLE_DEVICES=all
Expand Down
25 changes: 15 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

## Step 1: Set up workspace
### Environment
1. Ubuntu 20.04 LTS
2. ROS Version: ROS2 Iron
1. Ubuntu 24.04 LTS
2. ROS Version: ROS2 Jazzy

### ROS Packages
The following ROS packages are required for this project:
Expand Down Expand Up @@ -59,8 +59,8 @@ converter:
## Step 3: Build ROS2 workspace
Build the ROS2 workspace.
```
source /opt/ros/iron/setup.bash
colcon build
source /opt/ros/jazzy/setup.bash
colcon build --cmake-args -DBUILD_TESTING=OFF
```


Expand Down Expand Up @@ -98,22 +98,27 @@ can0 311 [8] 00 00 25 C6 FF FF F0 A4

In terminal 1, run these commands to start the base node for the Scout robot:
```
source /opt/ros/iron/setup.bash && source install/setup.bash
source /opt/ros/jazzy/setup.bash && source install/setup.bash
ros2 launch scout_base scout_mini_base.launch.py
```

In terminal 2, run these commands to start the keyboard-based controller:
```
source /opt/ros/iron/setup.bash
source /opt/ros/jazzy/setup.bash
ros2 run teleop_twist_keyboard teleop_twist_keyboard
```

## Step 6: Start GPS Waypoint Following
Launch the ROS nodes in the following order:
```
ros2 launch scout_base scout_mini_base.launch.py
ros2 launch fixposition_driver_ros2 node.launch
ros2 launch nav2_tutorial gps_waypoint_follower.launch.py use_mapviz:=True
ros2 launch nav2_tutorial fp_driver_node.launch config:=fp_driver_config.yaml
ros2 launch nav2_tutorial gps_waypoint_follower.launch.py
```

For 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.py
```

Finally, start the navigation. There are two types waypoint following methods. We can only choose one method each time we execute it.
Expand All @@ -127,10 +132,10 @@ ros2 run nav2_tutorial interactive_waypoint_follower

First, the user must populate the predefined gps_waypoints.yaml file with the waypoints the robot has to follow. The user can either provide the waypoints manually or use the provided waypoint logging tool as shown below:
```
ros2 run nav2_tutorial gps_waypoint_logger
ros2 run nav2_tutorial gps_waypoint_logger /path/to/file
```

Then, call the logged_waypoint_follower script to make the robot follow the logged waypoints.
```
ros2 run nav2_tutorial logged_waypoint_follower ~/gps_waypoints.yaml
ros2 run nav2_tutorial logged_waypoint_follower /path/to/file
```
16 changes: 0 additions & 16 deletions src/nav2_tutorial/config/demo_waypoints.yaml

This file was deleted.

72 changes: 72 additions & 0 deletions src/nav2_tutorial/config/fp_driver_config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**:
ros__parameters:
# Connection to the sensor one of:
# - Serial (<device>:<baudrate>)
# stream: serial:///dev/ttyUSB0:115200
# - TCP client (<ip_address>:<port>)
stream: tcpcli://10.0.2.1:21000
# Wait time in [s] to attempt reconnecting after connection lost
reconnect_delay: 5.0
# Delay warning threshold [s]. Note that this only works if your system time is synced to the VRTK2. This must be a float.
delay_warning: 0.03

# Messages that should be used by the driver. Note that the sensor must be configured accordingly for the correct
# port used in the "connection" above.
messages:
##### Fusion output
# - Odometry and status
- "FP_A-ODOMETRY" # configuration: FP_A-ODOMETRY
- "FP_A-ODOMENU" # configuration: FP_A-ODOMENU
- "FP_A-ODOMSH" # configuration: FP_A-ODOMSH
- "FP_A-ODOMSTATUS" # configuration: FP_A-ODOMSTATUS
- "FP_A-IMUBIAS" # configuration: FP_A-IMUBIAS
- "FP_A-EOE" # configuration: FP_A-EOE_FUSION and FP_A-EOE_<epoch>
# - Transforms
- "FP_A-TF" # configuration: FP_A-TF_{POIIMUH,VRTKCAM,POIVRTK,ECEFENU0,POIPOISH}
# - IMU data
- "FP_A-RAWIMU" # configuration: FP_A-RAWIMU
- "FP_A-CORRIMU" # configuration: FP_A-CORRIMU
# - LLH output
- "FP_A-LLH" # configuration: FP_A-LLH
# - NOV_B
- "NOV_B-INSPVAX" # configuration: NOV_B-INSPVAX
##### Info messages
- "FP_A-TEXT" # configuration: FP_A-TEXT_{ERROR,WARNING,INFO,DEBUG} (one or more)
##### GNSS related data
- "FP_A-GNSSANT" # configuration: FP_A-GNSSANT
- "FP_A-GNSSCORR" # configuration: FP_A-GNSSCORR
- "FP_A-TP" # configuration: FP_A-TP
##### NMEA (see also nmea_epoch param below)
- "GGA" # configuration: NMEA-GN-GGA_<epoch> (or NMEA-GP-GGA_<epoch>)
- "GLL" # configuration: NMEA-GN-GLL_<epoch> (or NMEA-GP-GLL_<epoch>)
- "GSA" # configuration: NMEA-GN-GSA_<epoch>
- "GST" # configuration: NMEA-GN-GST_<epoch> (or NMEA-GP-GST_<epoch>)
- "GSV" # configuration: NMEA-GX-GSV_<epoch>
- "HDT" # configuration: NMEA-GN-HDT_<epoch> (or NMEA-GP-HDT_<epoch>)
- "RMC" # configuration: NMEA-GN-RMC_<epoch> (or NMEA-GP-RMC_<epoch>)
- "VTG" # configuration: NMEA-GN-VTG_<epoch> (or NMEA-GP-VTG_<epoch>)
- "ZDA" # configuration: NMEA-GN-ZDA_<epoch> (or NMEA-GP-ZDA_<epoch>)
##### GNSS only position
- "NOV_B-BESTGNSSPOS" # This can be one or both of the _GNSS1 and _GNSS2 variants

# Driver behaviour
fusion_epoch: true # Enable fusion epoch output
nmea_epoch: "GNSS" # Choice for NMEA collection, must match NMEA message configuration type (<epoch> above), "" to disable
raw_output: false # Enable raw messages output
cov_warning: false # Enable covariance warnings
nav2_mode: true # Enable nav2 mode

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 velocity

# Node parameters
output_ns: "/fixposition" # Namespace for output topics, leave empty to use node namespace
speed_topic: "/fixposition/speed" # Wheelspeed input, empty to disable
corr_topic: "/rtcm" # Correction data input, empty to disable
qos_type: "default_long" # "sensor_short", "sensor_long", "default_short", "default_long"
13 changes: 13 additions & 0 deletions src/nav2_tutorial/config/gps_waypoints.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
waypoints:
- latitude: 47.40006353779471
longitude: 8.45033844082197
yaw: 0.17418822200497155
- latitude: 47.40003329651371
longitude: 8.450346118930105
yaw: 0.00957535866359162
- latitude: 47.40004876050602
longitude: 8.450407298343837
yaw: 0.0076037629009358025
- latitude: 47.40007840701886
longitude: 8.450400027239562
yaw: -0.0017132506239294317
Loading