オレオレハード＋Nervesの設計モデルを考えて実装したよ！

# はじめに
今は西海岸時間　UTC-8　12月23日 22:50

この記事は、[#NervesJP Advent Calendar 2021](https://qiita.com/advent-calendar/2021/nervesjp) の23日目です。!

昨日は @tatsuya6502 さんの[NervesでRustの関数をNIFとして呼び出す最小の手順（Rustlerを使用）](https://qiita.com/tatsuya6502/items/04d2bb1fbb05735be18b)でした。

###オレオレハード＋Nervesの設計モデルを考えて実装したよ！
オリジナルのオレオレハードとそこで動くNervesを使い機械制御をするには、並行・並列を前提とした機械制御のシステムデザインはどうしたら良いのか？を検討したものです。

# オレオレハードって？
- PLCに代わる機械制御を目的としたハードウェア(通称Exiシリーズ)を自分たち(@nishiuchikazuma、@kikuyuta のkochi.exメンバー)で作りました。
- BeagleBoneベース
- 豊富な接点をもつ3種類の機器構成
    - Combo(DI:8点,DO:4点,AI:6点,AO:1点)
    - DIO(DI:16点,DO:16点)
    - AIO(AI:16点,AO:16点)
- CPUボード＋拡張ボードで構成され各々(Combo,DIO,AIO)が独立して動作が可能
- I2C経由で取得／書き込み
- 電源はPoE
- スーパーキャパシタ(簡易UPS 電源断から1分程度供給可能)を持ち、電源断を検知しその間にシャットダウンなど。
- 動作温度:−25℃〜70℃、湿度:55℃/85% 結露なきこと
    - JIS試験実施(高温、低温、温湿度サイクル、振動、衝撃)
    - プログラマブルコントローラ− 装置への要求事項及び試験
    - JIS B 3502:2021 (IEC/FDIS 61131:2003) (JEMA/JSA) (2019確認)

## PLCに取って代わる素敵ハードが
```
# これで動く！！
set -x MIX_TARGET bbb
mix nerves.new exibee

# これで繋がる！！
Node.connect :"combo@exibee"
```

# 並行・並列を前提とした機械制御の設計モデル

## これまで(Prototypeオレオレハード+Python)
- 状態をもってループ
- ラダー言語で書かれた制御を模倣したような設計。)そりゃーループよ。
- ループ中のいろんな処理でループが大きくなり。)そりゃーループよ。
- ハードの制限、信頼性の担保をソフトで吸収しようとして遅くなり。)そりゃールー　以下略。

Pythonでも頑張ればもうちょっと良い感じにできたのかもしれませんが。
結論：ループしたくない


## Elixir的な新しい設計モデルってどんなの？

#### 設計にあたっての前提
- HWは信頼性の高い物を使用
    - PLC同等の信頼性で、HWの信頼性担保をソフトで頑張らない。
- イベントドリブン
    - 極力ループしたくない。
    - 接点が変化したイベントをキャッチし処理
- 並行処理が可能
    - 機器の制御モジュールの独立性を高くする。
    - 再利用、メンテナンス性、テストスコープを最小化

#### 観測者と制御Process
並行処理を行うために、機器の制御と状態を管理するプロセスを別にします。
これを行うことで同期・非同期を意識し独立したモジュールを実装する事ができます。

![20211208_独自ハードウェアで小水力発電所をいごかしたよ(ロジック編) #exibee #exineris #kochi.ex #5 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295240/d4035335-6421-04f2-ad59-710e3c342032.png)

![20211208_独自ハードウェアで小水力発電所をいごかしたよ(ロジック編) #exibee #exineris #kochi.ex #5 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295240/5f41506b-7889-44cb-6b4e-fd937fa2b98e.png)


#### Genserverで実現
同期、非同期で処理を実行するために以下のGenserverを用意します。
※小水力発電所の制御を行うための例です。

- StateServer
役割：状態（state, new_state）だけを扱う
{:global, :state_server}

- HealthCheck
Server
役割：障害を管理する（状態を受け取りヘルスチェックをする）
{:global, :health_check_server}

- LogicControllerServer
役割：状態を受け取りLogicControllerを操作する
{:global, :logic_controller_server}

![20211208_独自ハードウェアで小水力発電所をいごかしたよ(ロジック編) #exibee #exineris #kochi.ex #5 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295240/85f5528f-16a5-80e4-0865-7b88adcee682.png)

#### 処理ロジック
LogicControllerServerから実行され、接点を操作(DO)する関数を作っていきます。

例えばこんな)
小水力発電所の入力弁を閉じる場合
状態の管理や制御のロジックは全てGenserverで実装されているため、モノの状態を意識することなく接点操作を行う処理だけを作って行きます。

```Elixir:logic_controller.ex
defmodule Exibee.LogicController do
  require Logger

  alias Exibee.Elib, as: E
  alias Exibee.Valve, as: V #Genserverで実装された入力弁を操作するモジュール

  # 停止ボタン押下
  def stop_button_down() do
    log = "stop button down"
    E.send_log(__MODULE__, __ENV__, log)
    # 入力弁を閉じる
    V.close()
  end
  
  def open_button_down() do
　・・・
  end  
  ・
  ・
  ・
end
```

# HumanMoxで動かしてみる。

ひゅーまんもっくすとは

- 人力で盤・リレーの動きを模倣する手技


19.9kwクラスの小水力発電所の制御(例)

- 構成
    - Exi-Combo 1台+治具
    - Exi-DIO 1台+治具
- 次のシナリオで実際にいごかしてみます。
   - 起動→運転→停止→運転→非常停止→非常停止からの復帰

前編
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">オレオレハード+Nervesの設計モデルを考えて実装したよ！<a href="https://t.co/MFOIKPyxWv">https://t.co/MFOIKPyxWv</a><a href="https://twitter.com/hashtag/Nerves?src=hash&amp;ref_src=twsrc%5Etfw">#Nerves</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://twitter.com/hashtag/%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%89%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC2021?src=hash&amp;ref_src=twsrc%5Etfw">#アドベンドカレンダー2021</a> <a href="https://t.co/HrSmFYUx9K">pic.twitter.com/HrSmFYUx9K</a></p>&mdash; みっちぃ (@rigutter) <a href="https://twitter.com/rigutter/status/1474291067101282308?ref_src=twsrc%5Etfw">December 24, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

後編
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">後編　オレオレハード+Nervesの設計モデルを考えて実装したよ！<a href="https://t.co/MFOIKPyxWv">https://t.co/MFOIKPyxWv</a><a href="https://twitter.com/hashtag/Nerves?src=hash&amp;ref_src=twsrc%5Etfw">#Nerves</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://twitter.com/hashtag/%E3%82%A2%E3%83%89%E3%83%99%E3%83%B3%E3%83%89%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC2021?src=hash&amp;ref_src=twsrc%5Etfw">#アドベンドカレンダー2021</a> <a href="https://t.co/JEK7q3NOOC">pic.twitter.com/JEK7q3NOOC</a></p>&mdash; みっちぃ (@rigutter) <a href="https://twitter.com/rigutter/status/1474292003823579139?ref_src=twsrc%5Etfw">December 24, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



明日は @pojiro さんの[Nerves大好きな僕が2021年にしたこと](https://qiita.com/pojiro/items/30b6ef01c32882fc7c19)です！