class Pedestrian(BoxComponent):
    def __init__(
        self,
        init_state=[start_walk_lane[0], start_walk_lane[1], -np.pi / 2,
                    0],  # (x, y, theta, gait)
        number_of_gaits=6,
        gait_length=4,
        gait_progress=0,
        film_dim=(1, 6),
        prim_queue=None,  # primitive queue
        pedestrian_type='3',
    ):
        # init_state: initial state by default
        self.name = 'Pedestrian {}'.format(id(self))
        self.state = np.array(init_state, dtype="float")
        self.alive_time = 0
        self.is_dead = False
        self.number_of_gaits = film_dim[0] * film_dim[1]
        self.gait_length = gait_length
        self.gait_progress = gait_progress
        self.film_dim = film_dim
        self.pedestrian_type = random.choice(['1', '2', '3', '4', '5', '6'])
        if prim_queue == None:
            self.prim_queue = Queue()
        else:
            prim_queue = prim_queue
        self.fig = '../imglib/pedestrians/walking' + pedestrian_type + '.png'
        self.medic = '../imglib/pedestrians/medic' + '.png'
        self.all_pedestrian_types = {'1', '2', '3', '4', '5', '6'}
        self.dt = 0.1

    async def next(self, inputs, dt):
        """
        The pedestrian advances forward
        """
        #await trio.sleep(0)
        if self.is_dead:
            if self.fig != self.medic:
                self.fig = self.medic
        else:
            dee_theta, vee = inputs
            self.state[2] += dee_theta  # update heading of pedestrian
            self.state[0] += vee * np.cos(
                self.state[2]) * self.dt  # update x coordinate of pedestrian
            self.state[1] += vee * np.sin(
                self.state[2]) * self.dt  # update y coordinate of pedestrian
            distance_travelled = vee * self.dt  # compute distance travelled during dt
            gait_change = (self.gait_progress +
                           distance_travelled / self.gait_length
                           ) // 1  # compute number of gait change
            self.gait_progress = (self.gait_progress +
                                  distance_travelled / self.gait_length) % 1
            self.state[3] = int(
                (self.state[3] + gait_change) % self.number_of_gaits)
            self.alive_time += self.dt

    async def extract_primitive(self):
        #TODO: rewrite the comment below
        """
       This function updates the primitive queue and picks the next primitive to be applied. When there is no more primitive in the queue, it will
       return False

       """
        while self.prim_queue.len() > 0:
            if self.prim_queue.top(
            )[1] < 1:  # if the top primitive hasn't been exhausted
                prim_data, prim_progress = self.prim_queue.top()  # extract it
                return prim_data, prim_progress
            else:
                self.prim_queue.pop()  # pop it
        return False

    async def prim_next(self):
        #await trio.sleep(0)
        if await self.extract_primitive(
        ) == False:  # if there is no primitive to use
            await self.next((0, 0), self.dt)
        else:
            prim_data, prim_progress = await self.extract_primitive(
            )  # extract primitive data and primitive progress from prim
            start, finish, vee = prim_data  # extract data from primitive
            total_distance, _ = await self.get_walking_displacement(
                start, finish)
            if prim_progress == 0:  # ensure that starting position is correct at start of primitive
                self.state[0] = start[0]
                self.state[1] = start[1]
            if start == finish:  #waiting mode
                remaining_distance = 0
                self.state[3] = 0  # reset gait
                if self.prim_queue.len(
                ) > 1:  # if current not at last primitive
                    last_prim_data, last_prim_progress = self.prim_queue.bottom(
                    )  # extract last primitive
                    _, last_finish, vee = last_prim_data
                    _, heading = await self.get_walking_displacement(
                        self.state, last_finish)
                    if self.state[2] != heading:
                        self.state[2] = heading
            else:  # if in walking mode
                remaining_distance, heading = await self.get_walking_displacement(
                    self.state, finish)
                if self.state[2] != heading:
                    self.state[2] = heading
            if vee * self.dt > remaining_distance and remaining_distance != 0:
                await self.next((0, remaining_distance / self.dt), self.dt)
            else:
                await self.next((0, vee), self.dt)
            if total_distance != 0:
                prim_progress += self.dt / (total_distance / vee)
            self.prim_queue.replace_top(
                (prim_data, prim_progress))  # update primitive queue

    async def get_walking_displacement(self, start, finish):
        dx = finish[0] - start[0]
        dy = finish[1] - start[1]
        distance = np.linalg.norm(np.array([dx, dy]))
        heading = np.arctan2(dy, dx)
        return distance, heading

    async def start_ped(self, start_walk, end_walk):
        print('Start Pedestrian')
        self.start_walk_lane = start_walk
        self.end_walk_lane = end_walk
        self.prim_queue.enqueue(
            ((self.start_walk_lane, self.end_walk_lane, 60), 0))

    async def ped_walk(self):
        while (self.state[0] <
               self.end_walk_lane[0]):  # if not at the destination
            #print('Pedestrian is walking')
            #print(self.state)
            await self.prim_next()
            await trio.sleep(0)

    async def run(self, start_walk, end_walk):
        await self.start_ped(start_walk, end_walk)
        async with trio.open_nursery() as nursery:
            nursery.start_soon(self.ped_walk)
            await trio.sleep(0)
class Pedestrian:
    def __init__(
            self,
            init_state=[0, 0, 0, 0],  # (x, y, theta, gait)
            number_of_gaits=6,
            gait_length=4,
            gait_progress=0,
            film_dim=(1, 6),
            prim_queue=None,  # primitive queue
            pedestrian_type='3'):  # three types 1 or 2 or 3
        """
        Pedestrian class
        """
        # init_state: initial state by default (x = 0, y = 0, theta = 0, gait = 0)
        self.alive_time = 0
        self.state = np.array(init_state, dtype="float")
        self.number_of_gaits = film_dim[0] * film_dim[1]
        self.gait_length = gait_length
        self.gait_progress = gait_progress
        self.film_dim = film_dim
        if prim_queue == None:
            self.prim_queue = Queue()
        else:
            prim_queue = prim_queue
        self.fig = dir_path + '/imglib/pedestrians/walking' + pedestrian_type + '.png'

    def next(self, inputs, dt):
        """
        The pedestrian advances forward
        """
        dee_theta, vee = inputs
        self.state[2] += dee_theta  # update heading of pedestrian
        # update x coordinate of pedestrian
        self.state[0] += vee * np.cos(self.state[2]) * dt
        # update y coordinate of pedestrian
        self.state[1] += vee * np.sin(self.state[2]) * dt
        distance_travelled = vee * dt  # compute distance travelled during dt
        gait_change = (self.gait_progress + distance_travelled /
                       self.gait_length) // 1  # compute number of gait change
        self.gait_progress = (self.gait_progress +
                              distance_travelled / self.gait_length) % 1
        self.state[3] = int(
            (self.state[3] + gait_change) % self.number_of_gaits)

    def visualize(self):
        # convert gait number to i, j coordinates of subfigure
        current_gait = self.state[3]
        i = current_gait % self.film_dim[1]
        j = current_gait // self.film_dim[1]
        img = Image.open(self.fig)
        width, height = img.size
        sub_width = width / self.film_dim[1]
        sub_height = height / self.film_dim[0]
        lower = (i * sub_width, (j - 1) * sub_height)
        upper = ((i + 1) * sub_width, j * sub_height)
        area = (lower[0], lower[1], upper[0], upper[1])
        cropped_img = img.crop(area)
        return cropped_img

    def extract_primitive(self):
        # TODO: rewrite the comment below
        """
        This function updates the primitive queue and picks the next primitive to be applied. When there is no more primitive in the queue, it will
        return False

        """
        while self.prim_queue.len() > 0:
            # if the top primitive hasn't been exhausted
            if self.prim_queue.top()[1] < 1:
                prim_data, prim_progress = self.prim_queue.top()  # extract it
                return prim_data, prim_progress
            else:
                self.prim_queue.pop()  # pop it
        return False

    def prim_next(self, dt):
        if self.extract_primitive(
        ) == False:  # if there is no primitive to use
            self.next((0, 0), dt)
        else:
            # extract primitive data and primitive progress from prim
            prim_data, prim_progress = self.extract_primitive()
            start, finish, t_end = prim_data  # extract data from primitive
            if prim_progress == 0:  # ensure that starting position is correct at start of primitive
                self.state[0] = start[0]
                self.state[1] = start[1]
            if start == finish:  # waiting mode
                remaining_distance = 0
                self.state[3] = 0  # reset gait
                if self.prim_queue.len(
                ) > 1:  # if current not at last primitive
                    last_prim_data, last_prim_progress = self.prim_queue.bottom(
                    )  # extract last primitive
                    last_start, last_finish, last_t_end = last_prim_data
                    dx_last = last_finish[0] - self.state[0]
                    dy_last = last_finish[1] - self.state[1]
                    heading = np.arctan2(dy_last, dx_last)
                    if self.state[2] != heading:
                        self.state[2] = heading
            else:  # if in walking mode
                dx = finish[0] - self.state[0]
                dy = finish[1] - self.state[1]
                heading = np.arctan2(dy, dx)
                if self.state[2] != heading:
                    self.state[2] = heading
                remaining_distance = np.linalg.norm(np.array([dx, dy]))
            remaining_time = (1 - prim_progress) * t_end
            vee = remaining_distance / remaining_time
            self.next((0, vee), dt)
            prim_progress += dt / t_end
            self.prim_queue.replace_top(
                (prim_data, prim_progress))  # update primitive queue
Beispiel #3
0
class Pedestrian:
    def __init__(
            self,
            init_state=[0, 0, 0, 0],  # (x, y, theta, gait)
            number_of_gaits=6,
            gait_length=4,
            gait_progress=0,
            film_dim=(1, 6),
            prim_queue=None,  # primitive queue
            pedestrian_type='3',
            name=None,
            age=20):
        """
        Pedestrian class
        """
        # init_state: initial state by default (x = 0, y = 0, theta = 0, gait = 0)
        self.vee_max = 50
        self.alive_time = 0
        self.is_dead = False
        self.id = 0
        self.destination = (-1, -1)
        self.state = np.array(init_state, dtype="float")
        self.monitor_state = 0
        self.number_of_gaits = film_dim[0] * film_dim[1]
        self.gait_length = gait_length
        self.gait_progress = gait_progress
        self.film_dim = film_dim
        self.name = name
        self.age = age
        self.pedestrian_type = pedestrian_type
        if prim_queue == None:
            self.prim_queue = Queue()
        else:
            prim_queue = prim_queue
        self.fig = dir_path + '/imglib/pedestrians/walking' + pedestrian_type + '.png'

    def next(self, inputs, dt):
        """
        The pedestrian advances forward
        """
        if self.is_dead:
            if self.fig != medic:
                self.fig = medic
        else:
            dee_theta, vee = inputs
            self.state[2] += dee_theta  # update heading of pedestrian
            self.state[0] += vee * cos(
                self.state[2]) * dt  # update x coordinate of pedestrian
            self.state[1] += vee * sin(
                self.state[2]) * dt  # update y coordinate of pedestrian
            distance_travelled = vee * dt  # compute distance travelled during dt
            gait_change = (self.gait_progress +
                           distance_travelled / self.gait_length
                           ) // 1  # compute number of gait change
            self.gait_progress = (self.gait_progress +
                                  distance_travelled / self.gait_length) % 1
            self.state[3] = int(
                (self.state[3] + gait_change) % self.number_of_gaits)
            self.alive_time += dt

    def extract_primitive(self):
        #TODO: rewrite the comment below
        """
       This function updates the primitive queue and picks the next primitive to be applied. When there is no more primitive in the queue, it will
       return False

       """
        while self.prim_queue.len() > 0:
            if self.prim_queue.top(
            )[1] < 1:  # if the top primitive hasn't been exhausted
                prim_data, prim_progress = self.prim_queue.top()  # extract it
                return prim_data, prim_progress
            else:
                self.prim_queue.pop()  # pop it
        return False

    def prim_next(self, dt):
        if self.extract_primitive(
        ) == False:  # if there is no primitive to use
            self.next((0, 0), dt)
        else:
            prim_data, prim_progress = self.extract_primitive(
            )  # extract primitive data and primitive progress from prim
            start, finish, vee = prim_data  # extract data from primitive
            total_distance, _ = self.get_walking_displacement(start, finish)
            if prim_progress == 0:  # ensure that starting position is correct at start of primitive
                self.state[0] = start[0]
                self.state[1] = start[1]
            if start == finish:  #waiting mode
                remaining_distance = 0
                self.state[3] = 0  # reset gait
                if self.prim_queue.len(
                ) > 1:  # if current not at last primitive
                    last_prim_data, last_prim_progress = self.prim_queue.bottom(
                    )  # extract last primitive
                    _, last_finish, vee = last_prim_data
                    _, heading = self.get_walking_displacement(
                        self.state, last_finish)
                    if self.state[2] != heading:
                        self.state[2] = heading
            else:  # if in walking mode
                remaining_distance, heading = self.get_walking_displacement(
                    self.state, finish)
                if self.state[2] != heading:
                    self.state[2] = heading
            if vee * dt > remaining_distance and remaining_distance != 0:
                self.next((0, remaining_distance / dt), dt)
            else:
                self.next((0, vee), dt)
            if total_distance != 0:
                prim_progress += dt / (total_distance / vee)
            self.prim_queue.replace_top(
                (prim_data, prim_progress))  # update primitive queue

    def get_walking_displacement(self, start, finish):
        dx = finish[0] - start[0]
        dy = finish[1] - start[1]
        distance = np.linalg.norm(np.array([dx, dy]))
        heading = arctan2(dy, dx)
        return distance, heading

    # cross the street if light is green, or if the pedestrian just crossed the street, continue walking and ignore traffic light color
    def continue_walking(self, lane1, lane2, direction, remaining_time):
        person_xy = (self.state[0], self.state[1])
        walking = False
        theta = self.state[2]
        self.monitor_state = 4
        if person_xy in (lane1 + lane2) and remaining_time != -1:
            self.monitor_state = 3
            prim_data, prim_progress = self.prim_queue.get_element_at_index(-2)
            start, finish, vee = prim_data
            remaining_distance, _ = self.get_walking_displacement(
                start, finish)  # in this scenario, person_xy = start
            vee = max(vee, remaining_distance / remaining_time)
            if vee <= self.vee_max:
                walking = True
                self.monitor_state = 2
                # if the pedestrian isn't going fast enough, increase speed to cross street before light turns red
                self.prim_queue.replace_element_at_index(
                    ((start, finish, vee), prim_progress), -2)
        elif (person_xy == lane1[0]
              or person_xy == lane2[0]) and theta == direction[0]:
            walking = True
            self.monitor_state = 1
        elif (person_xy == lane1[1]
              or person_xy == lane2[1]) and theta == direction[1]:
            walking = True
            self.monitor_state = 1
        return walking

    # if the pedestrian isn't going fast enough, increase speed to cross street before light turns red
    def walk_faster(self, remaining_time):
        prim_data, prim_progress = self.prim_queue.top()
        start, finish, vee = prim_data
        remaining_distance, _ = self.get_walking_displacement(
            self.state, finish)
        if (remaining_distance / vee) > remaining_time:
            vee = remaining_distance / remaining_time
            if (vee <= self.vee_max):
                self.prim_queue.replace_top(
                    ((start, finish, vee), prim_progress))
class Pedestrian:
    def __init__(
        self,
        init_state=[2908, 665, -pi / 2, 0],  # (x, y, theta, gait)
        number_of_gaits=6,
        gait_length=4,
        gait_progress=0,
        film_dim=(1, 6),
        prim_queue=None,  # primitive queue
        pedestrian_type='3',
    ):
        # init_state: initial state by default
        #self.vee_max = 50
        self.alive_time = 0
        self.is_dead = False
        self.state = np.array(init_state, dtype="float")
        self.number_of_gaits = film_dim[0] * film_dim[1]
        self.gait_length = gait_length
        self.gait_progress = gait_progress
        self.film_dim = film_dim
        self.pedestrian_type = random.choice(['1', '2', '3', '4', '5', '6'])
        if prim_queue == None:
            self.prim_queue = Queue()
        else:
            prim_queue = prim_queue
        self.fig = dir_path + '/imglib/pedestrians/walking' + pedestrian_type + '.png'

    def next(self, inputs, dt):
        """
        The pedestrian advances forward
        """
        if self.is_dead:
            if self.fig != medic:
                self.fig = medic
        else:
            dee_theta, vee = inputs
            self.state[2] += dee_theta  # update heading of pedestrian
            self.state[0] += vee * cos(
                self.state[2]) * dt  # update x coordinate of pedestrian
            self.state[1] += vee * sin(
                self.state[2]) * dt  # update y coordinate of pedestrian
            distance_travelled = vee * dt  # compute distance travelled during dt
            gait_change = (self.gait_progress +
                           distance_travelled / self.gait_length
                           ) // 1  # compute number of gait change
            self.gait_progress = (self.gait_progress +
                                  distance_travelled / self.gait_length) % 1
            self.state[3] = int(
                (self.state[3] + gait_change) % self.number_of_gaits)
            self.alive_time += dt

    def extract_primitive(self):
        #TODO: rewrite the comment below
        """
       This function updates the primitive queue and picks the next primitive to be applied. When there is no more primitive in the queue, it will
       return False

       """
        while self.prim_queue.len() > 0:
            if self.prim_queue.top(
            )[1] < 1:  # if the top primitive hasn't been exhausted
                prim_data, prim_progress = self.prim_queue.top()  # extract it
                return prim_data, prim_progress
            else:
                self.prim_queue.pop()  # pop it
        return False

    def prim_next(self, dt):
        if self.extract_primitive(
        ) == False:  # if there is no primitive to use
            self.next((0, 0), dt)
        else:
            prim_data, prim_progress = self.extract_primitive(
            )  # extract primitive data and primitive progress from prim
            start, finish, vee = prim_data  # extract data from primitive
            total_distance, _ = self.get_walking_displacement(start, finish)
            if prim_progress == 0:  # ensure that starting position is correct at start of primitive
                self.state[0] = start[0]
                self.state[1] = start[1]
            if start == finish:  #waiting mode
                remaining_distance = 0
                self.state[3] = 0  # reset gait
                if self.prim_queue.len(
                ) > 1:  # if current not at last primitive
                    last_prim_data, last_prim_progress = self.prim_queue.bottom(
                    )  # extract last primitive
                    _, last_finish, vee = last_prim_data
                    _, heading = self.get_walking_displacement(
                        self.state, last_finish)
                    if self.state[2] != heading:
                        self.state[2] = heading
            else:  # if in walking mode
                remaining_distance, heading = self.get_walking_displacement(
                    self.state, finish)
                if self.state[2] != heading:
                    self.state[2] = heading
            if vee * dt > remaining_distance and remaining_distance != 0:
                self.next((0, remaining_distance / dt), dt)
            else:
                self.next((0, vee), dt)
            if total_distance != 0:
                prim_progress += dt / (total_distance / vee)
            self.prim_queue.replace_top(
                (prim_data, prim_progress))  # update primitive queue

    def get_walking_displacement(self, start, finish):
        dx = finish[0] - start[0]
        dy = finish[1] - start[1]
        distance = np.linalg.norm(np.array([dx, dy]))
        heading = arctan2(dy, dx)
        return distance, heading