IT... Y-axis Movement
Huh? Another degree of freedom? The Y-axis!
Yep, another degree of freedom! This time, it's to move the foot in the y-axis, or away from the sides of the body. The math for this stage is trigonometry again, however it is a bit more complex that before. This time, I'm going to use 2 diagrams to explain the math:
Diagram 1: | Diagram 2: |
Inputs/outputs:
Length A | Y Input |
Length B: | Output |
Length D | Z Input |
First, take a look at Digram 1. There are two things that need to be solved for: length B, which is the demand shoulder-foot length, and θ, which is the angle that needs to be sent to the motor to achieve the Y-axis input (specified by length A). To solve for B, you can take advantage of the two triangles that are formed; use A and D to solve for C with the pythagorean theorem: C = √(A2 + D2). C is the hypotenuse of another right triangle, so the pythagorean theorem can be used again: B = √(C2 - E2). Don't forget the E is constant (it is the actual length of the motor to the shoulder.
Now, here comes the tricky part. The method used to solve for B applies in all cases, but solving for θ is somewhat case-dependent. Firstly, note that I've defined the "𝟎" position of the foot (when A = 𝟎) to be under the bearing. When the foot is at 𝟎, it is actually tilted, and to get to be straight, A must equal E. For diagram 2 to apply, A is actually defined as a negative value. Now, let's start: I'll initially be refering to diagram 1. First, solve for angle a (I refer to this as theta in my code). This can be accomplished by any trigonometric function (since all sides are known and C considers the other lengths appropriately) but I chose to use tangent: tan(a) = ( A / D ) , or a = tan-1( A / D ). Now, skip over to solve for b (note that I call this alpha in my code). b can be solved easily with cosine: b = cos-1( E / C ). This is the part that requires insight: angles a and b add up to form an angle which (in the case of diagram 1) is greater than 90°; the part not covered by the 90° angle formed by the yellow lines is θ. When A becomes less than E, however, (a + b) is less than 90°; in this case, θ = 90° - (a + b). Isn't that cool?
So what if A is less than 𝟎? Refer to diagram 2: notice that a and b overlap (and don't worry, b will always be greater than a... yes, I checked) and θ now partly forms the 90° angle. In this case, θ = 90° - (b - a). Both cases can be summed up like here:
If A > 0: | θ = abs(90° - (b + a)) |
If A < 0 | θ = abs(90° - (b - a)) |
If A < E: | θ = -1 ✖️ θ |
Here's the end result!
But there is one more thing to consider: what happenns to B? Well, B is simply passed on to the other stages of the program as the z-axis input. It gets inputted into the stage that considers the x-axis, which outputs its own z-axis to the final stage that calculates the z-axis motor angles. This can be done because B is the x-axis output on a new, tilted plane ( if A is ever specified, the whole leg tilts inward right?); the Y plane. All other stages lie on this plane.
Confusing? That's because it is. This entire stage took me nearly a month of designing, only to find out that my algorithms were wrong. This design I crunched out on a Tuesday night after finishing my Calculus homework. Soon, I'll have another post will all my failed ideas; why they didn't work, or why I abandoned them (I had a really cool idea involving tangent lines and derivatives).
Anyway, here's the code. Note that I refer to a as theta and b as alpha, and I've created a function solveFootPosition
to organize all the stages/calculations.
The big stuff from this post is held in solveYMove
.
Problems... so far:
So far, no problems! I've tested this many times, with different x, y, and z positions and the math has been correct every time (I can check with a ruler to see if my x, y, and z inputs are considered accordingly). I'm really proud of this setup, and hopefully it won't fail me in the future!