Path: blob/main/tools/contributed/sumopy/plugins/prt/prt.py
169689 views
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo1# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.2# SUMOPy module3# Copyright (C) 2012-2021 University of Bologna - DICAM4# This program and the accompanying materials are made available under the5# terms of the Eclipse Public License 2.0 which is available at6# https://www.eclipse.org/legal/epl-2.0/7# This Source Code may also be made available under the following Secondary8# Licenses when the conditions for such availability set forth in the Eclipse9# Public License 2.0 are satisfied: GNU General Public License, version 210# or later which is available at11# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html12# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later1314# @file prt.py15# @author Joerg Schweizer16# @date 20121718"""19This plugin provides methods to run and analyze PRT networks.202122"""23import os24import sys25import numpy as np26import random27from agilepy.lib_base.processes import Process28#from xml.sax import saxutils, parse, handler29from collections import OrderedDict303132from coremodules.modules_common import *33import agilepy.lib_base.classman as cm34import agilepy.lib_base.arrayman as am35import agilepy.lib_base.xmlman as xm36#from agilepy.lib_base.misc import get_inversemap37#from agilepy.lib_base.geometry import find_area38#from agilepy.lib_base.processes import Process,CmlMixin,ff,call39from coremodules.network.network import SumoIdsConf40from coremodules.network.routing import edgedijkstra, get_mincostroute_edge2edge41from coremodules.simulation import sumo42from coremodules.simulation.sumo import traci43#from coremodules.network import routing44from coremodules.demand.demandbase import DemandobjMixin45from coremodules.simulation.simulationbase import SimobjMixin4647from coremodules.demand.virtualpop import StageTypeMixin, StrategyMixin48from coremodules.simulation import results as res4950#from demo import TraciDemo5152BERTHSTATES = {'free': 0, 'waiting': 1, 'boarding': 2, 'alighting': 3}53VEHICLESTATES = {'init': 0, 'waiting': 1, 'boarding': 2, 'alighting': 3,54'emptytrip': 4, 'occupiedtrip': 5, 'forewarding': 6, 'await_forwarding': 7}55LEADVEHICLESTATES = [VEHICLESTATES['boarding'], VEHICLESTATES['waiting'],56VEHICLESTATES['emptytrip'], VEHICLESTATES['occupiedtrip']]57STOPTYPES = {'person': 0, 'freight': 1, 'depot': 2, 'group': 3, 'mixed': 4}5859get_traci_odo = traci.vehicle.getDistance60get_traci_velocity = traci.vehicle.getSpeed61get_traci_route_all = traci.vehicle.getRoute62get_traci_routeindex = traci.vehicle.getRouteIndex63get_traci_distance = traci.vehicle.getDrivingDistance646566def get_traci_route(id_veh_sumo):67return get_traci_route_all(id_veh_sumo)[get_traci_routeindex(id_veh_sumo):]686970def get_entered_vehs(ids_veh_sumo_current, ids_veh_sumo_before):71ids_veh_entered_sumo = np.array(list(ids_veh_sumo_current.difference(ids_veh_sumo_before)), dtype=np.object)72n_entered = len(ids_veh_entered_sumo)73positions = np.zeros(n_entered, dtype=np.float32)74for i, id_veh_sumo in zip(xrange(n_entered), ids_veh_entered_sumo):75positions[i] = traci.vehicle.getLanePosition(id_veh_sumo)7677return list(ids_veh_entered_sumo[positions.argsort()])[::-1]787980INF = 10.0**1081INFINT = 10**1082# def detect_entered_left(x,y):83# """84# returns the enter and left elemets of list x (before)85# and list y (after)86# """87# if len(x) == 0:88# if len(y) == 0:89# return909192class Compressors(am.ArrayObjman):93def __init__(self, ident, prtservices, **kwargs):94self._init_objman(ident=ident,95parent=prtservices,96name='Compressors',97info='Comressors try to create platoons by shunting vehicles with common destination in a common shunt edge. Contains information and methods for compressors to create platoons.',98version=0.1,99**kwargs)100self._init_attributes()101102def _init_attributes(self):103#self.add(cm.ObjConf(PrtBerths('berths',self)) )104105self.add(cm.AttrConf('time_update', 1.0,106groupnames=['parameters'],107name='Update time',108info="Simulation update time.",109unit='s',110))111112self.add(cm.AttrConf('time_accumulation_max', 29.0,113groupnames=['parameters'],114name='Maximum accumulation time',115info="Maximum accumulation time in a buffer. After this time the buffer is trying to release the vehicles.",116unit='s',117))118119self.add(cm.AttrConf('time_release_min', 40.0,120groupnames=['parameters'],121name='Minimum realease time',122info="Minimum time that must pass between successive releases.",123unit='s',124))125126net = self.get_scenario().net127128self.add_col(am.IdsArrayConf('ids_detectoredge', net.edges,129name='Detector edge ID',130info='Detector edge ID is the edge from where vehicles are deviated into the compressor.',131is_index=True,132))133134self.add_col(am.IdlistsArrayConf('ids_shuntedges', net.edges,135name='Shunt edge IDs',136info='Shunt edge IDs where PRT vehicles with common destination are sorted.',137))138139self.set_version(0.1)140141def _init_constants(self):142self.do_not_save_attrs([143'decel', 'ids_comp_to_ids_detectedge_sumo', 'queuess',144'queuess_alloc', 'capacitiess', 'ids_edge_sumo_targets',145'are_queues_avail', 'releasetimes', 'releasetimes_queues',146'length_veh',147])148149def make(self, id_detectoredge=None, **kwargs):150print 'make', kwargs151# print ' ids_shuntedge',kwargs.get('ids_shuntedge',None),type(kwargs.get('ids_shuntedge',None)[0])152id_comp = self.add_row(ids_shuntedges=kwargs.get('ids_shuntedge', None),153ids_detectoredge=id_detectoredge154)155if id_detectoredge is None:156self.update(id_comp)157return id_comp158159def update(self, id_comp):160print 'update id_comp', id_comp161edges = self.get_scenario().net.edges162163self.ids_detectoredge[id_comp] = edges.get_incoming(self.ids_shuntedges[id_comp][0])[0]164165def update_all(self):166print 'update_all'167for id_comp in self.get_ids():168self.update(id_comp)169170def get_scenario(self):171return self.parent.get_scenario()172173def prepare_sim(self, process):174print 'Compressors.prepare_sim'175net = self.get_scenario().net176nodes = net.nodes177edges = net.edges178lanes = net.lanes179ids_edge_sumo = edges.ids_sumo180181id_prtmode = self.parent.id_prtmode182self.decel = self.parent.prtvehicles.decel_emergency183184ids = self.get_ids()185186if len(ids) == 0:187return []188189n_id_max = np.max(ids)+1190191self.ids_comp_to_ids_detectedge_sumo = np.zeros(n_id_max, dtype=np.object)192self.ids_comp_to_ids_detectedge_sumo[ids] = edges.ids_sumo[self.ids_detectoredge[ids]]193194# this is list of queues for all shunt lines for each compressor195self.queuess = np.zeros(n_id_max, dtype=np.object)196197# thses queus are the same as queuess but contains the allocated, but not yet arrived vehicles198self.queuess_alloc = np.zeros(n_id_max, dtype=np.object)199200# this is list of maximum queue length for all shunt lines for each compressor201self.capacitiess = np.zeros(n_id_max, dtype=np.object)202203# list with target edges for each queue for each compressor204self.ids_edge_sumo_targets = np.zeros(n_id_max, dtype=np.object)205206# list with availabilities for each queue for each compressor207self.are_queues_avail = np.zeros(n_id_max, dtype=np.object)208209# releasetimes for each compressor210self.releasetimes = np.zeros(n_id_max, dtype=np.int32)211212# releasetimes for each queue for each compressor213self.releasetimes_queues = np.zeros(n_id_max, dtype=np.object)214215self.length_veh = self.parent.prtvehicles.get_length()216217# this queue contains all vehicles on the detect edge218# it is used to identify whether a new vehicle has left the merge219self.ids_vehs_detect_sumo = np.zeros(n_id_max, dtype=np.object)220221for id_comp, ids_shuntedge in zip(ids, self.ids_shuntedges[ids]):222# print ' id_comp',id_comp223n_shunts = len(ids_shuntedge) # first edge is not a real shunt!!224225queues = n_shunts*[None]226queues_alloc = n_shunts*[None]227capacities = n_shunts*[None]228229for i, length_edge in zip(range(n_shunts), edges.lengths[ids_shuntedge]):230capacities[i] = max(2, int((length_edge-30.0)/(self.length_veh+0.5)))231queues[i] = []232queues_alloc[i] = []233234self.queuess[id_comp] = queues235self.queuess_alloc[id_comp] = queues_alloc236self.capacitiess[id_comp] = capacities237self.ids_edge_sumo_targets[id_comp] = n_shunts*['']238self.are_queues_avail[id_comp] = n_shunts*[True]239self.releasetimes_queues[id_comp] = n_shunts*[0]240241self.ids_vehs_detect_sumo[id_comp] = set()242# print ' capacities',self.capacitiess[id_comp]243# print ' queues',self.queuess[id_comp]244245return [(self.time_update.get_value(), self.process_step),246]247248def process_step(self, process):249simtime = process.simtime250print 79*'_'251print 'Compressors.process_step at', simtime252net = self.get_scenario().net253edges = net.edges254vehicles = self.parent.prtvehicles255ids = self.get_ids()256for id_comp,\257id_detectedge_sumo,\258ids_veh_detect_sumo,\259ids_shuntedge,\260ids_edge_sumo_target,\261queues,\262queues_alloc,\263capacities,\264are_queue_avail,\265releasetime_queues\266in zip(ids,267self.ids_comp_to_ids_detectedge_sumo[ids],268self.ids_vehs_detect_sumo[ids],269self.ids_shuntedges[ids],270self.ids_edge_sumo_targets[ids],271self.queuess[ids],272self.queuess_alloc[ids],273self.capacitiess[ids],274self.are_queues_avail[ids],275self.releasetimes_queues[ids],276):277n_queues = len(queues)278# print ' '+30*'><'279# print ' Compressor id_comp', id_comp,'n_queues',n_queues280# check for new vehicle arrivals/departures281282ids_veh_entered_sumo, ids_veh_left_sumo, ids_veh_new_sumo = vehicles.get_entered_left(283id_detectedge_sumo, ids_veh_detect_sumo)284285if 0:286print ' id_detectedge_sumo', id_detectedge_sumo287print ' ids_veh_detect_sumo', ids_veh_detect_sumo288print ' ids_veh_new_sumo', ids_veh_new_sumo289print ' ids_veh_entered_sumo=', ids_veh_entered_sumo290print ' ids_veh_left_sumo=', ids_veh_left_sumo291292if len(ids_veh_entered_sumo) > 0:293294ids_veh_entered = vehicles.get_ids_from_ids_sumo(ids_veh_entered_sumo)295296for id_veh_entered, id_veh_entered_sumo, id_leader, length_plat\297in zip(ids_veh_entered, ids_veh_entered_sumo,298vehicles.ids_leader[ids_veh_entered],299vehicles.lengths_plat[ids_veh_entered]):300301# we cannot deconcatenate here, vehicles are in movement302# instead, measure if there is enough room for the platoon303# otherwise send platoon through bypass304if (length_plat < 0.001) & (id_leader == -1):305# no platoon, it is a single vehicle306id_targetedge_sumo = traci.vehicle.getRoute(id_veh_entered_sumo)[-1]307ids_shuntedge_sumo = edges.ids_sumo[ids_shuntedge]308# print ' dispatch id_veh_entered_sumo %s'%id_veh_entered_sumo,id_targetedge_sumo,ids_edge_sumo_target309310is_found_queue = False311inds_queue = np.flatnonzero((np.array(ids_edge_sumo_target, object)312== id_targetedge_sumo) & np.array(are_queue_avail, dtype=np.bool))313# print ' inds_queue',inds_queue314if len(inds_queue) > 0:315#ind_queue = ids_edge_sumo_target.index(id_targetedge_sumo)316ind_queue = inds_queue[0]317queue = queues[ind_queue]318capa_queue = capacities[ind_queue]319len_queue = len(queue)320# print ' found ind_queue,len_queue,capa_queue',ind_queue,len_queue,capa_queue321# if len_queue < capa_queue:322self._alloc_queue(queue, queues_alloc[ind_queue],323capa_queue,324id_veh_entered,325id_veh_entered_sumo,326ids_shuntedge[ind_queue],327ids_shuntedge_sumo[ind_queue],328vehicles, edges)329330# queue is full now, remove target331# no, otherwise th target is lost to program the vehicles332if len_queue+1 == capa_queue:333are_queue_avail[ind_queue] = False334335is_found_queue = True336337if not is_found_queue:338# print ' no queue with target or specific queue is full, search for a new queue'339340is_found_queue = False341for ind_queue, queue in zip(range(1, n_queues), queues[1:]):342if len(queue) == 0:343is_found_queue = True344break345# ind_queue = 1 # start with 1 because 0 is bypass346#is_queueend = False347# while len(queues[ind_queue])>0 & (not is_queueend):348# is_queueend = ind_queue == n_queues-1349# if not350# ind_queue += 1351352if not is_found_queue:353# print ' all queues are busy, let vehicle %s go ahead'%id_veh_entered_sumo354pass355else:356# print ' configure target of new queue',ind_queue,id_targetedge_sumo357ids_edge_sumo_target[ind_queue] = id_targetedge_sumo358self._alloc_queue(queues[ind_queue],359queues_alloc[ind_queue],360capacities[ind_queue],361id_veh_entered,362id_veh_entered_sumo,363ids_shuntedge[ind_queue],364ids_shuntedge_sumo[ind_queue],365vehicles, edges)366367else:368# let platoon pass369pass370else:371# nothing happened372pass373374# update veh on detector edge375self.ids_vehs_detect_sumo[id_comp] = ids_veh_new_sumo376377if True: # do this later ...simtime - self.releasetimes[id_comp]> 10:378# now check if any of the vehicle in any of the queues has arrived379# and if a queue is complete, create a platoon, send it off and380# reset the queue381# print ' Deal with queues...'382for ind_queue, queue, queue_alloc,\383capacity, id_edge_sumo_target,\384id_shuntedge_sumo, releasetime_queue\385in zip(386range(n_queues), queues, queues_alloc,387capacities, ids_edge_sumo_target,388edges.ids_sumo[ids_shuntedge], releasetime_queues):389if 0:390print ' OOOO shunt %s --> target %s' % (id_shuntedge_sumo, id_edge_sumo_target)391print ' simtime-releasetime_queue', simtime-releasetime_queue392print ' queue', queue, id(queue)393print ' queue_alloc', queue_alloc394395# check if allocated arrived396ids_veh_arrived = []397for id_veh, id_veh_sumo in zip(queue_alloc, vehicles.ids_sumo[queue_alloc]):398if vehicles.reached_stop_sumo(id_veh_sumo):399ids_veh_arrived.append(id_veh)400401for id_veh in ids_veh_arrived:402queue_alloc.remove(id_veh)403404# check if queue reached capacity limit405len_queue = len(queue)406if (len(queue_alloc) == 0) & (len_queue > 0):407# no allocations for this queue408len_queue = len(queue)409# print ' rtq,rtc',releasetime_queue,self.releasetimes[id_comp], len_queue == capacity,simtime - releasetime_queue,simtime - self.releasetimes[id_comp]410# here we coukd also test timeout conditions411if ((len_queue == capacity) | ((simtime - releasetime_queue) > self.time_accumulation_max.get_value())) & (simtime - self.releasetimes[id_comp] > self.time_release_min.get_value()):412# queue is full413# print ' platoon and send vehicles:',queue414# action 1415# platoon all vehicles in queue, starting from last in queue416for i in range(len_queue-1, 0, -1):417vehicles.concatenate(queue[i], queue[i-1])418419# print ' check platooned vehicles:'420vehicles.get_platoon(queue[0])421# reprogram destination and start422for id_veh, id_veh_sumo in zip(queue, vehicles.ids_sumo[queue]):423vehicles.reschedule_trip_sumo(id_veh_sumo, id_edge_sumo_target)424#vehicles.control_slow_down( id_veh, speed = 6.0/3.6)425traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)426427# reset queue428del queue[:]429ids_edge_sumo_target[ind_queue] = ""430are_queue_avail[ind_queue] = True431releasetime_queues[ind_queue] = int(simtime)432self.releasetimes[id_comp] = int(simtime)433434def _alloc_queue(self, queue, queue_alloc, capa_queue,435id_veh, id_veh_sumo,436id_shuntedge, id_shuntedge_sumo, vehicles, edges):437438queue.append(id_veh)439queue_alloc.append(id_veh)440len_queue = len(queue)441#pos_stop = 1.0+(capa_queue-len_queue)*(self.length_veh+0.5)442pos_stop = edges.lengths[id_shuntedge]-10-len_queue*(self.length_veh+0.5)443# print '_alloc_queue',id_veh_sumo,id_shuntedge_sumo,capa_queue-len_queue,pos_stop444vehicles.reschedule_trip_sumo(id_veh_sumo, id_shuntedge_sumo)445446vehicles.set_stop(id_veh, id_shuntedge_sumo, pos_stop, laneindex=0)447# print ' get_traci_route',get_traci_route(id_veh_sumo)448# print ' get_traci_route_all',get_traci_route_all(id_veh_sumo)449# print ' get_traci_routeindex',get_traci_routeindex(id_veh_sumo)450#get_traci_route_all = traci.vehicle.getRoute451#get_traci_routeindex = traci.vehicle.getRouteIndex452# def get_traci_route453454455class Decompressors(Compressors):456def __init__(self, ident, prtservices, **kwargs):457self._init_objman(ident=ident,458parent=prtservices,459name='Decompressors',460info='Decomressors dissolve platoons by stopping and decatenating vehicles in parallel shunt edges. Contains information and methods for decompressors to create platoons.',461version=0.1,462**kwargs)463self._init_attributes()464465def _init_constants(self):466self.do_not_save_attrs([467'decel', 'ids_comp_to_ids_detectedge_sumo', 'queuess',468'queuess_alloc', 'capacitiess', # 'ids_edge_sumo_targets',469'are_queues_avail', 'releasetimes', 'releasetimes_queues',470'length_veh', 'ids_vehs_detect_sumo',471])472473def prepare_sim(self, process):474print 'Decompressors.prepare_sim'475net = self.get_scenario().net476nodes = net.nodes477edges = net.edges478lanes = net.lanes479ids_edge_sumo = edges.ids_sumo480481id_prtmode = self.parent.id_prtmode482self.decel = self.parent.prtvehicles.decel_emergency483484ids = self.get_ids()485if len(ids) == 0:486return []487n_id_max = np.max(ids)+1488489self.ids_comp_to_ids_detectedge_sumo = np.zeros(n_id_max, dtype=np.object)490self.ids_comp_to_ids_detectedge_sumo[ids] = edges.ids_sumo[self.ids_detectoredge[ids]]491492# this is list of queues for all shunt lines for each compressor493self.queuess = np.zeros(n_id_max, dtype=np.object)494495# this is list of target edges for all shunt lines for each compressor496self.ids_targetedgess_sumo = np.zeros(n_id_max, dtype=np.object)497498# thses queus are the same as queuess but contains the allocated, but not yet arrived vehicles499self.queuess_alloc = np.zeros(n_id_max, dtype=np.object)500501# this is list of maximum queue length for all shunt lines for each compressor502self.capacitiess = np.zeros(n_id_max, dtype=np.object)503504# list with target edges for each queue for each compressor505#self.ids_edge_sumo_targets = np.zeros(n_id_max,dtype = np.object)506507# list with availabilities for each queue for each compressor508self.are_queues_avail = np.zeros(n_id_max, dtype=np.object)509510# releasetimes for each compressor511self.releasetimes = np.zeros(n_id_max, dtype=np.int32)512513# releasetimes for each queue for each compressor514self.releasetimes_queues = np.zeros(n_id_max, dtype=np.object)515516self.length_veh = self.parent.prtvehicles.get_length()517518# this queue contains all vehicles on the detect edge519# it is used to identify whether a new vehicle has left the merge520self.ids_vehs_detect_sumo = np.zeros(n_id_max, dtype=np.object)521522for id_comp, ids_shuntedge in zip(ids, self.ids_shuntedges[ids]):523# print ' id_comp',id_comp524n_shunts = len(ids_shuntedge) # first edge is not a real shunt!!525526queues = n_shunts*[None]527queues_alloc = n_shunts*[None]528capacities = n_shunts*[None]529ids_targetedges_sumo = n_shunts*[None]530for i, length_edge in zip(range(n_shunts), edges.lengths[ids_shuntedge]):531capacities[i] = int((length_edge-25.0)/(self.length_veh+0.5))532queues[i] = []533queues_alloc[i] = []534ids_targetedges_sumo[i] = {}535536self.queuess[id_comp] = queues537self.queuess_alloc[id_comp] = queues_alloc538self.capacitiess[id_comp] = capacities539self.ids_targetedgess_sumo[id_comp] = ids_targetedges_sumo540#self.ids_edge_sumo_targets [id_comp] = n_shunts*['']541self.are_queues_avail[id_comp] = n_shunts*[True]542self.releasetimes_queues[id_comp] = np.arange(n_shunts)*int(self.time_accumulation_max.get_value()/n_shunts)543544self.ids_vehs_detect_sumo[id_comp] = set()545# print ' capacities',self.capacitiess[id_comp]546# print ' queues',self.queuess[id_comp]547548return [(self.time_update.get_value(), self.process_step),549]550551def process_step(self, process):552simtime = process.simtime553print 79*'_'554print 'Deompressors.process_step at', simtime555net = self.get_scenario().net556edges = net.edges557vehicles = self.parent.prtvehicles558ids = self.get_ids()559for id_comp,\560id_detectedge_sumo,\561ids_veh_detect_sumo,\562ids_shuntedge,\563queues,\564queues_alloc,\565capacities,\566are_queue_avail,\567releasetime_queues,\568ids_targetedges_sumo\569in zip(ids,570self.ids_comp_to_ids_detectedge_sumo[ids],571self.ids_vehs_detect_sumo[ids],572self.ids_shuntedges[ids],573self.queuess[ids],574self.queuess_alloc[ids],575self.capacitiess[ids],576self.are_queues_avail[ids],577self.releasetimes_queues[ids],578self.ids_targetedgess_sumo[ids]579):580n_queues = len(queues)581ids_shuntedge_sumo = edges.ids_sumo[ids_shuntedge]582# print ' '+60*'|'583# print ' Decompressor id_comp', id_comp,'n_queues',n_queues584# check for new vehicle arrivals/departures585586ids_veh_sumo = set(traci.edge.getLastStepVehicleIDs(id_detectedge_sumo))587if 0:588print ' id_detectedge_sumo', id_detectedge_sumo589print ' ids_veh_detect_sumo', ids_veh_detect_sumo, ids_veh_detect_sumo != ids_veh_sumo590print ' ids_veh_sumo=', ids_veh_sumo591ids_veh_sumo_raw = traci.edge.getLastStepVehicleIDs(id_detectedge_sumo)592print ' ids_veh_sumo_raw=', ids_veh_sumo_raw593594if ids_veh_detect_sumo != ids_veh_sumo:595# there are new vehicles596597#ids_veh_entered_sumo, poss = vehicles.get_ids_sumo_sorted(ids_veh_sumo.difference(ids_veh_detect_sumo))598# ids_veh_entered_sumo = list(ids_veh_sumo.difference(ids_veh_detect_sumo))599ids_veh_entered_sumo = get_entered_vehs(ids_veh_sumo, ids_veh_detect_sumo)600ids_veh_entered = vehicles.get_ids_from_ids_sumo(ids_veh_entered_sumo)601602if 0:603print ' ids_veh_entered', ids_veh_entered, type(ids_veh_entered)604# print ' poss',poss605print ' ids_veh_entered_sumo', ids_veh_entered_sumo606print ' ids_leader', vehicles.ids_leader[ids_veh_entered]607print ' ids_follower', vehicles.ids_follower[ids_veh_entered]608print ' lengths_plat', vehicles.lengths_plat[ids_veh_entered]609610for id_veh_entered, id_veh_entered_sumo, id_leader, length_plat\611in zip(ids_veh_entered, ids_veh_entered_sumo,612vehicles.ids_leader[ids_veh_entered],613vehicles.lengths_plat[ids_veh_entered]):614615# we cannot deconcatenate here, vehicles are in movement616# instead, measure if there is enough room for the platoon617# otherwise send platoon through bypass618if (length_plat > 0.001) & (id_leader == -1):619# vehicle is a platoon leader:620# find a queue that fits the platoon621id_targetedge_sumo = traci.vehicle.getRoute(id_veh_entered_sumo)[-1]622# print ' dispatch id_veh_entered_sumo %s with target %s'%(id_veh_entered_sumo,id_targetedge_sumo)623624is_found_queue = False625costs = np.zeros(n_queues, dtype=np.float32)626for ind_queue, queue, is_avail, capa in zip(range(n_queues), queues, are_queue_avail, capacities):627628dl = (capa - len(queue)) * self.length_veh - 2*length_plat629# print ' ceck queue %d with capa %d, len = %d, dl=%d'%(ind_queue,capa,len(queue),dl)630if (dl > 0) & is_avail:631costs[ind_queue] = dl632else:633costs[ind_queue] = np.inf634635ind_queue = np.argmin(costs)636# print ' ind_queue,costs',ind_queue,costs637# if costs[ind_queue] <10000:# OK queue has been found638#ind_queue = ids_edge_sumo_target.index(id_targetedge_sumo)639#ind_queue = inds_queue[0]640queue = queues[ind_queue]641capa_queue = capacities[ind_queue]642len_queue = len(queue)643# print ' found ind_queue,len_queue,capa_queue',ind_queue,len_queue,capa_queue644# if len_queue < capa_queue:645self._alloc_queue(queue, queues_alloc[ind_queue],646ids_targetedges_sumo[ind_queue],647capa_queue,648id_veh_entered,649id_veh_entered_sumo,650id_targetedge_sumo,651ids_shuntedge[ind_queue],652ids_shuntedge_sumo[ind_queue],653vehicles, edges)654655elif (id_leader > -1):656# this is a follower:657# shunt it to the same edge as its leader658id_targetedge_sumo = traci.vehicle.getRoute(id_veh_entered_sumo)[-1]659id_platoonleader = vehicles.get_platoonleader(id_leader)660for ind_queue, queue, capa_queue, in zip(range(n_queues), queues, capacities):661if id_platoonleader in queue:662# print ' found id_platoonleader prt.%d of prt.%d at queue %d'%(id_platoonleader,id_veh_entered,ind_queue)663self._alloc_queue_follower(664queue, queues_alloc[ind_queue],665ids_targetedges_sumo[ind_queue],666capa_queue,667id_veh_entered,668id_veh_entered_sumo,669id_targetedge_sumo,670ids_shuntedge_sumo[ind_queue],671vehicles)672break673else:674# individual vehicle675pass676677# update veh on detector edge678self.ids_vehs_detect_sumo[id_comp] = ids_veh_sumo679680# (simtime - self.releasetimes[id_comp]> self.time_release_min.get_value()): # do this later ...simtime - self.releasetimes[id_comp]> 10:681if 1:682# now check if any of the vehicle in any of the queues has arrived683# and if a queue is complete, create a platoon, send it off and684# reset the queue685# print ' Deal with queues...'686is_released = False687for ind_queue, queue, queue_alloc,\688ids_targetedge_sumo, capacity,\689id_shuntedge_sumo, releasetime_queue\690in zip(691range(n_queues), queues, queues_alloc,692ids_targetedges_sumo, capacities,693edges.ids_sumo[ids_shuntedge], releasetime_queues):694if 0:695print ' QQQQQQQQQQQ shunt %s ' % (id_shuntedge_sumo)696print ' simtime-releasetime_queue', simtime-releasetime_queue, (simtime - releasetime_queue > self.time_accumulation_max.get_value()), (simtime - self.releasetimes[id_comp] > 10)697print ' queue', queue, id(queue)698print ' ids_targetedge_sumo', ids_targetedge_sumo699print ' queue_alloc', queue_alloc700print ' releasetime_queue', releasetime_queue, simtime - releasetime_queue, simtime - releasetime_queue > self.time_accumulation_max.get_value()701# here we could also test timeout conditions702if (simtime - self.releasetimes[id_comp] > self.time_release_min.get_value()) & (simtime - releasetime_queue > self.time_accumulation_max.get_value()):703# if (simtime - self.releasetimes[id_comp]> self.time_release_min.get_value()):704705# check if allocated arrived706id_veh_arrived = -1707# for id_vehinfo,id_veh_sumo, length_plat in zip(range(),queue_alloc, vehicles.ids_sumo[queue_alloc],vehicles.lengths_plat[queue_alloc]):708709for id_veh in queue_alloc:710if vehicles.reached_stop_sumo(vehicles.ids_sumo[id_veh]):711id_veh_arrived = id_veh712break713714# print ' allocated prt.%d reached stop (-1 means no vehicle)'%(id_veh_arrived)715716if id_veh_arrived > -1:717# a platoon leader id_veh_arrived has arrived718719# print ' check if entire platoon arrived at the queue'720length_plat = vehicles.lengths_plat[id_veh_arrived]721ind_pl = queue.index(id_veh_arrived)722len_queue = len(queue)723ids_platoon = []724#ids_targetedge_plat_sumo= []725726if len_queue > ind_pl+1:727728for i, id_veh in zip(range(ind_pl+1, len_queue), queue[ind_pl+1:]):729# print ' check prt.%d with leader prt.%d'%(id_veh,vehicles.ids_leader[id_veh])730if vehicles.ids_leader[id_veh] != -1:731# print ' real lead prt.%d qlead prt.%d | plat lead prt.%d plat qlead prt.%d '%(vehicles.ids_leader[id_veh],queue[i-1],vehicles.get_platoonleader(id_veh),id_veh_arrived)732# if vehicles.ids_leader[id_veh] == queue[i-1]:733# print ' add'734# ids_platoon.append(id_veh)735#736if vehicles.get_platoonleader(id_veh) == id_veh_arrived:737# TODO: this is very inefficient, by happens738# when platoon has ben broken up during a merge operation739# idea: use a pointer to follower740ids_platoon.append(id_veh)741# ids_targetedge_plat_sumo.append(id_targetedge_sumo)742# print ' add'743else:744# is not a follower745pass746length_plat_arrived = len(ids_platoon)*self.length_veh + 0.5747# print ' arrived id_veh_arrived prt.%d at queue pos ind_pl=%d (should be 0)'%(id_veh_arrived,ind_pl)748# print ' with platoon length %.2fm > %.2fm?'%(length_plat_arrived,length_plat),(length_plat_arrived >= length_plat)& (not is_released),'is_released',is_released749750if (length_plat_arrived >= length_plat) & (not is_released):751# print ' entire platoon length in queue, now release...',ids_platoon752is_released = True753# reschedule leader754755vehicles.reschedule_trip(id_veh_arrived, ids_targetedge_sumo[id_veh_arrived])756id_veh_sumo = vehicles.get_id_sumo(id_veh_arrived)757#traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)758#vehicles.control_slow_down( id_veh_arrived, speed = 6.0/3.6)759# print ' queue_alloc',queue_alloc760# print ' queue',queue761# deconcatenate and reschedule followers762for id_veh, id_veh_sumo in zip(ids_platoon[::-1], vehicles.ids_sumo[ids_platoon[::-1]]):763vehicles.decatenate(id_veh)764vehicles.reschedule_trip_sumo(id_veh_sumo, ids_targetedge_sumo[id_veh])765#vehicles.control_slow_down( id_veh, speed = 6.0/3.6)766#traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)767queue.remove(id_veh)768del ids_targetedge_sumo[id_veh]769770releasetime_queues[ind_queue] = int(simtime)771self.releasetimes[id_comp] = int(simtime)772773# remove platoon leader774queue_alloc.remove(id_veh_arrived)775queue.remove(id_veh_arrived)776del ids_targetedge_sumo[id_veh_arrived]777778else:779# print ' platoon incomplete'780pass781else:782# print ' no leaders arrived in this quque'783pass784785def _alloc_queue(self, queue, queue_alloc, ids_targetedge_sumo, capa_queue,786id_veh, id_veh_sumo, id_targetedge_sumo,787id_shuntedge, id_shuntedge_sumo, vehicles, edges):788"""Queue allocation for platoon leader only."""789queue.append(id_veh)790791# store here also the target necessary to reprogram792queue_alloc.append(id_veh)793# TODO: idea, the original target should be stored in the vehicles db794ids_targetedge_sumo[id_veh] = id_targetedge_sumo795len_queue = len(queue)796797# make platoon leder always stop at the foremost position798pos_stop = 1.0 + capa_queue*(self.length_veh)799# print '_alloc_queue',id_veh_sumo,id_shuntedge_sumo,capa_queue-len_queue,pos_stop800vehicles.reschedule_trip_sumo(id_veh_sumo, id_shuntedge_sumo)801vehicles.set_stop(id_veh, id_shuntedge_sumo, pos_stop, laneindex=0)802803# Forced exit of vehicle from merge conrol804self.parent.mergenodes.exit_veh_forced(id_veh, id_veh_sumo, vehicles)805806def _alloc_queue_follower(self, queue, queue_alloc, ids_targetedge_sumo,807capa_queue,808id_veh, id_veh_sumo, id_targetedge_sumo,809id_shuntedge_sumo, vehicles):810"""Queue allocation for follower only."""811queue.append(id_veh)812# TODO: idea, the original target should be stored in the vehicles db813ids_targetedge_sumo[id_veh] = id_targetedge_sumo814# queue_alloc.append(id_veh)815#len_queue = len(queue)816817# make platoon leder always stop at the foremost position818#pos_stop = 1.0 + capa_queue*(self.length_veh + 0.5)819# print '_alloc_queue_follower',id_veh_sumo,id_shuntedge_sumo,id_targetedge_sumo820vehicles.reschedule_trip_sumo(id_veh_sumo, id_shuntedge_sumo)821#vehicles.set_stop(id_veh, id_shuntedge_sumo, pos_stop, laneindex = 0)822823824# class Shortmergenodes(Mergenodes):825826class Mergenodes(am.ArrayObjman):827def __init__(self, ident, prtservices, **kwargs):828self._init_objman(ident=ident,829parent=prtservices,830name='Merge nodes',831info='Contains information and methods for merging the flow of two vehicle streams, including platoons.',832version=0.2,833**kwargs)834self._init_attributes()835836def _init_attributes(self):837#self.add(cm.ObjConf(PrtBerths('berths',self)) )838839self.add(cm.AttrConf('time_update', 0.5,840groupnames=['parameters'],841name='Update time',842info="Update time for merges.",843unit='s',844))845846net = self.get_scenario().net847848self.add_col(am.IdsArrayConf('ids_node', net.nodes,849name='Node ID',850info='Network node ID.',851is_index=True,852))853854# self.add_col(am.IdsArrayConf('ids_edge_in1', net.edges,855# name = 'ID edge 1',856# info = 'ID of edge at entrance 1.',857# ))858if self.get_version() < 0.2:859self.delete('ids_mergenode_in1')860self.delete('ids_mergenode_in2')861self.delete('ids_mergenodes_out')862self.delete('distances_mergenode_in1')863self.delete('distances_mergenode_in2')864865self.add_col(am.IdsArrayConf('ids_node_in1', net.nodes,866name='ID node in 1',867info='ID of upstream network node at incoming line 1.',868))869870self.add_col(am.ArrayConf('distances_node_in1', 0.0,871groupnames=['parameters'],872name='Distance node in 1',873info="Distance to network node at incoming line 1.",874unit='m',875))876877# self.add_col(am.IdsArrayConf('ids_edge2', net.edges,878# name = 'ID edge 2',879# info = 'ID of edge at entrance 2.',880# ))881882self.add_col(am.IdsArrayConf('ids_node_in2', net.nodes,883name='ID node in 2',884info='ID of upstream network node at incoming line 2.',885))886887self.add_col(am.ArrayConf('distances_node_in2', 0.0,888groupnames=['parameters'],889name='Distance mergenode in 2',890info="Distance to upstream network node at incoming line 2.",891unit='m',892))893894self.add_col(am.IdlistsArrayConf('ids_nodes_out', net.nodes,895name='IDs nodes out',896info='IDs of downstream network nodes.',897))898899self.add_col(am.ArrayConf('are_station', default=False,900groupnames=['parameters'],901name='is station',902info="Node is the exit node of a station, comressor or decompressor. The incoming edge of this are internal and are not considered.",903))904905self.add_col(am.ArrayConf('are_entry', default=False,906groupnames=['parameters'],907name='is entry',908info="Node is a merge wich receives an entry line from a station, comressor or decompressor. This shorter line is always input line 1 and expects that vehicles have a speed close to zero.",909))910911self.set_version(0.2)912913def _init_constants(self):914self.do_not_save_attrs([915'ids_merge_to_ids_node_sumo', 'ids_merge_to_ids_edge_out_sumo',916'ids_node_to_ids_merge', 'ids_vehs_out_sumo,'917'ids_vehs_in1', 'ids_vehs_in1_sumo',918'ids_vehs_in2', 'ids_vehs_in2_sumo',919'ids_vehs_merged', 'ids_vehs_merged_sumo',920'lineinds_vehs_merged', 'vehicle_to_merge',921'vehicles_entries', 'vehicles_mains',922])923924def make_from_net(self):925"""926Make merge node database from network.927"""928print 'Mergenodes.make_from_net'929self.clear()930id_prtmode = self.parent.id_prtmode931932net = self.get_scenario().net933nodes = net.nodes934edges = net.edges935lanes = net.lanes936id_zippertype = nodes.types.choices['zipper']937938compressors = self.parent.compressors939decompressors = self.parent.decompressors940ids_detectoredges = set(compressors.ids_detectoredge.get_value())941ids_detectoredges.update(decompressors.ids_detectoredge.get_value())942943ids_shuntedges = set()944ids_mainlinedges = set()945946ids = compressors.get_ids()947for id_unit, ids_edge in zip(ids, compressors.ids_shuntedges[ids]):948# put in all shunts except for the bypass949print ' bypass of compressor', id_unit, '=', ids_edge[0]950ids_mainlinedges.add(ids_edge[0])951print ' update ids_shuntedges with compressors', ids_edge[1:]952ids_shuntedges.update(ids_edge[1:])953954# collect decompressornodes, wich will not become entry merges955ids = decompressors.get_ids()956ids_node_decompressorout = []957for id_unit, ids_edge in zip(ids, decompressors.ids_shuntedges[ids]):958# put in all shunts except for the bypass959print ' bypass of decompressor', id_unit, '=', ids_edge[0], 'id_tonode', edges.ids_tonode[ids_edge[0]]960ids_mainlinedges.add(ids_edge[0])961ids_node_decompressorout.append(edges.ids_tonode[ids_edge[0]])962print ' update ids_shuntedges with decompressors', ids_edge[1:]963ids_shuntedges.update(ids_edge[1:])964print ' ids_node_decompressorout', ids_node_decompressorout965ids_node_compressorout = edges.ids_tonode[list(ids_mainlinedges)]966ids_mainlinefromnodes = edges.ids_fromnode[list(ids_mainlinedges)]967968# now put also all incoming edges of main lines as shunts969# in order to cut of compressor entrance from downstrem search970# for id_edge in ids_mainlinedges:971# print ' update ids_shuntedges with mainline incoming',edges.get_incoming(id_edge)972# ids_shuntedges.update(edges.get_incoming(id_edge))973974print ' ids_shuntedges', ids_shuntedges975#ids_ptstop = ptstops.get_ids()976#id_mode_prt = self.parent.id_prtmode977978#ids_edges = net.lanes.ids_edge[ptstops.ids_lane[ids_ptstop]]979#ids_lanes = net.edges.ids_lanes[ids_edges]980#ids_lane = ptstops.ids_lane[ids_ptstop]981#edgelengths = net.edges.lengths982983ids_node = nodes.get_ids()984print ' ids_node', ids_node985for id_node, ids_edge_from, ids_edge_to, id_type in zip(986ids_node,987nodes.ids_incoming[ids_node],988nodes.ids_outgoing[ids_node],989nodes.types[ids_node],990):991992if True:993#994995print 60*'-'996print ' check node', id_node, nodes.ids_sumo[id_node], id_type, id_zippertype == id_type997998# id merge to be created, for debugging999id_merge = -110001001if (ids_edge_from is None):1002print ' WARNING: isolate node: ids_edge_from,ids_edge_to', ids_edge_from, ids_edge_to1003pass10041005elif (len(ids_edge_from) == 2) & (len(ids_edge_to) == 1):10061007# ids_mainlinedges.add(ids_edge[0])1008# ids_shuntedges.update(ids_edge[1:])10091010# check accesslevels1011id_edge1, id_edge2 = ids_edge_from1012ids_lane1, ids_lane2 = edges.ids_lanes[ids_edge_from]1013print ' id_edge1', id_edge1, 'ids_lane1', ids_lane1, self.is_prt_only(ids_lane1, lanes)1014print ' id_edge2', id_edge2, 'ids_lane2', ids_lane2, self.is_prt_only(ids_lane2, lanes)1015if self.is_prt_only(ids_lane1, lanes) & self.is_prt_only(ids_lane2, lanes):1016print ' +PRT merge with 2 PRT lines entering'10171018if id_type != id_zippertype:1019print 'WARNING: PRT network node %d %s is NOT in zipper mode!' % (id_node, nodes.ids_sumo[id_node])10201021if not ids_shuntedges.isdisjoint(ids_edge_from):1022print ' one incoming edge is a shunt edge. Detect last shunt node.'10231024# TODO: this should be a function of the compressor class1025id_tonode_out = edges.ids_tonode[ids_edge_to[0]]1026if id_tonode_out in ids_node_compressorout:1027print ' output node of compressor => station merge node with output node', id_tonode_out1028# model this node as a platform end node of a station1029id_merge = self.add_row(ids_node=id_node,1030ids_nodes_out=[id_tonode_out],1031are_station=True,1032)1033else:1034print ' compressor internal node'1035pass10361037# elif not ids_mainlinedges.isdisjoint(ids_edge_from):1038# print ' one incoming line is the bypass'1039# ids_node_out = self.search_downstream_merges(ids_edge_to[0], edges, lanes, id_prtmode)1040#1041# # model this node as a station output1042# self.add_row( ids_node = id_node,1043# ids_nodes_out = ids_node_out,1044# are_station = True,1045# )10461047else:1048print ' regular merge'1049id_node_up1, dist1 = self.search_upstream_merge(id_edge1, edges, lanes, id_prtmode)1050id_node_up2, dist2 = self.search_upstream_merge(id_edge2, edges, lanes, id_prtmode)10511052ids_node_out = self.search_downstream_merges(1053ids_edge_to[0], edges, lanes, id_prtmode, ids_sinkedge=ids_shuntedges)1054id_merge = self.add_row(ids_node=id_node,1055ids_node_in1=id_node_up1,1056distances_node_in1=dist1,1057ids_node_in2=id_node_up2,1058distances_node_in2=dist2,1059ids_nodes_out=ids_node_out,1060are_station=False,1061)10621063elif (len(ids_edge_from) == 1) & (len(ids_edge_to) == 2):10641065id_edge_from = ids_edge_from[0]1066ids_lane_in = edges.ids_lanes[id_edge_from]1067#al_in = lanes.get_accesslevel(edges.ids_lanes[id_edge_from], id_prtmode)1068#is_prt_in = lanes.ids_modes_allow[edges.ids_lanes[id_edge_from]] == id_prtmode1069is_prt_in = self.is_prt_only(ids_lane_in, lanes)1070print ' one in, 2 out => diverge node, access is_prt_in', is_prt_in, 'is_platform_in', self.is_platform(ids_lane_in, lanes)10711072# if id_edge_from in ids_detectoredges:1073# print ' fromnode is a detectoredge of a compressor'1074# id_node_up, dist = self.search_upstream_merge(id_edge_from, edges, lanes, id_prtmode)1075# self.add_row( ids_node = id_node,1076# ids_node_in1 = id_node_up,1077# distances_node_in1 = dist,1078# #ids_nodes_out = ids_node_out,1079# are_station = True,1080# )10811082# check if node is outgoing node at a station1083if 0: # no longer considered1084if is_prt_in & (id_node in ids_mainlinefromnodes):1085print ' Diverge node in front of a compressor/decompressorr.'1086id_node_up, dist = self.search_upstream_merge(id_edge_from, edges, lanes, id_prtmode)10871088id_edge1, id_edge2 = ids_edge_to1089if id_edge1 in ids_mainlinedges:1090id_edge = id_edge11091else:1092id_edge = id_edge210931094#ids_node_out = self.search_downstream_merges(id_edge, edges, lanes, id_prtmode, ids_sinkedge = ids_shuntedges)1095ids_node_out = [edges.ids_tonode[id_edge]]1096self.add_row(ids_node=id_node,1097ids_node_in1=id_node_up,1098distances_node_in1=dist,1099ids_nodes_out=ids_node_out,1100are_station=True,1101)11021103if self.is_platform(ids_lane_in, lanes):1104print ' mixed access level of incoming edge, check for platform exit node'11051106id_edge1, id_edge2 = ids_edge_to1107ids_lane1, ids_lane2 = edges.ids_lanes[ids_edge_to]11081109# here we could also decide on the number of lanes1110# but this may not be robust in the future1111print ' out id_edge1', id_edge1, 'ids_lane1', ids_lane1, 'is_prt_only', self.is_prt_only(ids_lane1, lanes)1112print ' out id_edge2', id_edge2, 'ids_lane2', ids_lane2, 'is_prt_only', self.is_prt_only(ids_lane2, lanes)1113# if self.is_prt_only(ids_lane1, lanes) & self.is_prt_only(ids_lane2, lanes):1114if self.is_prt_only(ids_lane2, lanes):11151116print ' Ped exit on outedge 1'1117#id_node_up, dist = self.search_upstream_merge(id_edge_from, edges, lanes, id_prtmode)1118ids_node_out = self.search_downstream_merges(1119id_edge2, edges, lanes, id_prtmode, ids_sinkedge=ids_shuntedges)1120id_merge = self.add_row(ids_node=id_node,1121#ids_node_in1 = id_node_up,1122#distances_node_in1 = dist,1123ids_nodes_out=ids_node_out,1124are_station=True,1125)11261127elif self.is_prt_only(ids_lane1, lanes):1128print ' Ped exit on outedge 2'1129#id_node_up, dist = self.search_upstream_merge(id_edge_from, edges, lanes, id_prtmode)1130ids_node_out = self.search_downstream_merges(1131id_edge1, edges, lanes, id_prtmode, ids_sinkedge=ids_shuntedges)1132id_merge = self.add_row(ids_node=id_node,1133#ids_node_in1 = id_node_up,1134#distances_node_in1 = dist,1135ids_nodes_out=ids_node_out,1136are_station=True,1137)11381139if id_merge >= 0:1140self.print_attrs(ids=[id_merge, ])11411142# now check if merge has entry line form stations or compressors'#,self.ids_node._index_to_id1143ids = self.get_ids()1144i = 01145while i < len(ids):1146id_merge = ids[i]11471148id_node_in1 = self.ids_node_in1[id_merge]1149id_node_in2 = self.ids_node_in2[id_merge]1150print ' check entry of id_merge', id_merge, 'id_node', self.ids_node[id_merge], ' no decomp', self.ids_node[id_merge] not in ids_node_decompressorout1151if (id_node_in1 > -1) & (id_node_in2 > -1)\1152& (self.ids_node[id_merge] not in ids_node_decompressorout):11531154print ' id_node_in1', self.ids_node_in1[id_merge], nodes.ids_sumo[self.ids_node_in1[id_merge]], self.ids_node.has_index(self.ids_node_in1[id_merge])1155print ' id_node_in2', self.ids_node_in2[id_merge], nodes.ids_sumo[self.ids_node_in2[id_merge]], self.ids_node.has_index(self.ids_node_in2[id_merge])1156if 1:1157id_merge_in1 = self.ids_node.get_id_from_index(self.ids_node_in1[id_merge])1158id_merge_in2 = self.ids_node.get_id_from_index(self.ids_node_in2[id_merge])1159print ' station check id_merge', id_merge, 'id_merge_in1', id_merge_in1, 'station', self.are_station[id_merge_in1], 'id_merge_in2', id_merge_in2, 'station', self.are_station[id_merge_in2]11601161if self.are_station[id_merge_in2]:1162self.are_entry[id_merge] = True1163# in line 2 is already entry line1164pass11651166elif self.are_station[id_merge_in1]:1167self.are_entry[id_merge] = True1168# move entry line from inline 1 to inline 211691170id_node_in2 = self.ids_node_in2[id_merge]1171dist2 = self.distances_node_in2[id_merge]11721173self.ids_node_in2[id_merge] = self.ids_node_in1[id_merge]1174self.distances_node_in2[id_merge] = self.distances_node_in1[id_merge]11751176self.ids_node_in1[id_merge] = id_node_in21177self.distances_node_in1[id_merge] = dist211781179i += 111801181def get_scenario(self):1182return self.parent.get_scenario()11831184def prepare_sim(self, process):1185print 'Mergenodes.prepare_sim'1186net = self.get_scenario().net1187nodes = net.nodes1188edges = net.edges1189lanes = net.lanes1190ids_edge_sumo = edges.ids_sumo11911192id_prtmode = self.parent.id_prtmode1193self.decel = self.parent.prtvehicles.decel_emergency11941195ids = self.get_ids()1196if len(ids) == 0:1197return []1198n_id_max = np.max(ids)+111991200# database with vehicle id as key and controlling merge as value1201self.vehicle_to_merge = {}12021203# vehicle database for merge operation1204self.vehicles_entries = {}1205self.vehicles_mains = {}12061207#self.ids_merge_to_ids_node_sumo = np.zeros(n_id_max,dtype = np.object)1208#self.ids_merge_to_ids_node_sumo[ids] = nodes.ids_sumo[self.ids_node[ids]]12091210self.ids_merge_to_ids_edge_out_sumo = np.zeros(n_id_max, dtype=np.object)1211#self.ids_node_to_ids_edge_out_sumo = np.zeros(n_id_max,dtype = np.object)1212self.ids_node_to_ids_merge = np.zeros(np.max(self.ids_node[ids])+1, dtype=np.int32)1213self.ids_node_to_ids_merge[self.ids_node[ids]] = ids12141215# this queue contains all vehicles on the outgoing edge1216# it is used to identify whether a new vehicle has left the merge1217self.ids_vehs_out_sumo = np.zeros(n_id_max, dtype=np.object)12181219# this queue contains all vehicles on line 1 between1220# merge and id_node_in11221self.ids_vehs_in1 = np.zeros(n_id_max, dtype=np.object)1222self.ids_vehs_in1_sumo = np.zeros(n_id_max, dtype=np.object)12231224# this queue contains all vehicles on line 2 between1225# merge and id_node_in21226self.ids_vehs_in2 = np.zeros(n_id_max, dtype=np.object)1227self.ids_vehs_in2_sumo = np.zeros(n_id_max, dtype=np.object)12281229# this queue contains the merged vehicles for the controlled range1230self.ids_vehs_merged = np.zeros(n_id_max, dtype=np.object)1231self.ids_vehs_merged_sumo = np.zeros(n_id_max, dtype=np.object)12321233# this queuse contains the line index (1 or 2, 0= not assigned)1234self.lineinds_vehs_merged = np.zeros(n_id_max, dtype=np.object)12351236#self.ids_merge_to_ids_edge_out_sumo[ids] = edges.ids_sumo[self.ids_node[ids]]1237ids_node = self.ids_node[ids]1238for id_merge, id_node, ids_edge_out in zip(ids, ids_node, nodes.ids_outgoing[ids_node]):1239if len(ids_edge_out) == 1:1240# regular merge1241self.ids_merge_to_ids_edge_out_sumo[id_merge] = ids_edge_sumo[ids_edge_out[0]]12421243elif len(ids_edge_out) == 2:1244# one edge is PRT, the other ped access1245# check accesslevels1246id_edge1, id_edge2 = ids_edge_out1247ids_lane1, ids_lane2 = edges.ids_lanes[ids_edge_out]1248al1 = lanes.get_accesslevel(ids_lane1, id_prtmode)1249al2 = lanes.get_accesslevel(ids_lane2, id_prtmode)1250if al1 == 2:1251self.ids_merge_to_ids_edge_out_sumo[id_merge] = ids_edge_sumo[id_edge1]1252#self.ids_node_to_ids_edge_out_sumo[id_node] = ids_edge_sumo[id_edge1]1253if al2 == 2:1254self.ids_merge_to_ids_edge_out_sumo[id_merge] = ids_edge_sumo[id_edge2]1255#self.ids_node_to_ids_edge_out_sumo[id_node] = ids_edge_sumo[id_edge2]12561257self.ids_vehs_out_sumo[id_merge] = set()12581259self.ids_vehs_in1[id_merge] = list()1260self.ids_vehs_in1_sumo[id_merge] = list()1261self.ids_vehs_in2[id_merge] = list()1262self.ids_vehs_in2_sumo[id_merge] = list()12631264self.ids_vehs_merged[id_merge] = list()1265self.ids_vehs_merged_sumo[id_merge] = list()1266self.lineinds_vehs_merged[id_merge] = list()12671268self.vehicles_entries[id_merge] = OrderedDict()1269self.vehicles_mains[id_merge] = OrderedDict()12701271return [(self.time_update.get_value(), self.process_step),1272]12731274def process_step(self, process):1275simtime = process.simtime1276print 79*'_'1277print 'Mergenodes.process_step at', simtime1278net = self.get_scenario().net1279vehicles = self.parent.prtvehicles1280ids = self.get_ids()1281for id_merge, id_node, id_edge_out, ids_node_out, ids_veh_out_sumo, is_entry in\1282zip(ids,1283self.ids_node[ids],1284self.ids_merge_to_ids_edge_out_sumo[ids],1285self.ids_nodes_out[ids],1286self.ids_vehs_out_sumo[ids],1287self.are_entry[ids],1288):1289print ' '+60*'.'1290print ' process id_merge', id_merge, ',id_node', id_node, net.nodes.ids_sumo[id_node]12911292####1293debug = 0 # id_merge in [3,4]1294# debug = (id_merge==1)|('gneJ1' in net.nodes.ids_sumo[ids_node_out])#'gneJ29':#'gneJ1':1295#debug = debug | (id_merge==17)| ('gneJ29' in net.nodes.ids_sumo[ids_node_out])1296###12971298if debug > 0:1299print ' ids_vehs_merged_sumo', self.ids_vehs_merged_sumo[id_merge]13001301# check for new vehicle arrivals/departures1302ids_veh_sumo = set(traci.edge.getLastStepVehicleIDs(id_edge_out))13031304if debug:1305print ' ids_veh_sumo_prev=', ids_veh_out_sumo1306print ' ids_veh_sumo=', ids_veh_sumo13071308if ids_veh_out_sumo != ids_veh_sumo:13091310# attention, this is a list, not an array with numpy indexing1311#ids_veh_entered_sumo = list(ids_veh_sumo.difference(ids_veh_out_sumo))1312ids_veh_entered_sumo = get_entered_vehs(ids_veh_sumo, ids_veh_out_sumo)1313# this is an array1314ids_veh_entered = vehicles.get_ids_from_ids_sumo(ids_veh_entered_sumo)1315#ids_veh_left = vehicles.get_ids_from_ids_sumo(list(ids_veh_sumo_prev.difference(ids_veh_sumo)))1316if debug > 0:1317print ' ids_veh_entered', ids_veh_entered, type(ids_veh_entered)1318# print ' ids_veh_entered_sumo',ids_veh_entered_sumo1319# print ' ids_leader',vehicles.ids_leader[ids_veh_entered]13201321if ids_node_out is None:1322# the present merge is an end node example at a station1323ids_merge_out = []1324else:1325# determine id merge according to given output node1326ids_merge_out = self.ids_node_to_ids_merge[ids_node_out]1327# if debug>0:1328# print ' ids_node_out',ids_node_out1329# print ' ids_merge_out',ids_merge_out1330ids_edge_mergeout_sumo = self.ids_merge_to_ids_edge_out_sumo[ids_merge_out]13311332# merge only vehicle without a leader (individual or first in a platoon)1333inds_entered = np.flatnonzero(vehicles.ids_leader[ids_veh_entered] == -1)13341335if len(inds_entered) > 0:1336for ind_entered, id_veh in zip(inds_entered, ids_veh_entered[inds_entered]):13371338id_veh_sumo = ids_veh_entered_sumo[ind_entered]1339if debug > 0:1340print ' >>exiting vehicle', id_veh_sumo, 'is_leader', vehicles.ids_leader[id_veh] == -1, 'ids_node_out', ids_node_out, 'ids_merge_out', ids_merge_out13411342# print ' route_sumo',route_sumo13431344if ids_node_out is not None:1345if debug > 0:1346print ' check which out mergenode are on the current route of the vehicle'13471348# exit from previous merge1349# if debug:1350# print ' vehicle',id_veh_sumo,'exits id_merge',id_merge1351self.exit_veh(id_veh, id_veh_sumo, id_merge, vehicles)13521353if len(ids_merge_out) > 0:13541355# inform the respectine merges1356# then communicate vehicle with dist to merge1357# attention, we need the first hit in the route1358# check which downstream merge to enter1359route_sumo = get_traci_route(id_veh_sumo)13601361routeinds = [INFINT]*len(ids_merge_out)1362# print ' ids_merge_out',ids_merge_out1363i = 01364for id_edge_sumo in ids_edge_mergeout_sumo:13651366if id_edge_sumo in route_sumo:1367routeinds[i] = route_sumo.index(id_edge_sumo)1368i += 113691370mergeind = np.argmin(routeinds)13711372if debug > 0:1373print ' route_sumo', route_sumo1374print ' routeinds', routeinds, 'downstream merge', routeinds[mergeind] < INFINT1375print ' ids_edge_mergeout_sumo', ids_edge_mergeout_sumo1376print ' mergeind,routeinds', mergeind, routeinds1377print ' ids_merge_out[mergeind]', ids_merge_out[mergeind], ids_edge_mergeout_sumo[mergeind]13781379if routeinds[mergeind] < INFINT:1380if debug > 0:1381print ' merge %d is on the route is_entry' % (ids_merge_out[mergeind])1382if self.are_entry[ids_merge_out[mergeind]]:1383if debug > 0:1384print ' call enter_veh_entry'1385self.enter_veh_entry(1386id_veh, id_veh_sumo, id_merge, ids_merge_out[mergeind], ids_edge_mergeout_sumo[mergeind], vehicles, debug=debug)1387else:1388if debug > 0:1389print ' call enter_veh'1390self.enter_veh(1391id_veh, id_veh_sumo, id_merge, ids_merge_out[mergeind], ids_edge_mergeout_sumo[mergeind], vehicles, debug=debug)1392else:1393# no downstream merge, vehicle goes into a station1394pass1395else:1396# print ' ids_node_out is empty means that there is a station or compressor'1397pass13981399else:1400if debug:1401print ' ids_node_out is None means that there is a station or compressor'1402# shunt edges behind.1403# completely disconnect from all merge controlls1404# including ghosts14051406# exit from previous merge1407self.exit_veh(id_veh, id_veh_sumo, id_merge, vehicles)14081409# update vehicles on detection edge1410self.ids_vehs_out_sumo[id_merge] = ids_veh_sumo14111412# process special merge decisions and processes for entry merge types1413if is_entry:1414self.process_step_entry(id_merge, vehicles, debug)1415if 0:1416print '========check mergeprocess'1417for id_merge, id_node_sumo, ids_veh_merged_sumo, ids_veh_merged in\1418zip(ids,1419net.nodes.ids_sumo[self.ids_node[ids]],1420self.ids_vehs_merged_sumo[ids],1421self.ids_vehs_merged[ids]1422):14231424print ' ', id_merge, id_node_sumo, ids_veh_merged_sumo1425# print ' ids_veh_merged',ids_veh_merged14261427def exit_veh(self, id_veh, id_veh_sumo, id_merge_from, vehicles, is_remove_from_control=False, debug=0):1428print 'exit_veh id_veh %s, id_merge_from %d ' % (id_veh_sumo, id_merge_from), 'entry', self.are_entry[id_merge_from]1429# print ' check for platooned vehicles:'1430# vehicles.get_platoon(id_veh)1431# in id_merge_from: take vehicle out of merged queue and input queue14321433if id_veh in self.ids_vehs_merged[id_merge_from]:1434# enterd veh should be in pole position in merge queue of merge_from14351436# pop if vehicles are properly merged1437# id_veh_from = self.ids_vehs_merged[id_merge_from].pop()1438# self.ids_vehs_merged_sumo.ids_vehs_merged[id_merge_from].pop()1439# if id_veh_from != id_veh:1440# print 'WARNING in enter_veh: veh %d instead of veh %d in polepos of merge %d'%(id_veh_from,id_veh, id_merge_from)1441# return False1442# lineind = self.lineinds_vehs_merged[id_merge_from].pop()1443# for testing: just remove, no matter where1444ind_pos = self.ids_vehs_merged[id_merge_from].index(id_veh)1445lineind = self.lineinds_vehs_merged[id_merge_from][ind_pos]14461447if len(self.ids_vehs_merged[id_merge_from]) > ind_pos+1:1448# there is a vehicle behind=> remove ghost1449id_veh_behind = self.ids_vehs_merged[id_merge_from][ind_pos+1]1450id_veh_tail = vehicles.get_platoontail(id_veh) # get last in platoon1451vehicles.del_ghost(id_veh_behind, id_veh_tail)1452if debug > 0:1453print ' del ghost from veh', id_veh_behind, 'ghost', id_veh_tail1454print ' check ghosts:', vehicles.ids_ghosts[id_veh_behind]1455# is there a vehicle in fron of the removed vehicle1456# this happens if a vehicle is interactively deviated1457if ind_pos > 0:14581459id_veh_infront = self.ids_vehs_merged[id_merge_from][ind_pos-1]1460id_veh_tail = vehicles.get_platoontail(id_veh_infront) # get last in platoon14611462id_edge_mergeout_sumo = self.ids_merge_to_ids_edge_out_sumo[id_merge_from]1463dist_to_merge_behind = get_traci_distance(1464vehicles.get_id_sumo(id_veh_behind), id_edge_mergeout_sumo, 3.0)1465dist_to_merge_infront = get_traci_distance(1466vehicles.get_id_sumo(id_veh_infront), id_edge_mergeout_sumo, 3.0)1467# print ' now let the vehicle behind %d, d=%.2f'%(id_veh_behind,dist_to_merge_behind),'see the vehicle in front %d, d=%.2f'%(id_veh_infront,dist_to_merge_infront)14681469vehicles.add_ghost(id_veh_behind, id_veh_tail, dist_to_merge_behind, dist_to_merge_infront)14701471# remove any possible ghosts from this vehicle to vehicles behind1472# this can happen if this vehicle passed by its ghost vehicle1473vehicles.del_ghosts(id_veh)14741475self.ids_vehs_merged[id_merge_from].pop(ind_pos) # remove(id_veh)1476self.ids_vehs_merged_sumo[id_merge_from].pop(ind_pos) # remove(id_veh_sumo)1477self.lineinds_vehs_merged[id_merge_from].pop(ind_pos)1478if debug > 0:1479print ' vehicle has been on line index', lineind1480# remove vehicle from line buffers1481if lineind == 1:1482self.ids_vehs_in1[id_merge_from].remove(id_veh) # pop()1483self.ids_vehs_in1_sumo[id_merge_from].remove(id_veh_sumo) # .pop()1484if self.are_entry[id_merge_from]:1485if debug > 0:1486print ' vehicle is involved in entry merge processes?', self.vehicles_mains[id_merge_from].has_key(id_veh)1487if self.vehicles_mains[id_merge_from].has_key(id_veh):1488#1489#id_veh_entry = self.vehicles_mains[id_merge_from][id_veh]14901491# TODO: this is still a lousy method, vehicles_mains neds to be improved1492for id_veh_entry, state in zip(self.vehicles_entries[id_merge_from].keys(), self.vehicles_entries[id_merge_from].values()):1493#state = self.vehicles_entries[id_merge_from][id_veh_entry]1494# print ' state before',state1495if state.has_key('id_veh_infront'):1496if state['id_veh_infront'] == id_veh:1497del state['id_veh_infront']1498if state.has_key('id_veh_behind'):1499if state['id_veh_behind'] == id_veh:1500del state['id_veh_behind']1501# print ' state after',state15021503del self.vehicles_mains[id_merge_from][id_veh]15041505if lineind == 2:1506self.ids_vehs_in2[id_merge_from].remove(id_veh) # .pop()1507self.ids_vehs_in2_sumo[id_merge_from].remove(id_veh_sumo) # .pop()15081509if self.are_entry[id_merge_from]:1510if debug > 0:1511print ' del veh prt.%s from vehicles_entries' % id_veh1512del self.vehicles_entries[id_merge_from][id_veh]1513else:1514pass15151516# remove from centralized database1517del self.vehicle_to_merge[id_veh]15181519else:1520# the entered vehicle is not in a merge queue1521# probably a new vehicle at station15221523# just be sure that the vehicle is not in any queue1524# but actually this cannot happen1525if id_veh in self.ids_vehs_in1[id_merge_from]:1526print 'WARNING in exit_veh: new veh %d should not be in inqueue 1' % id_veh1527self.ids_vehs_in1[id_merge_from].remove(id_veh)1528self.ids_vehs_in1_sumo[id_merge_from].remove(id_veh_sumo)15291530if id_veh in self.ids_vehs_in2[id_merge_from]:1531print 'WARNING in exit_veh: new veh %d should not be in inqueue 2' % id_veh1532self.ids_vehs_in2[id_merge_from].remove(id_veh)1533self.ids_vehs_in2_sumo[id_merge_from].remove(id_veh_sumo)15341535if self.vehicle_to_merge.has_key(id_veh):1536del self.vehicle_to_merge[id_veh]15371538if is_remove_from_control:1539# remove any merge control operations1540vehicles.del_all_ghosts(id_veh)15411542def exit_veh_forced(self, id_veh, id_veh_sumo, vehicles):1543if self.vehicle_to_merge.has_key(id_veh):1544# exit vehicle from respective merge1545self.exit_veh(id_veh, id_veh_sumo, self.vehicle_to_merge[id_veh], vehicles, is_remove_from_control=True)1546else:1547# id_veh not under any merge conrol1548pass15491550def print_vehs(self, id_veh1, id_veh2, dist1_min, dist1_max, dist2_min, dist2_max,1551lineind1, lineind2, pos_max=79):1552dist_max = max(dist1_min, dist1_max, dist2_min, dist2_max)+11553#dist_min = min(dist1_min, dist1_max, dist2_min, dist2_max)1554#dist_diff = dist_max-dist_min+10.01555if np.all([dist1_min, dist1_max, dist2_min, dist2_max]) > 0:1556f = float(pos_max)/dist_max1557print '________________________'1558print 'vehicle %s from line %d: %.f--%2f' % (id_veh1, lineind1, dist1_min, dist1_max)1559pos_min = int(dist1_min*f)1560pos_max = int(dist1_max*f)1561print max(pos_min-1, 0)*' '+'<'+(pos_max-pos_min)*'X'+'|'15621563pos_min = int(dist2_min*f)1564pos_max = int(dist2_max*f)1565print max(pos_min-1, 0)*' '+'<'+(pos_max-pos_min)*'X'+'|'1566print 'vehicle %s from line %d: %.f--%2f' % (id_veh2, lineind2, dist2_min, dist2_max)1567print '________________________'1568else:1569print 'WARNING: some negative distances:'1570print 'vehicle %s from line %d: %.f--%2f' % (id_veh1, lineind1, dist1_min, dist1_max)1571print 'vehicle %s from line %d: %.f--%2f' % (id_veh2, lineind2, dist2_min, dist2_max)15721573def enter_veh(self, id_veh, id_veh_sumo, id_merge_from, id_merge_to, id_edge_merge_sumo, vehicles, debug=0):1574print 'enter_veh id_veh %s, id_merge_from %d to id_merge_to %d' % (id_veh_sumo, id_merge_from, id_merge_to)15751576# in id_merge_from: take vehicle out of merged queue and input queue15771578# put vehicle in centralized database1579self.vehicle_to_merge[id_veh] = id_merge_to15801581# on which input line of merge id_merge_to does the vehicle approach?1582if id_veh in self.ids_vehs_merged[id_merge_to]:1583# vehicle is in merge queue and input line can be retrived from it1584indpos = self.ids_vehs_merged[id_merge_to].index(id_veh)15851586# on which input line is the vehicle at position index indpos1587lineind = self.lineinds_vehs_merged[id_merge_to][indpos]15881589elif self.ids_node_to_ids_merge[self.ids_node_in1[id_merge_to]] == id_merge_from:1590# vehicle not in merge queue, detect input line 1 with nodes db1591indpos = -11592lineind = 11593else:1594# vehicle not in merge queue, detect input line 2 with nodes db1595indpos = -11596lineind = 215971598if lineind == 1:1599# from line 11600self.ids_vehs_in1[id_merge_to].append(id_veh)1601self.ids_vehs_in1_sumo[id_merge_to].append(id_veh_sumo)1602dist_tomerge_head_new = self.distances_node_in1[id_merge_to] # correct with pos16031604elif lineind == 2:1605self.ids_vehs_in2[id_merge_to].append(id_veh)1606self.ids_vehs_in2_sumo[id_merge_to].append(id_veh_sumo)1607dist_tomerge_head_new = self.distances_node_in2[id_merge_to] # correct with pos16081609if indpos == -1:1610# vehicle is new and must be merged into ids_vehs_merged1611if debug > 0:1612print ' merge veh %d arriving from in %d at dist %.2fm' % (id_veh, lineind, dist_tomerge_head_new)16131614ids_vehs_merged = self.ids_vehs_merged[id_merge_to]1615ids_vehs_merged_sumo = self.ids_vehs_merged_sumo[id_merge_to]1616lineinds_vehs_merged = self.lineinds_vehs_merged[id_merge_to]1617#id_edge_merge_sumo = self.ids_merge_to_ids_edge_out_sumo[id_merge_to]1618ind_insert = len(ids_vehs_merged)1619is_insert = False1620id_veh_merged = -116211622# print ' ids_vehs_merged_sumo[%d]'%id_merge_to,ids_vehs_merged_sumo1623# print ' lineinds_vehs_merged[%d]'%id_merge_to,lineinds_vehs_merged1624if (ind_insert == 0) | self.are_station[id_merge_to]:1625if debug > 0:1626print ' new vehicle is the only vehicle or station', ind_insert, self.are_station[id_merge_to]16271628# vehicles heading toward a station merge are not1629# really merged because only one incoming line1630ids_vehs_merged.append(id_veh)1631ids_vehs_merged_sumo.append(id_veh_sumo)1632lineinds_vehs_merged.append(lineind)16331634elif ind_insert > 0: # there is at least another vehicle1635# slower, but more precise than self.distances_node_inX[id_merge_to]1636#dist_tomerge_head_new2 = get_traci_distance(id_veh_sumo,id_edge_merge_sumo, 3.0)1637#dist_tomerge_tail_new = dist_tomerge_head_new-0.5/ get_traci_velocity(id_veh_sumo)**2+vehicles.lengths_plat[id_veh]1638#dist_tomerge_tail_new = dist_tomerge_head_new+vehicles.lengths_plat[id_veh]1639id_veh_tail_new = vehicles.get_platoontail(id_veh)1640id_veh_tail_new_sumo = vehicles.ids_sumo[id_veh_tail_new]1641dist_tomerge_tail_new = get_traci_distance(id_veh_tail_new_sumo, id_edge_merge_sumo, 3.0)1642if debug > 0:1643# print ' new veh %d arriving from in %d at dist head %.2f /__| tail %.2fm'%(id_veh,lineind,dist_tomerge_head_new,dist_tomerge_tail_new)1644print ' ids_vehs_merged_sumo', ids_vehs_merged_sumo1645for id_veh_merged, id_veh_merged_sumo in zip(ids_vehs_merged[::-1], ids_vehs_merged_sumo[::-1]):1646dist_tomerge_head = get_traci_distance(id_veh_merged_sumo, id_edge_merge_sumo, 3.0)1647#stoppeddist_tomerge = dist-0.5/self.decel*get_traci_velocity(id_veh_merged_sumo)**2+vehicles.lengths_plat[id_veh]1648#stoppeddist_tomerge = dist+vehicles.lengths_plat[id_veh]1649id_veh_tail = vehicles.get_platoontail(id_veh_merged)1650id_veh_tail_sumo = vehicles.ids_sumo[id_veh_tail]1651dist_tomerge_tail = get_traci_distance(id_veh_tail_sumo, id_edge_merge_sumo, 3.0)16521653if debug > 0:1654self.print_vehs(id_veh, id_veh_merged,1655dist_tomerge_head_new, dist_tomerge_tail_new,1656dist_tomerge_head, dist_tomerge_tail,1657lineind, lineinds_vehs_merged[ind_insert-1])1658# print ' check veh %d arriving from in %d at dist head %.2f /__| tail %.2fm'%(id_veh,lineind,dist_tomerge_head_new,dist_tomerge_tail_new)1659# print ' check veh %d, d %.2fm, d_new %.2fm, ind_insert = %d'%(id_veh_merged,dist,dist_tomerge_head_new,ind_insert)1660# print ' ds %.2fm, ds_new %.2fm, v %.2f, v_new =%.2fm, '%(stoppeddist_tomerge,dist_tomerge_tail_new,get_traci_velocity(id_veh_merged_sumo),get_traci_velocity(id_veh_sumo),)1661# print ' tail veh %d, ds %.2fm'%(id_veh_tail,dist_tomerge_tail)16621663if lineind == lineinds_vehs_merged[ind_insert-1]:1664is_insert = True1665break16661667if dist_tomerge_tail_new > dist_tomerge_tail:1668# distance to merge of this vehicle in queue is greater1669# than the new vehicle1670# inseri on copies? No break16711672# isert in fron of currently checked vehicle1673is_insert = True1674break1675dist_last = dist_tomerge_head1676ind_insert -= 116771678if is_insert:1679# at least one vehicle is in front1680if debug > 0:1681print ' insert veh %d behind veh %d, index %d' % (id_veh, id_veh_merged, ind_insert)1682# send control info to involved vehicles1683if ind_insert == len(ids_vehs_merged):1684if debug > 0:1685print ' appended vehicle after veh', id_veh_tail_sumo, 'with leader', ids_vehs_merged_sumo[ind_insert-1], 'dtm=%.2fm' % dist_tomerge_tail1686# V1687# |1688# G ind_insert-116891690# is vehicle and ghost in the same input line?1691if lineinds_vehs_merged[ind_insert-1] != lineind:1692# id_ghost = ids_vehs_merged[ind_insert-1]# last veh in queue1693#vehicles.add_ghost(id_veh, id_ghost, dist_tomerge_head_new, dist)16941695vehicles.add_ghost(id_veh, id_veh_tail, dist_tomerge_head_new, dist_tomerge_tail)16961697elif ind_insert > 0:1698# there is at least 1 other veh in front1699if debug > 0:1700print ' vehicle will be inserted in front of', ids_vehs_merged_sumo[ind_insert], 'and in behind', id_veh_tail_sumo, 'with leader', ids_vehs_merged_sumo[ind_insert-1], 'dtm=%.2fm' % dist_tomerge_tail1701# G11702# |1703# V1704# |1705# G21706id_ghost1 = ids_vehs_merged[ind_insert]1707#id_ghost2 = ids_vehs_merged[ind_insert-1]1708id_ghost2 = id_veh_tail17091710vehicles.del_ghost(id_ghost1, id_ghost2)1711if lineinds_vehs_merged[ind_insert] != lineind:1712vehicles.add_ghost(id_ghost1, id_veh_tail_new, dist_last, dist_tomerge_tail_new)17131714if lineinds_vehs_merged[ind_insert-1] != lineind:1715#vehicles.add_ghost(id_veh, id_ghost2, dist_tomerge_head_new, dist)1716vehicles.add_ghost(id_veh, id_ghost2, dist_tomerge_head_new, dist_tomerge_tail)17171718else:1719if debug > 0:1720print ' prepend veh %d in front of veh %d, first index %d' % (id_veh, id_veh_merged, ind_insert)1721# is vehicle and ghost in the same input line?1722if lineinds_vehs_merged[ind_insert] != lineind:1723id_veh_behind = ids_vehs_merged[ind_insert] # last veh in queue1724vehicles.add_ghost(id_veh_behind, id_veh_tail_new, dist_tomerge_head, dist_tomerge_tail_new)17251726# finally insert vehicle in merge queue1727ids_vehs_merged.insert(ind_insert, id_veh)1728ids_vehs_merged_sumo.insert(ind_insert, id_veh_sumo)1729lineinds_vehs_merged.insert(ind_insert, lineind)17301731# inform downstream merges17321733# else:1734# # new vehicle is the only vehicle1735# ids_vehs_merged[0] = id_veh1736# ids_vehs_merged_sumo[0] = id_veh_sumo1737# lineinds_vehs_merged[0] = lineind17381739def enter_veh_entry(self, id_veh, id_veh_sumo, id_merge_from, id_merge_to, id_edge_merge_sumo, vehicles, debug=0):1740print 'enter_veh_entry id_veh %s, id_merge_from %d to id_merge_to %d' % (id_veh_sumo, id_merge_from, id_merge_to)17411742# in id_merge_from: take vehicle out of merged queue and input queue17431744# put vehicle in centralized database1745self.vehicle_to_merge[id_veh] = id_merge_to17461747# on which input line of merge id_merge_to does the vehicle approach?1748if id_veh in self.ids_vehs_merged[id_merge_to]:1749# vehicle is in merge queue and input line can be retrived from it1750indpos = self.ids_vehs_merged[id_merge_to].index(id_veh)17511752# on which input line is the vehicle at position index indpos1753lineind = self.lineinds_vehs_merged[id_merge_to][indpos]17541755elif self.ids_node_to_ids_merge[self.ids_node_in1[id_merge_to]] == id_merge_from:1756# vehicle not in merge queue, detect input line 1 with nodes db1757indpos = -11758lineind = 11759else:1760# vehicle not in merge queue, detect input line 2 with nodes db1761indpos = -11762lineind = 217631764# put vehicle in respective line queue1765ids_vehs_merged = self.ids_vehs_merged[id_merge_to]1766ids_vehs_merged_sumo = self.ids_vehs_merged_sumo[id_merge_to]1767lineinds_vehs_merged = self.lineinds_vehs_merged[id_merge_to]17681769if lineind == 1:1770# from line 1 (main line)1771if debug > 0:1772print ' Detected veh', id_veh_sumo, 'on mainline. Is new', indpos == -11773print ' check for platooned vehicles:'1774vehicles.get_platoon(id_veh)17751776id_edge_out_sumo = self.ids_merge_to_ids_edge_out_sumo[id_merge_to]1777dist_tomerge = get_traci_distance(id_veh_sumo, id_edge_out_sumo, 3.0)1778ids_vehs_in1 = self.ids_vehs_in1[id_merge_to]1779if len(ids_vehs_in1) > 0:1780id_veh1_last = self.ids_vehs_in1[id_merge_to][-1]1781else:1782id_veh1_last = -117831784id_veh2, state2 = self.get_mergeveh_entry(id_merge_to)1785if id_veh2 == -1:1786# no vehicle to merge1787if id_veh1_last != -1:1788# make ghost to last vehicle1789#id_veh_tail = vehicles.get_platoontail(id_veh1_last)1790#id_veh_tail_sumo = vehicles.ids_sumo[id_veh_tail]1791#dist_tomerge_tail = get_traci_distance(id_veh_tail_sumo, id_edge_out_sumo, 3.0)1792#vehicles.add_ghost(id_veh, id_veh_tail, dist_tomerge, dist_tomerge_tail)17931794# let SUMO do the distances1795pass17961797else:1798# merge is empty1799pass18001801elif state2['status'] != 'wait':1802# there is an approaching vehicle on entry line1803if state2['status'] == 'accelerate':1804# vehicle in acceleration mode1805if state2.has_key('id_veh_behind'):1806# accelerating vehicle has already a vehicle1807# in front of which to merge1808# => look at last vehicle18091810# let SUMO do the distances1811pass18121813else:1814# let the entering vehicle see the new vehicle1815state2['id_veh_behind'] = id_veh18161817if state2['status'] == 'sync':1818if state2.has_key('id_veh_behind'):1819# accelerating vehicle has already a vehicle1820# in front of which to merge1821# => look at last vehicle18221823# let SUMO do the distances1824pass18251826else:1827# speed is already synchonized, but has not yet1828# a vehicle behind1829# let look the new vehicle look at1830# the tail of the entering vehicle1831id_veh_tail = vehicles.get_platoontail(id_veh2)1832id_veh_tail_sumo = vehicles.ids_sumo[id_veh_tail]1833dist_tomerge_tail = get_traci_distance(id_veh_tail_sumo, id_edge_out_sumo, 3.0)1834vehicles.add_ghost(id_veh, id_veh_tail, dist_tomerge, dist_tomerge_tail)18351836self.ids_vehs_in1[id_merge_to].append(id_veh)1837self.ids_vehs_in1_sumo[id_merge_to].append(id_veh_sumo)18381839# append to main merge queue1840ids_vehs_merged.append(id_veh)1841ids_vehs_merged_sumo.append(id_veh_sumo)1842lineinds_vehs_merged.append(lineind)18431844elif lineind == 2:1845# from line 2 (entry line)1846if debug > 0:1847print ' Detected veh', id_veh_sumo, 'on entry line. Is new', indpos == -118481849self.ids_vehs_in2[id_merge_to].append(id_veh)1850self.ids_vehs_in2_sumo[id_merge_to].append(id_veh_sumo)1851if debug > 0:1852print ' command vehicle to stop and wait further instructions'1853#vehicles.control_slow_down(id_veh, speed = 6.0/3.6)1854#traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)1855# print ' set speed to',traci.vehicle.getMaxSpeed(id_veh_sumo)1856#traci.vehicle.slowDown(id_veh_sumo, 13.0, 5.0)18571858vehicles.control_stop(id_veh)18591860# prevent SUMO from reaccelerating vehicle1861# vehicles.switch_off_control(id_veh)1862if debug > 0:1863print ' set veh id_veh prt.%d' % id_veh1864self.vehicles_entries[id_merge_to][id_veh] = {'status': 'wait'}1865if debug > 0:1866print ' vehicles_entries[', id_merge_to, ']=', self.vehicles_entries[id_merge_to]1867#1868# self.vehicles_mains[id_merge_to][id_veh] = {}# later when used18691870# Attention: Vehicle on entry line not yet in queue.1871# this needs to be fixed later when it becomes clear where to insert1872# ids_vehs_merged.append(id_veh)1873# ids_vehs_merged_sumo.append(id_veh_sumo)1874# lineinds_vehs_merged.append(lineind)18751876def get_mergeveh_entry(self, id_merge):1877"""Returns ID and state of vehicle that is about to merege from1878the entry line. ID is -1 if no vehicle starts.1879"""1880vehicles_entries = self.vehicles_entries[id_merge]1881if len(vehicles_entries) == 0:1882return -1, {'status': 'wait'}1883else:1884return vehicles_entries.keys()[0], vehicles_entries.values()[0]18851886def process_step_entry(self, id_merge, vehicles, debug):1887print 'process_step_entry id_merge', id_merge1888if debug > 0:1889print ' vehicles_entries=', self.vehicles_entries[id_merge]1890print ' vehicles_mains', self.vehicles_mains[id_merge]1891# print ' self.vehicles_entries',self.vehicles_entries1892#self.vehicles_entries[id_merge]= OrderedDict()1893# self.vehicles_mains[id_merge] = OrderedDict()1894id_veh_del = -118951896# for id_veh, state in zip(self.vehicles_entries[id_merge].keys()[::-1],self.vehicles_entries[id_merge].values()[::-1]):1897# for id_veh, state in self.vehicles_entries.iteritems():1898# for id_veh, state in zip(self.vehicles_entries[id_merge].keys(),self.vehicles_entries[id_merge].values()):1899ids_veh_entry = self.vehicles_entries[id_merge].keys()1900states_veh_entry = self.vehicles_entries[id_merge].values()1901id_edge_out_sumo = self.ids_merge_to_ids_edge_out_sumo[id_merge]1902ids_veh_in1 = self.ids_vehs_in1[id_merge]1903time_update = self.time_update.get_value()1904i = 01905#is_cont = len(ids_veh_entry)>01906# while is_cont:1907if len(ids_veh_entry) > 0:1908id_veh = ids_veh_entry[0]1909id_veh_sumo = vehicles.get_id_sumo(id_veh)1910state = states_veh_entry[0]19111912ids_vehs_merged = self.ids_vehs_merged[id_merge]1913ids_vehs_merged_sumo = self.ids_vehs_merged_sumo[id_merge]1914lineinds_vehs_merged = self.lineinds_vehs_merged[id_merge]1915if debug > 0:1916print ' check id_veh_sumo', id_veh_sumo, 'status', state['status'], 'n vehs on main', len(ids_veh_in1)1917if state['status'] == 'wait':1918if traci.vehicle.isStopped(id_veh_sumo):1919# check potential conflict vehicle on main line19201921n1 = len(ids_veh_in1)1922if n1 == 0:1923if debug > 0:1924print ' main line is empty => accelerate immediately'1925for id_veh_plat in vehicles.get_platoon(id_veh):1926vehicles.control_speedup(id_veh_plat)1927state['status'] = 'accelerate'19281929ids_vehs_merged.append(id_veh)1930ids_vehs_merged_sumo.append(id_veh_sumo)1931lineinds_vehs_merged.append(2)19321933else:1934ids_veh_in1_sumo = self.ids_vehs_in1_sumo[id_merge]1935vehicles_main = self.vehicles_mains[id_merge]1936dist_in1 = self.distances_node_in1[id_merge]1937dist_in2 = self.distances_node_in2[id_merge]19381939i = 0 # n1-11940is_found = False1941while (i < n1) & (not is_found):1942id_veh1_sumo = ids_veh_in1_sumo[i]1943id_veh1 = ids_veh_in1[i]1944if debug > 0:1945print ' check', id_veh1_sumo # ,'free',id_veh1 not in vehicles_main19461947if True: # id_veh1 not in vehicles_main:19481949# get tail position of id_veh_main1950id_veh1_tail = vehicles.get_platoontail(id_veh1)1951id_veh1_tail_sumo = vehicles.ids_sumo[id_veh1_tail]1952pos1 = dist_in1-get_traci_distance(id_veh1_sumo, id_edge_out_sumo, 3.0)1953pos1_tail = dist_in1-get_traci_distance(id_veh1_tail_sumo, id_edge_out_sumo, 3.0)1954pos2 = dist_in2 - get_traci_distance(id_veh_sumo, id_edge_out_sumo, 3.0)1955p_from, p_to = self.get_pos_crit_entry(pos2,1956vehicles.lengths_plat[id_veh],1957get_traci_velocity(id_veh1_sumo),1958dist_in1, dist_in2,1959vehicles)1960if debug > 0:1961print ' potential veh %s (tail %s)' % (id_veh1_sumo, id_veh1_tail_sumo), 'at pos1_tail=%.1f>p_to=%.1f' % (pos1_tail, p_to), pos1_tail > p_to19621963print ' i=%d, n1=%d' % (i, n1), 'last vehicle on main', i == n1-1, 'more', i < n1-119641965#self.print_vehs(id_veh1, id_veh2, dist1_min, dist1_max, dist2_min, dist2_max,lineind1, lineind2, pos_max = 79)19661967# here we check whether the tail of the vehicle on the main line1968# has passed the critical point p_to19691970if pos1_tail > p_to:19711972if i == n1-1: # last vehicle on main1973if debug > 0:1974print ' insert id_veh', id_veh_sumo, 'behind id_veh1', id_veh1_sumo, 'the only veh on main'1975state['id_veh_infront'] = id_veh11976vehicles_main[id_veh1] = id_veh # no, it does not get a ghost1977# vehicles_main[id_veh1] = { 'id_veh':id_veh,1978# 'delta':pos1_tail-p_to1979# }1980is_found = True1981ids_vehs_merged.append(id_veh)1982ids_vehs_merged_sumo.append(id_veh_sumo)1983lineinds_vehs_merged.append(2)19841985elif i < n1-1: # there are others behind on main1986# ensure that gap is big enough1987id_veh_behind = ids_veh_in1[i+1]1988id_veh_behind_sumo = vehicles.ids_sumo[id_veh_behind]1989pos1 = dist_in1 - get_traci_distance(id_veh_behind_sumo, id_edge_out_sumo, 3.0)1990if debug > 0:1991print ' vehicle behind', id_veh_behind_sumo, 'pos=%.1f, p_from=%.1f' % (pos1, p_from), 'ok', pos1 < p_from1992if pos1 < p_from:1993state['id_veh_infront'] = id_veh11994state['id_veh_behind'] = id_veh_behind19951996vehicles_main[id_veh_behind] = id_veh1997#vehicles_main[id_veh1] = { 'id_veh_infront':id_veh}1998is_found = True1999j = ids_vehs_merged.index(id_veh1)+12000# print ' j=',j2001ids_vehs_merged.insert(j, id_veh)2002ids_vehs_merged_sumo.insert(j, id_veh_sumo)2003lineinds_vehs_merged.insert(j, 2)20042005# here we check whether the vehicle on the main line2006# has not yet reached the critical point p_from2007elif pos1 < p_from:2008if i == 0: # first vehicle on main2009if debug > 0:2010print ' insert id_veh', id_veh_sumo, 'in front of id_veh1', id_veh1_sumo, 'the only veh on main'2011state['id_veh_behind'] = id_veh12012vehicles_main[id_veh1] = id_veh2013is_found = True2014# determine insert position2015j = ids_vehs_merged.index(id_veh1)2016# print ' j=',j2017ids_vehs_merged.insert(j, id_veh)2018ids_vehs_merged_sumo.insert(j, id_veh_sumo)2019lineinds_vehs_merged.insert(j, 2)20202021# elif i < n1-1: # there are others behind on main2022# # ensure that gap is big enough2023# id_veh_behind = ids_veh_in1[i+1]2024# id_veh_behind_sumo = vehicles.ids_sumo[id_veh_behind]2025# pos1 = dist_in1 - get_traci_distance(id_veh_behind_sumo, id_edge_out_sumo, 3.0)2026# print ' vehicle behind',id_veh_behind_sumo,'pos=%.1f, p_from=%.1f'%(pos1,p_from),'ok',pos1<p_from2027# if pos1<p_from:2028# state['id_veh_infront'] = id_veh12029# state['id_veh_behind'] = id_veh_behind2030# is_found = True20312032i += 120332034if is_found:2035if debug > 0:2036print ' suitable vehicle after which entry vehicle can run has been found'2037# Note: if no vehicle has been found then2038# nothing will happen and the vehicle will2039# wait until the righ moment has arrived2040for id_veh_plat in vehicles.get_platoon(id_veh):2041vehicles.control_speedup(id_veh_plat)2042state['status'] = 'accelerate'20432044else:2045if debug > 0:2046print ' nothing will happen and the vehicle will wait until the righ moment has arrived'20472048elif state['status'] == 'accelerate':2049# test if speed reached2050if traci.vehicle.getSpeed(id_veh_sumo) > 0.9*vehicles.speed_max:2051if debug > 0:2052print ' synchronization reached for veh', id_veh_sumo2053state['status'] = 'sync'2054#id_veh_del = id_veh2055# now create ghosts2056# id_veh -> id_veh_infront_tail:2057if state.has_key('id_veh_infront'):2058id_veh_in_front = state['id_veh_infront']2059id_veh_infront_tail = vehicles.get_platoontail(id_veh_in_front)2060id_veh_infront_tail_sumo = vehicles.ids_sumo[id_veh_infront_tail]2061dist_tomerge = get_traci_distance(id_veh_sumo, id_edge_out_sumo, 3.0)2062dist_tomerge_tail = get_traci_distance(id_veh_infront_tail_sumo, id_edge_out_sumo, 3.0)2063if debug > 0:2064print ' add ghost to entering veh', id_veh_sumo, ' behind', id_veh_infront_tail_sumo, 'with leader', id_veh_in_front2065vehicles.add_ghost(id_veh, id_veh_infront_tail, dist_tomerge,2066dist_tomerge_tail, is_substitute=True)20672068if state.has_key('id_veh_behind'):2069id_veh_behind = state['id_veh_behind']2070id_veh_behind_sumo = vehicles.ids_sumo[id_veh_behind]20712072dist_tomerge_behind = get_traci_distance(id_veh_behind_sumo, id_edge_out_sumo, 3.0)20732074id_veh_tail = vehicles.get_platoontail(id_veh)2075id_veh_tail_sumo = vehicles.ids_sumo[id_veh_tail]2076dist_tomerge_tail = get_traci_distance(id_veh_tail_sumo, id_edge_out_sumo, 3.0)2077# print ' add ghost to mainline veh',id_veh_behind_sumo,' behind',id_veh_tail_sumo,'with leader',id_veh_sumo2078vehicles.add_ghost(id_veh_behind, id_veh_tail, dist_tomerge_behind,2079dist_tomerge_tail, is_substitute=True)20802081else:2082if debug > 0:2083speed = traci.vehicle.getSpeed(id_veh_sumo)2084print ' sync of veh', id_veh_sumo, ',v=%.1f, not yet reached: %.2f' % (speed, speed/vehicles.speed_max)20852086if state.has_key('id_veh_behind'):2087id_veh_behind_sumo = vehicles.ids_sumo[state['id_veh_behind']]2088info = traci.vehicle.getLeader(id_veh_behind_sumo, dist=200.0)2089if (info is not None):2090# extract lead vehicle ID and distance from info2091id_leader_sumo, dist_leader = info2092#speed = vehicles.speed_max2093speed = get_traci_velocity(id_veh_behind_sumo)2094dist_safe = vehicles.tau*speed + 0.5*speed**2/vehicles.decel_emergency2095dist_target = 2*dist_safe+vehicles.lengths_plat[id_veh]2096if debug > 0:2097print ' behind', id_veh_behind_sumo, 'with infront', id_leader_sumo, 'at dist=%.2f' % dist_leader, 'at ds=%.2f' % dist_safe, 'is_brake', dist_leader < dist_target2098if dist_leader < dist_target:2099dv = time_update*vehicles.decel2100if (speed-dv) > 0:2101if debug > 0:2102print ' slowdown', id_veh_behind_sumo, 'from speed %.2f to %.2f' % (speed, speed-dv)2103traci.vehicle.slowDown(id_veh_behind_sumo, speed-dv, time_update)2104else:2105dv = time_update*vehicles.decel2106if debug > 0:2107print ' accel', id_veh_behind_sumo, 'from speed %.2f to %.2f' % (speed, speed+dv)2108traci.vehicle.slowDown(id_veh_behind_sumo, speed+dv, time_update)21092110elif state['status'] == 'sync':2111pass21122113# if id_veh_del > -1:2114# del self.vehicles_entries[id_merge][id_veh_del]21152116def get_pos_crit_entry(self, pos2, len_veh2, speed, dist1, dist2, vehicles):2117"""2118Returns critical position interval of vehicle-platoon on main line2119with respect to the starting position of a vehicle at entry line.2120The returned critical position interval(pos_from, pos_to), which should2121ideally be free of vehicles.2122pos_from refers to the position of the nose of a vehicle on the main line2123pos_to refers to the position of the tail of the platoon on the main line.21242125"""2126# print 'get_pos_crit_entry pos2=%.1f, v=%.1f, d1=%.1f, d2=%.1f'%(pos2, speed, dist1, dist2)2127# see 1910302128decel_emergency = vehicles.decel_emergency2129decel_comfort = vehicles.decel2130time_emergency = vehicles.tau2131s2 = 0.5*speed**2/decel_comfort2132delta2 = dist2 - pos2 - s221332134s1 = speed**2/decel_comfort2135s_safe = time_emergency*speed + 0.5*speed**2/decel_emergency2136p_to = dist1 - delta2 - s1 + s_safe2137p_from = p_to-len_veh2-2*s_safe2138# print ' delta2=%.1f, s2=%.1f, s1=%.1f, ss=%.1f, CI=(%.1f,%.1f)'%(delta2,s2,s1,s_safe,p_from,p_to)2139return p_from, p_to21402141def search_upstream_merge(self, id_edge_start, edges, lanes, id_prtmode, ids_mainline=set()):2142"""2143Searches next upstream merge node.2144Returns id_node, length to node21452146"""2147# print 'search_upstream_merge id_edge_start',id_edge_start2148length = edges.lengths[id_edge_start]2149is_merge = False2150id_edge_platform = -12151id_edge = id_edge_start2152while (not is_merge):2153ids_edge_incoming = edges.get_incoming(id_edge)21542155# print ' search id_edge,ids_edge_incoming',id_edge,ids_edge_incoming2156if len(ids_edge_incoming) == 2:2157#id_edge1, id_edge2 = ids_edge_to2158ids_lane1, ids_lane2 = edges.ids_lanes[ids_edge_incoming]2159#al1 = lanes.get_accesslevel(ids_lane1, id_prtmode)2160#al2 = lanes.get_accesslevel(ids_lane2, id_prtmode)2161# print ' check: '2162# print ' id_edge1',ids_edge_incoming[0],'ids_lane1',ids_lane1,self.is_prt_only(ids_lane1, lanes)2163# print ' id_edge2',ids_edge_incoming[1],'ids_lane2',ids_lane2,self.is_prt_only(ids_lane2, lanes)2164if self.is_prt_only(ids_lane1, lanes) & self.is_prt_only(ids_lane2, lanes):2165# print ' 2 in, one out => it is a merge node'2166is_merge = True21672168elif len(ids_edge_incoming) == 1:2169ids_lane = edges.ids_lanes[ids_edge_incoming[0]]2170#al = lanes.get_accesslevel(ids_lane, id_prtmode)2171if self.is_prt_only(ids_lane, lanes) & (id_edge in ids_mainline):2172# print ' mainline input node2173is_merge = True21742175if self.is_platform(ids_lane, lanes):2176# print ' 1 in, with multiple access => it is a station output node'2177is_merge = True21782179if not is_merge:2180id_edge = ids_edge_incoming[0]2181length += edges.lengths[id_edge]21822183# print ' id_edge,is_merge',id_edge,is_merge2184# print ' found node',edges.ids_fromnode[id_edge]2185return edges.ids_fromnode[id_edge], length21862187def search_downstream_merges(self, id_edge_start, edges, lanes, id_prtmode, ids_sinkedge=set()):2188"""2189Searches next downstream merge nodes.2190Returns array of downstream merge node IDs21912192"""21932194ids_edge = set([id_edge_start])2195ids_mergenode = set()2196# print 'search_downstream_merges id_edge_start',id_edge_start,'is sinkedge', id_edge_start in ids_sinkedge21972198if id_edge_start in ids_sinkedge:2199return None # np.array([], dtype = np.int32)22002201is_cont = True2202#n_cont = 202203while (len(ids_edge) > 0) & is_cont:2204# print ' len(ids_edge)',len(ids_edge),ids_edge2205ids_edge_new = set()22062207for id_edge in ids_edge:2208ids_edge_outgoing = edges.get_outgoing(id_edge)2209# print ' id_edge,ids_edge_outgoing',id_edge,ids_edge_outgoing2210for id_downedge in ids_edge_outgoing:2211ids_lane = edges.ids_lanes[id_downedge]2212if id_downedge in ids_sinkedge:2213# print ' sinkedge id_downedge',id_downedge2214pass22152216elif self.is_prt_only(ids_lane, lanes):2217ids_downedge_incoming = edges.get_incoming(id_downedge)2218# print ' id_downedge,ids_downedge_incoming',id_downedge,ids_downedge_incoming2219is_merge = False22202221if len(ids_downedge_incoming) == 2:2222ids_lane1, ids_lane2 = edges.ids_lanes[ids_downedge_incoming]2223#al1 = lanes.get_accesslevel(ids_lane1, id_prtmode)2224#al2 = lanes.get_accesslevel(ids_lane2, id_prtmode)2225# print ' check al1,al2',al1,al2,(al1 == 2) & (al2 == 2)2226# if (al1 == 2) & (al2 == 2):# real merges2227if self.is_prt_only(ids_lane1, lanes) & self.is_prt_only(ids_lane2, lanes):2228# print ' add mergenode',edges.ids_fromnode[id_downedge]2229ids_mergenode.add(edges.ids_fromnode[id_downedge])2230is_merge = True22312232if not is_merge: # len(ids_downedge_incoming) == 1:2233#ids_lane = edges.ids_lanes[ids_downedge_incoming]2234# if lanes.get_accesslevel(ids_lane1, id_prtmode) == 2:2235# print ' no merge detected, add edge',id_downedge2236ids_edge_new.add(id_downedge)22372238# else:2239# print 'WARNING in search_downstream_merges: edge %d has %d incoming edges.'%(id_downedge, len(ids_downedge_incoming))22402241ids_edge = ids_edge_new.copy()2242# print ' ids_edge_new',ids_edge_new,ids_edge,len(ids_edge)2243# is_cont = n_cont>0 #id_edge_start not in ids_edge2244#n_cont -= 122452246# if not is_cont:2247# print ' endless!!id_edge_start,ids_edge',id_edge_start,ids_edge2248# print ' found ids_mergenode',ids_mergenode2249return np.array(list(ids_mergenode), dtype=np.int32)22502251def is_prt_only(self, ids_lane, lanes):2252if len(ids_lane) > 1:2253return False2254else:2255if len(lanes.ids_modes_allow[ids_lane[0]]) > 0:2256return lanes.ids_modes_allow[ids_lane[0]][0] == self.parent.id_prtmode2257else:2258return False22592260def is_platform(self, ids_lane, lanes):2261if len(ids_lane) > 1:2262if len(lanes.ids_modes_allow[ids_lane[1]]) > 0:2263# we could also chech ped on lane 02264return lanes.ids_modes_allow[ids_lane[1]][0] == self.parent.id_prtmode2265else:2266return False2267else:2268return False226922702271class PrtBerths(am.ArrayObjman):22722273def __init__(self, ident, prtstops, **kwargs):2274# print 'PrtVehicles vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1')2275self._init_objman(ident=ident,2276parent=prtstops,2277name='PRT Berths',2278info='PRT Berths.',2279**kwargs)22802281self._init_attributes()22822283def _init_attributes(self):2284#vtypes = self.get_scenario().demand.vtypes2285net = self.get_scenario().net2286self.add(cm.AttrConf('length_default', 4.0,2287groupnames=['parameters', 'options'],2288name='Default length',2289info='Default berth length.',2290unit='m',2291))22922293self.add_col(am.IdsArrayConf('ids_prtstop', self.parent,2294name='PRT stop ID',2295info='PRT stop ID',2296))22972298# states now dynamic, see prepare_sim2299# if hasattr(self,'states'):2300# self.delete('states')2301# self.add_col(am.ArrayConf( 'states', default = BERTHSTATES['free'],2302# dtype = np.int32,2303# choices = BERTHSTATES,2304# name = 'state',2305# info = 'State of berth.',2306# ))23072308self.add_col(am.ArrayConf('stoppositions', default=0.0,2309dtype=np.float32,2310name='Stop position',2311info='Position on edge where vehicle nose stops.',2312))23132314def _init_constants(self):2315self.do_not_save_attrs([2316'states', 'ids_veh',2317])23182319def prepare_sim(self, process):2320# print 'PrtBerths.prepare_sim'2321ids = self.get_ids()2322if len(ids) == 0:2323return []2324self.states = BERTHSTATES['free']*np.ones(np.max(ids)+1, dtype=np.int32)2325self.ids_veh = -1*np.ones(np.max(ids)+1, dtype=np.int32)2326return [] # berth has no update function23272328def get_scenario(self):2329return self.parent.get_scenario()23302331def get_prtvehicles(self):2332return self.parent.parent.prtvehicles23332334def make(self, id_stop, position_from=None, position_to=None,2335n_berth=None,2336offset_firstberth=0.0, offset_stoppos=-0.0):2337stoplength = position_to-position_from2338# print 'Berths.make',id_stop,stoplength23392340# TODO: let define berth number either explicitely or through stoplength23412342length_berth = self.length_default.get_value()2343positions = position_from + offset_firstberth\2344+ np.arange(length_berth-offset_firstberth, stoplength+length_berth, length_berth) + offset_stoppos2345n_berth = len(positions)23462347# force number of berth to be pair2348if n_berth % 2 == 1:2349positions = positions[1:]2350n_berth -= 123512352ids_berth = self.add_rows(n=n_berth,2353stoppositions=positions,2354ids_prtstop=id_stop * np.ones(n_berth, dtype=np.int32),2355)2356return ids_berth23572358def set_prtvehicles(self, prtvehicles):2359"""2360Defines attributes which are linked with prtvehicles2361"""2362self.add_col(am.IdsArrayConf('ids_veh_allocated', prtvehicles,2363name='Alloc. veh ID',2364info='ID of vehicle which have allocated this berth. -1 means no allocation.',2365))236623672368class PrtPlatoonStops(am.ArrayObjman):2369"""2370This class is only for backwardscompatibility with some scenarios.2371Is to be depricated2372"""23732374def __init__(self, ident, prtservices, **kwargs):2375pass23762377def get_edges(self, ids_prtstop):2378net = self.get_scenario().net2379return net.lanes.ids_edge[net.ptstops.ids_lane[self.ids_ptstop[ids_prtstop]]]23802381def get_berths(self):2382return self.berths.get_value()23832384def get_scenario(self):2385return self.parent.get_scenario()23862387def set_prtvehicles(self, prtvehicles):2388self.get_berths().set_prtvehicles(prtvehicles)23892390def set_vehicleman(self, vehicleman):2391self.add(cm.ObjConf(vehicleman, is_child=False, groups=['_private']))23922393def get_vehicleman(self):2394return self.vehicleman.get_value()239523962397class PrtStops(am.ArrayObjman):2398def __init__(self, ident, prtservices, **kwargs):2399self._init_objman(ident=ident,2400parent=prtservices,2401name='PRT stops',2402info='Contains information on PRT stops.',2403#xmltag = ('additional','busStop','stopnames'),2404version=0.1,2405**kwargs)2406self._init_attributes()24072408def _init_attributes(self):2409self.add(cm.ObjConf(PrtBerths('berths', self)))24102411berths = self.get_berths()2412net = self.get_scenario().net24132414self.add(cm.AttrConf('time_update', 0.5,2415groupnames=['parameters'],2416name='Update time',2417info="Update time for station.",2418unit='s',2419))24202421self.add(cm.AttrConf('time_kickout', 30.0,2422groupnames=['parameters'],2423name='Kickout time',2424info="Time to kick out empty vehicles after vehicles behing have been occupied with passengers.",2425unit='s',2426))2427self.add(cm.AttrConf('timeconst_flow', 0.98,2428groupnames=['parameters'],2429name='Flow time const',2430info="Constant to update the moving average flow.",2431))24322433self.add(cm.AttrConf('stoplinegap', 12.0,2434groupnames=['parameters'],2435name='Stopline gap',2436unit='m',2437info="Distance between stopline, where vehicles get started, and the end of the lane.",2438))24392440if hasattr(self, 'time_update_man'):2441self.delete('time_update_man')2442self.delete('timehorizon')24432444self.add_col(am.IdsArrayConf('ids_ptstop', net.ptstops,2445name='ID PT stop',2446info='ID of public transport stop. ',2447))24482449if hasattr(self, 'are_depot'):2450self.delete('are_depot')24512452self.add_col(am.ArrayConf('types', default=STOPTYPES['person'],2453dtype=np.int32,2454perm='rw',2455choices=STOPTYPES,2456name='Type',2457info='Type of stop.',2458))24592460self.add_col(am.IdlistsArrayConf('ids_berth_alight', berths,2461#groupnames = ['_private'],2462name='Alight berth IDs',2463info="Alight berth IDs.",2464))24652466self.add_col(am.IdlistsArrayConf('ids_berth_board', berths,2467#groupnames = ['_private'],2468name='Board berth IDs',2469info="Board berth IDs.",2470))24712472# self.add_col(am.ArrayConf( 'inds_berth_alight_allocated', default = 0,2473# #groupnames = ['_private'],2474# dtype = np.int32,2475# perm = 'rw',2476# name = 'Ind aberth lastalloc',2477# info = 'Berth index of last allocated berth in alight zone.',2478# ))24792480# self.add_col(am.ArrayConf( 'inds_berth_board_allocated', default = 0,2481# #groupnames = ['_private'],2482# dtype = np.int32,2483# perm = 'rw',2484# name = 'Ind bberth lastalloc',2485# info = 'Berth index of last allocated berth in boarding zone.',2486# ))24872488def _init_constants(self):2489self.do_not_save_attrs([2490'ids_stop_to_ids_edge_sumo', 'ids_stop_to_ids_edge',2491'stoplines', 'ids_stop_to_ids_acceledge_sumo',2492'id_edge_sumo_to_id_stop', 'inds_berth_alight_allocated',2493'inds_berth_board_allocated', 'ids_vehs_alight_allocated',2494'ids_vehs_board_allocated', 'times_plat_accumulate',2495'ids_vehs_sumo_prev', 'ids_vehs',2496'ids_vehs_toallocate', 'times_lastboard',2497'numbers_veh', 'numbers_person_wait',2498'flows_person', 'ids_veh_lead',2499'ids_veh_lastdep', 'ids_vehs_prog',2500'ids_persons_sumo_prev', 'ids_persons_sumo_boarded',2501'waittimes_persons', 'waittimes_tot',2502'id_person_to_origs_dests',2503'ids_detectoredge_decompr'2504])25052506def get_edges(self, ids_prtstop):2507net = self.get_scenario().net2508return net.lanes.ids_edge[net.ptstops.ids_lane[self.ids_ptstop[ids_prtstop]]]25092510def get_berths(self):2511return self.berths.get_value()25122513def get_scenario(self):2514return self.parent.get_scenario()25152516def set_prtvehicles(self, prtvehicles):2517self.get_berths().set_prtvehicles(prtvehicles)25182519def set_vehicleman(self, vehicleman):2520self.add(cm.ObjConf(vehicleman, is_child=False, groups=['_private']))25212522def get_vehicleman(self):2523return self.vehicleman.get_value()25242525def get_closest(self, coords):2526"""2527Returns the closest prt stop for each coord in coords vector.2528"""2529net = self.get_scenario().net2530ptstops = net.ptstops2531lanes = net.lanes2532n = len(coords)2533# print 'get_closest',n25342535#ids_stop = self.get_ids()25362537ids_prtstop = self.get_ids()2538ids_ptstop = self.ids_ptstop[ids_prtstop]2539coords_stop = ptstops.centroids[ids_ptstop]2540ids_edge_stop = net.lanes.ids_edge[ptstops.ids_lane[ids_ptstop]]25412542inds_closest = np.zeros(n, dtype=np.int32)25432544i = 02545for coord in coords:2546ind_closest = np.argmin(np.sum((coord-coords_stop)**2, 1))2547inds_closest[i] = ind_closest2548i += 125492550ids_prtstop_closest = ids_prtstop[inds_closest]2551ids_edge_closest = ids_edge_stop[inds_closest]25522553return ids_prtstop_closest, ids_edge_closest25542555def get_waitpositions(self, ids, is_alight=False, offset=-0.0):2556"""2557Assign randomly a wait-position for each stop in ids25582559offset is wait position relative to the vehicle nose.2560"""2561# print 'get_waitpositions min(ids),max(ids)',min(ids),is_alight,max(ids),offset2562positions = np.zeros(len(ids), dtype=np.float32)2563randint = random.randint2564if is_alight:2565ids_berths = self.ids_berth_alight[ids]2566else:2567ids_berths = self.ids_berth_board[ids]25682569stoppositions = self.get_berths().stoppositions2570# print ' ids_berths',ids_berths2571i = 02572for id_stop, ids_berth in zip(ids, ids_berths):2573#ids_berth = ids_berths[id_stop]2574ind_berth = randint(0, len(ids_berth)-1)25752576positions[i] = stoppositions[ids_berth[ind_berth]]2577# print ' id_stop,ids_berth,posiions',id_stop,ids_berth,stoppositions[ids_berth[ind_berth]]2578i += 12579#positions[i] = stoppositions[ids_berth[randint(0,len(ids_berth))]]2580# for id_stop , pos in zip(ids, positions):2581# print ' id_stop %d, is_alight = %s, pos %.2fm'%(id_stop, is_alight ,pos)25822583return positions+offset25842585def prepare_sim(self, process):2586print 'PrtStops.prepare_sim'2587net = self.get_scenario().net2588ptstops = net.ptstops2589ids_edge_sumo = net.edges.ids_sumo25902591berths = self.get_berths()2592lanes = net.lanes2593ids_edge_sumo = net.edges.ids_sumo2594ids = self.get_ids()25952596if len(ids) == 0: # np PRT stops in network2597return []25982599get_outgoing = net.edges.get_outgoing26002601# station management2602self.ids_stop_to_ids_edge_sumo = np.zeros(np.max(ids)+1, dtype=np.object)2603self.ids_stop_to_ids_edge = np.zeros(np.max(ids)+1, dtype=np.int32)26042605ids_stopedge = lanes.ids_edge[ptstops.ids_lane[self.ids_ptstop[ids]]]2606# print ' ids,self.stoplines[ids]',ids,self.stoplines[ids]2607self.ids_stop_to_ids_edge_sumo[ids] = ids_edge_sumo[ids_stopedge]2608self.ids_stop_to_ids_edge[ids] = ids_stopedge26092610# Determine stopline position where vehicles actually start2611# running off the station26122613# final stop at one meter before end of stopedge2614self.stoplines = np.zeros(np.max(ids)+1, dtype=np.float32)2615stoplinegap = self.stoplinegap.get_value()2616#self.stoplines[ids] = net.edges.lengths[ids_stopedge]-12.02617#stoplengths = net.edges.lengths[ids_stopedge]2618for id_stop, ids_berth_board, length_stopedge in zip(ids, self.ids_berth_board[ids], net.edges.lengths[ids_stopedge]):2619lastberthstoppos = berths.stoppositions[ids_berth_board][-1]2620if (length_stopedge-lastberthstoppos) > stoplinegap+1:2621self.stoplines[id_stop] = length_stopedge-stoplinegap2622print ' LI:id_stop', id_stop, 'length_stopedge', length_stopedge, 'stopline', self.stoplines[id_stop]26232624elif length_stopedge > lastberthstoppos:2625self.stoplines[id_stop] = 0.5*(length_stopedge+lastberthstoppos)2626print ' AV:id_stop', id_stop, 'length_stopedge', length_stopedge, 'stopline', self.stoplines[id_stop]26272628self.ids_stop_to_ids_acceledge_sumo = np.zeros(np.max(ids)+1, dtype=np.object)2629for id_stop, id_stopedge in zip(ids, ids_stopedge):2630self.ids_stop_to_ids_acceledge_sumo[id_stop] = ids_edge_sumo[get_outgoing(id_stopedge)[0]]26312632self.id_edge_sumo_to_id_stop = {}2633for id_stop, id_edge_sumo in zip(ids, self.ids_stop_to_ids_edge_sumo[ids]):2634self.id_edge_sumo_to_id_stop[id_edge_sumo] = id_stop26352636self.inds_berth_alight_allocated = -1*np.ones(np.max(ids)+1, dtype=np.int32)2637self.inds_berth_board_allocated = -1*np.ones(np.max(ids)+1, dtype=np.int32)2638self.ids_vehs_alight_allocated = np.zeros(np.max(ids)+1, dtype=np.object)2639self.ids_vehs_board_allocated = np.zeros(np.max(ids)+1, dtype=np.object)26402641# time when last platoon vehicle accumulation started2642# -1 means no platoon accumulation takes place2643self.times_plat_accumulate = -1*np.ones(np.max(ids)+1, dtype=np.int32)26442645self.ids_vehs_sumo_prev = np.zeros(np.max(ids)+1, dtype=np.object)2646self.ids_vehs = np.zeros(np.max(ids)+1, dtype=np.object)2647self.ids_vehs_toallocate = np.zeros(np.max(ids)+1, dtype=np.object)2648#2649self.times_lastboard = 10**4*np.ones(np.max(ids)+1, dtype=np.int32)26502651# for vehicle management2652self.numbers_veh = np.zeros(np.max(ids)+1, dtype=np.int32)2653self.numbers_person_wait = np.zeros(np.max(ids)+1, dtype=np.int32)2654self.flows_person = np.zeros(np.max(ids)+1, dtype=np.float32)2655self.ids_veh_lead = -1*np.ones(np.max(ids)+1, dtype=np.int32)2656#self.ids_veh_lastdep = -1*np.ones(np.max(ids)+1,dtype = np.int32)2657self.ids_vehs_prog = np.zeros(np.max(ids)+1, dtype=np.object)26582659# person management2660self.ids_persons_sumo_prev = np.zeros(np.max(ids)+1, dtype=np.object)2661#self.ids_persons_sumo_boarded = np.zeros(np.max(ids)+1,dtype = np.object)2662self.waittimes_persons = np.zeros(np.max(ids)+1, dtype=np.object)2663self.waittimes_tot = np.zeros(np.max(ids)+1, dtype=np.float32)26642665virtualpop = self.get_scenario().demand.virtualpop26662667ids_persons = virtualpop.get_ids()2668stagelists = virtualpop.get_plans().stagelists2669prttransits = virtualpop.get_plans().get_stagetable('prttransits')2670id_person_to_origs_dests = {}26712672# create map from person id to various destination information2673# TODO: needs to be improved for trip chains, move to prtservices2674# idea: whu not scan prttransits?2675for id_person, stagelist in zip(ids_persons, stagelists[virtualpop.ids_plan[ids_persons]]):2676# print ' check dests of id_person',id_person2677for stages, id_stage in stagelist:2678if stages.ident == 'prttransits':2679id_fromedge_sumo = ids_edge_sumo[stages.ids_fromedge[id_stage]]2680id_toedge_sumo = ids_edge_sumo[stages.ids_toedge[id_stage]]2681data_orig_dest = (self.id_edge_sumo_to_id_stop[id_fromedge_sumo],2682self.id_edge_sumo_to_id_stop[id_toedge_sumo],2683id_fromedge_sumo,2684id_toedge_sumo)26852686id_person_sumo = virtualpop.get_id_sumo_from_id(id_person)2687if id_person_to_origs_dests.has_key(id_person_sumo):2688id_person_to_origs_dests[id_person_sumo].append(data_orig_dest)2689else:2690id_person_to_origs_dests[id_person_sumo] = [data_orig_dest]2691# print ' prtdests = ',id_person_to_origs_dests[id_person_sumo]26922693# print ' id_person_to_origs_dests=\n',id_person_to_origs_dests2694self.id_person_to_origs_dests = id_person_to_origs_dests26952696# this is only used for crazy person stage detection2697# angles_stop =26982699# various initianilizations2700for id_stop, id_edge_sumo in zip(ids, self.ids_stop_to_ids_edge_sumo[ids]):2701# set allocation index to last possible berth2702self.inds_berth_alight_allocated[id_stop] = len(self.ids_berth_alight[id_stop])2703self.inds_berth_board_allocated[id_stop] = len(self.ids_berth_board[id_stop])27042705self.ids_vehs_alight_allocated[id_stop] = []2706self.ids_vehs_board_allocated[id_stop] = []27072708self.ids_vehs_sumo_prev[id_stop] = set([])2709self.ids_persons_sumo_prev[id_stop] = set([])2710#self.ids_persons_sumo_boarded [id_stop] = []2711self.waittimes_persons[id_stop] = {}2712self.ids_vehs[id_stop] = []2713self.ids_vehs_toallocate[id_stop] = []27142715self.ids_vehs_prog[id_stop] = []27162717# decompressor detector edge set2718self.ids_detectoredge_decompr = set(self.parent.decompressors.ids_detectoredge.get_value())27192720# traci.edge.subscribe(id_edge_sumo, [traci.constants.VAR_ARRIVED_VEHICLES_IDS])2721updatedata_berth = berths.prepare_sim(process)27222723return [(self.time_update.get_value(), self.process_step),2724]+updatedata_berth27252726def process_step(self, process):2727simtime = process.simtime2728print 79*'_'2729print 'PrtStops.process_step at', simtime2730net = self.get_scenario().net2731ptstops = net.ptstops2732berths = self.get_berths()2733lanes = net.lanes2734ids_edge_sumo = net.edges.ids_sumo2735vehicles = self.parent.prtvehicles2736virtualpop = self.get_scenario().demand.virtualpop2737ids = self.get_ids()27382739for id_stop, id_edge_sumo, ids_veh_sumo_prev, ids_person_sumo_prev in\2740zip(ids, self.ids_stop_to_ids_edge_sumo[ids],2741self.ids_vehs_sumo_prev[ids],2742self.ids_persons_sumo_prev[ids]):2743print ' '+60*'.'2744print ' process id_stop,id_edge_sumo', id_stop, id_edge_sumo2745if 0: # id_stop==1:27462747# print ' ids_berth_alight',self.ids_berth_alight[id_stop]2748# print ' ids_berth_board',self.ids_berth_board[id_stop]2749print ' ids_vehs', self.ids_vehs[id_stop]2750print ' ids_vehs_toallocate', self.ids_vehs_toallocate[id_stop]2751print ' inds_berth_alight_allocated', self.inds_berth_alight_allocated[id_stop]2752print ' ids_vehs_alight_allocated', self.ids_vehs_alight_allocated[id_stop]2753print ' ids_vehs_board_allocated', self.ids_vehs_board_allocated[id_stop]2754# print ' id_veh_lead prt.%d'%self.ids_veh_lead[id_stop]2755# print ' ids_vehs_prog',self.ids_vehs_prog[id_stop]27562757print ' iiinds_berth_alight_allocated', self.inds_berth_alight_allocated[id_stop]2758print ' iiinds_berth_board_allocated', self.inds_berth_board_allocated[id_stop]2759# print ' numbers_person_wait',self.numbers_person_wait[id_stop]27602761# print ' flow_person',self.flows_person[id_stop]2762# print ' waittimes_persons',self.waittimes_persons[id_stop]27632764# print ' waittimes_tot',self.waittimes_tot[id_stop]27652766# no longer print ' ids_persons_sumo_boarded',self.ids_persons_sumo_boarded[id_stop]2767# print ' times_lastboard',self.times_lastboard[id_stop]27682769if 0:2770for id_veh_sumo in self.ids_vehs_sumo_prev[id_stop]:2771print ' stopstate ', id_veh_sumo, bin(traci.vehicle.getStopState(id_veh_sumo))[2:], traci.vehicle.getRoute(id_veh_sumo)27722773if 0:2774self.get_berthqueues(id_stop)27752776# check for new vehicle arrivals/departures2777ids_veh_sumo = set(traci.edge.getLastStepVehicleIDs(id_edge_sumo))2778# print ' ids_veh_sumo_prev=',ids_veh_sumo_prev2779# print ' ids_veh_sumo=',ids_veh_sumo27802781if ids_veh_sumo_prev != ids_veh_sumo:2782ids_veh_entered = vehicles.get_ids_from_ids_sumo(get_entered_vehs(ids_veh_sumo, ids_veh_sumo_prev))2783ids_veh_left = vehicles.get_ids_from_ids_sumo(list(ids_veh_sumo_prev.difference(ids_veh_sumo)))2784for id_veh in ids_veh_entered:2785self.enter(id_stop, id_veh)27862787for id_veh in ids_veh_left:2788self.exit(id_stop, id_veh)2789self.ids_vehs_sumo_prev[id_stop] = ids_veh_sumo2790# print ' ids_veh_sumo_entered',ids_veh_sumo_entered2791# print ' ids_veh_sumo_left',ids_veh_sumo_left27922793# check whether allocated vehicles arrived at alighting berths2794ids_veh_remove = []2795for id_veh in self.ids_vehs_alight_allocated[id_stop]:2796# TODO: here we could also check vehicle position2797# print ' isStopped',vehicles.get_id_sumo(id_veh),traci.vehicle.isStopped(vehicles.get_id_sumo(id_veh))2798if traci.vehicle.isStopped(vehicles.get_id_sumo(id_veh)):2799ids_veh_remove.append(id_veh)2800id_berth_alight = vehicles.ids_berth[id_veh]2801berths.ids_veh[id_berth_alight] = id_veh2802berths.states[id_berth_alight] = BERTHSTATES['alighting']2803vehicles.alight(id_veh)28042805for id_veh in ids_veh_remove:2806self.ids_vehs_alight_allocated[id_stop].remove(id_veh)28072808# check whether we can move vehicles from alighting to2809# boarding berths28102811# TODO: here we must check if berth in boarding zone are free2812# AND if they are occupied with empty vehicles, those2813# vehicles need to be kicked out...but only in case2814# new vehicles are waiting to be allocated28152816ids_berth_alight = self.ids_berth_alight[id_stop][::-1]2817ids_berth_board = self.ids_berth_board[id_stop][::-1]28182819if True: # len(self.ids_vehs_alight_allocated[id_stop])==0:2820# all vehicles did arrive in alight position28212822# identify berth and vehicles ready to forward to boarding2823ids_veh_forward = []2824ids_berth_forward = []2825has_not_arrived = False2826for id_berth_alight, id_veh in zip(2827ids_berth_alight,2828berths.ids_veh[ids_berth_alight],2829):2830# print ' check alight->board for veh prt.%d'%id_veh,'at berth',id_berth_alight,berths.states[id_berth_alight], berths.states[id_berth_alight]==BERTHSTATES['free']28312832if id_veh >= 0: # is there a waiting vehicle28332834# make sure, that there are no vehicles which are2835# allocated for alight in front of the present vehicle2836ind = self.ids_vehs[id_stop].index(id_veh)2837# print ' check alloc veh in front',self.ids_vehs[id_stop][:ind],self.ids_vehs_alight_allocated[id_stop]28382839if not set(self.ids_vehs[id_stop][:ind]).isdisjoint(self.ids_vehs_alight_allocated[id_stop]):2840# print ' allocated veh in front! Stop forwarding'2841break28422843elif vehicles.is_completed_alighting(id_veh):2844ids_veh_forward.append(id_veh)2845ids_berth_forward.append(id_berth_alight)2846else:2847# print ' vehicle has prt.%d not finished alighting...'%id_veh2848# stop allocating berth in board zone2849# to prevent allocations behind non-allocated vehicles2850break28512852n_veh_alloc = len(ids_veh_forward)28532854if n_veh_alloc > 0:28552856if self.inds_berth_board_allocated[id_stop] > n_veh_alloc:2857queues = self.get_berthqueues(id_stop)2858else:2859queues = None28602861# print ' found %d veh at id_stop=%d to berth alloc with board alloc index %d'%(n_veh_alloc,id_stop, self.inds_berth_board_allocated [id_stop])2862# if queues is not None:2863# print ' queues',queues2864for id_berth_alight, id_veh in zip(2865ids_berth_forward,2866ids_veh_forward,2867):28682869id_berth_board = self.allocate_board(id_stop, n_veh_alloc, queues)2870# print ' try allocate id_veh=prt.%d for berth id_berth_board=%d'%(id_veh,id_berth_board)2871if id_berth_board >= 0:2872# print ' send vehicle id_veh %d to id_berth_board %d'%(id_veh,id_berth_board)#,berths.stoppositions[id_berth_board]2873n_veh_alloc -= 12874berths.ids_veh[id_berth_alight] = -128752876berths.states[id_berth_alight] = BERTHSTATES['free']28772878vehicles.control_stop_board(id_veh, id_stop, id_berth_board,2879id_edge_sumo=self.ids_stop_to_ids_edge_sumo[id_stop],2880position=berths.stoppositions[id_berth_board],2881)2882self.ids_vehs_board_allocated[id_stop].append(id_veh)28832884# if all allocated vehicles found their berth and all berths are free, then2885# reset alight allocation index2886# print ' check for reset of alight allocation index',self.inds_berth_alight_allocated[id_stop], len(self.ids_vehs_alight_allocated[id_stop])==0, np.all(berths.states[ids_berth_alight]==BERTHSTATES['free'])28872888if (len(self.ids_vehs_alight_allocated[id_stop]) == 0) & np.all(berths.states[ids_berth_alight] == BERTHSTATES['free']):28892890# print ' reset inds_berth_alight_allocated',self.inds_berth_alight_allocated[id_stop],'->',len(self.ids_berth_alight[id_stop])2891self.inds_berth_alight_allocated[id_stop] = len(self.ids_berth_alight[id_stop])28922893# try to allocate unallocated vehicles2894ids_veh_remove = []2895for id_veh in self.ids_vehs_toallocate[id_stop]:2896id_berth = self.allocate_alight(id_stop)2897if id_berth < 0:2898# allocation failed2899# print ' do nothing, vehicle %d continues to wait for allocation'%id_veh2900pass2901else:2902# command vehicle to go to berth for alighting2903# print ' send waiting vehicle id_veh %d to id_berth_alight %d'%(id_veh,id_berth)#,berths.stoppositions[id_berth]2904self.parent.prtvehicles.control_stop_alight(id_veh, id_stop, id_berth,2905id_edge_sumo=self.ids_stop_to_ids_edge_sumo[id_stop],2906position=self.get_berths().stoppositions[id_berth],2907)2908self.ids_vehs_alight_allocated[id_stop].append(id_veh)2909ids_veh_remove.append(id_veh)29102911for id_veh in ids_veh_remove:2912self.ids_vehs_toallocate[id_stop].remove(id_veh)29132914# else:2915# if len(self.ids_vehs_toallocate[id_stop])>0:2916# print ' HUSTON: there are vehs to allocate but cannot reset berthind'2917# print ' ids_vehs_toallocate',vehicles.ids_sumo[self.ids_vehs_toallocate[id_stop]]2918# print ' ids_vehs_toallocate',vehicles.ids_sumo[self.ids_vehs_toallocate[id_stop]]2919# print ' self.ids_vehs_alight_allocated[id_stop]',self.ids_vehs_alight_allocated[id_stop]2920# print ' berths.ids_veh',berths.ids_veh[ids_berth_alight]2921# print ' berths.states[ids_berth_alight]',berths.states[ids_berth_alight]29222923# check whether allocated vehicles arrived at boarding berths2924ids_veh_remove = []2925for id_veh in self.ids_vehs_board_allocated[id_stop]:2926# TODO: here we could also check vehicle position2927if traci.vehicle.isStopped(vehicles.get_id_sumo(id_veh)):2928ids_veh_remove.append(id_veh)2929id_berth_board = vehicles.ids_berth[id_veh]2930berths.ids_veh[id_berth_board] = id_veh2931berths.states[id_berth_board] = BERTHSTATES['boarding']2932vehicles.board(id_veh,2933id_edge_sumo=self.ids_stop_to_ids_edge_sumo[id_stop])29342935self.parent.vehicleman.indicate_trip_empty(id_veh, id_stop, simtime)2936# vehicle could become potentially the lead vehicle2937self.try_set_leadveh(id_stop, id_veh)29382939for id_veh in ids_veh_remove:2940self.ids_vehs_board_allocated[id_stop].remove(id_veh)29412942# if all allocated vehicles for board area2943# found their berth and all berths are free, then2944# reset allocation index2945# print ' check for reset of board berth', (self.inds_berth_board_allocated[id_stop] == 0),(len(self.ids_vehs_board_allocated[id_stop])==0), np.all(berths.states[ids_berth_board]==BERTHSTATES['free'])2946if (self.inds_berth_board_allocated[id_stop] == 0) & (len(self.ids_vehs_board_allocated[id_stop]) == 0):29472948if np.all(berths.states[ids_berth_board] == BERTHSTATES['free']):2949# print ' reset inds_berth_board_allocated to',len(self.ids_berth_board[id_stop])2950self.inds_berth_board_allocated[id_stop] = len(self.ids_berth_board[id_stop])2951# else:2952# print ' unfree boarding zone',berths.states[ids_berth_board]2953else:2954# print ' no reset: ids_vehs_board_allocated',self.ids_vehs_board_allocated[id_stop]2955# print ' berths.ids_veh',berths.ids_veh[ids_berth_board]2956# print ' berths.states[ids_berth_alight]',berths.states[ids_berth_board]2957pass2958# check for new person entering/left the station edge2959ids_person_sumo = set(traci.edge.getLastStepPersonIDs(id_edge_sumo))29602961n_enter = 02962if ids_person_sumo_prev != ids_person_sumo:29632964if 0:2965print ' change\n id_person_sumo', ids_person_sumo2966print ' ids_person_sumo_prev', ids_person_sumo_prev2967# print ' dir(traci.person)',dir(traci.person)2968# for id_person_sumo in ids_person_sumo:2969# print ' id_person_sumo',id_person_sumo,traci.person.getRoadID(id_person_sumo),traci.person.getVehicle(id_person_sumo)29702971# deal with persons who left the edge2972# NEW: this is done later when loaded vehicles are investigated29732974#ids_person_sumo_left = ids_person_sumo_prev.difference(ids_person_sumo)2975# print ' ids_person_sumo_left',ids_person_sumo_left2976# for id_person_sumo in ids_person_sumo_left:2977# print ' id_person_sumo_left pers',id_person_sumo,id_edge_sumo,traci.person.getRoadID(id_person_sumo),traci.person.getVehicle(id_person_sumo)2978# #print ' ids_person_sumo',ids_person_sumo2979# # tricky: if the person who left the edge id_edge_sumo2980# # shows still id_edge_sumo then this person is in a vehicle2981# if traci.person.getRoadID(id_person_sumo) == id_edge_sumo:2982# #print ' person boarded: pers',id_person_sumo,traci.person.getLanePosition(id_person_sumo)2983# self.ids_persons_sumo_boarded[id_stop].append(id_person_sumo)2984# self.waittimes_tot[id_stop] -= simtime - self.waittimes_persons[id_stop][id_person_sumo]2985# del self.waittimes_persons[id_stop][id_person_sumo]2986# self.numbers_person_wait[id_stop] -= 129872988# deal with persons who entered the edge2989ids_person_sumo_entered = ids_person_sumo.difference(ids_person_sumo_prev)2990for id_person_sumo in ids_person_sumo_entered:2991# print ' entered id_person_sumo',id_person_sumo,traci.person.getRoadID(id_person_sumo)2992if self.id_person_to_origs_dests.has_key(id_person_sumo):2993id_edge_sumo_dests = self.id_person_to_origs_dests[id_person_sumo]2994# check if person still has a PRT trip29952996if len(id_edge_sumo_dests) > 0:2997# check if next trip has origin edge equal to edge of this stop2998if id_edge_sumo_dests[0][2] == id_edge_sumo:2999# print ' add to waittimes_persons',id_person_sumo3000self.waittimes_persons[id_stop][id_person_sumo] = simtime3001n_enter += 130023003# communicate person entry to vehman3004self.parent.vehicleman.note_person_entered(3005id_stop, id_person_sumo, id_edge_sumo_dests[0][1])30063007# else:3008# print 'WARNING: person %s starts with % insted of %s.'%(id_person_sumo,id_edge_sumo_dests[0][2],id_edge_sumo)30093010self.numbers_person_wait[id_stop] += n_enter3011self.ids_persons_sumo_prev[id_stop] = ids_person_sumo30123013self.waittimes_tot += self.numbers_person_wait*self.time_update.get_value()30143015timeconst_flow = self.timeconst_flow.get_value()3016self.flows_person[id_stop] = timeconst_flow*self.flows_person[id_stop] + \3017(1.0-timeconst_flow)*float(n_enter)/self.time_update.get_value()30183019if 0:3020for id_person_sumo in ids_person_sumo_prev:3021print ' ids_person_sumo=%s pos = %.2f ' % (id_person_sumo, traci.person.getLanePosition(id_person_sumo))3022# nomore print ' ids_persons_sumo_boarded',self.ids_persons_sumo_boarded[id_stop]30233024# check if boarding is completed in load area,3025# starting with last vehicle3026ids_berth_board = self.ids_berth_board[id_stop][::-1]3027for id_berth_board, id_veh in zip(3028ids_berth_board,3029berths.ids_veh[ids_berth_board],3030):3031if id_veh >= 0: # is there a waiting vehicle3032id_veh_sumo = vehicles.get_veh_if_completed_boarding(id_veh)3033if id_veh_sumo:3034id_person_sumo = self.init_trip_occupied(id_stop,3035id_berth_board,3036id_veh,3037id_veh_sumo,3038simtime)3039if id_person_sumo is not None:3040# do some statistics here3041self.waittimes_tot[id_stop] -= simtime - self.waittimes_persons[id_stop][id_person_sumo]3042del self.waittimes_persons[id_stop][id_person_sumo]3043self.numbers_person_wait[id_stop] -= 130443045# check if there are passengers in the vehicles which wait for3046# alight allocate3047# TODO: can be replaced by a single instruction3048n_pax = 03049for id_veh in self.ids_vehs_alight_allocated[id_stop]+self.ids_vehs_toallocate[id_stop]:3050if vehicles.states[id_veh] == VEHICLESTATES['occupiedtrip']:3051n_pax += 13052# print ' n_pax' ,n_pax3053# check whether to foreward vehicles in boarding berth30543055# no foreward if all berth are free occupied vehicles3056if np.all(berths.states[ids_berth_board] == BERTHSTATES['free']):3057# print ' foreward all occupied id_stop,ids_berth_board',id_stop,ids_berth_board3058#self.foreward_boardzone(id_stop, ids_berth_board)3059self.times_lastboard[id_stop] = 10**4 # reset clock if all are free30603061# foreward if there are passengers in unallocated vehicles3062elif (self.numbers_person_wait[id_stop] == 0) & (n_pax > 0):3063# passengers arriving, no persons waiting3064# kick out immediately3065self.foreward_boardzone(id_stop, ids_berth_board, simtime)30663067# elif (self.numbers_person_wait[id_stop]>0) & (n_pax>0) & (self.times_lastboard[id_stop] == 10**4):3068elif ((self.numbers_person_wait[id_stop] > 0) | (n_pax > 0)) & (self.times_lastboard[id_stop] == 10**4):3069# passengers arriving but still persons boarding3070# reset kick-out counter3071self.times_lastboard[id_stop] = simtime30723073elif simtime - self.times_lastboard[id_stop] > self.time_kickout.get_value():3074# print ' call foreward_boardzone timeout',process.simtime,self.times_lastboard[id_stop],process.simtime - self.times_lastboard[id_stop]3075self.foreward_boardzone(id_stop, ids_berth_board, simtime)30763077# check whether a programmed vehicle can be started3078if self.types[id_stop] == STOPTYPES['group']:3079self.start_vehicles_platoon(id_stop, process)3080else:3081self.start_vehicles(id_stop, process)30823083def start_vehicles(self, id_stop, process):3084print 'start_vehicles=\n', self.ids_vehs_prog[id_stop]3085i = 03086vehicles = self.parent.prtvehicles3087ids_vehs_prog = self.ids_vehs_prog[id_stop]3088for time_start, id_veh, id_stop_target, is_started in ids_vehs_prog:3089if process.simtime > time_start:3090if not is_started:3091id_veh_sumo = vehicles.get_id_sumo(id_veh)3092if traci.vehicle.isStopped(id_veh_sumo):3093# print ' route prt.%d from stop %d to %d'%(id_veh,id_stop, id_stop_target)3094route, duration = self.route_stop_to_stop(id_stop, id_stop_target)3095# print ' route prt.%d from %d to %d'%(id_veh,self.ids_stop_to_ids_edge[id_stop],self.ids_stop_to_ids_edge[id_stop_target]),route3096vehicles.reschedule_trip(id_veh,3097route_sumo=self.get_scenario().net.edges.ids_sumo[route]3098)3099ids_vehs_prog[i][3] = True3100#self.parent.prtvehicles.control_slow_down( id_veh, speed = 6.0/3.6)3101# print ' limit MaxSpeed',id_veh_sumo3102traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)3103i += 131043105def route_stop_to_stop(self, id_stop_from, id_stop_to):3106# route3107return self.parent.get_route(self.ids_stop_to_ids_edge[id_stop_from],3108self.ids_stop_to_ids_edge[id_stop_to]3109)31103111def start_vehicles_platoon(self, id_stop, process, timeout_platoon=40, n_platoon_max=8):3112# print 'start_vehicles_platoon id_stop, times_plat_accumulate',id_stop,self.times_plat_accumulate[id_stop]3113# print ' ids_vehs_prog=\n',self.ids_vehs_prog[id_stop]31143115if self.times_plat_accumulate[id_stop] < 0:3116# print ' accumulation has not even started'3117return31183119vehicles = self.parent.prtvehicles3120ids_vehs_prog = self.ids_vehs_prog[id_stop]3121inds_platoon = []3122i = 0 # len(ids_vehs_prog)3123id_veh_nextplatoon = -13124for time_start, id_veh, id_stop_target, is_started in ids_vehs_prog: # [::-1]:31253126if not is_started:3127if len(inds_platoon) == 0:3128# check if first vehicle in platoon is stopped3129if traci.vehicle.isStopped(vehicles.get_id_sumo(id_veh)):3130inds_platoon.append(i)3131else:3132break3133else:3134# append to platoon3135inds_platoon.append(i)31363137i += 131383139# print ' trigger platoon?', inds_platoon,len(inds_platoon),n_platoon_max,process.simtime - self.times_plat_accumulate[id_stop],timeout_platoon3140if len(inds_platoon) == 0:3141return31423143if (process.simtime - self.times_plat_accumulate[id_stop] > timeout_platoon)\3144| (len(inds_platoon) >= n_platoon_max):31453146# platoon release triggered3147self._trigger_platoon(id_stop, inds_platoon)31483149def get_decompressoredge(self, route):3150"""3151Returns first occurance of a decompressoredge edge route from3152id_stop to id_stop_target.3153Returns -1 if nor decompressoredge is found.3154"""3155# print 'get_decompressoredge route',route3156# print ' self.ids_detectoredge_decompr',self.ids_detectoredge_decompr3157set_detectoredge = self.ids_detectoredge_decompr.intersection(set(route))3158# print ' set_detectoredge',set_detectoredge3159if len(set_detectoredge) == 0:3160return -13161else:3162#ids_detectoredge = list(set_detectoredge)3163id_detectoredge_first = -13164ind_min = 10**83165for id_detectoredge in set_detectoredge:3166if route.index(id_detectoredge) < ind_min:3167id_detectoredge_first = id_detectoredge3168return id_detectoredge_first31693170def _trigger_platoon(self, id_stop, inds_platoon):3171# print 'trigger_platoon inds_platoon',inds_platoon3172ids_vehs_prog = self.ids_vehs_prog[id_stop]3173vehicles = self.parent.prtvehicles31743175self.times_plat_accumulate[id_stop] = -131763177time_start_pre, id_veh_pre, id_stop_target_pre, is_prog_pre = ids_vehs_prog[inds_platoon[0]]3178vehicles.reschedule_trip(id_veh_pre, self.ids_stop_to_ids_edge_sumo[id_stop_target_pre])3179#self.parent.prtvehicles.control_slow_down( id_veh_pre, speed = 6.0/3.6)3180id_veh_pre_sumo = vehicles.get_id_sumo(id_veh_pre)31813182traci.vehicle.setMaxSpeed(id_veh_pre_sumo, 6.0/3.6)31833184ids_vehs_prog[inds_platoon[0]][3] = True3185# one vehicle platoon, no followers3186if len(inds_platoon) > 1:3187# try to concatenate followers31883189# search first detectoredge in route3190route_pre, traveltime = self.route_stop_to_stop(id_stop, id_stop_target_pre)3191id_detectoredge_pre = self.get_decompressoredge(route_pre)31923193for i in xrange(1, len(inds_platoon)):3194#time_start_pre, id_veh_pre, id_stop_target_pre, is_prog_pre = ids_vehs_prog[inds_platoon[i-1]]3195time_start, id_veh, id_stop_target, is_prog = ids_vehs_prog[inds_platoon[i]]3196route, traveltime = self.route_stop_to_stop(id_stop, id_stop_target)3197id_detectoredge = self.get_decompressoredge(route)3198id_veh_sumo = vehicles.get_id_sumo(id_veh)31993200# print ' check prt.%d'%ids_vehs_prog[inds_platoon[i]][1],'with leader prt.%d'%ids_vehs_prog[inds_platoon[i-1]][1],'same target',id_stop_target == id_stop_target_pre32013202# print ' route',route,'route_pre',route_pre3203# print ' id_detectoredge',id_detectoredge,'id_detectoredge_pre',id_detectoredge_pre3204# if id_stop_target == id_stop_target_pre:32053206# for platooning either same decompressor or same target3207if ((id_detectoredge == id_detectoredge_pre) & (id_detectoredge_pre != -1))\3208| (id_stop_target == id_stop_target_pre):3209# check also if leader stands immediately in from of follower32103211info = traci.vehicle.getLeader(id_veh_sumo, dist=10.0)3212# print ' check vehicle in front info',info3213if info is not None:3214id_veh_pre_sumo, dist = info3215if dist < 5.0:3216# print ' concatenate',id_veh,'with',id_veh_pre3217self.parent.prtvehicles.concatenate(id_veh, id_veh_pre)32183219# schedule and tell that vehicle has been scheduled3220self.parent.prtvehicles.reschedule_trip(id_veh, self.ids_stop_to_ids_edge_sumo[id_stop_target])3221ids_vehs_prog[inds_platoon[i]][3] = True32223223id_detectoredge_pre = id_detectoredge3224route_pre = route3225#time_start_pre = time_start3226id_veh_pre = id_veh3227id_stop_target_pre = id_stop_target3228#is_prog_pre = is_prog32293230# print ' limit MaxSpeed',id_veh_sumo3231traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)3232#self.parent.prtvehicles.control_slow_down( id_veh, speed = 6.0/3.6)32333234def try_set_leadveh(self, id_stop, id_veh):32353236if self.ids_veh_lead[id_stop] >= 0:3237# print 'try_set_leadveh leader already defined',id_stop,id_veh,self.ids_veh_lead[id_stop]3238return False3239else:3240ind_queue = self.ids_vehs[id_stop].index(id_veh)3241# print 'try_set_leadveh id_stop, id_veh,ind_queue',id_stop, 'prt.%d'%id_veh,ind_queue,len(self.ids_vehs[id_stop]),len(self.ids_vehs_prog[id_stop])32423243if ind_queue == 0: # len(self.ids_vehs[id_stop])-1:3244# print ' id_veh is new leader because last position',self.ids_vehs[id_stop].index(id_veh)3245# print ' ids_vehs',self.ids_vehs[id_stop]3246self.set_leadveh(id_stop, id_veh)3247return True32483249elif len(self.ids_vehs_prog[id_stop]) == ind_queue:3250# print ' id_veh is new leader because all vehicles in front are already programmed'3251self.set_leadveh(id_stop, id_veh)3252return True3253# elif len(self.ids_vehs_prog[id_stop])>0:3254# if (self.ids_vehs[id_stop][ind_queue-1] == self.ids_vehs_prog[id_stop][-1][1]) :3255# print ' id_veh is new leader because next vehicle %d is programmed'%(self.ids_vehs[id_stop][ind_queue-1],)3256# self.set_leadveh(id_stop, id_veh)3257# return True3258# else:3259# return False32603261else:3262return False32633264def set_leadveh(self, id_stop, id_veh):3265# print 'set_leadveh id_stop=%d, prt.%d'%( id_stop,id_veh)3266self.ids_veh_lead[id_stop] = id_veh32673268def program_leadveh(self, id_stop, id_veh, id_stop_target, time_start):3269# print 'program_leadveh prt.%d from id_stop %d to id_stop_target %d at %d'%(id_veh, id_stop,id_stop_target,time_start),'check leader',id_veh == self.ids_veh_lead[id_stop]32703271# check also if occupied in the meanwhile?? need to know emptytrip or not...3272if id_veh == self.ids_veh_lead[id_stop]:3273# check in vehman:if self.parent.prtvehicles.is_still_empty(id_veh):32743275if self.parent.prtvehicles.states[id_veh] == VEHICLESTATES['boarding']:3276id_berth_board = self.parent.prtvehicles.ids_berth[id_veh]3277self.init_trip_empty(id_stop, id_berth_board, id_veh, time_start, is_ask_vehman=False)32783279self.ids_veh_lead[id_stop] = -132803281# format for programmed vehicle list:3282# [time_start, id_veh, id_stop_target,is_started]3283self.ids_vehs_prog[id_stop].append([time_start, id_veh, id_stop_target, False])32843285if self.types[id_stop] == STOPTYPES['group']:3286# in platoon mode...3287# set a stop for this vehicle if there are only started, programmed3288# vehicles in front , or no vehicle32893290# check if this vehicle needs to stop in front of the stopline3291# in order to hold up other vehicles in the platoon3292# print ' check stopline',len(self.ids_vehs_prog[id_stop])3293# print ' ids_vehs_prog ',self.ids_vehs_prog[id_stop]3294is_stop = True3295for i in range(len(self.ids_vehs_prog[id_stop])-2, -1, -1):3296# print ' check prt.%d'%self.ids_vehs_prog[id_stop][i][1],'started',self.ids_vehs_prog[id_stop][i][3]3297if not self.ids_vehs_prog[id_stop][i][3]: # is already started3298is_stop = False3299break33003301if is_stop:3302# make this vehicle stop at stopline and reset platoon timer3303self.parent.prtvehicles.set_stop(3304id_veh, self.ids_stop_to_ids_edge_sumo[id_stop], self.stoplines[id_stop])3305self.times_plat_accumulate[id_stop] = time_start33063307# try make previous vehicle the lead vehicle3308ind_queue = self.ids_vehs[id_stop].index(id_veh)3309# print ' ids_vehs',self.ids_vehs[id_stop]3310# print ' ind_queue,queuelen,ok',ind_queue,len(self.ids_vehs[id_stop]),len(self.ids_vehs[id_stop]) > ind_queue+13311if len(self.ids_vehs[id_stop]) > ind_queue+1:3312id_veh_newlead = self.ids_vehs[id_stop][ind_queue+1]3313# print ' id_veh_newlead, state',id_veh_newlead, self.parent.prtvehicles.states[id_veh_newlead]3314if self.parent.prtvehicles.states[id_veh_newlead] in LEADVEHICLESTATES:3315self.set_leadveh(id_stop, id_veh_newlead)33163317# print ' new lead veh prt.%d'%(self.ids_veh_lead[id_stop],)3318return True33193320else:3321print ' no leader prt.%d exists' % (id_veh,)3322return False33233324def init_trip_occupied(self, id_stop, id_berth, id_veh, id_veh_sumo, simtime):3325# TODO: actually a berth method??3326berths = self.get_berths()33273328#id_veh_sumo = self.parent.prtvehicles.get_id_sumo(id_veh)3329n_pax = traci.vehicle.getPersonNumber(id_veh_sumo)3330# print 'init_trip_occupied', id_stop, id_berth, 'veh=%s'%id_veh_sumo,'simtime',simtime,'n_pax',n_pax33313332# identify whic of the boarding persons is in the3333# vehicle which completed boarding3334dist_min = np.inf3335id_person_sumo_inveh = None3336stoppos = berths.stoppositions[id_berth]33373338for id_person_sumo in self.ids_persons_sumo_prev[id_stop]:3339# print ' check veh of person',id_person_sumo,traci.person.getVehicle(id_person_sumo),id_veh_sumo33403341# here we check whether person id_person_sumo at stop id_stop3342# is already sitting in vehicle id_veh_sumo3343if traci.person.getVehicle(id_person_sumo) == id_veh_sumo:3344id_person_sumo_inveh = id_person_sumo33453346#d = abs(stoppos - traci.person.getLanePosition(id_person_sumo))3347# if d<dist_min:3348# dist_min = d3349# id_person_sumo_inveh = id_person_sumo33503351if id_person_sumo_inveh is not None:3352print ' found person %s in veh %s' % (id_person_sumo_inveh, id_veh_sumo)33533354# program vehicle to person's destination3355# print ' found person,origs_dests',id_person_sumo_inveh,self.id_person_to_origs_dests[id_person_sumo_inveh]3356id_stop_orig, id_stop_dest, id_edge_sumo_from, id_edge_sumo_to = \3357self.id_person_to_origs_dests[id_person_sumo_inveh].pop(0)3358# print ' found person', id_person_sumo_inveh,'from', id_stop_orig, id_edge_sumo_from,' to' , id_edge_sumo_to, id_stop_dest33593360stopline = self._get_stopline(id_stop, simtime)3361# print ' simtime', simtime33623363self.parent.prtvehicles.init_trip_occupied(3364id_veh, self.ids_stop_to_ids_edge_sumo[id_stop],3365stopline,3366)33673368# self.ids_persons_sumo_boarded[id_stop].remove(id_person_sumo_inveh)3369self.times_lastboard[id_stop] = simtime3370berths.states[id_berth] = BERTHSTATES['free']3371berths.ids_veh[id_berth] = -13372# self.ids_vehs_outset[id_stop].add(id_veh)3373self.try_set_leadveh(id_stop, id_veh)3374self.parent.vehicleman.init_trip_occupied(id_veh, id_stop, id_stop_dest, simtime)3375return id_person_sumo_inveh33763377else:3378print 'WARNING: on stop %d edge %s, berth %d no person found inside vehicle prt.%d' % (id_stop, self.ids_stop_to_ids_edge_sumo[id_stop], id_berth, id_veh)3379return None33803381def _get_stopline(self, id_stop, simtime):3382if self.types[id_stop] == STOPTYPES['group']:3383# print ' platooning...',id_stop,simtime3384if self.times_plat_accumulate[id_stop] < 0: # len(self.ids_vehs_prog[id_stop]) == 0:3385# print ' first in platoon-> stop it at exit-line',simtime3386#stopline = self.stoplines[id_stop]3387# actually not clear who will arrive first at the stopline3388# therefore do not stop. Stop must be set duruing rescheduling3389stopline = None3390self.times_plat_accumulate[id_stop] = simtime3391# print ' times_plat_accumulate',self.times_plat_accumulate[id_stop],simtime3392else:3393# print ' not first, let it approach previous veh.'3394stopline = None33953396else:3397# print ' no platooning: all vehicles stop and wait for start'3398stopline = self.stoplines[id_stop]3399# print ' times_plat_accumulate',self.times_plat_accumulate[id_stop],'simtime',simtime3400# print ' stopline',stopline3401return stopline34023403def init_trip_empty(self, id_stop, id_berth, id_veh, simtime, is_ask_vehman=True):3404# print 'Stops.init_trip_empty id_stop, id_berth, id_veh, is_ask_vehman', id_stop, id_berth, 'prt.%d'%id_veh, is_ask_vehman,'simtime',simtime3405# TODO: actually a berth method??3406berths = self.get_berths()34073408berths.states[id_berth] = BERTHSTATES['free']3409berths.ids_veh[id_berth] = -134103411# print ' proceed to stopline',self.stoplines[id_stop]3412stopline = self._get_stopline(id_stop, simtime)3413self.parent.prtvehicles.init_trip_empty(3414id_veh,3415self.ids_stop_to_ids_edge_sumo[id_stop],3416stopline)34173418if is_ask_vehman:3419self.try_set_leadveh(id_stop, id_veh)3420#id_stop_target = self.parent.vehicleman.init_trip_empty(id_veh, id_stop)3421self.parent.vehicleman.init_trip_empty(id_veh, id_stop, simtime)34223423# print 'init_trip_empty for',id_veh,' from',id_stop,'to',id_stop_target,id_edge_sumo_target3424#self.parent.prtvehicles.init_trip_empty(id_veh, self.ids_stop_to_ids_edge_sumo[id_stop_target])34253426# else:3427# self.parent.prtvehicles.init_trip_empty(id_veh, self.ids_stop_to_ids_edge_sumo[id_stop], -1)34283429# self.ids_vehs_outset[id_stop].add(id_veh)34303431def foreward_boardzone(self, id_stop, ids_berth_board, simtime):3432print 'foreward_boardzone', id_stop, ids_berth_board, 'simtime', simtime3433berths = self.get_berths()3434#ids_berth_board = self.ids_berth_board[id_stop][::-1]3435# inds_o berths.states[ids_berth_board] != BERTHSTATES['free']3436for id_berth, state in zip(ids_berth_board, berths.states[ids_berth_board]):3437# print ' id_berth,boarding?,id_veh',id_berth, state== BERTHSTATES['boarding'],berths.ids_veh[id_berth]3438if state == BERTHSTATES['boarding']:3439self.init_trip_empty(id_stop, id_berth, berths.ids_veh[id_berth], simtime)34403441self.times_lastboard[id_stop] = 10**4 # reset last board counter34423443def enter(self, id_stop, id_veh):3444print 'enter id_stop, id_veh', id_stop, 'prt.%d' % id_veh34453446self.parent.prtvehicles.decatenate(id_veh)34473448self.ids_vehs[id_stop].append(id_veh)34493450# tell vehman that veh arrived3451#self.numbers_veh_arr[id_stop] -= 13452self.parent.vehicleman.conclude_trip(id_veh, id_stop)34533454self.numbers_veh[id_stop] += 13455id_berth = self.allocate_alight(id_stop)3456if id_berth < 0:3457# print ' allocation failed, command vehicle to slow down and wait for allocation'3458self.ids_vehs_toallocate[id_stop].append(id_veh)3459self.parent.prtvehicles.control_slow_down(id_veh)3460else:3461# command vehicle to go to berth for alighting3462id_veh_sumo = self.parent.prtvehicles.ids_sumo[id_veh] # for debug only3463# print ' id_veh_sumo',id_veh_sumo3464#pos = traci.vehicle.getLanePosition(id_veh_sumo)3465if 0:3466print ' send entering vehicle id_veh %d, pos=%.2f to id_berth_alight %d at pos %.2fm' % (id_veh, traci.vehicle.getLanePosition(id_veh_sumo), id_berth, self.get_berths().stoppositions[id_berth])3467print ' ids_ghost', self.parent.prtvehicles.ids_ghosts[id_veh]3468print ' ids_leader', self.parent.prtvehicles.ids_leader[id_veh]3469print ' ids_follower', self.parent.prtvehicles.ids_follower[id_veh]34703471self.parent.prtvehicles.control_stop_alight(id_veh, id_stop, id_berth,3472id_edge_sumo=self.ids_stop_to_ids_edge_sumo[id_stop],3473position=self.get_berths().stoppositions[id_berth],3474)3475self.ids_vehs_alight_allocated[id_stop].append(id_veh)34763477def exit(self, id_stop, id_veh):3478# print 'exit prt.%d at stop %d'%(id_veh,id_stop)3479self.ids_vehs[id_stop].remove(id_veh)3480#id_stop_target = self.parent.vehicleman.start_trip(id_veh, id_stop)3481#self.parent.prtvehicles.reschedule_trip(id_veh, self.ids_stop_to_ids_edge_sumo[id_stop_target])3482#ind_veh = -13483# print ' ids_vehs_prog=\n',self.ids_vehs_prog[id_stop]3484i = 03485for time_start, id_veh_prog, id_stop_target, is_prog in self.ids_vehs_prog[id_stop]:3486if id_veh_prog == id_veh:3487self.ids_vehs_prog[id_stop].pop(i)3488break3489i = +134903491# self.ids_vehs_prog[id_stop].remove(id_veh)34923493self.numbers_veh[id_stop] -= 134943495def allocate_alight(self, id_stop):34963497# print 'allocate_alight',id_stop3498#self.inds_berth_alight_allocated [id_stop] = len(self.ids_berth_alight[id_stop])3499ind_berth = self.inds_berth_alight_allocated[id_stop]35003501if ind_berth == 0:3502# no free berth :(3503return -13504else:3505ind_berth -= 13506self.inds_berth_alight_allocated[id_stop] = ind_berth3507return self.ids_berth_alight[id_stop][ind_berth]35083509def allocate_board(self, id_stop, n_alloc, queues):3510"""3511Return successive berth ID to be allocated for boarding3512at given stop ID.3513n_alloc is the number of vehicles which remain to be3514allocated.3515"""35163517#self.inds_berth_alight_allocated [id_stop] = len(self.ids_berth_alight[id_stop])3518ind_berth = self.inds_berth_board_allocated[id_stop]3519# print 'allocate_board id_stop, n_alloc,ind_berth',id_stop, n_alloc,ind_berth3520if ind_berth == 0:3521# no free berth :(3522return -13523else:3524if queues is None:35253526# less or equal allocation positions in board zone3527# then vehicles to be allocated3528ind_berth -= 13529# print ' allocate in order ind_berth=',ind_berth3530self.inds_berth_board_allocated[id_stop] = ind_berth3531return self.ids_berth_board[id_stop][ind_berth]3532else:3533# there are more allocation positions in board zone3534# then vehicles to be allocated3535ind_berth -= 13536id_berth = self.ids_berth_board[id_stop][ind_berth]3537# print ' check queue, start with ind_berth=%d,n_alloc=%d, id_berth=%d, queue=%d, pos=%.2fm'%(ind_berth,n_alloc,id_berth,queues[id_berth],self.get_berths().stoppositions[id_berth]),queues[id_berth] == 0,ind_berth >= n_alloc3538while (queues[id_berth] == 0) & (ind_berth >= n_alloc):3539ind_berth -= 13540id_berth = self.ids_berth_board[id_stop][ind_berth]3541# print ' check queue, start with ind_berth=%d,n_alloc=%d, id_berth=%d, queue=%d, pos=%.2fm'%(ind_berth,n_alloc,id_berth,queues[id_berth],self.get_berths().stoppositions[id_berth]),queues[id_berth] == 0,ind_berth >= n_alloc35423543self.inds_berth_board_allocated[id_stop] = ind_berth3544return id_berth35453546def get_berthqueues(self, id_stop):3547# currently not used3548# print 'get_berthqueues',id_stop3549# TODO: use stop angle and person angle to detect waiting persons3550ids_berth_board = self.ids_berth_board[id_stop]3551stoppositions = self.get_berths().stoppositions[ids_berth_board]3552counters = np.zeros(len(stoppositions), dtype=np.int32)3553# print ' stoppositions',stoppositions3554for id_person_sumo in self.waittimes_persons[id_stop].keys():3555position = traci.person.getLanePosition(id_person_sumo)3556# print ' position',position3557dists = np.abs(stoppositions-position)3558# print ' dists',dists,np.any(dists<5)3559if np.any(dists < 0.8):3560ind_berth = np.argmin(dists)3561counters[ind_berth] += 135623563queues = {}3564for id_berth, count in zip(ids_berth_board, counters):3565queues[id_berth] = count35663567# print ' queues=\n',queues3568return queues35693570def make_from_net(self):3571"""3572Make prt stop database from PT stops in network.3573"""3574print 'make_from_net'3575self.clear()3576net = self.get_scenario().net3577ptstops = net.ptstops35783579ids_ptstop = ptstops.get_ids()3580id_mode_prt = self.parent.id_prtmode35813582#ids_edges = net.lanes.ids_edge[ptstops.ids_lane[ids_ptstop]]3583#ids_lanes = net.edges.ids_lanes[ids_edges]3584ids_lane = ptstops.ids_lane[ids_ptstop]3585#edgelengths = net.edges.lengths35863587for id_stop, id_lane, position_from, position_to in zip(3588ids_ptstop,3589# ids_lanes,3590ids_lane,3591ptstops.positions_from[ids_ptstop],3592ptstops.positions_to[ids_ptstop],3593):3594# get allowed modes of lane with index 13595modes_allow = net.lanes.ids_modes_allow[id_lane]3596# print ' check id_stop, modes_allow, position_from, position_to',id_stop, modes_allow, position_from, position_to3597if id_mode_prt in modes_allow:3598self.make(id_stop,3599position_from,3600position_to)36013602self.parent.make_fstar(is_update=True)3603self.parent.make_times_stop_to_stop()36043605def make(self, id_ptstop, position_from, position_to):3606"""3607Initialize a new prt stop and generate berth.3608"""3609id_stop = self.add_row(ids_ptstop=id_ptstop)3610ids_berth = self.get_berths().make(id_stop, position_from=position_from,3611position_to=position_to)3612n_berth = len(ids_berth)3613n_berth_alight = int(0.5*n_berth)3614n_berth_board = n_berth-n_berth_alight3615self.ids_berth_alight[id_stop] = ids_berth[0:n_berth_alight]3616self.ids_berth_board[id_stop] = ids_berth[n_berth_alight:n_berth]3617return id_stop361836193620class VehicleAdder(Process):3621def __init__(self, vehicles, logger=None, **kwargs):3622print 'VehicleAdder.__init__', vehicles, vehicles.parent.get_ident()3623self._init_common('vehicleadder', name='Vehicle adder',3624logger=logger,3625info='Add vehicles to PRT stops of network.',3626)3627self._vehicles = vehicles36283629attrsman = self.set_attrsman(cm.Attrsman(self))36303631self.n_vehicles = attrsman.add(cm.AttrConf('n_vehicles', kwargs.get('n_vehicles', -1),3632groupnames=['options'],3633perm='rw',3634name='Number of vehicles',3635info='Number of PRT vehicles to be added to the network. Use -1 to fill all present PRT stations.',3636))36373638def do(self):3639# print 'VehicleAdder.do'3640self._vehicles.add_to_net(n=self.n_vehicles)3641return True364236433644class PrtVehicles(am.ArrayObjman):36453646def __init__(self, ident, prtservices, **kwargs):3647# print 'PrtVehicles vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1')3648self._init_objman(ident=ident,3649parent=prtservices,3650name='PRT Veh.',3651info='PRT vehicle database. These are shared vehicles.',3652version=0.1,3653**kwargs)36543655self._init_attributes()36563657def _init_attributes(self):3658vtypes = self.get_scenario().demand.vtypes3659net = self.get_scenario().net36603661version = self.get_version()3662if version < 0.1:3663self.delete('speed_max')3664self.delete('time_emergency')3665self.delete('decel_comfort')3666self.delete('decel_emergency')3667self.delete('speed_max')36683669self.add(cm.AttrConf('time_update', 0.5,3670groupnames=['parameters'],3671name='Update time',3672info="Update time for traci controlled vehicles, es. at merge points.",3673unit='s',3674))36753676self.add(cm.AttrConf('speedmode_follower', 1,3677groupnames=['parameters'],3678name='Follower speed mode',3679info="""Follower speed mode. The single bits have the following meaning:3680bit0: Regard safe speed3681bit1: Regard maximum acceleration3682bit2: Regard maximum deceleration -3683bit3: Regard right of way at intersections3684bit4: Brake hard to avoid passing a red light3685""",3686))36873688self.add(cm.AttrConf('factor_speed_follower', 2.0,3689groupnames=['parameters'],3690name='Follower speed factor',3691info="""Follower speed factor.""",3692))36933694self.add(cm.AttrConf('accel_follower', 5.0,3695groupnames=['parameters'],3696name='Follower acceleration',3697info="Follower acceleration.",3698unit='m/s^2',3699))37003701self.add(cm.AttrConf('decel_follower', 5.0,3702groupnames=['parameters'],3703name='Follower deceleration',3704info="Follower deceleration.",3705unit='m/s^2',3706))37073708self.add(cm.AttrConf('decel_emergency_follower', 5.0,3709groupnames=['parameters'],3710name='Follower Emergency deceleration',3711info="Follower Emergency deceleration.",3712unit='m/s^2',3713))37143715self.add(cm.AttrConf('dist_min_follower', 0.0,3716groupnames=['parameters'],3717name='Follower min. distance',3718info="Follower minimum distance",3719unit='m',3720))37213722self.add(cm.AttrConf('tau_follower', 0.0,3723groupnames=['parameters'],3724name='Follower reaction time',3725info="Follower reaction time.",3726unit='s',3727))37283729self.add(cm.AttrConf('n_ghosts_max', 4,3730groupnames=['parameters'],3731name='Max ghosts',3732info="Maximum number of ghost vehicles. Ghost vehicles are used in merge controls.",3733))37343735# TODO: add/update vtypes here3736self.add_col(SumoIdsConf('Veh', xmltag='id'))37373738id_vtype = self.make_vtype(is_renew=version < 0.1)37393740if not hasattr(self, 'ids_vtype'):37413742self.add_col(am.IdsArrayConf('ids_vtype', vtypes,3743id_default=id_vtype,3744groupnames=['state'],3745name='Veh. type',3746info='PRT vehicle type.',3747#xmltag = 'type',3748))3749else:3750# this imposes parameters to alresdy existing data3751self.ids_vtype[self.get_ids()] = id_vtype37523753self.add_col(am.ArrayConf('states', default=VEHICLESTATES['init'],3754groupnames=['_private'],3755dtype=np.int32,3756choices=VEHICLESTATES,3757name='state',3758info='State of vehicle.',3759))37603761# self.add_col(am.IdsArrayConf( 'ids_targetprtstop', self.parent.prtstops,3762# groupnames = ['parameters'],3763# name = 'Target stop ID',3764# info = 'ID of current target PRT stop.',3765# ))37663767self.add_col(am.IdsArrayConf('ids_currentedge', net.edges,3768groupnames=['state'],3769name='Current edge ID',3770info='Edge ID of most recent reported position.',3771))37723773# self.add_col(am.IdsArrayConf( 'ids_targetedge', net.edges,3774# groupnames = ['state'],3775# name = 'Target edge ID',3776# info = 'Target edge ID to be reached. This can be either intermediate target edges (), such as a compressor station.',3777# ))37783779self.set_version(0.1)37803781def _init_constants(self):37823783self.do_not_save_attrs([3784'length',3785'tau', 'ids_berth',3786'are_update', 'velocities',3787'odos', 'ids_ghosts',3788'diststomerge0', 'diststomerge0_ghosts',3789'dists0', 'odos0_vehicles', 'odos0_ghosts',3790'ids_leader', 'ids_follower', 'lengths_plat',3791])37923793def get_net(self):3794return self.parent.get_scenario().net37953796def make_vtype(self, is_renew=False):3797print 'make_vtype PRT'3798vtypes = self.get_scenario().demand.vtypes3799prttype = 'PRT'38003801if (not vtypes.ids_sumo.has_index(prttype)) | is_renew:3802if vtypes.ids_sumo.has_index(prttype):3803vtypes.del_row(vtypes.ids_sumo.get_id_from_index(prttype))3804id_vtype = vtypes.add_vtype(prttype,3805accel=2.5,3806decel=2.5,3807decel_apparent=2.5, # followe should not be freightened3808decel_emergency=5.0,3809sigma=0.0,3810length=3.5,3811width=1.6,3812height=1.7,3813number_persons=1,3814capacity_persons=1,3815dist_min=0.3,3816tau=0.5,3817speed_max=60.0/3.6,3818factor_speed=0.9,3819deviation_speed=0.1, # slight deviation for better following3820# emissionclass= 'HBEFA3/zero',# defined in electricity model3821id_mode=self.parent.id_prtmode, # specifies mode for demand3822color=np.array((255, 240, 0, 255), np.float32)/255.0,3823shape_gui='evehicle',3824times_boarding=1.5,3825times_loading=20.0,3826sublane_alignment_lat='center',3827sublane_speed_max_lat=0.5,3828sublane_gap_min_lat=0.24,3829sublane_alignment_eager=1000000.0,3830#3831power_max=5000.0,3832mass=800.0,3833area_front_surface=3.5*1.6,3834coefficient_drag_air=0.4,3835moment_inertia_internal=0.01,3836coefficient_drag_radial=0.5,3837coefficient_drag_roll=0.005,3838efficiency_propulsion=0.9,3839#3840eprofile='prt',3841capacity_battery=2000.0,3842efficiency_reuperation=0.4,3843speed_charging=0.03,3844)38453846else:3847id_vtype = vtypes.ids_sumo.get_id_from_index(prttype)38483849# speedmode3850# https://sumo.dlr.de/docs/TraCI/Change_Vehicle_State.html3851# bit0: Regard safe speed3852# bit1: Regard maximum acceleration3853# bit2: Regard maximum deceleration -3854# bit3: Regard right of way at intersections3855# bit4: Brake hard to avoid passing a red light38563857#self._speedmode_leader = 73858#self._speedmode_follower = 638593860# leader and follower parameters are used when switching3861# between leader and follower in concatenate/deconcatenate3862self._speedmode_leader = 73863self._speedmode_follower = self.speedmode_follower.get_value()38643865self._factor_speed_leader = vtypes.factors_speed[id_vtype]3866self._factor_speed_follower = self.factor_speed_follower.get_value()38673868self._accel_leader = vtypes.accels[id_vtype]3869self._accel_follower = self.accel_follower.get_value()38703871self._decel_leader = vtypes.decels[id_vtype]3872self._decel_follower = self.decel_follower.get_value()38733874self._decel_emergency_leader = vtypes.decels_emergency[id_vtype]3875self._decel_emergency_follower = self.decel_emergency_follower.get_value()38763877self._dist_min_leader = vtypes.dists_min[id_vtype]3878self._dist_min_follower = self.dist_min_follower.get_value()38793880self._tau_leader = vtypes.taus[id_vtype]3881self._tau_follower = self.tau_follower.get_value()38823883# these are additional, somehow parameters3884# TODO: redundant parameters with leader and follower parameters3885# should be removed38863887self.length = vtypes.lengths[id_vtype]3888self.speed_max = vtypes.speeds_max[id_vtype]3889self.accel = vtypes.accels[id_vtype]3890self.decel = vtypes.decels[id_vtype]38913892self.decel_emergency = vtypes.decels_emergency[id_vtype]3893self.tau = vtypes.taus[id_vtype]3894self.dist_min = vtypes.dists_min[id_vtype]3895self.factor_speed = vtypes.factors_speed[id_vtype]38963897return id_vtype38983899def get_length(self):3900return self.length39013902def prepare_sim(self, process):3903print 'PrtVehicles.prepare_sim'3904if len(self) == 0:3905return []39063907ids = self.get_ids()3908net = self.get_scenario().net3909#nodes = net.nodes3910#edges = net.edges3911#lanes = net.lanes3912#ids_edge_sumo = edges.ids_sumo39133914id_prtmode = self.parent.id_prtmode39153916# here take parameters from first vtype and assume that all are the same3917# this call ensures that most recent parameters are considered3918id_vtype = self.make_vtype()39193920#ptstops = net.ptstops3921lanes = net.lanes3922#ids_edge_sumo = net.edges.ids_sumo39233924n_id_max = np.max(ids)+13925n_ghosts_max = self.n_ghosts_max.get_value()3926self.ids_berth = -1*np.ones(n_id_max, dtype=np.int32)39273928self.are_update = np.zeros(n_id_max, dtype=np.bool)3929self.velocities = np.zeros(n_id_max, dtype=np.float32)3930self.odos = np.zeros(n_id_max, dtype=np.float32)39313932self.ids_ghosts = -1*np.ones((n_id_max, n_ghosts_max), dtype=np.int32)39333934self.diststomerge0 = np.inf * np.ones((n_id_max, n_ghosts_max), dtype=np.float32)3935self.diststomerge0_ghosts = np.inf * np.ones((n_id_max, n_ghosts_max), dtype=np.float32)3936self.dists0 = np.inf * np.ones((n_id_max, n_ghosts_max), dtype=np.float32)39373938self.odos0_vehicles = -1 * np.ones((n_id_max, n_ghosts_max), dtype=np.float32)3939self.odos0_ghosts = -np.inf * np.ones((n_id_max, n_ghosts_max), dtype=np.float32)39403941# platooning3942# id of leader of this vehicle (vehicle in front), -1 = platoonleader3943self.ids_leader = -1 * np.ones(n_id_max, dtype=np.int32)39443945# id of follower of this vehicle (vehicle behind), -1 = last veh3946self.ids_follower = -1 * np.ones(n_id_max, dtype=np.int32)39473948# total length of platoon3949self.lengths_plat = np.zeros(n_id_max, dtype=np.float32)39503951return [(self.time_update.get_value(), self.process_step), ]39523953def add_ghost(self, id_veh, id_ghost, dist_to_merge_veh, dist_to_merge_ghost,3954is_substitute=False):3955ids_ghosts = list(self.ids_ghosts[id_veh])3956# if id_ghost in ids_ghosts:3957# # reconfigure existing3958# ind_ghost = self.ids_ghosts[id_veh].index(id_ghost)3959# id_ghost_old = self.ids_ghosts[id_veh][ind_ghost]3960# # try to delete old ghost3961# self.del_ghost(id_veh, id_ghost_old)3962# else:3963# add new ghost3964print 'add_ghost id_veh %d id_ghost %d' % (id_veh, id_ghost) # ,self.ids_ghosts.shape39653966if -1 not in ids_ghosts:3967# print 'ERROR: no more ghosts available, ids_ghosts',ids_ghosts3968# sys.exit(1)3969# print ' overwrite last ghost'3970# here we could sunstitute the ghost with the longest distance3971ind_ghost = len(ids_ghosts)-13972else:3973ind_ghost = ids_ghosts.index(-1)39743975if is_substitute:3976id_ghost_prev = ids_ghosts[ind_ghost]3977if id_ghost_prev > -1:3978self.stop_update(id_ghost_prev)3979if ind_ghost > 0:3980ind_ghost -= 139813982if ind_ghost > 0:3983print 'WARNING: unusual number of ghosts, ids_ghosts', ids_ghosts3984# sys.exit(1)39853986self.ids_ghosts[id_veh][ind_ghost] = id_ghost3987self.diststomerge0[id_veh][ind_ghost] = dist_to_merge_veh3988self.diststomerge0_ghosts[id_veh][ind_ghost] = dist_to_merge_ghost39893990# nose to nose distances3991self.dists0[id_veh][ind_ghost] = dist_to_merge_veh - dist_to_merge_ghost39923993# get absolute running distances3994self.odos0_vehicles[id_veh][ind_ghost] = get_traci_odo(self.get_id_sumo(id_veh))3995self.odos0_ghosts[id_veh][ind_ghost] = get_traci_odo(self.get_id_sumo(id_ghost))39963997# both ghosts and vehicles need update3998self.start_update(id_veh)3999self.start_update(id_ghost)40004001def del_ghosts(self, id_veh):4002if self.ids_ghosts[id_veh][0] == -1:4003# id_veh has no ghosts4004return4005else:4006for id_ghost in self.ids_ghosts[id_veh]:4007if id_ghost > -1:4008self.del_ghost(id_veh, id_ghost)40094010def del_ghost(self, id_veh, id_ghost):4011# print 'del_ghost id_veh %d id_ghost %d'%(id_veh, id_ghost)4012if id_ghost in self.ids_ghosts[id_veh]:40134014ind_ghost = list(self.ids_ghosts[id_veh]).index(id_ghost)4015self.ids_ghosts[id_veh][ind_ghost] = -140164017self.diststomerge0[id_veh][ind_ghost] = np.inf4018self.diststomerge0_ghosts[id_veh][ind_ghost] = np.inf4019self.dists0[id_veh][ind_ghost] = np.inf40204021self.odos0_vehicles[id_veh][ind_ghost] = -1.04022self.odos0_ghosts[id_veh][ind_ghost] = -np.inf40234024self.stop_update(id_veh)4025self.stop_update(id_ghost)4026else:4027# veh has not such ghost4028pass40294030def del_all_ghosts(self, id_veh):4031if self.ids_ghosts[id_veh][0] == -1:4032# id_veh has no ghosts4033return40344035for id_ghost in self.ids_ghosts[id_veh]:4036if id_ghost > -1:4037self.del_ghost(id_veh, id_ghost)40384039# just to be sure ...4040self.stop_update(id_veh)40414042def switch_off_control(self, id_veh):4043"""Direct way to switch of SUMO control of vehicles"""4044# print 'switch_off_control id_veh',id_veh4045traci.vehicle.setSpeedMode(self.ids_sumo[id_veh], 6) # 6=respect max accel/decel40464047def switch_on_control(self, id_veh):4048"""Direct way to switch of SUMO control of vehicles"""4049# print 'switch_on_control id_veh',id_veh4050traci.vehicle.setSpeedMode(self.ids_sumo[id_veh], self._speedmode_leader)40514052def start_update(self, id_veh):4053"""Start updating control by ghosts"""4054self.are_update[id_veh] = True4055traci.vehicle.setSpeedMode(self.ids_sumo[id_veh], 6) # 6=respect max accel/decel40564057def stop_update(self, id_veh):4058"""Stop updating control by ghosts"""4059if np.all(self.ids_ghosts[id_veh] == -1): # id_veh has no ghosts?40604061# attention stopping from being conrolled by merge means4062# handing control back to SUMO.4063# followers are not controlled by the merge process4064traci.vehicle.setSpeedMode(self.ids_sumo[id_veh], self._speedmode_leader)4065if id_veh not in self.ids_ghosts: # id_veh is no ghost ?4066self.are_update[id_veh] = False # stop updating40674068def process_step(self, process):4069simtime = process.simtime4070print 79*'_'4071print 'PrtVehicles.process_step at', simtime4072net = self.get_scenario().net4073vehicles = self.parent.prtvehicles4074ids = self.get_ids()4075if len(ids) == 0:4076return4077time_update = self.time_update.get_value()4078decel_emergency = self.decel_emergency4079# print ' update',len(np.flatnonzero(self.are_update[ids])),'vehicles'4080ids_update = ids[self.are_update[ids]]4081# print ' ids_update',ids_update40824083# print ' *Debug:'4084#ids_debug = [307, 236, 41, 231, 208, 44, 249, 229, 136]4085#ids_debug = [276,277,278]4086#4087# for id_veh, id_follower, id_leader in zip(ids_debug,self.ids_follower[ids_debug], self.ids_leader[ids_debug]):4088# print ' *id_veh',id_veh,'id_follower',id_follower,'id_leader',id_leader40894090# loop through vehicles that need speed modifications4091# these are vehicles which have ghosts or vehicles which are4092# in merge processes4093for id_veh, id_veh_sumo in zip(ids_update, self.ids_sumo[ids_update]):4094# update odometer and speed4095self.velocities[id_veh] = get_traci_velocity(id_veh_sumo)4096self.odos[id_veh] = get_traci_odo(id_veh_sumo)40974098if 0:4099ids_ghost = self.ids_ghosts[id_veh]4100print ' %7s' % id_veh_sumo, 'ghosts', ids_ghost, self.ids_leader[id_veh], "lp=%.1fm" % self.lengths_plat[id_veh]4101#odo = self.odos[id_veh]4102#delta_vehs = odo-self.odos0_vehicles[id_veh]4103#delta_ghosts = self.odos[ids_ghost] - self.odos0_ghosts[id_veh]4104# print ' delta_vehs, delta_ghosts',min(delta_vehs), min(delta_ghosts)#, self.dists0[id_veh]4105# print ' dists', min(self.dists0[id_veh] + delta_ghosts - delta_vehs)41064107#self.diststomerge0[id_veh][ind_ghost] = np.inf4108#self.diststomerge0_ghosts[id_veh][ind_ghost] = np.inf41094110# pick vehicle ids that must be controlled due to a present ghost4111ids_contr = ids_update[self.ids_ghosts[ids_update][:, 0] > -1]4112# print ' ids_contr',ids_contr4113# print ' self.ids_ghosts[ids_update][:,0]',self.ids_ghosts[ids_update][:,0]4114# print ' inds',self.ids_ghosts[ids_update][:,0]>-14115n_contr = len(ids_contr)4116n_ghosts_max = self.n_ghosts_max.get_value()41174118# no vehicles with ghost, nothing to control4119if n_contr == 0:4120return41214122# get gosts4123ids_ghosts = self.ids_ghosts[ids_contr]41244125# print ' self.odos[ids_contr]',self.odos[ids_contr].reshape(n_contr,1)4126# print ' self.odos0_vehicles[ids_contr]',self.odos0_vehicles[ids_contr]41274128# distance made since merge zone is entered4129deltas_vehs = self.odos[ids_contr].reshape(n_contr, 1)-self.odos0_vehicles[ids_contr]4130deltas_ghosts = self.odos[ids_ghosts] - self.odos0_ghosts[ids_contr]41314132#dists = self.dists0[ids_contr] + deltas_ghosts - deltas_vehs4133# print ' dists',dists4134#dists_min = np.min(self.dists0[ids_contr] + deltas_ghosts - deltas_vehs, 1) - (self.length+self.lengths_plat[ids_contr])41354136# get distance between nose of vehicle and tail of ghost which is closest4137dists_min = np.min(self.dists0[ids_contr] + deltas_ghosts - deltas_vehs -4138self.lengths_plat[ids_ghosts], 1) - self.length41394140# ??????? minimum dist to merge over all vehicles -> remove, not in use4141#diststomerge_min = np.min(self.diststomerge0[ids_contr] - deltas_vehs , 1)4142#self.diststomerge0[id_veh][ind_ghost] = dist_to_merge_veh4143# self.diststomerge0_ghosts[id_veh][ind_ghost] =41444145# print ' dists_min',dists_min4146velocities = self.velocities[ids_contr]41474148# print ' velocities_ghosts masked\n',self.velocities[ids_ghosts]41494150#mask_ghosts = INF*(ids_ghosts==-1).astype(np.float32)4151# print ' mask_ghosts\n',mask_ghosts4152velocities_ghosts = self.velocities[ids_ghosts] + INF*(ids_ghosts == -1)41534154# print ' velocities_ghosts masked\n',velocities_ghosts4155#4156# velocities of slowest ghosts4157velocities_ghost_min = np.min(self.velocities[ids_ghosts] + INF*(ids_ghosts == -1), 1)4158# print ' velocities_ghost_min\n',velocities_ghost_min4159dists_safe = self.tau*velocities + 0.5/decel_emergency*velocities*velocities4160dists_comf = self.tau*velocities + 0.5/self.decel * \4161(velocities*velocities-velocities_ghost_min*velocities_ghost_min)41624163# print ' dists_safe',dists_safe4164# print ' dists_comf',dists_comf4165#dists_crit = np.max(np.concatenate((dists_safe.reshape(n_contr,1),dists_comf.reshape(n_contr,1)),1),1)4166# print ' dists_crit',dists_crit41674168deltas_crit = dists_min-np.max(np.concatenate((dists_safe.reshape(n_contr, 1),4169dists_comf.reshape(n_contr, 1)), 1), 1)4170#deltas_crit = dists_min-dists_safe4171# print ' deltas_crit',deltas_crit4172inds_slow = deltas_crit < 04173inds_accel = (deltas_crit > 0) & (velocities < 0.8*velocities_ghost_min)4174# print ' inds_slow',inds_slow41754176if 0:4177for id_sumo, velocity, velocitiy_ghost_min,\4178dist_safe, dist_comf, dist_min, delta_crit,\4179is_slow, is_accel, length_plat\4180in zip(self.ids_sumo[ids_contr],4181velocities,4182velocities_ghost_min,4183dists_safe,4184dists_comf,4185dists_min,4186deltas_crit,4187inds_slow, inds_accel, self.lengths_plat[ids_contr],4188# diststomerge_min,4189):41904191if is_slow:4192a = '-'4193elif is_accel:4194a = '+'4195else:4196a = '='4197# print 'id_sumo, velocity, velocitiy_ghost_min,dist_safe,dist_comf,dist_min,delta_crit,is_slow,is_accel, length_plat\n',\4198# id_sumo, velocity, velocitiy_ghost_min,\4199# dist_safe,dist_comf,dist_min,delta_crit,\4200#is_slow,is_accel, length_plat42014202th = (dist_min + self.length)/velocity4203ds_check = self.tau*velocity + 0.5/decel_emergency*velocity*velocity4204# print ' %7s: v=%3.1f vg=%3.1f dh=%4.1f th=%4.1fs ds=%4.1f dc=%4.1f lp=%3.1f %s'%(id_sumo, velocity, velocitiy_ghost_min,dist_min,th,dist_safe,dist_comf,length_plat,a)42054206fact_urgent = np.ones(dists_safe.shape, dtype=np.float32) # np.clip(dists_safe/diststomerge_min,0.0,1.0)42074208v_delta_brake = time_update*self.decel*fact_urgent4209for id_sumo, velocity, dv in zip(self.ids_sumo[ids_contr[inds_slow]], velocities[inds_slow], v_delta_brake):4210# print ' deccel %s from %.2f to %.2fm/s dv = %.2fm/s'%(id_sumo, velocity, velocity-dv,dv)4211if velocity-dv > 0: # upset when negative velocities4212traci.vehicle.slowDown(id_sumo, velocity-dv, time_update)42134214v_delta_accel = time_update*self.accel*fact_urgent4215for id_sumo, velocity, dv in zip(self.ids_sumo[ids_contr[inds_accel]], velocities[inds_accel], v_delta_accel):4216#dv = time_update*self.accel4217# print ' accel %s from %.2f to %.2fm/s dv = %.2fm/s'%(id_sumo, velocity, velocity+dv,dv)4218traci.vehicle.slowDown(id_sumo, velocity+dv, time_update)42194220# print ' deltas_vehs',deltas_vehs4221# print ' self.ids_ghosts[ids_contr]',self.ids_ghosts[ids_contr]4222# print ' self.odos[self.ids_ghosts[ids_contr]]',self.odos[self.ids_ghosts[ids_contr]]4223# print ' self.odos0_ghosts[id_veh]',self.odos0_ghosts[ids_contr]4224# print ' deltas_ghosts',deltas_ghosts4225# print ' dists',dists4226# for id_contr, delta_vehs, delta_ghosts,dist in zip(ids_contr,deltas_vehs,deltas_ghosts,dists):4227# print ' veh',id_contr,'dist',dist42284229#self.length = vtypes.lengths[id_vtype]4230#self.speed_max = vtypes.speeds_max[id_vtype]4231#self.accel = vtypes.accels[id_vtype]4232#self.decel = vtypes.decels[id_vtype]4233#self.tau = vtypes.taus[id_vtype]42344235def reset_speedmode(self, id_veh_sumo):4236print 'reset_speedmode', id_veh_sumo4237# speed mode (0xb3)4238# Per default, the vehicle is using the given speed regarding the safe gap, the maximum acceleration, and the maximum deceleration. Furthermore, vehicles follow the right-of-way rules when approaching an intersection and if necessary they brake hard to avoid driving across a red light. One can control this behavior using the speed mode (0xb3) command, the given integer is a bitset (bit0 is the least significant bit) with the following fields:4239# 1 bit0: Regard safe speed4240# 2 bit1: Regard maximum acceleration4241# 4 bit2: Regard maximum deceleration4242# 8 bit3: Regard right of way at intersections4243# 16 bit4: Brake hard to avoid passing a red light4244# 1+2+44245# traci.vehicle.setSpeedMode(id_veh_sumo,7)4246#self.speed_max = vtypes.speeds_max[id_vtype]4247#self.accel = vtypes.accels[id_vtype]4248traci.vehicle.slowDown(id_veh_sumo, self.speed_max, self.speed_max/self.accel)4249# pass42504251def concatenate(self, id_veh, id_veh_pre):4252print 'concatenate prt.%d' % id_veh, 'behind prt.%d' % id_veh_pre4253# print ' >>'4254self.ids_leader[id_veh] = id_veh_pre4255self.ids_follower[id_veh_pre] = id_veh42564257id_veh_sumo = self.get_id_sumo(id_veh)42584259if 0:4260print 'follower params'4261print ' speedmode', self._speedmode_follower4262print ' factor_speed', self._factor_speed_follower4263print ' decel', self._decel_emergency_follower, '= decel_emergency'4264print ' accel_follower', self._accel_follower4265print ' dist_min', self._dist_min_follower4266print ' tau', self._tau_follower42674268# if 0:4269# traci.vehicle.setSpeedFactor(id_veh_sumo,2.0)# +random.uniform(-0.01,0.01)4270# traci.vehicle.setImperfection(id_veh_sumo,0.0)4271# traci.vehicle.setAccel(id_veh_sumo,3.5)4272# traci.vehicle.setMinGap(id_veh_sumo,0.01)4273# traci.vehicle.setTau(id_veh_sumo,0.2)42744275# if 1:4276traci.vehicle.setSpeedMode(id_veh_sumo, self._speedmode_follower)4277traci.vehicle.setSpeedFactor(id_veh_sumo, self._factor_speed_follower)4278# traci.vehicle.setImperfection(id_veh_sumo,0.0)4279traci.vehicle.setDecel(id_veh_sumo, self._decel_emergency_follower)4280traci.vehicle.setAccel(id_veh_sumo, self._accel_follower)4281traci.vehicle.setMinGap(id_veh_sumo, self._dist_min_follower)4282traci.vehicle.setTau(id_veh_sumo, self._tau_follower)42834284if self.lengths_plat[id_veh] > 0.1:4285self._update_concatenate(id_veh, self.lengths_plat[id_veh])4286else:4287self._update_concatenate(id_veh, 0.0)42884289def _update_concatenate(self, id_veh, length_plat):4290"""4291Propagates length to the first vehicle of the platoon4292"""4293# print '_update_concatenate prt.%s, length_plat=%.1f, length=%.1f,'%(id_veh,length_plat,self.length),'id_leader',self.ids_leader[id_veh]4294if self.ids_leader[id_veh] == -1:4295# first vehicle4296# print ' first vehicle prt.%s'%id_veh,length_plat4297self.lengths_plat[id_veh] = length_plat4298else:4299# propagate platoon length4300self.lengths_plat[id_veh] = 0.04301self._update_concatenate(self.ids_leader[id_veh], length_plat + self.length)43024303def decatenate(self, id_veh):4304print 'decatenate prt.%d' % id_veh43054306id_leader = self.ids_leader[id_veh]4307# print ' id_leader',id_leader4308if id_leader > -1:4309id_veh_sumo = self.get_id_sumo(id_veh)4310if self.ids_leader[id_leader] == -1:4311# leader of this vehicle is first in platoon4312# this should be normally the case if a platoon is4313# broken up from the first vehicle backwards43144315# calculate new shortened platoon length4316# TODO4317self.lengths_plat[id_veh] = self.lengths_plat[id_leader]-self.length4318else:4319print 'WARNING in decatenate: platoon broken up in the middel at', id_veh_sumo4320self.lengths_plat[id_veh] = 0.043214322# this vehicle will become first in the platoon4323self.ids_leader[id_veh] = -14324self.ids_follower[id_leader] = -14325# if 0:4326# traci.vehicle.setSpeedFactor(id_veh_sumo, 1.5)#+random.uniform(-0.01,0.01)4327# traci.vehicle.setMinGap(id_veh_sumo,0.3)4328# traci.vehicle.setImperfection(id_veh_sumo,0.0)4329# traci.vehicle.setTau(id_veh_sumo,0.8)4330# traci.vehicle.setAccel(id_veh_sumo,2.5)43314332# if 1:4333# reset parameters4334traci.vehicle.setSpeedMode(id_veh_sumo, self._speedmode_leader)43354336# rest are leader values taken from type def4337traci.vehicle.setSpeedFactor(id_veh_sumo, self.factor_speed) # +random.uniform(-0.01,0.01)4338traci.vehicle.setMinGap(id_veh_sumo, self.dist_min)4339# traci.vehicle.setImperfection(id_veh_sumo,1.0)4340traci.vehicle.setTau(id_veh_sumo, self.tau)4341traci.vehicle.setDecel(id_veh_sumo, self.decel)4342traci.vehicle.setAccel(id_veh_sumo, self.accel)4343else:4344# it is a leader itself and does not need to decatenate4345# remove platoon length4346self.lengths_plat[id_veh] = 0.043474348def get_platoonleader(self, id_veh):4349while self.ids_leader[id_veh] > -1:4350id_veh = self.ids_leader[id_veh]4351return id_veh43524353def get_platoontail(self, id_veh):4354while self.ids_follower[id_veh] > -1:4355id_veh = self.ids_follower[id_veh]4356return id_veh43574358def get_platoon(self, id_veh):4359print 'get_platoon', id_veh4360ids_veh = [id_veh, ]4361id_veh = self.ids_follower[id_veh]4362# print ' id_veh',id_veh4363while id_veh > -1:4364ids_veh.append(id_veh)4365id_veh = self.ids_follower[id_veh]4366print ' id_veh', id_veh43674368print ' ids_veh', ids_veh4369return ids_veh43704371def get_entered_left(self, id_edge_sumo, ids_veh_previous_sumo):4372"""4373Returns:4374array with SUMO IDs of entered vehicles during last poll4375array with SUMO IDs of left vehicles during last poll4376array with SUMO IDs current vehicles on id_edge_sumo4377Attention: in the returned entered/left lists,4378the first vehicle in the list entered/left first4379"""4380ids_veh_new_sumo = traci.edge.getLastStepVehicleIDs(id_edge_sumo)4381# print 'get_entered_left ids_veh_new_sumo=',ids_veh_new_sumo4382len_prev = len(ids_veh_previous_sumo)4383len_new = len(ids_veh_new_sumo)43844385if len_prev == 0:4386return ids_veh_new_sumo, [], ids_veh_new_sumo43874388if len_new == 0:4389return [], ids_veh_previous_sumo, []43904391ind_enter = 043924393for id_veh_sumo in ids_veh_new_sumo:43944395# if ind_enter+1 == len_prev:4396# ind_enter = len_new -14397# break43984399if id_veh_sumo == ids_veh_previous_sumo[0]:4400break44014402ind_enter += 14403# print ' ind_enter',ind_enter,ids_veh_new_sumo[0:ind_enter],ids_veh_new_sumo[ind_enter-1::-1]4404#ids_entered_sumo = ids_veh_new_sumo[0:ind_enter]44054406ind_leave = len_prev4407for id_veh_sumo in ids_veh_previous_sumo[::-1]:44084409if id_veh_sumo == ids_veh_new_sumo[-1]:4410break44114412ind_leave -= 14413# print ' ind_leave',ind_leave, ids_veh_previous_sumo[ind_leave:],ids_veh_previous_sumo[:ind_leave:-1]4414#ids_leave_sumo = ids_veh_previous_sumo[ind_leave:]44154416# return ids_entered_sumo, ids_leave_sumo, ids_veh_new_sumo4417# return reversed lists4418return ids_veh_new_sumo[0:ind_enter][::-1], ids_veh_previous_sumo[ind_leave:][::-1], ids_veh_new_sumo44194420# TODO: optimize!!!4421# return ids_veh_new_sumo[ind_enter-1::-1], ids_veh_previous_sumo[:ind_leave:-1], ids_veh_new_sumo44224423def control_stop(self, id_veh, laneindex=0):44244425id_veh_sumo = self.get_id_sumo(id_veh)4426speed = traci.vehicle.getSpeed(id_veh_sumo)4427pos = traci.vehicle.getLanePosition(id_veh_sumo)4428stopline = pos + 3.0 + 0.5/self.decel*speed**24429#time_slowdown = np.abs((speed0-speed)/self.decel)44304431print 'control_stop', id_veh_sumo, 'v = %.2f at pos %.1fm to stop at %.1fm on %s' % (speed, pos, stopline, traci.vehicle.getRoadID(id_veh_sumo))4432traci.vehicle.setStop(id_veh_sumo,4433traci.vehicle.getRoadID(id_veh_sumo),4434pos=stopline,4435laneIndex=laneindex,4436)44374438def control_speedup(self, id_veh):44394440id_veh_sumo = self.get_id_sumo(id_veh)4441print 'control_speedup', id_veh_sumo, 'isStopped', traci.vehicle.isStopped(id_veh_sumo), self.speed_max44424443if traci.vehicle.isStopped(id_veh_sumo):4444traci.vehicle.resume(id_veh_sumo)44454446traci.vehicle.setMaxSpeed(id_veh_sumo, self.speed_max)4447#self.control_slow_down(id_veh, self.speed_max)44484449def control_slow_down(self, id_veh, speed=1.0, time_slowdown=None):4450print 'control_slow_down', self.get_id_sumo(id_veh), speed, time_slowdown4451id_veh_sumo = self.get_id_sumo(id_veh)4452if time_slowdown is None:4453speed0 = traci.vehicle.getSpeed(id_veh_sumo)44544455time_slowdown = np.abs((speed0-speed)/self.decel)4456# print ' speed0=%.2fm/s, time_slowdown = %.2fs, dv=%.2fm/s'%(speed0,time_slowdown,speed0-speed)44574458traci.vehicle.slowDown(id_veh_sumo, speed, time_slowdown)4459#self.speed_max = vtypes.speeds_max[id_vtype]4460#self.accel = vtypes.accels[id_vtype]4461#self.decel = vtypes.decels[id_vtype]44624463def control_stop_alight(self, id_veh, id_stop, id_berth,4464id_edge_sumo=None,4465position=None,4466):4467id_veh_sumo = self.get_id_sumo(id_veh)4468p = traci.vehicle.getLanePosition(id_veh_sumo)4469print 'control_stop_alight', id_veh_sumo, p, '->', position, 'id_berth', id_berth4470#d = position - p4471#v = traci.vehicle.getSpeed(id_veh_sumo)4472#d_save = 1.0/(2*2.5)*(v**2)4473# print ' v=',v4474# print ' d,d_save',d,d_save4475self.states[id_veh] = VEHICLESTATES['forewarding']4476self.ids_berth[id_veh] = id_berth4477traci.vehicle.setStop(self.get_id_sumo(id_veh),4478id_edge_sumo,4479pos=position,4480flags=0,4481laneIndex=1,4482)44834484def control_stop_board(self, id_veh, id_stop, id_berth,4485id_edge_sumo=None,4486position=None,4487):44884489id_veh_sumo = self.get_id_sumo(id_veh)4490print 'control_stop_board', id_veh_sumo, id_stop, id_berth, id_edge_sumo, 'pos=%.2f,target %.2f' % (traci.vehicle.getLanePosition(id_veh_sumo), position)4491# print ' v=',traci.vehicle.getSpeed(id_veh_sumo)44924493# print 'control_stop_board',id_veh_sumo,traci.vehicle.getLanePosition(id_veh_sumo),'->',position,id_berth4494self.ids_berth[id_veh] = id_berth4495self.states[id_veh] = VEHICLESTATES['forewarding']4496# print ' StopState=',bin(traci.vehicle.getStopState(id_veh_sumo ))[2:]4497if traci.vehicle.isStopped(id_veh_sumo):4498traci.vehicle.resume(id_veh_sumo)44994500traci.vehicle.setStop(id_veh_sumo,4501id_edge_sumo,4502startPos=position-4.0,4503pos=position,4504flags=2, # park and trigger 1+2,#4505laneIndex=1,4506)45074508def alight(self, id_veh):4509# print 'alight',self.get_id_sumo(id_veh)4510# TODO: necessary to keep copy of state?4511self.states[id_veh] = VEHICLESTATES['alighting']4512# traci.vehicle.getStopState(self.get_id_sumo(id_veh))4513# VEHICLESTATES = {'init':0,'waiting':1,'boarding':2,'alighting'45144515def board(self, id_veh, id_edge_sumo=None, position=None):4516# print 'board',self.get_id_sumo(id_veh)4517# TODO: necessary to keep copy of state?4518self.states[id_veh] = VEHICLESTATES['boarding']4519#id_veh_sumo = self.get_id_sumo(id_veh)4520# print 'board',id_veh_sumo,'stopstate',bin(traci.vehicle.getStopState(id_veh_sumo ))[2:]4521# print ' ',dir(traci.vehicle)4522# traci.vehicle.getLastStepPersonIDs()4523# traci.vehicle.getStopState(self.get_id_sumo(id_veh))4524# VEHICLESTATES = {'init':0,'waiting':1,'boarding':2,'alighting'4525#traci.vehicle.setRoute(id_veh_sumo, [id_edge_sumo])4526# traci.vehicle.resume(id_veh_sumo)45274528# traci.vehicle.setStop( self.get_id_sumo(id_veh),4529# traci.vehicle.getRoadID(id_veh_sumo),4530# pos = traci.vehicle.getLanePosition(id_veh_sumo),4531# flags= 2,#4532# laneIndex= 1,4533# )4534# print 'board ',id_veh_sumo, traci.vehicle.getStopState(id_veh_sumo )# bin(traci.vehicle.getStopState(id_veh_sumo ))[2:]45354536def set_stop(self, id_veh, id_edge_sumo, stopline, laneindex=1):4537print 'set_stop', self.get_id_sumo(id_veh), stopline4538traci.vehicle.setStop(self.get_id_sumo(id_veh),4539id_edge_sumo,4540pos=stopline,4541laneIndex=laneindex,4542)45434544def reached_stop_sumo(self, id_veh_sumo):4545state = traci.vehicle.getStopState(id_veh_sumo)4546# print 'reached_stop',id_veh_sumo,bin(state),bin(state)[-1] == '1'4547return bin(state)[-1] == '1'45484549def is_completed_alighting(self, id_veh):4550# print 'is_completed_alighting',self.get_id_sumo(id_veh),self.states[id_veh],self.states[id_veh] == VEHICLESTATES['alighting'],traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)),type(traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)))4551if self.states[id_veh] == VEHICLESTATES['alighting']:4552if traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)) == 0:4553# print ' id_veh_sumo',self.get_id_sumo(id_veh),'completed alighting'4554self.states[id_veh] = VEHICLESTATES['await_forwarding']4555return True4556else:4557# somebody is still in the vehicle4558return False4559elif self.states[id_veh] == VEHICLESTATES['await_forwarding']:4560return True4561else:4562print 'WARNING: strange vehicle state %s while alighting prt.%d' % (self.states[id_veh], id_veh)4563return True45644565def is_completed_boarding(self, id_veh):4566# print 'is_completed_boarding',self.get_id_sumo(id_veh),self.states[id_veh],self.states[id_veh] == VEHICLESTATES['boarding'],traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)),type(traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)))4567if self.states[id_veh] == VEHICLESTATES['boarding']:4568if traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)) == 1:4569# print 'is_completed_boarding',self.get_id_sumo(id_veh),'completed boarding'4570self.states[id_veh] = VEHICLESTATES['waiting']4571return True4572else:4573False45744575else:4576return True45774578def get_veh_if_completed_boarding(self, id_veh):4579# print 'get_veh_if_completed_boarding',self.get_id_sumo(id_veh),self.states[id_veh],self.states[id_veh] == VEHICLESTATES['boarding'],traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)),type(traci.vehicle.getPersonNumber(self.get_id_sumo(id_veh)))45804581if self.states[id_veh] == VEHICLESTATES['boarding']:4582id_veh_sumo = self.get_id_sumo(id_veh)4583if traci.vehicle.getPersonNumber(id_veh_sumo) >= 1:4584# print 'get_veh_if_completed_boarding',id_veh_sumo,'completed boarding'4585self.states[id_veh] = VEHICLESTATES['waiting']4586return id_veh_sumo4587else:4588return ''45894590else:4591return ''45924593def init_trip_occupied(self, id_veh, id_edge_sumo, stopline=None):4594id_veh_sumo = self.get_id_sumo(id_veh)4595print 'init_trip_occupied', self.get_id_sumo(id_veh), 'from edge', id_edge_sumo, stopline4596# print ' current route:',traci.vehicle.getRoute(id_veh_sumo)4597self.states[id_veh] = VEHICLESTATES['occupiedtrip']45984599# print ' StopState=',bin(traci.vehicle.getStopState(id_veh_sumo ))[2:]4600if traci.vehicle.isStopped(id_veh_sumo):4601traci.vehicle.resume(id_veh_sumo)4602#traci.vehicle.changeTarget(self.get_id_sumo(id_veh), id_edge_sumo_dest)4603#traci.vehicle.changeTarget(self.get_id_sumo(id_veh), id_edge_sumo_dest)4604if stopline is not None:4605traci.vehicle.setStop(id_veh_sumo,4606id_edge_sumo,4607pos=stopline,4608laneIndex=1,4609)4610else:4611speed_crawl = 1.04612time_accel = 4.04613#traci.vehicle.slowDown(id_veh_sumo, speed_crawl, time_accel)46144615def init_trip_empty(self, id_veh, id_edge_sumo, stopline=None):4616print 'Vehicles.init_trip_empty', self.get_id_sumo(id_veh), id_edge_sumo, stopline4617self.states[id_veh] = VEHICLESTATES['emptytrip']4618id_veh_sumo = self.get_id_sumo(id_veh)4619if traci.vehicle.isStopped(id_veh_sumo):4620traci.vehicle.resume(id_veh_sumo)4621#traci.vehicle.changeTarget(id_veh_sumo, id_edge_sumo_to)4622if stopline is not None:4623# if stopline>=0:4624# print ' Route=',traci.vehicle.getRoute(id_veh_sumo)4625# print ' Position=',traci.vehicle.getLanePosition(id_veh_sumo),stopline4626# print ' StopState=',bin(traci.vehicle.getStopState(id_veh_sumo ))[2:]46274628traci.vehicle.setStop(id_veh_sumo,4629id_edge_sumo,4630pos=stopline,4631laneIndex=1,4632)4633else:4634speed_crawl = 1.04635time_accel = 4.04636#traci.vehicle.slowDown(id_veh_sumo, speed_crawl, time_accel)46374638def reschedule_trip_sumo(self, id_veh_sumo, id_edge_sumo_to=None, route_sumo=None):4639print 'reschedule_trip_sumo', id_veh_sumo, id_edge_sumo_to, route_sumo4640if traci.vehicle.isStopped(id_veh_sumo):4641traci.vehicle.resume(id_veh_sumo)46424643if route_sumo is not None:4644# set entire route4645traci.vehicle.setRoute(id_veh_sumo, route_sumo)4646else:4647# set new target and let SUMO do the routing4648traci.vehicle.changeTarget(id_veh_sumo, id_edge_sumo_to)46494650#4651#traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)4652# self.reset_speedmode(id_veh_sumo)4653#traci.vehicle.slowDown(id_veh_sumo, 13.0, 5.0)46544655def reschedule_trip(self, id_veh, id_edge_sumo_to=None, route_sumo=None):4656print 'reschedule_trip', self.get_id_sumo(id_veh), id_edge_sumo_to, route_sumo4657id_veh_sumo = self.get_id_sumo(id_veh)4658if traci.vehicle.isStopped(id_veh_sumo):4659traci.vehicle.resume(id_veh_sumo)46604661if route_sumo is not None:4662# set entire route4663traci.vehicle.setRoute(id_veh_sumo, route_sumo)4664else:4665# set new target and let SUMO do the routing4666traci.vehicle.changeTarget(id_veh_sumo, id_edge_sumo_to)46674668#4669# self.reset_speedmode(id_veh_sumo)4670# limit speed to run slowly on exit line4671# the merge will take over speed control46724673#traci.vehicle.setMaxSpeed(id_veh_sumo, 6.0/3.6)4674# print ' set speed to',traci.vehicle.getMaxSpeed(id_veh_sumo)4675#traci.vehicle.slowDown(id_veh_sumo, 13.0, 5.0)46764677def add_to_net(self, n=-1, length_veh_av=4.0):4678"""4679Add n PRT vehicles to network4680If n = -1 then fill up stops with vehicles.4681"""4682# print 'PrtVehicles.make',n,length_veh_av4683# self.clear()4684net = self.get_scenario().net4685ptstops = net.ptstops4686prtstops = self.parent.prtstops4687lanes = net.lanes4688ids_prtstop = prtstops.get_ids()4689ids_ptstop = prtstops.ids_ptstop[ids_prtstop]4690ids_veh = []4691n_stop = len(prtstops)46924693for id_prt, id_edge, pos_from, pos_to in zip(4694ids_prtstop,4695lanes.ids_edge[ptstops.ids_lane[ids_ptstop]],4696ptstops.positions_from[ids_ptstop],4697ptstops.positions_to[ids_ptstop],4698):4699# TODO: here we can select depos or distribute a4700# fixed number of vehicles or put them into berth4701# print ' ',pos_to,pos_from,int((pos_to-pos_from)/length_veh_av)4702if n > 0:4703n_veh_per_stop = int(float(n)/n_stop+0.5)4704else:4705n_veh_per_stop = int((pos_to-pos_from)/length_veh_av)4706# print ' n,n_stop,n_veh_per_stop',n,n_stop,n_veh_per_stop4707for i in range(n_veh_per_stop):4708id_veh = self.add_row(ids_stop_target=id_prt,4709ids_currentedge=id_edge,4710)47114712self.ids_sumo[id_veh] = self.get_id_sumo(id_veh)4713ids_veh.append(id_veh)47144715return ids_veh47164717# def write_veh4718#47194720def get_scenario(self):4721return self.parent.get_scenario()47224723def get_vtypes(self):4724"""4725Returns a set with all used PRT vehicle types.4726"""4727# print 'Vehicles_individual.get_vtypes',self.cols.vtype4728return set(self.ids_vtype.get_value())47294730def get_id_sumo(self, id_veh):4731return 'prt.%s' % (id_veh)47324733def get_id_from_id_sumo(self, id_veh_sumo):4734if len(id_veh_sumo.split('.')) == 2:4735prefix, id_veh = id_veh_sumo.split('.')4736if prefix == 'prt':4737return int(id_veh)4738else:4739return -14740return -147414742def get_ids_from_ids_sumo(self, ids_veh_sumo):4743n = len(ids_veh_sumo)4744ids = np.zeros(n, np.int32)4745for i in xrange(n):4746ids[i] = self.get_id_from_id_sumo(ids_veh_sumo[i])4747return ids47484749def get_id_line_xml(self):4750return 'prt'475147524753class PrtStrategy(StrategyMixin):4754def __init__(self, ident, parent=None,4755name='Personal Rapid Transit Strategy',4756info='With this strategy, the person uses Personla Rapid Transit as main transport mode.',4757**kwargs):47584759self._init_objman(ident, parent, name=name, info=info, **kwargs)4760attrsman = self.set_attrsman(cm.Attrsman(self))4761# specific init4762self._init_attributes()4763self._init_constants()47644765def _init_attributes(self):4766# print 'StrategyMixin._init_attributes'4767pass47684769def _init_constants(self):4770#virtualpop = self.get_virtualpop()4771#stagetables = virtualpop.get_stagetables()47724773#self._walkstages = stagetables.get_stagetable('walks')4774#self._ridestages = stagetables.get_stagetable('rides')4775#self._activitystages = stagetables.get_stagetable('activities')47764777#self._plans = virtualpop.get_plans()4778#4779# print 'AutoStrategy._init_constants'4780# print dir(self)4781# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])47824783modes = self.get_virtualpop().get_scenario().net.modes4784self._id_mode_bike = modes.get_id_mode('bicycle')4785self._id_mode_auto = modes.get_id_mode('passenger')4786self._id_mode_moto = modes.get_id_mode('motorcycle')4787self._id_mode_bus = modes.get_id_mode('bus')4788self.get_attrsman().do_not_save_attrs([4789'_id_mode_bike', '_id_mode_auto', '_id_mode_moto', '_id_mode_bus'4790])47914792def set_prtservice(self, prtservice):4793#self.add( cm.ObjConf( prtservice, is_child = False,groups = ['_private']))4794self.prtservice = prtservice4795self.get_attrsman().do_not_save_attrs(['prtservice'])47964797def preevaluate(self, ids_person):4798"""4799Preevaluation strategies for person IDs in vector ids_person.48004801Returns a preevaluation vector with a preevaluation value4802for each person ID. The values of the preevaluation vector are as follows:4803-1 : Strategy cannot be applied48040 : Stategy can be applied, but the preferred mode is not used48051 : Stategy can be applied, and preferred mode is part of the strategy48062 : Strategy uses predomunantly preferred mode48074808"""4809n_pers = len(ids_person)4810persons = self.get_virtualpop()4811preeval = np.zeros(n_pers, dtype=np.int32)48124813# TODO: here we could exclude by age or distance facilities-stops48144815# put 0 for persons whose preference is not public transport4816preeval[persons.ids_mode_preferred[ids_person] != self.prtservice.id_prtmode] = 048174818# put 2 for persons with car access and who prefer cars4819preeval[persons.ids_mode_preferred[ids_person] == self.prtservice.id_prtmode] = 248204821print ' PrtStrategy.preevaluate', len(np.flatnonzero(preeval))4822return preeval48234824def plan(self, ids_person, logger=None):4825"""4826Generates a plan for these person according to this strategie.4827Overriden by specific strategy.4828"""4829print 'PrtStrategy.pan', len(ids_person)4830#make_plans_private(self, ids_person = None, mode = 'passenger')4831# routing necessary?4832virtualpop = self.get_virtualpop()4833scenario = virtualpop.get_scenario()4834plans = virtualpop.get_plans() # self._plans4835demand = scenario.demand4836#ptlines = demand.ptlines48374838walkstages = plans.get_stagetable('walks')4839prtstages = plans.get_stagetable('prttransits')4840activitystages = plans.get_stagetable('activities')48414842activities = virtualpop.get_activities()4843activitytypes = demand.activitytypes4844prtstops = self.prtservice.prtstops48454846if len(prtstops) == 0:4847# no prt stops, no prt plans4848return True48494850net = scenario.net4851edges = net.edges4852lanes = net.lanes4853modes = net.modes4854landuse = scenario.landuse4855facilities = landuse.facilities48564857times_est_plan = plans.times_est4858# here we can determine edge weights for different modes48594860# this could be centralized to avoid redundance4861plans.prepare_stagetables(['walks', 'prttransits', 'activities'])4862# must be after preparation:4863if self.prtservice.times_stop_to_stop is None:4864self.prtservice.make_times_stop_to_stop()4865times_stop_to_stop = self.prtservice.times_stop_to_stop48664867ids_person_act, ids_act_from, ids_act_to\4868= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)48694870if len(ids_person_act) == 0:4871print 'WARNING in TrasitStrategy.plan: no eligible persons found.'4872return False48734874# temporary maps from ids_person to other parameters4875nm = np.max(ids_person_act)+14876map_ids_plan = np.zeros(nm, dtype=np.int32)4877#ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy())4878map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())48794880map_times = np.zeros(nm, dtype=np.int32)4881map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')48824883# set start time to plans (important!)4884plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]48854886map_ids_fac_from = np.zeros(nm, dtype=np.int32)4887map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]48884889n_plans = len(ids_person_act)4890print 'TrasitStrategy.plan n_plans=', n_plans48914892# make initial activity stage4893ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]4894poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]4895# this is the time when first activity starts4896# first activity is normally not simulated48974898names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]4899durations_act_from = activities.get_durations(ids_act_from)4900times_from = map_times[ids_person_act]-durations_act_from4901#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')49024903for id_plan,\4904time,\4905id_act_from,\4906name_acttype_from,\4907duration_act_from,\4908id_edge_from,\4909pos_edge_from \4910in zip(map_ids_plan[ids_person_act],4911times_from,4912ids_act_from,4913names_acttype_from,4914durations_act_from,4915ids_edge_from,4916poss_edge_from):49174918id_stage_act, time = activitystages.append_stage(4919id_plan, time,4920ids_activity=id_act_from,4921names_activitytype=name_acttype_from,4922durations=duration_act_from,4923ids_lane=edges.ids_lanes[id_edge_from][0],4924positions=pos_edge_from,4925)49264927##49284929ind_act = 049304931# main loop while there are persons performing4932# an activity at index ind_act4933while len(ids_person_act) > 0:4934ids_plan = map_ids_plan[ids_person_act]49354936times_from = map_times[ids_person_act]49374938names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]4939durations_act_to = activities.get_durations(ids_act_to)49404941ids_fac_from = map_ids_fac_from[ids_person_act]4942ids_fac_to = activities.ids_facility[ids_act_to]49434944centroids_from = facilities.centroids[ids_fac_from]4945centroids_to = facilities.centroids[ids_fac_to]4946dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1))4947dists_walk_max = virtualpop.dists_walk_max[ids_person_act]49484949# origin edge and position4950ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]4951poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]49524953# destination edge and position4954# attention, this methods assumes that all stops are reachable by foot4955ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]4956poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to]49574958# find closest prt stop!!4959ids_stop_from, ids_stopedge_from = prtstops.get_closest(centroids_from)4960ids_stop_to, ids_stopedge_to = prtstops.get_closest(centroids_to)49614962poss_stop_from = prtstops.get_waitpositions(ids_stop_from, offset=-0.5)4963poss_stop_to = prtstops.get_waitpositions(ids_stop_to, offset=-0.5)49644965i = 0.04966for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, id_stop_from, id_stopedge_from, pos_stop_from, id_stop_to, id_stopedge_to, pos_stop_to, dist_from_to, dist_walk_max\4967in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, ids_stop_from, ids_stopedge_from, poss_stop_from, ids_stop_to, ids_stopedge_to, poss_stop_to, dists_from_to, dists_walk_max):4968n_pers = len(ids_person_act)4969if logger:4970logger.progress(i/n_pers*100)4971i += 1.04972print 79*'_'4973print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person)49744975if (dist_from_to < dist_walk_max) | (id_edge_from == -1) | (id_edge_to == -1) | (id_stop_from == id_stop_to):4976print ' go by foot because distance is too short ', dist_from_to, 'edges', id_edge_from, id_edge_to, 'stops', id_stop_from, id_stop_to49774978id_stage_walk1, time = walkstages.append_stage(4979id_plan, time_from,4980id_edge_from=id_edge_from,4981position_edge_from=pos_edge_from,4982id_edge_to=id_edge_to,4983position_edge_to=pos_edge_to,4984)4985else:4986id_stage_walk1, time = walkstages.append_stage(id_plan, time_from,4987id_edge_from=id_edge_from,4988position_edge_from=pos_edge_from,4989id_edge_to=id_stopedge_from,4990position_edge_to=pos_stop_from, # -7.0,4991)49924993# take PRT4994# self.ids_edge_to_ids_prtstop4995id_stage_transit, time = prtstages.append_stage(4996id_plan, time,4997duration=times_stop_to_stop[id_stop_from, id_stop_to],4998id_fromedge=id_stopedge_from,4999id_toedge=id_stopedge_to,5000)50015002# walk from final prtstop to activity5003# print ' Stage for linktype %2d fromedge %s toedge %s'%(linktype, edges.ids_sumo[id_stopedge_to],edges.ids_sumo[id_edge_to] )5004id_stage_walk2, time = walkstages.append_stage(id_plan, time,5005id_edge_from=id_stopedge_to,5006position_edge_from=pos_stop_to,5007id_edge_to=id_edge_to,5008position_edge_to=pos_edge_to,5009)50105011# update time for trips estimation for this plan5012plans.times_est[id_plan] += time-time_from50135014# define current end time without last activity duration5015plans.times_end[id_plan] = time50165017id_stage_act, time = activitystages.append_stage(5018id_plan, time,5019ids_to=id_act_to,5020names_totype=name_acttype_to,5021durations=duration_act_to,5022ids_lane=edges.ids_lanes[id_edge_to][0],5023positions=pos_edge_to,5024)50255026# store time for next iteration in case other activities are5027# following5028map_times[id_person] = time50295030# select persons and activities for next setp5031ind_act += 15032ids_person_act, ids_act_from, ids_act_to\5033= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)503450355036class PrtTransits(StageTypeMixin):5037def __init__(self, ident, stages,5038name='Ride on PRT',5039info='Ride on Personal Rapid Transit network.',5040# **kwargs,5041):50425043print 'PrtTransits.__init__', ident, stages5044self.init_stagetable(ident,5045stages, name=name,5046info=info,5047)5048self._init_attributes()5049self._init_constants()50505051def _init_attributes(self):5052edges = self.get_virtualpop().get_net().edges50535054self.add_col(am.IdsArrayConf('ids_fromedge', edges,5055groupnames=['parameters'],5056name='Edge ID from',5057info='Edge ID of departure PRT station.',5058))50595060self.add_col(am.IdsArrayConf('ids_toedge', edges,5061groupnames=['parameters'],5062name='Edge ID to',5063info='Edge ID of destination PRT station.',5064))50655066def set_prtservice(self, prtservice):5067self.add(cm.ObjConf(prtservice, is_child=False, groups=['_private']))50685069def get_prtservice(self):5070return self.prtservice.get_value()50715072def prepare_planning(self):50735074prtservice = self.get_prtservice()5075print 'prttransits.prepare_planning', prtservice.times_stop_to_stop5076if prtservice.times_stop_to_stop is None:5077prtservice.make_times_stop_to_stop()5078print prtservice.times_stop_to_stop50795080def append_stage(self, id_plan, time_start=-1.0,5081duration=0.0,5082id_fromedge=-1, id_toedge=-1, **kwargs):5083"""5084Appends a PRT transit stage to plan id_plan.50855086"""5087# print 'PrtTransits.append_stage',id_stage50885089id_stage, time_end = StageTypeMixin.append_stage(self,5090id_plan,5091time_start,5092durations=duration,5093ids_fromedge=id_fromedge,5094ids_toedge=id_toedge,5095)50965097# add this stage to the vehicle database5098# ind_ride gives the index of this ride (within the same plan??)5099#ind_ride = self.parent.get_individualvehicles().append_ride(id_veh, id_stage)5100return id_stage, time_end51015102def to_xml(self, id_stage, fd, indent=0):5103# <ride from="1/3to0/3" to="0/4to1/4" lines="train0"/>5104net = self.get_virtualpop().get_net()5105#ids_stoplane = net.ptstops.ids_lane5106#ids_laneedge = net.lanes.ids_edge5107ids_sumoedge = net.edges.ids_sumo51085109#ind = self.get_ind(id_stage)5110fd.write(xm.start('ride', indent=indent))5111fd.write(xm.num('from', ids_sumoedge[self.ids_fromedge[id_stage]]))5112fd.write(xm.num('to', ids_sumoedge[self.ids_toedge[id_stage]]))5113fd.write(xm.num('lines', 'prt'))5114# if self.cols.pos_edge_from[ind]>0:5115# fd.write(xm.num('departPos', self.cols.pos_edge_from[ind]))5116# if self.cols.pos_edge_to[ind]>0:5117# fd.write(xm.num('arrivalPos', self.cols.pos_edge_to[ind]))51185119fd.write(xm.stopit()) # ends stage512051215122class VehicleMan(am.ArrayObjman):5123def __init__(self, ident, prtservices, **kwargs):5124self._init_objman(ident=ident,5125parent=prtservices,5126name='PRT vehicle management',5127info='PRT vehicle management.',5128#xmltag = ('additional','busStop','stopnames'),5129version=0.0,5130**kwargs)51315132self._init_attributes()5133self._init_constants()51345135def _init_attributes(self):5136self.add(cm.AttrConf('time_update', 2.0,5137groupnames=['parameters'],5138name='Man. update time',5139info="Update time for vehicle management.",5140unit='s',5141))51425143# self.time_update.set(5.0)51445145self.add(cm.AttrConf('time_update_flows', 10.0,5146groupnames=['parameters'],5147name='Flow update time',5148info="Update time for flow estimations.",5149unit='s',5150))5151# self.time_update.set(10.0)5152# if hasattr(self,'time_flowaverage'):5153# self.delete('time_flowaverage')51545155self.add(cm.AttrConf('time_est_max', 1200,5156groupnames=['parameters'],5157name='prediction interval',5158info="Prediction time range of vehicle management.",5159unit='s',5160))51615162self.add(cm.AttrConf('time_search_occupied', 10.0,5163groupnames=['parameters'],5164name='Occupied search time',5165info="Time interval for search of optimum departure time in case of an occupied vehicle trip.",5166unit='s',5167))51685169self.add(cm.AttrConf('time_search_empty', 20.0,5170groupnames=['parameters'],5171name='Empty search time',5172info="Time interval for search of optimum departure time in case of an empty vehicle trip.",5173unit='s',5174))51755176self.add(cm.AttrConf('weight_demand', 0.01,5177groupnames=['parameters'],5178name='Demand weight',5179info="Weight of current demand at stations when assigning empty vehicles trips.",5180))51815182self.add(cm.AttrConf('weight_flow', 1.0,5183groupnames=['parameters'],5184name='Flow weight',5185info="Weight of flows (changes in demand over time) at stations when assigning empty vehicles trips.",5186))51875188self.add(cm.AttrConf('constant_timeweight', 0.005,5189groupnames=['parameters'],5190name='Time weight const.',5191info="Constant for the exponential decay function weighting the time instance in the optimization function.",5192unit='1/s',5193))51945195# def set_stops(self,vehicleman):5196# self.add( cm.ObjConf( stops, is_child = False,groups = ['_private']))51975198def _init_constants(self):5199self.do_not_save_attrs([5200'ids_stop', 'numbers_veh_arr', 'n_est_max',5201'inflows_sched', 'inflows_person', 'inflows_person_last',5202'ids_veh', 'ids_stop_target', 'ids_stop_current',5203'times_order', 'occupiedtrips_new', 'emptytrips_new',5204'are_emptytrips',5205'log_inflows_temp',5206])52075208def get_stops(self):5209return self.parent.prtstops52105211def get_vehicles(self):5212return self.parent.prtvehicles52135214def get_scenario(self):5215return self.parent.parent.get_scenario()52165217def prepare_sim(self, process):5218print 'VehicleMan.prepare_sim'5219net = self.get_scenario().net5220# station management5221# self.ids_stop_to_ids_edge_sumo = np.zeros(np.max(ids)+1,dtype = np.object)52225223self.ids_stop = self.get_stops().get_ids()52245225if len(self.ids_stop) == 0:5226return []52275228n_stoparray = np.max(self.ids_stop)+15229self.numbers_veh_arr = np.zeros(n_stoparray, dtype=np.int32)52305231#self.n_est_max = self.time_est_max.get_value()/self.time_update_flows.get_value()5232self.n_est_max = int(self.time_est_max.get_value()/self.time_update_flows.get_value())5233self.inflows_sched = np.zeros((n_stoparray, self.n_est_max), dtype=np.int32)5234self.inflows_person = np.zeros(n_stoparray, dtype=np.int32)5235self.inflows_person_last = np.zeros(n_stoparray, dtype=np.int32)5236# vehicle management5237self.ids_veh = self.get_vehicles().get_ids()52385239if len(self.ids_veh) == 0:5240print 'WARNING: no PRT vehicles, please add PRT vehicles.'5241return []52425243n_veharray = np.max(self.ids_veh)+152445245# could go in vehicle array5246self.ids_stop_target = -1*np.ones(n_veharray, dtype=np.int32)5247self.ids_stop_current = -1*np.ones(n_veharray, dtype=np.int32)5248self.times_order = 10**6*np.ones(n_veharray, dtype=np.int32)5249# self.occupiedtrips_new = []#?? put this is also in general time scheme with more urgency??5250#self.emptytrips_new = []52515252# from veh arrays5253#self.are_emptytrips = np.zeros(n_veharray, dtype = np.bool)52545255# logging5256results = process.get_results()5257if results is not None:5258time_update_flows = self.time_update_flows.get_value()5259n_timesteps = int((process.duration-process.time_warmup)/time_update_flows+1)5260results.prtstopresults.init_recording(n_timesteps, time_update_flows)52615262self.log_inflows_temp = np.zeros(n_stoparray, dtype=np.int32)52635264return [(self.time_update.get_value(), self.process_step),5265(self.time_update_flows.get_value(), self.update_flows),5266]52675268def update_flows(self, process):5269# print 'update flow prediction'5270self.inflows_sched[:, 0] = 05271self.inflows_sched = np.roll(self.inflows_sched, -1)5272time_update_flows = self.time_update_flows.get_value()52735274if process.simtime > process.time_warmup:5275stops = self.get_stops()5276ids_stop = self.ids_stop5277prtstopresults = process.get_results().prtstopresults5278const_time = 1.0/time_update_flows # np.array([1.0/time_update_flows],dtype=np.float32)5279timestep = (process.simtime - process.simtime_start - process.time_warmup)/time_update_flows5280prtstopresults.record(timestep, ids_stop,5281inflows_veh=np.array(const_time * self.log_inflows_temp[ids_stop], dtype=np.float32),5282inflows_veh_sched=np.array(5283const_time * self.inflows_sched[ids_stop, 0], dtype=np.float32),5284numbers_person_wait=stops.numbers_person_wait[ids_stop],5285waittimes_tot=stops.waittimes_tot[ids_stop],5286inflows_person=np.array(const_time * self.inflows_person[ids_stop], dtype=np.float32),5287#inflows_person = stops.flows_person[ids_stop],5288)52895290self.inflows_person_last = self.inflows_person.copy()5291self.inflows_person[:] = 05292self.log_inflows_temp[:] = 052935294def process_step(self, process):5295print 79*'M'5296print 'VehicleMan.process_step'52975298stops = self.get_stops()5299#vehicles = self.get_vehicles()53005301has_programmed = True5302ids_veh_lead = stops.ids_veh_lead[self.ids_stop]5303inds_valid = np.flatnonzero(ids_veh_lead >= 0)5304while has_programmed:5305has_programmed = False53065307if len(inds_valid) > 0:53085309has_programmed |= self.push_occupied_leadvehs(ids_veh_lead[inds_valid], process)5310ids_veh_lead = stops.ids_veh_lead[self.ids_stop]5311inds_valid = np.flatnonzero(ids_veh_lead >= 0)5312# print ' self.ids_stop',self.ids_stop5313# print ' ids_veh_lead',ids_veh_lead5314has_programmed |= self.push_empty_leadvehs(ids_veh_lead[inds_valid], process)5315ids_veh_lead = stops.ids_veh_lead[self.ids_stop]5316inds_valid = np.flatnonzero(ids_veh_lead >= 0)53175318#has_programmed |= self.pull_empty_leadvehs(ids_veh_lead[inds_valid],process)5319#ids_veh_lead = stops.ids_veh_lead[self.ids_stop]5320#inds_valid = np.flatnonzero(ids_veh_lead >= 0)5321# print ' main:ids_veh_lead',has_programmed,len(inds_valid), stops.ids_veh_lead[self.ids_stop]5322else:5323# no more leaders5324has_programmed = False5325# print '\n terminated vehicle man n_est_max',self.n_est_max5326# print ' inflows_sched=\n',self.inflows_sched53275328def note_person_entered(self, id_stop, id_person_sumo, id_stop_dest):5329# here just estimate person flows5330self.inflows_person[id_stop] += 153315332def push_occupied_leadvehs(self, ids_veh_lead, process):5333n_timeslot_offset = 35334n_searchint = int(self.time_search_occupied.get_value()/self.time_update_flows.get_value()+0.5)5335stops = self.get_stops()5336vehicles = self.get_vehicles()53375338inds_valid = np.flatnonzero(vehicles.states[ids_veh_lead] == VEHICLESTATES['occupiedtrip'])5339if len(inds_valid) == 0:5340return False5341print 'push_occupied_leadvehs ids_veh_lead', ids_veh_lead[inds_valid]5342times_stop_to_stop = self.parent.times_stop_to_stop5343ids_stop_current = self.ids_stop_current[ids_veh_lead[inds_valid]]5344ids_stop_target = self.ids_stop_target[ids_veh_lead[inds_valid]]5345durations_est = times_stop_to_stop[ids_stop_current, ids_stop_target]5346# print ' duration_est, t_est_max',durations_est,self.n_est_max*self.time_update_flows.get_value()53475348inds_time_min = n_timeslot_offset+np.array(np.clip(np.array(1.0*durations_est/self.time_update_flows.get_value(5349), dtype=np.int32), 0, self.n_est_max-n_searchint-n_timeslot_offset), dtype=np.int32)5350inds_time_max = inds_time_min+n_searchint5351# print ' inds_time_min unclipped',n_timeslot_offset+np.array(1.0*durations_est/self.time_update_flows.get_value(),dtype=np.int32)5352# print ' inds_time_min clipped',inds_time_min5353# print ' inds_time_max',inds_time_max, self.inflows_sched.shape53545355for id_veh_lead, state, id_stop_current, id_stop_target, time_order, ind_min, ind_max, duration_est\5356in zip(5357ids_veh_lead[inds_valid],5358vehicles.states[ids_veh_lead[inds_valid]],5359self.ids_stop_current[ids_veh_lead[inds_valid]],5360self.ids_stop_target[ids_veh_lead[inds_valid]],5361self.times_order[ids_veh_lead[inds_valid]],5362inds_time_min,5363inds_time_max,5364durations_est,5365):53665367print ' check veh', id_veh_lead, state, 'id_stop_current', id_stop_current, 'id_stop_target', id_stop_target53685369#VEHICLESTATES = {'init':0,'waiting':1,'boarding':2,'alighting':3,'emptytrip':4,'occupiedtrip':5,'forewarding':6}5370# if state == VEHICLESTATES['occupiedtrip']:53715372#ids_stop = list(self.ids_stop)5373# ids_stop.remove(id_stop)5374#costs = (stops.numbers_person_wait[ids_stop]-stops.numbers_veh[ids_stop]-self.numbers_veh_arr[ids_stop])/self.parent.times_stop_to_stop[id_stop,ids_stop]5375#ids_stop [np.argmax(costs)]5376inds_time = np.arange(ind_min, ind_max)5377costs = self.inflows_sched[id_stop_target, inds_time]5378# print ' inds_time',inds_time5379# print ' inflows_sched',costs5380ind_time_depart = inds_time[np.argmin(costs)]53815382time_depart = process.simtime + ind_time_depart*self.time_update_flows.get_value()-duration_est5383# print ' ind_time_depart, time_arr, duration_est',ind_time_depart,process.simtime + ind_time_depart*self.time_update_flows.get_value(),duration_est5384# print ' time_order' ,time_order,'time_depart',time_depart,'delay',time_depart-time_order53855386stops.program_leadveh(id_stop_current, id_veh_lead, id_stop_target, time_depart)5387self.numbers_veh_arr[id_stop_target] += 15388self.inflows_sched[id_stop_target, ind_time_depart] += 153895390return True # at least one vehicle assigned53915392def push_empty_leadvehs(self, ids_veh_lead, process):5393n_timeslot_offset = 35394stops = self.get_stops()5395vehicles = self.get_vehicles()5396inds_valid = np.flatnonzero(vehicles.states[ids_veh_lead] == VEHICLESTATES['emptytrip'])5397if len(inds_valid) == 0:5398return False53995400print 'push_empty_leadvehs ids_veh_lead', ids_veh_lead[inds_valid]5401times_stop_to_stop = self.parent.times_stop_to_stop5402ids_stop_current = self.ids_stop_current[ids_veh_lead[inds_valid]]54035404n_stop_target = len(self.ids_stop)5405ids_stop_target = self.ids_stop.reshape(n_stop_target, 1)5406flow_person_est = (stops.flows_person[ids_stop_target] *5407self.time_update_flows.get_value()).reshape(n_stop_target, 1)5408n_searchint = int(self.time_search_empty.get_value()/self.time_update_flows.get_value()+0.5)5409inds_search_base = n_timeslot_offset + \5410np.arange(n_searchint, dtype=np.int32) * np.ones((n_stop_target, n_searchint), dtype=np.int32)54115412#self.numbers_veh = np.zeros(np.max(ids)+1, dtype = np.int32)5413#self.numbers_person_wait = np.zeros(np.max(ids)+1, dtype = np.int32)5414#self.flows_person = np.zeros(np.max(ids)+1, dtype = np.float32)5415#self.ids_veh_lead = -1*np.ones(np.max(ids)+1,dtype = np.int32)5416#self.ids_vehs_prog = np.zeros(np.max(ids)+1,dtype = np.object)5417is_started = False5418for id_veh_lead, id_stop_current, time_order, \5419in zip(5420ids_veh_lead[inds_valid],5421self.ids_stop_current[ids_veh_lead[inds_valid]],5422self.times_order[ids_veh_lead[inds_valid]],5423):54245425#id_stop_target = self.get_stop_emptytrip(id_stop_current)54265427durations_est = times_stop_to_stop[id_stop_current, ids_stop_target]5428ind_stop_current = np.flatnonzero(durations_est == 0)[0]5429print ' check veh', id_veh_lead, 'id_stop_current', id_stop_current, 'ind_stop_current', ind_stop_current5430inds_time_min = np.array(np.clip(np.array(1.0*durations_est/self.time_update_flows.get_value(),5431dtype=np.int32), 0, self.n_est_max-n_searchint), dtype=np.int32)5432inds_search = inds_search_base + inds_time_min.reshape(n_stop_target, 1)5433timeweight = np.exp(-self.constant_timeweight.get_value() * inds_search*self.time_update_flows.get_value())54345435# print ' demand',stops.numbers_person_wait[ids_stop_target]54365437costs = (self.weight_demand.get_value() * stops.waittimes_tot[ids_stop_target]5438+ self.weight_flow.get_value() * (flow_person_est-self.inflows_sched[ids_stop_target, inds_search])5439) * timeweight5440# costs = ( self.weight_demand.get_value() * ( stops.numbers_person_wait[ids_stop_target])\5441# + self.weight_flow.get_value() * (flow_person_est-self.inflows_sched[ids_stop_target, inds_search])\5442# )* timeweight54435444#costs = np.exp(+self.inflows_sched[ids_stop_target, inds_search]-flow_person_est)*timeweight5445#costs = (self.inflows_sched[ids_stop_target, inds_search]-flow_person_est)*timeweight5446costs[ind_stop_current, :] = -9999995447if 0:5448for ind, id_stop in zip(range(n_stop_target), ids_stop_target):5449print 40*'.'5450print ' id_stop', id_stop5451print ' waittimes_tot', stops.waittimes_tot[id_stop]5452print ' numbers_person_wait', stops.numbers_person_wait[id_stop]5453print ' flow_person_est', flow_person_est[ind]5454print ' inflows_sched', self.inflows_sched[id_stop, inds_search[ind]]5455print ' delta flow', (flow_person_est[ind]-self.inflows_sched[id_stop, inds_search[ind]])5456print ' demandcomp', self.weight_demand.get_value() * stops.numbers_person_wait[id_stop]5457print ' flowcomp', self.weight_flow.get_value() * (flow_person_est[ind]-self.inflows_sched[id_stop, inds_search[ind]])5458print ' arrivaltime est', inds_search[ind]*self.time_update_flows.get_value()5459print ' flow_person_est', flow_person_est[ind]546054615462# print ' flow_person_est',flow_person_#est5463print ' timeweight', timeweight[ind]5464print ' durations_est', durations_est[ind]5465print ' inds_search_base', inds_search_base[ind]5466# print ' inds_search unclipped\n',inds_search_base +np.array(1.0*durations_est/self.time_update_flows.get_value(),dtype=np.int32).reshape(n_stop_target,1)5467print ' inds_search clipped \n', inds_search[ind]5468print ' inds_time_min', inds_time_min[ind]5469# print ' ind_stop_current',ind_stop_current,durations_est[ind_stop_current]5470print ' costs=\n', costs[ind]5471# constant_timeweight54725473#5474ind_target = np.argmax(costs)5475ind_stop_target = ind_target/n_searchint5476#ind_time_arrive = ind_target%n_searchint+inds_time_min[ind_stop_target]5477ind_time_delta = ind_target % n_searchint5478ind_time_arrive = inds_search[ind_stop_target, ind_time_delta]5479if 0:5480print ' ind_target,n_searchint,ind_stop_target,ind_time_delta', ind_target, n_searchint, ind_target/n_searchint, ind_time_delta5481print ' ind_delta_depart,c_min', costs[ind_stop_target, ind_time_delta]5482print ' inds_time_min,ind_time_arrive', inds_time_min[ind_stop_target], ind_time_arrive54835484id_stop_target = ids_stop_target[ind_stop_target][0]5485time_depart = process.simtime + ind_time_arrive * \5486self.time_update_flows.get_value()-durations_est[ind_stop_target]5487# print '\n id_stop_target',id_stop_target5488# print ' time_order' ,time_order,'time_depart',time_depart,'delay',time_depart-time_order54895490is_started = stops.program_leadveh(id_stop_current, id_veh_lead, id_stop_target, time_depart)5491if is_started:5492self.numbers_veh_arr[id_stop_target] += 15493self.inflows_sched[id_stop_target, ind_time_arrive] += 15494else:5495print 'WARNING in push_empty_leadvehs: no vehicle prt.%d in stop %d' % (id_veh_lead, id_stop_target)5496return is_started54975498def pull_empty_leadvehs(self, ids_veh_lead, process):54995500n_timeslot_offset = 255015502#self.numbers_veh = np.zeros(np.max(ids)+1, dtype = np.int32)5503#self.numbers_person_wait = np.zeros(np.max(ids)+1, dtype = np.int32)55045505# inds_valid = np.flatnonzero( (vehicles.states[ids_veh_lead] == VEHICLESTATES['waiting'])\5506# & (stops.numbers_person_wait[self.ids_stop_current[ids_veh_lead]] == 0))5507vehicles = self.get_vehicles()5508stops = self.get_stops()5509print 'pull_empty_leadvehs', ids_veh_lead5510# print ' bordingstate',vehicles.states[ids_veh_lead] == VEHICLESTATES['boarding']5511# print ' nowaits stop',stops.numbers_person_wait[self.ids_stop_current[ids_veh_lead]] ==055125513times_stop_to_stop = self.parent.times_stop_to_stop55145515# get potential pull vehicles5516inds_valid = np.flatnonzero((vehicles.states[ids_veh_lead] == VEHICLESTATES['boarding'])5517& (stops.numbers_person_wait[self.ids_stop_current[ids_veh_lead]] == 0))55185519# print ' states',vehicles.states[ids_veh_lead], VEHICLESTATES['boarding']5520# print ' numbers_person_wait',stops.numbers_person_wait[self.ids_stop_current[ids_veh_lead]]5521# print ' &',(vehicles.states[ids_veh_lead] == VEHICLESTATES['boarding'])\5522# & (stops.numbers_person_wait[self.ids_stop_current[ids_veh_lead]] == 0)5523# print ' origins inds_valid',inds_valid5524if len(inds_valid) == 0:5525# print ' all stops busy'5526return False55275528#ids_veh_lead = ids_veh_lead[inds_valid]5529ids_stop_current = self.ids_stop_current[ids_veh_lead[inds_valid]]55305531# print ' available for pulling ids_veh_lead',ids_veh_lead5532# print ' ids_stop_current',ids_stop_current5533# get potential target station with demand5534demands = stops.numbers_person_wait[self.ids_stop]\5535- (0.5*stops.numbers_veh[self.ids_stop]5536+ self.numbers_veh_arr[self.ids_stop])5537inds_valid = np.flatnonzero(demands > 0)5538# print ' targets inds_valid',inds_valid5539if len(inds_valid) == 0:5540# print ' no demand'5541return False55425543ids_stop_target = self.ids_stop[inds_valid]5544demands = demands[inds_valid]55455546print ' ids_stop_current', ids_stop_current5547# print ' ids_stop_target',ids_stop_target5548# print ' demands',demands5549# calculate cost matrix with id_stop_current in rows and id_stop_target55505551#n_origin = len(ids_stop_current)5552#n_targets = len(ids_stop_target)5553times = times_stop_to_stop[ids_stop_current, :][:, ids_stop_target]5554times[times == 0] = 999995555timeweight = np.exp(-self.constant_timeweight.get_value() * times)5556#costs = times_stop_to_stop[ids_stop_current,:][:,ids_stop_target]5557#costs[costs == 0] = 999995558# print ' timeweight\n',timeweight55595560costs = timeweight * demands5561for id_stop_target, demand, number_veh, number_veh_arr\5562in zip(ids_stop_target, demands, stops.numbers_veh[ids_stop_target], self.numbers_veh_arr[ids_stop_target]):5563print ' id_stop_target', id_stop_target, 'dem', demand, 'n_veh', number_veh, 'n_veh_arr', number_veh_arr55645565#costs = np.zeros(costs.size, np.float32)-demands55665567inds_pull = np.argmax(costs, 1)5568# print ' costs\n',costs5569# print ' ->inds_pull,ids_stop_target',inds_pull,ids_stop_target[inds_pull]55705571durations_est = times_stop_to_stop[ids_stop_current, ids_stop_target[inds_pull]]5572# print ' duration_est, t_est_max',durations_est,self.n_est_max*self.time_update_flows.get_value()55735574inds_time_min = n_timeslot_offset+np.array(np.clip(np.array(1.0*durations_est/self.time_update_flows.get_value(5575), dtype=np.int32), 0, self.n_est_max-1-n_timeslot_offset), dtype=np.int32)5576inds_time_max = inds_time_min+25577# print ' inds_time_min',inds_time_min5578# print ' inds_time_max',inds_time_max55795580is_started = False5581for id_veh_lead, state, id_stop_current, id_stop_target, time_order, ind_min, ind_max, duration_est\5582in zip(5583ids_veh_lead[inds_valid],5584vehicles.states[ids_veh_lead],5585ids_stop_current,5586ids_stop_target[inds_pull],5587self.times_order[ids_veh_lead],5588inds_time_min,5589inds_time_max,5590durations_est,5591):55925593print ' check veh prt.%d' % (id_veh_lead), state, 'id_stop_current', id_stop_current, 'id_stop_target', id_stop_target55945595#VEHICLESTATES = {'init':0,'waiting':1,'boarding':2,'alighting':3,'emptytrip':4,'occupiedtrip':5,'forewarding':6}5596# if state == VEHICLESTATES['occupiedtrip']:55975598#ids_stop = list(self.ids_stop)5599# ids_stop.remove(id_stop)5600#costs = (stops.numbers_person_wait[ids_stop]-stops.numbers_veh[ids_stop]-self.numbers_veh_arr[ids_stop])/self.parent.times_stop_to_stop[id_stop,ids_stop]5601#ids_stop [np.argmax(costs)]5602inds_time = np.arange(ind_min, ind_max)5603costs = self.inflows_sched[id_stop_current, inds_time]5604ind_time_depart = inds_time[np.argmin(costs)]56055606self.inflows_sched[id_stop_target, ind_time_depart] += 15607time_depart = process.simtime + ind_time_depart*self.time_update_flows.get_value()-duration_est56085609# this is a workarouned that vehicle does first reach the stopline5610# before it gets rescheduled...try with stoplinecheck56115612# if time_depart < process.simtime+15:5613# time_depart = process.simtime+155614# print ' ind_time_depart, time_arr, duration_est',ind_time_depart,process.simtime + ind_time_depart*self.time_update_flows.get_value(),duration_est5615# print ' time_order' ,time_order,'time_depart',time_depart,'delay',time_depart-time_order56165617stops.program_leadveh(id_stop_current, id_veh_lead, id_stop_target, time_depart)5618self.numbers_veh_arr[id_stop_target] += 15619is_started = True56205621return is_started56225623def init_trip_occupied(self, id_veh, id_stop_from, id_stop_to, time_order):5624# print 'init_trip_occupied from',id_veh, id_stop_from, id_stop_to5625# search closest stop5626#self.are_emptytrips[id_veh] = False56275628self.ids_stop_current[id_veh] = id_stop_from5629self.ids_stop_target[id_veh] = id_stop_to5630self.times_order[id_veh] = time_order5631# print ' to stop',id_stop5632# return id_stop_to56335634def init_trip_empty(self, id_veh, id_stop, time_order):5635# print 'VehMan.init_trip_empty id_veh prt.%d,id_stop %d'%(id_veh,id_stop)5636# search closest stop5637self.ids_stop_current[id_veh] = id_stop5638self.times_order[id_veh] = time_order5639#self.are_emptytrips[id_veh] = True5640#id_stop_target = ids_stop[random.randint(0,len(ids_stop)-1)]5641# print ' to stop',id_stop5642# return id_stop_target56435644def indicate_trip_empty(self, id_veh, id_stop, time_order):5645# print 'indicate_trip_empty id_veh,id_stop',id_veh,id_stop5646# search closest stop5647self.ids_stop_current[id_veh] = id_stop5648self.times_order[id_veh] = time_order56495650def get_stop_emptytrip(self, id_stop):5651stops = self.get_stops()5652ids_stop = list(self.ids_stop)5653ids_stop.remove(id_stop)5654costs = (stops.numbers_person_wait[ids_stop]-stops.numbers_veh[ids_stop] -5655self.numbers_veh_arr[ids_stop])/self.parent.times_stop_to_stop[id_stop, ids_stop]56565657return ids_stop[np.argmax(costs)]56585659def conclude_trip(self, id_veh, id_stop):5660self.ids_stop_target[id_veh] = -15661self.numbers_veh_arr[id_stop] -= 156625663# measures actually arrived vehicles at stop5664# accumulates counts over one flow measurement interval5665self.log_inflows_temp[id_stop] += 1566656675668class PrtService(SimobjMixin, DemandobjMixin, cm.BaseObjman):5669def __init__(self, ident, simulation=None,5670name='PRT service', info='PRT service',5671**kwargs):5672# print 'PrtService.__init__',name56735674self._init_objman(ident=ident, parent=simulation,5675name=name, info=info, **kwargs)56765677attrsman = self.set_attrsman(cm.Attrsman(self))56785679# make PRTservice a demand object as link5680self.get_scenario().demand.add_demandobject(obj=self)56815682self._init_attributes()5683self._init_constants()56845685def get_scenario(self):5686return self.parent.parent56875688def _init_attributes(self):5689# print 'PrtService._init_attributes',hasattr(self,'prttransit')5690attrsman = self.get_attrsman()5691scenario = self.get_scenario()5692# here we ged classes not vehicle type5693# specific vehicle type within a class will be generated later5694modechoices = scenario.net.modes.names.get_indexmap()56955696# print ' modechoices',modechoices5697self.id_prtmode = attrsman.add(am.AttrConf('id_prtmode', modechoices['custom1'],5698groupnames=['options'],5699choices=modechoices,5700name='Mode',5701info='PRT transport mode (or vehicle class).',5702))57035704self.prtstops = attrsman.add(cm.ObjConf(PrtStops('prtstops', self)))5705self.compressors = attrsman.add(cm.ObjConf(Compressors('compressors', self)))5706self.decompressors = attrsman.add(cm.ObjConf(Decompressors('decompressors', self)))5707self.mergenodes = attrsman.add(cm.ObjConf(Mergenodes('mergenodes', self)))5708self.prtvehicles = attrsman.add(cm.ObjConf(PrtVehicles('prtvehicles', self)))5709self.vehicleman = attrsman.add(cm.ObjConf(VehicleMan('vehicleman', self)))57105711#self.demo = attrsman.add( cm.ObjConf(TraciDemo('demo',self)))57125713# --------------------------------------------------------------------5714# prt transit table5715# attention: prttransits will be a child of virtual pop,5716# and a link from prt service57175718# if not hasattr(self,'prttransit'):5719virtualpop = self.get_scenario().demand.virtualpop5720prttransits = virtualpop.get_plans().add_stagetable('prttransits', PrtTransits)57215722# print ' prttransits =',prttransits5723# add attribute as link5724# self.prttransits = attrsman.add(\5725# cm.ObjConf(prttransits,is_child = False ),5726# is_overwrite = False,)5727prttransits.set_prtservice(self)57285729prtstrategy = virtualpop.get_strategies().add_strategy(5730'prt', PrtStrategy, np.array([208, 50, 156, 230], np.float32)/255)5731# self.prttransits = attrsman.add(\5732# cm.ObjConf(prttransits,is_child = False ),5733# is_overwrite = False,)5734prtstrategy.set_prtservice(self)57355736# temporary attrfix5737#prtserviceconfig = self.parent.get_attrsman().prtservice5738#prtserviceconfig.groupnames = []5739#prtserviceconfig.add_groupnames(['demand objects'])57405741def _init_constants(self):5742# print 'PrtService._init_constants',self,self.parent5743attrsman = self.get_attrsman()5744self.times_stop_to_stop = None5745self.fstar = None5746self._results = None57475748attrsman.do_not_save_attrs(['times_stop_to_stop', 'fstar', '_results'5749'times_stop_to_stop', 'ids_edge_to_ids_prtstop',5750])57515752def get_vtypes(self):57535754ids_vtypes = set(self.prtvehicles.ids_vtype.get_value())5755return ids_vtypes57565757def get_writexmlinfo(self, is_route=False, is_plain=False, **kwargs):5758"""5759Returns three array where the first array is the5760begin time of the first vehicle and the second array is the5761write function to be called for the respectice vehicle and5762the third array contains the vehicle ids57635764Method used to sort trips when exporting to route or trip xml file5765"""5766print 'PRT.get_writexmlinfo'57675768# time of first PRT vehicle(s) to be inserted5769virtualpop = self.get_scenario().demand.virtualpop5770t_start = virtualpop.get_time_depart_first()57715772#t_start = 0.05773# time between insertion of consecutive vehicles at same stop5774t_delta = 10 # s57755776n_veh = len(self.prtvehicles)5777times_depart = np.zeros(n_veh, dtype=np.int32)5778writefuncs = np.zeros(n_veh, dtype=np.object)5779writefuncs[:] = self.write_prtvehicle_xml5780ids_veh = self.prtvehicles.get_ids()57815782id_edge_prev = -15783i = 05784t0 = t_start5785for id_edge in self.prtvehicles.ids_currentedge[ids_veh]:5786# print ' id_edge, t_start, id_edge_prev',id_edge, t0, id_edge_prev5787times_depart[i] = t05788t0 += t_delta5789if id_edge != id_edge_prev:5790t0 = t_start5791id_edge_prev = 1*id_edge5792i += 157935794return times_depart, writefuncs, ids_veh57955796def write_prtvehicle_xml(self, fd, id_veh, time_begin, indent=2):5797# print 'write_prtvehicle_xml',id_veh, time_begin5798# TODO: actually this should go in prtvehicles5799#time_veh_wait_after_stop = 36005800scenario = self.get_scenario()5801net = scenario.net58025803#lanes = net.lanes5804edges = net.edges5805#ind_ride = rides.get_inds(id_stage)5806#id_veh = rides.ids_veh[id_stage]5807prtvehicles = self.prtvehicles5808#ptstops = net.ptstops5809#prtstops = self.parent.prtstops5810#ids_prtstop = prtstops.get_ids()5811#ids_ptstop = prtstops.ids_ptstop[id_stop]5812# lanes.ids_edge[ptstops.ids_lane[ids_ptstop]],5813#id_lane_from = parking.ids_lane[id_parking_from]5814#laneindex_from = lanes.indexes[id_lane_from]5815#pos_from = parking.positions[id_parking_from]58165817#id_parking_to = rides.ids_parking_to[id_stage]5818#id_lane_to = parking.ids_lane[id_parking_to]5819#laneindex_to = lanes.indexes[id_lane_to]5820#pos_to = parking.positions[id_parking_to]58215822# write unique veh ID to prevent confusion with other veh declarations5823fd.write(xm.start('vehicle id="%s"' % prtvehicles.get_id_sumo(id_veh), indent+2))58245825fd.write(xm.num('depart', '%d' % time_begin))5826fd.write(xm.num('type', scenario.demand.vtypes.ids_sumo[prtvehicles.ids_vtype[id_veh]]))5827fd.write(xm.num('line', prtvehicles.get_id_line_xml()))5828fd.write(xm.stop())58295830# write route5831fd.write(xm.start('route', indent+4))5832# print ' edgeindex[ids_edge]',edgeindex[ids_edge]5833fd.write(xm.arr('edges', [edges.ids_sumo[prtvehicles.ids_currentedge[id_veh]]]))58345835# does not seem to have an effect, always starts at base????5836fd.write(xm.num('departPos', 'base'))5837#fd.write(xm.num('departLane', laneindex_from ))5838fd.write(xm.stopit())58395840# write depart stop5841# fd.write(xm.start('stop',indent+4))5842#fd.write(xm.num('lane', edges.ids_sumo[lanes.ids_edge[id_lane_from]]+'_%d'%laneindex_from ))5843#fd.write(xm.num('duration', time_veh_wait_after_stop))5844#fd.write(xm.num('startPos', pos_from ))5845#fd.write(xm.num('endPos', pos_from + parking.lengths[id_parking_from]))5846#fd.write(xm.num('triggered', "True"))5847# fd.write(xm.stopit())58485849fd.write(xm.end('vehicle', indent+2))58505851# def make_stops_and_vehicles(self, n_veh = -1):5852# self.prtstops.make_from_net()5853# self.prtvehicles.make(n_veh)5854# self.make_times_stop_to_stop()58555856def prepare_sim(self, process):5857print 'prepare_sim', self.ident5858# print ' self.times_stop_to_stop',self.times_stop_to_stop58595860if self.fstar is None:5861self.make_fstar()58625863if self.times_stop_to_stop is None:5864print ' times_stop_to_stop'5865self.make_times_stop_to_stop()58665867updatedata = self.prtvehicles.prepare_sim(process)5868updatedata += self.prtstops.prepare_sim(process)5869updatedata += self.compressors.prepare_sim(process)5870updatedata += self.decompressors.prepare_sim(process)5871updatedata += self.mergenodes.prepare_sim(process)5872updatedata += self.vehicleman.prepare_sim(process)5873#5874#updatedata += self.demo.prepare_sim(process)5875# print 'PrtService.prepare_sim updatedata',updatedata5876return updatedata58775878def make_fstar(self, is_update=False):5879if (self.fstar is None) | is_update:5880self.fstar = self.get_fstar()5881self.edgetimes = self.get_times(self.fstar)58825883def get_route(self, id_fromedge, id_toedge):5884"""5885Centralized function to determin fastest route between5886PRT network edges.5887"""5888duration, route = get_mincostroute_edge2edge(id_fromedge, id_toedge,5889weights=self.edgetimes, fstar=self.fstar)58905891return route, duration58925893def make_times_stop_to_stop(self, fstar=None, times=None):5894print 'make_times_stop_to_stop'5895log = self.get_logger()5896if fstar is None:5897if self.fstar is None:5898self.make_fstar()58995900fstar = self.fstar # get_fstar()5901times = self.edgetimes # self.get_times(fstar)59025903if len(fstar) == 0:5904self.times_stop_to_stop = [[]]5905return59065907ids_prtstop = self.prtstops.get_ids()5908if len(ids_prtstop) == 0:5909self.get_logger().w('WARNING: no PRT stops, no plans. Generate them!')5910return59115912ids_edge = self.prtstops.get_edges(ids_prtstop)59135914# check if all PRT stop edges are in fstar5915ids_ptstop = self.prtstops.ids_ptstop[ids_prtstop] # for debug only5916is_incomplete_fstar = False5917for id_edge, id_stop, id_ptstop in zip(ids_edge, ids_prtstop, ids_ptstop):5918# print ' Found PRT stop %d, PT stop %d with id_edge %d '%(id_stop,id_ptstop, id_edge)5919if not fstar.has_key(id_edge):5920print 'WARNING in make_times_stop_to_stop: PRT stop %d, PT stop %d has no id_edge %d in fstar' % (id_stop, id_ptstop, id_edge)5921is_incomplete_fstar = True59225923# check if fstar is complete (all to edges are in keys)5924ids_fromedge_set = set(fstar.keys())5925ids_sumo = self.get_scenario().net.edges.ids_sumo5926for id_fromedge in ids_fromedge_set:5927if not ids_fromedge_set.issuperset(fstar[id_fromedge]):5928is_incomplete_fstar = True5929ids_miss = fstar[id_fromedge].difference(ids_fromedge_set)5930print 'WARNING in make_times_stop_to_stop: incomplete fstar of id_fromedge = %d, %s' % (id_fromedge, ids_sumo[id_fromedge])5931for id_edge in ids_miss:5932print ' missing', id_edge, ids_sumo[id_edge]59335934if is_incomplete_fstar:5935return59365937# print ' ids_prtstop,ids_edge',ids_prtstop,ids_edge5938n_elem = np.max(ids_prtstop)+15939stop_to_stop = np.zeros((n_elem, n_elem), dtype=np.int32)59405941ids_edge_to_ids_prtstop = np.zeros(np.max(ids_edge)+1, dtype=np.int32)5942ids_edge_to_ids_prtstop[ids_edge] = ids_prtstop59435944ids_edge_target = set(ids_edge)59455946for id_stop, id_edge in zip(ids_prtstop, ids_edge):5947# print ' route for id_stop, id_edge',id_stop, id_edge59485949# remove origin from target5950ids_edge_target.discard(id_edge)59515952costs, routes = edgedijkstra(id_edge,5953ids_edge_target=ids_edge_target,5954weights=times, fstar=fstar5955)59565957# print ' ids_edge_target',ids_edge_target5958# print ' costs\n', costs5959# print ' routes\n', routes5960# for route in routes:5961# if len(route)==0:5962# print 'WARNING in make_times_stop_to_stop: empty route'5963# else:5964# print ' found route to id_edge, id_stop',route[-1],ids_edge_to_ids_prtstop[route[-1]],len(route)59655966if costs is not None:5967# TODO: could be vectorialized, but not so easy5968for id_edge_target in ids_edge_target:5969#stop_to_stop[id_edge,id_edge_target] = costs[id_edge_target]5970# print ' stop_orig,stop_target,costs ',ids_edge_to_ids_prtstop[id_edge],ids_edge_to_ids_prtstop[id_edge_target],costs[id_edge_target]5971# print ' stop_orig,costs ',ids_edge_to_ids_prtstop[id_edge],ids_sumo[id_edge]5972# print ' stop_target',ids_edge_to_ids_prtstop[id_edge_target],ids_sumo[id_edge_target]5973# print ' costs ',costs[id_edge_target]5974# stop_to_stop[ids_edge_to_ids_prtstop[[id_edge,id_edge_target]]]=costs[id_edge_target]5975if id_edge_target in costs:5976stop_to_stop[ids_edge_to_ids_prtstop[id_edge],5977ids_edge_to_ids_prtstop[id_edge_target]] = costs[id_edge_target]5978else:5979print 'WARNING in make_times_stop_to_stop: unreacle station id_fromedge = %d, %s' % (id_edge_target, ids_sumo[id_edge_target])5980is_incomplete_fstar = True59815982# put back origin to targets (probably not the best way)5983ids_edge_target.add(id_edge)5984# print ' ids_edge_target (all)',ids_edge_target59855986# print ' stop_to_stop',stop_to_stop5987# TODO: here we could also store the routes59885989if is_incomplete_fstar:5990return False59915992self.times_stop_to_stop = stop_to_stop5993self.ids_edge_to_ids_prtstop = ids_edge_to_ids_prtstop5994print ' times_stop_to_stop=\n', self.times_stop_to_stop5995return True59965997def get_fstar(self):5998"""5999Returns the forward star graph of the network as dictionary:6000fstar[id_fromedge] = set([id_toedge1, id_toedge2,...])6001"""6002print 'get_fstar'6003net = self.get_scenario().net6004# prt mode6005id_mode = self.id_prtmode60066007#ids_edge = self.get_ids()6008#fstar = np.array(np.zeros(np.max(ids_edge)+1, np.obj))6009fstar = {}6010connections = net.connections6011lanes = net.lanes60126013#inds_con = connections.get_inds()6014#ids_fromlane = connections.ids_fromlane.get_value()[inds_con]6015#ids_tolane = connections.ids_tolane.get_value()[inds_con]60166017ids_con = connections.get_ids()6018ids_fromlane = connections.ids_fromlane[ids_con]6019ids_tolane = connections.ids_tolane[ids_con]60206021ids_mainmode_from = lanes.ids_mode[ids_fromlane]6022ids_mainmode_to = lanes.ids_mode[ids_tolane]60236024#ids_modes_allow_from = lanes.ids_modes_allow[ids_fromlane]6025#ids_modes_allow_to = lanes.ids_modes_allow[ids_tolane]60266027ids_fromedge = lanes.ids_edge[ids_fromlane]6028ids_toedge = lanes.ids_edge[ids_tolane]6029# print ' ids_fromedge',ids_fromedge6030# print ' ids_modes_allow',ids_modes_allow60316032for id_fromedge, id_toedge, id_mode_allow_from, id_mode_allow_to, id_fromlane, id_tolane in\6033zip(ids_fromedge, ids_toedge, ids_mainmode_from, ids_mainmode_to,6034ids_fromlane, ids_tolane):60356036if id_mode_allow_from == id_mode:6037if id_mode_allow_to == id_mode:60386039if fstar.has_key(id_fromedge):6040fstar[id_fromedge].add(id_toedge)6041else:6042fstar[id_fromedge] = set([id_toedge])6043# if id_fromedge == 14048:6044# print ' id_fromedge, id_toedge',id_fromedge, id_toedge,fstar.has_key(id_fromedge)6045# print ' id_fromlane, id_tolane ',id_fromlane, id_tolane6046# print ' id_mode_allow_from, id_mode_allow_to',id_mode_allow_from, id_mode_allow_to60476048# for id_fromedge, id_toedge,ids_mode_allow_from,id_modes_allow_to in\6049# zip(ids_fromedge, ids_toedge, ids_modes_allow_from, ids_modes_allow_to):6050# if len(ids_mode_allow_from)>0:6051# if ids_mode_allow_from[-1] == id_mode:6052# if len(id_modes_allow_to)>0:6053# if id_modes_allow_to[-1] == id_mode:6054#6055# if fstar.has_key(id_fromedge):6056# fstar[id_fromedge].add(id_toedge)6057# else:6058# fstar[id_fromedge]=set([id_toedge])60596060return fstar60616062def get_times(self, fstar):6063"""6064Returns freeflow travel times for all edges.6065The returned array represents the speed and the index corresponds to6066edge IDs.60676068"""6069if len(fstar) == 0:6070return []60716072net = self.get_scenario().net6073#id_mode = net.modes.get_id_mode(mode)6074id_mode = self.id_prtmode6075# print 'get_times id_mode,is_check_lanes,speed_max',id_mode,is_check_lanes,speed_max6076ids_edge = np.array(fstar.keys(), dtype=np.int32)60776078times = np.array(np.zeros(np.max(ids_edge)+1, np.float32))6079speeds = net.edges.speeds_max[ids_edge]60806081# limit allowed speeds with max speeds of mode6082speeds = np.clip(speeds, 0.0, net.modes.speeds_max[id_mode])60836084times[ids_edge] = net.edges.lengths[ids_edge]/speeds60856086return times60876088def config_results(self, results):6089print 'PrtService.config_results', results, id(results)6090# keep a link to results here because needed to6091# log data during simulation6092# this link should not be followed during save process6093#self._results = results60946095tripresults = res.Tripresults('prttripresults', results,6096self.prtvehicles,6097self.get_scenario().net.edges,6098name='PRT trip results',6099info='Table with simulation results for each PRT vehicle. The results refer to the vehicle journey over the entire simulation period.',6100)6101results.add_resultobj(tripresults, groupnames=['Trip results'])61026103prtstopresults = Stopresults('prtstopresults', results, self.prtstops)6104results.add_resultobj(prtstopresults, groupnames=['PRT stop results'])61056106# def get_results(self):6107# return self._results61086109def process_results(self, results, process=None):6110pass611161126113class Stopresults(am.ArrayObjman):6114def __init__(self, ident, results, prtstops,6115name='Stop results',6116info='Table with simulation results of stops generated from vehicle management.',6117**kwargs):61186119self._init_objman(ident=ident,6120parent=results, # main results object6121info=info,6122name=name,6123**kwargs)61246125self.add(cm.AttrConf('time_step', 5.0,6126groupnames=['parameters'],6127name='Step time',6128info="Time of one recording step.",6129unit='s',6130))61316132self.add(cm.ObjConf(prtstops, is_child=False, # groupnames = ['_private']6133))61346135self.add_col(am.IdsArrayConf('ids_stop', prtstops,6136groupnames=['state'],6137is_index=True,6138name='PRT stop ID',6139info='ID of PRT stop.',6140))61416142attrinfos = [6143('inflows_veh', {'name': 'Vehicle in-flows', 'unit': '1/s',6144'dtype': np.float32, 'info': 'Vehicle flow into the stop over time.'}),6145('inflows_veh_sched', {'name': 'Sched. vehicle in-flows', 'unit': '1/s',6146'dtype': np.float32, 'info': 'Scheduled vehicle flow into the stop over time.'}),6147('inflows_person', {'name': 'Person in-flows', 'unit': '1/s',6148'dtype': np.float32, 'info': 'Person flow into the stop over time.'}),6149('numbers_person_wait', {'name': 'waiting person', 'dtype': np.int32,6150'info': 'Number of waiting persons at stop over time.'}),6151('waittimes_tot', {'name': 'total wait time', 'dtype': np.float32,6152'info': 'Wait times of all waiting persons at a stop over time.'}),6153]61546155for attrname, kwargs in attrinfos:6156self.add_resultattr(attrname, **kwargs)61576158def get_dimensions(self):6159return len(self), len(self.inflows_veh.get_default())61606161def get_prtstops(self):6162return self.prtstops.get_value()6163# return self.ids_stop.get_linktab()61646165def init_recording(self, n_timesteps, time_step):6166print 'init_recording n_timesteps, time_step', n_timesteps, time_step, len(self.ids_stop.get_linktab().get_ids())6167self.clear()61686169self.time_step.set_value(time_step)61706171for attrconfig in self.get_stopresultattrconfigs():6172# print ' reset attrconfig',attrconfig.attrname6173attrconfig.set_default(np.zeros(n_timesteps, dtype=attrconfig.get_dtype()))6174attrconfig.reset()6175# print ' default=',attrconfig.get_default(),attrconfig.get_default().dtype6176ids_stop = self.get_prtstops().get_ids()6177# print ' ids_stop',ids_stop6178self.add_rows(n=len(ids_stop), ids_stop=ids_stop)61796180def record(self, timestep, ids, **kwargs):6181inds = self.ids_stop.get_linktab().get_inds(ids)6182timestep_int = int(timestep)6183for attrname, values in kwargs.iteritems():6184# print ' record',attrname,'dtype',values.dtype,values.shape, 'array',getattr(self,attrname).get_value().dtype,'shape', getattr(self,attrname).get_value().shape6185# print ' inds',type(inds),inds.dtype,6186getattr(self, attrname).get_value()[inds, timestep_int] = values61876188def get_stopresultattrconfigs(self):6189return self.get_attrsman().get_group_attrs('PRT results').values()61906191def get_persons(self):6192return self.ids_person.get_linktab()61936194def add_resultattr(self, attrname, **kwargs):6195self.add_col(am.ArrayConf(attrname, 0, groupnames=['PRT results', 'results'], **kwargs))61966197def import_xml(self, sumo, datapaths):6198# no imports, data come from prtservice6199pass620062016202