diff --git a/rclcpp/services/minimal_client/CMakeLists.txt b/rclcpp/services/minimal_client/CMakeLists.txt index 18001ddf..3194adaa 100644 --- a/rclcpp/services/minimal_client/CMakeLists.txt +++ b/rclcpp/services/minimal_client/CMakeLists.txt @@ -14,10 +14,19 @@ find_package(ament_cmake REQUIRED) find_package(example_interfaces REQUIRED) find_package(rclcpp REQUIRED) -add_executable(client_main main.cpp) -ament_target_dependencies(client_main rclcpp example_interfaces) +add_executable(client_lambda lambda.cpp) +ament_target_dependencies(client_lambda rclcpp example_interfaces) -install(TARGETS client_main +add_executable(client_member_function member_function.cpp) +ament_target_dependencies(client_member_function rclcpp example_interfaces) + +add_executable(client_not_composable not_composable.cpp) +ament_target_dependencies(client_not_composable rclcpp example_interfaces) + +install(TARGETS + client_lambda + client_member_function + client_not_composable DESTINATION lib/${PROJECT_NAME}) if(BUILD_TESTING) diff --git a/rclcpp/services/minimal_client/lambda.cpp b/rclcpp/services/minimal_client/lambda.cpp new file mode 100644 index 00000000..f203de9f --- /dev/null +++ b/rclcpp/services/minimal_client/lambda.cpp @@ -0,0 +1,67 @@ +// Copyright 2016 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 "example_interfaces/srv/add_two_ints.hpp" +#include "rclcpp/rclcpp.hpp" + +using namespace std::chrono_literals; +using example_interfaces::srv::AddTwoInts; + +/* This example creates a subclass of Node and uses std::bind() to register a + * member function as a callback from the client. */ + +class MinimalClient : public rclcpp::Node +{ +public: + MinimalClient() + : Node("minimal_client") + { + client_ = this->create_client("add_two_ints"); + while (!client_->wait_for_service(1s)) { + if (!rclcpp::ok()) { + RCLCPP_ERROR(this->get_logger(), "client interrupted while waiting for service to appear."); + } + RCLCPP_INFO(this->get_logger(), "waiting for service to appear..."); + } + auto request = std::make_shared(); + request->a = 41; + request->b = 1; + auto result_future = client_->async_send_request( + request, + [this](rclcpp::Client::SharedFutureWithRequest result_future) { + auto result = result_future.get(); + auto request = result.first; + auto response = result.second; + RCLCPP_INFO( + this->get_logger(), "result of %" PRId64 " + %" PRId64 " = %" PRId64, + request->a, request->b, response->sum); + rclcpp::shutdown(); + }); + } + +private: + rclcpp::Client::SharedPtr client_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} diff --git a/rclcpp/services/minimal_client/member_function.cpp b/rclcpp/services/minimal_client/member_function.cpp new file mode 100644 index 00000000..cb01032e --- /dev/null +++ b/rclcpp/services/minimal_client/member_function.cpp @@ -0,0 +1,69 @@ +// Copyright 2016 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 "example_interfaces/srv/add_two_ints.hpp" +#include "rclcpp/rclcpp.hpp" + +using namespace std::chrono_literals; +using std::placeholders::_1; +using example_interfaces::srv::AddTwoInts; + +/* This example creates a subclass of Node and uses std::bind() to register a + * member function as a callback from the client. */ + +class MinimalClient : public rclcpp::Node +{ +public: + MinimalClient() + : Node("minimal_client") + { + client_ = this->create_client("add_two_ints"); + while (!client_->wait_for_service(1s)) { + if (!rclcpp::ok()) { + RCLCPP_ERROR(this->get_logger(), "client interrupted while waiting for service to appear."); + } + RCLCPP_INFO(this->get_logger(), "waiting for service to appear..."); + } + auto request = std::make_shared(); + request->a = 41; + request->b = 1; + auto result_future = client_->async_send_request( + request, std::bind(&MinimalClient::service_callback, this, _1)); + } + +private: + void service_callback(rclcpp::Client::SharedFutureWithRequest result_future) const + { + auto result = result_future.get(); + auto request = result.first; + auto response = result.second; + RCLCPP_INFO( + this->get_logger(), "result of %" PRId64 " + %" PRId64 " = %" PRId64, + request->a, request->b, response->sum); + rclcpp::shutdown(); + } + rclcpp::Client::SharedPtr client_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} diff --git a/rclcpp/services/minimal_client/main.cpp b/rclcpp/services/minimal_client/not_composable.cpp similarity index 75% rename from rclcpp/services/minimal_client/main.cpp rename to rclcpp/services/minimal_client/not_composable.cpp index 98feffd8..98d7f03f 100644 --- a/rclcpp/services/minimal_client/main.cpp +++ b/rclcpp/services/minimal_client/not_composable.cpp @@ -19,14 +19,20 @@ #include "example_interfaces/srv/add_two_ints.hpp" #include "rclcpp/rclcpp.hpp" -using AddTwoInts = example_interfaces::srv::AddTwoInts; +using namespace std::chrono_literals; +using example_interfaces::srv::AddTwoInts; + +/* We do not recommend this style anymore, because composition of multiple + * nodes in the same executable is not possible. Please see one of the subclass + * examples for the "new" recommended styles. This example is only included + * for completeness because it is similar to "classic" standalone ROS nodes. */ int main(int argc, char * argv[]) { rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("minimal_client"); auto client = node->create_client("add_two_ints"); - while (!client->wait_for_service(std::chrono::seconds(1))) { + while (!client->wait_for_service(1s)) { if (!rclcpp::ok()) { RCLCPP_ERROR(node->get_logger(), "client interrupted while waiting for service to appear."); return 1; @@ -43,10 +49,10 @@ int main(int argc, char * argv[]) RCLCPP_ERROR(node->get_logger(), "service call failed :("); return 1; } - auto result = result_future.get(); + auto response = result_future.get(); RCLCPP_INFO( node->get_logger(), "result of %" PRId64 " + %" PRId64 " = %" PRId64, - request->a, request->b, result->sum); + request->a, request->b, response->sum); rclcpp::shutdown(); return 0; } diff --git a/rclcpp/services/minimal_service/CMakeLists.txt b/rclcpp/services/minimal_service/CMakeLists.txt index 88d6d8d4..e01d76a3 100644 --- a/rclcpp/services/minimal_service/CMakeLists.txt +++ b/rclcpp/services/minimal_service/CMakeLists.txt @@ -14,10 +14,19 @@ find_package(ament_cmake REQUIRED) find_package(example_interfaces REQUIRED) find_package(rclcpp REQUIRED) -add_executable(service_main main.cpp) -ament_target_dependencies(service_main rclcpp example_interfaces) +add_executable(service_lambda lambda.cpp) +ament_target_dependencies(service_lambda rclcpp example_interfaces) -install(TARGETS service_main +add_executable(service_member_function member_function.cpp) +ament_target_dependencies(service_member_function rclcpp example_interfaces) + +add_executable(service_not_composable not_composable.cpp) +ament_target_dependencies(service_not_composable rclcpp example_interfaces) + +install(TARGETS + service_lambda + service_member_function + service_not_composable DESTINATION lib/${PROJECT_NAME}) if(BUILD_TESTING) diff --git a/rclcpp/services/minimal_service/lambda.cpp b/rclcpp/services/minimal_service/lambda.cpp new file mode 100644 index 00000000..cd820ade --- /dev/null +++ b/rclcpp/services/minimal_service/lambda.cpp @@ -0,0 +1,54 @@ +// Copyright 2016 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 "example_interfaces/srv/add_two_ints.hpp" +#include "rclcpp/rclcpp.hpp" + +using example_interfaces::srv::AddTwoInts; + +/* This example creates a subclass of Node and uses a fancy C++11 lambda + * function to shorten the callback syntax, at the expense of making the + * code somewhat more difficult to understand at first glance. */ + +class MinimalService : public rclcpp::Node +{ +public: + MinimalService() + : Node("minimal_service") + { + server_ = this->create_service( + "add_two_ints", + [this](const AddTwoInts::Request::SharedPtr request, + AddTwoInts::Response::SharedPtr response) { + RCLCPP_INFO( + this->get_logger(), + "request: %" PRId64 " + %" PRId64, request->a, request->b); + response->sum = request->a + request->b; + }); + } + +private: + rclcpp::Service::SharedPtr server_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} diff --git a/rclcpp/services/minimal_service/member_function.cpp b/rclcpp/services/minimal_service/member_function.cpp new file mode 100644 index 00000000..02ffca77 --- /dev/null +++ b/rclcpp/services/minimal_service/member_function.cpp @@ -0,0 +1,57 @@ +// Copyright 2016 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 "example_interfaces/srv/add_two_ints.hpp" +#include "rclcpp/rclcpp.hpp" + +using std::placeholders::_1; +using std::placeholders::_2; +using example_interfaces::srv::AddTwoInts; + +/* This example creates a subclass of Node and uses std::bind() to register a + * member function as a callback from the server. */ + +class MinimalService : public rclcpp::Node +{ +public: + MinimalService() + : Node("minimal_service") + { + server_ = this->create_service( + "add_two_ints", std::bind(&MinimalService::service_callback, this, _1, _2)); + } + +private: + void service_callback( + const AddTwoInts::Request::SharedPtr request, + AddTwoInts::Response::SharedPtr response) const + { + RCLCPP_INFO( + this->get_logger(), + "request: %" PRId64 " + %" PRId64, request->a, request->b); + response->sum = request->a + request->b; + } + rclcpp::Service::SharedPtr server_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} diff --git a/rclcpp/services/minimal_service/main.cpp b/rclcpp/services/minimal_service/not_composable.cpp similarity index 73% rename from rclcpp/services/minimal_service/main.cpp rename to rclcpp/services/minimal_service/not_composable.cpp index 3cf38fb3..8025292e 100644 --- a/rclcpp/services/minimal_service/main.cpp +++ b/rclcpp/services/minimal_service/not_composable.cpp @@ -18,15 +18,18 @@ #include "example_interfaces/srv/add_two_ints.hpp" #include "rclcpp/rclcpp.hpp" -using AddTwoInts = example_interfaces::srv::AddTwoInts; +using example_interfaces::srv::AddTwoInts; rclcpp::Node::SharedPtr g_node = nullptr; +/* We do not recommend this style anymore, because composition of multiple + * nodes in the same executable is not possible. Please see one of the subclass + * examples for the "new" recommended styles. This example is only included + * for completeness because it is similar to "classic" standalone ROS nodes. */ + void handle_service( - const std::shared_ptr request_header, - const std::shared_ptr request, - const std::shared_ptr response) + const AddTwoInts::Request::SharedPtr request, + AddTwoInts::Response::SharedPtr response) { - (void)request_header; RCLCPP_INFO( g_node->get_logger(), "request: %" PRId64 " + %" PRId64, request->a, request->b); diff --git a/rclcpp/topics/minimal_publisher/lambda.cpp b/rclcpp/topics/minimal_publisher/lambda.cpp index 324eb96e..a111c5bd 100644 --- a/rclcpp/topics/minimal_publisher/lambda.cpp +++ b/rclcpp/topics/minimal_publisher/lambda.cpp @@ -33,7 +33,7 @@ class MinimalPublisher : public rclcpp::Node { publisher_ = this->create_publisher("topic", 10); auto timer_callback = - [this]() -> void { + [this]() { auto message = std_msgs::msg::String(); message.data = "Hello, world! " + std::to_string(this->count_++); RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str()); diff --git a/rclcpp/topics/minimal_publisher/member_function.cpp b/rclcpp/topics/minimal_publisher/member_function.cpp index b211a5eb..1843f818 100644 --- a/rclcpp/topics/minimal_publisher/member_function.cpp +++ b/rclcpp/topics/minimal_publisher/member_function.cpp @@ -13,7 +13,6 @@ // limitations under the License. #include -#include #include #include diff --git a/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp b/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp index 39c1007a..e8fadd5a 100644 --- a/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp +++ b/rclcpp/topics/minimal_publisher/member_function_with_type_adapter.cpp @@ -13,7 +13,6 @@ // limitations under the License. #include -#include #include #include diff --git a/rclcpp/topics/minimal_publisher/member_function_with_unique_network_flow_endpoints.cpp b/rclcpp/topics/minimal_publisher/member_function_with_unique_network_flow_endpoints.cpp index 71437e9e..3295892d 100644 --- a/rclcpp/topics/minimal_publisher/member_function_with_unique_network_flow_endpoints.cpp +++ b/rclcpp/topics/minimal_publisher/member_function_with_unique_network_flow_endpoints.cpp @@ -13,7 +13,6 @@ // limitations under the License. #include -#include #include #include #include diff --git a/rclcpp/topics/minimal_subscriber/lambda.cpp b/rclcpp/topics/minimal_subscriber/lambda.cpp index 337009b2..ac549d34 100644 --- a/rclcpp/topics/minimal_subscriber/lambda.cpp +++ b/rclcpp/topics/minimal_subscriber/lambda.cpp @@ -17,6 +17,10 @@ #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" +/* This example creates a subclass of Node and uses a fancy C++11 lambda + * function to shorten the callback syntax, at the expense of making the + * code somewhat more difficult to understand at first glance. */ + class MinimalSubscriber : public rclcpp::Node { public: @@ -26,7 +30,7 @@ class MinimalSubscriber : public rclcpp::Node subscription_ = this->create_subscription( "topic", 10, - [this](std_msgs::msg::String::UniquePtr msg) { + [this](const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str()); }); } diff --git a/rclcpp/topics/minimal_subscriber/member_function.cpp b/rclcpp/topics/minimal_subscriber/member_function.cpp index 0f84d80d..762e65e8 100644 --- a/rclcpp/topics/minimal_subscriber/member_function.cpp +++ b/rclcpp/topics/minimal_subscriber/member_function.cpp @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include "rclcpp/rclcpp.hpp" @@ -20,6 +19,9 @@ using std::placeholders::_1; +/* This example creates a subclass of Node and uses std::bind() to register a + * member function as a callback from the subscriber. */ + class MinimalSubscriber : public rclcpp::Node { public: diff --git a/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp b/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp index bb9c8925..5f292089 100644 --- a/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp +++ b/rclcpp/topics/minimal_subscriber/member_function_with_type_adapter.cpp @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include #include #include diff --git a/rclcpp/topics/minimal_subscriber/member_function_with_unique_network_flow_endpoints.cpp b/rclcpp/topics/minimal_subscriber/member_function_with_unique_network_flow_endpoints.cpp index 5a008014..247fc367 100644 --- a/rclcpp/topics/minimal_subscriber/member_function_with_unique_network_flow_endpoints.cpp +++ b/rclcpp/topics/minimal_subscriber/member_function_with_unique_network_flow_endpoints.cpp @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - -#include #include #include #include