Main Content

시뮬레이션 및 코드 실행 중 파라미터 값 세트 간 전환하기

하나의 블록 파라미터에 대해 여러 개의 독립적인 값 세트를 저장하려면 구조체로 구성된 배열을 사용할 수 있습니다. 파라미터 세트 간에 전환하려면 배열의 요소에 대한 참조 역할을 하는 변수를 만들고 변수 값을 변경하십시오. 시뮬레이션 중에 변수 값을 변경할 수 있으며, 변수가 조정 가능형인 경우에는 생성된 코드 실행 중에 변수 값을 변경할 수 있습니다.

Variant 파라미터(Simulink.VariantVariable)를 사용하여 시뮬레이션과 코드 생성 중에 조건부로 모델의 블록 파라미터 값에 변화를 줄 수도 있습니다. 예제는 Create a Simple Variant Parameter Model 항목을 참조하십시오.

블록 파라미터에 변화하는 값을 사용하는 더 나은 방법은 Variant 파라미터(Simulink.VariantVariable)를 사용하는 것입니다. 이 워크플로를 사용하는 예제는 Create a Simple Variant Parameter Model 항목을 참조하십시오. Variant 파라미터 뱅크(Simulink.VariantBank)를 사용하여 Variant 파라미터를 생성된 코드에서 구조체형 배열로 그룹화합니다. Variant 파라미터 뱅크는 코드에서 포인터 전환을 사용하여 Variant 조건에 따라 활성 파라미터 값을 전환합니다.

예제 모델 살펴보기

예제 모델을 엽니다.

open_system('sldemo_fuelsys_dd_controller')

이 모델은 가솔린 엔진의 연료 공급 시스템을 나타냅니다. 모델의 출력값은 엔진으로 들어가는 연료 유량입니다.

switchable_compensation 중첩 서브시스템으로 이동합니다.

open_system(['sldemo_fuelsys_dd_controller/fuel_calc/',...
     'switchable_compensation'])

이 서브시스템은 연료 유량(fuel rate) 신호에서 잡음을 수정하고 필터링합니다. 서브시스템은 연료 공급 모드를 기반으로 다양한 필터 계수를 사용하며 엔진의 센서 고장에 따라 제어 로직을 변경합니다. 예를 들어, 정상 작동 중에는 제어 알고리즘이 low_mode 서브시스템을 활성화합니다. 센서 고장일 때는 rich_mode 서브시스템을 활성화합니다.

low_mode 서브시스템을 엽니다.

open_system(['sldemo_fuelsys_dd_controller/fuel_calc/',...
     'switchable_compensation/low_mode'])

Discrete Filter 블록이 연료 유량 신호를 필터링합니다. 블록 대화 상자에서 분자 파라미터는 필터의 분자 계수를 설정합니다.

형제 서브시스템 rich_mode에도 Discrete Filter 블록이 포함되어 있으나 계수가 다릅니다.

모델 다이어그램을 업데이트하여 신호 데이터형을 표시합니다. 블록의 입력 및 출력 신호는 단정밀도 부동소수점 데이터형 single을 사용합니다.

모델의 왼쪽 하단 모서리에서 모델 데이터 배지를 누른 다음 데이터 사전 링크를 클릭합니다. 이 모델의 데이터 사전 sldemo_fuelsys_dd_controller.sldd가 모델 탐색기에서 열립니다.

모델 탐색기의 모델 계층 구조 창에서 Design Data를 선택합니다.

내용 창에서 Simulink.NumericType 객체 중 하나(예: s16En15)의 속성을 확인합니다. 이 유형의 객체는 현재 단정밀도 부동소수점 데이터형 single형을 나타냅니다. 모델은 이들 객체를 사용하여 Discrete Filter 블록의 입력 신호, 출력 신호 등의 신호 데이터형을 설정합니다.

생성된 코드를 시뮬레이션하고 실행하는 동안 사용자가 제어하는 변수를 기반으로 각 서브시스템이 다른 분자 계수 간에 전환된다고 가정하겠습니다.

구조체로 구성된 배열에 파라미터 값 저장하기

구조체 값을 갖는 Simulink.Parameter 객체에 기존 분자 계수 세트를 저장합니다. 구조체의 각 필드에는 Discrete Filter 블록 중 하나에 대한 계수가 저장됩니다.

lowBlock = ['sldemo_fuelsys_dd_controller/fuel_calc/'...
    'switchable_compensation/low_mode/Discrete Filter'];
richBlock = ['sldemo_fuelsys_dd_controller/fuel_calc/'...
    'switchable_compensation/rich_mode/Discrete Filter'];
params.lowNumerator = eval(get_param(lowBlock,'Numerator'));
params.richNumerator = eval(get_param(richBlock,'Numerator'));
params = Simulink.Parameter(params);

params의 값을 임시 변수로 복사합니다. 이 임시 구조체에서 필드 값을 수정하고, 수정된 구조체를 params의 두 번째 요소로 할당합니다.

temp = params.Value;
temp.lowNumerator = params.Value.lowNumerator * 2;
temp.richNumerator = params.Value.richNumerator * 2;
params.Value(2) = temp;
clear temp

params 값이 두 구조체로 구성된 배열이 되었습니다. 각 구조체마다 필터 계수 세트가 하나씩 저장되어 있습니다.

파라미터 세트 간에 전환할 변수 만들기

Ctrl이라는 이름의 Simulink.Parameter 객체를 만듭니다.

Ctrl = Simulink.Parameter(2);
Ctrl.DataType = 'uint8';

low_mode 서브시스템의 Discrete Filter 블록 대화 상자에서 분자 파라미터를 표현식 params(Ctrl).lowNumerator로 설정합니다.

set_param(lowBlock,'Numerator','params(Ctrl).lowNumerator');

rich_mode 서브시스템의 Discrete Filter 블록에서 분자 파라미터의 값을 params(Ctrl).richNumerator로 설정합니다.

set_param(richBlock,'Numerator','params(Ctrl).richNumerator');

표현식은 변수 Ctrl을 사용하여 params의 구조체 중 하나를 선택합니다. 그런 다음 표현식은 구조체의 필드 중 하나를 역참조합니다. 필드 값은 분자 계수의 값을 설정합니다.

계수 세트 간에 전환하려면 구조체로 구성된 배열에서 Ctrl 값을 해당 인덱스로 변경하십시오.

Bus 객체를 구조체로 구성된 배열의 데이터형으로 사용하기

선택적으로, 구조체로 구성된 배열의 데이터형으로 사용할 Simulink.Bus 객체를 만듭니다. 다음을 수행할 수 있습니다.

  • 구조체의 형태를 제어합니다.

  • 각 필드에 대해 데이터형 및 물리 단위와 같은 특성을 제어합니다.

  • 생성된 코드에서 struct 유형의 이름을 제어합니다.

함수 Simulink.Bus.createObject를 사용하여 객체를 만들고 객체의 이름을 paramsType로 변경합니다.

Simulink.Bus.createObject(params.Value)
paramsType = slBus1;
clear slBus1

데이터 사전의 Simulink.NumericType 객체를 사용하여 구조체 필드의 데이터형을 제어할 수 있습니다. bus 객체에서 데이터형 객체의 이름을 사용하여 각 요소의 DataType 속성을 설정합니다.

paramsType.Elements(1).DataType = 's16En15';
paramsType.Elements(2).DataType = 's16En7';

bus 객체를 구조체로 구성된 배열의 데이터형으로 사용합니다.

params.DataType = 'Bus: paramsType';

스위칭 변수에 열거형 사용하기

선택적으로, 열거형을 스위칭 변수의 데이터형으로 사용할 수 있습니다. 각 파라미터 세트를 의미 있는 이름과 연결하고 스위칭 변수의 허용 값을 제한할 수 있습니다.

FilterCoeffs라는 이름의 열거형을 만듭니다. params의 각 구조체에 대한 열거형 멤버를 만듭니다. params에서의 각 열거형 멤버의 인덱스를 나타내는 기본 정수 값을 설정합니다.

Simulink.defineIntEnumType('FilterCoeffs',{'Weak','Aggressive'},[1 2])

열거형을 스위칭 변수의 데이터형으로 사용합니다. 변수 값을 인덱스 2에 해당하는 Aggressive로 설정합니다.

Ctrl.Value = FilterCoeffs.Aggressive;

데이터 사전에 새 객체 추가하기

만든 객체를 데이터 사전 sldemo_fuelsys_dd_controller.sldd에 추가합니다.

dictObj = Simulink.data.dictionary.open('sldemo_fuelsys_dd_controller.sldd');
sectObj = getSection(dictObj,'Design Data');
addEntry(sectObj,'Ctrl',Ctrl)
addEntry(sectObj,'params',params)
addEntry(sectObj,'paramsType',paramsType)

데이터 사전에 열거형을 저장할 수도 있습니다. 그러나 이 경우 변경 사항을 sldemo_fuelsys_dd_controller.sldd로 저장할 수 없으므로 열거형을 가져올 수 없습니다. 데이터 사전에 열거형을 저장하는 데 대한 자세한 내용은 Enumerations in Data Dictionary 항목을 참조하십시오.

시뮬레이션 중에 파라미터 세트 간 전환하기

제어기 모델 sldemo_fuelsys_dd_controller를 참조하는 예제 모델 sldemo_fuelsys_dd를 엽니다.

open_system('sldemo_fuelsys_dd')

시뮬레이션 중에 모델과 상호 작용할 수 있도록 시뮬레이션 중지 시간을 Inf로 설정합니다.

시뮬레이션 실행을 시작하고 Scope 블록 대화 상자를 엽니다. 스코프는 엔진이 정상 작동하는 동안 연료 유량(fuel 신호)이 상당한 진폭으로 진동하는 것을 보여줍니다.

모델 탐색기에서 데이터 사전 sldemo_fuelsys_dd_controller.sldd의 내용을 확인합니다. Ctrl 값을 FilterCoeffs.Weak로 설정합니다.

sldemo_fuelsys_dd 모델 다이어그램을 업데이트합니다. 스코프는 덜 공격적인 필터 계수로 인해 연료 유량 진동의 진폭이 감소함을 보여줍니다.

시뮬레이션을 중지합니다.

코드 생성하기 및 검사하기

Simulink Coder가 있는 경우 코드 실행 중에 파라미터 세트 간에 전환할 수 있는 코드를 생성할 수 있습니다.

모델 탐색기에서 데이터 사전 sldemo_fuelsys_dd_controller.sldd의 내용을 확인합니다. 내용 창에서 열 보기Storage Class로 설정합니다.

생성된 코드에서 구조체로 구성된 배열이 조정 가능한 전역 변수로 나타나도록 StorageClass 열을 사용하여 params에 스토리지 클래스 ExportedGlobal을 적용합니다. 코드 실행 중에 스위칭 변수의 값을 변경할 수 있도록 동일한 스토리지 클래스를 Ctrl에 적용합니다.

또는 다음 명령을 사용하여 객체를 구성합니다.

tempEntryObj = getEntry(sectObj,'params');
params = getValue(tempEntryObj);
params.StorageClass = 'ExportedGlobal';
setValue(tempEntryObj,params);

tempEntryObj = getEntry(sectObj,'Ctrl');
Ctrl = getValue(tempEntryObj);
Ctrl.StorageClass = 'ExportedGlobal';
setValue(tempEntryObj,Ctrl);

제어기 모델에서 코드를 생성합니다.

slbuild('sldemo_fuelsys_dd_controller')
### Starting build procedure for: sldemo_fuelsys_dd_controller
### Successful completion of code generation for: sldemo_fuelsys_dd_controller

Build Summary

Top model targets built:

Model                         Action           Rebuild Reason                                    
=================================================================================================
sldemo_fuelsys_dd_controller  Code generated.  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 53.671s

코드 생성 보고서에서 헤더 파일 sldemo_fuelsys_dd_controller_types.h를 확인합니다. 이 코드는 열거형 데이터형 FilterCoeffs를 정의합니다.

file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'sldemo_fuelsys_dd_controller_types.h');
coder.example.extractLines(file,'#ifndef DEFINED_TYPEDEF_FOR_FilterCoeffs_',...
    '/* Forward declaration for rtModel */',1,0)
#ifndef DEFINED_TYPEDEF_FOR_FilterCoeffs_
#define DEFINED_TYPEDEF_FOR_FilterCoeffs_

typedef enum {
  Weak = 1,                            /* Default value */
  Aggressive
} FilterCoeffs;

#endif

이 코드는 또한 Simulink.Bus 객체에 해당하는 구조체 유형 paramsType을 정의합니다. 필드는 모델의 단정밀도 부동소수점 데이터형을 사용합니다.

coder.example.extractLines(file,'#ifndef DEFINED_TYPEDEF_FOR_paramsType_',...
    '#ifndef DEFINED_TYPEDEF_FOR_FilterCoeffs_',1,0)
#ifndef DEFINED_TYPEDEF_FOR_paramsType_
#define DEFINED_TYPEDEF_FOR_paramsType_

typedef struct {
  real32_T lowNumerator[2];
  real32_T richNumerator[2];
} paramsType;

#endif

소스 파일 sldemo_fuelsys_dd_controller.c를 확인합니다. 이 코드는 열거형을 사용하여 스위칭 변수 Ctrl을 정의합니다.

file = fullfile('sldemo_fuelsys_dd_controller_ert_rtw',...
    'sldemo_fuelsys_dd_controller.c');
coder.example.extractLines(file,'FilterCoeffs Ctrl = Aggressive;',...
    '/* Block signals (default storage) */',1,0)
FilterCoeffs Ctrl = Aggressive;        /* Variable: Ctrl
                                        * Referenced by:
                                        *   '<S12>/Discrete Filter'
                                        *   '<S13>/Discrete Filter'
                                        */

이 코드는 또한 params 구조체로 구성된 배열도 정의합니다.

coder.example.extractLines(file,'/* Exported block parameters */',...
    '/* Variable: params',1,1)
/* Exported block parameters */
paramsType params[2] = { {
    { 8.7696F, -8.5104F },

    { 0.0F, 0.2592F }
  }, { { 17.5392F, -17.0208F },

    { 0.0F, 0.5184F }
  } } ;                                /* Variable: params

모델 step 함수의 코드 알고리즘은 스위칭 변수를 사용하여 구조체로 구성된 배열의 요소를 참조합니다.

구조체로 구성된 배열에 저장된 파라미터 세트 간에 전환하려면 코드 실행 중에 Ctrl 값을 변경하십시오.

데이터 사전에 대한 연결을 닫습니다. 이 예제에서는 저장되지 않은 변경 사항을 무시합니다. 변경 내용을 저장하려면 '-save' 옵션을 사용하십시오.

Simulink.data.dictionary.closeAll('sldemo_fuelsys_dd_controller.sldd','-discard')

관련 항목