3D Sim環境構築(5) 複数機同時飛行②

本記事の要約

  • parsim関数を使った方法では、同一環境での同時飛行は無理そうでした。
  • 別手法で同時飛行は実施できたので、今後はそちらを使います。

技術猫たちのおしゃべり

先輩~。お腹痛いから今日は休むっす~。

有言実行なのは評価しますが、流石に騙されません。

はぁ~、先輩が不吉なこと言うときは、結構ろくなことにならないんすよね……。

はっはっは、案外あっさり終わるかもしれませんし、頑張っていきましょう。

超不安っす……。

はじめに

という訳で、おはようございます、こんにちは、こんばんわ。
サバトラ先輩です。

本記事では、『3DSimで複数のUAVを同時飛行させる方法』の第2回を記載しております。
宜しければご覧ください。

なお、前回の『3D Sim環境構築(5) 3D Sim環境構築(5) 複数機同時飛行①』からの続きとなっていますので、
宜しければそちらの記事を先にご覧ください。


前回のおさらい

さて、まずは前回記事の要約を、改めて以下に記載します。

  • 複数機同時飛行を行うための手法を調査しました。
  • parsim関数を使って複数機同時飛行を検証してみました。

このように、前回でparsim関数を用いた複数シミュレーション同時実行を行った結果、別々の環境ながら同時飛行を実現することはできました。
そこで、今回はparsim関数を使って同一環境で同時飛行させことにチャレンジします。

が、期待させるのも良くないので、先に結論を書きます。今回は、parsim関数を用いて同一環境で飛行させることはできませんでした。

以下では、その検証の過程をまとめたいと思います。


今回注目するパラメータについて

前回の記事で、「同一環境で飛行しないのは、Simulation 3D Scene Configurationブロックのパラメータに原因がある」と推察しました。
この根拠は、以下の公式ドキュメントにあります。
UAV 用の Unreal Engine シミュレーションの仕組み(MathWorksさん公式)

公式ドキュメントにある通り、Simulation 3D Scene ConfigurationブロックはSimulink↔Unreal Engine間のインターフェースを司るブロックになります。そして、Unreal Engineシーンの選択、すなわちSimulinkからの通信先を選択できるパラメータは、Simulation 3D Scene Configurationブロックの[シーン ソース] パラメータのみです。VehiclesとSensorsのブロックも確認しましたが、こちらにはそれらしきパラメータはありませんでした。

ということで、この[シーン ソース] パラメータに基づいて工夫をすれば、同一環境で飛行が実現できるのではないかと考えた次第です。
そして、[シーン ソース] パラメータに設定できるのは「Default Scene」「Unreal Executable」「Unreal Editor」の3つになります。「Default Scene」については前回で確認済みですので、今回は残り2つのパラメータ設定で試してみましょう。


「Unreal Executable」の場合

まず、「Unreal Executable」とは、パッケージ化されたUnreal Engineシーンでシミュレーションを行うモードになります。手順としては、以下の通りとなります。
・Unreal Editorでシーンを作成⇒Unreal Editorでシーンをパッケージ化し、exeファイルを生成⇒Simulation 3D Scene Configurationブロックで生成したexeファイル及び対象シーンを指定。
なお、本手順は以下の公式ドキュメントを参考にしました。これにより、Unreal Editorを開かずカスタムシーンが使用できるので便利ですね。
Package Custom Scenes into Executable(MathWorksさん公式)

さて、これで準備もできましたので、[シーン ソース] パラメータを「Unreal Executable」に設定し、parsim関数を実施してみます。

すると、以下のような結果が得られました。

「Unreal Executable」でparsimを実行

動画を見ると、前回の「Default Scene」の時と何も変わっていません。別々の環境で飛行を行っているままです。
これは「Default Scene」の時と同様、それぞれのシミュレーションで別々のUnreal Engineを立ち上げているため発生している現象だと考えられます。とはいえ、これも想定内。同一シーンに接続する設定は無いので、これも当たり前の動作です。


「Unreal Editor」の場合

本命は、こちらの「Unreal Editor」設定。これはシミュレーション実施前に立ち上げているUnreal Editorに接続して、SimulinkとUnreal Editorでコシミュレーションを行う設定です。事前に立ち上げるUnreal Editorは1つなので、それぞれのシミュレーションが同じ環境に接続を試みるのではないかと期待しています。
ということで、『3D Sim環境構築(3) 飛行環境(Unreal Engine)をカスタマイズ』の時と同じ要領でUnreal Editorを起動し、parsim関数を実行してみました。

しかし、ここではシミュレーションは実施されず、Unreal Editor側で以下のエラーが発生しました。

Fatal error!

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000000

(以下略)

どうやら、無効なメモリアドレスにアクセスしようとして、アクセス違反例外が発生したようです。
Simulation 3D Scene Configurationブロックを複数回実行してるのが問題なのかな」と思い、該当ブロックをコメントアウトしたり色々工夫しましたが、どうもシミュレーションが実施できません。というか、検証している時に気づいたのですが、「Unreal Editor」設定でparsim関数を使った場合は、1機飛行すら実施できません。sim関数なら1機飛行は実施できるので、モデルには問題ありません。どうも、parsim関数と「Unreal Editor」設定の組み合わせに問題があるようです。

そこで追加の調査を行った所、以下の情報を見つけました。
Simulink および Unreal Editor を使用したシーンのカスタマイズ(MathWorksさん公式)
「MATLAB® または Simulink の外部で Unreal Editor を開くと、Simulink はエディターとの接続を確立できません。この接続を確立するには、プロジェクトを Simulink モデルから開くか、または MATLAB 関数を使用する必要があります。」

この情報に基づいて確認したところ、確かにUnreal Editorを直接起動した場合は、Simulinkとの接続ができませんでした。また、シミュレーションを行うセッションと別セッションのSimulinkでUnreal Editorを起動しても、シミュレーションを行うSimulinkとの接続ができませんでした。
これは推測ですが、どうやらSimulinkからUnreal Editorを立ち上げる際に、接続に関する各種設定が自動実施される仕様のようです。つまり、parsim関数で並列プールを立ち上げて複数シミュレーションを実施した場合は、別セッションで接続をかけているのと同じ状況になり、結果としてUnreal Editorとの接続が上手くいかなくなっているのではないかと予測できます。

なお、この仕様はUnreal Editorにインストールしたプラグインによるものでしょうから、安易に変更することも叶いません。つまり、「Unreal Editor」とparsim関数を用いた複数機同時飛行は状況的に詰んでおり、実質的に実現不可能な状態となってしまいました。


parsim関数を諦めて、別の手法で妥協する

なんて……、なんて、こったい……

残念ですが。上記の結果からparsim関数は諦めざるをえませんね

あんなに、あんなに苦労して検証したのに……!

同感ですが、開発していると往々にして起こることです。今回は潔く妥協しましょう。

よよよ~。僕は悲しいっす~。

……って、ん?あれ、先輩、今「妥協」って言いました?

言いましたね。今回は妥協します。

複数機同時飛行を止めるんじゃなくて?

いえ、複数機同時飛行は止めませんよ。これから、妥協の方法について説明します。

もしかすると、先ほど提示した以下の公式ドキュメントを見た時点で気づいた人もいるかもしれません。
UAV 用の Unreal Engine シミュレーションの仕組み(MathWorksさん公式)

はい、そうです。妥協の手法とは、簡単に言えば「Simulinkモデル内にVehicleブロックを増やす」ということです。
そして、実際にVehicleブロックを追加した物が以下になります。なお、今回は確認を簡単にするため、各Vehicleの位置情報にオフセットをかけたものを入力としています。

そして、シミュレーションした結果が以下の通りです。

3機同時飛行(Vehicleブロック追加)

できてるじゃないっすか!!

うわっ、びっくりしました。どうしたんですか、いきなり。

いや!……えぇっ、 こんな簡単に!? 先輩、このやり方に気づいてたんっすか!?

そうですね。前回調査してるときに、できそうだなー、とは思ってました。

だったら! 何故こっちの手法を最初から採用しないんすか!

圧が凄いです、落ち着いてください。……これを当初採用しなかったのには、次の理由があるんですよ。

  • 複雑の制御則を持った機体は1機までしか飛ばせない(ブロック数制限の問題)。
  • シングルスレッドで実行するため、CPU/メモリ使用率が低く、シミュレーションの速度が遅い(環境によるかも。下記ドキュメントもご参照のこと)。
    MATLAB が CPU のすべてのリソースを使用しないのはなぜですか?(MathWorksさん公式)
  • シミュレーションのモデルに制御と直接関係ないブロックが内在するため、制御則に変更が無くてもシミュレーション条件によってモデル変更の必要が出てくる。

特にブロック数制限の問題は、今後も壁になることも考えられますが。parsim関数で実現できないなら仕方ありませんね。
今後はメイン機体以外は飛行コースを引くだけの簡易モデルとして、複数機同時飛行を実現することにしましょう。

理屈は分かったっすけど……。先輩、単にparsim関数が面白そうだったから選んだ、っていうのが本音じゃないんっすよね?

……

……

……まあ、7割くらいは、そうとも言えますね。

……そ、そうっすか……


次回記事の予定

ということで、お疲れさまでした。ひとまずこれで、3DSim環境の構築は終わりです。

なんか、凄い脱力したっす。

さて、次回からは開発コンセプトを決めていくわけですが。ここで頑張っているチャ坊主くんに朗報です。

へ?何すか? 何か、嫌な予感するっすけど。

コンセプト案、チャ坊主くんが先導していいですよ。なので、次回までにいくつか案を考えといてくださいね。

それただの宿題じゃないすか!やだー!

では、次回は12/18(月)に更新予定です。どうぞよろしくお願いします。