Nanica.io Talk: A Raspberry Pi Hexy — Transcript
Delivered at PYCONPH — University of the Philippines Cebu. February 27, 2016
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 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 feeback loop comprising a position sensor, a control circuit, and a regular dc motor.
Hexy has 19 servos, one for each joint which allows you to control each of its 19 joints independently.
My 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 bi-peds 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.
Aside from PEP8, PEP20, refactoring and good names, here are two basic guidelines I keep in mind whenever I write code.
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 trigonomteric 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 negligble 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 Hip(), Knee(), 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 hip, knee and 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.