Reference to non existent field 'output' GUIDE GUI
Mostrar comentarios más antiguos
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{:});
Respuesta aceptada
Más respuestas (0)
Categorías
Más información sobre Get Started with MATLAB Support Package for Arduino Hardware en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!