文章目录
- 安装和简介
- 定义参数
- 仿真
- 可视化
安装和简介
OptiCommPy 是一个基于 Python 的开源框架,专门用于光纤通信系统、子系统及核心组件的数值仿真。它主要面向光通信领域的教育与科学研究,涵盖了从物理层光信号传输到接收端数字信号处理(DSP)的完整链路。安装没什么好说的,pip即可
pip install OptiCommPy-i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后,可以做一个简单的眼图测试。
定义参数
在OptiCommPy中,一般采取专门的parameters类进行参数传递。在仿真过程中,主要涉及到四类参数,分别是
- 全局与基础仿真参数,包括每符号采样数、调制阶数、符号速率、采样率
- 发射机参数,包括比特源、脉冲参数和马赫-曾德尔调制器参数
- 光纤信道参数
- 接收机参数
代码如下
fromoptic.utilsimportparameters SpS=16# 每符号采样数 (Samples per symbol)M=2# 调制阶数 (2-PAM 即 OOK)Rs=10e9# 符号速率 10 GBaudFs=SpS*Rs# 采样率 160 GHz# 发射机参数paramBits=parameters()paramBits.nBits=2000paramBits.mode='random'paramBits.seed=123paramPulse=parameters()paramPulse.pulseType='nrz'paramPulse.SpS=SpS paramMZM=parameters()paramMZM.Vpi=2.0paramMZM.Vb=-paramMZM.Vpi/2# 偏置在 Null 点实现 OOK# 信道参数 (80km 标准单模光纤)paramCh=parameters()paramCh.L=80paramCh.alpha=0.2paramCh.D=16paramCh.Fc=193.1e12paramCh.Fs=Fs# 接收机参数paramPD=parameters()paramPD.ideal=True# 设为 True 忽略噪声,方便观察纯净的眼图paramPD.B=Rs paramPD.Fs=Fs paramPD.seed=456仿真
仿真流程与物理过程保持一致,其步骤如下
- 发射端:电信号生成与脉冲成型
- 强度调制 (IM):电信号转换为光信号
- 光纤信道:光域传输与线性损伤
- 直接检测 (DD):光信号转换为电信号
- 接收端:电域滤波与采样
仿真代码为
importnumpyasnpfromoptic.comm.sourcesimportbitSourcefromoptic.comm.modulationimportmodulateGrayfromoptic.dsp.coreimportupsample,pulseShape,firFilter,anormfromoptic.utilsimportdBm2Wfromoptic.models.devicesimportmzm,photodiodefromoptic.models.channelsimportlinearFiberChannel# 1) 生成比特序列并映射为 2-PAM 符号bitsTx=bitSource(paramBits)symbTx=modulateGray(bitsTx,M,"pam")# 上采样与脉冲成型symbolsUp=upsample(symbTx,SpS)pulse=pulseShape(paramPulse)# 生成 NRZ 滤波器系数sigTx=firFilter(pulse,symbolsUp)# 对 upsampling 后的信号进行 FIR 滤波sigTx=anorm(sigTx)# 归一化到 1 Vpp# MZM 强度调制 (IM)Pi=dBm2W(3)sigTxo=mzm(np.sqrt(Pi),sigTx,paramMZM)# 理想连续波激光器输入光场幅度sigCh=linearFiberChannel(sigTxo,paramCh)# 光纤信道传输I_Rx=photodiode(sigCh,paramPD)# 光电二极管直接检测 (DD)可视化
接下来的目标是绘制下图
左图是信号接收图,右图是眼图,每一条线都表示一个脉冲信号。绘图代码如下
importmatplotlib.pyplotasplt plt.rcParams['font.sans-serif']='Times New Roman'fig,axs=plt.subplots(1,2,figsize=(14,5))t_ns=np.arange(len(I_Rx))/Fs*1e9num_samples=100*SpS axs[0].plot(t_ns[:num_samples],I_Rx[:num_samples],color='b',linewidth=1.5)axs[0].set_title('Received Electrical Signal (Time Domain)')axs[0].set_xlabel('Time (ns)')axs[0].set_ylabel('Amplitude (A.U.)')axs[0].grid(True,linestyle='--',alpha=0.7)# 图2:眼图 (Eye Diagram) - 【严格对齐符号边界】L=2*SpS# 每次截取 2 个符号周期的长度,以形成完整的“眼睛”结构N=len(I_Rx)//SpS-2# 计算总共有多少个可以对齐的符号周期foriinrange(N):trace=I_Rx[i*SpS:i*SpS+L]axs[1].plot(trace,color='blue',alpha=0.05,linewidth=0.8)axs[1].set_title('Eye Diagram')axs[1].set_xlabel('Time (samples)')axs[1].set_ylabel('Amplitude (A.U.)')axs[1].grid(True,linestyle='--',alpha=0.7)# 标记最佳采样点 (眼图张开最大处,即第 1 个符号周期的末尾)axs[1].axvline(x=SpS,color='r',linestyle='--',linewidth=2,label='Optimal Sampling Point')axs[1].legend()plt.tight_layout()plt.show()