Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Luenberger/Ackermann pole placement for MIMO systems. #456

Open
tfoliva opened this issue Mar 20, 2021 · 12 comments
Open

Luenberger/Ackermann pole placement for MIMO systems. #456

tfoliva opened this issue Mar 20, 2021 · 12 comments

Comments

@tfoliva
Copy link
Contributor

tfoliva commented Mar 20, 2021

I was in need of a function to perform state observers pole placement, so I wrote a wrapper function around the place(A, B, p) function as luenberger(A, C, p) which returns the observer gain matrix L. It makes use of the dual property between observability and controllability. I don't know if it is of any use, if it is I can push the code. Otherwise, if the decision to have only the place command was a deliberate project choice, please disregard.

On the other hand, I noticed that the ackermann function is only implemented for SISO systems. Is implementing it for MIMO systems on the roadmap? If it is, I can try to work on that...

@tfoliva
Copy link
Contributor Author

tfoliva commented Mar 20, 2021

I now noticed that #384 already mentions the second part of the issue.

@albheim
Copy link
Member

albheim commented Mar 21, 2021

For me personally I find it easy enough to use place(A, B, p) and place(A', C', p) so I don't really feel the need for a specific wrapper for that, but I'm not against it either.

For the second part we most certainly would like a MIMO place function, though I don't think ackermann works for MIMO so we have to look to other algorithms.

Connected to the issue you mentioned I actually started #402 a while ago. I implemented the basic version of the place that MATLAB uses, and was a bit dissappointed when I realised it only handled real poles and I didn't understand how to make it more general as MATLAB has. Haven't had time to look at it again since I lost motivation back then so it is just sitting there for now, think it is pretty much working but as I said, just real poles.

I had a quick look at robpole which seemed reasonable, and there are existing implementations in both python and matlab to get help with understanding the algorithm, so could maybe be a good option. But if you decide to take a look I think you can have a go at anything you think looks interesting.

@baggepinnen
Copy link
Member

We could at the very least document how to place poles for an observer in the Docstring to place, don't forget to transpose the resulting matrix as well

@albheim
Copy link
Member

albheim commented Mar 21, 2021

We could at the very least document how to place poles for an observer in the Docstring to place, don't forget to transpose the resulting matrix as well

Agreed, and maybe I need a wrapper given how well I remember to use it... As I said, not against it :)

@tfoliva
Copy link
Contributor Author

tfoliva commented Mar 21, 2021

We could at the very least document how to place poles for an observer in the Docstring to place, don't forget to transpose the resulting matrix as well

I did transpose the resulting matrix. This seems like a reasonable solution to me, one less function to "clunk" the library but the documentation should suffice in aiding anyone in need of such function. As for the documentation, I already wrote this piece of docstring (and adaptation of place's docstring) when writing my implementation of luenberger, so I think it could be repurposed

"""
    luenberger(A, C, p)
    luenberger(sys::StateSpace, p)

Calculate gain matrix `L` such that the poles of `(A - LC)` are in `p`.
Uses sytem's dual form (Controllability-Observability duality) applied to Ackermann's formula.
That is, `(A - BK)` is indentic to `(A' - C'L') == (A - LC)`.
"""

@tfoliva
Copy link
Contributor Author

tfoliva commented Mar 21, 2021

I am new to contributing on Github so I don't have much practice with pull requests and the whole workflow needed to get them approved, but I could try pushing the wrapper and the documentation...

@baggepinnen
Copy link
Member

This change would be so simple that you could probably try editing the file directly in github's web editor, just click the pen symbol when viewing the file.

@tfoliva
Copy link
Contributor Author

tfoliva commented Mar 21, 2021

For me personally I find it easy enough to use place(A, B, p) and place(A', C', p) so I don't really feel the need for a specific wrapper for that, but I'm not against it either.

For the second part we most certainly would like a MIMO place function, though I don't think ackermann works for MIMO so we have to look to other algorithms.

Connected to the issue you mentioned I actually started #402 a while ago. I implemented the basic version of the place that MATLAB uses, and was a bit dissappointed when I realised it only handled real poles and I didn't understand how to make it more general as MATLAB has. Haven't had time to look at it again since I lost motivation back then so it is just sitting there for now, think it is pretty much working but as I said, just real poles.

I had a quick look at robpole which seemed reasonable, and there are existing implementations in both python and matlab to get help with understanding the algorithm, so could maybe be a good option. But if you decide to take a look I think you can have a go at anything you think looks interesting.

I did take a look on your code yesterday and thought it seems promising. As for a more general version like the one MATLAB implements, I also looked over to the python control systems library and saw that their version wraps around a scipy.signal similar function which uses the algorithm you mentioned.

However, when using it today for the first time I had some trouble placing repeated poles on the same location... So I don't know yet if I did something wrong or if it is a limitation of the algorithm.

@olof3
Copy link
Contributor

olof3 commented Apr 3, 2021

I thought the conclusion was that there should be no added function, but an update to the docs, which I agree would be useful.

However it seems like this wrapper luenberger was indeed added in #457 ?!

The naming of luenberger and place is not symmetrical and quite confusing. And as @albheim wrote above

For me personally I find it easy enough to use place(A, B, p) and place(A', C', p) so I don't really feel the need for a specific wrapper for that, but I'm not against it either.

I see absolutely no need for it either. I think that we should revert this, but update the docs as was suggested above.

@tfoliva
Copy link
Contributor Author

tfoliva commented Apr 3, 2021

We could at the very least document how to place poles for an observer in the Docstring to place, don't forget to transpose the resulting matrix as well

Agreed, and maybe I need a wrapper given how well I remember to use it... As I said, not against it :)

I thought the conclusion was that the wrapper function would be useful, so I made the PR. But I agree that the naming convention is not symmetric either, it was just that I could not thing of a better name.

However, I think that reverting the change and just updating the documentation is OK as well...

Perhaps another option would be to make place take an optional argument (:c for control and :o for observer) like

place(A, B, p, :c)
place(A, C, p, :o)

Which would inform the function if the user intended to place observer poles or control poles. This way the naming convention is preserved, the user gets the added comfort of having an observer pole placement function and it's one less function.
I think it could even default to :c.

@olof3
Copy link
Contributor

olof3 commented Apr 3, 2021

However, I think that reverting the change and just updating the documentation is OK as well...

Perhaps another option would be to make place take an optional argument (:c for control and :o for observer) like

Yes, both options would be improvements. I think that I prefer your idea with :c/:o.

@olof3 olof3 mentioned this issue May 13, 2021
@stephans3
Copy link

You can find three simple methods of pole placement for MIMO systems in the Wikibooks about Control Systems.

Recently I have found the preprint Refined Transformation Approach for Stabilization of MIMO System by Pole Placement which seems to be a simple approach as well but I haven't had time to evaluate it.

As far as I understand the problem of pole placement for MIMO systems is that it strongly depends on the "special needs" (e.g. robustness, repeated poles, minimum gain, etc.) of the closed-loop.

I have found some articles covering these topics:

However, I have no implementation of one of them yet.

Probably it would make sense to have a common interface for a catalogue of possible methods covering certain flavors like robust or minimum gain pole placement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants