diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 1cd48e6360df7c..21ca224d2c514a 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -57,6 +57,8 @@ bool loopback_can = false; cereal::HealthData::HwType hw_type = cereal::HealthData::HwType::UNKNOWN; bool is_pigeon = false; const uint32_t NO_IGNITION_CNT_MAX = 2 * 60 * 60 * 24 * 1; // turn off charge after 1 days +const uint32_t VBATT_START_CHARGING = 12000; +const uint32_t VBATT_PAUSE_CHARGING = 10500; uint32_t no_ignition_cnt = 0; bool connected_once = false; bool ignition_last = false; @@ -353,11 +355,20 @@ void can_health(PubSocket *publisher) { } #ifndef __x86_64__ - if ((no_ignition_cnt > NO_IGNITION_CNT_MAX) && (health.usb_power_mode == (uint8_t)(cereal::HealthData::UsbPowerMode::CDP))){ - printf("TURN OFF CHARGING!\n"); - pthread_mutex_lock(&usb_lock); - libusb_control_transfer(dev_handle, 0xc0, 0xe6, (uint16_t)(cereal::HealthData::UsbPowerMode::CLIENT), 0, NULL, 0, TIMEOUT); - pthread_mutex_unlock(&usb_lock); + bool cdp_mode = health.usb_power_mode == (uint8_t)(cereal::HealthData::UsbPowerMode::CDP); + bool no_ignition_exp = no_ignition_cnt > NO_IGNITION_CNT_MAX; + if ((no_ignition_exp || (health.voltage < VBATT_PAUSE_CHARGING)) && cdp_mode && !ignition) { + printf("TURN OFF CHARGING!\n"); + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0xc0, 0xe6, (uint16_t)(cereal::HealthData::UsbPowerMode::CLIENT), 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); + } + if (!no_ignition_exp && (health.voltage > VBATT_START_CHARGING) && !cdp_mode) { + + printf("TURN ON CHARGING!\n"); + pthread_mutex_lock(&usb_lock); + libusb_control_transfer(dev_handle, 0xc0, 0xe6, (uint16_t)(cereal::HealthData::UsbPowerMode::CDP), 0, NULL, 0, TIMEOUT); + pthread_mutex_unlock(&usb_lock); } #endif diff --git a/selfdrive/thermald.py b/selfdrive/thermald.py index 7c42004d3267e4..4fa856c8161f9a 100755 --- a/selfdrive/thermald.py +++ b/selfdrive/thermald.py @@ -327,13 +327,6 @@ def thermald_thread(): elif usb_power and not usb_power_prev: params.delete("Offroad_ChargeDisabled") - if msg.thermal.batteryVoltage < 11500: - alert_connectivity_prompt = copy.copy(OFFROAD_ALERTS["Offroad_VoltageLow"]) - alert_connectivity_prompt["text"] += str(msg.thermal.batteryVoltage) + " Volts." - params.delete("Offroad_VoltageLow") - params.put("Offroad_VoltageLow", json.dumps(alert_connectivity_prompt)) - else: - params.delete("Offroad_VoltageLow") thermal_status_prev = thermal_status usb_power_prev = usb_power @@ -343,6 +336,13 @@ def thermald_thread(): # report to server once per minute if (count % int(60. / DT_TRML)) == 0: + if msg.thermal.batteryVoltage < 11500: + alert_connectivity_prompt = copy.copy(OFFROAD_ALERTS["Offroad_VoltageLow"]) + alert_connectivity_prompt["text"] += str(msg.thermal.batteryVoltage) + " Volts." + params.delete("Offroad_VoltageLow") + params.put("Offroad_VoltageLow", json.dumps(alert_connectivity_prompt)) + else: + params.delete("Offroad_VoltageLow") cloudlog.event("STATUS_PACKET", count=count, health=(health.to_dict() if health else None), diff --git a/selfdrive/traffic.py b/selfdrive/traffic.py new file mode 100644 index 00000000000000..7a22c540a9225d --- /dev/null +++ b/selfdrive/traffic.py @@ -0,0 +1,120 @@ +import os +import cv2 +import numpy as np +import zmq + +def detect(source): + + font = cv2.FONT_HERSHEY_SIMPLEX + img = cv2.imread(source) + + cimg = img + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + + + lower_red1 = np.array([0,100,100]) + upper_red1 = np.array([10,255,255]) + lower_red2 = np.array([160,100,100]) + upper_red2 = np.array([180,255,255]) + lower_green = np.array([40,50,50]) + upper_green = np.array([90,255,255]) + lower_yellow = np.array([15,150,150]) + upper_yellow = np.array([35,255,255]) + mask1 = cv2.inRange(hsv, lower_red1, upper_red1) + mask2 = cv2.inRange(hsv, lower_red2, upper_red2) + maskg = cv2.inRange(hsv, lower_green, upper_green) + masky = cv2.inRange(hsv, lower_yellow, upper_yellow) + maskr = cv2.add(mask1, mask2) + + size = img.shape + + r_circles = cv2.HoughCircles(maskr, cv2.HOUGH_GRADIENT, 1, 80, + param1=50, param2=10, minRadius=0, maxRadius=30) + + g_circles = cv2.HoughCircles(maskg, cv2.HOUGH_GRADIENT, 1, 60, + param1=50, param2=10, minRadius=0, maxRadius=30) + + y_circles = cv2.HoughCircles(masky, cv2.HOUGH_GRADIENT, 1, 30, + param1=50, param2=5, minRadius=0, maxRadius=30) + + # traffic light detect + r = 5 + bound = 4.0 / 10 + if r_circles is not None: + r_circles = np.uint16(np.around(r_circles)) + + for i in r_circles[0, :]: + if i[0] > size[1] or i[1] > size[0]or i[1] > size[0]*bound: + continue + + h, s = 0.0, 0.0 + for m in range(-r, r): + for n in range(-r, r): + + if (i[1]+m) >= size[0] or (i[0]+n) >= size[1]: + continue + h += maskr[i[1]+m, i[0]+n] + s += 1 + if h / s > 50: + cv2.circle(cimg, (i[0], i[1]), i[2]+10, (0, 255, 0), 2) + cv2.circle(maskr, (i[0], i[1]), i[2]+30, (255, 255, 255), 2) + #cv2.putText(cimg,'RED',(i[0], i[1]), font, 1,(255,0,0),2,cv2.LINE_AA) + print("RED") + if g_circles is not None: + g_circles = np.uint16(np.around(g_circles)) + + for i in g_circles[0, :]: + if i[0] > size[1] or i[1] > size[0] or i[1] > size[0]*bound: + continue + + h, s = 0.0, 0.0 + for m in range(-r, r): + for n in range(-r, r): + + if (i[1]+m) >= size[0] or (i[0]+n) >= size[1]: + continue + h += maskg[i[1]+m, i[0]+n] + s += 1 + if h / s > 100: + cv2.circle(cimg, (i[0], i[1]), i[2]+10, (0, 255, 0), 2) + cv2.circle(maskg, (i[0], i[1]), i[2]+30, (255, 255, 255), 2) + #cv2.putText(cimg,'GREEN',(i[0], i[1]), font, 1,(255,0,0),2,cv2.LINE_AA) + print("GREEN") + if y_circles is not None: + y_circles = np.uint16(np.around(y_circles)) + + for i in y_circles[0, :]: + if i[0] > size[1] or i[1] > size[0] or i[1] > size[0]*bound: + continue + + h, s = 0.0, 0.0 + for m in range(-r, r): + for n in range(-r, r): + + if (i[1]+m) >= size[0] or (i[0]+n) >= size[1]: + continue + h += masky[i[1]+m, i[0]+n] + s += 1 + if h / s > 50: + cv2.circle(cimg, (i[0], i[1]), i[2]+10, (0, 255, 0), 2) + cv2.circle(masky, (i[0], i[1]), i[2]+30, (255, 255, 255), 2) + #cv2.putText(cimg,'YELLOW',(i[0], i[1]), font, 1,(255,0,0),2,cv2.LINE_AA) + print("YELLOW") + + + return cimg +if __name__ == '__main__': + + + while True: + context = zmq.Context() + socket = context.socket(zmq.REP) + socket.bind("tcp://*:9000") + message = socket.recv() + print("Message is of type {}".format(type(message))) + print(message) + detectimg =detect(message) + sleep(0.05) + # This function either gives out "RED" "YELLOW" or "GREEN" + +