Edit me

Animation file for Goddard rocket problems, the animation is saved as a gif. Input is the ocp.solve() object, filename for the gif, and total time the gif should take. E.g. animateRocket(ocpSol, 'filename.gif', 6).

% Author: Dennis Edblom
function animateRocket(ocpSol, filename, time)

t = [];
X = [];
U = [];
for nPhase = 1:length(ocpSol)
    % Get variales
    t = [t; ocpSol(nPhase).NumericalResults.Independent'];
    X = [X; ocpSol(nPhase).NumericalResults.State'];
    U = [U; ocpSol(nPhase).NumericalResults.Control'];
end
% adding an extra frame with
t = [t;t(end)];
X = [X;X(end,:)];
U = [U;0];


% state vectors
h = X(:,2);

nImages = length(X);
% dt = t(2)-t(1);
dt = time/(nImages);


tmin = min(t);
tmax = max(t);
umin = min(U);
umax = max(U);
xmin = min(X);
xmax = max(X);
hmin = min(X(:,2));
hmax = max(X(:,2));
xl = (hmax-hmin)*0.2;
scale = 0.015*(hmax-hmin);
ymax = hmax + scale*7; % Rocket visible at the top
ymin = hmin - scale*4; % Thrust vector visible
nx = 3;
nu = 1;
xlabels = {'v', 'h', 'm'};

% Create the plot
% The first image will be initialized twice which removes some stutter in
% the gif image.
fig = figure('Position',[50 50 1000*0.8 800*0.8]);
set(fig,'color','w');

for k=1:nx
    % Create subplot
    subplot(nx+nu, 2, k*2)
    xlim([tmin,tmax]);
    ylim([xmin(k),xmax(k)]);
    % Add labels
    ylabel(xlabels{k});
    xlabel('Time [t]');

end
% Control
subplot(nx+nu, 2, 8)
xlim([tmin,tmax]);
ylim([umin,umax]);
% Add labels
ylabel('Control F');
xlabel('Time [t]');


subplot(4,2,[1 3 5 7]);
plot([-xl,xl],[hmin hmin],'k','LineWidth',2) %ground
xlim([-xl,xl]); % TODO make scalable with hmax
ylim([ymin,ymax]);
ylabel('Height h');
% first pos
Y = h(1);
T = U(1)/umax;
engine = patch(scale*[0 0 0.5 -0.5], Y + scale*[2 2 0 0], 'b');
body = patch(scale*[-0.5 0.5 0.5 -0.5] , Y + scale*(3 + [2 2 -2 -2]),'b');
nose = patch(scale*[0 0 0.5 -0.5], Y + scale*(5 + [1 1 0 0]), 'b');
exhaust1 = patch(T*scale*[-0.35 0.35 0.35 -0.35] , Y + scale*(T*[0 0 -2 -2]), 'r');
exhaust2 = patch(T*scale*[0.75 -0.75 0 0], Y - scale*(T*2 - T*[0 0 -1 -1]), 'r');



t_text = text(-0.8*xl,hmax,'t = 0');
frame = getframe(fig);
im{1} = frame2im(frame);
% Animation Loop
for i = 1:nImages
    for k=1:nx
        % Create subplot
        subplot(nx+nu, 2, k*2)

        plot(t(1:i), X(1:i,k),'LineWidth',2)
        xlim([tmin,tmax]);
        ylim([xmin(k),xmax(k)]);

        % Add labels
        ylabel(xlabels{k});
        xlabel('Time [t]');

    end
    % Plot control
    subplot(nx+nu, 2, 8)
    stairs(t(1:i), U(1:i),'LineWidth',2)
    xlim([tmin,tmax]);
    ylim([umin,umax]);
    % Add labels
    ylabel('Control F');
    xlabel('Time [t]');

    % Remove old cart
    delete(engine);
    delete(body);
    delete(nose);
    delete(exhaust1);
    delete(exhaust2);
    delete(t_text);

    subplot(4,2,[1 3 5 7]);
    % Draw rocket
    xlim([-xl,xl]);
    ylim([ymin,ymax]);
    ylabel('Height h');


    Y = h(i);
    T = U(i)/umax;
    engine = patch(scale*[0 0 0.5 -0.5], Y + scale*[2 2 0 0], 'b');
    body = patch(scale*[-0.5 0.5 0.5 -0.5] , Y + scale*(3 + [2 2 -2 -2]),'b');
    nose = patch(scale*[0 0 0.5 -0.5], Y + scale*(5 + [1 1 0 0]), 'b');
    exhaust1 = patch(T*scale*[-0.35 0.35 0.35 -0.35] , Y + scale*(T*[0 0 -2 -2]), 'r');
    exhaust2 = patch(T*scale*[0.75 -0.75 0 0], Y - scale*(T*2 - T*[0 0 -1 -1]), 'r');

    t_text = text(-0.8*xl,hmax,sprintf('t = %1.3f',t(i)));
    frame = getframe(fig);
    im{i} = frame2im(frame);
end


for i = 1:nImages
    [A,map] = rgb2ind(im{i},256);
    if i == 1
        imwrite(A,map,filename,'gif','LoopCount',Inf,'DelayTime',0);
        imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',dt); % to remove stutter.
    elseif i == nImages
        imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',1);
    else
        imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',dt);
    end
end
end