Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions src/data/Track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "rapidjson/filewritestream.h"

const uint64_t Track::MAX_INDEX = 65535;
const uint64_t Track::MAX_HISTORY = 100;
const std::string Track::STATE_ACTIVE = "ACTIVE";
const std::string Track::STATE_TENTATIVE = "TENTATIVE";
const std::string Track::STATE_COASTING = "COASTING";
Expand All @@ -36,12 +37,21 @@ std::string Track::uint2hex(uint64_t number)
void Track::set_state(uint64_t index, std::string _state)
{
state.at(index).push_back(_state);
if (state.at(index).size() > MAX_HISTORY)
{
state.at(index).erase(state.at(index).begin());
}
}

void Track::set_current(uint64_t index, Detection smoothed)
{
current.at(index) = smoothed;
associated.at(index).push_back(smoothed);
nAssociated.at(index)++;
if (associated.at(index).size() > MAX_HISTORY)
{
associated.at(index).erase(associated.at(index).begin());
}
}

void Track::set_acceleration(uint64_t index, double _acceleration)
Expand Down Expand Up @@ -92,6 +102,11 @@ uint64_t Track::get_nInactive(uint64_t index)
return nInactive.at(index);
}

uint64_t Track::get_nAssociated(uint64_t index)
{
return nAssociated.at(index);
}

uint64_t Track::add(Detection initial)
{
id.push_back(uint2hex(iNext));
Expand All @@ -103,6 +118,7 @@ uint64_t Track::add(Detection initial)
std::vector<Detection> _associated;
_associated.push_back(initial);
associated.push_back(_associated);
nAssociated.push_back(1);
nInactive.push_back(0);
iNext++;
if (iNext >= MAX_INDEX)
Expand Down Expand Up @@ -167,6 +183,12 @@ void Track::remove(uint64_t index)
} else {
throw std::out_of_range("Index out of bounds for 'associated' vector");
}

if (index < nAssociated.size()) {
nAssociated.erase(nAssociated.begin() + index);
} else {
throw std::out_of_range("Index out of bounds for 'nAssociated' vector");
}
}

std::string Track::to_json(uint64_t timestamp)
Expand Down Expand Up @@ -195,7 +217,7 @@ std::string Track::to_json(uint64_t timestamp)
document.GetAllocator());
object1.AddMember("acceleration",
acceleration.at(i), document.GetAllocator());
object1.AddMember("n", associated.at(i).size(),
object1.AddMember("n", get_nAssociated(i),
document.GetAllocator());
rapidjson::Value associatedDelay(rapidjson::kArrayType);
rapidjson::Value associatedDoppler(rapidjson::kArrayType);
Expand Down Expand Up @@ -233,4 +255,4 @@ std::string Track::to_json(uint64_t timestamp)
document.Accept(writer);

return strbuf.GetString();
}
}
14 changes: 12 additions & 2 deletions src/data/Track.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Track
/// @brief Track ID (4 digit alpha-numeric).
std::vector<std::string> id;

/// @brief State history for each track.
/// @brief State history for each track, most recent MAX_HISTORY entries only.
std::vector<std::vector<std::string>> state;

/// @brief Curent track position.
Expand All @@ -37,9 +37,12 @@ class Track
/// @brief Current acceleration (Hz/s).
std::vector<double> acceleration;

/// @brief Associated detections in track.
/// @brief Associated detections in track, most recent MAX_HISTORY entries only.
std::vector<std::vector<Detection>> associated;

/// @brief Total number of detections ever associated with each track.
std::vector<uint64_t> nAssociated;

/// @brief Number of updates the track has been tentative/coasting.
/// @details Forms criteria for track deletion.
std::vector<uint64_t> nInactive;
Expand All @@ -50,6 +53,9 @@ class Track
/// @brief Maximum integer index to wrap around.
static const uint64_t MAX_INDEX;

/// @brief Maximum retained state and associated detection history.
static const uint64_t MAX_HISTORY;

/// @brief String for state ACTIVE.
static const std::string STATE_ACTIVE;

Expand Down Expand Up @@ -127,6 +133,10 @@ class Track
/// @return Number of updates track has been tentative/coasting.
uint64_t get_nInactive(uint64_t index);

/// @brief Get total number of detections ever associated with a track.
/// @return Total number of associated detections.
uint64_t get_nAssociated(uint64_t index);

/// @brief Update an associated detection.
/// @param index Index of track to change.
/// @param update New associated detection.
Expand Down
31 changes: 30 additions & 1 deletion test/unit/process/tracker/TestTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "process/tracker/Tracker.h"
#include "data/meta/Constants.h"

#include "rapidjson/document.h"

#include <string>
#include <vector>
#include <random>
Expand Down Expand Up @@ -81,4 +83,31 @@ TEST_CASE("Test predict", "[predict]")
Catch::Matchers::WithinAbs(prediction_truth.get_delay().front(), 0.01));
CHECK_THAT(prediction.get_doppler().front(),
Catch::Matchers::WithinAbs(prediction_truth.get_doppler().front(), 0.01));
}
}

/// @brief Test that long-lived track histories remain bounded.
TEST_CASE("Track history is bounded for a long-lived track", "[track]")
{
Track track;
Detection initial(10, -20, 0);
uint64_t index = track.add(initial);

uint32_t nCycles = 500;
for (uint32_t i = 0; i < nCycles; i++)
{
track.set_current(index, initial);
track.set_state(index, "ASSOCIATED");
}

CHECK(track.get_nAssociated(index) == nCycles + 1);

std::string json = track.to_json(0);
rapidjson::Document doc;
doc.Parse(json.c_str());
const rapidjson::Value& data = doc["data"][0];

CHECK(data["n"].GetUint64() == nCycles + 1);
CHECK(data["associated_delay"].Size() <= 100);
CHECK(data["associated_doppler"].Size() <= 100);
CHECK(data["associated_state"].Size() <= 100);
}