概要
ROS 2とGazeboを使い、「失敗から学習するPhysical AI投球ロボット」を作成しました。
最初はランダムな力でボールを投げ、投球後に目標位置と着地点の誤差を計算し、その結果を使ってX方向とY方向の投射力を修正して精度を自動で高めていきます
デモ動画
動画では、ランダムな初期投射から始まり、失敗するたびに着地誤差が小さくなる様子を確認できます。
実行環境
- Mac Apple M1
- Docker Desktop
- ROS 2 Humble
- Gazebo Classic 11
- Python 3
- Cyclone DDS
ソースコード
コードとGazeboワールドはGitHubで公開しています。
https://github.com/inoueissei/physical-ai-ball-launcher
主なファイルは次のとおりです。
physical-ai-ball-launcher/
├── README.md
├── learn_2d.py
├── predict_force.py
├── ai_ball_launcher.world
└── results/
├── learning_results.csv
└── learning_console_10_trials.txt
作成したタスク
Gazebo上に、次の要素を配置しました。
- 発射台ロボット
- 投射用ボール
- 約5 m先の目標マーカー
- 赤色の目標エリア
- 緑色の目標中心
発射機構は簡略化し、ROS 2の/apply_link_wrenchサービスを使って、
ボールへX・Y・Z方向の力を加えています。
システムの流れ
処理の流れは次のとおりです。
- X・Y方向の初期投射力をランダムに決める
- Gazebo上でボールを投げる
- ボールの着地点を取得する
- 目標位置と着地点のX・Y誤差を計算する
- 誤差に応じて次の投射力を修正する
- 成功するまで投球を繰り返す
- 成功後もTrial 10まで投球を継続する
学習方法
X方向とY方向の誤差を、以下の式で求めています。
error_x = target_x - landing_x
error_y = target_y - landing_y
修正後の投射力は以下の考え方で更新します
next_force =
current_force
+ learning_rate × error / distance_per_force
通常の学習率は0.5としました。
そのため、投球ごとに誤差がおおむね半分ずつ小さくなります。
最初に目標範囲へ到達した後は、学習率を0.2へ変更し、 投射力を細かく調整する「精度向上モード」へ移行します。
TARGET_X = 3.84514
TARGET_Y = 0.34887
LEARNING_RATE = 0.5
PRECISION_LEARNING_RATE = 0.2
SUCCESS_RADIUS = 0.07
MAX_TRIALS = 10
成功条件は、ボール中心と目標中心の2次元距離が 0.07 m以下になることです。
distance_error =
sqrt(error_x^2 + error_y^2)
Macでの実行方法
- ターミナルで以下を実行
docker start pai_ros2
docker ps --filter name=pai_ros2
以下が表示されればOK
docker ps --filter name=pai_ros2
pai_ros2
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bdb32d4257e6 airobotbook/ros2-desktop-ai-robot-book-humble:latest "/bin/bash -c /entry…" 2 weeks ago Up Less than a second 0.0.0.0:9090->9090/tcp, [::]:9090->9090/tcp, 0.0.0.0:9876->9876/tcp, [::]:9876->9876/tcp, 0.0.0.0:6080->80/tcp, [::]:6080->80/tcp pai_ros2
- pai_ros2と表示
- STATUSがUp
- PORTSに6080->80/tcpが表示
続いてブラウザでUbuntuデスクトップを表示
http://localhost:6080/
- ROS連携版Gazeboを起動
Ubuntuターミナルで以下を実施
source /opt/ros/humble/setup.bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
ros2 launch gazebo_ros gazebo.launch.py \
world:=/home/ubuntu/ai_ball_launcher.world
Gazeboが開く
- 青い発射台とオレンジの発射筒
- 白い球
- 約5 m先の赤緑ターゲット
- 10投球の自動学習プログラムを実行
Mac側のターミナルで以下を実施
# docker execは、起動中のコンテナ内でコマンドを実行します。
docker exec -u ubuntu pai_ros2 bash -lc '
source /opt/ros/humble/setup.bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export PYTHONUNBUFFERED=1
mkdir -p /home/ubuntu/tamain_ai/results
python3 -u /home/ubuntu/tamain_ai/learn_2d.py 2>&1 |
tee /home/ubuntu/tamain_ai/results/learning_console_10_trials.txt
'
成功時:
- Trial 1からリアルタイム表示
- MISSのたびにX・Y方向の投射力を修正
- 初回成功後は精度向上モードへ移行
- Trial 10まで継続
- 最後にLEARNING SUMMARYを表示
実際の表示結果
AI SMART BALL LAUNCHER
Learning from failed attempts in Gazebo
Target : X=3.845, Y=0.349
Learning rate : 0.50
Success radius : 0.070 m
Maximum trials : 10
Random seed : 42
Random initial force: Fx=23.8366 N, Fy=3.1000 N
==========================================================
TRIAL 1
==========================================================
Force : Fx= 23.8366 N, Fy= 3.1000 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 2.1877 m, Y = -0.6542 m
Error : Ex= 1.6574 m, Ey= 1.0031 m
2D distance : 1.9373 m
Result : MISS
AI recognized the failed attempt.
Active learning rate: 0.50
Correction : dFx=+6.2899 N, dFy=+3.8111 N
Next force : Fx=30.1265 N, Fy=6.9111 N
==========================================================
TRIAL 2
==========================================================
Force : Fx= 30.1265 N, Fy= 6.9111 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.0161 m, Y = -0.1523 m
Error : Ex= 0.8290 m, Ey= 0.5012 m
2D distance : 0.9687 m
Result : MISS
AI recognized the failed attempt.
Active learning rate: 0.50
Correction : dFx=+3.1461 N, dFy=+1.9041 N
Next force : Fx=33.2727 N, Fy=8.8152 N
==========================================================
TRIAL 3
==========================================================
Force : Fx= 33.2727 N, Fy= 8.8152 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.4305 m, Y = 0.0985 m
Error : Ex= 0.4147 m, Ey= 0.2504 m
2D distance : 0.4844 m
Result : MISS
AI recognized the failed attempt.
Active learning rate: 0.50
Correction : dFx=+1.5737 N, dFy=+0.9513 N
Next force : Fx=34.8464 N, Fy=9.7665 N
==========================================================
TRIAL 4
==========================================================
Force : Fx= 34.8464 N, Fy= 9.7665 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.6377 m, Y = 0.2238 m
Error : Ex= 0.2074 m, Ey= 0.1251 m
2D distance : 0.2422 m
Result : MISS
AI recognized the failed attempt.
Active learning rate: 0.50
Correction : dFx=+0.7871 N, dFy=+0.4753 N
Next force : Fx=35.6335 N, Fy=10.2418 N
==========================================================
TRIAL 5
==========================================================
Force : Fx= 35.6335 N, Fy= 10.2418 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.7414 m, Y = 0.2864 m
Error : Ex= 0.1037 m, Ey= 0.0625 m
2D distance : 0.1211 m
Result : MISS
AI recognized the failed attempt.
Active learning rate: 0.50
Correction : dFx=+0.3937 N, dFy=+0.2375 N
Next force : Fx=36.0272 N, Fy=10.4793 N
==========================================================
TRIAL 6
==========================================================
Force : Fx= 36.0272 N, Fy= 10.4793 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.7933 m, Y = 0.3176 m
Error : Ex= 0.0519 m, Ey= 0.0312 m
2D distance : 0.0606 m
Result : SUCCESS
AI reached the target zone for the first time.
Switching to precision mode.
Consecutive successes: 1
Active learning rate: 0.20
Correction : dFx=+0.0788 N, dFy=+0.0475 N
Next force : Fx=36.1060 N, Fy=10.5268 N
==========================================================
TRIAL 7
==========================================================
Force : Fx= 36.1060 N, Fy= 10.5268 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.8036 m, Y = 0.3239 m
Error : Ex= 0.0415 m, Ey= 0.0250 m
2D distance : 0.0485 m
Result : SUCCESS
AI maintained a successful throw.
Consecutive successes: 2
Active learning rate: 0.20
Correction : dFx=+0.0630 N, dFy=+0.0380 N
Next force : Fx=36.1690 N, Fy=10.5647 N
==========================================================
TRIAL 8
==========================================================
Force : Fx= 36.1690 N, Fy= 10.5647 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.8119 m, Y = 0.3289 m
Error : Ex= 0.0332 m, Ey= 0.0200 m
2D distance : 0.0388 m
Result : SUCCESS
AI maintained a successful throw.
Consecutive successes: 3
Active learning rate: 0.20
Correction : dFx=+0.0504 N, dFy=+0.0304 N
Next force : Fx=36.2195 N, Fy=10.5951 N
==========================================================
TRIAL 9
==========================================================
Force : Fx= 36.2195 N, Fy= 10.5951 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.8186 m, Y = 0.3329 m
Error : Ex= 0.0266 m, Ey= 0.0160 m
2D distance : 0.0310 m
Result : SUCCESS
AI maintained a successful throw.
Consecutive successes: 4
Active learning rate: 0.20
Correction : dFx=+0.0403 N, dFy=+0.0243 N
Next force : Fx=36.2598 N, Fy=10.6194 N
==========================================================
TRIAL 10
==========================================================
Force : Fx= 36.2598 N, Fy= 10.6194 N
Target : X = 3.8451 m, Y = 0.3489 m
Landing : X = 3.8239 m, Y = 0.3361 m
Error : Ex= 0.0213 m, Ey= 0.0128 m
2D distance : 0.0248 m
Result : SUCCESS
AI maintained a successful throw.
Consecutive successes: 5
Active learning rate: 0.20
Correction : dFx=+0.0323 N, dFy=+0.0194 N
All 10 throws have been completed.
==========================================================
LEARNING SUMMARY
==========================================================
Trials completed : 10
Total successes : 5
First success : 6
Final result : SUCCESS
CSV saved to : /home/ubuntu/tamain_ai/results/learning_results.csv
The AI reached the target and maintained successful performance through the final trial.

