Home > Software engineering >  Orientation Matrix from Heading, Pitch and Roll
Orientation Matrix from Heading, Pitch and Roll

Time:02-06

I have a problem converting Heading, Pitch and Roll to an Orientation Matrix

How would I go about improving this to ensure Y and Z and are correctly calculated.

--[[
  get_orientation - Returns the orientation matrix of an object based on its heading, pitch, and roll in degrees.
  
  @param heading number - The heading of the object in degrees.
  @param pitch number - The pitch of the object in degrees.
  @param roll number - The roll of the object in degrees.
  @returns orientation table - The orientation matrix of the object, represented as a table with three unit vectors: x, y, and z.
]]
local function get_orientation(heading, pitch, roll)
    local orientation = {}

    -- Convert the heading, pitch, and roll from degrees to radians using math.rad
    heading = math.rad(heading)
    pitch = math.rad(pitch)
    roll = math.rad(roll)

    -- Calculate the x unit vector
    -- x is the Vec3 unit vector that points in the direction of the object's front
    orientation.x = {}
    orientation.x.x = math.cos(heading) * math.cos(pitch)
    orientation.x.y = math.sin(pitch)
    orientation.x.z = math.sin(heading) * math.cos(pitch)

    -- Calculate the y unit vector
    -- y is the Vec3 unit vector that points in the direction of the object's top
    orientation.y = {}
    orientation.y.x = -math.cos(heading) * math.sin(pitch)
    orientation.y.y = math.cos(pitch)
    orientation.y.z = -math.sin(heading) * math.sin(pitch)

    -- Calculate the z unit vector
    -- z is the Vec3 unit vector that points in the direction of the object's right side
    orientation.z = {}
    orientation.z.x = -math.sin(heading)
    orientation.z.z = -math.cos(heading) * math.cos(roll)
    orientation.z.y = math.sin(roll)

    -- Return the orientation matrix of the object
    return orientation
end

---------------------------------------------------
---------------------------------------------------
local lat = 41.610278
local lon = 41.599444
local heading = 90
local pitch = 25
local roll = 0
local alt = 100


local x, y = terrain.convertLatLonToMeters(lat, lon)

local orientation = get_orientation(heading, pitch, roll)

local position = {
    x=orientation.x,
    y=orientation.y,
    z=orientation.z,
    p={x=x,y=alt,z=y}
}

Export.LoSetCameraPosition(position)
local actual = Export.LoGetCameraPosition()

return {position=position, actual=actual}

There is a little more information about the Orientation here https://www.digitalcombatsimulator.com/en/support/faq/1256/#:~:text=level 10 m-,Orientation,-Object orientation is

I am attempting to build a function that takes lat, lon, alt, heading, pitch and roll and produce the Position matrix.

I have the example function so far, which does work but everything goes funky after -81 pitch and the roll does not work as intended.

CodePudding user response:

Formulas for 3D rotation are not simple, but they can be simply deduced from three consecutive 2D rotations.

local function apply_rotation(a, b, angle)
   local ax, ay, az, bx, by, bz = a.x, a.y, a.z, b.x, b.y, b.z
   a.x = math.cos(angle) * ax   math.sin(angle) * bx
   a.y = math.cos(angle) * ay   math.sin(angle) * by
   a.z = math.cos(angle) * az   math.sin(angle) * bz
   b.x = math.cos(angle) * bx - math.sin(angle) * ax
   b.y = math.cos(angle) * by - math.sin(angle) * ay
   b.z = math.cos(angle) * bz - math.sin(angle) * az
end

local function get_orientation(heading, pitch, roll)

    -- Convert the heading, pitch, and roll from degrees to radians using math.rad
    heading = math.rad(heading)
    pitch = math.rad(pitch)
    roll = math.rad(roll)

    -- x is the Vec3 unit vector that points in the direction of the object's front
    -- y is the Vec3 unit vector that points in the direction of the object's top
    -- z is the Vec3 unit vector that points in the direction of the object's right side
    local o = {
        x = { x=1, y=0, z=0 },
        y = { x=0, y=1, z=0 },
        z = { x=0, y=0, z=1 },
    }

    apply_rotation(o.x, o.z, heading)
    apply_rotation(o.x, o.y, pitch)
    apply_rotation(o.z, o.y, roll)

    -- Return the orientation matrix of the object
    return o
end
  • Related