AKAGI Rails

鉄道模型シミュレーターで遊んでいたはずが、気づいたらPythonなども。

Factorioのマテリアルハンドリング

またFactorioで遊んでいます。

稼働中の工場

このゲームに慣れてきたのもあって、大きめの工場を作ってもうまく回せるようになってきました。

さて本題。

マテリアルハンドリング(Factorioだと、ほぼベルト)を考えると、理想的な工場のレイアウトは以下の条件を満たします。

  1. アイテムの動線の長さが短い
  2. アイテムの動線の交差が少ない

さて、このうち a. について、どのアイテムの動線の長さを優先して短くするべきかという問題があります。

その答えとして、3つの目安があります。

  • 付加価値の付いたアイテムの動線は短くしておく
  • 流量の多い動線は短くしておく
  • インベントリで嵩張るアイテムの動線は短くしておく

ただし、時々ハンドクラフトするようなアイテムの材料になるものは、動線を長くしておくことも有効です。ベルト上のアイテムが在庫の役割も果たすからです。

インベントリの1マスに入るアイテム数は、

  • 銅鉱石 50単位
  • 銅板  100枚
  • 動線  200枚
  • 電子基板200枚
  • ロケット制御装置 10台

です。

ちょっと極端ですが、この中ではロケット制御装置が最もかさばります。

こういうものの動線が長くなっていると、工場内のレイアウト変更が生じた際、ベルト上の在庫を回収しようとしたときに、インベントリを圧迫して邪魔になります。

銅鉱石と銅板のインベントリ効率を考えると、倍半分の差があります。

僻地の鉱床からの金属輸送を考えると、炉で焼いて銅板、鉄板にしてから運んだほうが、1両の貨車により多く積んで運んでこれます。

自作車両PJでなにを考えるべきか

私はこれまでに107系,731系,キハ201系と3車種のVRM自作車両を製作してきました。数は多くありませんが,VRM自作車両の製作PJ(プロジェクト)を計画し遂行していく際に何を考え,実行したかという点を,経験談を踏まえて書き記してみます。

ポリゴンモデルの基本事項

話の前提として3Dポリゴンモデルの基本事項を知っておきましょう。

ポリゴンとは

基本的には、ポリゴンとは3次元仮想空間上の三角形の平面です。ただしVRMでは四角形平面のポリゴンも使えます。

小さなポリゴンの集合で複雑な形も表現します。これがポリゴンモデルの本質です。

少ないポリゴン数で仕上げたモデルを形容して「ローポリゴン(ローポリ)」といいます。逆に、ポリゴン数が多いモデルのことは、「ハイポリゴン(ハイポリ)」と言ったりします。

ポリゴンを細かくすればするほど、複雑な形状を滑らかに細かく表現できますが、ポリゴン1枚1枚を描画する描画負荷が重くのしかかります。ビュワー動作の高速性を保つには、見た目の精巧さのバランスを保った中でローポリに仕上げる技能が必要になります。

スムージングと頂点の法線(ノーマル)

ポリゴンは平面ですが,反射の計算はやや特殊です。

本来は平面の集合であるポリゴンですが,モデルに対してスムージングの設定を有効にすると,ポリゴン同士の交差角が一定以下の境界で,継ぎ目がなく表面がなめらかにつながっているかのように描画されるようになります。ポリゴンの表面自体は幾何的に平らなのですが,光の反射がなめらかな曲面であるかのように計算されるため,スムーズな表面の見た目となります。面取りを含む曲面は,この機能によってローポリゴンに仕上げることが出来るわけです。

反射計算のからくりは,頂点法線です。

法線とは,曲面上のある点において面と垂直な直線です。光の反射は光の入射角と面の法線の角度の関係で決まります。

ポリゴンでは,三角形の3つの頂点がそれぞれで法線の向きを持っています。これを頂点法線といいます。

スムージングでは,ある頂点に集まっている面から,中立的な法線の向きが自動設定されます。そして反射計算に使うポリゴンの内部の点における法線は,ポリゴンの3頂点の法線の向きで補間しています。このようにして滑らかな曲面であるかのような反射計算が行われます。(データの節約にもなります。)

手動で各頂点に法線向きを個別設定することもできます。面同士の特殊な合わせ目では手動で法線設定をすることがあります。

このほか,異なる複数の頂点を同一座標に重ねることでスムージングの計算をハックすることで望みの見た目を作ることがあります。モデリングツールのテクニックのほか,objのデータ仕様が背景知識として望ましいのですが,細かくなりすぎるのでここでは省きます。

テクスチャマッピング

ポリゴンそのものは色や模様を持ちません。ポリゴンにテクスチャ(模様)を貼り付けて模様や色を付けます。

ポリゴンで作り込みきれない細かな凹凸や,シェーダーに表現しきれない陰影の表現は,テクスチャで表現すると,ローポリでもリアリティのある車両モデルが作れます。

しかしテクスチャの仕込みがVRM自作車両の難易度が上がるポイントの一つです。

VRM自作車両は,マッピングに使用できるテクスチャの枚数と大きさに強い制限がかかっています。

  • メインテクスチャ256x256 or 512x256 (1枚)
    • 車体全般(台車・車輪・パンタグラフを含む)のテクスチャに使う
  • ユーザーテクスチャ 128x128 (1枚)
    • ユーザーが書き換え可能。方向幕などに使う

合計2枚でなんとか作らないといけない上にサイズも小さいため,必要なテクスチャを必要な解像度で盛り込むためには,ポリゴンで見た目を整える箇所と,テクスチャの芸当で見た目を整える箇所を,全体的なバランスが成立するように最初から想定しておく必要があります。

とくに,台車・車輪については,複数形式で共通の場合が多いですが,モデルを使い回すためには,各車両のテクスチャに共通で同じ場所にテクスチャが割当たってっている必要があります。

自作車両製作プロジェクトの始めかた

対象車両の選定

何を作るかを決めないことには何もできません。対象車両は次のような観点から総合的に選定する必要があります。

  • 自分が十分作りたい(情熱が注げる)か
  • 資料が十分集まるか
  • 製作難易度は自分の実力に見合うか

完成に漕ぎ着けるまでに必要な作業が非常に多いため,自分の情熱が完成まで持続するかどうかは重要です。好きな車両,思い入れのある車両かどうかは意外に大きな要因となるでしょう。

また,資料収集性も重要です。VRM4以降の公式車両と釣り合う品質を目指すと,そこそこ細部までディテールを追わなければなりません。過去の(今もういない)車両の場合は集められる資料に限界があります。ただでさえ,現在走っている車両であっても,台車,床下,屋根上などの資料は不足しがちになるため,自分の足で稼ぎきれない過去の車両は製作の難易度が上がります。また,居住地から遠い地方の車両も難易度が上がります。

また,作る車両を決めたときにある程度難易度が定まってしまう点にも注意が必要です。箱型で平面的に構成された車体であればそこそこ易しいですし,流線型の車体は難易度が急激に上がります。

ただし,自分の実力よりもやや上までの難易度であれば,情熱が自分の実力向上の追い風となります。

製作難易度の見極めに悩む場合

そこそこ一通りのポリゴンモデリングができる状態になっていれば,「○○系は自分の実力で作れるだろうか」という見極めをするのに,モックアップを作ってしまうという手があります。

この後の資料収集や工程編成を一回飛ばして,寸法は完全にメノコでいいので,先頭車の前頭部を仮組みしてしまうのです。これがモックアップです。

大抵の場合,車両の「顔」の印象を決めるのは前頭部です。しかも,意匠的に凝った作りになっているため,モデリングのそこそこ大きなハードルになっています。ある程度ここの形状がポリゴンモデリングの技術的に自分の思うようにできそうであれば,他の工程は(技術的には)なんとかなるという自信が持てます。

後に本制作に入るときはモックアップは一旦脇において,イチから作り直しましょう。

資料収集

鉄道ファン等の雑誌についている図面(形式図)は製作上の大きな助けになりますが,それだけでは作れません。大量の写真資料が結局のところ重要になります。

図面資料,写真資料の収集は,大まかに3ステップで考えることになります。

  1. 日常から集めておく。
    • 事あるごとにいろんな形式の車両を撮影して写真資料をストックしておくと,いつか使える(かもしれない)。
  2. 製作開始前に揃える。
    • 形式図などの図面資料は製作開始までに手元にあれば十分なので,やる気が十分に高まってから揃えればよい。
    • インターネット上にも多少の役に立つ写真資料はあるので,どのサイトにどんな資料があるかの見当を付けておくといい。
  3. 製作の中盤以降で足りない部分の写真資料をもう一度集めに行く。
    • 製作がある程度進むと,「当初は見えていなかったけどモデル上必要な部分」が見えてくるようになります。そのような不足している部分の資料はインターネットでは通常見当たらないので,自分で稼ぎに行ったほうがマシです。

自作車両制作プロジェクトの進めかた

工程編成

ポリゴンモデリングの作業では,後戻りをすることが現実的にも精神的にも難しい場合が多いです。したがって,できるだけ後戻りが生じないよう,一本道で出来上がるように作業の順序を事前にある程度想定しておくとよいです。

一例としては,

  1. ボディ素組(直方体を車体断面の形に整形して,長さを車体長に合わせる)
  2. 帯状塗装の境界(帯状の塗装の塗分け境界は,先にポリゴンを切ってしまったほうが楽)
  3. 分解(屋根・側面・妻面・前頭部にバラす)
  4. マド開け(窓や扉やライトユニットなどの開口部のポリゴンを切って,凹ませたり別オブジェクトに分けたりする。)
  5. 前頭部作り込み(ここで見た目の印象が決まる。)
  6. 台車・車輪(VRM自作車両としてビュワーで確認するのに台車・車輪が必要)
  7. このあたりでマッピングテクスチャの大まかな構成を決める。
  8. テクスチャができたところからペタペタとマッピングする。
  9. パンタグラフ(からくり機械みたいで難しい)
  10. 床下機器(黒っぽい箱だと諦めきれない微妙な箱が難しい。)
  11. 屋上機器(クーラー,無線アンテナ等。モデリングはあんまり難しくない)
  12. 室内モデル素組(運転室・客室等,区切られている空間は各々で直方体から作った方がいいかもしれない)
  13. 室内モデル穴あけ(内側から外を見る穴を開けておかなくてはいけない)
  14. 室内ディテールパーツ(運転台・座席等)
  15. 外構ディテールパーツ(追い込みたいところまで追い込む)

先行関係のない作業同士はパラレルで進めることもありえます。

しかし,イッパツでこの一本道工程を頭の中で計画して,後戻りなく遂行することは現実的には不可能です。「5.前頭部作り込み」あたりまでなら,1度白紙に戻すことがあってもよい,くらいの覚悟でいたほうがよいです。ある程度作業が進まないと見えてこない工程もあるためです。

いくら工夫しても,多少の後戻りはどうしても発生してきますが,どの程度の後戻りであれば白紙にせずにリカバリが出来るか,はポリゴンモデリングの実力次第です。

マッピングテクスチャのプランニング

先述のようにVRM自作車両は,マッピングに使用できるテクスチャの枚数と大きさに強い制限がかかっています。

  • メインテクスチャ256256 or 512256 (1枚)
  • ユーザーテクスチャ 128*128 (1枚)

合計2枚にうまく必要なテクスチャをペタペタと割り付けます。

大抵の場合,先頭車は,中間車よりも多くのテクスチャ領域を必要とします。必要領域の差を考慮して,中間車は256x256, 先頭車は512x256でテクスチャを構成できると理想的です。必ずしもここまで細かく考えなくてもいいのですが,VRAM(ビデオメモリ)の節約に有効だと考えられます。

継続のコツ

とにかく出来るところから作業をし続けることです。どこをやるか悩む前に,手戻り覚悟でどこでもいいからやる。

大抵は手戻りにならずに済むし,手戻りになったとしてもモデリング技術の練習として自分の経験値になります。

9割位で完成とする

作業終盤で追い込み始めるとどこで手を打ったらいいかわからなくなります。適当なところで終わりにしたほうがいいと思います。

107系は車内をやる気力と技量が不足していたので,VRM3車両のように外装だけで済まし,内装はテクスチャ表現のままでリリースしました。まあ9割にも届いてませんね。

731系は,9割位の完成度で一度公開しました。その後,兄弟形式のキハ201系の製作のタイミングで所々のディテールアップを行い,その結果を731系にも反映して再リリースしました。

ツールの選定

ポリゴンモデリングツール

VRM向けの自作車両を作るだけなら,モデリングツールの選定や,使い方の習得に金と時間をかけすぎるのはハッキリ言ってあまり価値がない(と思います)。

結論だけ言えば,Metasequoia有料版をポチッと早く買うのが,利便性とコストとかかる手間のバランスを考えて最適だと思います。(I.MAGICの中の人はあまり好きではないという噂もありましたが。)

画像編集ツール

ポリゴンモデリングのツールよりは,裾野が広くて選択肢も広いと思います。私はPhotoshopです。GIMPなどのフリーウェアでもいいかもしれません。

昔,IllustratorPhotoshopを行ったり来たりして作業いた頃もありましたが,Photoshopだけで最初から最後まで書き上げるやり方に変わりました。

おわりに

ここで紹介した考え方や方法は,あくまでAKAGIの一意見にすぎません。実際は人によってさまざまであるはずです。したがって,ここに書いたやり方を他人に強制するつもりではありません。(誰か他人に全く役に立たないというわけでは無いにせよ,です。)

どちらかというと,「AKAGIはこう考えてやったけど,他の人どうよ?」という趣旨が強いです。他の方からいろいろな方法が出てきたら,共通項や差異があることによって,より情報の価値が高まるのではないでしょうか。

それとTwitter#VRM自作車両 を検索すると,色んな人の自作車両の作りかけの様子が見られて楽しいです。

イベントのユーザIDを予約します

突然ですが,撮る夫くんVRMNXの機能拡張パッケージATENXA の内部で使用するため,VRMNXスクリプトで使用するイベントのユーザIDで以下の番号を予約します。

userID = 1060000 ~ 1069999 (撮る夫くん)
userID = 1850000 ~ 1859999 (ATENXA)

ATENXAを使ってギミックを仕込んだり,Pythonスクリプトを仕込もうと考えているレイアウトでは,バッティングしないように作っていただけるといいと思います。VRMユーザー各位におかれましてはよろしくお願いいたします。

いまのところ,ATENXAで内部使用するイベントも,VRMNXデフォルトの userID == 0 でSetしてしまっているのですが,次回以降のアップデートで予約領域のIDに変更します。

atenxa.richevent を使ってユーザが独自に設定しているイベントについては,ATENXAの予約領域の外で,好きなIDで設定してください。

続きを読む

4KモニターでA列車で行こう9をプレイすると

前回,PCスペックを紹介し,4Kモニターを自慢しました。

本日は4KモニターでA列車で行こう9をプレイしてみたいと思います。

字が小さい

ゲーム側の設定で4Kモニター用にGUIを大きくすることはできないようです。しかし,Windows側の互換設定が効果的です。

A-Train9の起動アイコンを右クリック→ ["プロパティ"] を選択します。

次に,["互換性"]のタブから["高DPI設定"]のボタンをクリックして,ダイアログで以下の設定にします。

こうすると,メニューの文字が読める大きさに戻ります。

メニューの字が大きくなりました。

グラフィックの描画解像度も1/2に低下するものだと思っていましたが,4Kのままみたいです。

AKAGIのPCスペックの話をしよう

今VRMNXとか他のゲームを遊んでいるPCは,2020年の初夏にツクモで買ってきたカスタマイズPCなのですがこれまでスペックを紹介していませんでした。

CPU: AMD Ryzen 7 3700X @3.6GHz RAM: 16GB GPU: NVIDIA GeForce RTX2070 SUPER (8GB VRAM) OS: Windows 10 Home

モニターはLGの27インチ 4Kモニターを使っています。大きいのですが,たまにメニューの文字が細かくなって読めないソフトがいます。

垂直同期を切った設定で, VRMNX ベンチマーク を実施した結果がこちらです。

VRMNXベンチマーク総合スコア4622

VRMで普通に遊んでいるぶんには,ほとんど快適な状態で遊ぶことができています。

実を言うと,あまり4Kの恩恵を感じないので,ディスプレイを設定で2Kに戻して,電気代を下げてもいいかななどと考えています。

Pythonらしいコードとは

Pythonらしさ」とは何か,という問に,簡単な答えを一つ用意するとしたら,「Python言語の利点を最大限活かした実装のやり方やコーディングスタイル」とでも言えるのではないでしょうか。本日は,「Pythonの禅」とPython標準のコーディング規約を紹介します。どちらも,Python公式から出されている PEP (Python Enhancement Proposals) という文書の一部であり,世界中のPythonプログラマに共有されているものです。

[PEP 20] The Zen of Python (Pythonの禅) を読もう

PEP 20 The Zen of Pythonでは,Pythonのデザインに関する原則について19行が記されています。日本語訳も多数見つかりますが,以下の記事が読みやすいでしょう。

qiita.com

The Zen of Python は哲学的な指針が列挙されているばかりで,すぐに実践するのは難しいかもしれませんが,どのような実装をすべきか悩んだときにはここに立ち返るとヒントが得られるかもしれません。

[PEP 8] Pythonコードのスタイルガイドを読もう

PEP 8では,Python標準ライブラリのPythonコードが従うべきコーディング規約が示されています。ただし,拘束力はそこまで強くないので,パッと見ですがPEP 8どおりでないPython標準ライブラリも無いわけではないみたいです。しかし,Python標準ライブラリのみならず,世界中のPythonコードに対してデファクトスタンダードのコーディング規約となっているフシがありますので,従っておいて損はありません。

PEP 8の日本語版は以下で読むことができます。

pep8-ja.readthedocs.io

すぐにでも実践したいいくつかの事項は,ここで改めて引用しながら紹介したいと思います。

インデント

Pythonコード内でのインデントには,半角スペース4つを使います。タブは原則として一切使いません。

関数などの途中で改行する場合の指針も示されていますが,厳密に唯一のルールが決められているわけではないので,ここは読みやすければある程度適当でもいいと思っています。

空行の入れ方

トップレベルの関数やクラスは、2行ずつ空けて定義するようにしてください。

クラス内部では、1行ずつ空けてメソッドを定義してください。

関連する関数のグループを分けるために、2行以上空けても構いません(ただし控えめに)。 関連するワンライナーの場合は、空行を省略しても問題ありません。(例: ダミー実装)

関数の中では、ロジックの境目を示すために、空行を控えめに使うようにします。

あまり空行を連発するとPythonコードとして品がないような印象を持たれます。

import

import文は原則,1モジュール1行ずつ記述します。

import文 は常にファイルの先頭、つまり モジュールコメントや docstring の直後、そしてモジュールのグローバル変数や定数定義の前に置くようにします。

import文 は次の順番でグループ化すべきです:

  1. 標準ライブラリ
  2. サードパーティに関連するもの
  3. ローカルな アプリケーション/ライブラリ に特有のもの

上のグループそれぞれの間には、1行空白を置くべきです。

PEP 8にはこのように書いてあるので,例えばVRMNXで使うならこのようになるはずです。

# LAYOUT

import os   # 標準ライブラリ
import sys

import vrmapi # ローカルのアプリケーションに特有のもの

# この行はatenxaのimportの前にどうしても必要なのでここに来る
sys.path.insert(0, vrmapi.SYSTEM().GetLayoutDir())

import atenxa  # ローカルのライブラリに特有のもの

# グローバル変数,定数定義
somedict = {}
NXSYS = vrmapi.SYSTEM()

def vrmevent(obj, ev, param):
    # 以下省略
    pass

コメントの書き方

PEP 8 -jaの本文に色々書いてありますが,一例を示せばちょうどこの上に書いた例のようになるはずです。インラインコメントでは,「スペース2つ以上 + # + スペース1つ」とすることになっていますが,スペースの使い方を忘れている方が多いです。

ドキュメンテーション文字列

別名 "docstrings" と言われています。別途PEP 257に規定があるので詳しく後述します。

命名規約

これは結構重要だと思っています。が,少なくともVRMNX界隈では今のところ皆さん好き勝手に書いているように見受けられます。

いちばん重要な原則

公開されているAPIの一部としてユーザーに見える名前は,実装よりも使い方を反映した名前にすべきです。

「撮る夫くん」の activate 関数を例に挙げてみます。 activate の実装は他ならぬイベントハンドラの実体にすぎませんが,撮る夫くんユーザーにはむしろ「撮る夫くんを有効化してくれる一行」として認識して頂くほうが理解しやすいだろうと考えられますので,toruo.vrmevent とか toruo.eventhandler とせずに,toruo.activate としました。

守るべき命名規約

簡単にまとめると以下のようになります。(標準ライブラリや組み込み関数,組み込み型は古い経緯があるのでこれに従わないケースがありますが,現在以降はこれに従うほうがよいでしょう。)

  • パッケージ・モジュールの名前は すべて小文字の短い名前にする。モジュール名では,必要であれば,アンダースコア _ は使ってよいが,パッケージ名では不可。

  • クラスの名前は原則, CapWords 方式とする。

  • 関数と変数の名前は,小文字のみ。読みやすくするために必要であれば,英単語をアンダースコア _ で区切る。

  • 定数扱いの変数は大文字のみ。必要に応じてアンダースコアで区切る。

  • 非公開プロパティ(モジュールの内部でのみ使用する前提であり,外部に公開していないグローバル変数や関数など)は,先頭をアンダースコア _ で始める

PEP 8では,関数の名前はクラスメソッドも含み,全部小文字ということになっていますが,肝心のvrmapiがCapWords方式で実装されているので困り果てています。ですが,各部品のイベントハンドラ(関数)は vrmevent とか vrmevent_xxx のように全部小文字+アンダースコアで生成されるので,大本営はvrmapiの中と外で命名規則を使い分けることを意図しているのでしょう。(本当に?)

VRM4~VRM5時代のVRMスクリプトはghost氏の提唱でCapWordsのハンガリアン記法が推奨されていましたが最早古いので,私の書くコードではあくまでPEP 8側に従っています。Pythonでは特に,クラスと関数がひと目見て区別できるコーディングスタイルは重要だと思います。

しかし,PEP 8の冒頭に「一貫性にこだわりすぎるのは、狭い心の現れである」とあるので,必要以上にとやかくは言いません。

比較に関する注意

None との比較には == は使いません。is または is not を使います。

# 正しい:
if foo is None:
    pass

if foo is not None:
    pass
# 間違い:
if foo != None:
    pass

if foo == None:
    pass

if not foo is None:
    pass

docstringsを書こう

コメントを書き込んでプログラムを分かりやすくしておくことは最早当たり前になっていますが(かといって徹底できていないのでおま言うw),関数の使い方やクラスの役割などを説明するコメントの書き方はある一定のルールが設けてあります。このルールに従っておくと,例えばVS Codeのような高機能エディタがうまく気を利かせて,コーディング中にポップアップでその説明を見せてくれたり,Sphinxのように自動でオンラインドキュメント化してくれるツールが存在したりするので,実務的にも得することができます。

docstringsの基本事項はPEP 257に規定されていますが,もう少し細かく書式を規定したものに,numpyスタイルとgoogleスタイルの二大流派があります。縦方向に省スペースでも書けるという点で,私はgoogleスタイルが好みです。

googleスタイルのdocstringsの書き方は,以下の記事が読みやすいです。

qiita.com

atenxaや撮る夫くんのコードにもgoogleスタイルでdocstringを書いています。コードごとSphinxに読み込ませると,こうやってドキュメントがほぼ全自動で作ってもらえるので大変便利です。

よいPython実装を真似しよう

The Zen of Pythonには,

There should be one-- and preferably only one --obvious way to do it. 何かをするための明らかな方法(実装)が,一つは……あわよくば,ただ一つだけの方法があるはずだ。

とはありますが,実際問題,Pythonプログラムには,実装の上手い下手や,実行速度の早い遅いが出てくるものです。

できるだけ分かりやすく,パフォーマンスも悪くない,上手な実装は,教科書のような書籍もいくつかありますが,有名なライブラリのコードを読んで,参考にして勉強するのもおすすめです。

個人的なおすすめをいくつか紹介します。

  • 標準モジュールのdatetime
    • カレンダー上の日付等を扱うモジュールです。曜日やうるう年の計算など,内容が分かりやすく,実装がきれいなので勉強になります。
  • seaborn (matplotlib拡張のデータ可視化ライブラリ)
    • matplotlibを内部で使用してmatplotlibよりも気が利いてきれいなグラフをささっと書いてくれるライブラリです。matplotlibのマニュアルを脇に開いて,seabornの実装を読み解くとPythonプログラミングの勉強にはなります。ですが分量は多いしmatplotlib自体も結構難解なので,普通に難解ではあります。VRMNXでは使う機会はないでしょうが,Pythonでのグラフ描きは比較的ポピュラーな用途かと思いますので紹介してみました。中級以上の方向け。

github.com

github.com

おわりに

Pythonまわりで実践したいこと,あるいは皆さんに布教したいことを勝手につらつらと書いてみました。PEP 8のコーディング規約も,GoogleスタイルDocstringsも,デファクトスタンダードとしてかなり有効に機能していますので,ご存じなかった方はぜひ参考にしてみてください。

今見てみると撮る夫くんではPEP 8やGoogleスタイルdocstringsの決まりごとを守れていない点がちらほら見受けられはしたので,若干反省もしておるところです。

編成側からセンサー間の距離測定ができるか

VRMNXpyで,2つのセンサー間の距離を,編成側から検測してみたいと思います。

単純な直線距離であれば,センサーの座標から簡単な計算で求めることができますが,線路に沿った距離はそう簡単には求められません。もちろん,丁寧に計算すれば求められますが,とても面倒です。ですので,Python処理を駆使して,線路上を走り回る編成オブジェクトから距離測定をしてみたいと思います。

フレームイベントを有効にしてデータを蓄積して距離を測るのですが,基本原理はおおまかに2つ考えられます。

  1. 毎フレームの座標  \vec{x} =trainobj.GetPosition() を記録する。1フレームで座標上を移動した距離  \sqrt{| \vec{x_t} - \vec{x_{t-1}}| ^2} を累積して距離とする。

  2. 毎フレームの描画時間  t と,編成の走行速度  v = trainobj.GetCurrentSpeed() を記録する。1フレームで座標上を移動した距離  v \Delta t を累積して距離とする。

1フレームの描画にかかる時間は必ずしも一定ではないので,時間積分を伴う 2. のやり方は誤差が出そうにも思われますが,かわりに実装上の演算が四則演算で済む(ルートの計算がいらない)ので計算コストが安そうです。

ということで,実装してみました。(コードは汚いので貼りませんw)

距離測定の結果

1周2851.48mmの変形オーバルコースに1個だけセンサーを設置しました。同じセンサーを2度踏むことになりますがで,コース長を繰り返し測ることができます。車両は雰囲気重視でDE10 + TOMIXクリーニングカー(USO800鉄道氏自作車両)です。East-iもってないので。

2回繰り返して測定し,このときは2回とも約2849mmという測定結果でした。若干短いですがこんなもんでしょう。

閉塞制御を実現する場合に,歓呼センサーと直下センサー間の距離を測定する用途などに使えるかなと思っています。

今回はセンサー間の距離測定を行いましたが,ほかにも,編成部品にレイアウト上のデータを色々集めさせることができるかもしれません。

  • センサーを通過する順序を記録する。
    • 閉塞の基本データを自動で生成する。
  • 線路上の走行位置をひたすら記録して走行経路の形状を取る。
    • 移動閉塞の基礎データに?

ATENXAでの閉塞式信号制御は,過去のレイコン作品で閉塞制御を組み込んだのが死ぬほど面倒くさかったことを教訓とし,組み込みの手順がさらに簡単になるようにしたいと思って,いろいろ考えています。それでは。