Inverse kinematic of the body

The inverse kinematics of the body is to transform pitch, roll and rotation into offsets for the x, y and z coordinate of a leg.

Definitions

\(l\) length of the body

\(w\) width of the body

\(pitch\) desired pitch

\(roll\) desired roll

\(rotation\) desired rotation

\(rotation\) desired rotation

\(m_{x}\) leg movement x

\(m_{y}\) leg movement y

\(m_{z}\) leg movement z

\(x\) x position of a leg relative to the center

\(z\) z position of a leg relative to the center

Pitch

The calculations for pitch are as follows: $$m_{x} = \frac{l(1-\cos(pitch))}{2}$$ $$m_{y} = \frac{l\sin(pitch)}{2}$$

Roll

The calculations for roll are as follows: $$m_{z} = \frac{w(1-\cos(roll))}{2}$$ $$m_{y} = \frac{w\sin(roll)}{2}$$

Rotation

The calculations for rotation are based on a rotation matrix. These calculations are as follows:

$$m_{x} = (x \times \cos(rotation) - z \times \sin(rotation)) - x$$ $$m_{z} = (x \times \sin(rotation) + z \times \cos(rotation)) - z$$

Combining Calculations

To combine these calculations you just calculate each one separately and then calculate the sum of all x calculations, then the sum of all y calculations and finally the sum of all z calculations.

Code

After transforming these calculations into code, we get this:

def calc_leg_offsets(leg, pitch, roll, rotation):
    # Get the X and Z coordinate of the leg
    x = (body_length / 2) if leg < 2 else -(body_length / 2)
    z = -(body_width / 2) if leg == 0 or leg == 3 else (body_width / 2)
    # Calculate the height difference of the leg to reach the target pitch
    height_diff_pitch = x * sin(radians(pitch))
    # Calculate the height difference of the leg to reach the target roll
    height_diff_roll = z * sin(radians(roll))
    # Calculate the X and Z offsets to keep the body centered
    movement_x_pitch = x * (1 - cos(radians(pitch)))
    movement_z_roll = z * (1 - cos(radians(roll)))
    # Calculate the rotation offsets
    movement_x_rotation = (x * cos(radians(rotation)) - z * sin(radians(rotation))) - x
    movement_z_rotation = (x * sin(radians(rotation)) + z * cos(radians(rotation))) - z
    # Merge the offsets and return them
    return (
        movement_x_pitch + movement_x_rotation,
        height_diff_pitch - height_diff_roll,
        movement_z_roll + movement_z_rotation
    )