From efef0a49841951576218b850f9cf971cfe8bb29d Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 12 Dec 2025 15:22:35 -0600 Subject: [PATCH 01/31] Add indexme file for the Autogen --- .../control-with-amdc/autogen/index.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 source/getting-started/control-with-amdc/autogen/index.md 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..e4c3ae34 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -0,0 +1,60 @@ +# Current Sensor Calibration + +## Background + +Motor drives typically require current sensors to provide feedback to the control system. This document describes a method to calibrate the current sensors to a linear model during commissioning of a motor drive. The calibration is characterized by two parameters, a gain and an offset, that describe how the sensed current appears as a voltage to the AMDC. + +Current sensors are transducers which produce an output signal (either current or voltage) proportional to the primary current flowing through the sensor. There are different types of current sensors relying on different physical phenomenons such as shunt resistors and hall-effect. For the purpose of this document, the specific type of sensor does not matter---just that the output signal is linear with the primary current, and that it is measured as a voltage by the control system. The current sensor needs to be calibrated against an appropriate reference before it can be used in the control system. This reference is a known, trusted current sensor, such as a precision digital multimeter (preferred), hall-effect current clamp, or the setpoint of a DC power supply. While the manufacturer datasheet provides nominal parameters, calibration of the current sensor is necessary to get accurate measurements to account for any deviation due to process variation. + +## Calibration Method + +A method is now provided to calibrate the current sensors in a motor drive. An example of the assumed system for a three phase motor is shown in the figure below. + +![Current Sensor Configuration](resources/current_sensor_drawing.svg) + +Typically, each phase has a current sensor associated with it that needs to be calibrated. This method assumes that the signal measured by the AMDC for each sensor is a voltage that must be converted into a current value. + +1. Connect the reference curent sensor (i.e. precision digital multimeter) to the phase U cable of the motor. +1. Set up your AMDC system to enable you to log the raw reading of the drive's current sensor attached to phase U (presumably, by sampling an ADC channel). It is recommended to use the AMDC's logging functionality so that data can be collected over a period of time (e.g. 100 ms) and post-processed to find the average value. +1. Record the drive's sensor reading when there is no current flowing through phase U. _Hint:_ remember to calculate this value as the average over a period of time. +1. Cause a "small" curent to flow through phase U (i.e., apply a voltage across phase U). The value of current is left to the discretion of the user based on the system nominal ratings. +1. Record the drive's sensor reading as well as the reference sensor's reading of the current flowing through the phase U cable. +1. Progressively increase the phase U current and record the readings. Do this over the full range of rated current, both positive and negative. +1. Tabulate the measurements as shown in this example [`exp_data.csv` file](./resources/exp_data.csv). +1. Fit a linear expression of the form $\text{Reading [V]} = \text{Gain [V/A]} \times \text{Current [A]} + \text{Offset [V]}$ to the obtained measurements. This [example Jupyter notebook](./resources/current_sensor_calibration.ipynb) is provided to illustrate the process. +1. Repeat the exercise for the remaining phases of the system. + +An example of the results are shown in the plot below. The obtained gain and offset can be used directly in the control code to convert the sensor reading into the actual current measurement. + +![Example Results](resources/fit.svg) + +```{tip} +Be sure to conduct the calibration process over the full range of current data (both positive and negative current) to account for any variation in the current sensor reading due to directionality of current. +``` +## Use of Calibration Data + +The below codeblock can be utilized by the user to convert between raw measurements from the sensor and the actual currents. + +```C +#define INV_GAIN (1.0/0.621) // Inverse of gain obtained from curve fit (1/0.621) +double offset = 4.739; // [V], offset from curve fit. This is a variable so that the drive can remeasure and adjust the offset at startup + +double current_measurement; // Actual current measurement, to be used in control algorithm + +current_measurement = (sensor_reading - offset)*INV_GAIN; // sensor_reading is the raw measurement and needs to be obtained by the user +``` + +```{tip} +In AMDC firmware versions 1.4.1 and above, the amds driver has a built in function `amds_convert_voltage()` to streamline this process. Default offset and gain values for each different sensor card are also included. +``` + +## Recalculate Offset At Startup +The offset value of the current sensors can drift over time. It is recommended that drive developers include code in their control logic to automatically re-zero the current sensor at startup, as follows: + +1. Prior to enabling the PWM, when it is known that there is no current flowing in the motor, record approximately 100 ms of sensor data on each phase. +2. For each phase, calculate the average of this data and use it as the new `offset` value in the code block above. +3. Proceed with starting-up the drive. + +## Conclusion + +The current sensor calibration method presented in this article should be viewed as a best-practice for motor drive development. Readers are welcome to directly use the provided code and Jupyter notebook in their motor drives. From 52120e3006516f9dc2853aeac682e9670fce1d7c Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 12 Dec 2025 15:32:44 -0600 Subject: [PATCH 02/31] Save the setup matlab file and simulink model --- .../control-with-amdc/autogen/simulink/setup.m | 0 .../autogen/simulink/setupModel.slx | Bin 0 -> 73127 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/setup.m create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/setupModel.slx diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setup.m b/source/getting-started/control-with-amdc/autogen/simulink/setup.m new file mode 100644 index 00000000..e69de29b diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setupModel.slx b/source/getting-started/control-with-amdc/autogen/simulink/setupModel.slx new file mode 100644 index 0000000000000000000000000000000000000000..d2ddd5ae29028c42cb7f95f94246e56d4f873741 GIT binary patch literal 73127 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 bQfQ{5r%w#ygeJs8__;bP#E%DXWQczN54ArB literal 0 HcmV?d00001 From 37cda4ad706cc5234448ca8b80687bfc8f9c4e16 Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 12 Dec 2025 15:40:35 -0600 Subject: [PATCH 03/31] Update the matlab code --- .../control-with-amdc/autogen/simulink/setup.asv | 4 ++++ .../control-with-amdc/autogen/simulink/setup.m | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/setup.asv diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setup.asv b/source/getting-started/control-with-amdc/autogen/simulink/setup.asv new file mode 100644 index 00000000..68a1dd0e --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/simulink/setup.asv @@ -0,0 +1,4 @@ + + +Ts = 1/(10e3); %Hz +Tsim = diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setup.m b/source/getting-started/control-with-amdc/autogen/simulink/setup.m index e69de29b..d4e95298 100644 --- a/source/getting-started/control-with-amdc/autogen/simulink/setup.m +++ b/source/getting-started/control-with-amdc/autogen/simulink/setup.m @@ -0,0 +1,4 @@ +clear; clc; + +Ts = 1/(10e3); % sec +Tsim = Ts/10; % sec \ No newline at end of file From 8be0727bc148a8cb22606a9671a5f89a60028f9e Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 12 Dec 2025 15:53:41 -0600 Subject: [PATCH 04/31] Add gitignore and update the simulink --- .../autogen/simulink/.gitignore | 5 +++++ .../autogen/simulink/integrator.slx | Bin 0 -> 72569 bytes 2 files changed, 5 insertions(+) create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/.gitignore create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/integrator.slx diff --git a/source/getting-started/control-with-amdc/autogen/simulink/.gitignore b/source/getting-started/control-with-amdc/autogen/simulink/.gitignore new file mode 100644 index 00000000..dc3e33f2 --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/integrator.slx b/source/getting-started/control-with-amdc/autogen/simulink/integrator.slx new file mode 100644 index 0000000000000000000000000000000000000000..0a4f10658fe8328bd7759a05a917b3202338bb7a GIT binary patch literal 72569 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 Date: Fri, 12 Dec 2025 16:02:05 -0600 Subject: [PATCH 05/31] Add auatogen code --- .../autogen/simulink/autogen/integrator.c | 65 +++++++ .../autogen/simulink/autogen/integrator.h | 98 +++++++++++ .../simulink/autogen/integrator_private.h | 30 ++++ .../simulink/autogen/integrator_types.h | 32 ++++ .../autogen/simulink/autogen/rtmodel.h | 34 ++++ .../autogen/simulink/autogen/rtwtypes.h | 160 ++++++++++++++++++ .../autogen/simulink/setup.m | 11 +- 7 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator.c create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator.h create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator_private.h create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator_types.h create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/autogen/rtmodel.h create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/autogen/rtwtypes.h diff --git a/source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator.c b/source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator.c new file mode 100644 index 00000000..95f41992 --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/autogen/integrator.h b/source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator.h new file mode 100644 index 00000000..e48642c4 --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/autogen/integrator_private.h b/source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator_private.h new file mode 100644 index 00000000..836e1446 --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/autogen/integrator_types.h b/source/getting-started/control-with-amdc/autogen/simulink/autogen/integrator_types.h new file mode 100644 index 00000000..6e991e41 --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/autogen/rtmodel.h b/source/getting-started/control-with-amdc/autogen/simulink/autogen/rtmodel.h new file mode 100644 index 00000000..17e57eab --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/autogen/rtwtypes.h b/source/getting-started/control-with-amdc/autogen/simulink/autogen/rtwtypes.h new file mode 100644 index 00000000..e074d42d --- /dev/null +++ b/source/getting-started/control-with-amdc/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/control-with-amdc/autogen/simulink/setup.m b/source/getting-started/control-with-amdc/autogen/simulink/setup.m index d4e95298..2c935adc 100644 --- a/source/getting-started/control-with-amdc/autogen/simulink/setup.m +++ b/source/getting-started/control-with-amdc/autogen/simulink/setup.m @@ -1,4 +1,13 @@ clear; clc; Ts = 1/(10e3); % sec -Tsim = Ts/10; % sec \ No newline at end of file +Tsim = Ts/10; % sec + +%% 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\'); +command = 'for /r %i in (*.c, *.h) do copy /y %i ..\autogen'; +[status, cmdout] = system(command); +cd(oldFolder); + From 06372353e99ea596ca7bd0b8c494eae3c0657662 Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 12 Dec 2025 16:03:11 -0600 Subject: [PATCH 06/31] Update the simulink --- .../autogen/simulink/integrator.slx | Bin 72569 -> 71977 bytes .../autogen/simulink/setup_model.slx | Bin 0 -> 82752 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/getting-started/control-with-amdc/autogen/simulink/setup_model.slx diff --git a/source/getting-started/control-with-amdc/autogen/simulink/integrator.slx b/source/getting-started/control-with-amdc/autogen/simulink/integrator.slx index 0a4f10658fe8328bd7759a05a917b3202338bb7a..76a54d7db2e0bbf2f807af556623674ebad37e17 100644 GIT binary patch delta 3556 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

i0VPRGUP}}X nD9N&d_~o1+l#{gP&LV|>rIR_?)|RAMcqR+|aBp=MiJtxqvh1W2 diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setup_model.slx b/source/getting-started/control-with-amdc/autogen/simulink/setup_model.slx new file mode 100644 index 0000000000000000000000000000000000000000..67e8f6cad7c1713925a1d163343a4428345120c1 GIT binary patch literal 82752 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 Date: Fri, 19 Dec 2025 15:29:54 -0600 Subject: [PATCH 07/31] Update the images --- .../images/autogen-model-susbsystem.svg | 172 ++++++++++++++++++ .../autogen/images/autogen-model.svg | 139 ++++++++++++++ .../images/discrete-time-integrator.svg | 1 + .../autogen/images/integrator-model.svg | 64 +++++++ .../autogen/images/rate-transition-back.svg | 1 + .../autogen/images/rate-transition-front.svg | 1 + .../autogen/images/step-block.svg | 1 + 7 files changed, 379 insertions(+) create mode 100644 source/getting-started/control-with-amdc/autogen/images/autogen-model-susbsystem.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/autogen-model.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/integrator-model.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/step-block.svg diff --git a/source/getting-started/control-with-amdc/autogen/images/autogen-model-susbsystem.svg b/source/getting-started/control-with-amdc/autogen/images/autogen-model-susbsystem.svg new file mode 100644 index 00000000..55df3a8e --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/autogen-model-susbsystem.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/autogen-model.svg b/source/getting-started/control-with-amdc/autogen/images/autogen-model.svg new file mode 100644 index 00000000..e71d87cb --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/autogen-model.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg b/source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg new file mode 100644 index 00000000..eca6bc1c --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/integrator-model.svg b/source/getting-started/control-with-amdc/autogen/images/integrator-model.svg new file mode 100644 index 00000000..6de4fc27 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/integrator-model.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg b/source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg new file mode 100644 index 00000000..2722a318 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg b/source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg new file mode 100644 index 00000000..a15ef559 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/step-block.svg b/source/getting-started/control-with-amdc/autogen/images/step-block.svg new file mode 100644 index 00000000..8ac03e02 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/step-block.svg @@ -0,0 +1 @@ + \ No newline at end of file From c8b9457fd6be5bdda6e46412b606f179566f004a Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 19 Dec 2025 16:10:56 -0600 Subject: [PATCH 08/31] Update the images --- .../control-with-amdc/autogen/images/check-atomic-unit.svg | 1 + .../control-with-amdc/autogen/images/custom-template-uncheck.svg | 1 + .../control-with-amdc/autogen/images/generate-code-only.svg | 1 + .../control-with-amdc/autogen/images/reference-model-setting.svg | 1 + .../control-with-amdc/autogen/images/reference-model-solver.svg | 1 + .../control-with-amdc/autogen/images/rename-integrator.svg | 1 + .../control-with-amdc/autogen/images/set-none-optimization.svg | 1 + .../control-with-amdc/autogen/images/step-setting.svg | 1 + .../control-with-amdc/autogen/images/system-target-file.svg | 1 + 9 files changed, 9 insertions(+) create mode 100644 source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/step-setting.svg create mode 100644 source/getting-started/control-with-amdc/autogen/images/system-target-file.svg diff --git a/source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg b/source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg new file mode 100644 index 00000000..451f9dde --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg b/source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg new file mode 100644 index 00000000..e12a7585 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg b/source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg new file mode 100644 index 00000000..082c23a0 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg b/source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg new file mode 100644 index 00000000..ee4d044f --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg b/source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg new file mode 100644 index 00000000..058b3d2a --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg b/source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg new file mode 100644 index 00000000..f4442392 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg b/source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg new file mode 100644 index 00000000..f5b987f8 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/step-setting.svg b/source/getting-started/control-with-amdc/autogen/images/step-setting.svg new file mode 100644 index 00000000..b4c39bd5 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/step-setting.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/system-target-file.svg b/source/getting-started/control-with-amdc/autogen/images/system-target-file.svg new file mode 100644 index 00000000..2070a2c9 --- /dev/null +++ b/source/getting-started/control-with-amdc/autogen/images/system-target-file.svg @@ -0,0 +1 @@ + \ No newline at end of file From 983a023644bda518fb5459b53f13b41718fa4e05 Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Fri, 19 Dec 2025 17:24:47 -0600 Subject: [PATCH 09/31] Revise index.md for Simulink code generation guide Updated the document to focus on Simulink automatic code generation for AMDC, including calibration methods, procedures, and integration with AMDC. --- .../control-with-amdc/autogen/index.md | 104 +++++++++++------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index e4c3ae34..27e586ad 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -1,60 +1,84 @@ -# Current Sensor Calibration +# Simulink Automatic Code Generation for AMDC -## Background +- This article explains how to implement the Simulink automatic code generation (autogen) by demonstrating an example using a simple integrator. -Motor drives typically require current sensors to provide feedback to the control system. This document describes a method to calibrate the current sensors to a linear model during commissioning of a motor drive. The calibration is characterized by two parameters, a gain and an offset, that describe how the sensed current appears as a voltage to the AMDC. +## Example of Model Configuration -Current sensors are transducers which produce an output signal (either current or voltage) proportional to the primary current flowing through the sensor. There are different types of current sensors relying on different physical phenomenons such as shunt resistors and hall-effect. For the purpose of this document, the specific type of sensor does not matter---just that the output signal is linear with the primary current, and that it is measured as a voltage by the control system. The current sensor needs to be calibrated against an appropriate reference before it can be used in the control system. This reference is a known, trusted current sensor, such as a precision digital multimeter (preferred), hall-effect current clamp, or the setpoint of a DC power supply. While the manufacturer datasheet provides nominal parameters, calibration of the current sensor is necessary to get accurate measurements to account for any deviation due to process variation. +- A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation. -## Calibration Method +

+ Integrator model +

-A method is now provided to calibrate the current sensors in a motor drive. An example of the assumed system for a three phase motor is shown in the figure below. +## Procedure -![Current Sensor Configuration](resources/current_sensor_drawing.svg) +### Pre-Requisites -Typically, each phase has a current sensor associated with it that needs to be calibrated. This method assumes that the signal measured by the AMDC for each sensor is a voltage that must be converted into a current value. +- User needs to install the dedicated MATLAB/Simulink toolbox/features - Embedded coder. -1. Connect the reference curent sensor (i.e. precision digital multimeter) to the phase U cable of the motor. -1. Set up your AMDC system to enable you to log the raw reading of the drive's current sensor attached to phase U (presumably, by sampling an ADC channel). It is recommended to use the AMDC's logging functionality so that data can be collected over a period of time (e.g. 100 ms) and post-processed to find the average value. -1. Record the drive's sensor reading when there is no current flowing through phase U. _Hint:_ remember to calculate this value as the average over a period of time. -1. Cause a "small" curent to flow through phase U (i.e., apply a voltage across phase U). The value of current is left to the discretion of the user based on the system nominal ratings. -1. Record the drive's sensor reading as well as the reference sensor's reading of the current flowing through the phase U cable. -1. Progressively increase the phase U current and record the readings. Do this over the full range of rated current, both positive and negative. -1. Tabulate the measurements as shown in this example [`exp_data.csv` file](./resources/exp_data.csv). -1. Fit a linear expression of the form $\text{Reading [V]} = \text{Gain [V/A]} \times \text{Current [A]} + \text{Offset [V]}$ to the obtained measurements. This [example Jupyter notebook](./resources/current_sensor_calibration.ipynb) is provided to illustrate the process. -1. Repeat the exercise for the remaining phases of the system. +### File Organization -An example of the results are shown in the plot below. The obtained gain and offset can be used directly in the control code to convert the sensor reading into the actual current measurement. +- Provide a preferred file organization so that the AMDC can access the generated C-code -![Example Results](resources/fit.svg) +### Create a Setup Model -```{tip} -Be sure to conduct the calibration process over the full range of current data (both positive and negative current) to account for any variation in the current sensor reading due to directionality of current. -``` -## Use of Calibration Data +- Save a new .m file as setup.m. +- Open a blank model of Simulink. +- Add a Discrete-time integrator +- Let us make a continuous time transfer function as a Plant (= 1). +- Add rate transition block before the integrator. +- In the rate transition, put T_{\mathrm{s}} as a sampling time. -The below codeblock can be utilized by the user to convert between raw measurements from the sensor and the actual currents. +- Make a (discrete time) integrator +- Provide a process of how to create a reference model (see [this](https://github.com/Severson-Group/AMDC-Examples/blob/develop/docs/autogen/Autogen.md#creating-a-referenced-model)) -```C -#define INV_GAIN (1.0/0.621) // Inverse of gain obtained from curve fit (1/0.621) -double offset = 4.739; // [V], offset from curve fit. This is a variable so that the drive can remeasure and adjust the offset at startup +### Model Setting -double current_measurement; // Actual current measurement, to be used in control algorithm +- Press Model Settings and go to Solver. In the Solver Selection, press Fixed-step. Set Fixed-step size as Tsim. -current_measurement = (sensor_reading - offset)*INV_GAIN; // sensor_reading is the raw measurement and needs to be obtained by the user -``` +

+ Integrator model +

-```{tip} -In AMDC firmware versions 1.4.1 and above, the amds driver has a built in function `amds_convert_voltage()` to streamline this process. Default offset and gain values for each different sensor card are also included. -``` +- In the Model Settings, go to Code Generation and click Browse for the System target file. Select ert.tlc Embedded coder. -## Recalculate Offset At Startup -The offset value of the current sensors can drift over time. It is recommended that drive developers include code in their control logic to automatically re-zero the current sensor at startup, as follows: +

+ Integrator model +

+ Integrator model +

+ Integrator model +

+ Integrator model +

Date: Sun, 21 Dec 2025 01:17:22 -0600 Subject: [PATCH 10/31] Revise Simulink model setup and C-code generation steps Updated the steps for creating and configuring a Simulink model, including detailed instructions for setting up a reference model and generating C-code. --- .../control-with-amdc/autogen/index.md | 86 ++++++++++--------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 27e586ad..f12b48ae 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -20,58 +20,62 @@ - Provide a preferred file organization so that the AMDC can access the generated C-code -### Create a Setup Model +### 1. Create a Setup Model -- Save a new .m file as setup.m. -- Open a blank model of Simulink. -- Add a Discrete-time integrator -- Let us make a continuous time transfer function as a Plant (= 1). -- Add rate transition block before the integrator. -- In the rate transition, put T_{\mathrm{s}} as a sampling time. - -- Make a (discrete time) integrator -- Provide a process of how to create a reference model (see [this](https://github.com/Severson-Group/AMDC-Examples/blob/develop/docs/autogen/Autogen.md#creating-a-referenced-model)) - -### Model Setting - -- Press Model Settings and go to Solver. In the Solver Selection, press Fixed-step. Set Fixed-step size as Tsim. +1. Save a new .m file as setup.m and define Ts = 1/(10e3), Tsim = Ts/10. +2. Open a blank model of Simulink. +3. Add a Step function with the default setting. +4. Add a Discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) with the default setting. +5. Add a rate transition block before the integrator. In the rate transition, put $T_{\mathrm{s}}$ as a sampling time. +6. Add a rate transition block after the integrator. In the rate transition, set the sampling time to -1. +7. Add a continuous-time transfer function as a Plant (= 1). +8. Add a Sum function and connect each block as shown below.

- Integrator model +

-- In the Model Settings, go to Code Generation and click Browse for the System target file. Select ert.tlc Embedded coder. +### 2. Model Setting -

- Integrator model -

- Integrator model -

- Integrator model -

- Integrator model -

+

-- Provide a process of how to generate C-code using Autogen feature, i.e., run `slbuild(modelName.slx)` command. +2. Right-click on the subsystem. Select Block parameters (Subsystem), check 'Treat as atomic unit', and click OK. +3. Right-click on the subsystem and select Subsystem & Model Reference. Select Convert and click Reference Model. +4. In the Input Parameters section, define the New model name as integrator. +5. Click Apply and Convert +6. Rename the reference model to be integrator. + +### 4. Reference Model Setting + +1. Double-click the integrator subsystem and click Model Settings. Click Model Settings in the Reference Model section. +2. Click Solver and in the Solver details, put Ts. +3. Save the Simulink file. + +### 5. Generate C-code + +1. Open the setup.m. +2. Copy and paste the following code. +```m +%% 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\'); +command = 'for /r %i in (*.c, *.h) do copy /y %i ..\autogen'; +[status, cmdout] = system(command); +cd(oldFolder); +``` ### Integration with AMDC From 29777723a35de3132a6bba4a4ab66dd985384701 Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Sun, 21 Dec 2025 01:17:36 -0600 Subject: [PATCH 11/31] Update image width in autogen index markdown --- source/getting-started/control-with-amdc/autogen/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index f12b48ae..bbc56f97 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -32,7 +32,7 @@ 8. Add a Sum function and connect each block as shown below.

- +

### 2. Model Setting From 0c425e7991a732dc9448a9f6eb27611365618f33 Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Sun, 21 Dec 2025 01:23:09 -0600 Subject: [PATCH 12/31] Update image width for integrator model in index.md --- source/getting-started/control-with-amdc/autogen/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index bbc56f97..6173a6bc 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -7,7 +7,7 @@ - A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation.

- Integrator model + Integrator model

## Procedure From 620303f690124604d27248a1e02d729a105522ac Mon Sep 17 00:00:00 2001 From: Daehoon Sung Date: Sun, 21 Dec 2025 01:23:25 -0600 Subject: [PATCH 13/31] Update index.md --- source/getting-started/control-with-amdc/autogen/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 6173a6bc..5bb240be 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -7,7 +7,7 @@ - A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation.

- Integrator model + Integrator model

## Procedure From 23000c99530569c1050e161cabaf642e8724a8c8 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 14:41:50 -0600 Subject: [PATCH 14/31] Rename files --- .../autogen/simulink/setup.m | 10 ++++++---- .../autogen/simulink/setupModel.slx | Bin 73127 -> 82752 bytes .../autogen/simulink/setup_model.slx | Bin 82752 -> 0 bytes 3 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 source/getting-started/control-with-amdc/autogen/simulink/setup_model.slx diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setup.m b/source/getting-started/control-with-amdc/autogen/simulink/setup.m index 2c935adc..7bc763a7 100644 --- a/source/getting-started/control-with-amdc/autogen/simulink/setup.m +++ b/source/getting-started/control-with-amdc/autogen/simulink/setup.m @@ -1,12 +1,14 @@ clear; clc; -Ts = 1/(10e3); % sec -Tsim = Ts/10; % sec +fs = 10e3; % sampling frequency (Hz) +Ts = 1/fs; % sampling time (sec) +Tsim = Ts/10; % simulation time (s) %% Autogen code for the controller -model='integrator'; % Name of the controller to be built -slbuild(model); % Generates the autogen code +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); diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setupModel.slx b/source/getting-started/control-with-amdc/autogen/simulink/setupModel.slx index d2ddd5ae29028c42cb7f95f94246e56d4f873741..67e8f6cad7c1713925a1d163343a4428345120c1 100644 GIT binary patch delta 22022 zcmeIa2{@E(7dURxs!&PF9!k;Jw~-}VC0WW+5*lMLmKn`LC{N24CYbq}p5!^eS(E6$ejFbIfw{eA(H3*nl# zwiL&u#APsx>ps_XF)l9d`An|=-b>_vi+&#RKi&PjwaEXH`M`VRe<*uQ^vM5C^*EY` z{LeIhLh+IRvf-ud=I2_QKQegs7IXdG^$VPlaQ@>1v-dqTDcx`Pm&6GRyT?I`xE2Z? ztHtz!(YjXt)hs z4&vA8YOh`t{P_d%6)vx^u&~KDsM#;)tYJX-ie*2~2?mTDzIu_e$_nSk)o7tB>rl|y=^5od!Jbhn2 zpf>r#l3CN-uRPu(7My!cG)&c6=|yF#W>d%OlGFP()6A9mJvUSo6&2aq+h4o?YGjzZ zg^PnfHot$k#5n6_Rel~-F5%Or)A^}e$F-~bJ`nP&HP#+Wf3f6K+=r{-BAOOOY{hWx z1im=xbg`R)dj6dQRZ*Tfxfum&5#>ww@*G}M?ONlmaB#K!n|Gxh#|ASSg5?v+uf2c& z{%T34&zkmi6!Yg5RYw=IxI)ph=^{!-pNG1U4=cCY*_jIpZVAY;v9nW;IAdp?U=e+8 z3Yi(juxk%Lg^M&e?qHa6W+gZ-T~ zw;3(Zt`6Xx?rsy&@b<{)sSRj}HV>vMwJ%+|R9KU`BRzDE)>fsEu$R~5-{YjNU4_1%xPDde>FQvyzBL0-~DTgO+M`EududkyOt1>$WRVix9+fxc(~r!XOfsU zb3;c}YL$tQ>#tN~D6QSNQAP@*c<*{RzFf9_0wW#>m zTy&e&VHdhY*|5sdKiX+;Uu7wy`_9|2t0dl7>xSGQ|D<4_eJ5vYyU6cR(A8;wKzRM3 zs5&L2;l-jetQFN%|0Wjuy5}b9z_~}m&kuC@Mvb27SN0w4tE$R*HiBB}ZT9p`JbLWd zZ7Ncyt=scZAX15VU}&H_RX*j8VU<%*vR%rKYbAQan;7q&K0m$6`gBCZWxPYi)f+dg z$`dTBo}85K`;gDyal6W?d^vl^1rgfa&EdNJXV-;`CsXUP+d}k5;`Iib1XyilCYiPL zV`mf`6YFyPz53t3id3VV+G1@j9pk{>S>YVmhAg*L>uV6znzexW(BhU!S7pnce4$;l z60)gYM|YOiQU88RVC1HywWkfe=zHK1(tU67j;ffQ$LbVwd&}1823K6&++J}FRmdBm zixKF?fB*e=;gct&?UmPAO-~k>M{C>8;uo)Y94c~~QoaJe?Z(>9n#}Oe7vF@f>9V3y zQyzy)AgPzl*zGm6yvlf^kfxs9O@28MCr`!?)CXC9YAFHLJOe+*?aDQ7`kpe0cpd)Tt)|uIm z!gdNY724suKd`rT!Ohs+ume6(t+=kboR0hZxjoCTm_KAVtjTLgwbUO~yJdzr1_Wdk z78Si!SzMHMIyyS}Q;EK_Q|eYH#r2hIwqiozepfo)f?BE##fPZ1XLlqXnD4{)GUGbm z;NCOqkEUBX+vVx*9(T@)2#a|C*yGD;pHL6^4Q@r~!v z8`^ML*5V0zTITX4n@4vuSRKg^oBl?T6c!r z2JC(@GWdxFPQK%X1I?DL;CPGPTv+E*qr(GL-N6Gn$Zmck5OLZ2SLrNR7~&TQ_)*Y?BLWA&QPJ49kMax_6)u!JMP9yK z+tx7=X(pJlmX(z)nmrw9(m(&!T;|Brr<;n;YbxI2xs(<5 z$w~r{Q|<@1Mv%#g-K3jf_TWSDDor0xEsTiKiZ8TIcy?S>r+rTEGI6iEY*u-q?e#|8 zd1`BwT7lcU9M}yuIewjGVPb1~pGb#43|d)y;m)0HsI29S5@d{VIU%8_(=YSoN&Y$7 zF39x^R%?Rh(R4X^qm%O*Gy@(T6-@JS@TtkDln&RqaLqcQogevpuzt@cbMv!G213qz zZu-4{84oJs_2#cb#Tq;0=g;;zo={l$TuUUeodwmL?yg`Tunb?>KQ z&A`6Ot*km$)!!X`g>QRqy>#JuxS@}fwcb92dI;|nG}z2uZVKLn?NbBZhRwsn12MWQ zt3{mES#7J?u!pfJM08%Z;8?->&s3i%$?27+*=#RxRqk16-|omy@tV~RjH zv$3*@3l-7S7(OAke_zs#y$xPbGAka`v)|-wI;U}a9jq4k775jC8W`@Y^KV#s`?~l- z=Uhf>&+I@m#Vc#)RSL24oL{u{naNs2Sq=Ah=Erz?6@-bUtv0*3KKzVNO{6xdOZXOe4FwCAycy2y1wsO-oNVTF;_uN5At?wQ8Vx zH8(HlD7`p(exR#vO=CakndjTbp@k(SY?)ATU2UdrR8>bM_*fC$CSicX(=8>F1E??5 z-iSOj8P=qhkb^n+v@$Hnwv{JzjC?BDx^d&tyH2!YKD@7_JZpUL@0WC%6QaC~>YX3xFBFk) z*Y2$j>*G^1G^)>hKBi^z>Befafja+KNFNt<$3L8xldPT&Lf-1U*EU>l=&Crfw|6sS z85bT$4T$;I#ygL;Z{2>|GXe{GfY9sZ4dO;iOLj@i+Z&-Crx}Cc?s4%SKYnb~{o|~3 zYw?o|AIy<&PjmhA&rbbyL!2hCQf&PYE zv$eTQd0+bQ@(RqJuEuz`2}@dd!vd@zK&a8`b#zC2%e4c0uR=~^`@DjIyp3Ae?N|ix z8$_SRYyOoG8=MFc$m8A9bA`plp?7EyL5I3>x_b{I5+iY@sk(mew-raKn*|MYMU=Ey z1B*AWFFLP8i&@7ndi5lGN7?FB{}gYXTP}}yI_q;C_;o()yA)ZF&i^>|(k0{Jf$pjq zLOZNFyg=^hE=R;wOmZrqTtwjd>5usf*e+tO<_7q4IK@tc_ z9Scd(PV-sQIGXEKrO*eSGfeY!NK>y&#(~iNsD#=vP$w9Y@8c9^hl98czRV}2Wt7O{kDep%hJ{16khP- zR|t%ESAjc${Z)B3gMa@e9DdWsA*lcT^L&2&9UZk@;HQ~b$j^DL1h4 z?13Ei%!Fiz%ywD*!9O!-4JqOJW83sc-te>a49dR^7okeBx&#ql~Y=kNh)1=agh#{25a zn~}MTJ?;mzP@df&ng@oCjSkD}>pMfr?U)>HpBu=s4mo=Q+rInarzZ!_9U7{Cd2M5- zZ;VXkkyxLa?RR(I#FA)QgWl+9!+0*1k7Y4hk2O2rVzzBz zb-Xa&Qkhp?o5kpZsOSMZ7FKaZj$qjtmRlz!Z5kXL+@3|h+}~AqJuOXT#QmJ}70M-do}x}q0l zY)bP+J{FZe*s7wcDnPw>1K4J~M{M5kT*bR_MG85apvpLH!}@@rCHmt#4jnp_n3PoU z#~gvvk&)ZGJKV|SHt=L%*ru)irHKcfoSf8cZLZ$9qt%##4;t{SIJG=`h33}1sks@O z6^GxQr^yirS%me%X*oBn!f7w#F5OaF?(Vul+_I_3FE+~?=aAw3=jZJA50!le5k`~w zn)F#FeOc87;z65`)Vm*#LL9v9@mwm|K7C!fTXEUD;`6u3MT^1Gats=RAiuz9OU|qp z?i*`tY%KMf!GFQV-hOE|UQ=@`lzOF@byr^B>hGX2H;?-9mwdP!yaz(PFHa(!X^6yx};5gK9hP?>oD<0TQmn$7LtCjlXGy zFxGfX@vvTjV@f*G5Tni72xUVY1QD;jn+#{@>gqbeR;(>7!r+yFf}2ySW}{aKk{^GQ zRNx7f(e@iV_d}OL?pk}R8-zLQEn7|nLZo@kqG305)0 zoL|NtbmJA1vo!tlqsYzZ`(CNJi?yfKf*w~wUE?N3KU$OQ>pvJsw7DHzpO$o_N&%0z1zNTJyOMf)nYthDa}PC)k2>c<2^If&ypx8Y zkdf=}&e!)iSY@r1+|=}M@b6^*mXXiM+i>Z7&z?Pd0r>;7K+IpQof&IlViG^l z36(;7lo^c&Itb6A*T}C~;{Zi6G-y0uRMGe* z?{9mN?9TwJ65qe~CcC?97WE5Z1@*%}1sp6(*8q_cBd=$*gKA~_ch|2*kV>@#s4OTT zfCbCCA(5832AduF6g!@@Kzg0W=MQh>@c2sLr^s#Gla^Q{1sLP`2d zy_8qrGoKqg>|k1U$T8dFMW|+bznNl0`X%G*`Xe_sD+Uy+S8X^2Nt-yzpUkHhyUuZU zd^NK(F{yUPD!lnd#5|cWxTkn5_acGbbmWYpb4pW_Yv@u<`|K{Ejn6z&Q$Lj?ZMiDW zj4eq3E|{IFrTVuH#pnhZhEt9JyQ6gi(w;r)d@u}wQsK_)Y0WJyULRgRICTm0h)qvU zLb3!p3?aPg!NFOOa9y^D)`pBW(K^9G-6=i0e=D*h^>~usMl-YWP9ul@@qB18DYk8T zGTs(DX1Z$CD&X$!i%tm_E*Of3uZPYD|7dU|TGe3-4xyECF>AckhYzd{Wv*z#>U>CP zAqKr#JUljI#teMg=BWHPM?CBqd%{w8WTn*?$k-_hM3uL3OnJe_IE=qTNN*cf2VP1f z9oIYzE;Yw5d4*-n>dYE^W=*v3bk+%s2c$?(nMJodT6a zRs5AVb8TYv_TKV-rDAH^eK~G?tb3f#F%R~|f^0;yeRz0}USI2T>Gr*q;h85;1ic8Z zvjfZnOnX5MVWcM*e`s#j1O zYSNN~uWvFpE_<%C< ziGDZLC@lFfg6)pnPGl%f9RsS4FYzSlgXgZgSj`PTnc98pm8CO<@a zar1d$zlVGVv=!7$2kx2kN?V^_RCjy2B-trfdr==0{}*1gi0KFKsB%VfAw#Xm@u%JP zs^*D_U+w}KkN?M z-*;u z(5&8hH)K8|lqb+AJl3a>sELRawJ{4@K7qDk`6$*($ndGTGBUC!7xZZeLVLwEYgw?5 zwu~C8H8eO*$Hb&SsdUXT#}Cv~jn<{36K0XnM7K46zKHEN?qq@b)BR z?!cnnM?%gXWtU8cT97gK=BB16oqk0vpH=~rK^MT$S<~rh_8rgixtGi%DYYZi%qG9B zkJ2Mw&yj|$;wpzX6{*hp;8m*vq@ti?qd*9UjbI7Ji)4occvE>K zzLQz#m*pBV-m@UXc-cu8g$2FF3&&!D8vm4q$$6Yz9Pf{rn;ASBXqwn__rv&HSo>}I zlFc`t=pr-0qpxfQR}0*%fNVPH<41b#XnzfOk(63$CK!J6r@^Maz~;Wd;%!fz9Qz2p z?Tj{yghb>n?@|?+MsE4tx+7`J%#J1MD^~BVe0ApXS|3L18%EolKjLJ=UJoZa=LK(W z$P5h#^(c{Ux;j_n(W4{zZ%%*@-@ZNa-Z0X&X7mj|azZBAF~?4UZI+dl70-I77h6($ zw(9m1U9FIqwfmElL&Wd7E;Are+o#9vYL7N*fL;k^V{n`cN$T0?;I59;ycbW;sY2Vr zv%1K8RaH0i952`Pqsda`}P-p&5nm#1rACWf+FA6!)psYe<&jb`oJ zc1^Pt>#IW#mI;kp!9|O%#>Gjl;HH#c3Dst`FRGqZv&eZ*&mp_y?Si{%(#So#{KQ- z5F&m&+o$7W_g+hR_u{f^02wBGaHpP^OA3A+{QSR7KhxV?0pJxp9RRI+;h)PGo-%kx$07b_1=d{F3-9szL;t0nJ8+JaB7dEubAg8tn;lz3vt?{_4nm@e0RvlTySyEk{ZE?)Lk&9UBg+l`}0`e;!cc~epnt6kv&=+~D zdt4j(rtts8u=D$0gvLo{{MGU-|KI}gpuF)-RtMkkSybjx6FqX`ZO5}y3Z|1{c5cpt zibvhQYe(@p)r55w2Sq$*Ov`|>LV6Ho-Q6+t`TD`K=c(#Sik6VSz^TaThHlHVar($$ z6Iz|cNC@m}zYK2Tagf&9>jtF@*1UP1(fQ<61Doe;O6^Z_g&$MEl&y7 zt@e4IBD?MBax4r74tHj%yF8o?c-J4C$;(sc@7BS}%Vu?4QPitXcIreU>XgkIw0N2o z(LfVw3ArwEuMBF&E5V~fk1*7Rr3)P1^rVcjBz@g-1ATc8=VV;F z_Lt_fxz006OII0G#hYQrF@~FCb%XqjE3Rj_rSkOM9?kx{!>{dwti-k4@v}$o=_DR~ zpK@v;Nq)fO*y2Mj&s@CYdf@COA>~AkU%A5h#389qSDaRCdwTG%i({pT5kI9g&LDpD z;%Gz!WKQB+D`)OXm=-)(ByaOB`E-NCh9jy`Ge}@asRE3+KVco&C3&x<{EHH^=LL)D znX1!{X+#%q6IN00y*X#4PCM2=c>UlY+5U{2oID&2FRE5wnOpEEt#jY0)gkxfwS={g zx!gT42B*6V7;#JIGm(dOyJapvSs7d0cO~rNvMP~}FQ*HN_g%Uq;~3B!QAn+_*bny$ zYz3Ji9Z&bKul9fPXUEK44@Ef&SXFr8Wn?WfJ{tJ(Z&|Ner|sJl=LoF03f<$vXV2`Q zCWenx*k2H66U)lBK=pMfCG!&WZPr17t35vQsV}#CFOvFr6wXRcT`KMQn=qngrFnqw z7X85olTXl)xcz!Vq#LvVSoPgKfz9+Rt;i)-{4j1AZyxHxKY}|b8|G=9va&5`R7zZ_$or< zxRGQVC3;GENO|Z$a8ogUPnb^is+~AvDY$vD%haLml~-beXLL+^Kb&%}uluk`o3XL- zU0H4FtT^Jf!!x3|UnJQJ^z}nS84_jnnt?%Z#J!*2hHKVz;5@Y6mF{P(ZFv@L3+DiR z9aSB0P{1x~F1tl3?;RWN?to;cA_(cuO*p2Iy#Y=mZ$Yl34hMZ?SJ&2KiuXzZJQZum z!AUwCEZnRQXc6;ixaVknWz%!4Q4EglI^;Ilkf!#PnJKoFTk2OrP0&}Y+2GMxeH+VU zgZtBC+n}cr-(mrWF4)=cKH)fgR-)#rpu`<~~vkv;K z@zPn2jAC_YB_27Ji8s%O!E#gittoIJ13NsHG}VSnF3@_BF@=2M z6ess;Zl*x@5o5lkgi}U)Us_t4VT+2s@9TX~g9!BO;3^J>eJMfn1`4D$?4m$vyb-Gi zpNaK3F&0B&rOs@%Lh7Jm!j2fq+m7$CM5_XZGJD!Vc`$^zJ$ISxq>z|b2_|0!_=qxU-hqEWHYW=6zH~-)L%m3{K z$p3f$^1plm@`o$V|LyyiKcMGA{!_!9xIQ|Cc_T=&d+?IM0q(ijMRQXV3*!{Sod>?Z zdM?E?f8iq-$9^OMia|jaNVzUjR?$*kEvd9xQbk<@ek-dIlpWDHsa-RaRdf`sP~3{e zXyEeY>Gd)u+^CoAf|cepSF-mOvKyIBrjp1~k`_cCvaS?`$|SqfiA)+@O48cYSXW9J zEnTq$-6y?bfeN;^2H+rQsjrq)RUx1fvLY(VO0c>fk0g9_tR@%XERC&aOd)#H+@Gxal|{4J#rY0GMRD0o|SDL#8q@c!rduO@J?uVa=pdsP0md#uON0P-s*jL{3Rc zku#U@(_A~EH|w8I*5g6z48;%&8r_HJ{f+8P6b4fg`!#{uj>4e0c#}=3zBD?MAvLkJ zDVxJyD@p0msNYsl#Ag4%10x!6lFGEAll>@Ue-kPZ)^x?Dq1>hm(f0@V5IZs*+nJP} zvH~Wd$@xD}17xt6R)BJXJ-?&Il&bt~iK*oLu$(1}`DHzX!|&fM2!Q|YiW6%avKR&o z5Fd;5kC^A?rh|Ol@;{*W>-IMhnIsRx03(`j04Rnj=!7fTn&M6+djDQRfaD+GK)y=+ z8&hnl6sE~;U;6LGPN8~`=@jNaTKMa_Uy1+avdDzNO{&v>wC*HRjLF_aj4QB@e}gT8 z9FzUZdmTkXZyL!9{jgFJ)muqPpTCM5hwhOxL!IQrrztC;3swoC^4M1uw0@-uP8nS$ zBY=j>&A?vVU#XH_Ah%@ZjLy>?$ve>|rIpBL%Y#ab4mAu4Uh1}Lb+s3Myih%e{^#?h zp|snz%2Gb2HKCmi4of84#WxL=G4kL-c|DW0FanwGvvE0lC7*QD!6rFH@=asK8rF@q z_ik=_m$YT!nbvtT2d_Uh3oy?r`*78kxBAS^JuNc4&3y|ylap6HKHP1fB%p1W-Dp91 zkc8B!Hi;U|n085Bi;px?e6%da z>rSA{N(+y<+s|J2-MaK|bk+JqO5}}mtf(T1x0%KHjDd={(>|$MaZf*urkFf6jPE4~ z$c4x~vc6_A#C6)sm)@1*)w+DlDj>S9j#jl&dglVu1848tUaq`+PIPgD^+?B_?toWv z(dQ1XzOd5%*6Wr1&*j|SKi=D$^2bQOj=}hgE2bujc3O^bdM|DLxrE4XRAv>(rgF=v*)JoS6_fbFRu|5 z+C*f4div5SG|b?gfh^wc0oeSMe;0g;Z(KqQ%*pu_NH`YQPND3EA$vceV^k&CyN6x*f}5nd>M1E;te^P){jwZ<*jzp2 z`vC@%f{}y$nKCdzALF}M9O?aztS`b-b5kO#x{y`zBsEPXyc$7M3r|oYs^MKoE@Txg zb;xKCCCwk`pDI0L(8}M-jw3I;vWkkDlClcnKNBEF|1oX430touQB@m*k8;Pi*s)ToOC4oRlB*YD`r9o82YblXkTu7>5 zV@i-IeNV#_2^d4RH0AMoxCsLyXlW=zma3xpF9`%u{GCaClL6rT_V7JQ?EQZ%5CtVA zB?OrJy+k<9Px2oM1PJmEG#V4UGkSxd#m80Uv)_=1 ziwpY^;bId+aAIihT5Z)P!$jHC0W5i>sRoK}BPVICZ`{;$M4ZjukL4EXWq%tTB;EoH85pmmHgu z2FAhX7XsG#Ce4ZX_U(C!;5cZ$xVV6R`4N5_}OfQ2AMQCf|K=`T-{>aN3pBoQ0J{sZrUJ$)StpfZWO zO}xqIJY8WZssBxPz~T1y*7l=#b$%gS&J17<^cBF7`Amj>S5#0(degteRKQPHf+JUs|DB|Kf({+UFOp0j(JA4czQF(Ln)H&jPjNVv z^e97Q2H)fCp8V1rE-vgxh>Oi9idza!c_r$(;mJ}X;JM^_GL;P01tL_mA^Z4xgJ)o% zTBce;pi~N27f6$U{UInp9=2LiQ#lXVNiTfgH4Om{mfQ#^Q@!nCc9cQ$-V~Y zNwcNtPb_+H=zJHU^ygOmd^1d`-V`coMO>0T>hypcoj<%Jy~@RB+9F6BDSi}J7SUUh zIN88qpvwZ6q|?Z+aOgg}C1|PTbd=;Si+xXzcYiny$3SCV*mmZqzF zi*V4L>XJe8F3w@=<8U$PeaA)YL>`<_dYf3;EVf$DbRcaPR zBOXg}{#HB|<-7+f(iavynSni|_dk`Nj-Gfl8>K|aqna-baVBWsODP^>YXb(f0d}#- zs8xv|8doBQ-hVXm3D6FX-ryMAqTS$Pvl zWUNmnC28bMWH5B4NFGGGl%55Rx&cytA{{&giRg{)Diub3*)x|}TK@oONTibuX+*lK z$!;QO3Yi1Byw+H83uFPNmg}&t*pG|c*XFbpf^(_ zQL9Ei6bYU&*O-p%uYF=KBX4tT(wuTA zIJ((W2E9?ji^A(!rf$#^a0O0gN@MR9z>^=So2i=(&Dx&=y+m}glQy(Bt0#6K~#h2rkKFrk<1Bz$7V$6sX$VdjR8_E9 zzZ_E5z=kF|o>LcuSz6eL&`;~JzApIdv56IbMuyG%&5|xOnm3t z{56%>n!g^wLcs6o*HFX8ex?zYn-~%R3KV}347%*35c=mMeksreQ&&?A^ao=#H`wMp zv4qkSQ7Ll@^*3Oq7T>^RIIG!mru||$Y==M+XT3?Zsw%&L12B;CRJ1>XO`x3s`-b*s zIM@Y-_RD&cXq7d7jTYoR746Sp6KE&EzM=gYZW8STpyU@OYyBFl7KT*v3yXgOn!w2c znh+Pp;Gdu-F;1*y$WcP74K#jDU4KA|Rm&W2F$uJe=*{>U$_;yqfpL!NHc@;iOjFk> zUSI>6=t|~9Z_vIKE6vG1)@0H|y!g@W2ku|tk}L-j696ad!}0R(H?G8io!Ijx8f357G;26}#?Eqo z$1U|qk{L`QoLgg!H|TkTf=wPL|AUz_oSB@%X$;ZtQ79PD=|nhdgc28`Asvf%KL8uy z8CVF0+6MqZbw$v;`kAu-bQ*){s;%wEzR8PQgzhVyizVvmv|6QUXiDM&EU8PsS8p^O zY6~gUqh}tf^fm_t42xz#-#uY(q^yWc4=HUa85dWq z*SJFw{L`1~1*?CC{<<_wnF{&+0Rd-WxSIe#$|_R7ScW4nZ7Fk0W0OtJhMO#n%%r}< zwfF0j~Zf9ZWGE33JxsA#I;RW+5M+3rSk!xLTH2zXVZ zrVB|~i9l3yarxTG(y_)4;h-sp{pFA}c`D5IoQd=0F@8N9e_oJ_>%3rQ(@dNdP87Rx zg7p`wZiCzPC@kBw%@syERruS^z;%Vsa_w#3(xKhBZ*~@rwizOz$n^N6qKiuz_ zI735YqL$#)**E!di`fl4IAQjQ1-PZ``E$Q~Gnk9hWRLOU=Cb$C#VwupO;5Cy*gd?s zCG4BF z{{a}ZR0te2nwpvls#8Cjj%68ZnjR>asr3vu%?_G6eT`t4Q$7uVA75G*!f ze-y^ai++DtG!?|w3OhPlKdp2-+Mv6XeO?4NpVQW4r;30tD0D<$trb~qWrmxE=lS-J zsea$)oVuJa8EbkPaZ4=2u`QWY}$@xRs(`{Uq>9 mbP607*W=}EyckYF^qW(IE5+YI#LBY$#c*;neRW|n*Z%>W#6r&i delta 13400 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 Date: Fri, 26 Dec 2025 14:47:36 -0600 Subject: [PATCH 15/31] Update m code in the article --- source/getting-started/control-with-amdc/autogen/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 5bb240be..1779b93d 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -69,9 +69,10 @@ 2. Copy and paste the following code. ```m %% Autogen code for the controller -model='integrator'; % Name of the controller to be built -slbuild(model); % Generates the autogen code +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); From 59594eea70c3fede4cbcbd310ba4fffc4d9dc3b5 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 14:54:48 -0600 Subject: [PATCH 16/31] Rename images and update document --- ...system.svg => autogen-model-subsystem.svg} | 0 .../control-with-amdc/autogen/index.md | 26 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) rename source/getting-started/control-with-amdc/autogen/images/{autogen-model-susbsystem.svg => autogen-model-subsystem.svg} (100%) diff --git a/source/getting-started/control-with-amdc/autogen/images/autogen-model-susbsystem.svg b/source/getting-started/control-with-amdc/autogen/images/autogen-model-subsystem.svg similarity index 100% rename from source/getting-started/control-with-amdc/autogen/images/autogen-model-susbsystem.svg rename to source/getting-started/control-with-amdc/autogen/images/autogen-model-subsystem.svg diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 1779b93d..99542052 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -6,9 +6,11 @@ - A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation. -

- Integrator model -

+```{image} images/integrator-model.svg +:alt: Integrator model +:width: 400px +:align: center +``` ## Procedure @@ -31,9 +33,11 @@ 7. Add a continuous-time transfer function as a Plant (= 1). 8. Add a Sum function and connect each block as shown below. -

- -

+```{image} images/autogen-model.svg +:alt: Autogen model +:width: 400px +:align: center +``` ### 2. Model Setting @@ -47,9 +51,11 @@ 1. Select the discrete-time integrator, and right-click. Select Create Subsystem from Selection. -

- -

+```{image} images/autogen-model-subsystem.svg +:alt: Autogen model subsystem +:width: 400px +:align: center +``` 2. Right-click on the subsystem. Select Block parameters (Subsystem), check 'Treat as atomic unit', and click OK. 3. Right-click on the subsystem and select Subsystem & Model Reference. Select Convert and click Reference Model. @@ -67,7 +73,7 @@ 1. Open the setup.m. 2. Copy and paste the following code. -```m +```MATLAB %% Autogen code for the controller model='integrator'; % name of the controller to be built slbuild(model); % generates the autogen code From 44262566e2a529659e96dd30c0dd5e6ce68e67f0 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 14:56:57 -0600 Subject: [PATCH 17/31] Update readme --- source/getting-started/control-with-amdc/autogen/index.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 99542052..c82655db 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -35,7 +35,7 @@ ```{image} images/autogen-model.svg :alt: Autogen model -:width: 400px +:width: 600px :align: center ``` @@ -53,7 +53,7 @@ ```{image} images/autogen-model-subsystem.svg :alt: Autogen model subsystem -:width: 400px +:width: 600px :align: center ``` @@ -88,7 +88,9 @@ cd(oldFolder); - Provide an example C-code to call the Autogen files within SDK, i.e., we need a following code: -https://github.com/Severson-Group/ARL-eturbo/blob/1ae4479c934d486e06f233d98f9384fda36a545d/Embedded/My-C-Code/usr/bm_4dof/task_bm_4dof.c#L649 +```c +controller_4DOF_step(); +``` ## Results From f5abcd81f856f518c8e9cc4ded4e81b76b08de1f Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 14:58:49 -0600 Subject: [PATCH 18/31] Update bullet points --- .../control-with-amdc/autogen/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index c82655db..a9d76be1 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -1,10 +1,10 @@ # 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. +This article explains how to implement the Simulink automatic code generation (autogen) by demonstrating an example using a simple integrator. ## Example of Model Configuration -- A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation. +A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation. ```{image} images/integrator-model.svg :alt: Integrator model @@ -16,13 +16,13 @@ ### Pre-Requisites -- User needs to install the dedicated MATLAB/Simulink toolbox/features - Embedded coder. +User needs to install the dedicated MATLAB/Simulink toolbox/features - Embedded coder. ### File Organization -- Provide a preferred file organization so that the AMDC can access the generated C-code +Provide a preferred file organization so that the AMDC can access the generated C-code -### 1. Create a Setup Model +### Create a Setup Model 1. Save a new .m file as setup.m and define Ts = 1/(10e3), Tsim = Ts/10. 2. Open a blank model of Simulink. @@ -39,7 +39,7 @@ :align: center ``` -### 2. Model Setting +### Model Setting 1. Press Model Settings and go to Solver. In the Solver Selection, press Fixed-step. Set Fixed-step size as Tsim. 2. In the Model Settings, go to Code Generation and click Browse for the System target file. Select ert.tlc Embedded coder. @@ -47,7 +47,7 @@ 4. In the Code Generation, go to Optimization and choose None for the Leverage target hardware instruction set extensions in the Target specific optimizations. 5. In the Code Generation, go to Templates and uncheck Generate an example main program in the Custom templates section. Then, click Apply and OK. -### 3. Create a Reference Model +### Create a Reference Model 1. Select the discrete-time integrator, and right-click. Select Create Subsystem from Selection. @@ -63,13 +63,13 @@ 5. Click Apply and Convert 6. Rename the reference model to be integrator. -### 4. Reference Model Setting +### Reference Model Setting 1. Double-click the integrator subsystem and click Model Settings. Click Model Settings in the Reference Model section. 2. Click Solver and in the Solver details, put Ts. 3. Save the Simulink file. -### 5. Generate C-code +### Generate C-code 1. Open the setup.m. 2. Copy and paste the following code. From af99cffe24e6b95f49321d7ab524e57e1c7bf160 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:02:06 -0600 Subject: [PATCH 19/31] Update size of figure --- source/getting-started/control-with-amdc/autogen/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index a9d76be1..44f9a6d9 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -8,7 +8,7 @@ A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be use ```{image} images/integrator-model.svg :alt: Integrator model -:width: 400px +:width: 300px :align: center ``` From b5670f8993d245266acd37eba242809b5e22311e Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:06:44 -0600 Subject: [PATCH 20/31] Add overview of Autogen --- source/getting-started/control-with-amdc/autogen/index.md | 8 ++++++-- .../control-with-amdc/autogen/simulink/setup.m | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 44f9a6d9..de3f326c 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -1,6 +1,10 @@ # 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. +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. ## Example of Model Configuration @@ -76,7 +80,7 @@ Provide a preferred file organization so that the AMDC can access the generated ```MATLAB %% Autogen code for the controller model='integrator'; % name of the controller to be built -slbuild(model); % generates the autogen code +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'; diff --git a/source/getting-started/control-with-amdc/autogen/simulink/setup.m b/source/getting-started/control-with-amdc/autogen/simulink/setup.m index 7bc763a7..a98dd334 100644 --- a/source/getting-started/control-with-amdc/autogen/simulink/setup.m +++ b/source/getting-started/control-with-amdc/autogen/simulink/setup.m @@ -6,7 +6,7 @@ %% Autogen code for the controller model='integrator'; % name of the controller to be built -slbuild(model); % generates the autogen code +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'; From 6b48e2bf6b46498288bed3b00bee115f309f9855 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:19:36 -0600 Subject: [PATCH 21/31] Update README --- .../control-with-amdc/autogen/index.md | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index de3f326c..f8647119 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -4,11 +4,7 @@ This article explains how to implement the Simulink automatic code generation (A ## 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. - -## Example of Model Configuration - -A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be used for creating the Simulink automatic code generation. +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 @@ -20,11 +16,24 @@ A simple discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) will be use ### Pre-Requisites -User needs to install the dedicated MATLAB/Simulink toolbox/features - Embedded coder. +User needs to install at least the following dedicated MATLAB/Simulink toolboxes/features: + +- Simulink +- Embedded coder +- Simulink coders ### File Organization -Provide a preferred file organization so that the AMDC can access the generated C-code +This article assumes that the uses has completed this tutorial, 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 Setup Model From 16ed4ffa5b95934c5d3f8d7fb475ad9ce2f58d29 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:41:07 -0600 Subject: [PATCH 22/31] Update readme --- .../control-with-amdc/autogen/index.md | 77 ++++++++++++------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index f8647119..1602c5dd 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -35,16 +35,26 @@ my-AMDC-workspace/ <= master repo simulink/ <= Now create this folder ``` -### Create a Setup Model +### Create a Simulink Model -1. Save a new .m file as setup.m and define Ts = 1/(10e3), Tsim = Ts/10. -2. Open a blank model of Simulink. -3. Add a Step function with the default setting. -4. Add a Discrete-time integrator ($\frac{K T_{\mathrm{s}}}{z - 1}$) with the default setting. -5. Add a rate transition block before the integrator. In the rate transition, put $T_{\mathrm{s}}$ as a sampling time. -6. Add a rate transition block after the integrator. In the rate transition, set the sampling time to -1. -7. Add a continuous-time transfer function as a Plant (= 1). -8. Add a Sum function and connect each block as shown below. +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. +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 the rate transition, put `Ts` as a sampling time. +7. Add a rate transition block after the integrator. In the rate transition, set the sampling time to `-1`. +8. Add a continuous-time transfer 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 @@ -54,15 +64,28 @@ my-AMDC-workspace/ <= master repo ### Model Setting -1. Press Model Settings and go to Solver. In the Solver Selection, press Fixed-step. Set Fixed-step size as Tsim. -2. In the Model Settings, go to Code Generation and click Browse for the System target file. Select ert.tlc Embedded coder. -3. In the Model Settings, go to Model Settings and click Code Generation. In the Build process section, check Generate code only. -4. In the Code Generation, go to Optimization and choose None for the Leverage target hardware instruction set extensions in the Target specific optimizations. -5. In the Code Generation, go to Templates and uncheck Generate an example main program in the Custom templates section. Then, click Apply and OK. - -### Create a Reference Model - -1. Select the discrete-time integrator, and right-click. Select Create Subsystem from Selection. +1. In `Modeling` tab, press `Model Settings` in `TOP MODEL` section. + - Under the `Solver`tree, in the `Solver Selection`, press `Fixed-step` + - Set `Fixed-step-size` as `Tsim`. +2. Go to `Code Generation`. + - Click `Browse` for the `System target file`. + - Select `ert.tlc Embedded coder`. + - In the `Build process` section, check `Generate code only`. +3. Go to `Optimization` under `Code Generation`. + - Choose `None` for the `Leverage target hardware instruction set extensions` in the `Target specific optimizations`. +4. Go to `Templates` under `Code Generation`. + - 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 @@ -70,22 +93,18 @@ my-AMDC-workspace/ <= master repo :align: center ``` -2. Right-click on the subsystem. Select Block parameters (Subsystem), check 'Treat as atomic unit', and click OK. -3. Right-click on the subsystem and select Subsystem & Model Reference. Select Convert and click Reference Model. -4. In the Input Parameters section, define the New model name as integrator. -5. Click Apply and Convert -6. Rename the reference model to be integrator. +### Referenced Model Setting -### Reference Model Setting - -1. Double-click the integrator subsystem and click Model Settings. Click Model Settings in the Reference Model section. -2. Click Solver and in the Solver details, put Ts. +1. Double-click the `integrator` referenced model and click `Model Settings` under `Modeling` tab. +2. Click `Model Settings` in the `REFERENCED MODEL` section. + - Set `Fixed-step-size` as `Ts`. 3. Save the Simulink file. ### Generate C-code -1. Open the setup.m. -2. Copy and paste the following 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 From 2fa6045ec64aa2fbdc099a0b63e170011efc9d32 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:44:07 -0600 Subject: [PATCH 23/31] Update README --- source/getting-started/control-with-amdc/autogen/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 1602c5dd..7c1e6231 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -24,7 +24,7 @@ User needs to install at least the following dedicated MATLAB/Simulink toolboxes ### File Organization -This article assumes that the uses has completed this tutorial, 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: +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 From 798529bb56ac24c42ad93b4dc0a2b29024344c2d Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:47:13 -0600 Subject: [PATCH 24/31] Update readme --- .../control-with-amdc/autogen/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 7c1e6231..d5b65c05 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -49,12 +49,12 @@ Tsim = Ts/10; % simulation time (s) ``` 3. Open a blank model of Simulink. -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 the rate transition, put `Ts` as a sampling time. -7. Add a rate transition block after the integrator. In the rate transition, set the sampling time to `-1`. -8. Add a continuous-time transfer block as a Plant (= 1). -9. Add a Sum function and connect each block as shown below. +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 From 213c3577c37791e2ef09284246bcd208abf81a19 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:49:31 -0600 Subject: [PATCH 25/31] Update indent --- .../control-with-amdc/autogen/index.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index d5b65c05..55b50c07 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -65,16 +65,16 @@ Tsim = Ts/10; % simulation time (s) ### Model Setting 1. In `Modeling` tab, press `Model Settings` in `TOP MODEL` section. - - Under the `Solver`tree, in the `Solver Selection`, press `Fixed-step` - - Set `Fixed-step-size` as `Tsim`. + 1. Under the `Solver`tree, in the `Solver Selection`, press `Fixed-step` + 2. Set `Fixed-step-size` as `Tsim`. 2. Go to `Code Generation`. - - Click `Browse` for the `System target file`. - - Select `ert.tlc Embedded coder`. - - In the `Build process` section, check `Generate code only`. + 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`. - - Choose `None` for the `Leverage target hardware instruction set extensions` in the `Target specific optimizations`. + 1. Choose `None` for the `Leverage target hardware instruction set extensions` in the `Target specific optimizations`. 4. Go to `Templates` under `Code Generation`. - - Uncheck `Generate an example main program` in the `Custom templates` section. + 1. Uncheck `Generate an example main program` in the `Custom templates` section. 5. Click `Apply` and `OK`. ### Create a Referenced Model @@ -97,7 +97,7 @@ Tsim = Ts/10; % simulation time (s) 1. Double-click the `integrator` referenced model and click `Model Settings` under `Modeling` tab. 2. Click `Model Settings` in the `REFERENCED MODEL` section. - - Set `Fixed-step-size` as `Ts`. + 1. Set `Fixed-step-size` as `Ts`. 3. Save the Simulink file. ### Generate C-code From 4afe97644eeb485f082c9e1a01edd5ceb9556dda Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:50:27 -0600 Subject: [PATCH 26/31] Add period --- source/getting-started/control-with-amdc/autogen/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 55b50c07..5acb524e 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -65,10 +65,10 @@ Tsim = Ts/10; % simulation time (s) ### 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` + 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`. + 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`. @@ -126,4 +126,4 @@ controller_4DOF_step(); ## Results -- After running the AMDC, show the input and output value through logging feature +- After running the AMDC, show the input and output value through logging feature. From a2e57245bc9c27ac27c858c67eca9315bcf3c74f Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:53:09 -0600 Subject: [PATCH 27/31] Update readme --- source/getting-started/control-with-amdc/autogen/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 5acb524e..77ddb0a4 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -48,7 +48,7 @@ Ts = 1/fs; % sampling time (sec) Tsim = Ts/10; % simulation time (s) ``` -3. Open a blank model of Simulink. +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. @@ -100,6 +100,8 @@ Tsim = Ts/10; % simulation time (s) 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`. From cd8ac9eb89aea833e628bbca26fb4eb9930d4231 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 15:55:46 -0600 Subject: [PATCH 28/31] Update readme --- source/getting-started/control-with-amdc/autogen/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 77ddb0a4..82840547 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -118,6 +118,8 @@ command = 'for /r %i in (*.c, *.h) do copy /y %i ..\autogen'; cd(oldFolder); ``` +3. Run the `setup.m`, and Autogen code are created in `simulink/autogen` folder. + ### Integration with AMDC - Provide an example C-code to call the Autogen files within SDK, i.e., we need a following code: From 142ebd093416dafd27c24c7cfcdb66920dd0d8f5 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 16:07:35 -0600 Subject: [PATCH 29/31] Update REAMDE --- .../control-with-amdc/autogen/index.md | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index 82840547..ee4974fe 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -124,8 +124,43 @@ cd(oldFolder); - Provide an example C-code to call the Autogen files within SDK, i.e., we need a following code: +`task_controller.c`: + ```c -controller_4DOF_step(); +// ... + +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 From a6f53a99f1fef8922d3115e33b5e2868fe64a24b Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 16:10:47 -0600 Subject: [PATCH 30/31] Update article --- source/getting-started/control-with-amdc/autogen/index.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/getting-started/control-with-amdc/autogen/index.md b/source/getting-started/control-with-amdc/autogen/index.md index ee4974fe..9b0a4bb0 100644 --- a/source/getting-started/control-with-amdc/autogen/index.md +++ b/source/getting-started/control-with-amdc/autogen/index.md @@ -122,7 +122,7 @@ cd(oldFolder); ### Integration with AMDC -- Provide an example C-code to call the Autogen files within SDK, i.e., we need a following code: +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`: @@ -143,7 +143,7 @@ int task_controller_init(void) { // ... - // Initialize autogen step + // Initialize Autogen step integrator_initialize(); // ... @@ -165,4 +165,6 @@ void task_controller_callback(void *arg) ## Results +THIS SECTION WILL BE UPDATED! + - After running the AMDC, show the input and output value through logging feature. From f1a9485827c0d4a1d7f52afd9782a94531be99b5 Mon Sep 17 00:00:00 2001 From: Takahiro Noguchi Date: Fri, 26 Dec 2025 16:14:05 -0600 Subject: [PATCH 31/31] Remove not used picture --- .../control-with-amdc/autogen/images/check-atomic-unit.svg | 1 - .../control-with-amdc/autogen/images/custom-template-uncheck.svg | 1 - .../autogen/images/discrete-time-integrator.svg | 1 - .../control-with-amdc/autogen/images/generate-code-only.svg | 1 - .../control-with-amdc/autogen/images/rate-transition-back.svg | 1 - .../control-with-amdc/autogen/images/rate-transition-front.svg | 1 - .../control-with-amdc/autogen/images/reference-model-setting.svg | 1 - .../control-with-amdc/autogen/images/reference-model-solver.svg | 1 - .../control-with-amdc/autogen/images/rename-integrator.svg | 1 - .../control-with-amdc/autogen/images/set-none-optimization.svg | 1 - .../control-with-amdc/autogen/images/step-block.svg | 1 - .../control-with-amdc/autogen/images/step-setting.svg | 1 - .../control-with-amdc/autogen/images/system-target-file.svg | 1 - 13 files changed, 13 deletions(-) delete mode 100644 source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/step-block.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/step-setting.svg delete mode 100644 source/getting-started/control-with-amdc/autogen/images/system-target-file.svg diff --git a/source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg b/source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg deleted file mode 100644 index 451f9dde..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/check-atomic-unit.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg b/source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg deleted file mode 100644 index e12a7585..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/custom-template-uncheck.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg b/source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg deleted file mode 100644 index eca6bc1c..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/discrete-time-integrator.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg b/source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg deleted file mode 100644 index 082c23a0..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/generate-code-only.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg b/source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg deleted file mode 100644 index 2722a318..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/rate-transition-back.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg b/source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg deleted file mode 100644 index a15ef559..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/rate-transition-front.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg b/source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg deleted file mode 100644 index ee4d044f..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/reference-model-setting.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg b/source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg deleted file mode 100644 index 058b3d2a..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/reference-model-solver.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg b/source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg deleted file mode 100644 index f4442392..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/rename-integrator.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg b/source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg deleted file mode 100644 index f5b987f8..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/set-none-optimization.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/step-block.svg b/source/getting-started/control-with-amdc/autogen/images/step-block.svg deleted file mode 100644 index 8ac03e02..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/step-block.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/step-setting.svg b/source/getting-started/control-with-amdc/autogen/images/step-setting.svg deleted file mode 100644 index b4c39bd5..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/step-setting.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/getting-started/control-with-amdc/autogen/images/system-target-file.svg b/source/getting-started/control-with-amdc/autogen/images/system-target-file.svg deleted file mode 100644 index 2070a2c9..00000000 --- a/source/getting-started/control-with-amdc/autogen/images/system-target-file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file