inputs.Transmitters

class inputs.Transmitters

Provides access to transmitters via reference or directly.

The following example displays the value of each transmitter on a TextScreen, which it assumes is assigned on any port.

from dataclasses import dataclass
from typing import List
from inputs import *
from controllables import TextScreen

# get any screen that's attached
screen = TextScreen()
screen.horizontal_alignment = TextScreen.HorizontalAlignment.LEFT

# one way to get a transmitter is via the transmitter reference class
left_transmitter : TransmitterReference = Transmitters.left_transmitter()

# we're going to collect the state of each button in this list
@dataclass
class ButtonData:
    hand : Hand
    id : ButtonId
    stream : Stream[float]
    last_signal : float = 0

button_data : List[ButtonData] = []

# here we fill in the buttons on the left transmitter
for button in ButtonId:
    left_stream = left_transmitter.stream(button)
    button_data.append(ButtonData(Hand.LEFT,button,left_stream))

# and here we fill in the buttons on the right transmitter
for button in ButtonId:
    # instead of getting a transmitter reference we skip
    # right to getting the stream via the stream function
    right_stream = Transmitters.stream(button,Hand.RIGHT)
    button_data.append(ButtonData(Hand.RIGHT,button,right_stream))

while True:
    for data in button_data:
        # copy all the signals into a buffer list
        incoming_signals = list(data.stream)
        # it'll be empty if our loop runs between samples
        if len(incoming_signals) > 0:
            # we ignore every sample except the freshest
            data.last_signal = incoming_signals[-1]
            # we could instead get the average, max, or
            # some other interesting value if we wanted
    # we assign the text all at once, because reassigning
    # to screen.text during play can cause half formed strings
    # to appear due to rendering in the middle of a loop
    screen.text = '\n'.join([f'{data.hand.name:5} {data.id.name:8}: {data.last_signal:1.1f}' for data in button_data])
static left_transmitter(id: int = 0) TransmitterReference

Use this to get a left handed transmitter. The id parameter is zero indexed.

The below code demonstrates listening to multiple left transmitter streams. It assumes that a TextScreen is assigned to a port.

from inputs import *
from controllables import TextScreen

screen = TextScreen()

purple_transmitter = Transmitters.left_transmitter(0)
blue_transmitter = Transmitters.left_transmitter(1)

purple_stream = purple_transmitter.stream(ButtonId.UP)
blue_stream = blue_transmitter.stream(ButtonId.UP)

purple_signal = 0
blue_signal = 0
while True:
    for signal in purple_stream:
        purple_signal = signal

    for signal in blue_stream:
        blue_signal = signal

    screen.text = f'purple: {purple_signal:0.2f}\nblue: {blue_signal:0.2f}'
static right_transmitter(id: int = 0) TransmitterReference

Use this to get a right handed transmitter. The id parameter is zero indexed.

The below code demonstrates listening to multiple right transmitter streams. It assumes that a TextScreen is assigned to a port.

from inputs import *
from controllables import TextScreen

screen = TextScreen()

orange_transmitter = Transmitters.right_transmitter(0)
red_transmitter = Transmitters.right_transmitter(1)

orange_stream = orange_transmitter.stream(ButtonId.UP)
red_stream = red_transmitter.stream(ButtonId.UP)

orange_signal = 0
red_signal = 0
while True:
    for signal in orange_stream:
        orange_signal = signal

    for signal in red_stream:
        red_signal = signal

    screen.text = f'orange: {orange_signal:0.2f}\nred: {red_signal:0.2f}'
static custom_transmitter() TransmitterReference

Use this to get a custom (i.e. keyboard) transmitter.

The example below demonstrates how to listen to a stream from a custom transmitter. It assumes that a TextScreen is a assigned to any port.

from inputs import *
from controllables import TextScreen

screen = TextScreen()

custom_transmitter = Transmitters.custom_transmitter()

x_stream = custom_transmitter.stream('x')

signal = 0
while True:
    for signal in x_stream:
        signal = signal

    screen.text = f'x: {signal:0.2f}'
static press(key: Union[ButtonId, str], value: float, hand: Optional[Hand], id: int = 0)

Use this to set the key of a transmitter to value. value refers to a float between 0 and 1 where 0 refers to button not being pressed and 1 being fully pressed. The key will retain its value until you call this method again. The value that the transmitter uses is the maximum of the value that is set here and the value from the real physical controller.

key should be supplied as a ButtonId when hand is set and it should supplied as a str otherwise. In the later case, it should be a single ascii letter corresponding to the key being pressed.

hand refers to the hand of the transmitter on which you want to set a key. hand should be None when pressing keys on a custom (i.e. keyboard) transmitter.

id disambiguates which transmitter on the chosen hand to press. The first transmitter has id zero. Custom transmitters don’t use id.

The following example demonstrates pressing transmitter keys on the left and custom transmitter. To see the effects, ensure that these transmitters are hooked up to actions on the robot.

from inputs import *
from time import sleep

while True:
    # press up on the left hand
    Transmitters.press(ButtonId.UP,1,Hand.LEFT)
    sleep(1)
    # release it
    Transmitters.press(ButtonId.UP,0,Hand.LEFT)
    # and press x on the custom transmitter
    Transmitters.press('x',1,None)
    sleep(1)
    # and then release it and loop
    Transmitters.press('x',0,None)
static press_left(button_id: ButtonId, value: float, id: int = 0)

Alias for press() with hand set to LEFT and passing button_id as key

static press_right(button_id: ButtonId, value: float, id: int = 0)

Alias for press() with hand set to RIGHT and passing button_id as key

static press_custom(key: str, value: float)

Alias for press() with hand set to None

static stream(key: Union[ButtonId, str], hand: Optional[Hand], id: int = 0) Stream[float]

Returns a stream of input values from this transmitter for the key key.

The below example demonstrates how to read from the stream of a left transmitter and the custom transmitter.

from inputs import *
from controllables import TextScreen

# get the output screen
screen = TextScreen()
screen.horizontal_alignment = TextScreen.HorizontalAlignment.LEFT

# here we get the 'x' button stream from the custom transmitter
x_stream = Transmitters.stream('x',None)
# here we get the up button stream from the left transmitter
up_stream = Transmitters.stream(ButtonId.UP,Hand.LEFT)

x_signal = 0
up_signal = 0
# in an infinite loop
while True:
    # we'll get get the last signal in the x stream
    for signal in x_stream:
        x_signal = signal

    # we'll get get the last signal in the up stream
    for signal in up_stream:
        up_signal = signal

    screen.text = f'x: {x_signal: 0.1f}\nup: {up_signal :0.1f}'
static reset()

Use this to clear any keys that are being pressed from code.

The following example shows how to use reset to release previous press commands. To see the effects, ensure that the transmitters are hooked up to actions on the robot.

from inputs import *
from time import sleep

while True:
    # press up on the left hand
    Transmitters.press(ButtonId.UP,1,Hand.LEFT)
    sleep(1)
    # release it
    Transmitters.reset()
    # and press x on the custom transmitter
    Transmitters.press('x',1,None)
    sleep(1)
    # and then release it and loop
    Transmitters.reset()