『マイコンカートに指示してみよう』

◆プログラム言語のお話・・・◆


【マイコンカート】

 私たちがコンピュータで何か仕事をするときは、多くの場合、既に誰かによって作成されたプログラム(ソフトウェア)を利用しています。
 コンピュータが唯一わかる「言葉」は、「マシン語」(機械語)と呼ばれています。「CD1F000D0A・・・」というようなパッとみただけでは人間にはわからない命令の集まりです。この「マシン語」は、難解な上、コンピュータ内部の仕組みに詳しい人しか扱えないため、多くの人に利用されるものではありません。
 そこで、より人間にわかりやすい「言葉」でコンピュータに指示できるように、いくつかの「プログラミング言語」が作られました。人間が使う言葉にも日本語、英語とあるように、用途別に、PASCAL, BASIC, LOGO, Lisp, Prolog, C, FORTRANなど様々な言語があります。
 今回は、『マイコンカート』という、『マイクロコンピュータ内蔵の自走式ロボット(カート)』を使い、「キューブベーシック」という「BASIC言語の1つ」を用いて、迷路を脱出するプログラミングを考えてみましょう。

◆『キューブ ベーシック』の起動◆

『スタート』ボタンから、『プログラム』 ⇒ 『応用ソフト』 ⇒ 『ハイパーキューブNet』を選び、 『ハイパーキューブNet』を起動しましょう。
次に、起動した後に、 『ハイパーキューブNet』の画面から『ベーシック』をクリックして下さい。


すると、次のような選択画面が表示されますので、「マイコンカート」を選択して下さい。


次のような画面が表示されます。

◆プログラム画面と、シミュレーション画面◆

この画面は、下の赤・青四角で示した部分をクリックすることで、マイコンカートに、指示するプログラムを入力する「プログラム画面」と実際の車に指示したのと同じように、画面上で試すことができる「シミュレーション画面」の2つの画面があります。

◆ポート◆

さて、マイコンカートには、4つの出力ポート(信号を出す部分)と、1つの入力ポート(信号を受け取る部分)があります。

意味 ポート番号 命令 データ
出力 右モータ POUT(1,データ)  7:最大前進
 0:停止
−7:最大後進
−7〜7
左モータ POUT(2,データ)
右の光 POUT(3,データ)  1:点灯
 0:消灯
左の光 POUT(4,データ)
入力 光センサ PINP(5) 10:障害物あり
 0:障害物なし

◆カートへ指示しよう◆

まずは、カートに直進する指示をしてみましょう。

1.機器の初期化がまず必要
最初に指示するのは、「機器の初期化」をする命令「pinit」(ピー・イニット)です。
「p」や「i」を入力中は、黒色の文字ですが、全部を入力すると、自動的に青色に変わります。

 ■役割
   機器の初期化をする命令
 ■書式
   pinit

2.モータを制御する命令は、pout(ピー・アウト)
次に、モータ類に指示する命令は、「pout」を使います。この命令は、下のように、引数を2つ必要としていて、最初に、指示する装置を示す「ポート番号」(1〜4)、次に、その装置に指示するデータとなります。

 ■役割
   ポートにデータを送信する命令
 ■書式
   pout(ポート番号,データ)
 ■利用例(右のモータを7の速度で動作を指示)
   pout(1,7)

3.直進するには、どうするの?
さて、上の表を見てみると、直進させるという直接的な命令がなさそうです。
そのかわり、右のモータを前進させる命令と、左のモータを前進させる命令があることがわかります。
そこで、直進させるために、両方のモータを前進させることにしてみます。

4.それでは、実行(シミュレーション)してみよう
それでは、下の赤四角で囲んだ「実行」ボタンを押して、実行(シミュレーション)してみましょう。
画面がシミュレーション画面に、切り替わって、カートが動く様子を見ることができます。
カートのタイヤが、灰色になっているほうが、動作しているモータです。


5.シミュレーション画面は、狭いので・・・
さて、しばらくすると、このシミュレーション画面からカートが飛び出したと思います。
そうすると下のようなメッセージが表示されます。ここまで、カートを動作させてもいいですが、途中でシミュレーションを中断したいときは、先ほどの実行ボタンの隣にあるボタンを押すと、中断することができます。

◆3秒たてば、右に曲がるように指示してみよう◆

直進は、うまく指示できたでしょうか?たった3行の命令で、カートは直進してくれましたので、次には、「3秒直進させて、右に曲がるように指示」するようにしてみようと思います。ここで登場する命令は、「pause」(ポーズ)を用います。
 ■役割
   プログラムの実行を指示された時間待つ命令
 ■書式
   pause n
   nは、10分の1秒単位なので、3秒の場合は、30を指示
 ■利用例(3秒待つ)
   pause 30

さて、皆さんは、どのように指示しますか?

◆センサーによる判断◆

迷路を脱出させるには、先ほどのように、指示した時間で、指示した方向に動作させるだけでは、色々な場面で困ることが多いでしょう。
今回利用しているカートには、障害物があるかどうかを判断するプログラムにしてみます。

「障害物があれば、止まるプログラム」

1.シミュレーション画面の準備

まず、シミュレーション画面に、障害物を準備してみましょう。
下のように、線を引くと、障害物を設置したことになります。


2.カートの位置を移動させるには・・・
 カートのスタート位置を変更したい場合には、ドラッグ(カートの上に、マウスカーソルを持ってきて、左クリックしながら、移動したい先まで、マウスで移動)してください。
 カートの向きは、カートの上で、右クリックすると、右に少し傾きます。

3.直進だけで、実行すると・・・
 さて、直進するだけのプログラムに、戻して、実行してみましょう。障害物にぶつかって、カートの前進が止まってしまいます。
ですが、ときどき、シミュレーションの限界で障害物を飛び越えてしまうときがあります。(~_~;)
そういう場合は、障害物を書き換えて試してみてください。

4.光センサを働かすには・・・
 障害物に近づけば、モータを止めて、ちゃんと停止させるようにしたいと思います。
そこで、光センサを使いたいのですが、そのためには光センサに入る光を発する、「発光ダイオード」を点灯させることが必要になります。
このカートには、正面から右側の障害物に光を当てる発光ダイオード(右の光)と、正面から左側の障害物に光を当てる発光ダイオード(左の光)の2つがついています。今回は、正面の障害物を見つければいいので、右の光だけを点灯させたいと思います。

pinit    '---機器の初期化
pout(1,7) '---前進を指示
pout(2,7)
pout(3,1) '---右の光を点灯

5.障害物があるかどうかを判断するには・・・
さて、障害物があるかどうかを判断するためには、ポートの5番から、データを受け取る必要があります。
そこで、光センサからのデータを受信する命令として、「pinp」(ピー・インプ)を利用します。
 ■役割
   ポートからデータを受信する命令
 ■書式
   pinp(5)

この命令は、0(障害物がない)か、10(障害物がある)のどちらかの値を返す「関数」といわれる命令です。
ですので、これ1つで利用するのではなく、つぎのような、「判断」をする文と組み合わせて、利用します。

 ■役割
   もし、式が正しいならば、命令を実行し、式が正しくなければ、なにも実行しないという文
 ■書式
   IF 式 THEN
    命令
   ENDIF

今回の場合は、モータを止めたいので、次のように記述します。

pinit    '---機器の初期化
pout(1,7) '---前進を指示
pout(2,7)
pout(3,1) '---右の光を点灯

if pinp(5)=10 then
  pout(1,0) 
'---停止を指示
  pout(2,0)
endif

さて、うまく動作するでしょうか・・・?

6.障害物があれば、モータを止める命令を、ず〜と動かすには・・・
 実は、先ほどのプログラムは、期待どおり、動作しません。というのは、赤い部分は、壁にぶつかるまでに実行が終わってしまっているのです。
そこで、赤い部分を、ず〜と繰り返して動作させたいので、次のように指示してみます。

 ■役割
   指示されたところから、実行するように、ジャンプする命令
 ■書式
   goto ラベル名
   ラベル名には、「*(アスタリスク)」を先頭にした好きな文字が指定できます。

pinit        '---機器の初期化
pout(1,7)     '---前進を指示
pout(2,7)
pout(3,1)     '---右の光を点灯

*LOOP
  if pinp(5)=10 then
    pout(1,0) '---停止を指示
    pout(2,0)
  endif
goto *LOOP  '--- *LOOPへ飛ぶ

◆変数の利用◆

さて、作ったは、数値の羅列で、少し読みづらいですし、その数字の意味は、ポートの表などを見ないとわかりません。
そこで、「変数」というものを利用して、プログラムを見やすくしてみます。
変数とは、例えば、「右モータ=1」というように、「右モータという変数の中に、(1)という値を代入する」として、準備します。
そうすると、今まで「pout(1,7)」としていたところが「pout(右モータ,7)」というように、わかりやすく書き換えることができます。

右モータ=1
左モータ=2
右の光=3
左の光=4
光センサ=5
ON=1
OFF=0
障害物あり=10

pinit
pout(右モータ,7)
pout(左モータ,7)
pout(右の光,ON)
*LOOP
  if pinp(光センサ)=障害物あり then
    pout(右モータ,0)
    pout(左モータ,0)
  endif
goto *LOOP

◆宿題:「迷路を脱出するプログラムを考えてみよう」◆