# Интеграция с Simulink

## Где модель

Основная модель:

```text
F:\set\workspace\setcorp\set506\AD\Inu_im_1wnd_3lvl\inu_im_1wnd_3lvl.slx
```

Версия для R2021b:

```text
F:\set\workspace\setcorp\set506\AD\Inu_im_1wnd_3lvl\inu_im_1wnd_3lvl_r2021b.slx
```

Инструкция запуска модели находится в:

```text
AD_Keil_Project\AD_docs\SIMULINK_MODEL_RUN_HELP.md
```

## Что найдено

| Артефакт | Статус |
|---|---|
| `Inu_im_1wnd_3lvl/inu_im_1wnd_3lvl.slx` | найден |
| `Inu_im_1wnd_3lvl/inu_im_1wnd_3lvl_r2021b.slx` | найден |
| `Inu_im_1wnd_3lvl/Inu/wrapper_inu.c` | найден |
| `Inu_im_1wnd_3lvl/Inu/controller.c` | найден |
| сгенерированный ERT-код `model.c/.h` | не найден |

Сейчас Keil-проект не является прямой автогенерацией из Simulink. В нём сделан C-интерфейс, через который можно связать модель, хост или ручной код с измерениями и командами.

## C-интерфейс

Файлы:

- `Core/Inc/simulink_interface.h`;
- `Core/Src/simulink_interface.c`;
- `Core/Inc/ad_parameter_identification.h`;
- `Core/Src/ad_parameter_identification.c`.

Основные функции:

```c
void SimulinkInterface_Init(void);
void SimulinkInterface_SetMeasurements(const AD_Measurements_t *meas);
void SimulinkInterface_SetCommand(const AD_Command_t *command);
void SimulinkInterface_StepFast(void);
void SimulinkInterface_StepSlow(void);
void SimulinkInterface_PackTelemetry(void);
```

## Команда от модели к MCU

Использовать `SimulinkInterface_OutputBus_t.command`:

```c
typedef struct
{
    uint8_t enable;
    uint8_t test_mode;
    uint8_t reset_faults;
    uint16_t pwm_polarity_flags;
    uint16_t pwm_timing_mode;
    uint16_t motor_control_type;
    uint16_t rotation_ramp_time_ms;
    float pwm_duty_limit;
    float rotation_frequency_Hz;
    float rotation_modulation;
    float current_limit_A;
    float voltage_limit_V;
    float undervoltage_limit_V;
    float speed_limit_rpm;
    float temperature_limit_C;
} AD_Command_t;
```

Минимальные условия для силового режима:

- `enable = 1`;
- `test_mode` равен одному из режимов `1`, `3`, `6..14`;
- `current_limit_A > 0`;
- `voltage_limit_V > 0`;
- сборка с `AD_PROJECT_POWER_TEST_ENABLE=1`;
- нет активной аварии.

## Режимы для модели

| Код | Режим |
|---:|---|
| 0 | `AD_PARAM_ID_MODE_IDLE` |
| 1 | `AD_PARAM_ID_MODE_STATOR_RESISTANCE` |
| 2 | `AD_PARAM_ID_MODE_NO_LOAD_MAGNETIZING` |
| 3 | `AD_PARAM_ID_MODE_LOCKED_ROTOR_LEAKAGE` |
| 4 | `AD_PARAM_ID_MODE_INERTIA_FRICTION` |
| 5 | `AD_PARAM_ID_MODE_DATA_LOGGING` |
| 6 | `AD_PARAM_ID_MODE_PWM_TEST_UH` |
| 7 | `AD_PARAM_ID_MODE_PWM_TEST_UL` |
| 8 | `AD_PARAM_ID_MODE_PWM_TEST_VH` |
| 9 | `AD_PARAM_ID_MODE_PWM_TEST_VL` |
| 10 | `AD_PARAM_ID_MODE_PWM_TEST_WH` |
| 11 | `AD_PARAM_ID_MODE_PWM_TEST_WL` |
| 12 | `AD_PARAM_ID_MODE_PWM_TEST_ALL` |
| 13 | `AD_PARAM_ID_MODE_AUTO_IDENTIFICATION` |
| 14 | `AD_PARAM_ID_MODE_ROTATION_3HZ` |

## Данные от MCU к модели

Использовать `SimulinkInterface_InputBus_t`:

- `measurements` - токи, DC-звено, скорость, температура, время;
- `motor_parameters` - оценённые параметры двигателя;
- `param_id_status` - флаги состояния;
- `param_id_faults` - флаги ошибок;
- `param_id_mode` - фактический режим.

Результаты измерений считаются действительными только по `motor_parameters.valid_mask`.

## Частоты вызова

В текущем Keil-проекте:

- `SimulinkInterface_StepFast()` вызывается на каждой итерации `AD_Project_Loop()`;
- `SimulinkInterface_StepSlow()` вызывается раз в 10 мс.

Для настоящего привода быстрый шаг лучше переносить в прерывание ADC/PWM, но текущая реализация уже позволяет проверить каналы, телеметрию и начальные измерительные импульсы.
