2026-05-13 16:14:42 +08:00
|
|
|
|
# RNG — 参数化随机数生成器
|
|
|
|
|
|
|
|
|
|
|
|
为 eqpalg 监控引擎提供仿真数据的测试工具。通过 JSON 配置和 DB2 表驱动,将可复用的数学模型绑定到信号项上,生成模拟量/布尔量的实时仿真数据写入共享内存,供 eqpalg-mon 消费和评估报警规则。
|
|
|
|
|
|
|
|
|
|
|
|
## 架构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
rng_models.json T_LOV_FDAAITEM (DB2)
|
|
|
|
|
|
│ │
|
|
|
|
|
|
│ 模型模板定义 │ 信号→模型绑定 (tables[1] 字段)
|
|
|
|
|
|
│ │
|
|
|
|
|
|
▼ ▼
|
|
|
|
|
|
ModelRegistry ──────── Generator ────── BinaryTele ────── CMemFix<PLC_DATA> ──► 共享内存
|
|
|
|
|
|
│
|
|
|
|
|
|
├── ConstantModel (y = c)
|
|
|
|
|
|
├── NormalModel (y = μ + σ·N(0,1))
|
|
|
|
|
|
├── LinearModel (y = k·t + b)
|
|
|
|
|
|
├── SineModel (y = A·sin(ω·t + φ) + offset)
|
|
|
|
|
|
├── UniformModel (y = random(center±delta))
|
|
|
|
|
|
├── SpikeModel (随机毛刺注入)
|
|
|
|
|
|
├── DriftModel (线性漂移)
|
|
|
|
|
|
├── CsvReplayModel (CSV 历史数据回放)
|
|
|
|
|
|
├── BoolRandomModel (概率随机布尔)
|
|
|
|
|
|
├── BoolToggleModel (固定周期翻转)
|
|
|
|
|
|
├── BoolCsvModel (CSV 布尔回放)
|
|
|
|
|
|
├── ValvePairModel (阀动作→到位传感器 时序仿真)
|
|
|
|
|
|
└── CompositeModel (base + noise 组合)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**设计原则**:模型模板与信号绑定分离。模型定义在 JSON 中,可复用;每个信号通过 DB2 的 `tables[1]` 字段选择模型,独立实例化,互不干扰。
|
|
|
|
|
|
|
|
|
|
|
|
## 编译
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd TestProject/RNG && mkdir -p build && cd build
|
|
|
|
|
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
|
|
|
|
|
make -j$(nproc)
|
|
|
|
|
|
# 可执行文件: ~/bin/RNG
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
依赖:GCC 10+, CMake 3.8+, vcpkg (nlohmann_json, mlpack, Armadillo), PACE/iPlature 框架。
|
|
|
|
|
|
|
|
|
|
|
|
## 配置
|
|
|
|
|
|
|
|
|
|
|
|
### rng_models.json
|
|
|
|
|
|
|
|
|
|
|
|
路径:`/users/dsc/code/TestProject/RNG/json/rng_models.json`
|
|
|
|
|
|
|
|
|
|
|
|
定义可复用的模型模板。每个模板有 `mode`(模型类型)和 `params`(模型参数)。信号项的 `defaultValue` 自动作为模型的基值参数。
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"models": {
|
|
|
|
|
|
"模板名称": { "mode": "模型类型", "params": { "参数名": 值 } }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### DB2 信号绑定
|
|
|
|
|
|
|
|
|
|
|
|
在 `T_LOV_FDAAITEM` 表中,`tables[1]` 字段(char[40])填写模型引用。语法:
|
|
|
|
|
|
|
|
|
|
|
|
| 格式 | 含义 | 示例 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `模型名` | 引用 JSON 中的模型模板 | `normal_tiny` |
|
|
|
|
|
|
| `csv:文件:列号` | 内联 CSV 数据回放 | `csv:spbdata:1` |
|
|
|
|
|
|
| `基模型+噪声模型` | 组合模型(叠加噪声) | `linear_slow+normal_tiny` |
|
|
|
|
|
|
| `pair模型:动作模型` | 阀到位传感器引用动作信号 | `valve_px_std:toggle_2s` |
|
2026-05-13 16:56:30 +08:00
|
|
|
|
| `!模型引用` | 布尔量取反 | `!toggle_2s` |
|
2026-05-13 16:14:42 +08:00
|
|
|
|
| 空或 `default` | 默认模型 `normal_tiny` | — |
|
|
|
|
|
|
|
|
|
|
|
|
## 模型参考
|
|
|
|
|
|
|
|
|
|
|
|
### 模拟量模型
|
|
|
|
|
|
|
|
|
|
|
|
所有模拟量模型实现 `evaluate(size_t t) -> float`,`t` 为时间索引(每 ~20ms 递增)。
|
|
|
|
|
|
|
|
|
|
|
|
#### constant — 固定值
|
|
|
|
|
|
|
|
|
|
|
|
y = c,c 取自 `defaultValue`。
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"constant_zero": { "mode": "constant", "params": {} }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### normal — 正态分布
|
|
|
|
|
|
|
|
|
|
|
|
y = μ + σ·N(0,1),μ 取自 `defaultValue`。
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| sigma | 标准差 | 0.01 |
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"normal_tiny": { "mode": "normal", "params": { "sigma": 0.01 } }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### linear — 线性变化
|
|
|
|
|
|
|
|
|
|
|
|
y = k·t + b,b 取自 `defaultValue`。
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
2026-05-13 16:34:00 +08:00
|
|
|
|
| k | 斜率(每 tick 增量) | 0.0 |
|
|
|
|
|
|
| period_ms | 周期(ms),t 按周期取模 | 0(无限) |
|
|
|
|
|
|
|
|
|
|
|
|
`period_ms > 0` 时,t = (实际 tick) % (period_ms / 20),模拟每周期重复的线性过程(如带钢卷取时张力逐渐增大然后释放)。`period_ms = 0` 时不取模。
|
2026-05-13 16:14:42 +08:00
|
|
|
|
|
|
|
|
|
|
```json
|
2026-05-13 16:34:00 +08:00
|
|
|
|
"linear_slow": { "mode": "linear", "params": { "k": 0.001, "period_ms": 600000 } }
|
2026-05-13 16:14:42 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### sine — 正弦波
|
|
|
|
|
|
|
|
|
|
|
|
y = A·sin(ω·t + φ) + offset,offset 取自 `defaultValue`。
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| A | 振幅 | 1.0 |
|
|
|
|
|
|
| omega | 角频率 | 1.0 |
|
|
|
|
|
|
| phi | 初相位 | 0.0 |
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"sine_ecc1": { "mode": "sine", "params": { "A": 5.0, "omega": 0.314, "phi": 0 } }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### uniform — 均匀随机
|
|
|
|
|
|
|
|
|
|
|
|
y = center ± delta,center 取自 `defaultValue`。
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| delta | 随机范围 | 0.01 |
|
|
|
|
|
|
|
|
|
|
|
|
#### spike — 随机毛刺
|
|
|
|
|
|
|
|
|
|
|
|
每个周期以 `probability` 概率触发一次幅值为 ±amplitude 的瞬时毛刺。
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| amplitude | 毛刺幅度 | 1.0 |
|
|
|
|
|
|
| probability | 每周期触发概率 | 0.01 |
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"spike_sharp": { "mode": "spike", "params": { "amplitude": 50, "probability": 0.05 } }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### drift — 线性漂移
|
|
|
|
|
|
|
|
|
|
|
|
y = base + drift_rate·t,base 取自 `defaultValue`。模拟传感器缓慢退化。
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
2026-05-13 16:34:00 +08:00
|
|
|
|
| drift_rate | 每 tick 漂移量 | 0.0 |
|
|
|
|
|
|
| period_ms | 周期(ms),t 按周期取模 | 0(无限) |
|
|
|
|
|
|
|
|
|
|
|
|
`period_ms > 0` 时形成锯齿波漂移:每个周期内从 base 线性漂移到 base + drift_rate·period_ticks,然后复位,模拟每个生产周期内的退化-复位行为。
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"drift_slow": { "mode": "drift", "params": { "drift_rate": 0.0001, "period_ms": 3600000 } }
|
|
|
|
|
|
```
|
2026-05-13 16:14:42 +08:00
|
|
|
|
|
|
|
|
|
|
#### csv — CSV 数据回放
|
|
|
|
|
|
|
|
|
|
|
|
从 CSV 文件读取指定列,循环回放。通常通过 `tables[1]` 内联语法使用,无需在 JSON 定义。
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"csv_example": { "mode": "csv", "params": { "file": "C308速度毛刺仿真.csv", "column": 0 } }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
CSV 文件存放路径:`/users/dsc/code/TestProject/data_files/`
|
|
|
|
|
|
|
|
|
|
|
|
### 布尔量模型
|
|
|
|
|
|
|
|
|
|
|
|
所有布尔量模型实现 `evaluateBool(size_t t) -> bool`。
|
|
|
|
|
|
|
|
|
|
|
|
#### bool_random — 概率随机
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| prob_true | 返回 true 的概率 | 0.5 |
|
|
|
|
|
|
|
|
|
|
|
|
#### bool_toggle — 固定周期翻转
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| period_ms | 翻转周期(毫秒) | 2000 |
|
|
|
|
|
|
|
|
|
|
|
|
周期前半段为 true,后半段为 false。
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"toggle_2s": { "mode": "bool_toggle", "params": { "period_ms": 2000 } }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### bool_csv — CSV 布尔回放
|
|
|
|
|
|
|
|
|
|
|
|
从 CSV 读取整数列,非零值为 true。
|
|
|
|
|
|
|
|
|
|
|
|
#### valve_pair — 阀动作→到位传感器 时序仿真
|
|
|
|
|
|
|
|
|
|
|
|
模拟液压阀/气动阀动作信号与到位接近开关之间的时序关系。使用了四态状态机:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
动作信号 A:
|
|
|
|
|
|
────────────┐ ┌────────────────
|
|
|
|
|
|
│ │
|
|
|
|
|
|
├── on_delay ──→ ├── off_delay ──→
|
|
|
|
|
|
到位传感器 B: │ ±jitter │ ±jitter
|
|
|
|
|
|
────────────┘ └────────────────
|
|
|
|
|
|
└─ 阀芯移动 ──→ └─ 阀芯复位 ──→
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 含义 | 默认值 |
|
|
|
|
|
|
|------|------|--------|
|
|
|
|
|
|
| on_delay_ms | 阀开到位延迟(ms) | 200 |
|
|
|
|
|
|
| off_delay_ms | 阀关到位延迟(ms) | 150 |
|
|
|
|
|
|
| delay_jitter_ms | 延迟抖动范围(±均匀随机) | 0 |
|
|
|
|
|
|
| flash_prob | 高电平期间每周期闪断概率 | 0 |
|
|
|
|
|
|
| delay_over_prob | 每次动作触发超时的概率 | 0 |
|
|
|
|
|
|
| delay_over_ms | 超时时的延迟值(ms) | 0 |
|
|
|
|
|
|
|
|
|
|
|
|
状态机:
|
|
|
|
|
|
- **IDLE_LOW**:等待动作信号上升沿
|
|
|
|
|
|
- **WAITING_RISE**:动作上升,计数延迟,期间冻结边沿检测
|
|
|
|
|
|
- **HIGH**:到位,监测动作下降沿或随机闪断
|
|
|
|
|
|
- **WAITING_FALL**:动作下降,计数关延迟,期间冻结边沿检测
|
|
|
|
|
|
|
|
|
|
|
|
**绑定方式**:到位传感器信号的 `tables[1]` 使用配对语法:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
tables[1] = "valve_px_std:toggle_2s"
|
|
|
|
|
|
↑ ↑
|
|
|
|
|
|
valve_pair 模板 动作信号的模型名
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
运行时通过模型名查找动作信号的 IModel 实例,每个周期读取其 `evaluateBool()` 值。
|
|
|
|
|
|
|
|
|
|
|
|
一对多支持:同一个动作信号可被多个 valve_pair 传感器跟随,各自独立维护状态机。
|
|
|
|
|
|
|
|
|
|
|
|
### 组合模型(Composite)
|
|
|
|
|
|
|
|
|
|
|
|
通过 `+` 连接两个模型名,构成 base + noise 组合:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
tables[1] = "linear_slow+normal_tiny"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`CompositeModel` 将两个模型的 `evaluate()` 结果相加。只适用于模拟量。
|
|
|
|
|
|
|
|
|
|
|
|
## 添加新模型
|
|
|
|
|
|
|
|
|
|
|
|
三步,不改现有代码逻辑:
|
|
|
|
|
|
|
|
|
|
|
|
1. **创建模型类**:在 `model/` 下新建头文件,继承 `IModel`,实现 `evaluate()` 或 `evaluateBool()`
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
struct ExponentialModel : IModel {
|
|
|
|
|
|
float lambda, base;
|
|
|
|
|
|
ExponentialModel(const json& p, float d) : lambda(p.value("lambda", 1.0f)), base(d) {}
|
|
|
|
|
|
float evaluate(size_t t) override { return base * expf(-lambda * t); }
|
|
|
|
|
|
};
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **注册到工厂**:在 `ModelRegistry.cc` 构造函数中添加一行
|
|
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
|
registerMode("exponential", [](const json& p, float d) { return std::make_unique<ExponentialModel>(p, d); });
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. **JSON 中添加模板**(可选,也可以直接用 `tables[1]` 内联语法)
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
"exp_decay": { "mode": "exponential", "params": { "lambda": 0.01 } }
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 数据流
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
PACE 定时器 (每 20ms)
|
|
|
|
|
|
│ TimeNotify(eventNo)
|
|
|
|
|
|
▼
|
|
|
|
|
|
Generator::wtite_in_shm(eventNo)
|
|
|
|
|
|
│
|
|
|
|
|
|
├─ BinaryTele.ReBuild(eventNo) ← 从 DB2 读取电文结构
|
|
|
|
|
|
│
|
|
|
|
|
|
├─ Pass 1: for each item:
|
|
|
|
|
|
│ ModelRegistry::getOrCreate(tables[1], defaultValue, item.name)
|
|
|
|
|
|
│ → 按信号 item 名创建独立模型实例
|
|
|
|
|
|
│
|
|
|
|
|
|
├─ Pass 2: for each item:
|
|
|
|
|
|
│ model->linkPeers(registry)
|
|
|
|
|
|
│ → valve_pair 模型查找动作信号实例
|
|
|
|
|
|
│
|
|
|
|
|
|
├─ Pass 3: for each item:
|
|
|
|
|
|
│ model->evaluate(t) / evaluateBool(t)
|
|
|
|
|
|
│ → 生成值写入 binary_tele[i].value
|
|
|
|
|
|
│
|
|
|
|
|
|
└─ BinaryTele.GetTeleData() → CMemFix<PLC_DATA>::push()
|
|
|
|
|
|
→ 写入共享内存环形缓冲
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
共享内存区由 `T_LOV_FDAAITEM` 的事件号区分,eqpalg-mon 按同样的事件号读取。
|
|
|
|
|
|
|
|
|
|
|
|
## 目录结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
TestProject/RNG/
|
|
|
|
|
|
├── json/
|
|
|
|
|
|
│ └── rng_models.json # 模型模板配置
|
|
|
|
|
|
├── model/
|
|
|
|
|
|
│ ├── IModel.h # 模型基类接口
|
|
|
|
|
|
│ ├── ConstantModel.h # 固定值
|
|
|
|
|
|
│ ├── NormalModel.h # 正态分布
|
|
|
|
|
|
│ ├── LinearModel.h # 线性变化
|
|
|
|
|
|
│ ├── SineModel.h # 正弦波
|
|
|
|
|
|
│ ├── UniformModel.h # 均匀随机
|
|
|
|
|
|
│ ├── SpikeModel.h # 随机毛刺
|
|
|
|
|
|
│ ├── DriftModel.h # 线性漂移
|
|
|
|
|
|
│ ├── CsvReplayModel.h # CSV 模拟量回放
|
|
|
|
|
|
│ ├── BoolRandomModel.h # 布尔随机
|
|
|
|
|
|
│ ├── BoolToggleModel.h # 布尔周期翻转
|
|
|
|
|
|
│ ├── BoolCsvModel.h # CSV 布尔回放
|
|
|
|
|
|
│ ├── ValvePairModel.h # 阀动作-到位传感器
|
|
|
|
|
|
│ ├── CompositeModel.h # 组合模型
|
|
|
|
|
|
│ ├── ModelRegistry.h # 工厂注册表(声明)
|
|
|
|
|
|
│ └── ModelRegistry.cc # 工厂注册表(实现)
|
|
|
|
|
|
├── RNG.h / RNG.cc # PACE 组件入口
|
|
|
|
|
|
├── RNG_icei.h / RNG_icei.cc # ICE 接口实现
|
|
|
|
|
|
├── Generator.h / Generator.cc # 数据生成 + 共享内存写入
|
|
|
|
|
|
├── RandT.h # 底层随机数工具
|
|
|
|
|
|
├── read_csv.hpp # CSV 文件读取
|
|
|
|
|
|
├── CMakeLists.txt # CMake 构建
|
|
|
|
|
|
└── README.md # 本文档
|
|
|
|
|
|
```
|