diff --git a/src/data/Track.cpp b/src/data/Track.cpp index 5cd7585..b1b3627 100644 --- a/src/data/Track.cpp +++ b/src/data/Track.cpp @@ -13,6 +13,7 @@ const uint64_t Track::MAX_INDEX = 65535; const std::string Track::STATE_ACTIVE = "ACTIVE"; const std::string Track::STATE_TENTATIVE = "TENTATIVE"; const std::string Track::STATE_COASTING = "COASTING"; +const std::string Track::STATE_ASSOCIATED = "ASSOCIATED"; // constructor Track::Track() @@ -33,7 +34,7 @@ std::string Track::uint2hex(uint64_t number) void Track::set_state(uint64_t index, std::string _state) { - state.at(index) = _state; + state.at(index).push_back(_state); } void Track::set_current(uint64_t index, Detection smoothed) @@ -57,7 +58,7 @@ uint64_t Track::get_nActive() uint64_t n = 0; for (size_t i = 0; i < id.size(); i++) { - if (state.at(i) == STATE_ACTIVE) + if (get_state(i) == STATE_ACTIVE) { n++; } @@ -70,7 +71,7 @@ uint64_t Track::get_nTentative() uint64_t n = 0; for (size_t i = 0; i < id.size(); i++) { - if (state.at(i) == STATE_TENTATIVE) + if (get_state(i) == STATE_TENTATIVE) { n++; } @@ -95,7 +96,7 @@ double Track::get_acceleration(uint64_t index) std::string Track::get_state(uint64_t index) { - return state.at(index); + return state.at(index).at(state.at(index).size()-1); } uint64_t Track::get_nInactive(uint64_t index) @@ -106,7 +107,9 @@ uint64_t Track::get_nInactive(uint64_t index) uint64_t Track::add(Detection initial) { id.push_back(uint2hex(iNext)); - state.push_back(STATE_TENTATIVE); + std::vector _state; + _state.push_back(STATE_TENTATIVE); + state.push_back(_state); current.push_back(initial); acceleration.push_back(0); std::vector _associated; @@ -121,6 +124,27 @@ uint64_t Track::add(Detection initial) return id.size()-1; } +void Track::promote(uint64_t index, uint32_t m, uint32_t n) +{ + if (state.at(index).size() >= n) + { + uint32_t _m = 0; + for (size_t i = state.at(index).size()-n; i < state.at(index).size(); i++) + { + if (state.at(index).at(i) == STATE_ACTIVE || + state.at(index).at(i) == STATE_ASSOCIATED) + { + _m++; + } + } + // promote track to ACTIVE if passes test + if (_m >= m) + { + state.at(index).at(state.at(index).size()-1) = STATE_ACTIVE; + } + } +} + void Track::remove(uint64_t index) { id.erase(id.begin() + index); @@ -141,7 +165,7 @@ std::string Track::to_json(uint64_t timestamp) rapidjson::Value value; for (int i = 0; i < get_n(); i++) { - if (state.at(i) != STATE_TENTATIVE) + if (get_state(i) != STATE_TENTATIVE) { value = rapidjson::StringRef(id.at(i).c_str()); arrayId.PushBack(value, allocator); diff --git a/src/data/Track.h b/src/data/Track.h index d6d0b8b..87e42ea 100644 --- a/src/data/Track.h +++ b/src/data/Track.h @@ -2,9 +2,10 @@ /// @class Track /// @brief A class to store track data. /// @details The ID is 4 digit hexadecimal with 16^4 = 65536 combinations. -/// @details The state can be TENTATIVE, ACTIVE or COASTING. +/// @details The state can be TENTATIVE, ASSOCIATED, ACTIVE or COASTING. /// @details Associated detections use null detections when no updates. /// @author 30hours +/// @todo I feel promote() should be implemented in the tracker. #ifndef TRACK_H #define TRACK_H @@ -19,11 +20,10 @@ class Track { private: /// @brief Track ID (4 digit alpha-numeric). - //std::unique_ptr> id; std::vector id; - /// @brief Current state (see VALID_STATE). - std::vector state; + /// @brief State history for each track. + std::vector> state; /// @brief Curent track position. std::vector current; @@ -53,6 +53,9 @@ private: /// @brief String for state COASTING. static const std::string STATE_COASTING; + /// @brief String for state ASSOCIATED. + static const std::string STATE_ASSOCIATED; + public: /// @brief Constructor. /// @return The object. @@ -68,7 +71,7 @@ public: /// @return hex Hexadecimal number. std::string uint2hex(uint64_t number); - /// @brief Set the state of a track. + /// @brief Set the state of the latest tracklet. /// @param index Index of track to change. /// @param state Updated state. /// @return Void. @@ -134,6 +137,12 @@ public: /// @return Index of last track. uint64_t add(Detection initial); + /// @brief Promote track to state ACTIVE if applicable. + /// @details Uses M of N rule for ACTIVE tracks. + /// @param index Index of track to change. + /// @return Void. + void promote(uint64_t index, uint32_t m, uint32_t n); + /// @brief Remove track based on index. /// @param index Index of track to remove. /// @return Void. diff --git a/src/process/tracker/Tracker.cpp b/src/process/tracker/Tracker.cpp index 8fae686..7fe4002 100644 --- a/src/process/tracker/Tracker.cpp +++ b/src/process/tracker/Tracker.cpp @@ -81,13 +81,14 @@ void Tracker::update(Detection *detection, uint64_t current) { Detection associated(delay[j], doppler[j], snr[j]); track.set_current(i, associated); - state = "ACTIVE"; - track.set_state(i, state); track.set_acceleration(i, (doppler[j]-dopplerTrack)/T); track.set_nInactive(i, 0); doNotInitiate[j] = true; + state = "ASSOCIATED"; + track.set_state(i, state); + // check for track promotion + track.promote(i, m, n); break; - // todo: check for track promotion } } @@ -98,6 +99,10 @@ void Tracker::update(Detection *detection, uint64_t current) state = "COASTING"; track.set_state(i, state); } + else + { + track.set_state(i, track.get_state(i)); + } track.set_nInactive(i, track.get_nInactive(i)+1); // remove if tentative or coasting too long