Search code examples
mathluatrigonometryangle

How can I determine angular velocity from a fixed heading while dealing with the wrap around


I am trying to determine angular velocity in degrees per second of an object.

I have only the heading of that object in degrees updated every 1/60th of a second (with 0 being North and 90 being East)

The specific issue I have is one of handling the wrap around when the object goes from say 355 degrees to 5 degrees passing over 0/360.

I'm currently thinking that perhaps I can average readings over time, excluding the outliers however that will add unnecessary lag to the system and reduce accuracy over that region.

Simple example code where degreesIn is the source and degreesPerSecondOut is the result

degreesPerSecondOut = (degreesIn or 0 - degreesInOld) * 60
degreesInOld = degreesIn

Expected results include a smooth and accurate transition whilst passing over 0 degrees


Additional Thought: The object I am calculating the angular velocity of should never exceed 1 revolution per second (or even per 1/60th of a second). Im not sure why but I feel this is useful.


Solution

  • My take:

    function velocity(ain,aout)
        ipersec = 60
        raw = aout - ain
        turn = math.min((-math.abs(raw))%360,math.abs(raw)%360)
        direction = math.abs(raw)/raw
        return direction*turn*ipersec
    end
    print(velocity(5,355),velocity(355,5),velocity(20,40),velocity(40,20))
    --[[600    -600    1200    -1200--]]
    

    My take - you have three components:

    1. Wrap around, simply handled with a %360. math.mod will work for 5.0.
    2. Even with wrap around, there are two ways you could have turned - we always want the minimal turn.
    3. A sign portion which indicates direction.

    Once you handle the wrap around, you realize that 355->5 or backward is no different then 10->20 - you could have taken 10 degrees, or 350, but we assume the shortest.