CostFunction是有用来计算残差e
和雅阁比J
的,给出状态值向量[x1,x2,...xn]
后按道理就可以根据方程f(x1,x2,...xn)
求解出方程的结果vector
和雅阁比矩阵J
class CostFunction {
public:
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) = 0;
const vector<int32>& parameter_block_sizes();
int num_residuals() const;
protected:
vector<int32>* mutable_parameter_block_sizes();
void set_num_residuals(int num_residuals);
};
CostFunction::parameter_block_sizes_
CostFunction::num_residuals_
//输入:parameters 输出:residuals jacobians
bool CostFunction::Evaluate(double const *const *parameters, double *residuals, double **jacobians)
状态值本身维度和在流体表面维度不一致的情况下使用
class LocalParameterization {
public:
virtual ~LocalParameterization() = default;
virtual bool Plus(const double* x,
const double* delta,
double* x_plus_delta) const = 0; //定义广义的加法
virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0;
virtual bool MultiplyByJacobian(const double* x,
const int num_rows,
const double* global_matrix,
double* local_matrix) const;
virtual int GlobalSize() const = 0; //原始空间对应的状态值维度
virtual int LocalSize() const = 0; //切平面上对应维度
};
只要是非线性的参数块都是定义的LocalParameterization,比如vins mono中的航向角是控制在[-180,180]之间就是一个非线性的
1.航向角相关的local parameter
template <typename T>
T NormalizeAngle(const T& angle_degrees) {
if (angle_degrees > T(180.0))
return angle_degrees - T(360.0);
else if (angle_degrees < T(-180.0))
return angle_degrees + T(360.0);
else
return angle_degrees;
};
class AngleLocalParameterization {
public:
template <typename T>
bool operator()(const T* theta_radians, const T* delta_theta_radians,
T* theta_radians_plus_delta) const {
*theta_radians_plus_delta =
NormalizeAngle(*theta_radians + *delta_theta_radians);
return true;
}
static ceres::LocalParameterization* Create() {
return (new ceres::AutoDiffLocalParameterization<AngleLocalParameterization,
1, 1>);
}
};
2.姿态相关的local parameter
1.声明local parameter的类型
ceres::LocalParameterization *local_parameter = new ceres::EigenQuaternionParameterization
2.添加local parameter数据
problem.AddParameterBlock(frame.q.coeffs().data(),4,local_parameter);
3.如果要参数为const的话
problem.SetParameterBlockConstant(frame.q.coeffs().data());
q.coeffs() //数据存储方式为: [x,y,z,w]
3.pose定义的local parameter
#include
#include
class PoseLocalParameterization : public ceres::LocalParameterization
{
virtual bool Plus(const double *x, const double *delta, double *x_plus_delta) const;
virtual bool ComputeJacobian(const double *x, double *jacobian) const;
virtual int GlobalSize() const { return 7; };
virtual int LocalSize() const { return 6; };
};
#include "pose_local_parameterization.h"
bool PoseLocalParameterization::Plus(const double *x, const double *delta, double *x_plus_delta) const
{
Eigen::Map<const Eigen::Vector3d> _p(x);
Eigen::Map<const Eigen::Quaterniond> _q(x + 3);
Eigen::Map<const Eigen::Vector3d> dp(delta);
Eigen::Quaterniond dq = Utility::deltaQ(Eigen::Map<const Eigen::Vector3d>(delta + 3));
Eigen::Map<Eigen::Vector3d> p(x_plus_delta);
Eigen::Map<Eigen::Quaterniond> q(x_plus_delta + 3);
p = _p + dp;
q = (_q * dq).normalized();
return true;
}
bool PoseLocalParameterization::ComputeJacobian(const double *x, double *jacobian) const
{
Eigen::Map<Eigen::Matrix<double, 7, 6, Eigen::RowMajor>> j(jacobian);
j.topRows<6>().setIdentity();
j.bottomRows<1>().setZero();
return true;
}