Getting displacement data from acceleration in matlab - matlab

Im working on a project right now using arduino and im stuck,i didn't find a way to get the displacement data from the data i get from the 3-axis accelerometer im using this code:
clear all, clc
%delete(arduino)
com='COM_31';
delete(instrfind({'Port'},{com}));
arduino=serial(com,'BaudRate',9600);
fopen(arduino);
while(1)
donnee=fscanf(arduino,'%f\t %f\t %f'),
x=data(1); y=data(2) ;z=data(3),
plot3(x,y,z)
hold on
end
fclose(arduino);
is there a simple way i can achieve this and plot the result in 3D
thanks,

If you declare three vectors from the start and fill them with your measured data you can plot the whole trajectory.
clear all; clc
%delete(arduino)
com='COM_31';
delete(instrfind({'Port'},{com}));
arduino=serial(com,'BaudRate',9600);
fopen(arduino);
fig=figure(1);clf;
x=0;y=0;z=0;
vx=0;vy=0;vz=0;
tic
while(1)
data=fscanf(arduino,'%f\t %f\t %f');
dt = toc;tic;
vx=vx+dt*data(1);
vy=vx+dt*data(2);
vz=vz+dt*data(3);
x(end+1)=x(end)+vx*dt;
y(end+1)=y(end)+vy*dt;
z(end+1)=z(end)+vz*dt;
plot3(x,y,z)
end
fclose(arduino);

Related

Time series animation in Matlab

I am new to working with time series in Matlab and am struggling with getting this going. I have time series heat-transfer data (over a period of 20ms in steps of 1 microsecond) at these 11 locations (see code below). I am clueless as to how I could put them together to be able to generate a plot at each time step and use getframe at each timestep to make an animation. Any help on how to get started with this would be much appreciated. Here is a link to the 11 data files, providing time on column1 and heat transfer on column2: https://drive.google.com/open?id=1oDAdapqvL-blecb7BOLzxpeiJBsqLd59
Please feel free to suggest any other tools (matplotlib/plotly etc.) that may be better in this scenario as well. Thanks a ton!
close all
clear all
x1=399.5
x2=400.5
y0=0
y1=4
y2=8
y3=12
y4=16
y5=20
y6=-4
y7=-8
y8=-12
y9=-16
y10=-20
%The gauge locations for the first row will be [x1,y1], [x1,y3], [x1,y5], [x1,y6], [x1,y8],
%[x1,y10]
%The gauge locations for the second row will be [x2,y0], [x2,y2], [x2,y4], [x2,y7],
%[x2,y9]
figure
plot(x1,y1,'r.', x1,y3,'r.', x1, y5, 'r.', x1, y6, 'r.', x1, y8, 'r.', x1, y10, 'r.')
hold
plot(x2,y0,'b.', x2,y2,'b.', x2, y4, 'b.', x2, y7, 'b.', x2, y9, 'b.')
axis([390 410 -30 30])
In Matlab you can use, as you said the getFrame and writeVideo functions. Ill explain it for a very general case, which you can then apply to yours.
Let's say we have a plot that changes it's data at every iteration inside a for loop (happens frequently when solving PDEs and so on) with an exemplary function solverIteration (made up...). We are plotting a vector y over our domain x.
In order to record the video we have to do the following:
video = VideoWriter('myVideo.avi'); %Create a video object
open(video); % Open video source - restricts the use of video for your program
for m=1:K
y = solverIteration(y);
plot(x,y);
drawnow;
vidFrame = getframe(gcf);
% instead of gcf you can specify which figure you want to capture
clf;
writeVideo(video,vidFrame); % adds frames to the video
end
close(video);
This script is an example for how to record a video. There are several examples and explanations at the official matlab site.

clearing serial buffer in matlab

i am simply printing there floats form my arduino or any other serial output device... in matlab i am receiving them and plotting them. it is being printed in arduino very fast but in matlab it is slower and after a a minute or so the plot is not reacting to the numbers from arduino fast... it seams matlab is slower and it is keeping the records in buffer? how can i clear it and get the fresh data plotted?
one more thing does it make sense that matlab can't import and plot a few numbers in 100Hz? What i am doing wrong or inefficient ?
clc
clear all
h = figure(1);
set(h,'UserData',1);
s=serial('/dev/tty.usbmodem1411','BaudRate',115200);
set(s,'DataBits',8);
set(s,'StopBits',1);
fopen(s);
s.ReadAsyncMode='continuous';
readasync(s);
tStart = tic;
xplot=subplot(3,1,1);
hold on;
xlabel('time(ms)');
ylabel('X angle(deg)');
yplot=subplot(3,1,2);
hold on;
xlabel('time(ms)');
ylabel('Y angle(deg)');
zplot=subplot(3,1,3);
hold on;
xlabel('time(ms)');
ylabel('Z angle(deg)');
cont=true;
xAngle = zeros(1,1000000);
yAngle = zeros(1,1000000);
zAngle = zeros(1,1000000);
i=0;
while(true)
i=i+1;
t = toc(tStart);
%angle = fscanf(s, '%f');
[x y z] = strread(fgetl(s,s.BytesAvailable),'%f %f %f');
plot(xplot,t,x,'.');
plot(yplot,t,y,'.');
plot(zplot,t,z,'.');
drawnow;
end
fclose(s);
It is likely that the speed of the 'plot' command is the problem. Creating a new plot is a slow operation, and so after you have received a few points, the time it takes to create the plot gets large. If you want to plot "real time" data in matlab, you will need to use some methods such as discussed in this question.
You can investigate the situation by changing your loop code to read data from the device and just print the line on the screen without plotting it. I expect you will see that the numbers can be printed as fast as they are received.

Matlab cannot plot the 3D graph using "surf" command

Matlab cannot give the 3d surface plot of the following program.Matlab gives the value of all the variables in matrix form. But it cacnot plot the 3d graph using surf command. Why matlab cannot plot a 3d graph using 'surf' command in symbolic variable?? pls help me....
clear all
close all
clc
syms r
c=1;
for R=0.01:0.01:0.03
R1(c)=R;
j=1;
for l=0.3:0.01:0.4
l1(j)=l;
A=l*exp(-r^2);
B=int(A,0,inf);
B1(c,j)=B;
j=j+1;
end
c=c+1;
end
B1=real(B1)
surf(R1,l1,B1')
You just need to add these three lines after the last end:
B1=double(B1) % Converts from symbolic to numerical
[X ,Y]=meshgrid(R1,l1); % Creates a grid that is R1,l1 size, repeated
surf(R1,l1,B1') % plot!

user defined gaussian kernel

I was wondering if anyone could look at this code. I'm trying to do a 3x3 gaussian kernel without using any matlab built-in functions. (Yes I am aware of all the built in functions of gaussian and convolution ie fspecial)
the result gives me a white image instead. not sure what's the problem with it.
clc;
close all;
clear all;
img=imread('image.jpg');
figure,imshow(img);
img2=zeros(size(img)+2);
newImg=zeros(size(img));
for rgb=1:3
for x=1:size(img,1)
for y=1:size(img,2)
img2(x+1,y+1,rgb)=img(x,y,rgb);
end
end
end
for i= 1:size(img2,1)-2
for j=1:size(img2,2)-2
window=zeros(9,1);
inc=1;
for x=1:3
for y=1:3
window(inc)=img2(i+x-1,j+y-1,rgb);
inc=inc+1;
end
end
kernel=[1;2;1;2;4;2;1;2;1];
% kernel=[0;1;0;1;-4;1;0;1;0];
med=window.*kernel;
disp(med);
med=sum(med);
med=floor(med);
newImg(i,j,:)=med;
end
end
newImg=uint8(newImg);
figure,imshow(newImg);
Thanks.
I guess you should normalize the kernel. I mean, devide each element by the sum of their value (16), to make their sum equal to 1:
kernel=[1;2;1;2;4;2;1;2;1]/16;

MATLAB: Dynamic heatmap

I have 3D matrix of dimensions D x D x N. I want to create a dynamic heatmap to show how it's varying over N. Here's the MATLAB code I used to achieve this.
for n=1:N
heatmap(dynamicCov(:,:,n));
pause(0.5);
end
The issue with this code is that for each n, it opens a new figure window. I want it to be updated in the same Heatmap window. Is it possible to do that? Is there any other way to achieve this?
Thanks.
You need to use the undocumented 2nd input to HeatMap that indicates whether a plot should be created or not, and a few other Handle Graphics tricks to get the handle to the figure that is created. Something like
data = rand(20,20,10); % create test data
hmo = HeatMap(data(:,:,1),false); % create but do not plot
plot(hmo); % do the plot
allHFig = findall(0,'Type','figure'); % get handle to all open figures
hFig = allHFig(1); % we want the most recently created figure
for idx = 2:size(data,3)
hmo = HeatMap(data(:,:,idx),false); % create heatmap but do not plot
plot(hmo,hFig); % plot to our existing figure
pause(0.5);
end
I found a better and a lot simpler way of doing this. It uses built in imagesc() function instead of HeatMap() function from Bioinformatics toolbox. The code is as follows:
dynamicCov = rand(20,20,10); % create test data
N = size(dynamicCov,3);
for n=1:N
imagesc(dynamicCov(:,:,n));
colormap('copper');
colorbar;
pause(0.5);
end
Reference: http://buli.waw.pl/matlab-heatmap-colormap/