そのような喧噪をよそに、今回も複雑な安全機能に対してエンジニアはどう対処してけばよいのかについて書こうと思う。
さて、前回の記事『ISO 26262との向き合い方 (16) 安全を売りにすることの意味』の冒頭で取り上げた日産自動車が開発したという「緊急操舵回避支援システム」について掘り下げて考えてみる。(公開情報だけで考えているので想像している部分と現実とは違っているかもしれません。ブログでは特定の会社のシステムを評価したいのではなく、安全機能の複雑性について理解を深めたいだけなので、その点、誤解なきようよろしくお願いします。)
緊急操舵回避システムの分析
日産自動車が2012年10月17日に発表した日産のニュースリリース『日産自動車、「緊急操舵回避支援システム」を開発』は、よく読んでみると、まだ市販の乗用車への搭載の予定は書かれていなかった。実用実験の成果を発表した段階ということのようだ。ニュースリリースを読むと、緊急操舵回避支援システムは1台のカメラ、3つのレーダー、5つのレーザースキャナを入力源として使っている。添付されいている資料によると、「前方衝突回避支援コンセプト」と「緊急操舵支援システム」が作動する一般的なシナリオは次のようなものが想定されている。(YouTubeによる動画はこちら。すごいです。)
【前方衝突回避支援コンセプト】
- 対象物を検知・識別する。
- ドライバーに警告を発する。
- 緩やかな減速を開始。
- 衝突に備えてシートベルトをきつく締める。
- コンマ数秒後、システムが衝突回避の限界に近づきドライバーが自力で衝突を回避できないと判断すると緊急ブレーキを作動しはじめ、衝突回避動作を支援する。
【緊急操舵支援システム】
- 対象物を検知・識別する。
- ドライバーに警告を発する。
- 物理的に回避可能な限界に近づきドライバーの操作は不十分と判断する。
- ECUは緊急ブレーキと緊急ステアリングのどちらで対応するかを一瞬で決定する。
- ステアリングが最適な措置の場合ハンドルを切ることが可能な方向をドライバーにモニタで知らせる。
- その直後に必要な操作(緊急ブレーキの作動か、緊急操舵か、それらの両方)を正確に実行する。
記事をもとに緊急操舵支援システムの入力部と衝突リスクを分析判定するECUの関係を図に書いてみた。分析判定のECUはもしかしたら一個ではないかもしれないが、ここはシンプルに一つだと仮定した。
ちなみに、レーダーとは電磁波を照射してその反射波を受信するデバイスで、照射された電磁波は広範囲に広る。一方レーザーは直進性が高く探りたい方向に向けて首を振らなければいけない。だからレーザーの方はスキャニングする必要がある。レーダーよりはデバイスの内部構造が複雑になると想像する。
まず、これらの入力装置だけを考えてもこの安全機能の複雑性がうかがえる。1つのカメラ、3つのレーダー、5つのレーザースキャナはそれぞれ監視するエリアがオーバーラップしてはいるものの、各自持ち場、見張る方向、センシングの方法が異なるので、どれかが故障すると緊急操舵支援システムは期待通りの働きができない。
合わせて9つのセンサを使っていて、どれか一つが故障してもシステムは正常動作しないという状態を FTA で描くと左記のようになる。
どのセンサが故障してもトップ事象の「緊急操舵支援システムのセンサ入力が利用できない」に至るため各基本事象は OR で接続される。
仮に各部品の故障率が 0.0001(1万分の1)だった場合、トップ事象としての故障率は各故障率を足すため0.0009 となり、およそ10倍の故障率にあたる 1000分の1に近づく。
たぶん、現実はそんなに故障率は高くないだろう。1000万分の1くらいかもしれない。頻度の低い使用なら問題ないレベルだろうが、例えば自動車の場合は販売量が非常に多い。10万台売れて100回使えば、トータルで1000万回になる。センサの故障は無視できるレベルではないことが分かる。
なお、故障状態を検出する手段があれば、どれかのセンサが故障した時点で故障状態を表示して修理に出して欲しいとドライバーに訴えることになる。修理をしてもらえば確率は元に戻るから、この足し算は必ずしも現実的とは言えない。また、部品の故障率は自動車のライフサイクルに対して一定であるとも限らない。自動車が生産されて廃棄されるまでの期間が仮に10年だったとして最後の1年がその前の9年と同じ確率かどうかは分からない。部品の故障率がバスタブ曲線状に変わる場合、製造後10年経過したときの「緊急操舵支援システムのセンサ入力が利用できない」確率は上記の確率よりも高くなっているかもしれないのだ。だから、FTAにおける事象発生の確率が一人歩きしないように注意しなければいけない。FTA における確率は目安というか、分析者がどれくらいの故障率を考えているかの程度の意思表示のようなものだ。後述する Systematic Failures や Usability が絡んでくると Random Failures の確率はトップ事象の発生に対して影響が小さくなってくる。(部品の故障に気を配っても、ソフトウェアの不具合やユーザーの誤使用で簡単にトップ事象が発生してしまうようになるということ) FTA における確率は 1/100 か 1/1000 か 1/10000 かくらいのおおざっぱなことを示すことが多いような気がする。(厳密な測定結果に基づく場合もあるかもしれないが・・・)
よって、上記の FTA 図で分析者やレビューワーが認識すべきなのは、9つのセンサがトップ事象に与える影響が同等であるということだ。別な言い方をするとどのセンサが故障しても緊急支援システムの正常動作の障害になるということである。そのリスクを軽減するための手段として、Fault Tolerant (構成部品の一部が故障しても正常に処理を続行するシステム)の構成を考えることはできる。ようするに部品の故障を見越して同じ役割分担のセンサを複数設置するという考え方だ。故障率の低い高信頼性部品に頼らず、標準部品を並列に設置して信号出力の OR を取るという安全設計の方法は故障期間がわずかでもあるとまずいようなシステムで使われている。
このケースでは例えば、前方レーダーが故障したときのことを考えて、もう一つ前方レーダーを設置する。宇宙で簡単に修理ができないときは、そういう選択肢は大いにありうるだろう。しかし、自動車の場合、前述の例のように部品が故障したことが分かれば、ドライバーに異常を知らせ、販売店で修理をしてもらえるので、コストアップにもつながるし、このケースでは Fault Tolerant は採用されないと考えられる。
そうなると重要なのは各センサが故障しているかどうかを正確に判定できるかどうかだ。衝突リスク分析判定ECUに入力される情報だけでセンサの故障が判定できれば一番よいが、センサからの入力だけでは確実に判定できない場合、故障検出のためのハードウェアを追加しなければいけない。
上記のセンサ故障の FTA の図にセンサの故障検出デバイスの故障事象を追加して、トップ事象を「緊急操舵支援システムを故障状態で使ってしまう」にしてみた。センサが故障していても、ドライバーがそれに気がついていればリスクを減らせる。しかし、センサの故障検出デバイスが故障していたら、センサの故障を知らせることはできない。
それなら、センサの故障検出デバイスの故障を検出するデバイスを追加するかと考える。こうやって、リスクコントロール手段は追加すればするほど、リスクが具現化する確率を減らすことができる。(AND接続が可能となるため、確率はどんどん小さくなっていく。)
しかし、リスクコントロール手段を追加するたびにコストは上がるし、システムが複雑化する。システムが複雑になることにより新たな Hazardous Situation が生まれるかもしれない。設計者が恐れるのは前者よりも後者の方だ。アーキテクチャが複雑になるとシステムが完全に動作するかどうかの検証作業も増える。故障検出機能の検証のためには故障状態を再現しなければいけない。完成品ではなかなか再現できないから、劣化の加速試験やシミュレーションが必要になる。シミュレーション環境を準備したら、シミュレーション環境が期待通りに動いているかどうかを Validation(妥当性確認)しないといけない。もう、切りがないのである。
なお、ここまで書いたことは FTA が発明された 1960年代の分析とそれほど変わりはないと思っている。静的な構造ベースでの 故障解析はなんだかんだ言っても有限の場合分けにしかならない。複雑でもいろいろなケースを想定して積み上げていけば、トップ事象を起こさない確率を高めることはできる。
故障の原因が統計的な要因のみ、すなわち Random Failures だけならなんとかなる 。しかし、そこに、Systematic failures や Usability が絡んでくると問題はそんなに簡単ではなくなる。
さきほどは、センサ類の入力側のデバイスの故障について考えたが、緊急操舵回避システムでは「表示灯」「表示装置」「警告ブザー」といった出力系のデバイスも制御しなければいけない。
それぞれの出力デバイスの故障も入力系と同じだが、表示装置となるモニタはもしかするとTVやカーナビと共通で使用するかもしれないので複雑性はさらに増加する。
緊急操舵回避システムでは、緊急時のドライバーがどちらにステアリングを切ればよいかを指示する。その指示をドライバーが実行できないとシステムが判断したときに初めてシステムが自動でステアリングを操作する。
だから、表示装置で方向を指示しなければいけない。カーナビ画面に小さく赤い矢印を出したのでは気づかれないかもしれない。いったん画面を全部消してでかでかと矢印を表示しないといけないだろう。しかも滅多に表示されるものではないから、それが何を意味するのか瞬時に判断できるようでなければいけない。ドライバーが20代でも30代でも40代でも50代でも60代でも70代でも判断できなければいけない。人が絡んだ安全オペレーションを考えるときは、Usability の分析も必要になる。相手が人間になると、統計的な手法の信頼性は低下する。Usability 分析で有効なのは シナリオである。どんなユーザーシナリオを想定したのかを記録しておく必要がある。よく使われるシナリオ、最大負荷となるシナリオを分析段階で記録しておき、それをもとに作ったシステムで事故が起こったら、事故のシナリオを追加して再分析する。人間の行動には一貫性はないから、設計時に想定できないような振る舞いをされることは現実にある。したがって、このフィードバックサイクルを積み重ねることが Usability 起因のリスク対策には有効となる。だから、実戦経験のない機能を初めて市場に出すときは、 Usability 対策が未熟であることはよくある。
さて、緊急操舵回避システムとカーナビとTVで表示装置を共有したのなら、緊急操舵回避システムが他に対して優先順位が高くなければいけないのだが、期待通りに動いていることは誰が検証するのか。カーナビ屋さんが「オレには知ったこっちゃない」と考えていると、思わぬコミュニケーションギャップにより緊急時に画面が切り替わるかどうかのテストが漏れる可能性がある。リスクレベルが高いシステムとリスクレベルが低いシステムでデバイスを共有する場合は、そこにある意識の違いがミスを生む可能性がある。
それはそれとして、緊急操舵回避システムで最も大きな問題は機能の独立性が崩れることだと考えている。
左の図を見てもらいたい。かつて自動車はその基本機能である、ステアリング、ブレーキ、エンジン(加速)の機能は完全に独立していた。
それぞれの機能は他の機能を意識する必要がなく、各機能の信頼性を高めることに集中すればよかった。これはソフトウェアの構造化設計、オブジェクト指向設計の基本である高凝集(High Cohesion)、疎結合(Low Coupling) の状態である。高凝集・疎結合が実現できていると、開発チーム側の役割分担もしやすい。
また、この図で分かるように機能にトリガーをかけるのはすべてドライバーである。それぞれの機能が正常に動作していれば、ステアリングのミス、ブレーキの遅れ、アクセルとブレーキの踏み間違いはすべてドライバーの責任になる。(『ISO 26262との向き合い方 (16) 安全を売りにすることの意味』参照のこと)
その後、ステアリングもブレーキもエンジン・アクセル制御も ECUとソフトウェアが絡むようになって、ブレーキとアクセルが同時に踏まれたときは、ブレーキを優先させるという判定をECU内部で行うようになった。このことは、ブレーキ制御とアクセス制御のECUに間に結合が生まれたことになるが、この程度であれば非常に小さな結合で留まっていると言えるだろう。
それがプリクラッシュセーフティのように自動でブレーキを制御することになるとシステムの中に大きな結合ができてしまう。
衝突回避のための自動ブレーキなら入力はもっと少なくてもよいかもしれないが、それでも衝突リスクを分析・判定するシステムの複雑性は小さくない。
一番の懸念事項は運転手のブレーキ操作、ステアリング操作と衝突リスク分析判定ECUの判断が異なった場合はどうするかだ。
衝突回避のブレーキシステムの場合は、ドライバーがステアリング操作をした場合、緊急ブレーキは動作させない仕様だったと思う。この場合は、上記の図でステアリング制御ECUから衝突リスク分析判定ECUに向かう矢印が一本増える。それによって、ステアリング制御と衝突リスク分析判定機能は結合したことになる。
そして、緊急操舵支援となるとこのように結合度はさらなに強くなる。
ドライバーのハンドル操作やブレーキペダル、アクセルペダルの操作と衝突リスク分析判定ECUの判断が相反したときの問題もさることながら、刻々と変わる状況に対して、センサーからの入力やドライバーの操作、ブレーキかステアリングかといった複雑な判定が必要になる。しかも、その判断は時間毎に変えなければいけないのである。
部品故障に関しても、緊急事態でないときに故障が分かればよいが、仮に衝突回避の直前または回避中にセンサ類に異常が検出されてしまった場合、どのような対応をしなければいけないだろうか。
故障検出が割り込み処理で入ってくるのか、ポーリングなのかによっても状況は変わってくる。衝突リスク分析判定ECUが自分で故障検出デバイスをポーリングするようになっていれば、衝突回避動作中はポーリングをやめればテストケースは減る。(衝突回避動作に入ったらセンサの情報は使わないという設計にした場合)
しかし、割り込み処理だったら、衝突回避中だろうがなんだろうが割り込まれてきて、故障認識時の処理が意図せず動いてしまうかもしれない。衝突回避中だけは割り込みを無視するようなソフトウェア設計にすると、ソフトウェアアイテムの高凝集(High Cohesion)、疎結合(Low Coupling)が崩れてくる。そうなってしまったソフトウェアを完璧にテストしようと思ったら、すべてのタイミングで期待通りの動作するかどうか検証しなければならず、有限の場合分けができなければ永遠にテストは終わらない。
この記事の前半で、静的な構造に関する問題だけならば有限事象なので検証は時間がかかっても収束するといったのはこのことだ。静的な構造の要素だけでなく、時間によって状況が変わる事象を考えなければいけないとなると、シナリオはすぐに爆発し、検証作業が時間切れになる可能性が高まる。
3.11 の後に「想定外を想定する」といったキーワードをよく聞いたが、時間によって状況が変化してしまう場合、想定外はあるという前提でシステムを設計しないと事故は起こってしまう。「想定外を想定する」のではなく、「想定外が起こる前提で最も効果的な安全対策を考えよう」が正しいアプローチだと思う。
ただ、だからといってツールや開発プロセス、各デバイスの高信頼性化だけに着目するのは木を見て森を見ずであると感じる。もっと上位層、要求仕様や安全やリスク分析の中で考えるべき問題、抽象化できない具体的なリスクやハザードに対するリスクコントロールについて考えることが遙かに重要である。抽象論ではなく、具体的なリスクを前にして、そこに対処することがシステムやユーザーの安全への寄与が大きいということを安全設計をするエンジニアは忘れてはいけない。
機器製造業者としては複雑な安全機能を追加しないことによってシステムのアーキテクチャをシンプルにし、テストケースを減らして、システム全体で安全性や信頼性を高めるという選択肢もあるのだ。安全機能を追加しない方がユーザーへの利益が大きいケースはあると思っている。
複雑な安全機能はソフトウェア設計者としてもイヤな感じがするが、安全システム設計者としてシステム全体を見なければいけない立場だったら、そのイヤな感じは増大する。
それは、ソフトウェアの世界で凝集度が低く、結合の強いソフトウェアの集まりが起こす、原因が非常に分かりにくい不具合の数々をこれまで見てきたからそう思うのかもしれない。
そのようなシステムで頭を悩ませてこなかった人たちは、独立性の高いハードウェアを組み合わせることで、多少複雑性が高くなっても、付加価値が高まればよいだろうと考えているのかもしれない。
いったん複雑なシステムを作ってしまうと、予防・是正の取り組みを繰り返しただけでは追いつかない場合がある。変更によって新たな不具合を作り込んでしい、負のスパイラルに陥ってしまう可能性があるからだ。複雑な安全機能にさらなるリスクコントロール手段を追加すると、それによって新しい Hazardous Situation が生まれる。
Random Failures, Systematic Failures, Usability に絡む問題がそれぞれ独立して考えられるのなら、そのようなアーキテクチャを選択した方が絶対にいい。この3つの要素が絡み合うシステムを作ってしまったら、後が大変で、ブログで解決方法を解説するレベルではなくなる。
実際の自動車制御はこんな単純なものではないことはわかっている。だからこそ、独立した機能同士の結合を弱くしておく努力の重要性を感じる。そこを崩してしまうと際限がなくなる。付加的安全機能は際限をなくしてしまうトリガーになるような気がするのである。
どんなに複雑でも、どうせソフトウェアで制御するなら一つの高性能なECUにやらせてしまえという考え方が出てくると、1980年代に医療機器の世界で起こった Therac-25 の事故が、自動車ドメインでも起きるかもしれない。
よって、上記の FTA 図で分析者やレビューワーが認識すべきなのは、9つのセンサがトップ事象に与える影響が同等であるということだ。別な言い方をするとどのセンサが故障しても緊急支援システムの正常動作の障害になるということである。そのリスクを軽減するための手段として、Fault Tolerant (構成部品の一部が故障しても正常に処理を続行するシステム)の構成を考えることはできる。ようするに部品の故障を見越して同じ役割分担のセンサを複数設置するという考え方だ。故障率の低い高信頼性部品に頼らず、標準部品を並列に設置して信号出力の OR を取るという安全設計の方法は故障期間がわずかでもあるとまずいようなシステムで使われている。
このケースでは例えば、前方レーダーが故障したときのことを考えて、もう一つ前方レーダーを設置する。宇宙で簡単に修理ができないときは、そういう選択肢は大いにありうるだろう。しかし、自動車の場合、前述の例のように部品が故障したことが分かれば、ドライバーに異常を知らせ、販売店で修理をしてもらえるので、コストアップにもつながるし、このケースでは Fault Tolerant は採用されないと考えられる。
そうなると重要なのは各センサが故障しているかどうかを正確に判定できるかどうかだ。衝突リスク分析判定ECUに入力される情報だけでセンサの故障が判定できれば一番よいが、センサからの入力だけでは確実に判定できない場合、故障検出のためのハードウェアを追加しなければいけない。
上記のセンサ故障の FTA の図にセンサの故障検出デバイスの故障事象を追加して、トップ事象を「緊急操舵支援システムを故障状態で使ってしまう」にしてみた。センサが故障していても、ドライバーがそれに気がついていればリスクを減らせる。しかし、センサの故障検出デバイスが故障していたら、センサの故障を知らせることはできない。
それなら、センサの故障検出デバイスの故障を検出するデバイスを追加するかと考える。こうやって、リスクコントロール手段は追加すればするほど、リスクが具現化する確率を減らすことができる。(AND接続が可能となるため、確率はどんどん小さくなっていく。)
しかし、リスクコントロール手段を追加するたびにコストは上がるし、システムが複雑化する。システムが複雑になることにより新たな Hazardous Situation が生まれるかもしれない。設計者が恐れるのは前者よりも後者の方だ。アーキテクチャが複雑になるとシステムが完全に動作するかどうかの検証作業も増える。故障検出機能の検証のためには故障状態を再現しなければいけない。完成品ではなかなか再現できないから、劣化の加速試験やシミュレーションが必要になる。シミュレーション環境を準備したら、シミュレーション環境が期待通りに動いているかどうかを Validation(妥当性確認)しないといけない。もう、切りがないのである。
なお、ここまで書いたことは FTA が発明された 1960年代の分析とそれほど変わりはないと思っている。静的な構造ベースでの 故障解析はなんだかんだ言っても有限の場合分けにしかならない。複雑でもいろいろなケースを想定して積み上げていけば、トップ事象を起こさない確率を高めることはできる。
故障の原因が統計的な要因のみ、すなわち Random Failures だけならなんとかなる 。しかし、そこに、Systematic failures や Usability が絡んでくると問題はそんなに簡単ではなくなる。
機能の独立性が脅かされるということ
緊急操舵回避システムの制御モデルを描くとこんな感じかではないかと思う。ブレーキ制御やステアリング制御はこんなに単純ではないと思うが、まずはこの単純なモデルで考えて見たい。さきほどは、センサ類の入力側のデバイスの故障について考えたが、緊急操舵回避システムでは「表示灯」「表示装置」「警告ブザー」といった出力系のデバイスも制御しなければいけない。
それぞれの出力デバイスの故障も入力系と同じだが、表示装置となるモニタはもしかするとTVやカーナビと共通で使用するかもしれないので複雑性はさらに増加する。
緊急操舵回避システムでは、緊急時のドライバーがどちらにステアリングを切ればよいかを指示する。その指示をドライバーが実行できないとシステムが判断したときに初めてシステムが自動でステアリングを操作する。
だから、表示装置で方向を指示しなければいけない。カーナビ画面に小さく赤い矢印を出したのでは気づかれないかもしれない。いったん画面を全部消してでかでかと矢印を表示しないといけないだろう。しかも滅多に表示されるものではないから、それが何を意味するのか瞬時に判断できるようでなければいけない。ドライバーが20代でも30代でも40代でも50代でも60代でも70代でも判断できなければいけない。人が絡んだ安全オペレーションを考えるときは、Usability の分析も必要になる。相手が人間になると、統計的な手法の信頼性は低下する。Usability 分析で有効なのは シナリオである。どんなユーザーシナリオを想定したのかを記録しておく必要がある。よく使われるシナリオ、最大負荷となるシナリオを分析段階で記録しておき、それをもとに作ったシステムで事故が起こったら、事故のシナリオを追加して再分析する。人間の行動には一貫性はないから、設計時に想定できないような振る舞いをされることは現実にある。したがって、このフィードバックサイクルを積み重ねることが Usability 起因のリスク対策には有効となる。だから、実戦経験のない機能を初めて市場に出すときは、 Usability 対策が未熟であることはよくある。
さて、緊急操舵回避システムとカーナビとTVで表示装置を共有したのなら、緊急操舵回避システムが他に対して優先順位が高くなければいけないのだが、期待通りに動いていることは誰が検証するのか。カーナビ屋さんが「オレには知ったこっちゃない」と考えていると、思わぬコミュニケーションギャップにより緊急時に画面が切り替わるかどうかのテストが漏れる可能性がある。リスクレベルが高いシステムとリスクレベルが低いシステムでデバイスを共有する場合は、そこにある意識の違いがミスを生む可能性がある。
それはそれとして、緊急操舵回避システムで最も大きな問題は機能の独立性が崩れることだと考えている。
左の図を見てもらいたい。かつて自動車はその基本機能である、ステアリング、ブレーキ、エンジン(加速)の機能は完全に独立していた。
それぞれの機能は他の機能を意識する必要がなく、各機能の信頼性を高めることに集中すればよかった。これはソフトウェアの構造化設計、オブジェクト指向設計の基本である高凝集(High Cohesion)、疎結合(Low Coupling) の状態である。高凝集・疎結合が実現できていると、開発チーム側の役割分担もしやすい。
また、この図で分かるように機能にトリガーをかけるのはすべてドライバーである。それぞれの機能が正常に動作していれば、ステアリングのミス、ブレーキの遅れ、アクセルとブレーキの踏み間違いはすべてドライバーの責任になる。(『ISO 26262との向き合い方 (16) 安全を売りにすることの意味』参照のこと)
その後、ステアリングもブレーキもエンジン・アクセル制御も ECUとソフトウェアが絡むようになって、ブレーキとアクセルが同時に踏まれたときは、ブレーキを優先させるという判定をECU内部で行うようになった。このことは、ブレーキ制御とアクセス制御のECUに間に結合が生まれたことになるが、この程度であれば非常に小さな結合で留まっていると言えるだろう。
それがプリクラッシュセーフティのように自動でブレーキを制御することになるとシステムの中に大きな結合ができてしまう。
衝突回避のための自動ブレーキなら入力はもっと少なくてもよいかもしれないが、それでも衝突リスクを分析・判定するシステムの複雑性は小さくない。
一番の懸念事項は運転手のブレーキ操作、ステアリング操作と衝突リスク分析判定ECUの判断が異なった場合はどうするかだ。
衝突回避のブレーキシステムの場合は、ドライバーがステアリング操作をした場合、緊急ブレーキは動作させない仕様だったと思う。この場合は、上記の図でステアリング制御ECUから衝突リスク分析判定ECUに向かう矢印が一本増える。それによって、ステアリング制御と衝突リスク分析判定機能は結合したことになる。
そして、緊急操舵支援となるとこのように結合度はさらなに強くなる。
ドライバーのハンドル操作やブレーキペダル、アクセルペダルの操作と衝突リスク分析判定ECUの判断が相反したときの問題もさることながら、刻々と変わる状況に対して、センサーからの入力やドライバーの操作、ブレーキかステアリングかといった複雑な判定が必要になる。しかも、その判断は時間毎に変えなければいけないのである。
部品故障に関しても、緊急事態でないときに故障が分かればよいが、仮に衝突回避の直前または回避中にセンサ類に異常が検出されてしまった場合、どのような対応をしなければいけないだろうか。
故障検出が割り込み処理で入ってくるのか、ポーリングなのかによっても状況は変わってくる。衝突リスク分析判定ECUが自分で故障検出デバイスをポーリングするようになっていれば、衝突回避動作中はポーリングをやめればテストケースは減る。(衝突回避動作に入ったらセンサの情報は使わないという設計にした場合)
しかし、割り込み処理だったら、衝突回避中だろうがなんだろうが割り込まれてきて、故障認識時の処理が意図せず動いてしまうかもしれない。衝突回避中だけは割り込みを無視するようなソフトウェア設計にすると、ソフトウェアアイテムの高凝集(High Cohesion)、疎結合(Low Coupling)が崩れてくる。そうなってしまったソフトウェアを完璧にテストしようと思ったら、すべてのタイミングで期待通りの動作するかどうか検証しなければならず、有限の場合分けができなければ永遠にテストは終わらない。
この記事の前半で、静的な構造に関する問題だけならば有限事象なので検証は時間がかかっても収束するといったのはこのことだ。静的な構造の要素だけでなく、時間によって状況が変わる事象を考えなければいけないとなると、シナリオはすぐに爆発し、検証作業が時間切れになる可能性が高まる。
3.11 の後に「想定外を想定する」といったキーワードをよく聞いたが、時間によって状況が変化してしまう場合、想定外はあるという前提でシステムを設計しないと事故は起こってしまう。「想定外を想定する」のではなく、「想定外が起こる前提で最も効果的な安全対策を考えよう」が正しいアプローチだと思う。
システマティック故障
これまでの話の中で、ソフトウェアの中の問題(=バグ)は考慮していなかった。しかし、9つのセンサの入力をリアルタイムに解析するとなると、解析の中には画像解析も含まれる訳だから、ソフトウェアの複雑化は避けらず、バグがまったくない状態にするのは相当難しい。ソフトウェアの内部構造を高凝集・疎結合にする努力はしたとしても、メモリリークなどがあるとその影響は他に伝搬してしまうし、仕様変更や不具合対策でソフトウェアを変更するとそれによって新たなバグを生む可能性もある。ただ、だからといってツールや開発プロセス、各デバイスの高信頼性化だけに着目するのは木を見て森を見ずであると感じる。もっと上位層、要求仕様や安全やリスク分析の中で考えるべき問題、抽象化できない具体的なリスクやハザードに対するリスクコントロールについて考えることが遙かに重要である。抽象論ではなく、具体的なリスクを前にして、そこに対処することがシステムやユーザーの安全への寄与が大きいということを安全設計をするエンジニアは忘れてはいけない。
機器製造業者としては複雑な安全機能を追加しないことによってシステムのアーキテクチャをシンプルにし、テストケースを減らして、システム全体で安全性や信頼性を高めるという選択肢もあるのだ。安全機能を追加しない方がユーザーへの利益が大きいケースはあると思っている。
複雑な安全機能はソフトウェア設計者としてもイヤな感じがするが、安全システム設計者としてシステム全体を見なければいけない立場だったら、そのイヤな感じは増大する。
それは、ソフトウェアの世界で凝集度が低く、結合の強いソフトウェアの集まりが起こす、原因が非常に分かりにくい不具合の数々をこれまで見てきたからそう思うのかもしれない。
そのようなシステムで頭を悩ませてこなかった人たちは、独立性の高いハードウェアを組み合わせることで、多少複雑性が高くなっても、付加価値が高まればよいだろうと考えているのかもしれない。
いったん複雑なシステムを作ってしまうと、予防・是正の取り組みを繰り返しただけでは追いつかない場合がある。変更によって新たな不具合を作り込んでしい、負のスパイラルに陥ってしまう可能性があるからだ。複雑な安全機能にさらなるリスクコントロール手段を追加すると、それによって新しい Hazardous Situation が生まれる。
Random Failures, Systematic Failures, Usability に絡む問題がそれぞれ独立して考えられるのなら、そのようなアーキテクチャを選択した方が絶対にいい。この3つの要素が絡み合うシステムを作ってしまったら、後が大変で、ブログで解決方法を解説するレベルではなくなる。
実際の自動車制御はこんな単純なものではないことはわかっている。だからこそ、独立した機能同士の結合を弱くしておく努力の重要性を感じる。そこを崩してしまうと際限がなくなる。付加的安全機能は際限をなくしてしまうトリガーになるような気がするのである。
どんなに複雑でも、どうせソフトウェアで制御するなら一つの高性能なECUにやらせてしまえという考え方が出てくると、1980年代に医療機器の世界で起こった Therac-25 の事故が、自動車ドメインでも起きるかもしれない。