How can I set a global variable in public properties App Designer that depends on another one?

476 views (last 30 days)
Alessandro Frongia
Alessandro Frongia on 27 Mar 2018
Answered: Steven Lord on 9 Dec 2020
Dear all,
I have a problem on understanding how properly set a global variable in App Designer.
Indeed, I am using App Designer that at the button pressing will run a waving sinusoid in the UIaxes. Since this sinusoid will be called in another function I want that its parameters are usable and visible also in other functions.
I saw in other guides that to do this the variable can be set in the Public properties. However if I write:
properties (Access = public)
Fs = 60; % samples per second
dt = 1/Fs; % seconds per sample
StopTime = 60; % seconds
t = (0:dt:StopTime-dt)'; % seconds
Fc = 0.47;
x = 300*sin(2*pi*Fc*(t))+((app.BWEditField.Value+20)*9.81); % Starting wave
end
As you can see, I would keep global and visible all the parameters that allows to build a sinusoid. However, when I run, it gives an error on dt because it says that it doesn't find Fs. It seems like that it does not run in line the code...
Simplyfing. The question is: How can I declare globally in the properties the variables X and Y, with Y that is defined using X?

Answers (2)

Eric Sargent
Eric Sargent on 23 Apr 2018
Edited: Eric Sargent on 9 Dec 2020
You need to define them as public properties and set the static values. You need to declare ALL of the variables you want/need to use in subsequent functions within the app.
[update]
Note, in the comments below, "app.tend" is used in StartupFcn but "tend" is not defined in properties)
properties (Access = public)
Fs = 60; % samples per second
StopTime = 60; % seconds
Fc = 0.47;
dt;
t;
x;
end
Then initialize the dependent variables in a startupFcn callback and refer to each of the variables as "app.<variablename>", such as:
function startupFcn(app)
app.dt = 1/app.Fs; % seconds per sample
app.t = (0:app.dt:app.StopTime-app.dt)'; % seconds
app.x = 300*sin(2*pi*app.Fc*(app.t))+((app.BWEditField.Value+20)*9.81); % Starting wave
end
Use the same dot notation in your subsequent code to access those variables.
plot(app.UIAxes,app.t,app.x)
  2 Comments
Alessandro Frongia
Alessandro Frongia on 30 Apr 2018
Just in case, here below is my current code. Briefly, I will explain what it has to do. The DropDown menu creates for each option a small random loop that merges repeated chirp signals (ystep, with t as time vector) in a final one (y, with tend as time vector). The loop includes just a way to create randomly the type of chirp. After that the other parameters are just a Edit field to insert a parameter who will change the offset of the signal and a slider who will increase the same offset by a percentage of the Edit field value. The rest is just 2 buttons, one to start and one to stop the plot of this signal, who has a rolling animation from right to left in the UI figure... Therefore, time vectors and the parameters to build the signal must be available for the various functions...
Here below the code:
classdef SailingTrainer < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
UIAxes matlab.ui.control.UIAxes
RunButton matlab.ui.control.Button
StopButton matlab.ui.control.Button
BWEditFieldLabel matlab.ui.control.Label
BWEditField matlab.ui.control.NumericEditField
ScenarioDropDownLabel matlab.ui.control.Label
ScenarioDropDown matlab.ui.control.DropDown
TrainingLevelLabel matlab.ui.control.Label
TrainingLevelSlider matlab.ui.control.Slider
end
properties (Access = public)
Fs = 60; % sample frequency
tpuls = 5; % length of chirp
StopTime = 60;
a = udp('','LocalHost','','LocalPort',5000); % Description
y;
end
methods (Access = public)
function startupFcn(app)
app.dt = 1/app.Fs; % seconds per sample
app.t = (0:app.dt:app.tpuls)'; % seconds
app.tend = (0:app.dt:app.StopTime)'; % seconds
% app.t = 0:0.0167:5;
% app.tend = 0:0.0167:60;
app.endvector = app.StopTime/app.tpuls;
end
end
methods (Access = private)
% Value changed function: ScenarioDropDown
function ScenarioDropDownValueChanged(app, event)
scenario = app.ScenarioDropDown.Value;
switch scenario
case 'Calm'
f0 = 0.4;
f1 = 0.7;
app.y = chirp(app.t, f0, app.t(end), f1,'linear');
sizechirp_vec=size(app.y);
sizechirp=sizechirp_vec(1,2);
for i = 1:(endvector-1)
mod = randi(3,1);
switch mod
case 1
type = 'linear';
case 2
type = 'logarithmic';
case 3
type = 'quadratic';
end
ystep= chirp(app.t, f0, app.t(end), f1,type);
app.y=[app.y,ystep(1:(sizechirp-1))];
end
app.y(app.y<0) = 0;
app.y = (20)*sign(app.y)+(app.BWEditField.Value+30);
case 'Choppy'
f0 = 0.5;
f1 = 0.9;
app.y = chirp(app.t, f0, app.t(end), f1,'linear');
sizechirp_vec=size(app.y);
sizechirp=sizechirp_vec(1,2);
for i = 1:(endvector-1)
mod = randi(3,1);
switch mod
case 1
type = 'linear';
case 2
type = 'logarithmic';
case 3
type = 'quadratic';
end
ystep= chirp(app.t, f0, app.t(end), f1,type);
app.y=[app.y,ystep(1:(sizechirp-1))];
end
app.y(app.y<0) = 0;
app.y = (30)*sign(app.y)+(app.BWEditField.Value+30);
case 'Open water'
f0 = 0.6;
f1 = 0.8;
app.y = chirp(app.t, f0, app.t(end), f1,'linear');
sizechirp_vec=size(app.y);
sizechirp=sizechirp_vec(1,2);
for i = 1:(endvector-1)
mod = randi(3,1);
switch mod
case 1
type = 'linear';
case 2
type = 'logarithmic';
case 3
type = 'quadratic';
end
ystep= chirp(app.t, f0, app.t(end), f1,type);
app.y=[app.y,ystep(1:(sizechirp-1))];
end
app.y(app.y<0) = 0;
app.y = (40)*sign(app.y)+(app.BWEditField.Value+30);
end
end
% Button pushed function: RunButton
function RunButtonPushed(app, event)
n=0; %initialization
i=1;
% 1 n = 3 seconds (???)
endcycle=30;
while (n<endcycle) %n decides the length of the recording (keep on mind that in the future it must be coherent with a start-stop system
fopen(app.a);
u.DatagramTerminateMode = 'off';
data = fscanf(app.a);
fclose(app.a);
results = str2num(data); % it takes the ASCII string from the bench and it puts the values in an array
results_array (i,:) = results; % it splits the data from the 4 sensors
%results_Newton = results_array*9.81; % conversion from Kg to N
Fsbv = results_array(:,1); % These are the 4 separated forces from each sensor
Fbbv = results_array(:,2);
Fbba = results_array(:,3);
Fsba = results_array(:,4);
Ftot = Fsbv+Fbbv+Fbba+Fsba; % Total force
plot(app.UIAxes,app.tend,app.y,'r',0,Ftot(i),':bo',...
'LineWidth',1,...
'MarkerSize',8,...
'MarkerEdgeColor',[0,0,0.5],...
'MarkerFaceColor',[1,0.6,0])
xlim(app.UIAxes,[-2 2])
ylim(app.UIAxes,[30 200])
i=i+1;
n=n+1;
% Delaying animation
app.t=app.t-10*app.dt;
drawnow limitrate
end
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 1184 798];
app.UIFigure.Name = 'UI Figure';
setAutoResize(app, app.UIFigure, true)
% Create UIAxes
app.UIAxes = uiaxes(app.UIFigure);
app.UIAxes.Box = 'on';
app.UIAxes.Position = [78 87 1091 536];
% Create RunButton
app.RunButton = uibutton(app.UIFigure, 'push');
app.RunButton.ButtonPushedFcn = createCallbackFcn(app, @RunButtonPushed, true);
app.RunButton.BackgroundColor = [0.1059 0.8196 0.1059];
app.RunButton.FontName = 'Tahoma';
app.RunButton.FontSize = 24;
app.RunButton.FontWeight = 'bold';
app.RunButton.FontColor = [1 1 1];
app.RunButton.Position = [12 686 165 36];
app.RunButton.Text = 'Run';
% Create StopButton
app.StopButton = uibutton(app.UIFigure, 'push');
app.StopButton.BackgroundColor = [0.8196 0.1059 0.1059];
app.StopButton.FontName = 'Tahoma';
app.StopButton.FontSize = 24;
app.StopButton.FontWeight = 'bold';
app.StopButton.FontColor = [1 1 1];
app.StopButton.Position = [12 632 165 39];
app.StopButton.Text = 'Stop';
% Create BWEditFieldLabel
app.BWEditFieldLabel = uilabel(app.UIFigure);
app.BWEditFieldLabel.HorizontalAlignment = 'right';
app.BWEditFieldLabel.Position = [124 14 25 15];
app.BWEditFieldLabel.Text = 'BW';
% Create BWEditField
app.BWEditField = uieditfield(app.UIFigure, 'numeric');
app.BWEditField.Limits = [0 Inf];
app.BWEditField.ValueDisplayFormat = '%11.3g';
app.BWEditField.HorizontalAlignment = 'center';
app.BWEditField.Position = [164 10 65 22];
app.BWEditField.Value = 80;
% Create ScenarioDropDownLabel
app.ScenarioDropDownLabel = uilabel(app.UIFigure);
app.ScenarioDropDownLabel.HorizontalAlignment = 'right';
app.ScenarioDropDownLabel.Position = [992 18 54 15];
app.ScenarioDropDownLabel.Text = 'Scenario';
% Create ScenarioDropDown
app.ScenarioDropDown = uidropdown(app.UIFigure);
app.ScenarioDropDown.Items = {'Calm', 'Choppy', 'Open water'};
app.ScenarioDropDown.ValueChangedFcn = createCallbackFcn(app, @ScenarioDropDownValueChanged, true);
app.ScenarioDropDown.Position = [1061 14 100 22];
app.ScenarioDropDown.Value = 'Calm';
% Create TrainingLevelLabel
app.TrainingLevelLabel = uilabel(app.UIFigure);
app.TrainingLevelLabel.HorizontalAlignment = 'right';
app.TrainingLevelLabel.Position = [12 10 67 28];
app.TrainingLevelLabel.Text = {'+/- Training'; 'Level (%)'};
% Create TrainingLevelSlider
app.TrainingLevelSlider = uislider(app.UIFigure);
app.TrainingLevelSlider.Limits = [0 20];
app.TrainingLevelSlider.MajorTicks = [0 5 10 15 20];
app.TrainingLevelSlider.Orientation = 'vertical';
app.TrainingLevelSlider.Position = [17 63 3 178];
end
end
methods (Access = public)
% Construct app
function app = SailingTrainer()
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end

Sign in to comment.


Steven Lord
Steven Lord on 9 Dec 2020
When defining properties' default values, you can only use the values of other properties if those properties are Constant. To access them you need to use the name of the class, which for purposes of this answer I'll call myappclass.
properties (Access = public, Constant)
Fs = 60; % samples per second
dt = 1/myappclass.Fs; % seconds per sample
StopTime = 60; % seconds
t = (0:myappclass.dt:myappclass.StopTime-myappclass.dt)'; % seconds
Fc = 0.47;
Those properties can be given values in the definition as they don't depend on the state of a particular instance of the class. The last property you tried to define cannot be given a default value in the properties block as it depends on the state of a particular instance of the class. You can define this property but you can't give it a value here. You could set its value in the constructor or in a regular method.
x = 300*sin(2*pi*Fc*(t))+((app.BWEditField.Value+20)*9.81); % Starting wave
end

Community Treasure Hunt

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

Start Hunting!