APP下载

基于Android的人体运动计步器系统的设计与实现

2016-07-04胡东旭蔡文超

电脑知识与技术 2016年15期

胡东旭+蔡文超

摘要:随着Android智能手机的进一步普及,针对Android智能手机内嵌的加速度传感器进行研究,利用人体行走过程中加速度传感器采集数据信息的变化规律,实现对行人脚步探测与计步系统。该系统内容包括两部分:行人运动数据采集与预处理模块设计和行人脚步识别探测模块设计,能够有效的实现运动数据采集、预处理、步态探测和计步的功能。

关键词:Android;加速度传感器;步态探测

中图分类号:TP393 文献标识码:A 文章编号:1009-3044(2016)15-0094-04

Abstract: With the further popularization of Android smartphones, aimed at the acceleration sensor embedded in the Android smartphone conduct a study , based on the changing law of the data information collected by the acceleration sensor during the walking process of human body to realize the pedestrian detection and measurement system. The system consist of two parts: data acquisition and pretreatment module design and pedestrian detection module design, it can effectively achieve the movement of data acquisition, pre-processing, gait detection and step counter function.

Key words: Android; acceleration sensor; gait detection

随着科技的发展,多功能智能设备的应用越来越受到人们的关注,智能手机作为人们工作生活中的必需品,不断地为人们带来快捷和方便。同时,由于人们对日常健康的关注程度逐渐增加,渴望能够实时获得自身的运动量以便对运动情况进行规划。当今市场上,常用的人体运动量检测应用多为计步器,但在实际使用中需要额外的硬件设备。本文将以Android平台为例,介绍智能手机计步器系统的软件设计、开发流程,实现仅依靠智能手机的日常运动计步器系统的设计。

1 系统相关技术分析

1.1 Android及传感器

Android是一种基于Linux平台的开放源代码的操作系统[1],主要用于便携设备。Android系统采用分层架构,分为四层:应用程序层、应用程序框架层、系统运行库层和Linux内核层。Android系统具有优秀的多种传感器支持特性,可支持加速度传感器、陀螺仪、磁力计、温度传感器、压力传感器等多种传感器。在Android平台下开发基于传感器的应用时,只需在程序注册相应的传感器监听器即可,因此本文选用Android平台进行计步器系统的开发。

1.2 开发环境

系统主要包括两大模块:行人运动数据采集与预处理模块和行人脚步识别探测模块。行人运动数据采集与预处理模块基于Android手机内部嵌入的加速度传感器开发,将加速度传感器监测的数据进行预处理后,送入行人脚步识别探测模块,根据行人脚步运动数据存在周期性,得到行人是否完成单步的运动。本系统主要运行Android SDK和Eclipse共同开发,实现实现运动数据采集、预处理、步态探测和计步的功能。

2 系统设计

本系统框架结构主要分为数据采集与处理和脚步探测两大部分。

2.1 数据采集与处理模块设计

数据采集模块主要通过Android手机内部嵌入的加速度传感器进行运动数据的采集,由于手机内部加速度传感器通常受到体积的限制,精度不高。因此,需要对采集的数据进行滤波,本模块采用截止频率为0.25Hz的一阶低通滤波,滤除连续数据序列中存在的数据波动、畸变点等。

2.2 脚步探测模块设计

脚步探测模块主要根据人体行走过程中加速度出现的周期性正弦变化特征,采用波峰检测的原理,通过检测加速度正弦波中连续波峰和波谷个数来识别步态[2],若检测到两个连续的波峰则记为一步。但由于运动规律或行走过程中人体的抖动等影响,加速度数据会产生伪波峰或伪波谷,进而导致步态的误判[3]。因此,基于波峰检测的计步算法中,需要甄别伪波峰与伪波谷,获得真实步态信息。为滤除伪波峰与为波谷,提高步态探测算法精度,需要解决一下几个问题:

1)滤除无效震动:由于移动终端的嵌入式传感器受到成本、体积等因素的限制,精度不高,容易受到轻微震动的影响。本文通过实验测得,在静止状况下,合加速度在9.7附近波动,且范围较小。本文设定加速度波动范围为0.3,即当合加速度之在9.4~10.0之间变化时,视为无效震动。

2)动态阈值:由于用户每一步产生的波峰波谷值不同,所以简单的设定固定的阈值进行峰谷判断,将会存在误判。本文根据行人每次单步的相似性与连贯性设置一个动态阈值,具体如下:阈值的初始化值为9.7,后续阈值为前一步的峰值与谷值的均值,进而实现动态阈值判断,增加步态检测的自适应性。

3)时间窗口检测:由于人体正常行走频率为0.5Hz-5Hz,单步周期为0.2s-2s,因此两个连续迈步起点的时间差介于0.2s-2s,如果连续两步的时间间隔小于0.2s或大于2s,则所测步伐无效,将新的阈值点设为迈步起点重新开始计步[4]。

具体的脚步探测算法流程如图1所示:首先,对参数进行初始化,包括初始阈值设置、时间窗口检测时间设置、滤波系数设置等;然后判断迈步起点,若某点符合要求,则从此点开始记录采集的传感器数据,并根据时间窗口的大小进行波峰波谷的检测,若峰谷值符合加速度精度要求,则计一步,同时更新动态阈值。

3 系统开发实现

3.1 数据采集及预处理

首先通过SensorManager注册系统所有传感器的管理器,再通过调用getDefaultSensor()方法来得到任意的传感器类型,并通过SensorEventListener实现对传感器输出信号的监听[5]。当监听到传感器信号输出时,调用checkForStep()函数,并在其内完成对采集的加速度数据的预处理。主要实现代码如下:

public StepDetection(Context context){

stepCount=0;

fengzhi=0.0f; //初始化峰值,用于第一步的启动及判断

guzhi=0.0f; //初始化谷值,用于第一步的起点及判断

yuzhi=9.7f; //初始化阈值,用于第二步起点判断

mSensorManager=(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);

}

/**

*处理传感器事件

*/

public SensorEventListener mSensorEventListener = new SensorEventListener() {

@SuppressWarnings("deprecation")

@Override

public void onSensorChanged(SensorEvent event) {

switch(event.sensor.getType()) {

case Sensor.TYPE_ACCELEROMETER:

checkForStep(event);

break;

default:

break;

}}

@Override

public void onAccuracyChanged(Sensor sensor, int accuracy) {

}};

/**

* 注册传感器

*/

@SuppressWarnings("deprecation")

public void startSensor() {

//Log.i(TAG, "[StepDetection] startSensor");

mSensorManager.registerListener(mSensorEventListener,

mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),

SensorManager.SENSOR_DELAY_GAME);}

/**

* 注销传感器

*/

public void stopSensor() {

mSensorManager.unregisterListener(mSensorEventListener);

accelList.clear();}

/**

* 脚步探测算法,利用行走的加速度特征判断脚步

*/

private void checkForStep(SensorEvent event) {

System.arraycopy(event.values,0,accel,0,3);

accelList.add(accel);

I++;

ListmagnitudeOfAccel=

StepDetectionUtil.getMagnitudeOfAccel(accelList,i); //计算合加速度

accelList.add(accel);

i++;

ListmagnitudeOfAccel=

StepDetectionUtil.getMagnitudeOfAccel(accelList,i);//计算和加速度

if(StepDetectionUtil.getIndexOFStart(magnitudeOfAccel,yuzhi)){//计步判断

stepCount++; //步数加1

STEPDETECTED=true; //设置单步完成标志

yuzhi=StepDetectionUtil.getYuzhi(); //更新阈值

StepDetectionUtil.resetArray();

accelList.clear(); //计步结束,清除加速度数据列表

flag=true;

i=0; }}

在checkForStep()函数中,将加速度传感器采集获得的数据添加到加速度数据列表acceList,并调用StepDetectionUtil辅助类中getMagnitudeOfAccel()函数。在getMagnitudeOfAccel()函数中,先求出瞬时加速度的合macc,并将其送入低通滤波函数LFValues(),将滤波后的合加速度存入magnitudeAccel列表。至此,完成了整个计步过程中数据采集及预处理模块的设计与软件实现。数据预处理主要实现代码如下:

/**

* 计算合加速度(引入低通滤波)

*/

public static List getMagnitudeOfAccel(List accelList,int i) {

float[] accel = new float[3]; // acc: acceleration of x, y, z

float macc = 0; // macc: magnitude of the acceleration

accel=accelList.get(i); // 取出刚才采集的加速度数值

macc = (float) Math.sqrt(accel[0] * accel[0] + accel[1] * accel[1] + accel[2] * accel[2]);

lastValues=LFValues(lastValues,macc); //调用低通滤波函数LFValues

magnitudeAccel.add(lastValues);

return magnitudeAccel;

}

/**

*一阶低通滤波器(基于限幅滤波算法)

*/

public static float LFValues(float value1,float value2){

if((value1-value2>LFTHRESHOLD)||(value2-value1)>LFTHRESHOLD)

// LFTHRESHOL为设置低通滤波器限定幅值差

return value2;

return value1;

}

3.2 脚步探测模块设计

在checkForStep()函数中,根据StepDetectionUtil.getIndexOFStart(magnitudeOfAccel,yuzhi)对合加速度与阈值的判断,是否满足单步完成条件。首先将合加速度列表中数据与单步完成时设置的阈值进行比较,当满足上下浮动不超过0.4时,再进行时间窗口判断,由于单步完成时间在0.2-2s之间,所以满足以上两个条件的点为单步完成时落脚点。在计步判断完成时,同时根据新一步的峰谷值更新单步完成时的阈值。主要实现代码如下所示:

/**

*起点判断,包括阈值判断、时间窗口检测、峰谷值更新

*/

public static boolean getIndexOFStart(ListmagnitudeAccel,float threshold){

Iterator it=magnitudeAccel.iterator();

float values;

int index=0;

while(it.hasNext()){

values=it.next();

if((values-threshold<=0.4)||(threshold-values<=0.4)){

if((index>=10)&&(index<=100)){ //时间窗口判断

toplow=getTopLowValues( magnitudeAccel);//更新峰谷值

return true; }}

index++;}

return false; }

/**

*计算峰谷值

*/

public static List getTopLowValues(List magnitudeAccel){

float topvalues=G; //G为初始设置的峰谷值9.7,辅助进行峰谷值的搜索

float lowvalues=G;

float takeOut;

List values=new ArrayList();

Iterator it =magnitudeAccel.iterator();

while(it.hasNext()){

takeOut=it.next();

if(takeOut>=topvalues){ //峰值搜索,更新

topvalues=takeOut;

}else if(takeOut<=lowvalues){ //谷值搜索,更新

lowvalues=takeOut; }}

values.add(topvalues);

values.add(lowvalues);

return values; }

/**

* 获取阈值

*/

public static float getYuzhi(){

return (getThreshold(toplow)); } //toplow为getTopLowValues()函数返回值

/**

* 计算单步完成判断阈值(动态阈值更新)

*/

public static float getThreshold(List topAndlow){

float threshold=9.7f;

Iterator it=topAndlow.iterator();

float topValue=0.0f;

float lowValue=0.0f;

int i=0;

while(it.hasNext()){ //分别取出峰谷值

if(i==0){

topValue=it.next();

i++;

}else{

lowValue=it.next();}}

if(topValue!=0 && lowValue!=0 && topValue!=lowValue){

threshold=(topValue+lowValue)/2; } // 峰谷值进行阈值更新

return threshold; } //返回新阈值用于下一步判断

4 结束语

本文基于Android平台进行传感器的应用开发,根据对人体运动时步态机理的分析,设计了改进型实用计步器算法。整个计步器系统,首先通过对传感器数据采集及预处理,降低了噪声干扰。其次,根据算法设计原理,根据阈值判断、时间窗口检测完成单步完成的判断。最后,根据单步内的合加速度数值进行峰谷值的搜索,并更新阈值判断数值,完成了整个计步系统的设计。

参考文献:

[1] 软件开发技术联盟. Android开发实战[M]. 北京: 清华大学出版社, 2013: 3-6.

[2] Lan KunChan, Shih WenYuah. Using smart-phones and floor plans for indoor location tracking[J]. IEEE Transactions on Human-Machine Systems, 2014, 44(2): 211-221.

[3] 陈国良, 李飞, 张言哲. 一种基于自适应波峰检测的MEMS计步算法[J]. 中国惯性技术学报, 2015, 23(3): 315-321.

[4] 张世哲. 基于惯性传感器和WiFi的室内定位系统的设计与实现[D]. 北京: 北京邮电大学, 2012.

[5] 郭霖. 第一行代码[M]. 北京: 人民邮电出版社, 2014: 441-447.