ビジョンフィードバック制御

画像が合うまで動き続ける

大阪大学 中島優作

← シリーズ一覧に戻る

参考資料

  • F. Chaumette, S. Hutchinson: Visual Servo Control, Part I: Basic Approaches, IEEE Robotics & Automation Magazine, 2006
    数式の基本はこれ 1 本で分かる(本スライドの記号もこれに合わせる)
  • S. Hutchinson, G. Hager, P. Corke: A Tutorial on Visual Servo Control, IEEE Trans. Robotics and Automation, 1996
  • P. Corke: Robotics, Vision and Control(教科書。Python のコード付き)
  • 川村貞夫: 相対位置誤差でロボットを動かす(チトセロボティクス 技術コラム)

前提:カメラ/デプスカメラ(キャリブレーション)、物体検出

なぜビジョンフィードバックか?

全画面表示

部品をドラッグして動かしてみよう。どちらも追従するが、見ながら動くだけがぴったり合う

うれしいことは 2 つ

① 目として使える
  • 置き方が毎回違う物を見つけて取りに行く
  • 動いている物を追いかける
  • 途中で物がずれても追従する
② 精度が上がる
  • キャリブレーション・ロボットのモデルが多少ずれていても合う
  • 画像が合うまで動き続けるので、誤差はフィードバックの中で吸収される
  • 精度の低いロボットでも、結果として精度が出る

① はよく知られた使い方。② こそビジョンフィードバックのいちばんおいしいところ

なぜ誤差が消えるのか

見てから動く:誤差が足し算で積み上がる 画像で検出+ 検出誤差 カメラ→ロボット座標+ キャリブ誤差 逆運動学+ リンク長の誤差 ロボットが動く+ たわみ・熱 ずれて到着全部の合計 見ながら動く:基準は「画像の中のずれ」だけ 画像で手先と相手のずれ同じ画像で両方を測る ずれを減らす方向へ少し動くモデルは「方向」が合えば十分 ずれ 0 で止まる残るのは画像の計測誤差 ずれが残っている間は繰り返す

モデルの誤差は「動く速さ・まっすぐさ」に効くだけで、最後に合う場所は変わらない

見てから動く vs 見ながら動く

見てから動く(Look-and-Move)
→ 全体の計画
見ながら動く(ビジュアルサーボ)
→ 局所的な合わせ込み
流れ1 回撮影 → 位置を計算 → 動く撮影と動作を毎周期繰り返す
精度を決めるものキャリブレーション+ロボットの絶対精度画像の計測(分解能・検出の安定さ)
速さ速い(あとは位置制御で一気に)合うまで時間がかかる。フレームレートで決まる
実装簡単。MoveIt で目標姿勢へ速度指令でリアルタイムに動かす仕組みが必要
向く作業大まかに取りに行く(ピッキング)穴への挿入・位置合わせ・動く物の追従
実際は組み合わせる スタート 全体の計画:見てから動く 障害物を避けて大きく近づく(MoveIt で目標姿勢へ) 局所的な合わせ込み:見ながら動く 目標

全体の計画で数 cm 手前まで速く行き、最後の数 cm を画像で合わせる

何で誤差を測るか:IBVS と PBVS

IBVS(画像ベース) 誤差= 今の点と目標の点 の画像上の差 ◎ キャリブ誤差に強い △ 3D の動きが遠回りになることも PBVS(位置ベース) 画像から 3D 姿勢推定 誤差=今と目標の 3D 位置・姿勢の差 ◎ 3D でまっすぐ動く △ キャリブ誤差がそのまま残る

「誤差を画像のまま使うか、3D に直してから使うか」の違い

カメラをどこに付けるか

手先に付ける(Eye-in-Hand)
  • 近づくほど大きく・細かく見える → 最後の位置合わせに強い
  • 「目標の見え方」を1 枚撮っておくだけで教示できる
  • 近すぎると相手が視野から外れる
外に固定(Eye-to-Hand)
  • 手先と相手を同じ画像で見られる → 相対的なずれを直接測れる
  • 作業場所全体を見渡せる
  • ロボット自身で相手が隠れることがある

両方を使うことも多い(固定カメラで近づき、手先カメラで合わせる)

ビジョンフィードバックの
ハードウェアと制御の注意点

フレームレートと遅れが効く

時間 ずれ 0 遅れが小さい:ゲインを上げても素直に収束 遅れが大きいのにゲインが高い:行き過ぎて振動
  • 普通のカメラは 30〜60 fps。撮影・転送・検出で、さらに数十 ms 遅れる
  • 遅れがあるほど、ゲインを上げると行き過ぎ・振動する
  • 動く物を速く追うなら1000 fps 級の高速ビジョンという選択肢もある

見えなくなると止まる

  • 視野から外れる:近づくほど、回すほど起きやすい(特に Eye-in-Hand)
  • 隠れる:ロボットのハンド・腕が相手を隠す(特に Eye-to-Hand)
  • 検出が揺れる:照明・映り込みで特徴点が飛ぶ → ロボットが震える
  • 対策:見失ったら止まる・戻る処理、マーカー(AprilTag/ArUco)、前処理

安定した検出がすべての前提 → 物体検出のスライドの前処理を参照

指令は位置ではなく速度で

カメラ30〜60 Hz ビジュアルサーボ手先の速度を計算 速度 → 関節角ヤコビ行列・積分 ロボット125 Hz〜1 kHz 遅いカメラと速いロボットの間をつなぐ
  • 毎フレーム「目標位置」を出し直すと、そのたびに加減速して止まる → ガタつく
  • 「この向きにこの速さで」と速度で指令し、ロボット側でなめらかにつなぐ
  • ROS 2 では MoveIt Servo が速度指令を受けて関節の指令にしてくれる

画像ベース(IBVS)

IBVS とは

  • 目標の位置にいるときの見え方を 1 枚撮っておく(特徴点 s*)
  • 今の特徴点 s が s* に重なるように、カメラ(手先)を動かす
  • 誤差は画像の上だけで計算 → ロボット座標での目標位置はどこにも出てこない
  • カメラの内部パラメータやロボットのモデルがずれていても、重なったところで止まる

「この見え方になるまで動け」= Teach by Showing(見せて教える)

IBVS の数式

vc = −λ L̂+ (s − s*)

  • s:今の画像の特徴(例:4 点の座標)(入力)
  • s*:目標の見え方の特徴(撮っておく)
  • vc:カメラの速度(並進 3 + 回転 3)(出力)
  • L̂:相互作用行列(画像ヤコビ行列)の推定値
  • λ:ゲイン(自分で決める)
  1. 画像から特徴 s を測る
  2. e = s − s*
  3. vc = −λ L̂+ e(L̂+ は擬似逆行列)
  4. vc を手先の速度指令に変換して送る(毎フレーム繰り返す)

重なっていれば e = 0(動かない)

記号は Chaumette & Hutchinson 2006 に合わせた

相互作用行列 L

ds/dt = L vc

カメラの速度 → 画像上の点の速度(関節速度 → 手先速度のヤコビ行列と同じ形)

画像上の 1 点 (x, y)(正規化座標)、奥行き Z のとき

L = ⎡ −1/Z  0  x/Z  xy  −(1+x²)  y ⎤
  ⎣ 0  −1/Z y/Z 1+y²  −xy  −x ⎦
  • 1 点で 2 行 → 6 自由度を決めるには3 点以上(ふつうは 4 点)
  • Z(奥行き)は正確でなくてよい。目標位置での Z を固定で使うことも多い
  • L がずれていても、動く方向がおおよそ合っていれば収束する

ゲイン λ の調整

時間 ずれ λ 小:安定だが遅い λ ちょうど λ 大:遅れがあると振動
  • ずれに比例した速度 → ずれが小さくなるほどゆっくり近づく(指数関数的に収束)
  • λ の上限はフレームレートと遅れで決まる
  • 実用では速度の上限をかける・ずれが大きいときは λ を下げる

位置ベース(PBVS)

PBVS とは

  • 画像から相手の3D 位置・姿勢を推定(マーカー、物体の 3D モデル、深度)
  • 「相手に対して手先がどこにいるべきか」との差を 3D で計算
  • 3D 空間でまっすぐ動くので、動きが分かりやすい
  • ただし姿勢推定にカメラの内部パラメータを使う → その誤差は残る

それでも「相手に対する相対位置」で合わせるので、見てから動くよりは誤差に強い

PBVS の数式

vc = −λ t, ωc = −λ θu

  • t:今のカメラから見た、目標のカメラ位置までの並進のずれ(入力)
  • θu:回転のずれ(回転軸 u × 角度 θ)(入力)
  • vc, ωc:カメラの並進・回転速度(出力)
  • λ:ゲイン
  1. 画像から相手の 3D 姿勢を推定
  2. 目標との差 t, θu を計算
  3. vc, ωc を計算
  4. 手先の速度指令にして送る(毎フレーム)

IBVS と同じ「ずれに比例した速度」

並進のずれの取り方にはいくつか流儀がある(Chaumette & Hutchinson 2006)

IBVS と PBVS の使い分け

IBVSPBVS
誤差を測る場所画像の上3D 空間
キャリブ誤差強い(最後は画像で合う)姿勢推定の誤差が残る
3D の動き大きく回ると遠回り・後退することもまっすぐ
視野から外れる外れにくい(画像の中で動く)外れることがある
準備目標の見え方を 1 枚撮る相手の 3D モデル・マーカー

精度が欲しい最後の位置合わせは IBVS、大きく動くときは PBVS や見てから動く

ROS 2 での実装

ROS 2 での構成

カメラノードimage_raw 特徴の検出AprilTag・YOLO サーボノードv = −λ L⁺ e(自作) MoveIt Servo速度 → 関節 ros2_controlロボット 特徴点(画素 → 正規化座標) TwistStamped(手先の速度) ロボットが動く → 見え方が変わる(ループ)
  • 自作するのはサーボノードだけ(誤差 → 速度の計算は数十行)
  • 本格的に使うなら ViSP(Inria のビジュアルサーボ用ライブラリ)

▶ MoveIt Servo ▶ ViSP

サーボノードの中身


import numpy as np
from geometry_msgs.msg import TwistStamped
def interaction_matrix(x, y, Z):
    return np.array([[-1/Z, 0, x/Z, x*y, -(1 + x*x), y],
                     [0, -1/Z, y/Z, 1 + y*y, -x*y, -x]])
def ibvs(s, s_star, Z_star, lam=0.5):
    # s, s_star: 正規化座標 [(x, y), ...] の 4 点
    L = np.vstack([interaction_matrix(x, y, Z_star) for x, y in s_star])
    e = (np.asarray(s) - np.asarray(s_star)).ravel()
    return -lam * np.linalg.pinv(L) @ e          # [vx, vy, vz, wx, wy, wz]

v = ibvs(s, s_star, Z_star=0.25)
v = np.clip(v, -0.1, 0.1)                        # 速度の上限
msg = TwistStamped()
msg.header.frame_id = "camera_color_optical_frame"   # カメラ座標系の速度
t = msg.twist
t.linear.x, t.linear.y, t.linear.z = v[:3]
t.angular.x, t.angular.y, t.angular.z = v[3:]
servo_pub.publish(msg)                           # → MoveIt Servo へ
                    

L は目標の見え方 s* と Z* で固定(簡単で安定)。速度は必ず上限で切る

活用事例

活用事例:キャリブレーションなしで高精度

  • チトセロボティクスの「クルーボ」:ビジュアルフィードバック制御ソフトウェア
  • 手先カメラ+固定カメラで、カメラとロボットのキャリブレーションが不要とうたう
  • カメラの位置・向きが変わっても動く → 頑丈な架台が要らず軽く小さく作れる
  • 同社の発表では、位置決め精度 0.02 mm(従来方式の目安 0.5 mm を超える)
  • 考え方の土台は「相対位置誤差でロボットを動かす」(→ 最後のコラム)

▶ チトセロボティクス ※ 精度は同社の発表値

活用事例:よくある使われ方

作業何を見るかポイント
穴へのピン挿入ピン先と穴最後の数 mm を IBVS で合わせる
コネクタ・ケーブルコネクタの形・マーカー柔らかい物はモデル通りに動かない → 見ながら直す
動く物の追従コンベア上の物フレームレートと遅れが勝負
実験器具の操作ピペット先端と容器器具の置き場所が毎回ずれても合う

どれも「置き場所や形が毎回少し違う」作業。その違いを画像で吸収する

コラム「絶対位置精度」は
本当に必要か?

コラムデカルトの見方:空間が先にある

空間の 1 点は、直交する座標系などを利用して、座標(X,Y,Z)で表現されます。デカルトの発想です。(中略)ロボットにも、この点を(X,Y,Z)と教えればロボットの指先をこの点に移動させることができます。

  • ロボットの「絶対位置精度」は、この空想した理想の座標系にどれだけ正しく行けるか
  • 見てから動く方式は、全部をこの座標系にそろえる努力の上に成り立つ

引用:川村貞夫「相対位置誤差でロボットを動かす」チトセロボティクス 技術コラム

コラムアリストテレスの見方:物が先にある

「リンゴは (3, 14, 28) cm にある」 座標系なし 「リンゴがテーブルの上に置かれている」

アリストテレスの場の捉え方は(中略)空間を定義する前に、対象物の存在から始まります。(中略)ロボットのシステムを構築する際に、空間(座標系)から考えるか、対象物から考えるかとなります。

引用:川村貞夫「相対位置誤差でロボットを動かす」チトセロボティクス 技術コラム

コラムキャリブレーションは理想を追う作業

現実の世界では、床が完全に水平ではなく、ロボットのリンクもわずかには撓み、固定されたはずのロボットも振動などでわずかにずれる、このような現実世界で、理想の空間を追い求めることがキャリブレーションとなります。

  • どれだけ合わせても、時間・温度・振動で少しずつずれていく
  • 精度を上げるほど、架台は重く、キャリブレーションは頻繁に

引用:川村貞夫「相対位置誤差でロボットを動かす」チトセロボティクス 技術コラム

コラム相対位置で動かす

我々が何かの作業をする場合に、まず初めに空間に注目するのではなく、対象物に注目します。(中略)その際、絶対座標系で表現する必要はなく、対象物と他の対象物の相対位置のみで表現して作業を達成できます。いわば、デカルト的ではなくアリストテレス的思考で十分となります。

  • ビジュアルフィードバックは、手先と相手のずれ(相対位置)だけを見て動く
  • 相手に対して合っているかどうかがすべて → そもそも「絶対精度」という概念が要らない

引用:川村貞夫「相対位置誤差でロボットを動かす」チトセロボティクス 技術コラム

コラム筆者の考え

  • 「位置精度」というと、自分(ロボット)を基準にした絶対の XYZ があるかのように考えがち
  • でも作業で大事なのは、相手に対して自分がずれているかどうかという相対の関係
  • 画像が合うまで動き続ければ、ロボットの精度はフィードバックの中に織り込まれ、結果として精度が出る
  • ロボットの精度が低い・キャリブレーションが難しい、というときこそビジョンフィードバックが効く
  • ただし「相手と手先が見えている」ことが前提。見えない区間は位置制御で

まとめ

  • ビジョンフィードバックは目として使えるだけでなく、精度も上げる
  • 画像が合うまで動き続けるので、キャリブ・ロボットの誤差は吸収される
  • IBVS:v = −λ L⁺ (s − s*)。最後の位置合わせに強い
  • 注意点はフレームレートと遅れ、見失い。指令は速度で(MoveIt Servo)
  • 「絶対位置」ではなく「相手との相対位置」で考える

ありがとうございました

← シリーズ一覧に戻る