Skip to content
119 changes: 78 additions & 41 deletions tools/replay/logreader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ bool LogReader::load(const char *data, size_t size, std::atomic<bool> *abort) {
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;
requires_controls_migration = false;
}

if (!filters_.empty()) {
Expand Down Expand Up @@ -61,9 +61,7 @@ bool LogReader::load(const char *data, size_t size, std::atomic<bool> *abort) {
rWarning("Failed to parse log : %s.\nRetrieved %zu events from corrupt log", e.getDescription().cStr(), events.size());
}

if (requires_migration) {
migrateOldEvents();
}
migrateOldEvents();

if (!events.empty() && !(abort && *abort)) {
events.shrink_to_fit();
Expand All @@ -74,43 +72,82 @@ bool LogReader::load(const char *data, size_t size, std::atomic<bool> *abort) {
}

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<cereal::Event>();
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.getActiveDEPRECATED());
new_state.setAlertSize(old_state.getAlertSizeDEPRECATED());
new_state.setAlertSound(old_state.getAlertSound2DEPRECATED());
new_state.setAlertStatus(old_state.getAlertStatusDEPRECATED());
new_state.setAlertText1(old_state.getAlertText1DEPRECATED());
new_state.setAlertText2(old_state.getAlertText2DEPRECATED());
new_state.setAlertType(old_state.getAlertTypeDEPRECATED());
new_state.setEnabled(old_state.getEnabledDEPRECATED());
new_state.setEngageable(old_state.getEngageableDEPRECATED());
new_state.setExperimentalMode(old_state.getExperimentalModeDEPRECATED());
new_state.setPersonality(old_state.getPersonalityDEPRECATED());
new_state.setState(old_state.getStateDEPRECATED());

// Serialize the new event to the buffer
auto buf_size = msg.getSerializedSize();
auto buf = buffer_.allocate(buf_size);
msg.serializeToBuffer(reinterpret_cast<unsigned char *>(buf), buf_size);

// Store the migrated event in the events list
auto event_data = kj::arrayPtr(reinterpret_cast<const capnp::word *>(buf), buf_size);
events.emplace_back(new_evt.which(), new_evt.getLogMonoTime(), event_data);
for (const auto &event : events) {
if (event.which == cereal::Event::CONTROLS_STATE && requires_controls_migration) {
migrateControlsState(event.data);
} else if (event.which == cereal::Event::ONROAD_EVENTS_D_E_P_R_E_C_A_T_E_D) {
migrateOnroadEvents(event.data);
}
}
}

void LogReader::migrateControlsState(const kj::ArrayPtr<const capnp::word> &event_data) {
// Read the old event data
capnp::FlatArrayMessageReader reader(event_data);
auto old_evt = reader.getRoot<cereal::Event>();
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.getActiveDEPRECATED());
new_state.setAlertSize(old_state.getAlertSizeDEPRECATED());
new_state.setAlertSound(old_state.getAlertSound2DEPRECATED());
new_state.setAlertStatus(old_state.getAlertStatusDEPRECATED());
new_state.setAlertText1(old_state.getAlertText1DEPRECATED());
new_state.setAlertText2(old_state.getAlertText2DEPRECATED());
new_state.setAlertType(old_state.getAlertTypeDEPRECATED());
new_state.setEnabled(old_state.getEnabledDEPRECATED());
new_state.setEngageable(old_state.getEngageableDEPRECATED());
new_state.setExperimentalMode(old_state.getExperimentalModeDEPRECATED());
new_state.setPersonality(old_state.getPersonalityDEPRECATED());
new_state.setState(old_state.getStateDEPRECATED());

// Serialize the new event to the buffer
auto buf_size = msg.getSerializedSize();
auto buf = buffer_.allocate(buf_size);
msg.serializeToBuffer(reinterpret_cast<unsigned char *>(buf), buf_size);

// Store the migrated event in the events list
auto migrated_event_data = kj::arrayPtr(reinterpret_cast<const capnp::word *>(buf), buf_size);
events.emplace_back(new_evt.which(), new_evt.getLogMonoTime(), migrated_event_data);
}

void LogReader::migrateOnroadEvents(const kj::ArrayPtr<const capnp::word> &event_data) {
// Read the old event data
capnp::FlatArrayMessageReader reader(event_data);
auto old_evt = reader.getRoot<cereal::Event>();
auto old_state = old_evt.getOnroadEventsDEPRECATED();

MessageBuilder msg;
auto new_evt = msg.initEvent(old_evt.getValid());
new_evt.setLogMonoTime(old_evt.getLogMonoTime());

size_t new_onroad_events_size = old_state.size();
auto new_onroad_events = new_evt.initOnroadEvents(new_onroad_events_size);
for (size_t j = 0; j < new_onroad_events_size; j++) {
new_onroad_events[j].setName(ONROAD_EVENT_NAME_MAP.at(old_state[j].getName()));
new_onroad_events[j].setEnable(old_state[j].getEnable());
new_onroad_events[j].setNoEntry(old_state[j].getNoEntry());
new_onroad_events[j].setWarning(old_state[j].getWarning());
new_onroad_events[j].setUserDisable(old_state[j].getUserDisable());
new_onroad_events[j].setSoftDisable(old_state[j].getSoftDisable());
new_onroad_events[j].setImmediateDisable(old_state[j].getImmediateDisable());
new_onroad_events[j].setPreEnable(old_state[j].getPreEnable());
new_onroad_events[j].setPermanent(old_state[j].getPermanent());
new_onroad_events[j].setOverrideLateral(old_state[j].getOverrideLateral());
new_onroad_events[j].setOverrideLongitudinal(old_state[j].getOverrideLongitudinal());
}

// Serialize the new event to the buffer
auto buf_size = msg.getSerializedSize();
auto buf = buffer_.allocate(buf_size);
msg.serializeToBuffer(reinterpret_cast<unsigned char *>(buf), buf_size);

// Store the migrated event in the events list
auto migrated_event_data = kj::arrayPtr(reinterpret_cast<const capnp::word *>(buf), buf_size);
events.emplace_back(new_evt.which(), new_evt.getLogMonoTime(), migrated_event_data);
}
105 changes: 104 additions & 1 deletion tools/replay/logreader.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,112 @@
#pragma once

#include <map>
#include <string>
#include <vector>

#include "cereal/gen/cpp/log.capnp.h"
#include "tools/replay/util.h"

using OldOnroadEventName = cereal::OnroadEventDEPRECATED::EventName;
using NewOnroadEventName = cereal::OnroadEvent::EventName;

#define MAP_ONROAD_EVENT_NAME(name) {OldOnroadEventName::name, NewOnroadEventName::name}

static const std::map<OldOnroadEventName, NewOnroadEventName> ONROAD_EVENT_NAME_MAP = {
MAP_ONROAD_EVENT_NAME(CAN_ERROR),
MAP_ONROAD_EVENT_NAME(STEER_UNAVAILABLE),
MAP_ONROAD_EVENT_NAME(WRONG_GEAR),
MAP_ONROAD_EVENT_NAME(DOOR_OPEN),
MAP_ONROAD_EVENT_NAME(SEATBELT_NOT_LATCHED),
MAP_ONROAD_EVENT_NAME(ESP_DISABLED),
MAP_ONROAD_EVENT_NAME(WRONG_CAR_MODE),
MAP_ONROAD_EVENT_NAME(STEER_TEMP_UNAVAILABLE),
MAP_ONROAD_EVENT_NAME(REVERSE_GEAR),
MAP_ONROAD_EVENT_NAME(BUTTON_CANCEL),
MAP_ONROAD_EVENT_NAME(BUTTON_ENABLE),
MAP_ONROAD_EVENT_NAME(PEDAL_PRESSED),
MAP_ONROAD_EVENT_NAME(CRUISE_DISABLED),
MAP_ONROAD_EVENT_NAME(SPEED_TOO_LOW),
MAP_ONROAD_EVENT_NAME(OUT_OF_SPACE),
MAP_ONROAD_EVENT_NAME(OVERHEAT),
MAP_ONROAD_EVENT_NAME(CALIBRATION_INCOMPLETE),
MAP_ONROAD_EVENT_NAME(CALIBRATION_INVALID),
MAP_ONROAD_EVENT_NAME(CONTROLS_MISMATCH),
MAP_ONROAD_EVENT_NAME(PCM_ENABLE),
MAP_ONROAD_EVENT_NAME(PCM_DISABLE),
MAP_ONROAD_EVENT_NAME(RADAR_FAULT),
MAP_ONROAD_EVENT_NAME(BRAKE_HOLD),
MAP_ONROAD_EVENT_NAME(PARK_BRAKE),
MAP_ONROAD_EVENT_NAME(MANUAL_RESTART),
MAP_ONROAD_EVENT_NAME(JOYSTICK_DEBUG),
MAP_ONROAD_EVENT_NAME(STEER_TEMP_UNAVAILABLE_SILENT),
MAP_ONROAD_EVENT_NAME(RESUME_REQUIRED),
MAP_ONROAD_EVENT_NAME(PRE_DRIVER_DISTRACTED),
MAP_ONROAD_EVENT_NAME(PROMPT_DRIVER_DISTRACTED),
MAP_ONROAD_EVENT_NAME(DRIVER_DISTRACTED),
MAP_ONROAD_EVENT_NAME(PRE_DRIVER_UNRESPONSIVE),
MAP_ONROAD_EVENT_NAME(PROMPT_DRIVER_UNRESPONSIVE),
MAP_ONROAD_EVENT_NAME(DRIVER_UNRESPONSIVE),
MAP_ONROAD_EVENT_NAME(BELOW_STEER_SPEED),
MAP_ONROAD_EVENT_NAME(LOW_BATTERY),
MAP_ONROAD_EVENT_NAME(PARAMSD_TEMPORARY_ERROR),
MAP_ONROAD_EVENT_NAME(ACC_FAULTED),
MAP_ONROAD_EVENT_NAME(SENSOR_DATA_INVALID),
MAP_ONROAD_EVENT_NAME(COMM_ISSUE),
MAP_ONROAD_EVENT_NAME(TOO_DISTRACTED),
MAP_ONROAD_EVENT_NAME(POSENET_INVALID),
MAP_ONROAD_EVENT_NAME(PRE_LANE_CHANGE_LEFT),
MAP_ONROAD_EVENT_NAME(PRE_LANE_CHANGE_RIGHT),
MAP_ONROAD_EVENT_NAME(LANE_CHANGE),
MAP_ONROAD_EVENT_NAME(LOW_MEMORY),
MAP_ONROAD_EVENT_NAME(STOCK_AEB),
MAP_ONROAD_EVENT_NAME(LDW),
MAP_ONROAD_EVENT_NAME(CAR_UNRECOGNIZED),
MAP_ONROAD_EVENT_NAME(INVALID_LKAS_SETTING),
MAP_ONROAD_EVENT_NAME(SPEED_TOO_HIGH),
MAP_ONROAD_EVENT_NAME(LANE_CHANGE_BLOCKED),
MAP_ONROAD_EVENT_NAME(RELAY_MALFUNCTION),
MAP_ONROAD_EVENT_NAME(PRE_ENABLE_STANDSTILL),
MAP_ONROAD_EVENT_NAME(STOCK_FCW),
MAP_ONROAD_EVENT_NAME(STARTUP),
MAP_ONROAD_EVENT_NAME(STARTUP_NO_CAR),
MAP_ONROAD_EVENT_NAME(STARTUP_NO_CONTROL),
MAP_ONROAD_EVENT_NAME(STARTUP_MASTER),
MAP_ONROAD_EVENT_NAME(FCW),
MAP_ONROAD_EVENT_NAME(STEER_SATURATED),
MAP_ONROAD_EVENT_NAME(BELOW_ENGAGE_SPEED),
MAP_ONROAD_EVENT_NAME(NO_GPS),
MAP_ONROAD_EVENT_NAME(WRONG_CRUISE_MODE),
MAP_ONROAD_EVENT_NAME(MODELD_LAGGING),
MAP_ONROAD_EVENT_NAME(DEVICE_FALLING),
MAP_ONROAD_EVENT_NAME(FAN_MALFUNCTION),
MAP_ONROAD_EVENT_NAME(CAMERA_MALFUNCTION),
MAP_ONROAD_EVENT_NAME(PROCESS_NOT_RUNNING),
MAP_ONROAD_EVENT_NAME(DASHCAM_MODE),
MAP_ONROAD_EVENT_NAME(SELFDRIVE_INITIALIZING),
MAP_ONROAD_EVENT_NAME(USB_ERROR),
MAP_ONROAD_EVENT_NAME(LOCATIOND_TEMPORARY_ERROR),
MAP_ONROAD_EVENT_NAME(CRUISE_MISMATCH),
MAP_ONROAD_EVENT_NAME(GAS_PRESSED_OVERRIDE),
MAP_ONROAD_EVENT_NAME(COMM_ISSUE_AVG_FREQ),
MAP_ONROAD_EVENT_NAME(CAMERA_FRAME_RATE),
MAP_ONROAD_EVENT_NAME(CAN_BUS_MISSING),
MAP_ONROAD_EVENT_NAME(SELFDRIVED_LAGGING),
MAP_ONROAD_EVENT_NAME(RESUME_BLOCKED),
MAP_ONROAD_EVENT_NAME(STEER_OVERRIDE),
MAP_ONROAD_EVENT_NAME(STEER_TIME_LIMIT),
MAP_ONROAD_EVENT_NAME(VEHICLE_SENSORS_INVALID),
MAP_ONROAD_EVENT_NAME(CALIBRATION_RECALIBRATING),
MAP_ONROAD_EVENT_NAME(LOCATIOND_PERMANENT_ERROR),
MAP_ONROAD_EVENT_NAME(PARAMSD_PERMANENT_ERROR),
MAP_ONROAD_EVENT_NAME(ACTUATORS_API_UNAVAILABLE),
MAP_ONROAD_EVENT_NAME(ESP_ACTIVE),
MAP_ONROAD_EVENT_NAME(PERSONALITY_CHANGED),
MAP_ONROAD_EVENT_NAME(AEB),
MAP_ONROAD_EVENT_NAME(LONGITUDINAL_MANEUVER),
MAP_ONROAD_EVENT_NAME(STARTUP_NO_SEC_OC_KEY),
};

const CameraType ALL_CAMERAS[] = {RoadCam, DriverCam, WideRoadCam};
const int MAX_CAMERAS = std::size(ALL_CAMERAS);

Expand Down Expand Up @@ -34,9 +135,11 @@ class LogReader {

private:
void migrateOldEvents();
void migrateControlsState(const kj::ArrayPtr<const capnp::word> &event_data);
void migrateOnroadEvents(const kj::ArrayPtr<const capnp::word> &event_data);

std::string raw_;
bool requires_migration = true;
bool requires_controls_migration = true;
std::vector<bool> filters_;
MonotonicBuffer buffer_{1024 * 1024};
};
5 changes: 4 additions & 1 deletion tools/replay/replay.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ void Replay::setupSegmentManager(bool has_filters) {
if (has_filters) {
std::vector<bool> filters(sockets_.size(), false);
for (size_t i = 0; i < sockets_.size(); ++i) {
filters[i] = (i == cereal::Event::Which::INIT_DATA || i == cereal::Event::Which::CAR_PARAMS || sockets_[i]);
filters[i] = (i == cereal::Event::Which::INIT_DATA ||
i == cereal::Event::Which::CAR_PARAMS ||
i == cereal::Event::Which::ONROAD_EVENTS_D_E_P_R_E_C_A_T_E_D ||
sockets_[i]);
}
seg_mgr_->setFilters(filters);
}
Expand Down
Loading