Bus signal: save and load

32 visualizzazioni (ultimi 30 giorni)
MM
MM il 27 Giu 2019
Commentato: Sara Nadeau il 5 Lug 2019
I have a simulink model from which I want to save a bus signal and load this into another simulink model. I have no problems with saving the bus signal (I think) but I can't get the bus signal loaded in an other file. I have made a simple example (see attachment) to get an idea what I want to do. test_bus_save saves the signal :) and I want to load that signal in test_bus_load.
What am I doing wrong? Is it possible to save a bus signal and load it into another model?
In my example I want to put the signal to workspace but in reality I just want to use the data from the signal in another model. But the problems is with loading the bus signal.
I've used Matlab 2016b and 2018b (the files are created with 2018b)

Risposte (7)

Sara Nadeau
Sara Nadeau il 27 Giu 2019
When I try the attached models, I get an error about the Output data type setting for the From File block. To use this method for logging/loading bus data, you'll need a Simulink.Bus object to use as a data type specification for the From File block. Then, you can set the From File block Output data type to Bus: myBus and load the data.
If you have access to R2019a, you can load bus data without needing a Simulink.Bus object using In Bus Element blocks.

MM
MM il 28 Giu 2019
I see I uploaded a file with the wrong configuration. I uploaded a new one. But this one doesn't work either.
I don't really know what you mean with the Simulink.Bus link. Should I use another block to load (and/or save) in simulink?

Sara Nadeau
Sara Nadeau il 28 Giu 2019
Hi Mark,
You're doing just the right thing with logging the bus data. That piece tends to be a bit easier than loading bus data in Simulink.
With any of the loading blocks, including From File and Inport blocks, you need to tell the block what kind of data to expect. Because buses are flexible, in order to load bus data, you need to have a specification for what the loading block should expect to find in the bus you're loading.
Luckily, there are some helper functions to make creating this bus object easy, when you want to load bus data that was logged from another model. You can use the Simulink.Bus.createObject function to create a Simulink.Bus specification for the bus you log in test_bus_load.
busInfo = Simulink.Bus.createObject('test_bus_save','test_bus_save/Bus Creator');
The return is a structure array (scalar, in this case, because we only passed in one block name) with a field for the block handle (block) and the name of the Simulink.Bus object specification (busName). The default name used when you do not name the bus signal in the model is slBus1, and if you name the bus signal, the Simulink.Bus specification created using this function takes the same name.
You can save this Simulink.Bus specification to a file and load the specification into the base workspace using a model callback for the model that loads the bus. Whatever strategy you use, the model loading the bus data needs access to the corresponding Simulink.Bus object.
When you specify the Output data type for the From File block, use the name of the Simulink.Bus object, not the name of the variable containing the structure of bus data. In this case, you would enter Bus: slBus1.
If you look into the bus object created with the Simulink.Bus.createObject function, you'll see it contains Simulink.BusElement objects that specify properties for each bus element, including the name and data type.
I hope this helps!

MM
MM il 2 Lug 2019
Modificato: MM il 2 Lug 2019
Hi Sara,
Thank you for the help. I tried to do (or understand) what you said, but I can't get it to work. Can you make an example for me so I can see what you mean?
I do also have R2019a but prefferably in R2018b (or lower) because of compatibility reasons with colleges.

Sara Nadeau
Sara Nadeau il 2 Lug 2019
Hi Mark,
No problem - I've attached a modified version of your example model that loads bus data showing how to create the Simulink.Bus object and use it to define the data type for the From File block. I added code and explanations of the necessary steps in the PreLoadFcn model callback. To get to the model callbacks, click the Model Explorer button (just to the right of the Model Configuration Paramters (gear) button). In the right-most section of the Model Explorer, click the Callbacks tab, and then you should see where I added the PreLoadFcn callback. When you load the model, it executes the code here.
I explained two different strategies for creating the Simulink.Bus object, depending on whether you're OK loading the structure of logged bus data into the workspace. The strategy that does not load data into the workspace requires you to run a line of code in the Command Window before opening the model and causing it to execute the callback. The code for that method is commented out, so the 'active' strategy in the callback loads the data from the file into the workspace and creates the Simulink.Bus object based on the structure of logged bus data. I built this example assuming that you had already run the model that logs the bus data, so the mat-file already exists on the path.
If you're OK loading data into the workspace, you can also use a root-level Inport block to load the bus data. I added one to the model as an example, in case it would be helpful for you.
I think this topic might help explain the concept of Simulink.Bus objects a bit more, though it does not specifically mention the use case we're working with, which is loading bus data as an external input. Basically, the Simulink.Bus object describes the 'shape' of the data, and the structure provides the data itself.
I hope this helps. Please let me know if you have any issues or if something does not work for you.

MM
MM il 2 Lug 2019
Hi Sara,
Thank you for the file. I've seen the Callbacks code and left it like you uploaded it. I've run test_bus_save.slx first so test_bus_input.mat is created. But when I open the file (test_bus_load_with_busobj) I get this error:
Model Load 1 Clear
04:30 PM Elapsed: 0.518 sec
Error evaluating 'PreLoadFcn' callback of block_diagram 'test_bus_load_with_busobj'.
Callback string is '% If you do not want to load the bus data into the base workspace, you can create a bus based
% on the model that logs the data and the block that creates the bus at its output. Use the
% syntax that saves a file. The file defines a function with the same name as the Simulink.Bus
% object that you can call in the model callback to define the Simulink.Bus object in the base
% workspace so you can use it to define the data type for ports in your model
% Run this command once in the Command Window to create the function file:
% busInfo = Simulink.Bus.createObject('test_bus_save','test_bus_save/Bus Creator','slBus1.m');
% Be sure that the file is saved on the path. Then, this is all you need in your model callback:
% slBus1
% If you are OK with loading the logged bus data into the base workspace, you can use the
% model callback to load the file containing the data (if you choose to store it in a file) and
% create a Simulink.Bus object from the structure of logged bus data. When you load data into
% your model from the workspace, you can use other blocks, including Inport blocks, to load
% the data into your model, not just a From File block.
% Contents of the callback for this strategy:
load('test_bus_input.mat');
busInfo = Simulink.Bus.createObject('abc');'
Caused by:
Invalid number of inputs.
(deleting the commented out part doesn't help) All files (test_bus_save.slx, test_bus_input.mat and test_bus_load_with_busobj.slx) are in the same (current) folder.
And when I run your test_bus_load_with_busobj.slx (ctrl+T) I get this error:
Invalid setting in 'test_bus_load_with_busobj/In1' for parameter 'OutDataTypeStr'.
Caused by:
Error evaluating parameter 'OutDataTypeStr' in 'test_bus_load_with_busobj/In1'
Cannot resolve variable 'slBus1'
Variable 'slBus1' does not exist.
Suggested Actions
Load a file into base workspace. Fix
Create a new variable. Fix
Component:Simulink | Category:Model error
Invalid setting in 'test_bus_load_with_busobj/From File' for parameter 'OutDataTypeStr'.
Caused by:
Error evaluating parameter 'OutDataTypeStr' in 'test_bus_load_with_busobj/From File'
Cannot resolve variable 'slBus1'
Variable 'slBus1' does not exist.
Suggested Actions
Load a file into base workspace. Fix
Create a new variable. Fix
Component:Simulink | Category:Model error
I tried R2018b and R2019a and didn't change anything in the files. I guess I'm still doing something wrong?
And when I clear the Calbacks and first run
busInfo = Simulink.Bus.createObject('test_bus_save','test_bus_save/Bus Creator','slBus1.m')
Then I get this:
Warning: Cannot use signal name (or propagated label) '' for the bus object name of block 'test_bus_save/Bus
Creator' because either the name/label is not a valid MATLAB name, or a variable already exists with that name. Using default identifier 'slBus1'
instead.
busInfo =
struct with fields:
block: 4.0004
busName: 'slBus1'
And both test_bus_save and Bus Creator are the right names. And when I run test_bus_load_with_busobj I get this error:
Error evaluating expression 'abc' for 'ExternalInput' specified in the Configuration Parameters dialog for block diagram 'test_bus_load_with_busobj'.
Caused by:
Undefined function or variable 'abc'.
Component:Simulink | Category:Model error
Error evaluating external inputs specified in the Configuration Parameters dialog on the Data Import/Export Page. External inputs may be specified as either (a) a list of matrices, structures or timeseries or (b) a single MATLAB expression or function
Component:Simulink | Category:Model error
So I'm not sure what I'm doing wrong.
  1 Commento
Sara Nadeau
Sara Nadeau il 2 Lug 2019
Hi Mark,
To start off, I forgot to mention that I have been using R2018b to work on a solution for you. You won't need to use 19a.
I'm sorry I've made this situation more confusing with a typo in the callback and trying to illustrate multiple use cases at once. I'll walk through each behavior you described, in the order that you mentioned them.
1) This is my fault. When I first tested each method, I forgot to save the model. I went back to retrace my steps and I wrote the line calling Simulink.Bus.createObject incorrectly. In the file I sent you, I pass the name of the struct as a character array, when the function expects the struct itself. To make this work, remove the quotes ('') around abc.
2) This error occurs because the line in the callback to create the Simulink.Bus object didn't complete, so the bus object is not defined in the workspace. This error is more fallout from my typo.
switching to second strategy
3. This warning is OK - I believe I mentioned something about this in the earlier comment. If you want this warning to go away, you can name the bus signal in the test_bus_save.slx model. Then, the created bus object will have the same name as the bus signal instead of slBus1, the default.
After running that line, you should have been able to run the test_bus_load_with_busobj.slx model without error because the line of code that you ran in the base workspace created the bus object. However, you hit this error:
4. The root-level Inport that I added to try to illustrate options that you have depending on your requirements depended on the mat-file being loaded in the workspace, and I think I neglected to note that.
To go back to basics and work with your original implementation, I've attached an update of the test_bus_load_with_busobj.slx file with a fix in the callback (no quotes on abc), the Inport block removed, and nothing specified for the Input parameter. Here is the workflow for seeing this bus loading in action:
  1. Run the test_bus_save model.
  2. Open the attached model, test_bus_load_with_busobj_rev01.slx.
  3. Simulate the attached model.

Accedi per commentare.


MM
MM il 4 Lug 2019
Thank you it works!
However I do have a new problems. When I try do use this method in my real model, I'll get an error "Reference to non-existent field 'time' "
Probably because I use look-up tables (1-D) connected to a Clock instead of the 3 signals (pulse, sine and sine) I used in my example. Is it possible to extract this time field out of the bus as well?
  1 Commento
Sara Nadeau
Sara Nadeau il 5 Lug 2019
Hi, Mark.
I'm glad you got it to work, mostly!
I'm not sure whether I can answer your question about the time field, without knowing more information about how you're saving and using the data. Is the relevant time field in the logged bus data?
If you're trying to access the time vector for the signals in the bus, you should be able to do that. The bus data gets logged as a structure, where each leaf element in the bus is a timeseries object. Each timeseries object has a Time field that you can access that contains the time data. Accessing this data could look like:
timeData = busStruct.busSignal1.Time;
where 'busStruct' is the name of the structure of logged data, 'busSignal1' is a leaf element at the top-level of the bus hierarchy, and 'Time' is used to access the Time property of the timeseries object representing the data for 'busSignal1'.
I'm not sure there's a way to access and use the time information in the model during simulation. I've attached a modified model that accesses time information from the bus data logged from test_bus_save.slx and uses it to create a timeseries object where the time and data values are both defined by the time data - this is a little bit weird, but you cannot load input data that doesn't have pairings of time and sample values.
I added a couple lines of code to the model PreLoadFcn callback to define the timeseries variable, which I've teen specified as external input data using the Input parameter on the Data Import/Export pane of the Model Configuration Parameters.
In the model, I added an Inport block that loads that timeseries specified in the Input parameter. The model works, and you have access to the time data from the logged bus data, but I'm not sure whether this is the best method.
I work on external input loading and data logging for Simulink. I am not as familiar with lookup tables. If you can't track down what in the model is trying to access a field called 'time,' and how to properly define that data, you may want to make a separate post seeking guidance to solve this issue.

Accedi per commentare.

Prodotti


Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by