Struct VisionSensor

Source
pub struct VisionSensor { /* private fields */ }
Expand description

VEX Vision Sensor

This struct represents a vision sensor plugged into a Smart Port.

Implementations§

Source§

impl VisionSensor

Source

pub const HORIZONTAL_RESOLUTION: u16 = 316u16

The horizontal resolution of the vision sensor.

This value is based on the VISION_FOV_WIDTH macro constant in PROS.

Source

pub const VERTICAL_RESOLUTION: u16 = 212u16

The vertical resolution of the vision sensor.

This value is based on the VISION_FOV_HEIGHT macro constant in PROS.

Source

pub const HORIZONTAL_FOV: f32 = 64.5999985f32

The horizontal FOV of the vision sensor in degrees.

Source

pub const VERTICAL_FOV: f32 = 46f32

The vertical FOV of the vision sensor in degrees.

Source

pub const DIAGONAL_FOV: f32 = 78f32

The diagonal FOV of the vision sensor in degrees.

Source

pub const UPDATE_INTERVAL: Duration

The update rate of the vision sensor.

Source

pub fn new(port: SmartPort) -> Self

Creates a new vision sensor from a Smart Port.

§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let sensor = VisionSensor::new(peripherals.port_1);
}
Source

pub fn set_signature( &mut self, id: u8, signature: VisionSignature, ) -> Result<(), VisionError>

Adds a detection signature to the sensor’s onboard memory.

This signature will be used to identify objects when using VisionSensor::objects.

The sensor can store up to 7 unique signatures, with each signature slot denoted by the id parameter. If a signature with an ID matching an existing signature on the sensor is added, then the existing signature will be overwritten with the new one.

§Volatile Memory

The memory on the Vision Sensor is volatile and will therefore be wiped when the sensor loses power. As a result, this function should be called every time the sensor is used on program start.

§Panics
  • Panics if the given signature ID is not in the interval [0, 7).
§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // These signatures can be generated using VEX's vision utility.
    let example_signature = VisionSignature::new(
        (10049, 11513, 10781),
        (-425, 1, -212),
        4.1,
    );

    // Set signature 1 one the sensor.
    _ = sensor.set_signature(1, example_signature);
}
Source

pub fn signature(&self, id: u8) -> Result<Option<VisionSignature>, VisionError>

Returns a signature from the sensor’s onboard volatile memory.

§Panics
  • Panics if the given signature ID is not in the interval [0, 7).
§Errors
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set an example signature in the sensor's first slot.
    _ = sensor.set_signature(1, VisionSignature::new(
        (10049, 11513, 10781),
        (-425, 1, -212),
        4.1,
    ));

    // Read signature 1 off the sensor.
    // This should be the same as the one we just set.
    if let Ok(Some(sig)) = sensor.signature(1) {
        println!("{:?}", sig);
    }
}
Source

pub fn signatures(&self) -> Result<[Option<VisionSignature>; 7], VisionError>

Returns all signatures currently stored on the sensor’s onboard volatile memory.

§Errors
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // A bunch of random color signatures.
    let sig_1 = VisionSignature::new((10049, 11513, 10781), (-425, 1, -212), 4.1);
    let sig_2 = VisionSignature::new((8973, 11143, 10058), (-2119, -1053, -1586), 5.4);
    let sig_3 = VisionSignature::new((-3665, -2917, -3292), (4135, 10193, 7164), 2.0);
    let sig_4 = VisionSignature::new((-5845, -4809, -5328), (-5495, -4151, -4822), 3.1);

    // Set signatures 1-4.
    _ = sensor.set_signature(1, sig_1);
    _ = sensor.set_signature(2, sig_2);
    _ = sensor.set_signature(3, sig_3);
    _ = sensor.set_signature(4, sig_4);

    // Read back the signatures from the sensor's memory.
    // These should be the signatures that we just set.
    if let Ok(signatures) = sensor.signatures() {
        for sig in signatures.into_iter().flatten() {
            println!("Found sig saved on sensor: {:?}", sig);
        }
    }
}
Source

pub fn add_code( &mut self, code: impl Into<VisionCode>, ) -> Result<(), VisionError>

Registers a color code to the sensor’s onboard memory. This code will be used to identify objects when using VisionSensor::objects.

Color codes are effectively “signature groups” that the sensor will use to identify objects containing the color of their signatures next to each other.

§Volatile Memory

The onboard memory of the Vision Sensor is volatile and will therefore be wiped when the sensor loses its power source. As a result, this function should be called every time the sensor is used on program start.

§Panics
  • Panics if one or more of the given signature IDs are not in the interval [0, 7).
§Errors
§Examples
use vexide::prelude::*;
use vexide::devices::smart::vision::DetectionSource;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Two color signatures.
    let sig_1 = VisionSignature::new((10049, 11513, 10781), (-425, 1, -212), 4.1);
    let sig_2 = VisionSignature::new((8973, 11143, 10058), (-2119, -1053, -1586), 5.4);

    // Store the signatures on the sensor.
    _ = sensor.set_signature(1, sig_1);
    _ = sensor.set_signature(2, sig_2);

    // Create a code assocating signatures 1 and 2 together.
    let code = VisionCode::from((1, 2));

    // Register our code on the sensor. When we call [`VisionSensor::objects`], the associated
    // signatures will be returned as a single object if their colors are detected next to each other.
    _ = sensor.add_code(code);

    // Scan for objects. Filter only objects matching the code we just set.
    if let Ok(objects) = sensor.objects() {
        for object in objects.iter().filter(|obj| obj.source == DetectionSource::Code(code)) {
            println!("{:?}", object);
        }
    }
}
Source

pub fn brightness(&self) -> Result<f64, VisionError>

Returns the current brightness setting of the vision sensor as a percentage.

The returned result should be from 0.0 (0%) to 1.0 (100%).

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set brightness to 50%
    _ = sensor.set_brightness(0.5);

    // Give the sensor time to update.
    sleep(VisionSensor::UPDATE_INTERVAL).await;

    // Read brightness. Should be 50%, since we just set it.
    if let Ok(brightness) = sensor.brightness() {
        assert_eq!(brightness, 0.5);
    }
}
Source

pub fn white_balance(&self) -> Result<WhiteBalance, VisionError>

Returns the current white balance of the vision sensor as an RGB color.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set white balance to manual.
    _ = sensor.set_white_balance(WhiteBalance::Manual(Rgb {
        r: 255,
        g: 255,
        b: 255,
    }));

    // Give the sensor time to update.
    sleep(VisionSensor::UPDATE_INTERVAL).await;

    // Read brightness. Should be 50%, since we just set it.
    if let Ok(white_balance) = sensor.white_balance() {
        assert_eq!(
            white_balance,
            WhiteBalance::Manual(Rgb {
                r: 255,
                g: 255,
                b: 255,
            })
        );
    }
}
Source

pub fn set_brightness(&mut self, brightness: f64) -> Result<(), VisionError>

Sets the brightness percentage of the vision sensor. Should be between 0.0 and 1.0.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set brightness to 50%
    _ = sensor.set_brightness(0.5);
}
Source

pub fn set_white_balance( &mut self, white_balance: WhiteBalance, ) -> Result<(), VisionError>

Sets the white balance of the vision sensor.

White balance can be either automatically set or manually set through an RGB color.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set white balance to manual.
    _ = sensor.set_white_balance(WhiteBalance::Manual(Rgb {
        r: 255,
        g: 255,
        b: 255,
    }));
}
Source

pub fn set_led_mode(&mut self, mode: LedMode) -> Result<(), VisionError>

Configure the behavior of the LED indicator on the sensor.

The default behavior is represented by LedMode::Auto, which will display the color of the most prominent detected object’s signature color. Alternatively, the LED can be configured to display a single RGB color.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set the LED to red at 100% brightness.
    _ = sensor.set_led_mode(LedMode::Manual(Rgb { r: 255, g: 0, b: 0 }, 1.0));
}
Source

pub fn led_mode(&self) -> Result<LedMode, VisionError>

Returns the user-set behavior of the LED indicator on the sensor.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set the LED to red at 100% brightness.
    _ = sensor.set_led_mode(LedMode::Manual(Rgb { r: 255, g: 0, b: 0 }, 1.0));

    // Give the sensor time to update.
    sleep(VisionSensor::UPDATE_INTERVAL).await;

    // Check the sensor's reported LED mode. Should be the same as what we just set
    if let Ok(led_mode) = sensor.led_mode() {
        assert_eq!(led_mode, LedMode::Manual(Rgb { r: 255, g: 0, b: 0 }, 1.0));
    }
}
Source

pub fn objects(&self) -> Result<Vec<VisionObject>, VisionError>

Returns a Vec of objects detected by the sensor.

§Errors
§Examples

With one signature:

use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set a color signature on the sensor's first slot.
    _ = sensor.set_signature(1, VisionSignature::new(
        (10049, 11513, 10781),
        (-425, 1, -212),
        4.1,
    ));

    // Scan for detected objects.
    if let Ok(objects) = sensor.objects() {
        for object in objects {
            println!("{:?}", object);
        }
    }
}

With multiple signatures:

use vexide::prelude::*;
use vexide::devices::smart::vision::DetectionSource;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Two color signatures.
    let sig_1 = VisionSignature::new((10049, 11513, 10781), (-425, 1, -212), 4.1);
    let sig_2 = VisionSignature::new((8973, 11143, 10058), (-2119, -1053, -1586), 5.4);

    // Store the signatures on the sensor.
    _ = sensor.set_signature(1, sig_1);
    _ = sensor.set_signature(2, sig_2);

    // Scan for objects.
    if let Ok(objects) = sensor.objects() {
        for object in objects {
            // Identify which signature the detected object matches.
            match object.source {
                DetectionSource::Signature(1) => println!("Detected object matching sig_1: {:?}", object),
                DetectionSource::Signature(2) => println!("Detected object matching sig_2: {:?}", object),
                _ => {},
            }
        }
    }
}
Source

pub fn object_count(&self) -> Result<usize, VisionError>

Returns the number of objects detected by the sensor.

§Errors
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Set a color signature on the sensor's first slot.
    _ = sensor.set_signature(1, VisionSignature::new(
        (10049, 11513, 10781),
        (-425, 1, -212),
        4.1,
    ));

    loop {
        if let Ok(n) = sensor.object_count() {
            println!("Sensor is currently detecting {n} objects.");
        }

        sleep(VisionSensor::UPDATE_INTERVAL).await;
    }
}
Source

pub fn set_mode(&mut self, mode: VisionMode) -> Result<(), VisionError>

Sets the vision sensor’s detection mode. See VisionMode for more information on what each mode does.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Place the sensor into "Wi-Fi mode", allowing you to connect to it via a hotspot
    // and recieve a video stream of its camera froma nother device.
    _ = sensor.set_mode(VisionMode::WiFi);
}
Source

pub fn mode(&self) -> Result<VisionMode, VisionError>

Returns the current detection mode that the sensor is using.

§Errors
  • A VisionError::Port error is returned if a vision sensor is not currently connected to the Smart Port.
§Examples
use vexide::prelude::*;

#[vexide::main]
async fn main(peripherals: Peripherals) {
    let mut sensor = VisionSensor::new(peripherals.port_1);

    // Place the sensor into "Wi-Fi mode", allowing you to connect to it via a hotspot
    // and recieve a video stream of its camera froma nother device.
    _ = sensor.set_mode(VisionMode::WiFi);

    sleep(VisionSensor::UPDATE_INTERVAL).await;

    // Since we just set the mode, we can get the mode off the sensor to verify that it's
    // now in Wi-Fi mode.
    if let Ok(mode) = sensor.mode() {
        assert_eq!(mode, VisionMode::WiFi);
    }
}

Trait Implementations§

Source§

impl Debug for VisionSensor

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<VisionSensor> for SmartPort

Source§

fn from(device: VisionSensor) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for VisionSensor

Source§

fn eq(&self, other: &VisionSensor) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

const fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl SmartDevice for VisionSensor

Source§

const UPDATE_INTERVAL: Duration

The frametime of the Vision Sensor.

Source§

fn port_number(&self) -> u8

Returns the port number of the SmartPort this device is registered on. Read more
Source§

fn device_type(&self) -> SmartDeviceType

Returns the variant of SmartDeviceType that this device is associated with. Read more
Source§

fn is_connected(&self) -> bool

Determine if this device type is currently connected to the SmartPort that it’s registered to. Read more
Source§

fn timestamp(&self) -> Result<SmartDeviceTimestamp, PortError>

Returns the timestamp recorded by this device’s internal clock. Read more
Source§

fn validate_port(&self) -> Result<(), PortError>

Verify that the device type is currently plugged into this port, returning an appropriate PortError if not available. Read more
Source§

impl Eq for VisionSensor

Source§

impl Send for VisionSensor

Source§

impl StructuralPartialEq for VisionSensor

Source§

impl Sync for VisionSensor

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.