Simulate proximity operations around an asteroid.
The spacecraft has 3-axis thruster control. Ideal attitude sensing is assumed. The PID controller produces a torque vector which is applied directly to the spacecraft. The control keeps the body X axis aligned towards the asteroid as the maneuver takes place. The initial relative velocity is zero; it takes about 3 minutes to achieve the target velocity, and another few minutes for the attitude rates to settle.
The 3D plot shows the resulting trajectory along with the force vector in green and the sensor vector (body X) in red.
See also Inertias, CircularManeuver, PID3Axis, RHSRigidBody6DOF, LoadCAD, DrawCAD
Contents
-------------------------------------------------------------------------- Copyright (c) 2013-2014 Princeton Satellite Systems, Inc. All rights reserved. -------------------------------------------------------------------------- Since version 2014.1 --------------------------------------------------------------------------
% This prevents problems if d is defined as a double in the workspace %-------------------------------------------------------------------- clear d
Simulation parameters
%----------------------- periodOrbit = 60; % min nPeriods = 1; dT = 1; % s rOrbit = 500; % m el = 0; % Elevation of orbit with respect to the xy-plane thrust = 0.1; % Thrust level for the tangential burn d.mass = 20; % kg % Compute the time parameters %---------------------------- tEnd = nPeriods*periodOrbit*60; nSim = ceil(tEnd/dT); % Spacecraft model - 6U CubeSat %------------------------------ d.inertia = Inertias( d.mass, [0.3 0.2 0.1], 'box', 1 ); % kg-m^2 % State vector [r;v;q;omega] %--------------------------- x = [rOrbit;0;0; 0;0;0; 1;0;0;0;0;0;0]; % Orbit normal assuming we always start in the xy-plane %------------------------------------------------------ u = Unit(x(1:3)); az = atan2(u(2),u(1)); uT = [sin(az)*cos(el);cos(az)*cos(el);sin(el)]; % Set up the control %------------------- dC = PID3Axis; % Default data structure dC.mode = 1; % 1 = align two vectors dC.body_vector = [1;0;0]; % align X axis dC.inertia = d.inertia;
Design the maneuver
Compute the required force and impulse to achieve the desired orbital period
%--------------------- [fR, iT] = CircularManeuver( periodOrbit, rOrbit, d.mass ); fprintf('Radial force = %12.2f N\n',fR); fprintf('Tangential impulse = %12.2f Ns\n',iT);
Radial force = 0.03 N Tangential impulse = 17.45 Ns
Simulate
%--------- % Plotting vectors %----------------- xP = zeros(length(x)+7,nSim); fP = zeros(3,nSim); % Time vector %------------ t = (0:(nSim-1))*dT; for k = 1:nSim % Align with nadir - i.e. towards the asteroid %--------------------------------------------- qECIToBody = x(7:10); uR = Unit(x(1:3)); dC.eci_vector = -uR; [d.torque, dC] = PID3Axis( qECIToBody, dC ); % Find the pointing error %------------------------ body_vector_eci = QTForm( qECIToBody, dC.body_vector ); arg = body_vector_eci'*dC.eci_vector; if( abs(arg) > 1 ) arg = sign(arg); end err = acos(arg); % Burn until the tangential impulse is complete %---------------------------------------------- if( iT > 0 ) fT = thrust; iT = iT - thrust*dT; else fT = 0; end % The total force vector %----------------------- d.force = fT*uT - fR*uR; fP(:,k) = d.force; % Store for plotting %------------------- xP(:,k) = [x;d.force;d.torque;err]; % Integrate %---------- x = RK4(@RHSRigidBody6DOF,x,dT,t(k),d); end
Plot the results
%------------------ [t,tL] = TimeLabl(t); yL = {'x (km)','y (km)','z (km)','v_x (km)','v_y (km)','v_z (km)'}; Plot2D( t, xP(1:6,:), tL, yL, 'Relative State' ) yL = {'q_s', 'q_x', 'q_y', 'q_z' 'err'}; Plot2D( t, xP( [7:10 20],:), tL, yL, 'Quaternion' ); yL = {'\omega_x','\omega_y','\omega_z'}; Plot2D( t, xP(11:13,:), tL, yL, 'Attitude Rate'); yL = {'f_x (N)' 'f_y (N)' 'f_z (N)' 't_x (Nm)' 't_y (Nm)' 't_z (Nm)'}; Plot2D( t, xP(14:19,:), tL, {'Force (N)','Torque (Nm)'}, 'Force and Torque',... 'lin',{[1 2 3],[4 5 6]}); % 3D plot %-------- g = LoadCAD('Apophis.obj',[],[],160); DrawCAD( g ); set(gcf,'name','Apophis Proximity Operations') hold on plot3(xP(1,:),xP(2,:),xP(3,:)); xlabel('X (m) ') ylabel('Y (m) ') zlabel('Z (m) ') % Add the force vectors %---------------------- dN = nSim/20; j = 1:dN:nSim; fPMag = log10(Mag(fP)); fP = Unit(fP); xP0 = xP(:,j); fPs = [fP(1,:).*fPMag;fP(2,:).*fPMag;fP(3,:).*fPMag]; quiver3(xP0(1,:),xP0(2,:),xP0(3,:),fPs(1,j),fPs(2,j),fPs(3,j),0.5,'r'); % Add the sensor vectors in green %-------------------------------- sP = QTForm( xP0(7:10,:), [1;0;0] ); quiver3(xP0(1,:),xP0(2,:),xP0(3,:),sP(1,:),sP(2,:),sP(3,:),0.5,'g'); %-------------------------------------- % PSS internal file version information %--------------------------------------