Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Obstacle avoidance

Drives around and turns away from obstacles, using an ultrasonic sensor on input 4 pointing forward. This version is async: it runs on any runtime, here driven by block_on.

use nxt_rs::{blocking::block_on, prelude::*, turn_ratio};

async fn run() -> nxt_rs::Result<()> {
    let brick = Brick::usb_first().await?;
    let (left, right, sonar) = brick.take((B.motor(), C.motor(), S4.ultrasonic())).await?;
    let mut drive = SyncedPair::new(left, right);

    loop {
        match sonar.read().await? {
            Some(distance) if distance < Centimeters(30) => {
                // Back off a little, then spin away.
                drive.forward(power!(-40)).degrees(degrees!(180)).brake().wait().await?;
                drive.steer(power!(50), turn_ratio!(-100)).degrees(degrees!(250)).brake().wait().await?;
            }
            Some(distance) if distance < Centimeters(60) => {
                drive.forward(power!(40)).await?;   // slow down near obstacles
            }
            _ => drive.forward(power!(75)).await?,
        }
    }
}

fn main() -> nxt_rs::Result<()> {
    block_on(run())
}

Notes

  • None means nothing reflected the sound: the way is clear, or the obstacle is soft or angled. Soft objects such as curtains absorb sound.
  • forward(..) without .degrees returns immediately and keeps the motors running, so the loop polls the sensor while driving.
  • Sending the same forward command over and over is harmless.