模糊函数(Ambiguity Function,AF)是评价雷达波形优劣和进行波形分析的基本工具。它可以清晰直观的描述波形与对应匹配滤波器的特征。模糊函数在分析距离/速度分辨率、距离/多普勒模糊和副瓣性能方面应用广泛。
上面这句话粘自很多年前的硕士论文,在写这篇博客时,本人已经不搞雷达很多年,由于需要评价雷达发射波形的优劣,需要对设计波形进行模糊函数评价,借助matlab可以直接画出模糊函数图,而本人一贯不爱用matlab,所以看了两本OpenGl教材后,自己写了个模糊函数三维程序,基本思路就是按照幅度由低到高依次设置蓝/青/绿/黄/红,然后根据三点计算法线方向,设置光照,生成三维效果秒杀matlab,由于这个程序需要集成在mfc中,所以将mfc的panel控件作为整个OpenGl画布。代码如下:全部程序可以到我的GitHub主页下载,里面还包括遗传算法的具体实现。先贴几张效果图吧,可以生成线性调频/二相编码/Frank等多项码信号的模糊函数。
这个程序多年前写的,代码写的很垃圾,也没有很多注释,只是实现了功能,整个程序vs2008和vs2010都可以调试通过(需要先配置好OpenGl安装环境)
1.AmbiguityFunction.h
/* Copyright (c) 2011-2013 Zhang Zhao(ZZ), zhangzhao0907@163.com
*
/*****************************************************************************
* AmbiguityFunction.h
*模糊函数类的头文件
* Zhang Zhao, 2011-2013
*****************************************************************************/
#pragma once
struct DataAF{
double x;
double z;
double h;
};
class AmbiguityFunction
{
public:
int i;
int SignalChoose;
DataAF Data[200][200];
public:
AmbiguityFunction(void);
AmbiguityFunction(int index);
~AmbiguityFunction(void);
void initDataSinalPulse(float pulseWidth=1,float Dopller=5);
void initDataLFM(float pulseWidth=1,float Dopller=5);
void initDataPulseSeries(float pulseWidth,float Dopller,float pulsePri,int N);
void initDataPhaseCode(float pulseWidth,float Dopller, double Code[],int N);
void initDataMultiPhaseCode(float pulseWidth,float Dopller, double Code[],int N);
void initDataFrankPhaseCode(float pulseWidth,float Dopller, double Code[],int N);
double GetMax();
double GetMin();
double SiglePulse(double T0,double T,double fd);
double LFM(double T0,double T,double fd,double FM);
double PulseSeries(double T0,double T,double fd,float TPri,int N);
double PhaseCode(float t1,float td,float fd,double Code[],int N);
double MultiPhaseCode(float t1,float td,float fd,double Code[],int N);
double FrankPhaseCode(float t1,float td,float fd,double Code[],int N);
};
2.AmbiguityFunction.cpp
/* Copyright (c) 2011-2013 Zhang Zhao(ZZ), zhangzhao0907@163.com
*
/*****************************************************************************
* AmbiguityFunction.cpp
*模糊函数类的实现文件
* Zhang Zhao, 2011-2013
*****************************************************************************/
#include "StdAfx.h"
#include "math.h"
#include "AmbiguityFunction.h"
#include "Complex.h"
#define pi 3.1415926
AmbiguityFunction::AmbiguityFunction(void)
{
i=0;
SignalChoose=0;
}
AmbiguityFunction::AmbiguityFunction(int index)
{
i=index;
}
AmbiguityFunction::~AmbiguityFunction(void)
{
}
void AmbiguityFunction::initDataSinalPulse(float pulseWidth,float Dopller)
{
for (int i = 0;i<200;i++)
{
for (int j = 0;j<200;j++)
{
double measure=0.01;
double x_m=measure*pulseWidth;
double z_m=measure*Dopller;
Data[i][j].x = i*x_m-100*x_m;
Data[i][j].z = j*z_m-100*z_m;
Data[i][j].h=2*SiglePulse(pulseWidth,Data[i][j].x,Data[i][j].z);
Data[i][j].x/=pulseWidth;
Data[i][j].z/=Dopller;
}
}
}
void AmbiguityFunction::initDataLFM(float pulseWidth,float Dopller)
{
for (int i = 0;i<200;i++)
{
for (int j = 0;j<200;j++)
{
double measure=0.01;
double x_m=measure*pulseWidth;
double z_m=measure*Dopller;
Data[i][j].x = i*x_m-100*x_m;
Data[i][j].z = j*z_m-100*z_m;
Data[i][j].h=2*LFM(pulseWidth,Data[i][j].x,Data[i][j].z,Dopller/pulseWidth);
Data[i][j].x/=pulseWidth;
Data[i][j].z/=Dopller;
}
}
}
void AmbiguityFunction::initDataPulseSeries(float pulseWidth,float Dopller,float pulsePri,int N)
{
for (int i = 0;i<200;i++)
{
for (int j = 0;j<200;j++)
{
double measure=0.01;
double x_m=measure*((pulsePri*(N-1))+0.133);
double z_m=measure*(Dopller+0.133);
Data[i][j].x = i*x_m-100*x_m;
Data[i][j].z = j*z_m-100*z_m;
Data[i][j].h=2*PulseSeries(pulseWidth,Data[i][j].x,Data[i][j].z,pulsePri,N);
Data[i][j].x/=((pulsePri*(N-1))+0.133);
Data[i][j].z/=(Dopller+0.133);
//Trace("%f,%f,%f",Data[i][j].x,Data[i][j].x,Data[i][j].x);
}
}
}
double AmbiguityFunction::GetMax()
{
double TmpMax = Data[0][0].h;
for (int i = 0;i<200;i++)
{
for (int j=0;j<200;j++)
{
TmpMax = max((double)Data[i][j].h,(double)TmpMax);
}
}
return TmpMax;
}
double AmbiguityFunction::GetMin()
{
double Tmpmin = Data[0][0].h;
for (int i = 0;i<200;i++)
{
for (int j=0;j<200;j++)
{
Tmpmin = min((double)Data[i][j].h,(double)Tmpmin);
}
}
return Tmpmin;
}
double AmbiguityFunction::SiglePulse(double T0,double T, double fd)
{
double TempT=1-fabs(T)/T0;
double TempTC=pi*fd*(T0-fabs(T));
double TempSin;
double eps=0.000001;
TempSin=sin(TempTC+eps);
TempSin/=(TempTC+eps);
return fabs(TempSin*TempT);//*(TempSin*TempT);
}
double AmbiguityFunction::LFM(double T0,double T, double fd,double FM)
{
double TempT=1-fabs(T)/T0;
double TempTC=pi*T0*(FM*T+fd)*TempT;
double TempSin;
if(TempTC==0.0)
TempSin=1;
else
{
TempSin=sin(TempTC);
TempSin/=TempTC;
}
return fabs(TempSin*TempT);//*(TempSin*TempT);
}
double AmbiguityFunction::PulseSeries(double T0,double T,double fd,float TPri,int N)
{
double AmbiValue=0.0;
double TempLeft;
double TempRight;
double eps=0.000001;
for(int q=-(N-1);q<=N-1;q++)
{
double TempC=pi*fd*(N-fabs((double)q)*TPri);
double TempSin=sin(TempC+eps);
double fm=(pi*fd*TPri);
double fmSin=sin(fm+eps);
TempRight=TempSin/fmSin;
if(TempRight==1)
TempRight=(N-fabs((double)q)*TPri)/TPri;
TempRight=fabs(TempRight);
if(fabs(T-q*TPri)<=T0)
{
TempLeft=SiglePulse(T0,T-q*TPri,fd);
AmbiValue+=(TempRight*TempLeft);
}
}
AmbiValue/=N;
return fabs (AmbiValue);
}
void AmbiguityFun