def set(self, names, values, update_dependent=True): """ Set the values of independent parameters and recompute dependents. Parameters:: names -- The names of the parameters to set. Type: string or list of strings values -- The new parameter values. Type: float or list of floats update_dependent -- Whether to update dependent parameter values afterwards. Default: True Type: bool Raises:: XMLException if name not present in model or if variable is not an independent parameter. Example:: CasadiModel.set('damper.d', 1.1) CasadiModel.set(['damper.d', 'gear.a'], [1.1, 10]) Limitations:: New parameter values only affect equations. Attributes like min and nominal that depend on parameters are not updated. These instead use the parameter values set at compile time. Alias variables may be reported as not being found. """ if isinstance(names, basestring): self._set(names, values) else: for (name, value) in zip(names, values): self._set(name, value) if update_dependent: casadi.updateDependent(self.ocp)
ocp = casadi.SymbolicOCP() #ocp.parseFMI('modelDescription.xml') ocp.parseFMI('modelDescription.xml', { 'sort_equations': False, 'eliminate_dependent': False }) ocp.sortType(True) # temporary solution: enables the new sorting print ocp x = ocp.variable('x') x_start = ocp.variable('x_start') u = ocp.variable('u') u_cost = ocp.variable('u_cost') print(x_start.getStart()), " == 1.0" casadi.updateDependent(ocp) print(u_cost.getStart()), " == 2.0?" print(u.getMax()), " == 0.2" x_start.setStart(2) print(x_start.getStart()), " == 2.0" print(x.getStart()), " == 2.0" print(u.getMax()), " == 0.4" print(u_cost.getStart()), " == 4.0" u_cost.setStart(3) # Error since u_cost is a dependent parameter? x.setStart( 4 ) # Not sure what we want here! What should happen if x_start changes value afterwards? # JModelica #from pyjmi import CasadiModel #from pymodelica import compile_fmux
# # import casadi ocp = casadi.SymbolicOCP() #ocp.parse_fmi('modelDescription.xml') ocp.parse_fmi('modelDescription.xml',{'sort_equations':False,'eliminate_dependent':False}) ocp.sortType(True) # temporary solution: enables the new sorting print ocp x = ocp.variable('x') x_start = ocp.variable('x_start') u = ocp.variable('u') u_cost = ocp.variable('u_cost') print(x_start.getStart()), " == 1.0" casadi.updateDependent(ocp) print(u_cost.getStart()), " == 2.0?" print(u.getMax()), " == 0.2" x_start.setStart(2) print(x_start.getStart()), " == 2.0" print(x.getStart()), " == 2.0" print(u.getMax()), " == 0.4" print(u_cost.getStart()), " == 4.0" u_cost.setStart(3) # Error since u_cost is a dependent parameter? x.setStart(4) # Not sure what we want here! What should happen if x_start changes value afterwards? # JModelica #from pyjmi import CasadiModel #from pymodelica import compile_fmux #jn = compile_fmux("Parameters", "parameters.mop") #model = CasadiModel(jn)
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()