计步器算法的c语言代码,基于三轴传感器的计步器代码实现-iOS
原有iOS計步器采用系統框架swift語言調用
/// 傳感器
///
/// - Parameter callbcak: 步數steps+距離distance
func caculateSensor(callbcak:@escaping(_ steps:Int,_ distance:Float) ->()) {
if CMPedometer.isStepCountingAvailable() && CMPedometer.isDistanceAvailable() {
self.sensor.startUpdates(from: Date(), withHandler: { (pedometerData:CMPedometerData?, error:Error?) in
if pedometerData != nil {
if pedometerData?.numberOfSteps != nil && pedometerData?.distance != nil{
callbcak(pedometerData?.numberOfSteps as! Int,(pedometerData?.distance?.floatValue)!);
}
}
})
}
}
改為三軸傳感器的計步器實現
圖片.png
開啟陀螺儀采集三軸數據
/**
* 開啟陀螺儀
*/
-(void)startUpdateAccelerometer{
/* 設置采樣的頻率,單位是秒 */
NSTimeInterval updateInterval = 1/30.0; // 每秒采樣30次 ()
/* 判斷是否加速度傳感器可用,如果可用則繼續 */
if ([self.motionManager isAccelerometerAvailable] == YES) {
/* 給采樣頻率賦值,單位是秒 */
[self.motionManager setAccelerometerUpdateInterval:updateInterval];
/* 加速度傳感器開始采樣,每次采樣結果在block中處理 */
[self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
{
CGFloat sqrtValue =sqrt(accelerometerData.acceleration.x*accelerometerData.acceleration.x+accelerometerData.acceleration.y*accelerometerData.acceleration.y+accelerometerData.acceleration.z*accelerometerData.acceleration.z); //采集到的三軸加速度矢量長度
[self detectorNewStep:sqrtValue]; //輸入算法計算
}];
}
}
計步核心
/*
* 檢測步子,并開始計步
* 1.傳入sersor中的數據
* 2.如果檢測到了波峰,并且符合時間差以及閾值的條件,則判定為1步
* 3.符合時間差條件,波峰波谷差值大于initialValue,則將該差值納入閾值的計算中
* */
-(void)detectorNewStep:(float) value{
if (gravityOld == 0) {
gravityOld = value;//第一次記錄
} else {
//如果是波峰
if ([self detectorPeak:value OldValue:gravityOld]) {
timeOfNow = [self nowTimeInterverl];//當前時間
//是否修改初始閥值(ThreadValue=2)兩個波峰的時間差(一步時間)大于0.22s
if (timeOfNow - timeOfLastPeak >= 220
&& (peakOfWave - valleyOfStepMinWave >= initialValue)) {
ThreadValue = [self peak_Valley_thread:(peakOfWave - valleyOfWave)];//調用閥值計算
}
//是否步點 波峰-波谷>=動態閥值ThreadValue
if (timeOfNow - timeOfLastPeak >= 220 && (peakOfWave - valleyOfWave >= ThreadValue)) {
timeOfLastPeak = timeOfNow;;//記錄波峰時間
/*
* 更新界面的處理,不涉及到算法
* 一般在通知更新界面之前,增加下面處理,為了處理無效運動:
* 1.連續記錄10才開始計步
* 2.例如記錄的9步用戶停住超過3秒,則前面的記錄失效,下次從頭開始
* 3.連續記錄了9步用戶還在運動,之前的數據才有效
*
*/
motion_step ++;//步數
is_motion_step_add = true;//is_motion_step_add 是否步數增加(修改波谷最小值)
self.stepCallback(motion_step);//刷新頁面數據
}
}
}
gravityOld = value;
}
波峰檢測
/*
* 檢測波峰
* 以下四個條件判斷為波峰:
* 1.目前點為下降的趨勢:isDirectionUp為false
* 2.之前的點為上升的趨勢:lastStatus為true
* 3.到波峰為止,持續上升大于等于2次
* 4.波峰值大于20
* 記錄波谷值
* 1.觀察波形圖,可以發現在出現步子的地方,波谷的下一個就是波峰,有比較明顯的特征以及差值
* 2.所以要記錄每次的波谷值,為了和下次的波峰做對比
* */
-(BOOL) detectorPeak:(float)newValue OldValue:(float)oldValue{
lastStatus = isDirectionUp;
if (newValue >= oldValue) {// 正在上升
isDirectionUp = YES;
continueUpCount++;
} else {// 下降
continueUpFormerCount = continueUpCount;
continueUpCount = 0;
isDirectionUp = NO;
}
// 此時下降,上一個點狀態是上升 且 (繼續上升的個數 >= 2 或者oldValue > 20)
if (!isDirectionUp && lastStatus
&& (continueUpFormerCount >= 2 || oldValue >= 20)) {// 波峰
peakOfWave = oldValue;
return YES;
} else if (!lastStatus && isDirectionUp) {// 波谷
if (valleyOfWave > oldValue || is_motion_step_add) {//選出波峰到來前的最低波谷值
is_motion_step_add = false;
valleyOfWave = oldValue;
}
return NO;
} else {
return NO;
}
}
閥值的計算
/*
* 閾值的計算
* 1.通過波峰波谷的差值計算閾值
* 2.記錄4個值,存入tempValue[]數組中
* 3.在將數組傳入函數averageValue中計算閾值
*/
-(float)peak_Valley_thread:(float)value{
float tempThread = ThreadValue;
if (tempValue.count < 4) {
tempValue[tempCount] = @(value);
tempCount++;
} else {
tempThread = [self averageValue:tempValue Num:4];
for (int i = 1; i < 4; i++) {
tempValue[i-1] = tempValue[i];
}
tempValue[3] = @(value);
}
return tempThread;
}
/* 梯度化閾值
* 1.計算數組的均值
* 2.通過均值將閾值梯度化在一個范圍里
* */
-(float)averageValue:(NSMutableArray *)value Num:(int)n{
float ave = 0;
for (int i = 0; i < n; i++) {
ave += [value[i] floatValue];
}
ave = ave / 4.0;
if (ave >= 8)
ave = (float) 4.3;
else if (ave >= 7 && ave < 8)
ave = (float) 3.3;
else if (ave >= 4 && ave < 7)
ave = (float) 2.28;
else if (ave >= 3 && ave < 4)
ave = (float) 1.98;
else {
ave = (float) initialValue;//initialValue = 1.1 最低波峰波谷差。
}
return ave;
}
總結
以上是生活随笔為你收集整理的计步器算法的c语言代码,基于三轴传感器的计步器代码实现-iOS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机 桌面黑屏怎么办,电脑黑屏怎么办?
- 下一篇: 软件测试方式汇总