Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
efef0a4
Add indexme file for the Autogen
Daehoon-Sung Dec 12, 2025
52120e3
Save the setup matlab file and simulink model
Daehoon-Sung Dec 12, 2025
37cda4a
Update the matlab code
Daehoon-Sung Dec 12, 2025
8be0727
Add gitignore and update the simulink
Daehoon-Sung Dec 12, 2025
5155e62
Add auatogen code
Daehoon-Sung Dec 12, 2025
0637235
Update the simulink
Daehoon-Sung Dec 12, 2025
968d3bb
Update the images
Daehoon-Sung Dec 19, 2025
c8b9457
Update the images
Daehoon-Sung Dec 19, 2025
983a023
Revise index.md for Simulink code generation guide
Daehoon-Sung Dec 19, 2025
8599a94
Revise Simulink model setup and C-code generation steps
Daehoon-Sung Dec 21, 2025
2977772
Update image width in autogen index markdown
Daehoon-Sung Dec 21, 2025
0c425e7
Update image width for integrator model in index.md
Daehoon-Sung Dec 21, 2025
620303f
Update index.md
Daehoon-Sung Dec 21, 2025
23000c9
Rename files
noguchi-takahiro Dec 26, 2025
378b580
Update m code in the article
noguchi-takahiro Dec 26, 2025
59594ee
Rename images and update document
noguchi-takahiro Dec 26, 2025
4426256
Update readme
noguchi-takahiro Dec 26, 2025
f5abcd8
Update bullet points
noguchi-takahiro Dec 26, 2025
af99cff
Update size of figure
noguchi-takahiro Dec 26, 2025
b5670f8
Add overview of Autogen
noguchi-takahiro Dec 26, 2025
6b48e2b
Update README
noguchi-takahiro Dec 26, 2025
16ed4ff
Update readme
noguchi-takahiro Dec 26, 2025
2fa6045
Update README
noguchi-takahiro Dec 26, 2025
798529b
Update readme
noguchi-takahiro Dec 26, 2025
213c357
Update indent
noguchi-takahiro Dec 26, 2025
4afe976
Add period
noguchi-takahiro Dec 26, 2025
a2e5724
Update readme
noguchi-takahiro Dec 26, 2025
cd8ac9e
Update readme
noguchi-takahiro Dec 26, 2025
142ebd0
Update REAMDE
noguchi-takahiro Dec 26, 2025
a6f53a9
Update article
noguchi-takahiro Dec 26, 2025
f1a9485
Remove not used picture
noguchi-takahiro Dec 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
170 changes: 170 additions & 0 deletions source/getting-started/control-with-amdc/autogen/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Simulink Automatic Code Generation for AMDC

This article explains how to implement the Simulink automatic code generation (Autogen) by demonstrating an example using a simple integrator.

## Simulink Autogen Code

Autogen is the process of converting a user Simulink model for a controller into equivalent C code for an embedded system (such as the AMDC). The Autogen feature in Simulink can be used to conveniently convert complex controller implementations into C-code for implementing it on the AMDC. This article presents a step-by-step process of using Autogen to convert a simle integrator (as shown in the figure below) into C code.

```{image} images/integrator-model.svg
:alt: Integrator model
:width: 300px
:align: center
```

## Procedure

### Pre-Requisites

User needs to install at least the following dedicated MATLAB/Simulink toolboxes/features:

- Simulink
- Embedded coder
- Simulink coders

### File Organization

This article assumes that the uses has completed the [Blink tutorial](../../tutorials/blink/index.md), where you set up your repository. To follow this Autogen tutorial, create a new `simulink` folder in your repository and organize the files as shown below:

```markdown
my-AMDC-workspace/ <= master repo
AMDC-Firmware/ <= AMDC-Firmware as library
...
my-AMDC-private-C-code/ <= Your private user C code
...
simulink/ <= Now create this folder
```

### Create a Simulink Model

1. In `simulink` folder, create a new MATLAB file (e.g., `setup.m`).
2. In `setup.m`, define `fs = 10e3`, `Ts = 1/fs`, `Tsim = Ts/10`.

User can copy-paste the following MATLAB code:

```MATLAB
fs = 10e3; % sampling frequency (Hz)
Ts = 1/fs; % sampling time (sec)
Tsim = Ts/10; % simulation time (s)
```

3. Open a blank model of Simulink, and save as `setupModel.slx` in `simulink` folder.
4. Add a `Step` block with the default setting.
5. Add a `Discrete-Time Integrator` block with the default setting.
6. Add a `Rate Transition` block before the integrator. In this block, put `Ts` as a sampling time.
7. Add a `Rate Transition` block after the integrator. In this block, set the sampling time to `-1`.
8. Add a continuous-time `Transfer Fcn` block as a Plant (= 1).
9. Add a `Sum` function and connect each block as 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 discrete-time integrator, 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 `integrator`.
6. Click `Apply` and `Convert`.
7. Rename the referenced model block to be `integrator`. 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 `integrator` referenced model and click `Model Settings` under `Modeling` tab.
2. Click `Model Settings` in the `REFERENCED MODEL` section.
1. 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/).

### Generate C-code

1. Open the `setup.m`.
2. Copy and paste the following code.

```MATLAB
%% Autogen code for the controller
model='integrator'; % name of the controller to be built
slbuild(model); % generates the Autogen code
oldFolder = cd('C:integrator_ert_rtw\');
% Copy only .c and .h files in autogen folder
command = 'for /r %i in (*.c, *.h) do copy /y %i ..\autogen';
[status, cmdout] = system(command);
cd(oldFolder);
```

3. Run the `setup.m`, and Autogen code are created in `simulink/autogen` folder.

### Integration with AMDC

Now, the user needs to update the user C code to incorporate the Autogen code generated from Simulink. To do this, update `task_controller.c` as follows:

`task_controller.c`:

```c
// ...

int task_controller_clear(void)
{
// ...

// Clear state struct for Simulink controller
memset(((void *) &integrator_DW_DW), 0, sizeof(DW_integrator_T));

// ...
}

int task_controller_init(void)
{
// ...

// Initialize Autogen step
integrator_initialize();

// ...
}

void task_controller_callback(void *arg)
{
// ...

// Update controller input parameters
integrator_U.STEP = STEP;

// Call Autogen code
integrator_step();

// ...
}
```

## Results

THIS SECTION WILL BE UPDATED!

- After running the AMDC, show the input and output value through logging feature.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# ignore MATLAB files

**/slprj
*.autosave
*.slxc
Original file line number Diff line number Diff line change
@@ -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: '<Root>/Out1' incorporates:
* DiscreteIntegrator: '<Root>/Discrete-Time Integrator'
*/
integrator_Y.Out1 = integrator_DW.DiscreteTimeIntegrator_DSTATE;

/* Update for DiscreteIntegrator: '<Root>/Discrete-Time Integrator' incorporates:
* Inport: '<Root>/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]
*/
Loading