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?
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.Ah, great. That's just what I was looking for! I wonder why it's not part of the standard functions?
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;
}
Did you read the post that N_Molson linked to? It's fairly well answered there.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.
Heilor said:Your code also isn't correct--you're including the vertical component of relative velocity when you're adjusting for centripetal acceleration
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 figured that you hadn't bothered to notice that the question had already been answered.
Centripetal acceleration uses the tangential velocity.Is there a reason not to do so?
Perhaps, but this isn't a particularly good assumption to make. That might change in the future.I thought they always are in Orbiter.
I figured that you hadn't bothered to notice that the question had already been answered.
Heilor said:Centripetal acceleration uses the tangential velocity.
Heilor said:Perhaps, but this isn't a particularly good assumption to make. That might change in the future.
Well, the OP had already acknowledged the link as being what he wanted, and code that isn't correct is less than usefulI 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.
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.My physics teacher failed to mention that On the wiki article on uniform circular motion I can't find any references to that. Got a link?
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.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 You can change it if you want.
Well, the OP had already acknowledged the link as being what he wanted, and code that isn't correct is less than useful
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.
Except that it isn't, as I've already explained, both here and in that other thread...... And the code is correct.
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.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.
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.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.
Except that it isn't, as I've already explained, both here and in that other thread...
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.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?
// 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]
#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()));
}
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;
}
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 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 Use GetSurfaceRef instead imo.
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.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.
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).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)?