融合定位学习--惯性器件误差分析及标定

1.环境问题

框架编译

cd imu_tk
mkdir build
cd build
cmake  ..
make

查看CMakelists,依赖还是qt4,但是Ubuntu 20.04 LTS中弃用了Qt4,可以下载并安装Qt5并进行改写。

sudo apt-get install build-essential
sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools
sudo apt-get install qtcreator
sudo apt-get install qt5*

整体进行改写比较麻烦,很多Qt4的方法已经被启用,但是仍然可以获得Qt4库作为软件依赖项

sudo add-apt-repository ppa:rock-core/qt4
sudo apt update
sudo apt-get install libqt4-dev
sudo apt-get install libqt4-opengl-dev

如果需要卸载qt4

sudo add-apt-repository --remove ppa:rock-core/qt4
sudo apt remove --autoremove libqt4* libqtcore4 libqtgui4 libqtwebkit4 qt4*

2. 加速度计对应残差的雅克比

残差:
在这里插入图片描述其中:
在这里插入图片描述展开a
在这里插入图片描述

待求参数:
在这里插入图片描述
根据链式求导法则:
在这里插入图片描述对参数分别求偏导数:
在这里插入图片描述

3.修改imu_tk中的上三角矩阵为下三角矩阵

主要是三处修改:
第一处初始化:

      // TODO: implement lower triad model here
      //
      // mis_yz, mis_zy, mis_zx:
      double(0), double(0), double(0),
      // mis_xz, mis_xy, mis_yx:
      parameters[0][0], parameters[0][1], parameters[0][2],
      //    s_x,    s_y,    s_z:
      parameters[0][3], parameters[0][4], parameters[0][5], 
      //    b_x,    b_y,    b_z: 
      parameters[0][6], parameters[0][7], parameters[0][8] 

第二处:

    //
    // TODO: implement lower triad model here
    //
    acc_calib_params[0] = init_acc_calib_.misXZ();
    acc_calib_params[1] = init_acc_calib_.misXY();
    acc_calib_params[2] = init_acc_calib_.misYX();

第三处:

 acc_calib_ = CalibratedTriad_<_T>( 
    //
    // TODO: implement lower triad model here
    // 
    0,0,0,
    min_cost_calib_params[0],
    min_cost_calib_params[1],
    min_cost_calib_params[2],
    min_cost_calib_params[3],
    min_cost_calib_params[4],
    min_cost_calib_params[5],
    min_cost_calib_params[6],
    min_cost_calib_params[7],
    min_cost_calib_params[8] 
  );

运行过程中,可能出现以下错误:
在这里插入图片描述
解决方法是使用gcc的堆栈保护功能:
在CMakelists中加入

add_compile_options(-g  -ggdb -O0 -Wall   -fstack-protector-all -march=native -fnon-call-exceptions)

运行结果:
在这里插入图片描述
在这里插入图片描述

4.ceres 非线性优化,求解加速度计内参

替换calibration.cpp的原本自动求导的MultiPosAccResidual类为下面的解析求导类代码:

template<typename _T1>
class MultiPosAccResidual  : public ceres::SizedCostFunction<1,9>
{
  public:
    MultiPosAccResidual(const _T1 &g_mag, const Eigen::Matrix< _T1, 3 , 1> &sample 
    ) : g_mag_(g_mag), sample_(sample){}
   
   virtual ~MultiPosAccResidual() {}
   virtual bool Evaluate(double const* const* parameters,double* residuals,double** jacobians) const 
	{
    Eigen::Matrix<double, 3, 1> raw_samp( 
      double(sample_(0)), 
      double(sample_(1)), 
      double(sample_(2)) 
    );
    /* Apply undistortion transform to accel measurements
         mis_mat_ <<  _T(1)   , -mis_yz  ,  mis_zy  ,
                       mis_xz ,  _T(1)   , -mis_zx  ,  
                      -mis_xy ,  mis_yx  ,  _T(1)   ; */
    CalibratedTriad_<double> calib_triad( 
      //
      // TODO: implement lower triad model here
      //
      // mis_yz, mis_zy, mis_zx:
      double(0), double(0), double(0),
      // mis_xz, mis_xy, mis_yx:
      parameters[0][0], parameters[0][1], parameters[0][2],
      //    s_x,    s_y,    s_z:
      parameters[0][3], parameters[0][4], parameters[0][5], 
      //    b_x,    b_y,    b_z: 
      parameters[0][6], parameters[0][7], parameters[0][8] 
    );
    
    // apply undistortion transform:
    Eigen::Matrix< double, 3 , 1> calib_samp = calib_triad.unbiasNormalize( raw_samp );
    
    residuals[0] = g_mag_*g_mag_ - calib_samp.squaredNorm();
    // residuals[0] = g_mag_- calib_samp.norm();

		if(jacobians != NULL)
		{
			if(jacobians[0] != NULL)
			{ 
        double S1 = parameters[0][0];
        double S2 = parameters[0][1];
        double S3 = parameters[0][2];

        double K1 = parameters[0][3];
        double K2 = parameters[0][4];
        double K3 = parameters[0][5];

        double b1 = parameters[0][6];
        double b2 = parameters[0][7];
        double b3 = parameters[0][8];

        double A1 = sample_(0);
        double A2 = sample_(1);
        double A3 = sample_(2);
        
        Eigen::MatrixXd a(3, 1);
         a << K1*(A1-b1), -S1*K1*(A1-b1)+K2*(A2-b2), -S2*K1*(A1-b1)-S3*K2*(A2-b2)+K3*(A3-b3);
        Eigen::MatrixXd da_dTheta(3, 9);
        da_dTheta << 0, 0, 0, A1-b1, 0, 0, -K1, 0, 0, 
                    -K1*(A1-b1), 0, 0, -S1*(A1-b1), A2-b2, 0, S1*K1, -K2, 0,
                    0, -K1*(A1-b1), -K2*(A2-b2), -S2*(A1-b1), -S3*(A2-b2), A3-b3, S2*K1, S3*K2, -K3;

        Eigen::Map<Eigen::Matrix<double, 1, 9, Eigen::RowMajor> > Jacob(jacobians[0]);
        Jacob.setZero();

        Jacob = - 2 * calib_samp.transpose() * da_dTheta;
                  
			}
		}

		return true;
	}

static ceres::CostFunction* Create ( const _T1 &g_mag, const Eigen::Matrix< _T1, 3 , 1> &sample )
  {
    return ( new MultiPosAccResidual<_T1>( g_mag, sample ) );
  }
protected:
	const _T1 g_mag_;
  const Eigen::Matrix< _T1, 3 , 1> sample_;
};

解析求导结果和自动求导一致:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值