diff --git a/tools/replay/logreader.cc b/tools/replay/logreader.cc index 415b8c0b5e..d751868de3 100644 --- a/tools/replay/logreader.cc +++ b/tools/replay/logreader.cc @@ -32,6 +32,9 @@ bool LogReader::load(const char *data, size_t size, std::atomic *abort) { auto which = event.which(); auto event_data = kj::arrayPtr(words.begin(), reader.getEnd()); words = kj::arrayPtr(reader.getEnd(), words.end()); + if (which == cereal::Event::Which::SELFDRIVE_STATE) { + requires_migration = false; + } if (!filters_.empty()) { if (which >= filters_.size() || !filters_[which]) @@ -58,6 +61,10 @@ bool LogReader::load(const char *data, size_t size, std::atomic *abort) { rWarning("Failed to parse log : %s.\nRetrieved %zu events from corrupt log", e.getDescription().cStr(), events.size()); } + if (requires_migration) { + migrateOldEvents(); + } + if (!events.empty() && !(abort && *abort)) { events.shrink_to_fit(); std::sort(events.begin(), events.end()); @@ -65,3 +72,45 @@ bool LogReader::load(const char *data, size_t size, std::atomic *abort) { } return false; } + +void LogReader::migrateOldEvents() { + size_t events_size = events.size(); + for (int i = 0; i < events_size; ++i) { + // Check if the event is of the old CONTROLS_STATE type + auto &event = events[i]; + if (event.which == cereal::Event::CONTROLS_STATE) { + // Read the old event data + capnp::FlatArrayMessageReader reader(event.data); + auto old_evt = reader.getRoot(); + auto old_state = old_evt.getControlsState(); + + // Migrate relevant fields from old CONTROLS_STATE to new SelfdriveState + MessageBuilder msg; + auto new_evt = msg.initEvent(old_evt.getValid()); + new_evt.setLogMonoTime(old_evt.getLogMonoTime()); + auto new_state = new_evt.initSelfdriveState(); + + new_state.setActive(old_state.getActive()); + new_state.setAlertSize(old_state.getAlertSize()); + new_state.setAlertSound(old_state.getAlertSound()); + new_state.setAlertStatus(old_state.getAlertStatus()); + new_state.setAlertText1(old_state.getAlertText1()); + new_state.setAlertText2(old_state.getAlertText2()); + new_state.setAlertType(old_state.getAlertType()); + new_state.setEnabled(old_state.getEnabled()); + new_state.setEngageable(old_state.getEngageable()); + new_state.setExperimentalMode(old_state.getExperimentalMode()); + new_state.setPersonality(old_state.getPersonality()); + new_state.setState(old_state.getState()); + + // Serialize the new event to the buffer + auto buf_size = msg.getSerializedSize(); + auto buf = buffer_.allocate(buf_size); + msg.serializeToBuffer(reinterpret_cast(buf), buf_size); + + // Store the migrated event in the events list + auto event_data = kj::arrayPtr(reinterpret_cast(buf), buf_size); + events.emplace_back(new_evt.which(), new_evt.getLogMonoTime(), event_data); + } + } +} diff --git a/tools/replay/logreader.h b/tools/replay/logreader.h index 782c00b90a..ab35954db6 100644 --- a/tools/replay/logreader.h +++ b/tools/replay/logreader.h @@ -34,7 +34,10 @@ public: std::vector events; private: + void migrateOldEvents(); + std::string raw_; + bool requires_migration = true; std::vector filters_; MonotonicBuffer buffer_{1024 * 1024}; }; diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index b7c55294fd..34dd33bc1a 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -171,7 +171,7 @@ void Replay::buildTimeline() { std::vector> timeline; for (const Event &e : log->events) { - if (e.which == cereal::Event::Which::CONTROLS_STATE) { + if (e.which == cereal::Event::Which::SELFDRIVE_STATE) { capnp::FlatArrayMessageReader reader(e.data); auto event = reader.getRoot(); auto cs = event.getSelfdriveState();