View Full Version : [Project] PiAnt

01-22-2014, 03:25 AM
Hi All,

Whilst browsing the net before Christmas I came across Zenta's A-Pod and was blown away!

The more I looked and read, the more I thought "I could do that" :veryhappy:

I soon found some servos on Ebay for £5 each, so put a request in to Santa for a bag of servos, a Raspberry Pi and two Adafruit PWM drivers.

Well Christmas came and so did Santa, so I started cutting out some Aluminum sheet.

My code is based on B.E.T.H by Dan, see http://www.projectsofdan.com/?page_id=186. It has taken quite some time to get my head round this code and I had to brush up on my vector rotation, but now I have a bot that will stand and wiggle a bit (Body Translation).


As you can imagine this has been a steep learning curve and now I have many questions, here are two that are worrying me just now.

1. I now realise A-pod uses very sexy servos costing 7 times I paid for my MG996Rs. These are not as accurate as I had hoped and I seem to need separate calibration values for each servo in order to get good angular positioning. Is this calibration normal or am I barking up the wrong tree with these servos altogether?

2. I am using 1.5mm Aluminum sheet as it was all I had and my bot now weighs 2.5Kg (without a head or tail), I wondered what others weighed? Is this too much for my servos?

I'm also having trouble getting the leg to move correctly, but I'm not sure if this is the servo calibration or the code.


01-22-2014, 11:07 AM
First: That looks pretty good!

In general, yes, servos are off a little bit and you'll need a separate calibration value for each servo. This is especially true for bargain analog servos.

Hexapods with RC servos have been built and have been working, but I would not expect them to be as smooth and consistent as those built with purpose-designed robot servos. Personally, I'm not a big fan of RC-style PWM control of servos even, so I view the "robot RC servos" on the market as less desirable than serial-protocol-based servos like Dongby or Robotis. This may be some snobbery on my part, though, as clearly there exists working RC-based hexapods.

2.5 kg is not too much for a hex of this size. 1.5mm aluminum is not particularly thick, either -- you'll want to roll the edges to get sufficient rigidity in that; flat 1.5mm (which is approximately 1/16" and approximately 14 gauge) has significant sideways flex.

With three legs on the ground, each servo sees 1/3 of the weight, times the length of the thigh part of the leg. It's hard to tell from the picture, but it looks like maybe 12 cm? If so, each servo sees approximately (2.5kg * 12cm / 3 legs) == 10 kg.cm per leg. If you look up the specs for MG996R, the maximum stall torque is 10 kg.cm, so you're teetering right at the edge, which is not a good place to be. The quickest fix is likely to make the thigh bones significantly shorter. I would try cutting them in half, given the servos and weight you're using. If possible, I'd make the center body narrower and shorter, too, although this has only a secondary effect on the load seen by the knee servos (may affect ankles more.)

Btw: The torque calculations I made above are a first-order approximation, not an example of proper static load analysis :-)

01-24-2014, 05:24 AM
Hi jwatte,

Thank-you for your reply it was very helpful, every day I fire up the bot, the servos seem to find a new 'zero' position despite any previous calibrations? I'm not completely sure this is the case but it's how it feels :-(

I'm still struggling to make it walk, but I thin I'm getting closer.


01-27-2014, 01:30 PM
After adding separate calibration values for each servo I saw the IK limb solving routine appear to work for the first time today, but now I have to stop :-(

PS jwatte, the Femur are 90mm long, so (2.5 * 9) / 3 = 7.5, moving in the right direction.


02-01-2014, 11:30 AM
Still struggling with walking. I am using Dan's code and I can move each leg in turn I can translate and rotate the body (within limits) but as soon as I try to walk it all goes wrong :(

02-01-2014, 12:00 PM
I have not used Dan's code, so not sure what is going on. Also not sure from your description "It all goes wrong" what that means. Could be that you don't have a working walking gait code? Does it work if you have the body suspended so no weight on it? Does it look like it is walking OK then? If so then is there an issue with your servos not being able to support the weight when you try to lift one or more legs? Which type of gait are you trying to use? If a Tripod, then it will try to lift three legs at once, which implies the other three have to support the weight.

But I do have code that was originally written by a Lynxmotion member Xan in Basic for the Basic Atom Pro and then was extended by myself and others. I have since then converted it to C/C++ and moved it to the Arduino and later to Linux.

If you wish to look at a different codebase, It would not be difficult to adapt the Phoenix code base to your platform. I have that code running on several Linux boxes including the RPI... https://github.com/KurtE/Raspberry_Pi

Note: there are a few different versions up on that project as I am experimenting on how to build, plus experimenting with converting the fixed point math to floating point...

The thing is that I don't have a version of the servo driver for the adafruit PWM driver. Not sure if they have a servo Driver for it in C or only Python. But probably would not be hard to adapt.

Maybe it would help to see a video of the current stuff to help to see what is going on.


02-01-2014, 12:18 PM
Post a video. That could tell us tons on what is going on. I'm not sure if Dan posted a video but if he did we can compare the two.

02-01-2014, 07:21 PM
Hey Andrew, thanks for checking out my site! Sorry for the delay, i just saw this thread. Honestly, as far as I know, you're the only person who's tried to use my code so you're breaking new ground.

The good news is that it "should" work given my configuration. Here are some videos:

So the problem must lie somewhere in our hardware differences. I agree that holding the bot in the air (i use an old paint can) is a good way to baseline things and negate any moderate servo torque issues.

There are a couple places in my code that are hardware specific that might get you:
1. Of course the init.h file where all the body/leg dimensions and angles are laid out

2. in ik.cpp at the end of the legIK() function, some offsets are applied (this is really bad programming/documentation on my part):

// Applies necessary corrections to servo angles to account for hardware
for( int legNum=0; legNum<3; legNum++ ){
leg[legNum].jointAngles.coxa = leg[legNum].jointAngles.coxa;
leg[legNum].jointAngles.femur = leg[legNum].jointAngles.femur - 13.58; // accounts for offset servo bracket on femur
leg[legNum].jointAngles.tibia = leg[legNum].jointAngles.tibia - 48.70 + 13.58 + 90; //counters offset servo bracket on femur, accounts for 90deg mounting, and bend of tibia
for( int legNum=3; legNum<6; legNum++ ){
leg[legNum].jointAngles.coxa = leg[legNum].jointAngles.coxa;
leg[legNum].jointAngles.femur = -(leg[legNum].jointAngles.femur - 13.58);
leg[legNum].jointAngles.tibia = -(leg[legNum].jointAngles.tibia - 48.70 + 13.58 + 90);

These offsets "correct" the servo horn mounting angle versus the axis of the link. If for example on my bot's femur, if you draw a line between the two servo horns, the servo position zeros will not be on this line. Same with the Tibia and a line between the servo and the foot vs the servo horn. So if yours are inline, you can delete the offsets or if not adjust accordingly.

3. My controls assume that angle 0 is straight, and positive is counterclockwise looking into the horn, negative is clockwise from straight. Make sure your servos are talking the same language.

Let me know if this helps at all and let us know how it turns out.

02-07-2014, 10:02 AM
Sorry Dan, Work is really getting in the way of my play-time!!!

I'm sure you code is fine, it's just how I am applying it to my bot.

I am a little confused about one thing? You initialise all the feet to there absolute positions, then in bodyFK() you rotate each leg by the COXA_ANGLE - that has confused me a little?

I will try to get a video of the walking motion, I'm sure I just need to invert an angle somewhere...


02-08-2014, 12:51 PM
Basically in the gait/step generation each foot is thought of in leg space. This makes it so you can use the same code on every leg. After the foot position is calculated in leg space, the rotation matrix rotates the leg space using the COXA_ANGLE to translate it into body space, so that each leg is oriented properly on the body.

02-18-2014, 10:57 AM
Hi Dan, I finally got to play again.
'Servo Language'
Looking down on top a posotive angle moves the leg clockwise on all legs.

Looking at the front of the bot a positive angle move the left fema up and the right down. A posotive angle moves tje left tibia in and the right out.

Does that make any sense?


02-18-2014, 02:10 PM
Because the left and right legs on my robot (PhantomX) are mirror images of each other, (ie, not the same exact leg copied and placed around the circle), I need to invert the servo angles for one side of the robot. You can see where i do that in the bottom of the legIK() function. legs 1-3 have different polarities than legs 4-6.

I suspect your robot is using the exact same legs all around in which case you need to NOT flip the servo angles. If that's the case, then just delete the leg4-6 case and make the 1-3 case cover 1-6. You might have to still flip the coxa servos though assuming all your coxa servos are facing up.

Edit: looking at your pic, your legs do seem to be mirrored left/right. Its strange then that its behaving as if the same angles are being sent to all servos. Think that through i guess.