IBM Rhapsodyでシミュレーション実行可能なステートマシーン図（ステートチャート図）を描く

#IBM Rhapsodyとは
[IBM Rhapsody](https://www.ibm.com/jp-ja/products/uml-tools)は、OMG Systems Modeling Language™ (OMG SysML) を使用して、迅速な要件分析とモデルベースの設計を可能にします。モデルは、実行およびシミュレーションによって検証することができ、システムエンジニアチームが複雑な機能を短時間で設計するのに役立ちます。

#概要
本記事では、シーケンス図の挙動に従いButtonブロックとTimerブロックがどのように振る舞うかをステートチャートで表現します。

#前回の記事
[シーケンス図を描く](https://qiita.com/daikan_murata/items/f583268b8b278a45dc45)
[ブロック図を描く](https://qiita.com/daikan_murata/items/e87e0671bbb76555eb70)

#手順
Buttonのステートチャートの作成、Timerのステートチャートの作成を順番に説明します。
##Buttonのステートチャート
シーケンス図上のButtonを選択し、右クリックメニューを開き、[新規ステートチャート]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/c7ff92d3-6ca9-ef88-4a82-15ab3c4c5115.png)
表示されたステートチャート図をクリックし、ミニメニューを表示し、左から2つ目の[状態]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/e45cd3cd-9175-7a35-716d-42c68bf3f7c5.png)
ステートチャート図をクリックすると状態が新規に生成されます。ButtonUpと名称変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/9b41db86-0251-ed22-cb3e-08443f024588.png)
同様の手順でButtonDownの状態を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/ac21e75d-21ab-b4ea-1b9f-3535ea0f4c1c.png)
###送信アクションの追加
ステートチャート図をクリックし、表示されたミニメニューの中央にある[送信アクション]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/06fbb0a9-5c67-94e9-7a12-af607e547447.png)
生成された送信アクションを右クリックし、[フィーチャー]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/17d36a88-540e-3e67-50df-d51158e01887.png)
ターゲット欄にて[itsTimer in BlockModeling::Button]を選択します。イベント欄にて[evStartStop in BlockModeling]を選択します。この設定により、Timerインスタンスに対してevStartStopイベントを送信します。[OK]をクリックし、フィーチャー設定画面を閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/d8157258-c6b6-07b7-32d4-cc00b9764f37.png)
送信アクションを選択し、右クリックメニューを開き、[テキストに合わせて拡大]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/df560765-c999-1a22-78d6-15493e7624ae.png)
ステートチャート図をクリックし、ミニメニューを表示し、一番左の[デフォルト遷移]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/45337bd8-e1eb-b1c7-0edd-0ee7f43fe341.png)
ステートチャート図の任意の場所をクリックした後、ButtonUpに対して線を引きます。これは、ButtonUpの状態から開始することを意味します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/e0cad1b0-0663-1b2a-e44e-764a1435ff7c.png)
ButtonUpをクリックし、ミニメニューを表示し、[遷移]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/54b6c2d1-28f5-bbed-5c58-0cec0efb9eea.png)
ButtonDownに対して線を引きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/a3e27ca9-e685-d1a5-f806-0c4deadf83a8.png)
同様にButtonDownからevStartStop to itsTimerに線を引きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/42eec708-c42c-90e2-a03e-e5ab074f3853.png)
evStartStop to itsTimerからButtonUpに線を引きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/0df02adb-cfe0-6bb6-7ca8-23598cbfa65b.png)
###トリガーの追加
次にトリガーを追加します。ButtonUpとButtonDownの間にある線を選択し、右クリックメニューを開き、[トリガーの選択]->[evPress()]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/7644fc9d-2cd5-045a-6d9d-7f46bf20957a.png)
トリガーとして設定したevPressが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/a4770434-7300-d72f-7c5b-9171652988bc.png)
同様にButtonDownとevStartStop to itsTimerの間の線を選択し、右クリックメニューを開き、evRelease()イベントをトリガーとして設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/d58873af-58f2-7261-e19d-302982e1277e.png)
evRelease()イベントが割り当てられました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/7bb3da7c-7f2f-feb2-5d35-8e38f74b8fa8.png)
これまでの作業により、ButtonブロックがButtonUpとButtonDownの二つの状態を持つことを表現しました。デフォルトではButtonUpの状態からはじまり、evPressイベントを受信するとButtonDownに遷移することを示しました。
ButtonDownの状態においてevReleaseイベントを受信すると、ButtonがButtonUp状態に遷移するとともに、Timerに対してevStartStopイベントを送信することを定義しました。
もう一度[シーケンス図](https://qiita.com/daikan_murata/items/f583268b8b278a45dc45)を振り返りましょう。シーケンス図で表現したButtonブロックのふるまいをステートチャートで表現することに成功しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/3eb90a57-ae61-2745-3591-70377b0b8db1.png)

##Timerのステートチャート
次に[ブロック図を描く](https://qiita.com/daikan_murata/items/e87e0671bbb76555eb70)で作成したSystem Architectureを開き、Timerブロックを選択します。右クリックメニューを開き、[新規追加]->[ステートチャート]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/ce2110c8-9131-2199-d81f-1e58dd9fc4d9.png)
ステートチャート図の背景（灰色）をクリックし、ミニメニューを表示します。左から二つ目の[状態]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/055f3daa-521f-8cd6-6469-61411b805a1e.png)
ステートチャート図の背景（灰色）をクリックし、NotTimingとTimingの二つの状態を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/97861e16-2bac-cc11-c118-f226b1e45e7f.png)
NotTimingを選択し、[遷移]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/6b793dbf-c1b6-75d1-913d-b0e70068e040.png)
NotTimingからTimingに対して線を引きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/7883a31a-556e-3758-0596-e117a7cb3751.png)
NotTimingとTimingの間の線を選択し、右クリックメニューを表示して、[トリガーの選択]->[evStartStop()]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/9a099a0a-50f9-8fb4-e908-67f798058668.png)
同様に、TimingからNotTimingに対して遷移を引き、evStartStop()を割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/b2c59c80-54e0-8279-98e3-3b4f5fa4b1e0.png)
ダイアグラムの背景をクリックし、ミニメニューを開きます。[デフォルト遷移]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/126dda59-513f-51b2-b177-9a3f8b3d8fa8.png)
ダイアグラム背景の任意の場所からNotTimingに対して線を引きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/a07e60bb-10ba-a01c-02c8-04bfefdcfb3a.png)
###時間イベント処理の追加
ダイアグラムの背景をクリックし、ミニメニューを表示します。[時間イベント受理]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/8de0cc09-e68c-d733-c410-32be5bd759ec.png)
Timingの右下近くをクリックし、時間イベント受理を生成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/7160fa26-8cf6-4260-57dc-75c609e6a289.png)
時間イベント受理をダブルクリックしてプロパティ画面を開き、期間の欄に1000と入力します。[OK]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/c2330c0e-44f1-bce5-8614-43ab688fbf57.png)
先の手順と同様に、Timingから時間イベント受理に対して遷移を引きます。つづいて時間イベント受理からTimingに対して遷移を引きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/55843c5c-3fc7-ca45-edd3-a2e8b1394085.png)
時間イベント受理からTimingに引いた遷移を選択し、右クリックメニューを表示、フィーチャーを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/2ae3c825-79ed-31e2-4593-bae5fae0aea4.png)
一般タブのアクション欄をクリックし、01行目にカーソルをあて、Ctrl+Spaceを実行します。
下矢印キーを押下し、incrementTime()を選択し、Enterを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/dc443fa8-1695-de38-6265-31ed9417d188.png)
incrementTime()の後ろにセミコロンを追加し、[OK]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/c3414721-1e04-da86-dd27-31c8921542ff.png)
メインメニューから[ファイル]->[保存]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228422/601bef29-b4f5-a436-439c-360620fb0233.png)
以上でTimingブロックのステートチャートの作成を完了しました。最初にNotTimingの状態から開始し、evStartStopイベントを受信すると 1000ミリ秒待ち、incrementTime操作を呼び出します。再びevStartStopイベントを受信するまでこの処理を繰り返します。evStartStopイベントを受信すると、NotTimingの状態に遷移します。incrementTime操作が呼ばれるたびに seconds++; が実行されることを思い出してください[（ブロック図を描く）](https://qiita.com/daikan_murata/items/e87e0671bbb76555eb70)。
#次の記事
[シミュレーション実行する](https://qiita.com/daikan_murata/items/0beb67d0fda390516735)