Подтвердить что ты не робот

Скорость измерения через iPhone SDK

Мне нужно реализовать собственное приложение для iPhone, чтобы измерить скорость телефона (в основном спидометр). Я знаю, что вы можете сделать это через CoreLocation API довольно легко, но меня беспокоит потребление батареи, поскольку это должно быть измерение в реальном времени, которое может использоваться в течение нескольких часов за раз. Я понимаю, что, хотя вы активно отслеживаете события из LocationManager (хотя я действительно не забочусь о местоположении GPS), он интенсивно заряжается батареями.

Другим очевидным вариантом для изучения будет использование акселерометров, чтобы попытаться вычислить скорость, но в API нет ничего, что могло бы вам помочь. Основываясь на моих исследованиях, это должно быть возможно сделать, но кажется чрезвычайно сложным и подверженным ошибкам. Переход от ускорения к скорости может быть сложным для начала, плюс данные акселерометра iPhone могут быть "шумными". Я знаком с примером SDK, который демонстрирует использование фильтрации низких/высоких частот и т.д. - но я не видел ни одного хорошего примера, показывающего скорость вычисления.

Есть ли у кого-нибудь реальный опыт, с которым они могут поделиться? Код был бы фантастическим, но на самом деле я просто хочу знать, успешно ли это сделал (для долговременного приложения) и какой подход они взяли.

EDIT. У меня есть рабочий прототип, который использует API LocationManager. Он работает нормально, но цикл обновления далеко не идеален для измерения скорости в реальном времени. В зависимости от обстоятельств иногда может потребоваться до 4-5 секунд для обновления. Круиз на заданной скорости имеет тенденцию работать нормально, но ускорение/торможение имеют тенденцию сильно отставать от точки зрения пользователя. Кроме того, мне нужно передавать скорость в некоторые другие вычисления, которые я делаю, и точность не в том, что мне нужно.

Кажется возможным, исходя из (очень немногих) других приложений, которые я видел, особенно gMeter, который утверждает, что не использует GPS но точно вычисляет скорость. Я действительно удивлен, что нет ссылок или каких-либо примеров кода, демонстрирующих это где-нибудь, что я могу найти. Я понимаю, что он сложный, но, безусловно, там что-то есть.

4b9b3361

Ответ 1

Поскольку GPS и акселерометр имеют разные недостатки, ваш лучший вариант - это, вероятно, комбинированный подход. Получите измерение от GPS каждую минуту или около того, а затем добавьте изменения в реальном времени с акселерометра.

Ответ 2

С практической точки зрения, вы не получите точной скорости от сил, действующих на акселерометр.

Используйте GPS с показаниями, сделанными с интервалом в 1 минуту, и установите GPS для сна между ними.

Вот пример:

SpeedViewController.h

CLLocationManager *locManager;
CLLocationSpeed speed;
NSTimer *timer;

@property (nonantomic,retain) NSTimer *timer;

SpeedViewController.m

#define kRequiredAccuracy 500.0 //meters
#define kMaxAge 10.0 //seconds

- (void)startReadingLocation {
    [locManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

    NSTimeInterval ageInSeconds = [newLocation.timestamp timeIntervalSinceNow];

    //ensure you have an accurate and non-cached reading
    if( newLocation.horizontalAccuracy > kRequiredAccuracy || fabs(ageInSeconds) > kMaxAge )
        return;

    //get current speed    
    currentSpeed = newLocation.speed;

    //this puts the GPS to sleep, saving power
    [locManager stopUpdatingLocation]; 

    //timer fires after 60 seconds, then stops
    self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(timeIntervalEnded:) userInfo:nil repeats:NO];
}

//this is a wrapper method to fit the required selector signature
- (void)timeIntervalEnded:(NSTimer*)timer {
    [self startReadingLocation];
}

Ответ 3

Ошибка ускорения будет накапливаться с течением времени. Лучше всего получить точную скорость от GPS, может быть, раз в минуту или меньше:

distanceTravelled = sqrt( (position2.x-position1.x)^2 + (position2.y-position1.y)^2 )
velocity = distanceTravelled/timeBetweenGPSReadings

(где ^2 означает квадрат)

Затем сделайте частые измерения акселерометра:

newVelocity = oldVelocity + accelerometer*timeBetweenAccelerometerReadings

Ответ 4

Я не уверен, что вы будете очень далеко пытаться отслеживать скорость с помощью акселерометра. Для этого вам необходимо убедиться, что вы захватили КАЖДОЕ ускорение, так как любые пропущенные точки данных указывают на неправильную скорость (это предполагает, что вы, конечно, можете преобразовать указанные значения акселерометра в стандартные единицы). Таким образом, вам придется постоянно запускать акселерометр, который сам засасывает совсем немного сока (и, опять же, вам не гарантируются все ускорения). Я бы рекомендовал использовать CoreLocation.

Ответ 5

Пока я не знаю iPhone API, я кое-что знаю о GPS и инерциальной навигации. Это может быть полезно.

GPS-приемники, с которыми я работал, могут обеспечить прямое измерение скорости с сигналов GPS, которые они получают. Эти измерения более точны, чем данные положения. Я не знаю, предоставляет ли API Apple доступ, или даже если Apple настроил свой приемник для предоставления этих данных. Это будет более эффективный путь для измерения скорости.

Следующий путь, учитывая, что у вас есть данные акселерометра и данные GPS, следует объединить их, как упоминалось ранее другими плакатами и комментариями. Использование GPS для периодической корректировки накопленного промежуточного измерения из данных акселерометра на практике очень хорошо работает. Это обеспечивает более частые измерения акселерометра и точность измерений GPS. Обычно используется фильтр Калмана. Но с учетом пределов точности и времени вашей выбранной платформы фильтр kalman может быть чрезмерным, а что-то более простое в реализации и запуске должно работать нормально.

Во всяком случае, нужно лишь кое-что подумать.