- Initialization
- ESKF
- NDT alignment
- Dynamic map loading
- Multithread processing
Goal: loading configuration, map loading, imu initialization, estimate the initial state of robot.
- reading configurations file: obtain meta data like imu lidar extrinisic, GNSS origin, sensor specs, etc.
- map loading: load submaps info (i.e., submap id, path of point cloud files) created by the mapping module
- IMU initialization: given the static state of robot, compute the sample mean and variance of accerometer and gyroscope, obtain bias and covariance of acc and gyr, gravity.
- initial state estimation:
- wait for the first valid gnss data
- use gnss position as the initial position, map cloud as target, current scan as source, do NDT alignment with decreasing resolution and different orientation.
- the alignment result, zero velocity and imu configuration are used as the initial state of ESKF.
Goal: estimate state given imu and lidar scan.
- prediction: integrate imu data, compute position, velocity, orientation, bias of accerometer and gyroscope, gravity, and covariance of measurment noise.
- correction: given NDT alignment result (current pose), compute error state and Kalman gain, correct the nominal states and reset the error.
Goal: based on the predicted pose from eskf, optimize the pose such that the residual of NDT alignment of target and source point cloud is minimized.
- target cloud: the point cloud of the current map.
- undistort the raw point cloud influenced by the motion
- align each scan point with imu reading, compute the the pose of lidar (imu) sensor by interoplation, i.e.,
$T_{W I_i}$ . - transform each scan point to the frame of the last imu reading, i.e.,
$p_{L_e} = T_{LI} * T_{I_e W} * T_{W I_i} * T_{IL} * p_{L_i}$
- align each scan point with imu reading, compute the the pose of lidar (imu) sensor by interoplation, i.e.,
- source cloud: the point cloud of the current undistored lidar scan.
- the initial guess is given by eskf prediction and alignment result is used as observation for eskf correction.
Goal: to save memory usage, load and unload map based on current position. This is processing in seperate thread.
- partition map into submaps (done in mapping module)
- load map meta data at the initialization stage, including id and path of each submap file
- based on the pose estimate from eskf, load the submaps that are close to current position, unload submaps that are far away (e.g., euclidian or manhattan distance of the map id).
Goal: reduce delay at the dynamic loading caused by building kd tree for NDT target cloud. Execute state esitimation and dynamic map loading concurrently.
- two seperate thread: a. ESKF state estimation. b. dynamic map loading.
- the main thread is for the ESKF state estimation. After the correction step, the main thread wakes up dynamic map loading thread by c++ `std::conditio_variable if map change is needed.
- the dynamic map loading thread is a event loop waiting for the notification from the main thread. Once woke up, it update viewer and kd tree of NDT target.
- NDT object is the data modified by both thread. A
mutexis used for NDT object to avoid data race.
- NDT score from different version of pcl are different. The older version (1.10) works better.
- Error handling: relocalization if ndt alignment fails. a. multi-level grid search using NDT alignment with GNSS initial position. b. other point cloud registration like ICP.
- Dynamic environment: maintain a local map during localization (using lio etc), detecting environmnet change during localization, update static map





