diff --git a/RoccarasoFlight/postprocessing/RCS/Functions&Files/RocketAnim.m b/RoccarasoFlight/postprocessing/RCS/Functions&Files/RocketAnim.m new file mode 100644 index 0000000000000000000000000000000000000000..8959d99f30a568d7e8d17305d6bb941e30702260 --- /dev/null +++ b/RoccarasoFlight/postprocessing/RCS/Functions&Files/RocketAnim.m @@ -0,0 +1,21 @@ +function OBJ = RocketAnim(RocketAttitude, Points, ConnList, edge, surface, alpha) +%OBJ = RocketAnim(RocketAttitude, Points, ConnList, edge, surface, alpha) +%Function for the creation of the the animated rocket, if called with +%ouptut returns the graphic object. +% INPUT: +% RocketAttitude= Attitude matrix of the rocket +% Points = Points of the rocket mesh, from the stlread function +% ConnList = Connectivity list of the rocket mesh, from the stlread function +% edge = Edge color of the rocket mesh +% surface = Face color of the rocket mesh +% alpha = Face alpha of the rocket mesh + + PointsRCKrotated = RocketAttitude'*Points'; %Mesh rotation + OBJ = triangulation(ConnList, PointsRCKrotated'); %Creation of triangulated object + OBJ = trimesh(OBJ); %Creation of the graphic object + %Object properties setting + OBJ.EdgeColor = edge; + OBJ.FaceColor = surface; + OBJ.FaceAlpha = alpha; +end + diff --git a/RoccarasoFlight/postprocessing/RCS/Functions&Files/STL2Obj.m b/RoccarasoFlight/postprocessing/RCS/Functions&Files/STL2Obj.m new file mode 100644 index 0000000000000000000000000000000000000000..71bf36f0994191cc6fdbf504109eea006e96166c --- /dev/null +++ b/RoccarasoFlight/postprocessing/RCS/Functions&Files/STL2Obj.m @@ -0,0 +1,37 @@ +function [ConnList, Points] = STL2Obj(name, type) +% [ConnList, Points] = STL2Obj(name) +%Read a STL file and return the vertex list (Points output) and the +%connectivity list (ConnList output). The points are resized, assuming that +%the units are in millimetres, and centered about the origin. + +%Stl reading +STL = stlread(name); + +%Struct extraction +ConnList = STL.ConnectivityList; +Points = STL.Points/1000; + +%Finding centre of the rocket + + +%Solid centering +dim = max(Points)/2; + +switch type + case 'r' + dim(1) = dim(1) - 0.0478568; + dim(3) = dim(3) - 0.00225635; + case 'p' + dim(3) = 0; + otherwise + dim(:) = 0; +end + +Points = Points - dim; + +Points = Points * [0, -1, 0; + 1, 0, 0; + 0, 0, 1]; +Points = Points * [1, 0, 0; + 0, 0,-1; + 0, 1, 0]; \ No newline at end of file diff --git a/RoccarasoFlight/postprocessing/RCS/Functions&Files/animateOrientation.m b/RoccarasoFlight/postprocessing/RCS/Functions&Files/animateOrientation.m new file mode 100644 index 0000000000000000000000000000000000000000..6ddfbbea7c872e5b8417d37c651070e9db1d81bb --- /dev/null +++ b/RoccarasoFlight/postprocessing/RCS/Functions&Files/animateOrientation.m @@ -0,0 +1,73 @@ +% Author: Pier Francesco Bachini +% +% This function displays a parallelepiped which has its orientation in space +% represented by the provided quaternions. +% If the quaternions are vectors all of the same length, then the +% parallelepid orientation will be animated following the quaternion data. +% NOTE: The quaternion data must be provided in x,y,z,w order + +function animateOrientation(dcm, time, video_name) + + + figure(); + view(3); + hold on; + axis equal + axis([-2 2 -2 2 -2 2]); + view(150,20); + plot3([-2 2], [0 0], [0 0], 'Color', 'blue'); % blue x + plot3([0 0], [-2 2], [0 0], 'Color', 'magenta'); % orange y + plot3([0 0], [0 0], [-2 2], 'Color', 'green'); % green z + + % Time box settings + time_elapsed = time; % Set new t0 = 0 + % time_elapsed = time - time(1); + timeBoxLocation = [.35 .8 .1 .1]; + timeBox = annotation('textbox',timeBoxLocation,'String', time_elapsed(1), 'Interpreter', 'latex'); + timeBox.FontSize = 24; + timeBox.BackgroundColor= 'w'; + OBJ = plot3(0,0,0, 'b'); + [ConnList, Points] = STL2Obj("rocket.STL", 'r'); + + if nargin > 2 %Set video settings + % High frame-rate for video + frame_rate = 5; + + % Change renderer + set(gcf, 'renderer', 'zbuffer'); + v = VideoWriter(video_name); + v.FrameRate = frame_rate; + open(v); + else + % Low frame-rate for only animation + frame_rate = 10; + end + grid on + set(gca, 'ZDir', 'reverse'); + set(gca, 'YDir', 'reverse'); + + xlabel('N') + ylabel('E') + zlabel('D') + for t = 2:(50/frame_rate):length(dcm) % 50 Hz is the frequency of NAS + R = dcm(:,:,t); + + + delete(OBJ) + OBJ = RocketAnim(R, Points, ConnList, 'none', 'k', 0.5); + formatSpec = '%.3f'; + sec = num2str(time_elapsed(t),formatSpec); + timeBox.String = sprintf('% s', sec); + drawnow + pause(0.02); + + if nargin > 2 + thisFrame = getframe(gcf); + writeVideo(v, thisFrame); + end + end + + if nargin > 2 + close(v); + end +end \ No newline at end of file diff --git a/RoccarasoFlight/postprocessing/RCS/Functions&Files/rocket.STL b/RoccarasoFlight/postprocessing/RCS/Functions&Files/rocket.STL new file mode 100644 index 0000000000000000000000000000000000000000..0162decfd81a6d96611c1393c0a586f7ed507272 Binary files /dev/null and b/RoccarasoFlight/postprocessing/RCS/Functions&Files/rocket.STL differ diff --git a/RoccarasoFlight/postprocessing/RCS/NAS quaternion.mat b/RoccarasoFlight/postprocessing/RCS/NAS quaternion.mat new file mode 100644 index 0000000000000000000000000000000000000000..5b1ec27dd377b44b5d023b506f7eeb61b42e12d3 Binary files /dev/null and b/RoccarasoFlight/postprocessing/RCS/NAS quaternion.mat differ diff --git a/RoccarasoFlight/postprocessing/RCS/descentPostProcess.m b/RoccarasoFlight/postprocessing/RCS/descentPostProcess.m index ea6b96f5ef98828373f4590a0089178befb6bb1d..a29c393d0f2b77f439c70639cd0b56fe7efe29fa 100644 --- a/RoccarasoFlight/postprocessing/RCS/descentPostProcess.m +++ b/RoccarasoFlight/postprocessing/RCS/descentPostProcess.m @@ -1,6 +1,7 @@ clear; clc; close all; %% adding path and recall data +addpath('Functions&Files') addpath("..\commonFunctions\"); main = importData('main'); @@ -40,9 +41,29 @@ xlabel('Time elapsed [s]') ylabel('Pressure altitude [m]') %% Drogue Descent Post -droguePara = descentPost(main, droguedescent, h0, 'drogue', (0.58/0.93)^2*pi, 21.95); -mainPara = descentPost(main, maindescent, h0, 'main', 7.34, 21.90); - +% droguePara = descentPost(main, droguedescent, h0, 'drogue', (0.58/0.93)^2*pi, 21.95); +% mainPara = descentPost(main, maindescent, h0, 'main', 7.34, 21.90); + +%% Attitude visualization +sensor = load('NAS quaternion.mat'); +qq = sensor.sensorTot_NoPitot; +time_qq = qq.nas.time; +qs = qq.nas.states(:,10); +qq = qq.nas.states(:,7:9); +test = vecnorm([qq, qs], 2, 2)-1; + +N = length(qs); +qs = permute(qs, [2, 3, 1]); +qq = permute(qq, [2, 3, 1]); +qv = [zeros(1,1, N), - qq(3,1,:), qq(2,1,:); + qq(3,1,:), zeros(1,1, N), - qq(1,1,:); + - qq(2,1,:), qq(1,1,:), zeros(1,1, N)]; +A_dcm = (qs.^2 - pagemtimes(qq, 'transpose', qq, 'none')) .* eye(3) + ... +2*pagemtimes(qq, 'none', qq, 'transpose') - 2 * qs.*qv; + + +% A_dcm = repmat(eye(3), [1 1 10]); +animateOrientation(A_dcm, time_qq); function para = descentPost(main, desc, h0, name, S, M) diff --git a/RoccarasoFlight/postprocessing/RCS/lol.avi b/RoccarasoFlight/postprocessing/RCS/lol.avi new file mode 100644 index 0000000000000000000000000000000000000000..62496eece41c0f8914eda08fe87a9ccf7c791526 Binary files /dev/null and b/RoccarasoFlight/postprocessing/RCS/lol.avi differ