Skip to content

Commit d7dbbb4

Browse files
wirelessnet2Comma Devicepd0wm
authored and
Casey Francis
committed
Dev UI
Dev UI Update onroad.cc Update car.capnp Update car.capnp Co-Authored-By: Comma Device <[email protected]> Co-Authored-By: Willem Melching <[email protected]>
1 parent 982178e commit d7dbbb4

File tree

8 files changed

+268
-23
lines changed

8 files changed

+268
-23
lines changed

cereal/car.capnp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ struct CarState {
197197
# clutch (manual transmission only)
198198
clutchPressed @28 :Bool;
199199

200+
lkMode @41 :Bool;
201+
engineRPM @42 :Float32;
202+
brakeToggle @43 :Bool;
203+
200204
# which packets this state came from
201205
canMonoTimes @12: List(UInt64);
202206

selfdrive/assets/img_brake_disc.png

51.3 KB
Loading

selfdrive/car/honda/carstate.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
def get_can_signals(CP, gearbox_msg, main_on_sig_msg):
1515
signals = [
16+
("ENGINE_RPM", "POWERTRAIN_DATA"),
1617
("XMISSION_SPEED", "ENGINE_DATA"),
1718
("WHEEL_SPEED_FL", "WHEEL_SPEEDS"),
1819
("WHEEL_SPEED_FR", "WHEEL_SPEEDS"),
@@ -168,6 +169,7 @@ def __init__(self, CP):
168169
self.brake_switch_active = False
169170
self.cruise_setting = 0
170171
self.v_cruise_pcm_prev = 0
172+
self.engineRPM = 0
171173

172174
def update(self, cp, cp_cam, cp_body):
173175
ret = car.CarState.new_message()
@@ -229,6 +231,7 @@ def update(self, cp, cp_cam, cp_body):
229231
ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_stalk(
230232
250, cp.vl["SCM_FEEDBACK"]["LEFT_BLINKER"], cp.vl["SCM_FEEDBACK"]["RIGHT_BLINKER"])
231233
ret.brakeHoldActive = cp.vl["VSA_STATUS"]["BRAKE_HOLD_ACTIVE"] == 1
234+
self.engineRPM = cp.vl["POWERTRAIN_DATA"]["ENGINE_RPM"]
232235

233236
# TODO: set for all cars
234237
if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.ODYSSEY_CHN, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORDH, CAR.CIVIC_BOSCH,

selfdrive/car/honda/interface.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ def init(CP, logcan, sendcan):
380380
def _update(self, c):
381381
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
382382

383+
384+
ret.lkMode = self.CS.lkMode
385+
ret.engineRPM = self.CS.engineRPM
386+
383387
buttonEvents = []
384388

385389
if self.CS.cruise_buttons != self.CS.prev_cruise_buttons:

selfdrive/ui/qt/onroad.cc

Lines changed: 208 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cmath>
44

55
#include <QDebug>
6+
#include <QString>
67

78
#include "selfdrive/common/timing.h"
89
#include "selfdrive/ui/qt/util.h"
@@ -171,8 +172,7 @@ void OnroadAlerts::paintEvent(QPaintEvent *event) {
171172
OnroadHud::OnroadHud(QWidget *parent) : QWidget(parent) {
172173
engage_img = loadPixmap("../assets/img_chffr_wheel.png", {img_size, img_size});
173174
dm_img = loadPixmap("../assets/img_driver_face.png", {img_size, img_size});
174-
175-
connect(this, &OnroadHud::valueChanged, [=] { update(); });
175+
brake_img = loadPixmap("../assets/img_brake_disc.png", {img_size, img_size});
176176
}
177177

178178
void OnroadHud::updateState(const UIState &s) {
@@ -185,27 +185,176 @@ void OnroadHud::updateState(const UIState &s) {
185185
if (cruise_set && !s.scene.is_metric) {
186186
maxspeed *= KM_TO_MILE;
187187
}
188-
QString maxspeed_str = cruise_set ? QString::number(std::nearbyint(maxspeed)) : "N/A";
189-
float cur_speed = sm["carState"].getCarState().getVEgo() * (s.scene.is_metric ? MS_TO_KPH : MS_TO_MPH);
188+
QString maxspeed_str = cruise_set ? QString::number(std::nearbyint(maxspeed)) : "-";
189+
float cur_speed = std::max(0.0, sm["carState"].getCarState().getVEgo() * (s.scene.is_metric ? MS_TO_KPH : MS_TO_MPH));
190190

191191
setProperty("is_cruise_set", cruise_set);
192192
setProperty("speed", QString::number(std::nearbyint(cur_speed)));
193193
setProperty("maxSpeed", maxspeed_str);
194194
setProperty("speedUnit", s.scene.is_metric ? "km/h" : "mph");
195195
setProperty("hideDM", cs.getAlertSize() != cereal::ControlsState::AlertSize::NONE);
196196
setProperty("status", s.status);
197-
198-
// update engageability and DM icons at 2Hz
199-
if (sm.frame % (UI_FREQ / 2) == 0) {
200-
setProperty("engageable", cs.getEngageable() || cs.getEnabled());
201-
setProperty("dmActive", sm["driverMonitoringState"].getDriverMonitoringState().getIsActiveMode());
202-
}
197+
setProperty("engageable", cs.getEngageable() || cs.getEnabled());
198+
setProperty("dmActive", sm["driverMonitoringState"].getDriverMonitoringState().getIsActiveMode());
199+
// -1.96133 is -0.2g of braking force, which is where most one-pedal enabled cars turn on brakelight -wn2
200+
setProperty("braking", sm["carControl"].getCarControl().getActuators().getAccel() < -1.96133 || sm["carState"].getCarState().getBrakePressed() || sm["carState"].getCarState().getBrakeLightsDEPRECATED());
201+
202+
const auto leadOne = sm["radarState"].getRadarState().getLeadOne();
203+
setProperty("lead_d_rel", leadOne.getDRel());
204+
setProperty("lead_v_rel", leadOne.getVRel());
205+
setProperty("lead_status", leadOne.getStatus());
206+
setProperty("angleSteers", sm["carState"].getCarState().getSteeringAngleDeg());
207+
208+
// If your car uses INDI or LQR, adjust this accordingly. -wirelessnet2
209+
setProperty("steerAngleDesired", sm["controlsState"].getControlsState().getLateralControlState().getPidState().getSteeringAngleDesiredDeg());
210+
setProperty("engineRPM", sm["carState"].getCarState().getEngineRPM());
203211
}
204212

205213
void OnroadHud::paintEvent(QPaintEvent *event) {
206214
QPainter p(this);
207215
p.setRenderHint(QPainter::Antialiasing);
208216

217+
int NvgWindow::devUiDrawElement(QPainter &p, int x, int y, const char* value, const char* label, const char* units, QColor &color) {
218+
configFont(p, "Open Sans", 30 * 2, "SemiBold");
219+
drawColoredText(p, x + 92, y + 80, QString(value), color);
220+
221+
configFont(p, "Open Sans", 28, "Regular");
222+
drawText(p, x + 92, y + 80 + 42, QString(label), 255);
223+
224+
if (strlen(units) > 0) {
225+
p.save();
226+
p.translate(x + 54 + 30 - 3 + 92, y + 37 + 25);
227+
p.rotate(-90);
228+
drawText(p, 0, 0, QString(units), 255);
229+
p.restore();
230+
}
231+
232+
return 110;
233+
}
234+
235+
void NvgWindow::drawLeftDevUi(QPainter &p, int x, int y) {
236+
int rh = 5;
237+
int ry = y;
238+
239+
// Add Relative Distance to Primary Lead Car
240+
// Unit: Meters
241+
if (true) {
242+
char val_str[8];
243+
char units_str[8];
244+
QColor valueColor = QColor(255, 255, 255, 255);
245+
246+
if (lead_status) {
247+
// Orange if close, Red if very close
248+
if (lead_d_rel < 5) {
249+
valueColor = QColor(255, 0, 0, 255);
250+
} else if (lead_d_rel < 15) {
251+
valueColor = QColor(255, 188, 0, 255);
252+
}
253+
snprintf(val_str, sizeof(val_str), "%d", (int)lead_d_rel);
254+
} else {
255+
snprintf(val_str, sizeof(val_str), "-");
256+
}
257+
258+
snprintf(units_str, sizeof(units_str), "m");
259+
260+
rh += devUiDrawElement(p, x, ry, val_str, "REL DIST", units_str, valueColor);
261+
ry = y + rh;
262+
}
263+
264+
// Add Relative Velocity vs Primary Lead Car
265+
// Unit: kph if metric, else mph
266+
if (true) {
267+
char val_str[8];
268+
QColor valueColor = QColor(255, 255, 255, 255);
269+
270+
if (lead_status) {
271+
// Red if approaching faster than 10mph
272+
// Orange if approaching (negative)
273+
if (lead_v_rel < -4.4704) {
274+
valueColor = QColor(255, 0, 0, 255);
275+
} else if (lead_v_rel < 0) {
276+
valueColor = QColor(255, 188, 0, 255);
277+
}
278+
279+
if (speedUnit == "mph") {
280+
snprintf(val_str, sizeof(val_str), "%d", (int)(lead_v_rel * 2.236936)); //mph
281+
} else {
282+
snprintf(val_str, sizeof(val_str), "%d", (int)(lead_v_rel * 3.6)); //kph
283+
}
284+
} else {
285+
snprintf(val_str, sizeof(val_str), "-");
286+
}
287+
288+
rh += devUiDrawElement(p, x, ry, val_str, "REL SPEED", speedUnit.toStdString().c_str(), valueColor);
289+
ry = y + rh;
290+
}
291+
292+
// Add Real Steering Angle
293+
// Unit: Degrees
294+
if (true) {
295+
char val_str[8];
296+
QColor valueColor = QColor(255, 255, 255, 255);
297+
298+
// Red if large steering angle
299+
// Orange if moderate steering angle
300+
if (std::fabs(angleSteers) > 12) {
301+
valueColor = QColor(255, 0, 0, 255);
302+
} else if (std::fabs(angleSteers) > 6) {
303+
valueColor = QColor(255, 188, 0, 255);
304+
}
305+
306+
snprintf(val_str, sizeof(val_str), "%.0f%s%s", angleSteers , "°", "");
307+
308+
rh += devUiDrawElement(p, x, ry, val_str, "REAL STEER", "", valueColor);
309+
ry = y + rh;
310+
}
311+
312+
// Add Desired Steering Angle
313+
// Unit: Degrees
314+
if (false) {
315+
char val_str[8];
316+
QColor valueColor = QColor(255, 255, 255, 255);
317+
318+
if (status != STATUS_DISENGAGED) {
319+
// Red if large steering angle
320+
// Orange if moderate steering angle
321+
if (std::fabs(angleSteers) > 12) {
322+
valueColor = QColor(255, 0, 0, 255);
323+
} else if (std::fabs(angleSteers) > 6) {
324+
valueColor = QColor(255, 188, 0, 255);
325+
}
326+
327+
snprintf(val_str, sizeof(val_str), "%.0f%s%s", steerAngleDesired, "°", "");
328+
} else {
329+
snprintf(val_str, sizeof(val_str), "-");
330+
}
331+
332+
rh += devUiDrawElement(p, x, ry, val_str, "DESIR STEER", "", valueColor);
333+
ry = y + rh;
334+
}
335+
336+
// Add Engine RPM
337+
// Unit: RPM
338+
if (true) {
339+
char val_str[8];
340+
QColor valueColor = QColor(255, 255, 255, 255);
341+
342+
if(engineRPM == 0) {
343+
snprintf(val_str, sizeof(val_str), "OFF");
344+
} else {
345+
snprintf(val_str, sizeof(val_str), "%d", (engineRPM));
346+
}
347+
348+
rh += devUiDrawElement(p, x, ry, val_str, "ENG RPM", "", valueColor);
349+
ry = y + rh;
350+
}
351+
352+
rh += 25;
353+
p.setBrush(QColor(0, 0, 0, 0));
354+
QRect ldu(x, y, 184, rh);
355+
p.drawRoundedRect(ldu, 20, 20);
356+
}
357+
209358
// Header gradient
210359
QLinearGradient bg(0, header_h - (header_h / 2.5), 0, header_h);
211360
bg.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.45));
@@ -241,10 +390,21 @@ void OnroadHud::paintEvent(QPaintEvent *event) {
241390
engage_img, bg_colors[status], 1.0);
242391
}
243392

244-
// dm icon
245393
if (!hideDM) {
246-
drawIcon(p, radius / 2 + (bdr_s * 2), rect().bottom() - footer_h / 2,
394+
// left Dev UI
395+
drawLeftDevUi(p, bdr_s * 2, bdr_s * 2 + rc.height());
396+
397+
// dm icon
398+
drawIcon(p, rc.center().x(), rect().bottom() - footer_h / 2 + 50,
247399
dm_img, QColor(0, 0, 0, 70), dmActive ? 1.0 : 0.2);
400+
401+
p.setOpacity(1.0); // dmActive will determine opacity of brake_img's bg without this :/ -wirelessnet2
402+
403+
// brake icon
404+
if (false) {
405+
drawIcon(p, rc.center().x() + 250, rect().bottom() - footer_h / 2 + 50,
406+
brake_img, QColor(0, 0, 0, 70), braking ? 1.0 : 0.2);
407+
}
248408
}
249409
}
250410

@@ -258,7 +418,17 @@ void OnroadHud::drawText(QPainter &p, int x, int y, const QString &text, int alp
258418
p.drawText(real_rect.x(), real_rect.bottom(), text);
259419
}
260420

261-
void OnroadHud::drawIcon(QPainter &p, int x, int y, QPixmap &img, QBrush bg, float opacity) {
421+
void NvgWindow::drawColoredText(QPainter &p, int x, int y, const QString &text, QColor &color) {
422+
QFontMetrics fm(p.font());
423+
QRect init_rect = fm.boundingRect(text);
424+
QRect real_rect = fm.boundingRect(init_rect, 0, text);
425+
real_rect.moveCenter({x, y - real_rect.height() / 2});
426+
427+
p.setPen(color);
428+
p.drawText(real_rect.x(), real_rect.bottom(), text);
429+
}
430+
431+
void NvgWindow::drawIcon(QPainter &p, int x, int y, QPixmap &img, QBrush bg, float opacity) {
262432
p.setPen(Qt::NoPen);
263433
p.setBrush(bg);
264434
p.drawEllipse(x - radius / 2, y - radius / 2, radius, radius);
@@ -320,7 +490,27 @@ void NvgWindow::drawLaneLines(QPainter &painter, const UIState *s) {
320490

321491
// paint path
322492
QLinearGradient bg(0, height(), 0, height() / 4);
323-
if (scene.end_to_end) {
493+
// wirelessnet2's rainbow barf path
494+
if (scene.enabled) {
495+
// openpilot is not disengaged
496+
if (scene.steeringPressed) {
497+
// The user is applying torque to the steering wheel
498+
bg.setColorAt(0, QColor(0, 191, 255, 255));
499+
bg.setColorAt(1, QColor(0, 95, 128, 50));
500+
} else {
501+
// Draw colored track
502+
int torqueScale = (int)std::fabs(510 * (float)scene.pidStateOutput);
503+
int red_lvl = std::fmin(255, torqueScale);
504+
int green_lvl = std::fmin(255, 510 - torqueScale);
505+
bg.setColorAt(0, QColor(red_lvl, green_lvl, 0, 255));
506+
bg.setColorAt(1, QColor((int)(0.5 * red_lvl), (int)(0.5 * green_lvl), 0, 50));
507+
}
508+
} else if (!scene.end_to_end) {
509+
// Draw white track when disengaged and not end_to_end
510+
bg.setColorAt(0, whiteColor());
511+
bg.setColorAt(1, whiteColor(0));
512+
} else {
513+
// Draw red vision track when disengaged and end_to_end
324514
const auto &orientation = (*s->sm)["modelV2"].getModelV2().getOrientation();
325515
float orientation_future = 0;
326516
if (orientation.getZ().size() > 16) {
@@ -330,15 +520,11 @@ void NvgWindow::drawLaneLines(QPainter &painter, const UIState *s) {
330520
float curve_hue = fmax(70, 112 - (orientation_future * 420));
331521
// FIXME: painter.drawPolygon can be slow if hue is not rounded
332522
curve_hue = int(curve_hue * 100 + 0.5) / 100;
333-
334-
bg.setColorAt(0.0 / 1.5, QColor::fromHslF(148 / 360., 1.0, 0.5, 1.0));
335-
bg.setColorAt(0.55 / 1.5, QColor::fromHslF(112 / 360., 1.0, 0.68, 0.8));
336-
bg.setColorAt(0.9 / 1.5, QColor::fromHslF(curve_hue / 360., 1.0, 0.65, 0.6));
337-
bg.setColorAt(1.0, QColor::fromHslF(curve_hue / 360., 1.0, 0.65, 0.0));
338-
} else {
339-
bg.setColorAt(0, whiteColor());
340-
bg.setColorAt(1, whiteColor(0));
523+
bg.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 0.4));
524+
bg.setColorAt(0.75 / 1.5, QColor::fromHslF(curve_hue / 360., 1.0, 0.68, 0.35));
525+
bg.setColorAt(1.0, QColor::fromHslF(curve_hue / 360., 1.0, 0.68, 0.0));
341526
}
527+
342528
painter.setBrush(bg);
343529
painter.drawPolygon(scene.track_vertices.v, scene.track_vertices.cnt);
344530
}

selfdrive/ui/qt/onroad.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,46 @@ class OnroadAlerts : public QWidget {
6666
class NvgWindow : public CameraViewWidget {
6767
Q_OBJECT
6868

69+
Q_PROPERTY(bool braking MEMBER braking);
70+
Q_PROPERTY(int lead_status MEMBER lead_status);
71+
Q_PROPERTY(float lead_d_rel MEMBER lead_d_rel);
72+
Q_PROPERTY(float lead_v_rel MEMBER lead_v_rel);
73+
Q_PROPERTY(float angleSteers MEMBER angleSteers);
74+
Q_PROPERTY(float steerAngleDesired MEMBER steerAngleDesired);
75+
Q_PROPERTY(int engineRPM MEMBER engineRPM);
76+
6977
public:
7078
explicit NvgWindow(VisionStreamType type, QWidget* parent = 0);
79+
void updateState(const UIState &s);
80+
81+
private:
82+
void drawIcon(QPainter &p, int x, int y, QPixmap &img, QBrush bg, float opacity);
83+
void drawText(QPainter &p, int x, int y, const QString &text, int alpha = 255);
84+
void drawLeftDevUi(QPainter &p, int x, int y);
85+
int devUiDrawElement(QPainter &p, int x, int y, const char* value, const char* label, const char* units, QColor &color);
86+
void drawColoredText(QPainter &p, int x, int y, const QString &text, QColor &color);
87+
88+
QPixmap engage_img;
89+
QPixmap dm_img;
90+
QPixmap brake_img;
91+
const int radius = 160;
92+
const int img_size = (radius / 2) * 1.5;
93+
QString speed;
94+
QString speedUnit;
95+
QString maxSpeed;
96+
bool is_cruise_set = false;
97+
bool engageable = false;
98+
bool dmActive = false;
99+
bool hideDM = false;
100+
int status = STATUS_DISENGAGED;
101+
102+
bool braking = false;
103+
int lead_status;
104+
float lead_d_rel = 0;
105+
float lead_v_rel = 0;
106+
float angleSteers = 0;
107+
float steerAngleDesired = 0;
108+
int engineRPM = 0;
71109

72110
protected:
73111
void paintGL() override;

0 commit comments

Comments
 (0)