#include "stdafx.h" #include "SARSatelliteSimulationAbstractCls.h" #include #include #include #include #include #include #include #include "BaseTool.h" #include #include #include #include #include #include #include AbstractSatelliteOribtModel::~AbstractSatelliteOribtModel() { } SatelliteOribtNode AbstractSatelliteOribtModel::getSatelliteOribtNode(double& timeFromStartTime, bool& antAzAngleFlag) { return SatelliteOribtNode(); } ErrorCode AbstractSatelliteOribtModel::getSatelliteOribtNode(double& timeFromStartTime, SatelliteOribtNode& node, bool& antAzAngleFlag) { return ErrorCode::VIRTUALABSTRACT; } ErrorCode AbstractSatelliteOribtModel::getSatelliteAntDirectNormal(SatelliteOribtNode& Rs, Vector3D& Rt, SatelliteAntDirect& antNode) { return ErrorCode(); } void AbstractSatelliteOribtModel::setSatelliteOribtStartTime(long double oribtRefrenceTime) { } long double AbstractSatelliteOribtModel::getSatelliteOribtStartTime() { return 0; } void AbstractSatelliteOribtModel::setbeamAngle(double beamAngle, bool RightLook) { } void AbstractSatelliteOribtModel::setAzAngleRange(double cycletime, double minAzAngle, double maxAzAngle, double referenceAzAngle, double referenceTimeFromStartTime) { } double AbstractSatelliteOribtModel::getAzAngleInCurrentTimeFromStartTime(double& currentTime) { return 0.0; } ErrorCode AbstractSatelliteOribtModel::getAzAngleInCurrentTimeFromStartTime(double& currentTime, double& AzAngle) { return ErrorCode::VIRTUALABSTRACT; } void AbstractSatelliteOribtModel::setAntnnaAxisX(double X, double Y, double Z) { } void AbstractSatelliteOribtModel::setAntnnaAxisY(double X, double Y, double Z) { } void AbstractSatelliteOribtModel::setAntnnaAxisZ(double X, double Y, double Z) { } ErrorCode AbstractSatelliteOribtModel::getZeroDopplerAntDirect(SatelliteOribtNode& node) { return ErrorCode(); } ErrorCode AbstractSatelliteOribtModel::getAntnnaDirection(SatelliteOribtNode& node) { return ErrorCode::VIRTUALABSTRACT; } double AbstractSatelliteOribtModel::getPt() { return 0.0; } double AbstractSatelliteOribtModel::getGri() { return 0.0; } void AbstractSatelliteOribtModel::setPt(double Pt) { } void AbstractSatelliteOribtModel::setGri(double gri) { } SatelliteOribtNode AbstractSARSatelliteModel::getSatelliteOribtNode(double& timeFromStartTime, bool& antAzAngleFlag) { return SatelliteOribtNode(); } ErrorCode AbstractSARSatelliteModel::getSatelliteOribtNode(double& timeFromStartTime, SatelliteOribtNode& node, bool& antAzAngleFlag) { return ErrorCode(); } ErrorCode AbstractSARSatelliteModel::getSatelliteAntDirectNormal(SatelliteOribtNode& Rs, Vector3D& Rt, SatelliteAntDirect& antNode) { return ErrorCode(); } void AbstractSARSatelliteModel::setSatelliteOribtModel(std::shared_ptr model) { } void AbstractSARSatelliteModel::setSARImageStartTime(long double imageStartTime) { } void AbstractSARSatelliteModel::setSARImageEndTime(long double imageEndTime) { } double AbstractSARSatelliteModel::getSARImageStartTime() { return 0; } double AbstractSARSatelliteModel::getSARImageEndTime() { return 0; } double AbstractSARSatelliteModel::getNearRange() { return 0.0; } void AbstractSARSatelliteModel::setNearRange(double NearRange) { } double AbstractSARSatelliteModel::getFarRange() { return 0.0; } void AbstractSARSatelliteModel::setFarRange(double FarRange) { } bool AbstractSARSatelliteModel::getIsRightLook() { return false; } void AbstractSARSatelliteModel::setIsRightLook(bool isR) { } void AbstractSARSatelliteModel::setCenterFreq(double Freq) { } double AbstractSARSatelliteModel::getCenterFreq() { return 0.0; } void AbstractSARSatelliteModel::setCenterLamda(double Lamda) { } double AbstractSARSatelliteModel::getCenterLamda() { return 0.0; } void AbstractSARSatelliteModel::setBandWidth(double bandwidth) { } double AbstractSARSatelliteModel::getBandWidth() { return 0.0; } POLARTYPEENUM AbstractSARSatelliteModel::getPolarType() { return POLARTYPEENUM(); } void AbstractSARSatelliteModel::setPolarType(POLARTYPEENUM type) { } void AbstractSARSatelliteModel::setPRF(double prf) { } double AbstractSARSatelliteModel::getPRF() { return 0; } double AbstractSARSatelliteModel::getFs() { return 0; } void AbstractSARSatelliteModel::setFs(double Fs) { } double AbstractSARSatelliteModel::getCenterLookAngle() { return 0.0; } void AbstractSARSatelliteModel::setCenterLookAngle(double angle) { } void AbstractSARSatelliteModel::setTransformRadiationPattern(std::shared_ptr radiationPanttern) { } void AbstractSARSatelliteModel::setReceiveRadiationPattern(std::shared_ptr radiationPanttern) { } std::shared_ptr AbstractSARSatelliteModel::getTransformRadiationPattern() { return std::shared_ptr(); } std::shared_ptr AbstractSARSatelliteModel::getReceiveRadiationPattern() { return std::shared_ptr(); } double AbstractSARSatelliteModel::getPt() { return 0.0; } double AbstractSARSatelliteModel::getGri() { return 0.0; } void AbstractSARSatelliteModel::setPt(double Pt) { } void AbstractSARSatelliteModel::setGri(double gri) { } ErrorCode ReadSateGPSPointsXML(QString xmlPath, std::vector& nodes) { // 读取文件 QFile file(xmlPath); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Cannot open file for reading."; return ErrorCode::FILEOPENFAIL; } QDomDocument doc; if (!doc.setContent(&file)) { qDebug() << "Failed to parse the XML."; file.close(); return ErrorCode::XMLPARSEFAIL; } file.close(); QDomElement root = doc.documentElement(); QDomNodeList gpsParamList = root.firstChildElement("GPS").elementsByTagName("GPSParam"); nodes.clear(); for (int i = 0; i < gpsParamList.size(); ++i) { QDomElement gpsParam = gpsParamList.at(i).toElement(); QDomElement timeStampElement = gpsParam.firstChildElement("TimeStamp"); QDomElement xPositionElement = gpsParam.firstChildElement("xPosition"); QDomElement yPositionElement = gpsParam.firstChildElement("yPosition"); QDomElement zPositionElement = gpsParam.firstChildElement("zPosition"); QDomElement xVelocityElement = gpsParam.firstChildElement("xVelocity"); QDomElement yVelocityElement = gpsParam.firstChildElement("yVelocity"); QDomElement zVelocityElement = gpsParam.firstChildElement("zVelocity"); if (timeStampElement.isNull() || xPositionElement.isNull() || yPositionElement.isNull() || zPositionElement.isNull() || xVelocityElement.isNull() ||yVelocityElement.isNull() ||zVelocityElement.isNull()) { nodes.clear(); return ErrorCode::XMLNOTFOUNDElEMENT; } QString timeStamp = timeStampElement.text(); QString xPosition = xPositionElement.text(); QString yPosition = yPositionElement.text(); QString zPosition = zPositionElement.text(); QString xVelocity = xVelocityElement.text(); QString yVelocity = yVelocityElement.text(); QString zVelocity = zVelocityElement.text(); // 转换 long double timestamp = convertToMilliseconds(timeStamp.toStdString()); SatelliteOribtNode node; node.time = timestamp; node.Px = xPosition.toDouble(); node.Py = yPosition.toDouble(); node.Pz = zPosition.toDouble(); node.Vx = xVelocity.toDouble(); node.Vy = yVelocity.toDouble(); node.Vz = zVelocity.toDouble(); nodes.push_back(node); } qDebug() << "--- GPS Node Extracted -----------------------------------------------------------"; qDebug() << "time\tPx\tPy\tPz\tVx\tVy\tVz"; for (int i = 0; i < nodes.size(); ++i) { SatelliteOribtNode node= nodes[i]; // 打印解译结果 qDebug() << (double)node.time << "\t" << node.Px << "\t" << node.Py << "\t" << node.Pz << "\t" << node.Vx << "\t" << node.Vy << "\t" << node.Vz; } qDebug() << "\n\n\n"; return ErrorCode::SUCCESS; } std::vector FilterSatelliteOribtNode(std::vector& nodes, double startTime, double endTime, long minCount) { if (minCount < nodes.size()) { return std::vector(0); } else {} std::vector dtime(nodes.size()); double centerTime = startTime + (endTime-startTime) / 2.0; // 排序 小 --> 大 std::sort(nodes.begin(), nodes.end(), [](SatelliteOribtNode& a, SatelliteOribtNode& b) { return a.time < b.time; }); // 计算插值 for (long i = 0; i < nodes.size(); i++) { dtime[i] =std::abs(nodes[i].time - centerTime); } // find min value idx long minIdx = 0; double min = dtime[0]; for (long i = 1; i < nodes.size(); i++) { if (dtime[i] < min) { min = (dtime[i]); minIdx = i; } else {} } std::vector result(0); // 左右查找 long left = minIdx; long right = minIdx+1; while (left >= 0 || right < nodes.size()) { // 左右检索 if (left >= 0) { result.push_back(nodes[left]); } else {} left--; if (right < nodes.size()) { result.push_back(nodes[right]); } else {} right++; if (result.size() > minCount) { break; } } return result; } std::shared_ptr CreateAbstractRadiationPattern(std::vector antPatternPoints) { std::shared_ptr pattern = std::make_shared(); for (long i = 0; i < antPatternPoints.size(); i++) { RadiationPatternGainPoint point = antPatternPoints[i]; pattern->setGain(point.theta, point.phi, point.GainValue); } pattern->RecontructGainMatrix(); return pattern; } std::vector ReadGainFile(QString antPatternFilePath) { std::vector dataPoints(0); QFile file(antPatternFilePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Failed to open the file."; return dataPoints; // 返回空向量 } QTextStream in(&file); QStringList headers = in.readLine().split(","); // 读取标题行 qDebug() << "Headers:" << headers; if (headers.count() < 3) { file.close(); return dataPoints; } qDebug() << "parase ant radiation pattern contains "; long theta_id = -1; long phi_id = -1; long gain_id = -1; for (long i = 0; i < headers.size(); i++) { if (headers[i].toLower().contains("theta")) { theta_id = i; } else if (headers[i].toLower().contains("phi")) { phi_id = i; } else if (headers[i].toLower().contains("gain")) { gain_id = i; } } if (theta_id == -1 || phi_id == -1 || gain_id == -1) { qDebug() << "Failed to find the field."; file.close(); return dataPoints; // 返回空向量 } QString line = ""; do{ QString line = in.readLine(); if (line.isNull()) { break; } if (line.isEmpty()) { continue; } QStringList fields = line.split(","); if (fields.size() >=3) { if (fields[0].isEmpty()) { continue; } RadiationPatternGainPoint point{0,0,0}; bool thetaflag = false; bool phiflag = false; bool gainflag = false; point.theta = fields[theta_id].toDouble(&thetaflag); // 这里存在风险,如果数据不是数字,会导致程序崩溃 point.phi = fields[phi_id].toDouble(&phiflag); point.GainValue = fields[gain_id].toDouble(&gainflag); if (!(thetaflag && phiflag && gainflag)) { file.close(); return std::vector< RadiationPatternGainPoint>(0); } // 角度转换为 -180 ~ 180 point.theta = point.theta > 180 ? point.theta - 360 : point.theta; point.phi = point.phi > 180 ? point.phi - 360 : point.phi; dataPoints.push_back(point); } else {} } while (!line.isNull()); qDebug() << "over"; file.close(); return dataPoints; } double getDopplerCenterFreq(double& lamda, double& R, Vector3D& Rs, Vector3D& Rt, Vector3D& Vs, Vector3D& Vt) { return ( - 2 / lamda) * dot(Rs - Rt, Vs - Vt) / R; // 星载合成孔径雷达原始回波数据模拟研究 3.18 } double getDopplerFreqRate(double& lamda, double& R, Vector3D& Rs, Vector3D& Rt, Vector3D& Vs, Vector3D& Vt, Vector3D& Ast) { return -(2/lamda)*(dot(Vs - Vt, Vs - Vt)/R+ dot(Ast, Rs - Rt) /R- std::pow(dot(Vs - Vt, Rs - Rt),2 )/std::pow(R,3));// 星载合成孔径雷达原始回波数据模拟研究 3.19 } AbstractRadiationPattern::AbstractRadiationPattern() { this->GainMap = std::vector(0); this->thetas = std::vector(0); this->phis = std::vector(0); this->GainMatrix = Eigen::MatrixXd(0, 0); } AbstractRadiationPattern::~AbstractRadiationPattern() { } double AbstractRadiationPattern::getGain(double& theta, double& phi ) { double gainValue = 0; ErrorCode state = getGain(theta, phi, gainValue); return gainValue; } std::vector AbstractRadiationPattern::getGainList() { return this->GainMap; } ErrorCode AbstractRadiationPattern::getGain(double& theta, double& phi, double& GainValue) { if (this->mintheta > theta || this->maxthetaminphi>phi || this->maxphi < phi) { GainValue = 0; return ErrorCode::OUTOFRANGE; } if (theta>=0&&std::sin(theta * d2r)*std::cos(phi*d2r) > this->EdgeXMax) { // 越界 GainValue = 0; return ErrorCode::OUTOFRANGE; } if (theta < 0 && -1*std::sin(theta * d2r) * std::cos(phi * d2r) < this->EdgeXMin) { GainValue = 0; return ErrorCode::OUTOFRANGE; } // 插值计算增益 if (this->GainMap.size() == 0) { // 原始增益 GainValue = 1; } else { // --双线性插值 if (this->GainMatrix.rows() != this->phis.size() || this->GainMatrix.cols() != this->thetas.size()) { this->RecontructGainMatrix(); } // 考虑根据双线性采样方法 long lasttheta = FindValueInStdVectorLast(this->thetas,theta); long nextTheta = lasttheta+1; long lastphi = FindValueInStdVectorLast(this->phis, phi);; long nextPhi = lastphi+1; if (lasttheta == -1 || nextTheta == -1 || lastphi == -1 || nextPhi == -1) { return ErrorCode::FIND_ID_ERROR; } double x1 = this->thetas[lasttheta]; double x2 = this->thetas[nextTheta]; double y1 = this->phis[lastphi]; double y2 = this->phis[nextPhi]; //double z11 = this->GainMatrix(lasttheta, lastphi);//std::pow(10,this->GainMatrix(lasttheta, lastphi)/10); //double z12 = this->GainMatrix(lasttheta, nextPhi);//std::pow(10,this->GainMatrix(lasttheta, nextPhi)/10); //double z21 = this->GainMatrix(nextTheta, lastphi);//std::pow(10,this->GainMatrix(nextTheta, lastphi)/10); //double z22 = this->GainMatrix(nextTheta, nextPhi);//std::pow(10,this->GainMatrix(nextTheta, nextPhi)/10); double z11 = std::pow(10,this->GainMatrix(lasttheta, lastphi)/10); double z12 = std::pow(10,this->GainMatrix(lasttheta, nextPhi)/10); double z21 = std::pow(10,this->GainMatrix(nextTheta, lastphi)/10); double z22 = std::pow(10,this->GainMatrix(nextTheta, nextPhi)/10); double x = theta; double y = phi; GainValue = (z11 * (x2 - x) * (y2 - y) + z21 * (x - x1) * (y2 - y) + z12 * (x2 - x) * (y - y1) + z22 * (x - x1) * (y - y1)); GainValue = GainValue / ((x2 - x1) * (y2 - y1)); GainValue = 10.0 * std::log10(GainValue); // 返回dB //qDebug() << "GainValue:" << GainValue << " " << lasttheta << " " << nextTheta << " " << lastphi << " " << nextPhi << " " << z11 << " " << z12 << " " << z21 << " " << z22; ErrorCode::SUCCESS; } return ErrorCode::SUCCESS; } ErrorCode AbstractRadiationPattern::getGainLinear(double& theta, double& phi, double& GainValue) { ErrorCode statecode=this->getGain(theta, phi, GainValue); if (statecode == ErrorCode::OUTOFRANGE) { GainValue = 0; return ErrorCode::SUCCESS; } else { return statecode; } } double AbstractRadiationPattern::getGainLearThetaPhi(double theta, double phi) { double gainvlaue = 0; this->getGainLinear(theta, phi, gainvlaue); return gainvlaue; } ErrorCode AbstractRadiationPattern::setGain(double& theta, double& phi, double& GainValue) { this->GainMap.push_back(RadiationPatternGainPoint{ theta,phi,GainValue }); return ErrorCode::SUCCESS; } ErrorCode AbstractRadiationPattern::RecontructGainMatrix(double threshold ) { this->thetas.clear(); this->phis.clear(); for(long i=0;iGainMap.size();i++){ double thetatempp = this->GainMap[i].theta; double phitempp = this->GainMap[i].phi; InsertValueInStdVector(this->thetas, this->GainMap[i].theta, false); InsertValueInStdVector(this->phis, this->GainMap[i].phi, false); } this->GainMatrix = Eigen::MatrixXd::Zero(this->phis.size(), this->thetas.size()); for (long i = 0; i < this->GainMap.size(); i++) { long theta_idx = FindValueInStdVector(this->thetas, this->GainMap[i].theta); long phi_idx = FindValueInStdVector(this->phis, this->GainMap[i].phi); if (theta_idx == -1 || phi_idx == -1) { qDebug() << "Error: RecontructGainMatrix failed"; return ErrorCode::FIND_ID_ERROR; } this->GainMatrix(theta_idx, phi_idx) = this->GainMap[i].GainValue; } // double mintheta, maxtheta, minphi, maxphi; this->mintheta = this->thetas[0]; this->maxtheta = this->thetas[this->thetas.size() - 1]; this->minphi = this->phis[0]; this->maxphi = this->phis[this->phis.size() - 1]; this->maxGain = this->GainMatrix.maxCoeff();// 最大增益 { this->EdgethetaMin = -90; this->EdgethetaMax = 90; this->EdgeXMax = 1; this->EdgeXMin = -1; } { double phi = 0; double theta = 0; double dt = 1e-6; double maxphiGain = 0; this->getGain(theta, phi, maxphiGain); double gain_tmep = maxphiGain; while (theta <= 90) { this->getGain(theta, phi, gain_tmep); if (gain_tmep > maxphiGain) { maxphiGain = gain_tmep; } theta = theta + dt; } while (theta >=- 90) { gain_tmep = this->getGain(theta, phi); if (gain_tmep > maxphiGain) { maxphiGain = gain_tmep; } theta = theta - dt; } this->maxPhiGain = maxphiGain; qDebug() << "phi=0 Gain : \t" << maxphiGain << " -- " << theta << " -- " << phi; } { double phi = 90; double theta = 0; double dt = 1; double maxphiGain = 0; this->getGain(theta, phi, maxphiGain); double gain_tmep = maxphiGain; while (theta <= 90) { this->getGain(theta, phi, gain_tmep); if (gain_tmep > maxphiGain) { maxphiGain = gain_tmep; } else {} theta = theta + dt; } theta = 0; while (theta >= -90) { gain_tmep = this->getGain(theta, phi); if (gain_tmep > maxphiGain) { maxphiGain = gain_tmep; } theta = theta - dt; } this->maxThetaGain = maxphiGain; qDebug() << "phi=90 Gain : \t" << maxphiGain << " -- " << theta << " -- " << phi; } // 根据阈值计算方位向扫描角的范围,注意这里以dB为单位,选择phi=0 时(即飞行方向,求解不同theta的最大增益) { double thetaEdgeMax = 0; double thetaEdgeMin = 0; double nexttheta = 0; double gain_temp = this->maxPhiGain; double phi = 0; double dt = 1e-5; double dgain = 0; // 直接循环,以1e-6次方为步长 while (thetaEdgeMax <= 90) { gain_temp = this->getGain(thetaEdgeMax, phi); if (gain_temp - this->maxPhiGain < threshold) { break; } thetaEdgeMax = thetaEdgeMax + dt; } while (thetaEdgeMin > -90) { gain_temp = this->getGain(thetaEdgeMin, phi); if (gain_temp - this->maxPhiGain < threshold) { break; } thetaEdgeMin = thetaEdgeMin - dt; } this->EdgethetaMax = thetaEdgeMax; this->EdgethetaMin = thetaEdgeMin; qDebug() << "phi=0 theta :\t" << thetaEdgeMin << " -- " << thetaEdgeMax; this->EdgeXMax = std::sin(thetaEdgeMax * d2r); // 计算X 轴范围 this->EdgeXMin = -1*std::sin(thetaEdgeMin * d2r); } return ErrorCode::SUCCESS; } std::vector AbstractRadiationPattern::getThetas() { return this->thetas; } std::vector AbstractRadiationPattern::getPhis() { return this->phis; } Eigen::MatrixXd AbstractRadiationPattern::getGainMatrix() { return this->GainMatrix; } double AbstractRadiationPattern::getMaxTheta() { double maxtheta = this->thetas[0]; long len = this->thetas.size(); if (maxtheta < this->thetas[len - 1]) { maxtheta = this->thetas[len - 1]; } return maxtheta; } double AbstractRadiationPattern::getMinTheta() { double mintheta = this->thetas[0]; long len = this->thetas.size(); if (mintheta > this->thetas[len - 1]) { mintheta = this->thetas[len - 1]; } return mintheta; return 0.0; } double AbstractRadiationPattern::getMaxPhi() { double maxphi = this->phis[0]; long len = this->phis.size(); if (maxphi < this->phis[len - 1]) { maxphi = this->phis[len - 1]; } return maxphi; return 0.0; } double AbstractRadiationPattern::getMinPhi() { double minphi = this->phis[0]; long len = this->phis.size(); if (minphi > this->phis[len - 1]) { minphi = this->phis[len - 1]; } return minphi; return 0.0; }