- ベストアンサー
ROBOTCのbSoundActive変数とは?
- ROBOTCのbSoundActive変数は、LEGO MINDSTORMSのサウンド機能が使えるかどうかを判定するための変数です。
- bSoundActive変数は、音を再生中であればtrue、再生していなければfalseとなります。
- 実際にプログラム上でbSoundActiveを使用する際は、==trueを省略しても問題ありませんが、明示的に指定することで可読性を高めることができます。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> 課題は「フローチャートに従ってプログラムを書け」というもので、できあがったプログラムは「超音波センサで障害物の距離(SensorValue(sonarSensor))を取得し、距離に応じた周波数のビープ音を鳴らす」というものでした。 なるほど。 >ここでの if(bSoundActive) は、「サウンド機能が使用可能かどうか」を調べるものであると説明されていました。 >何か不具合があってサウンド機能が使用できないときに、elseの方が実行されるという設計なのでしょう。 ドキュメントから、「サウンド再生中であればフラグが立つもの」であって、 「サウンド機能が使用可能であればフラグが立つもの」ではないと思います。 Googleで検索したら、いくつかプログラムが見つかりましたが、 どれも「いま音が出ているかどうか?」をチェックする目的で使用しているようでした。 例えば以下は、スターウォーズの曲を鳴らすプログラムです。 http://www.robotc.net/blog/?cat=5&paged=3 特定の音をPlayToneで時間長を指定して鳴らし、鳴り終わる(falseになる)のを while(bSoundActive);で待ちます。 「今音が出ていない」ことをフラグから読み取り、駆動が進むプログラムです。 > このプログラムは正しく動作します。(だからこそチェックに合格したのです。) ですから、なぜ正しく動作したのか、私にはわかりません。 最初に音が鳴っている状態からスタートしたのでなければ、このプログラムは、 何もせずに終わるのが正しい動作だからです。 1点だけ、 if(bSoundActive == false) { A; } else { B; } ではどうだったのか、というのは興味はあります。 検証ができない今(となっては?)言えるのは、それぐらいです。
その他の回答 (2)
- hidebun
- ベストアンサー率50% (92/181)
> nxtDisplayTextLine関数があるので、正しい使い方かは分かりませんが、 そういう時には、Googleで関数名を検索するだけで、使用例がほぼ見つかります。 調べてみましょう。 >(int型の変数の表示はこの方法で正しく表示されるようです) 正しい書式に従った記載方法ではないと、検証自体の意味がなくなってしまいます。 > 参考までに、最終的にチェックに合格したプログラムです。whileループの方が実行されます。 プログラムの実行開始時には、音が既に鳴っている状態なのでしょうか。 作成者の意図した動作でない限り、プログラムは言語を問わず、バグを含んだ状態です。 それゆえのご質問かと思いますが、その辺りも、先生に問い合わせてみましょう。 それから、本筋からそれてしまいますが、このwhile文は、breakしませんね。 音が鳴っている・いないにかかわらず、PlayImmediateTone関数をwait10Msec(1)しながら、 永遠に呼びつづけることになりますが、それで良いのでしょうか? (音が鳴りっ放しになる?) ・音がなっていなかったら鳴らす ・音がなっていたらちょっと待つ のような制御をしたい、というわけではないのでしょうか? であれば、 while(true) { if(bSoundActive) { } else { } } のような制御構造になると思うのです。
補足
> nxtDisplayTextLine関数 使用例ではprintfと同様に%dなどを使用していますが、まだ見ていなかった当時は感で書いて「とりあえず動作するから」と安易に考えていました。 確かに、想定外の使い方であれば誤作動してもおかしくありませんね。 課題は「フローチャートに従ってプログラムを書け」というもので、できあがったプログラムは「超音波センサで障害物の距離(SensorValue(sonarSensor))を取得し、距離に応じた周波数のビープ音を鳴らす」というものでした。 ここでの if(bSoundActive) は、「サウンド機能が使用可能かどうか」を調べるものであると説明されていました。 何か不具合があってサウンド機能が使用できないときに、elseの方が実行されるという設計なのでしょう。 breakしないとのことですが、手動で停止させるまで繰り返すので、問題ありません。 このプログラムは正しく動作します。(だからこそチェックに合格したのです。) ただ、「bSoundActiveは果たして何を示す変数だったのか」、「==trueを省略できなかった理由は何か」という点に疑問が残ったので、質問させていただきました。
- hidebun
- ベストアンサー率50% (92/181)
>「音を再生中ならばtrue、再生していなければfalse」という意味だと思うのですが 確かにそのように読めます。説明者にドキュメントを見せて、確認を求めてはいかがでしょうか? また、「自分でもこのようなプログラムを書いて確認してみたのだが」と、単に相手の揚げ足を取るのではなく、客観的に判断できる論拠を示すことが大切かと思います。 > 今度はbSoundActiveはtrueと判断せざるを得ません。 printfなどで、実際に変数の値を確認することはできませんか? 事象から、判断せざるを得ない、というよりも、実際の値を見る方が、より正確でしょう。 > この変数はbool型なので、普通==trueは省略してもよいと思うのですが、それだと不都合があるのですか? true/falseがどこかで再定義されて、例えば、 #define true 0 #define false 1 などのようになっていると、不都合があるでしょうが、ドキュメントの使用例を見ると、 while(bSoundActive) { } などとなっているので、trueは0ではないと思います。 trueの値, falseの値、bSoundActiveの値をif文の直前で確認してみましたか? ==trueが誤って代入文(=true)になっていたりしませんか?
補足
ご回答ありがとうございます。 そうですね、今度ヘルプを見せて確認してみようと思います。 > printfなどで、実際に変数の値を確認することはできませんか? 文字列を本体液晶画面に出力するnxtDisplayTextLine関数があるので、正しい使い方かは分かりませんが、 nxtDisplayTextLine(1, ""+bSoundActive); とすると0と表示されました。(int型の変数の表示はこの方法で正しく表示されるようです) > ==trueが誤って代入文(=true)になっていたりしませんか? 参考までに、最終的にチェックに合格したプログラムです。whileループの方が実行されます。 現在実行できる環境にないので、再確認はできませんが、条件文の==trueを取るとelse側が実行され、腑に落ちなくて仕方がなかった記憶があります。 task main(){ int nSonarValue = 0; if (bSoundActive==true) { // when TRUE while (true) { nSonarValue = SensorValue(sonarSensor); // Get SensorValue nxtDisplayTextLine(1,"SonarValue: "); // Display text nxtDisplayTextLine(2," "+nSonarValue); PlayImmediateTone(nSonarValue*100,1); wait10Msec(1); // Play sound and Wait } } else { // when FALSE nxtDisplayTextLine(1,"Sound Disable"); // Display text wait10Msec(200); } }
お礼
遅くなってすみません。 厳密に検証したわけではないのですが、以来他にもbool型に状態を記録するとうまくいかないのにint型で代用するとうまくいったという事例があり、私の中ではbool型の実装に不具合があるのではという結論で落ち着きました。 このような形で締め切ってしまい申し訳ございません。わざわざ付き合っていただいてありがとうございました。