アフレル スプリングカップ2019向けロボット ~レゴマインドストームEV3~ | そう備忘録

アフレル スプリングカップ2019向けロボット ~レゴマインドストームEV3~

アフレルスプリングカップ2019について

アフレル社が主催するアフレルスプリングカップ2019の競技規則が公開されていたので試しにロボットを組み立ててプログラミングした時の備忘録。

アフレルスプリングカップ2019は3月26日に東京、28日に大阪で開催される予定のロボットコンテストでWRO(World Robot Olympiad)を簡易にした競技内容で初めての人でも参加しやすい大会になっている。

部門は、

  • 小学生・中学生・高校生ミドル部門
  • 小学生エキスパート部門
  • 中学生エキスパート部門
  • 高校生エキスパート部門
  • ARCミドル部門
  • ARCエキスパート部門

に分かれていた。

詳細はこちら

小学生・中学生・高校生ミドル部門の競技規則を見た所、面白そうだったので挑戦してみることにした。

尚、自分は実際に出場するわけでは無いのと今回の記事のロボットとプログラミングではまだまだ詰めが足りない部分があるのでその辺はご承知おきください。

2019年3月25日追記

この記事ではカラーセンサーを2つ使用していますが実際の大会ではカラーセンサーは1つしか使えません。

大会ではレゴ・マインドストームEV3の基本セットの部品のみが使用できます。

自分は他のセットと混在していたのでうっかりカラーセンサーを2つ使ってしまっています。

アフレルスプリングカップ2019ロボット

競技規則

ミドル部門の詳しい競技規則はこちらを参照して欲しいのだが、ざっくり説明すると以下のルールになっている。

  • スタートして最初に2色(赤または黄)、4枚のラベルを読む
  • ラベルの並び順はランダム(下記の図では赤、黄、黄、赤)
  • ラベルが赤の場合は手前(画面下)のT字型のブロックを奥(画面上)の枠ブロック内に移動させる
  • ラベルが黄の場合は奥(画面上)のT字型のブロックを手前(画面下)の枠ブロック内に移動させる
  • ブロックの移動を合計4回繰り返す
  • ゴールする

アフレルスプリングカップ2019競技説明

T字型ブロックT字ブロック
枠ブロック枠ブロック

コースの制作

まずはコースの制作。

模造紙、ビニールテープは100円ショップで購入、後はえんぴつとハサミとのりで”できるだけ”正確にコースを再現した。

この”できるだけ”というがミソで実は自作のコースは本番とかなり出来が違う。

例えば、

  • 100円ショップのビニールテープが本番は中川ケミカル製のカッティングシート
  • 黒ライン(ビニールテープ)が本番は印刷
  • 外枠は緑のビニールテープでつくったが本番は茶色(茶色のテープが無かった)
  • 模造紙を張り合わせたのでコースの所々が浮いている

等々。

そして最大の違いはコースの左半分しか無いこと。

机のサイズの都合で左半分しか作れなかったけど、まぁこれでもプログラミングの基本的なところは組めるので良しとした。

実際の大会では試走の時間がとれるので、そこで本番環境との違いを調整する必要がある。

カラーセンサーは外部環境(屋外、屋内、昼、夜、照明など)によって測定値が変わってくるので、これだけ材質が違うと仮に実際に大会に出場するのならばかなりの調整が必要になるのだろうけど、今回は遊びなので良しとした。

コースの制作

機体の説明

機体のベースはトレーニングロボットとした。

機動性を考慮すると改良の余地はあると思うが、まずは基本的な機体で試してみることにする。

T字ブロックを持ち上げるアームMモーターでワームギアー>24枚ギアを使ってアームを上下させる

下限に達するとタッチセンサーが押されるようにした

アームの機構

アームが上がっている時

アームが上がっている時

アームが下がってタッチセンサーが押された状態

アームが下がってタッチセンサーが押された状態

カラーセンサーカラーセンサーはボディ下部に2つ

黒ラインのトレースと赤、黄ラベルの判断に使用する

車体を下からみた所

機体を下からみた所

2つのカラーセンサーでライントレースするカラーセンサーは2つ

Mainプログラム概要

Mainプログラムの概要は以下の通り

尚、実際の動きとプログラミングの様子の動画を記事の最後に載せているので参考にして欲しい。

プログラム概要 main

  1. 初期処理
  2. 最初の4枚のラベルの色を読んで数値配列に保存した後、右ターン
  3. 黒ラインまで前進した後、色(赤、黄)によって右または左ターンして赤ラベルまでライントレースしながら前進する
  4. T字型ブロックを持ち上げて反転、逆サイドの赤ラベルまでライントレースした後、T字型ブロックを枠内に下ろす
  5. バックして中央付近に戻った後、ラベルの色(赤、黄)によって右または左ターンして3に戻る

マイブロックは以下の4種類を作った。

Initial初期処理用のマイブロック
LineTrace黒ライントレース用のマイブロック

以前に作成したカラーセンサー2つでライントレースするプログラムを参考にしている

ColorStockカラーセンサーで読み取った色を数値配列に保存するマイブロック

数値配列についてはこちらの記事を参照

LiftDownアームを下げてT字型ブロックを枠内に下ろすマイブロック

Mainプログラム

Mainのプログラム。

量が多いので4枚に分けている

その1

Mainその1

その2

Mainその2

その3

Mainその3

その4

Mainその4

プログラム開始
初期処理(Initial)変数等の初期設定を行う
4~10までを4回繰り返す
カラーセンサーが赤(5)または黄(4)を感知するまで5を繰り返す
黒ライン上をトレースする(LineTrace)
止まる
0.1秒待機する
カラーセンサーで色を読み取って数値配列に保存する(ColorStock)
カラーセンサーが赤(5)または黄(4)以外を感知するまで10を繰り返す
10黒ライン上をトレースする(LineTrace)
11止まる
12右に90度旋回する
1314~37を2回繰り返す(本番では4回繰り返す必要がある)
14カラーセンサーの反射光の強さが20以下になるまで(黒ラインを検出するまで)15を繰り返す
15直進する
16数値配列(Color)から保存した色を読み込む
17数値配列(Color)からループインデックスに対応する色情報を取り出して18に引き渡す
1817からの色情報が5(赤)の時は19、4(黄)の場合は20に分岐する
19右旋回する
20左旋回する
21カラーセンサーが赤を検出するまで22を繰り返す
22黒ライン上をトレースする(LineTrace)
23止まる
24アームを上げてT字型ブロックを持ち上げる
25その場で180度旋回する
26カラーセンサーが赤を検出するまで27を繰り返す
27黒ライン上をトレースする(LineTrace)
28止まる
29少しだけ前進する(T字型ブロックを下ろす位置の調整)
30アームを下げてT字型ブロックを下ろす
31中央付近まで後進する
32止まる
33数値配列(Color)から保存した色を読み込む
34数値配列(Color)からループインデックスに対応する色情報を取り出して35に引き渡す
3533からの色情報が5(赤)の時は36、4(黄)の場合は37に分岐する
36右旋回する
37左旋回する

Mainで使用しているブロック

Mainで使用しているブロックは以下の11種類。

Initialブロック(マイブロック)

初期処理を行うマイブロック。

Initialマイブロック変数などを初期化する

詳細は後述する

ループブロック

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

ループ 4回繰り返す4回繰り返す

※赤 or 黄のラベルを4回読み込むのに使用する

  • ループ:カウント
  • カウント:4
赤または黄になるまで繰り返すカラーセンサーの色が赤(5)または黄(4)になるまで繰り返す

  • ループ:カラーセンサー、比較、色
  • 色のセット:4(黄)、5(赤)

最初の4枚のラベルの判断に使用する

赤または黄以外になるまで繰り返すカラーセンサーの色が赤(5)または黄(4)以外になるまで繰り返す

  • ループ:カラーセンサー、比較、色
  • 色のセット:0(色なし)、1(黒)、2(青)、3(緑)、6(白)、7(茶)

次のラベルに行くためのループ

ループ 2回繰り返す2回繰り返す

  • ループ:カウント
  • カウント:2
黒ラインまで繰り返す反射光の強さが20以下(黒ライン上)になるまで繰り返す

  • ループ:カラーセンサー、比較、反射光の強さ
  • 比較タイプ:4(<)
  • しきい値:20

黒ライン上では反射光の強さは11程度になったので20以下を黒ライン上と判断した

赤になるまで繰り返すカラーセンサーの色が赤(5)になるまで繰り返す

  • ループ:カラーセンサー、比較、色
  • 色のセット:5(赤)

コース上の赤ライン上で停止するために使用する

LineTraceブロック(マイブロック)

黒ライン上のトレースを行うマイブロック。

LineTraceマイブロック左右のカラーセンサーの反射光の強さの差分から左右の車輪のパワーを調整して黒ライン上のトレースを行うマイブロック

詳細は後述する

ステアリングブロック

左右のLモーターを同時に制御するブロック。前進、後退の他に旋回などの制御も可能。

尚、ステアリングブロックの詳細はこちらを参照

ステアリングブロック オフ左右のLモーターを停止させる

  • ステアリング:オフ
  • ブレーキ方法:真(惰性なしで停止)

カラーセンサーで色を読み取る時などに車輪を停止させるために使用する

右に90度旋回右に90度旋回する

  • ステアリング:角度
  • ステアリング:100(その場で右旋回)
  • パワー:40
  • 度:180(度)
  • ブレーキ方法:真(惰性なしで停止)

最初の4枚のラベルを読んだ後の右旋回で使用する

パワー15で前進パワー15で前進する

  • ステアリング:オン
  • ステアリング:0(直進)
  • パワー:15

黒ラインを見つけるまで前進する時に使用する

右旋回右に旋回する

  • ステアリング:角度
  • ステアリング:50(右旋回)
  • パワー:30
  • 度:350(度)
  • ブレーキ方法:真(惰性なしで停止)

黒ラインを見つけた後、右旋回する時に使用する

その場ので旋回では無く大きく回ることによりカラーセンサーが黒ラインを捉えるような角度での旋回を行う

左旋回左に旋回する

  • ステアリング:角度
  • ステアリング:ー50(左旋回)
  • パワー:30
  • 度:350(度)
  • ブレーキ方法:真(惰性なしで停止)

上記の右旋回の逆の動きをする

ラベルの色(赤 or 黄)によって左右逆の動きをする

その場で180度旋回その場で180度旋回する

  • ステアリング:角度
  • ステアリング:100(その場で旋回)
  • パワー:40
  • 角度:360
  • ブレーキ方法:真(惰性なしで停止)

アームでT字型ブロックを持ち上げた後、その場で旋回するために使用する

少しだけ前進する少しだけ前進する

  • ステアリング:角度
  • ステアリング:0(直進)
  • パワー:30
  • 角度:65
  • ブレーキ方法:真(惰性なしで停止)

T字型ブロックを下ろす前に位置調整の為、少しだけ前進する

バックするバック(後進)する

  • ステアリング:角度
  • ステアリング:0(直進)
  • パワー:ー40
  • 角度:500
  • ブレーキ方法:真(惰性なしで停止)

T字型ブロックを下ろした後に中央付近に戻るためにバックする

左旋回左に90度旋回する

  • ステアリング:角度
  • ステアリング:ー100(その場で左旋回)
  • パワー:40
  • 度:180(度)
  • ブレーキ方法:真(惰性なしで停止)

次の黒ラインに向かうに辺り旋回する為に使用する

ラベルが黄色の場合は次の黒ラインに向かうには左旋回する必要がある

待機ブロック

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

0.1秒待機する0.1秒待機する

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

カラーセンサーで色を読み取る時など正確性を増すために0.1秒待機する

待機させる事により誤動作が減ったので待機させている

ColorStockブロック(マイブロック)

ColorStockブロック(マイブロック)カラーセンサーで読み取った色の情報を数値配列に保存するブロック

詳細は後述する

変数ブロック

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

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

Color数値配列の読み込み数値配列(Color)から保存されている色情報を読み取る

  • 変数:読み込み、数値配列
  • 値:色情報が出力されるのでデータワイヤーで配列操作ブロックに引き渡す

ColorStockブロックで保存されたラベルの色(赤 or 黄)の情報を取り出すために使用する

配列操作ブロック

数値配列やロジック配列の操作(追加、読み込み)を行うブロック。

配列操作ブロックの詳細についてはこちらの記事を参照

配列操作ブロック数値配列(Color)に保存されている色情報をインデックス順に読み込む

  • 配列操作:インデックスで読み込み、数値
  • 配列入力:データワイヤーでColor数値配列を指定する
  • インデックス:ループインデックス※をデータワイヤーで指定する
  • 値:取り出した値(色情報)をデータワイヤーでスイッチブロックに引き渡す

ループインデックスは0、1、2、3・・・と0から始まりカウントアップされる

スイッチブロック

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

スイッチブロック(赤 or 黄の分岐)読み込んだ数値(色情報)により処理を分岐する

  • スイッチ:数値
  • 数値:データワイヤーで配列からブロックから色情報を数値で受け取る

赤の時は上の処理、黄の時は下の処理を行う

Mモーターブロック

軽いものを素早く動かすのが得意なMモーター。

Mモーターでアームを上げるMモーターでアームを上げてT字型のブロックを持ち上げる

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

LiftDownブロック(マイブロック)

LiftDownブロック(マイブロック)Mモーターを使ってアームを下げるマイブロック

詳細は後述する

Initialマイブロック

Initialは初期化をするマイブロック。

Initialマイブロック

ブロック開始
変数Powerに18をセットする

Powerはライントレースの時の左右のLモーターのベースとなるパワー

数値配列Colorを空にする
ポート1(左側)のカラーセンサーを反射光の強さのモードにする
ポート4(右側)のカラーセンサーを反射光の強さのモードにする

Initialで使用しているブロック

使用しているブロックは以下の2種類。

変数ブロック

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

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

変数Powerに18をセットする変数(Power)に18をセットする

  • 変数:書き込み、数値
  • 値:18

ライントレースする時のベースとなる車輪のパワーを18に設定する

この値を変えるとライントレースしている時のスピードが変わる

数値配列(Color)を空にする数値変数(Color)を空にする

  • 変数:書き込み、数値配列
  • 値:[](なし)

カラーセンサーで読み取った色情報を格納する為の数値配列

最初に空にしておく

カラーセンサーブロック

カラーセンサー反射光の強さカラーセンサーのモードを反射光の強さを測定するモードにする

  • カラーセンサー:測定、反射光の強さ
  • 照明:初期処理では使用しない
  • ポート:1と4の両方同じ処理を行う

カラーセンサーには3種類のモードがある。

  1. 色の判定
  2. 反射光の強さの測定
  3. 周囲の光の強さ(明るさ)の測定

このプログラムでは反射光の強さと色の判定の両方のモードを使用しているが初期処理ではまずは反射光の強さを測定するモードにしている

LineTraceマイブロック

LineTraceは黒ライン上をトレースするマイブロック。

LineTraceマイブロック

ブロック開始
ポート1(左側)のカラーセンサーで反射光の強さを読み取る
ポート4(右側)のカラーセンサーで反射光の強さを読み取る
左右のカラーセンサーの反射光の強さの差分から補正値を算出する
Power変数からベースのパワー(18)を読み取る
ベースのパワーに補正値を加算する
左車輪のLモーターに6の値をセットする
ベースのパワーから補正値を減算する
右車輪のLモーターに8の値をセットする

LineTraceで使用しているブロック

使用しているブロックは以下の4種類。

カラーセンサーブロック

カラーセンサー 反射光の強さポート1(左)と4(右)のカラーセンサーの反射光の強さを読み取る

  • カラーセンサー:測定、反射光の強さ
  • 照明:測定結果をデータワイヤーで後続の計算ブロックに引き渡す
  • ポート:1と4

変数ブロック

変数ブロック(Power)Initialマイブロックで設定した変数Powerの値を読み込む

  • 変数:読み込み、数値
  • 値:値をデータワイヤーで後続の数学ブロックに引き渡す

数学ブロック

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

数学ブロックの詳細はこちらの記事を参照

数学ブロック左右のカラーセンサーの反射光の強さの差から補正値を計算する

  • 数学:拡張機能
  • a:左側のカラーセンサーの反射光の強さをデータワイヤーで受け取る
  • b:右側のカラーセンサーの反射光の強さをデータワイヤーで受け取る
  • c:差分を補正する為の値※
  • d:使用しない
  • 結果:計算結果をデータワイヤーで左右のLモータもパワーに加・減算する
  • 演算:(a-b)÷c

※aーbの値をそのまま左右の車輪のパワーに加・減算してしまうと値が大きすぎて蛇行してしまうので、適当な数値で割っている

また計算の考え方の詳細はこちらの記事を参照

数学ブロック 足し算ベースのパワー(18)と上記の補正値を合算して左車輪のパワーに代入する

  • 数学:足し算
  • a:ベースのパワー18をデータワイヤーで受け取る
  • b:補正値をデータワイヤーで受け取る
  • 結果:a+bの結果をデータワイヤーで左車輪(ポートB)のパワーに引き渡す
数学ブロック 引き算ベースのパワー(18)から補正値を減算して右車輪のパワーに代入する

  • 数学:引き算
  • a:ベースのパワー18をデータワイヤーで受け取る
  • b:補正値をデータワイヤーで受け取る
  • 結果:aーbの結果をデータワイヤーで右車輪(ポートC)のパワーに引き渡す

Lモーターブロック

左右のパワーの計算結果をデータワイヤーで受け取って制御する。

Lモーターブロック左車輪のパワーを制御する

  • Lモーター:オン
  • パワー:数学ブロックから計算結果を受け取る
  • ポート:B
Lモーターブロック右車輪のパワーを制御する

  • Lモーター:オン
  • パワー:数学ブロックから計算結果を受け取る
  • ポート:C

ColorStockマイブロック

ColorStockはカラーセンサーで読み取った色を数値情報として数値配列(Color)に保存するマイブロック。

ColorStockマイブロック

ブロック開始
数値配列(Color)を読み込む
ポート1(左側)のカラーセンサーから色を読み込む

※同じカラーセンサーでも個体差があり、ポート1に接続したカラーセンサーの方が色を正確に読み取るのでポート1のカラーセンサーを使う事にした

数値配列に3で読み込んだ値を追加する(一番最後に追加される)
数値配列にセットする
3で読み込んだ値が5(赤)なら上、4(黄)なら下のロジックに分岐する

6以降の処理は競技としては必須では無いが読み取った色やタイミングが音で明示的に分かった方がご動作を検証しやすくなる

1760Hzのトーン周波数を再生する
440Hzのトーン周波数を再生する

ColorStockで使用しているブロック

使用しているブロックは以下の5種類。

変数ブロック

変数 数値配列数値配列(Color)に値を保存するために読み込む

  • 変数:読み込み、数値配列
  • 値:データワイヤーで配列操作ブロックに引き渡す
変数ブロック 数値配列の書き込み数値配列(Color)に値を書き込む

  • 変数:書き込み、数値配列
  • 値:後述の配列操作ブロックからデータワイヤーで受け取る

カラーセンサーブロック

カラーセンサー 色の読み取りポート1(左側)のカラーセンサーを使って色を読み取る

  • カラーセンサー:測定、色
  • 色:読み取った色をデータワイヤーで配列操作ブロックに引き渡す

配列操作ブロック

数値配列やロジック配列の操作(追加、読み込み)を行うブロック。

配列操作ブロックの詳細についてはこちらの記事を参照

配列操作ブロックカラーセンサーで読み取った色情報を順に数値配列に追加していく

  • 配列操作:追加、数値
  • 配列入力:前述の数値配列(Color)をデータワイヤーで受け取る
  • 値:カラーセンサーブロックで読み取った色情報をデータワイヤーで受け取る
  • 配列出力:結果をデータワイヤーで出力する

スイッチブロック

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

スイッチブロック(赤 or 黄の分岐)読み込んだ数値(色情報)により処理を分岐する

  • スイッチ:数値
  • 数値:データワイヤーで配列からブロックから色情報を数値で受け取る

赤の時は上の処理、黄の時は下の処理を行う

音ブロック

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

音ブロックの詳細はこちらの記事を参照

音ブロック1760Hz読み込んだ色が赤の時に1760Hzのトーン周波数の再生を行う

  • 音:トーン周波数の再生
  • 周波数:1760(Hz)
  • 持続時間:0.1(秒)
  • ボリューム:100
  • 再生タイプ:0
音ブロック440Hz読み込んだ色が黄の時に440Hzのトーン周波数の再生を行う

  • 音:トーン周波数の再生
  • 周波数:440(Hz)
  • 接続時間:0.1(秒)
  • ボリューム:100
  • 再生タイプ:0

LiftDownマイブロック

LiftDownはMモーターでアームを下限まで下げるためのマイブロック。

下限はタッチセンサーが押された事で判断する。

LiftDownマイブロック

ブロック開始
3をタッチセンサーが押されるまで繰り返す
Mモーターを使ってアームを下げる
Mモーターを停止する

LiftDownで使用しているブロック

使用しているブロックは以下の2種類。

ループブロック

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

タッチセンサーが押されるまでループするタッチセンサーが押されるまでループする

  • ループ:タッチセンサー、比較、状態
  • 状態:1(押された)

アームが下限まで達するとタッチセンサーが押される構造になっている

Mモーターブロック

軽いものを素早く動かすのが得意なMモーター。

Mモーター アームダウンMモーターでアームを下げる

  • Mモーター:オン
  • パワー:-20

タッチセンサーが押されるまで下げ続ける

Mモーター ストップMモーターを止める(アームを止める)

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

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

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

ロボットがT字型のブロックを反対側まで運ぶ様子を動画で確認してみて欲しい。

souichirou

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

おすすめ

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

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