Trailblazer Robotics
Unit 3 · Week 5

Distance, Color, Gyro

Three sensors that turn dumb motion into intelligent behavior.

You'll learn

Distance sensor

distance DistanceSensor = distance(PORT5);

double mm = DistanceSensor.objectDistance(mm);
if (mm < 150) {
  Brain.Screen.print("Object close: %.1f mm", mm);
}

Returns distance to the nearest object in millimeters. Good for wall-stop logic and lining up.

Optical / color sensor

optical EyeSensor = optical(PORT4);

EyeSensor.setLight(ledState::on);
color c = EyeSensor.color();
if (c == red)   Brain.Screen.print("Red");
if (c == green) Brain.Screen.print("Green");
if (c == blue)  Brain.Screen.print("Blue");

The optical sensor reports color and hue. Use it to detect game elements or line markings. Turn on the LED for consistent readings indoors.

Gyro / inertial sensor

inertial Gyro = inertial(PORT2);

int main() {
  Gyro.calibrate();
  while (Gyro.isCalibrating()) wait(50, msec);  // ~2 seconds, don't move the robot

  double heading = Gyro.heading(degrees);   // 0–360
  double rotation = Gyro.rotation(degrees); // unbounded
}

Heading stays between 0 and 360. Rotation can be 720 if you spun twice in a circle. Use rotation for PID turns because it's continuous, no jumps.

Sensors lie. The distance sensor returns garbage if it sees something shiny at a steep angle. The optical sensor reads "noise" if the LED is off. The gyro drifts a tiny bit each second. Always sanity-check: if a reading is impossible (negative distance, heading of 9999), throw it away.

Debouncing

Sensors flicker. If you check "is bumper pressed?" thousands of times a second, you might catch a single fluke reading. Wait a few ms or require two readings in a row before acting.

// Wait until bumper has been pressed for at least 50ms in a row
while (true) {
  if (FrontBumper.pressing()) {
    wait(50, msec);
    if (FrontBumper.pressing()) break;
  }
  wait(10, msec);
}

Curated references

Find the Bug

Two programs with intentional errors. Spot the bug.

Problem 5A
This program reads the gyro right after the brain turns on. The heading is always wildly off. Why?
int main() {
  inertial Gyro = inertial(PORT2);
  Gyro.calibrate();

  double heading = Gyro.heading(degrees);
  Brain.Screen.print("heading: %.1f", heading);
}
Problem 5B
This program is supposed to print "RED" when the optical sensor sees red. Instead it always prints "RED", even when the sensor sees nothing. Why?
optical EyeSensor = optical(PORT4);

if (EyeSensor.color() = red) {
  Brain.Screen.print("RED");
}
← Week 4 Next: Encoders →