mockWalk is a Python project for IMU gait analysis, IMU fitting, and a lightweight gait simulation model. Given 3-axis Linear Accel / Gyro / Gravity recordings, it estimates cadence, aligns steps (phase warping), and fits each axis with Fourier harmonics plus phase-domain Gaussian pulses, then exports gait_analysis.json for reconstruction and simulation. The simulator can generate synthetic IMU time series with noise/drift so you can validate algorithms, compare to real data, and batch-export figures and summary metrics.
Keywords: IMU gait analysis, IMU fitting, gait simulation model, cadence estimation, phase warping, Fourier fitting, Gaussian pulse transients, sensor noise/drift simulation, RMSE_norm, correlation
Install dependencies:
pip install numpy matplotlibFit a single session (and save fit.png):
python analyze_gait.py data/20260205_005806 --plotRun dynamic simulation for a single session (and save sim.png):
python -m src.run_simulation data/20260205_165320Batch run data/ and export figures to assets/:
python -m src.run_simulation data --force-analysis --deterministic --analysis-plot --export-assets<data_dir>/gait_analysis.json: fitted parameters- Optional (analysis
--plot):<data_dir>/fit.png - Optional (simulation):
<data_dir>/sim.png; batch simulation writesdata/test.png - Optional (
--export-assets):assets/compare.png,assets/sim.png,assets/summary.png,assets/test.png
mockWalk 是一个面向 步态分析、IMU 拟合 与 步态模拟模型 的 Python 工具链:输入 IMU 的三轴 Linear / Gyro / Gravity 记录,进行步频估计与步态相位对齐(phase warping),用傅里叶谐波与相位域高斯脉冲拟合每轴形状,并导出 gait_analysis.json 用于静态重构与动态仿真;仿真器还能叠加噪声/漂移生成合成序列,支持批量对比与汇总出图(fit.png、sim.png、汇总图)。
关键词:步态分析、IMU 拟合、步态模拟模型、IMU 步态仿真、加速度计、陀螺仪、重力向量、步频估计、相位对齐(phase warping)、傅里叶拟合、脉冲建模(冲击尖峰)、噪声漂移建模、仿真评估(RMSE_norm、相关系数)
- 自动读取数据目录下的
linear.csv、gyro.csv、gravity.csv - 统计采样率与时间跨度,并裁剪多传感器的共同时间区间
- 通过 FFT 峰值与自相关峰值估计步态主频,并在候选频率集合上做拟合误差比较
- 对主频进行全局搜索优化,得到更稳定的步频估计
- 在主频基础上做峰值检测(不足时自动降级为网格峰值)
- 分别对 Linear / Gyro / Gravity 的三轴做拟合,输出可复用参数(谐波系数、脉冲项、倍频因子、评分等)
- 可选绘图:对比原始信号与重构信号
- 可选卡尔曼滤波:对非重力传感器进行平滑(降低噪声对拟合的影响)
- 步态仿真:基于分析参数生成的时域信号,包含随机漂移、震颤等拟人化特征
- 步频估计与校正:先用 FFT 峰值与自相关峰值给出起始频率,再在
{f, f/2, 2f}候选上比较拟合质量,并通过全局搜索优化获得更稳定的步频。 - 峰值检测与相位对齐 (Phase Warping):以步态事件(峰/谷)为锚点将时间轴映射到相位轴,降低节律不均(轻微变速、步幅变化)对拟合的破坏,让模型更关注“每一步的形状”而不是“每一步发生在绝对时间的哪里”。
- 形状建模:Fourier 谐波 + 脉冲项:Fourier 负责主体周期形状;相位域高斯脉冲项用于刻画 jerk/冲击尖峰与非正弦的局部突变(比单纯堆叠高阶谐波更稳定,也更不容易过拟合到噪声)。
- 稳健拟合与数值稳定性:使用岭回归抑制病态设计矩阵带来的系数爆炸,可选鲁棒权重迭代(对离群点更不敏感),并对谐波阶数进行上限约束以避免越 Nyquist 的伪拟合。
- 预处理/滤波策略:包含去直流与去趋势、移动平均去漂移、可选 1D 卡尔曼平滑(非重力传感器),并在评分环节引入低通/高通维度的对比,避免“只拟合到高频噪声”或“只拟合到低频漂移”的假高分。
- 仿真拟人化与传感器质感:在重构信号基础上叠加随机游走偏置、相位抖动、增益抖动、频率漂移与生理震颤等,使输出更接近真实 IMU 的统计特征与短时不稳定性。
下图为分析阶段 --plot 生成的静态拟合对比:灰色为原始数据,彩色虚线为根据 Fourier 参数重构的纯净信号。该图来自 data/ 中某个数据集的拟合结果导出。
下图为使用仿真器生成的动态信号对比:包含随机游走漂移、频率抖动和生理震颤(模拟真实传感器噪声特征)。该图来自 data/ 中某个数据集的仿真结果导出。
flowchart TD
A[data_dir/linear.csv] --> L[CSV 加载]
B[data_dir/gyro.csv] --> L
C[data_dir/gravity.csv] --> L
L --> D[时间对齐与裁剪]
D --> E[步频初估\nFFT + 自相关]
E --> F["候选频率筛选<br/>(f, f/2, 2f)"]
F --> G[步频优化\n粗搜 + 细搜]
G --> H[峰值检测与相位对齐\n不足时降级为网格峰值]
H --> I[分轴拟合\nFourier + 可选脉冲项/扭曲策略]
I --> J[gait_analysis.json]
I --> K[对比图\n--plot]
flowchart LR
cli1[analyze_gait.py] --> main[src/main.py]
cli2[python -m src.main] --> main
cli3[python -m src.run_simulation] --> simcmd[src/run_simulation.py]
main --> cfg[src/config.py]
main --> io[src/io/loader.py]
main --> tu[src/utils/time_utils.py]
main --> freq[src/core/frequency.py]
main --> peaks[src/core/peaks.py]
main --> fourier[src/core/fourier.py]
main --> vizfit[src/viz/plotter.py]
main --> outjson[gait_analysis.json]
vizfit --> outfit[fit.png]
simcmd --> io
simcmd --> tu
simcmd --> simcore[src/core/simulator.py]
simcmd --> vizsim[src/viz/simulation_plots.py]
simcmd --> metrics[src/utils/metrics_utils.py]
simcmd --> outsim[sim.png]
simcmd --> outtest[test.png]
simcmd --> outassets[assets/*.png]
freq --> tu
freq --> sig[src/core/signal.py]
freq --> fu[src/core/fourier_utils.py]
peaks --> sig
peaks --> tu
fourier --> sig
fourier --> km[src/core/kalman.py]
fourier --> fu
fourier --> mu[src/utils/math_utils.py]
fourier --> peaks
vizfit --> fourier
vizfit --> tu
simcore --> fourier
vizsim --> simcore
仓库自带示例数据位于 data/,每个子目录是一段采集片段。可以用下面的命令复现实验输出与对比图:
python analyze_gait.py data/20260205_005806 --plot下图汇总了 data/ 目录下各数据集的步频估计与三类传感器的平均拟合评分(评分越高表示拟合越好):
下图汇总了 data/ 目录下各数据集的动态仿真对齐指标(RMSE_norm 越低越好,Corr 越高越好):
对应的数值表格:
(表格为示例,实际以每个数据集生成的 gait_analysis.json 为准)
| 数据集 | frequency (Hz) | Linear 平均评分 | Gyro 平均评分 | Gravity 平均评分 |
|---|---|---|---|---|
| 20260204_214640 | 0.847 | 49.4 | 50.6 | 51.2 |
| 20260205_005651 | 0.890 | 43.5 | 65.3 | 61.2 |
| 20260205_005806 | 0.857 | 67.1 | 84.9 | 77.9 |
| 20260205_165256 | 0.926 | 38.2 | 52.1 | 64.3 |
| 20260205_165320 | 0.941 | 48.3 | 51.5 | 49.5 |
更多对比图(每个数据集一张):
- 当前默认导出为单张总览图:
assets/compare.png、assets/sim.png,以及汇总图:assets/summary.png、assets/test.png
运行时需要一个数据目录,目录结构示例:
data_dir/
linear.csv
gyro.csv
gravity.csv
每个 CSV 需要包含表头字段(大小写敏感):
timestamp_ns,x,y,ztimestamp_ns:整型,纳秒时间戳(建议单调递增)x,y,z:浮点数,三轴数据(单位由数据源决定,项目不强制限定)
最小要求:
linear.csv必须存在,否则程序会直接退出gyro.csv、gravity.csv可选,不存在时会跳过对应拟合与输出
- Python >= 3.10(项目中使用了
dict | None等类型语法) - 依赖:
- numpy
- matplotlib(仅
--plot时需要)
如果你已经在本机环境安装了依赖,可直接运行。否则可执行:
pip install numpy matplotlibpython analyze_gait.py <data_dir>运行完成后会在 <data_dir> 下生成 gait_analysis.json。
python analyze_gait.py <data_dir> [--kalman] [--plot]<data_dir>:包含linear.csv的目录路径--kalman:启用 1D 卡尔曼滤波(对 Linear / Gyro 生效,不对 Gravity 生效)--plot:绘制 Linear / Gyro / Gravity 的原始与重构对比图- 输出:
<data_dir>/fit.png
- 输出:
使用 src/run_simulation.py 可以基于分析生成的 gait_analysis.json 运行动态仿真,验证参数在模拟运行时的表现(包含随机噪声与漂移)。
python -m src.run_simulation <data_dir>示例:
python -m src.run_simulation data/20260205_165320运行后会在 <data_dir> 下生成:
sim.png:动态仿真 vs 原始数据对比图
如果 <data_dir> 是 data/(包含多个子目录的根目录),则会对所有子目录批量运行,并在 data/ 下生成:
test.png:各数据集动态仿真指标汇总图(RMSE_norm / Corr)
你也可以加 --export-assets 把图导出到 assets/(单词命名、无下划线):
python -m src.run_simulation data --force-analysis --deterministic --analysis-plot --export-assetsassets/compare.png:拟合重构总览图(从某个数据集导出)assets/sim.png:动态仿真总览图(从某个数据集导出)assets/summary.png:步频与拟合评分汇总图assets/test.png:动态仿真指标汇总图
python -m src.run_simulation <data_dir|data> 支持以下参数(可任意组合):
--force-analysis:强制重新生成每个数据集的gait_analysis.json(并在需要时生成fit.png)--analysis-plot:在分析阶段输出fit.png(配合--force-analysis使用最清晰)--deterministic:关闭拟人化扰动(更稳定、便于对齐对比)--export-assets:将示例图与汇总图导出到assets/(compare.png/sim.png/summary.png/test.png)--optimize:在批量数据上搜索更优的仿真扰动参数,再用最佳参数重新批量生成图--intensity <float>:拟人化强度(仅在开启拟人化时生效)--noise-scale <float>:整体噪声缩放(对noiseSigma*统一缩放)--seed <int>:随机种子
分析单个数据集(不画图):
python analyze_gait.py data/20260205_005806分析单个数据集(画拟合图 fit.png):
python analyze_gait.py data/20260205_005806 --plot分析单个数据集(启用 Kalman):
python analyze_gait.py data/20260205_005806 --kalman --plot仿真单个数据集(输出 sim.png):
python -m src.run_simulation data/20260205_165320 --deterministic批量仿真并导出 assets/*.png:
python -m src.run_simulation data --force-analysis --deterministic --analysis-plot --export-assets批量搜索更优仿真扰动参数(然后生成/导出图片):
python -m src.run_simulation data --optimize --force-analysis --deterministic --analysis-plot --export-assetspython -m src.main <data_dir> [--kalman] [--plot]程序输出文件为:
<data_dir>/gait_analysis.json- 可选(分析阶段
--plot):<data_dir>/fit.png - 可选(仿真阶段):
<data_dir>/sim.png;批量仿真时在data/下生成test.png - 可选(
--export-assets):assets/compare.png、assets/sim.png、assets/summary.png、assets/test.png
顶层字段说明(简化描述,字段以实际输出为准):
frequency:最终估计的步态主频(Hz)duration:用于拟合的数据时长(秒)fourierAccel:Linear 三轴的傅里叶谐波参数,结构为长度 3 的数组[x,y,z]- 每个轴是一个扁平数组:
[mag1, phase1, mag2, phase2, ...]
- 每个轴是一个扁平数组:
pulseAccel:Linear 三轴的脉冲项参数(可能为空)- 每个轴是一个扁平数组:
[mu1, sigmaPhi1, amp1, mu2, sigmaPhi2, amp2, ...]
- 每个轴是一个扁平数组:
freqMulAccel:Linear 三轴的倍频因子(用于处理半频/倍频等情况)scoreAccel:Linear 三轴的拟合评分(综合指标,数值越大表示拟合越好)
Gyro 与 Gravity 的字段结构类似:
fourierGyro、pulseGyro、freqMulGyro、scoreGyrofourierGravity、pulseGravity、freqMulGravity、scoreGravity
重力相关字段:
gravity:Gravity 三轴的直流分量(DC)
如果你需要用输出参数合成信号,可参考实现:
src/core/fourier.py中的synth_mock_signals
整体流程可阅读 src/main.py 的 run_analysis:
- 加载
linear.csv(必需),以及可选的gyro.csv、gravity.csv - 计算线性加速度三轴幅度,幅度过小(当前阈值为 0.3)则认为运动不足并退出
- 主频估计:
- Linear 模长信号的 FFT 峰值与自相关峰值
- 可选叠加 Gyro 三轴的 FFT 峰值作为候选
- 候选主频筛选:
- 在
{f, f/2, 2f}候选集上比较拟合误差,选择更合理的频率
- 在
- 全局搜索优化主频(在局部范围内做粗搜与细搜)
- 峰值检测与相位对齐:
- 优先使用 Linear Z 的峰值检测
- 峰值不足时自动降级为“按周期网格选峰”
- 分轴拟合:
- Linear / Gyro:傅里叶谐波 + 可选脉冲项 + 可选相位扭曲/分段增益策略(用于改善冲击特征或节拍不均匀)
- Gravity:以傅里叶谐波为主,并输出 DC 分量
- 输出
gait_analysis.json,可选绘图对比
.
├── analyze_gait.py # 命令行入口
└── src/
├── main.py # 主流程编排与结果输出
├── config.py # 全局配置常量
├── run_simulation.py # 动态仿真与批量评估/导出
├── io/
│ └── loader.py # CSV 加载
├── core/
│ ├── simulator.py # 动态仿真器与噪声/拟人化扰动
│ ├── signal.py # 信号处理 (去趋势/滤波/评分等)
│ ├── frequency.py # 频率估计与优化
│ ├── peaks.py # 峰值检测与相位计算
│ ├── kalman.py # 1D 卡尔曼滤波
│ ├── fourier_utils.py # 设计矩阵与岭回归求解
│ └── fourier.py # 拟合策略与合成逻辑
├── utils/
│ ├── time_utils.py # 时间处理与裁剪
│ ├── metrics_utils.py # 指标计算
│ └── math_utils.py # 相位与角度工具
└── viz/
├── plotter.py # 拟合绘图对比
└── simulation_plots.py # 仿真与汇总绘图
配置文件位于 src/config.py:
MIN_FREQ_HZ/MAX_FREQ_HZ:步频搜索范围(默认 0.6 到 3.5 Hz)EPS:数值稳定性相关的小量ENABLE_KALMAN:是否启用卡尔曼滤波(运行时会根据--kalman动态覆盖)
常见原因:
linear.csv不存在或格式不正确(必须包含timestamp_ns,x,y,z)- 线性加速度幅度过小(当前阈值为 0.3),被判定为“运动不足”
- 主频估计不在范围内(默认 0.6 到 3.5 Hz)
--plot 依赖 matplotlib。若你在无 GUI 的环境运行(例如远程服务器),需要配置合适的后端或关闭绘图选项。
欢迎提交 Issue 或 Pull Request:
- Bug:请附上最小可复现实例、数据格式说明与运行命令
- 性能与质量改进:建议同时提供对比指标(例如拟合评分、运行耗时)
Apache 2.0许可证