Monday, February 16, 2015

Empirically testing the "three hats game"

After reading the brain teaser here, I couldn't convince myself that the solution was correct:
http://www.futilitycloset.com/2015/02/17/the-three-hats-game/
It still seems impossible to me that any player should be able to do better than 50% at guessing the color of his own hat. So I wrote a C program to try out the strategy across 10000 games and report what it found. And indeed it does seem to work. I'd paste the code, but blogger sucks at code formatting. So here it is instead:
https://gist.github.com/anonymous/b3e0a653097e61bec498

Friday, February 06, 2015

Ubuntu: use syndaemon disable touchpad while typing

As this page describes, syndaemon solves the problem of trying to type on a laptop and having the cursor jump somewhere else because it thinks you touched the touchpad:

http://www.webupd8.org/2009/11/ubuntu-automatically-disable-touchpad.html

Wednesday, January 28, 2015

Intuition for Young's Modulus

Today I was trying to remember how to use Young's Modulus.  I eventually figured it out (I think), but when I went to check my intuition, nobody else was describing it in these terms.  So it's odd that this wouldn't be a well-known intuitive aid, which I guess means I might just be wrong about it.  If so, please point that out in the comments.

But the mental shortcut is this: Young's Modulus (aka the Elastic Modulus) tells us how much pressure we have to apply to a material to double its length.

For example: Aluminum has a modulus of elasticity of 10 million PSI.  So if you had a piece of aluminum bar stock 1 inch square, and you pulled on it with a force of 10 million pounds, it'd end up twice as long as it started.  

Now, in reality the bar would tear before it'd stretch that far, because the maximum elongation for aluminum tends to be less than 30%.  But remembering that "E = pressure required to double the length" gets you into the right place to use the units correctly (for example, to say that 1% of 10 million PSI would elongate our bar by 1%).

Friday, January 23, 2015

Paperclip Maximizer 1.0

The AI does not hate you, nor does it love you, but you are made out of atoms which it can use for something else. 
—Eliezer Yudkowsky
A Paperclip Maximizer is an artificial intelligence whose sole purpose is to make as many paperclips as possible, which to the chagrin of its creator, ends up destroying the world in the process.  It's a way of explaining why the folks at MIRI think it's important to study ways of making AI that will benefit rather than harm us.
I have several friends who study AI, so I decided to creatively misunderstand the notion of a Paperclip Maximizer, and thus conclude that AI researchers are inexplicably preoccupied with paper clips.  So to ensure they never wanted for fasteners, I ordered a whole panoply of paperclips from around the internet and had them shipped to their desks over the course of a few weeks.

This amused me greatly, but after a few weeks it was time to take it to the next level.  Thus was born Paperclip Maximizer 1.0:


Here it is in action, with early prototype clips on display that didn't quite have that je ne sais quoi:





The mechanism is relatively simple, but taught me a lot about the subtleties of wire bending.  Two GWS S125 1T sail winch servos provide all the locomotion, controlled by an Arduino Leonardo and about 2 pages of code.

These particular servos have a lot more range of motion than normal servos, and are also easy to modify for continuous rotation.  That was important for the wire feed servo, which always needs to turn the same direction.  When you disassemble this particular servo, you can just remove the gear that connects the axle to the potentiometer.  Then when you drive it, if you tell it to move clockwise of where you left the pot, it'll turn clockwise forever, and vice versa.

The feed wheel is a piece of brass rod I knurled on the lathe to give it some bite.  It's pressed onto the servo, which means I needed to cut down a servo horn to a perfect cylinder.  To do that, I wrote a program for the Arduino to make it rotate continuously, then clamped the servo upright in the mill.  Then while the servo was spinning, I moved in with a spinning end mill.

Next to the feed wheel, you can see a bearing of about the same diameter.  Its job is to hold the wire against the feed wheel.  Originally I bolted the bearing in place, but the wire wouldn't feed consistently.  Turns out there's enough eccentricity in the feed wheel that I needed to let the bearing move in and out slightly.  So that's why you can see a big coil spring overhead, tensioning the bearing against the feed wheel and compressing the wire.  If you watch the video carefully, you can see the arm move in and out slightly on the long feeds, broadcasting to the world exactly how bad my lathe skills are.


Next comes the feed block.  Its job is to keep the wire straight and hold it in place while the bending unit bends the wire.  Like the rest of the project, this turns out to be much more constrained than I expected: if there's too much space between the block and the feed wheel, then when the bender pushes back on the wire, it can bow and kink.  And if there's too much space between the block and the bender, you can't get a tight bend in the wire.

I'd have liked to make the feed block longer to give me more room for the other components.  But it needs a small diameter hole to pass the wire, and small drill bits also tend to be short.  I think I even had to drill the block from both ends to reach all the way through with the bit I had available.

The bending head itself ended up also being pretty cramped.  It needed to extend high enough to leave room for the bearing that does the bending.  It's hard to see, but imagine the head starting out twice as thick as you see here:


I milled out all but a collar from the bottom half of the piece, and that's where it's attached to the servo.  You can just barely see that collar between the head and the servo, to the right of the bearing.  Then it had to reach over to the center of the bearing, but not crash into the feed block.  So I had the mill cut that nice curved shape that you see leading to the bearing nut.  But it wasn't a particularly critical dimension, so grinding the shape by hand would have worked just as well.  Then the head on the 1/4"-20 bolt that holds the bearing turned out to be a bit too thick, so I had to grind that to about half its normal thickness.

If you watch real wire bending machines, you'll see that they create different curves by feeding the wire while they adjust the benders.


Turns out it takes a lot of force to feed wire into a tight bend, and my feeder wasn't up to it.  So that's why I have to alternate feeding and bending, which I actually find quite delightful, since it adds to the quirky personality of the machine.  If I had known at the start that I wouldn't be able to feed while bending, I could have designed the machine to use a fixed bending finger instead of a bearing.  That would have made it a lot easier to make the tight bends needed for a paper clip -- since the bearing is round, it likes to deflect the wire back through the block as it approaches.

Since everything had to be jammed in close together, I was glad I chose to tap the mounting holes for the servos.  If I had to do the project over again, I'd save a lot of time by using acrylic on a laser.  But then I suppose I'd have to rearrange things, tap the acrylic, or maybe use some sort of press-in insert.



What about the big DC motor sitting on top of the bender?   That's the cutoff wheel:



I pressed down the factory plastic gear on the motor to expose more of the shaft, then hot glued on a dremel cutoff wheel.  The motor itself is held onto the bending head with double stick tape; not a great long-term solution.

The way it was supposed to work was to not reset the bender on the last bend, but instead keep moving past the wire.  Then I'd feed out the last leg of the paperclip, and then keep rotating the bending head clockwise until it brought around the cutoff wheel in to finish the job.

That's why you can see a dished out spot on top of the feed block -- I had to spend about 15 minutes manually and very gradually feeding the spinning wheel into the block so that it'd clear when moving into place, yet still end up close enough to the block to cut the wire instead of just deflecting it out of the way.

It's too bad that feature didn't work out, since the sparks you get with steel MIG welder wire make a great grand finale to the process!  But the motor is easy to stall against the wire, which generally also browns out the Arduino.  And about half the time, right at the end, the tiny sliver of remaining wire bends instead of cutting, leaving the finished paperclip attached to the next one.  Oh, and the cut also ends up being razor sharp: I lightly grazed my fingertip with one of the cutoff pieces of wire and ended up with a very clean, deep cut.  So that was the final nail in the coffin for the cutoff wheel.

Writing the Arduino code was one of the easiest parts of the project.  I invited my AI researcher friend over on a Saturday afternoon and we coded and tuned it over the course of an hour or two, making lots of misshapen proto-clips that you can see littered around in the video.  Everything is open loop: move the servo, wait, then move again.  For the wire feed, there are one or two values where the servo will stop because that's where I left the potentiometer when I modified the servo.  But the much better solution is to tell the servo library to detach, which stops the PWM signal to the servo, stopping it no matter where it thinks it is.

Sunday, January 04, 2015

Building new drawers

The crappy drawers in my kitchen were falling apart, so I took the faceplaces off and built new drawers.  I used 3/4" melamine-backed plywood for the sides, and 1/4" melamine-backed MDF for the bottom.  You can see a notch in the lowest tenon of each box joint where I cut the dado for the bottom.

I'm happy with how solid they turned out, but I managed to chip the melamine and sand through it in places when I was sanding the tails of the box joints flush.  So that's a cosmetic annoyance.

Everything's glued and nailed in place.  The nails through the box joints are another cosmetic issue, but I wanted the strength.  I guess if I cared enough, I could fill and paint it all smooth.


Thursday, January 01, 2015

Radial Mill



I see lots of small CNC milling machines these days, generally built like 3d printers: made of plastic or wood, or aluminum extrusion and bearings.  But unlike a 3d printer, subtractive milling involves huge forces, especially if you're trying to remove lots of metal.

The other thing I observe is that almost all the machines use cartesian axes: linear guides that move in perpendicular directions.  This makes a lot of sense in a manual mill where you're moving the axes by hand, but when it's computer-controlled, it's easy to do the math for all sorts of crazy coordinate systems.  So it makes sense to improve the machine mechanically in exchange for software complexity that's easy to share and replicate.

So I set out to make a machine that:

  • Is small enough to fit on a benchtop.  (36,000 pound machining centers are great, but it's always seemed funny to me that such huge machines usually work on workpieces only a few inches across)
  • Is stiff enough to accurately and quickly remove lots of metal.  I don't mind if it's a few hundred pounds as long as it's compact.
  • Exchanges as much mechanical complexity as possible to software.

Here's the result:



The two discs are flywheels from a Chevy smallblock, driven directly by steppers.  The upper disc can move the spindle on an arc from the center to the edge of the lower disc, where the workpiece is mounted.  So by rotating the two discs appropriately, we can put the spindle over any point on the lower disc.

One nifty side effect of this approach is that we get more torque and more accuracy in the lower table the closer we get to the center.



The complexity front was a huge success: the whole machine ends up being about a dozen parts in all.  8 non-off-the-shelf parts, 5 of which are used twice.

  • Table and two legs
  • Neck
  • Upper table
  • Stepper mounting plate (2)
  • Flywheels (2)
  • Wheel bearings (4), axle (2), top cap (2), bottom cap (2)


The flywheels are cast iron, which is great for vibration damping.  And the wheel bearings are from a Ford F-450 truck, and rated for thousands of pounds of load.  The axle is a length of 2 inch steel bar, and the top and bottom caps preload the bearings and hold the assembly together.  Here's the assembly, with prototype MDF end caps:


By comparison, here's a MakerSlide carriage picture I found at buildlog.net.  It has the custom aluminum extrusion, two mounting plates, six bearings (which typically use eccentric mounts so that they can be tensioned against the extrusion) and a long drive belt:


Way less rigid, and way more complicated.

All of the parts are straightforward to mill on a manual milling machine.  The top table is the only part with a curved contour, but it's not a critical dimension, and I just did it because I happened to be using a CNC Bridgeport.  Here you can see all the dimension labels I added in Sketchup to help me program the Bridgeport by hand:


Not particularly relevant to the machine itself, but when it came to choosing a controller, I opted to port GRBL to Raspberry Pi rather than using an Arduino.  The board costs about the same and has a lot more power, which I figured might be handy if I needed to implement the coordinate transformation in using a CPU-intensive hack.

In the next section I'll cover the many things that are still missing, but here's the end result for the machine in its current state.  I taped a marker to the spindle and had it draw the Hackaday skull and wrenches.  No Z-axis means no lifting the pen between segments, and no coordinate transform means that the image gets distorted in interesting ways, although it's still quite recognizable when drawn in that part of the space:



Things to improve

This is just a prototype.  Here's what needs improvement:

  • Backlash.  I measured about 0.010" backlash in the ring and spur gears, which is great for a starter motor on an engine, but terrible for a CNC machine.  I found a worm gear that will drive those threads with more torque (and more steps per inch), but it'd increase the mechanical complexity and I'm not sure if it'd improve the lash.
  • There's no Z axis!  Fittingly for a machine that's all about rotary axes, the up-down Z-axis, which needs to be linear, ended up taking more time than the rest of the project combined.  I never did manage to create linear motion that I was happy with, so to get it into some semblance of working I finally just bored out a piece of aluminum and held the spindle in place with a big set screw.
  • Software support.  The math for rectangular->polar coordinates really is quite simple, but integrating it with a G-code interpreter is another matter.  I managed to port GRBL to Raspberry Pi, but its assumptions about rectangular coordinates are baked in pretty deeply.  My research into TinyG and LinuxCNC don't make me optimistic.
  • Most of the machine is still made out of prototype MDF parts.  The plan was to start with MDF, then re-do with aluminum, then use steel or cast iron for the final draft.  I never got that far, so the black parts you see are just spray-painted MDF.
  • Work-holding, tuning and calibration are completely unaddressed.



Friday, November 14, 2014

Un-bricking a Parrot Ar.Drone 2.0 with a Xadow (arduino)

The Ar.Drone 2.0 creates a wifi access point using network 192.168.1.*, which conflicted with another network I was using on my laptop.  I telnetted in and changed bin/wifi_setup.sh to use 10.0.0. instead, but somehow when I rebooted, the Ar.Drone managed to assign my laptop the illegal address 0.0.0.2, which the rest of the TCP/IP stack refused to cooperate with.

I ordered a CP2102 USB adapter which people said they'd had success using to talk to the 1.8v TTL serial port on the Ar.Drone 2.0, but didn't want to wait for it to arrive.

So instead, I found an arduino board that runs on 3.3v and supports USB serial.  Some arduino variants won't do USB serial at all (even if they can be programmed over USB), and others tie the TX/RX pins to the USB serial.  The latter would have been fine, except that those boards tend to use 5v instead of 3.3v.

The xadow main + breakout boards fit the bill.  Unfortunately, the xadow board requires some tweaks to the arduino installation, but once I had that set up, I was able to use this sketch to link up the USB and TTL serial ports:

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200);
}
void loop() {
  if (Serial.available()) {
    int r = Serial.read();
    Serial1.write(r);
  }
  if (Serial1.available()) {
    int r = Serial1.read();
    Serial.write(r);
  }
}


Then I connected the grounds together (pin3 on the header on the bottom of the Ar.Drone 2.0, accessible by removing a black rectangular sticker).  Pin5 went to rx on the xadow breakout board, then I connected tx to pin6 through a 3.3k resistor to limit the current that I think ends up flowing from the 3.3v xadow board through the protection diodes in the IC in the Ar.Drone that's receiving the data and running at 1.8v.  A proper level conversion would have been better, but the Ar.Drone doesn't seem to mind.

Once I got it connected, plugging in the battery on the Ar.Drone booted it up, and I saw the startup messages in the arduino serial monitor.  I exited out of the arduino IDE, then used 'screen /dev/ttyACM0' to connect to the USB serial port in a way that supports things like colors and arrow keys.

Unfortunately, I didn't look at ifconfig before I fixed the wifi_setup.sh script and rebooted.  The script looked fine, and later I was able to change BASE_ADDRESS back to 10.0.0. and it seemed to work fine.  So the original failure is a mystery to me.