viam.components.input
=====================
.. py:module:: viam.components.input
Submodules
----------
.. toctree::
:maxdepth: 1
/autoapi/viam/components/input/client/index
/autoapi/viam/components/input/input/index
/autoapi/viam/components/input/service/index
Attributes
----------
.. autoapisummary::
viam.components.input.ControlFunction
Classes
-------
.. autoapisummary::
viam.components.input.Control
viam.components.input.Controller
viam.components.input.Event
viam.components.input.EventType
Package Contents
----------------
.. py:class:: Control
Bases: :py:obj:`str`, :py:obj:`enum.Enum`
Control identifies the input (specific Axis or Button) of a controller.
.. py:attribute:: ABSOLUTE_X
:value: 'AbsoluteX'
.. py:attribute:: ABSOLUTE_Y
:value: 'AbsoluteY'
.. py:attribute:: ABSOLUTE_Z
:value: 'AbsoluteZ'
.. py:attribute:: ABSOLUTE_RX
:value: 'AbsoluteRX'
.. py:attribute:: ABSOLUTE_RY
:value: 'AbsoluteRY'
.. py:attribute:: ABSOLUTE_RZ
:value: 'AbsoluteRZ'
.. py:attribute:: ABSOLUTE_HAT0_X
:value: 'AbsoluteHat0X'
.. py:attribute:: ABSOLUTE_HAT0_Y
:value: 'AbsoluteHat0Y'
.. py:attribute:: BUTTON_SOUTH
:value: 'ButtonSouth'
.. py:attribute:: BUTTON_EAST
:value: 'ButtonEast'
.. py:attribute:: BUTTON_WEST
:value: 'ButtonWest'
.. py:attribute:: BUTTON_NORTH
:value: 'ButtonNorth'
.. py:attribute:: BUTTON_LT
:value: 'ButtonLT'
.. py:attribute:: BUTTON_RT
:value: 'ButtonRT'
.. py:attribute:: BUTTON_LT2
:value: 'ButtonLT2'
.. py:attribute:: BUTTON_RT2
:value: 'ButtonRT2'
.. py:attribute:: BUTTON_L_THUMB
:value: 'ButtonLThumb'
.. py:attribute:: BUTTON_R_THUMB
:value: 'ButtonRThumb'
.. py:attribute:: BUTTON_SELECT
:value: 'ButtonSelect'
.. py:attribute:: BUTTON_START
:value: 'ButtonStart'
.. py:attribute:: BUTTON_MENU
:value: 'ButtonMenu'
.. py:attribute:: BUTTON_RECORD
:value: 'ButtonRecord'
.. py:attribute:: BUTTON_E_STOP
:value: 'ButtonEStop'
.. py:attribute:: ABSOLUTE_PEDAL_ACCELERATOR
:value: 'AbsolutePedalAccelerator'
.. py:attribute:: ABSOLUTE_PEDAL_BRAKE
:value: 'AbsolutePedalBrake'
.. py:attribute:: ABSOLUTE_PEDAL_CLUTCH
:value: 'AbsolutePedalClutch'
.. py:data:: ControlFunction
.. py:class:: Controller(name: str, *, logger: Optional[logging.Logger] = None)
Bases: :py:obj:`viam.components.component_base.ComponentBase`
Controller is a logical "container" more than an actual device
Could be a single gamepad, or a collection of digitalInterrupts
and analogReaders, a keyboard, etc.
::
from viam.components.input import Control, Controller, EventType
For more information, see `Input Controller component `_.
.. py:attribute:: API
:type: Final
The API of the Resource
.. py:method:: get_controls(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> List[Control]
:abstractmethod:
:async:
Returns a list of Controls provided by the Controller
::
# Get the controller from the machine.
my_controller = Controller.from_robot(
robot=machine, "my_controller")
# Get the list of Controls provided by the controller.
controls = await my_controller.get_controls()
# Print the list of Controls provided by the controller.
print(f"Controls: {controls}")
:returns: List of controls provided by the Controller
:rtype: List[Control]
For more information, see `Input Controller component `_.
.. py:method:: get_events(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> Dict[Control, Event]
:abstractmethod:
:async:
Returns the most recent Event for each input
(which should be the current state)
::
# Get the controller from the machine.
my_controller = Controller.from_robot(
robot=machine, "my_controller")
# Get the most recent Event for each Control.
recent_events = await my_controller.get_events()
# Print out the most recent Event for each Control.
print(f"Recent Events: {recent_events}")
:returns: The most recent event for each input
:rtype: Dict[Control, Event]
For more information, see `Input Controller component `_.
.. py:method:: register_control_callback(control: Control, triggers: List[EventType], function: Optional[ControlFunction], *, extra: Optional[Dict[str, Any]] = None, **kwargs)
:abstractmethod:
Register a function that will fire on given EventTypes for a given
Control
::
from viam.components.input import Control, EventType
# Define a function to handle pressing the Start Menu Button "BUTTON_START" on
# your controller, printing out the start time.
def print_start_time(event):
print(f"Start Menu Button was pressed at this time: {event.time}")
# Define a function that handles the controller.
async def handle_controller(controller):
# Get the list of Controls on the controller.
controls = await controller.get_controls()
# If the "BUTTON_START" Control is found, register the function
# print_start_time to fire when "BUTTON_START" has the event "ButtonPress"
# occur.
if Control.BUTTON_START in controls:
controller.register_control_callback(
Control.BUTTON_START, [EventType.BUTTON_PRESS], print_start_time)
else:
print("Oops! Couldn't find the start button control! Is your "
"controller connected?")
exit()
while True:
await asyncio.sleep(1.0)
async def main():
# ... < INSERT CONNECTION CODE FROM MACHINE'S CODE SAMPLE TAB >
# Get your controller from the machine.
my_controller = Controller.from_robot(
robot=machine, "my_controller")
# Run the handleController function.
await handle_controller(my_controller)
# ... < INSERT ANY OTHER CODE FOR MAIN FUNCTION >
:param control: The control to register the function for
:type control: Control
:param triggers: The events that will
trigger the function
:type triggers: List[EventType]
:param function: The function to run on
specific triggers
:type function: ControlFunction
For more information, see `Input Controller component `_.
.. py:method:: trigger_event(event: Event, *, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None, **kwargs) -> None
:async:
Directly send an Event (such as a button press) from external code
::
# Get your controller from the machine.
my_controller = Controller.from_robot(
robot=machine, "my_controller")
# Define a "Button is Pressed" event for the control BUTTON_START.
button_is_pressed_event = Event(
time(), EventType.BUTTON_PRESS, Control.BUTTON_START, 1.0)
# Trigger the event on your controller. Set this trigger to timeout if it has
# not completed in 7 seconds.
await my_controller.trigger_event(event=button_is_pressed_event, timeout=7.0)
:param event: The event to trigger
:type event: Event
For more information, see `Input Controller component `_.
.. py:method:: from_robot(robot: viam.robot.client.RobotClient, name: str) -> typing_extensions.Self
:classmethod:
Get the component named ``name`` from the provided robot.
:param robot: The robot
:type robot: RobotClient
:param name: The name of the component
:type name: str
:returns: The component, if it exists on the robot
:rtype: Self
.. py:method:: do_command(command: Mapping[str, ValueTypes], *, timeout: Optional[float] = None, **kwargs) -> Mapping[str, ValueTypes]
:abstractmethod:
:async:
Send/Receive arbitrary commands to the Resource
::
command = {"cmd": "test", "data1": 500}
result = await component.do_command(command)
:param command: The command to execute
:type command: Mapping[str, ValueTypes]
:raises NotImplementedError: Raised if the Resource does not support arbitrary commands
:returns: Result of the executed command
:rtype: Mapping[str, ValueTypes]
.. py:method:: get_geometries(*, extra: Optional[Dict[str, Any]] = None, timeout: Optional[float] = None) -> List[viam.proto.common.Geometry]
:async:
Get all geometries associated with the component, in their current configuration, in the
`frame `__ of the component.
::
geometries = await component.get_geometries()
if geometries:
# Get the center of the first geometry
print(f"Pose of the first geometry's centerpoint: {geometries[0].center}")
:returns: The geometries associated with the Component.
:rtype: List[Geometry]
.. py:method:: get_resource_name(name: str) -> viam.proto.common.ResourceName
:classmethod:
Get the ResourceName for this Resource with the given name
::
# Can be used with any resource, using an arm as an example
my_arm_name = Arm.get_resource_name("my_arm")
:param name: The name of the Resource
:type name: str
:returns: The ResourceName of this Resource
:rtype: ResourceName
.. py:method:: get_operation(kwargs: Mapping[str, Any]) -> viam.operations.Operation
Get the ``Operation`` associated with the currently running function.
When writing custom resources, you should get the ``Operation`` by calling this function and check to see if it's cancelled.
If the ``Operation`` is cancelled, then you can perform any necessary (terminating long running tasks, cleaning up connections, etc.
).
:param kwargs: The kwargs object containing the operation
:type kwargs: Mapping[str, Any]
:returns: The operation associated with this function
:rtype: viam.operations.Operation
.. py:method:: close()
:async:
Safely shut down the resource and prevent further use.
Close must be idempotent. Later configuration may allow a resource to be "open" again.
If a resource does not want or need a close function, it is assumed that the resource does not need to return errors when future
non-Close methods are called.
::
await component.close()
.. py:class:: Event
.. py:attribute:: time
:type: float
seconds since epoch
.. py:attribute:: event
:type: EventType
.. py:attribute:: control
:type: Control
.. py:attribute:: value
:type: float
0 or 1 for buttons, -1.0 to +1.0 for axes
.. py:property:: proto
.. py:method:: from_proto(proto: viam.proto.component.inputcontroller.Event) -> typing_extensions.Self
:classmethod:
.. py:class:: EventType
Bases: :py:obj:`str`, :py:obj:`enum.Enum`
Represents the type of input event.
.. py:attribute:: ALL_EVENTS
:value: 'AllEvents'
Callbacks registered for this event will be called in ADDITION to other registered event callbacks.
.. py:attribute:: CONNECT
:value: 'Connect'
Sent at controller initialization, and on reconnects.
.. py:attribute:: DISCONNECT
:value: 'Disconnect'
If unplugged, or wireless/network times out.
.. py:attribute:: BUTTON_PRESS
:value: 'ButtonPress'
Typical key press.
.. py:attribute:: BUTTON_RELEASE
:value: 'ButtonRelease'
Key release.
.. py:attribute:: BUTTON_HOLD
:value: 'ButtonHold'
Key is held down. This wil likely be a repeated event.
.. py:attribute:: BUTTON_CHANGE
:value: 'ButtonChange'
Both up and down for convenience during registration, not typically emitted.
.. py:attribute:: POSITION_CHANGE_ABSOLUTE
:value: 'PositionChangeAbs'
Absolute position is reported via Value, a la joysticks.
.. py:attribute:: POSITION_CHANGE_RELATIVE
:value: 'PositionChangeRel'
Relative position is reported via Value, a la mice, or simulating axes with up/down buttons.