胡東旭+蔡文超
摘要:隨著Android智能手機(jī)的進(jìn)一步普及,針對Android智能手機(jī)內(nèi)嵌的加速度傳感器進(jìn)行研究,利用人體行走過程中加速度傳感器采集數(shù)據(jù)信息的變化規(guī)律,實(shí)現(xiàn)對行人腳步探測與計(jì)步系統(tǒng)。該系統(tǒng)內(nèi)容包括兩部分:行人運(yùn)動(dòng)數(shù)據(jù)采集與預(yù)處理模塊設(shè)計(jì)和行人腳步識(shí)別探測模塊設(shè)計(jì),能夠有效的實(shí)現(xiàn)運(yùn)動(dòng)數(shù)據(jù)采集、預(yù)處理、步態(tài)探測和計(jì)步的功能。
關(guān)鍵詞:Android;加速度傳感器;步態(tài)探測
中圖分類號:TP393 文獻(xiàn)標(biāo)識(shí)碼: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
隨著科技的發(fā)展,多功能智能設(shè)備的應(yīng)用越來越受到人們的關(guān)注,智能手機(jī)作為人們工作生活中的必需品,不斷地為人們帶來快捷和方便。同時(shí),由于人們對日常健康的關(guān)注程度逐漸增加,渴望能夠?qū)崟r(shí)獲得自身的運(yùn)動(dòng)量以便對運(yùn)動(dòng)情況進(jìn)行規(guī)劃。當(dāng)今市場上,常用的人體運(yùn)動(dòng)量檢測應(yīng)用多為計(jì)步器,但在實(shí)際使用中需要額外的硬件設(shè)備。本文將以Android平臺(tái)為例,介紹智能手機(jī)計(jì)步器系統(tǒng)的軟件設(shè)計(jì)、開發(fā)流程,實(shí)現(xiàn)僅依靠智能手機(jī)的日常運(yùn)動(dòng)計(jì)步器系統(tǒng)的設(shè)計(jì)。
1 系統(tǒng)相關(guān)技術(shù)分析
1.1 Android及傳感器
Android是一種基于Linux平臺(tái)的開放源代碼的操作系統(tǒng)[1],主要用于便攜設(shè)備。Android系統(tǒng)采用分層架構(gòu),分為四層:應(yīng)用程序?qū)印?yīng)用程序框架層、系統(tǒng)運(yùn)行庫層和Linux內(nèi)核層。Android系統(tǒng)具有優(yōu)秀的多種傳感器支持特性,可支持加速度傳感器、陀螺儀、磁力計(jì)、溫度傳感器、壓力傳感器等多種傳感器。在Android平臺(tái)下開發(fā)基于傳感器的應(yīng)用時(shí),只需在程序注冊相應(yīng)的傳感器監(jiān)聽器即可,因此本文選用Android平臺(tái)進(jìn)行計(jì)步器系統(tǒng)的開發(fā)。
1.2 開發(fā)環(huán)境
系統(tǒng)主要包括兩大模塊:行人運(yùn)動(dòng)數(shù)據(jù)采集與預(yù)處理模塊和行人腳步識(shí)別探測模塊。行人運(yùn)動(dòng)數(shù)據(jù)采集與預(yù)處理模塊基于Android手機(jī)內(nèi)部嵌入的加速度傳感器開發(fā),將加速度傳感器監(jiān)測的數(shù)據(jù)進(jìn)行預(yù)處理后,送入行人腳步識(shí)別探測模塊,根據(jù)行人腳步運(yùn)動(dòng)數(shù)據(jù)存在周期性,得到行人是否完成單步的運(yùn)動(dòng)。本系統(tǒng)主要運(yùn)行Android SDK和Eclipse共同開發(fā),實(shí)現(xiàn)實(shí)現(xiàn)運(yùn)動(dòng)數(shù)據(jù)采集、預(yù)處理、步態(tài)探測和計(jì)步的功能。
2 系統(tǒng)設(shè)計(jì)
本系統(tǒng)框架結(jié)構(gòu)主要分為數(shù)據(jù)采集與處理和腳步探測兩大部分。
2.1 數(shù)據(jù)采集與處理模塊設(shè)計(jì)
數(shù)據(jù)采集模塊主要通過Android手機(jī)內(nèi)部嵌入的加速度傳感器進(jìn)行運(yùn)動(dòng)數(shù)據(jù)的采集,由于手機(jī)內(nèi)部加速度傳感器通常受到體積的限制,精度不高。因此,需要對采集的數(shù)據(jù)進(jìn)行濾波,本模塊采用截止頻率為0.25Hz的一階低通濾波,濾除連續(xù)數(shù)據(jù)序列中存在的數(shù)據(jù)波動(dòng)、畸變點(diǎn)等。
2.2 腳步探測模塊設(shè)計(jì)
腳步探測模塊主要根據(jù)人體行走過程中加速度出現(xiàn)的周期性正弦變化特征,采用波峰檢測的原理,通過檢測加速度正弦波中連續(xù)波峰和波谷個(gè)數(shù)來識(shí)別步態(tài)[2],若檢測到兩個(gè)連續(xù)的波峰則記為一步。但由于運(yùn)動(dòng)規(guī)律或行走過程中人體的抖動(dòng)等影響,加速度數(shù)據(jù)會(huì)產(chǎn)生偽波峰或偽波谷,進(jìn)而導(dǎo)致步態(tài)的誤判[3]。因此,基于波峰檢測的計(jì)步算法中,需要甄別偽波峰與偽波谷,獲得真實(shí)步態(tài)信息。為濾除偽波峰與為波谷,提高步態(tài)探測算法精度,需要解決一下幾個(gè)問題:
1)濾除無效震動(dòng):由于移動(dòng)終端的嵌入式傳感器受到成本、體積等因素的限制,精度不高,容易受到輕微震動(dòng)的影響。本文通過實(shí)驗(yàn)測得,在靜止?fàn)顩r下,合加速度在9.7附近波動(dòng),且范圍較小。本文設(shè)定加速度波動(dòng)范圍為0.3,即當(dāng)合加速度之在9.4~10.0之間變化時(shí),視為無效震動(dòng)。
2)動(dòng)態(tài)閾值:由于用戶每一步產(chǎn)生的波峰波谷值不同,所以簡單的設(shè)定固定的閾值進(jìn)行峰谷判斷,將會(huì)存在誤判。本文根據(jù)行人每次單步的相似性與連貫性設(shè)置一個(gè)動(dòng)態(tài)閾值,具體如下:閾值的初始化值為9.7,后續(xù)閾值為前一步的峰值與谷值的均值,進(jìn)而實(shí)現(xiàn)動(dòng)態(tài)閾值判斷,增加步態(tài)檢測的自適應(yīng)性。
3)時(shí)間窗口檢測:由于人體正常行走頻率為0.5Hz-5Hz,單步周期為0.2s-2s,因此兩個(gè)連續(xù)邁步起點(diǎn)的時(shí)間差介于0.2s-2s,如果連續(xù)兩步的時(shí)間間隔小于0.2s或大于2s,則所測步伐無效,將新的閾值點(diǎn)設(shè)為邁步起點(diǎn)重新開始計(jì)步[4]。
具體的腳步探測算法流程如圖1所示:首先,對參數(shù)進(jìn)行初始化,包括初始閾值設(shè)置、時(shí)間窗口檢測時(shí)間設(shè)置、濾波系數(shù)設(shè)置等;然后判斷邁步起點(diǎn),若某點(diǎn)符合要求,則從此點(diǎn)開始記錄采集的傳感器數(shù)據(jù),并根據(jù)時(shí)間窗口的大小進(jìn)行波峰波谷的檢測,若峰谷值符合加速度精度要求,則計(jì)一步,同時(shí)更新動(dòng)態(tài)閾值。
3 系統(tǒng)開發(fā)實(shí)現(xiàn)
3.1 數(shù)據(jù)采集及預(yù)處理
首先通過SensorManager注冊系統(tǒng)所有傳感器的管理器,再通過調(diào)用getDefaultSensor()方法來得到任意的傳感器類型,并通過SensorEventListener實(shí)現(xiàn)對傳感器輸出信號的監(jiān)聽[5]。當(dāng)監(jiān)聽到傳感器信號輸出時(shí),調(diào)用checkForStep()函數(shù),并在其內(nèi)完成對采集的加速度數(shù)據(jù)的預(yù)處理。主要實(shí)現(xiàn)代碼如下:
public StepDetection(Context context){
stepCount=0;
fengzhi=0.0f; //初始化峰值,用于第一步的啟動(dòng)及判斷
guzhi=0.0f; //初始化谷值,用于第一步的起點(diǎn)及判斷
yuzhi=9.7f; //初始化閾值,用于第二步起點(diǎn)判斷
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++;
List
StepDetectionUtil.getMagnitudeOfAccel(accelList,i); //計(jì)算合加速度
accelList.add(accel);
i++;
List
StepDetectionUtil.getMagnitudeOfAccel(accelList,i);//計(jì)算和加速度
if(StepDetectionUtil.getIndexOFStart(magnitudeOfAccel,yuzhi)){//計(jì)步判斷
stepCount++; //步數(shù)加1
STEPDETECTED=true; //設(shè)置單步完成標(biāo)志
yuzhi=StepDetectionUtil.getYuzhi(); //更新閾值
StepDetectionUtil.resetArray();
accelList.clear(); //計(jì)步結(jié)束,清除加速度數(shù)據(jù)列表
flag=true;
i=0; }}
在checkForStep()函數(shù)中,將加速度傳感器采集獲得的數(shù)據(jù)添加到加速度數(shù)據(jù)列表acceList,并調(diào)用StepDetectionUtil輔助類中g(shù)etMagnitudeOfAccel()函數(shù)。在getMagnitudeOfAccel()函數(shù)中,先求出瞬時(shí)加速度的合macc,并將其送入低通濾波函數(shù)LFValues(),將濾波后的合加速度存入magnitudeAccel列表。至此,完成了整個(gè)計(jì)步過程中數(shù)據(jù)采集及預(yù)處理模塊的設(shè)計(jì)與軟件實(shí)現(xiàn)。數(shù)據(jù)預(yù)處理主要實(shí)現(xiàn)代碼如下:
/**
* 計(jì)算合加速度(引入低通濾波)
*/
public static List
float[] accel = new float[3]; // acc: acceleration of x, y, z
float macc = 0; // macc: magnitude of the acceleration
accel=accelList.get(i); // 取出剛才采集的加速度數(shù)值
macc = (float) Math.sqrt(accel[0] * accel[0] + accel[1] * accel[1] + accel[2] * accel[2]);
lastValues=LFValues(lastValues,macc); //調(diào)用低通濾波函數(shù)LFValues
magnitudeAccel.add(lastValues);
return magnitudeAccel;
}
/**
*一階低通濾波器(基于限幅濾波算法)
*/
public static float LFValues(float value1,float value2){
if((value1-value2>LFTHRESHOLD)||(value2-value1)>LFTHRESHOLD)
// LFTHRESHOL為設(shè)置低通濾波器限定幅值差
return value2;
return value1;
}
3.2 腳步探測模塊設(shè)計(jì)
在checkForStep()函數(shù)中,根據(jù)StepDetectionUtil.getIndexOFStart(magnitudeOfAccel,yuzhi)對合加速度與閾值的判斷,是否滿足單步完成條件。首先將合加速度列表中數(shù)據(jù)與單步完成時(shí)設(shè)置的閾值進(jìn)行比較,當(dāng)滿足上下浮動(dòng)不超過0.4時(shí),再進(jìn)行時(shí)間窗口判斷,由于單步完成時(shí)間在0.2-2s之間,所以滿足以上兩個(gè)條件的點(diǎn)為單步完成時(shí)落腳點(diǎn)。在計(jì)步判斷完成時(shí),同時(shí)根據(jù)新一步的峰谷值更新單步完成時(shí)的閾值。主要實(shí)現(xiàn)代碼如下所示:
/**
*起點(diǎn)判斷,包括閾值判斷、時(shí)間窗口檢測、峰谷值更新
*/
public static boolean getIndexOFStart(List
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)){ //時(shí)間窗口判斷
toplow=getTopLowValues( magnitudeAccel);//更新峰谷值
return true; }}
index++;}
return false; }
/**
*計(jì)算峰谷值
*/
public static List
float topvalues=G; //G為初始設(shè)置的峰谷值9.7,輔助進(jìn)行峰谷值的搜索
float lowvalues=G;
float takeOut;
List
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()函數(shù)返回值
/**
* 計(jì)算單步完成判斷閾值(動(dòng)態(tài)閾值更新)
*/
public static float getThreshold(List
float threshold=9.7f;
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; } // 峰谷值進(jìn)行閾值更新
return threshold; } //返回新閾值用于下一步判斷
4 結(jié)束語
本文基于Android平臺(tái)進(jìn)行傳感器的應(yīng)用開發(fā),根據(jù)對人體運(yùn)動(dòng)時(shí)步態(tài)機(jī)理的分析,設(shè)計(jì)了改進(jìn)型實(shí)用計(jì)步器算法。整個(gè)計(jì)步器系統(tǒng),首先通過對傳感器數(shù)據(jù)采集及預(yù)處理,降低了噪聲干擾。其次,根據(jù)算法設(shè)計(jì)原理,根據(jù)閾值判斷、時(shí)間窗口檢測完成單步完成的判斷。最后,根據(jù)單步內(nèi)的合加速度數(shù)值進(jìn)行峰谷值的搜索,并更新閾值判斷數(shù)值,完成了整個(gè)計(jì)步系統(tǒng)的設(shè)計(jì)。
參考文獻(xiàn):
[1] 軟件開發(fā)技術(shù)聯(lián)盟. Android開發(fā)實(shí)戰(zhàn)[M]. 北京: 清華大學(xué)出版社, 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] 陳國良, 李飛, 張言哲. 一種基于自適應(yīng)波峰檢測的MEMS計(jì)步算法[J]. 中國慣性技術(shù)學(xué)報(bào), 2015, 23(3): 315-321.
[4] 張世哲. 基于慣性傳感器和WiFi的室內(nèi)定位系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D]. 北京: 北京郵電大學(xué), 2012.
[5] 郭霖. 第一行代碼[M]. 北京: 人民郵電出版社, 2014: 441-447.