diff --git a/common/autoware_api_utils/CMakeLists.txt b/common/autoware_api_utils/CMakeLists.txt new file mode 100644 index 000000000000..7ade69a6375b --- /dev/null +++ b/common/autoware_api_utils/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.5) +project(autoware_api_utils) + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic -Werror) +endif() + +find_package(ament_cmake_auto REQUIRED) +ament_auto_find_build_dependencies() + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + find_package(ament_cmake_gtest REQUIRED) + include_directories(include) + ament_lint_auto_find_test_dependencies() + ament_add_gtest(${PROJECT_NAME}_test test/test.cpp) + ament_target_dependencies(${PROJECT_NAME}_test rclcpp autoware_external_api_msgs) +endif() + +ament_auto_package() diff --git a/common/autoware_api_utils/include/autoware_api_utils/autoware_api_utils.hpp b/common/autoware_api_utils/include/autoware_api_utils/autoware_api_utils.hpp new file mode 100644 index 000000000000..d9aa11fa353a --- /dev/null +++ b/common/autoware_api_utils/include/autoware_api_utils/autoware_api_utils.hpp @@ -0,0 +1,21 @@ +// Copyright 2021 Tier IV, 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. + +#ifndef AUTOWARE_API_UTILS__AUTOWARE_API_UTILS_HPP_ +#define AUTOWARE_API_UTILS__AUTOWARE_API_UTILS_HPP_ + +#include "autoware_api_utils/rclcpp/proxy.hpp" +#include "autoware_api_utils/types/response.hpp" + +#endif // AUTOWARE_API_UTILS__AUTOWARE_API_UTILS_HPP_ diff --git a/common/autoware_api_utils/include/autoware_api_utils/rclcpp/client.hpp b/common/autoware_api_utils/include/autoware_api_utils/rclcpp/client.hpp new file mode 100644 index 000000000000..43d8f2fd45f4 --- /dev/null +++ b/common/autoware_api_utils/include/autoware_api_utils/rclcpp/client.hpp @@ -0,0 +1,72 @@ +// Copyright 2021 Tier IV, 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. + +#ifndef AUTOWARE_API_UTILS__RCLCPP__CLIENT_HPP_ +#define AUTOWARE_API_UTILS__RCLCPP__CLIENT_HPP_ + +#include +#include +#include "rclcpp/client.hpp" +#include "autoware_api_utils/types/response.hpp" + +namespace autoware_api_utils +{ + +template +class Client +{ +public: + RCLCPP_SMART_PTR_DEFINITIONS(Client) + + using ResponseStatus = autoware_external_api_msgs::msg::ResponseStatus; + using AutowareServiceResult = std::pair; + + Client(typename rclcpp::Client::SharedPtr client, rclcpp::Logger logger) + : client_(client), logger_(logger) + { + } + + AutowareServiceResult call( + const typename ServiceT::Request::SharedPtr & request, + const std::chrono::nanoseconds & timeout = std::chrono::seconds(2)) + { + // TODO(Takagi, Isamu): use rosidl_generator_traits::to_yaml (galactic) + RCLCPP_INFO(logger_, "client request"); + + if (!client_->service_is_ready()) { + RCLCPP_INFO(logger_, "client available"); + return {response_error("Internal service is not available."), nullptr}; + } + + auto future = client_->async_send_request(request); + if (future.wait_for(timeout) != std::future_status::ready) { + RCLCPP_INFO(logger_, "client timeout"); + return {response_error("Internal service has timed out."), nullptr}; + } + + // TODO(Takagi, Isamu): use rosidl_generator_traits::to_yaml (galactic) + RCLCPP_INFO(logger_, "client response"); + return {response_success(), future.get()}; + } + +private: + RCLCPP_DISABLE_COPY(Client) + + typename rclcpp::Client::SharedPtr client_; + rclcpp::Logger logger_; +}; + +} // namespace autoware_api_utils + +#endif // AUTOWARE_API_UTILS__RCLCPP__CLIENT_HPP_ diff --git a/common/autoware_api_utils/include/autoware_api_utils/rclcpp/proxy.hpp b/common/autoware_api_utils/include/autoware_api_utils/rclcpp/proxy.hpp new file mode 100644 index 000000000000..4cb71cbd4031 --- /dev/null +++ b/common/autoware_api_utils/include/autoware_api_utils/rclcpp/proxy.hpp @@ -0,0 +1,70 @@ +// Copyright 2021 Tier IV, 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. + +#ifndef AUTOWARE_API_UTILS__RCLCPP__PROXY_HPP_ +#define AUTOWARE_API_UTILS__RCLCPP__PROXY_HPP_ + +#include +#include +#include "rclcpp/rclcpp.hpp" +#include "autoware_api_utils/rclcpp/service.hpp" +#include "autoware_api_utils/rclcpp/client.hpp" + +namespace autoware_api_utils +{ + +template +class ServiceProxyNodeInterface +{ +public: + // Use a raw pointer because shared_from_this cannot be used in constructor. + explicit ServiceProxyNodeInterface(NodeT * node) + { + node_ = node; + } + + template + typename Service::SharedPtr + create_service( + const std::string & service_name, + CallbackT && callback, + const rmw_qos_profile_t & qos_profile = rmw_qos_profile_services_default, + rclcpp::CallbackGroup::SharedPtr group = nullptr) + { + auto wrapped_callback = Service::template wrap( + std::forward(callback), node_->get_logger()); + return Service::make_shared( + node_->template create_service( + service_name, std::move(wrapped_callback), qos_profile, group)); + } + + template + typename Client::SharedPtr + create_client( + const std::string & service_name, + const rmw_qos_profile_t & qos_profile = rmw_qos_profile_services_default, + rclcpp::CallbackGroup::SharedPtr group = nullptr) + { + return Client::make_shared( + node_->template create_client( + service_name, qos_profile, group), node_->get_logger()); + } + +private: + NodeT * node_; +}; + +} // namespace autoware_api_utils + +#endif // AUTOWARE_API_UTILS__RCLCPP__PROXY_HPP_ diff --git a/common/autoware_api_utils/include/autoware_api_utils/rclcpp/service.hpp b/common/autoware_api_utils/include/autoware_api_utils/rclcpp/service.hpp new file mode 100644 index 000000000000..cbb926adf2f2 --- /dev/null +++ b/common/autoware_api_utils/include/autoware_api_utils/rclcpp/service.hpp @@ -0,0 +1,57 @@ +// Copyright 2021 Tier IV, 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. + +#ifndef AUTOWARE_API_UTILS__RCLCPP__SERVICE_HPP_ +#define AUTOWARE_API_UTILS__RCLCPP__SERVICE_HPP_ + +#include "rclcpp/service.hpp" + +namespace autoware_api_utils +{ + +template +class Service +{ +public: + RCLCPP_SMART_PTR_DEFINITIONS(Service) + + explicit Service(typename rclcpp::Service::SharedPtr service) + : service_(service) + { + } + + template + static auto wrap(CallbackT && callback, const rclcpp::Logger & logger) + { + auto wrapped_callback = [logger, callback]( + typename ServiceT::Request::SharedPtr request, + typename ServiceT::Response::SharedPtr response) + { + // TODO(Takagi, Isamu): use rosidl_generator_traits::to_yaml (galactic) + RCLCPP_INFO(logger, "service request"); + callback(request, response); + RCLCPP_INFO(logger, "service response"); + }; + return wrapped_callback; + } + +private: + RCLCPP_DISABLE_COPY(Service) + + typename rclcpp::Service::SharedPtr service_; +}; + +} // namespace autoware_api_utils + +#endif // AUTOWARE_API_UTILS__RCLCPP__SERVICE_HPP_ diff --git a/common/autoware_api_utils/include/autoware_api_utils/types/response.hpp b/common/autoware_api_utils/include/autoware_api_utils/types/response.hpp new file mode 100644 index 000000000000..79e0a704fc1d --- /dev/null +++ b/common/autoware_api_utils/include/autoware_api_utils/types/response.hpp @@ -0,0 +1,72 @@ +// Copyright 2021 Tier IV, 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. + +#ifndef AUTOWARE_API_UTILS__TYPES__RESPONSE_HPP_ +#define AUTOWARE_API_UTILS__TYPES__RESPONSE_HPP_ + +#include +#include "rclcpp/rclcpp.hpp" +#include "autoware_external_api_msgs/msg/response_status.hpp" + +namespace autoware_api_utils +{ +using ResponseStatus = autoware_external_api_msgs::msg::ResponseStatus; + +inline bool is_success(const autoware_external_api_msgs::msg::ResponseStatus & status) +{ + return status.code == autoware_external_api_msgs::msg::ResponseStatus::SUCCESS; +} + +inline bool is_ignored(const autoware_external_api_msgs::msg::ResponseStatus & status) +{ + return status.code == autoware_external_api_msgs::msg::ResponseStatus::IGNORED; +} + +inline bool is_warn(const autoware_external_api_msgs::msg::ResponseStatus & status) +{ + return status.code == autoware_external_api_msgs::msg::ResponseStatus::WARN; +} + +inline bool is_error(const autoware_external_api_msgs::msg::ResponseStatus & status) +{ + return status.code == autoware_external_api_msgs::msg::ResponseStatus::ERROR; +} + +inline ResponseStatus response_success(const std::string & message = "") +{ + return autoware_external_api_msgs::build() + .code(autoware_external_api_msgs::msg::ResponseStatus::SUCCESS).message(message); +} + +inline ResponseStatus response_ignored(const std::string & message = "") +{ + return autoware_external_api_msgs::build() + .code(autoware_external_api_msgs::msg::ResponseStatus::IGNORED).message(message); +} + +inline ResponseStatus response_warn(const std::string & message = "") +{ + return autoware_external_api_msgs::build() + .code(autoware_external_api_msgs::msg::ResponseStatus::WARN).message(message); +} + +inline ResponseStatus response_error(const std::string & message = "") +{ + return autoware_external_api_msgs::build() + .code(autoware_external_api_msgs::msg::ResponseStatus::ERROR).message(message); +} + +} // namespace autoware_api_utils + +#endif // AUTOWARE_API_UTILS__TYPES__RESPONSE_HPP_ diff --git a/common/autoware_api_utils/package.xml b/common/autoware_api_utils/package.xml new file mode 100644 index 000000000000..48d983c5d2a7 --- /dev/null +++ b/common/autoware_api_utils/package.xml @@ -0,0 +1,28 @@ + + + + + autoware_api_utils + 0.0.0 + The autoware_api_utils package + Takagi, Isamu + Apache License 2.0 + + ament_cmake_auto + + autoware_external_api_msgs + rclcpp + + ament_cmake_gtest + ament_lint_auto + ament_lint_common + autoware_external_api_msgs + rclcpp + + rosidl_interface_packages + + + ament_cmake + + + diff --git a/common/autoware_api_utils/test/test.cpp b/common/autoware_api_utils/test/test.cpp new file mode 100644 index 000000000000..b074b747cffb --- /dev/null +++ b/common/autoware_api_utils/test/test.cpp @@ -0,0 +1,31 @@ +// Copyright 2021 Tier IV, 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 "gtest/gtest.h" +#include "rclcpp/rclcpp.hpp" +#include "autoware_api_utils/autoware_api_utils.hpp" + +TEST(autoware_api_utils, instantiate) { + rclcpp::Node node("autoware_api_utils_test"); + autoware_api_utils::ServiceProxyNodeInterface proxy(&node); +} + +int main(int argc, char ** argv) +{ + testing::InitGoogleTest(&argc, argv); + rclcpp::init(argc, argv); + bool result = RUN_ALL_TESTS(); + rclcpp::shutdown(); + return result; +}