ロボティクス入門ゼミ 教材 2017-10-27
変数とは値を入れておくための「箱」で、 プログラムが実行されている時にその値を変更することができる。 変数には、整数型、浮動小数点型、文字列型などいろいろな「型」の値を 格納することができる。 また、pythonではC言語などと違って変数の型を宣言する必要はない (自動で判別してくれる)。
次の例では、move_time という名前を付けた変数を使っている。
#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep
mL = LargeMotor('outA')
mR = LargeMotor('outB')
def motor_init():
mL.reset()
mR.reset()
def move_forward(t):
mL.run_timed(time_sp=t, speed_sp=500, stop_action='brake')
mR.run_timed(time_sp=t, speed_sp=500, stop_action='brake')
sleep(t/1000)
if __name__ == '__main__':
motor_init()
move_time = 2000 # move_time という変数を定義し2000を代入
move_forward(move_time) # move_timeには2000という値が入っている
sleep(1)
move_time = move_time/2 # move_time/2 を新たに move_time に代入
move_forward(move_time) # このとき move_time には 1000 という値が入っている
sleep(1)
move_time = move_time/2
move_forward(move_time) # このとき move_time には 1000 という値が入っている
整数や浮動小数点型の変数に対しては、この例のように通常の四則演算ができる
(足し算は「+」、引き算は「-」、掛け算は「*」、割り算は「/」)。
また上の例の、 move_time = move_time/2 は move_time /= 2 と書くこともできる。 つまり、/= 2 は、変数の値を 2で割って、その結果を再びその変数に格納する、という意味である。 同様に += , -= , *= も使える。
上で作成したプログラムを少し改良・変更して、次のような例からスタートする。
#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep
mL = LargeMotor('outA')
mR = LargeMotor('outB')
def motor_init():
mL.reset()
mR.reset()
mL.speed_sp=500
mR.speed_sp=500
mL.stop_action='brake'
mR.stop_action='brake'
def move_forward(t):
mL.run_timed(time_sp=t)
mR.run_timed(time_sp=t)
sleep(t/1000)
def main():
motor_init()
move_forward(2000)
if __name__ == '__main__':
main()
簡単のため、左右のモータのスピード設定値とブレーキモードは motor_init()の中で初期化してある。 また、実際の動作も main() 関数の中で記述し、スクリプトを起動したときに「関数」として実行するようにしてある。
for を使った繰り返しでは、まず「リスト」と呼ばれるデータの集まりを用意し、 その中の要素を1つずつ「ループ変数」に当てはめて繰り返しを実行する。 他の言語の forearch や for each に相当する。 基本的な書式は次の通り。
for ループ変数 in リスト:
処理
...
pythonのリストは、[1,2,3] や ['a','b','c'] のように、 各要素をコンマで区切って全体を [ と ] で囲む。
以下は、上の例の motor_init() の中を for ループを使って簡略したものである。
#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep
mL = LargeMotor('outA')
mR = LargeMotor('outB')
def motor_init():
for m in [mL,mR]: # ループ変数mにmLとmRを入れて繰り返す
m.reset()
m.speed_sp=500
m.stop_action='brake'
def move_forward(t):
mL.run_timed(time_sp=t)
mR.run_timed(time_sp=t)
sleep(t/1000)
def main():
motor_init()
move_forward(2000)
if __name__ == '__main__':
main()
for ループの場合も他のブロック同様、for 文の最後に : をつける、ループさせる部分をインデントする、 ということを忘れないように。
次に、回数を指定して繰り返しをさせてみる。
... 以上省略 ...
def main():
motor_init()
for i in ['a', 'b', 'c']:
move_forward(2000)
sleep(1)
... 以下省略 ...
この例では、ループ変数iに、文字列'a','b','c'がそれぞれ代入されて、 move_forward(2000)とsleep(1)が繰り返される。 実はこのループの中では、i というループ変数は一切使われていない。 つまり、単に3回繰り返すだけであれば、3つの要素を持つリストなら何でもよい。 が、通常は次のように数字のリストの方が簡単に書ける。
... 以上省略 ...
def main():
motor_init()
for i in [0,1,2]:
move_forward(2000)
sleep(1)
... 以下省略 ...
もちろん [0,1,2]の代わりに [1,1,1] と書いても [6,4,2] と書いても [0,'x','abc'] と書いても同じ動きをする (pythonのリストは、整数も文字列も一緒にリストの要素にできる)。
数字の並びの場合は、range()という関数を使って書くこともできる。 さらに、この例のようにループ変数がダミーの場合には、変数名として dummy や _ (単なるアンダースコア)が使われることがよくある。
... 以上省略 ...
def main():
motor_init()
for _ in range(3): # range(3) は [0,1,2]
move_forward(2000)
sleep(1)
... 以下省略 ...
range()は連続した数字を要素としてもつリストを作成ための関数で、 始まりと終わりや、ステップを指定することもできる。 上の例では、range(0,3) あるいは、range(0,3,1)と書いても同じである (0から始まって3未満の整数まで)。
実際にループ変数にどのような値が入っているのか、画面に表示させてみる。
... 以上省略 ...
def main():
motor_init()
for i in range(2,10,3): # range(2,10,3) は [2,5,8]
print(i) # iの値を画面に表示
move_forward(2000)
sleep(1)
... 以下省略 ...
【練習問題】0.5秒ごとにスピードを 0,200,400,600,400,200,0,-200,-400,-600,-400,-200,0 と変化させて動くロボットを作りなさい。
ある条件を満たしている間だけ処理を繰り返したい場合は、while を使う。
基本的な書式は次の通り。
while 条件:
処理
...
前節の例を while を使って書いてみる。 そのためには、1回繰り返すごとに1増える変数(カウンタ)を用意して、 この変数が指定した値を超えない間だけ処理を繰り返す。
... 以上省略 ...
def main():
motor_init()
i=0 # 繰り返しの回数を数える変数を用意
while i<3 : # i<3 の間繰り返す
move_forward(2000)
sleep(1)
i+=1 # iを1だけ増やす ( i = i+1 と同じ )
... 以下省略 ...