１万円台でＡＩ搭載ロボットアームを自作

6自由度ロボットアームDIYキットが8000円でAmazonで売っていたので、
これを使ってＡＩ搭載ロボットアームを自作しました。

<br/>
<iframe width="560" height="315" src="https://www.youtube.com/embed/VN-0e4llf3Y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br/>
<br/>

Raspberry Pi Picoからサーボモーター ドライバーに指令を送ってモーターを制御しています。

アームの軸の角度計算やAI(物体検出)は、Windowsパソコンでしています。

パソコンからRaspberry Pi Picoへは、USB仮想COMで指令を送っています。

このシステムの特徴は
* 材料は合計で１万円台で、全部Amazonで買えます。
* ロボットアームの組み立ては、ドライバーとラジオペンチでできます。
* 配線はピンを穴に差し込むだけで、半田付けは必要ありません。
* パソコンに接続してPythonで動かせます。

この記事ではAIで物体検出をした位置に、ロボットアームを移動させるまでの大まかな仕組みを説明します。

自作の具体的な手順は以下のサイトをご覧ください。
[uroa.jp](https://uroa.jp/)


# 部品一覧

| 名前 | 価格 | 画像 |
|:-:|:-:|:-:|
| 6自由度ロボットアームDIYキット | 8000円 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/4474f358-8f99-3efd-aa53-3e2ac47391ee.png" width="200"> |
| 20kg高トルク サーボモーター(※1) | 1800円 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/144eaeed-20ab-4cb5-c68a-7d81e8850796.png" width="200"> |
| サーボモーター ドライバー | 1000円 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/624b6523-5ed6-08b4-be95-778c827f804b.png" width="200"> |
| Raspberry Pi Picoスターターキット | 2000円 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/1651ab91-688e-d17a-e0b7-4999668b8d40.png" width="200"> |
| 電源アダプター (6V 3A) | 1900円 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/2c89c764-ab11-5301-57a7-0a61875aefb3.png" width="200"> |
| ウェブカメラ (1080P) | 4000円 | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/a6054ea8-04d7-6295-c2a9-c1e248b52ea8.png" width="200"> |

(※1) アームの根元から2番目のモーターは高い負荷がかかるので、20kg高トルク サーボモーターに換装しました。

時期により価格は変動しますが、全部で１万９千円くらいです。

# AIでロボットアームを動かすまでの手順

1. [配線](#配線)
1. [ソフトのセットアップ](#ソフトのセットアップ)
1. [モーターの可動範囲の確認](#モーターの可動範囲の確認)
1. [ロボットアームの組み立て](#ロボットアームの組み立て)
1. [軸の角度の調整](#軸の角度の調整)
1. [カメラのキャリブレーション](#カメラのキャリブレーション)
1. [アームの手先の位置の検出](#アームの手先の位置の検出)
1. [物体検出](#物体検出)
1. [物体検出した位置にアームを移動](#物体検出した位置にアームを移動)

以下で各手順を説明します。

# 配線

Raspberry Pi Picoとサーボモーター ドライバーは４本の線で接続します。

サーボモーター ドライバーには6Vの電源を供給します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/376119cc-57a7-7ac8-fb59-ed2c805bb549.png" width="800">  
<br/><br/>  
モーターの茶(GND)、赤(V+)、オレンジ(PWM)の線をサーボモーター ドライバーの黒・赤・黄の端子に接続します。(左図)
モーターの線の色が黒(GND)、赤(V+)、白(PWM)の場合もあります。(右図)

|  |  |
|:-:|:-:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/ee527770-9696-6610-05d6-a0a7999dee07.png" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/1a07432c-6567-ff0c-f8c8-fe9c932f019a.png" width="200" /> |

<br/>

モーターはアームの根元から手先に向かって J1, J2, J3, J4, J5, J6 と呼びます。
サーボモーター ドライバーのピンをブレッドボードに挿し、下から順にJ1～J6のモーターを接続します。
J2のモーターは高い負荷がかかるので、20kg高トルク サーボモーターに換装します。

|  |  |
|:-:|:-:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/79f495da-741a-978f-0556-73f1dca0ae4c.png" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/fbe422ac-ecfd-b316-e4f2-7bfa553c2969.png" width="300" /> |
<br/>
配線をすべて終えるとこんな感じです。

| サーボドライバの表側 | サーボドライバの裏側 |
|:-:|:-:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/065b8629-a44f-2562-fb4b-66a3b0c0d69c.png" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/12946f9c-ef0b-fc57-78c6-78c51bfa3acd.png" width="400" /> |

<br/>
※ 一部のサーボドライバでは下図のようにV+のピンを接続する必要があります。<br/>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/c9f868f7-1568-f0e8-6f18-c814788672d9.png" width="150" />

# ソフトのセットアップ

Raspberry Pi PicoはMicroPythonのアプリで制御します。
Raspberry Pi Picoにアプリを書き込むにはThonnyというソフトを使います。
セットアップの内容は以下になります。

1. GitHubからアプリをクローン
1. Pythonのパッケージのインストール
1. MicroPythonのダウンロード
1. Thonnyのインストール
1. MicroPythonのアプリをRaspberry Pi Picoに書き込み

詳細は [uroa.jp](https://uroa.jp/) をご覧ください。

# モーターの可動範囲の確認

配線とソフトのセットアップが終わったらパソコンからサーボモーターを動かしてみます。

|  |  |
|:-:|:-:|
| <img src="https://uroa.jp/_images/angle.gif" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/d176e42c-38c0-4c5a-ca82-4d1fc825a873.png" width="200" /> |

ロボットアームを組み立てるときは、アームが可動範囲を中心に動作するように気をつける必要があります。

# ロボットアームの組み立て

組み立てはドライバーとラジオペンチでできます。
動画を作りましたので参考にしてください。

<br/>
<iframe width="560" height="315" src="https://www.youtube.com/embed/eXKoVbLzFlU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


# 軸の角度の調整

サーボモーターへの角度の指令値と軸の角度との対応付けをします。
アームの根元から順に軸を J1, J2, J3, J4, J5, J6 と言います。
以下の写真ではJ2, J3, J4の軸の角度は0度です。

|  |  |
|:-:|:-:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/3e4c9c94-c5e7-1e3d-c0b1-605e7154ded7.png" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/b3f82f6b-0831-05d1-9a5e-1ac78ac9fe4d.png" width="300" /> |

0ボタンをクリックして、0度の時のサーボモーターの角度を記憶しておきます。

以下の写真ではJ2の軸の角度は-90度です。

|  |  |
|:-:|:-:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/f23162e1-8e24-32f0-6ff4-41a9392279ee.png" width="400" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/299592e2-4ccb-180b-0ad6-63c5ecd33784.png" width="300" /> |

-90ボタンをクリックして、-90度の時のサーボモーターの角度を記憶しておきます。

その他の軸も同様に基準となる軸の角度でのサーボモーターの角度を対応付けをさせます。

軸の角度と、アームの手先の位置と傾きは、以下のように一方から他方を求められる関係にあります。

<dl>
  <dt>順運動学</dt>
  <dd>軸の角度から手先の位置と傾きを求める。</dd>
  <dt>逆運動学</dt>
  <dd>手先の位置と傾きから軸の角度を求める。</dd>
</dl>

# カメラのキャリブレーション

このシステムには３種類の座標系があります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/f8b30e83-6c72-4c96-fe9e-9e38bf75241e.png" width="800" />

カメラのキャリブレーションではカメラ座標系とスクリーン座標系の設定をします。

<dl>
  <dt>カメラ座標系</dt>
  <dd>カメラ位置を原点とし、視線の方向がZ軸の座標系です。</dd>
  <dt>スクリーン座標系</dt>
  <dd>カメラで撮影した画像の座標系です。<br/>
   画像の左上が原点で、右方向がX軸、下方向がY軸です。</dd>
  <dt>ロボット座標系</dt>
  <dd>ロボットの土台を原点とする座標系です。<br/>
  ロボットに向かって手前がX軸、右方向がY軸、上方向がZ軸です。</dd>
</dl>

キャリブレーションにはチェッカーボードのような板を使います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/ace5eb84-a51f-4753-b9cd-4648d4151f00.png" width="600" />   

この板を様々な角度からカメラで撮影して、キャリブレーションをします。
   
# アームの手先の位置の検出
  
手先の位置の検出のために、OpenCVの **ArUcoマーカー** を使います。
ハンドの手先に２個と、ロボットの土台の板の上に３個のマーカーをつけています。
手先の2個のマーカーの中点が手先の位置になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/eda7783e-2cc3-4eef-b3fa-0eca77720b4b.png" width="500" />

カメラでマーカーを撮影すると、マーカーのカメラ座標とスクリーン座標が分かります。

板の上の３個のマーカーから板の平面の方程式が求まります。
平面の方程式から平面(板)と手先の距離が計算できます。
手先が板に激突しないためと、板の上の物体をつかむために、板と手先の距離は重要です。
   
# 物体検出

アプリにはお菓子の物体検出をするAIが入っています。
図の青い点はAIが検出した物体の位置です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/c3dbac54-afb5-4996-9bc2-cd8bf4d9ee37.png" width="300" />

# 物体検出した位置にアームを移動

AIが物体検出した座標はスクリーン座標です。
物体の位置にロボットアームを移動するには、スクリーン座標からロボット座標に変換する必要があります。

ロボット座標を指定して手先を動かすと、その位置での手先のカメラ座標とスクリーン座標が分かります。
下の写真のように複数の位置に手先を移動させると、ロボット座標とスクリーン座標のデータ対が作れます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118740/9414f615-8d1e-e643-eb55-3a6ccab87b1a.png" width="500" />

このデータ対を使って、スクリーン座標からロボット座標への変換器が作れます。

# まとめ

以上で、AIで検出した物体の位置に、ロボットアームを移動させる仕組みができました。

まとめると以下になります。

１. 物体検出のAIを使い物体のスクリーン座標を得る。

２. スクリーン座標からロボット座標へ変換する。

３. ロボット座標から軸の角度を逆運動学で求める。

４. 軸の角度からサーボモーターへの指令値を求める。

５. パソコンからRaspberry Pi Picoへ、USB仮想COMを使って指令値を送る。

６. Raspberry Pi Picoの中のMicroPythonのアプリがモーター ドライバーへ指令を送る。

- - -

わたし自身はアマチュア電子工作レベルで、電気や機械のプロではないです。
まちがいなどがあれば、コメント欄に書かれるかTwitterに連絡をお願いします。
Twitterでアプリの更新のお知らせもしていきます。
[![Twitter_Logo_White_On_Blue20.png](https://qiita-image-store.s3.amazonaws.com/0/118740/af910f48-8c6b-27cb-7951-eaa6e97afa87.png)](https://twitter.com/teatime77)  [teatime77](https://twitter.com/teatime77)

**ここまで読んでいただき、ありがとうございました。**