Map Range of 0-360 and handle it when values 'jumps' back to 0 (after 360)

Hi

I'm trying to map yaw of an IMU from values 0-360 to midi cc values 0-127
The problem is that I need only a small portion of the the values depending on the starting position.
For example: the starting position can be 340 degrees, the mapping function returns an expected
value (1,2,3...) but when I rotate above 360 degrees the IMU values goes back to zero, messing up my mapping function which return 0.

Any easy way to achieve the values being consistent (so the mapping function values will increase as I need even when the IMU go to 0 behind 360) ?

Below is my mapping function
yaw_ema is the compass heading in integer (0-360)
yaw_min - starting position
yaw_max - starting position+ 100 degrees

int val = map(constrain( yaw_ema, yaw_min, yaw_max), yaw_min, yaw_max, 0, 127);

Just to check I have understood correctly.

For example 90 to 270 works as you want because there is a simple progression from 90 to 270 but if you try to do the same from 270 up to 360 (259?) and on to 90 then there is jump because you go 357, 358, 359, 0, 1, 2...

Is that correct?

90 to 270 works without a problem.
The problem is when the values jump from 359 back to 0.. like you said 357..358..359..0
When the IMU heading "jumps" to 0, the mapping returns 0 when I need it to return something else (depend where I started the heading position)

OK.

I can’t give you a complete answer but if this were my problem I’d consider using x, y coordinates instead of degrees. If you use coordinates there is no jump at any point.

If you must use degrees then you could try adding 360 when you go from 359 to 0, so 0 becomes 360, 1 becomes 361 etc.

If you are never using a complete circle you could also try shifting the start point to 0, so for example make 90 to 270 into 0 to 180 etc. You then correct it back later when you need the correct figures.

Those are the methods I’d explore, I don’t know what’s right for you.

Don’t forget that trigonometric functions in C use radians not degrees.

The description of what you want to do is not very clear. Please try to present the goal more clearly and accurately.

jremington:
The description of what you want to do is not very clear. Please try to present the goal more clearly and accurately.

I have 0-359 values of heading, I'm want to catch a range of let's say 120 degrees of the board starting (power on) position and map it to Midi Control Change value (0-127).
When I have the starting position of heading at 60 for example and I rotate 120 degrees the mapping to 0-127 will work correctly.. but when the starting position of the heading is at 340 I'm starting to rotate the board and it maps correctly until the heading values reach 359 and then 0, when it goes to 0 the mapping function doesn't expect the heading to 'jump' to 0 suddenly and the mapping of (0-127) is messed up.
For example: heading of 340 will be mapped to 0, 350 will be mapped to 10 , 359 to 20 and when the board rotates a bit more, the heading will be 0 or above and the mapping will drop to 0 - the mapping will increase from 0 only when I'll rotate to 340 and above (until 0).
So the mapping function doesn't know how to handle the heading goes from 359 to 0...
I hope that's clear, thank you

Sorry, I understand the problem, but not what you actually want to do.

WHAT gets mapped to 0-127, and why?

There is undoubtedly a better way to do what you actually want to do.

arduinolover30
Given your clarification in reply #5 I think my suggestion:

If you are never using a complete circle you could also try shifting the start point to 0, so for example make 90 to 270 into 0 to 180 etc.

Would do what you want.

jremington:
Sorry, I understand the problem, but not what you actually want to do.

WHAT gets mapped to 0-127, and why?

There is undoubtedly a better way to do what you actually want to do.

A Midi controller gets mapped to 0-127 as these are the values of a midi control message,
What I want to achieve is that the heading will be mapped to a midi control message and will send appropriate values of based on the heading location, even when the heading goes from 359 to 0 I need the mapping value of the midi control message to be consistent.

A very handy mapping for heading error (heading = current direction of travel, bearing = desired direction of travel), which takes into account compass wrap, is the following:

int heading_error = (heading - bearing + 540)%360 - 180;  //result is in the range -180 to 180

heading and bearing are presumed integer degrees.

jremington:
A very handy mapping for heading error (heading = current direction of travel, bearing = desired direction of travel), which takes into account compass wrap, is the following:

int heading_error = (heading - bearing + 540)%360 - 180;  //result is in the range -180 to 180

heading and bearing are presumed integer degrees.

That's great, thanks a lot !

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.