# modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 3 of the License, or (at your option) any later version. # # CasADi is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with CasADi; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # # import casadi 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)
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()