Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add autoware_api_utils package #106

Merged
26 changes: 26 additions & 0 deletions common/autoware_api_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
Original file line number Diff line number Diff line change
@@ -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_
Original file line number Diff line number Diff line change
@@ -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 "autoware_api_utils/types/response.hpp"
#include "rclcpp/client.hpp"

#include <chrono>
#include <utility>

namespace autoware_api_utils
{
template <typename ServiceT>
class Client
{
public:
RCLCPP_SMART_PTR_DEFINITIONS(Client)

using ResponseStatus = autoware_external_api_msgs::msg::ResponseStatus;
using AutowareServiceResult = std::pair<ResponseStatus, typename ServiceT::Response::SharedPtr>;

Client(typename rclcpp::Client<ServiceT>::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))
{
RCLCPP_INFO(
logger_, "client request: \n%s", rosidl_generator_traits::to_yaml(*request).c_str());

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};
}

RCLCPP_INFO(
logger_, "client response: \n%s", rosidl_generator_traits::to_yaml(future.get()).c_str());
return {response_success(), future.get()};
}

private:
RCLCPP_DISABLE_COPY(Client)

typename rclcpp::Client<ServiceT>::SharedPtr client_;
rclcpp::Logger logger_;
};

} // namespace autoware_api_utils

#endif // AUTOWARE_API_UTILS__RCLCPP__CLIENT_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 "autoware_api_utils/rclcpp/client.hpp"
#include "autoware_api_utils/rclcpp/service.hpp"
#include "rclcpp/rclcpp.hpp"

#include <string>
#include <utility>

namespace autoware_api_utils
{
template <class NodeT>
class ServiceProxyNodeInterface
{
public:
// Use a raw pointer because shared_from_this cannot be used in constructor.
explicit ServiceProxyNodeInterface(NodeT * node) { node_ = node; }

template <typename ServiceT, typename CallbackT>
typename Service<ServiceT>::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<ServiceT>::template wrap<CallbackT>(
std::forward<CallbackT>(callback), node_->get_logger());
return Service<ServiceT>::make_shared(node_->template create_service<ServiceT>(
service_name, std::move(wrapped_callback), qos_profile, group));
}

template <typename ServiceT>
typename Client<ServiceT>::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<ServiceT>::make_shared(
node_->template create_client<ServiceT>(service_name, qos_profile, group),
node_->get_logger());
}

private:
NodeT * node_;
};

} // namespace autoware_api_utils

#endif // AUTOWARE_API_UTILS__RCLCPP__PROXY_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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 <typename ServiceT>
class Service
{
public:
RCLCPP_SMART_PTR_DEFINITIONS(Service)

explicit Service(typename rclcpp::Service<ServiceT>::SharedPtr service) : service_(service) {}

template <typename CallbackT>
static auto wrap(CallbackT && callback, const rclcpp::Logger & logger)
{
auto wrapped_callback = [logger, callback](
typename ServiceT::Request::SharedPtr request,
typename ServiceT::Response::SharedPtr response) {
RCLCPP_INFO(
logger, "service request: \n%s", rosidl_generator_traits::to_yaml(*request).c_str());
callback(request, response);
RCLCPP_INFO(
logger, "service response: \n%s", rosidl_generator_traits::to_yaml(*response).c_str());
};
return wrapped_callback;
}

private:
RCLCPP_DISABLE_COPY(Service)

typename rclcpp::Service<ServiceT>::SharedPtr service_;
};

} // namespace autoware_api_utils

#endif // AUTOWARE_API_UTILS__RCLCPP__SERVICE_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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 "rclcpp/rclcpp.hpp"

#include "autoware_external_api_msgs/msg/response_status.hpp"

#include <string>

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<autoware_external_api_msgs::msg::ResponseStatus>()
.code(autoware_external_api_msgs::msg::ResponseStatus::SUCCESS)
.message(message);
}

inline ResponseStatus response_ignored(const std::string & message = "")
{
return autoware_external_api_msgs::build<autoware_external_api_msgs::msg::ResponseStatus>()
.code(autoware_external_api_msgs::msg::ResponseStatus::IGNORED)
.message(message);
}

inline ResponseStatus response_warn(const std::string & message = "")
{
return autoware_external_api_msgs::build<autoware_external_api_msgs::msg::ResponseStatus>()
.code(autoware_external_api_msgs::msg::ResponseStatus::WARN)
.message(message);
}

inline ResponseStatus response_error(const std::string & message = "")
{
return autoware_external_api_msgs::build<autoware_external_api_msgs::msg::ResponseStatus>()
.code(autoware_external_api_msgs::msg::ResponseStatus::ERROR)
.message(message);
}

} // namespace autoware_api_utils

#endif // AUTOWARE_API_UTILS__TYPES__RESPONSE_HPP_
28 changes: 28 additions & 0 deletions common/autoware_api_utils/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">

<name>autoware_api_utils</name>
<version>0.0.0</version>
<description>The autoware_api_utils package</description>
<maintainer email="isamu.takagi@tier4.jp">Takagi, Isamu</maintainer>
<license>Apache License 2.0</license>

<buildtool_depend>ament_cmake_auto</buildtool_depend>

<depend>autoware_external_api_msgs</depend>
<depend>rclcpp</depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>autoware_external_api_msgs</test_depend>
<test_depend>autoware_lint_common</test_depend>
<test_depend>rclcpp</test_depend>

<member_of_group>rosidl_interface_packages</member_of_group>

<export>
<build_type>ament_cmake</build_type>
</export>

</package>
32 changes: 32 additions & 0 deletions common/autoware_api_utils/test/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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 "autoware_api_utils/autoware_api_utils.hpp"
#include "gtest/gtest.h"
#include "rclcpp/rclcpp.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;
}