Go to Post Engineers can really make a difference when people are in their time of need. - Elgin Clock [more]
Home
Go Back   Chief Delphi > Technical > Programming > Python
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 14-03-2014, 02:48
myork myork is offline
Registered User
FRC #2928
 
Join Date: Feb 2014
Location: United States
Posts: 11
myork has a spectacular aura aboutmyork has a spectacular aura about
PIDController causing code to fail silently

Hola,

We attempted to add a PIDController to our RobotPy code:


self.left_motors = wpilib.Talon(2)
self.left_encoder = wpilib.Encoder(2, 3)
self.left_pid_controller = wpilib.PIDController(self.p, self.i, self.d, self.left_encoder, self.left_motors)


But having the PIDController constructor line causes very strange behavior:

We raise a SystemExit when a joystick button is pressed in order to have RobotPy hot reload the code. This works fine, but if we include the PIDController line the code completely stops running. By "stops running" I mean Robot Comms are green, Robot Code is green, SmartDashboard says it's connected, but the none of the code is run. Print statements won't work, SmartDashboard updates on every tick aren't happening, etc. There is no Python running on the cRio.

Any idea what's going on or how to fix it?
Reply With Quote
  #2   Spotlight this post!  
Unread 14-03-2014, 13:49
Joe Ross's Avatar Unsung FIRST Hero
Joe Ross Joe Ross is offline
Registered User
FRC #0330 (Beachbots)
Team Role: Engineer
 
Join Date: Jun 2001
Rookie Year: 1997
Location: Los Angeles, CA
Posts: 8,558
Joe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond reputeJoe Ross has a reputation beyond repute
Re: PIDController causing code to fail silently

Is anything printed to the console?
Reply With Quote
  #3   Spotlight this post!  
Unread 15-03-2014, 01:41
Peter Johnson Peter Johnson is offline
WPILib Developer
FRC #0294 (Beach Cities Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Redondo Beach, CA
Posts: 247
Peter Johnson has much to be proud ofPeter Johnson has much to be proud ofPeter Johnson has much to be proud ofPeter Johnson has much to be proud ofPeter Johnson has much to be proud ofPeter Johnson has much to be proud ofPeter Johnson has much to be proud ofPeter Johnson has much to be proud of
Re: PIDController causing code to fail silently

It sounds like a crash, although it's hard to know for sure without a NetConsole dump (which should print something if this happens). Assuming it's a crash, I'll explain what's likely going on. There's a workaround (reimplement the PIDController class in Python), but naturally that's a bit ugly. I don't have a real fix at the moment, although I'll try to reproduce this locally.

Basically the problem is that hot reloads on the cRio VxWorks OS are a hack with resultant ugly corner cases, mostly because both Python and WPILib don't have good cleanup code. The hot reload implementation will be much cleaner and work much better on the 2015 control system (which is based on Linux instead of VxWorks), as it will be straightforward to restart the entire robot process (yes, this means that we can get really fancy and auto-restart immediately on file edits, without even a button press).

In short, when you set up a PIDController:
- RobotPy's PIDController is a wrapper around the WPILib C++ PIDController class.
- The WPILib C++ PIDController class uses the WPILib Notifier class and asks for the Calculate callback to get called every X ms.
- The Notifier class uses the FPGA timer and low-level interrupts to call back into the PIDController.

When you do a hot reload, the RollbackImporter tries to delete all of the loaded modules, and all of them are reloaded the next time your code imports them. The modules include wpilib itself, and I'm guessing that for some reason the Notifier itself or the PIDController callback is not getting cleaned up properly, and when the next timer tick comes along X ms later, the interrupt handler references a dangling pointer, resulting in a crash. It's also conceivable a race condition exists somewhere in the cleanup process.
__________________
Author of cscore - WPILib CameraServer for 2017+
Author of ntcore - WPILib NetworkTables for 2016+
Creator of RobotPy - Python for FRC

2010 FRC World Champions (294, 67, 177)
2007 FTC World Champions (30, 74, 23)
2001 FRC National Champions (71, 294, 125, 365, 279)
Reply With Quote
  #4   Spotlight this post!  
Unread 16-03-2014, 16:26
myork myork is offline
Registered User
FRC #2928
 
Join Date: Feb 2014
Location: United States
Posts: 11
myork has a spectacular aura aboutmyork has a spectacular aura about
Re: PIDController causing code to fail silently

Harumph. The netconsole did not indicate any crashes. With a different problem we had a crash and the netconsole output something like "fatal exception at 0x00000000". This did not happen with the PIDController line.

The output we had was strange, now that I think more about it. If I remember correctly it printed:

System exit called

and nothing after that.

This is part of our boot.py:

Code:
    ...
    while True:
        rollback = RollbackImporter()
        robot = None
        try:
            print("Importing user code.")
            robot = __import__("robot")
            print("Running user code.")
            robot.run()
            #runpy.run_module("robot", run_name="__main__")
        except SystemExit:
            print("System exit called")
            pass
        except:
            print("-"*60)
            traceback.print_exc(file=sys.stdout)
            print("-"*60)

    print("User code raised SystemExit; waiting 2 seconds before restart")
    time.sleep(2)
    ...

We would expect to see "User code raised SystemExit;..." after "System exit called", but we didn't.

Hmmm.... I think we've abandoned the PIDController for this season, but I'd like to figure out this problem as soon as I get the chance.
Reply With Quote
  #5   Spotlight this post!  
Unread 16-03-2014, 16:54
virtuald's Avatar
virtuald virtuald is offline
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,040
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: PIDController causing code to fail silently

For what it's worth, I've never trusted the hot reload functionality, and we just always reboot our robot when we're reloading code. It's only 30 seconds or so.
__________________
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
  #6   Spotlight this post!  
Unread 16-03-2014, 17:02
virtuald's Avatar
virtuald virtuald is offline
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,040
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: PIDController causing code to fail silently

Also, I've had very odd problems in the past using the PIDController, so I've tried to avoid using it for most things. When we've needed that level of control, we tend to use the PID control available on the Jaguar, instead of using the PIDController class.

One thing worth noting too is you can get more consistent control on your main thread if you control the amount of delay more precisely than using wpilib.Wait() at the end of each loop. We use this object to do it.

Code:
try:
    import wpilib
except ImportError:
    from pyfrc import wpilib


class PreciseDelay(object):
    '''
        Used to synchronize a timing loop.

        Usage:

            delay = PreciseDelay(time_to_delay)
            while something:
                # do things here
                delay.wait()

        TODO: Does this add unwanted overhead?
    '''
    
    def __init__(self, delay_period):
        '''
            :param delay_period: The amount of time to do a delay
        '''
        
        self.timer = wpilib.Timer()
        self.delay_period = delay_period
        
        self.timer.Start()
        
    def wait(self):
        '''Waits until the delay period has passed'''
        
        # we must *always* yield here, so other things can run
        wpilib.Wait(0.001)
        
        while not self.timer.HasPeriodPassed(self.delay_period):
            wpilib.Wait(0.001)
With something like this controlling your delay, you can implement PID-like control in your main loop without too many problems.
__________________
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 16-03-2014, 17:52
myork myork is offline
Registered User
FRC #2928
 
Join Date: Feb 2014
Location: United States
Posts: 11
myork has a spectacular aura aboutmyork has a spectacular aura about
Re: PIDController causing code to fail silently

Awesome PreciseDelay. Thanks, Dustin
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 19:53.

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