Part Three: Don't YAWn, this is important!

Hello again! Welcome to part three of our Myo Script Tutorial on orientation and gestures (parts one and two here). Last time I asked you to implement onPeriodic. Today, we’re going to talk about how to properly calculate delta yaw.

This is what I did:

  


YAW_DEADZONE = .1

    flyingLeft = false  
    flyingRight = false

    function onPeriodic()  
        if (centreYaw == 0) then
            return
        end
        local currentYaw = myo.getYaw()
        local deltaYaw = currentYaw - centreYaw
        printCount = printCount + 1
        if printCount >= 200 then
            myo.debug("deltaYaw = " .. deltaYaw)
        end
        if (deltaYaw > YAW_DEADZONE) then
            flyLeft()
        elseif (deltaYaw < -YAW_DEADZONE) then
            flyRight()
        else
            flyNeutral()
        end
    end

    function flyLeft()  
        if (flyingRight) then
            myo.debug("Not flying right");
            myo.keyboard("right_arrow","up")
            flyingRight = false
        end
        if (not flyingLeft) then
            myo.debug("Flying left");
            myo.keyboard("left_arrow","down")
            flyingLeft = true;
        end
    end

    function flyRight()  
        if (flyingLeft) then
            myo.debug("Not flying left");
            myo.keyboard("left_arrow","up")
            flyingLeft = false
        end
        if (not flyingRight) then
            myo.debug("Flying right");
            myo.keyboard("right_arrow","down")
            flyingRight = true
        end
    end

    function flyNeutral()  
        if  (flyingLeft) then
            myo.debug("Not flying left");
            myo.keyboard("left_arrow","up")
            flyingLeft = false
        end
        if (flyingRight) then
            myo.debug("Not flying right");
            myo.keyboard("right_arrow","up")
            flyingRight = false
        end
    end 

The reason I am only printing debug output every 200 times the function is called is because that function is called a LOT (every 10ms). It will just flood your debug console and you won’t be able to see anything else. Also, if the console gets too full debug commands will actually take a few milliseconds to execute, slowing down onPeriodic. There is a clear button that will purge the buffer and you should press it if things begin to feel unresponsive.

Anyway, this script basically works, but you may have already noticed a rather large flaw. Depending on where the actual 0 of the yaw is, at some point when rotating your arm you will flip from +π (180 degrees) to -π (-180 degrees) (or vice versa) and the script will now think you should be turning in the other direction. If you haven’t seen that, try it yourself. Center your yaw and then slowly spin clockwise until you flip from right to left. Unless you were very lucky it probably didn’t happen when your arm was pointing directly behind you, and if you were very unlucky it could have happened almost right away.

If you log the the value of deltaYaw you are calculating, you’ll be able to see the jump. Any guesses as to how to fix it? Try and experiment yourself before moving it.

The key is that your delta SHOULD be constrained between +/-π (or +/-180 degrees). If it’s outside of that, it will be WAY out. How much is way out?

Whether you can eyeball it or not probably depends on how good you are with radians (or if you wussed out and are using degrees). If you give up, it’s exactly 2π. (Highlight that for the answer.)

Try to figure out the correct way to calculate the difference between two radians (or degrees), and use it to determine deltaYaw. We’ll use it again later for roll (spoilers) so make it generic enough to handle both. I’ll be back tomorrow with the solution!

Newsletter

Enter your email address and get all latest content delivered to your inbox every now and then.