Clojure FizzBuzz Without Conditionals

Published on:
Tags: All, Clojure

Sure you may have done FizzBuzz before. Maybe you have even done it in Clojure. But have you done it without the use of any conditionals?

As your brain starts to work on the how this we be done, you might be wondering why you should do this in the first place?

There are two very good reasons for this. The first is that it is a kata.

Katas build your code practice

Code katas build your skill through practice. It doesn’t matter if you are a beginner or an expert. Just, like in all those martial arts movies with the swordsman practicing, so must we. We stretch and flex our coding muscles with katas to grow them and keep them in shape.

Yes, you may code every day at work. But it is not the same as kata practice. So much of day to day work involves complexity with large interconnected concerns. Our kata practice cuts the extra complexity out and leaves you alone with a focused small problem.

The second reason involves why you should try it, this time, without conditionals. The answer is creativity.

Constraints build creativity.

It turns out that constraints are a key way to drive creativity. Programming does not only require technical skills, but also creativity. We are seldom asked to build software without constraints. It drives design. Sure, it can be annoying when we have to communicate with a server that is only active on Tuesday and emits its response in Morse Code. But it gives us boundaries to unleash our creative spirit.

So go for it.

Give it a try

Ready? Here are the details.

  • Given a number, if it number is divisible by 3 return “fizz”.
  • If it is divisible by 5 return “buzz”.
  • If it is divisible by 3 and 5 return “fizzbuzz”.
  • Otherwise, just return the number.
  • Don’t use any conditionals like if else case cond.

When you are done, you can check out some of the other solutions. Try not to peek until you have done your version first though.

(There are some really awesome ones so far).

Feel free to link to yours in the comments too :)

Solutions

From @aderth

From @IamDrowsy

From @Bryanwoods

From @defndaines

From me

From @hyPiRion – a couple of notes for this one is that:

1
2
(+)
;; -> 0

and

1
2
(*)
;; -> 1

And once you think about that, you might want to read this :)

Happy Clojure Kataing!

The Five Stages of Writing a Book

Published on:
Tags: All

  1. Denial: I am not really writing a book.
  2. Anger: Why did I ever decide to write a book?
  3. Bargaining: If I just finish this book, I promise never to write another one.
  4. Depression: I am never going to finish this book.
  5. Resolution: I am writing a book and I am going to give it my frigging all.

Notes and Tips on Working From Home

Published on:
Tags: All

Recently, I switched from a traditional, “go to an office” job, to working from my home. It took some time to setup my home work space and get used to working remotely, but I finally have a system working for me. In this post, I thought I would share some things that I found useful.

Window Seat Please

If at all possible, locate your home work space near a window. The natural light does wonders for you mood and being able to glance up and look at trees and real life is a refreshing break from staring at code all day.

A Door is Great

Having a door to your workspace is a real advantage. It enables you to close off noise and other activity that might be going on in the house. It is also incredibly useful if you have small children. For my kids, if the door is closed, then it is a sign that Mommy is working – do not disturb.

Invest in a good chair.

Backs are very important. I started working from home with just my kitchen chair – big mistake. After a day or two, my back was crying out for something better. I did some research on good chairs to get and I ended up with a Steelcase Leap Chair. They are not cheap. But, I was able to get a refurb one that was considerably less than new, and my back loves it.

Don’t Sit All the Time

Even with my great chair, it is not the best to sit constantly. I had tried a straight standing desk a while back and I found that standing all the time was not the best for me. I prefer to mix it up. I got a adjustable Geek Desk. I generally stand up in the morning and sit in the afternoons.

Freedom from a Headset with a Good Mic

I have used a headset before when doing remote calls. They work fine, but after a while, I found it annoying to have on my head all day. I switched to a Blue Snowball Mic at home and am really happy with it. My voice comes in clear and I am headset free.

Dual Monitors for the Win

I use two Thunderbolt displays. One monitor I use for communications, it has my email, chat, and video on it. The other monitor I use for the codez. It works out pretty well to switch back and forth.

Good Software for Communication

Good communication is a must for working remotely. Someone cannot just wander over to your desk and ask you a question. Here is a list of communication tools I use at work:

  • Slack – for team communication.
  • Google Docs
  • Zoom – for video and screen sharing. It is way better than Google hangouts in terms of video quality.
  • Apple’s Screen sharing – for pair code development. This let’s people use whatever editor they are comfortable with, yet you can see the code and still share control.

Pair Programming is Awesome

At work, we do pair programming most of the time. I really like to work this way. One of the things that I was concerned about in switching to remote work was being lonely. Pair programming really helps in this. I am usually working with someone during the day, with one monitor going with video and voice, while the other monitor has the code we are working on. For me, it has all the advantages of idea sharing and group problem solving. I realize that working this way is not for everyone, but I am digging it.

Routine is Everything

When working for home, I have found it is crucial to have a good routine. Since we do a lot of pair programming at work, we all generally keep the same hours. Being a distributed team over North America, this means I start work at around 10am EST. I have found that having a routine a sticking to it helps structure my day. I get up, get dressed, eat breakfast, just like I was going to work. Then, I usually hack for a bit on personal stuff in the morning until it is time for work. Then at lunch, I go for a run or work out. Finally, and most importantly, in the evening, I leave the computer behind and devote time to family.

Don’t Forget to Visit with Other Humans

The downside of working from home is that it is very easy to not leave home. At one point, I realized that I had not left the house for a week. Not good. I try go to a social event where I will meet with other developers and friends every week. There is a nice developer coffee group that meets on Fridays. I also help run our Cincinnati Functional Programmer’s Group here in town. In general, I find that if I am driving somewhere and see people walking on the street and start thinking, “Look Humans!”, it is time to get out and socialize a bit more. Working remotely, makes going to conferences and being with other developers in person even more fun.

Summary (with a Dog Pic)

I have found working remotely to be quite enjoyable so far. It does take an extra effort to keep your life structured and communication flowing properly, but it is worth it.

My next challenge, since it is getting colder, is to get my dog to sleep on my feet while I work. No luck so far.

If anyone has any tips, let me know.

Green Eggs and Transducers

Published on:
Tags: All, Clojure

A quick tour of Clojure Transducers with core.async with Dr. Seuss as a guide.

Follow along at home by:

  • lein new green-eggs
  • modify your project.clj to include the following:
1
2
3
4
5
6
7
(defproject green-eggs "0.1.0-SNAPSHOT"
  :description "try them"
  :url "http://en.wikipedia.org/wiki/Green_Eggs_and_Ham"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0-alpha1"]
                 [org.clojure/core.async "0.1.338.0-5c5012-alpha"]])
  • Start up a repl and hack in!

Green Eggs and Ham

Transducers are a new feature of Clojure 1.7. Instead of trying to explain them with words, let’s take a look of them in action. First we need some data. Let’s def a vector of all the places you could try green eggs and ham.

1
2
3
4
5
6
7
8
9
10
11
12
(ns green-eggs.core
  (:require [clojure.core.async :as async]))

(def green-eggs-n-ham
  ["in the rain"
   "on a train"
   "in a box"
   "with a fox"
   "in a house"
   "with a mouse"
   "here or there"
   "anywhere"])

Next, let’s create a function that will transform the places into a “I would not eat them …” sentence.

1
2
3
4
5
(defn i-do-not-like-them [s]
  (format "I would not eat them %s." s))

(i-do-not-like-them "in the rain")
;; -> "I would not eat them in the rain."

We also need a function to take this result and actually try the green eggs and ham.

1
2
3
4
5
(defn try-them [s]
  (clojure.string/replace s  #" not" ""))

(try-them "I would not eat them in the rain.")
;; -> "I would eat them in the rain."

Now we have two transformations that we can apply to the vector of green-eggs-n-ham strings. One of the really nice things about transducers is that you can describe and compose this transformation without a data structure present.

1
2
3
4
(def sam-i-am-xform
  (comp
   (map i-do-not-like-them)
   (map try-them)))

We can run the transformation of the transducers against the data in a few ways.

  • into: Non-lazy turn the transformation into a collection
  • sequence: Same thing but lazy
  • transduce: Acts like reduce on the all the transformed elements
  • With core.async channels doing the transformations.

Let’s look at the green eggs and ham example for each one of these ways:

Into

Into takes a transducer and collection to work on and returns the vector we asked for:

1
2
3
4
5
6
7
8
9
(into [] sam-i-am-xform green-eggs-n-ham)
;; -> ["I would eat them in the rain."
;;     "I would eat them on a train."
;;     "I would eat them in a box."
;;     "I would eat them with a fox."
;;     "I would eat them in a house."
;;     "I would eat them with a mouse."
;;     "I would eat them here or there."
;;     "I would eat them anywhere."]

Sequence

Sequence takes similar arguments, but as promised, returns a lazy sequence that we can interact with.

1
2
3
4
5
(class (sequence sam-i-am-xform green-eggs-n-ham))
;; -> clojure.lang.LazyTransformer

(take 1 (sequence sam-i-am-xform green-eggs-n-ham))
;; -> ("I would eat them in the rain.")

Transduce

If we want to finally arrange all our sentences in the vectors into one string, we would use reduce. The way to do this with transducers is to use transduce. It takes a function of two arguments to perform the reduce, as well as an initial data input.

1
2
3
4
5
6
7
8
9
10
11
12
13
(transduce sam-i-am-xform #(str %1 %2 " ") "" green-eggs-n-ham)
;; -> "I would eat them in the rain.
;;     I would eat them on a train.
;;     I would eat them in a box.
;;     I would eat them with a fox.
;;     I would eat them in a house.
;;     I would eat them with a mouse.
;;     I would eat them here or there.
;;     I would eat them anywhere."

;;_note: In  1.7.0-alpha2, transduce changed and you need to use a
;;(transduce sam-i-am-xform (completing #(str %1 %2 " ")) "" green-eggs-n-ham)
;;instead.

Core.async

Core.async has a really nice way to define channels with a transducer that will transform each element on the channel.

1
(def sam-i-am-chan (async/chan 1 sam-i-am-xform))

Let’s define another channel to reduce the results of the sam-i-am-chan to a string.

1
(def result-chan (async/reduce #(str %1 %2 " ") "" sam-i-am-chan))

Finally, let’s actually put the green-eggs-n-ham data onto the sam-i-am-chan and let the data transformations flow….

1
(async/onto-chan sam-i-am-chan green-eggs-n-ham)

At last, we can get our result off the result channel and revel in the beauty of asynchronous data transducers.

1
2
3
4
5
6
7
8
9
10
11
(def i-like-them (async/<!! result-chan))

i-like-them
;; -> "I would eat them in the rain.
;;     I would eat them on a train.
;;     I would eat them in a box.
;;     I would eat them with a fox.
;;     I would eat them in a house.
;;     I would eat them with a mouse.
;;     I would eat them here or there.
;;     I would eat them anywhere."

Transducers are elegant and powerful, just like the rest of Clojure. Try them, you will like them :)

The Proper Pronunciation of Clojure’s Assoc

Published on:
Tags: All, Clojure

Sometimes I pause before talking to someone about Clojure code. Not because I am unsure of the code, but because I am unsure of how to pronounce the code. The particular code in question is Clojure’s assoc. I have heard it pronounced two ways. One is “assosh”, the other is “assok”. So, to determine it, I decided to conduct a scientific poll of the Clojure community.

I posted the poll on twitter to the Cojure community who follow me. The control group poll was not viewed by those who do not follow me, and/or, are not on twitter.

The results were startling.

  • assosh – 10
  • assok – 8
  • assose – 2
  • Jeremy – 1
  • asoaksh – 1

The community is clearly deeply divided on this important question.

After sifting through the raw data, I remembered my statistical analysis and threw out the extremes.

The conclusion was still a stark reality.

We do not as a community know how to pronounce assoc.

Solution

I can only see one way forward. We must address this as a community. I propose that the community documentation of Clojure Docs and Grimoire modify their sites to include audio pronunciation like this.

Remember, I’m pulling for you. We are all in this together.

Clojure X-Men

Published on:
Tags: All, Clojure

Nobody knows how it happened. Some people think it was due to the rapid expansion and adoption of Clojure. Other people say that the language itself was caused by something deeper and more magical. No one knows for sure. All that we really know is that people starting being born with extraordinary powers. Powers that no human had had before. They were strange and unique to each person they touched. The only thing that they all had in common, was that each was an aspect of the Clojure programming language.

Luke (AKA Lazy Luke)

Luke was a teenager when his powers came to him. His mother always complained that he was lazy. It was true, he did prefer to sleep until noon. He also had a habit of putting everything off to the last minute, like saving all his papers for the night before they were due. One day, though, he noticed something very strange. He could start to see the future. Well not really “see” it. But he could see the infinite possibilities of the future. Not very far into the future, but enough. It was a few milliseconds at first. But now it was up to a full second. He checked the Clojure Docs as soon as he realized his gift. It was lazy evaluation and power to deal with infinite sequences.

Spress

Spress, whose real name is Emily, came into her power early. She was only 5 years old. Her mother had taken her to a farm to visit with the animals. Her mother had pointed at the cow and told her daughter that it said “Moo”. Then, at the horse, saying “Neigh”. Spress smiled and pointed at a bucket and said “cow”. Her mother shook her head at her, but Spress only smiled bigger. She said “cow” again. Then, suddenly, the bucket went “Moo”. She was immediately taken to the Clojure X-Men school, where they identified her power as protocols. She trained her power and now is so good at solving the “expression problem”, she is known as “Spress”.

Multi

Nobody knows Multi’s background. He came to notice in his early twenties with his powers. Ordinary humans process sensory input, (like sight, touch, and sound), in an asynchronous fashion. However, when it gets processed in the brain, it runs into a single pipeline bottleneck – consciousness. Multi’s power is that he can concurrently process his higher level consciousness and reasoning to all this sensory input. The result is that he can move, think, and perform super fast and in a super smart way. He got the power of Clojure’s concurrency.

Dot

Dot always had a way with animals. She had many pets growing up. Later, she would go into the forest and the animals would seek her out. She would be found resting by a tree surrounded by deer and birds. One time, on her walk, she fell down a ditch and had her leg trapped under a log. Her mother arrived, after searching for her, to see a Bear reach down and gently remove the log. She stood dumbfounded, as her daughter thanked the bear and it nodded in reply as it turned away. She could talk with animals effortlessly. She had the power of Clojure’s Interop.

Bob

Bob is the leader of the Clojure X-Men. He seeks out people with the power of Clojure and helps train and educate them. He also is the most powerful. He can come into any argument, problem, or challenge and immediately separate out what is most important to focus on. He always knows the right thing to do, without getting bogged down in unnecessary details . His power is Clojure’s simplicity.

There might be others out there, we don’t know. We can only hope, that they are found by Bob and the Clojure X-Men and use their powers for good.

Love Songs Through History and Why You Should Create

Published on:
Tags: All

The Earliest Known Love Song

The earliest known love song was found in an Egyptian tomb. The fragment found in the 4,300 year old tomb read:

I love and admire your beauty. I am under it.

Medieval Love Songs

Moving forward in history to Medieval times, there are many examples of love songs. One of them from a great composer in the 14th century, named Guillaume de Machaut:, went something like this:

You are the true sapphire
that can heal and end all my sufferings,
the emerald which brings rejoicing,
the ruby to brighten and comfort the heart.

Love Songs from this Summer

Love songs abound on the radio and internet today. One was released by Coldplay recently, called “A Sky Full of Stars”. The lyrics go something like this:

Cause you're a sky
Cause you're a sky full of stars
I'm going to give you my heart
Cause you're a sky
Cause you're a sky full of stars
And cause you light up the path

Why Create?

I have nothing to say that has not been said

These are the whispering excuses that I hear in the back of my head when I sit down at a blank text editor:

  • Someone has already said this.
  • Someone has already built this algorithm.
  • Someone has already built this library.
  • I have nothing to say that has not been said before.

But it has not been said by you.

Love is a universal human emotion. We have evidence that people have been writing about it and singing about it for at least 4,000 years.

Hasn’t everything already been said about it?

No.

We still want to hear it again. We still want to hear it new, said by another. It means something slightly different, feels different when said again by someone else with different experiences, from a different life, from a different perspective..

The same goes for your writing, your code, your library, and your creation.

So open up your favorite editor and brush aside your fears. It is a blank canvas, ready for your thoughts and code.

Say it loud

Say it strong

Create

Don’t worry if it has been said before

It is new because it is said by you

A Taste of the Star Programming Language

Published on:
Tags: All, Star

A while ago, I was exploring creating a programming language with Instaparse. I ended up exploring some concepts of Speech Acts proposed by John McCarthy by creating my first toy language called Babar. Shortly after posting a blog about it, I got an email from someone saying that I might be interested in a full blown, real programming language that also incorporated Speech Acts. I happily started composing an reply to the email that started off with

That is so cool! ...

Then I realized that the author of the email and language was none other than Frank McCabe, one of the designers of the Go! programming language (not to be confused with Google Go). My brain froze while it was thinking

"OMG!!!! Frank McCabe, a real language designer, just emailed me!".

This unfortunately, made the rest of my email reply sound something like this

Frank,
That is so cool!  herp derp derp Speech Acts herp derp John
McCarthy derp...

His programming language is the Star Programming Language. It was originally developed for use at a company that he worked at called Starview. It has since been open sourced and moved to git. I finally had a bit a spare time and I had been itching to give Star a look. To my pleasant surprise, despite my initial fumbling email impression, Frank was open a friendly to get me started in it. I have only scratched the surface in exploring the language, but I wanted to share my initial impressions, as well as point you to some beginner katas that I put together, so that you could join in the fun.

Crash Overview

Star is a strongly typed, functional language. It is not a pure functional language because is allows assignment and stateful objects, but the language is designed in a way that immutable functional programming is encouraged. The feel of the language is concise but human readable.

Star is a coherent, general-purpose programming language that
combines elements from a wide variety of existing languages as
well as adding innovative elements of its own. Star inherits func-
tional programming in general, a Haskell-style type system, an F#-
style monad for parallel computations, and Concurrent ML for or-
chestrating concurrent and parallel applications.

Feel different on the Java platform: the star programming language dl.acm.org/…

Hello World

The best way to get a feel for it is to look at a few examples. Of course, let’s start off with Hello World.

1
2
3
main() do {
  logMsg(info, "Hello World");
}

Another way of doing our Hello World is in a worksheet. This feature is still in the works, but it will likely turn into a replacement for a REPL, being integrated into the editor. The import statement will also soon not be required. But a nice feature of using the worksheeet is that is a combined module and transcript of the session.

1
2
3
4
5
import worksheet

worksheet{
  show "hello world"
}

Here is what the output looks like:

Jun 11, 2014 11:21:09 AM  
INFO: "hello world" -> "hello world" at 4
info: execution took 0.053684428

Pattern Matching

Let’s take a look at another example. This time a naive fib function with pattern matching.

1
2
3
4
5
6
7
8
9
10
11
12
import worksheet

worksheet{
  fib(0) is 0
  fib(1) is 1
  fib(n) is fib(n-1) + fib(n-2)

  assert fib(0)=0;
  assert fib(1)=1;
  assert fib(3)=2;
  assert fib(10)=55;
}

Notice how the fib function is defined with pattern matching. Also how the keyword “is” is used instead of an “=” to make the code flow more readable (IMO).

The output of running the program is:

Jun 11, 2014 3:32:38 PM  
INFO: fib(0) = 0 ok at 9
Jun 11, 2014 3:32:38 PM  
INFO: fib(1) = 1 ok at 10
Jun 11, 2014 3:32:38 PM  
INFO: fib(3) = 2 ok at 11
Jun 11, 2014 3:32:38 PM  
INFO: fib(10) = 55 ok at 12
info: execution took 0.039725132

Pattern Matching with Guards

The declaration of pattern matching for functions can also include guards like in this fizzbuzz example

1
2
3
4
5
fizzbuzz has type (integer) => string
fizzbuzz(N) where N%3=0 and N%5=0 is "fizzbuzz"
fizzbuzz(N) where N%3=0 is "fizz"
fizzbuzz(N) where N%5=0 is "buzz"
fizzbuzz(N) default is "$N"

Also note the type declaration. The type declaration is optional. The complier is smart enough to figure it out. Sometimes it is more readable to include the type declaration. But, it can be left out for more concise code.

Cons Lists

One of the important collection types are cons lists. These are lists that you add to the front of and are destructed as the first element and then the rest of the list. To construct a cons list:

1
 testNumbers is cons of {1;2;3;4;5;6;7;8;9;10;11;12;13;14;15}

To use a cons list in a function with pattern matching:

1
2
3
listFizzBuzz has type (cons of integer) => cons of string
listFizzBuzz(nil) is nil
listFizzBuzz(cons(x, xs)) is cons(fizzbuzz(x), listFizzBuzz(xs))

The function listFizzBuzz takes in a list of integers and turns it into a list of strings using the fizzbuzz function. If we evaluate:

1
2
testNumbers is cons of {1;2;3;4;5;6;7;8;9;10;11;12;13;14;15}
result is listFizzBuzz(testNumbers)

The result will look like

1
cons of {"1";"2";"fizz";"4";"buzz";"fizz";"7";"8";"fizz";"buzz";"11";"fizz";"13";"14";"fizzbuzz"}

There are other collection types such as arrays and relations, (which are really cool – you can do queries on them like a database), but I haven’t explored them well enough to really talk about yet.

Actors and Speech Acts

Star has actors that use three Speech Acts: Notify, Request, and Query. The actors themselves can also be concurrent. I explored the Speech Act/ Actor model with an example from John McCarthy’s Elephant 2000 paper, which is a Airline Reservation system.

To use the notify speech act, you need to define what type the notifications are on the actors channel. In my case, the notifications are either going to be a book(string) method, or a cancel(string) method. To book a reservation for a person or cancel it.

1
type tx is book(string) or cancel(string);

The actor is defined using:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
flight((FlightName has type string), (MaxPeople has type integer)) is actor{
    var flightStatus := "open";

    setFlightStatus(s) do { flightStatus := s };

    on book(pname) on Tx do
        logMsg(info,"booking $pname on #FlightName's flight: max #MaxPeople current $(size(plist))");
    on book(pname) on Tx where size(plist) < MaxPeople do
      extend plist with pname;
    on book(pname) on Tx where size(plist) >= MaxPeople do
      logMsg(info, "sorry .. the flight is full");
    on book(pname) on Tx where flightStatus != "open" do
      logMsg(info, "sorry .. the flight is no longer open");

    on cancel(pname) on Tx do
      delete (X where X = pname) in plist;

    getPassengerList has type () => list of string;
    getPassengerList() is plist;
    }

There is some extra things in the code, but for right now, look at the book and cancel methods. These are the functions that will be called when the actor is notified like this:

1
2
3
F is flight("flight123", 5)
notify F with book("Carin") on Tx
notify F with book("Bob") on Tx

To query the actor we use :

1
 x is query F's getPassengerList with getPassengerList()

To use a request with the actor we use

1
 request F's setFlightStatus to setFlightStatus("closed")

Go Explore

I have only scratched the surface of the language, but I have had a great time. I invite you to come take a look.

Warning. Only the brave need apply. There is no StackOverflow. There is no user group or IRC channel yet. These are green fields to be discovered in the Open Source world. If it appeals to you as much as me, jump on in. Here are a few resources to get you going:

  • Star-Lang Katas: Clone the repo or fork the repos. It has a shell script to compile and run the star programs. It also has a emacs mode plugin and a reference pdf. The most important part is that it has a template of katas ready for your to solve. Your challenge: uncomment the assertion and make the code pass. My solutions are in the solutions branch when you are done. If you finish all of them and want more, consider creating some and submitting a pull request :)

  • I mentioned it earlier, but there is a great overview paper on the language itself here.

  • Finally, here is the repo of the Star Language itself https://github.com/fmccabe/star. Checkout out the tests. There are tons of sample star programs that cover the language’s features.

World Domination With Hexapods and Clojure

Published on:

Once you have your hexapod assembled and running using the hand held controller, of course, your thoughts naturally turn to world domination.

The most powerful tool in the world is the Clojure REPL

World domination requires the most powerful tools available. That of course calls for Clojure and the Clojure REPL. I recommend Emacs as the editor of choice of such an endeavor. However, it if you are content with city, state, or single country domination, other editors that support Clojure are also fine.

Connect the XBee to your computer

First, we need to get the computer to talk to the hexapod wirelessly. We can do this with a USB to Serial adapter that uses the paired XBee from the handheld commander.

Take the XBee from the handheld commander

and move it to the USB to serial adapter

Now plug the usb into your computer.

Get your Clojure ready

In your clojure project, the only magic you need is the Serial Port library. Import the library and list your serial ports. Then open the one that shows up for you.

1
2
3
4
5
6
7
8
9
(ns clj-hexapod.core
  (require [serial-port :as serial]))

;; Use this command to see what port your serial port
;; is assinged to
(serial/list-ports)

;; replace the USB0 with whater it shows
(def port (serial/open "/dev/ttyUSB0" 38400))

Since we are going to be talking to the hexapod. We need to send the commands in the same format that it is expecting. Basically, a packet of where the postions of the joystick are, as well as what buttons are pushed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(defn checksum [v]
  (mod (- 255 (reduce + v)) 256))

(defn vec->bytes [v]
  (byte-array (map #(-> % (Integer.) (.byteValue) (byte)) v)))

(defn build-packet [r-vert r-horz l-vert l-horz buttons]
  [255 ;header
   r-vert
   r-horz
   l-vert
   l-horz
   buttons
   0
   (checksum [r-vert r-horz l-vert l-horz buttons])])

(defn send [packet]
  (serial/write port (vec->bytes packet)))

From here, we can simply make functions for the joystick controls to go up and down

1
2
3
4
5
6
7
8
9
10
11
12
13
;;values between 129-254
(defn up [speed]
  "joystick up for speed between 1-100"
  (if (good-range? speed)
    (int (+ 129 (* 125 (/ speed 100.0))))
    CENTER))

;;values between 0 and 125
(defn down [speed]
  "joystick down speed between 1-100"
  (if (good-range? speed)
    (int (- 125 (* 125 (/ speed 100.0))))
    CENTER))

Then we can do things like walk, turn, and change the gait

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(defn walk-forward [speed]
  "walk forward speed between 1-100"
  (send (build-packet CENTER CENTER (up speed) CENTER 0)))

(defn walk-backwards [speed]
  "walk backwards speed between 1-100"
  (send (build-packet CENTER CENTER (down speed) CENTER 0)))

(defn walk-right [speed]
  "walk right speed between 1-100"
  (send (build-packet CENTER CENTER CENTER (up speed) 0)))

(defn walk-left [speed]
  "walk right speed between 1-100"
  (send (build-packet CENTER CENTER CENTER (down speed) 0)))

(defn turn-right [speed]
  "turn right speed between 1-100"
  (send (build-packet CENTER (up speed) CENTER CENTER 0)))

(defn turn-left [speed]
  "turn left speed between 1-100"
  (send (build-packet CENTER (down speed) CENTER CENTER 0)))

(defn change-gait [gait-key]
  (let [gait-num (gait-key gaits)]
    (send (build-packet CENTER CENTER CENTER CENTER gait-num))))

(defn stop []
  "stop hexapod"
  (send (build-packet CENTER CENTER CENTER CENTER 0)))

You can control it from the REPL with some simple commands

1
2
3
4
5
6
7
8
9
10
11
(walk-forward 20)
(walk-backwards 10)
(walk-right 10)
(walk-left 10)
(turn-right 10)
(turn-left 10)
(change-gait :ripple-smooth)
(change-gait :tripod-normal)
(change-gait :ripple)
(change-gait :amble)
(stop)

If you want to see the code, it is out on github as clj-hexapod. Please keep in mind that it is early days still, and I am still just exploring.

Phoneix Code Firmware

It is worth noting the the above code was meant to run with the default hexapod firmware. That is the “Nuke” firmware. There is another firmware, the Phoenix code, that gives the hexapod more lifelike moves and allows it to twist and shift is rather creepy ways.

I just loaded it on the hexapod yesterday. The commander software changed too, so I will of course need to revisit the code, to add in the new moves. But here is a sneak preview of what it can do:

That is my daughter singing in the background

That’s all for now

I hope I have given you pointers for getting started on your own world domination with Clojure and Hexapods. Remember to practice your laugh …. Muhahaha :)

Walking With Hexapods

Published on:
Tags: All, Robots

Here we see the PhantomX Hexapod thriving in the natural habitat of a cozy, climate controlled, modern house. But there was a time before the hexapod. In particular, there was a time of many hexapod parts and a high level software developer that somehow, despite her natural lack of mechanical skills, managed to bring it to life. This blog post endeavors to chronicle the high and low points of this journey. And perhaps, will make it easier for any other brave souls that would like to bring the Age of Hexapods into their homes.

Oh My! So Many Parts

I wasn’t really mentally prepared for the vast amounts of parts in the kit. Here is a sampling:

  • 18 AX-12A Servos
  • Top/ Bottom Body Plate
  • 20 Brackets
  • Arbotix Board
  • 2 Xbees
  • Lipo Battery & Charger
  • Arbotix programmer
  • 19 Cables
  • 50,000 nuts and screws (Really only about 850 – but you get my point)

First Things First

The very first thing to do is to make sure that you have all the parts. Once I went through the checklist and double counted all my screws, I was relieved to go onto the next task of programming the Arbotix and assign ids to servos and center them. These steps consisted of:

  • Getting the Arduino IDE going
  • Loading the Drivers and Libraries
  • Loading the ROS (Robot Operating System) on the Arbotix Board, so that it could be used to program the servos.

Each of the servos have to be assigned a number. This will let the program know which part of the leg is which, so that it will eventually – hopefully, be able to walk. Once the id is given, a sticker is labeled on the servo for future use. Centering the servos is a VERY important step not to overlook. If you do not center the servos, you will get into the unfortunate circumstance of having to dissemble the robot, cry, recenter the servos, and then reassemble the robot. Please avoid.

Putting It Together

The assembly starts with the feet and legs first. I was so pleased when I got the feet assembled, that I considered knitting little baby hexapod booties.

Next a servo and the tibia is added

Another servo and the tibia and femur is assembled

Finally, another servo and the whole leg is assembled

Newbie Advice

I would like to pause for a minute to share some advice from my trial and errors in assembly thus far:

  • Don’t overtighten screws – More is not better. It makes things like plexiglass frames crack and break.
  • Seating nuts in servos is hard – This isn’t really advice. Just moral support in your struggle. There are 18 servos and up to 20 nuts to seat in each servo.

Assembling the body

The body is where the board, battery and and cables go.

At long last, the legs can be attached to the body – with 120 screws of course.

Round two of Newbie Advice

  • For those who have never stripped wires and attached them to power supplies, like me, please mind that the wires are twisted so that the edges don’t fray out and short out everything requiring you to re-assign all the servos that lost their ids and much unscrewing, crying, and reassembling.
  • When programming the Arbotix board. You must remove the Xbee, or it will not work.
  • Also, did I mention not over-tightening screws? Also, the order in which you tighten the screws is important too. Try to tighten them all loosely in order, so you don’t stress the fiberglass parts and have something like this happen.

It is Alive!

Finally, the moment of truth. The hexapod is assembled and it is time to upload a test check on the board to make sure that everything is working alright.

It lives - the first test check of the PhantomX Hexapod

Walking with Hexapods

The kit comes with a commander that you assemble of course. You can use it to control the hexapod with hand-held joysticks.

The moment of truth, when it finally took its very first steps, and the Age of Hexapods began.

First cautious steps of running the PhantomX Hexapod with wireless controller

Stay tuned for the next post of how to control the hexapod with your Clojure code and loading the Phoenix firmware that gives it a life-like moves