Main parameters
The basic structure of the YAML files is a set of ROS parameters, lists that define the sensors to use, and the sensor definitions themselves. The top-level of the YAML is the definition of the node name /EkfCalNode
and a ROS2-specific implementation for ros__parameters
. Structuring the yaml in this way allows the node to utilize these parameters. The sim_params
section includes parameters that are only relevant to the simulation. The main simulation and node parameters are as follows
/EkfCalNode:
ros__parameters:
debug_log_level: 2
data_logging_on: true
data_log_rate: 10.0
augmenting_type: 0
augmenting_delta_time: 0.
augmenting_pos_error: 0.1
augmenting_ang_error: 0.1
process_noise:
pos: 1.0e-0
vel: 1.0e-1
ang_pos: 1.0e-0
pos_l_in_g: [0.0, 0.0, 0.0]
ang_l_to_g: 0.0
gps_init_type: 0
gps_init_baseline_dist: 100.0
gps_init_pos_thresh: 1.0
gps_init_ang_thresh: 0.1
use_root_covariance: true
sim_params:
seed: 0.0
use_seed: true
max_time: 10.0
number_of_runs: 10
run_number: 0
stationary_time: 0.1
truth_type: "cyclic"
pos_frequency: [0.3, 0.5, 0.7]
ang_frequency: [0.2, 0.3, 0.4]
pos_offset: [0.0, 0.0, 0.0]
ang_offset: [0.0, 0.0, 0.0]
ang_amplitude: 0.1
pos_amplitude: 1.0
pos_b_in_l_error: [0.5, 0.5, 0.5]
ang_b_to_l_error: [0.3, 0.3, 0.3]
positions:
- [0.0, 0.0, 0.0]
- [0.1, 0.1, 0.1]
- [-0.1, -0.1, -0.1]
- [0.0, 0.0, 0.0]
angles:
- [0.00, 0.00, 0.00]
- [0.01, 0.01, 0.01]
- [0.00, 0.00, 0.00]
pos_errors: [1.0, 1.0, 1.0]
ang_errors: [0.1, 0.1, 0.1]
pos_l_in_g_error: [1.0, 1.0, 1.0]
ang_l_to_g_error: 0.1
Sensors and parameters can be dynamically declared with a bit of tomfoolery. To achieve this, we must read from a known list to the declare and read unknown lists. Therefore, the following lists must exist, but can be empty. These define the parameter sections for each of their respective categories. Ensure that each of the sensors used in a configuration are declared here and defined later:
/EkfCalNode:
ros__parameters:
...
imu_list:
- "imu_1"
camera_list:
- "cam_1"
tracker_list:
- "orb"
fiducial_list:
- "charuco"
gps_list:
- "gps_1"
IMU parameters
The following is an example of an IMU input configuration.
/EkfCalNode:
ros__parameters:
...
imu:
imu_1:
is_extrinsic: false
is_intrinsic: false
rate: 1000.0
topic: "/imu_1"
variance: [
0.01, 0.01, 0.01,
0.01, 0.01, 0.01,
0.01, 0.01, 0.01,
0.01, 0.01, 0.01
]
pos_i_in_b: [0.0, 0.0, 0.0]
ang_i_to_b: [1.0, 0.0, 0.0, 0.0]
acc_bias: [0.0, 0.0, 0.0]
omg_bias: [0.0, 0.0, 0.0]
pos_stability: 1.0e-2
ang_stability: 1.0e-2
acc_bias_stability: 1.0e-3
omg_bias_stability: 1.0e-3
data_log_rate: 10.0
sim_params:
no_errors: false
time_bias_error: 1.0e-3
time_error: 1.0e-6
pos_error: [0.0, 0.0, 0.0]
ang_error: [0.0, 0.0, 0.0]
acc_error: [1.0e-3, 1.0e-3, 1.0e-3]
omg_error: [1.0e-2, 1.0e-2, 1.0e-2]
acc_bias_error: [0.0, 0.0, 0.0]
omg_bias_error: [0.0, 0.0, 0.0]
Camera parameters
The following is an example of an camera input configuration.
/EkfCalNode:
ros__parameters:
...
camera:
cam_1:
rate: 20.0
topic: "/cam_1"
pos_c_in_b: [0.0, 0.0, 0.0]
ang_c_to_b: [-0.5, 0.5, -0.5, 0.5]
variance: [
0.1, 0.1, 0.1,
0.1, 0.1, 0.1
]
tracker: "orb"
fiducial: "charuco"
pos_stability: 1.0e-9
ang_stability: 1.0e-9
data_log_rate: 10.0
intrinsics:
f_x: 0.01
f_y: 0.01
k_1: 0.0
k_2: 0.0
p_1: 0.0
p_2: 0.0
pixel_size: 5.0e-6
width: 1920
height: 1080
is_extrinsic: false
sim_params:
no_errors: false
time_bias_error: 1.0e-3
time_error: 1.0e-6
pos_error: [0.0, 0.0, 0.0]
ang_error: [0.0, 0.0, 0.0]
Tracker parameters
The following is an example of a tracker input configuration.
/EkfCalNode:
ros__parameters:
...
tracker:
orb:
feature_detector: 2
descriptor_extractor: 1
descriptor_matcher: 0
detector_threshold: 10.0
pixel_error: 0.5
min_feature_distance: 1.0
min_track_length: 2
max_track_length: 20
sim_params:
no_errors: false
feature_count: 500
room_size: 5.0
Fiducial parameters
The following is an example of a fiducial input configuration.
/EkfCalNode:
ros__parameters:
...
fiducial:
charuco:
fiducial_type: 1
squares_x: 5
squares_y: 7
square_length: 0.04
marker_length: 0.02
id: 0
pos_f_in_l: [5.0, 0.0, 0.0]
ang_f_to_l: [1.0, 0.0, 0.0, 0.0]
variance: [
0.1, 0.1, 0.1,
0.1, 0.1, 0.1
]
min_track_length: 0
max_track_length: 1
is_extrinsic: false
sim_params:
no_errors: false
pos_error: [0.0, 0.0, 0.0]
ang_error: [0.0, 0.0, 0.0]
t_vec_error: [1.0e-2, 1.0e-2, 1.0e-2]
r_vec_error: [1.0e-2, 1.0e-2, 1.0e-2]
GPS parameters
The following is an example of a GPS input configuration.
/EkfCalNode:
ros__parameters:
...
gps:
gps_1:
rate: 5.0
topic: "/gps_1"
pos_a_in_b: [0.0, 0, 0]
variance: [5.0, 5.0, 5.0]
data_log_rate: 5.0
is_extrinsic: false
sim_params:
no_errors: false
time_bias_error: 0.0
time_error: 1.0e-9
lla_error: [5.0, 5.0, 5.0]
pos_a_in_b_err: [0.0, 0.0, 0.0]
Parameter Adjustment
As with most Kalman Filter tunings the two primary knobs to turn are the measurement and process noise variables.
The measurement noise should be set to the sensor manufacturer's specified value if it has not yet been verified. Ideally, depending on the sensor, a calibration routine should be performed to find a more accurate measurement noise value.
The process noise can be harder to tune, especially when balancing such a large number of filter states, as is the case with ekf_cal
. In simulation, one can make use of the NEES plots that are produced to determine if the filter is being efficient in its estimations. The process noise should be changed to roughly keep the NEES within the specified confidence interval.
Finally, depending on the setup, it can be difficult to determine what is driving low filter performance. In complex cases, it is easiest to disable entire sensors or disable a sensors extrinsic/intrinsic calibration in steps in order to determine which is driving the largest errors.