SDK Question How do you get the vertical acceleration?

rocketman768

New member
Joined
Jun 25, 2008
Messages
54
Reaction score
0
Points
0
Is there a way to directly get the vertical acceleration of a ship?
 

rocketman768

New member
Joined
Jun 25, 2008
Messages
54
Reaction score
0
Points
0
Ah, great. That's just what I was looking for! I wonder why it's not part of the standard functions?
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Ah, great. That's just what I was looking for! I wonder why it's not part of the standard functions?
I suspect it's because the built-in surfaceMFD uses stepwise estimation, so Martin never had a need to add these functions, and not many people were clamoring to have them.

Glad my article helped you out, though :)
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
Code:
double get_vacc(OBJHANDLE vessel)
{
	VECTOR3 acc, fvec, vel, gpos;
	double r, vlen;
	OBJHANDLE ref;
	VESSEL * v;
	
	v = oapiGetVesselInterface(vessel);
	ref=v->GetSurfaceRef();
	
	// get the relative velocity in local vessel frame
	v->GetGlobalPos(gpos);
	v->GetRelativeVel(ref, vel);
	v->Global2Local(gpos+vel, vel);
        v->HorizonRot(vel, vel);

	// calculate the acceleration and convert to horizon coords
	v->GetForceVector(fvec);
	acc = fvec/v->GetMass();
	v->HorizonRot(acc, acc);

	// adjust for centripetal acceleration due to gravity 
	r=v->GetAltitude()+oapiGetSize(ref);
        vel.y=0;
	vlen=length(vel);
	acc.y += vlen*vlen/r;

	return acc.y;
}

The above gets you the current vertical acceleration adjusted for the centripetal acceleration due to gravity.
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
The above gets you the current vertical acceleration adjusted for the centripetal acceleration due to gravity.
Did you read the post that N_Molson linked to? It's fairly well answered there.

Your code also isn't correct--you're including the vertical component of relative velocity when you're adjusting for centripetal acceleration, and the distance from the center of a planet isn't always v->GetAltitude() + oapiGetSize(ref), since planets may not be spherical.
 
Last edited:

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
Did you read the post that N_Molson linked to? It's fairly well answered there.

No

Heilor said:
Your code also isn't correct--you're including the vertical component of relative velocity when you're adjusting for centripetal acceleration

Is there a reason not to do so?

Heilor said:
, and the distance from the center of a planet isn't always v->GetAltitude() + oapiGetSize(ref), since planets may not be spherical.

I thought they always are in Orbiter.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
I figured that you hadn't bothered to notice that the question had already been answered.

Is there a reason not to do so?
Centripetal acceleration uses the tangential velocity.

I thought they always are in Orbiter.
Perhaps, but this isn't a particularly good assumption to make. That might change in the future.
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
I figured that you hadn't bothered to notice that the question had already been answered.

I saw no code, the original poster I assumed wanted code, and this would also be good for anyone else in the future trying to find the answer to the same thing.

Heilor said:
Centripetal acceleration uses the tangential velocity.

My physics teacher failed to mention that :p On the wiki article on uniform circular motion I can't find any references to that. Got a link?

Heilor said:
Perhaps, but this isn't a particularly good assumption to make. That might change in the future.

I think it is an OK assumption to make. I don't see Orbiter in the near future supporting non-spherical bodies. But even so, for this version of Orbiter and all the previous versions the code is perfectly fine. If this does change in the future, then too bad :p You can change it if you want.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
I saw no code, the original poster I assumed wanted code, and this would also be good for anyone else in the future trying to find the answer to the same thing.
Well, the OP had already acknowledged the link as being what he wanted, and code that isn't correct is less than useful :p

My physics teacher failed to mention that :p On the wiki article on uniform circular motion I can't find any references to that. Got a link?
Odd, I'm not finding much discussion of it online--everything I see uses the case where velocity is already tangential to the force, so it doesn't come up.

It's obvious when you think about what the adjustment is actually doing--when you're in a circular orbit, your VACC is actually 0...even though the planet is still pulling on you, it's not actually resulting in a change in vertical velocity. You need to look at the vessel in a non-inertial rotating frame of reference, at which point the problem becomes clear: Orbiter is reporting the actual force vector affecting the vessel, but this doesn't include the centrifugal force that shows up as a result of us being in a rotating frame of reference. As a result, we need to compensate for the centrifugal force (not the centripetal force) in order to zero the VACC.

Since the observed centrifugal force is dependent on the angular (or tangential) velocity of the vessel, but not the vertical velocity, we need to remove the vertical velocity before applying it. Looking at the extreme corner cases shows why:
  • If you're in a stable circular orbit at a given altitude a with a velocity v0 which is entirely tangential to the gravitational force vector, VACC should be 0 (because your vertical velocity of 0 isn't changing).
  • If you're at that same altitude a with a velocity v1 which is equimagnitudinal to v0 but instead parallel to the gravitational force vector, VACC should be the acceleration caused by the gravitational force (because your vertical velocity is changing due to the gravitational force).
If you don't remove the vertical component of velocity before calculating the magnitude, you'll end up returning VACC = 0 for both of these cases.
I think it is an OK assumption to make. I don't see Orbiter in the near future supporting non-spherical bodies. But even so, for this version of Orbiter and all the previous versions the code is perfectly fine. If this does change in the future, then too bad :p You can change it if you want.
That's a fully up-to-you sort of thing. I try to avoid making assumptions unless they greatly simplify my life and aren't likely to change anytime soon. I used GetRelativePos in my code to get the actual distance from the center of the reference body.
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
Well, the OP had already acknowledged the link as being what he wanted, and code that isn't correct is less than useful :p

I didn't read what OP posted aside from his first post :p And the code is correct.

heilor said:
Odd, I'm not finding much discussion of it online--everything I see uses the case where velocity is already tangential to the force, so it doesn't come up.

Basically what is happening is that there is a radial acceleration inwards towards the center of the planet due to gravity, called the centripetal acceleration. But that acceleration only causes a change in direction, and not the speed. So to calculate acceleration, you need to remove the centripetal acceleration, otherwise you would see a speed change that is non-existent.

I am not 100% convinced that the vertical component should be removed. Have you found a reliable way of testing this ? I get too much fluctuations. I suppose for this you could always go the step wise calculation route. That'd definitely help with the fluctuations. Surface MFD might in fact be using that I think.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
... And the code is correct.
Except that it isn't, as I've already explained, both here and in that other thread...

Basically what is happening is that there is a radial acceleration inwards towards the center of the planet due to gravity, called the centripetal acceleration. But that acceleration only causes a change in direction, and not the speed. So to calculate acceleration, you need to remove the centripetal acceleration, otherwise you would see a speed change that is non-existent.
No, you don't need to remove the centripetal acceleration. The centripetal acceleration is still exerting a force on the vessel. You need to add the centrifugal acceleration, the inertial force that arises because the vessel is in a rotating reference frame. When the vessel is in a circular orbit, this will cancel out the gravitational force.

The magnitude of the centrifugal force (the force that appears to exist in the rotating reference frame) is dependent on the angular velocity of the reference frame. We don't need to convert to angular velocity, we can just use tangential velocity (by removing the vertical component after rotating the velocity vector to the horizon frame) to calculate the magnitude of the centrifugal force and add that to the vessel's force vector.

If you think closely about the two scenarios I posted above, you'll realize why this is the case. When the vessel has no tangential velocity, it's not in a rotating frame of reference, so we don't want to do anything to compensate.

I am not 100% convinced that the vertical component should be removed. Have you found a reliable way of testing this ? I get too much fluctuations. I suppose for this you could always go the step wise calculation route. That'd definitely help with the fluctuations. Surface MFD might in fact be using that I think.
You really ought to go read the previously linked thread since you're repeating or puzzling over a lot of what got said there :). Yes, the surface MFD is using a stepwise approximation of the vertical acceleration, which is why it shows occasional large fluctuations. As I explained there, the stepwise method was insufficient for my purposes, because in a distributed system the stepwise method has many difficulties.

The code that I posted there is what is being used by Orb:Connect, and I did fairly extensive testing of the method across a wide range of initial conditions to verify that it matched the SurfaceMFD value (with the exception of momentary inaccuracies caused by SurfaceMFD using a stepwise approximation). I'm quite sure that using only the tangential velocity when calculating the centrifugal force is the correct course of action.
 
Last edited:

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
Except that it isn't, as I've already explained, both here and in that other thread...

Well your explanation is insufficient for me. If you really want to prove that the code is wrong, show me some experimental evidence (measure in Orbiter).

BTW have you even seen the results that the above code produces and compared them to yours?
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Well your explanation is insufficient for me. If you really want to prove that the code is wrong, show me some experimental evidence (measure in Orbiter).

BTW have you even seen the results that the above code produces and compared them to yours?
Given that the article I wrote more than two years ago has been fairly well accepted by the community and several people who have used it, I think the burden of proof that I'm wrong and you're not falls to you.

But, okay, I'll bite and do your thinking for you. I don't need experimental evidence, all I need is math.

Assume there's a delta glider above the earth at a radius of 6.540M. It's going straight down toward the center of the planet at 9000m/s., pointing straight down, so its relative velocity in the local frame is {0, 0, 9000}. For simplicity let's say that the acceleration due to gravity at this point is -9.8m/s^2.
Let's run through your code:
Code:
	// get the relative velocity in local vessel frame
	v->GetGlobalPos(gpos); 
 v->GetRelativeVel(ref, vel); 
 v->Global2Local(gpos+vel, vel); [COLOR=red]// vel = {0, 0, 9000}
[/COLOR]
	// calculate the acceleration and convert to horizon coords
	v->GetForceVector(fvec);
	acc = fvec/v->GetMass();
	v->HorizonRot(acc, acc); [COLOR=red]// acc ~= {0, -9.8, 0}
[/COLOR]
	// adjust for centripetal acceleration due to gravity 
	r=v->GetAltitude()+oapiGetSize(ref); [COLOR=red]// r = 6540000
[/COLOR]	vlen=length(vel); [COLOR=red]// vlen = 9000
[/COLOR]	acc.y += vlen*vlen/r; [COLOR=red]// (vlen*vlen / r) = 12.39[/COLOR]
[COLOR=red]// acc.y = -9.8 + 12.39 = 2.59
[/COLOR]
Oopsies. Your code just said that this vessel, which is falling straight down, is accelerating upwards, away from the planet at 2.59m/s. Gravity doesn't work that way.

My code, given the same inputs, will ignore the vertical component of velocity (in the horizon frame) and return -9.8m/s for the vertical acceleration, as expected.
 

computerex

Addon Developer
Addon Developer
Joined
Oct 16, 2007
Messages
1,282
Reaction score
17
Points
0
Location
Florida
I was trying to compare the results from your code to mine, but I couldn't because yours crashes for any body that has no atmosphere. Experimentation does pay off you know :p Use GetSurfaceRef instead imo.

Yours is right, mine is left:

obtest.jpg


Code:
#define STRICT
#define ORBITER_MODULE

#include <orbitersdk.h>

double get_vacc(OBJHANDLE vessel)
{
	VECTOR3 acc, fvec, vel, gpos;
	double r, vlen;
	OBJHANDLE ref;
	VESSEL * v;

	v = oapiGetVesselInterface(vessel);
	ref=v->GetSurfaceRef();

	// get the relative velocity in local vessel frame
	v->GetGlobalPos(gpos);
	v->GetRelativeVel(ref, vel);
	v->Global2Local(gpos+vel, vel);
	v->HorizonRot(vel, vel);

	// calculate the acceleration and convert to horizon coords
	v->GetForceVector(fvec);
	acc = fvec/v->GetMass();
	v->HorizonRot(acc, acc);

	// adjust for centripetal acceleration due to gravity 
	r=v->GetAltitude()+oapiGetSize(ref);
	vel.y=0;
	vlen=length(vel);
	acc.y += vlen*vlen/r;

	return acc.y;
}

double get_vacc_heilor(OBJHANDLE vessel)
{
	double acc;
	VECTOR3 force_vec, acc_vec, spd_vec;
	VESSEL* ves = oapiGetVesselInterface(vessel);

	// Get the vectors we need
	ves->GetShipAirspeedVector(spd_vec);
	ves->GetForceVector(force_vec);

	// Normalize the speed vector
	spd_vec = spd_vec / length(spd_vec);

	// Calculate the acceleration vector
	acc_vec = force_vec / ves->GetMass();

	// Take the dot product
	acc = acc_vec.x * spd_vec.x + acc_vec.y * spd_vec.y + acc_vec.z * spd_vec.z;

	double vacc, lon, lat, radius, mag;
	VECTOR3 horacc_vec;
	VECTOR3 spd_vec2, glob_vpos, glob_rvel, loc_rvel;
	OBJHANDLE planet;

	// VACC
	ves->HorizonRot(acc_vec, horacc_vec);
	vacc = horacc_vec.y;

	// Account for "centrifugal acceleration"
	planet = ves->GetSurfaceRef();
	ves->GetGlobalPos(glob_vpos);
	ves->GetRelativeVel(planet, glob_rvel);
	ves->Global2Local((glob_rvel + glob_vpos), loc_rvel);
	ves->HorizonRot(loc_rvel, spd_vec2);
	ves->GetEquPos(lon, lat, radius);

	spd_vec2.y = 0;
	mag = length(spd_vec2);
	vacc += mag * mag / radius;

	return vacc;
}


DLLCLBK void opcPreStep(double simt, double simdt, double mjd)
{
	sprintf(oapiDebugString(), "%f %f", get_vacc(oapiGetFocusObject()), get_vacc_heilor(oapiGetFocusObject()));
}

So zeroing out the y component really does seem to produce better results. Thanks ;)

Final version for anyone who wants a copy/paste solution:

Code:
double get_vacc(OBJHANDLE vessel)
{
	VECTOR3 acc, fvec, vel, gpos;
	double r, vlen;
	OBJHANDLE ref;
	VESSEL * v;
	
	v = oapiGetVesselInterface(vessel);
	ref=v->GetSurfaceRef();
	
	// get the relative velocity in local vessel frame
	v->GetGlobalPos(gpos);
	v->GetRelativeVel(ref, vel);
	v->Global2Local(gpos+vel, vel);
        v->HorizonRot(vel, vel);

	// calculate the acceleration and convert to horizon coords
	v->GetForceVector(fvec);
	acc = fvec/v->GetMass();
	v->HorizonRot(acc, acc);

	// adjust for centripetal acceleration due to gravity 
	r=v->GetAltitude()+oapiGetSize(ref);
        vel.y=0;
	vlen=length(vel);
	acc.y += vlen*vlen/r;

	return acc.y;
}
 
Last edited:

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
I was trying to compare the results from your code to mine, but I couldn't because yours crashes for any body that has no atmosphere. Experimentation does pay off you know :p Use GetSurfaceRef instead imo.
Odd that I've never seen this crash before--did something change about GetAtmRef between 2006 and 2010? Orb:Connect was developed on 2006 and neither yagni nor I have tested it much on 2010.

I'll update that, though, thanks.
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Odd that I've never seen this crash before--did something change about GetAtmRef between 2006 and 2010? Orb:Connect was developed on 2006 and neither yagni nor I have tested it much on 2010.

I'll update that, though, thanks.
Never saw that crash because Orb:Connect is using GetSurfaceRef instead of GetAtmRef. Guess I updated it in Orb:Connect and never updated the post. Fixed the post now, thanks anyway.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,660
Reaction score
2,381
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Wouldn't it be enough to subtract gravity force vector from total forces vector, unless you are landed (effectively adding weight force to the corrected force vector)?
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Wouldn't it be enough to subtract gravity force vector from total forces vector, unless you are landed (effectively adding weight force to the corrected force vector)?
What would that accomplish? If you did that during, for example, atmospheric flight, you'd have the force vector from lift but not the force vector from gravity, so your calculated acceleration would be way off (since those two usually balance each other).

If you mean for accounting for orbital actions, "remove gravity" isn't the answer either, since what you should remove is based on your angular velocity, not the gravitational pull.
 
Top