【用意するもの】
Raspberry Pi3 Model B(LCDディスプレイは別でも込みでもよいので用意する)
- Micro SD カード(キットに含まれている場合もある)
- 電源コードやHDMIケーブル、USBマウス、キーボードなと(キットで購入してもよい)
- Windows PC(OS は7か10)
【参考書籍】
Windows の環境を整える
Qtの環境を構築するにはこちらの記事『(Windows)Qtの開発環境を構築(Qtのインストール)』を参照して欲しい。(インターネット環境だと多くの有益な記事を参照できるのでありがたい)Visual Studio 2017 Community版はこちらのサイトからダウンロードできる。
※Visial Studio 2017 Community版 をインストールするには数時間かかる場合があるので注意が必要。
vs_Community.exe を実行する。左記のメニューが表示されるまで 5~10分くらい。
左記のメニューを選択しインストールする。
インストールが完了するまで約1時間かかる。
※Visual Studio 2017 Community版 は試用ならば一ヶ月使える。Microsoft のIDを取得(無料で個人で作成することは可能)してログインすれば,ずっと使い続けることができる。
次に Qt の Windows版をインストールする。Qtには有料版と無料版があり、無料版はLGPLのライセンスによる使用制限があるが、今回のアプリ作成には無償版で十分に対応が可能。
基本,こちらのサイトのインストール手順に従う。Raspberry Pi3には Qt 4.x をインストールするが、Windows版では Qt 4.x のインストールはもうできないので、Qt 5.x をインストールする。(互換性はあるので問題はない)
Qt はパスに日本語が含まれるとコンパイルが上手くいかないので,インストール先は C:\Qt などのフォルダにインストールし,その配下で作業すること。
下記は Qt 5.10.0 を Windows 7 のPC にインストールしたときのコンポーネントの選択例
<選択が必須なコンポーネント>
- Qt Creator 4.6.0-rc1
- Qt 5.10.0
- MSVC 2017 64-bit
- MinGW 5.3.0 32bit
- Tools
- MinGW 5.3.0
なお,Qt はインストール後も Qt Maintanance Tool を使って,コンポーネントの追加,削除,更新を行うことができる。
Windows 7 64bit にインストールした Qt の「ビルドと実行」の設定内容。
ビルドと実行で、コンパイラを CとC++ ともに MinGW 32bit を設定する。
Raspberry Pi3 へQt をインストールする
Raspberry Pi3にRaspbianをインストールする。この手順については入門書を参照するか、インターネットで探す。基本はwww.raspberrypi.org のダウンロードサイトからNOOBSをダウンロードし、フォーマットしたSDカードにコピーして、インストールする。
Qt の最新バージョンは Qt 5.10 だが,Raspberry Pi向けの install イメージが配布されていないため,確実にインストール可能な Qt 4.8 をインストールする。(Qt 5.x のソースを Raspberry Pi上でコンパイルする方法も Web上で示されているが上手くいかなかった。)
Qt 4.8 インストール手順(※参考リンク)
① Raspberry Pi3上のコマンドラインから Qt4関連のソフトウェアをインストールする。
-------------------------------------
sudo apt-get install qt4-dev-tools
sudo apt-get install qtcreator
sudo apt-get install gcc
sudo apt-get install xterm
sudo apt-get install git-core
-------------------------------------
②QTCreatorを起動してgccのコンパイラーを追加する。
Tools/Options >ビルドと実行 > コンパイラ > 追加 > (GCCを選択)
また、コンパイラのパスの参照で/usr/bin/arm-linux-gnueabihf-gcc-6に設定・適用する。(C++ も C も gcc 6 を設定する)
左記はC++ のコンパイラを手動でgcc 6 に設定した様子。
③QTCreatorのビルドキットを設定する。
Tools/Options >ビルドと実行 > キット>コンパイラをGCCに選択・適用する。
④ Qt Creator で新規プロジェクトを作成し,空の状態でコンパイル,実行してエラーがないことを確認する。
その他 Qt に関する使用手順の解説はこちら
今回のシステムのデモ動画(5インチLCDで動かしたもの)はこちら
クロスプラットフォーム開発環境について
大規模で複雑化したソフトウェアをゼロから開発するのは無理がある。Windows ベースのリッチなGUI(Graphic User Interface)を実現するには,グラフィックライブラリやソフトウェア開発のプラットフォームが必要で、開発の大部分をWindows PC上で行い,実装は Raspberry Pi などのターゲットボードにというスタイルが効率がよい。
一般にはWindows と Linux , Mac OS では GUI に互換性がない。
しかし、Qt は Windows , Linux, Mac OS などの OS,プラットフォームに依存することなく,GUI アプリケーションソフトウェアを構築することができる。
Qt はライセンス条件を満たせば,無償で利用することが可能。
Qt(キュート)について知りたい場合は商用のライセンスを提供している SRA のサイトを見るとよい。マルチプラットフォーム開発の有効性などが解説されている。
Qtでできること
- WindowベースのGUI をQt Creator を使って,簡単に設計できる。
- Qt Creator で作成した 部品をアクセス(例えばクリック)したときに起動するソフトウェアを書くのが簡単。
- 複数のソフトウェア(例えば,アナログ信号の取り込みと波形の描画)を並行して動作させるマルチスレッドを実現できる。
ただし、Qt は C++で書かれており,C++ を理解していなければ,Qt を使いこなすことはできない。
プログラミング言語の系譜についてはこちらを参照してほしい。
Qt を使わないと 自力では難しいこと
- マルチスレッド処理
- 複数のスレッドをmsオーダーで正確に起動させることは難しい。
- スレッド間の同期や連携,データの受け渡しが Qt がないと難しい。
- 波形描画
- リアル波形描画は Qt に Customplot を追加することで比較的簡単に実現することができる。
- GUI と C++ アプリとの連携
- GUI と C++ アプリを連携させる方法は通常 OS に依存するが,Qt を使えば,OSの違いを意識することなく,連携させることができる。
Microsoft Visual Basic でもあらかじめ用意された各種のGUIパーツを配置して、それらのプロパティが変更されたり、マウスでクリックされたりするなどイベントが発生した場合の処理を記述してゆくことでアプリケーションプログラムを作成することができが、それは Windows OS上だけのことだ。
しかし、Qt はそれと同等のことを OSに関係なく(Windows, Linux, Mac OS)できる。また、GUIのイベントの発生から、イベントをトリガーにして指定したメソッドへキックするしくみは、Qt でコンパイルする過程の中に隠蔽されるため、アプリケーションの作成者は特定のボタンがクリックされたときに飛んでくるので、該当するメソッド(関数)の中身を書くだけでよい。
mainwindow.h に構築された関数定義の例
private slots:
// Run/Stop ボタンを押された時の処理
void on_pbt_run_clicked();
// 波形タイプボタンを押された時の処理
void on_pbt_wavetype_clicked();
// 電源ノイズフィルターボタンが押された時の処理
void on_pbt_ac_line_filter_clicked();
// ドリフトフリーフィルタボタンが押された時の処理
void on_pbt_drift_free_filter_clicked();
// ハイカットフィルタボタンが押されたときの処理
void on_pbt_hicut_filter_clicked();
// 表示感度ボタンが押された時の処理
void on_pbt_displaygain_clicked();
// 入力ソースボタンが押されたときの処理
void on_pbt_input_type_clicked();
// 周波数スピンボックスの値が変化したときの処理
void on_doubleSpinBox_frequency_valueChanged(double arg1);
Qt のこのしくみは Signal/Slot の関係を使っており、その概要については、以降の記事で説明したい。(各種 Qt の解説書にも詳しく書かれている)
現在の Window GUIベースのアプリケーションソフトウェアでは、Window とボタンやダイアログ、テキスト表示領域、ダイヤルやスライダーなどのGUI部品から発生するイベントを受けて、何らかの処理を行い、その結果をまたGUI部品に反映させるといったやり取りの積み重ねとなる。
また、そういったユーザインタフェースを伴うイベントの背後で、ファイルの入出力や定期的なインターバル割り込みイベントなどを処理する。
これらのシステム上の役割を3つのレイヤーで表現したのが、左記のクラス図となる。
一番上のレイヤーは ユーザーインターフェースを担う部分で Presentation Layer となる。
ユーザーが直接インタフェースする部分であるため、この部分の見た目の良さが商品の付加価値となる。また、時代や商品のラインナップによって、変わりやすい、または、変えることで違いをだす部分である。
Presentation Layer を構成するソフトウェア部品は環境が変わる(ディスプレイやプラットフォームが変わる、GUI部品の追加要求があるなど)ことを前提に、汎用的なGUIライブラリが使えるとよい。今回はそれが Qt となる。
なお、プレゼンテーションレイヤーは付加価値にはなるが、また、外から丸見えなため真似されやすい部分でもある。だから、組織のコア・コンピタンスにはなりにくい。商品の付加価値にはなるが、真似されないソフトウェア資産にはなりにくいので、GUIライブラリやツールを使ってさっさとかたづけたい領域である。
一番下のレイヤーは Data Source Layer で、データを取り込んだり、格納したりする役割を担っている。最近の機器は IoTのキーワードが示すように、ネットワークやポータブルメディアの I/F を持ち、それらの機能があるのが当たり前になりつつある。
Raspberry Pi にも最初から LANや WiFi, Bluetooth , USB, SDのハードウェアI/Fが付いており、ドライバや関連ライブラリも用意されている。
このレイヤーも必ず実装はしないといけない部分だが、汎用的なI/F とそれを扱うソフトウェアであるため、真似されないソフトウェア資産にはなりにくい。
なお、今回の事例ではアナログ信号を取り入れるため、その部分のハードウェア、ソフトウェアはコア資産となりうる。信号の取り込み後は、多くの場合、デジタルフィルタなどの二次処理を行う。
それらの二次処理は検証を行う必要があり、検証のたびにいちいちアナログ信号をA/D変換していたのでは効率が悪い。
よって、取り込んだアナログ信号をA/D変換したデータは Data Source Layer を使って、ファイルの保存したり、アナログ信号の代わりにsin波や、疑似データを入力に使ったりしたい。
それをC++の派生を使って実現しているのが、このクラス図となる。入力のI/Fは同じで、いろいろな入力クラスを派生させており、それを切り替えることで シミュレーションでデジタルフィルタの効き具合を確認したのち、アナログ信号をA/D変換したときにも期待された効果が出ているかどうかを確認することができる。
このようなフレームワークが出来上がっていれば、いちいち実機を使わずとも、シミュレーション環境でかなりの検証作業を行うことができる。
そして、もっとも重要なのが真ん中の Domain Layer となる。ドメインレイヤーは、そのドメインに特化したソフトウェア資産を配置する。
ここでは黄色のスレッドとタイマーのクラスを置いた。これらのクラスは Qt にライブラリで提供されているもので、定期的な割り込みを発生させて、インターバル処理を行うために必要だった。リアルタイムな波形処理を行うためには必要なしくみだが、ドメインに特化した機能とも言える。
そして、緑のクラスがこのシステムのコア資産となる部分だ。電源ノイズフィルタや、ドリフトフリーフィルタ、ハイカットフィルタは、信号処理の二次処理として必要なフィルタだが、そこにノウハウがある。だからこそ、今回の教育素材ではスケルトン(I/Fだけが用意されており、中が空)にしてある。そこはがんばって作成して欲しい。
心拍を検出するクラスもコア資産だ。その部分の性能を高めるには、多くのデータを通してみて最適なアルゴリズムを検証する必要があるだろう。それを実現することができれば、他社に真似できないコア・コンピタンスになる。
この3つのレイヤーのうち Domain Layer はもっとも寿命が長く、組織の利益の源泉になる資産である。
一方、Presentation Layer と Data Source Layer に配置されたソフトウェアは、商品の付加価値としては必要で、それがないと競争には勝てないのだが、時代や環境、ユーザーの要求とともにどんどん変わっていく宿命もある。
変化に対応が可能である必要があるということだ。ユーザーインターフェースは時代とととにリッチになっていくので、GUI部分のソフトウェアは効率よく開発できる環境を持っていたい。そのためには、GUIライブラリが必要であり、今ではGUIライブラリの多くはオブジェクト指向言語で提供されている。
データの入出力も同様にLAN, WiFi, Bluetooth, USB, SD などの I/Fが当たり前になっている現状では、それらのI/Fを必要に応じて使いこなせるプラットフォームが欲しい。
組込みソフトウェアアーキテクトが意識すべきは、この3つのレイヤーの役割、寿命、ソフトウェア資産としての価値の違いである。
その違いに応じて、必要なソフトウェア開発環境を用意し、効率がよく、かつ、商品群としての価値を最大に高めるアーキテクチャを用意する。
それができれば、デスマーチではなく、ユーザーに満足してもらえるクリエイティブな商品開発ができると思う。
P.S.
永年組込みソフトウェアを開発してきたエンジニアが描くモデルで,実現する機能がクラスやパッケージになっているものをよく見かける。例えば,デバイスドライバとか,システム制御とか,データライブラリといったクラスが並んでいると,何がコアコンピタンスとなりうるソフトウェアの再利用資産なのか分かりにくい。
今はそんなに規模が大きくなくても,いずれ訪れるソフトウェアの大規模化を想定して早いうちから組織的に重要となる再利用資産は何か,どれかを見極めておいた方がいい。
そのためにはクラスやパッケージを責務で分割して,その再利用資産が手足として使用するストレージやUIのI/Fは時代とともに変わりゆくものだとして設計する。
それができるようになると上記の 3 Layer にクラスやパッケージを分類することができるようになる。
P.S.
永年組込みソフトウェアを開発してきたエンジニアが描くモデルで,実現する機能がクラスやパッケージになっているものをよく見かける。例えば,デバイスドライバとか,システム制御とか,データライブラリといったクラスが並んでいると,何がコアコンピタンスとなりうるソフトウェアの再利用資産なのか分かりにくい。
今はそんなに規模が大きくなくても,いずれ訪れるソフトウェアの大規模化を想定して早いうちから組織的に重要となる再利用資産は何か,どれかを見極めておいた方がいい。
そのためにはクラスやパッケージを責務で分割して,その再利用資産が手足として使用するストレージやUIのI/Fは時代とともに変わりゆくものだとして設計する。
それができるようになると上記の 3 Layer にクラスやパッケージを分類することができるようになる。
※この記事に紹介した レイアードアーキテクチャについて、より深く知りたい方は『リアルタイムOSから出発して 組込みソフトエンジニアを極める』の3章 再利用の壁を越える をお読みください。
1 件のコメント:
レイヤー分割、ソフトウェア資産の話、とてもためになりました。貴重な知見をありがとうございます。
コメントを投稿