Skip to content

Commit

Permalink
Copy params into docker image (#5)
Browse files Browse the repository at this point in the history
* Copy params into docker image

* Update service image

* Add device and robot namespace

* Format

* Move files in better dirs
  • Loading branch information
rafal-gorecki authored Jun 17, 2024
1 parent b3b04a8 commit e041742
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 17 deletions.
11 changes: 4 additions & 7 deletions .github/workflows/build-docker-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,20 @@ on:
- development
- stable
target_distro:
description:
In case of "stable" release specify the ROS distro of the existing docker image (eg.
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.
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
description: In case of "stable" release specify the date of the existing docker image in format
YYYYMMDD (eg. 20220124)
type: string
default: "20131206"
default: '20131206'
repository_dispatch:
types: [rebuild]
pull_request:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vscode

*.pyc
81 changes: 81 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
repos:
# Standard hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-added-large-files
# mesh files has to be taken into account
args: [--maxkb=3000]
- id: check-ast
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: check-xml
- id: check-yaml
- id: debug-statements
- id: destroyed-symlinks
- id: detect-private-key
- id: end-of-file-fixer
- id: fix-byte-order-marker
- id: name-tests-test
- id: mixed-line-ending
- id: trailing-whitespace

# Python hooks
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.2
hooks:
- id: pyupgrade
args: [--py36-plus]

- repo: https://github.com/psf/black
rev: 24.4.0
hooks:
- id: black
args: [--line-length=99]

- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
args: ['--ignore=E501,W503'] # ignore too long line and line break before binary operator,
# black checks it

- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
args: [--profile, black]

# XML
- repo: https://github.com/tier4/pre-commit-hooks-ros
rev: v0.8.0
hooks:
- id: prettier-package-xml
- id: sort-package-xml

# YAML
- repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt
rev: 0.2.3
hooks:
- id: yamlfmt
files: ^(?!.*compose)(?!.*ekf\.yaml$).*$
args: [--mapping, '2', --sequence, '4', --offset, '2', --width, '100']

# Copyright
- repo: local
hooks:
- id: ament_copyright
name: ament_copyright
description: Check if copyright notice is available in all files.
entry: ament_copyright
language: system

# Spellcheck
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
- id: codespell
args: [--write-changes, --uri-ignore-words-list=ist, -L manuel]
exclude: CHANGELOG\.rst|\.(svg|pyc|drawio)$
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ RUN apt-get update && apt-get install -y \
apt-get clean && \
rm -rf src build && \
rm -rf /var/lib/apt/lists/*

COPY demo/config/ /config
COPY demo/nmea_navsat.launch.py /
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,26 @@ ROS 2 driver to parse NMEA strings and publish standard ROS 2 NavSatFix message

- `~/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``.
- `~/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
## 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.
Expand All @@ -47,4 +49,14 @@ cd nmea-gps-docker/demo
docker compose up
```

You should be able to see data on `/panther/fix` topic (`ros2 topic echo /panther/fix`).
You should be able to see data on `/panther/gps/fix` topic (`ros2 topic echo /panther/gps/fix`).

### Launch Parameters

Contained within the image is a custom `/nmea_navsat.launch.py`, which is not included in the ROS 2 package for the `nmea_navsat_driver`. This was specifically added to facilitate seamless integration with Husarion robots. The following parameters are included in this launch file:

| **Parameter** | **Description** | **Default Value** |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `params_file` | Path to the parameter file for the nmea_socket_driver node. | `/config/nmea_navsat_params.yaml` |
| `robot_namespace` | Namespace to all launched nodes and use namespace as tf_prefix. This aids in differentiating between multiple robots with the same devices. | `env("ROBOT_NAMESPACE")` (`""` if not specified) |
| `device_namespace` | Namespace for the device, utilized in TF frames and preceding device topics. This aids in differentiating between multiple cameras on the same robot. | `gps` |
9 changes: 3 additions & 6 deletions demo/compose.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
services:
nmea-gps:
image: husarion/nmea-gps:humble-2.0.1-20240209
image: husarion/nmea-gps:humble-2.0.1-20240617
network_mode: host
restart: always
volumes:
- ./params:/params
command: >
ros2 run nmea_navsat_driver nmea_socket_driver --ros-args
--params-file /params/nmea_socket_driver.yaml
-r __ns:=/panther
ros2 launch /nmea_navsat.launch.py
robot_namespace:=panther
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
/**/nmea_navsat_driver:
ros__parameters:
ip: "10.15.20.2"
ip: 10.15.20.2
port: 5000
buffer_size: 4096
timeout_sec: 2
80 changes: 80 additions & 0 deletions demo/nmea_navsat.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env python3

# Copyright 2024 Husarion sp. z o.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import (
EnvironmentVariable,
LaunchConfiguration,
PythonExpression,
)
from launch_ros.actions import Node


def generate_launch_description():
device_namespace = LaunchConfiguration("device_namespace")
declare_device_namespace_arg = DeclareLaunchArgument(
"device_namespace",
default_value="gps",
description="Namespace for the device, utilized in TF frames and preceding device topics. This aids in differentiating between multiple cameras on the same robot.",
)

params_file = LaunchConfiguration("params_file")
declare_params_file_arg = DeclareLaunchArgument(
"params_file",
default_value="/config/nmea_navsat_params.yaml",
description="Path to the parameter file for the nmea_socket_driver node.",
)

robot_namespace = LaunchConfiguration("robot_namespace")
declare_robot_namespace_arg = DeclareLaunchArgument(
"robot_namespace",
default_value=EnvironmentVariable("ROBOT_NAMESPACE", default_value=""),
description="Namespace to all launched nodes and use namespace as tf_prefix. This aids in differentiating between multiple robots with the same devices.",
)

tf_prefix = PythonExpression(
["'", robot_namespace, "/' if '", robot_namespace, "' != '' else ''"]
)

nmea_driver = Node(
package="nmea_navsat_driver",
executable="nmea_socket_driver",
name=device_namespace,
namespace=robot_namespace,
parameters=[
{
"frame_id": device_namespace,
"tf_prefix": tf_prefix,
},
params_file,
],
remappings=[
("fix", "~/fix"),
("heading", "~/heading"),
("time_reference", "~/time_reference"),
("vel", "~/vel"),
],
)

return LaunchDescription(
[
declare_params_file_arg,
declare_robot_namespace_arg,
declare_device_namespace_arg,
nmea_driver,
]
)

0 comments on commit e041742

Please sign in to comment.