def update_expressions(self): """ Update OCP expressions using current parameter values. """ ocp_expressions = [ self.ocp.initial, self.ocp.ode, self.ocp.alg, self.ocp.path, self.ocp.point, self.ocp.mterm, self.ocp.lterm ] parameters = casadi.vertcat([p.var() for p in self._parameters]) parameter_values = [p.getStart() for p in self._parameters] [ self.initial, self.ode, self.alg, self.path, self.point, self.mterm, self.lterm ] = casadi.substitute(ocp_expressions, [parameters], [parameter_values]) # Transform ODE RHS into residual if self._casadi_blt: self.ode = N.array(casadi.der(self.ocp.x)) - self.ode
def update_expressions(self): """ Update OCP expressions using current parameter values. """ ocp_expressions = [self.ocp.initial, self.ocp.ode, self.ocp.alg, self.ocp.path, self.ocp.point, self.ocp.mterm, self.ocp.lterm] parameters = casadi.vertcat([p.var() for p in self._parameters]) parameter_values = [p.getStart() for p in self._parameters] [self.initial, self.ode, self.alg, self.path, self.point, self.mterm, self.lterm] = casadi.substitute(ocp_expressions, [parameters], [parameter_values]) # Transform ODE RHS into residual if self._casadi_blt: self.ode = N.array(casadi.der(self.ocp.x)) - self.ode
def _load_xml_to_casadi(self, xml, verbose): # Create a symbolic OCP self.ocp = casadi.SymbolicOCP() options = {} options["verbose"] = verbose options["sort_equations"] = False options["eliminate_dependent"] = False self.ocp.parseFMI(xml, options) if self._casadi_blt: self.ocp.makeExplicit() self.ocp.eliminateAlgebraic() if len(self.ocp.z) > 0 or self.ocp.ode.empty(): raise RuntimeError("Unable to reformulate as ODE.") casadi.updateDependent(self.ocp) # Store list of non-free parameters self._parameters = ([pi for pi in self.ocp.pi] + [pd for pd in self.ocp.pd]) # Check the absence of multiple Mayer and Lagrange terms if self.ocp.lterm.numel() > 1: raise NotImplementedError("Multiple Lagrange terms are not " + "supported.") if self.ocp.mterm.numel() > 1: raise NotImplementedError("Multiple Mayer terms are not " + "supported.") # Identify variables variables = {} variables['x'] = self.ocp.x variables['u'] = self.ocp.u variables['w'] = self.ocp.z variables['p_opt'] = self.ocp.pf names = {} for vt in variables: names[vt] = [(var.getValueReference(), var.getName()) for var in variables[vt]] # Make sure the variables appear in value reference order var_vectors = {} for var_type in names: var_dict = dict((repr(v), v) for v in variables[var_type]) name_dict = dict((x[0], x[1]) for x in names[var_type]) if var_type == 'p_opt': free_times = 0 if self.xmldoc.get_opt_finaltime_free(): free_times += 1 if self.xmldoc.get_opt_starttime_free(): free_times += 1 var_vectors[var_type] = casadi.VariableVector(len(var_dict) - free_times) else: var_vectors[var_type] = casadi.VariableVector(len(var_dict)) i = 0 for vr in sorted(name_dict): if (self.xmldoc.get_opt_finaltime_free() or self.xmldoc.get_opt_starttime_free()): if (name_dict[vr] == "finalTime" or name_dict[vr] == "startTime"): continue var_vectors[var_type][i] = var_dict[name_dict[vr]] i = i + 1 self._var_vectors = var_vectors # Create symbolic variables self.dx = casadi.vertcat(casadi.der(var_vectors['x'])) self.x = casadi.vertcat(casadi.var(var_vectors['x'])) self.u = casadi.vertcat(casadi.var(var_vectors['u'])) self.w = casadi.vertcat(casadi.var(var_vectors['w'])) self.t = self.ocp.t self.p = casadi.vertcat(casadi.var(var_vectors['p_opt'])) sym_vars = {'dx': self.dx, 'x': self.x, 'u': self.u, 'w': self.w, 'p_opt': self.p} # Create maps from value reference to CasADi variable index and type vr_map = {} get_vr = self.xmldoc.get_value_reference for vt in sym_vars.keys(): i = 0 for v in sym_vars[vt]: var_name = str(v) if vt == "dx": var_name = convert_casadi_der_name(var_name) vr_map[get_vr(var_name)] = (i, vt) i = i + 1 self.vr_map = vr_map # Read integer parameter values separately (circumvent SymbolicOCP bug) integer_vars = self.xmldoc.get_all_integer_variables() if len(integer_vars) > 0: [int_vr, int_names] = \ zip(*[(var.get_value_reference(), var.get_name()) for var in integer_vars]) for (vr, start) in self.xmldoc.get_variable_start_attributes(): try: index = int_vr.index(vr) except ValueError: pass else: var = self.ocp.variable(int_names[index]) # Assume that independent parameters have start values if start is not None: var.setStart(start) casadi.updateDependent(self.ocp) # Handle dependent parameters # Count variables self.n_x = self.x.numel() self.n_u = self.u.numel() self.n_w = self.w.numel() self.n_p = self.p.numel() # Create scaling factors sf = {} sf['dx'] = N.ones(self.n_x) sf['x'] = N.ones(self.n_x) sf['u'] = N.ones(self.n_u) sf['w'] = N.ones(self.n_w) sf['p_opt'] = N.ones(self.n_p) self.sf = sf self._update_sf()