OpenModelica
License
https://openmodelica.org/useresresources/license/
- GNU AGPL Version 3.0
Installation on Linux/Ubuntu
https://openmodelica.org/download/download-linux/
sudo apt-get update sudo apt-get install ca-certificates curl gnupg
sudo curl -fsSL http://build.openmodelica.org/apt/openmodelica.asc | sudo gpg --dearmor -o /usr/share/keyrings/openmodelica-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/openmodelica-keyring.gpg] \ https://build.openmodelica.org/apt \ $(cat /etc/os-release | grep "\(UBUNTU\\|DEBIAN\\|VERSION\)_CODENAME" | sort | cut -d= -f 2 | head -1) \ stable" | sudo tee /etc/apt/sources.list.d/openmodelica.list
sudo apt update sudo apt install openmodelica
Python Interface: OMPython
https://github.com/OpenModelica/OMPython
https://qiita.com/US3/items/528aba504065e3745aa8
pip install --upgrade OMPython
Tutorials
https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/ompython.html
git clone https://github.com/OpenModelica/OpenModelica
BouncingBall by OMPython
python
import pandas as pd import matplotlib import matplotlib.pyplot as plt
from OMPython import OMCSessionZMQ omc = OMCSessionZMQ()
omc.sendExpression("getVersion()")
## 'OpenModelica 1.23.1'
omc.sendExpression("installPackage(Modelica)") omc.sendExpression("loadModel(Modelica)") omc.sendExpression("loadFile(\"./OpenModelica/OMCompiler/Examples/BouncingBall.mo\")")
## True
omc.sendExpression("getClassNames()")
## ('BouncingBall', 'ModelicaServices', 'Complex', 'Modelica')
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, fixed = true) "height of ball"; ## Real v(fixed = true) "velocity of ball"; ## Boolean flying(start = true, fixed = true) "true, if ball is flying"; ## Boolean impact; ## Real v_new(fixed = true); ## 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;
omc.sendExpression("simulate(BouncingBall, stopTime=3.0, outputFormat=\"csv\")")
## { ## 'resultFile': 'BouncingBall_res.csv', ## 'simulationOptions': "startTime = 0.0, stopTime = 3.0, numberOfIntervals = 500, tolerance = 1e-6, method = 'dassl', ## fileNamePrefix = 'BouncingBall', options = '', outputFormat = 'csv', variableFilter = '.*', cflags = '', simflags = ''", ## 'messages': 'LOG_SUCCESS | info | The initialization finished successfully without homotopy method.\n ## LOG_SUCCESS | info | The simulation finished successfully.\n', ## 'timeFrontend': 0.067590884, ## 'timeBackend': 0.023814135, ## 'timeSimCode': 0.004248845, ## 'timeTemplates': 0.007150218000000001, ## 'timeCompile': 1.506673157, ## 'timeSimulation': 0.035231169, ## 'timeTotal': 1.6510822539999999 ## }
df = pd.read_csv("BouncingBall_res.csv") df
## time h v der(h) der(v) v_new foo flying impact ## 0 0.000 1.000000e+00 0.00000 0.00000 -9.81 0.0 2 1 0 ## 1 0.006 9.998234e-01 -0.05886 -0.05886 -9.81 0.0 2 1 0 ## 2 0.012 9.992937e-01 -0.11772 -0.11772 -9.81 0.0 2 1 0 ## 3 0.018 9.984108e-01 -0.17658 -0.17658 -9.81 0.0 2 1 0 ## 4 0.024 9.971747e-01 -0.23544 -0.23544 -9.81 0.0 2 1 0 ## .. ... ... ... ... ... ... ... ... ... ## 687 2.982 2.101988e-11 0.00000 0.00000 0.00 0.0 1 0 1 ## 688 2.988 2.101988e-11 0.00000 0.00000 0.00 0.0 1 0 1 ## 689 2.994 2.101988e-11 0.00000 0.00000 0.00 0.0 1 0 1 ## 690 3.000 2.101988e-11 0.00000 0.00000 0.00 0.0 1 0 1 ## 691 3.000 2.101988e-11 0.00000 0.00000 0.00 0.0 1 0 1 ## ## [692 rows x 9 columns]
df.plot(x="time", y="h") plt.savefig("BouncingBall_res.png", bbox_inches='tight')
Information - How to Debug
## Getting error messages of the previous command omc.sendExpression("getErrorString()")
## '[<interactive>:1:1-1:0:writable] Error: Class getDummyError not found in scope <global scope> (looking for a function or record).\n'
Calling External C Functions
https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/interop_c_python.html
## TCP Server in Python vi getValue.py ================================ import socket HOST = '127.0.0.1' PORT = 12345 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s : s.bind((HOST, PORT)) s.listen() print(f"Listening on {HOST}:{PORT}") while True : conn, addr = s.accept() with conn : print('Connected by', addr) while True : data = conn.recv(1024) if not data : break print('Received', data.decode('utf-8')) print('Connection closed by', addr) ================================
python getValue.py
## TCP Client in C vi sendValue.c ================================ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <sys/socket.h> #include <unistd.h> #include "sendValue.h" int sendValue(const char *server_ip, int server_port, float value) { int sockfd; struct sockaddr_in server_addr; char message[64]; snprintf(message, sizeof(message), "%f", value); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket creation failed"); return -1; } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(server_port); if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) { perror("Invalid address"); close(sockfd); return -1; } if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("Connection failed"); close(sockfd); return -1; } if (send(sockfd, message, strlen(message), 0) < 0) { perror("Send failed"); close(sockfd); return -1; } printf("Message sent: %s\n", message); close(sockfd); return 0; } ================================
vi sendValue.h ================================ #ifndef SENDVALUE_H #define SENDVALUE_H int sendValue(const char *server_ip, int server_port, float value); #endif ================================
gcc -c -o sendValue.o sendValue.c
## Calling external C function sendValue() every 1 second vi BouncingBall.mo ================================ model BouncingBall parameter Real e=0.7 "coefficient of restitution"; parameter Real g=9.81 "gravity acceleration"; Real h(fixed=true, start=1) "height of ball"; Real v(fixed=true) "velocity of ball"; Boolean flying(fixed=true, start=true) "true, if ball is flying"; Boolean impact; Real v_new(fixed=true); Integer foo; Clock c = Clock(1); function sendValue input String server_ip = "127.0.0.1"; input Integer server_port = 12345; input Real value = 0.0; external "C" sendValue(server_ip, server_port, value) annotation(Include="#include \"sendValue.h\"", Library="sendValue.o"); end sendValue; equation impact = h <= 0.0; foo = if impact then 1 else 2; der(v) = if flying then -g else 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; flying = v_new > 0; reinit(v, v_new); end when; when {sample(0, 1)} then sendValue("127.0.0.1", 12345, h); end when; end BouncingBall; ================================
python
from OMPython import OMCSessionZMQ omc = OMCSessionZMQ() omc.sendExpression("loadFile(\"./BouncingBall.mo\")") omc.sendExpression("simulate(BouncingBall, stopTime=3.0, outputFormat=\"csv\")")
## { ## 'resultFile': 'BouncingBall_res.csv', ## 'simulationOptions': "startTime = 0.0, stopTime = 3.0, numberOfIntervals = 500, tolerance = 1e-6, method = 'dassl', ## fileNamePrefix = 'BouncingBall', options = '', outputFormat = 'csv', variableFilter = '.*', cflags = '', simflags = ''", ## 'messages': 'LOG_SUCCESS | info | The initialization finished successfully without homotopy method.\n ## Message sent: 1.000000\n ## Message sent: 0.225060\n ## Message sent: 0.042434\n ## Message sent: 0.000000\n ## LOG_SUCCESS | info | The simulation finished successfully.\n', ## 'timeFrontend': 0.002844552, ## 'timeBackend': 0.005307907000000001, ## 'timeSimCode': 0.0059751560000000006, ## 'timeTemplates': 0.008850144, ## 'timeCompile': 1.118291402, ## 'timeSimulation': 0.018550764, ## 'timeTotal': 1.159920236 ## }
## ===== Data received by getValue.py ===== ## Listening on 127.0.0.1:12345 ## Connected by ('127.0.0.1', 52362) ## Received 1.000000 ## Connection closed by ('127.0.0.1', 52362) ## Connected by ('127.0.0.1', 52376) ## Received 0.225060 ## Connection closed by ('127.0.0.1', 52376) ## Connected by ('127.0.0.1', 52386) ## Received 0.042434 ## Connection closed by ('127.0.0.1', 52386) ## Connected by ('127.0.0.1', 52402) ## Received 0.000000 ## Connection closed by ('127.0.0.1', 52402)
References
OpenModelica
https://openmodelica.org/
Acknowledgments
Daiphys is a professional-service company for research and development of leading-edge technologies in science and engineering.
Get started accelerating your business through our deep expertise in R&D with AI, quantum computing, and space development; please get in touch with Daiphys today!
Daiphys Technologies LLC - https://www.daiphys.com/