feat(flight): add aspect ratio lift and altitude-hold trim
- Derive lift slope and induced drag from each wing's aspect ratio, found by grouping connected wing blocks across short span gaps. - Give stabilizers and vertical wings their own parasitic drag from the stabilizerDrag config. - Replace designSpeed with a fixed lift constant and a liftScale multiplier. - Make auto trim hold the altitude the craft has when the pilot releases pitch, using nested altitude, climb and attitude loops. - Add /improvedaerodynamics (alias /aero) to list, read and set the main config values in game.
This commit is contained in:
1 parent
4b7fb0e1e8
commit
599ecae21f
10 files changed
+329
-48
No files matched your search
@@ -57,6 +57,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
// Torque (ship axes) one unit of pitch input on this node's pitch surfaces makes, measured every substep
|
||||
final Vector3d pitchResponse = new Vector3d();
|
||||
final Vector3d pitchResponseBuilding = new Vector3d();
|
||||
final AutoTrim.Targets trimTargets = new AutoTrim.Targets();
|
||||
volatile double savedTrim;
|
||||
|
||||
NodeState(NodeData data) {
|
||||
@@ -102,7 +103,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
|
||||
@Override
|
||||
public void publish(long tick) {
|
||||
published = new Frame(tick, buildingSurfaces.values().toArray(new AeroSurface[0]), buildingNodes);
|
||||
published = new Frame(tick, WingShape.withAspectRatios(buildingSurfaces.values()), buildingNodes);
|
||||
buildingSurfaces = new Long2ObjectOpenHashMap<>();
|
||||
buildingNodes = new Long2ObjectOpenHashMap<>();
|
||||
}
|
||||
@@ -131,7 +132,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
boolean improved = Config.IMPROVED_FLIGHT_MODEL.get();
|
||||
Matrix3dc inertia = ship.getMomentOfInertia();
|
||||
|
||||
updateNodes(frame, worldVelocity, rotation, inertia, w, dt, improved);
|
||||
updateNodes(frame, worldVelocity, transform.getPositionInWorld().y(), rotation, inertia, w, dt, improved);
|
||||
evaluate(frame, centerOfMass, v, w, improved, true, wrench);
|
||||
|
||||
if (Config.IMPLICIT_DAMPING.get()) {
|
||||
@@ -204,8 +205,10 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
private void evaluate(Frame frame, Vector3dc centerOfMass, double[] v, double[] w, boolean improved, boolean commit, Wrench out) {
|
||||
out.clear();
|
||||
double weight = clock.weight();
|
||||
double liftConstant = ImprovedAero.liftConstant(Config.DESIGN_SPEED.get());
|
||||
double liftConstant = ImprovedAero.LIFT_CONSTANT;
|
||||
double stallAngleScale = Config.STALL_ANGLE_SCALE.get();
|
||||
double liftScale = Config.LIFT_SCALE.get();
|
||||
double thinDrag = Config.STABILIZER_DRAG.get();
|
||||
double[] r = new double[3];
|
||||
if (commit) {
|
||||
wingStalled = false;
|
||||
@@ -224,7 +227,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
double input = s.type().controllable ? input(s, node, state, 0.0) : 0.0;
|
||||
|
||||
if (improved) {
|
||||
boolean nowStalled = ImprovedAero.evaluate(s, v, w, r, input, weight, liftConstant, stallAngleScale, stalled[i], out);
|
||||
boolean nowStalled = ImprovedAero.evaluate(s, v, w, r, input, weight, liftConstant, liftScale, stallAngleScale, thinDrag, stalled[i], out);
|
||||
if (commit) {
|
||||
stalled[i] = nowStalled;
|
||||
wingStalled |= nowStalled && s.type() == SurfaceType.WING;
|
||||
@@ -239,7 +242,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
probe.clear();
|
||||
double base = 0.0;
|
||||
if (improved) {
|
||||
ImprovedAero.evaluate(s, v, w, r, input, weight, liftConstant, stallAngleScale, stalled[i], probe);
|
||||
ImprovedAero.evaluate(s, v, w, r, input, weight, liftConstant, liftScale, stallAngleScale, thinDrag, stalled[i], probe);
|
||||
} else {
|
||||
WariumAero.evaluate(s, v, w, r, input, weight, probe);
|
||||
}
|
||||
@@ -247,7 +250,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
probe.clear();
|
||||
double nudged = input(s, node, state, delta);
|
||||
if (improved) {
|
||||
ImprovedAero.evaluate(s, v, w, r, nudged, weight, liftConstant, stallAngleScale, stalled[i], probe);
|
||||
ImprovedAero.evaluate(s, v, w, r, nudged, weight, liftConstant, liftScale, stallAngleScale, thinDrag, stalled[i], probe);
|
||||
} else {
|
||||
WariumAero.evaluate(s, v, w, r, nudged, weight, probe);
|
||||
}
|
||||
@@ -285,7 +288,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
};
|
||||
}
|
||||
|
||||
private void updateNodes(Frame frame, Vector3dc worldVelocity, Quaterniondc rotation, Matrix3dc inertia,
|
||||
private void updateNodes(Frame frame, Vector3dc worldVelocity, double altitude, Quaterniondc rotation, Matrix3dc inertia,
|
||||
double[] w, double dt, boolean improved) {
|
||||
double step = Config.CONTROL_SMOOTHING.get() ? INPUT_RATE_PER_TICK * clock.weight() : Double.POSITIVE_INFINITY;
|
||||
for (NodeData node : frame.nodes.values()) {
|
||||
@@ -296,7 +299,7 @@ public final class AeroState implements PhysicsBridge.Publishable {
|
||||
state.pitch = moveTowards(state.pitch, node.pitch(), step);
|
||||
state.yaw = moveTowards(state.yaw, node.yaw(), step);
|
||||
state.roll = moveTowards(state.roll, node.roll(), step);
|
||||
AutoTrim.update(state, node, worldVelocity, rotation, inertia, w, dt, improved && wingStalled);
|
||||
AutoTrim.update(state, node, worldVelocity, altitude, rotation, inertia, w, dt, improved && wingStalled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user