예제 #1
0
class EnvironmentListener(traci.StepListener):
	def __init__(self, sim_number, init=True, _seed=3, setting_obj=None, algo="ATNE", main_env=None, post_process_graph=None, new_players=False):
		super(EnvironmentListener, self).__init__()
		#seed(_seed)

		if not setting_obj:
			setting_obj = GraphSetting()

		self.GraphSetting = setting_obj

		self.GraphSetting.current_running_algo = algo

		self.sim_number = sim_number

		self.post_process = PostGraph(sim_number, columns=["sim_number", "sim_step", "veh_id", "edge_id", "speed", "capacity", "budget", "prev_poi", "algo"])


		#self.post_process = PostGraph(self.sim_number, columns=["sim_number", "sim_step", "veh_id", "edge_id", "speed", "capacity", "budget", "prev_poi"]) #this is handling for saving csv
		self.t = 0
		self.main_env = main_env
		self.new_players = new_players

		self.break_condition = False #condition to check if all vehicles has arrived

		
		file_dir = os.path.dirname(self.GraphSetting.sumo_config)
		map_list = glob.glob(os.path.join(file_dir, r"*.map"))
		try:
			self.sim_env = self.read(map_list[0])
			print(f"loaded map from {map_list[0]}")
			self.sim_env.GraphSetting = setting_obj #loading map need to change setting of the map
 

		except IndexError:
			print(f".map file generating for {self.GraphSetting.sumo_config}")
			self.sim_env = Environment(setting_obj = self.GraphSetting)
			self.save(self.GraphSetting.sumo_config, self.sim_env)

		self.algo = algo

		self.sim_env.algo = algo

		logging.info(f"RUNNING ALGO {algo} simulation {sim_number}")


		self.topleft = []
		self.topright = []
		self.bottomleft = []
		self.bottomright =[]
		self.total_list = []


		point1tl = np.array((self.sim_env.map_data.junctions[self.GraphSetting.refer[0]].x, self.sim_env.map_data.junctions[self.GraphSetting.refer[0]].y))
		point1tr = np.array((self.sim_env.map_data.junctions[self.GraphSetting.refer[2]].x, self.sim_env.map_data.junctions[self.GraphSetting.refer[2]].y))
		point1bl = np.array((self.sim_env.map_data.junctions[self.GraphSetting.refer[1]].x, self.sim_env.map_data.junctions[self.GraphSetting.refer[1]].y))
		point1br = np.array((self.sim_env.map_data.junctions[self.GraphSetting.refer[2]].x, self.sim_env.map_data.junctions[self.GraphSetting.refer[3]].y))


		for key, value in self.sim_env.map_data.junctions.items():
		#for item in junction_list:
			point2 = np.array((value.x, value.y))

			distance_topleft = np.linalg.norm(point1tl - point2) 
			distance_topright = np.linalg.norm(point1tr - point2) 
			distance_bottomleft = np.linalg.norm(point1bl - point2) 
			distance_bottomright = np.linalg.norm(point1br - point2) 

			#print(f"{key} {distance_topright} {distance_topleft} {distance_bottomright} {distance_bottomleft}")

			if distance_topright <= self.GraphSetting.radiusrefer:
				self.topright.append(key)
			if distance_topleft <= self.GraphSetting.radiusrefer:
				self.topleft.append(key)
			if distance_bottomright <= self.GraphSetting.radiusrefer:
				self.bottomright.append(key)
			if distance_bottomleft <= self.GraphSetting.radiusrefer:
				self.bottomleft.append(key)


		self.total_list.append(self.topleft)
		self.total_list.append(self.bottomleft)
		self.total_list.append(self.topright)
		self.total_list.append(self.bottomright)






		if init:
			self.initial_reward_random(self.GraphSetting.reward_numbers)
			self.initial_route_random(self.GraphSetting.car_numbers)





		self.junction_sub()


		
	def read(self, target_path):
		with open(target_path, "rb") as f:
			return pickle.load(f)
	def save(self, source_path, target_object):
		file_name = f"{os.path.basename(source_path).split('.')[0]}.map"
		file_dir = os.path.dirname(source_path)
		target_path = os.path.join(file_dir, file_name)
		with open(target_path, "wb") as f:
			pickle.dump(target_object, f)
			print(f"map saved to {target_path}")

	def reward_to_json(self, file_path):

		reward_dict = {obj.junction: obj.value for key, obj in self.sim_env.map_data.pois.items()}
		with open(os.path.join(file_path, "reward.json"), "w") as f:
			json.dump(reward_dict, f)


	



	def initial_route_random(self, amount, return_dicts=False, min_dist=False):

		logging.info(f"Initializing routes for {self.algo} sim {self.sim_number}")



		self.route_dict = {}
		self.veh_dict = {}

		start_junct_list = []
		for x in self.GraphSetting.startindex:
			start_junct_list.extend(self.total_list[x])

		end_junct_list = []
		for x in self.GraphSetting.endindex:
			end_junct_list.extend(self.total_list[x])

		index_amount_dict = {} #the given index how many routes is needed from it

		for x in set(self.GraphSetting.endindex):
			index_amount_dict[x] = round((self.GraphSetting.endindex.count(x) / len(self.GraphSetting.endindex)) * amount)

		print("number of routes to generate ", index_amount_dict)

		list_juncts = list(self.sim_env.map_data.junctions)

		dict_players = {}

		i = 0

		#min_dist_value = 0 #if we want all the routes to have similar to the min route distnace
		route_dist_index = defaultdict(list) #{id:[dist]}

		for key, route_amount in index_amount_dict.items():
			for _ in range(route_amount):
				veh_id = 'veh_'+str(i)
				route_id = 'route_'+str(i)

				#print(f"vehicle {i} ending index is {key}")
				
				while True:
					try:
						if key == 0:
							start = choice(self.total_list[1])
						else:	
							start = choice(start_junct_list)
						end = choice(self.total_list[key])
						#end = self.GraphSetting.destination

						if start == end:
							continue

						route = self.sim_env.map_data.find_best_route(start, end)

						if not route.edges:
							continue

						if min_dist:
							#populate routedistindex
							total_dist = 0
							for edge in route.edges:
								total_dist += self.sim_env.map_data.edges[edge]._distance
								route_dist_index[i].append(total_dist)


						break
					except traci.exceptions.TraCIException:
						continue
					except Exception as e:
						logging.debug(f"Failed addinv vehicle {veh_id}")
						continue

				route_edges = route.edges

				dict_players[i] = route_edges
				i += 1
				if return_dicts:
					continue

				try:

					traci.route.add(route_id, route_edges)
					traci.vehicle.add(veh_id, route_id,departLane='random')


					self.route_dict[route_id] = route_edges
					self.veh_dict[veh_id] = route_id

				except traci.exceptions.TraCIException:
					assert True, f"FAILED TO ADD ROUTE {veh_id}, edges:{route_edges}"



				self.sim_env.add_player(veh_id, route, end)
		

		if return_dicts:
			if min_dist:
				#find the shortest route and make every other one the same
				dist_dict = {key:value[-1] for key, value in route_dist_index.items()}
				min_route_id = min(dist_dict, key=dist_dict.get)
				print(f"Route {min_route_id} is the shortest route, with {route_dist_index[min_route_id][-1]}")

				for key, value in route_dist_index.items():
					if key == min_route_id:
						continue
					dict_players[key] = dict_players[key][:np.argmax(np.array(value) > route_dist_index[min_route_id][-1])]


			return dict_players

		#after all vehicles added
		#if self.sim_env.algo == "ATNE":

		if self.sim_env.algo != "BASE":
			self.sim_env.set_combinations(add=True) #initially set vehicle destination
		#self.sim_env.set_combinations_new(add=True)
		#combination is called after all players are added

		logging.info(f"Players added total {amount} in inital no mainenv")

		self.global_player_list = copy.deepcopy(self.sim_env.player_list)

		



	def change_capacity(self): #change the capacity of global player list

		for veh_id, veh_value in self.global_player_list.items():
			self.global_player_list[veh_id].capacity = get_truncated_normal(self.GraphSetting.player_capacity_random[0], self.GraphSetting.player_capacity_random[1], 0, self.GraphSetting.player_capacity_random[0]*2).rvs(1)[0]
			logging.info(f"resetting capacity values {veh_id} {self.global_player_list[veh_id].capacity}")

	def change_distance_capacity(self):
		for veh_id, veh_value in self.global_player_list.items():

			try:

				if self.GraphSetting.distance_capacity[0] == self.GraphSetting.distance_capacity[1]:
					self.global_player_list[veh_id].distance_capacity = (self.GraphSetting.distance_capacity[0] * self.global_player_list[veh_id].base_travel_time)


				else:
					self.global_player_list[veh_id].distance_capacity = np.random.randint(self.global_player_list[veh_id].base_travel_time * self.GraphSetting.distance_capacity[0], self.global_player_list[veh_id].base_travel_time * self.GraphSetting.distance_capacity[1])
			except ValueError:
				self.global_player_list[veh_id].distance_capacity = 0





	def initial_reward_random(self, amount): #initialize all the rewards

		#traci.junction.subscribeContext(GraphSetting.destination, tc.CMD_GET_VEHICLE_VARIABLE, 20, [tc.VAR_EDGES, tc.VAR_ROAD_ID])

		if not self.main_env:

			all_junctions = list(self.sim_env.map_data.junctions.keys())

			for i in range(amount):

				id_value = f'poi_{str(i)}'
				junction=choice(all_junctions)

				self.sim_env.map_data.pois[id_value] = Poi(junction, \
					get_truncated_normal(self.GraphSetting.player_reward_random[0], self.GraphSetting.player_reward_random[1], 0, self.GraphSetting.player_reward_random[0]*2).rvs(1)[0]) #add poi to dict with poi id as key

				#self.sim_env.poi_que[id_value] = {}
				self.sim_env.poi_list[id_value]= {}
				self.sim_env.poi_to_junct[id_value] = junction
				self.sim_env.poi_to_junct[junction] = id_value

				traci.poi.add(id_value, *traci.junction.getPosition(junction), color=(255,0,255,255), layer=10, height=10)
				#print(tuple(*traci.junction.getPosition(junction)))

				#Visualize.polygon(traci.junction.getPosition(junction), (255,0,255,255), 30)


				traci.poi.subscribeContext(id_value, tc.CMD_GET_VEHICLE_VARIABLE, self.GraphSetting.poi_radius, [tc.VAR_EDGES, tc.VAR_ROAD_ID])
				print(f'added {id_value} to location {junction}')

			self.global_poi = copy.deepcopy(self.sim_env.map_data.pois)

		else:
			#for when prev poi is set up
			for key, obj in self.main_env.global_poi.items():

				junction = obj.junction
				id_value = key


				self.sim_env.map_data.pois[id_value] = Poi(junction, obj.value) #add poi to dict with poi id as key

				#self.sim_env.poi_que[id_value] = {}
				self.sim_env.poi_list[id_value]= {}
				self.sim_env.poi_to_junct[key] = junction
				self.sim_env.poi_to_junct[junction] = id_value

				traci.poi.add(id_value, *traci.junction.getPosition(junction), color=(255,0,255,255), layer=10, height=10)
				#print(tuple(*traci.junction.getPosition(junction)))

				#Visualize.polygon(traci.junction.getPosition(junction), (255,0,255,255), 30)


				traci.poi.subscribeContext(id_value, tc.CMD_GET_VEHICLE_VARIABLE, self.GraphSetting.poi_radius, [tc.VAR_EDGES, tc.VAR_ROAD_ID])
				print(f'added {id_value} to location {junction}')


		self.sim_env.post_process_graph.reward_list =  self.sim_env.map_data.pois


	def step(self, t=0):
		#action performed after each step aka simulation step

		self.vehicle_sub() #constant sub to veh to handle veh being added during simulation
		self.break_condition = self.populate_post() #for populating post processing data, and set break condition to get when all vehicle arrives
		self.sim_env.process_poi(self.t)
		self.sim_env.process_destination() #subscribe to destination of veh to make sure it arrives
		self.sim_env.stop_vehicle_handle(self.t)
		self.t+=1



		
	def populate_post(self): #for post processing and make sure vehicle all arrives
		self.sim_env.veh_data = traci.vehicle.getAllSubscriptionResults()
		if self.sim_env.veh_data:
			for veh_id, values in self.sim_env.veh_data.items():

				post_list = [self.sim_number, self.t, veh_id, values[tc.VAR_ROAD_ID], values[tc.VAR_SPEED], \
				self.sim_env.player_list[veh_id].capacity, self.sim_env.player_list[veh_id].reward, self.sim_env.player_list[veh_id].prev_poi, self.sim_env.algo]

				self.sim_env.player_list[veh_id].node_hit.append(values[tc.VAR_ROAD_ID])
				self.sim_env.player_list[veh_id].positions.append(values[tc.VAR_POSITION])
				#print(f"{veh_id} - {values[tc.VAR_POSITION]}")

				self.post_process.append_row(post_list)

			return False

		#this is when the simulation is finished
		for key, value in self.sim_env.player_list.items():
			self.sim_env.post_process_graph.player_list.append(value)

		self.sim_env.post_process_graph.simulation_steps = self.t
		self.sim_env.post_process_graph.map_junctions = len(self.sim_env.map_data.junctions) + len(self.sim_env.map_data.edges)


		#add in the total simulation step into the list of steps
		for key, value in self.sim_env.post_process_graph.temp_coverage.items():
			value.append(self.t)
			if value[0] != 0:
				value.insert(0, 0)


		
		return True








	def vehicle_sub(self):
		for veh_id in traci.vehicle.getIDList():
			traci.vehicle.subscribe(veh_id, [tc.VAR_POSITION, tc.VAR_SPEED, tc.VAR_EDGES, tc.VAR_ROUTE_INDEX,tc.VAR_ROAD_ID])


	def junction_sub(self):
		len_junction = 0
		for junc, junc_obj in self.sim_env.map_data.junctions.items():
			if not ':' in junc:
				dist_from_junc = EnvironmentListener.mean([self.sim_env.map_data.edges[x].distance for x in junc_obj.adjacent_edges_from])
				if dist_from_junc:
					#traci subscribe need to convert miles to meters
					try:
						traci.junction.subscribeContext(junc, tc.CMD_GET_VEHICLE_VARIABLE, (dist_from_junc/4)*1609.34, [tc.VAR_EDGES, tc.VAR_ROAD_ID])
						len_junction+=1

					except Exception as e:
						pass

		#print('len junctions sub to ', len_junction) #show number of junc sub to



	@staticmethod
	def mean(list_value):
		if len(list_value) == 0:
			return
		return sum(list_value)/len(list_value)
예제 #2
0
class EnvironmentListener(traci.StepListener):
    def __init__(self):
        super(EnvironmentListener, self).__init__()
        self.sim_env = Environment()

        self.initial_reward_random(GraphSetting.reward_numbers)
        self.initial_route_random(GraphSetting.car_numbers)

        self.junction_sub()

    def initial_route_random(self, amount):

        list_edges = list(self.sim_env.map_data.edges)
        list_juncts = list(self.sim_env.map_data.junctions)
        for i in range(amount):
            veh_id = 'veh_' + str(i)
            route_id = 'route_' + str(i)
            #traci.route.add(route_id, [choice(list_edges) for _ in range(2)])
            #traci.route.add(route_id, [choice(list_edges), '-cell0_0N'])
            end = GraphSetting.destination
            start = choice(list_juncts)
            while start == end:
                start = choice(list_juncts)
            traci.route.add(
                route_id,
                self.sim_env.map_data.find_best_route(start, end).edges)
            traci.vehicle.add(veh_id,
                              route_id,
                              typeID='chevy_s10',
                              departLane='random')
            route = traci.route.getEdges(route_id)
            self.sim_env.add_player(veh_id, route, end)

    def initial_reward_random(self, amount, value=100):
        for i in range(amount):

            id_value = f'poi_{str(i)}'
            junction = choice(list(self.sim_env.map_data.junctions.keys()))

            self.sim_env.rewards_list[
                junction] = value  #reward list is inters of junctions
            self.sim_env.poi_list[id_value] = {}
            self.sim_env.poi_to_junct[id_value] = junction
            traci.poi.add(id_value,
                          *traci.junction.getPosition(junction),
                          color=(255, 255, 255, 0),
                          layer=10,
                          height=10)
            traci.poi.subscribeContext(id_value, tc.CMD_GET_VEHICLE_VARIABLE,
                                       50, [tc.VAR_EDGES, tc.VAR_ROAD_ID])
            print(f'added {id_value} to location {junction}')

    def step(self, t=0):
        #action performed after each step

        self.vehicle_sub()
        #self.sim_env.process_junction()
        self.sim_env.process_poi()

    def vehicle_sub(self):
        for veh_id in traci.vehicle.getIDList():
            traci.vehicle.subscribe(veh_id, [
                tc.VAR_POSITION, tc.VAR_SPEED, tc.VAR_EDGES,
                tc.VAR_ROUTE_INDEX, tc.VAR_ROAD_ID
            ])

    def junction_sub(self):
        len_junction = 0
        for junc, junc_obj in self.sim_env.map_data.junctions.items():
            if not ':' in junc:
                dist_from_junc = EnvironmentListener.mean([
                    self.sim_env.map_data.edges[x].distance
                    for x in junc_obj.adjacent_edges_from
                ])
                if dist_from_junc:
                    #traci subscribe need to convert miles to meters
                    traci.junction.subscribeContext(
                        junc, tc.CMD_GET_VEHICLE_VARIABLE,
                        (dist_from_junc / 4) * 1609.34,
                        [tc.VAR_EDGES, tc.VAR_ROAD_ID])
                    len_junction += 1
        print('len junctions sub to ', len_junction)

    @staticmethod
    def mean(list_value):
        if len(list_value) == 0:
            return
        return sum(list_value) / len(list_value)
예제 #3
0
class EnvironmentListener(traci.StepListener):
    def __init__(self, sim_number, init=True, _seed=None, ATNE=True):
        super(EnvironmentListener, self).__init__()
        seed(_seed)

        self.ATNE = ATNE

        self.sim_number = sim_number

        self.post_process = PostGraph(self.sim_number,
                                      columns=[
                                          "sim_number", "sim_step", "veh_id",
                                          "edge_id", "speed", "capacity",
                                          "budget", "prev_poi"
                                      ])
        self.t = 0

        self.break_condition = False  #condition to check if all vehicles has arrived

        file_dir = os.path.dirname(GraphSetting.sumo_config)
        map_list = glob.glob(os.path.join(file_dir, r"*.map"))
        try:
            self.sim_env = self.read(map_list[0])
            print(f"loaded map from {map_list[0]}")
        except IndexError:
            print(f".map file generating for {GraphSetting.sumo_config}")
            self.sim_env = Environment()
            self.save(GraphSetting.sumo_config, self.sim_env)

        if init:

            self.initial_reward_random(GraphSetting.reward_numbers)
            self.initial_route_random(GraphSetting.car_numbers)
            self.junction_sub()

    def read(self, target_path):
        with open(target_path, "rb") as f:
            return pickle.load(f)

    def save(self, source_path, target_object):
        file_name = f"{os.path.basename(source_path).split('.')[0]}.map"
        file_dir = os.path.dirname(source_path)
        target_path = os.path.join(file_dir, file_name)
        with open(target_path, "wb") as f:
            pickle.dump(target_object, f)
            print(f"map saved to {target_path}")

    def initial_route_random(self, amount, seed=None):

        list_edges = list(self.sim_env.map_data.edges)
        list_juncts = list(self.sim_env.map_data.junctions)

        for i in range(amount):
            veh_id = 'veh_' + str(i)
            route_id = 'route_' + str(i)
            #traci.route.add(route_id, [choice(list_edges) for _ in range(2)])
            #traci.route.add(route_id, [choice(list_edges), '-cell0_0N'])

            while True:
                try:
                    start = choice(list_juncts)
                    end = GraphSetting.destination
                    if GraphSetting.destination == "random":
                        end = choice(list_juncts)

                    if start == end:
                        continue

                    route = self.sim_env.map_data.find_best_route(start, end)

                    if not route.edges:
                        continue

                    break
                except traci.exceptions.TraCIException:
                    continue

            route_edges = route.edges

            try:

                traci.route.add(route_id, route_edges)
                traci.vehicle.add(veh_id, route_id, departLane='random')

            except traci.exceptions.TraCIException:
                assert True, f"FAILED TO ADD ROUTE {veh_id}, edges:{route_edges}"

            self.sim_env.add_player(veh_id, route, end)

        #after all vehicles added
        if self.ATNE:
            self.sim_env.set_combinations(add=True)
            #self.sim_env.set_combinations_new(add=True)
            #combination is called after all players are added

    def initial_reward_random(self, amount):  #initialize all the rewards

        #traci.junction.subscribeContext(GraphSetting.destination, tc.CMD_GET_VEHICLE_VARIABLE, 20, [tc.VAR_EDGES, tc.VAR_ROAD_ID])

        all_junctions = list(self.sim_env.map_data.junctions.keys())

        for i in range(amount):

            id_value = f'poi_{str(i)}'
            junction = choice(all_junctions)

            self.sim_env.map_data.pois[id_value] = Poi(junction, \
             get_truncated_normal(GraphSetting.player_reward_random[0], GraphSetting.player_reward_random[1], 0, GraphSetting.player_reward_random[0]*2).rvs(1)[0]) #add poi to dict with poi id as key

            #self.sim_env.poi_que[id_value] = {}
            self.sim_env.poi_list[id_value] = {}
            self.sim_env.poi_to_junct[id_value] = junction
            self.sim_env.poi_to_junct[junction] = id_value

            traci.poi.add(id_value,
                          *traci.junction.getPosition(junction),
                          color=(255, 0, 255, 255),
                          layer=10,
                          height=10)
            #print(tuple(*traci.junction.getPosition(junction)))

            #Visualize.polygon(traci.junction.getPosition(junction), (255,0,255,255), 30)

            traci.poi.subscribeContext(id_value, tc.CMD_GET_VEHICLE_VARIABLE,
                                       GraphSetting.poi_radius,
                                       [tc.VAR_EDGES, tc.VAR_ROAD_ID])
            print(f'added {id_value} to location {junction}')

    def step(self, t=0):
        #action performed after each step aka simulation step

        self.vehicle_sub(
        )  #constant sub to veh to handle veh being added during simulation
        self.break_condition = self.populate_post(
        )  #for populating post processing data, and set break condition to get when all vehicle arrives
        self.sim_env.process_poi()
        self.sim_env.process_destination(
        )  #subscribe to destination of veh to make sure it arrives
        self.sim_env.stop_vehicle_handle(self.t)
        self.t += 1

    def populate_post(
            self):  #for post processing and make sure vehicle all arrives
        self.sim_env.veh_data = traci.vehicle.getAllSubscriptionResults()
        if self.sim_env.veh_data:
            for veh_id, values in self.sim_env.veh_data.items():

                post_list = [self.sim_number, self.t, veh_id, values[tc.VAR_ROAD_ID], values[tc.VAR_SPEED], \
                self.sim_env.player_list[veh_id].capacity, self.sim_env.player_list[veh_id].reward, self.sim_env.player_list[veh_id].prev_poi\
                ]

                self.post_process.append_row(post_list)

            return False

        return True

    def vehicle_sub(self):
        for veh_id in traci.vehicle.getIDList():
            traci.vehicle.subscribe(veh_id, [
                tc.VAR_POSITION, tc.VAR_SPEED, tc.VAR_EDGES,
                tc.VAR_ROUTE_INDEX, tc.VAR_ROAD_ID
            ])

    def junction_sub(self):
        len_junction = 0
        for junc, junc_obj in self.sim_env.map_data.junctions.items():
            if not ':' in junc:
                dist_from_junc = EnvironmentListener.mean([
                    self.sim_env.map_data.edges[x].distance
                    for x in junc_obj.adjacent_edges_from
                ])
                if dist_from_junc:
                    #traci subscribe need to convert miles to meters
                    traci.junction.subscribeContext(
                        junc, tc.CMD_GET_VEHICLE_VARIABLE,
                        (dist_from_junc / 4) * 1609.34,
                        [tc.VAR_EDGES, tc.VAR_ROAD_ID])
                    len_junction += 1
        #print('len junctions sub to ', len_junction) #show number of junc sub to

    @staticmethod
    def mean(list_value):
        if len(list_value) == 0:
            return
        return sum(list_value) / len(list_value)