• g2o中的边Edge


    g2o中的边

    不用管他是几元边,其实本质上都是误差项
    而几元边就是对几个变量也就是所谓顶点求导数、下降方向罢了。

    g2o中包含三种形式边

    1. 单元边BaseUnaryEdge
    2. 二元边BaseBinaryEdge
    3. 多元边 BaseMultiEdge,BaseVariableSizedEdge

    说明一些含义啊

    1. 假设XXX是任意变量类型,当然可以是自定义的结构体、类之类的都行,xxxXXX类型的变量,当然不一定是同种or同一个。
    2. 假设id顶点编号,当然不一定是同种or同一个。
    3. 假设VVV顶点类型,当然不一定是同种or同一个。
    4. 假设num误差项维度是一个具体的数值,1,2,3啥的,其实就是雅克比矩阵的行数

    单元边BaseUnaryEdge

    自定义单元边

    class MyEdgeOne
        : public g2o::BaseUnaryEdge
    {
    public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW//Eigen库的对齐宏啥的
        MyEdgeOne(): BaseBinaryEdge()
        {
        	//随便写点也行吧
        }
    
        virtual bool read(std::istream &) { return false; }//还没写过不会用
        virtual bool write(std::ostream &) const { return false; }//还没写过不会用
    
        void computeError()
        {
            _error = 自己算去;//计算误差
        }
    
        void linearizeOplus()
        {
             _jacobianOplusXi =自己算去 ; //对误差项求i顶点的导数
        }
    		//按需要添加各种各样的数据类型与函数
    		void setxxx(XXX xxx_)
    		{
    			xxx = xxx_;
    		}
    		XXX xxx;
    		// 继承的类里面本身就有一些数据or函数主要是下面这几个
    		// _error 误差
    		// _measurement 观测
    		// _jacobianOplusXi 雅克比矩阵
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    设置Edge的连接与观测等

    MyEdgeOne *e = new MyEdgeOne();
    e->setVertex(0, dynamic_cast(optimizer.vertex(id))); //设置i顶点
    e->setMeasurement(xxx);//设置观测
    e->setxxx(xxx);//自己定义的各种函数
    
    • 1
    • 2
    • 3
    • 4

    设置完把边丢进去就行了

    二元边BaseBinaryEdge

    自定义二元边

    class MyEdgeTwo
        : public g2o::BaseUnaryEdge
    {
    public:
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW//Eigen库的对齐宏啥的
        MyEdgeTwo(): BaseBinaryEdge()
        {
        	//随便写点也行吧
        }
    
        virtual bool read(std::istream &) { return false; }//还没写过不会用
        virtual bool write(std::ostream &) const { return false; }//还没写过不会用
    
        void computeError()
        {
            _error = 自己算去;//计算误差
        }
    
        void linearizeOplus()
        {
             _jacobianOplusXi =自己算去 ; //对误差项求i顶点的导数
             _jacobianOplusXj =自己算去 ; //对误差项求j顶点的导数
        }
    		//按需要添加各种各样的数据类型与函数
    		void setxxx(XXX xxx_)
    		{
    			xxx = xxx_;
    		}
    		XXX xxx;
    		// 继承的类里面本身就有一些数据or函数主要是下面这几个
    		// _error 误差
    		// _measurement 观测
    		// _jacobianOplusXi 雅克比矩阵
    		// _jacobianOplusXj 雅克比矩阵
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    设置Edge的连接与观测等

    MyEdgeTwo *e = new MyEdgeTwo();
    e->setVertex(0, dynamic_cast(optimizer.vertex(id))); //设置i顶点
    e->setVertex(1, dynamic_cast(optimizer.vertex(id))); //设置j顶点
    e->setId(id);//设置顶点id
    e->setMeasurement(xxx);//设置观测
    e->setxxx(xxx);//自己定义的各种函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    设置完把边丢进去就行了

    多元边 BaseMultiEdge,BaseVariableSizedEdge

    后面版本改名字了?!何必呢??

    template 
    using BaseMultiEdge = BaseVariableSizedEdge;
    
    • 1
    • 2

    自定义多元边

    class MyEdgeHaoDuo
        : public g2o::BaseVariableSizedEdge
    {
     public:
      	EIGEN_MAKE_ALIGNED_OPERATOR_NEW//Eigen库的对齐宏啥的
      	MyEdgeHaoDuo():g2o::BaseVariableSizedEdge()
      	{
      		resize(EdgeNum/*顶点个数*/);
      	}
    
    		void computeError()
        {
        		//取出顶点的用于计算呗
        		VVV0 *v0 = static_cast(_vertices[0]);
        		VVV1 *v1 = static_cast(_vertices[1]);
        		VVV2 *v2 = static_cast(_vertices[2]);
        		// ...好多个
        		//要加const也行
        		//const VVV1 *v1 = static_cast(_vertices[0]);
        		// ...
            _error = 自己算去;//计算误差
        }
    
        virtual bool read(std::istream &) { return false; }//还没写过不会用
        virtual bool write(std::ostream &) const { return false; }//还没写过不会用
    
        void linearizeOplus()
        {
        		_jacobianOplus[0]=自己算去;//计算对应VVV0的雅克比
        		_jacobianOplus[1]=自己算去;//计算对应VVV1的雅克比
        		_jacobianOplus[2]=自己算去;//计算对应VVV2的雅克比
        		// ...好多个
        }
        // 继承的类里面本身就有一些数据or函数主要是下面这几个
    		// _error 误差
    		// _vertices 存储雅克比矩阵的向量
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    设置Edge的连接与观测等

    MyEdgeTwo *e = new MyEdgeTwo();
    e->setVertex(0, dynamic_cast(optimizer.vertex(id))); //设置0顶点
    e->setVertex(1, dynamic_cast(optimizer.vertex(id))); //设置1顶点
    e->setVertex(2, dynamic_cast(optimizer.vertex(id))); //设置2顶点
    //...好多顶点
    e->setId(id);//设置顶点id
    e->setMeasurement(xxx);//设置观测
    e->setxxx(xxx);//自己定义的各种函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    将边Edge加入的优化器中

    最后将边加入优化

     optimizer.addEdge(e);
    
    • 1
  • 相关阅读:
    UML——时序图
    又拍云 Redis 的改进之路
    【实践篇】Redis使用规范清单详解
    生成迷宫的算法
    写给Python社群的第5课:Python 函数,真的难吗?
    Python数据分析与机器学习32-聚类算法
    1545. 找出第 N 个二进制字符串中的第 K 位-递归法
    【网络篇】第十四篇——HTTP协议(一)(附带电视剧李浔同款爱心+端口号被恶意占用如何清除)
    盘点面试中常见的超大规模数据常见的算法问题
    flex 收缩计算、简写
  • 原文地址:https://blog.csdn.net/qq_45401419/article/details/127941689