【明日から使える】組込ソフトでの状態遷移設計を解説します!

状態遷移設計

約 10 分で読めます。



組込ソフトで大事な設計要素である状態遷移について解説していきます!



このページに来たということは、おそらく皆さんは現役の組込エンジニアで、

組込ソフト設計って、あまりノウハウが見つからないんだよなあ…

状態遷移って聞いたことあるけど、いまいち使い方がわからない…

大事とは聞くけど、やる意味があるのかよくわからん…

という悩みをお持ちと思います。
 少し前まで私もそうでした。
一緒に勉強していきましょう!

状態遷移を設計するとはどういうことか

詳細な説明はWikipedia(状態遷移図)に譲るとして、

機器自体もしくは機器に組み込んだソフトが何かしらの状態によって動作を変える必要がある場合に、取りうる状態と状態に紐付いた動作を漏れなく抽出することです。

身近な例としてはテレビの電源スイッチがありますね。
 テレビがOFFでスイッチを押すと、テレビをONにする動作をし、
 テレビがONでスイッチを押すと、テレビをOFFにする動作をします。

このように「スイッチを押す」という同じ操作でも、状態によって動作を変えています。



上記は単純なのでわかりやすいですが、例えば
 テレビがBlu-ray再生時に地上波のチャンネル変更ボタンを押したら
  ボタン操作自体を無視するのか?
   もしくは
  地上波モードに切り替えて、チャンネルを変更するのか?

と、やれる操作が多ければ多いほど、考慮すべき組合せも多くなります。

また、ユーザーの通常操作の他にも
 コンセントを引っこ抜かれた
 停電が発生した
といったことにも対応する必要があるでしょう。
 ※状態遷移設計ではこれらをまとめてイベントと呼びます。



これをコーディング中に並行して考えるのではどこかで破綻することが目に見えていますので、事前に状態とイベントとの組合せとして設計資料として整理しておくことで、コーディング及びテストに役立てることができます。

状態遷移設計することのメリット

実際に私が感じている具体的なメリットは以下です。

考慮漏れをなくすことができる

前記の通り、
 テレビがBlu-ray再生時に地上波のチャンネル変更ボタンを押したら
みたいなソフトエンジニアからすれば異常な操作(※)も漏れなく洗い出すことができます。
 ※ユーザー目線では通常操作なのですが。



異常操作時の動作仕様は上流工程で練られていないこともあるので、
 こういう状態でユーザーがこの操作したらどうしましょうか?
 自分はこういう動作がいいと思っているが、どうでしょうか?
というように、状態遷移設計資料を元にPMへの仕様案を打診するのにも使えるでしょう。



バグを減らすだけでなく、製品視点でより使い心地の良い操作感達成にも一役買うことができます。

工数見積もりに使える

例えば全状態が10個、全イベントが10個だとしたら、取りうる組合せは10×10=100個となります。

仮に1個のテストに5分かかるとしたら全部で500分なので、6時間20分です。
 実際はミーティングや休憩もあるので、1日から1日半といったところでしょうか?

もし一人のテストエンジニアが専属でテストをするとしたときに、上記6時間20分をテスト締め切りまでに捻出できるのか?というように作業見積もりに使うことができます。

上司・PMへの交渉材料に使える

前段落の続きとして、もし仮に締め切りまでに終わらないことが明らかな場合、
プロジェクトとしてアクションを取るよう上司・PMに依頼する必要があるでしょう。
 誰かに手伝ってもらい、締め切りを守る
 締め切りを少し伸ばす
などです。

前記見積もりに基づいた根拠あっての話なので、上司・PMも無視できません。

打診した時点で上司・PMは前記「一人でやったら絶対に間に合わない」ことを認知したことになりますので、もし間に合わなかった場合の責任は上司・PMになります。
 「腹くくってやるしかねえだろ」みたいに言われるなど、無茶もありますけどね…😅

レビューしてもらえる、より良い設計への気付きを得る

先ほどの例では全組合せが100個でしたのでなんとかなりそうですが、
これが10000個とかになったらさすがに大変でやってられないので、
 このまま進めても破綻するのが目に見えているな…
 別の切り口で設計するのが良いのでは?
気付きを得るきっかけになります。

また、設計レビューで先輩や同僚に見てもらうことで、自分では気づかなかった視点を得て、より良い設計につなげることも可能になるでしょう。

状態遷移設計の種類

状態遷移表

私がよく使っている状態遷移設計です。
縦軸に状態、横軸にイベント、で表を作って埋めていくものです。

例えば前記テレビの電源スイッチでは以下。
 初期状態は#1です。
 #1や#2は、イベント発生後の状態を指しています。

#テレビの状態イベント
電源スイッチを押す
1電源OFFテレビをONにする
#2
2電源ONテレビをOFFにする
#1



状態とイベントさえ列挙できれば機械的な作業で全部の組合せを網羅できるのと、組合せ数を数えるのが簡単なので、見積もりしやすいですし、説明の根拠にも使いやすいです。

一方で、全情報を網羅していて情報の粒度が細かいため、プレゼン資料などに貼り付けるのには向いていないです。

状態遷移図

初期状態と各状態をノードで表し、イベントと状態の遷移を矢印で表すやり方です。

例えば前記テレビの電源スイッチでは以下。
黒点は初期状態を表します。



パッと見でわかりやすいので、頭がごちゃごちゃせずに済みます。

一方で、状態数・イベント数が増えてくると、矢印が交差するなど見づらくなります。

実際にやってみる

例題設定

以下のようなエアコンのリモコンを例にやってみましょう。

・電源ON時は現在の情報をリモコンの液晶に表示する。
 運転種別(冷房⇔暖房)
 設定温度(0℃〜35℃)

・以下ボタンを持つ。
 ・電源ボタン(OFF⇔ON)
  ・電源OFF中は電源ボタン以外を押しても無視する。
 ・運転種別切り替えボタン
  冷房のときに押すと暖房に、暖房のときに押すと冷房に切り替わる。
  液晶の表示も切り替わる。
 ・温度上げるボタン、下げるボタン
  0℃のときに下げるボタンを押しても0℃のままとする。
  35℃のときに上げるボタンを押して35℃のままとする。

・冷房、暖房、それぞれで設定温度を保持する。

・単4電池で動作する。

何も考えずにやってみる

イベントは以下になるでしょうか。

・電源ボタン押下
・運転種別切り替えボタン押下
・温度上げるボタン押下
・温度下げるボタン押下
・電池切れを検出

電池切れになることもありますので、電池切れを入れています。
 いきなり電池を抜かれる場合もここに含めます。



お次は状態です。

・電源
 ・OFF
 ・ON
・運転種別
 ・冷房
 ・暖房
・設定温度
 ・冷房
  ・0℃
  ・1℃〜34℃
  ・35℃
 ・暖房
  ・0℃
  ・1℃〜34℃
  ・35℃

設定温度は下限値である0℃、上限値である35℃、およびそれ以外で分けました。
これは、0℃より下、また35℃より上、への温度変更ができない仕様があるためです。



これで状態とイベントが出揃いました。
これをそのまま状態遷移表にするとこちらの通りとなります。
 「Ver.0.1」シート
 36状態と5イベントで全組合せとしては180パターンとなりました。



多すぎるので、数を減らすことを考える

人にもよると思いますが、180パターンはちょっと多いですね。
なので、減らすことを考えてみましょう。
 結果はここの「Ver.0.2」シートにあります。

減らすにはお互いに関連がないもの同士で表を分けるのが有効です。



まず、電源OFF時は電源ボタン以外を押しても意味がないので、ここで表を1つ作ります。
サブマシン状態とは、ある状態で参照すべき追加の状態遷移表を指します。



また、冷房・暖房それぞれで逆の方の設定温度を変えることもできないので、表を分けましょう。



全部で10パターンとなり、最初の180パターンから18分の1に減らすことができました!

もちろんサブマシン状態として表同士の繋がりを表現することで考慮すべき設計は出てきますが、組合せ数を激減できたのは大きいですね!

終わりに

いかがでしたか。

最近状態遷移の考え方を使うことで、とても設計検証やバグ解析等がスムーズに行くことが多かったので、自分の知識整理も兼ねてまとめました。

まずは小さい設計から始めてみると成功体験を得ることができて自信がつくのでオススメです!

Comments

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