Rick Waldron

@rwaldron

github.com/rwldrn

[ @nodebots, #nodebots ]




She said yes.



TEACHING NODEBOTS
HOW TO WALK

with JavaScript




Async Input

Sensors ➡ Serialport
Streams ➡ Events




Async Output

What and When,
Now and Later




Hardware

Intrinsically Synchronous




Sequences

n. A following of one thing after another;




delay()

Execution Blocking

Sequential Execution



#include <Servo.h>

// create servo object to control a servo
Servo servo;

void setup() {
  // attaches the servo on pin 9 to the servo object
  servo.attach(9);

  servo.write(135);
  delay(346);

  servo.write(0);
  delay(1036);

  servo.write(45);
  delay(690);

  servo.write(180);
  delay(1036);

  servo.write(90);
  delay(690);
}


function delay( ms ) {
  var start = Date.now();
  while ( Date.now() < start + ms ) {}
}

var servo = new five.Servo(9);

servo.move(135);
delay(346);

servo.move(0);
delay(1036);

servo.move(45);
delay(690);

servo.move(180);
delay(1036);

servo.move(90);
delay(690);

// 4144 ms of BLOCKED EXECUTION.



Blocking Execution






setTimeout


var servo = new five.Servo(9);

// Center the servo at 90°
servo.move(135);

setTimeout(function() {
  servo.move(0);

  setTimeout(function() {
    servo.move(45);

    setTimeout(function() {
      servo.move(180);

      setTimeout(function() {
        servo.move(90);

      }, 1036);
    }, 690);
  }, 1036);
}, 346);





No Thanks.

Doesn't scale

Not Composable



Timer

timer_wrap.cc

Close, but 2-25ms disparity



process.nextTick

Define a callback to execute in the next turn of the event loop.

Process Execution

{
  0: null,
  1: null,
  2: [ task, task ],
  3: null,
  4: [ task ],
  5: null,
  6: [ task, task ],
  7: null
}
 

Execution

Two Step, Repeating Sequence

// Hitec HS-422 [ 6.0V: 0.16 sec/60° (160ms to travel 60°) ]

#include <Servo.h>

// Create servo objects
Servo servo1;
Servo servo2;

int degree = 90;

void setup() {
  // Initialize two servos on pins 9 and 10
  servo1.attach(9);
  servo2.attach(10);
}

void loop() {

  degree = degree == 90 ? 180 : 90;

  servo1.write(degree);
  servo2.write(degree);

  delay(480);
}
var five = require("johnny-five"),
    // "sequence" is not a real package
    sequence = require("sequence");

five.Board().on("ready", function() {
  var servos, degree;

  // Initialize two servos on pins 9 and 10
  [ 9, 10 ].map( five.Servo );

  // Create a servo array
  servos = five.Servos();

  degree = 90;

  sequence.loop( 500, function() {
    servos.move(
      degree = degree === 90 ? 180 : 90
    );
  });
});




Never Blocking

Sequential Execution


The Queue Array Might Look Like This


  [
    { delay: 346,   task: [Function] },
    { delay: 1036,  task: [Function] },
    { delay: 690,   task: [Function] },
    { delay: 346,   task: [Function] },
    { delay: 1036,  task: [Function] },
    { delay: 690,   task: [Function] }
  ]



Linear Registry...




Walking

A sequence of motions...

github.com/rwldrn/johnny-five