2018年8月26日日曜日

人間の手を予測するじゃんけんシステムにロボットハンドを追加する

0. はじめに

本書では、9章および10章において、コンピュータと勝負できるじゃんけんシステムを作成しました。

過去の履歴をもとに人間の手を予測する部分をパーセプトロンで、画像処理と組み合わせて人間の現在の手を読み取る部分に三層ニューラルネットワークやディープラーニングの畳み込みニューラルネットワーク (CNN) を用いました。

このシステムでは、コンピュータの出す手はディスプレイ上の画像として表現されていました。本ページでは、コンピュータの出す手をロボットハンドに表現させる手法を紹介します。

実際にそのシステムが稼働している様子を示したのが下図です。左側に見えている黒い物体がロボットハンドです。後述しますが、ここでは市販のものを用いています。


本システムが動作している様子は以下の動画に示されています。


本書のあとがきで「本書をきっかけに機械学習の機能を組み込んだ電子工作の作品作りにチャレンジするのも面白いでしょう」と記しました。このシステムはまさにそのような例になっています。完成までの時間を短縮するために市販のロボットハンドを用いましたが、これを自作のものにすれば、より独自性の高い作品となるでしょう。

以下では、このロボットハンドを追加したじゃんけんシステムの概要と仕組みを解説します。

1. 本システムの構成(ロボットハンド編)

今回、なるべく簡単にシステムを実現するため、ロボットハンドは下図の市販のものとしました。


これは、アマゾンで購入した下記の商品です。
選ぶときに考慮したのは、全ての指を独立にプログラムにより制御できることです。このロボットは5本の指を5つのサーボモーターで曲げ伸ばしするだけなので、サーボモーターの制御により自由に動かせることから選択しました。

なお、このロボットハンドはものを掴めるわけではない上に高価なので、このじゃんけんシステムのためだけに購入するのは現実的ではないでしょう。5つのサーボモーターを用いて簡易的な手を自作するのが良いかもしれません。

参考までに、このロボットハンドを構造を記します。5つのサーボモーターは全て手首よりの下の部分にあり、シャフトで動力を伝えて上部の指を曲げ伸ばししています。


このロボットには第一関節、第二関節があり、サーボモーターの動きと連動する仕組みになっています。この仕組みをそのまま自作で再現するのはそれなりに大変ですが、第一関節と第二関節のない5本の棒を曲げるだけなら比較的簡単に実現できるかもしれません。

サーボモーターを用いた工作は「実例で学ぶRaspberry Pi電子工作」の6脚ロボットの作成で取り扱いましたので、興味のある方はご参考ください。

ただし、電子工作に触れるのは初めてという方は、入門編である「カラー図解 最新 Raspberry Piで学ぶ電子工作」から学び始めるのが無難でしょう。

本ページの以下の内容は、ある程度電子工作に慣れている方向けの解説となっておりますのでご了承ください。

2. 本システムの構成(回路編)

このロボットハンドを制御するための回路部分が下図に示されています。このうち、Raspberry Piとカメラモジュールは本書で解説済のものです。


5本の指を制御するために追加しているのが、上図の「PCA9685搭載サーボドライバー」です。これは「実例で学ぶRaspberry Pi電子工作」の8章で6脚ロボットを制御する際に用いたもので、複数のサーボモーターを制御するためのものです。

スイッチサイエンスさんで購入できる「PCA9685搭載16チャネル PWM/サーボ ドライバー (I2C接続)」を用いています。

Raspberry Piとの接続は下図のようになっています。これもまた「実例で学ぶRaspberry Pi電子工作」の8章で用いた接続とほぼ同じです。

なお、ロボットハンドに供給する電源としては秋月電子通商さんで購入できる「スイッチングACアダプター6V2A」を用いました。ロボットハンドに7.5Vのアダプタが付属するのですが、PCA9685搭載サーボドライバーに接続できる最大の電圧が6Vであるため変更しました。なお、アダプターを接続するソケットはロボットハンドに付属するものが利用できます。



3. 本システムの構成(プログラム編)

このシステムを動作させるためには、I2Cと呼ばれる通信方法を有効にする必要があります。メニューの「設定」→「Raspberry Piの設定」で設定アプリケーションを起動し、「インターフェイス」タブを選択し、「I2C」の項目を「有効」にしてください。

次に、このシステムを動作させるためのプログラム janken-robothand.py をダウンロードします。これは、ディープラーニング用である ml-10-09-janken-deep.py をベースに作成しました。

まずターミナルを起動してください。ml-10-09-janken-deep.py がユーザーpiのホームに直接存在する場合は、そのまま下記のコマンドを実行して janken-robothand.py をダウンロードしてください。
wget https://raw.githubusercontent.com/neuralassembly/raspi/master/janken-robothand.py
もし、ml-10-09-janken-deep.py が bluebacks ディレクトリ内にある場合は、上記コマンドを実行する前に「cd bluebacks」コマンドを実行してください。

ダウンロードが終わったら、下記のコマンドで実行します。これは ml-10-09-janken-deep.py の実行方法と同じですね。
python janken-robothand.py ml-hand-cnn.h5
うまくいけば、ロボットハンドつきのじゃんけんシステムが動作します。

なお、「本書のディープラーニングの演習をkeras + TensorFlowで実行する方法」をもとにkerasのバックエンドをTensorFlowにしている方は、上記プログラムは動作しません。TensorFlow用のファイルを下記でダウンロードし、
wget https://raw.githubusercontent.com/neuralassembly/raspi/master/janken-robothand-tf.py
下記コマンドで実行するようにしてください。
python janken-robothand-tf.py ml-hand-cnn.h5

さて、本ページと同じ市販のロボットハンドを用いる場合は上記のプログラムの実行で良いのですが、ロボットハンドを自作した場合は調整が必要です。以下ではそのためのコメントをいくつか記します。

まず、ロボットハンドを動かすための命令は janken-robothand.py 内の下記の部分(guchokipa_servo関数)です。
def guchokipa_servo(i):
    if i==0: #グーのとき
        # 順に、親指~小指に対応するサーボの値。
        # 2番目の引数は常に0。範囲は143~410程度で276がゼロ点。
        # 以下同様。
        setPCA9685Duty(0, 0, 350)
        sleep(0.01)
        setPCA9685Duty(1, 0, 220)
        sleep(0.01)
        setPCA9685Duty(2, 0, 240)
        sleep(0.01)
        setPCA9685Duty(3, 0, 220)
        sleep(0.01)
        setPCA9685Duty(4, 0, 350)
    elif i==1: #チョキのとき
        setPCA9685Duty(0, 0, 350)
        sleep(0.01)
        setPCA9685Duty(1, 0, 380)
        sleep(0.01)
        setPCA9685Duty(2, 0, 360)
        sleep(0.01)
        setPCA9685Duty(3, 0, 220)
        sleep(0.01)
        setPCA9685Duty(4, 0, 350)
    elif  i==2: #パーのとき
        setPCA9685Duty(0, 0, 190)
        sleep(0.01)
        setPCA9685Duty(1, 0, 380)
        sleep(0.01)
        setPCA9685Duty(2, 0, 360)
        sleep(0.01)
        setPCA9685Duty(3, 0, 360)
        sleep(0.01)
        setPCA9685Duty(4, 0, 210)
引数として与えるiが0(グー)、1(チョキ)、2(パー)のときの、5つのサーボモーターに与える数値が定められています。 例えば、グー(i=0)のとき、親指から小指のサーボモーターに与えられる数値は、順に(350, 220, 240, 220, 350)となっています。

コメントにありますように、ここに与える数値は143~410程度で276がサーボモーターのゼロ点となっています。この数値は、ロボットハンドのつくり方によってまったく異なります。ですから、ロボットハンドごとに値を変更する必要があります。

しかし、じゃんけんシステムが動作しているときにこの数値を変更するのは困難です。そこで、数値調整のためのテストプログラム  janken-robothand-test.py を作成しました。下記のコマンドを実行してダウンロードしましょう。
wget https://raw.githubusercontent.com/neuralassembly/raspi/master/janken-robothand-test.py
このプログラムの実行方法は下記の通りです。
python janken-robothand-test.py 0
python janken-robothand-test.py 1
python janken-robothand-test.py 2
1つめの命令を実行すると、ロボットハンドは「グー」の形で静止します。2つ目なら「チョキ」、3つ目なら「パー」です。

このプログラム janken-robothand-test.py 内にも上と同じguchokipa_servo関数は存在します。そこで、 janken-robothand-test.py の guchokipa_servo関数を編集して「グー」、「チョキ」、「パー」の形に対応するサーボモーター用の数値を確定し、その数値の変更を janken-robothand.py 内のguchokipa_servo関数にも適用すれば良いのです。

あともう一点注意すべき箇所があります。 janken-robothand.py に下記の部分があります。
(中略)
    # "ぽん!"のタイミングでサーボが動くようタイミング調整
    sleep(2)
    # サーボを動かす
    guchokipa_servo(comp_choice)

    # サーボの動きはじめと手の描画のタイミング調整
    sleep(0.2)
(中略)
ここにある「sleep(2)」と「sleep(0.2)」は待ち時間を設定している部分ですが、これもロボットハンドにより調整が必要だろうと思います。

一つ目の「sleep(2)」は「じゃんけんぽん」という掛け声が始まってから何秒後にサーボモーターが動き始めるか、を設定しています。これを適切に調整して「ぽん!」の掛け声と同時にロボットハンドが動き始めるようにします。

二つ目の「sleep(0.2)」は、サーボモーターが動き始めてから何秒後に人間の手を確定させるか、を調整しています。この値が小さいと、まだ人間が手を出し切る前に手を読み取ってしまうので、誤認識が多くなるでしょう。

4. おわりに

以上、ロボットハンドを用いたじゃんけんシステムについて紹介しました。実際にこのシステムを作ろうとすると、高価なロボットハンドを購入するか、あるいは自作するかの選択となりますが、いずれにせよハードルは低くはありません。

しかし、動画を見ることで「機械学習と電子工作を組み合わせることで何ができるか」のイメージはつかめたのではないかと思います。

皆さんも、機械学習と電子工作を組み合わてどのようなシステムが可能か考えてみると楽しいでしょう。

2 件のコメント:

  1.  ディープラーニングを利用した mediapipe の手認識は非常に興味深い内容でした。
     「人間の手を予測するじゃんけんシステムにロボットハンドを追加する」の内容をRaspberry Pi 5 と mediapipeで実現するプログラムも公開してもらえないでしょうか。よろしくお願いいたします。

    返信削除
  2. 本ページに新規のコンテンツを追加するときの条件として、
    「多くの人が体験でき、楽しめること」を設けております。
    (これは、本ページが書籍のサポートページであるためです)

    最近追加した以下の2ページは、そういう例になっております。
    (Pi 5 とカメラがあれば体験できます)

    Raspberry Pi 5 でリアルタイムな姿勢推定と物体検出
    https://mlbb1.blogspot.com/2024/02/raspberry-pi-5.html
    Raspberry Pi 5 と mediapipe で AI とじゃんけん勝負してみた
    https://mlbb1.blogspot.com/2024/02/raspberry-pi-5-mediapipe-ai.html

    それに対し、本ページの内容は、既にAmazonでロボットハンドの入手はできず、
    上記の条件を満たさなくなっております。

    そのため、本ページに新規の内容を追加することは難しいです。ご容赦ください。

    よろしくお願いします。

    返信削除