Inverse kinematics

Been trying to understand inverse kinematics for programming my quadruped Crap-Crab. I started out by reading Wikipedia's version, which lost me completely (WTF?). But then I found the explanation by this guy and it turns out, as I thought to begin with, that it's simply a matter of applied trigonometry.

Here is exactly what I need in a nutshell:

inverse2.jpg

inverse3.jpg


There are some things that I’m wondering about though. For starters it bothers me that it doesn’t say where the actuators’ zero positions are at.  Can anyone help me understand this?

Also I presume the angles are in radians, which would mean that you’re actually working with angles in 3 different units:

(1) Radians (0 - 2*PI): for the math.
(2) Microseconds (1000 - 2000): for the servos.
(3) Degrees (0 - 180): because they make sense to people (atleast I find them more intuitive :slight_smile:

Is this a reasonable way of viewing it? All advice from someone who has made this work would be welcome.

The zero position is at 0°

The zero position is at 0° here – you have to adjust it for how your servos are actually positioned.

You work with radians, and then convert those to milliseconds just before sending to the servo (adjusted for its initial position, its range and trim), and to degrees just before displaying in any logs.

There is more than one way of calculating IK for a leg like this. For instance, I use this:

def _solve_triangle(a, b, c):
“”“Calculate an angle of a triangle using the law of cosines.”""
a, b, c = abs(a), abs(b), abs(c)
if a + b < c or a + c < b or b + c < a:
raise ValueError(“Impossible triangle: %r, %r, %r % (a, b, c))
cos = float(a 2 + b 2 - c 2) / (2 a b)
return math.acos(cos)


def _length(a, b):
“”“Calculate the length of a vector.”""
return math.sqrt(a 2 + b ** 2)

[…]

def _inverse_kinematics(self, (x, y, z)):
“”“Calculate the 3 angles of the leg, in degrees.”""
f = _length(x, y) - self.coxa
d = min(self.femur + self.tibia, _length(f, z))
hip = math.atan2(y, x)
knee = _solve_triangle(self.femur, d, self.tibia) - math.atan2(-z, f)
ankle = _solve_triangle(self.femur, self.tibia, d)
knee = -math.degrees(knee)
ankle = math.degrees(ankle) - 90
hip = math.degrees(hip) + self.hip_offset
return hip, knee, ankle

You can see I used degrees here, for easier debugging, but I convert it all to microseconds anyways before sending to the servo.
For me, the “zero” position of the servo is with coxa at 45° from the body, femur horizontal and tibia vertical – that’s why ankle and hip need offsets. That’s also when all the servos are at 90°.

There is an image illustrating my thinking with this formula:

Hey deshipu, thanks for

Hey deshipu, thanks for replying :wink:

First off… when I wrote “zero positions” I meant 0°, so the frase “The zero position is at 0°…” makes little sense. Just to make sure we’re understanding eachother.

However it seems we do cause then you write "For me, the “zero” position of the servo is with coxa at 45° from the body, femur horizontal and tibia vertical – that’s why ankle and hip need offsets. That’s also when all the servos are at 90°."

That is what I was talking about. And it would seem we have the same idea about the servo angles. Just to make sure I make this quick and dirty MS Paint drawing:

angles.jpg

I think that is what you meant too?

Anyway so I gather that the servo angles (as I feared) are not the same as the angles used in the kinematics calculations. For instance when the tibia-femur servo is at 90° then BETA is actually at 0°. Correct? If so doesn't this create problems for example if the servo is at 45° then BETA is -45°?

Sorry if my questions seem silly. While I do understand the theory of this I do have a hard time wrapping my head around the practical implementation. Hmm.. I think I'll make a 3D model and apply the math to that before doing it with my bot.

Ah and I'll take a closer look at your Python code a bit later...

The “zero” position of my

The “zero” position of my robot is exactly how you showed, and from the articles and code that I saw around, this seems to be the standard (hexapods tend to have the legs at right angles from the body, not at 45° though). Just a small note, that you should be looking at the angles between the centers of joints and the ends of legs – in my case, for example, tibia is the line from the center of the last servo, to ground – since the “foot” of the robot is glued to the side of the servo, the servo itself is a little bit diagonal, so that the foot touches the floor exactly under the center of the joint. It’s the same with measuring the distances later on – you always measure to the center of the joint, or the end of the leg, in a straight line. Also, I made my servo library so that it takes angles from -90° to +90° with 0 being in the middle – so it actually is the “zero position” in my case (simplified, it just sends 1500+a×10µs pulse to the servo).

Now, the “zero” position of the “virtual” robot that your inverse kinematics calculate, with all angles at 0°, would have tibia folded along femur, femur vertical pointing down, and coxa at a right angle from the body (depending whether x or y is along the body). So you have to add some offsets and maybe also reverse the directions.

Please remember that, since all the servos of the same type turn in the same direction, but the legs are mirror images of each other, you will need to reverse the angles on every other leg anyways! Also, decide how you want your x and y to be – relative to the body, or relative to the leg. You will want some parameters on the legs that tell you in which direction it sticks out from the body anyways, so that you can both move them closer or farther to the body, but also all of them to the left or to the right (then legs on one side move closer, on the other move farther).

By the way, here is an

By the way, here is an OpenSCAD model of the leg of my robot, which you can use for experiments. You just call it with the parameters for hip, knee and ankle angles (in degrees): https://bitbucket.org/thesheep/ukubik/src/tip/scad/leg.scad

(it doesn’t have the ankle servo trimmed for properly vertical tibia though)

Hey guys thanks a lot for

Hey guys thanks a lot for your input. I’ll need a bit of time to digest it all and ponder…

For the 3D model I was

For the 3D model I was thinking to make an application using some 3D engine or similar. The idea is to make an application that is in communication with the Arduino via serial and shows the same movements on the screen as is being executed by the robot simultaneously. I don’t want the 3D model to be a copy of the actual robot. I actually just want to show the limbs as lines, the joints as dots, the body as a circle and perhaps the surface plane as a grid. Simple!

I like the idea of using Python and I’m currently checking out the game/3D-engine called Panda3D, which works with Python. So since you’re also into Python I thought I might ask if you’ve tried out that one?

From what I gather it’s possible to create the model from scratch with code using primitives such as lines and circles. But I’m thinking perhaps the better option would be to import a model (made in some other program, perhaps this OpenScad) and use some provided means of skeletal animation (which I have no idea how to do right now).

Any experience with this?

No experience there, I hate

No experience there, I hate 3D generally. OpenScad does what I need to do in a relatively non-painful way, so I stuck with it.

I was considering Visual Python, and (very briefly) Blender, because it’s scripted in Python. In the end OpenScad had the lowest barrier to entry and solved my immediate problem. I might revisit Visual Python at some point, though.

By the way, for testing of the actual gaits it would be nice to also have a physics engine. Especially if you plan to make learning or evolutionary algorithms – you could use the simulation for speeding up the process, so that the actual physical robot starts with something already workable.

OK!Well I have some

OK!

Well I have some experience with 3D/game-engines, though not a whole lot. But I find that they provide a simple way of creating graphics applications with good performance, even if they are not games. The last engine I played with was DarkGDK (with Visual C++ Express), which among other things I used to create this serial oscilloscope. But it doesn’t seem like it’s being well supported anymore (atleast the free version) and besides I would like to avoid the hassle of C and use something quicker like Python for now. But I might eventually go back to C due to performance, which is why Panda3D seemed like a good option, because it works with BOTH Python and C++.

Regarding the physics engince then YUP I was thinking the same thing. Could be a great asset. I’m currently checking out this Visual Python that you mentioned (I suppose you mean VPython?). It apparently has a physics engine too, and definately seems easier to get started with that Panda3D. So thanks for the tip…

That’s why they invented

That’s why they invented Linear Algebra. It simplifies things a lot. Start learning LA before doing IK in 3D or even 2D. All tutorials about IK I have seen and worthy to read using vector notations.

Could you be a bit more

Could you be a bit more specific? Why did they invent LA? What exactly does it simplify? Why in this context do you think it’s useful/necessary?

I actually did study linear algebra, but the thing about math and me is that I forget it quicker than I learn it unless I USE IT. So this project is also a way for me to really learn some of the things I have previously “learned” just to pass an exam and later forgot.

Hmmm… Allthough I would

Hmmm… Allthough I would have liked a bit more info from MarkusB I think he did have a point. I was also thinking about using vectors and HOW. To represent the limbs? the movements of fixpoints (and if so then which)? OR indeed both? After googling some more I see that you can also use vectors to represent the axis of the servo, which I don’t see the point of at all :confused:

Oh well gotta keep reading…

 

You won’t need linear

You won’t need linear algebra for the individual leg, but it will come in handy when you want to move the leg relative to other things than its base. For instance, you will want to move the leg in an arc arund the center of the robot to have it turn in place. Or you witll want to rotate and tilt the robot’s body. Then it’s much easier to simply use a matrix to convert from one coordinate system to another, relative to the (rotated) robot’s body.

Picture

Thanks for posting the picture. It would be easier for me to communicate if the angles were named in computer language notation.

I don’t think it matters much if you call it geometry, trigonometry, vectors, or linear algebra. They are all tools to help you analyze the problem and formulate a solution. I suspect the choice is very much dependent on your background, associates, and willingness to experiment with different methodologies.

Question for group: These equations are relative to the center of rotation of the hip joint. Don’t we need to account for the center or zero point of the whole beast?

My hexapod never worked well and I have taken it apart for upgrades and not yet put it back together. Perhaps this project will inspire me to get going. Please continue to publish results and make me feel envious.

I still think it may be

I still think it may be advantageous to use vectors to represent the leg segments, as well as the movements, even though it’s not necessary. But I’m still not sure.

And like Duane and Deshipu both mentioned I too think it’s necessary to operate with several “coordinate systems”. I think the following would be a minimum:

(1) The “world” (i.e. the cartessian space in which the critter moves).
(2) One relative to the (center of?) the robot which is needed to coordinate the movements of the legs in conjunction.
(3) One relative to each leg which is needed for calculating the individual leg’s movements.

Perhaps it’s even better to operate with a “coordinate system” for each joint/leg segment?

Another thought… In the drawing above (and many others I’ve seen) the only end point is the foot §. But wouldn’t it be necessary to operate with another end point, namely where the leg is attached to the body? I mean sometimes this is the point you wish to move, e.g. when you want the body of the robot to tilt, twist or sway in order to move the center of gravity of the robot, which is necessary (for quadrupeds) before lifting a leg.

BTW here is another article about IK that may be of interest. Also the PDF from which I got the drawing and formulas in the topic description has a large chapter about Kinematics in general before mentioning IK. Still haven’t understood it well. Perhaps you’ll have better luck.

You get the other point for

You get the other point for free from the same formulas, because the position of the end of leg relative to the base of the leg is the same, except reversed, as the position of the base of the leg relative to the end of the leg. You just flip the signs.

Hey deshipu,I don’t quite

Hey deshipu,

I don’t quite understand how you’d use a matrix to convert from one system to another. Could you elaborate on that?

Just thought I’d share this

Just thought I’d share this amazing PDF. It should be interesting to everyone who’s into walking machines. It was named as source 1 in the PDF I mentioned earlier, from which I got the drawing and formulas in the topic description.

Now this new PDF actually doesn’t touch the subject of IK, BUT it has a very thorough explanation of forward kinematics, including translation from one system to another, using a rotation matrix.

Ah in both PDF’s they use the word “frame”. From what I gather this word is used to describe what we so far have called the individual coordinate systems (e.g. world, robot, leg). Is this a correct assumption?

Besides that this PDF has a lot of interesting info. For instance:

“Theoretically the total number of possible gait event sequences for a quadruped is 5040, but only a very small portion of them are suitable as gaits and used by animals…”

“Of all 5040 different possible gaits for quadrupeds, there are only 6 that allow the animal to have three legs in ground contact at all times. McGhee, and Frank (1968) showed, under somewhat restrictive conditions, that three of these six gaits were statically instable and one, the crawl gait, maximizes the stability margin…”

:smiley:

This looks interesting,

This looks interesting, thank you!

Ah BTW I found this math API

Ah BTW I found this math API for Python. It does vector/matrix-math very well apparently. Check it out…