SDK Question CentreOfMass asylum

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
10,002
Reaction score
4,418
Points
203
Location
Toulouse
Hello, :hello:

Working on the Lunar Lander, I'm trying to shift the centre of mass when it is "attached" (the tug and the lander are only 1 Orbiter vessel) with the DM tug stage. :coffee:


So I'm trying this, but it doesn't change anything :

Code:
VECTOR3 CoM = _V(0,-5,0);
ShiftCentreOfMass (CoM);

(I'm using the Y axis, that's normal)

The "Yellow box" in planetarium mode is still at _V(0,0,0) and there is no change in the vessel behaviour when using the thrusters. :dry:

ShiftCG moves the centre of mass to the desired location, but also moves the thrusters references. :facepalm:

So I wonder if ShiftCentreOfMass is useful to something, and if I have to use ShiftCG and then move the thrusters locations to their original reference points (that's going to be a pain !). :idk:

Thanks, :tiphat:

I made a search on the forum and found some relevant topics, but no one actually gives the answers...
 
Have been trying to keep track of the COG position by checking the touchdown points (at least in NTR source code), but so far this stuff evaded my understanding... You have my empathy, but not an answer, sorry...
 
I fear this is going to be a major developpement problem, no realism without CoM shifting :(

Also, why Centre of Mass and Center of Gravity ? Is it the same thing, physically speaking ? :idk: :beathead:
 
I fear this is going to be a major developpement problem, no realism without CoM shifting :(

Also, why Centre of Mass and Center of Gravity ? Is it the same thing, physically speaking ? :idk: :beathead:

It is not, there is a subtle difference, since gravity is not uniform.
 
This, found in another addon source code, give different results :

Code:
ShiftCentreOfMass(comshift*-1.0);
comshift=_V(0,-3,0);
ShiftCentreOfMass(comshift);

The camera view is locked at the center of mass. Zooming in and out changes nothing, the mesh has still the same size. Switching to internal view causes CTD. :idk:
 
Like Alice said: "This is getting curiouser and curiouser". Wonder if the stock DG pilot could come to our rescue?
 
Here's what I get for the "switching to internal view (F1) CTD bug" :

Code:
>	ntdll.dll!7c911230() 	
 	[Les frames ci-dessous sont peut-être incorrects et/ou manquants, aucun symbole chargé pour ntdll.dll]	
 	ntdll.dll!7c97c943() 	
 	ntdll.dll!7c96db9c() 	
 	ntdll.dll!7c97cd11() 	
 	ntdll.dll!7c97df66() 	
 	ntdll.dll!7c95a5d0() 	
 	ddraw.dll!736c5aaa() 	
 	ddraw.dll!736da91a() 	
 	msvcr80.dll!78134c39() 	
 	msvcr80.dll!78134d83() 	
 	dinput.dll!721f59bc() 	
 	orbiter.exe!004b1c5b() 	
 	orbiter.exe!00419c3c() 	
 	orbiter.exe!0041c377() 	
 	orbiter.exe!0041c5e6() 	
 	orbiter.exe!004d34ef() 	
 	kernel32.dll!7c816d4f() 	
 	kernel32.dll!7c8399f3()
 
ShiftCG moves the CoM, the mesh(es), the thrusters positions, the docking ports, the attachment points, the light sources positions and the camera position. The mesh and everything will move in the global position, but not in the local position.

ShiftCenterOfMass moves the CoM only. The mesh and everything will stay at the same global position, but will move in the local position.
 
ShiftCenterOfMass moves the CoM only. The mesh and everything will stay at the same global position, but will move in the local position.

That's probably what I don't get.

What is "moving in the local position" and "moving in the global position" in Orbiter ?

Global = relative to the Sun and Local = relative to the local GBody ? :idk:
 
The "Yellow box" in planetarium mode is still at _V(0,0,0) and there is no change in the vessel behaviour when using the thrusters. :dry:
I think you are missing the fact that the centre of mass of any vessel is always at it's origin. In other words, in the local vessel reference frame, the centre of mass is always at _V(0,0,0). From the SDK:
Note that in Orbiter, a vessel's CG coincides by definition always with the origin (0,0,0) of its local reference frame.

When you do a ShiftCentreOfMass, the vessel's global position is moved by the amount specified by the shift vector (the shift vector is in the local vessel reference frame). Since all the meshes, thrusters, etc, are defined relative to the local vessel reference frame, if you do not shift them then, in the global reference frame, they will move along with with the centre of mass. The effect is just like picking the whole ship up and instantly moving it by some distance.

When you do a ShiftCG, the vessel's global position is moved by the amount specified by the shift vector, just like with ShiftCentreOfMass. ShiftCG moves all the other parts of the vessel (meshes, thrusters etc) in the opposite direction by the same amount. In the global frame, the centre of mass has moved but the meshes, thrusters, etc, haven't. This means that the position of the mesh relative to other vessels remains unchanged. I suspect that this is the function you want to use, based on the description of your goals in your original post.

Bibi Uncle has the functions confused. From the SDK:
The shift of meshes (and any other reference positions defined in the local vessel frame, such as docking ports, etc.) is not performed by this function but must be executed separately. A more convenient way to implement a transition of the centre of mass is the function ShiftCG, which automatically takes care of translating meshes, docking ports, etc.
 
Thanks a lot. I think I got it.

So, to be very basic :

- ShiftCentreOfMass = Mere teleportation of the vessel.

- ShiftCG = Teleportation of the "logical ship", but not of the mesh ("visual ship").

Both could work, and both require to "manually" shift the references of everything.

ShiftCenterOfMass : we can warp the vessel x meters forward, then use ShiftMesh to shift the mesh 5 meters backwards. But we have to re-set all the thrusters, cameras & co... so that they fit with the mesh.

ShiftCG : we warp the vessel x meters forward, but this time we don't have to use ShiftMesh, as the mesh "stays behind". We also have to re-set everything.

So no "easy solution", correct me if I'm wrong... :hmm:
 
ShiftCG : we warp the vessel x meters forward, but this time we don't have to use ShiftMesh, as the mesh "stays behind". We also have to re-set everything.
This is the list from the SDK of things ShiftCG that moves:
  • Calls ShiftCentreOfMass (+shift) to align the vessel's global position with the new CG position.
  • Calls ShiftMeshes (-shift) to compensate the mesh positions
  • Applies equivalent shift to all
    • thruster positions,
    • docking ports,
    • attachment points,
    • explicitly defined light source positions,
    • and to the cockpit camera position
What remains to be "reset"?
 
Nothing, I think everything is there.

Too bad there isn't a function that doesn't applies equivalent shift to all ...

(my point being to simulate a shift in the center of mass / center of gravity following a stage jettison, like it can be done with multi stage rockets, except that I wanted to keep the references (thrusters, camera, docking port) related to the last stage).

And such a function would allow to simulate the shift of CoM / CoG that happens when, for exemple, the Space Shuttle burns the fuel in the external tank (the Shuttle-Tank CoM/CoG closes from the Shuttle CoM/CoG, as the tank gets lighter and lighter).
 
Last edited:
Too bad there isn't a function that doesn't applies equivalent shift to all ...
There is such a function - it is called "ShiftCentreOfMass" - but based on your comments below, I don't think that is what you want to use.

(my point being to simulate a shift in the center of mass / center of gravity following a stage jettison, like it can be done with multi stage rockets, except that I wanted to keep the references (thrusters, camera, docking port) related to the last stage).
I'm sorry, I don't understand. "Last stage" = "upper stage"? If so, you want ShiftCG for that.

And such a function would allow to simulate the shift of CoM / CoG that happens when, for exemple, the Space Shuttle burns the fuel in the external tank (the Shuttle-Tank CoM/CoG closes from the Shuttle CoM/CoG, as the tank gets lighter and lighter).
Again, use ShiftCG.

Do you understand what is meant by my previous post: "ShiftCG...In the global frame, the centre of mass has moved but the meshes, thrusters, etc, haven't"? Do you understand the difference between the local vessel reference frame and the global reference frame? Do you understand that if you move something in the local vessel reference frame it does not move in the global reference frame if the origin of the local vessel reference frame moves the opposite way? And therefore it does not move relative to other objects in the sim?

I'm sorry if I'm not communicating this very well...
 
Could you define "global" and "local" frames in simple words ? Thanks. I don't get what those two concepts really refer to. For me, "global" is a coordinate system (cartesian ?) centered on the Sun, and "local" a coordinate system (cartesian ?) centered on the local vessel reference point (which is the CoG ?).

Here is a schema that depicts :

1) The spacecraft in its "default configuration" (no tug)
2) What I'd like to have in "tug configuration"
3) What I get using ShiftCG (and why I have to move the (RCS) thrusters back to their positions (aligned with the mesh).

CoG.jpg


The under pic shows the "tug configuration" :

11_06_19_00-20-40_LM3.jpg
 
3) What I get using ShiftCG (and why I have to move the (RCS) thrusters back to their positions (aligned with the mesh).

CoG.jpg
This is strange, as thrusters should be moved with with the mesh, according to the SDK, what tblaxland noted:
  • Calls ShiftMeshes (-shift) to compensate the mesh positions
  • Applies equivalent shift to all
    • thruster positions,
    • docking ports,
    • attachment points,
    • explicitly defined light source positions,
    • and to the cockpit camera position
This means all the thrusters defined for the vessel should have been moved by the same offset and to the same position as was mesh, so like in your point 2).
 
Ok, that's what I was suspecting. The (-shift) offset apply only on the mesh. :yes:

Can someone try this out to confirm ?

I wouldn't be too surprised if there was a nasty bug lurking around there... :shifty:

---------- Post added at 06:06 PM ---------- Previous post was at 04:47 PM ----------

Here's a demonstration :

ShiftCG is at the end of clbkSetClassCaps

From the compilation of this sample :

Code:
// ==============================================================
//                 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"

// ==============================================================
// Some vessel parameters
// ==============================================================
const double  PB_SIZE       = 3.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  = 500.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  = 3e4;             
const double  PB_MAXHOVERTH = 1.5e4;
const double  PB_MAXRCSTH   = 2e2;

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);
    void clbkPostStep(double simt, double simdt, double mjd);

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_hover, th_rcs[14], th_group[4], th_retro;

    // 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));

    th_retro = CreateThruster (_V(0,0,-4.35), _V(0,0,-1), PB_MAXMAINTH, hpr, PB_ISP);
    CreateThrusterGroup (&th_retro, 1, THGROUP_RETRO);

    PARTICLESTREAMSPEC contrail_main = {
        0, 5.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_main = {
        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_main, _V(0,0.3,-10), &contrail_main);
    AddExhaustStream (th_main, _V(0,0.3,-5), &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, 8, 1, _V(0,-1.5,1), _V(0,-1,0));
    AddExhaust (th_hover, 8, 1, _V(0,-1.5,-1), _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, 2,
        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(0,-3, 1), &contrail_hover);
    AddExhaustStream (th_hover, _V(0,-3,-1), &contrail_hover);
    AddExhaustStream (th_hover, _V(0,-2, 1), &exhaust_hover);
    AddExhaustStream (th_hover, _V(0,-2,-1), &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,0.8,0));

    // associate a mesh for the visual
    AddMesh ("ShuttlePB");

    SetNosewheelSteering(true);
    [B]ShiftCG (_V(0,0,-5));[/B]
}

// ==============================================================
// 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
// ==============================================================
void ShuttlePB::clbkPostStep(double simt, double simdt, double mjd)
{
OBJHANDLE h_me = NULL;
h_me = GetHandle();

VESSEL* v = oapiGetVesselInterface(h_me);


double a = 0;
double b = 0;
double c = 0;

double tlse_long = 1.443364;
double tlse_lat = 43.604388;

v->GetEquPos(a,b,c);

double diff_long = a*DEG-tlse_long;
double diff_lat = b*DEG-tlse_lat;

double circo_loc = (2 * PI * (cos(b) * 6.37101e6))/360;
double circo = (2*PI*6.37101e6)/360;

sprintf(oapiDebugString(), "X %.3f Y %.3f", -diff_lat*circo, diff_long*circo_loc);

}
// --------------------------------------------------------------
// 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;
}
I get this :

11_06_22_20-02-02_PB1.jpg
 
Last edited:
Yes, this has happened to me as well when I tried to do CG shifting using that function. I thought the error was on my part somewhere.

Maybe this should be raised as an API bug issue?

Edit: I found a post in the Orbiter Project section by kwan3217. Perhaps it could get more attention.

http://www.orbiter-forum.com/project.php?issueid=428
 
Last edited:
Maybe this should be raised as an API bug issue?

Edit: I found a post in the Orbiter Project section by kwan3217. Perhaps it could get more attention.

http://www.orbiter-forum.com/project.php?issueid=428

If it is a bug, because it doesn't work as advertised, it should be reported as a bug in a separate report and not be attached to a feature request, which only suggests adding airfoils and control surfaces to the list of affected by ShiftCG objects/features.
 
I've changed the issue to a bug and updated the affected version to 2010-P1.
 
Back
Top