// ==============================================================
// ORBITER MODULE: ShuttlePB
// Part of the ORBITER SDK
// Copyright (C) 2002-2004 Martin Schweiger
// All rights reserved
//
// ShuttlePB.cpp
// Control module for ShuttlePB vessel class
//
// Notes:
// This is an example for a "minimal" vessel implementation which
// only overloads the clbkSetClassCaps method to define vessel
// capabilities and otherwise uses the default VESSEL class
// behaviour.
// ==============================================================
#define STRICT
#define ORBITER_MODULE
#include "orbitersdk.h"
#include "MyVessel.h"
#include "DeltaGlider.h"
#include "AAP.h"
#include "MFDButton.h"
#include "Horizon.h"
#include "InstrHsi.h"
#include "InstrAoa.h"
#include "InstrVs.h"
#include "RcsDial.h"
#include "AtctrlDial.h"
#include "NavButton.h"
#include "ElevTrim.h"
#include "Airbrake.h"
#include "UndockBtn.h"
#include "HudBtn.h"
#include "GearLever.h"
#include "NconeLever.h"
#include "FuelMfd.h"
#include "ThrottleMain.h"
#include "ThrottleHover.h"
#include "ThrottleScram.h"
#include "GimbalCtrl.h"
#include "SwitchArray.h"
#include "AirlockSwitch.h"
#include "Wheelbrake.h"
#include "MwsButton.h"
#include "ScnEditorAPI.h"
#include "DlgCtrl.h"
#include "meshres.h"
#include <stdio.h>
#include <math.h>
//=========================================================
// Vessel Animations
//=========================================================
void MyVessel::DefineAnimations()
{
//ANIMATIONCOMPONENT_HANDLE parent;
//static UINT gear_groups[2] = {5,6};
//static MGROUP_ROTATE gear (
// 0,
// gear_groups,
// 2,
// _V(0,-1.0,8.5),
// _V(1,0,0),
// (float)(0.45*PI)
//);
//static UINT wheel_groups[2] = {10,11};
//wheel = new MGROUP_ROTATE (
// 0,
// wheel_groups,
// 2,
// _V(0,-1.0,6.5),
// _V(1,0,0),
// (float)(2*PI)
//);
//anim_gear = CreateAnimation (0.0);
//parent = AddAnimationComponent (anim_gear, 0, 1, &gear);
//anim_wheel = CreateAnimation (0.0);
//AddAnimationComponent (anim_wheel, 0, 1, wheel, parent);
}
//=========================================================
// Vessel Capabilities
//=========================================================
void MyVessel::clbkSetClassCaps (FILEHANDLE cfg)
{
// vessel caps definitions
}
//=========================================================
// Vessel Load and Save Parameters
//=========================================================
void MyVessel::clbkLoadStateEx (FILEHANDLE scn, void *status)
{
char *line; while (oapiReadScenario_nextline (scn, line))
{
if (!strnicmp (line, "MYPARAM", 7))
{
sscanf (line+7, "%lf", &myparam);
}
else
{
ParseScenarioLineEx (line, status);
}
}
}
void MyVessel::clbkSaveState (FILEHANDLE scn)
{
VESSEL3::clbkSaveState (scn);
oapiWriteScenario_float (scn, "MYPARAM", myparam);
}
//=========================================================
// Animation Template
//=========================================================
void MyVessel::Timestep (double simt)
{
//if (gear_status == CLOSING || gear_status == OPENING)
//{
// double da = oapiGetSimStep() * gear_speed;
// if (gear_status == CLOSING)
// {
// if (gear_proc > 0.0)
// gear_proc = max (0.0, gear_proc-da);
// else
// gear_status = CLOSED;
// }
// else
// {
// // door opening
// if (gear_proc < 1.0)
// gear_proc = min (1.0, gear_proc+da);
// else
// gear_status = OPEN;
// }
// SetAnimation (anim_gear, gear_proc);
//}
}
//=========================================================
// Load and Delete Module Stuff
//=========================================================
DLLCLBK void InitModule (HINSTANCE hModule)
{
// perform global module initialisation here
}
DLLCLBK void ExitModule (HINSTANCE hModule)
{
// perform module cleanup here
}
//=========================================================
// Load and Delete Vessel Stuff
//=========================================================
DLLCLBK VESSEL *Init (OBJHANDLE hvessel, int flightmodel)
{
return new MyVessel (hvessel, flightmodel);
}
DLLCLBK void Exit (VESSEL *vessel)
{
if (vessel)
delete (MyVessel*)vessel;
}
// ==============================================================
// Some vessel parameters
// ==============================================================
const double PB_SIZE = 322.5; // mean radius [m]
const VECTOR3 PB_CS = {10.5,15.0,5.8}; // x,y,z cross sections [m^2]
const VECTOR3 PB_PMI = {2.28,2.31,0.79};// principal moments of inertia (mass-normalised) [m^2]
const VECTOR3 PB_RD = {0.025,0.025,0.02};//{0.05,0.1,0.05}; // rotation drag coefficients
const double PB_EMPTYMASS = 150000000.0; // empty vessel mass [kg]
const double PB_FUELMASS = 750.0; // max fuel mass [kg]
const double PB_ISP = 5e4; // fuel-specific impulse [m/s]
const VECTOR3 PB_TDP[3] = {{0,-1.5,2},{-1,-1.5,-1.5},{1,-1.5,-1.5}}; // touchdown points [m]
const VECTOR3 PB_COP = {0,0,0};//{0,0,-0.1}; // centre of pressure for airfoils [m]
const double PB_VLIFT_C = 2.0; // chord length [m]
const double PB_VLIFT_S = 2.0; // wing area [m^2]
const double PB_VLIFT_A = 2.5; // wing aspect ratio
const double PB_HLIFT_C = 2.0; // chord length [m]
const double PB_HLIFT_S = 1.5; // wing area [m^2]
const double PB_HLIFT_A = 2.0; // wing aspect ratio
const double PB_MAXMAINTH = 1.047e10;
const double PB_MAXRETROTH = 1.047e10;
const double PB_MAXHOVERTH = 3.0e9;
const double PB_MAXRCSTH = 6.3e5;
const VECTOR3 PB_DOCK_POS = {0,1.3,-1}; // docking port location [m]
const VECTOR3 PB_DOCK_DIR = {0,1,0}; // docking port approach direction
const VECTOR3 PB_DOCK_ROT = {0,0,-1}; // docking port alignment direction
// Calculate lift coefficient [Cl] as a function of aoa (angle of attack) over -Pi ... Pi
// Implemented here as a piecewise linear function
double LiftCoeff (double aoa)
{
int i;
const int nlift = 9;
static const double AOA[nlift] = {-180*RAD,-60*RAD,-30*RAD,-1*RAD,15*RAD,20*RAD,25*RAD,60*RAD,180*RAD};
static const double CL[nlift] = { 0, 0, -0.1, 0, 0.2, 0.25, 0.2, 0, 0};
static const double SCL[nlift] = {(CL[1]-CL[0])/(AOA[1]-AOA[0]), (CL[2]-CL[1])/(AOA[2]-AOA[1]),
(CL[3]-CL[2])/(AOA[3]-AOA[2]), (CL[4]-CL[3])/(AOA[4]-AOA[3]),
(CL[5]-CL[4])/(AOA[5]-AOA[4]), (CL[6]-CL[5])/(AOA[6]-AOA[5]),
(CL[7]-CL[6])/(AOA[7]-AOA[6]), (CL[8]-CL[7])/(AOA[8]-AOA[7])};
for (i = 0; i < nlift-1 && AOA[i+1] < aoa; i++);
return CL[i] + (aoa-AOA[i])*SCL[i];
}
// ==============================================================
// Shuttle-PB class interface
// ==============================================================
class ShuttlePB: public VESSEL3 {
public:
ShuttlePB (OBJHANDLE hVessel, int flightmodel);
~ShuttlePB ();
void clbkSetClassCaps (FILEHANDLE cfg);
private:
static void vlift (VESSEL *v, double aoa, double M, double Re,
void *context, double *cl, double *cm, double *cd);
static void hlift (VESSEL *v, double aoa, double M, double Re,
void *context, double *cl, double *cm, double *cd);
// transformations for control surface animations
static MGROUP_ROTATE trans_Laileron, trans_Raileron;
static MGROUP_ROTATE trans_Lelevator, trans_Relevator;
};
ShuttlePB::ShuttlePB (OBJHANDLE hVessel, int flightmodel)
: VESSEL3 (hVessel, flightmodel)
{
}
ShuttlePB::~ShuttlePB ()
{
}
// animation transformation definitions
static UINT GRP_LWING = 2;
static UINT GRP_RWING = 3;
static VECTOR3 LWING_REF = {-1.3,-0.725,-1.5};
static VECTOR3 LWING_AXIS = {-0.9619,-0.2735,0};
static VECTOR3 RWING_REF = {1.3,-0.725,-1.5};
static VECTOR3 RWING_AXIS = {0.9619,-0.2735,0};
static float AILERON_RANGE = (float)(20.0*RAD);
static float ELEVATOR_RANGE = (float)(30.0*RAD);
MGROUP_ROTATE ShuttlePB::trans_Laileron (0, &GRP_LWING, 1, LWING_REF, LWING_AXIS, AILERON_RANGE);
MGROUP_ROTATE ShuttlePB::trans_Raileron (0, &GRP_RWING, 1, RWING_REF, RWING_AXIS, AILERON_RANGE);
MGROUP_ROTATE ShuttlePB::trans_Lelevator (0, &GRP_LWING, 1, LWING_REF, LWING_AXIS, -ELEVATOR_RANGE);
MGROUP_ROTATE ShuttlePB::trans_Relevator (0, &GRP_RWING, 1, RWING_REF, RWING_AXIS, ELEVATOR_RANGE);
// ==============================================================
// Overloaded callback functions
// ==============================================================
// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void ShuttlePB::clbkSetClassCaps (FILEHANDLE cfg)
{
THRUSTER_HANDLE th_main, th_retro, th_hover, th_rcs[14], th_group[4];
// physical vessel parameters
SetSize (PB_SIZE);
SetEmptyMass (PB_EMPTYMASS);
SetPMI (PB_PMI);
SetCrossSections (PB_CS);
SetRotDrag (PB_RD);
SetTouchdownPoints (PB_TDP[0], PB_TDP[1], PB_TDP[2]);
// docking port definitions
SetDockParams (PB_DOCK_POS, PB_DOCK_DIR, PB_DOCK_ROT);
// airfoil definitions
CreateAirfoil3 (LIFT_VERTICAL, PB_COP, vlift, NULL, PB_VLIFT_C, PB_VLIFT_S, PB_VLIFT_A);
CreateAirfoil3 (LIFT_HORIZONTAL, PB_COP, hlift, NULL, PB_HLIFT_C, PB_HLIFT_S, PB_HLIFT_A);
// control surface animations
UINT anim_Laileron = CreateAnimation (0.5);
UINT anim_Raileron = CreateAnimation (0.5);
UINT anim_elevator = CreateAnimation (0.5);
AddAnimationComponent (anim_Laileron, 0, 1, &trans_Laileron);
AddAnimationComponent (anim_Raileron, 0, 1, &trans_Raileron);
AddAnimationComponent (anim_elevator, 0, 1, &trans_Lelevator);
AddAnimationComponent (anim_elevator, 0, 1, &trans_Relevator);
// aerodynamic control surface defintions
CreateControlSurface (AIRCTRL_ELEVATOR, 1.5, 0.7, _V( 0,0,-2.5), AIRCTRL_AXIS_XPOS, anim_elevator);
CreateControlSurface (AIRCTRL_AILERON, 1.5, 0.25, _V( 1,0,-2.5), AIRCTRL_AXIS_XPOS, anim_Laileron);
CreateControlSurface (AIRCTRL_AILERON, 1.5, 0.25, _V(-1,0,-2.5), AIRCTRL_AXIS_XNEG, anim_Raileron);
// propellant resources
PROPELLANT_HANDLE hpr = CreatePropellantResource (PB_FUELMASS);
// main engine
th_main = CreateThruster (_V(0,0,-4.35), _V(0,0,1), PB_MAXMAINTH, hpr, PB_ISP);
CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
AddExhaust (th_main, 8, 1, _V(0,0.3,-4.35), _V(0,0,-1));
PARTICLESTREAMSPEC contrail_main = {
0, 15.0, 46, 200, 0.15, 1.0, 5, 38.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
PARTICLESTREAMSPEC::ATM_PLOG, 1e9, 1
};
PARTICLESTREAMSPEC exhaust_main = {
0, 7.0, 20, 200, 0.05, 0.1, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
};
AddExhaustStream (th_main, _V(0,43,-384.7), &contrail_main);
AddExhaustStream (th_main, _V(0,43,-384.7), &exhaust_main);
AddExhaustStream (th_main, _V(0,-18,-384.7), &contrail_main);
AddExhaustStream (th_main, _V(0,-18,-384.7), &exhaust_main);
// retro engine
th_retro = CreateThruster (_V(0,0,-4.35), _V(0,0,-1), PB_MAXMAINTH, hpr, PB_ISP);
CreateThrusterGroup (&th_retro, 1, THGROUP_RETRO);
AddExhaust (th_retro, 8, 1, _V(0,0.3,-4.35), _V(0,0,-1));
PARTICLESTREAMSPEC contrail_retro = {
0, 12.0, 16, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
};
PARTICLESTREAMSPEC exhaust_retro = {
0, 2.0, 20, 200, 0.05, 0.1, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
};
AddExhaustStream (th_retro, _V(-27.5,16.40206,353.5885), &contrail_main);
AddExhaustStream (th_retro, _V(-27.5,16.40206,353.5885), &exhaust_main);
AddExhaustStream (th_retro, _V(27.5,16.40206,353.5885), &contrail_main);
AddExhaustStream (th_retro, _V(27.5,16.40206,353.5885), &exhaust_main);
// hover engine
th_hover = CreateThruster (_V(0,-1.5,0), _V(0,1,0), PB_MAXHOVERTH, hpr, PB_ISP);
CreateThrusterGroup (&th_hover, 1, THGROUP_HOVER);
AddExhaust (th_hover, 30, 2.1, _V(-49.96603,6.653036,276.5305), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(49.96603,6.653036,276.5305), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(49.96603,6.653036,258.0454), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(-49.96603,6.653036,258.0454), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(-100.2151,6.653036,5.876923), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(-76.65325,6.653036,6.04678), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(100.2151,6.653036,5.876923), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(76.65325,6.653036,6.04678), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(48.3807,-24,-229.6315), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(48.39203,-24,-211.1653), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(-48.3807,-24,-229.6315), _V(0,-1,0));
AddExhaust (th_hover, 30, 2.1, _V(-48.39203,-24,-211.1653), _V(0,-1,0));
PARTICLESTREAMSPEC contrail_hover = {
0, 5.0, 8, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 20,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
};
PARTICLESTREAMSPEC exhaust_hover = {
0, 2.0, 10, 200, 0.05, 0.05, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
};
AddExhaustStream (th_hover, _V(-49.96603,6.653036,276.5305), &contrail_hover);
AddExhaustStream (th_hover, _V(49.96603,6.653036,276.5305), &contrail_hover);
AddExhaustStream (th_hover, _V(-49.96603,6.653036,276.5305), &exhaust_hover);
AddExhaustStream (th_hover, _V(49.96603,6.653036,276.5305), &exhaust_hover);
AddExhaustStream (th_hover, _V(-49.96603,6.653036,258.0454), &contrail_hover);
AddExhaustStream (th_hover, _V(49.96603,6.653036,276.5305), &contrail_hover);
AddExhaustStream (th_hover, _V(49.96603,6.653036,258.0454), &exhaust_hover);
AddExhaustStream (th_hover, _V(-49.96603,6.653036,258.0454), &exhaust_hover);
AddExhaustStream (th_hover, _V(-100.2151,6.653036,5.876923), &contrail_hover);
AddExhaustStream (th_hover, _V(76.65325,6.653036,6.04678), &contrail_hover);
AddExhaustStream (th_hover, _V(-76.65325,6.653036,6.04678), &exhaust_hover);
AddExhaustStream (th_hover, _V(100.2151,6.653036,5.876923), &exhaust_hover);
AddExhaustStream (th_hover, _V(100.2151,6.653036,5.876923), &contrail_hover);
AddExhaustStream (th_hover, _V(-76.65325,6.653036,6.04678), &contrail_hover);
AddExhaustStream (th_hover, _V(76.65325,6.653036,6.04678), &exhaust_hover);
AddExhaustStream (th_hover, _V(-100.2151,6.653036,5.876923), &exhaust_hover);
AddExhaustStream (th_hover, _V(48.3807,-24,-229.6315), &contrail_hover);
AddExhaustStream (th_hover, _V(-48.3807,-24,-229.6315), &contrail_hover);
AddExhaustStream (th_hover, _V(48.3807,-24,-229.6315), &exhaust_hover);
AddExhaustStream (th_hover, _V(-48.3807,-24,-229.6315), &exhaust_hover);
AddExhaustStream (th_hover, _V(48.39203,-24,-211.1653), &contrail_hover);
AddExhaustStream (th_hover, _V(-48.39203,-24,-211.1653), &contrail_hover);
AddExhaustStream (th_hover, _V(48.39203,-24,-211.1653), &exhaust_hover);
AddExhaustStream (th_hover, _V(-48.39203,-24,-211.1653), &exhaust_hover);
// RCS engines
th_rcs[ 0] = CreateThruster (_V( 1,0, 3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 1] = CreateThruster (_V( 1,0, 3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 2] = CreateThruster (_V(-1,0, 3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 3] = CreateThruster (_V(-1,0, 3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 4] = CreateThruster (_V( 1,0,-3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 5] = CreateThruster (_V( 1,0,-3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 6] = CreateThruster (_V(-1,0,-3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 7] = CreateThruster (_V(-1,0,-3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 8] = CreateThruster (_V( 1,0, 3), _V(-1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[ 9] = CreateThruster (_V(-1,0, 3), _V( 1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[10] = CreateThruster (_V( 1,0,-3), _V(-1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[11] = CreateThruster (_V(-1,0,-3), _V( 1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[12] = CreateThruster (_V( 0,0,-3), _V(0,0, 1), PB_MAXRCSTH, hpr, PB_ISP);
th_rcs[13] = CreateThruster (_V( 0,0, 3), _V(0,0,-1), PB_MAXRCSTH, hpr, PB_ISP);
th_group[0] = th_rcs[0];
th_group[1] = th_rcs[2];
th_group[2] = th_rcs[5];
th_group[3] = th_rcs[7];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);
th_group[0] = th_rcs[1];
th_group[1] = th_rcs[3];
th_group[2] = th_rcs[4];
th_group[3] = th_rcs[6];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);
th_group[0] = th_rcs[0];
th_group[1] = th_rcs[4];
th_group[2] = th_rcs[3];
th_group[3] = th_rcs[7];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);
th_group[0] = th_rcs[1];
th_group[1] = th_rcs[5];
th_group[2] = th_rcs[2];
th_group[3] = th_rcs[6];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);
th_group[0] = th_rcs[0];
th_group[1] = th_rcs[4];
th_group[2] = th_rcs[2];
th_group[3] = th_rcs[6];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);
th_group[0] = th_rcs[1];
th_group[1] = th_rcs[5];
th_group[2] = th_rcs[3];
th_group[3] = th_rcs[7];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);
th_group[0] = th_rcs[8];
th_group[1] = th_rcs[11];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);
th_group[0] = th_rcs[9];
th_group[1] = th_rcs[10];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);
th_group[0] = th_rcs[8];
th_group[1] = th_rcs[10];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);
th_group[0] = th_rcs[9];
th_group[1] = th_rcs[11];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);
CreateThrusterGroup (th_rcs+12, 1, THGROUP_ATT_FORWARD);
CreateThrusterGroup (th_rcs+13, 1, THGROUP_ATT_BACK);
// camera parameters
SetCameraOffset (_V(0,1.478645,379.1345));
// associate a mesh for the visual
AddMesh ("Repaint NJ");
}
// ==============================================================
// Airfoil lift/drag functions
// ==============================================================
void ShuttlePB::vlift (VESSEL *v, double aoa, double M, double Re,
void *context, double *cl, double *cm, double *cd)
{
static const double clp[] = { // lift coefficient from -pi to pi in 10deg steps
-0.1,-0.5,-0.4,-0.1,0,0,0,0,0,0,0,0,0,0,-0.2,-0.6,-0.6,-0.4,0.2,0.5,0.9,0.8,0.2,0,0,0,0,0,0,0,0,0,0.1,0.4,0.5,0.3,-0.1,-0.5
};
static const double aoa_step = 10.0*RAD;
double a, fidx, saoa = sin(aoa);
a = modf((aoa+PI)/aoa_step, &fidx);
int idx = (int)(fidx+0.5);
*cl = clp[idx]*(1.0-a) + clp[idx+1]*a; // linear interpolation
*cm = 0.0; //-0.03*sin(aoa-0.1);
*cd = 0.03 + 0.4*saoa*saoa; // profile drag
*cd += oapiGetInducedDrag (*cl, 1.0, 0.5); // induced drag
*cd += oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04); // wave drag
}
void ShuttlePB::hlift (VESSEL *v, double aoa, double M, double Re,
void *context, double *cl, double *cm, double *cd)
{
static const double clp[] = { // lift coefficient from -pi to pi in 45deg steps
0,0.4,0,-0.4,0,0.4,0,-0.4,0,0.4
};
static const double aoa_step = 45.0*RAD;
double a, fidx;
a = modf((aoa+PI)/aoa_step, &fidx);
int idx = (int)(fidx+0.5);
*cl = clp[idx]*(1.0-a) + clp[idx+1]*a; // linear interpolation
*cm = 0.0;
*cd = 0.03;
*cd += oapiGetInducedDrag (*cl, 1.5, 0.6); // induced drag
*cd += oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04); // wave drag
}
// ==============================================================
// API callback interface
// ==============================================================
// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
return new ShuttlePB (hvessel, flightmodel);
}
// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
if (vessel) delete (ShuttlePB*)vessel;
}