#include #include #define NRANSI #include "nr.h" //Numerical Recipes #include "nrutil.h" //Numerical Recipes #include "Matrix3.h" #include "Vector3.h" /**************************** CONSTANTS *******************************/ #ifndef M_PI const double M_PI=3.14159265358979323846; #endif #define ROCKET_ENGINE static const NUMWING=4; /**************************** VARIABLES *******************************/ double dxsav,*xp,**yp; //Numerical Recipes int kmax,kount; //Numerical Recipes /*********************** STRUCTURE RigidBody **************************/ struct RigidBody { Vector3 T; // Translation Vector3 V; // Velocity double M; // Total Mass double phi,theta,psi; // Eulerian Angles Vector3 omega_ego; // Egocentric Angular Velocity Vector3 Ip; // Principle Inertia // RigidBody(){}; RigidBody(const double Tx, const double Ty, const double Tz, const double Vx, const double Vy, const double Vz, const double mass, const double a1, const double a2, const double a3, const double omega_ego_x, const double omega_ego_y, const double omega_ego_z, const double Ipx, const double Ipy, const double Ipz ) :T(Tx,Ty,Tz), V(Vx,Vy,Vz), M(mass), phi(a1), theta(a2), psi(a3), omega_ego(omega_ego_x,omega_ego_y,omega_ego_z), Ip(Ipx,Ipy,Ipz) {}; }; /************************ INLINE FUNCTIONS ****************************/ static inline double RADIAN(double x) { return M_PI * x / 180; }; static inline double DEG(double x) { return x / M_PI * 180; }; static inline double DeRedundancy(double x) { return fmod(x,M_PI*2); }; /*********************** FUNCTION DEFINTIONS **************************/ Matrix3 rot_matrix_from_euler (double phi, double theta, double psi) { return Matrix3 ( cos(phi), -sin(phi), 0, sin(phi), cos(phi), 0, 0, 0, 1) * Matrix3 ( cos(theta), 0, sin(theta), 0, 1, 0, -sin(theta), 0, cos(theta)) * Matrix3 ( 1, 0, 0, 0, cos(psi), -sin(psi), 0, sin(psi), cos(psi)) ; }; static void compute_euler_angular_velocity( double &phi_dot, double &theta_dot, double &psi_dot, const double phi, const double theta, const Vector3& omega) { /* Consider that the column vector of our angular velocities is equal to omega*inverse(the axes of rotation). Matlab was used to find the inverse of the axes of rotation: >> st = sym('sin(t)'); >> ct = sym('cos(t)'); >> sp = sym('sin(p)'); >> cp = sym('cos(p)'); ---- >> inv(M) ans = [ cp/ct/(cp^2+sp^2), sp/ct/(cp^2+sp^2), 0] [ -sp/(cp^2+sp^2), cp/(cp^2+sp^2), 0] [ cp*st/ct/(cp^2+sp^2), sp*st/ct/(cp^2+sp^2), 1] We need to multiply omega times this matrix. The code would have been much cleaner if I had used more extensive matrix and vector classes (multiply vector & matrices, normalize, etc.), but we were asked to only modify this file. */ Matrix3 m; m = Matrix3( cos(phi)/cos(theta), (sin(phi)/cos(theta)), 0, -sin(phi), cos(phi), 0, (sin(theta)*cos(phi))/cos(theta), (sin(theta)*sin(phi))/cos(theta), 1); # if 1 psi_dot = m[0][0]*omega[0] + m[0][1]*omega[1] + m[0][2]*omega[2]; theta_dot = m[1][0]*omega[0] + m[1][1]*omega[1] + m[1][2]*omega[2]; phi_dot = m[2][0]*omega[0] + m[2][1]*omega[1] + m[2][2]*omega[2]; # else # include "/afs/cs.unc.edu/home/hirota/public/290/rigid/viewer/rbody.bak/answer.h" # endif } /**********************************************************************/ /******************* CLASS DEF: RigidBodyDynamics *********************/ /**********************************************************************/ class RigidBodyDynamics { private: // For ODE Int static int DerivEvalCount; static const int StateDim; // Rigid Body static Vector3 Ip; // Principle Inertia static double M; // Mass // Rotor Specific Parameters static const int NumWing; static Vector3 Rotor[NUMWING]; static double Tilt_Angle; static Vector3 WingNormal[NUMWING]; public: // member funcs static void set_rotor(const int, const Vector3); static void set_tilt_angle(const double); static RigidBody ODE_Integrate( const RigidBody& rb, const double StartTime, const double EndTime); static void compute_derivatives(double x,double y[],double dydx[]); }; /********* DECLARE/INITIALIZE STATIC VARIABLES *********/ int RigidBodyDynamics::DerivEvalCount; const RigidBodyDynamics::StateDim=12; Vector3 RigidBodyDynamics::Ip; // Principle Inertia double RigidBodyDynamics::M; // Mass //Rotor Specific Parameters const RigidBodyDynamics::NumWing=NUMWING; Vector3 RigidBodyDynamics::Rotor[NUMWING]={ Vector3(1,0,0), Vector3(-1,0,0),Vector3(0,1,0),Vector3(0,-1,0)}; double RigidBodyDynamics::Tilt_Angle=5; Vector3 RigidBodyDynamics::WingNormal[NUMWING]; /**************** FUNCTION DEFINITIONS *****************/ void RigidBodyDynamics::set_rotor( const int rotor_index, const Vector3 rotor_position) { if(rotor_index<0||rotor_index>=NumWing) { fprintf(stderr,"wrong rotor_index\n"); return; } Rotor[rotor_index]=rotor_position; } void RigidBodyDynamics::set_tilt_angle(const double a) { Tilt_Angle=a; } RigidBody RigidBodyDynamics::ODE_Integrate( const RigidBody& rb, const double StartTime, const double EndTime) { Ip = rb.Ip; M = rb.M; for(int i=0; i