Open csenet opened 1 year ago
MUST
HAD BETTER
現時点での暫定的なあアーキテクチャ図を添付する
昨年度は実装できなかった部分であるので、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を用いた速度制御を行うことで安定性の向上を目指したい。 基盤に関しては昨年にスバル君が作ってくれたものがあるので、今回はこれを基盤におこして小型化を目指したい。 また重心問題にも対応できるなら尚良い。
自動運転周りで色々とアーキテクチャが更新されたので変更
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
StateManagerからservoつなぐの? StateManagerが持ってるのは物理世界を抽象化した線路図のグラフだから直接のやり取りは無理でTrainControllerにservoを動かすのをやってもらうんじゃないの?
StateManagerが物理世界のグラフと路線図のグラフを両方持っていて(これはフロントエンドでの表示でも使うため)、TrainControllerはStateManagerが持ってる物理世界の状態を更新することによってサーボが動く想定をしてる
物理世界のグラフって何をさしてるの サーボ(ストップレールとポイント)の状態?
グラフという表現は間違ってたかも。 はい、サーボの状態という意味です。
なるほど、その場合ってstateManagerのサーボの状態をもとに物理世界へのサーボに指令を出すサービスを間に挟まなくていいの?
その部分の認識がちょっと違うかもしれない 正確には、ESP32側が状態を常に監視してサーバー上のサーボの状態に合わせるという感じかな
あー、なるほど
前言ってたMQTTのサブスクライバとパブリッシャーのアーキテクチャの話か?
そうだね。MQTTのPub/Subを上手に使うためにそうゆう設計が良いかなと 具体的に、デバイスは初回起動時にhttpのGETっぽいメソッドを呼び出して仮想のそうである状態を取得してきて、それ以降は状態が更新されるたびに発行されるtopicをサブスクライブして変更が発生したら物理的な状態を更新するイメージ。
参考 https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/device-shadow-data-flow.html
フロントエンドとStateManager間の通信をGraphQLにしても良いかもしれない...?
ref #62
よくよく考えたら、State Managerにおいて一括で状態を管理するのはMircoservice archtectureに反しているような気がしてきた。あと、フロントエンドとの通信をいい感じにするためにBFF(Backend For Frontend)を追加してあげると良さそう。 少し設計を見直す。
オライリー本を読んだ感じ、同じ状態を用いるコンポーネントが存在する場合に、その共通の状態を管理するサービスを用意するのは正しそう。 ただ、今回の場合はState Managerにおける責務が大きすぎる気がするので修正する。
やりたいこと
実装を始めるにあたって、アーキテクチャを設計する。
実装の方針
前年度の内容をもとにして、今年度やりたいことをもとにしてソフトウェアとハードウェアを含めた全体のアーキテクチャ設計をする。