AnyMath 文档
Notebook

DMR协议物理层的系统模型

现代数字无线电通信系统要求数据传输具有高可靠性和高效率,尤其是在存在数据失真和失步风险的情况下。 专业移动无线电通信中使用的关键协议之一是DMR(数字移动无线电),它利用高效的调制和编码方法实现语音和数据的数字传输。

本项目探讨了DMR协议的系统模型,该模型涵盖了完整的信号处理链——从数据包生成到接收端的解调和同步。 对信号传输各阶段进行建模,有助于分析系统面对各类干扰和失真的抗干扰能力。

DMR协议与许多其他电信标准一样,采用类似于OSI(开放系统互连)模型的分层架构。DMR的主要层可划分为以下几类。

  1. 物理层(Physical Layer,PHY)。负责通过无线电信道传输和接收比特流,包括调制(4-FSK、FM)、 滤波、同步以及信道失真校正(编码也属于物理层,但在本例中不予讨论)。

  2. 数据链路层(Data Link Layer, DLL)。确保节点间数据的可靠传输,管理信道访问。包括DMR数据包的形成,例如语音和信令数据。 本例中展示了数据包。此外,该层还可包含错误控制(CRC、FEC)、逻辑信道管理(TDMA、两个时隙)以及寻址(用户和组的识别)。

  3. 网络层(Network Layer)。当DMR集成到包含互联网的更大系统中时,该层负责路由和网间交互。

  4. 在某些实现中还存在额外层:传输层(如果 DMR 基于 IP 运行)或例如应用层(Application Layer)——支持各项服务(语音、文本消息、遥测)。

DMR 标准主要关注物理层和信道层,因为正是这两个层决定了无线电信道的运行。网络功能通常在基础设施解决方案中实现(例如,在中继器和管理系统中)。

连接辅助功能以启动模型

In [ ]:
function run_model( name_model)
    
    Path = (@__DIR__) * "/" * name_model * ".engee"
    
    if name_model in [m.name for m in engee.get_all_models()] # 检查模型加载到内核的条件
        model = engee.open( name_model ) # 打开模型
        model_output = engee.run( model, verbose=true ); # 运行模型
    else
        model = engee.load( Path, force=true ) # 加载模型
        model_output = engee.run( model, verbose=true ); # 运行模型
        engee.close( name_model, force=true ); # 关闭模型
    end
    sleep(5)
    return model_output
end
Out[0]:
run_model (generic function with 1 method)

启动模型并分析结果

我们实现的模型包含以下关键模块。

  1. 数据包生成——生成与 DMR 数据包类型相对应的信号序列和空帧。

  2. 4-FSK调制——DMR中用于有效利用频带的数字调制方式。

  3. 升余弦滤波器——用于限制信号频谱并最大限度地减少符号间干扰。

  4. FM调制器——将数字信号转换为模拟信号,以便通过无线电信道进行传输。

  5. 模拟失步通信信道——模拟发射机与接收机之间的时序失步。
    image_3.png

  6. 信号序列检测与帧同步——用于在接收端恢复数据包时间位置的算法。
    image_5.png

为了测试俄语和英语消息的正确传输,我们将使用这两种语言的全字母句。

全字母句(源自希腊语,意为“所有字母”),或称全字母组合,是指使用字母表中所有或几乎所有字母、且尽可能不重复的短文本。

我们定义这样一条消息,并在模型中将其表示为字节形式以便于与信号交互,同时在消息末尾补零,使其元素数量为27的倍数(一个DMR数据包中包含216位数据)。 模型中的一部分代码如下所示。

In [ ]:
En = "Red fox jumps over the lazy dog"
Ru = "再吃点这些松软的法式面包,再喝点茶吧"
inp_sms = "$En. $Ru."
println("输入消息:")
println(inp_sms)
println()
bytes = Int.(Vector{UInt8}(inp_sms))
remainder = length(bytes) % 27
bytes = vcat(bytes, remainder == 0 ? Int[] : zeros(Int, 27 - remainder))
println("字节表示法:")
println(bytes)
println()
println("消息的帧数:$(length(bytes)/27)")
输入消息:
红狐狸跳过了那只懒洋洋的狗。再吃点这些松软的法式面包,再喝杯茶吧。

字节表示法:
[82, 101, 100, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103, 46, 32, 67, 209, 138, 208, 181, 209, 136, 209, 140, 32, 208, 182, 208, 181, 32, 208, 181, 209, 137, 209, 145, 32, 209, 141, 209, 130, 208, 184, 209, 133, 32, 208, 188, 209, 143, 208, 179, 208, 186, 208, 184, 209, 133, 32, 209, 132, 209, 128, 208, 176, 208, 189, 209, 134, 209, 131, 208, 183, 209, 129, 208, 186, 208, 184, 209, 133, 32, 208, 177, 209, 131, 208, 187, 208, 190, 208, 186, 44, 32, 208, 180, 208, 176, 32, 208, 178, 209, 139, 208, 191, 208, 181, 208, 185, 32, 209, 135, 208, 176, 209, 142, 46]

该消息的帧数:5.0

下图展示了已实现的完整模型。

image.png

让我们在 SNR = 25 的条件下运行该模型,以观察错误最少的结果。 如果您对系统的抗噪能力感兴趣,可以自行调整该参数进行实验。

In [ ]:
snr = 25
run_model("DMR") # 启动模型。
Out[0]:
SimulationResult(
    "err_symbol" => WorkspaceArray{Vector{Int64}}("DMR/err_symbol")
,
    "Frame_Synchronization.Delay" => WorkspaceArray{Float64}("DMR/Frame_Synchronization.Delay")
,
    "Inp" => WorkspaceArray{Vector{Int64}}("DMR/Inp")
,
    "Out" => WorkspaceArray{Vector{UInt32}}("DMR/Out")

)

接下来对结果进行分析。首先,我们展示输入和输出文本消息的字节表示,以及按字节统计的错误数量。

In [ ]:
println("SNR: $snr")
error_bytes = reduce(vcat,collect(simout["DMR/err_symbol"]).value)
println("错误数量:$(sum(error_bytes.>0))")
Delay = reduce(vcat,collect(simout["DMR/Frame_Synchronization.Delay"]).value)
println("位延迟:$(Int.(Delay[end]))")

Input = reduce(vcat,collect(simout["DMR/Inp"]).value)
plot(Input, seriestype = :steppre,  label = "Input")
Output = reduce(vcat,collect(simout["DMR/Out"]).value)
plot!(Output, seriestype = :steppre,  label = "Output")
SNR: 25
错误数量:0
位延迟:20
Out[0]:

如我们所见,当 SNR = 25 时未观察到错误,因此我们可以无误地解码文本消息。

In [ ]:
SMS_sim = reduce(vcat, collect(SMS_out).value)
SMS = filter(x -> x != 0x00000000, SMS_sim)
SMS = String(UInt8.(SMS))
println("恢复后的字符串: ", SMS)  # 多余的零将被忽略
还原后的句子:Red fox jumps over the lazy dog. 再吃点这些松软的法式面包,喝杯茶吧。

结论

本例分析了DMR系统模型,仅涉及协议的物理层。今后,如果社区对该主题感兴趣,我们将探讨该协议的其他层,并展示其各个组成部分的实现。