NXTプログラミング(6)


■ tachoLimitを指定する実験


tachoLimit(回転させたい角度)に100を指定してモーターを回した場合、100ほど回ったあとに止まりはじめるので、200ぐらい回る。そのあと再度モーターをtachoLimitに100を指定して回すとtachoCountはすでに本来回すべき位置(100+100 = 200)に達しているためモーターがうんともすんとも言わない。


「tachoCountの目標値」を内部的に管理しているのだと思うが、これを取得したりリセットしたりする手段が無いようで、どうにも不便である。GetOutputStateで取得できるBlockTachoCountが、この「tachoCountの目標値」かと思ったのだが、どうも測定してみると常にTachoCount == BlockTachoCountである。


「tachoCountの目標値」が取得できないのは、正直設計ミスだと思う。あるいは、BlockTachoCountを返す部分の実装ミスなのだろうか?


結局のところ、指定したパワーで回して、モーターの現在位置を見ながら適宜調整するようなプログラムをしたほうが確実である。


あと、回転位置自体は非常に正確取得できるのに、狙ったところに移動させるのは難しそうである。勢い余って100度ぐらい余裕で回りすぎてしまう。power == 100で回転させて、rotationCountが狙ったところに来たらモーター停止コマンドを送るbusy-loopを書いてテストしたところ、300ぐらい余計に回りすぎてしまう。


ギアでゆっくり回るように調整しないと正確さの要求される制御はさせられそうにない。



■ Bluetoothの通信遅延の実験


Bluetooth経由でこの手の制御を行なうとどれくらいラグがあるのか、NXTからstatusのリターンが必要なコマンド(GetBatteryLevel)をbusy-loopで回して計測してみたところ、秒間30回ぐらいループを回っていたのでBluetooth経由でも問題となるほど大きなラグではないと思った。*1


■ モーターのカウントのリセット


次にモーターのカウントを途中でリセットしてみよう。


nc.ResetMotorPosition(nxtMotorPort, false);


第二パラメータは、RESETMOTERPOSITIONコマンドのByte 3(4バイト目*2 )に渡される。


これは、BDKのDirect Commandsのp.9によると、相対フラグのようで、trueなら前回の移動場所からの相対でリセットされる。falseなら、絶対ポジションでリセットされると書いてある。私の頭が悪いのか、意味がさっぱりわからない。(またか!)


falseを指定して、ResetMotorPositionコマンドを送ると、RotationCountだけがリセットされ、0になった。TachoCountはリセットされない。ここがミソである。次にtrueを指定して、ResetMotorPositionコマンドを送った。RotationCountもTachoCountも変化なし。謎である。(わかる人はコメント欄でフォロー頼んます)


BDKのp.8には、TachoCountの説明に「Internal count,Number of counts since last reset of the moter」とあるのだが、ここのモーターのリセットコマンドが、このtachoCountのリセットに該当しないようなのだ。なんと言う紛らわしい書きかただろうか。RotationCountのほうは「Current position relative to last reset of the rotation sensor for this moter」とあって、どうもこのリセットコマンドは回転センサーに対するリセットに該当するようだ。


■ まとめ


tachoCountは電源投入後、ずっと累積されていく。tachoLimitを指定して回した場合、前回のtachoLimitを指定して回したはずの位置から今回指定されたtachoLimitを加算した値にtachoCountがなるように、モーターを回転させる。


RotationCountは、ResetMotorPositionでリセットできる。回転させる前にこれでリセットさせ、回転後に取得することでモーターがどれだけ回転したかを正確に知ることが出来る。

*1:USBのほうでも同じ条件でテストをしたかったのだが、NXTをUSB接続したときに仮想COMポートが出現しないので、わざわざfantomSDKを使うのが嫌だったのでテストしておらず。気が向いたらやる。fantomSDKはBluetoothとUSB、どちらでNXT接続されていてもプログラムするほうはそれを意識せずに済むのが利点なのだが、かなりのへたれライブラリなので私は使う気になれない。どうしてNXTをUSBで接続したときにBluetooth接続と同じく仮想COMポートが出現するような作りにしておかなかったのだろうか…。

*2:細かいことだが、BDKのDirect Commandsのp.4の下のほうの図のByte 5,Byte 6はByte 1から始まって5バイト目、6バイト目の意味なのに、P.5以降は、Byte 0と0バイト目から書かれている。とんでもない罠仕様である。p.6で ULONGのところがByte 8-12と5バイトもあるように書かれていたりとこの仕様書を書いた奴はよほど算数が出来ないのではないかややこしいので注意。