ROS1とROS2の違いは、機能の多さより通信の作りにあります。ROS1はROSマスターがノード同士を引き合わせ、ROS2はマスターを持たずDDSで互いを見つけます。この差が、障害時の挙動、QoS(通信品質)の設定、コードの書き方、移行の手間まで決めています。この記事では、両者をDockerで実際に動かした結果を交えて違いを整理し、2026年10月時点のサポート状況からどのディストリを選び、どう移行するかまで示します。
まとめ:ROS1とROS2の違いと2026年の結論
中核の違いは通信アーキテクチャです。ROS1はマスター(roscore)が名前解決を担うため、マスターが落ちると新しいノードはつながりません。ROS2はDDSの分散ディスカバリでマスターが不要になった代わりに、発行側が提供するQoSと購読側が要求するQoSに互換性が必要になりました。たとえばBEST_EFFORTで発行するセンサードライバに対して購読側を既定のRELIABLEで作ると、エラーにならないまま受信が0件になります。
2026年に新規で始めるならROS2です。ROS1の最終版Noeticは2025年5月にEOLとなり、ROS1のディストリはすべて公式サポート外です。ROS 2は長く使うならLTSのJazzy(2029年5月まで)かLyrical Luth(2031年5月まで)を選びます。既存のROS1資産はros1_bridgeで段階的に移せますが、ブリッジのREADMEではUbuntu 20.04がFull support、22.04がソースビルドを要する部分対応、24.04が非対応とされているため、ブリッジの実行環境を移行計画に含めてください。
ROS1とROS2の違いを一覧で比較
ROSは名前にOSと付きますが、Linux上で動くロボット向けのミドルウェアです。センサー処理や制御を「ノード」に分け、トピック(publish/subscribe)・サービス・アクションでつなぎます。ROS2はこの考え方を保ったまま中身を作り直した後継で、ROS1とはソースもワイヤ上の通信も互換性がありません。ROS自体の仕組みはROS(Robot Operating System)の構造とROS 2世代の選び方で詳しく扱っています。
| 観点 | ROS1(Noetic) | ROS2(Jazzy) |
|---|---|---|
| 相手の見つけ方 | ROSマスターが仲介 | DDSの分散ディスカバリ |
| 通信プロトコル | TCPROS/UDPROS | DDS(RTPS)、RMWで差し替え可 |
| マスター停止時 | 新規ノードが登録できない | マスター自体が無い |
| QoS | queue_sizeとlatchのみ | 信頼性・耐久性・履歴等 |
| Pythonライブラリ | rospy | rclpy |
| ビルド | catkin | ament+colcon |
| launch | XML | Python/XML/YAML |
| Tier 1のOS | Ubuntu 20.04 | Ubuntu 24.04、Windows 10 |
| マイコンとの連携 | rosserialなど | micro-ROSなど |
| セキュリティ | 標準機構なし | SROS2(DDS-Security) |
| サポート | 2025年5月EOL | 2029年5月まで |
以降の実測は、Docker公式のros:noetic-ros-core(Ubuntu 20.04.6、rospy 1.17.4)とros:jazzy-ros-core(Ubuntu 24.04.5、rclpy 7.1.12、既定RMWはrmw_fastrtps_cpp 8.4.4)で2026年10月28日に行いました。
通信アーキテクチャの違い:ROSマスターとDDSのディスカバリ
ROS1:マスター停止後の既存通信の継続と新規ノードの登録不可
ROS1のマスターは「どのノードがどのトピックを出しているか」の台帳で、データそのものはノード同士がTCPROSで直接やり取りします。そこで、10Hzで数値を送る発行ノードと購読ノードを動かしたまま、マスターのプロセスを止めて挙動を確かめました。
| 操作 | 結果(ROS1 Noetic) |
|---|---|
| マスター停止前の受信 | 73件目まで受信 |
| 停止から5秒後の既存購読ノード | 123件目まで受信が続く |
停止後のrostopic list |
Unable to communicate with master! |
| 停止後に起動した購読ノード | 10秒待っても受信0件 |
新しく起動したノードはUnable to register with master node [http://localhost:11311]: master may not be running yet. Will keep trying.を出したまま初期化が終わりませんでした。つまりマスターが落ちても動いている通信はすぐには切れませんが、ノードの再起動や追加、rostopicでの調査ができなくなります。現場で「ノードを1本再起動したら復帰しない」という形で表に出るのがこの単一障害点です。
ROS2:DDSによる相互検出とRMWによる通信層の切り替え
ROS2にはマスターのプロセスがありません。各ノードはDDSのディスカバリで発行側・購読側を自動で見つけるため、どのノードを再起動しても他のノードの参加には影響しません。DDSの実装はRMW(ROS Middleware)という抽象層の下にあり、環境変数RMW_IMPLEMENTATIONで切り替えます。REP-2000では、Kilted以降の対応表でeProsimaのFast DDS(既定)、Eclipse Cyclone DDS、RTI Connextに加えて、DDSではないEclipse Zenohを使うrmw_zenoh_cppもTier 1に入っています。マルチキャストが通らないネットワークやWi-Fi越しの構成では、この選択肢が効きます(Zenoh単体の使い方はZenohの実装とMQTT/DDSとの違いを参照)。
ROS2で注意したいのは、異なるディストリ同士の通信が保証されない点です。ROS 2の公式リリース一覧は、HumbleでビルドしたノードとIronでビルドしたノードの通信は「動くかもしれないがサポートされない」と明記しています。ロボット側と開発PC側でディストリを揃えるのが前提です。
QoSの違い:ROS1の書き方がROS2でそのまま通らない箇所
信頼性(Reliability):QoSの組み合わせと受信可否
ROS1で通信の挙動を決めるのはqueue_sizeとlatchくらいでした。ROS2では発行側と購読側がそれぞれQoSを宣言し、互換性が無い組み合わせはエラーにならず「つながらないまま」になります。Jazzyで信頼性の4通りを試した結果が次の表です。
| 発行側 | 購読側 | 受信 |
|---|---|---|
| RELIABLE | RELIABLE | 受信できる |
| BEST_EFFORT | RELIABLE | 0件(警告のみ) |
| RELIABLE | BEST_EFFORT | 受信できる |
| BEST_EFFORT | BEST_EFFORT | 受信できる |
受信0件のとき購読側に出たのはNew publisher discovered on topic 'chatter', offering incompatible QoS. No messages will be received from it. Last incompatible policy: RELIABILITYという警告1行だけで、例外は発生しません。カメラやLiDARのドライバはBEST_EFFORTで出すことが多く、購読側を既定(RELIABLE)のまま書くとこの組み合わせになります。センサー系のトピックを購読するときは、BEST_EFFORT・履歴5件のrclpy.qos.qos_profile_sensor_dataを指定し、つながらないときはros2 topic info -v /トピック名で双方のReliabilityとDurabilityを並べて確認します。
latch=TrueとTRANSIENT_LOCAL:遅延参加者への配信条件
ROS1のrospy.Publisher(..., latch=True)は、後から来た購読者にも最後のメッセージを渡します。Noeticで値42を1回だけ発行し、5秒後にrostopic echoしてもdata: 42を受け取れました。ROS2でこれに当たるのがDurabilityのTRANSIENT_LOCALですが、発行側だけ設定しても足りません。
| 発行側(1回だけ発行) | 遅れて起動した購読側 | 受信 |
|---|---|---|
| TRANSIENT_LOCAL | VOLATILE(既定) | 0件 |
| TRANSIENT_LOCAL | TRANSIENT_LOCAL | 1件(2回とも) |
| VOLATILE | TRANSIENT_LOCAL | 0件(DURABILITY警告) |
地図や設定値のように「最後の値を後から来たノードに渡したい」トピックは、発行側と購読側の両方に同じQoSを渡します。次のコードは初期化済みのnodeとインポート済みのInt32を使う発行側の抜粋で、購読側もcreate_subscriptionのQoS引数に同じlatchedを指定します。
from rclpy.qos import QoSProfile, ReliabilityPolicy, DurabilityPolicy
latched = QoSProfile(depth=1,
reliability=ReliabilityPolicy.RELIABLE,
durability=DurabilityPolicy.TRANSIENT_LOCAL)
pub = node.create_publisher(Int32, 'state', latched)
コマンドで確かめるときは、ros2 topic echo --once /stateのようにQoSを指定しなければ発行側に合わせて受信できました。逆に--qos-durability volatileを付けると6秒待っても何も表示されません。「CLIでは見えるのに自作ノードでは受け取れない」ときは、QoSの食い違いを最初に疑ってください。
コードとコマンドの対応:rospyとrclpy、catkinとcolcon
最小の発行ノードの書き方
同じ「10Hzで連番を送る」ノードを両方で書くと、違いはグローバルなinit_nodeからNodeオブジェクトへの移行と、ループからタイマーコールバックへの移行に集約されます。どちらもDockerで動かし、購読側で受信を確認したコードです。
# ROS1(rospy)
import rospy
from std_msgs.msg import Int32
rospy.init_node('talker')
pub = rospy.Publisher('chatter', Int32, queue_size=10)
r = rospy.Rate(10)
i = 0
while not rospy.is_shutdown():
pub.publish(i)
i += 1
r.sleep()
# ROS2(rclpy)
import rclpy
from rclpy.node import Node
from std_msgs.msg import Int32
def main():
rclpy.init()
node = Node('talker')
pub = node.create_publisher(Int32, 'chatter', 10)
count = 0
def tick():
nonlocal count
msg = Int32()
msg.data = count
pub.publish(msg)
count += 1
node.create_timer(0.1, tick)
rclpy.spin(node)
if __name__ == '__main__':
main()
rclpyのcreate_publisherの第3引数10は、履歴をKEEP_LASTで10件保持するQoSの省略形です。rospyのようにpub.publish(i)と数値を直接渡す書き方はできず、メッセージ型のインスタンスを作ってdataに入れます。
ビルド・実行・記録コマンドの対応表
| 作業 | ROS1 | ROS2 |
|---|---|---|
| マスター起動 | roscore | 不要 |
| ビルド | catkin_make | colcon build |
| 環境の読み込み | source devel/setup.bash | source install/setup.bash |
| ノード実行 | rosrun pkg node | ros2 run pkg node |
| launch | roslaunch pkg x.launch | ros2 launch pkg x.launch.py |
| トピック確認 | rostopic list/echo | ros2 topic list/echo |
| パラメータ | rosparam | ros2 param |
| 記録・再生 | rosbag record/play | ros2 bag record/play |
| 環境診断 | roswtf | ros2 doctor |
パラメータの扱いは対応表以上に変わっています。ROS1のパラメータはマスター上のグローバルなサーバーにありましたが、ROS2ではノードごとに持ち、宣言していないパラメータは既定で設定できません。rosparam setで何でも書き込めた前提のコードは、declare_parameterを足す書き換えが必要です。ROS2のビルド環境の作り方はROS 2の環境構築とcolconビルド手順にまとめています。
launchファイル:XMLからPython・XML・YAMLの3形式へ
ROS1のroslaunchはXMLだけでしたが、ROS2のros2 launchはPython・XML・YAMLの3形式を読めます。Jazzyのros-coreイメージにもlaunch_xmlとlaunch_yamlが入っていました。条件分岐やノードの動的な組み立てが要るならPython、ROS1のXMLを移植するだけならXMLが手戻りの少ない選択です。ただしタグや属性名はROS1と同一ではなく、たとえば公式の移行ガイドのとおり<node>のtype属性はexecに変わるため、ROS1の.launchをそのまま読ませることはできません。
対応OS・組み込み・セキュリティの違い
対応OS:WindowsもTier 1、macOSはTier 3
ROS1はUbuntuが事実上の唯一の選択肢でした。ROS2はREP-2000でOSごとにサポート段階(Tier)を定めており、Jazzyではamd64のUbuntu 24.04とWindows 10がTier 1、RHEL 9がTier 2、macOSはソースビルドのみのTier 3です。ArmのTier 1はUbuntuだけなので、Jetsonなどの実機はUbuntuを前提に組み、Windowsは開発・シミュレーション用に使う分担が現実的です。
マイコン:micro-ROS Agent経由のROS 2ネットワーク接続
ROS1はLinuxプロセス前提で、マイコンはrosserialでシリアル越しにつなぐのが一般的でした。ROS2ではmicro-ROSがFreeRTOSやZephyr上のマイコンをROS 2のノードとして動かし(micro_ros_setupの対応表ではHumble・Jazzy・Kilted・Lyrical・Rollingが対象)、エージェント経由で上位のLinuxノードと同じトピックでやり取りします。センサーやモーター制御をマイコン側に残したまま統合できるため、エッジ機器やAI/IoTソリューションのように現場の機器とLinuxをまたぐ構成で差が出ます。
セキュリティ:SROS2による認証・暗号化の有効化
ROS1には認証も暗号化も無く、同じネットワークに入れれば誰でもトピックを読み書きできました。ROS2はDDS-Securityを使うSROS2を持ち、ros2 securityコマンドで鍵ストアとノードごとの証明書を作り、公式チュートリアルのとおりROS_SECURITY_KEYSTOREに鍵ストアの場所、ROS_SECURITY_ENABLE=trueとROS_SECURITY_STRATEGY=Enforceを設定して有効化します。起動時には、作成した証明書を含むエンクレーブを–ros-args –enclaveで指定します。Enforceでは必要なセキュリティ設定が見つからなければ起動に失敗するため、鍵の配布先とエンクレーブの指定を確認します。Jazzyのros-coreイメージでもros2 securityは標準で使えました。工場や屋外でネットワークを他者と共有するロボットでは、これがROS2を選ぶ決め手の一つになります。
2026年のバージョン選定:ROS1のEOLとROS 2のサポート期間
Noetic EOL(2025年5月31日)後に残る選択肢
ROS1の最終版Noetic Ninjemys(Ubuntu 20.04向け)は2025年5月31日にEOLとなり、rosdistroの索引でもROS1のディストリはすべてend-of-lifeです。Dockerのros:noetic-ros-coreに入っていたrospyも2025年5月19日ビルドの1.17.4で止まっていました。動いているNoeticのシステムをすぐ止める必要はありませんが、脆弱性が見つかっても公式の修正は出ません。
移行までに時間が要る場合の選択肢は、Canonicalの有償延長サポートです。CanonicalのNoetic EOL告知によると、Ubuntu Proに含まれるESM for ROSでNoeticを2030年まで保守でき、Ubuntu Pro自体は個人利用なら無料です。製品としてNoeticを出荷済みで、すぐに移行できない場合の時間稼ぎとして使い、移行計画とセットで契約するのが妥当です。
ROS 2ディストリの選び方
ROS 2は毎年5月23日前後にリリースされ、偶数年がLTS(5年)、奇数年が通常版(約1.5年)です。公式のリリース一覧に載る2026年10月時点のサポート中ディストリは次の4つです。
| ディストリ | リリース | Tier 1のUbuntu | EOL |
|---|---|---|---|
| Humble Hawksbill(LTS) | 2022-05-23 | 22.04 | 2027年5月 |
| Jazzy Jalisco(LTS) | 2024-05-23 | 24.04 | 2029年5月 |
| Kilted Kaiju | 2025-05-23 | 24.04 | 2026年12月 |
| Lyrical Luth(LTS) | 2026-05-22 | 26.04 | 2031年5月 |
新規開発はJazzyかLyrical Luthで始めます。使いたいドライバやNav2・MoveItなどのパッケージがLyrical Luthに揃っていればLyrical Luth、揃っていなければ実績の厚いJazzyです。Humbleは残り約7か月なので、これから始める案件には選びません。Kiltedは公式リリース一覧で2026年12月(REP-2000の表記は2026年11月)に終わるため、rmw_zenohなどの新機能を試す検証用途に限ります。Lyrical Luthが対象とするOSはUbuntu 26.04 LTS(Resolute Raccoon)です。
ROS1からROS2への移行手順と注意点
ros1_bridgeの対応環境:20.04のフル対応と22.04のソースビルド
ROS1とROS2を並走させて少しずつ移す定番はros1_bridgeで、ROS1のトピックとROS2のトピックを相互に変換します。ただしros1_bridgeのREADMEの対応表で「Full support」なのはUbuntu 20.04(NoeticとFoxy/Galactic/Humble)だけです。22.04はソースからのビルドが必要、24.04はROS1自体が入らないため非対応と書かれています。これはブリッジを動かすマシンの条件です。ブリッジ側のROS2はHumble以前になるため、Jazzy以降の機体とのやり取りは異なるディストリ間の通信となり、公式には保証されません。ブリッジ前提で段階移行するなら、移行期間中は20.04上にNoeticとブリッジ用のROS2を置き、移行が終わった時点でJazzy以降へ上げる2段構えになります。
移行で手戻りが出やすい順番
- 依存パッケージの棚卸し:使っているドライバや外部パッケージに移行先ディストリのROS2版があるかを先に確かめる。無いものは代替を探すか自前で移植する。
- メッセージ定義の移植:
.msg/.srvの多くはそのまま使えるが、パッケージのpackage.xmlとCMakeLists.txtはament向けに書き直す。 - トピックごとのQoS設計:センサーは
BEST_EFFORT、地図や設定値はTRANSIENT_LOCALなど、ROS1のlatchや暗黙の挙動をQoSとして明示する。 - ノードの書き換え:
rospy→rclpy、パラメータのdeclare_parameter化、座標変換はtfからtf2_rosへ。 - launchと運用ツール:
.launchをPythonかXMLの新形式へ書き直す。ROS 2のbagはIron以降MCAP形式が既定でROS1の.bagとは別物なので、過去の記録を検証に使うなら変換手順も用意する。
3番を飛ばしてノードを書き換えると、ビルドは通るのにデータが届かない状態で原因探しに時間を使います。前の章のReliabilityとDurabilityの検証でも、互換性の無い組み合わせは例外にならず、警告を出して受信0件のまま動き続けました。
よくある質問
ROS2とは何ですか?
ROS2はロボット開発向けのオープンソースのミドルウェアで、ROS1の設計を作り直した後継です。マスターを廃してDDSで通信し、QoS・SROS2によるセキュリティ・WindowsのTier 1対応・micro-ROSによるマイコン対応を備えます。最初の正式版Ardent Apaloneは2017年12月8日に公開され、現在は毎年5月ごろに新ディストリが公開されています。
ROS1とROS2はどちらを使うべきですか?
2026年に新規で始めるならROS2です。ROS1はNoeticが2025年5月31日にEOLとなり、公式の修正は出ません。既存のROS1製品は、Canonicalの有償延長サポート(2030年まで)で時間を確保しつつ、ROS2への移行を計画します。
ROS1とROS2は同じネットワークで通信できますか?
そのままではできません。プロトコルが別物なので、ros1_bridgeでトピックを中継します。READMEではブリッジの実行環境としてUbuntu 20.04がフル対応、22.04がソースビルドを要する部分対応、24.04が非対応です。接続先ROS2が別ディストリの場合、その通信は公式には保証されません。
JazzyとHumbleはどちらを選べばよいですか?
これから始めるならJazzyです。HumbleのEOLは2027年5月で、JazzyのEOLは2029年5月です。どうしても必要なパッケージがHumbleにしか無い場合だけHumbleを選び、Jazzy以降へ上げる時期を最初から決めておきます。
ROS2のノード同士がつながらないときは何を確認しますか?
まずros2 topic info -vで発行側と購読側のQoS(ReliabilityとDurability)を比べます。次にROS_DOMAIN_IDが双方で同じか、ディストリが揃っているかを確かめ、それでも見えなければros2 doctor --reportでRMWとネットワークの設定を確認します。