#ifndef GPUTOOL_H #define GPUTOOL_H #ifdef __CUDANVCC___ #include "BaseConstVariable.h" #include #include #include #include // 默认显存分布 enum LAMPGPUDATETYPE { LAMP_LONG, LAMP_FLOAT, LAMP_COMPLEXFLOAT }; extern "C" struct CUDASigmaParam { float p1; float p2; float p3; float p4; float p5; float p6; }; extern "C" struct CUDAVector { float x; float y; float z; }; extern "C" struct CUDAVectorEllipsoidal { float theta; float phi; float pho; }; // GPU 内存函数 extern "C" void* mallocCUDAHost( long memsize); // 主机内存声明 extern "C" void FreeCUDAHost(void* ptr); extern "C" void* mallocCUDADevice( long memsize); // GPU内存声明 extern "C" void FreeCUDADevice(void* ptr); extern "C" void HostToDevice(void* hostptr, void* deviceptr, long memsize);//GPU 内存数据转移 设备 -> GPU extern "C" void DeviceToHost(void* hostptr, void* deviceptr, long memsize);//GPU 内存数据转移 GPU -> 设备 // 仿真所需的常用函数 extern "C" void distanceAB(float* Ax, float* Ay, float* Az, float* Bx, float* By, float* Bz, float* R, long member); extern "C" void BdistanceAs(float* Ax, float* Ay, float* Az, float Bx, float By, float Bz, float* R, long member); extern "C" void make_VectorA_B(float sX, float sY, float sZ, float* tX, float* tY, float* tZ, float* RstX, float* RstY, float* RstZ, long member); extern "C" void Norm_Vector(float* Vx, float* Vy, float* Vz, float* R, long member); extern "C" void cosAngle_VA_AB(float* Ax, float* Ay, float* Az, float* Bx, float* By, float* Bz, float* anglecos, long len); extern "C" void SatelliteAntDirectNormal(float* RstX, float* RstY, float* RstZ, float antXaxisX, float antXaxisY, float antXaxisZ, float antYaxisX, float antYaxisY, float antYaxisZ, float antZaxisX, float antZaxisY, float antZaxisZ, float antDirectX, float antDirectY, float antDirectZ, float* thetaAnt, float* phiAnt, long len); extern "C" void calculationEcho(float* sigma0, float* TransAnt, float* ReciveAnt,float* localangle, float* R, float* slopeangle,float nearRange, float Fs, float pt, float lamda, long FreqIDmax,cuComplex* echoAmp, long* FreqID, long len); extern "C" void CUDA_RTPC_SiglePRF( float antPx, float antPy, float antPZ,// 天线坐标 float antXaxisX, float antXaxisY, float antXaxisZ, // 天线坐标系 float antYaxisX, float antYaxisY, float antYaxisZ, // float antZaxisX, float antZaxisY, float antZaxisZ, float antDirectX, float antDirectY, float antDirectZ,// 天线指向 float* demx, float* demy, float* demz,long* demcls, // 地面坐标 float* demslopex, float* demslopey, float* demslopez, float* demslopeangle,// 地面坡度 float* Tantpattern, float Tstarttheta, float Tstartphi, float Tdtheta, float Tdphi, long Tthetapoints, long Tphipoints,// 天线方向图相关 float* Rantpattern, float Rstarttheta, float Rstartphi, float Rdtheta, float Rdphi, long Rthetapoints, long Rphipoints,// 天线方向图相关 float lamda, float fs, float nearrange, float Pt, long Freqnumbers, // 参数 CUDASigmaParam* sigma0Paramslist, long sigmaparamslistlen,// 地表覆盖类型-sigma插值对应函数-ulaby cuComplex* outecho,long* d_echoAmpFID, long len ); #endif #endif /** * double* databuffer = new double[nXSize * nYSize * 2]; poBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, databuffer, cols_count, rows_count, GDT_CFloat64, 0, 0); GDALClose((GDALDatasetH)poDataset); Eigen::MatrixXcd rasterData(nYSize, nXSize); // 使用Eigen的MatrixXcd for(size_t i = 0; i < nYSize; i++) { for(size_t j = 0; j < nXSize; j++) { rasterData(i, j) = std::complex(databuffer[i * nXSize * 2 + j * 2], databuffer[i * nXSize * 2 + j * 2 + 1]); } } delete[] databuffer; gdalImage demxyz(demxyzPath);// 地面点坐标 gdalImage demlandcls(this->LandCoverPath);// 地表覆盖类型 gdalImage demsloperxyz(this->demsloperPath);// 地面坡向 omp_lock_t lock; // 定义锁 omp_init_lock(&lock); // 初始化锁 long start_ids = 1250; for (start_ids = 1; start_ids < demxyz.height; start_ids = start_ids + line_invert) { // 8+ 17 + 0.3 MB QDateTime current = QDateTime::currentDateTime(); long pluseStep = Memory1MB * 100 / 3 / PlusePoint; if (pluseStep * num_thread * 3 > this->PluseCount) { pluseStep = this->PluseCount / num_thread / 3; } pluseStep = pluseStep > 50 ? pluseStep : 50; qDebug() << current.toString("yyyy-MM-dd HH:mm:ss.zzz") << " \tstart \t " << start_ids << " - " << start_ids + line_invert << "\t" << demxyz.height << "\t pluseCount:\t" << pluseStep; // 文件读取 Eigen::MatrixXd dem_x = demxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 1); // Eigen::MatrixXd dem_y = demxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 2); // Eigen::MatrixXd dem_z = demxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 3); // // 地表覆盖 std::shared_ptr dem_landcls = readDataArr(demlandcls, start_ids - 1, 0, line_invert + 1, demxyz.width, 1, GDALREADARRCOPYMETHOD::VARIABLEMETHOD); // 地表覆盖类型 long* dem_landcls_ptr = dem_landcls.get(); double localAngle = 30.0; bool sigmaNoZeroFlag = true; for (long ii = 0; ii < dem_x.rows(); ii++) { for (long jj = 0; jj < dem_y.cols(); jj++) { if (0 != this->SigmaDatabasePtr->getAmp(dem_landcls_ptr[dem_x.cols() * ii + jj], localAngle, polartype)) { sigmaNoZeroFlag = false; break; } } if (!sigmaNoZeroFlag) { break; } } if (sigmaNoZeroFlag) { continue; } //#ifdef DEBUGSHOWDIALOG // dialog->load_double_MatrixX_data(dem_z, "dem_z"); //#endif Eigen::MatrixXd demsloper_x = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 1); // Eigen::MatrixXd demsloper_y = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 2); // Eigen::MatrixXd demsloper_z = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 3); // Eigen::MatrixXd sloperAngle = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 4); // sloperAngle = sloperAngle.array() * T180_PI; long dem_rows = dem_x.rows(); long dem_cols = dem_x.cols(); long freqidx = 0;// #ifdef DEBUGSHOWDIALOG ImageShowDialogClass* dialog = new ImageShowDialogClass(nullptr); dialog->show(); Eigen::MatrixXd landaArr = Eigen::MatrixXd::Zero(dem_rows, dem_cols); for (long i = 0; i < dem_rows; i++) { for (long j = 0; j < dem_cols; j++) { landaArr(i, j) = dem_landcls.get()[i * dem_cols + j]; } } dialog->load_double_MatrixX_data(landaArr, "landCover"); #endif //qDebug() << " pluse bolck size :\t " << pluseStep << " all size:\t" << this->PluseCount; long processNumber = 0; #pragma omp parallel for for (long startprfidx = 0; startprfidx < this->PluseCount; startprfidx = startprfidx + pluseStep) { // 17 + 0.3 MB long prfcount_step = startprfidx + pluseStep < this->PluseCount ? pluseStep : this->PluseCount - startprfidx; Eigen::MatrixXcd echoPluse = Eigen::MatrixXcd::Zero(prfcount_step, PlusePoint); // 当前脉冲的回波积分情况 // 内存预分配 Eigen::MatrixXd Rst_x = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd Rst_y = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd Rst_z = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd R = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd localangle = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd Vst_x = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd Vst_y = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd Vst_z = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd fde = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd fr = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd Rx = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd sigam = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd echoAmp = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()).array() + Pt; Eigen::MatrixXd Rphi = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd TimeRange = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd TransAnt = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd ReciveAnt = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd AntTheta = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); Eigen::MatrixXd AntPhi = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()); double minR = 0, maxR = 0; double minLocalAngle = 0, maxLocalAngle = 0; Vector3D Rt = { 0,0,0 }; SatelliteOribtNode oRs = SatelliteOribtNode{ 0 };; Vector3D p0 = {}, slopeVector = {}, sateAntDirect = {}; Vector3D Rs = {}, Vs = {}, Ast = {}; SatelliteAntDirect antdirectNode = {}; std::complex echofreq; std::complex Imag1(0, 1); double TAntPattern = 1; // 发射天线方向图 double RAntPanttern = 1;// 接收天线方向图 double maxechoAmp = 1; double tempAmp = 1; for (long prfidx = 0; prfidx < prfcount_step; prfidx++) { oRs = sateOirbtNodes[prfidx + startprfidx]; // 计算天线方向图 for (long jj = 1; jj < dem_cols - 1; jj++) { for (long ii = 1; ii < dem_rows - 1; ii++) { p0.x = dem_x(ii, jj); p0.y = dem_y(ii, jj); p0.z = dem_z(ii, jj); this->TaskSetting->getSatelliteAntDirectNormal(oRs, p0, antdirectNode); //antdirectNode.ThetaAnt = antdirectNode.ThetaAnt * r2d; //antdirectNode.PhiAnt = antdirectNode.PhiAnt * r2d; AntTheta(ii, jj) = antdirectNode.ThetaAnt * r2d; AntPhi(ii, jj) = antdirectNode.PhiAnt * r2d; } } // 计算发射天线方向图 for (long jj = 1; jj < dem_cols - 1; jj++) { for (long ii = 1; ii < dem_rows - 1; ii++) { TransformPattern->getGainLinear(AntTheta(ii, jj), AntPhi(ii, jj), TransAnt(ii, jj)); //TransAnt(ii, jj) = TAntPattern; } } // 计算接收天线方向图 for (long jj = 1; jj < dem_cols - 1; jj++) { for (long ii = 1; ii < dem_rows - 1; ii++) { TransformPattern->getGainLinear(AntTheta(ii, jj), AntPhi(ii, jj), ReciveAnt(ii, jj)); //ReciveAnt(ii, jj) = RAntPanttern; } } // 计算经过增益的能量 echoAmp = Pt * TransAnt.array() * ReciveAnt.array(); maxechoAmp = echoAmp.maxCoeff(); if (std::abs(maxechoAmp) < PRECISIONTOLERANCE) { // 这种情况下,不在合成孔径范围中 continue; } Rs.x = sateOirbtNodes[prfidx + startprfidx].Px; // 卫星位置 Rs.y = sateOirbtNodes[prfidx + startprfidx].Py; Rs.z = sateOirbtNodes[prfidx + startprfidx].Pz; Vs.x = sateOirbtNodes[prfidx + startprfidx].Vx; // 卫星速度 Vs.y = sateOirbtNodes[prfidx + startprfidx].Vy; Vs.z = sateOirbtNodes[prfidx + startprfidx].Vz; Ast.x = sateOirbtNodes[prfidx + startprfidx].AVx;// 卫星加速度 Ast.y = sateOirbtNodes[prfidx + startprfidx].AVy; Ast.z = sateOirbtNodes[prfidx + startprfidx].AVz; Rst_x = Rs.x - dem_x.array(); // Rst = Rs - Rt; Rst_y = Rs.y - dem_y.array(); Rst_z = Rs.z - dem_z.array(); R = (Rst_x.array().pow(2) + Rst_y.array().pow(2) + Rst_z.array().pow(2)).array().sqrt(); // R minR = R.minCoeff(); maxR = R.maxCoeff(); //qDebug() << "minR:\t" << minR << " maxR:\t" << maxR; if (maxRFarRange) { continue; } else {} // getCosAngle // double c = dot(a, b) / (getlength(a) * getlength(b)); // return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d; // localangle = getCosAngle(Rst, slopeVector) * T180_PI; // 注意这个只能实时计算,因为非实时计算代价太大 localangle = (Rst_x.array() * demsloper_x.array() + Rst_y.array() * demsloper_y.array() + Rst_z.array() * demsloper_z.array()).array(); // dot(a, b) localangle = localangle.array() / R.array(); localangle = localangle.array() / (demsloper_x.array().pow(2) + demsloper_y.array().pow(2) + demsloper_z.array().pow(2)).array().sqrt().array(); localangle = localangle.array().acos(); // 弧度值 minLocalAngle = localangle.minCoeff(); maxLocalAngle = localangle.maxCoeff(); if (maxLocalAngle<0 || minLocalAngle>PI / 2) { continue; } else {} //Vst_x = Vs.x + 1 * earthRoute * dem_y.array(); // Vst = Vs - Vt; //Vst_y = Vs.y - 1 * earthRoute * dem_x.array(); //Vst_z = Vs.z - Eigen::MatrixXd::Zero(dem_x.rows(), dem_y.cols()).array(); //// 计算多普勒中心频率 Rst, Vst : ( - 2 / lamda) * dot(Rs - Rt, Vs - Vt) / R; // 星载合成孔径雷达原始回波数据模拟研究 3.18 //fde = (-2 / lamda) * (Rst_x.array() * Vst_x.array() + Rst_y.array() * Vst_y.array() + Rst_z.array() * Vst_z.array()).array() / (R.array()); //// 计算多普勒频率斜率 // 星载合成孔径雷达原始回波数据模拟研究 3.19 //// -(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)); //fr = (-2 / lamda) * // (Vst_x.array() * Vst_x.array() + Vst_y.array() * Vst_y.array() + Vst_z.array() * Vst_z.array()).array() / (R.array()) + // (-2 / lamda) * // (Ast.x * Rst_x.array() + Ast.y * Rst_y.array() + Ast.z * Rst_z.array()).array() / (R.array()) - // (-2 / lamda) * // (Vst_x.array() * Rst_x.array() + Vst_y.array() * Rst_y.array() + Vst_z.array() * Rst_z.array()).array().pow(2) / (R.array().pow(3)); // 计算回波 Rx = R;// -(lamda / 2) * (fde * TRx + 0.5 * fr * TRx * TRx); // 斜距历程值 // 逐点计算 this->SigmaDatabasePtr->getAmp(covercls, localangle, polartype); // 后向散射系数 HH for (long ii = 0; ii < dem_x.rows(); ii++) { for (long jj = 0; jj < dem_y.cols(); jj++) { sigam(ii, jj) = this->SigmaDatabasePtr->getAmp(dem_landcls_ptr[dem_x.cols() * ii + jj], localangle(ii, jj) * r2d, polartype); } } if (sigam.maxCoeff() > 0) {} else { continue; } // projArea = 1 / std::cos(sloperAngle) * std::sin(localangle); // 投影面积系数,单位投影面积 1m x 1m --注意这里是假设,后期再补充 // echoAmp = projArea*TAntPattern * RAntPanttern * sigam / (4 * PI * R * R); echoAmp = echoAmp.array() * sigam.array() * (1 / sloperAngle.array().cos() * localangle.array().sin()); // 反射强度 echoAmp = echoAmp.array() / (4 * PI * R.array().pow(2)); // 距离衰减 Rphi = -4 * PI / lamda * Rx.array();// 距离徙动相位 // 积分 TimeRange = ((2 * R.array() / LIGHTSPEED - TimgNearRange).array() * Fs).array(); double localAnglepoint = -1; long prf_freq_id = 0; for (long jj = 1; jj < dem_cols - 1; jj++) { for (long ii = 1; ii < dem_rows - 1; ii++) { prf_freq_id = std::floor(TimeRange(ii, jj)); if (prf_freq_id < 0 || prf_freq_id >= PlusePoint || localangle(ii, jj) < 0 || localangle(ii, jj) > PI / 2 || echoAmp(ii, jj) == 0) { continue; } echofreq = echoAmp(ii, jj) * std::exp(Rphi(ii, jj) * Imag1); echoPluse(prfidx, prf_freq_id) = echoPluse(prfidx, prf_freq_id) + echofreq; } } #ifdef DEBUGSHOWDIALOG ImageShowDialogClass* localangledialog = new ImageShowDialogClass(dialog); localangledialog->show(); localangledialog->load_double_MatrixX_data(localangle.array() * r2d, "localangle"); ImageShowDialogClass* sigamdialog = new ImageShowDialogClass(dialog); sigamdialog->show(); sigamdialog->load_double_MatrixX_data(TimeRange, "TimeRange"); ImageShowDialogClass* ampdialog = new ImageShowDialogClass(dialog); ampdialog->show(); ampdialog->load_double_MatrixX_data(echoAmp, "echoAmp"); Eigen::MatrixXd echoPluseamp = echoPluse.array().abs().cast().array(); ImageShowDialogClass* echoampdialog = new ImageShowDialogClass(dialog); echoampdialog->show(); echoampdialog->load_double_MatrixX_data(echoPluseamp, "echoPluseamp"); dialog->exec(); #endif //qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") << " end " << prfidx; } //qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")<<" step "<< prfcount_step; omp_set_lock(&lock); // 回波整体赋值处理 for (long prfidx = 0; prfidx < prfcount_step; prfidx++) { for (long freqidx = 0; freqidx < PlusePoint; freqidx++) { //qDebug() << prfidx << " " << freqidx << " " << echoPluse(prfidx, freqidx).real() << " + " << echoPluse(prfidx, freqidx).imag() << " j"; echo.get()[(prfidx + startprfidx) * PlusePoint + freqidx] = echo.get()[(prfidx + startprfidx) * PlusePoint + freqidx] + echoPluse(prfidx, freqidx); } } //this->EchoSimulationData->saveEchoArr(echo, 0, PluseCount); omp_unset_lock(&lock); // 解锁 //qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") << " step 2" << prfcount_step; } omp_set_lock(&lock); // 保存文件 processNumber = processNumber + pluseStep; this->EchoSimulationData->saveEchoArr(echo, 0, PluseCount); omp_unset_lock(&lock); // 解锁 qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") << " \t " << start_ids << "\t--\t " << start_ids + line_invert << "\t/\t" << demxyz.height; } omp_destroy_lock(&lock); // 销毁锁 */