はじめに
こんにちは、しがない高校生をしているBasalteと申します。
今回は画像認識で手をトラッキングし、ロボットアームをテレオペレーションするデモを解説します。
該当の動画はこちらになります。
ハンドトラッキングからロボットアームのテレオペ! pic.twitter.com/Hdm2sjRluT
— basalte(ばざると) (@basalte1199) September 20, 2024
システム構成
こちらのシステムのハードウェアは
RealSense + Openmanipulator-X
の二つで構成されています。
ソフトウェアはROS2 Humble上で構成されています。
realsense-ros + mediapipe + 逆運動学(自作) + DynamixelSDK
のような構成になっており、この順番にデータが流れていきます。また、使用しているROS2 ノードの数と一致していて、このノード間の通信はtopic通信を使用しています。
realsense-ros
使用しているrealsense-rosのリポジトリはこちらにあります。
RealSenseからのimageとdepthを同時に受け取ることができるrgbd topicを使用しています。詳細はこちらの神記事をご覧ください。
mediapipe
RealSenseから出てきたデータから手を認識するためにmediapipeという手のランドマークをたくさん認識できるライブラリを使用しています。処理も特段重いわけではなく使い勝手は良いと感じています。
ここでは大きく二つの計算をしています。
・手のboundingboxの面積からGripperの幅を計算
・手の3次元座標からロボットアームのEndEffectorの目標座標を計算
手のboundingboxを出す機能はないので、認識結果の20個ほどあるランドマークの中からx,y最大値とx,y最小値を出すコードを書いています。
この結果からカメラからの距離と合わせてcm単位の四方の辺の長さを計算し、その面積をGripperの幅に線形分布させています。一応Dゲインを入れていますが、あまり振動は治りませんでした。
また手の三次元座標はカメラの視野角とdepth情報があれば求めることができるため、depthを安定させるために複数のランドマークから取るなど工夫をしました。
その情報を手の初期位置との差分をとって、ロボットアームの原点からの座標に変換して出力しています。
tf2などは使用してないです。(わざわざ座標系を合わせるメリットはないので)
逆運動学(自作)
以下のように元々物体をPickするために逆運動学を解くコードはできていたので、入力に合わせて対応させるだけで動きました。
コントローラーで逆運動学! pic.twitter.com/eZObrplVuI
— basalte(ばざると) (@basalte1199) September 20, 2024
Mediapipeを実行しているノードから送られてきた目標座標を逆運動学を実行する関数に入力して各モーターの目標角度を出力しています。
Mediapipeの実行周期に依存しており、また計算に時間がかかってしまっていてあまり制御周期を出せていないため少し動作がカクついているように見えます。こちらは今後改善したいです。
またGripperの角度も固定していますが、今後手の角度を取得してそちらも目標座標として送る情報に含めたいです。
DynamixelSDKは送られてきた目標角度をモーターに入力しているだけなので、特に書くことはありません。
まとめ
今回はハンドトラッキングからロボットアームを動かすデモについて解説しました。
今回作成したプログラムは今後公開する予定がありますので、更新をお待ちください。
また説明に不備があったり不足しているなどしていた場合はコメントなどで教えていただけると幸いです。ありがとうございました。