本文へ進む

分岐を通るたびに進路を交互に変える

分岐の色通知を数え、左右の進路とライトを切り替えます。

必要な本体
1台。
線路・準備
内側と外側の周回コースを分岐でつなぎます。
終了方法
Enterで購読解除・停止。最後に接続を終了。
保存する場所
matrain-python-async/examples/alternating_routes.py
実行する場所
matrain-python-asyncフォルダー内。.venvのPythonを使います。

Mac:.venv/bin/python examples/alternating_routes.pyWindows:.venv\Scripts\python.exe examples\alternating_routes.py

通常終了の処理を原例のまま掲載しています。例外やCtrl+Cでの停止が保証されないため、異常時は本体のボタンを短く押して止めます。切断だけを停止とみなさないでください。

コード全文

alternating_routes.py
# Matrain publication modification: licensing/source notice added.
# Executable behavior is unchanged except for the adaptations documented below.
# Source: https://github.com/intelino-code/intelino-trainlib-async-py
# Source commit: 298e1fd4091e069180c30f338b4c285b13accbd0
# This software is made available by Innokind, Inc. DBA Intelino, under the
# terms of the Intelino Public License Agreement, Version 1.0 located at
# https://intelino.com/intelino-public-license. BY INSTALLING, DOWNLOADING,
# ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, YOU AGREE TO THE TERMS OF
# SUCH LICENSE AGREEMENT.

"""Example: Alternating routes (left/right) - async version."""
import asyncio
import aioconsole
from intelino.trainlib_async import (
    TrainScanner,
    Train,
)
from intelino.trainlib_async.messages import (
    TrainMsg,
    TrainMsgEventSnapCommandDetected,
)
from intelino.trainlib_async.enums import SteeringDecision, SnapColorValue


async def set_decision(train: Train, split_counter: int):
    """Pick a side based on the split counter."""
    if split_counter % 2 == 0:
        side = SteeringDecision.RIGHT
        color = (0, 0, 255)  # blue
    else:
        side = SteeringDecision.LEFT
        color = (255, 0, 0)  # red

    print(f"Next {repr(side)}, splits seen: {split_counter}")
    await train.set_next_split_steering_decision(side)
    await train.set_headlight_color(color, color)


def is_split_track_snap(msg: TrainMsgEventSnapCommandDetected):
    """Helper function to identify split track snaps."""
    return (msg.colors[0] == SnapColorValue.CYAN) and (
        msg.colors[1] != SnapColorValue.BLACK
    )


async def alternating_routes(train: Train):
    """Alternate between left and right turns."""
    split_counter = 0

    def observer_func(msg: TrainMsg):
        nonlocal split_counter

        if isinstance(msg, TrainMsgEventSnapCommandDetected) and is_split_track_snap(
            msg
        ):
            # we are on a split track (identified by its snaps)
            split_counter += 1
            asyncio.create_task(set_decision(train, split_counter))

    # subscribe to the notification stream
    subscription = train.notifications.subscribe(observer_func)

    await set_decision(train, split_counter)
    await train.drive_at_speed(40)

    # let the train run until the 'enter' key is pressed
    await aioconsole.ainput("Press <Enter> to exit at any time...\n")

    # cleanup
    subscription.dispose()
    await train.stop_driving()


async def main():
    async with TrainScanner() as train:
        # run our train program
        await alternating_routes(train)


if __name__ == "__main__":
    asyncio.run(main())

冒頭に配布条件と出典のコメントを追加しています。表示している全文と、個別保存・ZIP内のこのファイルは同じです。ライセンス・出典を読む

ファイルのダウンロード

ダウンロードの確認

ファイル名:

この端末に保存します。閲覧中のページはそのまま残ります。