在Eigen C ++上使用单精度(MatrixXf)获得双精度(MatrixXd)答案

时间:2017-08-26 14:17:30

标签: c++ eigen mpc

我在pixhawk硬件上编码了一个模型预测控制器来控制四轴飞行器的姿态(角度)。我和pixhawk的一位开发者交换了消息,他建议我使用单精度。我的代码是双精度的。

在此之前,我使用Eigen C ++ Library测试了MatrixXd(双精度)的数值问题,我的代码能够得到相同的答案。我使用ldlt() Cholesky解算器来处理密集的线性系统(所有其他求解器方法都导致了错误的答案)。

我将所有MatrixXd替换为MatrixXf,将double替换为float,以便以单精度解决问题,但我无法得到相同的答案。因此,我希望能够了解为什么在使用MatrixXd时,MatrixXf无法获得相同的答案。

以下是相关部分。当我使用y声明我的变量和矩阵时,最后的-nan(ind); -nan(ind)变量会产生MatrixXf作为解决方案,但当我使用MatrixXd时,我得到{{1}的所需解决方案1}}。

1; 0.9999

以下是QPhild功能:

// Hildreth's Quadratic Programming Loop

for (int i = 0; i < 3; i++)//i < r_cols - 1; i++)
{
    MatrixXf F = -2 * (H.transpose())*(Rs*r.col(i) - P*Xf);
    MatrixXf d = dd + dupast*uin;
    MatrixXf DeltaU = QPhild(E, F, CC, d);

    MatrixXf DeltaU_1(4, 2);
    DeltaU_1 << DeltaU(0, 0), DeltaU(1, 0),
        DeltaU(2, 0), DeltaU(3, 0),
        DeltaU(4, 0), DeltaU(5, 0),
        DeltaU(6, 0), DeltaU(7, 0);

    MatrixXf deltau = DeltaU_1.row(0);
    MatrixXf deltau_tran = deltau.transpose();
    u = u + deltau_tran;

    // Process
    x.col(i + 1) = Ad*x.col(i) + Bd*u;
    y = Cd*x.col(i + 1) + dist.col(i);

    // Model
    xh.col(i + 1) = A*xh.col(i) + B*deltau_tran + L*(y - C*xh.col(i));
    yh = C*xh.col(i + 1);

    Xf << x.col(i + 1) - x.col(i),
        y;
  }

 cout << y << endl << endl;

我知道主要问题来自上面的函数,因为我放了各种MatrixXf QPhild(MatrixXf E, MatrixXf F, MatrixXf CC, MatrixXf d) { MatrixXf CC_trans = CC.transpose(); MatrixXf T = CC*(E.ldlt().solve(CC_trans)); MatrixXf K = (CC*(E.ldlt().solve(F)) + d); int k_row = K.rows(); int k_col = K.cols(); MatrixXf lambda(k_row, k_col); lambda.setZero(k_row, k_col); MatrixXf al(0, 0); al.setConstant(10.0f); for (int km = 0; km < 40; km++) { MatrixXf lambda_p = lambda; // loop to determine lambda values for respective iterations for (int i = 0; i < k_row; i++) { MatrixXf t1 = T.row(i)*lambda; float t2 = T(i, i)*lambda(i, 0); float w = t1(0, 0) - t2; w = w + K(i, 0); float la = -w / T(i, i); if (la < 0.0f) lambda(i, 0) = 0.0f; else lambda(i, 0) = la; } al = (lambda - lambda_p).transpose() * (lambda - lambda_p); float all = al(0, 0); float tol = 0.0000001f; if (all < tol) break; } MatrixXf DeltaU = -E.ldlt().solve(F) - (E.ldlt().solve(CC_trans))*lambda; return DeltaU; } 行来检查其中各种矩阵的输出。他们从cout开始,然后转到0,然后转到inf

修改

现在我正在使用LLT分解而不是LDLT(尽管他们都给我相同的答案)。无论如何,我在double和float中都发布了Matrix nan的值,并带有相应的奇异值。

E中的

Matrix E

double

我不能将所有数字放在一行上,但行之间的空格用于区分不同的行。 1.84805e+12 1.65144e+12 7.557e+11 6.73531e+11 3.08645e+11 2.73966e+11 1.25821e+11 1.10981e+11 1.65144e+12 1.47576e+12 6.75306e+11 6.01881e+11 2.75811e+11 2.44823e+11 1.12436e+11 9.91757e+10 7.557e+11 6.75306e+11 3.0902e+11 2.7542e+11 1.26211e+11 1.1203e+11 5.14507e+10 4.53824e+10 6.73531e+11 6.01881e+11 2.7542e+11 2.45475e+11 1.12488e+11 9.98504e+10 4.58567e+10 4.04488e+10 3.08645e+11 2.75811e+11 1.26211e+11 1.12488e+11 5.15474e+10 4.5756e+10 2.10137e+10 1.85354e+10 2.73966e+11 2.44823e+11 1.1203e+11 9.98504e+10 4.5756e+10 4.06159e+10 1.86529e+10 1.64534e+10 1.25821e+11 1.12436e+11 5.14507e+10 4.58567e+10 2.10137e+10 1.86529e+10 8.56643e+09 7.5562e+09 1.10981e+11 9.91757e+10 4.53824e+10 4.04488e+10 1.85354e+10 1.64534e+10 7.5562e+09 6.66534e+09 E的奇异值:< / p>

double
3.98569e+12 5.24887e+06 1363.09 174.56 166.311 159.098 58.9402 54.5173 中的

Matrix E

float

1.84805e+12 1.65144e+12 7.557e+11 6.73531e+11 3.08645e+11 2.73966e+11 1.25821e+11 1.10981e+11 1.65144e+12 1.47576e+12 6.75307e+11 6.01881e+11 2.75811e+11 2.44823e+11 1.12436e+11 9.91757e+10 7.557e+11 6.75307e+11 3.0902e+11 2.7542e+11 1.26211e+11 1.1203e+11 5.14507e+10 4.53824e+10 6.73531e+11 6.01881e+11 2.7542e+11 2.45475e+11 1.12488e+11 9.98505e+10 4.58567e+10 4.04488e+10 3.08645e+11 2.75811e+11 1.26211e+11 1.12488e+11 5.15474e+10 4.5756e+10 2.10137e+10 1.85354e+10 2.73966e+11 2.44823e+11 1.1203e+11 9.98505e+10 4.5756e+10 4.06159e+10 1.86529e+10 1.64534e+10 1.25821e+11 1.12436e+11 5.14507e+10 4.58567e+10 2.10137e+10 1.86529e+10 8.56643e+09 7.5562e+09 1.10981e+11 9.91757e+10 4.53824e+10 4.04488e+10 1.85354e+10 1.64534e+10 7.5562e+09 6.66534e+09 奇异值为:

float

0 个答案:

没有答案