Building and Running My Polargraph SD

Complex print (better picture)

Once I received the kit, it didn’t take me too long to build. I used RJ-11 jacks and cables to connect the motors and gondola to the controller board. I started to print out the Polargraph SD’s case after it was posted to Thingiverse this morning. It’s going to take some time, the bottom of the case is just a little too big for my Thing-o-Matic, so I had to slice it into two pieces.

It certainly takes a long time to print, so I’m glad I waited to get a version that could run without a computer attached (although I suppose that could have been my Raspberry Pi’s job). Since nothing is being heated over 220° C, I don’t worry about leaving it alone. I’ve been starting prints before I leave for work in the morning, so they’re ready when I get home. That didn’t work out perfectly today, when this happened:

Solid square GameBoy

It had been going for about 7 hours. I’ve been trying the different printing styles, and this was called “solid square wave”. That seems to mean that every pixel that isn’t blank is solid black. Since it wasn’t turning out to be much of a drawing, I stopped the print.

Polargraph brownout

I’ve had other adventures too. We had a summer storm last week that caused two very short brownouts. They were long enough to trigger the alarm on my UPS, but not long enough to cause problems with my TV, XBox 360 or other electronics. The capacitor’s in the Arduino’s power supply kept it running, it never missed a step.

On the other hand, the steppers didn’t fare as well. It looks like when the brownouts occurred, there wasn’t enough current to keep the stepper motor’s locked in position, the pen fell down the paper. That caused the neat little mistake above. I’m using a giant linear wall-wart for a power supply, and I guess it doesn’t have enough output filtering to be able to supply the motors during those fractions of a second.

I’ve had a few other adventures. At one point I accidentally changed the pen width to be much too wide. This caused drawings to look too sparse (first attempt), instead of having the contrast it should.

I also had a positioning problem caused by running firmware that was too bleeding-edge out of the SVN tree. It meant I got to help debug the problem, which Sandy quickly fixed. When I tried the Norwegian drawing style, I ran into an issue with the way The Gimp made the headers on PGM files, which I fixed myself. That meant I wrote and submitted my first patch to an open source project.

I Bought A Polargraph SD

First drawing

A couple of years ago I saw a link to a robot called Hektor. The robot draws with a spray paint can, moved around by two stepper motors which dangle the can from a gondola. I thought it was great, but I never thought I’d have something like that.

In the last two years, I have learned about Arduino based drawing robots such as the Drawbot and the Polargraph. I got even more interested earlier this year following MakerBlock’s Drawbot adventures. I was busier at the time tinkering with my Makerbot, but I was also worried about another aspect: I didn’t want to have to leave my laptop connected to the machine for hours. One of my favorite features of my Thing-o-Matic is that I can operate it from the LCD interface and print from an SD card, so my laptop remains available.

Sandy Noble showed pictures in April of a prototype of the Polargraph SD. I watched that but when it was released I decided not to do anything because at £255 (after shipping) it was just too expensive. Earlier this month I got the itch again, and I was going to send an email asking if there would be a cheaper kit version when I noticed the vitamin kit. I can’t help but wonder if it was available the whole time and I just missed it every time I checked.

But it was there, and I had the time, so I bought one and started using it.

How Does Accelerated Printing Look?

Accelerated printing

Since I recently got accelerated printing working using Jetty’s firmware, I thought I would try to see what kind of quality difference I would get. The cute little octopus was designed by Makerbot, and I knew I had to print him. The copy on the left was printed without acceleration, using the standard 30 mm/s feedrate. He took about 45 minutes to print (he’s about 1.5″ tall).

The octopus on the right was printed accelerated at 75 mm/s, and took about 20 minutes. He actually came out pretty well. Some of the layers are slightly misaligned, but I know that my settings need more tweaking. The hovercar in front was actually my first really successful accelerated print. He was printed a few weeks ago, also at 75 mm/s.

The two Mac Plus models are a different story. They were the first objects I tried to at high speed after getting the calibration cubes to work well.  I believe the one on the right was printed first, but it was printed at 100 mm/s. The one of the left was printed at 75 mm/s and did better, but I think the model was just too small to be printed at such high speed. Since I was only using 15% infill, the layers took so little time I don’t think they were cooling enough before the next layer started, causing the poor finish.

I’ve been playing with accelerated printing on and off, I still need to do some tweaking. Stuff I want to come out well (such as my Raspberry Pi case, and a case I’m printing for my Polargraph SD) I still print unaccelerated.

What To Do With A Raspberry Pi?

Raspberry Pi case

Earlier this year when my number came up in the queue, I put in my order for a Raspberry Pi. It arrived in the last week or so, and I printed out HansH’s case to give it some protection and style. The print took surprisingly little time even though it wasn’t accelerated.

The only problem is I haven’t figured out what to do with it yet. I use Rogue Ameoba’s Radioshift (which apparently is no longer developed) to record two radio shows, but they don’t show up as podcasts in iTunes. I’ve been thinking of using the Pi to server up those files to iTunes so they would show up correctly.

Painting Makerbotted Figures

Pikachu

The first model I painted was my B-17 Flying Fortress. In that post I said I tried a cheap airbrush with a propellant can and it didn’t work. That model was largely hand painted.

But I haven’t stopped experimenting. For Christmas I got an Airbrush Depot TC-20T compress and SB84 airbrush. The compress is very nice. It’s not all that loud and having the tank means that it doesn’t have to run constantly. I’m always worried about annoying my downstairs neighbors, so that’s a serious plus.

As for the airbrush, I though it was pretty good. While it was a huge step up from the external mix piece of plastic junk I tried before, it was tough to clean. It also needed quite a bit of air to spray paint. I generally used the brush with the nozzle open all the way to get enough paint. This may be because it’s a side-loading airbrush. A month or two ago I was reassembling it after cleaning, and broke the nozzle when I overtightened it. I was going to buy a new one when I found that an Iwata wouldn’t cost too much more (I thought they were all $250+).

So I bought an Iwata-Medea Eclipse HP CS. As soon as I tried the Eclipse I knew what a huge difference there was. I knew people online liked them, but wow. It’s top-loading, and that makes it MUCH easier to clean. Pulling the lever back all the way to release the maximum amount of paint just drenches things, which is fantastic. The SB might as well have been an on-off device. A side effect of all this is that it doesn’t need as much air. When you have it in your hand, it’s easy to tell how much higher the manufacturing standards are. Add a quick disconnect and life is much easier.

So with my new tools I’ve been having a ton of fun painting models that I printed out with my Makerbot. Besides the Pikachu above, I’ve painted Alot, Piccolo, a Stegosaurus, a Cyberman, Bender, Purple Tentacle, and various pet monsters by Andreas.

I’ve figured out quite a bit while doing it. Preparing the model well before putting the primer on makes a big difference. It’s so easy for the paint to flake off afterwards, something you can see on Bender. Another problem I’ve had is paint colors. I’ve been using Createx opaque paint and mixing the colors myself. This has been fun but I quickly learned a lesson: mix more than you need and save it. With Bender and each of the pet monsters, I ended up having to repaint large portions of the model because I needed to put the base color back on and couldn’t match it closely enough.

I’ve found that Testor’s gray primer works great, and you can buy straight liquid so you can airbrush it on. For sealing the finished models I tried a few things before I found Testor’s Dullcote. It smells horrible, and I worry that I’m going to damage my airbrush with it. Next time, I think I’ll just buy the little spray cans instead. But unlike some of the other clear coats I found, it doesn’t change the colors making everything look less saturated and more boring.

I didn’t really have a use for my Makerbot when I bought it, but I think I may have found it. Since I’m close to getting to getting Jetty’s accelerated firmware fully calibrated, I’m looking forward to printing larger objects without it taking as long. My mistake the first few times? When you up the speed, you must up the flow rate. I kept forgetting to do that, which is why the extruder wasn’t putting out nearly enough plastic.

Honda Odyssey Bumper Fix

Van fix (distance)

A few months ago I ended up damaging the bumper on my Honda Odyssey minivan. One day I noticed it looked like my bumper was falling off. As it turned out, the end of the bumper broke off right at the point where it was attached to the frame. It probably got caught on something when I was backing up; or maybe someone just hit my car.

Either way, it was a bit worrying. I didn’t want my bumper to fall off in traffic, and I didn’t want to risk going into an automatic car wash. Duct tape (you can remnants in the photo above) didn’t hold well and looked even worse.

So I did what anyone with a Makerbot would do, I designed and printed a fix. It glues onto the end of the bumper and provides a hole for the bolt that keeps the bumper on the car. I’ve been driving around with it for a few weeks now and it works great.

My Odyssey Bumper Fix is available on Thingiverse, if you should have the same problem.

I can’t play Uncharted 2, or why the PS3 experience is terrible

Wow, the Playstation experience is still terrible. I wanted something new to play so I went down to Best Buy to waste a gift card I had and bought a copy of Uncharted 2. Here’s my experience so far:

  1. Boot console, insert game (1 minute)
  2. Game starts, decides it needs to update. This game is a few years old, so this isn’t too unreasonable. The first problem is number of updates. It says there are nine updates. Great. Would a combo update be so hard? Uncharted 2 is only the 5th best selling game on the system, and one they heavily promoted and bundled.
  3. The PS3 download about fifteen updates. For some reason, many of the updates don’t increase the counter of how many updates are applied, even though the change the percentage of total updating done.
  4. Also, the downloads aren’t fast. Despite my 12mb connection, I know they’re not going anywhere near that fast.
  5. And I could start the DLC process, but for game updates can’t be downloaded in the background, because the dashboard obviously couldn’t function while a download was going on.
  6. Finish all updates (20-30 minutes), they installed, game booted.
  7. I want to install the DLC that comes with the game (since I bought the Game of the Year edition). That means opening the PSN.
  8. Nope! I need to update my PS3′s firmware. Hit download, it gets the file, reboots, and installs. (10 minutes).
  9. Sign into PSN. Now I have to agree to two new license agreements. Not one but two.
  10. Get in, go to the redeem codes screen.
  11. The code is case sensitive, so I have to switch the keyboard to upper-case mode. But when I do that, the numbers become symbols, so I have to switch it back to lower case to type in the numbers. This means lots of switching.
  12. The code comes in three sections (ex: DF8R-34KF-FJ83). Each section must be entered individually, and the PS3 doesn’t automatically move to the next field when you’ve entered the content for the first. (5 minutes)
  13. Done! It authorizes me, now I can download my DLC. There is only… 28 pieces.
  14. Luckily, the PS3 will download it all for me. Wait… no… I have to choose each piece of DLC individually and hit download. There is no button to download all. (10 minutes).
  15. Some of the downloads are hundreds of MB. So I choose “download in background” for those. How do you know that’s working? You don’t. Of the 28 pieces of DLC, there is no way to know which ones I have already downloaded, which are downloading, and which I haven’t triggered yet.
  16. So I exit that screen and go to the “Downloads” screen in the PSN. It shows all 38 downloads I have access to (due to previous purchases). Yet it does not show which are downloaded or downloading.
  17. So instead I went back to the dashboard, and found the download screen there. It does show the 6 files that are still downloading. It does not estimate how much longer it will be until it’s done with all the downloads. (5 minutes)
  18. So here I am, waiting for downloads to finish. My PS3 has only downloading one thing at a time, averaging maybe 600KB/s on my 1500KB/s line. Left to download? That’s not shown either. But I’m guessing it’s over 3 GB (again, some of that content is BIG). It ended up taking 1 hour. (60 minutes)
  19. Downloads are done, it’s time to go install the downloads. I have to do each one individually. On the plus side, only 6 or 7 need installing. On the minus side, one of the largest ones won’t install, and three downloads are corrupt. Which two? Who knows! The one that won’t install gives a cryptic error number, which isn’t defined anywhere. But Google searches suggest it means the download was corrupt. (15 minutes).
  20. Now I get to go back and re-download a ton of stuff, because there is no way to know what I installed successfully and what I missed. So instead, I’ll skip re-downloading most of it, and hope I don’t miss anything I care too much about. (15 minutes)

What a mess. The interface has been terrible, and provides no useful information. It’s nice to know how valuable Sony things my time is. To play this game, I’ve lost 2.5 hours of my life. That means I’m giving up on trying to play tonight, and will go to bed hating my PS3. Right now I like my XBox 360 better, and it’s dead from RROD.

You know, when I bought the game there was a used copy for $5 less, and it wouldn’t have included any of the DLC. Spending an extra $5 cost me more than 90 minutes of my time.

Second Best Clojure Bot, Postmortem

Well, the Google AI Challenge is over, and I ended up as the second best Clojure bot. My skill rating was 53.23, which put me in 1,335th place. I never expected to be so high, but it turns out there weren’t a lot of Clojure entries. I was beaten, by a large margin, by thobel. He did a great job. With the contest over, I thought I’d post a little postmortem of how my bot worked.

Global State & Exploration

My bot really doesn’t keep any global state, which is one of the reasons it didn’t do better. I planned to start adding some, but I never got around to it as I got distracted by work and other things. Here is the only global state that really matters:

(def ^{:dynamic true} *current-defense* (atom nil))
(def ^{:dynamic true} *positions-to-fill* (atom #{}))
(def ^{:dynamic true} *positions-unfilled* (atom {}))

(def ^{:dynamic true} *ant-last-moves* (atom {}))

The first three variables keep track of bot’s defenses, which is the only form of coordination between the ants. *ants-last-moves* keeps track of the last move each ant made so they can be prevented from backtracking.

In fact, the backtracking prevention is the only form of exploration in the code. Each ant sets out when spawned in a random direction, and ants have a 90% chance of continuing in the direction they were already traveling.

Core Logic

The core of the bot is a function called process-ants-for-moves. It is called once for each ant and is responsible for determining what that individual ant will do. In the last set of changes I uploaded, I added some code to keep track of how long the turns were taking and abort processing if it hit the 90% mark. It runs the process-ant function for each ant, building up a list of where the ants new positions are so they can be sent to the server at the end of processing.

The process-ant has a list of individual functions it can apply to the world state to find the best move for the ant. Cleaning things up with some pseudo code, it looks like this:

(defn find-move-through-functions
  "Run each function, return the first valid non-nil direction"
  [ant valid-directions valid-directions-with-back ants-last-move]
  (when (not-empty valid-directions))
    (loop [functions-to-run {move-to-defend-our-hills :defense
                            move-to-emergency-defense :e-defense
                            move-to-capture-hill :capture
                            move-away-from-enemy :run-away
                            move-towards-food-classic :food
                            move-in-random-direction :random}]
      (if (not-empty functions-to-run)   ; Still functions to check
        (let [the-function-stuff (first functions-to-run)
              the-function (key the-function-stuff)
              the-function-purpose (val the-function-stuff)
              result (apply the-function ...)]
          (if (= :none result)
            nil     ; The answer is 'don't move'
            (if (empty? result)
              (recur (rest functions-to-run)) ; No answer, try next
              (random direction from result))))))))

This works quite well. It runs each function in turn for the ant. If the function returns nil, the next function is run. Otherwise a random direction for the list of possibilities the function returns is chosen as the ant’s move.

The Move Functions

There are quite a few of these, including some from experimentation that don’t actually get run. Here is the description of those that are in use, in priority order. They all tend to follow the same pattern. I never put it into a macro or function, but that would have been smart. Here is the basic template:

(defn some-move-function
  [ant _ _]
  (cond
    (check that that function applies, such as if we see enemies)
      nil  ; It doesn't

    :else
      (let [distances (calculate distances to things of interest)
            spots (sort distances and filter out things too far away)
            visible-spots (stuff in spots that's line-of-site of ant)
            closest-spot (first (first visible-spots))]
        (when closest-spot    ; If something matches the criteria
          ; Some additional processing may be done here
          (utilities/direction ant closest-spot)))))

The line-of-sight code was a pretty big improvement. It meant that ants no longer got stuck against water trying to get to a piece of food on the other side. The function is basically Bresenham’s line algorithm. It’s not perfect, but it worked well enough and was pretty fast. As it walks along the line, it checks for water. If it doesn’t find any, the line-of-sight is clear.

Each function returns a set of directions the ant should move in, and the code picks one randomly. The selection is weighted so the ants tend to move in straight lines.

move-to-defend-our-hills

This is the function that uses up most of the global state. The global variable *current-defense* is checked to see what kind of defense we should be running. This is set at the start of each turn based on the number of ants we have per hill.

This is the code that sets up the little formations around my hills. First the ant is checked against the list of defense positions. If the ant is already on one of the spots, the answer is the keyword :none, meaning “don’t move from that spot.”

If the ant isn’t in a good position, it checks to see if it’s within visual range of a spot that does need filling. If so, it goes straight to it. This has the effect that newly spawned ants first action is to move into any holes in the defensive positions. Because of the way the defenses are setup (and since ants can’t move diagonally), attackers have to come in from a corner or two-abreast if they don’t want to lose their ants. This was remarkably effective.

move-to-emergency-defense

Once the defensive positions are filled, the next thing to do is to run emergency defenses. The code finds the closest visible hill to the ant, and then checks if any enemy ants are too close.

If they are, any ants that can see that hill rush back to try to stand on top of it. This floods the hill with defenders, hopefully allowing it to survive the onslaught. Since there is no real state on the ants, as soon as the danger is passed (the enemies are gone), they go straight back to normal behavior.

move-to-capture-hill

Whenever my ants see an enemy hill, they go straight for it. There is no hesitation, no strategy, just suicide charges. As a result of the next function (move-away-from-enemy), my ants don’t tend to get near enemy hills unless the area is not well defended. I’ll often lose ants this way, but it’s amazingly effective at grabbing hills people leave undefended. If an enemy moves so much as moves a square or two off a hill, my ants have a good chance at taking it.

move-away-from-enemy

This function is my bot’s entire survival instinct. My ants run in the other direction from the closest enemy that’s within 8 squares. This does hamper food gathering, but it prevents my ants from getting roundly slaughtered during movement. Note that this function doesn’t apply if the ant is in one of the defense modes (since this function wouldn’t get run), or when the ant is within view distance of one of my hills (an old condition from before defense mode so my ants wouldn’t give up their home bases).

move-towards-food-classic

It’s called “classic” because I came up with a better function for finding food, but it was never turned on due to performance problems. This function simply moves the ant towards the nearest piece of food they can see (with the line-of-sight check). In practice, having multiple ants go after the same piece of food wasn’t a problem.

moves-in-random-direction

If nothing else came up with a move, the ant would go in a random direction. This caused (limited) exploration.

Things I Meant To Do

If you look through the code, you can find commented out sections from some of my experiments. One of the early ones was move-towards-food-res. It would find the closest ant to each piece of food and record a reservation. This prevented multiple ants from going towards one piece of food. When I turned this on, my ants picked up much less food. The simpler method seemed to work better.

The better method of finding food was diffusion. There are globals and functions to take the food that the bot knows about and diffuse their influence, producing a gradient that the ants could follow to the areas with the most food (see influence mapping).

It turned out that this was much too slow. Others got it working (quite well), but I didn’t. Data structures were (I think) a big part of this. I was using a pseudo queue made out of a vector, and it wasn’t that fast. As it turns out Clojure has a queue that simply has no syntax yet which was very fast, but I didn’t get around to converting my code. The other thing that would have helped was not recalculating everything each turn. I started planning this but never got around to it either.

Many people used some form of this to explore the maps, which would have also been a smart thing to do.

Debugging

One thing I learned a fair bit about was debugging. It’s something difficult to do in Clojure (since there aren’t any native debuggers that I know about), so I had to invent some. I started debugging by sprinkling my code with statements like this:

(utilities/debug-log "Ant at " ant " doing " the-function-purpose ", going " dir)

The actual function looked like this:

(defn debug-log
  "Log something to the console for us to go through later"
  [& message]
  (when defines/logging-enabled
    (binding [*out* (if (nil? defines/*log-file*)
                        *err*
                        defines/*log-file*)]
      (apply println message)
      (flush))))

First the function checked to see if logging was enabled. If it was the *log-file* global variable was checked. When defined, the code would write the log message out to a file (which I would use to follow what my bot was doing). If the file wasn’t defined, it would just spit the message to standard error (which would cause the ants server to mark my bot as crashed for producing unexpected output).

Later I started using the visualizer that was available in the forums, but I had to be careful. I found the python server wouldn’t terminate if I produced too much visualization output.

Summary

That’s basically it. I’ve put my bot’s source up on my GitHub account if you want to take a look at it. The Clojure code is in the src/ directory, and it’s pretty clear that it was under active development when I stopped. Code is still commented out in places from debugging.

AI Challenge Entries Closed

Aside

The entry period for the AI Challenge has closed, and they’re doing the final games. I really haven’t updated my bot in two weeks or so. I had some more ideas to do and optimizations, but I never got around to it. In the end, it looks like I’ll be the 2nd place Clojure bot as one of the other that was more actively developed took a giant leap above me. I’ll be happy to try again next year.