🌊 郊狼脉冲波形(概念、示例与转换)
📐 核心概念:频率与周期
在郊狼协议中,时间的基本单位为 ms (毫秒)。 波形频率本质上是指一个完整脉冲周期的时长(Period)。
常见频率对照表
| 脉冲频率 (Hz) | 波形周期/频率 (ms) | 听感/体感描述 |
|---|---|---|
| 1 Hz | 1000 ms | 极慢的跳动 |
| 5 Hz | 200 ms | 慢速节拍 |
| 10 Hz | 100 ms | 快速敲击 (啪啪啪) |
| 50 Hz | 20 ms | 粗糙震动 (突突突) |
| 100 Hz | 10 ms | 细腻震动 (嗡嗡嗡) |
代系差异
- V2 协议 组合决定:由
X(脉冲时长) +Y(间隔时长) 共同决定。例:
[1, 9]= 1ms脉冲 + 9ms间隔 = 10ms周期 (100Hz)。 - V3 协议 直接指定:直接输入波形周期的数值。脉冲与间隔的比例由 频率平衡参数 自动控制。
📉 V3 频率压缩算法
V3 协议为了节省数据带宽并优化高频段的控制精度,将 10ms ~ 1000ms 的物理时间映射到了 10 ~ 240 的字节值。
压缩逻辑
人体对低频(如 10Hz vs 11Hz)敏感,对高频(如 500Hz vs 550Hz)不敏感。因此采用分段线性压缩:
🖱️ 点击查看 Kotlin 算法实现
fun mapMsToByte(ms: Int): Int {
return when (ms) {
in 10..100 -> ms // 低频区:1:1 映射
in 101..600 -> (ms - 100) / 5 + 100 // 中频区:1:5 压缩
in 601..1000 -> (ms - 600) / 10 + 200 // 高频区:1:10 压缩
else -> 10 // 越界保护
}
}常用数值速查表
| 物理波形周期 (ms) | 对应频率 (Hz) | V3 协议输入值 |
|---|---|---|
| 10 ms | 100 Hz | 10 |
| 20 ms | 50 Hz | 20 |
| 50 ms | 20 Hz | 50 |
| 100 ms | 10 Hz | 100 |
| 110 ms | ~9 Hz | 102 |
| 150 ms | ~6.6 Hz | 110 |
| 650 ms | ~1.5 Hz | 204 |
| 750 ms | ~1.3 Hz | 215 |
线性渐变示例
若希望在 App 中实现平滑的频率变化,建议按照以下序列发送数据(每 100ms 发送一组):
1. 频率下降 (100Hz -> 10Hz)
目标:波形周期从 10ms 变到 100ms。 输入序列:10, 20, 30, 40, 50, 60, 70, 80, 90, 100
2. 频率下降 (10Hz -> 1Hz)
目标:波形周期从 100ms 变到 1000ms。 转换前 (ms):100, 120, 140, 160, 180, 200, 210, 220, 230, 240 (非线性分布) 输入序列:100, 104, 108, 112, 116, 120, 142, 164, 186, 240 (需根据公式计算)
提示
V3 每条指令包含 4 个波形数据。若要生成平滑渐变,可将计算出的序列填入这 4 个位置。不足 4 个时补 0。
⚡ 波形强度(脉宽)
波形强度本质是控制单次脉冲的宽度。脉冲越宽,能量越大,刺痛感越强。
- V2 Z 值:范围
0 ~ 31(通常用到 20)。 - V3 波形强度:范围
0 ~ 100。
转换公式
例:V2 中 Z=20 (强刺痛),对应 V3 中强度 100。
⏱️ 输出窗口与时序
设备并非实时响应每一个微秒的变化,而是基于时间窗口来处理数据。
- V2 机制:窗口为 100ms。每收到一个指令,重复执行该指令定义的波形 100ms。
- V3 机制:窗口逻辑上仍为 100ms,但内部细分为 4 个 25ms 的槽位。
- 每次 B0 指令携带 4 组频率/强度数据。
- 设备会依次播放这 4 组数据,每组持续 25ms。
⚠️ 长周期波形的断裂风险
如果设定的波形频率值 > 输出窗口(例如设定 500ms 的波形周期,但窗口只有 100ms): 下一条指令到达时,上一条指令的波形周期可能尚未走完。设备内部会进行重排,这可能导致实际输出的波形相位与预期不完全一致,但在体感上通常难以察觉。 建议:若需稳定输出低频波形,请保持连续发送相同的波形频率值。
🔄 附录:V2 到 V3 迁移指南
如果您正在升级旧代码,请遵循以下逻辑:
- 计算总周期:
- 转换频率: 将 代入 V3 频率压缩算法 获得输入字节。
- 转换强度:
- 填充数据: 将转换后的数据重复 4 次填入 V3 的 B0 指令槽位,以模拟 V2 的 100ms 持续输出效果。