本体 スナップ Scratch Python 現在地 まず、コード全体を見る 準備・接続ができていなければ、最初の準備 から進めます。以下のコードは、IDLEの編集画面へ丸ごと貼り付けて実行する例です。
first_train.pyの全体 コピー
from time import sleep
from intelino.trainlib import TrainScanner
with TrainScanner(timeout=10.0) as train:
print("connected:", train.name)
try:
train.drive_at_speed(30)
sleep(3)
finally:
train.stop_driving()
print("stopped")
print("finished")上から順番に読む from … import … は、使う道具を読み込む行です。TrainScannerはスマートトレイン本体を探す道具、sleepは指定した秒数だけ処理を待つ道具です。
withでスマートトレイン本体に接続し、trainという名前を付けます。train.drive_at_speed(30)は「そのスマートトレイン本体へ、30 cm/秒で走る命令を送る」という意味です。括弧の中が、命令に渡す値(引数)です。
コロン(:)の下の字下げは、処理のまとまりを表します。tryの中を実行した後、finallyの中で停止を試みます。字下げや括弧もコードの一部なので、消さずに使ってください。
下の短いコードは命令を試すための部分です。接続済みのtrainが必要で、そのまま単独のファイルとして実行するものではありません。走行やライトの例はtryの中へ字下げして入れ、finallyの停止処理を残します。
探す・接続する 命令を送る前に、どのスマートトレイン本体を使うか決めます。まずは1台で、名前が表示されるところまで確かめます。
スマートトレイン本体を探して接続する TrainScanner(timeout=10.0)from intelino.trainlib import TrainScannerは、スマートトレイン本体を探す道具を使えるようにする行です。
with … as train:で見つかったスマートトレイン本体をtrainという名前で扱います。その下で字下げした行が、接続中に行う処理です。timeoutは探す時間の上限で、走る時間ではありません。
何台も電源が入っていると、最初に見つかった別のスマートトレイン本体につながることがあります。対象を限定するときはdevice_identifierにスマートトレイン本体のBluetooth/UUIDアドレスを指定します。
接続部分の例(import行が必要) コピー
with TrainScanner(timeout=10.0) as train:
print(train.name) 1台・複数台を取得する get_train() / get_trains(count)最初のうちはwithを使う例で十分です。複数台の作例では、get_trains(2)のように台数を指定してスマートトレイン本体をまとめて受け取ります。
受け取った複数台には、それぞれ停止と切断が必要です。複数台の動かし方は共通の「Pythonの作例」に、終了処理まで含めて載せています。
countを省略、または0にすると時間内に見つかったスマートトレイン本体を取得します。at_mostで上限だけ指定する方法もあります。
名前・接続状態を読む name / is_connected値を読むだけの項目には、命令を実行する()を付けません。printは画面に表示するPythonの命令です。
Trueなら接続中、Falseなら未接続です。ただし、その後も通信が続く保証ではありません。実行中にスマートトレイン本体の電源が切れれば接続は失われます。
この案内の通信ライブラリでは、切断後も接続中の値が残る場合があります。接続・再接続の細かな条件は技術リファレンスで確認してください。
接続後に使う部分の例 コピー
print(train.name)
print(train.is_connected) 接続を終える disconnect()withを使う例では、字下げした部分を抜けると自動でdisconnectが呼ばれます。初心者向けの例では自分で追加する必要はありません。
切断は走行停止と同じではありません。まずstop_drivingで停止を送り、そのあと切断します。切断済みのtrainへさらに命令を送らず、新しい接続を作ります。
走る・止まる・分岐 最初に走って止まるコードを完成させ、その中の速さや時間を一つずつ変えてみます。
速さを数値で決める drive_at_speed(30)30は1秒あたり30 cmという速さの指定です。「30 cmだけ進む」という距離の指定ではありません。
実際の目標速度は本体の刻みに合わせて調整される場合があります。sleep(3)と合わせても正確な90 cmの移動を保証するものではありません。
後進する場合は、ファイル先頭でfrom intelino.trainlib.enums import MovementDirectionを追加し、direction=MovementDirection.BACKWARDを指定します。
接続後に使う部分の例 コピー
train.drive_at_speed(30)
sleep(3) スマートトレイン本体を止める stop_driving()sleep(3)はPythonを3秒待たせるだけです。走り続けているスマートトレイン本体を止めるにはstop_driving()が必要です。
最初の例ではfinallyの中に置いています。途中で通常の例外やCtrl+Cが起きたときも停止を試みるためです。ただし通信が切れていれば停止命令を届けられません。
接続後に使う部分の例 コピー
train.stop_driving() 速さを段階で選ぶ drive_at_speed_level(SpeedLevel.LEVEL1)数値で速さを指定する代わりに、決められた段階で動かせます。drive_at_speedと使い方を区別します。
ファイル先頭にfrom intelino.trainlib.enums import SpeedLevelを追加します。段階の名前を文字列の引用符で囲む必要はありません。
接続後に使う部分の例 コピー
train.drive_at_speed_level(
SpeedLevel.LEVEL1
)
sleep(3) 次の分岐を選ぶ set_next_split_steering_decision(next_decision)ファイル先頭にfrom intelino.trainlib.enums import SteeringDecisionを追加します。次に通る分岐へ着く前に命令を送ります。
これはスマートトレイン本体を発進させる命令ではありません。分岐レールと、その進行方向から選べる道を確認してから走らせます。LEFTとRIGHTはスマートトレイン本体の進行方向から見た左右です。
接続後に使う部分の例 コピー
train.set_next_split_steering_decision(
SteeringDecision.LEFT
)
train.drive_at_speed(30)
sleep(3) 貨車を切り離す decouple_wagon()切り離す位置を決め、貨車を正しい向きで連結して試します。この命令は、白・黄のスナップを置かずにPythonから切り離しを指示するものです。
切り離しだけで目的地まで運べるわけではありません。走る・止める処理と組み合わせて、切り離した後の動きも確かめます。
接続後に使う部分の例 コピー
train.decouple_wagon() ライト・スナップ ライトの色は数値で指定します。スナップの設定を変える命令では、スマートトレイン本体本体に保存されている動作との関係も確認します。
上のライトの色を変える set_top_led_color(r, g, b)3つの数字は光の赤・緑・青の強さです。例えば(255, 0, 0)は赤、(0, 0, 255)は青です。
最初のコードのtryの中を、次の3行に替えて試せます。sleepの間に色を見て、最後の行で上のライトを消します。
接続後に使う部分の例 コピー
train.set_top_led_color(0, 80, 255)
sleep(3)
train.set_top_led_color(0, 0, 0) 前後のライトの色を変える set_headlight_color(front=None, back=None)frontとbackはそれぞれ3つの数字の組です。上のライトの命令とは別に、走行用の前後ライトを設定します。
set_headlight_color()は直前に指定した色を記憶して戻す機能ではなく、本体の標準の色へ戻す呼び出しです。
接続後に使う部分の例 コピー
train.set_headlight_color(
front=(255, 255, 255),
back=(255, 0, 0)
)
sleep(3)
train.set_headlight_color() スナップの本体動作を切り替える set_snap_command_execution(True)スナップの色を読んだときに本体が行う動作をオン・オフする設定です。Pythonのイベントを登録する命令とは別です。
Falseにしたままだと、スナップだけで遊ぶときの動きも変わります。試した後はTrueへ戻します。色の検出と、読み取った命令の実行を区別してください。
対応する本体のBLE APIが1.2未満では使えません。実行に失敗するときは、単なる入力ミスと決めつけず対応条件を確認します。
接続後に使う部分の例 コピー
train.set_snap_command_execution(True) 保存されたカスタム動作を消す clear_custom_snap_commands()紫を含むスナップに、ゲームアプリで動きを登録していると、Pythonの処理と本体の動きが重なる場合があります。
この命令はその設定を消します。見ているだけの確認用命令ではありません。残したい設定がある場合は、消す必要があるかを先に考えます。
接続後に使う部分の例 コピー
train.clear_custom_snap_commands() 値を読む・変化を受け取る 今の値を読むことと、変化したときに知らせてもらうことは別です。まず画面に表示して、何を受け取ったかを確かめます。
距離・速さ・向きを読む distance_cm / speed_cmps / directiontrain.distance_cmのように書くと、本体から受け取っている値を読めます。数字を表示するだけならprintと組み合わせます。
読み取った値には通信や更新のタイミングがあります。目で見た位置と常に完全一致する測定値とは考えず、何度か試して比較します。
接続後に使う部分の例 コピー
print(train.distance_cm)
print(train.speed_cmps)
print(train.direction) 前側で色が変わったら受け取る add_front_color_change_listener(listener)関数は、名前を付けてまとめた処理です。def on_color(train, event):の下に、色が変わったときに行うことを書きます。
listenerは、その変化を受け取る関数です。登録するときはon_colorと名前だけを書き、on_color()とはしません。すぐ実行するのではなく、変化したときに呼んでもらうためです。
下の完成例を別の.pyファイルへ保存して実行します。色スナップを通る線路を用意し、表示される色を確かめます。複数色の並びを受け取るイベントとは別です。
色の変化を表示するコード全体 コピー
from time import sleep
from intelino.trainlib import TrainScanner
def on_color(train, event):
print(event.color)
with TrainScanner(timeout=10.0) as train:
train.add_front_color_change_listener(on_color)
try:
train.drive_at_speed(30)
sleep(5)
finally:
train.stop_driving()
train.remove_front_color_change_listener(on_color)色の並びを合図にする add_snap_command_detection_listener(listener)前側センサーの単色はcolor、スナップコマンドとして受け取った色の並びはcolorsです。末尾のsを見落とさないようにします。
「検出した」と「本体がその命令を実行した」も別の出来事です。add_snap_command_execution_listenerは実行側のイベントを受け取る命令です。
色の並びを使った完成コードは「スナップを合図にする」の作例で試せます。受け取る処理を登録した後、接続をすぐ終わらせないことも必要です。
分岐の判断を受け取る add_split_decision_listener(listener)次の分岐を選ぶset_next_split_steering_decisionと違い、こちらは分岐の判断が起きたことを受け取ります。
イベントを受け取る関数は、同期版でも別のスレッドで動きます。複数台で同じ変数や区間を扱う処理では、順番の衝突を考慮する必要があります。完成作例の終了処理と合わせて確認してください。
さらに詳しく実装する方へ 同期・非同期の全命令、通知、戻り値、列挙値、例外と細かな制約は技術リファレンス で確認できます。