Surveyor Source Code
Jump to navigation
Jump to search
// ============================================================== // ORBITER MODULE: Surveyor // Copyright (C) 2005 Kwan3217 // Released under the Gnu Free Documentation License // // Evolved from: // ORBITER MODULE: ShuttlePB // Part of the ORBITER SDK // Copyright (C) 2002-2004 Martin Schweiger // All rights reserved // // Surveyor.cpp // Control module for Surveyor vessel class // // ============================================================== #define STRICT #define ORBITER_MODULE #include "orbitersdk.h" // ============================================================== // Some vessel parameters // ============================================================== const double LANDER_EMPTY_MASS = 289.10; //Basic bus plus payload minus AMR minus retro case const double RETRO_EMPTY_MASS = 64.88; const double AMR_MASS = 3.82; const double RETRO_PROP_MASS=560.64; const double RETRO_THRUST = 39140; const double RETRO_BURNTIME = 40.5; const double RETRO_ITOT = RETRO_THRUST*RETRO_BURNTIME; const double RETRO_ISP = RETRO_ITOT/RETRO_PROP_MASS; const double RETRO_STA = -0.75; const double VERNIER_PROP_MASS = 70.98; const double VERNIER_ISP = 3200; const double VERNIER_THRUST = 463; const double VERNIER_RAD = 0.86; const double VERNIER_STA = -0.5; const double RCS_PROP_MASS=2; const double RCS_ISP = 630.0; const double RCS_THRUST = 0.25; const double RCS_RAD = 1; const double RCS_STA = -0.5; const double RCS_SPACE = 0.1; const double LEG_RAD = 1.5; const double LEG_STA =-0.6; // ============================================================== // Shuttle-PB class interface // ============================================================== class Surveyor: public VESSEL2 { public: Surveyor (OBJHANDLE hVessel, int flightmodel) : VESSEL2 (hVessel, flightmodel) {} void clbkSetClassCaps (FILEHANDLE cfg); void clbkPreStep(double SimT, double SimDT, double MJD); int clbkConsumeBufferedKey(DWORD key, bool down, char *kstate); THRUSTER_HANDLE th_vernier[3], th_retro, th_rcs[6], th_group[2]; double CalcEmptyMass(); PROPELLANT_HANDLE ph_vernier, ph_rcs, ph_retro; void SpawnObject(char* classname, char* ext, VECTOR3 ofs); void Jettison(); int status; void SetupMeshes(); void AddLanderMesh(); void AddRetroMesh(); void AddAMRMesh(); }; double Surveyor::CalcEmptyMass() { double EmptyMass=0; if(GetPropellantMass(ph_retro)>0.999*RETRO_PROP_MASS) { EmptyMass+=AMR_MASS; } if(GetPropellantMass(ph_retro)>1) { EmptyMass+=RETRO_EMPTY_MASS; } EmptyMass+=LANDER_EMPTY_MASS; return EmptyMass; } // ============================================================== // Overloaded callback functions // ============================================================== // -------------------------------------------------------------- // Set the capabilities of the vessel class // -------------------------------------------------------------- void Surveyor::clbkSetClassCaps (FILEHANDLE cfg) { // physical specs SetSize (1.0); SetPMI (_V(0.5,0.5,0.5)); SetCameraOffset (_V(0,0.8,0)); SetTouchdownPoints( _V( 0,LEG_RAD,LEG_STA), _V( sqrt(3.0)/2*LEG_RAD,-0.5*LEG_RAD,LEG_STA), _V(-sqrt(3.0)/2*LEG_RAD,-0.5*LEG_RAD,LEG_STA)); status=0; // propellant resources ph_vernier = CreatePropellantResource(VERNIER_PROP_MASS); ph_rcs = CreatePropellantResource(RCS_PROP_MASS); ph_retro = CreatePropellantResource(RETRO_PROP_MASS); th_retro = CreateThruster(_V(0.0,0.0,RETRO_STA), _V(0,0,1), RETRO_THRUST, ph_retro, RETRO_ISP); AddExhaust(th_retro, 2, 0.3); th_vernier[0] = CreateThruster(_V( 0.0*VERNIER_RAD, 1.0*VERNIER_RAD,VERNIER_STA), _V(0,0,1), VERNIER_THRUST, ph_vernier, VERNIER_ISP); th_vernier[1] = CreateThruster(_V( sqrt(3.0)/2*VERNIER_RAD,-0.5*VERNIER_RAD,VERNIER_STA), _V(0,0,1), VERNIER_THRUST, ph_vernier, VERNIER_ISP); th_vernier[2] = CreateThruster(_V(-sqrt(3.0)/2*VERNIER_RAD,-0.5*VERNIER_RAD,VERNIER_STA), _V(0,0,1), VERNIER_THRUST, ph_vernier, VERNIER_ISP); CreateThrusterGroup(th_vernier, 3, THGROUP_MAIN); for(int i=0;i<3;i++) { AddExhaust(th_vernier[i], 1, 0.1); } //Roll (Leg1) jets th_rcs[ 0] = CreateThruster (_V(-RCS_SPACE,RCS_RAD,RCS_STA), _V( 1,0,0), RCS_THRUST, ph_rcs, RCS_ISP); th_rcs[ 1] = CreateThruster (_V( RCS_SPACE,RCS_RAD,RCS_STA), _V(-1,0,0), RCS_THRUST, ph_rcs, RCS_ISP); //Leg2 jets th_rcs[ 2] = CreateThruster (_V( sqrt(3.0)/2*RCS_RAD,-0.5*RCS_RAD,RCS_STA-RCS_SPACE), _V(0, 0, 1), RCS_THRUST, ph_rcs, RCS_ISP); th_rcs[ 3] = CreateThruster (_V( sqrt(3.0)/2*RCS_RAD,-0.5*RCS_RAD,RCS_STA+RCS_SPACE), _V(0, 0,-1), RCS_THRUST, ph_rcs, RCS_ISP); //Leg3 jets th_rcs[ 4] = CreateThruster (_V(-sqrt(3.0)/2*RCS_RAD,-0.5*RCS_RAD,RCS_STA-RCS_SPACE), _V(0, 0, 1), RCS_THRUST, ph_rcs, RCS_ISP); th_rcs[ 5] = CreateThruster (_V(-sqrt(3.0)/2*RCS_RAD,-0.5*RCS_RAD,RCS_STA+RCS_SPACE), _V(0, 0,-1), RCS_THRUST, ph_rcs, RCS_ISP); th_group[0] = th_rcs[3]; th_group[1] = th_rcs[5]; CreateThrusterGroup (th_group, 2, THGROUP_ATT_PITCHDOWN); th_group[0] = th_rcs[2]; th_group[1] = th_rcs[4]; CreateThrusterGroup (th_group, 2, THGROUP_ATT_PITCHUP); th_group[0] = th_rcs[0]; CreateThrusterGroup (th_group, 1, THGROUP_ATT_BANKRIGHT); th_group[0] = th_rcs[1]; CreateThrusterGroup (th_group, 1, THGROUP_ATT_BANKLEFT); th_group[0] = th_rcs[3]; th_group[1] = th_rcs[4]; CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT); th_group[0] = th_rcs[2]; th_group[1] = th_rcs[5]; CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT); for (int i=0;i<6;i++) { AddExhaust(th_rcs[i],0.1,0.05); } // visual specs SetupMeshes(); } void Surveyor::clbkPreStep(double SimT, double SimDT, double MJD) { SetEmptyMass(CalcEmptyMass()); double P,Y,R; P=GetThrusterGroupLevel(THGROUP_ATT_PITCHUP)-GetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN); Y=GetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT)-GetThrusterGroupLevel(THGROUP_ATT_YAWLEFT); R=GetThrusterGroupLevel(THGROUP_ATT_BANKRIGHT)-GetThrusterGroupLevel(THGROUP_ATT_BANKLEFT); sprintf(oapiDebugString(),"Pitch %f Yaw %f Roll %f",P,Y,R); SetThrusterDir(th_vernier[0],_V(0.087*R,0,1)); SetThrusterDir(th_vernier[1],_V(0,0,1.0+0.05*P-0.05*Y)); SetThrusterDir(th_vernier[2],_V(0,0,1.0+0.05*P+0.05*Y)); if(status == 1 && GetPropellantMass(ph_retro)<1) { //Jettison the spent main retro Jettison(); } if(status == 0 && GetPropellantMass(ph_retro)<0.999*RETRO_PROP_MASS) { //Jettison the AMR if the retro has started burning Jettison(); //Relight the retro if needed SetThrusterLevel(th_retro,1); } } void Surveyor::AddLanderMesh() { VECTOR3 ofs = _V(0,0.3,0); AddMesh("Surveyor-Lander",&ofs); } void Surveyor::AddRetroMesh() { VECTOR3 ofs = _V(0,0,-0.5); AddMesh("Surveyor-Retro",&ofs); } void Surveyor::AddAMRMesh() { VECTOR3 ofs = _V(0,0,-0.8); AddMesh("Surveyor-AMR",&ofs); } void Surveyor::SetupMeshes() { ClearMeshes(); switch(status) { case 0: AddAMRMesh(); case 1: AddRetroMesh(); case 2: AddLanderMesh(); } } void Surveyor::SpawnObject(char* classname, char* ext, VECTOR3 ofs) { VESSELSTATUS vs; char name[256]; GetStatus(vs); Local2Rel (ofs, vs.rpos); vs.eng_main = vs.eng_hovr = 0.0; vs.status = 0; strcpy (name, GetName()); strcat (name, ext); oapiCreateVessel (name, classname, vs); } void Surveyor::Jettison() { switch(status) { case 0: status=1; SpawnObject("Surveyor_AMR","-AMR",_V(0,0,-0.8)); break; case 1: status=2; SpawnObject("Surveyor_Retro","-Retro",_V(0,0,-0.5)); break; } SetupMeshes(); } int Surveyor::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) { if (!down) return 0; // only process keydown events if (KEYMOD_SHIFT (kstate)) { } else { // unmodified keys switch (key) { case OAPI_KEY_L: // Fire Retro SetThrusterLevel(th_retro,1); return 1; } } return 0; } // ============================================================== // API callback interface // ============================================================== // -------------------------------------------------------------- // Vessel initialisation // -------------------------------------------------------------- DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel) { return new Surveyor (hvessel, flightmodel); } // -------------------------------------------------------------- // Vessel cleanup // -------------------------------------------------------------- DLLCLBK void ovcExit (VESSEL *vessel) { if (vessel) delete (Surveyor*)vessel; }