ueckoken / plarail2023

プラレールをIoT化して自動制御します
https://ueckoken.github.io/plarail2023/
1 stars 0 forks source link

アーキテクチャを決定する #8

Open csenet opened 1 year ago

csenet commented 1 year ago

やりたいこと

実装を始めるにあたって、アーキテクチャを設計する。

実装の方針

前年度の内容をもとにして、今年度やりたいことをもとにしてソフトウェアとハードウェアを含めた全体のアーキテクチャ設計をする。

csenet commented 1 year ago

今年度やりたいこと

MUST

HAD BETTER

csenet commented 1 year ago

現時点での暫定的なあアーキテクチャ図を添付する

IMG_8FDCFAD85D03-1

csenet commented 1 year ago

自動運転

昨年度は実装できなかった部分であるので、1から実装をする必要がある。 アルゴリズムの実装に関しては既に #7 にて議論している。路線の状態をグラフとして管理をする。 アルゴリズムにデータを渡すために色々をしなくてはいけないので、その部分に関しては別途実装する。

管理サイト

基本的にやりたいこととしては去年のサイトと同じだが、今回は状態を同期するためのプロトコルとしてconnect-webを採用したい。また、プラレールのレイアウトが微妙に変化することが予想されるのでフロントエンドの調整(SVG手打ち芸)が必要だが、可能ならこの部分を簡単にできるとなおよい。

状態管理

これまでとは異なるアーキテクチャで、列車の状態管理をモダンなIoTのアーキテクチャに近づけていきたい。 AWS IoTやAzureなどで利用されているアーキテクチャを模倣する感じで、MQTTでエッジの端末と通信してIOの状態の対応付けをバックエンド側で行うようにする。この部分は正直なところ、MongooseOSなどの既存の仕組みがあるが余裕があれば独自実装したい。 これまでは、KVSで管理していたがPodが死ぬと状態が失われるためアーキテクチャとしてはあまり良くない。 今回はアクセス頻度などを考慮して、MongoDBなどのNoSQLなDBで状態管理を行いたい。

列車検知

これまでのホールセンサーやCdSでは読み飛ばしが多くあった。今回はそうしたデータの読み飛ばしをなくすために、マイクロスイッチを用いた列車の通過検知と、列車が駅に停車した際にNFCタグを用いて列車を識別するような仕組みを実装したい。 基本手にはハードウェア側で大規模な処理をするわけではなく、イベントをhttp経由で通知してくれれば良い。(MQTTを採用するメリットは薄いような気もするがプロトコルの検討は必要かも)

ポイント・ストップレール制御

昨年度と同様にESP32にサーボモータを接続して制御を行うことを検討している。 昨年度からの違いとして、MQTTでブローカーと接続してあげることで現地会場でのサーバー構築作業がなくなるので良さそうかなと思っている。httpよりも薄い感じのプロトコルらしく、普通にESPで問題なく動きそう。 ベースとなるコードはあるものの、実装が大きく変わるのでソースコードの変更は必要。

カメラ配信

昨年度と同様にしてSkyWayを用いた映像中継を検討している。 車載カメラにはESP-EYEを採用してmjpegなどで受け取った映像を配信用PCからSkyWayに流すことを検討。 旧SkyWayがサービス終了するらしいので実装の変更は必要かもしれない。

ラジコン

ラジコンに関してはTWILITEを用いた速度制御を行うことで安定性の向上を目指したい。 基盤に関しては昨年にスバル君が作ってくれたものがあるので、今回はこれを基盤におこして小型化を目指したい。 また重心問題にも対応できるなら尚良い。

csenet commented 1 year ago

自動運転周りで色々とアーキテクチャが更新されたので変更

flowchart RL
subgraph 状態管理
管理画面 <-->|"connect-web"| StateManager

EventHandler <-->|"connect"| StateManager
StateManager <--> DB1[(state_db)]
end
subgraph 自動運転
TrainController <--> StateManager
DiagramManager --> PathPlanner
PathPlanner <--> TrainController
DiagramManager <--> DB2[(diagram_db)]
DiagramManager <-->|"connect-web"| 管理画面
end
subgraph 映像配信
Webカメラ --> |"USB"| 配信サイト
ESP-EYE -->|"mjpeg"| 配信サイト
配信サイト -->|"WebRTC"| SkyWay
SkyWay -->|"WebRTC"| 管理画面
end
subgraph エッジデバイス
StateManager <-->|"MQTT"| Servo
Sensor -->|"MQTT"| EventHandler
end
kienn-HCl commented 1 year ago

StateManagerからservoつなぐの? StateManagerが持ってるのは物理世界を抽象化した線路図のグラフだから直接のやり取りは無理でTrainControllerにservoを動かすのをやってもらうんじゃないの?

csenet commented 1 year ago

StateManagerが物理世界のグラフと路線図のグラフを両方持っていて(これはフロントエンドでの表示でも使うため)、TrainControllerはStateManagerが持ってる物理世界の状態を更新することによってサーボが動く想定をしてる

kienn-HCl commented 1 year ago

物理世界のグラフって何をさしてるの サーボ(ストップレールとポイント)の状態?

csenet commented 1 year ago

グラフという表現は間違ってたかも。 はい、サーボの状態という意味です。

kienn-HCl commented 1 year ago

なるほど、その場合ってstateManagerのサーボの状態をもとに物理世界へのサーボに指令を出すサービスを間に挟まなくていいの?

csenet commented 1 year ago

その部分の認識がちょっと違うかもしれない 正確には、ESP32側が状態を常に監視してサーバー上のサーボの状態に合わせるという感じかな

kienn-HCl commented 1 year ago

あー、なるほど

kienn-HCl commented 1 year ago

前言ってたMQTTのサブスクライバとパブリッシャーのアーキテクチャの話か?

csenet commented 1 year ago

そうだね。MQTTのPub/Subを上手に使うためにそうゆう設計が良いかなと 具体的に、デバイスは初回起動時にhttpのGETっぽいメソッドを呼び出して仮想のそうである状態を取得してきて、それ以降は状態が更新されるたびに発行されるtopicをサブスクライブして変更が発生したら物理的な状態を更新するイメージ。

参考 https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/device-shadow-data-flow.html

csenet commented 1 year ago

フロントエンドとStateManager間の通信をGraphQLにしても良いかもしれない...?

csenet commented 1 year ago

ref #62

csenet commented 1 year ago

よくよく考えたら、State Managerにおいて一括で状態を管理するのはMircoservice archtectureに反しているような気がしてきた。あと、フロントエンドとの通信をいい感じにするためにBFF(Backend For Frontend)を追加してあげると良さそう。 少し設計を見直す。

csenet commented 1 year ago

オライリー本を読んだ感じ、同じ状態を用いるコンポーネントが存在する場合に、その共通の状態を管理するサービスを用意するのは正しそう。 ただ、今回の場合はState Managerにおける責務が大きすぎる気がするので修正する。