|
| 1 | +/* Copyright (c) 2022, Gonzalo Ferrer |
| 2 | + * |
| 3 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | + * you may not use this file except in compliance with the License. |
| 5 | + * You may obtain a copy of the License at |
| 6 | + * |
| 7 | + * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | + * |
| 9 | + * Unless required by applicable law or agreed to in writing, software |
| 10 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | + * See the License for the specific language governing permissions and |
| 13 | + * limitations under the License. |
| 14 | + * |
| 15 | + * |
| 16 | + * FactorPriorInertial.cpp |
| 17 | + * |
| 18 | + * Created on: Jan 20, 2026 |
| 19 | + * Author: Gonzalo Ferrer |
| 20 | + * g.ferrer@skoltech.ru |
| 21 | + * Mobile Robotics Lab, Skoltech |
| 22 | + */ |
| 23 | + |
| 24 | + |
| 25 | +#include "mrob/factors/factorPriorInertial.hpp" |
| 26 | + |
| 27 | +#include <iostream> |
| 28 | + |
| 29 | +using namespace mrob; |
| 30 | + |
| 31 | + |
| 32 | +FactorPriorInertial::FactorPriorInertial(const Mat5 &observationPoseTarget, |
| 33 | + const Mat91 &obsBias, |
| 34 | + std::shared_ptr<Node> &nodePoseTarget, |
| 35 | + std::shared_ptr<Node> &nodeBiasGyro, |
| 36 | + std::shared_ptr<Node> &nodeBiasAcc, |
| 37 | + std::shared_ptr<Node> &nodeGravity, |
| 38 | + const Mat<18,18> &obsInf, |
| 39 | + Factor::robustFactorType robust_type): |
| 40 | + Factor(18,18, robust_type), W_(obsInf), r_(Vect<18>::Zero()), J_(Mat<18,18>::Zero()) |
| 41 | +{ |
| 42 | + |
| 43 | + obs_bias_gyro_ = obsBias.head(3); |
| 44 | + obs_bias_acc_= obsBias.segment<3>(3); |
| 45 | + obs_gravity_ = obsBias.tail(3); |
| 46 | + Tobs_target_inv_ = SE3tc(observationPoseTarget).inv(); |
| 47 | + // Ordering here MUST be the same. TODO handle any order. |
| 48 | + // [0] Pose Target |
| 49 | + // [1] bias gyro |
| 50 | + // [2] bias acc |
| 51 | + // [3] gravity in the global frame |
| 52 | + neighbourNodes_.push_back(nodePoseTarget); |
| 53 | + neighbourNodes_.push_back(nodeBiasGyro); |
| 54 | + neighbourNodes_.push_back(nodeBiasAcc); |
| 55 | + neighbourNodes_.push_back(nodeGravity); |
| 56 | +} |
| 57 | + |
| 58 | +void FactorPriorInertial::evaluate_residuals() |
| 59 | +{ |
| 60 | + // Anchor residuals as r = x - obs |
| 61 | + // r = ln(X * Tobs^-1) = - ln(Tobs * x^-1) |
| 62 | + // NOTE Tobs is a global observation (reference identity) |
| 63 | + Mat5 x_target = get_neighbour_nodes()->at(0).get()->get_state(); |
| 64 | + Tr_ = SE3tc(x_target) * Tobs_target_inv_; |
| 65 | + r_.head(9) << Tr_.Ln().head(9); |
| 66 | + |
| 67 | + // manifold for linear terms |
| 68 | + Mat31 bias_gyro = get_neighbour_nodes()->at(1)->get_state(); |
| 69 | + r_.segment<3>(9) << bias_gyro - obs_bias_gyro_; |
| 70 | + |
| 71 | + Mat31 bias_acc = get_neighbour_nodes()->at(2)->get_state(); |
| 72 | + r_.segment<3>(9+3) << bias_gyro - obs_bias_acc_; |
| 73 | + |
| 74 | + Mat31 bias_grav = get_neighbour_nodes()->at(3)->get_state(); |
| 75 | + r_.segment<3>(9+6) << bias_grav - obs_gravity_; |
| 76 | +} |
| 77 | + |
| 78 | +void FactorPriorInertial::evaluate_jacobians() |
| 79 | +{ |
| 80 | + J_ = Mat<18,18>::Identity(); |
| 81 | +} |
| 82 | + |
| 83 | +void FactorPriorInertial::evaluate_chi2() |
| 84 | +{ |
| 85 | + chi2_ = 0.5 * r_.dot(W_ * r_); |
| 86 | +} |
| 87 | + |
| 88 | +void FactorPriorInertial::print() const |
| 89 | +{ |
| 90 | + std::cout << "Printing Factor: " << id_ << ", obs= \n" |
| 91 | + << "\n Residuals= \n" << r_ |
| 92 | + << " \nand Information matrix\n" << W_ |
| 93 | + << "\n Calculated Jacobian = \n" << J_ |
| 94 | + << "\n Chi2 error = " << chi2_ |
| 95 | + << " and neighbour Nodes " << neighbourNodes_.size() |
| 96 | + << std::endl; |
| 97 | +} |
0 commit comments