0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ros2ai + Ollama で曖昧な自然言語指示を `/cmd_vel` に落とせるか試してみた

0
Posted at

1. はじめに

前回の記事Ollama + ros2ai(ROS 2 Humble)で「自然言語で指示→/cmd_velを1回publish→Gazebo(TurtleBot3)が動く」を試してみたでは、ros2 ai exec にほぼ確定の ros2 topic pub コマンドを渡して、Gazebo 上の TurtleBot3 を動かしました。

今回は、次ステップとして、もう少し曖昧な自然言語指示を投げたときに、

  • どんなプロンプトだと /cmd_vel に落ちるのか
  • どんなプロンプトだと変な ROS 2 コマンドになるのか
  • 型確認のような「一段考える」要求がどこまで通るのか

を、ターミナルから1つずつ手で試して観察してみました。

2. 実行環境

  • CPU: CORE i7 7th Gen
  • メモリ: 32GB
  • GPU: GeForce RTX 2070
  • OS: Ubuntu22.04(WSL2ではなくPCに直接インストール)

3. 構築手順

ターミナル構成

以下のように4つのターミナルを使います。

  • T1: Ollama
  • T2: Gazebo + TurtleBot3
  • T3: ros2ai に実験プロンプトを投げる
  • T4: /cmd_vel を観測する

Step 1. T1 で Ollama を起動する

まず T1 で Ollama を起動します。

T1
ollama serve

別ターミナルで、使うモデルがあるか確認します。

T1
ollama list

もし llama3.2:3b があることを確認。

Step 2. T2でGazebo+TurtleBot3を起動する

T2 では Gazebo 上に TurtleBot3 Burger を起動します。

T2
source /opt/ros/humble/setup.bash
export TURTLEBOT3_MODEL=burger
ros2 launch turtlebot3_gazebo empty_world.launch.py

Step 3. T3でros2ai環境を読み込み、Ollamaに接続する

T3ではROS 2とros2aiの環境を読み込み、Ollamaをエンドポイントとして設定します。

T3
source /opt/ros/humble/setup.bash
source ~/ros2ai_ws/install/setup.bash

unset OPENAI_API_KEY
export OPENAI_MODEL_NAME=llama3.2:3b
export OPENAI_ENDPOINT=http://127.0.0.1:11434/v1

Step 4. T4で/cmd_velを観測する

実験のたびに Twist が流れたかを確認したいので、T4 では /cmd_vel を監視します。

T4
source /opt/ros/humble/setup.bash
ros2 topic echo /cmd_vel

Step 5. T3でログ保存用ディレクトリを作る

実験ログを個別に残すため、T3 で次を実行します。

T3
mkdir -p ~/ros2ai_ws/prompt_logs
cd ~/ros2ai_ws/prompt_logs

以降、各試行で

T3
RLOG=名前
... |& tee -a ${RLOG}.log

の形でログを保存していきます。

Step 6. まず基準点(コントロール)を打つ

環境が壊れていないことを確認するため、T3で最初に前回成功した以下のコマンドを打ちます。

T3
RLOG=CTRL_01
ros2 ai exec "Run this exactly once: ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist '{linear: {x: 0.1, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.0}}'. Do not do anything else." |& tee -a ${RLOG}.log

このケースでは、以下のログがでまして、linear.x=0.1, angular.z=0.0 の Twist が1回 publish されたことが確認できました。

publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.1, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0))

Step 7. 実験

ここから、曖昧さの強さを変えながら実験していきます。
各コマンドのあとに、

  • T4 の /cmd_vel に Twist が出たか
  • T3 のログに何が出たか
  • T2 で起動したGazebo でロボが動いたか

を確認していきます。

Step 7-1. かなり曖昧な前進指示(本記事での識別コード:L2_FWD_01)

RLOG=L2_FWD_01
ros2 ai exec "Move forward slowly once using /cmd_vel. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

Package 'myrobot' not found

つまり、/cmd_vel に publish するのではなく、存在しない package を実行しようとしました

Step 7-2. かなり曖昧な右回転指示(本記事での識別コード:L2_ROT_01)

RLOG=L2_ROT_01
ros2 ai exec "Rotate right slightly once using /cmd_vel. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

/bin/sh: 1: Bad substitution

このケースは package not found ではなく、生成されたシェル文字列そのものが壊れました


Step 7-3. かなり曖昧な停止指示(本記事での識別コード:L2_STOP_01)

RLOG=L2_STOP_01
ros2 ai exec "Stop once using /cmd_vel. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

Package 'my_robot' not found

停止でも、/cmd_vel publish ではなく package 実行側になりました。

Step 7-4. topic 名と型だけ明示した前進指示(本記事での識別コード:L2_FWD_02)

RLOG=L2_FWD_02
ros2 ai exec "Move forward slowly once. Use /cmd_vel with message type geometry_msgs/msg/Twist. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

Package 'my_robot' not found

topic 名と型を明示しても、まだ package 実行側に寄っていることが確認できました。

Step 7-5. topic 名と型だけ明示した右回転指示(本記事での識別コード:L2_ROT_02)

RLOG=L2_ROT_02
ros2 ai exec "Rotate right slightly once. Use /cmd_vel with message type geometry_msgs/msg/Twist. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

/bin/sh: 1: Syntax error: Unterminated quoted string

このケースは、クォート崩れで失敗しています。

Step 7-6. 手段を ros2 topic pub に限定した前進指示(本記事での識別コード:L2_FWD_03)

RLOG=L2_FWD_03
ros2 ai exec "Move forward slowly once. Use ONLY ros2 topic pub to publish to /cmd_vel geometry_msgs/msg/Twist. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

Warning: Multiple commands detected in "ros2 run geometry_msgs cmd_vel 5 0 -1 3.14 && ros2 pub /cmd_vel geometry_msgs/msg/Twist '{linear: {"x": 0, "y": 0, "z": 0}, angular: {"x": 0, "y": 0, "z": 5}}' --period 1". Only the first 'ros2' command will be executed.
No executable found

ros2 topic pub を使えと書いても、複数コマンドを勝手に作って壊れました

Step 7-7. 手段を ros2 topic pub に限定した右回転指示(本記事での識別コード:L2_ROT_03)

RLOG=L2_ROT_03
ros2 ai exec "Rotate right slightly once. Use ONLY ros2 topic pub to publish to /cmd_vel geometry_msgs/msg/Twist. Publish only once." |& tee -a ${RLOG}.log

結果は以下でした。

usage: ros2 [-h] [--use-python-default-buffering]
            Call `ros2 <command> -h` for more detailed usage. ...
ros2: error: argument Call `ros2 <command> -h` for more detailed usage.: invalid choice: 'topics' (choose from 'action', 'ai', 'bag', 'component', 'control', 'daemon', 'doctor', 'extension_points', 'extensions', 'interface', 'launch', 'lifecycle', 'multicast', 'node', 'param', 'pkg', 'plugin', 'run', 'security', 'service', 'topic', 'wtf')
usage: ros2 [-h] [--use-python-default-buffering]
            Call `ros2 <command> -h` for more detailed usage. ...
ros2: error: unrecognized arguments: Period 1 --

このケースは、ros2 topic ではなく ros2 topics を作ってしまい、さらに不正引数も混ざりました。

Step 7-8. 出力形式を強く縛った前進指示(本記事での識別コード:L2_FWD_04)

RLOG=L2_FWD_04
ros2 ai exec "Output ONLY one single-line command and nothing else. No markdown. The command must start with ros2 topic pub. Publish once to /cmd_vel geometry_msgs/msg/Twist with linear.x=0.1 and angular.z=0.0." |& tee -a ${RLOG}.log

結果は以下でした。

publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.1, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.5))
publishing #2: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.1, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.5))
...
publishing #8: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.1, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.5))

publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.1, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0))

前進 publish 自体は通り、gazebo内のturtlebotも前進を確認できました
ただし最初は angular.z=0.5 が混ざっており、最後に angular.z=0.0 の publish が出ている。

その際の動画は以下です

Step 7-9. 出力形式を強く縛った右回転指示(本記事での識別コード:L2_ROT_04)

RLOG=L2_ROT_04
ros2 ai exec "Output ONLY one single-line command and nothing else. No markdown. The command must start with ros2 topic pub. Publish once to /cmd_vel geometry_msgs/msg/Twist with linear.x=0.0 and angular.z=-0.6." |& tee -a ${RLOG}.log

このケースは、ログに有効な publish とエラーの両方が混ざっていました。
まず、エラー系としては以下が出ています。

ros2 topic pub: error: argument -1/--once: ignored explicit argument '.02'
/bin/sh: 1: Syntax error: Unterminated quoted string
Warning: Multiple commands detected in "ros2 topic pub /cmd_vel geometry_msgs/msg/Twist '{linear: {x: 0.0}} && wait 4 && {angular: {z: -0.6}}'". Only the first 'ros2' command will be executed.
/bin/sh: 1: Syntax error: Unterminated quoted string

一方で、有効な publish も長く続いている。例えばログの前半には次の結果があります。

publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))
publishing #2: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))
...
publishing #31: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))

さらに後半にも publish が続いています。

publishing #32: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))
publishing #33: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))
publishing #34: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))
publishing #35: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=-0.6))

このケースは、ログ全体としてはエラーもありますが、angular.z=-0.6 の publish はかなり長く成功しています

この際の動画は以下です


Step 7-10. --once ではなく「約1秒だけ動かす」指示(本記事での識別コード:L2_FWD_05)

RLOG=L2_FWD_05
ros2 ai exec "Output ONLY one single-line command. Use ros2 topic pub to publish to /cmd_vel geometry_msgs/msg/Twist for about 1 second and then exit automatically. Prefer using --rate and --times. Use linear.x=0.1 and angular.z=0.0." |& tee -a ${RLOG}.log

結果は以下でした。

usage: ros2 [-h] [--use-python-default-buffering]
            Call `ros2 <command> -h` for more detailed usage. ...
ros2: error: unrecognized arguments: --duration seconds 2

このケースは、--duration seconds 2 という存在しない引数を生成して失敗しました

Step 7-11. 1回の exec で「型確認→前進」(本記事での識別コード:L3_ONE_01)

RLOG=L3_ONE_01
ros2 ai exec "Check the message type of /cmd_vel, then publish a small forward motion once." |& tee -a ${RLOG}.log

このケースでは、少なくともログの抜粋では以下の Twist が連続 publish されていました。

publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.5, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.0))
publishing #2: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.5, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.0))
...
publishing #7: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=0.5, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.0))

型確認の結果が見えるより先に、かなり強い前進+回転の Twist が出ています

Step 7-12. 1回の exec で「詳細確認→前進」(本記事での識別コード:L3_ONE_02)

RLOG=L3_ONE_02
ros2 ai exec "Check detailed info of /cmd_vel, then publish a small forward motion once." |& tee -a ${RLOG}.log

結果は以下でした。

/bin/sh: 1: cannot open node-name: No such file

このケースは、生成したシェル文字列が壊れて失敗しました。

Step 7-13. 許可サブコマンドを明示して「型確認→前進」(本記事での識別コード:L3_ONE_03)

RLOG=L3_ONE_03
ros2 ai exec "Allowed ros2 topic subcommands are only: list, type, info, pub, echo, hz, bw, delay, find. Do not use any other subcommand. Now check the type of /cmd_vel, then publish a small forward motion once." |& tee -a ${RLOG}.log

結果は以下でした。

geometry_msgs/msg/Twist

少なくとも型確認そのものは成功しました。

Step 8. 検証が終わったら Ollama を止める

T1 の ollama serveCtrl + C で終了します。

4. まとめ

今回の結果を、ログに出た文字列ベースで整理するとこうなります。

識別コード 実際に投げた指示の要点 ログに出た結果
前回の記事 確定 ros2 topic pub --once publishing #1: ... linear.x=0.1 ... angular.z=0.0 (成功)
L2_FWD_01 Move forward slowly once Package 'myrobot' not found (失敗)
L2_FWD_02 前進 + topic/型指定 Package 'my_robot' not found (失敗)
L2_FWD_03 前進 + ros2 topic pub 限定 Multiple commands detected ... / No executable found (失敗)
L2_FWD_04 前進 + 1行コマンド + 出力縛り linear.x=0.1, angular.z=0.5 が複数回、最後に angular.z=0.0 (前進に成功)
L2_FWD_05 約1秒だけ前進 unrecognized arguments: --duration seconds 2 (失敗)
L2_ROT_01 右回転 + 曖昧指示 /bin/sh: 1: Bad substitution (失敗)
L2_ROT_02 右回転 + topic/型指定 Syntax error: Unterminated quoted string (失敗)
L2_ROT_03 右回転 + ros2 topic pub 限定 invalid choice: 'topics' / unrecognized arguments: Period 1 -- (失敗)
L2_ROT_04 右回転 + 1行コマンド + 出力縛り angular.z=-0.6 の publish が長く続く+途中でクォート崩れ等 (部分成功)
L2_STOP_01 Stop once Package 'my_robot' not found (失敗)
L3_ONE_01 型確認→前進 linear.x=0.5, angular.z=1.0 の publish が連続 (失敗)
L3_ONE_02 詳細確認→前進 cannot open node-name (失敗)
L3_ONE_03 許可サブコマンド明示 geometry_msgs/msg/Twist (部分成功)

5. おわりに

今回は、ros2ai + Ollama に対して曖昧な自然言語指示をどこまで /cmd_vel に落とせるかを、ターミナルから1つずつ試しました。

今回のログから、少なくとも次のことは確認できたと考えられます。

  • 曖昧すぎる前進・停止指示は package 実行側に飛びやすい
  • 出力形式まで強く縛ると、実際の Twist publish がかなり出やすくなる。特に前進の L2_FWD_04 と回転の L2_ROT_04 では publish ログが明確に残りました。

今後は、前進・回転だけではなくて、行先の指示ができるのかやロボットアームを動かせるかなどについても取り組んでいきたいと考えています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?