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
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