Skip to content

Commit

Permalink
FIX: Do not store references to interpolated data
Browse files Browse the repository at this point in the history
- Copy the interpolated data
  * Especially when interpolating consecutive data (at different
timestamps)
  • Loading branch information
till213 committed Oct 12, 2024
1 parent 8066662 commit d400a21
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 51 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* The (obsolete) task number has now the correct 4 (instead of 6) digits
* The TAKEOFF declaration is now the actual first recorded position and the START declaration is now the coordinate of the first waypoint (previously it was the other way around)
* In analogy for the FINISH (last waypoint coordinate) and LANDING (last recorded position)
- The velocity, pitch bank and heading is calculated correctly again when *augmenting* imported flight data

# Under the Hood
- Added more flight import unit tests, covering now also the "flight augmentation" code
Expand Down
18 changes: 8 additions & 10 deletions src/Flight/src/FlightAugmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ void FlightAugmentation::augmentAttitudeAndVelocity(Aircraft &aircraft) noexcept
for (std::size_t i = 0; i < attitudeCount; ++i) {

if (i < attitudeCount - 1) {
AttitudeData currentAttitudeData = attitude[i];
auto &currentAttitudeData = attitude[i];
const auto currentTimestamp = currentAttitudeData.timestamp;
const auto nextTimeStamp = attitude[i + 1].timestamp;

const PositionData &currentPositionData = position.interpolate(currentTimestamp, NoTimeOffset);
const PositionData &nextPositionData = position.interpolate(nextTimeStamp, NoTimeOffset);
const auto currentPositionData = position.interpolate(currentTimestamp, NoTimeOffset);
const auto nextPositionData = position.interpolate(nextTimeStamp, NoTimeOffset);
const SkyMath::Coordinate currentPosition {currentPositionData.latitude, currentPositionData.longitude};
const SkyMath::Coordinate nextPosition {nextPositionData.latitude, nextPositionData.longitude};

Expand Down Expand Up @@ -194,10 +194,10 @@ void FlightAugmentation::augmentAttitudeAndVelocity(Aircraft &aircraft) noexcept

} else if (attitudeCount > 1) {
// Last point
AttitudeData &lastAttitudeData = attitude[i];
auto &lastAttitudeData = attitude[i];

// Velocity
AttitudeData &previousAttitudeData = attitude[i -1];
auto &previousAttitudeData = attitude[i -1];
if (d->aspects.testFlag(Aspect::Velocity)) {
lastAttitudeData.velocityBodyX = previousAttitudeData.velocityBodyX;
lastAttitudeData.velocityBodyY = previousAttitudeData.velocityBodyY;
Expand All @@ -218,7 +218,7 @@ void FlightAugmentation::augmentAttitudeAndVelocity(Aircraft &aircraft) noexcept
}
} else {
// Only one sampled data point ("academic case")
AttitudeData &lastAttitudeData = attitude[i];
auto &lastAttitudeData = attitude[i];

// Velocity
if (d->aspects.testFlag(Aspect::Velocity)) {
Expand Down Expand Up @@ -265,7 +265,6 @@ void FlightAugmentation::augmentStartProcedure(Aircraft &aircraft) noexcept
const auto lastTimestamp = aircraft.getPosition().getLast().timestamp;

if (d->aspects.testFlag(Aspect::Engine)) {

// Engine

auto &engine = aircraft.getEngine();
Expand Down Expand Up @@ -349,7 +348,6 @@ void FlightAugmentation::augmentStartProcedure(Aircraft &aircraft) noexcept
engineData.mixtureLeverPosition3 = SkyMath::fromPercent(75.0);
engineData.mixtureLeverPosition4 = SkyMath::fromPercent(75.0);
engine.upsertLast(engineData);

}

// Secondary flight controls
Expand Down Expand Up @@ -445,7 +443,7 @@ void FlightAugmentation::augmentStartProcedure(Aircraft &aircraft) noexcept
*/
void FlightAugmentation::augmentLandingProcedure(Aircraft &aircraft) noexcept
{
Position &position = aircraft.getPosition();
auto &position = aircraft.getPosition();
const auto lastTimestamp = position.getLast().timestamp;

// Engine
Expand Down Expand Up @@ -671,7 +669,7 @@ void FlightAugmentation::augmentLandingProcedure(Aircraft &aircraft) noexcept
// Adjust approach pitch for the last 3 minutes
// https://forum.aerosoft.com/index.php?/topic/123864-a320-pitch-angle-during-landing/
if (d->aspects.testFlag(Aspect::Pitch)) {
Attitude &attitude = aircraft.getAttitude();
auto &attitude = aircraft.getAttitude();
const auto attitudeCount = attitude.count();
if (attitudeCount > 0) {
auto index = attitudeCount - 1;
Expand Down
48 changes: 24 additions & 24 deletions src/PluginManager/src/Export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ std::vector<PositionData> Export::resamplePositionDataForExport(const Aircraft &
Position &position = aircraft.getPosition();
if (position.count() > 0) {
if (resamplingPeriod != SampleRate::ResamplingPeriod::Original) {
const std::int64_t duration = position.getLast().timestamp;
const std::int64_t deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp = 0;
const auto duration = position.getLast().timestamp;
const auto deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp {0};
while (timestamp <= duration) {
const PositionData &data = position.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
const auto data = position.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
if (!data.isNull()) {
interpolatedData.push_back(data);
}
Expand All @@ -115,11 +115,11 @@ std::vector<EngineData> Export::resampleEngineDataForExport(const Aircraft &airc
auto &engine = aircraft.getEngine();
if (engine.count() > 0) {
if (resamplingPeriod != SampleRate::ResamplingPeriod::Original) {
const std::int64_t duration = engine.getLast().timestamp;
const std::int64_t deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp = 0;
const auto duration = engine.getLast().timestamp;
const auto deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp {0};
while (timestamp <= duration) {
const EngineData &data = engine.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
const auto data = engine.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
if (!data.isNull()) {
interpolatedData.push_back(data);
}
Expand All @@ -141,11 +141,11 @@ std::vector<PrimaryFlightControlData> Export::resamplePrimaryFlightControlDataFo
auto &primaryFlightControl = aircraft.getPrimaryFlightControl();
if (primaryFlightControl.count() > 0) {
if (resamplingPeriod != SampleRate::ResamplingPeriod::Original) {
const std::int64_t duration = primaryFlightControl.getLast().timestamp;
const std::int64_t deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp = 0;
const auto duration = primaryFlightControl.getLast().timestamp;
const auto deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp {0};
while (timestamp <= duration) {
const PrimaryFlightControlData &data = primaryFlightControl.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
const auto data = primaryFlightControl.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
if (!data.isNull()) {
interpolatedData.push_back(data);
}
Expand All @@ -167,11 +167,11 @@ std::vector<SecondaryFlightControlData> Export::resampleSecondaryFlightControlDa
auto &secondaryFlightControl = aircraft.getSecondaryFlightControl();
if (secondaryFlightControl.count() > 0) {
if (resamplingPeriod != SampleRate::ResamplingPeriod::Original) {
const std::int64_t duration = secondaryFlightControl.getLast().timestamp;
const std::int64_t deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp = 0;
const auto duration = secondaryFlightControl.getLast().timestamp;
const auto deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp {0};
while (timestamp <= duration) {
const SecondaryFlightControlData &data = secondaryFlightControl.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
const auto data = secondaryFlightControl.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
if (!data.isNull()) {
interpolatedData.push_back(data);
}
Expand All @@ -193,11 +193,11 @@ std::vector<AircraftHandleData> Export::resampleAircraftHandleDataForExport(cons
auto &aircraftHandle = aircraft.getAircraftHandle();
if (aircraftHandle.count() > 0) {
if (resamplingPeriod != SampleRate::ResamplingPeriod::Original) {
const std::int64_t duration = aircraftHandle.getLast().timestamp;
const std::int64_t deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp = 0;
const auto duration = aircraftHandle.getLast().timestamp;
const auto deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp {0};
while (timestamp <= duration) {
const AircraftHandleData &data = aircraftHandle.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
const auto data = aircraftHandle.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
if (!data.isNull()) {
interpolatedData.push_back(data);
}
Expand All @@ -219,11 +219,11 @@ std::vector<LightData> Export::resampleLightDataForExport(const Aircraft &aircra
auto &light = aircraft.getLight();
if (light.count() > 0) {
if (resamplingPeriod != SampleRate::ResamplingPeriod::Original) {
const std::int64_t duration = light.getLast().timestamp;
const std::int64_t deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp = 0;
const auto duration = light.getLast().timestamp;
const auto deltaTime = Enum::underly(resamplingPeriod);
std::int64_t timestamp {0};
while (timestamp <= duration) {
const LightData &data = light.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
const auto data = light.interpolate(timestamp, TimeVariableData::Access::NoTimeOffset);
if (!data.isNull()) {
interpolatedData.push_back(data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,8 @@ bool MSFSSimConnectPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeV
if (objectId != SimConnectAi::InvalidObjectId) {

ok = true;
const auto &positionData = aircraft.getPosition().interpolate(currentTimestamp, access);
const auto &attitudeData = aircraft.getAttitude().interpolate(currentTimestamp, access);
const auto positionData = aircraft.getPosition().interpolate(currentTimestamp, access);
const auto attitudeData = aircraft.getAttitude().interpolate(currentTimestamp, access);
if (!positionData.isNull()) {
SimConnectPositionAndAttitudeAll simConnnectPositionAndAttitudeAll {positionData, attitudeData};
if (isUserAircraft) {
Expand All @@ -436,7 +436,7 @@ bool MSFSSimConnectPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeV

// Engine
if (ok) {
const EngineData &engineData = aircraft.getEngine().interpolate(currentTimestamp, access);
const auto engineData = aircraft.getEngine().interpolate(currentTimestamp, access);
if (!engineData.isNull()) {
SimConnectEngineAll simConnectEngineAll {engineData};
if (isUserAircraft) {
Expand Down Expand Up @@ -464,7 +464,7 @@ bool MSFSSimConnectPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeV

// Primary flight controls
if (ok) {
const PrimaryFlightControlData &primaryFlightControlData = aircraft.getPrimaryFlightControl().interpolate(currentTimestamp, access);
const auto primaryFlightControlData = aircraft.getPrimaryFlightControl().interpolate(currentTimestamp, access);
if (!primaryFlightControlData.isNull()) {
SimConnectPrimaryFlightControlAll simConnectPrimaryFlightControlAll {primaryFlightControlData};
if (isUserAircraft) {
Expand All @@ -483,7 +483,7 @@ bool MSFSSimConnectPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeV

// Secondary flight controls
if (ok) {
const SecondaryFlightControlData &secondaryFlightControlData = aircraft.getSecondaryFlightControl().interpolate(currentTimestamp, access);
const auto secondaryFlightControlData = aircraft.getSecondaryFlightControl().interpolate(currentTimestamp, access);
if (!secondaryFlightControlData.isNull()) {
SimConnectSecondaryFlightControlAll simConnectSecondaryFlightControlAll {secondaryFlightControlData};
if (isUserAircraft) {
Expand All @@ -502,7 +502,7 @@ bool MSFSSimConnectPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeV

// Aircraft handles & brakes
if (ok) {
const AircraftHandleData &aircraftHandleData = aircraft.getAircraftHandle().interpolate(currentTimestamp, access);
const auto aircraftHandleData = aircraft.getAircraftHandle().interpolate(currentTimestamp, access);
if (!aircraftHandleData.isNull()) {
SimConnectAircraftHandleAll simConnectAircraftHandleAll {aircraftHandleData};
if (isUserAircraft) {
Expand Down Expand Up @@ -530,7 +530,7 @@ bool MSFSSimConnectPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeV

// Lights
if (ok) {
const LightData &lightData = aircraft.getLight().interpolate(currentTimestamp, access);
const auto lightData = aircraft.getLight().interpolate(currentTimestamp, access);
if (!lightData.isNull()) {
SimConnectLightAll simConnectLightAll {lightData};
if (isUserAircraft) {
Expand Down
4 changes: 2 additions & 2 deletions src/Plugins/Connect/MSFSSimConnectPlugin/src/SimConnectAi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ void SimConnectAi::addObject(const Aircraft &aircraft, std::int64_t timestamp) n
const auto &aircraftInfo = aircraft.getAircraftInfo();
const auto &position = aircraft.getPosition();
const auto &attitude = aircraft.getAttitude();
const auto &positionData = position.interpolate(timestamp, TimeVariableData::Access::DiscreteSeek);
const auto &attitudeData = attitude.interpolate(timestamp, TimeVariableData::Access::DiscreteSeek);
const auto positionData = position.interpolate(timestamp, TimeVariableData::Access::DiscreteSeek);
const auto attitudeData = attitude.interpolate(timestamp, TimeVariableData::Access::DiscreteSeek);
const ::SIMCONNECT_DATA_INITPOSITION initialPosition = SimConnectPositionAndAttitudeAll::toInitialPosition(positionData, attitudeData, aircraftInfo.initialAirspeed);

const ::SIMCONNECT_DATA_REQUEST_ID requestId = Enum::underly(SimConnectType::DataRequest::AiObjectBase) + d->lastAiCreateRequestId;
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/Connect/PathCreator/src/PathCreatorPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ bool PathCreatorPlugin::sendAircraftData(std::int64_t currentTimestamp, TimeVari
bool dataAvailable {false};
if (currentTimestamp <= getCurrentFlight().getTotalDurationMSec()) {
dataAvailable = true;
const PositionData &currentPositionData = getCurrentFlight().getUserAircraft().getPosition().interpolate(getCurrentTimestamp(), access);
const PositionData currentPositionData = getCurrentFlight().getUserAircraft().getPosition().interpolate(getCurrentTimestamp(), access);
if (!currentPositionData.isNull()) {
// Start the elapsed timer after sending the first sample data
if (!isElapsedTimerRunning()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ bool FlightRadar24CsvWriter::write(const FlightData &flightData, const Aircraft
const QString callSign = flightData.flightNumber;
const auto interpolatedPositionData = Export::resamplePositionDataForExport(aircraft, d->pluginSettings.getResamplingPeriod());
for (const auto &positionData : interpolatedPositionData) {
const auto &attitudeData = aircraft.getAttitude().interpolate(positionData.timestamp, TimeVariableData::Access::NoTimeOffset);
const auto attitudeData = aircraft.getAttitude().interpolate(positionData.timestamp, TimeVariableData::Access::NoTimeOffset);
const auto dateTimeUtc = startDateTimeUtc.addMSecs(positionData.timestamp);
const auto secsSinceEpoch = dateTimeUtc.toSecsSinceEpoch();
const QString csv = QString::number(secsSinceEpoch) % Csv::CommaSep %
Expand Down
10 changes: 5 additions & 5 deletions src/Plugins/Flight/Export/IgcExport/src/IgcExportPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,12 +285,12 @@ inline bool IgcExportPlugin::exportFixes(const FlightData &flightData, const Air
const double heightAboveEllipsoid = convert.geoidToEllipsoidHeight(Convert::feetToMeters(positionData.altitude), positionData.latitude, positionData.longitude);

const int gnssAltitude = static_cast<int>(std::round(heightAboveEllipsoid));
const QByteArray gnssAltitudeByteArray = formatNumber(gnssAltitude, 5);
const auto gnssAltitudeByteArray = formatNumber(gnssAltitude, 5);
const int pressureAltitude = static_cast<int>(std::round(Convert::feetToMeters(positionData.pressureAltitude)));
const QByteArray pressureAltitudeByteArray = formatNumber(pressureAltitude, 5);
const EngineData &engineData = engine.interpolate(positionData.timestamp, TimeVariableData::Access::Linear);
const auto pressureAltitudeByteArray = formatNumber(pressureAltitude, 5);
const auto engineData = engine.interpolate(positionData.timestamp, TimeVariableData::Access::Linear);
const int noise = estimateEnvironmentalNoise(engineData);
const QDateTime currentTime = startTime.addMSecs(positionData.timestamp);
const auto currentTime = startTime.addMSecs(positionData.timestamp);
const QByteArray bRecord = IgcExportPluginPrivate::BRecord %
formatTime(currentTime) %
formatPosition(positionData.latitude, positionData.longitude) %
Expand All @@ -305,7 +305,7 @@ inline bool IgcExportPlugin::exportFixes(const FlightData &flightData, const Air

if (ok && (lastKFixTime.isNull() || lastKFixTime.secsTo(currentTime) >= ::KRecordIntervalSec)) {
const auto &attitude = aircraft.getAttitude();
const auto &attitudeData = attitude.interpolate(positionData.timestamp, TimeVariableData::Access::NoTimeOffset);
const auto attitudeData = attitude.interpolate(positionData.timestamp, TimeVariableData::Access::NoTimeOffset);
const auto trueAirspeed = Convert::feetPerSecondToKilometersPerHour(attitudeData.velocityBodyZ);
const auto indicatedAirspeed = Convert::trueToIndicatedAirspeed(trueAirspeed, positionData.altitude);
const QByteArray kRecord = IgcExportPluginPrivate::KRecord %
Expand Down
2 changes: 1 addition & 1 deletion src/Plugins/Module/Formation/src/Formation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ std::pair<PositionData, AttitudeData> Formation::calculateRelativePositionToUser
const auto &aircraft = flight.getUserAircraft();
const auto &position = aircraft.getPosition();
if (position.count() > 0) {
const auto &positionData = position.interpolate(timestamp, TimeVariableData::Access::DiscreteSeek);
const auto positionData = position.interpolate(timestamp, TimeVariableData::Access::DiscreteSeek);
const auto &aircraftInfo = aircraft.getAircraftInfo();
const auto &aircraftType = aircraftInfo.aircraftType;

Expand Down

0 comments on commit d400a21

Please sign in to comment.