Пример #1
0
    def reset(self):
        self._destroy()
        self.reward = 0.0
        self.prev_reward = 0.0
        self.t = 0.0
        self.human_render = False

        self.robots = {}

        while (True):
            a_0, x_0, y_0 = -np.pi / 2 + np.pi * random.random(
            ), 0.5 + 7 * random.random(), 0.5 + 4 * random.random()
            a_1, x_1, y_1 = -np.pi / 2 + np.pi * random.random(
            ), 0.5 + 7 * random.random(), 0.5 + 4 * random.random()
            if (ICRAMap().check_coincident_with_obstacle(x_0, y_0)
                    and ICRAMap().check_coincident_with_obstacle(x_1, y_1)):
                break

        self.robots['robot_0'] = Robot(
            self.world,
            a_0,
            x_0,
            y_0,
            # self.world, -np.pi / 2, -0.1, 4.5,
            'robot_0',
            0,
            'red',
            COLOR_RED)
        # cv2.waitKey()
        self.robots['robot_1'] = Robot(self.world, a_1, x_1, y_1, 'robot_1', 1,
                                       'blue', COLOR_BLUE)

        self.map = ICRAMap(self.world)
        self.bullets = Bullet(self.world)
        self.buff_areas = AllBuffArea()
        self.supply_areas = SupplyAreas()

        self.state_dict["robot_0"] = {
            "pos": (-1, -1),
            "angle": -1,
            "health": -1,
            "velocity": (0, 0),
            "robot_0": (-1, -1),
            "robot_1": (-1, -1)
        }
        self.state_dict["robot_1"] = {
            "pos": (-1, -1),
            "angle": -1,
            "health": -1,
            "velocity": (0, 0),
            "robot_0": (-1, -1),
            "robot_1": (-1, -1)
        }
        self.actions["robot_0"] = None
        self.actions["robot_1"] = None

        # return True

        return self.step(None)[0]
Пример #2
0
 def shoot(self, aim_x_position, aim_y_position):
     if aim_y_position != 0 and aim_x_position != 0:
         bullet = Bullet(self.position["x"], self.position["y"],
                         aim_x_position, aim_y_position)
         return bullet
     else:
         return None
Пример #3
0
 def fire_bullet(self):
     if self.can_shoot:
         self.room.fire_bullet_sound.play()
         new_bullet = Bullet(self.room, self.rect.centerx, self.y)
         new_bullet.x -= 4
         self.room.add_room_object(new_bullet)
         self.room.set_timer(15, self.reset_shooting)
         self.can_shoot = False
Пример #4
0
 def Update (self):
     for e in pygame.event.get():
         if e.type == pygame.KEYDOWN:
             if e.key == pygame.K_SPACE:
                 self.scene.AddObject(Bullet(self.scene, self.GetForward(1), self.rot))
Пример #5
0
    def reset(self):
        self._destroy()
        self.reward = 0.0
        self.prev_reward = 0.0
        self.t = 0.0
        self.human_render = False

        self.robots = {}
        '''
        avaiable_pos = [
            [0.5, 0.5], [0.5, 1.5], [0.5, 2.5], [0.5, 3.5],
            [1.5, 0.5], [1.5, 4.5], [1.5, 3.5],
            [2.5, 0.5], [2.5, 1.5], [2.5, 2.5], [2.5, 3.5],
            [4.0, 1.5], [4.0, 3.5],
            [5.5, 0.5], [5.5, 1.5], [5.5, 2.5], [5.5, 3.5],
            [6.5, 0.5], [6.5, 1.5], [6.5, 4.5],
            [7.5, 0.5], [7.5, 1.5], [7.5, 2.5], [7.5, 3.5]
        ]
        '''
        avaiable_pos = [
            [0.5, 0.5],
            [0.5, 2.0],
            [0.5, 3.0],
            [0.5, 4.5],  # 0 1 2 3 
            [1.5, 0.5],
            [1.5, 3.0],
            [1.5, 4.5],  # 4 5 6
            [2.75, 0.5],
            [2.75, 2.0],
            [2.75, 3.0],
            [2.75, 4.5],  # 7 8 9 10
            [4.0, 1.75],
            [4.0, 3.25],  # 11 12
            [5.25, 0.5],
            [5.25, 2.0],
            [5.25, 3.0],
            [5.25, 4.5],  # 13 14 15 16
            [6.5, 0.5],
            [6.5, 2.0],
            [6.5, 4.5],  # 17 18 19
            [7.5, 0.5],
            [7.5, 2.0],
            [7.5, 3.0],
            [7.5, 4.5]  # 20 21 22 23
        ]
        connected = [[1, 2, 3, 4], [0, 2, 3], [0, 1, 3, 5], [0, 1, 2, 6],
                     [0, 7], [2, 9], [3, 10], [8, 9, 10, 4], [7, 9, 10, 11],
                     [7, 8, 10, 5, 12], [7, 8, 9], [8, 14], [9, 15],
                     [14, 15, 16, 17], [13, 15, 16, 18, 11, 11, 11, 11, 11],
                     [13, 14, 16, 12, 12, 12, 12, 12], [13, 14, 15, 19],
                     [13, 20], [14, 21], [16, 23], [21, 22, 23, 17],
                     [20, 22, 23, 18], [20, 21, 23], [20, 21, 22, 19]]
        random_index = random.randint(0, 23)
        #random_index = 5
        init_pos_0 = avaiable_pos[random_index]
        init_pos_1 = avaiable_pos[random.choice(connected[random_index])]

        self.robots['robot_0'] = Robot(self.world, np.pi / 2, init_pos_0[0],
                                       init_pos_0[1], 'robot_0', 0, 'red',
                                       COLOR_RED)
        self.robots['robot_1'] = Robot(self.world, -np.pi, init_pos_1[0],
                                       init_pos_1[1], 'robot_1', 1, 'blue',
                                       COLOR_BLUE)

        self.map = ICRAMap(self.world)
        self.bullets = Bullet(self.world)
        self.buff_areas = AllBuffArea()
        self.supply_areas = SupplyAreas()

        self.state_dict["robot_0"] = {
            "pos": (-1, -1),
            "angle": -1,
            "health": -1,
            "velocity": (0, 0),
            "angular": 0,
            "robot_0": (-1, -1),
            "robot_1": (-1, -1)
        }
        self.state_dict["robot_1"] = {
            "pos": (-1, -1),
            "angle": -1,
            "health": -1,
            "velocity": (0, 0),
            "angular": 0,
            "robot_0": (-1, -1),
            "robot_1": (-1, -1)
        }
        self.actions["robot_0"] = None
        self.actions["robot_1"] = None

        return init_pos_1
Пример #6
0
class ICRAField(gym.Env, EzPickle):
    metadata = {
        # 'render.modes': ['human', 'rgb_array', 'state_pixels'],
        'render.modes': 'human',
        'video.frames_per_second': FPS
    }

    def __init__(self):
        EzPickle.__init__(self)
        self.seed()
        self.contactListener_keepref = ICRAContactListener(self)
        self.world = Box2D.b2World(
            (0, 0), contactListener=self.contactListener_keepref)
        self.viewer = None
        self.invisible_state_window = None
        self.invisible_video_window = None
        self.robots = {}
        self.map = None
        self.buff_areas = None
        self.bullets = None
        self.supply_areas = None
        self.detect_callback = detectCallback()

        self.reward = 0.0
        self.prev_reward = 0.0
        self.state_dict = {}
        self.actions = {}

    def seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    def _destroy(self):
        for robot_name in self.robots.keys():
            self.robots[robot_name].destroy()
        self.robots = {}
        if self.map:
            self.map.destroy()
        self.map = None
        if self.bullets:
            self.bullets.destroy()
        self.bullets = None

    def reset(self):
        self._destroy()
        self.reward = 0.0
        self.prev_reward = 0.0
        self.t = 0.0
        self.human_render = False

        self.robots = {}
        '''
        avaiable_pos = [
            [0.5, 0.5], [0.5, 1.5], [0.5, 2.5], [0.5, 3.5],
            [1.5, 0.5], [1.5, 4.5], [1.5, 3.5],
            [2.5, 0.5], [2.5, 1.5], [2.5, 2.5], [2.5, 3.5],
            [4.0, 1.5], [4.0, 3.5],
            [5.5, 0.5], [5.5, 1.5], [5.5, 2.5], [5.5, 3.5],
            [6.5, 0.5], [6.5, 1.5], [6.5, 4.5],
            [7.5, 0.5], [7.5, 1.5], [7.5, 2.5], [7.5, 3.5]
        ]
        '''
        avaiable_pos = [
            [0.5, 0.5],
            [0.5, 2.0],
            [0.5, 3.0],
            [0.5, 4.5],  # 0 1 2 3 
            [1.5, 0.5],
            [1.5, 3.0],
            [1.5, 4.5],  # 4 5 6
            [2.75, 0.5],
            [2.75, 2.0],
            [2.75, 3.0],
            [2.75, 4.5],  # 7 8 9 10
            [4.0, 1.75],
            [4.0, 3.25],  # 11 12
            [5.25, 0.5],
            [5.25, 2.0],
            [5.25, 3.0],
            [5.25, 4.5],  # 13 14 15 16
            [6.5, 0.5],
            [6.5, 2.0],
            [6.5, 4.5],  # 17 18 19
            [7.5, 0.5],
            [7.5, 2.0],
            [7.5, 3.0],
            [7.5, 4.5]  # 20 21 22 23
        ]
        connected = [[1, 2, 3, 4], [0, 2, 3], [0, 1, 3, 5], [0, 1, 2, 6],
                     [0, 7], [2, 9], [3, 10], [8, 9, 10, 4], [7, 9, 10, 11],
                     [7, 8, 10, 5, 12], [7, 8, 9], [8, 14], [9, 15],
                     [14, 15, 16, 17], [13, 15, 16, 18, 11, 11, 11, 11, 11],
                     [13, 14, 16, 12, 12, 12, 12, 12], [13, 14, 15, 19],
                     [13, 20], [14, 21], [16, 23], [21, 22, 23, 17],
                     [20, 22, 23, 18], [20, 21, 23], [20, 21, 22, 19]]
        random_index = random.randint(0, 23)
        #random_index = 5
        init_pos_0 = avaiable_pos[random_index]
        init_pos_1 = avaiable_pos[random.choice(connected[random_index])]

        self.robots['robot_0'] = Robot(self.world, np.pi / 2, init_pos_0[0],
                                       init_pos_0[1], 'robot_0', 0, 'red',
                                       COLOR_RED)
        self.robots['robot_1'] = Robot(self.world, -np.pi, init_pos_1[0],
                                       init_pos_1[1], 'robot_1', 1, 'blue',
                                       COLOR_BLUE)

        self.map = ICRAMap(self.world)
        self.bullets = Bullet(self.world)
        self.buff_areas = AllBuffArea()
        self.supply_areas = SupplyAreas()

        self.state_dict["robot_0"] = {
            "pos": (-1, -1),
            "angle": -1,
            "health": -1,
            "velocity": (0, 0),
            "angular": 0,
            "robot_0": (-1, -1),
            "robot_1": (-1, -1)
        }
        self.state_dict["robot_1"] = {
            "pos": (-1, -1),
            "angle": -1,
            "health": -1,
            "velocity": (0, 0),
            "angular": 0,
            "robot_0": (-1, -1),
            "robot_1": (-1, -1)
        }
        self.actions["robot_0"] = None
        self.actions["robot_1"] = None

        return init_pos_1
        #return self.step(None)[0]

    def getStateArray(self, robot_id):
        robot_state = self.state_dict[robot_id]
        pos = robot_state["pos"]
        velocity = robot_state["velocity"]
        angle = robot_state["angle"]
        angular = robot_state["angular"]
        health = robot_state["health"]
        robot_0 = robot_state["robot_0"]
        robot_1 = robot_state["robot_1"]
        return [
            pos[0], pos[1], velocity[0], velocity[1], angle, angular,
            robot_0[0], robot_0[1], robot_1[0], robot_1[1]
        ]

    def stepCollision(self):
        collision_bullet_robot = self.contactListener_keepref.collision_bullet_robot
        collision_bullet_wall = self.contactListener_keepref.collision_bullet_wall
        collision_robot_wall = self.contactListener_keepref.collision_robot_wall
        for bullet, robot in collision_bullet_robot:
            self.bullets.destroyById(bullet)
            if (self.robots[robot].buffLeftTime) > 0:
                self.robots[robot].loseHealth(25)
            else:
                self.robots[robot].loseHealth(50)
        for bullet in collision_bullet_wall:
            self.bullets.destroyById(bullet)
        for robot in collision_robot_wall:
            self.robots[robot].loseHealth(10)
        self.contactListener_keepref.clean()

    def stepAction(self, robot_name, action):
        # gas, rotate, transverse, rotate cloud terrance, shoot
        self.robots[robot_name].moveAheadBack(action[0])
        self.robots[robot_name].turnLeftRight(action[1])
        self.robots[robot_name].moveTransverse(action[2])
        self.robots[robot_name].rotateCloudTerrance(action[3])
        #print(int(self.t * FPS) % (60 * FPS))
        if int(self.t * FPS) % (60 * FPS) == 0:
            self.robots[robot_name].refreshReloadOppotunity()
        if action[5] > 0.99:
            self.robots[robot_name].addBullets()
            action[5] = +0.0
        if action[4] > 0.99 and int(self.t * FPS) % (FPS / 10) == 1:
            if (self.robots[robot_name].bullets_num > 0):
                init_angle, init_pos = self.robots[robot_name].getGunAnglePos()
                self.bullets.shoot(init_angle, init_pos)
                self.robots[robot_name].bullets_num -= 1

    def detectEnemy(self, robot_id):
        detected = {}
        for i in range(-170, 170, 5):
            angle, pos = self.robots[robot_id].getAnglePos()
            angle += math.pi / 2
            angle += i / 180 * math.pi
            p1 = (pos[0] + 0.2 * math.cos(angle),
                  pos[1] + 0.2 * math.sin(angle))
            p2 = (pos[0] + SCAN_RANGE * math.cos(angle),
                  pos[1] + SCAN_RANGE * math.sin(angle))
            self.world.RayCast(self.detect_callback, p1, p2)
            u = self.detect_callback.userData
            if u in self.robots.keys():
                if u not in detected.keys():
                    p = detected[u] = self.detect_callback.point
                    pos = self.robots[robot_id].getPos()
                    p = (p[0] - pos[0], p[1] - pos[1])
                    angle = math.atan2(p[1], p[0])
                    # Auto shoot
                    self.robots[robot_id].setCloudTerrance(angle)

        for robot_name in self.robots.keys():
            self.state_dict[robot_id][robot_name] = detected[
                robot_name] if robot_name in detected.keys() else (-1, -1)

    def updateRobotState(self, robot_id):
        self.state_dict[robot_id][robot_id] = self.robots[robot_id].getPos()
        self.state_dict[robot_id]["health"] = self.robots[robot_id].health
        self.state_dict[robot_id]["pos"] = self.robots[robot_id].getPos()
        self.state_dict[robot_id]["angle"] = self.robots[robot_id].getAngle()
        self.state_dict[robot_id]["velocity"] = self.robots[
            robot_id].getVelocity()
        self.state_dict[robot_id]["angular"] = self.robots[
            robot_id].hull.angularVelocity

    def setRobotAction(self, robot_id, action):
        self.actions[robot_id] = action

    def step(self, action):
        ###### observe ######
        for robot_name in self.robots.keys():
            self.detectEnemy(robot_name)
            self.updateRobotState(robot_name)

        ###### action ######
        self.setRobotAction("robot_0", action)
        for robot_name in self.robots.keys():
            action = self.actions[robot_name]
            if action is not None:
                self.stepAction(robot_name, action)
            self.robots[robot_name].step(1.0 / FPS)
        self.world.Step(1.0 / FPS, 6 * 30, 2 * 30)
        self.t += 1.0 / FPS

        ###### Referee ######
        self.stepCollision()
        self.buff_areas.detect(
            [self.robots["robot_0"], self.robots["robot_1"]], self.t)

        ###### reward ######
        step_reward = 0
        done = False
        # First step without action, called from reset()
        if self.actions["robot_0"] is not None:
            pos = self.state_dict["robot_0"]["pos"]
            e_pos = self.state_dict["robot_1"]["pos"]
            distance = (pos[0] - e_pos[0])**2 + (pos[1] - e_pos[1])**2
            self.reward = 10 / distance
            #self.reward = self.robots["robot_0"].health - \
            #self.robots["robot_1"].health
            #self.reward -= 0.1 * self.t * FPS
            step_reward = self.reward - self.prev_reward
            if self.robots["robot_0"].health <= 0:
                done = True
                #step_reward -= 1000
            if self.robots["robot_1"].health <= 0:
                done = True
                #step_reward += 1000
            self.prev_reward = self.reward

        return self.getStateArray("robot_0"), step_reward, done, {}

    def render(self, mode='human'):
        if self.viewer is None:
            from gym.envs.classic_control import rendering
            self.viewer = rendering.Viewer(WINDOW_W, WINDOW_H)
            self.time_label = pyglet.text.Label('0000',
                                                font_size=36,
                                                x=20,
                                                y=WINDOW_H * 5.0 / 40.00,
                                                anchor_x='left',
                                                anchor_y='center',
                                                color=(255, 255, 255, 255))
            self.score_label = pyglet.text.Label('0000',
                                                 font_size=36,
                                                 x=20,
                                                 y=WINDOW_H * 2.5 / 40.00,
                                                 anchor_x='left',
                                                 anchor_y='center',
                                                 color=(255, 255, 255, 255))
            self.health_label = pyglet.text.Label('0000',
                                                  font_size=16,
                                                  x=520,
                                                  y=WINDOW_H * 2.5 / 40.00,
                                                  anchor_x='left',
                                                  anchor_y='center',
                                                  color=(255, 255, 255, 255))
            self.bullets_label = pyglet.text.Label('0000',
                                                   font_size=16,
                                                   x=520,
                                                   y=WINDOW_H * 3.5 / 40.00,
                                                   anchor_x='left',
                                                   anchor_y='center',
                                                   color=(255, 255, 255, 255))
            self.buff_stay_time = pyglet.text.Label('0000',
                                                    font_size=16,
                                                    x=520,
                                                    y=WINDOW_H * 4.5 / 40.00,
                                                    anchor_x='left',
                                                    anchor_y='center',
                                                    color=(255, 255, 255, 255))
            self.buff_left_time = pyglet.text.Label('0000',
                                                    font_size=16,
                                                    x=520,
                                                    y=WINDOW_H * 5.5 / 40.00,
                                                    anchor_x='left',
                                                    anchor_y='center',
                                                    color=(255, 255, 255, 255))
            self.transform = rendering.Transform()

        if "t" not in self.__dict__:
            return  # reset() not called yet

        zoom = ZOOM * SCALE
        zoom_state = ZOOM * SCALE * STATE_W / WINDOW_W
        zoom_video = ZOOM * SCALE * VIDEO_W / WINDOW_W
        #scroll_x = self.car0.hull.position[0]
        #scroll_y = self.car0.hull.position[1]
        #angle = -self.car0.hull.angle
        scroll_x = 4.0
        scroll_y = 0.0
        angle = 0
        #vel = self.car0.hull.linearVelocity
        # if np.linalg.norm(vel) > 0.5:
        #angle = math.atan2(vel[0], vel[1])
        self.transform.set_scale(zoom, zoom)
        self.transform.set_translation(
            WINDOW_W / 2 - (scroll_x * zoom * math.cos(angle) -
                            scroll_y * zoom * math.sin(angle)),
            WINDOW_H / 4 - (scroll_x * zoom * math.sin(angle) +
                            scroll_y * zoom * math.cos(angle)))
        # self.transform.set_rotation(angle)

        self.map.draw(self.viewer)
        for robot_name in self.robots.keys():
            self.robots[robot_name].draw(self.viewer)
        self.bullets.draw(self.viewer)

        arr = None
        win = self.viewer.window
        if mode != 'state_pixels':
            win.switch_to()
            win.dispatch_events()

        if mode == 'human':
            self.human_render = True
            win.clear()
            t = self.transform
            gl.glViewport(0, 0, WINDOW_W, WINDOW_H)
            t.enable()
            self.render_background()
            for geom in self.viewer.onetime_geoms:
                geom.render()
            t.disable()
            self.render_indicators(WINDOW_W, WINDOW_H)
            win.flip()

        self.viewer.onetime_geoms = []
        return arr

    def close(self):
        if self.viewer is not None:
            self.viewer.close()
            self.viewer = None

    def render_background(self):
        gl.glBegin(gl.GL_QUADS)
        gl.glColor4f(0.4, 0.8, 0.4, 1.0)
        gl.glVertex3f(-PLAYFIELD, +PLAYFIELD, 0)
        gl.glVertex3f(+PLAYFIELD, +PLAYFIELD, 0)
        gl.glVertex3f(+PLAYFIELD, -PLAYFIELD, 0)
        gl.glVertex3f(-PLAYFIELD, -PLAYFIELD, 0)
        gl.glColor4f(0.4, 0.9, 0.4, 1.0)
        k = PLAYFIELD / 20.0
        for x in range(-20, 20, 2):
            for y in range(-20, 20, 2):
                gl.glVertex3f(k * x + k, k * y + 0, 0)
                gl.glVertex3f(k * x + 0, k * y + 0, 0)
                gl.glVertex3f(k * x + 0, k * y + k, 0)
                gl.glVertex3f(k * x + k, k * y + k, 0)
        gl.glEnd()
        self.buff_areas.render(gl)
        self.supply_areas.render(gl)

    def render_indicators(self, W, H):
        self.time_label.text = "Time: {} s".format(int(self.t))
        self.score_label.text = "Score: %04i" % self.reward
        self.health_label.text = "health left Car0 : {} Car1: {} ".format(
            self.robots["robot_0"].health, self.robots["robot_1"].health)
        self.bullets_label.text = "Car0 bullets : {}, oppotunity to add : {}  ".format(
            self.robots['robot_0'].bullets_num,
            self.robots['robot_0'].opportuniy_to_add_bullets)
        self.buff_stay_time.text = 'Buff Stay Time: Red {}s, Blue {}s'.format(
            int(self.buff_areas.buffAreas[0].maxStayTime),
            int(self.buff_areas.buffAreas[1].maxStayTime))
        self.buff_left_time.text = 'Buff Left Time: Red {}s, Blue {}s'.format(
            int(self.robots['robot_0'].buffLeftTime),
            int(self.robots['robot_1'].buffLeftTime))
        self.time_label.draw()
        self.score_label.draw()
        self.health_label.draw()
        self.bullets_label.draw()
        self.buff_stay_time.draw()
        self.buff_left_time.draw()