Bus signal: save and load
20 次查看(过去 30 天)
显示 更早的评论
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)
0 个评论
回答(7 个)
Sara Nadeau
2019-6-27
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.
0 个评论
Sara Nadeau
2019-6-28
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!
0 个评论
Sara Nadeau
2019-7-2
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.
0 个评论
MM
2019-7-2
1 个评论
Sara Nadeau
2019-7-2
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:
- Run the test_bus_save model.
- Open the attached model, test_bus_load_with_busobj_rev01.slx.
- Simulate the attached model.
MM
2019-7-4
1 个评论
Sara Nadeau
2019-7-5
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Composite Interfaces 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!