Guy on Simulink

Simulink & Model-Based Design

Initializing buses using a MATLAB Structure 10

Posted by Guy Rouleau,

Did you notice that since R2010a it is possible to initialize buses with a MATLAB structure? If you were not aware, here is how it works.

Starting from a Structure

Let's say I have a structure in the MATLAB workspace and I would like to make that a bus signal in Simulink. I can use Simulink.Bus.createObject to create a bus object:

myStruct.a = 5;
myStruct.b = true;
myStruct.c.x1 = 22;
myStruct.c.x2 = 3;
busInfo = Simulink.Bus.createObject(myStruct);

Then I can configure a Constant block to use this bus object as data type and to use myStruct as value.

Configuring a Constant block to output a bus

Constant block outputing a bus signal

Starting from a model

Let's say I have the following model where a bus signal is going through a Unit Delay block. I want to specify different initial values for the elements of the bus.

Specifying the initial condition for a bus signal

In that case I can use the handle to a port of the Unit Delay block as input to Simulink.Bus.createMATLABStruct. This will create a MATLAB structure with the same hierarchy as the bus, filled with zeros. I can then overwrite fields of this structure as needed and use it as the initial value of the Unit Delay.

portHandle = get_param(gcb,'PortHandles');
initStruct = Simulink.Bus.createMATLABStruct(portHandle.Inport);
initStruct.bus2.Pulse = 5;
initStruct.signal1.Chirp = 3;

Requirements to Use Bus Signal Initialization

To enable bus signal initialization, you need to set two Configuration Parameter diagnostics:

Even if you don't need to initialize buses, I always recommend using those setting. They help making your models easier to understand and improve the consistency of simulation results.

Now it's your turn

Look at Specifying Initial Conditions for Bus Signals for more details and let us know how you will use this feature by leaving a comment here.

10 CommentsOldest to Newest

Bob replied on : 1 of 10
I remember looking at this before, but going away disappointed because bus arrays (added about the same time, or in R2010b?) weren't supported. I didn't see this in your list of requirements / limitations. Did I misunderstand / has this changed?
guyr replied on : 2 of 10
@Bob, this topic is covered in the documentation for Arrays of buses: Arrays of buses can be initialized using a scalar structure. This scalar structure will be applied to all the individual buses in the array of buses. Please let me know if this is important for you to initialize the individual structures with different values, fur example using an array of structures.
Thomas Marullo replied on : 3 of 10
There is a limitation when you have multi-dimension buses. Modifying the above example to have "c" be multi-dimension: myStruct.a = 5; myStruct.b = true; myStruct.c = struct; myStruct.c(1).x1 = 22; myStruct.c(2).x1 = 3; busInfo = Simulink.Bus.createObject(myStruct); Then looking at the "c" element in the slBus1 object gives you Dimensions: 1, where it should be [1 2] >> slBus1.Elements(3) ans = Simulink.BusElement Name: 'c' DataType: 'c' Complexity: 'real' Dimensions: 1 DimensionsMode: 'Fixed' SamplingMode: 'Sample based' SampleTime: -1 I understand then there is a limitation with Simulink.Bus.createMATLABStruct if you have multi-dimension elements since it is not supported, but I have an example here that if modified with the Bus Editor to set the dimensions properly will work in Simulink. I am currently trying to modify Simulink.Bus.createObject so that it can handle such the case.
Guy Rouleau replied on : 4 of 10
@Thomas, Thank you for bringing that to our attention. I forwarded this information to our development team to see if this can be improved.
Radityo Pradipto replied on : 5 of 10
Do you guys find anything new on how to use multidimensional structure using 'Simulink.Bus.createObject' command? That would be really helpful for my team. My research team in University of Melbourne is currently working on how to expand the limitation multi dimensional structure above since we need it to simplify our simulation project, so I'll post something in case we manage to figure it out
Thomas Marullo replied on : 6 of 10
@Radityo, I modified the Simulink.Bus.createObject file, specifically the createBus function with a simple set of code that correctly sets the dimension parameter: %% tmm dimension change if (numel(node) > 1) el.Dimensions = [1 numel(node)]; end %% Full Function below: % Create Bus object (recursive calls) function [busName, idx]= createBus(sp, path, name, idx) busName=[]; if ~isstruct(sp) return; end if ~isempty(path) path = [path, '.']; end busObj=Simulink.Bus; nodeNames = fieldnames(sp); for n=1:size(nodeNames,1) node = sp.(nodeNames{n}); if isstruct(node) % Generate sub-bus subBusName = nodeNames{n}; [subBusName, idx] = createBus(node, [path, nodeNames{n}], subBusName, idx); el=Simulink.BusElement; el.Name =nodeNames{n}; el.DataType =subBusName; %% tmm dimension change if (numel(node) > 1) el.Dimensions = [1 numel(node)]; end %% busObj.Elements(end+1)=el; elseif isnumeric(node) || islogical(node) el=Simulink.BusElement; el.Name =nodeNames{n}; [el.DataType, el.Dimensions, el.Complexity]=getValueAttr(node); busObj.Elements(end+1)=el; else DAStudio.error('Simulink:tools:slbusCreateObjectNonNumericStructField', ... [path, nodeNames{n}]); end end [busName, idx] = generateBusName(name, idx); assignin('base', busName, busObj); end This seems to work very well. Let me know if it helps.
Guy Rouleau replied on : 7 of 10
Thank you Thomas Marullo for sharing your implementation. Our development team is working on supporting this feature as soon as possible.
Prashanth replied on : 8 of 10
I would like to know how to get Structure element Initialization code in Generated Source Code, I have numerous Structure used across models via Bis Signals. I have initialized in .m script as shown below. ######################################## LabelData_s = struct; LabelData_s.Scheduler = uint16(0); LabelData_s._Label_107= uint32(0); LabelData_s._Label_150= uint32(0); LabelData_s._Label_167= uint32(0); busInfo = Simulink.Bus.createObject(LabelData_s); Labels_Struct=eval(busInfo.busName); %clear variable in temp vars used for this script from workspace clear LabelData_s busInfo slBus* ####################################################################### Is it becoz i use "Simulink.Bus.createObject" , initialization code doesnt get generated in source code ? Also Bus Signal is a ExternalGlobal, if that matters ( which i think it doesnt) Regards Prashanth
Anup replied on : 9 of 10
Have there been any further updates to this? I am trying to initialize a signal of datatybe BusObject. The bus definition is a 4 level nested bus with the innermost bus being multi-dimensioned. When I create a Matlab structure out of it it ends up looking like this...
ExternalInputs_MATLABStruct = struct;
ExternalInputs_MATLABStruct.VehControls = struct;
ExternalInputs_MATLABStruct.VehControls.VehDrivingInputs = struct;
ExternalInputs_MATLABStruct.VehControls.VehDrivingInputs.TBCInput = struct;
ExternalInputs_MATLABStruct.VehControls.VehDrivingInputs.TBCInput(1, 1).Modes = 0;
ExternalInputs_MATLABStruct.VehControls.VehDrivingInputs.TBCInput(1, 1).Values = 0;
and so forth for the rest of the elements. Once I create the structure, I am trying to use it to initialize a signal of the same bus data type. I am doing so by specifying the structure name created above as the InitialValue field of the signal.
 Inputs = 

  Signal with properties:

         CoderInfo: [1x1 Simulink.CoderInfo]
       Description: ''
          DataType: 'Bus: ExternalInputs'
               Min: []
               Max: []
          DocUnits: ''
        Dimensions: -1
    DimensionsMode: 'Fixed'
        Complexity: 'real'
        SampleTime: -1
      SamplingMode: 'Sample based'
      InitialValue: 'ExternalInputs_MATLABStruct' 
When I try to build the model it gives the below error:
Data type of InitialValue 'ExternalInputs_MATLABStruct' must be double or the same as the signal object data type 
Any inputs?
Guy Rouleau replied on : 10 of 10
@Anup: Everything you are doing seems correct, so I am probably missing something. I recommend sending you example to technical support.