For the record, I’m programming in LabView. We decided to try out the gyro board from the 2017 KOP on our test robot. I set up a PID that works quite well to turn the robot to any angle. In order to turn my test code into a useful function, I need to detect when the turn is “done” and exit out of the control loop to return to the calling function. I’ve tried various ideas, e.g. when the absolute difference between the current angle and commanded angle is less than 0.1 degree, but nothing has worked reliably. I still have some ideas, such as looking at the angular rate, but I thought I could ask. For programmers who have solved this problem, what did you do to detect that the turn is done? Thanks!
BTW, I also intend to add a short timer so that we also exit even if the robot can’t turn (stuck or pinned).
In addition to the timeout you’ve mentioned, consider the case where the robot “overshoots” the target and then returns to the target. It’s possible you’d want to average together the last few samples and calculate the recent average difference (often referred to as the “error”). The goal would be to not declare success too early if the software happened to read an “on target” sample while it was actually in the process of overshooting…
Also, .1 degrees may be too fine an angular difference to declare success. Consider if perhaps 1 or 2 degrees is sufficient…
First expecting the turn to stop that quickly within .1 degree is very difficult. That means that you must have that level of accuracy in both the sensor and your drivetrain.
Things to consider:
you will probably find that depending on the rate your bot is turning at that is has some level of momentum such that it will keep turning slightly even after commanded to stop. If you stay on the same surface and at the same speed this should be fairly constant so you can account for it.
Do you have encoders on your drivetrain or a navX on your bot? They are additional sensors that could help you confirm the heading.
You can use PID to slow the turn down as it approaches the setpoint. Or if you are turning fast and overshoot it can help you turn back.
Path forward:
You should probably consider what the acceptable range that you need in order to be successful. You may find that you only need to be within a few degrees to achieve what you are looking for.
I have attached a screenshot of some sample code. In this instance 23.75 is our scalar offset that I talked about above. This may need more logic if you are using this code for different speeds. The setpoint is coming in from the top and we are doing rudimentary PID (P only) by multiplying a small number by the difference we setpoint and actual (error). Let me know if you need further explanation!
For determining if you are done: Threshold and debounce:
–Exit when error has been “acceptable” for some period of time
—“acceptable” error is application dependent, we’ve usually used 1-2 degrees
—Period of time is also application dependent - should be as short as possible, but still reject overshoot with some margin of error. 2-3x the oscillation period of your over-damped system is a decent option?
For putting a timeout on it, this is sometimes a valid solution. However, it presumes that regardless of which direction you are pointed, moving on to the next thing is still useful. Is this true in your particular case?
I simplified all of the syntax because I know almost none of the python language carries over into labview, but that’s a pretty simple way of handling it
If you are feeling cheeky you can also have it return a true/false at the end, which allows you for say
if(turnAngle() == True):
[insert code here]
because the if statement runs the method within itself, and that’s a nice, easy way to handle turning quickly
Another simple fix would be to create a method where you enter the degrees you want to turn. While the degrees you enter is not reached turn else stop powering motors. Using the gyro included in the KOP you can create an accurate turning mechanism.