1import collections 2import warnings 3 4from sympy.external import import_module 5 6autolevparser = import_module('sympy.parsing.autolev._antlr.autolevparser', 7 import_kwargs={'fromlist': ['AutolevParser']}) 8autolevlexer = import_module('sympy.parsing.autolev._antlr.autolevlexer', 9 import_kwargs={'fromlist': ['AutolevLexer']}) 10autolevlistener = import_module('sympy.parsing.autolev._antlr.autolevlistener', 11 import_kwargs={'fromlist': ['AutolevListener']}) 12 13AutolevParser = getattr(autolevparser, 'AutolevParser', None) 14AutolevLexer = getattr(autolevlexer, 'AutolevLexer', None) 15AutolevListener = getattr(autolevlistener, 'AutolevListener', None) 16 17 18def strfunc(z): 19 if z == 0: 20 return "" 21 elif z == 1: 22 return "_d" 23 else: 24 return "_" + "d" * z 25 26def declare_phy_entities(self, ctx, phy_type, i, j=None): 27 if phy_type in ("frame", "newtonian"): 28 declare_frames(self, ctx, i, j) 29 elif phy_type == "particle": 30 declare_particles(self, ctx, i, j) 31 elif phy_type == "point": 32 declare_points(self, ctx, i, j) 33 elif phy_type == "bodies": 34 declare_bodies(self, ctx, i, j) 35 36def declare_frames(self, ctx, i, j=None): 37 if "{" in ctx.getText(): 38 if j: 39 name1 = ctx.ID().getText().lower() + str(i) + str(j) 40 else: 41 name1 = ctx.ID().getText().lower() + str(i) 42 else: 43 name1 = ctx.ID().getText().lower() 44 name2 = "frame_" + name1 45 if self.getValue(ctx.parentCtx.varType()) == "newtonian": 46 self.newtonian = name2 47 48 self.symbol_table2.update({name1: name2}) 49 50 self.symbol_table.update({name1 + "1>": name2 + ".x"}) 51 self.symbol_table.update({name1 + "2>": name2 + ".y"}) 52 self.symbol_table.update({name1 + "3>": name2 + ".z"}) 53 54 self.type2.update({name1: "frame"}) 55 self.write(name2 + " = " + "_me.ReferenceFrame('" + name1 + "')\n") 56 57def declare_points(self, ctx, i, j=None): 58 if "{" in ctx.getText(): 59 if j: 60 name1 = ctx.ID().getText().lower() + str(i) + str(j) 61 else: 62 name1 = ctx.ID().getText().lower() + str(i) 63 else: 64 name1 = ctx.ID().getText().lower() 65 66 name2 = "point_" + name1 67 68 self.symbol_table2.update({name1: name2}) 69 self.type2.update({name1: "point"}) 70 self.write(name2 + " = " + "_me.Point('" + name1 + "')\n") 71 72def declare_particles(self, ctx, i, j=None): 73 if "{" in ctx.getText(): 74 if j: 75 name1 = ctx.ID().getText().lower() + str(i) + str(j) 76 else: 77 name1 = ctx.ID().getText().lower() + str(i) 78 else: 79 name1 = ctx.ID().getText().lower() 80 81 name2 = "particle_" + name1 82 83 self.symbol_table2.update({name1: name2}) 84 self.type2.update({name1: "particle"}) 85 self.bodies.update({name1: name2}) 86 self.write(name2 + " = " + "_me.Particle('" + name1 + "', " + "_me.Point('" + 87 name1 + "_pt" + "'), " + "_sm.Symbol('m'))\n") 88 89def declare_bodies(self, ctx, i, j=None): 90 if "{" in ctx.getText(): 91 if j: 92 name1 = ctx.ID().getText().lower() + str(i) + str(j) 93 else: 94 name1 = ctx.ID().getText().lower() + str(i) 95 else: 96 name1 = ctx.ID().getText().lower() 97 98 name2 = "body_" + name1 99 self.bodies.update({name1: name2}) 100 masscenter = name2 + "_cm" 101 refFrame = name2 + "_f" 102 103 self.symbol_table2.update({name1: name2}) 104 self.symbol_table2.update({name1 + "o": masscenter}) 105 self.symbol_table.update({name1 + "1>": refFrame+".x"}) 106 self.symbol_table.update({name1 + "2>": refFrame+".y"}) 107 self.symbol_table.update({name1 + "3>": refFrame+".z"}) 108 109 self.type2.update({name1: "bodies"}) 110 self.type2.update({name1+"o": "point"}) 111 112 self.write(masscenter + " = " + "_me.Point('" + name1 + "_cm" + "')\n") 113 if self.newtonian: 114 self.write(masscenter + ".set_vel(" + self.newtonian + ", " + "0)\n") 115 self.write(refFrame + " = " + "_me.ReferenceFrame('" + name1 + "_f" + "')\n") 116 # We set a dummy mass and inertia here. 117 # They will be reset using the setters later in the code anyway. 118 self.write(name2 + " = " + "_me.RigidBody('" + name1 + "', " + masscenter + ", " + 119 refFrame + ", " + "_sm.symbols('m'), (_me.outer(" + refFrame + 120 ".x," + refFrame + ".x)," + masscenter + "))\n") 121 122def inertia_func(self, v1, v2, l, frame): 123 124 if self.type2[v1] == "particle": 125 l.append("_me.inertia_of_point_mass(" + self.bodies[v1] + ".mass, " + self.bodies[v1] + 126 ".point.pos_from(" + self.symbol_table2[v2] + "), " + frame + ")") 127 128 elif self.type2[v1] == "bodies": 129 # Inertia has been defined about center of mass. 130 if self.inertia_point[v1] == v1 + "o": 131 # Asking point is cm as well 132 if v2 == self.inertia_point[v1]: 133 l.append(self.symbol_table2[v1] + ".inertia[0]") 134 135 # Asking point is not cm 136 else: 137 l.append(self.bodies[v1] + ".inertia[0]" + " + " + 138 "_me.inertia_of_point_mass(" + self.bodies[v1] + 139 ".mass, " + self.bodies[v1] + ".masscenter" + 140 ".pos_from(" + self.symbol_table2[v2] + 141 "), " + frame + ")") 142 143 # Inertia has been defined about another point 144 else: 145 # Asking point is the defined point 146 if v2 == self.inertia_point[v1]: 147 l.append(self.symbol_table2[v1] + ".inertia[0]") 148 # Asking point is cm 149 elif v2 == v1 + "o": 150 l.append(self.bodies[v1] + ".inertia[0]" + " - " + 151 "_me.inertia_of_point_mass(" + self.bodies[v1] + 152 ".mass, " + self.bodies[v1] + ".masscenter" + 153 ".pos_from(" + self.symbol_table2[self.inertia_point[v1]] + 154 "), " + frame + ")") 155 # Asking point is some other point 156 else: 157 l.append(self.bodies[v1] + ".inertia[0]" + " - " + 158 "_me.inertia_of_point_mass(" + self.bodies[v1] + 159 ".mass, " + self.bodies[v1] + ".masscenter" + 160 ".pos_from(" + self.symbol_table2[self.inertia_point[v1]] + 161 "), " + frame + ")" + " + " + 162 "_me.inertia_of_point_mass(" + self.bodies[v1] + 163 ".mass, " + self.bodies[v1] + ".masscenter" + 164 ".pos_from(" + self.symbol_table2[v2] + 165 "), " + frame + ")") 166 167 168def processConstants(self, ctx): 169 # Process constant declarations of the type: Constants F = 3, g = 9.81 170 name = ctx.ID().getText().lower() 171 if "=" in ctx.getText(): 172 self.symbol_table.update({name: name}) 173 # self.inputs.update({self.symbol_table[name]: self.getValue(ctx.getChild(2))}) 174 self.write(self.symbol_table[name] + " = " + "_sm.S(" + self.getValue(ctx.getChild(2)) + ")\n") 175 self.type.update({name: "constants"}) 176 return 177 178 # Constants declarations of the type: Constants A, B 179 else: 180 if "{" not in ctx.getText(): 181 self.symbol_table[name] = name 182 self.type[name] = "constants" 183 184 # Process constant declarations of the type: Constants C+, D- 185 if ctx.getChildCount() == 2: 186 # This is set for declaring nonpositive=True and nonnegative=True 187 if ctx.getChild(1).getText() == "+": 188 self.sign[name] = "+" 189 elif ctx.getChild(1).getText() == "-": 190 self.sign[name] = "-" 191 else: 192 if "{" not in ctx.getText(): 193 self.sign[name] = "o" 194 195 # Process constant declarations of the type: Constants K{4}, a{1:2, 1:2}, b{1:2} 196 if "{" in ctx.getText(): 197 if ":" in ctx.getText(): 198 num1 = int(ctx.INT(0).getText()) 199 num2 = int(ctx.INT(1).getText()) + 1 200 else: 201 num1 = 1 202 num2 = int(ctx.INT(0).getText()) + 1 203 204 if ":" in ctx.getText(): 205 if "," in ctx.getText(): 206 num3 = int(ctx.INT(2).getText()) 207 num4 = int(ctx.INT(3).getText()) + 1 208 for i in range(num1, num2): 209 for j in range(num3, num4): 210 self.symbol_table[name + str(i) + str(j)] = name + str(i) + str(j) 211 self.type[name + str(i) + str(j)] = "constants" 212 self.var_list.append(name + str(i) + str(j)) 213 self.sign[name + str(i) + str(j)] = "o" 214 else: 215 for i in range(num1, num2): 216 self.symbol_table[name + str(i)] = name + str(i) 217 self.type[name + str(i)] = "constants" 218 self.var_list.append(name + str(i)) 219 self.sign[name + str(i)] = "o" 220 221 elif "," in ctx.getText(): 222 for i in range(1, int(ctx.INT(0).getText()) + 1): 223 for j in range(1, int(ctx.INT(1).getText()) + 1): 224 self.symbol_table[name] = name + str(i) + str(j) 225 self.type[name + str(i) + str(j)] = "constants" 226 self.var_list.append(name + str(i) + str(j)) 227 self.sign[name + str(i) + str(j)] = "o" 228 229 else: 230 for i in range(num1, num2): 231 self.symbol_table[name + str(i)] = name + str(i) 232 self.type[name + str(i)] = "constants" 233 self.var_list.append(name + str(i)) 234 self.sign[name + str(i)] = "o" 235 236 if "{" not in ctx.getText(): 237 self.var_list.append(name) 238 239 240def writeConstants(self, ctx): 241 l1 = list(filter(lambda x: self.sign[x] == "o", self.var_list)) 242 l2 = list(filter(lambda x: self.sign[x] == "+", self.var_list)) 243 l3 = list(filter(lambda x: self.sign[x] == "-", self.var_list)) 244 try: 245 if self.settings["complex"] == "on": 246 real = ", real=True" 247 elif self.settings["complex"] == "off": 248 real = "" 249 except Exception: 250 real = ", real=True" 251 252 if l1: 253 a = ", ".join(l1) + " = " + "_sm.symbols(" + "'" +\ 254 " ".join(l1) + "'" + real + ")\n" 255 self.write(a) 256 if l2: 257 a = ", ".join(l2) + " = " + "_sm.symbols(" + "'" +\ 258 " ".join(l2) + "'" + real + ", nonnegative=True)\n" 259 self.write(a) 260 if l3: 261 a = ", ".join(l3) + " = " + "_sm.symbols(" + "'" + \ 262 " ".join(l3) + "'" + real + ", nonpositive=True)\n" 263 self.write(a) 264 self.var_list = [] 265 266 267def processVariables(self, ctx): 268 # Specified F = x*N1> + y*N2> 269 name = ctx.ID().getText().lower() 270 if "=" in ctx.getText(): 271 text = name + "'"*(ctx.getChildCount()-3) 272 self.write(text + " = " + self.getValue(ctx.expr()) + "\n") 273 return 274 275 # Process variables of the type: Variables qA, qB 276 if ctx.getChildCount() == 1: 277 self.symbol_table[name] = name 278 if self.getValue(ctx.parentCtx.getChild(0)) in ("variable", "specified", "motionvariable", "motionvariable'"): 279 self.type.update({name: self.getValue(ctx.parentCtx.getChild(0))}) 280 281 self.var_list.append(name) 282 self.sign[name] = 0 283 284 # Process variables of the type: Variables x', y'' 285 elif "'" in ctx.getText() and "{" not in ctx.getText(): 286 if ctx.getText().count("'") > self.maxDegree: 287 self.maxDegree = ctx.getText().count("'") 288 for i in range(ctx.getChildCount()): 289 self.sign[name + strfunc(i)] = i 290 self.symbol_table[name + "'"*i] = name + strfunc(i) 291 if self.getValue(ctx.parentCtx.getChild(0)) in ("variable", "specified", "motionvariable", "motionvariable'"): 292 self.type.update({name + "'"*i: self.getValue(ctx.parentCtx.getChild(0))}) 293 self.var_list.append(name + strfunc(i)) 294 295 elif "{" in ctx.getText(): 296 # Process variables of the type: Variales x{3}, y{2} 297 298 if "'" in ctx.getText(): 299 dash_count = ctx.getText().count("'") 300 if dash_count > self.maxDegree: 301 self.maxDegree = dash_count 302 303 if ":" in ctx.getText(): 304 # Variables C{1:2, 1:2} 305 if "," in ctx.getText(): 306 num1 = int(ctx.INT(0).getText()) 307 num2 = int(ctx.INT(1).getText()) + 1 308 num3 = int(ctx.INT(2).getText()) 309 num4 = int(ctx.INT(3).getText()) + 1 310 # Variables C{1:2} 311 else: 312 num1 = int(ctx.INT(0).getText()) 313 num2 = int(ctx.INT(1).getText()) + 1 314 315 # Variables C{1,3} 316 elif "," in ctx.getText(): 317 num1 = 1 318 num2 = int(ctx.INT(0).getText()) + 1 319 num3 = 1 320 num4 = int(ctx.INT(1).getText()) + 1 321 else: 322 num1 = 1 323 num2 = int(ctx.INT(0).getText()) + 1 324 325 for i in range(num1, num2): 326 try: 327 for j in range(num3, num4): 328 try: 329 for z in range(dash_count+1): 330 self.symbol_table.update({name + str(i) + str(j) + "'"*z: name + str(i) + str(j) + strfunc(z)}) 331 if self.getValue(ctx.parentCtx.getChild(0)) in ("variable", "specified", "motionvariable", "motionvariable'"): 332 self.type.update({name + str(i) + str(j) + "'"*z: self.getValue(ctx.parentCtx.getChild(0))}) 333 self.var_list.append(name + str(i) + str(j) + strfunc(z)) 334 self.sign.update({name + str(i) + str(j) + strfunc(z): z}) 335 if dash_count > self.maxDegree: 336 self.maxDegree = dash_count 337 except Exception: 338 self.symbol_table.update({name + str(i) + str(j): name + str(i) + str(j)}) 339 if self.getValue(ctx.parentCtx.getChild(0)) in ("variable", "specified", "motionvariable", "motionvariable'"): 340 self.type.update({name + str(i) + str(j): self.getValue(ctx.parentCtx.getChild(0))}) 341 self.var_list.append(name + str(i) + str(j)) 342 self.sign.update({name + str(i) + str(j): 0}) 343 except Exception: 344 try: 345 for z in range(dash_count+1): 346 self.symbol_table.update({name + str(i) + "'"*z: name + str(i) + strfunc(z)}) 347 if self.getValue(ctx.parentCtx.getChild(0)) in ("variable", "specified", "motionvariable", "motionvariable'"): 348 self.type.update({name + str(i) + "'"*z: self.getValue(ctx.parentCtx.getChild(0))}) 349 self.var_list.append(name + str(i) + strfunc(z)) 350 self.sign.update({name + str(i) + strfunc(z): z}) 351 if dash_count > self.maxDegree: 352 self.maxDegree = dash_count 353 except Exception: 354 self.symbol_table.update({name + str(i): name + str(i)}) 355 if self.getValue(ctx.parentCtx.getChild(0)) in ("variable", "specified", "motionvariable", "motionvariable'"): 356 self.type.update({name + str(i): self.getValue(ctx.parentCtx.getChild(0))}) 357 self.var_list.append(name + str(i)) 358 self.sign.update({name + str(i): 0}) 359 360def writeVariables(self, ctx): 361 #print(self.sign) 362 #print(self.symbol_table) 363 if self.var_list: 364 for i in range(self.maxDegree+1): 365 if i == 0: 366 j = "" 367 t = "" 368 else: 369 j = str(i) 370 t = ", " 371 l = [] 372 for k in list(filter(lambda x: self.sign[x] == i, self.var_list)): 373 if i == 0: 374 l.append(k) 375 if i == 1: 376 l.append(k[:-1]) 377 if i > 1: 378 l.append(k[:-2]) 379 a = ", ".join(list(filter(lambda x: self.sign[x] == i, self.var_list))) + " = " +\ 380 "_me.dynamicsymbols(" + "'" + " ".join(l) + "'" + t + j + ")\n" 381 l = [] 382 self.write(a) 383 self.maxDegree = 0 384 self.var_list = [] 385 386def processImaginary(self, ctx): 387 name = ctx.ID().getText().lower() 388 self.symbol_table[name] = name 389 self.type[name] = "imaginary" 390 self.var_list.append(name) 391 392 393def writeImaginary(self, ctx): 394 a = ", ".join(self.var_list) + " = " + "_sm.symbols(" + "'" + \ 395 " ".join(self.var_list) + "')\n" 396 b = ", ".join(self.var_list) + " = " + "_sm.I\n" 397 self.write(a) 398 self.write(b) 399 self.var_list = [] 400 401if AutolevListener: 402 class MyListener(AutolevListener): # type: ignore 403 def __init__(self, include_numeric=False): 404 # Stores data in tree nodes(tree annotation). Especially useful for expr reconstruction. 405 self.tree_property = {} 406 407 # Stores the declared variables, constants etc as they are declared in Autolev and SymPy 408 # {"<Autolev symbol>": "<SymPy symbol>"}. 409 self.symbol_table = collections.OrderedDict() 410 411 # Similar to symbol_table. Used for storing Physical entities like Frames, Points, 412 # Particles, Bodies etc 413 self.symbol_table2 = collections.OrderedDict() 414 415 # Used to store nonpositive, nonnegative etc for constants and number of "'"s (order of diff) 416 # in variables. 417 self.sign = {} 418 419 # Simple list used as a store to pass around variables between the 'process' and 'write' 420 # methods. 421 self.var_list = [] 422 423 # Stores the type of a declared variable (constants, variables, specifieds etc) 424 self.type = collections.OrderedDict() 425 426 # Similar to self.type. Used for storing the type of Physical entities like Frames, Points, 427 # Particles, Bodies etc 428 self.type2 = collections.OrderedDict() 429 430 # These lists are used to distinguish matrix, numeric and vector expressions. 431 self.matrix_expr = [] 432 self.numeric_expr = [] 433 self.vector_expr = [] 434 self.fr_expr = [] 435 436 self.output_code = [] 437 438 # Stores the variables and their rhs for substituting upon the Autolev command EXPLICIT. 439 self.explicit = collections.OrderedDict() 440 441 # Write code to import common dependencies. 442 self.output_code.append("import sympy.physics.mechanics as _me\n") 443 self.output_code.append("import sympy as _sm\n") 444 self.output_code.append("import math as m\n") 445 self.output_code.append("import numpy as _np\n") 446 self.output_code.append("\n") 447 448 # Just a store for the max degree variable in a line. 449 self.maxDegree = 0 450 451 # Stores the input parameters which are then used for codegen and numerical analysis. 452 self.inputs = collections.OrderedDict() 453 # Stores the variables which appear in Output Autolev commands. 454 self.outputs = [] 455 # Stores the settings specified by the user. Ex: Complex on/off, Degrees on/off 456 self.settings = {} 457 # Boolean which changes the behaviour of some expression reconstruction 458 # when parsing Input Autolev commands. 459 self.in_inputs = False 460 self.in_outputs = False 461 462 # Stores for the physical entities. 463 self.newtonian = None 464 self.bodies = collections.OrderedDict() 465 self.constants = [] 466 self.forces = collections.OrderedDict() 467 self.q_ind = [] 468 self.q_dep = [] 469 self.u_ind = [] 470 self.u_dep = [] 471 self.kd_eqs = [] 472 self.dependent_variables = [] 473 self.kd_equivalents = collections.OrderedDict() 474 self.kd_equivalents2 = collections.OrderedDict() 475 self.kd_eqs_supplied = None 476 self.kane_type = "no_args" 477 self.inertia_point = collections.OrderedDict() 478 self.kane_parsed = False 479 self.t = False 480 481 # PyDy ode code will be included only if this flag is set to True. 482 self.include_numeric = include_numeric 483 484 def write(self, string): 485 self.output_code.append(string) 486 487 def getValue(self, node): 488 return self.tree_property[node] 489 490 def setValue(self, node, value): 491 self.tree_property[node] = value 492 493 def getSymbolTable(self): 494 return self.symbol_table 495 496 def getType(self): 497 return self.type 498 499 def exitVarDecl(self, ctx): 500 # This event method handles variable declarations. The parse tree node varDecl contains 501 # one or more varDecl2 nodes. Eg varDecl for 'Constants a{1:2, 1:2}, b{1:2}' has two varDecl2 502 # nodes(one for a{1:2, 1:2} and one for b{1:2}). 503 504 # Variable declarations are processed and stored in the event method exitVarDecl2. 505 # This stored information is used to write the final SymPy output code in the exitVarDecl event method. 506 507 # determine the type of declaration 508 if self.getValue(ctx.varType()) == "constant": 509 writeConstants(self, ctx) 510 elif self.getValue(ctx.varType()) in\ 511 ("variable", "motionvariable", "motionvariable'", "specified"): 512 writeVariables(self, ctx) 513 elif self.getValue(ctx.varType()) == "imaginary": 514 writeImaginary(self, ctx) 515 516 def exitVarType(self, ctx): 517 # Annotate the varType tree node with the type of the variable declaration. 518 name = ctx.getChild(0).getText().lower() 519 if name[-1] == "s" and name != "bodies": 520 self.setValue(ctx, name[:-1]) 521 else: 522 self.setValue(ctx, name) 523 524 def exitVarDecl2(self, ctx): 525 # Variable declarations are processed and stored in the event method exitVarDecl2. 526 # This stored information is used to write the final SymPy output code in the exitVarDecl event method. 527 # This is the case for constants, variables, specifieds etc. 528 529 # This isn't the case for all types of declarations though. For instance 530 # Frames A, B, C, N cannot be defined on one line in SymPy. So we do not append A, B, C, N 531 # to a var_list or use exitVarDecl. exitVarDecl2 directly writes out to the file. 532 533 # determine the type of declaration 534 if self.getValue(ctx.parentCtx.varType()) == "constant": 535 processConstants(self, ctx) 536 537 elif self.getValue(ctx.parentCtx.varType()) in \ 538 ("variable", "motionvariable", "motionvariable'", "specified"): 539 processVariables(self, ctx) 540 541 elif self.getValue(ctx.parentCtx.varType()) == "imaginary": 542 processImaginary(self, ctx) 543 544 elif self.getValue(ctx.parentCtx.varType()) in ("frame", "newtonian", "point", "particle", "bodies"): 545 if "{" in ctx.getText(): 546 if ":" in ctx.getText() and "," not in ctx.getText(): 547 num1 = int(ctx.INT(0).getText()) 548 num2 = int(ctx.INT(1).getText()) + 1 549 elif ":" not in ctx.getText() and "," in ctx.getText(): 550 num1 = 1 551 num2 = int(ctx.INT(0).getText()) + 1 552 num3 = 1 553 num4 = int(ctx.INT(1).getText()) + 1 554 elif ":" in ctx.getText() and "," in ctx.getText(): 555 num1 = int(ctx.INT(0).getText()) 556 num2 = int(ctx.INT(1).getText()) + 1 557 num3 = int(ctx.INT(2).getText()) 558 num4 = int(ctx.INT(3).getText()) + 1 559 else: 560 num1 = 1 561 num2 = int(ctx.INT(0).getText()) + 1 562 else: 563 num1 = 1 564 num2 = 2 565 for i in range(num1, num2): 566 try: 567 for j in range(num3, num4): 568 declare_phy_entities(self, ctx, self.getValue(ctx.parentCtx.varType()), i, j) 569 except Exception: 570 declare_phy_entities(self, ctx, self.getValue(ctx.parentCtx.varType()), i) 571 # ================== Subrules of parser rule expr (Start) ====================== # 572 573 def exitId(self, ctx): 574 # Tree annotation for ID which is a labeled subrule of the parser rule expr. 575 # A_C 576 python_keywords = ["and", "as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except",\ 577 "exec", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "not", "or", "pass", "print",\ 578 "raise", "return", "try", "while", "with", "yield"] 579 580 if ctx.ID().getText().lower() in python_keywords: 581 warnings.warn("Python keywords must not be used as identifiers. Please refer to the list of keywords at https://docs.python.org/2.5/ref/keywords.html", 582 SyntaxWarning) 583 584 if "_" in ctx.ID().getText() and ctx.ID().getText().count('_') == 1: 585 e1, e2 = ctx.ID().getText().lower().split('_') 586 try: 587 if self.type2[e1] == "frame": 588 e1 = self.symbol_table2[e1] 589 elif self.type2[e1] == "bodies": 590 e1 = self.symbol_table2[e1] + "_f" 591 if self.type2[e2] == "frame": 592 e2 = self.symbol_table2[e2] 593 elif self.type2[e2] == "bodies": 594 e2 = self.symbol_table2[e2] + "_f" 595 596 self.setValue(ctx, e1 + ".dcm(" + e2 + ")") 597 except Exception: 598 self.setValue(ctx, ctx.ID().getText().lower()) 599 else: 600 # Reserved constant Pi 601 if ctx.ID().getText().lower() == "pi": 602 self.setValue(ctx, "_sm.pi") 603 self.numeric_expr.append(ctx) 604 605 # Reserved variable T (for time) 606 elif ctx.ID().getText().lower() == "t": 607 self.setValue(ctx, "_me.dynamicsymbols._t") 608 if not self.in_inputs and not self.in_outputs: 609 self.t = True 610 611 else: 612 idText = ctx.ID().getText().lower() + "'"*(ctx.getChildCount() - 1) 613 if idText in self.type.keys() and self.type[idText] == "matrix": 614 self.matrix_expr.append(ctx) 615 if self.in_inputs: 616 try: 617 self.setValue(ctx, self.symbol_table[idText]) 618 except Exception: 619 self.setValue(ctx, idText.lower()) 620 else: 621 try: 622 self.setValue(ctx, self.symbol_table[idText]) 623 except Exception: 624 pass 625 626 def exitInt(self, ctx): 627 # Tree annotation for int which is a labeled subrule of the parser rule expr. 628 int_text = ctx.INT().getText() 629 self.setValue(ctx, int_text) 630 self.numeric_expr.append(ctx) 631 632 def exitFloat(self, ctx): 633 # Tree annotation for float which is a labeled subrule of the parser rule expr. 634 floatText = ctx.FLOAT().getText() 635 self.setValue(ctx, floatText) 636 self.numeric_expr.append(ctx) 637 638 def exitAddSub(self, ctx): 639 # Tree annotation for AddSub which is a labeled subrule of the parser rule expr. 640 # The subrule is expr = expr (+|-) expr 641 if ctx.expr(0) in self.matrix_expr or ctx.expr(1) in self.matrix_expr: 642 self.matrix_expr.append(ctx) 643 if ctx.expr(0) in self.vector_expr or ctx.expr(1) in self.vector_expr: 644 self.vector_expr.append(ctx) 645 if ctx.expr(0) in self.numeric_expr and ctx.expr(1) in self.numeric_expr: 646 self.numeric_expr.append(ctx) 647 self.setValue(ctx, self.getValue(ctx.expr(0)) + ctx.getChild(1).getText() + 648 self.getValue(ctx.expr(1))) 649 650 def exitMulDiv(self, ctx): 651 # Tree annotation for MulDiv which is a labeled subrule of the parser rule expr. 652 # The subrule is expr = expr (*|/) expr 653 try: 654 if ctx.expr(0) in self.vector_expr and ctx.expr(1) in self.vector_expr: 655 self.setValue(ctx, "_me.outer(" + self.getValue(ctx.expr(0)) + ", " + 656 self.getValue(ctx.expr(1)) + ")") 657 else: 658 if ctx.expr(0) in self.matrix_expr or ctx.expr(1) in self.matrix_expr: 659 self.matrix_expr.append(ctx) 660 if ctx.expr(0) in self.vector_expr or ctx.expr(1) in self.vector_expr: 661 self.vector_expr.append(ctx) 662 if ctx.expr(0) in self.numeric_expr and ctx.expr(1) in self.numeric_expr: 663 self.numeric_expr.append(ctx) 664 self.setValue(ctx, self.getValue(ctx.expr(0)) + ctx.getChild(1).getText() + 665 self.getValue(ctx.expr(1))) 666 except Exception: 667 pass 668 669 def exitNegativeOne(self, ctx): 670 # Tree annotation for negativeOne which is a labeled subrule of the parser rule expr. 671 self.setValue(ctx, "-1*" + self.getValue(ctx.getChild(1))) 672 if ctx.getChild(1) in self.matrix_expr: 673 self.matrix_expr.append(ctx) 674 if ctx.getChild(1) in self.numeric_expr: 675 self.numeric_expr.append(ctx) 676 677 def exitParens(self, ctx): 678 # Tree annotation for parens which is a labeled subrule of the parser rule expr. 679 # The subrule is expr = '(' expr ')' 680 if ctx.expr() in self.matrix_expr: 681 self.matrix_expr.append(ctx) 682 if ctx.expr() in self.vector_expr: 683 self.vector_expr.append(ctx) 684 if ctx.expr() in self.numeric_expr: 685 self.numeric_expr.append(ctx) 686 self.setValue(ctx, "(" + self.getValue(ctx.expr()) + ")") 687 688 def exitExponent(self, ctx): 689 # Tree annotation for Exponent which is a labeled subrule of the parser rule expr. 690 # The subrule is expr = expr ^ expr 691 if ctx.expr(0) in self.matrix_expr or ctx.expr(1) in self.matrix_expr: 692 self.matrix_expr.append(ctx) 693 if ctx.expr(0) in self.vector_expr or ctx.expr(1) in self.vector_expr: 694 self.vector_expr.append(ctx) 695 if ctx.expr(0) in self.numeric_expr and ctx.expr(1) in self.numeric_expr: 696 self.numeric_expr.append(ctx) 697 self.setValue(ctx, self.getValue(ctx.expr(0)) + "**" + self.getValue(ctx.expr(1))) 698 699 def exitExp(self, ctx): 700 s = ctx.EXP().getText()[ctx.EXP().getText().index('E')+1:] 701 if "-" in s: 702 s = s[0] + s[1:].lstrip("0") 703 else: 704 s = s.lstrip("0") 705 self.setValue(ctx, ctx.EXP().getText()[:ctx.EXP().getText().index('E')] + 706 "*10**(" + s + ")") 707 708 def exitFunction(self, ctx): 709 # Tree annotation for function which is a labeled subrule of the parser rule expr. 710 711 # The difference between this and FunctionCall is that this is used for non standalone functions 712 # appearing in expressions and assignments. 713 # Eg: 714 # When we come across a standalone function say Expand(E, n:m) then it is categorized as FunctionCall 715 # which is a parser rule in itself under rule stat. exitFunctionCall() takes care of it and writes to the file. 716 # 717 # On the other hand, while we come across E_diff = D(E, y), we annotate the tree node 718 # of the function D(E, y) with the SymPy equivalent in exitFunction(). 719 # In this case it is the method exitAssignment() that writes the code to the file and not exitFunction(). 720 721 ch = ctx.getChild(0) 722 func_name = ch.getChild(0).getText().lower() 723 724 # Expand(y, n:m) * 725 if func_name == "expand": 726 expr = self.getValue(ch.expr(0)) 727 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 728 self.matrix_expr.append(ctx) 729 # _sm.Matrix([i.expand() for i in z]).reshape(z.shape[0], z.shape[1]) 730 self.setValue(ctx, "_sm.Matrix([i.expand() for i in " + expr + "])" + 731 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 732 else: 733 self.setValue(ctx, "(" + expr + ")" + "." + "expand()") 734 735 # Factor(y, x) * 736 elif func_name == "factor": 737 expr = self.getValue(ch.expr(0)) 738 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 739 self.matrix_expr.append(ctx) 740 self.setValue(ctx, "_sm.Matrix([_sm.factor(i, " + self.getValue(ch.expr(1)) + ") for i in " + 741 expr + "])" + ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 742 else: 743 self.setValue(ctx, "_sm.factor(" + "(" + expr + ")" + 744 ", " + self.getValue(ch.expr(1)) + ")") 745 746 # D(y, x) 747 elif func_name == "d": 748 expr = self.getValue(ch.expr(0)) 749 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 750 self.matrix_expr.append(ctx) 751 self.setValue(ctx, "_sm.Matrix([i.diff(" + self.getValue(ch.expr(1)) + ") for i in " + 752 expr + "])" + ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 753 else: 754 if ch.getChildCount() == 8: 755 frame = self.symbol_table2[ch.expr(2).getText().lower()] 756 self.setValue(ctx, "(" + expr + ")" + "." + "diff(" + self.getValue(ch.expr(1)) + 757 ", " + frame + ")") 758 else: 759 self.setValue(ctx, "(" + expr + ")" + "." + "diff(" + 760 self.getValue(ch.expr(1)) + ")") 761 762 # Dt(y) 763 elif func_name == "dt": 764 expr = self.getValue(ch.expr(0)) 765 if ch.expr(0) in self.vector_expr: 766 text = "dt(" 767 else: 768 text = "diff(_sm.Symbol('t')" 769 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 770 self.matrix_expr.append(ctx) 771 self.setValue(ctx, "_sm.Matrix([i." + text + 772 ") for i in " + expr + "])" + 773 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 774 else: 775 if ch.getChildCount() == 6: 776 frame = self.symbol_table2[ch.expr(1).getText().lower()] 777 self.setValue(ctx, "(" + expr + ")" + "." + "dt(" + 778 frame + ")") 779 else: 780 self.setValue(ctx, "(" + expr + ")" + "." + text + ")") 781 782 # Explicit(EXPRESS(IMPLICIT>,C)) 783 elif func_name == "explicit": 784 if ch.expr(0) in self.vector_expr: 785 self.vector_expr.append(ctx) 786 expr = self.getValue(ch.expr(0)) 787 if self.explicit.keys(): 788 explicit_list = [] 789 for i in self.explicit.keys(): 790 explicit_list.append(i + ":" + self.explicit[i]) 791 self.setValue(ctx, "(" + expr + ")" + ".subs({" + ", ".join(explicit_list) + "})") 792 else: 793 self.setValue(ctx, expr) 794 795 # Taylor(y, 0:2, w=a, x=0) 796 # TODO: Currently only works with symbols. Make it work for dynamicsymbols. 797 elif func_name == "taylor": 798 exp = self.getValue(ch.expr(0)) 799 order = self.getValue(ch.expr(1).expr(1)) 800 x = (ch.getChildCount()-6)//2 801 l = [] 802 for i in range(x): 803 index = 2 + i 804 child = ch.expr(index) 805 l.append(".series(" + self.getValue(child.getChild(0)) + 806 ", " + self.getValue(child.getChild(2)) + 807 ", " + order + ").removeO()") 808 self.setValue(ctx, "(" + exp + ")" + "".join(l)) 809 810 # Evaluate(y, a=x, b=2) 811 elif func_name == "evaluate": 812 expr = self.getValue(ch.expr(0)) 813 l = [] 814 x = (ch.getChildCount()-4)//2 815 for i in range(x): 816 index = 1 + i 817 child = ch.expr(index) 818 l.append(self.getValue(child.getChild(0)) + ":" + 819 self.getValue(child.getChild(2))) 820 821 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 822 self.matrix_expr.append(ctx) 823 self.setValue(ctx, "_sm.Matrix([i.subs({" + ",".join(l) + "}) for i in " + 824 expr + "])" + 825 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 826 else: 827 if self.explicit: 828 explicit_list = [] 829 for i in self.explicit.keys(): 830 explicit_list.append(i + ":" + self.explicit[i]) 831 self.setValue(ctx, "(" + expr + ")" + ".subs({" + ",".join(explicit_list) + 832 "}).subs({" + ",".join(l) + "})") 833 else: 834 self.setValue(ctx, "(" + expr + ")" + ".subs({" + ",".join(l) + "})") 835 836 # Polynomial([a, b, c], x) 837 elif func_name == "polynomial": 838 self.setValue(ctx, "_sm.Poly(" + self.getValue(ch.expr(0)) + ", " + 839 self.getValue(ch.expr(1)) + ")") 840 841 # Roots(Poly, x, 2) 842 # Roots([1; 2; 3; 4]) 843 elif func_name == "roots": 844 self.matrix_expr.append(ctx) 845 expr = self.getValue(ch.expr(0)) 846 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 847 self.setValue(ctx, "[i.evalf() for i in " + "_sm.solve(" + 848 "_sm.Poly(" + expr + ", " + "x),x)]") 849 else: 850 self.setValue(ctx, "[i.evalf() for i in " + "_sm.solve(" + 851 expr + ", " + self.getValue(ch.expr(1)) + ")]") 852 853 # Transpose(A), Inv(A) 854 elif func_name in ("transpose", "inv", "inverse"): 855 self.matrix_expr.append(ctx) 856 if func_name == "transpose": 857 e = ".T" 858 elif func_name in ("inv", "inverse"): 859 e = "**(-1)" 860 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + e) 861 862 # Eig(A) 863 elif func_name == "eig": 864 # "_sm.Matrix([i.evalf() for i in " + 865 self.setValue(ctx, "_sm.Matrix([i.evalf() for i in (" + 866 self.getValue(ch.expr(0)) + ").eigenvals().keys()])") 867 868 # Diagmat(n, m, x) 869 # Diagmat(3, 1) 870 elif func_name == "diagmat": 871 self.matrix_expr.append(ctx) 872 if ch.getChildCount() == 6: 873 l = [] 874 for i in range(int(self.getValue(ch.expr(0)))): 875 l.append(self.getValue(ch.expr(1)) + ",") 876 877 self.setValue(ctx, "_sm.diag(" + ("".join(l))[:-1] + ")") 878 879 elif ch.getChildCount() == 8: 880 # _sm.Matrix([x if i==j else 0 for i in range(n) for j in range(m)]).reshape(n, m) 881 n = self.getValue(ch.expr(0)) 882 m = self.getValue(ch.expr(1)) 883 x = self.getValue(ch.expr(2)) 884 self.setValue(ctx, "_sm.Matrix([" + x + " if i==j else 0 for i in range(" + 885 n + ") for j in range(" + m + ")]).reshape(" + n + ", " + m + ")") 886 887 # Cols(A) 888 # Cols(A, 1) 889 # Cols(A, 1, 2:4, 3) 890 elif func_name in ("cols", "rows"): 891 self.matrix_expr.append(ctx) 892 if func_name == "cols": 893 e1 = ".cols" 894 e2 = ".T." 895 else: 896 e1 = ".rows" 897 e2 = "." 898 if ch.getChildCount() == 4: 899 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + e1) 900 elif ch.getChildCount() == 6: 901 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + 902 e1[:-1] + "(" + str(int(self.getValue(ch.expr(1))) - 1) + ")") 903 else: 904 l = [] 905 for i in range(4, ch.getChildCount()): 906 try: 907 if ch.getChild(i).getChildCount() > 1 and ch.getChild(i).getChild(1).getText() == ":": 908 for j in range(int(ch.getChild(i).getChild(0).getText()), 909 int(ch.getChild(i).getChild(2).getText())+1): 910 l.append("(" + self.getValue(ch.getChild(2)) + ")" + e2 + 911 "row(" + str(j-1) + ")") 912 else: 913 l.append("(" + self.getValue(ch.getChild(2)) + ")" + e2 + 914 "row(" + str(int(ch.getChild(i).getText())-1) + ")") 915 except Exception: 916 pass 917 self.setValue(ctx, "_sm.Matrix([" + ",".join(l) + "])") 918 919 # Det(A) Trace(A) 920 elif func_name in ["det", "trace"]: 921 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + "." + 922 func_name + "()") 923 924 # Element(A, 2, 3) 925 elif func_name == "element": 926 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + "[" + 927 str(int(self.getValue(ch.expr(1)))-1) + "," + 928 str(int(self.getValue(ch.expr(2)))-1) + "]") 929 930 elif func_name in \ 931 ["cos", "sin", "tan", "cosh", "sinh", "tanh", "acos", "asin", "atan", 932 "log", "exp", "sqrt", "factorial", "floor", "sign"]: 933 self.setValue(ctx, "_sm." + func_name + "(" + self.getValue(ch.expr(0)) + ")") 934 935 elif func_name == "ceil": 936 self.setValue(ctx, "_sm.ceiling" + "(" + self.getValue(ch.expr(0)) + ")") 937 938 elif func_name == "sqr": 939 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + 940 ")" + "**2") 941 942 elif func_name == "log10": 943 self.setValue(ctx, "_sm.log" + 944 "(" + self.getValue(ch.expr(0)) + ", 10)") 945 946 elif func_name == "atan2": 947 self.setValue(ctx, "_sm.atan2" + "(" + self.getValue(ch.expr(0)) + ", " + 948 self.getValue(ch.expr(1)) + ")") 949 950 elif func_name in ["int", "round"]: 951 self.setValue(ctx, func_name + 952 "(" + self.getValue(ch.expr(0)) + ")") 953 954 elif func_name == "abs": 955 self.setValue(ctx, "_sm.Abs(" + self.getValue(ch.expr(0)) + ")") 956 957 elif func_name in ["max", "min"]: 958 # max(x, y, z) 959 l = [] 960 for i in range(1, ch.getChildCount()): 961 if ch.getChild(i) in self.tree_property.keys(): 962 l.append(self.getValue(ch.getChild(i))) 963 elif ch.getChild(i).getText() in [",", "(", ")"]: 964 l.append(ch.getChild(i).getText()) 965 self.setValue(ctx, "_sm." + ch.getChild(0).getText().capitalize() + "".join(l)) 966 967 # Coef(y, x) 968 elif func_name == "coef": 969 #A41_A53=COEF([RHS(U4);RHS(U5)],[U1,U2,U3]) 970 if ch.expr(0) in self.matrix_expr and ch.expr(1) in self.matrix_expr: 971 icount = jcount = 0 972 for i in range(ch.expr(0).getChild(0).getChildCount()): 973 try: 974 ch.expr(0).getChild(0).getChild(i).getRuleIndex() 975 icount+=1 976 except Exception: 977 pass 978 for j in range(ch.expr(1).getChild(0).getChildCount()): 979 try: 980 ch.expr(1).getChild(0).getChild(j).getRuleIndex() 981 jcount+=1 982 except Exception: 983 pass 984 l = [] 985 for i in range(icount): 986 for j in range(jcount): 987 # a41_a53[i,j] = u4.expand().coeff(u1) 988 l.append(self.getValue(ch.expr(0).getChild(0).expr(i)) + ".expand().coeff(" 989 + self.getValue(ch.expr(1).getChild(0).expr(j)) + ")") 990 self.setValue(ctx, "_sm.Matrix([" + ", ".join(l) + "]).reshape(" + str(icount) + ", " + str(jcount) + ")") 991 else: 992 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + 993 ")" + ".expand().coeff(" + self.getValue(ch.expr(1)) + ")") 994 995 # Exclude(y, x) Include(y, x) 996 elif func_name in ("exclude", "include"): 997 if func_name == "exclude": 998 e = "0" 999 else: 1000 e = "1" 1001 expr = self.getValue(ch.expr(0)) 1002 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 1003 self.matrix_expr.append(ctx) 1004 self.setValue(ctx, "_sm.Matrix([i.collect(" + self.getValue(ch.expr(1)) + "])" + 1005 ".coeff(" + self.getValue(ch.expr(1)) + "," + e + ")" + "for i in " + expr + ")" + 1006 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 1007 else: 1008 self.setValue(ctx, "(" + expr + 1009 ")" + ".collect(" + self.getValue(ch.expr(1)) + ")" + 1010 ".coeff(" + self.getValue(ch.expr(1)) + "," + e + ")") 1011 1012 # RHS(y) 1013 elif func_name == "rhs": 1014 self.setValue(ctx, self.explicit[self.getValue(ch.expr(0))]) 1015 1016 # Arrange(y, n, x) * 1017 elif func_name == "arrange": 1018 expr = self.getValue(ch.expr(0)) 1019 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 1020 self.matrix_expr.append(ctx) 1021 self.setValue(ctx, "_sm.Matrix([i.collect(" + self.getValue(ch.expr(2)) + 1022 ")" + "for i in " + expr + "])"+ 1023 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 1024 else: 1025 self.setValue(ctx, "(" + expr + 1026 ")" + ".collect(" + self.getValue(ch.expr(2)) + ")") 1027 1028 # Replace(y, sin(x)=3) 1029 elif func_name == "replace": 1030 l = [] 1031 for i in range(1, ch.getChildCount()): 1032 try: 1033 if ch.getChild(i).getChild(1).getText() == "=": 1034 l.append(self.getValue(ch.getChild(i).getChild(0)) + 1035 ":" + self.getValue(ch.getChild(i).getChild(2))) 1036 except Exception: 1037 pass 1038 expr = self.getValue(ch.expr(0)) 1039 if ch.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 1040 self.matrix_expr.append(ctx) 1041 self.setValue(ctx, "_sm.Matrix([i.subs({" + ",".join(l) + "}) for i in " + 1042 expr + "])" + 1043 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])") 1044 else: 1045 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + 1046 ".subs({" + ",".join(l) + "})") 1047 1048 # Dot(Loop>, N1>) 1049 elif func_name == "dot": 1050 l = [] 1051 num = (ch.expr(1).getChild(0).getChildCount()-1)//2 1052 if ch.expr(1) in self.matrix_expr: 1053 for i in range(num): 1054 l.append("_me.dot(" + self.getValue(ch.expr(0)) + ", " + self.getValue(ch.expr(1).getChild(0).expr(i)) + ")") 1055 self.setValue(ctx, "_sm.Matrix([" + ",".join(l) + "]).reshape(" + str(num) + ", " + "1)") 1056 else: 1057 self.setValue(ctx, "_me.dot(" + self.getValue(ch.expr(0)) + ", " + self.getValue(ch.expr(1)) + ")") 1058 # Cross(w_A_N>, P_NA_AB>) 1059 elif func_name == "cross": 1060 self.vector_expr.append(ctx) 1061 self.setValue(ctx, "_me.cross(" + self.getValue(ch.expr(0)) + ", " + self.getValue(ch.expr(1)) + ")") 1062 1063 # Mag(P_O_Q>) 1064 elif func_name == "mag": 1065 self.setValue(ctx, self.getValue(ch.expr(0)) + "." + "magnitude()") 1066 1067 # MATRIX(A, I_R>>) 1068 elif func_name == "matrix": 1069 if self.type2[ch.expr(0).getText().lower()] == "frame": 1070 text = "" 1071 elif self.type2[ch.expr(0).getText().lower()] == "bodies": 1072 text = "_f" 1073 self.setValue(ctx, "(" + self.getValue(ch.expr(1)) + ")" + ".to_matrix(" + 1074 self.symbol_table2[ch.expr(0).getText().lower()] + text + ")") 1075 1076 # VECTOR(A, ROWS(EIGVECS,1)) 1077 elif func_name == "vector": 1078 if self.type2[ch.expr(0).getText().lower()] == "frame": 1079 text = "" 1080 elif self.type2[ch.expr(0).getText().lower()] == "bodies": 1081 text = "_f" 1082 v = self.getValue(ch.expr(1)) 1083 f = self.symbol_table2[ch.expr(0).getText().lower()] + text 1084 self.setValue(ctx, v + "[0]*" + f + ".x +" + v + "[1]*" + f + ".y +" + 1085 v + "[2]*" + f + ".z") 1086 1087 # Express(A2>, B) 1088 # Here I am dealing with all the Inertia commands as I expect the users to use Inertia 1089 # commands only with Express because SymPy needs the Reference frame to be specified unlike Autolev. 1090 elif func_name == "express": 1091 self.vector_expr.append(ctx) 1092 if self.type2[ch.expr(1).getText().lower()] == "frame": 1093 frame = self.symbol_table2[ch.expr(1).getText().lower()] 1094 else: 1095 frame = self.symbol_table2[ch.expr(1).getText().lower()] + "_f" 1096 if ch.expr(0).getText().lower() == "1>>": 1097 self.setValue(ctx, "_me.inertia(" + frame + ", 1, 1, 1)") 1098 1099 elif '_' in ch.expr(0).getText().lower() and ch.expr(0).getText().lower().count('_') == 2\ 1100 and ch.expr(0).getText().lower()[0] == "i" and ch.expr(0).getText().lower()[-2:] == ">>": 1101 v1 = ch.expr(0).getText().lower()[:-2].split('_')[1] 1102 v2 = ch.expr(0).getText().lower()[:-2].split('_')[2] 1103 l = [] 1104 inertia_func(self, v1, v2, l, frame) 1105 self.setValue(ctx, " + ".join(l)) 1106 1107 elif ch.expr(0).getChild(0).getChild(0).getText().lower() == "inertia": 1108 if ch.expr(0).getChild(0).getChildCount() == 4: 1109 l = [] 1110 v2 = ch.expr(0).getChild(0).ID(0).getText().lower() 1111 for v1 in self.bodies: 1112 inertia_func(self, v1, v2, l, frame) 1113 self.setValue(ctx, " + ".join(l)) 1114 1115 else: 1116 l = [] 1117 l2 = [] 1118 v2 = ch.expr(0).getChild(0).ID(0).getText().lower() 1119 for i in range(1, (ch.expr(0).getChild(0).getChildCount()-2)//2): 1120 l2.append(ch.expr(0).getChild(0).ID(i).getText().lower()) 1121 for v1 in l2: 1122 inertia_func(self, v1, v2, l, frame) 1123 self.setValue(ctx, " + ".join(l)) 1124 1125 else: 1126 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + ".express(" + 1127 self.symbol_table2[ch.expr(1).getText().lower()] + ")") 1128 # CM(P) 1129 elif func_name == "cm": 1130 if self.type2[ch.expr(0).getText().lower()] == "point": 1131 text = "" 1132 else: 1133 text = ".point" 1134 if ch.getChildCount() == 4: 1135 self.setValue(ctx, "_me.functions.center_of_mass(" + self.symbol_table2[ch.expr(0).getText().lower()] + 1136 text + "," + ", ".join(self.bodies.values()) + ")") 1137 else: 1138 bodies = [] 1139 for i in range(1, (ch.getChildCount()-1)//2): 1140 bodies.append(self.symbol_table2[ch.expr(i).getText().lower()]) 1141 self.setValue(ctx, "_me.functions.center_of_mass(" + self.symbol_table2[ch.expr(0).getText().lower()] + 1142 text + "," + ", ".join(bodies) + ")") 1143 1144 # PARTIALS(V_P1_E>,U1) 1145 elif func_name == "partials": 1146 speeds = [] 1147 for i in range(1, (ch.getChildCount()-1)//2): 1148 if self.kd_equivalents2: 1149 speeds.append(self.kd_equivalents2[self.symbol_table[ch.expr(i).getText().lower()]]) 1150 else: 1151 speeds.append(self.symbol_table[ch.expr(i).getText().lower()]) 1152 v1, v2, v3 = ch.expr(0).getText().lower().replace(">","").split('_') 1153 if self.type2[v2] == "point": 1154 point = self.symbol_table2[v2] 1155 elif self.type2[v2] == "particle": 1156 point = self.symbol_table2[v2] + ".point" 1157 frame = self.symbol_table2[v3] 1158 self.setValue(ctx, point + ".partial_velocity(" + frame + ", " + ",".join(speeds) + ")") 1159 1160 # UnitVec(A1>+A2>+A3>) 1161 elif func_name == "unitvec": 1162 self.setValue(ctx, "(" + self.getValue(ch.expr(0)) + ")" + ".normalize()") 1163 1164 # Units(deg, rad) 1165 elif func_name == "units": 1166 if ch.expr(0).getText().lower() == "deg" and ch.expr(1).getText().lower() == "rad": 1167 factor = 0.0174533 1168 elif ch.expr(0).getText().lower() == "rad" and ch.expr(1).getText().lower() == "deg": 1169 factor = 57.2958 1170 self.setValue(ctx, str(factor)) 1171 # Mass(A) 1172 elif func_name == "mass": 1173 l = [] 1174 try: 1175 ch.ID(0).getText().lower() 1176 for i in range((ch.getChildCount()-1)//2): 1177 l.append(self.symbol_table2[ch.ID(i).getText().lower()] + ".mass") 1178 self.setValue(ctx, "+".join(l)) 1179 except Exception: 1180 for i in self.bodies.keys(): 1181 l.append(self.bodies[i] + ".mass") 1182 self.setValue(ctx, "+".join(l)) 1183 1184 # Fr() FrStar() 1185 # _me.KanesMethod(n, q_ind, u_ind, kd, velocity_constraints).kanes_equations(pl, fl)[0] 1186 elif func_name in ["fr", "frstar"]: 1187 if not self.kane_parsed: 1188 if self.kd_eqs: 1189 for i in self.kd_eqs: 1190 self.q_ind.append(self.symbol_table[i.strip().split('-')[0].replace("'","")]) 1191 self.u_ind.append(self.symbol_table[i.strip().split('-')[1].replace("'","")]) 1192 1193 for i in range(len(self.kd_eqs)): 1194 self.kd_eqs[i] = self.symbol_table[self.kd_eqs[i].strip().split('-')[0]] + " - " +\ 1195 self.symbol_table[self.kd_eqs[i].strip().split('-')[1]] 1196 1197 # Do all of this if kd_eqs are not specified 1198 if not self.kd_eqs: 1199 self.kd_eqs_supplied = False 1200 self.matrix_expr.append(ctx) 1201 for i in self.type.keys(): 1202 if self.type[i] == "motionvariable": 1203 if self.sign[self.symbol_table[i.lower()]] == 0: 1204 self.q_ind.append(self.symbol_table[i.lower()]) 1205 elif self.sign[self.symbol_table[i.lower()]] == 1: 1206 name = "u_" + self.symbol_table[i.lower()] 1207 self.symbol_table.update({name: name}) 1208 self.write(name + " = " + "_me.dynamicsymbols('" + name + "')\n") 1209 if self.symbol_table[i.lower()] not in self.dependent_variables: 1210 self.u_ind.append(name) 1211 self.kd_equivalents.update({name: self.symbol_table[i.lower()]}) 1212 else: 1213 self.u_dep.append(name) 1214 self.kd_equivalents.update({name: self.symbol_table[i.lower()]}) 1215 1216 for i in self.kd_equivalents.keys(): 1217 self.kd_eqs.append(self.kd_equivalents[i] + "-" + i) 1218 1219 if not self.u_ind and not self.kd_eqs: 1220 self.u_ind = self.q_ind.copy() 1221 self.q_ind = [] 1222 1223 # deal with velocity constraints 1224 if self.dependent_variables: 1225 for i in self.dependent_variables: 1226 self.u_dep.append(i) 1227 if i in self.u_ind: 1228 self.u_ind.remove(i) 1229 1230 1231 self.u_dep[:] = [i for i in self.u_dep if i not in self.kd_equivalents.values()] 1232 1233 force_list = [] 1234 for i in self.forces.keys(): 1235 force_list.append("(" + i + "," + self.forces[i] + ")") 1236 if self.u_dep: 1237 u_dep_text = ", u_dependent=[" + ", ".join(self.u_dep) + "]" 1238 else: 1239 u_dep_text = "" 1240 if self.dependent_variables: 1241 velocity_constraints_text = ", velocity_constraints = velocity_constraints" 1242 else: 1243 velocity_constraints_text = "" 1244 if ctx.parentCtx not in self.fr_expr: 1245 self.write("kd_eqs = [" + ", ".join(self.kd_eqs) + "]\n") 1246 self.write("forceList = " + "[" + ", ".join(force_list) + "]\n") 1247 self.write("kane = _me.KanesMethod(" + self.newtonian + ", " + "q_ind=[" + 1248 ",".join(self.q_ind) + "], " + "u_ind=[" + 1249 ", ".join(self.u_ind) + "]" + u_dep_text + ", " + 1250 "kd_eqs = kd_eqs" + velocity_constraints_text + ")\n") 1251 self.write("fr, frstar = kane." + "kanes_equations([" + 1252 ", ".join(self.bodies.values()) + "], forceList)\n") 1253 self.fr_expr.append(ctx.parentCtx) 1254 self.kane_parsed = True 1255 self.setValue(ctx, func_name) 1256 1257 def exitMatrices(self, ctx): 1258 # Tree annotation for Matrices which is a labeled subrule of the parser rule expr. 1259 1260 # MO = [a, b; c, d] 1261 # we generate _sm.Matrix([a, b, c, d]).reshape(2, 2) 1262 # The reshape values are determined by counting the "," and ";" in the Autolev matrix 1263 1264 # Eg: 1265 # [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12] 1266 # semicolon_count = 3 and rows = 3+1 = 4 1267 # comma_count = 8 and cols = 8/rows + 1 = 8/4 + 1 = 3 1268 1269 # TODO** Parse block matrices 1270 self.matrix_expr.append(ctx) 1271 l = [] 1272 semicolon_count = 0 1273 comma_count = 0 1274 for i in range(ctx.matrix().getChildCount()): 1275 child = ctx.matrix().getChild(i) 1276 if child == AutolevParser.ExprContext: 1277 l.append(self.getValue(child)) 1278 elif child.getText() == ";": 1279 semicolon_count += 1 1280 l.append(",") 1281 elif child.getText() == ",": 1282 comma_count += 1 1283 l.append(",") 1284 else: 1285 try: 1286 try: 1287 l.append(self.getValue(child)) 1288 except Exception: 1289 l.append(self.symbol_table[child.getText().lower()]) 1290 except Exception: 1291 l.append(child.getText().lower()) 1292 num_of_rows = semicolon_count + 1 1293 num_of_cols = (comma_count//num_of_rows) + 1 1294 1295 self.setValue(ctx, "_sm.Matrix(" + "".join(l) + ")" + ".reshape(" + 1296 str(num_of_rows) + ", " + str(num_of_cols) + ")") 1297 1298 def exitVectorOrDyadic(self, ctx): 1299 self.vector_expr.append(ctx) 1300 ch = ctx.vec() 1301 1302 if ch.getChild(0).getText() == "0>": 1303 self.setValue(ctx, "0") 1304 1305 elif ch.getChild(0).getText() == "1>>": 1306 self.setValue(ctx, "1>>") 1307 1308 elif "_" in ch.ID().getText() and ch.ID().getText().count('_') == 2: 1309 vec_text = ch.getText().lower() 1310 v1, v2, v3 = ch.ID().getText().lower().split('_') 1311 1312 if v1 == "p": 1313 if self.type2[v2] == "point": 1314 e2 = self.symbol_table2[v2] 1315 elif self.type2[v2] == "particle": 1316 e2 = self.symbol_table2[v2] + ".point" 1317 if self.type2[v3] == "point": 1318 e3 = self.symbol_table2[v3] 1319 elif self.type2[v3] == "particle": 1320 e3 = self.symbol_table2[v3] + ".point" 1321 get_vec = e3 + ".pos_from(" + e2 + ")" 1322 self.setValue(ctx, get_vec) 1323 1324 elif v1 in ("w", "alf"): 1325 if v1 == "w": 1326 text = ".ang_vel_in(" 1327 elif v1 == "alf": 1328 text = ".ang_acc_in(" 1329 if self.type2[v2] == "bodies": 1330 e2 = self.symbol_table2[v2] + "_f" 1331 elif self.type2[v2] == "frame": 1332 e2 = self.symbol_table2[v2] 1333 if self.type2[v3] == "bodies": 1334 e3 = self.symbol_table2[v3] + "_f" 1335 elif self.type2[v3] == "frame": 1336 e3 = self.symbol_table2[v3] 1337 get_vec = e2 + text + e3 + ")" 1338 self.setValue(ctx, get_vec) 1339 1340 elif v1 in ("v", "a"): 1341 if v1 == "v": 1342 text = ".vel(" 1343 elif v1 == "a": 1344 text = ".acc(" 1345 if self.type2[v2] == "point": 1346 e2 = self.symbol_table2[v2] 1347 elif self.type2[v2] == "particle": 1348 e2 = self.symbol_table2[v2] + ".point" 1349 get_vec = e2 + text + self.symbol_table2[v3] + ")" 1350 self.setValue(ctx, get_vec) 1351 1352 else: 1353 self.setValue(ctx, vec_text.replace(">", "")) 1354 1355 else: 1356 vec_text = ch.getText().lower() 1357 name = self.symbol_table[vec_text] 1358 self.setValue(ctx, name) 1359 1360 def exitIndexing(self, ctx): 1361 if ctx.getChildCount() == 4: 1362 try: 1363 int_text = str(int(self.getValue(ctx.getChild(2))) - 1) 1364 except Exception: 1365 int_text = self.getValue(ctx.getChild(2)) + " - 1" 1366 self.setValue(ctx, ctx.ID().getText().lower() + "[" + int_text + "]") 1367 elif ctx.getChildCount() == 6: 1368 try: 1369 int_text1 = str(int(self.getValue(ctx.getChild(2))) - 1) 1370 except Exception: 1371 int_text1 = self.getValue(ctx.getChild(2)) + " - 1" 1372 try: 1373 int_text2 = str(int(self.getValue(ctx.getChild(4))) - 1) 1374 except Exception: 1375 int_text2 = self.getValue(ctx.getChild(2)) + " - 1" 1376 self.setValue(ctx, ctx.ID().getText().lower() + "[" + int_text1 + ", " + int_text2 + "]") 1377 1378 1379 # ================== Subrules of parser rule expr (End) ====================== # 1380 1381 def exitRegularAssign(self, ctx): 1382 # Handle assignments of type ID = expr 1383 if ctx.equals().getText() in ["=", "+=", "-=", "*=", "/="]: 1384 equals = ctx.equals().getText() 1385 elif ctx.equals().getText() == ":=": 1386 equals = " = " 1387 elif ctx.equals().getText() == "^=": 1388 equals = "**=" 1389 1390 try: 1391 a = ctx.ID().getText().lower() + "'"*ctx.diff().getText().count("'") 1392 except Exception: 1393 a = ctx.ID().getText().lower() 1394 1395 if a in self.type.keys() and self.type[a] in ("motionvariable", "motionvariable'") and\ 1396 self.type[ctx.expr().getText().lower()] in ("motionvariable", "motionvariable'"): 1397 b = ctx.expr().getText().lower() 1398 if "'" in b and "'" not in a: 1399 a, b = b, a 1400 if not self.kane_parsed: 1401 self.kd_eqs.append(a + "-" + b) 1402 self.kd_equivalents.update({self.symbol_table[a]: 1403 self.symbol_table[b]}) 1404 self.kd_equivalents2.update({self.symbol_table[b]: 1405 self.symbol_table[a]}) 1406 1407 if a in self.symbol_table.keys() and a in self.type.keys() and self.type[a] in ("variable", "motionvariable"): 1408 self.explicit.update({self.symbol_table[a]: self.getValue(ctx.expr())}) 1409 1410 else: 1411 if ctx.expr() in self.matrix_expr: 1412 self.type.update({a: "matrix"}) 1413 1414 try: 1415 b = self.symbol_table[a] 1416 except KeyError: 1417 self.symbol_table[a] = a 1418 1419 if "_" in a and a.count("_") == 1: 1420 e1, e2 = a.split('_') 1421 if e1 in self.type2.keys() and self.type2[e1] in ("frame", "bodies")\ 1422 and e2 in self.type2.keys() and self.type2[e2] in ("frame", "bodies"): 1423 if self.type2[e1] == "bodies": 1424 t1 = "_f" 1425 else: 1426 t1 = "" 1427 if self.type2[e2] == "bodies": 1428 t2 = "_f" 1429 else: 1430 t2 = "" 1431 1432 self.write(self.symbol_table2[e2] + t2 + ".orient(" + self.symbol_table2[e1] + 1433 t1 + ", 'DCM', " + self.getValue(ctx.expr()) + ")\n") 1434 else: 1435 self.write(self.symbol_table[a] + " " + equals + " " + 1436 self.getValue(ctx.expr()) + "\n") 1437 else: 1438 self.write(self.symbol_table[a] + " " + equals + " " + 1439 self.getValue(ctx.expr()) + "\n") 1440 1441 def exitIndexAssign(self, ctx): 1442 # Handle assignments of type ID[index] = expr 1443 if ctx.equals().getText() in ["=", "+=", "-=", "*=", "/="]: 1444 equals = ctx.equals().getText() 1445 elif ctx.equals().getText() == ":=": 1446 equals = " = " 1447 elif ctx.equals().getText() == "^=": 1448 equals = "**=" 1449 1450 text = ctx.ID().getText().lower() 1451 self.type.update({text: "matrix"}) 1452 # Handle assignments of type ID[2] = expr 1453 if ctx.index().getChildCount() == 1: 1454 if ctx.index().getChild(0).getText() == "1": 1455 self.type.update({text: "matrix"}) 1456 self.symbol_table.update({text: text}) 1457 self.write(text + " = " + "_sm.Matrix([[0]])\n") 1458 self.write(text + "[0] = " + self.getValue(ctx.expr()) + "\n") 1459 else: 1460 # m = m.row_insert(m.shape[0], _sm.Matrix([[0]])) 1461 self.write(text + " = " + text + 1462 ".row_insert(" + text + ".shape[0]" + ", " + "_sm.Matrix([[0]])" + ")\n") 1463 self.write(text + "[" + text + ".shape[0]-1" + "] = " + self.getValue(ctx.expr()) + "\n") 1464 1465 # Handle assignments of type ID[2, 2] = expr 1466 elif ctx.index().getChildCount() == 3: 1467 l = [] 1468 try: 1469 l.append(str(int(self.getValue(ctx.index().getChild(0)))-1)) 1470 except Exception: 1471 l.append(self.getValue(ctx.index().getChild(0)) + "-1") 1472 l.append(",") 1473 try: 1474 l.append(str(int(self.getValue(ctx.index().getChild(2)))-1)) 1475 except Exception: 1476 l.append(self.getValue(ctx.index().getChild(2)) + "-1") 1477 self.write(self.symbol_table[ctx.ID().getText().lower()] + 1478 "[" + "".join(l) + "]" + " " + equals + " " + self.getValue(ctx.expr()) + "\n") 1479 1480 def exitVecAssign(self, ctx): 1481 # Handle assignments of the type vec = expr 1482 ch = ctx.vec() 1483 vec_text = ch.getText().lower() 1484 1485 if "_" in ch.ID().getText(): 1486 num = ch.ID().getText().count('_') 1487 1488 if num == 2: 1489 v1, v2, v3 = ch.ID().getText().lower().split('_') 1490 1491 if v1 == "p": 1492 if self.type2[v2] == "point": 1493 e2 = self.symbol_table2[v2] 1494 elif self.type2[v2] == "particle": 1495 e2 = self.symbol_table2[v2] + ".point" 1496 if self.type2[v3] == "point": 1497 e3 = self.symbol_table2[v3] 1498 elif self.type2[v3] == "particle": 1499 e3 = self.symbol_table2[v3] + ".point" 1500 # ab.set_pos(na, la*a.x) 1501 self.write(e3 + ".set_pos(" + e2 + ", " + self.getValue(ctx.expr()) + ")\n") 1502 1503 elif v1 in ("w", "alf"): 1504 if v1 == "w": 1505 text = ".set_ang_vel(" 1506 elif v1 == "alf": 1507 text = ".set_ang_acc(" 1508 # a.set_ang_vel(n, qad*a.z) 1509 if self.type2[v2] == "bodies": 1510 e2 = self.symbol_table2[v2] + "_f" 1511 else: 1512 e2 = self.symbol_table2[v2] 1513 if self.type2[v3] == "bodies": 1514 e3 = self.symbol_table2[v3] + "_f" 1515 else: 1516 e3 = self.symbol_table2[v3] 1517 self.write(e2 + text + e3 + ", " + self.getValue(ctx.expr()) + ")\n") 1518 1519 elif v1 in ("v", "a"): 1520 if v1 == "v": 1521 text = ".set_vel(" 1522 elif v1 == "a": 1523 text = ".set_acc(" 1524 if self.type2[v2] == "point": 1525 e2 = self.symbol_table2[v2] 1526 elif self.type2[v2] == "particle": 1527 e2 = self.symbol_table2[v2] + ".point" 1528 self.write(e2 + text + self.symbol_table2[v3] + 1529 ", " + self.getValue(ctx.expr()) + ")\n") 1530 elif v1 == "i": 1531 if v2 in self.type2.keys() and self.type2[v2] == "bodies": 1532 self.write(self.symbol_table2[v2] + ".inertia = (" + self.getValue(ctx.expr()) + 1533 ", " + self.symbol_table2[v3] + ")\n") 1534 self.inertia_point.update({v2: v3}) 1535 elif v2 in self.type2.keys() and self.type2[v2] == "particle": 1536 self.write(ch.ID().getText().lower() + " = " + self.getValue(ctx.expr()) + "\n") 1537 else: 1538 self.write(ch.ID().getText().lower() + " = " + self.getValue(ctx.expr()) + "\n") 1539 else: 1540 self.write(ch.ID().getText().lower() + " = " + self.getValue(ctx.expr()) + "\n") 1541 1542 elif num == 1: 1543 v1, v2 = ch.ID().getText().lower().split('_') 1544 1545 if v1 in ("force", "torque"): 1546 if self.type2[v2] in ("point", "frame"): 1547 e2 = self.symbol_table2[v2] 1548 elif self.type2[v2] == "particle": 1549 e2 = self.symbol_table2[v2] + ".point" 1550 self.symbol_table.update({vec_text: ch.ID().getText().lower()}) 1551 1552 if e2 in self.forces.keys(): 1553 self.forces[e2] = self.forces[e2] + " + " + self.getValue(ctx.expr()) 1554 else: 1555 self.forces.update({e2: self.getValue(ctx.expr())}) 1556 self.write(ch.ID().getText().lower() + " = " + self.forces[e2] + "\n") 1557 1558 else: 1559 name = ch.ID().getText().lower() 1560 self.symbol_table.update({vec_text: name}) 1561 self.write(ch.ID().getText().lower() + " = " + self.getValue(ctx.expr()) + "\n") 1562 else: 1563 name = ch.ID().getText().lower() 1564 self.symbol_table.update({vec_text: name}) 1565 self.write(name + " " + ctx.getChild(1).getText() + " " + self.getValue(ctx.expr()) + "\n") 1566 else: 1567 name = ch.ID().getText().lower() 1568 self.symbol_table.update({vec_text: name}) 1569 self.write(name + " " + ctx.getChild(1).getText() + " " + self.getValue(ctx.expr()) + "\n") 1570 1571 def enterInputs2(self, ctx): 1572 self.in_inputs = True 1573 1574 # Inputs 1575 def exitInputs2(self, ctx): 1576 # Stores numerical values given by the input command which 1577 # are used for codegen and numerical analysis. 1578 if ctx.getChildCount() == 3: 1579 try: 1580 self.inputs.update({self.symbol_table[ctx.id_diff().getText().lower()]: self.getValue(ctx.expr(0))}) 1581 except Exception: 1582 self.inputs.update({ctx.id_diff().getText().lower(): self.getValue(ctx.expr(0))}) 1583 elif ctx.getChildCount() == 4: 1584 try: 1585 self.inputs.update({self.symbol_table[ctx.id_diff().getText().lower()]: 1586 (self.getValue(ctx.expr(0)), self.getValue(ctx.expr(1)))}) 1587 except Exception: 1588 self.inputs.update({ctx.id_diff().getText().lower(): 1589 (self.getValue(ctx.expr(0)), self.getValue(ctx.expr(1)))}) 1590 1591 self.in_inputs = False 1592 1593 def enterOutputs(self, ctx): 1594 self.in_outputs = True 1595 def exitOutputs(self, ctx): 1596 self.in_outputs = False 1597 1598 def exitOutputs2(self, ctx): 1599 try: 1600 if "[" in ctx.expr(1).getText(): 1601 self.outputs.append(self.symbol_table[ctx.expr(0).getText().lower()] + 1602 ctx.expr(1).getText().lower()) 1603 else: 1604 self.outputs.append(self.symbol_table[ctx.expr(0).getText().lower()]) 1605 1606 except Exception: 1607 pass 1608 1609 # Code commands 1610 def exitCodegen(self, ctx): 1611 # Handles the CODE() command ie the solvers and the codgen part. 1612 # Uses linsolve for the algebraic solvers and nsolve for non linear solvers. 1613 1614 if ctx.functionCall().getChild(0).getText().lower() == "algebraic": 1615 matrix_name = self.getValue(ctx.functionCall().expr(0)) 1616 e = [] 1617 d = [] 1618 for i in range(1, (ctx.functionCall().getChildCount()-2)//2): 1619 a = self.getValue(ctx.functionCall().expr(i)) 1620 e.append(a) 1621 1622 for i in self.inputs.keys(): 1623 d.append(i + ":" + self.inputs[i]) 1624 self.write(matrix_name + "_list" + " = " + "[]\n") 1625 self.write("for i in " + matrix_name + ": " + matrix_name + 1626 "_list" + ".append(i.subs({" + ", ".join(d) + "}))\n") 1627 self.write("print(_sm.linsolve(" + matrix_name + "_list" + ", " + ",".join(e) + "))\n") 1628 1629 elif ctx.functionCall().getChild(0).getText().lower() == "nonlinear": 1630 e = [] 1631 d = [] 1632 guess = [] 1633 for i in range(1, (ctx.functionCall().getChildCount()-2)//2): 1634 a = self.getValue(ctx.functionCall().expr(i)) 1635 e.append(a) 1636 #print(self.inputs) 1637 for i in self.inputs.keys(): 1638 if i in self.symbol_table.keys(): 1639 if type(self.inputs[i]) is tuple: 1640 j, z = self.inputs[i] 1641 else: 1642 j = self.inputs[i] 1643 z = "" 1644 if i not in e: 1645 if z == "deg": 1646 d.append(i + ":" + "_np.deg2rad(" + j + ")") 1647 else: 1648 d.append(i + ":" + j) 1649 else: 1650 if z == "deg": 1651 guess.append("_np.deg2rad(" + j + ")") 1652 else: 1653 guess.append(j) 1654 1655 self.write("matrix_list" + " = " + "[]\n") 1656 self.write("for i in " + self.getValue(ctx.functionCall().expr(0)) + ":") 1657 self.write("matrix_list" + ".append(i.subs({" + ", ".join(d) + "}))\n") 1658 self.write("print(_sm.nsolve(matrix_list," + "(" + ",".join(e) + ")" + 1659 ",(" + ",".join(guess) + ")" + "))\n") 1660 1661 elif ctx.functionCall().getChild(0).getText().lower() in ["ode", "dynamics"] and self.include_numeric: 1662 if self.kane_type == "no_args": 1663 for i in self.symbol_table.keys(): 1664 try: 1665 if self.type[i] == "constants" or self.type[self.symbol_table[i]] == "constants": 1666 self.constants.append(self.symbol_table[i]) 1667 except Exception: 1668 pass 1669 q_add_u = self.q_ind + self.q_dep + self.u_ind + self.u_dep 1670 x0 = [] 1671 for i in q_add_u: 1672 try: 1673 if i in self.inputs.keys(): 1674 if type(self.inputs[i]) is tuple: 1675 if self.inputs[i][1] == "deg": 1676 x0.append(i + ":" + "_np.deg2rad(" + self.inputs[i][0] + ")") 1677 else: 1678 x0.append(i + ":" + self.inputs[i][0]) 1679 else: 1680 x0.append(i + ":" + self.inputs[i]) 1681 elif self.kd_equivalents[i] in self.inputs.keys(): 1682 if type(self.inputs[self.kd_equivalents[i]]) is tuple: 1683 x0.append(i + ":" + self.inputs[self.kd_equivalents[i]][0]) 1684 else: 1685 x0.append(i + ":" + self.inputs[self.kd_equivalents[i]]) 1686 except Exception: 1687 pass 1688 1689 # numerical constants 1690 numerical_constants = [] 1691 for i in self.constants: 1692 if i in self.inputs.keys(): 1693 if type(self.inputs[i]) is tuple: 1694 numerical_constants.append(self.inputs[i][0]) 1695 else: 1696 numerical_constants.append(self.inputs[i]) 1697 1698 # t = linspace 1699 t_final = self.inputs["tfinal"] 1700 integ_stp = self.inputs["integstp"] 1701 1702 self.write("from pydy.system import System\n") 1703 const_list = [] 1704 if numerical_constants: 1705 for i in range(len(self.constants)): 1706 const_list.append(self.constants[i] + ":" + numerical_constants[i]) 1707 specifieds = [] 1708 if self.t: 1709 specifieds.append("_me.dynamicsymbols('t')" + ":" + "lambda x, t: t") 1710 1711 for i in self.inputs: 1712 if i in self.symbol_table.keys() and self.symbol_table[i] not in\ 1713 self.constants + self.q_ind + self.q_dep + self.u_ind + self.u_dep: 1714 specifieds.append(self.symbol_table[i] + ":" + self.inputs[i]) 1715 1716 self.write("sys = System(kane, constants = {" + ", ".join(const_list) + "},\n" + 1717 "specifieds={" + ", ".join(specifieds) + "},\n" + 1718 "initial_conditions={" + ", ".join(x0) + "},\n" + 1719 "times = _np.linspace(0.0, " + str(t_final) + ", " + str(t_final) + 1720 "/" + str(integ_stp) + "))\n\ny=sys.integrate()\n") 1721 1722 # For outputs other than qs and us. 1723 other_outputs = [] 1724 for i in self.outputs: 1725 if i not in q_add_u: 1726 if "[" in i: 1727 other_outputs.append((i[:-3] + i[-2], i[:-3] + "[" + str(int(i[-2])-1) + "]")) 1728 else: 1729 other_outputs.append((i, i)) 1730 1731 for i in other_outputs: 1732 self.write(i[0] + "_out" + " = " + "[]\n") 1733 if other_outputs: 1734 self.write("for i in y:\n") 1735 self.write(" q_u_dict = dict(zip(sys.coordinates+sys.speeds, i))\n") 1736 for i in other_outputs: 1737 self.write(" "*4 + i[0] + "_out" + ".append(" + i[1] + ".subs(q_u_dict)" + 1738 ".subs(sys.constants).evalf())\n") 1739 1740 # Standalone function calls (used for dual functions) 1741 def exitFunctionCall(self, ctx): 1742 # Basically deals with standalone function calls ie functions which are not a part of 1743 # expressions and assignments. Autolev Dual functions can both appear in standalone 1744 # function calls and also on the right hand side as part of expr or assignment. 1745 1746 # Dual functions are indicated by a * in the comments below 1747 1748 # Checks if the function is a statement on its own 1749 if ctx.parentCtx.getRuleIndex() == AutolevParser.RULE_stat: 1750 func_name = ctx.getChild(0).getText().lower() 1751 # Expand(E, n:m) * 1752 if func_name == "expand": 1753 # If the first argument is a pre declared variable. 1754 expr = self.getValue(ctx.expr(0)) 1755 symbol = self.symbol_table[ctx.expr(0).getText().lower()] 1756 if ctx.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 1757 self.write(symbol + " = " + "_sm.Matrix([i.expand() for i in " + expr + "])" + 1758 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])\n") 1759 else: 1760 self.write(symbol + " = " + symbol + "." + "expand()\n") 1761 1762 # Factor(E, x) * 1763 elif func_name == "factor": 1764 expr = self.getValue(ctx.expr(0)) 1765 symbol = self.symbol_table[ctx.expr(0).getText().lower()] 1766 if ctx.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 1767 self.write(symbol + " = " + "_sm.Matrix([_sm.factor(i," + self.getValue(ctx.expr(1)) + 1768 ") for i in " + expr + "])" + 1769 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])\n") 1770 else: 1771 self.write(expr + " = " + "_sm.factor(" + expr + ", " + 1772 self.getValue(ctx.expr(1)) + ")\n") 1773 1774 # Solve(Zero, x, y) 1775 elif func_name == "solve": 1776 l = [] 1777 l2 = [] 1778 num = 0 1779 for i in range(1, ctx.getChildCount()): 1780 if ctx.getChild(i).getText() == ",": 1781 num+=1 1782 try: 1783 l.append(self.getValue(ctx.getChild(i))) 1784 except Exception: 1785 l.append(ctx.getChild(i).getText()) 1786 1787 if i != 2: 1788 try: 1789 l2.append(self.getValue(ctx.getChild(i))) 1790 except Exception: 1791 pass 1792 1793 for i in l2: 1794 self.explicit.update({i: "_sm.solve" + "".join(l) + "[" + i + "]"}) 1795 1796 self.write("print(_sm.solve" + "".join(l) + ")\n") 1797 1798 # Arrange(y, n, x) * 1799 elif func_name == "arrange": 1800 expr = self.getValue(ctx.expr(0)) 1801 symbol = self.symbol_table[ctx.expr(0).getText().lower()] 1802 1803 if ctx.expr(0) in self.matrix_expr or (expr in self.type.keys() and self.type[expr] == "matrix"): 1804 self.write(symbol + " = " + "_sm.Matrix([i.collect(" + self.getValue(ctx.expr(2)) + 1805 ")" + "for i in " + expr + "])" + 1806 ".reshape((" + expr + ").shape[0], " + "(" + expr + ").shape[1])\n") 1807 else: 1808 self.write(self.getValue(ctx.expr(0)) + ".collect(" + 1809 self.getValue(ctx.expr(2)) + ")\n") 1810 1811 # Eig(M, EigenValue, EigenVec) 1812 elif func_name == "eig": 1813 self.symbol_table.update({ctx.expr(1).getText().lower(): ctx.expr(1).getText().lower()}) 1814 self.symbol_table.update({ctx.expr(2).getText().lower(): ctx.expr(2).getText().lower()}) 1815 # _sm.Matrix([i.evalf() for i in (i_s_so).eigenvals().keys()]) 1816 self.write(ctx.expr(1).getText().lower() + " = " + 1817 "_sm.Matrix([i.evalf() for i in " + 1818 "(" + self.getValue(ctx.expr(0)) + ")" + ".eigenvals().keys()])\n") 1819 # _sm.Matrix([i[2][0].evalf() for i in (i_s_o).eigenvects()]).reshape(i_s_o.shape[0], i_s_o.shape[1]) 1820 self.write(ctx.expr(2).getText().lower() + " = " + 1821 "_sm.Matrix([i[2][0].evalf() for i in " + "(" + self.getValue(ctx.expr(0)) + ")" + 1822 ".eigenvects()]).reshape(" + self.getValue(ctx.expr(0)) + ".shape[0], " + 1823 self.getValue(ctx.expr(0)) + ".shape[1])\n") 1824 1825 # Simprot(N, A, 3, qA) 1826 elif func_name == "simprot": 1827 # A.orient(N, 'Axis', qA, N.z) 1828 if self.type2[ctx.expr(0).getText().lower()] == "frame": 1829 frame1 = self.symbol_table2[ctx.expr(0).getText().lower()] 1830 elif self.type2[ctx.expr(0).getText().lower()] == "bodies": 1831 frame1 = self.symbol_table2[ctx.expr(0).getText().lower()] + "_f" 1832 if self.type2[ctx.expr(1).getText().lower()] == "frame": 1833 frame2 = self.symbol_table2[ctx.expr(1).getText().lower()] 1834 elif self.type2[ctx.expr(1).getText().lower()] == "bodies": 1835 frame2 = self.symbol_table2[ctx.expr(1).getText().lower()] + "_f" 1836 e2 = "" 1837 if ctx.expr(2).getText()[0] == "-": 1838 e2 = "-1*" 1839 if ctx.expr(2).getText() in ("1", "-1"): 1840 e = frame1 + ".x" 1841 elif ctx.expr(2).getText() in ("2", "-2"): 1842 e = frame1 + ".y" 1843 elif ctx.expr(2).getText() in ("3", "-3"): 1844 e = frame1 + ".z" 1845 else: 1846 e = self.getValue(ctx.expr(2)) 1847 e2 = "" 1848 1849 if "degrees" in self.settings.keys() and self.settings["degrees"] == "off": 1850 value = self.getValue(ctx.expr(3)) 1851 else: 1852 if ctx.expr(3) in self.numeric_expr: 1853 value = "_np.deg2rad(" + self.getValue(ctx.expr(3)) + ")" 1854 else: 1855 value = self.getValue(ctx.expr(3)) 1856 self.write(frame2 + ".orient(" + frame1 + 1857 ", " + "'Axis'" + ", " + "[" + value + 1858 ", " + e2 + e + "]" + ")\n") 1859 1860 # Express(A2>, B) * 1861 elif func_name == "express": 1862 if self.type2[ctx.expr(1).getText().lower()] == "bodies": 1863 f = "_f" 1864 else: 1865 f = "" 1866 1867 if '_' in ctx.expr(0).getText().lower() and ctx.expr(0).getText().count('_') == 2: 1868 vec = ctx.expr(0).getText().lower().replace(">", "").split('_') 1869 v1 = self.symbol_table2[vec[1]] 1870 v2 = self.symbol_table2[vec[2]] 1871 if vec[0] == "p": 1872 self.write(v2 + ".set_pos(" + v1 + ", " + "(" + self.getValue(ctx.expr(0)) + 1873 ")" + ".express(" + self.symbol_table2[ctx.expr(1).getText().lower()] + f + "))\n") 1874 elif vec[0] == "v": 1875 self.write(v1 + ".set_vel(" + v2 + ", " + "(" + self.getValue(ctx.expr(0)) + 1876 ")" + ".express(" + self.symbol_table2[ctx.expr(1).getText().lower()] + f + "))\n") 1877 elif vec[0] == "a": 1878 self.write(v1 + ".set_acc(" + v2 + ", " + "(" + self.getValue(ctx.expr(0)) + 1879 ")" + ".express(" + self.symbol_table2[ctx.expr(1).getText().lower()] + f + "))\n") 1880 else: 1881 self.write(self.getValue(ctx.expr(0)) + " = " + "(" + self.getValue(ctx.expr(0)) + ")" + ".express(" + 1882 self.symbol_table2[ctx.expr(1).getText().lower()] + f + ")\n") 1883 else: 1884 self.write(self.getValue(ctx.expr(0)) + " = " + "(" + self.getValue(ctx.expr(0)) + ")" + ".express(" + 1885 self.symbol_table2[ctx.expr(1).getText().lower()] + f + ")\n") 1886 1887 # Angvel(A, B) 1888 elif func_name == "angvel": 1889 self.write("print(" + self.symbol_table2[ctx.expr(1).getText().lower()] + 1890 ".ang_vel_in(" + self.symbol_table2[ctx.expr(0).getText().lower()] + "))\n") 1891 1892 # v2pts(N, A, O, P) 1893 elif func_name in ("v2pts", "a2pts", "v2pt", "a1pt"): 1894 if func_name == "v2pts": 1895 text = ".v2pt_theory(" 1896 elif func_name == "a2pts": 1897 text = ".a2pt_theory(" 1898 elif func_name == "v1pt": 1899 text = ".v1pt_theory(" 1900 elif func_name == "a1pt": 1901 text = ".a1pt_theory(" 1902 if self.type2[ctx.expr(1).getText().lower()] == "frame": 1903 frame = self.symbol_table2[ctx.expr(1).getText().lower()] 1904 elif self.type2[ctx.expr(1).getText().lower()] == "bodies": 1905 frame = self.symbol_table2[ctx.expr(1).getText().lower()] + "_f" 1906 expr_list = [] 1907 for i in range(2, 4): 1908 if self.type2[ctx.expr(i).getText().lower()] == "point": 1909 expr_list.append(self.symbol_table2[ctx.expr(i).getText().lower()]) 1910 elif self.type2[ctx.expr(i).getText().lower()] == "particle": 1911 expr_list.append(self.symbol_table2[ctx.expr(i).getText().lower()] + ".point") 1912 1913 self.write(expr_list[1] + text + expr_list[0] + 1914 "," + self.symbol_table2[ctx.expr(0).getText().lower()] + "," + 1915 frame + ")\n") 1916 1917 # Gravity(g*N1>) 1918 elif func_name == "gravity": 1919 for i in self.bodies.keys(): 1920 if self.type2[i] == "bodies": 1921 e = self.symbol_table2[i] + ".masscenter" 1922 elif self.type2[i] == "particle": 1923 e = self.symbol_table2[i] + ".point" 1924 if e in self.forces.keys(): 1925 self.forces[e] = self.forces[e] + self.symbol_table2[i] +\ 1926 ".mass*(" + self.getValue(ctx.expr(0)) + ")" 1927 else: 1928 self.forces.update({e: self.symbol_table2[i] + 1929 ".mass*(" + self.getValue(ctx.expr(0)) + ")"}) 1930 self.write("force_" + i + " = " + self.forces[e] + "\n") 1931 1932 # Explicit(EXPRESS(IMPLICIT>,C)) 1933 elif func_name == "explicit": 1934 if ctx.expr(0) in self.vector_expr: 1935 self.vector_expr.append(ctx) 1936 expr = self.getValue(ctx.expr(0)) 1937 if self.explicit.keys(): 1938 explicit_list = [] 1939 for i in self.explicit.keys(): 1940 explicit_list.append(i + ":" + self.explicit[i]) 1941 if '_' in ctx.expr(0).getText().lower() and ctx.expr(0).getText().count('_') == 2: 1942 vec = ctx.expr(0).getText().lower().replace(">", "").split('_') 1943 v1 = self.symbol_table2[vec[1]] 1944 v2 = self.symbol_table2[vec[2]] 1945 if vec[0] == "p": 1946 self.write(v2 + ".set_pos(" + v1 + ", " + "(" + expr + 1947 ")" + ".subs({" + ", ".join(explicit_list) + "}))\n") 1948 elif vec[0] == "v": 1949 self.write(v2 + ".set_vel(" + v1 + ", " + "(" + expr + 1950 ")" + ".subs({" + ", ".join(explicit_list) + "}))\n") 1951 elif vec[0] == "a": 1952 self.write(v2 + ".set_acc(" + v1 + ", " + "(" + expr + 1953 ")" + ".subs({" + ", ".join(explicit_list) + "}))\n") 1954 else: 1955 self.write(expr + " = " + "(" + expr + ")" + ".subs({" + ", ".join(explicit_list) + "})\n") 1956 else: 1957 self.write(expr + " = " + "(" + expr + ")" + ".subs({" + ", ".join(explicit_list) + "})\n") 1958 1959 # Force(O/Q, -k*Stretch*Uvec>) 1960 elif func_name in ("force", "torque"): 1961 1962 if "/" in ctx.expr(0).getText().lower(): 1963 p1 = ctx.expr(0).getText().lower().split('/')[0] 1964 p2 = ctx.expr(0).getText().lower().split('/')[1] 1965 if self.type2[p1] in ("point", "frame"): 1966 pt1 = self.symbol_table2[p1] 1967 elif self.type2[p1] == "particle": 1968 pt1 = self.symbol_table2[p1] + ".point" 1969 if self.type2[p2] in ("point", "frame"): 1970 pt2 = self.symbol_table2[p2] 1971 elif self.type2[p2] == "particle": 1972 pt2 = self.symbol_table2[p2] + ".point" 1973 if pt1 in self.forces.keys(): 1974 self.forces[pt1] = self.forces[pt1] + " + -1*("+self.getValue(ctx.expr(1)) + ")" 1975 self.write("force_" + p1 + " = " + self.forces[pt1] + "\n") 1976 else: 1977 self.forces.update({pt1: "-1*("+self.getValue(ctx.expr(1)) + ")"}) 1978 self.write("force_" + p1 + " = " + self.forces[pt1] + "\n") 1979 if pt2 in self.forces.keys(): 1980 self.forces[pt2] = self.forces[pt2] + "+ " + self.getValue(ctx.expr(1)) 1981 self.write("force_" + p2 + " = " + self.forces[pt2] + "\n") 1982 else: 1983 self.forces.update({pt2: self.getValue(ctx.expr(1))}) 1984 self.write("force_" + p2 + " = " + self.forces[pt2] + "\n") 1985 1986 elif ctx.expr(0).getChildCount() == 1: 1987 p1 = ctx.expr(0).getText().lower() 1988 if self.type2[p1] in ("point", "frame"): 1989 pt1 = self.symbol_table2[p1] 1990 elif self.type2[p1] == "particle": 1991 pt1 = self.symbol_table2[p1] + ".point" 1992 if pt1 in self.forces.keys(): 1993 self.forces[pt1] = self.forces[pt1] + "+ -1*(" + self.getValue(ctx.expr(1)) + ")" 1994 else: 1995 self.forces.update({pt1: "-1*(" + self.getValue(ctx.expr(1)) + ")"}) 1996 1997 # Constrain(Dependent[qB]) 1998 elif func_name == "constrain": 1999 if ctx.getChild(2).getChild(0).getText().lower() == "dependent": 2000 self.write("velocity_constraints = [i for i in dependent]\n") 2001 x = (ctx.expr(0).getChildCount()-2)//2 2002 for i in range(x): 2003 self.dependent_variables.append(self.getValue(ctx.expr(0).expr(i))) 2004 2005 # Kane() 2006 elif func_name == "kane": 2007 if ctx.getChildCount() == 3: 2008 self.kane_type = "no_args" 2009 2010 # Settings 2011 def exitSettings(self, ctx): 2012 # Stores settings like Complex on/off, Degrees on/off etc in self.settings. 2013 try: 2014 self.settings.update({ctx.getChild(0).getText().lower(): 2015 ctx.getChild(1).getText().lower()}) 2016 except Exception: 2017 pass 2018 2019 def exitMassDecl2(self, ctx): 2020 # Used for declaring the masses of particles and rigidbodies. 2021 particle = self.symbol_table2[ctx.getChild(0).getText().lower()] 2022 if ctx.getText().count("=") == 2: 2023 if ctx.expr().expr(1) in self.numeric_expr: 2024 e = "_sm.S(" + self.getValue(ctx.expr().expr(1)) + ")" 2025 else: 2026 e = self.getValue(ctx.expr().expr(1)) 2027 self.symbol_table.update({ctx.expr().expr(0).getText().lower(): ctx.expr().expr(0).getText().lower()}) 2028 self.write(ctx.expr().expr(0).getText().lower() + " = " + e + "\n") 2029 mass = ctx.expr().expr(0).getText().lower() 2030 else: 2031 try: 2032 if ctx.expr() in self.numeric_expr: 2033 mass = "_sm.S(" + self.getValue(ctx.expr()) + ")" 2034 else: 2035 mass = self.getValue(ctx.expr()) 2036 except Exception: 2037 a_text = ctx.expr().getText().lower() 2038 self.symbol_table.update({a_text: a_text}) 2039 self.type.update({a_text: "constants"}) 2040 self.write(a_text + " = " + "_sm.symbols('" + a_text + "')\n") 2041 mass = a_text 2042 2043 self.write(particle + ".mass = " + mass + "\n") 2044 2045 def exitInertiaDecl(self, ctx): 2046 inertia_list = [] 2047 try: 2048 ctx.ID(1).getText() 2049 num = 5 2050 except Exception: 2051 num = 2 2052 for i in range((ctx.getChildCount()-num)//2): 2053 try: 2054 if ctx.expr(i) in self.numeric_expr: 2055 inertia_list.append("_sm.S(" + self.getValue(ctx.expr(i)) + ")") 2056 else: 2057 inertia_list.append(self.getValue(ctx.expr(i))) 2058 except Exception: 2059 a_text = ctx.expr(i).getText().lower() 2060 self.symbol_table.update({a_text: a_text}) 2061 self.type.update({a_text: "constants"}) 2062 self.write(a_text + " = " + "_sm.symbols('" + a_text + "')\n") 2063 inertia_list.append(a_text) 2064 2065 if len(inertia_list) < 6: 2066 for i in range(6-len(inertia_list)): 2067 inertia_list.append("0") 2068 # body_a.inertia = (_me.inertia(body_a, I1, I2, I3, 0, 0, 0), body_a_cm) 2069 try: 2070 frame = self.symbol_table2[ctx.ID(1).getText().lower()] 2071 point = self.symbol_table2[ctx.ID(0).getText().lower().split('_')[1]] 2072 body = self.symbol_table2[ctx.ID(0).getText().lower().split('_')[0]] 2073 self.inertia_point.update({ctx.ID(0).getText().lower().split('_')[0] 2074 : ctx.ID(0).getText().lower().split('_')[1]}) 2075 self.write(body + ".inertia" + " = " + "(_me.inertia(" + frame + ", " + 2076 ", ".join(inertia_list) + "), " + point + ")\n") 2077 2078 except Exception: 2079 body_name = self.symbol_table2[ctx.ID(0).getText().lower()] 2080 body_name_cm = body_name + "_cm" 2081 self.inertia_point.update({ctx.ID(0).getText().lower(): ctx.ID(0).getText().lower() + "o"}) 2082 self.write(body_name + ".inertia" + " = " + "(_me.inertia(" + body_name + "_f" + ", " + 2083 ", ".join(inertia_list) + "), " + body_name_cm + ")\n") 2084