-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.m
194 lines (167 loc) · 5.68 KB
/
main.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
% NOTE: This srcipt will not run as expected unless you fill in proper
% code in trajhandle and controlhandle
% You should not modify any part of this script except for the
% visualization part
%
% ***************** MEAM 620 QUADROTOR SIMULATION *****************
close all
clear
addpath('utils')
addpath('trajectories')
% You can change trajectory here
% trajectory generator
% trajhandle = @step;
trajhandle = @circle;
% trajhandle = @diamond;
% controller
controlhandle = @controller;
% real-time
real_time = true;
% *********** YOU SHOULDN'T NEED TO CHANGE ANYTHING BELOW **********
% number of quadrotors
nquad = 1;
% max time
time_tol = 25;
% parameters for simulation
params = crazyflie();
%% **************************** FIGURES *****************************
fprintf('Initializing figures...\n')
h_fig = figure;
subplot(222);
h_2d2 = gca;
axis equal
grid on
title('正视图')
view(2);
xlabel('x'); ylabel('y');
subplot(223);
h_2d3 = gca;
axis equal
grid on
title('俯视图')
view(-90, 0);
ylabel('y'); zlabel('z');
subplot(224);
h_2d4 = gca;
axis equal
grid on
title('侧视图')
view(0, 0);
xlabel('x'); zlabel('z');
subplot(221);
h_3d = gca;
axis equal
grid on
title('3D视图')
view(3);
xlabel('x [m]'); ylabel('y [m]'); zlabel('z [m]');
quadcolors = lines(nquad);
set(gcf,'Renderer','OpenGL')
%% *********************** INITIAL CONDITIONS ***********************
fprintf('Setting initial conditions...\n')
max_iter = 5000; % max iteration
starttime = 0; % start of simulation in seconds
tstep = 0.01; % this determines the time step at which the solution is given
cstep = 0.05; % image capture time interval
nstep = cstep/tstep;
time = starttime; % current time
err = []; % runtime errors
for qn = 1:nquad
% Get start and stop position
des_start = trajhandle(0, qn);
des_stop = trajhandle(inf, qn);
stop{qn} = des_stop.pos;
x0{qn} = init_state( des_start.pos, 0 );
xtraj{qn} = zeros(max_iter*nstep, length(x0{qn}));
ttraj{qn} = zeros(max_iter*nstep, 1);
end
x = x0; % state
pos_tol = 0.01;
vel_tol = 0.01;
%% ************************* RUN SIMULATION *************************
% OUTPUT_TO_VIDEO = 1;
% if OUTPUT_TO_VIDEO == 1
% v = VideoWriter('diamond.avi');
% open(v)
% end
fprintf('Simulation Running....')
% Main loop
for iter = 1:max_iter
iter;
timeint = time:tstep:time+cstep;
tic;
% Iterate over each quad
for qn = 1:nquad
% Initialize quad plot
if iter == 1
QP{qn} = QuadPlot(qn, x0{qn}, 0.1, 0.04, quadcolors(qn,:), max_iter, h_3d);
QP2{qn} = QuadPlot(qn, x0{qn}, 0.1, 0.04, quadcolors(qn,:), max_iter, h_2d2);
QP3{qn} = QuadPlot(qn, x0{qn}, 0.1, 0.04, quadcolors(qn,:), max_iter, h_2d3);
QP4{qn} = QuadPlot(qn, x0{qn}, 0.1, 0.04, quadcolors(qn,:), max_iter, h_2d4);
desired_state = trajhandle(time, qn);
QP{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time);
QP2{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time);
QP3{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time);
QP4{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time);
h_title = suptitle(sprintf('iteration: %d, time: %4.2f', iter, time));
end
% Run simulation
[tsave, xsave] = ode45(@(t,s) quadEOM(t, s, qn, controlhandle, trajhandle, params), timeint, x{qn});
x{qn} = xsave(end, :)';
% Save to traj
xtraj{qn}((iter-1)*nstep+1:iter*nstep,:) = xsave(1:end-1,:);
ttraj{qn}((iter-1)*nstep+1:iter*nstep) = tsave(1:end-1);
% Update quad plot
desired_state = trajhandle(time + cstep, qn);
QP{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time + cstep);
QP2{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time + cstep);
QP3{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time + cstep);
QP4{qn}.UpdateQuadPlot(x{qn}, [desired_state.pos; desired_state.vel], time + cstep);
set(h_title, 'String', sprintf('iteration: %d, time: %4.2f', iter, time + cstep))
% if OUTPUT_TO_VIDEO == 1
% im = frame2im(getframe(gcf));
% writeVideo(v,im);
% end
end
time = time + cstep; % Update simulation time
t = toc;
% Check to make sure ode45 is not timing out
if(t> cstep*50)
err = 'Ode45 Unstable';
break;
end
% Pause to make real-time
if real_time && (t < cstep)
pause(cstep - t);
end
% Check termination criteria
if terminate_check(x, time, stop, pos_tol, vel_tol, time_tol)
break
end
end
% if OUTPUT_TO_VIDEO == 1
% close(v);
% end
%% ************************* POST PROCESSING *************************
% Truncate xtraj and ttraj
for qn = 1:nquad
xtraj{qn} = xtraj{qn}(1:iter*nstep,:);
ttraj{qn} = ttraj{qn}(1:iter*nstep);
end
% Plot the saved position and velocity of each robot
for qn = 1:nquad
% Truncate saved variables
QP{qn}.TruncateHist();
% Plot position for each quad
h_pos{qn} = figure('Name', ['Quad ' num2str(qn) ' : position']);
plot_state(h_pos{qn}, QP{qn}.state_hist(1:3,:), QP{qn}.time_hist, 'pos', 'vic');
plot_state(h_pos{qn}, QP{qn}.state_des_hist(1:3,:), QP{qn}.time_hist, 'pos', 'des');
% Plot velocity for each quad
h_vel{qn} = figure('Name', ['Quad ' num2str(qn) ' : velocity']);
plot_state(h_vel{qn}, QP{qn}.state_hist(4:6,:), QP{qn}.time_hist, 'vel', 'vic');
plot_state(h_vel{qn}, QP{qn}.state_des_hist(4:6,:), QP{qn}.time_hist, 'vel', 'des');
end
if(~isempty(err))
error(err);
end
fprintf('finished.\n')