最小構成のモデルベース開発事例 バックナンバー

最小構成のモデルベース開発事例 バックナンバー 事例

はじめに

第2章のバックナンバーはこちら。

A/D、D/Aだけを持った装置にPID制御を載せるという最小構成の制御ユニットをモデルベース開発に則って開発するという事例のお話。

途中からインターフェースがA/D、D/AからCANに変わるという、
とんでもない仕様変更をくらう若干事実っぽいエピソードも入る。

参考書籍等

モデルベース開発とは?

なぜか、日本語Wkipediaだとモデルベース開発がモデル駆動開発へリダイレクトされる。
英語版のWikipediaを張っておく。
https://en.wikipedia.org/wiki/Model-based_design

Model-based design - Wikipedia

モデルベースの設計(MBD)は、複雑な制御、信号処理、および通信システムの設計に関連する問題に対処する数学的および視覚的な方法。これは、多くのモーションコントロール、産業機器、航空宇宙、および自動車のアプリケーションで使用される。モデルベースの設計は、組み込みソフトウェアの設計に適用される方法論である。

Wikipedia(英語)のModel-based designの日本語訳(https://en.wikipedia.org/wiki/Model-based_design)

仕様書編

背景、目的

  • 仕様書等の開発ドキュメントは大きい話から書いていく
    • 背景、経緯、目的など。
  • 背景、経緯、目的は形式的なものではなく、ドキュメントの誤認識を抑制する仕掛けの一つ。

物理構成

  • 仕様も大きい話から書いていく。
  • まずは物理構成の開発対象の外側も含んだ構成。
  • 次に開発対象の内部の構成。

論理構成

  • 論理構成を考える際は物理値変換部と制御に分けた方が良い
    • 物理的な制約と仕様の切り離しができ、移植性とシミュレーション可能性が引きあがる効果がある。
  • 早期検証を考えることで品質保証リスクを下げる仕掛けを考えておくとよい。
    • 当然、関係者との調整は必要になる。
    • よって、説得材料等もそろえておいた方が良い。

物理値変換

  • 外部委託する際/される際は何かしら明確な検収要件を決めるべき。
    • 特に実環境が容易に手配できない場合は、大体手段を用意する必要がある。
  • アクセル開度のように安全性に関わる部分は多重化していることが多い。

制御モデル

  • PID制御は位置型速度型がある。
    • 位置型はワインドアップの課題を抱えている。
    • 速度型はワインドアップの課題を解消しており、使い勝手が良い。
  • ソフトウェアで実現するには離散化が必要。

離散化

  • 離散化はテイラー展開を応用して実現している。
    • テイラー展開に\(f(t)=f(t0+Δt)\)の制約を掛けると式が単純化される。
  • 総和法、差分法は初歩、テイラー展開は原理、そのあとに離散化の基礎。
    • 初歩の後に原理、原理の後に基礎を押さえておくと良い。
  • 総和法、差分法はテイラー展開の第2項までを使用した式がベースになっている。
    • よって、第3項以降が誤差となる
  • 使用する項数を増やせば制度は上がる方向になる。
  • 仕様上は3項までを想定、運用では2項までということが良くある。
  • テイラー展開第3項までを使用した積分近似手法は台形法と呼ばれる。
  • テイラー展開第3項までを使用した微分近似手法は中心差分法と呼ばれる。
    • \(f(t0+Δt)\)で解いたパターンだと前進差分法。
    • \(f(t0−Δt)\)で解いたパターンだと後進差分法。
  • 数式を解く場合は、「絵を描けるか」という観点で解くと迷わなくて良い場合がある。
    • 納得もできるし、説明もし易い。

離散化の話で3回に渡ったんで、それのまとめ。

  • ぶっちゃけ総和法と差分法だけ知ってればOK。(初歩)
  • しかし、それらの向こう側も知っておく必要がある。(原理)
  • そして、知った上で不要と判断して意図的に捨てる。(基礎)

という感じのアプローチを意識できていれば、
変に初歩で止まって応用が利かないということは起こりにくくなる。

PID離散化

  • 速度型PIDの復習。
  • PIDの積分を総和法で、微分を差分法に置き換えた。
  • \(Δt\)は制御周期。
    今回の場合は\(10[ms]\)。
    ・ワインドアップ対策は積分要素に切り替えスイッチとサチュレーションを含めることで対応。

制御対象

  • 制御対象はおおよそ一次遅れ系で表現できることが多い。
  • アクセル開度と一次遅れ系の関係性を持っているのは出力。
  • 出力(仕事率)から車速が算出できる。

制御対象離散化

  • 積分要素には基本的にはサチュレーションを入れた方が安全。
  • 物理量を算出する際は基本的にはSI単位系だが、制御として必要な単位はその限りではない。
    • よって、単位変換が必要な場合がある。

フィルタ

  • ノイズは様々な種類があり、設置場所や扱う信号によって異なる。
  • 複数のノイズ対策をソフトウェアで実施するとリアルタイム性が犠牲になることがある。
    • よって、適切なフィルタアルゴリズムが無いか調べる必要が出てくる。

上流検証編

MILS

  • 離散化済みであれば、ExcelでもPID制御のシミュレーションは可能。
    • ただし、かなり面倒くさい
    • MATLAB/Simulinkが無い時代は恐らくこういった面倒なことをやっていたのだろう。
  • 制御器と制御対象をつないでMILSにすることができる。
  • SignalBuilderを使ってテストパターンを作れる。
  • わざと問題のあるモデルと比較すると、今回の対策の効能が見えるのでやってみると良い。

ACG(自動コード生成)

  • SimulinkCoderを使ってSimulinkモデルをACGできる。
    • SimulinkCoderを使用するためにはMATLAB Coderのライセンスも必要。
  • ACGされたコードは可読性が良くない場合がある。
    • プロタイプの段階では、一旦可読性は無視するという選択もあり。
    • リコードする場合は別の手段で品質担保することを考える必要がある。

SILS

  • CコードをS-Function化することでSimuklinkブロックとして扱えるようになる。
    • MILSの一部を差し替えても同様の動きになるかを確認できる。
    • 元のSimulinkモデルと同一の入力にして出力を比較することで一致性確認ができる。

S-Function

  • S-Function Builderの使い方の説明。
    • これ以外のS-Functionの作成方法もある。
  • Simulinkに抵抗ある人はS-Functionから始めても良いかもしれない。
    • 出力を波形で見れる。
    • 複数のロジックの入出力の簡単な繋ぎ替えができる。

プラントリアル化

  • プラントモデルの精度を上げるためには本物の動作特性が必要。
    • 一次遅れ系を使っている場合、時定数と定常ゲインが重要。
  • 立ち上がり時定数と立下り時定数が異なる場合がある。
    • プラント出力の偏差を見て切り替えるような仕掛けが必要になる。
  • 出力(仕事率)と速度の関係は質量が確定していれば算出可能。
  • 最大速度が確定していれば、定常ゲインが算出可能。

PID振動対策

  • 時間も調整可能パラメータの一部と考える。
  • さらに時間の単位も調整可能のパラメータと考えられる。

可変周期PID

  • \(Δt\)をパラメータとして扱うことができる。
    • これにより、PIDの駆動周期が可変でも対応可能。
  • \(Δt\)と駆動周期が同時に変化するので、数学的には通常のPIDと同一と言える。
    • 総和法、差分法による誤差分があるため完全一致とはいかないが、ほとんどの制御では問題なく動作する。

ネットワークMILS

  • 制御とインターフェースを分けたことで、インターフェースだけを差し替えるということは可能。
    • だたし、簡単かどうかは別問題。
  • Simulinkモデルがあればラピッドコントローラで疑似的なECUを作ることは可能。
    • CANに限定するならば、車載ネットワークシミュレータを使用することも可能。
  • CANはマルチマスタなネットワーク。
    • しかし概念上は個別の信号線を模しているだけ。
  • CANをうまく利用するためにはネットワーク構成を明確にする必要がある。
    • ノード、CANID、シグナル。
  • CANoeでネットワーク構造を定義するにはdbcファイルを作成する必要がある。
    • dbcファイルはCANdb++で作成。
  • ネットワーク定義はノード、メッセージ、シグナルの階層構造になる。
    • ノードにメッセージをぶら下げる。
    • メッセージにシグナルをぶら下げる。
  • dbcファイルがあると、「モデル生成ウィザード」でCANoe上に自動でネットワーク構築できる。
  • 「シミュレーションバス」であれば、実際のCAN回線につなぐ必要はない。
  • ノードパネルでシグナルの値を手打ちで変更可能。
    • 本格的にテスト利用するにはCAPL言語を使用した方が良い。
  • CANoeに組み込むSimulinkDLLを作成するにはSimulinkCoderとCANoeのMATLABコンポーネントが必要。
  • Simulinkモデルの入出力にCANoe IOのSingnal Input/Outputを接続してSignalを読んだり更新したりできる。
  • SimulinkDLLはCANoeの各ノード毎に設定できる。
  • dbc、モデル生成ウィザード、SimulinkDLL、シミュレーションまでの流れを復習。
  • そしてやっと動かした!
  • あとは徐々に本物と差し替えたりすると応用の幅が広がる。

ネットワークRAPID

  • ダミーの信号を作る際は、普通はラピッドコントローラを使用する。
  • 時間精度がそれほど求められないのであれば、PCから制御するタイプでもある程度なんとかなる。
  • 正直言うとまずはMicroAutoBox使った方が良い。
    • すでに精度や性能の見積が出来ているのであれば、費用対効果を意識しだしても良い。
  • プログラマブルな振る舞いの場合、MATLAB Functionブロックを使用した方が楽な場合がある。
    • 可能であれば、StateFlowの利用も検討しておくと状態の見える化が出来て吉。
  • Simulinkモデルだけでは正しい保証は困難。
  • テストパターンとテスト結果もセットであれば、最も正しい仕様書になる可能性は高い。
  • SimulinkDLLの出力を2つのシグナルに渡すには2つの手法がある。
    • Signal Outputブロックを2つ使用。
      システム変数に書き込んでからCAPLで各シグナルへ分配。
  • 複数の回線のシグナルを扱うにはゲートウェイノードを定義する必要がある。
    • SimulinkDLL、CAPLのどっちを使うにしても同様の対応が必要。
  • SimulinkモデルからCANoeのシステム変数に出力する場合はSystemVriableOutputブロックを使用する。
  • CANoeでシステム変数を定義できる。
    • システム変数の型は、扱うシグナルに近いものを選択しておいた方が良い。
  • CAPLはValueObjectというイベントハンドラを起点に処理を走らせる。
  • シグナル更新とCAN送信は別物。
    • シグナルの更新有無に関係なく送信周期を定義できる。
  • CAPLもブレークポイント、ステップ実行などのデバッグ機能は保有している。
    • ただし、シミュレーションバスの時だけ可能。
  • 送信周期はプロットで見るか、CAN回線モニタで確認できる。

Bypass

  • Bypassという実験手法がある。
  • 使用する回線は特に決められていないが、EthernetやCANであることが多い。
  • アルゴリズムが確定しておらず、試行回数を増やす場合にとても有効な手法。
  • Bypassの標準的実現手段としてASAM XCPがある。
  • XCPの物理層はCAN/CAN-FD/Ethernetなど多岐に渡る。
  • Bypassを効率的に実現するにはSTIM、DAQの知識があった方が良い。
    • Bypass対応ツールもXCPの知識が前提となる設定項目が多い。
  • XCPonEthernetはヘッダ、パケット、テイルの三つ組み構成。
  • CTOパケットはPIDとDATAだけの構成。
  • CTOパケットはCMD、RES、ERR、EV、SERVの5種類。
    • 基本的にはCMD、RES、ERRだけ知っておけば良い。
  • DTOパケットのパターンは4パターン。
  • TimeStampフィールドのパターンも4パターン。
  • 使用する物理層で使用できるデータ領域に依存しておおよそ2パターンに集約される。
    • 最小構成版と最大構成版の2パターン。
    • しかし、CAN-FDの台頭に伴い、中間のパターンが乱立する可能性あり。
  • CMDだけでメモリの読み書きはできる。
    • その場合、MTAという概念が重要になる。
  • メモリダンプに向いたUPLOAD、DOWNLOAD。
  • リアルタイムモニタに向いたSHORT_UPLOAD、SHORT_DOWNLOAD。
  • DAQ、STIMは事前にアドレス、サイズの情報をツール、ECUの間で共有する。
  • DAQはECU内の制御周期直後のタイミングで送出されるため常に更新後の最新値を効率的に得られる。
  • STIMの送出自体はイベントと同期している必要はないが、実際に更新されるのは制御周期の直前。
  • Bypassを実現するにはMCツールが必要。
    • MがMeasurementで計測。
    • CがCalibrationでキャリブレーション。
  • MCツールの代表格にETAS社製INCAとVector製CANapeがある。
    • どちらが良いということは無く、使用実績から選択した方が良い。
  • CANoeとCANapeは全く別のツール。
  • A2LファイルがあるとXCP関連の設定を省ける場合がある。
    • 通常はA2Lファイルがあるので、XCP関連設定は気にしなくて良いことが多い。
    • プロトタイプの段階ではA2Lが無いことがあるので、無い場合はXCPの仕様を見ながら一つ一つ設定していくことになる。
  • CANapeでXCPonEthernetをする場合はデバイスタイプはXCPを選べばOK。
    • 設定を進めて行くと、トランスポート層の選択でEthernetが出てくる。
  • A2Lはデータベースファイルという名称で記載されている。
  • A2Lはビルド毎に自動更新させることが可能。
    • ビルド、リプログラミング、計測がシームレスに実施できる。
    • よって、本来であればA2Lを最大活用する方針の方が正しい。
  • CPにもversionが存在する。
    • 最も基本的な構成はversion1.1。
  • ブロックモードを使うとCMD効率的に動作する。
    • しかし、今回は使わない。
  • シードキーを使うとセキュリティロックが掛けられる。
    • しかし、今回は使わない。
  • MODIFY_BITS、SHORT_DOWNLOAD、SHORT_UPLOAD等はデフォルトでは無効になっている。
    • ECU側が対応しているならば、効率化するために有効化しておいた方が良い。
  • DAQリストを駆動させるイベントの定義が必要。
  • DAQリストタイプはStaticDAQとDynamicDAQの2種類がある。
    • 今回はDynamicDAQ
  • トランスポート層はEthernetとしての設定。
    • デフォルトではCTRがオフになっているので、オンに切り替える。
  • XCP設定だけをもったA2Lを参照。
  • このA2Lがあれば、XCP設定はスキップできる。
  • このA2Lがあれば、CANapeからINCAへ移行も一応できる。
    • 100%問題無いとは言い切れないが。
  • ASAP2 Studioで読み書き用の変数定義ができる。
    • 本来はmapファイルから設定する。
  • A2Lの中には使用されていないパラメータも存在する。
    • ResolutionとAccuracy。
  • A2Lで変数定義ができれば、CANape上の計測対象設定は比較的簡単。
  • DAQ計測をする場合は計測設定でCyclicを指定しておく必要がある。
  • パラメータWindowに登録した変数は書き換えが可能。
    • STIMに対応していればSTIMで、対応してなければDOWNLOAD、SHORT_DOWNLOADで書き換えとなる。
  • CANapeでは計測対象の変数以外にCANape内でのみ読み書き可能なグローバル変数が定義できる。
    • 関数エディタから追加編集可能。
  • SimulinkにCANapeIOブロックを繋ぐことでCANapeと連携可能なDLLが作成可能。
    • CANoeと異なり、CANapeIOの変数名はCANapeと合わせる必要はない。
    • しかし、合わせておいた方が楽ではある。
  • グローバル変数をモニタすることが可能。
    • SimulinkDLLの動作確認だけであれば、グローバル変数で見た方が問題が起きた際の実機との切り分けがし易い。
  • やっとBypass実施。
  • いままでの内容を振り返った。
    • 一連の流れを大きく把握していれば、ツールが変っても適応できる。

ドライビングシミュレータ(CARLA)

  • いつもの小芝居でスタート。
  • オープンソースドライビングシミュレータのCARLA。
    • 自動運転のトレーニング用。
    • 車両だけでなく人も動かせる。
  • CARLAはPythonAPIを使ってPythonから制御できる。
  • PythonはDLLを呼び出すことができる。
    • よって、C言語書かれたPID制御をPythonから利用する場合はDLLにした方が良い。
  • CARLAはWindows向け環境はある程度揃っている。
    • とりあえず、動かす場合はmanual_control.pyがお手頃。
  • CARLAのサンプルのmanual_control.pyに制御を組み込む際はKeyboardControlクラスの_parse_vehicle_keysメソッドあたりに突っ込めば良い。
  • 車速はworld.player.get_velocity()で取得可能。
    • ただし、3次元ベクトルで取得されるのでノルムに変換する必要がある。
  • PythonAPIを叩きすぎると重くなる。
    • Sleep関数等を使用して処理の頻度を下げることで回避可能。
  • ID制御が弱い場合、PゲインかIゲインを調整するのが一般的。
    • しかし、今回はそもそも想定周期が異なっていた。
  • 時間の刻み(タイムスタンプ)が明確であれば、前回値との差で時間差が特定できる。
    • この時間差を積分単位時間としてPIDの演算に組み込むことができる。
    • (無事、伏線回収!)
  • CARLAにPID制御を組み込めた。
  • 自動車業界で自動運転以外でもPythonの使いどころは多い。
    • 自動テスト環境の一部とか。
  • コスト構造を意識すると問題点が見えやすい。
    • これにより何に対して創意工夫をすれば良いかが分かる。
  • ご拝読ありがとうございました!

第2章

第2章のバックナンバーはこちら。

コメント

タイトルとURLをコピーしました