GUI handles reference to non-existent field 'timer'

2 ビュー (過去 30 日間)
4007william
4007william 2020 年 2 月 28 日
コメント済み: 4007william 2020 年 3 月 1 日
After initiating the code below the GUI appears, but if I try to press any of the buttons I get a Reference to non-existent field 'timer' error. I have changed the GUI visibility to on, and am still getting this error. See code and full error text below.
____________________________________________________
ERROR
_______________________________________________________________
Reference to non-existent field 'timer'.
Error in Boid_GUI>Start_Callback (line 91)
start(handles.timer)
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in Boid_GUI (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)Boid_GUI('Start_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback.
_________________________________________________________________________
CODE
____________________________________________________________
function varargout = Boid_GUI(varargin)
% BOID_GUI MATLAB code for Boid_GUI.fig
% BOID_GUI, by itself, creates a new BOID_GUI or raises the existing
% singleton*.
%
% H = BOID_GUI returns the handle to a new BOID_GUI or the handle to
% the existing singleton*.
%
% BOID_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in BOID_GUI.M with the given input arguments.
%
% BOID_GUI('Property','Value',...) creates a new BOID_GUI or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before Boid_GUI_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to Boid_GUI_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help Boid_GUI
% Last Modified by GUIDE v2.5 27-Feb-2020 23:38:53
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @Boid_GUI_OpeningFcn, ...
'gui_OutputFcn', @Boid_GUI_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before Boid_GUI is made visible.
function Boid_GUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to Boid_GUI (see VARARGIN)
% Choose default command line output for Boid_GUI
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes Boid_GUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
handles.N = 20; % define the number of boids
% initialize boids position and velocity
boid.pos = 5000.*rand(handles.N,2);
boid.vel = [150.*rand(handles.N,1) 10.*rand(handles.N,1)];
boid_plotter(boid,handles) % call the function to plot the boids in the GUI window
% create timer object
handles.timer = timer;
set(handles.timer,'TimerFcn',{@my_callback_fun,handles},'Period',.1)
set(handles.timer,'ExecutionMode','fixedRate','UserData',boid)
% --- Outputs from this function are returned to the command line.
function varargout = Boid_GUI_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on button press in Start.
function Start_Callback(hObject, eventdata, handles)
% hObject handle to Start (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
start(handles.timer)
% --- Executes on button press in Stop.
function Stop_Callback(hObject, eventdata, handles)
% hObject handle to Stop (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
stop(handles.timer)
% --- Executes on button press in Reset.
function Reset_Callback(hObject, eventdata, handles)
% hObject handle to Reset (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
stop(handles.timer)
% initialize boids position and velocity
boid.pos = 5000.*rand(handles.N,2);
boid.vel = [150.*rand(handles.N,1) zeros(handles.N,1)];
set(handles.timer,'UserData',boid)
% --- Executes on slider movement.
function slider3_Callback(hObject, eventdata, handles)
% hObject handle to slider3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
% --- Executes during object creation, after setting all properties.
function slider3_CreateFcn(hObject, eventdata, handles)
% hObject handle to slider3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
% --- Executes on slider movement.
function slider4_Callback(hObject, eventdata, handles)
% hObject handle to slider4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
% --- Executes during object creation, after setting all properties.
function slider4_CreateFcn(hObject, eventdata, handles)
% hObject handle to slider4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
% --- Executes on slider movement.
function slider5_Callback(hObject, eventdata, handles)
% hObject handle to slider5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
% --- Executes during object creation, after setting all properties.
function slider5_CreateFcn(hObject, eventdata, handles)
% hObject handle to slider5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
function my_callback_fun(obj,event,handles)
% get data
boid = get(obj,'UserData');
% move boids
[boid.pos,boid.vel] = move_all_boids(boid.pos,boid.vel,handles);
% plot boids
boid_plotter(boid,handles)
% update data
set(obj,'UserData',boid);
%-----------------------------------------------------------------------
function boid_plotter(boid,handles)
h = axis(handles.axes1);
plot(boid.pos(:,1),boid.pos(:,2),'o')
axis([0 5000 0 5000]);
set(gca,'XTick',[],'YTick',[])
hold on
for i=1:size(boid.vel,1)
plot([boid.pos(i,1) boid.pos(i,1)+boid.vel(i,1)],...
[boid.pos(i,2) boid.pos(i,2)+boid.vel(i,2)],'r')
end
hold off
function [pos,vel] = move_all_boids(pos,vel,handles)
h = findobj(gcf,'Style','slider');
behavior_strength = get(h,'Value');
% cycle through all boids
for i=1:size(pos,1)
% calculate behaviorial velocity maneuvers
separation = 1*behavior_strength{1}*avoid(pos,i,200);
allignment = 5*behavior_strength{2}*match_vel(vel,i);
cohesion = .5*behavior_strength{3}*center_of_mass(pos,i);
% update boid
vel(i,:) = vel(i,:) + separation + allignment + cohesion;
% keep velocity magnitude constant (150)
vel(i,:) = 150*(vel(i,:)/norm(vel(i,:)));
% update position and restrict the values within the plot axis (mod.m, % modulus function)
pos(i,:) = mod(pos(i,:) + vel(i,:),5000);
end
%---------------------------------------------------------------
function v1 = center_of_mass(pos,i)
% function to move each boid towards the precieved
% center of mass of the rest of the flock
% percieved center of mass
pc = (sum(pos,1) - pos(i,:))/(size(pos,1)-1);
% move the boid towards the center by 1%
v1 = 0.01*(pc - pos(i,:));
%---------------------------------------------------------------
function v2 = avoid(pos,i,dist)
% function to move each boid away from other boids
v2 = [0 0];
for k = 1:size(pos,1)
if k ~= i
if norm(pos(i,:) - pos(k,:)) < dist
v2 = (pos(i,:) - pos(k,:))-v2 ;
end
end
end
%---------------------------------------------------------------
function v3 = match_vel(vel,i)
% function to match each boids velocity with near birds
% note: same as rule one but with velocity rather than position
pv = (sum(vel,1) - vel(i,:))/(size(vel,1) - 1);
v3 = 0.01*(pv - vel(i,:));

採用された回答

Geoff Hayes
Geoff Hayes 2020 年 2 月 28 日
While your code in the Boid_GUI_OpeningFcn function is adding the timer to the handles structure, you are only modifying the "local" copy of it. If you want to save these changes to this structure, then you need to call guidata so that all other callbacks (from that point on) receive the updated version of handles. So in the Boid_GUI_OpeningFcn just do
% --- Executes just before Boid_GUI is made visible.
function Boid_GUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to Boid_GUI (see VARARGIN)
% Choose default command line output for Boid_GUI
handles.output = hObject;
% UIWAIT makes Boid_GUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
handles.N = 20; % define the number of boids
% initialize boids position and velocity
boid.pos = 5000.*rand(handles.N,2);
boid.vel = [150.*rand(handles.N,1) 10.*rand(handles.N,1)];
boid_plotter(boid,handles) % call the function to plot the boids in the GUI window
% create timer object
handles.timer = timer;
set(handles.timer,'TimerFcn',{@my_callback_fun,handles},'Period',.1)
set(handles.timer,'ExecutionMode','fixedRate','UserData',boid)
% Update handles structure
guidata(hObject, handles);
I just moved the line guidata(hObject, handles); to the end of the function. Note that whenever you make a change to handles you always need to call guidata in this manner.
  2 件のコメント
Geoff Hayes
Geoff Hayes 2020 年 2 月 28 日
Also, be careful with this line of code
set(handles.timer,'TimerFcn',{@my_callback_fun,handles},'Period',.1)
You are passing a copy of handles structure as it is now as an input parameter to the callback. If this structure changes over time (by other callback, etc.) then this input to the timer callback will not. Typically, if I want my timer callback to have access to the handles structure, I pass in the handle to the GUI figure and then request the handles structure from within the callback. For example,
set(handles.timer,'TimerFcn',{@my_callback_fun,handles.figure1},'Period',.1)
and then in the callback
function my_callback_fun(obj,event,hFigure)
% get the handles structure
handles = guidata(hFigure);
% get data
boid = get(obj,'UserData');
% etc.
4007william
4007william 2020 年 3 月 1 日
Thank you for the help and tips!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMigrate GUIDE Apps についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by