Pythonロボティクスコース レッスン 30

Pythonロボティクスコース レッスン 30

テーマ.8-1 複数のモーターを使用した多軸ロボットアームの製作

複数のモーターを使用してロボットアームを製作しよう!

このレッスンで学ぶこと

テーマ8では、工場で使用されているロボットアームの仕組みを学び、その簡単なモデルを製作して、制御プログラムの作成に取り組みます。

このレッスンでは、複数のモーターを組み合わせて、「3軸ロボットアーム」を製作します。また、その操作を行うために、独自のモジュールとクラスを定義して、簡単な運搬作業を行うプログラムを作成します。

ロボットアームとは

ロボットアームは、人の腕や手のように多数の関節を持つ産業用ロボットの一種です。ロボットアームにはモーターなどの複数のアクチュエータ(駆動部品)が使われており、それらを同時に制御して様々な作業を行います。

2. 1 ロボットアームの用途

ロボットアームは様々な用途で使われており、工場の製造ラインで行う「製品の運搬」や「部品の組み立て」以外にも、「塗装」や「溶接」などの工程がロボットアームで既に自動化されています。

2. 2 ロボットアームの種類

ロボットアームは関節の数や、関節の取り付け向きによっていくつかの種類に分かれています。下の表に、その代表的なロボットアームをまとめています。

サーボモーターの非同期制御と同期制御

今回製作するロボットアームでは、複数の関節を同時に動かして、ものを持ち上げたり、運んだりする動作を行います。このように複数の関節をモーターを使って同時に動かす場合、非同期で制御する方法と同期して制御する方法があります。

3. 1 非同期制御と同期制御のちがい

まずは下の動画を見て、それぞれの制御方法でモーターの動きにどのようなちがいがあるのかを確認しましょう。

非同期制御の場合、回転前と回転後の角度の差が小さいモーターほど、早く回転が終わり停止しています。一方で同期制御の場合は、回転前と回転後の角度の差の大小に関係なく、すべてのモータが同じタイミングで動き出し、そして停止しています。

このような違いがあるのは、それぞれ次のように制御しているためです。

  • 非同期制御
    すべてのモーターをばらばらに制御する。
  • 同期制御
    同じタイミングで回転し終えるように、それぞれのモーターの速さを調整して制御する。

今回は、「同期制御」を使ってロボットアームの関節を制御します。

3. 2 同期制御のプログラム作成

同期制御では、開始と終了のタイミングを合わせるために、それぞれのモーターに対して個別に回転の速さを決めます。

この速さを決めるためには、「回転後の角度」だけでなく、「回転前の(現在の)角度」も必要です。

しかし、Servomotorクラスには現在の角度を知るためのプロパティやメソッドが用意されていません。そこで、まずはServomotorクラスを継承し、新たに角度を記録するためのプロパティや現在の角度を取得するメソッドを追加した独自クラスを作成しましょう。

■ 独自のサーボモータークラスの定義

MyServomotorという名前で独自クラスを定義します。このクラスには以下のプロパティとメソッドを追加し、さらにスーパークラスのメソッドもオーバーライドします。

【 追加するプロパティとメソッド 】
プロパティ名またはメソッド名内容
angleプロパティ角度を記録するための変数
get_angle()メソッド現在の角度を取得するメソッド
【 オーバーライドするメソッド 】
メソッド名変更内容
__init__()メソッドangleプロパティの初期値を90度に設定し、その角度まで回転する
set_angle()メソッド回転後の角度をangleプロパティに記録する

では、以下のコードを参考にして、新しいプログラムファイルにMyServomotorクラスを書きましょう。

■ 同期制御を行う関数の定義

「回転前の角度」を取得できるクラスを定義したので、このクラスを前提として複数のサーボモーターを同期制御する関数をsyncRotateServos()という名前で用意します。

※ syncは、「同期」を表す「synchronous」を省略した表記です。

syncRotateServos()関数には位置引数として「回転にかける時間」と、可変長な位置引数として「MyServomotorクラスのインスタンスと回転後の角度のタプル」を渡します。

追加【16行目、17行目】

つまり、この関数は次のようにして使います。

関数の定義に戻りましょう。まずは先頭で、各サーボモーターの回転の速度を求めます。回転の速度を求める式は次の通りです。

回転の速度 = (回転後の角度 - 回転前の角度)/ 回転にかける時間

求めた速度は、MyServomotorクラスの各インスタンスのID値をキーとして、辞書に格納しましょう。

追加【17行目~22行目】

それぞれのサーボモーターの回転速度(1ミリ秒あたりの回転角度)が求められたので、それに従って1ミリ秒おきに少しずつ回転させます。また、時間の間隔をあけるためにtimeモジュールを使うので、プログラムの先頭でインポートしておきましょう。これで関数の完成です。

【 サンプルコード 3-2-1 】
追加【1行目、25~30行目】

■ プログラムファイルのモジュール化

折角なので、【 サンプルコード 3-2-1 】をモジュールとして使えるようにしてみましょう。「myservo(.py)」という名前を付けてPCに保存し、Studuino:bit内にそのファイルをコピーしてください。

■ 同期制御の動作確認

新たに作成したモジュールをテストしましょう。下の図のように、拡張ボードのP13P14の端子にサーボモーターを接続して、ステーに固定してください。

新しく、以下のようなプログラムを作成し、2つのサーボモーターが同期して回転することを確かめましょう。

【 サンプルコード 3-2-2 】

3軸ロボットアームの組立て

ここからの学習には、3つの関節軸をもつロボットアームを使います。以下の組立説明書を確認して、ロボットアームを組み立てましょう。

4. 1 組み立てに必要なパーツ

【 パーツ一覧 】
  • Studuino:bit×1
  • ロボット拡張ユニット×1
  • 電池ボックス×1
  • DCモーター×1
  • サーボモーター×2
  • ブロック基本四角(白)×2
  • ブロック基本四角(グレー)×2
  • ブロック三角(グレー)×1
  • ブロックハーフA(グレー)×4
  • ブロックハーフB(グレー)×2
  • ブロックハーフB(黒)×2
  • ブロックハーフB(赤)×2
  • ブロックハーフC(白)×11
  • ブロックハーフD(白)×8
  • ステー×7
  • ギヤ大×2
  • ギヤ用タイヤゴム×2
  • 回転軸×4
【 アーテックブロックの形状 】

4. 2 組立説明書

以下のリンク先から組立説明書を確認しましょう。

ロボットアームの組立説明書ここまでできたらクリック

3軸ロボットアームの制御プログラムの作成

組立てたロボットアームは、「腕」「手」「ボディ」の3つの関節を持っています。

それぞれの関節の軸は次のように動かします。

  • 腕の動き(サーボモーター:P13)
  • 手の動き(サーボモーター:P14)
  • ボディの動き(DCモーター:M1)

一般的なロボットアームには4つ以上の軸があります。ただし、組み立てたロボットのアームのように3つしか軸を持たない場合でも、「つかむ/はなす」「持ち上げる/下ろす」「運ぶ」の基本的な動作を行うことはできます。

5. 1 ロボットアームの制御クラスの定義

では、チャプター3で作成したmyservo(.py)モジュールを利用してロボットアームを制御するためのクラスRobotArmを定義しましょう。このクラスには次のプロパティとメソッドを用意します。

【 RobotArmクラスのプロパティ 】
プロパティ名役割
arm腕の関節を動かすサーボモーターを制御するためのオブジェクトを格納
hand手の関節を動かすサーボモーターを制御するためのオブジェクトを格納
bodyボディの関節を動かすDCモーターを制御するためのオブジェクトを格納
【 RobotArmクラスのメソッド 】
メソッド名内容
__init__()各プロパティの初期値を設定するコンストラクタ
pick()腕と手を制御して、ものを持ち上げる動作を行うメソッド
place()腕と手を制御して、持ち上げたものを置く動作を行うメソッド
rotate()ボディを制御して、回転する動作を行うメソッド
stop()回転中のボディを停止するメソッド

それでは順番にコードを書いていきましょう。

■ 各プロパティと「init()メソッド」の定義

はじめに、RobotArmクラスを宣言して、各プロパティを準備する__init__()メソッドを定義します。サーボモーターやDCモーターの接続先の端子名をキーワード引数として受け取り、インスタンスを作成して変数に格納しましょう。

■ ものを持ち上げる「pick()メソッド」の定義

今回は持ち上げる対象をブロックにします。ブロックを持ち上げるときは、次の順番でサーボモーターを動かします。

  1. 手(hand)を開きながら腕(arm)を下げる
  2. 手(hand)を閉じてブロックをつかむ
  3. 腕(arm)を上げてブロックを持ち上げる

この一連の動きをコードで書くと次のようになります。1つしかサーボモーターを動かさない場合でも、作成したsyncRotateServos()関数を使うことで、回転の速さを調整できます。

※サーボモーターに指定する角度や回転にかける時間は、あとで動作を確認しながら調整します。
追加【10行目~13行目】

では動作テスト用に、以下のコードを追加しましょう。プログラムを実行して、用意したブロックをつかんで持ち上げることができるか確認しましょう。もし、ブロックをつかめない場合は、コードの12行目で手のサーボモーターの角度を調整してください。

追加【16行目~17行目】

■ 持ち上げたものを置く「place()メソッド」の定義

持ち上げたブロックを置くときは、次の順番でサーボモーターを動かします。

  1. 腕(arm)を下げてブロックを置く
  2. 手(hand)を開いてブロックをはなす
  3. 手(hand)を閉じながら腕(arm)を上げる

この一連の動きをコードで書くと次のようになります。pick()メソッドを作成したときと同じく、テスト用のコードを追加して、つかんだブロックが問題なく置けることを確認しましょう。

追加【 16行目~19行目、24行目 】

■ ボディの回転を制御する「rotate()メソッド」と「stop()メソッド」の定義

ボディの関節にはDCモーターを使用しているため、サーボモーターのときとは違い、「時間」と「向き」と「速さ」で回転を制御します。

そのため、この関数は引数として、「時間duration」と「速さspeed」と「向きdirection」の3つを受け取ります。

またこれらの引数は、値の指定を省略できるように、デフォルト引数としてそれぞれ次のようにデフォルト値を設定します。

def rotate(self, duration=-1, speed=50, direction="cw"):

durationのデフォルト値を「-1」としているのは、回転時間を決めずに制御できるようにするためです。つまり、値の指定を省略した場合は、停止命令があるまでずっと回転を続けるメソッドとして使用できるようにします。

そして、その停止命令を行うためのメソッドもstop()という名前で用意しておきましょう。

追加【4行目、21行目~29行目、31行目、32行目】

最後に、動作テスト用に1行コードを追加してプログラムを実行しましょう。持ち上げたブロックを、ボディを回転して別の場所に置くことができれば成功です。

追加【38行目】

■ RobotArmクラスの定義

完成したRobotArmクラスの定義は以下のようになります。次以降のレッスンでもこのクラスを使用していきます。

【 サンプルコード 5-1-1 】

課題:複数のブロックを運搬するプログラムの作成

前のチャプターで作成したRobotArmクラスを使用して、ロボットアームで3つのブロックを指定された場所へ運搬する課題に取り組みます。

【 課題の内容 】
  • 黒、緑、黄の3つのブロックを用意して、それぞれ下のように配置します。そしてこれらのブロックを、それぞれ同じ色の円までロボットアームで運びます。(※ブロックはどの順番に運んでも構いません。)
  • ロボットアームは、中央の大きな2つの円に合わせて設置します。
  • ロボットアームのボディの向きは、小さな灰色の円に合わせます。

6. 1 ロボットアーム用フィールドの準備

この課題では、キットに付属している以下のフィールドを使用します。

もし紛失してしまった場合は、以下のリンク先からデータをダウンロードして、A3用紙にカラー印刷してください。

ロボットアーム用フィールド_A3

A3用紙に印刷できない場合は、以下のデータをA4用紙2枚に印刷して、切り取り線に沿って切り離し、2枚をテープ等で裏から留めてください。

ロボットアーム用フィールド_A4

6. 2 プログラムの作成例

例えば、ブロックを「黒 ⇒ 緑 ⇒ 黄」の順番に運ぶ場合、ロボットアームは次の手順で動かします。

【 ロボットアームの動作手順 】
  1. 黒ブロックをつかんで持ち上げる(pick()
  2. 時計回りにボディを回転して黒の円まで移動(rotate()
  3. 黒ブロックを置く(place()
  4. 反時計回りにボディを回転して赤の円まで移動(rotate()
  5. 緑ブロックをつかんで持ち上げる(pick()
  6. 時計回りにボディを回転して緑の円まで移動(rotate()
  7. 緑ブロックを置く(place()
  8. 時計回りにボディを回転して青の円まで移動(rotate()
  9. 黄ブロックをつかんで持ち上げる(pick()
  10. 時計回りにボディを回転して黄の円まで移動(rotate()
  11. 黄ブロックを置く(place()

この手順を踏まえると、ボディを回転させる時間は調整が必要ですが、おおよそ以下のようなコードになります。

【 サンプルコード 6-3-1 】
※36行目~47行目がこの課題のために書いたコードになります。

おわりに

7. 1 このレッスンのまとめ

このレッスンでは、サーボモーターの同期制御と非同期制御について学び、3つのモーターを組み合わせたロボットアームの製作を行いました。また、その制御のために、独自のクラスを定義し、簡単な運搬作業を行う課題に取り組みました。

前のテーマで学習した車型ロボットや今回取り組んだロボットアームは、どちらも広く利用されているスタンダードなロボットであり、ロボット工学を学ぶ良い教材として、専門学校や大学でも使われています。

このレッスンでは、そのすべてに触れることはできませんが、将来そういった進路を考えている人は、インターネットや図書館などを利用して、ぜひ最先端のロボット技術について調べてみてください。

7. 2 次のレッスンについて

次のレッスンでは、今回組立てたロボットアームに赤外線フォトリフレクタを追加し、フィールド上の位置を検出して正確に移動する機能を開発します。

TOP