![]() |
NavX MXP Continuous Angle to Calculate Derivative
For our autoalignment sequence, we have an algorithm to 'find' the correct motor speed necessary to turn the robot at a certain velocity. The algorithm bumps up motor speed every 100ms until the robot is turning at a certain very slow velocity. The NavX's getRate() function had very low resolution so we wrote a class to calculate the average change in yaw over time (derivative). However, for this to work at all headings we'd need a method on the NavX to return a continuous angle. 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 which makes the robot think that it just turned the full 360 degrees in a matter of milliseconds.
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. To get around this issue currently, we're checking if the derivative is less than something like 30 deg/s, and if it isn't just return 0 deg/s, but that's really hacky and I'd like to actually fix the problem. My team is using Java. Thanks for your help! |
Re: NavX MXP Continuous Angle to Calculate Derivative
I think that was a software bug... have you updated to the latest software?
|
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
You should be able to use some modulo arithmetic operations to solve the jump from 0 / 360. I'm not sure how you have it configured but on our we have the issue because it jumps from -180 / 180. Question though - what are you trying to achieve by closing the loop to a specific turning speed? We use the same setup and close the loop on the current field orientation angle. In that way you can have the robot quickly turn when it's farther away from the set point, and slow down as it approaches where you want it to be so you have minimal overshoot. |
Re: NavX MXP Continuous Angle to Calculate Derivative
Would x=x%180.... (modulo operator) work? May need to preserve sign.
|
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
|
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
Also note there's a recent firmware release which increases the update rate maximum to 100Hz, so it might be worth downloading the latest release, running the setup to update the libraries, and updating the firmware. Please feel free to contact support@kauailabs.com if you still have trouble. |
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
Quote:
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);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);EDIT: Test code: Code:
#include <math.h>Code:
previous=360.000000 present=0.000000 shortest_angle=0.000000 |
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
Quote:
I haven't updated the NavX libraries yet, as we leave for Missouri State Champs at 3:00 tomorrow and we're in a time crunch. Ether's fix seemed the quickest and easiest. Thank you everyone for all the help! I can post source code for our autoalignment command and the derivative calculator in a few days if anyone is interested. |
Re: NavX MXP Continuous Angle to Calculate Derivative
This year on 254 we switched to using a simple Rotation2d class for all angles (because, among other reasons, dealing with angle rollover as you did here is easy to screw up). Internally, this class stores the sine and cosine of an angle explicitly. This has some nice properties:
|
Re: NavX MXP Continuous Angle to Calculate Derivative
Thanks Ether... learn something new everyday!
The way Microsoft's library present's this function is like so: IEEERemainder = dividend - (divisor * Math.Round(dividend / divisor)) It's great to see such a compatible use-case for this function as written in this thread... this function has also helped improve some bugs in my simulations as well. :) |
Re: NavX MXP Continuous Angle to Calculate Derivative
Here is a c++ equivalent within standard libraries:
http://en.cppreference.com/w/cpp/numeric/math/remainder |
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
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? |
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
|
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
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. |
Re: NavX MXP Continuous Angle to Calculate Derivative
Quote:
There was definitely a noticeable improvement on the conventional PID controller. One problem we were facing without the velocity controller was that our turns were highly dependent on momentum. We really would have liked to run the velocity loop underneath our teleop driving code too, but integral windup caused a lot of unpredictable behavior over long periods of time. |
| All times are GMT -5. The time now is 10:37. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi