diff --git a/docs/micromate_protocol_reference.md b/docs/micromate_protocol_reference.md index ad2020b..d93d0ba 100644 --- a/docs/micromate_protocol_reference.md +++ b/docs/micromate_protocol_reference.md @@ -1811,7 +1811,55 @@ given it, and `/db/import/idf_file` needs no change at all. must carry it out of the chain walk. Losing it means losing the ability to name the file correctly. -### ⚠ Unresolved: the `0x0C` peak float +### ✅ RESOLVED 2026-09-30: the `0x0C` float is the PER-SAMPLE peak vector sum + +**`0x0C` content[`Tran` label − 12], float32 BE, = the peak vector sum computed +sample by sample.** Exact to 0.000% on all four bench waveforms, against a PVS +recomputed from the decoded samples: + +| key | `0x0C` float | per-sample PVS | err | `sqrt(Σpeak²)` | `max(T,V,L)` | +|---|---|---|---|---|---| +| `…82` | 1.37198 | 1.37198 | **+0.000%** | 1.41746 | 1.37063 | +| `…83` | 2.35414 | 2.35414 | **+0.000%** | 2.37824 | 2.22274 | +| `…84` | 3.51515 | 3.51515 | **−0.000%** | 3.78731 | 3.44194 | +| `…85` | 0.42267 | 0.42267 | **−0.000%** | 0.46678 | 0.41985 | + +> #### ⚠ Retraction — why this looked unresolved +> +> The previous entry (below, kept) observed the float running 2–5% above +> `max(T,V,L)` and concluded it was **not** the peak vector sum, because +> "computed PVS runs *higher* than both". +> +> That computed PVS was `sqrt(T² + V² + L²)` **from the three reported channel +> peaks** — and that is an *upper bound* on the real thing, not the real thing. +> The channel maxima do not occur at the same instant, so combining them +> overstates the true peak. Every measurement in the old table is consistent +> with the correct answer: `max(T,V,L) ≤ stored ≤ sqrt(Σpeak²)`, in all five rows. +> +> A near-miss worth recording: on UM20147's event the stored float matched +> `sqrt(Σpeak²)` to **0.048%**, which briefly looked like proof it *was* that +> quantity. It is not — the peaks on that event simply happen to be nearly +> coincident in time. **One sample agreeing with a formula is not evidence when +> a second formula fits it equally well;** the six CB events separated them +> immediately (errors to −9.5%). + +**The offset is now established, not inferred** — four independent confirmations +at 0.000%, plus a fifth on the other firmware line. + +**Why this is worth having: it is a free self-check on the decoder.** The device +computed this number from the same samples we decode, independently of our +codec. If a decoded event's per-sample PVS does not match the stored float, the +decode is wrong. Given this codebase's history of *silent* channel truncation — +walker bugs that shorten a channel and raise nothing — a per-event invariant +that costs one float comparison is cheap insurance. Worth wiring into the +download path. + +⚠ It remains true that `max(T,V,L)` and `sqrt(Σpeak²)` are **not** +interchangeable with it, so a consumer wanting the vector sum must use this +field or decode the samples — it cannot be reconstructed from the three +per-channel peaks. + +#### Superseded: the original "unresolved" entry The float32 extracted from `0x0C` runs 2–5% above `max(Tran, Vert, Long)` from the decoded samples: @@ -1824,15 +1872,38 @@ the decoded samples: | `…84` | 3.5152 | 3.4419 | | `…85` | 0.4227 | 0.4198 | -It is not peak vector sum either (computed PVS runs *higher* than both). The +~~It is not peak vector sum either (computed PVS runs *higher* than both). The field may not be the peak at all — its offset was inferred from a byte marker, -not established. **Do not rely on it** until it is pinned properly. +not established. **Do not rely on it** until it is pinned properly.~~ Worth noting the histogram (`…81`) and the loudest waveform (`…84`) report *identical* peaks to four decimals, in both measures. That is self-consistent: the histogram's single 1-minute interval spans the whole thumping session, so its maximum should equal the loudest event in it. +### `0x0C` field map, from UM20147 (11.0BD, 2026-09-30) + +Real bytes, 221 B response → 210 B content declared at `data[0] = 0xd2`: + +``` +content[ 0] day 0x1e = 30 +content[ 1] month 0x09 +content[ 2:4] year BE 0x07ea = 2026 +content[ 4] ⚠ 0xb3 = 179 — unidentified, same slot as 0x1C's content[6] +content[ 5:8] h:m:s 13:27:33 +content[11] RECORD TYPE 0x08 histogram / 0x07 waveform +content[12] "Location\0" sensor-location label +content[34] "test2\0" the setup file name, without its extension +content[76] "UM20147\0" serial +content[86] float32 BE the per-sample PEAK VECTOR SUM (= Tran − 12) +content[98] "Tran\0\0" + float32 BE at +6 +content[112] "Vert" … content[126] "Long" … content[140] "Mic" … +``` + +⚠ The setup name here is `test2` — no extension — where `0x41` reported +`test2.MMB` and `0x40` reported `test2.mmb` in the same session. Three commands, +three spellings of one file. See *Setup-name case*. + ## Event download, per-event delete, and ACH config (2026-09-25) Three captures with operator-supplied ground truth, including Thor screenshots of