|
18 | 18 |
|
19 | 19 | from . import config |
20 | 20 | from .exception import ControlNotImplemented |
21 | | -from .timeresp import TimeResponseData |
22 | 21 |
|
23 | 22 | # Define module default parameter values |
24 | 23 | _optimal_trajectory_methods = {'shooting', 'collocation'} |
@@ -140,7 +139,8 @@ class OptimalControlProblem(): |
140 | 139 | def __init__( |
141 | 140 | self, sys, timepts, integral_cost, trajectory_constraints=[], |
142 | 141 | terminal_cost=None, terminal_constraints=[], initial_guess=None, |
143 | | - trajectory_method=None, basis=None, log=False, **kwargs): |
| 142 | + trajectory_method=None, basis=None, log=False, kwargs_check=True, |
| 143 | + **kwargs): |
144 | 144 | """Set up an optimal control problem.""" |
145 | 145 | # Save the basic information for use later |
146 | 146 | self.system = sys |
@@ -183,7 +183,7 @@ def __init__( |
183 | 183 | " discrete time systems") |
184 | 184 |
|
185 | 185 | # Make sure there were no extraneous keywords |
186 | | - if kwargs: |
| 186 | + if kwargs_check and kwargs: |
187 | 187 | raise TypeError("unrecognized keyword(s): ", str(kwargs)) |
188 | 188 |
|
189 | 189 | self.trajectory_constraints = _process_constraints( |
@@ -829,7 +829,7 @@ def compute_mpc(self, x, squeeze=None): |
829 | 829 | return res.inputs[:, 0] |
830 | 830 |
|
831 | 831 | # Create an input/output system implementing an MPC controller |
832 | | - def create_mpc_iosystem(self): |
| 832 | + def create_mpc_iosystem(self, **kwargs): |
833 | 833 | """Create an I/O system implementing an MPC controller""" |
834 | 834 | # Check to make sure we are in discrete time |
835 | 835 | if self.system.dt == 0: |
@@ -857,11 +857,17 @@ def _output(t, x, u, params={}): |
857 | 857 | res = self.compute_trajectory(u, print_summary=False) |
858 | 858 | return res.inputs[:, 0] |
859 | 859 |
|
| 860 | + # Define signal names, if they are not already given |
| 861 | + if not kwargs.get('inputs'): |
| 862 | + kwargs['inputs'] = self.system.state_labels |
| 863 | + if not kwargs.get('outputs'): |
| 864 | + kwargs['outputs'] = self.system.input_labels |
| 865 | + if not kwargs.get('states'): |
| 866 | + kwargs['states'] = self.system.ninputs * \ |
| 867 | + (self.timepts.size if self.basis is None else self.basis.N) |
| 868 | + |
860 | 869 | return ct.NonlinearIOSystem( |
861 | | - _update, _output, dt=self.system.dt, |
862 | | - inputs=self.system.nstates, outputs=self.system.ninputs, |
863 | | - states=self.system.ninputs * \ |
864 | | - (self.timepts.size if self.basis is None else self.basis.N)) |
| 870 | + _update, _output, dt=self.system.dt, **kwargs) |
865 | 871 |
|
866 | 872 |
|
867 | 873 | # Optimal control result |
@@ -923,7 +929,7 @@ def __init__( |
923 | 929 | print("* Final cost:", self.cost) |
924 | 930 |
|
925 | 931 | # Process data as a time response (with "outputs" = inputs) |
926 | | - response = TimeResponseData( |
| 932 | + response = ct.TimeResponseData( |
927 | 933 | ocp.timepts, inputs, states, issiso=ocp.system.issiso(), |
928 | 934 | transpose=transpose, return_x=return_states, squeeze=squeeze) |
929 | 935 |
|
@@ -1129,10 +1135,10 @@ def create_mpc_iosystem( |
1129 | 1135 | ocp = OptimalControlProblem( |
1130 | 1136 | sys, horizon, cost, trajectory_constraints=constraints, |
1131 | 1137 | terminal_cost=terminal_cost, terminal_constraints=terminal_constraints, |
1132 | | - log=log, **kwargs) |
| 1138 | + log=log, kwargs_check=False, **kwargs) |
1133 | 1139 |
|
1134 | 1140 | # Return an I/O system implementing the model predictive controller |
1135 | | - return ocp.create_mpc_iosystem() |
| 1141 | + return ocp.create_mpc_iosystem(**kwargs) |
1136 | 1142 |
|
1137 | 1143 |
|
1138 | 1144 | # |
|
0 commit comments