几元边就有几个Jacobian
例如g2o定义的二元边就有_jacobianOplusXi和_jacobianOplusXj
源码中BaseEdge定义如下:D决定了误差的维度
template <int D, typename E>
class BaseEdge : public OptimizableGraph::Edge
{
public:
static const int Dimension = D;
typedef E Measurement;
typedef Eigen::Matrix<number_t, D, 1, Eigen::ColMajor> ErrorVector;
typedef Eigen::Matrix<number_t, D, D, Eigen::ColMajor> InformationType;
一个具体例子:
class VertexPose : public g2o::BaseVertex<6, Sophus::SE3d> {
class EdgeProjection : public g2o::BaseUnaryEdge<2, Eigen::Vector2d, VertexPose> {
_jacobianOplusXi
<< -fx / Z, 0, fx * X / Z2, fx * X * Y / Z2, -fx - fx * X * X / Z2, fx * Y / Z,
0, -fy / Z, fy * Y / (Z * Z), fy + fy * Y * Y / Z2, -fy * X * Y / Z2, -fy * X / Z;
typedef g2o::BlockSolver<g2o::BlockSolverTraits<6, 3>> BlockSolverType; // pose is 6, landmark is 3
class CurveFittingVertex : public g2o::BaseVertex<3, Eigen::Vector3d> {
class CurveFittingEdge : public g2o::BaseUnaryEdge<1, double, CurveFittingVertex> {
double y = exp(abc[0] * _x * _x + abc[1] * _x + abc[2]);
_jacobianOplusXi[0] = -_x * _x * y;
_jacobianOplusXi[1] = -_x * y;
_jacobianOplusXi[2] = -y;
typedef g2o::BlockSolver<g2o::BlockSolverTraits<3, 1>> BlockSolverType; // 每个误差项优化变量维度为3,误差值维度为1
class BaseBinaryEdge : public BaseEdge<D, E>
{
public:
typedef VertexXi VertexXiType;
typedef VertexXj VertexXjType;
static const int Di = VertexXiType::Dimension;
static const int Dj = VertexXjType::Dimension;
static const int Dimension = BaseEdge<D, E>::Dimension;
typedef typename BaseEdge<D,E>::Measurement Measurement;
typedef typename Eigen::Matrix<number_t, D, Di, D==1?Eigen::RowMajor:Eigen::ColMajor>::AlignedMapType JacobianXiOplusType;
typedef typename Eigen::Matrix<number_t, D, Dj, D==1?Eigen::RowMajor:Eigen::ColMajor>::AlignedMapType JacobianXjOplusType;
typedef typename BaseEdge<D,E>::ErrorVector ErrorVector;
typedef typename BaseEdge<D,E>::InformationType InformationType;
D决定了误差的维度,从映射的角度讲,三维情况下就是2维的,二维的情况下是1维的;然后E是measurement的类型,也就是测量值是什么类型的,这里E就是什么类型的(一般都是Eigen::VectorN表示的,N是自然数)