Previously, I calculated the axis of orientation based on anatomical structures, such as the toes in a paw.
But I found that this doesn't work when I can't distinguish between the toes very well or if the 'heel' (blue square) is way off. So I decided to look for better alternatives and I decided to try and calculate the inertial axis.
This page gives a great explanation of how to calculate it, but I have trouble understanding the steps of getting from the Center of Mass (or pressure in my case) to an angle.
The explanation boils it down to: which uses the Center of Pressure and a value p, of which I don't know what it is.
I had access to the Matlab code that calculated this axis for human feet and did my best to translate it to Python:
x = 0.508 # sensor size in the x-direction
y = 0.762 # sensor size in the y-direction
Ptot = 0 # total pressure
Px = 0 # first order moment(x)
Py = 0 # first order moment(y)
Pxx = 0 # second order moment (y)
Pyy = 0 # second order moment (x)
Pxy = 0 # second order moment (xy)
for row in range(rows): # y-direction
for col in range(cols): # x-direction
if data[row,col] > 0.0: # If not zero
temp = 1
else:
temp = 0
Ptot = Ptot + temp # Add 1 for every sensor that is nonzero
Px = Px + (x * col + x / 2) * temp
Py = Py + (y * row + y / 2) * temp
Pxx = Pxx + (x * y * y * y / 12 + x * y * (row * y + y / 2) * (row * y + y / 2) ) * temp
Pyy = Pyy + (y * x * x * x / 12 + x * y * (col * x + x / 2) * (col * x + x / 2) ) * temp
Pxy = Pxy + (x * y * (row * y + y / 2) * (row * x + x / 2)) * temp
CoPY = Py / Ptot
CoPX = Px / Ptot
CoP = [CoPX, CoPY]
Ixx = Pxx - Ptot * self.x * self.y * CoPY * CoPY
Iyy = Pyy - Ptot * self.x * self.y * CoPX * CoPX
Ixy = Pxy - Ptot * self.x * self.y * CoPY * CoPX
angle = (math.atan(2 * Ixy / (Iyy - Ixx))) / 2
Ixp = Ixx * math.cos(angle) * math.cos(angle) + Iyy * math.sin(angle) * math.sin(angle) - 2 * Ixy * math.sin(angle) * math.cos(angle)
Iyp = Iyy * math.cos(angle) * math.cos(angle) + Ixx * math.sin(angle) * math.sin(angle) + 2 * Ixy * math.sin(angle) * math.cos(angle)
RotationMatrix = [[math.cos(angle), math.sin(angle)], [-math.sin(angle), math.cos(angle)]]
So as far as I understood it, sin(angle) and cos(angle) from RotationMatrix are used to determine the axis. But I don't really understand how to use these values to draw an axis through the paw and rotate it around it.
Any idea what I'm doing wrong and/or what I should do to solve it?
If someone feels the need to experiment, here's a file with all the sliced arrays that contain the pressure data of each paw. To clarfiy: walk_sliced_data is a dictionary that contains ['ser_3', 'ser_2', 'sel_1', 'sel_2', 'ser_1', 'sel_3'], which are the names of the measurements. Each measurement contains another dictionary, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (example from 'sel_1') which represent the impacts that were extracted.