Skip to content

Commit 65bc221

Browse files
author
Your Name
committed
Updated documentation
1 parent fd5f5c3 commit 65bc221

File tree

10 files changed

+86
-59
lines changed

10 files changed

+86
-59
lines changed

.github/workflows/blank.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
name: Simulink DLL Test
44

5-
# Controls when the action will run.
5+
# Controls when the action will run.
66
on:
77
# Triggers the workflow on push or pull request events but only for the main branch
88
push:
@@ -35,4 +35,4 @@ jobs:
3535
- name: Run pytest
3636
run: |
3737
cd Example2
38-
pytest
38+
pytest

Example1/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@
33
For demonstrating minimal dll functionality and the steps required to run a model in Python.
44

55
![](dllModel.png)
6-

Example1/dllModel.ipynb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"source": [
4747
"class B_dllModel_T(ctypes.Structure):\n",
4848
" \"\"\"Simulink.Parameter SimulinkGlobals\"\"\"\n",
49+
"\n",
4950
" _fields_ = [\n",
5051
" (\"SimulationSignal1\", real_T),\n",
5152
" (\"SignalOut3\", real32_T),\n",
@@ -55,21 +56,25 @@
5556
"\n",
5657
"class ExtU_dllModel_T(ctypes.Structure):\n",
5758
" \"\"\"SimulinkGlobal Inputs to Model\"\"\"\n",
59+
"\n",
5860
" _fields_ = [(\"SignalIin2\", uint16_T)]\n",
5961
"\n",
6062
"\n",
6163
"class ExtY_dllModel_T(ctypes.Structure):\n",
6264
" \"\"\"SimulinkGlobal Outputs from Model\"\"\"\n",
65+
"\n",
6366
" _fields_ = [(\"OutputPort2\", real32_T)]\n",
6467
"\n",
6568
"\n",
6669
"class P_dllModel_T(ctypes.Structure):\n",
6770
" \"\"\"SimulinkGlobal Parameters\"\"\"\n",
71+
"\n",
6872
" _fields_ = [(\"K2\", uint16_T)]\n",
6973
"\n",
7074
"\n",
7175
"class Timing(ctypes.Structure):\n",
7276
" \"\"\" Timing STructure\"\"\"\n",
77+
"\n",
7378
" _fields_ = [\n",
7479
" (\"clockTick0\", uint32_T),\n",
7580
" (\"clockTickH0\", uint32_T),\n",
@@ -78,6 +83,7 @@
7883
"\n",
7984
"class tag_RTM_dllModel_T(ctypes.Structure):\n",
8085
" \"\"\" tag RTM \"\"\"\n",
86+
"\n",
8187
" _fields_ = [\n",
8288
" (\"errorStatus\", ctypes.c_char_p),\n",
8389
" (\"Timing\", Timing),\n",

Example2/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
A simple discrete transfer function. Compiled with a 1st order low pass filter.
66

7-
There are two example notebooks for Example 2.
7+
There are two example notebooks for Example 2.
88

99
1. [Simple Example](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf.ipynb) - A simple low-level ctypes wrapper.
1010
2. [Pythonic Example](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf-python_class.ipynb) - Use Python syntactic sugar to create a high level [TransferTF python](https://github.com/dapperfu/python_SimulinkDLL/blob/master/Example2/discretetf.py) class to interact with the model. Adds datalogging and pandas integration.
1111

1212
Example 2 also contains sample `pytest` tests in the [`tests`](https://github.com/dapperfu/python_SimulinkDLL/tree/master/Example2/tests) directory. This demonstrates how you can use `pytest` to test Simulink models. Sample test results are shown shown in [test_results.md.](test_results.md)
1313

14-
- For the tests example the model shared library is presented to tests as a `pytest` fixture defined in [`conftest.py`](tests/conftest.py)
14+
- For the tests example the model shared library is presented to tests as a `pytest` fixture defined in [`conftest.py`](tests/conftest.py)

Example2/discrete_tf-python_class.ipynb

Lines changed: 40 additions & 40 deletions
Large diffs are not rendered by default.

Example2/discrete_tf.ipynb

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"- Simulate a sine-wave input through the Simulink model & compare it to `python-control` forced response.\n",
1414
"- Configure the model with the transfer function $\\frac{1}{1s+1}$ and plot a step response. Compare the step response to the `python-control` forced-response with the same input.\n",
1515
"\n",
16-
"![](discrete_tf.png)"
16+
"![](discrete_tf.png)\n",
17+
"\n",
18+
"- [Pythonic discrete_tf](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf-python_class.ipynb) Pythonize the code below into a DiscreteTF class, uses additional Python tools like pandas"
1719
]
1820
},
1921
{
@@ -791,7 +793,7 @@
791793
{
792794
"data": {
793795
"text/plain": [
794-
"<matplotlib.collections.LineCollection at 0x7f7cce6f8700>"
796+
"<matplotlib.collections.LineCollection at 0x7fcca96b2880>"
795797
]
796798
},
797799
"execution_count": 18,
@@ -847,6 +849,13 @@
847849
"Using the characteristics of a first order transfer function test that the transfer function matches."
848850
]
849851
},
852+
{
853+
"cell_type": "markdown",
854+
"metadata": {},
855+
"source": [
856+
"Find the index of where the step occurs."
857+
]
858+
},
850859
{
851860
"cell_type": "code",
852861
"execution_count": 19,
@@ -868,6 +877,13 @@
868877
"step_idx"
869878
]
870879
},
880+
{
881+
"cell_type": "markdown",
882+
"metadata": {},
883+
"source": [
884+
"Calculate where the response crosses $63.2\\%$ & $86.4\\%$"
885+
]
886+
},
871887
{
872888
"cell_type": "code",
873889
"execution_count": 20,
@@ -878,6 +894,13 @@
878894
"tau2_idx = np.where(df.output < (1 - np.exp(-2 * tau)))[0][-1]"
879895
]
880896
},
897+
{
898+
"cell_type": "markdown",
899+
"metadata": {},
900+
"source": [
901+
"Subtract off the time of the step and compare to $\\tau$ and $2\\tau$"
902+
]
903+
},
881904
{
882905
"cell_type": "code",
883906
"execution_count": 21,

Example3/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Adapted from [Mathworks's Simulation of a Bouncing Ball](https://www.mathworks.c
44

55
![](bouncing_ball.png)
66

7-
Running a Simulation in Simulink also has some overhead. By compiling the model to a shared library and executing it, this overhead is eliminated.
7+
Running a Simulation in Simulink also has some overhead. By compiling the model to a shared library and executing it, this overhead is eliminated.
88

99
`bouncing_ball_benchmark.m` benchmarks the model by testing increasingly smaller time steps. The model was then compiled and tested in Python and the corresponding times are recorded below.
1010

@@ -13,4 +13,4 @@ Running a Simulation in Simulink also has some overhead. By compiling the model
1313
| 1e-4 | 0.5905 | 0.06 |
1414
| 1e-5 | 1.0461 | 0.61 |
1515
| 1e-6 | 8.1991 | 6.08 |
16-
| 1e-7 | 78.9901 | 60.18 |
16+
| 1e-7 | 78.9901 | 60.18 |

Example3/bouncing_ball.ipynb

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@
2727
"import ctypes\n",
2828
"import os\n",
2929
"\n",
30+
"import matplotlib.pyplot as plt\n",
3031
"import pandas as pd\n",
3132
"from rtwtypes import *\n",
3233
"\n",
33-
"import matplotlib.pyplot as plt\n",
34-
"\n",
3534
"dll_path = os.path.abspath(\"bouncing_ball_win64.dll\")\n",
3635
"dll = ctypes.windll.LoadLibrary(dll_path)\n",
3736
"# Model entry point functions\n",
@@ -103,10 +102,10 @@
103102
"\n",
104103
"df.plot(x=\"time\", y=[\"ball_position\"])\n",
105104
"plt.title(\"Ball Position (m)\")\n",
106-
"plt.grid('on')\n",
105+
"plt.grid(\"on\")\n",
107106
"plt.title(\"Ball Velocity (m/s)\")\n",
108107
"df.plot(x=\"time\", y=[\"ball_velocity\"])\n",
109-
"plt.grid('on')"
108+
"plt.grid(\"on\")"
110109
]
111110
},
112111
{
@@ -157,7 +156,7 @@
157156
"df = pd.DataFrame(rows)\n",
158157
"\n",
159158
"df.plot(x=\"time\", y=[\"ball_position\", \"ball_velocity\"])\n",
160-
"plt.grid('on')"
159+
"plt.grid(\"on\")"
161160
]
162161
},
163162
{
@@ -194,7 +193,7 @@
194193
"df = pd.DataFrame(rows)\n",
195194
"\n",
196195
"df.plot(x=\"time\", y=[\"ball_position\", \"ball_velocity\"])\n",
197-
"plt.grid('on')"
196+
"plt.grid(\"on\")"
198197
]
199198
}
200199
],

Example3/bouncing_ball_benchmark.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
idx=1;
2222
results=zeros(4,10);
2323
for Ts = [1e-4, 1e-5, 1e-6, 1e-7]
24-
24+
2525
for i = 1:10
2626
tic
2727
sim('bouncing_ball', 25)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ For a given library or model configuring the Python should only need done when t
5353

5454
A simple discrete transfer function. Compiled with a 1st order low pass filter.
5555

56-
There are two example notebooks for Example 2.
56+
There are two example notebooks for Example 2.
5757

5858
1. [Simple Example](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf.ipynb) - A simple low-level ctypes wrapper.
5959
2. [Pythonic Example](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf-python_class.ipynb) - Use Python syntactic sugar to create a high level [TransferTF python](https://github.com/dapperfu/python_SimulinkDLL/blob/master/Example2/discretetf.py) class to interact with the model. Adds datalogging and pandas integration.
@@ -72,7 +72,7 @@ Adapted from [Mathworks's Simulation of a Bouncing Ball](https://www.mathworks.c
7272

7373
![](Example3/bouncing_ball.png)
7474

75-
Running a Simulation in Simulink also has some overhead. By compiling the model to a shared library and executing it, this overhead is eliminated.
75+
Running a Simulation in Simulink also has some overhead. By compiling the model to a shared library and executing it, this overhead is eliminated.
7676

7777
`bouncing_ball_benchmark.m` benchmarks the model by testing increasingly smaller time steps. The model was then compiled and tested in Python and the corresponding times are recorded below.
7878

@@ -87,7 +87,7 @@ Running a Simulation in Simulink also has some overhead. By compiling the model
8787

8888
This project also serves as a proof of concept for using [CI/CD devops techniques](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) with Simulink Models. There is a [`Jenkinsfile` ](Jenkinsfile) that will build each of the examples and archive the artifacts:
8989

90-
- shared library (`.dll`)
90+
- shared library (`.dll`)
9191
- header files (`.h`)
9292

9393
Jenkins Pipeline screenshot:

0 commit comments

Comments
 (0)