You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
9.3 KiB

/*********版权所有C2020武汉高德红外股份有限公司***************************************
* Arith_ZHRPY.h
*
* <-> --
*
* 2.0
* 11531yj
* 2023.10.26
*
*****************************************************************************************/
#ifndef Arith_ZHRPY_h__
#define Arith_ZHRPY_h__
#include <math.h>
#include <memory.h>
namespace sRPYCacl {
/********************************************************
:
* y x/
-z
* x0°0-360°
* y0° 0-90°
* z0° -180-180°/
**********************************************************
*
**********************************************************/
#define ANGLE(x) (x / 3.141592653589793 * 180)
#define RADIAN(x) (x / 180 * 3.141592653589793)
#define ABS(x) ((x) < 0 ? -(x) : (x)) //取x的绝对值
#define MIN(a, b) ((a) < (b) ? (a) : (b)) //取a、b两者中的最小值
#define MAX(a, b) ((a) > (b) ? (a) : (b)) //取a、b两者中的最大值
#define PI 3.141592653589793
#define AzimuthMax 360
#define PitchMax 80
#define PitchMin -5
#define Standardzation 1 //1/0 1 标定误差模式 / 0 修正后定位模式
#define RPYMode 1 // 1 载机姿态角参与计算 / 0 载荷姿态角参与计算
#define ROWS 5 //读数据的行数
#define COLS 9 //读数据的列数
typedef double DOUBLE64;
typedef int SINT32;
const double a = 6378137; //地球长轴
const double f = 1 / 298.257222101; //地球椭偏率
const double b = 6356752.3141; //地球短轴
const double ee = 0.0066943800229; //地球第一偏心率
const double epep = 0.00673949677548; //地球第二偏心率
const int FrameRate = 20; //帧频HZ 729帧频50HZ、5kg帧频20HZ
/**********************************************************
*
**********************************************************/
//光电伺服坐标系到光电基准坐标系的安装旋角误差
typedef struct tgAngle3D {
DOUBLE64 dHAngle; //航向夹角
DOUBLE64 dVAngle; //俯仰夹角
DOUBLE64 dSAngle; //横滚夹角
}Angle3D;
//光电基准到载体惯导直角坐标系位置偏差
typedef struct tgBiasXYZ {
DOUBLE64 deltaX; //X坐标的偏差
DOUBLE64 deltaY; //Y坐标的偏差
DOUBLE64 deltaZ; //Z坐标的偏差
}BiasXYZ;
//RPY姿态角
typedef struct tgEulerRPY {
DOUBLE64 Yaw; //方位角
DOUBLE64 Pitch; //俯仰角
DOUBLE64 Roll; //横滚角
}EulerRPY;
//定义空间直角坐标系
typedef struct tgPointXYZ {
DOUBLE64 X;
DOUBLE64 Y;
DOUBLE64 Z;
}PointXYZ;
//定义大地坐标系
typedef struct tgPointBLH
{
DOUBLE64 B; //纬度
DOUBLE64 L; //经度
DOUBLE64 H; //高度
}PointBLH;
//定义极坐标系
typedef struct tgPointPole {
DOUBLE64 Pitch; //俯仰角
DOUBLE64 Azimuth; //方位角
DOUBLE64 distance; //极径
DOUBLE64 fRoll; //横滚
}Pole;
//目标结构体
typedef struct stTrgOutput
{
unsigned char nObjID; //目标编号
double tLon; //目标经度
double tLat; //目标纬度
double tH; //目标高度
double tX; //地心地固X
double tY; //地心地固Y
double tZ; //地心地固Z
double tSpeedX; //目标X方向速度
double tSpeedY; //目标Y方向速度
double tSpeedZ; //目标Z方向速度
double Speed; //目标的合速度
}stTrgOutput;
//载机结构体
typedef struct stTrackPlatInfo
{
unsigned char nPlaneID; //载机编号
double fLon; //载机经度
double fLat; //载机纬度
double fWGS_H; //载机高度
double fPlatAz; //载机航向角
double fPlatPt; //载机俯仰角
double fPlatRoll; //载机横滚角
double fServoAz; //伺服方位角
double fServoPt; //伺服俯仰角
double fRoll; //伺服横滚角
double x; //CGCS直角坐标x
double y; //CGCS直角坐标y
double z; //CGCS直角坐标z
double Distance; //激光测距值
double tarLon; //目标真实经度
double tarLat; //目标真实纬度
double tarH; //目标真实高度
}stTrackPlatInfo;
//标定误差参数设置
void setBiasPara(Angle3D EoServoToEoBias, BiasXYZ EoToZTPosBias);
/**********************************************************
*
**********************************************************/
///////////////////////////////////////光电目标测角上报////////////////////////////////////////////////
//光电吊舱伺服极坐标 转 (北天东)地理极坐标
Pole getNUEPoleFromEOServoPole(Pole targetServoPole, EulerRPY stEulerRPY);
//光电吊舱伺服极坐标 转 光电伺服直角坐标
PointXYZ getXYZFromPole(Pole targetServoPole);
//光电伺服直角坐标 转 光电基准直角坐标
PointXYZ getEOBaseXYZFromEOServoXYZ(PointXYZ targetServoXYZ, Angle3D eoServoToEoBias);
//光电基准直角坐标 转 载体惯导直角坐标
PointXYZ getZTXYZFromEOBaseXYZ(PointXYZ targetEOBaseXYZ, BiasXYZ eoToZTPosBias);
//函数功能用于计算最优修正矩阵AngleError3D在转换过程中找最优的修正矩阵 [载体惯导直角坐标 ->北天东直角坐标 -> 北天东极坐标-> 目标大地坐标(经纬高)]
PointBLH getPosFromZTXYZ(PointXYZ targetZTXYZ, EulerRPY stEulerRPY, PointBLH selfPointBLH, PointBLH targetBLH, double* Sum_Error_Min, Angle3D* AngleError3D);
//载体惯导直角坐标 转 地理直角坐标
PointXYZ getNUEXYZFromZTXYZ(PointXYZ targetZTXYZ, EulerRPY stEulerRPY);
//地理直角坐标 转 地理极坐标
Pole getPoleFromXYZ(PointXYZ targetNUEXYZ);
////////////////////////////////目标大地坐标系下经纬高解算///////////////////////////////////
//目标的地理极坐标 转 大地坐标系下的坐标
PointBLH getPosFromNUEPole(Pole targetNUEPole, PointBLH selfPointBLH);
//载机自身的经纬高 转 地心空间直角坐标系
PointXYZ getXYZFromBLH(PointBLH selfPointBLH);
//目标的地理极坐标 转 地理直角坐标
PointXYZ getZTFromPole(Pole targetPole);
//目标的地心空间直角坐标
PointXYZ getCGCSFromNUE(PointXYZ targetPointXYZ, PointXYZ selfPointXYZ);
//目标的地心空间直角坐标转地心大地坐标
PointBLH getBLHFromXYZ(PointXYZ pointXYZ);
///////////////////////////////////////目标地理导引//////////////////////////////////////////////////////////
//目标经纬高、载机自身经纬高 转 到 地理极坐标
Pole getNUEPoleFromENUXYZ(PointBLH ptselfBLH, PointBLH ptTargetBLH);
//从地心地固直角坐标 转 极坐标
Pole getPoleFromCGCS(PointXYZ ptTargetXYZ, PointXYZ ptSelfXYZ);
// 从地心地固直角坐标 转 北天东直角坐标
PointXYZ getENUFromCGCS(PointXYZ ptTargetXYZ, PointXYZ ptSelfXYZ);
// 从载体直角坐标 转 极坐标
Pole getPoleFromZT(PointXYZ targetPointXYZ);
//(北天东)地理极坐标 转 光电伺服坐标系下的极坐标
Pole getEOServoPoleFromNUEPole(Pole targetNUEPole, EulerRPY stEulerRPY);
//地理直角坐标 转 载体惯导直角坐标
PointXYZ getZTXYZFromNUEXYZ(PointXYZ targetNUEXYZ, EulerRPY nueToZTBias);
//载体惯导坐标系下的直角坐标 转 光电基准系下的直角坐标
PointXYZ getEOBaseXYZFromZTXYZ(PointXYZ targetZTXYZ, BiasXYZ ztToEOBaseBias);
//光电基准系直角 转 光电伺服坐标系下直角坐标
PointXYZ getEOServoXYZFromEOBaseXYZ(PointXYZ targetEOBaseXYZ, Angle3D eoBaseToEOServoBias);
//直角坐标转极坐标(右手系)
Pole getPoleFromXYZ(PointXYZ targetXYZ);
//极坐标转直角坐标(右手系)
PointXYZ getXYZFromPole(Pole targetPole);
//误差修正函数:函数返回值为修正矩阵,函数只调用一次
Angle3D getAngle3DFromEOServoPole(Pole targetServoPole, EulerRPY stEulerRPY, PointBLH selfPointBLH, PointBLH targetBLH, double* Sum_Error_Min, Angle3D* AngleError3D);
Angle3D TarGetLocate_Cal(stTrackPlatInfo mytrack);
EulerRPY Zh_dRPY(stTrackPlatInfo track);
EulerRPY Zh_dRPYDown(stTrackPlatInfo track);
//矩阵乘法
void MultiMat(DOUBLE64* A, DOUBLE64* B, DOUBLE64* AB, SINT32 m, SINT32 n, SINT32 p);
//M1(3*3) * M2(3*3)
void MultiMat33(DOUBLE64* A, DOUBLE64* B, DOUBLE64* AB);
//M1(3*3) * M2(3*3) * M3(3*3)
void MultiMat333(DOUBLE64* A, DOUBLE64* B, DOUBLE64* C, DOUBLE64* ABC);
//坐标(矢量)旋转: M1(3*3) * M2(3,1)
PointXYZ RtPoint(DOUBLE64* M, PointXYZ Point);
//绕X轴旋转矩阵
void Rx(DOUBLE64 omega, DOUBLE64* Opp);
//绕Y轴旋转矩阵
void Ry(DOUBLE64 omega, DOUBLE64* Opp);
//绕Z轴旋转矩阵
void Rz(DOUBLE64 omega, DOUBLE64* Opp);
void R_y(DOUBLE64 omega, DOUBLE64* Opp);
EulerRPY SumRPYCacl(Pole ServoAngle, EulerRPY s_RPYAngle);
EulerRPY SumRPYCaclDown(Pole ServoAngle, EulerRPY s_RPYAngle);
}
#endif