def process_ac(logfile): '''Processes the provided ArduCopter logfile and outputs the maximum distance from home. param: logfile Path to the ArduCopter binary log file return: max_rng Maximum range from start point, or None if bad file ''' if os.path.getsize(logfile) == 0: return log = arducopter_extract.ArduLog(logfile) try: positions_unfiltered = log.extract_6dof3()[:, (5, 6, 4)] except KeyError: badlogs = open('badlogs.txt', 'a') badlogs.write('%s\n' % (logfile)) badlogs.close() return positions = [] for i in range(len(positions_unfiltered)): if positions_unfiltered[i, 0] != 0: utm_coord = utm.from_latlon(positions_unfiltered[i, 0], positions_unfiltered[i, 1]) positions.append( [utm_coord[0], utm_coord[1], positions_unfiltered[i, 2]]) if len(positions) == 0: return positions = np.array(positions) distances = np.zeros(len(positions)) for i in range(len(distances)): distances[i] = np.linalg.norm(positions[i, :] - positions[0, :]) max_rng = np.max(distances) return max_rng
def get_extents(logfile): '''Plots the extents of the specified logfile''' if os.path.getsize(logfile) == 0: return if os.path.splitext(logfile)[1].lower() == '.bin': logstruct = arducopter_extract.ArduLog(logfile) try: positions_unfiltered = logstruct.extract_6dof3()[:,(5, 6, 4)] #x, y, -z except KeyError: badlogs = open('badlogs.txt', 'a') badlogs.write('%s\n' % (logfile)) badlogs.close() return elif os.path.splitext(logfile)[1].lower() == '.csv': logstruct = dji_extract.DJILog(logfile) positions_unfiltered = logstruct.extract_6dof() if positions_unfiltered is None: return positions_unfiltered = np.array([[position[2], position[1], position[3]] for position in positions_unfiltered]) positions = [] utm_zone = 'Z' utm_zonenum = 0 for i in range(len(positions_unfiltered)): if positions_unfiltered[i, 0] != 0 and positions_unfiltered[i, 1] != 0: utm_coord = utm.from_latlon(positions_unfiltered[i, 0], positions_unfiltered[i, 1]) positions.append([utm_coord[0], utm_coord[1], positions_unfiltered[i, 2]]) utm_zonenum = utm_coord[2] utm_zone = utm_coord[3] if len(positions) == 0: return np_positions = np.array(positions) min_coords = np.amin(np_positions, 0) max_coords = np.amax(np_positions, 0) coord_range = max_coords - min_coords scale = 0.1 pos_map = np.zeros((int(coord_range[0] * scale) + 1, int(coord_range[1] * scale) + 1), dtype=np.uint8) mTw = np.array([[scale, 0, -scale * min_coords[0]], [0, scale, -scale * min_coords[1]], [0, 0, 1]]) world_pos = np.vstack((np_positions[:,0:2].transpose(), np.ones(np_positions.shape[0]))) map_pos = np.floor(np.matmul(mTw, world_pos)) for i in range(map_pos.shape[1] - 1): cv2.line(pos_map, (int(map_pos[0, i]), int(map_pos[1, i])), (int(map_pos[0, i+1]), int(map_pos[1, i+1])), 255) contours, hierarchy = cv2.findContours(pos_map, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) rect = cv2.boundingRect(contours[0]) box = np.array([[rect[0], rect[0], rect[0] + rect[2], rect[0] + rect[2]], [rect[1], rect[1] + rect[3], rect[1], rect[1] + rect[3]], [1, 1, 1, 1]]) wTm = invert_tf(mTw) box_world = np.matmul(wTm, box) extents = [] for i in range(box_world.shape[1]): ll_coord = utm.to_latlon(box_world[0, i], box_world[1, i], utm_zonenum, utm_zone) extents.append(ll_coord) return extents
def plot_ardupath(log, output_filename, overwrite=False): '''Plots the specified ArduCopter log as an ESRI shapefile at the specified output path. param: log ArduCopter binary log file path param: output_filename Output path ''' if os.path.getsize(log) == 0: return if os.path.isfile( "%s.shp" % (os.path.splitext(output_filename)[0])) and not overwrite: return logstruct = arducopter_extract.ArduLog(log) try: positions_unfiltered = logstruct.extract_6dof3()[:, (5, 6, 4)] except KeyError: badlogs = open('badlogs.txt', 'a') badlogs.write('%s\n' % (log)) badlogs.close() return positions = [] for i in range(len(positions_unfiltered)): if positions_unfiltered[i, 0] != 0: positions.append(positions_unfiltered[i, :]) if len(positions) == 0: return coords = [[position[1], position[0]] for position in positions] alts = [position[2] for position in positions] writer = shapefile.Writer(output_filename) writer.field('log', 'C') writer.line([coords]) writer.record(log) writer.close() proj = open("%s.prj" % (os.path.splitext(output_filename)[0]), 'w') epsg1 = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]]' proj.write(epsg1) proj.close()
def extract_takeoffs_apm(logfile): '''Processes the given APM logfile for the aircraft type and number of takeoffs :returns acft Aircraft type as string. One of SOLO, PX4, or S1000 tofs Number of takeoffs ''' log_struct = arducopter_extract.ArduLog(logfile) acft = log_struct.getType() if acft == arducopter_extract.ACFT.SOLO: acft_str = 'SOLO' elif acft == arducopter_extract.ACFT.PX4: acft_str = 'PX4' elif acft == arducopter_extract.ACFT.S1000: acft_str = 'S1000' else: acft_str = 'UNKNOWN' print("%s: Unknown aircraft" % (logfile)) retval = log_struct.extract_takeoffs() if retval is None: return None takeoff_date, takeoff_times, landing_times = retval return acft_str, len(takeoff_times)
def process_ac(logfile, output_file): '''Processes the provided ArduCopter logfile and outputs the distance flown to the specified output file. Appends the following line to the output file: `'$s:%.0f\n' % (logfile, distance)` param: logfile Path to the ArduCopter binary log file param: output_file Path to the common output file ''' if os.path.getsize(logfile) == 0: return log = arducopter_extract.ArduLog(logfile) try: positions_unfiltered = log.extract_6dof3()[:, (5, 6, 4)] except KeyError: badlogs = open('badlogs.txt', 'a') badlogs.write('%s\n' % (logfile)) badlogs.close() return positions = [] for i in range(len(positions_unfiltered)): if positions_unfiltered[i, 0] != 0: utm_coord = utm.from_latlon(positions_unfiltered[i, 0], positions_unfiltered[i, 1]) positions.append( [utm_coord[0], utm_coord[1], positions_unfiltered[i, 2]]) if len(positions) == 0: return positions = np.array(positions) distances = np.zeros(len(positions) - 1) for i in range(len(distances)): distances[i] = np.linalg.norm(positions[i, :] - positions[i + 1, :]) distance = np.sum(distances) with open(output_file, 'a') as file: file.write('%s:%.0f\n' % (logfile, distance))