連続記事#2 要求を仕様化する

# 背景・目的
自社向けの勉強会でなにかテーマを決めて、ソフトウェア開発の上流工程から下流工程まで説明する連続講座を開催し、自分のスキルアップしたいと考えました。
講座参加者に学びになれば尚良、と考えました。この記事は講座を補足説明する位置づけとしたいと考えています。

現在予定している講座はつぎのとおりです。

 * 要求の理解　
 * 要求を仕様化する ★いまここ
 * 設計
 * テスト
 * 実装

今回の講座の資料はこちらにアップロードしました。

[組み込みソフトウェア基礎_【連続講座 #2】要求仕様を定義する](https://www.docswell.com/s/juraruming/KVYP4K-2022-06-16-211650)

# テーマ
前回は[要求仕様を正しく理解するには?](https://qiita.com/juraruming/items/0fecf339735c86fdc2a1)というテーマで要求を正しく理解するポイントについて書きました。
今回は　**要求を仕様化する** ポイントについて書きます。

## テーマの説明
テーマは **既存組込み製品(CQ EVカート)のマイコンを変更する** と決めました。
このテーマに決めた理由は次のとおりです。

 * 講師が持っており、対象装置のドメイン知識を理解している。
 * ソフトウェアの構造を理解している。

上記理由に加えて対象装置のマイコンが新規採用非推奨品になったこともあり、
　**学習・スキルアップのため別マイコンに変更してみよう** と考えました。

### EVカートについて
変更対象のEVカート・EVカートのソフトウェアについて説明します。

#### 走行動画
つぎの動画のようにスロットルを操作するとモータが回転し走行します。

https://youtube.com/shorts/t8grJVxvEGg?feature=share

### ハードウェア
EVカートの基板に注目した動画です。
基板は2枚で構成されています。下側の大きい基板のうえにマイコンが実装されている小さな基板をスタックします。
下側の大きい基板を **インバータ基板** 、上の小さい基板を **CPU基板** と呼びます。
可変抵抗(アクセルの代替)を操作するとモータが回転します。

https://youtu.be/v5NdeAOgM-Q


#### もう少し詳しい説明
もう少し詳しい説明はこちらの資料を参照ください。
 **第1章　EVカートとは何か?** を見ると全体像がなんとなくわかると思います。

<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/K3NG1K/embed" data-aspect="1.4118"></script><div class="docswell-link"><a href="https://www.docswell.com/s/juraruming/K3NG1K-2022-06-15-211831">EV カートで始めるモデルベース開発 by @juraruming</a></div>

### テーマの前提説明
テーマ　**【既存組込み製品のマイコンを変更する】** は次の前提とします。

 * 派生開発(既にある装置でCPU基板のみ変更)
 * ハードウェアあり。電気的仕様確認OK。
 * 旧マイコンでのソフトウェア資産あり。※[GitHub](https://github.com/grace2riku/cq-ev-kart-gcc), [資料](https://www.docswell.com/s/juraruming/5Q7RVZ-2022-06-15-230120)の各リンク
 * 個人開発(お仕事にも適用できるエッセンスはあるかと思います)


## 要求一覧
今回のテーマの要求を次に決めました。
私が個人的に実現したい要求に決めました。ビジネスではお客様の要求になると思います。

 * マイコンを移植したい。
 * ハードウェアの拡張に対応できるソフトウェア構造にしたい。
 * TDD(テスト駆動開発)したい。


## 要求を仕様化する準備
[要求一覧](#要求一覧)で決めた要求をソフトウェアで設計⇛実装しやすくするために **要求の仕様化** をしていきます。
とはいってもいきなり要求を仕様化することは難しいかと思います。
要求を仕様化するには準備が必要と思います。具体的にはつぎの知識が必要と思います。

 1. 開発対象の構造・関係
 1. 用語(の定義・共有)
 1. 要求の目的・背景を明確にすること

※今回要求の仕様化がうまくできませんでした。なぜうまくできなかったか記事の最後で振り返ります。

## 開発対象の構造・関係
開発対象のことを理解する必要があります。例えばつぎの項目があります。

　* メカと電気の関連
　* 電気とソフトウェアの関連
ソフトウェアで電気的仕様のxx条件になるようプログラムするとメカがどう動くか、の知識。
※今回はこれが明確になっている前提とします。


## 用語(の定義・共有)
開発対象で使う専門用語・専門知識をまとめた用語集は有用と思っています。
開発者同士がコミュケーションし(会話ができる)、円滑に開発できる手助けとなると思います。
用語集があると次のメリットがあると考えられます。

　* 開発チームに新規参加するメンバーが早く馴染める。
　* 用語集自体が会社の資産になるかもしれない。

今回作ってみた用語集はこちらです。

[用語集](https://docs.google.com/spreadsheets/d/1qG0yf4QlYj-mvI-HShvhVj3eU4ZH56i96Era1rvGoAw/edit#gid=1176272537)

Webで検索すればわかる用語(例.CppUTest)は書かず、プロジェクトメンバーで共通認識を持ちたい用語(例. 旧マイコン)を書いています。

### 用語集の必要性を感じた事例
4年くらい前に会社のメカ・電気・IT・組み込みソフトウェアエンジニア(私)でEVカートの開発をしてレースに出場するという活動をしていました。そのときの話です。

参考)
 * [2018年の活動](https://persol-tech-s.co.jp/corporate/news/report/527.html)
 * [2019年の活動](https://touch.persol-group.co.jp/20190828_4430/)
 * [2019年の活動詳細 AWSで走行データを可視化](https://www.slideshare.net/KoujiAbe/awsev)

EVカートはモータの巻線も手巻きします。
いざカートに巻線完了したモータ・基板をとりつけカートとして走れる形にして動作確認すると、なんと意図していた方向とは逆にモータが回転しEVカートが逆走してしまいました。
原因はモータの巻線方向とソフトウェアのモータ回転方向の制御が一致していないためでした。
このときは笑い話ですみましたが実際の開発現場で同様の事例が起きたら・・・と想像したら気をつけようと思いました。
対策として開発メンバーが参照する共有ドキュメントにモータの巻線方向・ソフトウェアの制御(時計または反時計方向の通電制御でモータは物理的にどう回転するか)についての説明を記載しておけば良いと思いました。
開発対象の知識をメンバー間で共有し用語集という形でまとめておくことの必要性を感じた出来事でした。


## 要求の目的・背景を明確にすること
【要求】には目的・背景があると思います。それを理解しているか・否かが重要と思います。
要求の目的・背景を理解しているメリットとして次があります。

 1. お客様が本当に求めるものがつくれる
 1. 設計の考慮漏れがなくなる
 1. 重点的にテストすべきポイントがわかる 
 1. 2, 3の結果、開発の出戻り工数が少なくなる 

### 要求の目的・背景を理解する難しさ
とはいえ要求の目的・背景を理解する難しさ・ポイントがあるかと思います。
要求の目的・背景を理解する難しさ・ポイントを因数分解してみます。

 * 要求の目的・背景を深ぼる工数がない。
 * 要求の目的・背景を理解するのに時間がかかる。
 * 要求の目的・背景をお客様から引き出すのにスキル(※)が必要。
   ※対象装置の知識・ヒアリング・コミュケーション能力

## 要求の仕様化
[要求一覧](#要求一覧)をUSDMの形式で仕様化していきます。
今回書いた[USDMはこちら](https://docs.google.com/spreadsheets/d/1qG0yf4QlYj-mvI-HShvhVj3eU4ZH56i96Era1rvGoAw/edit#gid=0)です。

普段USDMを使うことはないのですが、USDMを書いて感じた特徴的なことはつぎのとおりです。

 * 要求に名前をつける
 * 要求を階層化する
 * 要求には理由を書く

### 要求に名前をつける
今回書いたUSDMを見ると要求に名前がついていることに気づくと思います。

 * マイコンを移植したい ⇛ **【PORTING01】** 
 * ハードウェアの拡張に対応できるソフトウェア構造にしたい ⇛ **【SCALABLE01】** 
 * TDD(テスト駆動開発)したい ⇛ **【TDD01】** 

　名前をつけることで次の効果があると思います。
 * 仕様を特定しやすい(開発メンバーで会話しやすい。共通認識持ちやすい)
 * 仕様とテストの紐付けができる(このテストはこの要求から導かれたものという関係がわかる) 


### 要求を階層化する
物事を整理するとき、構造を考える時 **階層化** することは有効だと思います。
USDMは　**要求を階層化して表現する** 手法があります。

要求: PORTING01の例だと次のようになります。

要求: PORTING01
└ PORTING01-1: 要求PORTING01を階層化して記載した要求
　└　PORTING01-1-1: 要求から導いた仕様

### 要求には理由を書く
[要求の目的・背景を明確にすること](##要求の目的・背景を明確にすること)で書いたように要求の目的・背景を理解しておくことで設計で考慮すべき点・テストすべきポイントがわかるなどの効果が考えられると書きました。
USDMには要求の下に **理由** の記載欄があります。ここに要求の理由を書くことで要求の目的・背景を伝えることができます。

要求: SCALABLE01の例だと次になります。

SCALABLE01: ハードウェアの拡張に対応できるソフトウェア構造にしたい。
　【理由】異なるインバータ基板、マイコンにも容易に移植可能なソフトウェア構造にして欲しい。

この【理由】欄の記載があることでインバータ基板の拡張を考えていることが想像できます。
ソフトウェア設計者は異なるインバータ基板の拡張を考慮し設計することになると思います。


# 書いたUSDMの振り返り
今回書いた[USDM](https://docs.google.com/spreadsheets/d/1qG0yf4QlYj-mvI-HShvhVj3eU4ZH56i96Era1rvGoAw/edit#gid=0)はうまく書けていない、という感想です。
うまく書けていない思う理由ですがつぎのとおりです。

 * 要求を仕様化した仕様記載はソフトウェア設計できる粒度になっていないから

今回書いたUSDMは要求を箇条書きした文書になっている感じです。
なにか良いUSDMのサンプルを探していたら[参考資料 2](#参考資料)のドキュメント **LEDキューブシステムUSDM仕様書** を見つけました。
こちらの仕様書を見ると次のように仕様が分類され、別シートで記載されています。

 * 第1章	ハードウェア構成とハードウェア要求仕様
 * 第2章	操作仕様
 * 第3章	表示仕様
 * 第4章	通信仕様

このUSDM仕様書のように要求を適切な単位で分類してから要求を仕様化していく必要があったな、と学びました。


# 参考資料

1. USDMの入門
AFFORDD　派生開発推進協議会
[T02：「USDM」の入門](https://affordd.jp/grouptag/t2/)
USDMの入門資料があります。

1. USDMの仕様書の例
[USDMで仕様書を書いてみた](http://shikou-sakugo.cocolog-nifty.com/blog/2011/04/usdm-e6f1.html)
ページ冒頭の **LEDキューブシステムUSDM仕様書** は個人的に参考になりそうです。


# 次回予定
 **要求を仕様化する** は如何でしたでしょうか?
なにかお役にたてると嬉しいです。
よければ感想などをコメントくださるとありがたく、猫のように喜びます。

次回の自社向け勉強会は7/21(木)に開催を予定しています。その頃にまた勉強会の内容を記事化したいと考えています。
勉強会の内容はつぎを考えています。

 * 要求仕様の理解
 * 要求を仕様化する　★いまここ
 * 設計 ※次はこれ!!!
 * テスト
 * 実装

次回は定義した仕様からソフトウェアの **設計** をやってみようと考えています。
設計は【分析・概要設計】⇛【実装のための詳細設計】と段階を踏んで実施していきたいと考えています。
次回は【分析・概要設計】をやってみたいと思います。

最後まで長文を読んでいただきありがとうございました。次回もよろしくおねがいします。