- Joined
- May 30, 2008
- Messages
- 5,580
- Reaction score
- 2
- Points
- 0
Purpose: Calculate precisely (ie, without resorting to stepwise estimation) the ACC and VACC components of the SurfaceMFD.
Forum References:
Getting Acceleration Vectors
Posted by: Topper
http://orbiter-forum.com/showthread.php?t=3315&highlight=acceleration
Gives code for a stepwise estimation of horizontal and vertical accelerations, with respect to the local horizon reference frame.
Reading the Acceleration
Posted by: V8Li
http://www.orbiter-forum.com/showthread.php?t=1564&highlight=acceleration
Gives code which aims at getting a precise calculation in post 7, but due to several math errors doesn't get there, and settles on a stepwise estimation using delta-s/delta-t.
------------------------------
Unless otherwise noted, coordinates are with respect to the local horizon reference frame.
Correcting Previous Assumptions:
Both of the above threads (Topper's in post 1; V8Li's in post 3, from reverend) make the assumption that the ACC value displayed on the SurfaceMFD is horizontal component of acceleration. This is not the case, and can be proven by pointing yourself straight up while under full acceleration and noting that the ACC ~= VACC.
Rather, the ACC value displayed on the SurfaceMFD appears to be a stepwise delta estimation of whatever is displayed in the airspeed tape. This is evident in the momentary extreme values present on the ACC tape when switching between airspeed modes. Essentially, the ACC tape shows the vehicle's rate of change of airspeed, or stated differently(and in a form more suitable for precise instantaneous acceleration), acceleration along the airspeed vector.
This value is more convenient from a pilot's perspective than the horizontal component of acceleration; for example, during ascent or descent the pilot may be looking to maintain a constant airspeed. Given horizontal and vertical components of acceleration, both must be zeroed in order to maintain airspeed; given instead airspeed rate-of-change, only that must be zeroed to maintain airspeed.
I assume that the VACC (and VS) elements are as expected; that is, they are the y-component of their respective overall vectors in the local horizon frame.
The ACC Calculation:
The ACC value as displayed in the SurfaceMFD is, as stated above, "acceleration along the airspeed vector." Without further ado, the code to calculate this for the focus vessel (code is deliberately left unoptimized for ease of reading) follows. This code uses the "double length(const VECTOR3 &a)" function as defined in OrbiterAPI.h--you shouldn't have to write this on your own.
Comparison to stepwise estimation methods:
Performance: Although the above computation is more complex than that required for a stepwise estimation, it needs only be performed once per sim step and will introduce an extremely small amount of overhead when compared to the typical amount of processing done by a ship in any given timestep.
Accuracy: Testing was performed by printing the output to oapiDebugString(), and the value was compared to the ACC given for the TAS airspeed mode in SurfaceMFD. The value calculated here was identical to that displayed during level flight. Differences during extreme maneuevers can be explained by the slower response time of the stepwise estimation method.
Moreover, this precise calculation does not rely on accurate timing for the previous value, and in a distributed environment will be unaffected by any potential loss of data caused due to unreliable (or slow) networks.
The VACC calculation:
The VACC value displayed in the SurfaceMFD is, as described above, the y-component of the acceleration vector in the local horizon frame. Assuming the acceleration vector has already been calculated as shown in the previous code fragment, this calculation should be straightforward:
However, testing of this method shows this to be inaccurate; specifically, at high velocities the indicated VACC will be much lower than actual due to the curvature of the earth. This is most notable at orbital velocities, where actual VACC is ~0, but the above method will indicate a VACC of ~-1g.
To account for this, we have to take into account the "centrifugal acceleration" of the craft, as it's in a rotating reference frame around the planet. Thus:
Comparison to stepwise estimation methods:
Performance: This computation is significantly more complex than a stepwise estimation, but would still amount for a relatively small portion of the per-step processing performed by a vessel.
Accuracy: Testing was performed by printing the output to oapiDebugString(), and the value was compared to the VACC given in SurfaceMFD. The value calculated here is very close to that acquired by the stepwise estimation, but appears to differ by about +.005 in the vicinity of Earth, at all speed ranges, from landed to orbit.
I don't know why, but it appears that the centrifugal force calculation is over-compensating somewhat. Any ideas?
A note about landed ships, from later in the thread:
The above calculation won't work when the ship is landed:
However, since you know that VACC=0 when landed, you can just check to see if the vessel is landed and set the VACC to 0:
Conclusion:
In situations where a stepwise estimation is unsuitable, here are the methods needed to precisely (and instantaneously) calculate the ACC and VACC elements as shown on the SurfaceMFD. However, even if the error in the VACC element can be corrected, the increased overhead may not justify the slight increase in accuracy.
Forum References:
Getting Acceleration Vectors
Posted by: Topper
http://orbiter-forum.com/showthread.php?t=3315&highlight=acceleration
Gives code for a stepwise estimation of horizontal and vertical accelerations, with respect to the local horizon reference frame.
Reading the Acceleration
Posted by: V8Li
http://www.orbiter-forum.com/showthread.php?t=1564&highlight=acceleration
Gives code which aims at getting a precise calculation in post 7, but due to several math errors doesn't get there, and settles on a stepwise estimation using delta-s/delta-t.
------------------------------
Unless otherwise noted, coordinates are with respect to the local horizon reference frame.
Correcting Previous Assumptions:
Both of the above threads (Topper's in post 1; V8Li's in post 3, from reverend) make the assumption that the ACC value displayed on the SurfaceMFD is horizontal component of acceleration. This is not the case, and can be proven by pointing yourself straight up while under full acceleration and noting that the ACC ~= VACC.
Rather, the ACC value displayed on the SurfaceMFD appears to be a stepwise delta estimation of whatever is displayed in the airspeed tape. This is evident in the momentary extreme values present on the ACC tape when switching between airspeed modes. Essentially, the ACC tape shows the vehicle's rate of change of airspeed, or stated differently(and in a form more suitable for precise instantaneous acceleration), acceleration along the airspeed vector.
This value is more convenient from a pilot's perspective than the horizontal component of acceleration; for example, during ascent or descent the pilot may be looking to maintain a constant airspeed. Given horizontal and vertical components of acceleration, both must be zeroed in order to maintain airspeed; given instead airspeed rate-of-change, only that must be zeroed to maintain airspeed.
I assume that the VACC (and VS) elements are as expected; that is, they are the y-component of their respective overall vectors in the local horizon frame.
The ACC Calculation:
The ACC value as displayed in the SurfaceMFD is, as stated above, "acceleration along the airspeed vector." Without further ado, the code to calculate this for the focus vessel (code is deliberately left unoptimized for ease of reading) follows. This code uses the "double length(const VECTOR3 &a)" function as defined in OrbiterAPI.h--you shouldn't have to write this on your own.
Code:
double acc;
VECTOR3 force_vec, acc_vec, spd_vec;
VESSEL* ves = oapiGetVesselInterface(oapiGetFocusObject());
// 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;
Performance: Although the above computation is more complex than that required for a stepwise estimation, it needs only be performed once per sim step and will introduce an extremely small amount of overhead when compared to the typical amount of processing done by a ship in any given timestep.
Accuracy: Testing was performed by printing the output to oapiDebugString(), and the value was compared to the ACC given for the TAS airspeed mode in SurfaceMFD. The value calculated here was identical to that displayed during level flight. Differences during extreme maneuevers can be explained by the slower response time of the stepwise estimation method.
Moreover, this precise calculation does not rely on accurate timing for the previous value, and in a distributed environment will be unaffected by any potential loss of data caused due to unreliable (or slow) networks.
The VACC calculation:
The VACC value displayed in the SurfaceMFD is, as described above, the y-component of the acceleration vector in the local horizon frame. Assuming the acceleration vector has already been calculated as shown in the previous code fragment, this calculation should be straightforward:
Code:
// INCORRECT
double vacc;
VECTOR3 horacc_vec;
ves->HorizonRot(acc_vec, horacc_vec);
vacc = horacc_vec.y;
// INCORRECT
To account for this, we have to take into account the "centrifugal acceleration" of the craft, as it's in a rotating reference frame around the planet. Thus:
Code:
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"
// Get the relative velocity in the local frame
planet = ves->GetSurfaceRef();
ves->GetGlobalPos(glob_vpos);
ves->GetRelativeVel(planet, glob_rvel);
ves->Global2Local((glob_rvel + glob_vpos), loc_rvel);
// Transform to horizon reference frame
ves->HorizonRot(loc_rvel, spd_vec2);
ves->GetEquPos(lon, lat, radius);
// Determine the centrifugal acceleration
spd_vec2.y = 0;
mag = length(spd_vec2);
vacc += mag * mag / radius;
Performance: This computation is significantly more complex than a stepwise estimation, but would still amount for a relatively small portion of the per-step processing performed by a vessel.
Accuracy: Testing was performed by printing the output to oapiDebugString(), and the value was compared to the VACC given in SurfaceMFD. The value calculated here is very close to that acquired by the stepwise estimation, but appears to differ by about +.005 in the vicinity of Earth, at all speed ranges, from landed to orbit.
I don't know why, but it appears that the centrifugal force calculation is over-compensating somewhat. Any ideas?
A note about landed ships, from later in the thread:
The above calculation won't work when the ship is landed:
The ground contact force that Orbiter adds doesn't take into account the gravitational pull of the sun, but the gravitational force vector does. Thus, the pull of the sun isn't offset in the total force vector.
However, since you know that VACC=0 when landed, you can just check to see if the vessel is landed and set the VACC to 0:
Maybe I'm missing something else but the answer seems pretty simple. This error is only due to the contact force when landed, right? Can't you just set VACC=0 when landed (use GetFlightStatus to check)?
Conclusion:
In situations where a stepwise estimation is unsuitable, here are the methods needed to precisely (and instantaneously) calculate the ACC and VACC elements as shown on the SurfaceMFD. However, even if the error in the VACC element can be corrected, the increased overhead may not justify the slight increase in accuracy.
Last edited: