OpenModelica Python Interface and PySimulator

This chapter describes the OpenModelica Python integration facilities.

OMPython – OpenModelica Python Interface

OMPython – OpenModelica Python API is a free, open source, highly portable Python based interactive session handler for Modelica scripting. It provides the modeler with components for creating a complete Modelica modeling, compilation and simulation environment based on the latest OpenModelica library standard available. OMPython is architectured to combine both the solving strategy and model building. So domain experts (people writing the models) and computational engineers (people writing the solver code) can work on one unified tool that is industrially viable for optimization of Modelica models, while offering a flexible platform for algorithm development and research. OMPython v2.0 is not a standalone package, it depends upon the OpenModelica installation.

OMPython v2.0 is implemented in Python using the OmniORB and OmniORBpy - high performance CORBA ORBs for Python and it supports the Modelica Standard Library version 3.2 that is included in starting with OpenModelica 1.9.2. It is now primarily available using the command pip install ompython, but it is also possible to run python setup.py install manually or use the version provided in the Windows installer.

Features of OMPython

OMPython provides user friendly features like:

  • Interactive session handling, parsing, interpretation of commands and

    Modelica expressions for evaluation, simulation, plotting, etc.

  • Interface to the latest OpenModelica API calls.

  • Optimized parser results that give control over every element of the

    output.

  • Helper functions to allow manipulation on Nested dictionaries.

  • Easy access to the library and testing of OpenModelica commands.

Test Commands

To test the command outputs, simply create an OMCSession object by importing from the OMPython library within Python interepreter. The module allows you to interactively send commands to the OMC server and display their output.

To get started, create an OMCSession object:

>>> from OMPython import OMCSession
>>> omc = OMCSession()
>>> omc.sendExpression("getVersion()")
v1.9.4-dev.beta2
>>> omc.sendExpression("cd()")
«DOCHOME»
>>> omc.sendExpression("loadModel(Modelica)")
True
>>> omc.sendExpression("loadFile(getInstallationDirectoryPath() + \"/share/doc/omc/testmodels/BouncingBall.mo\")")
True
>>> omc.sendExpression("instantiateModel(BouncingBall)")
class BouncingBall
  parameter Real e = 0.7 "coefficient of restitution";
  parameter Real g = 9.81 "gravity acceleration";
  Real h(start = 1.0) "height of ball";
  Real v "velocity of ball";
  Boolean flying(start = true) "true, if ball is flying";
  Boolean impact;
  Real v_new;
  Integer foo;
equation
  impact = h <= 0.0;
  foo = if impact then 1 else 2;
  der(v) = if flying then -g else 0.0;
  der(h) = v;
  when {h <= 0.0 and v <= 0.0, impact} then
    v_new = if edge(impact) then (-e) * pre(v) else 0.0;
    flying = v_new > 0.0;
    reinit(v, v_new);
  end when;
end BouncingBall;

We get the name and other properties of a class:

>>> omc.sendExpression("getClassNames()")
('BouncingBall', 'ModelicaServices', 'Complex', 'Modelica')
>>> omc.sendExpression("isPartial(BouncingBall)")
False
>>> omc.sendExpression("isPackage(BouncingBall)")
False
>>> omc.sendExpression("isModel(BouncingBall)")
True
>>> omc.sendExpression("checkModel(BouncingBall)")
Check of BouncingBall completed successfully.
Class BouncingBall has 6 equation(s) and 6 variable(s).
1 of these are trivial equation(s).
>>> omc.sendExpression("getClassRestriction(BouncingBall)")
model
>>> omc.sendExpression("getClassInformation(BouncingBall)")
('model', '', False, False, False, '«OPENMODELICAHOME»/share/doc/omc/testmodels/BouncingBall.mo', False, 1, 1, 23, 17, (), False, False)
>>> omc.sendExpression("getConnectionCount(BouncingBall)")
0
>>> omc.sendExpression("getInheritanceCount(BouncingBall)")
0
>>> omc.sendExpression("getComponentModifierValue(BouncingBall,e)")
0.7
>>> omc.sendExpression("checkSettings()")
{'RTLIBS': ' -lOpenModelicaRuntimeC  -llapack -lblas   -lm -lomcgc -lpthread -rdynamic', 'OMC_FOUND': True, 'MODELICAUSERCFLAGS': '', 'C_COMPILER_RESPONDING': True, 'OPENMODELICAHOME': '«OPENMODELICAHOME»', 'CREATE_FILE_WORKS': True, 'SYSTEM_INFO': 'Linux asap 3.13.0-77-generic #121-Ubuntu SMP Wed Jan 20 10:50:42 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux\n', 'HAVE_CORBA': True, 'OMDEV_PATH': '', 'C_COMPILER_VERSION': 'Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)\nTarget: x86_64-pc-linux-gnu\nThread model: posix\n', 'OMC_PATH': '«OPENMODELICAHOME»/bin/omc', 'WORKING_DIRECTORY': '«DOCHOME»', 'REMOVE_FILE_WORKS': True, 'CONFIGURE_CMDLINE': "Configured 2016-02-18 13:12:14 using arguments: '--disable-option-checking --prefix=«OPENMODELICAHOME» --without-cppruntime --with-omniORB --enable-modelica3d CC=clang CXX=clang++ OMPCC=gcc -fopenmp CFLAGS=-O2 -march=native --without-omc --with-omlibrary=core --with-ombuilddir=«OPENMODELICAHOME» --cache-file=/dev/null --srcdir=.'", 'SYSTEM_PATH': '/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/var/lib/hudson/.local/bin/:/var/lib/hudson/.cabal/bin/;«OPENMODELICAHOME»/bin', 'OS': 'linux', 'OPENMODELICALIBRARY': '«OPENMODELICAHOME»/lib/omlibrary', 'C_COMPILER': 'clang'}

The common combination of a simulation followed by getting a value and doing a plot:

>>> omc.sendExpression("simulate(BouncingBall, stopTime=3.0)")
{'timeCompile': 0.229290396, 'simulationOptions': "startTime = 0.0, stopTime = 3.0, numberOfIntervals = 500, tolerance = 1e-06, method = 'dassl', fileNamePrefix = 'BouncingBall', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''", 'timeBackend': 0.004728133000000001, 'messages': '', 'timeFrontend': 0.255693717, 'timeSimulation': 0.009913094, 'timeTemplates': 0.005842274000000001, 'timeSimCode': 0.1004661229999999, 'timeTotal': 0.6060702819999999, 'resultFile': '«DOCHOME»/BouncingBall_res.mat'}
"Warning: The initial conditions are not fully specified. Use +d=initialization for more information.
"
>>> omc.sendExpression("val(h , 2.0)")
0.0423943077288

Import As Library

To use the module from within another python program, simply import OMCSession from within the using program. Make use of the execute() function of the OMPython library to send commands to the OMC server.

For example:

answer = OMPython.execute(cmd)

Full example:

# test.py
from OMPython import OMCSession
omc = OMCSession()
cmds = [
  "loadModel(Modelica)",
  "model test end test;",
  'loadFile(getInstallationDirectoryPath() + "/share/doc/omc/testmodels/BouncingBall.mo")'
  "getIconAnnotation(Modelica.Electrical.Analog.Basic.Resistor)",
  "getElementsInfo(Modelica.Electrical.Analog.Basic.Resistor)",
  "simulate(BouncingBall)",
  "plot(h)"
  ]
for cmd in cmds:
  answer = omc.sendExpression(cmd)
  print "\\nResult:\\n%s"%answer

Implementation

Client Implementation

The OpenModelica Python API Interface – OMPython, attempts to mimic the OMShell's style of operations.

OMPython is designed to,

  • Initialize the CORBA communication.
  • Send commands to the Omc server via the CORBA interface.
  • Receive the string results.
  • Use the Parser module to format the results.
  • Return or display the results.

PySimulator

PySimulator provides a graphical user interface for performing analyses and simulating different model types (currently Functional Mockup Units and Modelica Models are supported), plotting result variables and applying simulation result analysis tools like Fast Fourier Transform.

Read more about the PySimulator at https://github.com/PySimulator/PySimulator.