Books I Am Reading

This post is about the books I am reading right now, with short reviews.

Books

Zero to Maker: Learn (Just Enough) to make (Just About) Anything by David Lang

Something must be said about inspiration. This book is great at providing continuing inspiration in my quest for building with my hands. I am still reading this book, but I love it. The specific practical advice is not always realistic or applicable to anyone, but the back story is fantastic and I love reading how the author turned into maker so quickly and so successfully. Perhaps there is a path down the road of this hobby that offers something different.

Makers: The New Industrial Revolution by Chris Anderson

This book by the head editor of Wired magazine provides insightful and fascinating view point that we are at a brink of the new industrial revolution. If anything, this blog and my obsession is a living proof. Anderson believes that the current tools, costs and opportunity is immense for those interested in becoming inventors and entrepreneurs at the same time. He offers some convincing evidence, by artificially bringing to the market a new type of sprinkler, following his dad's footsteps decades ago. It's a thought provoking read and I highly recommend it.

Make: Electronics by Charles Platt

This is one of the best introductory books to electronics, and it takes time to get through. I am about 25% through, and I already learned so much about physics, electricity and electronics to be pretty dangerous, literally, in my office/workshop. I read enough to understand that a fuse may save me from a fire, and have since promptly purchased a buttload of 2A, 3A, 5A mini car fuses, which work great with big batteries.

Anyway, this book I highly recommend for the fundamentals.

Programming Arduino – Getting Started With Sketches, by Simon Monk

Very short, and very surface level coverage. I did not find this book overly useful, and finished it in a weekend.

Exploring Arduino – Tools and Techniques for Engineering Wizardry by Jeremy Blum

This is a fantastic book, very much in depth and with great examples. I am still reading it. Probably the best book on Arduino at the moment.

Arduino Cookbook, by Michael Margolis

This book was recommended to me at a meetup, and it's a thick heavy book. I must admit I only looked through the first third, and have not yet used the recipes in practice. But the breadth of coverage is impressive.

Making an Arduino Controlled Robot, by Michael Morgolis

This is another great book with lots of good examples, but all the code is filled with delay(). I'll discuss in later posts why this is terrible, and offer an alternative. I just started reading it, so standby for more details.

Programming the BeagleBone Black, by Simon Monk

This is a better "short" introduction than Arduino, and uses JavaScript (since BeagleBone now comes with Cloud9 + node.js). I read about a half, since I am not currently working on BeagleBone yet, I am waiting for another moment.

↳ Keep reading …

How It All Started

I've been a software engineer or technical leader for most of my career, which approaches on 20 years (I just recently hit 40 earlier this year). I started coding when I still lived in Kharkov, Ukraine, not too far from where the war is raging right now (a fact I am still finding hard to believe). I wrote my first program sometime in 1988, which was a keyboard driven version of "Paint": you could move a cursor that drew a line on your screen, and save and recall your creations. This was all before the mouse made it over there.

Just around my 40th birthday I wanted to fix a subwoofer that I intended to use for the birthday party that day. It was a Mackie powered subwoofer, about 500W (plenty loud), but it's been broken since the last Burning Man, when it quietly died in the 110'F heat. I opened it up, found some wires that seem inappropriately disconnected, and soldered loose ends to what I thought was the right receptacle with a crappy giveaway soldering iron I received at some Java conference more than a decade ago. I wasted two hours of my life aimlessly trying to "fix" the subwoofer, and while I was doing that a realization dawned on me: I have absolutely zero idea about how any of this electronics actually works... I did remember some facts about resistors and capacitors, but I surely couldn't tell what was what in front of me, how it all fit together, and more importantly: how was I going to fix this thing.

In the end I was not successful in my quest. I've assembled the subwoofer back to it's original form, and it's currently sitting in my garage waiting to be delivered someone with trained hands at JK Sound SF, someone who can actually fix it. But in the meantime, I signed up for a soldering class at the TechShop, and purchased a "pro" level soldering iron – Weller WES51 on Amazon. This is how it all began.

↳ Keep reading …

Back-Seat Driver: Autonomous Robot Maneuvering

BackSeat Driver: Autonomous Vehicle Library for Arduino

Today I am introducing the Back Seat Driver – a library for programming autonomous (or not) arduino based robots. Source Code on Github.

This library provides a convenient non-blocking command API to programmatically drive an autonomous vehicle. Current implementation is aimed at a 2-wheeled robot, with the two Servo motors setup opposite each other. Therefore to move the robot forward (or backward), two Servos need to rotate in the opposite direction (this is certainly true in the current version of the library, but may be more flexible in the future if need arises).

Library Features:

  • Intuitive and easy to read/use API
  • Non-blocking duration-based maneuvers, i.e. "go forward for half a second, then do this..."
  • Un-timed moves, such as "go backward" indefinitely
  • Turn by angle, computed based on the the wheel ratio coefficient that can be adjusted for each size of tire
  • Much more linear speed curve, when mapping from speed in % from 0 to 100, to Servo microseconds. Using arctan() function allows to flatten out uneven Servo speed response curve (see graph in the PDF for Parallax Arduino Robot Shield Kit).

Design Boundary

Imagine an autonomous robot, driving itself around, sensing and reacting to the environment around it. You can imagine yourself shouting robots command, as you see it approach a table: "Stop, turn left and see if it's any better". For any robot to be autonomous this logic must also be implemented in code. But the imagined scenario creates a clear boundary which separates an instructional algorithm that avoids obstacles and determines what the robot does next, from the robot movement library, which simply knows how to spin robot's wheels to achieve a move or a turn. This project, as you probably guessed, is about the latter part.

Non-Blocking Control

Nowhere in the library is the dreaded delay() function called (this is similar to ANSI/C sleep()), and so the program flow is never paused. . The client of the library is able to provide callback functions to be executed at the end of a given maneuver, such as a turn.

As a trade-off, the client is required to periodically call robot->isManeuvering() function, to ensure that all callbacks have a chance to execute and clear, and any maneuvers stopped. If this function is not called frequently enough, turns can go on for longer and thus be wildly inaccurate. This requires more coordination, but provides for a lot of options to execute logic while maneuvers are happening.

Neither does the library use any precious Arduino interrupts.

Hardware Requirements

For an example hardware see DIY kit called "Parallax Arduino Robot Shield" available here: http://www.parallax.com/product/323

Any Arduino card with 2 Servo motors attached would work. For most Servo motors that can move the vehicle you would need a decent power supply. The robot above uses 5 x 1.5V AA batteries for a total of 7.5V and about 1Amp. A dedicated motor shield such as Adafruit Motor Shield V2, would be an excellent choice, but there are many others.

Disclaimer and Invitation to Collaborate

This project is also an eternal learning quest for the author, who only started tinkering with Arduino at the end of June 2014. Therefore please keep in mind that this library is not written by an Arduino expert, although the author does have an extensive software development background in other languages.

Any suggestions or modifications are welcome, and will be considered, discussed and decided on in the issues or pull requests.

Usage

Moving Forward, Backward

The speed value passed into the APIs provided by the library are expected to be always positive, and expressed in percent % of the total max speed of the servos.

    // puts motors into 100% speed, forward motion,
    // and immediately return from the function
    robot.goForward(100);

or

   // go backwards @ 50% speed, for 1 second, and then call
   // turnAround() local function (defined elsewhere)
   robot.goBackward (50, 1000, &turnAround);

   ....

   // somewhere else in the code

   // wait for the any maneuvers to finish
   if (!robot.isManeuvering())  { ... }

Speed

Speed is always passed in a positive integer, from 0 to 100 (expressed in %).

Internal helper converts that to Servo's microseconds PWM timing. In addition we apply arctan() function to transform speed and provide more linear response between speed and RPMs, compared to when specifying microseconds directly.

Duration and Callbacks

Duratation based API calls, such as

// load specific Adapter for our motors
#include <BackSeatDriver_TwoServoAdapter.h>
// now load the main library
#include <BackSeatDriver.h>

// initialize the adapter with two pins assigned to
// the two servos
BackSeatDriver_TwoServoAdapter adapter(13, 12);
// intialize BackSeatDriver itself, passing it the driver.
BackSeatDriver robot(&adapter);
// now we can ask our robot to move...
robot.goForward(100); // move forward at 100% speed

is giving robot instructions that will stop the robot after the duration of time passes (defined in milliseconds from the start of the maneuver).

To remain within design goals of the library, the client should aim at not performing any blocking calls or delays itself, as doing so will make BackSeatDriver inaccurate, and will prohibit from effectively integrating other similar libraries. In the world where many things should be moving at once, nothing in the code path seems worthy of a dead pause of the delay, although for simple tasks it sure makes coding easy.

Example

In this example the client uses Sonar sensor to detect objects ahead. If an object is found, the robot turns left (-)45 degrees, and then immediately checks again for distance. If the distance to the objects ahead is farther than the previous reading, it stays on this route and keeps moving. Otherwise it rotates 90 degrees, to now be at +45 degrees to the original direction. If that direction isn't better than the front, it turns for additional 135 degrees, making it a full 180' degrees from the original direction.

This example algorithm is setup in a just a few lines of code using C/C++ style function pointers used as callbacks at the end of each maneuver, but provide for a pretty effective obstacle avoidance strategy (but albeit a random direction).

// Define the two pins used by the two Servos attached to the wheels (expected to be attached
// in an opposite direction to each other
// load specific Adapter for our motors
#include <BackSeatDriver_TwoServoAdapter.h>

// now load the main library
#include <BackSeatDriver.h>

// initialize the adapter with two pins assigned to the two servos
BackSeatDriver_TwoServoAdapter adapter(13, 12);

// intialize BackSeatDriver itself, passing it the driver.
BackSeatDriver robot(&adapter);

void setup()
{
    robot.attach();
}

void loop()
{
    // The most important check below serves two key purposes:
    //
    //   1. make sure that any existing maneuvering that may be happening should be
    //      finished, and if so stop the robot and execute maneuver's callbacks()
    //
    //   2. avoids doing any instructions until the robot is out of the maneuver.
    //      This could be optional, as many things can be done during the time
    //      robot is maneuvering, perhaps with other arms or sensors.
    //

    if (!bot.isManeuvering()) {

        // this is the default motion
        bot.goForward(100);

        // check distance to objects ahead
        spaceAhead = detectSpaceAhead();
        if (spaceAhead < 50) { // if under < 50cm start manuevering
            // turn left 45 degrees, and when done call the checkLeft() function.
            robot.turn(-45, &checkLeft);
        }
    }
}

void checkLeft() {
    int spaceAfterTurn = spaceAhead();
    if (spaceAfterTurn < spaceAhead)
        bot.turn(90, &checkRight);
}

void checkRight() {
    int spaceAfterTurn = spaceAhead();
    if (spaceAfterTurn < spaceAhead)
        bot.turn(135, NULL);
}

Conclusion

↳ Keep reading …

12-Step Program for Scaling Web Applications on PostgreSQL

On Tuesday night this week Wanelo hosted a monthly meeting of SFPUG - San Francisco PostgreSQL User Group, and I gave a talk that presented a summary to date of Wanelo's performance journey to today. The presentation ended upo being much longer than I originally anticipated, and went on for an hour and a half. Whoops! With over a dozen questions near the end, it felt good to share the tips and tricks that we learned while scaling our app.

↳ Keep reading …

Detangling Business Logic in Rails Apps with PORO Events and Observers

With any Rails app that evolves along with substantial user growth and active feature development, pretty soon a moment comes when there appears to be a decent amount of tangled logic, AKA "technical debt."

↳ Keep reading …

High Read/Write Performance PostgreSQL 9.2 and Joyent Cloud

At Wanelo we are pretty ardent fans of PostgreSQL database server, but try not to be dogmatic about it. 

I have personally used PostgreSQL since version 7.4, dating back to some time in 2003 or 4. I was always impressed with how easy it was to get PostgreSQL installed on a UNIX system, how quick it was to configure (only two config files to edit), and how simple it was to create and authenticate users.

↳ Keep reading …

The Case for Vertical Sharding

Wanelo's recent surge in popularity rewarded our engineers with a healthy stream of scaling problems to solve.

Among the many performance initiatives launched over the last few weeks, vertical sharding has been the most impactful and interesting so far.

↳ Keep reading …

The Big Switch How We Rebuilt Wanelo from Scratch and Lived to Tell About It

The Wanelo you see today is a completely different website than the one that existed a few months ago. It’s been rewritten and rebuilt from the ground up, as part of a process that took about two months. We thought we’d share the details of what we did and what we learned, in case someone out there ever finds themselves in a similar situation, weighing the risks of either working with a legacy stack or going full steam ahead with a rewrite.

↳ Keep reading …