Как преобразовать углы Эйлера и высоту камеры дрона в координаты центра изображения?

Я пытаюсь вычислить реальную 3D-координату центрального пикселя изображения, сделанного с помощью дрона. У меня есть долгота, широта, высота и углы Эйлера (рыскание, тангаж и крен) дрона. Предполагается, что земля плоская (на уровне моря, поскольку это абсолютная высота дрона).

Пока я смотрю только на центр изображения, поэтому угол поворота может быть не нужен, но он у меня все еще есть для использования в будущем.

Если возможно, меня интересуют долгота, широта, высота (0) центра изображения.

Я пробовал создать матрицу вращения с углами Эйлера и умножить ее на вектор между дроном и землей. Затем добавляем результат к вектору исходного положения дрона, а затем добавляем к длине, пока он не достигнет уровня моря. Но, похоже, это не дает желаемого результата.

РЕДАКТИРОВАТЬ: Я работал над этой проблемой и сделал некоторые обновления, но я все еще не понял. Я рисую свой результат на карте и сравнивая с известными местоположениями, и я могу сказать, что мой результат неверен. КОД:

func calculateImagePointCoordinate(v: GLKVector3, droneCoords: Coordinate, gimYaw: Float, gimPitch: Float, gimRoll: Float) -> Coordinate {
// v = GLKVector3 with image coordinates, example (0,0,altitude) for image center

    let radYaw      = degreesToRadians(gimYaw)
    let radPitch    = degreesToRadians(gimPitch)
    let radRoll     = degreesToRadians(gimRoll)

    let rotationMatrixRoll = GLKMatrix3Make(1, 0, 0,
                                            0, cosf(radRoll), sinf(radRoll),
                                            0, -sinf(radRoll), cosf(radRoll))

    let rotationMatrixPitch = GLKMatrix3Make(cosf(radPitch), 0, sinf(radPitch),
                                             0, 1, 0,
                                             -sinf(radPitch), 0, cosf(radPitch))

    let rotationMatrixYaw = GLKMatrix3Make(cosf(radYaw), sinf(radYaw), 0,
                                           -sinf(radYaw), cosf(radYaw), 0,
                                           0, 0, 1)

    let rollPitch = GLKMatrix3Multiply(rotationMatrixRoll, rotationMatrixPitch)
    let rollPitchYaw = GLKMatrix3Multiply(rollPitch, rotationMatrixYaw)

    let transpose = GLKMatrix3Transpose(rollPitchYaw)

    let rotatedVector   = GLKMatrix3MultiplyVector3(rollPitchYaw, v)

    let rotateBack = GLKMatrix3MultiplyVector3(transpose, rotatedVector)

    var coordinate = droneCoords.addDistance(inMeters: Double(rotateBack.x), withBearingInRadians: Double.pi / 2)
    coordinate = coordinate.addDistance(inMeters: Double(rotateBack.y), withBearingInRadians: Double.pi)

  return coordinate
}

Я пробовал использовать метод, описанный Beta в этой теме: Как преобразовать углы Эйлера в вектор направления? но я, кажется, что-то не понимаю.

Я не уверен, какой угол использовать при добавлении векторных компонентов в конце. И я предполагаю, что это может быть моей проблемой. Мой класс Coordinate использует только long и lat, но нужно ли мне каким-то образом добавить компонент z, чтобы он был правильным? И под каким углом в таком случае его добавить?


person JVarga    schedule 04.04.2019    source источник


Ответы (1)


Я думаю, что у меня есть решение, оно еще не протестировано должным образом, но, похоже, оно работает для моего небольшого набора тестов. Добавление компонентов вектора под углом к ​​осям x и y решило мою проблему.

var coordinate = droneCoords.addDistance(inMeters: Double(rotateBack.x), withBearingInRadians: Double.pi)
coordinate = coordinate.addDistance(inMeters: Double(rotateBack.y), withBearingInRadians: Double.pi/2)
person JVarga    schedule 24.04.2019