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 based on a given signature.
Properties – Object data returned from get_data.
exists – Whether the object exists in the current detection as a Boolean.
width – Width of the detected object in pixels.
height – Height of the detected object in pixels.
centerX – X position of the object’s center in pixels.
centerY – Y position of the object’s center in pixels.
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 in degrees.
originX – X position of the object’s top-left corner in pixels.
originY – Y position of the object’s top-left corner in pixels.
id – Tag ID of the object.
type – Returns the object’s type.
Getters#
get_data#
get_data
filters the data from the Vision Sensor frame to return a tuple. The Vision Sensor can detect AprilTag IDs.
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 |
---|---|
|
The camera to retrieve data from:
|
|
What signature to get data of. Available signatures are:
|
|
Optional. Sets the maximum number of objects that can be returned from 1 to 24 (default: 8). |
# Climb upward when an AprilTag is detected
drone.take_off(starting_altitude=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.
Some property values are based off of the detected object’s position in the Vision Sensor’s view at the time that get_data
was used. Each Vision Sensor has a different resolution:
Forward-facing: 640 x 480 pixels
Downward-facing: 640 x 400 pixels
.exists#
.exists
returns if the index exists in the tuple or not. This property returns a Boolean value. Returns an error if there are no detected objects.
True
– The index exists.False
– The index does not exist.
# Climb upward when an AprilTag is detected
drone.take_off(starting_altitude=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 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(starting_altitude=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 as an integer in degrees from 1 to 359.
# Turn left or right based on the rotation of an AprilTag ID
drone.take_off(starting_altitude=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 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 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)