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
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.
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.
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.
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.
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.
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.
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.
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.
The minimum data rate that you can set a rotation sensor to, in milliseconds.
The amount of unique sensor readings per one revolution of the sensor.
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:
- unit: The
RotationUnitto use for the return value.
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:
- unit: The
RotationUnitto use for the return value.
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
RotationUnitto use for the angle.
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.
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.FORWARDis 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.REVERSEis 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
Directionto set the sensor to.
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.
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.
The interval at which the Brain will send new packets to an AbstractMotor.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.FORWARDis 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.REVERSEis 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.
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.
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.
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
Gearsetto use for the motor.
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.
Inherited Members
- AbstractMotor
- WRITE_INTERVAL_MS
- set_voltage
- set_velocity
- brake
- set_position_target
- is_exp
- is_v5
- max_voltage
- velocity
- power
- torque
- voltage
- raw_position
- current
- efficiency
- current_limit
- voltage_limit
- temperature
- set_profiled_velocity
- reset_position
- set_current_limit
- set_voltage_limit
- is_over_temperature
- is_over_current
- is_driver_fault
- is_driver_over_current
- status
- faults
- motor_type
- position
- set_position
- set_direction
- direction
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.
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.
Inherited Members
- AbstractMotor
- WRITE_INTERVAL_MS
- set_voltage
- set_velocity
- brake
- set_position_target
- is_exp
- is_v5
- max_voltage
- velocity
- power
- torque
- voltage
- raw_position
- current
- efficiency
- current_limit
- voltage_limit
- temperature
- set_profiled_velocity
- reset_position
- set_current_limit
- set_voltage_limit
- is_over_temperature
- is_over_current
- is_driver_fault
- is_driver_over_current
- status
- faults
- motor_type
- position
- set_position
- set_direction
- direction
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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)
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)
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.
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)
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)
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.
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.
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.
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.
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.
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.
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:
- Color detection
- Custom model detection
- AprilTag detection (requires color detection to be enabled)
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.
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.
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
AiVisionColorCodeto register.
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.
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.
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
AiVisionColorto register.
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].
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.
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.
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:
- mode: The new
AiVisionFlagsto set.
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.
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:
- family: The
AprilTagFamilyfor the sensor to try to detect.
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.
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.