Go to Post Not only would it be cool but the mental image of Dave's suffering when he writes a message in unintelligible characters makes me grin uncontrollably. - Andrew Schreiber [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
 
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 21-05-2016, 22:15
Richard100 Richard100 is online now
Registered User
FRC #0836 (RoboBees)
Team Role: Mentor
 
Join Date: Nov 2009
Rookie Year: 2008
Location: Southern Maryland
Posts: 79
Richard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to behold
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Ether View Post
modulo is not what you want here.

what you want is the shortest angle from the previous reading to the present reading, with the correct sign. The IEEERemainder function1 does this with one line of code:
Code:
shortest_angle = IEEERemainder(present-previous,360);
C# and Java both support IEEERemainder.


If your language does not support IEEERemainder, you can use this one-line function instead:
Code:
shortest_angle = (present-previous) - 360*floor(0.5+(present-previous)/360);


Some practical considerations regarding this approach ...

Note that if one is streaming readings from an angular position sensor (such as a gyro or IMU), one would need to add an accumulator to this shortest_angle function to continually maintain angular position.

Also be aware that the function is sensitive to sampling rate. This is because a late sample might allow a current position (the 'present' variable) to get more than 180 degrees away the previous position (the 'previous' variable). If this happens then the shortest angle will switch to the other side of the cycle. If you've ever noticed movies where wagon or car wheels appear to be moving backwards then you've seen this aliasing effect (this can happen to your sensor, too).

To avoid this, ensure the iteration period is at least shorter than (1 / 2*RPS), where RPS is the maximum revolutions per second expected from the sensor reading stream. For example, if your robot maximum yaw rotation rate is 1000 deg/sec, you must iterate the function no slower than every 180 ms ... (someone check my math).

This is likely not a problem for most FRC robots, as yaw rates don't normally get that high (ours don't get much higher than 500 deg/sec), and computational iteration rates are probably much faster - but one should be aware of the constraint. You might try the function on a robot mechanism that rotates much faster and wonder why your code is suddenly unreliable.

If the sensor readings are noisy, this will further erode the sampling margin. If the peak noise level in degrees is 'n', then the sampling constraint becomes:

Loop Period < (180 - 2*n)/(360 * RPS)

Of course, excessive noise should be remedied (fixing the root cause). One should just keep in mind that it's good practice to maintain healthy margin for practical issues like noise, and in fact whether your loop can always be trusted to occur on schedule.

The exploit of the shortest directional path property of the IEEERemainder function is quite clever for dealing with these orientation discontinuities. I wasn't aware of it until Ether pointed it out - (thank you Ether). It doesn't appear that LabVIEW has this function (although easy enough to build from primitives) ... unless I'm just not finding it - anyone know for sure?
Reply With Quote
  #2   Spotlight this post!  
Unread 21-05-2016, 22:38
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 7,995
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Richard100 View Post
The exploit of the shortest directional path property of the IEEERemainder function is quite clever for dealing with these orientation discontinuities. I wasn't aware of it until Ether pointed it out - (thank you Ether). It doesn't appear that LabVIEW has this function (although easy enough to build from primitives) ... unless I'm just not finding it - anyone know for sure?
Look at the Endnote at the bottom of the last page.


Reply With Quote
  #3   Spotlight this post!  
Unread 22-05-2016, 13:41
Richard100 Richard100 is online now
Registered User
FRC #0836 (RoboBees)
Team Role: Mentor
 
Join Date: Nov 2009
Rookie Year: 2008
Location: Southern Maryland
Posts: 79
Richard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to behold
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Ether View Post
Look at the Endnote at the bottom of the last page.


The Endnote LV code you reference is functionally equivalent to shortest_angle = (present-previous) - 360*floor(0.5+(present-previous)/360); provided here ...
Quote:
Originally Posted by Ether View Post

If your language does not support IEEERemainder, you can use this one-line function instead:
Code:
shortest_angle = (present-previous) - 360*floor(0.5+(present-previous)/360);
Both can be written in LV by building up the function from other primitive programming functions (as you depict in the endnote image).

What I wanted to know was whether LabVIEW has IEEERemainder as a programming function (call it Rem). There is a Mod (%) function (known in LV as Quotient & Remainder), but of course Rem and Mod differ in how they internally round, which is what makes Rem useful here.

Same question as you asked here, only for the LabVIEW language. Equivalent to asking: Can it be done in LabVIEW "... with one line of code".

Any LabVIEW experts know? If not, might this be in the development pipeline?
Reply With Quote
  #4   Spotlight this post!  
Unread 21-05-2016, 22:49
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 7,995
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Richard100 View Post
Note that if one is streaming readings from an angular position sensor (such as a gyro or IMU), one would need to add an accumulator to this shortest_angle function to continually maintain angular position.
It's not clear what you're saying here.

You don't need an accumulator when using a gyro if all you care about is your heading.

The desired heading and the gyro angle do not have a range constraint in this case.

For example, the gyro angle could be 721 degrees and the desired heading could be -1 degree. The function would return -2 degrees as the shortest angle, which is the value you want.


Reply With Quote
  #5   Spotlight this post!  
Unread 22-05-2016, 15:53
Richard100 Richard100 is online now
Registered User
FRC #0836 (RoboBees)
Team Role: Mentor
 
Join Date: Nov 2009
Rookie Year: 2008
Location: Southern Maryland
Posts: 79
Richard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to behold
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Ether View Post
You don't need an accumulator when using a gyro if all you care about is your heading.
Not finding this to be very clear either. We're likely discussing different aspects of the problem.

Quote:
Originally Posted by Ether View Post

It's not clear what you're saying here.
Ok. The OP's framing of the problem:

Quote:
Originally Posted by lethc View Post
Currently both getAngle() and getYaw() are not continuous, and their ranges are [0, 360] and [-180, 180] respectively, so at the point where the robot crosses the threshold of a range the values jump ~360 degrees ...

Does anyone have any ideas on how I would get a continuous angle heading ...?
Proposed solution:

Quote:
Originally Posted by Ether View Post
what you want is the shortest angle from the previous reading to the present reading, with the correct sign. The IEEERemainder function1 does this with one line of code:
Code:
shortest_angle = IEEERemainder(present-previous,360);
C# and Java both support IEEERemainder.


If your language does not support IEEERemainder, you can use this one-line function instead:
Code:
shortest_angle = (present-previous) - 360*floor(0.5+(present-previous)/360);
Proposed solution amendment:

Quote:
Originally Posted by Richard100 View Post
Note that if one is streaming readings from an angular position sensor (such as a gyro or IMU), one would need to add an accumulator to this shortest_angle function to continually maintain angular position.
If the OP streamed a series of sensor readings, range constrained as [0,360], into a function

Code:
shortest_angle = (present-previous) - 360*floor(0.5+(present-previous)/360)
the resulting output would need to be accumulated to maintain position. Say robot yaw initializes at 0 degrees, moves clockwise over time to 15 degrees, then counter-clockwise to 350 degrees, as reported by the range constrained sensor. Consider:

Code:
Iteration       Previous        Present         Pres-Prev       Function       Accum
1		0		0	        0               0              0
2	        0               5	        5               5	       5
3	        5	        10	        5	        5	       10
4	        10	        15	        5	        5	       15
5	        15	        10	       -5	       -5	       10
6	        10	        350	        340	       -20	      -10
Rather than using what the OP started with, a Present value exhibiting the range-constrained discontinuity, it sounds like the OP needs the accumulated function result.

I'm interpreting the OPs desire for a function that converts his range-constrained sensor output to a non-range-constrained one. Your IEEERemainder function, with an accumulator, accomplishes this.
Reply With Quote
  #6   Spotlight this post!  
Unread 22-05-2016, 16:35
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 7,995
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Richard100 View Post
Not finding this to be very clear either. We're likely discussing different aspects of the problem.

I am discussing the solution to this aspect of the OP's original framing of the problem (see bolded portion):
Quote:
Originally Posted by lethc View Post
Does anyone have any ideas on how I would get a continuous angle heading from the NavX? I.E. one that doesn't jump from 360 to 0 instantly, because that messes up the derivative calculation
You don't need a continuous angle to do a simple difference calculation (which is what I anticipated the OP was really wanting).

The IEEERemainder gives you that answer:

Quote:
Originally Posted by Ether View Post
what you want is the shortest angle from the previous reading to the present reading, with the correct sign. The IEEERemainder function1 does this with one line of code:
Code:
shortest_angle = IEEERemainder(present-previous,360);
Quote:
Originally Posted by lethc View Post
Just tried this out and it works perfectly. Thank you for your help.

Reply With Quote
  #7   Spotlight this post!  
Unread 22-05-2016, 19:50
Richard100 Richard100 is online now
Registered User
FRC #0836 (RoboBees)
Team Role: Mentor
 
Join Date: Nov 2009
Rookie Year: 2008
Location: Southern Maryland
Posts: 79
Richard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to beholdRichard100 is a splendid one to behold
Re: NavX MXP Continuous Angle to Calculate Derivative

Thanks for taking time to walk through this! The distinction you reference clears up the differing perspectives / solution space.
Reply With Quote
  #8   Spotlight this post!  
Unread 22-05-2016, 20:25
Alan Anderson's Avatar
Alan Anderson Alan Anderson is offline
Software Architect
FRC #0045 (TechnoKats)
Team Role: Mentor
 
Join Date: Feb 2004
Rookie Year: 2004
Location: Kokomo, Indiana
Posts: 9,112
Alan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond reputeAlan Anderson has a reputation beyond repute
Re: NavX MXP Continuous Angle to Calculate Derivative

Quote:
Originally Posted by Richard100 View Post
Same question as you asked here, only for the LabVIEW language. Equivalent to asking: Can it be done in LabVIEW "... with one line of code".

Any LabVIEW experts know? If not, might this be in the development pipeline?
You can do a "line of code" in LabVIEW by putting it in a Formula Node. It's exactly like writing an expression in C.
Reply With Quote
  #9   Spotlight this post!  
Unread 12-06-2016, 12:29
tr6scott's Avatar
tr6scott tr6scott is online now
Um, I smell Motor!
AKA: Scott McBride
FRC #2137 (TORC)
Team Role: Mentor
 
Join Date: Dec 2007
Rookie Year: 2005
Location: Oxford, MI
Posts: 505
tr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond reputetr6scott has a reputation beyond repute
Re: NavX MXP Continuous Angle to Calculate Derivative

Labview Subvi implementation of this attached.
Tested with the data set published, and checked results.
Sorry, not a LV guru, so did not take the time create input matrix and results.
(started too, but I knew there was a much simpler way than the way I was doing it.)

Thanks, we struggled with the gyro rollover in the past and this implementation seems to solve all of the issues we have tried to conditionally fix in the past.

Thanks Ether.
Attached Thumbnails
Click image for larger version

Name:	Capture.PNG
Views:	11
Size:	8.4 KB
ID:	20850  
Attached Files
File Type: vi ShortestAngle-Ether.vi (11.2 KB, 1 views)
__________________
The sooner we get behind schedule, the more time we have to catch up.

Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 10:37.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi