|
|
@ -148,7 +148,9 @@ void Replay::buildTimeline() { |
|
|
|
|
|
|
|
|
|
|
|
for (const Event *e : log->events) { |
|
|
|
for (const Event *e : log->events) { |
|
|
|
if (e->which == cereal::Event::Which::CONTROLS_STATE) { |
|
|
|
if (e->which == cereal::Event::Which::CONTROLS_STATE) { |
|
|
|
auto cs = e->event.getControlsState(); |
|
|
|
capnp::FlatArrayMessageReader reader(e->data); |
|
|
|
|
|
|
|
auto event = reader.getRoot<cereal::Event>(); |
|
|
|
|
|
|
|
auto cs = event.getControlsState(); |
|
|
|
|
|
|
|
|
|
|
|
if (engaged != cs.getEnabled()) { |
|
|
|
if (engaged != cs.getEnabled()) { |
|
|
|
if (engaged) { |
|
|
|
if (engaged) { |
|
|
@ -232,6 +234,7 @@ void Replay::queueSegment() { |
|
|
|
|
|
|
|
|
|
|
|
auto begin = std::prev(cur, std::min<int>(segment_cache_limit / 2, std::distance(segments_.begin(), cur))); |
|
|
|
auto begin = std::prev(cur, std::min<int>(segment_cache_limit / 2, std::distance(segments_.begin(), cur))); |
|
|
|
auto end = std::next(begin, std::min<int>(segment_cache_limit, std::distance(begin, segments_.end()))); |
|
|
|
auto end = std::next(begin, std::min<int>(segment_cache_limit, std::distance(begin, segments_.end()))); |
|
|
|
|
|
|
|
begin = std::prev(end, std::min<int>(segment_cache_limit, std::distance(segments_.begin(), end))); |
|
|
|
// load one segment at a time
|
|
|
|
// load one segment at a time
|
|
|
|
auto it = std::find_if(cur, end, [](auto &it) { return !it.second || !it.second->isLoaded(); }); |
|
|
|
auto it = std::find_if(cur, end, [](auto &it) { return !it.second || !it.second->isLoaded(); }); |
|
|
|
if (it != end && !it->second) { |
|
|
|
if (it != end && !it->second) { |
|
|
@ -316,7 +319,9 @@ void Replay::startStream(const Segment *cur_segment) { |
|
|
|
auto it = std::find_if(events.cbegin(), events.cend(), |
|
|
|
auto it = std::find_if(events.cbegin(), events.cend(), |
|
|
|
[](auto e) { return e->which == cereal::Event::Which::INIT_DATA; }); |
|
|
|
[](auto e) { return e->which == cereal::Event::Which::INIT_DATA; }); |
|
|
|
if (it != events.cend()) { |
|
|
|
if (it != events.cend()) { |
|
|
|
uint64_t wall_time = (*it)->event.getInitData().getWallTimeNanos(); |
|
|
|
capnp::FlatArrayMessageReader reader((*it)->data); |
|
|
|
|
|
|
|
auto event = reader.getRoot<cereal::Event>(); |
|
|
|
|
|
|
|
uint64_t wall_time = event.getInitData().getWallTimeNanos(); |
|
|
|
if (wall_time > 0) { |
|
|
|
if (wall_time > 0) { |
|
|
|
route_date_time_ = QDateTime::fromMSecsSinceEpoch(wall_time / 1e6); |
|
|
|
route_date_time_ = QDateTime::fromMSecsSinceEpoch(wall_time / 1e6); |
|
|
|
} |
|
|
|
} |
|
|
@ -325,9 +330,11 @@ void Replay::startStream(const Segment *cur_segment) { |
|
|
|
// write CarParams
|
|
|
|
// write CarParams
|
|
|
|
it = std::find_if(events.begin(), events.end(), [](auto e) { return e->which == cereal::Event::Which::CAR_PARAMS; }); |
|
|
|
it = std::find_if(events.begin(), events.end(), [](auto e) { return e->which == cereal::Event::Which::CAR_PARAMS; }); |
|
|
|
if (it != events.end()) { |
|
|
|
if (it != events.end()) { |
|
|
|
car_fingerprint_ = (*it)->event.getCarParams().getCarFingerprint(); |
|
|
|
capnp::FlatArrayMessageReader reader((*it)->data); |
|
|
|
|
|
|
|
auto event = reader.getRoot<cereal::Event>(); |
|
|
|
|
|
|
|
car_fingerprint_ = event.getCarParams().getCarFingerprint(); |
|
|
|
capnp::MallocMessageBuilder builder; |
|
|
|
capnp::MallocMessageBuilder builder; |
|
|
|
builder.setRoot((*it)->event.getCarParams()); |
|
|
|
builder.setRoot(event.getCarParams()); |
|
|
|
auto words = capnp::messageToFlatArray(builder); |
|
|
|
auto words = capnp::messageToFlatArray(builder); |
|
|
|
auto bytes = words.asBytes(); |
|
|
|
auto bytes = words.asBytes(); |
|
|
|
Params().put("CarParams", (const char *)bytes.begin(), bytes.size()); |
|
|
|
Params().put("CarParams", (const char *)bytes.begin(), bytes.size()); |
|
|
@ -361,14 +368,16 @@ void Replay::publishMessage(const Event *e) { |
|
|
|
if (event_filter && event_filter(e, filter_opaque)) return; |
|
|
|
if (event_filter && event_filter(e, filter_opaque)) return; |
|
|
|
|
|
|
|
|
|
|
|
if (sm == nullptr) { |
|
|
|
if (sm == nullptr) { |
|
|
|
auto bytes = e->bytes(); |
|
|
|
auto bytes = e->data.asBytes(); |
|
|
|
int ret = pm->send(sockets_[e->which], (capnp::byte *)bytes.begin(), bytes.size()); |
|
|
|
int ret = pm->send(sockets_[e->which], (capnp::byte *)bytes.begin(), bytes.size()); |
|
|
|
if (ret == -1) { |
|
|
|
if (ret == -1) { |
|
|
|
rWarning("stop publishing %s due to multiple publishers error", sockets_[e->which]); |
|
|
|
rWarning("stop publishing %s due to multiple publishers error", sockets_[e->which]); |
|
|
|
sockets_[e->which] = nullptr; |
|
|
|
sockets_[e->which] = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
sm->update_msgs(nanos_since_boot(), {{sockets_[e->which], e->event}}); |
|
|
|
capnp::FlatArrayMessageReader reader(e->data); |
|
|
|
|
|
|
|
auto event = reader.getRoot<cereal::Event>(); |
|
|
|
|
|
|
|
sm->update_msgs(nanos_since_boot(), {{sockets_[e->which], event}}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -382,10 +391,13 @@ void Replay::publishFrame(const Event *e) { |
|
|
|
(e->which == cereal::Event::WIDE_ROAD_ENCODE_IDX && !hasFlag(REPLAY_FLAG_ECAM))) { |
|
|
|
(e->which == cereal::Event::WIDE_ROAD_ENCODE_IDX && !hasFlag(REPLAY_FLAG_ECAM))) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
auto eidx = capnp::AnyStruct::Reader(e->event).getPointerSection()[0].getAs<cereal::EncodeIndex>(); |
|
|
|
|
|
|
|
if (eidx.getType() == cereal::EncodeIndex::Type::FULL_H_E_V_C && isSegmentMerged(eidx.getSegmentNum())) { |
|
|
|
if (isSegmentMerged(e->eidx_segnum)) { |
|
|
|
CameraType cam = cam_types.at(e->which); |
|
|
|
auto &segment = segments_.at(e->eidx_segnum); |
|
|
|
camera_server_->pushFrame(cam, segments_[eidx.getSegmentNum()]->frames[cam].get(), eidx); |
|
|
|
auto cam = cam_types.at(e->which); |
|
|
|
|
|
|
|
if (auto &frame = segment->frames[cam]; frame) { |
|
|
|
|
|
|
|
camera_server_->pushFrame(cam, frame.get(), e); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -399,7 +411,7 @@ void Replay::stream() { |
|
|
|
events_updated_ = false; |
|
|
|
events_updated_ = false; |
|
|
|
if (exit_) break; |
|
|
|
if (exit_) break; |
|
|
|
|
|
|
|
|
|
|
|
Event cur_event(cur_which, cur_mono_time_); |
|
|
|
Event cur_event{cur_which, cur_mono_time_, {}}; |
|
|
|
auto eit = std::upper_bound(events_->begin(), events_->end(), &cur_event, Event::lessThan()); |
|
|
|
auto eit = std::upper_bound(events_->begin(), events_->end(), &cur_event, Event::lessThan()); |
|
|
|
if (eit == events_->end()) { |
|
|
|
if (eit == events_->end()) { |
|
|
|
rInfo("waiting for events..."); |
|
|
|
rInfo("waiting for events..."); |
|
|
@ -430,7 +442,7 @@ void Replay::stream() { |
|
|
|
precise_nano_sleep(behind_ns); |
|
|
|
precise_nano_sleep(behind_ns); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!evt->frame) { |
|
|
|
if (evt->eidx_segnum == -1) { |
|
|
|
publishMessage(evt); |
|
|
|
publishMessage(evt); |
|
|
|
} else if (camera_server_) { |
|
|
|
} else if (camera_server_) { |
|
|
|
if (speed_ > 1.0) { |
|
|
|
if (speed_ > 1.0) { |
|
|
|