Skip to content

Commit d2948f2

Browse files
authored
replay: Add next engagement / disengagement jump capabilities (commaai#23248)
* seek engament/disengament in qlogs * cleanup * cleanup * little more * add output * remove qinfo * fix typo * do nothing if tm less than current mono time * const * short variable name * lgtm
1 parent 9cb0ebe commit d2948f2

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

selfdrive/ui/replay/main.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ void keyboardThread(Replay *replay_) {
5555
qDebug() << "invalid argument";
5656
}
5757
getch(); // remove \n from entering seek
58+
} else if (c == 'e') {
59+
replay_->seekToFlag(FindFlag::nextEngagement);
60+
} else if (c == 'd') {
61+
replay_->seekToFlag(FindFlag::nextDisEngagement);
5862
} else if (c == 'm') {
5963
replay_->seekTo(+60, true);
6064
} else if (c == 'M') {

selfdrive/ui/replay/replay.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ Replay::Replay(QString route, QStringList allow, QStringList block, SubMaster *s
3131
events_ = std::make_unique<std::vector<Event *>>();
3232
new_events_ = std::make_unique<std::vector<Event *>>();
3333

34+
qRegisterMetaType<FindFlag>("FindFlag");
3435
connect(this, &Replay::seekTo, this, &Replay::doSeek);
36+
connect(this, &Replay::seekToFlag, this, &Replay::doSeekToFlag);
3537
connect(this, &Replay::segmentChanged, this, &Replay::queueSegment);
3638
}
3739

@@ -109,6 +111,55 @@ void Replay::doSeek(int seconds, bool relative) {
109111
queueSegment();
110112
}
111113

114+
void Replay::doSeekToFlag(FindFlag flag) {
115+
if (flag == FindFlag::nextEngagement) {
116+
qInfo() << "seeking to the next engagement...";
117+
} else if (flag == FindFlag::nextDisEngagement) {
118+
qInfo() << "seeking to the disengagement...";
119+
}
120+
121+
updateEvents([&]() {
122+
if (auto next = find(flag)) {
123+
uint64_t tm = *next - 2 * 1e9; // seek to 2 seconds before next
124+
if (tm <= cur_mono_time_) {
125+
return true;
126+
}
127+
128+
cur_mono_time_ = tm;
129+
current_segment_ = currentSeconds() / 60;
130+
return isSegmentMerged(current_segment_);
131+
} else {
132+
qWarning() << "seeking failed";
133+
return true;
134+
}
135+
});
136+
137+
queueSegment();
138+
}
139+
140+
std::optional<uint64_t> Replay::find(FindFlag flag) {
141+
// Search in all segments
142+
for (const auto &[n, _] : segments_) {
143+
if (n < current_segment_) continue;
144+
145+
LogReader log;
146+
bool cache_to_local = true; // cache qlog to local for fast seek
147+
if (!log.load(route_->at(n).qlog.toStdString(), nullptr, cache_to_local, 0, 3)) continue;
148+
149+
for (const Event *e : log.events) {
150+
if (e->mono_time > cur_mono_time_ && e->which == cereal::Event::Which::CONTROLS_STATE) {
151+
const auto cs = e->event.getControlsState();
152+
if (flag == FindFlag::nextEngagement && cs.getEnabled()) {
153+
return e->mono_time;
154+
} else if (flag == FindFlag::nextDisEngagement && !cs.getEnabled()) {
155+
return e->mono_time;
156+
}
157+
}
158+
}
159+
}
160+
return std::nullopt;
161+
}
162+
112163
void Replay::pause(bool pause) {
113164
updateEvents([=]() {
114165
qInfo() << (pause ? "paused..." : "resuming");

selfdrive/ui/replay/replay.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ enum REPLAY_FLAGS {
2121
REPLAY_FLAG_NO_VIPC = 0x0400,
2222
};
2323

24+
enum class FindFlag {
25+
nextEngagement,
26+
nextDisEngagement
27+
};
28+
2429
class Replay : public QObject {
2530
Q_OBJECT
2631

@@ -39,14 +44,17 @@ class Replay : public QObject {
3944
signals:
4045
void segmentChanged();
4146
void seekTo(int seconds, bool relative);
47+
void seekToFlag(FindFlag flag);
4248

4349
protected slots:
4450
void queueSegment();
4551
void doSeek(int seconds, bool relative);
52+
void doSeekToFlag(FindFlag flag);
4653
void segmentLoadFinished(bool sucess);
4754

4855
protected:
4956
typedef std::map<int, std::unique_ptr<Segment>> SegmentMap;
57+
std::optional<uint64_t> find(FindFlag flag);
5058
void startStream(const Segment *cur_segment);
5159
void stream();
5260
void setCurrentSegment(int n);

0 commit comments

Comments
 (0)