diff --git a/common/autoware_ad_api_msgs/CMakeLists.txt b/common/autoware_ad_api_msgs/CMakeLists.txt
new file mode 100644
index 0000000000000..74f2196f189c0
--- /dev/null
+++ b/common/autoware_ad_api_msgs/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.5)
+project(autoware_ad_api_msgs)
+
+find_package(ament_cmake_auto REQUIRED)
+ament_auto_find_build_dependencies()
+
+rosidl_generate_interfaces(${PROJECT_NAME}
+ srv/InterfaceVersion.srv
+ DEPENDENCIES
+ builtin_interfaces
+ std_msgs
+ geometry_msgs
+)
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_auto_package()
diff --git a/common/autoware_ad_api_msgs/README.md b/common/autoware_ad_api_msgs/README.md
new file mode 100644
index 0000000000000..d6c01f285425c
--- /dev/null
+++ b/common/autoware_ad_api_msgs/README.md
@@ -0,0 +1,17 @@
+# autoware_ad_api_msgs
+
+## InterfaceVersion
+
+This API provides the interface version of the set of AD APIs.
+It follows [Semantic Versioning][semver] in order to provide an intuitive understanding of the changes between versions.
+
+### Use cases
+
+Considering the product life cycle, there will be multiple vehicles that use different versions of the AD API due to changes in requirements or some improvements.
+For example, a vehicle uses `v1` for stability and another vehicle uses `v2` for more functionality.
+
+In that situation, the AD API users such as developers of a Web service have to switch the application behavior based on the version that each vehicle uses.
+
+
+
+[semver]: https://semver.org/
diff --git a/common/autoware_ad_api_msgs/package.xml b/common/autoware_ad_api_msgs/package.xml
new file mode 100644
index 0000000000000..6165f788d9b4b
--- /dev/null
+++ b/common/autoware_ad_api_msgs/package.xml
@@ -0,0 +1,29 @@
+
+
+
+ autoware_ad_api_msgs
+ 0.0.0
+ The autoware_ad_api_msgs package
+ Takagi, Isamu
+ Apache License 2.0
+
+ ament_cmake_auto
+
+ geometry_msgs
+ std_msgs
+
+ builtin_interfaces
+ rosidl_default_generators
+
+ builtin_interfaces
+ rosidl_default_runtime
+
+ ament_lint_auto
+ ament_lint_common
+
+ rosidl_interface_packages
+
+
+ ament_cmake
+
+
diff --git a/common/autoware_ad_api_msgs/srv/InterfaceVersion.srv b/common/autoware_ad_api_msgs/srv/InterfaceVersion.srv
new file mode 100644
index 0000000000000..93ba2680f1859
--- /dev/null
+++ b/common/autoware_ad_api_msgs/srv/InterfaceVersion.srv
@@ -0,0 +1,4 @@
+---
+uint16 major
+uint16 minor
+uint16 patch
diff --git a/common/component_interface_utils/CMakeLists.txt b/common/component_interface_utils/CMakeLists.txt
new file mode 100644
index 0000000000000..ba32ad10851d5
--- /dev/null
+++ b/common/component_interface_utils/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.8)
+project(component_interface_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)
+ ament_lint_auto_find_test_dependencies()
+endif()
+
+ament_auto_package()
diff --git a/common/component_interface_utils/README.md b/common/component_interface_utils/README.md
new file mode 100644
index 0000000000000..3bcc195901511
--- /dev/null
+++ b/common/component_interface_utils/README.md
@@ -0,0 +1,26 @@
+# component_interface_utils
+
+## Features
+
+This is a utility package that provides the following features:
+
+- Logging for service and client
+
+## Usage
+
+1. This package requires interface information in this format.
+
+ ```cpp
+ struct SampleService
+ {
+ using Service = sample_msgs::srv::ServiceType;
+ static constexpr char name[] = "/sample/service";
+ };
+ ```
+
+2. Create a wrapper using the above definition as follows.
+
+ ```cpp
+ component_interface_utils::Service::SharedPtr srv_;
+ srv_ = component_interface_utils::create_service(node, ...);
+ ```
diff --git a/common/component_interface_utils/include/component_interface_utils/rclcpp.hpp b/common/component_interface_utils/include/component_interface_utils/rclcpp.hpp
new file mode 100644
index 0000000000000..0101fce383b9f
--- /dev/null
+++ b/common/component_interface_utils/include/component_interface_utils/rclcpp.hpp
@@ -0,0 +1,21 @@
+// Copyright 2022 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 COMPONENT_INTERFACE_UTILS__RCLCPP_HPP_
+#define COMPONENT_INTERFACE_UTILS__RCLCPP_HPP_
+
+#include
+#include
+
+#endif // COMPONENT_INTERFACE_UTILS__RCLCPP_HPP_
diff --git a/common/component_interface_utils/include/component_interface_utils/rclcpp/create_interface.hpp b/common/component_interface_utils/include/component_interface_utils/rclcpp/create_interface.hpp
new file mode 100644
index 0000000000000..3a67d40bace70
--- /dev/null
+++ b/common/component_interface_utils/include/component_interface_utils/rclcpp/create_interface.hpp
@@ -0,0 +1,61 @@
+// Copyright 2022 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 COMPONENT_INTERFACE_UTILS__RCLCPP__CREATE_INTERFACE_HPP_
+#define COMPONENT_INTERFACE_UTILS__RCLCPP__CREATE_INTERFACE_HPP_
+
+#include
+#include
+
+#include
+
+namespace component_interface_utils
+{
+
+/// Create a service wrapper for logging. This is a private implementation.
+template
+typename Service::SharedPtr create_service_impl(
+ NodeT * node, CallbackT && callback, rclcpp::CallbackGroup::SharedPtr group = nullptr)
+{
+ // Use a node pointer because shared_from_this cannot be used in constructor.
+ // This function is a wrapper for the following.
+ // https://github.com/ros2/rclcpp/blob/48068130edbb43cdd61076dc1851672ff1a80408/rclcpp/include/rclcpp/node.hpp#L267-L281
+ auto wrapped = Service::wrap(callback, node->get_logger());
+ auto service = node->template create_service(
+ SpecT::name, wrapped, rmw_qos_profile_services_default, group);
+ return Service::make_shared(service);
+}
+
+/// Create a service wrapper for logging. This is for lambda or bound function.
+template
+typename Service::SharedPtr create_service(
+ NodeT * node, CallbackT && callback, rclcpp::CallbackGroup::SharedPtr group = nullptr)
+{
+ return create_service_impl(node, std::forward(callback), group);
+}
+
+/// Create a service wrapper for logging. This is for member function of node.
+template
+typename Service::SharedPtr create_service(
+ NodeT * node, typename Service::template CallbackType callback,
+ rclcpp::CallbackGroup::SharedPtr group = nullptr)
+{
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+ return create_service_impl(node, std::bind(callback, node, _1, _2), group);
+}
+
+} // namespace component_interface_utils
+
+#endif // COMPONENT_INTERFACE_UTILS__RCLCPP__CREATE_INTERFACE_HPP_
diff --git a/common/component_interface_utils/include/component_interface_utils/rclcpp/service_server.hpp b/common/component_interface_utils/include/component_interface_utils/rclcpp/service_server.hpp
new file mode 100644
index 0000000000000..221df60e9f81e
--- /dev/null
+++ b/common/component_interface_utils/include/component_interface_utils/rclcpp/service_server.hpp
@@ -0,0 +1,62 @@
+// Copyright 2022 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 COMPONENT_INTERFACE_UTILS__RCLCPP__SERVICE_SERVER_HPP_
+#define COMPONENT_INTERFACE_UTILS__RCLCPP__SERVICE_SERVER_HPP_
+
+#include
+
+namespace component_interface_utils
+{
+
+/// The wrapper class of rclcpp::Service for logging.
+template
+class Service
+{
+public:
+ RCLCPP_SMART_PTR_DEFINITIONS(Service)
+
+ template
+ using CallbackType = void (NodeT::*)(
+ typename SpecT::Service::Request::SharedPtr, typename SpecT::Service::Response::SharedPtr);
+
+ /// Constructor.
+ explicit Service(typename rclcpp::Service::SharedPtr service)
+ {
+ service_ = service; // to keep the reference count
+ }
+
+ /// Create a service callback with logging added.
+ template
+ static auto wrap(CallbackT && callback, const rclcpp::Logger & logger)
+ {
+ auto wrapped = [logger, callback](
+ typename SpecT::Service::Request::SharedPtr request,
+ typename SpecT::Service::Response::SharedPtr response) {
+ using rosidl_generator_traits::to_yaml;
+ RCLCPP_INFO_STREAM(logger, "service call: " << SpecT::name << "\n" << to_yaml(*request));
+ callback(request, response);
+ RCLCPP_INFO_STREAM(logger, "service exit: " << SpecT::name << "\n" << to_yaml(*response));
+ };
+ return wrapped;
+ }
+
+private:
+ RCLCPP_DISABLE_COPY(Service)
+ typename rclcpp::Service::SharedPtr service_;
+};
+
+} // namespace component_interface_utils
+
+#endif // COMPONENT_INTERFACE_UTILS__RCLCPP__SERVICE_SERVER_HPP_
diff --git a/common/component_interface_utils/package.xml b/common/component_interface_utils/package.xml
new file mode 100644
index 0000000000000..3eebdfcd52e55
--- /dev/null
+++ b/common/component_interface_utils/package.xml
@@ -0,0 +1,22 @@
+
+
+
+ component_interface_utils
+ 0.0.0
+ The component_interface_utils package
+ Takagi, Isamu
+ Apache License 2.0
+
+ ament_cmake_auto
+
+ autoware_ad_api_msgs
+ rclcpp
+ rclcpp_components
+
+ ament_lint_auto
+ autoware_lint_common
+
+
+ ament_cmake
+
+
diff --git a/system/default_ad_api/CMakeLists.txt b/system/default_ad_api/CMakeLists.txt
new file mode 100644
index 0000000000000..cebb265023d81
--- /dev/null
+++ b/system/default_ad_api/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.8)
+project(default_ad_api)
+
+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()
+
+ament_auto_add_library(${PROJECT_NAME} SHARED
+ src/interface_version.cpp
+)
+
+rclcpp_components_register_nodes(${PROJECT_NAME} "default_ad_api::InterfaceVersionNode")
+
+if(BUILD_TESTING)
+ find_package(ament_lint_auto REQUIRED)
+ ament_lint_auto_find_test_dependencies()
+ find_package(launch_testing_ament_cmake)
+ add_launch_test(test/main.test.py)
+endif()
+
+install(
+ PROGRAMS script/web_server.py
+ DESTINATION lib/${PROJECT_NAME}
+)
+
+ament_auto_package(INSTALL_TO_SHARE launch test)
diff --git a/system/default_ad_api/include/default_ad_api/nodes/interface_version.hpp b/system/default_ad_api/include/default_ad_api/nodes/interface_version.hpp
new file mode 100644
index 0000000000000..f91d96e2c2a61
--- /dev/null
+++ b/system/default_ad_api/include/default_ad_api/nodes/interface_version.hpp
@@ -0,0 +1,42 @@
+// Copyright 2022 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 DEFAULT_AD_API__NODES__INTERFACE_VERSION_HPP_
+#define DEFAULT_AD_API__NODES__INTERFACE_VERSION_HPP_
+
+#include "default_ad_api/specs/interface/version.hpp"
+
+#include
+#include
+
+namespace default_ad_api
+{
+
+class InterfaceVersionNode : public rclcpp::Node
+{
+public:
+ explicit InterfaceVersionNode(const rclcpp::NodeOptions & options);
+
+private:
+ using InterfaceVersion = autoware_ad_api_msgs::srv::InterfaceVersion;
+
+ component_interface_utils::Service::SharedPtr srv_;
+ void onInterfaceVersion(
+ const InterfaceVersion::Request::SharedPtr request,
+ const InterfaceVersion::Response::SharedPtr response);
+};
+
+} // namespace default_ad_api
+
+#endif // DEFAULT_AD_API__NODES__INTERFACE_VERSION_HPP_
diff --git a/system/default_ad_api/include/default_ad_api/specs/interface/version.hpp b/system/default_ad_api/include/default_ad_api/specs/interface/version.hpp
new file mode 100644
index 0000000000000..7aa46c675f021
--- /dev/null
+++ b/system/default_ad_api/include/default_ad_api/specs/interface/version.hpp
@@ -0,0 +1,31 @@
+// Copyright 2022 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 DEFAULT_AD_API__SPECS__INTERFACE__VERSION_HPP_
+#define DEFAULT_AD_API__SPECS__INTERFACE__VERSION_HPP_
+
+#include "autoware_ad_api_msgs/srv/interface_version.hpp"
+
+namespace ad_api::interface::version
+{
+
+struct T
+{
+ using Service = autoware_ad_api_msgs::srv::InterfaceVersion;
+ static constexpr char name[] = "/api/interface/version";
+};
+
+} // namespace ad_api::interface::version
+
+#endif // DEFAULT_AD_API__SPECS__INTERFACE__VERSION_HPP_
diff --git a/system/default_ad_api/launch/default_ad_api.launch.py b/system/default_ad_api/launch/default_ad_api.launch.py
new file mode 100644
index 0000000000000..206689f38296c
--- /dev/null
+++ b/system/default_ad_api/launch/default_ad_api.launch.py
@@ -0,0 +1,47 @@
+# Copyright 2022 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.
+
+import launch
+from launch_ros.actions import ComposableNodeContainer
+from launch_ros.actions import Node
+from launch_ros.descriptions import ComposableNode
+
+
+def _create_api_node(node_name, class_name, **kwargs):
+ return ComposableNode(
+ namespace="default_ad_api/node",
+ name=node_name,
+ package="default_ad_api",
+ plugin="default_ad_api::" + class_name,
+ **kwargs
+ )
+
+
+def generate_launch_description():
+ components = [
+ _create_api_node("interface_version", "InterfaceVersionNode"),
+ ]
+ container = ComposableNodeContainer(
+ namespace="default_ad_api",
+ name="container",
+ package="rclcpp_components",
+ executable="component_container_mt",
+ composable_node_descriptions=components,
+ )
+ web_server = Node(
+ package="default_ad_api",
+ name="web_server",
+ executable="web_server.py",
+ )
+ return launch.LaunchDescription([container, web_server])
diff --git a/system/default_ad_api/package.xml b/system/default_ad_api/package.xml
new file mode 100644
index 0000000000000..3f0fd55896a98
--- /dev/null
+++ b/system/default_ad_api/package.xml
@@ -0,0 +1,27 @@
+
+
+
+ default_ad_api
+ 0.1.0
+ The default_ad_api package
+ Takagi, Isamu
+ Apache License 2.0
+
+ ament_cmake_auto
+
+ autoware_ad_api_msgs
+ component_interface_utils
+ rclcpp
+ rclcpp_components
+
+ python3-flask
+
+ ament_lint_auto
+ autoware_lint_common
+ launch_testing
+ launch_testing_ament_cmake
+
+
+ ament_cmake
+
+
diff --git a/system/default_ad_api/script/web_server.py b/system/default_ad_api/script/web_server.py
new file mode 100755
index 0000000000000..ac2e4762cd80b
--- /dev/null
+++ b/system/default_ad_api/script/web_server.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+
+# Copyright 2022 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.
+
+import sys
+from threading import Thread
+
+from autoware_ad_api_msgs.srv import InterfaceVersion
+import flask
+import rclpy
+from rclpy.node import Node
+
+app = flask.Flask(__name__)
+cli = None
+
+
+@app.route("/interface/version")
+def interface_version():
+ req = InterfaceVersion.Request()
+ res = cli.call(req)
+ return flask.jsonify(convert_dict(res))
+
+
+def create_service(node, service_type, service_name):
+ cli = node.create_client(service_type, service_name)
+ while not cli.wait_for_service(timeout_sec=1.0):
+ node.get_logger().info(f"service not available, waiting again... ({service_name}")
+ return cli
+
+
+def convert_dict(msg):
+ fields = getattr(msg, "get_fields_and_field_types", None)
+ if not fields:
+ return msg
+ return {field: convert_dict(getattr(msg, field)) for field in fields()}
+
+
+def spin_ros_node():
+ global cli
+ rclpy.init(args=sys.argv)
+ node = Node("ad_api_default_web_server")
+ cli = create_service(node, InterfaceVersion, "/api/interface/version")
+ rclpy.spin(node)
+
+
+if __name__ == "__main__":
+ thread = Thread(target=spin_ros_node)
+ thread.start()
+ app.run(host="localhost", port=8888, debug=True)
+ rclpy.shutdown()
+ thread.join()
diff --git a/system/default_ad_api/src/interface_version.cpp b/system/default_ad_api/src/interface_version.cpp
new file mode 100644
index 0000000000000..7286d4006a502
--- /dev/null
+++ b/system/default_ad_api/src/interface_version.cpp
@@ -0,0 +1,38 @@
+// Copyright 2022 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 "default_ad_api/nodes/interface_version.hpp"
+
+namespace default_ad_api
+{
+
+InterfaceVersionNode::InterfaceVersionNode(const rclcpp::NodeOptions & options)
+: Node("interface_version", options)
+{
+ srv_ = component_interface_utils::create_service(
+ this, &InterfaceVersionNode::onInterfaceVersion);
+}
+
+void InterfaceVersionNode::onInterfaceVersion(
+ const InterfaceVersion::Request::SharedPtr, const InterfaceVersion::Response::SharedPtr response)
+{
+ response->major = 0;
+ response->minor = 1;
+ response->patch = 0;
+}
+
+} // namespace default_ad_api
+
+#include
+RCLCPP_COMPONENTS_REGISTER_NODE(default_ad_api::InterfaceVersionNode)
diff --git a/system/default_ad_api/test/main.test.py b/system/default_ad_api/test/main.test.py
new file mode 100644
index 0000000000000..728f8a3604ada
--- /dev/null
+++ b/system/default_ad_api/test/main.test.py
@@ -0,0 +1,49 @@
+# Copyright 2022 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.
+
+import importlib.util
+import unittest
+
+from ament_index_python.packages import get_package_share_directory
+import launch
+import launch_testing.actions
+import launch_testing.markers
+import launch_testing.tools
+import pytest
+
+
+@pytest.mark.launch_test
+@launch_testing.markers.keep_alive
+def generate_test_description():
+ path = get_package_share_directory("default_ad_api") + "/launch/default_ad_api.launch.py"
+ specification = importlib.util.spec_from_file_location("launch_script", path)
+ launch_script = importlib.util.module_from_spec(specification)
+ specification.loader.exec_module(launch_script)
+ return launch.LaunchDescription(
+ [
+ *launch_script.generate_launch_description().describe_sub_entities(),
+ launch_testing.actions.ReadyToTest(),
+ ]
+ )
+
+
+class TestMain(unittest.TestCase):
+ def test_interface_version(self, launch_service, proc_info, proc_output):
+ prefix = get_package_share_directory("default_ad_api")
+ target = prefix + "/test/node/interface_version.py"
+ action = launch.actions.ExecuteProcess(cmd=["python3", target])
+ with launch_testing.tools.launch_process(launch_service, action, proc_info, proc_output):
+ proc_info.assertWaitForStartup(process=action, timeout=1)
+ proc_info.assertWaitForShutdown(process=action, timeout=3)
+ launch_testing.asserts.assertExitCodes(proc_info, process=action)
diff --git a/system/default_ad_api/test/node/interface_version.py b/system/default_ad_api/test/node/interface_version.py
new file mode 100644
index 0000000000000..d5abd2924e24e
--- /dev/null
+++ b/system/default_ad_api/test/node/interface_version.py
@@ -0,0 +1,38 @@
+# Copyright 2022 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.
+
+from autoware_ad_api_msgs.srv import InterfaceVersion
+import rclpy
+import rclpy.node
+
+rclpy.init()
+node = rclpy.node.Node("test_client")
+
+client = node.create_client(InterfaceVersion, "/api/interface/version")
+if not client.wait_for_service(timeout_sec=3.0):
+ exit(1)
+
+request = InterfaceVersion.Request()
+future = client.call_async(request)
+rclpy.spin_until_future_complete(node, future)
+response = future.result()
+
+if response.major != 0:
+ exit(1)
+if response.minor != 1:
+ exit(1)
+if response.patch != 0:
+ exit(1)
+
+rclpy.shutdown()