How I practiced clean code and made a hexapod robot dance at the same time.
Delivered at Python Conference Philippines 2016— University of the Philippines, Cebu. February 27, 2016 (Transcript)
Hi everyone. I am Mithi.
This is Hexy.
Hexy’s frame is designed and open-sourced by ArcBotics.
You can download it from Github and have it cut from a flat sheet of acrylic by any lazer cutting service provider.
You can screw the parts together with readily available 3m screws and nuts.
My modified Hexy uses 9-gram metal geared micro servo motors as plastic gears and carbon gears are prone to be overloaded by Hexy’s weight.
A servo is a type of motor whose output shaft goes to a desired angular position and stays there.
It does this via a feedback loop comprising a position sensor, a control circuit, and a regular dc motor.
Hexy has nineteen servos, one for each joint which allows you to control each of its nineteen joints independently.
My modified Hexy does all its computing on board in this tiny computer called a Raspberry Pi Zero.
It’s pretty powerful for a computer that retails for 5 U.S. dollars and around 2/3 the size of a credit card.
I used two Adafruit 16-Channel PWM drivers chained together to drive the servos since the Raspberry Pi Zero’s not capable of sending 19 individual control signals directly.
The Raspberry Pi Zero communicates with the drivers via a widely-used two-wire communication protocol called the I2C.
To understand how to move a six-legged robot, let’s examine how simple bipeds like human beings walk.
Basically, we perform alternating “strides” with the left and right sides of our body.
A stride goes like this:
- First, lift one leg off the ground, then push that side of the body forward as the opposite side retracts.
- After that, swing the lifted leg forward, and finally fall forward for that leg to contact the ground.
You can modify and play around this “stride algorithm” to produce awesome moves for Hexy.
One of my main motivations in writing Hexy’s code from the ground up is because I wanted to get better at writing cleaner code.
In his book Clean Code, Robert Martin says that a person reads her own code at least 10x more than she writes it, and countless hours are lost because of poorly written code.
This is why it is not enough that code functions, it should also be clean.
For me, clean code has the following qualities:
- One, it performs as expected and as required
- Two, it is easy to understand, reuse, modify, maintain, and extend
- And three, it contains everything it needs and nothing that it doesn’t.
More importantly, clean code is achieved because the one who wrote it cared enough to write it well.
Writing clean code is hard, but I know I get better at it by listening to the wisdom of veteran coders and by writing more code with cleanliness in mind.
One is that sometimes, the best code is no code at all. Less code almost always means fewer potential bugs.
The original code contains threading locks everywhere, but I realized that I didn’t need them at all. The original code also used trigonometric functions so that the foot followed a smooth sinusoidal curve.
However, when I showed Hexy walking to my friends, Hexy walking with a curved foot fall algorithm and a linear foot fall algorithm, nobody noticed the difference. Because the linear footfall is simpler and the difference was negligible I used that in my code.
The other guiding principle is that my classes and methods should follow what is also known as the single responsibility principle.
They say that the first rule when writing methods is that they should be small. The second rule is that they should be smaller than that.
Similarly, the first rule of writing classes is that they should be small, and the second rule is that they should be smaller than that.
We measure the size of methods with physical lines. We measure the size of classes with its responsibilities.
A class should have one and only one job. All its methods is there to fulfill its purpose. If it has only one job, it should be simple enough to describe in one simple sentence.
The original walk algorithm was hard-coded like this.
The code in the left is walking forward, the code in the right is walking backward.
I refactored it by removing duplication with the use of a few helper methods and now it looks like this which I think is easier to read.
Consequently, I can now use it like this, which is really convenient!
The original code contained a
Hexapod class, a
Neck class and a
Leg class. The
Leg class contained around a dozen methods, and some of them I don’t think belonged there.
Particularly, there were three functions called
Ankle(), which does practically the same thing which the
neck does — positioning the servo.
I deleted the
Neck class and created a more general
Joint class. I deleted the three aforementioned methods and instantiated three
Joint objects named
ankle instead which made more sense.
I’ve written a rather lengthy documentation of this project, if you want to know more check: http://hexyrobot.wordpress.com
Anyway, I hope I didn’t bore you too much. To end this talk, I hope you enjoy this video of Hexy dancing.