PosCalibrate/calPoint.h
2025-10-15 14:50:31 +08:00

169 lines
5.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef CALPOINT_H
#define CALPOINT_H
#include "qglobal.h"
#include <cmath>
#include "QDebug"
// 定义常量
const double Re = 6378.14; // 地球半径km
const double PI = 3.14159265358979323846;
const double Heading_IMUBase =63.888;
const double Pitch_IMUBase = -0.121;
const double Roll_IMUBase = -0.082;
const double Heading_OPABase=64.062;
const double Pitch_OPABase = -0.332;
const double Roll_OPABase = 89.812;
const double OpticalAxisAngle_N0=90;
const double OpticalAxisAngle_E0= 90;
const double OpticalAxisAngle_D0=0;
// 角度转弧度函数
double deg2rad(double deg) {
return deg * PI / 180.0;
}
// 弧度转角度函数
double rad2deg(double rad) {
return rad * 180.0 / PI;
}
// 模运算函数
double mod(double x, double y) {
return x - y * std::floor(x / y);
}
// 矩阵乘法函数
void matrixMultiply(double A[3][3], double B[3][3], double result[3][3]) {
for(int i=0; i<3; i++) {
for(int j=0; j<3; j++) {
result[i][j] = 0;
for(int k=0; k<3; k++) {
result[i][j] += A[i][k] * B[k][j];
}
}
}
}
void matrixMultiplyVector(double A[3][3], double B[3], double result[3]) {
for(int i=0; i<3; i++) {
result[i] = 0;
for(int j=0; j<3; j++) {
result[i] += A[i][j] * B[j];
}
}
}
QVector<double> calRes(double Lon_A,double Lat_A,double Hei_A,double Lon_B,double Lat_B, double Hei_B,double HeadingReal,double PitchReal,double RollReal){
// 将角度由度转化为弧度
double Lon_A_Rad = deg2rad(Lon_A); // A机经度rad
double Lat_A_Rad = deg2rad(Lat_A); // A机纬度rad
double Lon_B_Rad = deg2rad(Lon_B); // B机经度rad
double Lat_B_Rad = deg2rad(Lat_B); // B机纬度rad
// 双机位置地心直角坐标系及双机距离km
double X_A = (Re + Hei_A) * std::cos(Lat_A_Rad) * std::cos(Lon_A_Rad);
double Y_A = (Re + Hei_A) * std::cos(Lat_A_Rad) * std::sin(Lon_A_Rad);
double Z_A = (Re + Hei_A) * std::sin(Lat_A_Rad);
double X_B = (Re + Hei_B) * std::cos(Lat_B_Rad) * std::cos(Lon_B_Rad);
double Y_B = (Re + Hei_B) * std::cos(Lat_B_Rad) * std::sin(Lon_B_Rad);
double Z_B = (Re + Hei_B) * std::sin(Lat_B_Rad);
// B机相对于A机的直角坐标km
double XYZ_BA[3] = {X_B - X_A, Y_B - Y_A, Z_B - Z_A};
// 双机距离km
double D_BA = std::sqrt(XYZ_BA[0]*XYZ_BA[0] + XYZ_BA[1]*XYZ_BA[1] + XYZ_BA[2]*XYZ_BA[2]);
qDebug()<< "双机距离: "<<D_BA<<"km";
// 根据三轴坐标旋转矩阵计算B机相对于A机的方位角、俯仰角
double Lon_A_Rad1 = Lon_A_Rad;
double Lat_A_Rad1 = -Lat_A_Rad;
double MR_X[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
double MR_Y[3][3] = {
{std::cos(Lat_A_Rad1), 0, -std::sin(Lat_A_Rad1)},
{0, 1, 0},
{std::sin(Lat_A_Rad1), 0, std::cos(Lat_A_Rad1)}
};
double MR_Z[3][3] = {
{std::cos(Lon_A_Rad1), std::sin(Lon_A_Rad1), 0},
{-std::sin(Lon_A_Rad1), std::cos(Lon_A_Rad1), 0},
{0, 0, 1}
};
// 矩阵乘法MR_X * MR_Y * MR_Z
double temp1[3][3], MR_XYZ[3][3];
matrixMultiply(MR_X, MR_Y, temp1);
matrixMultiply(temp1, MR_Z, MR_XYZ);
// 矩阵乘法MR_XYZ * XYZ_BA 天东北坐标
double UEN_BA0[3];
matrixMultiplyVector(MR_XYZ, XYZ_BA, UEN_BA0);
double NED_BA0[3];
NED_BA0[0] = UEN_BA0[2];
NED_BA0[1] = UEN_BA0[1];
NED_BA0[2]= -UEN_BA0[0];
// POS姿态角度换算为弧度
double HeadingReal_Rad = deg2rad(Heading_OPABase-Heading_IMUBase-HeadingReal);
double PitchReal_Rad = deg2rad(Pitch_OPABase-Pitch_IMUBase-PitchReal);
double RollReal_Rad = deg2rad(Roll_OPABase-Roll_IMUBase-RollReal);
// 由实时姿态计算位置的坐标旋转矩阵
double NED_MR_D[3][3] = {
{std::cos(HeadingReal_Rad), -std::sin(HeadingReal_Rad), 0},
{std::sin(HeadingReal_Rad), std::cos(HeadingReal_Rad), 0},
{0, 0, 1}
};
double NED_MR_E[3][3] = {
{std::cos(PitchReal_Rad), 0, std::sin(PitchReal_Rad)},
{0, 1, 0},
{-std::sin(PitchReal_Rad), 0, std::cos(PitchReal_Rad)}
};
double NED_MR_N[3][3] = {
{1, 0, 0},
{0, std::cos(RollReal_Rad), -std::sin(RollReal_Rad)},
{0, std::sin(RollReal_Rad), std::cos(RollReal_Rad)}
};
double temp2[3][3], NED_XYZ[3][3];
matrixMultiply(NED_MR_N, NED_MR_E, temp2);
matrixMultiply(temp2, NED_MR_D, NED_XYZ);
// 矩阵乘法MR_XYZ * XYZ_BA 天东北坐标
double NED_BA_Real[3];
matrixMultiplyVector(NED_XYZ, NED_BA0, NED_BA_Real);
double NED_N_BA_Real=NED_BA_Real[0];
double NED_E_BA_Real=NED_BA_Real[1];
double NED_D_BA_Real=NED_BA_Real[2];
double BARotate_N = rad2deg(atan2(NED_D_BA_Real,NED_E_BA_Real))-OpticalAxisAngle_N0;
double BARotate_E = rad2deg(atan2(NED_D_BA_Real,NED_N_BA_Real))-OpticalAxisAngle_E0;
double OpticalAxisAngle_D0_Rad = deg2rad(OpticalAxisAngle_D0);
double OpticalAxisRotate_N = std::cos(OpticalAxisAngle_D0_Rad)*BARotate_N-std::sin(OpticalAxisAngle_D0_Rad)*BARotate_E;
double OpticalAxisRotate_E = std::sin(OpticalAxisAngle_D0_Rad)*BARotate_N+std::cos(OpticalAxisAngle_D0_Rad)*BARotate_E;
qDebug()<<"OpticalAxisRotate_N is "<< OpticalAxisRotate_N;
qDebug()<<"OpticalAxisRotate_E is "<< OpticalAxisRotate_E;
// 输出结果
QVector<double> res;
res.append(OpticalAxisRotate_E);
res.append(OpticalAxisRotate_N);
return res;
}
#endif // CALPOINT_H