├── .github └── workflows │ └── blank.yml ├── .gitignore ├── .pre-commit-config.yaml ├── Example1 ├── README.md ├── dllModel.ipynb ├── dllModel.png ├── dllModel.slx ├── dllModel_Solver.png ├── dllModel_build.m ├── dllModel_ert_shrlib_rtw │ ├── codedescriptor.dmr │ ├── defines.txt │ ├── dllModel.bat │ ├── dllModel.c │ ├── dllModel.def │ ├── dllModel.h │ ├── dllModel.mk │ ├── dllModel.obj │ ├── dllModel.rsp │ ├── dllModel_comp.rsp │ ├── dllModel_data.c │ ├── dllModel_data.obj │ ├── dllModel_private.h │ ├── dllModel_ref.rsp │ ├── dllModel_types.h │ ├── ert_main.c │ ├── modelsources.txt │ ├── rtw_proj.tmw │ └── rtwtypes.h ├── dllModel_init.m ├── dllModel_win64.dll ├── dllModel_win64.lib └── rtwtypes.py ├── Example2 ├── README.md ├── discrete_tf-python_class.ipynb ├── discrete_tf.ipynb ├── discrete_tf.mdl ├── discrete_tf.png ├── discrete_tf.so ├── discrete_tf_build.m ├── discrete_tf_ert_shrlib_rtw │ ├── codedescriptor.dmr │ ├── defines.txt │ ├── discrete_tf.bat │ ├── discrete_tf.c │ ├── discrete_tf.def │ ├── discrete_tf.h │ ├── discrete_tf.mk │ ├── discrete_tf.obj │ ├── discrete_tf.rsp │ ├── discrete_tf_comp.rsp │ ├── discrete_tf_private.h │ ├── discrete_tf_ref.rsp │ ├── discrete_tf_types.h │ ├── ert_main.c │ ├── modelsources.txt │ ├── rtw_proj.tmw │ └── rtwtypes.h ├── discrete_tf_files │ ├── discrete_tf_15_1.png │ ├── discrete_tf_18_1.png │ ├── discrete_tf_19_1.png │ ├── discrete_tf_23_1.png │ ├── discrete_tf_24_1.png │ └── discrete_tf_27_1.png ├── discrete_tf_init.m ├── discrete_tf_step.png ├── discrete_tf_win64.dll ├── discrete_tf_win64.lib ├── discretetf.py ├── rtwtypes.py ├── step_response.png ├── test_results.md └── tests │ ├── conftest.py │ ├── discretetf.py │ ├── rtwtypes.py │ └── test_01.py ├── Example3 ├── README.md ├── bouncing_ball.ipynb ├── bouncing_ball.png ├── bouncing_ball.slx ├── bouncing_ball_benchmark.m ├── bouncing_ball_build.m ├── bouncing_ball_ert_shrlib_rtw │ ├── bouncing_ball.bat │ ├── bouncing_ball.c │ ├── bouncing_ball.def │ ├── bouncing_ball.h │ ├── bouncing_ball.mk │ ├── bouncing_ball.obj │ ├── bouncing_ball.rsp │ ├── bouncing_ball_comp.rsp │ ├── bouncing_ball_private.h │ ├── bouncing_ball_ref.rsp │ ├── bouncing_ball_types.h │ ├── codedescriptor.dmr │ ├── defines.txt │ ├── ert_main.c │ ├── html │ │ ├── bouncing_ball_c.html │ │ ├── bouncing_ball_codegen_rpt.html │ │ ├── bouncing_ball_coderassumptions.html │ │ ├── bouncing_ball_contents.html │ │ ├── bouncing_ball_h.html │ │ ├── bouncing_ball_interface.html │ │ ├── bouncing_ball_metrics.html │ │ ├── bouncing_ball_private_h.html │ │ ├── bouncing_ball_replacements.html │ │ ├── bouncing_ball_subsystems.html │ │ ├── bouncing_ball_survey.html │ │ ├── bouncing_ball_trace.html │ │ ├── bouncing_ball_traceInfo.js │ │ ├── bouncing_ball_types_h.html │ │ ├── css │ │ │ └── coder_app.css │ │ ├── define.js │ │ ├── ert_main_c.html │ │ ├── hilite_warning.png │ │ ├── inspect.html │ │ ├── js │ │ │ └── coder_app.js │ │ ├── nav.html │ │ ├── navToolbar.html │ │ ├── rtwhilite.js │ │ ├── rtwmsg.html │ │ ├── rtwreport.css │ │ ├── rtwreport_utils.js │ │ ├── rtwshrink.js │ │ ├── rtwtypes_h.html │ │ ├── search.js │ │ ├── spinner.gif │ │ └── traceInfo_flag.js │ ├── modelsources.txt │ ├── rtw_proj.tmw │ └── rtwtypes.h ├── bouncing_ball_files │ ├── bouncing_ball_4_1.png │ ├── bouncing_ball_4_2.png │ ├── bouncing_ball_7_1.png │ └── bouncing_ball_8_1.png ├── bouncing_ball_init.m ├── bouncing_ball_win64.dll ├── bouncing_ball_win64.lib ├── rtwtypes.py └── sldemo_bounceExample_02.png ├── GitHub_Actions.png ├── Jenkinsfile ├── LICENSE ├── README.md ├── jenkins_artifacts.png └── jenkins_pipeline.png /.github/workflows/blank.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Simulink DLL Test 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the main branch 8 | push: 9 | branches: [ main ] 10 | pull_request: 11 | branches: [ main ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | - name: Set up Python 3.8 28 | uses: actions/setup-python@v2 29 | with: 30 | python-version: 3.8 31 | - name: Install dependencies 32 | run: | 33 | python -m pip install --upgrade pip 34 | python -m pip install control pytest pandas numpy 35 | - name: Run pytest 36 | run: | 37 | cd Example2 38 | pytest 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | MinGW/ 2 | castxml/ 3 | DevelopmentScratch/ 4 | 5 | *.mat 6 | *.slxc 7 | *.o 8 | # Byte-compiled / optimized / DLL files 9 | __pycache__/ 10 | *.py[cod] 11 | *$py.class 12 | 13 | # C extensions 14 | *.so 15 | 16 | # Distribution / packaging 17 | .Python 18 | env/ 19 | build/ 20 | develop-eggs/ 21 | dist/ 22 | downloads/ 23 | eggs/ 24 | .eggs/ 25 | lib/ 26 | lib64/ 27 | parts/ 28 | sdist/ 29 | var/ 30 | wheels/ 31 | *.egg-info/ 32 | .installed.cfg 33 | *.egg 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | .hypothesis/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # pyenv 81 | .python-version 82 | 83 | # celery beat schedule file 84 | celerybeat-schedule 85 | 86 | # SageMath parsed files 87 | *.sage.py 88 | 89 | # dotenv 90 | .env 91 | 92 | # virtualenv 93 | .venv 94 | venv/ 95 | ENV/ 96 | 97 | # Spyder project settings 98 | .spyderproject 99 | .spyproject 100 | 101 | # Rope project settings 102 | .ropeproject 103 | 104 | # mkdocs documentation 105 | /site 106 | 107 | # mypy 108 | .mypy_cache/ 109 | 110 | **/castxml/* 111 | **/dllModel/* 112 | **/slprj/** 113 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: master 4 | hooks: 5 | - id: trailing-whitespace 6 | - id: end-of-file-fixer 7 | - id: check-yaml 8 | - id: debug-statements 9 | - id: requirements-txt-fixer 10 | - repo: https://github.com/psf/black 11 | rev: master 12 | hooks: 13 | - id: black 14 | args: [--target-version=py37] 15 | - repo: https://github.com/asottile/reorder_python_imports 16 | rev: master 17 | hooks: 18 | - id: reorder-python-imports 19 | args: [--py37-plus] 20 | - repo: https://github.com/asottile/pyupgrade 21 | rev: master 22 | hooks: 23 | - id: pyupgrade 24 | args: [--py37-plus] 25 | - repo: https://github.com/nbQA-dev/nbQA 26 | rev: 0.5.9 27 | hooks: 28 | - id: nbqa-black 29 | additional_dependencies: [black==20.8b1] 30 | args: [--nbqa-mutate] 31 | - id: nbqa-pyupgrade 32 | additional_dependencies: [pyupgrade==2.10.0] 33 | args: [--nbqa-mutate, --py36-plus] 34 | - id: nbqa-isort 35 | additional_dependencies: [isort==5.7.0] 36 | args: [--nbqa-mutate] 37 | -------------------------------------------------------------------------------- /Example1/README.md: -------------------------------------------------------------------------------- 1 | ### Example 1: [dllModel.ipynb](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example1/dllModel.ipynb) 2 | 3 | For demonstrating minimal dll functionality and the steps required to run a model in Python. 4 | 5 | ![](dllModel.png) 6 | -------------------------------------------------------------------------------- /Example1/dllModel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel.png -------------------------------------------------------------------------------- /Example1/dllModel.slx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel.slx -------------------------------------------------------------------------------- /Example1/dllModel_Solver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_Solver.png -------------------------------------------------------------------------------- /Example1/dllModel_build.m: -------------------------------------------------------------------------------- 1 | %% Model Builder 2 | 3 | % Close all models. 4 | bdclose('all'); 5 | % Clear matlab environment. 6 | clear; 7 | % Determine model name from the build script name 8 | model = strtok(mfilename, '_'); 9 | % Run the model init script. 10 | feval([model '_init']); 11 | % Open the model. 12 | open_system(model); 13 | % 14 | rtwbuild(model); 15 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/codedescriptor.dmr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_ert_shrlib_rtw/codedescriptor.dmr -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/defines.txt: -------------------------------------------------------------------------------- 1 | MODEL=dllModel 2 | NUMST=1 3 | NCSTATES=0 4 | HAVESTDIO 5 | MODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 6 | CLASSIC_INTERFACE=0 7 | ALLOCATIONFCN=0 8 | TID01EQ=0 9 | TERMFCN=1 10 | ONESTEPFCN=1 11 | MAT_FILE=0 12 | MULTI_INSTANCE_CODE=0 13 | INTEGER_CODE=0 14 | MT=0 15 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel.bat: -------------------------------------------------------------------------------- 1 | @if not "%MINGW_ROOT%" == "" (@set "PATH=%PATH%;%MINGW_ROOT%") 2 | 3 | cd . 4 | 5 | if "%1"=="" ("C:\R2018b\bin\win64\gmake" -f dllModel.mk all) else ("C:\R2018b\bin\win64\gmake" -f dllModel.mk %1) 6 | @if errorlevel 1 goto error_exit 7 | 8 | exit /B 0 9 | 10 | :error_exit 11 | echo The make command returned an error of %errorlevel% 12 | An_error_occurred_during_the_call_to_make 13 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dllModel.c 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #include "dllModel.h" 17 | #include "dllModel_private.h" 18 | 19 | /* Exported block signals */ 20 | real32_T SignalIn; /* '/InputPort1' */ 21 | real_T SimulationSignal2; /* '/Gain2' */ 22 | real32_T SignalOut; /* '/Gain' */ 23 | 24 | /* Exported block parameters */ 25 | real32_T K = 1.0F; /* Variable: K 26 | * Referenced by: '/Gain' 27 | */ 28 | 29 | /* Block signals (default storage) */ 30 | B_dllModel_T dllModel_B; 31 | 32 | /* External inputs (root inport signals with default storage) */ 33 | ExtU_dllModel_T dllModel_U; 34 | 35 | /* External outputs (root outports fed by signals with default storage) */ 36 | ExtY_dllModel_T dllModel_Y; 37 | 38 | /* Real-time model */ 39 | RT_MODEL_dllModel_T dllModel_M_; 40 | RT_MODEL_dllModel_T *const dllModel_M = &dllModel_M_; 41 | 42 | /* Model step function */ 43 | void dllModel_step(void) 44 | { 45 | /* Gain: '/Gain' incorporates: 46 | * Inport: '/InputPort1' 47 | */ 48 | SignalOut = K * SignalIn; 49 | 50 | /* Gain: '/Gain1' incorporates: 51 | * Inport: '/InputPort2' 52 | */ 53 | dllModel_B.SignalOut2 = (uint16_T)(((uint32_T)dllModel_P.K2 * 54 | dllModel_U.SignalIn2) >> 14); 55 | 56 | /* Sum: '/Sum' */ 57 | dllModel_B.SignalOut3 = SignalOut + (real32_T)dllModel_B.SignalOut2; 58 | 59 | /* Outport: '/OutputPort2' */ 60 | dllModel_Y.OutputPort2 = dllModel_B.SignalOut3; 61 | 62 | /* DigitalClock: '/Digital Clock' */ 63 | dllModel_B.SimulationSignal1 = (((dllModel_M->Timing.clockTick0+ 64 | dllModel_M->Timing.clockTickH0* 4294967296.0)) * 0.1); 65 | 66 | /* Gain: '/Gain2' */ 67 | SimulationSignal2 = 1.0 * dllModel_B.SimulationSignal1; 68 | 69 | /* Update absolute time for base rate */ 70 | /* The "clockTick0" counts the number of times the code of this task has 71 | * been executed. The resolution of this integer timer is 0.1, which is the step size 72 | * of the task. Size of "clockTick0" ensures timer will not overflow during the 73 | * application lifespan selected. 74 | * Timer of this task consists of two 32 bit unsigned integers. 75 | * The two integers represent the low bits Timing.clockTick0 and the high bits 76 | * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment. 77 | */ 78 | dllModel_M->Timing.clockTick0++; 79 | if (!dllModel_M->Timing.clockTick0) { 80 | dllModel_M->Timing.clockTickH0++; 81 | } 82 | } 83 | 84 | /* Model initialize function */ 85 | void dllModel_initialize(void) 86 | { 87 | /* Registration code */ 88 | 89 | /* initialize real-time model */ 90 | (void) memset((void *)dllModel_M, 0, 91 | sizeof(RT_MODEL_dllModel_T)); 92 | 93 | /* block I/O */ 94 | (void) memset(((void *) &dllModel_B), 0, 95 | sizeof(B_dllModel_T)); 96 | 97 | /* exported global signals */ 98 | SimulationSignal2 = 0.0; 99 | SignalOut = 0.0F; 100 | 101 | /* external inputs */ 102 | SignalIn = 0.0F; 103 | dllModel_U.SignalIn2 = 0U; 104 | 105 | /* external outputs */ 106 | (void) memset((void *)&dllModel_Y, 0, 107 | sizeof(ExtY_dllModel_T)); 108 | } 109 | 110 | /* Model terminate function */ 111 | void dllModel_terminate(void) 112 | { 113 | /* (no terminate code required) */ 114 | } 115 | 116 | /* 117 | * File trailer for generated code. 118 | * 119 | * [EOF] 120 | */ 121 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | dllModel_M_ 3 | dllModel_M 4 | dllModel_U 5 | dllModel_Y 6 | dllModel_initialize 7 | dllModel_step 8 | dllModel_terminate 9 | 10 | 11 | SignalIn 12 | SimulationSignal2 13 | SignalOut 14 | K 15 | dllModel_P 16 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dllModel.h 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTW_HEADER_dllModel_h_ 17 | #define RTW_HEADER_dllModel_h_ 18 | #include 19 | #ifndef dllModel_COMMON_INCLUDES_ 20 | # define dllModel_COMMON_INCLUDES_ 21 | #include "rtwtypes.h" 22 | #endif /* dllModel_COMMON_INCLUDES_ */ 23 | 24 | #include "dllModel_types.h" 25 | 26 | /* Macros for accessing real-time model data structure */ 27 | #ifndef rtmGetErrorStatus 28 | # define rtmGetErrorStatus(rtm) ((rtm)->errorStatus) 29 | #endif 30 | 31 | #ifndef rtmSetErrorStatus 32 | # define rtmSetErrorStatus(rtm, val) ((rtm)->errorStatus = (val)) 33 | #endif 34 | 35 | /* Block signals (default storage) */ 36 | typedef struct { 37 | real_T SimulationSignal1; /* '/Digital Clock' */ 38 | real32_T SignalOut3; /* '/Sum' */ 39 | uint16_T SignalOut2; /* '/Gain1' */ 40 | } B_dllModel_T; 41 | 42 | /* External inputs (root inport signals with default storage) */ 43 | typedef struct { 44 | uint16_T SignalIn2; /* '/InputPort2' */ 45 | } ExtU_dllModel_T; 46 | 47 | /* External outputs (root outports fed by signals with default storage) */ 48 | typedef struct { 49 | real32_T OutputPort2; /* '/OutputPort2' */ 50 | } ExtY_dllModel_T; 51 | 52 | /* Parameters (default storage) */ 53 | struct P_dllModel_T_ { 54 | uint16_T K2; /* Variable: K2 55 | * Referenced by: '/Gain1' 56 | */ 57 | }; 58 | 59 | /* Real-time Model Data Structure */ 60 | struct tag_RTM_dllModel_T { 61 | const char_T * volatile errorStatus; 62 | 63 | /* 64 | * Timing: 65 | * The following substructure contains information regarding 66 | * the timing information for the model. 67 | */ 68 | struct { 69 | uint32_T clockTick0; 70 | uint32_T clockTickH0; 71 | } Timing; 72 | }; 73 | 74 | /* Block parameters (default storage) */ 75 | extern P_dllModel_T dllModel_P; 76 | 77 | /* Block signals (default storage) */ 78 | extern B_dllModel_T dllModel_B; 79 | 80 | /* External inputs (root inport signals with default storage) */ 81 | extern ExtU_dllModel_T dllModel_U; 82 | 83 | /* External outputs (root outports fed by signals with default storage) */ 84 | extern ExtY_dllModel_T dllModel_Y; 85 | 86 | /* 87 | * Exported Global Signals 88 | * 89 | * Note: Exported global signals are block signals with an exported global 90 | * storage class designation. Code generation will declare the memory for 91 | * these signals and export their symbols. 92 | * 93 | */ 94 | extern real32_T SignalIn; /* '/InputPort1' */ 95 | extern real_T SimulationSignal2; /* '/Gain2' */ 96 | extern real32_T SignalOut; /* '/Gain' */ 97 | 98 | /* 99 | * Exported Global Parameters 100 | * 101 | * Note: Exported global parameters are tunable parameters with an exported 102 | * global storage class designation. Code generation will declare the memory for 103 | * these parameters and exports their symbols. 104 | * 105 | */ 106 | extern real32_T K; /* Variable: K 107 | * Referenced by: '/Gain' 108 | */ 109 | 110 | /* Model entry point functions */ 111 | extern void dllModel_initialize(void); 112 | extern void dllModel_step(void); 113 | extern void dllModel_terminate(void); 114 | 115 | /* Real-time Model object */ 116 | extern RT_MODEL_dllModel_T *const dllModel_M; 117 | 118 | /*- 119 | * The generated code includes comments that allow you to trace directly 120 | * back to the appropriate location in the model. The basic format 121 | * is /block_name, where system is the system number (uniquely 122 | * assigned by Simulink) and block_name is the name of the block. 123 | * 124 | * Use the MATLAB hilite_system command to trace the generated code back 125 | * to the model. For example, 126 | * 127 | * hilite_system('') - opens system 3 128 | * hilite_system('/Kp') - opens and selects block Kp which resides in S3 129 | * 130 | * Here is the system hierarchy for this model 131 | * 132 | * '' : 'dllModel' 133 | */ 134 | #endif /* RTW_HEADER_dllModel_h_ */ 135 | 136 | /* 137 | * File trailer for generated code. 138 | * 139 | * [EOF] 140 | */ 141 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_ert_shrlib_rtw/dllModel.obj -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel.rsp: -------------------------------------------------------------------------------- 1 | dllModel.obj 2 | dllModel_data.obj 3 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel_comp.rsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_ert_shrlib_rtw/dllModel_comp.rsp -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dllModel_data.c 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #include "dllModel.h" 17 | #include "dllModel_private.h" 18 | 19 | /* Block parameters (default storage) */ 20 | P_dllModel_T dllModel_P = { 21 | /* Variable: K2 22 | * Referenced by: '/Gain1' 23 | */ 24 | 32768U 25 | }; 26 | 27 | /* 28 | * File trailer for generated code. 29 | * 30 | * [EOF] 31 | */ 32 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel_data.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_ert_shrlib_rtw/dllModel_data.obj -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dllModel_private.h 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTW_HEADER_dllModel_private_h_ 17 | #define RTW_HEADER_dllModel_private_h_ 18 | #include "rtwtypes.h" 19 | #ifndef UCHAR_MAX 20 | #include 21 | #endif 22 | 23 | #if ( UCHAR_MAX != (0xFFU) ) || ( SCHAR_MAX != (0x7F) ) 24 | #error Code was generated for compiler with different sized uchar/char. \ 25 | Consider adjusting Test hardware word size settings on the \ 26 | Hardware Implementation pane to match your compiler word sizes as \ 27 | defined in limits.h of the compiler. Alternatively, you can \ 28 | select the Test hardware is the same as production hardware option and \ 29 | select the Enable portable word sizes option on the Code Generation > \ 30 | Verification pane for ERT based targets, which will disable the \ 31 | preprocessor word size checks. 32 | #endif 33 | 34 | #if ( USHRT_MAX != (0xFFFFU) ) || ( SHRT_MAX != (0x7FFF) ) 35 | #error Code was generated for compiler with different sized ushort/short. \ 36 | Consider adjusting Test hardware word size settings on the \ 37 | Hardware Implementation pane to match your compiler word sizes as \ 38 | defined in limits.h of the compiler. Alternatively, you can \ 39 | select the Test hardware is the same as production hardware option and \ 40 | select the Enable portable word sizes option on the Code Generation > \ 41 | Verification pane for ERT based targets, which will disable the \ 42 | preprocessor word size checks. 43 | #endif 44 | 45 | #if ( UINT_MAX != (0xFFFFFFFFU) ) || ( INT_MAX != (0x7FFFFFFF) ) 46 | #error Code was generated for compiler with different sized uint/int. \ 47 | Consider adjusting Test hardware word size settings on the \ 48 | Hardware Implementation pane to match your compiler word sizes as \ 49 | defined in limits.h of the compiler. Alternatively, you can \ 50 | select the Test hardware is the same as production hardware option and \ 51 | select the Enable portable word sizes option on the Code Generation > \ 52 | Verification pane for ERT based targets, which will disable the \ 53 | preprocessor word size checks. 54 | #endif 55 | 56 | #if ( ULONG_MAX != (0xFFFFFFFFU) ) || ( LONG_MAX != (0x7FFFFFFF) ) 57 | #error Code was generated for compiler with different sized ulong/long. \ 58 | Consider adjusting Test hardware word size settings on the \ 59 | Hardware Implementation pane to match your compiler word sizes as \ 60 | defined in limits.h of the compiler. Alternatively, you can \ 61 | select the Test hardware is the same as production hardware option and \ 62 | select the Enable portable word sizes option on the Code Generation > \ 63 | Verification pane for ERT based targets, which will disable the \ 64 | preprocessor word size checks. 65 | #endif 66 | 67 | /* Skipping ulong_long/long_long check: insufficient preprocessor integer range. */ 68 | #endif /* RTW_HEADER_dllModel_private_h_ */ 69 | 70 | /* 71 | * File trailer for generated code. 72 | * 73 | * [EOF] 74 | */ 75 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel_ref.rsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_ert_shrlib_rtw/dllModel_ref.rsp -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/dllModel_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: dllModel_types.h 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTW_HEADER_dllModel_types_h_ 17 | #define RTW_HEADER_dllModel_types_h_ 18 | #include "rtwtypes.h" 19 | 20 | /* Parameters (default storage) */ 21 | typedef struct P_dllModel_T_ P_dllModel_T; 22 | 23 | /* Forward declaration for rtModel */ 24 | typedef struct tag_RTM_dllModel_T RT_MODEL_dllModel_T; 25 | 26 | #endif /* RTW_HEADER_dllModel_types_h_ */ 27 | 28 | /* 29 | * File trailer for generated code. 30 | * 31 | * [EOF] 32 | */ 33 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/ert_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: ert_main.c 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #include 17 | #include /* This ert_main.c example uses printf/fflush */ 18 | #include "dllModel.h" /* Model's header file */ 19 | #include "rtwtypes.h" 20 | 21 | /* 22 | * Associating rt_OneStep with a real-time clock or interrupt service routine 23 | * is what makes the generated code "real-time". The function rt_OneStep is 24 | * always associated with the base rate of the model. Subrates are managed 25 | * by the base rate from inside the generated code. Enabling/disabling 26 | * interrupts and floating point context switches are target specific. This 27 | * example code indicates where these should take place relative to executing 28 | * the generated code step function. Overrun behavior should be tailored to 29 | * your application needs. This example simply sets an error status in the 30 | * real-time model and returns from rt_OneStep. 31 | */ 32 | void rt_OneStep(void); 33 | void rt_OneStep(void) 34 | { 35 | static boolean_T OverrunFlag = false; 36 | 37 | /* Disable interrupts here */ 38 | 39 | /* Check for overrun */ 40 | if (OverrunFlag) { 41 | rtmSetErrorStatus(dllModel_M, "Overrun"); 42 | return; 43 | } 44 | 45 | OverrunFlag = true; 46 | 47 | /* Save FPU context here (if necessary) */ 48 | /* Re-enable timer or interrupt here */ 49 | /* Set model inputs here */ 50 | 51 | /* Step the model */ 52 | dllModel_step(); 53 | 54 | /* Get model outputs here */ 55 | 56 | /* Indicate task complete */ 57 | OverrunFlag = false; 58 | 59 | /* Disable interrupts here */ 60 | /* Restore FPU context here (if necessary) */ 61 | /* Enable interrupts here */ 62 | } 63 | 64 | /* 65 | * The example "main" function illustrates what is required by your 66 | * application code to initialize, execute, and terminate the generated code. 67 | * Attaching rt_OneStep to a real-time clock is target specific. This example 68 | * illustrates how you do this relative to initializing the model. 69 | */ 70 | int_T main(int_T argc, const char *argv[]) 71 | { 72 | /* Unused arguments */ 73 | (void)(argc); 74 | (void)(argv); 75 | 76 | /* Initialize model */ 77 | dllModel_initialize(); 78 | 79 | /* Attach rt_OneStep to a timer or interrupt service routine with 80 | * period 0.1 seconds (the model's base sample time) here. The 81 | * call syntax for rt_OneStep is 82 | * 83 | * rt_OneStep(); 84 | */ 85 | printf("Warning: The simulation will run forever. " 86 | "Generated ERT main won't simulate model step behavior. " 87 | "To change this behavior select the 'MAT-file logging' option.\n"); 88 | fflush((NULL)); 89 | while (rtmGetErrorStatus(dllModel_M) == (NULL)) { 90 | /* Perform other application tasks here */ 91 | } 92 | 93 | /* Disable rt_OneStep() here */ 94 | 95 | /* Terminate model */ 96 | dllModel_terminate(); 97 | return 0; 98 | } 99 | 100 | /* 101 | * File trailer for generated code. 102 | * 103 | * [EOF] 104 | */ 105 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/modelsources.txt: -------------------------------------------------------------------------------- 1 | dllModel.c 2 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/rtw_proj.tmw: -------------------------------------------------------------------------------- 1 | Simulink Coder project for dllModel using . MATLAB root = C:\R2018b. SimStruct date: 24-Jul-2018 19:01:04 2 | This file is generated by Simulink Coder for use by the make utility 3 | to determine when to rebuild objects when the name of the current Simulink Coder project changes. 4 | The rtwinfomat located at: ..\slprj\ert_shrlib\dllModel\tmwinternal\binfo.mat 5 | -------------------------------------------------------------------------------- /Example1/dllModel_ert_shrlib_rtw/rtwtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: rtwtypes.h 3 | * 4 | * Code generated for Simulink model 'dllModel'. 5 | * 6 | * Model version : 1.66 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 10:54:34 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTWTYPES_H 17 | #define RTWTYPES_H 18 | 19 | /* Logical type definitions */ 20 | #if (!defined(__cplusplus)) 21 | # ifndef false 22 | # define false (0U) 23 | # endif 24 | 25 | # ifndef true 26 | # define true (1U) 27 | # endif 28 | #endif 29 | 30 | /*=======================================================================* 31 | * Target hardware information 32 | * Device type: MATLAB Host 33 | * Number of bits: char: 8 short: 16 int: 32 34 | * long: 32 long long: 64 35 | * native word size: 64 36 | * Byte ordering: LittleEndian 37 | * Signed integer division rounds to: Zero 38 | * Shift right on a signed integer as arithmetic shift: on 39 | *=======================================================================*/ 40 | 41 | /*=======================================================================* 42 | * Fixed width word size data types: * 43 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 44 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 45 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 46 | *=======================================================================*/ 47 | typedef signed char int8_T; 48 | typedef unsigned char uint8_T; 49 | typedef short int16_T; 50 | typedef unsigned short uint16_T; 51 | typedef int int32_T; 52 | typedef unsigned int uint32_T; 53 | typedef long long int64_T; 54 | typedef unsigned long long uint64_T; 55 | typedef float real32_T; 56 | typedef double real64_T; 57 | 58 | /*===========================================================================* 59 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 60 | * real_T, time_T, ulong_T, ulonglong_T. * 61 | *===========================================================================*/ 62 | typedef double real_T; 63 | typedef double time_T; 64 | typedef unsigned char boolean_T; 65 | typedef int int_T; 66 | typedef unsigned int uint_T; 67 | typedef unsigned long ulong_T; 68 | typedef unsigned long long ulonglong_T; 69 | typedef char char_T; 70 | typedef unsigned char uchar_T; 71 | typedef char_T byte_T; 72 | 73 | /*===========================================================================* 74 | * Complex number type definitions * 75 | *===========================================================================*/ 76 | #define CREAL_T 77 | 78 | typedef struct { 79 | real32_T re; 80 | real32_T im; 81 | } creal32_T; 82 | 83 | typedef struct { 84 | real64_T re; 85 | real64_T im; 86 | } creal64_T; 87 | 88 | typedef struct { 89 | real_T re; 90 | real_T im; 91 | } creal_T; 92 | 93 | #define CINT8_T 94 | 95 | typedef struct { 96 | int8_T re; 97 | int8_T im; 98 | } cint8_T; 99 | 100 | #define CUINT8_T 101 | 102 | typedef struct { 103 | uint8_T re; 104 | uint8_T im; 105 | } cuint8_T; 106 | 107 | #define CINT16_T 108 | 109 | typedef struct { 110 | int16_T re; 111 | int16_T im; 112 | } cint16_T; 113 | 114 | #define CUINT16_T 115 | 116 | typedef struct { 117 | uint16_T re; 118 | uint16_T im; 119 | } cuint16_T; 120 | 121 | #define CINT32_T 122 | 123 | typedef struct { 124 | int32_T re; 125 | int32_T im; 126 | } cint32_T; 127 | 128 | #define CUINT32_T 129 | 130 | typedef struct { 131 | uint32_T re; 132 | uint32_T im; 133 | } cuint32_T; 134 | 135 | #define CINT64_T 136 | 137 | typedef struct { 138 | int64_T re; 139 | int64_T im; 140 | } cint64_T; 141 | 142 | #define CUINT64_T 143 | 144 | typedef struct { 145 | uint64_T re; 146 | uint64_T im; 147 | } cuint64_T; 148 | 149 | /*=======================================================================* 150 | * Min and Max: * 151 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 152 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 153 | *=======================================================================*/ 154 | #define MAX_int8_T ((int8_T)(127)) 155 | #define MIN_int8_T ((int8_T)(-128)) 156 | #define MAX_uint8_T ((uint8_T)(255U)) 157 | #define MAX_int16_T ((int16_T)(32767)) 158 | #define MIN_int16_T ((int16_T)(-32768)) 159 | #define MAX_uint16_T ((uint16_T)(65535U)) 160 | #define MAX_int32_T ((int32_T)(2147483647)) 161 | #define MIN_int32_T ((int32_T)(-2147483647-1)) 162 | #define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) 163 | #define MAX_int64_T ((int64_T)(9223372036854775807LL)) 164 | #define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) 165 | #define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) 166 | 167 | /* Block D-Work pointer type */ 168 | typedef void * pointer_T; 169 | 170 | #endif /* RTWTYPES_H */ 171 | 172 | /* 173 | * File trailer for generated code. 174 | * 175 | * [EOF] 176 | */ 177 | -------------------------------------------------------------------------------- /Example1/dllModel_init.m: -------------------------------------------------------------------------------- 1 | %% Tunable parameters. 2 | K=Simulink.Parameter; 3 | K.Value=1; 4 | K.CoderInfo.StorageClass='ExportedGlobal'; 5 | 6 | K2=Simulink.Parameter; 7 | K2.Value=2; 8 | K2.CoderInfo.StorageClass='SimulinkGlobal'; 9 | 10 | %% Signals. 11 | SignalIn=Simulink.Signal; 12 | SignalIn.CoderInfo.StorageClass='ExportedGlobal'; 13 | 14 | SignalIn2=Simulink.Signal; 15 | SignalIn2.CoderInfo.StorageClass='SimulinkGlobal'; 16 | 17 | SignalOut=Simulink.Signal; 18 | SignalOut.CoderInfo.StorageClass='ExportedGlobal'; 19 | 20 | SignalOut2=Simulink.Signal; 21 | SignalOut2.CoderInfo.StorageClass='SimulinkGlobal'; 22 | 23 | SignalOut3=Simulink.Signal; 24 | SignalOut3.CoderInfo.StorageClass='SimulinkGlobal'; 25 | 26 | SimulationSignal1=Simulink.Signal; 27 | SimulationSignal1.CoderInfo.StorageClass='SimulinkGlobal'; 28 | 29 | SimulationSignal2=Simulink.Signal; 30 | SimulationSignal2.CoderInfo.StorageClass='ExportedGlobal'; 31 | -------------------------------------------------------------------------------- /Example1/dllModel_win64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_win64.dll -------------------------------------------------------------------------------- /Example1/dllModel_win64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example1/dllModel_win64.lib -------------------------------------------------------------------------------- /Example1/rtwtypes.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | """ 4 | /*=======================================================================* 5 | * Fixed width word size data types: * 6 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 7 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 8 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 9 | *=======================================================================*/ 10 | """ 11 | int8_T = ctypes.c_byte 12 | uint8_T = ctypes.c_ubyte 13 | int16_T = ctypes.c_short 14 | uint16_T = ctypes.c_ushort 15 | int32_T = ctypes.c_int 16 | uint32_T = ctypes.c_uint 17 | int64_T = ctypes.c_longlong 18 | uint64_T = ctypes.c_ulonglong 19 | real32_T = ctypes.c_float 20 | real64_T = ctypes.c_double 21 | """ 22 | /*===========================================================================* 23 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 24 | * real_T, time_T, ulong_T, ulonglong_T. * 25 | *===========================================================================*/ 26 | """ 27 | real_T = ctypes.c_double 28 | time_T = ctypes.c_double 29 | boolean_T = ctypes.c_ubyte 30 | int_T = ctypes.c_int 31 | uint_T = ctypes.c_uint 32 | ulong_T = ctypes.c_ulong 33 | ulonglong_T = ctypes.c_ulonglong 34 | char_T = ctypes.c_char 35 | uchar_T = ctypes.c_ubyte 36 | char_T = ctypes.c_byte 37 | """ 38 | /*===========================================================================* 39 | * Complex number type definitions * 40 | *===========================================================================*/ 41 | """ 42 | 43 | 44 | class creal32_T(ctypes.Structure): 45 | _fields_ = [ 46 | ("re", real32_T), 47 | ("im", real32_T), 48 | ] 49 | 50 | 51 | class creal64_T(ctypes.Structure): 52 | _fields_ = [ 53 | ("re", real64_T), 54 | ("im", real64_T), 55 | ] 56 | 57 | 58 | class creal_T(ctypes.Structure): 59 | _fields_ = [ 60 | ("re", real_T), 61 | ("im", real_T), 62 | ] 63 | 64 | 65 | class cint8_T(ctypes.Structure): 66 | _fields_ = [ 67 | ("re", int8_T), 68 | ("im", int8_T), 69 | ] 70 | 71 | 72 | class cuint8_T(ctypes.Structure): 73 | _fields_ = [ 74 | ("re", uint8_T), 75 | ("im", uint8_T), 76 | ] 77 | 78 | 79 | class cint16_T(ctypes.Structure): 80 | _fields_ = [ 81 | ("re", int16_T), 82 | ("im", int16_T), 83 | ] 84 | 85 | 86 | class cuint16_T(ctypes.Structure): 87 | _fields_ = [ 88 | ("re", uint16_T), 89 | ("im", uint16_T), 90 | ] 91 | 92 | 93 | class cint32_T(ctypes.Structure): 94 | _fields_ = [ 95 | ("re", int32_T), 96 | ("im", int32_T), 97 | ] 98 | 99 | 100 | class cuint32_T(ctypes.Structure): 101 | _fields_ = [ 102 | ("re", uint32_T), 103 | ("im", uint32_T), 104 | ] 105 | 106 | 107 | class cint64_T(ctypes.Structure): 108 | _fields_ = [ 109 | ("re", int64_T), 110 | ("im", int64_T), 111 | ] 112 | 113 | 114 | class cuint64_T(ctypes.Structure): 115 | _fields_ = [ 116 | ("re", uint64_T), 117 | ("im", uint64_T), 118 | ] 119 | -------------------------------------------------------------------------------- /Example2/README.md: -------------------------------------------------------------------------------- 1 | ### Example 2: [discrete_tf-python_class.ipynb](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf-python_class.ipynb) 2 | 3 | ![](discrete_tf.png) 4 | 5 | A simple discrete transfer function. Compiled with a 1st order low pass filter. 6 | 7 | There are two example notebooks for Example 2. 8 | 9 | 1. [Simple Example](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf.ipynb) - A simple low-level ctypes wrapper. 10 | 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. 11 | 12 | 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) 13 | 14 | - For the tests example the model shared library is presented to tests as a `pytest` fixture defined in [`conftest.py`](tests/conftest.py) 15 | -------------------------------------------------------------------------------- /Example2/discrete_tf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf.png -------------------------------------------------------------------------------- /Example2/discrete_tf.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf.so -------------------------------------------------------------------------------- /Example2/discrete_tf_build.m: -------------------------------------------------------------------------------- 1 | %% Model Builder 2 | % Close all models. 3 | bdclose('all'); 4 | % Clear matlab environment. 5 | clear; 6 | % Change to the build script folder 7 | cd(fileparts(mfilename('fullpath'))); 8 | 9 | % Model To Build 10 | model = 'discrete_tf'; 11 | % Run the model init script. 12 | feval([model '_init']); 13 | % Open the model. 14 | open_system(model); 15 | % RealTimeWorkshop Build 16 | rtwbuild(model); 17 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/codedescriptor.dmr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_ert_shrlib_rtw/codedescriptor.dmr -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/defines.txt: -------------------------------------------------------------------------------- 1 | MODEL=discrete_tf 2 | NUMST=1 3 | NCSTATES=0 4 | HAVESTDIO 5 | MODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 6 | UNIX 7 | CLASSIC_INTERFACE=0 8 | ALLOCATIONFCN=0 9 | TID01EQ=0 10 | TERMFCN=1 11 | ONESTEPFCN=1 12 | MAT_FILE=0 13 | MULTI_INSTANCE_CODE=0 14 | INTEGER_CODE=0 15 | MT=0 16 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.bat: -------------------------------------------------------------------------------- 1 | @if not "%MINGW_ROOT%" == "" (@set "PATH=%PATH%;%MINGW_ROOT%") 2 | 3 | cd . 4 | 5 | if "%1"=="" ("C:\R2018b\bin\win64\gmake" -f discrete_tf.mk all) else ("C:\R2018b\bin\win64\gmake" -f discrete_tf.mk %1) 6 | @if errorlevel 1 goto error_exit 7 | 8 | exit /B 0 9 | 10 | :error_exit 11 | echo The make command returned an error of %errorlevel% 12 | An_error_occurred_during_the_call_to_make 13 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: discrete_tf.c 3 | * 4 | * Code generated for Simulink model 'discrete_tf'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018 8 | * C/C++ source code generated on : Sun Feb 7 20:06:09 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Emulation hardware selection: 13 | * Differs from embedded hardware (MATLAB Host) 14 | * Code generation objectives: Unspecified 15 | * Validation result: Not run 16 | */ 17 | 18 | #include "discrete_tf.h" 19 | #include "discrete_tf_private.h" 20 | 21 | /* Exported block signals */ 22 | real_T OutputSignal; /* '/Discrete Transfer Fcn' */ 23 | real_T SimTime; /* '/Digital Clock' */ 24 | 25 | /* Exported block parameters */ 26 | real_T InputSignal = 0.0; /* Variable: InputSignal 27 | * Referenced by: '/Constant' 28 | */ 29 | real_T den[2] = { 1.0, -0.99950012497916929 } ;/* Variable: den 30 | * Referenced by: '/Discrete Transfer Fcn' 31 | */ 32 | 33 | real_T num[2] = { 0.0, 0.0014996250624921886 } ;/* Variable: num 34 | * Referenced by: '/Discrete Transfer Fcn' 35 | */ 36 | 37 | /* Block states (default storage) */ 38 | DW_discrete_tf_T discrete_tf_DW; 39 | 40 | /* Real-time model */ 41 | RT_MODEL_discrete_tf_T discrete_tf_M_; 42 | RT_MODEL_discrete_tf_T *const discrete_tf_M = &discrete_tf_M_; 43 | 44 | /* Model step function */ 45 | void discrete_tf_step(void) 46 | { 47 | /* DiscreteTransferFcn: '/Discrete Transfer Fcn' */ 48 | OutputSignal = num[1] * discrete_tf_DW.DiscreteTransferFcn_states; 49 | 50 | /* DigitalClock: '/Digital Clock' */ 51 | SimTime = ((discrete_tf_M->Timing.clockTick0) * 0.001); 52 | 53 | /* Update for DiscreteTransferFcn: '/Discrete Transfer Fcn' incorporates: 54 | * Constant: '/Constant' 55 | */ 56 | discrete_tf_DW.DiscreteTransferFcn_states = (InputSignal - den[1] * 57 | discrete_tf_DW.DiscreteTransferFcn_states) / den[0]; 58 | 59 | /* Update absolute time for base rate */ 60 | /* The "clockTick0" counts the number of times the code of this task has 61 | * been executed. The resolution of this integer timer is 0.001, which is the step size 62 | * of the task. Size of "clockTick0" ensures timer will not overflow during the 63 | * application lifespan selected. 64 | */ 65 | discrete_tf_M->Timing.clockTick0++; 66 | } 67 | 68 | /* Model initialize function */ 69 | void discrete_tf_initialize(void) 70 | { 71 | /* Registration code */ 72 | 73 | /* initialize real-time model */ 74 | (void) memset((void *)discrete_tf_M, 0, 75 | sizeof(RT_MODEL_discrete_tf_T)); 76 | 77 | /* block I/O */ 78 | 79 | /* exported global signals */ 80 | OutputSignal = 0.0; 81 | SimTime = 0.0; 82 | 83 | /* states (dwork) */ 84 | (void) memset((void *)&discrete_tf_DW, 0, 85 | sizeof(DW_discrete_tf_T)); 86 | } 87 | 88 | /* Model terminate function */ 89 | void discrete_tf_terminate(void) 90 | { 91 | /* (no terminate code required) */ 92 | } 93 | 94 | /* 95 | * File trailer for generated code. 96 | * 97 | * [EOF] 98 | */ 99 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.def: -------------------------------------------------------------------------------- 1 | { 2 | global: 3 | discrete_tf_M_; 4 | discrete_tf_M; 5 | discrete_tf_initialize; 6 | discrete_tf_step; 7 | discrete_tf_terminate; 8 | 9 | 10 | OutputSignal; 11 | SimTime; 12 | InputSignal; 13 | den; 14 | num; 15 | local: 16 | *; 17 | }; 18 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: discrete_tf.h 3 | * 4 | * Code generated for Simulink model 'discrete_tf'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018 8 | * C/C++ source code generated on : Sun Feb 7 20:06:09 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Emulation hardware selection: 13 | * Differs from embedded hardware (MATLAB Host) 14 | * Code generation objectives: Unspecified 15 | * Validation result: Not run 16 | */ 17 | 18 | #ifndef RTW_HEADER_discrete_tf_h_ 19 | #define RTW_HEADER_discrete_tf_h_ 20 | #include 21 | #ifndef discrete_tf_COMMON_INCLUDES_ 22 | # define discrete_tf_COMMON_INCLUDES_ 23 | #include "rtwtypes.h" 24 | #include "rtw_continuous.h" 25 | #include "rtw_solver.h" 26 | #endif /* discrete_tf_COMMON_INCLUDES_ */ 27 | 28 | #include "discrete_tf_types.h" 29 | 30 | /* Macros for accessing real-time model data structure */ 31 | #ifndef rtmGetErrorStatus 32 | # define rtmGetErrorStatus(rtm) ((rtm)->errorStatus) 33 | #endif 34 | 35 | #ifndef rtmSetErrorStatus 36 | # define rtmSetErrorStatus(rtm, val) ((rtm)->errorStatus = (val)) 37 | #endif 38 | 39 | /* Block states (default storage) for system '' */ 40 | typedef struct { 41 | real_T DiscreteTransferFcn_states; /* '/Discrete Transfer Fcn' */ 42 | } DW_discrete_tf_T; 43 | 44 | /* Real-time Model Data Structure */ 45 | struct tag_RTM_discrete_tf_T { 46 | const char_T * volatile errorStatus; 47 | 48 | /* 49 | * Timing: 50 | * The following substructure contains information regarding 51 | * the timing information for the model. 52 | */ 53 | struct { 54 | uint32_T clockTick0; 55 | } Timing; 56 | }; 57 | 58 | /* Block states (default storage) */ 59 | extern DW_discrete_tf_T discrete_tf_DW; 60 | 61 | /* 62 | * Exported Global Signals 63 | * 64 | * Note: Exported global signals are block signals with an exported global 65 | * storage class designation. Code generation will declare the memory for 66 | * these signals and export their symbols. 67 | * 68 | */ 69 | extern real_T OutputSignal; /* '/Discrete Transfer Fcn' */ 70 | extern real_T SimTime; /* '/Digital Clock' */ 71 | 72 | /* 73 | * Exported Global Parameters 74 | * 75 | * Note: Exported global parameters are tunable parameters with an exported 76 | * global storage class designation. Code generation will declare the memory for 77 | * these parameters and exports their symbols. 78 | * 79 | */ 80 | extern real_T InputSignal; /* Variable: InputSignal 81 | * Referenced by: '/Constant' 82 | */ 83 | extern real_T den[2]; /* Variable: den 84 | * Referenced by: '/Discrete Transfer Fcn' 85 | */ 86 | extern real_T num[2]; /* Variable: num 87 | * Referenced by: '/Discrete Transfer Fcn' 88 | */ 89 | 90 | /* Model entry point functions */ 91 | extern void discrete_tf_initialize(void); 92 | extern void discrete_tf_step(void); 93 | extern void discrete_tf_terminate(void); 94 | 95 | /* Real-time Model object */ 96 | extern RT_MODEL_discrete_tf_T *const discrete_tf_M; 97 | 98 | /*- 99 | * The generated code includes comments that allow you to trace directly 100 | * back to the appropriate location in the model. The basic format 101 | * is /block_name, where system is the system number (uniquely 102 | * assigned by Simulink) and block_name is the name of the block. 103 | * 104 | * Use the MATLAB hilite_system command to trace the generated code back 105 | * to the model. For example, 106 | * 107 | * hilite_system('') - opens system 3 108 | * hilite_system('/Kp') - opens and selects block Kp which resides in S3 109 | * 110 | * Here is the system hierarchy for this model 111 | * 112 | * '' : 'discrete_tf' 113 | */ 114 | #endif /* RTW_HEADER_discrete_tf_h_ */ 115 | 116 | /* 117 | * File trailer for generated code. 118 | * 119 | * [EOF] 120 | */ 121 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.obj -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf.rsp: -------------------------------------------------------------------------------- 1 | discrete_tf.obj 2 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf_comp.rsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_ert_shrlib_rtw/discrete_tf_comp.rsp -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: discrete_tf_private.h 3 | * 4 | * Code generated for Simulink model 'discrete_tf'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018 8 | * C/C++ source code generated on : Sun Feb 7 20:06:09 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Emulation hardware selection: 13 | * Differs from embedded hardware (MATLAB Host) 14 | * Code generation objectives: Unspecified 15 | * Validation result: Not run 16 | */ 17 | 18 | #ifndef RTW_HEADER_discrete_tf_private_h_ 19 | #define RTW_HEADER_discrete_tf_private_h_ 20 | #include "rtwtypes.h" 21 | #endif /* RTW_HEADER_discrete_tf_private_h_ */ 22 | 23 | /* 24 | * File trailer for generated code. 25 | * 26 | * [EOF] 27 | */ 28 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf_ref.rsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_ert_shrlib_rtw/discrete_tf_ref.rsp -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/discrete_tf_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: discrete_tf_types.h 3 | * 4 | * Code generated for Simulink model 'discrete_tf'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018 8 | * C/C++ source code generated on : Sun Feb 7 20:06:09 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Emulation hardware selection: 13 | * Differs from embedded hardware (MATLAB Host) 14 | * Code generation objectives: Unspecified 15 | * Validation result: Not run 16 | */ 17 | 18 | #ifndef RTW_HEADER_discrete_tf_types_h_ 19 | #define RTW_HEADER_discrete_tf_types_h_ 20 | 21 | /* Forward declaration for rtModel */ 22 | typedef struct tag_RTM_discrete_tf_T RT_MODEL_discrete_tf_T; 23 | 24 | #endif /* RTW_HEADER_discrete_tf_types_h_ */ 25 | 26 | /* 27 | * File trailer for generated code. 28 | * 29 | * [EOF] 30 | */ 31 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/ert_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: ert_main.c 3 | * 4 | * Code generated for Simulink model 'discrete_tf'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018 8 | * C/C++ source code generated on : Sun Feb 7 20:06:09 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Emulation hardware selection: 13 | * Differs from embedded hardware (MATLAB Host) 14 | * Code generation objectives: Unspecified 15 | * Validation result: Not run 16 | */ 17 | 18 | #include 19 | #include /* This ert_main.c example uses printf/fflush */ 20 | #include "discrete_tf.h" /* Model's header file */ 21 | #include "rtwtypes.h" 22 | 23 | /* 24 | * Associating rt_OneStep with a real-time clock or interrupt service routine 25 | * is what makes the generated code "real-time". The function rt_OneStep is 26 | * always associated with the base rate of the model. Subrates are managed 27 | * by the base rate from inside the generated code. Enabling/disabling 28 | * interrupts and floating point context switches are target specific. This 29 | * example code indicates where these should take place relative to executing 30 | * the generated code step function. Overrun behavior should be tailored to 31 | * your application needs. This example simply sets an error status in the 32 | * real-time model and returns from rt_OneStep. 33 | */ 34 | void rt_OneStep(void); 35 | void rt_OneStep(void) 36 | { 37 | static boolean_T OverrunFlag = false; 38 | 39 | /* Disable interrupts here */ 40 | 41 | /* Check for overrun */ 42 | if (OverrunFlag) { 43 | rtmSetErrorStatus(discrete_tf_M, "Overrun"); 44 | return; 45 | } 46 | 47 | OverrunFlag = true; 48 | 49 | /* Save FPU context here (if necessary) */ 50 | /* Re-enable timer or interrupt here */ 51 | /* Set model inputs here */ 52 | 53 | /* Step the model */ 54 | discrete_tf_step(); 55 | 56 | /* Get model outputs here */ 57 | 58 | /* Indicate task complete */ 59 | OverrunFlag = false; 60 | 61 | /* Disable interrupts here */ 62 | /* Restore FPU context here (if necessary) */ 63 | /* Enable interrupts here */ 64 | } 65 | 66 | /* 67 | * The example "main" function illustrates what is required by your 68 | * application code to initialize, execute, and terminate the generated code. 69 | * Attaching rt_OneStep to a real-time clock is target specific. This example 70 | * illustrates how you do this relative to initializing the model. 71 | */ 72 | int_T main(int_T argc, const char *argv[]) 73 | { 74 | /* Unused arguments */ 75 | (void)(argc); 76 | (void)(argv); 77 | 78 | /* Initialize model */ 79 | discrete_tf_initialize(); 80 | 81 | /* Attach rt_OneStep to a timer or interrupt service routine with 82 | * period 0.001 seconds (the model's base sample time) here. The 83 | * call syntax for rt_OneStep is 84 | * 85 | * rt_OneStep(); 86 | */ 87 | printf("Warning: The simulation will run forever. " 88 | "Generated ERT main won't simulate model step behavior. " 89 | "To change this behavior select the 'MAT-file logging' option.\n"); 90 | fflush((NULL)); 91 | while (rtmGetErrorStatus(discrete_tf_M) == (NULL)) { 92 | /* Perform other application tasks here */ 93 | } 94 | 95 | /* Disable rt_OneStep() here */ 96 | 97 | /* Terminate model */ 98 | discrete_tf_terminate(); 99 | return 0; 100 | } 101 | 102 | /* 103 | * File trailer for generated code. 104 | * 105 | * [EOF] 106 | */ 107 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/modelsources.txt: -------------------------------------------------------------------------------- 1 | discrete_tf.c 2 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/rtw_proj.tmw: -------------------------------------------------------------------------------- 1 | Simulink Coder project for discrete_tf using . MATLAB root = /usr/local/MATLAB/R2018a. SimStruct date: 06-Feb-2018 00:40:31 2 | This file is generated by Simulink Coder for use by the make utility 3 | to determine when to rebuild objects when the name of the current Simulink Coder project changes. 4 | The rtwinfomat located at: ../slprj/ert_shrlib/discrete_tf/tmwinternal/binfo.mat 5 | -------------------------------------------------------------------------------- /Example2/discrete_tf_ert_shrlib_rtw/rtwtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: rtwtypes.h 3 | * 4 | * Code generated for Simulink model 'discrete_tf'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 8.14 (R2018a) 06-Feb-2018 8 | * C/C++ source code generated on : Sun Feb 7 20:06:09 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Emulation hardware selection: 13 | * Differs from embedded hardware (MATLAB Host) 14 | * Code generation objectives: Unspecified 15 | * Validation result: Not run 16 | */ 17 | 18 | #ifndef RTWTYPES_H 19 | #define RTWTYPES_H 20 | 21 | /* Logical type definitions */ 22 | #if (!defined(__cplusplus)) 23 | # ifndef false 24 | # define false (0U) 25 | # endif 26 | 27 | # ifndef true 28 | # define true (1U) 29 | # endif 30 | #endif 31 | 32 | /*=======================================================================* 33 | * Target hardware information 34 | * Device type: MATLAB Host 35 | * Number of bits: char: 8 short: 16 int: 32 36 | * long: 64 long long: 64 37 | * native word size: 64 38 | * Byte ordering: LittleEndian 39 | * Signed integer division rounds to: Zero 40 | * Shift right on a signed integer as arithmetic shift: on 41 | *=======================================================================*/ 42 | 43 | /*=======================================================================* 44 | * Fixed width word size data types: * 45 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 46 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 47 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 48 | *=======================================================================*/ 49 | typedef signed char int8_T; 50 | typedef unsigned char uint8_T; 51 | typedef short int16_T; 52 | typedef unsigned short uint16_T; 53 | typedef int int32_T; 54 | typedef unsigned int uint32_T; 55 | typedef long int64_T; 56 | typedef unsigned long uint64_T; 57 | typedef float real32_T; 58 | typedef double real64_T; 59 | 60 | /*===========================================================================* 61 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 62 | * real_T, time_T, ulong_T, ulonglong_T. * 63 | *===========================================================================*/ 64 | typedef double real_T; 65 | typedef double time_T; 66 | typedef unsigned char boolean_T; 67 | typedef int int_T; 68 | typedef unsigned int uint_T; 69 | typedef unsigned long ulong_T; 70 | typedef unsigned long long ulonglong_T; 71 | typedef char char_T; 72 | typedef unsigned char uchar_T; 73 | typedef char_T byte_T; 74 | 75 | /*===========================================================================* 76 | * Complex number type definitions * 77 | *===========================================================================*/ 78 | #define CREAL_T 79 | 80 | typedef struct { 81 | real32_T re; 82 | real32_T im; 83 | } creal32_T; 84 | 85 | typedef struct { 86 | real64_T re; 87 | real64_T im; 88 | } creal64_T; 89 | 90 | typedef struct { 91 | real_T re; 92 | real_T im; 93 | } creal_T; 94 | 95 | #define CINT8_T 96 | 97 | typedef struct { 98 | int8_T re; 99 | int8_T im; 100 | } cint8_T; 101 | 102 | #define CUINT8_T 103 | 104 | typedef struct { 105 | uint8_T re; 106 | uint8_T im; 107 | } cuint8_T; 108 | 109 | #define CINT16_T 110 | 111 | typedef struct { 112 | int16_T re; 113 | int16_T im; 114 | } cint16_T; 115 | 116 | #define CUINT16_T 117 | 118 | typedef struct { 119 | uint16_T re; 120 | uint16_T im; 121 | } cuint16_T; 122 | 123 | #define CINT32_T 124 | 125 | typedef struct { 126 | int32_T re; 127 | int32_T im; 128 | } cint32_T; 129 | 130 | #define CUINT32_T 131 | 132 | typedef struct { 133 | uint32_T re; 134 | uint32_T im; 135 | } cuint32_T; 136 | 137 | #define CINT64_T 138 | 139 | typedef struct { 140 | int64_T re; 141 | int64_T im; 142 | } cint64_T; 143 | 144 | #define CUINT64_T 145 | 146 | typedef struct { 147 | uint64_T re; 148 | uint64_T im; 149 | } cuint64_T; 150 | 151 | /*=======================================================================* 152 | * Min and Max: * 153 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 154 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 155 | *=======================================================================*/ 156 | #define MAX_int8_T ((int8_T)(127)) 157 | #define MIN_int8_T ((int8_T)(-128)) 158 | #define MAX_uint8_T ((uint8_T)(255U)) 159 | #define MAX_int16_T ((int16_T)(32767)) 160 | #define MIN_int16_T ((int16_T)(-32768)) 161 | #define MAX_uint16_T ((uint16_T)(65535U)) 162 | #define MAX_int32_T ((int32_T)(2147483647)) 163 | #define MIN_int32_T ((int32_T)(-2147483647-1)) 164 | #define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) 165 | #define MAX_int64_T ((int64_T)(9223372036854775807L)) 166 | #define MIN_int64_T ((int64_T)(-9223372036854775807L-1L)) 167 | #define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFUL)) 168 | 169 | /* Block D-Work pointer type */ 170 | typedef void * pointer_T; 171 | 172 | #endif /* RTWTYPES_H */ 173 | 174 | /* 175 | * File trailer for generated code. 176 | * 177 | * [EOF] 178 | */ 179 | -------------------------------------------------------------------------------- /Example2/discrete_tf_files/discrete_tf_15_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_files/discrete_tf_15_1.png -------------------------------------------------------------------------------- /Example2/discrete_tf_files/discrete_tf_18_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_files/discrete_tf_18_1.png -------------------------------------------------------------------------------- /Example2/discrete_tf_files/discrete_tf_19_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_files/discrete_tf_19_1.png -------------------------------------------------------------------------------- /Example2/discrete_tf_files/discrete_tf_23_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_files/discrete_tf_23_1.png -------------------------------------------------------------------------------- /Example2/discrete_tf_files/discrete_tf_24_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_files/discrete_tf_24_1.png -------------------------------------------------------------------------------- /Example2/discrete_tf_files/discrete_tf_27_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_files/discrete_tf_27_1.png -------------------------------------------------------------------------------- /Example2/discrete_tf_init.m: -------------------------------------------------------------------------------- 1 | %% Transfer Function Definition 2 | sys = tf(3, [2, 1]); 3 | sysd = c2d(sys,1e-3); 4 | % Plot a step function 5 | step(sys, sysd); 6 | % Save plot 7 | print(gcf, '-dpng', 'step_response.png') 8 | 9 | % Model Run Speed. 10 | Ts=1e-3; 11 | 12 | %% Parameters 13 | num=Simulink.Parameter; 14 | num.Value=sysd.Numerator{1}; 15 | num.CoderInfo.StorageClass='ExportedGlobal'; 16 | 17 | den=Simulink.Parameter; 18 | den.Value=sysd.Denominator{1}; 19 | den.CoderInfo.StorageClass='ExportedGlobal'; 20 | 21 | InputSignal=Simulink.Parameter; 22 | InputSignal.Value=0; 23 | InputSignal.CoderInfo.StorageClass='ExportedGlobal'; 24 | %% Signals. 25 | 26 | OutputSignal=Simulink.Signal; 27 | OutputSignal.CoderInfo.StorageClass='ExportedGlobal'; 28 | 29 | SimTime=Simulink.Signal; 30 | SimTime.CoderInfo.StorageClass='ExportedGlobal'; 31 | -------------------------------------------------------------------------------- /Example2/discrete_tf_step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_step.png -------------------------------------------------------------------------------- /Example2/discrete_tf_win64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_win64.dll -------------------------------------------------------------------------------- /Example2/discrete_tf_win64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/discrete_tf_win64.lib -------------------------------------------------------------------------------- /Example2/discretetf.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import os 3 | import platform 4 | 5 | import pandas as pd 6 | from rtwtypes import real_T 7 | 8 | 9 | class DiscreteTF: 10 | def __init__(self, model="discrete_tf"): 11 | self.model = model 12 | if platform.system() == "Linux": 13 | self.dll_path = os.path.abspath(f"{model}.so") 14 | self.dll = ctypes.cdll.LoadLibrary(self.dll_path) 15 | elif platform.system() == "Windows": 16 | self.dll_path = os.path.abspath(f"{model}_win64.dll") 17 | self.dll = ctypes.windll.LoadLibrary(self.dll_path) 18 | else: 19 | raise Exception("System Not Supported") 20 | 21 | # Model entry point functions 22 | self.__initialize = getattr(self.dll, f"{model}_initialize") 23 | self.__step = getattr(self.dll, f"{model}_step") 24 | self.__model_terminate = getattr(self.dll, f"{model}_terminate") 25 | 26 | # Model signals 27 | self._output = real_T.in_dll(self.dll, "OutputSignal") 28 | self._time = real_T.in_dll(self.dll, "SimTime") 29 | 30 | # Model Parameters 31 | self._input_signal = real_T.in_dll(self.dll, "InputSignal") 32 | self._num = (real_T * 2).in_dll(self.dll, "num") 33 | self._den = (real_T * 2).in_dll(self.dll, "den") 34 | 35 | def initialize(self): 36 | """Initialize the Model.""" 37 | self.__initialize() 38 | self.step_num = -1 39 | 40 | def step(self): 41 | """Step through the model Model.""" 42 | self.__step() 43 | self.step_num += 1 44 | 45 | def terminate(self): 46 | """Terminate the model Model.""" 47 | self.__model_terminate() 48 | 49 | def init_log(self): 50 | """Create an empty datalog and intialize the model.""" 51 | self.data = dict() 52 | self.data["input"] = list() 53 | self.data["output"] = list() 54 | self.data["time"] = list() 55 | self.initialize() 56 | 57 | def step_log(self): 58 | """Step the data and log it.""" 59 | self.step() 60 | self.data["input"].append(self.input_signal) 61 | self.data["output"].append(self.output) 62 | self.data["time"].append(self.time) 63 | 64 | @property 65 | def dataframe(self): 66 | return pd.DataFrame(self.data) 67 | 68 | def plot(self): 69 | self.dataframe.plot(x="time", y=["input", "output"]) 70 | 71 | # Signals 72 | @property 73 | def output(self): 74 | # Model output, return a Python datatype 75 | return float(self._output.value) 76 | 77 | @property 78 | def time(self): 79 | # Model time, return a Python datatype 80 | return float(self._time.value) 81 | 82 | # Parameters 83 | # Use setters/getters to make it as pythonic as possible 84 | @property 85 | def num(self): 86 | # Convert the ctypes Array to a python list. 87 | return list(self._num) 88 | 89 | @num.setter 90 | def num(self, value): 91 | # This size was specified at compile time and does 92 | # need the library to be recompiled to change. 93 | assert len(value) in [1, 2] 94 | if len(value) == 2: 95 | self._num[0] = float(value[0]) 96 | self._num[1] = float(value[1]) 97 | else: 98 | self._num[0] = float(0) 99 | self._num[1] = float(value[0]) 100 | 101 | @property 102 | def den(self): 103 | return list(self._den) 104 | 105 | @den.setter 106 | def den(self, value): 107 | # This size was specified at compile time and does 108 | # need the library to be recompiled to change. 109 | assert len(value) in [1, 2] 110 | if len(value) == 2: 111 | self._den[0] = float(value[0]) 112 | self._den[1] = float(value[1]) 113 | else: 114 | self._den[0] = float(0) 115 | self._den[1] = float(value[0]) 116 | 117 | @property 118 | def input_signal(self): 119 | return float(self._input_signal.value) 120 | 121 | @input_signal.setter 122 | def input_signal(self, value): 123 | self._input_signal.value = float(value) 124 | 125 | # 'Pretty' Display for IPython/Notebooks. 126 | def __repr__(self): 127 | return f"{self.model}<{self.time}, {self.input_signal}, {self.output}>" 128 | -------------------------------------------------------------------------------- /Example2/rtwtypes.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | """ 4 | /*=======================================================================* 5 | * Fixed width word size data types: * 6 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 7 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 8 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 9 | *=======================================================================*/ 10 | """ 11 | int8_T = ctypes.c_byte 12 | uint8_T = ctypes.c_ubyte 13 | int16_T = ctypes.c_short 14 | uint16_T = ctypes.c_ushort 15 | int32_T = ctypes.c_int 16 | uint32_T = ctypes.c_uint 17 | int64_T = ctypes.c_longlong 18 | uint64_T = ctypes.c_ulonglong 19 | real32_T = ctypes.c_float 20 | real64_T = ctypes.c_double 21 | """ 22 | /*===========================================================================* 23 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 24 | * real_T, time_T, ulong_T, ulonglong_T. * 25 | *===========================================================================*/ 26 | """ 27 | real_T = ctypes.c_double 28 | time_T = ctypes.c_double 29 | boolean_T = ctypes.c_ubyte 30 | int_T = ctypes.c_int 31 | uint_T = ctypes.c_uint 32 | ulong_T = ctypes.c_ulong 33 | ulonglong_T = ctypes.c_ulonglong 34 | char_T = ctypes.c_char 35 | uchar_T = ctypes.c_ubyte 36 | char_T = ctypes.c_byte 37 | """ 38 | /*===========================================================================* 39 | * Complex number type definitions * 40 | *===========================================================================*/ 41 | """ 42 | 43 | 44 | class creal32_T(ctypes.Structure): 45 | _fields_ = [ 46 | ("re", real32_T), 47 | ("im", real32_T), 48 | ] 49 | 50 | 51 | class creal64_T(ctypes.Structure): 52 | _fields_ = [ 53 | ("re", real64_T), 54 | ("im", real64_T), 55 | ] 56 | 57 | 58 | class creal_T(ctypes.Structure): 59 | _fields_ = [ 60 | ("re", real_T), 61 | ("im", real_T), 62 | ] 63 | 64 | 65 | class cint8_T(ctypes.Structure): 66 | _fields_ = [ 67 | ("re", int8_T), 68 | ("im", int8_T), 69 | ] 70 | 71 | 72 | class cuint8_T(ctypes.Structure): 73 | _fields_ = [ 74 | ("re", uint8_T), 75 | ("im", uint8_T), 76 | ] 77 | 78 | 79 | class cint16_T(ctypes.Structure): 80 | _fields_ = [ 81 | ("re", int16_T), 82 | ("im", int16_T), 83 | ] 84 | 85 | 86 | class cuint16_T(ctypes.Structure): 87 | _fields_ = [ 88 | ("re", uint16_T), 89 | ("im", uint16_T), 90 | ] 91 | 92 | 93 | class cint32_T(ctypes.Structure): 94 | _fields_ = [ 95 | ("re", int32_T), 96 | ("im", int32_T), 97 | ] 98 | 99 | 100 | class cuint32_T(ctypes.Structure): 101 | _fields_ = [ 102 | ("re", uint32_T), 103 | ("im", uint32_T), 104 | ] 105 | 106 | 107 | class cint64_T(ctypes.Structure): 108 | _fields_ = [ 109 | ("re", int64_T), 110 | ("im", int64_T), 111 | ] 112 | 113 | 114 | class cuint64_T(ctypes.Structure): 115 | _fields_ = [ 116 | ("re", uint64_T), 117 | ("im", uint64_T), 118 | ] 119 | -------------------------------------------------------------------------------- /Example2/step_response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example2/step_response.png -------------------------------------------------------------------------------- /Example2/test_results.md: -------------------------------------------------------------------------------- 1 | # Test Report 2 | 3 | *Report generated on 24-Feb-2021 at 14:22:12 by [pytest-md]* 4 | 5 | [pytest-md]: https://github.com/hackebrot/pytest-md 6 | 7 | ## Summary 8 | 9 | 6 tests ran in 0.36 seconds 10 | 11 | - 6 passed 12 | 13 | ## 6 passed 14 | 15 | ### tests/test_01.py 16 | 17 | `test_steps` 0.01s 18 | 19 | `test_time` 0.01s 20 | 21 | `test_steady_state` 0.04s 22 | 23 | `test_control_tf` 0.00s 24 | 25 | `test_sine_response` 0.22s 26 | 27 | `test_step_response` 0.03s 28 | -------------------------------------------------------------------------------- /Example2/tests/conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | import control 5 | import pytest 6 | from discretetf import DiscreteTF 7 | 8 | 9 | @pytest.fixture 10 | def Ts(): 11 | """ Simulink time step. """ 12 | return 1e-3 13 | 14 | 15 | @pytest.fixture(scope="function") 16 | def mdl(): 17 | """Pytest fixture for the model. 18 | Run the initialize function before handing off the model 19 | Run the terminate function after recieving the model. 20 | 21 | This ensures that each test has the same starting model state. 22 | """ 23 | mdl = DiscreteTF() 24 | mdl.initialize() 25 | yield mdl 26 | mdl.terminate() 27 | 28 | 29 | @pytest.fixture(scope="function") 30 | def sysd(Ts): 31 | """ python-control discrete transfer function """ 32 | sys = control.TransferFunction([3], [2, 1]) 33 | return control.c2d(sys, Ts) 34 | -------------------------------------------------------------------------------- /Example2/tests/discretetf.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import os 3 | import platform 4 | 5 | import pandas as pd 6 | from rtwtypes import real_T 7 | 8 | 9 | class DiscreteTF: 10 | def __init__(self, model="discrete_tf"): 11 | self.model = model 12 | if platform.system() == "Linux": 13 | self.dll_path = os.path.abspath(f"{model}.so") 14 | self.dll = ctypes.cdll.LoadLibrary(self.dll_path) 15 | elif platform.system() == "Windows": 16 | self.dll_path = os.path.abspath(f"{model}_win64.dll") 17 | self.dll = ctypes.windll.LoadLibrary(self.dll_path) 18 | else: 19 | raise Exception("System Not Supported") 20 | 21 | # Model entry point functions 22 | self.__initialize = getattr(self.dll, f"{model}_initialize") 23 | self.__step = getattr(self.dll, f"{model}_step") 24 | self.__model_terminate = getattr(self.dll, f"{model}_terminate") 25 | 26 | # Model signals 27 | self._output = real_T.in_dll(self.dll, "OutputSignal") 28 | self._time = real_T.in_dll(self.dll, "SimTime") 29 | 30 | # Model Parameters 31 | self._input_signal = real_T.in_dll(self.dll, "InputSignal") 32 | self._num = (real_T * 2).in_dll(self.dll, "num") 33 | self._den = (real_T * 2).in_dll(self.dll, "den") 34 | 35 | def initialize(self): 36 | """Initialize the Model.""" 37 | self.__initialize() 38 | self.step_num = -1 39 | 40 | def step(self): 41 | """Step through the model Model.""" 42 | self.__step() 43 | self.step_num += 1 44 | 45 | def terminate(self): 46 | """Terminate the model Model.""" 47 | self.__model_terminate() 48 | 49 | def init_log(self): 50 | """Create an empty datalog and intialize the model.""" 51 | self.data = dict() 52 | self.data["input"] = list() 53 | self.data["output"] = list() 54 | self.data["time"] = list() 55 | self.initialize() 56 | 57 | def step_log(self): 58 | """Step the data and log it.""" 59 | self.step() 60 | self.data["input"].append(self.input_signal) 61 | self.data["output"].append(self.output) 62 | self.data["time"].append(self.time) 63 | 64 | @property 65 | def dataframe(self): 66 | return pd.DataFrame(self.data) 67 | 68 | def plot(self): 69 | self.dataframe.plot(x="time", y=["input", "output"]) 70 | 71 | # Signals 72 | @property 73 | def output(self): 74 | # Model output, return a Python datatype 75 | return float(self._output.value) 76 | 77 | @property 78 | def time(self): 79 | # Model time, return a Python datatype 80 | return float(self._time.value) 81 | 82 | # Parameters 83 | # Use setters/getters to make it as pythonic as possible 84 | @property 85 | def num(self): 86 | # Convert the ctypes Array to a python list. 87 | return list(self._num) 88 | 89 | @num.setter 90 | def num(self, value): 91 | # This size was specified at compile time and does 92 | # need the library to be recompiled to change. 93 | assert len(value) in [1, 2] 94 | if len(value) == 2: 95 | self._num[0] = float(value[0]) 96 | self._num[1] = float(value[1]) 97 | else: 98 | self._num[0] = float(0) 99 | self._num[1] = float(value[0]) 100 | 101 | @property 102 | def den(self): 103 | return list(self._den) 104 | 105 | @den.setter 106 | def den(self, value): 107 | # This size was specified at compile time and does 108 | # need the library to be recompiled to change. 109 | assert len(value) in [1, 2] 110 | if len(value) == 2: 111 | self._den[0] = float(value[0]) 112 | self._den[1] = float(value[1]) 113 | else: 114 | self._den[0] = float(0) 115 | self._den[1] = float(value[0]) 116 | 117 | @property 118 | def input_signal(self): 119 | return float(self._input_signal.value) 120 | 121 | @input_signal.setter 122 | def input_signal(self, value): 123 | self._input_signal.value = float(value) 124 | 125 | # 'Pretty' Display for IPython/Notebooks. 126 | def __repr__(self): 127 | return f"{self.model}<{self.time}, {self.input_signal}, {self.output}>" 128 | -------------------------------------------------------------------------------- /Example2/tests/rtwtypes.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | """ 4 | /*=======================================================================* 5 | * Fixed width word size data types: * 6 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 7 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 8 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 9 | *=======================================================================*/ 10 | """ 11 | int8_T = ctypes.c_byte 12 | uint8_T = ctypes.c_ubyte 13 | int16_T = ctypes.c_short 14 | uint16_T = ctypes.c_ushort 15 | int32_T = ctypes.c_int 16 | uint32_T = ctypes.c_uint 17 | int64_T = ctypes.c_longlong 18 | uint64_T = ctypes.c_ulonglong 19 | real32_T = ctypes.c_float 20 | real64_T = ctypes.c_double 21 | """ 22 | /*===========================================================================* 23 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 24 | * real_T, time_T, ulong_T, ulonglong_T. * 25 | *===========================================================================*/ 26 | """ 27 | real_T = ctypes.c_double 28 | time_T = ctypes.c_double 29 | boolean_T = ctypes.c_ubyte 30 | int_T = ctypes.c_int 31 | uint_T = ctypes.c_uint 32 | ulong_T = ctypes.c_ulong 33 | ulonglong_T = ctypes.c_ulonglong 34 | char_T = ctypes.c_char 35 | uchar_T = ctypes.c_ubyte 36 | char_T = ctypes.c_byte 37 | """ 38 | /*===========================================================================* 39 | * Complex number type definitions * 40 | *===========================================================================*/ 41 | """ 42 | 43 | 44 | class creal32_T(ctypes.Structure): 45 | _fields_ = [ 46 | ("re", real32_T), 47 | ("im", real32_T), 48 | ] 49 | 50 | 51 | class creal64_T(ctypes.Structure): 52 | _fields_ = [ 53 | ("re", real64_T), 54 | ("im", real64_T), 55 | ] 56 | 57 | 58 | class creal_T(ctypes.Structure): 59 | _fields_ = [ 60 | ("re", real_T), 61 | ("im", real_T), 62 | ] 63 | 64 | 65 | class cint8_T(ctypes.Structure): 66 | _fields_ = [ 67 | ("re", int8_T), 68 | ("im", int8_T), 69 | ] 70 | 71 | 72 | class cuint8_T(ctypes.Structure): 73 | _fields_ = [ 74 | ("re", uint8_T), 75 | ("im", uint8_T), 76 | ] 77 | 78 | 79 | class cint16_T(ctypes.Structure): 80 | _fields_ = [ 81 | ("re", int16_T), 82 | ("im", int16_T), 83 | ] 84 | 85 | 86 | class cuint16_T(ctypes.Structure): 87 | _fields_ = [ 88 | ("re", uint16_T), 89 | ("im", uint16_T), 90 | ] 91 | 92 | 93 | class cint32_T(ctypes.Structure): 94 | _fields_ = [ 95 | ("re", int32_T), 96 | ("im", int32_T), 97 | ] 98 | 99 | 100 | class cuint32_T(ctypes.Structure): 101 | _fields_ = [ 102 | ("re", uint32_T), 103 | ("im", uint32_T), 104 | ] 105 | 106 | 107 | class cint64_T(ctypes.Structure): 108 | _fields_ = [ 109 | ("re", int64_T), 110 | ("im", int64_T), 111 | ] 112 | 113 | 114 | class cuint64_T(ctypes.Structure): 115 | _fields_ = [ 116 | ("re", uint64_T), 117 | ("im", uint64_T), 118 | ] 119 | -------------------------------------------------------------------------------- /Example2/tests/test_01.py: -------------------------------------------------------------------------------- 1 | import control 2 | import numpy as np 3 | 4 | 5 | def test_steps(mdl, Ts): 6 | """Test the step counter""" 7 | mdl.initialize() 8 | for _ in range(int(15 / Ts)): 9 | mdl.step() 10 | assert mdl.step_num == 14999 11 | 12 | 13 | def test_time(mdl, Ts): 14 | """Test simulation time after given number of steps.""" 15 | mdl.initialize() 16 | for _ in range(int(15 / Ts)): 17 | mdl.step() 18 | assert mdl.time == 15 - Ts 19 | 20 | 21 | def test_steady_state(mdl, Ts): 22 | """Test Step response steady state condition""" 23 | mdl.input_signal = 1.0 24 | for _ in range(int(100 / Ts)): 25 | mdl.step() 26 | assert np.isclose(mdl.output, mdl.input_signal * 3) 27 | 28 | 29 | def test_control_tf(mdl, sysd): 30 | """Test that the discrete transfer function's numerator and denominator match 31 | those calculated from python-control. 32 | """ 33 | assert np.isclose(mdl.num[1], sysd.num).all() 34 | assert np.isclose(mdl.den, sysd.den).all() 35 | 36 | 37 | def test_sine_response(mdl, sysd, Ts): 38 | """ 39 | Test that a sine wave input to the Simulink Transfer function matches the forced_response 40 | output given the same input. 41 | """ 42 | sys = control.TransferFunction([3], [2, 1]) 43 | sysd = control.c2d(sys, Ts) 44 | 45 | mdl.init_log() 46 | f = 0.5 # Hz 47 | for step in range(int(10 * 1e3)): 48 | mdl.input_signal = np.sin(2 * np.pi * step * f * Ts) 49 | mdl.step_log() 50 | df = mdl.dataframe 51 | _, yout, _ = control.forced_response(sysd, df.time, df.input) 52 | np.allclose(yout, df.output) 53 | 54 | 55 | def test_step_response(mdl, Ts): 56 | """ Test a step response for 1/(s+1)""" 57 | # Static Gain 58 | K = 1 59 | # Time Constant. 60 | tau = 1 61 | sys = control.TransferFunction([K], [tau, 1]) 62 | sysd = control.c2d(sys, Ts) 63 | mdl.num = sysd.num[0][0] 64 | mdl.den = sysd.den[0][0] 65 | 66 | mdl.init_log() 67 | for step in range(int(10 * 1e3)): 68 | mdl.input_signal = 1 if step >= 1 / Ts else 0 69 | mdl.step_log() 70 | df = mdl.dataframe 71 | 72 | step_idx = np.where(df.input > 0)[0][0] 73 | tau1_idx = np.where(df.output < (1 - np.exp(-1 * tau)))[0][-1] 74 | tau2_idx = np.where(df.output < (1 - np.exp(-2 * tau)))[0][-1] 75 | assert np.isclose(df.time[tau1_idx] - df.time[step_idx], tau) 76 | assert np.isclose(df.time[tau2_idx] - df.time[step_idx], 2 * tau) 77 | -------------------------------------------------------------------------------- /Example3/README.md: -------------------------------------------------------------------------------- 1 | ### Example 3: [bouncing_ball.ipynb](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example3/bouncing_ball.ipynb) 2 | 3 | Adapted from [Mathworks's Simulation of a Bouncing Ball](https://www.mathworks.com/help/simulink/slref/simulation-of-a-bouncing-ball.html) 4 | 5 | ![](bouncing_ball.png) 6 | 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. 8 | 9 | `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. 10 | 11 | | Time Step | Simulink Duration (s) | Python Duration (s) | 12 | | --------- | --------------------- | ------------------- | 13 | | 1e-4 | 0.5905 | 0.06 | 14 | | 1e-5 | 1.0461 | 0.61 | 15 | | 1e-6 | 8.1991 | 6.08 | 16 | | 1e-7 | 78.9901 | 60.18 | 17 | -------------------------------------------------------------------------------- /Example3/bouncing_ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball.png -------------------------------------------------------------------------------- /Example3/bouncing_ball.slx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball.slx -------------------------------------------------------------------------------- /Example3/bouncing_ball_benchmark.m: -------------------------------------------------------------------------------- 1 | %% Benchmark Bouncing Ball Simulation 2 | 3 | gravitational_constant = Simulink.Parameter; 4 | gravitational_constant.Value = -9.81; 5 | gravitational_constant.CoderInfo.StorageClass='ExportedGlobal'; 6 | 7 | coefficient_of_restitution = Simulink.Parameter; 8 | coefficient_of_restitution.Value = -0.8; 9 | coefficient_of_restitution.CoderInfo.StorageClass='ExportedGlobal'; 10 | 11 | ball_position = Simulink.Signal; 12 | ball_position.CoderInfo.StorageClass='ExportedGlobal'; 13 | 14 | ball_velocity = Simulink.Signal; 15 | ball_velocity.CoderInfo.StorageClass='ExportedGlobal'; 16 | 17 | 18 | SimTime = Simulink.Signal; 19 | SimTime.CoderInfo.StorageClass='ExportedGlobal'; 20 | 21 | idx=1; 22 | results=zeros(4,10); 23 | for Ts = [1e-4, 1e-5, 1e-6, 1e-7] 24 | 25 | for i = 1:10 26 | tic 27 | sim('bouncing_ball', 25) 28 | results(idx, i) = toc; 29 | end 30 | idx=idx+1; 31 | end 32 | mean(results, 2) 33 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_build.m: -------------------------------------------------------------------------------- 1 | %% Model Builder 2 | 3 | % Close all models. 4 | bdclose('all'); 5 | % Clear matlab environment. 6 | clear; 7 | % Change to the build script folder 8 | cd(fileparts(mfilename('fullpath'))); 9 | 10 | % Determine model name from the build script name 11 | model = 'bouncing_ball'; 12 | % Run the model init script. 13 | feval([model '_init']); 14 | % Open the model. 15 | open_system(model); 16 | % 17 | rtwbuild(model); 18 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.bat: -------------------------------------------------------------------------------- 1 | @if not "%MINGW_ROOT%" == "" (@set "PATH=%PATH%;%MINGW_ROOT%") 2 | 3 | cd . 4 | 5 | if "%1"=="" ("C:\R2018b\bin\win64\gmake" -f bouncing_ball.mk all) else ("C:\R2018b\bin\win64\gmake" -f bouncing_ball.mk %1) 6 | @if errorlevel 1 goto error_exit 7 | 8 | exit /B 0 9 | 10 | :error_exit 11 | echo The make command returned an error of %errorlevel% 12 | An_error_occurred_during_the_call_to_make 13 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: bouncing_ball.c 3 | * 4 | * Code generated for Simulink model 'bouncing_ball'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 16:13:51 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #include "bouncing_ball.h" 17 | #include "bouncing_ball_private.h" 18 | 19 | /* Exported block signals */ 20 | real_T SimTime; /* '/Digital Clock' */ 21 | real32_T ball_position; /* '/Velocity Integrator' */ 22 | real32_T ball_velocity; /* '/Acceleration Integrator' */ 23 | 24 | /* Exported block parameters */ 25 | real32_T coefficient_of_restitution = -0.8F;/* Variable: coefficient_of_restitution 26 | * Referenced by: '/Constant1' 27 | */ 28 | real32_T gravitational_constant = -9.81F;/* Variable: gravitational_constant 29 | * Referenced by: '/Constant' 30 | */ 31 | 32 | /* Block states (default storage) */ 33 | DW_bouncing_ball_T bouncing_ball_DW; 34 | 35 | /* Real-time model */ 36 | RT_MODEL_bouncing_ball_T bouncing_ball_M_; 37 | RT_MODEL_bouncing_ball_T *const bouncing_ball_M = &bouncing_ball_M_; 38 | 39 | /* Model step function */ 40 | void bouncing_ball_step(void) 41 | { 42 | boolean_T rtb_Compare; 43 | int32_T IC2; 44 | real32_T IC; 45 | 46 | /* RelationalOperator: '/Compare' incorporates: 47 | * Constant: '/Constant' 48 | */ 49 | rtb_Compare = (bouncing_ball_DW.VelocityIntegrator_DSTATE <= 0.0F); 50 | 51 | /* InitialCondition: '/IC2' */ 52 | if (bouncing_ball_DW.IC2_FirstOutputTime) { 53 | bouncing_ball_DW.IC2_FirstOutputTime = false; 54 | IC2 = 10; 55 | } else { 56 | IC2 = 0; 57 | } 58 | 59 | /* End of InitialCondition: '/IC2' */ 60 | 61 | /* DiscreteIntegrator: '/Velocity Integrator' */ 62 | if (rtb_Compare && (bouncing_ball_DW.VelocityIntegrator_PrevResetSta <= 0)) { 63 | bouncing_ball_DW.VelocityIntegrator_DSTATE = (real32_T)IC2; 64 | } 65 | 66 | ball_position = bouncing_ball_DW.VelocityIntegrator_DSTATE; 67 | 68 | /* End of DiscreteIntegrator: '/Velocity Integrator' */ 69 | 70 | /* InitialCondition: '/IC' incorporates: 71 | * Constant: '/Constant1' 72 | * Product: '/Multiply' 73 | */ 74 | if (bouncing_ball_DW.IC_FirstOutputTime) { 75 | bouncing_ball_DW.IC_FirstOutputTime = false; 76 | IC = 15.0F; 77 | } else { 78 | IC = coefficient_of_restitution * 79 | bouncing_ball_DW.AccelerationIntegrator_DSTATE; 80 | } 81 | 82 | /* End of InitialCondition: '/IC' */ 83 | 84 | /* DiscreteIntegrator: '/Acceleration Integrator' */ 85 | if (rtb_Compare && (bouncing_ball_DW.AccelerationIntegrator_PrevRese <= 0)) { 86 | bouncing_ball_DW.AccelerationIntegrator_DSTATE = IC; 87 | } 88 | 89 | ball_velocity = bouncing_ball_DW.AccelerationIntegrator_DSTATE; 90 | 91 | /* End of DiscreteIntegrator: '/Acceleration Integrator' */ 92 | 93 | /* DigitalClock: '/Digital Clock' */ 94 | SimTime = ((bouncing_ball_M->Timing.clockTick0) * 0.001); 95 | 96 | /* Update for DiscreteIntegrator: '/Velocity Integrator' */ 97 | bouncing_ball_DW.VelocityIntegrator_DSTATE += 0.001F * ball_velocity; 98 | bouncing_ball_DW.VelocityIntegrator_PrevResetSta = (int8_T)rtb_Compare; 99 | 100 | /* Update for DiscreteIntegrator: '/Acceleration Integrator' incorporates: 101 | * Constant: '/Constant' 102 | */ 103 | bouncing_ball_DW.AccelerationIntegrator_DSTATE += 0.001F * 104 | gravitational_constant; 105 | bouncing_ball_DW.AccelerationIntegrator_PrevRese = (int8_T)rtb_Compare; 106 | 107 | /* Update absolute time for base rate */ 108 | /* The "clockTick0" counts the number of times the code of this task has 109 | * been executed. The resolution of this integer timer is 0.001, which is the step size 110 | * of the task. Size of "clockTick0" ensures timer will not overflow during the 111 | * application lifespan selected. 112 | */ 113 | bouncing_ball_M->Timing.clockTick0++; 114 | } 115 | 116 | /* Model initialize function */ 117 | void bouncing_ball_initialize(void) 118 | { 119 | /* Registration code */ 120 | 121 | /* initialize real-time model */ 122 | (void) memset((void *)bouncing_ball_M, 0, 123 | sizeof(RT_MODEL_bouncing_ball_T)); 124 | 125 | /* block I/O */ 126 | 127 | /* exported global signals */ 128 | SimTime = 0.0; 129 | ball_position = 0.0F; 130 | ball_velocity = 0.0F; 131 | 132 | /* states (dwork) */ 133 | (void) memset((void *)&bouncing_ball_DW, 0, 134 | sizeof(DW_bouncing_ball_T)); 135 | 136 | /* Start for InitialCondition: '/IC2' */ 137 | bouncing_ball_DW.IC2_FirstOutputTime = true; 138 | 139 | /* Start for InitialCondition: '/IC' */ 140 | bouncing_ball_DW.IC_FirstOutputTime = true; 141 | 142 | /* InitializeConditions for DiscreteIntegrator: '/Velocity Integrator' */ 143 | bouncing_ball_DW.VelocityIntegrator_DSTATE = 10.0F; 144 | bouncing_ball_DW.VelocityIntegrator_PrevResetSta = 2; 145 | 146 | /* InitializeConditions for DiscreteIntegrator: '/Acceleration Integrator' */ 147 | bouncing_ball_DW.AccelerationIntegrator_DSTATE = 15.0F; 148 | bouncing_ball_DW.AccelerationIntegrator_PrevRese = 2; 149 | } 150 | 151 | /* Model terminate function */ 152 | void bouncing_ball_terminate(void) 153 | { 154 | /* (no terminate code required) */ 155 | } 156 | 157 | /* 158 | * File trailer for generated code. 159 | * 160 | * [EOF] 161 | */ 162 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | bouncing_ball_M_ 3 | bouncing_ball_M 4 | bouncing_ball_initialize 5 | bouncing_ball_step 6 | bouncing_ball_terminate 7 | 8 | 9 | SimTime 10 | ball_position 11 | ball_velocity 12 | coefficient_of_restitution 13 | gravitational_constant 14 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: bouncing_ball.h 3 | * 4 | * Code generated for Simulink model 'bouncing_ball'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 16:13:51 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTW_HEADER_bouncing_ball_h_ 17 | #define RTW_HEADER_bouncing_ball_h_ 18 | #include 19 | #ifndef bouncing_ball_COMMON_INCLUDES_ 20 | # define bouncing_ball_COMMON_INCLUDES_ 21 | #include "rtwtypes.h" 22 | #endif /* bouncing_ball_COMMON_INCLUDES_ */ 23 | 24 | #include "bouncing_ball_types.h" 25 | 26 | /* Macros for accessing real-time model data structure */ 27 | #ifndef rtmGetErrorStatus 28 | # define rtmGetErrorStatus(rtm) ((rtm)->errorStatus) 29 | #endif 30 | 31 | #ifndef rtmSetErrorStatus 32 | # define rtmSetErrorStatus(rtm, val) ((rtm)->errorStatus = (val)) 33 | #endif 34 | 35 | /* Block states (default storage) for system '' */ 36 | typedef struct { 37 | real32_T VelocityIntegrator_DSTATE; /* '/Velocity Integrator' */ 38 | real32_T AccelerationIntegrator_DSTATE;/* '/Acceleration Integrator' */ 39 | int8_T VelocityIntegrator_PrevResetSta;/* '/Velocity Integrator' */ 40 | int8_T AccelerationIntegrator_PrevRese;/* '/Acceleration Integrator' */ 41 | boolean_T IC2_FirstOutputTime; /* '/IC2' */ 42 | boolean_T IC_FirstOutputTime; /* '/IC' */ 43 | } DW_bouncing_ball_T; 44 | 45 | /* Real-time Model Data Structure */ 46 | struct tag_RTM_bouncing_ball_T { 47 | const char_T * volatile errorStatus; 48 | 49 | /* 50 | * Timing: 51 | * The following substructure contains information regarding 52 | * the timing information for the model. 53 | */ 54 | struct { 55 | uint32_T clockTick0; 56 | } Timing; 57 | }; 58 | 59 | /* Block states (default storage) */ 60 | extern DW_bouncing_ball_T bouncing_ball_DW; 61 | 62 | /* 63 | * Exported Global Signals 64 | * 65 | * Note: Exported global signals are block signals with an exported global 66 | * storage class designation. Code generation will declare the memory for 67 | * these signals and export their symbols. 68 | * 69 | */ 70 | extern real_T SimTime; /* '/Digital Clock' */ 71 | extern real32_T ball_position; /* '/Velocity Integrator' */ 72 | extern real32_T ball_velocity; /* '/Acceleration Integrator' */ 73 | 74 | /* 75 | * Exported Global Parameters 76 | * 77 | * Note: Exported global parameters are tunable parameters with an exported 78 | * global storage class designation. Code generation will declare the memory for 79 | * these parameters and exports their symbols. 80 | * 81 | */ 82 | extern real32_T coefficient_of_restitution;/* Variable: coefficient_of_restitution 83 | * Referenced by: '/Constant1' 84 | */ 85 | extern real32_T gravitational_constant;/* Variable: gravitational_constant 86 | * Referenced by: '/Constant' 87 | */ 88 | 89 | /* Model entry point functions */ 90 | extern void bouncing_ball_initialize(void); 91 | extern void bouncing_ball_step(void); 92 | extern void bouncing_ball_terminate(void); 93 | 94 | /* Real-time Model object */ 95 | extern RT_MODEL_bouncing_ball_T *const bouncing_ball_M; 96 | 97 | /*- 98 | * These blocks were eliminated from the model due to optimizations: 99 | * 100 | * Block '/Scope' : Unused code path elimination 101 | */ 102 | 103 | /*- 104 | * The generated code includes comments that allow you to trace directly 105 | * back to the appropriate location in the model. The basic format 106 | * is /block_name, where system is the system number (uniquely 107 | * assigned by Simulink) and block_name is the name of the block. 108 | * 109 | * Use the MATLAB hilite_system command to trace the generated code back 110 | * to the model. For example, 111 | * 112 | * hilite_system('') - opens system 3 113 | * hilite_system('/Kp') - opens and selects block Kp which resides in S3 114 | * 115 | * Here is the system hierarchy for this model 116 | * 117 | * '' : 'bouncing_ball' 118 | * '' : 'bouncing_ball/Compare To Zero' 119 | */ 120 | #endif /* RTW_HEADER_bouncing_ball_h_ */ 121 | 122 | /* 123 | * File trailer for generated code. 124 | * 125 | * [EOF] 126 | */ 127 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.obj -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball.rsp: -------------------------------------------------------------------------------- 1 | bouncing_ball.obj 2 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball_comp.rsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball_comp.rsp -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: bouncing_ball_private.h 3 | * 4 | * Code generated for Simulink model 'bouncing_ball'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 16:13:51 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTW_HEADER_bouncing_ball_private_h_ 17 | #define RTW_HEADER_bouncing_ball_private_h_ 18 | #include "rtwtypes.h" 19 | #endif /* RTW_HEADER_bouncing_ball_private_h_ */ 20 | 21 | /* 22 | * File trailer for generated code. 23 | * 24 | * [EOF] 25 | */ 26 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball_ref.rsp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball_ref.rsp -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/bouncing_ball_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: bouncing_ball_types.h 3 | * 4 | * Code generated for Simulink model 'bouncing_ball'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 16:13:51 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTW_HEADER_bouncing_ball_types_h_ 17 | #define RTW_HEADER_bouncing_ball_types_h_ 18 | 19 | /* Forward declaration for rtModel */ 20 | typedef struct tag_RTM_bouncing_ball_T RT_MODEL_bouncing_ball_T; 21 | 22 | #endif /* RTW_HEADER_bouncing_ball_types_h_ */ 23 | 24 | /* 25 | * File trailer for generated code. 26 | * 27 | * [EOF] 28 | */ 29 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/codedescriptor.dmr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_ert_shrlib_rtw/codedescriptor.dmr -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/defines.txt: -------------------------------------------------------------------------------- 1 | MODEL=bouncing_ball 2 | NUMST=1 3 | NCSTATES=0 4 | HAVESTDIO 5 | MODEL_HAS_DYNAMICALLY_LOADED_SFCNS=0 6 | CLASSIC_INTERFACE=0 7 | ALLOCATIONFCN=0 8 | TID01EQ=0 9 | TERMFCN=1 10 | ONESTEPFCN=1 11 | MAT_FILE=0 12 | MULTI_INSTANCE_CODE=0 13 | INTEGER_CODE=0 14 | MT=0 15 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/ert_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: ert_main.c 3 | * 4 | * Code generated for Simulink model 'bouncing_ball'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 16:13:51 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #include 17 | #include /* This ert_main.c example uses printf/fflush */ 18 | #include "bouncing_ball.h" /* Model's header file */ 19 | #include "rtwtypes.h" 20 | 21 | /* 22 | * Associating rt_OneStep with a real-time clock or interrupt service routine 23 | * is what makes the generated code "real-time". The function rt_OneStep is 24 | * always associated with the base rate of the model. Subrates are managed 25 | * by the base rate from inside the generated code. Enabling/disabling 26 | * interrupts and floating point context switches are target specific. This 27 | * example code indicates where these should take place relative to executing 28 | * the generated code step function. Overrun behavior should be tailored to 29 | * your application needs. This example simply sets an error status in the 30 | * real-time model and returns from rt_OneStep. 31 | */ 32 | void rt_OneStep(void); 33 | void rt_OneStep(void) 34 | { 35 | static boolean_T OverrunFlag = false; 36 | 37 | /* Disable interrupts here */ 38 | 39 | /* Check for overrun */ 40 | if (OverrunFlag) { 41 | rtmSetErrorStatus(bouncing_ball_M, "Overrun"); 42 | return; 43 | } 44 | 45 | OverrunFlag = true; 46 | 47 | /* Save FPU context here (if necessary) */ 48 | /* Re-enable timer or interrupt here */ 49 | /* Set model inputs here */ 50 | 51 | /* Step the model */ 52 | bouncing_ball_step(); 53 | 54 | /* Get model outputs here */ 55 | 56 | /* Indicate task complete */ 57 | OverrunFlag = false; 58 | 59 | /* Disable interrupts here */ 60 | /* Restore FPU context here (if necessary) */ 61 | /* Enable interrupts here */ 62 | } 63 | 64 | /* 65 | * The example "main" function illustrates what is required by your 66 | * application code to initialize, execute, and terminate the generated code. 67 | * Attaching rt_OneStep to a real-time clock is target specific. This example 68 | * illustrates how you do this relative to initializing the model. 69 | */ 70 | int_T main(int_T argc, const char *argv[]) 71 | { 72 | /* Unused arguments */ 73 | (void)(argc); 74 | (void)(argv); 75 | 76 | /* Initialize model */ 77 | bouncing_ball_initialize(); 78 | 79 | /* Attach rt_OneStep to a timer or interrupt service routine with 80 | * period 0.001 seconds (the model's base sample time) here. The 81 | * call syntax for rt_OneStep is 82 | * 83 | * rt_OneStep(); 84 | */ 85 | printf("Warning: The simulation will run forever. " 86 | "Generated ERT main won't simulate model step behavior. " 87 | "To change this behavior select the 'MAT-file logging' option.\n"); 88 | fflush((NULL)); 89 | while (rtmGetErrorStatus(bouncing_ball_M) == (NULL)) { 90 | /* Perform other application tasks here */ 91 | } 92 | 93 | /* Disable rt_OneStep() here */ 94 | 95 | /* Terminate model */ 96 | bouncing_ball_terminate(); 97 | return 0; 98 | } 99 | 100 | /* 101 | * File trailer for generated code. 102 | * 103 | * [EOF] 104 | */ 105 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_codegen_rpt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bouncing_ball Code Generation Report 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_coderassumptions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Coder Assumptions for 'bouncing_ball' 5 | 6 | 7 | 8 | 9 |

10 | Coder Assumptions for 'bouncing_ball' 11 |

12 |
13 |

14 | List of assumptions that you can check and expected results for selected target environment. For more information see, Verification of Code Generation Assumptions. 15 |

16 |
17 |
18 | 19 |
20 |

21 | C Language Configuration for MATLAB Host Target Hardware 22 |

23 | 24 | 25 | 154 | 155 | 156 | 157 |
26 |

27 | 28 | 29 | 32 | 35 | 36 | 37 | 38 | 41 | 44 | 45 | 46 | 47 | 50 | 53 | 54 | 55 | 56 | 59 | 62 | 63 | 64 | 65 | 68 | 71 | 72 | 73 | 74 | 77 | 80 | 81 | 82 | 83 | 86 | 89 | 90 | 91 | 92 | 95 | 98 | 99 | 100 | 101 | 104 | 107 | 108 | 109 | 110 | 113 | 116 | 117 | 118 | 119 |
30 | BitPerChar 31 | 33 | 8 34 |
39 | BitPerShort 40 | 42 | 16 43 |
48 | BitPerInt 49 | 51 | 32 52 |
57 | BitPerLong 58 | 60 | 32 61 |
66 | BitPerLongLong 67 | 69 | 64 70 |
75 | BitPerFloat 76 | 78 | 32 79 |
84 | BitPerDouble 85 | 87 | 64 88 |
93 | BitPerPointer 94 | 96 | 64 97 |
102 | BitPerSizeT 103 | 105 | 64 106 |
111 | BitPerPtrDiffT 112 | 114 | 64 115 |
120 |
121 | 122 | 125 | 128 | 129 | 130 | 131 | 134 | 137 | 138 | 139 | 140 | 143 | 146 | 147 | 148 | 149 |
123 | Endianess 124 | 126 | LittleEndian 127 |
132 | Shift right for signed integer is arithmetic shift 133 | 135 | True 136 |
141 | Signed integer division rounds to 142 | 144 | Zero 145 |
150 | 151 |

152 | 153 |
158 |

159 | Floating-Point Numbers 160 |

161 | 162 | 163 | 196 | 197 | 198 | 199 |
164 |

165 | Code generation is configured to support floating-point numbers, therefore your target environment might perform subnormal number calculations. 166 |

167 |

168 | 169 | 170 | 173 | 176 | 177 | 178 | 179 | 182 | 185 | 186 | 187 | 188 |
171 | Flush-to-zero computed subnormal values (FTZ) 172 | 174 | False 175 |
180 | Flush-to-zero incoming subnormal values (DAZ) 181 | 183 | False 184 |
189 | 190 |

191 |

192 | If the assumptions are not correct, subnormal numbers might cause mismatches between model and generated code simulation results. For more information see, Subnormal Number Performance. 193 |

194 | 195 |
200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 42 | 43 | 44 | 45 | 51 | 52 | 53 | 54 | 60 | 61 | 62 | 63 | 69 | 70 | 71 | 72 | 78 | 79 | 80 | 81 | 87 | 88 | 89 | 90 | 96 | 97 | 98 | 99 | 105 | 106 | 107 | 108 |
28 | 29 | Contents 30 | 31 | 32 |
37 | 40 | 41 |
46 | 47 | Summary 48 | 49 | 50 |
55 | 56 | Subsystem Report 57 | 58 | 59 |
64 | 65 | Code Interface Report 66 | 67 | 68 |
73 | 74 | Traceability Report 75 | 76 | 77 |
82 | 83 | Static Code Metrics Report 84 | 85 | 86 |
91 | 92 | Code Replacements Report 93 | 94 | 95 |
100 | 101 | Coder Assumptions 102 | 103 | 104 |
109 |
110 | 111 | 117 | 118 | 119 | 120 | 156 | 157 | 158 | 159 | 222 | 223 | 224 | 225 | 261 | 262 | 263 | 264 |
112 | 113 | Generated Code 114 | 115 | 116 |
121 | 122 | 123 | 126 | 129 | 130 | 131 | 132 | 135 | 150 | 151 | 152 | 153 |
124 | [-] 125 | 127 | Main file 128 |
133 | 134 | 136 | 137 | 138 | 144 | 145 | 146 | 147 |
139 | 140 | ert_main.c 141 | 142 | 143 |
148 | 149 |
154 | 155 |
160 | 161 | 162 | 165 | 168 | 169 | 170 | 171 | 174 | 216 | 217 | 218 | 219 |
163 | [-] 164 | 166 | Model files 167 |
172 | 173 | 175 | 176 | 177 | 183 | 184 | 185 | 186 | 192 | 193 | 194 | 195 | 201 | 202 | 203 | 204 | 210 | 211 | 212 | 213 |
178 | 179 | bouncing_ball.c 180 | 181 | 182 |
187 | 188 | bouncing_ball.h 189 | 190 | 191 |
196 | 197 | bouncing_ball_private.h 198 | 199 | 200 |
205 | 206 | bouncing_ball_types.h 207 | 208 | 209 |
214 | 215 |
220 | 221 |
226 | 227 | 228 | 231 | 234 | 235 | 236 | 237 | 240 | 255 | 256 | 257 | 258 |
229 | [+] 230 | 232 | Utility files (1) 233 |
238 | 239 | 241 | 242 | 243 | 249 | 250 | 251 | 252 | 253 | 254 |
259 | 260 |
265 |
266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_interface.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code Interface Report for bouncing_ball 5 | 6 | 7 | 8 | 9 |

10 | Code Interface Report for bouncing_ball 11 |

12 |

13 | Table of Contents 14 |

15 | 48 |

49 | 50 | Entry-Point Functions 51 | 52 | 53 |

54 |

55 | Function: bouncing_ball_initialize 56 |

57 | 58 | 59 | 62 | 68 | 69 | 70 | 71 | 74 | 77 | 78 | 79 | 80 | 83 | 86 | 87 | 88 | 89 | 92 | 95 | 96 | 97 | 98 | 101 | 104 | 105 | 106 | 107 | 110 | 113 | 114 | 115 | 116 |
60 | Prototype 61 | 63 | 64 | void bouncing_ball_initialize(void) 65 | 66 | 67 |
72 | Description 73 | 75 | Initialization entry point of generated code 76 |
81 | Timing 82 | 84 | Must be called exactly once 85 |
90 | Arguments 91 | 93 | None 94 |
99 | Return value 100 | 102 | None 103 |
108 | Header file 109 | 111 | bouncing_ball.h 112 |
117 |

118 | Function: bouncing_ball_step 119 |

120 | 121 | 122 | 125 | 131 | 132 | 133 | 134 | 137 | 140 | 141 | 142 | 143 | 146 | 149 | 150 | 151 | 152 | 155 | 158 | 159 | 160 | 161 | 164 | 167 | 168 | 169 | 170 | 173 | 176 | 177 | 178 | 179 |
123 | Prototype 124 | 126 | 127 | void bouncing_ball_step(void) 128 | 129 | 130 |
135 | Description 136 | 138 | Output entry point of generated code 139 |
144 | Timing 145 | 147 | Must be called periodically, every 0.001 seconds 148 |
153 | Arguments 154 | 156 | None 157 |
162 | Return value 163 | 165 | None 166 |
171 | Header file 172 | 174 | bouncing_ball.h 175 |
180 |

181 | Function: bouncing_ball_terminate 182 |

183 | 184 | 185 | 188 | 194 | 195 | 196 | 197 | 200 | 203 | 204 | 205 | 206 | 209 | 212 | 213 | 214 | 215 | 218 | 221 | 222 | 223 | 224 | 227 | 230 | 231 | 232 | 233 | 236 | 239 | 240 | 241 | 242 |
186 | Prototype 187 | 189 | 190 | void bouncing_ball_terminate(void) 191 | 192 | 193 |
198 | Description 199 | 201 | Termination entry point of generated code 202 |
207 | Timing 208 | 210 | Must be called exactly once 211 |
216 | Arguments 217 | 219 | None 220 |
225 | Return value 226 | 228 | None 229 |
234 | Header file 235 | 237 | bouncing_ball.h 238 |
243 |

244 | 245 | Inports 246 | 247 | 248 |

249 |

250 | No Inports in model. 251 |

252 |

253 | 254 | Outports 255 | 256 | 257 |

258 |

259 | No Outports in model. 260 |

261 |

262 | 263 | Interface Parameters 264 | 265 | 266 |

267 | 268 | 269 | 275 | 281 | 287 | 293 | 294 | 295 | 296 | 299 | 302 | 305 | 308 | 309 | 310 | 311 | 314 | 317 | 320 | 323 | 324 | 325 | 326 |
270 | 271 | Parameter Source 272 | 273 | 274 | 276 | 277 | Code Identifier 278 | 279 | 280 | 282 | 283 | Data Type 284 | 285 | 286 | 288 | 289 | Dimension 290 | 291 | 292 |
297 | coefficient_of_restitution 298 | 300 | coefficient_of_restitution 301 | 303 | real32_T 304 | 306 | 1 307 |
312 | gravitational_constant 313 | 315 | gravitational_constant 316 | 318 | real32_T 319 | 321 | 1 322 |
327 |

328 | 329 | Data Stores 330 | 331 | 332 |

333 |

334 | No data stores in the model; note that this report lists only data stores with non-auto storage class and global data stores 335 |

336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_metrics.html: -------------------------------------------------------------------------------- 1 | Static Code Metrics Report for bouncing_ball 2 | 3 | 4 | 5 |

Static Code Metrics Report for bouncing_ball

6 |

Static Code Metrics report is not generated. On the Configuration Parameters > Code Generation > Report pane, select Static code metrics. On the model diagram window, select Code > C/C++ Code > Code Generation Report > Open Model Report or rebuild the model.

7 | 8 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_private_h.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 
13 | 
14 | 
15 | 
16 | 
17 | 
18 | 
19 | 
20 | 
21 | 
22 | 
23 | 
24 | 
25 | 
26 | 
27 | 
28 | 
29 | 
30 | 
31 | 
32 | 
33 | 
34 | 
35 | 
36 | 
37 | 
38 | 
39 | 
40 | 
41 | 
42 | 
43 | 
44 | 
45 | 
46 | 
47 | 
48 | 
49 | 
50 | 
51 | 
52 | 
53 | 
54 | 
55 | 
56 | 
57 | 
58 | 
59 | 
60 | 
61 | 
62 | 
63 | 
64 | 
65 | 
1/*
2 * File: bouncing_ball_private.h
3 *
4 * Code generated for Simulink model 'bouncing_ball'.
5 *
6 * Model version : 1.20
7 * Simulink Coder version : 9.0 (R2018b) 24-May-2018
8 * C/C++ source code generated on : Sat Feb 6 16:13:51 2021
9 *
10 * Target selection: ert_shrlib.tlc
11 * Embedded hardware selection: Intel->x86-64 (Windows64)
12 * Code generation objectives: Unspecified
13 * Validation result: Not run
14 */
15
16#ifndef RTW_HEADER_bouncing_ball_private_h_
17#define RTW_HEADER_bouncing_ball_private_h_
18#include "rtwtypes.h"
19#endif /* RTW_HEADER_bouncing_ball_private_h_ */
20
21/*
22 * File trailer for generated code.
23 *
24 * [EOF]
25 */
26
66 |
67 | 68 | 69 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_replacements.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code replacements in bouncing_ball 5 | 6 | 7 | 8 | 9 |

10 | Code replacements in bouncing_ball 11 |

12 |
13 | 14 |
15 | Code replacements report not generated. Select 'Summarize which blocks triggered code replacements'. 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_subsystems.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Non-virtual subsystems in bouncing_ball 5 | 6 | 7 | 8 | 9 |

10 | Non-virtual subsystems in bouncing_ball 11 |

12 |
13 | 14 |
15 |
16 | 17 |
18 |

19 | 1. Code Mapping [hide] 20 |

21 | 22 | 23 | 38 | 39 | 40 | 41 | 47 | 48 | 49 | 50 |
24 |

25 | The following table:

    26 |
  • 27 | provides a mapping from the non-virtual subsystems in the model to functions or reusable functions in the generated code and 28 |
  • 29 |
  • 30 | notes exceptions that caused some non-virtual subsystems to not reuse code even though they were assigned a function packaging setting ('Function packaging' entry on the Subsystem Block Dialog) of 'Auto' or 'Reusable function'. 31 |
  • 32 | 33 |
34 | 35 |

36 | 37 |
42 | 43 | No non-virtual subsystems generating functions in model 44 | 45 | 46 |
51 |

52 | 2. Code Reuse Exceptions [hide] 53 |

54 | 55 | 56 | 74 | 75 | 76 | 77 | 80 | 81 | 82 | 83 |
57 |

58 | The following section provides details on each exception that caused a non-virtual subsystem with a function packaging setting of

    59 |
  • 60 | 'Auto' to become an inlined code segment, 61 |
  • 62 |
  • 63 | 'Auto' to become a non-reusable function without arguments, or 64 |
  • 65 |
  • 66 | 'Reusable function' to become a non-reusable function without arguments. 67 |
  • 68 | 69 |
70 | Note:This section does not report graphically identical non-virtual subsystems marked as 'Auto' that were not reused due to differences in their functional properties (such as dimensions, datatypes, work vectors, parameters, etc.). You may identify reasons for non-reuse in such cases by inspecting the differences in the functional attributes of the subsystems in the model or in the inlined generated code. 71 |

72 | 73 |
78 |
No reuse exception in model 79 |
84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_survey.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Code Generation Report for 'bouncing_ball' 5 | 6 | 7 | 8 | 9 |

10 | Code Generation Report for 'bouncing_ball' 11 |

12 |
13 | 14 |
15 |
16 | 17 |
18 |

19 | Model Information 20 |

21 | 22 | 23 | 74 | 75 | 76 | 77 |
24 |

25 | 26 | 27 | 30 | 33 | 34 | 35 | 36 | 39 | 42 | 43 | 44 | 45 | 48 | 51 | 52 | 53 | 54 | 57 | 60 | 61 | 62 | 63 |
28 | Author 29 | 31 | user 32 |
37 | Last Modified By 38 | 40 | user 41 |
46 | Model Version 47 | 49 | 1.20 50 |
55 | Tasking Mode 56 | 58 | SingleTasking 59 |
64 |
67 | 68 | Configuration settings at time of code generation 69 | 70 | 71 |

72 | 73 |
78 |

79 | Code Information 80 |

81 | 82 | 83 | 161 | 162 | 163 | 164 |
84 |

85 | 86 | 87 | 90 | 93 | 94 | 95 | 96 | 99 | 102 | 103 | 104 | 105 | 108 | 111 | 112 | 113 | 114 | 117 | 120 | 121 | 122 | 123 | 126 | 129 | 130 | 131 | 132 | 135 | 138 | 139 | 140 | 141 | 144 | 153 | 154 | 155 | 156 |
88 | System Target File 89 | 91 | ert_shrlib.tlc 92 |
97 | Hardware Device Type 98 | 100 | Intel->x86-64 (Windows64) 101 |
106 | Simulink Coder Version 107 | 109 | 9.0 (R2018b) 24-May-2018 110 |
115 | Timestamp of Generated Source Code 116 | 118 | Sat Feb 6 16:13:51 2021 119 |
124 | 125 | 127 | 128 |
133 | Type of Build 134 | 136 | Model 137 |
142 | Objectives Specified 143 | 145 | 146 | 147 | Unspecified 148 | 149 | 150 | 151 | 152 |
157 | 158 |

159 | 160 |
165 |

166 | Additional Information 167 |

168 | 169 | 170 | 185 | 186 | 187 | 188 |
171 | 172 | 173 | 176 | 179 | 180 | 181 | 182 |
174 | Code Generation Advisor 175 | 177 | Not run 178 |
183 | 184 |
189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_trace.html: -------------------------------------------------------------------------------- 1 | Traceability Report for bouncing_ball 2 | 3 | 4 | 25 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_traceInfo.js: -------------------------------------------------------------------------------- 1 | function RTW_rtwnameSIDMap() { 2 | this.rtwnameHashMap = new Array(); 3 | this.sidHashMap = new Array(); 4 | this.rtwnameHashMap[""] = {sid: "bouncing_ball"}; 5 | this.sidHashMap["bouncing_ball"] = {rtwname: ""}; 6 | this.rtwnameHashMap[""] = {sid: "bouncing_ball:10"}; 7 | this.sidHashMap["bouncing_ball:10"] = {rtwname: ""}; 8 | this.rtwnameHashMap["/Acceleration Integrator"] = {sid: "bouncing_ball:3"}; 9 | this.sidHashMap["bouncing_ball:3"] = {rtwname: "/Acceleration Integrator"}; 10 | this.rtwnameHashMap["/Compare To Zero"] = {sid: "bouncing_ball:10"}; 11 | this.sidHashMap["bouncing_ball:10"] = {rtwname: "/Compare To Zero"}; 12 | this.rtwnameHashMap["/Constant"] = {sid: "bouncing_ball:1"}; 13 | this.sidHashMap["bouncing_ball:1"] = {rtwname: "/Constant"}; 14 | this.rtwnameHashMap["/Constant1"] = {sid: "bouncing_ball:14"}; 15 | this.sidHashMap["bouncing_ball:14"] = {rtwname: "/Constant1"}; 16 | this.rtwnameHashMap["/Digital Clock"] = {sid: "bouncing_ball:20"}; 17 | this.sidHashMap["bouncing_ball:20"] = {rtwname: "/Digital Clock"}; 18 | this.rtwnameHashMap["/Ground"] = {sid: "bouncing_ball:8"}; 19 | this.sidHashMap["bouncing_ball:8"] = {rtwname: "/Ground"}; 20 | this.rtwnameHashMap["/IC"] = {sid: "bouncing_ball:4"}; 21 | this.sidHashMap["bouncing_ball:4"] = {rtwname: "/IC"}; 22 | this.rtwnameHashMap["/IC2"] = {sid: "bouncing_ball:9"}; 23 | this.sidHashMap["bouncing_ball:9"] = {rtwname: "/IC2"}; 24 | this.rtwnameHashMap["/Multiply"] = {sid: "bouncing_ball:15"}; 25 | this.sidHashMap["bouncing_ball:15"] = {rtwname: "/Multiply"}; 26 | this.rtwnameHashMap["/Scope"] = {sid: "bouncing_ball:12"}; 27 | this.sidHashMap["bouncing_ball:12"] = {rtwname: "/Scope"}; 28 | this.rtwnameHashMap["/Terminator"] = {sid: "bouncing_ball:11"}; 29 | this.sidHashMap["bouncing_ball:11"] = {rtwname: "/Terminator"}; 30 | this.rtwnameHashMap["/Terminator1"] = {sid: "bouncing_ball:22"}; 31 | this.sidHashMap["bouncing_ball:22"] = {rtwname: "/Terminator1"}; 32 | this.rtwnameHashMap["/Velocity Integrator"] = {sid: "bouncing_ball:7"}; 33 | this.sidHashMap["bouncing_ball:7"] = {rtwname: "/Velocity Integrator"}; 34 | this.rtwnameHashMap["/u"] = {sid: "bouncing_ball:10:1"}; 35 | this.sidHashMap["bouncing_ball:10:1"] = {rtwname: "/u"}; 36 | this.rtwnameHashMap["/Compare"] = {sid: "bouncing_ball:10:2"}; 37 | this.sidHashMap["bouncing_ball:10:2"] = {rtwname: "/Compare"}; 38 | this.rtwnameHashMap["/Constant"] = {sid: "bouncing_ball:10:3"}; 39 | this.sidHashMap["bouncing_ball:10:3"] = {rtwname: "/Constant"}; 40 | this.rtwnameHashMap["/y"] = {sid: "bouncing_ball:10:5"}; 41 | this.sidHashMap["bouncing_ball:10:5"] = {rtwname: "/y"}; 42 | this.getSID = function(rtwname) { return this.rtwnameHashMap[rtwname];} 43 | this.getRtwname = function(sid) { return this.sidHashMap[sid];} 44 | } 45 | RTW_rtwnameSIDMap.instance = new RTW_rtwnameSIDMap(); 46 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/bouncing_ball_types_h.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 
13 | 
14 | 
15 | 
16 | 
17 | 
18 | 
19 | 
20 | 
21 | 
22 | 
23 | 
24 | 
25 | 
26 | 
27 | 
28 | 
29 | 
30 | 
31 | 
32 | 
33 | 
34 | 
35 | 
36 | 
37 | 
38 | 
39 | 
40 | 
41 | 
42 | 
43 | 
44 | 
45 | 
46 | 
47 | 
48 | 
49 | 
50 | 
51 | 
52 | 
53 | 
54 | 
55 | 
56 | 
57 | 
58 | 
59 | 
60 | 
61 | 
62 | 
63 | 
64 | 
65 | 
66 | 
67 | 
68 | 
69 | 
70 | 
71 | 
1/*
2 * File: bouncing_ball_types.h
3 *
4 * Code generated for Simulink model 'bouncing_ball'.
5 *
6 * Model version : 1.20
7 * Simulink Coder version : 9.0 (R2018b) 24-May-2018
8 * C/C++ source code generated on : Sat Feb 6 16:13:51 2021
9 *
10 * Target selection: ert_shrlib.tlc
11 * Embedded hardware selection: Intel->x86-64 (Windows64)
12 * Code generation objectives: Unspecified
13 * Validation result: Not run
14 */
15
16#ifndef RTW_HEADER_bouncing_ball_types_h_
17#define RTW_HEADER_bouncing_ball_types_h_
18
19/* Forward declaration for rtModel */
20typedef struct tag_RTM_bouncing_ball_T RT_MODEL_bouncing_ball_T;
21
22#endif /* RTW_HEADER_bouncing_ball_types_h_ */
23
24/*
25 * File trailer for generated code.
26 *
27 * [EOF]
28 */
29
72 |
73 | 74 | 75 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/css/coder_app.css: -------------------------------------------------------------------------------- 1 | /* Copyright 2013-2014 The MathWorks, Inc. */ 2 | pre#code { 3 | font-family: Consolas, Courier; 4 | font-size: small; 5 | } 6 | 7 | .ct { 8 | font-style: italic; 9 | color: #117755 10 | } /* comment */ 11 | .pp { 12 | font-weight:bold; 13 | color: #992211 14 | } /* preprocessor */ 15 | .kw, .br { 16 | font-weight:bold; 17 | color: #112266 18 | } /* keyword or brace */ 19 | .dt { 20 | font-weight:bold; 21 | color: #112266 22 | } /* data type */ 23 | .tk { 24 | font-style: normal; 25 | color: #112266 26 | } /* regular token */ 27 | pre#code a.req { 28 | text-decoration: none; 29 | color: #112266 30 | } 31 | pre#code a.req_active { 32 | cursor: pointer; 33 | text-decoration: underline; 34 | } 35 | pre#code a.req_active:hover { 36 | cursor: pointer; 37 | color: blue; 38 | text-decoration: underline 39 | } 40 | pre#code a.blk { 41 | text-decoration: none; 42 | } 43 | pre#code a.blk_active { 44 | cursor: pointer; 45 | text-decoration: underline; 46 | } 47 | pre#code a.blk_active:hover { 48 | cursor: pointer; 49 | color: blue; 50 | text-decoration: underline 51 | } 52 | a.hilite { 53 | font-style: normal; 54 | color: black; 55 | background-color: #ffff99; 56 | } /* highlight token */ 57 | tr.hilite { 58 | font-style: normal; 59 | color: black; 60 | background-color: #aff 61 | } /* highlight row */ 62 | a.hiliteToken, tr.hiliteToken, td.hiliteToken { 63 | background-color: #ffff99; 64 | } 65 | .hiliteCurrentLine, tr.hiliteCurrentLine > td { 66 | font-style: normal; 67 | color: black; 68 | background-color: #aff; 69 | border-top: dashed darkblue 1px; 70 | border-bottom: dashed darkblue 1px; 71 | } 72 | tr.hiliteCurrentLine > td:first-child { 73 | border-left: dashed darkblue 1px; 74 | } 75 | tr.hiliteCurrentLine > td:last-child { 76 | border-right: dashed darkblue 1px; 77 | } 78 | 79 | span.hiliteTotalLine { 80 | font-style: normal; 81 | color: #aff; 82 | } 83 | span.hiliteCurrentLine { 84 | font-style: normal; 85 | color: #ffff99; 86 | } 87 | a.tk { 88 | text-decoration: none; 89 | } 90 | a.tk:hover { 91 | text-decoration: none; 92 | } 93 | a.active { 94 | text-decoration: underline; 95 | } 96 | a.active:hover { 97 | cursor: pointer; 98 | color: blue; 99 | text-decoration: underline 100 | } /* hyperlink */ 101 | table.code { 102 | border: 0px 103 | } 104 | table.code td { 105 | vertical-align: top; 106 | } 107 | table.code td.highlightedCurrent { 108 | background-color: #819FF7; 109 | } 110 | table.code > tr:first { 111 | text-align: right; 112 | } /* hyperlink */ 113 | 114 | ul.popup_attrib_list { 115 | list-style-type:none; 116 | display: block; 117 | margin: 0; 118 | padding: 0; 119 | } 120 | ul.popup_attrib_list li { 121 | list-style-type:none; 122 | display: inline; 123 | margin: 0 18px 0 0; 124 | padding: 0; 125 | } 126 | .highlighted { 127 | background-color:yellow; 128 | } 129 | a:class1 { 130 | color: -webkit-link; 131 | text-decoration: underline; 132 | cursor: hand; 133 | } 134 | .scroll 135 | { 136 | height:80px; 137 | overflow:scroll; 138 | overflow-x:hidden; 139 | } 140 | div#popup_window { 141 | position: absolute; 142 | background-color: rgb(203,203,255); 143 | border: solid 3px #ECECEC; 144 | border-radius: 5px; 145 | /* shadow box around the window*/ 146 | -moz-box-shadow: 0 3px 3px rgba(0,0,0,0.4), inset 0 1px #FFF; 147 | -webkit-box-shadow: 0 3px 3px rgba(0,0,0,0.4), inset 0 1px #FFF; 148 | box-shadow: 0 3px 3px rgba(0,0,0,0.4), inset 0 1px #FFF; 149 | padding: 2px; 150 | } 151 | div#popup_window a { 152 | text-decoration: none; 153 | color: green; 154 | } 155 | div#popup_window a:hover { 156 | cursor: pointer; 157 | text-decoration: underline; 158 | color: blue; 159 | } 160 | div#popup_window tr.selected { 161 | background-color: #ffff99; 162 | } 163 | div#token_usage_nav { 164 | border-bottom: 1px solid gray; 165 | } 166 | table#token_usage_details { 167 | cellpadding: 100px; 168 | table-layout:fixed; 169 | border: 0px; 170 | } 171 | .token_usage_details_tabrow { 172 | width: 40px; 173 | } 174 | table#token_usage_details td { 175 | padding-right: 5em; 176 | padding-left: 1em; 177 | } 178 | .token_usage_details_tabrow:hover { 179 | background-color: gray; 180 | } 181 | .nav_table td.hidden { 182 | display: none; 183 | } 184 | table#codeTbl tr td { 185 | color: #112266 186 | } 187 | table#codeTbl tr td { 188 | padding-left: 10px; 189 | } 190 | table#codeTbl tr td:first-child { 191 | font-style: italic; 192 | color: #888888; 193 | text-align: right; 194 | padding-left:0px; 195 | } 196 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/define.js: -------------------------------------------------------------------------------- 1 | function CodeDefine() { 2 | this.def = new Array(); 3 | this.def["rt_OneStep"] = {file: "ert_main_c.html",line:33,type:"fcn"};this.def["main"] = {file: "ert_main_c.html",line:70,type:"fcn"};this.def["SimTime"] = {file: "bouncing_ball_c.html",line:20,type:"var"};this.def["ball_position"] = {file: "bouncing_ball_c.html",line:21,type:"var"};this.def["ball_velocity"] = {file: "bouncing_ball_c.html",line:22,type:"var"};this.def["coefficient_of_restitution"] = {file: "bouncing_ball_c.html",line:25,type:"var"};this.def["gravitational_constant"] = {file: "bouncing_ball_c.html",line:28,type:"var"};this.def["bouncing_ball_DW"] = {file: "bouncing_ball_c.html",line:33,type:"var"};this.def["bouncing_ball_M_"] = {file: "bouncing_ball_c.html",line:36,type:"var"};this.def["bouncing_ball_M"] = {file: "bouncing_ball_c.html",line:37,type:"var"};this.def["bouncing_ball_step"] = {file: "bouncing_ball_c.html",line:40,type:"fcn"};this.def["bouncing_ball_initialize"] = {file: "bouncing_ball_c.html",line:117,type:"fcn"};this.def["bouncing_ball_terminate"] = {file: "bouncing_ball_c.html",line:152,type:"fcn"};this.def["DW_bouncing_ball_T"] = {file: "bouncing_ball_h.html",line:43,type:"type"};this.def["RT_MODEL_bouncing_ball_T"] = {file: "bouncing_ball_types_h.html",line:20,type:"type"};this.def["int8_T"] = {file: "rtwtypes_h.html",line:47,type:"type"};this.def["uint8_T"] = {file: "rtwtypes_h.html",line:48,type:"type"};this.def["int16_T"] = {file: "rtwtypes_h.html",line:49,type:"type"};this.def["uint16_T"] = {file: "rtwtypes_h.html",line:50,type:"type"};this.def["int32_T"] = {file: "rtwtypes_h.html",line:51,type:"type"};this.def["uint32_T"] = {file: "rtwtypes_h.html",line:52,type:"type"};this.def["int64_T"] = {file: "rtwtypes_h.html",line:53,type:"type"};this.def["uint64_T"] = {file: "rtwtypes_h.html",line:54,type:"type"};this.def["real32_T"] = {file: "rtwtypes_h.html",line:55,type:"type"};this.def["real64_T"] = {file: "rtwtypes_h.html",line:56,type:"type"};this.def["real_T"] = {file: "rtwtypes_h.html",line:62,type:"type"};this.def["time_T"] = {file: "rtwtypes_h.html",line:63,type:"type"};this.def["boolean_T"] = {file: "rtwtypes_h.html",line:64,type:"type"};this.def["int_T"] = {file: "rtwtypes_h.html",line:65,type:"type"};this.def["uint_T"] = {file: "rtwtypes_h.html",line:66,type:"type"};this.def["ulong_T"] = {file: "rtwtypes_h.html",line:67,type:"type"};this.def["ulonglong_T"] = {file: "rtwtypes_h.html",line:68,type:"type"};this.def["char_T"] = {file: "rtwtypes_h.html",line:69,type:"type"};this.def["uchar_T"] = {file: "rtwtypes_h.html",line:70,type:"type"};this.def["byte_T"] = {file: "rtwtypes_h.html",line:71,type:"type"};this.def["creal32_T"] = {file: "rtwtypes_h.html",line:81,type:"type"};this.def["creal64_T"] = {file: "rtwtypes_h.html",line:86,type:"type"};this.def["creal_T"] = {file: "rtwtypes_h.html",line:91,type:"type"};this.def["cint8_T"] = {file: "rtwtypes_h.html",line:98,type:"type"};this.def["cuint8_T"] = {file: "rtwtypes_h.html",line:105,type:"type"};this.def["cint16_T"] = {file: "rtwtypes_h.html",line:112,type:"type"};this.def["cuint16_T"] = {file: "rtwtypes_h.html",line:119,type:"type"};this.def["cint32_T"] = {file: "rtwtypes_h.html",line:126,type:"type"};this.def["cuint32_T"] = {file: "rtwtypes_h.html",line:133,type:"type"};this.def["cint64_T"] = {file: "rtwtypes_h.html",line:140,type:"type"};this.def["cuint64_T"] = {file: "rtwtypes_h.html",line:147,type:"type"};this.def["pointer_T"] = {file: "rtwtypes_h.html",line:168,type:"type"};} 4 | CodeDefine.instance = new CodeDefine(); 5 | var testHarnessInfo = {OwnerFileName: "", HarnessOwner: "", HarnessName: "", IsTestHarness: "0"}; 6 | var relPathToBuildDir = "../ert_main.c"; 7 | var fileSep = "\\"; 8 | var isPC = true; 9 | function Html2SrcLink() { 10 | this.html2SrcPath = new Array; 11 | this.html2Root = new Array; 12 | this.html2SrcPath["ert_main_c.html"] = "../ert_main.c"; 13 | this.html2Root["ert_main_c.html"] = "ert_main_c.html"; 14 | this.html2SrcPath["bouncing_ball_c.html"] = "../bouncing_ball.c"; 15 | this.html2Root["bouncing_ball_c.html"] = "bouncing_ball_c.html"; 16 | this.html2SrcPath["bouncing_ball_h.html"] = "../bouncing_ball.h"; 17 | this.html2Root["bouncing_ball_h.html"] = "bouncing_ball_h.html"; 18 | this.html2SrcPath["bouncing_ball_private_h.html"] = "../bouncing_ball_private.h"; 19 | this.html2Root["bouncing_ball_private_h.html"] = "bouncing_ball_private_h.html"; 20 | this.html2SrcPath["bouncing_ball_types_h.html"] = "../bouncing_ball_types.h"; 21 | this.html2Root["bouncing_ball_types_h.html"] = "bouncing_ball_types_h.html"; 22 | this.html2SrcPath["rtwtypes_h.html"] = "../rtwtypes.h"; 23 | this.html2Root["rtwtypes_h.html"] = "rtwtypes_h.html"; 24 | this.getLink2Src = function (htmlFileName) { 25 | if (this.html2SrcPath[htmlFileName]) 26 | return this.html2SrcPath[htmlFileName]; 27 | else 28 | return null; 29 | } 30 | this.getLinkFromRoot = function (htmlFileName) { 31 | if (this.html2Root[htmlFileName]) 32 | return this.html2Root[htmlFileName]; 33 | else 34 | return null; 35 | } 36 | } 37 | Html2SrcLink.instance = new Html2SrcLink(); 38 | var fileList = [ 39 | "ert_main_c.html","bouncing_ball_c.html","bouncing_ball_h.html","bouncing_ball_private_h.html","bouncing_ball_types_h.html","rtwtypes_h.html"]; 40 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/hilite_warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_ert_shrlib_rtw/html/hilite_warning.png -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/inspect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 34 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/nav.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/navToolbar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 59 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/rtwmsg.html: -------------------------------------------------------------------------------- 1 | Block-to-Code Highlighting Message 2 | 3 | 4 | 5 |

Block-to-Code Highlighting Message

6 | 7 | 8 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/rtwreport.css: -------------------------------------------------------------------------------- 1 | /* Copyright 2011-2016 The MathWorks, Inc. */ 2 | body,p,table {font-family: calibri, verdana, sans-serif;} 3 | button,.buton {font-family: calibri, verdana, sans-serif;} 4 | button,.button {font-size: small;} 5 | .small_font {font-size: small;} 6 | h1 { font-weight: normal; color: #000066; } 7 | td { vertical-align: top } 8 | th { background-color: #eeeeee; text-align: left; } 9 | a:link { color: #0033cc; } 10 | a:visited { color: #666666; } 11 | input { font-family: sans-serif, verdana, calibri; } 12 | table { 13 | background-color: #ffffff; 14 | width: 100%; 15 | } 16 | 17 | table.toc, table.button, table.panel { 18 | border-style: none; 19 | } 20 | 21 | /* LineNumber */ 22 | .LN { 23 | font-style: italic; 24 | color: #888888; 25 | } 26 | 27 | /* Comment */ 28 | .CT { 29 | font-style: italic; 30 | color: #117755; 31 | } 32 | 33 | /* PreProcessor */ 34 | PP { 35 | /* font-weight: bold; */ 36 | color: #992211; 37 | } 38 | 39 | /* Keyword */ 40 | .KW { 41 | /* font-weight: bold; */ 42 | color: #0000FF; 43 | } 44 | 45 | /* Datatype */ 46 | .DT { 47 | /* font-weight: bold; */ 48 | color: #112266 49 | } 50 | 51 | .highlighted { 52 | background-color: yellow; 53 | } 54 | 55 | .highlightedCurrent { 56 | background-color: #819FF7; 57 | } 58 | 59 | input.search { 60 | background-color: #ffffff; 61 | } 62 | 63 | input.failedSearch { 64 | background-color: #F78181; 65 | } 66 | 67 | /* ensure that code2model links are comment green */ 68 | a.code2model:link { 69 | color: #117755; 70 | font-style: italic; 71 | } 72 | a.code2model:visited{ 73 | color: #117755; 74 | font-style: italic; 75 | } 76 | 77 | .toc td, .button td, .panel td { 78 | border-style: none; 79 | padding: 4px; 80 | } 81 | 82 | h1 { font-weight: normal; color: #000066; } 83 | td { vertical-align: top } 84 | th { background-color: #eeeeee; text-align: left; } 85 | a:link { color: #0033cc; } 86 | a:visited { color: #666666; } 87 | 88 | /******* table *******/ 89 | /* default table style */ 90 | table.AltRow { 91 | border-collapse: collapse; border: none; border-spacing: 0pt; 92 | border-top: solid #4F81BD 1.0pt; border-bottom: solid #4F81BD 1.0pt; 93 | } 94 | table.AltRow th, table.AltRow td { padding: 2pt 8pt 2pt 2pt } 95 | /* default alternating row style */ 96 | table.AltRow tr.even td { background-color:#D3DFEE; border:none;} 97 | table.AltRow tr.odd td { background-color:#FFFFFF; border:none;} 98 | /* tr class="heading" */ 99 | table.AltRow tr.heading td, table.AltRow th { 100 | background-color:#FFFFFF; font-weight:bold; border:none; 101 | border-bottom: solid #4F81BD 1.0pt; 102 | } 103 | /* table class="FirstColumn" */ 104 | table.FirstColumn td:first-child { font-weight:bold } 105 | /* table class="TotalRow" */ 106 | table.TotalRow tr:last-child { font-weight:bold } 107 | table.TotalRow tr:last-child td { border-top: solid #4F81BD 1.0pt } 108 | 109 | a.closeButton { 110 | background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #f9f9f9), color-stop(1, #e9e9e9) ); 111 | background:-moz-linear-gradient( center top, #f9f9f9 5%, #e9e9e9 100% ); 112 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e9e9e9'); 113 | background-color:#f9f9f9; 114 | -webkit-border-top-left-radius:20px; 115 | -moz-border-radius-topleft:20px; 116 | border-top-left-radius:20px; 117 | -webkit-border-top-right-radius:20px; 118 | -moz-border-radius-topright:20px; 119 | border-top-right-radius:20px; 120 | -webkit-border-bottom-right-radius:20px; 121 | -moz-border-radius-bottomright:20px; 122 | border-bottom-right-radius:20px; 123 | -webkit-border-bottom-left-radius:20px; 124 | -moz-border-radius-bottomleft:20px; 125 | border-bottom-left-radius:20px; 126 | text-indent:0; 127 | border:2px solid #dcdcdc; 128 | display:inline-block; 129 | color:#454143; 130 | font-family:Arial; 131 | font-size:15px; 132 | font-weight:bold; 133 | font-style:normal; 134 | height:20px; 135 | line-height:20px; 136 | width:20px; 137 | text-decoration:none; 138 | text-align:center; 139 | cursor: pointer; 140 | } 141 | a.closeButton:hover { 142 | background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #e9e9e9), color-stop(1, #f9f9f9) ); 143 | background:-moz-linear-gradient( center top, #e9e9e9 5%, #f9f9f9 100% ); 144 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e9e9e9', endColorstr='#f9f9f9'); 145 | background-color:#e9e9e9; 146 | } 147 | a.closeButton:active { 148 | position:relative; 149 | top:1px; 150 | } 151 | 152 | .button { 153 | -moz-box-shadow:inset 0px 1px 0px 0px #ffffff; 154 | -webkit-box-shadow:inset 0px 1px 0px 0px #ffffff; 155 | box-shadow:inset 0px 1px 0px 0px #ffffff; 156 | background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ededed), color-stop(1, #dfdfdf) ); 157 | background:-moz-linear-gradient( center top, #ededed 5%, #dfdfdf 100% ); 158 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed', endColorstr='#dfdfdf'); 159 | background-color:#ededed; 160 | -webkit-border-top-left-radius:5px; 161 | -moz-border-radius-topleft:5px; 162 | border-top-left-radius:5px; 163 | -webkit-border-top-right-radius:5px; 164 | -moz-border-radius-topright:5px; 165 | border-top-right-radius:5px; 166 | -webkit-border-bottom-right-radius:5px; 167 | -moz-border-radius-bottomright:5px; 168 | border-bottom-right-radius:5px; 169 | -webkit-border-bottom-left-radius:5px; 170 | -moz-border-radius-bottomleft:5px; 171 | border-bottom-left-radius:5px; 172 | text-indent:0px; 173 | border:1px solid #dcdcdc; 174 | display:inline-block; 175 | color:black; 176 | font-family:Arial; 177 | font-size:12px; 178 | font-weight:bold; 179 | font-style:normal; 180 | height:12px; 181 | line-height:12px; 182 | width:45px; 183 | text-decoration:none; 184 | text-align:center; 185 | text-shadow:1px 1px 0px #ffffff; 186 | } 187 | .button:hover { 188 | background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #dfdfdf), color-stop(1, #ededed) ); 189 | background:-moz-linear-gradient( center top, #dfdfdf 5%, #ededed 100% ); 190 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dfdfdf', endColorstr='#ededed'); 191 | background-color:#dfdfdf; 192 | }.button:active { 193 | position:relative; 194 | top:1px; 195 | }.button:disabled { 196 | color:#777777; 197 | } 198 | 199 | ul.nav_list { 200 | list-style-type:none; 201 | display: block; 202 | margin: 0; 203 | padding: 0; 204 | } 205 | ul.nav_list li { 206 | list-style-type:none; 207 | display: inline; 208 | margin: 0 18px 0 0; 209 | padding: 0; 210 | } 211 | 212 | .nav_toolbar { 213 | background-color: #aff; 214 | margin-top: 0; 215 | } 216 | 217 | .inspect_body { 218 | margin: 0; 219 | margin-bottom: 0; 220 | display: inline; 221 | vertical-align:middle; 222 | } 223 | 224 | table.nav_table { 225 | background-color: #aff; 226 | border: none; 227 | width: 100%; 228 | display: inline; 229 | vertical-align:middle; 230 | } 231 | 232 | table#rtwIdTracePanel > tr > td { 233 | white-space: nowrap; 234 | table-layout:fixed; 235 | vertical-align:middle; 236 | } 237 | 238 | table.nav_table > button { 239 | height: 20px; 240 | } 241 | select#fileSelector { 242 | padding: 5px; 243 | font-size: 16px; 244 | line-height: 1; 245 | border-radius: 0; 246 | height: 34px; 247 | } 248 | 249 | .treeTable table{ 250 | table-layout: fixed; 251 | } 252 | .treeTable td:first-child > span{ 253 | display: inline-block; 254 | text-overflow: ellipsis; 255 | overflow: hidden; 256 | width: 100%; 257 | } 258 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/rtwreport_utils.js: -------------------------------------------------------------------------------- 1 | // Copyright 2011-2013 The MathWorks, Inc. 2 | 3 | 4 | function local_onload() { 5 | if (typeof top.rtwreport_document_frame !== "undefined") { 6 | var docObj = window.document; 7 | var alink = docObj.getElementById("linkToText_plain"); 8 | if (alink) { 9 | alink.href = "matlab:coder.internal.editUrlTextFile('" + alink.href + "')"; 10 | } 11 | alink = docObj.getElementById("linkToCS"); 12 | if (alink) { 13 | alink.href = "matlab:coder.internal.viewCodeConfigsetFromReport('" + alink.href + "');"; 14 | } 15 | } 16 | } 17 | 18 | var utils = (function() { 19 | 20 | // Load via Microsoft.XMLDOM--for older versions of IE 21 | function loadXML_MSXMLDOM(filename, callback, async) { 22 | if (navigator.appName == "Microsoft Internet Explorer") { 23 | // Internet Explorer 5/6 24 | try { 25 | var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 26 | xmlDoc.async = async; 27 | xmlDoc.onreadystatechange = function() { 28 | if (xmlDoc.readyState == 4) { 29 | callback(xmlDoc); 30 | } 31 | } 32 | xmlDoc.load(filename); 33 | return true; 34 | } catch(e) { 35 | } 36 | } 37 | return false; 38 | } 39 | 40 | // Load via XMLHttpRequest 41 | function loadXML_XHR(filename, callback, async) { 42 | if (window.XMLHttpRequest) { 43 | try { 44 | var xhr = new XMLHttpRequest(); 45 | xhr.onreadystatechange = function() { 46 | if (this.readyState == 4) { 47 | callback(this.responseXML); 48 | } 49 | } 50 | xhr.open("GET", filename, async); 51 | xhr.send(""); 52 | return true; 53 | } catch(e) { 54 | if (navigator.appName === "Netscape" && e.code === 1012) { 55 | // file not found: ignore 56 | return true; 57 | } 58 | } 59 | } 60 | return false; 61 | } 62 | 63 | return { 64 | trimText: function(s) { 65 | // In IE9, String.trim not present 66 | if (s && s.trim) { 67 | return s.trim(); 68 | } 69 | else { 70 | return s; 71 | } 72 | }, 73 | getText: function(elt) { 74 | // In IE9, use 'text' property rather than 'textContent' 75 | return elt.textContent ? elt.textContent : elt.text; 76 | }, 77 | loadXML: function(filename, callback, options) { 78 | var async = !!options && typeof(options["async"]) !== "undefined" ? options.async : true; 79 | if (!loadXML_XHR(filename, callback, async)) { 80 | if (!loadXML_MSXMLDOM(filename, callback, async)) { 81 | return false; 82 | } 83 | } 84 | return true; 85 | } 86 | }; 87 | })(); 88 | 89 | function code2model(sid) { 90 | utils.loadXML("http://localhost:31415/matlab/feval/coder.internal.code2model?arguments=[\"" + sid + "\"]", function() {}); 91 | //window.location.href = "matlab:coder.internal.code2model('" + sid + "')"; 92 | } 93 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/rtwshrink.js: -------------------------------------------------------------------------------- 1 | // Copyright 2011-2017 The MathWorks, Inc. 2 | 3 | function RTW_STRUCT(prop, value) { 4 | this.prop = prop; 5 | if (typeof(value) == 'undefined') { 6 | this.value = ""; 7 | } else { 8 | this.value = value; 9 | } 10 | } 11 | 12 | // initialize the cache when code generation report is first loaded 13 | function RTW_BOOK() { 14 | this.length = 0; 15 | this.rtw_pages = new Array(); 16 | this.getPage = function(file) { 17 | return this.rtw_pages[file]; 18 | }; 19 | this.addPage = function(file) { 20 | var page; 21 | if (this.hasPage(file)) { 22 | page = this.rtw_pages[file]; 23 | } else { 24 | page = new RTW_PAGE(file); 25 | this.rtw_pages[file] = page; 26 | } 27 | return page; 28 | }; 29 | this.hasPage = function(file) { 30 | return typeof(this.rtw_pages[file]) != 'undefined'; 31 | }; 32 | this.removePage = function(file) { 33 | var tmp; 34 | if (typeof(this.rtw_pages[file]) != 'undefined') { 35 | tmp = this.rtw_pages[file]; 36 | delete this.rtw_pages[file]; 37 | this.length--; 38 | } 39 | return tmp; 40 | }; 41 | } 42 | 43 | if (!RTW_BOOK.instance) { 44 | RTW_BOOK.instance = new RTW_BOOK(); 45 | } 46 | 47 | function RTW_PAGE() { 48 | this.length = 0; 49 | this.items = new Array(); 50 | this.pagename = ''; 51 | if (arguments.length > 0 && typeof(arguments[1]) != 'undefined') { 52 | this.pagename = arguments[1]; 53 | } 54 | 55 | this.getItem = function(id) { 56 | return this.items[id]; 57 | }; 58 | this.getItems = function() { 59 | return this.items; 60 | }; 61 | this.addItem = function(id, value) { 62 | var tmp; 63 | if (typeof(value) != 'undefined') { 64 | if (typeof(this.items[id]) != 'undefined') { 65 | this.length++; 66 | } else { 67 | tmp = this.items[id]; 68 | } 69 | this.items[id] = value; 70 | this.length++; 71 | } 72 | return tmp; 73 | }; 74 | this.hasItem = function(id) { 75 | return typeof(this.items[id]) != 'undefined'; 76 | }; 77 | this.removeItem = function(id) { 78 | var tmp; 79 | if (typeof(this.items[id]) != 'undefined') { 80 | tmp = this.items[id]; 81 | delete this.items[id]; 82 | this.length--; 83 | } 84 | return tmp; 85 | }; 86 | } 87 | 88 | function rtwTableShrink(doc, obj, id, isSymbol) { 89 | var hide, hide_text, show, show_text; 90 | if (isSymbol) { 91 | hide = "[-]"; 92 | hide_text = hide; 93 | show = "[+]"; 94 | show_text = show; 95 | } else { 96 | hide = "[hide]"; 97 | hide_text = "[hide]"; 98 | show = "[show]"; 99 | show_text = "[show]"; 100 | } 101 | hide = "" + hide + ""; 102 | show = "" + show + ""; 103 | if (doc.getElementsByName) { 104 | var o = doc.getElementsByName(id); 105 | for (var oid = 0; oid < o.length; ++oid) { 106 | if (o[oid].style.display === "none") { 107 | o[oid].style.display = ""; 108 | } else { 109 | o[oid].style.display = "none"; 110 | } 111 | } 112 | if (o.length >= 0 && addToPage) { 113 | addToPage(doc, o[0], 'display'); 114 | } 115 | } 116 | 117 | // IE supports innerText while other browsers support textContent 118 | if (obj.textContent) { 119 | var objText = obj.textContent; 120 | } else { 121 | var objText = obj.innerText; 122 | } 123 | 124 | if (objText.toLowerCase() === show_text.toLowerCase()) { 125 | obj.innerHTML = hide; 126 | } else { 127 | obj.innerHTML = show; 128 | } 129 | 130 | if (addToPage) { 131 | addToPage(doc, obj, 'innerHTML'); 132 | } 133 | } 134 | 135 | function rtwTableExpand(doc, controlObj, id) { 136 | if (doc.getElementById) { 137 | var obj = doc.getElementById(id); 138 | if (obj && obj.style.display === "none") { 139 | rtwTableShrink(doc, controlObj, id, false); 140 | } 141 | } 142 | } 143 | 144 | function restoreState(docObj) { 145 | var filename = docObj.location.href; 146 | if (RTW_BOOK.instance && RTW_BOOK.instance.hasPage(filename)) { 147 | var page = RTW_BOOK.instance.getPage(filename); 148 | var items = page.getItems(); 149 | var elem; 150 | if (docObj.getElementsByName) { 151 | for (var i in items) { 152 | var o = docObj.getElementsByName(i); 153 | for (var oid = 0; oid < o.length; ++oid) { 154 | elem = o[oid]; 155 | if (items[i].prop === 'display') { 156 | if (elem.style.display === 'none') { 157 | elem.style.display = ''; 158 | } else { 159 | elem.style.display = 'none'; 160 | } 161 | } else if (items[i].prop === 'innerHTML') { 162 | elem.innerHTML = items[i].value; 163 | } 164 | } 165 | } 166 | } 167 | } 168 | } 169 | 170 | function addToPage(docObj, obj, prop) { 171 | var filename = docObj.location.href; 172 | if (RTW_BOOK.instance) { 173 | var page; 174 | if (RTW_BOOK.instance.hasPage(filename)) { 175 | page = RTW_BOOK.instance.getPage(filename); 176 | } else { 177 | page = RTW_BOOK.instance.addPage(filename); 178 | } 179 | if (page.hasItem(obj.id)) { 180 | page.removeItem(obj.id); 181 | } else { 182 | var my_struct; 183 | if (prop === "display") { 184 | my_struct = new RTW_STRUCT(prop, obj.style.display); 185 | } else { 186 | my_struct = new RTW_STRUCT(prop, obj.innerHTML); 187 | } 188 | page.addItem(obj.id, my_struct); 189 | } 190 | } 191 | } 192 | 193 | function rtwSwitchView(doc, obj1, obj2) { 194 | if (doc.getElementsByName) { 195 | var o = doc.getElementsByName(obj1); 196 | for (var oid = 0; oid < o.length; ++oid) { 197 | o[oid].style.display = "none"; 198 | } 199 | if (o.length >= 0 && addToPage) { 200 | addToPage(doc, o[0], 'display'); 201 | } 202 | var o = doc.getElementsByName(obj2); 203 | for (var oid = 0; oid < o.length; ++oid) { 204 | o[oid].style.display = ""; 205 | } 206 | if (o.length >= 0 && addToPage) { 207 | addToPage(doc, o[0], 'display'); 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_ert_shrlib_rtw/html/spinner.gif -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/html/traceInfo_flag.js: -------------------------------------------------------------------------------- 1 | function TraceInfoFlag() { 2 | this.traceFlag = new Array(); 3 | this.traceFlag["bouncing_ball.c:49c61"]=1; 4 | this.traceFlag["bouncing_ball.c:62c19"]=1; 5 | this.traceFlag["bouncing_ball.c:62c72"]=1; 6 | this.traceFlag["bouncing_ball.c:78c37"]=1; 7 | this.traceFlag["bouncing_ball.c:85c19"]=1; 8 | this.traceFlag["bouncing_ball.c:85c72"]=1; 9 | this.traceFlag["bouncing_ball.c:94c51"]=1; 10 | this.traceFlag["bouncing_ball.c:97c46"]=1; 11 | this.traceFlag["bouncing_ball.c:97c56"]=1; 12 | this.traceFlag["bouncing_ball.c:103c50"]=1; 13 | this.traceFlag["bouncing_ball.c:103c60"]=1; 14 | } 15 | top.TraceInfoFlag.instance = new TraceInfoFlag(); 16 | function TraceInfoLineFlag() { 17 | this.lineTraceFlag = new Array(); 18 | this.lineTraceFlag["bouncing_ball.c:49"]=1; 19 | this.lineTraceFlag["bouncing_ball.c:52"]=1; 20 | this.lineTraceFlag["bouncing_ball.c:53"]=1; 21 | this.lineTraceFlag["bouncing_ball.c:54"]=1; 22 | this.lineTraceFlag["bouncing_ball.c:56"]=1; 23 | this.lineTraceFlag["bouncing_ball.c:62"]=1; 24 | this.lineTraceFlag["bouncing_ball.c:63"]=1; 25 | this.lineTraceFlag["bouncing_ball.c:66"]=1; 26 | this.lineTraceFlag["bouncing_ball.c:74"]=1; 27 | this.lineTraceFlag["bouncing_ball.c:75"]=1; 28 | this.lineTraceFlag["bouncing_ball.c:76"]=1; 29 | this.lineTraceFlag["bouncing_ball.c:78"]=1; 30 | this.lineTraceFlag["bouncing_ball.c:79"]=1; 31 | this.lineTraceFlag["bouncing_ball.c:85"]=1; 32 | this.lineTraceFlag["bouncing_ball.c:86"]=1; 33 | this.lineTraceFlag["bouncing_ball.c:89"]=1; 34 | this.lineTraceFlag["bouncing_ball.c:94"]=1; 35 | this.lineTraceFlag["bouncing_ball.c:97"]=1; 36 | this.lineTraceFlag["bouncing_ball.c:98"]=1; 37 | this.lineTraceFlag["bouncing_ball.c:103"]=1; 38 | this.lineTraceFlag["bouncing_ball.c:104"]=1; 39 | this.lineTraceFlag["bouncing_ball.c:105"]=1; 40 | this.lineTraceFlag["bouncing_ball.c:137"]=1; 41 | this.lineTraceFlag["bouncing_ball.c:140"]=1; 42 | this.lineTraceFlag["bouncing_ball.c:143"]=1; 43 | this.lineTraceFlag["bouncing_ball.c:144"]=1; 44 | this.lineTraceFlag["bouncing_ball.c:147"]=1; 45 | this.lineTraceFlag["bouncing_ball.c:148"]=1; 46 | } 47 | top.TraceInfoLineFlag.instance = new TraceInfoLineFlag(); 48 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/modelsources.txt: -------------------------------------------------------------------------------- 1 | bouncing_ball.c 2 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/rtw_proj.tmw: -------------------------------------------------------------------------------- 1 | Simulink Coder project for bouncing_ball using . MATLAB root = C:\R2018b. SimStruct date: 24-Jul-2018 19:01:04 2 | This file is generated by Simulink Coder for use by the make utility 3 | to determine when to rebuild objects when the name of the current Simulink Coder project changes. 4 | The rtwinfomat located at: ..\slprj\ert_shrlib\bouncing_ball\tmwinternal\binfo.mat 5 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_ert_shrlib_rtw/rtwtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: rtwtypes.h 3 | * 4 | * Code generated for Simulink model 'bouncing_ball'. 5 | * 6 | * Model version : 1.20 7 | * Simulink Coder version : 9.0 (R2018b) 24-May-2018 8 | * C/C++ source code generated on : Sat Feb 6 16:13:51 2021 9 | * 10 | * Target selection: ert_shrlib.tlc 11 | * Embedded hardware selection: Intel->x86-64 (Windows64) 12 | * Code generation objectives: Unspecified 13 | * Validation result: Not run 14 | */ 15 | 16 | #ifndef RTWTYPES_H 17 | #define RTWTYPES_H 18 | 19 | /* Logical type definitions */ 20 | #if (!defined(__cplusplus)) 21 | # ifndef false 22 | # define false (0U) 23 | # endif 24 | 25 | # ifndef true 26 | # define true (1U) 27 | # endif 28 | #endif 29 | 30 | /*=======================================================================* 31 | * Target hardware information 32 | * Device type: MATLAB Host 33 | * Number of bits: char: 8 short: 16 int: 32 34 | * long: 32 long long: 64 35 | * native word size: 64 36 | * Byte ordering: LittleEndian 37 | * Signed integer division rounds to: Zero 38 | * Shift right on a signed integer as arithmetic shift: on 39 | *=======================================================================*/ 40 | 41 | /*=======================================================================* 42 | * Fixed width word size data types: * 43 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 44 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 45 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 46 | *=======================================================================*/ 47 | typedef signed char int8_T; 48 | typedef unsigned char uint8_T; 49 | typedef short int16_T; 50 | typedef unsigned short uint16_T; 51 | typedef int int32_T; 52 | typedef unsigned int uint32_T; 53 | typedef long long int64_T; 54 | typedef unsigned long long uint64_T; 55 | typedef float real32_T; 56 | typedef double real64_T; 57 | 58 | /*===========================================================================* 59 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 60 | * real_T, time_T, ulong_T, ulonglong_T. * 61 | *===========================================================================*/ 62 | typedef double real_T; 63 | typedef double time_T; 64 | typedef unsigned char boolean_T; 65 | typedef int int_T; 66 | typedef unsigned int uint_T; 67 | typedef unsigned long ulong_T; 68 | typedef unsigned long long ulonglong_T; 69 | typedef char char_T; 70 | typedef unsigned char uchar_T; 71 | typedef char_T byte_T; 72 | 73 | /*===========================================================================* 74 | * Complex number type definitions * 75 | *===========================================================================*/ 76 | #define CREAL_T 77 | 78 | typedef struct { 79 | real32_T re; 80 | real32_T im; 81 | } creal32_T; 82 | 83 | typedef struct { 84 | real64_T re; 85 | real64_T im; 86 | } creal64_T; 87 | 88 | typedef struct { 89 | real_T re; 90 | real_T im; 91 | } creal_T; 92 | 93 | #define CINT8_T 94 | 95 | typedef struct { 96 | int8_T re; 97 | int8_T im; 98 | } cint8_T; 99 | 100 | #define CUINT8_T 101 | 102 | typedef struct { 103 | uint8_T re; 104 | uint8_T im; 105 | } cuint8_T; 106 | 107 | #define CINT16_T 108 | 109 | typedef struct { 110 | int16_T re; 111 | int16_T im; 112 | } cint16_T; 113 | 114 | #define CUINT16_T 115 | 116 | typedef struct { 117 | uint16_T re; 118 | uint16_T im; 119 | } cuint16_T; 120 | 121 | #define CINT32_T 122 | 123 | typedef struct { 124 | int32_T re; 125 | int32_T im; 126 | } cint32_T; 127 | 128 | #define CUINT32_T 129 | 130 | typedef struct { 131 | uint32_T re; 132 | uint32_T im; 133 | } cuint32_T; 134 | 135 | #define CINT64_T 136 | 137 | typedef struct { 138 | int64_T re; 139 | int64_T im; 140 | } cint64_T; 141 | 142 | #define CUINT64_T 143 | 144 | typedef struct { 145 | uint64_T re; 146 | uint64_T im; 147 | } cuint64_T; 148 | 149 | /*=======================================================================* 150 | * Min and Max: * 151 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 152 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 153 | *=======================================================================*/ 154 | #define MAX_int8_T ((int8_T)(127)) 155 | #define MIN_int8_T ((int8_T)(-128)) 156 | #define MAX_uint8_T ((uint8_T)(255U)) 157 | #define MAX_int16_T ((int16_T)(32767)) 158 | #define MIN_int16_T ((int16_T)(-32768)) 159 | #define MAX_uint16_T ((uint16_T)(65535U)) 160 | #define MAX_int32_T ((int32_T)(2147483647)) 161 | #define MIN_int32_T ((int32_T)(-2147483647-1)) 162 | #define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) 163 | #define MAX_int64_T ((int64_T)(9223372036854775807LL)) 164 | #define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) 165 | #define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) 166 | 167 | /* Block D-Work pointer type */ 168 | typedef void * pointer_T; 169 | 170 | #endif /* RTWTYPES_H */ 171 | 172 | /* 173 | * File trailer for generated code. 174 | * 175 | * [EOF] 176 | */ 177 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_files/bouncing_ball_4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_files/bouncing_ball_4_1.png -------------------------------------------------------------------------------- /Example3/bouncing_ball_files/bouncing_ball_4_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_files/bouncing_ball_4_2.png -------------------------------------------------------------------------------- /Example3/bouncing_ball_files/bouncing_ball_7_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_files/bouncing_ball_7_1.png -------------------------------------------------------------------------------- /Example3/bouncing_ball_files/bouncing_ball_8_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_files/bouncing_ball_8_1.png -------------------------------------------------------------------------------- /Example3/bouncing_ball_init.m: -------------------------------------------------------------------------------- 1 | Ts = 1e-3; 2 | 3 | gravitational_constant = Simulink.Parameter; 4 | gravitational_constant.Value = -9.81; 5 | gravitational_constant.CoderInfo.StorageClass='ExportedGlobal'; 6 | 7 | coefficient_of_restitution = Simulink.Parameter; 8 | coefficient_of_restitution.Value = -0.8; 9 | coefficient_of_restitution.CoderInfo.StorageClass='ExportedGlobal'; 10 | 11 | ball_position = Simulink.Signal; 12 | ball_position.CoderInfo.StorageClass='ExportedGlobal'; 13 | 14 | ball_velocity = Simulink.Signal; 15 | ball_velocity.CoderInfo.StorageClass='ExportedGlobal'; 16 | 17 | 18 | SimTime = Simulink.Signal; 19 | SimTime.CoderInfo.StorageClass='ExportedGlobal'; 20 | -------------------------------------------------------------------------------- /Example3/bouncing_ball_win64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_win64.dll -------------------------------------------------------------------------------- /Example3/bouncing_ball_win64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/bouncing_ball_win64.lib -------------------------------------------------------------------------------- /Example3/rtwtypes.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | 3 | """ 4 | /*=======================================================================* 5 | * Fixed width word size data types: * 6 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 7 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 8 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 9 | *=======================================================================*/ 10 | """ 11 | int8_T = ctypes.c_byte 12 | uint8_T = ctypes.c_ubyte 13 | int16_T = ctypes.c_short 14 | uint16_T = ctypes.c_ushort 15 | int32_T = ctypes.c_int 16 | uint32_T = ctypes.c_uint 17 | int64_T = ctypes.c_longlong 18 | uint64_T = ctypes.c_ulonglong 19 | real32_T = ctypes.c_float 20 | real64_T = ctypes.c_double 21 | """ 22 | /*===========================================================================* 23 | * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * 24 | * real_T, time_T, ulong_T, ulonglong_T. * 25 | *===========================================================================*/ 26 | """ 27 | real_T = ctypes.c_double 28 | time_T = ctypes.c_double 29 | boolean_T = ctypes.c_ubyte 30 | int_T = ctypes.c_int 31 | uint_T = ctypes.c_uint 32 | ulong_T = ctypes.c_ulong 33 | ulonglong_T = ctypes.c_ulonglong 34 | char_T = ctypes.c_char 35 | uchar_T = ctypes.c_ubyte 36 | char_T = ctypes.c_byte 37 | """ 38 | /*===========================================================================* 39 | * Complex number type definitions * 40 | *===========================================================================*/ 41 | """ 42 | 43 | 44 | class creal32_T(ctypes.Structure): 45 | _fields_ = [ 46 | ("re", real32_T), 47 | ("im", real32_T), 48 | ] 49 | 50 | 51 | class creal64_T(ctypes.Structure): 52 | _fields_ = [ 53 | ("re", real64_T), 54 | ("im", real64_T), 55 | ] 56 | 57 | 58 | class creal_T(ctypes.Structure): 59 | _fields_ = [ 60 | ("re", real_T), 61 | ("im", real_T), 62 | ] 63 | 64 | 65 | class cint8_T(ctypes.Structure): 66 | _fields_ = [ 67 | ("re", int8_T), 68 | ("im", int8_T), 69 | ] 70 | 71 | 72 | class cuint8_T(ctypes.Structure): 73 | _fields_ = [ 74 | ("re", uint8_T), 75 | ("im", uint8_T), 76 | ] 77 | 78 | 79 | class cint16_T(ctypes.Structure): 80 | _fields_ = [ 81 | ("re", int16_T), 82 | ("im", int16_T), 83 | ] 84 | 85 | 86 | class cuint16_T(ctypes.Structure): 87 | _fields_ = [ 88 | ("re", uint16_T), 89 | ("im", uint16_T), 90 | ] 91 | 92 | 93 | class cint32_T(ctypes.Structure): 94 | _fields_ = [ 95 | ("re", int32_T), 96 | ("im", int32_T), 97 | ] 98 | 99 | 100 | class cuint32_T(ctypes.Structure): 101 | _fields_ = [ 102 | ("re", uint32_T), 103 | ("im", uint32_T), 104 | ] 105 | 106 | 107 | class cint64_T(ctypes.Structure): 108 | _fields_ = [ 109 | ("re", int64_T), 110 | ("im", int64_T), 111 | ] 112 | 113 | 114 | class cuint64_T(ctypes.Structure): 115 | _fields_ = [ 116 | ("re", uint64_T), 117 | ("im", uint64_T), 118 | ] 119 | -------------------------------------------------------------------------------- /Example3/sldemo_bounceExample_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/Example3/sldemo_bounceExample_02.png -------------------------------------------------------------------------------- /GitHub_Actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/GitHub_Actions.png -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | stages { 4 | stage('Build Libraries') { 5 | parallel { 6 | stage('Build Example 1') { 7 | steps { 8 | runMATLABCommand 'run(\'Example1\\dllModel_build\')' 9 | } 10 | } 11 | 12 | stage('Build Example 2') { 13 | steps { 14 | runMATLABCommand 'run(\'Example2\\discrete_tf_build\')' 15 | } 16 | } 17 | 18 | stage('Build Example 3') { 19 | steps { 20 | runMATLABCommand 'run(\'Example3\\bouncing_ball_build\')' 21 | } 22 | } 23 | 24 | } 25 | } 26 | 27 | stage('Archive Artifacts') { 28 | steps { 29 | archiveArtifacts(artifacts: '**/*.dll, **/*.h', fingerprint: true, onlyIfSuccessful: true) 30 | } 31 | } 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Jed Frey 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-Simulink 2 | 3 | Run your Simulink models & libraries in Python. 4 | 5 | ## Motivation 6 | 7 | 1. Running software-in-the-loop tests with Simulink becomes time consuming with Matlab & Simulink overhead. There are ways to reduce it (Model reference, etc) however nothing has shown to be as fast as a precompiled shared library. 8 | 9 | 2. Python has a very mature set of tools and packages to automate testing. 10 | 11 | 3. Testing can be distributed to machines without Matlab/Simulink licenses. 12 | 13 | 4. There are more and more Python developers. Being able to hand off a Simulink Library for further use there is a good feature. 14 | 15 | ## Use cases 16 | 17 | 1. Use Python and it's ecosystem to run complex Simulink models. 18 | 2. Use Python & `pytest` to run Software-in-the-Loop (SIL) tests on Simulink subsystems. 19 | 3. Give Simulink algorithms to developers without Matlab/Simulink licenses to use. 20 | 4. Use GitHub/GitLab actions and Python to automate testing in the cloud. 21 | 5. Start a programming language war at your company. 22 | 23 | ## Disclaimer 24 | 25 | This repository is a set of instructions, with examples, on how to create a Pythonic wrapper for Simulink models. It **is not** a turnkey Python module to do this: 26 | 27 | ```python 28 | import simulinkdll 29 | simulinkdll.run("my_model.slx") 30 | do_stuff() 31 | ``` 32 | 33 | For a given library or model configuring the Python should only need done when the Simulink Parameters/Signals change. The end developer will then be able do a `import simulink_model`, but it takes development time. 34 | 35 | ### High level instructions. 36 | 37 | 1. [Create a shared library in Simulink.](https://www.mathworks.com/help/ecoder/ug/creating-and-using-host-based-shared-libraries.html) 38 | 2. Create Python representations of all items in the header file. 39 | 3. Open the shared library (`.dll`, `.so`) in Python and run the model. 40 | 41 | # Examples 42 | 43 | ### [Simple DLL Export](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example1/dllModel.ipynb) 44 | 45 | - For demonstrating minimal dll functionality and the steps required to run a model in Python. 46 | - Demonstrate implementions of `SimulinkGlobal` vs `ExportedGlobal` in `Simulink.Parameter` and `Simulink.Signal` variables. 47 | 48 | ![](Example1/dllModel.png) 49 | 50 | ### [Discrete Transfer Function](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf-python_class.ipynb) 51 | 52 | ![](Example2/discrete_tf.png) 53 | 54 | A simple discrete transfer function. Compiled with a 1st order low pass filter. 55 | 56 | There are two example notebooks for Example 2. 57 | 58 | 1. [Simple Example](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example2/discrete_tf.ipynb) - A simple low-level ctypes wrapper. 59 | 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. 60 | 61 | - 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 [Example2/test_results.md.](https://github.com/dapperfu/python_SimulinkDLL/blob/master/Example2/test_results.md) 62 | 63 | - Tests can be run on [GitHub actions](https://github.com/features/actions) as well. An example of pipeline file is provided: [.github/workflows/blank.yml](https://github.com/dapperfu/python_SimulinkDLL/blob/master/.github/workflows/blank.yml). 64 | 65 | This is an example badge: [![Simulink DLL Test](https://github.com/dapperfu/python_SimulinkDLL/actions/workflows/blank.yml/badge.svg)](https://github.com/dapperfu/python_SimulinkDLL/actions/workflows/blank.yml) 66 | 67 | ![](GitHub_Actions.png) 68 | 69 | ### [Bouncing Ball](https://nbviewer.jupyter.org/github/dapperfu/python_SimulinkDLL/blob/master/Example3/bouncing_ball.ipynb) 70 | 71 | Adapted from [Mathworks's Simulation of a Bouncing Ball](https://www.mathworks.com/help/simulink/slref/simulation-of-a-bouncing-ball.html) 72 | 73 | ![](Example3/bouncing_ball.png) 74 | 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. 76 | 77 | `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. 78 | 79 | | Time Step | Simulink Duration (s) | Python Duration (s) | 80 | | --------- | --------------------- | ------------------- | 81 | | 1e-4 | 0.5905 | 0.06 | 82 | | 1e-5 | 1.0461 | 0.61 | 83 | | 1e-6 | 8.1991 | 6.08 | 84 | | 1e-7 | 78.9901 | 60.18 | 85 | 86 | # Jenkins Build Automation 87 | 88 | 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: 89 | 90 | - shared library (`.dll`) 91 | - header files (`.h`) 92 | 93 | Jenkins Pipeline screenshot: 94 | 95 | ![Jenkins pipeline screenshot](jenkins_pipeline.png) 96 | 97 | Jenkins Artifacts screenshot: 98 | 99 | ![Jenkins artifacts](jenkins_artifacts.png) 100 | 101 | # Discussion, Questions & Feedback 102 | 103 | - https://github.com/dapperfu/Python-Simulink/discussions 104 | -------------------------------------------------------------------------------- /jenkins_artifacts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/jenkins_artifacts.png -------------------------------------------------------------------------------- /jenkins_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dapperfu/Python-Simulink/dde92b1f63588975a86e95ed7236e771e1e5ac96/jenkins_pipeline.png --------------------------------------------------------------------------------