├── .clang-format
├── .github
└── workflows
│ ├── docker-ros.yml
│ └── industrial_ci.yml
├── .gitignore
├── .gitlab-ci.yml
├── LICENSE
├── README.md
├── mqtt_client
├── CHANGELOG.rst
├── CMakeLists.txt
├── config
│ ├── params.aws.yaml
│ ├── params.ros2.aws.yaml
│ ├── params.ros2.fixed-type-and-qos.yaml
│ ├── params.ros2.primitive-fixed-type-and-qos.yaml
│ ├── params.ros2.primitive.yaml
│ ├── params.ros2.yaml
│ └── params.yaml
├── doc
│ └── mainpage.dox
├── include
│ └── mqtt_client
│ │ ├── MqttClient.h
│ │ └── MqttClient.ros2.hpp
├── launch
│ ├── standalone.launch
│ └── standalone.launch.ros2.xml
├── nodelet_plugins.xml
├── package.xml
└── src
│ ├── MqttClient.cpp
│ └── MqttClient.ros2.cpp
└── mqtt_client_interfaces
├── CHANGELOG.rst
├── CMakeLists.txt
├── msg
└── RosMsgType.msg
├── package.xml
└── srv
├── IsConnected.srv
└── ros2
├── NewMqtt2RosBridge.srv
└── NewRos2MqttBridge.srv
/.clang-format:
--------------------------------------------------------------------------------
1 | Language: Cpp
2 | BasedOnStyle: Google
3 | AlignEscapedNewlines: Right
4 | AllowShortFunctionsOnASingleLine: Empty
5 | BraceWrapping:
6 | AfterCaseLabel: true
7 | AfterClass: true
8 | AfterControlStatement: true
9 | AfterEnum: true
10 | AfterFunction: true
11 | AfterNamespace: true
12 | AfterObjCDeclaration: true
13 | AfterStruct: true
14 | AfterUnion: true
15 | AfterExternBlock: true
16 | BeforeCatch: true
17 | BeforeElse: true
18 | ConstructorInitializerIndentWidth: 2
19 | ContinuationIndentWidth: 2
20 | IncludeCategories:
21 | - Regex: '^<[^\/]*\.h>'
22 | Priority: 1
23 | - Regex: '^<[^\/]*>'
24 | Priority: 2
25 | - Regex: '^<.*>'
26 | Priority: 3
27 | - Regex: '.*'
28 | Priority: 4
29 | IndentWidth: 2
30 | IndentWrappedFunctionNames: true
31 | KeepEmptyLinesAtTheStartOfBlocks: true
32 | MaxEmptyLinesToKeep: 2
33 | SpacesInContainerLiterals: false
--------------------------------------------------------------------------------
/.github/workflows/docker-ros.yml:
--------------------------------------------------------------------------------
1 | name: docker-ros
2 |
3 | on: push
4 |
5 | jobs:
6 |
7 | ros:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: ika-rwth-aachen/docker-ros@main
11 | with:
12 | platform: amd64,arm64
13 | target: run
14 | image-tag: ros
15 | base-image: rwthika/ros:latest
16 | command: roslaunch mqtt_client standalone.launch
17 | enable-industrial-ci: 'true'
18 |
19 | ros2:
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: ika-rwth-aachen/docker-ros@main
23 | with:
24 | platform: amd64,arm64
25 | target: run
26 | image-tag: ros2
27 | enable-push-as-latest: 'true'
28 | base-image: rwthika/ros2:latest
29 | command: ros2 launch mqtt_client standalone.launch.ros2.xml
30 | enable-industrial-ci: 'true'
31 |
--------------------------------------------------------------------------------
/.github/workflows/industrial_ci.yml:
--------------------------------------------------------------------------------
1 | name: industrial_ci
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | industrial_ci:
7 | name: ROS ${{ matrix.ROS_DISTRO }} (${{ matrix.ROS_REPO }})
8 | runs-on: ubuntu-latest
9 | strategy:
10 | matrix:
11 | ROS_DISTRO:
12 | - noetic
13 | - humble
14 | - iron
15 | - jazzy
16 | - rolling
17 | ROS_REPO:
18 | - testing
19 | - main
20 | steps:
21 | - uses: actions/checkout@v3
22 | - uses: ros-industrial/industrial_ci@master
23 | with:
24 | config: ${{ toJSON(matrix) }}
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.toptal.com/developers/gitignore/api/ros,ros2,c++,linux,macos,python,pycharm,visualstudiocode
2 | # Edit at https://www.toptal.com/developers/gitignore?templates=ros,ros2,c++,linux,macos,python,pycharm,visualstudiocode
3 |
4 | ### C++ ###
5 | # Prerequisites
6 | *.d
7 |
8 | # Compiled Object files
9 | *.slo
10 | *.lo
11 | *.o
12 | *.obj
13 |
14 | # Precompiled Headers
15 | *.gch
16 | *.pch
17 |
18 | # Compiled Dynamic libraries
19 | *.so
20 | *.dylib
21 | *.dll
22 |
23 | # Fortran module files
24 | *.mod
25 | *.smod
26 |
27 | # Compiled Static libraries
28 | *.lai
29 | *.la
30 | *.a
31 | *.lib
32 |
33 | # Executables
34 | *.exe
35 | *.out
36 | *.app
37 |
38 | ### Linux ###
39 | *~
40 |
41 | # temporary files which can be created if a process still has a handle open of a deleted file
42 | .fuse_hidden*
43 |
44 | # KDE directory preferences
45 | .directory
46 |
47 | # Linux trash folder which might appear on any partition or disk
48 | .Trash-*
49 |
50 | # .nfs files are created when an open file is removed but is still being accessed
51 | .nfs*
52 |
53 | ### macOS ###
54 | # General
55 | .DS_Store
56 | .AppleDouble
57 | .LSOverride
58 |
59 | # Icon must end with two \r
60 | Icon
61 |
62 |
63 | # Thumbnails
64 | ._*
65 |
66 | # Files that might appear in the root of a volume
67 | .DocumentRevisions-V100
68 | .fseventsd
69 | .Spotlight-V100
70 | .TemporaryItems
71 | .Trashes
72 | .VolumeIcon.icns
73 | .com.apple.timemachine.donotpresent
74 |
75 | # Directories potentially created on remote AFP share
76 | .AppleDB
77 | .AppleDesktop
78 | Network Trash Folder
79 | Temporary Items
80 | .apdisk
81 |
82 | ### macOS Patch ###
83 | # iCloud generated files
84 | *.icloud
85 |
86 | ### PyCharm ###
87 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
88 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
89 |
90 | # User-specific stuff
91 | .idea/**/workspace.xml
92 | .idea/**/tasks.xml
93 | .idea/**/usage.statistics.xml
94 | .idea/**/dictionaries
95 | .idea/**/shelf
96 |
97 | # AWS User-specific
98 | .idea/**/aws.xml
99 |
100 | # Generated files
101 | .idea/**/contentModel.xml
102 |
103 | # Sensitive or high-churn files
104 | .idea/**/dataSources/
105 | .idea/**/dataSources.ids
106 | .idea/**/dataSources.local.xml
107 | .idea/**/sqlDataSources.xml
108 | .idea/**/dynamic.xml
109 | .idea/**/uiDesigner.xml
110 | .idea/**/dbnavigator.xml
111 |
112 | # Gradle
113 | .idea/**/gradle.xml
114 | .idea/**/libraries
115 |
116 | # Gradle and Maven with auto-import
117 | # When using Gradle or Maven with auto-import, you should exclude module files,
118 | # since they will be recreated, and may cause churn. Uncomment if using
119 | # auto-import.
120 | # .idea/artifacts
121 | # .idea/compiler.xml
122 | # .idea/jarRepositories.xml
123 | # .idea/modules.xml
124 | # .idea/*.iml
125 | # .idea/modules
126 | # *.iml
127 | # *.ipr
128 |
129 | # CMake
130 | cmake-build-*/
131 |
132 | # Mongo Explorer plugin
133 | .idea/**/mongoSettings.xml
134 |
135 | # File-based project format
136 | *.iws
137 |
138 | # IntelliJ
139 | out/
140 |
141 | # mpeltonen/sbt-idea plugin
142 | .idea_modules/
143 |
144 | # JIRA plugin
145 | atlassian-ide-plugin.xml
146 |
147 | # Cursive Clojure plugin
148 | .idea/replstate.xml
149 |
150 | # SonarLint plugin
151 | .idea/sonarlint/
152 |
153 | # Crashlytics plugin (for Android Studio and IntelliJ)
154 | com_crashlytics_export_strings.xml
155 | crashlytics.properties
156 | crashlytics-build.properties
157 | fabric.properties
158 |
159 | # Editor-based Rest Client
160 | .idea/httpRequests
161 |
162 | # Android studio 3.1+ serialized cache file
163 | .idea/caches/build_file_checksums.ser
164 |
165 | ### PyCharm Patch ###
166 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
167 |
168 | # *.iml
169 | # modules.xml
170 | # .idea/misc.xml
171 | # *.ipr
172 |
173 | # Sonarlint plugin
174 | # https://plugins.jetbrains.com/plugin/7973-sonarlint
175 | .idea/**/sonarlint/
176 |
177 | # SonarQube Plugin
178 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
179 | .idea/**/sonarIssues.xml
180 |
181 | # Markdown Navigator plugin
182 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
183 | .idea/**/markdown-navigator.xml
184 | .idea/**/markdown-navigator-enh.xml
185 | .idea/**/markdown-navigator/
186 |
187 | # Cache file creation bug
188 | # See https://youtrack.jetbrains.com/issue/JBR-2257
189 | .idea/$CACHE_FILE$
190 |
191 | # CodeStream plugin
192 | # https://plugins.jetbrains.com/plugin/12206-codestream
193 | .idea/codestream.xml
194 |
195 | # Azure Toolkit for IntelliJ plugin
196 | # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
197 | .idea/**/azureSettings.xml
198 |
199 | ### Python ###
200 | # Byte-compiled / optimized / DLL files
201 | __pycache__/
202 | *.py[cod]
203 | *$py.class
204 |
205 | # C extensions
206 |
207 | # Distribution / packaging
208 | .Python
209 | build/
210 | develop-eggs/
211 | dist/
212 | downloads/
213 | eggs/
214 | .eggs/
215 | lib/
216 | lib64/
217 | parts/
218 | sdist/
219 | var/
220 | wheels/
221 | share/python-wheels/
222 | *.egg-info/
223 | .installed.cfg
224 | *.egg
225 | MANIFEST
226 |
227 | # PyInstaller
228 | # Usually these files are written by a python script from a template
229 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
230 | *.manifest
231 | *.spec
232 |
233 | # Installer logs
234 | pip-log.txt
235 | pip-delete-this-directory.txt
236 |
237 | # Unit test / coverage reports
238 | htmlcov/
239 | .tox/
240 | .nox/
241 | .coverage
242 | .coverage.*
243 | .cache
244 | nosetests.xml
245 | coverage.xml
246 | *.cover
247 | *.py,cover
248 | .hypothesis/
249 | .pytest_cache/
250 | cover/
251 |
252 | # Translations
253 | *.mo
254 | *.pot
255 |
256 | # Django stuff:
257 | *.log
258 | local_settings.py
259 | db.sqlite3
260 | db.sqlite3-journal
261 |
262 | # Flask stuff:
263 | instance/
264 | .webassets-cache
265 |
266 | # Scrapy stuff:
267 | .scrapy
268 |
269 | # Sphinx documentation
270 | docs/_build/
271 |
272 | # PyBuilder
273 | .pybuilder/
274 | target/
275 |
276 | # Jupyter Notebook
277 | .ipynb_checkpoints
278 |
279 | # IPython
280 | profile_default/
281 | ipython_config.py
282 |
283 | # pyenv
284 | # For a library or package, you might want to ignore these files since the code is
285 | # intended to run in multiple environments; otherwise, check them in:
286 | # .python-version
287 |
288 | # pipenv
289 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
290 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
291 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
292 | # install all needed dependencies.
293 | #Pipfile.lock
294 |
295 | # poetry
296 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
297 | # This is especially recommended for binary packages to ensure reproducibility, and is more
298 | # commonly ignored for libraries.
299 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
300 | #poetry.lock
301 |
302 | # pdm
303 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
304 | #pdm.lock
305 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
306 | # in version control.
307 | # https://pdm.fming.dev/#use-with-ide
308 | .pdm.toml
309 |
310 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
311 | __pypackages__/
312 |
313 | # Celery stuff
314 | celerybeat-schedule
315 | celerybeat.pid
316 |
317 | # SageMath parsed files
318 | *.sage.py
319 |
320 | # Environments
321 | .env
322 | .venv
323 | env/
324 | venv/
325 | ENV/
326 | env.bak/
327 | venv.bak/
328 |
329 | # Spyder project settings
330 | .spyderproject
331 | .spyproject
332 |
333 | # Rope project settings
334 | .ropeproject
335 |
336 | # mkdocs documentation
337 | /site
338 |
339 | # mypy
340 | .mypy_cache/
341 | .dmypy.json
342 | dmypy.json
343 |
344 | # Pyre type checker
345 | .pyre/
346 |
347 | # pytype static type analyzer
348 | .pytype/
349 |
350 | # Cython debug symbols
351 | cython_debug/
352 |
353 | # PyCharm
354 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
355 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
356 | # and can be added to the global gitignore or merged into this file. For a more nuclear
357 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
358 | #.idea/
359 |
360 | ### Python Patch ###
361 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
362 | poetry.toml
363 |
364 | # ruff
365 | .ruff_cache/
366 |
367 | # LSP config files
368 | pyrightconfig.json
369 |
370 | ### ROS ###
371 | devel/
372 | logs/
373 | bin/
374 | msg_gen/
375 | srv_gen/
376 | msg/*Action.msg
377 | msg/*ActionFeedback.msg
378 | msg/*ActionGoal.msg
379 | msg/*ActionResult.msg
380 | msg/*Feedback.msg
381 | msg/*Goal.msg
382 | msg/*Result.msg
383 | msg/_*.py
384 | build_isolated/
385 | devel_isolated/
386 |
387 | # Generated by dynamic reconfigure
388 | *.cfgc
389 | /cfg/cpp/
390 | /cfg/*.py
391 |
392 | # Ignore generated docs
393 | *.dox
394 | *.wikidoc
395 |
396 | # eclipse stuff
397 | .project
398 | .cproject
399 |
400 | # qcreator stuff
401 | CMakeLists.txt.user
402 |
403 | srv/_*.py
404 | *.pcd
405 | *.pyc
406 | qtcreator-*
407 | *.user
408 |
409 | /planning/cfg
410 | /planning/docs
411 | /planning/src
412 |
413 |
414 | # Emacs
415 | .#*
416 |
417 | # Catkin custom files
418 | CATKIN_IGNORE
419 |
420 | ### ROS2 ###
421 | install/
422 | log/
423 |
424 | # Ignore generated docs
425 |
426 | # eclipse stuff
427 |
428 | # qcreator stuff
429 |
430 |
431 |
432 | # Emacs
433 |
434 | # Colcon custom files
435 | COLCON_IGNORE
436 | AMENT_IGNORE
437 |
438 | ### VisualStudioCode ###
439 | .vscode/*
440 | !.vscode/settings.json
441 | !.vscode/tasks.json
442 | !.vscode/launch.json
443 | !.vscode/extensions.json
444 | !.vscode/*.code-snippets
445 |
446 | # Local History for Visual Studio Code
447 | .history/
448 |
449 | # Built Visual Studio Code Extensions
450 | *.vsix
451 |
452 | ### VisualStudioCode Patch ###
453 | # Ignore all local history of files
454 | .history
455 | .ionide
456 |
457 | # End of https://www.toptal.com/developers/gitignore/api/ros,ros2,c++,linux,macos,python,pycharm,visualstudiocode
458 |
459 | !mqtt_client/doc/mainpage.dox
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | ros:
2 | trigger:
3 | include:
4 | - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml
5 | strategy: depend
6 | variables:
7 | IMAGE_TAG: ros
8 | BASE_IMAGE: rwthika/ros:latest
9 | COMMAND: roslaunch mqtt_client standalone.launch
10 | PLATFORM: amd64,arm64
11 | TARGET: dev,run
12 | ENABLE_INDUSTRIAL_CI: 'true'
13 |
14 | ros2:
15 | trigger:
16 | include:
17 | - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml
18 | strategy: depend
19 | variables:
20 | IMAGE_TAG: ros2
21 | BASE_IMAGE: rwthika/ros2:latest
22 | COMMAND: ros2 launch mqtt_client standalone.launch.ros2.xml
23 | PLATFORM: amd64,arm64
24 | TARGET: dev,run
25 | ENABLE_INDUSTRIAL_CI: 'true'
26 | ENABLE_PUSH_AS_LATEST: 'true'
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Institute for Automotive Engineering of RWTH Aachen University
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mqtt_client
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | 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.
14 |
15 | > [!IMPORTANT]
16 | > This repository is open-sourced and maintained by the [**Institute for Automotive Engineering (ika) at RWTH Aachen University**](https://www.ika.rwth-aachen.de/).
17 | > **V2X Communication** is one of many research topics within our [*Vehicle Intelligence & Automated Driving*](https://www.ika.rwth-aachen.de/en/competences/fields-of-research/vehicle-intelligence-automated-driving.html) domain.
18 | > If you would like to learn more about how we can support your automated driving or robotics efforts, feel free to reach out to us!
19 | > :email: ***opensource@ika.rwth-aachen.de***
20 |
21 | - [Installation](#installation)
22 | - [docker-ros](#docker-ros)
23 | - [Usage](#usage)
24 | - [Quick Start](#quick-start)
25 | - [Launch](#launch)
26 | - [Configuration](#configuration)
27 | - [Primitive Messages](#primitive-messages)
28 | - [Latency Computation](#latency-computation)
29 | - [Package Summary](#package-summary)
30 | - [How It Works](#how-it-works)
31 | - [Acknowledgements](#acknowledgements)
32 |
33 | ## Installation
34 |
35 | The *mqtt_client* package is released as an official ROS / ROS 2 package and can easily be installed via a package manager.
36 |
37 | ```bash
38 | sudo apt update
39 | sudo apt install ros-$ROS_DISTRO-mqtt-client
40 | ```
41 |
42 | 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).
43 |
44 | ```bash
45 | # mqtt_client$
46 | rosdep install -r --ignore-src --from-paths .
47 |
48 | # ROS
49 | # workspace$
50 | catkin build -DCMAKE_BUILD_TYPE=Release mqtt_client
51 |
52 | # ROS 2
53 | # workspace$
54 | colcon build --packages-up-to mqtt_client --cmake-args -DCMAKE_BUILD_TYPE=Release
55 | ```
56 |
57 | ### docker-ros
58 |
59 | *mqtt_client* is also available as a Docker image, containerized through [*docker-ros*](https://github.com/ika-rwth-aachen/docker-ros).
60 |
61 | ```bash
62 | # ROS
63 | docker run --rm ghcr.io/ika-rwth-aachen/mqtt_client:ros
64 |
65 | # ROS 2
66 | docker run --rm ghcr.io/ika-rwth-aachen/mqtt_client:ros2
67 | ```
68 |
69 |
70 | ## Usage
71 |
72 | The *mqtt_client* can be easily integrated into an existing ROS-based system. Below, you first find a quick start guide to test the *mqtt_client* on a single machine. Then, more details are presented on how to launch and configure it in more complex applications.
73 |
74 | ### Quick Start
75 |
76 | Follow these steps to quickly launch a working *mqtt_client* that is sending ROS messages via an MQTT broker to itself.
77 |
78 | #### Demo Broker
79 |
80 | It is assumed that an MQTT broker (such as [*Mosquitto*](https://mosquitto.org/)) is running on `localhost:1883`.
81 |
82 | For this demo, you may easily launch *Mosquitto* with its default configuration using *Docker*.
83 |
84 | ```bash
85 | docker run --rm --network host --name mosquitto eclipse-mosquitto
86 | ```
87 |
88 | For a more advanced setup of your own broker, check out our instructions for running an MQTT broker in Docker with enabled authentication and encryption [here](https://github.com/ika-rwth-aachen/mqtt-in-docker).
89 |
90 | #### Demo Configuration
91 |
92 | 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:
93 |
94 | - ROS messages received locally on ROS topic `/ping/ros` are sent to the broker on MQTT topic `pingpong/ros`;
95 | - MQTT messages received from the broker on MQTT topic `pingpong/ros` are published locally on ROS topic `/pong/ros`;
96 | - primitive ROS messages received locally on ROS topic `/ping/primitive` are sent as primitive (string) messages to the broker on MQTT topic `pingpong/primitive`;
97 | - MQTT messages received from the broker on MQTT topic `pingpong/primitive` are published locally as primitive ROS messages on ROS topic `/pong/primitive`.
98 |
99 | ```yaml
100 | broker:
101 | host: localhost
102 | port: 1883
103 | bridge:
104 | ros2mqtt:
105 | - ros_topic: /ping/ros
106 | mqtt_topic: pingpong/ros
107 | - ros_topic: /ping/primitive
108 | mqtt_topic: pingpong/primitive
109 | primitive: true
110 | mqtt2ros:
111 | - mqtt_topic: pingpong/ros
112 | ros_topic: /pong/ros
113 | - mqtt_topic: pingpong/primitive
114 | ros_topic: /pong/primitive
115 | primitive: true
116 | ```
117 |
118 | #### Demo Client Launch
119 |
120 | After building your ROS workspace, launch the *mqtt_client* node with the pre-configured demo parameters using *roslaunch*, which should yield the following output.
121 |
122 | ```bash
123 | # ROS
124 | roslaunch mqtt_client standalone.launch
125 |
126 | # ROS 2
127 | ros2 launch mqtt_client standalone.launch.ros2.xml
128 | ```
129 |
130 | ```txt
131 | [ WARN] [1665575657.358869079]: Parameter 'broker/tls/enabled' not set, defaulting to '0'
132 | [ WARN] [1665575657.359798329]: Parameter 'client/id' not set, defaulting to ''
133 | [ WARN] [1665575657.359810889]: Client buffer can not be enabled when client ID is empty
134 | [ WARN] [1665575657.360300703]: Parameter 'client/clean_session' not set, defaulting to '1'
135 | [ WARN] [1665575657.360576344]: Parameter 'client/keep_alive_interval' not set, defaulting to '60.000000'
136 | [ WARN] [1665575657.360847295]: Parameter 'client/max_inflight' not set, defaulting to '65535'
137 | [ INFO] [1665575657.361281461]: Bridging ROS topic '/ping/ros' to MQTT topic 'pingpong/ros'
138 | [ INFO] [1665575657.361303380]: Bridging primitive ROS topic '/ping/primitive' to MQTT topic 'pingpong/primitive'
139 | [ INFO] [1665575657.361352809]: Bridging MQTT topic 'pingpong/ros' to ROS topic '/pong/ros'
140 | [ INFO] [1665575657.361370558]: Bridging MQTT topic 'pingpong/primitive' to primitive ROS topic '/pong/primitive'
141 | [ INFO] [1665575657.362153083]: Connecting to broker at 'tcp://localhost:1883' ...
142 | [ INFO] [1665575657.462622065]: Connected to broker at 'tcp://localhost:1883'
143 | ```
144 |
145 | Note that the *mqtt_client* successfully connected to the broker and also echoed which ROS/MQTT topics are being bridged. For testing the communication between *mqtt_client*, itself, and other MQTT clients, open five new terminals.
146 |
147 | In order to test the communication among *mqtt_clients*, publish any ROS message on ROS topic `/ping/ros` and wait for a response on ROS topic `/pong/ros`.
148 |
149 | ```bash
150 | # 1st terminal: publish ROS message to /ping
151 |
152 | # ROS
153 | rostopic pub -r 1 /ping/ros std_msgs/String "Hello MQTT"
154 |
155 | # ROS 2
156 | ros2 topic pub /ping/ros std_msgs/msg/String "{data: \"Hello MQTT\"}"
157 | ```
158 |
159 | ```bash
160 | # 2nd terminal: listen for ROS messages on /pong
161 |
162 | # ROS
163 | rostopic echo /pong/ros
164 |
165 | # ROS 2
166 | ros2 topic echo /pong/ros
167 | ```
168 |
169 | 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.
170 |
171 | ```bash
172 | # ROS 2
173 | # mqtt_client$
174 | ros2 launch mqtt_client standalone.launch.ros2.xml params_file:=$(ros2 pkg prefix mqtt_client)/share/mqtt_client/config/params.ros2.primitive.yaml
175 | ```
176 |
177 | ```bash
178 | # 3rd terminal: publish primitive ROS message to /ping/primitive
179 |
180 | # ROS
181 | rostopic pub -r 1 /ping/primitive std_msgs/Int32 42
182 |
183 | # ROS2
184 | ros2 topic pub /ping/primitive std_msgs/msg/Int32 "{data: 42}"
185 | ```
186 |
187 | ```bash
188 | # 4th terminal: listen for primitive ROS messages on /pong/primitive
189 |
190 | # ROS
191 | rostopic echo /pong/primitive
192 |
193 | # ROS2
194 | ros2 topic echo /pong/primitive
195 | ```
196 |
197 | ```bash
198 | # 5th terminal: publish primitive MQTT message to pingpong/primitive directly using mosquitto_pub
199 | docker run --rm --network host eclipse-mosquitto mosquitto_pub -h localhost -t "pingpong/primitive" --repeat 20 --repeat-delay 1 -m 69
200 | ```
201 |
202 | If everything works as expected, the second terminal should print a message at 1Hz, while the fourth terminal should print two different messages at 1Hz.
203 |
204 | ### Launch
205 |
206 | You can start the *mqtt_client* node with:
207 |
208 | ```bash
209 | # ROS
210 | roslaunch mqtt_client standalone.launch
211 |
212 | # ROS 2
213 | ros2 launch mqtt_client standalone.launch.ros2.xml
214 | ```
215 |
216 | 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`.
217 |
218 | ```bash
219 | # ROS
220 | roslaunch mqtt_client standalone.launch params_file:=""
221 |
222 | # ROS 2
223 | ros2 launch mqtt_client standalone.launch.ros2.xml params_file:=""
224 | ```
225 |
226 | 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.
227 |
228 | ### Configuration
229 |
230 | All available ROS parameters supported by the *mqtt_client* and their default values (in `[]`) are listed in the following.
231 |
232 | #### Broker Parameters
233 |
234 | ```yaml
235 | broker:
236 | host: # [localhost] IP address or hostname of the machine running the MQTT broker
237 | port: # [1883] port the MQTT broker is listening on
238 | user: # username used for authenticating to the broker (if empty, will try to connect anonymously)
239 | pass: # password used for authenticating to the broker
240 | tls:
241 | enabled: # [false] whether to connect via SSL/TLS
242 | ca_certificate: # [/etc/ssl/certs/ca-certificates.crt] CA certificate file trusted by client (relative to ROS_HOME)
243 | ```
244 |
245 | #### Client Parameters
246 |
247 | ```yaml
248 | client:
249 | id: # unique ID string used to identify the client (broker may allow empty ID and automatically generate one)
250 | buffer:
251 | size: # [0] maximum number of messages buffered by the bridge when not connected to broker (only available if client ID is not empty)
252 | directory: # [buffer] directory used to buffer messages when not connected to broker (relative to ROS_HOME)
253 | last_will:
254 | topic: # topic used for this client's last-will message (no last will, if not specified)
255 | message: # [offline] last-will message
256 | qos: # [0] QoS value for last-will message
257 | retained: # [false] whether to retain last-will message
258 | clean_session: # [true] whether to use a clean session for this client
259 | keep_alive_interval: # [60.0] keep-alive interval in seconds
260 | max_inflight: # [65535] maximum number of inflight messages
261 | tls:
262 | certificate: # client certificate file (only needed if broker requires client certificates; relative to ROS_HOME)
263 | key: # client private key file (relative to ROS_HOME)
264 | password: # client private key password
265 | version: # TLS version (https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/mqtt/ssl_options.h#L305)
266 | verify: # verify the client should conduct post-connect checks.
267 | alpn_protos: # list of ALPN protocols (https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_protos.html)
268 | ```
269 |
270 | #### Bridge Parameters
271 |
272 | ##### ROS
273 |
274 | ```yaml
275 | bridge:
276 | ros2mqtt: # Array specifying which ROS topics to map to which MQTT topics
277 | - ros_topic: # ROS topic whose messages are transformed to MQTT messages
278 | mqtt_topic: # MQTT topic on which the corresponding ROS messages are sent to the broker
279 | primitive: # [false] whether to publish as primitive message
280 | inject_timestamp: # [false] whether to attach a timestamp to a ROS2MQTT payload (for latency computation on receiver side)
281 | advanced:
282 | ros:
283 | queue_size: # [1] ROS subscriber queue size
284 | mqtt:
285 | qos: # [0] MQTT QoS value
286 | retained: # [false] whether to retain MQTT message
287 | mqtt2ros: # Array specifying which MQTT topics to map to which ROS topics
288 | - mqtt_topic: # MQTT topic on which messages are received from the broker
289 | ros_topic: # ROS topic on which corresponding MQTT messages are published
290 | primitive: # [false] whether to publish as primitive message (if coming from non-ROS MQTT client)
291 | advanced:
292 | mqtt:
293 | qos: # [0] MQTT QoS value
294 | ros:
295 | queue_size: # [1] ROS publisher queue size
296 | latched: # [false] whether to latch ROS message
297 | ```
298 |
299 | ##### ROS 2
300 |
301 | ```yaml
302 | bridge:
303 | ros2mqtt: # Object specifying which ROS topics to map to which MQTT topics
304 | ros_topics: # Array specifying which ROS topics to bridge
305 | - {{ ros_topic_name }} # The ROS topic that should be bridged, corresponds to the sub-object in the YAML
306 | {{ ros_topic_name }}:
307 | mqtt_topic: # MQTT topic on which the corresponding ROS messages are sent to the broker
308 | primitive: # [false] whether to publish as primitive message
309 | ros_type: # [*empty*] If set, the ROS msg type provided will be used. If empty, the type is automatically deduced via the publisher
310 | inject_timestamp: # [false] whether to attach a timestamp to a ROS2MQTT payload (for latency computation on receiver side)
311 | advanced:
312 | ros:
313 | queue_size: # [1] ROS subscriber queue size
314 | qos:
315 | reliability: # [auto] One of "auto", "system_default", "reliable", "best_effort". If auto, the QoS is automatically determined via the publisher
316 | durability: # [auto] One of "auto", "system_default", "volatile", "transient_local". If auto, the QoS is automatically determined via the publisher
317 | mqtt:
318 | qos: # [0] MQTT QoS value
319 | retained: # [false] whether to retain MQTT message
320 | mqtt2ros: # Object specifying which MQTT topics to map to which ROS topics
321 | mqtt_topics: # Array specifying which ROS topics to bridge
322 | - {{ mqtt_topic_name }} # The MQTT topic that should be bridged, corresponds to the sub-object in the YAML
323 | {{ mqtt_topic_name }}:
324 | ros_topic: # ROS topic on which corresponding MQTT messages are published
325 | ros_type: # [*empty*] If set, the ROS msg type provided will be used. If empty, the type is automatically deduced via the MQTT message
326 | primitive: # [false] whether to publish as primitive message (if coming from non-ROS MQTT client)
327 | advanced:
328 | mqtt:
329 | qos: # [0] MQTT QoS value
330 | ros:
331 | queue_size: # [1] ROS publisher queue size
332 | latched: # [false] whether to latch ROS message
333 | qos:
334 | reliability: # [system_default] One of "system_default", "reliable", "best_effort".
335 | durability: # [system_default] One of "system_default", "volatile", "transient_local".
336 | ```
337 |
338 | ## Primitive Messages
339 |
340 | As seen in the [Quick Start](#quick-start), the *mqtt_client* can not only exchange arbitrary ROS messages with other *mqtt_clients*, but it can also exchange primitive message data with other non-*mqtt_client* MQTT clients. This allows ROS-based devices to exchange primitive messages with devices not based on ROS. The `primitive` parameter can be set for both ROS-to-MQTT (`bridge/ros2mqtt`) and for MQTT-to-ROS (`bridge/mqtt2ros`) transmissions.
341 |
342 | If a ROS-to-MQTT transmission is configured as `primitive` and the ROS message type is one of the supported primitive ROS message types, the raw data is published as a string. The supported primitive ROS message types are [`std_msgs/String`](http://docs.ros.org/en/api/std_msgs/html/msg/String.html), [`std_msgs/Bool`](http://docs.ros.org/en/api/std_msgs/html/msg/Bool.html), [`std_msgs/Char`](http://docs.ros.org/en/api/std_msgs/html/msg/Char.html), [`std_msgs/UInt8`](http://docs.ros.org/en/api/std_msgs/html/msg/UInt8.html), [`std_msgs/UInt16`](http://docs.ros.org/en/api/std_msgs/html/msg/UInt16.html), [`std_msgs/UInt32`](http://docs.ros.org/en/api/std_msgs/html/msg/UInt32.html), [`std_msgs/UInt64`](http://docs.ros.org/en/api/std_msgs/html/msg/UInt16.html), [`std_msgs/Int8`](http://docs.ros.org/en/api/std_msgs/html/msg/Int8.html), [`std_msgs/Int16`](http://docs.ros.org/en/api/std_msgs/html/msg/Int16.html), [`std_msgs/Int32`](http://docs.ros.org/en/api/std_msgs/html/msg/Int32.html), [`std_msgs/Int64`](http://docs.ros.org/en/api/std_msgs/html/msg/Int64.html), [`std_msgs/Float32`](http://docs.ros.org/en/api/std_msgs/html/msg/Float32.html), [`std_msgs/Float32`](http://docs.ros.org/en/api/std_msgs/html/msg/Float64.html).
343 |
344 | If an MQTT-to-ROS transmission is configured as `primitive`, the MQTT message is interpreted and published as a primitive data type, if possible. The message is probed in the following order: `bool` ([`std_msgs/Bool`](http://docs.ros.org/en/api/std_msgs/html/msg/Bool.html)), `int` ([`std_msgs/Int32`](http://docs.ros.org/en/api/std_msgs/html/msg/Int32.html)), `float` ([`std_msgs/Float32`](http://docs.ros.org/en/api/std_msgs/html/msg/Float32.html)), `string` ([`std_msgs/String`](http://docs.ros.org/en/api/std_msgs/html/msg/String.html)).
345 |
346 |
347 | ## Latency Computation
348 |
349 | The *mqtt_client* provides built-in functionality to measure the latency of transferring a ROS message via an MQTT broker back to ROS. Note that this functionality is only available for non-primitive messages (see [Primitive Messages](#primitive-messages)). 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. **Naturally, this is only accurate to the level of synchronization between clocks on sending and receiving machine.**
350 |
351 | 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/`.
352 |
353 | These latencies can be printed easily with *rostopic echo*
354 |
355 | ```bash
356 | # ROS
357 | rostopic echo --clear //latencies//data
358 |
359 | # ROS 2
360 | ros2 topic echo //latencies//data
361 | ```
362 |
363 | or plotted with [rqt_plot](http://wiki.ros.org/rqt_plot):
364 |
365 | ```bash
366 | # ROS
367 | rosrun rqt_plot rqt_plot //latencies//data
368 |
369 | # ROS 2
370 | ros2 run rqt_plot rqt_plot //latencies//data
371 | ```
372 |
373 |
374 | ## Package Summary
375 |
376 | This short package summary documents the package in line with the [ROS Wiki Style Guide](http://wiki.ros.org/StyleGuide).
377 |
378 | ### ROS
379 |
380 | #### Nodelets
381 |
382 | ##### `mqtt_client/MqttClient`
383 |
384 | Enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the [MQTT](http://mqtt.org) protocol.
385 |
386 | ###### Subscribed Topics
387 |
388 | - `` ([`topic_tools/ShapeShifter`](http://wiki.ros.org/topic_tools))
389 | ROS topic whose messages are transformed to MQTT messages and sent to the MQTT broker. May have arbitrary ROS message type.
390 |
391 | ###### Published Topics
392 |
393 | - `` ([`topic_tools/ShapeShifter`](http://wiki.ros.org/topic_tools))
394 | ROS topic on which MQTT messages received from the MQTT broker are published. May have arbitrary ROS message type.
395 | - `~/latencies/` ([`std_msgs/Float64`](https://docs.ros.org/en/api/std_msgs/html/msg/Float64.html))
396 | Latencies measured on the message transfer to `` are published here, if the received messages have a timestamp injected (see [Latency Computation](#latency-computation)).
397 |
398 | ###### Services
399 |
400 | - `~is_connected` ([`mqtt_client/srv/IsConnected`](mqtt_client_interfaces/srv/IsConnected.srv))
401 | Returns whether the client is connected to the MQTT broker.
402 |
403 | ###### Parameters
404 |
405 | See [Configuration](#configuration).
406 |
407 | ### ROS 2
408 |
409 | #### Components
410 |
411 | ##### `mqtt_client/MqttClient`
412 |
413 | Enables connected ROS-based devices or robots to exchange ROS messages via an MQTT broker using the [MQTT](http://mqtt.org) protocol.
414 |
415 | ###### Subscribed Topics
416 |
417 | - `` ([`rclcpp::SerializedMessage`](https://docs.ros.org/en/ros2_packages/rolling/api/rclcpp/generated/classrclcpp_1_1GenericSubscription.html))
418 | ROS topic whose messages are transformed to MQTT messages and sent to the MQTT broker. May have arbitrary ROS message type.
419 |
420 | ###### Published Topics
421 |
422 | - `` ([`rclcpp::SerializedMessage`](https://docs.ros.org/en/ros2_packages/rolling/api/rclcpp/generated/classrclcpp_1_1GenericPublisher.html))
423 | ROS topic on which MQTT messages received from the MQTT broker are published. May have arbitrary ROS message type.
424 | - `~/latencies/` ([`std_msgs/Float64`](https://docs.ros.org/en/api/std_msgs/html/msg/Float64.html))
425 | Latencies measured on the message transfer to `` are published here, if the received messages have a timestamp injected (see [Latency Computation](#latency-computation)).
426 |
427 | ###### Services
428 |
429 | - `~/is_connected` ([`mqtt_client/srv/IsConnected`](mqtt_client_interfaces/srv/IsConnected.srv))
430 | Returns whether the client is connected to the MQTT broker.
431 |
432 | - `~/new_ros2mqtt_bridge` ([`mqtt_client/srv/NewRos2MqttBridge`](mqtt_client_interfaces/srv/NewRos2MqttBridge.srv))
433 | Returns whether a new ROS -> MQTT bridge was created.
434 |
435 | - `~/new_mqtt2ros_bridge` ([`mqtt_client/srv/NewMqtt2RosBridge`](mqtt_client_interfaces/srv/NewMqtt2RosBridge.srv))
436 | Returns whether a new MQTT -> ROS bridge was created.
437 |
438 |
439 |
440 | ###### Parameters
441 |
442 | See [Configuration](#configuration).
443 |
444 |
445 | ## How It Works
446 |
447 | ### ROS
448 |
449 | 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.
450 |
451 | 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:
452 |
453 | ```cpp
454 | void ros2mqtt(topic_tools::ShapeShifter::ConstPtr&, std::string&)
455 | ```
456 |
457 | 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`.
458 |
459 | 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.
460 |
461 | 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.
462 |
463 | 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).
464 |
465 | 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:
466 |
467 | ```txt
468 | [... serialized timestamp ... | ... serialized ROS messsage ...]
469 | [... serialized ROS messsage ...]
470 | ```
471 |
472 | To summarize, the dataflow is as follows:
473 |
474 | - a ROS message of arbitrary type is received on ROS topic `` and passed to the generic callback
475 | - ROS message type information is extracted and wrapped as a `RosMsgType`
476 | - ROS message type information is serialized and sent via the MQTT broker on MQTT topic `mqtt_client/ros_msg_type/`
477 | - the actual ROS message is serialized
478 | - if `inject_timestamp`, the current timestamp is serialized and concatenated with the message
479 | - the actual MQTT message is sent via the MQTT broker on MQTT topic ``
480 | - an MQTT message containing the ROS message type information is received on MQTT topic `mqtt_client/ros_msg_type/`
481 | - message type information is extracted and the ShapeShifter ROS publisher is configured
482 | - information about whether a timestamp is injected is stored for the specific topic
483 | - an MQTT message containing the actual ROS message is received
484 | - depending on whether a timestamp is injected, it is decoded into the serialized ROS message and the serialized timestamp
485 | - if the message contained a timestamp, the latency is computed and published on ROS topic `~/latencies/`
486 | - the serialized ROS message is published using the *ShapeShifter* on ROS topic ``
487 |
488 |
489 | ## Acknowledgements
490 |
491 | 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).
492 |
--------------------------------------------------------------------------------
/mqtt_client/CHANGELOG.rst:
--------------------------------------------------------------------------------
1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 | Changelog for package mqtt_client
3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 |
5 | 2.3.0 (2024-05-30)
6 | ------------------
7 | * Merge pull request `#61 `_ from Chance-Maritime-Technologies/dev-explicitTypes
8 | Added the ability to explicitly set type names and some QoS settings
9 | * Merge remote-tracking branch 'upstream/main' into dev-explicitTypes
10 | * Merge pull request `#63 `_ from tecnalia-medical-robotics/system-fmt
11 | Use system version of libfmt instead of rosfmt vendored one on ROS 1
12 | * Merge pull request `#60 `_ from ika-rwth-aachen/feature/nodename_in_params_file
13 | Modify ROS2 node name in params files
14 | * Merge pull request `#58 `_ from ika-rwth-aachen/feature/configure_node_name
15 | Make ROS/ROS2 node name configurable via launch file
16 | * Contributors: JayHerpin, Lennart Reiher
17 |
18 | 2.2.1 (2024-03-19)
19 | ------------------
20 | * Merge pull request #50 from babakc/main
21 | Amend AWS IoT CLI command in collect the correct endpoint
22 | * Contributors: Lennart Reiher
23 |
24 | 2.2.0 (2023-11-29)
25 | ------------------
26 | * Merge pull request `#35 `_ from mvccogo/main
27 | Dynamic registration of topics
28 | * Merge pull request `#36 `_ from ika-rwth-aachen/fix/ros1-latencies
29 | Fix bug in ros1 latency deserialization
30 | * Contributors: Lennart Reiher, Matheus V. C. Cogo, mvccogo
31 |
32 | 2.1.0 (2023-09-18)
33 | ------------------
34 | * Merge pull request #31 from ika-rwth-aachen/features/ros2-component
35 | ROS2 Component
36 | * Merge pull request #30 from oxin-ros/ros2-add-multiple-topics
37 | ROS 2: add multiple topics
38 | * Merge pull request #28 from oxin-ros/add-ALPN-protocol-support-for-aws
39 | Add ALPN protocol support for AWS
40 | * Contributors: David B, David Buckman, Lennart Reiher
41 |
42 | 2.0.1 (2023-06-10)
43 | ------------------
44 | * fix unrecognized build type with catkin_make_isolated
45 | order of statements is somehow revelant; catkin_make_isolated would not detect the build type; build farm jobs were failing; https://build.ros.org/job/Ndev__mqtt_client__ubuntu_focal_amd64/10/console
46 | * Contributors: Lennart Reiher
47 |
48 | 2.0.0 (2023-06-10)
49 | ------------------
50 | * Merge pull request #23 from ika-rwth-aachen/docker-ros
51 | Integrate docker-ros
52 | * Merge pull request #16 from ika-rwth-aachen/dev/ros2
53 | Add support for ROS2
54 | * Contributors: Lennart Reiher
55 |
56 | 1.1.0 (2022-10-13)
57 | ------------------
58 | * Merge pull request #6 from ika-rwth-aachen/feature/primitive-msgs
59 | Support exchange of primitive messages with other MQTT clients
60 | * Contributors: Lennart Reiher
61 |
62 | 1.0.2 (2022-10-07)
63 | ------------------
64 | * Merge pull request #4 from ika-rwth-aachen/improvement/runtime-optimization
65 | Optimize runtime
66 | * Merge pull request #5 from ika-rwth-aachen/ci
67 | Set up CI
68 | * Contributors: Lennart Reiher
69 |
70 | 1.0.1 (2022-08-11)
71 | ------------------
72 | * Merge pull request #3 from ika-rwth-aachen/doc/code-api
73 | Improve Code API Documentation
74 | * Merge pull request #1 from ika-rwth-aachen/improvement/documentation
75 | Improve documentation
76 | * Contributors: Lennart Reiher
77 |
--------------------------------------------------------------------------------
/mqtt_client/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.12.0 FATAL_ERROR)
2 | project(mqtt_client)
3 |
4 | find_package(ros_environment REQUIRED QUIET)
5 | set(ROS_VERSION $ENV{ROS_VERSION})
6 |
7 | ## Compile as C++17
8 | add_compile_options(-std=c++17)
9 | link_libraries("$<$,$,9.0>>:-lstdc++fs>")
10 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
11 | add_compile_options(-Wall -Wextra -Wpedantic)
12 | endif()
13 |
14 | # === ROS2 (AMENT) =============================================================
15 | if(${ROS_VERSION} EQUAL 2)
16 |
17 | find_package(ament_cmake REQUIRED)
18 |
19 | find_package(fmt REQUIRED)
20 | find_package(mqtt_client_interfaces REQUIRED)
21 | find_package(rclcpp REQUIRED)
22 | find_package(rclcpp_components REQUIRED)
23 | find_package(std_msgs REQUIRED)
24 |
25 | # Paho MQTT C++ apt package doesn't include CMake config
26 | # find_package(PahoMqttCpp REQUIRED)
27 | find_library(PahoMqttC_LIBRARY libpaho-mqtt3as.so.1 REQUIRED)
28 | find_library(PahoMqttCpp_LIBRARY libpaho-mqttpp3.so.1 REQUIRED)
29 |
30 | add_library(${PROJECT_NAME}_lib SHARED src/MqttClient.ros2.cpp)
31 |
32 | rclcpp_components_register_node(${PROJECT_NAME}_lib
33 | PLUGIN "mqtt_client::MqttClient"
34 | EXECUTABLE ${PROJECT_NAME}
35 | )
36 |
37 | target_include_directories(${PROJECT_NAME}_lib PUBLIC
38 | $
39 | $)
40 |
41 | target_link_libraries(${PROJECT_NAME}_lib
42 | ${PahoMqttC_LIBRARY}
43 | ${PahoMqttCpp_LIBRARY}
44 | )
45 |
46 | ament_target_dependencies(${PROJECT_NAME}_lib
47 | fmt
48 | mqtt_client_interfaces
49 | rclcpp
50 | rclcpp_components
51 | std_msgs
52 | )
53 |
54 | install(TARGETS ${PROJECT_NAME}_lib
55 | ARCHIVE DESTINATION lib
56 | LIBRARY DESTINATION lib
57 | RUNTIME DESTINATION bin
58 | )
59 |
60 | install(
61 | DIRECTORY launch
62 | DESTINATION share/${PROJECT_NAME}
63 | FILES_MATCHING PATTERN "*ros2*"
64 | )
65 |
66 | install(
67 | DIRECTORY config
68 | DESTINATION share/${PROJECT_NAME}
69 | FILES_MATCHING PATTERN "*ros2*"
70 | )
71 |
72 | # if(BUILD_TESTING)
73 | # find_package(ament_lint_auto REQUIRED)
74 | # # the following line skips the linter which checks for copyrights
75 | # # comment the line when a copyright and license is added to all source files
76 | # set(ament_cmake_copyright_FOUND TRUE)
77 | # # the following line skips cpplint (only works in a git repo)
78 | # # comment the line when this package is in a git repo and when
79 | # # a copyright and license is added to all source files
80 | # set(ament_cmake_cpplint_FOUND TRUE)
81 | # ament_lint_auto_find_test_dependencies()
82 | # endif()
83 |
84 | ament_package()
85 |
86 | # === ROS1 (CATKIN) ============================================================
87 | elseif(${ROS_VERSION} EQUAL 1)
88 |
89 | ## Find catkin macros and libraries
90 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
91 | ## is used, also find other catkin packages
92 | find_package(catkin REQUIRED COMPONENTS
93 | mqtt_client_interfaces
94 | nodelet
95 | roscpp
96 | std_msgs
97 | topic_tools
98 | )
99 |
100 | ## System dependencies are found with CMake's conventions
101 | find_package(PahoMqttCpp REQUIRED)
102 | set(PahoMqttCpp_LIBRARIES PahoMqttCpp::paho-mqttpp3)
103 |
104 | find_package(fmt REQUIRED)
105 | set(fmt_LIBRARIES fmt::fmt)
106 |
107 |
108 | ## Uncomment this if the package has a setup.py. This macro ensures
109 | ## modules and global scripts declared therein get installed
110 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
111 | # catkin_python_setup()
112 |
113 | ################################################
114 | ## Declare ROS messages, services and actions ##
115 | ################################################
116 |
117 | ## To declare and build messages, services or actions from within this
118 | ## package, follow these steps:
119 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in
120 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
121 | ## * In the file package.xml:
122 | ## * add a build_depend tag for "message_generation"
123 | ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
124 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
125 | ## but can be declared for certainty nonetheless:
126 | ## * add a exec_depend tag for "message_runtime"
127 | ## * In this file (CMakeLists.txt):
128 | ## * add "message_generation" and every package in MSG_DEP_SET to
129 | ## find_package(catkin REQUIRED COMPONENTS ...)
130 | ## * add "message_runtime" and every package in MSG_DEP_SET to
131 | ## catkin_package(CATKIN_DEPENDS ...)
132 | ## * uncomment the add_*_files sections below as needed
133 | ## and list every .msg/.srv/.action file to be processed
134 | ## * uncomment the generate_messages entry below
135 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
136 |
137 | ## Generate messages in the 'msg' folder
138 | # add_message_files(
139 | # FILES
140 | # Message1.msg
141 | # Message2.msg
142 | # )
143 |
144 | ## Generate services in the 'srv' folder
145 | # add_service_files(
146 | # FILES
147 | # Service1.srv
148 | # Service2.srv
149 | # )
150 |
151 | ## Generate actions in the 'action' folder
152 | # add_action_files(
153 | # FILES
154 | # Action1.action
155 | # Action2.action
156 | # )
157 |
158 | ## Generate added messages and services with any dependencies listed here
159 | # generate_messages(
160 | # DEPENDENCIES
161 | # std_msgs
162 | # )
163 |
164 | ################################################
165 | ## Declare ROS dynamic reconfigure parameters ##
166 | ################################################
167 |
168 | ## To declare and build dynamic reconfigure parameters within this
169 | ## package, follow these steps:
170 | ## * In the file package.xml:
171 | ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
172 | ## * In this file (CMakeLists.txt):
173 | ## * add "dynamic_reconfigure" to
174 | ## find_package(catkin REQUIRED COMPONENTS ...)
175 | ## * uncomment the "generate_dynamic_reconfigure_options" section below
176 | ## and list every .cfg file to be processed
177 |
178 | ## Generate dynamic reconfigure parameters in the 'cfg' folder
179 | # generate_dynamic_reconfigure_options(
180 | # cfg/params.cfg
181 | # )
182 |
183 | ###################################
184 | ## catkin specific configuration ##
185 | ###################################
186 | ## The catkin_package macro generates cmake config files for your package
187 | ## Declare things to be passed to dependent projects
188 | ## INCLUDE_DIRS: uncomment this if your package contains header files
189 | ## LIBRARIES: libraries you create in this project that dependent projects also need
190 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need
191 | ## DEPENDS: system dependencies of this project that dependent projects also need
192 | catkin_package(
193 | INCLUDE_DIRS include
194 | LIBRARIES ${PROJECT_NAME}
195 | CATKIN_DEPENDS
196 | nodelet
197 | roscpp
198 | std_msgs
199 | topic_tools
200 | DEPENDS
201 | fmt
202 | PahoMqttCpp
203 | )
204 |
205 | ###########
206 | ## Build ##
207 | ###########
208 |
209 | ## Specify additional locations of header files
210 | ## Your package locations should be listed before other locations
211 | include_directories(
212 | include
213 | ${catkin_INCLUDE_DIRS}
214 | )
215 |
216 | ## Declare a C++ library
217 | add_library(${PROJECT_NAME}
218 | src/MqttClient.cpp
219 | )
220 |
221 | ## Add cmake target dependencies of the library
222 | ## as an example, code may need to be generated before libraries
223 | ## either from message generation or dynamic reconfigure
224 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
225 |
226 | ## Declare a C++ executable
227 | ## With catkin_make all packages are built within a single CMake context
228 | ## The recommended prefix ensures that target names across packages don't collide
229 | # add_executable(${PROJECT_NAME}_node src/hx_testmanager_node.cpp)
230 |
231 | ## Rename C++ executable without prefix
232 | ## The above recommended prefix causes long target names, the following renames the
233 | ## target back to the shorter version for ease of user use
234 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
235 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
236 |
237 | ## Add cmake target dependencies of the executable
238 | ## same as for the library above
239 | add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
240 |
241 | ## Specify libraries to link a library or executable target against
242 | target_link_libraries(${PROJECT_NAME}
243 | ${catkin_LIBRARIES}
244 | ${fmt_LIBRARIES}
245 | ${PahoMqttCpp_LIBRARIES}
246 | )
247 |
248 | #############
249 | ## Install ##
250 | #############
251 |
252 | # all install targets should use catkin DESTINATION variables
253 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
254 |
255 | ## Mark executable scripts (Python etc.) for installation
256 | ## in contrast to setup.py, you can choose the destination
257 | # install(PROGRAMS
258 | # scripts/my_python_script
259 | # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
260 | # )
261 |
262 | ## Mark executables and/or libraries for installation
263 | install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}
264 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
265 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
266 | RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
267 | )
268 |
269 | ## Mark cpp header files for installation
270 | install(DIRECTORY include/${PROJECT_NAME}/
271 | DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
272 | # FILES_MATCHING PATTERN "*.h"
273 | # PATTERN ".svn" EXCLUDE
274 | )
275 |
276 | ## Mark other files for installation (e.g. launch and bag files, etc.)
277 | install(FILES
278 | nodelet_plugins.xml
279 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
280 | )
281 | install(DIRECTORY
282 | launch
283 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
284 | PATTERN "*ros2*" EXCLUDE
285 | )
286 | install(DIRECTORY
287 | config
288 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
289 | PATTERN "*ros2*" EXCLUDE
290 | )
291 |
292 | #############
293 | ## Testing ##
294 | #############
295 |
296 | ## Add gtest based cpp test target and link libraries
297 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_hx_testmanager.cpp)
298 | #if(CATKIN_ENABLE_TESTING)
299 | # find_package(rostest REQUIRED)
300 | # add_rostest_gtest(test_ika_dogm test/ika_dogm.test test/UnitTest.cpp)
301 | # catkin_add_gtest(test_ika_dogm test/UnitTest.cpp)
302 | # target_link_libraries(test_ika_dogm ${catkin_LIBRARIES} ${PROJECT_NAME}_dogm_creation)
303 | #endif()
304 | # if(TARGET ${PROJECT_NAME}-test)
305 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
306 | # endif()
307 |
308 | ## Add folders to be run by python nosetests
309 | # catkin_add_nosetests(test)
310 |
311 | endif()
312 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.aws.yaml:
--------------------------------------------------------------------------------
1 | # YAML alias for MQTT SSL version.
2 | # The supported values are defined at:
3 | # https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/mqtt/ssl_options.h#L305
4 | tls_1_2: &tls_1_2 3
5 |
6 | broker:
7 | # YOU MUST CHANGE THIS ENDPOINT
8 | # Can be found by executing: aws iot describe-endpoint --endpoint-type iot:Data-ATS
9 | host: not-a-real-endpoint-please-use-your-own.us-west-2.amazonaws.com
10 | port: 8883
11 | tls:
12 | enabled: true
13 | # Available at https://www.amazontrust.com/repository/AmazonRootCA1.pem
14 | ca_certificate: path/to/AmazonRootCA1.pem
15 | client:
16 | id: user
17 | # Whether or not to start a clean session with each reconnect.
18 | # If True, the server will forget all subscriptions with each reconnect.
19 | # Set False to request that the server resume an existing session or start
20 | # a new session that may be resumed after a connection loss.
21 | clean_session: false
22 | # The keep alive value, in seconds, to send in CONNECT packet.
23 | keep_alive_interval: 6.0
24 | tls:
25 | # The certificate generated by the AWS IoT Core service
26 | certificate: path/to/a-certificate.pem
27 | # The private key generated by the AWS IoT Core service
28 | key: path/to/a-private-key.pem
29 | # AWS uses TLS v1.2 to encrypt all communication.
30 | version: *tls_1_2
31 | verify: true
32 | # https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_protos.html
33 | alpn_protos:
34 | # MQTT over AWS IOT requires an ALPN protocol negotiation.
35 | # https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
36 | - x-amzn-mqtt-ca
37 | buffer:
38 | enabled: true
39 | bridge:
40 | # NOTE: It seems that AWS IOT only supports primitive topics. Using non-primitive
41 | # types results in the error message `Connection to broker lost, will try to reconnect...`
42 | ros2mqtt:
43 | - ros_topic: /ping/primitive
44 | mqtt_topic: pingpong/primitive
45 | primitive: true
46 | mqtt2ros:
47 | - mqtt_topic: pingpong/primitive
48 | ros_topic: /pong/primitive
49 | primitive: true
50 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.ros2.aws.yaml:
--------------------------------------------------------------------------------
1 | /**/*:
2 | ros__parameters:
3 | broker:
4 | # YOU MUST CHANGE THIS ENDPOINT
5 | # Can be found by executing: aws iot describe-endpoint --endpoint-type iot:Data-ATS
6 | host: not-a-real-endpoint-please-use-your-own.us-west-2.amazonaws.com
7 | port: 8883
8 | tls:
9 | enabled: true
10 | # Available at https://www.amazontrust.com/repository/AmazonRootCA1.pem
11 | ca_certificate: path/to/AmazonRootCA1.pem
12 | client:
13 | id: user
14 | # Whether or not to start a clean session with each reconnect.
15 | # If True, the server will forget all subscriptions with each reconnect.
16 | # Set False to request that the server resume an existing session or start
17 | # a new session that may be resumed after a connection loss.
18 | clean_session: false
19 | # The keep alive value, in seconds, to send in CONNECT packet.
20 | keep_alive_interval: 6.0
21 | tls:
22 | # The certificate generated by the AWS IoT Core service
23 | certificate: path/to/a-certificate.pem
24 | # The private key generated by the AWS IoT Core service
25 | key: path/to/a-private-key.pem
26 | # AWS uses TLS v1.2 to encrypt all communication.
27 | # The supported values are defined at:
28 | # https://github.com/eclipse/paho.mqtt.cpp/blob/master/src/mqtt/ssl_options.h#L305
29 | version: 3 # TLS v1.2
30 | verify: true
31 | # https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_alpn_protos.html
32 | alpn_protos:
33 | # MQTT over AWS IOT requires an ALPN protocol negotiation.
34 | # https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
35 | - x-amzn-mqtt-ca
36 | buffer:
37 | enabled: true
38 | bridge:
39 | # NOTE: It seems that AWS IOT only supports primitive topics. Using non-primitive
40 | # types results in the error message `Connection to broker lost, will try to reconnect...`
41 | ros2mqtt:
42 | ros_topics:
43 | - /ping/primitive
44 | /ping/primitive:
45 | mqtt_topic: pingpong/primitive
46 | primitive: true
47 | mqtt2ros:
48 | mqtt_topics:
49 | - pingpong/primitive
50 | pingpong/primitive:
51 | ros_topic: /pong/primitive
52 | primitive: true
53 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.ros2.fixed-type-and-qos.yaml:
--------------------------------------------------------------------------------
1 | /**/*:
2 | ros__parameters:
3 | broker:
4 | host: localhost
5 | port: 1883
6 | bridge:
7 | ros2mqtt:
8 | ros_topics:
9 | - /ping/primitive
10 | /ping/primitive:
11 | mqtt_topic: pingpong/primitive
12 | primitive: false
13 | ros_type: std_msgs/msg/Bool
14 | advanced:
15 | ros:
16 | queue_size: 10
17 | qos:
18 | durability: auto
19 | reliability: auto
20 | mqtt2ros:
21 | mqtt_topics:
22 | - pingpong/primitive
23 | pingpong/primitive:
24 | ros_topic: /pong/primitive
25 | primitive: false
26 | ros_type: std_msgs/msg/Bool
27 | advanced:
28 | ros:
29 | queue_size: 10
30 | qos:
31 | durability: transient_local
32 | reliability: reliable
33 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.ros2.primitive-fixed-type-and-qos.yaml:
--------------------------------------------------------------------------------
1 | /**/*:
2 | ros__parameters:
3 | broker:
4 | host: localhost
5 | port: 1883
6 | bridge:
7 | ros2mqtt:
8 | ros_topics:
9 | - /ping/primitive
10 | /ping/primitive:
11 | mqtt_topic: pingpong/primitive
12 | primitive: true
13 | ros_type: std_msgs/msg/Bool
14 | advanced:
15 | ros:
16 | queue_size: 10
17 | qos:
18 | durability: auto
19 | reliability: auto
20 | mqtt2ros:
21 | mqtt_topics:
22 | - pingpong/primitive
23 | pingpong/primitive:
24 | ros_topic: /pong/primitive
25 | primitive: true
26 | ros_type: std_msgs/msg/Bool
27 | advanced:
28 | ros:
29 | queue_size: 10
30 | qos:
31 | durability: transient_local
32 | reliability: reliable
33 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.ros2.primitive.yaml:
--------------------------------------------------------------------------------
1 | /**/*:
2 | ros__parameters:
3 | broker:
4 | host: localhost
5 | port: 1883
6 | bridge:
7 | ros2mqtt:
8 | ros_topics:
9 | - /ping/primitive
10 | /ping/primitive:
11 | mqtt_topic: pingpong/primitive
12 | primitive: true
13 | mqtt2ros:
14 | mqtt_topics:
15 | - pingpong/primitive
16 | pingpong/primitive:
17 | ros_topic: /pong/primitive
18 | primitive: true
19 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.ros2.yaml:
--------------------------------------------------------------------------------
1 | /**/*:
2 | ros__parameters:
3 | broker:
4 | host: localhost
5 | port: 1883
6 | bridge:
7 | ros2mqtt:
8 | ros_topics:
9 | - /ping/ros
10 | /ping/ros:
11 | mqtt_topic: pingpong/ros
12 | mqtt2ros:
13 | mqtt_topics:
14 | - pingpong/ros
15 | pingpong/ros:
16 | ros_topic: /pong/ros
17 |
--------------------------------------------------------------------------------
/mqtt_client/config/params.yaml:
--------------------------------------------------------------------------------
1 | broker:
2 | host: localhost
3 | port: 1883
4 | bridge:
5 | ros2mqtt:
6 | - ros_topic: /ping/ros
7 | mqtt_topic: pingpong/ros
8 | - ros_topic: /ping/primitive
9 | mqtt_topic: pingpong/primitive
10 | primitive: true
11 | mqtt2ros:
12 | - mqtt_topic: pingpong/ros
13 | ros_topic: /pong/ros
14 | - mqtt_topic: pingpong/primitive
15 | ros_topic: /pong/primitive
16 | primitive: true
--------------------------------------------------------------------------------
/mqtt_client/doc/mainpage.dox:
--------------------------------------------------------------------------------
1 | /**
2 |
3 | \mainpage
4 |
5 | \htmlinclude manifest.html
6 |
7 | \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.
8 |
9 | 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.
10 |
11 |
16 |
17 | */
--------------------------------------------------------------------------------
/mqtt_client/include/mqtt_client/MqttClient.h:
--------------------------------------------------------------------------------
1 | /*
2 | ==============================================================================
3 | MIT License
4 |
5 | Copyright 2022 Institute for Automotive Engineering of RWTH Aachen University.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 | ==============================================================================
25 | */
26 |
27 |
28 | #pragma once
29 |
30 | #include
31 | #include