ROS(ROS2)- サービス - パッケージ作成

 クラウディア
1. 概要
2. ワークスペース作成
3. パッケージ作成
4. ソース作成

1. 概要

 以下、「Ubuntu 24.04」の環境で。  本ページは、下記のサイトを参考にさせていただきました。
Understanding services — ROS 2 Documentation: Rolling documentation」
「Writing a simple service and client (C++) — ROS 2 Documentation: Foxy documentation

2. ワークスペース作成

 ワークスペース名を、「ros2_ws」として、まずワークスペースのエリアを確保します。

mkdir -pv ~/ros2_ws/src

3. パッケージ作成

 パッケージの作成方法が、やや異なります。

cd ~/ros2_ws/src

ros2 pkg create --build-type ament_cmake cpp_srvcli --dependencies rclcpp example_interfaces
 作成されるものが異なるので、メッセージをメモしておきます。

package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['hogehoge <hogehoge@todo.todo>']
licenses: ['TODO: License declaration']
build type: ament_cmake
dependencies: ['rclcpp', 'example_interfaces']
creating folder ./cpp_srvcli
creating ./cpp_srvcli/package.xml
creating source and include folder
creating folder ./cpp_srvcli/src
creating folder ./cpp_srvcli/include/cpp_srvcli
creating ./cpp_srvcli/CMakeLists.txt

[WARNING]: Unknown license 'TODO: License declaration'.  This has been set in the package.xml, but no LICENSE file has been created.
It is recommended to use one of the ament license identifiers:
Apache-2.0
BSL-1.0
BSD-2.0
BSD-2-Clause
BSD-3-Clause
GPL-3.0-only
LGPL-3.0-only
MIT
MIT-0
 下記のファイルが作成されます。

`-- cpp_srvcli
    |-- CMakeLists.txt
    |-- include
    |   `-- cpp_srvcli
    |-- package.xml
    `-- src

4. ソース作成

 ソースを作成します。  サーバ側のソース。

vi ~/ros2_ws/src/cpp_srvcli/src/add_two_ints_server.cpp
 下記を記述します。

#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/add_two_ints.hpp"

#include <memory>

void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
          std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>      response)
{
	response->sum = request->a + request->b;
	RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld",
                request->a, request->b);
	RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
}

int main(int argc, char* argv[])
{
	rclcpp::init(argc, argv);

	std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_server");

	rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service =
		node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints", &add);

	RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");

	rclcpp::spin(node);
	rclcpp::shutdown();
}
 クライアント側のソース。

vi ~/ros2_ws/src/cpp_srvcli/src/add_two_ints_client.cpp

#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/add_two_ints.hpp"

#include <chrono>
#include <cstdlib>
#include <memory>

using namespace std::chrono_literals;

int main(int argc, char* argv[])
{
	rclcpp::init(argc, argv);

	if (argc != 3)
	{
		RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "usage: add_two_ints_client X Y");
		return 1;
	}

	std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_client");
	rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr client =
	node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");

	auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();
	request->a = atoll(argv[1]);
	request->b = atoll(argv[2]);

	while (!client->wait_for_service(1s))
	{
		if (!rclcpp::ok())
		{
			RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
			return 0;
		}
		RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
	}

	auto result = client->async_send_request(request);

	// Wait for the result.
	if (rclcpp::spin_until_future_complete(node, result) == rclcpp::FutureReturnCode::SUCCESS)
	{
		RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sum: %ld", result.get()->sum);
	}
	else
	{
		RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service add_two_ints");
	}

	rclcpp::shutdown();
	return 0;
}
 設定ファイルを編集。

vi ~/ros2_ws/src/cpp_srvcli/CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(cpp_srvcli)

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(example_interfaces REQUIRED)

add_executable(server src/add_two_ints_server.cpp)
ament_target_dependencies(server rclcpp example_interfaces)

add_executable(client src/add_two_ints_client.cpp)
ament_target_dependencies(client rclcpp example_interfaces)

install(TARGETS
  server
  client
  DESTINATION lib/${PROJECT_NAME})

ament_package()

vi ~/ros2_ws/src/cpp_srvcli/package.xml

<?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>cpp_srvcli</name>
	<version>0.0.0</version>
	<description>C++ client server tutorial</description>
	<maintainer email="hogehoge@todo.todo">hogehoge</maintainer>
	<license>Apache License 2.0</license>

	<buildtool_depend>ament_cmake</buildtool_depend>

	<depend>rclcpp</depend>
	<depend>example_interfaces</depend>

	<test_depend>ament_lint_auto</test_depend>
	<test_depend>ament_lint_common</test_depend>

	<export>
	<build_type>ament_cmake</build_type>
	</export>
</package>
AbemaTV 無料体験
ネットオークションの相場、統計、価格比較といえばオークファン