當用戶編寫了自定義的S函數或者使用Simulink標准庫中的模塊搭建子系統后,可以通過封裝為其設計顯示外觀,追加參數對話框。
封裝是構建一個以對話框為接口的交互界面的過程,它將復雜的模塊邏輯關系隱藏起來,封裝之后僅提供給用戶GUI界面填寫參數。用戶僅需操作對話框即可實現自定義的功能。
11.1 Mask Editor封裝模塊
Mask Editor封裝的對象有兩種:
- Simulink Library中的模塊構成的子系統,每個參數已經具有變量名和依附的控件,只需將其鏈接到新封裝的GUI控件上即可;
- S函數編寫的模塊,需要為每個參數創建變量名和參數控件。
11.1.1 封裝模塊構成的子系統
y=ax^2+b;
右擊Mask→Create Mask
包括4個頁面:
- Icon&Ports:編輯子系統的模塊外觀,如在子系統圖標中添加線條、文本和圖像等;
- Parameters&Dialog:添加或修改模塊參數,並為其設計控件類型;
- Initialization:編輯子模塊的初始化腳本;
- Documentation:添加子模塊的功能介紹及Help文檔路徑。
Icon&Ports
- disp('y=a*x^2+b');
將字符串顯示在子系統框圖的中央。
- text(x,y,'text'):x、y為坐標對,表示text相對於遠點所顯示的位置;
- text(x,y,'text','horizontalAlignment','halign','verticalAlignment','valign'):設置文本顯示的坐標和方位;
- text(x,y,'text','texmode','on'):開啟tex文本模式。
text(0,0,'y=a*x^2+b','horizontalAlignment','left','verticalAlignment','bottom');
通過Icon Units開啟歸一化,坐標范圍0~1。
在text和disp函數語句之前使用color函數,可以規定文本顯示時所使用的顏色,參數可為blue、green、red、cyan、magenta、yellow、black。
color('magenta'); text(0.3,0.3,'y=a*x^2+b','horizontalAlignment','left','verticalAlignment','bottom');
如果使用多種顏色,可以使用多個color分段調整文字的顏色。
- image:將圖片展示到子系統或S函數模塊框圖上。
image(imread('Mask_demo01.jpg'));將
圖片全伸展展示。
image(imread('Mask_demo01.jpg'),'top-left');
部分區域顯示。
在定義完Parameters&Dialog之后,可以通過plot函數繪制圖像到所封裝的方框圖上。
在Icon drawing commands中輸入以下代碼。
a=str2num(get_param(gcbh,'g_a')); b=str2num(get_param(gcbh,'g_b')); t=0:0.1:10; plot(t,a*t.^2+b);
Icon units選擇AutoScale。
封裝子系統的模塊圖標時,可以使用Port_label函數設置輸入輸出端口的顯示名稱
- port_label('port_type',port_number,'label','texmode','on');
port_type是指輸入或輸出端口,用input、output表示,當子系統為使能子系統、觸發子系統或與流控制相連的Action子系統時,也可以指定Enable、trigger或Action端口。
port_number為port_type指定的端口類型存在多個端口時端口的序號,從1開始。
label為在指定端口顯示的文本字樣。
texmode表示tex模式開啟與否。
在Icon drawing commands中輸入以下代碼。
port_label('input',1,'In','texmode','on'); port_label('output',1,'Out','texmode','on');
Parameters&Dialog
- Parameter:包括edit、popup、radiobutton和checkbox等控件,其具有value屬性,用戶可輸入或選擇參數的值,並將該值以變量的形式傳遞到模塊內部使用,用戶可以定義控件參數發生變化時所觸發的回調函數。
- Display:作用是提示用戶信息,比如文字或圖片。
- Container:含Panel、tab、group box等,可以進行分組,控件tab和group box內部還可以再使用Mask Controls。其中tab控件與其他控件有所不同,不能直接添加到模塊對象中,需要與稱作tabcontainer的隱藏控件共同使用。這些控件僅僅在視覺上起到簡明、美觀的提示作用,沒有value屬性和回調函數。
- Action:包括超鏈接和按鈕兩種控件,可通過單擊動作觸發用戶自定義的回調函數,但是控件本身沒有變量名,也不必傳遞到封裝的模型或S函數內部的功能。
Dialog Box是當前對話框已經包含的控件信息表格,表格默認顯示3個屬性:type、Prompt、Name,分別表示控件的類型、說明標簽和變量名。
屬性列表:
屬性名 | 作用說明 |
Name | 控件變量名 |
Value | 控件變量的值 |
Prompt | 控件作用提示文字 |
Type | 控件類型選擇 |
Evaluate | 控件中輸入的內容作為字符串,進行一次eval(str)操作 |
Tunable | 仿真過程中控件值是否可變 |
Read only | 只讀,不可編輯 |
Hidden | 隱藏控件 |
Never save | 即使控件改變也不保存 |
Enable | 僅在Read only時不使能,用戶不能編輯控件,顯示為灰色 |
Visible | 控制控件是否可見,僅當Hidden時使用 |
Callback | 編寫或調用控件的回調函數 |
Item location | New/Current row,設定控件放在當前行或者另起一行 |
Prompt location | Top/Left,設定說明文字在控件的上方或左方 |
輸入非法性檢查(輸入字母則報錯):
function check_num(param) % This function check if the value of param is a number data type. val = get_param(gcbh, param); if isletter(val) errordlg(['Input value of ', param(end) ,' must be a number data-type!']); return; end
Initialization
主要用於定義模塊的初始化命令,已經封裝過的參數名將列在左側。
此頁面可以填入M代碼。
模塊的Initialization commands在以下時刻執行:
- 當Icon draw commands或Initialization commands里更改封裝參數時;
- 當Icon draw commands有內容時,翻轉或旋轉模塊;
- 雙擊打開模塊的參數對話框或單擊參數對話框上的Apply/OK/Cancel按鈕關閉對話框時;
- 當使用set_param函數更改模塊參數的值時,賦相同值也會觸發;
- 拷貝此模塊到同一模型中或其他模型中;
- 模型運行仿真時;
- 模型編譯生成代碼時;
- 模型工具欄中選擇Updata diagram時。
如果需要在上述時刻觸發某些動作,或者重新刷新模塊的外觀,可以在這里編寫M腳本或調用M函數。
Documentation
用來補充模塊的說明信息及Help按鈕的功能。
Type的內容顯示到模塊參數對話框的左上角,Description的內容則緊隨其后。
11.1.2 封裝S函數編寫的模塊
直接按11.1.1中方法Mask即可。
11.2 編程自動封裝模塊
11.2.1模塊的屬性
>> get(gcbh) Path: 'mymodel' Name: 'y=a*x^2+b' Tag: '' Description: '' Type: 'block' Parent: 'mymodel' Handle: 5.0001 HiliteAncestors: 'none' RequirementInfo: '' FontName: 'auto' FontSize: -1 FontWeight: 'auto' FontAngle: 'auto' Selected: 'on' MaskType: 'Custom' MaskDescription: 'This block supplies a demo of masking.' MaskHelp: '' MaskPromptString: 'a|b' MaskStyleString: 'edit,edit' MaskVariables: 'g_a=@1;g_b=@2;' MaskTunableValueString: 'on,on' MaskCallbackString: 'check_num('g_a');|check_num('g_b');' MaskEnableString: 'on,on' MaskVisibilityString: 'on,on' MaskToolTipString: 'on,on' MaskVarAliasString: '' MaskInitialization: '' MaskSelfModifiable: 'off' MaskDisplay: 'a=str2num(get_param(gcbh,'g_a'));↵b=str2num(get_param(gcbh,'g_b'));↵t=0:0.1:10;↵plot(t,a*t.^2+b);' MaskBlockDVGIcon: '' MaskIconFrame: 'on' MaskIconOpaque: 'opaque' MaskIconRotate: 'none' MaskPortRotate: 'default' MaskIconUnits: 'autoscale' MaskValueString: '1|20' MaskRunInitForIconRedraw: 'off' MaskTabNameString: '' Mask: 'on' MaskCallbacks: {2×1 cell} MaskEnables: {2×1 cell} MaskNames: {2×1 cell} MaskPropertyNameString: 'g_a|g_b' MaskPrompts: {2×1 cell} MaskStyles: {2×1 cell} MaskTunableValues: {2×1 cell} MaskValues: {2×1 cell} MaskToolTipsDisplay: {2×1 cell} MaskVisibilities: {2×1 cell} MaskVarAliases: {2×1 cell} MaskWSVariables: [1×2 struct] MaskTabNames: {2×1 cell} MaskObject: [] Ports: [1×9 double] Position: [1×4 double] Orientation: 'right' PortRotationType: 'default' ForegroundColor: 'black' BackgroundColor: 'white' DropShadow: 'off' IOType: 'none' NamePlacement: 'normal' ShowName: 'on' HideAutomaticName: 'on' Priority: '' Commented: 'off' AttributesFormatString: '' TargetArchitectureMapping: {} InstantiateOnLoad: 'off' PolySpaceEndComment: '' PolySpaceStartComment: '' AncestorBlock: '' ReferenceBlock: '' SourceLibraryInfo: '' LibraryVersion: '' UserDataPersistent: 'off' UserData: [] CompiledIsActive: 'on' RTWdata: [] HDLData: [] Diagnostics: '' DialogParameters: [1×1 struct] IntrinsicDialogParameters: [1×1 struct] AlgorithmParameters: [1×1 struct] SecondaryAlgorithmParameters: [1×1 struct] CompiledSampleTime: [-1 0] InputSignalNames: {''} OutputSignalNames: {''} ModelParamTableInfo: [] StatePerturbationForJacobian: '1.0e-05' SCDEnableBlockLinearizationSpecification: 'off' SCDBlockLinearizationSpecification: [] CopyFcn: '' DeleteFcn: '' UndoDeleteFcn: '' LoadFcn: '' ModelCloseFcn: '' PreSaveFcn: '' PostSaveFcn: '' InitFcn: '' StartFcn: '' PauseFcn: '' ContinueFcn: '' StopFcn: '' NameChangeFcn: '' ClipboardFcn: '' DestroyFcn: '' PreCopyFcn: '' OpenFcn: '' CloseFcn: '' PreDeleteFcn: '' ParentCloseFcn: '' MoveFcn: '' BlockType: 'SubSystem' BlockDescription: 'Select the settings for the subsystem block. To enable parameters for code generation, select 'Treat as atomic unit'.' LinkStatus: 'none' StaticLinkStatus: 'none' PortConnectivity: [2×1 struct] PortHandles: [1×1 struct] LineHandles: [1×1 struct] CompiledPortWidths: [0×0 struct] CompiledPortDimensions: [0×0 struct] CompiledPortDataTypes: [0×0 struct] CompiledPortUnits: [0×0 struct] CompiledPortComplexSignals: [0×0 struct] CompiledPortFrameData: [0×0 struct] DataTypeOverride_Compiled: 'UseLocalSettings' MinMaxOverflowLogging_Compiled: 'UseLocalSettings' Capabilities: [1×1 Capabilities] IOSignalStrings: [] RuntimeObject: [0×1 double] ExtModeUploadOption: 'none' ExtModeLoggingSupported: 'off' ExtModeLoggingTrig: 'off' ShowPortLabels: 'FromPortIcon' BlockChoice: '' TemplateBlock: '' MemberBlocks: '' Permissions: 'ReadWrite' ErrorFcn: '' PermitHierarchicalResolution: 'All' TreatAsAtomicUnit: 'off' MinAlgLoopOccurrences: 'off' PropExecContextOutsideSubsystem: 'off' SystemSampleTime: '-1' RTWSystemCode: 'Auto' RTWFcnNameOpts: 'Auto' RTWFcnName: '' RTWFileNameOpts: 'Auto' RTWFileName: '' FunctionInterfaceSpec: 'void_void' FunctionWithSeparateData: 'off' RTWMemSecFuncInitTerm: 'Inherit from model' RTWMemSecFuncExecute: 'Inherit from model' RTWMemSecDataConstants: 'Inherit from model' RTWMemSecDataInternal: 'Inherit from model' RTWMemSecDataParameters: 'Inherit from model' IsSubsystemVirtual: 'on' Variant: 'off' VariantControl: '' OverrideUsingVariant: '' GeneratePreprocessorConditionals: 'off' AllowZeroVariantControls: 'off' PropagateVariantConditions: 'off' ActiveVariant: '' ActiveVariantBlock: '' TreatAsGroupedWhenPropagatingVariantConditions: 'on' Location: [1×4 double] Open: 'off' PortBlocksUseCompactNotation: 'off' ScrollbarOffset: [-106 -133] SetDomainSpec: 'off' DomainSpecType: 'Deduce' CompiledDomainSpecType: 'Unset' ModelBrowserVisibility: 'off' ModelBrowserWidth: 200 ScreenColor: 'white' CurrentBlock: 'Gain' CurrentOutputPort: [] Blocks: {6×1 cell} Lines: [5×1 struct] DeleteChildFcn: '' PaperOrientation: 'landscape' PaperPosition: [1×4 double] PaperPositionMode: 'auto' PaperType: 'usletter' PaperSize: [11 8.5000] PaperUnits: 'inches' TiledPaperMargins: [1×4 double] TiledPageScale: 1 ShowPageBoundaries: 'off' ZoomFactor: '100' ReportName: '' g_a: '1' g_b: '20'
inspect(gcbh)
與封裝有關的屬性列表:
屬性名 | 屬性的值 | 作用說明 |
MaskType | 'Custom' | Mask Editor的Documentation頁面的參數 |
MaskDescription | 'This block supplies a demo of masking.' | Mask Editor的Documentation頁面的參數 |
MaskHelp | 'helpview('xxx.html');' | Mask Editor的Documentation頁面的參數 |
MaskPromptString | 'a|b' | 參數的說明字符串,不同參數說明字符之間使用'|'分隔 |
MaskStyleString | 'edit,edit' | 參數的控件類型字符串,兩兩之間使用','分隔 |
MaskVariables | 'g_a=@1;g_b=@2;' | 參數變量名及其編號的字符串,兩兩之間使用';'分隔 |
MaskTunableValueString | 'on,on' | 表征參數是否在仿真時間內可調,使用','分隔 |
MaskCallbackString | 'check_num('g_a');|check_num('g_b');' | 表示參數Callback調用的內容字符串,使用'|'分隔 |
MaskEnableString | 'on,on' | 表示參數是否使能的字符串,使用','分隔 |
MaskVisibilityString | 'on,on' | 表示參數是否可見的字符串,使用','分隔 |
MaskToolTipString | 'on.on' | 表示當鼠標停留在模塊外觀框圖范圍內是是否在提示框顯示參數值 |
MaskInitialization | '' | Initialization Command的內容字符串 |
MaskDisplay | 'a=str2num(get_param(gcbh,'g_a')); |
Icon Draw Commands的內容字符串 |
MaskValueString | '1|20' | 模塊封裝參數的當前值,用'|'分隔 |
MaskCallbacks | Cell類型的MaskCallbackString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskEnables | Cell類型的MaskEnableString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskNames | Cell類型的參數名 |
可以使用元胞數組的下標進行訪問或編輯 |
MaskPropertyNameString | g_a|g_b | 字符形式,將參數變量名用'|'分隔並連接起來 |
MaskPrompts | Cell類型的MaskPromptsString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskStyles | Cell類型的MaskStylesString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskTunableValues | Cell類型的MaskTunableValuesString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskValues | Cell類型的MaskValuesString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskToolTipsDisplay | Cell類型的MaskToolTipsString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskVisibilities | Cell類型的MaskVisibilitiesString | 可以使用元胞數組的下標進行訪問或編輯 |
MaskTabNames | Cell型數組,每個元素為對應參數所在tab頁面的名字 | 可以使用元胞數組的下標進行訪問或編輯 |
幫助文檔:https://www.mathworks.com/help/simulink/slref/mask-parameters.html
11.2.2 使用set_param和get_param封裝模塊
- ParameterValue=get_param(Object,ParameterName)
Object表示模塊或者模型的句柄或模型模塊路徑,ParameterName表示模塊或模型的屬性。
- set_param(Object,ParameterName,value)
parameterName和value可以多組成對出現。
例:
set_param('mymodel/y=a*x^2+b','Maskvisibilities',{'on','off'})
使用Excel編輯封裝:
function masktool(block, excelfile) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This function help to mask parameters into block selected. % MaskNames should not be the same % MaskPrompts, MaskNames, MaskStyles, popupcontents, MaskTabs, MaskCallbackStrings % are written in Excel and this function can automatically transfer them % % block - the block need to be masked % excelfile - parameters saved in the excelfile % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % index definition promts_index = 1; names_index = 2; styles_index = 3; popups_index = 4; tabs_index = 5; callbacks_index = 6; % get data in excelfile [num, str] = xlsread(excelfile); % get mask prompts and saved as cell format promts = str(2:end,promts_index); % get mask names and saved as cell format names = str(2:end,names_index); % change names to MaskVariables format len = length(names); maskvar = ''; for ii = 1 : len maskvar = [maskvar, names{ii}, '=@', num2str(ii), ';']; %OK end % get mask styles and saved as cell format styles = str(2:end,styles_index); % get mask tab names tabname = str(2:end, tabs_index); % get callbacks strings callbackstr = str(2:end, callbacks_index); %get block's handle blockhandle = get_param(block,'Handle'); % get model properties prop = get(blockhandle); % mask promts into block set_param(blockhandle, 'MaskPrompts', promts); % mask names into block (MaskNames or MaskPropertyNameString is a readonly property) %set_param(blockhandle, 'MaskNames', names); set_param(blockhandle, 'MaskVariables', maskvar); % mask styles intoblock set_param(blockhandle, 'MaskStyles', styles); % check popup to write strings style = str(2:end, styles_index); % get popup strings popups = str(2:end, popups_index); % popuplen = length(popups); % for ii = 1 :popuplen % str2pro = popups{ii}; % str2pro(findstr(popups{ii} ,char(10))) = ''; %char(10) = line change token, delete it % popups{ii} = str2pro; % end % get MaskStyleString stylestring = get_param(blockhandle, 'MaskStyleString'); % get empty start index from MaskStyleString and its length and its total number emptystart = regexp(stylestring,'<empty>'); lenempty = length('<empty>'); if ~isempty(emptystart) numtorep = length(emptystart); % draw popup content from excelfile content = cell(numtorep); count = 1; num = length(style); for ii = 1:num if strcmp(style{ii}, 'popup')||strcmp(style{ii}, 'radiobutton') content{count} = str(ii + 1, popups_index); % content keep format as xxx|xxx|xxx count = count + 1; end end end % part stylestring to seperate parts % create cell using () not {} if ~isempty(emptystart) strpart = cell(numtorep + 1); strpart{1} = stylestring(1: emptystart(1) - 1); for ii = 2 : numtorep strpart{ii} = stylestring(emptystart(ii-1) + lenempty :emptystart(ii) - 1); end strpart{numtorep + 1} = stylestring(emptystart(end) + lenempty : end); % insert content into strpart maskstring =strpart{1}; for ii = 1: numtorep maskstring = strcat(maskstring, content{ii}); maskstring = strcat(maskstring, strpart{ii + 1}); end % cell changed to string stylestring = char(maskstring); % delete char(10) (which is not \n or \r) stylestring(findstr(stylestring, char(10))) = ''; %delete char(10) change line token % set MaskStyleString into block set_param(blockhandle, 'MaskStyleString', stylestring); end % set tab names set_param(blockhandle, 'MaskTabNames', tabname); % format callback str to xx|xx|xx|xx style but not display in callback dialog % cbnum = length(callbackstr); % cbstr = ''; % for ii = 1:cbnum % cbstr = [cbstr, callbackstr{ii},'|']; % end % cbstr % set MaskCallbacks set_param(blockhandle, 'MaskCallbacks', callbackstr); % get model name modelname = get_param(blockhandle, 'Name'); %modelpath = get_param(blockhandle, 'Path'); %fullname = fullfile(modelpath, modelname); % write Parameters automatically paramstr = get_param(blockhandle, 'MaskPropertyNameString'); paramstr(findstr(paramstr,'|')) = ','; set_param(blockhandle, 'Parameters', paramstr); % write S-Function name automatically set_param(blockhandle, 'FunctionName', excelfile); % print OK info disp([modelname, ' Mask Over!']);
>> masktool(gcbh,'BlkName.xls'); S-Function Mask Over!
11.2.3 使用Simulink.Mask類封裝模塊
Simulink.Mask類給模塊創建一個封裝對象,再通過對象的子方法來操作其各個屬性。Simulink.Mask類提供的方法包括以下操作:
- 創建、拷貝、刪除模塊的封裝;
- 創建、拷貝、刪除模塊封裝的參數;
- 決定封裝的對象模塊;
- 獲取封裝時的工作空間變量。
>> maskObj=Simulink.Mask.get(gcbh) maskObj = Mask - 屬性: Type: 'Custom' Description: 'This block supplies a demo of masking.' Help: '' Initialization: '' SelfModifiable: 'off' Display: 'a=str2num(get_param(gcbh,'g_a'));↵b=str2num(get_param(gcbh,'g_b'));↵t=0:0.1:10;↵plot(t,a*t.^2+b);' IconFrame: 'on' IconOpaque: 'opaque' RunInitForIconRedraw: 'off' IconRotate: 'none' PortRotate: 'default' IconUnits: 'autoscale' Parameters: [1×2 Simulink.MaskParameter] ParameterConstraints: [0×0 Simulink.Mask.Constraints] CrossParameterConstraints: [0×0 Simulink.Mask.CrossParameterConstraints] BaseMask: [0×0 Simulink.Mask]
MaskObj成員列表:
屬性成員名 | 說明 |
Type | Mask Type |
Description | Mask Description |
Help | 打開help文檔的代碼 |
Initialization | 初始化命令 |
SelfModifiable | 是否使能模塊修改自身內容,如popup的下拉菜單內容在Callback中被改變 |
Display | 繪制模塊外觀的代碼 |
IconFrame | IconFrame是否可見 |
IconOpaque | 模塊圖標是否透明 |
RunInitForIconRedraw | 在執行模塊外觀繪制前是否必須執行初始化命令 |
IconRotate | 模塊外觀圖標是否跟隨模塊一起旋轉 |
IconUnits | 模塊外觀圖標的單位設置,'pixel|autoscale|normalized' |
Parameters | 封裝參數集合,類型為Simulink.MaskParameters |
BaseMask | 未使用屬性 |
Simulink.Mask類子方法列表:
子方法名 | 功能說明 |
addParameter | 向模塊中增加一個參數,參數名與值成對輸入,當所封裝模塊與Simulink標准庫有關聯時,使用此函數會報錯 |
copy | 將一個模塊的封裝拷貝到另外一個模塊 |
create | 為未封裝的模塊創建一個封裝對象 |
delete | 為模塊解封裝並刪除封裝對象變量 |
get | 獲取模塊的封裝並存為一個對象變量 |
getDialogControl | 查找封裝對象中的控件,參數為控件的變量名Name,返回被查找對象變量及其父對象變量 |
isMaskWithDialog | 當前對象是否封裝了對話框 |
getOwner | 獲取當前封裝所依附的模塊 |
getParameter | 獲取某個參數的屬性,輸入參數為這個參數的Name |
getWorkspaceVariables | 獲取當前封裝所使用的所用參數並將參數名與值作為結構體變量返回 |
numParameters | 返回封裝中參數的個數 |
removeAllParameters | 刪除封裝中所有的參數,一般不建議使用。當刪除的Mask的Owner與Simulink標准庫中存在鏈接關系的話,禁止刪除 |
set | 設置封裝某個屬性的值,用法類似set_param,屬性名與值可成對輸入 |
addDialogControl | 為父對象添加控件,父對象可以為模塊的封裝對象,也可為group和tab container等能夠包容子控件的控件對象 |
封裝Simulink子系統
對於未封裝的子系統:
maskObj=Simulink.Mask.create(gcbh); maskObj.Type='Custom'; maskObj.Description='This demo displays how to mask a model.'; maskObj.Display='t=0:0.1:10;y=t.^2+1;plot(t,y)'; g_a=maskObj.addParameter('Type','edit','Name','g_a','Prompt','a','Value','0'); g_b=maskObj.addParameter('Type','edit','Name','g_b','Prompt','b','Value','0'); g_a.set('Value','1'); g_b.Value='20';
封裝S函數模塊
function masktool_neo(block, excelfile) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % This function help to mask parameters and displays into block selected. % MaskNames should not be the same % MaskPrompts, MaskNames, MaskStyles, popupcontents, MaskTabs, MaskCallbackStrings % are written in Excel and this function can automatically transfer them to % the S-function block.Block masked by this tool can not be edited in Mask % Editor. % % block - the block need to be masked % excelfile - parameters saved in the excelfile % % button, image, text, hyperlink, group supported %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % index definition promts_index = 1; names_index = 2; styles_index = 3; popups_index = 4; % tabs_index = 5; callbacks_index = 6; % get data in excelfile [num, str] = xlsread(excelfile); % get mask prompts and saved as cell format promts = str(2:end,promts_index); % get mask names and saved as cell format names = str(2:end,names_index); % change names to MaskVariables format % get mask styles and saved as cell format styles = str(2:end,styles_index); % get mask tab names % tabname = str(2:end, tabs_index); % get TypeOptions typeopts = str(2:end, popups_index); % get callbacks strings callbackstr = str(2:end, callbacks_index); % test if gcbh is masked. If masked , delete the old mask and create a % blank one. maskobj = Simulink.Mask.get(block); if ~isempty(maskobj) maskobj.delete; end maskobj = Simulink.Mask.create(block); % parameter list value p_str = []; % get the object of groupbox "Parameter" % par_obj = maskobj.getDialogControl('ParameterGroupVar'); % add controls according to the styles. len = length(names); for ii = 1:len if ismember(styles{ii}, {'text','group','tab'}) % addDialogControl without callback prop = maskobj.addDialogControl(styles{ii},names{ii}); prop.Prompt = promts{ii}; elseif ismember(styles{ii}, {'pushbutton','hyperlink'}) % addDialogControl for Action controls, they have Callback prop = maskobj.addDialogControl(styles{ii},names{ii}); prop.Prompt = promts{ii}; prop.Callback = callbackstr{ii}; elseif ismember(styles{ii}, 'image') % addDialogControl without Prompt prop = maskobj.addDialogControl(styles{ii},names{ii}); elseif ismember(styles{ii},{'edit','checkbox'}) % 'dial','spinbox','slider' only supported in 2014a and later % addParameter p_str = [p_str, names{ii}, ',']; p = maskobj.addParameter('Type', styles{ii}, 'Prompt', promts{ii},'Name', names{ii}, 'Callback', callbackstr{ii}); elseif ismember(styles{ii}, {'popup','radiobutton'}) % addParameter for parameters that have TypeOptions p_str = [p_str, names{ii}, ',']; expression = '\|'; split_str = regexp(typeopts{ii},expression,'split'); maskobj.addParameter('Type', styles{ii},'TypeOptions', split_str, 'Prompt', promts{ii}, 'Name', names{ii}, 'Callback', callbackstr{ii}); end end % write S-Function name and parameter-list automatically set_param(block, 'FunctionName', excelfile); set_param(block, 'Parameters', p_str(1:end - 1)); disp('Current block is masked automatically.');
11.3 使用GUIDE封裝模塊
使用S-Function模塊結合Level M S函數文件在Simulinnk中實現選擇Excel文件,並將其中數據按照采樣時間順序輸出的功能。
在模塊的對話框中,將數據通過表格展示,並直接將Excel中數據的圖像繪制出來。
function [sys,x0,str,ts,simStateCompliance] = sfun_xlsread(t,x,u,flag,g_file_path) switch flag, case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(g_file_path); case 1, sys=mdlDerivatives(t,x,u); case 2, sys=mdlUpdate(t,x,u); case 3, sys=mdlOutputs(t,x,u); case 4, sys=mdlGetTimeOfNextVarHit(t,x,u); case 9, sys=mdlTerminate(t,x,u); otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); end function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(g_file_path) global data len cnt [data, str] = xlsread(g_file_path); len = length(data); sizes = simsizes; sizes.NumContStates = 0; sizes.NumDiscStates = 0; sizes.NumOutputs = 1; sizes.NumInputs = 0; sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 1; sys = simsizes(sizes); x0 = []; str = []; ts = [0,0]; cnt = 0; simStateCompliance = 'UnknownSimState'; function sys=mdlDerivatives(t,x,u) sys = []; function sys=mdlUpdate(t,x,u) sys = []; function sys=mdlOutputs(t,x,u) global data len cnt cnt = cnt + 1; if cnt <= len sys = data(cnt); else sys = data(end); end function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; sys = t + sampleTime; function sys=mdlTerminate(t,x,u) sys = [];
function varargout = sfun_xlsread_gui(varargin) % SFUN_XLSREAD_GUI MATLAB code for sfun_xlsread_gui.fig % SFUN_XLSREAD_GUI, by itself, creates a new SFUN_XLSREAD_GUI or raises the existing % singleton*. % % H = SFUN_XLSREAD_GUI returns the handle to a new SFUN_XLSREAD_GUI or the handle to % the existing singleton*. % % SFUN_XLSREAD_GUI('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in SFUN_XLSREAD_GUI.M with the given input arguments. % % SFUN_XLSREAD_GUI('Property','Value',...) creates a new SFUN_XLSREAD_GUI or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before sfun_xlsread_gui_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to sfun_xlsread_gui_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help sfun_xlsread_gui % Last Modified by GUIDE v2.5 26-Jul-2014 19:44:47 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @sfun_xlsread_gui_OpeningFcn, ... 'gui_OutputFcn', @sfun_xlsread_gui_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before sfun_xlsread_gui is made visible. function sfun_xlsread_gui_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to sfun_xlsread_gui (see VARARGIN) % Choose default command line output for sfun_xlsread_gui handles.output = hObject; % Update handles structure guidata(hObject, handles); % UIWAIT makes sfun_xlsread_gui wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = sfun_xlsread_gui_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) close(gcf); % --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) % hObject handle to pushbutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) close(gcf); % --- Executes on button press in pushbutton3. function pushbutton3_Callback(hObject, eventdata, handles) % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) disp('Help button is pressed. User can supply help file themselves.'); % --- Executes on button press in pushbutton4. function pushbutton4_Callback(hObject, eventdata, handles) % hObject handle to pushbutton4 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename, pathname] = uigetfile({'*.xls','*.xlsx'}, 'Select an Excel file'); if isequal(filename,0) set_param(gcbh, 'g_file_path', ''); set(handles.edit1, 'string', ''); disp('User selected Cancel'); return; else file_path = fullfile(pathname, filename); set_param(gcbh, 'g_file_path', file_path); set(handles.edit1, 'string', file_path); end [data, str] = xlsread(file_path); set(handles.uitable1, 'data', data); axes(handles.axes1); bar(data, 'g'); function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of edit1 as a double % --- Executes during object creation, after setting all properties. function edit1_CreateFcn(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end