Reference to non existent field 'output' GUIDE GUI

3 views (last 30 days)
Hi there,
I am working on a GUI project that was written back in 2017. It uses MatLab 2016b and was working until recently. If I just click on the .fig file for the GUI I am not able to connect to the arduino Due using the connect callback function, and I recieve error #1. If I run the associated .m script which generates the .fig file, I am able to connect to the arduino but I am limited in functionality and I recieve the error #2. I made an adjustment to the GUI using the guide editor and saved it, but I have since deleted the adjustment and saved it again - I am not sure if this influenced the error.
Code:
function varargout = PlatformGUI_V1(varargin)
% PLATFORMGUI_V1 MATLAB code for PlatformGUI_V1.fig
% PLATFORMGUI_V1, by itself, creates a new PLATFORMGUI_V1 or raises the existing
% singleton*.
%
% H = PLATFORMGUI_V1 returns the handle to a new PLATFORMGUI_V1 or the handle to
% the existing singleton*.
%
% PLATFORMGUI_V1('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in PLATFORMGUI_V1.M with the given input arguments.
%
% PLATFORMGUI_V1('Property','Value',...) creates a new PLATFORMGUI_V1 or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before PlatformGUI_V1_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to PlatformGUI_V1_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 PlatformGUI_V1
% Last Modified by GUIDE v2.5 24-Jul-2023 16:21:01
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @PlatformGUI_V1_OpeningFcn, ...
'gui_OutputFcn', @PlatformGUI_V1_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 PlatformGUI_V1 is made visible.
function PlatformGUI_V1_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 PlatformGUI_V1 (see VARARGIN)
% Choose default command line output for PlatformGUI_V1
%% Initialize GUI States
%
%
handles = setDefaultStates(hObject, handles);
%% Display current COM ports (For Windows and MAC/LINUX)
%
%
% Previous version (WK)
% windowscom=getAvailableComPort(true);
% numwincom=size(windowscom);
% maccom=getAvailableComPort(false);
% nummaccom=size(maccom);
%
% message = sprintf('WIN COM PORTS:\n');
% for i=1:numwincom
% message = sprintf('%s%s\n',message,windowscom{i});
% end
% message = sprintf('%sMAC/LINUX COM PORTS:\n',message);
% for i=1:nummaccom
% message = sprintf('%s%s\n',message,maccom{i});
% end
% set(handles.comport_text,'String',message);
displayComPortList(handles)
%%
%Update handles structure
guidata(hObject, handles);
% --- Outputs from this function are returned to the command line.
function varargout = PlatformGUI_V1_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% Get default command line output from handles structure
varargout{1} = handles.output;
% --- Executes on button press in Connect/Close
function Connect_Callback(hObject, eventdata, handles)
%Create serial object and set some properties
% handles.comPort = get(handles.com_select,'String');
handles = setSerial(handles);
set(handles.com_select, 'Enable', 'off');
set(handles.change_com, 'Enable', 'off');
%Large buffer sizes so that we can catch all data even if one side is busy
set(handles.s,'OutputBufferSize',100000);
set(handles.s,'InputBufferSize',100000);
%Update message
set(handles.status,'String','Connecting to the Arduino');
%Try to connect... Yell at user if there is a problem
try
fopen(handles.s);
catch
warning('Connection Unsucessful: Try COM Port');
set(handles.status,'String','Connection Unsucessful: Try COM Port');
return
end
%Setting to match to the Arduino
set(handles.s,'DataBits',8);
set(handles.s,'StopBits',1);
%If you change BaudRate, you need to double check it on the Arduino end
set(handles.s,'BaudRate',115200);
set(handles.s,'Parity','none');
set(handles.status,'String','Connected');
%Clear data lines
flushinput(handles.s);
flushoutput(handles.s);
%Default GUI button to be off, so user can't do things out of order
set(handles.forward,'Enable','on');
set(handles.reverse,'Enable','on');
set(handles.surge_forward,'Enable','on');
set(handles.surge_reverse,'Enable','on');
set(handles.resetpos,'Enable','on');
set(handles.stop,'Enable','on');
set(handles.setpid,'Enable','on');
set(handles.continuous,'Enable','on');
set(handles.set_position,'Enable','on');
%Update handles structure
guidata(hObject, handles);
function pushbutton2_Callback(hObject, eventdata, handles)
% This should be renamed to 'close', but need to double check if any other
% functions call it using "pushbutton2"
fclose(serial(handles.s))
set(handles.com_select, 'Enable', 'on');
set(handles.change_com, 'Enable', 'on');
set(handles.status,'String','Arduino Disconnected');
% --- Executes on button press forward/reverse/resetpos/start/stop/readdata/writedata
function forward_Callback(hObject, eventdata, handles)
try
%set state in arduinoland
fprintf(handles.s,'%s',char(4));
catch
%send error if arduino is not connect
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
%Update status text
set(handles.status,'String','Forward Command');
function reverse_Callback(hObject, eventdata, handles)
try
fprintf(handles.s,'%s',char(5));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Reverse Command');
function surge_reverse_Callback(hObject, eventdata, handles)
try
fprintf(handles.s,'%s',char(6));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Surge Reverse Command');
function surge_forward_Callback(hObject, eventdata, handles)
try
fprintf(handles.s,'%s',char(1));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Surge Forward Command');
function resetpos_Callback(hObject, eventdata, handles)
try
fprintf(handles.s,'%s',char(3));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Encoder Position Reset');
function start_Callback(hObject, eventdata, handles)
%StopNow variable allows a method to break the while loop when start is hit
handles.StopNow=true;
%update handles structure
guidata(hObject,handles)
%create warning if no data sent to arduino
if ~handles.DataWritten
warning('No Data Written to Arduino');
set(handles.status,'String','ERROR: Write Motion Data to Arduino');
return
end
%update state in arduinoland to do motion tracking
try
fprintf(handles.s,'%s',char(9));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Motion Initialized');
%% Set Datalogging
flushinput(handles.s);
%open up datalogging file
clock_now = clock; %gets a 6-element vector of the current date and time in decimal form [year month day hour minute seconds]
clock_now(6) = round(clock_now(6)); %round to the nearest second
date_and_time_string = ''; %initialize
for i = 1:1:6 %build up the time into a string
date_and_time_string = [date_and_time_string,num2str(clock_now(i),'%02d')];
if i==3 || i==5 %after the day, and after the minute, add an underscore in the file name
date_and_time_string = [date_and_time_string,'_']; %add an underscore (_)
end
end
%create the "data" directory in the current location, if necessary
if exist('data')~=7 %if "data" does not yet exist
mkdir('data'); %creat it
end
%% Set plot
%clear axis
cla reset;
%define current axis
axes1=gca;
% Create ylabel
ylabel('Amplitude mm');
% Set the remaining axes properties
set(axes1,'YColor',[0 0 0]);
%Set axis limit (y)
ylim(axes1,[0 600]);
% Create xlabel
xlabel('Time (s)');
% Create title
title('Test Data','FontSize',16);
% Set the remaining axes properties
set(axes1,'FontSize',12,'LineStyleOrderIndex',2,'XGrid','on','YGrid','on');
% Create legend
legend(axes1,'show');
%create plot for continous motion
plot2 = plot(rand(4),'MarkerSize',2,'LineWidth',2);
file_name = ['data/data_',date_and_time_string,'.csv'];
fid = fopen(file_name,'w');
x=1;
scrollWidth = 20;
%% While Loop
while (handles.StopNow)
%read data value sent from arduino, write to array
data(x,:)=fscanf(handles.s,'%f').';
%using the newly read data, grab the time and position values for each
%actuator and send it to the plot. (look at example data logging file
%to understand each column
for k = 1:numel(plot2)
set(plot2(k), 'XData',(data(:,5*k)-data(1,5*k))/1000, 'YData', data(:,5*(k-1)+1))
end
%set y limits for plot
ylim(axes1,[0 600]);
%create a scrolling min x limit
xmin=(data(x,5)-data(1,5))/1000-scrollWidth;
%make sure data length is size of scrollwidth prior to scrolling
if(xmin>0)
xlim(axes1,[xmin (data(x,5)-data(1,5))/1000]);
else
xlim(axes1,[0 scrollWidth]);
end
%increment
x=x+1;
%update plot AND update StopNow if 'stop' is pressed by user
drawnow limitrate
%get current handles struct
handles=guidata(hObject); %% Don't delete FUNCTIONAL!
end
%% Write Data
%allow user to plot the test data
set(handles.testdataplotbutton,'Enable','on');
%update handles
guidata(hObject, handles);
% couldn't get the heading to write properly to csv, i think it's because
% it overwrites each time
% heading= ['Leg 1 Position' 'Setpoint' 'Interpolated Setpoint' 'Speed Setting (3200 Max)' 'Time (Absolute ms)' 'Leg 2 Position' 'Setpoint' 'Interpolated Setpoint' 'Speed Setting (3200 Max)' 'Time (Absolute ms)' 'Leg 3 Position' 'Setpoint' 'Interpolated Setpoint' 'Speed Setting (3200 Max)' 'Time (Absolute ms)' 'Floor Leg Position' 'Setpoint' 'Interpolated Setpoint' 'Speed Setting (3200 Max)' 'Time (Absolute ms)'];
% csvwrite(file_name,heading)
handles.testdata=data;
csvwrite(file_name,data)
guidata(hObject,handles)
fclose(fid); %close the datalogging file
function stop_Callback(hObject, eventdata, handles)
%this is so that you can stop the start function
handles.StopNow=false;
%update handles
guidata(hObject,handles)
try
fprintf(handles.s,'%s',char(0));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Motor Stopped');
function writedata_Callback(hObject, eventdata, handles)
try
fprintf(handles.s,'%s',char(2));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
%call the inverse function and update the handles function based on that
handles=inv_func_Callback(hObject, eventdata, handles)
guidata(hObject,handles)
%plot the leg data
raw_leg_plot(handles.t, [handles.YMatrix1(1,:);handles.YMatrix1(2,:);handles.YMatrix1(3,:);handles.YMatrix1(4,:)], handles)
%write only integers to the Arduino
data1=mat2str( uint16(handles.YMatrix1(1,:)))
data2=mat2str( uint16(handles.YMatrix1(2,:)))
data3=mat2str( uint16(handles.YMatrix1(3,:)))
data4=mat2str( uint16(handles.YMatrix1(4,:)))
%signal the end of a length array by '9999'
fprintf(handles.s,'%s',data1);
fprintf(handles.s,'%s',' 9999');
fprintf(handles.s,'%s',data2);
fprintf(handles.s,'%s',' 9999');
fprintf(handles.s,'%s',data3);
fprintf(handles.s,'%s',' 9999');
fprintf(handles.s,'%s',data4);
fprintf(handles.s,'%s',' 9999');
%global variable that verifies that data was sent to arduino
handles.DataWritten = true;
%allow for the start command to be used
set(handles.start,'Enable','on');
guidata(hObject,handles)
set(handles.status,'String','Motion Data Sent to Arduino');
% --- com select function
function com_select_Callback(hObject, eventdata, handles)
function com_select_CreateFcn(hObject, eventdata, handles)
%creates the text box for com select and a callback for it
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in change_com.
function change_com_Callback(hObject, eventdata, handles)
%this function doesnt do anything, it just gives the user the 'feel' of
%changing a button
displayComPortList(handles);
guidata(hObject, handles);
% --- Executes when user changes value in sin input text boxes
function amp_Callback(hObject, eventdata, handles)
%lots of variables to write here.
%to define which DOF the textbox alters, the 'current_data' property is the
%value found the drop down menu. If EQ 2 is selected then, Heave becomes
%heave 2.
%a cleaner way to do this would be nice, especially if it allows for "n"
%amount of equations
switch handles.current_data
case 'Heave'
handles.heave_amp=str2double(get(hObject,'String'));
case 'Surge'
handles.surge_amp=str2double(get(hObject,'String'));
case 'Roll'
handles.roll_amp=str2double(get(hObject,'String'));
case 'Pitch'
handles.pitch_amp=str2double(get(hObject,'String'));
case 'Heave2'
handles.heave_amp2=str2double(get(hObject,'String'));
case 'Surge2'
handles.surge_amp2=str2double(get(hObject,'String'));
case 'Roll2'
handles.roll_amp2=str2double(get(hObject,'String'));
case 'Pitch2'
handles.pitch_amp2=str2double(get(hObject,'String'));
end
%update the equation shown below the graph by passing the handle structure
update_func(handles)
%modify handles to reflect the sin input given in the text box
handles=calc_sin_input(handles);
%updata handles
guidata(hObject,handles)
%plot motion data
handles=plot_data_Callback(hObject, eventdata, handles);
%update handles
guidata(hObject,handles)
function amp_CreateFcn(hObject, eventdata, handles)
%create textbox
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%default to zero
set(hObject,'String','0')
function freq_Callback(hObject, eventdata, handles)
switch handles.current_data
case 'Heave'
handles.heave_freq=str2double(get(hObject,'String'));
handles.heave_freq = handles.heave_freq*2*pi;
case 'Surge'
handles.surge_freq=str2double(get(hObject,'String'));
handles.surge_freq = handles.surge_freq*2*pi;
case 'Roll'
handles.roll_freq=str2double(get(hObject,'String'));
handles.roll_freq = handles.roll_freq*2*pi;
case 'Pitch'
handles.pitch_freq=str2double(get(hObject,'String'));
handles.pitch_freq = handles.pitch_freq*2*pi;
case 'Heave2'
handles.heave_freq2=str2double(get(hObject,'String'));
handles.heave_freq2 = handles.heave_freq2*2*pi;
case 'Surge2'
handles.surge_freq2=str2double(get(hObject,'String'));
handles.surge_freq2 = handles.surge_freq2*2*pi;
case 'Roll2'
handles.roll_freq2=str2double(get(hObject,'String'));
handles.roll_freq2 = handles.roll_freq2*2*pi;
case 'Pitch2'
handles.pitch_freq2=str2double(get(hObject,'String'));
handles.pitch_freq2 = handles.pitch_freq2*2*pi;
end
update_func(handles)
handles=calc_sin_input(handles);
guidata(hObject,handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function freq_CreateFcn(hObject, eventdata, handles)
% hObject handle to freq (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
set(hObject,'String','0')
function phase_Callback(hObject, eventdata, handles)
switch handles.current_data
case 'Heave'
handles.heave_phase=str2double(get(hObject,'String'));
handles.heave_phase = handles.heave_phase*pi/180;
case 'Surge'
handles.surge_phase=str2double(get(hObject,'String'));
handles.surge_phase = handles.surge_phase*pi/180;
case 'Roll'
handles.roll_phase=str2double(get(hObject,'String'));
handles.roll_phase = handles.roll_phase*pi/180;
case 'Pitch'
handles.pitch_phase=str2double(get(hObject,'String'));
handles.pitch_phase = handles.pitch_phase*pi/180;
case 'Heave2'
handles.heave_phase2=str2double(get(hObject,'String'));
handles.heave_phase2 = handles.heave_phase2*pi/180;
case 'Surge2'
handles.surge_phase2=str2double(get(hObject,'String'));
handles.surge_phase2 = handles.surge_phase2*pi/180;
case 'Roll2'
handles.roll_phase2=str2double(get(hObject,'String'));
handles.roll_phase2 = handles.roll_phase2*pi/180;
case 'Pitch2'
handles.pitch_phase2=str2double(get(hObject,'String'));
handles.pitch_phase2 = handles.pitch_phase2*pi/180;
end
update_func(handles)
handles=calc_sin_input(handles)
guidata(hObject,handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function phase_CreateFcn(hObject, eventdata, handles)
% hObject handle to phase (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
set(hObject,'String','0')
function bias_Callback(hObject, eventdata, handles)
switch handles.current_data
case 'Heave'
handles.heave_bias=str2double(get(hObject,'String'));
case 'Surge'
handles.surge_bias=str2double(get(hObject,'String'));
case 'Roll'
handles.roll_bias=str2double(get(hObject,'String'));
case 'Pitch'
handles.pitch_bias=str2double(get(hObject,'String'));
case 'Heave2'
handles.heave_bias2=str2double(get(hObject,'String'));
case 'Surge2'
handles.surge_bias2=str2double(get(hObject,'String'));
case 'Roll2'
handles.roll_bias2=str2double(get(hObject,'String'));
case 'Pitch2'
handles.pitch_bias2=str2double(get(hObject,'String'));
end
update_func(handles)
handles=calc_sin_input(handles)
guidata(hObject,handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function bias_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
set(hObject,'String','0')
% --- Executes on selection change in popupmenu3.
function motion_select_Callback(hObject, eventdata, handles)
str = get(hObject, 'String');
val = get(hObject,'Value');
str_eq = get(handles.eq_select,'String');
val_eq = get(handles.eq_select,'Value');
% Set current data to the selected data set.
% Very gross, hate this method
switch str_eq{val_eq}
case 'Eq 1'
switch str{val}
case 'Heave'
handles.current_data = 'Heave';
set(handles.amp,'String',handles.heave_amp)
set(handles.freq,'String',handles.heave_freq)
set(handles.phase,'String',handles.heave_phase)
set(handles.bias,'String',handles.heave_bias)
case 'Surge'
handles.current_data = 'Surge';
set(handles.amp,'String',handles.surge_amp)
set(handles.freq,'String',handles.surge_freq)
set(handles.phase,'String',handles.surge_phase)
set(handles.bias,'String',handles.surge_bias)
case 'Roll'
handles.current_data = 'Roll';
set(handles.amp,'String',handles.roll_amp)
set(handles.freq,'String',handles.roll_freq)
set(handles.phase,'String',handles.roll_phase)
set(handles.bias,'String',handles.roll_bias)
case 'Pitch'
handles.current_data = 'Pitch';
set(handles.amp,'String',handles.pitch_amp)
set(handles.freq,'String',handles.pitch_freq)
set(handles.phase,'String',handles.pitch_phase)
set(handles.bias,'String',handles.pitch_bias)
end
case 'Eq 2'
switch str{val}
case 'Heave'
handles.current_data = 'Heave2';
set(handles.amp,'String',handles.heave_amp2)
set(handles.freq,'String',handles.heave_freq2)
set(handles.phase,'String',handles.heave_phase2)
set(handles.bias,'String',handles.heave_bias2)
case 'Surge'
handles.current_data = 'Surge2';
set(handles.amp,'String',handles.surge_amp2)
set(handles.freq,'String',handles.surge_freq2)
set(handles.phase,'String',handles.surge_phase2)
set(handles.bias,'String',handles.surge_bias2)
case 'Roll'
handles.current_data = 'Roll2';
set(handles.amp,'String',handles.roll_amp2)
set(handles.freq,'String',handles.roll_freq2)
set(handles.phase,'String',handles.roll_phase2)
set(handles.bias,'String',handles.roll_bias2)
case 'Pitch'
handles.current_data = 'Pitch2';
set(handles.amp,'String',handles.pitch_amp2)
set(handles.freq,'String',handles.pitch_freq2)
set(handles.phase,'String',handles.pitch_phase2)
set(handles.bias,'String',handles.pitch_bias2)
end
end
% Save the handles structure.
guidata(hObject,handles)
function eq_select_Callback(hObject, eventdata, handles)
str_eq = get(hObject, 'String');
val_eq = get(hObject,'Value');
str = get(handles.motion_select,'String');
val = get(handles.motion_select,'Value');
% Set current data to the selected data set.
switch str_eq{val_eq}
case 'Eq 1'
switch str{val}
case 'Heave'
handles.current_data = 'Heave';
set(handles.amp,'String',handles.heave_amp)
set(handles.freq,'String',handles.heave_freq)
set(handles.phase,'String',handles.heave_phase)
set(handles.bias,'String',handles.heave_bias)
case 'Surge'
handles.current_data = 'Surge';
set(handles.amp,'String',handles.surge_amp)
set(handles.freq,'String',handles.surge_freq)
set(handles.phase,'String',handles.surge_phase)
set(handles.bias,'String',handles.surge_bias)
case 'Roll'
handles.current_data = 'Roll';
set(handles.amp,'String',handles.roll_amp)
set(handles.freq,'String',handles.roll_freq)
set(handles.phase,'String',handles.roll_phase)
set(handles.bias,'String',handles.roll_bias)
case 'Pitch'
handles.current_data = 'Pitch';
set(handles.amp,'String',handles.pitch_amp)
set(handles.freq,'String',handles.pitch_freq)
set(handles.phase,'String',handles.pitch_phase)
set(handles.bias,'String',handles.pitch_bias)
end
case 'Eq 2'
switch str{val}
case 'Heave'
handles.current_data = 'Heave2';
set(handles.amp,'String',handles.heave_amp2)
set(handles.freq,'String',handles.heave_freq2)
set(handles.phase,'String',handles.heave_phase2)
set(handles.bias,'String',handles.heave_bias2)
case 'Surge'
handles.current_data = 'Surge2';
set(handles.amp,'String',handles.surge_amp2)
set(handles.freq,'String',handles.surge_freq2)
set(handles.phase,'String',handles.surge_phase2)
set(handles.bias,'String',handles.surge_bias2)
case 'Roll'
handles.current_data = 'Roll2';
set(handles.amp,'String',handles.roll_amp2)
set(handles.freq,'String',handles.roll_freq2)
set(handles.phase,'String',handles.roll_phase2)
set(handles.bias,'String',handles.roll_bias2)
case 'Pitch'
handles.current_data = 'Pitch2';
set(handles.amp,'String',handles.pitch_amp2)
set(handles.freq,'String',handles.pitch_freq2)
set(handles.phase,'String',handles.pitch_phase2)
set(handles.bias,'String',handles.pitch_bias2)
end
end
% Save the handles structure.
guidata(hObject,handles)
function motion_select_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function eq_select_CreateFcn(hObject, eventdata, handles)
% hObject handle to eq_select (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: popupmenu controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%function to create sin inputs
function handles=calc_sin_input(handles)
t=[0:.1:60];
handles.t=t;
handles.heave=handles.heave_amp*sin(handles.heave_freq*t+handles.heave_phase)+handles.heave_bias+handles.heave_amp2*sin(handles.heave_freq2*t+handles.heave_phase2)+handles.heave_bias2;
handles.surge=handles.surge_amp*sin(handles.surge_freq*t+handles.surge_phase)+handles.surge_bias+handles.surge_amp2*sin(handles.surge_freq2*t+handles.surge_phase2)+handles.surge_bias2;
handles.roll=handles.roll_amp*sin(handles.roll_freq*t+handles.roll_phase)+handles.roll_bias+handles.roll_amp2*sin(handles.roll_freq2*t+handles.roll_phase2)+handles.roll_bias2;
handles.pitch=handles.pitch_amp*sin(handles.pitch_freq*t+handles.pitch_phase)+ handles.pitch_bias+handles.pitch_amp2*sin(handles.pitch_freq2*t+handles.pitch_phase2)+handles.pitch_bias2;
% --- Executes on button press in plot_data.
function handles=plot_data_Callback(hObject, eventdata, handles)
%allow user to write data to arduino now that motion data has been created
set(handles.writedata,'Enable','on');
guidata(hObject, handles);
%trigger warnings if user goes beyond recommended values
%currently triggers everytime? maybe annoying, consider change to single
%warning
if ~handles.Motion_Warned_rot
if (abs(handles.pitch_amp)+abs(handles.pitch_bias))>=20
uiwait(msgbox('WARNING: Max amplitude for Pitch is set higher than 20 degs. Platform limit is 25 degs. Proceed with caution.','Motion WARNING'))
handles.Motion_Warned_rot=true;
end
if (abs(handles.roll_amp)+abs(handles.roll_bias))>=20
uiwait(msgbox('WARNING: Max amplitude for Roll is set higher than 20 degs. Platform limit is 25 degs. Proceed with caution.','Motion WARNING'))
handles.Motion_Warned_rot=true;
end
end
if ~handles.Motion_Warned_trans
if (abs(handles.heave_amp)+abs(handles.heave_bias))>=500
uiwait(msgbox('WARNING: Max amplitude for Heave is set higher than 500 mm. Platform limit is 550 mm. Proceed with caution.','Motion WARNING'))
handles.Motion_Warned_trans=true;
end
if (abs(handles.surge_amp)+abs(handles.surge_bias))>=500
uiwait(msgbox('WARNING: Max amplitude for Surge is set higher than 500 mm. Platform limit is 550 mm. Proceed with caution.','Motion WARNING'))
handles.Motion_Warned_trans=true;
end
end
guidata(hObject,handles)
%plot motion data
raw_motion_plot(handles.t, [handles.heave;handles.surge], [handles.roll;handles.pitch], handles)
% --- Executes on button press in heavebox/surgebox/pitchbox/rollbox.
function heavebox_Callback(hObject, eventdata, handles)
%the value of the heave box is held in the handle structure, so all this
%callback does is re-plot the motion data according to the check boxes
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function surgebox_Callback(hObject, eventdata, handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function pitchbox_Callback(hObject, eventdata, handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function rollbox_Callback(hObject, eventdata, handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
% --- Executes on button press in inv_func.
function handles=inv_func_Callback(hObject, eventdata, handles)
%call the inverse func to calculate leg lengths
Inverse_Kinematics_funct(handles.t,handles.heave,handles.surge,handles.pitch,handles.roll,handles,hObject)
handles=guidata(hObject);
%check if you exceed max leg lengths
max(max(handles.YMatrix1))
if ~handles.Leg_Warned
if max(max(handles.YMatrix1))>=500
uiwait(msgbox('WARNING: Max leg length will be higher than 500 mm. Platform limit is 550 mm. Proceed with caution.','Motion WARNING'))
handles.Leg_Warned=true;
end
end
guidata(hObject,handles)
% --- Executes on toggle selection of the plot commands.
function plot_motion_Callback(hObject, eventdata, handles)
handles=plot_data_Callback(hObject, eventdata, handles);
guidata(hObject,handles)
function plot_leg_Callback(hObject, eventdata, handles)
hold off
handles=inv_func_Callback(hObject, eventdata, handles);
raw_leg_plot(handles.t, [handles.YMatrix1(1,:);handles.YMatrix1(2,:);handles.YMatrix1(3,:);handles.YMatrix1(4,:)], handles)
function testdataplotbutton_Callback(hObject, eventdata, handles)
try
hold off
test_data_plot(handles.testdata, handles)
catch
warning('Start Motion to Generate Data');
set(handles.status,'String','ERROR: No Test Data Available');
return
end
% --- Executes when GUI is closed, before destroying properties
function figure1_DeleteFcn(hObject, eventdata, handles)
%stop start loop
handles.StopNow=false;
guidata(hObject,handles)
%close arduino
try
fclose(serial(handles.s))
fprintf(handles.s,'%s',char(0));
catch
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
set(handles.status,'String','Arduino Disconnected');
% --- Executes on button press in custom_motion.
function custom_motion_Callback(hObject, eventdata, handles)
set(handles.writedata,'Enable','on');
guidata(hObject, handles);
%% Import the data
currentFolder = pwd;
filename='/Manual_Data.xlsx';
path=[pwd filename];
[~, ~, raw] = xlsread(path,'Sheet1');
raw = raw(2:end,:);
%% Create output variable
data = reshape([raw{:}],size(raw));
%% Allocate imported array to column variable names
handles.t = data(:,1)';
handles.heave = data(:,2)';
handles.surge= data(:,3)';
handles.pitch= data(:,4)';
handles.roll= data(:,5)';
guidata(hObject,handles)
%show handles for debugging
handles
%% Clear temporary variables
clearvars data raw;
plot_data_Callback(hObject, eventdata, handles)
% --- PID textboxes, value is intrinsic to handles. These functions call a
% warning to the user
function Kp_Callback(hObject, eventdata, handles)
if ~handles.PIDWarned
uiwait(msgbox('WARNING: Adjusting PID parameters may move platform into unstable operating regions. Proceed with Caution. Refer to User Manual.','PID WARNING'))
handles.PIDWarned=true;
guidata(hObject,handles)
end
function Kp_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Kd_Callback(hObject, eventdata, handles)
if ~handles.PIDWarned
uiwait(msgbox('WARNING: Adjusting PID parameters may move platform into unstable operating regions. Proceed with Caution. Refer to User Manual.','PID WARNING'))
handles.PIDWarned=true;
guidata(hObject,handles)
end
function Kd_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function Ki_Callback(hObject, eventdata, handles)
if ~handles.PIDWarned
uiwait(msgbox('WARNING: Adjusting PID parameters may move platform into unstable operating regions. Proceed with Caution. Refer to User Manual.','PID WARNING'))
handles.PIDWarned=true;
guidata(hObject,handles)
end
function Ki_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in setpid.
function setpid_Callback(hObject, eventdata, handles)
%writes PID values to Arduino via state 8 in ArduinoLand
Kp=get(handles.Kp,'String');
Kd=get(handles.Kd,'String');
Ki=get(handles.Ki,'String');
try
fprintf(handles.s,'%s',char(8));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
fprintf(handles.s,'%s',Kp);
fprintf(handles.s,'%s',' 9999 ');
fprintf(handles.s,'%s',Ki);
fprintf(handles.s,'%s',' 9999 ');
fprintf(handles.s,'%s',Kd);
fprintf(handles.s,'%s',' 9999');
% --- Function that controls what is shown in the textbox below the plot
function update_func(handles)
message = sprintf(' = %dsin(%dt+%d)+%d + %dsin(%dt+%d)+%d\n',handles.heave_amp,handles.heave_freq,handles.heave_phase,handles.heave_bias,handles.heave_amp2,handles.heave_freq2,handles.heave_phase2,handles.heave_bias2);
message = sprintf('%s = %dsin(%dt+%d)+%d + %dsin(%dt+%d)+%d\n',message,handles.surge_amp,handles.surge_freq,handles.surge_phase,handles.surge_bias,handles.surge_amp2,handles.surge_freq2,handles.surge_phase2,handles.surge_bias2);
message = sprintf('%s = %dsin(%dt+%d)+%d + %dsin(%dt+%d)+%d\n',message,handles.pitch_amp,handles.pitch_freq,handles.pitch_phase,handles.pitch_bias,handles.pitch_amp2,handles.pitch_freq2,handles.pitch_phase2,handles.pitch_bias2);
message = sprintf('%s = %dsin(%dt+%d)+%d + %dsin(%dt+%d)+%d\n',message,handles.roll_amp,handles.roll_freq,handles.roll_phase,handles.roll_bias,handles.roll_amp2,handles.roll_freq2,handles.roll_phase2,handles.roll_bias2);
set(handles.eq_stat,'String',message);
%function to calculate the step position leg lengths for the platform
function handles=single_inv_func(hObject, eventdata, handles)
%get values from sliders
handles.heave_sing=get(handles.heave_slider,'Value');
handles.surge_sing=get(handles.surge_slider,'Value');
handles.roll_sing=get(handles.roll_slider,'Value');
handles.pitch_sing=get(handles.pitch_slider,'Value');
%calculate desired step leg lengths
Single_Inverse_Kinematics_funct(handles.heave_sing,handles.surge_sing,handles.pitch_sing,handles.roll_sing,handles,hObject)
handles=guidata(hObject);
% --- Executes on button press in set_position.
function set_position_Callback(hObject, eventdata, handles)
%go to state 7 in ArduinoLand
try
fprintf(handles.s,'%s',char(7));
catch
warning('Arduino Not Connected');
set(handles.status,'String','ERROR: Arduino Not Connected');
return
end
%calc lengths
handles=single_inv_func(hObject, eventdata, handles);
%convert to ints
leg1=mat2str( uint16(handles.YMatrix_Sing(1,1)))
leg2=mat2str( uint16(handles.YMatrix_Sing(2,1)))
leg3=mat2str( uint16(handles.YMatrix_Sing(3,1)))
leg4=mat2str( uint16(handles.YMatrix_Sing(4,1)))
%write to Arduino
%could reconfigure arduino code to make 9999 unnecessary
fprintf(handles.s,'%s',leg1);
fprintf(handles.s,'%s',' 9999 ');
fprintf(handles.s,'%s',leg2);
fprintf(handles.s,'%s',' 9999 ');
fprintf(handles.s,'%s',leg3);
fprintf(handles.s,'%s',' 9999 ');
fprintf(handles.s,'%s',leg4);
fprintf(handles.s,'%s',' 9999');
% --- Toggle State of continous
function continuous_Callback(hObject, eventdata, handles)
% --- Executes on slider movement.
function heave_slider_Callback(hObject, eventdata, handles)
%generate number string to put under slider
handles.heave_sing=round(get(handles.heave_slider,'Value'),1);
str = sprintf('%3.1f',handles.heave_sing);
handles=guidata(hObject);
set(handles.heave_textbox,'String',str);
handles=single_inv_func(hObject, eventdata, handles)
%warn if the position is dangerous
%on second warn just make the text red
if handles.YMatrix_Sing(1,1) > 550 || handles.YMatrix_Sing(2,1) > 550 || handles.YMatrix_Sing(3,1) > 550 || handles.YMatrix_Sing(4,1) > 550
if ~handles.Position_Warned
uiwait(msgbox('WARNING: Resulting Actuator length will be higher than 550 mm. Platform will not be able to reach position. Proceed with caution.','Motion WARNING'))
handles.Position_Warned=true;
end
set(handles.set_position,'ForegroundColor','red');
else
set(handles.set_position,'ForegroundColor','black');
if get(handles.continuous,'Value')
set_position_Callback(hObject, eventdata, handles)
end
end
guidata(hObject,handles)
function heave_slider_CreateFcn(hObject, eventdata, handles)
%set slider limits
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
set(hObject,'Max',550)
set(hObject,'Min',0)
function roll_slider_Callback(hObject, eventdata, handles)
handles.roll_sing=round(get(handles.roll_slider,'Value'),1);
str = sprintf('%3.1f',handles.roll_sing);
handles=guidata(hObject);
set(handles.roll_textbox,'String',str);
handles=single_inv_func(hObject, eventdata, handles)
if handles.YMatrix_Sing(1,1) > 550 || handles.YMatrix_Sing(2,1) > 550 || handles.YMatrix_Sing(3,1) > 550 || handles.YMatrix_Sing(4,1) > 550
if ~handles.Position_Warned
uiwait(msgbox('WARNING: Resulting Actuator length will be higher than 550 mm. Platform will not be able to reach position. Proceed with caution.','Motion WARNING'))
handles.Position_Warned=true;
end
set(handles.set_position,'ForegroundColor','red');
else
set(handles.set_position,'ForegroundColor','black');
if get(handles.continuous,'Value')
set_position_Callback(hObject, eventdata, handles)
end
end
guidata(hObject,handles)
function roll_slider_CreateFcn(hObject, eventdata, handles)
% hObject handle to roll_slider (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
set(hObject,'Max',25)
set(hObject,'Min',-25)
function pitch_slider_Callback(hObject, eventdata, handles)
handles.pitch_sing=round(get(handles.pitch_slider,'Value'),1);
str = sprintf('%3.1f',handles.pitch_sing);
handles=guidata(hObject);
set(handles.pitch_textbox,'String',str);
handles=single_inv_func(hObject, eventdata, handles)
if handles.YMatrix_Sing(1,1) > 550 || handles.YMatrix_Sing(2,1) > 550 || handles.YMatrix_Sing(3,1) > 550 || handles.YMatrix_Sing(4,1) > 550
if ~handles.Position_Warned
uiwait(msgbox('WARNING: Resulting Actuator length will be higher than 550 mm. Platform will not be able to reach position. Proceed with caution.','Motion WARNING'))
handles.Position_Warned=true;
end
set(handles.set_position,'ForegroundColor','red');
else
set(handles.set_position,'ForegroundColor','black');
if get(handles.continuous,'Value')
set_position_Callback(hObject, eventdata, handles)
end
end
guidata(hObject,handles)
function pitch_slider_CreateFcn(hObject, eventdata, handles)
% hObject handle to pitch_slider (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
set(hObject,'Max',25)
set(hObject,'Min',-25)
function surge_slider_Callback(hObject, eventdata, handles)
handles.surge_sing=round(get(handles.surge_slider,'Value'),1);
str = sprintf('%3.1f',handles.surge_sing);
handles=guidata(hObject);
set(handles.surge_textbox,'String',str);
handles=single_inv_func(hObject, eventdata, handles)
if handles.YMatrix_Sing(1,1) > 550 || handles.YMatrix_Sing(2,1) > 550 || handles.YMatrix_Sing(3,1) > 550 || handles.YMatrix_Sing(4,1) > 550
if ~handles.Position_Warned
uiwait(msgbox('WARNING: Resulting Actuator length will be higher than 550 mm. Platform will not be able to reach position. Proceed with caution.','Motion WARNING'))
handles.Position_Warned=true;
end
set(handles.set_position,'ForegroundColor','red');
else
set(handles.set_position,'ForegroundColor','black');
if get(handles.continuous,'Value')
set_position_Callback(hObject, eventdata, handles)
end
end
guidata(hObject,handles)
function surge_slider_CreateFcn(hObject, eventdata, handles)
% hObject handle to surge_slider (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
set(hObject,'Max',550)
set(hObject,'Min',0)
% --- Executes on toggle of the leg checkboxes
function leg1_box_Callback(hObject, eventdata, handles)
plot_leg_Callback(hObject, eventdata, handles)
function leg2_box_Callback(hObject, eventdata, handles)
plot_leg_Callback(hObject, eventdata, handles)
function leg3_box_Callback(hObject, eventdata, handles)
plot_leg_Callback(hObject, eventdata, handles)
function floorleg_box_Callback(hObject, eventdata, handles)
plot_leg_Callback(hObject, eventdata, handles)
% --- Executes on button press in pushbutton26.
function pushbutton26_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton26 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% --- Executes on button press in gohome.
function pushbutton27_Callback(hObject, eventdata, handles)
% hObject handle to gohome (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Error #1:
Struct contents reference from a non-struct array object.
Error in setSerial (line 5)
ports = get(handles.com_select, 'String');
Error in PlatformGUI_V1>Connect_Callback (line 119)
handles = setSerial(handles);
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in PlatformGUI_V1 (line 64)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)PlatformGUI_V1('Connect_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
Error #2:
>> PlatformGUI_V1
Reference to non-existent field 'output'.
Error in PlatformGUI_V1>PlatformGUI_V1_OutputFcn (line 111)
varargout{1} = handles.output;
Error in gui_mainfcn (line 264)
feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
Error in PlatformGUI_V1 (line 64)
gui_mainfcn(gui_State, varargin{:});

Accepted Answer

Voss
Voss on 25 Jul 2023
You should always run the m-file (don't try to run the fig-file by itself). Therefore only error #2 is relevant.
To fix error #2, include the line
handles.output = handles.figure1;
in PlatformGUI_V1_OpeningFcn, somewhere before the guidata(hObject, handles); line. This is a line of code automatically created by GUIDE which must have been deleted by mistake at some point.
I assume the Tag of your figure is 'figure1', which is the default, so if you didn't change it in GUIDE, it should be 'figure1'. To make sure, you can open the fig file in GUIDE, click on the figure itself and see the Tag in the bottom-left status bar or in the Object Browser. If the Tag of your figure is not 'figure1', replace 'figure1' in the line of code I gave above with whatever the Tag really is.
An alternative would be to replace
varargout{1} = handles.output;
in PlatformGUI_V1_OutputFcn, with
varargout{1} = handles.figure1;
again, using your figure's Tag if it's not 'figure1'.

More Answers (0)

Products


Release

R2016b

Community Treasure Hunt

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

Start Hunting!