def _is_tracking_restarted(last_place, start_loc, timeseries): return eaisr.is_tracking_restarted_in_range(last_place.enter_ts, start_loc.ts, timeseries)
def has_trip_ended(self, prev_point, curr_point, timeseries, last10PointsDistances, last5MinsDistances, last5MinTimes): # Another mismatch between phone and server. Phone stops tracking too soon, # so the distance is still greater than the threshold at the end of the trip. # But then the next point is a long time away, so we can split again (similar to a distance filter) if prev_point is None: logging.debug("prev_point is None, continuing trip") else: timeDelta = curr_point.ts - prev_point.ts distDelta = pf.calDistance(prev_point, curr_point) if timeDelta > 0: speedDelta = old_div(distDelta, timeDelta) else: speedDelta = np.nan speedThreshold = old_div(float(self.distance_threshold), self.time_threshold) if eaisr.is_tracking_restarted_in_range(prev_point.ts, curr_point.ts, timeseries): logging.debug("tracking was restarted, ending trip") return True ongoing_motion_check = len( eaisr.get_ongoing_motion_in_range(prev_point.ts, curr_point.ts, timeseries)) > 0 if timeDelta > 2 * self.time_threshold and not ongoing_motion_check: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" % (prev_point.ts, curr_point.ts, self.time_threshold, curr_point.ts - prev_point.ts, ongoing_motion_check)) return True # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html # Longest flight is 17 hours, which is the longest you can go without cell reception # And even if you split an air flight that long into two, you will get some untracked time in the # middle, so that's good. TWELVE_HOURS = 12 * 60 * 60 if timeDelta > TWELVE_HOURS: logging.debug( "prev_point.ts = %s, curr_point.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" % (prev_point.ts, curr_point.ts, TWELVE_HOURS, curr_point.ts - prev_point.ts)) return True if (timeDelta > 2 * self.time_threshold and # We have been here for a while speedDelta < speedThreshold): # we haven't moved very much logging.debug( "prev_point.ts = %s, curr_point.ts = %s, threshold = %s, large gap = %s, ending trip" % (prev_point.ts, curr_point.ts, self.time_threshold, curr_point.ts - prev_point.ts)) return True else: logging.debug( "prev_point.ts = %s, curr_point.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" % (prev_point.ts, curr_point.ts, timeDelta, self.time_threshold, distDelta, self.distance_threshold, speedDelta, speedThreshold)) # The -30 is a fuzz factor intended to compensate for older clients # where data collection stopped after 5 mins, so that we never actually # see 5 mins of data if (len(last10PointsDistances) < self.point_threshold - 1 or len(last5MinsDistances) == 0 or last5MinTimes.max() < self.time_threshold - 30): logging.debug("Too few points to make a decision, continuing") return False # Normal end-of-trip case logging.debug( "last5MinsDistances.max() = %s, last10PointsDistance.max() = %s" % (last5MinsDistances.max(), last10PointsDistances.max())) if (last5MinsDistances.max() < self.distance_threshold and last10PointsDistances.max() < self.distance_threshold): return True
def has_trip_ended(self, lastPoint, currPoint, timeseries): # So we must not have been moving for the last _time filter_ # points. So the trip must have ended # Since this is a distance filter, we detect that the last # trip has ended at the time that the new trip starts. So # if the last_trip_end_point is lastPoint, then # curr_trip_start_point should be currPoint. But then we will # have problems with the spurious, noisy points that are # generated until the geofence is turned on, if ever # So we will continue to defer new trip starting until we # have worked through all of those. timeDelta = currPoint.ts - lastPoint.ts distDelta = pf.calDistance(lastPoint, currPoint) logging.debug( "lastPoint = %s, time difference = %s dist difference %s" % (lastPoint, timeDelta, distDelta)) if timeDelta > self.time_threshold: # We have been at this location for more than the time filter. # This could be because we have not been moving for the last # _time filter_ points, or because we didn't get points for # that duration, (e.g. because we were underground) if timeDelta > 0: speedDelta = old_div(distDelta, timeDelta) else: speedDelta = np.nan # this is way too slow. On ios, we use 5meters in 10 minutes. # On android, we use 10 meters in 5 mins, which seems to work better # for this kind of test speedThreshold = old_div(float(self.distance_threshold * 2), (old_div(self.time_threshold, 2))) if eaisr.is_tracking_restarted_in_range(lastPoint.ts, currPoint.ts, timeseries): logging.debug("tracking was restarted, ending trip") return True # In general, we get multiple locations between each motion activity. If we see a bunch of motion activities # between two location points, and there is a large gap between the last location and the first # motion activity as well, let us just assume that there was a restart ongoing_motion_in_range = eaisr.get_ongoing_motion_in_range( lastPoint.ts, currPoint.ts, timeseries) ongoing_motion_check = len(ongoing_motion_in_range) > 0 if timeDelta > self.time_threshold and not ongoing_motion_check: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" % (lastPoint.ts, currPoint.ts, self.time_threshold, currPoint.ts - lastPoint.ts, ongoing_motion_check)) return True # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html # Longest flight is 17 hours, which is the longest you can go without cell reception # And even if you split an air flight that long into two, you will get some untracked time in the # middle, so that's good. TWELVE_HOURS = 12 * 60 * 60 if timeDelta > TWELVE_HOURS: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" % (lastPoint.ts, currPoint.ts, TWELVE_HOURS, currPoint.ts - lastPoint.ts)) return True if (timeDelta > self.time_threshold and # We have been here for a while speedDelta < speedThreshold): # we haven't moved very much # This can happen even during ongoing trips due to spurious points # generated on some iOS phones # https://github.com/e-mission/e-mission-server/issues/577#issuecomment-376379460 if eaistc.is_huge_invalid_ts_offset(self, lastPoint, currPoint, timeseries, ongoing_motion_in_range): # invalidate from memory and the database. logging.debug("About to set valid column for index = %s" % (currPoint.idx)) self.filtered_points_df.valid.iloc[currPoint.idx] = False logging.debug("After dropping %d, filtered points = %s" % (currPoint.idx, self.filtered_points_df. iloc[currPoint.idx - 5:currPoint.idx + 5][["valid", "fmt_time"]])) logging.debug("remove huge invalid ts offset point = %s" % currPoint) timeseries.invalidate_raw_entry(currPoint["_id"]) # We currently re-retrieve the last point every time, so # searching upwards is good enough but if we use # lastPoint = currPoint, we should update currPoint here return False else: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ending trip" % (lastPoint.ts, currPoint.ts, self.time_threshold, currPoint.ts - lastPoint.ts)) return True else: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" % (lastPoint.ts, currPoint.ts, timeDelta, self.time_threshold, distDelta, self.distance_threshold, speedDelta, speedThreshold)) return False
def has_trip_ended(self, prev_point, curr_point, timeseries, last10PointsDistances, last5MinsDistances, last5MinTimes): # Another mismatch between phone and server. Phone stops tracking too soon, # so the distance is still greater than the threshold at the end of the trip. # But then the next point is a long time away, so we can split again (similar to a distance filter) if prev_point is None: logging.debug("prev_point is None, continuing trip") else: timeDelta = curr_point.ts - prev_point.ts distDelta = pf.calDistance(prev_point, curr_point) if timeDelta > 0: speedDelta = old_div(distDelta, timeDelta) else: speedDelta = np.nan speedThreshold = old_div(float(self.distance_threshold), self.time_threshold) if eaisr.is_tracking_restarted_in_range(prev_point.ts, curr_point.ts, timeseries): logging.debug("tracking was restarted, ending trip") return True ongoing_motion_check = len(eaisr.get_ongoing_motion_in_range(prev_point.ts, curr_point.ts, timeseries)) > 0 if timeDelta > 2 * self.time_threshold and not ongoing_motion_check: logging.debug("lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" % (prev_point.ts, curr_point.ts,self.time_threshold, curr_point.ts - prev_point.ts, ongoing_motion_check)) return True # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html # Longest flight is 17 hours, which is the longest you can go without cell reception # And even if you split an air flight that long into two, you will get some untracked time in the # middle, so that's good. TWELVE_HOURS = 12 * 60 * 60 if timeDelta > TWELVE_HOURS: logging.debug("prev_point.ts = %s, curr_point.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" % (prev_point.ts, curr_point.ts, TWELVE_HOURS, curr_point.ts - prev_point.ts)) return True if (timeDelta > 2 * self.time_threshold and # We have been here for a while speedDelta < speedThreshold): # we haven't moved very much logging.debug("prev_point.ts = %s, curr_point.ts = %s, threshold = %s, large gap = %s, ending trip" % (prev_point.ts, curr_point.ts,self.time_threshold, curr_point.ts - prev_point.ts)) return True else: logging.debug("prev_point.ts = %s, curr_point.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" % (prev_point.ts, curr_point.ts, timeDelta, self.time_threshold, distDelta, self.distance_threshold, speedDelta, speedThreshold)) # The -30 is a fuzz factor intended to compensate for older clients # where data collection stopped after 5 mins, so that we never actually # see 5 mins of data if (len(last10PointsDistances) < self.point_threshold - 1 or len(last5MinsDistances) == 0 or last5MinTimes.max() < self.time_threshold - 30): logging.debug("Too few points to make a decision, continuing") return False # Normal end-of-trip case logging.debug("last5MinsDistances.max() = %s, last10PointsDistance.max() = %s" % (last5MinsDistances.max(), last10PointsDistances.max())) if (last5MinsDistances.max() < self.distance_threshold and last10PointsDistances.max() < self.distance_threshold): return True
def has_trip_ended(self, lastPoint, currPoint, timeseries): # So we must not have been moving for the last _time filter_ # points. So the trip must have ended # Since this is a distance filter, we detect that the last # trip has ended at the time that the new trip starts. So # if the last_trip_end_point is lastPoint, then # curr_trip_start_point should be currPoint. But then we will # have problems with the spurious, noisy points that are # generated until the geofence is turned on, if ever # So we will continue to defer new trip starting until we # have worked through all of those. timeDelta = currPoint.ts - lastPoint.ts distDelta = pf.calDistance(lastPoint, currPoint) logging.debug( "lastPoint = %s, time difference = %s dist difference %s" % (lastPoint, timeDelta, distDelta)) if timeDelta > self.time_threshold: # We have been at this location for more than the time filter. # This could be because we have not been moving for the last # _time filter_ points, or because we didn't get points for # that duration, (e.g. because we were underground) if timeDelta > 0: speedDelta = distDelta / timeDelta else: speedDelta = np.nan # this is way too slow. On ios, we use 5meters in 10 minutes. # On android, we use 10 meters in 5 mins, which seems to work better # for this kind of test speedThreshold = float( self.distance_threshold * 2) / (self.time_threshold / 2) if eaisr.is_tracking_restarted_in_range(lastPoint.ts, currPoint.ts, timeseries): logging.debug("tracking was restarted, ending trip") return True # In general, we get multiple locations between each motion activity. If we see a bunch of motion activities # between two location points, and there is a large gap between the last location and the first # motion activity as well, let us just assume that there was a restart ongoing_motion_check = len( eaisr.get_ongoing_motion_in_range(lastPoint.ts, currPoint.ts, timeseries)) > 0 if timeDelta > self.time_threshold and not ongoing_motion_check: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" % (lastPoint.ts, currPoint.ts, self.time_threshold, currPoint.ts - lastPoint.ts, ongoing_motion_check)) return True # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html # Longest flight is 17 hours, which is the longest you can go without cell reception # And even if you split an air flight that long into two, you will get some untracked time in the # middle, so that's good. TWELVE_HOURS = 12 * 60 * 60 if timeDelta > TWELVE_HOURS: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" % (lastPoint.ts, currPoint.ts, TWELVE_HOURS, currPoint.ts - lastPoint.ts)) return True if (timeDelta > self.time_threshold and # We have been here for a while speedDelta < speedThreshold): # we haven't moved very much logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ending trip" % (lastPoint.ts, currPoint.ts, self.time_threshold, currPoint.ts - lastPoint.ts)) return True else: logging.debug( "lastPoint.ts = %s, currPoint.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" % (lastPoint.ts, currPoint.ts, timeDelta, self.time_threshold, distDelta, self.distance_threshold, speedDelta, speedThreshold)) return False
def _is_tracking_restarted(last_place, start_loc, timeseries): return eaisr.is_tracking_restarted_in_range(last_place.enter_ts, start_loc.ts, timeseries)
def has_trip_ended(self, lastPoint, currPoint, timeseries): # So we must not have been moving for the last _time filter_ # points. So the trip must have ended # Since this is a distance filter, we detect that the last # trip has ended at the time that the new trip starts. So # if the last_trip_end_point is lastPoint, then # curr_trip_start_point should be currPoint. But then we will # have problems with the spurious, noisy points that are # generated until the geofence is turned on, if ever # So we will continue to defer new trip starting until we # have worked through all of those. timeDelta = currPoint.ts - lastPoint.ts distDelta = pf.calDistance(lastPoint, currPoint) logging.debug("lastPoint = %s, time difference = %s dist difference %s" % (lastPoint, timeDelta, distDelta)) if timeDelta > self.time_threshold: # We have been at this location for more than the time filter. # This could be because we have not been moving for the last # _time filter_ points, or because we didn't get points for # that duration, (e.g. because we were underground) if timeDelta > 0: speedDelta = distDelta / timeDelta else: speedDelta = np.nan # this is way too slow. On ios, we use 5meters in 10 minutes. # On android, we use 10 meters in 5 mins, which seems to work better # for this kind of test speedThreshold = float(self.distance_threshold * 2) / (self.time_threshold / 2) if eaisr.is_tracking_restarted_in_range(lastPoint.ts, currPoint.ts, timeseries): logging.debug("tracking was restarted, ending trip") return True # In general, we get multiple locations between each motion activity. If we see a bunch of motion activities # between two location points, and there is a large gap between the last location and the first # motion activity as well, let us just assume that there was a restart ongoing_motion_check = len(eaisr.get_ongoing_motion_in_range(lastPoint.ts, currPoint.ts, timeseries)) > 0 if timeDelta > self.time_threshold and not ongoing_motion_check: logging.debug("lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" % (lastPoint.ts, currPoint.ts,self.time_threshold, currPoint.ts - lastPoint.ts, ongoing_motion_check)) return True # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html # Longest flight is 17 hours, which is the longest you can go without cell reception # And even if you split an air flight that long into two, you will get some untracked time in the # middle, so that's good. TWELVE_HOURS = 12 * 60 * 60 if timeDelta > TWELVE_HOURS: logging.debug("lastPoint.ts = %s, currPoint.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" % (lastPoint.ts, currPoint.ts, TWELVE_HOURS, currPoint.ts - lastPoint.ts)) return True if (timeDelta > self.time_threshold and # We have been here for a while speedDelta < speedThreshold): # we haven't moved very much logging.debug("lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ending trip" % (lastPoint.ts, currPoint.ts,self.time_threshold, currPoint.ts - lastPoint.ts)) return True else: logging.debug("lastPoint.ts = %s, currPoint.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" % (lastPoint.ts, currPoint.ts, timeDelta, self.time_threshold, distDelta, self.distance_threshold, speedDelta, speedThreshold)) return False