Vision#

Introduction#

The VEX AIR Drone’s Vision Sensor detects and tracks AprilTag IDs. This allows the drone to analyze its surroundings, follow objects, and react based on detected visual data. Below is a list of all available methods and properties:

Getters – Detect if the drone is holding an object.

  • get_data – Returns a tuple of detected objects for a specific signature.

Properties – Object data returned from get_data.

  • exists – Whether the object exists in the current detection.

  • width – Width of the detected object.

  • height – Height of the detected object.

  • centerX – X position of the object’s center.

  • centerY – Y position of the object’s center.

  • bearing – Angle of the object relative to the front Vision Sensor or the degrees needed for the drone to face the object.

  • rotation – Orientation of the object.

  • originX – X position of the object’s top-left corner.

  • originY – Y position of the object’s top-left corner.

  • id – Tag ID of the object.

  • type – Returns the object’s type.

Getters#

get_data#

get_data filters data from the Vision Sensor frame to a single signature — a saved description of something the sensor can recognize, such as an AprilTag ID — and returns a tuple.

The tuple stores objects ordered from largest to smallest by width, starting at index 0. Each object’s properties can be accessed using its index. An empty tuple is returned if no matching objects are detected.

Usage:
drone.vision.get_data(camera, signature, count)

Parameters

Description

camera

The camera to retrieve data from: either the DOWNWARD_CAMERA or the FORWARD_CAMERA.

signature

Filters the dataset to only include data of the given signature. Available signatures are:

  • ALL_TAGS - All AprilTag IDs
  • TAG0 through TAG37 - A single AprilTag ID from 0 to 37

count

Optional. Sets the maximum number of objects that can be returned from 1 to 24 (default: 8).

# Climb upward when an AprilTag ID is detected
drone.take_off(climb_to=500)
while True:
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        drone.climb_for(direction=UP, distance=200)

Properties#

There are multiple properties that are included with each object stored in a tuple after get_data is used.

All property values except .id and .type describe the detected object’s position, size, orientation, or bearing at the moment get_data was used. These values are measured in pixels or degrees. Each Vision Sensor has a different resolution:

  • Forward-facing: 640 x 480 pixels

  • Downward-facing: 640 x 400 pixels

.exists#

.exists returns a Boolean value indicating whether the index exists in the tuple. Returns an error if there are no detected objects.

  • True – The index exists.

  • False – The index does not exist.

# Climb upward when an AprilTag ID is detected
drone.take_off(climb_to=500)
while True:
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        drone.climb_for(direction=UP, distance=200)

.width#

.width returns the width of the detected object in pixels as an integer from 1 to 640.

# Show if the AprilTag ID appears large or small
while True:
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    clear_console()
    if vision_data[0].exists:
        if vision_data[0].width > 100:
            print("Large")
        else:
            print("Small")
    wait(0.2, SECONDS)

.height#

.height returns the height of the detected object in pixels as an integer from 1 to 480.

# Show if the AprilTag ID appears large or small
while True:
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    clear_console()
    if vision_data[0].exists:
        if vision_data[0].height > 100:
            print("Large")
        else:
            print("Small")
    wait(0.2, SECONDS)

.centerX#

.centerX returns the x-coordinate of the center of the detected object in pixels as an integer from 1 to 640.

# Show if an AprilTag ID is to the left or the right of the camera
while True:
    clear_console()
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        if vision_data[0].centerX < 320:
            print("To the left!")
        else:
            print("To the right!")
    wait(0.2, SECONDS)

.centerY#

.centerY returns the y-coordinate of the center of the detected object in pixels as an integer from 1 to 480.

# Take off and align drone with AprilTag ID on wall
# Change drone.take_off parameter to see different results
drone.take_off(climb_to=800)
vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
if vision_data[0].exists:
    if vision_data[0].centerY < 240:
        print("Below the target!")
    else:
        print("Above the target!")
else:
    print("No target found!")

.bearing#

.bearing returns an angle indicating an object’s position relative to the drone. The behavior depends on which Vision Sensor is used.

A value of 0° indicates the center of the object and sensor are aligned. Positive values mean the object is to the right, while negative values mean the object is to the left.

Sensor

Returns

Downward

Degrees the front of the drone must turn to align with the center of the object, from –180º to 180º.

Forward

Degrees the object is offset to the left or right of the Vision Sensor’s center from –180º to 180º.

# Align the front of the drone to an AprilTag ID
drone.set_turn_velocity(15)
drone.take_off(climb_to=500)
while True:
    vision_data = drone.vision.get_data(DOWNWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        if -20 < vision_data[0].bearing < 20:
            # Hover once sensor is centered on AprilTag ID
            drone.hover()
            controller.sound.play(SUCCESS)
            while controller.sound.is_active():
                wait(50, MSEC)
        elif vision_data[0].bearing < -21:
            drone.turn(LEFT)
        else:
            drone.turn(RIGHT)
    wait(5, MSEC)

.rotation#

.rotation returns the orientation of the detected AprilTag ID as an integer in degrees from 1 to 359.

# Turn left or right based on the rotation of an AprilTag ID
drone.take_off(climb_to=1000)
while True:
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        if 240 < vision_data[0].rotation < 300:
            drone.turn_for(LEFT, 90)
        elif 60 < vision_data[0].rotation < 120:
            drone.turn_for(RIGHT, 90)
        else:
            drone.hover()
    wait(0.2, SECONDS)

.originX#

.originX returns the x-coordinate of the top-left corner of the detected object’s bounding box in pixels as an integer from 1 to 640.

# Draw lines to the AprilTag ID origin from all corners
while True:
    controller.screen.clear_screen()
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        controller.screen.draw_line(0, 0, vision_data[0].originX, vision_data[0].originY)
        controller.screen.draw_line(0, 480, vision_data[0].originX, vision_data[0].originY)
        controller.screen.draw_line(640, 0, vision_data[0].originX, vision_data[0].originY)
        controller.screen.draw_line(640, 480, vision_data[0].originX, vision_data[0].originY)
    wait(0.2, SECONDS)

.originY#

.originY returns the y-coordinate of the top-left corner of the detected object’s bounding box in pixels as an integer from 1 to 480.

# Draw lines to the AprilTag ID origin from all corners
while True:
    controller.screen.clear_screen()
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        controller.screen.draw_line(0, 0, vision_data[0].originX, vision_data[0].originY)
        controller.screen.draw_line(0, 480, vision_data[0].originX, vision_data[0].originY)
        controller.screen.draw_line(640, 0, vision_data[0].originX, vision_data[0].originY)
        controller.screen.draw_line(640, 480, vision_data[0].originX, vision_data[0].originY)
    wait(0.2, SECONDS)

.id#

.id returns the identification number of the detected AprilTag ID as an integer from 0 to 37.

# Display the detected AprilTag ID
while True:
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    clear_console()
    if vision_data[0].exists:
        print(vision_data[0].id)
    wait(0.2, SECONDS)

.type#

.type returns what type of object is detected. It will return the following:

Object Type

Numeric Value

Included Objects

drone.vision.TAG_OBJECT

8

AprilTag IDs

drone.vision.COLOR_OBJECT

1

Color signatures - Coming Soon!

drone.vision.CODE_OBJECT

2

Color codes - Coming Soon!

# Display what AprilTag ID is detected
while True:
    controller.screen.clear_screen()
    controller.screen.set_cursor(1, 1)
    vision_data = drone.vision.get_data(FORWARD_CAMERA, ALL_TAGS)
    if vision_data[0].exists:
        if vision_data[0].type == drone.vision.TAG_OBJECT:
            controller.screen.print("AprilTag ID: ")
            controller.screen.print(vision_data[0].id)

    wait(0.1, SECONDS)