超过460,000+ 应用技术资源下载
pdf

基于VC++实时海浪功率谱分析软件设计

  • 1星
  • 日期: 2018-10-09
  • 大小: 196.17KB
  • 所需积分:1分
  • 下载次数:0
  • favicon收藏
  • rep举报
  • 分享
  • free评论
标签: VC++

随机信号频谱和功率谱分析常用到快速付里叶变换(FFT),本文介绍一种基于VC++6.0 设计类实现FFT 的方法,并在此基础上编写了实时海浪功率谱分析软件。设计类Fft 具有一定的通用性,可用于其它随机信号频谱分析。Pierson 把Rice 关于通讯无线电噪声理论应用于海浪研究后,利用谱的概念来描述随机海浪逐渐成为研究海浪的主要手段[1]。如今,谱方法已成为研究海浪及其相关问题的有力工具,因为,谱是随机海浪一个重要的统计性质,它不仅包含着海浪的二阶信息,而且还直接给出海浪组成波能量相对于频率和方向的分布,这正是海洋工程和航海领域等特别关心的[2]。目前常用的海浪谱估计方法有两种:相关函数法和周期图法。本文采用周期图法,周期图法实现的核心是离散付里叶变换(DFT)的实现。然而,离散付里叶变换计算量大,计算时间长,尤其在采样点的个数较多时,计算量大到让人无法容忍的程度。快速付里变换(FFT)大大提高了运算速度,所以用到付里叶变换时,多采用FFT 算法。本文采用 FFT 算法,先得到样本2048 个时域采样点的粗谱估计,再利用平滑算法,得到平滑谱。利用VC++环境主要为了设计实时、具有一定通用性的海浪功率谱分析软件。VC 中没有现成的FFT 函数或类供编程者调用,因此需要编程实现,实现方法有两种,一种是编写函数;另一种设计付里叶变换类。前者对于小程序编写是可行的,很不利于软件的模块化设计和功能的扩充;后者不仅有利于程序的模块化设计,还有利于软件的升级,更好的发挥VC++面向对象编程的优势。因此,选择后者设计付里叶变换类[3]。设计的付里叶变换类具有快速付里叶变换和快速付里叶逆变换两种功能,以后根据需要可随时修改,增加封装函数,实现更多功能。

文档内容节选

基于 VC实时海浪功率谱分析软件设计 Real time software design for power spectrum estimation of waves based on VC 中国海洋大学海洋环境学院, 青岛 ,266003 唐原广 贺成柱 Yuanguang Tang Chengzhu He 摘要:随机信号频谱和功率谱分析常用到快速付里叶变换FFT ,本文介绍一种基于 VC60 设计类实现 FFT 的方法,并在此基础上编写了实时海浪功率谱分析软件设计类 Fft 具有一定的通用性,可用于其它随机信号频谱分析 关键词:频谱分析,FFT,VC 中图分类号:TP31111,TP2024 文献标识码 A Abstract:One common method of estimating random signals spectrum is FFT This paper introduces a way to implement FFT which is based on a class Fft founded by VC6......

基于 VC++实时海浪功率谱分析软件设计 Real time software design for power spectrum estimation of waves based on VC++ (中国海洋大学海洋环境学院, 青岛 ,266003) 唐原广 贺成柱 Yuanguang Tang Chengzhu He 摘要:随机信号频谱和功率谱分析常用到快速付里叶变换(FFT ),本文介绍一种基于 VC++6.0 设计类实现 FFT 的方法,并在此基础上编写了实时海浪功率谱分析软件。设计类 Fft 具有一定的通用性,可用于其它随机信号频谱分析。 关键词:频谱分析,FFT,VC++ 中图分类号:TP311.11,TP202+.4 文献标识码 A Abstract|:One common method of estimating random signals' spectrum is FFT. This paper introduces a way to implement FFT, which is based on a class Fft founded by VC++6.0. The software for estimating spectrum of waves is developed based on the class. The class Fft is universal, so it could also be used for other random signals’ spectrum estimation. Keywords:Spectrum estimation, FFT, VC++ 1 概述 Pierson 把 Rice 关于通讯无线电噪声理论应用于海浪研究后,利用谱的概念来描述随机 海浪逐渐成为研究海浪的主要手段[1]。如今,谱方法已成为研究海浪及其相关问题的有力工 具,因为,谱是随机海浪一个重要的统计性质,它不仅包含着海浪的二阶信息,而且还直接 给出海浪组成波能量相对于频率和方向的分布,这正是海洋工程和航海领域等特别关心的 [2]。目前常用的海浪谱估计方法有两种:相关函数法和周期图法。本文采用周期图法,周期 图法实现的核心是离散付里叶变换(DFT)的实现。然而,离散付里叶变换计算量大,计算 时间长,尤其在采样点的个数较多时,计算量大到让人无法容忍的程度。快速付里变换(FFT) 大大提高了运算速度,所以用到付里叶变换时,多采用 FFT 算法。 本文采用 FFT 算法,先得到样本 2048 个时域采样点的粗谱估计,再利用平滑算法,得 到平滑谱。利用 VC++环境主要为了设计实时、具有一定通用性的海浪功率谱分析软件。 VC 中没有现成的 FFT 函数或类供编程者调用,因此需要编程实现,实现方法有两种, 一种是编写函数;另一种设计付里叶变换类。前者对于小程序编写是可行的,很不利于软件 的模块化设计和功能的扩充;后者不仅有利于程序的模块化设计,还有利于软件的升级,更 好的发挥 VC++面向对象编程的优势。因此,选择后者设计付里叶变换类[3]。 设计的付里叶变换类具有快速付里叶变换和快速付里叶逆变换两种功能,以后根据需要 可随时修改,增加封装函数,实现更多功能。 2 快速付里叶变换(FFT)原理: 2.1 离散付里叶变换(DFT)定义式 设有限长序列 ( )x n 的长度为 N ( 0 n N ≤ ≤ ),它的离散付里叶变换 ( )X k 仍然是一个长 度为 N ( 0 k N ≤ ≤ X k ( ) = D F T x n ( [ )] = ∑ n = 0 )的频域有限长序列,这种正反变换的关系式为 0 k N ≤ ≤ N − 1 x n W ( ) k n N ( 2-1) x n ( ) = ID F T X k ( [ ) ] 1 X k W ) ( N − = ∑ n = 0 0 n N ≤ ≤ ( 2-2) n k − N 其中, NW kn π−= e jnk N 2 基金项目:国家 863 项目——海洋监测技术成果标准化工程:波浪方向浮标(编号 200407) 2.2 快速付里叶变换 2.2.1 快速付里叶变换的优点 由 DFT 定义式可以看出,要完成 N 个值的 ( )X k 计算共需 2N 次复数乘法和 ( N N − 次 1) 复数加法运算。当采样点数 N 增大时,运算量急剧增长,这对数据处理形成极大障碍。本 文所处理的数据,每个样本采样点个数为 2048 个,若采用此方法,处理每个样本需要进行 近千万次复数运算。 FFT 利用旋转因子 kn NW 的特点,大大减少了运算次数,当采样点个数 N = 时,全部 2M 运算可分解为 M 级蝶形运算,每级都包含 / 2N 次复数乘法运算, N 次复数加法运算,全部 工作量为 / 2MN 次复数乘法运算, MN 次加法运算。 2.2.2 快速付里叶变换时间抽选法的原理[4] 设采样点数 2M N = ,M 为正整数,把时间序列 ( )x n 的 DFT 运算按 n 为偶数,n 为奇 数分解为两部分: X k ( ) = N 2 1 − ∑ r = 0 x r W (2 ) 2 N rk + N 2 1 − ∑ r = 0 x r W (2 (2 N 1) + r 1) + k = N 2 1 − ∑ r = 0 x r W (2 )( 2 N ) rk + W k N N 2 1 − ∑ r = 0 x r (2 + 1)( W 2 N ) rk ( 2-3) 其中 0 Nr≤ ≤ 2 1 − , (2 ) r 表示 n 为偶数部分, (2 x x r + 表示 n 为奇数部分。 1) 令 , G k ( ) = − 1 N 2 ∑ r = 0 x (2 ) r W rk N / 2 (2-4) H k ( ) = W k N x (2 r + 1) W rk N − 1 N 2 ∑ = 0 r + 推导得: X k ( ) X k ( + ) ) ( k N G k W H k ( = N 2 = ) k N G k W H k ( − ( ) (2-5) ) 其中, k=0,1,2…,N/2-1 N 个点的离散付里叶变换被分成了两组 / 2N 个点的变换,式(2-5)给出了精简后的 ( )X k 的 计算公式,分解后运算量大约节省了近一半,如此分解下去,每次分解都可以节约近一半的 计算量,直到分解成 /2N 组数,每组两个 ( ) x n 的元素。 2.2.3 时间抽选法的两个重要特点 按照上面公式进行奇偶分解运算有两个重要特点: 1, 同址运算:所谓同址运算就是当数据输入到存储器之后,每级运算结果仍然存储在 原有的同一组存储器中,直到最后一级算完,中间无需增设其他存储单元。 2, 码位倒读:时间抽选法运算时,最后输出结果是按顺序排列的,即 X(0)、X(1)、X(2)… 直到 X(N-1)顺序输出,而输入 x(n)的排列,看上去是乱序的。这种乱序是时间抽选法本身 造成的,但这种乱序也是有规律的——码位倒读,将自然顺序的十进制数按二进制表示的数 字首尾位置颠倒,再重新按十进制数读出即可得倒序码。 以上两点是实现快速付里叶变换程序的基础,也就是设计类核心代码编写的基础。 3 FFT 类的设计 1,利用 VC++的 AppWizard 建立一个基于单文档的应用程序,命名为 Specturm,此应 用程序只是作为创建新类的载体,本身没有实际意义。 2,创建新类,点击菜单 Insert->New Class…,Class type 选项选择 Generic Class,类名 为:Fft ,至此,类框架已经创建完毕,但他并不具备 FFT 功能。 3,手工修改类 Fft 类的头文件 Fft.h 和实现文件 Fft.cpp,根据快速付里叶变换时间抽选 法的原理及其两个重要特点给设计类编写代码。 限于篇幅下面只给出 Fft.cpp 中关键函数的部分代码 void CFft::fft(complex *data, int datalen) //快速付里叶变换函数 { …… int i=0,j=0,k=0,l=0; complex cm_up, cm_down, cm_product; //定义中间变量 initW(datalen); //初始化旋转因子 change(data,datalen); //码位倒读 …… //蝶形运算 } 代码添加完成后,编译检查,消除语法错误。此时,在工程文件夹 Spectrum 下可以看 到刚刚修改成功的两个类文件 Fft.h 和 Fft.cpp。至此, FFT 类 Fft 设计完成。 4 基于 FFT 类 Fft 的实时海浪功率谱分析软件的设计: 1, 海浪功率谱分析原理[2]: 假定所分析的海浪是各态历经的平稳过程,则其谱可用其波面位移的一个样本 nζ 实现。 S ( 2 r π N ) = 1 π 2 N | N ∑ n = 1 ζ n − 1 2 r π N i e ( n − 1) 2 | = 1 π 2 N A r 2 , r =0,1,2…,N/2. (4-1) 其中, A r N = ∑ 1 ζ− k = 0 − i 2 r π N k , S 表示离散功率谱密度, nζ 是波面位移序列。 e n − 1 t 2 ) r ( S = 可推导得: N Aπω ∆ r ωω = ∆ , r =0,1,2…,N/2; (4-2) , r 其中,N 表示采样点的个数, t∆ 表示采样时间间隔。公式详细推导参看文献[2]。 上式 ∆ 范围内离散谱值,公式中容易知 rA 是 nζ 的离散付里叶变换,可 t / ω π< < 2 r (式 4-2)给出 0 以利用编写的 Fft 类实现。 2 软件设计 为建立友好人机界面,在 VC++环境下建立一个基类为 CFormView 的单文档应用程序, 命名为 DispWaveData。它具有实时获取波浪数据和对数据进行功率谱分析等多种功能。 图 4-1 是运行程序后处理数据得到的界面,从图中可以看出当前数据峰值频率是 0.16Hz,功率谱密度的峰值是 0.43m2s(米 2 秒)。界面生成后,给各个命令按钮添加响应函 数,并根据各自功能添加代码。 添加 Fft 类,具体步骤如下: 将设计完成的类文件 Fft.h 和 Fft.cpp 复制到 DispWaveData 工程所在文件夹,然后单击 VC 菜单 Project->Add to project->Files…,在打开文件选择对话框中选择 Fft.h 和 Fft.cpp, 单击 OK, 就把创建的 Fft 类加入了工程 DispWaveData,注意要想使用此类,还要在相应的 实现文件的头文件(DispWaveDataView.h)里将 Fft.h 说明:#include 。 图 4-1 Stastistics 按钮 ( 界 面 左 边 上 数 第 一 个 按 钮 ) 相 关 联 的 函 数 OnButtonStatistics()和 DrawPower 按钮(界面左边上数第五个按钮)相关联的函数 OnDrawPower()介绍如下。函数 OnButtonStatistics()的功能是从数据文件中读入原始序列,并对序列进行付里叶变换,及功 率谱计算,也就是由时域 nζ 得到频域 rA ,从而得到功率谱序列 rS ,此时得到的 rS 是 nζ 的 粗谱估计,利用平滑算法得到新的平滑谱序列,最后给出峰值频率和功率谱密度的峰值。函 数 OnDrawPower()的作用是利用得到的平滑谱序列在 picture 控件(界面左上角)上绘制功 率谱密度随频率变化曲线。限于篇幅,只将 OnButtonStatistics()部分代码给出: void CDispWaveDataView::OnButtonStatistics() { ...... CFft fft; //定义一个 Fft 类的对象 FILE *fp; //定义文件指针 complex data[2048]; //定义复数数组,complex 是自定义的结构体类型,表示复数 float S[2048]; //定义功率谱序列; fp=fopen(“.\\data\\tempdata.dat”,"r"); //打开实时波面位移数据文件 for(int i=0;i<2048;i++) //读入波面位移序列,实序列,令虚部为零 { fscanf(fp,"%f",&data[i].real); data[i].img=0; } fft.fft(data,2048); //使用 Fft 类封装的函数,对 data 序列进行付里叶变换 //利用公式 2 ,算 S(i)。其中 N=2048,采样间隔为 0.5 秒。 ) r = S ω ( ∆ 2 π for(i=0;i<2048;i++) S(i)= (data[i].real*data[i].real+ data[i].img*data[i].img)/(4*2048*PI); t N A r ...... } 从代码(黑体部分)中可以看出,添加了 Fft 类后,要进行快速付里叶变换,只需声明 一个 Fft 类的对象,便可以发挥类的作用,实现快速付里叶变换,提高了编程效率。 5 结束语 此程序所有代码,已在 WindowsXP 下由 VC++6.0 运行通过,并成功运用于我单位所研 制的 SZF 型波浪浮标测得数据的实时功率谱分析,作为模块已成功集成到 SZF 型波浪浮标 岸站接收处理系统中,通过大量试验,得到了较好的效果。 参考文献 [1]叶安乐,李凤岐编著. 物理海洋学[M].青岛:青岛海洋大学出版社,1992.12. [2]徐德伦,于定勇编著. 随机海浪理论[M].北京:高等教育出版社,2001.8. [3]刘其洪等. 基于模板的通用文件对话框的可视化定制[J].微计算机信息.2003.10 [4]王宝祥主编. 信号与系统[M].哈尔滨:哈尔滨工业大学出版社,2000.7. 唐原广(1963-),男(汉族),教授,主要从事海洋仪器仪表研发工作。 贺成柱(1982-),男(汉族),研士研究生在读,研究方向为海洋监测技术。 Email: hechengzhu04@163.com Biography: Yuanguang Tang(1963-), male, Han, Professor. Main scientific research field: Ocean 作者简介 Instruments. Chengzhu He(1982-), male, Han, Graduate Student. Main scientific research field: Marine monitoring technology. 通信地址:266003 山东青岛中国海洋大学海洋环境学院 贺成柱 (266003 College of Physical and Environmental Oceanography, Ocean University of China, Qingdao, Shandong) Chengzhu He 作者创新观点:利用 VC++面向对象的特点和类封装特性,根据付里叶变换原理,设计 通用付里叶变化类,并成功运用于海浪功率谱分析,既提高了编程效率,又有利于软件升级。
更多简介内容

评论


个人中心

意见反馈

求资源

回顶部

下载专区


TI最新应用解决方案

工业电子 汽车电子 个人电子

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

EEWorld下载中心——分享有价值的电子技术资料

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2018 EEWORLD.com.cn, Inc. All rights reserved
$(function(){ var appid = $(".select li a").data("channel"); $(".select li a").click(function(){ var appid = $(this).data("channel"); $('.select dt').html($(this).html()); $('#channel').val(appid); }) })