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
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