前几天写了一篇关于如何记步的博客之后,我就在思考怎么样利用手机的传感器来计算步长呢?和记步不一样,步长是一个相对比较精确的值,通过手机端那个不靠谱的加速度传感器真的有办法计算步长吗?
看了几篇利用GPS计算步长方法,大概就是现在我们用的一些运动软件的算法了,先利用不太精确的GPS画出运动轨迹,计算出轨迹的长度,再除上运动步数,就是步长了。当然其中会运用到很多辅助算法来提高精确值,实际上在距离足够远的时候,也据说数据量足够多的时候,可以得出较为精确的步长值。
当然这是我需要的吗?No,远远不够,如果在室内,在地下停车场呢,GPS就完全失效了,这个时候能够依赖的就只有加速度了。我又缩小了搜索范围——基于加速度的步长算法,还是找到几篇相关文章的,大致分为两种方式:
1.对加速度求积分算出行进距离
2.通过把加速度传感器绑在腿上,感知波形
第二种方式对于手机根本不适用(手机不是拿在手上就是装兜里,谁没事挂腿上),直接毙掉。再看第一种,有尝试的价值,但实际尝试后也有各种各样的问题,一个关键问题就是手机传感器精度不够,实际偏差非常大,很可惜也不行。
看起来好像在手机端做步长算法好像根本不可能,现实也的的确确是这样。我本来也打算放弃来着,不过前两天突然灵机一动,能不能利用之前写的记步算法中用的两个数据来简单预测呢?
说做就做,算法可以说简单到离谱了,以我自己为模板来尝试,35米左右距离大约走五十步左右,实际偏差在正负五米,实际误差还是挺大,但是也比上面的方法一要精确多了。
好了也不卖关子了,来说说是哪两个数据,如图:

解释下坐标系,横坐标时间(单位ms),纵坐标加速度(单位m/s),加速度包含重力加速度,这个我之前的文章有写,可以看看。
H就是一步的波峰波谷(两个波谷求个均值)差值,W就是波谷之间的距离,也就是走一步所需的时间。再来看算法:
float steplength=0.37f+W/10000+0.29f*H/5;
很简单的算法是不是?
经过我个人测试,在大范围还是有一定的精准度的,但是在细节方面却千差万别。实际测试每百米上下浮动在二十米到三十米左右,这还是我个人测试的结果,依然不够精确。
简单讲下我的思考方式,首先实际行走一段距离,用不同的步速和步长进行行走,计算W和H的值,根据数据大致可以画一张图(当然过程中也要采集步长)当然这些只是我的个人数据,不具有一般性,所有数据图我就不放了,乱糟糟的,有兴趣自己画吧。最后大致推出这样的公式,具体有能力的同学可以做个大数据分析,应该是可以推导个近似公式。
这个方式还具有很多的改进空间,可以用一些更科学的方式(滤波、均值什么的),当我毕竟不是要用于商用,算的更精确对我来说也没什么必要,在这仅仅是提出我个人的一个计算步长的猜想,抛砖引玉。
————————————————————————————————————————————————————
补充一下,最近发现上面的公式还是有些问题。发现一个问题,H越大时步长确实是越大的,但是W增大时,对于步长其实反而是有负增益的,但是又不完全是线性减少,有待研究。在这提醒下,上面的公式只是我随手凑出来的,并不太准确。
————————————————————————————————————————————————————————
我发现自己路走偏了,本来想用两个不精确的数据来估计一个确定数据就非常的不靠谱,我还期望用一个固定的公式来做精准的推测。我准备学习一些经典的预测方法再做一次尝试。
————————————————————————————————————————————————————————
不好意思误导大家了,在这里必须澄清一下,实际上有很多论文都谈到步长的计算方式,只不过仅仅作为论文的一部分,没有单独拿出来说而已。由于博主论文看的少,最近开始补这方面的论文才发现实际上有很多的实现方法(甚至有些接近于我的想法,说明我的方向是没错的)。所以上面的看看就行,不要全信。
顺便说一下其中很大一部分论文在计算步长的时候用到了我上面提到的参数H,用了最小二乘法来推线性比例。实际上我也走过这条路,不过效果并不是很好,我还是坚持用H加W的算法,最近想引入卡尔曼滤波器再试试,看下效果如何。
————————————————————————————————————————————————————————
上面的公式我就不改了,献给给有耐心看到底的朋友,重新给一个 个人认为还是较为不错的公式,亲测效果还是不错的(150米正常行走偏差十米以内,跑步偏差四十米以内):
float steplength=0.37f-0.000155f*W+0.1638f*(float) Math.sqrt(H);
主要利用了最小二乘法,还有个人的一些推测。
————————————————————————————————————————————————————————
最近把计步器算法和步长估计封装成类了,有兴趣的点这里(Android计步器实现)