Webプログラマの夏休み PHPでNゲージ模型を自由自在に動かそう[動画つき]

第5回補講:ポイントと同時走行

夏休みは終わってしまいましたが、もう1回だけ続けさせてください。今回は、第3回で扱った「車両のオブジェクト化」を進めて、ポイントの制御も組み合わせてみたいと思います。まずは簡単に復習しておきましょう。

第1回では、制御コマンドをプログラム中に直接書いていました。第2回ではコマンドの対象となる「レール」をオブジェクトにし、レールに対してdriveメソッドやsenseメソッドを呼びだすように変更しました。これらのやり方では、複数の車両を同時に動かすことは可能でしたが、すべての車両の移動が完了するまで、次の移動を開始することはできませんでした。

そこで第3回では車両をオブジェクトにして、それぞれのstepメソッドを、メインループから順に呼びだすだけにしました。それぞれの車両のstepメソッドの中で、次のレールが空いていたらそこまで進み、空いていなかったら何もせずにリターンすることで、他の車両の移動が完了していなくても、別の車両が動きだせるようにしました。他の車両がいるレールに入ってしまうのを避けるため、各レールにlockメソッドを用意し、レールが使用中かどうかがわかるようにしました。

今回使うポイントも、基本的にはlockしてから切り替えれば問題ありません。ただ、特殊なポイントでは、これだけでは特性を生かしきれない場合があります。

複線レイアウト

今回のレイアウトは、3つの駅があり、それぞれに上りと下りのホームがあるというものです。よくある折り返しの駅の形で、両端の駅はどちらのホームにも入れるように、交差/平行を切り替えられるポイントを使用しています。このポイントは回路を2つ使うので、14回路すべてを使う形になりました(当初は2つを並列にしようと考えていたのですが、2つで4A程度流れるので、今回使用したピーク3.5AのドライバICでは駆動できませんでした⁠⁠。

画像
図1 複線のレイアウト
図1 複線のレイアウト
リスト1 複線ポイント制御のrailconf.txt
#    10       20       35       45       60       70
#        06       05       03       01       00
# 10 |--------|--------|--------|--------|--------|
#               p9><p4            pb><p2
# 12 |--------|--------|--------|--------|--------|
#        07       08       0a       0c       0d

R00,7010,6010
R0d,7012,6012
p0201,6010,5210
p020c,6012,5212
p0b01,5210,4510
p0b0c,5212,4512
P0201,6010,5311
P020c,6012,5211
P0b01,5211,4510
P0b0c,5311,4512
R03,4510,3510
R0a,4512,3512
p0405,3510,2810
p0408,3512,2812
p0905,2810,2010
p0908,2812,2012
P0405,3510,2811
P0408,3512,2711
P0905,2711,2010
P0908,2811,2012
R06,2010,1010
R07,2012,1012
TA,6010,7010,50
TB,6012,7012,50
TC,1010,2010,50
TD,1012,2012,50
S0000,AApApAAAApApAA

ここで期待するのは、平行モードのときは上りと下りに別々の車両が通れ、交差モードのときは1つの車両しか通れないという動作です。ポイントそのものをlockしてしまうと、平行モードのときも上りと下りが片方ずつしか通れなくなってしまいます。また、このポイントの2つの回路は、片方だけを切り替えてもうまく働かないため、必ず2つを同時に切り替える必要があり、1回路ずつ別のlockにすることもできません。どうするのがよいでしょうか。

複線用ポイント
複線用ポイント
図2 ポイントの走行モード
図2 ポイントの走行モード

モード付き排他

いくつか考え方はあると思うのですが、今回はポイントの切り替えのlockと、ポイント上のレールのlockを別々に持つようにしました。そして、ポイントの向き(交差/平行)が同じであれば、ポイントは何重にでもlockできるようにしました。車両がまっすぐ入るときは、片方のレールだけをlockした上で、ポイントを平行側にlockします。この状態では、他の車両が他方のレールをlockし、さらにポイントを平行側に2回目のlockをすることができます。一方、車両が交差して入るときは、両方のレールをlockした上で、ポイントを交差側にlockします。この状態では、他の車両は一切ポイントに入ることができないことになります。

また細かい点ですが、中央の駅を出たことが確認できたら、最後まで進む前に、中央の駅の線路のlockを解除しています。こうしないと、次の車両が駅に入ってこれず、ポイントの上下線を同時に通過するというシチュエーションが永遠に訪れないことになってしまいます。

レイアウトエディタでの入力

第3回でご紹介したシミュレータは、レール1の端とレール2の端が同じ座標の場合に、片方のレールの端まで車両が進むと、引き続きもう片方のレールで走行を続けるようになっています。レールどうしの角度などは関係ありません。そのため、今回のような交差するレールを、シミュレータに入力する場合は、注意が必要です。

まず、2本のレールが単に交差している場合、問題はありません。このシミュレータでは、レールが交差していても、相手のレールとの干渉はありません。

しかし、交差している点でレールをいったん切ってしまうと、この座標に4つのレールの端が重なっていることになり、シミュレータは次にどのレールに車両を進めればよいかわからなくなってしまいます。このような車両はエラー状態となり、画面左上に移動して表示されます(レイアウトエディタでは、この車両はレールに乗っていないため表示されず、保存すると取り除かれます⁠⁠。今回使用した交差/平行ポイントの場合、ちょうど交差しているところで配線が変わるため、この問題が発生します。

図3 交差レールの入力
図3 交差レールの入力

そこで、レールのつながっている先をシミュレータに明示するため、1箇所に4つのレールの端点を重ねるのではなく、少しずらした2箇所に、2つずつのレールの端点を重ねるようにします。こうすると、左上のレールの端点には右下のレールの端点だけが重なっており、右上のレールの端点には左下のレールの端点だけが重なっている形になるため、シミュレータは正しく車両を進めることができるようになります。

今回のシミュレータや関連ファイルは以下のリンクからダウンロードできます。

ニコニコ動画:https://www.nicovideo.jp/watch/sm8056558

おわりに

「PHPプログラマの夏休み」と題してお送りしてきたこの企画ですが、おかげさまで反響も多く、大変はげみになりました。この場をお借りして読者の皆様にお礼を申し上げます。

本連載はいったんここで終了いたしますが、リクエストなどがあればできるだけ対応させていただきたいと考えておます。ぜひコメントやメールなどでお寄せいただければと思います。

また逆に、読者の皆様の方で「こんなのをやってみた」といったものがあれば、ぜひコメント等でお知らせいただければ幸いに存じます。

ありがとうございました。

おすすめ記事

記事・ニュース一覧