diff --git a/rclcpp/README.md b/rclcpp/README.md index 35b81da1..8e4dfde7 100644 --- a/rclcpp/README.md +++ b/rclcpp/README.md @@ -1,4 +1,15 @@ -# rclcpp examples +# Minimal rclcpp wait-set cookbook recipes -This directory contains many examples of how to do common tasks with rclcpp. -The intent is that this material will be easy to copy-and-paste into your own projects. +This package contains a few different strategies for creating nodes which use `rclcpp::waitset` +to wait and handle ROS entities, that is, subscribers, timers, clients, services, guard +conditions and waitables. + +* `wait_set_topics_and_timer.cpp`: Simple example using multiple subscriptions, + publishers, and a timer. +* `wait_set_random_order.cpp`: An example showing user-defined + data handling and a random publisher. `executor_random_order.cpp` run the same node logic + using `SingleThreadedExecutor` to compare the data handling order. +* `wait_set_and_executor_composition.cpp`: An example showing how to combine a + `SingleThreadedExecutor` and a wait-set. +* `wait_set_topics_with_different_rate.cpp`: An example showing how to use a custom trigger + condition to handle topics with different topic rates. diff --git a/rclcpp/wait_set/wait_set.cpp b/rclcpp/wait_set/wait_set.cpp deleted file mode 100644 index b7fe8b5d..00000000 --- a/rclcpp/wait_set/wait_set.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2020 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 - -#include "example_interfaces/srv/add_two_ints.hpp" -#include "rclcpp/rclcpp.hpp" -#include "std_msgs/msg/string.hpp" - -int main(int argc, char * argv[]) -{ - rclcpp::init(argc, argv); - - auto do_nothing = [](std_msgs::msg::String::UniquePtr) {assert(false);}; - auto add_two_ints = - []( - const std::shared_ptr, - const std::shared_ptr, - const std::shared_ptr) - {assert(false);}; - - auto node = std::make_shared("wait_set_example_node"); - - auto guard_condition = std::make_shared(); - auto guard_condition2 = std::make_shared(); - - auto sub = node->create_subscription("~/chatter", 10, do_nothing); - rclcpp::SubscriptionOptions so; - so.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable; - auto sub2 = node->create_subscription("~/chatter", 10, do_nothing, so); - - auto pub = node->create_publisher("~/chatter", 10); - rclcpp::PublisherOptions po; - po.use_intra_process_comm = rclcpp::IntraProcessSetting::Enable; - auto pub2 = node->create_publisher("~/chatter", 10, po); - - auto client = node->create_client("~/add_two_ints"); - auto service = - node->create_service("~/add_two_ints", add_two_ints); - - rclcpp::WaitSet wait_set( - std::vector{{sub}}, - std::vector{guard_condition}); - wait_set.add_subscription(sub2); - wait_set.add_guard_condition(guard_condition2); - - { - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Timeout); - } - - guard_condition->trigger(); - - { - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Ready); - assert(wait_result.get_wait_set().get_rcl_wait_set().guard_conditions[0] != nullptr); - assert(wait_result.get_wait_set().get_rcl_wait_set().guard_conditions[1] == nullptr); - assert(wait_result.get_wait_set().get_rcl_wait_set().subscriptions[0] == nullptr); - assert(wait_result.get_wait_set().get_rcl_wait_set().subscriptions[1] == nullptr); - } - - wait_set.remove_guard_condition(guard_condition2); - - { - // still fails with timeout - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Timeout); - } - - wait_set.remove_guard_condition(guard_condition); - - { - // still fails with timeout - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Timeout); - } - - wait_set.remove_subscription(sub2); - - { - // still fails with timeout - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Timeout); - } - - // auto pub = node->create_publisher("~/chatter", 1); - pub->publish(std_msgs::msg::String().set__data("test")); - - { - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Ready); - assert(wait_result.get_wait_set().get_rcl_wait_set().subscriptions[0] != nullptr); - std_msgs::msg::String msg; - rclcpp::MessageInfo msg_info; - assert(sub->take(msg, msg_info)); - assert(msg.data == "test"); - } - - wait_set.remove_subscription(sub); - - { - // now fails (fast) with empty - auto wait_result = wait_set.wait(std::chrono::seconds(1)); - assert(wait_result.kind() == rclcpp::WaitResultKind::Empty); - } - - return 0; -}