Merge remote-tracking branch 'upstream/master' into toyota-lta

pull/27494/head
Shane Smiskol 3 years ago
commit b14fc9fa0f
  1. 2
      .github/workflows/selfdrive_tests.yaml
  2. 5
      Jenkinsfile
  3. 13
      selfdrive/car/__init__.py
  4. 15
      selfdrive/car/nissan/carcontroller.py
  5. 7
      selfdrive/car/nissan/values.py
  6. 14
      selfdrive/car/tesla/carcontroller.py
  7. 7
      selfdrive/car/tesla/values.py
  8. 2
      selfdrive/controls/controlsd.py
  9. 16
      selfdrive/navd/map_renderer.cc
  10. 1
      selfdrive/navd/map_renderer.h
  11. 40
      selfdrive/test/process_replay/compare_logs.py
  12. 70
      selfdrive/test/process_replay/model_replay.py
  13. 2
      selfdrive/test/process_replay/model_replay_ref_commit
  14. 2
      selfdrive/ui/qt/widgets/cameraview.cc
  15. 2
      selfdrive/ui/soundd/sound.cc
  16. 2
      tools/cabana/binaryview.cc
  17. 2
      tools/cabana/cabana
  18. 12
      tools/cabana/cabana.cc
  19. 4
      tools/cabana/canmessages.cc
  20. 3
      tools/cabana/canmessages.h
  21. 2
      tools/cabana/dbcmanager.cc
  22. 2
      tools/cabana/videowidget.cc

@ -294,7 +294,7 @@ jobs:
- name: Run model replay with ONNX
timeout-minutes: 2
run: |
${{ env.RUN_CL }} "ONNXCPU=1 CI=1 coverage run selfdrive/test/process_replay/model_replay.py && \
${{ env.RUN_CL }} "ONNXCPU=1 CI=1 NO_NAV=1 coverage run selfdrive/test/process_replay/model_replay.py && \
coverage xml"
- name: Run unit tests
timeout-minutes: 5

5
Jenkinsfile vendored

@ -11,6 +11,7 @@ export SOURCE_DIR=${env.SOURCE_DIR}
export GIT_BRANCH=${env.GIT_BRANCH}
export GIT_COMMIT=${env.GIT_COMMIT}
export AZURE_TOKEN='${env.AZURE_TOKEN}'
export MAPBOX_TOKEN='${env.MAPBOX_TOKEN}'
source ~/.bash_profile
if [ -f /TICI ]; then
@ -47,9 +48,11 @@ pipeline {
TEST_DIR = "/data/openpilot"
SOURCE_DIR = "/data/openpilot_source/"
AZURE_TOKEN = credentials('azure_token')
MAPBOX_TOKEN = credentials('mapbox_token')
}
options {
timeout(time: 4, unit: 'HOURS')
timeout(time: 3, unit: 'HOURS')
disableConcurrentBuilds(abortPrevious: env.BRANCH_NAME != 'master')
}
stages {

@ -1,8 +1,9 @@
# functions common among cars
import capnp
from collections import namedtuple
from cereal import car
from common.numpy_fast import clip
from common.numpy_fast import clip, interp
from typing import Dict
# kg of standard extra cargo to count for drive, gas, etc...
@ -10,6 +11,7 @@ STD_CARGO_KG = 136.
ButtonType = car.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
AngleRateLimit = namedtuple('AngleRateLimit', ['speed_bp', 'angle_v'])
def apply_hysteresis(val: float, val_steady: float, hyst_gap: float) -> float:
@ -111,6 +113,15 @@ def apply_toyota_steer_torque_limits(apply_torque, apply_torque_last, motor_torq
return int(round(float(apply_torque)))
def apply_std_steer_angle_limits(apply_angle, apply_angle_last, v_ego, LIMITS):
# pick angle rate limits based on wind up/down
steer_up = apply_angle_last * apply_angle > 0. and abs(apply_angle) > abs(apply_angle_last)
rate_limits = LIMITS.ANGLE_RATE_LIMIT_UP if steer_up else LIMITS.ANGLE_RATE_LIMIT_DOWN
angle_rate_lim = interp(v_ego, rate_limits.speed_bp, rate_limits.angle_v)
return clip(apply_angle, apply_angle_last - angle_rate_lim, apply_angle_last + angle_rate_lim)
def crc8_pedal(data):
crc = 0xFF # standard init value
poly = 0xD5 # standard crc8: x8+x7+x6+x4+x2+1

@ -1,6 +1,6 @@
from cereal import car
from common.numpy_fast import clip, interp
from opendbc.can.packer import CANPacker
from selfdrive.car import apply_std_steer_angle_limits
from selfdrive.car.nissan import nissancan
from selfdrive.car.nissan.values import CAR, CarControllerParams
@ -14,7 +14,7 @@ class CarController:
self.frame = 0
self.lkas_max_torque = 0
self.last_angle = 0
self.apply_angle_last = 0
self.packer = CANPacker(dbc_name)
@ -28,18 +28,11 @@ class CarController:
### STEER ###
lkas_hud_msg = CS.lkas_hud_msg
lkas_hud_info_msg = CS.lkas_hud_info_msg
apply_angle = actuators.steeringAngleDeg
steer_hud_alert = 1 if hud_control.visualAlert in (VisualAlert.steerRequired, VisualAlert.ldw) else 0
if CC.latActive:
# windup slower
if self.last_angle * apply_angle > 0. and abs(apply_angle) > abs(self.last_angle):
angle_rate_lim = interp(CS.out.vEgo, CarControllerParams.ANGLE_DELTA_BP, CarControllerParams.ANGLE_DELTA_V)
else:
angle_rate_lim = interp(CS.out.vEgo, CarControllerParams.ANGLE_DELTA_BP, CarControllerParams.ANGLE_DELTA_VU)
apply_angle = clip(apply_angle, self.last_angle - angle_rate_lim, self.last_angle + angle_rate_lim)
apply_angle = apply_std_steer_angle_limits(actuators.steeringAngleDeg, self.apply_angle_last, CS.out.vEgo, CarControllerParams)
# Max torque from driver before EPS will give up and not apply torque
if not bool(CS.out.steeringPressed):
@ -57,7 +50,7 @@ class CarController:
apply_angle = CS.out.steeringAngleDeg
self.lkas_max_torque = 0
self.last_angle = apply_angle
self.apply_angle_last = apply_angle
if self.CP.carFingerprint in (CAR.ROGUE, CAR.XTRAIL, CAR.ALTIMA) and pcm_cancel_cmd:
can_sends.append(nissancan.create_acc_cancel_cmd(self.packer, self.car_fingerprint, CS.cruise_throttle_msg))

@ -4,7 +4,7 @@ from enum import Enum
from cereal import car
from panda.python import uds
from selfdrive.car import dbc_dict
from selfdrive.car import AngleRateLimit, dbc_dict
from selfdrive.car.docs_definitions import CarInfo, Harness
from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
@ -12,9 +12,8 @@ Ecu = car.CarParams.Ecu
class CarControllerParams:
ANGLE_DELTA_BP = [0., 5., 15.]
ANGLE_DELTA_V = [5., .8, .15] # windup limit
ANGLE_DELTA_VU = [5., 3.5, 0.4] # unwind limit
ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[0., 5., 15.], angle_v=[5., .8, .15])
ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[0., 5., 15.], angle_v=[5., 3.5, 0.4])
LKAS_MAX_TORQUE = 1 # A value of 1 is easy to overpower
STEER_THRESHOLD = 1.0

@ -1,5 +1,6 @@
from common.numpy_fast import clip, interp
from common.numpy_fast import clip
from opendbc.can.packer import CANPacker
from selfdrive.car import apply_std_steer_angle_limits
from selfdrive.car.tesla.teslacan import TeslaCAN
from selfdrive.car.tesla.values import DBC, CANBUS, CarControllerParams
@ -8,7 +9,7 @@ class CarController:
def __init__(self, dbc_name, CP, VM):
self.CP = CP
self.frame = 0
self.last_angle = 0
self.apply_angle_last = 0
self.packer = CANPacker(dbc_name)
self.pt_packer = CANPacker(DBC[CP.carFingerprint]['pt'])
self.tesla_can = TeslaCAN(self.packer, self.pt_packer)
@ -24,20 +25,15 @@ class CarController:
lkas_enabled = CC.latActive and not hands_on_fault
if lkas_enabled:
apply_angle = actuators.steeringAngleDeg
# Angular rate limit based on speed
steer_up = self.last_angle * apply_angle > 0. and abs(apply_angle) > abs(self.last_angle)
rate_limit = CarControllerParams.RATE_LIMIT_UP if steer_up else CarControllerParams.RATE_LIMIT_DOWN
max_angle_diff = interp(CS.out.vEgo, rate_limit.speed_points, rate_limit.max_angle_diff_points)
apply_angle = clip(apply_angle, self.last_angle - max_angle_diff, self.last_angle + max_angle_diff)
apply_angle = apply_std_steer_angle_limits(actuators.steeringAngleDeg, self.apply_angle_last, CS.out.vEgo, CarControllerParams)
# To not fault the EPS
apply_angle = clip(apply_angle, CS.out.steeringAngleDeg - 20, CS.out.steeringAngleDeg + 20)
else:
apply_angle = CS.out.steeringAngleDeg
self.last_angle = apply_angle
self.apply_angle_last = apply_angle
can_sends.append(self.tesla_can.create_steering_control(apply_angle, lkas_enabled, self.frame))
# Longitudinal control (in sync with stock message, about 40Hz)

@ -2,14 +2,13 @@ from collections import namedtuple
from typing import Dict, List, Union
from cereal import car
from selfdrive.car import dbc_dict
from selfdrive.car import AngleRateLimit, dbc_dict
from selfdrive.car.docs_definitions import CarInfo
from selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
Ecu = car.CarParams.Ecu
Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
AngleRateLimit = namedtuple('AngleRateLimit', ['speed_points', 'max_angle_diff_points'])
class CAR:
@ -104,8 +103,8 @@ BUTTONS = [
]
class CarControllerParams:
RATE_LIMIT_UP = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., .8, .15])
RATE_LIMIT_DOWN = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., 3.5, 0.4])
ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[0., 5., 15.], angle_v=[5., .8, .15])
ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[0., 5., 15.], angle_v=[5., 3.5, 0.4])
JERK_LIMIT_MAX = 8
JERK_LIMIT_MIN = -8
ACCEL_TO_SPEED_MULTIPLIER = 3

@ -627,7 +627,7 @@ class Controls:
max_torque = abs(self.last_actuators.steer) > 0.99
if undershooting and turning and good_speed and max_torque:
self.events.add(EventName.steerSaturated)
elif lac_log.active and not CS.steeringPressed and lac_log.saturated:
elif lac_log.active and lac_log.saturated:
dpath_points = lat_plan.dPathPoints
if len(dpath_points):
# Check if we deviated from the path

@ -4,10 +4,10 @@
#include <string>
#include <QApplication>
#include <QBuffer>
#include <QDebug>
#include "common/util.h"
#include "common/timing.h"
#include "common/swaglog.h"
#include "selfdrive/ui/qt/maps/map_helpers.h"
const float DEFAULT_ZOOM = 13.5; // Don't go below 13 or features will start to disappear
@ -56,22 +56,27 @@ MapRenderer::MapRenderer(const QMapboxGLSettings &settings, bool online) : m_set
m_map->setFramebufferObject(fbo->handle(), fbo->size());
gl_functions->glViewport(0, 0, WIDTH, HEIGHT);
QObject::connect(m_map.data(), &QMapboxGL::mapLoadingFailed, [=](QMapboxGL::MapLoadingFailure err_code, const QString &reason) {
LOGE("Map loading failed with %d: '%s'\n", err_code, reason.toStdString().c_str());
});
if (online) {
vipc_server.reset(new VisionIpcServer("navd"));
vipc_server->create_buffers(VisionStreamType::VISION_STREAM_MAP, NUM_VIPC_BUFFERS, false, WIDTH, HEIGHT);
vipc_server->start_listener();
pm.reset(new PubMaster({"navThumbnail"}));
sm.reset(new SubMaster({"liveLocationKalman", "navRoute"}));
sm.reset(new SubMaster({"liveLocationKalman", "navRoute"}, {"liveLocationKalman"}));
timer = new QTimer(this);
timer->setSingleShot(true);
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(msgUpdate()));
timer->start(50);
timer->start(0);
}
}
void MapRenderer::msgUpdate() {
sm->update(0);
sm->update(1000);
if (sm->updated("liveLocationKalman")) {
auto location = (*sm)["liveLocationKalman"].getLiveLocationKalman();
@ -92,6 +97,9 @@ void MapRenderer::msgUpdate() {
}
updateRoute(route);
}
// schedule next update
timer->start(0);
}
void MapRenderer::updatePosition(QMapbox::Coordinate position, float bearing) {

@ -25,7 +25,6 @@ public:
bool loaded();
~MapRenderer();
private:
std::unique_ptr<QOpenGLContext> ctx;
std::unique_ptr<QOffscreenSurface> surface;

@ -2,6 +2,7 @@
import bz2
import sys
import math
import capnp
import numbers
import dictdiffer
from collections import Counter
@ -30,20 +31,23 @@ def remove_ignored_fields(msg, ignore):
continue
for k in keys[:-1]:
try:
attr = getattr(msg, k)
except AttributeError:
break
else:
v = getattr(attr, keys[-1])
if isinstance(v, bool):
val = False
elif isinstance(v, numbers.Number):
val = 0
# indexing into list
if k.isdigit():
attr = attr[int(k)]
else:
raise NotImplementedError('Error ignoring field')
setattr(attr, keys[-1], val)
return msg.as_reader()
attr = getattr(attr, k)
v = getattr(attr, keys[-1])
if isinstance(v, bool):
val = False
elif isinstance(v, numbers.Number):
val = 0
elif isinstance(v, (list, capnp.lib.capnp._DynamicListBuilder)):
val = []
else:
raise NotImplementedError(f"Unknown type: {type(v)}")
setattr(attr, keys[-1], val)
return msg
def get_field_tolerance(diff_field, field_tolerances):
@ -79,12 +83,12 @@ def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None, tolerance=Non
print(msg1, msg2)
raise Exception("msgs not aligned between logs")
msg1_bytes = remove_ignored_fields(msg1, ignore_fields).as_builder().to_bytes()
msg2_bytes = remove_ignored_fields(msg2, ignore_fields).as_builder().to_bytes()
msg1 = remove_ignored_fields(msg1, ignore_fields)
msg2 = remove_ignored_fields(msg2, ignore_fields)
if msg1_bytes != msg2_bytes:
msg1_dict = msg1.to_dict(verbose=True)
msg2_dict = msg2.to_dict(verbose=True)
if msg1.to_bytes() != msg2.to_bytes():
msg1_dict = msg1.as_reader().to_dict(verbose=True)
msg2_dict = msg2.as_reader().to_dict(verbose=True)
dd = dictdiffer.diff(msg1_dict, msg2_dict, ignore=ignore_fields)

@ -20,14 +20,17 @@ from system.version import get_commit
from tools.lib.framereader import FrameReader
from tools.lib.logreader import LogReader
TEST_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36"
SEGMENT = 0
TEST_ROUTE = "2f4452b03ccb98f0|2022-12-03--13-45-30"
SEGMENT = 6
MAX_FRAMES = 100 if PC else 600
NAV_FRAMES = 20
NO_NAV = "NO_NAV" in os.environ # TODO: make map renderer work in CI
SEND_EXTRA_INPUTS = bool(os.getenv("SEND_EXTRA_INPUTS", "0"))
VIPC_STREAM = {"roadCameraState": VisionStreamType.VISION_STREAM_ROAD, "driverCameraState": VisionStreamType.VISION_STREAM_DRIVER,
"wideRoadCameraState": VisionStreamType.VISION_STREAM_WIDE_ROAD}
def get_log_fn(ref_commit, test_route):
return f"{test_route}_model_tici_{ref_commit}.bz2"
@ -39,6 +42,47 @@ def replace_calib(msg, calib):
return msg
def nav_model_replay(lr):
pm = messaging.PubMaster(['liveLocationKalman', 'navRoute'])
sock = messaging.sub_sock('navModel', conflate=False, timeout=1000)
log_msgs = []
try:
managed_processes['mapsd'].start()
managed_processes['navmodeld'].start()
# setup position and route
nav = [m for m in lr if m.which() == 'navRoute']
llk = [m for m in lr if m.which() == 'liveLocationKalman']
assert len(nav) > 0 and len(llk) > 0
for _ in range(30):
for s in (llk, nav):
msg = s[0]
pm.send(msg.which(), msg.as_builder().to_bytes())
if messaging.recv_one(sock) is not None:
break
else:
raise Exception("no navmodeld outputs")
time.sleep(2)
messaging.drain_sock_raw(sock)
# run replay
for _ in range(NAV_FRAMES):
# 2Hz decimation
for _ in range(10):
pm.send(llk[0].which(), llk[0].as_builder().to_bytes())
time.sleep(0.1)
with Timeout(5, "timed out waiting for nav model outputs"):
log_msgs.append(messaging.recv_one_retry(sock))
finally:
managed_processes['mapsd'].stop()
managed_processes['navmodeld'].stop()
return log_msgs
def model_replay(lr, frs):
if not PC:
spinner = Spinner()
@ -154,8 +198,10 @@ if __name__ == "__main__":
'wideRoadCameraState': FrameReader(get_url(TEST_ROUTE, SEGMENT, log_type="ecamera"), readahead=True)
}
# run replay
# run replays
log_msgs = model_replay(lr, frs)
if not NO_NAV:
log_msgs += nav_model_replay(lr)
# get diff
failed = False
@ -164,15 +210,29 @@ if __name__ == "__main__":
ref_commit = f.read().strip()
log_fn = get_log_fn(ref_commit, TEST_ROUTE)
try:
cmp_log = list(LogReader(BASE_URL + log_fn))[:2*MAX_FRAMES]
expected_msgs = 2*MAX_FRAMES
if not NO_NAV:
expected_msgs += NAV_FRAMES
cmp_log = list(LogReader(BASE_URL + log_fn))[:expected_msgs]
ignore = [
'logMonoTime',
'modelV2.frameDropPerc',
'modelV2.modelExecutionTime',
'driverStateV2.modelExecutionTime',
'driverStateV2.dspExecutionTime'
'driverStateV2.dspExecutionTime',
'navModel.dspExecutionTime',
'navModel.modelExecutionTime',
]
if PC:
ignore += [
'modelV2.laneLines.0.t',
'modelV2.laneLines.1.t',
'modelV2.laneLines.2.t',
'modelV2.laneLines.3.t',
'modelV2.roadEdges.0.t',
'modelV2.roadEdges.1.t',
]
# TODO this tolerance is absurdly large
tolerance = 2.0 if PC else None
results: Any = {TEST_ROUTE: {}}

@ -1 +1 @@
30efb4238327d723e17a3bda7e7c19c18f8a3b18
4b2c6516cd460ee443b9006f01233168edf3d170

@ -359,7 +359,7 @@ void CameraWidget::vipcThread() {
if (!vipc_client || cur_stream != requested_stream_type) {
clearFrames();
qDebug() << "connecting to stream " << requested_stream_type << ", was connected to " << cur_stream;
cur_stream = requested_stream_type;;
cur_stream = requested_stream_type;
vipc_client.reset(new VisionIpcClient(stream_name, cur_stream, false));
}
active_stream_type = cur_stream;

@ -48,7 +48,7 @@ void Sound::update() {
// scale volume using ambient noise level
if (sm.updated("microphone")) {
float volume = util::map_val(sm["microphone"].getMicrophone().getFilteredSoundPressureWeightedDb(), 30.f, 52.f, 0.f, 1.f);
float volume = util::map_val(sm["microphone"].getMicrophone().getFilteredSoundPressureWeightedDb(), 30.f, 54.f, 0.f, 1.f);
volume = QAudio::convertVolume(volume, QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale);
Hardware::set_volume(volume);
}

@ -202,7 +202,7 @@ void BinaryViewModel::updateState() {
}
}
for (int i = 0; i < row_count; ++i) {
for (int i = 0; i < row_count * column_count; ++i) {
if (i >= prev_items.size() || prev_items[i].val != items[i].val) {
auto idx = index(i / column_count, i % column_count);
emit dataChanged(idx, idx);

@ -1,4 +1,4 @@
#!/bin/sh
cd "$(dirname "$0")"
export LD_LIBRARY_PATH="../../opendbc/can:$LD_LIBRARY_PATH"
exec ./_cabana "$1"
exec ./_cabana "$@"

@ -15,6 +15,7 @@ int main(int argc, char *argv[]) {
cmd_parser.addPositionalArgument("route", "the drive to replay. find your drives at connect.comma.ai");
cmd_parser.addOption({"demo", "use a demo route instead of providing your own"});
cmd_parser.addOption({"qcam", "load qcamera"});
cmd_parser.addOption({"ecam", "load wide road camera"});
cmd_parser.addOption({"data_dir", "local directory with routes", "data_dir"});
cmd_parser.process(app);
const QStringList args = cmd_parser.positionalArguments();
@ -29,10 +30,17 @@ int main(int argc, char *argv[]) {
dir.mkdir(msgq_path);
setenv("OPENPILOT_PREFIX", qPrintable(uuid), 1);
int ret = 0;
const QString route = args.empty() ? DEMO_ROUTE : args.first();
uint32_t replay_flags = REPLAY_FLAG_NONE;
if (cmd_parser.isSet("ecam")) {
replay_flags |= REPLAY_FLAG_ECAM;
} else if (cmd_parser.isSet("qcam")) {
replay_flags |= REPLAY_FLAG_QCAMERA;
}
CANMessages p(&app);
if (p.loadRoute(route, cmd_parser.value("data_dir"), cmd_parser.isSet("qcam"))) {
int ret = 0;
if (p.loadRoute(route, cmd_parser.value("data_dir"), replay_flags)) {
MainWindow w;
w.showMaximized();
ret = app.exec();

@ -21,8 +21,8 @@ static bool event_filter(const Event *e, void *opaque) {
return c->eventFilter(e);
}
bool CANMessages::loadRoute(const QString &route, const QString &data_dir, bool use_qcam) {
replay = new Replay(route, {"can", "roadEncodeIdx", "carParams"}, {}, nullptr, use_qcam ? REPLAY_FLAG_QCAMERA : 0, data_dir, this);
bool CANMessages::loadRoute(const QString &route, const QString &data_dir, uint32_t replay_flags) {
replay = new Replay(route, {"can", "roadEncodeIdx", "wideRoadEncodeIdx", "carParams"}, {}, nullptr, replay_flags, data_dir, this);
replay->setSegmentCacheLimit(settings.cached_segment_limit);
replay->installEventFilter(event_filter, this);
QObject::connect(replay, &Replay::segmentsMerged, this, &CANMessages::eventsMerged);

@ -26,13 +26,14 @@ public:
enum FindFlags{ EQ, LT, GT };
CANMessages(QObject *parent);
~CANMessages();
bool loadRoute(const QString &route, const QString &data_dir, bool use_qcam);
bool loadRoute(const QString &route, const QString &data_dir, uint32_t replay_flags = REPLAY_FLAG_NONE);
void seekTo(double ts);
QList<QPointF> findSignalValues(const QString&id, const Signal* signal, double value, FindFlags flag, int max_count);
bool eventFilter(const Event *event);
inline QString routeName() const { return replay->route()->name(); }
inline QString carFingerprint() const { return replay->carFingerprint().c_str(); }
inline VisionStreamType visionStreamType() const { return replay->hasFlag(REPLAY_FLAG_ECAM) ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD; }
inline double totalSeconds() const { return replay->totalSeconds(); }
inline double routeStartTime() const { return replay->routeStartTime() / (double)1e9; }
inline double currentSec() const { return replay->currentSeconds(); }

@ -111,7 +111,7 @@ DBCManager *dbc() {
std::vector<const Signal*> DBCMsg::getSignals() const {
std::vector<const Signal*> ret;
for (auto &[name, sig] : sigs) ret.push_back(&sig);
for (auto &[_, sig] : sigs) ret.push_back(&sig);
std::sort(ret.begin(), ret.end(), [](auto l, auto r) { return l->start_bit < r->start_bit; });
return ret;
}

@ -21,7 +21,7 @@ VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0);
cam_widget = new CameraWidget("camerad", VISION_STREAM_ROAD, false, this);
cam_widget = new CameraWidget("camerad", can->visionStreamType(), false, this);
cam_widget->setFixedSize(parent->width(), parent->width() / 1.596);
main_layout->addWidget(cam_widget);

Loading…
Cancel
Save