API Question ShiftCG

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Yes, you need to manually move the airfoils in exactly the opposite direction of ShiftCG.

How? So if the shiftcg is (0,-4,0). Shifts the cg -4 in the y direction. The craft should tilt that way
 

kocmolyf

Addon Developer
Addon Developer
Joined
Aug 16, 2014
Messages
95
Reaction score
1
Points
8
First you need to make sure the airfoil stays fixed to the body. ShiftCG doesn't change the airfoil position, but it *does* change most other positions (like thrusters, and the visual mesh). So if the CG moved in -4 Y, you need to move all airfoils in +4 Y so that they keep their body position.

Now, which way will the craft tilt? While flying in the atmosphere, the physics wants to keep the CG and the airfoil "in a line", so that the CG is directly in front of the airfoil in relation to the incoming air. So if you move the CG in -4 Y (and shifted the airfoil in +4 Y), the body will rotate around the airfoil so that the CG is back at 0. The CG will "travel up in Y", if that makes sense. Or you can think of the body "tilting" in the opposite direction of the shift.

Hopefully that makes sense. You should know that your questions are a bit hard to follow, because you have to be very precise when you talk about rotation and tilt. For example a counterclockwise rotation from one side is a clockwise rotation when viewed from the other side. If you could hand-draw a diagram of what you think you are doing it would be super helpful. Reposting MSL diagrams is not as useful because we already understand how MSL works; we can't see where your specific error is.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Lets forget shiftCG. But what I what the capsule to tilt back about 20 degrees . The after chute deployment shift/tilt so it is level or 90 degrees
MSLCAP_zpsjgfba7hb.jpg

change the lift function.
mslcaplift_zps5ii1uc8b.jpg

but it seems wrong
 
Last edited:

kocmolyf

Addon Developer
Addon Developer
Joined
Aug 16, 2014
Messages
95
Reaction score
1
Points
8
Interesting. Can you paste exactly the code you're using for airfoil creation and the two lift functions?
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
This is what it looks like entering earth.
MSLAIR_zpsnlvgdypw.jpg

Code:
void VLiftCoeff(double aoa, double M, double Re, double *cl, double *cm, double *cd)
{
	static const double step = RAD*15.0;
	static const double istep = 1.0 / step;
	static const int nabsc = 25;
	static const double CL[nabsc] = { 0.1, 0.17, 0.2, 0.2, 0.17, 0.1, 0, -0.11, -0.24, -0.38, -0.5, -0.5, -0.02, 0.6355, 0.63, 0.46, 0.28, 0.13, 0.0, -0.16, -0.26, -0.29, -0.24, -0.1, 0.1 };
	static const double CM[nabsc] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.002, 0.004, 0.0025, 0.0012, 0, -0.0012, -0.0007, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	// lift and moment coefficients from -180 to 180 in 15 degree steps.
	// This uses a documented lift slope of 0.0437/deg, everything else is rather ad-hoc

	aoa += PI;
	int idx = max(0, min(23, (int)(aoa*istep)));
	double d = aoa*istep - idx;
	*cl = CL[idx] + (CL[idx + 1] - CL[idx])*d;
	*cm = CM[idx] + (CM[idx + 1] - CM[idx])*d;
	*cd = 0.06 + oapiGetInducedDrag(*cl, 2.266, 0.6);
}

// 2. horizontal lift component (vertical stabiliser and body)

void HLiftCoeff(double beta, double M, double Re, double *cl, double *cm, double *cd)
{
	static const double step = RAD*22.5;
	static const double istep = 1.0 / step;
	static const int nabsc = 17;
	static const double CL[nabsc] = { 0, 0.2, 0.3, 0.2, 0, -0.2, -0.3, -0.2, 0, 0.2, 0.3, 0.2, 0, -0.2, -0.3, -0.2, 0 };

	beta += PI;
	int idx = max(0, min(15, (int)(beta*istep)));
	double d = beta*istep - idx;
	*cl = CL[idx] + (CL[idx + 1] - CL[idx])*d;
	*cm = 0.0;
	*cd = 0.02 + oapiGetInducedDrag(*cl, 1.5, 0.6);
}

Code:
CreateAirfoil(LIFT_VERTICAL, _V(0, 0.01, 0.1), VLiftCoeff, 5.5, 0, 1.27);
CreateAirfoil(LIFT_HORIZONTAL, _V(0, 0, 0.01), HLiftCoeff, 5.5, 0, 1.27);
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,342
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Your CM function for the vertical lift is not symmetric around 0° AOA.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Thanks. Any suggestion, then?

Also Told I need to rotate 180 degrees so the lift is going in the correct direction
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,342
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Thanks. Any suggestion, then?

Make sure that the following rules always apply at any AOA possible:

CL(AOA1) = -CL(-AOA1)
CM(AOA1) = -CM(-AOA1)
CD(AOA1) = CD(-AOA1)

Then, your aerodynamic definition is like expected for axial symmetric body with CP on Z axis.

When you shift the airfoil with the CoG, the forces will be like your CoG is hanging feathered on the CP.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Thanks. confused:huh:

Code:
void VLiftCoeff (double aoa, double M, double Re, double *cl, double *cm, double *cd)
{
	static const double step = RAD*30.0;
	static const double istep = 1.0/step;
	static const int nabsc = 13;
//	Angle of attack	-180	-150	-120	-90		-60		-30		0		30	 60		90		120		150	  180
	static const double CL[nabsc] = {	0,	-0.12,	-0.1,	  0,	  0,	  0,	0,		0,	  0,	 0,		0.1,	0.12,	0};
	static const double CM[nabsc] = {	0,	-0.0002,-0.0004, -0.0004,-0.0003,-0.0002, 0, 0.0002, 0.0003, 0.0004, 0.0004,0.0002,	0};
	// lift and moment coefficients from -180 to 180 in 30 degree steps.

	aoa += PI;
	int idx = max (0, min (11, (int)(aoa*istep)));
	double d = aoa*istep - idx;
	*cl = CL[idx] + (CL[idx+1]-CL[idx])*d;
	*cm = ( CM[idx] + (CM[idx+1]-CM[idx])*d ) / 10;
	*cd = 0.25 + oapiGetInducedDrag (*cl, 1.27, 0.3);
}
here the aoa is aoa += PI;
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,624
Reaction score
2,342
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Thanks. confused:huh:
here the aoa is aoa += PI;

So, rotated by 180° (which is PI in radians - 2 * PI = 360° or a full circle, of radius 1)
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Ok so looking at the code. It looks like 0 AOA is center
// Angle of attack -180 -150 -120 -90 -60 -30 0 30 60 90 120 150 180
So I what to rotate in 180 degrees?
So aoa=+ (PI*2) ?
 

kocmolyf

Addon Developer
Addon Developer
Joined
Aug 16, 2014
Messages
95
Reaction score
1
Points
8
This is what it looks like entering earth.

OK, I see what's going on now. First just a refresher that Orbiter axes are left-handed, but angles are right-handed:

lefthand.jpg

Hand.gif


Now let's sort this out.

First, you need to decide on which way "forward" will be in your mesh. Currently, "forward" (+Z axis) is facing through the heat shield. That's a reasonable choice, you just need to pick something and stick with it. I'll assume the current setup for the rest of this.

Second, since you're entering "forward", you need to remove your "aoa += PI" line. Orbiter accounts for angle of attack correctly if you're entering head-first. Having this rotation will just get you into trouble.

OK - we have our coordinate system set up. So what should the lift be? Look at your reference picture:

MSLAIR_zpsnlvgdypw.jpg


I'm going to call this "up tilt", where you would expect the lift vector to go upwards, away from the planet. First - what is our angle of attack? Assuming you got rid of "aoa += PI", this is a negative rotation about the X axis, so you have negative angle of attack. So you should have positive coefficients of lift (CL) for negative angles of attack. How does the code look?

Code:
static const double CL[nabsc] = { 0.1, 0.17, 0.2, 0.2, 0.17, 0.1, 0, -0.11, -0.24, -0.38, -0.5, -0.5, -0.02, 0.6355, 0.63, 0.46, 0.28, 0.13, 0.0, -0.16, -0.26, -0.29, -0.24, -0.1, 0.1 };

Looks good! Your only problem here was that angle of attack was wrong. If you delete "aoa += PI", lift will work as expected.

Next problem: the coefficient of pitch moment (CM). There are a few options here:

  1. You can simulate what's really going on, and place your airfoil at exactly the center of pressure and only apply lift forces. (HARD).
  2. You can cheat with what you have (EASY).

I'm going to assume #2 here, since it's the quickest way to get what you want.

The first thing to do is fix your coefficient of moment table. As Urwumpe pointed out, it's off-center. I've added comments to show the degree marks for you (you can see that 0 pitch moment is at 15 degrees of AoA):

Code:
static const double CM[nabsc] =
 {    0,    0,    0,    0,    0,    0,    0,    0,    0, 0.002, 0.004, 0.0025, 0.0012,    0, -0.0012, -0.0007, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// -180, -165, -150, -135, -120, -105,  -90,  -75,  -60,   -45,   -30,    -15,      0,   15,      30,      45,

Once you've re-centered your table, you need to make sure it's stable. A stable pitch moment table will counteract the current rotation. For example, a negative angle of attack should produce a positive pitch moment. Luckily, the table looks good here too!

Finally, the cheat. Instead of trying to use ShiftCG and EditAirfoil, and working out what the linear lift should be to produce the desired moments, just hack the desired outcome into the lift function:

Code:
aoa -= desired_trim_angle;

Whatever your desired trim angle is currently (for example, -20 degrees after dropping ballast), just subtract it off of the current angle of attack. If you're sitting directly head-on at 0 degrees, and you drop ballast, the capsule will suddenly think it's at 0 - (-20) = +20 degrees, and start to pitch down (because of the stable pitch moment table). It should stabilize exactly where you want it.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Thanks So on earth I get this:
mslair2_zpsyl5zuhdl.jpg


Code:
void VLiftCoeff(double aoa, double M, double Re, double *cl, double *cm, double *cd)
{
	static const double step = RAD*15.0;
	static const double istep = 1.0 / step;
	static const int nabsc = 25;
//	static const double CL[nabsc] = { 0.1, 0.17, 0.2, 0.2, 0.17, 0.1, 0, -0.11, -0.24, -0.38, -0.5, -0.5, -0.02, 0.6355, 0.63, 0.46, 0.28, 0.13, 0.0, -0.16, -0.26, -0.29, -0.24, -0.1, 0.1 };
	static const double CL[nabsc] = { 0.1, 0.17, 0.2, 0.2, 0.17, 0.1, 0, -0.11, -0.24, -0.38, -0.5, -0.5, -0.02, 0.6355, 0.63, 0.46, 0.28, 0.13, 0.0, -0.16, -0.26, -0.29, -0.24, -0.1, 0.1 };
	static const double CM[nabsc] =
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.002, 0.004, 0.0025, 0.0012, 0, -0.0012, -0.0007, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	// -180, -165, -150, -135, -120, -105,  -90,  -75,  -60,   -45,   -30,    -15,      0,   15,      30,      45,
	
	
	//	static const double CM[nabsc] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.002, 0.004, 0.0025, 0.0012, 0, -0.0012, -0.0007, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	// lift and moment coefficients from -180 to 180 in 15 degree steps.
	// This uses a documented lift slope of 0.0437/deg, everything else is rather ad-hoc
	aoa -= -20;
	//aoa += PI*2;
	int idx = max(0, min(23, (int)(aoa*istep)));
	double d = aoa*istep - idx;
	*cl = CL[idx] + (CL[idx + 1] - CL[idx])*d;
	*cm = CM[idx] + (CM[idx + 1] - CM[idx])*d;
	*cd = 0.06 + oapiGetInducedDrag(*cl, 2.266, 0.6);
}

Code:
CreateAirfoil(LIFT_VERTICAL, _V(0, -0.01, -0.1), VLiftCoeff, 5.5, 0, 1.27);
CreateAirfoil(LIFT_HORIZONTAL, _V(0, 0, 0.01), HLiftCoeff, 5.5, 0, 1.27);

Can the I change the desired trim angle change? Because was the chute deploys now it should be level or 90 degrees pitch.
 

kocmolyf

Addon Developer
Addon Developer
Joined
Aug 16, 2014
Messages
95
Reaction score
1
Points
8
Can the I change the desired trim angle change? Because was the chute deploys now it should be level or 90 degrees pitch.

This is a little nasty, but if there are only a couple different desired pitch trim angles, you can create a couple of functions, then use EditAirfoil to swap between them:

Code:
void VLiftCoeff(double aoa, double M, double Re, double *cl, double *cm, double *cd, double desired_trim_angle)
{
// ...

    aoa -= desired_trim_angle;

// ...
}

void VLiftCoeffAoA0(double aoa, double M, double Re, double *cl, double *cm, double *cd)
{
    VLiftCoeff(aoa, M, Re, cl, cm, cd, 0.0);
}

void VLiftCoeffAoA20(double aoa, double M, double Re, double *cl, double *cm, double *cd)
{
    VLiftCoeff(aoa, M, Re, cl, cm, cd, -20.0 * PI / 180.0);
}

(edited to correct degrees -> radians)
 
Last edited:

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Thanks. I might try different angles. Not sure which angle I need/want. I thought about trying with a AP mfd?

---------- Post added at 08:51 PM ---------- Previous post was at 01:41 PM ----------

I did this:
Code:
void VLiftCoeff(double aoa, double M, double Re, double *cl, double *cm, double *cd, double desired_trim_angle)
{
	static const double step = RAD*15.0;
	static const double istep = 1.0 / step;
	static const int nabsc = 25;
//	static const double CL[nabsc] = { 0.1, 0.17, 0.2, 0.2, 0.17, 0.1, 0, -0.11, -0.24, -0.38, -0.5, -0.5, -0.02, 0.6355, 0.63, 0.46, 0.28, 0.13, 0.0, -0.16, -0.26, -0.29, -0.24, -0.1, 0.1 };
	static const double CL[nabsc] = { 0.1, 0.17, 0.2, 0.2, 0.17, 0.1, 0, -0.11, -0.24, -0.38, -0.5, -0.5, -0.02, 0.6355, 0.63, 0.46, 0.28, 0.13, 0.0, -0.16, -0.26, -0.29, -0.24, -0.1, 0.1 };
	static const double CM[nabsc] =
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.002, 0.004, 0.0025, 0.0012, 0, -0.0012, -0.0007, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	// -180, -165, -150, -135, -120, -105,  -90,  -75,  -60,   -45,   -30,    -15,      0,   15,      30,      45,
	
	
	//	static const double CM[nabsc] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.002, 0.004, 0.0025, 0.0012, 0, -0.0012, -0.0007, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	// lift and moment coefficients from -180 to 180 in 15 degree steps.
	// This uses a documented lift slope of 0.0437/deg, everything else is rather ad-hoc
	aoa -= desired_trim_angle;
	//aoa += PI*2;
	int idx = max(0, min(23, (int)(aoa*istep)));
	double d = aoa*istep - idx;
	*cl = CL[idx] + (CL[idx + 1] - CL[idx])*d;
	*cm = CM[idx] + (CM[idx + 1] - CM[idx])*d;
	*cd = 0.06 + oapiGetInducedDrag(*cl, 2.266, 0.6);
}
but get this error:
Error 2 error C2664: 'void VESSEL::CreateAirfoil(AIRFOIL_ORIENTATION,const VECTOR3 &,AirfoilCoeffFunc,double,double,double) const' : cannot convert argument 3 from 'void (__cdecl *)(double,double,double,double *,double *,double *,double)' to 'AirfoilCoeffFunc' C:\orbiter100830\Orbitersdk\samples\MSLBACKSHELL\MSLBACKSHELL.CPP 134 1 MSLBACKSHELL


Code:
CreateAirfoil(LIFT_VERTICAL, _V(0, -0.01, -0.1), VLiftCoeff, 5.5, 0, 1.27);


So we are on the same page. When the desired trim angle is -20. The craft should pitch to -20.?
 
Last edited:

francisdrake

Addon Developer
Addon Developer
Joined
Mar 23, 2008
Messages
1,085
Reaction score
901
Points
128
Website
francisdrakex.deviantart.com
....
aoa -= desired_trim_angle;
----
This may be a dumb question to ask, but is there a value asigned to 'desired_trim_angle'?

And I am not quite sure, but I guess the trim angle should be in radians, right?
So 20° AoA would be 20°/180*PI = 0.349 rad.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
It is what ever the Aoa is in?

But i think I need to be able to simulate the shift of gravity. That tilts the capsule one way and then back another.
 

kocmolyf

Addon Developer
Addon Developer
Joined
Aug 16, 2014
Messages
95
Reaction score
1
Points
8
So we are on the same page. When the desired trim angle is -20. The craft should pitch to -20.?

Yes, that is correct.

I did this:

You can't do that, unfortunately. You may not be aware, but you're using something in C called a function pointer. Instead of passing a value like a number, you're passing the name of a function that Orbiter is going to invoke later on (when it needs you to explain its aerodynamics).

This function pointer isn't just a name, though, it also has a type (or "signature"). And this particular function has the signature of (double aoa, double M, double Re, double *cl, double *cm, double *cd). It doesn't know anything about desired_trim_angle - that's an additional piece of information only you understand. That's what the compiler error is saying - the signature of your function doesn't match the expected callback signature.

That's why I suggested having a couple different functions which "hard code" the desired_trim_angle. It's not pretty or flexible, but it will work.

I'm having vague recollections of there being an alternate callback that gives you e.g. a vessel pointer to use, but I don't have the API docs handy to check.
 

gattispilot

Addon Developer
Addon Developer
Joined
Oct 17, 2007
Messages
8,724
Reaction score
2,689
Points
203
Location
Dallas, TX
Did I miss something on your code.
Code:
void VLiftCoeff(double aoa, double M, double Re, double *cl, double *cm, double *cd, double desired_trim_angle)
{
// ...

    aoa -= desired_trim_angle;

// ...
}
 

kocmolyf

Addon Developer
Addon Developer
Joined
Aug 16, 2014
Messages
95
Reaction score
1
Points
8
The problem is you can't pass my version of VLiftCoeff directly into CreateAirfoil. You need to use one of the two "wrappers" I made, like this:

Code:
CreateAirfoil(LIFT_VERTICAL, _V(0, -0.01, -0.1), VLiftCoeffAoA0, 5.5, 0, 1.27);

// or

CreateAirfoil(LIFT_VERTICAL, _V(0, -0.01, -0.1), VLiftCoeffAoA20, 5.5, 0, 1.27);


---------- Post added 04-05-15 at 12:27 AM ---------- Previous post was 04-04-15 at 08:19 PM ----------

And I am not quite sure, but I guess the trim angle should be in radians, right?
So 20° AoA would be 20°/180*PI = 0.349 rad.

Oh, super good catch! My bad on that one. Yes, you should modify my code to pass a radians value.
 
Top