diff --git a/.github/workflows/docker-ros.yml b/.github/workflows/docker-ros.yml
index 3e32f5c..ad92316 100644
--- a/.github/workflows/docker-ros.yml
+++ b/.github/workflows/docker-ros.yml
@@ -4,27 +4,51 @@ on: push
jobs:
- ros:
+ ros2-humble:
runs-on: ubuntu-latest
steps:
- uses: ika-rwth-aachen/docker-ros@main
with:
- platform: amd64,arm64
+ platform: amd64
target: run
- image-tag: ros
- base-image: rwthika/ros:latest
- command: roslaunch mqtt_client standalone.launch
- enable-industrial-ci: 'true'
+ base-image: rwthika/ros2:humble
+ command: ros2 launch mqtt_client standalone.launch.xml
+ image-tag: humble
+ rmw-implementation: rmw_zenoh_cpp
- ros2:
+ ros2-jazzy:
runs-on: ubuntu-latest
steps:
- uses: ika-rwth-aachen/docker-ros@main
with:
- platform: amd64,arm64
+ platform: amd64
target: run
- image-tag: ros2
+ base-image: rwthika/ros2:jazzy
+ command: ros2 launch mqtt_client standalone.launch.xml
+ image-tag: jazzy
enable-push-as-latest: 'true'
- base-image: rwthika/ros2:latest
- command: ros2 launch mqtt_client standalone.launch.ros2.xml
- enable-industrial-ci: 'true'
+ rmw-implementation: rmw_zenoh_cpp
+
+ ros2-kilted:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: ika-rwth-aachen/docker-ros@main
+ with:
+ platform: amd64
+ target: run
+ base-image: rwthika/ros2:kilted
+ command: ros2 launch mqtt_client standalone.launch.xml
+ image-tag: kilted
+ rmw-implementation: rmw_zenoh_cpp
+
+ ros2-rolling:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: ika-rwth-aachen/docker-ros@main
+ with:
+ platform: amd64
+ target: run
+ base-image: rwthika/ros2:rolling
+ command: ros2 launch mqtt_client standalone.launch.xml
+ image-tag: rolling
+ rmw-implementation: rmw_zenoh_cpp
diff --git a/.github/workflows/industrial_ci.yml b/.github/workflows/industrial_ci.yml
index 25bdc5f..8d6890d 100644
--- a/.github/workflows/industrial_ci.yml
+++ b/.github/workflows/industrial_ci.yml
@@ -9,13 +9,11 @@ jobs:
strategy:
matrix:
ROS_DISTRO:
- - noetic
- humble
- - iron
- jazzy
+ - kilted
- rolling
ROS_REPO:
- - testing
- main
steps:
- uses: actions/checkout@v3
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 663fb66..16bf4a2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,26 +1,11 @@
-ros:
- trigger:
- include:
- - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml
- strategy: depend
- variables:
- IMAGE_TAG: ros
- BASE_IMAGE: rwthika/ros:latest
- COMMAND: roslaunch mqtt_client standalone.launch
- PLATFORM: amd64,arm64
- TARGET: dev,run
- ENABLE_INDUSTRIAL_CI: 'true'
-
ros2:
trigger:
include:
- remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml
strategy: depend
variables:
- IMAGE_TAG: ros2
- BASE_IMAGE: rwthika/ros2:latest
- COMMAND: ros2 launch mqtt_client standalone.launch.ros2.xml
PLATFORM: amd64,arm64
TARGET: dev,run
- ENABLE_INDUSTRIAL_CI: 'true'
- ENABLE_PUSH_AS_LATEST: 'true'
+ BASE_IMAGE: rwthika/ros2:jazzy
+ COMMAND: ros2 launch mqtt_client standalone.launch.xml
+ RMW_IMPLEMENTATION: rmw_zenoh_cpp
diff --git a/README.md b/README.md
index 4627672..670bed8 100644
--- a/README.md
+++ b/README.md
@@ -5,12 +5,11 @@
-
-
+
-The *mqtt_client* package provides a ROS nodelet or ROS 2 component node that enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the [MQTT](http://mqtt.org) protocol. This works generically for arbitrary ROS message types. The *mqtt_client* can also exchange primitive messages with MQTT clients running on devices not based on ROS.
+The *mqtt_client* package provides a ROS 2 component node that enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the [MQTT](http://mqtt.org) protocol. This works generically for arbitrary ROS message types. The *mqtt_client* can also exchange primitive messages with MQTT clients running on devices not based on ROS.
> [!IMPORTANT]
> This repository is open-sourced and maintained by the [**Institute for Automotive Engineering (ika) at RWTH Aachen University**](https://www.ika.rwth-aachen.de/).
@@ -27,29 +26,23 @@ The *mqtt_client* package provides a ROS nodelet or ROS 2 component node that en
- [Primitive Messages](#primitive-messages)
- [Latency Computation](#latency-computation)
- [Package Summary](#package-summary)
-- [How It Works](#how-it-works)
- [Acknowledgements](#acknowledgements)
## Installation
-The *mqtt_client* package is released as an official ROS / ROS 2 package and can easily be installed via a package manager.
+The *mqtt_client* package is released as an official ROS 2 package and can easily be installed via a package manager.
```bash
sudo apt update
sudo apt install ros-$ROS_DISTRO-mqtt-client
```
-If you would like to install *mqtt_client* from source, simply clone this repository into your ROS workspace. All dependencies that are listed in the ROS [`package.xml`](package.xml) can be installed using [*rosdep*](http://wiki.ros.org/rosdep).
+If you would like to install *mqtt_client* from source, simply clone this repository into your ROS 2 workspace. All dependencies that are listed in the ROS [`package.xml`](package.xml) can be installed using [*rosdep*](http://wiki.ros.org/rosdep).
```bash
# mqtt_client$
rosdep install -r --ignore-src --from-paths .
-# ROS
-# workspace$
-catkin build -DCMAKE_BUILD_TYPE=Release mqtt_client
-
-# ROS 2
# workspace$
colcon build --packages-up-to mqtt_client --cmake-args -DCMAKE_BUILD_TYPE=Release
```
@@ -59,11 +52,7 @@ colcon build --packages-up-to mqtt_client --cmake-args -DCMAKE_BUILD_TYPE=Releas
*mqtt_client* is also available as a Docker image, containerized through [*docker-ros*](https://github.com/ika-rwth-aachen/docker-ros).
```bash
-# ROS
-docker run --rm ghcr.io/ika-rwth-aachen/mqtt_client:ros
-
-# ROS 2
-docker run --rm ghcr.io/ika-rwth-aachen/mqtt_client:ros2
+docker run --rm ghcr.io/ika-rwth-aachen/mqtt_client:latest # or distro-specific tags, e.g., :rolling
```
@@ -89,7 +78,7 @@ For a more advanced setup of your own broker, check out our instructions for run
#### Demo Configuration
-The *mqtt_client* is best configured with a ROS parameter *yaml* file. The configuration shown below (also see [`params.yaml`](mqtt_client/config/params.yaml) / [`params.ros2.yaml`](mqtt_client/config/params.ros2.yaml)) allows an exchange of messages as follows:
+The *mqtt_client* is best configured with a ROS parameter *yaml* file. The configuration shown below (also see [`params.yaml`](mqtt_client/config/params.yaml) / [`params.yaml`](mqtt_client/config/params.yaml)) allows an exchange of messages as follows:
- ROS messages received locally on ROS topic `/ping/ros` are sent to the broker on MQTT topic `pingpong/ros`;
- MQTT messages received from the broker on MQTT topic `pingpong/ros` are published locally on ROS topic `/pong/ros`;
@@ -117,14 +106,10 @@ bridge:
#### Demo Client Launch
-After building your ROS workspace, launch the *mqtt_client* node with the pre-configured demo parameters using *roslaunch*, which should yield the following output.
+Launch the *mqtt_client* node with the pre-configured demo parameters:
```bash
-# ROS
-roslaunch mqtt_client standalone.launch
-
-# ROS 2
-ros2 launch mqtt_client standalone.launch.ros2.xml
+ros2 launch mqtt_client standalone.launch.xml
```
```txt
@@ -148,49 +133,28 @@ In order to test the communication among *mqtt_clients*, publish any ROS message
```bash
# 1st terminal: publish ROS message to /ping
-
-# ROS
-rostopic pub -r 1 /ping/ros std_msgs/String "Hello MQTT"
-
-# ROS 2
ros2 topic pub /ping/ros std_msgs/msg/String "{data: \"Hello MQTT\"}"
```
```bash
# 2nd terminal: listen for ROS messages on /pong
-
-# ROS
-rostopic echo /pong/ros
-
-# ROS 2
ros2 topic echo /pong/ros
```
In order to test the communication between *mqtt_client* and other MQTT clients, publish a primitive ROS message on ROS topic `/ping/primitive`, directly publish a primitive MQTT message on MQTT topic `pingpong/primitive` and wait for responses on ROS topic `/pong/primitive`. Note that you need to restart the ROS 2 *mqtt_client* with a different config file.
```bash
-# ROS 2
# mqtt_client$
-ros2 launch mqtt_client standalone.launch.ros2.xml params_file:=$(ros2 pkg prefix mqtt_client)/share/mqtt_client/config/params.ros2.primitive.yaml
+ros2 launch mqtt_client standalone.launch.xml params_file:=$(ros2 pkg prefix mqtt_client)/share/mqtt_client/config/params.primitive.yaml
```
```bash
# 3rd terminal: publish primitive ROS message to /ping/primitive
-
-# ROS
-rostopic pub -r 1 /ping/primitive std_msgs/Int32 42
-
-# ROS2
ros2 topic pub /ping/primitive std_msgs/msg/Int32 "{data: 42}"
```
```bash
# 4th terminal: listen for primitive ROS messages on /pong/primitive
-
-# ROS
-rostopic echo /pong/primitive
-
-# ROS2
ros2 topic echo /pong/primitive
```
@@ -206,24 +170,16 @@ If everything works as expected, the second terminal should print a message at 1
You can start the *mqtt_client* node with:
```bash
-# ROS
-roslaunch mqtt_client standalone.launch
-
-# ROS 2
-ros2 launch mqtt_client standalone.launch.ros2.xml
+ros2 launch mqtt_client standalone.launch.xml
```
-This will automatically load the provided demo [`params.yaml`](mqtt_client/config/params.yaml) / [`params.ros2.yaml`](mqtt_client/config/params.ros2.yaml). If you wish to load your custom configuration file, simply pass `params_file`.
+This will automatically load the provided demo [`params.yaml`](mqtt_client/config/params.yaml) / [`params.yaml`](mqtt_client/config/params.yaml). If you wish to load your custom configuration file, simply pass `params_file`.
```bash
-# ROS
-roslaunch mqtt_client standalone.launch params_file:=""
-
-# ROS 2
-ros2 launch mqtt_client standalone.launch.ros2.xml params_file:=""
+ros2 launch mqtt_client standalone.launch.xml params_file:=""
```
-In order to exploit the benefits of *mqtt_client* being a ROS nodelet / ROS 2 component, load the nodelet / component to your own nodelet manager / component container.
+In order to exploit the benefits of *mqtt_client* being a ROS 2 component, load the component into your own component container.
### Configuration
@@ -269,35 +225,6 @@ client:
#### Bridge Parameters
-##### ROS
-
-```yaml
-bridge:
- ros2mqtt: # Array specifying which ROS topics to map to which MQTT topics
- - ros_topic: # ROS topic whose messages are transformed to MQTT messages
- mqtt_topic: # MQTT topic on which the corresponding ROS messages are sent to the broker
- primitive: # [false] whether to publish as primitive message
- inject_timestamp: # [false] whether to attach a timestamp to a ROS2MQTT payload (for latency computation on receiver side)
- advanced:
- ros:
- queue_size: # [1] ROS subscriber queue size
- mqtt:
- qos: # [0] MQTT QoS value
- retained: # [false] whether to retain MQTT message
- mqtt2ros: # Array specifying which MQTT topics to map to which ROS topics
- - mqtt_topic: # MQTT topic on which messages are received from the broker
- ros_topic: # ROS topic on which corresponding MQTT messages are published
- primitive: # [false] whether to publish as primitive message (if coming from non-ROS MQTT client)
- advanced:
- mqtt:
- qos: # [0] MQTT QoS value
- ros:
- queue_size: # [1] ROS publisher queue size
- latched: # [false] whether to latch ROS message
-```
-
-##### ROS 2
-
```yaml
bridge:
ros2mqtt: # Object specifying which ROS topics to map to which MQTT topics
@@ -350,23 +277,15 @@ The *mqtt_client* provides built-in functionality to measure the latency of tran
In order to inject the current timestamp into outgoing MQTT messages, the parameter `inject_timestamp` has to be set for the corresponding `bridge/ros2mqtt` entry. The receiving *mqtt_client* will then automatically publish the measured latency in seconds as a ROS `std_msgs/Float64` message on topic `//latencies/`.
-These latencies can be printed easily with *rostopic echo*
+These latencies can be printed easily with:
```bash
-# ROS
-rostopic echo --clear //latencies//data
-
-# ROS 2
ros2 topic echo //latencies//data
```
or plotted with [rqt_plot](http://wiki.ros.org/rqt_plot):
```bash
-# ROS
-rosrun rqt_plot rqt_plot //latencies//data
-
-# ROS 2
ros2 run rqt_plot rqt_plot //latencies//data
```
@@ -375,56 +294,25 @@ ros2 run rqt_plot rqt_plot //latencies//da
This short package summary documents the package in line with the [ROS Wiki Style Guide](http://wiki.ros.org/StyleGuide).
-### ROS
-
-#### Nodelets
-
-##### `mqtt_client/MqttClient`
-
-Enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the [MQTT](http://mqtt.org) protocol.
-
-###### Subscribed Topics
-
-- `` ([`topic_tools/ShapeShifter`](http://wiki.ros.org/topic_tools))
- ROS topic whose messages are transformed to MQTT messages and sent to the MQTT broker. May have arbitrary ROS message type.
-
-###### Published Topics
-
-- `` ([`topic_tools/ShapeShifter`](http://wiki.ros.org/topic_tools))
- ROS topic on which MQTT messages received from the MQTT broker are published. May have arbitrary ROS message type.
-- `~/latencies/` ([`std_msgs/Float64`](https://docs.ros.org/en/api/std_msgs/html/msg/Float64.html))
- Latencies measured on the message transfer to `` are published here, if the received messages have a timestamp injected (see [Latency Computation](#latency-computation)).
-
-###### Services
-
-- `~is_connected` ([`mqtt_client/srv/IsConnected`](mqtt_client_interfaces/srv/IsConnected.srv))
- Returns whether the client is connected to the MQTT broker.
-
-###### Parameters
-
-See [Configuration](#configuration).
+### Components
-### ROS 2
-
-#### Components
-
-##### `mqtt_client/MqttClient`
+#### `mqtt_client/MqttClient`
Enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the [MQTT](http://mqtt.org) protocol.
-###### Subscribed Topics
+##### Subscribed Topics
- `` ([`rclcpp::SerializedMessage`](https://docs.ros.org/en/ros2_packages/rolling/api/rclcpp/generated/classrclcpp_1_1GenericSubscription.html))
ROS topic whose messages are transformed to MQTT messages and sent to the MQTT broker. May have arbitrary ROS message type.
-###### Published Topics
+##### Published Topics
- `` ([`rclcpp::SerializedMessage`](https://docs.ros.org/en/ros2_packages/rolling/api/rclcpp/generated/classrclcpp_1_1GenericPublisher.html))
ROS topic on which MQTT messages received from the MQTT broker are published. May have arbitrary ROS message type.
- `~/latencies/` ([`std_msgs/Float64`](https://docs.ros.org/en/api/std_msgs/html/msg/Float64.html))
Latencies measured on the message transfer to `` are published here, if the received messages have a timestamp injected (see [Latency Computation](#latency-computation)).
-###### Services
+##### Services
- `~/is_connected` ([`mqtt_client/srv/IsConnected`](mqtt_client_interfaces/srv/IsConnected.srv))
Returns whether the client is connected to the MQTT broker.
@@ -435,57 +323,11 @@ Enables connected ROS-based devices or robots to exchange ROS messages via an MQ
- `~/new_mqtt2ros_bridge` ([`mqtt_client/srv/NewMqtt2RosBridge`](mqtt_client_interfaces/srv/NewMqtt2RosBridge.srv))
Returns whether a new MQTT -> ROS bridge was created.
-
-
-###### Parameters
+##### Parameters
See [Configuration](#configuration).
-## How It Works
-
-### ROS
-
-The *mqtt_client* is able to bridge ROS messages of arbitrary message type to an MQTT broker. To this end, it needs to employ generic ROS subscribers and publishers, which only take shape at runtime.
-
-These generic ROS subscribers and publishers are realized through [topic_tools::ShapeShifter](http://docs.ros.org/diamondback/api/topic_tools/html/classtopic__tools_1_1ShapeShifter.html). For each pair of `ros_topic` and `mqtt_topic` specified under `bridge/ros2mqtt/`, a ROS subscriber is setup with the following callback signature:
-
-```cpp
-void ros2mqtt(topic_tools::ShapeShifter::ConstPtr&, std::string&)
-```
-
-Inside the callback, the generic messages received on the `ros_topic` are serialized using [ros::serialization](http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes). The serialized form is then ready to be sent to the MQTT broker on the specified `mqtt_topic`.
-
-Upon retrieval of an MQTT message, it is republished as a ROS message on the ROS network. To this end, [topic_tools::ShapeShifter::morph](http://docs.ros.org/indigo/api/topic_tools/html/classtopic__tools_1_1ShapeShifter.html#a2b74b522fb49dac05d48f466b6b87d2d) is used to have the ShapeShifter publisher take the shape of the specific ROS message type.
-
-The required metainformation on the ROS message type can however only be extracted in the ROS subscriber callback of the publishing *mqtt_client* with calls to [topic_tools::ShapeShifter::getMD5Sum](http://docs.ros.org/indigo/api/topic_tools/html/classtopic__tools_1_1ShapeShifter.html#af05fbf42757658e4c6a0f99ff72f7daa), [topic_tools::ShapeShifter::getDataType](http://docs.ros.org/indigo/api/topic_tools/html/classtopic__tools_1_1ShapeShifter.html#a9d57b2285213fda5e878ce7ebc42f0fb), and [topic_tools::ShapeShifter::getMessageDefinition](http://docs.ros.org/indigo/api/topic_tools/html/classtopic__tools_1_1ShapeShifter.html#a503af7234eeba0ccefca64c4d0cc1df0). These attributes are wrapped in a ROS message of custom type [mqtt_client::RosMsgType](mqtt_client_interfaces/msg/RosMsgType.msg), serialized using [ros::serialization](http://wiki.ros.org/roscpp/Overview/MessagesSerializationAndAdaptingTypes) and also shared via the MQTT broker on a special topic.
-
-When an *mqtt_client* receives such ROS message type metainformation, it configures the corresponding ROS ShapeShifter publisher using [topic_tools::ShapeShifter::morph](http://docs.ros.org/indigo/api/topic_tools/html/classtopic__tools_1_1ShapeShifter.html#a2b74b522fb49dac05d48f466b6b87d2d).
-
-The *mqtt_client* also provides functionality to measure the latency of transferring a ROS message via an MQTT broker back to ROS. To this end, the sending client injects the current timestamp into the MQTT message. The receiving client can then compute the latency between message reception time and the injected timestamp. The information about whether a timestamp is injected is also included in the custom [mqtt_client::RosMsgType](mqtt_client_interfaces/msg/RosMsgType.msg) message that is sent before. The actual `std::vector` message payload takes on one of the following forms:
-
-```txt
-[... serialized timestamp ... | ... serialized ROS messsage ...]
-[... serialized ROS messsage ...]
-```
-
-To summarize, the dataflow is as follows:
-
-- a ROS message of arbitrary type is received on ROS topic `` and passed to the generic callback
- - ROS message type information is extracted and wrapped as a `RosMsgType`
- - ROS message type information is serialized and sent via the MQTT broker on MQTT topic `mqtt_client/ros_msg_type/`
- - the actual ROS message is serialized
- - if `inject_timestamp`, the current timestamp is serialized and concatenated with the message
- - the actual MQTT message is sent via the MQTT broker on MQTT topic ``
-- an MQTT message containing the ROS message type information is received on MQTT topic `mqtt_client/ros_msg_type/`
- - message type information is extracted and the ShapeShifter ROS publisher is configured
- - information about whether a timestamp is injected is stored for the specific topic
-- an MQTT message containing the actual ROS message is received
- - depending on whether a timestamp is injected, it is decoded into the serialized ROS message and the serialized timestamp
- - if the message contained a timestamp, the latency is computed and published on ROS topic `~/latencies/`
- - the serialized ROS message is published using the *ShapeShifter* on ROS topic ``
-
-
## Acknowledgements
This research is accomplished within the projects [6GEM](https://6gem.de/) (FKZ 16KISK036K) and [UNICAR*agil*](https://www.unicaragil.de/) (FKZ 16EMO0284K). We acknowledge the financial support for the projects by the Federal Ministry of Education and Research of Germany (BMBF).
diff --git a/mqtt_client/CMakeLists.txt b/mqtt_client/CMakeLists.txt
index de5dc92..15d14e6 100644
--- a/mqtt_client/CMakeLists.txt
+++ b/mqtt_client/CMakeLists.txt
@@ -1,9 +1,6 @@
cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR)
project(mqtt_client)
-find_package(ros_environment REQUIRED QUIET)
-set(ROS_VERSION $ENV{ROS_VERSION})
-
## Compile as C++17
add_compile_options(-std=c++17)
link_libraries("$<$,$,9.0>>:-lstdc++fs>")
@@ -11,301 +8,56 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
-# === ROS2 (AMENT) =============================================================
-if(${ROS_VERSION} EQUAL 2)
-
- find_package(ament_cmake REQUIRED)
-
- find_package(fmt REQUIRED)
- find_package(mqtt_client_interfaces REQUIRED)
- find_package(rclcpp REQUIRED)
- find_package(rclcpp_components REQUIRED)
- find_package(std_msgs REQUIRED)
-
- # Paho MQTT C++ apt package doesn't include CMake config
- # find_package(PahoMqttCpp REQUIRED)
- find_library(PahoMqttC_LIBRARY libpaho-mqtt3as.so.1 REQUIRED)
- find_library(PahoMqttCpp_LIBRARY libpaho-mqttpp3.so.1 REQUIRED)
-
- add_library(${PROJECT_NAME}_lib SHARED src/MqttClient.ros2.cpp)
-
- rclcpp_components_register_node(${PROJECT_NAME}_lib
- PLUGIN "mqtt_client::MqttClient"
- EXECUTABLE ${PROJECT_NAME}
- )
-
- target_include_directories(${PROJECT_NAME}_lib PUBLIC
- $
- $)
-
- target_link_libraries(${PROJECT_NAME}_lib
- ${PahoMqttC_LIBRARY}
- ${PahoMqttCpp_LIBRARY}
- )
-
- ament_target_dependencies(${PROJECT_NAME}_lib
- fmt
- mqtt_client_interfaces
- rclcpp
- rclcpp_components
- std_msgs
- )
-
- install(TARGETS ${PROJECT_NAME}_lib
- ARCHIVE DESTINATION lib
- LIBRARY DESTINATION lib
- RUNTIME DESTINATION bin
- )
-
- install(
- DIRECTORY launch
- DESTINATION share/${PROJECT_NAME}
- FILES_MATCHING PATTERN "*ros2*"
- )
-
- install(
- DIRECTORY config
- DESTINATION share/${PROJECT_NAME}
- FILES_MATCHING PATTERN "*ros2*"
- )
-
- # if(BUILD_TESTING)
- # find_package(ament_lint_auto REQUIRED)
- # # the following line skips the linter which checks for copyrights
- # # comment the line when a copyright and license is added to all source files
- # set(ament_cmake_copyright_FOUND TRUE)
- # # the following line skips cpplint (only works in a git repo)
- # # comment the line when this package is in a git repo and when
- # # a copyright and license is added to all source files
- # set(ament_cmake_cpplint_FOUND TRUE)
- # ament_lint_auto_find_test_dependencies()
- # endif()
-
- ament_package()
-
-# === ROS1 (CATKIN) ============================================================
-elseif(${ROS_VERSION} EQUAL 1)
-
- ## Find catkin macros and libraries
- ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
- ## is used, also find other catkin packages
- find_package(catkin REQUIRED COMPONENTS
- mqtt_client_interfaces
- nodelet
- roscpp
- std_msgs
- topic_tools
- )
-
- ## System dependencies are found with CMake's conventions
- find_package(PahoMqttCpp REQUIRED)
- set(PahoMqttCpp_LIBRARIES PahoMqttCpp::paho-mqttpp3)
-
- find_package(fmt REQUIRED)
- set(fmt_LIBRARIES fmt::fmt)
-
-
- ## Uncomment this if the package has a setup.py. This macro ensures
- ## modules and global scripts declared therein get installed
- ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
- # catkin_python_setup()
-
- ################################################
- ## Declare ROS messages, services and actions ##
- ################################################
-
- ## To declare and build messages, services or actions from within this
- ## package, follow these steps:
- ## * Let MSG_DEP_SET be the set of packages whose message types you use in
- ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
- ## * In the file package.xml:
- ## * add a build_depend tag for "message_generation"
- ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
- ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
- ## but can be declared for certainty nonetheless:
- ## * add a exec_depend tag for "message_runtime"
- ## * In this file (CMakeLists.txt):
- ## * add "message_generation" and every package in MSG_DEP_SET to
- ## find_package(catkin REQUIRED COMPONENTS ...)
- ## * add "message_runtime" and every package in MSG_DEP_SET to
- ## catkin_package(CATKIN_DEPENDS ...)
- ## * uncomment the add_*_files sections below as needed
- ## and list every .msg/.srv/.action file to be processed
- ## * uncomment the generate_messages entry below
- ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
-
- ## Generate messages in the 'msg' folder
- # add_message_files(
- # FILES
- # Message1.msg
- # Message2.msg
- # )
-
- ## Generate services in the 'srv' folder
- # add_service_files(
- # FILES
- # Service1.srv
- # Service2.srv
- # )
+find_package(ament_cmake REQUIRED)
+find_package(fmt REQUIRED)
+find_package(mqtt_client_interfaces REQUIRED)
+find_package(rclcpp REQUIRED)
+find_package(rclcpp_components REQUIRED)
+find_package(std_msgs REQUIRED)
+
+# Paho MQTT C++ apt package doesn't include CMake config
+find_library(PahoMqttC_LIBRARY libpaho-mqtt3as.so.1 REQUIRED)
+find_library(PahoMqttCpp_LIBRARY libpaho-mqttpp3.so.1 REQUIRED)
+
+add_library(${PROJECT_NAME}_lib SHARED src/MqttClient.cpp)
+
+rclcpp_components_register_node(${PROJECT_NAME}_lib
+ PLUGIN "mqtt_client::MqttClient"
+ EXECUTABLE ${PROJECT_NAME}
+)
+
+target_include_directories(${PROJECT_NAME}_lib PUBLIC
+ $
+ $)
+
+target_link_libraries(${PROJECT_NAME}_lib
+ ${PahoMqttC_LIBRARY}
+ ${PahoMqttCpp_LIBRARY}
+)
+
+ament_target_dependencies(${PROJECT_NAME}_lib
+ fmt
+ mqtt_client_interfaces
+ rclcpp
+ rclcpp_components
+ std_msgs
+)
+
+install(TARGETS ${PROJECT_NAME}_lib
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin
+)
+
+install(
+ DIRECTORY launch
+ DESTINATION share/${PROJECT_NAME}
+)
+
+install(
+ DIRECTORY config
+ DESTINATION share/${PROJECT_NAME}
+)
+
+ament_package()
- ## Generate actions in the 'action' folder
- # add_action_files(
- # FILES
- # Action1.action
- # Action2.action
- # )
-
- ## Generate added messages and services with any dependencies listed here
- # generate_messages(
- # DEPENDENCIES
- # std_msgs
- # )
-
- ################################################
- ## Declare ROS dynamic reconfigure parameters ##
- ################################################
-
- ## To declare and build dynamic reconfigure parameters within this
- ## package, follow these steps:
- ## * In the file package.xml:
- ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
- ## * In this file (CMakeLists.txt):
- ## * add "dynamic_reconfigure" to
- ## find_package(catkin REQUIRED COMPONENTS ...)
- ## * uncomment the "generate_dynamic_reconfigure_options" section below
- ## and list every .cfg file to be processed
-
- ## Generate dynamic reconfigure parameters in the 'cfg' folder
- # generate_dynamic_reconfigure_options(
- # cfg/params.cfg
- # )
-
- ###################################
- ## catkin specific configuration ##
- ###################################
- ## The catkin_package macro generates cmake config files for your package
- ## Declare things to be passed to dependent projects
- ## INCLUDE_DIRS: uncomment this if your package contains header files
- ## LIBRARIES: libraries you create in this project that dependent projects also need
- ## CATKIN_DEPENDS: catkin_packages dependent projects also need
- ## DEPENDS: system dependencies of this project that dependent projects also need
- catkin_package(
- INCLUDE_DIRS include
- LIBRARIES ${PROJECT_NAME}
- CATKIN_DEPENDS
- nodelet
- roscpp
- std_msgs
- topic_tools
- DEPENDS
- fmt
- PahoMqttCpp
- )
-
- ###########
- ## Build ##
- ###########
-
- ## Specify additional locations of header files
- ## Your package locations should be listed before other locations
- include_directories(
- include
- ${catkin_INCLUDE_DIRS}
- )
-
- ## Declare a C++ library
- add_library(${PROJECT_NAME}
- src/MqttClient.cpp
- )
-
- ## Add cmake target dependencies of the library
- ## as an example, code may need to be generated before libraries
- ## either from message generation or dynamic reconfigure
- # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
-
- ## Declare a C++ executable
- ## With catkin_make all packages are built within a single CMake context
- ## The recommended prefix ensures that target names across packages don't collide
- # add_executable(${PROJECT_NAME}_node src/hx_testmanager_node.cpp)
-
- ## Rename C++ executable without prefix
- ## The above recommended prefix causes long target names, the following renames the
- ## target back to the shorter version for ease of user use
- ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
- # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
-
- ## Add cmake target dependencies of the executable
- ## same as for the library above
- add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
-
- ## Specify libraries to link a library or executable target against
- target_link_libraries(${PROJECT_NAME}
- ${catkin_LIBRARIES}
- ${fmt_LIBRARIES}
- ${PahoMqttCpp_LIBRARIES}
- )
-
- #############
- ## Install ##
- #############
-
- # all install targets should use catkin DESTINATION variables
- # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
-
- ## Mark executable scripts (Python etc.) for installation
- ## in contrast to setup.py, you can choose the destination
- # install(PROGRAMS
- # scripts/my_python_script
- # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
- # )
-
- ## Mark executables and/or libraries for installation
- install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}
- ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
- LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
- RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
- )
-
- ## Mark cpp header files for installation
- install(DIRECTORY include/${PROJECT_NAME}/
- DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
- # FILES_MATCHING PATTERN "*.h"
- # PATTERN ".svn" EXCLUDE
- )
-
- ## Mark other files for installation (e.g. launch and bag files, etc.)
- install(FILES
- nodelet_plugins.xml
- DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
- )
- install(DIRECTORY
- launch
- DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
- PATTERN "*ros2*" EXCLUDE
- )
- install(DIRECTORY
- config
- DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
- PATTERN "*ros2*" EXCLUDE
- )
-
- #############
- ## Testing ##
- #############
-
- ## Add gtest based cpp test target and link libraries
- # catkin_add_gtest(${PROJECT_NAME}-test test/test_hx_testmanager.cpp)
- #if(CATKIN_ENABLE_TESTING)
- # find_package(rostest REQUIRED)
- # add_rostest_gtest(test_ika_dogm test/ika_dogm.test test/UnitTest.cpp)
- # catkin_add_gtest(test_ika_dogm test/UnitTest.cpp)
- # target_link_libraries(test_ika_dogm ${catkin_LIBRARIES} ${PROJECT_NAME}_dogm_creation)
- #endif()
- # if(TARGET ${PROJECT_NAME}-test)
- # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
- # endif()
-
- ## Add folders to be run by python nosetests
- # catkin_add_nosetests(test)
-
-endif()
diff --git a/mqtt_client/config/params.aws.yaml b/mqtt_client/config/params.aws.yaml
index 4114b8d..d330469 100644
--- a/mqtt_client/config/params.aws.yaml
+++ b/mqtt_client/config/params.aws.yaml
@@ -1,49 +1,52 @@
-# YAML alias for MQTT SSL version.
-# The supported values are defined at:
-# https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/mqtt/ssl_options.h#L305
-tls_1_2: &tls_1_2 3
-
-broker:
- # YOU MUST CHANGE THIS ENDPOINT
- # Can be found by executing: aws iot describe-endpoint --endpoint-type iot:Data-ATS
- host: not-a-real-endpoint-please-use-your-own.us-west-2.amazonaws.com
- port: 8883
- tls:
- enabled: true
- # Available at https://www.amazontrust.com/repository/AmazonRootCA1.pem
- ca_certificate: path/to/AmazonRootCA1.pem
-client:
- id: user
- # Whether or not to start a clean session with each reconnect.
- # If True, the server will forget all subscriptions with each reconnect.
- # Set False to request that the server resume an existing session or start
- # a new session that may be resumed after a connection loss.
- clean_session: false
- # The keep alive value, in seconds, to send in CONNECT packet.
- keep_alive_interval: 6.0
- tls:
- # The certificate generated by the AWS IoT Core service
- certificate: path/to/a-certificate.pem
- # The private key generated by the AWS IoT Core service
- key: path/to/a-private-key.pem
- # AWS uses TLS v1.2 to encrypt all communication.
- version: *tls_1_2
- verify: true
- # https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_protos.html
- alpn_protos:
- # MQTT over AWS IOT requires an ALPN protocol negotiation.
- # https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
- - x-amzn-mqtt-ca
- buffer:
- enabled: true
-bridge:
- # NOTE: It seems that AWS IOT only supports primitive topics. Using non-primitive
- # types results in the error message `Connection to broker lost, will try to reconnect...`
- ros2mqtt:
- - ros_topic: /ping/primitive
- mqtt_topic: pingpong/primitive
- primitive: true
- mqtt2ros:
- - mqtt_topic: pingpong/primitive
- ros_topic: /pong/primitive
- primitive: true
+/**/*:
+ ros__parameters:
+ broker:
+ # YOU MUST CHANGE THIS ENDPOINT
+ # Can be found by executing: aws iot describe-endpoint --endpoint-type iot:Data-ATS
+ host: not-a-real-endpoint-please-use-your-own.us-west-2.amazonaws.com
+ port: 8883
+ tls:
+ enabled: true
+ # Available at https://www.amazontrust.com/repository/AmazonRootCA1.pem
+ ca_certificate: path/to/AmazonRootCA1.pem
+ client:
+ id: user
+ # Whether or not to start a clean session with each reconnect.
+ # If True, the server will forget all subscriptions with each reconnect.
+ # Set False to request that the server resume an existing session or start
+ # a new session that may be resumed after a connection loss.
+ clean_session: false
+ # The keep alive value, in seconds, to send in CONNECT packet.
+ keep_alive_interval: 6.0
+ tls:
+ # The certificate generated by the AWS IoT Core service
+ certificate: path/to/a-certificate.pem
+ # The private key generated by the AWS IoT Core service
+ key: path/to/a-private-key.pem
+ # AWS uses TLS v1.2 to encrypt all communication.
+ # The supported values are defined at:
+ # https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/mqtt/ssl_options.h#L305
+ version: 3 # TLS v1.2
+ verify: true
+ # https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_protos.html
+ alpn_protos:
+ # MQTT over AWS IOT requires an ALPN protocol negotiation.
+ # https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
+ - x-amzn-mqtt-ca
+ buffer:
+ enabled: true
+ bridge:
+ # NOTE: It seems that AWS IOT only supports primitive topics. Using non-primitive
+ # types results in the error message `Connection to broker lost, will try to reconnect...`
+ ros2mqtt:
+ ros_topics:
+ - /ping/primitive
+ /ping/primitive:
+ mqtt_topic: pingpong/primitive
+ primitive: true
+ mqtt2ros:
+ mqtt_topics:
+ - pingpong/primitive
+ pingpong/primitive:
+ ros_topic: /pong/primitive
+ primitive: true
diff --git a/mqtt_client/config/params.ros2.fixed-type-and-qos.yaml b/mqtt_client/config/params.fixed-type-and-qos.yaml
similarity index 100%
rename from mqtt_client/config/params.ros2.fixed-type-and-qos.yaml
rename to mqtt_client/config/params.fixed-type-and-qos.yaml
diff --git a/mqtt_client/config/params.ros2.primitive-fixed-type-and-qos.yaml b/mqtt_client/config/params.primitive-fixed-type-and-qos.yaml
similarity index 100%
rename from mqtt_client/config/params.ros2.primitive-fixed-type-and-qos.yaml
rename to mqtt_client/config/params.primitive-fixed-type-and-qos.yaml
diff --git a/mqtt_client/config/params.ros2.primitive.yaml b/mqtt_client/config/params.primitive.yaml
similarity index 100%
rename from mqtt_client/config/params.ros2.primitive.yaml
rename to mqtt_client/config/params.primitive.yaml
diff --git a/mqtt_client/config/params.ros2.aws.yaml b/mqtt_client/config/params.ros2.aws.yaml
deleted file mode 100644
index d330469..0000000
--- a/mqtt_client/config/params.ros2.aws.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-/**/*:
- ros__parameters:
- broker:
- # YOU MUST CHANGE THIS ENDPOINT
- # Can be found by executing: aws iot describe-endpoint --endpoint-type iot:Data-ATS
- host: not-a-real-endpoint-please-use-your-own.us-west-2.amazonaws.com
- port: 8883
- tls:
- enabled: true
- # Available at https://www.amazontrust.com/repository/AmazonRootCA1.pem
- ca_certificate: path/to/AmazonRootCA1.pem
- client:
- id: user
- # Whether or not to start a clean session with each reconnect.
- # If True, the server will forget all subscriptions with each reconnect.
- # Set False to request that the server resume an existing session or start
- # a new session that may be resumed after a connection loss.
- clean_session: false
- # The keep alive value, in seconds, to send in CONNECT packet.
- keep_alive_interval: 6.0
- tls:
- # The certificate generated by the AWS IoT Core service
- certificate: path/to/a-certificate.pem
- # The private key generated by the AWS IoT Core service
- key: path/to/a-private-key.pem
- # AWS uses TLS v1.2 to encrypt all communication.
- # The supported values are defined at:
- # https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/mqtt/ssl_options.h#L305
- version: 3 # TLS v1.2
- verify: true
- # https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_protos.html
- alpn_protos:
- # MQTT over AWS IOT requires an ALPN protocol negotiation.
- # https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
- - x-amzn-mqtt-ca
- buffer:
- enabled: true
- bridge:
- # NOTE: It seems that AWS IOT only supports primitive topics. Using non-primitive
- # types results in the error message `Connection to broker lost, will try to reconnect...`
- ros2mqtt:
- ros_topics:
- - /ping/primitive
- /ping/primitive:
- mqtt_topic: pingpong/primitive
- primitive: true
- mqtt2ros:
- mqtt_topics:
- - pingpong/primitive
- pingpong/primitive:
- ros_topic: /pong/primitive
- primitive: true
diff --git a/mqtt_client/config/params.ros2.yaml b/mqtt_client/config/params.ros2.yaml
deleted file mode 100644
index dd6a862..0000000
--- a/mqtt_client/config/params.ros2.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-/**/*:
- ros__parameters:
- broker:
- host: localhost
- port: 1883
- bridge:
- ros2mqtt:
- ros_topics:
- - /ping/ros
- /ping/ros:
- mqtt_topic: pingpong/ros
- mqtt2ros:
- mqtt_topics:
- - pingpong/ros
- pingpong/ros:
- ros_topic: /pong/ros
diff --git a/mqtt_client/config/params.yaml b/mqtt_client/config/params.yaml
index bf0a2d2..dd6a862 100644
--- a/mqtt_client/config/params.yaml
+++ b/mqtt_client/config/params.yaml
@@ -1,16 +1,16 @@
-broker:
- host: localhost
- port: 1883
-bridge:
- ros2mqtt:
- - ros_topic: /ping/ros
- mqtt_topic: pingpong/ros
- - ros_topic: /ping/primitive
- mqtt_topic: pingpong/primitive
- primitive: true
- mqtt2ros:
- - mqtt_topic: pingpong/ros
- ros_topic: /pong/ros
- - mqtt_topic: pingpong/primitive
- ros_topic: /pong/primitive
- primitive: true
\ No newline at end of file
+/**/*:
+ ros__parameters:
+ broker:
+ host: localhost
+ port: 1883
+ bridge:
+ ros2mqtt:
+ ros_topics:
+ - /ping/ros
+ /ping/ros:
+ mqtt_topic: pingpong/ros
+ mqtt2ros:
+ mqtt_topics:
+ - pingpong/ros
+ pingpong/ros:
+ ros_topic: /pong/ros
diff --git a/mqtt_client/doc/mainpage.dox b/mqtt_client/doc/mainpage.dox
index 3db36d0..2afe0d9 100644
--- a/mqtt_client/doc/mainpage.dox
+++ b/mqtt_client/doc/mainpage.dox
@@ -4,7 +4,7 @@
\htmlinclude manifest.html
-\b mqtt_client provides a ROS nodelet that enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the MQTT protocol. This works generically for arbitrary ROS message types.
+\b mqtt_client provides a ROS 2 component node that enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the MQTT protocol. This works generically for arbitrary ROS message types.
Please note that this is the Code API Documentation. Check out the GitHub repository for more information on how to use the package, including a Quick Start guide.
diff --git a/mqtt_client/include/mqtt_client/MqttClient.h b/mqtt_client/include/mqtt_client/MqttClient.h
deleted file mode 100644
index e89e33a..0000000
--- a/mqtt_client/include/mqtt_client/MqttClient.h
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
-==============================================================================
-MIT License
-
-Copyright 2022 Institute for Automotive Engineering of RWTH Aachen University.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-==============================================================================
-*/
-
-
-#pragma once
-
-#include
-#include