Path: blob/main/tools/contributed/sumopy/coremodules/demand/vehicles.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 vehicles.py15# @author Joerg Schweizer16# @date 20121718import os19import sys20import string21from collections import OrderedDict22from xml.sax import saxutils, parse, handler23import numpy as np24from numpy import random25import agilepy.lib_base.classman as cm26import agilepy.lib_base.arrayman as am27import agilepy.lib_base.xmlman as xm28from agilepy.lib_base.misc import random_choice, get_inversemap2930from coremodules.network.network import SumoIdsConf, MODES3132LANECHANGEMODELS = ['LC2013', 'JE2013', 'DK2008', 'SL2015']3334# http://sumo.dlr.de/wiki/Models/Emissions/HBEFA3-based35EMISSIONCLASSES = {36'HBEFA3/Bus': 'average urban bus (all fuel types)',37'HBEFA3/Coach': 'average long distance bus (all fuel types)',38'HBEFA3/HDV': 'average heavy duty vehicle (all fuel types)',39'HBEFA3/HDV_G': 'average gasoline driven heavy duty vehicle',40'HBEFA3/HDV_D_EU0': 'diesel driven heavy duty vehicle Euro norm 0',41'HBEFA3/HDV_D_EU1': 'diesel driven heavy duty vehicle Euro norm 1',42'HBEFA3/HDV_D_EU2': 'diesel driven heavy duty vehicle Euro norm 2',43'HBEFA3/HDV_D_EU3': 'diesel driven heavy duty vehicle Euro norm 3',44'HBEFA3/HDV_D_EU4': 'diesel driven heavy duty vehicle Euro norm 4',45'HBEFA3/HDV_D_EU5': 'diesel driven heavy duty vehicle Euro norm 5',46'HBEFA3/HDV_D_EU6': 'diesel driven heavy duty vehicle Euro norm 6',47'HBEFA3/HDV_D_East': 'Eastern norm heavy duty',48'HBEFA3/zero': 'zero emission vehicle',49'HBEFA3/LDV': 'average light duty vehicles (all fuel types)',50'HBEFA3/LDV_G_EU0': 'gasoline driven light duty vehicle Euro norm 0',51'HBEFA3/LDV_G_EU1': 'gasoline driven light duty vehicle Euro norm 1',52'HBEFA3/LDV_G_EU2': 'gasoline driven light duty vehicle Euro norm 2',53'HBEFA3/LDV_G_EU3': 'gasoline driven light duty vehicle Euro norm 3',54'HBEFA3/LDV_G_EU4': 'gasoline driven light duty vehicle Euro norm 4',55'HBEFA3/LDV_G_EU5': 'gasoline driven light duty vehicle Euro norm 5',56'HBEFA3/LDV_G_EU6': 'gasoline driven light duty vehicle Euro norm 6',57'HBEFA3/LDV_G_East': 'Eastern norm light duty gasoline',58'HBEFA3/LDV_D_EU0': 'diesel driven light duty vehicle Euro norm 0',59'HBEFA3/LDV_D_EU1': 'diesel driven light duty vehicle Euro norm 1',60'HBEFA3/LDV_D_EU2': 'diesel driven light duty vehicle Euro norm 2',61'HBEFA3/LDV_D_EU3': 'diesel driven light duty vehicle Euro norm 3',62'HBEFA3/LDV_D_EU4': 'diesel driven light duty vehicle Euro norm 4',63'HBEFA3/LDV_D_EU5': ' diesel driven light duty vehicle Euro norm 5',64'HBEFA3/LDV_D_EU6': 'diesel driven light duty vehicle Euro norm 6',65'HBEFA3/PC': 'average passenger car (all fuel types)',66'HBEFA3/PC_Alternative': 'passenger car with alternative fuel technology',67'HBEFA3/PC_G_EU0': 'gasoline driven passenger car Euro norm 0',68'HBEFA3/PC_G_EU1': 'gasoline driven passenger car Euro norm 1',69'HBEFA3/PC_G_EU2': 'gasoline driven passenger car Euro norm 2',70'HBEFA3/PC_G_EU3': 'gasoline driven passenger car Euro norm 3',71'HBEFA3/PC_G_EU4': 'gasoline driven passenger car Euro norm 4',72'HBEFA3/PC_G_EU5': 'gasoline driven passenger car Euro norm 5',73'HBEFA3/PC_G_EU6': 'gasoline driven passenger car Euro norm 6',74'HBEFA3/PC_G_East': 'Eastern norm gasoline passenger car',75'HBEFA3/PC_D_EU0': 'diesel driven passenger car Euro norm 0',76'HBEFA3/PC_D_EU1': 'diesel driven passenger car Euro norm 1',77'HBEFA3/PC_D_EU2': 'diesel driven passenger car Euro norm 2',78'HBEFA3/PC_D_EU3': 'diesel driven passenger car Euro norm 3',79'HBEFA3/PC_D_EU4': 'diesel driven passenger car Euro norm 4',80'HBEFA3/PC_D_EU5': 'diesel driven passenger car Euro norm 5',81'HBEFA3/PC_D_EU6': 'diesel driven passenger car Euro norm 6 ',82}8384GUISHAPES = [85"pedestrian",86"bicycle",87"motorcycle",88"passenger",89"passenger/sedan",90"passenger/hatchback",91"passenger/wagon",92"passenger/van",93"delivery",94"truck",95"truck/semitrailer",96"truck/trailer",97"bus",98"bus/city",99"bus/flexible", # (length per carriage 8.25)100"bus/overland", # (length per carriage 8.25)101"rail", # (length per carriage 24.5)102"rail/light", # (length per carriage 16.85)103"rail/city", # (length per carriage 5.71)104"rail/slow", # (length per carriage 9.44)105"rail/fast", # (length per carriage 24.775)106"rail/cargo", # (length per carriage 13.86)107"evehicle",108"ship",109]110111CARFOLLOWMODELS = ['Krauss', 'KraussOrig1', 'PWagner2009', 'BKerner', 'IDM', 'IDMM',112'KraussPS', 'KraussAB', 'SmartSK', 'Wiedemann', 'W99', 'Daniel1', 'ACC', 'CACC', 'Rail']113114ALIGNMMENTS_LAT = ['center', 'left', 'right', 'compact', 'nice', 'arbitrary']115116117class Electricalprofiles(am.ArrayObjman):118def __init__(self, ident, parent, **kwargs):119print 'Electricalprofiles.__init__'120self._init_objman(ident=ident,121parent=parent,122name='Electrical profiles',123info='Profiles of different electrical subsystems, including battery and energy recovery',124version=0.0,125**kwargs)126self._init_attributes()127if len(self) == 0:128self.add_profiles_default()129130def _init_attributes(self):131print 'Electricalprofiles._init_attributes'132self.add_col(SumoIdsConf('profilename', name='Electric profile', perm='rw'))133self.add_col(am.ArrayConf('capacities_battery', 0.8,134groupnames=['parameters', 'key'],135name='Maximum battery capacity',136unit='Wh',137info='Maximum battery capacity',138xmltag='maximumBatteryCapacity',139))140141self.add_col(am.ArrayConf('efficiencies_reuperation', 0.8,142groupnames=['parameters', 'key'],143name='Recuperation efficiency',144info='Recuperation efficiency.',145xmltag='recuperationEfficiency',146))147148self.add_col(am.ArrayConf('speeds_charging', 0.1,149groupnames=['parameters', 'key'],150name='Min. charging speed',151unit='km/h',152info='Minimum velocity to start charging',153xmltag='stoppingTreshold',154))155156def add_profiles_default(self):157self.add_profile('evehicle',158capacity_battery=24000.0,159efficiency_reuperation=0.4,160speed_charging=0.03)161self.add_profile('ebus',162capacity_battery=80000.0,163efficiency_reuperation=0.4,164speed_charging=0.03)165self.add_profile('etram',166capacity_battery=100000.0,167efficiency_reuperation=0.6,168speed_charging=0.03)169# self.add_profile('prt',170# capacity_battery = 24000.0,171# efficiency_reuperation = 0.5,172# speed_charging = 0.03)173174def add_profile(self, profilename, **kwargs):175# print 'add_vtype',vtype,kwargs176if self.ids_sumo.has_index(profilename):177# vtype already exist178_id = self.ids_sumo.get_id_from_index(profilename)179else:180_id = self.add_row(ids_sumo=profilename)181182self.set_row(_id,183capacities_battery=kwargs.get("capacity_battery", None),184efficiencies_reuperation=kwargs.get("efficiency_reuperation", None),185speeds_charging=kwargs.get("speed_charging", None),186)187188189class VehicleTypes(am.ArrayObjman):190def __init__(self, parent, net, is_add_default=True, **kwargs):191print 'VehicleTypes.__init__ is_add_default', is_add_default192self._init_objman(ident='vtypes',193parent=parent,194name='Vehicle Types',195info='Table of all available vehicle types, each with specific physical characteristics. Each vehicle can be used multiple times in the simulation',196xmltag=('vTypes', 'vType', 'ids_sumo'),197version=0.4,198**kwargs)199self._init_attributes()200201if is_add_default:202# self.eprofiles.get_value().add_profiles_default()203self.add_vtypes_default()204self.set_version(0.3)205206def _init_attributes(self):207print 'VehicleTypes._init_attributes', len(self), self.get_ident_abs()208net = self.parent.get_net()209demand = self.parent210211# scalar parameters212# lanechange model is now centralized: all vehicle types have the same213# lanechange model.214if self.get_version() < 0.1:215self.delete('lanechangemodels')216self.delete('alignments_lat')217self.delete('speeds_max_lat')218self.delete('gaps_min_lat')219220self.add(cm.AttrConf('lanechangemodel', LANECHANGEMODELS[0],221groupnames=['parameters'],222choices=LANECHANGEMODELS,223name='Lanechange model',224info="Lanechange model. The choice of the lanechange model will also determine the choice of lanechange parameters. With model SL2015, sublanes will be simulated.",225# xmltag = 'laneChangeModel', # exported manually226))227228self.add(cm.AttrConf('pedestrian_model', 'striping',229groupnames=['parameters', 'pedestrian'],230name='Pedestrian Model',231choices=['striping', 'nonInteracting', 'None'],232perm='rw',233info='Type of Pedestrian model.',234#cml = optionprefix+'--pedestrian.model',235))236237self.add(cm.AttrConf('width_pedestrian_striping', 0.35,238groupnames=['parameters', 'pedestrian'],239name='Ped. stripe width',240unit='m',241perm='rw',242info="Width of parallel stripes for segmenting a sidewalk (meters) for use with model 'striping'",243#cml = optionprefix+'--pedestrian.striping.stripe-width',244))245246self.add(cm.AttrConf('slowdownfactor_pedestrian_striping', 0.2,247groupnames=['parameters', 'pedestrian'],248name='Ped. slowdown',249perm='rw',250info="Factor for random slow-downs [0,1] for use with model 'striping'",251#cml = optionprefix+'--pedestrian.striping.dawdling',252))253254self.add(cm.AttrConf('jamtime_pedestrian_striping', 10,255groupnames=['parameters', 'pedestrian'],256name='Ped. jamtime',257unit='s',258perm='rw',259info="Time before pedestrian jams are resolved. For use with model 'striping'",260#cml = optionprefix+'--pedestrian.striping.jamtime',261))262263self.add(cm.AttrConf('jamtime_pedestrian_crossing_striping', 10,264groupnames=['parameters', 'pedestrian'],265name='Ped. jamtime at crossing',266unit='s',267perm='rw',268info="Time before pedestrian jams are resolved at crossings. For use with model 'striping'",269#cml = optionprefix+'--pedestrian.striping.jamtime',270))271272self.add(cm.ObjConf(Electricalprofiles('eprofiles', self)))273274# column parameters275self.add_col(SumoIdsConf('vtype', name='Type name', perm='rw'))276277self.add_col(am.IdsArrayConf('ids_mode', net.modes,278perm='rw',279groupnames=['parameters'],280#choices = net.modes.names.get_indexmap(),281name='Mode',282info='ID of transport mode.',283xmltag='vClass',284xmlmap=get_inversemap(net.modes.names.get_indexmap())285))286# for temporary upgrade287if hasattr(self.ids_mode, 'choices'):288del self.ids_mode.choices289290self.ids_mode.set_perm('rw')291292# if self.get_version() < 0.2:293# ids_mode = getattr(self,'ids_mode')294# ids_mode.xmlmap = get_inversemap(net.modes.names.get_indexmap())295# ids_mode.groupnames = ['parameters']296297self.add_col(am.ArrayConf('shares_in_mode', 1.0,298groupnames=['parameters', 'planning'],299name='Share in mode',300info="Share of this vehicle type within the same transport mode",301xmltag='probability',302))303304self.add_col(am.ArrayConf('lengths', 5.0,305groupnames=['parameters', 'geometry'],306name='Length',307unit='m',308info="The vehicle's netto-length",309xmltag='length',310))311312self.add_col(am.ArrayConf('widths', 2.0,313groupnames=['parameters', 'geometry'],314name='Width',315unit='m',316info="The vehicle's width.",317xmltag='width',318))319320self.add_col(am.ArrayConf('heights', 1.5,321groupnames=['parameters', 'geometry'],322name='Height',323unit='m',324info="The vehicle's height.",325xmltag='height',326))327328self.add_col(am.ArrayConf('numbers_persons_initial', 1,329groupnames=['parameters', 'logistics'],330name='Passengers',331info="Initial number of persons in the vehicle.",332xmltag='personNumber',333))334335self.add_col(am.ArrayConf('capacities_persons', 1,336groupnames=['parameters', 'logistics'],337name='Capacity',338info="Maximum number of persons that fit in a vehicle.",339xmltag='personCapacity',340))341342self.add_col(am.ArrayConf('numbers_container', 0,343groupnames=['parameters', 'logistics'],344name='Containers',345info="Initial number of containers on the vehicle.",346xmltag='containerNumber',347))348349self.add_col(am.ArrayConf('speeds_max', 70.0,350groupnames=['parameters', 'mechanics'],351name='Max. speed',352unit='m/s',353info="The vehicle's maximum velocity",354xmltag='maxSpeed',355))356357self.add_col(am.ArrayConf('factors_speed', 1.0,358groupnames=['parameters', 'mechanics'],359name='Speed factor',360info="The vehicle's expected multiplicator for lane speed limits.",361xmltag='speedFactor',362))363364self.add_col(am.ArrayConf('deviations_speed', 0.0,365groupnames=['parameters', 'mechanics'],366name='Speed dev.',367info="The deviation of the speed factor.",368xmltag='speedDev',369))370371self.add_col(am.ArrayConf('accels', 0.8,372groupnames=['parameters', 'mechanics'],373name='Max. accel.',374unit='m/s^2',375info='The deceleration ability of vehicles of this type',376xmltag='accel',377))378379self.add_col(am.ArrayConf('decels', 3.0,380groupnames=['parameters', 'mechanics'],381name='Decel.',382unit='m/s^2',383info='The typical brake deceleration of vehicles of this type',384xmltag='decel',385))386387self.add_col(am.ArrayConf('decels_apparent', 4.5,388groupnames=['parameters', 'mechanics'],389name='Apparent. decel.',390unit='m/s^2',391info='The apparent deceleration of the vehicle as used by the standard model (in m/s^2). The follower uses this value as expected maximal deceleration of the leader',392xmltag='apparentDecel',393))394395self.add_col(am.ArrayConf('decels_emergency', 4.5,396groupnames=['parameters', 'mechanics'],397name='Emergency. decel.',398unit='m/s^2',399info='The maximal physically possible deceleration for the vehicle',400xmltag='emergencyDecel',401))402403self.add_col(am.ArrayConf('powers_max', 100000.0,404groupnames=['parameters', 'energy', 'key'],405name='Max. power',406unit='W',407info='The maximalum mechanical power that the vehicle can provide.',408xmltag='maximumPower',409))410411self.add_col(am.ArrayConf('masses', 1000.0,412groupnames=['parameters', 'mechanics', 'key'],413name='Mass',414unit='Kg',415info='Total vehicle mass',416xmltag='vehicleMass',417))418419self.add_col(am.ArrayConf('areas_front_surface', 4.0,420groupnames=['parameters', 'key'],421name='Front surface area',422unit='m^2',423info='Front surface area.',424xmltag='frontSurfaceArea',425))426427self.add_col(am.ArrayConf('coefficients_drag_air', 0.4,428groupnames=['parameters', 'mechanics', 'key'],429name='Air drag coefficient',430info='Air drag coefficient.',431xmltag='airDragCoefficient',432))433434self.add_col(am.ArrayConf('moments_inertia_internal', 0.01,435groupnames=['parameters', 'mechanics', 'key'],436name='Internal moment of inertia',437unit='Kg m^2',438info='Mom. of inertia of int. rot. elements.',439xmltag='internalMomentOfInertia',440))441442self.add_col(am.ArrayConf('coefficients_drag_radial', 0.5,443groupnames=['parameters', 'mechanics', 'key'],444name='Radial drag coefficient',445info='Radial drag coefficient.',446xmltag='radialDragCoefficient',447))448449self.add_col(am.ArrayConf('coefficients_drag_roll', 0.01,450groupnames=['parameters', 'mechanics', 'key'],451name='Rolling resistance coefficient',452info='Rolling resistance coefficient.',453xmltag='rollDragCoefficient',454))455456self.add_col(am.ArrayConf('powers_aux', 100.0,457groupnames=['parameters', 'energy', 'key'],458name='Constant auxiliary power',459unit='W',460info='Average constant auxiliary power intake (for electronics, airconditioning, lights, etc).',461xmltag='constantPowerIntake',462))463464self.add_col(am.ArrayConf('efficiencies propulsion', 0.9,465groupnames=['parameters', 'energy', 'key'],466name='Propulsion efficiency',467info='Drive efficiency, the ratio between mechanical energy and consumed tank energy (fuel or batteries).',468xmltag='propulsionEfficiency',469))470eprofiles = self.eprofiles.get_value()471self.add_col(am.IdsArrayConf('ids_eprofile', eprofiles,472groupnames=['parameters', 'energy'],473choices=eprofiles.ids_sumo.get_indexmap(),474name='Electrical profile',475info='Defines battery, energy recovery and charging parameters.',476))477478self.add_col(am.ArrayConf('taus', 1.0,479groupnames=['parameters', 'driver'],480name='Reaction',481unit='s',482info="The driver's reaction time in s (actually the minimum time gap)",483xmltag='tau',484))485486self.add_col(am.ArrayConf('sigmas', 0.5,487groupnames=['parameters', 'driver'],488name='Driver',489info='The driver imperfection in driving (between 0 and 1). Used only in follower models SUMOKrauss, SKOrig',490xmltag='sigma',491))492493self.add_col(am.ArrayConf('dists_min', 2.5,494groupnames=['parameters', 'driver'],495name='Min. gap',496unit='m',497info="Minimum empty space after leader.",498xmltag='minGap',499))500501self.add_col(am.ArrayConf('times_boarding', 15.0,502groupnames=['parameters', 'driver'],503name='boarding time',504unit='s',505info="The time required by a person to board the vehicle.",506xmltag='boardingDuration',507))508509self.add_col(am.ArrayConf('times_loading', 180.0,510groupnames=['parameters', 'driver'],511name='loading time',512unit='s',513info="The time required to load the vehicle.",514xmltag='loadingDuration',515))516517self.add_col(am.ArrayConf('have_reroute_device', False,518groupnames=['parameters'],519name='has reroute device',520info="Has a reroute device, which allows rerouting during the simulation. See also rerouting options",521xmltag='reroute',522))523524self.add_col(am.ArrayConf('have_taxi_device', False,525groupnames=['parameters'],526name='has taxi device',527info="Vehicles with taxi devices can act as taxis and pick up and drop people from the virtual population who are using the taxi strategy.",528# xmltag = '',# tag set explicitely529))530531emissionclasses_xml = {}532for key in EMISSIONCLASSES.keys():533emissionclasses_xml[key] = key # yes, map onto itself, otherwise choice values are taken534535self.add_col(am.ArrayConf('emissionclasses', 'HBEFA3/HDV_D_EU4',536dtype='object',537groupnames=['parameters', 'emissions'],538choices=get_inversemap(EMISSIONCLASSES),539name='Emission',540info="HBEFA3 emission class, see sourceforge.net/apps/mediawiki/sumo/index.php?title=Simulation/Models/Emissions/HBEFA-based",541xmltag='emissionClass',542xmlmap=emissionclasses_xml,543))544545self.add_col(am.ArrayConf('impatiences', -1000.0,546groupnames=['parameters', 'driver'],547name='Impatience',548info="Impatience offset between -1000.0 and 1.0 (-100 or less equals off). Impatience grows at 1/teleport. If 1.0 is reached driver will disrigard priorities.",549xmltag='impatience',550))551552self.add_col(am.ArrayConf('shapes_gui', "passenger",553dtype='object',554groupnames=['parameters', 'geometry'],555name='GUI shape',556choices=GUISHAPES,557info="How this vehicle is rendered.",558xmltag='guiShape',559))560561if self.get_version() < 0.3:562ids = self.get_ids()563changemap = {}564for _id, guishape in zip(ids, self.shapes_gui[ids]):565if guishape.split('/')[0] == 'transport':566guishape = guishape.replace('transport', 'truck')567self.shapes_gui.choices = 1*GUISHAPES568569self.add_col(am.ArrayConf('colors', np.array((1.0, 1.0, 1.0, 1.0), np.float32),570metatype='color',571groupnames=['parameters', 'geometry'],572name='Color',573info="This vehicle type's color as RGBA tuple with values from 0 to 1.0",574xmltag='color',575))576577self.add_col(am.ArrayConf('lanechange_strategies', 1.0,578groupnames=['parameters', 'lanechange'],579name='Lane strategy',580info="Lanechange model strategy factor. The eagerness for performing strategic lane changing. Higher values result in earlier lane-changing. default: 1.0, range [0-inf]",581xmltag='lcStrategic',582))583self.add_col(am.ArrayConf('lanechange_coops', 1.0,584groupnames=['parameters', 'lanechange'],585name='Lane coop',586info="Lanechange model cooperative factor.The willingness for performing cooperative lane changing. Lower values result in reduced cooperation. default: 1.0, range [0-1]",587xmltag='lcCooperative',588))589590self.add_col(am.ArrayConf('lanechange_gains', 1.0,591groupnames=['parameters', 'lanechange'],592name='Lane gain',593info="Lanechange model gain factor.The eagerness for performing lane changing to gain speed. Higher values result in more lane-changing. default: 1.0, range [0-inf]",594xmltag='lcSpeedGain',595))596597self.add_col(am.ArrayConf('lanechange_rightkeepings', 1.0,598groupnames=['parameters', 'lanechange'],599name='Lane right',600info="Lanechange model keep right factor.The eagerness for following the obligation to keep right. Higher values result in earlier lane-changing. default: 1.0, range [0-inf]",601xmltag='lcKeepRight',602))603604self.add_col(am.ArrayConf('sublane_alignments_lat', ALIGNMMENTS_LAT[0],605dtype='object',606groupnames=['parameters', 'sublane'],607choices=ALIGNMMENTS_LAT,608name='sublane alignment',609info='Lateral alignment within a lane. For sublane model only.',610xmltag='latAlignment',611))612613self.add_col(am.ArrayConf('sublane_speeds_max_lat', 1.0,614groupnames=['parameters', 'sublane'],615name='Sublane max. speed',616unit='m/s',617info="The vehicle's maximum velocity in lateral direction. For sublane model only.",618xmltag='maxSpeedLat',619))620621self.add_col(am.ArrayConf('sublane_accel_lat', 2.5,622groupnames=['parameters', 'sublane'],623name='Sublane accel',624unit='m/s^2',625info="The vehicle's acceleration in lateral direction. For sublane model only.",626xmltag='lcAccelLat',627))628629self.add_col(am.ArrayConf('sublane_gaps_min_lat', 0.12,630groupnames=['parameters', 'sublane'],631name='Sublane min. gap',632unit='m',633info="The vehicle's minimum distance to other vehicles in lateral direction. For sublane model only.",634xmltag='minGapLat',635))636637self.add_col(am.ArrayConf('sublane_alignments_eager', 1.0,638groupnames=['parameters', 'sublane'],639name='Sublane eager',640info="The eagerness using the configured lateral alignment within the lane. Higher values result in increased willingness to sacrifice speed for alignment. default: 1.0, range [0-inf]. For sublane model only.",641xmltag='lcSublane',642))643644self.add_col(am.ArrayConf('sublane_assertive', 1.0,645groupnames=['parameters', 'sublane'],646name='Sublane assertive',647info="Willingness to accept lower front and rear gaps on the target lane. default: 0, range 0 to 1. For sublane model only.",648xmltag='lcAssertive',649))650651self.add_col(am.ArrayConf('sublane_pushyfactors', 0.0,652groupnames=['parameters', 'sublane'],653name='Sublane pushy',654info="Willingness to encroach laterally on other drivers. default: 0.0, range 0 or 1. For sublane model only.",655xmltag='lcPushy',656))657self.add_col(am.ArrayConf('sublane_impatiences', 1.0,658groupnames=['parameters', 'sublane'],659name='Sublane impatience',660info="dynamic factor for modifying lcAssertive and lcPushy. default: 0 (no effect) range -1 to 1. Impatience acts as a multiplier. At -1 the multiplier is 0.5 and at 1 the multiplier is 1.5. For sublane model only.",661xmltag='lcImpatience',662))663664self.add_col(am.ArrayConf('sublane_time_to_impatiences', 1,665groupnames=['parameters', 'sublane'],666name='Sublane time to impatience',667info="Time to reach maximum impatience (of 1). Impatience grows whenever a lane-change manoeuvre is blocked.. For sublane model only.",668unit='s',669xmltag='lcTimeToImpatience',670))671672self.add_col(am.ArrayConf('carfollowermodels', CARFOLLOWMODELS[0], # Kraus673groupnames=['parameters', 'driver'],674choices=CARFOLLOWMODELS,675name='Carfollower model',676info="Carfollower model.",677xmltag='carFollowModel',678))679680if hasattr(self, 'sublane_impatience'):681self.delete('sublane_impatience')682self.delete('sublane_time_to_impatience')683684# this provides a link from public transport to vtypes685# demand.ptlines.set_vtypes(self)686687self.add(cm.FuncConf('func_make_row', 'on_add_row', None,688groupnames=['rowfunctions', '_private'],689name='New type',690info='Add a new vehicle type or dublicate when called with ID.',691is_returnval=False,692))693694self.add(cm.FuncConf('func_delete_row', 'on_del_row', None,695groupnames=['rowfunctions', '_private'],696name='Del type',697info='Delete vehicle type.',698is_returnval=False,699))700701self.attrconfignames_pedestrian = ['lengths', 'widths', 'heights',702'speeds_max', 'factors_speed',703'deviations_speed', 'accels', 'decels',704'taus', 'dists_min', 'ids_mode',705'emissionclasses', 'impatiences', 'shapes_gui',706'colors']707708self.do_not_save_attrs(['attrconfignames_pedestrian'])709710def format_ids(self, ids):711return ','.join(self.ids_sumo[ids])712713def get_id_from_formatted(self, idstr):714return self.ids_sumo.get_id_from_index(idstr)715716def get_ids_from_formatted(self, idstrs):717return self.ids_sumo.get_ids_from_indices_save(idstrs.split(','))718719def on_del_row(self, id_row=None):720if id_row is not None:721# print 'on_del_row', id_row722self.del_row(id_row)723724def on_add_row(self, id_row=None):725# print 'on_add_row',id_row,len(self),(id_row is None)|(len(self)==0)726if (id_row is None) | (len(self) == 0):727# print ' first'728_id = self.add_row()729# print ' add id=',_id730elif id_row is not None:731732row_last = self.get_row(id_row)733id_sumo = row_last['ids_sumo']734id_data = id_sumo.split('_')735# print ' clone',id_data,len(id_data)736i = 1737if len(id_data) == 1:738row_last['ids_sumo'] = id_sumo+'_%03d' % i739else:740# print ' create new i',int(id_data[-1])741try:742i = int(id_data[-1])743i += 1744id_sumo = id_data[0]745for s in id_data[1:-1]:746id_sumo += '_'+s747# print ' new i:',i,id_sumo+'_%03d'%i748row_last['ids_sumo'] = id_sumo+'_%03d' % i749except:750id_sumo = id_data[0]751for s in id_data[1:]:752id_sumo += '_'+s753754row_last['ids_sumo'] = id_sumo+'_%03d' % i755756# print ' row_last',row_last757_id = self.add_row(**row_last)758# print ' _id',_id759else:760print ' clone last'761i = 1762row_last = self.get_row(self.get_ids()[-1])763row_last['ids_sumo'] += '_%03d' % i # important for all indexed attrs!!764# print ' row_last',row_last765_id = self.add_row(**row_last)766# print ' _id',_id767768def clear_vtypes(self):769self.clear()770771def add_vtype_parser(self, vtype, **kwargs):772if self.ids_sumo.has_index(vtype):773# vtype already exist774id_vtype = self.ids_sumo.get_id_from_index(vtype)775self.set_row(id_vtype, **kwargs)776return id_vtype777else:778id_vtype = self.add_row(ids_sumo=vtype, **kwargs)779return id_vtype780781def add_vtype(self, vtype, **kwargs):782print 'add_vtype', vtype, kwargs783if self.ids_sumo.has_index(vtype):784# vtype already exist785_id = self.ids_sumo.get_id_from_index(vtype)786else:787_id = self.add_row(ids_sumo=vtype)788789if kwargs.has_key('mode'):790id_mode = MODES.get(kwargs['mode'], 1)791del kwargs['mode']792elif kwargs.has_key('id_mode'):793id_mode = kwargs['id_mode']794del kwargs['id_mode']795else:796id_mode = 1797798#_id = self.add_row( ids_sumo = vtype, ids_mode = id_mode,**kwargs)799800if kwargs.has_key('eprofile'):801eprofiles = self.eprofiles.get_value()802eprofile = kwargs['eprofile']803eprofiles.add_profile(eprofile, **kwargs)804id_eprofile = eprofiles.ids_sumo.get_id_from_index(eprofile)805emissionclass = 'Energy/unknown'806else:807id_eprofile = -1808emissionclass = kwargs.get("emissionclass", None),809810self.set_row(_id,811shares_in_mode=kwargs.get("share_in_mode", 1.0),812accels=kwargs.get("accel", 2.9),813decels=kwargs.get("decel", 4.5),814decels_apparent=kwargs.get("decel_apparent", 4.5),815decels_emergency=kwargs.get("decel_emergency", 4.5),816taus=kwargs.get("tau", None),817sigmas=kwargs.get("sigma", 0.5),818lengths=kwargs.get("length", 4.3),819widths=kwargs.get("width", 1.8),820heights=kwargs.get("height", 1.50),821dists_min=kwargs.get("dist_min", 1.0),822speeds_max=kwargs.get("speed_max", 180.0/3.6),823factors_speed=kwargs.get("factor_speed", 1.0),824deviations_speed=kwargs.get("deviation_speed", 0.0),825ids_mode=id_mode, # specifies mode for demand826colors=kwargs.get("color", np.array((185, 85, 255, 255), np.float32)/255.0),827impatiences=kwargs.get("impatience", -1000),828shapes_gui=kwargs.get("shape_gui", 'passenger'),829numbers_persons=kwargs.get("number_persons", None),830capacities_persons=kwargs.get("capacity_persons", None),831emissionclasses=emissionclass,832lanechanges=kwargs.get("lanechange", None),833lanechange_strategies=kwargs.get("lanechange_strategy", None),834lanechange_coops=kwargs.get("lanechange_coop", None),835lanechange_gains=kwargs.get("lanechange_gain", None),836lanechange_rightkeepings=kwargs.get("lanechange_rightkeeping", None),837sublane_alignments_lat=kwargs.get("sublane_alignment_lat", None),838sublane_speeds_max_lat=kwargs.get("sublane_speed_max_lat", None),839sublane_gaps_min_lat=kwargs.get("sublane_gap_min_lat", None),840sublane_alignments_eager=kwargs.get("sublane_alignment_eager", None),841sublane_pushyfactors=kwargs.get("sublane_pushyfactor", None),842sublane_impatiences=kwargs.get("sublane_impatience", None),843sublane_time_to_impatiences=kwargs.get("sublane_time_to_impatience", None),844#845powers_max=kwargs.get("power_max", None),846masses=kwargs.get("mass", None),847areas_front_surface=kwargs.get("area_front_surface", kwargs.get(848"width", 1.8)*kwargs.get("height", 1.50)),849coefficients_drag_air=kwargs.get("coefficient_drag_air", None),850moments_inertia_internal=kwargs.get("moment_inertia_internal", None),851coefficients_drag_radial=kwargs.get("coefficient_drag_radial", None),852coefficients_drag_roll=kwargs.get("coefficient_drag_roll", None),853efficiencies_propulsion=kwargs.get("efficiency_propulsion", None),854ids_eprofile=id_eprofile,855have_taxi_device=kwargs.get("has_taxi_device", False),856have_reroute_device=kwargs.get("has_reroute_device", False),857carfollowermodel=kwargs.get("carfollowermodel", CARFOLLOWMODELS[0]),858)859860return _id861862def add_vtypes_default(self):863print 'add_vtypes_default'864# self.del_rows(self.get_ids())865self.add_vtype('pedestrian',866accel=1.5,867decel=2.0,868decel_apparent=3.0,869decel_emergency=3.0,870sigma=0.5,871length=0.25,872width=0.44,873height=1.719,874number_persons=1,875capacity_persons=1,876dist_min=0.05,877speed_max=5.4/3.6,878deviation_speed=0.2,879mode='pedestrian', # specifies mode for demand880color=np.array((210, 128, 0, 255), np.float32)/255.0,881shape_gui='pedestrian',882impatience=1.0,883emissionclass='HBEFA3/zero',884times_boarding=0.0,885times_loading=0.0,886sublane_alignment_lat='nice',887sublane_speed_max_lat=0.5,888sublane_gap_min_lat=0.5,889sublane_alignment_eager=0.5,890sublane_pushyfactor=0.5,891carfollowermodel=CARFOLLOWMODELS[0],892)893894self.add_vtype('passenger1',895accel=2.9,896decel=3.0,897decel_apparent=8.0,898decel_emergency=8.0,899sigma=0.5,900length=4.3,901height=1.50,902width=1.8,903number_persons=1,904capacity_persons=4,905dist_min=1.0,906speed_max=180.0/3.6,907deviation_speed=0.1,908mode='passenger', # specifies mode for demand909color=np.array((185, 85, 255, 255), np.float32)/255.0,910shape_gui='passenger',911impatience=1.0,912emissionclass='HBEFA3/PC',913times_boarding=10.0,914times_loading=90.0,915sublane_alignment_lat='center',916sublane_speed_max_lat=1.0,917sublane_gap_min_lat=0.12,918carfollowermodels=CARFOLLOWMODELS[0],919)920921self.add_vtype('bicycle',922accel=1.2,923decel=3.0,924decel_apparent=8.0,925decel_emergency=8.0,926sigma=0.7,927length=1.6,928width=0.9,929height=1.7,930number_persons=1,931capacity_persons=1,932dist_min=0.5,933speed_max=18.0/3.6,934deviation_speed=0.2,935mode='bicycle', # specifies mode for demand936impatience=1.0,937emissionclass='HBEFA3/zero',938color=np.array((94, 203, 57, 255), np.float32)/255.0,939shape_gui='bicycle',940lanechange_strategy=1.0,941lanechange_coop=1.0,942lanechange_gain=1.0,943lanechange_rightkeeping=1.0,944times_boarding=15.0,945times_loading=0.0,946sublane_alignment_lat='right',947sublane_speed_max_lat=0.8,948sublane_gap_min_lat=0.12,949sublane_alignment_eager=1.0,950sublane_pushyfactor=0.0,951)952953self.add_vtype('vespa',954accel=4.5,955decel=4.5,956decel_apparent=8.0,957decel_emergency=8.0,958sigma=0.7,959length=1.5,960height=1.7,961width=0.95,962number_persons=1,963capacity_persons=1,964dist_min=0.5,965speed_max=60.0/3.6,966deviation_speed=0.1,967mode='moped', # specifies mode for demand968impatience=1.0,969emissionclass='HBEFA3/LDV_G_EU3',970color=np.array((205, 92, 0, 255), np.float32)/255.0,971shape_gui='motorcycle',972times_boarding=20.0,973times_loading=10.0,974sublane_alignment_lat='left',975sublane_speed_max_lat=1.0,976sublane_gap_min_lat=0.12,977sublane_alignment_eager=0.9,978sublane_pushyfactor=0.8,979)980981self.add_vtype('motorcycle',982accel=4.5,983decel=4.5,984decel_apparent=8.0,985decel_emergency=8.0,986sigma=0.7,987length=1.5,988height=1.7,989width=0.95,990number_persons=1,991capacity_persons=1,992dist_min=0.5,993speed_max=180.0/3.6,994deviation_speed=0.1,995mode='motorcycle', # specifies mode for demand996impatience=1.0,997emissionclass='HBEFA3/LDV_G_EU3',998color=np.array((205, 92, 0, 255), np.float32)/255.0,999shape_gui='motorcycle',1000times_boarding=20.0,1001times_loading=10.0,1002sublane_alignment_lat='left',1003sublane_speed_max_lat=1.0,1004sublane_gap_min_lat=0.12,1005sublane_alignment_eager=0.9,1006sublane_pushyfactor=0.8,1007)10081009self.add_vtype('taxi1',1010accel=1.9,1011decel=2.5,1012decel_apparent=8.0,1013decel_emergency=8.0,1014sigma=0.5,1015length=5.0,1016height=1.80,1017width=1.8,1018number_persons=1,1019capacity_persons=4,1020dist_min=1.0,1021speed_max=180.0/3.6,1022deviation_speed=0.05,1023mode='taxi', # specifies mode for demand1024color=np.array((185, 185, 255, 255), np.float32)/255.0,1025shape_gui='passenger/sedan',1026impatience=1.0,1027emissionclass='HBEFA3/PC',1028times_boarding=30.0,1029times_loading=90.0,1030sublane_alignment_lat='center',1031sublane_speed_max_lat=0.8,1032sublane_gap_min_lat=0.12,1033has_taxi_device=True,1034)10351036self.add_vtype('bus',1037share_in_mode=0.5,1038accel=1.2,1039decel=2.0,1040decel_apparent=8.0,1041decel_emergency=8.0,1042sigma=0.9,1043length=12.0,1044height=3.4,1045width=2.5,1046number_persons=20,1047capacity_persons=85,1048dist_min=0.5,1049speed_max=80.0/3.6,1050deviation_speed=0.05,1051mode='bus', # specifies mode for demand1052impatience=1.0,1053emissionclass='HBEFA3/Bus',1054color=np.array((255, 192, 0, 255), np.float32)/255.0,1055shape_gui='bus',1056times_boarding=2.0,1057times_loading=0.0,1058sublane_alignment_lat='center',1059sublane_speed_max_lat=0.5,1060sublane_gap_min_lat=0.24,1061sublane_alignment_eager=10.0,1062)10631064self.add_vtype('bus_flexible',1065share_in_mode=0.5,1066accel=1.2,1067decel=2.0,1068decel_apparent=8.0,1069decel_emergency=8.0,1070sigma=0.9,1071length=17.9,1072width=2.5,1073height=3.0,1074number_persons=40,1075capacity_persons=140,1076dist_min=0.5,1077speed_max=80.0/3.6,1078deviation_speed=0.05,1079mode='bus', # specifies mode for demand1080impatience=1.0,1081emissionclass='HBEFA3/Bus',1082color=np.array((255, 192, 255, 255), np.float32)/255.0,1083shape_gui='bus/flexible',1084times_boarding=2.0,1085times_loading=0.0,1086sublane_alignment_lat='center',1087sublane_speed_max_lat=0.5,1088sublane_gap_min_lat=0.24,1089sublane_alignment_eager=100.0,1090)10911092self.add_vtype('tram1',1093accel=1.0,1094decel=1.2,1095decel_apparent=1.5,1096decel_emergency=1.5,1097sigma=0.9,1098length=22.0,1099width=2.4,1100height=3.2,1101number_persons=50,1102capacity_persons=120,1103dist_min=0.5,1104speed_max=80.0/3.6,1105deviation_speed=0.05,1106mode='tram', # specifies mode for demand1107impatience=1.0,1108emissionclass='HBEFA3/zero',1109color=np.array((255, 192, 255, 255), np.float32)/255.0,1110shape_gui='rail/railcar',1111times_boarding=1.5,1112times_loading=0.0,1113sublane_alignment_lat='center',1114sublane_speed_max_lat=0.5,1115sublane_gap_min_lat=0.24,1116sublane_alignment_eager=1000000.0,1117)11181119self.add_vtype('rail_urban1',1120accel=1.0,1121decel=1.2,1122decel_apparent=1.5,1123decel_emergency=1.5,1124sigma=0.9,1125length=36.0,1126width=3.0,1127height=3.6,1128number_persons=200,1129capacity_persons=300,1130dist_min=0.5,1131speed_max=100.0/3.6,1132deviation_speed=0.005,1133mode='rail_urban', # specifies mode for demand1134emissionclass='HBEFA3/zero',1135color=np.array((255, 192, 255, 255), np.float32)/255.0,1136shape_gui='rail/railcar',1137times_boarding=1.5,1138times_loading=0.0,1139sublane_alignment_lat='center',1140sublane_speed_max_lat=0.5,1141sublane_gap_min_lat=0.24,1142sublane_alignment_eager=1000000.0,1143)11441145self.add_vtype('van1',1146accel=1.9,1147decel=3.5,1148decel_apparent=5.5,1149decel_emergency=5.0,1150sigma=0.5,1151length=5.0,1152height=2.50,1153width=1.9,1154number_persons=1,1155capacity_persons=2,1156dist_min=1.0,1157speed_max=100.0/3.6,1158deviation_speed=0.1,1159mode='delivery', # specifies mode for demand1160color=np.array((185, 185, 255, 255), np.float32)/255.0,1161shape_gui='passenger/van',1162impatience=1.0,1163emissionclass='HBEFA3/LDV_D_EU3',1164times_boarding=15.0,1165times_loading=90.0,1166sublane_alignment_lat='center',1167sublane_speed_max_lat=1.0,1168sublane_gap_min_lat=0.12,1169)11701171self.add_vtype('truck',1172share_in_mode=1.0/3,1173accel=1.5,1174decel=2.5,1175decel_apparent=5.0,1176decel_emergency=5.0,1177sigma=0.5,1178length=8.0,1179height=3.50,1180width=2.0,1181number_persons=1,1182capacity_persons=2,1183dist_min=1.0,1184speed_max=90.0/3.6,1185deviation_speed=0.05,1186mode='truck', # specifies mode for demand1187color=np.array((185, 185, 255, 255), np.float32)/255.0,1188shape_gui='truck',1189impatience=1.0,1190emissionclass='HBEFA3/HDV_D_EU2',1191times_boarding=10.0,1192times_loading=180.0,1193sublane_alignment_lat='center',1194sublane_speed_max_lat=1.0,1195sublane_gap_min_lat=0.12,1196)11971198self.add_vtype('truck_semitrailer',1199share_in_mode=1.0/3,1200accel=1.0,1201decel=2.0,1202decel_apparent=4.0,1203decel_emergency=4.0,1204sigma=0.5,1205length=10.0,1206height=4.50,1207width=2.0,1208number_persons=1,1209capacity_persons=2,1210dist_min=1.0,1211speed_max=90.0/3.6,1212deviation_speed=0.05,1213mode='truck', # specifies mode for demand1214color=np.array((185, 185, 255, 255), np.float32)/255.0,1215shape_gui='truck/semitrailer',1216impatience=1.0,1217emissionclass='HBEFA3/HDV_D_EU2',1218times_boarding=10.0,1219times_loading=300.0,1220sublane_alignment_lat='center',1221sublane_speed_max_lat=1.0,1222sublane_gap_min_lat=0.12,1223)12241225self.add_vtype('truck_trailer',1226share_in_mode=1.0/3,1227accel=1.0,1228decel=2.0,1229decel_apparent=4.0,1230decel_emergency=4.0,1231sigma=0.5,1232length=12.0,1233height=3.50,1234width=2.0,1235number_persons=1,1236capacity_persons=2,1237dist_min=1.0,1238speed_max=90.0/3.6,1239deviation_speed=0.05,1240mode='truck', # specifies mode for demand1241color=np.array((185, 185, 255, 255), np.float32)/255.0,1242shape_gui='truck/trailer',1243impatience=1.0,1244emissionclass='HBEFA3/HDV_D_EU2',1245times_boarding=10.0,1246times_loading=600.0,1247sublane_alignment_lat='center',1248sublane_speed_max_lat=1.0,1249sublane_gap_min_lat=0.12,1250)12511252self.add_vtype('evehicle1',1253accel=2.5,1254decel=3.5,1255decel_apparent=8.0,1256decel_emergency=8.0,1257sigma=1.0,1258length=3.5,1259width=1.6,1260height=1.7,1261number_persons=1,1262capacity_persons=4,1263dist_min=0.5,1264speed_max=120.0/3.6,1265deviation_speed=0.1,1266eprofile='evehicle',1267mode='evehicle', # specifies mode for demand1268color=np.array((255, 240, 0, 255), np.float32)/255.0,1269shape_gui='evehicle',1270times_boarding=15.0,1271times_loading=20.0,1272sublane_alignment_lat='center',1273sublane_speed_max_lat=0.5,1274sublane_gap_min_lat=0.24,1275sublane_alignment_eager=1000000.0,1276#1277power_max=50000.0,1278mass=800.0,1279area_front_surface=3.5*1.6,1280coefficient_drag_air=0.4,1281moment_inertia_internal=0.01,1282coefficient_drag_radial=0.5,1283coefficient_drag_roll=0.005,1284efficiency_propulsion=0.9,1285#1286capacity_battery=2000.0,1287efficiency_reuperation=0.4,1288speed_charging=0.03,1289)12901291def normalize_shares(self):1292"""1293Normalize the shares of all vehicle type within each mode.1294"""1295for id_mode in self.get_modes():1296ids_vtype = self.select_by_mode(id_mode)1297if len(ids_vtype) > 0:1298shares = self.shares_in_mode[ids_vtype]1299self.shares_in_mode[ids_vtype] = shares/np.sum(shares)13001301def get_vtype_for_mode(self, id_mode=None, mode=None, is_sumoid=False):1302"""1303Returns vehicle type ID of mode id_mode,1304chosen according to predefined probabilities.1305depricated? Used by mapmatching1306"""1307# print 'get_vtypes_for_mode', id_mode, mode1308#1309if id_mode is None:1310id_mode = MODES[mode]13111312ids_veh_mode = self.select_ids(self.ids_mode.get_value() == id_mode)1313if len(ids_veh_mode) == 0:1314return -1 # no vehicle type of this mode13151316share_veh_mode = self.shares_in_mode[ids_veh_mode]13171318# print ' ids_veh_mode',ids_veh_mode1319# print ' share_veh_mode',share_veh_mode1320ind = np.argmax(random.rand(len(share_veh_mode))*share_veh_mode)1321if is_sumoid:1322return self.ids_sumo[ids_veh_mode[ind]]1323else:1324return ids_veh_mode[ind]13251326def select_by_mode(self, id_mode=None, mode=None, is_sumoid=False,1327is_share=False):1328"""1329Returns a list with all vehice ids from a given mode.1330If is_share is True then also a list with the1331respective shares for each type is returned.1332"""13331334if id_mode is None:1335id_mode = MODES[mode]13361337# print 'select_by_mode',id_mode, mode1338# print ' ids',self.get_ids()1339# print ' ids_mode',self.ids_mode[self.get_ids()]1340ids = self.select_ids(self.ids_mode.get_value() == id_mode)1341#print ' ids_type',self.ids_sumo[ids]#1342# print ' ids_mode',self.ids_mode.get_value()1343if is_sumoid:1344idval = self.ids_sumo[ids]1345else:1346idval = ids13471348if is_share:1349return idval, self.shares_in_mode[ids]1350else:1351return idval13521353def generate_vtypes_for_mode(self, n, id_mode=None, mode=None, is_sumoid=False):1354"""1355Returns a list of n vehicle types for a given mode,1356Mode can be given as SUMO name or ID.1357Vehicle types av be returned with SUMO names if is_sumoid = True1358"""13591360if id_mode is None:1361id_mode = MODES[mode]1362# print 'generate_vtypes_for_mode', id_mode, mode13631364# print ' ids_mode',self.ids_mode.get_value()1365# print ' self.ids_mode.get_value()==id_mode',self.ids_mode.get_value()==id_mode1366ids_veh_mode = self.select_ids(self.ids_mode.get_value() == id_mode)13671368if len(ids_veh_mode) == 0:1369return []13701371share_veh_mode = self.shares_in_mode[ids_veh_mode]13721373ids_veh = ids_veh_mode[random_choice(n, share_veh_mode)]13741375if is_sumoid:1376return self.ids_sumo[ids_veh]1377else:1378return ids_veh13791380# see select_by_mode1381# def get_vtypes_by_mode(self, id_mode=None, mode=None, is_sumoid = False):1382# """1383# Returns a list of all vehicle types that are available for a given mode1384# Mode can be given as SUMO name or ID.1385# Vehicle types av be returned with SUMO names if is_sumoid = True1386# """1387# if id_mode is None:1388# id_mode = MODES[mode]1389#1390# ids_veh_mode = self.select_ids(self.ids_mode.get_value()==id_mode)1391#1392# if is_sumoid:1393# return self.ids_sumo[ids_veh_mode]1394# else:1395# return ids_veh_mode13961397def get_modes(self):1398"""1399Returns a list of mode ids for which there are1400currently vehicles in the database.1401"""1402# print 'getClasses',self._types1403return list(set(self.ids_mode.value))14041405def get_modechoices(self):1406"""1407Returns a dictionary of modes for which there are1408currently vehicles in the database.1409Key is mode name and value is mode ID1410"""1411mode_vtypes = self.get_modes()1412mode_choice = OrderedDict()1413for mode, id_mode in MODES.iteritems():1414if id_mode in mode_vtypes:1415mode_choice[mode] = id_mode1416return mode_choice14171418def get_vtypechoices(self):1419"""1420Returns a dictionary of vehicle types for which there are1421currently vehicles in the database.1422Key is vehicle type name and value is vehicle type ID1423"""1424ids = self.get_ids()1425type_choices = OrderedDict()1426for id_type, name_type in zip(self.ids_sumo[ids], ids):1427type_choices[name_type] = id_type14281429return type_choices14301431def _write_xml_body(self, fd, indent, objconfigs, idcolconfig_include_tab, colconfigs,1432objcolconfigs,1433xmltag_item, attrconfig_id, xmltag_id, ids, ids_xml):1434# print 'Vtypes._write_xml_body ident,ids',self.ident,ids1435# print ' xmltag_item %s,xmltag_id %s,attrconfig_id %s'%(xmltag_item,xmltag_id ,attrconfig_id)14361437# !!!these attrs cause error in duaiterate and duaroute in version 1.01438attrsnames_exclude = [] # ['times_boarding','times_loading']14391440# ids_xml not used here!!1441if ids is None:1442ids = self.get_ids()1443for attrconfig in objconfigs:1444attrconfig.get_value().write_xml(fd, indent+2)14451446# check if columns contain objects1447#objcolconfigs = []1448scalarcolconfigs = colconfigs1449# for attrconfig in colconfigs:1450# if attrconfig.metatype == 'obj':1451# objcolconfigs.append(attrconfig)1452# else:1453# scalarcolconfigs.append(attrconfig)14541455for _id in ids:1456fd.write(xm.start(xmltag_item, indent+2))14571458# print ' vtypes:make tag and id',_id1459if xmltag_id == '':1460# no id tag will be written1461pass1462elif (attrconfig_id is None) & (xmltag_id is not None):1463# use specified id tag and and specified id values1464fd.write(xm.num(xmltag_id, id_xml))14651466elif (attrconfig_id is not None):1467# use id tag and values of attrconfig_id1468attrconfig_id.write_xml(fd, _id)14691470if self.ids_mode[_id] == 1:1471# print ' write pedestrian mode'1472attrconfigs_key = []1473for attrconfigname in self.attrconfignames_pedestrian:1474getattr(self, attrconfigname).write_xml(fd, _id)1475else:1476# print ' write all other modes'1477attrconfigs_key = self.get_group('key')1478# print ' write columns',len(scalarcolconfigs)>0,len(idcolconfig_include_tab)>0,len(objcolconfigs)>01479for attrconfig in scalarcolconfigs:1480# print ' scalarcolconfig',attrconfig.attrname1481if attrconfig.attrname not in attrsnames_exclude:1482if attrconfig not in attrconfigs_key:1483attrconfig.write_xml(fd, _id)14841485# insert lanechange model here:1486fd.write(xm.num('laneChangeModel', self.lanechangemodel.get_value()))14871488if self.have_taxi_device[_id]:1489fd.write(""" line="taxi" """)1490# if len(attrconfigs_key)==0:1491# # no keyword parameters1492# fd.write(xm.stopit())1493# else:1494fd.write(xm.stop())1495if self.ids_eprofile[_id] != -1:1496# write electricity profile1497eprofiles = self.eprofiles.get_value()1498id_eprofile = self.ids_eprofile[_id]1499fd.write((indent+4)*' '+"""<param key="has.battery.device" value="true"/>\n""")15001501for attrconf in eprofiles.get_group('key'):1502# print ' eprofile',attrconf.attrname,attrconf.xmltag,'value',attrconf[id_eprofile]1503fd.write((indent+4)*' '+"""<param key="%s" value="%.3f"/>\n""" %1504(attrconf.xmltag, attrconf[id_eprofile]))15051506for attrconf in attrconfigs_key:1507# print ' param',attrconf.attrname,attrconf.xmltag,'value',attrconf[id_eprofile]1508fd.write((indent+4)*' '+"""<param key="%s" value="%.3f"/>\n""" % (attrconf.xmltag, attrconf[_id]))15091510if self.have_taxi_device[_id]:1511fd.write((indent+4)*' '+"""<param key="has.taxi.device" value="true"/>\n""")15121513fd.write(xm.end(xmltag_item, indent+4))15141515# print ' _write_xml_body: done'15161517def export_xml(self, filepath, encoding='UTF-8'):1518print 'export_xml to %s' % (filepath)15191520try:1521fd = open(filepath, 'w')1522except:1523print 'WARNING in vtypes.export_xml: could not open', filepath1524return False15251526fd.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)1527indent = 01528##15291530self.write_xml(fd, indent=indent,1531#ids = ids_vtype_selected,1532is_print_begin_end=True)1533fd.close()15341535# def write_xml(self, fd, indent, xmltag_id = 'id', ids = None,1536# is_print_begin_end = True, attrconfigs_excluded = []):1537#1538# attrconfigs_excluded.append('lanechangemodel')15391540def import_xml(self, filepath):1541print 'import_xml from %s' % (filepath)1542reader = VtypeReader(self)1543parse(filepath, reader)1544self.normalize_shares()154515461547class VtypeReader(handler.ContentHandler):1548"""Parses vtype XML file and read into vtypes database."""15491550def __init__(self, vtypes):1551self._vtypes = vtypes1552self._add_vtype = vtypes.add_vtype_parser1553xmlattrmap = {}1554for attrconfig in vtypes.get_group('parameters'):1555xmltag = attrconfig.xmltag15561557if xmltag not in ['laneChangeModel', 'vClass']:1558xmlattrmap[xmltag] = attrconfig15591560self._xmlattrmap = xmlattrmap1561self._id_vclass_dist = None15621563def startElement(self, name, attrs):1564if name == 'vType':1565params = {}15661567# print 'startElement',attrs['id'],self._id_vclass_dist1568if attrs.has_key('laneChangeModel'):1569lanechangemodel = attrs['laneChangeModel']1570if lanechangemodel in LANECHANGEMODELS:1571self._vtypes.lanechangemodel.set_value(lanechangemodel)15721573if attrs.has_key('vClass'):1574if self._id_vclass_dist is None:1575params['ids_mode'] = self._vtypes.ids_mode.get_value_from_string(attrs['vClass'])1576else:1577params['ids_mode'] = self._id_vclass_dist # set vclass to distribution id15781579# for xmltag, xmlval in self._xmlattrmap.iteritems():1580for xmltag in attrs.keys():1581if self._xmlattrmap.has_key(xmltag):1582attrconfig = self._xmlattrmap[xmltag]1583params[attrconfig.attrname] = attrconfig.get_value_from_xmlattr(attrs)15841585# print ' params',params1586self._add_vtype(attrs['id'], **params)15871588elif name == 'vTypeDistribution':1589# here we simply define the vclass of the following vtypes as distribution id1590# print ' vTypeDistribution',attrs['id']1591# print ' map', get_inversemap(self._vtypes.ids_mode.xmlmap)1592self._id_vclass_dist = self._vtypes.ids_mode.get_value_from_string(attrs['id'])1593# print ' self._id_vclass_dist',self._id_vclass_dist15941595def endElement(self, name):1596if name == 'vTypeDistribution':1597self._id_vclass_dist = None159815991600