NDT localization workflow
Higher level workflow
- Set input point cloud
- Copy the pointer to the pointcloud message
- Build the voxel grid
- Calculate the initial guess:
- No sensors:
- IMU available:
- Vehicle odometry available:
- IMU and Vehicle odometry available:
- Execute NDT optimization loop starting with the initial guess
- Set the vehicle pose state to the resulting base_link pose
- Calculate the translation difference between the initial guess and the ndt estimate:
- If it's bigger than a threshold, use the initial guess.
- Else, use the ndt estimate.
- Calculate the velocity and acceleration using this estimate
- Mostly first level derivation by dividing the transform delta to the time delta.
- Acceleration is estimated using the difference between the current and the previous velocity estimates.
- Publish the estimates
- Publish all of the initial guesses(despite only one of them should be getting calculated).
- Publish the ndt estimate.
- Add the transform to the frame graph.
Notes:
- A fixed transform is applied to the initial guess before ndt matching. The authors refer to the estimates with this transformation applied, the
localizer estimates and when the estimate is transformed back to its original frame, it's called the ndt estimate.
- This static transform is a global variable and is not read from the transform graph.
Lower Level Workflow
Follows the equations from this paper, section 6.2.
- Compute the gauss parameters
- The gaussian probability function is modified to account for outliers. See Eq. 6.7 and 6.8 on details of this.
- Transform the scanned cloud using the initial guess.
- Compute the gradients and Hessian analytically. See page 63 on the paper for exact mathematical details.
- Compute coefficients for computing the Jacobian and Hessian matrices. (Eq. 6.19)
- For each point in the translated point cloud:
- Search for a list of neighbors for a fixed radius in the voxel grid:
- For each neighboring voxel
- Compute the first and second order derivatives using the pre-calculated coefficients
- Using the Hessian and the probability score gradient, the pose update is calculated according to Newton's method.
- $
H\Delta p = -g$ : Here the $H$ is the hessian matrix, $\Delta p$ is the pose delta and $g$ is the gradient of the NDT score function that was calculated with the rest of derivatives in the previous steps.
- This linear equation is solved by applying JacobiSVD to the Hessian matrix and then solving for the negative score gradient $
-g$.
- Normalize the pose delta
- Calculate the step length
- Udate the pose
- If the max number of iterations are reached or the step size is smaller than an epsilon, stop the loop. Else go to step 4.
- The paper suggests an epsilon of 1e-6 but the implementation uses 0.1
Positive Impressions
- Concerns are somewhat separated on the algorithm level.
- Having a base class of registration that the NDT entity is derived from seems like the start of a good inheritance structure for future extensions.
- Parameter naming and calculations are taken from an actual paper making it easier to read, review and reproduce.
Negative Impressions
High level workflow:
- Minimal documentation/comments.
- Relies heavily on global variables that get modified by different static callbacks.
- Almost entire high level workflow of ndt localization occurs in the pointcloud callback without utilizing any helper functions.
- Low readability.
- Hard to distinguish separate functionality.
- Interleaved steps.
- A lot of repeating code for different configurations/implementations.
- Somewhat cryptic parameter names.
- Vehicle kinematic state relies on differentiating two consecutive transforms over a time delta.
Low level workflow:
- Redundant operations occur in the run-time loop:
- Optimization loop is interleaved with NDT specific steps.