Example #1
0
def get_data_file(bn: str) -> str:
    import act4e_interfaces
    p = os.path.dirname(act4e_interfaces.__file__)
    data = os.path.join(p, 'data')
    f = os.path.join(data, bn)
    if not os.path.exists(f):
        raise ZException('does not exist', f=f)
    return read_ustring_from_utf8_file(f)
Example #2
0
def make_scenario_main(args=None):
    setup_logging()
    parser = argparse.ArgumentParser()

    parser.add_argument("--config", help="Configuration", required=True)
    parser.add_argument("-o", "--output", help="Destination directory", required=True)
    parser.add_argument("-n", "--num", type=int, help="Number of scenarios to generate", required=True)

    parsed = parser.parse_args(args=args)
    config: str = parsed.config
    basename = os.path.basename(config).split(".")[0]
    data = read_ustring_from_utf8_file(config)
    interpreted = yaml.load(data, Loader=yaml.Loader)
    n: int = parsed.num
    output: str = parsed.output
    params = object_from_ipce(interpreted, ScenarioGenerationParam, iedo=iedo)
    for i in range(n):
        scenario_name = f"{basename}-{i:03d}"
        yaml_str = _get_map_yaml(params.map_name)
        scenario = make_scenario(
            yaml_str=yaml_str,
            scenario_name=scenario_name,
            only_straight=params.only_straight,
            min_dist=params.min_dist,
            delta_y_m=params.delta_y_m,
            robots_npcs=params.robots_npcs,
            robots_parked=params.robots_parked,
            robots_pcs=params.robots_parked,
            nduckies=params.nduckies,
            duckie_min_dist_from_other_duckie=params.duckie_min_dist_from_other_duckie,
            duckie_min_dist_from_robot=params.duckie_min_dist_from_robot,
            duckie_y_bounds=params.duckie_y_bounds,
            delta_theta_rad=np.deg2rad(params.theta_tol_deg),
        )
        scenario_struct = ipce_from_object(scenario, Scenario, ieso=ieso)
        scenario_yaml = yaml.dump(scenario_struct)
        filename = os.path.join(output, f"{scenario_name}.scenario.yaml")
        write_ustring_to_utf8_file(scenario_yaml, filename)
        dm = interpret_scenario(scenario)
        output_dir = os.path.join(output, scenario_name)
        dw.draw_static(dm, output_dir=output_dir)
        export_gltf(dm, output_dir, background=False)
Example #3
0
def make_scenario_main(args=None):
    setup_logging()
    parser = argparse.ArgumentParser()

    # parser.add_argument("--config", help="Configuration", required=True)
    parser.add_argument("-o",
                        "--output",
                        help="Destination directory",
                        required=True)
    parser.add_argument("-n",
                        "--num",
                        type=int,
                        help="Number of scenarios to generate",
                        required=True)
    parser.add_argument(
        "--styles",
        default="synthetic-F",
        help=
        "Draw preview in various styles, comma separated. (needs gym duckietown)",
    )

    parsed, rest = parser.parse_known_args(args=args)
    if parsed.styles == "all":
        styles = ["synthetic", "synthetic-F", "photos", "smooth"]
    else:
        styles = parsed.styles.split(",")
    for config in rest:
        basename = os.path.basename(config).split(".")[0]
        data = read_ustring_from_utf8_file(config)
        interpreted = yaml.load(data, Loader=yaml.Loader)
        n: int = parsed.num
        output: str = parsed.output
        params: ScenarioGenerationParam = object_from_ipce(
            interpreted, ScenarioGenerationParam, iedo=iedo)
        for i in range(n):
            scenario_name = f"{basename}-{i:03d}"
            yaml_str = _get_map_yaml(params.map_name)
            scenario = make_scenario(
                yaml_str=yaml_str,
                scenario_name=scenario_name,
                only_straight=params.only_straight,
                min_dist=params.min_dist,
                delta_y_m=params.delta_y_m,
                robots_npcs=params.robots_npcs,
                robots_parked=params.robots_parked,
                robots_pcs=params.robots_pcs,
                nduckies=params.nduckies,
                duckie_min_dist_from_other_duckie=params.
                duckie_min_dist_from_other_duckie,
                duckie_min_dist_from_robot=params.duckie_min_dist_from_robot,
                duckie_y_bounds=params.duckie_y_bounds,
                delta_theta_rad=np.deg2rad(params.theta_tol_deg),
                pc_robot_protocol=params.pc_robot_protocol,
                npc_robot_protocol=params.npc_robot_protocol,
                tree_density=params.tree_density,
                tree_min_dist=params.tree_min_dist,
            )

            # styles = ['smooth']
            for style in styles:
                try:
                    from gym_duckietown.simulator import Simulator
                except ImportError:
                    logger.warning(traceback.format_exc())
                    # noinspection PyUnusedLocal
                    Simulator = None
                else:
                    sim = Simulator(
                        "4way",
                        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,
                    )
                    logger.info("resetting")
                    sim.reset()
                    m = cast(
                        dw.MapFormat1,
                        yaml.load(scenario.environment, Loader=yaml.Loader))

                    if "objects" not in m:
                        m["objects"] = {}
                    obs: Dict[str, object] = m["objects"]

                    for robot_name, srobot in scenario.robots.items():
                        st = dw.SE2Transform.from_SE2(
                            pose_from_friendly(srobot.configuration.pose))

                        obs[robot_name] = dict(kind="duckiebot",
                                               pose=st.as_json_dict(),
                                               height=0.12,
                                               color=srobot.color)

                    for duckie_name, duckie in scenario.duckies.items():
                        st = dw.SE2Transform.from_SE2(
                            pose_from_friendly(duckie.pose))
                        obs[duckie_name] = dict(kind="duckie",
                                                pose=st.as_json_dict(),
                                                height=0.08,
                                                color=duckie.color)

                    sim._interpret_map(m)
                    sim.reset()
                    logger.info("rendering obs")
                    img = sim.render_obs()
                    out = os.path.join(output, scenario_name, style, "cam.png")
                    save_rgb_to_png(img, out)
                    out = os.path.join(output, scenario_name, style, "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)
                    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, scenario_name, style,
                                     "top_down.jpg"))
                    save_rgb_to_jpg(horiz, out)
                    out = cast(
                        FilePath,
                        os.path.join(output, scenario_name, style,
                                     "top_down.png"))
                    save_rgb_to_png(horiz, out)

                    dw.Tile.style = style
                    dm = interpret_scenario(scenario)
                    output_dir = os.path.join(output, scenario_name, style)
                    dw.draw_static(dm, output_dir=output_dir)
                    export_gltf(dm, output_dir, background=False)

            scenario_struct = ipce_from_object(scenario, Scenario, ieso=ieso)
            scenario_yaml = yaml.dump(scenario_struct)
            filename = os.path.join(output, scenario_name, f"scenario.yaml")
            write_ustring_to_utf8_file(scenario_yaml, filename)
Example #4
0
def export_gltf(dm: DuckietownMap, outdir: str, background: bool = True):
    gltf = GLTF()
    # setattr(gltf, 'md52PV', {})

    scene_index = add_scene(gltf, Scene(nodes=[]))

    map_nodes = []
    it: IterateByTestResult

    tiles = list(iterate_by_class(dm, Tile))
    if not tiles:
        raise ZValueError("no tiles?")
    for it in tiles:
        tile = cast(Tile, it.object)
        name = it.fqn[-1]
        fn = tile.fn
        fn_normal = tile.fn_normal
        fn_emissive = tile.fn_emissive
        fn_metallic_roughness = tile.fn_metallic_roughness
        fn_occlusion = tile.fn_occlusion
        material_index = make_material(
            gltf,
            doubleSided=False,
            baseColorFactor=[1, 1, 1, 1.0],
            fn=fn,
            fn_normals=fn_normal,
            fn_emissive=fn_emissive,
            fn_metallic_roughness=fn_metallic_roughness,
            fn_occlusion=fn_occlusion,
        )
        mi = get_square()
        mesh_index = add_polygon(
            gltf,
            name + "-mesh",
            vertices=mi.vertices,
            texture=mi.textures,
            colors=mi.color,
            normals=mi.normals,
            material=material_index,
        )
        node1_index = add_node(gltf, Node(mesh=mesh_index))

        i, j = ij_from_tilename(name)
        c = (i + j) % 2
        color = [1, 0, 0, 1.0] if c else [0, 1, 0, 1.0]
        add_back = False
        if add_back:

            material_back = make_material(gltf, doubleSided=False, baseColorFactor=color)
            back_mesh_index = add_polygon(
                gltf,
                name + "-mesh",
                vertices=mi.vertices,
                texture=mi.textures,
                colors=mi.color,
                normals=mi.normals,
                material=material_back,
            )

            flip = np.diag([1.0, 1.0, -1.0, 1.0])
            flip[2, 3] = -0.01
            back_index = add_node(gltf, Node(mesh=back_mesh_index, matrix=gm(flip)))
        else:
            back_index = None

        tile_transform = it.transform_sequence
        tile_matrix2d = tile_transform.asmatrix2d().m
        s = dm.tile_size
        scale = np.diag([s, s, s, 1])
        tile_matrix = SE3_from_SE2(tile_matrix2d)
        tile_matrix = tile_matrix @ scale @ SE3_rotz(-np.pi / 2)

        tile_matrix_float = list(tile_matrix.T.flatten())
        if back_index is not None:
            children = [node1_index, back_index]
        else:
            children = [node1_index]
        tile_node = Node(name=name, matrix=tile_matrix_float, children=children)
        tile_node_index = add_node(gltf, tile_node)

        map_nodes.append(tile_node_index)

    if background:
        bg_index = add_background(gltf)
        add_node_to_scene(gltf, scene_index, bg_index)

    exports = {
        "Sign": export_sign,
        # XXX: the tree model is crewed up
        "Tree": export_tree,
        # "Tree": None,
        "Duckie": export_duckie,
        "DB18": export_DB18,
        # "Bus": export_bus,
        # "Truck": export_truck,
        # "House": export_house,
        "TileMap": None,
        "TrafficLight": export_trafficlight,
        "LaneSegment": None,
        "PlacedObject": None,
        "DuckietownMap": None,
        "Tile": None,
    }

    for it in iterate_by_class(dm, PlacedObject):
        ob = it.object

        K = type(ob).__name__
        if isinstance(ob, Sign):
            K = "Sign"

        if K not in exports:
            logger.warn(f"cannot convert {type(ob).__name__}")
            continue

        f = exports[K]
        if f is None:
            continue
        thing_index = f(gltf, it.fqn[-1], ob)

        tile_transform = it.transform_sequence
        tile_matrix2d = tile_transform.asmatrix2d().m
        tile_matrix = SE3_from_SE2(tile_matrix2d) @ SE3_rotz(np.pi / 2)
        sign_node_index = add_node(gltf, Node(children=[thing_index]))
        tile_matrix_float = list(tile_matrix.T.flatten())
        tile_node = Node(name=it.fqn[-1], matrix=tile_matrix_float, children=[sign_node_index])
        tile_node_index = add_node(gltf, tile_node)
        map_nodes.append(tile_node_index)

    mapnode = Node(name="tiles", children=map_nodes)
    map_index = add_node(gltf, mapnode)
    add_node_to_scene(gltf, scene_index, map_index)

    # add_node_to_scene(model, scene_index, node1_index)
    yfov = np.deg2rad(60)
    camera = Camera(
        name="perpcamera",
        type="perspective",
        perspective=PerspectiveCameraInfo(aspectRatio=4 / 3, yfov=yfov, znear=0.01, zfar=1000),
    )
    gltf.model.cameras.append(camera)

    t = np.array([2, 2, 0.15])
    matrix = look_at(pos=t, target=np.array([0, 2, 0]))
    cam_index = add_node(gltf, Node(name="cameranode", camera=0, matrix=list(matrix.T.flatten())))
    add_node_to_scene(gltf, scene_index, cam_index)

    cleanup_model(gltf)

    fn = os.path.join(outdir, "main.gltf")
    make_sure_dir_exists(fn)
    logger.info(f"writing to {fn}")
    gltf.export(fn)
    if True:
        data = read_ustring_from_utf8_file(fn)

        j = json.loads(data)
        data2 = json.dumps(j, indent=2)
        write_ustring_to_utf8_file(data2, fn)

    fnb = os.path.join(outdir, "main.glb")
    logger.info(f"writing to {fnb}")
    gltf.export(fnb)
    verify_trimesh = False
    if verify_trimesh:
        res = trimesh.load(fn)
        # camera_pose, _ = res.graph['cameranode']
        # logger.info(res=res)
        import pyrender

        scene = pyrender.Scene.from_trimesh_scene(res)
def read_from_file(fn: str, K: type):
    data = read_ustring_from_utf8_file(fn)
    y = yaml.load(data, Loader=yaml.Loader)
    # noinspection PyTypeChecker
    return object_from_ipce(y, K)