Struct Cube

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

The cube.

Provides API to control the cube. The API has two types:

  • High-level API
  • Low-level API

The high-level API provides easy-to-use basic feature to control the cube such as moving, turning on/off the light, and playing sound.

The low-level API provides the API for more fine-grained control and configuration. The API allows to send/receive all the raw protocol messages, which allows to use all the features of toio cube defined in the specification.

This is the example of the high-level API:

use std::time::Duration;
use toio::Cube;
use tokio::time::delay_for;

#[tokio::main]
async fn main() {
    // Search for the nearest cube.
    let mut cube = Cube::search().nearest().await.unwrap();

    // Connect.
    cube.connect().await.unwrap();

    // Print status.
    println!("version   : {}", cube.version().await.unwrap());
    println!("battery   : {}%", cube.battery().await.unwrap());
    println!("button    : {}", cube.button().await.unwrap());

    // Move forward.
    cube.go(10, 10, None).await.unwrap();

    delay_for(Duration::from_secs(3)).await;

    // Spin for 2 seconds.
    cube.go(100, 5, Some(Duration::from_secs(2))).await.unwrap();

    delay_for(Duration::from_secs(3)).await;
}

Implementations§

Source§

impl Cube

Source

pub fn search() -> Searcher

Returns Searcher instance to search for cubes.

To find the nearest cube,

use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();

    cube.connect().await.unwrap();
}

To find all cubes,

use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cubes = Cube::search().all().await.unwrap();

    for mut cube in cubes {
        cube.connect().await.unwrap();
    }
}

By default, the search timeout is 3 seconds. Use [Cube::search_timeout][] to set custom timeout.

Source

pub fn id(&self) -> &str

Gets the device id.

Source

pub fn rssi(&self) -> i32

Gets the signal strength.

Source

pub async fn version(&mut self) -> Result<String>

Gets the BLE protocol version.

Source

pub async fn battery(&mut self) -> Result<usize>

Gets the battery status.

Returns the percentage of the remaining battery.

Source

pub async fn collision(&mut self) -> Result<bool>

Gets the collision status.

Returns true if the cube is in collision.

Source

pub async fn slope(&mut self) -> Result<bool>

Gets the slope status.

Returns true if the cube slopes.

Source

pub async fn button(&mut self) -> Result<bool>

Gets the button status.

Returns true if the button is pressed.

Source

pub async fn position(&mut self) -> Result<Option<Position>>

Gets the position information.

Returns the position information which is read by the sensor. Returns None if no position information is available.

Source

pub async fn std_id(&mut self) -> Result<Option<StdId>>

Gets the standard id.

Returns the standard id which is read by the sensor. Returns None if no id is available.

Source

pub async fn go( &mut self, left: isize, right: isize, duration: Option<Duration>, ) -> Result<()>

Moves the cube.

left and right are the rotation speed of each wheel. The value must be in the range from -100 to 100. The negative number rotates backward, while the positive rotates forward. If specified, the wheels rotate for the given duration. If the duration is None, wheels rotate forever. The duration must be in the range from 1 to 2559 milliseconds.

use std::time::Duration;
use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Move forward.
    cube.go(10, 10, None).await.unwrap();

    // Move backward.
    cube.go(-10, -10, None).await.unwrap();

    // Spin counterclockwise.
    cube.go(5, 50, None).await.unwrap();

    // Spin clockwise for 1 second.
    cube.go(50, 5, Some(Duration::from_secs(1))).await.unwrap();
}
Source

pub async fn stop(&mut self) -> Result<()>

Stops the cube.

Both wheels stop rotating.

use std::time::Duration;
use tokio::time::delay_for;
use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Move forward.
    cube.go(10, 10, None).await.unwrap();

    delay_for(Duration::from_secs(3)).await;

    // Stop the cube.
    cube.stop().await.unwrap();
}
Source

pub async fn play_preset(&mut self, id: SoundPresetId) -> Result<()>

Plays sound preset.

use toio::{Cube, SoundPresetId};

#[tokio::main]
async fn main() {
    let mut cube = toio::Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    cube.play_preset(SoundPresetId::Enter).await.unwrap();
}
Source

pub async fn play(&mut self, repeat: usize, ops: Vec<SoundOp>) -> Result<()>

Plays sound.

Play sound in accordance with the list of sound operations. The number of sound operations must be less than 60. The duration for each sound must be in the range from 1 to 2559 milliseconds. The repeat count must be less than 256.

use std::time::Duration;
use toio::{Cube, SoundOp, Note};

#[tokio::main]
async fn main() {
    let mut cube = toio::Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    cube.play(
        // Repeats three times.
        3,
        // Plays two sound for 500 milliseconds for each.
        vec![
            SoundOp::new(Note::C5, Duration::from_millis(500)),
            SoundOp::new(Note::A6, Duration::from_millis(500)),
        ],
    ).await.unwrap();
}
Source

pub async fn stop_sound(&mut self) -> Result<()>

Stops playing sound.

use std::time::Duration;
use tokio::time::delay_for;
use toio::{Cube, SoundOp, Note};

#[tokio::main]
async fn main() {
    let mut cube = toio::Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Starts playing sound.
    cube.play(1, vec![SoundOp::new(Note::C5, Duration::from_secs(2))]).await.unwrap();

    delay_for(Duration::from_secs(1)).await;

    // Stops the sound.
    cube.stop_sound().await.unwrap();
}
Source

pub async fn light(&mut self, repeat: usize, ops: Vec<LightOp>) -> Result<()>

Turns on the light as programmed.

The light color is set by RGB value, each of which must be in range 0 to 255. The number of light operations must be less than 30. The repeat count must be less than 256. The duration of each light operation must be less than 2560 milliseconds.

use std::time::Duration;
use toio::{Cube, LightOp};

#[tokio::main]
async fn main() {
    let mut cube = toio::Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    cube.light(
        // Repeats 10 times.
        10,
        // Turns on the red, green, blue light for 100 milliseconds for each.
        vec![
            LightOp::new(255, 0, 0, Some(Duration::from_millis(100))),
            LightOp::new(0, 255, 0, Some(Duration::from_millis(100))),
            LightOp::new(0, 0, 255, Some(Duration::from_millis(100))),
        ],
    ).await.unwrap();
}
Source

pub async fn light_on( &mut self, red: u8, green: u8, blue: u8, duration: Option<Duration>, ) -> Result<()>

Turns on the light.

The light color is set by RGB value, each of which must be in range 0 to 255. The duration must be less than 2560 milliseconds.

use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cube = toio::Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Turns on the green light.
    cube.light_on(0, 255, 0, None).await.unwrap();
}
Source

pub async fn light_off(&mut self) -> Result<()>

Turns off the light.

use std::time::Duration;
use tokio::time::delay_for;
use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cube = toio::Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Turns on the light.
    cube.light_on(255, 255, 255, None).await.unwrap();

    delay_for(Duration::from_secs(3)).await;

    // Turns off the light.
    cube.light_off().await.unwrap();
}
Source

pub async fn connect(&mut self) -> Result<()>

Connects to the cube.

This must be called first before operating on the cube.

use toio::Cube;

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();

    // Connects to the cube.
    cube.connect().await.unwrap();
}
Source

pub async fn events(&mut self) -> Result<EventStream>

Subscribes to events.

use futures::prelude::*;
use toio::{Cube, Event};

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    let mut events = cube.events().await.unwrap();
    while let Some(event) = events.next().await {
        match event {
            Event::Collision(collided) => println!("collided: {}", collided),
            Event::Battery(remain) => println!("battery: {}%", remain),
            _ => {},
        }
    }
}
Source

pub async fn write_msg(&mut self, msg: Message, with_resp: bool) -> Result<()>

Writes a raw message to the device.

This is the low-level API that allows to directly write the protocol data structures defined in proto to the cube device. Some data triggers events which can be retrieved by Cube::raw_msgs or Cube::events.

use toio::{Cube, proto::*};

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Move forward.
    cube.write_msg(
        Message::Motor(Motor::Simple(MotorSimple::new(
            MotorId::Left,
            MotorDir::Forward,
            30,
            MotorId::Right,
            MotorDir::Forward,
            30,
        ))),
        false,
    ).await.unwrap();
}
Source

pub async fn read_msg(&mut self, uuid: &Uuid) -> Result<()>

Sends a read request to the device.

This is the low-level API to request to read values in the device. This usually triggers events which can be retrieved by Cube::raw_msgs or Cube::events.

use futures::prelude::*;
use toio::{Cube, proto::*};

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Subscribe to raw messages.
    let mut msgs = cube.raw_msgs().await.unwrap();

    // Send a read request for motor state to the cube.
    cube.read_msg(&UUID_MOTION).await.unwrap();

    // Receive the motor state, which is sent as response to the read request.
    while let Some(msg) = msgs.next().await {
        match msg {
            Message::Motion(Motion::Detect(d)) => {
                println!("{:?}", d);
                break;
            }
            _ => {}
        }
    }
}
Source

pub async fn raw_msgs(&mut self) -> Result<BoxStream<'static, Message>>

Subscribe to raw messages.

This is the low-level API to subscribe to raw protocol messages from the cube device.

use futures::prelude::*;
use toio::{Cube, proto::*};

#[tokio::main]
async fn main() {
    let mut cube = Cube::search().nearest().await.unwrap();
    cube.connect().await.unwrap();

    // Subscribe to raw messages.
    let mut msgs = cube.raw_msgs().await.unwrap();

    // Receive raw messages.
    while let Some(msg) = msgs.next().await {
        match msg {
            Message::Motion(Motion::Detect(d)) => {
            }
            _ => {}
        }
    }
}

Trait Implementations§

Source§

impl Debug for Cube

Source§

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

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

impl Drop for Cube

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl Freeze for Cube

§

impl !RefUnwindSafe for Cube

§

impl Send for Cube

§

impl !Sync for Cube

§

impl Unpin for Cube

§

impl !UnwindSafe for Cube

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.