go_on
Posts: 4
Joined: Wed Jun 05, 2019 7:59 am

Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 8:23 am

Hello all, I've stuck in a stage of my project.

Shortly, I have a project for autonomous control of DC motors using Pi Camera. I've designed a Fuzzy PID Controller to do so.

PID controller's feedback is the location and radius of the target object on the camera interface. And PID controller's Kp, Ki and Kd gains are adjusted via a Mamdani Fuzzy Inference System (FIS). Then I control the motors using PWM signals. During the process I use VNC Viewer and I get the video output of the camera. So, I didn't disable these yet but if it's possible I want to keep at least the VNC Viewer.

My issue is, Mamdani FIS is running extremely slowly to calculate the result value. Takes nearly 5 seconds. I need it to calculate the value instantly. Here's the Mamdani FIS code below:

Code: Select all

import numpy as np

#Trapezoidal Membership Function
def trpmf(alt,ust,a,b,c,d,xi):
  global x 
  global mu_x 
  global mu_xi

  x1 = np.arange(alt,a-.001,.001)
  x2 = np.arange(a,b-.001,.001)
  x3 = np.arange(b,c-.001,.001)
  x4 = np.arange(c,d-.001,.001)
  x5 = np.arange(d,ust,.001)
  
  x = np.concatenate([x1,x2,x3,x4,x5])
  alfa = 1
  mux1= np.zeros(x1.shape) 
  mux2= alfa*(x2-a)/(b-a) 
  mux3= alfa*np.ones(x3.shape) 
  mux4= alfa*(x4-d)/(c-d) 
  mux5= np.zeros(x5.shape)
  mu_x = np.concatenate([mux1, mux2, mux3, mux4, mux5])

  if xi>=a and xi<b and a!=b:
    mu_xi=alfa*(xi-a)/(b-a)
  elif xi>=a and xi<b and a==b:
    mu_xi=alfa
  elif xi>=b and xi<=c:
    mu_xi=alfa
  elif xi>c and xi<=d and c!=d:
    mu_xi=alfa*(xi-d)/(c-d)
  elif xi>c and xi<=d and c==d:
    mu_xi=alfa
  else:
    mu_xi=0
  return 0

#Triangular Membership Function
def trgmf(alt,ust,a,b,c,xi):
  global x 
  global mu_x 
  global mu_xi

  x1 = np.arange(alt,a-.001,.001)
  x2 = np.arange(a,b-.001,.001)
  x3 = np.arange(b,c-.001,.001)
  x4 = np.arange(c,ust,.001)

  x = np.concatenate([x1,x2,x3,x4])
  alfa = 1

  mu_x1 = np.zeros(x1.shape)
  mu_x2 = alfa*(x2-a)/(b-a)
  mu_x3 = alfa*(x3-c)/(b-c)
  mu_x4 = np.zeros(x4.shape)
  mu_x = np.concatenate([mu_x1, mu_x2, mu_x3, mu_x4])

  if xi>=a and xi<=b:
    mu_xi = (xi-a)/(b-a)
  elif xi<=c and xi>b:
    mu_xi = (xi-c)/(b-c)
  else:
    mu_xi = 0
  return 0

#The Mamdani FIS
def mamdani_x(ei,dei,ki): 
  global x
  global mu_x
  global mu_xi
  # e(t) Error Membership Functions
  trpmf(-100,300,-55,-55,0,55,ei)
  mu_e_SC = mu_xi
  trgmf(-100,300,0,55,110,ei)
  mu_e_CA = mu_xi
  trgmf(-100,300,55,110,165,ei)
  mu_e_A = mu_xi
  trgmf(-100,300,110,165,220,ei)
  mu_e_O = mu_xi
  trgmf(-100,300,165,220,275,ei)
  mu_e_F = mu_xi
  trpmf(-100,300,220,275,300,300,ei)
  mu_e_CF = mu_xi
  # de(t) Derivative Error Membership Functions
  trpmf(-100,300,-50,-50,-3,0,dei)
  mu_de_N = mu_xi
  trpmf(-100,300,0,3,100,100,dei)
  mu_de_P = mu_xi
  trgmf(-100,300,-3,0,3,dei)
  mu_de_SC = mu_xi
  # K(z) Output Membership Function
  trpmf(-100,300,3.15,3.15,3.25,3.3,ki)
  mu_S = mu_x
  trgmf(-100,300,3.25,3.3,3.35,ki)
  mu_CD = mu_x
  trgmf(-100,300,3.3,3.35,3.4,ki)
  mu_D = mu_x
  trgmf(-100,300,3.35,3.4,3.45,ki)
  mu_OM = mu_x
  trgmf(-100,300,3.4,3.45,3.5,ki)
  mu_Y = mu_x
  trpmf(-100,300,3.45,3.5,3.6,3.6,ki)
  mu_CY = mu_x

  #Rules Base via "AND" Operation
  mu_kural1 = min(mu_e_SC,mu_de_N)
  mu_kural2 = min(mu_e_CA,mu_de_N)
  mu_kural3 = min(mu_e_A,mu_de_N)
  mu_kural4 = min(mu_e_O,mu_de_N)
  mu_kural5 = min(mu_e_F,mu_de_N)
  mu_kural6 = min(mu_e_CF,mu_de_N)

  mu_kural7 = min(mu_e_SC,mu_de_SC)
  mu_kural8 = min(mu_e_CA,mu_de_SC)
  mu_kural9 = min(mu_e_A,mu_de_SC)
  mu_kural10 = min(mu_e_O,mu_de_SC)
  mu_kural11 = min(mu_e_F,mu_de_SC)
  mu_kural12 = min(mu_e_CF,mu_de_SC)

  mu_kural13 = min(mu_e_SC,mu_de_P)
  mu_kural14 = min(mu_e_CA,mu_de_P)
  mu_kural15 = min(mu_e_A,mu_de_P)
  mu_kural16 = min(mu_e_O,mu_de_P)
  mu_kural17 = min(mu_e_F,mu_de_P)
  mu_kural18 = min(mu_e_CF,mu_de_P)

  #Result Fuzzy Sets of the Rules via "THEN" operation
  mu_sonuc1 = np.dot(mu_kural1,mu_S)
  mu_sonuc2 = np.dot(mu_kural2,mu_S)
  mu_sonuc3 = np.dot(mu_kural3,mu_CD)
  mu_sonuc4 = np.dot(mu_kural4,mu_D)
  mu_sonuc5 = np.dot(mu_kural5,mu_OM)
  mu_sonuc6 = np.dot(mu_kural6,mu_Y)

  mu_sonuc7 = np.dot(mu_kural7,mu_S)
  mu_sonuc8 = np.dot(mu_kural8,mu_CD)
  mu_sonuc9 = np.dot(mu_kural9,mu_D)
  mu_sonuc10 = np.dot(mu_kural10,mu_OM)
  mu_sonuc11 = np.dot(mu_kural11,mu_Y)
  mu_sonuc12 = np.dot(mu_kural12,mu_CY)

  mu_sonuc13 = np.dot(mu_kural13,mu_CD)
  mu_sonuc14 = np.dot(mu_kural14,mu_D)
  mu_sonuc15 = np.dot(mu_kural15,mu_OM)
  mu_sonuc16 = np.dot(mu_kural16,mu_Y)
  mu_sonuc17 = np.dot(mu_kural17,mu_CY)
  mu_sonuc18 = np.dot(mu_kural18,mu_CY)

  #Output Fuzzy Set via "IMPLEMENTATION" Operation
  mu_b1 = max(max(mu_sonuc1,mu_sonuc2,key=tuple),mu_sonuc3,key=tuple)
  mu_b2 = max(max(mu_sonuc4,mu_sonuc5,key=tuple),mu_sonuc6,key=tuple)
  mu_b3 = max(max(mu_sonuc7,mu_sonuc8,key=tuple),mu_sonuc9,key=tuple)
  mu_b4 = max(max(mu_sonuc10,mu_sonuc11,key=tuple),mu_sonuc12,key=tuple)
  mu_b5 = max(max(mu_sonuc13,mu_sonuc14,key=tuple),mu_sonuc15,key=tuple)
  mu_b6 = max(max(mu_sonuc16,mu_sonuc17,key=tuple),mu_sonuc18,key=tuple)
  mu_bx = max(max(mu_b1,mu_b2,key=tuple),mu_b3,key=tuple)
  mu_by = max(max(mu_b4,mu_b5,key=tuple),mu_b6,key=tuple)
  mu_birlestirme = max(mu_bx,mu_by,key=tuple)

  #The Result of Numerical Output via "DEFUZZYICATION" Operation
  a_cbk = sum(mu_birlestirme)
  k = sum([np.dot(mu_birlestirme,x)])/a_cbk
  return k


Kp = mamdani_x(275,-21,0)
Ki = Kp/2
Kd = Ki/2
print(Kp)
I've tried to use ZRAM but it only improved the performance like 0,5 sec, so it looked like irrelevant to my issue. Also I've seen this parallel python thing but I couldn't download Cython on the device.
Any help will be appreciated.
Last edited by go_on on Wed Jun 05, 2019 10:17 am, edited 1 time in total.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 23083
Joined: Sat Jul 30, 2011 7:41 pm

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 9:00 am

I cannot really comment much on the algorithm, but it doesnt seem to have loops that can be optimised etc.

So that leaves things like compiling the Python code rather than interpreting it, or perhaps rewriting the code in a faster language (C, C++). However, AIUI, Numpy is a C library under Python so I would expect that to work fairly quickly already.

This might help with using C/C++ https://stackoverflow.com/questions/111 ... rays-for-c

EDIT: what is the input? Can you make it 'smaller'?
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
"My grief counseller just died, luckily, he was so good, I didn't care."

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 7026
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 9:09 am

Use "htop" or similar to confirm that it is Python itself that is maxing out, rather than something else on the system. (VNC will be consuming a chunk of resources)
Insert some time measurement within your code to see whether there are particular operations that take the majority of the time. Those are then the best candidates for optimising (if possible).
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

go_on
Posts: 4
Joined: Wed Jun 05, 2019 7:59 am

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 10:34 am

Firstly, thanks for your opinions. I'm a newby to this forum and was worried if noone would try to help me out.
jamesh wrote:
Wed Jun 05, 2019 9:00 am
I cannot really comment much on the algorithm, but it doesnt seem to have loops that can be optimised etc.

So that leaves things like compiling the Python code rather than interpreting it, or perhaps rewriting the code in a faster language (C, C++). However, AIUI, Numpy is a C library under Python so I would expect that to work fairly quickly already.

This might help with using C/C++ https://stackoverflow.com/questions/111 ... rays-for-c

EDIT: what is the input? Can you make it 'smaller'?
I haven't got enough time for rewriting the code with another language. Need to handle it using Python I'm afraid.

My inputs are two error functions by pixels. The difference of the reference values and the values of radius and the location of the centre (x,y) of an object which is tracked by an object tracking program. They have values between 0-60 and 0-275. But couldn't understand how this is relevant? Functions with smaller values, faster program? I haven't gone for the 0-60 values yet. Maybe it will be faster, I'll try this out.
6by9 wrote:
Wed Jun 05, 2019 9:09 am
Use "htop" or similar to confirm that it is Python itself that is maxing out, rather than something else on the system. (VNC will be consuming a chunk of resources)
Insert some time measurement within your code to see whether there are particular operations that take the majority of the time. Those are then the best candidates for optimising (if possible).
I've also tried to do this but couldn't understand what is the screen showing to me :)
I'll try the time measurements too.

--

Thanks for the advices and sorry for my English if it's awful :)

go_on
Posts: 4
Joined: Wed Jun 05, 2019 7:59 am

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 12:29 pm

6by9 wrote:
Wed Jun 05, 2019 9:09 am
Use "htop" or similar to confirm that it is Python itself that is maxing out, rather than something else on the system. (VNC will be consuming a chunk of resources)
Insert some time measurement within your code to see whether there are particular operations that take the majority of the time. Those are then the best candidates for optimising (if possible).
Oh, here's my htop output. It looks like my program is maxing out the system while VNC isn't that effective.
What do I need to do now? Is there a solution for my issue?

Image

By the way, do you recommend Cython in order the running the codes faster? I'm afraid to install that if it would effect the Python in a bad way on my system and erase some files so I weren't be able to run my programs anymore? :) ;) Does it do something like this? Effect my system and destroy my project? :) I know I look paranoid but I really need to be careful.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 23083
Joined: Sat Jul 30, 2011 7:41 pm

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 12:44 pm

Can you move some procressing to another core? It's maxed out on one core only.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
"My grief counseller just died, luckily, he was so good, I didn't care."

User avatar
bensimmo
Posts: 4129
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 3:16 pm

Have a look here to see if you can work out which version will be quickest for you.
Or just install and try it yourself.
Better still if you clone your card so you have a backup. It's a little old but, since pythons now testing 3.8 version.
“Which is the fastest version of Python?” by Anthony Shaw https://link.medium.com/fcpDJdu7gX

Or look to see if something in the SciPy module can do some of the hard lifting?

Remove global variables if possible (apparently slower)
Setup the main code into a main function (again apparently quicker).
Python startup *is* slow, get a faster SD card?

go_on
Posts: 4
Joined: Wed Jun 05, 2019 7:59 am

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 3:42 pm

jamesh wrote:
Wed Jun 05, 2019 12:44 pm
Can you move some procressing to another core? It's maxed out on one core only.
Do you recommend any method to achieve this? I've tried multiprocessing but I've failed.

I'm quite new all to this staff.

Thanks.
bensimmo wrote:
Wed Jun 05, 2019 3:16 pm
Have a look here to see if you can work out which version will be quickest for you.
Or just install and try it yourself.
Better still if you clone your card so you have a backup. It's a little old but, since pythons now testing 3.8 version.
“Which is the fastest version of Python?” by Anthony Shaw https://link.medium.com/fcpDJdu7gX

Or look to see if something in the SciPy module can do some of the hard lifting?

Remove global variables if possible (apparently slower)
Setup the main code into a main function (again apparently quicker).
Python startup *is* slow, get a faster SD card?
I was considering to install Cython when i saw the parallel python video. But I was afraid to install because I'm worried if it may conflict with my Pi's Python and cause errors which would destroy me psycologically. But I'll check PyPy.

I use Samsung 32GB microSDHC. I'll try to remove those global variables and code in main func too. Thank you.
Last edited by go_on on Wed Jun 05, 2019 3:54 pm, edited 2 times in total.

Heater
Posts: 12976
Joined: Tue Jul 17, 2012 3:02 pm

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 3:51 pm

Your code, as posted, takes nearly two and a half seconds to run on my 64 Intel PC.

Code: Select all

$ time python go_on.py
3.44949019632

real    0m2.361s
user    0m1.281s
sys     0m2.078s
In my experience a Pi 3 is 5 or 10 times slower than my PC. Python of course is 10 or a 100 times slower than a compiled language like C or C++. I have algorithms that take a minute in Python but less than 500ms in C.

As such I think that if you want "instant" results, you are going to need to recode all of that in a more performant language.
I need it to calculate the value instantly.
That of course is impossible.

What you need to do is make your PID control loop work about 10 times faster than the thing you are trying to control can respond. Preferably with an accurate iteration period.

By the way, your code does actually run on my PC. I have no camera input or image detection or motor control outputs, have you taken the time for all that into account?

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 23083
Joined: Sat Jul 30, 2011 7:41 pm

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 4:23 pm

go_on wrote:
Wed Jun 05, 2019 3:42 pm
jamesh wrote:
Wed Jun 05, 2019 12:44 pm
Can you move some procressing to another core? It's maxed out on one core only.
Do you recommend any method to achieve this? I've tried multiprocessing but I've failed.

I'm quite new all to this staff.

Thanks.
Sorry not familiar with Python, and have no time anyway.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
"My grief counseller just died, luckily, he was so good, I didn't care."

User avatar
bensimmo
Posts: 4129
Joined: Sun Dec 28, 2014 3:02 pm
Location: East Yorkshire

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 5:27 pm

go_on wrote:
Wed Jun 05, 2019 3:42 pm

I was considering to install Cython when i saw the parallel python video. But I was afraid to install because I'm worried if it may conflict with my Pi's Python and cause errors which would destroy me psycologically. But I'll check PyPy.

I use Samsung 32GB microSDHC. I'll try to remove those global variables and code in main func too. Thank you.
That's what I recommend a copy of the card, if you can get another one.
It's easy to go back :-)

I don't know how much they will save, it's probably only fractions and tiny fraction of a second in the setup of the function.etc., you'll need to find which part is slow.
Time each function first.
there is a module called timit, but I've never used it (I've always use time (start and stop) module, which is not the most accurate method, but does work reasonably to get ideas.

MarkTF
Posts: 297
Joined: Tue Mar 03, 2015 4:59 pm

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 8:51 pm

go_on wrote:
Wed Jun 05, 2019 8:23 am
Any help will be appreciated.
I'd start by getting rid of passing results via global variables and explicitly return those values from each function definition. I suspect you might be generating some large arrays in the function calls that aren't actually used, but it's very hard to follow the program flow with global variables.

hippy
Posts: 5610
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Python code is being executed slowly on Pi 3 B+

Wed Jun 05, 2019 11:54 pm

go_on wrote:
Wed Jun 05, 2019 3:42 pm
I was considering to install Cython ... But I was afraid to install because I'm worried if it may conflict with my Pi's Python and cause errors which would destroy me psycologically.
cython can be installed without any impact on Python itself.

Its most basic function is generating a .c file from your .py code. When that's compiled into a library, which can then be called by other Python code, it will then run more quickly.

wrapper.py

Code: Select all

import main
main.HelloWorld()
main.pyx <- Note that is .pyx, not .py

Code: Select all

def HelloWorld():
  print("Hello World!")
setup.py

Code: Select all

from distutils.core import setup
from Cython.Build import cythonize
setup( ext_modules = cythonize("main.pyx") )
Then it is simply a case of ...

Code: Select all

sudo apt-get install cython
python setup.py build_ext --inplace
python wrapper.py
That will then converts main.pyx into main.c, compiles and links it to main.so, which the wrapper.py includes and calls. The "Hello World" message is printed from within the C extension 'main'.

So, if you put your existing code in 'main.pyx', rebuild the extension, when you call your main your existing code will be run as if it had been C code.

pootle
Posts: 323
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

Re: Python code is being executed slowly on Pi 3 B+

Thu Jun 06, 2019 6:31 am

I think you should be able to get a big improvement by refactoring the code, and potentially get numpy to do a lot more work per call (and fewer calls).

Can you declare the numpy arrays once up front and re-use them?

Can you shape the data so that the sequences like:

Code: Select all

  mu_kural1 = min(mu_e_SC,mu_de_N)
  mu_kural2 = min(mu_e_CA,mu_de_N)
  mu_kural3 = min(mu_e_A,mu_de_N)
  mu_kural4 = min(mu_e_O,mu_de_N)
  mu_kural5 = min(mu_e_F,mu_de_N)
  mu_kural6 = min(mu_e_CF,mu_de_N)

  mu_kural7 = min(mu_e_SC,mu_de_SC)
  mu_kural8 = min(mu_e_CA,mu_de_SC)
  mu_kural9 = min(mu_e_A,mu_de_SC)
  mu_kural10 = min(mu_e_O,mu_de_SC)
  mu_kural11 = min(mu_e_F,mu_de_SC)
  mu_kural12 = min(mu_e_CF,mu_de_SC)

  mu_kural13 = min(mu_e_SC,mu_de_P)
  mu_kural14 = min(mu_e_CA,mu_de_P)
  mu_kural15 = min(mu_e_A,mu_de_P)
  mu_kural16 = min(mu_e_O,mu_de_P)
  mu_kural17 = min(mu_e_F,mu_de_P)
  mu_kural18 = min(mu_e_CF,mu_de_P)
are a single call.

Also can you reduce the size of the data sets - you are using some pretty big numpy arrays.

You may not need to use the camera at full resolution - using a binning mode or even getting the camera to resize the image to reduce the size of the arrays would make a huge difference.

What actual speed do you require? - as heater said yuo only need to feedback loop to go about 10 X as fast as the response time of the underlying motors etc. I found even with small (micrometal) motors, by the time rotational inertia of the motor / gearbox / and whatever it drives was accounted for, I only needed about 20 loops per second to get good control.

pootle
Posts: 323
Joined: Wed Sep 04, 2013 10:20 am
Location: Staffordshire
Contact: Website

Re: Python code is being executed slowly on Pi 3 B+

Thu Jun 06, 2019 6:39 am

I'm also wondering what benefit the fuzzies bring to a reasonably well setup pid control loop. Have you tried running with just a straight pid control loop?

Return to “General discussion”