Ceres assertion raised
When executing a wolf_node using a separated thread for the solver, the execution chrashed since an assertion in CeresManager::addFactor()
is raised:
assert((unsigned int)(ceres_problem_->NumResidualBlocks()) == fac_2_residual_idx_.size() && "ceres residuals different from wrapper residuals");
Conclusions of debugging:
In multi-threading, SolverManager::update()
can be eventually called in the process of removing a frame and its "desendants". With the previous implementation (now, solved), the order of notification of removal and removing descendants leaded to state blocks REMOVE notifications sent to problem before REMOVE notifications for factors. This raised an assertion. Also, two different functions to take the state blocks and factors notifications was also a potential crashing point. I say "truncated" notifications to this.
Changes implemented_
- Improved
SolverManager
and derived classes functions names (with "xxxDerived()" functions). - Created
SolverManager::check()
and improvedCeresManager::checkDerived()
. - Modified
remove()
of some wolf nodes to avoid this effect (documented in a comment). - Anyway, modified
SolverManager
to correctly handle "truncated" notifications: Postpone notifications to ADD factors before adding all involved state blocks or REMOVE state blocks before removing all involved state blocks. It shows a WARNING. - Added attributes in
SolverManager
:std::set<FactorBasePtr> factors_
andstd::map<StateBlockPtr,FrameBasePtrList> state_blocks_2_factors_
. - Added a test in
gtest_solver_manager
that checks in multi-threading this issue for 5s. One thread creating and destroying frame (with capture,feature and factor) and the other callingSolverManager::update()
).