Go to Post It's a process of elimination led by inspiration. - JaneYoung [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 04-07-2016, 13:02
team-4480's Avatar
team-4480 team-4480 is offline
Debug? What's that?
FRC #4480
 
Join Date: Jan 2015
Rookie Year: 2013
Location: Minnesooota
Posts: 222
team-4480 will become famous soon enoughteam-4480 will become famous soon enough
Why won't this PID loop stop?

Hi,

I am trying pretty hard to get this PID loop for a turnaround button using this nice example. The problem I am having is that no matter what I set the kToleranceDegrees to, the robot will still oscillate back and forth when I know for sure that it is within my tolerance. Am I forgetting to do something? I don't feel like adjusting the PID values will do anything because the robot won't even stop when the target is 90 degrees, the gyro reads 89.4 degrees and the tolerance is 10 degrees! What am I do wrong? Thanks!
__________________
#Python4Life
Reply With Quote
  #2   Spotlight this post!  
Unread 04-07-2016, 13:31
Oblarg Oblarg is offline
Registered User
AKA: Eli Barnett
FRC #0449 (The Blair Robot Project)
Team Role: Mentor
 
Join Date: Mar 2009
Rookie Year: 2008
Location: Philadelphia, PA
Posts: 1,087
Oblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond repute
Re: Why won't this PID loop stop?

Quote:
Originally Posted by team-4480 View Post
Hi,

I am trying pretty hard to get this PID loop for a turnaround button using this nice example. The problem I am having is that no matter what I set the kToleranceDegrees to, the robot will still oscillate back and forth when I know for sure that it is within my tolerance. Am I forgetting to do something? I don't feel like adjusting the PID values will do anything because the robot won't even stop when the target is 90 degrees, the gyro reads 89.4 degrees and the tolerance is 10 degrees! What am I do wrong? Thanks!
Caveat: I am only familiar with the java version of WPILib and am assuming that the functionality is the same.

The loop does not automatically stop when you're within tolerance of the setpoint. Rather, the tolerance setting is used by the onTarget() function to determine whether or not you have reached your setpoint. If you wish to stop the loop once you've reached your setpoint, you'll have to write code to disable the PID controller once onTarget() returns true. Note that you can also set a buffer length for your PID controller which will require that the average over n interations of your main loop be within the tolerance of the setpoint for onTarget() to return true, which is a good idea to prevent the loop from disabling if it overshoots the setpoint.

However, you should not need to disable the PID loop to eliminate oscillations - if your robot is oscillating around setpoint, then you need to tune it better to reduce the overshoot. If you find it difficult to reduce/eliminate the overshoot without making it difficult or impossible for the robot to actually reach the setpoint, consider implementing a "minimum output" for your PID loop rather than letting it actually go smoothly to 0.
__________________
"Mmmmm, chain grease and aluminum shavings..."
"The breakfast of champions!"

Member, FRC Team 449: 2007-2010
Drive Mechanics Lead, FRC Team 449: 2009-2010
Alumnus/Technical Mentor, FRC Team 449: 2010-Present
Lead Technical Mentor, FRC Team 4464: 2012-2015
Technical Mentor, FRC Team 5830: 2015-2016
Reply With Quote
  #3   Spotlight this post!  
Unread 04-07-2016, 13:40
team-4480's Avatar
team-4480 team-4480 is offline
Debug? What's that?
FRC #4480
 
Join Date: Jan 2015
Rookie Year: 2013
Location: Minnesooota
Posts: 222
team-4480 will become famous soon enoughteam-4480 will become famous soon enough
Re: Why won't this PID loop stop?

Quote:
Originally Posted by Oblarg View Post
Caveat: I am only familiar with the java version of WPILib and am assuming that the functionality is the same.

The loop does not automatically stop when you're within tolerance of the setpoint. Rather, the tolerance setting is used by the onTarget() function to determine whether or not you have reached your setpoint. If you wish to stop the loop once you've reached your setpoint, you'll have to write code to disable the PID controller once onTarget() returns true.
I did actually write code so that if it was onTarget(), it would be disabled but it never worked because I found out that if you call onTarget too often, it never returns true.
__________________
#Python4Life
Reply With Quote
  #4   Spotlight this post!  
Unread 04-07-2016, 13:47
Oblarg Oblarg is offline
Registered User
AKA: Eli Barnett
FRC #0449 (The Blair Robot Project)
Team Role: Mentor
 
Join Date: Mar 2009
Rookie Year: 2008
Location: Philadelphia, PA
Posts: 1,087
Oblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond reputeOblarg has a reputation beyond repute
Re: Why won't this PID loop stop?

Quote:
Originally Posted by team-4480 View Post
I did actually write code so that if it was onTarget(), it would be disabled but it never worked because I found out that if you call onTarget too often, it never returns true.
You are possibly encountering a bug that was discovered this year.

Edit: Or possibly not, as a reply in that thread indicates that bug does not occur in the python version of WPILib. I'd suggest looking through the PIDController code and debugging to find why this is happening.

Edit 2: I have never worked with python myself, so perhaps I'm missing something, but it seems to me that the onTarget() function in the python WPILib doesn't actually, erm, do anything (other than throw a value error):

Code:
def onTarget(self):
    """Return True if the error is within the percentage of the total input
    range, determined by setTolerance. This assumes that the maximum and
    minimum input were set using :func:`setInput`.
    :returns: True if the error is less than the tolerance
    """
    raise ValueError("No tolerance value set when using PIDController.onTarget()")
__________________
"Mmmmm, chain grease and aluminum shavings..."
"The breakfast of champions!"

Member, FRC Team 449: 2007-2010
Drive Mechanics Lead, FRC Team 449: 2009-2010
Alumnus/Technical Mentor, FRC Team 449: 2010-Present
Lead Technical Mentor, FRC Team 4464: 2012-2015
Technical Mentor, FRC Team 5830: 2015-2016

Last edited by Oblarg : 04-07-2016 at 17:05.
Reply With Quote
  #5   Spotlight this post!  
Unread 04-07-2016, 18:58
alst alst is offline
Programming Mentor
AKA: Alan
FRC #0830 (RatPack)
Team Role: Mentor
 
Join Date: Jul 2015
Rookie Year: 1830
Location: MI
Posts: 10
alst is an unknown quantity at this point
Re: Why won't this PID loop stop?

Quote:
Originally Posted by Oblarg View Post
Edit 2: I have never worked with python myself, so perhaps I'm missing something, but it seems to me that the onTarget() function in the python WPILib doesn't actually, erm, do anything (other than throw a value error):

Code:
def onTarget(self):
    """Return True if the error is within the percentage of the total input
    range, determined by setTolerance. This assumes that the maximum and
    minimum input were set using :func:`setInput`.
    :returns: True if the error is less than the tolerance
    """
    raise ValueError("No tolerance value set when using PIDController.onTarget()")
The onTarget method of each instance gets assigned to either PercentageTolerance_onTarget or AbsoluteTolerance_onTarget when you call setTolerance, setAbsoluteTolerance, or setPercentTolerance (i.e. you have to call one of those before calling onTarget):
https://github.com/robotpy/robotpy-w...r.py#L431-L467
Reply With Quote
  #6   Spotlight this post!  
Unread 04-07-2016, 19:46
virtuald's Avatar
virtuald virtuald is online now
RobotPy Guy
AKA: Dustin Spicuzza
FRC #1418 (), FRC #1973, FRC #4796, FRC #6367 ()
Team Role: Mentor
 
Join Date: Dec 2008
Rookie Year: 2003
Location: Boston, MA
Posts: 1,058
virtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant future
Re: Why won't this PID loop stop?

There are a number of bugs with the current WPILib PIDController implementation. The python implementation follows the java implementation closely, so it shares these issues. Here are bug reports on WPILib's github site:
  • #29: PIDController: setSetpoint causes onTarget to be false
  • #30: PIDController: race condition for enable/disable and PIDWrite
  • #31: PIDController: getError() is incorrect when setContinuous is True

In particular, #29 is probably the one that is biting you (it bit me for a similar reason). If you keep calling setSetpoint (like that example does), each time it is called it will reset things such that onTarget is false, which means the robot will never stop oscillating.

There are a number of ways of dealing with this problem -- the easiest is to not call setSetpoint if the input is close (within 0.001) to the original input. However, this isn't satisfactory either for a number of reasons... so I ended up writing my own magicbot-compatible implementation, it'll be part of magicbot next year.
__________________
Maintainer of RobotPy - Python for FRC
Creator of pyfrc (Robot Simulator + utilities for Python) and pynetworktables/pynetworktables2js (NetworkTables for Python & Javascript)

2017 Season: Teams #1973, #4796, #6369
Team #1418 (remote mentor): Newton Quarterfinalists, 2016 Chesapeake District Champion, 2x Innovation in Control award, 2x district event winner
Team #1418: 2015 DC Regional Innovation In Control Award, #2 seed; 2014 VA Industrial Design Award; 2014 Finalists in DC & VA
Team #2423: 2012 & 2013 Boston Regional Innovation in Control Award


Resources: FIRSTWiki (relaunched!) | My Software Stuff
Reply With Quote
  #7   Spotlight this post!  
Unread 04-07-2016, 22:03
GeeTwo's Avatar
GeeTwo GeeTwo is online now
Technical Director
AKA: Gus Michel II
FRC #3946 (Tiger Robotics)
Team Role: Mentor
 
Join Date: Jan 2014
Rookie Year: 2013
Location: Slidell, LA
Posts: 3,610
GeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond repute
Re: Why won't this PID loop stop?

If the system has enough inertia that it continues out of the tolerance range, it will continue to oscillate. If this is your issue, I suggest a more dampening D (differential term) to bring the output back when it "overshoots" the design target.
__________________

If you can't find time to do it right, how are you going to find time to do it over?
If you don't pass it on, it never happened.
Robots are great, but inspiration is the reason we're here.
Friends don't let friends use master links.
Reply With Quote
  #8   Spotlight this post!  
Unread 04-07-2016, 22:43
team-4480's Avatar
team-4480 team-4480 is offline
Debug? What's that?
FRC #4480
 
Join Date: Jan 2015
Rookie Year: 2013
Location: Minnesooota
Posts: 222
team-4480 will become famous soon enoughteam-4480 will become famous soon enough
Re: Why won't this PID loop stop?

Quote:
Originally Posted by virtuald View Post
In particular, #29 is probably the one that is biting you (it bit me for a similar reason). If you keep calling setSetpoint (like that example does), each time it is called it will reset things such that onTarget is false, which means the robot will never stop oscillating.
So if I did a state machine for that setSetpoint like this:

Code:
if state == 1:
    setSetpoint(90)
    state = 2
elif state ==2:
    if onTarget():
        state=3
Would that solve the issue?
__________________
#Python4Life
Reply With Quote
  #9   Spotlight this post!  
Unread 04-07-2016, 23:06
virtuald's Avatar
virtuald virtuald is online now
RobotPy Guy
AKA: Dustin Spicuzza
FRC #1418 (), FRC #1973, FRC #4796, FRC #6367 ()
Team Role: Mentor
 
Join Date: Dec 2008
Rookie Year: 2003
Location: Boston, MA
Posts: 1,058
virtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant future
Re: Why won't this PID loop stop?

Quote:
Originally Posted by team-4480 View Post
So if I did a state machine for that setSetpoint like this:

Code:
if state == 1:
    setSetpoint(90)
    state = 2
elif state ==2:
    if onTarget():
        state=3
Would that solve the issue?
That seems to be a bit more complex than necessary. First, don't ignore the other suggestions on this thread -- proper tuning will go a long way also. But, if you want onTarget to work, then a simpler solution is:

Code:
self.last = None
...


if self.last is None or abs(self.last - target) > 0.001:
    self.pid_controller.setSetpoint(target)
    self.last = target
__________________
Maintainer of RobotPy - Python for FRC
Creator of pyfrc (Robot Simulator + utilities for Python) and pynetworktables/pynetworktables2js (NetworkTables for Python & Javascript)

2017 Season: Teams #1973, #4796, #6369
Team #1418 (remote mentor): Newton Quarterfinalists, 2016 Chesapeake District Champion, 2x Innovation in Control award, 2x district event winner
Team #1418: 2015 DC Regional Innovation In Control Award, #2 seed; 2014 VA Industrial Design Award; 2014 Finalists in DC & VA
Team #2423: 2012 & 2013 Boston Regional Innovation in Control Award


Resources: FIRSTWiki (relaunched!) | My Software Stuff

Last edited by virtuald : 05-07-2016 at 15:45. Reason: Rename input -> target
Reply With Quote
  #10   Spotlight this post!  
Unread 05-07-2016, 12:28
team-4480's Avatar
team-4480 team-4480 is offline
Debug? What's that?
FRC #4480
 
Join Date: Jan 2015
Rookie Year: 2013
Location: Minnesooota
Posts: 222
team-4480 will become famous soon enoughteam-4480 will become famous soon enough
Re: Why won't this PID loop stop?

Quote:
Originally Posted by virtuald View Post
Code:
self.last = None
...


if self.last is None or abs(self.last - input) > 0.001:
    self.pid_controller.setSetpoint(input)
    self.last = input
I don't see how that would work if I were to give the input as 90, it would go through and then self.last would become 90 and then it wouldn't do anything because 90-90 is 0. For me, in order to get that to work, self.last would have to be set like this self.last = self.gyro.getYaw(). But I really don't know what I am doing with setting up PID loops so I could(and probably am) dead wrong.
__________________
#Python4Life
Reply With Quote
  #11   Spotlight this post!  
Unread 05-07-2016, 15:44
virtuald's Avatar
virtuald virtuald is online now
RobotPy Guy
AKA: Dustin Spicuzza
FRC #1418 (), FRC #1973, FRC #4796, FRC #6367 ()
Team Role: Mentor
 
Join Date: Dec 2008
Rookie Year: 2003
Location: Boston, MA
Posts: 1,058
virtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant futurevirtuald has a brilliant future
Re: Why won't this PID loop stop?

Quote:
Originally Posted by team-4480 View Post
I don't see how that would work if I were to give the input as 90, it would go through and then self.last would become 90 and then it wouldn't do anything because 90-90 is 0. For me, in order to get that to work, self.last would have to be set like this self.last = self.gyro.getYaw(). But I really don't know what I am doing with setting up PID loops so I could(and probably am) dead wrong.
My bad, I should have named the variable 'target', not 'input' (I've changed it above). It's the value that you pass to setSetpoint. Working through the code:

Let's say your target value is 90.

First iteration: self.last is None, setSetpoint would be called
Second iteration: self.last is 90, setSetpoint would not be called
Third iteration: self.last is 90, setSetpoint would not be called
... and so on

However, the setpoint does not get changed -- so the PIDController will still be trying to converge the output to the last setpoint that was set (which is 90). And more importantly, onTarget will work correctly, because it isn't getting reset by the call to setSetpoint.
__________________
Maintainer of RobotPy - Python for FRC
Creator of pyfrc (Robot Simulator + utilities for Python) and pynetworktables/pynetworktables2js (NetworkTables for Python & Javascript)

2017 Season: Teams #1973, #4796, #6369
Team #1418 (remote mentor): Newton Quarterfinalists, 2016 Chesapeake District Champion, 2x Innovation in Control award, 2x district event winner
Team #1418: 2015 DC Regional Innovation In Control Award, #2 seed; 2014 VA Industrial Design Award; 2014 Finalists in DC & VA
Team #2423: 2012 & 2013 Boston Regional Innovation in Control Award


Resources: FIRSTWiki (relaunched!) | My Software Stuff
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 01:14.

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