Search code examples
pythonattributeerrormicropythonpid-controller

microPython attributeError in __init__


EDIT: Thanks to the age old tradition of unplugging and plugging everything back in I got it to work; I reflashed the WiPy module and reinstalled the Pymakr plugin.

I am currently in the process of writing a PID-controller for micropython (we have to make a linefollower). I have implemented the PID algorithm in microPython as a class.

I will be using the WiPy module from Pycom to control my linefollower.

For now the actual program doesn't do much, I just wanted to test if the program was reasonably fast, as such I have some random numbers for the input and the K-values and the output function is just left empty.

However whenever I try to run a little test script where I create the object and calculate the PID a 100 times, I get an attributeError in the init of the PID-class. This is the method that gives me trouble:

def __init__(self, input_func, output_func, P_factor=1.0, I_factor=0.0,
             D_factor=0.0):

    ... previous variable declarations ...

    # Initializer for the time. This will form the basis for the timebased
    # calculations. This time will mark the start of a time-block.
    self.last_calculate_time = utime.ticks_ms()

The last line is the one that gives me trouble. The main program has this in it:

def motorOutput(PID_output):
    """
    Function for driving the two motors depending on the PID output.
    """
    pass

def generateInput():
    """
    Return a random float
    """
    return 2.5


if __name__ == "__main__":

    print("creating PID controller")
    PID_controller = PID.PID(generateInput, motorOutput, 1.0, 0.5, 1.5)
    counter = 0
    print("starting loop")
    while counter < 1000:
        counter += 1
        PID_controller.calculate()

    print("finished loop")

This is the output that I get when running the file:

>>> Running main.py

>>>
>>> creating PID controller
╝Traceback (most recent call last):
File "<stdin>", line 60, in <module>
File "/flash/lib/PID.py", line 95, in __init__
AttributeError: 'PID' object has no attribute 'last_calculate_time'
╝>
MicroPython v1.8.6-621-g17ee404e on 2017-05-25; WiPy with ESP32

Solution

  • You're receiving this error because you are attempting to assign an attribute which hasn't been declared and I assume you are using python 2's classic class style. Add a definition for last_calculate_time in your PID class such as last_calculate_time = None and then it should work as expected.

    A more suitable approach would be passing object as an argument to your class definition as below, causing it to be treated as a New Style Class:

    class PID(object):
        def __init__(self):
            self.last_calculate_time = utime.ticks_ms()
    

    More information can be seen at: https://wiki.python.org/moin/NewClassVsClassicClass