johnny-five
Version:
The JavaScript Arduino Programming Framework.
498 lines (414 loc) • 13.5 kB
JavaScript
var five = require("../lib/johnny-five.js");
var keypress = require("keypress");
var board = new five.Board();
// Limb measurements
var coxa = 1.5;
var femur = 2.25;
var tibia = 4.5;
// Body measurements
var center = {
// 4 inches from coxa to coxa
y: 4,
// 3 inches from coxa to center of body
x: 3
};
// var props = [ "x", "y", "z" ];
// var limbs = {
// rf: {},
// rr: {},
// lf: {},
// lr: {}
// };
// Object.keys(limbs).forEach(function(limb) {
// limbs[limb] = props.reduce(function(accum, prop) {
// accum[prop] = 0;
// return accum;
// }, {});
// });
// console.log( limbs );
// Current positions
var RFx, RFy, RFz;
var RRx, RRy, RRz;
var LFx, LFy, LFz;
var LRx, LRy, LRz;
board.on("ready", function() {
var speed, commands, motors;
// // Right Front Servos (1)
// var RF0 = new five.Servo(8);
// var RF1 = new five.Servo(9);
// var RF2 = new five.Servo(10);
// // Right Rear Servos (2)
// var RR0 = new five.Servo(2);
// var RR1 = new five.Servo(3);
// var RR2 = new five.Servo(4);
// // Left Front Servos (3)
// var LF0 = new five.Servo(11);
// var LF1 = new five.Servo(12);
// var LF2 = new five.Servo(13);
// // Left Rear Servos (4)
// var LR0 = new five.Servo(5);
// var LR1 = new five.Servo(6);
// var LR2 = new five.Servo(7);
// counters
var j = 0;
var counter = 0;
function controller( ch, key ) {
if ( key ) {
// moves the robot body around in a circle
if (key.name === "a") {
around(1.5, 3);
}
// The following three functions are the basic creep gait walk functions. By varying the number of steps in shiftWalk(steps,time) you can control the speed of the grait
else if (key.name === "q") {
shiftWalk(50, 10);
} else if (key.name === "w") {
shiftWalk(25, 10);
} else if (key.name === "e") {
shiftWalk(13, 10);
}
// center the robot
else if (key.name === "c") {
fullMove(0, 0, 4);
}
// move the robot up and down using IK
else if (key.name === "u") {
up(3, 5);
}
// Rotate the robots body back and forth
else if (key.name === "l") {
rotate(25);
rotate(-50);
rotate(25);
} else if (key.name === "r") {
smoothMove(3, LFx, LFy, 4 - 2, 50, 10);
} else if (key.name === "t") {
smoothMove(1, RFx, RFy, RFz - 2, 50, 10);
} else if (key.name === "f") {
smoothMove(4, LRx, LRy, 4 - 2, 50, 10);
smoothMove(2, RRx, RRy, 4 - 2, 50, 10);
} else if (key.name === "g") {
smoothMove(2, RRx, RRy, 4 - 2, 50, 10);
} else if (key.name === "z") {
turn(25, 10);
}
}
}
keypress(process.stdin);
process.stdin.on("keypress", controller);
process.stdin.setRawMode(true);
process.stdin.resume();
});
// // This function rotates the robot body from the current
// // position to "degree" and then back.
// function rotate(degree) {
// var RFcur = RF0.position;
// var RRcur = RR0.position;
// var LFcur = LF0.position;
// var LRcur = LR0.position;
// Serial.println(RFcur);
// if (degree > 0) {
// for (var count1 = 0; count1 < degree; count1++) {
// RFcur += 1;
// RRcur += 1;
// LFcur += 1;
// LRcur += 1;
// RF0.write(RFcur);
// RR0.write(RRcur);
// LF0.write(LFcur);
// LR0.write(LRcur);
// delay(10);
// }
// } else {
// for (var count1 = 0; count1 > degree; count1--) {
// RFcur -= 1;
// RRcur -= 1;
// LFcur -= 1;
// LRcur -= 1;
// RF0.write(RFcur);
// RR0.write(RRcur);
// LF0.write(LFcur);
// LR0.write(LRcur);
// delay(10);
// }
// }
// }
// // Move a leg from current position to new position smoothly by using small angle chages broken up into "steps" every t1 milliseconds
// function smoothMove(servoNumber, x, y, z, t1, steps) {
// // RF
// if (servoNumber == 1) {
// // how big each step is
// var dx = (x - RFx) / steps;
// var dy = (y - RFy) / steps;
// var dz = (z - RFz) / steps;
// // moves the leg along each axis by the corresponding delta, waits t1 then repeats
// for (var i = 0; i <= steps; i++) {
// RFx += dx;
// RFy += dy;
// RFz += dz;
// moveServos2RF(RFx, RFy, RFz);
// delay(t1);
// }
// }
// // RR
// else if (servoNumber == 2) {
// var dx = (x - RRx) / steps;
// var dy = (y - RRy) / steps;
// var dz = (z - RRz) / steps;
// for (var i = 0; i <= steps; i++) {
// RRx += dx;
// RRy += dy;
// RRz += dz;
// moveServos2RR(RRx, RRy, RRz);
// delay(t1);
// }
// }
// // LF
// if (servoNumber == 3) {
// var dx = (x - LFx) / steps;
// var dy = (y - LFy) / steps;
// var dz = (z - LFz) / steps;
// for (var i = 0; i <= steps; i++) {
// LFx += dx;
// LFy += dy;
// LFz += dz;
// moveServos2LF(LFx, LFy, LFz);
// delay(t1);
// }
// }
// // LR
// else if (servoNumber == 4) {
// var dx = (x - LRx) / steps;
// var dy = (y - LRy) / steps;
// var dz = (z - LRz) / steps;
// for (var i = 0; i <= steps; i++) {
// LRx += dx;
// LRy += dy;
// LRz += dz;
// moveServos2LR(LRx, LRy, LRz);
// delay(t1);
// }
// } else if (servoNumber == 0) {
// }
// }
// // This is the primary creep gait that I've developed. It uses the smoothMove functions broken up into a number of "steps" with a delay "time" between each step
// function shiftWalk(steps, time) {
// // starting vertical position
// var z = 3;
// // How far to raise the leg for each movement
// var dz = -2;
// // shift entire body forward and to the left. This causes the robot to move forward 1 inch
// // and prepares for the left legs to move
// smoothFullMove(2, -1, z, 2, 1, z, steps * 2, time);
// print3(LRx, LRy, LRz);
// // Moves left back leg up then forward then down
// smoothMove(4, LRx, LRy, z + dz, steps, time); // moveServos2LR(3,5,1);
// smoothMove(4, 1, 5, z + dz, steps, time); // moveServos2LR(1,5,1);
// smoothMove(4, 1, 5, z, steps, time); // moveServos2LR(0,5,3);
// // Moves left front leg up then forward then down
// smoothMove(3, -1, 5, z + dz, steps, time); // moveServos2LF(-1,5,0);
// smoothMove(3, -3, 5, z + dz, steps, time); // moveServos2LF(-3,5,1);
// smoothMove(3, -3, 5, z, steps, time); // moveServos2LF(-3,5,3);
// // shift entire body forward and to the right. This causes the robot to move forward 1 inch
// // and prepares for the right legs to move
// smoothFullMove(2, 1, z, 2, -1, z, steps * 2, time);
// // Moves right back leg up then forward then down
// smoothMove(2, 3, 5, z + dz, steps, time); // moveServos2LR(3,5,1);
// smoothMove(2, 1, 5, z + dz, steps, time); // moveServos2LR(1,5,1);
// smoothMove(2, 1, 5, z, steps, time); // moveServos2LR(0,5,3);
// // Moves right front leg up then forward then down
// smoothMove(1, -1, 5, z + dz, steps, time); // moveServos2LF(-1,5,0);
// smoothMove(1, -3, 5, z + dz, steps, time); // moveServos2LF(-3,5,1);
// smoothMove(1, -3, 5, z, steps, time); // moveServos2LF(-3,5,3);
// }
// /*IK MOVE FUNCTIONS*/
// // moves the robot vertically from z1 to z2 and then back to z1
// function up(z1, z2) {
// var z = z1;
// while (z <= z2) {
// fullMove(0, 0, z);
// delay(25);
// z += .1;
// }
// while (z >= z1) {
// fullMove(0, 0, z);
// delay(25);
// z -= .1;
// }
// }
// // moves the robot in a circle of radius r and at a height z
// function around(r, z) {
// var x = 0;
// while (x <= 2 * 3.14) {
// fullMove(r * cos(x), r * sin(x), z);
// delay(50);
// x += .1;
// }
// }
// // Moves the entire robot body to position x,y,z. Note this results in very jerky movements
// function fullMove(x, y, z) {
// var rightY = center.y - y;
// var leftY = center.y + y;
// var frontX = x - center.x;
// var backX = x + center.x;
// RFx = x - center.x;
// RFy = center.y - y;
// RFz = z;
// RRx = x + center.x;
// RRy = center.y - y;
// RRz = z;
// LFx = x - center.x;
// LFy = center.y + y;
// LFz = z;
// LRx = x + center.x;
// LRy = center.y + y;
// LRz = z;
// moveServosRF(gamma(RFx, RFy, RFz), alpha(RFx, RFy, RFz), beta(RFx, RFy, RFz));
// moveServosRR(gamma(RRx, RRy, RRz), alpha(RRx, RRy, RRz), beta(RRx, RRy, RRz));
// moveServosLF(gamma(LFx, LFy, LFz), alpha(LFx, LFy, LFz), beta(LFx, LFy, LFz));
// moveServosLR(gamma(LRx, LRy, LRz), alpha(LRx, LRy, LRz), beta(LRx, LRy, LRz));
// }
// // Moves the entire body from x0,y0,z0 to x,y,z smoothly with "steps" steps separated by t1 milliseconds. This is usefully for shifting the center of gravity
// function smoothFullMove(x0, y0, z0, x, y, z, t1, steps) {
// var dx = (x - x0) / steps;
// var dy = (y - y0) / steps;
// var dz = (z - z0) / steps;
// for (var i = 0; i < steps; i++) {
// x0 += dx;
// y0 += dy;
// z0 += dz;
// fullMove(x0, y0, z0);
// delay(t1);
// }
// }
// // used for attaching the legs to the servos at the right position
// function calibrate() {
// RR0.write(90);
// RR1.write(0);
// RR2.write(90);
// RF0.write(90);
// RF1.write(0);
// RF2.write(90);
// LR0.write(90);
// LR1.write(0);
// LR2.write(90);
// LF0.write(90);
// LF1.write(0);
// LF2.write(90);
// }
// function calibrate2() {
// moveServosRF(90, 90, 90);
// moveServosRR(90, 90, 90);
// moveServosLF(90, 90, 90);
// moveServosLR(90, 90, 90);
// }
// /***INVERSE KINEMATICS***/
// // IK for gamma (coxa angle)
// function gamma(x, y, a) {
// var g = atan(x / y);
// return int(g * 57.3) + 90;
// }
// // IK for beta (femur angle)
// function beta(x, y, a) {
// var g = atan(x / y);
// x /= cos(g);
// // var bet =acos((pow(x,2)+pow(y,2)+pow(a,2)-pow(c,2)-pow(b,2))/(-2*c*b));
// var bet = acos((pow(a, 2) + pow(y - coxa, 2) - pow(tibia, 2) - pow(femur, 2)) / (-2 * femur * tibia));
// return int(bet * 57.3);
// }
// // IK for alpha (tibia angle)
// function alpha(x, y, a) {
// var g = atan(x / y);
// x /= cos(g);
// var L2 = sqrt(pow(a, 2) + pow(y - coxa, 2));
// var alp1 = atan((y - coxa) / a);
// var alp2 = acos((pow(tibia, 2) - pow(femur, 2) - pow(L2, 2)) / (-2 * femur * L2));
// var alp = alp1 + alp2;
// return int(alp * 57.3);
// }
// /**Move Functions**/
// // The following "moveServos2XX" move the tip of the corresponding
// // legs to the points x,y,z. This probably could have been combined
// // with the "moveServosXX" functions but were written after so
// // they simply call those functions.
// //
// function moveServos2RR(x, y, z) {
// //
// RRx = x;
// RRy = y;
// RRz = z;
// moveServosRR(gamma(RRx, RRy, RRz), alpha(RRx, RRy, RRz), beta(RRx, RRy, RRz));
// }
// function moveServos2RF(x, y, z) {
// RFx = x;
// RFy = y;
// RFz = z;
// moveServosRF(gamma(RFx, RFy, RFz), alpha(RFx, RFy, RFz), beta(RFx, RFy, RFz));
// }
// function moveServos2LR(x, y, z) {
// LRx = x;
// LRy = y;
// LRz = z;
// // Serial.print("alpha");
// // Serial.println(alpha(LRx,LRy,LRz));
// moveServosLR(gamma(LRx, LRy, LRz), alpha(LRx, LRy, LRz), beta(LRx, LRy, LRz));
// }
// function moveServos2LF(x, y, z) {
// LFx = x;
// LFy = y;
// LFz = z;
// moveServosLF(gamma(LFx, LFy, LFz), alpha(LFx, LFy, LFz), beta(LFx, LFy, LFz));
// }
// // The following "moveServosXX" functions move the servos in one leg to the given angles. gamma (g), alpha (a), and beta (b) as defined in the IK model
// function moveServosRR(g, a, b) {
// // The following calibrations were determined experimentally to get the angles to line up with the IK equations
// g = (g);
// a = (180 - a + 10);
// b = (b + 10);
// RR0.write(g);
// RR1.write(a);
// RR2.write(b);
// // if out of range
// if (g > 180 || g < 0 || a > 180 || a < 0 || b > 180 || b < 0)
// Serial.println("RR error");
// // print3(g,a,b);
// }
// // move the joints in the RF servo to angles g, a, and b
// function moveServosRF(g, a, b) {
// // The following calibrations were determined experimentally to get the angles to line up with the IK equations
// g = (g);
// a = (180 - a + 10);
// b = (b + 10);
// RF0.write(g);
// RF1.write(a);
// RF2.write(b);
// // if out of range
// if (g > 180 || g < 0 || a > 180 || a < 0 || b > 180 || b < 0)
// Serial.println("RF error");
// }
// // move the joints in the LR servo to angles g, a, and b
// function moveServosLR(g, a, b) {
// // The following calibrations were determined experimentally to get the angles to line up with the IK equations
// g = 180 - g - 10;
// a = 180 - a + 5;
// b = b + 5;
// LR0.write(g);
// LR1.write(a);
// LR2.write(b);
// // if out of range
// if (g > 180 || g < 0 || a > 180 || a < 0 || b > 180 || b < 0) {
// Serial.println("LR error");
// }
// }
// // move the joints in the LF servo to angles g, a, and b
// function moveServosLF(g, a, b) {
// // The following calibrations were determined experimentally to get the angles to line up with the IK equations
// g = 180 - g + 5;
// a = 180 - a - 7;
// b = b + 15;
// LF0.write(g);
// LF1.write(a);
// LF2.write(b);
// // if out of range
// if (g > 180 || g < 0 || a > 180 || a < 0 || b > 180 || b < 0)
// Serial.println("LF error");
// }