@@ -108,15 +108,15 @@ class FlatSystem(NonlinearIOSystem):
108
108
-----
109
109
The class must implement two functions:
110
110
111
- zflag = flatsys.foward(x, u)
111
+ zflag = flatsys.foward(x, u, params )
112
112
This function computes the flag (derivatives) of the flat output.
113
113
The inputs to this function are the state 'x' and inputs 'u' (both
114
114
1D arrays). The output should be a 2D array with the first
115
115
dimension equal to the number of system inputs and the second
116
116
dimension of the length required to represent the full system
117
117
dynamics (typically the number of states)
118
118
119
- x, u = flatsys.reverse(zflag)
119
+ x, u = flatsys.reverse(zflag, params )
120
120
This function system state and inputs give the the flag (derivatives)
121
121
of the flat output. The input to this function is an 2D array whose
122
122
first dimension is equal to the number of system inputs and whose
@@ -216,7 +216,7 @@ def _flat_updfcn(self, t, x, u, params={}):
216
216
def _flat_outfcn (self , t , x , u , params = {}):
217
217
# Return the flat output
218
218
zflag = self .forward (x , u , params )
219
- return np .array (zflag [: ][0 ])
219
+ return np .array ([ zflag [i ][0 ] for i in range ( len ( zflag )) ])
220
220
221
221
222
222
# Utility function to compute flag matrix given a basis
@@ -244,8 +244,8 @@ def _basis_flag_matrix(sys, basis, flag, t, params={}):
244
244
245
245
# Solve a point to point trajectory generation problem for a flat system
246
246
def point_to_point (
247
- sys , timepts , x0 = 0 , u0 = 0 , xf = 0 , uf = 0 , T0 = 0 , basis = None , cost = None ,
248
- constraints = None , initial_guess = None , minimize_kwargs = {} , ** kwargs ):
247
+ sys , timepts , x0 = 0 , u0 = 0 , xf = 0 , uf = 0 , T0 = 0 , cost = None , basis = None ,
248
+ trajectory_constraints = None , initial_guess = None , params = None , ** kwargs ):
249
249
"""Compute trajectory between an initial and final conditions.
250
250
251
251
Compute a feasible trajectory for a differentially flat system between an
@@ -284,7 +284,7 @@ def point_to_point(
284
284
Function that returns the integral cost given the current state
285
285
and input. Called as `cost(x, u)`.
286
286
287
- constraints : list of tuples, optional
287
+ trajectory_constraints : list of tuples, optional
288
288
List of constraints that should hold at each point in the time vector.
289
289
Each element of the list should consist of a tuple with first element
290
290
given by :class:`scipy.optimize.LinearConstraint` or
@@ -337,8 +337,15 @@ def point_to_point(
337
337
T0 = timepts [0 ] if len (timepts ) > 1 else T0
338
338
339
339
# Process keyword arguments
340
+ if trajectory_constraints is None :
341
+ # Backwards compatibility
342
+ trajectory_constraints = kwargs .pop ('constraints' , None )
343
+
344
+ minimize_kwargs = {}
340
345
minimize_kwargs ['method' ] = kwargs .pop ('minimize_method' , None )
341
346
minimize_kwargs ['options' ] = kwargs .pop ('minimize_options' , {})
347
+ minimize_kwargs .update (kwargs .pop ('minimize_kwargs' , {}))
348
+
342
349
if kwargs :
343
350
raise TypeError ("unrecognized keywords: " , str (kwargs ))
344
351
@@ -353,11 +360,14 @@ def point_to_point(
353
360
# Make sure we have enough basis functions to solve the problem
354
361
if basis .N * sys .ninputs < 2 * (sys .nstates + sys .ninputs ):
355
362
raise ValueError ("basis set is too small" )
356
- elif (cost is not None or constraints is not None ) and \
363
+ elif (cost is not None or trajectory_constraints is not None ) and \
357
364
basis .N * sys .ninputs == 2 * (sys .nstates + sys .ninputs ):
358
365
warnings .warn ("minimal basis specified; optimization not possible" )
359
366
cost = None
360
- constraints = None
367
+ trajectory_constraints = None
368
+
369
+ # Figure out the parameters to use, if any
370
+ params = sys .params if params is None else params
361
371
362
372
#
363
373
# Map the initial and final conditions to flat output conditions
@@ -366,8 +376,8 @@ def point_to_point(
366
376
# and then evaluate this at the initial and final condition.
367
377
#
368
378
369
- zflag_T0 = sys .forward (x0 , u0 )
370
- zflag_Tf = sys .forward (xf , uf )
379
+ zflag_T0 = sys .forward (x0 , u0 , params )
380
+ zflag_Tf = sys .forward (xf , uf , params )
371
381
372
382
#
373
383
# Compute the matrix constraints for initial and final conditions
@@ -400,7 +410,7 @@ def point_to_point(
400
410
# Start by solving the least squares problem
401
411
alpha , residuals , rank , s = np .linalg .lstsq (M , Z , rcond = None )
402
412
403
- if cost is not None or constraints is not None :
413
+ if cost is not None or trajectory_constraints is not None :
404
414
# Search over the null space to minimize cost/satisfy constraints
405
415
N = sp .linalg .null_space (M )
406
416
@@ -418,7 +428,7 @@ def traj_cost(null_coeffs):
418
428
zflag = (M_t @ coeffs ).reshape (sys .ninputs , - 1 )
419
429
420
430
# Find states and inputs at the time points
421
- x , u = sys .reverse (zflag )
431
+ x , u = sys .reverse (zflag , params )
422
432
423
433
# Evaluate the cost at this time point
424
434
costval += cost (x , u )
@@ -429,13 +439,13 @@ def traj_cost(null_coeffs):
429
439
traj_cost = lambda coeffs : coeffs @ coeffs
430
440
431
441
# Process the constraints we were given
432
- traj_constraints = constraints
433
- if constraints is None :
442
+ traj_constraints = trajectory_constraints
443
+ if traj_constraints is None :
434
444
traj_constraints = []
435
- elif isinstance (constraints , tuple ):
445
+ elif isinstance (traj_constraints , tuple ):
436
446
# TODO: Check to make sure this is really a constraint
437
- traj_constraints = [constraints ]
438
- elif not isinstance (constraints , list ):
447
+ traj_constraints = [traj_constraints ]
448
+ elif not isinstance (traj_constraints , list ):
439
449
raise TypeError ("trajectory constraints must be a list" )
440
450
441
451
# Process constraints
@@ -456,7 +466,7 @@ def traj_const(null_coeffs):
456
466
zflag = (M_t @ coeffs ).reshape (sys .ninputs , - 1 )
457
467
458
468
# Find states and inputs at the time points
459
- states , inputs = sys .reverse (zflag )
469
+ states , inputs = sys .reverse (zflag , params )
460
470
461
471
# Evaluate the constraint function along the trajectory
462
472
for type , fun , lb , ub in traj_constraints :
@@ -507,8 +517,8 @@ def traj_const(null_coeffs):
507
517
# Transform the trajectory from flat outputs to states and inputs
508
518
#
509
519
510
- # Createa trajectory object to store the resul
511
- systraj = SystemTrajectory (sys , basis )
520
+ # Create a trajectory object to store the result
521
+ systraj = SystemTrajectory (sys , basis , params = params )
512
522
513
523
# Store the flag lengths and coefficients
514
524
# TODO: make this more pythonic
0 commit comments