パソコンで鉄道模型を制御するための基礎検討(13)
制御盤操作GUI+自動運転
[はじめに]
前述のNゲージレイアウトの制御盤操作GUIソフトウエアに自動運転機能を追加したものを試作しました。
これらのソフトは基本的な動作テストをWindows11上でのみ行なっています。
また私が勝手に企画し試作したシステムで、現状susukuma鉄道模型チャンネルに採用される予定はありません。
そのためバグが残っていたり、鉄道模型マニアから見たらおかしなところもあると思います。
ですがパソコンから無線/有線でリモート制御したい、自動運転もしたいという方の参考になれば幸いです。
鉄道模型用制御システムとしてはすでにDCC対応の機器やTOMIXのTNOSが販売されています。
DCCの場合は車両側にDCCの通信/制御を行なう回路を搭載する必要があるそうです。
それに対しここで紹介する方式(SNTC2)はsusukuma鉄道模型チャンネルで採用しているデュアルキャブ方式にPCからの制御を追加するものです。
そのため列車に追加回路を搭載する必要がありません。
複数閉塞区間を設けて個別電圧制御することで制限はありますが連続した線路に複数車両を走行させることも可能です。
またデュアルキャブ方式に部分的な導入を行なったり、マニュアル操作と自動制御の混合運転も可能です。
TOMIXのTNOSも複数閉塞区間を用いて制御するシステムですが、レイアウトプランや運転モードはTOMIXから提供されているものの中から選ぶ必要があります。
一方、ここで紹介しているSNTC2ではシリアルネットワークを利用して大規模で複雑なレイアウトに対応でき、また自由に自動運転プログラムを組むことができます。
これらのソフトは基本的な動作テストをWindows11上でのみ行なっています。
また私が勝手に企画し試作したシステムで、現状susukuma鉄道模型チャンネルに採用される予定はありません。
そのためバグが残っていたり、鉄道模型マニアから見たらおかしなところもあると思います。
ですがパソコンから無線/有線でリモート制御したい、自動運転もしたいという方の参考になれば幸いです。
鉄道模型用制御システムとしてはすでにDCC対応の機器やTOMIXのTNOSが販売されています。
DCCの場合は車両側にDCCの通信/制御を行なう回路を搭載する必要があるそうです。
それに対しここで紹介する方式(SNTC2)はsusukuma鉄道模型チャンネルで採用しているデュアルキャブ方式にPCからの制御を追加するものです。
そのため列車に追加回路を搭載する必要がありません。
複数閉塞区間を設けて個別電圧制御することで制限はありますが連続した線路に複数車両を走行させることも可能です。
またデュアルキャブ方式に部分的な導入を行なったり、マニュアル操作と自動制御の混合運転も可能です。
TOMIXのTNOSも複数閉塞区間を用いて制御するシステムですが、レイアウトプランや運転モードはTOMIXから提供されているものの中から選ぶ必要があります。
一方、ここで紹介しているSNTC2ではシリアルネットワークを利用して大規模で複雑なレイアウトに対応でき、また自由に自動運転プログラムを組むことができます。
[プログラムとデモデータ]
ダウンロード(右クリック-->名前を付けてリンク先を保存)し、ZIP圧縮してあるので展開してください。
下記プログラムを実行するにはPythonと関連モジュールがパソコンにインストールされている必要があります。
展開して出来たikcp2フォルダ内には以下のファイルが入っています。
dummy_hard_ikcp2.py
ハードウェア(信号機やポイント等を制御する回路基板)無しでパソコン上に鉄道レイアウトの制御盤を表示し、マウスによる操作や自動運転プログラムをシミュレーションするプログラムです。
なおこのプログラムでは信号機の制御基板に備わっているタイマー機能やセンサーによる信号色自動切替、6灯式信号機のポイント連動のシミュレーション機能は実装していません。
us_ikcp2.py
USBシリアルインターフェイス(有線)で鉄道レイアウト側と接続し制御するプログラムです。
このプログラムを実行するには有線接続用ハードウェア、 制御対象の基板、基板接続に対応した制御盤データ(注1)が必要です。
bt_ikcp2.py
ブルートゥース(無線)で鉄道レイアウト側と接続し制御するプログラムです。
このプログラムを実行するには無線接続用ハードウェアとソフトウェア、 制御対象の基板、基板接続に対応した制御盤データ(注1)が必要です。
(注1)ハードウェア接続自動抽出や制御盤エディタで作成したcontrol_panel_数字.txt
dummy_hard_ikcp_gui2.py
上記のdummy_hard_ikcp2.pyから呼び出される下位プログラムです。
制御盤の表示、マウスやキーボード入力、ハードウェア(制御基板)のシミュレーション、自動運転プログラムの実行を行ないます。
ikcp_gui2.py
上記のus_ikcp2.py、bt_ikcp2.pyから呼び出される下位プログラムです。
制御盤の表示、マウスやキーボード入力、ハードウェア(制御基板)とのコマンド/データの送受、自動運転プログラムの実行を行ないます。
control_panel_1.txt
運転制御盤のデモ用データです。6種類の制御基板をネットワークに接続した物になっています。
demo1~3.py
上記のプログラムで実行する自動運転プログラムの記述例です。
自動運転プログラムの作成方法の説明用です。
dummy_hard_demo1~3.cmd
マウスクリックのみで起動するためのwindows用バッチファイルの例です。
下記プログラムを実行するにはPythonと関連モジュールがパソコンにインストールされている必要があります。
展開して出来たikcp2フォルダ内には以下のファイルが入っています。
dummy_hard_ikcp2.py
ハードウェア(信号機やポイント等を制御する回路基板)無しでパソコン上に鉄道レイアウトの制御盤を表示し、マウスによる操作や自動運転プログラムをシミュレーションするプログラムです。
なおこのプログラムでは信号機の制御基板に備わっているタイマー機能やセンサーによる信号色自動切替、6灯式信号機のポイント連動のシミュレーション機能は実装していません。
us_ikcp2.py
USBシリアルインターフェイス(有線)で鉄道レイアウト側と接続し制御するプログラムです。
このプログラムを実行するには有線接続用ハードウェア、 制御対象の基板、基板接続に対応した制御盤データ(注1)が必要です。
bt_ikcp2.py
ブルートゥース(無線)で鉄道レイアウト側と接続し制御するプログラムです。
このプログラムを実行するには無線接続用ハードウェアとソフトウェア、 制御対象の基板、基板接続に対応した制御盤データ(注1)が必要です。
(注1)ハードウェア接続自動抽出や制御盤エディタで作成したcontrol_panel_数字.txt
dummy_hard_ikcp_gui2.py
上記のdummy_hard_ikcp2.pyから呼び出される下位プログラムです。
制御盤の表示、マウスやキーボード入力、ハードウェア(制御基板)のシミュレーション、自動運転プログラムの実行を行ないます。
ikcp_gui2.py
上記のus_ikcp2.py、bt_ikcp2.pyから呼び出される下位プログラムです。
制御盤の表示、マウスやキーボード入力、ハードウェア(制御基板)とのコマンド/データの送受、自動運転プログラムの実行を行ないます。
control_panel_1.txt
運転制御盤のデモ用データです。6種類の制御基板をネットワークに接続した物になっています。
demo1~3.py
上記のプログラムで実行する自動運転プログラムの記述例です。
自動運転プログラムの作成方法の説明用です。
dummy_hard_demo1~3.cmd
マウスクリックのみで起動するためのwindows用バッチファイルの例です。
[各ファイルの関係]
プログラムファイルや制御盤データ、ハードウェアの関係を図にしました。
[起動方法]
プログラムを起動するにはプログラムや関連ファイルのあるフォルダでコマンドウインドウ(注2)を開き、キーボード入力します。
(注2)コマンドウィンドウを開くにはフォルダ内で右クリックし[ターミナルで開く]を選択する。
ハードウェアなしのシミュレーションで制御盤データ=control_panel_1.txt、自動運転プログラム= demo1.py なら起動コマンドは
python dummy_hard_ikcp2.py control_panel_1.txt demo1.py
Bluetoothで無線接続する場合なら
python bt_ikcp2.py control_panel_1.txt demo1.py
USB-Serialで有線接続する場合なら
python us_ikcp2.py control_panel_1.txt demo1.py
制御盤データ(*.txt)を指定しない場合はcontrol_panel_n.pyで1<=n<=100の内、一番大きい数字のファイルを読み込みます。
自動運転プログラム *.py は指定しなくても起動でき、その場合はGUIによるマニュアル操作のみ可能です。
オプションとして-printを指定すると自動運転プログラムから制御基板へのアクセスごとにコマンドウインドウに表示が出ます。
-print_wを指定すると制御基板への書き込みの時だけ、-print_rを指定すると読み出しの時だけ表示が出ます。
オプションとして-beepを指定すると自動運転プログラムから制御基板へのアクセスごとにbeep音が出ます。
-beep_wを指定すると制御基板への書き込みの時だけ、-beep_rを指定すると読み出しの時だけbeep音が出ます。
上記のコマンドを*.cmdのバッチファイルにテキストエディタで書き込んでおけば、そのバッチファイルをマウスでダブルクリックしてプログラムを起動できます。
例として dummy_hard_demo1~3.cmd を上記ikcp2フォルダに添付しました。
なおバッチファイルをマウスクリックして起動した場合、ファイル指定ミスや自動運転プログラムのバグがあってもコマンドウィンドウが即閉じてしまうのでエラー表示が読めません。
その場合はバッチファイルは使わず、コマンドウィンドウを開いてコマンドによる起動をすることでエラー情報を得やすくなります。
(注2)コマンドウィンドウを開くにはフォルダ内で右クリックし[ターミナルで開く]を選択する。
ハードウェアなしのシミュレーションで制御盤データ=control_panel_1.txt、自動運転プログラム= demo1.py なら起動コマンドは
python dummy_hard_ikcp2.py control_panel_1.txt demo1.py
Bluetoothで無線接続する場合なら
python bt_ikcp2.py control_panel_1.txt demo1.py
USB-Serialで有線接続する場合なら
python us_ikcp2.py control_panel_1.txt demo1.py
制御盤データ(*.txt)を指定しない場合はcontrol_panel_n.pyで1<=n<=100の内、一番大きい数字のファイルを読み込みます。
自動運転プログラム *.py は指定しなくても起動でき、その場合はGUIによるマニュアル操作のみ可能です。
オプションとして-printを指定すると自動運転プログラムから制御基板へのアクセスごとにコマンドウインドウに表示が出ます。
-print_wを指定すると制御基板への書き込みの時だけ、-print_rを指定すると読み出しの時だけ表示が出ます。
オプションとして-beepを指定すると自動運転プログラムから制御基板へのアクセスごとにbeep音が出ます。
-beep_wを指定すると制御基板への書き込みの時だけ、-beep_rを指定すると読み出しの時だけbeep音が出ます。
上記のコマンドを*.cmdのバッチファイルにテキストエディタで書き込んでおけば、そのバッチファイルをマウスでダブルクリックしてプログラムを起動できます。
例として dummy_hard_demo1~3.cmd を上記ikcp2フォルダに添付しました。
なおバッチファイルをマウスクリックして起動した場合、ファイル指定ミスや自動運転プログラムのバグがあってもコマンドウィンドウが即閉じてしまうのでエラー表示が読めません。
その場合はバッチファイルは使わず、コマンドウィンドウを開いてコマンドによる起動をすることでエラー情報を得やすくなります。
[GUI手動操作]
自動運転プログラムの実行と同時に、制御盤上でのマウスクリックやキーボード入力でマニュアル操作が可能です。
以前のレイアウト制御ソフトと同じマニュアル操作ができます。
今回追加で制御盤上のセンサーをマウスクリックして疑似の車両検出信号を出す機能を追加しました。
自動運転プログラム作成時のテスト等に使えると思います。
hキーを押すとコマンドウインドウにマニュアル操作のhelpが表示されます。
helpをpdf変換したものを添付します。
ikcp2_gui_help.pdf
以前のレイアウト制御ソフトと同じマニュアル操作ができます。
今回追加で制御盤上のセンサーをマウスクリックして疑似の車両検出信号を出す機能を追加しました。
自動運転プログラム作成時のテスト等に使えると思います。
hキーを押すとコマンドウインドウにマニュアル操作のhelpが表示されます。
helpをpdf変換したものを添付します。
ikcp2_gui_help.pdf
【自動運転プログラムの言語】
自動運転プログラムはpython言語で記述します。
pythonについて詳しく勉強しなくても、以下で説明する自動運転用関数やサンプル記述(demo1~3.py)を参考にすれば比較的容易に希望するプログラムを作成することができると思います。
ただし、pythonではインデント(字下げ)が重要な事(プログラム中のif文などのブロック範囲を決める)に注意する必要があります。
pythonは非常に強力で広く使われている言語ですので、興味がある方は解説本やWeb検索で調べてみてください。
なお私は基本的にハード屋で、今回公開したソフトはとりあえず動くものを初めて作ったというレベルです。
pythonについて詳しく勉強しなくても、以下で説明する自動運転用関数やサンプル記述(demo1~3.py)を参考にすれば比較的容易に希望するプログラムを作成することができると思います。
ただし、pythonではインデント(字下げ)が重要な事(プログラム中のif文などのブロック範囲を決める)に注意する必要があります。
pythonは非常に強力で広く使われている言語ですので、興味がある方は解説本やWeb検索で調べてみてください。
なお私は基本的にハード屋で、今回公開したソフトはとりあえず動くものを初めて作ったというレベルです。
【自動運転プログラムの実行タイミング】
メインプログラム(*_ikcp2.py)では周期的にハードウエアと通信し、制御盤のGUIプログラム(*_gui2.py)や自動運転プログラムもそれに合わせて繰り返し実行されます。
そのため自動運転プログラムには状態変化や指定時間到達のイベント検出条件とその判定結果に応じた動作を記述します。
もしイベント判定条件を間違えて連続で無駄なハードウエアへの書き込みをするとうまく動かなくなる可能性が高いので注意が必要です。
そのため自動運転プログラムには状態変化や指定時間到達のイベント検出条件とその判定結果に応じた動作を記述します。
もしイベント判定条件を間違えて連続で無駄なハードウエアへの書き込みをするとうまく動かなくなる可能性が高いので注意が必要です。
【自動運転用関数】
メインプログラム中で定義してある自動運転用関数や引数等を以下に示します。
==== 制御対象の状態読み出し、書き込み関数 ====
auto_read(ID) <-- 制御対象の状態読み出し
auto_write(ID,data) <-- 制御対象へ設定値書き込み
上記関数の引数IDとは制御盤に表示されているポイント、信号機、コントローラー、センサー、スイッチの識別番号です。
(IDはキーボードのnで表示/非表示が切替わります。)
auto_read(ID)の戻り値と、auto_write(ID,data)の書き込みデータ の意味と値域は以下の通りです。
コントローラーは複数の項目数値を持っていて、IDの次に項目指定の1文字を追加することでアクセスできます。
例えば電流値ならauto_read(ID,"m")、加速度設定するならauto_write(ID,"a",data)と記述します。
コントローラーの項目指定文字列(1文字)と項目の意味、値域は以下の通りです。
auto_check(ID) <-- 関数内でauto_read(ID)により制御対象の状態を読み出し、前回実行時の値と今回の値を比べて異なっていたら1、同じなら0を返す。
auto_check(ID,new=A) <-- 前回、今回で読み出し値に変化があり、今回のデータがAと同じなら1、それ以外なら0を返す。
auto_check(ID,old=B) <-- 前回、今回で読み出し値に変化があり、前回のデータがBと同じなら1、それ以外なら0を返す。
auto_check(ID,new=A,old=B) <-- 前回、今回で読み出し値に変化があり、今回のデータがAと同じでさらに前回のデータがBと同じなら1、それ以外なら0を返す。
コントローラーの各項目をチェックしたい場合は上記のauto_readと同じように識別文字を追加することで可能です。
例えばauto_check(ID,"m")と記述します。
auto_checkk(ID)の初回実行時は前回の読み出し値が未定義となりますが、その場合は0を返します。
==== 時間計測、判定関数 ====
以下の関数により時間計測のスタート、経過時間の取得、時間の判定を行なうことができます。
異なったスタート時刻や経過時間を独立に扱うため、呼出時の引数としてkeyを指定します。
keyは数字や文字列が使えます。
auto_time_start(key) <-- keyで識別される時間計測を0からスタートさせる。
auto_time(key) <-- keyで識別される経過時間を単位が秒の浮動小数点数として返す。。
auto_time_check(key,t) <-- keyで識別される経過時間がt未満なら0を返す。
経過時間がt以上なら時間計測を0から再スタートし戻り値として1を返す。tは単位が秒の浮動小数点数または整数。
もしkeyで識別される時間計測がまだスタートしていない場合はスタートさせ、戻り値として0を返す。
==== 初期化のための変数 ====
auto_init_flag
これは関数ではなく初期値が1に設定された単なる変数です。
繰り返し実行される自動運転プログラムの中で初期化処理を行なうためにメインプログラム側で定義しています。
demo2.py、demo3.pyで使用し、解説しています。
==== 制御対象の状態読み出し、書き込み関数 ====
auto_read(ID) <-- 制御対象の状態読み出し
auto_write(ID,data) <-- 制御対象へ設定値書き込み
上記関数の引数IDとは制御盤に表示されているポイント、信号機、コントローラー、センサー、スイッチの識別番号です。
(IDはキーボードのnで表示/非表示が切替わります。)
auto_read(ID)の戻り値と、auto_write(ID,data)の書き込みデータ の意味と値域は以下の通りです。
ポイント、スローポイント、スイッチでは接続方向を示す0 or 1
3灯式信号機では 赤=1、 黄=2、青=3、消灯=0
6灯式信号機では下2bitが右側、その上の2bitが左側の信号色指定になっているため
赤赤=5,赤黄=6,赤青=7,黄赤=9,黄黄=10,黄青=11,青赤=13,青黄=14,青青=15,消灯=0
コントローラーでは車両の駆動電圧制御値(PWM値)で0~200
センサーは読み出し値が列車検出時に1、未検出時に0で、書き込みはできません。
3灯式信号機では 赤=1、 黄=2、青=3、消灯=0
6灯式信号機では下2bitが右側、その上の2bitが左側の信号色指定になっているため
赤赤=5,赤黄=6,赤青=7,黄赤=9,黄黄=10,黄青=11,青赤=13,青黄=14,青青=15,消灯=0
コントローラーでは車両の駆動電圧制御値(PWM値)で0~200
センサーは読み出し値が列車検出時に1、未検出時に0で、書き込みはできません。
コントローラーは複数の項目数値を持っていて、IDの次に項目指定の1文字を追加することでアクセスできます。
例えば電流値ならauto_read(ID,"m")、加速度設定するならauto_write(ID,"a",data)と記述します。
コントローラーの項目指定文字列(1文字)と項目の意味、値域は以下の通りです。
"m" = 列車の駆動電流で単位はmA(検出最小単位は10mA、誤差±10mA程度)、読み出しのみ可能
"o" = 列車の駆動電圧制御値(PWM値)に下駄を履かせるためのoffsetで0~126
"a" = 加速度(列車の駆動電圧の変化の速さを指定)で1~126
"t" = 列車の駆動電圧制御値(PWM値)を変動させる周期で10msec,20msec,30msec,40msecのいずれか(車両の低速安定化のためのwobbling用)
"p" = 列車の駆動電圧制御値(PWM値)の変動幅で0~62((車両の低速安定化のためのwobbling用)
"v" = 列車の駆動電圧制御値(PWM値)で0~200(文字指定なしの場合と同じ)
なお信号機にも複数項目(色別タイマー)がありますがそれらには未対応です。
==== 制御対象の状態変化検出関数 ===="o" = 列車の駆動電圧制御値(PWM値)に下駄を履かせるためのoffsetで0~126
"a" = 加速度(列車の駆動電圧の変化の速さを指定)で1~126
"t" = 列車の駆動電圧制御値(PWM値)を変動させる周期で10msec,20msec,30msec,40msecのいずれか(車両の低速安定化のためのwobbling用)
"p" = 列車の駆動電圧制御値(PWM値)の変動幅で0~62((車両の低速安定化のためのwobbling用)
"v" = 列車の駆動電圧制御値(PWM値)で0~200(文字指定なしの場合と同じ)
なお信号機にも複数項目(色別タイマー)がありますがそれらには未対応です。
auto_check(ID) <-- 関数内でauto_read(ID)により制御対象の状態を読み出し、前回実行時の値と今回の値を比べて異なっていたら1、同じなら0を返す。
auto_check(ID,new=A) <-- 前回、今回で読み出し値に変化があり、今回のデータがAと同じなら1、それ以外なら0を返す。
auto_check(ID,old=B) <-- 前回、今回で読み出し値に変化があり、前回のデータがBと同じなら1、それ以外なら0を返す。
auto_check(ID,new=A,old=B) <-- 前回、今回で読み出し値に変化があり、今回のデータがAと同じでさらに前回のデータがBと同じなら1、それ以外なら0を返す。
コントローラーの各項目をチェックしたい場合は上記のauto_readと同じように識別文字を追加することで可能です。
例えばauto_check(ID,"m")と記述します。
auto_checkk(ID)の初回実行時は前回の読み出し値が未定義となりますが、その場合は0を返します。
==== 時間計測、判定関数 ====
以下の関数により時間計測のスタート、経過時間の取得、時間の判定を行なうことができます。
異なったスタート時刻や経過時間を独立に扱うため、呼出時の引数としてkeyを指定します。
keyは数字や文字列が使えます。
auto_time_start(key) <-- keyで識別される時間計測を0からスタートさせる。
auto_time(key) <-- keyで識別される経過時間を単位が秒の浮動小数点数として返す。。
auto_time_check(key,t) <-- keyで識別される経過時間がt未満なら0を返す。
経過時間がt以上なら時間計測を0から再スタートし戻り値として1を返す。tは単位が秒の浮動小数点数または整数。
もしkeyで識別される時間計測がまだスタートしていない場合はスタートさせ、戻り値として0を返す。
==== 初期化のための変数 ====
auto_init_flag
これは関数ではなく初期値が1に設定された単なる変数です。
繰り返し実行される自動運転プログラムの中で初期化処理を行なうためにメインプログラム側で定義しています。
demo2.py、demo3.pyで使用し、解説しています。
【デモプログラム】
自動運転プログラムの参考例として3本を紹介します。
これらのプログラムを修正、拡張すればかなり複雑な自動運転も可能だと思います。
demo1.py
No.4かNo.6のどちらかの信号機をマウスクリックの手動操作で青に変化させると自動でもう一方の信号機を赤にしてNo2のポイントも切り替えます。
プログラム起動はハードウェア無しの場合ではコマンドウィンドウで
python ./dummy_hard_ikcp2.py demo1.py
と入力するか、バッチファイル dummy_hard_demo1.cmd をダブルクリックします。
demo1.pyやバッチファイルの内容はテキストエディタで見たり修正したりできます。
if文の条件判定にauto_check()を使用し、条件に応じてauto_write()で信号機とポイントへ設定値を書き込んでいます。
auto_check()を使用しているので信号機が青に変化するとその後1回だけ書き込みが行なわれます。
#以降はコメント文です。
これらのプログラムを修正、拡張すればかなり複雑な自動運転も可能だと思います。
demo1.py
No.4かNo.6のどちらかの信号機をマウスクリックの手動操作で青に変化させると自動でもう一方の信号機を赤にしてNo2のポイントも切り替えます。
プログラム起動はハードウェア無しの場合ではコマンドウィンドウで
python ./dummy_hard_ikcp2.py demo1.py
と入力するか、バッチファイル dummy_hard_demo1.cmd をダブルクリックします。
demo1.pyやバッチファイルの内容はテキストエディタで見たり修正したりできます。
if文の条件判定にauto_check()を使用し、条件に応じてauto_write()で信号機とポイントへ設定値を書き込んでいます。
auto_check()を使用しているので信号機が青に変化するとその後1回だけ書き込みが行なわれます。
#以降はコメント文です。
demo2.py
プログラム起動はハードウェア無しの場合ではコマンドウィンドウで
python ./dummy_hard_ikcp2.py demo2.py
と入力するか、バッチファイル dummy_hard_demo2.cmd をダブルクリックします。
demo2.pyやバッチファイルの内容はテキストエディタで見たり修正したりできます。
以下、内容について説明します。
まず先頭のif文でauto_init_flagを判定に使ってstate1とstate2の変数を1に初期化しています。
判定後にauto_init_flag=0にしていますので、demo2.pyの最初の実行時のみ初期化処理が行なわれます。
その次の前半のif/elif文ではID番号=2のポイント切替とID番号=4の信号機の信号色切替を行なっています。
後半のif/elif文ではID番号1のコントローラーの設定値をいろいろ変更しています。
前半、後半ともauto_time_check(key,t)でtで指定した遅延時間後に各動作が行なわれます。
また各動作毎にstate1、state2を更新し次の動作の選択に使用することで実行順序を制御しています。
前半、後半の動作をお互いに干渉せず独立したタイミングで行なうために auto_time_check(key,t)のkeyを1、2と異なるものとし、動作順指定の変数もstate1、state2と別にしています。
プログラム起動はハードウェア無しの場合ではコマンドウィンドウで
python ./dummy_hard_ikcp2.py demo2.py
と入力するか、バッチファイル dummy_hard_demo2.cmd をダブルクリックします。
demo2.pyやバッチファイルの内容はテキストエディタで見たり修正したりできます。
以下、内容について説明します。
まず先頭のif文でauto_init_flagを判定に使ってstate1とstate2の変数を1に初期化しています。
判定後にauto_init_flag=0にしていますので、demo2.pyの最初の実行時のみ初期化処理が行なわれます。
その次の前半のif/elif文ではID番号=2のポイント切替とID番号=4の信号機の信号色切替を行なっています。
後半のif/elif文ではID番号1のコントローラーの設定値をいろいろ変更しています。
前半、後半ともauto_time_check(key,t)でtで指定した遅延時間後に各動作が行なわれます。
また各動作毎にstate1、state2を更新し次の動作の選択に使用することで実行順序を制御しています。
前半、後半の動作をお互いに干渉せず独立したタイミングで行なうために auto_time_check(key,t)のkeyを1、2と異なるものとし、動作順指定の変数もstate1、state2と別にしています。
demo3.py
プログラム起動はハードウェア無しの場合ではコマンドウィンドウで
python ./dummy_hard_ikcp2.py demo3.py
と入力するか、バッチファイル dummy_hard_demo3.cmd をダブルクリックします。
demo3.pyやバッチファイルの内容はテキストエディタで見たり修正したりできます。
このプログラムは全種類のハードウェアについての値の読み出しと書き込みを行なう例として作成しました。
auto_time_check(0,1.0)を条件判定に使い、約1秒毎にハードウェアの値の読み出しと別の値の書き込みを行ないます。
ハードウェアを選択するための変数 stateは1秒毎に更新し、すべてのハードウェアにアクセスし終わったらstateをリセットしてループさせています。
なお、センサーは読み出しのみ可能で書き込みはできないので、コマンドウインドウへ読み出し値をプリントしています。
プログラム起動はハードウェア無しの場合ではコマンドウィンドウで
python ./dummy_hard_ikcp2.py demo3.py
と入力するか、バッチファイル dummy_hard_demo3.cmd をダブルクリックします。
demo3.pyやバッチファイルの内容はテキストエディタで見たり修正したりできます。
このプログラムは全種類のハードウェアについての値の読み出しと書き込みを行なう例として作成しました。
auto_time_check(0,1.0)を条件判定に使い、約1秒毎にハードウェアの値の読み出しと別の値の書き込みを行ないます。
ハードウェアを選択するための変数 stateは1秒毎に更新し、すべてのハードウェアにアクセスし終わったらstateをリセットしてループさせています。
なお、センサーは読み出しのみ可能で書き込みはできないので、コマンドウインドウへ読み出し値をプリントしています。
【注意点】
・関数auto_check()やauto_time_check()は前回実行時の値をauto_save、auto_time_saveという名前のpythonの辞書データに格納しています。
ですので自動運転プログラム(ユーザープログラム)側ではこのデータ名を使わないようにしてください。
・レイアウト上の各種初期設定(信号色やポイントの切替方向、コントローラー=PWR_S基板の設定)は自動運転プログラム内で行なうこともできますが面倒です。
そこで運転制御盤のGUIでマウスやキーボードを使うか、制御基板に接続されたスイッチを使って初期状態を設定し、wキー入力で制御盤データファイル control_panel_数字.txt にその状態を出力するほうが簡単です。
以降は自動運転プログラム起動時に対応する制御盤データファイルを指定すればOKとなります。
なお、このレイアウトの初期状態設定と書き出しは制御盤エディタではできません。
dummy_hard_ikcp2.py か bt_ikcp2.py、または us_ikcp2.py を自動運転プログラムの指定なしで起動して行ないます。
・コメント文やコマンドウィンドウにプリントする文字列として日本語文字を使う場合は以下の文字コード指定をプログラムの先頭行に追加する必要があります。
# -*- coding: utf-8 -*-
またプログラムをテキストエディタで作成または修正して出力するときの文字コードをutf-8(ユニコード)にする必要があります。
ですので自動運転プログラム(ユーザープログラム)側ではこのデータ名を使わないようにしてください。
・レイアウト上の各種初期設定(信号色やポイントの切替方向、コントローラー=PWR_S基板の設定)は自動運転プログラム内で行なうこともできますが面倒です。
そこで運転制御盤のGUIでマウスやキーボードを使うか、制御基板に接続されたスイッチを使って初期状態を設定し、wキー入力で制御盤データファイル control_panel_数字.txt にその状態を出力するほうが簡単です。
以降は自動運転プログラム起動時に対応する制御盤データファイルを指定すればOKとなります。
なお、このレイアウトの初期状態設定と書き出しは制御盤エディタではできません。
dummy_hard_ikcp2.py か bt_ikcp2.py、または us_ikcp2.py を自動運転プログラムの指定なしで起動して行ないます。
・コメント文やコマンドウィンドウにプリントする文字列として日本語文字を使う場合は以下の文字コード指定をプログラムの先頭行に追加する必要があります。
# -*- coding: utf-8 -*-
またプログラムをテキストエディタで作成または修正して出力するときの文字コードをutf-8(ユニコード)にする必要があります。