象とプログラミング ~レゴマインドストームEV3~ | そう備忘録

象とプログラミング ~レゴマインドストームEV3~

レゴマインドストームEV3の象(Elephant)

教育用レゴマインドストームEV3の拡張セットで象(Elephant)を組み立ててみた。

象は基本セットの他に拡張セットが必要で、値段もするので躊躇していたのだけれども拡張セットを購入すると象の他にもスピナー工場やタンクボットなどを組み立てることが出来るので思い切って購入してみた。

象は1つのLモーターで4つの足を動かして前進、後退ができる。

四足歩行の具体的な仕組みは後ほど書くとして両肩を揺らして左右にバランスをとりながらの、いかにも象が歩行している感がでていて秀逸な機構だった。

また秀逸と言えば鼻の構造も素晴らしい。

鼻を持ち上げたり(象が咆哮するときによく見るシーン)、内側に丸めて物を持ち上げる(材木を運ぶ時によく見るシーン)ことができて実際の鼻の動きをかなりの精度で再現している。

これを設計できるレゴビルダーは本当にすごいと思うし尊敬する。

また足と鼻の他には頭全体を上下に動かすことができる。

Mモーターとラックギア(棒状のギア)の組み合わせで頭を上げながら鼻を持ち上げながらの象の咆哮(音声ファイルの再生)は象を作ったらやってみたい、ある意味お約束の動きだと思う。

象 レゴマインドストームEV3

 

2019年1月23日 追記

象がバーベルを持ち上げて歩く動画を追加した

象(Elephant)の組み立て動画

拡張セットで象を組み立てた時の動画。

駆動部・センサー類の説明

四足歩行、頭の上下、鼻の動きについての説明。

四足歩行

Lモーター(ポートA)

象の足は1つのLモーターで四足を動かしている

象の足用のLモーター

また足の構造は以下の様になっている。

足全体の構造

中心にある小さいギアがLモーターで反時計回りに回転すると両側のギアは時計回りに回転する

支点は1~4の4ヶ所

1と3、1と4は白い曲線状のブロックで接続されている

  • 1はギアの円周に沿って円運動を行う
  • 2は固定されている
  • 3と4は1の動きに合わせて2を中心とした円弧運動をする

この時、4が一番左にあるのは1が時計の8時ぐらいの位置にある時で、逆に一番右にあるのは1が2時ぐらいの位置にある時となる

左前足下の動きを簡易的に表した図

同様に3が一番左にあるのは1が時計の10時ぐらいの位置にある時で、逆に一番右にあるときは1が4時ぐらいの位置にある時になる

1が時計回転をしている場合、先に4が左端に達して少し遅れて3が左端に達する

詳しくは動画を見て欲しいがこの若干のズレ(遅れ)によって左前足はオールを漕ぐ様な動作をして前進する

左後ろ足も前足とほぼ同じ様な動きをするが違うのはタイミング

前足が後方にある時は後ろ足は前方、逆に前足が前方にある時は後ろ足は後方にある

左側の足を動きを簡易的に表した図

また右側の足も同様の動きをするのだが対角線にある左前と右後ろ、左後ろと右前は同じ動きをする※

※左前足が前の時は右後ろ足も前

象の足

こうして4足で交互に漕ぐような動きをして象は前進する

またモーターを逆回転させると象の足は逆に漕ぐような動きをして後退する

頭の上下運動

Mモーター(ポートD)

象の頭部は1を中心に回転する事で頭を持ち上げることができる

象の頭部の構造

Mモータの回転をラックギア(棒状のギア)を使って前後運動に変換して2、3を前後(写真上では左右)に動かして頭部を持ち上げる

Mモータ周辺の機構

Mモータの構造

Mモータの回転運動をaの部分の前後(写真上では左右)運動に変換する

象の頭の動きの簡易図

 

頭の動きとカラーセンサー(ポート4)頭部を持ち上げると赤いブロックがカラーセンサーに近づく

カラーセンサーで色を判定して赤色が判別されたらこれ以上上昇させない様にストップさせる安全装置としての役割がある

頭部のカラーセンサー

カラーセンサーで赤を判定した状態

カラーセンサーで赤を判定した状態

鼻の動き

Lモーター(ポートB)

鼻は多数のギアが連なって構成されている

象の鼻の構造

Lモーターで頭部付近のギアを回転させると連なったギアにより鼻の先端のギアまで回転が伝わる

先端ではギアが回転しない様に固定されているので回転運動がブロック(鼻)の運動に変換されて鼻が持ち上がったり逆に丸まったりする

尚、鼻を持ち上げる方向にはL字型のストッパーが付いているので一定以上には持ち上がらない構造になっている

象の鼻の構造とストッパー

鼻を持ち上げる動きをした時の簡易的な図

象の鼻の先端の機構

鼻の動きとタッチセンサー(ポート1)鼻も頭部と同様ストッパー機能がついている

鼻が持ち上がって黒いブロックがタッチセンサーに触れるとそれ以上上昇させない様に制御をする事ができる

鼻のタッチセンサー

タッチセンサーが押されている状態

鼻のタッチセンサーが押されている状態

しっぽ可動すると言えばしっぽも可動する

ユニバーサルジョイントブロックをつかってしっぽが左右に振れるようになっている

象のしっぽ

プログラム概要

まずはプログラムの全体構造、細かいブロック毎の機能やロジックは後述する。

また今回はマイブロックを使って複数のブロックに分けているのでブロック毎の説明とする。

尚、記事の最後にプログラミングと実際の動きの動画を載せているので確認してみて欲しい

main メインのブロック

ここから条件に応じてReset、Lift_and_Roar、grabを呼び出してコントロールする

main

mainブロック

Reset初期処理の役割のブロック、頭、鼻を定位置に戻す

Reset

Resetブロック

Lift_and_Roar鼻を持ち上げて咆哮した後、Resetを呼び出して頭、鼻を定位置に戻す

Lift_and_Roar

Lift and Roarブロック

grabResetを呼び出して頭、鼻を定位置に戻した後、鼻を内側に丸めてバーベルを持ち上げる

grab

grabブロック

バーベル

バーベル

プログラム全体

mainブロック

全体の制御をするメインプログラム。

mainブロック

プログラム開始
Resetブロック呼び出す
プログラム終了まで4~21を繰り返す
int変数にゼロをセットする
インテリジェントブロックボタンが押されるまで待機する
押されたボタンにより処理を振り分ける

上:7~9

下:10~12

左:13

右:14

中央:15

int変数を読みこむ
1を加算する
int変数に書き込む(int変数は1になる)
10int変数を読みこむ
111を減算する
12int変数に書き込む(int変数はー1になる)
13Lift_adn_Roarマイブロックを呼び出す
14grabマイブロックを呼び出す
15象の鳴き声(咆哮)音声を再生する
16int変数を読みこむ
17int変数が0で無いかどうかを比較する

0以外:真(7~12の処理を通ってきている)

0:偽

18真の時19~21の処理を行う

偽の時は何もしない

19int変数を読みこむ
20-5を掛ける
21掛けた値を回転数として前進/後退歩行する

マイナス:前進する

プラス:後退する

Reset(マイブロック)

象の頭と鼻を初期状態に設定する。

Resetブロック

プログラム開始
頭を上げる
カラーセンサーが赤色を判定する(頭が上限に達する)まで待機
頭を上げるのを停止する
鼻を持ち上げる
タッチセンサーが押されるまで(鼻が上限に達する)まで待機
鼻を持ち上げるのを停止する
象の鳴き声(咆哮)音声を再生する
1秒間待機する
10頭を所定の位置まで下げる
110.1秒待機
12頭の駆動用モーターの測定値をリセットする
13鼻を所定の位置まで下げる
140.1秒待機
15鼻の駆動用モーターの測定値をリセットする

Lift_and_Roar(マイブロック)

鼻を持ち上げて咆哮する。

Lift_and_Roar マイブロック

プログラム開始
鼻を持ち上げる
タッチセンサーが押されるまで(鼻が上限に達する)まで待機
鼻を少しだけ下げる
Resetブロックを呼び出す

grab(マイブロック)

バーベルを持ち上げる。

grab マイブロック

プログラム開始
Resetブロックを呼び出す

バーベルを持ち上げる前に頭と鼻が所定の位置にある必要があるのでResetを呼び出している

頭を上げる
鼻を上げる
頭をゆっくり下げる(3の前の位置まで戻す)
更に弱いパワーで頭を1秒間下げる(下限まで下げる)
鼻を下げる
頭を上げる

※8と9は同時並行で行う

鼻を内側に曲げる

※頭を上げながら鼻を内側に曲げることによりバーベルを持ち上げる

使用したブロック

今回使用したブロックは以下の10種類。

Mモーターブロック

軽いものを素早く動かすことに適したモーター。

象の頭を上下に動かす為に使用している。

Mモーター オン
Resetブロック

Mモーターで象の頭を上げる(上げ続ける)

  • Mモーター:オン
  • パワー:50

※カラーセンサーが赤を判定するまで(後述)パワーオンの状態を保つ

Mモーター オフResetブロック

Mモーターを停止させる

  • Mモーター:オフ
  • ブレーキ方法:真(惰性なしで停止)

※カラーセンサーが赤を判定したら停止させる

Mモーター 初期状態Resetブロック

頭を初期状態の位置まで角度指定で下げる

  • Mモーター:角度
  • パワー:-40(頭を下げる方向)
  • 角度:770(度)
  • ブレーキ方法:真(惰性なしで停止)
Mモーター 頭を上げるgrab

頭を角度指定で上げる

  • Mモーター:角度
  • パワー:100
  • 角度:350(度)
  • ブレーキ方法:真(惰性なしで停止)

バーベルを持ち上げる前に一旦頭と鼻を上げる動作

Mモーター 頭を下げるgrab

頭を角度指定でゆっくり下げる

  • Mモーター:角度
  • パワー:ー50
  • 角度:350(度)
  • ブレーキ方法:真(惰性なしで停止)

バーベルを持ち上げる前に頭と鼻を上げた後、同じ角度分(350度)だけゆっくりと頭を下げる(初期状態に戻す)

Mモーター 頭を下げるgrab

頭を1秒間弱いパワーで下げる

  • Mモーター:秒数
  • パワー:-10
  • 時間:1(秒)
  • ブレーキ方法:真(惰性なしで停止)

頭を一番下まで下げるために弱いパワーで1秒間下げ続ける

Mモーター 頭をゆっくり上げるgrab

頭をゆっくりと上げる

  • Mモーター:角度
  • パワー:30
  • 角度:400(度)
  • ブレーキ方法:真(惰性なしで停止)

鼻を内側に曲げながら頭をゆっくりとあげる事によりバーベルを持ち上げる

Lモータブロック

重いものをゆっくり動かすのが得意なLモータ。

前進、後退の歩行と鼻を曲げる動作に使用している。

Lモーター パワーオン
Resetブロック

Lモーターで象の鼻を上げる(上げ続ける)

  • Lモーター:オン
  • パワー:-60
  • ポート:B(鼻用)

※タッチセンサーが押されるまで(後述)パワーオンの状態を保つ

Lモーター パワーオフResetブロック

Lモーターを停止させる

  • Lモーター:オフ
  • ブレーキ方法:真(惰性なしで停止)
  • ポート:B(鼻用)

※タッチセンサーが押されたら停止させる

Lモーター 鼻を初期状態まで下げるResetブロック

鼻を初期状態の位置まで角度指定で下げる

  • Lモーター:角度
  • パワー:90(鼻を下げる方向)
  • 角度:770(度)
  • ブレーキ方法:真(惰性なしで停止)
  • ポート:B(鼻用)
Lモーター 鼻を角度指定で上げるgrab

鼻を角度指定で上げる

  • Lモーター:角度
  • パワー:ー100
  • 角度:300(度)
  • ブレーキ方法:真(惰性なしで停止)
  • ポート:B(鼻用)

バーベルを持ち上げる前に一旦頭と鼻を上げる動作

Lモーター 鼻を角度指定で下げるgrab

鼻を角度指定でゆっくり下げる(内側に曲げる)

  • Lモーター:角度
  • パワー:70
  • 角度:500(度)
  • ブレーキ方法:真(惰性なしで停止)
  • ポート:B(鼻用)

バーベルを持ち上げる前に頭と鼻を上げた後、鼻を下げて更に少し内側に曲げる

Lモーター 鼻を更に内側に曲げるgrab

鼻を内側に曲げてバーベルを持ち上げる

  • Lモーター:角度
  • パワー:30
  • 角度:300(度)
  • ブレーキ方法:真(惰性なしで停止)
  • ポート:B(鼻用)
Lモーター 鼻ゆっくり持ち上げるLift_and_Roar

象を咆哮させる前にLモーターで象の鼻をゆっくり上げる(上げ続ける)

※Resetの時よりも弱いパワー

  • Lモーター:オン
  • パワー:-30
  • ポート:B(鼻用)

※タッチセンサーが押されるまで(後述)パワーオンの状態を保つ

Lモーター 鼻を少しだけ下げるLift_and_Roar

タッチセンサーが押されたら少しだけ鼻を下げる

※この後、頭を上げるので鼻が干渉しないようにする

  • Lモーター:角度
  • パワー:10
  • 角度:30(度)
  • ブレーキ方法:真(惰性なしで停止)
  • ポート:B(鼻用)
Lモーター 象の歩行main

Lモーター(ポートA)で四足歩行(前進/後退)する

  • Lモーター:回転数
  • パワー:100
  • 回転数:前進または後退ボタンにより計算された回転数をデータワイヤーで受け取る
  • ブレーキ方法:真(断続的な運動)
  • ポート:A(四足歩行用)

待機ブロック

指定された条件に一致するまで待機するブロック。

カラーセンサーで赤色を検出した、タッチセンサーが押された等の条件に一致するまで待機する。

カラーセンサーが赤色を検出するまで待機する
Resetブロック

カラーセンサーが赤色を検出するまで待機する

  • 待機:カラーセンサー、比較、色
  • 色のセット:5(赤)
  • 色:検出した色の番号を出力する(今回は未使用)

頭を上限まで上げた状態だとカラーセンサーは赤色を検出する

タッチセンサーが押されるまで待機するResetブロック

タッチセンサーが押されるまで待機する

  • 待機:タッチセンサー、比較、状態
  • 状態:1(押された)
  • 測定値:状態を値で出力する(今回は未使用)
1秒間待機するResetブロック

1秒間待機する

  • 待機:時間
  • 秒:1(秒)

1秒待機の他に0.1秒待機も使用している

インテリジェントブロックボタンが押されるまで待機するmain

インテリジェントブロックボタンの上下左右、中央のボタンが押されるまで待機する

  • 待機:インテリジェントブロックボタン、比較
  • ボタンIDのセット:1(左)、2(中央)、3(右)、4(上)、5(下)
  • 状態:1(押された)
  • ボタンID:押されたボタンを数値(ID)で出力する

音ブロック

様々な音を再生する為のブロック。

尚、音ブロックの詳細についてはこちらの記事を参照

象の咆哮(音声)の再生
Resetブロック

象の鳴き声(咆哮)音声ファイルを再生する

  • 音:ファイルの再生
  • ファイル名:Elephant call(象の鳴き声)
  • 再生タイプ:0(完了待ち)

モーター回転ブロック

モーター回転ブロックで測定値をリセットする。

尚、モーター回転ブロックの詳細についてはこちらの記事を参照

モーター回転測定値のリセット
Resetブロック

ポートB(鼻)とD(頭)のモーターの測定値をリセットする

尚、この処理は必ずしも必須では無い

初期処理の一貫として測定値をリセットしている

  • モーター回転:リセット
  • ポート:DとB

ループブロック

指定した条件に一致するまでループ(同じ処理を繰り返す)する。

ループブロック
mainブロック

プログラム終了まで繰り返す

※インテリジェントブロックボタンによりそれぞれの処理を実行した後、ループして最初に戻る

  • ループ:無限

変数ブロック

プログラム中の数値や文字列、ロジック(”真” or ”偽”)を保存することができる。

尚、変数ブロックの詳細についてはこちらの記事を参照

変数intにゼロをセット
mainブロック

変数intにゼロをセットする

  • 変数:書き込み、数値
  • 値:0※
  • 変数名:int

※変数を使って前進/後退の制御を行う

  • 0:停止
  • 1:前進
  • -1:後退
変数intの読み込み
mainブロック

変数intを読み込む

  • 変数:読み込み、数値
  • 値:データワイヤーで後続のブロック(計算ブロックなど)に出力する
  • 変数名:int
変数intへの書き込み
mainブロック

変数intに計算結果を書き込む

  • 変数:書き込み、数値
  • 値:データワイヤーで計算結果を受け取って書き込む
  • 変数名:int

スイッチブロック

入力された条件により処理を分岐するブロック。

今回はインテリジェントブロックボタンにより実行する処理を分岐する。

スイッチブロック
mainブロック

インテリジェントブロックボタンのボタンIDにより処理を振り分ける

  • スイッチ:数値
  • 数値:データワイヤーでインテリジェントブロックボタンのボタンIDを受け取る
  • 4:上ボタンを押された時の処理
  • 5:下ボタンを押された時の処理
  • 1:左ボタンを押された時の処理
  • 3:右ボタンを押された時の処理
  • 2:中央ボタンを押された時の処理
スイッチブロック 前進/後退
mainブロック

変数intがゼロで無い時にボタンの上または下が押されたと判断して象を前進/後退させる

  • スイッチ:ロジック
  • ロジック:比較ブロック(後述)の結果をデータワイヤーで受け取る
  • 真:Lモーターを制御して象を前進/後退させる
  • 偽:何もしない

数学ブロック

数学計算を行って結果を出力するブロック。

尚、数学ブロックの詳細についてはこちらの記事を参照

数学ブロック 足し算
mainブロック

インテリジェントブロックの上ボタンが押された時に変数intに1を加算する

  • 数学:足し算
  • a:データワイヤーで変数intを受け取る
  • b:1
  • 結果:変数intに1を加算した値を出力してデータワイヤーで後続の処理に引き渡す
数学ブロック 引き算
mainブロック

インテリジェントブロックの下ボタンが押された時に変数intから1を減算する

  • 数学:引き算
  • a:データワイヤーで変数intを受け取る
  • b:1
  • 結果:変数intに1を減算した値を出力してデータワイヤーで後続の処理に引き渡す
数学ブロック 掛け算
mainブロック

変数intに-5を掛けて結果に出力する

  • 数学:掛け算
  • a:データワイヤーで変数intを受け取る
  • b:-5
  • 結果:変数intに-5を掛けた値を出力してデータワイヤーで後続の処理に引き渡す※

※前進の時は変数intには1、後退の時は-1がセットされている

-5を掛けた値をLモーターの回転数として引き渡すことにより特定の量だけ象を前進/後退させる

比較ブロック

2つの数値を比較して結果をロジック(”真” or ”偽”)で出力するブロック。

尚、比較ブロックの詳細についてはこちらの記事を参照

比較ブロック
mainブロック

変数intがゼロで無い時にボタンの上か下が押されたと判断する

  • 比較:≠(~と等しくありません)
  • a:データワイヤーで変数intを受け取る
  • b:0
  • 結果:変数intがゼロで無い時に真、ゼロの時は偽が出力される※

※ボタンの上か下が押された時にだけ前進/後退の処理をしたいので比較している

プログラミングと実際に動かしてみた時の動画

象のプログラミングと実際に動かしてみた時の動画。

歩行の様子や鼻の動きなど動画で見るとより分かりやすいので見て欲しい。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

2件のフィードバック

  1. 都落ち より:

    このページを真似しながら一個ずつ理解していって、さきほどようやく象を動かすことができました。
    Resetで頭と鼻を戻すとき、770度では戻り過ぎるみたいで、そこだけ調整が必要でした。
    すごく参考になりました。ありがとうございます。
    追伸:バーベルをなかなか掴んでくれないことにやきもきしますね(笑)

    • souichirou より:

      都落ちさん
      コメントありがとうございます。
      参考になったとのコメント嬉しいです。
      自分も試行錯誤の中で色々なサイトを参考にしたので少しでも誰かの参考になればと思い記事して残しておきました。
      役に立ったのであれば幸いです。

      バーベルを掴む前に鼻がぶつかってしまうのですよね(笑)

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。