presenting motion of random walkers in matlab - matlab

I have simulated some random walkers. I used
plot(xb,yb,'b--o')
to show particles in each step. I saw a code in below link with beautiful particles with tail which moves in a blur way. Is there a way which I could my random walkers the same as the walkers in the link in mat lab? Could anyone tell me which should I use instead of the plot function I used?
beautiful particles
The code I tried:
clear all
close all
lbox=20;
%random fluctuation
eta = (2.*pi).*.1;
vs=0.02;
n=200;
birdl=[1:n];
axis([0 lbox 0 lbox])
axis('square')
hold on
xb=rand(n,1).*lbox; %first possition
yb=rand(n,1).*lbox; %first possition
vxb = 1;
vyb = 1;
for steps=1:5000;
xb = xb + vxb;
yb = yb+ vyb;
for bird1 = 1:n;
%periodic boundary condition
if(xb(bird1)<0);xb(bird1)=xb(bird1)+lbox; end
if (yb(bird1)<0);yb(bird1)=yb(bird1)+lbox;end
if (xb(bird1)>lbox);xb(bird1)=xb(bird1)-lbox;end
if (yb(bird1)>lbox);yb(bird1)=yb(bird1)-lbox;end
end
ang=eta.*(rand(n,1)-0.5);
vxb = vs.*cos(ang);
vyb = vs.*sin(ang);
cla
set(gcf,'doublebuffer','on')
plot(xb,yb,'.b')
%quiver(xb,yb,vxb,vyb,'b')
drawnow
end

If you want to create a sort of trail of where the particles have recently been, you can store the previous nStore plots and change their color so that older plots gradually darken and fade to black (alpha transparency like in your sample isn't possible with line objects in MATLAB). Here's a reworking of your code (with a few other improvements, like replacing the inner boundary condition loop with indexing):
clear all
close all
lbox = 20;
%random fluctuation
eta = (2.*pi).*1;
vs = 0.05;
n = 200;
set(gcf, 'doublebuffer', 'on', 'Color', 'k');
set(gca, 'Visible', 'off');
axis([0 lbox 0 lbox])
axis('square')
hold on
xb = rand(n, 1).*lbox; %first possition
yb = rand(n, 1).*lbox; %first possition
vxb = 1;
vyb = 1;
hList = [];
nStore = 30;
cMap = [zeros(nStore+1, 1) linspace(1, 0, nStore+1).' zeros(nStore+1, 1)];
for steps = 1:200
xb = xb + vxb;
yb = yb + vyb;
%periodic boundary condition
index = (xb < 0);
xb(index) = xb(index) + lbox;
index = (yb < 0);
yb(index) = yb(index) + lbox;
index = (xb > lbox);
xb(index) = xb(index) - lbox;
index = (yb > lbox);
yb(index) = yb(index) - lbox;
ang = eta.*(rand(n,1)-0.5);
vxb = vs.*cos(ang);
vyb = vs.*sin(ang);
h = plot(xb, yb, '.g', 'MarkerSize', 12);
if (numel(hList) == nStore)
delete(hList(nStore));
hList = [h hList(1:end-1)];
else
hList = [h hList];
end
set(hList, {'Color'}, num2cell(cMap(1:numel(hList), :), 2));
drawnow
end
And here's an animation:
I created the animation by adding the following code:
% After the drawnow...
frame = getframe(gca);
im = frame2im(frame);
imind(:, :, 1, steps) = uint8(rgb2ind(im, cMap, 'nodither'));
% After the loop...
imwrite(imind(:, :, 1, 1:2:end), cMap, 'randwalk.gif', ...
'Loopcount', Inf, 'DelayTime', 0);
I had to trim out some frames to make the gif smaller.

My shot at "nicer" random walk:
clear all
close all
lbox=20;
figure('Color',[0 0 0])
%random fluctuation
eta = (2.*pi).*1;
vs=0.02;
n=300;
birdl=[1:n];
axis([0 lbox 0 lbox])
axis('square')
hold on
xb=rand(n,1).*lbox; %first possition
yb=rand(n,1).*lbox; %first possition
vxb = 1;
vyb = 1;
for steps=1:5000;
xb = xb + vxb;
yb = yb+ vyb;
for bird1 = 1:n;
%periodic boundary condition
if (xb(bird1)<0);xb(bird1)=xb(bird1)+lbox; end
if (yb(bird1)<0);yb(bird1)=yb(bird1)+lbox;end
if (xb(bird1)>lbox);xb(bird1)=xb(bird1)-lbox;end
if (yb(bird1)>lbox);yb(bird1)=yb(bird1)-lbox;end
end
ang=eta.*(rand(n,1)-0.5);
vxb = vs.*cos(ang);
vyb = vs.*sin(ang);
cla
set(gca,'Color',[0 0 0]);
set(gcf,'doublebuffer','on')
set(gca,'YTick',[]);
set(gca,'XTick',[]);
plot(xb,yb,'.g','markersize',10)
% this should draw lines, but its slow and not as neat as a web app
% plot([xb xb-vxb*5]',[yb yb-vyb*5]','g')
drawnow
end

Related

Model Predictive Control (MPC) for electromechanical system

So I want to create an MPC controller for my seesaw-cart system. All the "grunt work" (getting equations of motion, state-space representation etc.) has been done, so I went into coding into MATLAB.
Here's the following:
clc; clear all; close all;
yalmip('clear')
%% Parameters
a = 0.116553; % height of center mass of the pendulum, [m]
b = 0; % position of the weight B on the vertical rod (not taken into consideration)
c = 0.180047; % height of the center of mass of the cart, [m]
mA = 4.839; % mass of the pendulum, [kg]
mB = 0; % not taken into consideration
mC = 1; % mass of the cart, [kg]
g = 9.81; % gravity factor, [m/s^2]
kappa = 0.1; % coefficient of the viscous damping in the rotational joint
J = 0.68; % moment of inertia of the pendulum, [kgm^2]
Ke = 0.077; % motor constant of the EM force, [Vs^-1]
Kt = 0.077; % proportional moment motor constant, [NmA^-1]
Ra = 2.6; % electrical resistance, [ohm]
p = 1/3.71; % motor gearbox ratio
r = 7.7*10^(-3); % effective radius of the motor shaft, [m]
%% Defining the continuous system
A = [0 1 0 0;
(a*mA*g+b*mB*g)/(J+mB*b^2), -kappa/(J+mB*b^2), -mC*g/(J+mB*b^2), -Ke*Kt/(mC*(J+mB*b^2)*Ra*p^2*r^2);
0 0 0 1;
(a*mA*g+b*mB*g)/(J+mB*b^2)-g, -kappa*c/(J+mB*b^2), -c*mC*g/(J+mB*b^2), -(J+mB*b^2+mC*c^2)*Ke*Kt/(mC*(J+mB*b^2)*Ra*p^2*r^2)];
B = [0;
Kt/(mC*(J+mB*b^2)*Ra*p^2*r^2);
0;
(J+mB*b^2+mC*c^2)*Kt/(mC*(J+mB*b^2)*Ra*p^2*r^2)];
C = eye(4); % check
D = 0;
sysC = ss(A, B, C, D);
%% Defining the discrete system
Ts = 10e-3; % sample time
sysD = c2d(sysC,Ts); % discrete time
Ad = sysD.A;
Bd = sysD.B;
%% Formulation of the MPC problem
[nx, nu] = size(B);
Q = eye(nx);
R = eye(nu);
N = 1000;
% Input constraints, maximum and minimum voltage
umin = -6;
umax = 6;
% Still have to find this
xmin = [-deg2rad(10); -deg2rad(50); -0.5; -10];
xmax = [deg2rad(10); deg2rad(50); 0.5; 10];
uVar = sdpvar(repmat(nu,1,N),ones(1,N));
xVar = sdpvar(repmat(nx,1,N+1),ones(1,N+1));
constraints = [];
objective = 0;
ops = sdpsettings('verbose',0,'solver','quadprog');
for k = 1:N
objective = objective + xVar{k}'*Q*xVar{k} + uVar{k}*R*uVar{k};
constraints = [constraints, xVar{k+1} == Ad*xVar{k} + Bd*uVar{k}];
constraints = [constraints , umin <= uVar{k} <= umax , xmin <= xVar{k+1} <= xmax];
end
controller = optimizer(constraints, objective,ops,xVar{1},[uVar{:}]);
%% Simulation of the linearized model
nSim = 1000;
x0 = [0; 0; 0; 0.05]; % initial values, check
time = 0:Ts:nSim*Ts;
x = zeros(nx,nSim+1);
u = zeros(nu,nSim);
x(:,1) = x0;
for i = 2:nSim+1
disp(strcat(['Sim iter: ', num2str(i-1)]));
uOpt = controller{x(:,i-1)};
u(:,i-1) = uOpt(:,1);
x(:,i) = Ad*x(:,i-1) + Bd*u(:,i-1);
end
%% Plot
figure;
subplot(4,1,1);
plot(time,x(1,:), 'LineWidth', 2, 'Color', 'red'); grid; ylabel('{\theta} (rad)'); title('States');
subplot(4,1,2);
plot(time,x(2,:), 'LineWidth', 2, 'Color', [0.6350, 0.0780, 0.1840]); grid; ylabel('$\dot{\theta}$ (rad/s)', 'Interpreter', 'latex');
subplot(4,1,3);
plot(time,x(3,:), 'LineWidth', 2, 'Color', [0.4940, 0.1840, 0.5560]); grid; ylabel('s (m)');
subplot(4,1,4);
plot(time,x(4,:), 'LineWidth', 2, 'Color',[0, 0.7, 0.9]); grid; ylabel('$\dot{s}$ (m/s)', 'Interpreter', 'latex'); xlabel('t (s)');
figure;
stairs(time(1:end-1),u, 'LineWidth', 2, 'Color',[1, 0.647, 0]); grid; ylabel('Ua (V)'); xlabel('t (s)'); title('Input');
So I was wondering for any suggestions on improvements. What can I do to make my regulator more robust?
Here are my outputs for this particular code:
Note: I'm using YALMIP for the optimization part of the MPC.
You lose feasibility after a few iterations,
sol =
struct with fields:
yalmipversion: '20210331'
matlabversion: '9.9.0.1524771 (R2020b) Update 2'
yalmiptime: 0.1159
solvertime: 0.2331
info: 'Infeasible problem (QUADPROG))'
problem: 1
K>> i
i =
4
Your MPC controller is thus badly tuned (too short horizon being the obvious start)
Also, your definition of u is weird as it has length 4 instead of length N (thus meaning you have two trailing variables in u which never are used, leading to them having value Nan when you look at them)
There are numerous MPC-examples in the tutorials which you should be able to use directly
https://yalmip.github.io/example/standardmpc/
YALMIP-specific question are better asked at
https://github.com/yalmip/YALMIP/discussions
https://groups.google.com/g/yalmip

Airfoil plot issue

I am having an issue with plotting my airfoil on matlab. It appears that there are some abberations with only one or two values. I have checked again and again with the formulas so they should be good. I have not converted to degrees so that's not the issue.
%% setup
clc
clear all
%type of airfoil
typeNACA = '2312';
%extract values of airfoil type
M = str2double(typeNACA(1)); % max camber %chord
P = str2double(typeNACA(2)); % chordwise position
Thmax = str2double(typeNACA(3:4));
M=M/100;
P=P/100
Thmax=Thmax/100;
% gridpoints
gridpoints = 1000;
% Airfoil grid
x = linspace(0,1,gridpoints);
%camber equations
%yc1(x) = (M/P^2)*(2*P*x-x^2);
%yc(x) = (M/(1-P)^2*(1-2*P+2*Px-x^2); % (for P =< x <1)
%dyc1 = (2*M/P^2)*(P-x)
%dyc2 = (2*M)/(1-P^2)*(P-x)
%Camber and gradient
yc = ones(gridpoints,1);
dyc= ones(gridpoints,1);
theta=ones(gridpoints,1);
for i=1:gridpoints
if (x(i) >= 0 && x(i) < P)
yc(i) = (M/P^2)*(2*P*x(i)-x(i)^2); % (for 0 =< x < P)
dyc(i)= ((2*M)/P^2)*(P - x(i)); %dyc/dx
elseif (x(i) >= P && x(i) <= 1) % (for P =< x <1)
yc(i)=(M/(1-P)^2)*(1-2*P+2*P*x(i)-x(i)^2);
dyc(i) = (2*M)/((1-P)^2*(P-x(i)));
end
theta(i) = atan(dyc(i)); %angle theta
end
% thickness coefficients
a0 = 0.2969;
a1 = -0.126;
a2 = -0.3516;
a3 = 0.2843;
a4 = -0.1036; % -0.1015 for open TE -0.1036 for closed TE
%thickness distribution
yt = ones(gridpoints,1);
for i=1:1:gridpoints
yt(i) = (Thmax/0.2)*(a0*x(i)^0.5 + a1*x(i) + a2*x(i)^2 + a3*x(i)^3 + a4*x(i)^4);
end
% Upper surface points
xu = ones(gridpoints,1);
yu = ones(gridpoints,1);
for i= 1:gridpoints
xu(i) = x(i) - yt(i)*sin(theta(i));
yu(i) = yc(i) + yt(i)*cos(theta(i));
end
% Lower surface points
xl = ones(gridpoints,1);
yl = ones(gridpoints,1);
for i=1:1:gridpoints
xl(i) = x(i) + yt(i)*sin(theta(i));
yl(i) = yc(i) - yt(i)*cos(theta(i));
end
%PLOT
f1 = figure(1);
hold on; grid on;
axis equal
plot(xu,yu,'r';
plot(xl,yl,'b');
well! The first problem is you've forgotten the closing parenthesis in the second line from the end. But if you want me to check your code, I need to have your typeNACA() function .m file to revise it. Or u can post its code here.
%PLOT
f1 = figure(1);
hold on; grid on;
axis equal
plot(xu,yu,'r';
plot(xl,yl,'b');

Plot the MajorAxisLength and the MinorAxisLength - Matlab

I found this script below in https://blogs.mathworks.com/steve/2010/07/30/visualizing-regionprops-ellipse-measurements/
I wish to plot also the MajorAxisLength and the MinorAxisLength, how can I do it?
Script:
url = 'https://blogs.mathworks.com/images/steve/2010/rice_binary.png';
bw = imread(url);
imshow(bw)
s = regionprops(bw, 'Orientation', 'MajorAxisLength', ...
'MinorAxisLength', 'Eccentricity', 'Centroid');
imshow(bw)
hold on
phi = linspace(0,2*pi,50);
cosphi = cos(phi);
sinphi = sin(phi);
for k = 1:length(s)
xbar = s(k).Centroid(1);
ybar = s(k).Centroid(2);
a = s(k).MajorAxisLength/2;
b = s(k).MinorAxisLength/2;
theta = pi*s(k).Orientation/180;
R = [ cos(theta) sin(theta)
-sin(theta) cos(theta)];
xy = [a*cosphi; b*sinphi];
xy = R*xy;
x = xy(1,:) + xbar;
y = xy(2,:) + ybar;
plot(x,y,'r','LineWidth',2);
end
hold off
You have a lot of unnecessary code in what you posted. I don't think you actually attempted to adjust it for what you say you want to plot. Given what you said you are trying to do in the comments, I think this is the code you want in order to plot the Major Axis Length vs. Minor Axis Length
url = 'https://blogs.mathworks.com/images/steve/2010/rice_binary.png';
bw = imread(url);
s = regionprops(bw, 'Orientation', 'MajorAxisLength', ...
'MinorAxisLength', 'Eccentricity', 'Centroid'); %Get region props
Major=zeros(size(s));
Minor=zeros(size(s));
for k = 1:length(s)
Major(k)= s(k).MajorAxisLength; %get your y values
Minor(k)= s(k).MinorAxisLength; %get your x values
end
figure %create a new figure because you don't want to plot on top of the image
plot(Minor, Major, 'o') %plot
xlabel('Minor Axis Length')
ylabel('Major Axis Length')

Graphically represent density of iterations

Kind all,
I am working in MATLAB and I'm using Monte Carlo techniques to fit a model. Basically, if we assume that my model is a simple function such as
y=m*x^2+c
And that both my parameters m and c vary between 0.5 and 10, I may randomly draw from such a parameter space and obtain each time a new y. If I plot all my realizations of y I obtain something similar to the following figure:
Is there a way to represent the DENSITY of the realizations? I mean, is there a way (instead of plotting all the realizations) to obtain some kind of contour plot that lies between the minimum of my iterations and the maximum for which its color represents the amount of realizations that fall within a certain interval?
Thanks all!
This isn't very pretty, but you could vary the parameters and play with the scatter/plotting, to make it a bit more visually appealing.
Also I assumed a gaussian distribution instead of your random one (totally random coloring will give you a uniform density). Also this code could be optimized for speed.
n = 1000;
l = 100;
x = linspace(1, 10, l);
y = repmat(x.^2, n, 1);
c = repmat(normrnd(1, 1, n, 1), 1, l);
m = repmat(normrnd(1, 1, n, 1), 1, l);
y = y.*m + c;
p = plot(y', '.');
figure; hold on;
for i = 1:l
[N,edges,bin] = histcounts(y(:, i));
density = N./sum(N);
c = zeros(n, 3);
for j = 1:n
c(j, :) = [1-density(bin(j))/max(density), 1-density(bin(j))/max(density), 1-density(bin(j))/max(density)];
end
scatter(ones(n, 1)*x(i),y(:, i),[],c,'filled');
end
Gives
This creates a histogram of y values for every position in x, then calculates the probability density for each y-value and colors in the points. Here, the y-values for every position x are normalized individually, to color the points according to the overall density of the plot you need to renormalize.
You can calculate y for discrete points of x, while setting random values for c and m. Then using hist function you can find a "not-normalized density" of function values for a given x. You can then normalize it to get a real density of the values, so that the overall area under the distribution curve sums up to 1.
In order to visualize it, you construct a mesh grid [X, Y] along the values of x and y and put the density values as Z. Now you can either plot the surf or its contour plot.
Here is the code:
clear;
n = 1000000; %number of simulation steps
%parameter ranges
m_min = 0.5; m_max = 10;
c_min = 0.5; c_max = 10;
%x points
x_min = 1; x_max = 4; x_count = 100;
x = linspace(x_min, x_max, x_count);
x2 = x.^2;
y_min = 0; y_max = m_max*x_max*x_max + c_max; y_step = 1;
m = rand(n, 1)*(m_max - m_min) + m_min;
c = rand(n, 1)*(c_max - c_min) + c_min;
c = repmat(c, 1, x_count);
y = m*x2 + c;
x_step = (x_max- x_min)/(x_count-1);
[X, Y] = meshgrid(x_min:x_step:x_max, y_min-y_step:y_step:y_max+y_step);
Z = zeros(size(X));
bins = y_min:y_step:y_max;
for i=1:x_count
[n_hist,y_hist] = hist(y(:, i), bins);
%add zeros on both sides to close the profile
n_hist = [0 n_hist 0];
y_hist = [y_min-y_step y_hist y_max+y_step];
%normalization
S = trapz(y_hist,n_hist); %area under the bow
n_hist = n_hist/S; %scaling of the bow
Z(:, i) = n_hist';
end
surf(X, Y, Z, 'EdgeColor','none');
colormap jet;
xlim([x_min x_max]);
ylim([y_min y_max]);
xlabel('X');
ylabel('Y');
figure
contour(X,Y,Z, 20);
colormap jet;
colorbar;
grid on;
title('Density as function of X');
xlabel('X');
ylabel('Y');
Another interesting view is a plot of each section depending on the x value:
Here is the code for this plot:
clear;
n = 1000000; %number of simulation steps
%parameter ranges
m_min = 0.5; m_max = 10;
c_min = 0.5; c_max = 10;
%x points
x_min = 1; x_max = 4; x_count = 12;
x = linspace(x_min, x_max, x_count);
x2 = x.^2;
m = rand(n, 1)*(m_max - m_min) + m_min;
c = rand(n, 1)*(c_max - c_min) + c_min;
c = repmat(c, 1, x_count);
y = m*x2 + c;
%colors for the plot
colors = ...
[ 0 0 1; 0 1 0; 1 0 0; 0 1 1; 1 0 1; 0 0.75 0.75; 0 0.5 0; 0.75 0.75 0; ...
1 0.50 0.25; 0.75 0 0.75; 0.7 0.7 0.7; 0.8 0.7 0.6; 0.6 0.5 0.4; 1 1 0; 0 0 0 ];
%container for legend entries
legend_list = cell(1, x_count);
for i=1:x_count
bin_number = 30; %number of histogramm bins
[n_hist,y_hist] = hist(y(:, i), bin_number);
n_hist(1) = 0; n_hist(end) = 0; %set first and last values to zero
%normalization
S = trapz(y_hist,n_hist); %area under the bow
n_hist = n_hist/S; %scaling of the bow
plot(y_hist,n_hist, 'Color', colors(i, :), 'LineWidth', 2);
hold on;
legend_list{i} = sprintf('Plot of x = %2.2f', x(i));
end
xlabel('y');
ylabel('pdf(y)');
legend(legend_list);
title('Density depending on x');
grid on;
hold off;

Fixed light source in MATLAB

I want to draw an earth in Matlab with a fixed light source around it, that way I can observe earth's rotation with dayside and nightside . But now I get stuck on how to use the function light.
My Matlab code is as follows:
figure
load('topo.mat','topo','topomap1');
[x,y,z] = sphere(50);
cla reset
axis square off
props.AmbientStrength = 0.1;
props.DiffuseStrength = 1;
props.SpecularColorReflectance = .5;
props.SpecularExponent = 20;
props.SpecularStrength = 1;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.FaceLighting = 'phong';
props.Cdata = topo;
h=surface(x,y,z,props);
h1=light('position',[-1 0 0],'Style','infinite');
% light('position',[-1.5 0.5 -0.5], 'color', [.6 .2 .2]);
set(gcf,'color',[1 1 1]);
el=0;
for az=0:10:300
view(az, el)
drawnow;
end