我试图在不使用iPhone / Xcode中的设备GPS的情况下获得车速,下面是我尝试的代码,但它不在车上工作,它只在行走时返回速度 - 运行
我尝试根据CoreMotion加速度值计算速度,然后将速度值转换为mph。
#import "ViewController.h"
#import "HighpassFilter.h"
#import "GraphVC.h"
@import UIKit;
#include <AudioToolbox/AudioToolbox.h>
#define kUpdateFrequency 60.0
static double timeInterval = 1.0/kUpdateFrequency;
@interface ViewController () <GraphVCDelegate>
{
double lastAx[4],lastAy[4],lastAz[4];
int countX, countY, countZ, accCount;
double lastVx, lastVy, lastVz, maxV;
int type;
HighpassFilter * filter;
CMMotionManager * manager;
GraphVC * graphVC;
}
@property (weak, nonatomic) IBOutlet UILabel *speedLabel;
@property (weak, nonatomic) IBOutlet UILabel *xaccLabel;
@property (weak, nonatomic) IBOutlet UILabel *yaccLabel;
@property (weak, nonatomic) IBOutlet UILabel *zaccLabel;
@property (weak, nonatomic) IBOutlet UILabel *maxvLabel;
@property (nonatomic, assign) BOOL paused;
@property (nonatomic, assign) BOOL soundPlayed;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
lastVx = 0, lastVy = 0, lastVz = 0;
accCount = maxV = type = 0;
_soundPlayed = false;
for (int i = 0; i < 4; ++i){
lastAx[i] = lastAy[i] = lastAz[i] = 0;
}
manager = [[CMMotionManager alloc] init];
manager.accelerometerUpdateInterval = timeInterval;
manager.gyroUpdateInterval = timeInterval;
filter = [[HighpassFilter alloc] initWithSampleRate:kUpdateFrequency cutoffFrequency:5.0];
[manager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *data, NSError *error) {
[self outputAccelertion:data];
}];
}
- (void)viewDidAppear:(BOOL)animated{
graphVC = nil;
}
- (void)outputAccelertion:(CMDeviceMotion*)data
{
CMAcceleration acc = [data userAcceleration];
CMAcceleration gacc = [data gravity];
acc.x += gacc.x, acc.y += gacc.y, acc.z += gacc.z;
CMRotationMatrix rot = [data attitude].rotationMatrix;
CMAcceleration accRef;
//first correct the direction
accRef.x = acc.x*rot.m11 + acc.y*rot.m12 + acc.z*rot.m13;
accRef.y = acc.x*rot.m21 + acc.y*rot.m22 + acc.z*rot.m23;
accRef.z = acc.x*rot.m31 + acc.y*rot.m32 + acc.z*rot.m33;
//filter the data
[filter addAcceleration:accRef];
if (!_paused && graphVC && type == 1){
[graphVC.unfiltered addX:accRef.x y:accRef.y z:accRef.z];
[graphVC.filtered addX:filter.x y:filter.y z:filter.z];
}
//add threshold
accRef.x = (fabs(filter.x) < 0.03) ? 0 : filter.x;
accRef.y = (fabs(filter.y) < 0.03) ? 0 : filter.y;
accRef.z = (fabs(filter.z) < 0.03) ? 0 : filter.z;
//we use simpson 3/8 integration method here
accCount = (accCount+1)%4;
lastAx[accCount] = accRef.x, lastAy[accCount] = accRef.y, lastAz[accCount] = accRef.z;
if (!_paused && graphVC && type == 0)
[graphVC.unfiltered addX:lastVx+accRef.x*timeInterval y:lastVy+accRef.y*timeInterval z:lastVz+accRef.z*timeInterval];
if (accCount == 3){
lastVx += (lastAx[0]+lastAx[1]*3+lastAx[2]*3+lastAx[3]) * 0.125 * timeInterval * 3;
lastVy += (lastAy[0]+lastAy[1]*3+lastAy[2]*3+lastAy[3]) * 0.125 * timeInterval * 3;
lastVz += (lastAz[0]+lastAz[1]*3+lastAz[2]*3+lastAz[3]) * 0.125 * timeInterval * 3;
}
//add a fake force
//(when acc is zero for a continuous time, we should assume that velocity is zero)
if (accRef.x == 0) countX++; else countX = 0;
if (accRef.y == 0) countY++; else countY = 0;
if (accRef.z == 0) countZ++; else countZ = 0;
if (countX == 10){
countX = 0;
lastVx = 0;
}
if (countY == 10){
countY = 0;
lastVy = 0;
}
if (countZ == 10){
countZ = 0;
lastVz = 0;
}
if (!_paused && graphVC && type == 0)
[graphVC.filtered addX:lastVx y:lastVy z:lastVz];
//get total V
double vx = lastVx * 9.8, vy = lastVy * 9.8, vz = lastVz * 9.8;
double lastV = sqrt(vx * vx + vy * vy + vz * vz);
lastV = sqrt(lastV * 2.23694);
[_speedLabel setText:[NSString stringWithFormat:@"%.2f",lastV]];
[_xaccLabel setText:[NSString stringWithFormat:@"%.2f g",accRef.x]];
[_yaccLabel setText:[NSString stringWithFormat:@"%.2f g",accRef.y]];
[_zaccLabel setText:[NSString stringWithFormat:@"%.2f g",accRef.z]];
if (fabs(maxV) < fabs(lastV)){
maxV = lastV;
[_maxvLabel setText:[NSString stringWithFormat:@"%.2f mph", maxV]];
if(maxV > 15 && _soundPlayed==false){
AudioServicesPlaySystemSound(1104);
_soundPlayed = true;
}
}
}
- (void)valueChanged:(int)n{
type = n;
}
@end
提前致谢