def mapsd_thread(): global last_gps context = zmq.Context() poller = zmq.Poller() gps_external_sock = messaging.sub_sock(context, 8032, poller, conflate=True) map_data_sock = messaging.pub_sock(context, 8065) traffic_data_sock = messaging.sub_sock(context, 8208, poller, conflate=True) cur_way = None curvature_valid = False curvature = None upcoming_curvature = 0. dist_to_turn = 0. road_points = None speedLimittraffic = 0 speedLimittraffic_prev = 0 max_speed = None max_speed_ahead = None max_speed_ahead_dist = None max_speed_prev = 0 speedLimittrafficvalid = False while True: gps_ext = None traffic = None for socket, event in poller.poll(0): if socket is gps_external_sock: gps_ext = messaging.recv_one(socket) elif socket is traffic_data_sock: traffic = arne182.LiveTrafficData.from_bytes(socket.recv()) if traffic is not None: if traffic.speedLimitValid: speedLimittraffic = traffic.speedLimit if abs(speedLimittraffic_prev - speedLimittraffic) > 0.1: speedLimittrafficvalid = True speedLimittraffic_prev = speedLimittraffic if traffic.speedAdvisoryValid: speedLimittrafficAdvisory = traffic.speedAdvisory speedLimittrafficAdvisoryvalid = True else: speedLimittrafficAdvisoryvalid = False else: speedLimittrafficAdvisoryvalid = False speedLimittrafficvalid = False if gps_ext is not None: gps = gps_ext.gpsLocationExternal else: continue save_gps_data(gps) last_gps = gps fix_ok = gps.flags & 1 if gps.accuracy > 2.0: fix_ok = False if not fix_ok or last_query_result is None or not cache_valid: cur_way = None curvature = None max_speed_ahead = None max_speed_ahead_dist = None curvature_valid = False upcoming_curvature = 0. dist_to_turn = 0. road_points = None map_valid = False else: map_valid = True lat = gps.latitude lon = gps.longitude heading = gps.bearing speed = gps.speed query_lock.acquire() cur_way = Way.closest(last_query_result, lat, lon, heading, cur_way) if cur_way is not None: pnts, curvature_valid = cur_way.get_lookahead( lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) if pnts is not None: xs = pnts[:, 0] ys = pnts[:, 1] road_points = [float(x) for x in xs], [float(y) for y in ys] if speed < 5: curvature_valid = False if curvature_valid and pnts.shape[0] <= 3: curvature_valid = False else: curvature_valid = False upcoming_curvature = 0. curvature = None dist_to_turn = 0. # The curvature is valid when at least MAPS_LOOKAHEAD_DISTANCE of road is found if curvature_valid: # Compute the curvature for each point with np.errstate(divide='ignore'): circles = [ circle_through_points(*p) for p in zip(pnts, pnts[1:], pnts[2:]) ] circles = np.asarray(circles) radii = np.nan_to_num(circles[:, 2]) radii[radii < 15.] = 10000 if cur_way.way.tags['highway'] == 'trunk': radii = radii * 1.6 # https://media.springernature.com/lw785/springer-static/image/chp%3A10.1007%2F978-3-658-01689-0_21/MediaObjects/298553_35_De_21_Fig65_HTML.gif if cur_way.way.tags[ 'highway'] == 'motorway' or cur_way.way.tags[ 'highway'] == 'motorway_link': radii = radii * 2.8 curvature = 1. / radii # Index of closest point closest = np.argmin(np.linalg.norm(pnts, axis=1)) dist_to_closest = pnts[ closest, 0] # We can use x distance here since it should be close # Compute distance along path dists = list() dists.append(0) for p, p_prev in zip(pnts, pnts[1:, :]): dists.append(dists[-1] + np.linalg.norm(p - p_prev)) dists = np.asarray(dists) dists = dists - dists[closest] + dist_to_closest dists = dists[1:-1] close_idx = np.logical_and(dists > 0, dists < 500) dists = dists[close_idx] curvature = curvature[close_idx] if len(curvature): # TODO: Determine left or right turn curvature = np.nan_to_num(curvature) upcoming_curvature = np.amax(curvature) dist_to_turn = np.amin(dists[np.logical_and( curvature >= np.amax(curvature), curvature <= np.amax(curvature))]) else: upcoming_curvature = 0. dist_to_turn = 999 query_lock.release() dat = messaging.new_message() dat.init('liveMapData') if last_gps is not None: dat.liveMapData.lastGps = last_gps if cur_way is not None: dat.liveMapData.wayId = cur_way.id # Speed limit max_speed = cur_way.max_speed(heading) max_speed_ahead = None max_speed_ahead_dist = None if max_speed is not None: max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead( max_speed, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) else: max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead( speed * 1.1, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) # TODO: anticipate T junctions and right and left hand turns based on indicator if max_speed_ahead is not None and max_speed_ahead_dist is not None: dat.liveMapData.speedLimitAheadValid = True dat.liveMapData.speedLimitAhead = float(max_speed_ahead) dat.liveMapData.speedLimitAheadDistance = float( max_speed_ahead_dist) if max_speed is not None: if abs(max_speed - max_speed_prev) > 0.1: speedLimittrafficvalid = False max_speed_prev = max_speed advisory_max_speed = cur_way.advisory_max_speed() if speedLimittrafficAdvisoryvalid: dat.liveMapData.speedAdvisoryValid = True dat.liveMapData.speedAdvisory = speedLimittrafficAdvisory / 3.6 else: if advisory_max_speed is not None: dat.liveMapData.speedAdvisoryValid = True dat.liveMapData.speedAdvisory = advisory_max_speed # Curvature dat.liveMapData.curvatureValid = curvature_valid dat.liveMapData.curvature = float(upcoming_curvature) dat.liveMapData.distToTurn = float(dist_to_turn) if road_points is not None: dat.liveMapData.roadX, dat.liveMapData.roadY = road_points if curvature is not None: dat.liveMapData.roadCurvatureX = [float(x) for x in dists] dat.liveMapData.roadCurvature = [float(x) for x in curvature] if speedLimittrafficvalid: if speedLimittraffic > 0.1: dat.liveMapData.speedLimitValid = True dat.liveMapData.speedLimit = speedLimittraffic / 3.6 map_valid = False else: speedLimittrafficvalid = False else: if max_speed is not None and map_valid: dat.liveMapData.speedLimitValid = True dat.liveMapData.speedLimit = max_speed dat.liveMapData.mapValid = map_valid map_data_sock.send(dat.to_bytes())
def mapsd_thread(): global last_gps context = zmq.Context() poller = zmq.Poller() gps_sock = messaging.sub_sock(context, service_list['gpsLocation'].port, conflate=True) gps_external_sock = messaging.sub_sock( context, service_list['gpsLocationExternal'].port, conflate=True, poller=poller) map_data_sock = messaging.pub_sock(context, service_list['liveMapData'].port) traffic_data_sock = messaging.sub_sock( context, service_list['liveTrafficData'].port, conflate=True, poller=poller) cur_way = None curvature_valid = False curvature = None upcoming_curvature = 0. dist_to_turn = 0. road_points = None speedLimittraffic = 0 speedLimittraffic_prev = 0 max_speed = None max_speed_ahead = None max_speed_ahead_dist = None max_speed_prev = 0 speedLimittrafficvalid = False while True: gps = messaging.recv_one(gps_sock) gps_ext = None traffic = None for socket, event in poller.poll(0): if socket is gps_external_sock: gps_ext = messaging.recv_one(socket) elif socket is traffic_data_sock: traffic = messaging.recv_one(socket) if traffic is not None: if traffic.liveTrafficData.speedLimitValid: speedLimittraffic = traffic.liveTrafficData.speedLimit if abs(speedLimittraffic_prev - speedLimittraffic) > 0.1: speedLimittrafficvalid = True speedLimittraffic_prev = speedLimittraffic if traffic.liveTrafficData.speedAdvisoryValid: speedLimittrafficAdvisory = traffic.liveTrafficData.speedAdvisory speedLimittrafficAdvisoryvalid = True else: speedLimittrafficAdvisoryvalid = False else: speedLimittrafficAdvisoryvalid = False speedLimittrafficvalid = False if gps_ext is not None: gps = gps_ext.gpsLocationExternal else: gps = gps.gpsLocation save_gps_data(gps) last_gps = gps fix_ok = gps.flags & 1 if not fix_ok or last_query_result is None or not cache_valid: cur_way = None curvature = None max_speed_ahead = None max_speed_ahead_dist = None curvature_valid = False upcoming_curvature = 0. dist_to_turn = 0. road_points = None map_valid = False else: map_valid = True lat = gps.latitude lon = gps.longitude heading = gps.bearing speed = gps.speed query_lock.acquire() cur_way = Way.closest(last_query_result, lat, lon, heading, cur_way) if cur_way is not None: pnts, curvature_valid = cur_way.get_lookahead( lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) xs = pnts[:, 0] ys = pnts[:, 1] road_points = [float(x) for x in xs], [float(y) for y in ys] if speed < 10: curvature_valid = False if curvature_valid and pnts.shape[0] <= 3: curvature_valid = False # The curvature is valid when at least MAPS_LOOKAHEAD_DISTANCE of road is found if curvature_valid: # Compute the curvature for each point with np.errstate(divide='ignore'): circles = [ circle_through_points(*p) for p in zip(pnts, pnts[1:], pnts[2:]) ] circles = np.asarray(circles) radii = np.nan_to_num(circles[:, 2]) radii[radii < 10] = np.inf curvature = 1. / radii # Index of closest point closest = np.argmin(np.linalg.norm(pnts, axis=1)) dist_to_closest = pnts[ closest, 0] # We can use x distance here since it should be close # Compute distance along path dists = list() dists.append(0) for p, p_prev in zip(pnts, pnts[1:, :]): dists.append(dists[-1] + np.linalg.norm(p - p_prev)) dists = np.asarray(dists) dists = dists - dists[closest] + dist_to_closest dists = dists[1:-1] close_idx = np.logical_and(dists > 0, dists < 500) dists = dists[close_idx] curvature = curvature[close_idx] if len(curvature): # TODO: Determine left or right turn curvature = np.nan_to_num(curvature) # Outlier rejection new_curvature = np.percentile(curvature, 90, interpolation='lower') k = 0.6 upcoming_curvature = k * upcoming_curvature + ( 1 - k) * new_curvature in_turn_indices = curvature > 0.8 * new_curvature if np.any(in_turn_indices): dist_to_turn = np.min(dists[in_turn_indices]) else: dist_to_turn = 999 else: upcoming_curvature = 0. dist_to_turn = 999 query_lock.release() dat = messaging.new_message() dat.init('liveMapData') if last_gps is not None: dat.liveMapData.lastGps = last_gps if cur_way is not None: dat.liveMapData.wayId = cur_way.id # Speed limit max_speed = cur_way.max_speed() if max_speed is not None: #new_latitude = gps.latitude + (MAPS_LOOKAHEAD_DISTANCE * cos(heading/180*3.14159265358979) / (6371010 + gps.altitude)) * (180 / 3.14159265358979) #new_longitude = gps.longitude + (MAPS_LOOKAHEAD_DISTANCE * sin(heading/180*3.14159265358979) / (6371010 + gps.altitude)) * (180 / 3.14159265358979) / cos(gps.latitude * 3.14159265358979/180) ahead_speed = None max_speed_ahead = None max_speed_ahead_dist = None #ahead_speed = Way.closest(last_query_result, new_latitude, new_longitude, heading, ahead_speed) #if ahead_speed is not None and ahead_speed < max_speed: # max_speed_ahead = ahead_speed.max_speed() # print "speed ahead found" # print max_speed_ahead # max_speed_ahead_dist = cur_way.distance_to_closest_node(lat, lon, heading, pnts) # print "distance" # print max_speed_ahead_dist if abs(max_speed - max_speed_prev) > 0.1: speedLimittrafficvalid = False max_speed_prev = max_speed # TODO: use the function below to anticipate upcoming speed limits max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead( max_speed, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) if max_speed_ahead is not None and max_speed_ahead_dist is not None: dat.liveMapData.speedLimitAheadValid = True dat.liveMapData.speedLimitAhead = float(max_speed_ahead) dat.liveMapData.speedLimitAheadDistance = float( max_speed_ahead_dist) advisory_max_speed = cur_way.advisory_max_speed() if speedLimittrafficAdvisoryvalid: dat.liveMapData.speedAdvisoryValid = True dat.liveMapData.speedAdvisory = speedLimittrafficAdvisory / 3.6 else: if advisory_max_speed is not None: dat.liveMapData.speedAdvisoryValid = True dat.liveMapData.speedAdvisory = advisory_max_speed # Curvature dat.liveMapData.curvatureValid = curvature_valid dat.liveMapData.curvature = float(upcoming_curvature) dat.liveMapData.distToTurn = float(dist_to_turn) if road_points is not None: dat.liveMapData.roadX, dat.liveMapData.roadY = road_points if curvature is not None: dat.liveMapData.roadCurvatureX = [float(x) for x in dists] dat.liveMapData.roadCurvature = [float(x) for x in curvature] if speedLimittrafficvalid: if speedLimittraffic > 0.1: dat.liveMapData.speedLimitValid = True dat.liveMapData.speedLimit = speedLimittraffic / 3.6 map_valid = False else: speedLimittrafficvalid = False else: if max_speed is not None: dat.liveMapData.speedLimitValid = True dat.liveMapData.speedLimit = max_speed #print "speedLimittraffic_prev" #print speedLimittraffic_prev #print "speedLimittraffic" #print speedLimittraffic #print "max_speed_prev" #print max_speed_prev #print "max_speed" #print max_speed #print "speedLimittrafficvalid" #if speedLimittrafficvalid: # print "True" #else: # print "False" dat.liveMapData.mapValid = map_valid map_data_sock.send(dat.to_bytes())
def mapsd_thread(): global last_gps context = zmq.Context() gps_sock = messaging.sub_sock(context, service_list['gpsLocation'].port, conflate=True) gps_external_sock = messaging.sub_sock(context, service_list['gpsLocationExternal'].port, conflate=True) map_data_sock = messaging.pub_sock(context, service_list['liveMapData'].port) cur_way = None curvature_valid = False curvature = None upcoming_curvature = 0. dist_to_turn = 0. road_points = None while True: gps = messaging.recv_one(gps_sock) gps_ext = messaging.recv_one_or_none(gps_external_sock) if gps_ext is not None: gps = gps_ext.gpsLocationExternal else: gps = gps.gpsLocation last_gps = gps fix_ok = gps.flags & 1 if not fix_ok or last_query_result is None or not cache_valid: cur_way = None curvature = None curvature_valid = False upcoming_curvature = 0. dist_to_turn = 0. road_points = None map_valid = False else: map_valid = True lat = gps.latitude lon = gps.longitude heading = gps.bearing speed = gps.speed query_lock.acquire() cur_way = Way.closest(last_query_result, lat, lon, heading, cur_way) if cur_way is not None: pnts, curvature_valid = cur_way.get_lookahead(lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) xs = pnts[:, 0] ys = pnts[:, 1] road_points = [float(x) for x in xs], [float(y) for y in ys] if speed < 10: curvature_valid = False if curvature_valid and pnts.shape[0] <= 3: curvature_valid = False # The curvature is valid when at least MAPS_LOOKAHEAD_DISTANCE of road is found if curvature_valid: # Compute the curvature for each point with np.errstate(divide='ignore'): circles = [circle_through_points(*p) for p in zip(pnts, pnts[1:], pnts[2:])] circles = np.asarray(circles) radii = np.nan_to_num(circles[:, 2]) radii[radii < 10] = np.inf curvature = 1. / radii # Index of closest point closest = np.argmin(np.linalg.norm(pnts, axis=1)) dist_to_closest = pnts[closest, 0] # We can use x distance here since it should be close # Compute distance along path dists = list() dists.append(0) for p, p_prev in zip(pnts, pnts[1:, :]): dists.append(dists[-1] + np.linalg.norm(p - p_prev)) dists = np.asarray(dists) dists = dists - dists[closest] + dist_to_closest dists = dists[1:-1] close_idx = np.logical_and(dists > 0, dists < 500) dists = dists[close_idx] curvature = curvature[close_idx] if len(curvature): # TODO: Determine left or right turn curvature = np.nan_to_num(curvature) # Outlier rejection new_curvature = np.percentile(curvature, 90, interpolation='lower') k = 0.6 upcoming_curvature = k * upcoming_curvature + (1 - k) * new_curvature in_turn_indices = curvature > 0.8 * new_curvature if np.any(in_turn_indices): dist_to_turn = np.min(dists[in_turn_indices]) else: dist_to_turn = 999 else: upcoming_curvature = 0. dist_to_turn = 999 query_lock.release() dat = messaging.new_message() dat.init('liveMapData') if last_gps is not None: dat.liveMapData.lastGps = last_gps if cur_way is not None: dat.liveMapData.wayId = cur_way.id # Seed limit max_speed = cur_way.max_speed() if max_speed is not None: dat.liveMapData.speedLimitValid = True dat.liveMapData.speedLimit = max_speed # TODO: use the function below to anticipate upcoming speed limits #max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead(max_speed, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) #if max_speed_ahead is not None and max_speed_ahead_dist is not None: # dat.liveMapData.speedLimitAheadValid = True # dat.liveMapData.speedLimitAhead = float(max_speed_ahead) # dat.liveMapData.speedLimitAheadDistance = float(max_speed_ahead_dist) advisory_max_speed = cur_way.advisory_max_speed() if advisory_max_speed is not None: dat.liveMapData.speedAdvisoryValid = True dat.liveMapData.speedAdvisory = advisory_max_speed # Curvature dat.liveMapData.curvatureValid = curvature_valid dat.liveMapData.curvature = float(upcoming_curvature) dat.liveMapData.distToTurn = float(dist_to_turn) if road_points is not None: dat.liveMapData.roadX, dat.liveMapData.roadY = road_points if curvature is not None: dat.liveMapData.roadCurvatureX = [float(x) for x in dists] dat.liveMapData.roadCurvature = [float(x) for x in curvature] dat.liveMapData.mapValid = map_valid map_data_sock.send(dat.to_bytes())
def run(self): self.logger.debug("Entered run method for thread :" + str(self.name)) cur_way = None curvature_valid = False curvature = None upcoming_curvature = 0. dist_to_turn = 0. road_points = None max_speed = None max_speed_ahead = None max_speed_ahead_dist = None max_speed_prev = 0 start = time.time() while True: if time.time() - start > 2.5: print("Mapd MapsdThread lagging by: %s" % str(time.time() - start - 0.1)) if time.time() - start < 1.5: time.sleep(1.0) continue else: start = time.time() self.logger.debug("starting new cycle in endless loop") query_lock = self.sharedParams.get('query_lock', None) query_lock.acquire() gps = self.sharedParams['last_gps'] query_lock.release() if gps is None: continue fix_ok = gps.flags & 1 self.logger.debug("fix_ok = %s" % str(fix_ok)) if not fix_ok or self.sharedParams[ 'last_query_result'] is None or not self.sharedParams[ 'cache_valid']: self.logger.debug("fix_ok %s" % fix_ok) self.logger.error("Error in fix_ok logic") cur_way = None curvature = None max_speed_ahead = None max_speed_ahead_dist = None curvature_valid = False upcoming_curvature = 0. dist_to_turn = 0. road_points = None map_valid = False else: map_valid = True lat = gps.latitude lon = gps.longitude heading = gps.bearing speed = gps.speed query_lock.acquire() cur_way = Way.closest(self.sharedParams['last_query_result'], lat, lon, heading, cur_way) query_lock.release() if cur_way is not None: self.logger.debug("cur_way is not None ...") pnts, curvature_valid = cur_way.get_lookahead( lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) if pnts is not None: xs = pnts[:, 0] ys = pnts[:, 1] road_points = [float(x) for x in xs], [float(y) for y in ys] if speed < 5: curvature_valid = False if curvature_valid and pnts.shape[0] <= 3: curvature_valid = False else: curvature_valid = False upcoming_curvature = 0. curvature = None dist_to_turn = 0. # The curvature is valid when at least MAPS_LOOKAHEAD_DISTANCE of road is found if curvature_valid: # Compute the curvature for each point with np.errstate(divide='ignore'): circles = [ circle_through_points(*p, direction=True) for p in zip(pnts, pnts[1:], pnts[2:]) ] circles = np.asarray(circles) radii = np.nan_to_num(circles[:, 2]) radii[abs(radii) < 15.] = 10000 if cur_way.way.tags[ 'highway'] == 'trunk_link' or cur_way.way.tags[ 'highway'] == 'motorway_link': radii = radii * 1.6 # https://media.springernature.com/lw785/springer-static/image/chp%3A10.1007%2F978-3-658-01689-0_21/MediaObjects/298553_35_De_21_Fig65_HTML.gif elif cur_way.way.tags['highway'] == 'motorway': radii = radii * 2.8 curvature = 1. / radii rate = [ rate_curvature_points(*p) for p in zip(pnts[1:], pnts[2:], curvature[0:], curvature[1:]) ] rate = ([0] + rate) curvature = np.abs(curvature) curvature = np.multiply( np.minimum(np.multiply(rate, 4000) + 0.7, 1.1), curvature) # Index of closest point closest = np.argmin(np.linalg.norm(pnts, axis=1)) dist_to_closest = pnts[ closest, 0] # We can use x distance here since it should be close # Compute distance along path dists = list() dists.append(0) for p, p_prev in zip(pnts, pnts[1:, :]): dists.append(dists[-1] + np.linalg.norm(p - p_prev)) dists = np.asarray(dists) dists = dists - dists[closest] + dist_to_closest dists = dists[1:-1] close_idx = np.logical_and(dists > 0, dists < 500) dists = dists[close_idx] curvature = curvature[close_idx] if len(curvature): curvature = np.nan_to_num(curvature) upcoming_curvature = np.amax(curvature) dist_to_turn = np.amin(dists[np.logical_and( curvature >= upcoming_curvature, curvature <= upcoming_curvature)]) else: upcoming_curvature = 0. dist_to_turn = 999 dat = messaging.new_message() dat.init('liveMapData') last_gps = self.sharedParams.get('last_gps', None) if last_gps is not None: dat.liveMapData.lastGps = last_gps if cur_way is not None: dat.liveMapData.wayId = cur_way.id self.sharedParams['osm_way_id'] = cur_way.id # Speed limit max_speed = cur_way.max_speed(heading) max_speed_ahead = None max_speed_ahead_dist = None if max_speed is not None: max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead( max_speed, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) else: max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead( speed * 1.1, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) # TODO: anticipate T junctions and right and left hand turns based on indicator if max_speed_ahead is not None and max_speed_ahead_dist is not None: dat.liveMapData.speedLimitAheadValid = True dat.liveMapData.speedLimitAhead = float(max_speed_ahead) dat.liveMapData.speedLimitAheadDistance = float( max_speed_ahead_dist) if max_speed is not None: if abs(max_speed - max_speed_prev) > 0.1: max_speed_prev = max_speed # Curvature dat.liveMapData.curvatureValid = curvature_valid dat.liveMapData.curvature = float(upcoming_curvature) dat.liveMapData.distToTurn = float(dist_to_turn) if road_points is not None: dat.liveMapData.roadX, dat.liveMapData.roadY = road_points if curvature is not None: dat.liveMapData.roadCurvatureX = [float(x) for x in dists] dat.liveMapData.roadCurvature = [ float(x) for x in curvature ] else: self.sharedParams['osm_way_id'] = 0 if max_speed is not None and map_valid: dat.liveMapData.speedLimitValid = True dat.liveMapData.speedLimit = max_speed dat.liveMapData.mapValid = map_valid self.logger.debug("Sending ... liveMapData ... %s", str(dat)) self.pm.send('liveMapData', dat)