Merge branch 'upstream/openpilot/master' into sync-20260417

# Conflicts:
#	docs/CARS.md
#	opendbc_repo
#	panda
#	system/updated/updated.py
#	tinygrad_repo
This commit is contained in:
Jason Wen
2026-04-17 02:08:25 -04:00
54 changed files with 1498 additions and 796 deletions
+5 -2
View File
@@ -276,7 +276,10 @@ struct RouteIdentifier {
std::string display_slice() const {
const int begin = slice_explicit ? slice_begin : available_begin;
const int end = slice_explicit ? slice_end : available_end;
if (end < 0 || end == begin) {
if (end < 0) {
return std::to_string(begin) + ":";
}
if (end == begin) {
return std::to_string(begin);
}
return std::to_string(begin) + ":" + std::to_string(end);
@@ -378,7 +381,7 @@ public:
StreamAccumulator &operator=(const StreamAccumulator &) = delete;
void setDbcName(const std::string &dbc_name);
void appendEvent(cereal::Event::Which which, kj::ArrayPtr<const capnp::word> data);
void appendEvent(kj::ArrayPtr<const capnp::word> data);
void appendCanFrames(CanServiceKind service, const std::vector<LiveCanFrame> &frames);
StreamExtractBatch takeBatch();
const std::string &carFingerprint() const;
+1 -3
View File
@@ -598,9 +598,7 @@ struct StreamPoller::Impl {
}
kj::ArrayPtr<const capnp::word> data(reinterpret_cast<const capnp::word *>(msg->getData()),
size / sizeof(capnp::word));
capnp::FlatArrayMessageReader event_reader(data);
const cereal::Event::Reader event = event_reader.getRoot<cereal::Event>();
accumulator->appendEvent(event.which(), data);
accumulator->appendEvent(data);
received_messages.fetch_add(1);
}
}
+1 -1
View File
@@ -355,7 +355,7 @@ bool apply_route_slice_change(AppSession *session, UiState *state, std::string_v
int begin = 0;
int end = 0;
if (!parse_slice_spec(slice_text, &begin, &end)) {
state->error_text = "Slice must be N or N:M.";
state->error_text = "Slice must be N, N:, or N:M.";
state->open_error_popup = true;
return false;
}
+80 -61
View File
@@ -3,6 +3,7 @@
#include "tools/jotpluggler/common.h"
#include <capnp/dynamic.h>
#include <kj/exception.h>
#include <chrono>
#include <cmath>
@@ -205,6 +206,18 @@ struct LoadStats {
mutable std::mutex progress_mutex;
};
// Skip individual messages that our local Cap'n Proto schema can't project,
// such as logs recorded by a newer build.
template <typename Fn>
void with_parseable_event(kj::ArrayPtr<const capnp::word> data, Fn &&fn) {
try {
capnp::FlatArrayMessageReader event_reader(data);
fn(event_reader.getRoot<cereal::Event>());
} catch (const kj::Exception &) {
return;
}
}
std::string curve_label(std::string_view series_name) {
return std::string(series_name.empty() ? std::string_view{"plot"} : series_name);
}
@@ -666,11 +679,11 @@ std::vector<TimelineEntry> extract_segment_timeline(const std::vector<Event> &ev
if (event_record.which != cereal::Event::Which::SELFDRIVE_STATE) {
continue;
}
capnp::FlatArrayMessageReader event_reader(event_record.data);
const cereal::Event::Reader event = event_reader.getRoot<cereal::Event>();
const auto sd = event.getSelfdriveState();
const double mono_time = static_cast<double>(event.getLogMonoTime()) / 1.0e9;
append_timeline_entry(&timeline, mono_time, alert_status_to_timeline_type(sd.getAlertStatus(), sd.getEnabled()));
with_parseable_event(event_record.data, [&](const cereal::Event::Reader &event) {
const auto sd = event.getSelfdriveState();
const double mono_time = static_cast<double>(event.getLogMonoTime()) / 1.0e9;
append_timeline_entry(&timeline, mono_time, alert_status_to_timeline_type(sd.getAlertStatus(), sd.getEnabled()));
});
}
return timeline;
@@ -682,9 +695,9 @@ std::vector<LogEntry> extract_segment_logs(const std::vector<Event> &events) {
std::string last_alert_key;
for (const Event &event_record : events) {
capnp::FlatArrayMessageReader event_reader(event_record.data);
const cereal::Event::Reader event = event_reader.getRoot<cereal::Event>();
append_log_event(event_record.which, event, 0.0, &logs, &last_alert_key);
with_parseable_event(event_record.data, [&](const cereal::Event::Reader &event) {
append_log_event(event_record.which, event, 0.0, &logs, &last_alert_key);
});
}
return logs;
@@ -694,9 +707,9 @@ RouteMetadata extract_segment_metadata(const std::vector<Event> &events) {
RouteMetadata metadata;
for (const Event &event_record : events) {
if (event_record.which != cereal::Event::Which::CAR_PARAMS) continue;
capnp::FlatArrayMessageReader event_reader(event_record.data);
const cereal::Event::Reader event = event_reader.getRoot<cereal::Event>();
metadata.car_fingerprint = event.getCarParams().getCarFingerprint().cStr();
with_parseable_event(event_record.data, [&](const cereal::Event::Reader &event) {
metadata.car_fingerprint = event.getCarParams().getCarFingerprint().cStr();
});
if (!metadata.car_fingerprint.empty()) break;
}
return metadata;
@@ -1263,24 +1276,20 @@ void append_fast_node(const ResolvedNode &node,
}
}
void append_event_fast(cereal::Event::Which which,
int32_t eidx_segnum,
kj::ArrayPtr<const capnp::word> data,
const SchemaIndex &schema,
const dbc::Database *can_dbc,
bool skip_raw_can,
double time_offset,
SeriesAccumulator *series) {
if (eidx_segnum != -1) {
return;
}
void append_event_fast_reader(cereal::Event::Which which,
const cereal::Event::Reader &event,
const SchemaIndex &schema,
const dbc::Database *can_dbc,
bool skip_raw_can,
double time_offset,
SeriesAccumulator *series) {
const uint16_t which_index = static_cast<uint16_t>(which);
if (which_index >= schema.by_which.size() || !schema.by_which[which_index].has_value()) {
return;
}
const ResolvedService &service = *schema.by_which[which_index];
capnp::FlatArrayMessageReader event_reader(data);
const cereal::Event::Reader event = event_reader.getRoot<cereal::Event>();
const capnp::DynamicStruct::Reader dynamic_event(event);
const capnp::DynamicValue::Reader payload = dynamic_event.get(service.union_field);
const double tm = static_cast<double>(event.getLogMonoTime()) / 1.0e9 - time_offset;
append_fixed_scalar_point(&series->fixed_series[static_cast<size_t>(service.valid_slot)],
tm,
@@ -1329,8 +1338,23 @@ void append_event_fast(cereal::Event::Which which,
}
}
const capnp::DynamicStruct::Reader dynamic_event(event);
append_fast_node(service.payload, dynamic_event.get(service.union_field), tm, series);
append_fast_node(service.payload, payload, tm, series);
}
void append_event_fast(cereal::Event::Which which,
int32_t eidx_segnum,
kj::ArrayPtr<const capnp::word> data,
const SchemaIndex &schema,
const dbc::Database *can_dbc,
bool skip_raw_can,
double time_offset,
SeriesAccumulator *series) {
if (eidx_segnum != -1) {
return;
}
with_parseable_event(data, [&](const cereal::Event::Reader &event) {
append_event_fast_reader(which, event, schema, can_dbc, skip_raw_can, time_offset, series);
});
}
void append_events_fast_range(const std::vector<Event> &events,
@@ -1987,10 +2011,7 @@ struct StreamAccumulator::Impl {
return;
}
detected_dbc_name = next_dbc;
can_dbc.reset();
if (!detected_dbc_name.empty()) {
can_dbc.emplace(resolve_dbc_path(detected_dbc_name));
}
can_dbc = load_dbc_by_name(detected_dbc_name);
}
};
@@ -2008,35 +2029,35 @@ void StreamAccumulator::setDbcName(const std::string &dbc_name) {
impl_->refresh_dbc();
}
void StreamAccumulator::appendEvent(cereal::Event::Which which, kj::ArrayPtr<const capnp::word> data) {
capnp::FlatArrayMessageReader event_reader(data);
const cereal::Event::Reader event = event_reader.getRoot<cereal::Event>();
const double boot_time = static_cast<double>(event.getLogMonoTime()) / 1.0e9;
if (!impl_->time_offset.has_value()) {
impl_->time_offset = boot_time;
}
if (which == cereal::Event::Which::CAR_PARAMS) {
const std::string fingerprint = event.getCarParams().getCarFingerprint().cStr();
if (!fingerprint.empty() && fingerprint != impl_->car_fingerprint) {
impl_->car_fingerprint = fingerprint;
impl_->refresh_dbc();
void StreamAccumulator::appendEvent(kj::ArrayPtr<const capnp::word> data) {
with_parseable_event(data, [&](const cereal::Event::Reader &event) {
const cereal::Event::Which which = event.which();
const double boot_time = static_cast<double>(event.getLogMonoTime()) / 1.0e9;
if (!impl_->time_offset.has_value()) {
impl_->time_offset = boot_time;
}
if (which == cereal::Event::Which::CAR_PARAMS) {
const std::string fingerprint = event.getCarParams().getCarFingerprint().cStr();
if (!fingerprint.empty() && fingerprint != impl_->car_fingerprint) {
impl_->car_fingerprint = fingerprint;
impl_->refresh_dbc();
}
}
}
append_event_fast(which,
-1,
data,
impl_->schema,
impl_->can_dbc ? &*impl_->can_dbc : nullptr,
true,
*impl_->time_offset,
&impl_->series);
append_log_event(which, event, *impl_->time_offset, &impl_->logs, &impl_->last_alert_key);
if (which == cereal::Event::Which::SELFDRIVE_STATE) {
const auto sd = event.getSelfdriveState();
append_timeline_entry(&impl_->timeline, boot_time - *impl_->time_offset,
alert_status_to_timeline_type(sd.getAlertStatus(), sd.getEnabled()));
}
append_event_fast_reader(which,
event,
impl_->schema,
impl_->can_dbc ? &*impl_->can_dbc : nullptr,
impl_->can_dbc.has_value(),
*impl_->time_offset,
&impl_->series);
append_log_event(which, event, *impl_->time_offset, &impl_->logs, &impl_->last_alert_key);
if (which == cereal::Event::Which::SELFDRIVE_STATE) {
const auto sd = event.getSelfdriveState();
append_timeline_entry(&impl_->timeline, boot_time - *impl_->time_offset,
alert_status_to_timeline_type(sd.getAlertStatus(), sd.getEnabled()));
}
});
}
void StreamAccumulator::appendCanFrames(CanServiceKind service, const std::vector<LiveCanFrame> &frames) {
@@ -2126,13 +2147,11 @@ RouteData load_route_data(const std::string &route_name,
const RouteMetadata metadata = detect_route_metadata(segments, route.selector);
const std::string resolved_dbc = !dbc_name.empty() ? dbc_name : detect_dbc_for_fingerprint(metadata.car_fingerprint);
const std::optional<dbc::Database> can_dbc = resolved_dbc.empty()
? std::nullopt
: std::optional<dbc::Database>(std::in_place, resolve_dbc_path(resolved_dbc));
const std::optional<dbc::Database> can_dbc = load_dbc_by_name(resolved_dbc);
const SchemaIndex &schema = SchemaIndex::instance();
LoadedRouteArtifacts artifacts = load_route_series_parallel(segments, schema, can_dbc ? &*can_dbc : nullptr,
route.selector, !resolved_dbc.empty(), &stats);
route.selector, can_dbc.has_value(), &stats);
RouteData route_data = build_route_data(std::move(artifacts.series),
std::move(artifacts.can_messages),
std::move(artifacts.logs),
-16
View File
@@ -26,15 +26,6 @@ function op_install() {
echo -e " ↳ [${GREEN}${NC}] op installed successfully. Open a new shell to use it."
}
function loge() {
if [[ -f "$LOG_FILE" ]]; then
# error type
echo "$1" >> $LOG_FILE
# error log
echo "$2" >> $LOG_FILE
fi
}
function retry() {
local attempts=$1
shift
@@ -148,13 +139,11 @@ function op_check_os() {
;;
* )
echo -e " ↳ [${RED}${NC}] Incompatible Ubuntu version $VERSION_CODENAME detected!"
loge "ERROR_INCOMPATIBLE_UBUNTU" "$VERSION_CODENAME"
return 1
;;
esac
else
echo -e " ↳ [${RED}${NC}] No /etc/os-release on your system. Make sure you're running on Ubuntu, or similar!"
loge "ERROR_UNKNOWN_UBUNTU"
return 1
fi
@@ -162,7 +151,6 @@ function op_check_os() {
echo -e " ↳ [${GREEN}${NC}] macOS detected."
else
echo -e " ↳ [${RED}${NC}] OS type $OSTYPE not supported!"
loge "ERROR_UNKNOWN_OS" "$OSTYPE"
return 1
fi
}
@@ -210,7 +198,6 @@ function op_setup() {
SETUP_SCRIPT="tools/setup_dependencies.sh"
if ! $OPENPILOT_ROOT/$SETUP_SCRIPT; then
echo -e "[${RED}${NC}] Dependencies installation failed!"
loge "ERROR_DEPENDENCIES_INSTALLATION"
return 1
fi
et="$(date +%s)"
@@ -222,7 +209,6 @@ function op_setup() {
st="$(date +%s)"
if ! retry 3 git submodule update --jobs 4 --init --recursive; then
echo -e "[${RED}${NC}] Getting git submodules failed!"
loge "ERROR_GIT_SUBMODULES"
return 1
fi
et="$(date +%s)"
@@ -232,7 +218,6 @@ function op_setup() {
st="$(date +%s)"
if ! retry 3 git lfs pull; then
echo -e "[${RED}${NC}] Pulling git lfs files failed!"
loge "ERROR_GIT_LFS"
return 1
fi
et="$(date +%s)"
@@ -468,7 +453,6 @@ function _op() {
-d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;;
--dry ) shift 1; DRY="1" ;;
-n | --no-verify ) shift 1; NO_VERIFY="1" ;;
-l | --log ) shift 1; LOG_FILE="$1" ; shift 1 ;;
esac
# parse Commands
+1 -45
View File
@@ -33,39 +33,6 @@ cat << 'EOF'
EOF
}
function sentry_send_event() {
SENTRY_KEY=dd0cba62ba0ac07ff9f388f8f1e6a7f4
SENTRY_URL=https://sentry.io/api/4507726145781760/store/
EVENT=$1
EVENT_TYPE=${2:-$EVENT}
EVENT_LOG=${3:-"NA"}
PLATFORM=$(uname -s)
ARCH=$(uname -m)
SYSTEM=$(uname -a)
if [[ $PLATFORM == "Darwin" ]]; then
OS="macos"
elif [[ $PLATFORM == "Linux" ]]; then
OS="linux"
fi
if [[ $ARCH == armv8* ]] || [[ $ARCH == arm64* ]] || [[ $ARCH == aarch64* ]]; then
ARCH="aarch64"
elif [[ $ARCH == "x86_64" ]] || [[ $ARCH == i686* ]]; then
ARCH="x86"
fi
PYTHON_VERSION=$(echo $(python3 --version 2> /dev/null || echo "NA"))
BRANCH=$(echo $(git -C $OPENPILOT_ROOT rev-parse --abbrev-ref HEAD 2> /dev/null || echo "NA"))
COMMIT=$(echo $(git -C $OPENPILOT_ROOT rev-parse HEAD 2> /dev/null || echo "NA"))
curl -s -o /dev/null -X POST -g --data "{ \"exception\": { \"values\": [{ \"type\": \"$EVENT\" }] }, \"tags\" : { \"event_type\" : \"$EVENT_TYPE\", \"event_log\" : \"$EVENT_LOG\", \"os\" : \"$OS\", \"arch\" : \"$ARCH\", \"python_version\" : \"$PYTHON_VERSION\" , \"git_branch\" : \"$BRANCH\", \"git_commit\" : \"$COMMIT\", \"system\" : \"$SYSTEM\" } }" \
-H 'Content-Type: application/json' \
-H "X-Sentry-Auth: Sentry sentry_version=7, sentry_key=$SENTRY_KEY, sentry_client=op_setup/0.1" \
$SENTRY_URL 2> /dev/null
}
function check_stdin() {
if [ -t 0 ]; then
INTERACTIVE=1
@@ -131,7 +98,6 @@ function check_git() {
echo "Checking for git..."
if ! command -v "git" > /dev/null 2>&1; then
echo -e " ↳ [${RED}${NC}] git not found on your system, can't continue!"
sentry_send_event "SETUP_FAILURE" "ERROR_GIT_NOT_FOUND"
return 1
else
echo -e " ↳ [${GREEN}${NC}] git found.\n"
@@ -150,7 +116,6 @@ function git_clone() {
fi
echo -e " ↳ [${RED}${NC}] failed to clone openpilot!"
sentry_send_event "SETUP_FAILURE" "ERROR_GIT_CLONE"
return 1
}
@@ -159,18 +124,9 @@ function install_with_op() {
$OPENPILOT_ROOT/tools/op.sh install
$OPENPILOT_ROOT/tools/op.sh post-commit
LOG_FILE=$(mktemp)
if ! $OPENPILOT_ROOT/tools/op.sh --log $LOG_FILE setup; then
if ! $OPENPILOT_ROOT/tools/op.sh setup; then
echo -e "\n[${RED}${NC}] failed to install openpilot!"
ERROR_TYPE="$(cat "$LOG_FILE" | sed '1p;d')"
ERROR_LOG="$(cat "$LOG_FILE" | sed '2p;d')"
sentry_send_event "SETUP_FAILURE" "$ERROR_TYPE" "$ERROR_LOG" || true
return 1
else
sentry_send_event "SETUP_SUCCESS" || true
fi
echo -e "\n----------------------------------------------------------------------"