学习|从原理上出发,足不出户刷长跑(要刷就刷有步数的长跑)

写在前面:这。。大概算是一篇技术贴吧。。

需要准备的东西:夜神模拟器(@夜神  请准备好广告费,过两天我让海绵宝宝去收)https://www.yeshen.com/

        阳光体育服务平台app(这个**软件真对得起它的评分):链接(也可以去公众号下载): https://share.weiyun.com/5NeBevD (密码:D2Rb)

        以及。。请给我个赞安慰安慰我浪费在这破软件上的时间。👍

 

进入主题——足不出户刷长跑

  既然是学习,先来讲讲原理吧。想要完成一次长跑,需要达成以下几点:

    1. 跑满5个规定的点
    2. 跑满规定的路程(男生2km)
    3. 速度在规定范围内(男生要在2m/s~4m/s)超过最大规定速度或者低于最小规定速度,都视为无效成绩

  上面三点是硬性条件,不满足就无法完成长跑。所以一些root后的位置模拟app、以及现在还有一些不用root手机的虚拟定位app都可以完成这个要求,而且它们的摇杆用起来比模拟器用鼠标点舒服多了(小声逼逼)。

  但是这样会有一个问题,就是完成长跑后会发现2km,步数为10步。。(飞呢???)

  是的,这个破app还会计步。虽然不是硬性条件,但是成绩看起来总归有那么些不舒服。

  计步app原理

(以下关于计步原理,主要是来自这篇文章http://www.sohu.com/a/190966257_468626

  电子计步器通常是内置一个加速度传感器(Accelerometer)和一个运算单元(MCU),通过加速度传感器感应用户的加速度变化,然后通过MCU来估算行走的步数。电子式计步器通常采用三轴加速度传感器,可以感应用户在三维方向上的运动,且内置较为复杂的计步算法。

  目前智能手机和某些非智能手机都内置了加速度传感器,只需要增加相应的软件即可实现计步,无需增加硬件成本。智能手表,智能手环类产品也都内置加速度传感器和计步算法,方便用户监控自己的运动量。

计步app

  以放置在手腕处的加速度传感器(手环、手机其实一样)为例。用户在水平步行运动中,手腕处的加速度会收到重力加速度和甩手加速度的双重影响。如下图所示,红色箭头表示重力加速度,绿色箭头表示甩手加速度。

  受力分析

  在步行过程中,重力加速度始终垂直与大地,甩手动作带来的加速度呈周期性变化。 反映到图表中,可以看到,在步行运动中,垂直和前进产生的加速度与时间大致为一个周期性信号。

  

  通过对轨迹的峰值进行检测计算和加速度阀值决策,即可实时计算用户运动的步数,还可依此进一步估算用户步行距离。

计步算法:

  计步算法可以分为四大类,一是峰值检测算法,二是变换域算法,三是滤波算法,四是模式识别算法。根据所设计的计步器在人体上布放的位置不同,如腕部、腰部、鞋底等,可以选择不同的计步算法。

   峰值检测类算法原理简单,易于实现,应用较为广泛。这里简单介绍峰值检测类算法。用户在运动中,可能把设备放置于口袋或者包中,亦或拿在手中。所以设备的放置方向不确定。那么首先,我们通过计算三个加速度的矢量长度,可以获得一条步行运动的正弦曲线轨迹。

  第二步就是峰值检测,我们记录了上次矢量长度和运动方向,通过矢量长度的变化,可以判断当前加速度的方向,并和上一次保存的加速度方向进行比较。如果是相反的,即是刚过峰值状态,则进入计步逻辑进行计步,否则就舍弃这段。通过对峰值次数的累加,那我们就可得计算得到用户步行的步数。

  最后,就是去噪音(干扰)。手机或智能手表等手持设备会有一些低幅度和快速的抽动状态,即我们俗称的手抖,或者某个用户想通过短时快速反复摇动设备来模拟人走路,这些干扰数据如果不剔除,会影响记步的准确值,对于这种干扰,我们可以通过给检测加上阀值和步频判断来过滤。目前人类最快的跑步频率为5HZ(当然不排除人类借助其它设备跑步频率超过这个频率),也就是说相邻两步的时间间隔的至少大于0.2秒,如图中的计步时间,若两次计步之间的时间间隔小于0.2秒,则不计步。这样我们就过滤了高频噪声,即步频过快的情况。同时我们通过和上次加速度大小进行比较,设置一定的阀值Threshold来判断运动是否属于有效(如图中的绿线),有效运动才可进行记步。

  如果已知步行和跑步的步数,那么再通过人体身高,体重及性别就可以大致知道此人的步长,改进后即可变成一个测距离及测速计。通过三轴加速度传感器,我们可以知道用户的运动状态。除了计步,还可以利用加速度传感器与陀螺仪及磁传感器融合进行步行航迹推算。  

  

 

  所以从原理上出发——计步来源于摇手机,但是手摇太累,所以使用夜神模拟器录制”摇一摇“操作,然后加速重复操作(虽然有些被过滤掉,但至少看起来数据不再那么假)。

   进入正题——开始操作

  本来想好写一大堆话的,等到打算写了却发现没啥好写的。先看视频吧,把一些操作写到了视频里。视频是拼接的,第一次录的时候,差点么把我手点抽筋。等录完视频帮舍友刷跑步的时候又发现了个更舒服点的操作,打算放在视频之后讲。(原本打算一遍录一遍讲解的,不过宿舍里比较吵,所以就打字幕了。小黑的歌和颜一样好=w=

  https://www.bilibili.com/video/av47516576/

  注:

    1. 录制摇一摇操作时,其他不必要的时间不要太长
    2. 不要先跑完5个点再去刷满路程,因为这样路程一满2km系统就会自动结束,你就来不及”摇一摇“了。(而且后期可以直接快速定位你所需要的点  俗称:飞起来)
    3. 一旦你定位的两个点距离过远,瞬时速度就会超过6.5m/s,也就说瞬时速度会变红,系统会认为你在飞,并且不会把你的这段路程计入总路程(我试过40.5m/s的瞬时速度= =)。
    4. 在刷路程的时候尽量先把自己的速度提升上去(除了手速快点,下面会讲一个优化的方法),这样可以给你更多时间去获得步数。
    5. 在刷步数的时候记得关注你的匀速,跌落最小速度成绩就无效了。

  看完视频,感觉步数问题是得到了很好的解决,而且在镜湖里刷长跑也确实挺爽,但是点来点去也太TM累了。而且有的时候还控制不好距离

  然后我发现这个模拟器的虚拟定位可以记住位置!!!

  所以我打算找两个距离差不多的点,然后在这两个点来回切换(视频稍后放),顿时省力多了。

  我试了一下,凭我电脑的延迟,两个点相聚11.414788113819023米时,我的速度正好可以达到6.5m/s,而且可以被记入路程。【蜜汁微笑】

  

  那么问题来了:地图上我只有经纬坐标,怎么计算距离呢?

 解:

  设两点A、B的经、纬度分别为(jA,wA)(jB,wB),则半径为R的球面上两点间的最短距离(大圆弧)为:

  弧AB=R*arccos[sin(wA)sin(wB)+cos(wA)cos(wB)*cos(jA-jB)]

  地球是一个近乎标准的椭球体,它的赤道半径为6378.140千米,极半径为6356.755千米,平均半径6371.004千米。如果我们假设地球是一个完美的球体,那么它的半径就是地球的平均半径,记为R。如果以0度经线为基准,那么根据地球表面任意两点的经纬度就可以计算出这两点间的地表距离(这里忽略地球表面地形对计算带来的误差,仅仅是理论上的估算值)。设第一点A的经纬度为(LonA, LatA),第二点B的经纬度为(LonB, LatB),按照0度经线的基准,东经取经度的正值(Longitude),西经取经度负值(-Longitude),北纬取90-纬度值(90-Latitude),南纬取90+纬度值(90+Latitude),则经过上述处理过后的两点被计为(MLonA, MLatA)和(MLonB, MLatB)。那么根据三角推导,可以得到计算两点距离的如下公式:

  C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB)

  Distance = R*Arccos(C)*Pi/180

  这里,R和Distance单位是相同,如果是采用6371.004千米作为半径,那么Distance就是千米为单位。

  如果仅对经度作正负的处理,而不对纬度作90-Latitude(假设都是北半球,南半球只有澳洲具有应用意义)的处理,那么公式将是:

  C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)*cos(MLonA-MLonB)

  Distance = R*Arccos(C)*Pi/180

  以上通过简单的三角变换就可以推出。

  如果三角函数的输入和输出都采用弧度值,那么公式还可以写作:

  C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)

  Distance = R*Arccos(C)*Pi/180

  附:源代码

/** 
 * google maps的脚本里代码 
 */    
private const double EARTH_RADIUS = 6378.137; 
private static double rad(double d) 
{ 
     return d * Math.PI / 180.0; 
}  

/** 
 * 根据两点间经纬度坐标(double值),计算两点间距离,单位为米 
 */ 
public static double GetDistance(double lat1, double lng1, double lat2, double lng2) 
{ 
    double radLat1 = rad(lat1); 
    double radLat2 = rad(lat2); 
    double a = radLat1 - radLat2; 
    double b = rad(lng1) - rad(lng2); 
    double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) + 
    Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2))); 
    s = s * EARTH_RADIUS; 
    s = Math.Round(s * 10000) / 10000; 
    return s; 
} 

  

  可以自己去选点然后计算距离鸭~~~~~~

  然后我给两个檀香旁边的点吧:

  A(32.092334,118.64402)  B(32.092383,118.64392)

  距离=0.011414788113819024 km =11.414788113819023 m

  放视频:https://www.bilibili.com/video/av47516576/?p=2

  

  

  开挂一时爽,一直开挂一直爽啊。(这一点都不苏维埃。)

 

  尝试了这些,最后觉得还不如去跑一圈来的舒服点。(不是大家不喜欢锻炼,只是不喜欢这种形式罢了。。)

  我可没不让大家阳光长跑啊!!!!

 

  仅供学习交流,因使用本工具而造成的一切不良后果由使用者自行承担,与作者无关(¬︿̫̿¬☆)

 

  为了我的继续运营,请大家继续一如既往地表面支持阳光长跑。。

 

 

  其实吧,有的时候网络环境好的话,飞起来也是会被记入系统的。

  而且,就步数这个有些手机的传感器确实不那么灵敏,所以说步数严格来说不能作为一个评判标准。← ←。懂我几个意思吧。

 

posted @ 2019-03-28 09:13  自救默示录  阅读(5902)  评论(2编辑  收藏