🐯 룸핏 앱 — 화면·모듈·파이프라인 연결도

어떤 화면에 어떤 모듈이, 어떤 데이터 흐름으로 연결되는지 — APP feat/spoex-v3 @ a6d67c6d / FW 2.0.0-dev.1

FW (MCU)
BLE 통신
기기 상태
VBT 엔진
VBT 공통
SPOEX
리모컨
화면 (UI)

📡 데이터 수신 파이프라인 (FW → 앱 → 화면)

MCU ISR10kHz FOC
BLE TX50ms 주기
FlutterBluePlusNordic UART
BleBufferService패킷 조립
ResponseFactoryv3/Dev 자동판별
DeviceStateServiceRx 변수 갱신
posL/R, spdL/R, forceL/R

▸ v3 Report (17B): pos, force만  |  Dev Report (41B): + spd, acc, Icmd, Ifb, fLoad, mode, region, weightSet

🏋️ VBT 분석 파이프라인 (DeviceStateService → 렙 피드백)

DeviceStateServiceposL/R, spdL/R
BleVbtSource50ms Timer 샘플링
VbtRawSample 생성
VbtPipelineButterworth LPF
FW Speed 우선 사용
TurningPointV3극점 감지
StreamingRepDetector렙 세그먼테이션
1-rep 버퍼
FeedbackServiceRepFeedback
SetReport
SessionReport
VbtWorkoutViewModel풀체인 조립
posHistory, velHistory
repSampleIndices
← listen ←
DataSource.samplesStream<VbtRawSample>
|
→ pipeline.ingest()pos, fwSpeedMmS
|
→ detector.onSample()pos, vel, force
|
→ UI notifyListeners()

📤 명령 전송 파이프라인 (화면 → FW)

화면 UI버튼/슬라이더
SpoexBleCommands명령 래퍼
BluetoothControllerwriteCharacteristic
Nordic UART TX패킷 전송
FW protocol.cProtocol_Receive
ACK 응답DeviceStateService
Rx 변수 갱신
명령코드파라미터ACK
MODE_CHANGE-0~5 (모드ID)WeightModeResponse
SET_WEIGHT-0.5kg 단위 (max 59kg)WeightResponse
WEIGHT_ON/OFF-boolOnOffResponse (점진 완료 후)
SET_RANGE0x62LOW/HIGHSetRangeResponse
ECC_LEVEL-kg (Negative 모드)EccLevelResponse
0xF5 0x05debugparamId + value (모드별)없음
0xF5 0x20/21debugDev Report ON/OFF없음

🔨 묠니르 (Mjolnir) — 1RM 이벤트

⚙️ M0 — 묠니르 세팅 spoex/mjolnir/mjolnir_setup_screen.dart
MjolnirController SpoexBleCommands DeviceStateService MjolnirSettings
줄 선택L / R / Both
MjolnirControllerautoSetup()
SpoexBleCommandsMODE_CHANGE(2=Band)
adjustWeightTo(59kg)
START_REPORT
DeviceStateServicepositionL 수신 시작
저점 등록 UI현재위치 표시
데이터 소스
DeviceStateService.positionL/R
BLE Report 50ms 주기
BLE 명령 순서
MODE→WEIGHT→REPORT→RANGE
각 200ms 간격
저장
SharedPreferences (줄 선택)
MjolnirSettings.saveSide()
🎯 M1 — 캘리브레이션 spoex/mjolnir/mjolnir_calibration_screen.dart
MjolnirController DeviceStateService
DeviceStateServicepositionL (실시간)
안정 감지position 변화 < threshold
고점 자동 등록SpoexBleCommands
.sendSetRangeHigh()
🏋️ M3 — 묠니르 운동 spoex/mjolnir/mjolnir_workout_screen.dart
MjolnirController MjolnirSession DeviceStateService AutoPhotoService
DeviceStateServicepositionL (실시간)
MjolnirSessionmaxPosition 추적
start/end 시간
위치 게이지 UI현재 vs 최대
자동종료 감지하강 시 30%/10초
SpoexBleCommandsmjolnirEnd()
M4 결과 화면
🏆 M4 — 결과 + QR spoex/mjolnir/mjolnir_result_screen.dart
MjolnirSession SpoexStorage
MjolnirSessionmaxPosition
duration
SpoexStorageSupabase 업로드
sid=mj_xxxxx
QR 코드리더보드 웹 링크

🏋️ AI-VBT 체험

🔧 V2 — 머신 세팅 (6종 모드) spoex/vbt/vbt_machine_setup_screen.dart
SpoexBleCommands WeightModePresets DeviceStateService
모드 탭 선택6종: Const/Neg/Band
Iso/Hydro/Vib
파라미터 입력무게 ±0.5/±5
슬라이더/보조
SpoexBleCommands① sendModeChange(n)
② adjustWeightTo(kg)
③ sendIso/Hydro/VibPreset
④ sendSlewRate
⑤ sendAutoWeight
FW 적용WeightController
case 0~5 분기
모드메인 파라미터BLE 명령보조 (접힘)
0 Constant무게 (kg)adjustWeightToSlewRate
1 Negative기본부하 + 이완부하adjustWeightTo + sendEccLevelSlewRate
2 Band최대부하adjustWeightToSlewRate
3 Isokinetic목표속도 + 상한클램프sendIsoPreset(Vt, Kp, Ki)Kp, Ki, SlewRate
4 Hydraulic강도(kg) + 개형(N)sendHydroPreset(Vmax, N, minR)Vmax, MinRatio, SlewRate
5 Vibration주파수(Hz) + 진폭(kg)sendVibPreset(freq, amp, maxR)MaxRatio, SlewRate
📊 V4 — VBT 운동 (실시간) spoex/vbt/vbt_workout_screen.dart
VbtWorkoutViewModel BleVbtSource VbtPipeline StreamingRepDetector VbtFeedbackService SpoexBleCommands DeviceStateService
initState()Dev Report ON
0xF5 0x20
DeviceStateServiceposL/R + spdL/R
(Dev Report 41B)
BleVbtSource50ms Timer
VbtRawSample{pos, speed}
VbtWorkoutViewModel_onSample()
_onSample()
pipeline.ingest()pos + fwSpeedMmS
(FW 우선, null=미분)
detector.onSample()pos, vel, force
feedbackServiceRepFeedback stream
UI 업데이트렙카운트, 속도바
포지션차트, 수직선
피드백 메시지
렙 카운터
vm.currentRepCount
_currentReps.length
속도 바
vm.velLHistory / velRHistory
FW Speed 우선, mm/s
포지션 차트
vm.posLHistory / posRHistory
_PolylinePainter (CustomPaint)
렙 수직선
vm.repSampleIndices
탭 토글 ON/OFF
피드백
latestRep.messages
RepFeedback → messageSimple
카메라
_showCamera (토글)
위젯 연결 TODO
📋 V5 — 세트 리포트 spoex/vbt/vbt_set_report_screen.dart
VbtWorkoutViewModel VbtFeedbackService
feedbackServicegenerateSetReport()
SetReportavgVel, peakVel
totalReps, vLoss
repDetails[]
리포트 카드속도/파워/피로도 표시
🎛️ 기본 리모컨 remote/remote_workout_screen.dart
RemoteWorkoutController RemoteWorkoutDeviceController RemoteWorkoutDeviceStateController DeviceStateService MotionAnalysisService
DeviceStateServicemotionTime → Worker trigger
MotionAnalysisServiceposition → velocity → force
(레거시 v1 엔진)
LineChartComponent위치+Iq 실시간 차트
±0.5 / ±5 버튼
RemoteWorkoutControllerweightPlus/Minus
weightPlusFive/MinusFive
DeviceCommandControllerWEIGHT_ADJUST
BLE TX
3분할 레이아웃
Chart : Config : Control = 3:2:4
모드 변경
바텀시트 → DeviceController
6종 모드 분기 (수정 완료)
가동범위
SET_RANGE LOW/HIGH
무게 OFF 상태에서만
🔬 DEV 리모컨 (고급 디버깅) remote/remote_dev_screen.dart
RemoteWorkoutController VbtEngine SpoexBleCommands WeightModePresets DeviceStateService
initState()Dev Report ON
DeviceStateService모든 Dev Report 필드
pos/spd/acc/Icmd/Ifb/fLoad/mode/region
인디케이터 행FW모드, L/R spd, L/R force
DeviceStateServicepositionL/R
VbtEngineingest(pos, Side)
렙 감지세트모드 증가/드롭 연동
SpoexBleCommandsadjustWeightTo
(자동 무게 증감)
모드 6칩Const/Neg/Band
Iso/Hydro/Vib
모드별 슬라이더프리셋 버튼 포함
적용 버튼sendModeChange
+ sendXxxPreset
+ sendSlewRate/IqLimit
FW 반영
차트 채널 토글
Pos / Spd / Acc / Icmd / Ifb / FLoad
UI만 완성, 데이터 주입 TODO
세트 모드
증가 / 드롭
VbtEngine 렙 감지 → N렙마다 무게 자동 변경
FW 버전 표시
AppBar 좌: FW 2.0.0-dev.1
AppBar 우: APP commit hash
가동범위
다이얼로그 (저점/고점/ROM)
실시간 position + ACK 결과 표시

핵심 인프라 모듈

📡 bluetooth/ — BLE 통신 계층
FlutterBluePlusBLE 스캔/연결
BluetoothController연결 관리
writeCharacteristic
BleBufferServiceFF FF + size 파싱
체크섬 검증
ResponseFactorycmd코드 → Response 객체
패킷 길이로 v3/Dev 판별
Commands (앱→FW)
22개
weight, mode, range, report, debug 등
Responses (FW→앱)
16개
report, onoff, weight_mode, firmware_ver 등
패킷 형식
[FF FF] [size] [cmd] [data...] [checksum]
📟 device/ — 기기 상태 + 명령
ResponseFactory
DeviceStateServiceGetX 전역 서비스
Rx<double> posL/R, forceL/R
Rx<double> speedL/R
Rx<int> motionTime, weightMode
← 읽기 ←
모든 화면
모든 화면
DeviceCommandControllersetBothWeightMode()
setConstantMode/Iso/Hydro/Vib
executeBluetoothCommand()
BluetoothController

단일 진실 소스 — 모든 화면은 DeviceStateService를 통해 기기 상태를 읽음. BLE 응답을 직접 파싱하지 않음.

🧠 vbt_engine/ — VBT 분석 엔진 (순수 Dart)
VbtPipelineButterworth LPF 3Hz
fwSpeed 우선 사용
TurningPointDetectorV3극점 감지
stationaryTol 0.5mm
StreamingRepDetector렙 세그먼테이션
hybrid clustering
적응형 ROM 필터
VbtFeedbackServiceRepFeedback
SetReport
SessionReport
테스트
34개 유닛테스트
BLE/Sim 무관 동일 동작
Flutter 의존
없음 (순수 Dart)
단위 테스트 가능
Force 추정
F = F_motor + m × a
FLoad(FW) or loadKg(앱)
🔌 vbt_common/ — VBT 공통 (DataSource + ViewModel)
DataSource용도FW Speed사용처
BleVbtSource실기기 BLE✅ DeviceStateService.speedL/RVBT 체험, 묠니르
SimVbtSourcesine파 시뮬❌ 미분 fallbackVBT 시뮬레이터
TouchVbtSource터치 드래그터치 시뮬 위젯
RandomVbtSource랜덤 패턴자동 데모
VbtWorkoutViewModelChangeNotifier
DataSource → Pipeline → Detector → Feedback 조립
VBT 화면들V4 운동, V5 리포트
DEV 리모컨
🎪 spoex/ — SPOEX 전시 전용
SpoexBleCommands
FW 명령 래퍼 (단일 진입점)
sendModeChange, adjustWeightTo, sendIso/Hydro/VibPreset, devReportOn/Off
WeightModePresets
6모드 정의 + 프리셋
Iso/Hydro/Vib 프리셋, 모드별 SlewRate 기본값
MjolnirController
묠니르 자동세팅 + 세션
autoSetup() → MODE_CHANGE → WEIGHT → REPORT → RANGE
SpoexStorage
Supabase 업로드
묠니르 세션 결과 → 리더보드