Port FluidSim core and scenarios to C++20
This commit is contained in:
64
include/FluidSim/DynoCurve.hpp
Normal file
64
include/FluidSim/DynoCurve.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace fluidsim::port {
|
||||
|
||||
struct DynoPoint {
|
||||
float power_kw{};
|
||||
float torque_nm{};
|
||||
};
|
||||
|
||||
// Shared rolling peak curve from the C# Scenario base class. Each bin stores
|
||||
// the greatest observed power and torque independently, with missing bins
|
||||
// interpolated when the engine crosses an RPM range too quickly to sample it.
|
||||
class DynoCurve {
|
||||
public:
|
||||
static constexpr float rpm_bin_size = 50.0f;
|
||||
|
||||
void reset() {
|
||||
bins_.clear();
|
||||
last_bin_ = invalid_bin;
|
||||
}
|
||||
|
||||
void update(float rpm, float power_kw, float torque_nm) {
|
||||
if (!std::isfinite(rpm) || rpm <= 0.0f || !std::isfinite(power_kw) || !std::isfinite(torque_nm))
|
||||
return;
|
||||
const auto bin = static_cast<std::size_t>(rpm / rpm_bin_size);
|
||||
if (bin >= bins_.max_size()) return;
|
||||
while (bins_.size() <= bin) bins_.push_back({});
|
||||
|
||||
if (last_bin_ != invalid_bin && bin > last_bin_ + 1) {
|
||||
const float last_power = bins_[last_bin_].power_kw > 0.0f ? bins_[last_bin_].power_kw : 0.0f;
|
||||
const float last_torque = bins_[last_bin_].torque_nm > 0.0f ? bins_[last_bin_].torque_nm : 0.0f;
|
||||
for (std::size_t missing = last_bin_ + 1; missing < bin; ++missing) {
|
||||
const float t = static_cast<float>(missing - last_bin_) /
|
||||
static_cast<float>(bin - last_bin_);
|
||||
const float interpolated_power = last_power + (power_kw - last_power) * t;
|
||||
const float interpolated_torque = last_torque + (torque_nm - last_torque) * t;
|
||||
auto& point = bins_[missing];
|
||||
if (interpolated_power > point.power_kw || point.power_kw <= 0.0f)
|
||||
point.power_kw = interpolated_power;
|
||||
if (interpolated_torque > point.torque_nm || point.torque_nm <= 0.0f)
|
||||
point.torque_nm = interpolated_torque;
|
||||
}
|
||||
}
|
||||
|
||||
auto& current = bins_[bin];
|
||||
if (power_kw > current.power_kw || current.power_kw <= 0.0f) current.power_kw = power_kw;
|
||||
if (torque_nm > current.torque_nm || current.torque_nm <= 0.0f) current.torque_nm = torque_nm;
|
||||
last_bin_ = bin;
|
||||
}
|
||||
|
||||
const std::vector<DynoPoint>& bins() const { return bins_; }
|
||||
|
||||
private:
|
||||
static constexpr std::size_t invalid_bin = static_cast<std::size_t>(-1);
|
||||
std::vector<DynoPoint> bins_;
|
||||
std::size_t last_bin_{invalid_bin};
|
||||
};
|
||||
|
||||
} // namespace fluidsim::port
|
||||
Reference in New Issue
Block a user