45 const uint32_t currentTimestamp = vve_.getTimestamp();
46 const float velocity = vve_.getEstimatedVelocity();
47 const float acceleration = vve_.getInertialVerticalAcceleration();
50 float decelSample = std::max(0.0F, -acceleration);
52 if (currentTimestamp > lastTs_) {
53 const auto deltaTime =
static_cast<float>(currentTimestamp - lastTs_);
54 const float deltaVelocity = velocity - lastVel_;
55 float estimatedDecel = (deltaTime > 0.0F) ? std::max(0.0F, -deltaVelocity / deltaTime) : 0.0F;
56 decelSample = MAGIC_HALF * (decelSample + estimatedDecel);
59 filteredDecel_ = alpha_ * decelSample + (1.0F - alpha_) * filteredDecel_;
61 if (velocity > minClimbVel_ && filteredDecel_ > MIN_VALID_DECEL) {
62 tToApogee_ = velocity / filteredDecel_;
63 predApogeeTs_ = currentTimestamp +
static_cast<uint32_t
>(tToApogee_ * MS_TO_S_FACTOR);
65 const float altitude = vve_.getEstimatedAltitude();
66 predApogeeAlt_ = altitude + velocity * tToApogee_ -
67 MAGIC_HALF * filteredDecel_ * tToApogee_ * tToApogee_;
74 lastTs_ = currentTimestamp;
76 numWarmups_ = std::min(numWarmups_ + 1, MAX_WARMUPS);
80 const uint32_t currentTimestamp = vve_.getTimestamp();
81 const float velocity = vve_.getEstimatedVelocity();
82 const float acceleration = vve_.getInertialVerticalAcceleration();
84 float kEstimate = 0.0F;
85 if (std::fabs(velocity) > 1.0F) {
86 kEstimate = std::max(0.0F, -(acceleration + GRAVITY_MS2)) / (velocity * velocity);
89 filteredDecel_ = alpha_ * kEstimate + (1.0F - alpha_) * filteredDecel_;
90 const float dragToMassRatio = filteredDecel_;
92 if (velocity > minClimbVel_ && dragToMassRatio > MIN_VALID_DECEL) {
93 const float terminalVelocity = std::sqrt(GRAVITY_MS2 / dragToMassRatio);
94 tToApogee_ = (terminalVelocity / GRAVITY_MS2) * std::atan(velocity / terminalVelocity);
95 const float deltaAltitude = (terminalVelocity * terminalVelocity / (2.0F * GRAVITY_MS2)) *
96 std::log1p((velocity * velocity) /
97 (terminalVelocity * terminalVelocity));
99 predApogeeTs_ = currentTimestamp +
static_cast<uint32_t
>(tToApogee_ * MS_TO_S_FACTOR);
100 predApogeeAlt_ = vve_.getEstimatedAltitude() + deltaAltitude;
106 lastTs_ = currentTimestamp;
110 const uint32_t currentTimestamp_ms = vve_.getTimestamp();
111 const float altitude_m = vve_.getEstimatedAltitude();
112 const float velocity_ms = vve_.getEstimatedVelocity();
113 const float acceleration_ms2 = vve_.getInertialVerticalAcceleration();
115 constexpr size_t FEATURE_COUNT = 10;
118 const std::array<float, FEATURE_COUNT> coeffs = {
130 const float intercept = 308.64734694;
134 const float decel = std::fabs(acceleration_ms2);
135 const float delta_h_simple = MAGIC_HALF * (velocity_ms * velocity_ms) / decel;
139 const std::array<float, FEATURE_COUNT> inputs = {
144 velocity_ms * velocity_ms,
145 velocity_ms * acceleration_ms2,
146 velocity_ms * delta_h_simple,
147 acceleration_ms2 * acceleration_ms2,
148 acceleration_ms2 * delta_h_simple,
149 delta_h_simple * delta_h_simple,
152 float apogeeRemaining_m = intercept;
153 for (
size_t i = 0; i < FEATURE_COUNT; ++i) {
154 apogeeRemaining_m += coeffs[i] * inputs[i];
159 predApogeeAlt_ = altitude_m + apogeeRemaining_m;
162 tToApogee_ = velocity_ms / decel;
163 predApogeeTs_ = currentTimestamp_ms +
static_cast<uint32_t
>(tToApogee_ * MS_TO_S_FACTOR);
167 lastTs_ = currentTimestamp_ms;
168 lastVel_ = velocity_ms;
169 numWarmups_ = std::min(numWarmups_ + 1, MAX_WARMUPS);
179 const float gravity = 9.80665F;
180 const float velocity = vve_.getEstimatedVelocity();
181 const float height = vve_.getEstimatedAltitude();
185 const float kVelocityEpsilon = 0.001F;
186 const float kVelocityScaleForAlpha = 150.0F;
187 const float kAlphaMin = 0.02F;
188 const float kAlphaMax = 0.25F;
189 const float kMinDragCoefficient = 0.00001F;
190 const float kApogeeFactor = 0.5F;
191 const float kBallisticDenominator = 2.0F;
195 if (velocity <= 0.0F)
197 predApogeeAlt_ = height;
203 const float acceleration = vve_.getInertialVerticalAcceleration();
206const float kMeasured = -(acceleration + gravity) /
207 (velocity * velocity + kVelocityEpsilon);
209 if (kMeasured > 0.0F && kMeasured < 1.0F)
211 float alpha = clamp(std::fabs(velocity) / kVelocityScaleForAlpha,
214 currentDragCoefficient = (1.0F - alpha) * currentDragCoefficient + alpha * kMeasured;
220 if (currentDragCoefficient > kMinDragCoefficient)
222 apogee = height + (kApogeeFactor / currentDragCoefficient) *
223 logf((gravity + currentDragCoefficient * velocity * velocity) / gravity);
228 apogee = height + (velocity * velocity) /
229 (kBallisticDenominator * gravity);
232 predApogeeAlt_ = apogee;