#include "stdafx.h" #include "SARSatelliteSimulationAbstractCls.h" #include #include #include #include #include #include #include #include "BaseTool.h" #include #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; } QVector AbstractSARSatelliteModel::getFreqList() { double bandwidth = this->getBandWidth()/1e6; // 频率范围 double centerFreq = this->getCenterFreq() / 1e6; // 中心频率 double nearR = this->getNearRange(); double farR = this->getFarRange(); // 计算分辨率 long long centerFreq_long = long long(centerFreq); long long bandwidth_long = long long(bandwidth); long long bandhalf = ceil(bandwidth_long / 2); long long bw = bandhalf * 2; double Resolution = LIGHTSPEED / 2.0/1e6 / bw; long freqpoints = ceil((farR - nearR) / Resolution + 1); Eigen::VectorXd freqs=Eigen::VectorXd::LinSpaced(freqpoints, -bandhalf, bandhalf); freqs = freqs.array() + 1.0 * centerFreq_long; QVector freqlist(freqpoints); for (long i = 0; i < freqpoints; i++) { freqlist[i] = freqs[i]*1e6; } return freqlist; } void AbstractSARSatelliteModel::setRefphaseRange(double refRange) { this->refRangePhase = refRange; } double AbstractSARSatelliteModel::getRefphaseRange() { return this->refRangePhase; } POLARTYPEENUM AbstractSARSatelliteModel::getPolarType() { return POLARTYPEENUM(); } void AbstractSARSatelliteModel::setPolarType(POLARTYPEENUM type) { } void AbstractSARSatelliteModel::setPRF(double prf) { } double AbstractSARSatelliteModel::getPRF() { return 0; } double AbstractSARSatelliteModel::getFs() { double NearRange = this->getNearRange(); double FarRange = this->getFarRange(); QVector freqpoints = this->getFreqList(); long freqNum = freqpoints.size(); double timeRange = 2 * (FarRange - NearRange) / LIGHTSPEED; double fs = (freqNum-1) / timeRange; return fs; //return 0.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) { } double AbstractSARSatelliteModel::getDopplerParametersReferenceTime() { return 0.0; } void AbstractSARSatelliteModel::setDopplerParametersReferenceTime(double time) { } std::vector AbstractSARSatelliteModel::getDopplerCentroidCoefficients() { return std::vector(); } void AbstractSARSatelliteModel::setDopplerCentroidCoefficients(std::vector DopplerCentroids) { } std::vector AbstractSARSatelliteModel::getDopplerRateValuesCoefficients() { return std::vector(); } void AbstractSARSatelliteModel::setDopplerRateValuesCoefficients(std::vector DopplerRateValues) { } 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(new AbstractRadiationPattern); for (long i = 0; i < antPatternPoints.size(); i++) { pattern->setGain(antPatternPoints[i].theta, antPatternPoints[i].phi, antPatternPoints[i].GainValue); } pattern->RecontructGainMatrix(); return pattern; } std::vector ReadGainFile(QString antPatternFilePath) { std::vector dataPoints(0); //std::vector dataPoints; if (!QFileInfo(antPatternFilePath).exists()) { return dataPoints; } std::string filepath = antPatternFilePath.toLocal8Bit().constData(); qDebug() << "ant file path:\t" << QString::fromStdString(filepath); std::ifstream file(filepath); if (!file.is_open()) { std::cerr << "Failed to open the file." << std::endl; return dataPoints; // 返回空向量 } file.seekg(0); std::string headerline; std::getline(file, headerline); // 读取标题行 std::vector headers; std::stringstream ss(headerline); std::string header; while (std::getline(ss, header, ',')) { headers.push_back(header); } qDebug() << "Headers:"; for (const auto& h : headers) { qDebug() << " " << QString::fromStdString(h); } if (headers.size() < 3) { file.close(); return dataPoints; // 返回空向量 } qDebug() << "Parse ant radiation pattern contains " ; long theta_id = -1; long phi_id = -1; long gain_id = -1; // 查找 'theta', 'phi', 'gain' 字段 for (size_t i = 0; i < headers.size(); ++i) { std::string header_lower = headers[i]; std::transform(header_lower.begin(), header_lower.end(), header_lower.begin(), ::tolower); if (header_lower.find("theta") != std::string::npos) { theta_id = i; } else if (header_lower.find("phi") != std::string::npos) { phi_id = i; } else if (header_lower.find("gain") != std::string::npos) { gain_id = i; } } if (theta_id == -1 || phi_id == -1 || gain_id == -1) { std::cerr << "Failed to find the field." << std::endl; file.close(); return dataPoints; // 返回空向量 } std::vector lines(0); // 读取数据行 std::string line; while (std::getline(file, line)) { if (line.empty()) { break; } lines.push_back(line); } qDebug() << "Read file over" ; file.close(); dataPoints = std::vector< RadiationPatternGainPoint>(lines.size()); for (long ii = 0; ii < dataPoints.size(); ii++) { line = lines[ii]; QStringList fields = QString::fromStdString(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[ii] = point; } else {} } lines.clear(); //lines.swap(std::vector(0)); 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 (this->GainMap.size() == 0) { // 原始增益 GainValue = 1; } else { // --双线性插值 if (this->GainMatrix.rows() != this->thetas.size() || this->GainMatrix.cols() != this->phis.size()) { return ErrorCode::OUTOFRANGE; } // 考虑根据双线性采样方法 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 z11 = this->GainMatrix(lasttheta, lastphi) ; double z12 = this->GainMatrix(lasttheta, nextPhi) ; double z21 = this->GainMatrix(nextTheta, lastphi) ; double z22 = this->GainMatrix(nextTheta, nextPhi) ; 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; } /* * 重构天线方向图矩阵 * 这个函数存在堆溢出问题,与2024年12月19日重写 * 根据阈值计算方位向扫描角的范围,注意这里以dB为单位,选择phi=0 时(即飞行方向,求解不同theta的最大增益) */ ErrorCode AbstractRadiationPattern::RecontructGainMatrix(double threshold) { this->thetas.clear(); this->phis.clear(); for (long i = 0; i < this->GainMap.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->thetas.size(), this->phis.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||theta_idx<0||phi_idx<0||theta_idx>=this->thetas.size()||phi_idx>=this->phis.size()) { 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]; long thetanum = this->thetas.size(); long phinum = this->phis.size(); Eigen::VectorXd thetapoints = linspace(mintheta, maxtheta, thetanum); Eigen::VectorXd phipoints = linspace(minphi, maxphi, phinum); Eigen::MatrixXd gaintemp = Eigen::MatrixXd::Zero(thetanum, phinum); qDebug() << "gain init" ; for (long i = 0; i < thetanum; i++) { for (long j = 0; j < phinum; j++) { gaintemp(i, j) = this->getGain(thetapoints[i], phipoints[j]); } } this->GainMatrix = Eigen::MatrixXd::Zero(thetanum, phinum); for (long i = 0; i < thetanum; i++) { for (long j = 0; j < phinum; j++) { this->GainMatrix(i, j) = gaintemp(i, j); } } this->thetas.clear(); for (long i = 0; i < thetanum; i++) { this->thetas.push_back(thetapoints[i]); } this->phis.clear(); for (long i = 0; i < phinum; i++) { this->phis.push_back(phipoints[i]); } 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; }