デバイスの向きにジャイロとコンパスを使用する小さな屋内ナビゲーション アプリを開発しています。ジャイロを使ってコンパス データを滑らかにします。私のセンサーフュージョンは次のようになります。これは、すべてが発生する私の motionHandler です。
// Listen to events from the motionManager
motionHandler = ^ (CMDeviceMotion *motion, NSError *error) {
__block float heading;
heading = mHeading;
CMAttitude *currentAttitude = motion.attitude;
//Initial heading setting
if (lastHeading == 0 && heading != 0) {
updatedHeading = heading;
}
lastHeading = heading;
if (oldQuaternion.w != 0 || oldQuaternion.x != 0 || oldQuaternion.y != 0 || oldQuaternion.z != 0){
diffQuaternion = [self multiplyQuaternions:[self inverseQuaternion:oldQuaternion] :currentAttitude.quaternion];
diffQuaternion = [self normalizeQuaternion:diffQuaternion];
}
oldQuaternion = currentAttitude.quaternion;
diffYaw = RADIANS_TO_DEGREES([self yawFromQuaternion:diffQuaternion]);
quaternion = currentAttitude.quaternion;
//Get Pitch
rpy.pitch = -[self pitchFromQuaternion:quaternion];
rpy.pitch += M_PI/2;
//Use Yaw-Difference for Heading
updatedHeading = updatedHeading - diffYaw;
//Heading has to be between 0 and 360 degrees
if (updatedHeading < 0) {
updatedHeading = 360 + updatedHeading;
}
else if (updatedHeading > 360) {
updatedHeading -= 360;
}
//fusionate gyro estimated heading with new magneticHeading
updatedHeading = (19.0*updatedHeading + 1.0*heading)/20.0;
//generate queternion
rotation = [self createFromAxisAngle:0 :rpy.pitch :DEGREES_TO_RADIANS(updatedHeading)];
};
実際のセンサー フュージョン式は次の行ですupdatedHeading = (19.0*updatedHeading + 1.0*heading)/20.0;
。そして、これは最新の見出し情報を受け取る私の didUpdateHeading 関数です。
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
// Get new heading
mHeading = newHeading.magneticHeading;
mHeading += 90;
if (mHeading > 360) {
mHeading -= 360;
}
}
diffYaw
は、ジャイロスコープによって計算された方位の変化です。rotation
最後の四元数です。これは、0 度と 360 度の間の移行時という 1 つの特定のケースを除いて、完璧に機能します。
updatedHeading
が 360 に近いが 360 より小さく、 0 のすぐ上にある場合mHeading
、結果は円を描くように移動します。たとえば、updatedHeading
= 355 とmHeading
= 5 の場合、正しい結果は 360 から 5 の間になるはずです。しかし、私の式は 337.5 度を計算します。
この問題には一般的な回避策が必要だと思います…</p>