41 const uint32_t currentTimestamp = vve_.getTimestamp();
42 const float velocity = vve_.getEstimatedVelocity();
43 const float acceleration = vve_.getInertialVerticalAcceleration();
46 float decelSample = std::max(0.0F, -acceleration);
48 if (currentTimestamp > lastTs_) {
49 const auto deltaTime =
static_cast<float>(currentTimestamp - lastTs_);
50 const float deltaVelocity = velocity - lastVel_;
51 float estimatedDecel = (deltaTime > 0.0F) ? std::max(0.0F, -deltaVelocity / deltaTime) : 0.0F;
52 decelSample = MAGIC_HALF * (decelSample + estimatedDecel);
55 filteredDecel_ = alpha_ * decelSample + (1.0F - alpha_) * filteredDecel_;
57 if (velocity > minClimbVel_ && filteredDecel_ > MIN_VALID_DECEL) {
58 tToApogee_ = velocity / filteredDecel_;
59 predApogeeTs_ = currentTimestamp +
static_cast<uint32_t
>(tToApogee_ * MS_TO_S_FACTOR);
61 const float altitude = vve_.getEstimatedAltitude();
62 predApogeeAlt_ = altitude + velocity * tToApogee_ -
63 MAGIC_HALF * filteredDecel_ * tToApogee_ * tToApogee_;
70 lastTs_ = currentTimestamp;
72 numWarmups_ = std::min(numWarmups_ + 1, MAX_WARMUPS);
76 const uint32_t currentTimestamp = vve_.getTimestamp();
77 const float velocity = vve_.getEstimatedVelocity();
78 const float acceleration = vve_.getInertialVerticalAcceleration();
80 float kEstimate = 0.0F;
81 if (std::fabs(velocity) > 1.0F) {
82 kEstimate = std::max(0.0F, -(acceleration + GRAVITY_MS2)) / (velocity * velocity);
85 filteredDecel_ = alpha_ * kEstimate + (1.0F - alpha_) * filteredDecel_;
86 const float dragToMassRatio = filteredDecel_;
88 if (velocity > minClimbVel_ && dragToMassRatio > MIN_VALID_DECEL) {
89 const float terminalVelocity = std::sqrt(GRAVITY_MS2 / dragToMassRatio);
90 tToApogee_ = (terminalVelocity / GRAVITY_MS2) * std::atan(velocity / terminalVelocity);
91 const float deltaAltitude = (terminalVelocity * terminalVelocity / (2.0F * GRAVITY_MS2)) *
92 std::log1p((velocity * velocity) /
93 (terminalVelocity * terminalVelocity));
95 predApogeeTs_ = currentTimestamp +
static_cast<uint32_t
>(tToApogee_ * MS_TO_S_FACTOR);
96 predApogeeAlt_ = vve_.getEstimatedAltitude() + deltaAltitude;
102 lastTs_ = currentTimestamp;
106 const uint32_t currentTimestamp_ms = vve_.getTimestamp();
107 const float altitude_m = vve_.getEstimatedAltitude();
108 const float velocity_ms = vve_.getEstimatedVelocity();
109 const float acceleration_ms2 = vve_.getInertialVerticalAcceleration();
113 const size_t featureCount = 10;
116 const float coeffs[] = {
128 const float intercept = 308.64734694;
132 double decel = std::fabs(acceleration_ms2);
133 double delta_h_simple = (velocity_ms * velocity_ms) / (2.0 * decel);
137 const double inputs[featureCount] = {
142 velocity_ms * velocity_ms,
143 velocity_ms * acceleration_ms2,
144 velocity_ms * delta_h_simple,
145 acceleration_ms2 * acceleration_ms2,
146 acceleration_ms2 * delta_h_simple,
147 delta_h_simple * delta_h_simple,
150 double apogeeRemaining_m = intercept;
151 for (
size_t i = 0; i < featureCount; ++i) {
152 apogeeRemaining_m += coeffs[i] * inputs[i];
157 predApogeeAlt_ = altitude_m + apogeeRemaining_m;
160 tToApogee_ = velocity_ms / decel;
161 predApogeeTs_ = currentTimestamp_ms +
static_cast<uint32_t
>(tToApogee_ * MS_TO_S_FACTOR);
165 lastTs_ = currentTimestamp_ms;
166 lastVel_ = velocity_ms;
167 numWarmups_ = std::min(numWarmups_ + 1, MAX_WARMUPS);
169 printf(
"Current Timestamp: %u, Altitude: %.2f, Velocity: %.2f, Acceleration: %.2f, Predicted Apogee Remaining: %.2f, Delta H: %.2f\n",
170 currentTimestamp_ms, altitude_m, velocity_ms, acceleration_ms2, apogeeRemaining_m, delta_h_simple);