動的テストとは、テスト対象の実機上でプログラムを動かして、ソフトウェア処理の動きを見える化する、グレーボックステストのテスト手法です。
言葉を聞いたことがあっても、どのように実施するテストなのか、どんな効果があるのか、ツールの導入には手間が掛かるのか、など多くの疑問を持たれる方もいらっしゃるのではないでしょうか。今回は弊社のプロジェクトを例に、「動的テストツール DT10」を使って、何ができたのか、どのような効果を上げたのかご紹介します。
新人が先輩とチームを作り、ライントレースカーを一から開発し、ソフトウェア開発技術を競う”若手の晴れ舞台”とも言える弊社恒例のロボコンレース。エンジニア1年生の私が「動的テストツールDT10」を使ってみた成果、そして、レースの結果はいかに・・・。
ハートランド・データのロボコン
こちらがロボコンレースのビギナーコースです。よこ約 4.4m、たて約3.2mのシート上に幅2㎝のラインが引かれたコースで、S字カーブあり、ブリッジあり、シケインありで、ビギナーコースといっても、車を上手く制御しないとコースアウトしてしまう、完走も難しいコースです。このコースをライントレースで1周し、そのタイムを競うのが弊社ハートランドのロボコンです。ちなみにエキスパートコースは、スタートシグナルの画像識別による自動スタート、車庫入れや障害物の回避など、さらに難しいソフトウェア制御を必要とするコースで、未だに完走したものはいません。
ロボコンカーのメインユニットは、”Raspberry Pi 3 Model b+” 。この通称ラズパイを使用すること、決まった予算内で製作することがレギュレーションです。ラズパイを搭載した実際のロボコンカーがこちら!車体設計と製作は、頼りになる先輩にお任せしました。先輩みたいに、安定感のあるガッチリした車体です。
こちらのロボコンカーの主なソフトウェアの要件は、以下の2つです。
1.5つのフォトセンサーからの電圧値の取得(SPI接続したA/DコンバータICで、1chずつ電圧値を取得)
2.駆動部の2つのモーター制御(PWM制御)
個々の処理は、マイコン開発の評価キットのテキストやネット上の情報で実現可能ですが、この2つの要件を組み合わせて、どのようにリアルタイムな制御をすれば良いのか・・・先輩、助けてください。
ロボコンカーをどのようにデバッグするか?
ソフトウェアの実装は、先輩とペアプログラミングを行い、処理の雛形を一緒に作成することにしました。センサーで検出した値をすぐにフィードバッグして、モーターの制御に反映させるバランスやリアルタイム性を要するソフトウェア処理に対して、どうやって動作確認するのが良いか?という問題がありました。また、良い速度で、カーブを上手く曲がり切れるには、地道なチューニング作業が必要になることを想定していました。
動作確認としては、検出したセンサーの値が見たい。実際にロボコンカーを走らせながら、センサーの値に応じたモーター制御ができているかを確認したい。プログラムを動作させた時の内部情報とそれによる外部動作をリアルタイムで確認できる”動的テストツール”を使う時が来ました。システム全体の動きを見て、どこが問題ありそうかを把握したい。先輩も業務で忙しそうなので、デバッグ時の解析ログを後で見てもらって、アドバイスをもらえるような開発スタイルで進めたいと思い、「DT10」を使う事を考えました。ついでに、Linux機器へのDT10導入も初めてになるので、勉強の目的も兼ねて、チャレンジしてみました。
DT10のセットアップ
DT10では、printf文でのデバッグ手法と同様に、テストポイントと呼ぶテストコードを挿入します。テストポイントは、自動挿入できますし、削除も容易なので、エディタ上でprintf文を出し入れするよりも、カンタンで、コードの書き間違いも少ないです。
テストポイントの情報は、ターゲットのI/FからDynamicTracer(DT10のハードウェア)あるいはPCへ出力する必要があります。この処理をドライバと呼び、 これをターゲットに組み込む必要があります。ドライバは接続方式やターゲットのOSごとにサンプルが提供され、出力するためのアルゴリズムはすでに実装されているので、導入もカンタンです。ターゲット用の開発統合環境にサンプルドライバを組込み、コンパイルして、ターゲットに書き込むだけです。今回ロボコンカーで使用するラズパイには、無線LANモジュールが搭載されているため、Ethernet接続でトレースデータを出力させる方式を採用しました。 これにより、ロボコンカーを実際に走らせながら、デバッグができるようになります。
ドライバはソースコードとなっており、Ethernet接続方式では、IPアドレスの指定を変更するだけで、DT10でログ取得ができました。ソースコードベースということで、ターゲットや使い方に合わせて最適なカスタマイズが可能です。DT10のユーザー様では、私と同じ新人エンジニアの方が、重要度の低いログを自動で間引いて、不具合解析作業の効率化を実現させたドライバを独自にカスタマイズした事例もあります。 (活用事例の記事はこちら)
ロボコンカーの動きをDT10で動的解析
実行経路を解析する
ひと通りの実装が完了したところで、DT10を使ってソフトウェアの全体的な動作を確認・解析していきます。まずは実行経路を確認します。センサーから値を取得する処理、そして、モーターの制御を行っている処理をそれぞれ確認していきます。
DT10では取得したテストレポート(トレースログ)が、上の図のように表示されます。実行経路のリストは、どのファイルのどの関数のステップを通過したのかを示して、該当のコードも同期表示するため、ステップごとにコードを読み進めることが可能です。また、マルチスレッドの解析にも対応するので、それぞれのスレッドの処理ごとに色分けして、確認しやすくしました。さらに、実行経路は以下のビューのようにスレッドごと、関数ごとにその遷移をグラフ表示するので、どのタイミングで処理が切り替わったかを俯瞰できました。
これらのレポートをもとに、先輩にデバッグ結果をレビューしても良いのですが、先輩が以前に開発した解析補助ツールもあえて使ってみました。エクスポートしたDT10のトレースログを解析補助ツールにインポートすることで、コードの中身とその通過・未通過情報を可視化できます。先輩の理解が早いのか?ツールが良いのか?とてもスムーズにレビューが進められました。
処理時間を解析する
次に処理時間に目を向けます。センサーからの出力電圧を取得する処理は、5つあるセンサーの値をA/Dコンバータを使って、逐次取得しています。そのため、5つすべての値を取得したうえで、ロボコンカーが、ラインに対してどの方向を向いているかを判定し、その判定結果をもとにモーター制御処理を行います。5つすべてのA/D値の取得処理を待つため、モーター処理を行うスレッドは暫定的に決めた時間でディレイさせました。ここでは、5つのセンサーから値を取得するまでに、どれくらい実行時間になるのかをDT10で計測しました。
DT10で計測した時間をヒストグラム表示すると、センサーから値を取得するためには、平均5.5ms程度、バラツキもあり、最大値は7msを超えていることがわかりました。およそ6msあれば処理が完了するので、それより大きいところは無視できると考え、妥当なディレイ時間のあたりをつけられました。
ここまでの解析結果が得られるまでに、ロボコンカーを走らせたのは、実はたったの1回だけ。
従来あるprintf文の手法であれば、テストコードの書き換え、時間測定用の処理の追加が頻発しています。DT10では、テストポイントをカンタンに設定できて、1回のテスト実行でも、あらゆる解析情報を出力してくれるので、新規開発の立ち上げには、とても効果的に思います。とりあえず走るものは、すぐに出来あがりました。レース本番でも、今回の立ち上げみたいに、ロケットスタートできればいいのですが・・・。
正常時と異常時の変数値比較
さらに、ある環境下において、なぜかロボコンカーがコースアウトしてしまうという現象が発生しました。カーブをうまく曲がれた場合と、コースアウトしてしまう場合で、DT10で取得した経路情報や変数値を比較してみます。プラグインツールの”DT-TREx”(下図)で、2つのトレースログを比較し、経路や変数値の差異ある箇所を緑色で識別できます。変数値が異なるためすべて色が塗られている・・・!?
こうして、正常時と異常時で、変数値が全く違う事がすぐに判明しました。センサーから取得したA/D値で、正常時は2600、ある環境下では2400に対して、ラインを判別で設定していた閾値は、2500。つまり、ある環境下では、期待どおりのライン判別ができていなかったのです。また、ラインを判別できなかった場合に、モーター制御処理も適切でないことも分かりました。
いよいよレース本番
いよいよ本番です。スタートすると、スムーズに走行していた練習のときとは違って、少し動きがぎこちない気もしますが、コース中盤まではイイ感じで走っています。ひょっとすれば優勝かも・・・!と思った矢先、カーブを曲がらずにコースを外れ、ラインを探してる素振りを見せるも、しばらくして停止・・・。こうして、僕たちの春が終わりました。
わがチームは、コースアウトで記録無し。くっ、悔しい!悔しすぎます。練習ではスムーズに走破していたロボコンカーに何があったのか・・・
はい、実は上記の「正常時と異常時の変数値比較」における「ある環境」とは、本番の環境のことなんです。なんと、コースアウトの原因であるセンサーのA/D値のズレは、練習と本番での照明の明るさの違いでした。
その場で、練習中のトレースログと本番のトレースログを比較して、チューニングをした上でもう一度走れたら、絶対に優勝していたに違いありません。
やはりDT10のような「ものさし」を持つこと、そして運用テストの重要性も身にしみて感じました。
まとめ
本番はとても悔しい結果になりましたが、組込み開発経験の浅い私でも、自分で書いたソフトウェアの動きをDT10で俯瞰したり、詳細を確認したりして、問題を解決することができました。目で見てわかりにくいもの、説明しにくいものを見える化するDT10という「ものさし」があることで、先輩とのレビュー、デバッグや不具合の解析がスムーズにできたように思います。今後のプロジェクトにおいても、事前にどうやって開発作業を進めるかを良く考えることや、開発現場の様々な場面でDT10をどのように活用するかを考えて行きたいと思います。
14日間の無料トライアル実施中!
動的テストツールの使い勝手をお客様の開発環境で評価いただける、14日間の無料トライアルを実施しております。ぜひ、DTシリーズの使いやすさ・多彩な解析機能をお試しください。