Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# do not edit, generated by pymoca
from __future__ import print_function, division
import sympy
import sympy.physics.mechanics as mech
from pymoca.backends.sympy.runtime import OdeModel
from sympy import sin, cos, tan
class Quad(OdeModel):
def __init__(self):
super(Quad, self).__init__()
# states
phi, theta, psi_, P, Q, R, x, y, z, U, V, W = mech.dynamicsymbols('phi, theta, psi_, P, Q, R, x, y, z, U, V, W')
self.x = sympy.Matrix([phi, theta, psi_, P, Q, R, x, y, z, U, V, W])
self.x0 = {
phi : 0,
theta : 0,
psi_ : 0,
P : 0,
Q : 0,
R : 0,
x : 0,
# do not edit, generated by pymoca
from __future__ import print_function, division
import sympy
import sympy.physics.mechanics as mech
from pymoca.backends.sympy.runtime import OdeModel
from sympy import sin, cos, tan
class Aircraft(OdeModel):
def __init__(self):
super(Aircraft, self).__init__()
# states
body__x, body__v_x = mech.dynamicsymbols('body.x, body.v_x')
self.x = sympy.Matrix([body__x, body__v_x])
self.x0 = {
body__x : 0,
body__v_x : 0,
}
# variables
body__f_x, body__a_x, accel__a_x, accel__ma_x, accel__b_x__u, accel__b_x__y = mech.dynamicsymbols('body.f_x, body.a_x, accel.a_x, accel.ma_x, accel.b_x.u, accel.b_x.y')
self.v = sympy.Matrix([body__f_x, body__a_x, accel__a_x, accel__ma_x, accel__b_x__u, accel__b_x__y])
# do not edit, generated by pymoca
from __future__ import print_function, division
import sympy
import sympy.physics.mechanics as mech
from pymoca.backends.sympy.runtime import OdeModel
from sympy import sin, cos, tan
class SpringSystem(OdeModel):
def __init__(self):
super(SpringSystem, self).__init__()
# states
x, v_x = mech.dynamicsymbols('x, v_x')
self.x = sympy.Matrix([x, v_x])
self.x0 = {
x : 1.0,
v_x : 1.0,
}
# variables
spring__x, spring__f, damper__v, damper__f = mech.dynamicsymbols('spring.x, spring.f, damper.v, damper.f')
self.v = sympy.Matrix([spring__x, spring__f, damper__v, damper__f])
# do not edit, generated by pymoca
from __future__ import print_function, division
import sympy
import sympy.physics.mechanics as mech
from pymoca.backends.sympy.runtime import OdeModel
from sympy import sin, cos, tan
class Estimator(OdeModel):
def __init__(self):
super(Estimator, self).__init__()
# states
x = mech.dynamicsymbols('x')
self.x = sympy.Matrix([x])
self.x0 = {
x : 0,
}
# variables
y = mech.dynamicsymbols('y')
self.v = sympy.Matrix([y])
def get_derivative(self, s):
# Case 1: s is a constant, e.g. MX(5)
if ca.MX(s).is_constant():
return 0
# Case 2: s is a symbol, e.g. MX(x)
elif s.is_symbolic():
if s.name() not in self.derivative:
if len(self.for_loops) > 0 and s in self.for_loops[-1].indexed_symbols:
# Create a new indexed symbol, referencing to the for loop index inside the vector derivative symbol.
for_loop_symbol = self.for_loops[-1].indexed_symbols[s]
s_without_index = self.get_mx(ast.ComponentRef(name=for_loop_symbol.tree.name))
der_s_without_index = self.get_derivative(s_without_index)
if ca.MX(der_s_without_index).is_symbolic():
return self.get_indexed_symbol(ast.ComponentRef(name=der_s_without_index.name(), indices=for_loop_symbol.tree.indices), der_s_without_index)
else:
return 0
else:
der_s = _new_mx("der({})".format(s.name()), s.size())
# If the derivative contains an expression (e.g. der(x + y)) this method is
# called with MX variables that are the result of a ca.symvar call. This
# ca.symvar call strips the _modelica_shape field from the MX variable,
# therefore we need to find the original MX to get the modelica shape.
der_s._modelica_shape = \
self.nodes[self.current_class][s.name()]._modelica_shape
self.derivative[s.name()] = der_s
self.nodes[self.current_class][der_s.name()] = der_s
return der_s
else:
return self.derivative[s.name()]
def exitExpression(self, tree: ast.Expression):
if isinstance(tree.operator, ast.ComponentRef):
op_name = tree.operator.name
else:
op_name = tree.operator
if len(tree.operands) == 1:
self.xml[tree] = E(
'operator', name=op_name,
*[self.xml[c] for c in tree.operands])
else:
self.xml[tree] = E(
'apply', builtin=op_name,
*[self.xml[c] for c in tree.operands])
if options.flatten_only:
# Load folder
_ast = None
for root, dir, files in os.walk(model_folder, followlinks=True):
for item in fnmatch.filter(files, "*.mo"):
logger.info("Parsing {}".format(item))
with open(os.path.join(root, item), 'r') as f:
if _ast is None:
_ast = parser.parse(f.read())
else:
_ast.extend(parser.parse(f.read()))
logger.info("Flattening")
_ast = tree.flatten(_ast, ast.ComponentRef.from_string(model_name))
print(_ast)
else:
# Set CasADi installation folder
if options.casadi_folder is not None:
sys.path.append(options.casadi_folder)
from pymoca.backends.casadi.api import transfer_model
import casadi as ca
logger.info("Generating CasADi model")
compiler_options = \
{'replace_constants': True,
'replace_parameter_expressions': True,
'eliminable_variable_expression': r'_\w+',
'detect_aliases': True,
def generate(ast_tree: ast.Tree, model_name: str):
"""
:param ast_tree: AST to generate from
:param model_name: class to generate
:return: sympy source code for model
"""
component_ref = ast.ComponentRef.from_string(model_name)
ast_tree_new = copy.deepcopy(ast_tree)
ast_walker = TreeWalker()
flat_tree = flatten(ast_tree_new, component_ref)
sympy_gen = SympyGenerator()
ast_walker.walk(sympy_gen, flat_tree)
return sympy_gen.src[flat_tree]
def get_derivative(self, s):
# Case 1: s is a constant, e.g. MX(5)
if ca.MX(s).is_constant():
return 0
# Case 2: s is a symbol, e.g. MX(x)
elif s.is_symbolic():
if s.name() not in self.derivative:
if len(self.for_loops) > 0 and s in self.for_loops[-1].indexed_symbols:
# Create a new indexed symbol, referencing to the for loop index inside the vector derivative symbol.
for_loop_symbol = self.for_loops[-1].indexed_symbols[s]
s_without_index = self.get_mx(ast.ComponentRef(name=for_loop_symbol.tree.name))
der_s_without_index = self.get_derivative(s_without_index)
if ca.MX(der_s_without_index).is_symbolic():
return self.get_indexed_symbol(ast.ComponentRef(name=der_s_without_index.name(), indices=for_loop_symbol.tree.indices), der_s_without_index)
else:
return 0
else:
der_s = _new_mx("der({})".format(s.name()), s.size())
# If the derivative contains an expression (e.g. der(x + y)) this method is
# called with MX variables that are the result of a ca.symvar call. This
# ca.symvar call strips the _modelica_shape field from the MX variable,
# therefore we need to find the original MX to get the modelica shape.
der_s._modelica_shape = \
self.nodes[self.current_class][s.name()]._modelica_shape
self.derivative[s.name()] = der_s
self.nodes[self.current_class][der_s.name()] = der_s
return der_s
def generate(ast_tree: ast.Tree, model_name: str, options: Dict[str, bool]=None) -> Model:
"""
:param ast_tree: AST to generate from
:param model_name: class to generate
:param options: dictionary of generator options
:return: casadi model
"""
options = _merge_default_options(options)
component_ref = ast.ComponentRef.from_string(model_name)
ast_walker = GeneratorWalker()
flat_tree = flatten(ast_tree, component_ref)
component_ref_tuple = component_ref.to_tuple()
casadi_gen = Generator(flat_tree, component_ref_tuple[-1], options)
ast_walker.walk(casadi_gen, flat_tree)
return casadi_gen.model