venice

Venice is an open-source Micropython runtime for VEX V5 robots.

from venice import Motor, Gearset, Direction
import venice.vasyncio

async def main():
    my_motor = Motor(
        1,
        Direction.FORWARD,
        Gearset.GREEN
    )
    my_motor.set_voltage(10.0)
vasyncio.run(main())
   1"""
   2Venice is an open-source Micropython runtime for VEX V5 robots.
   3
   4```python
   5from venice import Motor, Gearset, Direction
   6import venice.vasyncio
   7
   8async def main():
   9    my_motor = Motor(
  10        1,
  11        Direction.FORWARD,
  12        Gearset.GREEN
  13    )
  14    my_motor.set_voltage(10.0)
  15vasyncio.run(main())
  16```
  17"""
  18
  19from __future__ import annotations
  20
  21from typing import ClassVar, List, Literal, Union
  22
  23
  24class RotationUnit:
  25    """Represents a unit of rotation for angles."""
  26
  27    RADIANS: ClassVar["RotationUnit"]
  28    """The rotation unit representing radians."""
  29
  30    DEGREES: ClassVar["RotationUnit"]
  31    """The rotation unit representing degrees."""
  32
  33    TURNS: ClassVar["RotationUnit"]
  34    """The rotation unit representing turns (revolutions)."""
  35
  36
  37RotationUnit.RADIANS = RotationUnit()
  38RotationUnit.DEGREES = RotationUnit()
  39RotationUnit.TURNS = RotationUnit()
  40
  41
  42class TimeUnit:
  43    """Represents a unit of time."""
  44
  45    MILLIS: ClassVar["TimeUnit"]
  46    """The time unit representing milliseconds."""
  47
  48    SECONDS: ClassVar["TimeUnit"]
  49    """The time unit representing seconds."""
  50
  51
  52TimeUnit.MILLIS = TimeUnit()
  53TimeUnit.SECONDS = TimeUnit()
  54
  55
  56class Direction:
  57    """A rotational direction."""
  58
  59    FORWARD: ClassVar["Direction"]
  60    """Rotates in the forward direction."""
  61
  62    REVERSE: ClassVar["Direction"]
  63    """Rotates in the reverse direction."""
  64
  65
  66Direction.FORWARD = Direction()
  67Direction.REVERSE = Direction()
  68
  69
  70class Gearset:
  71    """Internal gearset used by VEX Smart motors."""
  72
  73    RED: ClassVar["Gearset"]
  74    """36:1 gear ratio"""
  75
  76    GREEN: ClassVar["Gearset"]
  77    """18:1 gear ratio"""
  78
  79    BLUE: ClassVar["Gearset"]
  80    """6:1 gear ratio"""
  81
  82
  83Gearset.RED = Gearset()
  84Gearset.GREEN = Gearset()
  85Gearset.BLUE = Gearset()
  86
  87
  88class BrakeMode:
  89    """Determines the behavior a motor should use when braking with `AbstractMotor.brake`."""
  90
  91    COAST: ClassVar["BrakeMode"]
  92    """Motor never brakes."""
  93
  94    BRAKE: ClassVar["BrakeMode"]
  95    """Motor uses regenerative braking to slow down faster."""
  96
  97    HOLD: ClassVar["BrakeMode"]
  98    """Motor exerts force holding itself in the same position."""
  99
 100
 101BrakeMode.COAST = BrakeMode()
 102BrakeMode.BRAKE = BrakeMode()
 103BrakeMode.HOLD = BrakeMode()
 104
 105
 106class MotorType:
 107    """Represents the type of a Smart motor.
 108
 109    Either a 11W (V5) or 5.5W (EXP) motor."""
 110
 111    EXP: ClassVar["MotorType"]
 112    """A 5.5W Smart Motor"""
 113
 114    V5: ClassVar["MotorType"]
 115    """An 11W Smart Motor"""
 116
 117
 118class RotationSensor:
 119    """A rotation sensor plugged into a Smart Port.
 120
 121    The VEX V5 Rotation Sensor, measures the absolute position, rotation count,
 122    and angular velocity of a rotating shaft.
 123
 124    # Hardware Overview
 125
 126    The sensor provides absolute rotational position tracking from 0° to 360° with 0.088° accuracy.
 127    The sensor is composed of two magnets which utilize the
 128    [Hall Effect](https://en.wikipedia.org/wiki/Hall_effect_sensor) to indicate angular
 129    position. A chip inside the rotation sensor (a Cortex M0+) then keeps track of the total
 130    rotations of the sensor to determine total position traveled.
 131
 132    Position is reported by VEXos in centidegrees before being converted to a float
 133    in the given unit of rotation.
 134
 135    The absolute angle reading is preserved across power cycles (similar to a potentiometer), while
 136    the position count stores the cumulative forward and reverse revolutions relative to program
 137    start, however the *position* reading will be reset if the sensor loses power. Angular velocity
 138    is measured in degrees per second.
 139
 140    Like all other Smart devices, VEXos will process sensor updates every 10mS.
 141    """
 142
 143    def __init__(self, port: int, direction: Direction = Direction.FORWARD):
 144        """Creates a new rotation sensor on the given port.
 145
 146        Whether or not the sensor should be reversed on creation can be specified.
 147
 148        Args:
 149
 150        * port: The port number (1-21).
 151
 152        * direction: The direction of rotation. Defaults to forward.
 153        """
 154
 155    MIN_DATA_INTERVAL_MS: int = 5
 156    """The minimum data rate that you can set a rotation sensor to, in milliseconds."""
 157
 158    TICKS_PER_ROTATION: int = 36000
 159    """The amount of unique sensor readings per one revolution of the sensor."""
 160
 161    def position(self, unit: RotationUnit) -> float:
 162        """Returns the total accumulated rotation of the sensor over time, in
 163        the specified units.
 164
 165        Args:
 166
 167        * unit: The `RotationUnit` to use for the return value.
 168        """
 169        ...
 170
 171    def angle(self, unit: RotationUnit) -> float:
 172        """Returns the absolute angle of rotation measured by the sensor.
 173
 174        This value is reported from 0-360 degrees.
 175
 176        Args:
 177
 178        * unit: The `RotationUnit` to use for the return value.
 179        """
 180        ...
 181
 182    def set_position(self, angle: float, angle_unit: RotationUnit):
 183        """Sets the sensor's position reading.
 184
 185        Args:
 186
 187        * angle: The angle to set the sensor to.
 188        * angle_unit: The `RotationUnit` to use for the angle.
 189        """
 190        ...
 191
 192    def velocity(self) -> float:
 193        """Returns the sensor's current velocity in degrees per second."""
 194        ...
 195
 196    def reset_position(self):
 197        """Resets the sensor's position reading to zero."""
 198        ...
 199
 200    def set_direction(self, new_direction: Direction):
 201        """Sets the sensor to operate in a given `Direction`.
 202
 203        This determines which way the sensor considers to be “forwards”. You can use the marking on
 204        the top of the motor as a reference:
 205
 206        - When `Direction.FORWARD` is specified, positive velocity/voltage values will cause the
 207          motor to rotate **with the arrow on the top**. Position will increase as the motor rotates
 208          **with the arrow**.
 209        - When `Direction.REVERSE` is specified, positive velocity/voltage values will cause the
 210          motor to rotate **against the arrow on the top**. Position will increase as the motor
 211          rotates **against the arrow**.
 212
 213        Args:
 214
 215        * new_direction: The new `Direction` to set the sensor to.
 216        """
 217        ...
 218
 219    def direction(self):
 220        """Returns the `Direction` of this sensor."""
 221        ...
 222
 223    def status(self) -> int:
 224        """Returns the sensor's internal status code."""
 225        ...
 226
 227    def set_data_interval(self, interval: float, interval_unit: TimeUnit):
 228        """Sets the internal computation speed of the rotation sensor.
 229
 230        This method does NOT change the rate at which user code can read data off the sensor, as the
 231        brain will only talk to the device every 10mS regardless of how fast data is being sent or
 232        computed.
 233
 234        This duration should be above `RotationSensor.MIN_DATA_INTERVAL_MS` (5 milliseconds).
 235
 236        Args:
 237
 238        * interval: The new interval to set the sensor to.
 239        * interval_unit: The unit of the interval.
 240        """
 241
 242
 243class AbstractMotor:
 244    """A motor plugged into a Smart Port.
 245
 246    This is an abstract class supporting shared methods for both the 5W (Exp)
 247    and 11W motor variants. To create a motor, use the initializers of `ExpMotor`
 248    or `V5Motor`, respectively.
 249
 250    # Overview
 251
 252    The V5 Smart Motors come in two variants: [an 11W model](https://www.vexrobotics.com/276-4840.html),
 253    with interchangeable gear cartridges and [a 5.5W model](https://www.vexrobotics.com/276-4842.html),
 254    with a fixed gearing. The 11W motor supports three cartridge options, which will gear the motor
 255    down from its base RPM of 3600: a red cartridge providing 100 RPM output, a green cartridge for
 256    200 RPM, and a blue cartridge for 600 RPM. The 5.5W motor comes with a non-interchangeable 200
 257    RPM gear cartridge.
 258
 259    Smart Motors feature several integrated sensors, including an encoder for measuring the velocity
 260    and position of the motor, a temperature sensor for detecting overheats, and sensors for
 261    measuring output voltage, current, and efficiency.
 262
 263    Communication between a Smart motor and the V5 Brain occur at two different intervals. While
 264    the motor communicates with the Brain every 5 milliseconds (and commands can be written to the
 265    motor every 5mS), the Brain only reads data from the motor every 10mS. This effectively places
 266    the data *write* interval at 5mS and the data *read* interval at 10mS.
 267
 268    More in-depth specs for the 11W motor can be found [here](https://kb.vex.com/hc/en-us/articles/360060929971-Understanding-V5-Smart-Motors).
 269
 270    # Current Limitations
 271
 272    There are some cases where VEXos or the motor itself may decide to limit output current:
 273
 274    - **Stall Prevention**: The stall current on 11W motors is limited to 2.5A. This limitation
 275      eliminates the need for automatic resetting fuses (PTC devices) in the motor, which can
 276      disrupt operation. By restricting the stall current to 2.5A, the motor effectively avoids
 277      undesirable performance dips and ensures that users do not inadvertently cause stall
 278      situations.
 279
 280    - **Motor Count**: Robots that use 8 or fewer 11W motors will have the aforementioned current limit
 281      of 2.5A set for each motor. Robots using more than 8 motors, will have a lower default current limit
 282      per-motor than 2.5A. This limit is determined in VEXos by a calculation accounting for the number of
 283      motors plugged in, and the user's manually set current limits using `AbstractMotor.set_current_limit`. For
 284      more information regarding the current limiting behavior of VEXos, see [this forum post](https://www.vexforum.com/t/how-does-the-decreased-current-affect-the-robot-when-using-more-than-8-motors/72650/4).
 285
 286    - **Temperature Management**: Motors have an onboard sensor for measuring internal temperature.
 287      If the motor determines that it is overheating, it will throttle its output current and warn
 288      the user.
 289
 290    # Motor Control
 291
 292    Each motor contains a sophisticated control system built around a Cortex M0+ microcontroller.
 293    The microcontroller continuously monitors position, speed, direction, voltage, current, and
 294    temperature through integrated sensors.
 295
 296    The onboard motor firmware implements a set of pre-tuned PID (Proportional-Integral-Derivative)
 297    controllers operating on a 10-millisecond cycle for position and velocity control. Motors also
 298    have braking functionality for holding a specific position under load.
 299    """
 300
 301    WRITE_INTERVAL_MS: int = 5
 302    """The interval at which the Brain will send new packets to an `AbstractMotor`."""
 303
 304    def set_voltage(self, voltage: float):
 305        """Sets the motor's output voltage.
 306
 307        This voltage value spans from -12 (fully spinning reverse) to +12 (fully spinning forwards)
 308        volts, and controls the raw output of the motor.
 309
 310        Args:
 311
 312        - voltage: The output voltage of the motor in volts.
 313        """
 314        ...
 315
 316    def set_velocity(self, rpm: int):
 317        """Spins the motor at a target velocity.
 318
 319        This velocity corresponds to different actual speeds in RPM depending on the gearset used
 320        for the motor. Velocity is held with an internal PID controller to ensure consistent
 321        speed, as opposed to setting the motor's voltage.
 322
 323        Args:
 324
 325        - rpm: The desired target velocity in RPM.
 326        """
 327        ...
 328
 329    def brake(self):
 330        """Sets the motor's target to a given `BrakeMode`."""
 331        ...
 332
 333    def set_position_target(
 334        self, position: float, position_unit: RotationUnit, velocity: int
 335    ):
 336        """Sets an absolute position target for the motor to attempt to reach using its internal
 337        PID control.
 338
 339        Args:
 340
 341        - position: The desired position of the motor after the movement operation.
 342        - position_unit: The unit of the position.
 343        - velocity: The desired speed of the velocity in RPM during the movement operation
 344        """
 345        ...
 346
 347    def is_exp(self) -> bool:
 348        """Returns `True` if the motor is a 5.5W (EXP) Smart Motor."""
 349        ...
 350
 351    def is_v5(self) -> bool:
 352        """Returns `True` if the motor is an 11W (V5) Smart Motor."""
 353        ...
 354
 355    def max_voltage(self) -> float:
 356        """Returns the maximum voltage for the motor based off of its `MotorType`.
 357
 358        See `V5Motor.MAX_VOLTAGE` and `ExpMotor.MAX_VOLTAGE`."""
 359        ...
 360
 361    def velocity(self) -> float:
 362        """Returns the motor's estimate of its angular velocity in rotations per minute (RPM).
 363
 364        # Accuracy
 365
 366        In some cases, this reported value may be noisy or inaccurate, especially for systems where
 367        accurate velocity control at high speeds is required (such as flywheels). If the
 368        accuracy of this value proves inadequate, you may opt to perform your own velocity
 369        calculations by differentiating `AbstractMotor.position` over the reported internal timestamp
 370        of the motor (currently not exposed in the Venice API).
 371
 372        > For more information about Smart motor velocity estimation, see [this article](https://sylvie.fyi/sylib/docs/db/d8e/md_module_writeups__velocity__estimation.html).
 373
 374        # Note
 375
 376        This is the **estimated** velocity, not the **target** velocity. The Venice API currently does
 377        not mirror vexide's `Motor::target` so there is no way to get the target velocity.
 378        """
 379        ...
 380
 381    def power(self) -> float:
 382        """Returns the power drawn by the motor in Watts."""
 383        ...
 384
 385    def torque(self) -> float:
 386        """Returns the torque output of the motor in Nm."""
 387        ...
 388
 389    def voltage(self) -> float:
 390        """Returns the voltage the motor is drawing in volts."""
 391        ...
 392
 393    def raw_position(self) -> int:
 394        """Returns the most recently recorded raw encoder tick data from the motor's IME.
 395
 396        The motor's integrated encoder has a TPR of 4096. Gearset is not taken into consideration
 397        when dealing with the raw value, meaning this measurement will be taken relative to the
 398        motor's internal position *before* being geared down from 3600RPM.
 399
 400        Methods such as `AbstractMotor.reset_position` and `AbstractMotor.set_position` do not
 401        change the value of this raw measurement.
 402        """
 403        ...
 404
 405    def current(self) -> float:
 406        """Returns the electrical current draw of the motor in amps."""
 407        ...
 408
 409    def efficiency(self) -> float:
 410        """Returns the efficiency of the motor from a range of [0.0, 1.0].
 411
 412        An efficiency of 1.0 means that the motor is moving electrically while drawing no electrical
 413        power, and an efficiency of 0.0 means that the motor is drawing power but not moving."""
 414        ...
 415
 416    def current_limit(self) -> float:
 417        """Returns the current limit for the motor in amps.
 418
 419        This limit can be configured with the `AbstractMotor.set_current_limit` method."""
 420        ...
 421
 422    def voltage_limit(self) -> float:
 423        """Returns the voltage limit for the motor if one has been explicitly set."""
 424        ...
 425
 426    def temperature(self) -> float:
 427        """Returns the internal temperature recorded by the motor in increments of 5 °C."""
 428        ...
 429
 430    def set_profiled_velocity(self, rpm: int):
 431        """Changes the output velocity for a profiled movement (motor_move_absolute or
 432        motor_move_relative).
 433
 434        This will have no effect if the motor is not following a profiled movement.
 435
 436        Args:
 437
 438        - rpm: The new profiled velocity target in rotations per minute.
 439        """
 440        ...
 441
 442    def reset_position(self):
 443        """Sets the current encoder position to zero without moving the motor.
 444
 445        Analogous to taring or resetting the encoder to the current position.
 446        """
 447        ...
 448
 449    def set_current_limit(self, amps: float):
 450        """Sets the current limit for the motor in amps.
 451
 452        Args:
 453
 454        - amps: The new current limit in amps.
 455        """
 456        ...
 457
 458    def set_voltage_limit(self, volts: float):
 459        """Sets the voltage limit for the motor in volts.
 460
 461        Args:
 462
 463        - volts: The new voltage limit in volts.
 464        """
 465        ...
 466
 467    def is_over_temperature(self) -> bool:
 468        """Returns `True` if the motor's over temperature flag is set."""
 469        ...
 470
 471    def is_over_current(self):
 472        """Returns `True` if the motor's over-current flag is set."""
 473        ...
 474
 475    def is_driver_fault(self):
 476        """Returns `True` if a H-bridge (motor driver) fault has occurred."""
 477        ...
 478
 479    def is_driver_over_current(self):
 480        """Returns `True` if the motor's H-bridge has an over-current fault."""
 481        ...
 482
 483    def status(self) -> int:
 484        """Returns the status flags of a motor as bits."""
 485        ...
 486
 487    def faults(self) -> int:
 488        """Returns the fault flags of the motor as bits."""
 489        ...
 490
 491    def motor_type(self):
 492        """Returns the type of the motor.
 493
 494        This does not check the hardware, it simply returns the type that the motor was created
 495        with."""
 496        ...
 497
 498    def position(self, unit: RotationUnit) -> float:
 499        """Returns the angular position of the motor as measured by the IME (integrated motor encoder).
 500
 501        This is returned as a floating-point number in the given `RotationUnit`.
 502
 503        # Gearing affects position!
 504
 505        Position measurements are dependent on the Motor's `Gearset`, and may be reported
 506        incorrectly if the motor is configured with the incorrect gearset variant. Make sure
 507        that the motor is configured with the same gearset as its physical cartridge color.
 508
 509        Args:
 510
 511        - unit: The unit in which to return the position.
 512        """
 513        ...
 514
 515    def set_position(self, position: float, position_unit: RotationUnit):
 516        """Sets the current encoder position to the given position without moving the motor.
 517
 518        Analogous to taring or resetting the encoder so that the new position is equal to the given
 519        position.
 520
 521        Args:
 522
 523        - position: The position to set the encoder to.
 524        - position_unit: The unit of the given position.
 525        """
 526        ...
 527
 528    def set_direction(self, direction: Direction):
 529        """Sets the motor to operate in a given `Direction`.
 530
 531        This determines which way the motor considers to be “forwards”. You can use the marking on
 532        the back of the motor as a reference:
 533
 534        - When `Direction.FORWARD` is specified, positive velocity/voltage values will cause the
 535          motor to rotate **with the arrow on the back**. Position will increase as the motor
 536          rotates **with the arrow**.
 537        - When `Direction.REVERSE` is specified, positive velocity/voltage values will cause the
 538          motor to rotate **against the arrow on the back**. Position will increase as the motor
 539          rotates **against the arrow**.
 540
 541        Args:
 542
 543        - direction: The direction to set the motor to.
 544        """
 545        ...
 546
 547    def direction(self):
 548        """Returns the `Direction` of this motor."""
 549        ...
 550
 551
 552class V5Motor(AbstractMotor):
 553    """Represents an 11W (V5) Smart Motor. See `AbstractMotor`."""
 554
 555    MAX_VOLTAGE: Literal[12] = 12
 556    """The maximum voltage value that can be sent to a `V5Motor`."""
 557
 558    def __init__(self, port: int, direction: Direction, gearset: Gearset):
 559        """Creates a new 11W (V5) Smart Motor.
 560
 561        See `ExpMotor.__init__` to create a 5.5W (EXP) Smart Motor.
 562
 563        Args:
 564
 565        - port: The smart port to initialize the motor on.
 566        - direction: The direction to set the motor to.
 567        - gearset: The gearset to set the motor to.
 568        """
 569        ...
 570
 571    def set_gearset(self, gearset: Gearset):
 572        """Sets the gearset of an 11W motor.
 573
 574        This may silently fail if the motor is a 5.5W motor, which occurs in the edge
 575        case described in `V5Motor.gearset`.
 576
 577        Args:
 578
 579        - gearset: the new `Gearset` to use for the motor.
 580        """
 581        ...
 582
 583    def gearset(self) -> Gearset:
 584        """Returns the gearset of an 11W motor.
 585
 586        For 5.5W motors [1], this will always be returned as `Gearset.GREEN`.
 587
 588        [1] There is a slim edge case in which you initialize a `V5Motor` at a time
 589        when the specified port indeed has a plugged-in 11W motor, but then unplug
 590        it and replace it with a 5.5W motor. Note that the respective constructors of
 591        `V5Motor` and `ExpMotor` *will* throw if the motor is not the correct type.
 592        """
 593        ...
 594
 595
 596class ExpMotor(AbstractMotor):
 597    """Represents an 5.5W (EXP) Smart Motor. See `AbstractMotor`."""
 598
 599    def __init__(self, port: int, direction: Direction):
 600        """Creates a new 5.5W (EXP) Smart Motor.
 601
 602        See `V5Motor.__init__` to create a 11W (V5) Smart Motor.
 603
 604        Args:
 605
 606        - port: The smart port to initialize the motor on.
 607        - direction: The direction to set the motor to.
 608        """
 609        ...
 610
 611    MAX_VOLTAGE: Literal[8] = 8
 612    """The maximum voltage value that can be sent to a `ExpMotor`."""
 613
 614
 615class DistanceObject:
 616    """Readings from a physical object detected by a Distance Sensor."""
 617
 618    distance: int
 619    "The distance of the object from the sensor (in millimeters)."
 620
 621    confidence: float
 622    """The confidence in the distance measurement from 0.0 to 1.0."""
 623
 624    velocity: float
 625    """Observed velocity of the object in m/s."""
 626
 627    relative_size: int
 628    """A guess at the object's "relative size".
 629
 630    This is a value that has a range of 0 to 400. A 18" x 30" grey card will return a value of
 631    approximately 75 in typical room lighting. If the sensor is not able to detect an object,
 632    None is returned.
 633
 634    This sensor reading is unusual, as it is entirely unitless with the seemingly arbitrary
 635    range of 0-400 existing due to VEXCode's
 636    [`vex::sizeType`](https://api.vex.com/v5/home/python/Enums.html#object-size-types) enum
 637    having four variants. It's unknown what the sensor is *actually* measuring here either,
 638    so use this data with a grain of salt."""
 639
 640
 641class DistanceSensor:
 642    """A distance sensor plugged into a Smart Port.
 643
 644    The VEX V5 Distance Sensor uses a
 645    Class 1 laser to measure the distance, object size classification, and relative velocity of a
 646    single object.
 647
 648    # Hardware Overview
 649
 650    The sensor uses a narrow-beam Class 1 laser (similar to phone proximity sensors) for precise
 651    detection. It measures distances from 20mm to 2000mm with varying accuracy (±15mm below 200mm,
 652    ±5% above 200mm).
 653
 654    The sensor can classify detected objects by relative size, helping distinguish between walls and
 655    field elements. It also measures the relative approach velocity between the sensor and target.
 656
 657    Due to the use of a laser, measurements are single-point and highly directional, meaning that
 658    objects will only be detected when they are directly in front of the sensor's field of view.
 659
 660    Like all other Smart devices, VEXos will process sensor updates every 10mS.
 661    """
 662
 663    def __init__(self, port: int):
 664        """Creates a new distance sensor given the port.
 665
 666        Args:
 667
 668        - port: The port number of the sensor.
 669        """
 670        ...
 671
 672    def object(self) -> Union[DistanceObject, None]:
 673        """Attempts to detect an object, returning `None` if no object could be found."""
 674        ...
 675
 676    def status(self) -> int:
 677        """Returns the internal status code of the distance sensor.
 678
 679        The status code of the signature can tell you if the sensor is still initializing or if it
 680        is working correctly.
 681
 682        - If the distance sensor is still initializing, the status code will be 0x00.
 683        - If it is done initializing and functioning correctly, the status code will be 0x82 or
 684          0x86.
 685        """
 686        ...
 687
 688
 689class AiVisionColor:
 690    """A color signature used by an AI Vision Sensor to detect color blobs."""
 691
 692    r: int
 693    """The red component of the RGB color value."""
 694
 695    g: int
 696    """The green component of the RGB color value."""
 697
 698    b: int
 699    """The blue component of the RGB color value."""
 700
 701    hue_range: float
 702    """The accepted hue range of the color. VEXcode limits this value to [0, 20]"""
 703
 704    saturation_range: float
 705    """The accepted saturation range of the color."""
 706
 707    def __init__(
 708        self, r: int, g: int, b: int, hue_range: float, saturation_range: float
 709    ):
 710        """Creates a new `AiVisionColor` from the provided args.
 711
 712        Args:
 713
 714        - r: The red component of the RGB color value.
 715        - g: The green component of the RGB color value.
 716        - b: The blue component of the RGB color value.
 717        - hue_range: The accepted hue range of the color.
 718        - saturation_range: The accepted saturation range of the color.
 719        """
 720        ...
 721
 722
 723class AiVisionColorCode:
 724    """A color code used by an AI Vision Sensor to detect groups of color blobs.
 725
 726    Color codes are effectively "groups" of color signatures. A color code associated multiple color
 727    signatures on the sensor will be detected as a single object when all signatures are seen next
 728    to each other.
 729
 730    Color codes can associate up to 7 color signatures and detections will be returned as
 731    `AiVisionObject.Code` variants.
 732    """
 733
 734    def __init__(
 735        self,
 736        first: Union[int, None],
 737        second: Union[int, None],
 738        third: Union[int, None],
 739        fourth: Union[int, None],
 740        fifth: Union[int, None],
 741        sixth: Union[int, None],
 742        seventh: Union[int, None],
 743    ):
 744        """Creates a new `AiVisionColorCode` from the provided args.
 745
 746        Args:
 747
 748        - first: the first color signature id.
 749        - second: the second color signature id.
 750        - third: the third color signature id.
 751        - fourth: the fourth color signature id.
 752        - fifth: the fifth color signature id.
 753        - sixth: the sixth color signature id.
 754        - seventh: the seventh color signature id.
 755        """
 756        ...
 757
 758    # we annotate the docstring as @public because pdoc otherqise doesn't
 759    # document slot items
 760    def __getitem__(self, item: int):
 761        """@public Returns the color signature id at the given index.
 762
 763        Note that this does NOT support setting. For example, the following code works:
 764        ```python
 765        color_code_ids = [1, 2, 3, 4, 5, 6, 7]
 766        my_color_code = AiVisionColorCode(*color_code_ids)
 767        print(my_color_code[2]) # prints 3
 768        ```
 769        But this code doesn't:
 770        ```python
 771        color_code_ids = [1, 2, 3, 4, 5, 6, 7]
 772        my_color_code = AiVisionColorCode(*color_code_ids)
 773        my_color_code[6] = 9 # fails
 774        ```
 775        """
 776        ...
 777
 778
 779class AiVisionDetectionMode:
 780    """Flags relating to the sensor's detection mode."""
 781
 782    APRILTAG: ClassVar["AiVisionDetectionMode"]
 783    """Enable apriltag detection"""
 784
 785    COLOR: ClassVar["AiVisionDetectionMode"]
 786    """Enable color detection"""
 787
 788    MODEL: ClassVar["AiVisionDetectionMode"]
 789    """Enable model detection"""
 790
 791    COLOR_MERGE: ClassVar["AiVisionDetectionMode"]
 792    """Merge color blobs?"""
 793
 794    def __or__(self, value) -> AiVisionDetectionMode:
 795        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned
 796
 797        ```python
 798        sensor = AiVisionSensor(7)
 799        # enable apriltag and color detection
 800        sensor.set_detection_mode(AiVisionDetectionMode.APRILTAG | AiVisionDetectionMode.COLOR)
 801        ```
 802        """
 803        ...
 804
 805    def __ior__(self, value):
 806        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. `self` is set to the result.
 807
 808        ```python
 809        sensor = AiVisionSensor(7)
 810        # enable apriltag and color detection
 811        mode = AiVisionDetectionMode.APRILTAG
 812        mode |= AiVisionDetectionMode.COLOR
 813        sensor.set_detection_mode(mode)
 814        ```
 815        """
 816        ...
 817
 818
 819AiVisionDetectionMode.APRILTAG = AiVisionDetectionMode()
 820AiVisionDetectionMode.COLOR = AiVisionDetectionMode()
 821AiVisionDetectionMode.MODEL = AiVisionDetectionMode()
 822AiVisionDetectionMode.COLOR_MERGE = AiVisionDetectionMode()
 823
 824
 825class AiVisionFlags:
 826    """Represents the mode of the AI Vision sensor."""
 827
 828    DISABLE_APRILTAG: ClassVar["AiVisionFlags"]
 829    """Disable apriltag detection"""
 830
 831    DISABLE_COLOR: ClassVar["AiVisionFlags"]
 832    """Disable color detection"""
 833
 834    DISABLE_MODEL: ClassVar["AiVisionFlags"]
 835    """Disable model detection"""
 836
 837    COLOR_MERGE: ClassVar["AiVisionFlags"]
 838    """Merge color blobs?"""
 839
 840    DISABLE_STATUS_OVERLAY: ClassVar["AiVisionFlags"]
 841    """Disable status overlay"""
 842
 843    DISABLE_USB_OVERLAY: ClassVar["AiVisionFlags"]
 844    """Disable USB overlay"""
 845
 846    def __or__(self, value) -> AiVisionDetectionMode:
 847        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned
 848
 849        ```python
 850        sensor = AiVisionSensor(7)
 851        # disable status and usb overlays
 852        sensor.set_flags(AiVisionFlags.DISABLE_STATUS_OVERLAY | AiVisionFlags.DISABLE_USB_OVERLAY)
 853        ```
 854        """
 855        ...
 856
 857    def __ior__(self, value):
 858        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. `self` is set to the result.
 859
 860        ```python
 861        sensor = AiVisionSensor(7)
 862        # disable status and usb overlays
 863        mode = AiVisionFlags.DISABLE_STATUS_OVERLAY
 864        mode |= AiVisionFlags.DISABLE_USB_OVERLAY
 865        sensor.set_flags(mode)
 866        ```
 867        """
 868        ...
 869
 870
 871AiVisionFlags.DISABLE_APRILTAG = AiVisionFlags()
 872AiVisionFlags.DISABLE_COLOR = AiVisionFlags()
 873AiVisionFlags.DISABLE_MODEL = AiVisionFlags()
 874AiVisionFlags.COLOR_MERGE = AiVisionFlags()
 875AiVisionFlags.DISABLE_STATUS_OVERLAY = AiVisionFlags()
 876AiVisionFlags.DISABLE_USB_OVERLAY = AiVisionFlags()
 877
 878
 879class AiVisionColorObject:
 880    """The data associated with an AI Vision object detected by color blob detection."""
 881
 882    id: int
 883    """ID of the signature used to detect this object."""
 884
 885    position_x: int
 886    """The x component of the top-left corner of the object."""
 887
 888    position_y: int
 889    """The y component of the top-left corner of the object."""
 890
 891    width: int
 892    """The width of the object."""
 893
 894    height: int
 895    """The height of the object."""
 896
 897
 898class AiVisionCodeObject:
 899    """The data associated with an AI Vision object detected by color code detection."""
 900
 901    id: int
 902    """ID of the code used to detect this object."""
 903
 904    position_x: int
 905    """The x component of the position of the object."""
 906
 907    position_y: int
 908    """The y component of the position of the object."""
 909
 910    width: int
 911    """The width of the object."""
 912
 913    height: int
 914    """The height of the object."""
 915
 916    def angle(self, unit: RotationUnit) -> float:
 917        """The angle of the object's associated colors. Not always reliably available.
 918
 919        Args:
 920
 921        - units: The unit of measurement for the angle. This is the unit of
 922        the returned `float`.
 923        """
 924        ...
 925
 926
 927class AiVisionAprilTagObject:
 928    """The data associated with an AI Vision object detected by apriltag detection."""
 929
 930    id: int
 931    """The detected AprilTag(s) ID number"""
 932
 933    top_left_x: int
 934    """x component of the position of the top-left corner of the tag"""
 935
 936    top_left_y: int
 937    """y component of the position of the top-left corner of the tag"""
 938
 939    top_right_x: int
 940    """x component of the position of the top-right corner of the tag"""
 941
 942    top_right_y: int
 943    """y component of the position of the top-right corner of the tag"""
 944
 945    bottom_left_x: int
 946    """x component of the position of the bottom-left corner of the tag"""
 947
 948    bottom_left_y: int
 949    """y component of the position of the bottom-left corner of the tag"""
 950
 951    bottom_right_x: int
 952    """x component of the position of the bottom-right corner of the tag"""
 953
 954    bottom_right_y: int
 955    """y component of the position of the bottom-right corner of the tag"""
 956
 957
 958class AiVisionModelObject:
 959    """The data associated with an AI Vision object detected by an onboard model."""
 960
 961    id: int
 962    """ID of the detected object."""
 963
 964    position_x: int
 965    """The x component of the position of the object."""
 966
 967    position_y: int
 968    """The y component of the position of the object."""
 969
 970    width: int
 971    """The width of the object."""
 972
 973    height: int
 974    """The height of the object."""
 975
 976    confidence: int
 977    """The confidence reported by the model."""
 978
 979    classification: str
 980    """A string describing the specific onboard model used to detect this object."""
 981
 982
 983class AprilTagFamily:
 984    """Possible april tag families to be detected by the `AiVisionSensor`."""
 985
 986    CIRCLE21H7: ClassVar["AprilTagFamily"]
 987    """Circle21h7 family"""
 988
 989    TAG16H5: ClassVar["AprilTagFamily"]
 990    """16h5 family"""
 991
 992    TAG36H11: ClassVar["AprilTagFamily"]
 993    """36h11 family"""
 994
 995    TAG25H9: ClassVar["AprilTagFamily"]
 996    """25h9 family"""
 997
 998
 999AprilTagFamily.TAG36H11 = AprilTagFamily()
1000AprilTagFamily.TAG25H9 = AprilTagFamily()
1001AprilTagFamily.TAG16H5 = AprilTagFamily()
1002AprilTagFamily.CIRCLE21H7 = AprilTagFamily()
1003
1004
1005class AiVisionSensor:
1006    """An AI Vision sensor.
1007
1008    The AI Vision sensor is
1009    meant to be a direct upgrade from the Vision Sensor with a wider camera range
1010    and AI model capabilities.
1011
1012    # Hardware overview
1013
1014    The AI Vision sensor has three detection modes that can all be enabled at the same time:
1015    - [Color detection](AiVisionDetectionMode::COLOR)
1016    - [Custom model detection](AiVisionDetectionMode::MODEL)
1017    - [AprilTag detection](AiVisionDetectionMode::APRILTAG) (requires color detection to be enabled)
1018
1019    Currently there is no known way to upload custom models to the sensor and fields do not have
1020    AprilTags. However, there are built-in models that can be used for detection.
1021
1022    See [VEX's documentation](https://kb.vex.com/hc/en-us/articles/30326315023892-Using-AI-Classifications-with-the-AI-Vision-Sensor) for more information.
1023
1024    The resolution of the AI Vision sensor is 320x240 pixels. It has a horizontal FOV of 74 degrees
1025    and a vertical FOV of 63 degrees. Both of these values are a slight upgrade from the Vision
1026    Sensor.
1027
1028    Unlike the Vision Sensor, the AI Vision sensor uses more human-readable color signatures that
1029    may be created without the AI Vision utility, though uploading color signatures with VEX's AI
1030    Vision Utility over USB is still an option.
1031    """
1032
1033    MAX_OBJECTS: int = 24
1034    """Maximum number of objects that can be detected at once."""
1035
1036    HORIZONTAL_RESOLUTION: int = 320
1037    """The horizontal resolution of the AI Vision sensor."""
1038
1039    VERTICAL_RESOLUTION: int = 240
1040    """The vertical resolution of the AI Vision sensor."""
1041
1042    HORIZONTAL_FOV: float = 74.0
1043    """The horizontal FOV of the vision sensor in degrees."""
1044
1045    VERTICAL_FOV: float = 63.0
1046    """The vertical FOV of the vision sensor in degrees."""
1047
1048    DIAGONAL_FOV: float = 87.0
1049    """The diagonal FOV of the vision sensor in degrees."""
1050
1051    def temperature(self) -> float:
1052        """Returns the current temperature of the sensor in degrees Celsius."""
1053        ...
1054
1055    def set_color_code(self, id: int, code: AiVisionColorCode):
1056        """
1057        Registers a color code association on the sensor.
1058
1059        Color codes are effectively "groups" of color signatures. A color code associated multiple
1060        color signatures on the sensor will be detected as a single object when all signatures are
1061        seen next to each other.
1062
1063        Args:
1064
1065        - id: The ID of the color code to register. Must be in [1, 8].
1066        - code: The `AiVisionColorCode` to register.
1067        """
1068
1069    def color_code(self, id: int) -> Union[AiVisionColorCode, None]:
1070        """Returns the color code set on the AI Vision sensor with the given ID if it exists.
1071
1072        Args:
1073
1074        - id: The ID of the color code to retrieve. Must be in [1, 8].
1075
1076        Returns:
1077
1078        - The color code associated with the given ID if it exists, or None if no color code is set.
1079        """
1080        ...
1081
1082    def color_codes(self) -> List[Union[AiVisionColorCode, None]]:
1083        """Returns all color codes set on the AI Vision sensor as a list of 8 optional `AiVisionColorCode` objects."""
1084        ...
1085
1086    def set_color(self, id: int, color: AiVisionColor) -> AiVisionColor:
1087        """Sets a color signature for the AI Vision sensor.
1088
1089        Args:
1090
1091        - id: The ID of the color signature to register. Must be in [1, 7].
1092        - color: The `AiVisionColor` to register.
1093        """
1094        ...
1095
1096    def color(self, id: int) -> Union[AiVisionColor, None]:
1097        """Returns the color signature set on the AI Vision sensor with the given ID if it exists.
1098
1099        Args:
1100
1101        - id: The ID of the color signature to retrieve. Must be in [1, 7].
1102        """
1103        ...
1104
1105    def colors(self) -> List[Union[AiVisionColor, None]]:
1106        """Returns all color signatures set on the AI Vision sensor as a list of 7 optional `AiVisionColor` objects."""
1107        ...
1108
1109    def set_detection_mode(self, mode: AiVisionDetectionMode):
1110        """Sets the detection mode of the AI Vision sensor.
1111
1112        Args:
1113
1114        - mode: The new `AiVisionDetectionMode` to set.
1115        """
1116        ...
1117
1118    def flags(self) -> AiVisionFlags:
1119        """Returns the current flags of the AI Vision sensor including the detection mode flags set by `AiVisionSensor.set_detection_mode`."""
1120        ...
1121
1122    def set_flags(self, mode: AiVisionFlags):
1123        """Set the full flags of the AI Vision sensor, including the detection mode.
1124
1125        Args:
1126
1127        - mode: The new `AiVisionFlags` to set.
1128        """
1129        ...
1130
1131    def start_awb(self):
1132        """Restarts the automatic white balance process."""
1133        ...
1134
1135    def enable_test(self, test: int):
1136        """Unknown use.
1137
1138        Args:
1139
1140        - test: unknown purpose.
1141        """
1142        ...
1143
1144    def set_apriltag_family(self, family: AprilTagFamily):
1145        """Sets the AprilTag family that the sensor will try to detect.
1146
1147        Args:
1148
1149        - family: The `AprilTagFamily` for the sensor to try to detect.
1150        """
1151        ...
1152
1153    def object_count(self) -> int:
1154        """Returns the number of objects currently detected by the AI Vision sensor."""
1155        ...
1156
1157    def objects(
1158        self,
1159    ) -> List[
1160        Union[
1161            AiVisionColorObject,
1162            AiVisionCodeObject,
1163            AiVisionModelObject,
1164            AiVisionAprilTagObject,
1165        ]
1166    ]:
1167        """Returns all objects detected by the AI Vision sensor."""
1168        ...
1169
1170
1171# TODOs:
1172# * controller
1173# * vasyncio
1174# * competition runtime
class RotationUnit:
25class RotationUnit:
26    """Represents a unit of rotation for angles."""
27
28    RADIANS: ClassVar["RotationUnit"]
29    """The rotation unit representing radians."""
30
31    DEGREES: ClassVar["RotationUnit"]
32    """The rotation unit representing degrees."""
33
34    TURNS: ClassVar["RotationUnit"]
35    """The rotation unit representing turns (revolutions)."""

Represents a unit of rotation for angles.

RADIANS: ClassVar[RotationUnit] = <RotationUnit object>

The rotation unit representing radians.

DEGREES: ClassVar[RotationUnit] = <RotationUnit object>

The rotation unit representing degrees.

TURNS: ClassVar[RotationUnit] = <RotationUnit object>

The rotation unit representing turns (revolutions).

class TimeUnit:
43class TimeUnit:
44    """Represents a unit of time."""
45
46    MILLIS: ClassVar["TimeUnit"]
47    """The time unit representing milliseconds."""
48
49    SECONDS: ClassVar["TimeUnit"]
50    """The time unit representing seconds."""

Represents a unit of time.

MILLIS: ClassVar[TimeUnit] = <TimeUnit object>

The time unit representing milliseconds.

SECONDS: ClassVar[TimeUnit] = <TimeUnit object>

The time unit representing seconds.

class Direction:
57class Direction:
58    """A rotational direction."""
59
60    FORWARD: ClassVar["Direction"]
61    """Rotates in the forward direction."""
62
63    REVERSE: ClassVar["Direction"]
64    """Rotates in the reverse direction."""

A rotational direction.

FORWARD: ClassVar[Direction] = <Direction object>

Rotates in the forward direction.

REVERSE: ClassVar[Direction] = <Direction object>

Rotates in the reverse direction.

class Gearset:
71class Gearset:
72    """Internal gearset used by VEX Smart motors."""
73
74    RED: ClassVar["Gearset"]
75    """36:1 gear ratio"""
76
77    GREEN: ClassVar["Gearset"]
78    """18:1 gear ratio"""
79
80    BLUE: ClassVar["Gearset"]
81    """6:1 gear ratio"""

Internal gearset used by VEX Smart motors.

RED: ClassVar[Gearset] = <Gearset object>

36:1 gear ratio

GREEN: ClassVar[Gearset] = <Gearset object>

18:1 gear ratio

BLUE: ClassVar[Gearset] = <Gearset object>

6:1 gear ratio

class BrakeMode:
89class BrakeMode:
90    """Determines the behavior a motor should use when braking with `AbstractMotor.brake`."""
91
92    COAST: ClassVar["BrakeMode"]
93    """Motor never brakes."""
94
95    BRAKE: ClassVar["BrakeMode"]
96    """Motor uses regenerative braking to slow down faster."""
97
98    HOLD: ClassVar["BrakeMode"]
99    """Motor exerts force holding itself in the same position."""

Determines the behavior a motor should use when braking with AbstractMotor.brake.

COAST: ClassVar[BrakeMode] = <BrakeMode object>

Motor never brakes.

BRAKE: ClassVar[BrakeMode] = <BrakeMode object>

Motor uses regenerative braking to slow down faster.

HOLD: ClassVar[BrakeMode] = <BrakeMode object>

Motor exerts force holding itself in the same position.

class MotorType:
107class MotorType:
108    """Represents the type of a Smart motor.
109
110    Either a 11W (V5) or 5.5W (EXP) motor."""
111
112    EXP: ClassVar["MotorType"]
113    """A 5.5W Smart Motor"""
114
115    V5: ClassVar["MotorType"]
116    """An 11W Smart Motor"""

Represents the type of a Smart motor.

Either a 11W (V5) or 5.5W (EXP) motor.

EXP: ClassVar[MotorType]

A 5.5W Smart Motor

V5: ClassVar[MotorType]

An 11W Smart Motor

class RotationSensor:
119class RotationSensor:
120    """A rotation sensor plugged into a Smart Port.
121
122    The VEX V5 Rotation Sensor, measures the absolute position, rotation count,
123    and angular velocity of a rotating shaft.
124
125    # Hardware Overview
126
127    The sensor provides absolute rotational position tracking from 0° to 360° with 0.088° accuracy.
128    The sensor is composed of two magnets which utilize the
129    [Hall Effect](https://en.wikipedia.org/wiki/Hall_effect_sensor) to indicate angular
130    position. A chip inside the rotation sensor (a Cortex M0+) then keeps track of the total
131    rotations of the sensor to determine total position traveled.
132
133    Position is reported by VEXos in centidegrees before being converted to a float
134    in the given unit of rotation.
135
136    The absolute angle reading is preserved across power cycles (similar to a potentiometer), while
137    the position count stores the cumulative forward and reverse revolutions relative to program
138    start, however the *position* reading will be reset if the sensor loses power. Angular velocity
139    is measured in degrees per second.
140
141    Like all other Smart devices, VEXos will process sensor updates every 10mS.
142    """
143
144    def __init__(self, port: int, direction: Direction = Direction.FORWARD):
145        """Creates a new rotation sensor on the given port.
146
147        Whether or not the sensor should be reversed on creation can be specified.
148
149        Args:
150
151        * port: The port number (1-21).
152
153        * direction: The direction of rotation. Defaults to forward.
154        """
155
156    MIN_DATA_INTERVAL_MS: int = 5
157    """The minimum data rate that you can set a rotation sensor to, in milliseconds."""
158
159    TICKS_PER_ROTATION: int = 36000
160    """The amount of unique sensor readings per one revolution of the sensor."""
161
162    def position(self, unit: RotationUnit) -> float:
163        """Returns the total accumulated rotation of the sensor over time, in
164        the specified units.
165
166        Args:
167
168        * unit: The `RotationUnit` to use for the return value.
169        """
170        ...
171
172    def angle(self, unit: RotationUnit) -> float:
173        """Returns the absolute angle of rotation measured by the sensor.
174
175        This value is reported from 0-360 degrees.
176
177        Args:
178
179        * unit: The `RotationUnit` to use for the return value.
180        """
181        ...
182
183    def set_position(self, angle: float, angle_unit: RotationUnit):
184        """Sets the sensor's position reading.
185
186        Args:
187
188        * angle: The angle to set the sensor to.
189        * angle_unit: The `RotationUnit` to use for the angle.
190        """
191        ...
192
193    def velocity(self) -> float:
194        """Returns the sensor's current velocity in degrees per second."""
195        ...
196
197    def reset_position(self):
198        """Resets the sensor's position reading to zero."""
199        ...
200
201    def set_direction(self, new_direction: Direction):
202        """Sets the sensor to operate in a given `Direction`.
203
204        This determines which way the sensor considers to be “forwards”. You can use the marking on
205        the top of the motor as a reference:
206
207        - When `Direction.FORWARD` is specified, positive velocity/voltage values will cause the
208          motor to rotate **with the arrow on the top**. Position will increase as the motor rotates
209          **with the arrow**.
210        - When `Direction.REVERSE` is specified, positive velocity/voltage values will cause the
211          motor to rotate **against the arrow on the top**. Position will increase as the motor
212          rotates **against the arrow**.
213
214        Args:
215
216        * new_direction: The new `Direction` to set the sensor to.
217        """
218        ...
219
220    def direction(self):
221        """Returns the `Direction` of this sensor."""
222        ...
223
224    def status(self) -> int:
225        """Returns the sensor's internal status code."""
226        ...
227
228    def set_data_interval(self, interval: float, interval_unit: TimeUnit):
229        """Sets the internal computation speed of the rotation sensor.
230
231        This method does NOT change the rate at which user code can read data off the sensor, as the
232        brain will only talk to the device every 10mS regardless of how fast data is being sent or
233        computed.
234
235        This duration should be above `RotationSensor.MIN_DATA_INTERVAL_MS` (5 milliseconds).
236
237        Args:
238
239        * interval: The new interval to set the sensor to.
240        * interval_unit: The unit of the interval.
241        """

A rotation sensor plugged into a Smart Port.

The VEX V5 Rotation Sensor, measures the absolute position, rotation count, and angular velocity of a rotating shaft.

Hardware Overview

The sensor provides absolute rotational position tracking from 0° to 360° with 0.088° accuracy. The sensor is composed of two magnets which utilize the Hall Effect to indicate angular position. A chip inside the rotation sensor (a Cortex M0+) then keeps track of the total rotations of the sensor to determine total position traveled.

Position is reported by VEXos in centidegrees before being converted to a float in the given unit of rotation.

The absolute angle reading is preserved across power cycles (similar to a potentiometer), while the position count stores the cumulative forward and reverse revolutions relative to program start, however the position reading will be reset if the sensor loses power. Angular velocity is measured in degrees per second.

Like all other Smart devices, VEXos will process sensor updates every 10mS.

RotationSensor(port: int, direction: Direction = <Direction object>)
144    def __init__(self, port: int, direction: Direction = Direction.FORWARD):
145        """Creates a new rotation sensor on the given port.
146
147        Whether or not the sensor should be reversed on creation can be specified.
148
149        Args:
150
151        * port: The port number (1-21).
152
153        * direction: The direction of rotation. Defaults to forward.
154        """

Creates a new rotation sensor on the given port.

Whether or not the sensor should be reversed on creation can be specified.

Args:

  • port: The port number (1-21).

  • direction: The direction of rotation. Defaults to forward.

MIN_DATA_INTERVAL_MS: int = 5

The minimum data rate that you can set a rotation sensor to, in milliseconds.

TICKS_PER_ROTATION: int = 36000

The amount of unique sensor readings per one revolution of the sensor.

def position(self, unit: RotationUnit) -> float:
162    def position(self, unit: RotationUnit) -> float:
163        """Returns the total accumulated rotation of the sensor over time, in
164        the specified units.
165
166        Args:
167
168        * unit: The `RotationUnit` to use for the return value.
169        """
170        ...

Returns the total accumulated rotation of the sensor over time, in the specified units.

Args:

def angle(self, unit: RotationUnit) -> float:
172    def angle(self, unit: RotationUnit) -> float:
173        """Returns the absolute angle of rotation measured by the sensor.
174
175        This value is reported from 0-360 degrees.
176
177        Args:
178
179        * unit: The `RotationUnit` to use for the return value.
180        """
181        ...

Returns the absolute angle of rotation measured by the sensor.

This value is reported from 0-360 degrees.

Args:

def set_position(self, angle: float, angle_unit: RotationUnit):
183    def set_position(self, angle: float, angle_unit: RotationUnit):
184        """Sets the sensor's position reading.
185
186        Args:
187
188        * angle: The angle to set the sensor to.
189        * angle_unit: The `RotationUnit` to use for the angle.
190        """
191        ...

Sets the sensor's position reading.

Args:

  • angle: The angle to set the sensor to.
  • angle_unit: The RotationUnit to use for the angle.
def velocity(self) -> float:
193    def velocity(self) -> float:
194        """Returns the sensor's current velocity in degrees per second."""
195        ...

Returns the sensor's current velocity in degrees per second.

def reset_position(self):
197    def reset_position(self):
198        """Resets the sensor's position reading to zero."""
199        ...

Resets the sensor's position reading to zero.

def set_direction(self, new_direction: Direction):
201    def set_direction(self, new_direction: Direction):
202        """Sets the sensor to operate in a given `Direction`.
203
204        This determines which way the sensor considers to be “forwards”. You can use the marking on
205        the top of the motor as a reference:
206
207        - When `Direction.FORWARD` is specified, positive velocity/voltage values will cause the
208          motor to rotate **with the arrow on the top**. Position will increase as the motor rotates
209          **with the arrow**.
210        - When `Direction.REVERSE` is specified, positive velocity/voltage values will cause the
211          motor to rotate **against the arrow on the top**. Position will increase as the motor
212          rotates **against the arrow**.
213
214        Args:
215
216        * new_direction: The new `Direction` to set the sensor to.
217        """
218        ...

Sets the sensor to operate in a given Direction.

This determines which way the sensor considers to be “forwards”. You can use the marking on the top of the motor as a reference:

  • When Direction.FORWARD is specified, positive velocity/voltage values will cause the motor to rotate with the arrow on the top. Position will increase as the motor rotates with the arrow.
  • When Direction.REVERSE is specified, positive velocity/voltage values will cause the motor to rotate against the arrow on the top. Position will increase as the motor rotates against the arrow.

Args:

  • new_direction: The new Direction to set the sensor to.
def direction(self):
220    def direction(self):
221        """Returns the `Direction` of this sensor."""
222        ...

Returns the Direction of this sensor.

def status(self) -> int:
224    def status(self) -> int:
225        """Returns the sensor's internal status code."""
226        ...

Returns the sensor's internal status code.

def set_data_interval(self, interval: float, interval_unit: TimeUnit):
228    def set_data_interval(self, interval: float, interval_unit: TimeUnit):
229        """Sets the internal computation speed of the rotation sensor.
230
231        This method does NOT change the rate at which user code can read data off the sensor, as the
232        brain will only talk to the device every 10mS regardless of how fast data is being sent or
233        computed.
234
235        This duration should be above `RotationSensor.MIN_DATA_INTERVAL_MS` (5 milliseconds).
236
237        Args:
238
239        * interval: The new interval to set the sensor to.
240        * interval_unit: The unit of the interval.
241        """

Sets the internal computation speed of the rotation sensor.

This method does NOT change the rate at which user code can read data off the sensor, as the brain will only talk to the device every 10mS regardless of how fast data is being sent or computed.

This duration should be above RotationSensor.MIN_DATA_INTERVAL_MS (5 milliseconds).

Args:

  • interval: The new interval to set the sensor to.
  • interval_unit: The unit of the interval.
class AbstractMotor:
244class AbstractMotor:
245    """A motor plugged into a Smart Port.
246
247    This is an abstract class supporting shared methods for both the 5W (Exp)
248    and 11W motor variants. To create a motor, use the initializers of `ExpMotor`
249    or `V5Motor`, respectively.
250
251    # Overview
252
253    The V5 Smart Motors come in two variants: [an 11W model](https://www.vexrobotics.com/276-4840.html),
254    with interchangeable gear cartridges and [a 5.5W model](https://www.vexrobotics.com/276-4842.html),
255    with a fixed gearing. The 11W motor supports three cartridge options, which will gear the motor
256    down from its base RPM of 3600: a red cartridge providing 100 RPM output, a green cartridge for
257    200 RPM, and a blue cartridge for 600 RPM. The 5.5W motor comes with a non-interchangeable 200
258    RPM gear cartridge.
259
260    Smart Motors feature several integrated sensors, including an encoder for measuring the velocity
261    and position of the motor, a temperature sensor for detecting overheats, and sensors for
262    measuring output voltage, current, and efficiency.
263
264    Communication between a Smart motor and the V5 Brain occur at two different intervals. While
265    the motor communicates with the Brain every 5 milliseconds (and commands can be written to the
266    motor every 5mS), the Brain only reads data from the motor every 10mS. This effectively places
267    the data *write* interval at 5mS and the data *read* interval at 10mS.
268
269    More in-depth specs for the 11W motor can be found [here](https://kb.vex.com/hc/en-us/articles/360060929971-Understanding-V5-Smart-Motors).
270
271    # Current Limitations
272
273    There are some cases where VEXos or the motor itself may decide to limit output current:
274
275    - **Stall Prevention**: The stall current on 11W motors is limited to 2.5A. This limitation
276      eliminates the need for automatic resetting fuses (PTC devices) in the motor, which can
277      disrupt operation. By restricting the stall current to 2.5A, the motor effectively avoids
278      undesirable performance dips and ensures that users do not inadvertently cause stall
279      situations.
280
281    - **Motor Count**: Robots that use 8 or fewer 11W motors will have the aforementioned current limit
282      of 2.5A set for each motor. Robots using more than 8 motors, will have a lower default current limit
283      per-motor than 2.5A. This limit is determined in VEXos by a calculation accounting for the number of
284      motors plugged in, and the user's manually set current limits using `AbstractMotor.set_current_limit`. For
285      more information regarding the current limiting behavior of VEXos, see [this forum post](https://www.vexforum.com/t/how-does-the-decreased-current-affect-the-robot-when-using-more-than-8-motors/72650/4).
286
287    - **Temperature Management**: Motors have an onboard sensor for measuring internal temperature.
288      If the motor determines that it is overheating, it will throttle its output current and warn
289      the user.
290
291    # Motor Control
292
293    Each motor contains a sophisticated control system built around a Cortex M0+ microcontroller.
294    The microcontroller continuously monitors position, speed, direction, voltage, current, and
295    temperature through integrated sensors.
296
297    The onboard motor firmware implements a set of pre-tuned PID (Proportional-Integral-Derivative)
298    controllers operating on a 10-millisecond cycle for position and velocity control. Motors also
299    have braking functionality for holding a specific position under load.
300    """
301
302    WRITE_INTERVAL_MS: int = 5
303    """The interval at which the Brain will send new packets to an `AbstractMotor`."""
304
305    def set_voltage(self, voltage: float):
306        """Sets the motor's output voltage.
307
308        This voltage value spans from -12 (fully spinning reverse) to +12 (fully spinning forwards)
309        volts, and controls the raw output of the motor.
310
311        Args:
312
313        - voltage: The output voltage of the motor in volts.
314        """
315        ...
316
317    def set_velocity(self, rpm: int):
318        """Spins the motor at a target velocity.
319
320        This velocity corresponds to different actual speeds in RPM depending on the gearset used
321        for the motor. Velocity is held with an internal PID controller to ensure consistent
322        speed, as opposed to setting the motor's voltage.
323
324        Args:
325
326        - rpm: The desired target velocity in RPM.
327        """
328        ...
329
330    def brake(self):
331        """Sets the motor's target to a given `BrakeMode`."""
332        ...
333
334    def set_position_target(
335        self, position: float, position_unit: RotationUnit, velocity: int
336    ):
337        """Sets an absolute position target for the motor to attempt to reach using its internal
338        PID control.
339
340        Args:
341
342        - position: The desired position of the motor after the movement operation.
343        - position_unit: The unit of the position.
344        - velocity: The desired speed of the velocity in RPM during the movement operation
345        """
346        ...
347
348    def is_exp(self) -> bool:
349        """Returns `True` if the motor is a 5.5W (EXP) Smart Motor."""
350        ...
351
352    def is_v5(self) -> bool:
353        """Returns `True` if the motor is an 11W (V5) Smart Motor."""
354        ...
355
356    def max_voltage(self) -> float:
357        """Returns the maximum voltage for the motor based off of its `MotorType`.
358
359        See `V5Motor.MAX_VOLTAGE` and `ExpMotor.MAX_VOLTAGE`."""
360        ...
361
362    def velocity(self) -> float:
363        """Returns the motor's estimate of its angular velocity in rotations per minute (RPM).
364
365        # Accuracy
366
367        In some cases, this reported value may be noisy or inaccurate, especially for systems where
368        accurate velocity control at high speeds is required (such as flywheels). If the
369        accuracy of this value proves inadequate, you may opt to perform your own velocity
370        calculations by differentiating `AbstractMotor.position` over the reported internal timestamp
371        of the motor (currently not exposed in the Venice API).
372
373        > For more information about Smart motor velocity estimation, see [this article](https://sylvie.fyi/sylib/docs/db/d8e/md_module_writeups__velocity__estimation.html).
374
375        # Note
376
377        This is the **estimated** velocity, not the **target** velocity. The Venice API currently does
378        not mirror vexide's `Motor::target` so there is no way to get the target velocity.
379        """
380        ...
381
382    def power(self) -> float:
383        """Returns the power drawn by the motor in Watts."""
384        ...
385
386    def torque(self) -> float:
387        """Returns the torque output of the motor in Nm."""
388        ...
389
390    def voltage(self) -> float:
391        """Returns the voltage the motor is drawing in volts."""
392        ...
393
394    def raw_position(self) -> int:
395        """Returns the most recently recorded raw encoder tick data from the motor's IME.
396
397        The motor's integrated encoder has a TPR of 4096. Gearset is not taken into consideration
398        when dealing with the raw value, meaning this measurement will be taken relative to the
399        motor's internal position *before* being geared down from 3600RPM.
400
401        Methods such as `AbstractMotor.reset_position` and `AbstractMotor.set_position` do not
402        change the value of this raw measurement.
403        """
404        ...
405
406    def current(self) -> float:
407        """Returns the electrical current draw of the motor in amps."""
408        ...
409
410    def efficiency(self) -> float:
411        """Returns the efficiency of the motor from a range of [0.0, 1.0].
412
413        An efficiency of 1.0 means that the motor is moving electrically while drawing no electrical
414        power, and an efficiency of 0.0 means that the motor is drawing power but not moving."""
415        ...
416
417    def current_limit(self) -> float:
418        """Returns the current limit for the motor in amps.
419
420        This limit can be configured with the `AbstractMotor.set_current_limit` method."""
421        ...
422
423    def voltage_limit(self) -> float:
424        """Returns the voltage limit for the motor if one has been explicitly set."""
425        ...
426
427    def temperature(self) -> float:
428        """Returns the internal temperature recorded by the motor in increments of 5 °C."""
429        ...
430
431    def set_profiled_velocity(self, rpm: int):
432        """Changes the output velocity for a profiled movement (motor_move_absolute or
433        motor_move_relative).
434
435        This will have no effect if the motor is not following a profiled movement.
436
437        Args:
438
439        - rpm: The new profiled velocity target in rotations per minute.
440        """
441        ...
442
443    def reset_position(self):
444        """Sets the current encoder position to zero without moving the motor.
445
446        Analogous to taring or resetting the encoder to the current position.
447        """
448        ...
449
450    def set_current_limit(self, amps: float):
451        """Sets the current limit for the motor in amps.
452
453        Args:
454
455        - amps: The new current limit in amps.
456        """
457        ...
458
459    def set_voltage_limit(self, volts: float):
460        """Sets the voltage limit for the motor in volts.
461
462        Args:
463
464        - volts: The new voltage limit in volts.
465        """
466        ...
467
468    def is_over_temperature(self) -> bool:
469        """Returns `True` if the motor's over temperature flag is set."""
470        ...
471
472    def is_over_current(self):
473        """Returns `True` if the motor's over-current flag is set."""
474        ...
475
476    def is_driver_fault(self):
477        """Returns `True` if a H-bridge (motor driver) fault has occurred."""
478        ...
479
480    def is_driver_over_current(self):
481        """Returns `True` if the motor's H-bridge has an over-current fault."""
482        ...
483
484    def status(self) -> int:
485        """Returns the status flags of a motor as bits."""
486        ...
487
488    def faults(self) -> int:
489        """Returns the fault flags of the motor as bits."""
490        ...
491
492    def motor_type(self):
493        """Returns the type of the motor.
494
495        This does not check the hardware, it simply returns the type that the motor was created
496        with."""
497        ...
498
499    def position(self, unit: RotationUnit) -> float:
500        """Returns the angular position of the motor as measured by the IME (integrated motor encoder).
501
502        This is returned as a floating-point number in the given `RotationUnit`.
503
504        # Gearing affects position!
505
506        Position measurements are dependent on the Motor's `Gearset`, and may be reported
507        incorrectly if the motor is configured with the incorrect gearset variant. Make sure
508        that the motor is configured with the same gearset as its physical cartridge color.
509
510        Args:
511
512        - unit: The unit in which to return the position.
513        """
514        ...
515
516    def set_position(self, position: float, position_unit: RotationUnit):
517        """Sets the current encoder position to the given position without moving the motor.
518
519        Analogous to taring or resetting the encoder so that the new position is equal to the given
520        position.
521
522        Args:
523
524        - position: The position to set the encoder to.
525        - position_unit: The unit of the given position.
526        """
527        ...
528
529    def set_direction(self, direction: Direction):
530        """Sets the motor to operate in a given `Direction`.
531
532        This determines which way the motor considers to be “forwards”. You can use the marking on
533        the back of the motor as a reference:
534
535        - When `Direction.FORWARD` is specified, positive velocity/voltage values will cause the
536          motor to rotate **with the arrow on the back**. Position will increase as the motor
537          rotates **with the arrow**.
538        - When `Direction.REVERSE` is specified, positive velocity/voltage values will cause the
539          motor to rotate **against the arrow on the back**. Position will increase as the motor
540          rotates **against the arrow**.
541
542        Args:
543
544        - direction: The direction to set the motor to.
545        """
546        ...
547
548    def direction(self):
549        """Returns the `Direction` of this motor."""
550        ...

A motor plugged into a Smart Port.

This is an abstract class supporting shared methods for both the 5W (Exp) and 11W motor variants. To create a motor, use the initializers of ExpMotor or V5Motor, respectively.

Overview

The V5 Smart Motors come in two variants: an 11W model, with interchangeable gear cartridges and a 5.5W model, with a fixed gearing. The 11W motor supports three cartridge options, which will gear the motor down from its base RPM of 3600: a red cartridge providing 100 RPM output, a green cartridge for 200 RPM, and a blue cartridge for 600 RPM. The 5.5W motor comes with a non-interchangeable 200 RPM gear cartridge.

Smart Motors feature several integrated sensors, including an encoder for measuring the velocity and position of the motor, a temperature sensor for detecting overheats, and sensors for measuring output voltage, current, and efficiency.

Communication between a Smart motor and the V5 Brain occur at two different intervals. While the motor communicates with the Brain every 5 milliseconds (and commands can be written to the motor every 5mS), the Brain only reads data from the motor every 10mS. This effectively places the data write interval at 5mS and the data read interval at 10mS.

More in-depth specs for the 11W motor can be found here.

Current Limitations

There are some cases where VEXos or the motor itself may decide to limit output current:

  • Stall Prevention: The stall current on 11W motors is limited to 2.5A. This limitation eliminates the need for automatic resetting fuses (PTC devices) in the motor, which can disrupt operation. By restricting the stall current to 2.5A, the motor effectively avoids undesirable performance dips and ensures that users do not inadvertently cause stall situations.

  • Motor Count: Robots that use 8 or fewer 11W motors will have the aforementioned current limit of 2.5A set for each motor. Robots using more than 8 motors, will have a lower default current limit per-motor than 2.5A. This limit is determined in VEXos by a calculation accounting for the number of motors plugged in, and the user's manually set current limits using AbstractMotor.set_current_limit. For more information regarding the current limiting behavior of VEXos, see this forum post.

  • Temperature Management: Motors have an onboard sensor for measuring internal temperature. If the motor determines that it is overheating, it will throttle its output current and warn the user.

Motor Control

Each motor contains a sophisticated control system built around a Cortex M0+ microcontroller. The microcontroller continuously monitors position, speed, direction, voltage, current, and temperature through integrated sensors.

The onboard motor firmware implements a set of pre-tuned PID (Proportional-Integral-Derivative) controllers operating on a 10-millisecond cycle for position and velocity control. Motors also have braking functionality for holding a specific position under load.

WRITE_INTERVAL_MS: int = 5

The interval at which the Brain will send new packets to an AbstractMotor.

def set_voltage(self, voltage: float):
305    def set_voltage(self, voltage: float):
306        """Sets the motor's output voltage.
307
308        This voltage value spans from -12 (fully spinning reverse) to +12 (fully spinning forwards)
309        volts, and controls the raw output of the motor.
310
311        Args:
312
313        - voltage: The output voltage of the motor in volts.
314        """
315        ...

Sets the motor's output voltage.

This voltage value spans from -12 (fully spinning reverse) to +12 (fully spinning forwards) volts, and controls the raw output of the motor.

Args:

  • voltage: The output voltage of the motor in volts.
def set_velocity(self, rpm: int):
317    def set_velocity(self, rpm: int):
318        """Spins the motor at a target velocity.
319
320        This velocity corresponds to different actual speeds in RPM depending on the gearset used
321        for the motor. Velocity is held with an internal PID controller to ensure consistent
322        speed, as opposed to setting the motor's voltage.
323
324        Args:
325
326        - rpm: The desired target velocity in RPM.
327        """
328        ...

Spins the motor at a target velocity.

This velocity corresponds to different actual speeds in RPM depending on the gearset used for the motor. Velocity is held with an internal PID controller to ensure consistent speed, as opposed to setting the motor's voltage.

Args:

  • rpm: The desired target velocity in RPM.
def brake(self):
330    def brake(self):
331        """Sets the motor's target to a given `BrakeMode`."""
332        ...

Sets the motor's target to a given BrakeMode.

def set_position_target( self, position: float, position_unit: RotationUnit, velocity: int):
334    def set_position_target(
335        self, position: float, position_unit: RotationUnit, velocity: int
336    ):
337        """Sets an absolute position target for the motor to attempt to reach using its internal
338        PID control.
339
340        Args:
341
342        - position: The desired position of the motor after the movement operation.
343        - position_unit: The unit of the position.
344        - velocity: The desired speed of the velocity in RPM during the movement operation
345        """
346        ...

Sets an absolute position target for the motor to attempt to reach using its internal PID control.

Args:

  • position: The desired position of the motor after the movement operation.
  • position_unit: The unit of the position.
  • velocity: The desired speed of the velocity in RPM during the movement operation
def is_exp(self) -> bool:
348    def is_exp(self) -> bool:
349        """Returns `True` if the motor is a 5.5W (EXP) Smart Motor."""
350        ...

Returns True if the motor is a 5.5W (EXP) Smart Motor.

def is_v5(self) -> bool:
352    def is_v5(self) -> bool:
353        """Returns `True` if the motor is an 11W (V5) Smart Motor."""
354        ...

Returns True if the motor is an 11W (V5) Smart Motor.

def max_voltage(self) -> float:
356    def max_voltage(self) -> float:
357        """Returns the maximum voltage for the motor based off of its `MotorType`.
358
359        See `V5Motor.MAX_VOLTAGE` and `ExpMotor.MAX_VOLTAGE`."""
360        ...

Returns the maximum voltage for the motor based off of its MotorType.

See V5Motor.MAX_VOLTAGE and ExpMotor.MAX_VOLTAGE.

def velocity(self) -> float:
362    def velocity(self) -> float:
363        """Returns the motor's estimate of its angular velocity in rotations per minute (RPM).
364
365        # Accuracy
366
367        In some cases, this reported value may be noisy or inaccurate, especially for systems where
368        accurate velocity control at high speeds is required (such as flywheels). If the
369        accuracy of this value proves inadequate, you may opt to perform your own velocity
370        calculations by differentiating `AbstractMotor.position` over the reported internal timestamp
371        of the motor (currently not exposed in the Venice API).
372
373        > For more information about Smart motor velocity estimation, see [this article](https://sylvie.fyi/sylib/docs/db/d8e/md_module_writeups__velocity__estimation.html).
374
375        # Note
376
377        This is the **estimated** velocity, not the **target** velocity. The Venice API currently does
378        not mirror vexide's `Motor::target` so there is no way to get the target velocity.
379        """
380        ...

Returns the motor's estimate of its angular velocity in rotations per minute (RPM).

Accuracy

In some cases, this reported value may be noisy or inaccurate, especially for systems where accurate velocity control at high speeds is required (such as flywheels). If the accuracy of this value proves inadequate, you may opt to perform your own velocity calculations by differentiating AbstractMotor.position over the reported internal timestamp of the motor (currently not exposed in the Venice API).

For more information about Smart motor velocity estimation, see this article.

Note

This is the estimated velocity, not the target velocity. The Venice API currently does not mirror vexide's Motor::target so there is no way to get the target velocity.

def power(self) -> float:
382    def power(self) -> float:
383        """Returns the power drawn by the motor in Watts."""
384        ...

Returns the power drawn by the motor in Watts.

def torque(self) -> float:
386    def torque(self) -> float:
387        """Returns the torque output of the motor in Nm."""
388        ...

Returns the torque output of the motor in Nm.

def voltage(self) -> float:
390    def voltage(self) -> float:
391        """Returns the voltage the motor is drawing in volts."""
392        ...

Returns the voltage the motor is drawing in volts.

def raw_position(self) -> int:
394    def raw_position(self) -> int:
395        """Returns the most recently recorded raw encoder tick data from the motor's IME.
396
397        The motor's integrated encoder has a TPR of 4096. Gearset is not taken into consideration
398        when dealing with the raw value, meaning this measurement will be taken relative to the
399        motor's internal position *before* being geared down from 3600RPM.
400
401        Methods such as `AbstractMotor.reset_position` and `AbstractMotor.set_position` do not
402        change the value of this raw measurement.
403        """
404        ...

Returns the most recently recorded raw encoder tick data from the motor's IME.

The motor's integrated encoder has a TPR of 4096. Gearset is not taken into consideration when dealing with the raw value, meaning this measurement will be taken relative to the motor's internal position before being geared down from 3600RPM.

Methods such as AbstractMotor.reset_position and AbstractMotor.set_position do not change the value of this raw measurement.

def current(self) -> float:
406    def current(self) -> float:
407        """Returns the electrical current draw of the motor in amps."""
408        ...

Returns the electrical current draw of the motor in amps.

def efficiency(self) -> float:
410    def efficiency(self) -> float:
411        """Returns the efficiency of the motor from a range of [0.0, 1.0].
412
413        An efficiency of 1.0 means that the motor is moving electrically while drawing no electrical
414        power, and an efficiency of 0.0 means that the motor is drawing power but not moving."""
415        ...

Returns the efficiency of the motor from a range of [0.0, 1.0].

An efficiency of 1.0 means that the motor is moving electrically while drawing no electrical power, and an efficiency of 0.0 means that the motor is drawing power but not moving.

def current_limit(self) -> float:
417    def current_limit(self) -> float:
418        """Returns the current limit for the motor in amps.
419
420        This limit can be configured with the `AbstractMotor.set_current_limit` method."""
421        ...

Returns the current limit for the motor in amps.

This limit can be configured with the AbstractMotor.set_current_limit method.

def voltage_limit(self) -> float:
423    def voltage_limit(self) -> float:
424        """Returns the voltage limit for the motor if one has been explicitly set."""
425        ...

Returns the voltage limit for the motor if one has been explicitly set.

def temperature(self) -> float:
427    def temperature(self) -> float:
428        """Returns the internal temperature recorded by the motor in increments of 5 °C."""
429        ...

Returns the internal temperature recorded by the motor in increments of 5 °C.

def set_profiled_velocity(self, rpm: int):
431    def set_profiled_velocity(self, rpm: int):
432        """Changes the output velocity for a profiled movement (motor_move_absolute or
433        motor_move_relative).
434
435        This will have no effect if the motor is not following a profiled movement.
436
437        Args:
438
439        - rpm: The new profiled velocity target in rotations per minute.
440        """
441        ...

Changes the output velocity for a profiled movement (motor_move_absolute or motor_move_relative).

This will have no effect if the motor is not following a profiled movement.

Args:

  • rpm: The new profiled velocity target in rotations per minute.
def reset_position(self):
443    def reset_position(self):
444        """Sets the current encoder position to zero without moving the motor.
445
446        Analogous to taring or resetting the encoder to the current position.
447        """
448        ...

Sets the current encoder position to zero without moving the motor.

Analogous to taring or resetting the encoder to the current position.

def set_current_limit(self, amps: float):
450    def set_current_limit(self, amps: float):
451        """Sets the current limit for the motor in amps.
452
453        Args:
454
455        - amps: The new current limit in amps.
456        """
457        ...

Sets the current limit for the motor in amps.

Args:

  • amps: The new current limit in amps.
def set_voltage_limit(self, volts: float):
459    def set_voltage_limit(self, volts: float):
460        """Sets the voltage limit for the motor in volts.
461
462        Args:
463
464        - volts: The new voltage limit in volts.
465        """
466        ...

Sets the voltage limit for the motor in volts.

Args:

  • volts: The new voltage limit in volts.
def is_over_temperature(self) -> bool:
468    def is_over_temperature(self) -> bool:
469        """Returns `True` if the motor's over temperature flag is set."""
470        ...

Returns True if the motor's over temperature flag is set.

def is_over_current(self):
472    def is_over_current(self):
473        """Returns `True` if the motor's over-current flag is set."""
474        ...

Returns True if the motor's over-current flag is set.

def is_driver_fault(self):
476    def is_driver_fault(self):
477        """Returns `True` if a H-bridge (motor driver) fault has occurred."""
478        ...

Returns True if a H-bridge (motor driver) fault has occurred.

def is_driver_over_current(self):
480    def is_driver_over_current(self):
481        """Returns `True` if the motor's H-bridge has an over-current fault."""
482        ...

Returns True if the motor's H-bridge has an over-current fault.

def status(self) -> int:
484    def status(self) -> int:
485        """Returns the status flags of a motor as bits."""
486        ...

Returns the status flags of a motor as bits.

def faults(self) -> int:
488    def faults(self) -> int:
489        """Returns the fault flags of the motor as bits."""
490        ...

Returns the fault flags of the motor as bits.

def motor_type(self):
492    def motor_type(self):
493        """Returns the type of the motor.
494
495        This does not check the hardware, it simply returns the type that the motor was created
496        with."""
497        ...

Returns the type of the motor.

This does not check the hardware, it simply returns the type that the motor was created with.

def position(self, unit: RotationUnit) -> float:
499    def position(self, unit: RotationUnit) -> float:
500        """Returns the angular position of the motor as measured by the IME (integrated motor encoder).
501
502        This is returned as a floating-point number in the given `RotationUnit`.
503
504        # Gearing affects position!
505
506        Position measurements are dependent on the Motor's `Gearset`, and may be reported
507        incorrectly if the motor is configured with the incorrect gearset variant. Make sure
508        that the motor is configured with the same gearset as its physical cartridge color.
509
510        Args:
511
512        - unit: The unit in which to return the position.
513        """
514        ...

Returns the angular position of the motor as measured by the IME (integrated motor encoder).

This is returned as a floating-point number in the given RotationUnit.

Gearing affects position!

Position measurements are dependent on the Motor's Gearset, and may be reported incorrectly if the motor is configured with the incorrect gearset variant. Make sure that the motor is configured with the same gearset as its physical cartridge color.

Args:

  • unit: The unit in which to return the position.
def set_position(self, position: float, position_unit: RotationUnit):
516    def set_position(self, position: float, position_unit: RotationUnit):
517        """Sets the current encoder position to the given position without moving the motor.
518
519        Analogous to taring or resetting the encoder so that the new position is equal to the given
520        position.
521
522        Args:
523
524        - position: The position to set the encoder to.
525        - position_unit: The unit of the given position.
526        """
527        ...

Sets the current encoder position to the given position without moving the motor.

Analogous to taring or resetting the encoder so that the new position is equal to the given position.

Args:

  • position: The position to set the encoder to.
  • position_unit: The unit of the given position.
def set_direction(self, direction: Direction):
529    def set_direction(self, direction: Direction):
530        """Sets the motor to operate in a given `Direction`.
531
532        This determines which way the motor considers to be “forwards”. You can use the marking on
533        the back of the motor as a reference:
534
535        - When `Direction.FORWARD` is specified, positive velocity/voltage values will cause the
536          motor to rotate **with the arrow on the back**. Position will increase as the motor
537          rotates **with the arrow**.
538        - When `Direction.REVERSE` is specified, positive velocity/voltage values will cause the
539          motor to rotate **against the arrow on the back**. Position will increase as the motor
540          rotates **against the arrow**.
541
542        Args:
543
544        - direction: The direction to set the motor to.
545        """
546        ...

Sets the motor to operate in a given Direction.

This determines which way the motor considers to be “forwards”. You can use the marking on the back of the motor as a reference:

  • When Direction.FORWARD is specified, positive velocity/voltage values will cause the motor to rotate with the arrow on the back. Position will increase as the motor rotates with the arrow.
  • When Direction.REVERSE is specified, positive velocity/voltage values will cause the motor to rotate against the arrow on the back. Position will increase as the motor rotates against the arrow.

Args:

  • direction: The direction to set the motor to.
def direction(self):
548    def direction(self):
549        """Returns the `Direction` of this motor."""
550        ...

Returns the Direction of this motor.

class V5Motor(AbstractMotor):
553class V5Motor(AbstractMotor):
554    """Represents an 11W (V5) Smart Motor. See `AbstractMotor`."""
555
556    MAX_VOLTAGE: Literal[12] = 12
557    """The maximum voltage value that can be sent to a `V5Motor`."""
558
559    def __init__(self, port: int, direction: Direction, gearset: Gearset):
560        """Creates a new 11W (V5) Smart Motor.
561
562        See `ExpMotor.__init__` to create a 5.5W (EXP) Smart Motor.
563
564        Args:
565
566        - port: The smart port to initialize the motor on.
567        - direction: The direction to set the motor to.
568        - gearset: The gearset to set the motor to.
569        """
570        ...
571
572    def set_gearset(self, gearset: Gearset):
573        """Sets the gearset of an 11W motor.
574
575        This may silently fail if the motor is a 5.5W motor, which occurs in the edge
576        case described in `V5Motor.gearset`.
577
578        Args:
579
580        - gearset: the new `Gearset` to use for the motor.
581        """
582        ...
583
584    def gearset(self) -> Gearset:
585        """Returns the gearset of an 11W motor.
586
587        For 5.5W motors [1], this will always be returned as `Gearset.GREEN`.
588
589        [1] There is a slim edge case in which you initialize a `V5Motor` at a time
590        when the specified port indeed has a plugged-in 11W motor, but then unplug
591        it and replace it with a 5.5W motor. Note that the respective constructors of
592        `V5Motor` and `ExpMotor` *will* throw if the motor is not the correct type.
593        """
594        ...

Represents an 11W (V5) Smart Motor. See AbstractMotor.

V5Motor(port: int, direction: Direction, gearset: Gearset)
559    def __init__(self, port: int, direction: Direction, gearset: Gearset):
560        """Creates a new 11W (V5) Smart Motor.
561
562        See `ExpMotor.__init__` to create a 5.5W (EXP) Smart Motor.
563
564        Args:
565
566        - port: The smart port to initialize the motor on.
567        - direction: The direction to set the motor to.
568        - gearset: The gearset to set the motor to.
569        """
570        ...

Creates a new 11W (V5) Smart Motor.

See ExpMotor.__init__ to create a 5.5W (EXP) Smart Motor.

Args:

  • port: The smart port to initialize the motor on.
  • direction: The direction to set the motor to.
  • gearset: The gearset to set the motor to.
MAX_VOLTAGE: Literal[12] = 12

The maximum voltage value that can be sent to a V5Motor.

def set_gearset(self, gearset: Gearset):
572    def set_gearset(self, gearset: Gearset):
573        """Sets the gearset of an 11W motor.
574
575        This may silently fail if the motor is a 5.5W motor, which occurs in the edge
576        case described in `V5Motor.gearset`.
577
578        Args:
579
580        - gearset: the new `Gearset` to use for the motor.
581        """
582        ...

Sets the gearset of an 11W motor.

This may silently fail if the motor is a 5.5W motor, which occurs in the edge case described in V5Motor.gearset.

Args:

  • gearset: the new Gearset to use for the motor.
def gearset(self) -> Gearset:
584    def gearset(self) -> Gearset:
585        """Returns the gearset of an 11W motor.
586
587        For 5.5W motors [1], this will always be returned as `Gearset.GREEN`.
588
589        [1] There is a slim edge case in which you initialize a `V5Motor` at a time
590        when the specified port indeed has a plugged-in 11W motor, but then unplug
591        it and replace it with a 5.5W motor. Note that the respective constructors of
592        `V5Motor` and `ExpMotor` *will* throw if the motor is not the correct type.
593        """
594        ...

Returns the gearset of an 11W motor.

For 5.5W motors [1], this will always be returned as Gearset.GREEN.

[1] There is a slim edge case in which you initialize a V5Motor at a time when the specified port indeed has a plugged-in 11W motor, but then unplug it and replace it with a 5.5W motor. Note that the respective constructors of V5Motor and ExpMotor will throw if the motor is not the correct type.

class ExpMotor(AbstractMotor):
597class ExpMotor(AbstractMotor):
598    """Represents an 5.5W (EXP) Smart Motor. See `AbstractMotor`."""
599
600    def __init__(self, port: int, direction: Direction):
601        """Creates a new 5.5W (EXP) Smart Motor.
602
603        See `V5Motor.__init__` to create a 11W (V5) Smart Motor.
604
605        Args:
606
607        - port: The smart port to initialize the motor on.
608        - direction: The direction to set the motor to.
609        """
610        ...
611
612    MAX_VOLTAGE: Literal[8] = 8
613    """The maximum voltage value that can be sent to a `ExpMotor`."""

Represents an 5.5W (EXP) Smart Motor. See AbstractMotor.

ExpMotor(port: int, direction: Direction)
600    def __init__(self, port: int, direction: Direction):
601        """Creates a new 5.5W (EXP) Smart Motor.
602
603        See `V5Motor.__init__` to create a 11W (V5) Smart Motor.
604
605        Args:
606
607        - port: The smart port to initialize the motor on.
608        - direction: The direction to set the motor to.
609        """
610        ...

Creates a new 5.5W (EXP) Smart Motor.

See V5Motor.__init__ to create a 11W (V5) Smart Motor.

Args:

  • port: The smart port to initialize the motor on.
  • direction: The direction to set the motor to.
MAX_VOLTAGE: Literal[8] = 8

The maximum voltage value that can be sent to a ExpMotor.

class DistanceObject:
616class DistanceObject:
617    """Readings from a physical object detected by a Distance Sensor."""
618
619    distance: int
620    "The distance of the object from the sensor (in millimeters)."
621
622    confidence: float
623    """The confidence in the distance measurement from 0.0 to 1.0."""
624
625    velocity: float
626    """Observed velocity of the object in m/s."""
627
628    relative_size: int
629    """A guess at the object's "relative size".
630
631    This is a value that has a range of 0 to 400. A 18" x 30" grey card will return a value of
632    approximately 75 in typical room lighting. If the sensor is not able to detect an object,
633    None is returned.
634
635    This sensor reading is unusual, as it is entirely unitless with the seemingly arbitrary
636    range of 0-400 existing due to VEXCode's
637    [`vex::sizeType`](https://api.vex.com/v5/home/python/Enums.html#object-size-types) enum
638    having four variants. It's unknown what the sensor is *actually* measuring here either,
639    so use this data with a grain of salt."""

Readings from a physical object detected by a Distance Sensor.

distance: int

The distance of the object from the sensor (in millimeters).

confidence: float

The confidence in the distance measurement from 0.0 to 1.0.

velocity: float

Observed velocity of the object in m/s.

relative_size: int

A guess at the object's "relative size".

This is a value that has a range of 0 to 400. A 18" x 30" grey card will return a value of approximately 75 in typical room lighting. If the sensor is not able to detect an object, None is returned.

This sensor reading is unusual, as it is entirely unitless with the seemingly arbitrary range of 0-400 existing due to VEXCode's vex::sizeType enum having four variants. It's unknown what the sensor is actually measuring here either, so use this data with a grain of salt.

class DistanceSensor:
642class DistanceSensor:
643    """A distance sensor plugged into a Smart Port.
644
645    The VEX V5 Distance Sensor uses a
646    Class 1 laser to measure the distance, object size classification, and relative velocity of a
647    single object.
648
649    # Hardware Overview
650
651    The sensor uses a narrow-beam Class 1 laser (similar to phone proximity sensors) for precise
652    detection. It measures distances from 20mm to 2000mm with varying accuracy (±15mm below 200mm,
653    ±5% above 200mm).
654
655    The sensor can classify detected objects by relative size, helping distinguish between walls and
656    field elements. It also measures the relative approach velocity between the sensor and target.
657
658    Due to the use of a laser, measurements are single-point and highly directional, meaning that
659    objects will only be detected when they are directly in front of the sensor's field of view.
660
661    Like all other Smart devices, VEXos will process sensor updates every 10mS.
662    """
663
664    def __init__(self, port: int):
665        """Creates a new distance sensor given the port.
666
667        Args:
668
669        - port: The port number of the sensor.
670        """
671        ...
672
673    def object(self) -> Union[DistanceObject, None]:
674        """Attempts to detect an object, returning `None` if no object could be found."""
675        ...
676
677    def status(self) -> int:
678        """Returns the internal status code of the distance sensor.
679
680        The status code of the signature can tell you if the sensor is still initializing or if it
681        is working correctly.
682
683        - If the distance sensor is still initializing, the status code will be 0x00.
684        - If it is done initializing and functioning correctly, the status code will be 0x82 or
685          0x86.
686        """
687        ...

A distance sensor plugged into a Smart Port.

The VEX V5 Distance Sensor uses a Class 1 laser to measure the distance, object size classification, and relative velocity of a single object.

Hardware Overview

The sensor uses a narrow-beam Class 1 laser (similar to phone proximity sensors) for precise detection. It measures distances from 20mm to 2000mm with varying accuracy (±15mm below 200mm, ±5% above 200mm).

The sensor can classify detected objects by relative size, helping distinguish between walls and field elements. It also measures the relative approach velocity between the sensor and target.

Due to the use of a laser, measurements are single-point and highly directional, meaning that objects will only be detected when they are directly in front of the sensor's field of view.

Like all other Smart devices, VEXos will process sensor updates every 10mS.

DistanceSensor(port: int)
664    def __init__(self, port: int):
665        """Creates a new distance sensor given the port.
666
667        Args:
668
669        - port: The port number of the sensor.
670        """
671        ...

Creates a new distance sensor given the port.

Args:

  • port: The port number of the sensor.
def object(self) -> Optional[DistanceObject]:
673    def object(self) -> Union[DistanceObject, None]:
674        """Attempts to detect an object, returning `None` if no object could be found."""
675        ...

Attempts to detect an object, returning None if no object could be found.

def status(self) -> int:
677    def status(self) -> int:
678        """Returns the internal status code of the distance sensor.
679
680        The status code of the signature can tell you if the sensor is still initializing or if it
681        is working correctly.
682
683        - If the distance sensor is still initializing, the status code will be 0x00.
684        - If it is done initializing and functioning correctly, the status code will be 0x82 or
685          0x86.
686        """
687        ...

Returns the internal status code of the distance sensor.

The status code of the signature can tell you if the sensor is still initializing or if it is working correctly.

  • If the distance sensor is still initializing, the status code will be 0x00.
  • If it is done initializing and functioning correctly, the status code will be 0x82 or 0x86.
class AiVisionColor:
690class AiVisionColor:
691    """A color signature used by an AI Vision Sensor to detect color blobs."""
692
693    r: int
694    """The red component of the RGB color value."""
695
696    g: int
697    """The green component of the RGB color value."""
698
699    b: int
700    """The blue component of the RGB color value."""
701
702    hue_range: float
703    """The accepted hue range of the color. VEXcode limits this value to [0, 20]"""
704
705    saturation_range: float
706    """The accepted saturation range of the color."""
707
708    def __init__(
709        self, r: int, g: int, b: int, hue_range: float, saturation_range: float
710    ):
711        """Creates a new `AiVisionColor` from the provided args.
712
713        Args:
714
715        - r: The red component of the RGB color value.
716        - g: The green component of the RGB color value.
717        - b: The blue component of the RGB color value.
718        - hue_range: The accepted hue range of the color.
719        - saturation_range: The accepted saturation range of the color.
720        """
721        ...

A color signature used by an AI Vision Sensor to detect color blobs.

AiVisionColor(r: int, g: int, b: int, hue_range: float, saturation_range: float)
708    def __init__(
709        self, r: int, g: int, b: int, hue_range: float, saturation_range: float
710    ):
711        """Creates a new `AiVisionColor` from the provided args.
712
713        Args:
714
715        - r: The red component of the RGB color value.
716        - g: The green component of the RGB color value.
717        - b: The blue component of the RGB color value.
718        - hue_range: The accepted hue range of the color.
719        - saturation_range: The accepted saturation range of the color.
720        """
721        ...

Creates a new AiVisionColor from the provided args.

Args:

  • r: The red component of the RGB color value.
  • g: The green component of the RGB color value.
  • b: The blue component of the RGB color value.
  • hue_range: The accepted hue range of the color.
  • saturation_range: The accepted saturation range of the color.
r: int

The red component of the RGB color value.

g: int

The green component of the RGB color value.

b: int

The blue component of the RGB color value.

hue_range: float

The accepted hue range of the color. VEXcode limits this value to [0, 20]

saturation_range: float

The accepted saturation range of the color.

class AiVisionColorCode:
724class AiVisionColorCode:
725    """A color code used by an AI Vision Sensor to detect groups of color blobs.
726
727    Color codes are effectively "groups" of color signatures. A color code associated multiple color
728    signatures on the sensor will be detected as a single object when all signatures are seen next
729    to each other.
730
731    Color codes can associate up to 7 color signatures and detections will be returned as
732    `AiVisionObject.Code` variants.
733    """
734
735    def __init__(
736        self,
737        first: Union[int, None],
738        second: Union[int, None],
739        third: Union[int, None],
740        fourth: Union[int, None],
741        fifth: Union[int, None],
742        sixth: Union[int, None],
743        seventh: Union[int, None],
744    ):
745        """Creates a new `AiVisionColorCode` from the provided args.
746
747        Args:
748
749        - first: the first color signature id.
750        - second: the second color signature id.
751        - third: the third color signature id.
752        - fourth: the fourth color signature id.
753        - fifth: the fifth color signature id.
754        - sixth: the sixth color signature id.
755        - seventh: the seventh color signature id.
756        """
757        ...
758
759    # we annotate the docstring as @public because pdoc otherqise doesn't
760    # document slot items
761    def __getitem__(self, item: int):
762        """@public Returns the color signature id at the given index.
763
764        Note that this does NOT support setting. For example, the following code works:
765        ```python
766        color_code_ids = [1, 2, 3, 4, 5, 6, 7]
767        my_color_code = AiVisionColorCode(*color_code_ids)
768        print(my_color_code[2]) # prints 3
769        ```
770        But this code doesn't:
771        ```python
772        color_code_ids = [1, 2, 3, 4, 5, 6, 7]
773        my_color_code = AiVisionColorCode(*color_code_ids)
774        my_color_code[6] = 9 # fails
775        ```
776        """
777        ...

A color code used by an AI Vision Sensor to detect groups of color blobs.

Color codes are effectively "groups" of color signatures. A color code associated multiple color signatures on the sensor will be detected as a single object when all signatures are seen next to each other.

Color codes can associate up to 7 color signatures and detections will be returned as AiVisionObject.Code variants.

AiVisionColorCode( first: Optional[int], second: Optional[int], third: Optional[int], fourth: Optional[int], fifth: Optional[int], sixth: Optional[int], seventh: Optional[int])
735    def __init__(
736        self,
737        first: Union[int, None],
738        second: Union[int, None],
739        third: Union[int, None],
740        fourth: Union[int, None],
741        fifth: Union[int, None],
742        sixth: Union[int, None],
743        seventh: Union[int, None],
744    ):
745        """Creates a new `AiVisionColorCode` from the provided args.
746
747        Args:
748
749        - first: the first color signature id.
750        - second: the second color signature id.
751        - third: the third color signature id.
752        - fourth: the fourth color signature id.
753        - fifth: the fifth color signature id.
754        - sixth: the sixth color signature id.
755        - seventh: the seventh color signature id.
756        """
757        ...

Creates a new AiVisionColorCode from the provided args.

Args:

  • first: the first color signature id.
  • second: the second color signature id.
  • third: the third color signature id.
  • fourth: the fourth color signature id.
  • fifth: the fifth color signature id.
  • sixth: the sixth color signature id.
  • seventh: the seventh color signature id.
def __getitem__(self, item: int):
761    def __getitem__(self, item: int):
762        """@public Returns the color signature id at the given index.
763
764        Note that this does NOT support setting. For example, the following code works:
765        ```python
766        color_code_ids = [1, 2, 3, 4, 5, 6, 7]
767        my_color_code = AiVisionColorCode(*color_code_ids)
768        print(my_color_code[2]) # prints 3
769        ```
770        But this code doesn't:
771        ```python
772        color_code_ids = [1, 2, 3, 4, 5, 6, 7]
773        my_color_code = AiVisionColorCode(*color_code_ids)
774        my_color_code[6] = 9 # fails
775        ```
776        """
777        ...

Returns the color signature id at the given index.

Note that this does NOT support setting. For example, the following code works:

color_code_ids = [1, 2, 3, 4, 5, 6, 7]
my_color_code = AiVisionColorCode(*color_code_ids)
print(my_color_code[2]) # prints 3

But this code doesn't:

color_code_ids = [1, 2, 3, 4, 5, 6, 7]
my_color_code = AiVisionColorCode(*color_code_ids)
my_color_code[6] = 9 # fails
class AiVisionDetectionMode:
780class AiVisionDetectionMode:
781    """Flags relating to the sensor's detection mode."""
782
783    APRILTAG: ClassVar["AiVisionDetectionMode"]
784    """Enable apriltag detection"""
785
786    COLOR: ClassVar["AiVisionDetectionMode"]
787    """Enable color detection"""
788
789    MODEL: ClassVar["AiVisionDetectionMode"]
790    """Enable model detection"""
791
792    COLOR_MERGE: ClassVar["AiVisionDetectionMode"]
793    """Merge color blobs?"""
794
795    def __or__(self, value) -> AiVisionDetectionMode:
796        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned
797
798        ```python
799        sensor = AiVisionSensor(7)
800        # enable apriltag and color detection
801        sensor.set_detection_mode(AiVisionDetectionMode.APRILTAG | AiVisionDetectionMode.COLOR)
802        ```
803        """
804        ...
805
806    def __ior__(self, value):
807        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. `self` is set to the result.
808
809        ```python
810        sensor = AiVisionSensor(7)
811        # enable apriltag and color detection
812        mode = AiVisionDetectionMode.APRILTAG
813        mode |= AiVisionDetectionMode.COLOR
814        sensor.set_detection_mode(mode)
815        ```
816        """
817        ...

Flags relating to the sensor's detection mode.

APRILTAG: ClassVar[AiVisionDetectionMode] = <AiVisionDetectionMode object>

Enable apriltag detection

COLOR: ClassVar[AiVisionDetectionMode] = <AiVisionDetectionMode object>

Enable color detection

MODEL: ClassVar[AiVisionDetectionMode] = <AiVisionDetectionMode object>

Enable model detection

COLOR_MERGE: ClassVar[AiVisionDetectionMode] = <AiVisionDetectionMode object>

Merge color blobs?

def __or__(self, value) -> AiVisionDetectionMode:
795    def __or__(self, value) -> AiVisionDetectionMode:
796        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned
797
798        ```python
799        sensor = AiVisionSensor(7)
800        # enable apriltag and color detection
801        sensor.set_detection_mode(AiVisionDetectionMode.APRILTAG | AiVisionDetectionMode.COLOR)
802        ```
803        """
804        ...

Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned

sensor = AiVisionSensor(7)
# enable apriltag and color detection
sensor.set_detection_mode(AiVisionDetectionMode.APRILTAG | AiVisionDetectionMode.COLOR)
def __ior__(self, value):
806    def __ior__(self, value):
807        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. `self` is set to the result.
808
809        ```python
810        sensor = AiVisionSensor(7)
811        # enable apriltag and color detection
812        mode = AiVisionDetectionMode.APRILTAG
813        mode |= AiVisionDetectionMode.COLOR
814        sensor.set_detection_mode(mode)
815        ```
816        """
817        ...

Bitwise OR is applied to the internal bitflags, "merging" the modes. self is set to the result.

sensor = AiVisionSensor(7)
# enable apriltag and color detection
mode = AiVisionDetectionMode.APRILTAG
mode |= AiVisionDetectionMode.COLOR
sensor.set_detection_mode(mode)
class AiVisionFlags:
826class AiVisionFlags:
827    """Represents the mode of the AI Vision sensor."""
828
829    DISABLE_APRILTAG: ClassVar["AiVisionFlags"]
830    """Disable apriltag detection"""
831
832    DISABLE_COLOR: ClassVar["AiVisionFlags"]
833    """Disable color detection"""
834
835    DISABLE_MODEL: ClassVar["AiVisionFlags"]
836    """Disable model detection"""
837
838    COLOR_MERGE: ClassVar["AiVisionFlags"]
839    """Merge color blobs?"""
840
841    DISABLE_STATUS_OVERLAY: ClassVar["AiVisionFlags"]
842    """Disable status overlay"""
843
844    DISABLE_USB_OVERLAY: ClassVar["AiVisionFlags"]
845    """Disable USB overlay"""
846
847    def __or__(self, value) -> AiVisionDetectionMode:
848        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned
849
850        ```python
851        sensor = AiVisionSensor(7)
852        # disable status and usb overlays
853        sensor.set_flags(AiVisionFlags.DISABLE_STATUS_OVERLAY | AiVisionFlags.DISABLE_USB_OVERLAY)
854        ```
855        """
856        ...
857
858    def __ior__(self, value):
859        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. `self` is set to the result.
860
861        ```python
862        sensor = AiVisionSensor(7)
863        # disable status and usb overlays
864        mode = AiVisionFlags.DISABLE_STATUS_OVERLAY
865        mode |= AiVisionFlags.DISABLE_USB_OVERLAY
866        sensor.set_flags(mode)
867        ```
868        """
869        ...

Represents the mode of the AI Vision sensor.

DISABLE_APRILTAG: ClassVar[AiVisionFlags] = <AiVisionFlags object>

Disable apriltag detection

DISABLE_COLOR: ClassVar[AiVisionFlags] = <AiVisionFlags object>

Disable color detection

DISABLE_MODEL: ClassVar[AiVisionFlags] = <AiVisionFlags object>

Disable model detection

COLOR_MERGE: ClassVar[AiVisionFlags] = <AiVisionFlags object>

Merge color blobs?

DISABLE_STATUS_OVERLAY: ClassVar[AiVisionFlags] = <AiVisionFlags object>

Disable status overlay

DISABLE_USB_OVERLAY: ClassVar[AiVisionFlags] = <AiVisionFlags object>

Disable USB overlay

def __or__(self, value) -> AiVisionDetectionMode:
847    def __or__(self, value) -> AiVisionDetectionMode:
848        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned
849
850        ```python
851        sensor = AiVisionSensor(7)
852        # disable status and usb overlays
853        sensor.set_flags(AiVisionFlags.DISABLE_STATUS_OVERLAY | AiVisionFlags.DISABLE_USB_OVERLAY)
854        ```
855        """
856        ...

Bitwise OR is applied to the internal bitflags, "merging" the modes. The result is returned

sensor = AiVisionSensor(7)
# disable status and usb overlays
sensor.set_flags(AiVisionFlags.DISABLE_STATUS_OVERLAY | AiVisionFlags.DISABLE_USB_OVERLAY)
def __ior__(self, value):
858    def __ior__(self, value):
859        """@public Bitwise OR is applied to the internal bitflags, "merging" the modes. `self` is set to the result.
860
861        ```python
862        sensor = AiVisionSensor(7)
863        # disable status and usb overlays
864        mode = AiVisionFlags.DISABLE_STATUS_OVERLAY
865        mode |= AiVisionFlags.DISABLE_USB_OVERLAY
866        sensor.set_flags(mode)
867        ```
868        """
869        ...

Bitwise OR is applied to the internal bitflags, "merging" the modes. self is set to the result.

sensor = AiVisionSensor(7)
# disable status and usb overlays
mode = AiVisionFlags.DISABLE_STATUS_OVERLAY
mode |= AiVisionFlags.DISABLE_USB_OVERLAY
sensor.set_flags(mode)
class AiVisionColorObject:
880class AiVisionColorObject:
881    """The data associated with an AI Vision object detected by color blob detection."""
882
883    id: int
884    """ID of the signature used to detect this object."""
885
886    position_x: int
887    """The x component of the top-left corner of the object."""
888
889    position_y: int
890    """The y component of the top-left corner of the object."""
891
892    width: int
893    """The width of the object."""
894
895    height: int
896    """The height of the object."""

The data associated with an AI Vision object detected by color blob detection.

id: int

ID of the signature used to detect this object.

position_x: int

The x component of the top-left corner of the object.

position_y: int

The y component of the top-left corner of the object.

width: int

The width of the object.

height: int

The height of the object.

class AiVisionCodeObject:
899class AiVisionCodeObject:
900    """The data associated with an AI Vision object detected by color code detection."""
901
902    id: int
903    """ID of the code used to detect this object."""
904
905    position_x: int
906    """The x component of the position of the object."""
907
908    position_y: int
909    """The y component of the position of the object."""
910
911    width: int
912    """The width of the object."""
913
914    height: int
915    """The height of the object."""
916
917    def angle(self, unit: RotationUnit) -> float:
918        """The angle of the object's associated colors. Not always reliably available.
919
920        Args:
921
922        - units: The unit of measurement for the angle. This is the unit of
923        the returned `float`.
924        """
925        ...

The data associated with an AI Vision object detected by color code detection.

id: int

ID of the code used to detect this object.

position_x: int

The x component of the position of the object.

position_y: int

The y component of the position of the object.

width: int

The width of the object.

height: int

The height of the object.

def angle(self, unit: RotationUnit) -> float:
917    def angle(self, unit: RotationUnit) -> float:
918        """The angle of the object's associated colors. Not always reliably available.
919
920        Args:
921
922        - units: The unit of measurement for the angle. This is the unit of
923        the returned `float`.
924        """
925        ...

The angle of the object's associated colors. Not always reliably available.

Args:

  • units: The unit of measurement for the angle. This is the unit of the returned float.
class AiVisionAprilTagObject:
928class AiVisionAprilTagObject:
929    """The data associated with an AI Vision object detected by apriltag detection."""
930
931    id: int
932    """The detected AprilTag(s) ID number"""
933
934    top_left_x: int
935    """x component of the position of the top-left corner of the tag"""
936
937    top_left_y: int
938    """y component of the position of the top-left corner of the tag"""
939
940    top_right_x: int
941    """x component of the position of the top-right corner of the tag"""
942
943    top_right_y: int
944    """y component of the position of the top-right corner of the tag"""
945
946    bottom_left_x: int
947    """x component of the position of the bottom-left corner of the tag"""
948
949    bottom_left_y: int
950    """y component of the position of the bottom-left corner of the tag"""
951
952    bottom_right_x: int
953    """x component of the position of the bottom-right corner of the tag"""
954
955    bottom_right_y: int
956    """y component of the position of the bottom-right corner of the tag"""

The data associated with an AI Vision object detected by apriltag detection.

id: int

The detected AprilTag(s) ID number

top_left_x: int

x component of the position of the top-left corner of the tag

top_left_y: int

y component of the position of the top-left corner of the tag

top_right_x: int

x component of the position of the top-right corner of the tag

top_right_y: int

y component of the position of the top-right corner of the tag

bottom_left_x: int

x component of the position of the bottom-left corner of the tag

bottom_left_y: int

y component of the position of the bottom-left corner of the tag

bottom_right_x: int

x component of the position of the bottom-right corner of the tag

bottom_right_y: int

y component of the position of the bottom-right corner of the tag

class AiVisionModelObject:
959class AiVisionModelObject:
960    """The data associated with an AI Vision object detected by an onboard model."""
961
962    id: int
963    """ID of the detected object."""
964
965    position_x: int
966    """The x component of the position of the object."""
967
968    position_y: int
969    """The y component of the position of the object."""
970
971    width: int
972    """The width of the object."""
973
974    height: int
975    """The height of the object."""
976
977    confidence: int
978    """The confidence reported by the model."""
979
980    classification: str
981    """A string describing the specific onboard model used to detect this object."""

The data associated with an AI Vision object detected by an onboard model.

id: int

ID of the detected object.

position_x: int

The x component of the position of the object.

position_y: int

The y component of the position of the object.

width: int

The width of the object.

height: int

The height of the object.

confidence: int

The confidence reported by the model.

classification: str

A string describing the specific onboard model used to detect this object.

class AprilTagFamily:
984class AprilTagFamily:
985    """Possible april tag families to be detected by the `AiVisionSensor`."""
986
987    CIRCLE21H7: ClassVar["AprilTagFamily"]
988    """Circle21h7 family"""
989
990    TAG16H5: ClassVar["AprilTagFamily"]
991    """16h5 family"""
992
993    TAG36H11: ClassVar["AprilTagFamily"]
994    """36h11 family"""
995
996    TAG25H9: ClassVar["AprilTagFamily"]
997    """25h9 family"""

Possible april tag families to be detected by the AiVisionSensor.

CIRCLE21H7: ClassVar[AprilTagFamily] = <AprilTagFamily object>

Circle21h7 family

TAG16H5: ClassVar[AprilTagFamily] = <AprilTagFamily object>

16h5 family

TAG36H11: ClassVar[AprilTagFamily] = <AprilTagFamily object>

36h11 family

TAG25H9: ClassVar[AprilTagFamily] = <AprilTagFamily object>

25h9 family

class AiVisionSensor:
1006class AiVisionSensor:
1007    """An AI Vision sensor.
1008
1009    The AI Vision sensor is
1010    meant to be a direct upgrade from the Vision Sensor with a wider camera range
1011    and AI model capabilities.
1012
1013    # Hardware overview
1014
1015    The AI Vision sensor has three detection modes that can all be enabled at the same time:
1016    - [Color detection](AiVisionDetectionMode::COLOR)
1017    - [Custom model detection](AiVisionDetectionMode::MODEL)
1018    - [AprilTag detection](AiVisionDetectionMode::APRILTAG) (requires color detection to be enabled)
1019
1020    Currently there is no known way to upload custom models to the sensor and fields do not have
1021    AprilTags. However, there are built-in models that can be used for detection.
1022
1023    See [VEX's documentation](https://kb.vex.com/hc/en-us/articles/30326315023892-Using-AI-Classifications-with-the-AI-Vision-Sensor) for more information.
1024
1025    The resolution of the AI Vision sensor is 320x240 pixels. It has a horizontal FOV of 74 degrees
1026    and a vertical FOV of 63 degrees. Both of these values are a slight upgrade from the Vision
1027    Sensor.
1028
1029    Unlike the Vision Sensor, the AI Vision sensor uses more human-readable color signatures that
1030    may be created without the AI Vision utility, though uploading color signatures with VEX's AI
1031    Vision Utility over USB is still an option.
1032    """
1033
1034    MAX_OBJECTS: int = 24
1035    """Maximum number of objects that can be detected at once."""
1036
1037    HORIZONTAL_RESOLUTION: int = 320
1038    """The horizontal resolution of the AI Vision sensor."""
1039
1040    VERTICAL_RESOLUTION: int = 240
1041    """The vertical resolution of the AI Vision sensor."""
1042
1043    HORIZONTAL_FOV: float = 74.0
1044    """The horizontal FOV of the vision sensor in degrees."""
1045
1046    VERTICAL_FOV: float = 63.0
1047    """The vertical FOV of the vision sensor in degrees."""
1048
1049    DIAGONAL_FOV: float = 87.0
1050    """The diagonal FOV of the vision sensor in degrees."""
1051
1052    def temperature(self) -> float:
1053        """Returns the current temperature of the sensor in degrees Celsius."""
1054        ...
1055
1056    def set_color_code(self, id: int, code: AiVisionColorCode):
1057        """
1058        Registers a color code association on the sensor.
1059
1060        Color codes are effectively "groups" of color signatures. A color code associated multiple
1061        color signatures on the sensor will be detected as a single object when all signatures are
1062        seen next to each other.
1063
1064        Args:
1065
1066        - id: The ID of the color code to register. Must be in [1, 8].
1067        - code: The `AiVisionColorCode` to register.
1068        """
1069
1070    def color_code(self, id: int) -> Union[AiVisionColorCode, None]:
1071        """Returns the color code set on the AI Vision sensor with the given ID if it exists.
1072
1073        Args:
1074
1075        - id: The ID of the color code to retrieve. Must be in [1, 8].
1076
1077        Returns:
1078
1079        - The color code associated with the given ID if it exists, or None if no color code is set.
1080        """
1081        ...
1082
1083    def color_codes(self) -> List[Union[AiVisionColorCode, None]]:
1084        """Returns all color codes set on the AI Vision sensor as a list of 8 optional `AiVisionColorCode` objects."""
1085        ...
1086
1087    def set_color(self, id: int, color: AiVisionColor) -> AiVisionColor:
1088        """Sets a color signature for the AI Vision sensor.
1089
1090        Args:
1091
1092        - id: The ID of the color signature to register. Must be in [1, 7].
1093        - color: The `AiVisionColor` to register.
1094        """
1095        ...
1096
1097    def color(self, id: int) -> Union[AiVisionColor, None]:
1098        """Returns the color signature set on the AI Vision sensor with the given ID if it exists.
1099
1100        Args:
1101
1102        - id: The ID of the color signature to retrieve. Must be in [1, 7].
1103        """
1104        ...
1105
1106    def colors(self) -> List[Union[AiVisionColor, None]]:
1107        """Returns all color signatures set on the AI Vision sensor as a list of 7 optional `AiVisionColor` objects."""
1108        ...
1109
1110    def set_detection_mode(self, mode: AiVisionDetectionMode):
1111        """Sets the detection mode of the AI Vision sensor.
1112
1113        Args:
1114
1115        - mode: The new `AiVisionDetectionMode` to set.
1116        """
1117        ...
1118
1119    def flags(self) -> AiVisionFlags:
1120        """Returns the current flags of the AI Vision sensor including the detection mode flags set by `AiVisionSensor.set_detection_mode`."""
1121        ...
1122
1123    def set_flags(self, mode: AiVisionFlags):
1124        """Set the full flags of the AI Vision sensor, including the detection mode.
1125
1126        Args:
1127
1128        - mode: The new `AiVisionFlags` to set.
1129        """
1130        ...
1131
1132    def start_awb(self):
1133        """Restarts the automatic white balance process."""
1134        ...
1135
1136    def enable_test(self, test: int):
1137        """Unknown use.
1138
1139        Args:
1140
1141        - test: unknown purpose.
1142        """
1143        ...
1144
1145    def set_apriltag_family(self, family: AprilTagFamily):
1146        """Sets the AprilTag family that the sensor will try to detect.
1147
1148        Args:
1149
1150        - family: The `AprilTagFamily` for the sensor to try to detect.
1151        """
1152        ...
1153
1154    def object_count(self) -> int:
1155        """Returns the number of objects currently detected by the AI Vision sensor."""
1156        ...
1157
1158    def objects(
1159        self,
1160    ) -> List[
1161        Union[
1162            AiVisionColorObject,
1163            AiVisionCodeObject,
1164            AiVisionModelObject,
1165            AiVisionAprilTagObject,
1166        ]
1167    ]:
1168        """Returns all objects detected by the AI Vision sensor."""
1169        ...

An AI Vision sensor.

The AI Vision sensor is meant to be a direct upgrade from the Vision Sensor with a wider camera range and AI model capabilities.

Hardware overview

The AI Vision sensor has three detection modes that can all be enabled at the same time:

Currently there is no known way to upload custom models to the sensor and fields do not have AprilTags. However, there are built-in models that can be used for detection.

See VEX's documentation for more information.

The resolution of the AI Vision sensor is 320x240 pixels. It has a horizontal FOV of 74 degrees and a vertical FOV of 63 degrees. Both of these values are a slight upgrade from the Vision Sensor.

Unlike the Vision Sensor, the AI Vision sensor uses more human-readable color signatures that may be created without the AI Vision utility, though uploading color signatures with VEX's AI Vision Utility over USB is still an option.

MAX_OBJECTS: int = 24

Maximum number of objects that can be detected at once.

HORIZONTAL_RESOLUTION: int = 320

The horizontal resolution of the AI Vision sensor.

VERTICAL_RESOLUTION: int = 240

The vertical resolution of the AI Vision sensor.

HORIZONTAL_FOV: float = 74.0

The horizontal FOV of the vision sensor in degrees.

VERTICAL_FOV: float = 63.0

The vertical FOV of the vision sensor in degrees.

DIAGONAL_FOV: float = 87.0

The diagonal FOV of the vision sensor in degrees.

def temperature(self) -> float:
1052    def temperature(self) -> float:
1053        """Returns the current temperature of the sensor in degrees Celsius."""
1054        ...

Returns the current temperature of the sensor in degrees Celsius.

def set_color_code(self, id: int, code: AiVisionColorCode):
1056    def set_color_code(self, id: int, code: AiVisionColorCode):
1057        """
1058        Registers a color code association on the sensor.
1059
1060        Color codes are effectively "groups" of color signatures. A color code associated multiple
1061        color signatures on the sensor will be detected as a single object when all signatures are
1062        seen next to each other.
1063
1064        Args:
1065
1066        - id: The ID of the color code to register. Must be in [1, 8].
1067        - code: The `AiVisionColorCode` to register.
1068        """

Registers a color code association on the sensor.

Color codes are effectively "groups" of color signatures. A color code associated multiple color signatures on the sensor will be detected as a single object when all signatures are seen next to each other.

Args:

  • id: The ID of the color code to register. Must be in [1, 8].
  • code: The AiVisionColorCode to register.
def color_code(self, id: int) -> Optional[AiVisionColorCode]:
1070    def color_code(self, id: int) -> Union[AiVisionColorCode, None]:
1071        """Returns the color code set on the AI Vision sensor with the given ID if it exists.
1072
1073        Args:
1074
1075        - id: The ID of the color code to retrieve. Must be in [1, 8].
1076
1077        Returns:
1078
1079        - The color code associated with the given ID if it exists, or None if no color code is set.
1080        """
1081        ...

Returns the color code set on the AI Vision sensor with the given ID if it exists.

Args:

  • id: The ID of the color code to retrieve. Must be in [1, 8].

Returns:

  • The color code associated with the given ID if it exists, or None if no color code is set.
def color_codes(self) -> List[Optional[AiVisionColorCode]]:
1083    def color_codes(self) -> List[Union[AiVisionColorCode, None]]:
1084        """Returns all color codes set on the AI Vision sensor as a list of 8 optional `AiVisionColorCode` objects."""
1085        ...

Returns all color codes set on the AI Vision sensor as a list of 8 optional AiVisionColorCode objects.

def set_color(self, id: int, color: AiVisionColor) -> AiVisionColor:
1087    def set_color(self, id: int, color: AiVisionColor) -> AiVisionColor:
1088        """Sets a color signature for the AI Vision sensor.
1089
1090        Args:
1091
1092        - id: The ID of the color signature to register. Must be in [1, 7].
1093        - color: The `AiVisionColor` to register.
1094        """
1095        ...

Sets a color signature for the AI Vision sensor.

Args:

  • id: The ID of the color signature to register. Must be in [1, 7].
  • color: The AiVisionColor to register.
def color(self, id: int) -> Optional[AiVisionColor]:
1097    def color(self, id: int) -> Union[AiVisionColor, None]:
1098        """Returns the color signature set on the AI Vision sensor with the given ID if it exists.
1099
1100        Args:
1101
1102        - id: The ID of the color signature to retrieve. Must be in [1, 7].
1103        """
1104        ...

Returns the color signature set on the AI Vision sensor with the given ID if it exists.

Args:

  • id: The ID of the color signature to retrieve. Must be in [1, 7].
def colors(self) -> List[Optional[AiVisionColor]]:
1106    def colors(self) -> List[Union[AiVisionColor, None]]:
1107        """Returns all color signatures set on the AI Vision sensor as a list of 7 optional `AiVisionColor` objects."""
1108        ...

Returns all color signatures set on the AI Vision sensor as a list of 7 optional AiVisionColor objects.

def set_detection_mode(self, mode: AiVisionDetectionMode):
1110    def set_detection_mode(self, mode: AiVisionDetectionMode):
1111        """Sets the detection mode of the AI Vision sensor.
1112
1113        Args:
1114
1115        - mode: The new `AiVisionDetectionMode` to set.
1116        """
1117        ...

Sets the detection mode of the AI Vision sensor.

Args:

def flags(self) -> AiVisionFlags:
1119    def flags(self) -> AiVisionFlags:
1120        """Returns the current flags of the AI Vision sensor including the detection mode flags set by `AiVisionSensor.set_detection_mode`."""
1121        ...

Returns the current flags of the AI Vision sensor including the detection mode flags set by AiVisionSensor.set_detection_mode.

def set_flags(self, mode: AiVisionFlags):
1123    def set_flags(self, mode: AiVisionFlags):
1124        """Set the full flags of the AI Vision sensor, including the detection mode.
1125
1126        Args:
1127
1128        - mode: The new `AiVisionFlags` to set.
1129        """
1130        ...

Set the full flags of the AI Vision sensor, including the detection mode.

Args:

def start_awb(self):
1132    def start_awb(self):
1133        """Restarts the automatic white balance process."""
1134        ...

Restarts the automatic white balance process.

def enable_test(self, test: int):
1136    def enable_test(self, test: int):
1137        """Unknown use.
1138
1139        Args:
1140
1141        - test: unknown purpose.
1142        """
1143        ...

Unknown use.

Args:

  • test: unknown purpose.
def set_apriltag_family(self, family: AprilTagFamily):
1145    def set_apriltag_family(self, family: AprilTagFamily):
1146        """Sets the AprilTag family that the sensor will try to detect.
1147
1148        Args:
1149
1150        - family: The `AprilTagFamily` for the sensor to try to detect.
1151        """
1152        ...

Sets the AprilTag family that the sensor will try to detect.

Args:

def object_count(self) -> int:
1154    def object_count(self) -> int:
1155        """Returns the number of objects currently detected by the AI Vision sensor."""
1156        ...

Returns the number of objects currently detected by the AI Vision sensor.

def objects( self) -> List[Union[AiVisionColorObject, AiVisionCodeObject, AiVisionModelObject, AiVisionAprilTagObject]]:
1158    def objects(
1159        self,
1160    ) -> List[
1161        Union[
1162            AiVisionColorObject,
1163            AiVisionCodeObject,
1164            AiVisionModelObject,
1165            AiVisionAprilTagObject,
1166        ]
1167    ]:
1168        """Returns all objects detected by the AI Vision sensor."""
1169        ...

Returns all objects detected by the AI Vision sensor.

Home Learn API Discord GitHub