feat(analysis): M1 온디바이스 속도 전용 분석 파이프라인#38
Merged
Conversation
main의 기존 CV fallback 경로(analysis_trim_page.dart)가 여전히 BallTracker.calcSpeedKmh를 참조 — Task 13에서 해당 경로를 새 파이프라인으로 교체하기 전까지는 유지 필요.
findReleaseFrame(int?) → findRelease(ReleaseResult) API 변경 대응. Task 13에서 전체 파이프라인 교체 전까지 임시 어댑터.
[캘리브레이션] - CalibrationViewModel/Providers/Overlay/Page 신규 추가 - 저장 시 setDefault 자동 호출 — 안 하면 트림 화면이 영원히 기본 프로파일을 못 찾아 캘리브레이션 기능 전체가 죽은 코드가 됨 - 트림 화면 AppBar에 캘리브레이션 진입점 추가(기존엔 도달 경로 없었음) [분석 파이프라인 배선] - 트림 화면 분석 버튼을 Gemini/로컬 폴백 체인에서 AnalysisPipeline(drift-check 포함) 호출로 교체 - 결과 화면이 참조하던 구버전 AnalysisData(video_analysis_service)를 신규 도메인 AnalysisData로 교체, RPM 표시 제거(M1 스코프 아님), 실패 사유 배너(speedFailureUserMessage) 추가 - 라우터의 잔존 구버전 AnalysisData 참조도 함께 교정(도달 불가능한 라우트지만 타입 불일치로 analyze 에러 유발)
트림 화면이 AnalysisPipeline 배선으로 교체되며 GeminiAnalysisService를 더 이상 참조하지 않음. gemini_analysis_service_test.dart는 순수 로직을 자체 복제해 테스트하므로 서비스 삭제와 무관하게 유지.
[analysis_pipeline] - drift-check가 currentFrame과 referenceFrame으로 같은 프레임(frames.first)을 넘겨 항상 ok를 반환하던 버그 수정. 캘리브레이션 시점 레퍼런스 이미지 (profile.referenceImagePath)를 디코드해 실제 referenceFrame으로 사용. 레퍼런스 파일을 읽거나 디코드할 수 없으면 안전하게 recalibrationRequired 처리 - drift가 autoCorrected일 때 speedConfidence에 소폭 페널티(0.9x) 반영 (스펙 요구사항) - 프레임 추출 결과가 비어있는 경로에서 speedFailure가 null로 남아 결과 화면에 빈 안내 문구가 뜨던 문제 수정 (lowConfidence로 설정) - 더 이상 쓰이지 않는 fpsHint 파라미터 제거, 호출부(analysis_trim_page, 골든 회귀 테스트) 동기화 [speed_estimator_service] - release.confidence가 최종 speed confidence 계산에 반영되지 않던 문제 수정 [analysis_state_machine] - impact 판정 lane-y 임계값을 다른 곳과 동일한 실제 레인 길이(18.29m)로 통일
- video_analysis_service.dart: lib/ 어디서도 참조되지 않는 구(舊) CV-fallback 파일. 새 도메인 엔티티와 이름이 겹치는 AnalysisData 클래스를 정의해 혼란만 유발하고 있어 삭제 - ball_detection_service.dart의 BallTracker: Task 13에서 analysis_trim_page가 재작성되며 마지막 참조가 사라진 죽은 코드 삭제 (BallDetection/ BallDetectionService는 유지) - app_router.dart: 아무 곳에서도 navigate하지 않는 고아 라우트 '/analysis/result' 제거. extra를 Map<String, dynamic>으로 무가드 캐스팅하던 코드라 실제로 호출됐다면 런타임에 터졌을 코드였음
[calibration_drift_checker] - 레퍼런스(고해상도 갤러리 사진)와 현재 프레임(ffmpeg 480px 추출) 해상도가 달라 정규화 좌표가 서로 다른 픽셀 스케일로 해석되던 문제 수정 — 비교 전 레퍼런스를 현재 프레임 크기로 리사이즈 - 탐색 반경(12px) 특성상 driftScoreNormalized만으로는 재캘리브레이션 임계값(대각선 5%)에 도달할 수 없어 게이트가 사실상 no-op이던 문제 수정 — NCC 최저 기준 미달 또는 탐색창 경계에서 최적 매칭이 나온 포인트를 "신뢰 불가"로 집계해 2개 이상이면 오프셋 크기와 무관하게 재캘리브레이션 요구로 판단 [analysis_pipeline] - release 미검출을 impactNotFound로 오분류하던 실패 사유 분리 (release 미검출 → releaseNotFound, impact만 없으면 impactNotFound)
[calibration_drift_checker_test] - 기존 200x200 정사각 테스트는 우연히 임계값이 도달 가능해 통과하던 케이스 — 레퍼런스 3배 고해상도(1440x810) vs 현재 프레임(480x270) 조건의 테스트 추가: (1) 동일 장면·다른 해상도는 리사이즈 후 ok로 판정, (2) 현재 프레임에 마커가 전혀 없으면 NCC 최저 기준 미달로 재캘리브레이션 요구 [gemini_analysis_service_test] - 삭제된 서비스(gemini_analysis_service)를 검증하던 테스트 제거 — 파일 내부에 재정의한 헬퍼 함수만 검증하는 자기순환 테스트였음
BoxFit.contain 렌더링 시 레터박스 영역을 고려하지 않고 탭 좌표를 컨테이너 전체 크기로 정규화하던 문제 수정. 저장되는 nx/ny가 이미지 상대 좌표가 아니라 컨테이너 상대 좌표였고, 이 값이 분석 파이프라인의 이미지-정규화 좌표(BallDetection.cx/cy)와 같은 공간으로 취급되어 호모그래피가 체계적으로 틀어지고 있었다. - computeContainRect(순수 함수)로 실제 이미지 표시 영역을 계산해 레터박스 탭은 무시하고, 탭 좌표를 이미지 상대로 변환 - 마커도 동일 변환의 역으로 정확한 위치에 렌더링 - 캘리브레이션 스텝 안내를 한국어 완전 문장으로, 마커에 순번 표시
[calibration] - 프로파일 없이 분석 시작 시 SnackBar 대신 안내+캘리브레이션 진입 다이얼로그로 교체 (analysis_trim_page) [result] - 구속 측정불가 시 "다시 촬영하기"를 primary CTA로 추가, 저장하기는 secondary로 강등 (analysis_result_page) [camera] - 좌상단 닫기 버튼, 녹화 중 mm:ss 타이머 추가 - 원본 예외 노출하던 에러 메시지를 사용자 카피로 교체, 예외는 debugPrint로만 (analysis_camera_page, analysis_trim_page) [rpm 잔존 카피 제거] - 로딩 위젯의 "회전수 측정 중" 스텝 제거 - 선택 화면 팁 문구를 구속 측정 중심으로 교체 - 히스토리 카드 "RPM 미측정" 행 제거 - 상세 화면 RPM 통계 제거, 구속 단독 중앙 정렬 [theme] - 선택 화면 안내 박스의 하드코딩 white-alpha 배경/보더를 AppColors 팔레트 토큰으로 교체 (라이트 테마 대응)
대형 PR(수십 커밋)에서 15턴 내에 리뷰를 못 끝내고 error_max_turns로 실패 (run 28901873998).
M1 파이프라인 실기기 검증을 위해 진입점 복원. 테플 내부테스터 배포는 애플 베타심사 안 거치므로 리스크 없음. 정식 App Store 제출 전에는 재검토 필요 — 원래 비활성화 사유(앱스토어 이슈) 자체가 해소된 건 아님.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docs/superpowers/specs/2026-07-07-ball-tracking-redesign-design.md, 플랜:docs/superpowers/plans/2026-07-07-ball-tracking-m1-speed-pipeline.md(둘 다 gitignore 대상이라 이 diff엔 안 잡힘 — 별도 공유 필요)진행 중 발견/수정된 이슈
액션 필요 (배포 전 필수)
Supabase
ball_analysis테이블에 컬럼 추가 SQL을 대시보드에서 직접 실행해야 함(에이전트가 대신 실행하지 않음):이거 없이 분석 결과 저장 시 insert 실패함.
Test plan
flutter test test/features/analysis/ test/golden_reference/— 55/55 통과 (골든 회귀는 fixture 없어 정상 skip)flutter analyze— 0 errors (기존 baseline 경고 11개만)