Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ROS 2 dockerized example for nmea GPS #3

Merged
merged 10 commits into from
Feb 16, 2024
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
97 changes: 55 additions & 42 deletions .github/workflows/build-docker-image.yaml
Original file line number Diff line number Diff line change
@@ -1,51 +1,64 @@
name: Build/Publish Docker Image
---
name: Build/Publish ROS Docker Image

on:
push:
branches:
- 'main'
workflow_dispatch:
inputs:
tag:
description: 'tag that the image will be built with'
build_type:
description: Is it a "development" or a "stable" release?
required: true
default: 'noetic'
branch:
description: 'branch that will be used to build image'
required: true
default: 'main'

default: development
type: choice
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, is it still in development or stable? I think we should aim to stabilize it and move away from reliance on this image. Are there plans to release tag v1.0.0 or something similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the docker repositories we added the development and the release build. Here are the options:
image

The purpose is to push images with date and package version.
image

After the PR is closed we can trigger the release build to make sure that image is tested and does work.
image
It adds to existing image e. g. humble-2.0.1-20240209 -stable to the tag what gives humble-2.0.1-20240209-stable.

Referring to the version. The tag of images are versions of the built package described in package.xml and the date of docker image build.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for the misunderstanding. I've used this feature before, but I was referring to the GitHub tag.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay! So after the PR I can release this!

options:
- development
- stable
target_distro:
description:
In case of "stable" release specify the ROS distro of the existing docker image (eg.
humble)
type: string
default: ardent
target_release:
description:
In case of "stable" release specify the version of the existing docker image (eg.
1.0.12)
type: string
default: 0.0.0
target_date:
description:
In case of "stable" release specify the date of the existing docker image in format
YYYYMMDD (eg. 20220124)
type: string
default: "20131206"
repository_dispatch:
types: [rebuild]
pull_request:
types:
- closed
- opened

jobs:
build_nmea_gps_ros:
runs-on: ubuntu-20.04
build:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
ros_distro: [iron, humble]

steps:

- name: Checkout
uses: actions/checkout@v1
with:
ref: ${{ github.event.inputs.branch }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
version: latest

- name: Login to Docker Registry
uses: docker/login-action@v1
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Checkout
uses: actions/checkout@v2

- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/arm64, linux/amd64
push: true
tags: husarion/nmea-gps:noetic
- name: Build Docker Image
uses: husarion-ci/[email protected]
with:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
main_branch_name: ros2
build_type: ${{ inputs.build_type }}
ros_distro: ${{ matrix.ros_distro }}
platforms: linux/amd64, linux/arm64
# variables important only for stable release
target_distro: ${{ inputs.target_distro }}
target_release: ${{ inputs.target_release }}
target_date: ${{ inputs.target_date }}
32 changes: 17 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
FROM ros:noetic-ros-core
ARG ROS_DISTRO=humble
ARG PREFIX=
FROM husarnet/ros:${PREFIX}${ROS_DISTRO}-ros-core

ARG ROS_DISTRO
ARG PREFIX

SHELL ["/bin/bash", "-c"]

WORKDIR /ros_ws
WORKDIR /ros2_ws

RUN apt-get update && \
apt-get install -y \
git \
python3-pip && \
pip3 install \
rosdep && \
git clone -b decode-udp-line https://github.com/ros-drivers/nmea_navsat_driver.git src/nmea_navsat_driver && \
RUN apt-get update && apt-get install -y \
ros-dev-tools python3-transforms3d && \
git clone -b ros2 https://github.com/ros-drivers/nmea_navsat_driver.git src/nmea_navsat_driver && \
rosdep init && \
rosdep update --rosdistro $ROS_DISTRO && \
rosdep install --from-paths src -y -i && \
rosdep install -i --from-path src --rosdistro $ROS_DISTRO -y && \
source /opt/ros/$ROS_DISTRO/setup.bash && \
catkin_make -DCATKIN_ENABLE_TESTING=0 -DCMAKE_BUILD_TYPE=Release && \
apt-get autoremove -y && \
colcon build --cmake-args -DBUILD_TESTING=OFF -DCMAKE_BUILD_TYPE=Release && \
echo $(cat /ros2_ws/src/nmea_navsat_driver/package.xml | grep '<version>' | sed -r 's/.*<version>([0-9]+.[0-9]+.[0-9]+)<\/version>/\1/g') >> /version.txt && \
# Size optimalization
apt-get remove -y \
ros-dev-tools && \
apt-get clean && \
rm -rf src build && \
rm -rf /var/lib/apt/lists/*

COPY ./ros_entrypoint.sh /
ENTRYPOINT [ "/ros_entrypoint.sh" ]
44 changes: 37 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,50 @@
# nmea-gps-docker
Building a Docker image for a GPS module

### GPS API
The repository includes a GitHub Actions workflow that automatically deploys built Docker images to the [husarion/nmea-gps-docker](https://hub.docker.com/r/husarion/nmea-gps) Docker Hub repositories. This process is based on the [ros-drivers/nmea_navsat_driver](https://github.com/ros-drivers/nmea_navsat_driver/tree/ros2) repository.

GPS data in [NMEA](https://en.wikipedia.org/wiki/NMEA_0183) format is forwarded to RPi IP address at port 5000, typically it is `10.15.20.2:5000`.
You can make sure the address is correct by typing [http://10.15.20.1](http://10.15.20.1) into your browser (Username: `admin`, Password: `Husarion1`). Navigate to `Services -> GPS -> NMEA -> NMEA forwarding -> Hostname and Port`. Remember that you must be connected to the robot's WIFi network. If changes were needed, finish the connfiguration by pressing `save & apply` at the bottom of the screen.
[![.github/workflows/build-docker-image.yaml](https://github.com/husarion/nmea-gps-docker/actions/workflows/build-docker-image.yaml/badge.svg?branch=ros2)](https://github.com/husarion/nmea-gps-docker/actions/workflows/build-docker-image.yaml)

Data frequency is 1Hz and can be interacted ether with GPSD daemon (`gpsd -N udp://10.15.20.2:5000`) or directly with [ROS package](https://github.com/ros-drivers/nmea_navsat_driver/tree/decode-udp-line) redirecting signal to ROS topic.
## ROS Nodes

### nmea_navsat_driver

ROS 2 driver to parse NMEA strings and publish standard ROS 2 NavSatFix message types. Does not require the GPSD daemon to be running.

#### Publishers

- `~/fix` [*sensor_msgs/msg/NavSatFix*]: GPS position fix reported by the device. This will be published with whatever positional and status data was available even if the device doesn't have a valid fix. Invalid fields may contain NaNs.
- `~/heading` [*geometry_msgs/msg/QuaternionStamped*]: stamped orientation of heading.
- `~/time_reference` [*sensor_msgs/msg/TimeReference*]: The timestamp from the GPS device is used as the `time_ref``.
- `~/vel` [*geometry_msgs/msg/TwistStamped*]: Velocity output from the GPS device. Only published when the device outputs valid velocity information. The driver does not calculate the velocity based on only position fixes.

#### Parameters

Node GPS parameters:
- `~/time_ref_source` [*string*, default: **'gps'**]: The value to use as the source in the `sensor_msgs/msg/TimeReference`.
- `~/useRMC` [*bool*, default: **False**]: Whether to generate position fixes from GGA sentences or RMC sentences. If True, fixes will be generated from RMC. If False, fixes will be generated based on the GGA sentences. Using GGA sentences allows for approximated covariance output while RMC provides velocity information.
- `~/frame_id` [*string*, default: **'gps'**]: The`frame_id` for the header of the `sensor_msgs/msg/NavSatFix` and `geometry_msgs/msg/TwistStamped` output messages. Will be resolved with `tf_prefix` if defined.
- `~/tf_prefix` [*string*, default: **''**]: Adds prefix to the `frame_id`.

`nmea_socket_driver.py` parameters:
- `~/ip` [*string*, default: **'0.0.0.0'**]: The ip of socket server.
- `~/port` [*int*, default: **10110**]: The port of socket server.
- `~/buffer_size` [*int*, default: **4096**]: Communication buffer.
- `~/timeout_sec` [*double*, default: **2**]: Timeout during waiting for packages in the socket.

# Panther Demo

GPS data in [NMEA](https://en.wikipedia.org/wiki/NMEA_0183) format is forwarded to RPi IP address at port 5000, typically it is `10.15.20.2:5000`.
You can make sure the address is correct by typing [http://10.15.20.1](http://10.15.20.1) into your browser (Username: `admin`, Password: `Husarion1`). Navigate to `Services -> GPS -> NMEA -> NMEA forwarding -> Hostname and Port`. Remember that you must be connected to the robot's WIFi network. If changes were needed, finish the configuration by pressing `save & apply` at the bottom of the screen.

Data frequency is 1Hz and can be interacted ether with GPSD daemon (`gpsd -N udp://10.15.20.2:5000`) or directly with [ROS package](https://github.com/ros-drivers/nmea_navsat_driver/tree/ros2) redirecting signal to ROS 2 topic.

It is recommended to use docker image. To start the container type:

```bash
git clone https://github.com/husarion/nmea-gps-docker.git
cd nmea-gps-docker
cd nmea-gps-docker/demo

docker compose up
```

You should be able to see data on `/panther/fix` topic (`rostopic echo /panther/fix`).
You should be able to see data on `/panther/fix` topic (`ros2 topic echo /panther/fix`).
13 changes: 0 additions & 13 deletions compose.yaml

This file was deleted.

10 changes: 10 additions & 0 deletions demo/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:
nmea-gps:
image: husarion/nmea-gps:humble-2.0.1-20240209
network_mode: host
volumes:
- ./params:/params
command: >
ros2 run nmea_navsat_driver nmea_socket_driver --ros-args
--params-file /params/nmea_socket_driver.yaml
-r __ns:=/panther
6 changes: 6 additions & 0 deletions demo/params/nmea_socket_driver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**/nmea_navsat_driver:
ros__parameters:
ip: "10.15.20.2"
port: 5000
buffer_size: 4096
timeout_sec: 2
7 changes: 0 additions & 7 deletions ros_entrypoint.sh

This file was deleted.

Loading