本文へ進む

進行方向に合うセンサーの色を使う

前進時は前側、後進時は後側の色通知を使います。

必要な本体
1台。
線路・準備
色スナップを付けた周回コース。
終了方法
Enterで購読解除・停止・前後ライトを戻して切断。
保存する場所
matrain-python-async/examples/color_change/1b_single_train_driving.py
実行する場所
matrain-python-asyncフォルダー内。.venvのPythonを使います。

Mac:.venv/bin/python examples/color_change/1b_single_train_driving.pyWindows:.venv\Scripts\python.exe examples\color_change\1b_single_train_driving.py

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

コード全文

color_change/1b_single_train_driving.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.

"""Color change event example (1b): Single train driving."""
import asyncio
import aioconsole
from intelino.trainlib_async import (
    TrainScanner,
    Train,
)
from intelino.trainlib_async.messages import (
    TrainMsg,
    TrainMsgEventFrontColorChanged,
    TrainMsgEventBackColorChanged,
    TrainMsgEventMovementDirectionChanged,
)
from intelino.trainlib_async.enums import SnapColorValue, MovementDirection


async def color_change(train: Train):
    """
    Wait for color change events and set headlights/taillights
    based on the seen color on the front sensor relative to the driving
    direction.
    """
    # train's local state
    drive_direction: MovementDirection = MovementDirection.STOP

    async def new_color(color: SnapColorValue):
        if color not in (SnapColorValue.BLACK, SnapColorValue.UNKNOWN):
            # ignore black and unknown
            print(f"New color: {color}")
            rgb = color.to_rgb_bytes()
            await train.set_headlight_color(rgb, rgb)

    def observer_func(msg: TrainMsg):
        nonlocal drive_direction

        if isinstance(msg, TrainMsgEventMovementDirectionChanged):
            # update state only
            drive_direction = msg.direction

        elif isinstance(msg, TrainMsgEventFrontColorChanged):
            if drive_direction != MovementDirection.BACKWARD:
                # accept forward and stopped directions
                asyncio.create_task(new_color(msg.color))

        elif isinstance(msg, TrainMsgEventBackColorChanged):
            if drive_direction == MovementDirection.BACKWARD:
                asyncio.create_task(new_color(msg.color))

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

    # start driving
    await train.drive_at_speed(35)

    # let the train program 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()
    await train.set_headlight_color()


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


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

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

ファイルのダウンロード

ダウンロードの確認

ファイル名:

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