Skip to content

Implement a better algorithm for pole placement #117

Closed

Description

@vmatos

Hello!
I've happened to compare pole placement with Matlab's, and found out that returned matrix doesn't make the poles fall in the chosen values.
I made an example script just like python-control/examples/slicot-test.py for matlab and python.

Matlab script:

A = [
[                0, 0, 0, 1],
[-42.7207306947135, 0, 0, 0],
[                0, 0, 0, 0],
[ 47.0334901743703, 0, 0, 0]];

C = [[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]];

p = [-31., -21., -20., -30.];

L = place(A',C',p)
eigs(A' - C'*L)

% L= 31.0000  -42.7207         0   47.0335
%          0   21.0000         0         0
%          0         0   20.0000         0
%     1.0000         0         0   30.0000
% eigs = -20, -21, -30, -31

Python script:

import numpy as np              # Numerical library
from scipy import *             # Load the scipy functions
from control.matlab import *    # Load the controls systems library

A = matrix([
[                0, 0, 0, 1],
[-42.7207306947135, 0, 0, 0],
[                0, 0, 0, 0],
[ 47.0334901743703, 0, 0, 0]])

C = matrix([[ 1.,  0.,  0.,  0.],
       [ 0.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  1.]])

p = [-31., -21., -20., -30.]
L = place(A.T, C.T, p)
print "Pole place: L = ", L
print "Pole place: eigs = ", np.linalg.eig(A.T - C.T * L)[0]

#Pole place: L =  [[  0.73152698  -1.12180554  -0.           5.01688279]
# [ -1.12180554  22.72030247  -0.          -7.69345088]
# [ -0.          -0.          20.          -0.        ]
# [  5.01688279  -7.69345088  -0.          34.40626723]]
#Pole place: eigs =  [ -6.85809669 -30.         -21.         -20.        ]
# >>> control.__version__
# '0.7.0'

Am I using it wrong?

Activity

  1. robertobucher commented on Oct 11, 2016

    @robertobucher
    Member

    The problemis related to the MIMO system: it doesn't have a unique
    solution! SW like Matlab or Scilab or Scicoslab use algorithms that are
    able to find well conditioned solutions, python not!

    For my lab I've implemented a replacement of the usual python "place"
    command, in order to implement a wrapper to old fortran functions, able
    to solve this problem finding a good solution. The solution is not
    exactly the same found in Matlab, but it is well conditioned and usable
    in real experiments.

    The implemented SW is available at my homepage (robertobucher.dti.supsi.ch)

    Roberto

    On 10/11/2016 04:44 PM, Vitor Matos wrote:

    Hello!
    I've happened to compare pole placement with Matlab's, and found out
    that returned matrix doesn't make the poles fall in the chosen values.
    I made an example script just like
    |python-control/examples/slicot-test.py| for matlab and python.

    Matlab script:

    |A = [ [ 0, 0, 0, 1], [-42.7207306947135, 0, 0, 0], [ 0, 0, 0, 0], [
    47.0334901743703, 0, 0, 0]]; C = [[ 1., 0., 0., 0.], [ 0., 1., 0.,
    0.], [ 0., 0., 1., 0.], [ 0., 0., 0., 1.]]; p = [-31., -21., -20.,
    -30.]; L = place(A',C',p) eigs(A' - C'*L) % L= 31.0000 -42.7207 0
    47.0335 % 0 21.0000 0 0 % 0 0 20.0000 0 % 1.0000 0 0 30.0000 % eigs =
    -20, -21, -30, -31 |

    Python script:

    |import numpy as np # Numerical library from scipy import * # Load the
    scipy functions from control.matlab import * # Load the controls
    systems library A = matrix([ [ 0, 0, 0, 1], [-42.7207306947135, 0, 0,
    0], [ 0, 0, 0, 0], [ 47.0334901743703, 0, 0, 0]]) C = matrix([[ 1.,
    0., 0., 0.], [ 0., 1., 0., 0.], [ 0., 0., 1., 0.], [ 0., 0., 0., 1.]])
    p = [-31., -21., -20., -30.] L = place(A.T, C.T, p) print "Pole place:
    L = ", L print "Pole place: eigs = ", np.linalg.eig(A.T - C.T * L)[0]
    #Pole place: L = [[ 0.73152698 -1.12180554 -0. 5.01688279] # [
    -1.12180554 22.72030247 -0. -7.69345088] # [ -0. -0. 20. -0. ] # [
    5.01688279 -7.69345088 -0. 34.40626723]] #Pole place: eigs = [
    -6.85809669 -30. -21. -20. ] # >>> control.version # '0.7.0' |

    Am I using it wrong?

    —
    You are receiving this because you are subscribed to this thread.
    Reply to this email directly, view it on GitHub
    #117, or mute
    the thread
    https://github.com/notifications/unsubscribe-auth/AH9h_u_TnU6GaDcZUrLQnqW3k9XId1shks5qy6DlgaJpZM4KTtoW.

  2. vmatos commented on Oct 11, 2016

    @vmatos
    Author

    Thank you Roberto!
    Meanwhile I found that scipy already has scipy.signal.place_poles, which results in the same as Matlab for this system.

  3. murrayrm commented on Oct 11, 2016

    @murrayrm
    Member

    I think we should leave this issue open. We should do one of the following:

    • Replace the current python-control place function with 'scipy.signal.place_poles'
    • Rewrite the current python-control place to provide well-conditioned solutions

    I think I prefer the first as long as scipy.signal.place_poles is compatible. We would just convert control.place to a wrapper function (we already require scipy as a dependency).

  4. changed the title [-]Pole placement not right?[/-] [+]Implement a better algorithm for pole placement[/+] on Dec 30, 2017
  5. don4get commented on Jan 5, 2019

    @don4get
    Contributor

    It seems like this issue is already solved as there are now 4 possible ways to make pole placement (2 from scipy, one from slycot and one last without dependency).

  6. added this to the 0.8.3 milestone on May 12, 2019
  7. murrayrm commented on Jun 9, 2019

    @murrayrm
    Member

    Issue is resolved. Current place function uses SciPy and there are alternatives available (place_varga, acker).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions