def __init__(self): from pgdrive.engine.engine_utils import get_engine, engine_initialized assert engine_initialized( ), "You should not create manager before the initialization of BaseEngine" self.engine = get_engine() Randomizable.__init__(self, self.engine.global_random_seed) self.spawned_objects = {}
def __init__(self, map_config: dict = None, random_seed=None): """ Map can be stored and recover to save time when we access the map encountered before """ assert random_seed is None # assert random_seed == map_config[ # self.SEED # ], "Global seed {} should equal to seed in map config {}".format(random_seed, map_config[self.SEED]) super(BaseMap, self).__init__(config=map_config) self.film_size = (get_global_config()["draw_map_resolution"], get_global_config()["draw_map_resolution"]) self.road_network = RoadNetwork() # A flatten representation of blocks, might cause chaos in city-level generation. self.blocks = [] # Generate map and insert blocks self.engine = get_engine() self._generate() assert self.blocks, "The generate methods does not fill blocks!" # a trick to optimize performance self.road_network.after_init() self.spawn_roads = [Road(FirstPGBlock.NODE_2, FirstPGBlock.NODE_3)] self.detach_from_world()
def destroy(self): engine = get_engine() if engine.task_manager.hasTaskNamed(self.CHASE_TASK_NAME): engine.task_manager.remove(self.CHASE_TASK_NAME) if engine.task_manager.hasTaskNamed(self.TOP_DOWN_TASK_NAME): engine.task_manager.remove(self.TOP_DOWN_TASK_NAME) self.current_track_vehicle = None
def get_available_respawn_places(self, map, randomize=False): """ In each episode, we allow the vehicles to respawn at the start of road, randomize will give vehicles a random position in the respawn region """ engine = get_engine() ret = {} for bid, bp in self.safe_spawn_places.items(): if bid in self.spawn_places_used: continue # save time calculate once if not bp.get("spawn_point_position", False): lane = map.road_network.get_lane( bp["config"]["spawn_lane_index"]) assert isinstance( lane, StraightLane ), "Now we don't support respawn on circular lane" long = self.RESPAWN_REGION_LONGITUDE / 2 spawn_point_position = lane.position(longitudinal=long, lateral=0) bp.force_update({ "spawn_point_heading": np.rad2deg(lane.heading_at(long)), "spawn_point_position": (spawn_point_position[0], spawn_point_position[1]) }) spawn_point_position = bp["spawn_point_position"] lane_heading = bp["spawn_point_heading"] result = rect_region_detection(engine, spawn_point_position, lane_heading, self.RESPAWN_REGION_LONGITUDE, self.RESPAWN_REGION_LATERAL, CollisionGroup.Vehicle) if (engine.global_config["debug"] or engine.global_config["debug_physics_world"]) \ and bp.get("need_debug", True): shape = BulletBoxShape( Vec3(self.RESPAWN_REGION_LONGITUDE / 2, self.RESPAWN_REGION_LATERAL / 2, 1)) vis_body = engine.render.attach_new_node( BulletGhostNode("debug")) vis_body.node().addShape(shape) vis_body.setH(panda_heading(lane_heading)) vis_body.setPos(panda_position(spawn_point_position, z=2)) engine.physics_world.dynamic_world.attach(vis_body.node()) vis_body.node().setIntoCollideMask(CollisionGroup.AllOff) bp.force_set("need_debug", False) if not result.hasHit(): new_bp = copy.deepcopy(bp).get_dict() if randomize: new_bp["config"] = self._randomize_position_in_slot( new_bp["config"]) ret[bid] = new_bp self.spawn_places_used.append(bid) return ret
def __init__(self): assert engine_initialized( ), "You should initialize engine before adding camera to vehicle" config = get_global_config()["vehicle_config"]["depth_camera"] self.BUFFER_W, self.BUFFER_H = config[0], config[1] self.VIEW_GROUND = config[2] super(DepthCamera, self).__init__() cam = self.get_cam() lens = self.get_lens() cam.lookAt(0, 2.4, 1.3) lens.setFov(60) lens.setAspectRatio(2.0) if get_engine( ).mode == RENDER_MODE_NONE or not AssetLoader.initialized(): return # add shader for it if get_global_config()["headless_machine_render"]: vert_path = AssetLoader.file_path("shaders", "depth_cam_gles.vert.glsl") frag_path = AssetLoader.file_path("shaders", "depth_cam_gles.frag.glsl") else: from pgdrive.utils import is_mac if is_mac(): vert_path = AssetLoader.file_path("shaders", "depth_cam_mac.vert.glsl") frag_path = AssetLoader.file_path("shaders", "depth_cam_mac.frag.glsl") else: vert_path = AssetLoader.file_path("shaders", "depth_cam.vert.glsl") frag_path = AssetLoader.file_path("shaders", "depth_cam.frag.glsl") custom_shader = Shader.load(Shader.SL_GLSL, vertex=vert_path, fragment=frag_path) cam.node().setInitialState( RenderState.make(ShaderAttrib.make(custom_shader, 1))) if self.VIEW_GROUND: self.GROUND = GeoMipTerrain("mySimpleTerrain") self.GROUND.setHeightfield( AssetLoader.file_path("textures", "height_map.png")) # terrain.setBruteforce(True) # # Since the terrain is a texture, shader will not calculate the depth information, we add a moving terrain # # model to enable the depth information of terrain self.GROUND_MODEL = self.GROUND.getRoot() self.GROUND_MODEL.setPos(-128, 0, self.GROUND_HEIGHT) self.GROUND_MODEL.hide(CamMask.AllOn) self.GROUND_MODEL.show(CamMask.DepthCam) self.GROUND.generate()
def _add_building_and_speed_limit(self, road): # add house lanes = road.get_lanes(self.block_network) for idx, lane in enumerate(lanes): lane.set_speed_limit(self.SPEED_LIMIT) if idx % 2 == 1: # add toll position = lane.position(lane.length / 2, 0) building = get_engine().spawn_object( TollGateBuilding, lane=lane, position=position, heading=lane.heading_at(0) ) self.dynamic_nodes.append(building.body) self._block_objects.append(building)
def destroy(self): """ Fully delete this element and release the memory """ from pgdrive.engine.engine_utils import get_engine engine = get_engine() self.detach_from_world(engine.physics_world) if self._body is not None and hasattr(self.body, "object"): self.body.generated_object = None if self.origin is not None: self.origin.removeNode() self.dynamic_nodes.clear() self.static_nodes.clear() self._config.clear()
def _recover_vehicles_from_data(self, traffic_mgr: TrafficManager, episode_data: dict): assert isinstance(self.restore_vehicles, dict), "No place to restore vehicles" import pgdrive.component.vehicle.vehicle_type as v_types traffics = episode_data["init_traffic"] engine = get_engine() for name, config in traffics.items(): car_type = getattr(v_types, config["type"]) car = car_type.create_traffic_vehicle_from_config( traffic_mgr, config) self.restore_vehicles[name] = car car.attach_to_world(engine.pbr_worldNP, engine.physics_world) logging.debug("Recover {} Traffic Vehicles".format( len(self.restore_vehicles)))
def reset(self): """ Generate an accident scene or construction scene on block :return: None """ self.accident_lanes = [] engine = get_engine() accident_prob = self.accident_prob if abs(accident_prob - 0.0) < 1e-2: return for block in engine.current_map.blocks: if type(block) not in [Straight, Curve, InRampOnStraight, OutRampOnStraight]: # blocks with exists do not generate accident scene continue if self.np_random.rand() > accident_prob: # prob filter continue road_1 = Road(block.pre_block_socket.positive_road.end_node, block.road_node(0, 0)) road_2 = Road(block.road_node(0, 0), block.road_node(0, 1)) if not isinstance(block, Straight) else None if self.np_random.rand() > self.PROHIBIT_SCENE_PROB: accident_road = self.np_random.choice([road_1, road_2]) if not isinstance(block, Curve) else road_2 accident_road = road_1 if accident_road is None else accident_road is_ramp = isinstance(block, InRampOnStraight) or isinstance(block, OutRampOnStraight) on_left = True if self.np_random.rand() > 0.5 or (accident_road is road_2 and is_ramp) else False accident_lane_idx = 0 if on_left else -1 lane = accident_road.get_lanes(engine.current_map.road_network)[accident_lane_idx] longitude = lane.length - self.ACCIDENT_AREA_LEN lateral_len = engine.current_map.config[engine.current_map.LANE_WIDTH] lane = engine.current_map.road_network.get_lane(accident_road.lane_index(accident_lane_idx)) self.accident_lanes += accident_road.get_lanes(engine.current_map.road_network) self.prohibit_scene(lane, longitude, lateral_len, on_left) else: accident_road = self.np_random.choice([road_1, road_2]) accident_road = road_1 if accident_road is None else accident_road is_ramp = isinstance(block, InRampOnStraight) or isinstance(block, OutRampOnStraight) on_left = True if self.np_random.rand() > 0.5 or (accident_road is road_2 and is_ramp) else False lanes = accident_road.get_lanes(engine.current_map.road_network) accident_lane_idx = self.np_random.randint(0, len(lanes) - 1) if on_left else -1 lane = lanes[accident_lane_idx] longitude = self.np_random.rand() * lane.length / 2 + lane.length / 2 if self.np_random.rand() > 0.5: self.break_down_scene(lane, longitude) else: self.barrier_scene(lane, longitude)
def __init__(self, num_lasers: int = 16, distance: float = 50, enable_show=True): # properties self.available = True if num_lasers > 0 and distance > 0 else False parent_node_np: NodePath = get_engine().render self.origin = parent_node_np.attachNewNode("Could_points") show = enable_show and (AssetLoader.loader is not None) self.dim = num_lasers self.num_lasers = num_lasers self.perceive_distance = distance self.height = self.DEFAULT_HEIGHT self.radian_unit = 2 * np.pi / num_lasers if self.num_lasers > 0 else None self.start_phase_offset = 0 self._lidar_range = np.arange( 0, self.num_lasers) * self.radian_unit + self.start_phase_offset # override these properties to decide which elements to detect and show self.origin.hide(CamMask.RgbCam | CamMask.Shadow | CamMask.Shadow | CamMask.DepthCam) self.mask = CollisionGroup.BrokenLaneLine self.cloud_points_vis = [] if show else None logging.debug("Load Vehicle Module: {}".format( self.__class__.__name__)) if show: for laser_debug in range(self.num_lasers): ball = AssetLoader.loader.loadModel( AssetLoader.file_path("models", "box.bam")) ball.setScale(0.001) ball.setColor(0., 0.5, 0.5, 1) shape = BulletSphereShape(0.1) ghost = BulletGhostNode('Lidar Point') ghost.setIntoCollideMask(CollisionGroup.AllOff) ghost.addShape(shape) laser_np = self.origin.attachNewNode(ghost) self.cloud_points_vis.append(laser_np) ball.getChildren().reparentTo(laser_np)
def _create_vehicle_chassis(self): self.LENGTH = type(self).LENGTH self.WIDTH = type(self).WIDTH self.HEIGHT = type(self).HEIGHT assert self.LENGTH < BaseVehicle.MAX_LENGTH, "Vehicle is too large!" assert self.WIDTH < BaseVehicle.MAX_WIDTH, "Vehicle is too large!" chassis = BaseRigidBodyNode(self.name, BodyName.Vehicle) chassis.setIntoCollideMask(CollisionGroup.Vehicle) chassis_shape = BulletBoxShape( Vec3(self.WIDTH / 2, self.LENGTH / 2, self.HEIGHT / 2)) ts = TransformState.makePos(Vec3(0, 0, self.HEIGHT / 2)) chassis.addShape(chassis_shape, ts) chassis.setMass(self.MASS) chassis.setDeactivationEnabled(False) chassis.notifyCollisions( True ) # advance collision check, do callback in pg_collision_callback physics_world = get_engine().physics_world vehicle_chassis = BulletVehicle(physics_world.dynamic_world, chassis) vehicle_chassis.setCoordinateSystem(ZUp) self.dynamic_nodes.append(vehicle_chassis) return vehicle_chassis
def __init__( self, vehicle_config: Union[dict, Config] = None, name: str = None, random_seed=None, ): """ This Vehicle Config is different from self.get_config(), and it is used to define which modules to use, and module parameters. And self.physics_config defines the physics feature of vehicles, such as length/width :param vehicle_config: mostly, vehicle module config :param random_seed: int """ # check assert vehicle_config is not None, "Please specify the vehicle config." assert engine_initialized( ), "Please make sure game engine is successfully initialized!" # NOTE: it is the game engine, not vehicle drivetrain self.engine = get_engine() BaseObject.__init__(self, name, random_seed, self.engine.global_config["vehicle_config"]) BaseVehicleState.__init__(self) self.update_config(vehicle_config) am_i_the_special_one = self.config["am_i_the_special_one"] # build vehicle physics model vehicle_chassis = self._create_vehicle_chassis() self.add_body(vehicle_chassis.getChassis()) self.system = vehicle_chassis self.chassis = self.origin self.wheels = self._create_wheel() # powertrain config self.increment_steering = self.config["increment_steering"] self.enable_reverse = self.config["enable_reverse"] self.max_speed = self.config["max_speed"] self.max_steering = self.config["max_steering"] # visualization color = sns.color_palette("colorblind") idx = get_np_random().randint(len(color)) rand_c = color[idx] if am_i_the_special_one: rand_c = color[2] # A pretty green self.top_down_color = (rand_c[0] * 255, rand_c[1] * 255, rand_c[2] * 255) self.panda_color = rand_c self._add_visualization() # modules, get observation by using these modules self.lane: Optional[AbstractLane] = None self.lane_index = None self.navigation: Optional[Navigation] = None self.lidar: Optional[Lidar] = None # detect surrounding vehicles self.side_detector: Optional[SideDetector] = None # detect road side self.lane_line_detector: Optional[ LaneLineDetector] = None # detect nearest lane lines self.image_sensors = {} # state info self.throttle_brake = 0.0 self.steering = 0 self.last_current_action = deque([(0.0, 0.0), (0.0, 0.0)], maxlen=2) self.last_position = (0, 0) self.last_heading_dir = self.heading self.dist_to_left_side = None self.dist_to_right_side = None # step info self.out_of_route = None self.on_lane = None self.spawn_place = (0, 0) self._init_step_info() # others self._add_modules_for_vehicle() self.takeover = False self.expert_takeover = False self.energy_consumption = 0 self.action_space = self.get_action_space_before_init( extra_action_dim=self.config["extra_action_dim"]) self.break_down = False # overtake_stat self.front_vehicles = set() self.back_vehicles = set() if self.engine.current_map is not None: self.reset()
def __init__(self, control_object, random_seed=None, config=None): Randomizable.__init__(self, random_seed) Configurable.__init__(self, config) self.engine = get_engine() self.control_object = control_object self.action_info = dict()