Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-EKF support #14650

Merged
merged 76 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from 71 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
c36c016
ekf2: Multi-EKF support
dagar Sep 4, 2020
558eab1
ekf2: add EKF2_SEL_ERR_RED to configure selector error reduction thre…
dagar Sep 7, 2020
baf1582
ekf2: add gyro difference checking to selector
priseborough Sep 9, 2020
68f89f4
ekf2 selector param metadata and minor style fixes
dagar Sep 15, 2020
11d9fde
ekf2: selector only check gyros on sensors_status_imu update
dagar Sep 16, 2020
fe2fde0
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 16, 2020
3f373cf
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 17, 2020
91b69a9
ekf2: selector move gyro inconsistency check to updateErrorScores() a…
dagar Sep 17, 2020
41551d9
ekf2: selector consolidate publish and reset logic
dagar Sep 17, 2020
74e2a0d
ekf2: selector log accumualted gyro error
dagar Sep 17, 2020
250d4a8
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 17, 2020
ce0ae64
increase ORB_MULTI_MAX_INSTANCES 4 -> 9 and EKF2 max instances 4 -> 6
dagar Sep 17, 2020
ebe0505
sensors: calculate sensor differences relative to mean
priseborough Sep 17, 2020
3434b2b
msg: update sensor_status_imu comments to reflect calculation wrt mean
priseborough Sep 17, 2020
3b61a42
ekf2: modify ekf selector for changed sensor_status_imu msg
priseborough Sep 17, 2020
f9a40a6
msg: add accel error data to estimator_selector_status
priseborough Sep 18, 2020
6a078ac
ekf2: Add accel difference checking to ekf selector and update parame…
priseborough Sep 18, 2020
9ab7381
ekf2: selector code style and fix param metadata type
dagar Sep 18, 2020
68a0fcb
ekf2: selector log _accel_fault_detected
dagar Sep 18, 2020
6e49e82
sensors: IMU inconsistency don't include disabled accels and gyros
dagar Sep 18, 2020
7ecf0fb
ekf2: selector prevent republishing old position estimtes (possible o…
dagar Sep 18, 2020
2868069
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 18, 2020
786ed8e
logger limit multi instances
dagar Sep 18, 2020
54daa22
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 20, 2020
88db500
simulator: Add third IMU
priseborough Sep 20, 2020
9d617c6
ROMFS: Add third IMU to posix build
priseborough Sep 20, 2020
cb6aa19
ekf2 simplify multi-startup
dagar Sep 20, 2020
2c5688c
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 21, 2020
029f439
ekf2 multi testing changes (enable on fmu-v5 and durandal)
dagar Sep 21, 2020
1f3bbec
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 21, 2020
1dff9c8
Jenkins hardware estimator_selector_status
dagar Sep 21, 2020
d6f8d15
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 22, 2020
bcdfbd4
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 23, 2020
91606e2
fmu-v5 ekf2 multi IMU only, Cube orange ekf2 multi IMU & MAG
dagar Sep 23, 2020
b9d786b
boards adjust multi-ekf testing parameters (enable on px4_fmu-v4pro, …
dagar Sep 24, 2020
214d161
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 24, 2020
d99b1be
ekf2 add trylock for status
dagar Sep 24, 2020
25fa8e5
[WIP] Tools/ecl_ekf multi-support (not finished)
dagar Sep 24, 2020
34a58ad
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 25, 2020
410a19c
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 26, 2020
9430513
logger topics minor
dagar Sep 26, 2020
1d7f19e
Update submodule nuttx to latest Sat Sep 26 15:30:26 UTC 2020
PX4BuildBot Sep 26, 2020
d4ec8e3
add system command to get and set system time
baumanta Sep 26, 2020
ba9a271
Update submodule ecl to latest Sat Sep 26 15:30:31 UTC 2020
PX4BuildBot Sep 26, 2020
21640f5
Update submodule mavlink v2.0 to latest Sat Sep 26 15:30:19 UTC 2020
dagar Sep 26, 2020
2ddd0ac
ekf2 multi disable if flash constrianed and re-publish odometry
dagar Sep 26, 2020
54f3a9b
ekf2 multi fix lockstep and extend Tools/ecl_ekf to process all insta…
dagar Sep 26, 2020
6fb5502
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 28, 2020
76656c9
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 28, 2020
9459f9a
init.d-posix rcS fix SENS_IMU_MODE
dagar Sep 28, 2020
92c0740
cdev posix increase devmap 128 -> 256
dagar Sep 28, 2020
c9e700c
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 28, 2020
f3cb418
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 28, 2020
15abfe7
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Sep 28, 2020
64df921
revert EKF2 multi enabled by default for testing
dagar Sep 28, 2020
a1a949b
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 5, 2020
867f792
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 6, 2020
0c009d0
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 7, 2020
e2cc2a4
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 13, 2020
89dc5c5
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 13, 2020
50b357d
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 13, 2020
c427f93
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 18, 2020
fb3d4e5
ekf2: selector add max instances static assert
dagar Oct 18, 2020
88d0239
up to 4 accels and gyros are supported now
dagar Oct 18, 2020
d21e469
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 21, 2020
e336dae
ekf2: selector fix delta_q_reset
dagar Oct 21, 2020
f690f54
SITL enable multi-ekf by default
dagar Oct 21, 2020
8cff5d5
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 21, 2020
19305c5
simulator: only send controls after components finish
dagar Oct 9, 2020
40e6cc9
ekf2 selector only print primary EKF change if unhealthy
dagar Oct 22, 2020
cc9319a
Merge remote-tracking branch 'px4/master' into pr-ekf2_selector
dagar Oct 26, 2020
d0a7dca
ROMFS: posix rcS disable multi-ekf
dagar Oct 27, 2020
cf71520
uORB revert debug changes
dagar Oct 27, 2020
00e9254
logger: reduce default mult-ekf and sensor logging to save memory
dagar Oct 27, 2020
eb23306
px4_work_queue: reduce wq:nav_and_controllers stack
dagar Oct 27, 2020
44c1d81
Jenkins hardware print all estimator attitude and position messages, …
dagar Oct 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .ci/Jenkinsfile-hardware
Original file line number Diff line number Diff line change
Expand Up @@ -846,14 +846,14 @@ void statusFTDI() {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "dataman status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "df"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "dmesg"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "ekf2 status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "free"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "gps status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener adc_report"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener battery_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener cpuload"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener estimator_sensor"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener estimator_selector_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener estimator_sensor_bias"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener estimator_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener logger_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener sensor_accel"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "listener sensor_accel_fifo"'
Expand Down Expand Up @@ -901,6 +901,7 @@ void statusFTDI() {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "uorb top -1 -a"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "ver all"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "work_queue status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "ekf2 status"'
// stop logger
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-FTDI_*` --cmd "logger off"'
}
Expand All @@ -919,12 +920,12 @@ void statusSEGGER() {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "dataman status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "df -h"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "dmesg"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "ekf2 status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "free"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "gps status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener adc_report"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener battery_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener cpuload"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener estimator_selector_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener estimator_sensor_bias"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener estimator_status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "listener logger_status"'
Expand Down Expand Up @@ -974,6 +975,7 @@ void statusSEGGER() {
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "uorb top -1 -a"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "ver all"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "work_queue status"'
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "ekf2 status"'
// stop logger
sh './Tools/HIL/run_nsh_cmd.py --device `find /dev/serial -name *usb-SEGGER_*` --cmd "logger off"'
}
Expand Down
6 changes: 6 additions & 0 deletions ROMFS/px4fmu_common/init.d-posix/rcS
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ then
# Speedup SITL startup
param set EKF2_REQ_GPS_H 0.5

# Multi-EKF
param set EKF2_MULTI_IMU 3
param set SENS_IMU_MODE 0
param set EKF2_MULTI_MAG 2
param set SENS_MAG_MODE 0

# By default log from boot until first disarm.
param set SDLOG_MODE 1
# enable default, estimator replay and vision/avoidance logging profiles
Expand Down
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.airship_apps
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ else
# EKF2
#
param set SYS_MC_EST_GROUP 2
ekf2 start
ekf2 start &
fi
fi

Expand Down
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.fw_apps
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#
# Start the attitude and position estimator.
#
ekf2 start
ekf2 start &

#
# Start attitude controller.
Expand Down
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.mc_apps
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ else
# EKF2
#
param set SYS_MC_EST_GROUP 2
ekf2 start
ekf2 start &
fi
fi

Expand Down
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.rover_apps
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#
# Start the attitude and position estimator.
#
ekf2 start
ekf2 start &
#attitude_estimator_q start
#local_position_estimator start

Expand Down
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.uuv_apps
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Begin Estimator Group Selection #
###############################################################################

ekf2 start
ekf2 start &

###############################################################################
# End Estimator Group Selection #
Expand Down
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.vehicle_setup
Original file line number Diff line number Diff line change
Expand Up @@ -199,5 +199,5 @@ fi
if [ $VEHICLE_TYPE = none ]
then
echo "No autostart ID found"
ekf2 start
ekf2 start &
fi
2 changes: 1 addition & 1 deletion ROMFS/px4fmu_common/init.d/rc.vtol_apps
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# Begin Estimator group selection #
###############################################################################

ekf2 start
ekf2 start &

###############################################################################
# End Estimator group selection #
Expand Down
22 changes: 10 additions & 12 deletions Tools/ecl_ekf/analyse_logdata_ekf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
from analysis.post_processing import get_estimator_check_flags

def analyse_ekf(
ulog: ULog, check_levels: Dict[str, float], red_thresh: float = 1.0,
amb_thresh: float = 0.5, min_flight_duration_seconds: float = 5.0,
ulog: ULog, check_levels: Dict[str, float], multi_instance: int = 0,
red_thresh: float = 1.0, amb_thresh: float = 0.5, min_flight_duration_seconds: float = 5.0,
in_air_margin_seconds: float = 5.0, pos_checks_when_sensors_not_fused: bool = False) -> \
Tuple[str, Dict[str, str], Dict[str, float], Dict[str, float]]:
"""
:param ulog:
:param check_levels:
:param multi_instance:
:param red_thresh:
:param amb_thresh:
:param min_flight_duration_seconds:
Expand All @@ -30,22 +31,19 @@ def analyse_ekf(
"""

try:
estimator_states = ulog.get_dataset('estimator_states').data
print('found estimator_states data')
estimator_states = ulog.get_dataset('estimator_states', multi_instance).data
except:
raise PreconditionError('could not find estimator_states data')
raise PreconditionError('could not find estimator_states instance', multi_instance)

try:
estimator_status = ulog.get_dataset('estimator_status').data
print('found estimator_status data')
estimator_status = ulog.get_dataset('estimator_status', multi_instance).data
except:
raise PreconditionError('could not find estimator_status data')
raise PreconditionError('could not find estimator_status instance', multi_instance)

try:
_ = ulog.get_dataset('estimator_innovations').data
print('found estimator_innovations data')
_ = ulog.get_dataset('estimator_innovations', multi_instance).data
except:
raise PreconditionError('could not find estimator_innovations data')
raise PreconditionError('could not find estimator_innovations instance', multi_instance)

try:
in_air = InAirDetector(
Expand All @@ -71,7 +69,7 @@ def analyse_ekf(

metrics = calculate_ecl_ekf_metrics(
ulog, innov_flags, innov_fail_checks, sensor_checks, in_air, in_air_no_ground_effects,
red_thresh=red_thresh, amb_thresh=amb_thresh)
multi_instance, red_thresh=red_thresh, amb_thresh=amb_thresh)

check_status, master_status = perform_ecl_ekf_checks(
metrics, sensor_checks, innov_fail_checks, check_levels)
Expand Down
19 changes: 9 additions & 10 deletions Tools/ecl_ekf/analysis/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
def calculate_ecl_ekf_metrics(
ulog: ULog, innov_flags: Dict[str, float], innov_fail_checks: List[str],
sensor_checks: List[str], in_air: InAirDetector, in_air_no_ground_effects: InAirDetector,
red_thresh: float = 1.0, amb_thresh: float = 0.5) -> Tuple[dict, dict, dict, dict]:
multi_instance: int = 0, red_thresh: float = 1.0, amb_thresh: float = 0.5) -> Tuple[dict, dict, dict, dict]:

sensor_metrics = calculate_sensor_metrics(
ulog, sensor_checks, in_air, in_air_no_ground_effects,
Expand All @@ -22,9 +22,9 @@ def calculate_ecl_ekf_metrics(
innov_fail_metrics = calculate_innov_fail_metrics(
innov_flags, innov_fail_checks, in_air, in_air_no_ground_effects)

imu_metrics = calculate_imu_metrics(ulog, in_air_no_ground_effects)
imu_metrics = calculate_imu_metrics(ulog, multi_instance, in_air_no_ground_effects)

estimator_status_data = ulog.get_dataset('estimator_status').data
estimator_status_data = ulog.get_dataset('estimator_status', multi_instance).data

# Check for internal filter nummerical faults
ekf_metrics = {'filter_faults_max': np.amax(estimator_status_data['filter_fault_flags'])}
Expand All @@ -44,10 +44,10 @@ def calculate_ecl_ekf_metrics(

def calculate_sensor_metrics(
ulog: ULog, sensor_checks: List[str], in_air: InAirDetector,
in_air_no_ground_effects: InAirDetector, red_thresh: float = 1.0,
amb_thresh: float = 0.5) -> Dict[str, float]:
in_air_no_ground_effects: InAirDetector, multi_instance: int = 0,
red_thresh: float = 1.0, amb_thresh: float = 0.5) -> Dict[str, float]:

estimator_status_data = ulog.get_dataset('estimator_status').data
estimator_status_data = ulog.get_dataset('estimator_status', multi_instance).data

sensor_metrics = dict()

Expand Down Expand Up @@ -131,10 +131,9 @@ def calculate_innov_fail_metrics(
return innov_fail_metrics


def calculate_imu_metrics(
ulog: ULog, in_air_no_ground_effects: InAirDetector) -> dict:
def calculate_imu_metrics(ulog: ULog, multi_instance, in_air_no_ground_effects: InAirDetector) -> dict:

estimator_status_data = ulog.get_dataset('estimator_status').data
estimator_status_data = ulog.get_dataset('estimator_status', multi_instance).data

imu_metrics = dict()

Expand All @@ -158,7 +157,7 @@ def calculate_imu_metrics(
in_air_no_ground_effects, np.mean)

# IMU bias checks
estimator_states_data = ulog.get_dataset('estimator_states').data
estimator_states_data = ulog.get_dataset('estimator_states', multi_instance).data

imu_metrics['imu_dang_bias_median'] = np.sqrt(np.sum([np.square(calculate_stat_from_signal(
estimator_states_data, 'estimator_states', signal, in_air_no_ground_effects, np.median))
Expand Down
18 changes: 8 additions & 10 deletions Tools/ecl_ekf/plotting/pdf_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from analysis.detectors import PreconditionError
import analysis.data_version_handler as dvh

def create_pdf_report(ulog: ULog, output_plot_filename: str) -> None:
def create_pdf_report(ulog: ULog, multi_instance: int, output_plot_filename: str) -> None:
"""
creates a pdf report of the ekf analysis.
:param ulog:
Expand All @@ -29,20 +29,18 @@ def create_pdf_report(ulog: ULog, output_plot_filename: str) -> None:
# save the plots to PDF

try:
estimator_status = ulog.get_dataset('estimator_status').data
print('found estimator_status data')
estimator_status = ulog.get_dataset('estimator_status', multi_instance).data
except:
raise PreconditionError('could not find estimator_status data')
raise PreconditionError('could not find estimator_status instance', multi_instance)

try:
estimator_states = ulog.get_dataset('estimator_states').data
print('found estimator_states data')
estimator_states = ulog.get_dataset('estimator_states', multi_instance).data
except:
raise PreconditionError('could not find estimator_states data')
raise PreconditionError('could not find estimator_states instance', multi_instance)

try:
estimator_innovations = ulog.get_dataset('estimator_innovations').data
estimator_innovation_variances = ulog.get_dataset('estimator_innovation_variances').data
estimator_innovations = ulog.get_dataset('estimator_innovations', multi_instance).data
estimator_innovation_variances = ulog.get_dataset('estimator_innovation_variances', multi_instance).data
innovation_data = estimator_innovations
for key in estimator_innovation_variances:
# append 'var' to the field name such that we can distingush between innov and innov_var
Expand All @@ -65,7 +63,7 @@ def create_pdf_report(ulog: ULog, output_plot_filename: str) -> None:
for key in innovation_data:
innovation_data[key] = innovation_data[key][0:innovation_data_min_length]

print('found innovation data (merged estimator_innovations + estimator_innovation_variances)')
print('found innovation data (merged estimator_innovations + estimator_innovation_variances) instance', multi_instance)

except:
raise PreconditionError('could not find innovation data')
Expand Down
68 changes: 44 additions & 24 deletions Tools/ecl_ekf/process_logdata_ekf.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,21 @@ def process_logdata_ekf(
except:
raise PreconditionError('could not open {:s}'.format(filename))

ekf_instances = 1

try:
estimator_selector_status = ulog.get_dataset('estimator_selector_status',).data
print('found estimator_selector_status (multi-ekf) data')

for instances_available in estimator_selector_status['instances_available']:
if instances_available > ekf_instances:
ekf_instances = instances_available

print(ekf_instances, 'ekf instances')

except:
print('could not find estimator_selector_status data')

try:
# get the dictionary of fail and warning test thresholds from a csv file
with open(check_level_dict_filename, 'r') as file:
Expand All @@ -100,30 +115,35 @@ def process_logdata_ekf(
raise PreconditionError('could not find {:s}'.format(check_level_dict_filename))

in_air_margin = 5.0 if sensor_safety_margins else 0.0
# perform the ekf analysis
master_status, check_status, metrics, airtime_info = analyse_ekf(
ulog, check_levels, red_thresh=1.0, amb_thresh=0.5, min_flight_duration_seconds=5.0,
in_air_margin_seconds=in_air_margin)

test_results = create_results_table(
check_table_filename, master_status, check_status, metrics, airtime_info)

# write metadata to a .csv file
with open('{:s}.mdat.csv'.format(filename), "w") as file:

file.write("name,value,description\n")

# loop through the test results dictionary and write each entry on a separate row, with data comma separated
# save data in alphabetical order
key_list = list(test_results.keys())
key_list.sort()
for key in key_list:
file.write(key + "," + str(test_results[key][0]) + "," + test_results[key][1] + "\n")
print('Test results written to {:s}.mdat.csv'.format(filename))

if plot:
create_pdf_report(ulog, '{:s}.pdf'.format(filename))
print('Plots saved to {:s}.pdf'.format(filename))

for multi_instance in range(ekf_instances):

print('\nestimator instance:', multi_instance)

# perform the ekf analysis
master_status, check_status, metrics, airtime_info = analyse_ekf(
ulog, check_levels, multi_instance, red_thresh=1.0, amb_thresh=0.5, min_flight_duration_seconds=5.0,
in_air_margin_seconds=in_air_margin)

test_results = create_results_table(
check_table_filename, master_status, check_status, metrics, airtime_info)

# write metadata to a .csv file
with open('{:s}-{:d}.mdat.csv'.format(filename, multi_instance), "w") as file:

file.write("name,value,description\n")

# loop through the test results dictionary and write each entry on a separate row, with data comma separated
# save data in alphabetical order
key_list = list(test_results.keys())
key_list.sort()
for key in key_list:
file.write(key + "," + str(test_results[key][0]) + "," + test_results[key][1] + "\n")
print('Test results written to {:s}-{:d}.mdat.csv'.format(filename, multi_instance))

if plot:
create_pdf_report(ulog, multi_instance, '{:s}-{:d}.pdf'.format(filename, multi_instance))
print('Plots saved to {:s}-{:d}.pdf'.format(filename, multi_instance))

return test_results

Expand Down
1 change: 1 addition & 0 deletions msg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ set(msg_files
esc_status.msg
estimator_innovations.msg
estimator_optical_flow_vel.msg
estimator_selector_status.msg
estimator_sensor_bias.msg
estimator_states.msg
estimator_status.msg
Expand Down
22 changes: 22 additions & 0 deletions msg/estimator_selector_status.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
uint64 timestamp # time since system start (microseconds)

uint8 primary_instance

uint8 instances_available

uint32 instance_changed_count
uint64 last_instance_change

uint32 accel_device_id
uint32 baro_device_id
uint32 gyro_device_id
uint32 mag_device_id

float32[9] combined_test_ratio
float32[9] relative_test_ratio
bool[9] healthy

float32[4] accumulated_gyro_error
float32[4] accumulated_accel_error
bool gyro_fault_detected
bool accel_fault_detected
Loading