Skip to content

Commit

Permalink
reset, loading vehicles, equal spacing
Browse files Browse the repository at this point in the history
  • Loading branch information
kanaadp committed Feb 7, 2017
1 parent c8dbb8f commit 20112e3
Show file tree
Hide file tree
Showing 48 changed files with 351 additions and 9,592 deletions.
56 changes: 21 additions & 35 deletions cistar-dev/build-tester.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,49 @@
import logging

from cistar.envs.velocity import SimpleVelocityEnvironment
from cistar.core.exp import SumoExperiment
from rllab.envs.base import Env

from cistar.generators.loop import CircleGenerator

from cistar.envs.velocity import SimpleVelocityEnvironment
from cistar.scenarios.loop.gen import CircleGenerator
from cistar.scenarios.loop.loop_scenario import LoopScenario
logging.basicConfig(level=logging.WARNING)

num_cars = 4

num_rl = 4
num_cars = 10
num_rl = 5

sumo_params = {"port": 8873}

def constant_vel(**kwargs):
return 15
sumo_binary = "sumo-gui"

type_controllers = {"rl": None}

type_counts = {"rl": num_rl}
type_params = {"rl": (num_rl, None), "slow": (5, constant_vel)}

env_params = {"target_velocity": 25}

initial_config = {}

net_params = {"length": 200, "lanes": 1, "speed_limit":35, "resolution": 40, "net_path":"debug/net/"}

type_list=["rl"]
cfg_params = {"type_list": ["rl"], "start_time": 0, "end_time":3000, "cfg_path":"debug/cfg/", "num_cars":num_cars, "type_counts":{"rl": 4}, "use_flows":True, "period":"1"}

scenario = LoopScenario("test-exp", num_cars, type_params, cfg_params, net_params, generator_class=CircleGenerator)

##data path needs to be relative to cfg location
cfg_params = {"type_list": ["rl"], "start_time": 0, "num_cars":num_cars, "end_time":3000, "cfg_path":"debug/cfg/", "type_counts":type_counts, "use_flows":True, "period":"1"}

leah_sumo_params = {"port": 8873}#, "cfg":"/Users/kanaad/code/research/learning-traffic/sumo/learning-traffic/cistar-dev/debug/cfg/test-exp-200m1l.sumo.cfg"}
leah_sumo_params = {"port": 8873}

exp = SumoExperiment("test-exp", SimpleVelocityEnvironment, env_params, num_cars, num_rl, type_controllers, sumo_binary, leah_sumo_params, initial_config, CircleGenerator, net_params, cfg_params)
exp = SumoExperiment(SimpleVelocityEnvironment, env_params, sumo_binary, sumo_params, scenario)

logging.info("Experiment Set Up complete")

for _ in range(50):
exp.env.step([25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25])
exp.env.step([25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25])
exp.env.reset()
for _ in range(20):
exp.env.step([15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15])
exp.env.step(
[25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25])
exp.env.reset()
for _ in range(10):
exp.env.step([25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25])

# print("resetting state")
# exp.env.reset()
# print("state reset")
# for _ in range(20):
# exp.env.step([0,0,0,0])
# print("resetting state")
# exp.env.reset()
# print("state reset")
# for _ in range(10):
# exp.env.step([20,20,20,20])
# for _ in range(30):
# exp.env.step([25, 25, 25, 25])
# print("resetting state")
# exp.env.reset()
exp.env.step(
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15])

exp.env.terminate()
92 changes: 43 additions & 49 deletions cistar-dev/cistar/core/base_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@

class SumoEnvironment(Env):

def __init__(self, num_vehicles, num_rl_vehicles, env_params,
type_controllers, sumo_binary, sumo_params, initial_config):
def __init__(self,env_params, type_params, sumo_binary, sumo_params, scenario):
"""
Initialize the Sumo Environment, by starting SUMO, setting up TraCI and initializing vehicles
Input
-----
num_vehicles : total number of vehicles, RL and controller based
env_params : use this dictionary to pass in parameters relevant to the environment
(i.e. shape, size of simulatiomn; constants for step functions, etc. )
vehicle_controllers : dictionary of car -> controller assignments for non-RL cars
type_params : dictionary of car -> (count, controller) assignments
sumo_binary : SUMO library to start
sumo_params : port, config file, out, error etc.
Expand All @@ -47,20 +46,19 @@ def __init__(self, num_vehicles, num_rl_vehicles, env_params,
info : a dictionary containing other diagnostic information from the previous action
"""

self.num_vehicles = num_vehicles
self.num_rl_vehicles = num_rl_vehicles
self.num_vehicles = scenario.num_vehicles
self.num_rl_vehicles = scenario.num_rl_vehicles
self.env_params = env_params
self.type_controllers = type_controllers
self.type_params = type_params
self.sumo_binary = sumo_binary
self.initial_config = initial_config
self.initial_state = {}

if "port" not in sumo_params:
raise logging.error("SUMO port not defined")
raise ValueError("SUMO port not defined")
else:
self.port = sumo_params["port"]

self.cfg = sumo_params['cfg']

self.cfg = scenario.cfg

# (could cause error, port occupied, should catch for exception)
# TODO: Catch sumo/traci errors
Expand All @@ -71,24 +69,24 @@ def __init__(self, num_vehicles, num_rl_vehicles, env_params,
subprocess.Popen([self.sumo_binary, "-c", self.cfg, "--remote-port",
str(self.port), "--step-length", str(0.1)], stdout=sys.stdout, stderr=sys.stderr)

logging.info(" Initializing TraCI on port " + str(self.port) + "!")
logging.debug(" Initializing TraCI on port " + str(self.port) + "!")
traci.init(self.port)

# may have to manually add cars here
self.initialize_simulation()

self.ids = traci.vehicle.getIDList()
self.controlled_ids = [i for i in self.ids if not traci.vehicle.getTypeID(i) == "rl"]
self.rl_ids = [i for i in self.ids if traci.vehicle.getTypeID(i) == "rl"]

for index, car_id in enumerate(self.rl_ids):
logging.info("Car with id " + car_id + " is on route " + str(traci.vehicle.getRouteID(car_id)))
logging.info("Car with id " + car_id + " is on edge " + str(traci.vehicle.getLaneID(car_id)))
logging.info("Car with id " + car_id + " has valid route: " + str(traci.vehicle.isRouteValid(car_id)))
logging.info("Car with id " + car_id + " has speed: " + str(traci.vehicle.getSpeed(car_id)))
logging.info("Car with id " + car_id + " has pos: " + str(traci.vehicle.getPosition(car_id)))
logging.info("Car with id " + car_id + " has route: " + str(traci.vehicle.getRoute(car_id)))
logging.info("Car with id " + car_id + " is at index: " + str(traci.vehicle.getRouteIndex(car_id)))
for index, car_id in enumerate(self.ids):
traci.vehicle.setSpeedMode(car_id, 0)
logging.debug("Car with id " + car_id + " is on route " + str(traci.vehicle.getRouteID(car_id)))
logging.debug("Car with id " + car_id + " is on edge " + str(traci.vehicle.getLaneID(car_id)))
logging.debug("Car with id " + car_id + " has valid route: " + str(traci.vehicle.isRouteValid(car_id)))
logging.debug("Car with id " + car_id + " has speed: " + str(traci.vehicle.getSpeed(car_id)))
logging.debug("Car with id " + car_id + " has pos: " + str(traci.vehicle.getPosition(car_id)))
logging.debug("Car with id " + car_id + " has route: " + str(traci.vehicle.getRoute(car_id)))
logging.debug("Car with id " + car_id + " is at index: " + str(traci.vehicle.getRouteIndex(car_id)))

# could possibly be handled in sumo experiment
self.store_initial_state()
Expand All @@ -98,7 +96,7 @@ def initialize_simulation(self):
Needs to generate, and place cars in the correct places,
If cars are placed on routes in CFG, or generated in flows, step until all cars are on the board
(this method can be overridden, so init never needs to be)
(this method can and should be overridden for different initializations )
"""
print("there are " + str(traci.vehicle.getIDCount()) + " cars loaded")
while traci.vehicle.getIDCount() < self.num_vehicles:
Expand All @@ -114,16 +112,16 @@ def store_initial_state(self):
"""
Store initial state so that simulation can be reset at the end
"""
if not self.initial_config:
# Get initial state of each vehicle, and store in initial config object
for veh_id in self.ids:
type_id = traci.vehicle.getTypeID(veh_id)
route_id = traci.vehicle.getRouteID(veh_id)
lane_index = traci.vehicle.getLaneIndex(veh_id)
lane_pos = traci.vehicle.getLanePosition(veh_id)
speed = traci.vehicle.getSpeed(veh_id)
pos = traci.vehicle.getPosition(veh_id)
self.initial_config[veh_id] = (type_id, route_id, lane_index, lane_pos, speed, pos)

# Get initial state of each vehicle, and store in initial config object
for veh_id in self.ids:
type_id = traci.vehicle.getTypeID(veh_id)
route_id = traci.vehicle.getRouteID(veh_id)
lane_index = traci.vehicle.getLaneIndex(veh_id)
lane_pos = traci.vehicle.getLanePosition(veh_id)
speed = traci.vehicle.getSpeed(veh_id)
pos = traci.vehicle.getPosition(veh_id)
self.initial_state[veh_id] = (type_id, route_id, lane_index, lane_pos, speed, pos)

def apply_action(self, car_id, action):
"""
Expand All @@ -147,28 +145,27 @@ def step(self, rl_actions):
done : a boolean, indicating whether the episode has ended
info : a dictionary containing other diagnostic information from the previous action
"""
logging.info("================= performing step =================")
logging.debug("================= performing step =================")
for car_id in self.controlled_ids:
action = self.type_controllers[traci.vehicle.getTypeID(car_id)].get_action()
car_type = traci.vehicle.getTypeID(car_id)
action = self.type_params[car_type][1]()
self.apply_action(car_id, action=action)
logging.info("Car with id " + car_id + " is on route " + str(traci.vehicle.getRouteID(car_id)))
logging.debug("Car with id " + car_id + " is on route " + str(traci.vehicle.getRouteID(car_id)))

for index, car_id in enumerate(self.rl_ids):
action = rl_actions[index]
self.apply_action(car_id, action=action)

traci.simulationStep()

# for index, car_id in enumerate(self.rl_ids):
car_id = self.rl_ids[0]

logging.info("Car with id " + car_id + " is on route " + str(traci.vehicle.getRouteID(car_id)))
logging.info("Car with id " + car_id + " is on edge " + str(traci.vehicle.getLaneID(car_id)))
logging.info("Car with id " + car_id + " has valid route: " + str(traci.vehicle.isRouteValid(car_id)))
logging.info("Car with id " + car_id + " has speed: " + str(traci.vehicle.getSpeed(car_id)))
logging.info("Car with id " + car_id + " has pos: " + str(traci.vehicle.getPosition(car_id)))
logging.info("Car with id " + car_id + " has route: " + str(traci.vehicle.getRoute(car_id)))
logging.info("Car with id " + car_id + " is at index: " + str(traci.vehicle.getRouteIndex(car_id)))
for index, car_id in enumerate(self.rl_ids):
logging.debug("Car with id " + car_id + " is on route " + str(traci.vehicle.getRouteID(car_id)))
logging.debug("Car with id " + car_id + " is on edge " + str(traci.vehicle.getLaneID(car_id)))
logging.debug("Car with id " + car_id + " has valid route: " + str(traci.vehicle.isRouteValid(car_id)))
logging.debug("Car with id " + car_id + " has speed: " + str(traci.vehicle.getSpeed(car_id)))
logging.debug("Car with id " + car_id + " has pos: " + str(traci.vehicle.getPosition(car_id)))
logging.debug("Car with id " + car_id + " has route: " + str(traci.vehicle.getRoute(car_id)))
logging.debug("Car with id " + car_id + " is at index: " + str(traci.vehicle.getRouteIndex(car_id)))

self._state = np.array([traci.vehicle.getSpeed(vID) for vID in self.controlled_ids])
reward = self.compute_reward(self._state)
Expand All @@ -184,17 +181,15 @@ def reset(self):
"""

for car_id in self.ids:
type_id, route_id, lane_index, lane_pos, speed, pos = self.initial_config[car_id]
type_id, route_id, lane_index, lane_pos, speed, pos = self.initial_state[car_id]

print("Moving car " + car_id + " from " + str(traci.vehicle.getPosition(car_id)) + " to " + str(pos))
logging.debug("Moving car " + car_id + " from " + str(traci.vehicle.getPosition(car_id)) + " to " + str(pos))
traci.vehicle.remove(car_id)
traci.vehicle.addFull(car_id, route_id, typeID=str(type_id), departLane=str(lane_index),
departPos=str(lane_pos), departSpeed=str(speed))
traci.vehicle.setSpeedMode(car_id, 0)

traci.simulationStep()
for car_id in self.ids:
print("Car " + car_id + " from " + str(traci.vehicle.getPosition(car_id)) + " to " + str(pos))

@property
def action_space(self):
Expand All @@ -219,4 +214,3 @@ def terminate(self):
traci.close()



93 changes: 15 additions & 78 deletions cistar-dev/cistar/core/exp.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import logging
import datetime

import os
import errno
from cistar.core.generator import Generator

"""
Primary sumo++ file, imports API from supporting files and manages in teractions
Expand All @@ -15,59 +14,23 @@
Interfaces with sumo on the other side
"""


def ensure_dir(path):
try:
os.makedirs(path)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
return path


class Generator:

CFG_PATH = "./"
NET_PATH = "./"
DATA_PREFIX = "data/"

def __init__(self, net_path, cfg_path, data_prefix, base):
self.net_path = net_path
self.cfg_path = cfg_path
self.data_prefix = data_prefix
self.base = base
self.name = base
self.netfn = ""

ensure_dir("%s" % self.net_path)
ensure_dir("%s" % self.cfg_path)
ensure_dir("%s" % self.cfg_path + self.data_prefix)

def generate_net(self, params):
raise NotImplementedError

def generate_cfg(self, params):
raise NotImplementedError


class SumoExperiment():

def __init__(self, name, env_class, env_params, num_vehicles, num_rl_vehicles, type_controllers, sumo_binary, sumo_params, initial_config, file_generator=None, net_params=None,
cfg_params=None):
def __init__(self, env_class, env_params, sumo_binary, sumo_params, scenario):
"""
name : tag to associate experiment with
env_class : Environment to be initialized
num_vehicles : number of total vehicles in the simulation
num_rl_vehicles : these vehicles do not have a controller assigned to them
vehicle_params : vehicle type string -> controller (method that takes in state, returns action)
example:
num_rl_vehicles=8
num_rl_vehicles=4
num_vehicles=10
vehicle params:
'acc' -> acc_controller_fn
'human-0.5-delay' -> human-delay
'human-1.0-delay' -> human-delay
'rl' -> 8
'acc' -> (2, acc_controller_fn)
'human-0.5-delay' -> (2, human-delay)
'human-1.0-delay' -> (2,human-delay)
'rl' -> (4, None)
sumo_binary : path to sumo executable
sumo_params : parameters to pass to sumo, e.g. step-length (can also be in sumo-cfg)
Expand All @@ -77,43 +40,17 @@ def __init__(self, name, env_class, env_params, num_vehicles, num_rl_vehicles, t
cfg_params : params to be passed to the environement class upon initialization
cfg : specify a configuration, rather than create a new one
"""
self.name = name
self.num_vehicles = num_vehicles
self.num_rl_vehicles = num_rl_vehicles
self.name = scenario.name
self.num_vehicles = scenario.num_vehicles
self.env_params = env_params
self.initial_config = initial_config
self.type_controllers = type_controllers

logging.info(" Starting experiment" + str(name) + " at " + str(datetime.datetime.utcnow()))

if "cfg" not in sumo_params:
logging.info(" Config file not defined, generating using generator")
if file_generator is None:
logging.error("Invalid file generator!")
elif net_params is None:
logging.error("No network params specifed!")
elif cfg_params is None:
logging.error("No config params specified")
else:
net_path = Generator.NET_PATH
cfg_path = Generator.CFG_PATH
data_prefix = Generator.DATA_PREFIX

if "net_path" in net_params:
net_path = net_params["net_path"]
if "cfg_path" in cfg_params:
cfg_path = cfg_params["cfg_path"]
if "data_prefix" in cfg_params:
data_prefix = cfg_params["data_prefix"]
self.type_params = scenario.type_params
self.cfg = scenario.cfg

generator = file_generator(net_path, cfg_path, data_prefix, self.name)
generator.generate_net(net_params)
self.cfg, self.outs = generator.generate_cfg(cfg_params)
sumo_params['cfg'] = generator.cfg_path + self.cfg
logging.info(" Starting experiment" + str(self.name) + " at " + str(datetime.datetime.utcnow()))

logging.info("initializing enviornment.")
logging.info("initializing environment.")

self.env = env_class(self.num_vehicles, self.num_rl_vehicles, self.env_params, self.type_controllers, sumo_binary, sumo_params, initial_config)
self.env = env_class(self.env_params, self.type_params, sumo_binary, sumo_params, scenario)

def getCfg(self):
return self.cfg
Expand Down

0 comments on commit 20112e3

Please sign in to comment.