Android计步器算法实现
最近在研究惯性导航和其他导航算法的融合,顺手把计步、步长等一堆算法写成类了,舒服~
这篇文章我不会具体的讲解实现原理,有兴趣研究的朋友直接看我写的计步算法实现和步长计算。
Android系统有自带的计步器,那么为什么要自己实现一套记步算法呢?
一.可以做步长估计
二.鉴于国产手机碎片化比较严重,不同系统都会有一套自己的记步算法,导致系统算法在实际运用中表现不同:
1.算法的灵敏度不同,具体表现在非步态信号的滤除不同,有的算法滤波更严格,也更精确。
2.算法的缓冲带长度不同,具体表现在走了多少步以后算法认为人开始走路,此时算法才开始返回走路的步数,中间会有一段时间不返回任何数据。
三、自己实现记步算法可以保证算法的稳定性,以及一开始走路就可以立刻开始记步(当然这是不严谨的)
使用样例:
StepDetector Step;//回调接口 StepDetector.StepDetectorCallback callback=new StepDetector.StepDetectorCallback() {@Overridepublic void catchStep(int step) {//获取行走步数,行走步长、行走距离和行走状态Step.getStep();Step.getDistance();Step.getLength();Step.getState();}};//初始化Step=new StepDetector(callback);//传入加速度数据,为三轴加速度的标量和Step.refreshAcceleration(acc);
类型及算法实现代码:
***********************
*by jjwwwww
***********************
import java.util.Timer;
import java.util.TimerTask;public class StepDetector {//回调接口public interface StepDetectorCallback{void catchStep(int step);}//行走状态,WALK行走;STAY静止public enum WalkState{WALK,STAY}//步数private int Step=0;//步长private float Length=0;//行走距离private float distance=0;//定时器相关private Timer timer;private TimerTask task;//最新加速度值private float Acc;//保存之前的加速度个数private int Acc_num=100;//加速度保存的数组private float[] Accs;private int Acc_count=0;//人行状态计算保存数组private float[] Accs_state;//行走状态private WalkState State;//回调函数private StepDetector.StepDetectorCallback mycallback;//需要传入回调函数,或者为nullpublic StepDetector(StepDetector.StepDetectorCallback callback){mycallback=callback;//开启定时器,每20ms一次task=new TimerTask() {@Overridepublic void run() {Detect(Acc);}};timer=new Timer();timer.schedule(task,100,20);Accs=new float[Acc_num];Accs_state=new float[20];}//得到计步数public int getStep(){return this.Step;}//得到步长public float getLength(){return this.Length;}//得到行走距离public float getDistance(){return this.distance;}//得到当前状态public WalkState getState(){return this.State;}//传入加速度,为三轴加速度的标量和public void refreshAcceleration(float acc){this.Acc=acc;}//检测是否走了一步private void Detect(float acc){if(Acc_num>0){Accs[Acc_count]=acc;Accs_state[Acc_count%20]=acc;//状态更新if (Acc_count%20==0){UpdateState();}//检测是否走一步float[] data1=new float[Acc_num];float[] data2=new float[Acc_num];float[] data3=new float[Acc_num];float[] data4=new float[Acc_num];for(int i=0,j=Acc_count;i<Acc_num;i++,j--){if(j<0){j+= Acc_num;}data1[i]=(Accs[j]);}data2[0]=(data1[0]+data1[1])/2;data2[Acc_num-1]=(data1[Acc_num-1]+data1[Acc_num-2])/2;for(int i=1;i<Acc_num-1;i++){data2[i]=data1[i-1]+data1[i]+data1[i+1];data2[i]/=3;}float ave=0f;float ave_offset=0.8f;for(int i=0;i<Acc_num;i++){ave+=data2[i];}ave/=Acc_num;for (int i=1;i<Acc_num-1;i++){data3[i]=(data2[i]-data2[i+1])/20;}for(int i=1;i<Acc_num;i++){if(data3[i-1]*data3[i]<0){if(data3[i]>0&&data2[i]>(ave+ave_offset)){data4[i]=1;}else if(data3[i]<0&&data2[i]<(ave-ave_offset)){data4[i]=-1;}}else if(data3[i]==0&&i<(Acc_num-1)){if(data3[i-1]*data3[i+1]<0){if(data2[i]>(ave+ave_offset)){data4[i]=1;}else if(data2[i]<(ave-ave_offset)){data4[i]=-1;}}}}for(int i=0,j=0,sign=0;i<Acc_num;i++){if(data4[i]!=0){if (sign==1&&data4[i]==1){if(data2[i]>data2[j]){data4[j]=0;j=i;} else{data4[i]=0;}}else if(sign==-1&&data4[i]==-1){if(data2[i]<data2[j]){data4[j]=0;j=i;} else{data4[i]=0;}}else{sign=(int)data4[i];j=i;}}}int index=Acc_num/5;if(data4[index]<0){int up=index;int down=index;for(int i=index+1;i<Acc_num;i++){if(data4[i]>0){up=i;break;}}for(int i=up+1;i<Acc_num;i++){if(data4[i]<0){down=i;break;}}if(down-index>Acc_num/7&&down-index<Acc_num/1.5&&(2*data2[up]-data2[index]-data2[down])>6){int sum=0;for(int i=index+1;i<down;i++){if(data2[i]>ave){sum++;}}//确定走步if(sum>(down-index)/4.5) {Step++;//回调if (mycallback!=null) {mycallback.catchStep(Step);}//步长计算DetectStepLength((down-index)*20,(2*data2[up]-data2[index]-data2[down])/2);}}}if(++Acc_count==Acc_num){Acc_count=0;}}}//步长计算,该公式利用最小二乘法推导出,有一定可信性private void DetectStepLength(int time,float f){float steplength=0.35f-0.000155f*time+0.1638f*(float) Math.sqrt(f);this.Length=(this.Length+steplength)/2;distance+=steplength;}//行走状态更新,利用加速度方差方差private void UpdateState(){float ave=0;float var=0;for(int i=0;i<Accs_state.length;i++){ave+=Accs_state[i];}ave/=Accs_state.length;for(int i=0;i<Accs_state.length;i++){var+=(Accs_state[i]-ave)*(Accs_state[i]-ave);}var/=Accs_state.length;//0.2~0.5为佳if (var<0.4){State=WalkState.STAY;}else{State=WalkState.WALK;}}
}
有不足之处,欢迎指点~~~
Android计步器算法实现(2)
Android计步器算法实现相关推荐
- Android计步器算法实现(2)
Android计步器算法实现(2) 前言 算法实现的意义 现实原因 优缺点 算法原理 运动状态判断 计步原理 步长计算原理 Java实现 补充 观测点的作用 数据的存放方式 前言 在之前我也写过两篇关 ...
- 一种基于陀螺仪传感器的准确计步器算法
一种基于陀螺仪传感器的准确计步器算法 A Gyroscope Based Accurate Pedometer Algorithm 作者:Sampath Jayalath.Nimsiri Abhaya ...
- Android计步器的实现(1)
最近项目中要加一个计步器的功能,Github上搜索一堆,都是bug漫天飞(微信也有bug^_^,关于bug的原因有:异常开关机.调整手机时间. 正常开关机.跨天问题,这几种原因复合在一起更容易造成计步 ...
- # Pedometer 计步器算法简介
Pedometer 计步器算法简介 以Android 6.0 M 为例,它为Pedometer计步器(以下简称Pedo)提供了两颗虚拟传感器(以下用sensor):Step Counter和Step ...
- android 计步器
我们经常会看到微信 QQ 以及其他一些运动app里面都有一个计步功能,那它是怎么实现的呢? 今天我们就来实现一下,以下代码都是从一个整体项目中抽离出来的,为了理解简单方便我把UI部分数据保存部分全部都 ...
- android 计步器 开发,Android计步器开发
本文只赘述Android计步器开发里计步的原理. 在Android4.4版本之后,新增了STEP_COUNTER和STEP_DECTECTOR STEP_COUNTER表示自从开机以来,你走的步数累计 ...
- Android计步器的实现(2)
上一篇见: Android计步器的实现(1) 2.时间戳工具 public abstract class Util4Pedometer {/*** @return milliseconds since ...
- Android计步器小Demo
描述 android计步器的实现,自定义的一个弧形进度条,记步通过手机的传感器来实现,也就是说不支持传感器的机子(应该很老的了吧)就没有效果.看看效果图: 自定义View public class S ...
- 计步器算法简述和模块使用
计步器作为算法功能模块, 本应该和业务模块分离, 解耦合. 这样也可以更加专注于算法的升级. 我来简述一下计步器算法的实现原理, 给大家一些启发. 1. 算法 对于所有计步器而言, 早期必然是使用加速 ...
最新文章
- spark scala word2vec 和多层分类感知器在情感分析中的实际应用
- docker: docker安装和镜像下载
- 视频直播技术之iOS端推流
- 过程记录 yolov3目标检测输出目标坐标和原图物体像素坐标比较
- ADO.Net 缓冲 插入大型数据
- Socket粘包问题终极解决方案—Netty版(2W字)!
- 创业与老子的顺其自然
- 使用 Rust 构建分布式 Key-Value Store
- mono webservice问题请教
- 我的世界java版地牢种子_我的世界地牢种子坐标解析 地牢种子代码介绍
- VS2019.Net Core智能提示英文转换中文教程
- 【实战】Spring+Spring MVC+Mybatis实战项目之云笔记项目
- 技术团队人员管理:组建团队的方式
- 如何清理占用计算机内存,告诉你如何深度清理电脑内存
- A001-185-2521-李子泓
- 使用Firefox+Tor+FoxyProxy+Noscript+IETab进行安全自由的网上冲浪
- InfoJet Service,一个InfoPath Web表单产品
- centos7安装google浏览器,解决双击无法启动问题
- 明日之后找回原来的服务器,明日之后怎么找回原来的账号
- Arduino+2.4G模块做航模遥控器