Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite0f71f4

Browse files
committed
update documentation + allow constraints in scipy.optimize form
1 parentd121102 commite0f71f4

File tree

3 files changed

+74
-45
lines changed

3 files changed

+74
-45
lines changed

‎control/optimal.py

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -50,44 +50,48 @@ class OptimalControlProblem():
5050
integral_cost : callable
5151
Function that returns the integral cost given the current state
5252
and input. Called as integral_cost(x, u).
53-
trajectory_constraints : list oftuples, optional
53+
trajectory_constraints : list ofconstraints, optional
5454
List of constraints that should hold at each point in the time
55-
vector. Each element of the list should consist of a tuple with
56-
first element given by :meth:`~scipy.optimize.LinearConstraint` or
57-
:meth:`~scipy.optimize.NonlinearConstraint` and the remaining
58-
elements of the tuple are the arguments that would be passed to
59-
those functions. The constraints will be applied at each time
60-
point along the trajectory.
55+
vector. Each element of the list should be an object of type
56+
:class:`~scipy.optimize.LinearConstraint` with arguments `(A, lb,
57+
ub)` or :class:`~scipy.optimize.NonlinearConstraint` with arguments
58+
`(fun, lb, ub)`. The constraints will be applied at each time point
59+
along the trajectory.
6160
terminal_cost : callable, optional
6261
Function that returns the terminal cost given the current state
6362
and input. Called as terminal_cost(x, u).
64-
initial_guess : 1D or 2D array_like
65-
Initial inputs to use as a guess for the optimal input. The
66-
inputs should either be a 2D vector of shape (ninputs, horizon)
67-
or a 1D input of shape (ninputs,) that will be broadcast by
68-
extension of the time axis.
6963
trajectory_method : string, optional
7064
Method to use for carrying out the optimization. Currently supported
7165
methods are 'shooting' and 'collocation' (continuous time only). The
7266
default value is 'shooting' for discrete time systems and
7367
'collocation' for continuous time systems
68+
initial_guess : (tuple of) 1D or 2D array_like
69+
Initial states and/or inputs to use as a guess for the optimal
70+
trajectory. For shooting methods, an array of inputs for each time
71+
point should be specified. For collocation methods, the initial
72+
guess is either the input vector or a tuple consisting guesses for
73+
the state and the input. Guess should either be a 2D vector of
74+
shape (ninputs, ntimepts) or a 1D input of shape (ninputs,) that
75+
will be broadcast by extension of the time axis.
7476
log : bool, optional
7577
If `True`, turn on logging messages (using Python logging module).
76-
Use ``logging.basicConfig`` to enable logging output (e.g., to a file).
77-
kwargs : dict, optional
78-
Additional parameters (passed to :func:`scipy.optimal.minimize`).
78+
Use :py:func:`logging.basicConfig` to enable logging output
79+
(e.g., to a file).
7980
8081
Returns
8182
-------
8283
ocp : OptimalControlProblem
8384
Optimal control problem object, to be used in computing optimal
8485
controllers.
8586
86-
Additional parameters
87-
---------------------
87+
Other Parameters
88+
----------------
8889
basis : BasisFamily, optional
8990
Use the given set of basis functions for the inputs instead of
9091
setting the value of the input at each point in the timepts vector.
92+
terminal_constraints : list of constraints, optional
93+
List of constraints that should hold at the terminal point in time,
94+
in the same form as `trajectory_constraints`.
9195
solve_ivp_method : str, optional
9296
Set the method used by :func:`scipy.integrate.solve_ivp`.
9397
solve_ivp_kwargs : str, optional
@@ -182,20 +186,6 @@ def __init__(
182186
ifkwargs:
183187
raiseTypeError("unrecognized keyword(s): ",str(kwargs))
184188

185-
# Process trajectory constraints
186-
def_process_constraints(constraint_list,name):
187-
ifisinstance(constraint_list,tuple):
188-
constraint_list= [constraint_list]
189-
elifnotisinstance(constraint_list,list):
190-
raiseTypeError(f"{name} constraints must be a list")
191-
192-
# Make sure that we recognize all of the constraint types
193-
forctype,fun,lb,ubinconstraint_list:
194-
ifnotctypein [opt.LinearConstraint,opt.NonlinearConstraint]:
195-
raiseTypeError(f"unknown{name} constraint type{ctype}")
196-
197-
returnconstraint_list
198-
199189
self.trajectory_constraints=_process_constraints(
200190
trajectory_constraints,"trajectory")
201191
self.terminal_constraints=_process_constraints(
@@ -1017,9 +1007,6 @@ def solve_ocp(
10171007
If True, assume that 2D input arrays are transposed from the standard
10181008
format. Used to convert MATLAB-style inputs to our format.
10191009
1020-
kwargs : dict, optional
1021-
Additional parameters (passed to :func:`scipy.optimal.minimize`).
1022-
10231010
Returns
10241011
-------
10251012
res : OptimalControlResult
@@ -1456,3 +1443,45 @@ def _evaluate_output_range_constraint(x, u):
14561443

14571444
# Return a nonlinear constraint object based on the polynomial
14581445
return (opt.NonlinearConstraint,_evaluate_output_range_constraint,lb,ub)
1446+
1447+
#
1448+
# Utility functions
1449+
#
1450+
1451+
#
1452+
# Process trajectory constraints
1453+
#
1454+
# Constraints were originally specified as a tuple with the type of
1455+
# constraint followed by the arguments. However, they are now specified
1456+
# directly as SciPy constraint objects.
1457+
#
1458+
# The _process_constraints() function will covert everything to a consistent
1459+
# internal representation (currently a tuple with the constraint type as the
1460+
# first element.
1461+
#
1462+
def_process_constraints(clist,name):
1463+
ifisinstance(
1464+
clist, (tuple,opt.LinearConstraint,opt.NonlinearConstraint)):
1465+
clist= [clist]
1466+
elifnotisinstance(clist,list):
1467+
raiseTypeError(f"{name} constraints must be a list")
1468+
1469+
# Process individual list elements
1470+
constraint_list= []
1471+
forconstraintinclist:
1472+
ifisinstance(constraint,tuple):
1473+
# Original style of constraint
1474+
ctype,fun,lb,ub=constraint
1475+
ifnotctypein [opt.LinearConstraint,opt.NonlinearConstraint]:
1476+
raiseTypeError(f"unknown{name} constraint type{ctype}")
1477+
constraint_list.append(constraint)
1478+
elifisinstance(constraint,opt.LinearConstraint):
1479+
constraint_list.append(
1480+
(opt.LinearConstraint,constraint.A,
1481+
constraint.lb,constraint.ub))
1482+
elifisinstance(constraint,opt.NonlinearConstraint):
1483+
constraint_list.append(
1484+
(opt.NonlinearConstraint,constraint.fun,
1485+
constraint.lb,constraint.ub))
1486+
1487+
returnconstraint_list

‎control/tests/optimal_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def test_finite_horizon_simple(method):
6464

6565
# State and input constraints
6666
constraints= [
67-
(sp.optimize.LinearConstraint,np.eye(3), [-5,-5,-1], [5,5,1]),
67+
sp.optimize.LinearConstraint(np.eye(3), [-5,-5,-1], [5,5,1]),
6868
]
6969

7070
# Quadratic state and input penalty
@@ -148,7 +148,7 @@ def test_discrete_lqr():
148148

149149
# Add state and input constraints
150150
trajectory_constraints= [
151-
(sp.optimize.LinearConstraint,np.eye(3), [-5,-5,-.5], [5,5,0.5]),
151+
sp.optimize.LinearConstraint(np.eye(3), [-5,-5,-.5], [5,5,0.5]),
152152
]
153153

154154
# Re-solve
@@ -461,7 +461,7 @@ def test_ocp_argument_errors():
461461

462462
# State and input constraints
463463
constraints= [
464-
(sp.optimize.LinearConstraint,np.eye(3), [-5,-5,-1], [5,5,1]),
464+
sp.optimize.LinearConstraint(np.eye(3), [-5,-5,-1], [5,5,1]),
465465
]
466466

467467
# Quadratic state and input penalty
@@ -522,7 +522,7 @@ def test_optimal_basis_simple(basis):
522522

523523
# State and input constraints
524524
constraints= [
525-
(sp.optimize.LinearConstraint,np.eye(3), [-5,-5,-1], [5,5,1]),
525+
sp.optimize.LinearConstraint(np.eye(3), [-5,-5,-1], [5,5,1]),
526526
]
527527

528528
# Quadratic state and input penalty
@@ -594,7 +594,7 @@ def test_equality_constraints():
594594
deffinal_point_eval(x,u):
595595
returnx
596596
final_point= [
597-
(sp.optimize.NonlinearConstraint,final_point_eval, [0,0], [0,0])]
597+
sp.optimize.NonlinearConstraint(final_point_eval, [0,0], [0,0])]
598598

599599
optctrl=opt.OptimalControlProblem(
600600
sys,time,cost,terminal_constraints=final_point)

‎doc/optimal.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,16 @@ parameter can be used to specify a cost function for the final point in the
125125
trajectory.
126126

127127
The `constraints` parameter is a list of constraints similar to that used by
128-
the:func:`scipy.optimize.minimize` function. Each constraint isa tuple of
129-
one of the following forms::
128+
the:func:`scipy.optimize.minimize` function. Each constraint isspecified
129+
usingone of the following forms::
130130

131-
(LinearConstraint,A, lb, ub)
132-
(NonlinearConstraint,f, lb, ub)
131+
LinearConstraint(A, lb, ub)
132+
NonlinearConstraint(f, lb, ub)
133133

134134
For a linear constraint, the 2D array `A` is multiplied by a vector
135135
consisting of the current state `x` and current input `u` stacked
136-
vertically, then compared with the upper and lower bound. Thisconstrain is
137-
satisfied if
136+
vertically, then compared with the upper and lower bound. Thisconstraint
137+
issatisfied if
138138

139139
..code::python
140140

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp