| 155 | } |
| 156 | |
| 157 | void Estimator::ProcessKeyframeInBackend(std::shared_ptr<Frame> keyframe) { |
| 158 | LOG_DEBUG("Backend processing keyframe {}", keyframe->GetFrameId()); |
| 159 | |
| 160 | // Lock entire BA process |
| 161 | std::unique_lock<std::shared_mutex> lock(m_map_mutex); |
| 162 | |
| 163 | // Find previous keyframe |
| 164 | std::shared_ptr<Frame> prev_keyframe = nullptr; |
| 165 | if (m_keyframes.size() >= 2) { |
| 166 | for (int i = static_cast<int>(m_keyframes.size()) - 2; i >= 0; --i) { |
| 167 | if (m_keyframes[i]->GetFrameId() < keyframe->GetFrameId()) { |
| 168 | prev_keyframe = m_keyframes[i]; |
| 169 | break; |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | // Triangulate new MapPoints |
| 175 | int new_points = 0; |
| 176 | if (prev_keyframe) { |
| 177 | new_points = TriangulateNewMapPoints(prev_keyframe, keyframe); |
| 178 | } |
| 179 | |
| 180 | // Run BA |
| 181 | if (new_points > 0 && m_keyframes.size() >= 2) { |
| 182 | Optimizer optimizer; |
| 183 | optimizer.SetCamera(m_camera, m_boundary_margin); |
| 184 | |
| 185 | BAResult ba_result; |
| 186 | if (m_tracking_state == TrackingState::VIO) { |
| 187 | ba_result = optimizer.RunLocalBAwithInertial(m_keyframes, m_gravity); |
| 188 | |
| 189 | // Update bias |
| 190 | auto last_kf = m_keyframes.back(); |
| 191 | Eigen::Vector3f new_gyro_bias = last_kf->GetGyroBias(); |
| 192 | Eigen::Vector3f new_accel_bias = last_kf->GetAccelBias(); |
| 193 | UpdatePreintegrationsWithNewBias(new_gyro_bias, new_accel_bias); |
| 194 | } else { |
| 195 | ba_result = optimizer.RunLocalBA(m_keyframes); |
| 196 | } |
| 197 | |
| 198 | LOG_DEBUG("Backend BA: {} keyframes, {} inliers, {} outliers, cost {:.2f}->{:.2f}", |
| 199 | m_keyframes.size(), ba_result.num_inliers, ba_result.num_outliers, |
| 200 | ba_result.initial_cost, ba_result.final_cost); |
| 201 | |
| 202 | // Update current pose |
| 203 | if (!m_keyframes.empty()) { |
| 204 | m_current_pose = m_keyframes.back()->GetTwb(); |
| 205 | } |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | Estimator::EstimationResult Estimator::ProcessFrame(const cv::Mat& image, double timestamp) { |
| 210 | auto frame_start = std::chrono::high_resolution_clock::now(); |
nothing calls this directly
no test coverage detected