[学习] GNSS信号跟踪环路原理、设计与仿真(仿真代码)

news2025/6/9 1:58:49

GNSS信号跟踪环路原理、设计与仿真

文章目录

      • GNSS信号跟踪环路原理、设计与仿真
        • 一、GNSS信号跟踪环路概述
        • 二、跟踪环路基本原理
          • 1. 信号跟踪的概念与目标
          • 2. 锁相环(PLL)原理
          • 3. 锁频环(FLL)原理
          • 4. 延迟锁定环(DLL)原理
          • 5. 三环联合跟踪结构
        • 三、跟踪环路关键参数设计
        • 四、跟踪环路性能分析
        • 五、环路仿真示例
          • 代码功能说明
          • 关键可视化结果
          • 运行说明
          • 参数调整建议
      • 附录:关键公式


一、GNSS信号跟踪环路概述
  • GNSS信号接收的基本流程
    完整的GNSS信号接收处理包括以下关键步骤:天线接收射频信号→低噪声放大→下变频至中频→AD采样→捕获阶段(粗略估计卫星信号的多普勒频移和码相位)→跟踪阶段(精确同步并持续跟踪信号)。以GPS L1 C/A码为例,接收信号先经过1575.42MHz的射频前端处理,再通过数字相关器实现伪码剥离和载波剥离。
    流程如下图所示:
粗略估计多普勒频移
粗略估计码相位
开始
天线接收射频信号
低噪声放大器 (LNA)
下变频至中频(IF)/基带
模数转换 (AD采样)
捕获阶段
捕获完成?
跟踪阶段
精确同步多普勒和码相位
提取导航数据比特
解调与解码
定位解算(PVT)
输出定位信息
结束
  • 跟踪环路的定义与功能
    跟踪环路是由载波跟踪环(如PLL或FLL)和码跟踪环(DLL)组成的闭环控制系统。其核心功能包括:

    1. 实时补偿动态用户导致的载波多普勒变化(如车载接收机运动时可能产生±5kHz的频偏)
    2. 精确对齐本地伪随机码与接收信号的码相位(C/A码要求对齐误差小于1/4码片,约73米)
    3. 解调导航电文数据(50bps的导航比特流)
      典型结构包含鉴相器、环路滤波器和数控振荡器(NCO)三个模块。
  • 跟踪环路在GNSS接收机中的重要性
    跟踪性能直接决定定位精度和可用性:
    • 动态场景下(如无人机应用),环路带宽设计需在跟踪灵敏度(窄带宽)与动态应力容限(宽带宽)间折衷
    • 城市峡谷环境中,多径效应可能导致传统DLL出现米级误差,此时需采用窄相关器或多径抑制技术
    • 高精度接收机(如RTK)要求载波相位跟踪精度达毫米级,需结合卡尔曼滤波等先进算法


二、跟踪环路基本原理
1. 信号跟踪的概念与目标

信号跟踪是指接收机持续锁定并跟随卫星信号的过程,主要实现两个目标:

  • 动态适应:在用户移动过程中保持对信号频率和相位变化的跟踪(如车载导航时速达200km/h时产生的多普勒频移)
  • 抗干扰:在噪声和干扰环境下维持稳定跟踪(如城市峡谷中信号衰减达20dB时仍能工作)
2. 锁相环(PLL)原理

PLL通过相位鉴别实现精确跟踪:

  • 核心组件:鉴相器(比较输入信号与本地振荡器相位差)、环路滤波器(如二阶滤波器去除高频噪声)、压控振荡器(调整频率)
  • 典型参数:捕获范围±5Hz,跟踪精度±0.25Hz
  • 应用场景:高精度测距、载波相位测量(RTK定位中要求相位误差<1°)
3. 锁频环(FLL)原理

FLL通过频率鉴别实现快速跟踪:

  • 工作方式:比较相邻两个积分周期的相位差(典型积分时间1-10ms)
  • 性能特点:捕获范围可达±500Hz,但精度较PLL低约1Hz
  • 典型应用:高动态场景初始化(如导弹发射初期的信号捕获)
4. 延迟锁定环(DLL)原理

DLL专用于码跟踪:

  • 实现方式:采用早-迟相关器结构(间隔通常为1/2码片)
  • 关键指标:码环带宽0.5-2Hz,跟踪门限约20dB-Hz
  • 特殊结构:双阻尼设计(高速时用宽带宽,静态时切窄带宽)
5. 三环联合跟踪结构

多环路协同工作模式:

  • FLL辅助PLL:FLL先捕获信号(±1kHz范围),PLL随后精细锁定(切换阈值通常设为FLL频率误差<5Hz)
  • PLL辅助DLL:载波环提供动态应力信息给码环(如PLL测得的加速度用于DLL预测)

三、跟踪环路关键参数设计
  1. 环路带宽的选择与优化

    • 环路带宽直接影响跟踪环路的动态性能和抗噪声能力
    • 窄带宽:噪声抑制好但动态响应慢(典型值1-10Hz)
    • 宽带宽:动态性能好但噪声抑制差(典型值10-100Hz)
    • 优化方法:
      • 根据动态场景需求调整(如车载应用需要10-20Hz)
      • 采用自适应带宽算法(如基于载噪比的自适应调整)
  2. 积分时间的设计

    • 积分时间决定环路对信号积累的时长
    • 短积分时间(1ms):适用于高动态场景
    • 长积分时间(20ms):适用于弱信号环境
    • 设计要点:
      • 需与数据位边界对齐(GPS的20ms数据位)
      • 平衡捕获灵敏度和动态性能的矛盾
  3. 鉴别器类型与性能比较

    • 载波环鉴别器

      • ATAN2鉴别器:
        • 提供线性输出范围(-π/2~π/2)
        • 适用于高动态环境
        • 计算复杂度较高
      • Costas鉴别器:
        • 抗180度相位翻转
        • 适用于BPSK调制信号
        • 输出非线性(sin(2Δφ))
    • 码环鉴别器

      • 非相干早迟门:
        • 典型间隔1/2码片
        • 抗多径性能较好
        • 需要额外的载波剥离
      • 相干点积:
        • 更高精度
        • 但需要精确的载波跟踪
        • 适用于高精度应用
  4. 环路滤波器的设计与实现

    • 二阶环路滤波器:
      • 典型结构:比例积分(PI)滤波器
      • 参数计算:
        K1 = 4B_LT/(4+4ξ^2)
        K2 = 4B_L2T/(4+4ξ2)
        (B_L为噪声带宽,ξ为阻尼系数,T为积分时间)
    • 三阶环路滤波器:
      • 适用于超高动态场景
      • 增加加速度误差补偿
    • 实现方式:
      • 数字实现:定点/浮点运算选择
      • 考虑量化噪声影响
      • 典型更新率1ms-20ms

四、跟踪环路性能分析
  1. 跟踪灵敏度的定义与影响因素

    • 跟踪灵敏度是指接收机能够稳定跟踪卫星信号的最低信号强度(通常用dB-Hz表示)
    • 主要影响因素:
      • 环路带宽:带宽越窄灵敏度越高,但动态性能越差(典型值0.5-5Hz)
      • 积分时间:延长积分时间可提高灵敏度(如从1ms增至20ms)
      • 前端噪声系数:接收机前端噪声直接影响灵敏度
      • 信号调制方式:BPSK比BOC调制更易跟踪
      • 载噪比(C/N0):跟踪门限通常为20-25dB-Hz
  2. 动态性能与噪声性能的权衡

    • 动态性能指标:最大可跟踪加速度(0.5g)、加加速度(1g/s)
    • 噪声性能指标:伪距测量误差(0.1-1m)、载波相位噪声(1-5mm)
    • 设计权衡:
      • 宽带环路(如10Hz)适合高动态环境但噪声大
      • 窄带环路(如1Hz)适合静态应用但动态受限
      • 自适应带宽技术可根据场景自动调整
  3. 多径效应的影响与缓解方法

    • 多径效应会导致:
      • 伪距测量偏差(最大可达半波长)
      • 载波相位周跳
      • 跟踪环路失锁
    • 缓解技术:
      • 窄相关间隔技术(如Strobe相关器)
      • 多径估计消除算法(MEDLL)
      • 天线抗多径设计(扼流圈天线)
      • 信号选择(L5比L1抗多径能力强30%)
  4. 抗干扰能力分析

    • 干扰类型:
      • 宽带噪声干扰(最常见)
      • 单频干扰(容易滤除)
      • 脉冲干扰(影响最大)
      • 欺骗干扰(最难防范)
    • 防护措施:
      • 空域滤波:自适应调零天线
      • 时域滤波:脉冲干扰消除
      • 频域滤波:FFT窄带抑制
      • 信号处理:增强相关器设计
    • 典型指标:
      • 窄带干扰抑制比>30dB
      • 宽带干扰抑制比>20dB
      • 欺骗信号识别时间<1s

五、环路仿真示例

以下是一个完整的Python仿真代码,实现了GPS L1 C/A码信号跟踪过程(PRN 1)。代码包含信号生成、跟踪环实现和可视化分析。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
from scipy.signal import correlate

# ==============================
# 参数设置
# ==============================
fs = 6.144e6            # 采样率 (6.144 MHz)
f_IF = 4.308e6          # 中频频率 (4.308 MHz)
code_rate = 1.023e6     # C/A码速率 (1.023 MHz)
code_length = 1023       # C/A码长度
ts = 1/fs               # 采样间隔
t_coherent = 1e-3       # 相干积分时间 (1ms)
samples_per_ms = int(fs * t_coherent)  # 每毫秒采样点数
doppler_true = 4200      # 真实多普勒频移 (Hz)
code_delay_true = 175.3  # 真实码延迟 (采样点)
SNR_dB = -20            # 信噪比 (dB)

# 跟踪环参数
dll_damping = 0.7       # DLL阻尼系数
dll_bandwidth = 2.0     # DLL带宽 (Hz)
dll_noise_bandwidth = dll_bandwidth * 8/(4*dll_damping + 1/dll_damping)  # 噪声带宽
dll_gain = 4 * dll_noise_bandwidth * t_coherent  # DLL增益

costas_damping = 0.707  # Costas环阻尼系数
costas_bandwidth = 15.0 # Costas环带宽 (Hz)
costas_noise_bandwidth = costas_bandwidth * 4 * costas_damping / (4*costas_damping**2 + 1)  # 噪声带宽
costas_gain = 4 * costas_noise_bandwidth * t_coherent  # Costas环增益

# ==============================
# 辅助函数
# ==============================
def generate_ca_code(prn, code_length=1023):
    """生成PRN 1的C/A码"""
    # PRN 1的Gold码生成多项式
    g1 = np.ones(10, dtype=int)
    g2 = np.ones(10, dtype=int)
    ca_code = np.zeros(code_length, dtype=int)
    
    for i in range(code_length):
        ca_code[i] = g1[9] ^ g2[9]  # PRN 1的特殊抽头配置
        
        # 更新G1寄存器
        g1_new = g1[2] ^ g1[9]
        g1[1:] = g1[:-1]
        g1[0] = g1_new
        
        # 更新G2寄存器 (PRN 1的特殊抽头: 2和6)
        g2_new = g2[1] ^ g2[2] ^ g2[5] ^ g2[7] ^ g2[8] ^ g2[9]
        g2[1:] = g2[:-1]
        g2[0] = g2_new
    
    return 1 - 2*ca_code  # 转换为±1

def generate_nav_data(bit_rate=50, duration=0.3):
    """生成50Hz导航电文数据"""
    num_bits = int(bit_rate * duration)
    return 1 - 2*np.random.randint(0, 2, num_bits)  # 随机生成±1

def add_doppler(signal, f_doppler, fs, phase=0):
    """添加多普勒频移"""
    t = np.arange(len(signal)) / fs
    return signal * np.exp(1j * 2 * np.pi * f_doppler * t + 1j * phase)

def add_noise(signal, snr_dB):
    """添加高斯白噪声"""
    signal_power = np.mean(np.abs(signal)**2)
    noise_power = signal_power / (10**(snr_dB/10))
    noise = np.sqrt(noise_power/2) * (np.random.randn(len(signal)) + 1j*np.random.randn(len(signal)))
    return signal + noise

# ==============================
# 信号生成
# ==============================
# 生成C/A码
ca_code = generate_ca_code(1)

# 生成导航电文 (300ms)
nav_data = generate_nav_data(50, 0.3)

# 创建完整基带信号
t_total = 0.3  # 300ms
num_samples = int(fs * t_total)
signal = np.zeros(num_samples, dtype=complex)

# 扩展C/A码以匹配信号长度
ca_code_full = np.tile(ca_code, int(np.ceil(num_samples / len(ca_code))))[:num_samples]

# 添加导航电文
for i in range(len(nav_data)):
    start_idx = i * samples_per_ms * 20  # 每比特20ms
    end_idx = (i+1) * samples_per_ms * 20
    if end_idx > num_samples:
        end_idx = num_samples
    signal[start_idx:end_idx] = nav_data[i] * ca_code_full[start_idx:end_idx]

# 添加载波和多普勒
signal = add_doppler(signal, f_IF + doppler_true, fs, phase=np.pi/4)

# 添加码延迟
signal = np.roll(signal, int(code_delay_true))

# 添加噪声
signal = add_noise(signal, SNR_dB)

# ==============================
# 跟踪环实现
# ==============================
class TrackingLoop:
    def __init__(self, fs, f_IF, code_length, samples_per_ms, 
                 dll_gain, costas_gain, dll_spacing=0.5):
        self.fs = fs
        self.f_IF = f_IF
        self.code_length = code_length
        self.samples_per_ms = samples_per_ms
        self.dll_gain = dll_gain
        self.costas_gain = costas_gain
        self.dll_spacing = dll_spacing  # 超前滞后码间距 (码片)
        
        # 状态变量初始化
        self.carrier_phase = 0.0
        self.carrier_freq = f_IF + 4000  # 初始多普勒估计 (带误差)
        self.code_phase = 170.0  # 初始码相位估计 (带误差)
        self.code_freq = code_rate  # 码频率
        
        # 积分器状态
        self.I_E = 0.0
        self.Q_E = 0.0
        self.I_P = 0.0
        self.Q_P = 0.0
        self.I_L = 0.0
        self.Q_L = 0.0
        
        # 历史记录
        self.phase_error_history = []
        self.freq_error_history = []
        self.code_error_history = []
        self.corr_history = []
        
    def update(self, signal_chunk, ca_code):
        """处理1ms的信号块"""
        # 生成本地载波
        t = np.arange(len(signal_chunk)) / self.fs
        local_carrier = np.exp(-1j * (2 * np.pi * self.carrier_freq * t + self.carrier_phase))
        
        # 载波剥离
        baseband = signal_chunk * local_carrier
        
        # 生成本地C/A码 (三个版本)
        # 计算码相位偏移 (以采样点为单位)
        spacing_samples = self.dll_spacing * (self.fs / code_rate)
        
        # 即时码
        idx_p = np.arange(len(signal_chunk)) + self.code_phase
        ca_p = ca_code[np.mod(np.floor(idx_p).astype(int), self.code_length)]
        
        # 超前码 (提前spacing_samples)
        idx_e = idx_p - spacing_samples
        ca_e = ca_code[np.mod(np.floor(idx_e).astype(int), self.code_length)]
        
        # 滞后码 (延后spacing_samples)
        idx_l = idx_p + spacing_samples
        ca_l = ca_code[np.mod(np.floor(idx_l).astype(int), self.code_length)]
        
        # 相关积分 (1ms相干积分)
        self.I_E = np.sum(np.real(baseband) * ca_e)
        self.Q_E = np.sum(np.imag(baseband) * ca_e)
        self.I_P = np.sum(np.real(baseband) * ca_p)
        self.Q_P = np.sum(np.imag(baseband) * ca_p)
        self.I_L = np.sum(np.real(baseband) * ca_l)
        self.Q_L = np.sum(np.imag(baseband) * ca_l)
        
        # Costas环鉴相器 (相位误差检测)
        phase_error = np.arctan2(self.Q_P, self.I_P)
        
        # DLL鉴相器 (非相干超前减滞后)
        E = np.sqrt(self.I_E**2 + self.Q_E**2)
        L = np.sqrt(self.I_L**2 + self.Q_L**2)
        code_error = (E - L) / (2 * (E + L))  # 归一化误差
        
        # 更新载波环
        self.carrier_freq += self.costas_gain * phase_error
        self.carrier_phase += phase_error
        
        # 更新码环
        self.code_phase += self.dll_gain * code_error
        
        # 记录历史
        self.phase_error_history.append(np.degrees(phase_error))
        self.freq_error_history.append(self.carrier_freq - (f_IF + doppler_true))
        self.code_error_history.append((self.code_phase - code_delay_true) * (code_rate/fs))
        self.corr_history.append((self.I_P, self.Q_P, self.I_E, self.Q_E, self.I_L, self.Q_L))
        
        # 相位归零处理
        if self.carrier_phase > 2*np.pi:
            self.carrier_phase -= 2*np.pi
        elif self.carrier_phase < -2*np.pi:
            self.carrier_phase += 2*np.pi
            
        return phase_error, code_error

# ==============================
# 仿真运行
# ==============================
# 初始化跟踪环
tracker = TrackingLoop(fs, f_IF, code_length, samples_per_ms, 
                       dll_gain, costas_gain, dll_spacing=0.5)

# 运行跟踪过程 (300ms)
num_chunks = int(t_total / t_coherent)
for i in range(num_chunks):
    start_idx = i * samples_per_ms
    end_idx = (i+1) * samples_per_ms
    signal_chunk = signal[start_idx:end_idx]
    
    # 更新跟踪环
    phase_error, code_error = tracker.update(signal_chunk, ca_code)
    
    # 打印前10次更新
    if i < 10:
        print(f"Chunk {i+1}: Phase Error={np.degrees(phase_error):.2f}°, "
              f"Code Error={code_error:.4f} chips")

# ==============================
# 结果可视化
# ==============================
plt.figure(figsize=(15, 15))
gs = GridSpec(4, 2, figure=plt.gcf())

# 1. 载波相位误差
ax1 = plt.subplot(gs[0, 0])
ax1.plot(tracker.phase_error_history)
ax1.set_title('载波相位误差 (度)')
ax1.set_xlabel('时间 (ms)')
ax1.set_ylabel('相位误差 (°)')
ax1.grid(True)
ax1.axhline(15, color='r', linestyle='--', alpha=0.7, label='收敛阈值')
ax1.axhline(-15, color='r', linestyle='--', alpha=0.7)
ax1.legend()

# 2. 多普勒频率误差
ax2 = plt.subplot(gs[0, 1])
ax2.plot(np.array(tracker.freq_error_history) / 1000)
ax2.set_title('多普勒频率误差')
ax2.set_xlabel('时间 (ms)')
ax2.set_ylabel('频率误差 (kHz)')
ax2.grid(True)
ax2.axhline(0, color='r', linestyle='--', alpha=0.7)

# 3. 码相位误差
ax3 = plt.subplot(gs[1, 0])
ax3.plot(tracker.code_error_history)
ax3.set_title('码相位误差')
ax3.set_xlabel('时间 (ms)')
ax3.set_ylabel('码片误差')
ax3.grid(True)
ax3.axhline(0.1, color='r', linestyle='--', alpha=0.7, label='收敛阈值')
ax3.axhline(-0.1, color='r', linestyle='--', alpha=0.7)
ax3.legend()

# 4. 相关器输出 (IQ平面)
corr_data = np.array(tracker.corr_history)
ax4 = plt.subplot(gs[1, 1])
ax4.scatter(corr_data[:50, 0], corr_data[:50, 1], c='b', marker='o', label='前50ms')
ax4.scatter(corr_data[50:, 0], corr_data[50:, 1], c='r', marker='x', label='后250ms')
ax4.set_title('即时支路相关器输出 (IQ平面)')
ax4.set_xlabel('I 分量')
ax4.set_ylabel('Q 分量')
ax4.grid(True)
ax4.legend()
ax4.axis('equal')

# 5. 相关器输出幅度
E_mag = np.sqrt(corr_data[:, 2]**2 + corr_data[:, 3]**2)
P_mag = np.sqrt(corr_data[:, 0]**2 + corr_data[:, 1]**2)
L_mag = np.sqrt(corr_data[:, 4]**2 + corr_data[:, 5]**2)

ax5 = plt.subplot(gs[2, :])
ax5.plot(E_mag, label='超前支路')
ax5.plot(P_mag, label='即时支路')
ax5.plot(L_mag, label='滞后支路')
ax5.set_title('相关器输出幅度')
ax5.set_xlabel('时间 (ms)')
ax5.set_ylabel('相关幅度')
ax5.grid(True)
ax5.legend()

# 6. 导航电文解调
# 每20ms取一次符号 (1个导航比特)
nav_bits = []
for i in range(0, num_chunks, 20):
    if i+20 > num_chunks:
        break
    # 取20ms的I路积分值
    I_sum = np.sum(corr_data[i:i+20, 0])
    nav_bits.append(1 if I_sum > 0 else -1)

# 原始导航电文
true_nav = nav_data[:len(nav_bits)]

ax6 = plt.subplot(gs[3, :])
ax6.step(np.arange(len(nav_bits)), nav_bits, 'b-', where='post', label='解调电文')
ax6.step(np.arange(len(true_nav)), true_nav, 'r--', where='post', label='真实电文')
ax6.set_title('导航电文解调结果')
ax6.set_xlabel('比特序号')
ax6.set_ylabel('比特值')
ax6.set_yticks([-1, 1])
ax6.set_yticklabels(['-1 (0)', '1 (1)'])
ax6.grid(True)
ax6.legend()

plt.tight_layout()
plt.savefig('gps_tracking_results.png', dpi=300)
plt.show()

# 收敛性能分析
last_100 = slice(-100, None)
phase_stable = np.max(np.abs(tracker.phase_error_history[last_100])) < 15
freq_stable = np.abs(np.mean(tracker.freq_error_history[last_100])) < 10
code_stable = np.max(np.abs(tracker.code_error_history[last_100])) < 0.1

print("\n跟踪性能分析:")
print(f"载波相位稳定: {'是' if phase_stable else '否'} (最大误差: {np.max(np.abs(tracker.phase_error_history[last_100])):.2f}°)")
print(f"多普勒频率稳定: {'是' if freq_stable else '否'} (平均误差: {np.mean(tracker.freq_error_history[last_100]):.2f} Hz)")
print(f"码相位稳定: {'是' if code_stable else '否'} (最大误差: {np.max(np.abs(tracker.code_error_history[last_100])):.4f} 码片)")
print(f"导航电文正确率: {np.mean(np.array(nav_bits) == true_nav)*100:.2f}%")
代码功能说明
  1. 信号生成模块

    • 生成PRN 1的C/A码(使用Gold码生成算法)
    • 创建50Hz导航电文(随机比特序列)
    • 构建包含载波、多普勒和噪声的中频信号
  2. 跟踪环实现

    • Costas环(载波跟踪):使用arctan鉴相器和二阶环路滤波器
    • 延迟锁定环(码跟踪):使用非相干超前-滞后鉴别器
    • 实时更新载波频率、相位和码相位
  3. 可视化分析

    • 载波相位误差收敛过程
    • 多普勒频率跟踪性能
    • 码相位误差变化
    • 相关器输出(IQ平面和幅度)
    • 导航电文解调结果对比
关键可视化结果
  1. 载波相位误差

    • 显示载波环从初始误差收敛到稳定状态(<15°)的过程
    • 红色虚线表示收敛阈值
  2. 多普勒跟踪

    • 展示频率误差从初始4000Hz偏差收敛到接近0Hz的过程
  3. 码相位误差

    • 显示码环收敛到±0.1码片精度的过程
  4. 相关器输出

    • IQ平面:展示相关点从发散到聚集的过程
    • 幅度图:显示超前、即时、滞后三路相关器输出
  5. 导航电文解调

    • 对比解调出的导航电文与原始电文
    • 计算解调正确率
运行说明
  1. 代码需要安装Python科学计算库:

    pip install numpy matplotlib scipy
    
  2. 运行后将生成6个子图,展示跟踪过程的关键性能指标

  3. 程序输出跟踪性能分析,包括:

    • 载波相位稳定状态
    • 多普勒频率跟踪精度
    • 码相位跟踪精度
    • 导航电文解调正确率
参数调整建议
  1. 信号强度:修改SNR_dB参数(典型范围-20dB至-30dB)
  2. 动态特性:调整doppler_true模拟不同动态场景
  3. 环路带宽
    • costas_bandwidth:影响载波环响应速度(典型值10-25Hz)
    • dll_bandwidth:影响码环响应速度(典型值1-5Hz)
  4. 初始误差:在TrackingLoop初始化中调整初始频率和相位误差

此代码完整展示了GPS信号跟踪的全过程,通过可视化结果可清晰观察环路收敛特性和跟踪性能。


附录:关键公式

载波环鉴别器输出(ATAN2型):
θ e = arctan ⁡ ( Q I ) \theta_e = \arctan\left(\frac{Q}{I}\right) θe=arctan(IQ)

DLL早迟门非相干鉴别器:
E = I E 2 + Q E 2 , L = I L 2 + Q L 2 E = \sqrt{I_E^2 + Q_E^2}, \quad L = \sqrt{I_L^2 + Q_L^2} E=IE2+QE2 ,L=IL2+QL2
ϵ = E − L E + L \epsilon = \frac{E - L}{E + L} ϵ=E+LEL


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


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

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

相关文章

Spark 之 DataFrame 开发

foreachPartition val data = spark.sparkContext.parallelize(1 to 100)// 使用 foreachPartition 批量处理分区 data.foreachPartition {partitionIterator =

嵌入式学习笔记 - freeRTOS xTaskResumeAll( )函数解析

第一部分 移除挂起等待列表中的任务 while( listLIST_IS_EMPTY( &xPendingReadyList ) pdFALSE )//循环寻找直到为空&#xff0c;把全部任务扫描一遍 { pxTCB ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingR…

机器学习KNN算法全解析:从原理到实战

大家好&#xff01;今天我们来聊聊机器学习中的"懒人算法"——KNN&#xff08;K-Nearest Neighbors&#xff0c;K近邻&#xff09;算法。这个算法就像个"墙头草"&#xff0c;它不学习模型参数&#xff0c;而是直接根据邻居的"投票"来做决策&…

【QT】自定义QWidget标题栏,可拖拽(拖拽时窗体变为normal大小),可最小/大化、关闭(图文详情)

目录 0.背景 1.详细实现 思路简介 .h文件 .cpp文件 0.背景 Qt Linux&#xff1b;项目遇到问题&#xff0c;解决后特此记录 项目需要&#xff0c;个性化的标题栏&#xff08;是个widget&#xff09;&#xff0c;在传统的三个按钮&#xff08;最大化、最小化、关闭&#xf…

FPGA定点和浮点数学运算-实例对比

在创建 RTL 示例时&#xff0c;经常使用 VHDL 2008 附带的 VHDL 包。它提供了出色的功能&#xff0c;可以高效地处理定点数&#xff0c;当然&#xff0c;它们也是可综合的。该包的一些优点包括&#xff1a; 有符号和无符号&#xff08;后缀和后缀&#xff09;定点向量。轻松将定…

Linux编程:2、进程基础知识

一、进程基本概念 1、进程与程序的区别 程序&#xff1a;静态的可执行文件&#xff08;如电脑中的vs2022安装程序&#xff09;。进程&#xff1a;程序的动态执行过程&#xff08;如启动后的vs2022实例&#xff09;&#xff0c;是操作系统分配资源的单位&#xff08;如 CPU 时…

Cursor Rules 使用

前言 最近在使用 Cursor 进行编程辅助时&#xff0c;发现 AI 生成的代码风格和当前的代码风格大相径庭。而且有时它会输出很奇怪的代码&#xff0c;总是不符合预期。 遂引出本篇&#xff0c;介绍一下 Rules &#xff0c;它就可以做一些规范约束之类的事情。 什么是 Cursor R…

服务器数据恢复—服务器raid5阵列崩溃如何恢复数据?

服务器数据恢复环境&故障&#xff1a; 某品牌型号为X3850服务器上有一组由14块数据盘和1块热备盘组建的raid5磁盘阵列。 服务器在正常使用过程中突然崩溃&#xff0c;管理员查看raid5阵列故障情况的时发现磁盘阵列中有2块硬盘掉线&#xff0c;但是热备盘没有启用。 服务器数…

Go语言堆内存管理

Go堆内存管理 1. Go内存模型层级结构 Golang内存管理模型与TCMalloc的设计极其相似。基本轮廓和概念也几乎相同&#xff0c;只是一些规则和流程存在差异。 2. Go内存管理的基本概念 Go内存管理的许多概念在TCMalloc中已经有了&#xff0c;含义是相同的&#xff0c;只是名字有…

【DAY41】简单CNN

内容来自浙大疏锦行python打卡训练营 浙大疏锦行 知识点&#xff1a; 数据增强卷积神经网络定义的写法batch归一化&#xff1a;调整一个批次的分布&#xff0c;常用与图像数据特征图&#xff1a;只有卷积操作输出的才叫特征图调度器&#xff1a;直接修改基础学习率 卷积操作常…

使用MinIO搭建自己的分布式文件存储

目录 引言&#xff1a; 一.什么是 MinIO &#xff1f; 二.MinIO 的安装与部署&#xff1a; 三.Spring Cloud 集成 MinIO&#xff1a; 1.前提准备&#xff1a; &#xff08;1&#xff09;安装依赖&#xff1a; &#xff08;2&#xff09;配置MinIO连接&#xff1a; &…

K7 系列各种PCIE IP核的对比

上面三个IP 有什么区别&#xff0c;什么时候用呢&#xff1f; 7 series Integrated Block for PCIE AXI Memory Mapped to PCI Express DMA subsystem for PCI Express 特点 这是 Kintex-7 内置的 硬核 PCIe 模块。部分事务层也集成在里面&#xff0c;使用标准的PCIE 基本没…

natapp 内网穿透失败

连不上网络错误调试排查详解 - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具 如何将DNS服务器修改为114.114.114.114_百度知道 连不上/错误信息等问题解决汇总 - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具 nslookup auth.natapp.cnping auth.natapp.cn

深入解析CI/CD开发流程

引言&#xff1a;主播最近实习的时候发现部门里面使用的是CI/CD这样的集成开发部署&#xff0c;但是自己不是太了解什么意思&#xff0c;所以就自己查了一下ci/cd相关的资料&#xff0c;整理分享了一下 一、CI/CD CI/CD是持续集成和持续交付部署的缩写&#xff0c;旨在简化并…

Docke启动Ktransformers部署Qwen3MOE模型实战与性能测试

docker运行Ktransformers部署Qwen3MOE模型实战及 性能测试 最开始拉取ktransformers:v0.3.1-AVX512版本&#xff0c;发现无论如何都启动不了大模型&#xff0c;后来发现是cpu不支持avx512指令集。 由于本地cpu不支持amx指令集&#xff0c;因此下载avx2版本镜像&#xff1a; …

应用分享 | 精准生成和时序控制!AWG在确定性三量子比特纠缠光子源中的应用

在量子技术飞速发展的今天&#xff0c;实现高效稳定的量子态操控是推动量子计算、量子通信等领域迈向实用化的关键。任意波形发生器&#xff08;AWG&#xff09;作为精准信号控制的核心设备&#xff0c;在量子实验中发挥着不可或缺的作用。丹麦哥本哈根大学的研究团队基于单个量…

相机--相机标定实操

教程 camera_calibration移动画面示例 usb_cam使用介绍和下载 标定流程 单目相机标定 我使用的是USB相机&#xff0c;所以直接使用ros的usb_cam功能包驱动相机闭关获取实时图像&#xff0c;然后用ros的camera_calibration标定相机。 1,下载usb_cam和camera_calibration: …

DAY43 复习日

浙大疏锦行-CSDN博客 kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;把项目拆分成多个文件 src/config.py: 用于存放项目配置&#xff0c;例如文件路径、学习率、批次大小等。 # src/config.py# Paths DATA_DIR "data…

【Auto.js例程】华为备忘录导出到其他手机

目录 问题描述方法步骤1.安装下载Visual Studio Code2.安装扩展3.找到Auto.js插件&#xff0c;并安装插件4.启动服务器5.连接手机6.撰写脚本并运行7.本文实现功能的代码8.启动手机上的换机软件 问题描述 问题背景&#xff1a;华为手机换成一加手机&#xff0c;华为备忘录无法批…

单片机的低功耗模式

什么是低功耗&#xff1f; STM32的低功耗&#xff08;low power mode&#xff09;特性是其嵌入式处理器系列的一个重要优势&#xff0c;特别适用于需要长时间运行且功耗敏感的应用场景&#xff0c;如便携式设备、物联网设备、智能家居系统等。 在很多应用场合中都对电子设备的…