10 KiB
Batch Evaluation of Square Root Optimization and Marginalization
In this tutorial we detail how you can use the batch evaluation scripts to reproduce the results of the ICCV'21 paper Demmel et al., "Square Root Marginalization for Sliding-Window Bundle Adjustment". In the paper we discuss how square root estimation techniques can be used in Basalt's optimization-based sliding-window odometry to make optimization faster and marginalization numerially more stable. See the project page for further details.
Basalt's VIO/VO now runs with single-precision floating point numbers
by default, using the new square root formulation. The conventional
squared (Hessian-based) formualtion is still available via config
options. For manual testing, you can pass --use-double true
or
--use-double false
(default) as command line arguments to
basalt_vio
, and change config.vio_sqrt_marg
in the config file,
which controls if the marginalization prior is stored in Hessian or
Jacobian form (default: true
), as well as
config.vio_linearization_type
in the config file, which controls
whether to use Schur complement, or nullspace projection and
QR-decomposition for optimization and marginalization ("ABS_SC"
or
"ABS_QR"
(default)).
In the following tutorial we systematically compare the different formulations in single and double precision to reproduce the results from the ICCV'21 paper. You can of course adjust the correspondig config files to evaluate other aspects of the system.
Prerequisites
- Source installation of Basalt: The batch evaluation scripts
by default assume that the
build
folder is directly inside the source checkoutbasalt
. See README.md for instructions. - Downloads of the datasets: We evaluate EuRoC (all 11
sequneces), TUMVI (euroc format in 512x512 resultion; sequences:
corridor1-2, magistrale1-2, room1-2, slides1-2), and Kitti
Odometry (sequences 00-10). It's recommended to store the data
locally on an SSD to ensure that reading the images is not the
bottleneck during evaluation (on a multicore desktop Basalt runs
many times faster than real-time). There are instructions for
downloading these dataset: EuRoC,
TUMVI,
KITTI. Calibration for EuRoC and TUMVI is
provided in the
data
folder. For KITTI you can use thebasalt_convert_kitti_calib.py
script to convert the provided calibration to a Basalt-compatible format (see KITTI). - Dependencies of evaluation scripts: You need pip packages
py_ubjson
,matplotlib
,numpy
,munch
,scipy
,pylatex
,toml
. How to install depends on your Python setup (virtualenv, conda, ...). To just install for the local user with pip you can use the commandpython3 -m pip install --user -U py_ubjson matplotlib numpy munch scipy pylatex toml
. For generating result tables and plots you additionally need latexmk and a LaTeX distribution (Ubuntu:sudo apt install texlive-latex-extra latexmk
; macOS with Homebrew:brew install --cask mactex
).
Folder Structure
The batch evaluation scripts and config files assume a certain folder structure inside a "parent" folder, since relative paths are used to find the compiled executable and calibration files. So it's important to follow the folder structure.
parent-folder/
├─ basalt/
│ ├─ build/
│ │ ├─ basalt_vio
│ │ ├─ ...
│ ├─ data/
│ │ ├─ euroc_ds_calib.json
│ │ ├─ ...
│ ├─ ...
├─ experiments/
│ ├─ iccv_tutorial/
│ │ ├─ basalt_batch_config.toml
│ │ ├─ experiments-iccv.toml
│ │ ├─ 01_iccv_all/
│ │ │ ├─ ...
│ │ ├─ 02_iccv_runtime/
│ │ │ ├─ ...
As a sibling of the basalt
source checkout we'll have an
experiments
folder, and inside, a folder iccv_tutorial
for this
tutorial. Into that folder, we copy the provided
basalt_batch_config.toml
file that defines the configurations we
want to evaluate and from which we generate individual config files
for each VIO / VO run. We also copy the provided
experiments-iccv.toml
config file, which defines the results tables
and plots that we generate from the experiments' logs.
Note: Commands in this tutorial are assumed to be executed from within
parent-folder
unless specified otherwise.
mkdir -p experiments/iccv_tutorial
cp basalt/data/iccv21/basalt_batch_config.toml experiments/iccv_tutorial/
cp basalt/data/iccv21/experiments-iccv.toml experiments/iccv_tutorial/
Generate Experimental Configs
First, edit the copied configuration file
experiments/iccv_tutorial/basalt_batch_config.toml
and modify all
"dataset-path"
lines to point to the locations where you downloaded
the datasets to.
Now, we can generate per-experiment config files:
cd experiments/iccv_tutorial/
../../basalt/scripts/batch/generate-batch-configs.py .
This will create subfolder 01_iccv_all
containing folders
vio_euroc
, vio_tumvi
, and vo_kitti
, which in turn contain all
generated basalt_config_...json
files, one for each experiment we
will run.
Run Experiments
We can now run all experiments for those generate configs. Each config / sequence combination will automatically be run twice and only the second run is evaluated, which is meant to ensure that file system caches are hot.
Since we also evaluate runtimes, we recommend that you don't use the machine running the experiments for anything else and also ensure no expensive background tasks are running during the evaluation. On one of our desktops with 12 (virtual) cores the total evaluation of all sequences takes aroudn 3:30h. Your milage may vary of course depending on the hardware.
cd experiments/iccv_tutorial/
time ../../basalt/scripts/batch/run-all-in.sh 01_iccv_all/
Inside 01_iccv_all
, a new folder with the start-time of the
experimental run is created, e.g., 20211006-143137
, and inside that
you can again see the same per-dataset subfolders vio_euroc
,
vio_tumvi
, and vo_kitti
, inside of which there is a folder for
each config / run. Inside these per-run folders you can find log files
including the command line output, which you can inspect in case
something doesn't work.
In a second terminal, you can check the status of evaluation while it is running (adjust the argument to match the actual folder name).
cd experiments/iccv_tutorial/
../../basalt/scripts/batch/list-jobs.sh 01_iccv_all/20211006-143137
If you see failed experiments for the square root solver in single precision, don't worry, that is expected.
Generate Results Tables and Plots
After all experimental runs have completed, you can generate a PDF file with tabulated results and plots, similar to those in the ICCV'21 paper.
cd experiments/iccv_tutorial/
../../basalt/scripts/batch/generate-tables.py --config experiments-iccv.toml --open
The results are in the generated tables/experiments-iccv.pdf
file
(and with the --open
argument should automatically open with the
default PDF reader).
Better Runtime Evaluation
The experiments above have the extended logging of eigenvalue and nullspace information enabled, which does cost a little extra runtime. To get a better runtime comparison, you can re-run the experiments without this extended logging. The downside is, that you can only generate the results tables, but not the plots.
We assume that you have already followed the tutorial above, including the initial folder setup. For these modified experiments, we redo all three steps (generating config files; running experiments; generating results) with slight modifications.
First, edit the experiments/iccv_tutorial/basalt_batch_config.toml
file at the bottom, and uncomment the commented entries in
_batch.combinations
as well as the commented revision
. At the same
time, comment out the initially uncommented lines. It should look
something like this after the modifications:
[_batch.combinations]
#vio_euroc = ["vio", "savetumgt", "extlog", "runtwice", "all_meth", "all_double", "all_euroc"]
#vio_tumvi = ["vio", "tumvivio", "savetumgt", "extlog", "runtwice", "all_meth", "all_double", "more_tumvi"]
#vo_kitti = ["vo", "kittivo", "savetumgt", "extlog", "runtwice", "all_meth", "all_double", "all_kitti"]
vio_euroc = ["vio", "runtwice", "all_meth", "all_double", "all_euroc"]
vio_tumvi = ["vio", "tumvivio", "runtwice", "all_meth", "all_double", "more_tumvi"]
vo_kitti = ["vo", "kittivo", "runtwice", "all_meth", "all_double", "all_kitti"]
[_batch]
#revision = "01_iccv_all"
revision = "02_iccv_runtime"
You can see that we removed the savetumgt
and extlog
named config
elements and that generated config files and results for this second
run of experiments will be placed in 02_iccv_runtime
.
Now generate config files and start the experimental runs:
cd experiments/iccv_tutorial/
../../basalt/scripts/batch/generate-batch-configs.py .
time ../../basalt/scripts/batch/run-all-in.sh 02_iccv_runtime/
Before generating the results PDF you need to now edit the
experiments-iccv.toml
file, point it to the new location for
experimental logs and disable the generation of plots. Check the place
towards the start of the file where substitutions for
EXP_PATTERN_VIO
and EXP_PATTERN_VO
are defined, as well as
SHOW_TRAJECTORY_PLOTS
, SHOW_EIGENVALUE_PLOTS
, and
SHOW_NULLSPACE_PLOTS
. After your modifications, that section should
look something like:
###################
## where to find experimental runs
[[substitutions]]
#EXP_PATTERN_VIO = "01_iccv_all/*-*/vio_*/"
#EXP_PATTERN_VO = "01_iccv_all/*-*/vo_*/"
EXP_PATTERN_VIO = "02_iccv_runtime/*-*/vio_*/"
EXP_PATTERN_VO = "02_iccv_runtime/*-*/vo_*/"
###################
## which kind of plots to show
[[substitutions]]
SHOW_TRAJECTORY_PLOTS = false
SHOW_EIGENVALUE_PLOTS = false
SHOW_NULLSPACE_PLOTS = false
Now we can generate the results tables for the new experimental runs with the same command as before:
cd experiments/iccv_tutorial/
../../basalt/scripts/batch/generate-tables.py --config experiments-iccv.toml --open