Skip to content

Commit

Permalink
Merge f29680e into d1688c6
Browse files Browse the repository at this point in the history
  • Loading branch information
kanaadp committed Mar 19, 2020
2 parents d1688c6 + f29680e commit e707a73
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 155 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -42,7 +42,7 @@ before_install:

# [sumo] dependencies and binaries
- pushd $HOME/build/flow-project
- ./flow/scripts/setup_sumo_ubuntu1604.sh
- ./flow/scripts/setup_libsumo_ubuntu.sh
- popd
- source ~/.bashrc

Expand Down
11 changes: 11 additions & 0 deletions examples/simulate.py
Expand Up @@ -45,13 +45,19 @@ def parse_args(args):
action='store_true',
help='Specifies whether to generate an emission file from the '
'simulation.')
parser.add_argument(
'--libsumo',
action='store_true',
help='Whether to run with libsumo')

return parser.parse_known_args(args)[0]


if __name__ == "__main__":
flags = parse_args(sys.argv[1:])

assert not (flags.libsumo and flags.aimsun), "Cannot enable both libsumo and aimsun!"

# Get the flow_params object.
module = __import__("exp_configs.non_rl", fromlist=[flags.exp_config])
flow_params = getattr(module, flags.exp_config).flow_params
Expand All @@ -64,6 +70,11 @@ def parse_args(args):

# Update some variables based on inputs.
flow_params['sim'].render = not flags.no_render
if flags.libsumo:
print("Running with libsumo! Make sure you have it installed!")
import libsumo
assert libsumo.isLibsumo(), "Failed to load libsumo"
flow_params['sim'].use_libsumo = flags.libsumo
flow_params['simulator'] = 'aimsun' if flags.aimsun else 'traci'

# Specify an emission path if they are meant to be generated.
Expand Down
13 changes: 11 additions & 2 deletions examples/train.py
Expand Up @@ -68,6 +68,9 @@ def parse_args(args):
parser.add_argument(
'--checkpoint_path', type=str, default=None,
help='Directory with checkpoint to restore training from.')
parser.add_argument(
'--libsumo',
action='store_true', help='Whether to run with libsumo')

return parser.parse_known_args(args)[0]

Expand Down Expand Up @@ -189,8 +192,15 @@ def setup_exps_rllib(flow_params,
"RLlib. Try running this experiment using RLlib: 'python train.py EXP_CONFIG'"
else:
assert False, "Unable to find experiment config!"

flow_params = submodule.flow_params
if flags.libsumo:
print("Running with libsumo! Make sure you have it installed!")
import libsumo
assert libsumo.isLibsumo(), "Failed to load libsumo"
flow_params['sim'].use_libsumo = flags.libsumo

if flags.rl_trainer.lower() == "rllib":
flow_params = submodule.flow_params
n_cpus = submodule.N_CPUS
n_rollouts = submodule.N_ROLLOUTS
policy_graphs = getattr(submodule, "POLICY_GRAPHS", None)
Expand Down Expand Up @@ -221,7 +231,6 @@ def setup_exps_rllib(flow_params,
trials = run_experiments({flow_params["exp_tag"]: exp_config})

elif flags.rl_trainer == "Stable-Baselines":
flow_params = submodule.flow_params
# Path to the saved files
exp_tag = flow_params['exp_tag']
result_name = '{}/{}'.format(exp_tag, strftime("%Y-%m-%d-%H:%M:%S"))
Expand Down
47 changes: 44 additions & 3 deletions flow/core/kernel/network/traci.py
Expand Up @@ -804,9 +804,50 @@ def generate_cfg(self, net_params, traffic_lights, routes):
add=self.addfn,
rou=self.roufn,
gui=self.guifn))
t = E('time')
t.append(E('begin', value=repr(0)))
cfg.append(t)

# initial time of the simulation
cfg.append(E('begin', value=repr(0)))

# simulation step length
cfg.append(E('step-length', value=repr(self.sim_params.sim_step)))

# add the lateral resolution of the sublanes (if requested)
if self.sim_params.lateral_resolution is not None:
cfg.append(E("lateral-resolution",
value=str(self.sim_params.lateral_resolution)))

# use a ballistic integration step (if request)
if self.sim_params.use_ballistic:
cfg.append(E("step-method.ballistic", value="true"))

# add the emission path to the sumo command (if requested)
if self.sim_params.emission_path is not None:
ensure_dir(self.sim_params.emission_path)
emission_out = os.path.join(
os.path.abspath(self.sim_params.emission_path),
"{}-emission.xml".format(self.network.name))
cfg.append(E("emission-output", value=emission_out))

# add step logs (if requested)
no_step_log = "true" if self.sim_params.no_step_log else "false"
cfg.append(E("no-step-log", value=no_step_log))

if self.sim_params.overtake_right:
cfg.append(E("lanechange.overtake-right", value="true"))

# specify a simulation seed (if requested)
if self.sim_params.seed is not None:
cfg.append(E("seed", value=str(self.sim_params.seed)))

if not self.sim_params.print_warnings:
cfg.append(E("no-warnings", value="true"))

# set the time it takes for a gridlock teleport to occur
cfg.append(E("time-to-teleport",
value=str(int(self.sim_params.teleport_time))))

# check collisions at intersections
cfg.append(E("collision.check-junctions", value="true"))

printxml(cfg, self.cfg_path + self.sumfn)
return self.sumfn
Expand Down
98 changes: 32 additions & 66 deletions flow/core/kernel/simulation/traci.py
@@ -1,7 +1,6 @@
"""Script containing the TraCI simulation kernel class."""

from flow.core.kernel.simulation import KernelSimulation
from flow.core.util import ensure_dir
import flow.config as config
import traci.constants as tc
import traci
Expand Down Expand Up @@ -84,83 +83,48 @@ def start_simulation(self, network, sim_params):
else "sumo"

# command used to start sumo
sumo_call = [
sumo_binary, "-c", network.cfg,
sumo_call = [sumo_binary, "-c", network.cfg]
sumo_call_params = [
"--remote-port", str(sim_params.port),
"--num-clients", str(sim_params.num_clients),
"--step-length", str(sim_params.sim_step)
]

# use a ballistic integration step (if request)
if sim_params.use_ballistic:
sumo_call.append("--step-method.ballistic")

# add step logs (if requested)
if sim_params.no_step_log:
sumo_call.append("--no-step-log")

# add the lateral resolution of the sublanes (if requested)
if sim_params.lateral_resolution is not None:
sumo_call.append("--lateral-resolution")
sumo_call.append(str(sim_params.lateral_resolution))

# add the emission path to the sumo command (if requested)
if sim_params.emission_path is not None:
ensure_dir(sim_params.emission_path)
emission_out = os.path.join(
sim_params.emission_path,
"{0}-emission.xml".format(network.name))
sumo_call.append("--emission-output")
sumo_call.append(emission_out)
else:
emission_out = None

if sim_params.overtake_right:
sumo_call.append("--lanechange.overtake-right")
sumo_call.append("true")

# specify a simulation seed (if requested)
if sim_params.seed is not None:
sumo_call.append("--seed")
sumo_call.append(str(sim_params.seed))

if not sim_params.print_warnings:
sumo_call.append("--no-warnings")
sumo_call.append("true")

# set the time it takes for a gridlock teleport to occur
sumo_call.append("--time-to-teleport")
sumo_call.append(str(int(sim_params.teleport_time)))

# check collisions at intersections
sumo_call.append("--collision.check-junctions")
sumo_call.append("true")

logging.info(" Starting SUMO on port " + str(port))
logging.debug(" Cfg file: " + str(network.cfg))
if sim_params.num_clients > 1:
logging.info(" Num clients are" +
str(sim_params.num_clients))
logging.debug(" Emission file: " + str(emission_out))
logging.debug(" Step length: " + str(sim_params.sim_step))

# Opening the I/O thread to SUMO
self.sumo_proc = subprocess.Popen(
sumo_call,
stdout=subprocess.DEVNULL,
preexec_fn=os.setsid
)

# wait a small period of time for the subprocess to activate
# before trying to connect with traci
if os.environ.get("TEST_FLAG", 0):
time.sleep(0.1)
try:
use_libsumo = sim_params.use_libsumo
except AttributeError:
use_libsumo = False

if sim_params.render or not use_libsumo:
# Opening the I/O thread to SUMO
self.sumo_proc = subprocess.Popen(
sumo_call + sumo_call_params, preexec_fn=os.setsid)

# wait a small period of time for the subprocess to
# activate before trying to connect with traci
if os.environ.get("TEST_FLAG", 0):
time.sleep(0.1)
else:
time.sleep(config.SUMO_SLEEP)

traci_connection = traci.connect(port, numRetries=100)
traci_connection.setOrder(0)
traci_connection.simulationStep()
else:
time.sleep(config.SUMO_SLEEP)
import libsumo

# Use libsumo to create a simulation instance.
libsumo.start(sumo_call)
libsumo.simulationStep()

traci_connection = traci.connect(port, numRetries=100)
traci_connection.setOrder(0)
traci_connection.simulationStep()
# libsumo will act as the kernel API
traci_connection = libsumo

return traci_connection
except Exception as e:
Expand All @@ -172,6 +136,8 @@ def start_simulation(self, network, sim_params):
def teardown_sumo(self):
"""Kill the sumo subprocess instance."""
try:
os.killpg(self.sumo_proc.pid, signal.SIGTERM)
# In case not using libsumo, kill the process.
if self.sumo_proc is not None:
os.killpg(self.sumo_proc.pid, signal.SIGTERM)
except Exception as e:
print("Error during teardown: {}".format(e))
34 changes: 27 additions & 7 deletions flow/core/kernel/traffic_light/traci.py
Expand Up @@ -2,6 +2,7 @@

from flow.core.kernel.traffic_light import KernelTrafficLight
import traci.constants as tc
from traci.exceptions import FatalTraCIError, TraCIException


class TraCITrafficLight(KernelTrafficLight):
Expand Down Expand Up @@ -43,17 +44,22 @@ def pass_api(self, kernel_api):
# number of traffic light nodes
self.num_traffic_lights = len(self.__ids)

# subscribe the traffic light signal data
for node_id in self.__ids:
self.kernel_api.trafficlight.subscribe(
node_id, [tc.TL_RED_YELLOW_GREEN_STATE])
if self.master_kernel.vehicle.render:
# subscribe the traffic light signal data
for node_id in self.__ids:
self.kernel_api.trafficlight.subscribe(
node_id, [tc.TL_RED_YELLOW_GREEN_STATE])

def update(self, reset):
"""See parent class."""
tls_obs = {}
for tl_id in self.__ids:
tls_obs[tl_id] = \
self.kernel_api.trafficlight.getSubscriptionResults(tl_id)
if self.master_kernel.vehicle.render:
for tl_id in self.__ids:
tls_obs[tl_id] = \
self.kernel_api.trafficlight.getSubscriptionResults(tl_id)
else:
for tl_id in self.__ids:
tls_obs[tl_id] = self._get_libsumo_subscription_results(tl_id)
self.__tls = tls_obs.copy()

def get_ids(self):
Expand All @@ -74,3 +80,17 @@ def set_state(self, node_id, state, link_index="all"):
def get_state(self, node_id):
"""See parent class."""
return self.__tls[node_id][tc.TL_RED_YELLOW_GREEN_STATE]

def _get_libsumo_subscription_results(self, tl_id):
"""Create a traci-style subscription result in the case of libsumo."""
try:
res = {
tc.TL_RED_YELLOW_GREEN_STATE:
self.kernel_api.trafficlight.getRedYellowGreenState(tl_id)
}
except (TraCIException, FatalTraCIError):
# This is in case a vehicle exited the network and has not been
# unscubscribed yet.
res = None

return res
16 changes: 0 additions & 16 deletions flow/core/kernel/vehicle/base.py
Expand Up @@ -306,22 +306,6 @@ def get_speed(self, veh_id, error=-1001):
"""
raise NotImplementedError

def get_default_speed(self, veh_id, error=-1001):
"""Return the expected speed if no control were applied.
Parameters
----------
veh_id : str or list of str
vehicle id, or list of vehicle ids
error : any, optional
value that is returned if the vehicle is not found
Returns
-------
float
"""
raise NotImplementedError

def get_position(self, veh_id, error=-1001):
"""Return the position of the vehicle relative to its current edge.
Expand Down

0 comments on commit e707a73

Please sign in to comment.