diff --git a/GPS_receiver.py b/GPS_receiver.py index 24c970eee705a8082ef9a8785a4aef1c7e09d339..a2793c7c7ac18c7a66f5854cb6d68656bcc9514f 100644 --- a/GPS_receiver.py +++ b/GPS_receiver.py @@ -36,9 +36,10 @@ class TCPReceiver(socketserver.StreamRequestHandler): #start TCP server which receives the messages from the RUTX11 def start_GPSthread(CONFIG): - global TCPServerInstance + global TCPServerInstance, GPS_Ringbuffer + GPS_ringbuf.set_min_frame_movement(CONFIG['min-movement-frame']) GPS_poort = 8500 #port to which the TCP nmea string is send - for i in range(0,5): + for _ in range(0,5): ip_address = get_ip_address() if ip_address != None: break if ip_address == None: diff --git a/camera.py b/camera.py index ca330615344ac1486d13269d5d914ad9ddee26d2..8cce0ce82474c2f5c218eb77396f85a45dc989fe 100644 --- a/camera.py +++ b/camera.py @@ -15,8 +15,8 @@ class take_img(Thread): self._running = True self.save_IMGS = CONFIG['save-IMGS'] self.save_GPS = CONFIG['save-GPS'] - self.usb = USB_class(CONFIG['save-every-x']) + self.GPS_check = CONFIG['GPS-checks'] # connecting to the first available camera self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice()) @@ -27,10 +27,12 @@ class take_img(Thread): # converting to opencv bgr format self.converter.OutputPixelFormat = pylon.PixelType_BGR8packed self.converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned + Thread.__init__(self) print("Image taker thread started") def run(self): + global GPS_lock, GPS_ringbuf, to_process_deque while self.camera.IsGrabbing() and self._running: grabResult = self.camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException) if grabResult.GrabSucceeded(): @@ -39,16 +41,21 @@ class take_img(Thread): image = self.converter.Convert(grabResult) img = image.GetArray() with GPS_lock: - data_obj = GPS_ringbuf.get_dataobject(timestamp) - - #send image to neural network - to_process_deque.append({'file_name': filename, 'img': img,'data': data_obj}) - if self.save_GPS == True: + (data_obj, is_moving) = GPS_ringbuf.get_dataobject(timestamp) + + #save GPS data + if (self.GPS_check == False) or (self.save_GPS == True) and (is_moving == True): gps_filename = timestamp.strftime("%y_%m_%d") #one file/day self.usb.write_line(GPS_ringbuf.curitem_as_string(timestamp), gps_filename) - if self.save_IMGS == True: - self.usb.save_img(img, timestamp.strftime("%y_%m_%dT%H"), filename) + #only process images when we are moving & the GPS buffer is filled + if (self.GPS_check == False) or (is_moving == True): + if (self.GPS_check == False) or ((data_obj.lat >= 0) and (data_obj.lng >= 0)): + #send image to neural network + to_process_deque.append({'file_name': filename, 'img': img,'data': data_obj}) + + if self.save_IMGS == True: + self.usb.save_img(img, timestamp.strftime("%y_%m_%dT%H"), filename) grabResult.Release() self.camera.StopGrabbing() diff --git a/cfg/classification.yaml b/cfg/classification.yaml index ff40e66605f2ffa1558b1d4d2d3ace58425b590b..910ce6030a3ee37124b1b0f8de893d9faf476bfc 100644 --- a/cfg/classification.yaml +++ b/cfg/classification.yaml @@ -17,6 +17,8 @@ Camera: False AGENSO: False save-GPS: False save-IMGS: False +save-every-x: 10 #dont save all imgs & GPS coordinates, its simply to much +min-movement-frame: 0.1 #m between frames #folders weights-folder: weights diff --git a/cfg/detection.yaml b/cfg/detection.yaml index 2fb93a7bab75f51432a77049b9de3dda1b64e0d7..e416d33191bb2f7c5599f82ee88de2a3594884e4 100644 --- a/cfg/detection.yaml +++ b/cfg/detection.yaml @@ -11,13 +11,15 @@ nms-thres: 0.3 view-img: True #general -logging: False +logging: False #logging is the only process which can cause out of memory crashes! GPS: True Camera: True AGENSO: True save-GPS: True save-IMGS: True save-every-x: 10 #dont save all imgs & GPS coordinates, its simply to much +min-movement-frame: 0.1 #m between frames +GPS-checks: False #enable/disable GPS moving checks to facilitate desk debugging #folders weights-folder: weights diff --git a/data_types.py b/data_types.py index f4aad61a937441f01f55dfaba291c6a4791a857c..3719c1c5c6ad153b20988d9d48e9f96703423bce 100644 --- a/data_types.py +++ b/data_types.py @@ -19,8 +19,8 @@ class data_class():#lat, lng, hdop, satnum, gps_quality, timestamp def __init__(self): self.timestamp = "0-0-0T0:0:0" self.gps_quality = "Not valid" #values: Not valid, Fixed, Diff fix, RTK, RTK F - self.lat = 0 - self.lng = 0 + self.lat = -1 + self.lng = -1 self.hdop = 0 self.satnum = 0 self.diseases = [] @@ -79,57 +79,64 @@ class timestep: self.gpsquality = nmea_GGA_msg.gps_qual self.gpstime = nmea_GGA_msg.timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") self.rectime = datetime.utcnow().strftime("%y-%m-%dT%H:%M:%S.%f") - + self.moving = False ##----------------------------------------------------------------------------------------------------------- #ring buffer of gps values so we can retreive them & determine if we are moving class GPS_Ringbuffer: def __init__(self, size): + self.min_movement_frame = 0 #minimal movement vetween frames + self.min_movement = 0 #minimal movement over the entire buffer. + self.decdegr_to_m = 0.00001 #very rough conversion from DD to M self.size = size self.prevlat = 0 self.prevlng = 0 self.prevtimestamp = datetime.utcnow()#.strftime("%y-%m-%dT%H:%M:%S.%f") self.data = [] - self.point = 0 #inital poisition - + self.f_pnt = 0 #inital poisition + self.l_pnt = 1 #last position (always before the firstpo in a ring) #init array fake_nmea_GGA_msg = fake_nmea_class(self.prevtimestamp) for _ in range(0, size):#i self.data.append(timestep(fake_nmea_GGA_msg, 0,0)) - - def update_pointer(self): - self.point = (self.point + 1) % self.size - + + def update_pointer(self, pointer): + return (pointer + 1) % self.size + def set_min_frame_movement(self, min_movement_frame): + self.min_movement = min_movement_frame * self.decdegr_to_m * self.size + self.min_movement_frame = min_movement_frame + #put new value in the rinngbuffer en update the values def put(self, nmea_GGA_msg, timestamp): - self.update_pointer() + self.f_pnt = self.update_pointer(self.f_pnt) + self.l_pnt = self.update_pointer(self.l_pnt) lat = nmea_GGA_msg.latitude lng = nmea_GGA_msg.longitude time_dif = (timestamp - self.prevtimestamp).total_seconds() lat_dif = (lat - self.prevlat) lng_dif = (lng - self.prevlng) - self.data[self.point].lat = lat - self.data[self.point].lng =lng - self.data[self.point].latdif = lat_dif/time_dif - self.data[self.point].lngdif = lng_dif/time_dif - self.data[self.point].hdop = nmea_GGA_msg.horizontal_dil - self.data[self.point].satnum = nmea_GGA_msg.num_sats - self.data[self.point].gpsquality = nmea_GGA_msg.gps_qual - self.data[self.point].gpstime = nmea_GGA_msg.timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") - self.data[self.point].rectime = timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") - #print('prev_lat: %f, lat: %f, diff: %f' %(self.prevlat, lat, self.data[self.point].latdif)) - #print('prev_lng: %f, lng: %f, diff: %f' %(self.prevlng, lng, self.data[self.point].lngdif)) + self.data[self.f_pnt].lat = lat + self.data[self.f_pnt].lng =lng + self.data[self.f_pnt].latdif = lat_dif/time_dif + self.data[self.f_pnt].lngdif = lng_dif/time_dif + self.data[self.f_pnt].hdop = nmea_GGA_msg.horizontal_dil + self.data[self.f_pnt].satnum = nmea_GGA_msg.num_sats + self.data[self.f_pnt].gpsquality = nmea_GGA_msg.gps_qual + self.data[self.f_pnt].gpstime = nmea_GGA_msg.timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") + self.data[self.f_pnt].rectime = timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") + self.data[self.f_pnt].moving = self.determine_hasmoved() + #print('prev_lat: %f, lat: %f, diff: %f' %(self.prevlat, lat, self.data[self.f_pnt].latdif)) + #print('prev_lng: %f, lng: %f, diff: %f' %(self.prevlng, lng, self.data[self.f_pnt].lngdif)) self.prevtimestamp = timestamp self.prevlat = lat self.prevlng = lng - #compute the current location based on the time and position difference between the last two coordinates def get_currentlocation(self, timestamp): - avg_latdiff = self.data[self.point].latdif - avg_lngdiff = self.data[self.point].lngdif + avg_latdiff = self.data[self.f_pnt].latdif + avg_lngdiff = self.data[self.f_pnt].lngdif time_dif = (timestamp - self.prevtimestamp).total_seconds() #print(avg_latdiff) @@ -143,27 +150,48 @@ class GPS_Ringbuffer: def get_dataobject(self, timestamp): data_obj = data_class() data_obj.timestamp = timestamp.strftime("%y-%m-%dT%H:%M:%S") - data_obj.set_gpsquality(self.data[self.point].gpsquality) + data_obj.set_gpsquality(self.data[self.f_pnt].gpsquality) (data_obj.lat, data_obj.lng) = self.get_currentlocation(timestamp) - data_obj.hdop = float(self.data[self.point].hdop) - data_obj.satnum = int(self.data[self.point].satnum) - return data_obj + data_obj.hdop = float(self.data[self.f_pnt].hdop) + data_obj.satnum = int(self.data[self.f_pnt].satnum) + return (data_obj, self.data[self.f_pnt].moving) #determine movement over the last samples def determine_hasmoved(self): total_latdiff = 0 total_lngdiff = 0 - avg_hdop = 0 + for pos in self.data: total_latdiff += pos.latdif - total_lngdiff += pos.lngdif - avg_hdop += pos.hdop - avg_hdop = avg_hdop / self.size - if (total_latdiff > avg_hdop) or (total_lngdiff > avg_hdop): + total_lngdiff += pos.lngdif + total_movement = total_latdiff + total_lngdiff + if (total_movement > self.min_movement): return True else: return False + #only use first & last sample, faster for big buffers + def determine_hasmoved_fast(self): + itemone = self.data[self.f_pnt] + itemtwo = self.data[self.l_pnt] + + lat_movement = abs(itemone.lat - itemtwo.lat) + lng_movement = abs(itemone.lng - itemtwo.lng) + total_movement = lat_movement + lng_movement + if (total_movement > self.min_movement): + return True + else: + return False + + + def determine_has_moved_onlynow(self): + total_movement = self.data[self.f_pnt].latdif + self.data[self.f_pnt].lngdif + if (total_movement > self.min_movement_frame): + return True + else: + return False + + #print the buffer for debugging purposes def print_all_values(self): for item in self.data: @@ -171,10 +199,10 @@ class GPS_Ringbuffer: #return last item as string def curitem_as_string(self, camera_timestamp): - item = self.data[self.point] + item = self.data[self.f_pnt] GPS_string = str(item.lat) + "," + str(item.lng) + "," + str(item.latdif) + "," + str(item.lngdif) + "," GPS_string += str(item.hdop) + "," + str(item.satnum) + "," + str(item.gpsquality) + "," - GPS_string += item.gpstime + "," + item.rectime + "," + camera_timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") +"\n" + GPS_string += item.gpstime + "," + item.rectime + "," + camera_timestamp.strftime("%y-%m-%dT%H:%M:%S.%f") + str(item.moving) +"\n" return GPS_string @@ -182,8 +210,8 @@ class GPS_Ringbuffer: #fake nmea class, used to initialise the RING buffer class fake_nmea_class: def __init__(self,prevtimestamp): - self.latitude = 0 - self.longitude = 0 + self.latitude = -1 + self.longitude = -1 self.horizontal_dil = 0 self.num_sats = 0 self.gps_qual = 0 diff --git a/inference.py b/inference.py index c47b3bc2653a172df747a376463aec0e47482897..7a950d787e7386fb2eaacd0fdb0ee1a62625dc33 100644 --- a/inference.py +++ b/inference.py @@ -402,6 +402,7 @@ class post_processing(Thread): self._running = True self.freememory = free_gbs() self.call_counter = 0 + # Initialize the thread Thread.__init__(self) print("to_send_queue to file saver started") @@ -411,6 +412,7 @@ class post_processing(Thread): while self._running: item = to_send_queue.get() #blocking operation if CONFIG['AGENSO'] == True: + #check free memory self.call_counter = self.call_counter + 1 if self.call_counter >= CHECK_EVERY: self.freememory = free_gbs() @@ -482,7 +484,8 @@ if __name__ == '__main__': image_thread.start() dl_thread.start() proc_res_thread.start() - AGENSO_thread.start() + if CONFIG['AGENSO'] == True: + AGENSO_thread.start() #wait for key stroke, then quit program @@ -491,4 +494,5 @@ if __name__ == '__main__': image_thread.terminate() dl_thread.terminate() proc_res_thread.terminate() - AGENSO_thread.terminate() \ No newline at end of file + if CONFIG['AGENSO'] == True: + AGENSO_thread.terminate() \ No newline at end of file