前回から,ROBOLABでLASM(LEGO Assembly Language)のコードをテキスト出力して,ROBOLABのコマンド・アイコンとアセンブラのコードの対応を調べている。
センサーの値などを比較して,分岐を行うLASMのコードがなかなか難しかったので,紹介しておきたい。
このプログラムは,ポート2に接続した光センサーが,40より大きな値を返したらモーターAを順方向に回転させ,40以下だったら,逆方向に回転させるプログラムである。赤着地と赤ジャンプに挟まれているので,この動作を延々と繰り返す。
LASMのコードを出力すると次のようになる(先頭と末尾の一部を省略しています)。
------------------------------------
sent 1,3
senm 1,4,0
Label0:
chkl 2,40,1,9,1,Label1002
pwr 1,2,7
dir 2,1
out 2,1
jmpl Label1003
Label1002:
pwr 1,2,7
dir 0,1
out 2,1
Label1003:
jmpl Label0
endt
------------------------------------
sent 1,3は,SetSensorTypeでセンサーのタイプを指定する。引数はsensor number, sensor typeの順だ。sensor numberは0から始まるので,1はRCXの入力ポート2を示す。sensor type(センサータイプ)は0:Nosensor,1:Switch,2:Temperature,3:Reflection,4:Angleなので,3はReflection(反射)を意味する。
senm 1,4,0は,SetSensorModeでセンサーのモードを指定する。引数は,順にsenm sensor number, sensor mode, slopeである。
sensor mode(センサーモード)は,0:Raw,1:Boolean,2:TransitionCnt,3:PeriodCounter,4:PctFullScale,5:Celsius,6:Fahrenheit,7:AngleStepsだ。ここでは4:PctFullScaleを指定している。
これで,光センサーは光の反射をパーセントで返すことになる。
Label0が赤着地で,jmpl Label0が赤ジャンプに対応している。難しいのがLabel0の次のchklである。chklのすぐ下のコードから見ていこう。pwr 1,2,7,dir 2,1,out 2,1が前回(第249話)説明したようにパワーの設定,回転方向の設定,モーターへの出力だ。
dir 2,1の最初の引数2がforwards(順方向)で,第2引数の1が出力ポートAを示す。だから,この3行がROBOLABプログラムの光センサー分岐コマンドの上への分岐に対応している。
chklの飛び先のLabel1002には,pwr 1,2,7,dir 0,1,out 2,1と記述されている。dirの第1引数0がbackwards(逆方向)を示している。この部分のコードが光センサー分岐コマンドの下への分岐に対応している。だから,chkl 2,40,1,9,1,Label1002でLabel1002に飛ぶのは,光センサーが返す値が40以下の時である。
Mindstorms SDKのLASM Byte codes.pdfによると,chklの引数はchkl src1,val1,relop,src2,val2,forward labelである。srcはsource,valはvalueの略だ。relopについて,pdfには説明がないのだが,Relational Operator,つまり関係演算子の略だろう。Relopに指定できる値は0:Greater than,1:Less than,2:Equal to,3:Different fromだ。
pdfのchklの説明の項には,If the comparison fails(evaluates to FALSE) the execution jumps to the given address.と書いてある。比較に失敗すると(偽と評価されると)指定されたアドレス(ラベル)にジャンプすると訳される。
chklの引数の並びからすると,関係演算子は1:Less thanだ。Less thanがFALSE(偽)と判定されたときに逆回転をするLabel1002に飛ぶのだから,Basic風に書くと,if not (40 < ポート2の値) then goto Label1002となる。
chkl 2,40,1,9,1,Label1002の引数のうち,2,40,1,9,1の真ん中の1がLess thanで左側の2,40が「固定値で40」を意味し,右側の9,1が「センサーで1番(RCXではポート2)」という意味だ。
Not込みで関係演算子として表現するとif 40 >= ポート2の値 then goto Label1002となり,ROBOLABの分岐コマンドと一致する。
さて,春は分岐の季節である。こうしろうは4月から,大学生として大阪に分岐する。でも,「こうしろうのMindStorms日記」は終わらない。プログラムは分岐と合流を繰り返しながら進んでいくものだから。