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