m-lundberg / simple-pid

A simple and easy to use PID controller in Python
MIT License
801 stars 217 forks source link

output_limits incompatible with calling pid on non-singleton arrays #18

Closed glucenag closed 4 years ago

glucenag commented 4 years ago

Hey there,

I'd like to call pid on a (2,) numpy array (say), as in:


pid = PID(1,2,3,setpoint=0)
cv = pid(pv)

This works fine UNLESS I set

pid.output_limits = (-10, 10)

which itself works fine when pid is called on singletons. Otherwise I get the error:

Traceback (most recent call last):
  File "C:\Users\james\anaconda3\envs\venv37_drift_null\lib\threading.py", line 926, in _bootstrap_inner
    self.run()
  File "C:\Users\james\anaconda3\envs\venv37_drift_null\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "<input>", line 92, in driftNulling
  File "C:\Users\james\anaconda3\envs\venv37_drift_null\lib\site-packages\simple_pid\PID.py", line 101, in __call__
    self._integral = _clamp(self._integral, self.output_limits)  # avoid integral windup
  File "C:\Users\james\anaconda3\envs\venv37_drift_null\lib\site-packages\simple_pid\PID.py", line 9, in _clamp
    elif upper is not None and value > upper:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Any hints ?

Thanks !

Gustavo

glucenag commented 4 years ago

Any ideas anyone ? Struggling with this ...

m-lundberg commented 4 years ago

Hello,

First off, sorry for the slow response.

The library does not officially support passing an array as input to the PID. The library deliberately has no dependencies (such as numpy) to keep it light and simple. The fact that it worked at all in some cases was just a happy accident I'm afraid.

You should be able to get around this pretty easily though. If I understand you correctly, you want your output (cv) to be an array containing one value for each value in pv, right? If so, you could use

cv = np.array([pid(x) for x in pv])

or something similar depending on what you want exactly.

That said, I might look into what it would take to support taking arrays as input if I have time sometime. It might be possible to implement support without actually requiring numpy to be installed.

glucenag commented 4 years ago

Hey there. No worries. I implemented it like you suggested. Easy workaround. Thanks for answering!

m-lundberg commented 4 years ago

Glad I could help!