Files
VesiscanClinicalAndroid/app/src/main/java
dw.jang 08f5a182df feat(hospital): 병원 임상·정렬에 IMU 를 남긴다 — 600/601 sensor.imu
병원 경로는 `mtb?` 를 보내면서 **piezo 콜백만** 걸고 있었다. 응답에 딸려 오는
`rim:`(IMU)은 받는 곳이 없어 그대로 버려졌고, 저장된 측정에 IMU 가 하나도 없었다.
labdb 600/601 의 `sensor` 가 "항상 빈 객체"였던 이유다.

## 왜 필요한가
자세는 조작자가 고르는 실험 조건이라 판정에는 안 쓴다. 필요한 것은 다른 것이다 —
같은 조건 20회 반복에서 **어떤 회차만 값이 튈 때**, 알고리즘 문제인지 환자가 그 순간
움직인 것인지 가를 근거가 없었다. 정렬도 사람이 프로브를 옮겨 가며 재는 과정이라,
특정 위치의 파형이 이상할 때 자리 탓인지 흔들림 탓인지 알 수 없었다.

## 수집 — ImuSidecar
세 루프가 같은 패턴이라 헬퍼로 뺐다. 저장이 있는 두 곳에만 붙인다:
  · HospitalModeView  (600 · 20회 반복)
  · AnchorAlignView   (601 · 0~4cm 탐색 + 확인)
좌우 정렬 루프는 화면 안내용 스트리밍이라 저장이 없어 건드리지 않았다.

응답 순서가 `reb×6 → raa → rim` 이라 IMU 가 나중에 온다. piezo 를 받은 뒤 0.7초
기다리고, 안 오면 비운다. **IMU 가 없다고 측정을 실패로 돌리지 않는다** — 펌웨어·설정에
따라 `rim:` 이 없을 수 있고, 그때 실패로 만들면 기존에 되던 일이 안 되게 된다.

## 저장 — 형제 CSV
파형 행(meta + s0..s99)을 넓히지 않았다. 그 헤더는 이미 올라간 데이터와 파서가 함께
쓰는 규약이고, IMU 는 채널당이 아니라 **회차당** 값이라 같은 행에 넣으면 6 채널 행에
같은 IMU 를 여섯 번 복사하게 된다.

  600  <측정파일>_imu.csv              scan_id 로 파형과 잇는다
  601  align_{n}cm_imu.csv
       align_{n}cm_confirm_imu.csv     파형과 같은 confirm 분리 규칙

601 에서 confirm 을 따로 두는 이유는 파형과 같다 — 확인 측정의 IMU 가 판정에 쓰인
탐색 측정 것을 덮으면 안 된다.

## 업로드 — sensor.imu (600·601 같은 모양)
  "sensor": { "imu": [ {ax,ay,az,gx,gy,gz}, … ] }
  ax/ay/az = g · gx/gy/gz = dps

⚠ **없으면 빈 객체다. 0 으로 채우면 안 된다.** 부재가 곧 "그때는 안 쟀다" 이고,
0 으로 채우면 "무중력·완전 정지"로 정반대로 읽힌다. 이전 업로드분 전부가 여기 해당한다.

## 문서
LABDB_DATATYPES.md 의 "sensor 는 항상 빈 객체" 기술을 고치고 IMU 절을 새로 썼다.
labdb 쪽에 필요한 일(저장·뷰어 표시·없음/0 구분·마이그레이션 불필요)과 파생값
(accel_mag·gyro_mag) 계산식을 함께 적었다. 프로토콜 이름과 기존 필드는 그대로라
추가 키뿐이며 기존 파서를 깨지 않는다.

테스트 3건 추가(IMU 유/무 · cycle 분리 · confirm 이 sweep 을 덮지 않음).
601 15건 · 600 11건 전부 통과.

⚠ 실기기 미검증 — 병원 설정(2.3MHz·c3)에서도 `rim:` 이 오는지는 프로브로 확인해야 한다.
  파싱 자체는 dev 임상에서 쓰던 같은 수집기다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 17:08:26 +09:00
..