Engee 文档
Notebook

DMR协议物理层的系统模型

现代数字无线电通信系统要求数据传输的高可靠性和效率,特别是如果存在数据失真和去同步的风险。 专业移动无线电通信中使用的关键协议之一是DMR(数字移动无线电),它使用高效的调制和编码技术提供数字语音和数据传输。

本项目考察DMR协议系统模型,其中包括完整的信号处理链,从数据包生成到接收侧的解调和同步。 对信号传输的每个阶段进行建模,可以分析系统对各种类型干扰和失真的抵抗力。

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

  1. 物理层(PHY)。 它负责通过无线信道发送和接收比特流,并在信道中包括调制(4-FSK,FM),滤波,同步和失真校正(编码也属于物理层,但我们在这个例子中不考虑它)。

  2. 数据链路层(DLL)。 在节点之间提供可靠的数据传输,管理对环境的访问。 它包括DMR数据包的生成,例如语音和信号数据。 此示例演示数据包。 它还可以包括错误控制(CRC,FEC),逻辑信道管理(TDMA,两个时隙),寻址(订户和组的识别)。

  3. 网络层。 提供路由和网络间通信,如果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](附件:image_3.png)

  6. 信号序列检测和帧同步-用于恢复接收侧数据包的临时位置的算法。
    image_5.png

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

一个pangram(来自希腊语—"所有字母"),或多字母,是一个短文本,使用字母表中的所有或几乎所有字母,如果可能的话,不重复它们。

我们将设置这样的消息,并且在模型中,我们将以字节形式表示它,以便于与信号交互,并将消息补充为向量中元素数量的零,即27的倍数(一个DMR数据包中的216 模型中的部分代码如下所示。

In [ ]:
En = "Red fox jumps over the lazy dog"
Ru = "Cъешь же ещё этих мягких французских булок, да выпей чаю"
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)")
Входное сообщение:
Red fox jumps over the lazy dog. Cъешь же ещё этих мягких французских булок, да выпей чаю.

Байтовое представление:
[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. Cъешь же ещё этих мягких французских булок, да выпей чаю.

结论

在此示例中,分析DMR系统模型,仅影响物理协议层。 将来,如果社区对该主题感兴趣,我们将研究该协议的其他级别,并介绍其各个组成部分的实现。