Replies: 3 comments 5 replies
-
I wouldn't expect any drift in the acceleration data. Can you elaborate? There may be a small nonzero stationary value due to imperfect alignment of the sensor in the casing, but I suppose you could subtract this.
You can measure angular velocity (rotation), but not linear velocity (translation).
Can you elaborate on the objective? Is it an independent homework problem? Or is it to improve driving a robot? Is it to estimate distance? Could the wheel speed be used to estimate the speed? |
Beta Was this translation helpful? Give feedback.
-
|
Thanks a lot, @Debenben and @laurensvalk for your feedback and input! @Debenben thank you for sharing your script for calibration. I was also trying to do something similar a while ago but it was much less sophisticated and only subtracted the offset when noticing that the hub was stationary. I will give your version a try and let you know! @laurensvalk This is a really good idea I will try it as well! |
Beta Was this translation helpful? Give feedback.
-
|
Since we have better imu functions and calibration routines in pybricks now it should be a lot easier to do this integration more accurately now. In case anyone wants to give it a try, this is what I came up with: """
Proof-of-Concept for estimating movement along X-Axis from acceleration measurements.
Concept and notation based on en.wikipedia.org/wiki/Kalman_filter.
Time is measured in Seconds, distance in Millimenters.
State x = (coordinate position, coordinate velocity, coordinate acceleration).
"""
from pybricks.hubs import ThisHub
from pybricks.parameters import Axis
from pybricks.tools import Matrix, vector
hub = ThisHub() # use TechnicHub or Prime/InventorHub
if hub.imu.settings()[4] == (9806.65, -9806.65, 9806.65, -9806.65, 9806.65, -9806.65):
print("Hub is not calibrated; Starting calibration!")
import _imu_calibrate
def invert2x2(M): # returns inverse of matrix M
a = M[0,0]
b = M[0,1]
c = M[1,0]
d = M[1,1]
return 1/(a*d - b*c)*Matrix([[d, -b], [-c, a]])
# parameters:
dt = 0.0011 # time between measurements = duration of while loop iteration. 0.0011 for TechnicHub 0.0008 for Prime/InventorHub.
sigma = 63 # uncertainty of measured coordinate acceleration z
variance = 1617 # variance of change of z
a_g = 9806.65 # gravity
a_thresh = 60 # acceleration change threshold for stationary detection
a_count = 10 # acceleration number threshold for stationary detection
I = Matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) # unit matrix
F = Matrix([[1, dt, 0.5*dt**2], [0, 1, dt], [0, 0, 1]]) # state transistion matrix
Q = variance*dt*I # uncorrelated noise
#Q = variance*Matrix([[0.25*dt**4, 0.5*dt**3, 0.5*dt**2], [0.5*dt**3, dt**2, dt], [0.5*dt**2, dt, 1]]) # piecewise white noise
# initialize values:
x_post = vector(0, 0, 0) # initial state
P_post = sigma*I # initial covariance
a_last = vector(0, 0, 0) # last measured acceleration value
stationary = 0 # count accelerations below threshold
count = 0 # count loop iterations
while True:
count += 1
# prediction:
x_pred = F*x_post
P_pred = F*P_post*F.T + Q
# measurement:
a = hub.imu.acceleration()
O = hub.imu.orientation()
if abs(a - a_last) < a_thresh:
stationary += 1
else:
stationary = 0
a_last = a
if stationary > a_count:
# hub is stationary -> coordinate acceleration and velocity measured as 0
H = Matrix([[0, 0, 1], [0, 1, 0]])
z = vector(0, 0)
S = H*P_pred*H.T + sigma*Matrix([[1, 0], [0, 1]])
K = P_pred*H.T*invert2x2(S)
else:
# hub is moving -> coordinate acceleration measured as z
H = vector(0, 0, 1).T
z = (H*O*a_g - a.T)[0]
S = H*P_pred*H.T + sigma
K = P_pred*H.T*S**(-1)
# correction:
x_post = x_pred + K*(z - H*x_pred)
P_post = (I - K*H)*P_pred
if count%100 == 0:
# coordinate position, coordinate velocity, coordinate acceleration
print(f"{x_post[0]:+09.2f}, {x_post[1]:+09.2f}, {x_post[2]:+09.2f}")
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hey,
I'm currently working on a project where I need to accurately estimate the velocity of the Prime Hub based on its IMU acceleration data, specifically from imu.acceleration(Axis.X). Despite my efforts, I'm finding it challenging to obtain a reliable estimate due to the inherent noise and drift present in the acceleration data. While I've managed to mitigate the noise to some extent using a moving average filter, the drift remains a significant obstacle, leading to unreasonable and wrong results.
Does anyone have experience or advice on effectively compensating for the drift in IMU acceleration data or is there a direct method to obtain velocity data from the Prime Hub that I may have overlooked?
Any insights or advice would be greatly appreciated.
Thank you in advance for your help!
Beta Was this translation helpful? Give feedback.
All reactions