Использование Core Motion для определения высоты и азимута телефона

Казалось бы, это должно быть что-то легкое, но мне просто не везет.

Что я хочу сделать, так это использовать основное движение, чтобы отслеживать, куда направлена ​​камера телефона (для своего рода приложения дополненной реальности). Пользователь наводил телефон на контрольную точку (как если бы фотографировал ее) и нажимал кнопку, чтобы «выровнять» положение телефона с объектом. Теперь, когда пользователь направляет камеру телефона на другие объекты, мне нужно определить изменение высоты телефона (от -90º до +90º) и азимута (от 0º до 360º).

Углы Эйлера, заданные CMAttitude, не кажутся мне нужными. Я попытался кэшировать CMAttitude, полученный, когда пользователь нажимает «выравнивание». Затем, когда пользователь перемещает телефон, я получаю новый CMAttitude и используюmultiByInverseOfAttitude, чтобы определить отличие от эталонного положения.

- (void)checkForMotion {
    CMMotionManager *motionMgr = appDelegate.motionMgr;
    CMDeviceMotion *deviceMotion = motionMgr.deviceMotion;
    CMAttitude *attitude = deviceMotion.attitude;

    if (referenceAttitude != nil) 
    {
        [attitude multiplyByInverseOfAttitude: referenceAttitude];

        double deltaAlt = attitude.pitch;
        double deltaAzm = attitude.roll;

        // Do something with deltaAlt and deltaAz
    }
    else 
    {
        NSLog(@"Getting new referenceAttitude");
        self.referenceAttitude = attitude;
    }
}

Но это просто не дает нужных результатов. Если телефон держать вертикально (длинной осью вверх) то deltaAlt работает нормально. Пока телефон направлен на горизонт (alt = 0), deltaAzm также правильный. Однако, если телефон направлен, скажем, на 45º в небо, то при перемещении телефона по азимуту меняется и высотная составляющая. Эти два переплетены таким образом, что я не могу понять.

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


person btschumy    schedule 21.01.2011    source источник
comment
Вы уже нашли какие-то решения проблемы?   -  person Raj Pawan Gumdal    schedule 24.04.2011


Ответы (1)


В целом ваш подход кажется мне разумным. Я думаю, что это то же самое, что и в демо-приложении Teapot. Может быть, самый простой способ - проверить это и взглянуть на него:

CMMotionManager и гироскоп на iPhone 4

Если вы планируете обрабатывать более сложные движения в будущем, я рекомендую трудный путь, то есть кватернионы. Да, не так просто, но если вы однажды получили это, это очень удобно.

person Kay    schedule 01.02.2011