Gawkerbot

The robot that watches you. All the time. Never blinks. A bit of a creep really.






What is it?

Gawkerbot is a robot (well, sort of) with eyes that locks on to anyone within its field of vision. Eye movement is achieved using a CD drive mechanism and some simple 3D printed mechanical parts. The main components used for tracking are an ATmega microcontroller, two PIR motion sensors and two ultrasonic distance sensors, one mounted inside each eye.

How Does it Work?

Once placed on its intended spot on the wall, Gawkerbot needs to make an initial calibration run to get to know its surroundings. The ATmega stores the distance to the nearest obstacle or opposing wall for a number of fixed eye position. No one can be in the field of vision during calibration or it will mess up the baseline data. After calibration, when the motion sensor triggers, the eyes starts scanning each position until both distance sensors gets a closer reading than the baseline. Once the eyes has honed in on someone the two distance sensors—covering partially separate areas—allows for determining which direction the person moves next.

The distance sensors inside the eyes and a PIR sensor are sending data back to the microcontroller. The little dude is walking toward the right. He's currently in sector (B) and is detected by both distance sensors. Since the PIR sensor is detecting movement, the eyes will start turning once he enters the (R) sector.


Design and Build Process

The idea for this project came to me in a semi-conscious state some months ago when I was down with the flu. But unlike most fever dreams this one still made sense after I woke up. What was even better was that building it would required the use of a 3D printer, which I had been looking for an excuse to buy anyway.

3D Printer Acquired

Being from the paleolithic era I found it fitting that I should get the most ancient 3D printer I could find. That happened to be a refurbished Wanhao Duplicator i3, version 1. It's a Prusa clone that has generally gotten favorable reviews, except for it's reputation for occasionally catching on fire.
I went with a low-end printer since I didn't see any substantial features in the midrange ones that would justify the price tag. Well I suppose it comes down to how much you value convenience. Also I'd rather hold out for the day that Samsung starts making cheap DLP/SLA printers for the broad market. I like FDM technology for the fact that anyone can build a printer at home. That's pretty cool. But I really feel that FDM will go the way of the matrix printer eventually. Of course—once Samsung gets around to do 3D printers—I'll also have to wait until someone hacks the suicide chip on the $199 proprietary resin cartridge.

No more grinding stuff out of mammoth ivory for this Cro-Magnon.


Eye Movement

Initially I wanted to use Nitinol wire for turning the eyes. Nitnol in action, YouTube.
It would make for a completely silent movement, possibly instilling into an uninitiated observer a powerful sense of black magic being employed. But after doing some more research on Nitinol I could roughly guesstimate a 100% likelihood of the project spiraling out of control. Bigly.
The sane choice would be to just use either servos or stepper motors. Going through my junk drawer I found neither, but I did find a bag of scavenged CD drive mechanisms, which triggered a brain wave: Hook up one eye to the CD drive sled, add a connecting rod to a lever attached to the other eye and tack on a potentiometer for a makeshift servo mechanism.
Of course, just buying the right parts might have been easier but this way I'd get even more use out of the 3D printer when making the extra bits needed for the mechanics. Plus it gave me a rationale for having held on to those moldy old CD drives for several years.

Deciding what to put the eyes inside of

The idea was to use a wall mounted mask of some kind since the assembly can't be moved after initial calibration. But I didn't really have a specific design in mind. I just knew I needed a dome with large circular holes for the eyeballs to fit through, and enough space inside to hide the mechanism. I briefly considered making a faux hunting trophy head but that would be problematic since game animals usually don't have forward-facing eyes. (Well bears do now come to think of it, so I guess that could have been an option.)
Anyways, after an hour of browsing Thingiverse I found an awesome reproduction of a late 19th century firefighters smoke mask. I instantly knew I had found what I didn't know I was looking for.
The 3D model was created by [Snorri]. The same guy also runs a business out of Belgium—Snorri Arms— that makes artisanal "custom airsoft guns, traps, accessories and more."  It appears they've tapped into an alternate timeline where vikings developed modern technology, which culminated in some bitchin' old-norse style firearms. Awesome stuff all of it!
Some sources speculate that the original smoke mask was an inspiration in the design of C-3PO... Makes one wonder who (or what) was the inspiration for Jar-Jar Binks? Well I guess some stones are best left unturned as they say.

3D Modeling

I had no experience with 3D modelling prior to this so it was slow going at first. I knew roughly what parts I needed to make but I didn't know what modeling software was right for the job. After some brief misadventures in Sketchup I became aware of the existence of OpenSCAD and parametric 3D design. I was somewhat surprised by how little effort was needed to churn out mechanical parts using that method. That being said I still needed to print most parts several times over to make everything fit together properly.

OpenSCAD model of eye to be printed in two parts. Compartment for motion sensor in the middle. 
The shaft axis has a channel through it for data wires and also for fitting a potentiometer dial shaft into. 




Eyes connected by a horizontal rod for transferring movement.
The vertical rod on the left eye attaches to the CD drive sled.

The thingy to mount the CD drive and eyes onto.


Printing

The print bed of the i3 came lined with painters tape that got shredded after a couple of prints. The tape was stuck to the bed with some awfully tough glue and I had to use half a can of WD-40 for scraping all that gunk off. I then put on a sheet of BuildTak which has lasted me ever since. Recently I took the glass pane out of an old scanner and cut it to fit the print bed. Once the BuildTak has worn out I'll see if I can get the i3 to print on that instead.
The prints for the project generally turned out fine. The one bump in the road was when I tried a different make of filament and got some underextrusion. I might get better results with it at a higher extruder temperature. Will try that some time.
All parts where printed using PLA filament.

Mechanics Test Run

The moving parts of Gawkerbot after assembly.


I used an H-bridge motor controller IC for running the motor, with a PWM output on the ATmega controlling the voltage. I was a bit worried that I would put too much stress on the CD drive mechanism by piling on friction load from the mechanics and potentiometer dial. Testing didn't reveal any immediate issues of stalling or gear grinding. I'm not sure what voltage the drive was designed for but I played it safe and capped the voltage across the motor to about 1.5V.

Printing the Mask

The mask printed in nine pieces over the course of several days. After gluing them together I applied a layer of wood putty to hide the seams and to cover up some pretty severe under extrusion on part of the print. I never took the time to sand the mask smooth, but after I spray painted it, that turned out to be a nice effect since it somewhat gives the impression of a rough cast-iron surface.

This print turned out less than perfect. Saved it from the trashcan with some putty.


Glowing Eyes

Towards the end of the build process I realized that I wanted the eyes to light up once they have focused in on a target. For that purpose I hotglued some bright blue LEDs to the inside of the mask. The effect would have been more impressive if I could've made the eyeballs light up from within. But at that point the build had already been lengthier than expected so I took the easy way out here. Also I think green LEDs would have looked cooler but I didn't have any bright ones laying around.

LEDs for eye illumination. The springs on the bottom left connects with metal plates on the back board to complete the circuit.

Afterthoughts

As to be expected, a few things didn't turn out as planned once put to practice. These are the main stumbling blocks I ran into during testing, and the solutions I came up with:

Distance Sensor Accuracy

The type of distance sensor I used has a range of about 6 meters under ideal conditions. However it performs considerably worse against soft and lumpy objects, which includes fully clothed humans. I was aware of this going in but it turned out to be a bit worse than I expected. The sensors worked reliably up to about 1.5 meters but beyond that the readings became increasingly hit and miss. 
I had to spend a fair bit of time compensating for that in software. I used a combination of multiple readings, heuristics and generally having the ATmega do some guesswork on what's going on. It was also necessary to find a balance between having quick reaction to movement, and preventing the eyes from constantly jittering about due to inconsistent sensor input. 
In the end Gawkerbot managed to do the right thing more often than not, up to a range of 4 meters. That was fine since that's the width of the room I wanted to put it in.

Gawkerbot Squints

Initial testing revealed that the left and right detection sectors, where only one of the distance sensors would trigger, where too narrow. What slipped my mind while designing the eye was that the sensor compartment inside the eyeball would have needed to be skewed at a slight outward angle, with the business end of the sensor still protruding at the center of the eyeball. 
The process of printing new eyes, assembling and fitting sensors and cables inside all over again felt like too much of a chore. I decided to go with a quick fix and just replace the connecting rod between the eyes with a slightly shorter one. That fixed the technical problem. Sadly it also inflicted Gawkerbot with a bit of a squint.
Maybe I'll find the energy to fix this issue properly sometime in the future. But this solution works and the squint isn't super noticeable.
In the "before" picture the (B) sector is too wide which decreases accuracy when locking on to a target. (L) and (R) are to narrow. The eyes being a bit wonky in the "after" picture fixes the issue.

Extra Motion Sensor

At first I used a single motion sensor for helping Gawkerbot decide when to take action. Later in the build i added a second one, and arranged them to have partially separate fields of vision, each pointing 30° to the left and right. This way Gawkerbot will get a rough idea of where movement is coming from at times when the target is not in view by the distance sensors. A small fix that definitely improves performance.
If I ever get around to building a Gawkerbot 2.0 I might actually try relying more on using motion sensors. I would arrange several of them in a semicircle with little blinders in between. I would then only need a single distance sensor for fine adjustments. I might even get away with substituting it for a lower-end model, the type with separate transmitter and receiver, fitting one inside each eye. It would make for a much cheaper build as well as more straightforward code.
The big caveat is that the standard cheap PIR sensor used with Arduino and such triggers continuously for several seconds once it senses motion. That's undesirable for this application, so I would need to find some way to hack it's hardware to shorten the trigger period. If you happen know how—please let me know in the comments.

Final Assembly

Time to put everything together in its final form. I was going to mount the stuff on an old wooden cutting board that I had painted black the day before. I would lie if I said that I wasn't a tiny little bit fed up with the project at this point, so I was happy to finally have the goal line in sight.
But the good lord wanted to test me apparently. The wood had become badly warped because of the moisture from the paint. So I had to put it under a heavy weight for a few days, and then apply a fresh coat of paint. "Jobe, had you known about my trials you probably could've put your own situation into some well needed perspective," I mused to myself.
Second try went better. I had originally intended to solder the electronics permanently onto perf board. But it turned out both the prototype breadboard and eye mechanics fit snugly together inside the mask. I decided to honor the KISS principle and keep things the way they where. 
All in all I feel that Gawkerbot ended up with a pleasing exterior and that he—so to speak—ties the room together. With those big ping-pong ball eyes he looks a bit like a steampunk version of Bender from Futurama. The one thing I would have changed is to maybe have the mouth hatch painted in a different color. As it is now there's a bit too much of the same copper coat all over. If that keeps bothering me it won't be too hard to fix later though.

Oh Gawkerbot, you're such a lovable wierdo.

I'm always amused and fascinated by devices that uses low tech solutions to achieve seemingly complex behavior. It was a fun experience to make one myself.

Electrical Components Used

2 x MaxBotix LV-MaxSonar-EZ4 ultrasonic distance sensors.
1 x potentiometer. (Used for determining eye direction.)
2 x no name PIR motion sensors.
1 x Atmel ATmega328p microcontroller.
1 x TI SN754410 quad H-bridge motor driver.
1 x 7-segment LED display. (Used for testing, debugging and calibration.)
2 x 2N7000 MOSFETs. (For eye illumination switch.)
2 x Li-Ion battery cells from an old laptop, connected in parallel.
1 x Battery charging/protection module.
1 x 5V boost regulator module.
2 x flip switches. One for power, one for switching between calibration and normal mode.
And also a few resistors, diodes, LEDs and capacitors.

Software

All code was written in C, using the standard toolchain with AVR-GCC and AVRdude. The core is essentially a big while loop with a bunch of polling and nested if statements. No hardware interrupts where used. As often is the case I kept building on top of what was initially intended to be throwaway test code for too long. Once things got to work properly I avoided trying to do any refactoring lest I should break something. Well the KISS principle says to "Keep It Stupid, Simple" right? So that's what I did. In total about 1000 lines of code.

Signing Out

This first blog entry ended up being a rather lengthy, rambling one. If you made it this far my hat is off to you, sir or ma'am.

Comments