Matlab assignin('base',...) Resets - matlab

I am attempting to write a function that, if called before any animation, will handle the close events without extra code in the animation file.
function matlabStopFunction(varargin)
persistent runs
if runs==2
runs = [];
end
if isempty(runs)
evalin('base','figure(''DeleteFcn'',#matlabStopFunction);');
runs = 1;
else
assignin('base','play',false);
pause(1);
runs = 2;
end
end
Here's a sample animation code that I've been using:
function sampleAnimation
matlabStopFunction;
r = 5;
th = 0;
play = true;
while play
x = r * cosd(th);
y = r * -sind(th);
plot(x,y,'r*');
axis([-10 10 -10 10]);
th = th + 45;
pause(0.25);
end
end
The stop function works fine creating the figure, and when I close the figure, it calls the same function as expected (including the assignin on line 10). However, when stepping through, when I first get back to the base function (sampleAnimation), play is false as would be expected:
But when I step one more line, play is reset to true
Am I incorrectly assigning the value of play to false in the stop function, and if so, how could I correct this so that the animation stops when the figure is closed while keeping the code inside the animation to a minimum? I am trying to replicate the method on this blog except with all the code contained in a separate file.
I am running Matlab 2014b on Windows 8.1.

To answer your question - you are modifying the value play in the base workspace - where as the loop is in the workspace of the sampleAnimation function -> so you are not changing the required value to stop the animation. To verify this clear your variables in the base workspace clear before you run your code and you will see that the variable play is created and set to false.
By the way there is a much simpler way to do this, you animation can create a figure and then you can stop when it is deleted:
function sampleAnimation
h = figure;
r = 5;
th = 0;
while ishandle ( h )
x = r * cosd(th);
y = r * -sind(th);
plot(x,y,'r*');
axis([-10 10 -10 10]);
th = th + 45;
pause(0.25);
end
end

Related

Matlab gui with pause function

I am using the GUIDE for matlab gui.
The gui built in order to communicate with keithley current measurement device through GPIB.
When using a toggle button for Current measurement while loop, i am using a pause() function inside the while loop for each iteration and a ytranspose on the y array reading results.
function Measure_Callback(hObject, eventdata, handles)
global GPIB1
global filename
global timeStep
disp('Measurement in progress \n stopwatch starts!');
tic
x=0;
n=0;
while get(hObject,'Value')
fprintf(GPIB1, 'printnumber(smua.measure.i(smua.nvbuffer1))');
fprintf(GPIB1, 'printbuffer(1,1,nvbuffer1)');
A = fscanf(GPIB1);
if length(A)<20
x = x+1;
n = n+1;
t(n) = toc ;
y(x) = str2double(A);
plot(t,y,'-bo',...
'LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[.49 1 .63],...
'MarkerSize',10);
grid on
hold on
end
title('Current vs Time','FontSize', 15)
xlabel('Time [s]','FontSize', 15)
ylabel('Current [A]','FontSize', 15)
a = timeStep;
pause(a)
end
disp('Measurement terminated');
disp('Elapsed time: ');
elapsedtime = toc;
elapsedtime_string = num2str(elapsedtime);
disp(elapsedtime_string);
ytrans = transpose(y);
csvwrite(filename,ytrans);
fprintf(GPIB1, 'smua.source.output = smua.OUTPUT_OFF');
For the pause function i'm geting error:
?? Error using ==> pause Error while evaluating uicontrol Callback
For the transpose(y) function i'm also getting a error:
its undefined y.
Cant understand why are those errors and could use some help.
Thank you!
First off, as people say, post the errors and the code. Do you know if length(A) is smaller than 20 in the first time you run the loop? Because if not, A is not defined and you can't transpose something that is not there. Initialize A before the loop to something and see if the error persists (or print out length(A) to make sure the loop gets entered the first run).
As for the pause error, make sure pause is an int or double, not a string. If you get your global timeStep from the GUI field, it is probably a string and you need to covert it to double first.

For Loop and indexing

Following is my code :
function marks(my_numbers)
handle = zeros(5,1)
x = 10 ;
y = 10:20:100 ;
for i = 1
for j = 1:5 ;
handle(j,i) = rectangle('position',[x(i),y(j),20 10],'facecolor','r')
end
end
end
now lets say input argument my_numbers = 2
so i have written the code :
set(handle(j(my_numbers),1),'facecolor','g')
With this command, rectangle with lower left corner at (30,10) should have turned green. But MATLAB gives an error of index exceeds matrix dimensions
This is more an illustrated comment than an answer, but as #hagubear mentioned your i index is pointless so you could remove it altogether.
Using set(handle(my_numbers,1),'facecolor','g') will remove the error, because you were trying to access handles(j(2),1) and that was not possible because j is a scalar.
Anyhow using this line after your plot works fine:
set(handle(my_numbers,1),'facecolor','g')
According to your comment below, here is a way to call the function multiple times and add green rectangles as you go along. There are 2 files for the purpose of demonstration, the function per se and a script to call the function multiple times and generate an animated gif:
1) The function:
function marks(my_numbers)
%// Get green and red rectangles to access their properties.
GreenRect = findobj('Type','rectangle','FaceColor','g');
RedRect = findobj('Type','rectangle');
%// If 1st call to the function, create your plot
if isempty(RedRect)
handle = zeros(5,1);
x = 10 ;
y = 10:20:100 ;
for j = 1:5 ;
handle(j) = rectangle('position',[x,y(j),20 10],'facecolor','r');
end
set(handle(my_numbers,1),'facecolor','g')
%// If not 1st call, fetch existing green rectangles and color them green. Then color the appropriate rectangle given by my_numbers.
else
RedRect = flipud(RedRect); %// Flip them to maintain correct order
if numel(GreenRect) > 0
hold on
for k = numel(GreenRect)
set(GreenRect(k),'facecolor','g')
set(RedRect(my_numbers,1),'facecolor','g')
end
end
end
2) The script:
clear
clc
%// Shuffle order for appearance of green rectangles.
iter = randperm(5);
filename = 'MyGifFile.gif';
for k = iter
marks(k)
pause(1)
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if k == iter(1)
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
end
Here is the animated gif of the output:

MATLAB GUI User Input Update

I have a MATLAB GUI which takes values from the user input , do some calculation based on those and plot them in the GUI.
Everything is all right and working BUT when I change the values in the GUI it does not plot as expected and gives and error of dimension mismatch. However, there is no dimension mismatch and if I go to the script and press run again (the big green arrow) and then click plot again, it plots the values as expected.
I have initialized all of my values that I use but I can not see how can fix this. I need something like update command for all of the script each time I press the 'plot' button.
Any help is appreciated, many thanks!..
CODE:
a = str2double(get(handles.edit14,'String'));
b = str2double(get(handles.edit15,'String'));
c = str2double(get(handles.edit16,'String'));
d = str2double(get(handles.edit18,'String'));
e = str2double(get(handles.edit19,'String'));
f = str2double(get(handles.edit20,'String'));
for Veff=[a:b:c] %user input speeds (a,b,c) (comes from user)
q = 0.5*1.225*(Veff*1000/3600)^2;
F1=q*S; M1=q*S*Cref;
FX1=(F1*coef(:,1)); FZ1=(F1*coef(:,3)); MM1=(M1*coef(:,5));
W=[d*g:e*g:f*g]; %define mass range (d,e,f comes from user)
for lw=1:1:length(W)
XGEquation2max1 = ((((-FB*(Xa-Xb))-(((FX1(12)))*(Za-Zr))-(((FZ1(7))))*(Xa-Xr))-((max(MM1))))./W(lw)) + Xa;
CGPercent(lw,column) = (XGEquation2max1 - Cstart)/Cref * 100;
end
column=column+1;
end
speed_matrix = [a:b:c];
mass_matrix = [d:e:f];
ns = size(speed_matrix);
ns= ns(2);
count5 = 1;
for ns=1:1:ns
hold all
axes(handles.axes4)
plot(CGPercent(:,ns),transpose(mass_matrix)/1000)
count5 = count5 + 1;
end
Main problem is with the variables 'd,e,f' because when I change 'a,b,c' only (i.e speed) there is no problem.

Matlab not plotting, endless loop

I'm trying to use the bisection method in Matlab to find the root of an equation as q varies from 2000-3000 in 10 step intervals. My code however does not print out a graph even though I have a plot statement and I think it creates an infinite loop since when I run it matlab says busy and I can't close the program unless I force close. I can't see anything in my code that would cause this though, could someone help me out?
function myFunction
a = 20;
b = 40;
tol = 1e-4;
q = 2000:10:3000;
t = zeros(101,1);
for i=(1:length(q))
f = #(x) (((1800).*log((160000)./(160000 - (x.*q(i)))) - (9.812).*x)./750) - 1;
t(i) = bisect(f,a,b,tol);
end
figure(1)
plot(q,t)
function c=bisect(f,a,b,tol)
k=0;
while b-a > tol
c = (a-b)/2;
if sign(f(c)) == sign(f(b))
b=c;
else
a=c;
end
k=k+1;
end
end
end
It should also be noted that I have used this bisect method before and it does work so I don't think the problem is with that function.
Your error is here:
c = (a-b)/2;
You initialize a=20 and b=40. c is initially set to -10. But you really want c to be halfway between a and b, which means you want:
c = (a+b)/2;
Also, add a drawnow right after you plot statement to force MATLAB to draw graphics.

using timer in MATLAB to extract the system time

!I am using MATLAB to design an Analog Clock. Currently, my code simply displays the (or plots rather) the clock design with the hands (hours, mins, secs) and does not tick. Here is my code:
function raviClock(h,m,s)
drawClockFace;
%TIMER begins-------
t = timer;
t.ExecutionMode = 'FixedSpacing'; %Use one of the repeating modes
t.Period = 1; %Fire on 1 second intervals
t.TimerFcn = #timer_setup; %When fired, call this function
start(t);
set(gcf,'DeleteFcn',#(~,~)stop(t));
end
function timer_setup(varargin)
format shortg;
timenow = clock;
h = timenow(4);
m = timenow(5);
s = timenow(6);
% hour hand
hours= h + m/60 + s/3600;
hourAngle= 90 - hours*(360/12);
% compute coordinates for pointing end of hour hand and draw it
[xhour, yhour]= polar2xy(0.6, hourAngle);
plot([0 xhour], [0 yhour], 'k-','linewidth',7.4)
% minute hand
mins= m + s/60;
minsAngle= 90 - mins*(360/60);
% compute coordinates for pointing end of minute hand and draw it
[xmins, ymins]= polar2xy(0.75, minsAngle);
plot([0 xmins], [0 ymins], 'r-','linewidth',4)
%second's hand
second = s;
secAngle = 90- second*(360/60);
[xsec, ysec]= polar2xy(0.85, secAngle);
plot([0 xsec], [0 ysec], 'm:','linewidth',2)
%end % while ends
end
%--------------------------------------------------------
function drawClockFace
%close all
axis([-1.2 1.2 -1.2 1.2])
axis square equal
hold on
theta= 0;
for k= 0:59
[xX,yY]= polar2xy(1.05,theta);
plot(xX,yY,'k*')
[x,y]= polar2xy(0.9,theta);
if ( mod(k,5)==0 ) % hour mark
plot(x,y,'<')
else % minute mark
plot(x,y,'r*')
end
theta= theta + 360/60;
end
end
%-----------------------------------------------------------------
function [x, y] = polar2xy(r,theta)
rads= theta*pi/180;
x= r*cos(rads);
y= r*sin(rads);
end
This is simply taking a static data of values for the HOUR, MINUTE and SECOND arguments when i initially call my function. I tried using the following in a while loop but it didn't help much
format shortg
c=clock
clockData = fix(c)
h = clockData(4)
m = clockData(5)
s = clockData(6)
and passing the h, m and s to the respective cuntions. I want to know how I can use the TIMER obkjects and callbacks for extracting the information of [hrs mins secs] so i can compute the respective point co-ordinates in real time as the clock ticks.
I'd do a couple of things here.
First, you probably don't really need to pass the h, m, s inputs, if you are displaying current time. Add this to the top of your function to auto set these variables.
if nargin == 0
[~,~,~,h,m,s] = datevec(now);
end
Then, it is pretty easy to use a time to call this function periodically. Something like this.
t = timer;
t.ExecutionMode = 'FixedSpacing'; %Use one of the repeating modes
t.Period = 1; %Fire on 1 second intervals
t.TimerFcn = #(~,~)raviClock; %When fired, call this function (ignoring 2 inputs)
start(t); %GO!
Use docsearch timer for in depth documentation of the timer objects. But the code above should get you started.
To stop the timer, run
stop(t);
To stop the timer when the window is closed, put the stop command into the window deletion callback:
set(gcf,'DeleteFcn',#(~,~)stop(t)); %NOte: Better to explicitly use a figure number, rather than gcf.