本記事について
ETロボコンとは、組込みソフトウェアプログラミング教育を目的としたロボコンのことである。
スタートからゴールまでのタイム + 難所クリアなどのボーナスタイムの合計と、ソフトウェアの内容を説明するモデルの完成度によって競われる。
本記事では、ETロボコンに挑戦する筆者が開発をする中でぶち当たった一つの問題と、その解決方法を書いていく。
開発環境
- MacOS High Sierra
- C++
今回起きた問題
状態
走行体が倒立時に問答無用ですぐに倒れる。
問題が発生した状況
運営本部から実装をお願いされていた、走行体が転倒した際にモーターの回転を停止する関数の実装中だった。この関数を使用すると走行体の倒立が不安定になり、この関数をコメント化して挙動を見ると、倒立が安定した。
想定される問題について考えたことと、解決策実施の結果
論理エラー
まずはプログラム自体に問題がないかをチェックしていった。
問題はなかった。
実行時エラー
メモリリーク
次に走行体が倒立できない原因として考えたのは、メモリリークだった。
恥ずかしながら司令塔の役割を果たすapp.cppから、ev3apiのモーターやセンサーのポインタを利用して、他クラスで利用するev3api関連を初期化していなかったので、メモリを喰っているのは間違いなかった。走行中にメモリ量が足りなくなってしまったのではないか、というわけだ。
しかし、変更点が多くなりすぎるので、これは最後に確かめることにした。
呼び出し時間
最後に考えたのは呼び出し時間だ。
走行体は4ミリ秒ごとに倒立に関係する関数を呼ぶことによって倒立を維持している。4ミリ秒経つまでにプログラムを最後まで処理しきれていないければ、倒立が維持できないはずである。
浅学ながらインライン関数を使えば呼び出し時間を短縮できると考え、倒立に関係する関数をインライン化していった。しかし、効果はなかった。
また、今年のプログラムにはAPIを柔軟に、後からでも楽に拡張するために、あらかじめMotorならMotorを継承したMotor_expandというように、API拡張クラスをAPIとそれを利用するクラスの間に挟んでいた。
継承という形だったので、呼び出し時間に影響はないと勝手に思っていたが、この拡張クラスを抜くと、無事に倒立できるようになった。
解決して
考えてみると、継承したクラスは親クラスのメンバおよびメンバ関数を持っているとはいえ、書いてある場所は別だから呼び出しには結局時間がかかるのかもしれない……などと思った。検証はしてない。しなければとは思うが、してない。したら載せようと思う。
でも、もしわかる方いたら教えてください。