Difference between revisions of "Surveyor Source Code"
Jump to navigation
Jump to search
m |
m |
||
Line 1: | Line 1: | ||
− | + | // ============================================================== | |
− | // ============================================================== | + | // ORBITER MODULE: Surveyor |
− | // ORBITER MODULE: Surveyor | + | // Copyright (C) 2005 Kwan3217 |
− | // Copyright (C) 2005 Kwan3217 | + | // Released under the Gnu Free Documentation License |
− | // Released under the Gnu Free Documentation License | + | // |
− | // | + | // Evolved from: |
− | // Evolved from: | + | // ORBITER MODULE: ShuttlePB |
− | // ORBITER MODULE: ShuttlePB | + | // Part of the ORBITER SDK |
− | // Part of the ORBITER SDK | + | // Copyright (C) 2002-2004 Martin Schweiger |
− | // Copyright (C) 2002-2004 Martin Schweiger | + | // All rights reserved |
− | // All rights reserved | + | // |
− | // | + | // Surveyor.cpp |
− | // Surveyor.cpp | + | // Control module for Surveyor vessel class |
− | // Control module for Surveyor vessel class | + | // |
− | // | + | // ============================================================== |
− | // ============================================================== | + | |
− | + | #define STRICT | |
− | #define STRICT | + | #define ORBITER_MODULE |
− | #define ORBITER_MODULE | + | |
− | + | #include "orbitersdk.h" | |
− | #include "orbitersdk.h" | + | |
− | + | // ============================================================== | |
− | // ============================================================== | + | // Some vessel parameters |
− | // Some vessel parameters | + | // ============================================================== |
− | // ============================================================== | + | const double LANDER_EMPTY_MASS = 289.10; //Basic bus plus payload minus AMR minus retro case |
− | 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 RETRO_EMPTY_MASS = 64.88; | + | const double AMR_MASS = 3.82; |
− | const double AMR_MASS = 3.82; | + | |
− | + | const double RETRO_PROP_MASS=560.64; | |
− | const double RETRO_PROP_MASS=560.64; | + | const double RETRO_THRUST = 39140; |
− | const double RETRO_THRUST = 39140; | + | const double RETRO_BURNTIME = 40.5; |
− | const double RETRO_BURNTIME = 40.5; | + | const double RETRO_ITOT = RETRO_THRUST*RETRO_BURNTIME; |
− | const double RETRO_ITOT = RETRO_THRUST*RETRO_BURNTIME; | + | const double RETRO_ISP = RETRO_ITOT/RETRO_PROP_MASS; |
− | const double RETRO_ISP = RETRO_ITOT/RETRO_PROP_MASS; | + | const double RETRO_STA = -0.75; |
− | const double RETRO_STA = -0.75; | + | |
− | + | const double VERNIER_PROP_MASS = 70.98; | |
− | const double VERNIER_PROP_MASS = 70.98; | + | const double VERNIER_ISP = 3200; |
− | const double VERNIER_ISP = 3200; | + | const double VERNIER_THRUST = 463; |
− | const double VERNIER_THRUST = 463; | + | const double VERNIER_RAD = 0.86; |
− | const double VERNIER_RAD = 0.86; | + | const double VERNIER_STA = -0.5; |
− | const double VERNIER_STA = -0.5; | + | |
− | + | const double RCS_PROP_MASS=2; | |
− | const double RCS_PROP_MASS=2; | + | const double RCS_ISP = 630.0; |
− | const double RCS_ISP = 630.0; | + | const double RCS_THRUST = 0.25; |
− | const double RCS_THRUST = 0.25; | + | const double RCS_RAD = 1; |
− | const double RCS_RAD = 1; | + | const double RCS_STA = -0.5; |
− | const double RCS_STA = -0.5; | + | const double RCS_SPACE = 0.1; |
− | const double RCS_SPACE = 0.1; | + | |
− | + | const double LEG_RAD = 1.5; | |
− | const double LEG_RAD = 1.5; | + | const double LEG_STA =-0.6; |
− | const double LEG_STA =-0.6; | + | |
− | + | ||
− | + | // ============================================================== | |
− | // ============================================================== | + | // Shuttle-PB class interface |
− | // Shuttle-PB class interface | + | // ============================================================== |
− | // ============================================================== | + | |
− | + | class Surveyor: public VESSEL2 { | |
− | class Surveyor: public VESSEL2 { | + | public: |
− | 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 Surveyor::CalcEmptyMass() { | ||
double EmptyMass=0; | 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 | + | // Overloaded callback functions |
− | // ============================================================== | + | // ============================================================== |
− | + | ||
− | // -------------------------------------------------------------- | + | // -------------------------------------------------------------- |
− | // Set the capabilities of the vessel class | + | // Set the capabilities of the vessel class |
− | // -------------------------------------------------------------- | + | // -------------------------------------------------------------- |
− | void Surveyor::clbkSetClassCaps (FILEHANDLE cfg) { | + | 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); | 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) { | + | 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(); | 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() { | + | void Surveyor::AddLanderMesh() { |
− | + | VECTOR3 ofs = _V(0,0.3,0); | |
− | + | AddMesh("Surveyor-Lander",&ofs); | |
− | } | + | } |
− | void Surveyor::AddRetroMesh() { | + | void Surveyor::AddRetroMesh() { |
− | + | VECTOR3 ofs = _V(0,0,-0.5); | |
− | + | AddMesh("Surveyor-Retro",&ofs); | |
− | } | + | } |
− | void Surveyor::AddAMRMesh() { | + | void Surveyor::AddAMRMesh() { |
− | + | VECTOR3 ofs = _V(0,0,-0.8); | |
− | + | AddMesh("Surveyor-AMR",&ofs); | |
− | } | + | } |
− | + | ||
− | void Surveyor::SetupMeshes() { | + | void Surveyor::SetupMeshes() { |
− | + | ClearMeshes(); | |
− | + | switch(status) { | |
− | + | case 0: | |
− | + | AddAMRMesh(); | |
− | + | case 1: | |
− | + | AddRetroMesh(); | |
− | + | case 2: | |
− | + | AddLanderMesh(); | |
− | + | } | |
− | } | + | } |
− | + | ||
− | void Surveyor::SpawnObject(char* classname, char* ext, VECTOR3 ofs) { | + | 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() { | + | void Surveyor::Jettison() { |
switch(status) { | 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) { | + | 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 | + | // API callback interface |
− | // ============================================================== | + | // ============================================================== |
− | + | ||
− | // -------------------------------------------------------------- | + | // -------------------------------------------------------------- |
− | // Vessel initialisation | + | // Vessel initialisation |
− | // -------------------------------------------------------------- | + | // -------------------------------------------------------------- |
− | DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel) | + | DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel) |
− | { | + | { |
− | + | return new Surveyor (hvessel, flightmodel); | |
− | } | + | } |
− | + | ||
− | // -------------------------------------------------------------- | + | // -------------------------------------------------------------- |
− | // Vessel cleanup | + | // Vessel cleanup |
− | // -------------------------------------------------------------- | + | // -------------------------------------------------------------- |
− | DLLCLBK void ovcExit (VESSEL *vessel) | + | DLLCLBK void ovcExit (VESSEL *vessel) |
− | { | + | { |
− | + | if (vessel) delete (Surveyor*)vessel; | |
− | } | + | } |
− |
Revision as of 02:20, 28 December 2005
// ============================================================== // 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; }