乘波前行的问题

news2024/11/27 14:39:37

1.问题:

考虑两个信号叠加在一起,比如,一个是工频信号50Hz,一个是叠加的高频信号比如有3KHz,简单起见,两个信号都是幅值固定的标准的正弦波,现在我们期望得到那个高频信号,相对工频信号的相对时域波形,它会是什么样的?它的幅值会抖动吗?它会发生类似红移的效应吗?你怎么验算这个操作?

2.尝试构建数学公式

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# paramsIn => resultOut 
#
import json
import binascii
import numpy as np;
import sys
import struct
import numpy as np
import matplotlib.pyplot as plt
import signal_2048_two_sin

# 绘制信号和包络
def showTwoPairSignals(t, x, spectrum_before, amplitude_envelope, spectrum_after, freqScale, fs):
    freq = np.arange(0, 1024*(10000.0/2048), 10000.0/2048)
    fig, axs = plt.subplots(2, 2, figsize=(10, 8))
    axs[0, 0].plot(t, x)
    axs[0, 0].set_xlabel('Time (s)')
    axs[0, 0].set_ylabel('Amplitude')
    axs[0, 0].set_title('Original Signal')

    axs[1, 0].plot(freq, spectrum_before)
    axs[1, 0].set_xlabel('Frequency (Hz)')
    axs[1, 0].set_ylabel('Amplitude')
    axs[1, 0].set_title('Spectrum Before Transformation')
    axs[1, 0].set_xlim(0, fs/2)

    axs[0, 1].plot(t, amplitude_envelope)
    axs[0, 1].set_xlabel('Time (s)')
    axs[0, 1].set_ylabel('Amplitude')
    axs[0, 1].set_title('Amplitude Envelope')

    axs[1, 1].plot(freq, spectrum_after)
    axs[1, 1].set_xlabel('Frequency (Hz)')
    axs[1, 1].set_ylabel('Amplitude')
    axs[1, 1].set_title('Spectrum After Transformation')
    axs[1, 1].set_xlim(0, fs/2)

    plt.tight_layout()
    plt.show()

def calc_envelope(fft_complex_result, scale_fft, center_fft, zoomOfFreq):
    print(len(fft_complex_result))
    data_array = fft_complex_result;
    center_freq = center_fft/scale_fft;
    zoomOfFreq = zoomOfFreq/scale_fft;


    #频谱进行数字带通滤波
    min_freq = center_freq - zoomOfFreq;
    max_freq = center_freq + zoomOfFreq;
    if(min_freq <0): min_freq = 0;
    if(max_freq>=(len(data_array)//2)): max_freq =len(data_array)//2;
    for i in range(len(data_array)//2): #注意data_array包含对称的频谱。
        if(i<min_freq): 
            data_array[i] = 0+0j;
            data_array[-1*i] = 0+0j;
        else:
            if(i>max_freq): 
                data_array[i] = 0+0j;
                data_array[-1*i] = 0+0j;
            #no else

    # 幅角变换
    X = data_array;
    phase_shift = np.zeros(len(X))
    for idx in np.arange(0, len(X)//2):
        phase_shift[idx] = -np.angle(X[-idx])
    X_corrected = X * np.exp( 1j * phase_shift)
    
    # 转回时域
    sampleDataFilted  = np.real(np.fft.ifft(X_corrected)); #我不知道为什么不取abs,但是既有的电机时域数据去零点的结果是正确的。
    amplitude_spectrum = [(abs(x)/len(sampleDataFilted)) for x in sampleDataFilted]
    amplitude_spectrum = np.clip(amplitude_spectrum, 0, 65535).astype(np.uint16)

    # 傅里叶变换
    X_of_Envelope = np.fft.fft(amplitude_spectrum)  # 计算原始信号的傅里叶变换
    X_of_Envelope = X_of_Envelope[:len(X_of_Envelope)//2]
    absFFTOfEnvelope = [abs(item)/len(X_of_Envelope) for item in X_of_Envelope];
        
    # to hex again 
    # 将浮点数组转换为 2 字节uint16编码的二进制数据
    ba = amplitude_spectrum.tobytes()
    hex_data = binascii.hexlify(ba).decode('utf-8')
    root = {
        'binData':hex_data,
        'pt':len(hex_data)/2/2, #hex=>byte /2 byte=>uint16 /2
        'byte_len': len(hex_data),
        'scale': (scale_fft*(len(hex_data)/2))
    }

    # out put  json obj: root is ready 
    # it should turn into str => python variable: resultOut
    #######################################################################################

    # json => str
    json_string = json.dumps(root)
    print(json_string);
    resultOut = json_string;
    return (json_string, amplitude_spectrum, absFFTOfEnvelope);

(signal, FFT_result, FFT_abs) = signal_2048_two_sin.genSignal(2048, 2000, 1800)
(envelopeHex, envelope_result, absFFTOfEnvelope) = calc_envelope(FFT_result, 10000/2048., 2000, 250);
print(envelope_result)


showTwoPairSignals(np.arange(0, 2048.0/10000, 1/10000), signal, FFT_abs[:len(FFT_abs)//2], envelope_result, absFFTOfEnvelope, 10000.0/2048, 10000.0)



#其中:signal_2048_two_sin.genSignal(2048, 2000, 1800)的代码参见下文

 

import math
import wave
import struct
import numpy as np
import matplotlib.pyplot as plt


def genSignal(pt, freq1, freq2):
    # 采样率和采样点数
    sample_rate = 10000
    num_samples = 2048

    # 信号频率和振幅
    frequency_1 = freq1
    frequency_2 = freq2
    amplitude = 0.5

    # 计算每个采样点的时间间隔
    time_interval = 1 / sample_rate

    # 初始化采样点列表
    samples = []
    signal = []
    # 生成采样点
    for i in range(num_samples):
        t = i * time_interval
        value = amplitude * math.sin(2 * math.pi * frequency_1 * t) + amplitude * math.sin(2 * math.pi * frequency_2 * t)
        scaled_value = round(value * 32767)  # 缩放到S16范围
        if(scaled_value>=32767):
            scaled_value = 32767
        if(scaled_value<=-32767):
            scaled_value = 32767
        signal.append(scaled_value)
        samples.append(struct.pack('<h', scaled_value))  # 打包为16位整数,并添加到采样点列表

    # 保存到WAV文件
    wave_file = wave.open('output.wav', 'wb')
    wave_file.setnchannels(1)
    wave_file.setsampwidth(2)
    wave_file.setframerate(sample_rate)
    wave_file.writeframes(b''.join(samples))
    wave_file.close()

    t = np.arange(0, len(signal));
    fig = plt.figure(1, figsize=(8, 10));
    plt1 = fig.add_subplot(2, 1, 1)
    plt1.plot(t,signal)
    plt1.set_xlabel('Time (s)')
    plt1.set_ylabel('Amplitude')
    plt1.set_title('Original Signal')


    # 傅里叶变换
    X = np.fft.fft(signal)  # 计算原始信号的傅里叶变换
    freq = np.arange(0,len(X))
    absFFT = [abs(item) for item in X]; #*2/len(X)
    plt2 = fig.add_subplot(2, 1, 2)
    plt2.plot(freq, absFFT)
    plt2.set_xlabel('Freq (?Hz)')
    plt2.set_ylabel('Amplitude')
    plt2.set_title('FFT')
    fig.show()
    return (signal, X, absFFT);

2.1实际显示效果:

原始波形在左侧,右侧的时域波形似乎完全不对,它应该频率很低才对。但是频谱显示,右侧的峰线确实在左移。我错在哪里了?

上面那个滤波处理,我没有选高通滤波,而是企图直接抹掉频域的一根根谱线,此时的幅角变换我弄错了,对吧? 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1254661.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Seurat Tutorial 1:标准分析流程,基于 PBMC 3K 数据集

目录 1 设置 Seurat 对象2 标准预处理工作流程 2.1 QC 和选择细胞进行进一步分析3 数据归一化4 识别高变特征&#xff08;特征选择&#xff09;5 标准化数据6 执行线性降维7 确定数据集的维度8 细胞聚类9 运行非线性降维 (UMAP/tSNE)10 寻找差异表达特征&#xff08;cluster b…

数据结构(超详细讲解!!)第二十五节 线索二叉树

1.线索二叉树的定义和结构 问题的提出&#xff1a; 通过遍历二叉树可得到结点的一个线性序列&#xff0c;在线性序列中&#xff0c;很容易求得某个结点的直接前驱和后继。但是在二叉树上只能找到结点的左孩子、右孩子&#xff0c;结点的前驱和后继只有在遍历过程中才能得到…

计算机视觉面试题-02

图像处理和计算机视觉基础 什么是图像滤波&#xff1f;有哪些常见的图像滤波器&#xff1f; 图像滤波是一种通过在图像上应用滤波器&#xff08;卷积核&#xff09;来改变图像外观或提取图像特征的图像处理技术。滤波器通常是一个小的矩阵&#xff0c;通过在图像上进行卷积…

【Linux】第二十站:模拟实现shell

文章目录 一、shell的实现细节1.shell的一些细节2.用户名、主机名、工作目录2.输入命令3.改为循环4.切割字符串5.普通命令的执行6.内建命令的处理7.子进程的退出码8.总结 二、模式实现shell完整代码 一、shell的实现细节 1.shell的一些细节 shell操作系统的一个外壳程序。 s…

【JavaEE初阶】浅谈进程

✏️✏️✏️今天正式进入JavaEE初阶的学习&#xff0c;给大家分享一下关于进程的一些基础知识。了解这部分内容&#xff0c;只是为后续多线程编程打好基础&#xff0c;因此进程部分的知识&#xff0c;不需要了解更加细节的内容。 清风的CSDN博客 &#x1f61b;&#x1f61b;&a…

Unsupervised Skill Discovery via Recurrent Skill Training论文笔记

Zheyuan Jiang, Jingyue Gao, Jianyu Chen (2022). Unsupervised Skill Discovery via Recurrent Skill Training. In Conference on Neural Information Processing Systems (NeurIPS), 2022. 通过循环技能训练发现无监督技能 1、Motivation 以往的无监督技能发现方法主要使…

Spring面向切面编程(AOP);Spring控制反转(IOC);解释一下Spring AOP里面的几个名词;Spring 的 IoC支持哪些功能

文章目录 Spring面向切面编程(AOP)什么是AOPSpring AOP and AspectJ AOP 的区别&#xff1f;Spring AOP中的动态代理如何理解 Spring 中的代理&#xff1f;解释一下Spring AOP里面的几个名词Spring在运行时通知对象Spring切面可以应用5种类型的通知&#xff1a;什么是切面 Aspe…

【开源】基于Vue+SpringBoot的食品生产管理系统

项目编号&#xff1a; S 044 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S044&#xff0c;文末获取源码。} 项目编号&#xff1a;S044&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 加工厂管理模块2.2 客户管理模块2.3…

Typescript基础面试题 | 05.精选 ts 面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

代码随想录算法训练营第四十九天|123. 买卖股票的最佳时机III 、188. 买卖股票的最佳时机 IV

LeetCode 123. 买卖股票的最佳时机 III 题目链接&#xff1a;123. 买卖股票的最佳时机 III - 力扣&#xff08;LeetCode&#xff09; 这个道题和121. 买卖股票的最佳时机 I、122. 买卖股票的最佳时机 II很像&#xff0c;是两题的结合。 我们就定义两个数组来实现。 代码&…

【Apache Doris】Manager极致丝滑地运维管理

【Apache Doris】Manager极致丝滑地运维管理 1.标准VS可视化运维管理2. 环境信息2.1.硬件信息2.2.软件信息 3.前置准备3.1.安装包准备3.2.文档手册准备 4.集群初始化4.1.系统参数预设4.2.Manager部署4.3.新集群部署4.4 监控告警4.4.1 监控4.4.2 告警 5. 集群升级5.1 新包准备5.…

C#,《小白学程序》第二十一课:大数的减法(BigInteger Subtract)

1 文本格式 using System; using System.Linq; using System.Text; using System.Collections.Generic; /// <summary> /// 大数的&#xff08;加减乘除&#xff09;四则运算、阶乘运算 /// 乘法计算包括小学生算法、Karatsuba和Toom-Cook3算法 /// </summary> p…

第二十一章 解读XML与JSON文件格式(工具)

XML 带分隔符的文件仅有两维的数据&#xff1a;行 & 列。如果我们想在程序之间交换数据结构&#xff0c;需要一种方法把层次结构&#xff0c;序列&#xff0c;集合和其它的数据结构编码成文本。 今天要说的 XML 是最突出的处理上述这种转换的标记格式&#xff0c;它使用标…

01、copilot+pycharm

之——free for student 目录 之——free for student 杂谈 正文 1.for student 2.pycharm 3.使用 杂谈 copilot是github推出的AI程序员&#xff0c;将chatgpt搬到了私人终端且无token限制&#xff0c;下面是使用方法。 GitHub Copilot 是由 GitHub 与 OpenAI 合作开发的…

智能AI名片-Pushmall推贴SCRM数字名片的发展趋势

智能AI名片-Pushmall推贴SCRM数字名片的发展趋势 基于相识靠铺人脉相互引荐&#xff0c;共享人脉资源&#xff0c;众筹共创赋能交友、商务实现大众创业&#xff0c;灵活创收的智能AI名片平台。帮助企业实现成员管理与客户资源管理。功能说明 1、搜索查询&#xff1a;个人信息与…

Leetcode—828.统计子串中的唯一字符【困难】

2023每日刷题&#xff08;四十一&#xff09; Leetcode—828.统计子串中的唯一字符 算法思想 枚举所有种类字母在s中出现的位置&#xff0c;分别统计只包含这个字母不包含该类字母中其他字母的子串个数 实现代码 int uniqueLetterString(char* s) {int len strlen(s);cha…

Quartz定时任务基础

springBoot有一个定时执行某个方法的 注解&#xff1a; Scheduled 可以满足挺多的需求&#xff0c;但是到了一些场景&#xff0c;就显得比较麻烦&#xff0c;比如&#xff1a; 机器待机五分钟后执行切换待机状态。如果是按照使用Scheduled注解&#xff0c;就得持久化一个表&…

【5G PHY】5G SS/PBCH块介绍(四)

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

利用ngrok实现内网穿透(全网最详细教程)

准备工具&#xff1a; 1、phpstudy 用于在本地搭建网站 2、ngrok 用于将自己的本地端口暴露到公网上&#xff0c;从而实现内网穿透 文章开始前给大家分享一个学习人工智能的网站&#xff0c;通俗易懂&#xff0c;风趣幽默 人工智能https://www.captainbed.cn/myon/ ~~~~~…

C#文件基本操作(判断文件是否存在、创建文件、复制或移动文件、删除文件以及获取文件基本信息)

目录 一、判断文件是否存在 1.File类的Exists()方法 2.FileInfo类的Exists属性 二、创建文件 1.File类的Create()方法 2.FileInfo类的Create()方法 三、复制或移动文件 1.File类的Copy()方法 2.File类的Move()方法 3.FileInfo类的CopyTo()方法 四、删除文件 1.File…