I save the data from my simulation with the to file block to a .mat file.
When I start a new simulation, Simulink will overwrite the file if I dont set a new filename in the blocks properties.
Is it possible to add automaticly the current date / time to the filename? For the later usecase, i would be to extensive to set a filename for every new simulation manually.
thank you!
You can create a callback that will be called whenever a simulation is started and update the filename pointed by the ToFile block
In your callback function (my_callback.m) :
block = find_system(bdroot,'Name','NameOfTheToFileBlock');
if ~isempty(block)
file_name = strcat('filename_', datestr(now, 'yyyy-mm-dd HH:MM:SS'), '.mat');
set_param(block{1}, 'Filename', file_name);
end
You can setup the callback programmatically that way :
set_param('your_model','StartFcn','my_callback');
Related
I have a model in which I am using a CombiTable1D to retrieve an external input from a .txt file. The file is generated by a Python script at the moment but in the final phase of the project, it is going to be updated each second. For now, simulation takes place without a problem as the .txt file is static. Just read the file and make simulation according to the data written there.
What I want to do is to simulate a model until a certain time, let's say 100s, and then make it wait until a real time event by which the .txt file is updated for the next external input values between 100-200. The simulation should continue by getting these new values for the next 100 seconds.
As I have already been working with OMPython, it is really practical for me to edit the .txt file using Python, let's say for each 10 seconds in real time. I can now simulate the model until the time instance that I define as the refreshing point of the external input. But I couldn't figure out how to keep the state of the simulation and make it read the file once again.
Actually, this sounds like a co-simulation scenario to me. Anyway, what you could do is to extend from CombiTable1D and have something like
block CombiTable1DWithUpdate
extends Modelica.Blocks.Tables.CombiTable1D(final tableOnFile=true);
algorithm
when sample(0, 10) then
readTableData(tableID, /* force update */ true, verboseRead);
end when;
end CombiTable1DWithUpdate;
In addition the the answer I accepted, I want to give another solution which is not so efficient. For a simple model with a capacitor and resistor, I made successfull tests but with more complex models, it doesn't function properly. In a Modelica script, realTimeSimulation.mos:
outputFile := "stepResult.mat";
simulation_step := 1;
start_time := 0;
stop_time := start_time+simulation_step;
loadFile("WhereverTheFileIs.mo");
buildModel(myTestModel);
system("myTestModel-override=startTime="+String(start_time)+",stopTime="+String(stop_time)+" -r="+outputFile);
will build the model and simulate the first step until the simulation time t=1s. Later on, using Python the text file is updated. The new data for the time between t=1s and t=2s are written to the text file where I am getting the input of the model. Then another step of the simulation is made for the time between t=1s and t=2s. As a loop, it continues like forever like: actualize the data, make new simulation for the new time interval. The trick is, reading the output file created at the end of each step and giving all the variable values as the new initial conditions to the simulation, using following script:
valueList := readSimulationResultVars(outputFile);
start_time := start_time+simulation_step;
stop_time := stop_time+simulation_step;
value := val(OpenModelica.Scripting.stringVariableName(valueList[1]),start_time,outputFile);',
variableString := valueList[1] + "=" + String(value);
for i in 2:size(valueList,1) loop
value := val(OpenModelica.Scripting.stringVariableName(valueList[i]),start_time,outputFile);
variableString := variableString + "," + valueList[i] + "=" + String(value);
end for;
system("myTestModel-override startTime="+String(start_time)+",stopTime="+String(stop_time)+",variableString+" -r="+outputFile);
I'm saving a 1x50 array in a variable in a netCDF file and this operation is done every ~10sec.
I would like also to save matlab'time datestr(now) (YYYY-MM-DDTHH:MM:SS).
How should I do ?
I tried to store the date (datestr(now)) in a time variable without success.
Kind regards,
To store a variable in your workspace to a .mat file, you can use this:
variable = 1; % Variable to store.
fileName = ['fileName - ', datestr(now, 'yyyy-mm-dd HH.MM.SS'), '.mat'];
save(fileName, '-mat', 'variable');
Note that a ':' in the date string will make the save() function throw an error.
I finaly succeed in store time in my netCDF file.
1. I defined a 'time' dimension
2. I defined a dimension for my 1x50 value
then I wrote my data
ncwrite(ncfilename, 'data',myData.',[1 i]);
ncwrite(ncfilename, 'time',myData_triggertime,i);
where myData (my 1x50 array), myData_triggertime (=datestr(now)) are updated at each acquisition loop and i incremented at each loop.
kind regards
I have being to share data between several callback options in Matlab, however no succes so far. I have a gui with multiple tables which I use to get the input from the user. I have multiple callback functions for the different tables. I would like to use the data from table 1 and callback 1 together with the date in table 2 in callback two.
function MaterialProperties(Material, Data)
Material_data = get(Material, 'Data');
% Avoid bluehighlight in table
set(Material,'Data',{'dummy'});
set(Material,'Data', Material_data);
% Store variable in workspace
assignin('base','Material_data',Material_data)
%Mat_data = guidata(gcbo);
%for i=1:size(Material_data,2)
% Mat_data.MatData{i}=Material_data{i};
%end
% Save the change you made to the structure
guidata(gcbo,Mat_data)
assignin('base','Mat_data',Mat_data)
end
function Stacking_sequence(Layup, Data)
% I want to use the date (Material_data) of MaterialProperties here in this callback
layup_data = get(Layup, 'Data');
%overwrite data with a dummy and restore the old data afterwards, to force deselection
set(Layup,'Data',{'dummy'});
set(Layup,'Data', layup_data );
%store variable in workspace
assignin('base','layup_data',layup_data)
layup = strsplit(layup_data{1,1},'\');
assignin('base','layup',layup)
end
Can anyone help. I tried theMatlab help, but the suggestions stated there didn't work (maybe I implemented it wrong)
It looks like you simply need to retrieve the handles structure at the beginning of callback 2, like you did in the first callback:
Mat_data = guidata(gcbo);
after which it should be available in the 2nd callback. By the way this very line and the 3 lines following it are commented in your code is that a mistake?
Alternative solution:
As an alternative solution, you can use setappdata/getappdata to share data between function callbacks as well as in the command window, depending on where you store those data.
For example, if you save Material_data at the end of the 1st callback using something like this:
setappdata(0,'MatData',Material_Data); % Save in the Matlab root 0 (accessible everywhere), and give some dummy name)
Then at the beginning of the 2nd callback, you can retrieve the data using getappdata:
Material_Data = getappdata(0,'MatData');
and you're good to go. Instead of using the 0 root, you could also store the data in the GUI itself, using for example handles.FigureGUI or whatever the name of the figure is. Then the data would be available only if the figure is not closed/deleted. Play around with those and see what you prefer.
Hope that helps!
I am trying to create a schedule task that reads in a excel file and saves the data. It's working, but when I try to save new data with the same variable name, it overwrites even when I use the '-append' function.
read_date = (datestr(busdate(today)-4,'mmddyyyy'));
cd('C:\Users\jdoe\Desktop\weathertemps');
csvdata = xlsread(strcat('temp_', num2str(read_date),'.XLS'));
htemp = [csvdata(1,5),csvdata(2,5),csvdata(3,5),csvdata(4,5)];
ltemp = [csvdata(7,5),csvdata(8,5),csvdata(9,5),csvdata(10,5)];
todaydata = [str2num(read_date),htemp,ltemp];
cd('C:\Users\jdoe\Desktop\weathertemps\Data');
save mydata.mat todaydata -append;
This saves a vector<1,9> called todaydata in a mat file called mydata.mat. How do I go back into that same vector and make it an array of <2,9> with next day's data?
Append is for adding new variables to the mat file. To do what you want to do, you must load the variable from the mat file, modify it, and save it back in, overwriting the variable in the mat file.
i'm trying to save values of iterations in a loop. After this function, they will execute other functions before coming to the next iteration. But the problem i'm facing is, it overwrites them and bcomes 000000. Only the last iteration values are seen. How can i fix it ? Is there a way not to use the same variable and save them ? i read about append but will have to use different var name n is not really nice to do so.
function DistanceMatrix(iteration,distance_row)
load('data.mat','oridata')
load('centroids.mat','centroids')
for i = distance_row:(distance_row+3)
for j=1:300 %no.genes
total=0;
for k=1:6
total=total+((oridata(j,k)- centroids(i,k))^2);
end
DistMatrix_Val(i,j)=sqrt(total);
end
end
save('DistanceMatrix.mat','DistMatrix_Val')
DistMatrix_Val;
GroupMatrix(iteration,distance_row)
end
This is the output. I WOULD LIKE TO STORE ALL ITERATION's value and not overwrite them. Can any1 help ?
OK. Use
load('DistanceMatrix.mat','DistMatrix_Val')
or
persistent DistMatrix_Val
just before the first load command you showed to us.
I think this is what you should do:
functon DistanceMatrix = DistanceMatrix(iteration,distance_row)
Rather than saving the variable at the end of the function, you return it.
After returning it you can include the variable in a bigger variable (for example a three dimensional Nx4x300 matrix)
If neccesary you can then save it at the end.