Record feedback with LKAS button (#35888)

* record feedback with LKAS button

* fix alert test

* slightly simplify feedbackd

* "Audio Feedback Saved" upon time expiration or early stop

* earlySend --> earlyStop

* userFlag --> userBookmark

* RecordAudioFeedback param/toggle

* add audioFeedback test

* simplify feedbackd

* send bookmark regardless of toggle, show feedback event with higher priority

* add userBookmark to selfdrived sm

* fix mispelled param name

* default off and move to main

* segmentNum --> blockNum, earlyStop --> lastBlock

* preserve audioFeedback

* get rid of lastBlock and just send bookmark saved at the end

* update raylib side

* update toggle description and add raylib toggle

---------

Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com>
This commit is contained in:
Jimmy
2025-08-05 13:41:41 -07:00
committed by GitHub
parent 112d615ac9
commit d7b0a5fa7e
24 changed files with 217 additions and 44 deletions
+5 -5
View File
@@ -194,7 +194,7 @@ int handle_encoder_msg(LoggerdState *s, Message *msg, std::string &name, struct
return bytes_count;
}
void handle_user_flag(LoggerdState *s) {
void handle_preserve_segment(LoggerdState *s) {
static int prev_segment = -1;
if (s->logger.segment() == prev_segment) return;
@@ -222,7 +222,7 @@ void loggerd_thread() {
typedef struct ServiceState {
std::string name;
int counter, freq;
bool encoder, user_flag, record_audio;
bool encoder, preserve_segment, record_audio;
} ServiceState;
std::unordered_map<SubSocket*, ServiceState> service_state;
std::unordered_map<SubSocket*, struct RemoteEncoder> remote_encoders;
@@ -246,7 +246,7 @@ void loggerd_thread() {
.counter = 0,
.freq = it.decimation,
.encoder = encoder,
.user_flag = it.name == "userFlag",
.preserve_segment = (it.name == "userBookmark") || (it.name == "audioFeedback"),
.record_audio = record_audio,
};
}
@@ -281,8 +281,8 @@ void loggerd_thread() {
if (do_exit) break;
ServiceState &service = service_state[sock];
if (service.user_flag) {
handle_user_flag(&s);
if (service.preserve_segment) {
handle_preserve_segment(&s);
}
// drain socket
+4 -4
View File
@@ -282,15 +282,15 @@ class TestLoggerd:
sent.clear_write_flag()
assert sent.to_bytes() == m.as_builder().to_bytes()
def test_preserving_flagged_segments(self):
services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) | {"userFlag"}
def test_preserving_bookmarked_segments(self):
services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) | {"userBookmark"}
self._publish_random_messages(services)
segment_dir = self._get_latest_log_dir()
assert getxattr(segment_dir, PRESERVE_ATTR_NAME) == PRESERVE_ATTR_VALUE
def test_not_preserving_unflagged_segments(self):
services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) - {"userFlag"}
def test_not_preserving_nonbookmarked_segments(self):
services = set(random.sample(CEREAL_SERVICES, random.randint(5, 10))) - {"userBookmark", "audioFeedback"}
self._publish_random_messages(services)
segment_dir = self._get_latest_log_dir()
+1
View File
@@ -106,6 +106,7 @@ procs = [
PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC),
PythonProcess("uploader", "system.loggerd.uploader", always_run),
PythonProcess("statsd", "system.statsd", always_run),
PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad),
# debug procs
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar),