1. はじめに
前回の記事「Ubuntu 24.04とYOLO11によるAI物体検出の要素技術検証」では、Intel Processor N95を搭載したUbuntu PCを使用し、YOLO11によるリアルタイム物体検出を検証しました。
YOLO11nとYOLO11sのCPU推論性能を比較し、一般物体の検出や誤認識の事例を確認しました。
今回はその続編として、YOLO11による画像認識結果をROS2(Robot Operating System 2)に連携し、ロボットの停止要求に相当する速度指令メッセージを生成する検証を行いました。
カメラ画像から人物を検出した場合にROS2トピックへ通知し、別のROS2ノードがその通知を受信して、全速度成分がゼロのメッセージをPublishする構成です。
なお、今回の検証はROS2による通信と停止要求メッセージの生成までを対象としており、実際のロボットの走行・停止動作は行っていません。
関連記事: Ubuntu 24.04とYOLO11によるAI物体検出の要素技術検証
2. 検証目的
今回の検証では、次の3点を確認します。
- YOLO11による人物検出結果をROS2トピックにPublishできること
- 別のROS2ノードで人物検出結果をSubscribeできること
- 人物検出時に、停止要求として全速度成分がゼロの
geometry_msgs/msg/TwistメッセージをPublishできること
画像認識処理と速度指令の生成処理を別々のROS2ノードとして実装し、Publish/Subscribeによる連携を確認します。
3. 検証環境
3.1 ハードウェア構成
| 項目 | 内容 |
|---|---|
| PC | Intel Processor N95搭載PC |
| CPU | Intel Processor N95(4コア/4スレッド) |
| 内蔵GPU | Intel UHD Graphics |
| Webカメラ | Logicool C920 |
| カメラ取得解像度 | 640 × 480ピクセル |
今回も専用GPUによるアクセラレーションは使用せず、CPUでYOLO11の推論を実行しました。
3.2 ソフトウェア構成
| 項目 | バージョン |
|---|---|
| OS | Ubuntu 24.04 LTS |
| ROS2 | Jazzy |
| Python | 3.12系 |
| Ultralytics | 8.4.183 |
| PyTorch | 2.14.1 |
| OpenCV | 5.0.0.93 |
| AIモデル | YOLO11n |
YOLO11の実行には、前回作成したPython仮想環境 yolo-venv を引き続き使用しました。
ROS2 Jazzyの rclpy とUltralyticsを同じPythonプロセスから利用し、画像認識処理をROS2ノードとして実装しています。
4. システム構成
4.1 全体構成
今回のシステムは、2つのROS2ノードで構成しています。
Logicool C920 → YOLO11n(yolo_node) → /person_detected → person_stop_node → /cmd_vel_test
最初の yolo_node がWebカメラ画像を取得し、YOLO11nによって人物を検出します。
検出結果は、std_msgs/msg/Bool 型のROS2トピック /person_detected にPublishします。
次に、person_stop_node がこのトピックをSubscribeし、人物が検出された場合に、全速度成分がゼロの geometry_msgs/msg/Twist メッセージを /cmd_vel_test にPublishします。

4.2 ROS2ノードとトピック
| ノード | 入出力 | トピック | メッセージ型 |
|---|---|---|---|
| yolo_node | Publish | /person_detected | std_msgs/msg/Bool |
| person_stop_node | Subscribe | /person_detected | std_msgs/msg/Bool |
| person_stop_node | Publish | /cmd_vel_test | geometry_msgs/msg/Twist |
/person_detected は、人物が検出された場合に true、検出されない場合に false を通知します。/cmd_vel_test は、今回の検証用に用意したトピックです。
実際のロボット制御で使用する /cmd_vel とは分離し、既存のロボットやNav2などに影響しない構成としました。
5. ROS2ノードの実装
5.1 YOLO11による人物検出ノード
前回の物体検出プログラムをベースに、ROS2のPublisherを追加しました。
YOLO11nの学習済みモデルを使用し、検出した物体のクラス名が person であるかを判定します。
person_detected = False
for box in results[0].boxes:
class_id = int(box.cls[0])
if self.model.names[class_id] == 'person':
person_detected = True
break
msg = Bool()
msg.data = person_detected
self.publisher.publish(msg)
この処理では、人物として検出された物体が1つでも存在すれば true をPublishします。
人物が検出されなかった場合は false をPublishします。
また、OpenCVによるカメラ画像の取得と、YOLO11による検出結果の画面表示も継続しています。
【図1:YOLO11nによる人物検出】
前回と同様のカメラ画像(これはノートPCですが)で、これで人物を検出します。

5.2 停止要求ノード
次に、/person_detected をSubscribeする person_stop_node を作成しました。
人物検出結果が true の場合、geometry_msgs/msg/Twist 型のメッセージを生成し、/cmd_vel_test にPublishします。
def person_callback(self, msg):
if msg.data:
stop_msg = Twist()
self.publisher.publish(stop_msg)
self.get_logger().info(
'Person detected -> STOP request'
)
ROS2の Twist メッセージでは、線速度と角速度を指定できます。
今回のコードでは、Twist() の初期値を利用し、すべての速度成分を0.0としています。
| 速度成分 | 設定値 |
|---|---|
| linear.x | 0.0 |
| linear.y | 0.0 |
| linear.z | 0.0 |
| angular.x | 0.0 |
| angular.y | 0.0 |
| angular.z | 0.0 |
なお、false を受信した場合には速度指令をPublishしません。
今回のノードは、人物検出時の停止要求メッセージ生成に限定した実装です。
6. 動作検証結果
6.1 人物検出結果のPublish
YOLO11nを使用したROS2ノードを起動し、Webカメラに人物が映る状態と、映らない状態で動作を確認しました。
別のターミナルで、以下のコマンドを実行しました。
ros2 topic echo /person_detected
人物を検出した場合には、次のメッセージが出力されました。
data: true
---
人物が検出されない場合には、次のメッセージが出力されました。
data: false
---
これにより、YOLO11の画像認識結果をROS2トピックにPublishできることを確認しました。
6.2 停止要求ノードによるSubscribe
続いて、person_stop_node を起動しました。
人物検出時に、停止要求ノードが /person_detected の true を受信し、停止要求のログを出力することを確認しました。
Person detected -> STOP request
これにより、YOLO11ノードと停止要求ノード間のPublish/Subscribe通信が正常に動作していることを確認しました。
6.3 ゼロ速度指令のPublish
さらに、別のターミナルで以下のコマンドを実行しました。
ros2 topic echo /cmd_vel_test
人物検出時に、次のメッセージが出力されました。
linear:
x: 0.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
これにより、人物検出結果を受けて、全速度成分がゼロの Twist メッセージを生成・Publishできることを確認しました。
【図2:ROS2トピックの出力結果】


6.4 検証結果のまとめ
| 検証項目 | 結果 |
|---|---|
| YOLO11nによる人物検出 | 確認 |
| /person_detectedへのtrue/falseのPublish | 確認 |
| person_stop_nodeによるSubscribe | 確認 |
| /cmd_vel_testへのゼロ速度TwistのPublish | 確認 |
| 実機ロボットの停止動作 | 未実施 |
今回の検証により、AI画像認識からROS2通信、停止要求メッセージ生成までの一連の処理が正常に動作することを確認しました。
7. 考察と今後の課題
7.1 人物の部分的な検出
今回の検証では、カメラ画像に手など身体の一部分が入っただけでも、person と判定され、true がPublishされる場面がありました。
現在の実装では、YOLO11が person クラスとして検出した物体が1つでも存在すれば、人物検出と判断します。
そのため、人物全体が映っていることを確認する処理や、検出信頼度による独自の判定条件は設けていません。
また、部分的な人物の検出と、別の対象物を人物と判定する誤検出については、区別して評価する必要があります。
実用システムへの適用には、検出信頼度、連続検出回数、判定時間などの条件を検討する必要があります。
7.2 停止要求と実際のロボット停止の違い
今回確認したのは、全速度成分がゼロの Twist メッセージをPublishできることです。
これは、実際のロボットが確実に停止することを保証するものではありません。
例えば、Nav2やWeb操作ノードなど、別のノードが同時に /cmd_vel へ移動指令をPublishしている場合、停止要求の後に新たな移動指令が送信される可能性があります。
そのため、実機で利用する場合には、速度指令を一元的に管理する仲裁機構などが必要になります。
また、カメラの停止、YOLOノードの異常終了、ROS2通信の途絶などによって人物検出結果が更新されなくなる場合も考慮する必要があります。
7.3 安全機能としての位置づけ
YOLO11による人物検出は、画像認識機能を利用した動作判断の一例です。
ただし、今回の構成は安全認証された人検知・停止システムではありません。
実際の移動ロボットでは、LiDARなどによる障害物検出、非常停止機構、モーター制御側のタイムアウト処理など、独立した安全対策が必要になります。
今回の検証は、画像認識結果をROS2の制御系へ連携するための要素技術検証と位置づけています。
8. 今後の展開
今回の検証では、YOLO11による人物検出結果をROS2トピックとして通知し、別ノードで停止要求メッセージを生成するところまで確認しました。
今後は、次のような発展を検討しています。
- ROS2の速度指令仲裁ノードとの連携
- 人物検出結果を利用したロボットの動作切り替え
- Nav2による自律移動との連携
- LiDARなどの距離センサーとの組み合わせ
- Raspberry Piなどのエッジデバイスへの展開
画像認識、ROS2、センサー、モーター制御を組み合わせることで、周辺環境を認識し、その結果を動作に反映するロボットシステムへの発展が考えられます。
9. まとめ
Ubuntu 24.04 LTS、ROS2 Jazzy、YOLO11nを使用し、AI画像認識とROS2による停止要求の連携検証を実施しました。
今回の検証では、以下の3点を確認しました。
- YOLO11nによる人物検出結果を
/person_detectedにPublishできた - 別のROS2ノードで人物検出結果をSubscribeできた
- 人物検出時に
/cmd_vel_testへ全速度成分がゼロのTwistメッセージをPublishできた
これにより、AI画像認識からROS2通信を経由して速度指令メッセージを生成するまでの一連の動作を確認しました。
今回の検証では実機ロボットの走行・停止は行っていませんが、画像認識結果をロボット制御システムへ連携するための基本構成を確認できました。
今後は、実機ロボットとの連携や、LiDARなどのセンサー情報との組み合わせについても検討していきます。
関連技術: Ubuntu 24.04 / ROS2 Jazzy / Python / YOLO11 / OpenCV / 画像認識 / ROS2 Publish・Subscribe / geometry_msgs / ロボット制御 / フィジカルAI
開発・技術検証に関するお問い合わせ
株式会社インデペンデンスシステムズ横浜では、組込みLinux、Raspberry Pi、ROS2、センサー連携、画像処理などを利用したソフトウェア開発・技術検証に取り組んでいます。
技術検証や既存システムとの連携については、企業サイトのお問い合わせフォームよりご相談ください。

