I have a .m file where I do some actions with Simulink model, and I would like to check if the currently used model is the entire model or a subsystem. Is there a specific syntax or function to check this? I need to be able to perform actions differently depending on Simulink system.
You can always use bdroot to get the name of the top level system and use string comparison to see if you have a subsystem or not:
sysname = 'f14/Actuator Model';
istoplevel = strcmp(bdroot(sysname), sysname);
isEntireModel = isequal( get_param( gcs, 'Type' ), 'block_diagram' );
Can you try this, after opening your model, or replace gcs with system name [make sure load it before using either with load_system or open_system]:
h=find_system(gcs,'FindAll',1,'SearchDepth',1,'BlockType','SubSystem');
if isempty(h)
disp('Has Subsystems');
else
disp('No Subsystems');
end
h=find_system(gcs,'FindAll',1,'SearchDepth',1,'BlockType','ModelReference');
if isempty(h)
disp('Has Models');
else
disp('No Models');
end
easier way would be, say your model name is vdp, then:
bdIsLoaded('vdp')
Related
I have used the following code pattern to access my *.accdb files:
accdb_path='C:\path\to\accdb\file\wbe3.accdb';
accdb_url= [ 'jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='''';DBQ=' accdb_path ];
conn = database('','','','sun.jdbc.odbc.JdbcOdbcDriver',accdb_url);
If instead I want to create a new *.accdb file, how would I do that? There is much on the web about how to connect, but I haven't found how to create the *.accdb file itself.
In case it matters, I want to be able to execute SQL 92 syntax. I am using Matlab 2015b. I do not want to use the Matlab GUI for exploring databases.
Actually, what you are attempting to do can be very tricky to achieve. It may require a direct interface to Access through an ActiveX control and I'm not even sure it can be done. It seems that the web is lacking a solid information pool concerning Access interoperability.
One quick workaround I can suggest you, althrough miserable, is to manually create an empty ACCDB file that you can use as template and then duplicate it whenever a new database must be created:
conn = CreateDB('C:\PathB\wbe3.accdb');
function accdb_conn = CreateDB(accdb_path)
status = copyfile('C:\PathA\template.accdb',accdb_path,'f');
if (status)
accdb_url = ['jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ=' accdb_path];
accdb_conn = database('','','','sun.jdbc.odbc.JdbcOdbcDriver',accdb_url);
else
accdb_conn = [];
error(['Could not duplicate the ACCDB template to the directory "' accdb_path '".']);
end
end
The following example is based on Tommaso's answer, which provides code for copying an empty *.accdb file and connecting to the copy. Based on an afternoon of trial, error, perusing of the web/help, I've expanded on that to create a database table and export a Matlab table to it. I've also embedded comments showing where modifications are needed, presumably due to my older 2015b version of Matlab, error catching constructs, and caveats in the file copy.
srcPath = [pwd '/emptyFile.accdb']; % Source
tgtPath = [pwd '/new.accdb']; % Target
cpyStatOk = copyfile( srcPath, tgtPath );
% No warning B4 clobber target file
if cpyStatOk
accdb_url= [ ...
'jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='''';DBQ=' ...
tgtPath ];
conn = database('','','','sun.jdbc.odbc.JdbcOdbcDriver',accdb_url);
else
error('Couldn''t copy %s to %s',srcPath,tgtPath);
end % if cpyStatOk
try
% conn.Execute(['CREATE TABLE tstMLtbl2accdb ' ... Not for 2015b
curs = conn.exec(['CREATE TABLE tstMLtbl2accdb ' ...
'( NumCol INTEGER, StrCol VARCHAR(255) );']);
if ~isempty( curs.Message )
% fprintf(2,'%s: %s\n',mfilename,curs.Message);
error('%s: %s\n',mfilename,curs.Message);
% Trigger `catch` & close(conn)
end %if
% sqlwrite( conn, 'tstMLtbl2accdb', ...Not supported in 2015b
datainsert( conn, 'tstMLtbl2accdb', {'NumCol','StrCol'}, ...
table( floor(10*rand(5,1)), {'abba';'cadabra';'dog';'cat';'mouse'}, ...
'VariableNames',{'NumCol','StrCol'} ) );
catch xcptn
close(conn)
fprintf(2,'Done `catch xcptn`\n');
rethrow(xcptn);
end % try
%
% Other database manipulations here
%
close(conn)
disp(['Done ' mfilename]);
This has been immensely educational for myself, and I hope it is useful for others considering the use of SQL as an alternative to the more code-heavy Matlab counterpart to relational database manipulations. With this amount of overhead, I'd have to say that it is not attractive to perform SQL manipulations on data residing in the Matlab workspace except where one really needs the hyperoptimization of relational database query engines.
To those savvy with interfacing to Access, your comment on the purpose of the field names argument of the datainsert function would be appreciated. It is dubbed colnames in the documentation. From testing, the field names and number of columns must match between the existing target table in Access and the source table in Matlab. So the field names argument doesn't seem to serve any purpose. The help documentation isn't all that helpful.
AFTERNOTE: I've composed a "specification" for the colnams argument based on examples from TMW. TMW has confirmed this explanation:
The colnames argument tells the external database environment the names and order of fields of the data container supplied via the data argument. These field names are used to match the fields of the transferred data with fields in the table tablename residing within the external database environment. Because of this explicit name matching, the order of the fields in data do not have to match the order of the fields in tablename.
If I find any departures of empirical behaviour from the above "specification", I will update this answer.
I'm working on automated model building. In some cases I have do convert a bus into another bus (the structure is the same, but there can be variants in the names). It works for a static model where I can change the datatype of the inputs and outputs, but I didn't find any way to do this from the command line or directly in an embedded MATLAB function.
Does anybody know a way to do this?
mfb = find(sfroot, '-isa', 'Stateflow.EMChart', 'Name', 'test');
out = get(mfb, 'Outputs');
out.set('DataType', ['Bus: ' component_source.test]);
Does Matlab have a kind of with...end command? http://msdn.microsoft.com/en-us/library/wc500chb(v=vs.80).aspx
I have a variable in my workspace which contains a lot of nested data. Now I don't want to have to type this all the time:
Root.ChildLevel1.A = Root.ChildLevel1.B + Root.ChildLevel1.C
But rather something like:
with Root.ChildLevel1
A = B + C
end
is this possible?
I'm not aware of such functionality in Matlab.
What you can do is
cur = Root.ChildLevel1;
cur.A = cur.B + cur.C;
Edit:
According to comment by #Nick, if Root.ChildLevel1 is not subclass of handle,
then one should add the following line:
Root.ChildLevel1 = cur;
I would also recommend to
clear cur;
at the end.
I have to say that I would not recommend using this function very often, but I once tried a FEX contribution that allows you to unpack structs.
Of course this will still require you to update the struct after you have done the calculations so I only use it for subfunctions that mainly use the struct as input.
I am not sure, but I think this is the one I tried:
http://www.mathworks.com/matlabcentral/fileexchange/26216-structure-fields-to-variables
I am getting an error when running matlab code. Here I am trying to use one of the outputs of previous code as input to my new code.
??? Reference to non-existent field 'y1'.
Can anyone help me?
A good practice might be to check if the field exists before accessing it:
if isfield( s, 'y1' )
% s.y1 exists - you may access it
s.y1
else
% s.y1 does not exist - what are you going to do about it?
end
To take Edric's comment into account, another possible way is
try
% access y1
s.y1
catch em
% verify that the error indeed stems from non-existant field
if strcmp(em.identifier, 'MATLAB:nonExistentField')
fprintf(1, 'field y1 does not exist...\n');
else
throw( em ); % different error - handle by caller?
end
end
Have you used the command load to load data from file(s)?
if yes, this function overwrite your current variables, therefore, they become non-existent, so when you call, it instead of using:
load ('filename');
use:
f=load ('filename');
now, to refer to any variable inside the loaded file use f.varname, for
example if there is a network called net saved within the loaded data you may use it like:
a = f.net(fv);
I would first explain my situation and then give the solution.
I first save a variable op, it is a struct , its name is coef.mat;
I load this variable using coef = load( file_path, '-mat');
In a new function, I pass variable coef to it as a parameter, at here, the error Reference to non-existent field pops out.
My solution:
Just replace coef with coef.op, then pass it to the function, it will work.
So, I think the reason behind is that: the struct was saved as a variable, when you use load and want to acess the origin variable, you need point it out directly using dot(.) operation, you can directly open the variable in Matlab workspace and find out what it wraps inside the variable.
In your case, if your the outputs of previous code is a struct(It's my guess, but you haven't pointed out) and you saved it as MyStruct, you load it as MyInput = load(MyStruct), then when use it as function's parameter, it should be MyInput.y1.
Hops it would work!
At first load it on command window and observe the workspace window. You can see the structure name. It will work by accessing structure name. Example:
lm=load('data.mat');
disp(lm.SAMPLE.X);
Here SAMPLE is the structure name and X is a member of the structure
So, I figured out how to call one gui from another and send back and forth information via varargin and varargout. However, right now I'm in a situation where I have two separate guis (one is not called from the other), and I believe I need some other method if I want to communicate between them.
More exactly, I'm making two GUIs that interact with Simulink. One GUI opens when the model is opened and keeps track of information. The other GUI will open when a block is double-clicked. I want to send information from this GUI to the information-tracking GUI.
So, from what I've searched, I can accomplish this either by using a Listener in the information-tracking GUI; or I can modify the variables in the information-tracking GUI directly using setappdata/getappdata or findall(0, ...).
So far my attemps haven't worked and I was wondering if I'm taking the write approach. Can someone point me in a direction? Let me know if I can provide more info!
I use the setappdata/getappdata method all the time for this sort of thing. Here is a general breakdown of what you do. When you create the figures give them a tag like this:
figure( ..., 'Tag', 'info_gui', ... ); % tag name is up to you
figure( ..., 'Tag', 'other_gui', ... ); % tag name is up to you
Anytime you need the handle to one or the other figures just make a call to findobj like this
info_gui_handle = findobj('tag','info_gui');
other_gui_handle = findobj('tag','other_gui');
Ok now lets store some example data in the info_gui that we will update later
info_gui_data.x = 1;
info_gui_data.y = 1;
setappdata( info_gui_handle, 'info_gui_data', info_gui_data);
Once you have your figures set up you can do things like this:
% First you get a handle to the info gui figure
info_gui_handle = findobj('tag','info_gui');
% Next you get the appdata thats stored in this figure. In this example
% I have previously stored a struct variable called
% 'info_gui_data' inside the appdata of the info_gui
info_gui_data = getappdata(info_gui_handle ,'info_gui_data');
% Make your changes whatever they are. Here I am modifying variables x
% and y that are stored in the struct info_gui_data
info_gui_data.x = 2;
info_gui_data.y = 2;
% Now that I've made changes to the local variable info_gui_data I can
% now store it back into the info gui's appdata.
setappdata(info_gui_handle ,'info_gui_data',info_gui_data);
I like to store all of my figure appdata in one giant struct. Seems easier to keep track of but its up to you. Hope this helps :)
You could also try using guidata and guihandles.
Suppose the handle to GUI1 is H1. In GUI1, when you want to store data that you can retrieve later, use:
guidata(H1,data)
In GUI2, when you need the data, use:
data = guidata(H1);
Alternatively, you could store your data in the Property 'User Data' of your uicontrol object. Make sure you set the Property 'Tag' to something valid (e.g. 'mybutton'). To access this from GUI2, use:
handles = guihandles(H1);
data = get(handles.mybutton,'UserData');