Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

175 lines (133 sloc) 3.737 kb

Sonar - Scanner

Run with:

node eg/sonar-scan.js
var five = require("johnny-five"),
  board;

board = new five.Board();

board.on("ready", function() {
  var center, collision, degrees, step, facing,
    range, redirect, look, isScanning, scanner, sonar, servos;

  // Collision distance (inches)
  collision = 6;

  // Starting scanner scanning position (degrees)
  degrees = 90;

  // Servo scanning steps (degrees)
  step = 10;

  // Current facing direction
  facing = "";

  // Scanning range (degrees)
  range = [0, 170];

  // Servo center point (degrees)
  center = range[1] / 2;

  // Redirection map
  redirect = {
    left: "right",
    right: "left"
  };

  // Direction to look after releasing scanner lock (degrees)
  look = {
    forward: center,
    left: 130,
    right: 40
  };

  // Scanning state
  isScanning = true;

  // Sonar instance (distance detection)
  sonar = new five.Sonar("A2");
  // Servo instance (panning)
  scanner = new five.Servo({
    pin: 12,
    range: range
  });

  servos = {
    right: new five.Servo({
      pin: 10,
      type: "continuous"
    }),
    left: new five.Servo({
      pin: 11,
      type: "continuous"
    })
  };

  // Initialize the scanner at it's center point
  // Will be exactly half way between the range's
  // lower and upper bound
  scanner.center();

  servos.right.to(90);
  servos.left.to(90);

  // Scanner/Panning loop
  this.loop(100, function() {
    var bounds;

    bounds = {
      left: center + 10,
      right: center - 10
    };

    // During course change, scanning is paused to avoid
    // overeager redirect instructions[1]
    if (isScanning) {
      // Calculate the next step position
      if (degrees >= scanner.range[1] || degrees === scanner.range[0]) {
        step *= -1;
      }

      // Update the position in degrees
      degrees += step;

      // The following three conditions will help determine
      // which way the bot should turn if a potential collision
      // may occur in the sonar "change" event handler[2]
      if (degrees > bounds.left) {
        facing = "left";
      }

      if (degrees < bounds.right) {
        facing = "right";
      }

      if (degrees > bounds.right && degrees < bounds.left) {
        facing = "forward";
      }

      scanner.to(degrees);
    }
  });

  // [2] Sonar "change" events are emitted when the value of a
  // distance reading has changed since the previous reading
  //
  sonar.on("change", function(err) {
    var turnTo;

    // Detect collision
    if (Math.abs(this.inches) < collision && isScanning) {
      // Scanning lock will prevent multiple collision detections
      // of the same obstacle
      isScanning = false;
      turnTo = redirect[facing] || Object.keys(redirect)[Date.now() % 2];

      // Log collision detection to REPL
      console.log(
        [Date.now(),
          "Collision detected " + this.inches + " inches away.",
          "Turning " + turnTo.toUpperCase() + " to avoid"
        ].join("\n")
      );

      // Override the next scan position (degrees)
      // degrees = look[ turnTo ];

      // [1] Allow 1000ms to pass and release the scanning lock
      // by setting isScanning state to true.
      board.wait(1500, function() {
        console.log("Release Scanner Lock");
        isScanning = true;
      });
    }
  });
});


// Reference
//
// http://www.maxbotix.com/pictures/articles/012_Diagram_690X480.jpg

License

Copyright (c) 2012, 2013, 2014 Rick Waldron waldron.rick@gmail.com Licensed under the MIT license. Copyright (c) 2014, 2015 The Johnny-Five Contributors Licensed under the MIT license.

Jump to Line
Something went wrong with that request. Please try again.