Open JacopoPan opened 4 years ago
Yes, that is still the case. And is definitely something worth contributing to via a PR.
If you need help / feedback on the implementation, let's chat on this thread.
Hi, I am implementing an EKF-based state estimator in AirSim simple_flight as described in the issue above (using 4 sensors) as part of my Master's Thesis at TUM and IABG. My implementation is still in a very early phase, however, I would much appreciate your feedback. Here is the branch to the forked repository: https://github.com/subedisuman/AirSim/tree/ekf. I am looking forward to your comments and hope my developments will be beneficial for the AirSim community.
Hi @subedisuman! That's great to hear. I will take a look at your fork when having time. I would love to see this becoming a PR.
In the following branch, I have implemented an Extended Kalman Filter (EKF) based state estimator as a part of my Master Thesis. It uses the following sensor measurements: IMU, GPS, Barometer, and Magnetometer to estimate the following states: local (NED) x-y-z positions, x-y-z velocities, attitudes, and IMU and barometer sensor biases. I have documented the changes I made below. There is also a demo to try things out and see results in plots :). I have tested it using Linux (Ubuntu 20.04.4 LTS) build of AirSim and UE 4.25. I would say it is content-wise complete and would appreciate your comments and remarks to help make improvements and run tests and validations. I would also like to know the next steps towards a pull request. Thanks :).
msr/airlib
namespace.msr/airlib
to simple_flight
and vice versa.simple_flight
namespace.geodetic2Ned()
used in EKF to convert GPS output to NED co-ordinates.is_new_
flag as a state variable that is set false before a sensor is updated and is set true if a valid output is generated. Also see IMU, GPS, Barometer, and Magnetometer models.is_new_ = True
whenever an output is produced. Added additional parameters and GPS random white noise. Added IMU turn-on bias as parameters.kinematics.twist.linear.norm() > approx_zero_vel_
check in takeoff()
.resetVehicleApi()
that resets a vehicle api. Used to reset EKF of the vehicle.additional settings:
{
"SettingsVersion": 1.2,
"SimMode": "Multirotor",
"Recording": {
"RecordInterval": 0.1,
"Cameras": []
},
"DefaultSensors": {
"Barometer": {
"SensorType": 1,
"Enabled": true,
"PressureFactorSigma": 0.001825,
"PressureFactorTau": 3600,
"UncorrelatedNoiseSigma": 2.7,
"UpdateLatency": 0,
"UpdateFrequency": 50,
"StartupDelay": 0
},
"Imu": {
"SensorType": 2,
"Enabled": true,
"AngularRandomWalk": 0.3,
"GyroBiasStabilityTau": 500,
"GyroBiasStability": 4.6,
"VelocityRandomWalk": 0.24,
"AccelBiasStabilityTau": 800,
"AccelBiasStability": 36,
"AccelTurnOnBiasX": 0, // m/s^2
"AccelTurnOnBiasY": 0, // m/s^2
"AccelTurnOnBiasZ": 0, // m/s^2
"GyroTurnOnBiasX": 0, // deg/s
"GyroTurnOnBiasY": 0, // deg/s
"GyroTurnOnBiasZ": 0 // deg/s
},
"Gps": {
"SensorType": 3,
"Enabled": true,
"EphTimeConstant": 0.9,
"EpvTimeConstant": 0.9,
"EphInitial": 25,
"EpvInitial": 25,
"EphFinal": 0.1,
"EpvFinal": 0.1,
"EphMin3d": 3,
"EphMin2d": 4,
"SigmaLong": 0.00003, // longitude random noise standard deviation (deg)
"SigmaLat": 0.00003, // latitude random noise standard deviation (deg)
"SigmaAlt": 1.0, // altitude random noise standard deviation (m)
"SigmaVelX": 0.1, // gps velocity random noise standard deviation (m/s)
"SigmaVelY": 0.1, // gps velocity random noise standard deviation (m/s)
"SigmaVelZ": 0.1, // gps velocity random noise standard deviation (m/s)
"UpdateLatency": 0,
"UpdateFrequency": 10,
"StartupDelay": 0
},
"Magnetometer": {
"SensorType": 4,
"Enabled": true,
"NoiseSigma": 0.005,
"ScaleFactor": 1,
"NoiseBias": 0,
"UpdateLatency": 0,
"UpdateFrequency": 50,
"StartupDelay": 0
}
},
"EkfSetting": {
"Enabled": true,
"GpsFusion": true,
"BaroFusion": true,
"MagnetoFusion": true,
"Imu": { // imu random error standard deviations
"AccelErrorStdDevX": 0.1, // m/s^2
"AccelErrorStdDevY": 0.1, // m/s^2
"AccelErrorStdDevZ": 0.1, // m/s^2
"GyroErrorStdDevX": 0.2, // deg/s
"GyroErrorStdDevY": 0.2, // deg/s
"GyroErrorStdDevZ": 0.2 // deg/s
},
"Gps": { // gps random error standard deviations
"PositionErrorStdDevX": 4.0, // m
"PositionErrorStdDevY": 4.0, // m
"PositionErrorStdDevZ": 4.0, // m
"VelocityErrorStdDevX": 0.2, // m/s
"VelocityErrorStdDevY": 0.2, // m/s
"VelocityErrorStdDevZ": 0.2 // m/s
},
"Barometer": { // barometer altitude random error standard deviation
"PositionErrorStdDevZ": 2.0 // m
},
"Magnetometer": { // magnetometer magnetic flux random error standard deviations
"MagFluxErrorStdDevX": 0.01, // Gauss
"MagFluxErrorStdDevY": 0.01, // Gauss
"MagFluxErrorStdDevZ": 0.01 // Gauss
},
"PseudoMeasurement": { // R matrix for Quaternion normalization
"QuaternionNormR": 0.000001
},
"InitialStatesStdErr": { // standard deviations of initial states errors
"PositionX": 6.0, // m
"PositionY": 6.0, // m
"PositionZ": 6.0, // m
"LinearVelocityX": 1.0, // m/s
"LinearVelocityY": 1.0, // m/s
"LinearVelocityZ": 1.0, // m/s
"QuaternionW": 0.05,
"QuaternionX": 0.05,
"QuaternionY": 0.05,
"QuaternionZ": 0.05,
"AccelBiasX": 0.1, // m/s^2
"AccelBiasY": 0.1, // m/s^2
"AccelBiasZ": 0.1, // m/s^2
"GyroBiasX": 1, // deg/s
"GyroBiasY": 1, // deg/s
"GyroBiasZ": 1, // deg/s
"BaroBias": 1 // m
},
"InitialStatesErr": { // initial states errors
"PositionX": 0.0, // m
"PositionY": 0.0, // m
"PositionZ": 0.0, // m
"LinearVelocityX": 0.0, // m/s
"LinearVelocityY": 0.0, // m/s
"LinearVelocityZ": 0.0, // m/s
"AttitideRoll": 0.0, // deg
"AttitidePitch": 0.0, // deg
"AttitideYaw": 0.0, // deg
"AccelBiasX": 0, // m/s^2
"AccelBiasY": 0, // m/s^2
"AccelBiasZ": 0, // m/s^2
"GyroBiasX": 0, // deg/s
"GyroBiasY": 0, // deg/s
"GyroBiasZ": 0, // deg/s
"BaroBias": 0.0 // m
}
}
}
(Optional but recommended): install the local airsim client. There is an additional resetVehicleApi()
that resets vehicle and thus EKF if required.
"EkfSetting": {
"Enabled": true, // true to use ekf estimated states in other components, else use ground truth
"GpsFusion": true, // true to fuse gps measurements
"BaroFusion": true, // true to fuse barometer measurement
"MagnetoFusion": true // true to fuse magnetometer measurements
}
client.reset()
here, I hit the failResetUpdateOrdering("Multiple reset() calls detected without call to update()");
here, of one of the sensors due to two consecutive resets without update. There is, however, a hint that this check could be redundant.I get the following error as a result of the Github actions for Windows build:
Build FAILED.
"D:\a\AirSim\AirSim\AirSim.sln" (default target) (1) ->
"D:\a\AirSim\AirSim\AirLibUnitTests\AirLibUnitTests.vcxproj" (default target) (11) ->
(ClCompile target) ->
D:\a\AirSim\AirSim\AirLibUnitTests\main.cpp : fatal error C1128: number of sections exceeded object file format limit: compile with /bigobj [D:\a\AirSim\AirSim\AirLibUnitTests\AirLibUnitTests.vcxproj]
0 Warning(s)
1 Error(s)
There is already a solution mentioned, but I am not sure about this.
Thank you very much @subedisuman, for the detailed update. You are doing an excellent job! Keep it up!
Hi @jonyMarino. Thank you for your kind remarks. Regarding the recent announcement to close the support for this repository, I wonder how it affects this potential pull request? I would love to get your feedback regarding this issue and the new strategy. The current implementation can make use of the AirSim imu, gps, barometer, and magnetometer sensor signals to compute and use estimated states based on configurable EKF parameters. Ongoing work-in-progress is to test the implementation. If possible, I would also love to get your feedbacks regarding the functionality, the implementation, the procedures to test it, and the next steps regarding the potential pull request. Thank you.
Is this
still the case (I would believe so, by looking at AirSimSimpleFlightEstimator.hpp) and then something that might be worthwhile contributing to?