Merge branch 'testing' into devel-zht

This commit is contained in:
Rick Lan
2020-03-22 15:21:24 +10:00
19 changed files with 95 additions and 40 deletions
+14 -4
View File
@@ -18,11 +18,11 @@ You can test your changes on your machine by running `run_docker_tests.sh`. This
### Automated Testing
All PRs are automatically checked by travis. Check out `.travis.yml` for what travis runs. Any new tests sould be added to travis.
All PRs are automatically checked by Github Actions. Check out `.github/workflows/` for what Github Actions runs. Any new tests sould be added to Github Actions.
### Code Style and Linting
Code is automatically checked for style by travis as part of the automated tests. You can also run these tests yourself by running `pylint_openpilot.sh` and `flake8_openpilot.sh`.
Code is automatically checked for style by Github Actions as part of the automated tests. You can also run these tests yourself by running `pylint_openpilot.sh` and `flake8_openpilot.sh`.
## Car Ports (openpilot)
@@ -32,9 +32,19 @@ If you port openpilot to a substantially new car brand, see this more generic [B
## Pull Requests
Pull requests should be against the master branch. Before running master on in-car hardware, you'll need to run
Pull requests should be against the master branch. Before running master on in-car hardware, you'll need to clone the submodules too. That can be done by recursively cloning the repository:
```
git clone https://github.com/commaai/openpilot.git --recursive
```
Or alternatively, when on the master branch:
```
git submodule init
git submodule update
```
in order to pull down the submodules, such as `panda` and `opendbc`.
The reasons for having submodules on a dedicated repository and our new development philosophy can be found in our [post about externalization](https://medium.com/@comma_ai/a-2020-theme-externalization-13b33326d8b3).
Modules that are in seperate repositories include:
* apks
* cereal
* laika
* opendbc
* panda
+3
View File
@@ -85,6 +85,9 @@ unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l) {
case 0x117: // ACC_10 Automatic Cruise Control
crc ^= (uint8_t[]){0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC}[counter];
break;
case 0x120: // TSK_06 Drivetrain Coordinator
crc ^= (uint8_t[]){0xC4,0xE2,0x4F,0xE4,0xF8,0x2F,0x56,0x81,0x9F,0xE5,0x83,0x44,0x05,0x3F,0x97,0xDF}[counter];
break;
case 0x121: // Motor_20 Driver Throttle Inputs
crc ^= (uint8_t[]){0xE9,0x65,0xAE,0x6B,0x7B,0x35,0xE5,0x5F,0x4E,0xC7,0x86,0xA2,0xBB,0xDD,0xEB,0xB4}[counter];
break;
+2 -2
View File
@@ -1108,8 +1108,8 @@ BO_ 1413 Systeminfo_01: 8 Gateway_MQB
SG_ SI_BUS_15 : 30|1@1+ (1,0) [0|1] "" Vector__XXX
BO_ 288 TSK_06: 8 Motor_Diesel_MQB
SG_ TSK_06_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
SG_ TSK_06_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
SG_ TSK_Radbremsmom : 12|12@1+ (8,0) [0|32760] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
SG_ TSK_Status : 24|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
SG_ TSK_v_Begrenzung_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB
+2 -1
View File
@@ -2117,7 +2117,8 @@ void cameras_run(DualCameraState *s) {
int ret = poll(fds, ARRAYSIZE(fds), 1000);
if (ret <= 0) {
LOGE("poll failed (%d)", ret);
if (errno == EINTR || errno == EAGAIN) continue;
LOGE("poll failed (%d - %d)", ret, errno);
break;
}
+4 -3
View File
@@ -604,8 +604,8 @@ void* visionserver_client_thread(void* arg) {
}
int ret = zmq_poll(polls, num_polls, -1);
if (ret < 0) {
if (errno == EINTR) continue;
LOGE("poll failed (%d)", ret);
if (errno == EINTR || errno == EAGAIN) continue;
LOGE("poll failed (%d - %d)", ret, errno);
break;
}
if (polls[0].revents) {
@@ -796,7 +796,8 @@ void* visionserver_thread(void* arg) {
int ret = zmq_poll(polls, ARRAYSIZE(polls), -1);
if (ret < 0) {
LOGE("poll failed (%d)", ret);
if (errno == EINTR || errno == EAGAIN) continue;
LOGE("poll failed (%d - %d)", ret, errno);
break;
}
if (polls[0].revents) {
+6 -5
View File
@@ -6,11 +6,14 @@ from common.realtime import DT_CTRL
from selfdrive.car import gen_empty_fingerprint
from selfdrive.controls.lib.drive_helpers import EventTypes as ET, create_event
from selfdrive.controls.lib.vehicle_model import VehicleModel
# dp
from common.realtime import sec_since_boot
from common.params import Params
params = Params()
from selfdrive.dragonpilot.dragonconf import dp_get_last_modified
GearShifter = car.CarState.GearShifter
# generic car and radar interfaces
@@ -128,10 +131,8 @@ class CarInterfaceBase():
events.append(create_event('wrongCarMode', [ET.NO_ENTRY, ET.USER_DISABLE]))
if cs_out.espDisabled:
events.append(create_event('espDisabled', [ET.NO_ENTRY, ET.SOFT_DISABLE]))
if not self.dragon_toyota_stock_dsu:
if not self.dragon_allow_gas:
if cs_out.gasPressed:
events.append(create_event('pedalPressed', [ET.PRE_ENABLE]))
if cs_out.gasPressed and not self.dragon_toyota_stock_dsu and not self.dragon_allow_gas:
events.append(create_event('pedalPressed', [ET.PRE_ENABLE]))
# TODO: move this stuff to the capnp strut
if not self.dragon_lat_ctrl:
@@ -150,7 +151,7 @@ class CarInterfaceBase():
# DragonAllowGas
if not self.dragon_allow_gas:
if (cs_out.gasPressed and (not self.gas_pressed_prev) and cs_out.vEgo > gas_resume_speed) or \
(cs_out.brakePressed and (not self.brake_pressed_prev or not cs_out.standstill)):
(cs_out.brakePressed and (not self.brake_pressed_prev or not cs_out.standstill)):
events.append(create_event('pedalPressed', [ET.NO_ENTRY, ET.USER_DISABLE]))
else:
if cs_out.brakePressed and (not self.brake_pressed_prev or not cs_out.standstill):
+2 -1
View File
@@ -140,7 +140,7 @@ FINGERPRINTS = {
CAR.LEXUS_RX_TSS2: [
# 2020 Lexus RX 350
{
36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 740: 5, 742: 8, 743: 8, 764: 8, 765: 8, 767:4, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 824: 8, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 891: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 987: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8,1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594:8, 1595: 8, 1600: 8, 1649: 8, 1775: 8, 1777: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1816: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8, 2015: 8, 2016: 8, 2024: 8
36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 740: 5, 742: 8, 743: 8, 764: 8, 765: 8, 767:4, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 824: 8, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 891: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 987: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8,1082: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1575: 8, 1592: 8, 1594:8, 1595: 8, 1600: 8, 1649: 8, 1775: 8, 1777: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1808: 8, 1816: 8, 1872: 8, 1880: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8, 2015: 8, 2016: 8, 2024: 8
}],
CAR.CHR: [{
36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 614: 8, 643: 7, 658: 8, 705: 8, 740: 5, 767:4, 800: 8, 810: 2, 812: 8, 814: 8, 830: 7, 835: 8, 836: 8, 845: 5, 869: 7, 870: 7, 871: 2, 898: 8, 913: 8, 918: 8, 921: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 1014: 8, 1017: 8, 1020: 8, 1021: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1082: 8, 1083: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1175: 8, 1228: 8, 1235: 8, 1237: 8, 1279: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8
@@ -756,6 +756,7 @@ FW_VERSIONS = {
b'8965B42170\x00\x00\x00\x00\x00\x00',
b'8965B42171\x00\x00\x00\x00\x00\x00',
b'8965B42181\x00\x00\x00\x00\x00\x00',
b'\x028965B0R01200\x00\x00\x00\x008965B0R02200\x00\x00\x00\x00',
],
(Ecu.fwdRadar, 0x750, 0xf): [
b'\x018821F3301200\x00\x00\x00\x00',
+2 -2
View File
@@ -61,8 +61,8 @@ def dmonitoringd_thread(sm=None, pm=None):
dp_enable_driver_monitoring = False if params.get("DragonEnableDriverMonitoring", encoding='utf8') == "0" else True
try:
dp_awareness_time = int(params.get("DragonSteeringMonitorTimer", encoding='utf8'))
except TypeError:
dp_awareness_time = 0.
except (TypeError, ValueError):
dp_awareness_time = 70.
driver_status.awareness_time = 86400 if dp_awareness_time <= 0. else dp_awareness_time * 60.
else:
dp_enable_driver_monitoring = False
+4 -1
View File
@@ -78,7 +78,10 @@ class LanePlanner():
def update_d_poly(self, v_ego):
ts = sec_since_boot()
if ts - self.ts_last_check >= 5.:
self.camera_offset = int(params.get("DragonCameraOffset", encoding='utf8')) * 0.01
try:
self.camera_offset = int(params.get("DragonCameraOffset", encoding='utf8')) * 0.01
except (TypeError, ValueError):
self.camera_offset = CAMERA_OFFSET
self.ts_last_check = ts
# only offset left and right lane lines; offsetting p_poly does not make sense
self.l_poly[3] += self.camera_offset
+1
View File
@@ -34,6 +34,7 @@ class LongitudinalMpc():
self.prev_lead_status = False
self.prev_lead_x = 0.0
self.new_lead = False
self.last_cloudlog_t = 0.0
# df from Shane Smiskol
+1 -1
View File
@@ -85,7 +85,7 @@ class LongControl():
v_ego_pid = max(v_ego, MIN_CAN_SPEED) # Without this we get jumps, CAN bus reports 0 when speed < 0.3
if self.long_control_state == LongCtrlState.off or gas_pressed:
if self.long_control_state == LongCtrlState.off or gas_pressed or brake_pressed:
self.v_pid = v_ego_pid
self.pid.reset()
output_gb = 0.
+35 -8
View File
@@ -25,20 +25,24 @@ DESIRES = {
LaneChangeDirection.none: {
LaneChangeState.off: log.PathPlan.Desire.none,
LaneChangeState.preLaneChange: log.PathPlan.Desire.none,
LaneChangeState.laneChangeStarting: log.PathPlan.Desire.none,
LaneChangeState.laneChangeFinishing: log.PathPlan.Desire.none,
},
LaneChangeDirection.left: {
LaneChangeState.off: log.PathPlan.Desire.none,
LaneChangeState.preLaneChange: log.PathPlan.Desire.none,
LaneChangeState.laneChangeStarting: log.PathPlan.Desire.laneChangeLeft,
LaneChangeState.laneChangeFinishing: log.PathPlan.Desire.laneChangeLeft,
},
LaneChangeDirection.right: {
LaneChangeState.off: log.PathPlan.Desire.none,
LaneChangeState.preLaneChange: log.PathPlan.Desire.none,
LaneChangeState.laneChangeStarting: log.PathPlan.Desire.laneChangeRight,
LaneChangeState.laneChangeFinishing: log.PathPlan.Desire.laneChangeRight,
},
}
def calc_states_after_delay(states, v_ego, steer_angle, curvature_factor, steer_ratio, delay):
states[0].x = v_ego * delay
states[0].psi = v_ego * curvature_factor * math.radians(steer_angle) / steer_ratio * delay
@@ -58,6 +62,7 @@ class PathPlanner():
self.lane_change_state = LaneChangeState.off
self.lane_change_direction = LaneChangeDirection.none
self.lane_change_timer = 0.0
self.lane_change_ll_prob = 1.0
self.prev_one_blinker = False
# dragonpilot
@@ -97,19 +102,30 @@ class PathPlanner():
if self.lane_change_enabled:
self.dragon_auto_lc_enabled = True if self.params.get("DragonEnableAutoLC", encoding='utf8') == "1" else False
# adjustable assisted lc min speed
self.dragon_assisted_lc_min_mph = int(self.params.get("DragonAssistedLCMinMPH", encoding='utf8')) * CV.MPH_TO_MS
try:
self.dragon_assisted_lc_min_mph = float(self.params.get("DragonAssistedLCMinMPH", encoding='utf8'))
except (TypeError, ValueError):
self.dragon_assisted_lc_min_mph = 37
self.dragon_assisted_lc_min_mph *= CV.MPH_TO_MS
if self.dragon_assisted_lc_min_mph < 0:
self.dragon_assisted_lc_min_mph = 0
if self.dragon_auto_lc_enabled:
# adjustable auto lc min speed
self.dragon_auto_lc_min_mph = int(self.params.get("DragonAutoLCMinMPH", encoding='utf8')) * CV.MPH_TO_MS
try:
self.dragon_auto_lc_min_mph = float(self.params.get("DragonAutoLCMinMPH", encoding='utf8'))
except (TypeError, ValueError):
self.dragon_auto_lc_min_mph = 60
self.dragon_auto_lc_min_mph *= CV.MPH_TO_MS
if self.dragon_auto_lc_min_mph < 0:
self.dragon_auto_lc_min_mph = 0
# when auto lc is smaller than assisted lc, we set assisted lc to the same speed as auto lc
if self.dragon_auto_lc_min_mph < self.dragon_assisted_lc_min_mph:
self.dragon_assisted_lc_min_mph = self.dragon_auto_lc_min_mph
# adjustable auto lc delay
self.dragon_auto_lc_delay = int(self.params.get("DragonAutoLCDelay", encoding='utf8'))
try:
self.dragon_auto_lc_delay = float(self.params.get("DragonAutoLCDelay", encoding='utf8'))
except (TypeError, ValueError):
self.dragon_auto_lc_delay = 2.
if self.dragon_auto_lc_delay < 0:
self.dragon_auto_lc_delay = 0
else:
@@ -174,19 +190,30 @@ class PathPlanner():
# off
if self.lane_change_state == LaneChangeState.off and one_blinker and not self.prev_one_blinker and not below_lane_change_speed:
self.lane_change_state = LaneChangeState.preLaneChange
self.lane_change_ll_prob = 1.0
# pre
elif self.lane_change_state == LaneChangeState.preLaneChange:
if not one_blinker or below_lane_change_speed:
self.lane_change_state = LaneChangeState.off
elif torque_applied:
self.lane_change_state = LaneChangeState.laneChangeStarting
# starting
elif self.lane_change_state == LaneChangeState.laneChangeStarting:
# fade out lanelines over 1s
self.lane_change_ll_prob = max(self.lane_change_ll_prob - DT_MDL, 0.0)
# 98% certainty
if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01:
self.lane_change_state = LaneChangeState.laneChangeFinishing
# finishing
elif self.lane_change_state == LaneChangeState.laneChangeFinishing and lane_change_prob < 0.5:
if one_blinker:
elif self.lane_change_state == LaneChangeState.laneChangeFinishing:
# fade in laneline over 1s
self.lane_change_ll_prob = min(self.lane_change_ll_prob + DT_MDL, 1.0)
if one_blinker and self.lane_change_ll_prob > 0.99:
self.lane_change_state = LaneChangeState.preLaneChange
else:
elif self.lane_change_ll_prob > 0.99:
self.lane_change_state = LaneChangeState.off
# when finishing, we reset timer to none.
@@ -203,8 +230,8 @@ class PathPlanner():
# Turn off lanes during lane change
if desire == log.PathPlan.Desire.laneChangeRight or desire == log.PathPlan.Desire.laneChangeLeft:
self.LP.l_prob = 0.
self.LP.r_prob = 0.
self.LP.l_prob *= self.lane_change_ll_prob
self.LP.r_prob *= self.lane_change_ll_prob
self.libmpc.init_weights(MPC_COST_LAT.PATH / 10.0, MPC_COST_LAT.LANE, MPC_COST_LAT.HEADING, self.steer_rate_cost)
else:
self.libmpc.init_weights(MPC_COST_LAT.PATH, MPC_COST_LAT.LANE, MPC_COST_LAT.HEADING, self.steer_rate_cost)
+4 -1
View File
@@ -152,7 +152,10 @@ class Planner():
modified = dp_get_last_modified()
if self.dp_last_modified != modified:
self.dragon_slow_on_curve = False if self.params.get("DragonEnableSlowOnCurve", encoding='utf8') == "0" else True
self.dragon_accel_profile = int(self.params.get("DragonAccelProfile", encoding='utf8'))
try:
self.dragon_accel_profile = int(self.params.get("DragonAccelProfile", encoding='utf8'))
except (TypeError, ValueError):
self.dragon_accel_profile = ACCEL_NORMAL_MODE
if self.dragon_accel_profile >= 2 or self.dragon_accel_profile <= -2:
self.dragon_accel_profile = 0
self.dp_last_modified = modified
+4 -1
View File
@@ -24,7 +24,10 @@ def main():
if dp_last_modified != modified:
enabled = True if params.get("DragonEnableAutoShutdown", encoding='utf8') == '1' else False
if enabled:
secs = int(params.get("DragonAutoShutdownAt", encoding='utf8')) * 60
try:
secs = int(params.get("DragonAutoShutdownAt", encoding='utf8')) * 60
except (TypeError, ValueError):
secs = 0
dp_last_modified = modified
if last_enabled != enabled or last_secs != secs or started or usb_online:
+2 -2
View File
@@ -25,8 +25,8 @@ int main() {
assert(system_logger);
struct logger *crash_logger = android_logger_open(logger_list, LOG_ID_CRASH);
assert(crash_logger);
// struct logger *kernel_logger = android_logger_open(logger_list, LOG_ID_KERNEL);
// assert(kernel_logger);
struct logger *kernel_logger = android_logger_open(logger_list, (log_id_t)5); // LOG_ID_KERNEL
assert(kernel_logger);
Context * c = Context::create();
PubSocket * androidLog = PubSocket::create(c, "androidLog");
-2
View File
@@ -420,8 +420,6 @@ def thermald_thread():
fw_version_match_prev = fw_version_match
should_start_prev = should_start
#print(msg)
# dragonpilot
ts = sec_since_boot()
# update variable status every 10 secs
+4 -1
View File
@@ -1249,11 +1249,14 @@ static void ui_draw_blank(UIState *s) {
}
void ui_draw(UIState *s) {
ui_draw_sidebar(s);
if (s->vision_connected && s->active_app == cereal_UiLayoutState_App_home && s->status != STATUS_STOPPED) {
ui_draw_sidebar(s);
ui_draw_vision(s);
} else {
ui_draw_blank(s);
if (!s->scene.uilayout_sidebarcollapsed) {
ui_draw_sidebar(s);
}
}
{
+3 -3
View File
@@ -95,9 +95,9 @@ static void ui_draw_sidebar_battery_text(UIState *s, bool hasSidebar) {
const int battery_img_x = hasSidebar ? 150 : -(sbr_w);
const int battery_img_y = 305;
char battery_str[6];
snprintf(battery_str, sizeof(battery_str), "%d%%", s->scene.batteryPercent);
nvgFillColor(s->vg, strcmp(s->scene.batteryStatus, "Charging") == 0? COLOR_GREEN : s->scene.batteryPercent <= 50? COLOR_YELLOW : s->scene.batteryPercent <= 15? COLOR_RED : COLOR_WHITE);
char battery_str[7];
snprintf(battery_str, sizeof(battery_str), "%d%%%s", s->scene.batteryPercent, strcmp(s->scene.batteryStatus, "Charging") == 0 ? "+" : "-");
nvgFillColor(s->vg, COLOR_WHITE);
nvgFontSize(s->vg, 40);
nvgFontFace(s->vg, "sans-regular");
nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE);
+2 -2
View File
@@ -666,9 +666,9 @@ static void ui_update(UIState *s) {
int ret = zmq_poll(polls, 1, 1000);
#endif
if (ret < 0) {
if (errno == EINTR) continue;
if (errno == EINTR || errno == EAGAIN) continue;
LOGW("poll failed (%d)", ret);
LOGE("poll failed (%d - %d)", ret, errno);
close(s->ipc_fd);
s->ipc_fd = -1;
s->vision_connected = false;