Skip to content

Commit 120e333

Browse files
committed
address first round of TODO items + add stochastic system examples
1 parent f0aa458 commit 120e333

File tree

9 files changed

+100
-53
lines changed

9 files changed

+100
-53
lines changed

control/lti.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -558,19 +558,12 @@ def frequency_response(
558558
>>> G = ct.ss([[-1, -2], [3, -4]], [[5], [7]], [[6, 8]], [[9]])
559559
>>> mag, phase, omega = ct.frequency_response(G, [0.1, 1., 10.])
560560
561-
.. todo::
562-
Add example with MIMO system
563-
564-
#>>> sys = rss(3, 2, 2)
565-
#>>> mag, phase, omega = freqresp(sys, [0.1, 1., 10.])
566-
#>>> mag[0, 1, :]
567-
#array([ 55.43747231, 42.47766549, 1.97225895])
568-
#>>> phase[1, 0, :]
569-
#array([-0.12611087, -1.14294316, 2.5764547 ])
570-
#>>> # This is the magnitude of the frequency response from the 2nd
571-
#>>> # input to the 1st output, and the phase (in radians) of the
572-
#>>> # frequency response from the 1st input to the 2nd output, for
573-
#>>> # s = 0.1i, i, 10i.
561+
>>> sys = ct.rss(3, 2, 2)
562+
>>> mag, phase, omega = ct.frequency_response(sys, [0.1, 1., 10.])
563+
>>> mag[0, 1, :] # Magnitude of second input to first output
564+
array([..., ..., ...])
565+
>>> phase[1, 0, :] # Phase of first input to second output
566+
array([..., ..., ...])
574567
575568
"""
576569
from .frdata import FrequencyResponseData

control/matlab/wrappers.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,6 @@ def bode(*args, **kwargs):
5454
5555
>>> sys = ss([[1, -2], [3, -4]], [[5], [7]], [[6, 8]], 9)
5656
>>> mag, phase, omega = bode(sys)
57-
58-
.. todo::
59-
60-
Document these use cases
61-
62-
* >>> bode(sys, w) # doctest: +SKIP
63-
* >>> bode(sys1, sys2, ..., sysN) # doctest: +SKIP
64-
* >>> bode(sys1, sys2, ..., sysN, w) # doctest: +SKIP
65-
* >>> bode(sys1, 'plotstyle1', ..., sysN, 'plotstyleN') # doctest: +SKIP
66-
6757
>>> bode(sys, w) # one system, freq vector # doctest: +SKIP
6858
>>> bode(sys1, sys2, ..., sysN) # several systems # doctest: +SKIP
6959
>>> bode(sys1, sys2, ..., sysN, w) # doctest: +SKIP

doc/examples.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ online sources.
5656
examples/cruise
5757
examples/describing_functions
5858
examples/interconnect_tutorial
59-
examples/kincar-fusion
60-
examples/mhe-pvtol
6159
examples/mpc_aircraft
6260
examples/pvtol-lqr-nested
6361
examples/pvtol-outputfbk

doc/examples/kalman-pvtol.ipynb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../examples/cds112-L7_kalman-pvtol.ipynb

doc/stochastic.rst

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -187,33 +187,49 @@ time optimal controller. For the second two forms, the :func:`dlqr`
187187
function can be used. Additional arguments and details are given on
188188
the :func:`lqr` and :func:`dlqr` documentation pages.
189189

190-
.. todo::
191-
Convert the following code to testcode
190+
.. testsetup:: kalman
191+
192+
sys = ct.rss(2, 2, 2)
193+
Qu = np.eye(2)
194+
Qv = np.eye(2)
195+
Qw = np.eye(2)
196+
Qx = np.eye(2)
197+
198+
timepts = np.linspace(0, 10)
199+
U = ct.white_noise(timepts, Qv)
200+
Y = ct.white_noise(timepts, Qw)
201+
202+
X0 = np.zeros(2)
203+
P0 = np.eye(2)
192204

193205
The :func:`create_estimator_iosystem` function can be used to create
194206
an I/O system implementing a Kalman filter, including integration of
195207
the Riccati ODE. The command has the form
196208

197-
.. code::
209+
.. testcode:: kalman
198210

199211
estim = ct.create_estimator_iosystem(sys, Qv, Qw)
200212

201213
The input to the estimator is the measured outputs `Y` and the system
202214
input `U`. To run the estimator on a noisy signal, use the command
203215

204-
.. code::
216+
.. testcode:: kalman
205217

206-
resp = ct.input_output_response(est, timepts, [Y, U], [X0, P0])
218+
resp = ct.input_output_response(estim, timepts, [Y, U], [X0, P0])
207219

208220
If desired, the :func:`correct` parameter can be set to False
209-
to allow prediction with no additional sensor information::
221+
to allow prediction with no additional sensor information:
222+
223+
.. testcode:: kalman
210224

211225
resp = ct.input_output_response(
212-
estim, timepts, 0, [X0, P0], param={'correct': False})
226+
estim, timepts, 0, [X0, P0], params={'correct': False})
213227

214228
The :func:`create_estimator_iosystem` and
215229
:func:`create_statefbk_iosystem` functions can be used to combine an
216-
estimator with a state feedback controller::
230+
estimator with a state feedback controller:
231+
232+
.. testcode:: kalman
217233

218234
K, _, _ = ct.lqr(sys, Qx, Qu)
219235
estim = ct.create_estimator_iosystem(sys, Qv, Qw, P0)
@@ -229,13 +245,19 @@ estimated state :math:`\hat x` (output of `estim`):
229245
230246
The closed loop controller `clsys` includes both the state
231247
feedback and the estimator dynamics and takes as its input the desired
232-
state :math:`x_\text{d}` and input :math:`u_\text{d}`::
248+
state :math:`x_\text{d}` and input :math:`u_\text{d}`:
249+
250+
.. testcode:: kalman
251+
:hide:
252+
253+
Xd = np.zeros((2, timepts.size))
254+
Ud = np.zeros((2, timepts.size))
255+
256+
.. testcode:: kalman
233257

234258
resp = ct.input_output_response(
235259
clsys, timepts, [Xd, Ud], [X0, np.zeros_like(X0), P0])
236260

237-
.. todo::
238-
Add example (with plots?)
239261

240262

241263
Maximum Likelihood Estimation
@@ -374,5 +396,17 @@ problems:
374396
optimal.gaussian_likelihood_cost
375397
optimal.disturbance_range_constraint
376398

377-
.. todo::
378-
Add example: LQE vs MHE (from CDS 112)
399+
Examples
400+
========
401+
402+
The following examples illustrate the use of tools from the stochastic
403+
systems module. Background information for these examples can be
404+
found in the FBS2e supplement on `Optimization-Based Control
405+
<https://fbswiki.org/wiki/index.php/OBC>`_).
406+
407+
.. toctree::
408+
:maxdepth: 1
409+
410+
Kalman filter (kinematic car) <examples/kincar-fusion>
411+
(Extended) Kalman filtering (PVTOL) <examples/kalman-pvtol>
412+
Moving horizon estimation (PVTOL) <examples/mhe-pvtol>

examples/cds110-L4b_lqr-tracking.ipynb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,22 @@
907907
}
908908
],
909909
"metadata": {
910+
"kernelspec": {
911+
"display_name": "Python 3 (ipykernel)",
912+
"language": "python",
913+
"name": "python3"
914+
},
910915
"language_info": {
911-
"name": "python"
916+
"codemirror_mode": {
917+
"name": "ipython",
918+
"version": 3
919+
},
920+
"file_extension": ".py",
921+
"mimetype": "text/x-python",
922+
"name": "python",
923+
"nbconvert_exporter": "python",
924+
"pygments_lexer": "ipython3",
925+
"version": "3.13.1"
912926
}
913927
},
914928
"nbformat": 4,

examples/cds112-L7_kalman-pvtol.ipynb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,22 @@
416416
}
417417
],
418418
"metadata": {
419+
"kernelspec": {
420+
"display_name": "Python 3 (ipykernel)",
421+
"language": "python",
422+
"name": "python3"
423+
},
419424
"language_info": {
420-
"name": "python"
425+
"codemirror_mode": {
426+
"name": "ipython",
427+
"version": 3
428+
},
429+
"file_extension": ".py",
430+
"mimetype": "text/x-python",
431+
"name": "python",
432+
"nbconvert_exporter": "python",
433+
"pygments_lexer": "ipython3",
434+
"version": "3.13.1"
421435
}
422436
},
423437
"nbformat": 4,

examples/cds112-L9_mhe-pvtol.ipynb

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,6 @@
2828
"import control.flatsys as fs"
2929
]
3030
},
31-
{
32-
"cell_type": "code",
33-
"execution_count": null,
34-
"id": "1a4e4084",
35-
"metadata": {},
36-
"outputs": [],
37-
"source": [
38-
"# Import the new MHE routines (to be moved to python-control)\n",
39-
"# import ctrlutil as opt_"
40-
]
41-
},
4231
{
4332
"cell_type": "markdown",
4433
"id": "d72a155b",
@@ -749,8 +738,22 @@
749738
}
750739
],
751740
"metadata": {
741+
"kernelspec": {
742+
"display_name": "Python 3 (ipykernel)",
743+
"language": "python",
744+
"name": "python3"
745+
},
752746
"language_info": {
753-
"name": "python"
747+
"codemirror_mode": {
748+
"name": "ipython",
749+
"version": 3
750+
},
751+
"file_extension": ".py",
752+
"mimetype": "text/x-python",
753+
"name": "python",
754+
"nbconvert_exporter": "python",
755+
"pygments_lexer": "ipython3",
756+
"version": "3.13.1"
754757
}
755758
},
756759
"nbformat": 4,

examples/stochresp.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@
284284
"name": "python",
285285
"nbconvert_exporter": "python",
286286
"pygments_lexer": "ipython3",
287-
"version": "3.9.1"
287+
"version": "3.13.1"
288288
}
289289
},
290290
"nbformat": 4,

0 commit comments

Comments
 (0)