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() {
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.