ロボット開発の最前線!「ROS2」で変わる未来のシステム構築
2025年08月18日
- 研究開発
ロボット技術が多様な産業で活用される中、ROSはその中核を担う重要な技術の一つです。
しかし、ROSについてまだなじみがない方もいらっしゃるかもしれません。
そこで本記事では、ROSの基本的な知識、特に現在主流となっている「ROS2」に焦点を当て、その概要から開発、実際の活用例までを解説します。
しかし、ROSについてまだなじみがない方もいらっしゃるかもしれません。
そこで本記事では、ROSの基本的な知識、特に現在主流となっている「ROS2」に焦点を当て、その概要から開発、実際の活用例までを解説します。
ROSとは何か?:ロボット開発を加速するフレームワーク
「ROS」は「Robot Operating System」の略称です。その名前からOS(オペレーティングシステム)の一種と思われがちですが、厳密にはロボットシステム開発のためのオープンソースのフレームワーク、つまりミドルウエアにあたります。

ミドルウエアとは、オペレーティングシステム(OS)とアプリケーションの間に位置し、OSの機能だけでは不足するさまざまな機能を提供するソフトウエアのことです。ROSは、具体的には以下のような機能を提供することで、ロボット開発を効率化します。
オープンソースであるため、公式だけでなく、さまざまな個人や団体が拡張機能を開発し、活発なコミュニティーが形成されているのも大きな特徴です。
- 通信機能:ロボット内のさまざまなコンポーネント間でのデータ送受信を容易にします。
- 開発ツール:デバッグやシミュレーション、データの可視化やロギングなど、開発を補助する豊富なツールを提供します。
オープンソースであるため、公式だけでなく、さまざまな個人や団体が拡張機能を開発し、活発なコミュニティーが形成されているのも大きな特徴です。
なぜROS2なのか?:ROS1からROS2への進化
現在利用されているROSには「ROS1」と「ROS2」が存在します。ROS2はROS1の課題点を改善するために開発されたアップデート版であり、基本的には互換性がありません。ROS1は2025年5月に公式サポートが終了したため、現在ではROS2がメインとなっています。
ROS2で特に改善された主な点には、以下のものが挙げられます。
ROS2で特に改善された主な点には、以下のものが挙げられます。
- 通信方式の変更:ROS1が独自のプロトコルを使用していたのに対し、ROS2では標準的なDDS(Data Distribution Service)プロトコルを採用しています。
- リアルタイム性の向上:リアルタイム制御が求められるロボットアプリケーションでの利用に適しています。
- マルチプロセス環境のサポート:複数のプロセスやマシン間での連携が容易になりました。
- セキュリティー面の向上:より安全なシステム構築が可能になっています。
ROS2が活躍する場面
ROS2は、非常に幅広い分野で活用されています。
- ドローン
- AMR/AGV(自律移動ロボット/無人搬送車)
- 産業用ロボット
- 自動運転
自動運転向けのオープンソースソフトウエアであるAutowareでも活用されています。 - 建設機械の施工管理システム
- ロボットアクチュエータ
ROS2の開発環境と言語の使い分け
ROS2の開発は、さまざまなプラットフォームに対応していますが、基本的にはUbuntu(Linux)を利用することが多いです。
プログラミング言語は、主にC++とPythonが使われます。これらには明確な使い分けがあり、システム全体で両方を併用することが一般的です。
プログラミング言語は、主にC++とPythonが使われます。これらには明確な使い分けがあり、システム全体で両方を併用することが一般的です。
C++ | リアルタイム性やパフォーマンスを優先したい場合に推奨されます。言語特性に加え、Pythonよりも細かなパフォーマンスチューニングが可能で、ビルドしてライブラリとして配布しやすい特性があります。世の中のROS2コードはC++の割合が多い傾向にあります。 |
---|---|
Python | PyTorchなどのPythonライブラリを利用したい場合や、簡単なプロトタイプ作成、GUI作成などに適しています。 |
その他、mROS2やmicro-ROSのように一部のマイコン上でROS2を構築するプロジェクトや、ROS2 for UnityのようにUnityアプリ上でROS2を構築するプロジェクト、さらにはrosbridge suiteのようにJava、JavaScript、Rustなど他の言語でROS2メッセージを受け取れるようにするためのブリッジも存在します。
- Unity はゲーム開発用プラットフォームです。
ROS2を支えるエコシステム
ROS2は、以下の4つの要素から成る強力なエコシステム(開発や運用を支援する包括的なシステムや環境)によって支えられています。
コミュニティー
世界中に多くの利用者がいるため、情報が入手しやすく、疑問を解決しやすい環境があります。
ツール群、機能群
データの可視化ツール(rvizなど)やロギングツール、さらには各種センサーのドライバーや高度なアルゴリズムなど、さまざまな団体が提供するツールや機能が豊富に存在します。

LiDAR SLAMを行った結果をrvizで可視化
通信
ROS2の要素の中でも中核にあたるのが通信機能です。
同一ネットワーク内であれば、異なるマシン間でもモジュール(ノード:NODE)同士がスムーズに通信できます。
同一ネットワーク内であれば、異なるマシン間でもモジュール(ノード:NODE)同士がスムーズに通信できます。

パッケージ
関連する機能をまとめたROS2プログラムの基本単位です。
ソースコードと設定ファイルで構成され、他の開発者と共有する際に活用されます。
ソースコードと設定ファイルで構成され、他の開発者と共有する際に活用されます。
ROS2パッケージの構成とコーディングの雰囲気
ROS2のプログラムは「パッケージ」という単位で管理されます。一般的なC++のROS2パッケージは、以下のような構造を持ちます。

- 関連する機能をまとめたROS2プログラムの基本単位
- ソースコードと設定ファイルで構成される
- 他の人と共有するときは、パッケージを利用
src | ソースコード(.cppファイルなど)が格納されます。 |
---|---|
include/[パッケージ名] | ヘッダーファイル(.hppファイルなど)が格納されます。 |
package.xml | パッケージのメタ情報(名前、バージョン、依存関係など)を記述します。 ROS2のビルドシステムは、このファイルを参照してパッケージ間の依存関係を解決します。 |
CMakeLists.txt | パッケージのビルド方法を記述するファイルです。 ament_cmakeというCMakeの拡張機能と合わせて、ビルドを自動化します。 |
実際のC++コードの雰囲気を見てみましょう。
ROS2では、rclcppというライブラリを使ってノードを実装します。
ROS2では、rclcppというライブラリを使ってノードを実装します。
// my_node.hpp -------------------------------------------------------------
// ROS2のライブラリのインクルード
#include "rclcpp/rclcpp.hpp“
// メッセージ型のインクルード
// ROS2標準のものに加え自作のカスタムメッセージ型が使用可能
#include “std_msgs/msg/float32.hpp" // ROS2標準のメッセージ型
#include “my_msgs/msg/route.hpp" // カスタムメッセージ型
// Nodeクラスを継承して独自のノードを定義
class MyNode : public rclcpp::Node
{
public:
MyNode(const rclcpp::NodeOptions& options = rclcpp::NodeOptions());
private:
// サブスクライバーの定義
rclcpp::Subscription<my_msgs::msg::Route>::SharedPtr _sub;
// パブリッシャーの定義
rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtr _pub;
// コールバック関数の定義
void _callback(const my_msgs::msg::Route::SharedPtr msg);
};
// ROS2のライブラリのインクルード
#include "rclcpp/rclcpp.hpp“
// メッセージ型のインクルード
// ROS2標準のものに加え自作のカスタムメッセージ型が使用可能
#include “std_msgs/msg/float32.hpp" // ROS2標準のメッセージ型
#include “my_msgs/msg/route.hpp" // カスタムメッセージ型
// Nodeクラスを継承して独自のノードを定義
class MyNode : public rclcpp::Node
{
public:
MyNode(const rclcpp::NodeOptions& options = rclcpp::NodeOptions());
private:
// サブスクライバーの定義
rclcpp::Subscription<my_msgs::msg::Route>::SharedPtr _sub;
// パブリッシャーの定義
rclcpp::Publisher<std_msgs::msg::Float32>::SharedPtr _pub;
// コールバック関数の定義
void _callback(const my_msgs::msg::Route::SharedPtr msg);
};
// my_node.cpp -------------------------------------------------------------
#include “my_node.hpp“
// コンストラクタでパブリッシャーとサブスクライバーを設定
// 数行の記述により通信の設定が完了
MyNode::MyNode(const rclcpp::NodeOptions& options):
rclcpp::Node(“my_node", options)
{
// サブスクライバーの設定
_sub = this->create_subscription<my_msgs::msg::Route>(
“target_route",
rclcpp::QoS(10),
std::bind(&myNode::_callback, this, std::placeholders::_1)
);
// パブリッシャーの設定
_pub = this->create_publisher<std_msgs::msg::Float32>(
“target_velocity”,
rclcpp::QoS(10),
);
}
// コールバック関数:ノードの処理の本体となる部分
void MyNode::_callback(const my_msgs::msg::Route::SharedPtr msg)
{
// 走行制御であれば目標速度の計算など、メインの処理を記述
float target_velocity = calculate_target_velocity(msg);
// 計算結果をメッセージに変換
auto pub_msg = std_msgs::msg::Float32();
pub_msg.data = target_velocity;
// メッセージのパブリッシュ
_pub->publish(pub_msg);
}
#include “my_node.hpp“
// コンストラクタでパブリッシャーとサブスクライバーを設定
// 数行の記述により通信の設定が完了
MyNode::MyNode(const rclcpp::NodeOptions& options):
rclcpp::Node(“my_node", options)
{
// サブスクライバーの設定
_sub = this->create_subscription<my_msgs::msg::Route>(
“target_route",
rclcpp::QoS(10),
std::bind(&myNode::_callback, this, std::placeholders::_1)
);
// パブリッシャーの設定
_pub = this->create_publisher<std_msgs::msg::Float32>(
“target_velocity”,
rclcpp::QoS(10),
);
}
// コールバック関数:ノードの処理の本体となる部分
void MyNode::_callback(const my_msgs::msg::Route::SharedPtr msg)
{
// 走行制御であれば目標速度の計算など、メインの処理を記述
float target_velocity = calculate_target_velocity(msg);
// 計算結果をメッセージに変換
auto pub_msg = std_msgs::msg::Float32();
pub_msg.data = target_velocity;
// メッセージのパブリッシュ
_pub->publish(pub_msg);
}
// main.cpp -------------------------------------------------------------
// main関数:ROS2の初期化とノードの実行
int main(int argc, char * argv[]) {
// ROS2の初期化
rclcpp::init(argc, argv);
// ノードの実行
rclcpp::spin(std::make_shared<MyNode>());
// ROS2の終了処理
rclcpp::shutdown();
return 0;
}
// main関数:ROS2の初期化とノードの実行
int main(int argc, char * argv[]) {
// ROS2の初期化
rclcpp::init(argc, argv);
// ノードの実行
rclcpp::spin(std::make_shared<MyNode>());
// ROS2の終了処理
rclcpp::shutdown();
return 0;
}
この例が示すように、ROS2では通信の基本的な設定が数行の記述で済み、コールバック関数がノードの処理の本体となります。Dynamixel SDKなどの実際の製品コードでも、同様にROS2とモータードライバーのインターフェースとなるROS2パッケージが提供されており、ハードウエアと接続するROS2パッケージによく見られる構成となっています。
本記事では、ロボット開発のためのオープンソースフレームワーク「ROS」について、特に現在の主流である「ROS2」を中心に解説しました。
ROS2は、その豊富な機能と柔軟性によって、多岐にわたるロボットシステムの開発を強力に支援します。
今後もロボット技術の進化とともに、ROS2の活躍の場はさらに広がっていくことでしょう。
- ROSはロボットシステム開発のためのミドルウエアであり、通信機能、開発ツール、アルゴリズムなどを提供します。
- ROS1からROS2への移行が進んでおり、ROS2は通信方式の改善、リアルタイム性やセキュリティーの向上が図られています。
- 開発はUbuntu環境が基本で、C++とPythonを用途に応じて使い分けることが一般的です。
- ROS2は活発なコミュニティー、豊富なツール群、強力な通信機能から成るエコシステムが特徴です。
- ROS2のコーディングでは、通信の基本的な設定は容易であり、コールバック関数を実装することがメインとなります。
ROS2は、その豊富な機能と柔軟性によって、多岐にわたるロボットシステムの開発を強力に支援します。
今後もロボット技術の進化とともに、ROS2の活躍の場はさらに広がっていくことでしょう。