From ba1c821fb943f0de2a157ed94b3f03fae2ad641e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 5 Jun 2025 09:43:04 +0200 Subject: [PATCH 1/2] Fix typos, documentation links, Int64 handling and add test --- README.md | 2 +- mqtt_client/CMakeLists.txt | 20 ++++++------- .../include/mqtt_client/MqttClient.ros2.hpp | 2 +- mqtt_client/src/MqttClient.ros2.cpp | 14 +++++----- mqtt_client/test/test_fixed_primitive.cpp | 28 +++++++++++++++++++ 5 files changed, 46 insertions(+), 20 deletions(-) create mode 100644 mqtt_client/test/test_fixed_primitive.cpp diff --git a/README.md b/README.md index 7693dce..4627672 100644 --- a/README.md +++ b/README.md @@ -339,7 +339,7 @@ bridge: 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. -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). +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/UInt64.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/Float64`](http://docs.ros.org/en/api/std_msgs/html/msg/Float64.html). 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)). diff --git a/mqtt_client/CMakeLists.txt b/mqtt_client/CMakeLists.txt index de5dc92..5cb1396 100644 --- a/mqtt_client/CMakeLists.txt +++ b/mqtt_client/CMakeLists.txt @@ -69,17 +69,15 @@ if(${ROS_VERSION} EQUAL 2) 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() + if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() + + find_package(ament_cmake_gtest REQUIRED) + ament_add_gtest(test_fixed_primitive test/test_fixed_primitive.cpp) + target_link_libraries(test_fixed_primitive ${PROJECT_NAME}_lib) + endif() ament_package() diff --git a/mqtt_client/include/mqtt_client/MqttClient.ros2.hpp b/mqtt_client/include/mqtt_client/MqttClient.ros2.hpp index 0d5c6b8..6677ff6 100644 --- a/mqtt_client/include/mqtt_client/MqttClient.ros2.hpp +++ b/mqtt_client/include/mqtt_client/MqttClient.ros2.hpp @@ -199,7 +199,7 @@ class MqttClient : public rclcpp::Node, const Ros2MqttInterface& ros2mqtt) const; /** - * @brief Get the candiate topic endpoints for subscription matching + * @brief Get the candidate topic endpoints for subscription matching * * @param ros2mqtt the ROS to MQTT interface spec * diff --git a/mqtt_client/src/MqttClient.ros2.cpp b/mqtt_client/src/MqttClient.ros2.cpp index c45be95..bf7f62c 100644 --- a/mqtt_client/src/MqttClient.ros2.cpp +++ b/mqtt_client/src/MqttClient.ros2.cpp @@ -67,8 +67,8 @@ T mqtt2float(mqtt::const_message_ptr mqtt_msg) { std::size_t pos; const T v = std::stold(str_msg, &pos); - if (pos != str_msg.size()) - throw std::invalid_argument ("not all charaters processed"); + if (pos != str_msg.size()) + throw std::invalid_argument ("not all characters processed"); return v; } @@ -79,8 +79,8 @@ T mqtt2int(mqtt::const_message_ptr mqtt_msg) { std::size_t pos; const T v = std::stoll(str_msg, &pos); - if (pos != str_msg.size()) - throw std::invalid_argument ("not all charaters processed"); + if (pos != str_msg.size()) + throw std::invalid_argument ("not all characters processed"); return v; } @@ -150,9 +150,9 @@ bool fixedMqtt2PrimitiveRos(mqtt::const_message_ptr mqtt_msg, msg.data = mqtt2int(mqtt_msg); serializeRosMessage(msg, serialized_msg); - } else if (msg_type == "std_msgs/msg/Int64") { - std_msgs::msg::Int32 msg; - msg.data = mqtt2int(mqtt_msg); + } else if (msg_type == "std_msgs/msg/Int64") { + std_msgs::msg::Int64 msg; + msg.data = mqtt2int(mqtt_msg); serializeRosMessage(msg, serialized_msg); } else if (msg_type == "std_msgs/msg/Float32") { diff --git a/mqtt_client/test/test_fixed_primitive.cpp b/mqtt_client/test/test_fixed_primitive.cpp new file mode 100644 index 0000000..e1191db --- /dev/null +++ b/mqtt_client/test/test_fixed_primitive.cpp @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include "mqtt_client/MqttClient.ros2.hpp" + +namespace mqtt_client { +// forward declaration of function under test +bool fixedMqtt2PrimitiveRos(mqtt::const_message_ptr mqtt_msg, + const std::string& msg_type, + rclcpp::SerializedMessage &serialized_msg); +} + +TEST(FixedMqtt2PrimitiveRos, Int64Conversion) { + auto mqtt_msg = mqtt::make_message("test", "42"); + rclcpp::SerializedMessage serialized; + ASSERT_TRUE(mqtt_client::fixedMqtt2PrimitiveRos(mqtt_msg, + "std_msgs/msg/Int64", + serialized)); + std_msgs::msg::Int64 out; + mqtt_client::deserializeRosMessage(serialized, out); + EXPECT_EQ(out.data, 42); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From f4a7bd6bca8fbcfd4c4a7a7a35efdf34c96cf8d1 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Wed, 18 Jun 2025 08:27:20 +0000 Subject: [PATCH 2/2] revert codex tests --- mqtt_client/CMakeLists.txt | 20 ++++++++-------- mqtt_client/test/test_fixed_primitive.cpp | 28 ----------------------- 2 files changed, 11 insertions(+), 37 deletions(-) delete mode 100644 mqtt_client/test/test_fixed_primitive.cpp diff --git a/mqtt_client/CMakeLists.txt b/mqtt_client/CMakeLists.txt index 5cb1396..de5dc92 100644 --- a/mqtt_client/CMakeLists.txt +++ b/mqtt_client/CMakeLists.txt @@ -69,15 +69,17 @@ if(${ROS_VERSION} EQUAL 2) FILES_MATCHING PATTERN "*ros2*" ) - if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - set(ament_cmake_cpplint_FOUND TRUE) - ament_lint_auto_find_test_dependencies() - - find_package(ament_cmake_gtest REQUIRED) - ament_add_gtest(test_fixed_primitive test/test_fixed_primitive.cpp) - target_link_libraries(test_fixed_primitive ${PROJECT_NAME}_lib) - endif() + # 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() diff --git a/mqtt_client/test/test_fixed_primitive.cpp b/mqtt_client/test/test_fixed_primitive.cpp deleted file mode 100644 index e1191db..0000000 --- a/mqtt_client/test/test_fixed_primitive.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include -#include "mqtt_client/MqttClient.ros2.hpp" - -namespace mqtt_client { -// forward declaration of function under test -bool fixedMqtt2PrimitiveRos(mqtt::const_message_ptr mqtt_msg, - const std::string& msg_type, - rclcpp::SerializedMessage &serialized_msg); -} - -TEST(FixedMqtt2PrimitiveRos, Int64Conversion) { - auto mqtt_msg = mqtt::make_message("test", "42"); - rclcpp::SerializedMessage serialized; - ASSERT_TRUE(mqtt_client::fixedMqtt2PrimitiveRos(mqtt_msg, - "std_msgs/msg/Int64", - serialized)); - std_msgs::msg::Int64 out; - mqtt_client::deserializeRosMessage(serialized, out); - EXPECT_EQ(out.data, 42); -} - -int main(int argc, char **argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -}