Skip to content

🌊 郊狼脉冲波形(概念、示例与转换)

📐 核心概念:频率与周期

在郊狼协议中,时间的基本单位为 ms (毫秒)波形频率本质上是指一个完整脉冲周期的时长(Period)。

T (ms)=1000f (Hz) T \text{ (ms)} = \frac{1000}{f \text{ (Hz)}}

常见频率对照表

脉冲频率 (Hz)波形周期/频率 (ms)听感/体感描述
1 Hz1000 ms极慢的跳动
5 Hz200 ms慢速节拍
10 Hz100 ms快速敲击 (啪啪啪)
50 Hz20 ms粗糙震动 (突突突)
100 Hz10 ms细腻震动 (嗡嗡嗡)

代系差异

  • V2 协议 组合决定:由 X (脉冲时长) + Y (间隔时长) 共同决定。

    例:[1, 9] = 1ms脉冲 + 9ms间隔 = 10ms周期 (100Hz)。

  • V3 协议 直接指定:直接输入波形周期的数值。脉冲与间隔的比例由 频率平衡参数 自动控制。

📉 V3 频率压缩算法

V3 协议为了节省数据带宽并优化高频段的控制精度,将 10ms ~ 1000ms 的物理时间映射到了 10 ~ 240 的字节值。

压缩逻辑

人体对低频(如 10Hz vs 11Hz)敏感,对高频(如 500Hz vs 550Hz)不敏感。因此采用分段线性压缩:

🖱️ 点击查看 Kotlin 算法实现
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 ms100 Hz10
20 ms50 Hz20
50 ms20 Hz50
100 ms10 Hz100
110 ms~9 Hz102
150 ms~6.6 Hz110
650 ms~1.5 Hz204
750 ms~1.3 Hz215

线性渐变示例

若希望在 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

转换公式

V3 StrengthV2 Z-Value×5 \text{V3 Strength} \approx \text{V2 Z-Value} \times 5

例:V2 中 Z=20 (强刺痛),对应 V3 中强度 100。

⏱️ 输出窗口与时序

设备并非实时响应每一个微秒的变化,而是基于时间窗口来处理数据。

  • V2 机制:窗口为 100ms。每收到一个指令,重复执行该指令定义的波形 100ms。
  • V3 机制:窗口逻辑上仍为 100ms,但内部细分为 4 个 25ms 的槽位
    • 每次 B0 指令携带 4 组频率/强度数据。
    • 设备会依次播放这 4 组数据,每组持续 25ms。

⚠️ 长周期波形的断裂风险

如果设定的波形频率值 > 输出窗口(例如设定 500ms 的波形周期,但窗口只有 100ms): 下一条指令到达时,上一条指令的波形周期可能尚未走完。设备内部会进行重排,这可能导致实际输出的波形相位与预期不完全一致,但在体感上通常难以察觉。 建议:若需稳定输出低频波形,请保持连续发送相同的波形频率值。

🔄 附录:V2 到 V3 迁移指南

如果您正在升级旧代码,请遵循以下逻辑:

  1. 计算总周期

    Ttotal=V2X+V2Y T_{total} = V2_X + V2_Y

  2. 转换频率: 将 TtotalT_{total} 代入 V3 频率压缩算法 获得输入字节。
  3. 转换强度

    StrengthV3=V2Z×5 Strength_{V3} = V2_Z \times 5

  4. 填充数据: 将转换后的数据重复 4 次填入 V3 的 B0 指令槽位,以模拟 V2 的 100ms 持续输出效果。