diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md new file mode 100644 index 00000000..c4300e21 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -0,0 +1,70 @@ +# Control with AMDC Using Simulink Autogen + +## Background + +Modern motor drive systems rely on embedded controllers to execute control algorithms in real time. Traditionally, these algorithms are implemented manually in C/C++, which is time-consuming and prone to implementation errors, especially for complex control systems. + +However, Simulink provides a MATLAB-based graphical environment for modeling and simulating control systems. It is extensively used to model, simulate, and analyze complex dynamical systems, including motor drives. The GUI and block diagram environment in Simulink make it user-friendly and easy to validate system performance and controller performance. + +The process of converting a user Simulink model for a controller to equivalent C-code for an embedded system (such as the AMDC) is called Automatic Code Generation (Autogen). By using the Autogen capability, control algorithms developed in a block-diagram form can be automatically converted into C code for execution on embedded platforms. This enables developers to design, simulate, and validate control strategies before deploying them to hardware. As a result, it improves development efficiency, reduces implementation errors, and provides a more intuitive framework for control system design. + +## Control Approach with Simulink and AMDC + +The Simulink + AMDC workflow separates control development into two domains: + +- **Design domain (Simulink):** + The control algorithm is developed and validated using a graphical model. + +- **Execution domain (AMDC):** + The generated C code is executed in real time on the embedded controller. + +In this workflow, the Simulink model represents the control logic, while the AMDC is responsible for executing this logic at a fixed time interval using real sensor data. The Simulink model is typically structured into three subsystems: + +1. **Input/Output (I/O):** Used for simulation and visualization only +2. **Plant:** Represents the physical system (used for simulation) +3. **Controller:** Contains the control logic to be deployed + +Only the **controller subsystem** is converted into embedded C code. + +### Recommended Workflow + +The recommended workflow for developing control code is: + +1. Develop and validate the control algorithm in Simulink +2. Convert the controller to an atomic subsystem and then to a referenced model +3. Generate C code using Simulink Autogen +4. Integrate generated code into the AMDC project +5. Execute and validate on hardware + +## Important Considerations for Simulink Models + +For successful development and integration of control code, the following considerations must be observed: + +1. **Discrete-Time Implementation**: All blocks within the controller must be discrete-time, since the AMDC executes control logic at fixed sampling intervals. +2. **Fixed-Step Solver**: The Simulink model must use a fixed-step solver to ensure compatibility with real-time execution. +3. **Consistent Sample Time**: The entire controller subsystem should operate at a single, well-defined sample time before converting to an atomic subsystem and creating a referenced model. +4. **Code Generation Settings**: The code generation target should be set to Embedded Coder (`ert.tlc`). The build configuration should enable "Generate Code Only". +5. **Referenced Model Usage**: The controller subsystem should be converted to an atomic subsystem, then converted to a referenced model. Any updates to model settings should be performed after opening the referenced model as the top model. +6. **AMDC Integration Details** + - All generated source (`*.c`) and header (`*.h`) files must be included in the AMDC project. + - The autogenerated folder must be added to the compiler include paths. + - Do not delete any generated files, as some auxiliary files may be required during compilation. +7. **File and Path Constraints** + - File paths must not contain whitespace. + - The path to the folder containing the MATLAB script and the Simulink model, as well as any parent directory, must not include whitespace. Otherwise, it will result in a build error. + +This organization ensures that the autogenerated controller code is correctly compiled and integrated into the AMDC firmware. + +## Example Model + +An example tutorial, [Tutorial: Autogen](../../tutorials/autogen/index.md), is provided to demonstrate the Simulink Autogen workflow for control implementation and its integration with the AMDC. + +## Conclusion + +The Simulink Autogen workflow provides a structured and efficient approach for implementing control algorithms on the AMDC. By separating control design from embedded implementation, this approach enables: + +- Rapid development and iteration +- Improved reliability through simulation +- Clear mapping between design and execution + +This methodology is recommended for developing advanced control systems on the AMDC platform. diff --git a/source/getting-started/control-with-amdc/autogen/resources/autogen-example.svg b/source/getting-started/control-with-amdc/autogen/resources/autogen-example.svg new file mode 100644 index 00000000..769a9ce8 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/resources/autogen-example.svg @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + AMDC + + + + + + + Controller(DSP) + PWM Peripheral + ADC Peripheral + AnalogInput + PWM Output + 0-9V + 0-0.9 Duty Cycle + + diff --git a/source/getting-started/control-with-amdc/autogen/resources/autogenExample.slx b/source/getting-started/control-with-amdc/autogen/resources/autogenExample.slx new file mode 100644 index 00000000..c78c89f9 Binary files /dev/null and b/source/getting-started/control-with-amdc/autogen/resources/autogenExample.slx differ diff --git a/source/getting-started/control-with-amdc/autogen/resources/autogenExampleInit.m b/source/getting-started/control-with-amdc/autogen/resources/autogenExampleInit.m new file mode 100644 index 00000000..7bab4676 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/resources/autogenExampleInit.m @@ -0,0 +1,17 @@ +clear all; +close all; +clc; + +%% Simulink model properties for an example case +V_i = 3; % This is a voltage at analog input +V_g = 1/10; % This is the gain to scale the analog input by and set PWM duty ratio +V_hi = 0.9; % Upper limit of PWM duty cycle +V_low = 0; % Lower limit of PWM duty cycle + +%% Simulation time +T_end = 10; % Simulation end time +T_step = 1e-6; % Simulation time step + +%% Autogen code for the controller +model='exampleController'; % Name of the controller to be built +slbuild(model); % Generates the autogen code diff --git a/source/getting-started/tutorials/autogen/images/autogen-model-subsystem.svg b/source/getting-started/tutorials/autogen/images/autogen-model-subsystem.svg new file mode 100644 index 00000000..905803ee --- /dev/null +++ b/source/getting-started/tutorials/autogen/images/autogen-model-subsystem.svg @@ -0,0 +1 @@ +InputOutputgenerateDutyDothetaduty_aduty_bduty_cgenerateDutyomegathetaDoduty_aduty_bduty_c diff --git a/source/getting-started/tutorials/autogen/images/autogen-model.svg b/source/getting-started/tutorials/autogen/images/autogen-model.svg new file mode 100644 index 00000000..7de58e79 --- /dev/null +++ b/source/getting-started/tutorials/autogen/images/autogen-model.svg @@ -0,0 +1 @@ +InputCalculate Duty Ratio Outputcos+coscos+xxx++++++omegathetaDoduty_aduty_bduty_c diff --git a/source/getting-started/tutorials/autogen/images/integrator-model.svg b/source/getting-started/tutorials/autogen/images/integrator-model.svg new file mode 100644 index 00000000..6de4fc27 --- /dev/null +++ b/source/getting-started/tutorials/autogen/images/integrator-model.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/getting-started/tutorials/autogen/index.md b/source/getting-started/tutorials/autogen/index.md new file mode 100644 index 00000000..3d116820 --- /dev/null +++ b/source/getting-started/tutorials/autogen/index.md @@ -0,0 +1,231 @@ +# Tutorial: Autogen + +- **Goal:** Generate Autogen code based on Simulink model. +- **Complexity:** 3 / 5 +- **Estimated Time:** 40 min + +This tutorial goes over: + +- Organization of your repository to store the Simulink Autogen codebase +- Creation a Simulink simulation model to generate Autogen code +- Control implementation using the AMDC hardware + +## Tutorial Requirements + +1. Working AMDC hardware +2. Completion of the ["Voltage Source Inverter" tutorial](../vsi/index.md) +3. Read ["Control with AMDC Using Simulink Autogen" article](../../control-with-amdc/autogen/index.md) to understand an overview of Autogen + +## File Organization + +The first step is to organize your repository. Create a new `modeling/simulink` folder and an `autogen` folder in your repository, as shown below: + +```markdown +my-AMDC-workspace/ <= master repo +|-- modeling/ +| |-- simulink/ <= Now create this folder +|-- control/ + |-- AMDC-Firmware/ <= AMDC-Firmware as submodule + |-- my-AMDC-private-C-code/ <= Your private user C code + |-- usr/ + | -- controller/ <= Your private user app + | -- autogen/ <= Now create this folder +``` + +## Install Required MATLAB/Simulink Toolbox + +To develop control code using Simulink Autogen, the following software components are required: + +- [Simulink Coder](https://www.mathworks.com/help/rtw/index.html) +- [Embedded Coder](https://www.mathworks.com/help/ecoder/index.html) + +Additional toolboxes may be required depending on the specific control design. + +## Create a Simulink Model + +Now that you create a Simulink model that will be used to generate Autogen code. In this example, you will replace the C code in the VSI app developed in the ["Voltage Source Inverter" tutorial](../vsi/index.md) with Autogen code to calculate the duty ratios. + +1. In `simulink` folder, create a new MATLAB file named `setup.m`. +2. In `setup.m`, copy-paste the following MATLAB code: + +```MATLAB +fs = 10e3; % sampling frequency (Hz) +Ts = 1/fs; % sampling time (sec) +Tsim = Ts/10; % simulation time (s) + +omega = 377.0; % (rad/s) +Do = 0.8; % (--) +``` + +3. Open a blank model of Simulink, and save it as `setupModel.slx` in the `simulink` folder. +4. Add a `Constant` block and set its value to `omega`. +5. Add an `Integrator` block and connect it to the `Constant` block. Rename the output signal of this integrator to be `theta`. +6. Add a `Constant` block and set its value to `Do`. +7. Add two `Rate Transition` blocks and connect them to the `Integrator` and `Constant` blocks created above. In each `Rate Transition` block, set the sampling time `Ts`. +8. Create Simulink blocks to implement the following duty ratio calculation developed [here](../vsi/index.md/#c-code-controller): + +```c +// Calculate desired duty ratios +double duty_a = 0.5 + Do/2.0 * cos(theta); +double duty_b = 0.5 + Do/2.0 * cos(theta - 2.0*M_PI/3.0); +double duty_c = 0.5 + Do/2.0 * cos(theta - 4.0*M_PI/3.0); +``` + +9. Add a `Rate Transition` block after the duty ratio calculations. In these blocks, set the sampling time to `-1`. +10. The expected block diagram is shown below: + +```{image} images/autogen-model.svg +:alt: Autogen model +:width: 600px +:align: center +``` + +### Model Setting + +1. In `Modeling` tab, press `Model Settings` in `TOP MODEL` section. + 1. Under the `Solver` tree, in the `Solver Selection`, press `Fixed-step`. + 2. Set `Fixed-step-size` as `Tsim`. +2. Go to `Code Generation`. + 1. Click `Browse` for the `System target file`. + 2. Select `ert.tlc Embedded coder`. + 3. In the `Build process` section, check `Generate code only`. +3. Go to `Optimization` under `Code Generation`. + 1. Choose `None` for the `Leverage target hardware instruction set extensions` in the `Target specific optimizations`. +4. Go to `Templates` under `Code Generation`. + 1. Uncheck `Generate an example main program` in the `Custom templates` section. +5. Click `Apply` and `OK`. + +### Create a Referenced Model + +1. Select the duty ratio calculation blocks, and right-click. +2. Select `Create Subsystem from Selection`. +3. Right-click on the subsystem created. Select `Block parameters (Subsystem)`, check `Treat as atomic unit`, and click `OK`. +4. Right-click on the subsystem and select `Subsystem & Model Reference`. Select `Convert` and click `Referenced Model ...`. +5. In the `Input Parameters` section, define the `New model name` as `generateDuty`. +6. Click `Apply` and `Convert`. +7. Rename the referenced model block to be `generateDuty`. The expected Simulink model is shown below: + +```{image} images/autogen-model-subsystem.svg +:alt: Autogen model subsystem +:width: 600px +:align: center +``` + +### Referenced Model Setting + +1. Double-click the `generateDuty` referenced model and click `Model Settings` under `Modeling` tab. +2. Click `Model Settings` in the `REFERENCED MODEL` section. + 1. Under the `Solver` tree, set `Fixed-step-size` as `Ts`. +3. Save the Simulink file. + +The example of Simulink file along with the referenced model is stored [here](./simulink/). Note that this Simulink model was created using MATLAB R2024b. + +### Generate C-code + +1. Open the `setup.m`. +2. Copy and paste the following code. + +```MATLAB +%% Autogen code for the controller +model='generateDuty'; % name of the controller to be built +slbuild(model); % generates the Autogen code +oldFolder = cd('C:generateDuty_ert_rtw\'); +% Copy only .c and .h files in autogen folder +command = 'for /r %i in (*.c, *.h) do copy /y %i ..\..\..\control\my-AMDC-private-C-code\usr\controller\autogen'; +[status, cmdout] = system(command); +cd(oldFolder); +``` + +3. Run the `setup.m` to generate C code. All autogenerated `.c` and `.h` files should be placed within `autogen` folder. Among these generated files, the most relevant are: + +- `generateDuty.c` — implementation of the control logic +- `generateDuty.h` — interface definitions (inputs, outputs, function declarations) + +These files define the controller as a callable function with input and output structures, consistent with the execution model described earlier. + +4. Open the SDK, and make sure that the `autogen` folder appears under the `Project Explorer`. If it does not, refresh the project. + +## Integration with AMDC + +Now, the user needs to update the user C code developed in the ["Voltage Source Inverter" tutorial](../vsi/index.md) to incorporate the Autogen code generated from Simulink. Specifically, this requires modifying `task_controller_clear`, `task_controller_init`, and `task_controller_callback` functions. Within the callback function, the control task executes the developed code at a fixed sampling interval, and the following items need to be included: + +1. Populate inputs, such as constant values or sampled sensor data. The input variables are defined with `_U` suffix (e.g., `generateDuty_U`). +2. Call the controller step function +3. Route outputs to actuators, such as PWM duty cycles. The output variables are defined with `_Y` suffix (e.g., `generateDuty_Y`). + +The functions that need to be updated for this example are shown below: + +`task_controller.c`: + +```c +// ... + +int task_controller_clear(void) +{ + // ... + + // Clear state struct for Simulink controller + memset(((void *) &generateDuty_DW_DW), 0, sizeof(DW_generateDuty_T)); + + // ... +} + +int task_controller_init(void) +{ + // ... + + // Initialize Autogen step + generateDuty_initialize(); + + // ... +} + +double Ts = 1.0 / (double) TASK_CONTROLLER_UPDATES_PER_SEC; +double theta = 0.0; // [rad] +double omega = 377.0; // [rad/s] +double Do = 0.8; // [--] + +void task_controller_callback(void *arg) +{ + // ... + + // Update theta + theta += (Ts * omega); + + // Wrap to 2*pi + theta = fmod(theta, 2.0 * M_PI); + + // Populate inputs + generateDuty_U.Do = Do; // Inputs to controller as a constant value + generateDuty_U.theta = theta; // Inputs to controller as feedback + + // Call Autogen code + generateDuty_step(); + + // Calculate desired duty ratios + double duty_a = generateDuty_Y.duty_a; // Outputs from controller + double duty_b = generateDuty_Y.duty_b; // Outputs from controller + double duty_c = generateDuty_Y.duty_c; // Outputs from controller + + // Update PWM peripheral in FPGA + pwm_set_duty(0, duty_a); // Set HB1 duty ratio (INV1, PWM1 and PWM2) + pwm_set_duty(1, duty_b); // Set HB2 duty ratio (INV1, PWM3 and PWM4) + pwm_set_duty(2, duty_c); // Set HB3 duty ratio (INV1, PWM5 and PWM6) + + // ... +} +``` + +```{note} +In this example, the input `theta` is generated within the code. However, this can be obtained from sensor measurements, such as encoder readings. +``` + +## Running the AMDC + +We are now ready to run the new control code with Autogen! Try running the control task by typing `ctrl init`. You should obtain the same results as in the ["Voltage Source Inverter" tutorial](../vsi/index.md). + +## Conclusion + +**Congratulations!** + +You have now built an updated user app with Autogen code for the voltage source inverter. These techniques can be extended for many other control problems, e.g., current regulation, motion control, or even more advanced controller. By modifying the Simulink model and continuously generating C code, you can effectively develop new control algorithms. diff --git a/source/getting-started/tutorials/autogen/simulink/.gitignore b/source/getting-started/tutorials/autogen/simulink/.gitignore new file mode 100644 index 00000000..dc3e33f2 --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/.gitignore @@ -0,0 +1,5 @@ +# ignore MATLAB files + +**/slprj +*.autosave +*.slxc \ No newline at end of file diff --git a/source/getting-started/tutorials/autogen/simulink/autogen/integrator.c b/source/getting-started/tutorials/autogen/simulink/autogen/integrator.c new file mode 100644 index 00000000..95f41992 --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/autogen/integrator.c @@ -0,0 +1,65 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: integrator.c + * + * Code generated for Simulink model 'integrator'. + * + * Model version : 1.2 + * Simulink Coder version : 25.2 (R2025b) 28-Jul-2025 + * C/C++ source code generated on : Fri Dec 12 15:58:48 2025 + * + * Target selection: ert.tlc + * Embedded hardware selection: Intel->x86-64 (Windows64) + * Code generation objectives: Unspecified + * Validation result: Not run + */ + +#include "integrator.h" + +/* Block states (default storage) */ +DW_integrator_T integrator_DW; + +/* External inputs (root inport signals with default storage) */ +ExtU_integrator_T integrator_U; + +/* External outputs (root outports fed by signals with default storage) */ +ExtY_integrator_T integrator_Y; + +/* Real-time model */ +static RT_MODEL_integrator_T integrator_M_; +RT_MODEL_integrator_T *const integrator_M = &integrator_M_; + +/* Model step function */ +void integrator_step(void) +{ + /* Outport: '/Out1' incorporates: + * DiscreteIntegrator: '/Discrete-Time Integrator' + */ + integrator_Y.Out1 = integrator_DW.DiscreteTimeIntegrator_DSTATE; + + /* Update for DiscreteIntegrator: '/Discrete-Time Integrator' incorporates: + * Inport: '/In1' + */ + integrator_DW.DiscreteTimeIntegrator_DSTATE += 0.0001 * integrator_U.In1; +} + +/* Model initialize function */ +void integrator_initialize(void) +{ + /* (no initialization code required) */ +} + +/* Model terminate function */ +void integrator_terminate(void) +{ + /* (no terminate code required) */ +} + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/source/getting-started/tutorials/autogen/simulink/autogen/integrator.h b/source/getting-started/tutorials/autogen/simulink/autogen/integrator.h new file mode 100644 index 00000000..e48642c4 --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/autogen/integrator.h @@ -0,0 +1,98 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: integrator.h + * + * Code generated for Simulink model 'integrator'. + * + * Model version : 1.2 + * Simulink Coder version : 25.2 (R2025b) 28-Jul-2025 + * C/C++ source code generated on : Fri Dec 12 15:58:48 2025 + * + * Target selection: ert.tlc + * Embedded hardware selection: Intel->x86-64 (Windows64) + * Code generation objectives: Unspecified + * Validation result: Not run + */ + +#ifndef integrator_h_ +#define integrator_h_ +#ifndef integrator_COMMON_INCLUDES_ +#define integrator_COMMON_INCLUDES_ +#include "rtwtypes.h" +#include "math.h" +#endif /* integrator_COMMON_INCLUDES_ */ + +#include "integrator_types.h" + +/* Macros for accessing real-time model data structure */ +#ifndef rtmGetErrorStatus +#define rtmGetErrorStatus(rtm) ((rtm)->errorStatus) +#endif + +#ifndef rtmSetErrorStatus +#define rtmSetErrorStatus(rtm, val) ((rtm)->errorStatus = (val)) +#endif + +/* Block states (default storage) for system '' */ +typedef struct { + real_T DiscreteTimeIntegrator_DSTATE;/* '/Discrete-Time Integrator' */ +} DW_integrator_T; + +/* External inputs (root inport signals with default storage) */ +typedef struct { + real_T In1; /* '/In1' */ +} ExtU_integrator_T; + +/* External outputs (root outports fed by signals with default storage) */ +typedef struct { + real_T Out1; /* '/Out1' */ +} ExtY_integrator_T; + +/* Real-time Model Data Structure */ +struct tag_RTM_integrator_T { + const char_T * volatile errorStatus; +}; + +/* Block states (default storage) */ +extern DW_integrator_T integrator_DW; + +/* External inputs (root inport signals with default storage) */ +extern ExtU_integrator_T integrator_U; + +/* External outputs (root outports fed by signals with default storage) */ +extern ExtY_integrator_T integrator_Y; + +/* Model entry point functions */ +extern void integrator_initialize(void); +extern void integrator_step(void); +extern void integrator_terminate(void); + +/* Real-time Model object */ +extern RT_MODEL_integrator_T *const integrator_M; + +/*- + * The generated code includes comments that allow you to trace directly + * back to the appropriate location in the model. The basic format + * is /block_name, where system is the system number (uniquely + * assigned by Simulink) and block_name is the name of the block. + * + * Use the MATLAB hilite_system command to trace the generated code back + * to the model. For example, + * + * hilite_system('') - opens system 3 + * hilite_system('/Kp') - opens and selects block Kp which resides in S3 + * + * Here is the system hierarchy for this model + * + * '' : 'integrator' + */ +#endif /* integrator_h_ */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/source/getting-started/tutorials/autogen/simulink/autogen/integrator_private.h b/source/getting-started/tutorials/autogen/simulink/autogen/integrator_private.h new file mode 100644 index 00000000..836e1446 --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/autogen/integrator_private.h @@ -0,0 +1,30 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: integrator_private.h + * + * Code generated for Simulink model 'integrator'. + * + * Model version : 1.2 + * Simulink Coder version : 25.2 (R2025b) 28-Jul-2025 + * C/C++ source code generated on : Fri Dec 12 15:58:48 2025 + * + * Target selection: ert.tlc + * Embedded hardware selection: Intel->x86-64 (Windows64) + * Code generation objectives: Unspecified + * Validation result: Not run + */ + +#ifndef integrator_private_h_ +#define integrator_private_h_ +#include "rtwtypes.h" +#include "integrator_types.h" +#endif /* integrator_private_h_ */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/source/getting-started/tutorials/autogen/simulink/autogen/integrator_types.h b/source/getting-started/tutorials/autogen/simulink/autogen/integrator_types.h new file mode 100644 index 00000000..6e991e41 --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/autogen/integrator_types.h @@ -0,0 +1,32 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: integrator_types.h + * + * Code generated for Simulink model 'integrator'. + * + * Model version : 1.2 + * Simulink Coder version : 25.2 (R2025b) 28-Jul-2025 + * C/C++ source code generated on : Fri Dec 12 15:58:48 2025 + * + * Target selection: ert.tlc + * Embedded hardware selection: Intel->x86-64 (Windows64) + * Code generation objectives: Unspecified + * Validation result: Not run + */ + +#ifndef integrator_types_h_ +#define integrator_types_h_ + +/* Forward declaration for rtModel */ +typedef struct tag_RTM_integrator_T RT_MODEL_integrator_T; + +#endif /* integrator_types_h_ */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/source/getting-started/tutorials/autogen/simulink/autogen/rtmodel.h b/source/getting-started/tutorials/autogen/simulink/autogen/rtmodel.h new file mode 100644 index 00000000..17e57eab --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/autogen/rtmodel.h @@ -0,0 +1,34 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: rtmodel.h + * + * Code generated for Simulink model 'integrator'. + * + * Model version : 1.2 + * Simulink Coder version : 25.2 (R2025b) 28-Jul-2025 + * C/C++ source code generated on : Fri Dec 12 15:58:48 2025 + * + * Target selection: ert.tlc + * Embedded hardware selection: Intel->x86-64 (Windows64) + * Code generation objectives: Unspecified + * Validation result: Not run + */ + +#ifndef rtmodel_h_ +#define rtmodel_h_ +#include "integrator.h" + +/* Macros generated for backwards compatibility */ +#ifndef rtmGetStopRequested +#define rtmGetStopRequested(rtm) ((void*) 0) +#endif +#endif /* rtmodel_h_ */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/source/getting-started/tutorials/autogen/simulink/autogen/rtwtypes.h b/source/getting-started/tutorials/autogen/simulink/autogen/rtwtypes.h new file mode 100644 index 00000000..e074d42d --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/autogen/rtwtypes.h @@ -0,0 +1,160 @@ +/* + * Academic License - for use in teaching, academic research, and meeting + * course requirements at degree granting institutions only. Not for + * government, commercial, or other organizational use. + * + * File: rtwtypes.h + * + * Code generated for Simulink model 'integrator'. + * + * Model version : 1.2 + * Simulink Coder version : 25.2 (R2025b) 28-Jul-2025 + * C/C++ source code generated on : Fri Dec 12 15:58:48 2025 + * + * Target selection: ert.tlc + * Embedded hardware selection: Intel->x86-64 (Windows64) + * Code generation objectives: Unspecified + * Validation result: Not run + */ + +#ifndef RTWTYPES_H +#define RTWTYPES_H + +/* Logical type definitions */ +#if (!defined(__cplusplus)) +#ifndef false +#define false (0U) +#endif + +#ifndef true +#define true (1U) +#endif +#endif + +/*=======================================================================* + * Target hardware information + * Device type: Intel->x86-64 (Windows64) + * Number of bits: char: 8 short: 16 int: 32 + * long: 32 + * native word size: 64 + * Byte ordering: LittleEndian + * Signed integer division rounds to: Zero + * Shift right on a signed integer as arithmetic shift: on + *=======================================================================*/ + +/*=======================================================================* + * Fixed width word size data types: * + * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * + * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * + * real32_T, real64_T - 32 and 64 bit floating point numbers * + *=======================================================================*/ +typedef signed char int8_T; +typedef unsigned char uint8_T; +typedef short int16_T; +typedef unsigned short uint16_T; +typedef int int32_T; +typedef unsigned int uint32_T; +typedef float real32_T; +typedef double real64_T; + +/*===========================================================================* + * Generic type definitions: boolean_T, char_T, byte_T, int_T, uint_T, * + * real_T, time_T, ulong_T. * + *===========================================================================*/ +typedef double real_T; +typedef double time_T; +typedef unsigned char boolean_T; +typedef int int_T; +typedef unsigned int uint_T; +typedef unsigned long ulong_T; +typedef char char_T; +typedef unsigned char uchar_T; +typedef char_T byte_T; + +/*===========================================================================* + * Complex number type definitions * + *===========================================================================*/ +#define CREAL_T + +typedef struct { + real32_T re; + real32_T im; +} creal32_T; + +typedef struct { + real64_T re; + real64_T im; +} creal64_T; + +typedef struct { + real_T re; + real_T im; +} creal_T; + +#define CINT8_T + +typedef struct { + int8_T re; + int8_T im; +} cint8_T; + +#define CUINT8_T + +typedef struct { + uint8_T re; + uint8_T im; +} cuint8_T; + +#define CINT16_T + +typedef struct { + int16_T re; + int16_T im; +} cint16_T; + +#define CUINT16_T + +typedef struct { + uint16_T re; + uint16_T im; +} cuint16_T; + +#define CINT32_T + +typedef struct { + int32_T re; + int32_T im; +} cint32_T; + +#define CUINT32_T + +typedef struct { + uint32_T re; + uint32_T im; +} cuint32_T; + +/*=======================================================================* + * Min and Max: * + * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * + * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * + *=======================================================================*/ +#define MAX_int8_T ((int8_T)(127)) +#define MIN_int8_T ((int8_T)(-128)) +#define MAX_uint8_T ((uint8_T)(255U)) +#define MAX_int16_T ((int16_T)(32767)) +#define MIN_int16_T ((int16_T)(-32768)) +#define MAX_uint16_T ((uint16_T)(65535U)) +#define MAX_int32_T ((int32_T)(2147483647)) +#define MIN_int32_T ((int32_T)(-2147483647-1)) +#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) + +/* Block D-Work pointer type */ +typedef void * pointer_T; + +#endif /* RTWTYPES_H */ + +/* + * File trailer for generated code. + * + * [EOF] + */ diff --git a/source/getting-started/tutorials/autogen/simulink/generateDuty.slx b/source/getting-started/tutorials/autogen/simulink/generateDuty.slx new file mode 100644 index 00000000..e8bd7a12 Binary files /dev/null and b/source/getting-started/tutorials/autogen/simulink/generateDuty.slx differ diff --git a/source/getting-started/tutorials/autogen/simulink/setup.asv b/source/getting-started/tutorials/autogen/simulink/setup.asv new file mode 100644 index 00000000..68a1dd0e --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/setup.asv @@ -0,0 +1,4 @@ + + +Ts = 1/(10e3); %Hz +Tsim = diff --git a/source/getting-started/tutorials/autogen/simulink/setup.m b/source/getting-started/tutorials/autogen/simulink/setup.m new file mode 100644 index 00000000..5ccdefc7 --- /dev/null +++ b/source/getting-started/tutorials/autogen/simulink/setup.m @@ -0,0 +1,18 @@ +clear; clc; + +fs = 10e3; % sampling frequency (Hz) +Ts = 1/fs; % sampling time (sec) +Tsim = Ts/10; % simulation time (s) + +omega = 377.0; % (rad/s) +Do = 0.8; % (--) + +%% Autogen code for the controller +model='generateDuty'; % name of the controller to be built +slbuild(model); % generates the Autogen code +oldFolder = cd('C:generateDuty_ert_rtw\'); +% Copy only .c and .h files in autogen folder +command = 'for /r %i in (*.c, *.h) do copy /y %i ..\..\..\control\my-AMDC-private-C-code\usr\controller\autogen'; +[status, cmdout] = system(command); +cd(oldFolder); + diff --git a/source/getting-started/tutorials/autogen/simulink/setupModel.slx b/source/getting-started/tutorials/autogen/simulink/setupModel.slx new file mode 100644 index 00000000..5623215d Binary files /dev/null and b/source/getting-started/tutorials/autogen/simulink/setupModel.slx differ