diff --git a/README.ko-KR.md b/README.ko-KR.md index 6f91b69..7f27b3b 100644 --- a/README.ko-KR.md +++ b/README.ko-KR.md @@ -178,7 +178,7 @@ optional arguments: -m MESSAGES, --messages MESSAGES Only consider given messages. Must be a comma- separated list of names, like - 'sensor_combined,vehicle_gps_position' + 'sensor_combined,vehicle_gnss' -d DELIMITER, --delimiter DELIMITER Use delimiter in CSV (default is ',') -o DIR, --output DIR Output directory (default is same as input file) @@ -208,7 +208,8 @@ optional arguments: -o OUTPUT_FILENAME, --output OUTPUT_FILENAME output filename --topic TOPIC_NAME topic name with position data - (default=vehicle_gps_position) + (default=vehicle_gnss, or vehicle_gps_position in + older logs) --camera-trigger CAMERA_TRIGGER Camera trigger topic name (e.g. camera_capture) ``` @@ -232,7 +233,7 @@ options: -m MESSAGES, --messages MESSAGES Only consider given messages. Must be a comma- separated list of names, like - 'sensor_combined,vehicle_gps_position' + 'sensor_combined,vehicle_gnss' -i, --ignore Ignore string parsing exceptions -v, --verbose Print extra debugging information ``` diff --git a/README.md b/README.md index 631c525..c48786a 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ optional arguments: -m MESSAGES, --messages MESSAGES Only consider given messages. Must be a comma- separated list of names, like - 'sensor_combined,vehicle_gps_position' + 'sensor_combined,vehicle_gnss' -d DELIMITER, --delimiter DELIMITER Use delimiter in CSV (default is ',') -o DIR, --output DIR Output directory (default is same as input file) @@ -208,7 +208,8 @@ optional arguments: -o OUTPUT_FILENAME, --output OUTPUT_FILENAME output filename --topic TOPIC_NAME topic name with position data - (default=vehicle_gps_position) + (default=vehicle_gnss, or vehicle_gps_position in + older logs) --camera-trigger CAMERA_TRIGGER Camera trigger topic name (e.g. camera_capture) ``` @@ -232,7 +233,7 @@ options: -m MESSAGES, --messages MESSAGES Only consider given messages. Must be a comma- separated list of names, like - 'sensor_combined,vehicle_gps_position' + 'sensor_combined,vehicle_gnss' -i, --ignore Ignore string parsing exceptions -v, --verbose Print extra debugging information ``` diff --git a/pyulog/ulog2csv.py b/pyulog/ulog2csv.py index adadca8..018a0a1 100644 --- a/pyulog/ulog2csv.py +++ b/pyulog/ulog2csv.py @@ -23,7 +23,7 @@ def main(): parser.add_argument( '-m', '--messages', dest='messages', help=("Only consider given messages. Must be a comma-separated list of" - " names, like 'sensor_combined,vehicle_gps_position'")) + " names, like 'sensor_combined,vehicle_gnss'")) parser.add_argument('-d', '--delimiter', dest='delimiter', action='store', help="Use delimiter in CSV (default is ',')", default=',') diff --git a/pyulog/ulog2kml.py b/pyulog/ulog2kml.py index a3f8fcb..d8bdaf9 100644 --- a/pyulog/ulog2kml.py +++ b/pyulog/ulog2kml.py @@ -12,6 +12,19 @@ #pylint: disable=too-many-locals, invalid-name, consider-using-enumerate, too-many-arguments #pylint: disable=unused-variable +# GNSS topics, newest first: vehicle_gnss replaced vehicle_gps_position +_GNSS_TOPICS = ['vehicle_gnss', 'vehicle_gps_position'] + +# Names of each position field: 'lon' in vehicle_global_position, camera_capture +# and older vehicle_gps_position, 'longitude_deg' in vehicle_gps_position and +# 'receiver.longitude' in vehicle_gnss +_POSITION_FIELDS = { + 'lon': ['lon', 'longitude_deg', 'receiver.longitude'], + 'lat': ['lat', 'latitude_deg', 'receiver.latitude'], + 'alt': ['alt', 'altitude_msl_m', 'receiver.altitude_msl'], + 'fix_type': ['fix_type', 'receiver.fix_type'], +} + def main(): """Command line interface""" @@ -22,8 +35,9 @@ def main(): parser.add_argument('-o', '--output', dest='output_filename', help="output filename", default='track.kml') parser.add_argument('--topic', dest='topic_name', - help="topic name with position data (default=vehicle_gps_position)", - default='vehicle_gps_position') + help="topic name with position data (default=vehicle_gnss, or" + " vehicle_gps_position in older logs)", + default=None) parser.add_argument('--camera-trigger', dest='camera_trigger', help="Camera trigger topic name (e.g. camera_capture)", default=None) @@ -39,7 +53,7 @@ def main(): # alternative example call: # convert_ulog2kml(args.filename, 'test.kml', ['vehicle_global_position', -# 'vehicle_gps_position'], [_kml_default_colors, lambda x: simplekml.Color.green]) +# 'vehicle_gnss'], [_kml_default_colors, lambda x: simplekml.Color.green]) def _kml_default_colors(x): @@ -51,12 +65,12 @@ def _kml_default_colors(x): simplekml.Color.lawngreen, simplekml.Color.indianred, simplekml.Color.hotpink, simplekml.Color.bisque, simplekml.Color.cyan, simplekml.Color.darksalmon, simplekml.Color.deepskyblue, simplekml.Color.lime, simplekml.Color.orchid] - return colors_arr[x] + return colors_arr[x % len(colors_arr)] -def convert_ulog2kml(ulog_file_name, output_file_name, position_topic_name= - 'vehicle_gps_position', colors=_kml_default_colors, altitude_offset=0, +def convert_ulog2kml(ulog_file_name, output_file_name, position_topic_name=None, + colors=_kml_default_colors, altitude_offset=0, minimum_interval_s=0.1, style=None, camera_trigger_topic_name=None, disable_str_exceptions=False): """ @@ -64,8 +78,9 @@ def convert_ulog2kml(ulog_file_name, output_file_name, position_topic_name= :param ulog_file_name: The ULog filename to open and read :param output_file_name: KML Output file name - :param position_topic_name: either name of a topic (must have 'lon', 'lat' & - 'alt' fields), or a list of topic names + :param position_topic_name: either name of a topic with a position, or a list + of topic names. Defaults to vehicle_gnss, or vehicle_gps_position in + older logs :param colors: lambda function with flight mode (int) (or -1) as input and returns a color (eg 'fffff8f0') (or list of lambda functions if multiple position_topic_name's) @@ -92,6 +107,9 @@ def convert_ulog2kml(ulog_file_name, output_file_name, position_topic_name= used_style[key] = style[key] + default_topic = position_topic_name is None + if default_topic: + position_topic_name = _GNSS_TOPICS if not isinstance(position_topic_name, list): position_topic_name = [position_topic_name] colors = [colors] @@ -102,6 +120,12 @@ def convert_ulog2kml(ulog_file_name, output_file_name, position_topic_name= load_topic_names.append(camera_trigger_topic_name) ulog = ULog(ulog_file_name, load_topic_names, disable_str_exceptions) + if default_topic: + logged_topics = {elem.name for elem in ulog.data_list} + position_topic_name = [next((topic for topic in _GNSS_TOPICS if topic in logged_topics), + _GNSS_TOPICS[0])] + colors = [colors] + # get flight modes try: cur_dataset = ulog.get_dataset('vehicle_status') @@ -121,6 +145,16 @@ def convert_ulog2kml(ulog_file_name, output_file_name, position_topic_name= kml.save(output_file_name) +def _get_field(data, name, required=True): + """ data of position field `name`, under whichever name the topic uses """ + for field_name in _POSITION_FIELDS[name]: + if field_name in data: + return data[field_name] + if required: + raise KeyError(name + ' not found in data') + return None + + def _kml_add_camera_triggers(kml, ulog, camera_trigger_topic_name, altitude_offset): """ Add camera trigger points to the map @@ -134,13 +168,9 @@ def _kml_add_camera_triggers(kml, ulog, camera_trigger_topic_name, altitude_offs if len(cur_dataset) > 0: cur_dataset = cur_dataset[0] - # 'longitude_deg' is used in newer PX4 versions - pos_lon = (cur_dataset.data['lon'] if 'lon' in cur_dataset.data else - cur_dataset.data['longitude_deg']) - pos_lat = (cur_dataset.data['lat'] if 'lat' in cur_dataset.data else - cur_dataset.data['latitude_deg']) - pos_alt = (cur_dataset.data['alt'] if 'alt' in cur_dataset.data else - cur_dataset.data['altitude_msl_m']) + pos_lon = _get_field(cur_dataset.data, 'lon') + pos_lat = _get_field(cur_dataset.data, 'lat') + pos_alt = _get_field(cur_dataset.data, 'alt') sequence = cur_dataset.data['seq'] for i in range(len(pos_lon)): @@ -167,17 +197,14 @@ def _kml_add_position_data(kml, ulog, position_topic_name, colors, style, cur_dataset = cur_dataset[0] - # 'longitude_deg' is used in newer PX4 versions - pos_lon = (cur_dataset.data['lon'] if 'lon' in cur_dataset.data else - cur_dataset.data['longitude_deg']) - pos_lat = (cur_dataset.data['lat'] if 'lat' in cur_dataset.data else - cur_dataset.data['latitude_deg']) - pos_alt = (cur_dataset.data['alt'] if 'alt' in cur_dataset.data else - cur_dataset.data['altitude_msl_m']) + pos_lon = _get_field(cur_dataset.data, 'lon') + pos_lat = _get_field(cur_dataset.data, 'lat') + pos_alt = _get_field(cur_dataset.data, 'alt') pos_t = cur_dataset.data['timestamp'] + fix_type = _get_field(cur_dataset.data, 'fix_type', required=False) - if 'fix_type' in cur_dataset.data: - indices = cur_dataset.data['fix_type'] > 2 # use only data with a fix + if fix_type is not None: + indices = fix_type > 2 # use only data with a fix pos_lon = pos_lon[indices] pos_lat = pos_lat[indices] pos_alt = pos_alt[indices] diff --git a/pyulog/ulog2ros2bag.py b/pyulog/ulog2ros2bag.py index 08f3183..99487e8 100644 --- a/pyulog/ulog2ros2bag.py +++ b/pyulog/ulog2ros2bag.py @@ -68,7 +68,7 @@ def main(): dest="messages", help=( "Only consider given messages. Must be a comma-separated list of" - " names, like 'sensor_combined,vehicle_gps_position'" + " names, like 'sensor_combined,vehicle_gnss'" ), )