nmayorov / pyins

A Python package for Inertial Navigation Systems modeling and analysis
MIT License
79 stars 29 forks source link

EstimationModel args #21

Open chrisflesher opened 1 month ago

chrisflesher commented 1 month ago

I was having a bit of trouble figuring out how exactly to initialize EstimationModel from values listed on a spec sheet. Maybe adding some examples / units would help?

My gyro specs are:

bias_stability: 0.05 [°/hr]
bias_time_constant: 900 [s]
angle_random_walk: 0.012 [°/√hr]
sample_rate: 100 [1/s]

The EstimationModel requires the following fields:

bias_sd, Am guessing this means the standard deviation of the initial bias when you first turn on the sensor? Just want to verify the units would be [rad/s]? noise, bias_walk, The current documentation seems pretty clear on these, just double-checking the units would be [rad/s^0.5] and [rad/s^1.5] respectively?

Does something like this look correct for how to initialize the model from the above spec sheet values?

EstimationModel(
    bias_sd=math.sqrt(bias_time_const/2.) * bias_stability * pyins.transform.DH_TO_RS,
    noise=angle_random_walk * pyins.transform.DRH_TO_RRS,
    bias_walk=bias_stability * pyins.transform.DH_TO_RS * math.sqrt(sample_rate))
nmayorov commented 1 month ago

Maybe adding some examples / units would help?

This is indeed somewhat tricky. But as I've used a single class for both gyro and accel models the only reasonable option seems to be using SI units. I'll try to include units/conversions hints into the docstring.

bias_sd, Am guessing this means the standard deviation of the initial bias when you first turn on the sensor? Just want to verify the units would be [rad/s]?

Yes, the meaning is as you said, the units are rad/s and m/s/s for gyros and accels.

noise, bias_walk, The current documentation seems pretty clear on these, just double-checking the units would be [rad/s^0.5] and [rad/s^1.5] respectively?

Yes, absolutely correct.

Does something like this look correct for how to initialize the model from the above spec sheet values?

EstimationModel(
    bias_sd=math.sqrt(bias_time_const/2.) * bias_stability * pyins.transform.DH_TO_RS,
    noise=angle_random_walk * pyins.transform.DRH_TO_RRS,
    bias_walk=bias_stability * pyins.transform.DH_TO_RS * math.sqrt(sample_rate))

This is more tricky I'd say. There is certainly a gap between how actual sensors work and what is a reasonable model to use in estimation filters (of course we can use exact models in modelling scenarios, which pyins is frankly mainly suited for).

For practical filters I typically start with the following question: what it the bias variation over typical time of filter operation? Say the typical time of operation is 1 hour and you've measured that the bias statistically changes by about 10 deg/hour after 1 hour of operation (in Allan deviation sense), then it's reasonable to set bias_walk=10 * DH_TO_RS / 60 (10 deg/hour/root-hour) and then perhaps increase this parameter based on performance metrics.

In your case something like bias_walk=bias_stability * pyins.transform.DH_TO_RS / 60 would be more reasonable to start with I'd say. Obviously take that with a grain of salt, but unless your are working with high-end sensors it's unlikely that you want to go deep into super precise statistical models of their operation.

Another thing is that if you have strong reasons to believe that the bias behaves as exponentially correlated random process (what you've hinted with bias_sd) it is possible to implement such bias model in pyins. I haven't included it for simplicity, but it's not difficult.


Hope you find it somehow helpful.

chrisflesher commented 1 month ago

Thank you very much for the insight into how to set parameters.

Yes I was trying to model bias_sd as an exponentially correlated random process. But may try a more emperical approach as you're suggesting.

For bias walk I think you are correct the above equation doesn't work (the units aren't even correct!). I have a new guess of bias_walk=bias_stability * pyins.transform.DH_TO_RS / math.sqrt(bias_time_constant) where bias_time_constant is where the trough (minimum) is on an Allan deviation plot. Maybe with worst case temperature changes my gyro has 1deg/hr drift which would be 1 * pyins.transform.DH_TO_RS / 30. This seems somewhat similar as your answer of 10 * pyins.transform.DH_TO_RS / 60. Any additional thoughts here?