スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


にほんブログ村 その他趣味ブログ LEGO・ブロックへ

お絵かきロボ - プログラミング編 (2/4)

お絵かきプログラムのコア部分は、ある(u, v)の角度、例えば (30°, 60°) から (45°, 90°)へちゃんと動かせるかという点です。uの増え方 と vの増え方 が異なる点に注意です。今回のプログラムでは、u, vはそれぞれ motorC と motorB に対応しています。また、ウォームギアとターンテーブルの外側の比率は 1:56 ですので、ターンテーブルでの30°回転は、motorの1680°回転になります。

NXCで該当する関数を調べてみると…、
RotateMotorEx(OUT_BC, 50, 1680, 50, true, true);
これでバッチリじゃん!と思いきや、4つ目の引数(同期の%を表す、例:100なら同じ方向に同じスピードで同期、-50なら逆方向に半分のスピードで同期)が0でも10でもなんか速度が変わらない…。また、用意されているportがOUT_BCしかないので、Bの回転する角度>Cの回転する角度 の時はいいんだけど、Bの回転する角度<Cの回転する角度 の時は100%超えちゃうので、この関数は使えない…。マニュアル1000ページ作るパワーあるなら、このあたりをもう少しキメ細かくして欲しいのですが…。まあ愚痴はこのへんにします。

RobotCでは、2通り方法を考えました。
1. 同期の機能を使う。
2. motorB, motorCを別taskとして独立に動かす。Timerの機能を使って、足並みをそろえながらすすめる(motorCはmotorBの半分だけの角度を回す、という具合)。

2.の方は結局試していませんが、回す角度を正確にできそうな反面、あんまり細かく時間でそろえると回す角度が小さすぎてうまくいかなくなる可能性があります。RobotCでは回す角度が30°ぐらいでは小さすぎて制御が失敗することが多いです。少なくとも90°ぐらいは回さなくてはなりません。できれば360°以上。

1.の方は以下のコードではじめの定数の部分を変えて、いくつか実験をしました。これは Bの回転する角度>Cの回転する角度 の場合です。
task main(){
  const float destB = 1680.0;          // motorBの回転する角度
  const float destC = 840.0;           // motorCの回転する角度 (マイナスならmotorBと逆方向)
  const float turnRatio = destC/destB; // 同期の割合。NXCのRotateMotorExの4つ目の引数に相当。
  const float motorPower = 100;        // motorBのパワー (マイナスならmotorBが逆方向に回る)
  
  nMotorEncoder[motorB] = 0;
  nMotorEncoder[motorC] = 0;
  wait1Msec(100);
  
  nMotorEncoderTarget[motorB] = -abs(destB);
  nSyncedMotors = synchBC;
  nSyncedTurnRatio = turnRatio * 100;
  motor[motorB] = motorPower;
  while(nMotorRunState[motorB] != runStateIdle && nMotorRunState[motorB] != runStateHoldPosition){
  }
  motor[motorB] = 0;
  motor[motorC] = 0;
  
  float resultDegreeB = nMotorEncoder[motorB];
  float resultDegreeC = nMotorEncoder[motorC];
}
重要な点は9行目、11行目、15行目です。RobotCのHelpには書いてないことだらけです。
・9行目: nMotorEncoderによる値のリセットは時間がかかるため、wait1Msec(100); が必要とのこと。Forumより。
・15行目: runStateHoldPosition (減速して止まりかかってる状態)に関してもチェックをしないと、早く減速しすぎるためか、指定した回転する角度に達せず、動作が止まってしまう。bugとしか思えません。Forumより。
・11行目: Helpにはマイナスの時はその値に達するとcoastモードで惰性で回ると書いてあるけど、プラスよりマイナスの方がちゃんと指定した値で止まります。

また、実験の結果は以下のことが示唆されました。
・motorC側は回転して欲しい角度にぎりぎり達しない(1~5°ぐらい手前)
・motorC側の回転して欲しい角度が100°ぐらいをきると, 8°~10°ぐらい達しなくなってしまう。この時は、motorRatioを +1% 水増しした方が成績がよい。
・motorPowerは 50 より 100 の方が成績がよい。これはmotorCのパワーが小さくなると誤差が大きくなるためと推測されます。

以上より、RobotCで同期の機能を使って、motorPower=100で実装することにしました。
スポンサーサイト


にほんブログ村 その他趣味ブログ LEGO・ブロックへ

コメントの投稿

非公開コメント

No title

制御系のプログラムはハードと密接に関連してくるので、難しそうですね。
私は業務用アプリ位しかプログラムの経験がないんですが、随分違うものなんですね。

レゴだと強度的にも大変な部分も多いと思いますが、頑張ってください!

Re: No title

僕も制御系のプログラムははじめてで苦戦してます…。たまにプログラムをミスして、レゴからバキッッバキッッと音が聞こえるとさすがに焦ります。

完成したら続きを書こうと思ってるのですが、正月過ぎたら進み具合がなかなか芳しくないですねー。もう一頑張りします!
リンク
フリーエリア
プロフィール

tsukuba.lego

Author:tsukuba.lego
●主な登場人物
koba : 会長. RCX, WeDo, NXT1.0, NXT2.0を持つ.
matk : 副会長. 2010年夏にNXT2.0を購入, 20年来のレゴ熱復活.
●会員募集中です!小学生から歓迎. 近日月1ぐらいで集まる予定.
mail:tsukuba.lego@gmail.com
YouTube (tsukubalego)
Twitter(tsukubalego)

カテゴリ
最新記事
最新コメント
月別アーカイブ
検索フォーム
RSSリンクの表示
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
最新トラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。