ROS(ROS2)- パッケージ作成 - Ubuntu

クラウディア 
1. 概要
2. ワークスペース作成
3. パッケージ作成
4. ビルド
5. 実行
6. ソースコード
7. 備考

1. 概要

 理解するためには、作ってみるです。  以下、「Ubuntu 24.04」の環境で。  なかなか、いいサンプルがありません。  「examples/rclcpp at jazzy · ros2/examples · GitHub」のものを使おうと思いますが。  上記は、「rolling」のようなので、いつ中身が変わるかは、わかりません。  参考にしているのは、2024年11月28日時点のものです。

2. ワークスペース作成

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

mkdir -pv ~/colcon_ws/src

3. パッケージ作成

 「mypackage」という名前のパッケージを作成します。

cd ~/colcon_ws/src

ros2 pkg create mypackage
 下記のような出力がありまして・・・。

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: []
creating folder ./mypackage
creating ./mypackage/package.xml
creating source and include folder
creating folder ./mypackage/src
creating folder ./mypackage/include/mypackage
creating ./mypackage/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
 結果として、下記のディレクトリ・ファイルが作成されます。

`-- mypackage
    |-- CMakeLists.txt
    |-- include
    |   `-- mypackage
    |-- package.xml
    `-- src
 参考サイトで紹介されている、ソースコードを作成します。  コードの内容は、末尾に記述しています。  ソースコード作成の結果、下記のような構成になるはずです。

|-- CMakeLists.txt
|-- include
|   `-- mypackage
|       |-- publisher_node.hpp
|       |-- subscriber_node.hpp
|       `-- visibility.h
|-- package.xml
`-- src
    |-- composed.cpp
    |-- publisher_node.cpp
    |-- standalone_publisher.cpp
    |-- standalone_subscriber.cpp
    `-- subscriber_node.cpp

4. ビルド

 ビルドします。

cd ~/colcon_ws
colcon build --packages-select mypackage
 うまくいけば、下記のような表示なるはず。  (時間は、もっとかかると思います)

Starting >>> mypackage
Finished <<< mypackage [3.78s]

Summary: 1 package finished [4.78s]

5. 実行

 作成したものを実行します。  2つの端末で実行します。  「Subscriber」側。

ros2 run mypackage composition_subscriber
 「Publisher」側。

ros2 run mypackage composition_publisher
 「Subscriber」側の表示。

[INFO] [1732868452.471512538] [subscriber_node]: Subscriber: 'Hello, world! 0'
[INFO] [1732868452.969242249] [subscriber_node]: Subscriber: 'Hello, world! 1'
[INFO] [1732868453.465351847] [subscriber_node]: Subscriber: 'Hello, world! 2'
[INFO] [1732868453.966899584] [subscriber_node]: Subscriber: 'Hello, world! 3'
[INFO] [1732868454.468686238] [subscriber_node]: Subscriber: 'Hello, world! 4'
[INFO] [1732868454.967533737] [subscriber_node]: Subscriber: 'Hello, world! 5'
 「Publisher」側の表示。

[INFO] [1732868452.467683305] [publisher_node]: Publisher: 'Hello, world! 0'
[INFO] [1732868452.966664863] [publisher_node]: Publisher: 'Hello, world! 1'
[INFO] [1732868453.463301435] [publisher_node]: Publisher: 'Hello, world! 2'
[INFO] [1732868453.963718499] [publisher_node]: Publisher: 'Hello, world! 3'
[INFO] [1732868454.466485590] [publisher_node]: Publisher: 'Hello, world! 4'
[INFO] [1732868454.963764438] [publisher_node]: Publisher: 'Hello, world! 5'
 止めるときは、Ctrl+C で止めます。

6. ソースコード

 コピー元のソースから必要な部分のみを取り出し、加工しています。  ヘッダ。  「~/colcon_ws/src/mypackage/include/mypackage」配下に作成します。  「publisher_node.hpp」

#ifndef MINIMAL_COMPOSITION__PUBLISHER_NODE_HPP_
#define MINIMAL_COMPOSITION__PUBLISHER_NODE_HPP_

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include "mypackage/visibility.h"

class PublisherNode : public rclcpp::Node
{
public:
  MINIMAL_COMPOSITION_PUBLIC PublisherNode(rclcpp::NodeOptions options);

private:
  void on_timer();
  size_t count_;
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
  rclcpp::TimerBase::SharedPtr timer_;
};

#endif
 「subscriber_node.hpp」

#ifndef MINIMAL_COMPOSITION__SUBSCRIBER_NODE_HPP_
#define MINIMAL_COMPOSITION__SUBSCRIBER_NODE_HPP_

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
#include "mypackage/visibility.h"

class SubscriberNode : public rclcpp::Node
{
public:
	MINIMAL_COMPOSITION_PUBLIC SubscriberNode(rclcpp::NodeOptions options);

private:
	rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

#endif
 「visibility.h」

#ifndef MINIMAL_COMPOSITION__VISIBILITY_H_
#define MINIMAL_COMPOSITION__VISIBILITY_H_

#ifdef __cplusplus
extern "C"
{
#endif

#if defined _WIN32 || defined __CYGWIN__

  #ifdef __GNUC__
    #define MINIMAL_COMPOSITION_EXPORT __attribute__ ((dllexport))
    #define MINIMAL_COMPOSITION_IMPORT __attribute__ ((dllimport))
  #else
    #define MINIMAL_COMPOSITION_EXPORT __declspec(dllexport)
    #define MINIMAL_COMPOSITION_IMPORT __declspec(dllimport)
  #endif

  #ifdef MINIMAL_COMPOSITION_DLL
    #define MINIMAL_COMPOSITION_PUBLIC MINIMAL_COMPOSITION_EXPORT
  #else
    #define MINIMAL_COMPOSITION_PUBLIC MINIMAL_COMPOSITION_IMPORT
  #endif

  #define MINIMAL_COMPOSITION_PUBLIC_TYPE MINIMAL_COMPOSITION_PUBLIC

  #define MINIMAL_COMPOSITION_LOCAL

#else

  #define MINIMAL_COMPOSITION_EXPORT __attribute__ ((visibility("default")))
  #define MINIMAL_COMPOSITION_IMPORT

  #if __GNUC__ >= 4
    #define MINIMAL_COMPOSITION_PUBLIC __attribute__ ((visibility("default")))
    #define MINIMAL_COMPOSITION_LOCAL  __attribute__ ((visibility("hidden")))
  #else
    #define MINIMAL_COMPOSITION_PUBLIC
    #define MINIMAL_COMPOSITION_LOCAL
  #endif

  #define MINIMAL_COMPOSITION_PUBLIC_TYPE
#endif

#ifdef __cplusplus
}
#endif

#endif
 ソース。  「~/colcon_ws/src/mypackage/src」配下に作成します。  「composed.cpp」

#include <memory>
#include "mypackage/publisher_node.hpp"
#include "mypackage/subscriber_node.hpp"
#include "rclcpp/rclcpp.hpp"

int main(int argc, char* argv[])
{
	rclcpp::init(argc, argv);
	rclcpp::executors::SingleThreadedExecutor exec;
	rclcpp::NodeOptions options;
	auto publisher_node = std::make_shared<PublisherNode>(options);
	auto subscriber_node = std::make_shared<SubscriberNode>(options);
	exec.add_node(publisher_node);
	exec.add_node(subscriber_node);
	exec.spin();
	rclcpp::shutdown();

	return 0;
}
 「publisher_node.hpp」

#include <chrono>
#include "mypackage/publisher_node.hpp"
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

PublisherNode::PublisherNode(rclcpp::NodeOptions options)
: Node("publisher_node", options), count_(0)
{
	publisher_ = create_publisher<std_msgs::msg::String>("topic", 10);
	timer_ = create_wall_timer(500ms, std::bind(&PublisherNode::on_timer, this));
}

void PublisherNode::on_timer()
{
	auto message = std_msgs::msg::String();
	message.data = "Hello, world! " + std::to_string(count_++);
	RCLCPP_INFO(this->get_logger(), "Publisher: '%s'", message.data.c_str());
	publisher_->publish(message);
}

#include "rclcpp_components/register_node_macro.hpp"

RCLCPP_COMPONENTS_REGISTER_NODE(PublisherNode)
 「standalone_publisher.cpp」

#include <memory>
#include "mypackage/publisher_node.hpp"
#include "rclcpp/rclcpp.hpp"

int main(int argc, char* argv[])
{
	rclcpp::init(argc, argv);
	rclcpp::spin(std::make_shared<PublisherNode>(rclcpp::NodeOptions()));
	rclcpp::shutdown();

	return 0;
}
 「standalone_subscriber.cpp」

#include <memory>
#include "mypackage/subscriber_node.hpp"
#include "rclcpp/rclcpp.hpp"

int main(int argc, char* argv[])
{
	rclcpp::init(argc, argv);
	rclcpp::spin(std::make_shared<SubscriberNode>(rclcpp::NodeOptions()));
	rclcpp::shutdown();

	return 0;
}
 「subscriber_node.cpp」

#include "mypackage/subscriber_node.hpp"
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

SubscriberNode::SubscriberNode(rclcpp::NodeOptions options)
: Node("subscriber_node", options)
{
  subscription_ = create_subscription<std_msgs::msg::String>(
    "topic",
    10,
    [this](std_msgs::msg::String::UniquePtr msg) {
      RCLCPP_INFO(this->get_logger(), "Subscriber: '%s'", msg->data.c_str());
    });
}

#include "rclcpp_components/register_node_macro.hpp"

RCLCPP_COMPONENTS_REGISTER_NODE(SubscriberNode)
 「CMakeLists.txt」「package.xml」  「~/colcon_ws/src/mypackage」配下に作成します(元があるので、編集)。  「CMakeLists.txt」

cmake_minimum_required(VERSION 3.8)
project(mypackage)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
	add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(std_msgs REQUIRED)

include_directories(include)

add_library(composition_nodes SHARED
            src/publisher_node.cpp
            src/subscriber_node.cpp)
target_compile_definitions(composition_nodes
	PRIVATE "MINIMAL_COMPOSITION_DLL")
ament_target_dependencies(composition_nodes rclcpp rclcpp_components std_msgs)

# This package installs libraries without exporting them.
# Export the library path to ensure that the installed libraries are available.
if(NOT WIN32)
	ament_environment_hooks(
		"${ament_cmake_package_templates_ENVIRONMENT_HOOK_LIBRARY_PATH}")
endif()

add_executable(composition_publisher src/standalone_publisher.cpp)
target_link_libraries(composition_publisher composition_nodes)
ament_target_dependencies(composition_publisher rclcpp)

add_executable(composition_subscriber src/standalone_subscriber.cpp)
target_link_libraries(composition_subscriber composition_nodes)
ament_target_dependencies(composition_subscriber rclcpp)

add_executable(composition_composed src/composed.cpp)
target_link_libraries(composition_composed composition_nodes)
ament_target_dependencies(composition_composed rclcpp class_loader)

install(TARGETS
	composition_nodes
	ARCHIVE DESTINATION lib
	LIBRARY DESTINATION lib
	RUNTIME DESTINATION bin)

install(TARGETS
	composition_publisher
	composition_subscriber
	composition_composed
	DESTINATION lib/${PROJECT_NAME})

if(BUILD_TESTING)
	find_package(ament_lint_auto REQUIRED)
	ament_lint_auto_find_test_dependencies()
endif()

ament_package()
 「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>mypackage</name>
  <version>0.0.1</version>
  <description>MyPackage</description>
  <maintainer email="hogehoge@sing.ne.jp">hogehoge</maintainer>
  <license>BSD License</license>

  <author email="jacob@openrobotics.org">Jacob Perron</author>
  <author>Mikael Arguedas</author>
  <author>Morgan Quigley</author>
  <author email="sloretz@openrobotics.org">Shane Loretz</author>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <build_depend>rclcpp</build_depend>
  <build_depend>rclcpp_components</build_depend>
  <build_depend>std_msgs</build_depend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>rclcpp_components</exec_depend>
  <exec_depend>std_msgs</exec_depend>

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

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

7. 備考

 本ページは、下記のサイトを参考にさせていただきました。
ROS 2におけるワークスペース・パッケージの作成とビルド #ROS2」
「ROS2チュートリアル - パッケージ作成 #ROS2」
「examples/rclcpp at jazzy · ros2/examples · GitHub
AbemaTV 無料体験
ネットオークションの相場、統計、価格比較といえばオークファン
健康サポート特集
ハイスピードプラン
EMEET 1
マイニングベース
葬送のフリーレン Prime Video
Amazonギフトカード
5G CONNECT