diff --git a/rclcpp/topics/minimal_publisher/CMakeLists.txt b/rclcpp/topics/minimal_publisher/CMakeLists.txt index 305b2f2e..7f689544 100644 --- a/rclcpp/topics/minimal_publisher/CMakeLists.txt +++ b/rclcpp/topics/minimal_publisher/CMakeLists.txt @@ -20,6 +20,9 @@ ament_target_dependencies(publisher_lambda rclcpp std_msgs) add_executable(publisher_member_function member_function.cpp) ament_target_dependencies(publisher_member_function rclcpp std_msgs) +add_executable(publisher_member_function_with_type_adapter member_function_with_type_adapter.cpp) +ament_target_dependencies(publisher_member_function_with_type_adapter rclcpp std_msgs) + add_executable(publisher_member_function_with_unique_network_flow_endpoints member_function_with_unique_network_flow_endpoints.cpp) ament_target_dependencies(publisher_member_function_with_unique_network_flow_endpoints rclcpp std_msgs) @@ -29,6 +32,7 @@ ament_target_dependencies(publisher_not_composable rclcpp std_msgs) install(TARGETS publisher_lambda publisher_member_function + publisher_member_function_with_type_adapter publisher_member_function_with_unique_network_flow_endpoints publisher_not_composable DESTINATION lib/${PROJECT_NAME} diff --git a/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp b/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp new file mode 100644 index 00000000..39c1007a --- /dev/null +++ b/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp @@ -0,0 +1,94 @@ +// Copyright 2021 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +#include "rclcpp/type_adapter.hpp" +#include "rclcpp/rclcpp.hpp" + +#include "std_msgs/msg/string.hpp" + +using namespace std::chrono_literals; + +/* Normally a TypeAdapter specialization like this would go in a header + * and be reused by the publisher and subscriber rather than copy-pasted + * like this. We chose to include this here because it makes this example + * more "self-contained". */ + +template<> +struct rclcpp::TypeAdapter +{ + using is_specialized = std::true_type; + using custom_type = std::string; + using ros_message_type = std_msgs::msg::String; + + static + void + convert_to_ros_message( + const custom_type & source, + ros_message_type & destination) + { + destination.data = source; + } + + static + void + convert_to_custom( + const ros_message_type & source, + custom_type & destination) + { + destination = source.data; + } +}; + +/* In this example, a publisher uses a type adapter to use a `std::string` + * in place of a `std_msgs::msg::String` in the argument expected by + * the publish method. Note that publish will also work with a + * `std_msgs::msg::String` argument. */ + +class MinimalPublisher : public rclcpp::Node +{ + using MyAdaptedType = rclcpp::TypeAdapter; + +public: + MinimalPublisher() + : Node("minimal_publisher"), count_(0) + { + publisher_ = this->create_publisher("topic", 10); + timer_ = this->create_wall_timer( + 500ms, std::bind(&MinimalPublisher::timer_callback, this)); + } + +private: + void timer_callback() + { + std::string message = "Hello, world! " + std::to_string(count_++); + RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.c_str()); + publisher_->publish(message); + } + rclcpp::TimerBase::SharedPtr timer_; + rclcpp::Publisher::SharedPtr publisher_; + size_t count_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} diff --git a/rclcpp/topics/minimal_subscriber/CMakeLists.txt b/rclcpp/topics/minimal_subscriber/CMakeLists.txt index 4a771c3f..d9221c48 100644 --- a/rclcpp/topics/minimal_subscriber/CMakeLists.txt +++ b/rclcpp/topics/minimal_subscriber/CMakeLists.txt @@ -23,6 +23,9 @@ ament_target_dependencies(subscriber_member_function rclcpp std_msgs) add_executable(subscriber_member_function_with_topic_statistics member_function_with_topic_statistics.cpp) ament_target_dependencies(subscriber_member_function_with_topic_statistics rclcpp std_msgs) +add_executable(subscriber_member_function_with_type_adapter member_function_with_type_adapter.cpp) +ament_target_dependencies(subscriber_member_function_with_type_adapter rclcpp std_msgs) + add_executable(subscriber_member_function_with_unique_network_flow_endpoints member_function_with_unique_network_flow_endpoints.cpp) ament_target_dependencies(subscriber_member_function_with_unique_network_flow_endpoints rclcpp std_msgs) @@ -33,6 +36,7 @@ install(TARGETS subscriber_lambda subscriber_member_function subscriber_member_function_with_topic_statistics + subscriber_member_function_with_type_adapter subscriber_member_function_with_unique_network_flow_endpoints subscriber_not_composable DESTINATION lib/${PROJECT_NAME}) diff --git a/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp b/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp new file mode 100644 index 00000000..bb9c8925 --- /dev/null +++ b/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp @@ -0,0 +1,86 @@ +// Copyright 2021 Open Source Robotics Foundation, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include + +#include "rclcpp/type_adapter.hpp" +#include "rclcpp/rclcpp.hpp" + +#include "std_msgs/msg/string.hpp" + +using std::placeholders::_1; + +/* Normally a TypeAdapter specialization like this would go in a header + * and be reused by the publisher and subscriber rather than copy-pasted + * like this. We chose to include this here because it makes this example + * more "self-contained". */ + +template<> +struct rclcpp::TypeAdapter +{ + using is_specialized = std::true_type; + using custom_type = std::string; + using ros_message_type = std_msgs::msg::String; + + static + void + convert_to_ros_message( + const custom_type & source, + ros_message_type & destination) + { + destination.data = source; + } + + static + void + convert_to_custom( + const ros_message_type & source, + custom_type & destination) + { + destination = source.data; + } +}; + +/* In this example, a subscriber uses a type adapter to use a `std::string` + * in place of a `std_msgs::msg::String` in the subscription's callback. */ + +class MinimalSubscriber : public rclcpp::Node +{ + using MyAdaptedType = rclcpp::TypeAdapter; + +public: + MinimalSubscriber() + : Node("minimal_subscriber") + { + subscription_ = this->create_subscription( + "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); + } + +private: + void topic_callback(const std::string & msg) const + { + RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.c_str()); + } + rclcpp::Subscription::SharedPtr subscription_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +}