#include #include #include #include #include #include #include #include #include "BaseConstVariable.h" #include "GPURFPC.cuh" #ifdef __CUDANVCC___ __device__ float GPU_getSigma0dB(CUDASigmaParam param, float theta) {//线性值 float sigma = param.p1 + param.p2 * exp(-param.p3 * theta) + param.p4 * cos(param.p5 * theta + param.p6); return sigma; } __device__ CUDAVectorEllipsoidal GPU_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 ) { CUDAVectorEllipsoidal result{ 0,0,-1 }; // 求解天线增益 float Xst = -1 * RstX; // 卫星 --> 地面 float Yst = -1 * RstY; float Zst = -1 * RstZ; float AntXaxisX = antXaxisX; float AntXaxisY = antXaxisY; float AntXaxisZ = antXaxisZ; float AntYaxisX = antYaxisX; float AntYaxisY = antYaxisY; float AntYaxisZ = antYaxisZ; float AntZaxisX = antZaxisX; float AntZaxisY = antZaxisY; float AntZaxisZ = antZaxisZ; // 归一化 float RstNorm = sqrtf(Xst * Xst + Yst * Yst + Zst * Zst); float AntXaxisNorm = sqrtf(AntXaxisX * AntXaxisX + AntXaxisY * AntXaxisY + AntXaxisZ * AntXaxisZ); float AntYaxisNorm = sqrtf(AntYaxisX * AntYaxisX + AntYaxisY * AntYaxisY + AntYaxisZ * AntYaxisZ); float AntZaxisNorm = sqrtf(AntZaxisX * AntZaxisX + AntZaxisY * AntZaxisY + AntZaxisZ * AntZaxisZ); float Rx = Xst / RstNorm; float Ry = Yst / RstNorm; float Rz = Zst / RstNorm; float Xx = AntXaxisX / AntXaxisNorm; float Xy = AntXaxisY / AntXaxisNorm; float Xz = AntXaxisZ / AntXaxisNorm; float Yx = AntYaxisX / AntYaxisNorm; float Yy = AntYaxisY / AntYaxisNorm; float Yz = AntYaxisZ / AntYaxisNorm; float Zx = AntZaxisX / AntZaxisNorm; float Zy = AntZaxisY / AntZaxisNorm; float Zz = AntZaxisZ / AntZaxisNorm; float Xant = (Rx * Yy * Zz - Rx * Yz * Zy - Ry * Yx * Zz + Ry * Yz * Zx + Rz * Yx * Zy - Rz * Yy * Zx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx); float Yant = -(Rx * Xy * Zz - Rx * Xz * Zy - Ry * Xx * Zz + Ry * Xz * Zx + Rz * Xx * Zy - Rz * Xy * Zx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx); float Zant = (Rx * Xy * Yz - Rx * Xz * Yy - Ry * Xx * Yz + Ry * Xz * Yx + Rz * Xx * Yy - Rz * Xy * Yx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx); // 计算theta 与 phi float Norm = sqrtf(Xant * Xant + Yant * Yant + Zant * Zant); // 计算 pho float ThetaAnt = acosf(Zant / Norm); // theta 与 Z轴的夹角 float PhiAnt = atanf(Yant / Xant); // -pi/2 ~pi/2 if (abs(Yant) < PRECISIONTOLERANCE) { // X轴上 PhiAnt = 0; } else if (abs(Xant) < PRECISIONTOLERANCE) { // Y轴上,原点 if (Yant > 0) { PhiAnt = PI / 2; } else { PhiAnt = -PI / 2; } } else if (Xant < 0) { if (Yant > 0) { PhiAnt = PI + PhiAnt; } else { PhiAnt = -PI + PhiAnt; } } else { // Xant>0 X 正轴 } if (isnan(PhiAnt)) { printf("V=[%f,%f,%f];norm=%f;thetaAnt=%f;phiAnt=%f;\n", Xant, Yant, Zant, Norm, ThetaAnt, PhiAnt); } result.theta = ThetaAnt; result.phi = PhiAnt; result.Rho = Norm; return result; } __device__ float GPU_BillerInterpAntPattern(float* antpattern, float starttheta, float startphi, float dtheta, float dphi, long thetapoints, long phipoints, float searththeta, float searchphi) { float stheta = searththeta; float sphi = searchphi; if (stheta > 90) { return 0; } else {} float pthetaid = (stheta - starttheta) / dtheta;// float pphiid = (sphi - startphi) / dphi; long lasttheta = floorf(pthetaid); long nextTheta = lasttheta + 1; long lastphi = floorf(pphiid); long nextPhi = lastphi + 1; if (lasttheta < 0 || nextTheta < 0 || lastphi < 0 || nextPhi < 0 || lasttheta >= thetapoints || nextTheta >= thetapoints || lastphi >= phipoints || nextPhi >= phipoints) { return 0; } else { float x = stheta; float y = sphi; float x1 = lasttheta * dtheta + starttheta; float x2 = nextTheta * dtheta + starttheta; float y1 = lastphi * dphi + startphi; float y2 = nextPhi * dphi + startphi; float z11 = antpattern[lasttheta * phipoints + lastphi]; float z12 = antpattern[lasttheta * phipoints + nextPhi]; float z21 = antpattern[nextTheta * phipoints + lastphi]; float z22 = antpattern[nextTheta * phipoints + nextPhi]; //z11 = powf(10, z11 / 10); // dB-> 线性 //z12 = powf(10, z12 / 10); //z21 = powf(10, z21 / 10); //z22 = powf(10, z22 / 10); float 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)); return GainValue; } } __device__ cuComplex GPU_calculationEcho(float sigma0, float TransAnt, float ReciveAnt, float localangle, float R, float slopeangle, float Pt, float lamda) { float amp = Pt * TransAnt * ReciveAnt; amp = amp * sigma0; amp = amp / (powf(4 * LAMP_CUDA_PI, 2) * powf(R, 4)); // 反射强度 float phi = (-4 * LAMP_CUDA_PI / lamda) * R; cuComplex echophi = make_cuComplex(0, phi); cuComplex echophiexp = cuCexpf(echophi); cuComplex echo = make_cuComplex(echophiexp.x * amp, echophiexp.y * amp); return echo; } __global__ void CUDA_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) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < len) { float Xst = -1 * RstX[idx]; // 卫星 --> 地面 float Yst = -1 * RstY[idx]; float Zst = -1 * RstZ[idx]; float AntXaxisX = antXaxisX; float AntXaxisY = antXaxisY; float AntXaxisZ = antXaxisZ; float AntYaxisX = antYaxisX; float AntYaxisY = antYaxisY; float AntYaxisZ = antYaxisZ; float AntZaxisX = antZaxisX; float AntZaxisY = antZaxisY; float AntZaxisZ = antZaxisZ; // 归一化 float RstNorm = sqrtf(Xst * Xst + Yst * Yst + Zst * Zst); float AntXaxisNorm = sqrtf(AntXaxisX * AntXaxisX + AntXaxisY * AntXaxisY + AntXaxisZ * AntXaxisZ); float AntYaxisNorm = sqrtf(AntYaxisX * AntYaxisX + AntYaxisY * AntYaxisY + AntYaxisZ * AntYaxisZ); float AntZaxisNorm = sqrtf(AntZaxisX * AntZaxisX + AntZaxisY * AntZaxisY + AntZaxisZ * AntZaxisZ); float Rx = Xst / RstNorm; float Ry = Yst / RstNorm; float Rz = Zst / RstNorm; float Xx = AntXaxisX / AntXaxisNorm; float Xy = AntXaxisY / AntXaxisNorm; float Xz = AntXaxisZ / AntXaxisNorm; float Yx = AntYaxisX / AntYaxisNorm; float Yy = AntYaxisY / AntYaxisNorm; float Yz = AntYaxisZ / AntYaxisNorm; float Zx = AntZaxisX / AntZaxisNorm; float Zy = AntZaxisY / AntZaxisNorm; float Zz = AntZaxisZ / AntZaxisNorm; float Xant = (Rx * Yy * Zz - Rx * Yz * Zy - Ry * Yx * Zz + Ry * Yz * Zx + Rz * Yx * Zy - Rz * Yy * Zx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx); float Yant = -(Rx * Xy * Zz - Rx * Xz * Zy - Ry * Xx * Zz + Ry * Xz * Zx + Rz * Xx * Zy - Rz * Xy * Zx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx); float Zant = (Rx * Xy * Yz - Rx * Xz * Yy - Ry * Xx * Yz + Ry * Xz * Yx + Rz * Xx * Yy - Rz * Xy * Yx) / (Xx * Yy * Zz - Xx * Yz * Zy - Xy * Yx * Zz + Xy * Yz * Zx + Xz * Yx * Zy - Xz * Yy * Zx); // 计算theta 与 phi float Norm = sqrtf(Xant * Xant + Yant * Yant + Zant * Zant); // 计算 pho float ThetaAnt = acosf(Zant / Norm); // theta 与 Z轴的夹角 float PhiAnt = atanf(Yant / Xant); // -pi/2 ~pi/2 if (abs(Yant) < PRECISIONTOLERANCE) { // X轴上 PhiAnt = 0; } else if (abs(Xant) < PRECISIONTOLERANCE) { // Y轴上,原点 if (Yant > 0) { PhiAnt = PI / 2; } else { PhiAnt = -PI / 2; } } else if (Xant < 0) { if (Yant > 0) { PhiAnt = PI + PhiAnt; } else { PhiAnt = -PI + PhiAnt; } } else { // Xant>0 X 正轴 } if (isnan(PhiAnt)) { printf("V=[%f,%f,%f];norm=%f;thetaAnt=%f;phiAnt=%f;\n", Xant, Yant, Zant, Norm, ThetaAnt, PhiAnt); } //if (abs(ThetaAnt - 0) < PRECISIONTOLERANCE) { // PhiAnt = 0; //} //else {} thetaAnt[idx] = ThetaAnt * r2d; phiAnt[idx] = PhiAnt * r2d; //printf("Rst=[%f,%f,%f];AntXaxis = [%f, %f, %f];AntYaxis=[%f,%f,%f];AntZaxis=[%f,%f,%f];phiAnt=%f;thetaAnt=%f;\n", Xst, Yst, Zst // , AntXaxisX, AntXaxisY, AntXaxisZ // , AntYaxisX, AntYaxisY, AntYaxisZ // , AntZaxisX, AntZaxisY, AntZaxisZ // , phiAnt[idx] // , thetaAnt[idx] //); } } __global__ void CUDA_BillerInterpAntPattern(float* antpattern, float starttheta, float startphi, float dtheta, float dphi, long thetapoints, long phipoints, float* searththeta, float* searchphi, float* searchantpattern, long len) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < len) { float stheta = searththeta[idx]; float sphi = searchphi[idx]; float pthetaid = (stheta - starttheta) / dtheta;// float pphiid = (sphi - startphi) / dphi; long lasttheta = floorf(pthetaid); long nextTheta = lasttheta + 1; long lastphi = floorf(pphiid); long nextPhi = lastphi + 1; if (lasttheta < 0 || nextTheta < 0 || lastphi < 0 || nextPhi < 0 || lasttheta >= thetapoints || nextTheta >= thetapoints || lastphi >= phipoints || nextPhi >= phipoints) { searchantpattern[idx] = 0; } else { float x = stheta; float y = sphi; float x1 = lasttheta * dtheta + starttheta; float x2 = nextTheta * dtheta + starttheta; float y1 = lastphi * dphi + startphi; float y2 = nextPhi * dphi + startphi; float z11 = antpattern[lasttheta * phipoints + lastphi]; float z12 = antpattern[lasttheta * phipoints + nextPhi]; float z21 = antpattern[nextTheta * phipoints + lastphi]; float z22 = antpattern[nextTheta * phipoints + nextPhi]; z11 = powf(10, z11 / 10); z12 = powf(10, z12 / 10); z21 = powf(10, z21 / 10); z22 = powf(10, z22 / 10); float 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)); searchantpattern[idx] = GainValue; } } } __global__ void CUDA_calculationEcho(float* sigma0, float* TransAnt, float* ReciveAnt, float* localangle, float* R, float* slopeangle, float nearRange, float Fs, float Pt, float lamda, long FreqIDmax, cuComplex* echoArr, long* FreqID, long len) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < len) { float r = R[idx]; float amp = Pt * TransAnt[idx] * ReciveAnt[idx]; amp = amp * sigma0[idx]; amp = amp / (powf(4 * LAMP_CUDA_PI, 2) * powf(r, 4)); // 反射强度 // 处理相位 float phi = (-4 * LAMP_CUDA_PI / lamda) * r; cuComplex echophi = make_cuComplex(0, phi); cuComplex echophiexp = cuCexpf(echophi); float timeR = 2 * (r - nearRange) / LIGHTSPEED * Fs; long timeID = floorf(timeR); //if (timeID < 0 || timeID >= FreqIDmax) { // timeID = 0; // amp = 0; //} cuComplex echo = make_cuComplex(echophiexp.x, echophiexp.y); echoArr[idx] = echo; FreqID[idx] = timeID; } } __global__ void CUDA_AntPatternInterpGain(float* anttheta, float* antphi, float* gain, float* antpattern, float starttheta, float startphi, float dtheta, float dphi, int thetapoints, int phipoints, long len) { int idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < len) { float temptheta = anttheta[idx]; float tempphi = antphi[idx]; float antPatternGain = GPU_BillerInterpAntPattern(antpattern, starttheta, startphi, dtheta, dphi, thetapoints, phipoints, temptheta, tempphi); gain[idx] = antPatternGain; } } __global__ void CUDA_InterpSigma( long* demcls, float* sigmaAmp, float* localanglearr, long len, CUDASigmaParam* sigma0Paramslist, long sigmaparamslistlen) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < len) { long clsid = demcls[idx]; float localangle = localanglearr[idx]; CUDASigmaParam tempsigma = sigma0Paramslist[clsid]; if (localangle < 0 || localangle >= LAMP_CUDA_PI / 2) { sigmaAmp[idx] = 0; } else {} if (abs(tempsigma.p1) < PRECISIONTOLERANCE && abs(tempsigma.p2) < PRECISIONTOLERANCE && abs(tempsigma.p3) < PRECISIONTOLERANCE && abs(tempsigma.p4) < PRECISIONTOLERANCE && abs(tempsigma.p5) < PRECISIONTOLERANCE && abs(tempsigma.p6) < PRECISIONTOLERANCE ) { sigmaAmp[idx] = 0; } else { float sigma = GPU_getSigma0dB(tempsigma, localangle); sigma = powf(10.0, sigma / 10.0);// 后向散射系数 //printf("cls:%d;localangle=%f;sigma0=%f;\n", clsid, localangle, sigma); sigmaAmp[idx] = sigma; } } } __global__ void CUDAKernel_RFPC_Caluation_R_Gain( float antX, float antY, float antZ, // 天线的坐标 float* targetX, float* targetY, float* targetZ, long len, // 地面坐标 long* demCls, float* demSlopeX, float* demSlopeY, float* demSlopeZ, // 地表坡度矢量 float antXaxisX, float antXaxisY, float antXaxisZ, // 天线坐标系的X轴 float antYaxisX, float antYaxisY, float antYaxisZ,// 天线坐标系的Y轴 float antZaxisX, float antZaxisY, float antZaxisZ,// 天线坐标系的Z轴 float antDirectX, float antDirectY, float antDirectZ,// 天线的指向 float Pt,// 发射能量 double refPhaseRange, float* TransAntpattern, float Transtarttheta, float Transstartphi, float Transdtheta, float Transdphi, int Transthetapoints, int Transphipoints, // 发射天线方向图 float* ReceiveAntpattern, float Receivestarttheta, float Receivestartphi, float Receivedtheta, float Receivedphi, int Receivethetapoints, int Receivephipoints,//接收天线方向图 float NearR, float FarR, // 距离范围 CUDASigmaParam* sigma0Paramslist, long sigmaparamslistlen,// 插值图 float* factorj, long freqnum, double* outR, // 输出距离 float* outAmp // 输出增益 ) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < len) { double tx = targetX[idx]; double ty = targetY[idx]; double tz = targetZ[idx]; double RstX = antX - tx; // 计算坐标矢量 double RstY = antY - ty; double RstZ = antZ - tz; float slopeX = demSlopeX[idx]; float slopeY = demSlopeY[idx]; float slopeZ = demSlopeZ[idx]; double RstR2 = RstX * RstX + RstY * RstY + RstZ * RstZ; double RstR = sqrt(RstR2); // 矢量距离 //printf("antX=%f;antY=%f;antZ=%f;targetX=%f;targetY=%f;targetZ=%f;RstR=%.6f;diffR=%.6f;\n",antX,antY,antZ,targetX,targetY,targetZ,RstR, RstR - 9.010858499003178e+05); if (RstRFarR) { outAmp[idx] = 0; outR[idx] = 0; } else { // 求解坡度 float slopR = sqrtf(slopeX * slopeX + slopeY * slopeY + slopeZ * slopeZ); // float dotAB = RstX * slopeX + RstY * slopeY + RstZ * slopeZ; float localangle = acosf(dotAB / (RstR * slopR)); // 局地入射角 float ampGain = 0; // 求解天线方向图指向 CUDAVectorEllipsoidal antVector = GPU_SatelliteAntDirectNormal( RstX, RstY, RstZ, antXaxisX, antXaxisY, antXaxisZ, antYaxisX, antYaxisY, antYaxisZ, antZaxisX, antZaxisY, antZaxisZ, antDirectX, antDirectY, antDirectZ ); if (antVector.Rho > 0) { // 发射方向图 float temptheta = antVector.theta * r2d; float tempphi = antVector.phi * r2d; float TansantPatternGain = GPU_BillerInterpAntPattern( TransAntpattern, Transtarttheta, Transstartphi, Transdtheta, Transdphi, Transthetapoints, Transphipoints, temptheta, tempphi); // 接收方向图 float antPatternGain = GPU_BillerInterpAntPattern( ReceiveAntpattern, Receivestarttheta, Receivestartphi, Receivedtheta, Receivedphi, Receivethetapoints, Receivephipoints, temptheta, tempphi); // 计算 float sigma0 = 0; { long clsid = demCls[idx]; //printf("clsid=%d\n", clsid); CUDASigmaParam tempsigma = sigma0Paramslist[clsid]; if (localangle < 0 || localangle >= LAMP_CUDA_PI / 2) { sigma0 = 0; } else {} if (abs(tempsigma.p1) < PRECISIONTOLERANCE && abs(tempsigma.p2) < PRECISIONTOLERANCE && abs(tempsigma.p3) < PRECISIONTOLERANCE && abs(tempsigma.p4) < PRECISIONTOLERANCE && abs(tempsigma.p5) < PRECISIONTOLERANCE && abs(tempsigma.p6) < PRECISIONTOLERANCE ) { sigma0 = 0; } else { float sigma = GPU_getSigma0dB(tempsigma, localangle); sigma0 = powf(10.0, sigma / 10.0);// 后向散射系数 } } ampGain = TansantPatternGain * antPatternGain; ampGain = ampGain / (powf(4 * LAMP_CUDA_PI, 2) * powf(RstR, 4)); // 反射强度 outAmp[idx] = ampGain * Pt * sigma0; outR[idx] = RstR - refPhaseRange; } else { outAmp[idx] = 0; outR[idx] = 0; } } } } __global__ void CUDAKernel_PRF_CalFreqEcho( double* Rarr, float* ampArr, long pixelcount, float* factorj, long freqnum, double dx, double nearR, cuComplex* PRFEcho, long prfid) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < freqnum) { float fatorj = factorj[idx]; float phi = 0; float amptemp = 0; cuComplex tempfreqEcho = PRFEcho[prfid * freqnum + idx]; for (long i = 0; i < pixelcount; i++) { // 区域积分 //phi = (R = R - (floor(R / lamda) - 1) * lamda)* fatorj; // 相位 float phi = Rarr[i] * factorj[idx]; // 相位 amptemp = ampArr[i]; //printf("amp=%f\n", amptemp); // Eular; exp(ix)=cos(x)+isin(x) tempfreqEcho.x = tempfreqEcho.x + amptemp * cos(phi); // 实部 tempfreqEcho.y = tempfreqEcho.y + amptemp * sin(phi); // 虚部 //printf("freqid=%d;fatorj=%.12f;d_R=%.10f;phi=%.10f;echo=complex(%.5f,%.5f)\n", idx, fatorj, Rarr[i], phi, tempfreqEcho.x, tempfreqEcho.y); } PRFEcho[prfid * freqnum + idx] = tempfreqEcho; } } __global__ void CUDAKernel_PRFSumEcho_Rows( double* Rarr,float* ampArr,long Rows,long Cols, long startRid, float* factorj, long freqnum, cuComplex* freqRowsbuffer, long tempRows ){ long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < Rows) { // 按行汇总 double R = 0; double tempamp = 0; float phi = 0; long rid = idx + startRid; float factor = 0; for (long jj = 0; jj < freqnum; jj++) { tempamp = ampArr[rid * Cols + jj]; R = Rarr[rid * Cols + jj]; for (long ii = 0; ii < freqnum; ii++) { phi = R * factorj[ii]; freqRowsbuffer[idx * freqnum + ii].x = freqRowsbuffer[idx * freqnum + ii].x + tempamp * cos(phi); // 实部 freqRowsbuffer[idx * freqnum + ii].y = freqRowsbuffer[idx * freqnum + ii].y + tempamp * sin(phi); // 虚部 } //freqRowsbuffer[idx * freqnum + ii] = tempfreqEcho; } } } __global__ void CUDAKernel_PRFSumEcho_Freq( cuComplex* freqRowsbuffer, long tempRows,long freqnum, cuComplex* PRFEcho, long prfid ) { long idx = blockIdx.x * blockDim.x + threadIdx.x; if (idx < freqnum) { // 按行汇总 cuComplex tempfreqEcho = freqRowsbuffer[prfid * freqnum + idx]; cuComplex temp = tempfreqEcho; for (long ii = 0; ii < tempRows; ii++) { // 求和汇总 temp = freqRowsbuffer[ii * freqnum + idx]; tempfreqEcho.x = tempfreqEcho.x + temp.x; tempfreqEcho.y = tempfreqEcho.y + temp.y; } freqRowsbuffer[prfid * freqnum + idx] = tempfreqEcho; } } #endif