def draw_maps_main(args=None): coloredlogs.install(level="DEBUG") from duckietown_world.world_duckietown import load_map from duckietown_world.resources import list_maps if args is None: args = sys.argv[1:] parser = argparse.ArgumentParser() parser.add_argument("--output", help="output dir", default="out-draw_maps") parser.add_argument("map_names", nargs=argparse.REMAINDER) parsed = parser.parse_args(args) output = parsed.output if parsed.map_names: map_names = parsed.map_names else: map_names = list_maps() logger.info("Drawing the maps %s." % ", ".join(map_names)) from duckietown_world.gltf import export_gltf for map_name in map_names: duckietown_map = load_map(map_name) out = os.path.join(output, map_name) draw_map(out, duckietown_map) style = "synthetic-F" export_gltf(duckietown_map, out) draw_map_gymd(map_name, out, style) y = duckietown_map.as_json_dict() fn = os.path.join(out, "map.json") with open(fn, "w") as f: f.write(json.dumps(y, indent=4))
def draw_logs_main_(output, filename): if output is None: output = filename + '.out' if not os.path.exists(output): os.makedirs(output) logger.info('processing file %s' % filename) log = read_simulator_log(filename) duckietown_env = log.duckietown if log.observations: images = {'observations': log.observations} else: images = None interval = SampledSequence.from_iterator( enumerate(log.trajectory.timestamps)) evaluated = evaluate_rules(poses_sequence=log.trajectory, interval=interval, world=duckietown_env, ego_name='ego') timeseries = make_timeseries(evaluated) timeseries.update(timeseries_actions(log)) print(evaluated) draw_static(duckietown_env, output, images=images, timeseries=timeseries) return evaluated
def draw_maps_main(args=None): from duckietown_world.world_duckietown import list_maps, load_map if args is None: args = sys.argv[1:] parser = argparse.ArgumentParser() parser.add_argument("--output", help="output dir", default="out-draw_maps") parser.add_argument("map_names", nargs=argparse.REMAINDER) parsed = parser.parse_args(args) output = parsed.output if parsed.map_names: map_names = parsed.map_names else: map_names = list_maps() logger.info("Drawing the maps %s." % ", ".join(map_names)) for map_name in map_names: duckietown_map = load_map(map_name) out = os.path.join(output, map_name) draw_map(out, duckietown_map) y = duckietown_map.as_json_dict() fn = os.path.join(out, "map.json") with open(fn, "w") as f: f.write(json.dumps(y, indent=4))
def make_groups( tabs: Dict[str, Tab], timeseries_groups: Optional[Dict[str, TimeseriesGroups]] ) -> Dict[str, TabGroup]: if timeseries_groups: logger.info(tabs=list(tabs), timeseries_groups=timeseries_groups) tab_groups = {} for k, v in timeseries_groups.items(): mytabs = {kk: tabs[kk] for kk in v.contains} tab_groups[k] = TabGroup(v.title, tabs=mytabs) return tab_groups # raise NotImplementedError() else: groups = {} for tid, tab in tabs.items(): if "/" in tid: this_group, _, code = tid.partition("/") else: this_group = "main" code = tid if this_group not in groups: groups[this_group] = TabGroup(this_group, {}) groups[this_group].tabs[code] = tab return groups
def read_simulator_log(filename): from duckietown_world.world_duckietown import DB18, construct_map duckietown_map = None curpos_timestamps = [] curpos_values = [] timestamps_observations = [] observations = [] for ob in read_log(filename): if ob.topic == 'map_info': map_data = ob.data['map_data'] tile_size = ob.data['tile_size'] duckietown_map = construct_map(map_data, tile_size) if ob.topic == 'observations': timestamps_observations.append(ob.timestamp) observations.append(ob.data) # if ob.topic == 'misc': # sim = ob.data['Simulator'] # cur_pos = sim['cur_pos'] # cur_angle = sim['cur_angle'] # # curpos_values.append((cur_pos, cur_angle)) # curpos_timestamps.append(ob.timestamp) if ob.topic == 'Simulator': sim = ob.data cur_pos = sim['cur_pos'] cur_angle = sim['cur_angle'] curpos_values.append((cur_pos, cur_angle)) curpos_timestamps.append(ob.timestamp) if timestamps_observations: logger.info('Found %d observations' % len(timestamps_observations)) observations = SampledSequence(timestamps_observations, observations) else: observations = None if not duckietown_map: msg = 'Could not find duckietown_map.' raise Exception(msg) transforms = [] for cur_pos, cur_angle in curpos_values: transform = duckietown_map.se2_from_curpos(cur_pos, cur_angle) transforms.append(transform) trajectory = SampledSequence(curpos_timestamps, transforms) if not curpos_timestamps: msg = 'Could not find any position.' raise Exception(msg) robot = DB18() duckietown_map.set_object('ego', robot, ground_truth=trajectory) return SimulatorLog(duckietown=duckietown_map, observations=observations, trajectory=trajectory)
def draw_map(output: str, duckietown_map: "DuckietownMap") -> None: from duckietown_world.world_duckietown import DuckietownMap if not os.path.exists(output): os.makedirs(output) assert isinstance(duckietown_map, DuckietownMap) fns = draw_static(duckietown_map, output_dir=output, pixel_size=(640, 640), area=None) for fn in fns: logger.info(f"Written to {fn}")
def load_map(map_name): logger.info('loading map %s' % map_name) maps_dir = get_maps_dir() fn = os.path.join(maps_dir, map_name + '.yaml') if not os.path.exists(fn): msg = 'Could not find file %s' % fn raise ValueError(msg) data = open(fn).read() yaml_data = yaml.load(data) # from gym_duckietown.simulator import ROAD_TILE_SIZE tile_size = 0.61 # XXX return construct_map(yaml_data, tile_size)
def draw_map_gymd(map_name: str, output: AbsDirPath, style: str): try: from gym_duckietown.simulator import Simulator except ImportError: return sim = Simulator( map_name, enable_leds=True, domain_rand=False, num_tris_distractors=0, camera_width=640, camera_height=480, # distortion=True, color_ground=[0, 0.3, 0], # green style=style, ) sim.reset() logger.info("rendering obs") img = sim.render_obs() out = os.path.join(output, "cam.jpg") save_rgb_to_jpg(img, out) sim.cur_pos = [-100.0, -100.0, -100.0] from gym_duckietown.simulator import FrameBufferMemory td = FrameBufferMemory(width=1024, height=1024) # noinspection PyProtectedMember horiz = sim._render_img( width=td.width, height=td.height, multi_fbo=td.multi_fbo, final_fbo=td.final_fbo, img_array=td.img_array, top_down=True, ) # img = sim.render("top_down") out = cast(FilePath, os.path.join(output, "top_down.jpg")) save_rgb_to_jpg(horiz, out)
def draw_static( root: PlacedObject, output_dir: str, pixel_size: Tuple[int, int] = (480, 480), area=None, images=None, timeseries=None, height_of_stored_images: Optional[int] = None, main_robot_name: Optional[str] = None, ) -> Sequence[str]: from duckietown_world.world_duckietown import get_sampling_points, ChooseTime images = images or {} timeseries = timeseries or {} if not os.path.exists(output_dir): os.makedirs(output_dir) fn_svg = os.path.join(output_dir, "drawing.svg") fn_html = os.path.join(output_dir, "drawing.html") timestamps = get_sampling_points(root) # logger.info(f'timestamps: {timestamps}') if len(timestamps) == 0: keyframes = SampledSequence[Timestamp]([0], [0]) else: keyframes = SampledSequence[Timestamp](range(len(timestamps)), timestamps) # nkeyframes = len(keyframes) if area is None: areas = [] all_keyframes = keyframes.values keyframes_for_extent = [all_keyframes[0], all_keyframes[-1]] for t in keyframes_for_extent: root_t = root.filter_all(ChooseTime(t)) # print(i, root_t) rarea = get_extent_points(root_t) areas.append(rarea) area = reduce(RectangularArea.join, areas) logger.info("area: %s" % area) drawing, base = get_basic_upright2(fn_svg, area, pixel_size) # drawing.add(drawing.defs()) gmg = drawing.g() base.add(gmg) static, dynamic = get_static_and_dynamic(root) t0 = keyframes.values[0] root_t0 = root.filter_all(ChooseTime(t0)) g_static = drawing.g() g_static.attribs["class"] = "static" draw_recursive(drawing, root_t0, g_static, draw_list=static) base.add(g_static) obs_div = Tag(name="div") imagename2div = {} for name in images: imagename2div[name] = Tag(name="div") obs_div.append(imagename2div[name]) # logger.debug('dynamic: %s' % dynamic) for i, t in keyframes: g_t = drawing.g() g_t.attribs["class"] = "keyframe keyframe%d" % i root_t = root.filter_all(ChooseTime(t)) draw_recursive(drawing, root_t, g_t, draw_list=dynamic) base.add(g_t) for name, sequence in images.items(): try: obs = sequence.at(t) updated = True except UndefinedAtTime: obs = sequence.at_or_previous(t) updated = False img = Tag(name="img") if isinstance(obs, bytes): data = obs else: data = obs.bytes_contents if height_of_stored_images is not None: data = get_resized_image(data, height_of_stored_images) img.attrs["src"] = data_encoded_for_src(data, "image/jpeg") # print('image %s %s: %.4fMB ' % (i, t, len(resized) / (1024 * 1024.0))) img.attrs["class"] = "keyframe keyframe%d" % i img.attrs["visualize"] = "hide" img.attrs["updated"] = int(updated) imagename2div[name].append(img) other = "" # language=html visualize_controls = """\ <style> *[visualize_parts=false] { display: none; } </style> <p> <input id='checkbox-static' type="checkbox" onclick="hideshow(this);" checked>static data</input> <input id='checkbox-textures' type="checkbox" onclick="hideshow(this);" checked>textures</input> <input id='checkbox-axes' type="checkbox" onclick="hideshow(this);">axes</input> <br/> <input id='checkbox-lane_segments' type="checkbox" onclick="hideshow(this);">map lane segments</input> (<input id='checkbox-lane_segments-control_points' type="checkbox" onclick="hideshow( this);">control points</input>)</p> </p> <p> <input id='checkbox-vehicles' type="checkbox" onclick="hideshow(this);" checked>vehicles</input> <input id='checkbox-duckies' type="checkbox" onclick="hideshow(this);" checked>duckies</input> <input id='checkbox-signs' type="checkbox" onclick="hideshow(this);" checked>signs</input> <input id='checkbox-sign-papers' type="checkbox" onclick="hideshow(this);" checked>signs textures</input> <input id='checkbox-decorations' type="checkbox" onclick="hideshow(this);" checked>decorations</input> </p> <p> <input id='checkbox-current_lane' type="checkbox" onclick="hideshow(this);">current lane</input> <input id='checkbox-anchors' type="checkbox" onclick="hideshow(this);">anchor point</input> </p> <script> var checkboxValues = null; name2selector = { "checkbox-static": "g.static", "checkbox-textures": "g.static .tile-textures", "checkbox-axes": "g.axes", "checkbox-lane_segments": "g.static .LaneSegment", "checkbox-lane_segments-control_points": " .control-point", "checkbox-current_lane": "g.keyframe .LaneSegment", "checkbox-duckies": ".Duckie", "checkbox-signs": ".Sign", "checkbox-sign-papers": ".Sign .sign-paper", "checkbox-vehicles": ".Vehicle", "checkbox-decorations": ".Decoration", 'checkbox-anchors': '.Anchor', }; function hideshow(element) { console.log(element); element_name = element.id; console.log(element_name); selector = name2selector[element_name]; checked = element.checked; console.log(selector); console.log(checked); elements = document.querySelectorAll(selector); elements.forEach(_ => _.setAttribute('visualize_parts', checked)); checkboxValues[element_name] = checked; try { localStorage.setItem("checkboxValues", JSON.stringify(checkboxValues)); } catch (error) { console.log('cannot save preferences.'); console.log(error); } } function init() { for(var name in name2selector) { console.log(name); element = document.getElementById(name); if(name in checkboxValues) { element.checked = checkboxValues[name]; } hideshow(element); } } document.addEventListener("DOMContentLoaded", function(event) { init(); }); try { checkboxValues = JSON.parse(localStorage.getItem('checkboxValues')) || {}; } catch (error) { console.log('cannot load preferences.'); console.log(error); checkboxValues = {} } init(); console.log(checkboxValues); </script> """ div_timeseries = str(make_tabs(timeseries)) obs_div = str(obs_div) html = make_html_slider( drawing, keyframes, obs_div=obs_div, other=other, div_timeseries=div_timeseries, visualize_controls=visualize_controls, ) with open(fn_html, "w") as f: f.write(html) # language=css style = """ .sign-paper { display: none; } g.axes, .LaneSegment { display: none; } """ drawing.defs.add(drawing.style(style)) drawing.save(pretty=True) logger.info("Written SVG to %s" % fn_svg) logger.info("Written HTML to %s" % fn_html) return [fn_svg, fn_html]
def draw_static(root, output_dir, pixel_size=(480, 480), area=None, images=None, timeseries=None): from duckietown_world.world_duckietown import get_sampling_points, ChooseTime images = images or {} timeseries = timeseries or {} if not os.path.exists(output_dir): os.makedirs(output_dir) fn_svg = os.path.join(output_dir, 'drawing.svg') fn_html = os.path.join(output_dir, 'drawing.html') timestamps = get_sampling_points(root) if len(timestamps) == 0: keyframes = SampledSequence([0], [0]) else: keyframes = SampledSequence(range(len(timestamps)), timestamps) # nkeyframes = len(keyframes) if area is None: areas = [] for i, t in keyframes: root_t = root.filter_all(ChooseTime(t)) rarea = get_extent_points(root_t) areas.append(rarea) area = reduce(RectangularArea.join, areas) logger.info('area: %s' % area) drawing, base = get_basic_upright2(fn_svg, area, pixel_size) gmg = drawing.g() base.add(gmg) static, dynamic = get_static_and_dynamic(root) t0 = keyframes.values[0] root_t0 = root.filter_all(ChooseTime(t0)) g_static = drawing.g() g_static.attribs['class'] = 'static' draw_recursive(drawing, root_t0, g_static, draw_list=static) base.add(g_static) obs_div = Tag(name='div') imagename2div = {} for name in images: imagename2div[name] = Tag(name='div') obs_div.append(imagename2div[name]) # logger.debug('dynamic: %s' % dynamic) for i, t in keyframes: g_t = drawing.g() g_t.attribs['class'] = 'keyframe keyframe%d' % i root_t = root.filter_all(ChooseTime(t)) draw_recursive(drawing, root_t, g_t, draw_list=dynamic) base.add(g_t) for name, sequence in images.items(): try: obs = sequence.at(t) except UndefinedAtTime: pass else: img = Tag(name='img') resized = get_resized_image(obs.bytes_contents, 200) img.attrs['src'] = data_encoded_for_src(resized, 'image/jpeg') # print('image %s %s: %.4fMB ' % (i, t, len(resized) / (1024 * 1024.0))) img.attrs['class'] = 'keyframe keyframe%d' % i img.attrs['visualize'] = 'hide' imagename2div[name].append(img) other = "" # language=html visualize_controls = """\ <style> *[visualize_parts=false] { display: none; } </style> <p> <input id='checkbox-static' type="checkbox" onclick="hideshow(this);" checked>static data</input> <input id='checkbox-textures' type="checkbox" onclick="hideshow(this);" checked>textures</input> <input id='checkbox-axes' type="checkbox" onclick="hideshow(this);">axes</input> <br/> <input id='checkbox-lane_segments' type="checkbox" onclick="hideshow(this);">map lane segments</input> (<input id='checkbox-lane_segments-control_points' type="checkbox" onclick="hideshow(this);">control points</input>)</p> </p> <p> <input id='checkbox-vehicles' type="checkbox" onclick="hideshow(this);" checked>vehicles</input> <input id='checkbox-duckies' type="checkbox" onclick="hideshow(this);" checked>duckies</input> <input id='checkbox-signs' type="checkbox" onclick="hideshow(this);" checked>signs</input> <input id='checkbox-sign-papers' type="checkbox" onclick="hideshow(this);" checked>signs textures</input> <input id='checkbox-decorations' type="checkbox" onclick="hideshow(this);" checked>decorations</input> </p> <p> <input id='checkbox-current_lane' type="checkbox" onclick="hideshow(this);">current lane</input> <input id='checkbox-anchors' type="checkbox" onclick="hideshow(this);">anchor point</input> </p> <script> var checkboxValues = JSON.parse(localStorage.getItem('checkboxValues')) || {}; console.log(checkboxValues); name2selector = { "checkbox-static": "g.static", "checkbox-textures": "g.static .tile-textures", "checkbox-axes": "g.axes", "checkbox-lane_segments": "g.static .LaneSegment", "checkbox-lane_segments-control_points": " .control-point", "checkbox-current_lane": "g.keyframe .LaneSegment", "checkbox-duckies": ".Duckie", "checkbox-signs": ".Sign", "checkbox-sign-papers": ".Sign .sign-paper", "checkbox-vehicles": ".Vehicle", "checkbox-decorations": ".Decoration", 'checkbox-anchors': '.Anchor', }; function hideshow(element) { console.log(element); element_name = element.id; console.log(element_name); selector = name2selector[element_name]; checked = element.checked; console.log(selector); console.log(checked); elements = document.querySelectorAll(selector); elements.forEach(_ => _.setAttribute('visualize_parts', checked)); checkboxValues[element_name] = checked; localStorage.setItem("checkboxValues", JSON.stringify(checkboxValues)); } document.addEventListener("DOMContentLoaded", function(event) { for(var name in name2selector) { console.log(name); element = document.getElementById(name); if(name in checkboxValues) { element.checked = checkboxValues[name]; } hideshow(element); } }); </script> """ div_timeseries = str(make_tabs(timeseries)) obs_div = str(obs_div) html = make_html_slider(drawing, keyframes, obs_div=obs_div, other=other, div_timeseries=div_timeseries, visualize_controls=visualize_controls) with open(fn_html, 'w') as f: f.write(html) # language=css style = """ .sign-paper { display: none; } g.axes, .LaneSegment { display: none; } """ drawing.defs.add(drawing.style(style)) drawing.save(pretty=True) logger.info('Written SVG to %s' % fn_svg) logger.info('Written HTML to %s' % fn_html) return [fn_svg, fn_html]
def read_simulator_log(filename): from duckietown_world.world_duckietown import DB18, construct_map duckietown_map = None B_CURPOS = 'curpos' TOPIC_OBSERVATIONS = 'observations' TOPIC_ACTIONS = 'actions' TOPIC_RENDER_TIME = 'render_time' other_topics = [TOPIC_RENDER_TIME, TOPIC_ACTIONS, TOPIC_OBSERVATIONS] builders = defaultdict(SampledSequenceBuilder) for ob in read_log(filename): if ob.topic == 'map_info': map_data = ob.data['map_data'] tile_size = ob.data['tile_size'] duckietown_map = construct_map(map_data, tile_size) for _ in other_topics: if ob.topic == _: builders[_].add(ob.timestamp, ob.data) if ob.topic == 'Simulator': sim = ob.data cur_pos = sim['cur_pos'] cur_angle = sim['cur_angle'] builders[B_CURPOS].add(ob.timestamp, (cur_pos, cur_angle)) if len(builders[TOPIC_OBSERVATIONS]): observations = builders[TOPIC_OBSERVATIONS].as_sequence() logger.info('Found %d observations' % len(observations)) else: observations = None if not duckietown_map: msg = 'Could not find duckietown_map.' raise Exception(msg) curpos_sequence = builders[B_CURPOS].as_sequence() def curpos2transform(_): cur_pos, cur_angle = _ return duckietown_map.se2_from_curpos(cur_pos, cur_angle) trajectory = curpos_sequence.transform_values(curpos2transform) if not len(trajectory): msg = 'Could not find any position.' raise Exception(msg) robot = DB18() duckietown_map.set_object('ego', robot, ground_truth=trajectory) render_time = builders[TOPIC_RENDER_TIME].as_sequence() actions = builders[TOPIC_ACTIONS].as_sequence() return SimulatorLog(duckietown=duckietown_map, observations=observations, trajectory=trajectory, render_time=render_time, actions=actions)