Skip to content

Commit c03b771

Browse files
bnavigatormurrayrm
authored andcommitted
rename 'type' keyword
1 parent 99ec022 commit c03b771

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

control/statefbk.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
# External packages and modules
4343
import numpy as np
4444
import scipy as sp
45+
import warnings
4546

4647
from . import statesp
4748
from .mateqn import care, dare, _check_shape
@@ -597,10 +598,10 @@ def dlqr(*args, **kwargs):
597598

598599
# Function to create an I/O sytems representing a state feedback controller
599600
def create_statefbk_iosystem(
600-
sys, gain, integral_action=None, estimator=None, type=None,
601+
sys, gain, integral_action=None, estimator=None, controller_type=None,
601602
xd_labels='xd[{i}]', ud_labels='ud[{i}]', gainsched_indices=None,
602603
gainsched_method='linear', name=None, inputs=None, outputs=None,
603-
states=None):
604+
states=None, **kwargs):
604605
"""Create an I/O system using a (full) state feedback controller
605606
606607
This function creates an input/output system that implements a
@@ -684,7 +685,7 @@ def create_statefbk_iosystem(
684685
hull of the scheduling points, the gain at the nearest point is
685686
used.
686687
687-
type : 'linear' or 'nonlinear', optional
688+
controller_type : 'linear' or 'nonlinear', optional
688689
Set the type of controller to create. The default for a linear gain
689690
is a linear controller implementing the LQR regulator. If the type
690691
is 'nonlinear', a :class:NonlinearIOSystem is created instead, with
@@ -728,6 +729,18 @@ def create_statefbk_iosystem(
728729
if not isinstance(sys, InputOutputSystem):
729730
raise ControlArgument("Input system must be I/O system")
730731

732+
# Process (legacy) keywords
733+
if kwargs.get('type') is not None:
734+
warnings.warn(
735+
"keyword 'type' is deprecated; use 'controller_type'",
736+
DeprecationWarning)
737+
if controller_type is not None:
738+
raise ControlArgument(
739+
"duplicate keywords 'type` and 'controller_type'")
740+
controller_type = kwargs.pop('type')
741+
if kwargs:
742+
raise TypeError("unrecognized keywords: ", str(kwargs))
743+
731744
# See whether we were give an estimator
732745
if estimator is not None:
733746
# Check to make sure the estimator is the right size
@@ -781,13 +794,14 @@ def create_statefbk_iosystem(
781794
raise ControlArgument("gain must be an array or a tuple")
782795

783796
# Decide on the type of system to create
784-
if gainsched and type == 'linear':
797+
if gainsched and controller_type == 'linear':
785798
raise ControlArgument(
786-
"type 'linear' not allowed for gain scheduled controller")
787-
elif type is None:
788-
type = 'nonlinear' if gainsched else 'linear'
789-
elif type not in {'linear', 'nonlinear'}:
790-
raise ControlArgument(f"unknown type '{type}'")
799+
"controller_type 'linear' not allowed for"
800+
" gain scheduled controller")
801+
elif controller_type is None:
802+
controller_type = 'nonlinear' if gainsched else 'linear'
803+
elif controller_type not in {'linear', 'nonlinear'}:
804+
raise ControlArgument(f"unknown controller_type '{controller_type}'")
791805

792806
# Figure out the labels to use
793807
if isinstance(xd_labels, str):
@@ -845,7 +859,7 @@ def _compute_gain(mu):
845859
return K
846860

847861
# Define the controller system
848-
if type == 'nonlinear':
862+
if controller_type == 'nonlinear':
849863
# Create an I/O system for the state feedback gains
850864
def _control_update(t, states, inputs, params):
851865
# Split input into desired state, nominal input, and current state
@@ -879,7 +893,7 @@ def _control_output(t, states, inputs, params):
879893
_control_update, _control_output, name=name, inputs=inputs,
880894
outputs=outputs, states=states, params=params)
881895

882-
elif type == 'linear' or type is None:
896+
elif controller_type == 'linear' or controller_type is None:
883897
# Create the matrices implementing the controller
884898
if isctime(sys):
885899
# Continuous time: integrator
@@ -898,7 +912,7 @@ def _control_output(t, states, inputs, params):
898912
inputs=inputs, outputs=outputs, states=states)
899913

900914
else:
901-
raise ControlArgument(f"unknown type '{type}'")
915+
raise ControlArgument(f"unknown controller_type '{controller_type}'")
902916

903917
# Define the closed loop system
904918
closed = interconnect(

control/tests/statefbk_test.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
import pytest
88
import itertools
9+
import warnings
910
from math import pi, atan
1011

1112
import control as ct
@@ -569,7 +570,12 @@ def test_statefbk_iosys(
569570

570571
# Create an I/O system for the controller
571572
ctrl, clsys = ct.create_statefbk_iosystem(
572-
sys, K, integral_action=C_int, estimator=est, type=type)
573+
sys, K, integral_action=C_int, estimator=est,
574+
controller_type=type, name=type)
575+
576+
# Make sure the name got set correctly
577+
if type is not None:
578+
assert ctrl.name == type
573579

574580
# If we used a nonlinear controller, linearize it for testing
575581
if type == 'nonlinear':
@@ -763,8 +769,20 @@ def test_statefbk_errors(self):
763769
with pytest.raises(ControlArgument, match="gain must be an array"):
764770
ctrl, clsys = ct.create_statefbk_iosystem(sys, "bad argument")
765771

766-
with pytest.raises(ControlArgument, match="unknown type"):
767-
ctrl, clsys = ct.create_statefbk_iosystem(sys, K, type=1)
772+
with pytest.warns(DeprecationWarning, match="'type' is deprecated"):
773+
ctrl, clsys = ct.create_statefbk_iosystem(sys, K, type='nonlinear')
774+
775+
with pytest.raises(ControlArgument, match="duplicate keywords"):
776+
with warnings.catch_warnings():
777+
warnings.simplefilter("ignore")
778+
ctrl, clsys = ct.create_statefbk_iosystem(
779+
sys, K, type='nonlinear', controller_type='nonlinear')
780+
781+
with pytest.raises(TypeError, match="unrecognized keywords"):
782+
ctrl, clsys = ct.create_statefbk_iosystem(sys, K, typo='nonlinear')
783+
784+
with pytest.raises(ControlArgument, match="unknown controller_type"):
785+
ctrl, clsys = ct.create_statefbk_iosystem(sys, K, controller_type=1)
768786

769787
# Errors involving integral action
770788
C_int = np.eye(2, 4)

0 commit comments

Comments
 (0)