Issue #11 · CSV 3건 · 검출 로직은 Sirius/wearable-pet 의
Tflm.cpp 실제 코드 · 축별 기여 및 샘플레이트 비교 포함 · 2026-07-28
145005
27
peaks · 108.5s · 14.9/min
x/y/z 지배 15% / 37% / 48%
145259
0
peaks · 37.7s · 0.0/min
x/y/z 지배 0% / 0% / 0%
145401
29
peaks · 49.0s · 35.5/min
x/y/z 지배 97% / 3% / 0%
실제 펌웨어 코드 기준입니다 —
Sirius/wearable-pet 레포에서 검출 로직을 찾아 그대로 옮겼습니다:
firmware/…/src/source/predict/Tflm.cpp의
process_acceleration_data() (495–553번 줄) 와
src/header/predict/Tflm.h 의 상수.
남은 재구성은 라벨 게이트 하나뿐입니다. 아래 걸음수는 게이트 적용 전 값이라,
실제 기기에서는 이보다 작거나 같습니다.
축 관련 중요 — 이 알고리즘은 축별로 임계를 넘는지 보지 않습니다.
가속도 크기 |a| = √(x²+y²+z²)를 4차 Butterworth로 저역통과시킨 뒤,
그 값에 절대 임계 15.0를 겁니다 (Tflm.cpp:540-546). 중력을 빼지 않습니다 —
정지 상태 기준선이 이미 9.8이라 임계 15.0은 중력 위로 약 5.2 m/s² 여유를 요구합니다.
그래서 아래 “지배 축”은 그 걸음이 카운팅된 순간, 세 축 중 윈도우 평균 대비 편차가
가장 컸던 축이라는 뜻입니다 — 그 축이 단독으로 임계를 넘겼다는 뜻이 아닙니다.
축이 단독이었다면 어땠을지는 “축별 독립 검출”(연한 막대)로 따로 뽑았습니다.
축별 요약
accel_xaccel_yaccel_z진한 막대 = 지배 축 걸음 수 · 연한 막대 = 축별 독립 검출
샘플레이트 비교 — 100 Hz vs 50 Hz
CSV는 ~101 Hz로 기록돼 있고, 펌웨어도 accel ODR을 104 Hz로 설정한 뒤
(Tflm.cpp:1031) trigger_handler가 데시메이션 없이
모든 DATA_READY 샘플을 버퍼에 넣습니다. 즉 CSV가 실제 기기 스트림과 같은 레이트입니다.
여기서 불일치가 하나 보입니다 —
IIR 계수는 SAMPLING_RATE 50.0f, CUTOFF_FREQ 5.0f
기준으로 설계돼 있습니다 (Tflm.h:21-22). 주파수 응답을 직접 계산해보면 fs=50 Hz에서
-3 dB가 정확히 5.00 Hz로 떨어져 설계값과 일치합니다.
그런데 실제로는 104 Hz로 돌아가므로 같은 계수가 -3 dB @ 10.4 Hz로
동작합니다 — 의도의 2배로 덜 걸러집니다. 아래 “50 Hz” 열은 신호를 열화시킨 게
아니라 필터가 원래 설계된 조건이고, 거기서 걸음수가 절반 가까이 줄어듭니다.
걸음수 (점선 = CSV 원본 기준선 · 세로선 = 데시메이션 위상별 편차)
CSV 원본(~101 Hz) 대비 변화율
file
~101 Hz
50 Hz
Δ
위상 범위
25 Hz
Δ
145005
27
12
-56%
11–12
3
-89%
145259
0
0
—
0–0
0
—
145401
29
16
-45%
16–17
0
-100%
145005
— 27 peaks · 108.5s
10,948 samples @ 100.93 Hz · 윈도우 43개 · 지배 축 x 4 ·
y 10 ·
z 13
필터 후 |a| 와 임계선 (빨간 점선을 넘는 국소 최대값만 걸음으로 셉니다)
필터 후 최댓값 73.07 · 99퍼센타일
23.2 · 임계 15.0 초과 구간 1.69%
확대 구간 0.0–7.92s — 원시 x/y/z와 카운팅 시점
(세로선 = 걸음, 색 = 그 순간 편차가 가장 큰 축 · 점을 누르면 세 축 편차가 보입니다)
accel_xaccel_yaccel_z
전체 구간 걸음별 지배 축 (축별 행에 점 하나 = 걸음 하나)
가속도 크기 |a| — 실제 임계 판정 대상
윈도우별 피크 수 (250샘플 ≈ 2.5초 · 연한 회색 = 활동 게이트 탈락)
누적 피크 수
145259
— 0 peaks · 37.7s
3,807 samples @ 100.93 Hz · 윈도우 15개 · 지배 축 x 0 ·
y 0 ·
z 0
필터 후 |a| 와 임계선 (빨간 점선을 넘는 국소 최대값만 걸음으로 셉니다)
필터 후 최댓값 13.82 · 99퍼센타일
11.76 · 임계 15.0 초과 구간 0.0%
확대 구간 0.0–7.92s — 원시 x/y/z와 카운팅 시점
(세로선 = 걸음, 색 = 그 순간 편차가 가장 큰 축 · 점을 누르면 세 축 편차가 보입니다)
accel_xaccel_yaccel_z
전체 구간 걸음별 지배 축 (축별 행에 점 하나 = 걸음 하나)
가속도 크기 |a| — 실제 임계 판정 대상
윈도우별 피크 수 (250샘플 ≈ 2.5초 · 연한 회색 = 활동 게이트 탈락)
누적 피크 수
145401
— 29 peaks · 49.0s
4,951 samples @ 100.93 Hz · 윈도우 19개 · 지배 축 x 28 ·
y 1 ·
z 0
필터 후 |a| 와 임계선 (빨간 점선을 넘는 국소 최대값만 걸음으로 셉니다)
필터 후 최댓값 18.1 · 99퍼센타일
16.23 · 임계 15.0 초과 구간 2.63%
확대 구간 20.31–28.23s — 원시 x/y/z와 카운팅 시점
(세로선 = 걸음, 색 = 그 순간 편차가 가장 큰 축 · 점을 누르면 세 축 편차가 보입니다)
accel_xaccel_yaccel_z
전체 구간 걸음별 지배 축 (축별 행에 점 하나 = 걸음 하나)
가속도 크기 |a| — 실제 임계 판정 대상
윈도우별 피크 수 (250샘플 ≈ 2.5초 · 연한 회색 = 활동 게이트 탈락)
누적 피크 수
전체 수치
file
samples
dur(s)
windows
peaks
게이트 후
cadence
dom x
dom y
dom z
indep x
indep y
indep z
20260728_145005.csv
10,948
108.5
43
27
26
14.9
4
10
13
12
12
12
20260728_145259.csv
3,807
37.7
15
0
0
0.0
0
0
0
0
0
0
20260728_145401.csv
4,951
49.0
19
29
28
35.5
28
1
0
18
0
0
“peaks” = 검출기가 낸 값(게이트 전). “게이트 후” = std 기반 활동 게이트 적용. “dom” = 지배 축별 걸음 수
(합 = steps). “indep” = 각 축만으로 같은 검출기를 돌렸을 때의 걸음 수 (합이 steps와 다름).