모델 어드바이저 사용자 지정 구성을 만들고 배포하기
R2026b모델이 회사의 표준 및 모델링 지침을 충족하는지 검사하기 위해 모델 어드바이저를 사용자 지정할 수 있습니다. 이 예제에서는 모델 어드바이저에 사용자 지정 검사를 추가하고 필요하지 않은 기본 제공 검사를 제거하는 방법을 보여줍니다. 사용자 지정 검사 구성을 저장하고 이를 개발 그룹 내의 다른 사용자에게 배포할 수 있습니다. 사용자 지정 구성을 배포하면 개발 그룹에서 동일한 검사 세트를 사용하여 모델을 검토할 수 있습니다.
특정 언어 버전의 MATLAB®에서 사용자 지정 모델 어드바이저 구성을 만들고 불러오면 MATLAB을 다른 언어로 전환하더라도 표시 이름은 해당 언어로 유지됩니다. 이는 구성 파일이 원래 언어 설정을 유지하고 이러한 표시 이름을 번역하는 것이 지원되지 않기 때문입니다.
사용자 지정 검사 정의하기
이 예제에서는 다음 네 가지 유형의 사용자 지정 검사를 정의합니다.
수정 작업을 제공하는 편집 시 검사(edit-time check).
모델 어드바이저에서만 실행되며, 결과를 블록 및 서브시스템별로 그룹화하고 수정 작업을 제공하는 검사.
모델 어드바이저에서만 실행되고 모델 구성 파라미터 설정을 확인하는 검사.
블록 파라미터 설정에 대한 제약 조건을 지정하고 수정 작업을 제공하는 편집 시 검사(edit-time check).
예제 파일에는 sl_customization.m 파일이 포함되어 있습니다. 이 파일에는 사용자 지정 검사를 정의하는 함수에 대한 호출을 포함하는 sl_customization 함수가 들어 있습니다. sl_customization.m 파일을 열고 검사합니다.
function sl_customization(cm) % SL_CUSTOMIZATION - Model Advisor customization demonstration. % Copyright 2019 The MathWorks, Inc. % register custom checks cm.addModelAdvisorCheckFcn(@defineModelAdvisorChecks); % ----------------------------- % defines Model Advisor Checks % ----------------------------- function defineModelAdvisorChecks defineEditTimeCheck defineDetailStyleCheck; defineConfigurationParameterCheck; defineNewBlockConstraintCheck;
sl_customization 함수는 사용자 지정 검사를 등록하기 위한 addModelAdvisorCheckFcn 메서드를 포함하는 customization manager 객체를 받습니다. 이 메서드에 대한 입력값은 4개의 사용자 지정 검사에 해당하는 4개의 검사 정의 함수의 호출을 포함하는 함수 defineModelAdvisorChecks에 대한 핸들입니다.
수정 작업이 있는 편집 시 검사
defineEditTimeCheck.m 파일에는 defineEditTimeCheck 검사 정의 함수가 포함되어 있으며, 이 함수는 Inport 블록 및 Outport 블록이 출력 데이터형에 따라 특정 색을 갖는지 확인하는 검사를 정의합니다. 이 검사는 다른 편집된 블록도 검사해야 하지만, 동일한 수준 또는 전체 모델 계층 구조에서 영향을 받는 블록까지 검사할 필요는 없습니다. 이 검사는 올바른 색을 갖지 않는 블록의 색을 업데이트하는 수정 작업을 제공합니다. 이 검사의 이름은 [Check color of Inport and Outport blocks]입니다. 이 검사는 편집 시(edit-time)와 모델 어드바이저에서 모두 실행됩니다. defineEditTimeCheck.m 파일을 열고 검사합니다.
function defineEditTimeCheck % Check the background color of Inport and Outport blocks. rec = ModelAdvisor.Check("advisor.edittimecheck.PortColor"); rec.Title = 'Check color of Inport and Outport blocks'; rec.CallbackHandle = 'MyEditTimeChecks.PortColor'; mdladvRoot = ModelAdvisor.Root; mdladvRoot.publish(rec,'Demo');
편집 시 검사에는 ModelAdvisor.EdittimeCheck 기본 클래스에서 파생되는 클래스 정의 PortColor가 있습니다. 이 유형의 검사를 만드는 방법에 대한 자세한 내용은 Define Edit-Time Checks to Comply with Conditions That You Specify with the Model Advisor 항목을 참조하십시오. +MyEditTimeChecks라는 폴더를 만들고 PortColor.m을 이 폴더에 저장합니다.
copyfile PortColor.m* +MyEditTimeChecks
PortColor.m 파일을 열고 검사합니다.
classdef PortColor < ModelAdvisor.EdittimeCheck % Check that ports conform to software design standards for background color. % % Background Color Data Types % orange Boolean % green all floating-point % cyan all integers % Light Blue Enumerations and Bus Objects % white auto % methods function obj=PortColor(checkId) obj=obj@ModelAdvisor.EdittimeCheck(checkId); obj.traversalType = edittimecheck.TraversalTypes.BLKITER; end function violation = blockDiscovered(obj, blk) violation = []; if strcmp(get_param(blk,'BlockType'),'Inport') || strcmp(get_param(blk,'BlockType'),'Outport') dataType = get_param(blk,'OutDataTypeStr'); currentBgColor = get_param(blk,'BackgroundColor'); if strcmp(dataType,'boolean') if ~strcmp(currentBgColor, 'orange') % Create a violation object using the ModelAdvisor.ResultDetail class. violation = ModelAdvisor.ResultDetail; ModelAdvisor.ResultDetail.setData(violation,'SID',Simulink.ID.getSID(blk)); violation.CheckID = obj.checkId; violation.Description = 'Inport/Outport blocks with Boolean outputs should be orange.'; violation.title = 'Port Block Color'; violation.ViolationType = 'warn'; end elseif any(strcmp({'single','double'},dataType)) if ~strcmp(currentBgColor, 'green') violation = ModelAdvisor.ResultDetail; ModelAdvisor.ResultDetail.setData(violation,'SID',Simulink.ID.getSID(blk)); violation.CheckID = obj.checkId; violation.Description = 'Inport/Outport blocks with floating-point outputs should be green.'; violation.title = 'Port Block Color'; violation.ViolationType = 'warn'; end elseif any(strcmp({'uint8','uint16','uint32','int8','int16','int32'}, dataType)) if ~strcmp(currentBgColor, 'cyan') violation = ModelAdvisor.ResultDetail; ModelAdvisor.ResultDetail.setData(violation,'SID',Simulink.ID.getSID(blk)); violation.CheckID = obj.checkId; violation.Description = 'Inport/Outport blocks with integer outputs should be cyan.'; violation.title = 'Port Block Color'; violation.ViolationType = 'warn'; end elseif contains(dataType,'Bus:') if ~strcmp(currentBgColor, 'lightBlue') violation = ModelAdvisor.ResultDetail; ModelAdvisor.ResultDetail.setData(violation,'SID',Simulink.ID.getSID(blk)); violation.CheckID = obj.checkId; violation.Description = 'Inport/Outport blocks with bus outputs should be light blue.'; violation.title = 'Port Block Color'; violation.ViolationType = 'warn'; end elseif contains(dataType,'Enum:') if ~strcmp(currentBgColor, 'lightBlue') violation = ModelAdvisor.ResultDetail; ModelAdvisor.ResultDetail.setData(violation,'SID',Simulink.ID.getSID(blk)); violation.CheckID = obj.checkId; violation.Description = 'Inport/Outport blocks with enumeration outputs should be light blue.'; violation.title = 'Port Block Color'; violation.ViolationType = 'warn'; end elseif contains(dataType, 'auto') if ~strcmp(currentBgColor, 'white') violation = ModelAdvisor.ResultDetail; ModelAdvisor.ResultDetail.setData(violation,'SID',Simulink.ID.getSID(blk)); violation.CheckID = obj.checkId; violation.Description = 'Inport/Outport blocks with auto outputs should be white.'; violation.title = 'Port Block Color'; violation.ViolationType = 'warn'; end end end end function violation = finishedTraversal(obj) violation = []; end function success = fix(obj, violation) success = true; dataType = get_param(violation.Data,'OutDataTypeStr'); if strcmp(dataType,'boolean') set_param(violation.Data,'BackgroundColor','orange'); elseif any(strcmp({'single','double'},dataType)) set_param(violation.Data,'BackgroundColor','green'); elseif any(strcmp({'uint8','uint16','uint32','int8','int16','int32'}, dataType)) set_param(violation.Data,'BackgroundColor','cyan'); elseif contains(dataType,'Bus:') || contains(dataType,'Enum:') set_param(violation.Data,'BackgroundColor','lightBlue'); elseif contains(dataType,'auto') set_param(violation.Data,'BackgroundColor','white'); end end end end
수정 작업이 있는 모델 어드바이저 검사
defineDetailStyleCheck.m 파일에는 defineDetailStyleCheck 검사 정의 함수가 포함되어 있으며, 이 함수는 블록 아래에 이름이 표시되지 않는 블록을 나열하는 검사를 정의합니다. 이 검사는 이러한 이름을 블록 아래로 이동하는 수정 작업을 제공합니다. 이 검사의 이름은 블록 이름이 블록 아래에 표시되는지 검사입니다. 이 검사 작성 스타일은 모델 어드바이저에서만 실행되는 검사를 위한 것입니다. defineDetailStyleCheck.m 파일을 열고 검사합니다.
function defineDetailStyleCheck mdladvRoot = ModelAdvisor.Root; % Create ModelAdvisor.Check object and set properties. rec = ModelAdvisor.Check('com.mathworks.sample.detailStyle'); rec.Title = 'Check whether block names appear below blocks'; rec.TitleTips = 'Check position of block names'; rec.setCallbackFcn(@DetailStyleCallback,'None','DetailStyle'); % Create ModelAdvisor.Action object for setting fix operation. myAction = ModelAdvisor.Action; myAction.setCallbackFcn(@ActionCB); myAction.Name='Make block names appear below blocks'; myAction.Description='Click the button to place block names below blocks'; rec.setAction(myAction); mdladvRoot.publish(rec, 'Demo'); % publish check into Demo group. end % ----------------------------- % This callback function uses the DetailStyle CallbackStyle type. % ----------------------------- function DetailStyleCallback(system, CheckObj) mdladvObj = Simulink.ModelAdvisor.getModelAdvisor(system); % get object % Find all blocks whose name does not appear below blocks violationBlks = find_system(system, 'Type','block',... 'NamePlacement','alternate',... 'ShowName', 'on'); if isempty(violationBlks) ElementResults = ModelAdvisor.ResultDetail; ElementResults.Description = 'Identify blocks where the name is not displayed below the block.'; ElementResults.ViolationType = 'pass'; ElementResults.Status = 'All blocks have names displayed below the block.'; else for i=1:numel(violationBlks) ElementResults(1,i) = ModelAdvisor.ResultDetail; end for i=1:numel(ElementResults) ModelAdvisor.ResultDetail.setData(ElementResults(i), 'SID',violationBlks{i}); ElementResults(i).Description = 'Identify blocks where the name is not displayed below the block.'; ElementResults(i).Status = 'The following blocks have names that do not display below the blocks:'; ElementResults(i).RecAction = 'Change the location such that the block name is below the block.'; ElementResults(i).ViolationType = 'warn'|'info'|'fail'; end mdladvObj.setActionEnable(true); end CheckObj.setResultDetails(ElementResults); end % ----------------------------- % This action callback function changes the location of block names. % ----------------------------- function result = ActionCB(taskobj) mdladvObj = taskobj.MAObj; checkObj = taskobj.Check; resultDetailObjs = checkObj.ResultDetails; for i=1:numel(resultDetailObjs) % take some action for each of them block=Simulink.ID.getHandle(resultDetailObjs(i).Data); set_param(block,'NamePlacement','normal'); end result = ModelAdvisor.Text('Changed the location such that the block name is below the block.'); mdladvObj.setActionEnable(false); end
이 검사는 디폴트 서식 지정을 생성하는 setCallbackFcn 유형의 DetailStyle을 사용하므로, 모델 어드바이저에 나타나는 결과의 서식을 지정하기 위해 ModelAdvisor.FormatTemplate 또는 다른 모델 어드바이저 서식 지정 API를 사용할 필요가 없습니다. 이 유형의 검사 정의 함수를 만드는 방법에 대한 자세한 내용은 Fix a Model to Comply with Conditions That You Specify with the Model Advisor 항목을 참조하십시오.
모델 구성 파라미터 설정 검사
defineConfigurationParameterCheck.m 파일에는 defineConfigurationParameterCheck 검사 정의 함수가 포함되어 있으며, 이 함수는 MISRA C:2012 준수 코드 생성에 영향을 미칠 수 있는 모델 구성 파라미터 설정을 식별하는 검사를 정의합니다. 이 검사의 이름은 [Check model configuration parameters]입니다.
이 검사에는 지원 XML 데이터 파일이 필요하며, 이 파일은 MATLAB 경로에 있어야 하고 검사하려는 모델 구성 파라미터 설정을 포함해야 합니다. 이 예제에서 해당 파일은 configurationParameterDataFile.xml입니다. 이 검사 유형을 만드는 방법에 대한 자세한 내용은 Create Model Advisor Check for Model Configuration Parameters 항목을 참조하십시오.
defineConfigurationParameterCheck.m 파일을 열고 검사합니다.
function defineConfigurationParameterCheck % Create ModelAdvisor.Check object and set properties. rec = ModelAdvisor.Check('com.mathworks.sample.configurationParameter'); rec.Title = 'Check model configuration parameters'; rec.setCallbackFcn(@(system)(Advisor.authoring.CustomCheck.checkCallback... (system)), 'None', 'DetailStyle'); rec.TitleTips = 'Identify configuration parameters that might impact MISRA C:2012 compliant code generation.'; % --- data file input parameters rec.setInputParametersLayoutGrid([1 1]); inputParam1 = ModelAdvisor.InputParameter; inputParam1.Name = 'Data File'; inputParam1.Value = 'configurationParameterDataFile.xml'; inputParam1.Type = 'String'; inputParam1.Description = 'Name or full path of XML data file.'; inputParam1.setRowSpan([1 1]); inputParam1.setColSpan([1 1]); rec.setInputParameters({inputParam1}); % -- set fix operation act = ModelAdvisor.Action; act.setCallbackFcn(@(task)(Advisor.authoring.CustomCheck.actionCallback... (task))); act.Name = 'Modify Settings'; act.Description = 'Modify model configuration settings.'; rec.setAction(act); % publish check into Demo folder. mdladvRoot = ModelAdvisor.Root; mdladvRoot.publish(rec, 'Demo'); end
블록 파라미터 제약 조건 검사
defineNewBlockConstraintCheck.m 파일에는 defineNewBlockConstraintCheck 검사 정의 함수가 포함되어 있으며, 이 함수는 사각형 형태를 갖지 않는 Logical Operator 블록을 식별하는 검사를 정의합니다. 이 검사의 이름은 Logical Operator 블록의 아이콘 형태 검사입니다.
블록 파라미터 제약 조건 검사는 편집 시 검사(edit-time checking)를 지원합니다. 이 검사 유형에 대한 자세한 내용은 Define Model Advisor Checks for Supported and Unsupported Blocks and Parameters 항목을 참조하십시오.
defineNewBlockConstraintCheck.m 파일을 열고 검사합니다.
function defineNewBlockConstraintCheck rec = Advisor.authoring.createBlockConstraintCheck('com.mathworks.sample.blockConstraint',... 'Constraints',@createBlockConstraints); % constraint creation is part of block constraint check definition rec.Title = 'Check icon shape of Logical Operator blocks'; rec.TitleTips = 'Checks icon shape of Logical Operator blocks. Icon shape of Logical Operator should be rectangular.'; % Publish check into Demo folder. mdladvRoot = ModelAdvisor.Root; mdladvRoot.publish(rec, 'Demo'); end function constraints = createBlockConstraints() % Create block constraints. c1 = Advisor.authoring.PositiveBlockParameterConstraint; c1.ID = 'ID_c1'; c1.BlockType = 'Logic'; c1.ParameterName = 'IconShape'; c1.SupportedParameterValues = {'rectangular'}; c1.ValueOperator = 'eq'; constraints = {c1}; end
createBlockConstraints 함수는 블록 제약 조건 c1을 정의합니다. Advisor.authoring.createBlockConstraintCheck 함수에는 제약 조건 생성 함수 createBlockConstraints를 호출하는 'Constraints' 이름-값 인수가 있습니다.
모델 어드바이저에서 사용자 지정 검사 보기
사용자 지정 검사를 사용할 수 있는지 확인하려면 모델 어드바이저를 여십시오.
1. 사용자 지정 검사가 모델 어드바이저에 표시되도록 하려면 모델 어드바이저의 검사 정보 캐시를 새로 고쳐야 합니다. MATLAB 명령 프롬프트에 다음을 입력합니다.
Advisor.Manager.refresh_customizations();
2. 예제 모델을 엽니다.
open_system('AdvisorCustomizationExample.slx');3. 모델링 탭에서 모델 어드바이저를 엽니다. MATLAB 명령 프롬프트에 다음 명령을 입력하여 모델 어드바이저를 열 수도 있습니다.
modeladvisor('AdvisorCustomizationExample.slx');Updating Model Advisor cache... Model Advisor cache updated. For new customizations, to update the cache, use the Advisor.Manager.refresh_customizations method.
4. 제품별 > Demo 폴더를 확장합니다. 검사 정의 함수에서 publish 명령은 검사를 제품별 > Demo 폴더에 추가합니다.

모델 어드바이저 사용자 지정 구성을 지정하고 배포하기
모델 어드바이저에 포함할 검사와 편집 시 검사(edit-time checking) 중에 사용할 검사를 지정하려면, 모델 어드바이저 구성 편집기를 사용하십시오.
1. 구성 편집기를 열려면 모델 어드바이저에서 열기 > 구성 편집기 열기를 클릭합니다.
2. 검사 및 폴더를 추가하거나 제거하려면 모델 어드바이저 구성 편집기의 편집 섹션에 있는 옵션 중에서 선택합니다.
3. 구성을 저장하려면 저장을 선택합니다. 창이 열리고 구성을 JSON 파일로 저장할지 묻는 메시지가 표시됩니다. 이 예제의 경우, demoConfiguration.json 파일에 이 예제를 위한 4개의 사용자 지정 검사가 포함되어 있으므로 구성을 저장할 필요가 없습니다.
4. 모델과 모델 어드바이저 구성 편집기를 닫습니다.
bdclose;
사용자 지정 검사 구성을 모델과 연결하고 검사 문제 해결하기
검사 문제를 해결하려면 먼저 구성을 모델에 연결하십시오. 그러면 편집 시(edit-time)에 문제를 해결할 수도 있고 모델 어드바이저에서 문제를 해결할 수도 있습니다.
1. 예제 모델을 엽니다.
open_system('AdvisorCustomizationExample.slx');2. 사용자 지정 구성 demoConfiguration.json을 모델에 연결합니다. 사용자 지정 구성을 모델에 연결하면, 모델을 열 때마다 모델이 동일한 검사 구성을 사용합니다. 모델링 탭을 클릭하고 모델 어드바이저 > 편집 시 검사를 선택합니다. 구성 파라미터 대화 상자에서 모델 어드바이저 구성 파일 파라미터에 대해 구성 파일의 경로를 지정합니다. 또는 명령 프롬프트에 다음 명령을 입력합니다.
ModelAdvisor.setModelConfiguration('AdvisorCustomizationExample', 'demoConfiguration.json');
3. 모델링 탭을 클릭하고 모델 어드바이저 > 편집 시 검사를 선택하여 편집 시 검사를 활성화합니다. 구성 파라미터 대화 상자가 열립니다. 편집 시 검사 파라미터를 선택합니다. 또는 명령 프롬프트에 다음 명령을 입력할 수 있습니다.
edittime.setAdvisorChecking('AdvisorCustomizationExample','on');
모델의 최상위 수준에서 2개 Inport 블록의 출력 데이터형은 int32입니다. 이 블록들은 녹청색이어야 하므로 편집 시 경고를 발생시킵니다. Outport 블록은 데이터형이 auto이고 흰색이므로 경고를 발생시키지 않습니다.

4. 각 Inport 블록에 대해 편집 시 경고 창을 클릭합니다. 그런 다음 수정을 클릭합니다. 블록의 색이 녹청색으로 바뀌고 경고가 사라집니다.
5. Logical Operator 블록은 사각형 형태여야 하므로 경고를 발생시킵니다. 편집 시 경고 창을 클릭한 다음 수정을 클릭합니다. Logical Operator 블록의 형태가 사각형으로 바뀌고 경고가 사라집니다.
6. 이제 편집 시 검사 경고를 해결했으므로, 모델 어드바이저를 열어 나머지 검사 문제를 해결합니다.
modeladvisor('AdvisorCustomizationExample.slx');Model Advisor is removing the existing report.
7. 모델 어드바이저의 사용자 지정 구성에 4개의 검사가 포함되어 있습니다. 검사 실행을 클릭합니다. 편집 시 해결한 2개의 검사는 통과합니다. 다른 2개의 검사는 경고를 발생시킵니다.

8. 블록 이름이 블록 아래에 표시되는지 검사 검사를 클릭합니다. 수정 사항을 적용하고 경고를 해결하려면 오른쪽 창에서 수정을 클릭합니다.
9. [Check model configuration parameters] 검사를 클릭합니다. 수정 사항을 적용하고 경고를 해결하려면 수정을 클릭합니다.
10. 검사를 다시 실행합니다. 이제 모든 검사가 통과합니다.
11. 모델과 모델 어드바이저를 닫습니다.
bdclose;
12. 작업 디렉터리에서 파일을 제거합니다. 다음 명령을 입력하여 모델 어드바이저의 검사 정보 캐시를 새로 고칩니다.
Advisor.Manager.refresh_customizations
모델 어드바이저 사용자 지정 구성을 프로그래밍 방식으로 실행하고 결과 보기
모델 어드바이저 구성을 프로그래밍 방식으로 실행한 다음 모델 어드바이저에서 결과를 열 수 있습니다.
1. ModelAdvisor.run 함수를 호출합니다.
SysResultObjArray = ModelAdvisor.run({'AdvisorCustomizationExample'},...
'Configuration','demoConfiguration.json');
2. 다음을 입력하여 모델 어드바이저에서 결과를 확인합니다.
viewReport(SysResultObjArray{1},'MA')
3. 대화 상자에서 계속을 클릭합니다. 이제 수정 사항을 적용하고 경고를 해결할 수 있습니다.
4. 모델과 모델 어드바이저를 닫습니다.
bdclose;
5. 작업 디렉터리에서 파일을 제거합니다. 다음 명령을 입력하여 모델 어드바이저의 검사 정보 캐시를 새로 고칩니다.
Advisor.Manager.refresh_customizations
참고 항목
ModelAdvisor.Check | ModelAdvisor.EdittimeCheck