Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/coremodules/demand/vehicles.py
169689 views
1
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
2
# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.
3
# SUMOPy module
4
# Copyright (C) 2012-2021 University of Bologna - DICAM
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file vehicles.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
import os
20
import sys
21
import string
22
from collections import OrderedDict
23
from xml.sax import saxutils, parse, handler
24
import numpy as np
25
from numpy import random
26
import agilepy.lib_base.classman as cm
27
import agilepy.lib_base.arrayman as am
28
import agilepy.lib_base.xmlman as xm
29
from agilepy.lib_base.misc import random_choice, get_inversemap
30
31
from coremodules.network.network import SumoIdsConf, MODES
32
33
LANECHANGEMODELS = ['LC2013', 'JE2013', 'DK2008', 'SL2015']
34
35
# http://sumo.dlr.de/wiki/Models/Emissions/HBEFA3-based
36
EMISSIONCLASSES = {
37
'HBEFA3/Bus': 'average urban bus (all fuel types)',
38
'HBEFA3/Coach': 'average long distance bus (all fuel types)',
39
'HBEFA3/HDV': 'average heavy duty vehicle (all fuel types)',
40
'HBEFA3/HDV_G': 'average gasoline driven heavy duty vehicle',
41
'HBEFA3/HDV_D_EU0': 'diesel driven heavy duty vehicle Euro norm 0',
42
'HBEFA3/HDV_D_EU1': 'diesel driven heavy duty vehicle Euro norm 1',
43
'HBEFA3/HDV_D_EU2': 'diesel driven heavy duty vehicle Euro norm 2',
44
'HBEFA3/HDV_D_EU3': 'diesel driven heavy duty vehicle Euro norm 3',
45
'HBEFA3/HDV_D_EU4': 'diesel driven heavy duty vehicle Euro norm 4',
46
'HBEFA3/HDV_D_EU5': 'diesel driven heavy duty vehicle Euro norm 5',
47
'HBEFA3/HDV_D_EU6': 'diesel driven heavy duty vehicle Euro norm 6',
48
'HBEFA3/HDV_D_East': 'Eastern norm heavy duty',
49
'HBEFA3/zero': 'zero emission vehicle',
50
'HBEFA3/LDV': 'average light duty vehicles (all fuel types)',
51
'HBEFA3/LDV_G_EU0': 'gasoline driven light duty vehicle Euro norm 0',
52
'HBEFA3/LDV_G_EU1': 'gasoline driven light duty vehicle Euro norm 1',
53
'HBEFA3/LDV_G_EU2': 'gasoline driven light duty vehicle Euro norm 2',
54
'HBEFA3/LDV_G_EU3': 'gasoline driven light duty vehicle Euro norm 3',
55
'HBEFA3/LDV_G_EU4': 'gasoline driven light duty vehicle Euro norm 4',
56
'HBEFA3/LDV_G_EU5': 'gasoline driven light duty vehicle Euro norm 5',
57
'HBEFA3/LDV_G_EU6': 'gasoline driven light duty vehicle Euro norm 6',
58
'HBEFA3/LDV_G_East': 'Eastern norm light duty gasoline',
59
'HBEFA3/LDV_D_EU0': 'diesel driven light duty vehicle Euro norm 0',
60
'HBEFA3/LDV_D_EU1': 'diesel driven light duty vehicle Euro norm 1',
61
'HBEFA3/LDV_D_EU2': 'diesel driven light duty vehicle Euro norm 2',
62
'HBEFA3/LDV_D_EU3': 'diesel driven light duty vehicle Euro norm 3',
63
'HBEFA3/LDV_D_EU4': 'diesel driven light duty vehicle Euro norm 4',
64
'HBEFA3/LDV_D_EU5': ' diesel driven light duty vehicle Euro norm 5',
65
'HBEFA3/LDV_D_EU6': 'diesel driven light duty vehicle Euro norm 6',
66
'HBEFA3/PC': 'average passenger car (all fuel types)',
67
'HBEFA3/PC_Alternative': 'passenger car with alternative fuel technology',
68
'HBEFA3/PC_G_EU0': 'gasoline driven passenger car Euro norm 0',
69
'HBEFA3/PC_G_EU1': 'gasoline driven passenger car Euro norm 1',
70
'HBEFA3/PC_G_EU2': 'gasoline driven passenger car Euro norm 2',
71
'HBEFA3/PC_G_EU3': 'gasoline driven passenger car Euro norm 3',
72
'HBEFA3/PC_G_EU4': 'gasoline driven passenger car Euro norm 4',
73
'HBEFA3/PC_G_EU5': 'gasoline driven passenger car Euro norm 5',
74
'HBEFA3/PC_G_EU6': 'gasoline driven passenger car Euro norm 6',
75
'HBEFA3/PC_G_East': 'Eastern norm gasoline passenger car',
76
'HBEFA3/PC_D_EU0': 'diesel driven passenger car Euro norm 0',
77
'HBEFA3/PC_D_EU1': 'diesel driven passenger car Euro norm 1',
78
'HBEFA3/PC_D_EU2': 'diesel driven passenger car Euro norm 2',
79
'HBEFA3/PC_D_EU3': 'diesel driven passenger car Euro norm 3',
80
'HBEFA3/PC_D_EU4': 'diesel driven passenger car Euro norm 4',
81
'HBEFA3/PC_D_EU5': 'diesel driven passenger car Euro norm 5',
82
'HBEFA3/PC_D_EU6': 'diesel driven passenger car Euro norm 6 ',
83
}
84
85
GUISHAPES = [
86
"pedestrian",
87
"bicycle",
88
"motorcycle",
89
"passenger",
90
"passenger/sedan",
91
"passenger/hatchback",
92
"passenger/wagon",
93
"passenger/van",
94
"delivery",
95
"truck",
96
"truck/semitrailer",
97
"truck/trailer",
98
"bus",
99
"bus/city",
100
"bus/flexible", # (length per carriage 8.25)
101
"bus/overland", # (length per carriage 8.25)
102
"rail", # (length per carriage 24.5)
103
"rail/light", # (length per carriage 16.85)
104
"rail/city", # (length per carriage 5.71)
105
"rail/slow", # (length per carriage 9.44)
106
"rail/fast", # (length per carriage 24.775)
107
"rail/cargo", # (length per carriage 13.86)
108
"evehicle",
109
"ship",
110
]
111
112
CARFOLLOWMODELS = ['Krauss', 'KraussOrig1', 'PWagner2009', 'BKerner', 'IDM', 'IDMM',
113
'KraussPS', 'KraussAB', 'SmartSK', 'Wiedemann', 'W99', 'Daniel1', 'ACC', 'CACC', 'Rail']
114
115
ALIGNMMENTS_LAT = ['center', 'left', 'right', 'compact', 'nice', 'arbitrary']
116
117
118
class Electricalprofiles(am.ArrayObjman):
119
def __init__(self, ident, parent, **kwargs):
120
print 'Electricalprofiles.__init__'
121
self._init_objman(ident=ident,
122
parent=parent,
123
name='Electrical profiles',
124
info='Profiles of different electrical subsystems, including battery and energy recovery',
125
version=0.0,
126
**kwargs)
127
self._init_attributes()
128
if len(self) == 0:
129
self.add_profiles_default()
130
131
def _init_attributes(self):
132
print 'Electricalprofiles._init_attributes'
133
self.add_col(SumoIdsConf('profilename', name='Electric profile', perm='rw'))
134
self.add_col(am.ArrayConf('capacities_battery', 0.8,
135
groupnames=['parameters', 'key'],
136
name='Maximum battery capacity',
137
unit='Wh',
138
info='Maximum battery capacity',
139
xmltag='maximumBatteryCapacity',
140
))
141
142
self.add_col(am.ArrayConf('efficiencies_reuperation', 0.8,
143
groupnames=['parameters', 'key'],
144
name='Recuperation efficiency',
145
info='Recuperation efficiency.',
146
xmltag='recuperationEfficiency',
147
))
148
149
self.add_col(am.ArrayConf('speeds_charging', 0.1,
150
groupnames=['parameters', 'key'],
151
name='Min. charging speed',
152
unit='km/h',
153
info='Minimum velocity to start charging',
154
xmltag='stoppingTreshold',
155
))
156
157
def add_profiles_default(self):
158
self.add_profile('evehicle',
159
capacity_battery=24000.0,
160
efficiency_reuperation=0.4,
161
speed_charging=0.03)
162
self.add_profile('ebus',
163
capacity_battery=80000.0,
164
efficiency_reuperation=0.4,
165
speed_charging=0.03)
166
self.add_profile('etram',
167
capacity_battery=100000.0,
168
efficiency_reuperation=0.6,
169
speed_charging=0.03)
170
# self.add_profile('prt',
171
# capacity_battery = 24000.0,
172
# efficiency_reuperation = 0.5,
173
# speed_charging = 0.03)
174
175
def add_profile(self, profilename, **kwargs):
176
# print 'add_vtype',vtype,kwargs
177
if self.ids_sumo.has_index(profilename):
178
# vtype already exist
179
_id = self.ids_sumo.get_id_from_index(profilename)
180
else:
181
_id = self.add_row(ids_sumo=profilename)
182
183
self.set_row(_id,
184
capacities_battery=kwargs.get("capacity_battery", None),
185
efficiencies_reuperation=kwargs.get("efficiency_reuperation", None),
186
speeds_charging=kwargs.get("speed_charging", None),
187
)
188
189
190
class VehicleTypes(am.ArrayObjman):
191
def __init__(self, parent, net, is_add_default=True, **kwargs):
192
print 'VehicleTypes.__init__ is_add_default', is_add_default
193
self._init_objman(ident='vtypes',
194
parent=parent,
195
name='Vehicle Types',
196
info='Table of all available vehicle types, each with specific physical characteristics. Each vehicle can be used multiple times in the simulation',
197
xmltag=('vTypes', 'vType', 'ids_sumo'),
198
version=0.4,
199
**kwargs)
200
self._init_attributes()
201
202
if is_add_default:
203
# self.eprofiles.get_value().add_profiles_default()
204
self.add_vtypes_default()
205
self.set_version(0.3)
206
207
def _init_attributes(self):
208
print 'VehicleTypes._init_attributes', len(self), self.get_ident_abs()
209
net = self.parent.get_net()
210
demand = self.parent
211
212
# scalar parameters
213
# lanechange model is now centralized: all vehicle types have the same
214
# lanechange model.
215
if self.get_version() < 0.1:
216
self.delete('lanechangemodels')
217
self.delete('alignments_lat')
218
self.delete('speeds_max_lat')
219
self.delete('gaps_min_lat')
220
221
self.add(cm.AttrConf('lanechangemodel', LANECHANGEMODELS[0],
222
groupnames=['parameters'],
223
choices=LANECHANGEMODELS,
224
name='Lanechange model',
225
info="Lanechange model. The choice of the lanechange model will also determine the choice of lanechange parameters. With model SL2015, sublanes will be simulated.",
226
# xmltag = 'laneChangeModel', # exported manually
227
))
228
229
self.add(cm.AttrConf('pedestrian_model', 'striping',
230
groupnames=['parameters', 'pedestrian'],
231
name='Pedestrian Model',
232
choices=['striping', 'nonInteracting', 'None'],
233
perm='rw',
234
info='Type of Pedestrian model.',
235
#cml = optionprefix+'--pedestrian.model',
236
))
237
238
self.add(cm.AttrConf('width_pedestrian_striping', 0.35,
239
groupnames=['parameters', 'pedestrian'],
240
name='Ped. stripe width',
241
unit='m',
242
perm='rw',
243
info="Width of parallel stripes for segmenting a sidewalk (meters) for use with model 'striping'",
244
#cml = optionprefix+'--pedestrian.striping.stripe-width',
245
))
246
247
self.add(cm.AttrConf('slowdownfactor_pedestrian_striping', 0.2,
248
groupnames=['parameters', 'pedestrian'],
249
name='Ped. slowdown',
250
perm='rw',
251
info="Factor for random slow-downs [0,1] for use with model 'striping'",
252
#cml = optionprefix+'--pedestrian.striping.dawdling',
253
))
254
255
self.add(cm.AttrConf('jamtime_pedestrian_striping', 10,
256
groupnames=['parameters', 'pedestrian'],
257
name='Ped. jamtime',
258
unit='s',
259
perm='rw',
260
info="Time before pedestrian jams are resolved. For use with model 'striping'",
261
#cml = optionprefix+'--pedestrian.striping.jamtime',
262
))
263
264
self.add(cm.AttrConf('jamtime_pedestrian_crossing_striping', 10,
265
groupnames=['parameters', 'pedestrian'],
266
name='Ped. jamtime at crossing',
267
unit='s',
268
perm='rw',
269
info="Time before pedestrian jams are resolved at crossings. For use with model 'striping'",
270
#cml = optionprefix+'--pedestrian.striping.jamtime',
271
))
272
273
self.add(cm.ObjConf(Electricalprofiles('eprofiles', self)))
274
275
# column parameters
276
self.add_col(SumoIdsConf('vtype', name='Type name', perm='rw'))
277
278
self.add_col(am.IdsArrayConf('ids_mode', net.modes,
279
perm='rw',
280
groupnames=['parameters'],
281
#choices = net.modes.names.get_indexmap(),
282
name='Mode',
283
info='ID of transport mode.',
284
xmltag='vClass',
285
xmlmap=get_inversemap(net.modes.names.get_indexmap())
286
))
287
# for temporary upgrade
288
if hasattr(self.ids_mode, 'choices'):
289
del self.ids_mode.choices
290
291
self.ids_mode.set_perm('rw')
292
293
# if self.get_version() < 0.2:
294
# ids_mode = getattr(self,'ids_mode')
295
# ids_mode.xmlmap = get_inversemap(net.modes.names.get_indexmap())
296
# ids_mode.groupnames = ['parameters']
297
298
self.add_col(am.ArrayConf('shares_in_mode', 1.0,
299
groupnames=['parameters', 'planning'],
300
name='Share in mode',
301
info="Share of this vehicle type within the same transport mode",
302
xmltag='probability',
303
))
304
305
self.add_col(am.ArrayConf('lengths', 5.0,
306
groupnames=['parameters', 'geometry'],
307
name='Length',
308
unit='m',
309
info="The vehicle's netto-length",
310
xmltag='length',
311
))
312
313
self.add_col(am.ArrayConf('widths', 2.0,
314
groupnames=['parameters', 'geometry'],
315
name='Width',
316
unit='m',
317
info="The vehicle's width.",
318
xmltag='width',
319
))
320
321
self.add_col(am.ArrayConf('heights', 1.5,
322
groupnames=['parameters', 'geometry'],
323
name='Height',
324
unit='m',
325
info="The vehicle's height.",
326
xmltag='height',
327
))
328
329
self.add_col(am.ArrayConf('numbers_persons_initial', 1,
330
groupnames=['parameters', 'logistics'],
331
name='Passengers',
332
info="Initial number of persons in the vehicle.",
333
xmltag='personNumber',
334
))
335
336
self.add_col(am.ArrayConf('capacities_persons', 1,
337
groupnames=['parameters', 'logistics'],
338
name='Capacity',
339
info="Maximum number of persons that fit in a vehicle.",
340
xmltag='personCapacity',
341
))
342
343
self.add_col(am.ArrayConf('numbers_container', 0,
344
groupnames=['parameters', 'logistics'],
345
name='Containers',
346
info="Initial number of containers on the vehicle.",
347
xmltag='containerNumber',
348
))
349
350
self.add_col(am.ArrayConf('speeds_max', 70.0,
351
groupnames=['parameters', 'mechanics'],
352
name='Max. speed',
353
unit='m/s',
354
info="The vehicle's maximum velocity",
355
xmltag='maxSpeed',
356
))
357
358
self.add_col(am.ArrayConf('factors_speed', 1.0,
359
groupnames=['parameters', 'mechanics'],
360
name='Speed factor',
361
info="The vehicle's expected multiplicator for lane speed limits.",
362
xmltag='speedFactor',
363
))
364
365
self.add_col(am.ArrayConf('deviations_speed', 0.0,
366
groupnames=['parameters', 'mechanics'],
367
name='Speed dev.',
368
info="The deviation of the speed factor.",
369
xmltag='speedDev',
370
))
371
372
self.add_col(am.ArrayConf('accels', 0.8,
373
groupnames=['parameters', 'mechanics'],
374
name='Max. accel.',
375
unit='m/s^2',
376
info='The deceleration ability of vehicles of this type',
377
xmltag='accel',
378
))
379
380
self.add_col(am.ArrayConf('decels', 3.0,
381
groupnames=['parameters', 'mechanics'],
382
name='Decel.',
383
unit='m/s^2',
384
info='The typical brake deceleration of vehicles of this type',
385
xmltag='decel',
386
))
387
388
self.add_col(am.ArrayConf('decels_apparent', 4.5,
389
groupnames=['parameters', 'mechanics'],
390
name='Apparent. decel.',
391
unit='m/s^2',
392
info='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',
393
xmltag='apparentDecel',
394
))
395
396
self.add_col(am.ArrayConf('decels_emergency', 4.5,
397
groupnames=['parameters', 'mechanics'],
398
name='Emergency. decel.',
399
unit='m/s^2',
400
info='The maximal physically possible deceleration for the vehicle',
401
xmltag='emergencyDecel',
402
))
403
404
self.add_col(am.ArrayConf('powers_max', 100000.0,
405
groupnames=['parameters', 'energy', 'key'],
406
name='Max. power',
407
unit='W',
408
info='The maximalum mechanical power that the vehicle can provide.',
409
xmltag='maximumPower',
410
))
411
412
self.add_col(am.ArrayConf('masses', 1000.0,
413
groupnames=['parameters', 'mechanics', 'key'],
414
name='Mass',
415
unit='Kg',
416
info='Total vehicle mass',
417
xmltag='vehicleMass',
418
))
419
420
self.add_col(am.ArrayConf('areas_front_surface', 4.0,
421
groupnames=['parameters', 'key'],
422
name='Front surface area',
423
unit='m^2',
424
info='Front surface area.',
425
xmltag='frontSurfaceArea',
426
))
427
428
self.add_col(am.ArrayConf('coefficients_drag_air', 0.4,
429
groupnames=['parameters', 'mechanics', 'key'],
430
name='Air drag coefficient',
431
info='Air drag coefficient.',
432
xmltag='airDragCoefficient',
433
))
434
435
self.add_col(am.ArrayConf('moments_inertia_internal', 0.01,
436
groupnames=['parameters', 'mechanics', 'key'],
437
name='Internal moment of inertia',
438
unit='Kg m^2',
439
info='Mom. of inertia of int. rot. elements.',
440
xmltag='internalMomentOfInertia',
441
))
442
443
self.add_col(am.ArrayConf('coefficients_drag_radial', 0.5,
444
groupnames=['parameters', 'mechanics', 'key'],
445
name='Radial drag coefficient',
446
info='Radial drag coefficient.',
447
xmltag='radialDragCoefficient',
448
))
449
450
self.add_col(am.ArrayConf('coefficients_drag_roll', 0.01,
451
groupnames=['parameters', 'mechanics', 'key'],
452
name='Rolling resistance coefficient',
453
info='Rolling resistance coefficient.',
454
xmltag='rollDragCoefficient',
455
))
456
457
self.add_col(am.ArrayConf('powers_aux', 100.0,
458
groupnames=['parameters', 'energy', 'key'],
459
name='Constant auxiliary power',
460
unit='W',
461
info='Average constant auxiliary power intake (for electronics, airconditioning, lights, etc).',
462
xmltag='constantPowerIntake',
463
))
464
465
self.add_col(am.ArrayConf('efficiencies propulsion', 0.9,
466
groupnames=['parameters', 'energy', 'key'],
467
name='Propulsion efficiency',
468
info='Drive efficiency, the ratio between mechanical energy and consumed tank energy (fuel or batteries).',
469
xmltag='propulsionEfficiency',
470
))
471
eprofiles = self.eprofiles.get_value()
472
self.add_col(am.IdsArrayConf('ids_eprofile', eprofiles,
473
groupnames=['parameters', 'energy'],
474
choices=eprofiles.ids_sumo.get_indexmap(),
475
name='Electrical profile',
476
info='Defines battery, energy recovery and charging parameters.',
477
))
478
479
self.add_col(am.ArrayConf('taus', 1.0,
480
groupnames=['parameters', 'driver'],
481
name='Reaction',
482
unit='s',
483
info="The driver's reaction time in s (actually the minimum time gap)",
484
xmltag='tau',
485
))
486
487
self.add_col(am.ArrayConf('sigmas', 0.5,
488
groupnames=['parameters', 'driver'],
489
name='Driver',
490
info='The driver imperfection in driving (between 0 and 1). Used only in follower models SUMOKrauss, SKOrig',
491
xmltag='sigma',
492
))
493
494
self.add_col(am.ArrayConf('dists_min', 2.5,
495
groupnames=['parameters', 'driver'],
496
name='Min. gap',
497
unit='m',
498
info="Minimum empty space after leader.",
499
xmltag='minGap',
500
))
501
502
self.add_col(am.ArrayConf('times_boarding', 15.0,
503
groupnames=['parameters', 'driver'],
504
name='boarding time',
505
unit='s',
506
info="The time required by a person to board the vehicle.",
507
xmltag='boardingDuration',
508
))
509
510
self.add_col(am.ArrayConf('times_loading', 180.0,
511
groupnames=['parameters', 'driver'],
512
name='loading time',
513
unit='s',
514
info="The time required to load the vehicle.",
515
xmltag='loadingDuration',
516
))
517
518
self.add_col(am.ArrayConf('have_reroute_device', False,
519
groupnames=['parameters'],
520
name='has reroute device',
521
info="Has a reroute device, which allows rerouting during the simulation. See also rerouting options",
522
xmltag='reroute',
523
))
524
525
self.add_col(am.ArrayConf('have_taxi_device', False,
526
groupnames=['parameters'],
527
name='has taxi device',
528
info="Vehicles with taxi devices can act as taxis and pick up and drop people from the virtual population who are using the taxi strategy.",
529
# xmltag = '',# tag set explicitely
530
))
531
532
emissionclasses_xml = {}
533
for key in EMISSIONCLASSES.keys():
534
emissionclasses_xml[key] = key # yes, map onto itself, otherwise choice values are taken
535
536
self.add_col(am.ArrayConf('emissionclasses', 'HBEFA3/HDV_D_EU4',
537
dtype='object',
538
groupnames=['parameters', 'emissions'],
539
choices=get_inversemap(EMISSIONCLASSES),
540
name='Emission',
541
info="HBEFA3 emission class, see sourceforge.net/apps/mediawiki/sumo/index.php?title=Simulation/Models/Emissions/HBEFA-based",
542
xmltag='emissionClass',
543
xmlmap=emissionclasses_xml,
544
))
545
546
self.add_col(am.ArrayConf('impatiences', -1000.0,
547
groupnames=['parameters', 'driver'],
548
name='Impatience',
549
info="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.",
550
xmltag='impatience',
551
))
552
553
self.add_col(am.ArrayConf('shapes_gui', "passenger",
554
dtype='object',
555
groupnames=['parameters', 'geometry'],
556
name='GUI shape',
557
choices=GUISHAPES,
558
info="How this vehicle is rendered.",
559
xmltag='guiShape',
560
))
561
562
if self.get_version() < 0.3:
563
ids = self.get_ids()
564
changemap = {}
565
for _id, guishape in zip(ids, self.shapes_gui[ids]):
566
if guishape.split('/')[0] == 'transport':
567
guishape = guishape.replace('transport', 'truck')
568
self.shapes_gui.choices = 1*GUISHAPES
569
570
self.add_col(am.ArrayConf('colors', np.array((1.0, 1.0, 1.0, 1.0), np.float32),
571
metatype='color',
572
groupnames=['parameters', 'geometry'],
573
name='Color',
574
info="This vehicle type's color as RGBA tuple with values from 0 to 1.0",
575
xmltag='color',
576
))
577
578
self.add_col(am.ArrayConf('lanechange_strategies', 1.0,
579
groupnames=['parameters', 'lanechange'],
580
name='Lane strategy',
581
info="Lanechange model strategy factor. The eagerness for performing strategic lane changing. Higher values result in earlier lane-changing. default: 1.0, range [0-inf]",
582
xmltag='lcStrategic',
583
))
584
self.add_col(am.ArrayConf('lanechange_coops', 1.0,
585
groupnames=['parameters', 'lanechange'],
586
name='Lane coop',
587
info="Lanechange model cooperative factor.The willingness for performing cooperative lane changing. Lower values result in reduced cooperation. default: 1.0, range [0-1]",
588
xmltag='lcCooperative',
589
))
590
591
self.add_col(am.ArrayConf('lanechange_gains', 1.0,
592
groupnames=['parameters', 'lanechange'],
593
name='Lane gain',
594
info="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]",
595
xmltag='lcSpeedGain',
596
))
597
598
self.add_col(am.ArrayConf('lanechange_rightkeepings', 1.0,
599
groupnames=['parameters', 'lanechange'],
600
name='Lane right',
601
info="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]",
602
xmltag='lcKeepRight',
603
))
604
605
self.add_col(am.ArrayConf('sublane_alignments_lat', ALIGNMMENTS_LAT[0],
606
dtype='object',
607
groupnames=['parameters', 'sublane'],
608
choices=ALIGNMMENTS_LAT,
609
name='sublane alignment',
610
info='Lateral alignment within a lane. For sublane model only.',
611
xmltag='latAlignment',
612
))
613
614
self.add_col(am.ArrayConf('sublane_speeds_max_lat', 1.0,
615
groupnames=['parameters', 'sublane'],
616
name='Sublane max. speed',
617
unit='m/s',
618
info="The vehicle's maximum velocity in lateral direction. For sublane model only.",
619
xmltag='maxSpeedLat',
620
))
621
622
self.add_col(am.ArrayConf('sublane_accel_lat', 2.5,
623
groupnames=['parameters', 'sublane'],
624
name='Sublane accel',
625
unit='m/s^2',
626
info="The vehicle's acceleration in lateral direction. For sublane model only.",
627
xmltag='lcAccelLat',
628
))
629
630
self.add_col(am.ArrayConf('sublane_gaps_min_lat', 0.12,
631
groupnames=['parameters', 'sublane'],
632
name='Sublane min. gap',
633
unit='m',
634
info="The vehicle's minimum distance to other vehicles in lateral direction. For sublane model only.",
635
xmltag='minGapLat',
636
))
637
638
self.add_col(am.ArrayConf('sublane_alignments_eager', 1.0,
639
groupnames=['parameters', 'sublane'],
640
name='Sublane eager',
641
info="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.",
642
xmltag='lcSublane',
643
))
644
645
self.add_col(am.ArrayConf('sublane_assertive', 1.0,
646
groupnames=['parameters', 'sublane'],
647
name='Sublane assertive',
648
info="Willingness to accept lower front and rear gaps on the target lane. default: 0, range 0 to 1. For sublane model only.",
649
xmltag='lcAssertive',
650
))
651
652
self.add_col(am.ArrayConf('sublane_pushyfactors', 0.0,
653
groupnames=['parameters', 'sublane'],
654
name='Sublane pushy',
655
info="Willingness to encroach laterally on other drivers. default: 0.0, range 0 or 1. For sublane model only.",
656
xmltag='lcPushy',
657
))
658
self.add_col(am.ArrayConf('sublane_impatiences', 1.0,
659
groupnames=['parameters', 'sublane'],
660
name='Sublane impatience',
661
info="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.",
662
xmltag='lcImpatience',
663
))
664
665
self.add_col(am.ArrayConf('sublane_time_to_impatiences', 1,
666
groupnames=['parameters', 'sublane'],
667
name='Sublane time to impatience',
668
info="Time to reach maximum impatience (of 1). Impatience grows whenever a lane-change manoeuvre is blocked.. For sublane model only.",
669
unit='s',
670
xmltag='lcTimeToImpatience',
671
))
672
673
self.add_col(am.ArrayConf('carfollowermodels', CARFOLLOWMODELS[0], # Kraus
674
groupnames=['parameters', 'driver'],
675
choices=CARFOLLOWMODELS,
676
name='Carfollower model',
677
info="Carfollower model.",
678
xmltag='carFollowModel',
679
))
680
681
if hasattr(self, 'sublane_impatience'):
682
self.delete('sublane_impatience')
683
self.delete('sublane_time_to_impatience')
684
685
# this provides a link from public transport to vtypes
686
# demand.ptlines.set_vtypes(self)
687
688
self.add(cm.FuncConf('func_make_row', 'on_add_row', None,
689
groupnames=['rowfunctions', '_private'],
690
name='New type',
691
info='Add a new vehicle type or dublicate when called with ID.',
692
is_returnval=False,
693
))
694
695
self.add(cm.FuncConf('func_delete_row', 'on_del_row', None,
696
groupnames=['rowfunctions', '_private'],
697
name='Del type',
698
info='Delete vehicle type.',
699
is_returnval=False,
700
))
701
702
self.attrconfignames_pedestrian = ['lengths', 'widths', 'heights',
703
'speeds_max', 'factors_speed',
704
'deviations_speed', 'accels', 'decels',
705
'taus', 'dists_min', 'ids_mode',
706
'emissionclasses', 'impatiences', 'shapes_gui',
707
'colors']
708
709
self.do_not_save_attrs(['attrconfignames_pedestrian'])
710
711
def format_ids(self, ids):
712
return ','.join(self.ids_sumo[ids])
713
714
def get_id_from_formatted(self, idstr):
715
return self.ids_sumo.get_id_from_index(idstr)
716
717
def get_ids_from_formatted(self, idstrs):
718
return self.ids_sumo.get_ids_from_indices_save(idstrs.split(','))
719
720
def on_del_row(self, id_row=None):
721
if id_row is not None:
722
# print 'on_del_row', id_row
723
self.del_row(id_row)
724
725
def on_add_row(self, id_row=None):
726
# print 'on_add_row',id_row,len(self),(id_row is None)|(len(self)==0)
727
if (id_row is None) | (len(self) == 0):
728
# print ' first'
729
_id = self.add_row()
730
# print ' add id=',_id
731
elif id_row is not None:
732
733
row_last = self.get_row(id_row)
734
id_sumo = row_last['ids_sumo']
735
id_data = id_sumo.split('_')
736
# print ' clone',id_data,len(id_data)
737
i = 1
738
if len(id_data) == 1:
739
row_last['ids_sumo'] = id_sumo+'_%03d' % i
740
else:
741
# print ' create new i',int(id_data[-1])
742
try:
743
i = int(id_data[-1])
744
i += 1
745
id_sumo = id_data[0]
746
for s in id_data[1:-1]:
747
id_sumo += '_'+s
748
# print ' new i:',i,id_sumo+'_%03d'%i
749
row_last['ids_sumo'] = id_sumo+'_%03d' % i
750
except:
751
id_sumo = id_data[0]
752
for s in id_data[1:]:
753
id_sumo += '_'+s
754
755
row_last['ids_sumo'] = id_sumo+'_%03d' % i
756
757
# print ' row_last',row_last
758
_id = self.add_row(**row_last)
759
# print ' _id',_id
760
else:
761
print ' clone last'
762
i = 1
763
row_last = self.get_row(self.get_ids()[-1])
764
row_last['ids_sumo'] += '_%03d' % i # important for all indexed attrs!!
765
# print ' row_last',row_last
766
_id = self.add_row(**row_last)
767
# print ' _id',_id
768
769
def clear_vtypes(self):
770
self.clear()
771
772
def add_vtype_parser(self, vtype, **kwargs):
773
if self.ids_sumo.has_index(vtype):
774
# vtype already exist
775
id_vtype = self.ids_sumo.get_id_from_index(vtype)
776
self.set_row(id_vtype, **kwargs)
777
return id_vtype
778
else:
779
id_vtype = self.add_row(ids_sumo=vtype, **kwargs)
780
return id_vtype
781
782
def add_vtype(self, vtype, **kwargs):
783
print 'add_vtype', vtype, kwargs
784
if self.ids_sumo.has_index(vtype):
785
# vtype already exist
786
_id = self.ids_sumo.get_id_from_index(vtype)
787
else:
788
_id = self.add_row(ids_sumo=vtype)
789
790
if kwargs.has_key('mode'):
791
id_mode = MODES.get(kwargs['mode'], 1)
792
del kwargs['mode']
793
elif kwargs.has_key('id_mode'):
794
id_mode = kwargs['id_mode']
795
del kwargs['id_mode']
796
else:
797
id_mode = 1
798
799
#_id = self.add_row( ids_sumo = vtype, ids_mode = id_mode,**kwargs)
800
801
if kwargs.has_key('eprofile'):
802
eprofiles = self.eprofiles.get_value()
803
eprofile = kwargs['eprofile']
804
eprofiles.add_profile(eprofile, **kwargs)
805
id_eprofile = eprofiles.ids_sumo.get_id_from_index(eprofile)
806
emissionclass = 'Energy/unknown'
807
else:
808
id_eprofile = -1
809
emissionclass = kwargs.get("emissionclass", None),
810
811
self.set_row(_id,
812
shares_in_mode=kwargs.get("share_in_mode", 1.0),
813
accels=kwargs.get("accel", 2.9),
814
decels=kwargs.get("decel", 4.5),
815
decels_apparent=kwargs.get("decel_apparent", 4.5),
816
decels_emergency=kwargs.get("decel_emergency", 4.5),
817
taus=kwargs.get("tau", None),
818
sigmas=kwargs.get("sigma", 0.5),
819
lengths=kwargs.get("length", 4.3),
820
widths=kwargs.get("width", 1.8),
821
heights=kwargs.get("height", 1.50),
822
dists_min=kwargs.get("dist_min", 1.0),
823
speeds_max=kwargs.get("speed_max", 180.0/3.6),
824
factors_speed=kwargs.get("factor_speed", 1.0),
825
deviations_speed=kwargs.get("deviation_speed", 0.0),
826
ids_mode=id_mode, # specifies mode for demand
827
colors=kwargs.get("color", np.array((185, 85, 255, 255), np.float32)/255.0),
828
impatiences=kwargs.get("impatience", -1000),
829
shapes_gui=kwargs.get("shape_gui", 'passenger'),
830
numbers_persons=kwargs.get("number_persons", None),
831
capacities_persons=kwargs.get("capacity_persons", None),
832
emissionclasses=emissionclass,
833
lanechanges=kwargs.get("lanechange", None),
834
lanechange_strategies=kwargs.get("lanechange_strategy", None),
835
lanechange_coops=kwargs.get("lanechange_coop", None),
836
lanechange_gains=kwargs.get("lanechange_gain", None),
837
lanechange_rightkeepings=kwargs.get("lanechange_rightkeeping", None),
838
sublane_alignments_lat=kwargs.get("sublane_alignment_lat", None),
839
sublane_speeds_max_lat=kwargs.get("sublane_speed_max_lat", None),
840
sublane_gaps_min_lat=kwargs.get("sublane_gap_min_lat", None),
841
sublane_alignments_eager=kwargs.get("sublane_alignment_eager", None),
842
sublane_pushyfactors=kwargs.get("sublane_pushyfactor", None),
843
sublane_impatiences=kwargs.get("sublane_impatience", None),
844
sublane_time_to_impatiences=kwargs.get("sublane_time_to_impatience", None),
845
#
846
powers_max=kwargs.get("power_max", None),
847
masses=kwargs.get("mass", None),
848
areas_front_surface=kwargs.get("area_front_surface", kwargs.get(
849
"width", 1.8)*kwargs.get("height", 1.50)),
850
coefficients_drag_air=kwargs.get("coefficient_drag_air", None),
851
moments_inertia_internal=kwargs.get("moment_inertia_internal", None),
852
coefficients_drag_radial=kwargs.get("coefficient_drag_radial", None),
853
coefficients_drag_roll=kwargs.get("coefficient_drag_roll", None),
854
efficiencies_propulsion=kwargs.get("efficiency_propulsion", None),
855
ids_eprofile=id_eprofile,
856
have_taxi_device=kwargs.get("has_taxi_device", False),
857
have_reroute_device=kwargs.get("has_reroute_device", False),
858
carfollowermodel=kwargs.get("carfollowermodel", CARFOLLOWMODELS[0]),
859
)
860
861
return _id
862
863
def add_vtypes_default(self):
864
print 'add_vtypes_default'
865
# self.del_rows(self.get_ids())
866
self.add_vtype('pedestrian',
867
accel=1.5,
868
decel=2.0,
869
decel_apparent=3.0,
870
decel_emergency=3.0,
871
sigma=0.5,
872
length=0.25,
873
width=0.44,
874
height=1.719,
875
number_persons=1,
876
capacity_persons=1,
877
dist_min=0.05,
878
speed_max=5.4/3.6,
879
deviation_speed=0.2,
880
mode='pedestrian', # specifies mode for demand
881
color=np.array((210, 128, 0, 255), np.float32)/255.0,
882
shape_gui='pedestrian',
883
impatience=1.0,
884
emissionclass='HBEFA3/zero',
885
times_boarding=0.0,
886
times_loading=0.0,
887
sublane_alignment_lat='nice',
888
sublane_speed_max_lat=0.5,
889
sublane_gap_min_lat=0.5,
890
sublane_alignment_eager=0.5,
891
sublane_pushyfactor=0.5,
892
carfollowermodel=CARFOLLOWMODELS[0],
893
)
894
895
self.add_vtype('passenger1',
896
accel=2.9,
897
decel=3.0,
898
decel_apparent=8.0,
899
decel_emergency=8.0,
900
sigma=0.5,
901
length=4.3,
902
height=1.50,
903
width=1.8,
904
number_persons=1,
905
capacity_persons=4,
906
dist_min=1.0,
907
speed_max=180.0/3.6,
908
deviation_speed=0.1,
909
mode='passenger', # specifies mode for demand
910
color=np.array((185, 85, 255, 255), np.float32)/255.0,
911
shape_gui='passenger',
912
impatience=1.0,
913
emissionclass='HBEFA3/PC',
914
times_boarding=10.0,
915
times_loading=90.0,
916
sublane_alignment_lat='center',
917
sublane_speed_max_lat=1.0,
918
sublane_gap_min_lat=0.12,
919
carfollowermodels=CARFOLLOWMODELS[0],
920
)
921
922
self.add_vtype('bicycle',
923
accel=1.2,
924
decel=3.0,
925
decel_apparent=8.0,
926
decel_emergency=8.0,
927
sigma=0.7,
928
length=1.6,
929
width=0.9,
930
height=1.7,
931
number_persons=1,
932
capacity_persons=1,
933
dist_min=0.5,
934
speed_max=18.0/3.6,
935
deviation_speed=0.2,
936
mode='bicycle', # specifies mode for demand
937
impatience=1.0,
938
emissionclass='HBEFA3/zero',
939
color=np.array((94, 203, 57, 255), np.float32)/255.0,
940
shape_gui='bicycle',
941
lanechange_strategy=1.0,
942
lanechange_coop=1.0,
943
lanechange_gain=1.0,
944
lanechange_rightkeeping=1.0,
945
times_boarding=15.0,
946
times_loading=0.0,
947
sublane_alignment_lat='right',
948
sublane_speed_max_lat=0.8,
949
sublane_gap_min_lat=0.12,
950
sublane_alignment_eager=1.0,
951
sublane_pushyfactor=0.0,
952
)
953
954
self.add_vtype('vespa',
955
accel=4.5,
956
decel=4.5,
957
decel_apparent=8.0,
958
decel_emergency=8.0,
959
sigma=0.7,
960
length=1.5,
961
height=1.7,
962
width=0.95,
963
number_persons=1,
964
capacity_persons=1,
965
dist_min=0.5,
966
speed_max=60.0/3.6,
967
deviation_speed=0.1,
968
mode='moped', # specifies mode for demand
969
impatience=1.0,
970
emissionclass='HBEFA3/LDV_G_EU3',
971
color=np.array((205, 92, 0, 255), np.float32)/255.0,
972
shape_gui='motorcycle',
973
times_boarding=20.0,
974
times_loading=10.0,
975
sublane_alignment_lat='left',
976
sublane_speed_max_lat=1.0,
977
sublane_gap_min_lat=0.12,
978
sublane_alignment_eager=0.9,
979
sublane_pushyfactor=0.8,
980
)
981
982
self.add_vtype('motorcycle',
983
accel=4.5,
984
decel=4.5,
985
decel_apparent=8.0,
986
decel_emergency=8.0,
987
sigma=0.7,
988
length=1.5,
989
height=1.7,
990
width=0.95,
991
number_persons=1,
992
capacity_persons=1,
993
dist_min=0.5,
994
speed_max=180.0/3.6,
995
deviation_speed=0.1,
996
mode='motorcycle', # specifies mode for demand
997
impatience=1.0,
998
emissionclass='HBEFA3/LDV_G_EU3',
999
color=np.array((205, 92, 0, 255), np.float32)/255.0,
1000
shape_gui='motorcycle',
1001
times_boarding=20.0,
1002
times_loading=10.0,
1003
sublane_alignment_lat='left',
1004
sublane_speed_max_lat=1.0,
1005
sublane_gap_min_lat=0.12,
1006
sublane_alignment_eager=0.9,
1007
sublane_pushyfactor=0.8,
1008
)
1009
1010
self.add_vtype('taxi1',
1011
accel=1.9,
1012
decel=2.5,
1013
decel_apparent=8.0,
1014
decel_emergency=8.0,
1015
sigma=0.5,
1016
length=5.0,
1017
height=1.80,
1018
width=1.8,
1019
number_persons=1,
1020
capacity_persons=4,
1021
dist_min=1.0,
1022
speed_max=180.0/3.6,
1023
deviation_speed=0.05,
1024
mode='taxi', # specifies mode for demand
1025
color=np.array((185, 185, 255, 255), np.float32)/255.0,
1026
shape_gui='passenger/sedan',
1027
impatience=1.0,
1028
emissionclass='HBEFA3/PC',
1029
times_boarding=30.0,
1030
times_loading=90.0,
1031
sublane_alignment_lat='center',
1032
sublane_speed_max_lat=0.8,
1033
sublane_gap_min_lat=0.12,
1034
has_taxi_device=True,
1035
)
1036
1037
self.add_vtype('bus',
1038
share_in_mode=0.5,
1039
accel=1.2,
1040
decel=2.0,
1041
decel_apparent=8.0,
1042
decel_emergency=8.0,
1043
sigma=0.9,
1044
length=12.0,
1045
height=3.4,
1046
width=2.5,
1047
number_persons=20,
1048
capacity_persons=85,
1049
dist_min=0.5,
1050
speed_max=80.0/3.6,
1051
deviation_speed=0.05,
1052
mode='bus', # specifies mode for demand
1053
impatience=1.0,
1054
emissionclass='HBEFA3/Bus',
1055
color=np.array((255, 192, 0, 255), np.float32)/255.0,
1056
shape_gui='bus',
1057
times_boarding=2.0,
1058
times_loading=0.0,
1059
sublane_alignment_lat='center',
1060
sublane_speed_max_lat=0.5,
1061
sublane_gap_min_lat=0.24,
1062
sublane_alignment_eager=10.0,
1063
)
1064
1065
self.add_vtype('bus_flexible',
1066
share_in_mode=0.5,
1067
accel=1.2,
1068
decel=2.0,
1069
decel_apparent=8.0,
1070
decel_emergency=8.0,
1071
sigma=0.9,
1072
length=17.9,
1073
width=2.5,
1074
height=3.0,
1075
number_persons=40,
1076
capacity_persons=140,
1077
dist_min=0.5,
1078
speed_max=80.0/3.6,
1079
deviation_speed=0.05,
1080
mode='bus', # specifies mode for demand
1081
impatience=1.0,
1082
emissionclass='HBEFA3/Bus',
1083
color=np.array((255, 192, 255, 255), np.float32)/255.0,
1084
shape_gui='bus/flexible',
1085
times_boarding=2.0,
1086
times_loading=0.0,
1087
sublane_alignment_lat='center',
1088
sublane_speed_max_lat=0.5,
1089
sublane_gap_min_lat=0.24,
1090
sublane_alignment_eager=100.0,
1091
)
1092
1093
self.add_vtype('tram1',
1094
accel=1.0,
1095
decel=1.2,
1096
decel_apparent=1.5,
1097
decel_emergency=1.5,
1098
sigma=0.9,
1099
length=22.0,
1100
width=2.4,
1101
height=3.2,
1102
number_persons=50,
1103
capacity_persons=120,
1104
dist_min=0.5,
1105
speed_max=80.0/3.6,
1106
deviation_speed=0.05,
1107
mode='tram', # specifies mode for demand
1108
impatience=1.0,
1109
emissionclass='HBEFA3/zero',
1110
color=np.array((255, 192, 255, 255), np.float32)/255.0,
1111
shape_gui='rail/railcar',
1112
times_boarding=1.5,
1113
times_loading=0.0,
1114
sublane_alignment_lat='center',
1115
sublane_speed_max_lat=0.5,
1116
sublane_gap_min_lat=0.24,
1117
sublane_alignment_eager=1000000.0,
1118
)
1119
1120
self.add_vtype('rail_urban1',
1121
accel=1.0,
1122
decel=1.2,
1123
decel_apparent=1.5,
1124
decel_emergency=1.5,
1125
sigma=0.9,
1126
length=36.0,
1127
width=3.0,
1128
height=3.6,
1129
number_persons=200,
1130
capacity_persons=300,
1131
dist_min=0.5,
1132
speed_max=100.0/3.6,
1133
deviation_speed=0.005,
1134
mode='rail_urban', # specifies mode for demand
1135
emissionclass='HBEFA3/zero',
1136
color=np.array((255, 192, 255, 255), np.float32)/255.0,
1137
shape_gui='rail/railcar',
1138
times_boarding=1.5,
1139
times_loading=0.0,
1140
sublane_alignment_lat='center',
1141
sublane_speed_max_lat=0.5,
1142
sublane_gap_min_lat=0.24,
1143
sublane_alignment_eager=1000000.0,
1144
)
1145
1146
self.add_vtype('van1',
1147
accel=1.9,
1148
decel=3.5,
1149
decel_apparent=5.5,
1150
decel_emergency=5.0,
1151
sigma=0.5,
1152
length=5.0,
1153
height=2.50,
1154
width=1.9,
1155
number_persons=1,
1156
capacity_persons=2,
1157
dist_min=1.0,
1158
speed_max=100.0/3.6,
1159
deviation_speed=0.1,
1160
mode='delivery', # specifies mode for demand
1161
color=np.array((185, 185, 255, 255), np.float32)/255.0,
1162
shape_gui='passenger/van',
1163
impatience=1.0,
1164
emissionclass='HBEFA3/LDV_D_EU3',
1165
times_boarding=15.0,
1166
times_loading=90.0,
1167
sublane_alignment_lat='center',
1168
sublane_speed_max_lat=1.0,
1169
sublane_gap_min_lat=0.12,
1170
)
1171
1172
self.add_vtype('truck',
1173
share_in_mode=1.0/3,
1174
accel=1.5,
1175
decel=2.5,
1176
decel_apparent=5.0,
1177
decel_emergency=5.0,
1178
sigma=0.5,
1179
length=8.0,
1180
height=3.50,
1181
width=2.0,
1182
number_persons=1,
1183
capacity_persons=2,
1184
dist_min=1.0,
1185
speed_max=90.0/3.6,
1186
deviation_speed=0.05,
1187
mode='truck', # specifies mode for demand
1188
color=np.array((185, 185, 255, 255), np.float32)/255.0,
1189
shape_gui='truck',
1190
impatience=1.0,
1191
emissionclass='HBEFA3/HDV_D_EU2',
1192
times_boarding=10.0,
1193
times_loading=180.0,
1194
sublane_alignment_lat='center',
1195
sublane_speed_max_lat=1.0,
1196
sublane_gap_min_lat=0.12,
1197
)
1198
1199
self.add_vtype('truck_semitrailer',
1200
share_in_mode=1.0/3,
1201
accel=1.0,
1202
decel=2.0,
1203
decel_apparent=4.0,
1204
decel_emergency=4.0,
1205
sigma=0.5,
1206
length=10.0,
1207
height=4.50,
1208
width=2.0,
1209
number_persons=1,
1210
capacity_persons=2,
1211
dist_min=1.0,
1212
speed_max=90.0/3.6,
1213
deviation_speed=0.05,
1214
mode='truck', # specifies mode for demand
1215
color=np.array((185, 185, 255, 255), np.float32)/255.0,
1216
shape_gui='truck/semitrailer',
1217
impatience=1.0,
1218
emissionclass='HBEFA3/HDV_D_EU2',
1219
times_boarding=10.0,
1220
times_loading=300.0,
1221
sublane_alignment_lat='center',
1222
sublane_speed_max_lat=1.0,
1223
sublane_gap_min_lat=0.12,
1224
)
1225
1226
self.add_vtype('truck_trailer',
1227
share_in_mode=1.0/3,
1228
accel=1.0,
1229
decel=2.0,
1230
decel_apparent=4.0,
1231
decel_emergency=4.0,
1232
sigma=0.5,
1233
length=12.0,
1234
height=3.50,
1235
width=2.0,
1236
number_persons=1,
1237
capacity_persons=2,
1238
dist_min=1.0,
1239
speed_max=90.0/3.6,
1240
deviation_speed=0.05,
1241
mode='truck', # specifies mode for demand
1242
color=np.array((185, 185, 255, 255), np.float32)/255.0,
1243
shape_gui='truck/trailer',
1244
impatience=1.0,
1245
emissionclass='HBEFA3/HDV_D_EU2',
1246
times_boarding=10.0,
1247
times_loading=600.0,
1248
sublane_alignment_lat='center',
1249
sublane_speed_max_lat=1.0,
1250
sublane_gap_min_lat=0.12,
1251
)
1252
1253
self.add_vtype('evehicle1',
1254
accel=2.5,
1255
decel=3.5,
1256
decel_apparent=8.0,
1257
decel_emergency=8.0,
1258
sigma=1.0,
1259
length=3.5,
1260
width=1.6,
1261
height=1.7,
1262
number_persons=1,
1263
capacity_persons=4,
1264
dist_min=0.5,
1265
speed_max=120.0/3.6,
1266
deviation_speed=0.1,
1267
eprofile='evehicle',
1268
mode='evehicle', # specifies mode for demand
1269
color=np.array((255, 240, 0, 255), np.float32)/255.0,
1270
shape_gui='evehicle',
1271
times_boarding=15.0,
1272
times_loading=20.0,
1273
sublane_alignment_lat='center',
1274
sublane_speed_max_lat=0.5,
1275
sublane_gap_min_lat=0.24,
1276
sublane_alignment_eager=1000000.0,
1277
#
1278
power_max=50000.0,
1279
mass=800.0,
1280
area_front_surface=3.5*1.6,
1281
coefficient_drag_air=0.4,
1282
moment_inertia_internal=0.01,
1283
coefficient_drag_radial=0.5,
1284
coefficient_drag_roll=0.005,
1285
efficiency_propulsion=0.9,
1286
#
1287
capacity_battery=2000.0,
1288
efficiency_reuperation=0.4,
1289
speed_charging=0.03,
1290
)
1291
1292
def normalize_shares(self):
1293
"""
1294
Normalize the shares of all vehicle type within each mode.
1295
"""
1296
for id_mode in self.get_modes():
1297
ids_vtype = self.select_by_mode(id_mode)
1298
if len(ids_vtype) > 0:
1299
shares = self.shares_in_mode[ids_vtype]
1300
self.shares_in_mode[ids_vtype] = shares/np.sum(shares)
1301
1302
def get_vtype_for_mode(self, id_mode=None, mode=None, is_sumoid=False):
1303
"""
1304
Returns vehicle type ID of mode id_mode,
1305
chosen according to predefined probabilities.
1306
depricated? Used by mapmatching
1307
"""
1308
# print 'get_vtypes_for_mode', id_mode, mode
1309
#
1310
if id_mode is None:
1311
id_mode = MODES[mode]
1312
1313
ids_veh_mode = self.select_ids(self.ids_mode.get_value() == id_mode)
1314
if len(ids_veh_mode) == 0:
1315
return -1 # no vehicle type of this mode
1316
1317
share_veh_mode = self.shares_in_mode[ids_veh_mode]
1318
1319
# print ' ids_veh_mode',ids_veh_mode
1320
# print ' share_veh_mode',share_veh_mode
1321
ind = np.argmax(random.rand(len(share_veh_mode))*share_veh_mode)
1322
if is_sumoid:
1323
return self.ids_sumo[ids_veh_mode[ind]]
1324
else:
1325
return ids_veh_mode[ind]
1326
1327
def select_by_mode(self, id_mode=None, mode=None, is_sumoid=False,
1328
is_share=False):
1329
"""
1330
Returns a list with all vehice ids from a given mode.
1331
If is_share is True then also a list with the
1332
respective shares for each type is returned.
1333
"""
1334
1335
if id_mode is None:
1336
id_mode = MODES[mode]
1337
1338
# print 'select_by_mode',id_mode, mode
1339
# print ' ids',self.get_ids()
1340
# print ' ids_mode',self.ids_mode[self.get_ids()]
1341
ids = self.select_ids(self.ids_mode.get_value() == id_mode)
1342
#print ' ids_type',self.ids_sumo[ids]#
1343
# print ' ids_mode',self.ids_mode.get_value()
1344
if is_sumoid:
1345
idval = self.ids_sumo[ids]
1346
else:
1347
idval = ids
1348
1349
if is_share:
1350
return idval, self.shares_in_mode[ids]
1351
else:
1352
return idval
1353
1354
def generate_vtypes_for_mode(self, n, id_mode=None, mode=None, is_sumoid=False):
1355
"""
1356
Returns a list of n vehicle types for a given mode,
1357
Mode can be given as SUMO name or ID.
1358
Vehicle types av be returned with SUMO names if is_sumoid = True
1359
"""
1360
1361
if id_mode is None:
1362
id_mode = MODES[mode]
1363
# print 'generate_vtypes_for_mode', id_mode, mode
1364
1365
# print ' ids_mode',self.ids_mode.get_value()
1366
# print ' self.ids_mode.get_value()==id_mode',self.ids_mode.get_value()==id_mode
1367
ids_veh_mode = self.select_ids(self.ids_mode.get_value() == id_mode)
1368
1369
if len(ids_veh_mode) == 0:
1370
return []
1371
1372
share_veh_mode = self.shares_in_mode[ids_veh_mode]
1373
1374
ids_veh = ids_veh_mode[random_choice(n, share_veh_mode)]
1375
1376
if is_sumoid:
1377
return self.ids_sumo[ids_veh]
1378
else:
1379
return ids_veh
1380
1381
# see select_by_mode
1382
# def get_vtypes_by_mode(self, id_mode=None, mode=None, is_sumoid = False):
1383
# """
1384
# Returns a list of all vehicle types that are available for a given mode
1385
# Mode can be given as SUMO name or ID.
1386
# Vehicle types av be returned with SUMO names if is_sumoid = True
1387
# """
1388
# if id_mode is None:
1389
# id_mode = MODES[mode]
1390
#
1391
# ids_veh_mode = self.select_ids(self.ids_mode.get_value()==id_mode)
1392
#
1393
# if is_sumoid:
1394
# return self.ids_sumo[ids_veh_mode]
1395
# else:
1396
# return ids_veh_mode
1397
1398
def get_modes(self):
1399
"""
1400
Returns a list of mode ids for which there are
1401
currently vehicles in the database.
1402
"""
1403
# print 'getClasses',self._types
1404
return list(set(self.ids_mode.value))
1405
1406
def get_modechoices(self):
1407
"""
1408
Returns a dictionary of modes for which there are
1409
currently vehicles in the database.
1410
Key is mode name and value is mode ID
1411
"""
1412
mode_vtypes = self.get_modes()
1413
mode_choice = OrderedDict()
1414
for mode, id_mode in MODES.iteritems():
1415
if id_mode in mode_vtypes:
1416
mode_choice[mode] = id_mode
1417
return mode_choice
1418
1419
def get_vtypechoices(self):
1420
"""
1421
Returns a dictionary of vehicle types for which there are
1422
currently vehicles in the database.
1423
Key is vehicle type name and value is vehicle type ID
1424
"""
1425
ids = self.get_ids()
1426
type_choices = OrderedDict()
1427
for id_type, name_type in zip(self.ids_sumo[ids], ids):
1428
type_choices[name_type] = id_type
1429
1430
return type_choices
1431
1432
def _write_xml_body(self, fd, indent, objconfigs, idcolconfig_include_tab, colconfigs,
1433
objcolconfigs,
1434
xmltag_item, attrconfig_id, xmltag_id, ids, ids_xml):
1435
# print 'Vtypes._write_xml_body ident,ids',self.ident,ids
1436
# print ' xmltag_item %s,xmltag_id %s,attrconfig_id %s'%(xmltag_item,xmltag_id ,attrconfig_id)
1437
1438
# !!!these attrs cause error in duaiterate and duaroute in version 1.0
1439
attrsnames_exclude = [] # ['times_boarding','times_loading']
1440
1441
# ids_xml not used here!!
1442
if ids is None:
1443
ids = self.get_ids()
1444
for attrconfig in objconfigs:
1445
attrconfig.get_value().write_xml(fd, indent+2)
1446
1447
# check if columns contain objects
1448
#objcolconfigs = []
1449
scalarcolconfigs = colconfigs
1450
# for attrconfig in colconfigs:
1451
# if attrconfig.metatype == 'obj':
1452
# objcolconfigs.append(attrconfig)
1453
# else:
1454
# scalarcolconfigs.append(attrconfig)
1455
1456
for _id in ids:
1457
fd.write(xm.start(xmltag_item, indent+2))
1458
1459
# print ' vtypes:make tag and id',_id
1460
if xmltag_id == '':
1461
# no id tag will be written
1462
pass
1463
elif (attrconfig_id is None) & (xmltag_id is not None):
1464
# use specified id tag and and specified id values
1465
fd.write(xm.num(xmltag_id, id_xml))
1466
1467
elif (attrconfig_id is not None):
1468
# use id tag and values of attrconfig_id
1469
attrconfig_id.write_xml(fd, _id)
1470
1471
if self.ids_mode[_id] == 1:
1472
# print ' write pedestrian mode'
1473
attrconfigs_key = []
1474
for attrconfigname in self.attrconfignames_pedestrian:
1475
getattr(self, attrconfigname).write_xml(fd, _id)
1476
else:
1477
# print ' write all other modes'
1478
attrconfigs_key = self.get_group('key')
1479
# print ' write columns',len(scalarcolconfigs)>0,len(idcolconfig_include_tab)>0,len(objcolconfigs)>0
1480
for attrconfig in scalarcolconfigs:
1481
# print ' scalarcolconfig',attrconfig.attrname
1482
if attrconfig.attrname not in attrsnames_exclude:
1483
if attrconfig not in attrconfigs_key:
1484
attrconfig.write_xml(fd, _id)
1485
1486
# insert lanechange model here:
1487
fd.write(xm.num('laneChangeModel', self.lanechangemodel.get_value()))
1488
1489
if self.have_taxi_device[_id]:
1490
fd.write(""" line="taxi" """)
1491
# if len(attrconfigs_key)==0:
1492
# # no keyword parameters
1493
# fd.write(xm.stopit())
1494
# else:
1495
fd.write(xm.stop())
1496
if self.ids_eprofile[_id] != -1:
1497
# write electricity profile
1498
eprofiles = self.eprofiles.get_value()
1499
id_eprofile = self.ids_eprofile[_id]
1500
fd.write((indent+4)*' '+"""<param key="has.battery.device" value="true"/>\n""")
1501
1502
for attrconf in eprofiles.get_group('key'):
1503
# print ' eprofile',attrconf.attrname,attrconf.xmltag,'value',attrconf[id_eprofile]
1504
fd.write((indent+4)*' '+"""<param key="%s" value="%.3f"/>\n""" %
1505
(attrconf.xmltag, attrconf[id_eprofile]))
1506
1507
for attrconf in attrconfigs_key:
1508
# print ' param',attrconf.attrname,attrconf.xmltag,'value',attrconf[id_eprofile]
1509
fd.write((indent+4)*' '+"""<param key="%s" value="%.3f"/>\n""" % (attrconf.xmltag, attrconf[_id]))
1510
1511
if self.have_taxi_device[_id]:
1512
fd.write((indent+4)*' '+"""<param key="has.taxi.device" value="true"/>\n""")
1513
1514
fd.write(xm.end(xmltag_item, indent+4))
1515
1516
# print ' _write_xml_body: done'
1517
1518
def export_xml(self, filepath, encoding='UTF-8'):
1519
print 'export_xml to %s' % (filepath)
1520
1521
try:
1522
fd = open(filepath, 'w')
1523
except:
1524
print 'WARNING in vtypes.export_xml: could not open', filepath
1525
return False
1526
1527
fd.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)
1528
indent = 0
1529
##
1530
1531
self.write_xml(fd, indent=indent,
1532
#ids = ids_vtype_selected,
1533
is_print_begin_end=True)
1534
fd.close()
1535
1536
# def write_xml(self, fd, indent, xmltag_id = 'id', ids = None,
1537
# is_print_begin_end = True, attrconfigs_excluded = []):
1538
#
1539
# attrconfigs_excluded.append('lanechangemodel')
1540
1541
def import_xml(self, filepath):
1542
print 'import_xml from %s' % (filepath)
1543
reader = VtypeReader(self)
1544
parse(filepath, reader)
1545
self.normalize_shares()
1546
1547
1548
class VtypeReader(handler.ContentHandler):
1549
"""Parses vtype XML file and read into vtypes database."""
1550
1551
def __init__(self, vtypes):
1552
self._vtypes = vtypes
1553
self._add_vtype = vtypes.add_vtype_parser
1554
xmlattrmap = {}
1555
for attrconfig in vtypes.get_group('parameters'):
1556
xmltag = attrconfig.xmltag
1557
1558
if xmltag not in ['laneChangeModel', 'vClass']:
1559
xmlattrmap[xmltag] = attrconfig
1560
1561
self._xmlattrmap = xmlattrmap
1562
self._id_vclass_dist = None
1563
1564
def startElement(self, name, attrs):
1565
if name == 'vType':
1566
params = {}
1567
1568
# print 'startElement',attrs['id'],self._id_vclass_dist
1569
if attrs.has_key('laneChangeModel'):
1570
lanechangemodel = attrs['laneChangeModel']
1571
if lanechangemodel in LANECHANGEMODELS:
1572
self._vtypes.lanechangemodel.set_value(lanechangemodel)
1573
1574
if attrs.has_key('vClass'):
1575
if self._id_vclass_dist is None:
1576
params['ids_mode'] = self._vtypes.ids_mode.get_value_from_string(attrs['vClass'])
1577
else:
1578
params['ids_mode'] = self._id_vclass_dist # set vclass to distribution id
1579
1580
# for xmltag, xmlval in self._xmlattrmap.iteritems():
1581
for xmltag in attrs.keys():
1582
if self._xmlattrmap.has_key(xmltag):
1583
attrconfig = self._xmlattrmap[xmltag]
1584
params[attrconfig.attrname] = attrconfig.get_value_from_xmlattr(attrs)
1585
1586
# print ' params',params
1587
self._add_vtype(attrs['id'], **params)
1588
1589
elif name == 'vTypeDistribution':
1590
# here we simply define the vclass of the following vtypes as distribution id
1591
# print ' vTypeDistribution',attrs['id']
1592
# print ' map', get_inversemap(self._vtypes.ids_mode.xmlmap)
1593
self._id_vclass_dist = self._vtypes.ids_mode.get_value_from_string(attrs['id'])
1594
# print ' self._id_vclass_dist',self._id_vclass_dist
1595
1596
def endElement(self, name):
1597
if name == 'vTypeDistribution':
1598
self._id_vclass_dist = None
1599
1600