2013-05-13 45 views
11

Tôi có một ứng dụng ghi lại các góc khi người dùng đang đi quanh một vật thể, trong khi thiết bị trỏ (tốt nhất) ở giữa đối tượng. Góc được đặt lại trên lệnh của người dùng - do đó thái độ tham chiếu được đặt lại.Thay đổi thái độ - góc và trục - toán học quaternion

Sử dụng Góc Euler sản xuất khóa Gimbal, vì vậy tôi hiện đang sử dụng quaternion và tính góc theo cách này:

double angleFromLastPosition = acos(fromLastPositionAttitude.quaternion.w) * 2.0f; 

này cho ra độ chính xác tốt và nó hoạt động hoàn hảo NẾU sân và yaw của thiết bị không thay đổi. Nói cách khác, khi góc hiển thị 360 độ, tôi kết thúc ở cùng một vị trí với phần đầu của vòng tròn.

Bài toán 1: nếu thiết bị yaw và pitch thay đổi nhẹ (người dùng không chỉ trực tiếp vào tâm của đối tượng), do đó, hãy sử dụng angleFromLastPosition. Tôi hiểu phần này, vì công thức góc của tôi chỉ cho thấy góc ở giữa hai thái độ thiết bị trong không gian 3D.

Kịch bản:

  • tôi đánh dấu sự bắt đầu của thái độ luân chuyển và bắt đầu di chuyển trong một vòng tròn xung quanh đối tượng trong khi chỉ vào trung tâm
  • tôi dừng lại ở, nói rằng, 45 độ và thay đổi độ cao của các thiết bị bằng cách chỉ nó cao hơn hoặc thấp hơn. Góc thay đổi tương ứng.
  • Điều tôi muốn thấy là: góc nằm ở 45 độ, ngay cả khi thay đổi độ cao hoặc thay đổi.

Câu hỏi 1 là, làm cách nào tôi có thể tính toán cuộn của thiết bị bằng cách sử dụng quaternions và bỏ qua các thay đổi trong hai trục khác (ít nhất là trong một số độ hợp lý).

Vấn đề 2: nếu tôi xoay một chút và sau đó đóng băng thiết bị hoàn toàn (trên chân máy để không rung chút nào), góc AngleFromLastPosition trôi ở tốc độ 1 độ trong khoảng 10-20 giây và dường như không là tuyến tính. Nói cách khác, nó trôi nhanh vào lúc đầu, sau đó làm chậm đáng kể. Đôi khi tôi không bị trôi dạt chút nào - góc là đá cứng nếu thiết bị dừng. Và điều này làm tôi mất đi sự hiểu biết những gì đang xảy ra.

Câu hỏi 2, những gì đang xảy ra ở đây và làm thế nào tôi có thể xử lý sự trôi dạt?

Tôi đã đi qua một số bài viết và hướng dẫn, và toán học bậc bốn là ngoài tôi vào lúc này, hy vọng ai đó sẽ có thể giúp đỡ với một mẹo, liên kết, hoặc vài dòng mã.

+0

có thể trôi dạt có liên quan đến [Drifting Yaw] (http://stackoverflow.com/questions/13613239/drifting-yaw-angle-after-moving-fast?rq=1)? nếu có, việc tìm kiếm công thức cho câu hỏi 1 sẽ xử lý cả hai vấn đề :) –

+0

Nếu bạn đang sử dụng CMAttitude, có lý do cụ thể nào mà bạn không thể sử dụng từLastPositionAttitude.roll để có được cuộn thiết bị không? Tôi đánh giá cao điều này là không sử dụng tài sản quaternion, nhưng nó có để được sử dụng! –

+0

có, bắt đầu với điều đó - bằng cách sử dụng góc euler sản xuất một khóa gimbal và mất độ tự do. quay hoàn toàn không phải là 360 độ khi thiết bị không được căn chỉnh với trục Z. ít nhất đây là sự hiểu biết của tôi về hiệu ứng .... –

Trả lời

4

Tôi đã thử nghiệm điều này và có vẻ như hoạt động theo những gì bạn đang tìm kiếm trong Câu hỏi 1, Andrei.

Tôi đặt đồng hồ ban đầu ban đầu là 0 và ngay sau thẻ đầu tiên tôi lưu trữ góc được trả về từ walkaroundAngleFromAttitude: fromHomeAngle: trong chế độ đồng hồ, để sử dụng sau này.

thử nghiệm của tôi bao gồm bắt đầu cập nhật thiết bị sử dụng một hệ quy chiếu:

[_motionManager 
startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical 
toQueue:operationQueue 
withHandler:handler]; 

và sử dụng các phương pháp sau đây gọi là trong phạm vi xử lý:

- (CMQuaternion) multiplyQuanternion:(CMQuaternion)left withRight:(CMQuaternion)right { 

    CMQuaternion newQ; 
    newQ.w = left.w*right.w - left.x*right.x - left.y*right.y - left.z*right.z; 
    newQ.x = left.w*right.x + left.x*right.w + left.y*right.z - left.z*right.y; 
    newQ.y = left.w*right.y + left.y*right.w + left.z*right.x - left.x*right.z; 
    newQ.z = left.w*right.z + left.z*right.w + left.x*right.y - left.y*right.x; 

    return newQ; 
} 

-(float)walkaroundRawAngleFromAttitude:(CMAttitude*)attitude { 

    CMQuaternion e = (CMQuaternion){0,0,1,1}; 
    CMQuaternion quatConj = attitude.quaternion; 
    quatConj.x *= -1; quatConj.y *= -1; quatConj.z *= -1; 
    CMQuaternion quat1 = attitude.quaternion; 
    CMQuaternion quat2 = [self multiplyQuanternion:quat1 withRight:e]; 
    CMQuaternion quat3 = [self multiplyQuanternion:quat2 withRight:quatConj]; 

    return atan2f(quat3.y, quat3.x); 
} 
-(float)walkaroundAngleFromAttitude:(CMAttitude*)attitude fromHomeAngle:(float)homeangle { 

    float rawangle = [self walkaroundRawAngleFromAttitude:attitude]; 
    if (rawangle <0) rawangle += M_PI *2; 
    if (homeangle < 0) homeangle += M_PI *2; 
    float finalangle = rawangle - homeangle; 
    if (finalangle < 0) finalangle += M_PI *2; 

    return finalangle; 
} 

này được sử dụng một số mã sửa đổi và mở rộng từ Finding normal vector to iOS device

Chỉnh sửa để giải quyết Câu hỏi 2 & Bài toán 2:

Điều này có thể không giải quyết được. Tôi đã nhìn thấy nó trong các ứng dụng khác (ví dụ 360 pano) và đã đọc về các bài đọc bị lỗi trong con quay hồi chuyển và như vậy. Nếu bạn cố gắng bù đắp cho nó, tất nhiên bạn sẽ kết thúc với một kinh nghiệm jittery khi một số chuyển động quay đích thực được ném bởi mã bồi thường. Cho đến khi tôi đã được giải thích trong vài năm qua, đây là một vấn đề dựa trên phần cứng.

+0

cảm ơn sự giúp đỡ của bạn, với một số tinh chỉnh, tôi nhận được mã của bạn làm việc, và nó giải quyết vấn đề của tôi_1. Cần thêm thời gian để kiểm tra và tinh chỉnh, nhưng tôi chắc chắn tôi có mọi thứ tôi cần để hoàn thành nó. Drift đang hoạt động khác nhau hiện nay, nó trôi cho vài độ và sau đó dừng lại - góc là đá rắn với chỉ 10 độ biến đổi. Đó là hoàn toàn chấp nhận được cho ứng dụng này. Tôi sẽ chơi với nó và sẽ đăng bài nếu tôi tìm ra những gì nó phụ thuộc vào, cho đến khi đó, đó là trong hộp đổ lỗi phần cứng và nó là đủ tốt :) chúc mừng –

+0

@AndreiG. Những thứ tốt, vui mừng tôi có thể cho bạn một bàn tay. Ngoài ra, điều này đã cho tôi bài tập rất cần thiết để trở lại môn toán bậc ba :) Chúc mừng –

+0

@TomPace Xin chào, tôi cũng đang cố tìm một giải pháp cho một thứ tương tự như vậy, Bạn có thể xem câu hỏi của tôi ở đây không: Link] (http://stackoverflow.com/questions/19239482/using-quaternion-instead-of-roll-pitch-and-yaw-to-track-device-motion) .Tôi nghĩ rằng tôi đã tìm thấy sự thay đổi trong phần góc Nhưng tôi không chắc chắn rằng tôi đang đi đúng hướng. Tôi vẫn cần phải tìm ra cách theo dõi chuyển động của điện thoại trong các trục khác nhau. Tiến độ hiện tại của tôi là [ở đây] (http://pastebin.com/faPWUVE2). Cảm ơn trước. – iSeeker

Các vấn đề liên quan