ドナドナされるプログラマのメモ

Windows用アプリのプログラミングメモ

Factorio + AAI Programmable Vehiclesで自動移動&陣形形成+補給

Factorioにて採掘・戦闘を自動化するため、AAI Programmable Vehiclesと、関連MODを入れてみた。

そして、さっそく惑星内の敵性生命体を滅ぼすための制御回路を構築してみた。


An Example of Half-Automated Troop in Factorio using AAI Programmable Vehicles

目次

 

全体構成

f:id:donadonasan:20200611192418p:plain

AAI Programmable Vehiclesを使った移動・陣形構築・修理回路 外観

これにより、Pathで設定した経路に沿って車群が移動し、WayPointにて所定の陣形となり、各車両の修理完了後に次のWayPointへ向かって再び移動する。もし途中に敵の巣があったら蹂躙する。

BluePrintは以下。

Half-automatic troops for Factorio using AAI Prog…

各部分の働きは以下の通り。

f:id:donadonasan:20200611193924p:plain

AAI Programmable Vehiclesを使った移動・陣形構築・修理回路 概略構成

 

各車両状態の取得と移動目標の設定、車両不在の表示

 

f:id:donadonasan:20200611195240p:plain

車両状態の取得と移動目標の設定、車両不在の表示 外観

最も面積をとっている「各車両状態の取得と移動目標の設定、車両不在の表示」部分は車両台数分だけある「車両状態の(略)表示」から構成されている。

各「車両状態の(略)表示」部分は、「群移動目標の設定」部が出力する群としての移動目標座標と、「Y座標設定」「X座標設定」「車両間隔設定」から得た車群における自車の目標相対座標をもとに自車の移動目標を設定する。また、自車の速度やHP、存在の有無を出力する。そして存在しなくなった(撃破された)場合は赤ライトを点灯する。

f:id:donadonasan:20200611195736p:plain

車両状態の取得と移動目標の設定、車両不在の表示 概略構成

「移動目標の設定」部は、外部からこのマスのX・Y座標(X, Y)、群移動目標のX・Y座標(Xpos, Ypos)、車両間隔Dを受け取ります。これらに対し、Xpos = Xpos+X×D, Ypos = Ypos+Y×Dを演算してUnit Controllerに出力します。X×D, Y×Dを各マスで演算しているのは無駄なのですが、信号の混入がこわいので絶縁も兼ねて各マスでやっています。UnitControllerはこの情報と「制御対象の設定」部から受け取った車両IDに基づき対象車両の目標座標を設定します。UnitControllerによる目標更新間隔は、デフォルトでは1(60回/秒)ですが60(1回/秒)と遅くしてAIの経路探索頻度を減らしFactorioを軽くしています。

f:id:donadonasan:20200611202041p:plain

移動目標の設定 詳細構成

「制御対象の設定」部は、他の各部へ車両IDを提供します。この例では定数を設定していますが、下記のように隣接するマスの車両IDに1を足すようにしているものが大半です。1を足した信号は信号混入を防ぐため算術回路で絶縁後(下図の*+0)、マス内の各部へ供給しています。

f:id:donadonasan:20200611202205p:plain

制御対象の設定 詳細構成

「車両状態の取得」部は、Unit Scannerを使って対象の存在・速度・HPを取得し、速度およびHPが次のWayPointへの移動にふさわしい状態かチェックし結果を出力します。対象の存在はBattery信号を使っています。速度は10未満ならOK、HPは所定値より大きければOKとしています。HPは車種ごとに設定する必要があります。自動化は可能だけど設定頻度が少ない割に複雑になるのでやってません。

f:id:donadonasan:20200611203425p:plain

車両状態の取得 詳細構成

「車両状態の表示」部は、車両状態の取得部からのバッテリ状態信号が0になったらライトを赤に光らせる構成となっています。

f:id:donadonasan:20200611205807p:plain

車両状態の表示 詳細構成

群状態の取得

f:id:donadonasan:20200611210411p:plain

群状態の取得 外観

群状態の取得部は、以下の合計値を演算する。

  • 総車両数
  • 停止している車両数
  • HP回復済み車両数

各情報は中央部・1層目・2層目・3層目・4層目と層ごとに分かれて「各車両状態の取得と移動目標の設定、車両不在の表示」部から送られてくる。これは、層毎に異なる車両を設定していた頃の名残である。そして、送られてきた信号を絶縁後合計している。

f:id:donadonasan:20200611210801p:plain

群状態の取得 概略構成

群状態の取得部は、信号絶縁部と合計部からなる。合計部はなくてもよいが、あったほうがわかりやすい・・・と思う。

f:id:donadonasan:20200611211034p:plain

群状態の取得 詳細構成

群移動目標の設定

f:id:donadonasan:20200611211214p:plain

群移動目標の設定 外観

群移動目標の設定部は群状態の取得部から受け取った信号とPath Scannerからの信号により動作し群としての移動目標座標を出力する。

以下の流れで動作する。

  1. 次の移動目標への移動条件を満たしたか判定する
  2. 満たした場合、ヒステリシス付きエッジカウンタによりカウンタを1だけ増やす。以後、このカウンタは移動を開始するなどの条件を満たすまでは増えない(エッジトリガ)。
  3. カウンタ値から、移動目標を示すウェイポイント番号を生成する。
  4. Path Scannerを用いてウェイポイント番号より移動目標の座標を生成する。

f:id:donadonasan:20200611213539p:plain

群移動目標の設定 概略構成

全てのウェイポイントを通過すると、ウェイポイント信号生成が出力するウェイポイント番号は無効な番号となってしまい、Path Scannerは座標(0,0)を出力してしまう。これは望ましくない挙動なため、ウェイポイント信号が上限を超えないようにしている。上限値はPath Scannerが出力するウェイポイント信号数の信号を使っている。

f:id:donadonasan:20200611215644p:plain

群移動目標の設定 詳細構成

車両間隔設定

車両の間隔を設定する。以下、D=1, 2それぞれの例を示す。

f:id:donadonasan:20200611220241p:plain

車両間隔D=1の場合

f:id:donadonasan:20200611220419p:plain

車両間隔D=2の場合

X座標設定、Y座標設定

上がY=-12, 下がY=12, 左がX=-12, 右がX=12である。

各車両のUnit Data初期化

各車両のUnit Dataを初期化するための仮設備である。Vehicle Deployerを正しく使えば要らないはずの設備なので、詳細は省略する。普段は未稼働で使いたいときのみ算術回路に配線を追加してUnit Dataを初期化する。ループ回路の仕様上、Unit Data Controllerの更新間隔は1としている。

f:id:donadonasan:20200611220908p:plain

各車両のUnit Data初期化 外観

f:id:donadonasan:20200611221114p:plain

各車両のUnit Data初期化 詳細構成