Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/coremodules/demand/virtualpop.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 virtualpop.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
import os
20
import sys
21
import numpy as np
22
from numpy import random
23
import agilepy.lib_base.classman as cm
24
import agilepy.lib_base.arrayman as am
25
import agilepy.lib_base.xmlman as xm
26
from agilepy.lib_base.misc import random_choice, get_inversemap
27
from agilepy.lib_base.processes import Process
28
29
#from coremodules.modules_common import *
30
from coremodules.network.network import SumoIdsConf, MODES
31
from coremodules.network import routing
32
from coremodules.simulation import results as res
33
from demandbase import *
34
import virtualpop_results as res
35
36
37
GENDERS = {'male': 0, 'female': 1, 'unknown': -1}
38
39
OCCUPATIONS = {'unknown': -1,
40
'worker': 1,
41
'student': 2,
42
'employee': 3,
43
'public employee': 4,
44
'selfemployed': 5,
45
'pensioneer': 6,
46
'other': 7
47
}
48
49
50
class Activities(am.ArrayObjman):
51
# https://sumo.dlr.de/docs/Networks/PlainXML.html#edge_descriptions
52
def __init__(self, ident, virtualpop, **kwargs):
53
54
self._init_objman(ident=ident, parent=virtualpop, name='Activities',
55
info='Activity database of persons contains type, time, duration and location of activities.',
56
version=0.0,
57
**kwargs)
58
59
self._init_attributes()
60
61
def _init_attributes(self):
62
63
# activity types now in demand
64
activitytypes = self.parent.get_demand().activitytypes
65
self.add_col(am.IdsArrayConf('ids_activitytype', activitytypes,
66
groupnames=['parameters'],
67
choices=activitytypes.names.get_indexmap(),
68
name='Type',
69
info='Type of activity performed during the stop.',
70
#xmltag = 'actType',
71
#xmlmap = get_inversemap( activitytypes.names.get_indexmap()),
72
))
73
74
# attention, this may cause trouble during init if
75
# facilities are not yet initialized
76
self.add_col(am.IdsArrayConf('ids_facility', self.parent.get_scenario().landuse.facilities,
77
groupnames=['parameters'],
78
name='ID fac.',
79
info='Facility ID where activity takes place.',
80
#activitytype = 'home',
81
))
82
83
# self.add_col(am.ArrayConf( 'descriptions', '',
84
# dtype = np.object,
85
# perm='rw',
86
# is_index = True,
87
# name = 'Description',
88
# info = 'Description of activity.',
89
# ))
90
91
# self.add_col(am.IdlistsArrayConf( 'ids_landusetypes', self.parent.get_landuse().landusetypes,
92
# name = 'Landuse types',
93
# info = "Landuse type IDs, eher this activity type can take place.",
94
# ))
95
96
self.add_col(am.ArrayConf('hours_begin_earliest', 0.0,
97
dtype=np.float32,
98
groupnames=['parameters'],
99
perm='rw',
100
name='Earliest hour begin',
101
unit='h',
102
info='Earliest hour when this activity can begin.',
103
))
104
105
self.add_col(am.ArrayConf('hours_begin_latest', 1.0,
106
dtype=np.float32,
107
groupnames=['parameters'],
108
perm='rw',
109
name='Latest begin hour',
110
unit='h',
111
info='Latest hour when this activity can begin.',
112
))
113
114
self.add_col(am.ArrayConf('durations_min', 6.0,
115
dtype=np.float32,
116
groupnames=['parameters'],
117
perm='rw',
118
name='Min. Duration',
119
unit='h',
120
info='Minimum activity duration for a person within a day.',
121
))
122
123
self.add_col(am.ArrayConf('durations_max', 8.0,
124
dtype=np.float32,
125
groupnames=['parameters'],
126
perm='rw',
127
name='Max. Duration',
128
unit='h',
129
info='Maximum activity duration for a person within a day.',
130
))
131
132
def get_hours_end_earliest(self, ids):
133
return self.hours_begin_earliest[ids]+self.durations_min[ids]
134
135
def get_hours_end_latest(self, ids):
136
return self.hours_begin_latest[ids]+self.durations_max[ids]
137
138
def get_durations(self, ids, pdf='unit'):
139
durations = np.zeros(len(ids), dtype=np.float32)
140
i = 0
141
for time_start, time_end in zip(
142
np.array(self.durations_min[ids]*3600, dtype=np.int32),
143
np.array(self.durations_max[ids]*3600, dtype=np.int32)):
144
145
durations[i] = np.random.randint(time_start, time_end, 1)
146
i += 1
147
return durations
148
149
def get_times_end(self, ids, pdf='unit'):
150
"""
151
Returns an array with activity ending time for the
152
given activity IDs.
153
The ending time is calculated by drawing random samples
154
from the departure interval.
155
The random samples are drawn according to the given probability
156
density function, pdf.
157
158
Input arguments:
159
ids: integer array with activity IDs
160
pdf: probability density function 'unit'|'normal'
161
162
Returned arguments:
163
times_end: integer array with departure times
164
"""
165
times_end = np.zeros(len(ids), dtype=np.float32)
166
i = 0
167
for time_start, time_end in zip(
168
np.array(self.get_hours_end_earliest(ids)*3600, dtype=np.int32),
169
np.array(self.get_hours_end_latest(ids)*3600, dtype=np.int32)):
170
171
times_end[i] = np.random.randint(time_start, time_end, 1)
172
i += 1
173
174
return times_end
175
176
def get_times_begin(self, ids, pdf='unit'):
177
"""
178
Returns an array with beginning time for the
179
given activity IDs.
180
The begin time is calculated by drawing random samples
181
from the departure interval.
182
The random samples are drawn according to the given probability
183
density function, pdf.
184
185
Input arguments:
186
ids: integer array with activity IDs
187
pdf: probability density function 'unit'|'normal'
188
189
Returned arguments:
190
times_begin: integer array with departure times
191
"""
192
times_begin = np.zeros(len(ids), dtype=np.float32)
193
i = 0
194
for time_start, time_end in zip(
195
np.array(self.get_hours_begin_earliest(ids)*3600, dtype=np.int32),
196
np.array(self.get_hours_begin_latest(ids)*3600, dtype=np.int32)):
197
198
times_begin[i] = np.random.randint(time_start, time_end, 1)
199
i += 1
200
201
return times_begin
202
203
def add_activities(self, ids_activitytype, ids_facility,
204
hours_begin_earliest=None,
205
hours_begin_latest=None,
206
durations_min=None,
207
durations_max=None):
208
209
n_pers = len(ids_activitytype)
210
activitytypes = self.ids_activitytype.get_linktab()
211
212
if hours_begin_earliest is None:
213
# np.ones(n_pers, dtype = np.float32)*
214
hours_begin_earliest = activitytypes.hours_begin_earliest[ids_activitytype]
215
216
if hours_begin_latest is None:
217
hours_begin_latest = activitytypes.hours_begin_latest[ids_activitytype]
218
219
if durations_min is None:
220
durations_min = activitytypes.durations_min[ids_activitytype]
221
222
if durations_max is None:
223
durations_max = activitytypes.durations_max[ids_activitytype]
224
225
ids = self.add_rows(n=n_pers,
226
ids_activitytype=ids_activitytype,
227
ids_facility=ids_facility,
228
hours_begin_earliest=hours_begin_earliest,
229
hours_begin_latest=hours_begin_latest,
230
durations_min=durations_min,
231
durations_max=durations_max,
232
)
233
234
return ids
235
236
237
class IndividualAutos(am.ArrayObjman):
238
239
def __init__(self, ident, population, **kwargs):
240
# print 'individualvehicle vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1')
241
self._init_objman(ident=ident,
242
parent=population,
243
name='Indiv. Autos',
244
info='Individual auto database. These are privately owned autos.',
245
**kwargs)
246
247
self._init_attributes()
248
self._init_constants()
249
250
def _init_constants(self):
251
252
self.do_not_save_attrs(['mode', 'mode_prefix',
253
'_edges', '_lanes', '_individualvehicle', '_ids_vtype_sumo', '_ids_edge_sumo',
254
'_id_mode', '_get_laneid_allowed', '_get_sumoinfo_from_id_lane',
255
'_space_access', '_parking', '_time_after_unboarding',
256
])
257
258
def def_mode(self):
259
self.mode = 'passenger'
260
self.mode_prefix = 'iauto'
261
262
def _init_attributes(self):
263
vtypes = self.parent.get_demand().vtypes
264
self.def_mode()
265
266
ids_vtype = vtypes.select_by_mode(mode=self.mode)
267
268
self.add(cm.AttrConf('space_access', 0.5,
269
groupnames=['options'],
270
perm='rw',
271
name='Space access',
272
unit='m',
273
info='Space to access vehicles at parkings. This is typically less than the vehicle length.',
274
))
275
276
self.add(cm.AttrConf('time_after_unboarding', 5,
277
groupnames=['options'],
278
perm='rw',
279
name='time after unboarding',
280
unit='s',
281
info='Time the vehicle waits before disappearing after unboarding.',
282
))
283
284
self.add_col(am.IdsArrayConf('ids_vtype', vtypes,
285
id_default=ids_vtype[0],
286
groupnames=['state'],
287
name='Veh. type',
288
info='Vehicle type.',
289
#xmltag = 'type',
290
))
291
292
self.add_col(am.IdsArrayConf('ids_person', self.parent,
293
groupnames=['state'],
294
name='ID person',
295
info='ID of person who ownes the vehicle.',
296
))
297
298
self.add_col(am.ArrayConf('times_exec', 0.0,
299
name='Exec time',
300
info='Total route execution time from simulation run of last plan.',
301
unit='s',
302
))
303
304
def get_virtualpop(self):
305
return self.parent
306
307
def get_ids_veh_pop(self):
308
"""
309
To be overridden by other individual vehicle types.
310
"""
311
return self.get_virtualpop().ids_iauto
312
313
def get_share(self, is_abs=False):
314
n_veh = len(self)
315
if is_abs:
316
return n_veh
317
else:
318
return float(n_veh)/float(len(self.get_virtualpop()))
319
320
def get_stagetable(self):
321
return self.parent.get_plans().get_stagetable('autorides')
322
323
def get_demand(self):
324
return self.parent.parent
325
326
def clear_vehicles(self):
327
self.get_ids_veh_pop()[self.ids_person.get_value()] = -1
328
self.clear()
329
330
def assign_to_persons(self, ids_person):
331
# print 'assign_to_persons',len(ids_person),self.mode
332
# self.clear_vehicles()
333
#ids_person_noveh = set(ids_person).difference(set(self.ids_person))
334
n_new = len(ids_person)
335
#
336
# this call is selecting a veh id aof the specific mode
337
# according to its share within this mode
338
ids_vtype = self.get_demand().vtypes.generate_vtypes_for_mode(n_new, mode=self.mode)
339
340
# print ' ids_vtype',ids_vtype
341
ids_veh = self.add_rows(n=n_new,
342
ids_person=ids_person,
343
ids_vtype=ids_vtype,
344
)
345
self.get_ids_veh_pop()[ids_person] = ids_veh
346
return ids_veh
347
348
def get_vtypes(self):
349
"""
350
Returns a set with all used vehicle types.
351
"""
352
# print 'Vehicles_individual.get_vtypes',self.cols.vtype
353
return set(self.ids_vtype.get_value())
354
355
def get_id_veh_xml(self, id_veh, id_stage):
356
return self.mode_prefix + '.%s.%s' % (id_veh, id_stage)
357
358
def get_id_line_xml(self, id_veh):
359
return self.mode_prefix + '.%s' % (id_veh)
360
361
def get_id_from_id_sumo(self, id_veh_sumo):
362
# print 'get_id_from_id_sumo',id_veh_sumo,id_veh_sumo.split('.'),self.mode_prefix
363
if len(id_veh_sumo.split('.')) == 3:
364
prefix, id_veh, id_stage = id_veh_sumo.split('.')
365
if prefix == self.mode_prefix:
366
return int(id_veh)
367
else:
368
return -1
369
return -1
370
371
def get_info_from_id_sumo(self, id_veh_sumo):
372
if len(id_veh_sumo.split('.')) == 3:
373
prefix, id_veh, id_stage = id_veh_sumo.split('.')
374
if prefix == self.mode_prefix:
375
return int(id_veh), int(id_stage)
376
else:
377
return -1, -1
378
return -1, -1
379
380
# def append_ride(self, id_veh, id_ride):
381
# ids_ride = self.ids_rides[id_veh]
382
# if ids_ride is None:
383
# self.ids_rides[id_veh] = [id_ride]
384
# else:
385
# ids_ride.append(id_ride)
386
387
def prepare_write_xml(self, is_route=True, is_plain=False):
388
"""
389
Prepare xml export. Must return export function.
390
"""
391
virtualpop = self.get_virtualpop()
392
scenario = virtualpop.get_scenario()
393
#plans = virtualpop.get_plans()
394
395
self._rides = self.get_stagetable()
396
self._edges = scenario.net.edges
397
self._lanes = scenario.net.lanes
398
#self._individualvehicle = virtualpop.get_ibikes()
399
self._ids_vtype_sumo = scenario.demand.vtypes.ids_sumo
400
self._ids_edge_sumo = self._edges.ids_sumo
401
self._id_mode = scenario.net.modes.get_id_mode(self.mode)
402
self._get_laneid_allowed = self._edges.get_laneid_allowed
403
self._get_sumoinfo_from_id_lane = scenario.net.lanes.get_sumoinfo_from_id_lane
404
self._space_access = self.space_access.get_value()
405
#self._time_veh_wait_after_stop = 3600
406
self._parking = virtualpop.get_landuse().parking
407
self._time_after_unboarding = self.time_after_unboarding.get_value()
408
409
# TODO: here we'd need also a case with is_plain and is_route
410
if is_plain:
411
return self.write_xml_no_line
412
413
elif is_route:
414
return self.write_xml
415
else:
416
return self.write_xml_noroute
417
418
def get_id_veh(self, id_stage):
419
return self._rides.ids_iauto[id_stage]
420
421
def write_xml_no_line(self, fd, id_stage, time_begin, indent=2):
422
# same as write_xml, but without id_line, route and stops
423
424
# TODO: actually this should go in individualvehicle
425
#time_veh_wait_after_stop = 3600
426
#plans = self.get_plans()
427
#walkstages = plans.get_stagetable('walks')
428
#rides = plans.get_stagetable('autorides')
429
#activitystages = plans.get_stagetable('activities')
430
431
rides = self._rides
432
#lanes = self._lanes
433
parking = self._parking
434
#net = self.get_net()
435
#lanes = net.lanes
436
#edges = net.edges
437
#ind_ride = rides.get_inds(id_stage)
438
id_veh = self.get_id_veh(id_stage)
439
#individualvehicle = self._iveh
440
id_vtype = self.ids_vtype[id_veh]
441
442
# id_veh_ride,
443
# ids_vtypes_iveh[id_veh],
444
# ids_edges_rides_arr[ind_ride],
445
# ids_parking_from_rides_arr[ind_ride],
446
# ids_parking_to_rides_arr[ind_ride],
447
448
id_parking_from = rides.ids_parking_from[id_stage]
449
id_lane_from = parking.ids_lane[id_parking_from]
450
#laneindex_from = self._lanes.indexes[id_lane_from]
451
pos_from = parking.positions[id_parking_from]
452
453
id_parking_to = rides.ids_parking_to[id_stage]
454
id_lane_to = parking.ids_lane[id_parking_to]
455
#laneindex_to = self._lanes.indexes[id_lane_to]
456
pos_to = parking.positions[id_parking_to]
457
458
# write unique veh ID to prevent confusion with other veh declarations
459
fd.write(xm.start('trip id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2))
460
461
# get start time of first stage of the plan
462
#id_plan = rides.ids_plan[id_stage]
463
#stages0, id_stage0 = self.get_plans().stagelists[id_plan][0]
464
465
# this is the time when the vehicle appers in the scenario
466
fd.write(xm.num('depart', '%.d' % rides.times_init[id_stage]))
467
#fd.write(xm.num('depart', '%.d'%stages0.times_start[id_stage0]))
468
469
fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype]))
470
471
# no line
472
#fd.write(xm.num('line', self.get_id_line_xml(id_veh) ))
473
474
fd.write(xm.num('from', self._ids_edge_sumo[rides.ids_edges[id_stage]][0]))
475
fd.write(xm.num('to', self._ids_edge_sumo[rides.ids_edges[id_stage]][-1]))
476
477
fd.write(xm.num('departPos', pos_from))
478
fd.write(xm.num('departLane', self._lanes.indexes[id_lane_from]))
479
480
fd.write(xm.stop())
481
482
# no route
483
# fd.write(xm.start('route',indent+4))
484
# print ' edgeindex[ids_edge]',edgeindex[ids_edge]
485
# fd.write(xm.arr('edges',self._ids_edge_sumo[rides.ids_edges[id_stage]]))
486
487
# no stops
488
489
fd.write(xm.end('trip', indent+2))
490
491
def write_xml(self, fd, id_stage, time_begin, indent=2):
492
493
# TODO: actually this should go in individualvehicle
494
#time_veh_wait_after_stop = 3600
495
#plans = self.get_plans()
496
#walkstages = plans.get_stagetable('walks')
497
#rides = plans.get_stagetable('autorides')
498
#activitystages = plans.get_stagetable('activities')
499
500
rides = self._rides
501
#lanes = self._lanes
502
parking = self._parking
503
#net = self.get_net()
504
#lanes = net.lanes
505
#edges = net.edges
506
#ind_ride = rides.get_inds(id_stage)
507
id_veh = self.get_id_veh(id_stage)
508
#individualvehicle = self._iveh
509
id_vtype = self.ids_vtype[id_veh]
510
511
# id_veh_ride,
512
# ids_vtypes_iveh[id_veh],
513
# ids_edges_rides_arr[ind_ride],
514
# ids_parking_from_rides_arr[ind_ride],
515
# ids_parking_to_rides_arr[ind_ride],
516
517
id_parking_from = rides.ids_parking_from[id_stage]
518
id_lane_from = parking.ids_lane[id_parking_from]
519
#laneindex_from = self._lanes.indexes[id_lane_from]
520
pos_from = parking.positions[id_parking_from]
521
522
id_parking_to = rides.ids_parking_to[id_stage]
523
id_lane_to = parking.ids_lane[id_parking_to]
524
#laneindex_to = self._lanes.indexes[id_lane_to]
525
pos_to = parking.positions[id_parking_to]
526
527
# write unique veh ID to prevent confusion with other veh declarations
528
fd.write(xm.start('vehicle id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2))
529
530
# get start time of first stage of the plan
531
#id_plan = rides.ids_plan[id_stage]
532
#stages0, id_stage0 = self.get_plans().stagelists[id_plan][0]
533
534
# this is the time when the vehicle appers in the scenario
535
fd.write(xm.num('depart', '%.d' % rides.times_init[id_stage]))
536
#fd.write(xm.num('depart', '%.d'%stages0.times_start[id_stage0]))
537
538
fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype]))
539
fd.write(xm.num('line', self.get_id_line_xml(id_veh)))
540
fd.write(xm.num('departPos', pos_from))
541
fd.write(xm.num('departLane', self._lanes.indexes[id_lane_from]))
542
543
fd.write(xm.stop())
544
545
# write route
546
fd.write(xm.start('route', indent+4))
547
# print ' edgeindex[ids_edge]',edgeindex[ids_edge]
548
fd.write(xm.arr('edges', self._ids_edge_sumo[rides.ids_edges[id_stage]]))
549
550
# does not seem to have an effect, always starts at base????
551
#fd.write(xm.num('departPos', pos_from))
552
#fd.write(xm.num('departLane', laneindex_from ))
553
fd.write(xm.stopit())
554
555
# write depart stop
556
fd.write(xm.start('stop', indent+4))
557
#id_lane = self._lanes.ids_edge[id_lane_from]
558
fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane_from)))
559
# in 0.31 the vehicle will wait until after this duration
560
# so it will be removed unless it will get a timeout function
561
#fd.write(xm.num('duration', time_veh_wait_after_stop))
562
fd.write(xm.num('startPos', pos_from - parking.lengths[id_parking_from]))
563
fd.write(xm.num('endPos', pos_from))
564
fd.write(xm.num('triggered', "True"))
565
566
# chrashes with parking=True in 0.30!
567
# however if not parked the vhcle is blocking the traffic
568
# while waiting: workaround: delay departure to be shure that person already arrived
569
570
fd.write(xm.num('parking', "True")) # in windows 0.30 parked vehicles do not depart!!
571
#fd.write(xm.num('parking', "False"))
572
fd.write(xm.stopit())
573
574
# write arrival stop
575
fd.write(xm.start('stop', indent+4))
576
fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane_to)))
577
fd.write(xm.num('duration', self._time_after_unboarding)) # for unboarding only
578
fd.write(xm.num('startPos', pos_to - parking.lengths[id_parking_to]))
579
fd.write(xm.num('endPos', pos_to))
580
#fd.write(xm.num('triggered', "True"))
581
fd.write(xm.stopit())
582
583
fd.write(xm.end('vehicle', indent+2))
584
585
def write_xml_noroute(self, fd, id_stage, time_begin, indent=2):
586
587
# TODO: actually this should go in individualvehicle
588
#time_veh_wait_after_stop = 3600
589
#plans = self.get_plans()
590
#walkstages = plans.get_stagetable('walks')
591
#rides = plans.get_stagetable('autorides')
592
#activitystages = plans.get_stagetable('activities')
593
594
rides = self._rides
595
#lanes = self._lanes
596
parking = self._parking
597
#net = self.get_net()
598
#lanes = net.lanes
599
#edges = net.edges
600
#ind_ride = rides.get_inds(id_stage)
601
id_veh = self.get_id_veh(id_stage)
602
#individualvehicle = self._iveh
603
id_vtype = self.ids_vtype[id_veh]
604
605
# id_veh_ride,
606
# ids_vtypes_iveh[id_veh],
607
# ids_edges_rides_arr[ind_ride],
608
# ids_parking_from_rides_arr[ind_ride],
609
# ids_parking_to_rides_arr[ind_ride],
610
611
id_parking_from = rides.ids_parking_from[id_stage]
612
id_lane_from = parking.ids_lane[id_parking_from]
613
#laneindex_from = self._lanes.indexes[id_lane_from]
614
pos_from = parking.positions[id_parking_from]
615
616
id_parking_to = rides.ids_parking_to[id_stage]
617
id_lane_to = parking.ids_lane[id_parking_to]
618
#laneindex_to = self._lanes.indexes[id_lane_to]
619
pos_to = parking.positions[id_parking_to]
620
621
# write unique veh ID to prevent confusion with other veh declarations
622
fd.write(xm.start('trip id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2))
623
624
# get start time of first stage of the plan
625
#id_plan = rides.ids_plan[id_stage]
626
#stages0, id_stage0 = self.get_plans().stagelists[id_plan][0]
627
628
# this is the time when the vehicle appers in the scenario
629
fd.write(xm.num('depart', '%.d' % rides.times_init[id_stage]))
630
#fd.write(xm.num('depart', '%.d'%stages0.times_start[id_stage0]))
631
632
fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype]))
633
fd.write(xm.num('line', self.get_id_line_xml(id_veh)))
634
635
fd.write(xm.num('from', self._ids_edge_sumo[rides.ids_edges[id_stage]][0]))
636
fd.write(xm.num('to', self._ids_edge_sumo[rides.ids_edges[id_stage]][-1]))
637
638
fd.write(xm.num('departPos', pos_from))
639
fd.write(xm.num('departLane', self._lanes.indexes[id_lane_from]))
640
641
fd.write(xm.stop())
642
643
# write route
644
# fd.write(xm.start('route',indent+4))
645
# print ' edgeindex[ids_edge]',edgeindex[ids_edge]
646
# fd.write(xm.arr('edges',self._ids_edge_sumo[rides.ids_edges[id_stage]]))
647
648
# does not seem to have an effect, always starts at base????
649
#fd.write(xm.num('departPos', pos_from))
650
#fd.write(xm.num('departLane', laneindex_from ))
651
# fd.write(xm.stopit())
652
653
# write depart stop
654
fd.write(xm.start('stop', indent+4))
655
#id_lane = self._lanes.ids_edge[id_lane_from]
656
fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane_from)))
657
# in 0.31 the vehicle will wait until after this duration
658
# so it will be removed unless it will get a timeout function
659
#fd.write(xm.num('duration', time_veh_wait_after_stop))
660
fd.write(xm.num('startPos', pos_from - parking.lengths[id_parking_from]))
661
fd.write(xm.num('endPos', pos_from))
662
fd.write(xm.num('triggered', "True"))
663
664
# chrashes with parking=True in 0.30!
665
# however if not parked the vhcle is blocking the traffic
666
# while waiting: workaround: delay departure to be shure that person already arrived
667
668
fd.write(xm.num('parking', "True")) # in windows 0.30 parked vehicles do not depart!!
669
#fd.write(xm.num('parking', "False"))
670
fd.write(xm.stopit())
671
672
# write arrival stop
673
fd.write(xm.start('stop', indent+4))
674
fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane_to)))
675
fd.write(xm.num('duration', self._time_after_unboarding)) # for unboarding only
676
fd.write(xm.num('startPos', pos_to - parking.lengths[id_parking_to]))
677
fd.write(xm.num('endPos', pos_to))
678
#fd.write(xm.num('triggered', "True"))
679
fd.write(xm.stopit())
680
681
fd.write(xm.end('trip', indent+2))
682
683
684
class IndividualBikes(IndividualAutos):
685
686
def __init__(self, ident, population, **kwargs):
687
# print 'individualvehicle vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1')
688
self._init_objman(ident=ident,
689
parent=population,
690
name='Indiv. Bikes',
691
info='Individual bike database. These are privately owned bikes.',
692
**kwargs)
693
self._init_attributes()
694
self._init_constants()
695
696
def _init_attributes(self):
697
698
IndividualAutos._init_attributes(self)
699
700
def _init_constants(self):
701
702
self.do_not_save_attrs(['mode', 'mode_prefix',
703
'_edges', '_ids_vtype_sumo', '_ids_edge_sumo',
704
'_id_mode', '_get_laneid_allowed', '_get_sumoinfo_from_id_lane',
705
'_space_access',
706
])
707
708
def def_mode(self):
709
self.mode = 'bicycle'
710
self.mode_prefix = 'ibike'
711
712
def get_ids_veh_pop(self):
713
"""
714
To be overridden by other individual vehicle types.
715
"""
716
return self.parent.ids_ibike
717
718
def get_stagetable(self):
719
return self.parent.get_plans().get_stagetable('bikerides')
720
721
def get_id_veh(self, id_stage):
722
return self._rides.ids_ibike[id_stage]
723
724
def prepare_write_xml(self, is_route=True, is_plain=False):
725
"""
726
Prepare xml export. Must return export function.
727
"""
728
virtualpop = self.get_virtualpop()
729
scenario = virtualpop.get_scenario()
730
#plans = virtualpop.get_plans()
731
self._rides = self.get_stagetable()
732
self._edges = scenario.net.edges
733
#self._individualvehicle = virtualpop.get_ibikes()
734
self._ids_vtype_sumo = scenario.demand.vtypes.ids_sumo
735
self._ids_edge_sumo = self._edges.ids_sumo
736
self._id_mode = scenario.net.modes.get_id_mode(self.mode)
737
self._get_laneid_allowed = self._edges.get_laneid_allowed
738
self._get_sumoinfo_from_id_lane = scenario.net.lanes.get_sumoinfo_from_id_lane
739
self._space_access = self.space_access.get_value()
740
if is_plain:
741
return self.write_xml_no_line
742
else:
743
return self.write_xml
744
745
# def _limit_pos(self,pos,id_edge):
746
747
def write_xml_no_line(self, fd, id_stage, time_begin, indent=2):
748
rides = self._rides
749
id_veh = self.get_id_veh(id_stage)
750
# print 'write_xml',id_stage, time_begin,self.get_id_veh_xml(id_veh, id_stage)
751
# print ' ids_edge_from,ids_edge_to',rides.ids_edge_from[id_stage],rides.ids_edge_to[id_stage],self._get_laneid_allowed( rides.ids_edge_from[id_stage], self._id_mode),self._get_laneid_allowed( rides.ids_edge_to[id_stage], self._id_mode)
752
753
# TODO: actually this should go in individualvehicle
754
#time_veh_wait_after_stop = 3600
755
#plans = self.get_plans()
756
#walkstages = plans.get_stagetable('walks')
757
#rides = plans.get_stagetable('bikerides')
758
#activitystages = plans.get_stagetable('activities')
759
760
# for debug only:
761
#virtualpop = self.get_virtualpop()
762
#ids_edge_sumo = virtualpop.get_net().edges.ids_sumo
763
764
#parking = self.get_landuse().parking
765
#net = self.get_net()
766
#lanes = net.lanes
767
#edges = net.edges
768
769
#ind_ride = rides.get_inds(id_stage)
770
771
#individualvehicle = self.get_ibikes()
772
id_vtype = self.ids_vtype[id_veh]
773
774
# id_veh_ride,
775
# ids_vtypes_iveh[id_veh],
776
# ids_edges_rides_arr[ind_ride],
777
# ids_parking_from_rides_arr[ind_ride],
778
# ids_parking_to_rides_arr[ind_ride],
779
780
#id_parking_from = rides.ids_parking_from[id_stage]
781
#id_lane_from = parking.ids_lane[id_parking_from]
782
#laneindex_from = lanes.indexes[id_lane_from]
783
#pos_from = parking.positions[id_parking_from]
784
785
#id_parking_to = rides.ids_parking_to[id_stage]
786
#id_lane_to = parking.ids_lane[id_parking_to]
787
#laneindex_to = lanes.indexes[id_lane_to]
788
#pos_to = parking.positions[id_parking_to]
789
790
# write unique veh ID to prevent confusion with other veh declarations
791
fd.write(xm.start('trip id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2))
792
793
# get start time of first stage of the plan
794
#id_plan = rides.ids_plan[id_stage]
795
#stages0, id_stage0 = self.get_plans().stagelists[id_plan][0]
796
797
# this is the time when the vehicle appers in the scenario
798
#fd.write(xm.num('depart', '%.d'%rides.times_init[id_stage]))
799
fd.write(xm.num('depart', '%.d' % time_begin))
800
fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype]))
801
#fd.write(xm.num('line', self.get_id_line_xml(id_veh) ))
802
#fd.write(xm.num('departPos', pos_from))
803
#fd.write(xm.num('departLane', laneindex_from ))
804
fd.write(xm.num('from', self._ids_edge_sumo[rides.ids_edge_from[id_stage]]))
805
fd.write(xm.num('to', self._ids_edge_sumo[rides.ids_edge_to[id_stage]]))
806
pos_from = rides.positions_from[id_stage]
807
pos_to = rides.positions_to[id_stage]
808
fd.write(xm.num('departPos', pos_from))
809
fd.write(xm.num('arrivalPos', pos_to))
810
fd.write(xm.num('departLane', 'best'))
811
812
fd.write(xm.stop())
813
814
# no route
815
816
# no stops written here
817
818
fd.write(xm.end('trip', indent+2))
819
820
def write_xml(self, fd, id_stage, time_begin, indent=2):
821
rides = self._rides
822
id_veh = self.get_id_veh(id_stage)
823
# print 'write_xml',id_stage, time_begin,self.get_id_veh_xml(id_veh, id_stage)
824
# print ' ids_edge_from,ids_edge_to',rides.ids_edge_from[id_stage],rides.ids_edge_to[id_stage],self._get_laneid_allowed( rides.ids_edge_from[id_stage], self._id_mode),self._get_laneid_allowed( rides.ids_edge_to[id_stage], self._id_mode)
825
826
# TODO: actually this should go in individualvehicle
827
#time_veh_wait_after_stop = 3600
828
#plans = self.get_plans()
829
#walkstages = plans.get_stagetable('walks')
830
#rides = plans.get_stagetable('bikerides')
831
#activitystages = plans.get_stagetable('activities')
832
833
# for debug only:
834
#virtualpop = self.get_virtualpop()
835
#ids_edge_sumo = virtualpop.get_net().edges.ids_sumo
836
837
#parking = self.get_landuse().parking
838
#net = self.get_net()
839
#lanes = net.lanes
840
#edges = net.edges
841
842
#ind_ride = rides.get_inds(id_stage)
843
844
#individualvehicle = self.get_ibikes()
845
id_vtype = self.ids_vtype[id_veh]
846
847
# id_veh_ride,
848
# ids_vtypes_iveh[id_veh],
849
# ids_edges_rides_arr[ind_ride],
850
# ids_parking_from_rides_arr[ind_ride],
851
# ids_parking_to_rides_arr[ind_ride],
852
853
#id_parking_from = rides.ids_parking_from[id_stage]
854
#id_lane_from = parking.ids_lane[id_parking_from]
855
#laneindex_from = lanes.indexes[id_lane_from]
856
#pos_from = parking.positions[id_parking_from]
857
858
#id_parking_to = rides.ids_parking_to[id_stage]
859
#id_lane_to = parking.ids_lane[id_parking_to]
860
#laneindex_to = lanes.indexes[id_lane_to]
861
#pos_to = parking.positions[id_parking_to]
862
863
# write unique veh ID to prevent confusion with other veh declarations
864
fd.write(xm.start('vehicle id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2))
865
866
# get start time of first stage of the plan
867
#id_plan = rides.ids_plan[id_stage]
868
#stages0, id_stage0 = self.get_plans().stagelists[id_plan][0]
869
870
# this is the time when the vehicle appers in the scenario
871
#fd.write(xm.num('depart', '%.d'%rides.times_init[id_stage]))
872
fd.write(xm.num('depart', '%.d' % time_begin))
873
fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype]))
874
fd.write(xm.num('line', self.get_id_line_xml(id_veh)))
875
#fd.write(xm.num('departPos', pos_from))
876
#fd.write(xm.num('departLane', laneindex_from ))
877
fd.write(xm.num('from', self._ids_edge_sumo[rides.ids_edge_from[id_stage]]))
878
fd.write(xm.num('to', self._ids_edge_sumo[rides.ids_edge_to[id_stage]]))
879
pos_from = rides.positions_from[id_stage]
880
pos_to = rides.positions_to[id_stage]
881
fd.write(xm.num('departPos', pos_from))
882
fd.write(xm.num('arrivalPos', pos_to))
883
fd.write(xm.num('departLane', 'best'))
884
885
fd.write(xm.stop())
886
887
# write route
888
fd.write(xm.start('route', indent+4))
889
# print ' ids_edges',rides.ids_edges[id_stage]
890
# print ' ids_sumo',self._ids_edge_sumo[rides.ids_edges[id_stage]]
891
fd.write(xm.arr('edges', self._ids_edge_sumo[rides.ids_edges[id_stage]]))
892
# fd.write(xm.arr('edges',edges.ids_sumo[rides.ids_edges[id_stage]]))
893
894
# does not seem to have an effect, always starts at base????
895
896
#id_edge = rides.ids_edge_from[id_stage]
897
# print ' id_lane',id_lane,self._get_sumoinfo_from_id_lane(id_lane),'id_edge',id_edge,ids_edge_sumo[id_edge]
898
899
fd.write(xm.stopit())
900
901
# write depart stop
902
fd.write(xm.start('stop', indent+4))
903
id_lane = self._get_laneid_allowed(rides.ids_edge_from[id_stage], self._id_mode)
904
fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane)))
905
# in 0.31 the vehicle will wait until after this duration
906
# so it will be removed unless it will get a timeout function
907
#fd.write(xm.num('duration', time_veh_wait_after_stop))
908
if pos_from > self._space_access:
909
fd.write(xm.num('startPos', pos_from - self._space_access))
910
fd.write(xm.num('endPos', pos_from+self._space_access))
911
else:
912
fd.write(xm.num('startPos', 0.1*pos_from))
913
fd.write(xm.num('endPos', pos_from+self._space_access))
914
915
fd.write(xm.num('triggered', "True"))
916
917
# chrashes with parking=True in 0.30!
918
# however if not parked the vhcle is blocking the traffic
919
# while waiting: workaround: delay departure to be shure that person already arrived
920
921
fd.write(xm.num('parking', 'True')) # in windows 0.30 parked vehicles do not depart!!
922
#fd.write(xm.num('parking', "False"))
923
fd.write(xm.stopit())
924
925
# write arrival stop
926
fd.write(xm.start('stop', indent+4))
927
928
id_lane = self._get_laneid_allowed(rides.ids_edge_to[id_stage], self._id_mode)
929
#id_edge = rides.ids_edge_to[id_stage]
930
# print ' id_lane',id_lane,self._get_sumoinfo_from_id_lane(id_lane),'id_edge',id_edge,ids_edge_sumo[id_edge]
931
932
fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane)))
933
fd.write(xm.num('duration', 5)) # for unboarding only
934
if pos_to > self._space_access:
935
fd.write(xm.num('startPos', pos_to - self._space_access))
936
fd.write(xm.num('endPos', pos_to))
937
else:
938
fd.write(xm.num('startPos', 0.1*pos_to))
939
fd.write(xm.num('endPos', pos_to))
940
#fd.write(xm.num('triggered', "True"))
941
fd.write(xm.stopit())
942
943
fd.write(xm.end('vehicle', indent+2))
944
945
946
class IndividualMotorcycles(IndividualBikes):
947
948
def __init__(self, ident, population, **kwargs):
949
# print 'individualvehicle vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1')
950
self._init_objman(ident=ident,
951
parent=population,
952
name='Indiv. Moto',
953
info='Individual Motorcycle/moped database. These are privately owned motorcycles.',
954
**kwargs)
955
IndividualBikes._init_attributes(self)
956
IndividualBikes._init_constants(self)
957
958
def def_mode(self):
959
self.mode = 'motorcycle'
960
self.mode_prefix = 'imoto'
961
962
def get_ids_veh_pop(self):
963
"""
964
To be overridden by other individual vehicle types.
965
"""
966
return self.parent.ids_imoto
967
968
def get_stagetable(self):
969
return self.parent.get_plans().get_stagetable('motorides')
970
971
def get_id_veh(self, id_stage):
972
return self._rides.ids_imoto[id_stage]
973
974
975
class StrategyMixin(cm.BaseObjman):
976
def __init__(self, ident, parent=None,
977
name='Strategy mixin', info='Info on strategy.',
978
**kwargs):
979
"""
980
To be overridden.
981
"""
982
# attention parent is the Strategies table
983
self._init_objman(ident, parent, **kwargs)
984
attrsman = self.set_attrsman(cm.Attrsman(self))
985
986
def _init_attributes(self, **kwargs):
987
# print 'StrategyMixin._init_attributes'
988
attrsman = self.get_attrsman()
989
990
def get_id_strategy(self):
991
return self.parent.names.get_id_from_index(self.get_ident())
992
993
def get_scenario(self):
994
return self.parent.parent.get_scenario()
995
996
def get_activities(self):
997
return self.parent.parent.get_activities()
998
999
def get_virtualpop(self):
1000
return self.parent.parent
1001
1002
def get_plans(self):
1003
return self.parent.parent.plans
1004
1005
def clip_positions(self, positions, ids_edge):
1006
lengths = self.get_scenario().net.edges.lengths[ids_edge]
1007
# print 'clip_positions',positions.shape,ids_edge.shape,lengths.shape
1008
positions_clip = np.clip(positions, self.dist_node_min*np.ones(len(positions),
1009
dtype=np.float32), lengths-self.dist_node_min)
1010
inds = lengths < 2*self.dist_node_min
1011
# print ' inds.shape',inds.shape,positions_clip.shape
1012
positions_clip[inds] = 0.5*lengths[inds]
1013
return positions_clip
1014
1015
def _init_attributes_strategy(self, **kwargs):
1016
attrsman = self.get_attrsman()
1017
self.dist_node_min = attrsman.add(cm.AttrConf('dist_node_min', kwargs.get('dist_node_min', 40.0),
1018
groupnames=['options'],
1019
perm='rw',
1020
name='Min. dist to nodes',
1021
unit='m',
1022
info='Minimum distance between starting position and node center.',
1023
))
1024
1025
def get_utility_specific(self, id_plan):
1026
"""Method returns a strategy specific Utility. Here simly a constant is returned. This constant needs to be defined as attribute of the specific strategy"""
1027
1028
return 0.0
1029
1030
# def _init_constants_strategy(self):
1031
# #print '_init_constants_strategy'
1032
# modes = self.get_virtualpop().get_scenario().net.modes
1033
# self._id_mode_bike = modes.get_id_mode('bicycle')
1034
# self._id_mode_auto = modes.get_id_mode('passenger')
1035
# self._id_mode_moto = modes.get_id_mode('motorcycle')
1036
# self.get_attrsman().do_not_save_attrs([
1037
# '_id_mode_bike','_id_mode_auto','_id_mode_moto',
1038
# ])
1039
# print ' _id_mode_auto',self._id_mode_auto
1040
1041
# def are_feasible(self, ids_person):
1042
# """
1043
# Returns a bool vector, with True values for
1044
# persons where this strategy can be applied.
1045
# """
1046
# return []
1047
1048
# def is_feasible(self, id_person):
1049
# """
1050
# Returns True if this strategy is feasible for this person.
1051
# Overriden by specific strategy.
1052
# """
1053
# return False
1054
1055
def preevaluate(self, ids_person):
1056
"""
1057
Preevaluation strategies for person IDs in vector ids_person.
1058
1059
Returns a preevaluation vector with a preevaluation value
1060
for each person ID. The values of the preevaluation vector are as follows:
1061
-1 : Strategy cannot be applied
1062
0 : Stategy can be applied, but the preferred mode is not used
1063
1 : Stategy can be applied, and preferred mode is part of the strategy
1064
2 : Strategy uses predomunantly preferred mode
1065
1066
"""
1067
return zeros(len(ids_person), dtype=np.int32)
1068
1069
def plan(self, ids_person, logger=None, **kwargs):
1070
"""
1071
Generates a plan for these person according to this strategie.
1072
Overriden by specific strategy.
1073
"""
1074
pass
1075
1076
1077
class NoneStrategy(StrategyMixin):
1078
def __init__(self, ident, parent=None,
1079
name='None strategy',
1080
info='With this strategy, no mobility plan is generated.',
1081
**kwargs):
1082
1083
self._init_objman(ident, parent, name=name, info=info, **kwargs)
1084
attrsman = self.set_attrsman(cm.Attrsman(self))
1085
1086
1087
class WalkStrategy(StrategyMixin):
1088
def __init__(self, ident, parent=None,
1089
name='Walk Strategy',
1090
info='With this strategy, the person walks to all destinations.',
1091
version=0.1,
1092
**kwargs):
1093
1094
self._init_objman(ident, parent, name=name, info=info, **kwargs)
1095
attrsman = self.set_attrsman(cm.Attrsman(self))
1096
# specific init
1097
self._init_attributes()
1098
self._init_constants()
1099
1100
def _init_attributes(self, **kwargs):
1101
# print 'StrategyMixin._init_attributes'
1102
attrsman = self.get_attrsman()
1103
1104
self.utility_constant = attrsman.add(cm.AttrConf('utility_constant', kwargs.get('utility_constant', -0.0556),
1105
groupnames=['options'],
1106
perm='rw',
1107
name='Utility constant for walk strategy',
1108
info='Constant to calculate utility: U = Const + value_of_time*time_exec',
1109
))
1110
1111
self.is_walk_filter = attrsman.add(cm.AttrConf('is_walk_filter', kwargs.get('is_walk_filter', False),
1112
groupnames=['options'],
1113
name='Walk Filter',
1114
info=""" Enable the Walk filter.
1115
If it is True : Generate walk plans only for people who respect the max distance parameter.
1116
If it is False: Generate walk plans for all virtual population.
1117
""",
1118
))
1119
1120
# if hasattr(self,'max_dist_fac'):
1121
# dist_fac_max_default = self.max_dist_fac
1122
# attrsman.delete('max_dist_fac')
1123
# else:
1124
# dist_fac_max_default = kwargs.get('dist_fac_max',500.0)
1125
1126
self.dist_fac_max = attrsman.add(cm.AttrConf('dist_fac_max', kwargs.get('dist_fac_max', 500.0),
1127
groupnames=['options'],
1128
perm='rw',
1129
name='Max distance facilities',
1130
unit='m',
1131
info="""Max distance between origin and destination facilities corrisponding to the first and second activity.
1132
If the line of sight distance is greater than this distance, the walk plan will not be created.
1133
Will be only applied to those who have not walking as preferred mode.
1134
""",
1135
))
1136
1137
# if self.get_version() < 0.1:
1138
# self.set_version(0.1)
1139
1140
def _init_constants(self):
1141
#virtualpop = self.get_virtualpop()
1142
#stagetables = virtualpop.get_stagetables()
1143
1144
#self._walkstages = stagetables.get_stagetable('walks')
1145
#self._ridestages = stagetables.get_stagetable('rides')
1146
#self._activitystages = stagetables.get_stagetable('activities')
1147
1148
#self._plans = virtualpop.get_plans()
1149
#
1150
# print 'AutoStrategy._init_constants'
1151
# print dir(self)
1152
# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])
1153
1154
modes = self.get_virtualpop().get_scenario().net.modes
1155
self._id_mode_bike = modes.get_id_mode('bicycle')
1156
self._id_mode_auto = modes.get_id_mode('passenger')
1157
self._id_mode_moto = modes.get_id_mode('motorcycle')
1158
self._id_mode_bus = modes.get_id_mode('bus')
1159
self._id_mode_ped = modes.get_id_mode('pedestrian')
1160
self.get_attrsman().do_not_save_attrs([
1161
'_id_mode_bike', '_id_mode_auto', '_id_mode_moto',
1162
'_id_mode_bus', '_id_mode_ped',
1163
])
1164
1165
def get_utility_specific(self, id_plan):
1166
return self.utility_constant
1167
1168
def preevaluate(self, ids_person):
1169
"""
1170
Preevaluation strategies for person IDs in vector ids_person.
1171
1172
Returns a preevaluation vector with a preevaluation value
1173
for each person ID. The values of the preevaluation vector are as follows:
1174
-1 : Strategy cannot be applied
1175
0 : Stategy can be applied, but the preferred mode is not used
1176
1 : Stategy can be applied, and preferred mode is part of the strategy
1177
2 : Strategy uses predomunantly preferred mode
1178
1179
"""
1180
n_pers = len(ids_person)
1181
persons = self.get_virtualpop()
1182
preeval = np.zeros(n_pers, dtype=np.int32)
1183
1184
# TODO: here we could exclude by age or distance facilities-stops
1185
1186
# put 0 for persons whose preference is not walking, but can walk (everybody can walk)
1187
preeval[persons.ids_mode_preferred[ids_person] != self._id_mode_ped] = 0
1188
1189
# put 2 for persons whose preference is walking
1190
preeval[persons.ids_mode_preferred[ids_person] == self._id_mode_ped] = 2
1191
1192
# in case
1193
if self.is_walk_filter:
1194
1195
max_dist_fac_sqr = self.dist_fac_max**2
1196
1197
vp = self.get_virtualpop()
1198
scenario = vp.get_scenario()
1199
1200
facilities = scenario.landuse.facilities
1201
centroids = facilities.centroids
1202
activities = vp.get_activities()
1203
1204
ids_pers_filter = ids_person[persons.ids_mode_preferred[ids_person] != self._id_mode_ped]
1205
for i, ids_activity in zip(xrange(len(ids_pers_filter)), vp.activitypatterns[ids_pers_filter]):
1206
1207
id_act1 = ids_activity[0]
1208
id_act2 = ids_activity[1]
1209
id_fac_from = activities.ids_facility[id_act1]
1210
id_fac_to = activities.ids_facility[id_act2]
1211
dist_fac_sqr = np.sum((centroids[id_fac_from] - centroids[id_fac_to])**2)
1212
if dist_fac_sqr > max_dist_fac_sqr:
1213
preeval[i] = -1
1214
1215
print ' WalkStrategy.preevaluate', len(np.flatnonzero(preeval >= 0))
1216
return preeval
1217
1218
def plan(self, ids_person, logger=None, **kwargs):
1219
"""
1220
Generates a plan for these person according to this strategie.
1221
Overriden by specific strategy.
1222
"""
1223
print 'WalkStrategy.pan', len(ids_person)
1224
#make_plans_private(self, ids_person = None, mode = 'passenger')
1225
# routing necessary?
1226
virtualpop = self.get_virtualpop()
1227
plans = virtualpop.get_plans() # self._plans
1228
demand = virtualpop.get_demand()
1229
#ptlines = demand.ptlines
1230
1231
walkstages = plans.get_stagetable('walks')
1232
#transitstages = plans.get_stagetable('transits')
1233
activitystages = plans.get_stagetable('activities')
1234
1235
activities = virtualpop.get_activities()
1236
activitytypes = demand.activitytypes
1237
landuse = virtualpop.get_landuse()
1238
facilities = landuse.facilities
1239
#parking = landuse.parking
1240
1241
scenario = virtualpop.get_scenario()
1242
net = scenario.net
1243
edges = net.edges
1244
lanes = net.lanes
1245
modes = net.modes
1246
1247
#ptstops = net.ptstops
1248
1249
ids_laneedge = net.lanes.ids_edge
1250
1251
times_est_plan = plans.times_est
1252
# here we can determine edge weights for different modes
1253
1254
# this could be centralized to avoid redundance
1255
plans.prepare_stagetables(['walks', 'activities'])
1256
1257
ids_person_act, ids_act_from, ids_act_to\
1258
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
1259
1260
if len(ids_person_act) == 0:
1261
print 'WARNING in WalkStrategy.plan: no eligible persons found.'
1262
return False
1263
1264
# temporary maps from ids_person to other parameters
1265
nm = np.max(ids_person_act)+1
1266
map_ids_plan = np.zeros(nm, dtype=np.int32)
1267
#ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy())
1268
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
1269
1270
map_times = np.zeros(nm, dtype=np.int32)
1271
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
1272
1273
# set start time to plans (important!)
1274
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
1275
1276
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
1277
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
1278
1279
n_plans = len(ids_person_act)
1280
print 'TrasitStrategy.plan n_plans=', n_plans
1281
1282
# make initial activity stage
1283
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
1284
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
1285
# this is the time when first activity starts
1286
# first activity is normally not simulated
1287
1288
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
1289
durations_act_from = activities.get_durations(ids_act_from)
1290
times_from = map_times[ids_person_act]-durations_act_from
1291
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
1292
1293
for id_plan,\
1294
time,\
1295
id_act_from,\
1296
name_acttype_from,\
1297
duration_act_from,\
1298
id_edge_from,\
1299
pos_edge_from \
1300
in zip(map_ids_plan[ids_person_act],
1301
times_from,
1302
ids_act_from,
1303
names_acttype_from,
1304
durations_act_from,
1305
ids_edge_from,
1306
poss_edge_from):
1307
1308
id_stage_act, time = activitystages.append_stage(
1309
id_plan, time,
1310
ids_activity=id_act_from,
1311
names_activitytype=name_acttype_from,
1312
durations=duration_act_from,
1313
ids_lane=edges.ids_lanes[id_edge_from][0],
1314
positions=pos_edge_from,
1315
)
1316
1317
##
1318
1319
ind_act = 0
1320
1321
# main loop while there are persons performing
1322
# an activity at index ind_act
1323
while len(ids_person_act) > 0:
1324
ids_plan = map_ids_plan[ids_person_act]
1325
1326
times_from = map_times[ids_person_act]
1327
1328
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
1329
durations_act_to = activities.get_durations(ids_act_to)
1330
1331
ids_fac_from = map_ids_fac_from[ids_person_act]
1332
ids_fac_to = activities.ids_facility[ids_act_to]
1333
1334
centroids_from = facilities.centroids[ids_fac_from]
1335
centroids_to = facilities.centroids[ids_fac_to]
1336
1337
# origin edge and position
1338
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
1339
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
1340
1341
# destination edge and position
1342
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
1343
poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to]
1344
1345
#ids_stop_from = ptstops.get_closest(centroids_from)
1346
#ids_stop_to = ptstops.get_closest(centroids_to)
1347
1348
#ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]]
1349
#ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]]
1350
1351
# do random pos here
1352
# poss_stop_from = 0.5*( ptstops.positions_from[ids_stop_from]\
1353
# +ptstops.positions_to[ids_stop_from])
1354
1355
# poss_stop_to = 0.5*( ptstops.positions_from[ids_stop_to]\
1356
# +ptstops.positions_to[ids_stop_to])
1357
1358
i = 0.0
1359
for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, \
1360
in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to):
1361
n_pers = len(ids_person_act)
1362
if logger:
1363
logger.progress(i/n_pers*100)
1364
i += 1.0
1365
print 79*'_'
1366
print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person)
1367
1368
id_stage_walk1, time = walkstages.append_stage(id_plan, time_from,
1369
id_edge_from=id_edge_from,
1370
position_edge_from=pos_edge_from,
1371
id_edge_to=id_edge_to,
1372
position_edge_to=pos_edge_to, # -7.0,
1373
)
1374
1375
# update time for trips estimation for this plan
1376
plans.times_est[id_plan] += time-time_from
1377
1378
# define current end time without last activity duration
1379
plans.times_end[id_plan] = time
1380
1381
id_stage_act, time = activitystages.append_stage(
1382
id_plan, time,
1383
ids_activity=id_act_to,
1384
names_activitytype=name_acttype_to,
1385
durations=duration_act_to,
1386
ids_lane=edges.ids_lanes[id_edge_to][0],
1387
positions=pos_edge_to,
1388
)
1389
1390
# store time for next iteration in case other activities are
1391
# following
1392
map_times[id_person] = time
1393
1394
# select persons and activities for next setp
1395
ind_act += 1
1396
ids_person_act, ids_act_from, ids_act_to\
1397
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
1398
1399
1400
class AutoStrategy(StrategyMixin):
1401
def __init__(self, ident, parent=None,
1402
name='Auto strategy',
1403
info='With this strategy, the person uses his private auto as main transport mode.',
1404
**kwargs):
1405
1406
self._init_objman(ident, parent, name=name, info=info, **kwargs)
1407
attrsman = self.set_attrsman(cm.Attrsman(self))
1408
# specific init
1409
self._init_attributes()
1410
self._init_constants()
1411
1412
def _init_attributes(self, **kwargs):
1413
# print 'StrategyMixin._init_attributes'
1414
attrsman = self.get_attrsman()
1415
1416
self.utility_constant = attrsman.add(cm.AttrConf('utility_constant', kwargs.get('utility_constant', 0.0),
1417
groupnames=['options'],
1418
perm='rw',
1419
name='Utility constant for auto strategy',
1420
info='Constant to calculate utility: U = Const + value_of_time*time_exec',
1421
))
1422
1423
modechoices = self.get_virtualpop().get_scenario().net.modes.names.get_indexmap()
1424
modechoices['No fallback'] = None
1425
# print ' modechoices',modechoices
1426
self.id_mode_fallback = attrsman.add(am.AttrConf('id_mode_fallback', modechoices['taxi'],
1427
groupnames=['options'],
1428
choices=modechoices,
1429
name='Fallback Mode for Auto strategy',
1430
info="""Transport mode to be used instead of "passenger" mode
1431
in case the origin and destination cannot be connected by a route.
1432
This is typically the case with origins or destinations
1433
in traffic restricted zones.
1434
Coose for example "taxi" to get access to traffic restricted Zones.
1435
""",
1436
))
1437
1438
def _init_constants(self):
1439
#virtualpop = self.get_virtualpop()
1440
#stagetables = virtualpop.get_stagetables()
1441
1442
#self._walkstages = stagetables.get_stagetable('walks')
1443
#self._ridestages = stagetables.get_stagetable('rides')
1444
#self._activitystages = stagetables.get_stagetable('activities')
1445
1446
#self._plans = virtualpop.get_plans()
1447
#
1448
# print 'AutoStrategy._init_constants'
1449
# print dir(self)
1450
# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])
1451
1452
modes = self.get_virtualpop().get_scenario().net.modes
1453
self._id_mode_bike = modes.get_id_mode('bicycle')
1454
self._id_mode_auto = modes.get_id_mode('passenger')
1455
self._id_mode_moto = modes.get_id_mode('motorcycle')
1456
self.get_attrsman().do_not_save_attrs([
1457
'_id_mode_bike', '_id_mode_auto', '_id_mode_moto',
1458
])
1459
1460
def get_utility_specific(self, id_plan):
1461
return self.utility_constant
1462
1463
def preevaluate(self, ids_person):
1464
"""
1465
Preevaluation strategies for person IDs in vector ids_person.
1466
1467
Returns a preevaluation vector with a preevaluation value
1468
for each person ID. The values of the preevaluation vector are as follows:
1469
-1 : Strategy cannot be applied
1470
0 : Stategy can be applied, but the preferred mode is not used
1471
1 : Stategy can be applied, and preferred mode is part of the strategy
1472
2 : Strategy uses predomunantly preferred mode
1473
1474
"""
1475
n_pers = len(ids_person)
1476
print 'Autostrategy.preevaluate', n_pers, 'persons'
1477
persons = self.get_virtualpop()
1478
preeval = np.zeros(n_pers, dtype=np.int32)
1479
1480
# put -1 for persons without car access
1481
preeval[persons.ids_iauto[ids_person] == -1] = -1
1482
print ' persons having no auto', len(np.flatnonzero(persons.ids_iauto[ids_person] == -1))
1483
1484
# put 0 for persons with car but with a different preferred mode
1485
preeval[(persons.ids_iauto[ids_person] > -1)
1486
& (persons.ids_mode_preferred[ids_person] != self._id_mode_auto)] = 0
1487
1488
print ' persons with car but with a different preferred mode', len(np.flatnonzero((persons.ids_iauto[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] != self._id_mode_auto)))
1489
1490
# put 2 for persons with car access and who prefer the car
1491
preeval[(persons.ids_iauto[ids_person] > -1)
1492
& (persons.ids_mode_preferred[ids_person] == self._id_mode_auto)] = 2
1493
print ' persons with car access and who prefer the car', len(np.flatnonzero((persons.ids_iauto[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] == self._id_mode_auto)))
1494
1495
return preeval
1496
1497
# def are_feasible(self, ids_person):
1498
# """
1499
# Returns a bool vector, with True values for
1500
# persons where this strategy can be applied.
1501
# """
1502
# persons = self.get_virtualpop()
1503
#
1504
# # check if person has a car
1505
# # one may also check if there is parking available
1506
# # at all desinations
1507
# return persons.ids_iautos[ids_person] >= 0
1508
1509
def plan(self, ids_person, logger=None, **kwargs):
1510
"""
1511
Generates a plan for these person according to this strategie.
1512
Overriden by specific strategy.
1513
"""
1514
#make_plans_private(self, ids_person = None, mode = 'passenger')
1515
# routing necessary?
1516
virtualpop = self.get_virtualpop()
1517
plans = virtualpop.get_plans() # self._plans
1518
walkstages = plans.get_stagetable('walks')
1519
ridestages = plans.get_stagetable('autorides')
1520
activitystages = plans.get_stagetable('activities')
1521
1522
activities = virtualpop.get_activities()
1523
activitytypes = virtualpop.get_demand().activitytypes
1524
landuse = virtualpop.get_landuse()
1525
facilities = landuse.facilities
1526
parking = landuse.parking
1527
1528
scenario = virtualpop.get_scenario()
1529
edges = scenario.net.edges
1530
lanes = scenario.net.lanes
1531
modes = scenario.net.modes
1532
demand = scenario.demand
1533
vtyes = demand.vtypes
1534
1535
ids_mode = scenario.demand.vtypes.ids_mode
1536
iautos = virtualpop.get_iautos()
1537
1538
#times_est_plan = plans.times_est
1539
1540
# here we can determine edge weights for different modes
1541
plans.prepare_stagetables(['walks', 'autorides', 'activities'])
1542
1543
# get initial travel times for persons.
1544
# initial travel times depend on the initial activity
1545
1546
landuse.parking.clear_booking()
1547
1548
ids_person_act, ids_act_from, ids_act_to\
1549
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
1550
1551
if len(ids_person_act) == 0:
1552
print 'WARNING in Autostrategy.plan: no eligible persons found.'
1553
return False
1554
1555
# ok
1556
1557
# temporary maps from ids_person to other parameters
1558
1559
nm = np.max(ids_person_act)+1
1560
map_ids_plan = np.zeros(nm, dtype=np.int32)
1561
#ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy())
1562
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
1563
1564
# err
1565
map_times = np.zeros(nm, dtype=np.int32)
1566
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
1567
1568
# set start time to plans (important!)
1569
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
1570
1571
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
1572
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
1573
1574
# err
1575
map_ids_parking_from = np.zeros(nm, dtype=np.int32)
1576
map_are_fallback = np.zeros(nm, dtype=bool)
1577
ids_parking_from, are_fallback = parking.get_closest_parkings(virtualpop.ids_iauto[ids_person_act],
1578
ids_mode[iautos.ids_vtype[virtualpop.ids_iauto[ids_person_act]]],
1579
facilities.centroids[activities.ids_facility[ids_act_from]],
1580
dists_walk_max=virtualpop.dists_walk_max[ids_person_act],
1581
id_mode_fallback=self.id_mode_fallback,
1582
)
1583
#are_fallback = np.zeros(len(ids_person_act), dtype = bool)
1584
1585
if len(ids_parking_from) == 0:
1586
return False
1587
1588
# err
1589
1590
map_ids_parking_from[ids_person_act] = ids_parking_from
1591
map_are_fallback[ids_person_act] = are_fallback
1592
1593
n_plans = len(ids_person_act)
1594
print 'AutoStrategy.plan n_plans=', n_plans
1595
# print ' map_ids_parking_from[ids_person_act].shape',map_ids_parking_from[ids_person_act].shape
1596
# set initial activity
1597
# this is because the following steps start with travel
1598
# and set the next activity
1599
#names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
1600
# for id_plan
1601
1602
ind_act = 0
1603
1604
# make initial activity stage
1605
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
1606
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
1607
# this is the time when first activity starts
1608
# first activity is normally not simulated
1609
1610
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
1611
durations_act_from = activities.get_durations(ids_act_from)
1612
times_from = map_times[ids_person_act]-durations_act_from
1613
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
1614
1615
for id_plan,\
1616
time,\
1617
id_act_from,\
1618
name_acttype_from,\
1619
duration_act_from,\
1620
id_edge_from,\
1621
pos_edge_from \
1622
in zip(map_ids_plan[ids_person_act],
1623
times_from,
1624
ids_act_from,
1625
names_acttype_from,
1626
durations_act_from,
1627
ids_edge_from,
1628
poss_edge_from):
1629
1630
id_stage_act, time = activitystages.append_stage(
1631
id_plan,
1632
time,
1633
ids_activity=id_act_from,
1634
names_activitytype=name_acttype_from,
1635
durations=duration_act_from,
1636
ids_lane=edges.ids_lanes[id_edge_from][0],
1637
positions=pos_edge_from,
1638
)
1639
1640
# main loop while there are persons performing
1641
# an activity at index ind_act
1642
while len(ids_person_act) > 0:
1643
ids_plan = map_ids_plan[ids_person_act]
1644
ids_veh = virtualpop.ids_iauto[ids_person_act]
1645
1646
#ids_mode = vtypes.ids_mode[iautos.ids_vtype[ids_veh]]
1647
# print ids_veh
1648
#inds_pers = virtualpop.get_inds(ids_person)
1649
# self.persons.cols.mode_preferred[inds_pers]='private'
1650
1651
times_from = map_times[ids_person_act]
1652
1653
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
1654
durations_act_to = activities.get_durations(ids_act_to)
1655
1656
ids_fac_from = map_ids_fac_from[ids_person_act]
1657
ids_fac_to = activities.ids_facility[ids_act_to]
1658
1659
centroids_to = facilities.centroids[ids_fac_to]
1660
1661
# origin edge and position
1662
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
1663
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
1664
1665
# this method will find and occupy parking space
1666
ids_parking_from = map_ids_parking_from[ids_person_act]
1667
1668
# print ' ids_veh.shape',ids_veh.shape
1669
# print ' centroids_to.shape',centroids_to.shape
1670
ids_parking_to, are_fallback = parking.get_closest_parkings(ids_veh,
1671
ids_mode[iautos.ids_vtype[ids_veh]],
1672
centroids_to,
1673
dists_walk_max=virtualpop.dists_walk_max[ids_person_act],
1674
id_mode_fallback=self.id_mode_fallback,
1675
)
1676
1677
map_are_fallback[ids_person_act] |= are_fallback
1678
1679
ids_lane_parking_from = parking.ids_lane[ids_parking_from]
1680
ids_edge_parking_from = lanes.ids_edge[ids_lane_parking_from]
1681
poss_edge_parking_from = parking.positions[ids_parking_from]
1682
1683
# print ' ids_parking_to.shape',ids_parking_to.shape
1684
# print ' np.max(parking.get_ids()), np.max(ids_parking_to)',np.max(parking.get_ids()), np.max(ids_parking_to)
1685
ids_lane_parking_to = parking.ids_lane[ids_parking_to]
1686
ids_edge_parking_to = lanes.ids_edge[ids_lane_parking_to]
1687
poss_edge_parking_to = parking.positions[ids_parking_to]
1688
1689
# Fallback mode, if an auto can't run between origin and destination parkings, then the vehicle is changed with a taxy
1690
# print ' prepare routing'
1691
#fstar = edges.get_fstar(is_ignor_connections=False)
1692
#times_primary = edges.get_times(id_mode= self._id_mode_auto, is_check_lanes=True)
1693
1694
if self.id_mode_fallback is not None:
1695
ids_vtype_fallback, share_fallback = demand.vtypes.select_by_mode(self.id_mode_fallback, is_share=True)
1696
# print ' ids_vtype_fallback, share_fallback',ids_vtype_fallback, share_fallback
1697
1698
# for id_edge_orig, id_edge_dest, id_veh, i in zip(ids_edge_parking_from, ids_edge_parking_to, ids_veh, range(len(ids_veh))):
1699
# cost, route = routing.get_mincostroute_edge2edge(id_edge_orig,
1700
# id_edge_dest,
1701
# weights = times_primary,# mode dependent!
1702
# fstar=fstar
1703
# )
1704
# if route == []:
1705
# if self.id_mode_fallback != 1:
1706
# print 'fallback mode for vehicle %d of person %d'%(id_veh, virtualpop.get_iautos().ids_person[id_veh])
1707
# are_fallback[i] = True
1708
# virtualpop.get_iautos().ids_vtype[id_veh] = np.random.choice(id_vtype_mode[0], p = id_vtype_mode[1])
1709
# print ids_veh
1710
1711
# destination edge and position
1712
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
1713
poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to]
1714
1715
i = 0.0
1716
n_pers = len(ids_person_act)
1717
for id_person, id_mode, is_fallback, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_parking_from, pos_edge_parking_from, id_parking_from, id_parking_to, id_edge_parking_to, pos_edge_parking_to, id_edge_to, pos_edge_to\
1718
in zip(ids_person_act, ids_mode[iautos.ids_vtype[ids_veh]], map_are_fallback[ids_person_act], ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_parking_from, poss_edge_parking_from, ids_parking_from, ids_parking_to, ids_edge_parking_to, poss_edge_parking_to, ids_edge_to, poss_edge_to):
1719
if logger:
1720
logger.progress(i/n_pers*100)
1721
i += 1.0
1722
#plans.set_row(id_plan, ids_person = id_person, ids_strategy = self.get_id_strategy())
1723
1724
# start creating stages for activity
1725
id_stage_walk1, time = walkstages.append_stage(
1726
id_plan, time_from,
1727
id_edge_from=id_edge_from,
1728
position_edge_from=pos_edge_from,
1729
id_edge_to=id_edge_parking_from,
1730
position_edge_to=pos_edge_parking_from-1.5, # wait 1.5 m before nose of parked car
1731
)
1732
1733
print ' id_person,id_veh', id_person, id_veh
1734
# ride from car parking to road edge near activity
1735
id_stage_car, time, is_fallback = ridestages.append_stage(
1736
id_plan,
1737
id_mode,
1738
is_fallback,
1739
self.id_mode_fallback,
1740
time_start=time,
1741
id_veh=id_veh,
1742
# delay to be sure that person arrived!(workaround in combination with parking=False)
1743
time_init=time+30, # time_from,
1744
id_parking_from=id_parking_from,
1745
id_parking_to=id_parking_to,
1746
# TODO: here we could use id_edge_to as via edge to emulate search for parking
1747
)
1748
1749
if is_fallback & (self.id_mode_fallback is not None):
1750
# now we are sure fallback mode is needed
1751
# set a fallback vtype for this id_veh
1752
iautos.ids_vtype[id_veh] = np.random.choice(ids_vtype_fallback, p=share_fallback)
1753
map_are_fallback[id_person] = True
1754
1755
if id_stage_car > -1:
1756
# print ' car ride successful'
1757
id_stage_walk2, time = walkstages.append_stage(
1758
id_plan, time,
1759
id_edge_from=id_edge_parking_to,
1760
position_edge_from=pos_edge_parking_to-1.5, # ecessary?
1761
id_edge_to=id_edge_to,
1762
position_edge_to=pos_edge_to,
1763
)
1764
else:
1765
# print ' parking not connected or distance too short, modify first walk and go directly to activity'
1766
# print ' id_stage_walk1',id_stage_walk1,type(id_stage_walk1)
1767
# print ' id_edge_from',id_edge_from
1768
# print ' position_edge_from',position_edge_from
1769
# print ' id_edge_to',id_edge_to
1770
# print ' position_edge_to',position_edge_to
1771
1772
time = walkstages.modify_stage(
1773
id_stage_walk1, time_from,
1774
id_edge_from=id_edge_from,
1775
position_edge_from=pos_edge_from,
1776
id_edge_to=id_edge_to,
1777
position_edge_to=pos_edge_to,
1778
)
1779
1780
# store time estimation for this plan
1781
# note that these are the travel times, no activity time
1782
plans.times_est[id_plan] += time-time_from
1783
1784
# define current end time without last activity duration
1785
plans.times_end[id_plan] = time
1786
1787
# finally add activity and respective duration
1788
1789
id_stage_act, time = activitystages.append_stage(
1790
id_plan, time,
1791
ids_activity=id_act_to,
1792
names_activitytype=name_acttype_to,
1793
durations=duration_act_to,
1794
ids_lane=edges.ids_lanes[id_edge_to][0],
1795
positions=pos_edge_to,
1796
)
1797
1798
map_times[id_person] = time
1799
# return time
1800
##
1801
1802
# prepare next activity (not yet tested)
1803
map_ids_parking_from[ids_person_act] = ids_parking_to
1804
1805
# select persons and activities for next setp
1806
ind_act += 1
1807
ids_person_act, ids_act_from, ids_act_to\
1808
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
1809
# update timing with (random) activity duration!!
1810
1811
return True
1812
1813
1814
class BikeStrategy(StrategyMixin):
1815
def __init__(self, ident, parent=None,
1816
name='Bike strategy',
1817
info='With this strategy, the person uses his private bike as main transport mode.',
1818
**kwargs):
1819
1820
self._init_objman(ident, parent, name=name, info=info, **kwargs)
1821
attrsman = self.set_attrsman(cm.Attrsman(self))
1822
# specific init
1823
self._init_attributes(**kwargs)
1824
self._init_constants()
1825
1826
def _init_attributes(self, **kwargs):
1827
# print 'StrategyMixin._init_attributes'
1828
attrsman = self.get_attrsman()
1829
1830
self._init_attributes_strategy(**kwargs)
1831
self.n_iter_bikeacces_max = attrsman.add(cm.AttrConf('n_iter_bikeacces_max', kwargs.get('n_iter_bikeacces_max', 5),
1832
groupnames=['options'],
1833
perm='rw',
1834
name='Max. bike access search iterations',
1835
info='Max. number of iterations while searching an edge with bike access.',
1836
))
1837
1838
self.length_edge_min = attrsman.add(cm.AttrConf('length_edge_min', kwargs.get('length_edge_min', 20.0),
1839
groupnames=['options'],
1840
perm='rw',
1841
name='Min. edge length search',
1842
unit='m',
1843
info='Min. edge length when searching an edge with bike access.',
1844
))
1845
1846
self.utility_constant = attrsman.add(cm.AttrConf('utility_constant', kwargs.get('utility_constant', -0.5604),
1847
groupnames=['options'],
1848
perm='rw',
1849
name='Utility constant for bike strategy',
1850
info='Constant to calculate utility: U = Const + value_of_time*time_exec',
1851
))
1852
1853
def _init_constants(self):
1854
#virtualpop = self.get_virtualpop()
1855
#stagetables = virtualpop.get_stagetables()
1856
1857
#self._walkstages = stagetables.get_stagetable('walks')
1858
#self._ridestages = stagetables.get_stagetable('rides')
1859
#self._activitystages = stagetables.get_stagetable('activities')
1860
1861
#self._plans = virtualpop.get_plans()
1862
#
1863
# print 'AutoStrategy._init_constants'
1864
# print dir(self)
1865
# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])
1866
1867
modes = self.get_virtualpop().get_scenario().net.modes
1868
self._id_mode_ped = modes.get_id_mode('pedestrian')
1869
self._id_mode_bike = modes.get_id_mode('bicycle')
1870
self._id_mode_auto = modes.get_id_mode('passenger')
1871
self._id_mode_moto = modes.get_id_mode('motorcycle')
1872
self._edges = self.get_virtualpop().get_scenario().net.edges
1873
self.get_attrsman().do_not_save_attrs([
1874
'_id_mode_bike', '_id_mode_auto', '_id_mode_moto',
1875
'_id_mode_ped',
1876
'_edges'])
1877
1878
def get_utility_specific(self, id_plan):
1879
return self.utility_constant
1880
1881
def preevaluate(self, ids_person):
1882
"""
1883
Preevaluation strategies for person IDs in vector ids_person.
1884
1885
Returns a preevaluation vector with a preevaluation value
1886
for each person ID. The values of the preevaluation vector are as follows:
1887
-1 : Strategy cannot be applied
1888
0 : Stategy can be applied, but the preferred mode is not used
1889
1 : Stategy can be applied, and preferred mode is part of the strategy
1890
2 : Strategy uses predomunantly preferred mode
1891
1892
"""
1893
n_pers = len(ids_person)
1894
print 'BikeStrategy.preevaluate', n_pers, 'persons'
1895
persons = self.get_virtualpop()
1896
preeval = np.zeros(n_pers, dtype=np.int32)
1897
1898
# put -1 for persons without car access
1899
preeval[persons.ids_ibike[ids_person] == -1] = -1
1900
print ' persons having no bike', len(np.flatnonzero(persons.ids_ibike[ids_person] == -1))
1901
1902
# put 0 for persons with bike but with a different preferred mode
1903
preeval[(persons.ids_ibike[ids_person] > -1)
1904
& (persons.ids_mode_preferred[ids_person] != self._id_mode_bike)] = 0
1905
1906
print ' persons with bike but with a different preferred mode', len(np.flatnonzero((persons.ids_ibike[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] != self._id_mode_bike)))
1907
1908
# put 2 for persons with bike access and who prefer the bike
1909
preeval[(persons.ids_ibike[ids_person] > -1)
1910
& (persons.ids_mode_preferred[ids_person] == self._id_mode_bike)] = 2
1911
print ' persons with car access and who prefer the car', len(np.flatnonzero((persons.ids_ibike[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] == self._id_mode_bike)))
1912
1913
return preeval
1914
1915
def get_edge_bikeaccess(self, id_edge, is_search_backward=False, is_get_route=False, is_star=False, bstar=0, fstar=0, n_iter_bikeacces_max=None):
1916
# get firts edge allowing bikes and pedestrian, saving route, frontward or backward. You can include bstar or fstar:
1917
# check only connected links. You can obtain also the route.
1918
# print 'get_edge_bikeaccess',id_edge, is_search_backward,'id_sumo',self._edges.ids_sumo[id_edge]
1919
1920
if n_iter_bikeacces_max is None:
1921
n_iter_bikeacces_max = self.n_iter_bikeacces_max
1922
1923
id_mode = self._id_mode_bike
1924
id_mode_ped = self._id_mode_ped
1925
get_accesslevel = self._edges.get_accesslevel
1926
if is_star:
1927
if is_search_backward:
1928
get_next = bstar
1929
else:
1930
get_next = fstar
1931
else:
1932
if is_search_backward:
1933
get_next = self._edges.get_incoming
1934
else:
1935
get_next = self._edges.get_outgoing
1936
1937
edgelengths = self._edges.lengths
1938
#ids_tried = set()
1939
ids_current = [id_edge]
1940
id_bikeedge = -1
1941
pos = 0.0
1942
n = 0
1943
ids = [id_edge]
1944
coll_ids = [0]
1945
route = []
1946
while (id_bikeedge < 0) & (n < n_iter_bikeacces_max):
1947
n += 1
1948
1949
ids_new = []
1950
for id_edge_test, is_long_enough in zip(ids_current, edgelengths[ids_current] > self.length_edge_min):
1951
# print ' check id',id_edge_test, is_long_enough,get_accesslevel(id_edge_test, id_mode)
1952
if is_long_enough & (get_accesslevel(id_edge_test, id_mode) >= 0) & (get_accesslevel(id_edge_test, id_mode_ped) >= 0):
1953
id_bikeedge = id_edge_test
1954
1955
if is_get_route:
1956
if n == 1:
1957
route = []
1958
else:
1959
route.append(id_edge_test)
1960
if n > 2:
1961
route.append(coll_ids[ids.index(id_edge_test)])
1962
if n > 3:
1963
for n in range(n-3):
1964
route.append(coll_ids[ids.index(route[-1])])
1965
1966
if is_search_backward is not True:
1967
route.reverse()
1968
1969
# print ' found',id_bikeedge,self._edges.ids_sumo[id_bikeedge]
1970
break
1971
else:
1972
1973
if is_star:
1974
ids_new += get_next[id_edge_test]
1975
if is_get_route:
1976
ids += get_next[id_edge_test]
1977
for i in range(len(get_next[id_edge_test])):
1978
coll_ids.append(id_edge_test)
1979
1980
else:
1981
ids_new += get_next(id_edge_test)
1982
if is_get_route:
1983
ids += get_next(id_edge_test)
1984
for i in range(len(get_next(id_edge_test))):
1985
coll_ids += id_edge_test
1986
1987
ids_current = ids_new
1988
1989
if id_bikeedge > -1:
1990
if is_search_backward:
1991
pos = edgelengths[id_bikeedge]-0.5*self.length_edge_min
1992
else:
1993
pos = 0.5*self.length_edge_min
1994
1995
if id_bikeedge == -1:
1996
print 'WARNING in get_edge_bikeaccess no access for', id_edge, self._edges.ids_sumo[id_edge]
1997
1998
if is_get_route:
1999
return id_bikeedge, pos, route
2000
else:
2001
return id_bikeedge, pos
2002
2003
def plan_bikeride(self, id_plan, time_from, id_veh,
2004
id_edge_from, pos_edge_from,
2005
id_edge_to, pos_edge_to,
2006
dist_from_to, dist_walk_max,
2007
walkstages, ridestages):
2008
2009
# start creating stages
2010
id_stage_walk1 = -1
2011
id_stage_bike = -1
2012
2013
id_edge_from_bike, pos_from_bike = self.get_edge_bikeaccess(id_edge_from)
2014
id_edge_to_bike, pos_to_bike = self.get_edge_bikeaccess(id_edge_to, is_search_backward=True)
2015
2016
if (dist_from_to < dist_walk_max) | (id_edge_from_bike == -1) | (id_edge_to_bike == -1):
2017
# print ' go by foot because distance is too short or no bike access',dist_from_to,id_edge_from_bike,id_edge_to_bike
2018
id_stage_walk1, time = walkstages.append_stage(
2019
id_plan, time_from,
2020
id_edge_from=id_edge_from,
2021
position_edge_from=pos_edge_from,
2022
id_edge_to=id_edge_to,
2023
position_edge_to=pos_edge_to,
2024
)
2025
2026
else:
2027
# print ' try to take the bike',id_veh
2028
# print ' id_edge_from_bike',edges.ids_sumo[id_edge_from_bike],pos_from_bike
2029
# print ' id_edge_to_bike',edges.ids_sumo[id_edge_to_bike],pos_to_bike
2030
2031
if id_edge_from_bike != id_edge_from:
2032
# print ' must walk from origin to bikerack',time_from
2033
2034
id_stage_walk1, time = walkstages.append_stage(
2035
id_plan, time_from,
2036
id_edge_from=id_edge_from,
2037
position_edge_from=pos_edge_from,
2038
id_edge_to=id_edge_from_bike,
2039
position_edge_to=pos_from_bike,
2040
)
2041
2042
if id_edge_to_bike != id_edge_to:
2043
# print ' must cycle from bikerack to dest bike rack',time
2044
id_stage_bike, time = ridestages.append_stage(
2045
id_plan, time,
2046
id_veh=id_veh,
2047
# delay to be sure that person arrived!(workaround in combination with parking=False)
2048
time_init=time-10, # time_from,
2049
id_edge_from=id_edge_from_bike,
2050
position_edge_from=pos_from_bike,
2051
id_edge_to=id_edge_to_bike,
2052
position_edge_to=pos_to_bike,
2053
)
2054
if id_stage_bike > -1:
2055
# print ' must walk from dest bikerack to dest',time
2056
id_stage_walk2, time = walkstages.append_stage(
2057
id_plan, time,
2058
id_edge_from=id_edge_to_bike,
2059
position_edge_from=pos_to_bike,
2060
id_edge_to=id_edge_to,
2061
position_edge_to=pos_edge_to,
2062
)
2063
2064
else:
2065
# print ' cycle from bikerack to destination',time
2066
id_stage_bike, time = ridestages.append_stage(
2067
id_plan, time,
2068
id_veh=id_veh,
2069
# delay to be sure that person arrived!(workaround in combination with parking=False)
2070
time_init=time-10, # time_from,
2071
id_edge_from=id_edge_from_bike,
2072
position_edge_from=pos_from_bike,
2073
id_edge_to=id_edge_to,
2074
position_edge_to=pos_edge_to,
2075
)
2076
else:
2077
# print ' cycle directly from orign edge',time_from
2078
if id_edge_to_bike != id_edge_to:
2079
# print ' must cycle from origin to bikerack',time_from
2080
2081
#pos_to_bike = 0.1*edges.lengths[id_edge_to_bike]
2082
id_stage_bike, time = ridestages.append_stage(
2083
id_plan, time_from,
2084
id_veh=id_veh,
2085
# delay to be sure that person arrived!(workaround in combination with parking=False)
2086
time_init=time_from-10, # time_from,
2087
id_edge_from=id_edge_from,
2088
position_edge_from=pos_edge_from,
2089
id_edge_to=id_edge_to_bike,
2090
position_edge_to=pos_to_bike,
2091
)
2092
if id_stage_bike > -1:
2093
id_stage_walk2, time = walkstages.append_stage(
2094
id_plan, time,
2095
id_edge_from=id_edge_to_bike,
2096
position_edge_from=pos_to_bike,
2097
id_edge_to=id_edge_to,
2098
position_edge_to=pos_edge_to,
2099
)
2100
else:
2101
# print ' must cycle from origin to destination',time_from
2102
id_stage_bike, time = ridestages.append_stage(
2103
id_plan, time_from,
2104
id_veh=id_veh,
2105
# delay to be sure that person arrived!(workaround in combination with parking=False)
2106
time_init=time_from-10, # time_from,
2107
id_edge_from=id_edge_from,
2108
position_edge_from=pos_edge_from,
2109
id_edge_to=id_edge_to,
2110
position_edge_to=pos_edge_to,
2111
)
2112
2113
# here we should have created a bike ride
2114
# if not, for ehatever reason,
2115
# we walk from origin to destination
2116
if id_stage_bike == -1:
2117
# print ' walk because no ride stage has been planned',time_from
2118
if id_stage_walk1 == -1:
2119
# no walk stage has been planned
2120
id_stage_walk1, time = walkstages.append_stage(
2121
id_plan, time_from,
2122
id_edge_from=id_edge_from,
2123
position_edge_from=pos_edge_from,
2124
id_edge_to=id_edge_to,
2125
position_edge_to=pos_edge_to,
2126
)
2127
2128
elif time_from == time:
2129
# walking to bike has already been schedules,
2130
# but cycling failed. So walk the whole way
2131
time = walkstages.modify_stage(
2132
id_stage_walk1, time_from,
2133
id_edge_from=id_edge_from,
2134
position_edge_from=pos_edge_from,
2135
id_edge_to=id_edge_to,
2136
position_edge_to=pos_edge_to,
2137
)
2138
return time
2139
2140
def plan(self, ids_person, logger=None, **kwargs):
2141
"""
2142
Generates a plan for these person according to this strategie.
2143
Overriden by specific strategy.
2144
"""
2145
#make_plans_private(self, ids_person = None, mode = 'passenger')
2146
# routing necessary?
2147
virtualpop = self.get_virtualpop()
2148
plans = virtualpop.get_plans() # self._plans
2149
walkstages = plans.get_stagetable('walks')
2150
ridestages = plans.get_stagetable('bikerides')
2151
activitystages = plans.get_stagetable('activities')
2152
2153
activities = virtualpop.get_activities()
2154
activitytypes = virtualpop.get_demand().activitytypes
2155
landuse = virtualpop.get_landuse()
2156
facilities = landuse.facilities
2157
#parking = landuse.parking
2158
2159
scenario = virtualpop.get_scenario()
2160
edges = scenario.net.edges
2161
lanes = scenario.net.lanes
2162
modes = scenario.net.modes
2163
2164
#times_est_plan = plans.times_est
2165
2166
# here we can determine edge weights for different modes
2167
plans.prepare_stagetables(['walks', 'bikerides', 'activities'])
2168
2169
# get initial travel times for persons.
2170
# initial travel times depend on the initial activity
2171
2172
# landuse.parking.clear_booking()
2173
2174
ids_person_act, ids_act_from, ids_act_to\
2175
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
2176
2177
if len(ids_person_act) == 0:
2178
print 'WARNING in BikeStrategy.plan: no eligible persons found.'
2179
return False
2180
2181
# ok
2182
2183
# temporary maps from ids_person to other parameters
2184
nm = np.max(ids_person_act)+1
2185
map_ids_plan = np.zeros(nm, dtype=np.int32)
2186
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
2187
2188
map_times = np.zeros(nm, dtype=np.int32)
2189
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
2190
2191
# set start time to plans (important!)
2192
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
2193
2194
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
2195
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
2196
2197
#map_ids_parking_from = np.zeros(nm, dtype = np.int32)
2198
# ids_parking_from, inds_vehparking = parking.get_closest_parkings( virtualpop.ids_iauto[ids_person_act],
2199
# facilities.centroids[activities.ids_facility[ids_act_from]])
2200
# if len(ids_parking_from)==0:
2201
# return False
2202
2203
# err
2204
2205
#map_ids_parking_from[ids_person_act] = ids_parking_from
2206
2207
n_plans = len(ids_person_act)
2208
print 'BikeStrategy.plan n_plans=', n_plans
2209
# print ' map_ids_parking_from[ids_person_act].shape',map_ids_parking_from[ids_person_act].shape
2210
# set initial activity
2211
# this is because the following steps start with travel
2212
# and set the next activity
2213
#names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
2214
# for id_plan
2215
2216
ind_act = 0
2217
2218
# make initial activity stage
2219
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
2220
2221
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
2222
poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from)
2223
2224
# this is the time when first activity starts
2225
# first activity is normally not simulated
2226
2227
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
2228
durations_act_from = activities.get_durations(ids_act_from)
2229
times_from = map_times[ids_person_act]-durations_act_from
2230
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
2231
2232
# do initial stage
2233
# could be common to all strategies
2234
for id_plan,\
2235
time,\
2236
id_act_from,\
2237
name_acttype_from,\
2238
duration_act_from,\
2239
id_edge_from,\
2240
pos_edge_from \
2241
in zip(map_ids_plan[ids_person_act],
2242
times_from,
2243
ids_act_from,
2244
names_acttype_from,
2245
durations_act_from,
2246
ids_edge_from,
2247
poss_edge_from):
2248
2249
id_stage_act, time = activitystages.append_stage(
2250
id_plan, time,
2251
ids_activity=id_act_from,
2252
names_activitytype=name_acttype_from,
2253
durations=duration_act_from,
2254
ids_lane=edges.ids_lanes[id_edge_from][0],
2255
positions=pos_edge_from,
2256
)
2257
2258
# main loop while there are persons performing
2259
# an activity at index ind_act
2260
while len(ids_person_act) > 0:
2261
ids_plan = map_ids_plan[ids_person_act]
2262
ids_veh = virtualpop.ids_ibike[ids_person_act]
2263
dists_walk_max = virtualpop.dists_walk_max[ids_person_act]
2264
times_from = map_times[ids_person_act]
2265
2266
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
2267
durations_act_to = activities.get_durations(ids_act_to)
2268
2269
ids_fac_from = map_ids_fac_from[ids_person_act]
2270
ids_fac_to = activities.ids_facility[ids_act_to]
2271
2272
# origin edge and position
2273
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
2274
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
2275
poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from)
2276
2277
centroids_from = facilities.centroids[ids_fac_from]
2278
2279
# this method will find and occupy parking space
2280
#ids_parking_from = map_ids_parking_from[ids_person_act]
2281
2282
# print ' ids_veh.shape',ids_veh.shape
2283
# print ' centroids_to.shape',centroids_to.shape
2284
#ids_parking_to, inds_vehparking = parking.get_closest_parkings(ids_veh, centroids_to)
2285
2286
#ids_lane_parking_from = parking.ids_lane[ids_parking_from]
2287
#ids_edge_parking_from = lanes.ids_edge[ids_lane_parking_from]
2288
#poss_edge_parking_from = parking.positions[ids_parking_from]
2289
2290
# print ' ids_parking_to.shape',ids_parking_to.shape
2291
# print ' np.max(parking.get_ids()), np.max(ids_parking_to)',np.max(parking.get_ids()), np.max(ids_parking_to)
2292
#ids_lane_parking_to = parking.ids_lane[ids_parking_to]
2293
#ids_edge_parking_to = lanes.ids_edge[ids_lane_parking_to]
2294
#poss_edge_parking_to = parking.positions[ids_parking_to]
2295
2296
# destination edge and position
2297
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
2298
2299
poss_edge_to1 = facilities.positions_roadedge_closest[ids_fac_to]
2300
poss_edge_to = self.clip_positions(poss_edge_to1, ids_edge_to)
2301
centroids_to = facilities.centroids[ids_fac_to]
2302
2303
# debug poscorrection..OK
2304
# for id_edge, id_edge_sumo, length, pos_to1, pos in zip(ids_edge_to, edges.ids_sumo[ids_edge_to],edges.lengths[ids_edge_to],poss_edge_to1, poss_edge_to):
2305
# print ' ',id_edge, 'IDe%s'%id_edge_sumo, 'L=%.2fm'%length, '%.2fm'%pos_to1, '%.2fm'%pos
2306
2307
dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1))
2308
2309
i = 0.0
2310
n_pers = len(ids_person_act)
2311
for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, dist_from_to, dist_walk_max\
2312
in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, dists_from_to, dists_walk_max):
2313
if logger:
2314
logger.progress(i/n_pers*100)
2315
i += 1.0
2316
print 79*'*'
2317
print ' plan id_plan', id_plan, 'time_from', time_from, 'from', id_edge_from, pos_edge_from, 'to', id_edge_to, pos_edge_to
2318
print ' id_edge_from', edges.ids_sumo[id_edge_from], 'id_edge_to', edges.ids_sumo[id_edge_to]
2319
2320
time = self.plan_bikeride(id_plan, time_from, id_veh,
2321
id_edge_from, pos_edge_from,
2322
id_edge_to, pos_edge_to,
2323
dist_from_to, dist_walk_max,
2324
walkstages, ridestages)
2325
2326
################
2327
2328
# store time estimation for this plan
2329
# note that these are the travel times, no activity time
2330
plans.times_est[id_plan] += time-time_from
2331
2332
# define current end time without last activity duration
2333
plans.times_end[id_plan] = time
2334
2335
# finally add activity and respective duration
2336
2337
id_stage_act, time = activitystages.append_stage(
2338
id_plan, time,
2339
ids_activity=id_act_to,
2340
names_activitytype=name_acttype_to,
2341
durations=duration_act_to,
2342
ids_lane=edges.ids_lanes[id_edge_to][0],
2343
positions=pos_edge_to,
2344
)
2345
2346
map_times[id_person] = time
2347
# return time
2348
##
2349
2350
# select persons and activities for next setp
2351
ind_act += 1
2352
ids_person_act, ids_act_from, ids_act_to\
2353
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
2354
# update timing with (random) activity duration!!
2355
2356
return True
2357
2358
2359
class TaxiStrategy(StrategyMixin):
2360
def __init__(self, ident, parent=None,
2361
name='taxi strategy',
2362
info='With this strategy, the person uses his private taxi as main transport mode.',
2363
**kwargs):
2364
2365
self._init_objman(ident, parent, name=name, info=info, **kwargs)
2366
attrsman = self.set_attrsman(cm.Attrsman(self))
2367
# specific init
2368
self._init_attributes(**kwargs)
2369
self._init_constants()
2370
2371
def _init_attributes(self, **kwargs):
2372
# print 'StrategyMixin._init_attributes'
2373
attrsman = self.get_attrsman()
2374
2375
self._init_attributes_strategy(**kwargs)
2376
self.n_iter_acces_max = attrsman.add(cm.AttrConf('n_iter_acces_max', kwargs.get('n_iter_acces_max', 5),
2377
groupnames=['options'],
2378
perm='rw',
2379
name='Max. access search iterations',
2380
info='Max. number of iterations while searching an edge with taxi access.',
2381
))
2382
2383
self.length_edge_min = attrsman.add(cm.AttrConf('length_edge_min', kwargs.get('length_edge_min', 20.0),
2384
groupnames=['options'],
2385
perm='rw',
2386
name='Min. edge length search',
2387
unit='m',
2388
info='Min. edge length when searching an edge with taxi access.',
2389
))
2390
2391
self.utility_constant = attrsman.add(cm.AttrConf('utility_constant', kwargs.get('utility_constant', 0.0),
2392
groupnames=['options'],
2393
perm='rw',
2394
name='Utility constant for taxi strategy',
2395
info='Constant to calculate utility: U = Const + value_of_time*time_exec',
2396
))
2397
2398
def _init_constants(self):
2399
#virtualpop = self.get_virtualpop()
2400
#stagetables = virtualpop.get_stagetables()
2401
2402
#self._walkstages = stagetables.get_stagetable('walks')
2403
#self._ridestages = stagetables.get_stagetable('rides')
2404
#self._activitystages = stagetables.get_stagetable('activities')
2405
2406
#self._plans = virtualpop.get_plans()
2407
#
2408
# print 'AutoStrategy._init_constants'
2409
# print dir(self)
2410
# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])
2411
2412
modes = self.get_virtualpop().get_scenario().net.modes
2413
self._id_mode_ped = modes.get_id_mode('pedestrian')
2414
#self._id_mode_bike = modes.get_id_mode('bicycle')
2415
#self._id_mode_auto = modes.get_id_mode('passenger')
2416
self._id_mode_taxi = modes.get_id_mode('taxi')
2417
self._edges = self.get_virtualpop().get_scenario().net.edges
2418
self.get_attrsman().do_not_save_attrs([
2419
'_id_mode_ped', '_id_mode_taxi',
2420
'_edges'])
2421
2422
def get_utility_specific(self, id_plan):
2423
return self.utility_constant
2424
2425
def preevaluate(self, ids_person):
2426
"""
2427
Preevaluation strategies for person IDs in vector ids_person.
2428
2429
Returns a preevaluation vector with a preevaluation value
2430
for each person ID. The values of the preevaluation vector are as follows:
2431
-1 : Strategy cannot be applied
2432
0 : Stategy can be applied, but the preferred mode is not used
2433
1 : Stategy can be applied, and preferred mode is part of the strategy
2434
2 : Strategy uses predomunantly preferred mode
2435
2436
"""
2437
n_pers = len(ids_person)
2438
persons = self.get_virtualpop()
2439
preeval = np.zeros(n_pers, dtype=np.int32)
2440
2441
# TODO: here we could exclude by age or distance facilities-stops
2442
2443
# put 0 for persons whose preference is not public transport
2444
preeval[persons.ids_mode_preferred[ids_person] != self._id_mode_taxi] = 0
2445
2446
# put 2 for persons with car access and who prefer cars
2447
preeval[persons.ids_mode_preferred[ids_person] == self._id_mode_taxi] = 2
2448
2449
print ' TaxiStrategy.preevaluate', len(np.flatnonzero(preeval))
2450
return preeval
2451
2452
def get_edge_access(self, id_edge, is_search_backward=False, is_get_route=False, is_star=False, bstar=0, fstar=0, n_iter_acces_max=None):
2453
# get firts edge allowing bikes and pedestrian, saving route, frontward or backward. You can include bstar or fstar:
2454
# check only connected links. You can obtain also the route.
2455
# print 'get_edge_bikeaccess',id_edge, is_search_backward,'id_sumo',self._edges.ids_sumo[id_edge]
2456
print 'get_edge_access id_edge', id_edge, 'is_search_backward', is_search_backward, 'n_iter_acces_max', self.n_iter_acces_max
2457
if n_iter_acces_max is None:
2458
n_iter_acces_max = self.n_iter_acces_max
2459
2460
id_mode = self._id_mode_taxi
2461
id_mode_ped = self._id_mode_ped
2462
get_accesslevel = self._edges.get_accesslevel
2463
if is_star:
2464
if is_search_backward:
2465
get_next = bstar
2466
else:
2467
get_next = fstar
2468
else:
2469
if is_search_backward:
2470
get_next = self._edges.get_incoming
2471
else:
2472
get_next = self._edges.get_outgoing
2473
2474
edgelengths = self._edges.lengths
2475
#ids_tried = set()
2476
ids_current = [id_edge]
2477
id_modeedge = -1
2478
pos = 0.0
2479
n = 0
2480
ids = [id_edge]
2481
coll_ids = [0]
2482
route = []
2483
print 'start id_modeedge', id_modeedge, 'n', n, 'n_iter_acces_max', n_iter_acces_max, (id_modeedge < 0), (n < n_iter_acces_max)
2484
2485
while (id_modeedge < 0) & (n < n_iter_acces_max):
2486
print ' while id_modeedge', id_modeedge, 'n', n
2487
n += 1
2488
2489
ids_new = []
2490
for id_edge_test, is_long_enough in zip(ids_current, edgelengths[ids_current] > self.length_edge_min):
2491
print ' check id', id_edge_test, is_long_enough, 'taxi access', get_accesslevel(id_edge_test, id_mode), 'ped access', get_accesslevel(id_edge_test, id_mode_ped)
2492
if is_long_enough & (get_accesslevel(id_edge_test, id_mode) >= 0) & (get_accesslevel(id_edge_test, id_mode_ped) >= 0):
2493
id_modeedge = id_edge_test
2494
2495
if is_get_route:
2496
if n == 1:
2497
route = []
2498
else:
2499
route.append(id_edge_test)
2500
if n > 2:
2501
route.append(coll_ids[ids.index(id_edge_test)])
2502
if n > 3:
2503
for n in range(n-3):
2504
route.append(coll_ids[ids.index(route[-1])])
2505
if is_search_backward is not True:
2506
route.reverse()
2507
2508
print ' found', id_modeedge, self._edges.ids_sumo[id_modeedge]
2509
break
2510
else:
2511
2512
if is_star:
2513
ids_new += get_next[id_edge_test]
2514
if is_get_route:
2515
ids += get_next[id_edge_test]
2516
for i in range(len(get_next[id_edge_test])):
2517
coll_ids.append(id_edge_test)
2518
2519
else:
2520
ids_new += get_next(id_edge_test)
2521
if is_get_route:
2522
ids += get_next(id_edge_test)
2523
for i in range(len(get_next(id_edge_test))):
2524
coll_ids += id_edge_test
2525
2526
ids_current = ids_new
2527
2528
if id_modeedge > -1:
2529
if is_search_backward:
2530
pos = edgelengths[id_modeedge]-0.5*self.length_edge_min
2531
else:
2532
pos = 0.5*self.length_edge_min
2533
2534
if id_modeedge == -1:
2535
print 'WARNING in TaxiStrategy.get_edge_access no access at id_edge', id_edge, self._edges.ids_sumo[id_edge]
2536
2537
if is_get_route:
2538
return id_modeedge, pos, route
2539
else:
2540
return id_modeedge, pos
2541
2542
def plan_taxiride(self, id_plan, time_from, id_veh,
2543
id_edge_from, pos_edge_from,
2544
id_edge_to, pos_edge_to,
2545
dist_from_to, dist_walk_max,
2546
walkstages, ridestages):
2547
2548
# start creating stages
2549
id_stage_walk1 = -1
2550
id_stage_moto = -1
2551
2552
id_edge_from_taxi, pos_from_taxi = self.get_edge_access(id_edge_from)
2553
id_edge_to_taxi, pos_to_taxi = self.get_edge_access(id_edge_to, is_search_backward=True)
2554
2555
if (dist_from_to < dist_walk_max) | (id_edge_from_taxi == -1) | (id_edge_to_taxi == -1):
2556
print ' go by foot because distance is too short or no taxi access', dist_from_to, id_edge_from_taxi, id_edge_to_taxi
2557
id_stage_walk1, time = walkstages.append_stage(
2558
id_plan, time_from,
2559
id_edge_from=id_edge_from,
2560
position_edge_from=pos_edge_from,
2561
id_edge_to=id_edge_to,
2562
position_edge_to=pos_edge_to,
2563
)
2564
2565
else:
2566
print ' try to take the taxi'
2567
# print ' id_edge_from_taxi',edges.ids_sumo[id_edge_from_taxi],pos_from_taxi
2568
# print ' id_edge_to_taxi',edges.ids_sumo[id_edge_to_taxi],pos_to_taxi
2569
2570
if id_edge_from_taxi != id_edge_from:
2571
print ' must walk from origin to taxi accessible edge, time_from', time_from
2572
# walk to taxi edge
2573
id_stage_walk1, time = walkstages.append_stage(
2574
id_plan, time_from,
2575
id_edge_from=id_edge_from,
2576
position_edge_from=pos_edge_from,
2577
id_edge_to=id_edge_from_taxi,
2578
position_edge_to=pos_from_taxi,
2579
)
2580
2581
if id_edge_to_taxi != id_edge_to:
2582
print ' must walk from taxi accessible edge to dest, time_from', time
2583
# take taxi
2584
id_stage_taxi, time = ridestages.append_stage(
2585
id_plan, time,
2586
id_veh=id_veh,
2587
# could book taxi here in advance?
2588
time_init=time-10, # needed with taxi??
2589
id_edge_from=id_edge_from_taxi,
2590
position_edge_from=pos_from_taxi,
2591
id_edge_to=id_edge_to_taxi,
2592
position_edge_to=pos_to_taxi,
2593
)
2594
if id_stage_taxi > -1:
2595
# walk to dest
2596
id_stage_walk2, time = walkstages.append_stage(
2597
id_plan, time,
2598
id_edge_from=id_edge_to_taxi,
2599
position_edge_from=pos_to_taxi,
2600
id_edge_to=id_edge_to,
2601
position_edge_to=pos_edge_to,
2602
)
2603
2604
else:
2605
print ' ride taxi from taxi edge to destination', time
2606
# take taxi
2607
id_stage_taxi, time = ridestages.append_stage(
2608
id_plan, time,
2609
id_veh=id_veh,
2610
# could book taxi here in advance?
2611
time_init=time, # time_from,
2612
id_edge_from=id_edge_from_taxi,
2613
position_edge_from=pos_from_taxi,
2614
id_edge_to=id_edge_to,
2615
position_edge_to=pos_edge_to,
2616
)
2617
else:
2618
print ' take taxi directly from edge of origin', time_from
2619
if id_edge_to_taxi != id_edge_to:
2620
print ' must walk from taxi accessible destination to destination', time_from
2621
2622
id_stage_taxi, time = ridestages.append_stage(
2623
id_plan, time_from,
2624
id_veh=id_veh,
2625
# could book taxi here in advance?
2626
time_init=time_from, # time_from,
2627
id_edge_from=id_edge_from,
2628
position_edge_from=pos_edge_from,
2629
id_edge_to=id_edge_to_taxi,
2630
position_edge_to=pos_to_taxi,
2631
)
2632
if id_stage_taxi > -1:
2633
id_stage_walk2, time = walkstages.append_stage(
2634
id_plan, time,
2635
id_edge_from=id_edge_to_taxi,
2636
position_edge_from=pos_to_taxi,
2637
id_edge_to=id_edge_to,
2638
position_edge_to=pos_edge_to,
2639
)
2640
else:
2641
print ' take taxi directly from origin to destination', time_from
2642
id_stage_taxi, time = ridestages.append_stage(
2643
id_plan, time_from,
2644
id_veh=id_veh,
2645
# could book taxi here in advance?
2646
time_init=time_from, # time_from,
2647
id_edge_from=id_edge_from,
2648
position_edge_from=pos_edge_from,
2649
id_edge_to=id_edge_to,
2650
position_edge_to=pos_edge_to,
2651
)
2652
2653
# here we should have created a taxi ride
2654
# if not, for whatever reason,
2655
# we walk from origin to destination
2656
if id_stage_taxi == -1:
2657
print ' walk because no ride stage has been planned', time_from
2658
if id_stage_walk1 == -1:
2659
# no walk stage has been planned
2660
id_stage_walk1, time = walkstages.append_stage(
2661
id_plan, time_from,
2662
id_edge_from=id_edge_from,
2663
position_edge_from=pos_edge_from,
2664
id_edge_to=id_edge_to,
2665
position_edge_to=pos_edge_to,
2666
)
2667
2668
elif time_from == time:
2669
# walking to taxi has already been schedules,
2670
# but taxi ride failed. So walk the whole way
2671
time = walkstages.modify_stage(
2672
id_stage_walk1, time_from,
2673
id_edge_from=id_edge_from,
2674
position_edge_from=pos_edge_from,
2675
id_edge_to=id_edge_to,
2676
position_edge_to=pos_edge_to,
2677
)
2678
return time
2679
2680
def plan(self, ids_person, logger=None):
2681
"""
2682
Generates a plan for these person according to this strategie.
2683
Overriden by specific strategy.
2684
"""
2685
#make_plans_private(self, ids_person = None, mode = 'passenger')
2686
# routing necessary?
2687
virtualpop = self.get_virtualpop()
2688
plans = virtualpop.get_plans() # self._plans
2689
walkstages = plans.get_stagetable('walks')
2690
ridestages = plans.get_stagetable('taxirides')
2691
activitystages = plans.get_stagetable('activities')
2692
2693
activities = virtualpop.get_activities()
2694
activitytypes = virtualpop.get_demand().activitytypes
2695
landuse = virtualpop.get_landuse()
2696
facilities = landuse.facilities
2697
#parking = landuse.parking
2698
2699
scenario = virtualpop.get_scenario()
2700
edges = scenario.net.edges
2701
lanes = scenario.net.lanes
2702
modes = scenario.net.modes
2703
2704
#times_est_plan = plans.times_est
2705
2706
# here we can determine edge weights for different modes
2707
plans.prepare_stagetables(['walks', 'taxirides', 'activities'])
2708
2709
# get initial travel times for persons.
2710
# initial travel times depend on the initial activity
2711
2712
# landuse.parking.clear_booking()
2713
2714
ids_person_act, ids_act_from, ids_act_to\
2715
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
2716
2717
if len(ids_person_act) == 0:
2718
print 'WARNING in TaxiStrategy.plan: no eligible persons found.'
2719
return False
2720
2721
# ok
2722
2723
# temporary maps from ids_person to other parameters
2724
nm = np.max(ids_person_act)+1
2725
map_ids_plan = np.zeros(nm, dtype=np.int32)
2726
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
2727
2728
map_times = np.zeros(nm, dtype=np.int32)
2729
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
2730
2731
# set start time to plans (important!)
2732
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
2733
2734
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
2735
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
2736
2737
#map_ids_parking_from = np.zeros(nm, dtype = np.int32)
2738
# ids_parking_from, inds_vehparking = parking.get_closest_parkings( virtualpop.ids_iauto[ids_person_act],
2739
# facilities.centroids[activities.ids_facility[ids_act_from]])
2740
# if len(ids_parking_from)==0:
2741
# return False
2742
2743
# err
2744
2745
#map_ids_parking_from[ids_person_act] = ids_parking_from
2746
2747
n_plans = len(ids_person_act)
2748
print 'TaxiStrategy.plan n_plans=', n_plans
2749
# print ' map_ids_parking_from[ids_person_act].shape',map_ids_parking_from[ids_person_act].shape
2750
# set initial activity
2751
# this is because the following steps start with travel
2752
# and set the next activity
2753
#names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
2754
# for id_plan
2755
2756
ind_act = 0
2757
2758
# make initial activity stage
2759
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
2760
2761
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
2762
poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from)
2763
2764
# this is the time when first activity starts
2765
# first activity is normally not simulated
2766
2767
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
2768
durations_act_from = activities.get_durations(ids_act_from)
2769
times_from = map_times[ids_person_act]-durations_act_from
2770
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
2771
2772
# do initial stage
2773
# could be common to all strategies
2774
for id_plan,\
2775
time,\
2776
id_act_from,\
2777
name_acttype_from,\
2778
duration_act_from,\
2779
id_edge_from,\
2780
pos_edge_from \
2781
in zip(map_ids_plan[ids_person_act],
2782
times_from,
2783
ids_act_from,
2784
names_acttype_from,
2785
durations_act_from,
2786
ids_edge_from,
2787
poss_edge_from):
2788
2789
id_stage_act, time = activitystages.append_stage(
2790
id_plan, time,
2791
ids_activity=id_act_from,
2792
names_activitytype=name_acttype_from,
2793
durations=duration_act_from,
2794
ids_lane=edges.ids_lanes[id_edge_from][0],
2795
positions=pos_edge_from,
2796
)
2797
2798
# main loop while there are persons performing
2799
# an activity at index ind_act
2800
while len(ids_person_act) > 0:
2801
ids_plan = map_ids_plan[ids_person_act]
2802
ids_veh = virtualpop.ids_imoto[ids_person_act]
2803
dists_walk_max = virtualpop.dists_walk_max[ids_person_act]
2804
times_from = map_times[ids_person_act]
2805
2806
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
2807
durations_act_to = activities.get_durations(ids_act_to)
2808
2809
ids_fac_from = map_ids_fac_from[ids_person_act]
2810
ids_fac_to = activities.ids_facility[ids_act_to]
2811
2812
# origin edge and position
2813
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
2814
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
2815
poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from)
2816
2817
centroids_from = facilities.centroids[ids_fac_from]
2818
2819
# destination edge and position
2820
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
2821
2822
poss_edge_to1 = facilities.positions_roadedge_closest[ids_fac_to]
2823
poss_edge_to = self.clip_positions(poss_edge_to1, ids_edge_to)
2824
centroids_to = facilities.centroids[ids_fac_to]
2825
2826
dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1))
2827
2828
i = 0.0
2829
n_pers = len(ids_person_act)
2830
for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, dist_from_to, dist_walk_max\
2831
in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, dists_from_to, dists_walk_max):
2832
if logger:
2833
logger.progress(i/n_pers*100)
2834
i += 1.0
2835
print 79*'*'
2836
print ' plan id_plan', id_plan, 'time_from', time_from, 'from', id_edge_from, pos_edge_from, 'to', id_edge_to, pos_edge_to
2837
print ' id_edge_from', edges.ids_sumo[id_edge_from], 'id_edge_to', edges.ids_sumo[id_edge_to]
2838
2839
time = self.plan_taxiride(id_plan, time_from, id_veh,
2840
id_edge_from, pos_edge_from,
2841
id_edge_to, pos_edge_to,
2842
dist_from_to, dist_walk_max,
2843
walkstages, ridestages)
2844
2845
################
2846
2847
# store time estimation for this plan
2848
# note that these are the travel times, no activity time
2849
plans.times_est[id_plan] += time-time_from
2850
2851
# define current end time without last activity duration
2852
plans.times_end[id_plan] = time
2853
2854
# finally add activity and respective duration
2855
2856
id_stage_act, time = activitystages.append_stage(
2857
id_plan, time,
2858
ids_activity=id_act_to,
2859
names_activitytype=name_acttype_to,
2860
durations=duration_act_to,
2861
ids_lane=edges.ids_lanes[id_edge_to][0],
2862
positions=pos_edge_to,
2863
)
2864
2865
map_times[id_person] = time
2866
# return time
2867
##
2868
2869
# select persons and activities for next setp
2870
ind_act += 1
2871
ids_person_act, ids_act_from, ids_act_to\
2872
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
2873
# update timing with (random) activity duration!!
2874
2875
return True
2876
2877
2878
class MotorcycleStrategy(StrategyMixin):
2879
def __init__(self, ident, parent=None,
2880
name='motorcycle strategy',
2881
info='With this strategy, the person uses his private motorcycle as main transport mode.',
2882
**kwargs):
2883
2884
self._init_objman(ident, parent, name=name, info=info, **kwargs)
2885
attrsman = self.set_attrsman(cm.Attrsman(self))
2886
# specific init
2887
self._init_attributes(**kwargs)
2888
self._init_constants()
2889
2890
def _init_attributes(self, **kwargs):
2891
# print 'StrategyMixin._init_attributes'
2892
attrsman = self.get_attrsman()
2893
2894
self._init_attributes_strategy(**kwargs)
2895
self.n_iter_motoacces_max = attrsman.add(cm.AttrConf('n_iter_motoacces_max', kwargs.get('n_iter_motoacces_max', 5),
2896
groupnames=['options'],
2897
perm='rw',
2898
name='Max. motorcycle access search iterations',
2899
info='Max. number of iterations while searching an edge with motorcycle access.',
2900
))
2901
2902
self.length_edge_min = attrsman.add(cm.AttrConf('length_edge_min', kwargs.get('length_edge_min', 20.0),
2903
groupnames=['options'],
2904
perm='rw',
2905
name='Min. edge length search',
2906
unit='m',
2907
info='Min. edge length when searching an edge with motorcycle access.',
2908
))
2909
2910
self.utility_constant = attrsman.add(cm.AttrConf('utility_constant', kwargs.get('utility_constant', -0.0161),
2911
groupnames=['options'],
2912
perm='rw',
2913
name='Utility constant for moto strategy',
2914
info='Constant to calculate utility: U = Const + value_of_time*time_exec',
2915
))
2916
2917
def _init_constants(self):
2918
#virtualpop = self.get_virtualpop()
2919
#stagetables = virtualpop.get_stagetables()
2920
2921
#self._walkstages = stagetables.get_stagetable('walks')
2922
#self._ridestages = stagetables.get_stagetable('rides')
2923
#self._activitystages = stagetables.get_stagetable('activities')
2924
2925
#self._plans = virtualpop.get_plans()
2926
#
2927
# print 'AutoStrategy._init_constants'
2928
# print dir(self)
2929
# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])
2930
2931
modes = self.get_virtualpop().get_scenario().net.modes
2932
self._id_mode_ped = modes.get_id_mode('pedestrian')
2933
self._id_mode_bike = modes.get_id_mode('bicycle')
2934
self._id_mode_auto = modes.get_id_mode('passenger')
2935
self._id_mode_moto = modes.get_id_mode('motorcycle')
2936
self._edges = self.get_virtualpop().get_scenario().net.edges
2937
self.get_attrsman().do_not_save_attrs([
2938
'_id_mode_bike', '_id_mode_auto', '_id_mode_moto',
2939
'_id_mode_ped',
2940
'_edges'])
2941
2942
def get_utility_specific(self, id_plan):
2943
return self.utility_constant
2944
2945
def preevaluate(self, ids_person):
2946
"""
2947
Preevaluation strategies for person IDs in vector ids_person.
2948
2949
Returns a preevaluation vector with a preevaluation value
2950
for each person ID. The values of the preevaluation vector are as follows:
2951
-1 : Strategy cannot be applied
2952
0 : Stategy can be applied, but the preferred mode is not used
2953
1 : Stategy can be applied, and preferred mode is part of the strategy
2954
2 : Strategy uses predomunantly preferred mode
2955
2956
"""
2957
n_pers = len(ids_person)
2958
print 'MotorcycleStrategy.preevaluate', n_pers, 'persons'
2959
persons = self.get_virtualpop()
2960
preeval = np.zeros(n_pers, dtype=np.int32)
2961
2962
# put -1 for persons without motorcycle access
2963
preeval[persons.ids_imoto[ids_person] == -1] = -1
2964
print ' persons having no motorcycle', len(np.flatnonzero(persons.ids_imoto[ids_person] == -1))
2965
2966
# put 0 for persons with motorcycle but with a different preferred mode
2967
preeval[(persons.ids_imoto[ids_person] > -1)
2968
& (persons.ids_mode_preferred[ids_person] != self._id_mode_moto)] = 0
2969
2970
print ' persons with motorcycle but with a different preferred mode', len(np.flatnonzero((persons.ids_imoto[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] != self._id_mode_moto)))
2971
2972
# put 2 for persons with motorcycle access and who prefer the car
2973
preeval[(persons.ids_imoto[ids_person] > -1)
2974
& (persons.ids_mode_preferred[ids_person] == self._id_mode_moto)] = 2
2975
print ' persons with motorcycle access and who prefer the car', len(np.flatnonzero((persons.ids_imoto[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] == self._id_mode_moto)))
2976
2977
return preeval
2978
2979
def get_edge_motoaccess(self, id_edge, is_search_backward=False, is_get_route=False, is_star=False, bstar=0, fstar=0, n_iter_motoacces_max=None):
2980
# get firts edge allowing bikes and pedestrian, saving route, frontward or backward. You can include bstar or fstar:
2981
# check only connected links. You can obtain also the route.
2982
# print 'get_edge_bikeaccess',id_edge, is_search_backward,'id_sumo',self._edges.ids_sumo[id_edge]
2983
2984
if n_iter_motoacces_max is None:
2985
n_iter_motoacces_max = self.n_iter_motoacces_max
2986
2987
id_mode = self._id_mode_moto
2988
id_mode_ped = self._id_mode_ped
2989
get_accesslevel = self._edges.get_accesslevel
2990
if is_star:
2991
if is_search_backward:
2992
get_next = bstar
2993
else:
2994
get_next = fstar
2995
else:
2996
if is_search_backward:
2997
get_next = self._edges.get_incoming
2998
else:
2999
get_next = self._edges.get_outgoing
3000
3001
edgelengths = self._edges.lengths
3002
#ids_tried = set()
3003
ids_current = [id_edge]
3004
id_motoedge = -1
3005
pos = 0.0
3006
n = 0
3007
ids = [id_edge]
3008
coll_ids = [0]
3009
route = []
3010
while (id_motoedge < 0) & (n < n_iter_motoacces_max):
3011
n += 1
3012
3013
ids_new = []
3014
for id_edge_test, is_long_enough in zip(ids_current, edgelengths[ids_current] > self.length_edge_min):
3015
# print ' check id',id_edge_test, is_long_enough,get_accesslevel(id_edge_test, id_mode)
3016
if is_long_enough & (get_accesslevel(id_edge_test, id_mode) >= 0) & (get_accesslevel(id_edge_test, id_mode_ped) >= 0):
3017
id_motoedge = id_edge_test
3018
3019
if is_get_route:
3020
if n == 1:
3021
route = []
3022
else:
3023
route.append(id_edge_test)
3024
if n > 2:
3025
route.append(coll_ids[ids.index(id_edge_test)])
3026
if n > 3:
3027
for n in range(n-3):
3028
route.append(coll_ids[ids.index(route[-1])])
3029
if is_search_backward is not True:
3030
route.reverse()
3031
3032
# print ' found',id_motoedge,self._edges.ids_sumo[id_motoedge]
3033
break
3034
else:
3035
3036
if is_star:
3037
ids_new += get_next[id_edge_test]
3038
if is_get_route:
3039
ids += get_next[id_edge_test]
3040
for i in range(len(get_next[id_edge_test])):
3041
coll_ids.append(id_edge_test)
3042
3043
else:
3044
ids_new += get_next(id_edge_test)
3045
if is_get_route:
3046
ids += get_next(id_edge_test)
3047
for i in range(len(get_next(id_edge_test))):
3048
coll_ids += id_edge_test
3049
3050
ids_current = ids_new
3051
3052
if id_motoedge > -1:
3053
if is_search_backward:
3054
pos = edgelengths[id_motoedge]-0.5*self.length_edge_min
3055
else:
3056
pos = 0.5*self.length_edge_min
3057
3058
if id_motoedge == -1:
3059
print 'WARNING in get_edge_motoaccess no access for', id_edge, self._edges.ids_sumo[id_edge]
3060
3061
if is_get_route:
3062
return id_motoedge, pos, route
3063
else:
3064
return id_motoedge, pos
3065
3066
def plan_motoride(self, id_plan, time_from, id_veh,
3067
id_edge_from, pos_edge_from,
3068
id_edge_to, pos_edge_to,
3069
dist_from_to, dist_walk_max,
3070
walkstages, ridestages):
3071
3072
# start creating stages
3073
id_stage_walk1 = -1
3074
id_stage_moto = -1
3075
3076
id_edge_from_moto, pos_from_moto = self.get_edge_motoaccess(id_edge_from)
3077
id_edge_to_moto, pos_to_moto = self.get_edge_motoaccess(id_edge_to, is_search_backward=True)
3078
3079
if (dist_from_to < dist_walk_max) | (id_edge_from_moto == -1) | (id_edge_to_moto == -1):
3080
# print ' go by foot because distance is too short or no moto access',dist_from_to,id_edge_from_moto,id_edge_to_moto
3081
id_stage_walk1, time = walkstages.append_stage(
3082
id_plan, time_from,
3083
id_edge_from=id_edge_from,
3084
position_edge_from=pos_edge_from,
3085
id_edge_to=id_edge_to,
3086
position_edge_to=pos_edge_to,
3087
)
3088
3089
else:
3090
# print ' try to take the moto',id_veh
3091
# print ' id_edge_from_moto',edges.ids_sumo[id_edge_from_moto],pos_from_moto
3092
# print ' id_edge_to_moto',edges.ids_sumo[id_edge_to_moto],pos_to_moto
3093
3094
if id_edge_from_moto != id_edge_from:
3095
# print ' must walk from origin to motorack',time_from
3096
3097
id_stage_walk1, time = walkstages.append_stage(
3098
id_plan, time_from,
3099
id_edge_from=id_edge_from,
3100
position_edge_from=pos_edge_from,
3101
id_edge_to=id_edge_from_moto,
3102
position_edge_to=pos_from_moto,
3103
)
3104
3105
if id_edge_to_moto != id_edge_to:
3106
# print ' must ride from motorack to dest motorack',time
3107
id_stage_moto, time = ridestages.append_stage(
3108
id_plan, time,
3109
id_veh=id_veh,
3110
# delay to be sure that person arrived!(workaround in combination with parking=False)
3111
time_init=time-10, # time_from,
3112
id_edge_from=id_edge_from_moto,
3113
position_edge_from=pos_from_moto,
3114
id_edge_to=id_edge_to_moto,
3115
position_edge_to=pos_to_moto,
3116
)
3117
if id_stage_moto > -1:
3118
# print ' must walk from dest motorack to dest',time
3119
id_stage_walk2, time = walkstages.append_stage(
3120
id_plan, time,
3121
id_edge_from=id_edge_to_moto,
3122
position_edge_from=pos_to_moto,
3123
id_edge_to=id_edge_to,
3124
position_edge_to=pos_edge_to,
3125
)
3126
3127
else:
3128
# print ' ride from motorack to destination',time
3129
id_stage_moto, time = ridestages.append_stage(
3130
id_plan, time,
3131
id_veh=id_veh,
3132
# delay to be sure that person arrived!(workaround in combination with parking=False)
3133
time_init=time-10, # time_from,
3134
id_edge_from=id_edge_from_moto,
3135
position_edge_from=pos_from_moto,
3136
id_edge_to=id_edge_to,
3137
position_edge_to=pos_edge_to,
3138
)
3139
else:
3140
# print ' cycle directly from orign edge',time_from
3141
if id_edge_to_moto != id_edge_to:
3142
# print ' must ride from origin to motorack',time_from
3143
3144
#pos_to_bike = 0.1*edges.lengths[id_edge_to_bike]
3145
id_stage_moto, time = ridestages.append_stage(
3146
id_plan, time_from,
3147
id_veh=id_veh,
3148
# delay to be sure that person arrived!(workaround in combination with parking=False)
3149
time_init=time_from-10, # time_from,
3150
id_edge_from=id_edge_from,
3151
position_edge_from=pos_edge_from,
3152
id_edge_to=id_edge_to_moto,
3153
position_edge_to=pos_to_moto,
3154
)
3155
if id_stage_moto > -1:
3156
id_stage_walk2, time = walkstages.append_stage(
3157
id_plan, time,
3158
id_edge_from=id_edge_to_moto,
3159
position_edge_from=pos_to_moto,
3160
id_edge_to=id_edge_to,
3161
position_edge_to=pos_edge_to,
3162
)
3163
else:
3164
# print ' must ride from origin to destination',time_from
3165
id_stage_moto, time = ridestages.append_stage(
3166
id_plan, time_from,
3167
id_veh=id_veh,
3168
# delay to be sure that person arrived!(workaround in combination with parking=False)
3169
time_init=time_from-10, # time_from,
3170
id_edge_from=id_edge_from,
3171
position_edge_from=pos_edge_from,
3172
id_edge_to=id_edge_to,
3173
position_edge_to=pos_edge_to,
3174
)
3175
3176
# here we should have created a moto ride
3177
# if not, for ehatever reason,
3178
# we walk from origin to destination
3179
if id_stage_moto == -1:
3180
# print ' walk because no ride stage has been planned',time_from
3181
if id_stage_walk1 == -1:
3182
# no walk stage has been planned
3183
id_stage_walk1, time = walkstages.append_stage(
3184
id_plan, time_from,
3185
id_edge_from=id_edge_from,
3186
position_edge_from=pos_edge_from,
3187
id_edge_to=id_edge_to,
3188
position_edge_to=pos_edge_to,
3189
)
3190
3191
elif time_from == time:
3192
# walking to bike has already been schedules,
3193
# but cycling failed. So walk the whole way
3194
time = walkstages.modify_stage(
3195
id_stage_walk1, time_from,
3196
id_edge_from=id_edge_from,
3197
position_edge_from=pos_edge_from,
3198
id_edge_to=id_edge_to,
3199
position_edge_to=pos_edge_to,
3200
)
3201
return time
3202
3203
def plan(self, ids_person, logger=None):
3204
"""
3205
Generates a plan for these person according to this strategie.
3206
Overriden by specific strategy.
3207
"""
3208
#make_plans_private(self, ids_person = None, mode = 'passenger')
3209
# routing necessary?
3210
virtualpop = self.get_virtualpop()
3211
plans = virtualpop.get_plans() # self._plans
3212
walkstages = plans.get_stagetable('walks')
3213
ridestages = plans.get_stagetable('motorides')
3214
activitystages = plans.get_stagetable('activities')
3215
3216
activities = virtualpop.get_activities()
3217
activitytypes = virtualpop.get_demand().activitytypes
3218
landuse = virtualpop.get_landuse()
3219
facilities = landuse.facilities
3220
#parking = landuse.parking
3221
3222
scenario = virtualpop.get_scenario()
3223
edges = scenario.net.edges
3224
lanes = scenario.net.lanes
3225
modes = scenario.net.modes
3226
3227
#times_est_plan = plans.times_est
3228
3229
# here we can determine edge weights for different modes
3230
plans.prepare_stagetables(['walks', 'motorides', 'activities'])
3231
3232
# get initial travel times for persons.
3233
# initial travel times depend on the initial activity
3234
3235
# landuse.parking.clear_booking()
3236
3237
ids_person_act, ids_act_from, ids_act_to\
3238
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
3239
3240
if len(ids_person_act) == 0:
3241
print 'WARNING in MotorcycleStrategy.plan: no eligible persons found.'
3242
return False
3243
3244
# ok
3245
3246
# temporary maps from ids_person to other parameters
3247
nm = np.max(ids_person_act)+1
3248
map_ids_plan = np.zeros(nm, dtype=np.int32)
3249
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
3250
3251
map_times = np.zeros(nm, dtype=np.int32)
3252
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
3253
3254
# set start time to plans (important!)
3255
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
3256
3257
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
3258
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
3259
3260
#map_ids_parking_from = np.zeros(nm, dtype = np.int32)
3261
# ids_parking_from, inds_vehparking = parking.get_closest_parkings( virtualpop.ids_iauto[ids_person_act],
3262
# facilities.centroids[activities.ids_facility[ids_act_from]])
3263
# if len(ids_parking_from)==0:
3264
# return False
3265
3266
# err
3267
3268
#map_ids_parking_from[ids_person_act] = ids_parking_from
3269
3270
n_plans = len(ids_person_act)
3271
print 'MotorcycleStrategy.plan n_plans=', n_plans
3272
# print ' map_ids_parking_from[ids_person_act].shape',map_ids_parking_from[ids_person_act].shape
3273
# set initial activity
3274
# this is because the following steps start with travel
3275
# and set the next activity
3276
#names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
3277
# for id_plan
3278
3279
ind_act = 0
3280
3281
# make initial activity stage
3282
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
3283
3284
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
3285
poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from)
3286
3287
# this is the time when first activity starts
3288
# first activity is normally not simulated
3289
3290
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
3291
durations_act_from = activities.get_durations(ids_act_from)
3292
times_from = map_times[ids_person_act]-durations_act_from
3293
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
3294
3295
# do initial stage
3296
# could be common to all strategies
3297
for id_plan,\
3298
time,\
3299
id_act_from,\
3300
name_acttype_from,\
3301
duration_act_from,\
3302
id_edge_from,\
3303
pos_edge_from \
3304
in zip(map_ids_plan[ids_person_act],
3305
times_from,
3306
ids_act_from,
3307
names_acttype_from,
3308
durations_act_from,
3309
ids_edge_from,
3310
poss_edge_from):
3311
3312
id_stage_act, time = activitystages.append_stage(
3313
id_plan, time,
3314
ids_activity=id_act_from,
3315
names_activitytype=name_acttype_from,
3316
durations=duration_act_from,
3317
ids_lane=edges.ids_lanes[id_edge_from][0],
3318
positions=pos_edge_from,
3319
)
3320
3321
# main loop while there are persons performing
3322
# an activity at index ind_act
3323
while len(ids_person_act) > 0:
3324
ids_plan = map_ids_plan[ids_person_act]
3325
ids_veh = virtualpop.ids_imoto[ids_person_act]
3326
dists_walk_max = virtualpop.dists_walk_max[ids_person_act]
3327
times_from = map_times[ids_person_act]
3328
3329
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
3330
durations_act_to = activities.get_durations(ids_act_to)
3331
3332
ids_fac_from = map_ids_fac_from[ids_person_act]
3333
ids_fac_to = activities.ids_facility[ids_act_to]
3334
3335
# origin edge and position
3336
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
3337
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
3338
poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from)
3339
3340
centroids_from = facilities.centroids[ids_fac_from]
3341
3342
# this method will find and occupy parking space
3343
#ids_parking_from = map_ids_parking_from[ids_person_act]
3344
3345
# print ' ids_veh.shape',ids_veh.shape
3346
# print ' centroids_to.shape',centroids_to.shape
3347
#ids_parking_to, inds_vehparking = parking.get_closest_parkings(ids_veh, centroids_to)
3348
3349
#ids_lane_parking_from = parking.ids_lane[ids_parking_from]
3350
#ids_edge_parking_from = lanes.ids_edge[ids_lane_parking_from]
3351
#poss_edge_parking_from = parking.positions[ids_parking_from]
3352
3353
# print ' ids_parking_to.shape',ids_parking_to.shape
3354
# print ' np.max(parking.get_ids()), np.max(ids_parking_to)',np.max(parking.get_ids()), np.max(ids_parking_to)
3355
#ids_lane_parking_to = parking.ids_lane[ids_parking_to]
3356
#ids_edge_parking_to = lanes.ids_edge[ids_lane_parking_to]
3357
#poss_edge_parking_to = parking.positions[ids_parking_to]
3358
3359
# destination edge and position
3360
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
3361
3362
poss_edge_to1 = facilities.positions_roadedge_closest[ids_fac_to]
3363
poss_edge_to = self.clip_positions(poss_edge_to1, ids_edge_to)
3364
centroids_to = facilities.centroids[ids_fac_to]
3365
3366
# debug poscorrection..OK
3367
# for id_edge, id_edge_sumo, length, pos_to1, pos in zip(ids_edge_to, edges.ids_sumo[ids_edge_to],edges.lengths[ids_edge_to],poss_edge_to1, poss_edge_to):
3368
# print ' ',id_edge, 'IDe%s'%id_edge_sumo, 'L=%.2fm'%length, '%.2fm'%pos_to1, '%.2fm'%pos
3369
3370
dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1))
3371
3372
i = 0.0
3373
n_pers = len(ids_person_act)
3374
for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, dist_from_to, dist_walk_max\
3375
in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, dists_from_to, dists_walk_max):
3376
if logger:
3377
logger.progress(i/n_pers*100)
3378
i += 1.0
3379
print 79*'*'
3380
print ' plan id_plan', id_plan, 'time_from', time_from, 'from', id_edge_from, pos_edge_from, 'to', id_edge_to, pos_edge_to
3381
print ' id_edge_from', edges.ids_sumo[id_edge_from], 'id_edge_to', edges.ids_sumo[id_edge_to]
3382
3383
time = self.plan_motoride(id_plan, time_from, id_veh,
3384
id_edge_from, pos_edge_from,
3385
id_edge_to, pos_edge_to,
3386
dist_from_to, dist_walk_max,
3387
walkstages, ridestages)
3388
3389
################
3390
3391
# store time estimation for this plan
3392
# note that these are the travel times, no activity time
3393
plans.times_est[id_plan] += time-time_from
3394
3395
# define current end time without last activity duration
3396
plans.times_end[id_plan] = time
3397
3398
# finally add activity and respective duration
3399
3400
id_stage_act, time = activitystages.append_stage(
3401
id_plan, time,
3402
ids_activity=id_act_to,
3403
names_activitytype=name_acttype_to,
3404
durations=duration_act_to,
3405
ids_lane=edges.ids_lanes[id_edge_to][0],
3406
positions=pos_edge_to,
3407
)
3408
3409
map_times[id_person] = time
3410
# return time
3411
##
3412
3413
# select persons and activities for next setp
3414
ind_act += 1
3415
ids_person_act, ids_act_from, ids_act_to\
3416
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
3417
# update timing with (random) activity duration!!
3418
3419
return True
3420
3421
3422
class TransitStrategy(StrategyMixin):
3423
def __init__(self, ident, parent=None,
3424
name='Public Transport Strategy',
3425
info='With this strategy, the person uses public transport.',
3426
**kwargs):
3427
3428
self._init_objman(ident, parent, name=name, info=info, **kwargs)
3429
attrsman = self.set_attrsman(cm.Attrsman(self))
3430
# specific init
3431
self._init_attributes()
3432
self._init_constants()
3433
3434
def _init_attributes(self, **kwargs):
3435
# print 'StrategyMixin._init_attributes'
3436
attrsman = self.get_attrsman()
3437
3438
self.utility_constant = attrsman.add(cm.AttrConf('utility_constant', kwargs.get('utility_constant', 0.3727),
3439
groupnames=['options'],
3440
perm='rw',
3441
name='Utility constant for transit strategy',
3442
info='Constant to calculate utility: U = Const + value_of_time*time_exec',
3443
))
3444
3445
def _init_constants(self):
3446
#virtualpop = self.get_virtualpop()
3447
#stagetables = virtualpop.get_stagetables()
3448
3449
#self._walkstages = stagetables.get_stagetable('walks')
3450
#self._ridestages = stagetables.get_stagetable('rides')
3451
#self._activitystages = stagetables.get_stagetable('activities')
3452
3453
#self._plans = virtualpop.get_plans()
3454
#
3455
# print 'AutoStrategy._init_constants'
3456
# print dir(self)
3457
# self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans'])
3458
3459
modes = self.get_virtualpop().get_scenario().net.modes
3460
self._id_mode_bike = modes.get_id_mode('bicycle')
3461
self._id_mode_auto = modes.get_id_mode('passenger')
3462
self._id_mode_moto = modes.get_id_mode('motorcycle')
3463
self._id_mode_bus = modes.get_id_mode('bus')
3464
self.get_attrsman().do_not_save_attrs([
3465
'_id_mode_bike', '_id_mode_auto', '_id_mode_moto', '_id_mode_bus'
3466
])
3467
3468
def preevaluate(self, ids_person):
3469
"""
3470
Preevaluation strategies for person IDs in vector ids_person.
3471
3472
Returns a preevaluation vector with a preevaluation value
3473
for each person ID. The values of the preevaluation vector are as follows:
3474
-1 : Strategy cannot be applied
3475
0 : Stategy can be applied, but the preferred mode is not used
3476
1 : Stategy can be applied, and preferred mode is part of the strategy
3477
2 : Strategy uses predomunantly preferred mode
3478
3479
"""
3480
n_pers = len(ids_person)
3481
persons = self.get_virtualpop()
3482
preeval = np.zeros(n_pers, dtype=np.int32)
3483
3484
# TODO: here we could exclude by age or distance facilities-stops
3485
3486
# put 0 for persons whose preference is not public transport
3487
preeval[persons.ids_mode_preferred[ids_person] != self._id_mode_bus] = 0
3488
3489
# put 2 for persons with car access and who prefer cars
3490
preeval[persons.ids_mode_preferred[ids_person] == self._id_mode_bus] = 2
3491
3492
print ' TransitStrategy.preevaluate', len(np.flatnonzero(preeval))
3493
return preeval
3494
3495
def plan_transit(self, id_plan, time_from,
3496
id_edge_from, pos_edge_from,
3497
id_edge_to, pos_edge_to,
3498
id_stop_from, id_stopedge_from, pos_stop_from,
3499
id_stop_to, id_stopedge_to, pos_stop_to,
3500
#dist_from_to, dist_walk_max,
3501
walkstages, transitstages,
3502
ptlines, ptfstar, pttimes,
3503
stops_to_enter, stops_to_exit,
3504
ids_laneedge, ids_stoplane, ptstops):
3505
3506
edges = self.get_scenario().net.edges
3507
print 'plan_transit id_plan', id_plan, 'id_edge_from %d (%s)' % (id_edge_from, edges.ids_sumo[id_edge_from]), 'id_edge_to %d (%s)' % (id_edge_to, edges.ids_sumo[id_edge_to])
3508
3509
# debug?
3510
is_debug = False # id_plan == 14983
3511
3512
if is_debug:
3513
3514
print ' id_stop_from', id_stop_from, 'id_stop_to', id_stop_to
3515
3516
ptlinks = ptlines.get_ptlinks()
3517
ptlinktypes = ptlinks.types.choices
3518
type_enter = ptlinktypes['enter']
3519
type_transit = ptlinktypes['transit']
3520
type_board = ptlinktypes['board']
3521
type_alight = ptlinktypes['alight']
3522
type_transfer = ptlinktypes['transfer']
3523
type_walk = ptlinktypes['walk']
3524
type_exit = ptlinktypes['exit']
3525
3526
if (id_edge_from == id_stopedge_from) & (abs(pos_edge_from-pos_stop_from) < 1.0):
3527
time = time_from
3528
id_stage_walk1 = None
3529
if is_debug:
3530
print ' no initial walk required.'
3531
print ' id_edge_from', id_edge_from, edges.ids_sumo[id_edge_from]
3532
print ' pos_edge_from', pos_edge_from
3533
else:
3534
id_stage_walk1, time = walkstages.append_stage(id_plan, time_from,
3535
id_edge_from=id_edge_from,
3536
position_edge_from=pos_edge_from,
3537
id_edge_to=id_stopedge_from,
3538
position_edge_to=pos_stop_from, # -7.0,
3539
)
3540
if is_debug:
3541
print ' add initial walk stage'
3542
print ' id_edge_from', id_edge_from, edges.ids_sumo[id_edge_from]
3543
print ' pos_edge_from', pos_edge_from
3544
print ' IIIInitial walk'
3545
print ' id_stopedge_from', id_stopedge_from, edges.ids_sumo[id_stopedge_from]
3546
print ' pos_stop_from', pos_stop_from
3547
3548
if is_debug:
3549
print ' TTTransit'
3550
print ' id_stopedge_to', id_stopedge_to, edges.ids_sumo[id_stopedge_to]
3551
print ' pos_stop_to', pos_stop_to
3552
print ' ----------------------------------'
3553
print ' id_stop_from', id_stop_from
3554
print ' id_stop_to', id_stop_to
3555
3556
durations, linktypes, ids_line, ids_fromstop, ids_tostop =\
3557
ptlinks.route(id_stop_from, id_stop_to,
3558
fstar=ptfstar, times=pttimes,
3559
stops_to_enter=stops_to_enter,
3560
stops_to_exit=stops_to_exit)
3561
3562
if is_debug:
3563
print ' routing done. make plan, success', len(linktypes) > 0
3564
3565
if is_debug:
3566
print ' ids_line ', ids_line
3567
print ' ids_fromstop', ids_fromstop
3568
print ' ids_tostop ', ids_tostop
3569
3570
if (type_transit in linktypes): # is there any public transport line to take?
3571
3572
# go though PT links and generate transits and walks to trasfer
3573
ids_stopedge_from = ids_laneedge[ids_stoplane[ids_fromstop]]
3574
ids_stopedge_to = ids_laneedge[ids_stoplane[ids_tostop]]
3575
poss_stop_from = 0.5*(ptstops.positions_from[ids_fromstop]
3576
+ ptstops.positions_to[ids_fromstop])
3577
poss_stop_to = 0.5*(ptstops.positions_from[ids_tostop]
3578
+ ptstops.positions_to[ids_tostop])
3579
3580
# this is wait time buffer to be added to the successive stage
3581
# as waiting is currently not modelled as an extra stage
3582
duration_wait = 0.0
3583
3584
# check if initial walk needs to be modified
3585
if (id_stage_walk1 is not None) & (linktypes[0] == type_walk):
3586
if is_debug:
3587
print ' Modify initial walk from stop fromedge %d (%s) toedge %d (%s)' % (id_edge_from, edges.ids_sumo[id_edge_from], ids_stopedge_from[0], edges.ids_sumo[ids_stopedge_from[0]])
3588
3589
is_initial_walk_done = True
3590
time = walkstages.modify_stage(
3591
id_stage_walk1,
3592
id_edge_from=id_edge_from,
3593
position_edge_from=pos_edge_from,
3594
id_edge_to=ids_stopedge_to[0],
3595
position_edge_to=poss_stop_to[0],
3596
)
3597
else:
3598
is_initial_walk_done = False
3599
3600
# create stages for PT
3601
for i, linktype, id_line, duration,\
3602
id_stopedge_from, pos_fromstop,\
3603
id_stopedge_to, pos_tostop in\
3604
zip(xrange(len(linktypes)),
3605
linktypes,
3606
ids_line,
3607
durations,
3608
ids_stopedge_from, poss_stop_from,
3609
ids_stopedge_to, poss_stop_to,
3610
):
3611
if is_debug:
3612
print ' ...........................'
3613
print ' stage for linktype %2d fromedge %s toedge %s' % (linktype, edges.ids_sumo[id_stopedge_from], edges.ids_sumo[id_stopedge_to])
3614
print ' id_stopedge_from,id_stopedge_to', id_stopedge_from, id_stopedge_to
3615
3616
if linktype == type_transit: # transit!
3617
# check if last link type has also been a transit
3618
if i > 0:
3619
if linktypes[i-1] == type_transit:
3620
if is_debug:
3621
print ' add inter-transit walk stage'
3622
# introdice a walk stage to be sure that
3623
# person gets to the middle of the stop
3624
id_stage_transfer, time = walkstages.append_stage(
3625
id_plan, time,
3626
id_edge_from=ids_stopedge_to[i-1],
3627
position_edge_from=poss_stop_to[i-1],
3628
id_edge_to=ids_stopedge_to[i-1],
3629
position_edge_to=poss_stop_to[i-1],
3630
duration=0.0, # moving within stop area
3631
)
3632
3633
if is_debug:
3634
print ' add transit stage id_line', id_line
3635
id_stage_transit, time = transitstages.append_stage(
3636
id_plan, time,
3637
id_line=id_line,
3638
duration=duration+duration_wait,
3639
id_fromedge=id_stopedge_from,
3640
id_toedge=id_stopedge_to,
3641
)
3642
duration_wait = 0.0
3643
3644
elif (linktype == type_walk) & ((i > 0) | (not is_initial_walk_done)):
3645
# walk to transfer, no initial walk if done
3646
if is_debug:
3647
print ' add walk to transfer'
3648
id_stage_transfer, time = walkstages.append_stage(
3649
id_plan, time,
3650
id_edge_from=id_stopedge_from,
3651
position_edge_from=pos_fromstop,
3652
id_edge_to=id_stopedge_to,
3653
position_edge_to=pos_tostop,
3654
duration=duration+duration_wait,
3655
)
3656
duration_wait = 0.0
3657
3658
else: # all other link time are no modelld
3659
# do not do anything , just add wait time to next stage
3660
if is_debug:
3661
print ' do noting add duration', duration
3662
duration_wait += duration
3663
3664
# walk from final stop to activity
3665
i = len(linktypes)-1 # last link index
3666
3667
if is_debug:
3668
print ' linktypes', linktypes, 'i', i, 'linktypes[i]', linktypes[i], linktypes[i] == type_walk
3669
3670
if linktypes[i] == type_walk:
3671
if is_debug:
3672
print ' Modify final walk from stop fromedge %d (%s) toedge %d (%s)' % (id_stopedge_to, edges.ids_sumo[id_stopedge_to], id_edge_to, edges.ids_sumo[id_edge_to])
3673
3674
time = walkstages.modify_stage(
3675
id_stage_transfer,
3676
id_edge_from=ids_stopedge_from[i],
3677
position_edge_from=poss_stop_from[i],
3678
id_edge_to=id_edge_to,
3679
position_edge_to=pos_edge_to,
3680
)
3681
3682
else:
3683
if is_debug:
3684
print ' Add final walk stage fromedge %d (%s) toedge %d (%s)' % (id_stopedge_to, edges.ids_sumo[id_stopedge_to], id_edge_to, edges.ids_sumo[id_edge_to])
3685
3686
id_stage_walk2, time = walkstages.append_stage(id_plan, time,
3687
id_edge_from=id_stopedge_to,
3688
position_edge_from=pos_tostop,
3689
id_edge_to=id_edge_to,
3690
position_edge_to=pos_edge_to,
3691
)
3692
3693
else:
3694
# there is no public transport line linking these nodes.
3695
if is_debug:
3696
print ' No PT lines used create direct walk stage'
3697
3698
if id_stage_walk1 is None:
3699
# Create first walk directly from home to activity
3700
id_stage_walk1, time = walkstages.append_stage(id_plan,
3701
time_from,
3702
id_edge_from=id_edge_from,
3703
position_edge_from=pos_edge_from,
3704
id_edge_to=id_edge_to,
3705
position_edge_to=pos_edge_to,
3706
)
3707
else:
3708
# Modify first walk directly from home to activity
3709
time = walkstages.modify_stage(id_stage_walk1, time_from,
3710
id_edge_from=id_edge_from,
3711
position_edge_from=pos_edge_from,
3712
id_edge_to=id_edge_to,
3713
position_edge_to=pos_edge_to,
3714
)
3715
3716
return time
3717
3718
def plan(self, ids_person, logger=None, **kwargs):
3719
"""
3720
Generates a plan for these person according to this strategie.
3721
Overriden by specific strategy.
3722
"""
3723
print 'TransitStrategy.plan', len(ids_person)
3724
#make_plans_private(self, ids_person = None, mode = 'passenger')
3725
# routing necessary?
3726
virtualpop = self.get_virtualpop()
3727
plans = virtualpop.get_plans() # self._plans
3728
demand = virtualpop.get_demand()
3729
ptlines = demand.ptlines
3730
3731
walkstages = plans.get_stagetable('walks')
3732
transitstages = plans.get_stagetable('transits')
3733
activitystages = plans.get_stagetable('activities')
3734
3735
activities = virtualpop.get_activities()
3736
activitytypes = demand.activitytypes
3737
landuse = virtualpop.get_landuse()
3738
facilities = landuse.facilities
3739
parking = landuse.parking
3740
3741
scenario = virtualpop.get_scenario()
3742
net = scenario.net
3743
edges = net.edges
3744
lanes = net.lanes
3745
modes = net.modes
3746
3747
ptstops = net.ptstops
3748
3749
# print ' demand',demand
3750
# print ' demand.ptlines',demand.ptlines,dir(demand.ptlines)
3751
# print ' demand.ptlines.get_ptlinks()',demand.ptlines.get_ptlinks()
3752
# print ' demand.virtualpop',demand.virtualpop,dir(demand.virtualpop)
3753
# print ' demand.trips',demand.trips,dir(demand.trips)
3754
if len(ptlines) == 0:
3755
print 'WARNING in TrasitStrategy.plan: no transit services available. Create public trasit services by connecting stops.'
3756
return False
3757
3758
ptlinks = ptlines.get_ptlinks()
3759
if len(ptlinks) == 0:
3760
print 'WARNING in TrasitStrategy.plan: no public transport links. Run methods: "create routes" and "build links" from public trasport services.'
3761
return False
3762
3763
ptlinktypes = ptlinks.types.choices
3764
3765
ptfstar = ptlinks.get_fstar()
3766
pttimes = ptlinks.get_times()
3767
stops_to_enter, stops_to_exit = ptlinks.get_stops_to_enter_exit()
3768
3769
ids_stoplane = ptstops.ids_lane
3770
ids_laneedge = net.lanes.ids_edge
3771
3772
times_est_plan = plans.times_est
3773
# here we can determine edge weights for different modes
3774
3775
# this could be centralized to avoid redundance
3776
plans.prepare_stagetables(['walks', 'transits', 'activities'])
3777
3778
ids_person_act, ids_act_from, ids_act_to\
3779
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
3780
3781
if len(ids_person_act) == 0:
3782
print 'WARNING in TrasitStrategy.plan: no eligible persons found.'
3783
return False
3784
3785
# temporary maps from ids_person to other parameters
3786
nm = np.max(ids_person_act)+1
3787
map_ids_plan = np.zeros(nm, dtype=np.int32)
3788
#ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy())
3789
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
3790
3791
map_times = np.zeros(nm, dtype=np.int32)
3792
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
3793
3794
# set start time to plans (important!)
3795
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
3796
3797
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
3798
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
3799
3800
n_plans = len(ids_person_act)
3801
print 'TrasitStrategy.plan n_plans=', n_plans
3802
3803
# make initial activity stage
3804
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
3805
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
3806
# this is the time when first activity starts
3807
# first activity is normally not simulated
3808
3809
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
3810
durations_act_from = activities.get_durations(ids_act_from)
3811
times_from = map_times[ids_person_act]-durations_act_from
3812
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
3813
3814
for id_plan,\
3815
time,\
3816
id_act_from,\
3817
name_acttype_from,\
3818
duration_act_from,\
3819
id_edge_from,\
3820
pos_edge_from \
3821
in zip(map_ids_plan[ids_person_act],
3822
times_from,
3823
ids_act_from,
3824
names_acttype_from,
3825
durations_act_from,
3826
ids_edge_from,
3827
poss_edge_from):
3828
3829
id_stage_act, time = activitystages.append_stage(
3830
id_plan, time,
3831
ids_activity=id_act_from,
3832
names_activitytype=name_acttype_from,
3833
durations=duration_act_from,
3834
ids_lane=edges.ids_lanes[id_edge_from][0],
3835
positions=pos_edge_from,
3836
)
3837
3838
##
3839
3840
ind_act = 0
3841
3842
# main loop while there are persons performing
3843
# an activity at index ind_act
3844
while len(ids_person_act) > 0:
3845
ids_plan = map_ids_plan[ids_person_act]
3846
3847
times_from = map_times[ids_person_act]
3848
3849
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
3850
durations_act_to = activities.get_durations(ids_act_to)
3851
3852
ids_fac_from = map_ids_fac_from[ids_person_act]
3853
ids_fac_to = activities.ids_facility[ids_act_to]
3854
3855
centroids_from = facilities.centroids[ids_fac_from]
3856
centroids_to = facilities.centroids[ids_fac_to]
3857
3858
# origin edge and position
3859
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
3860
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
3861
3862
# destination edge and position
3863
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
3864
poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to]
3865
3866
ids_stop_from = ptstops.get_closest(centroids_from)
3867
ids_stop_to = ptstops.get_closest(centroids_to)
3868
3869
ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]]
3870
ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]]
3871
3872
# do random pos here
3873
poss_stop_from = 0.5*(ptstops.positions_from[ids_stop_from]
3874
+ ptstops.positions_to[ids_stop_from])
3875
3876
poss_stop_to = 0.5*(ptstops.positions_from[ids_stop_to]
3877
+ ptstops.positions_to[ids_stop_to])
3878
3879
i = 0.0
3880
for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, id_stop_from, id_stopedge_from, pos_stop_from, id_stop_to, id_stopedge_to, pos_stop_to\
3881
in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, ids_stop_from, ids_stopedge_from, poss_stop_from, ids_stop_to, ids_stopedge_to, poss_stop_to):
3882
n_pers = len(ids_person_act)
3883
if logger:
3884
logger.progress(i/n_pers*100)
3885
i += 1.0
3886
print 79*'_'
3887
print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person)
3888
3889
time = self.plan_transit(id_plan, time_from,
3890
id_edge_from, pos_edge_from,
3891
id_edge_to, pos_edge_to,
3892
id_stop_from, id_stopedge_from, pos_stop_from,
3893
id_stop_to, id_stopedge_to, pos_stop_to,
3894
#dist_from_to, dist_walk_max,
3895
walkstages, transitstages,
3896
ptlines, ptfstar, pttimes,
3897
stops_to_enter, stops_to_exit,
3898
ids_laneedge, ids_stoplane, ptstops)
3899
3900
# update time for trips estimation for this plan
3901
plans.times_est[id_plan] += time-time_from
3902
3903
# define current end time without last activity duration
3904
plans.times_end[id_plan] = time
3905
3906
id_stage_act, time = activitystages.append_stage(
3907
id_plan, time,
3908
ids_activity=id_act_to,
3909
names_activitytype=name_acttype_to,
3910
durations=duration_act_to,
3911
ids_lane=edges.ids_lanes[id_edge_to][0],
3912
positions=pos_edge_to,
3913
)
3914
3915
# store time for next iteration in case other activities are
3916
# following
3917
map_times[id_person] = time
3918
3919
# select persons and activities for next setp
3920
ind_act += 1
3921
ids_person_act, ids_act_from, ids_act_to\
3922
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
3923
3924
3925
class BikeTransitStrategy(BikeStrategy, TransitStrategy):
3926
def __init__(self, ident, parent=None,
3927
name='Bike+Public Transport Strategy',
3928
info='With this strategy, the person combines bike and public transport.',
3929
**kwargs):
3930
3931
self._init_objman(ident, parent, name=name, info=info, **kwargs)
3932
attrsman = self.set_attrsman(cm.Attrsman(self))
3933
# specific init
3934
self._init_attributes()
3935
self._init_constants()
3936
3937
def _init_attributes(self):
3938
# print 'StrategyMixin._init_attributes'
3939
BikeStrategy._init_attributes(self)
3940
TransitStrategy._init_attributes(self)
3941
3942
def _init_constants(self):
3943
3944
BikeStrategy._init_constants(self)
3945
TransitStrategy._init_constants(self)
3946
3947
def preevaluate(self, ids_person):
3948
"""
3949
Preevaluation strategies for person IDs in vector ids_person.
3950
3951
Returns a preevaluation vector with a preevaluation value
3952
for each person ID. The values of the preevaluation vector are as follows:
3953
-1 : Strategy cannot be applied
3954
0 : Stategy can be applied, but the preferred mode is not used
3955
1 : Stategy can be applied, and preferred mode is part of the strategy
3956
2 : Strategy uses predomunantly preferred mode
3957
3958
"""
3959
n_pers = len(ids_person)
3960
persons = self.get_virtualpop()
3961
preeval = np.zeros(n_pers, dtype=np.int32)
3962
3963
inds_prefer = (persons.ids_mode_preferred[ids_person] == self._id_mode_bus)\
3964
| (persons.ids_mode_preferred[ids_person] == self._id_mode_bike)\
3965
3966
inds_avail = persons.ids_ibike[ids_person] > -1
3967
preeval[np.logical_not(inds_avail)] = -1
3968
# TODO: here we could exclude by age or distance facilities-stops
3969
3970
# put 0 for persons whose preference is not public transport
3971
preeval[inds_avail & np.logical_not(inds_prefer)] = 0
3972
3973
# put 2 for persons with bike access and who prefer bike or bus
3974
preeval[inds_avail & inds_prefer] = 1
3975
3976
print ' BikeTransitStrategy.preevaluate', len(np.flatnonzero(preeval))
3977
return preeval
3978
3979
def plan(self, ids_person, logger=None, **kwargs):
3980
"""
3981
Generates a plan for these person according to this strategie.
3982
Overriden by specific strategy.
3983
"""
3984
print 'TransitStrategy.plan', len(ids_person)
3985
#make_plans_private(self, ids_person = None, mode = 'passenger')
3986
# routing necessary?
3987
virtualpop = self.get_virtualpop()
3988
plans = virtualpop.get_plans() # self._plans
3989
demand = virtualpop.get_demand()
3990
ptlines = demand.ptlines
3991
3992
walkstages = plans.get_stagetable('walks')
3993
transitstages = plans.get_stagetable('transits')
3994
ridestages = plans.get_stagetable('bikerides')
3995
activitystages = plans.get_stagetable('activities')
3996
3997
activities = virtualpop.get_activities()
3998
activitytypes = demand.activitytypes
3999
landuse = virtualpop.get_landuse()
4000
facilities = landuse.facilities
4001
#parking = landuse.parking
4002
4003
scenario = virtualpop.get_scenario()
4004
net = scenario.net
4005
edges = net.edges
4006
lanes = net.lanes
4007
modes = net.modes
4008
4009
ptstops = net.ptstops
4010
4011
# print ' demand',demand
4012
# print ' demand.ptlines',demand.ptlines,dir(demand.ptlines)
4013
# print ' demand.ptlines.get_ptlinks()',demand.ptlines.get_ptlinks()
4014
# print ' demand.virtualpop',demand.virtualpop,dir(demand.virtualpop)
4015
# print ' demand.trips',demand.trips,dir(demand.trips)
4016
if len(ptlines) == 0:
4017
print 'WARNING in TrasitStrategy.plan: no transit services available.'
4018
return False
4019
4020
ptlinks = ptlines.get_ptlinks()
4021
ptlinktypes = ptlinks.types.choices
4022
4023
ptfstar = ptlinks.get_fstar()
4024
pttimes = ptlinks.get_times()
4025
stops_to_enter, stops_to_exit = ptlinks.get_stops_to_enter_exit()
4026
4027
ids_stoplane = ptstops.ids_lane
4028
ids_laneedge = net.lanes.ids_edge
4029
4030
times_est_plan = plans.times_est
4031
# here we can determine edge weights for different modes
4032
4033
# this could be centralized to avoid redundance
4034
plans.prepare_stagetables(['walks', 'bikerides', 'transits', 'activities'])
4035
4036
ids_person_act, ids_act_from, ids_act_to\
4037
= virtualpop.get_activities_from_pattern(0, ids_person=ids_person)
4038
4039
if len(ids_person_act) == 0:
4040
print 'WARNING in TrasitStrategy.plan: no eligible persons found.'
4041
return False
4042
4043
# temporary maps from ids_person to other parameters
4044
nm = np.max(ids_person_act)+1
4045
map_ids_plan = np.zeros(nm, dtype=np.int32)
4046
#ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy())
4047
map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy())
4048
4049
map_times = np.zeros(nm, dtype=np.int32)
4050
map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit')
4051
4052
# set start time to plans (important!)
4053
plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act]
4054
4055
map_ids_fac_from = np.zeros(nm, dtype=np.int32)
4056
map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from]
4057
4058
n_plans = len(ids_person_act)
4059
print 'TrasitStrategy.plan n_plans=', n_plans
4060
4061
# make initial activity stage
4062
ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]]
4063
poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]]
4064
# this is the time when first activity starts
4065
# first activity is normally not simulated
4066
4067
names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]]
4068
durations_act_from = activities.get_durations(ids_act_from)
4069
times_from = map_times[ids_person_act]-durations_act_from
4070
#times_from = activities.get_times_end(ids_act_from, pdf = 'unit')
4071
4072
for id_plan,\
4073
time,\
4074
id_act_from,\
4075
name_acttype_from,\
4076
duration_act_from,\
4077
id_edge_from,\
4078
pos_edge_from \
4079
in zip(map_ids_plan[ids_person_act],
4080
times_from,
4081
ids_act_from,
4082
names_acttype_from,
4083
durations_act_from,
4084
ids_edge_from,
4085
poss_edge_from):
4086
4087
id_stage_act, time = activitystages.append_stage(
4088
id_plan, time,
4089
ids_activity=id_act_from,
4090
names_activitytype=name_acttype_from,
4091
durations=duration_act_from,
4092
ids_lane=edges.ids_lanes[id_edge_from][0],
4093
positions=pos_edge_from,
4094
)
4095
4096
##
4097
4098
ind_act = 0
4099
4100
# main loop while there are persons performing
4101
# an activity at index ind_act
4102
while len(ids_person_act) > 0:
4103
ids_plan = map_ids_plan[ids_person_act]
4104
4105
times_from = map_times[ids_person_act]
4106
4107
ids_veh = virtualpop.ids_ibike[ids_person_act]
4108
dists_walk_max = virtualpop.dists_walk_max[ids_person_act]
4109
names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]]
4110
durations_act_to = activities.get_durations(ids_act_to)
4111
4112
ids_fac_from = map_ids_fac_from[ids_person_act]
4113
ids_fac_to = activities.ids_facility[ids_act_to]
4114
4115
centroids_from = facilities.centroids[ids_fac_from]
4116
centroids_to = facilities.centroids[ids_fac_to]
4117
4118
# origin edge and position
4119
ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from]
4120
poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from]
4121
4122
# destination edge and position
4123
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
4124
poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to]
4125
4126
ids_stop_from = ptstops.get_closest(centroids_from)
4127
ids_stop_to = ptstops.get_closest(centroids_to)
4128
4129
ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]]
4130
ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]]
4131
4132
centroids_stop_from = ptstops.centroids[ids_stop_from]
4133
centroids_stop_to = ptstops.centroids[ids_stop_to]
4134
# do random pos here
4135
poss_stop_from = 0.5*(ptstops.positions_from[ids_stop_from]
4136
+ ptstops.positions_to[ids_stop_from])
4137
4138
poss_stop_to = 0.5*(ptstops.positions_from[ids_stop_to]
4139
+ ptstops.positions_to[ids_stop_to])
4140
4141
dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1))
4142
dists_from_stop_from = np.sqrt(np.sum((centroids_stop_from - centroids_from)**2, 1))
4143
dists_stop_to_to = np.sqrt(np.sum((centroids_to - centroids_stop_to)**2, 1))
4144
4145
i = 0.0
4146
for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, id_stop_from, id_stopedge_from, pos_stop_from, id_stop_to, id_stopedge_to, pos_stop_to, dists_from_to, dist_from_stop_from, dist_stop_to_to, dist_walk_max\
4147
in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, ids_stop_from, ids_stopedge_from, poss_stop_from, ids_stop_to, ids_stopedge_to, poss_stop_to, dists_from_to, dists_from_stop_from, dists_stop_to_to, dists_walk_max):
4148
n_pers = len(ids_person_act)
4149
if logger:
4150
logger.progress(i/n_pers*100)
4151
i += 1.0
4152
print 79*'_'
4153
print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person)
4154
#dist_from_stop_from, dist_stop_to_to
4155
4156
time = self.plan_bikeride(id_plan, time_from, id_veh,
4157
id_edge_from, pos_edge_from,
4158
id_stopedge_from, pos_stop_from,
4159
dist_from_stop_from, dist_walk_max,
4160
walkstages, ridestages)
4161
4162
time = self.plan_transit(id_plan, time,
4163
id_stopedge_from, pos_stop_from,
4164
id_stopedge_to, pos_stop_to,
4165
id_stop_from, id_stopedge_from, pos_stop_from,
4166
id_stop_to, id_stopedge_to, pos_stop_to,
4167
#dist_from_to, dist_walk_max,
4168
walkstages, transitstages,
4169
ptlines, ptfstar, pttimes,
4170
stops_to_enter, stops_to_exit,
4171
ids_laneedge, ids_stoplane, ptstops)
4172
4173
time = self.plan_bikeride(id_plan, time, id_veh,
4174
id_stopedge_to, pos_stop_to,
4175
id_edge_to, pos_edge_to,
4176
dist_stop_to_to, dist_walk_max,
4177
walkstages, ridestages)
4178
4179
# update time for trips estimation for this plan
4180
plans.times_est[id_plan] += time-time_from
4181
4182
# define current end time without last activity duration
4183
plans.times_end[id_plan] = time
4184
4185
id_stage_act, time = activitystages.append_stage(
4186
id_plan, time,
4187
ids_activity=id_act_to,
4188
names_activitytype=name_acttype_to,
4189
durations=duration_act_to,
4190
ids_lane=edges.ids_lanes[id_edge_to][0],
4191
positions=pos_edge_to,
4192
)
4193
4194
# store time for next iteration in case other activities are
4195
# following
4196
map_times[id_person] = time
4197
4198
# select persons and activities for next setp
4199
ind_act += 1
4200
ids_person_act, ids_act_from, ids_act_to\
4201
= virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act)
4202
4203
4204
class Strategies(am.ArrayObjman):
4205
def __init__(self, ident, virtualpop, **kwargs):
4206
self._init_objman(ident,
4207
parent=virtualpop,
4208
name='Mobility Strategies',
4209
info="""Contains different mobility strategies.
4210
A strategy has methods to identify whether a strategy is applicaple to a person
4211
and to make a plan fo a person.
4212
""",
4213
version=0.3,
4214
**kwargs)
4215
4216
self.add_col(am.ArrayConf('names',
4217
default='',
4218
dtype='object',
4219
perm='r',
4220
is_index=True,
4221
name='Short name',
4222
info='Strategy name. Must be unique, used as index.',
4223
))
4224
self._init_attributes()
4225
self._init_constants()
4226
4227
def _init_attributes(self):
4228
4229
self.add_col(cm.ObjsConf('strategies',
4230
groupnames=['state'],
4231
name='Strategy',
4232
info='Strategy object.',
4233
))
4234
4235
if hasattr(self, 'vot'): # self.get_version() < 0.3:
4236
value_of_time_default = self.vot.get_value()
4237
self.delete('vot')
4238
else:
4239
value_of_time_default = 0.07/60 # here in euro per second
4240
4241
self.add(cm.AttrConf('value_of_time', value_of_time_default,
4242
groupnames=['parameters'],
4243
name='Value of time (VOT)',
4244
unit='1/s',
4245
perm='rw',
4246
info="This parameter weights the travel time in each strategies utility function: utility = utility_strategy_specific + value_of_time*time_exec +noise",
4247
))
4248
4249
self.add_col(am.ArrayConf('colors', np.ones(4, np.float32),
4250
dtype=np.float32,
4251
groupnames=['parameters'],
4252
metatype='color',
4253
perm='rw',
4254
name='Color',
4255
info="Route color. Color as RGBA tuple with values from 0.0 to 1.0",
4256
xmltag='color',
4257
))
4258
4259
if self.get_version() < 0.2:
4260
self._set_colors_default()
4261
4262
if self.get_version() < 0.3:
4263
self.set_version(0.3)
4264
4265
def format_ids(self, ids):
4266
return ', '.join(self.names[ids])
4267
4268
def get_id_from_formatted(self, idstr):
4269
return self.names.get_id_from_index(idstr)
4270
4271
def get_ids_from_formatted(self, idstrs):
4272
return self.names.get_ids_from_indices_save(idstrs.split(','))
4273
4274
def add_default(self):
4275
4276
self.add_strategy('walk', WalkStrategy)
4277
self.add_strategy('auto', AutoStrategy)
4278
self.add_strategy('bike', BikeStrategy)
4279
self.add_strategy('transit', TransitStrategy)
4280
self.add_strategy('biketransit', BikeTransitStrategy)
4281
self.add_strategy('motorcycle', MotorcycleStrategy)
4282
self.add_strategy('taxi', TaxiStrategy)
4283
self._set_colors_default()
4284
4285
def _set_colors_default(self):
4286
colors_default = {'walk': np.array([160, 72, 0, 220], np.float32)/255,
4287
'auto': np.array([250, 213, 0, 220], np.float32)/255,
4288
'bike': np.array([8, 191, 73, 210], np.float32)/255,
4289
'transit': np.array([8, 77, 191, 220], np.float32)/255,
4290
'biketransit': np.array([8, 201, 223, 220], np.float32)/255,
4291
'motorcycle': np.array([170, 200, 0, 220], np.float32)/255,
4292
'taxi': np.array([40, 240, 240, 220], np.float32)/255,
4293
}
4294
ids = self.names.get_ids_from_indices_save(colors_default.keys())
4295
self.colors[ids] = colors_default.values() # np.array(colors_default.values(), np.float32).reshape(-1,4)
4296
4297
#self.colors.indexset(colors_default.keys(), colors_default.values())
4298
4299
def add_strategy(self, ident, Strategyclass, color=(0.0, 0.0, 0.0, 1.0)):
4300
# print 'add_strategy', ident
4301
if not self.names.has_index(ident):
4302
strategy = Strategyclass(ident, self)
4303
self.add_row(names=ident,
4304
strategies=strategy,
4305
colours=color,
4306
)
4307
return strategy
4308
else:
4309
# print 'WARNING in add_strategy: strategy %s already initialized'%ident
4310
return self.strategies[self.names.get_id_from_index(ident)]
4311
4312
def preevaluate(self, ids_person):
4313
"""
4314
Preevaluation of strategies for person IDs in vector ids_person.
4315
4316
Returns a vector with strategy IDs and a preevaluation matrix.
4317
The rows of the matrix corrispond to each person ID.
4318
The columns corrsopond to reck strategy ID.
4319
The values of the preevaluation matrix are as follows:
4320
-1 : Strategy cannot be applied
4321
0 : Stategy can be applied, but the preferred mode is not used
4322
1 : Stategy can be applied, and preferred mode is part of the strategy
4323
2 : Strategy uses predomunantly preferred mode
4324
4325
"""
4326
print 'preevaluate strategies'
4327
ids_strat = self.get_ids()
4328
n_pers = len(ids_person)
4329
n_strat = len(ids_strat)
4330
4331
preeval = np.zeros((n_pers, n_strat), dtype=np.int32)
4332
for i, strategy in zip(range(n_strat), self.strategies[ids_strat]):
4333
print ' preevaluate strategiy', strategy.ident
4334
preeval[i, :] = strategy.preevaluate(ids_person)
4335
4336
return ids_strat, preeval
4337
4338
4339
class StageTypeMixin(am.ArrayObjman):
4340
def init_stagetable(self, ident, stages, name='', info="Stage of Plan"):
4341
4342
self._init_objman(ident=ident, parent=stages, name=name,
4343
info=info,
4344
version=0.2,
4345
)
4346
4347
self.add_col(am.IdsArrayConf('ids_plan', self.get_plans(),
4348
#groupnames = ['state'],
4349
name='ID plan',
4350
info='ID of plan.',
4351
xmltag='type',
4352
))
4353
4354
self.add_col(am.ArrayConf('times_start', -1.0,
4355
groupnames=['parameters'], # new
4356
name='Start time',
4357
unit='s',
4358
info='Planned or estimated time when this stage starts. Value -1 means unknown.',
4359
))
4360
4361
self.add_col(am.ArrayConf('durations', -1.0,
4362
name='Duration',
4363
groupnames=['parameters'], # new
4364
unit='s',
4365
info='Planned or estimated duration for this stage starts. Value -1 means unknown.',
4366
xmltag='type',
4367
))
4368
4369
def _init_constants(self):
4370
self._fstarmap = {}
4371
self._timesmap = {}
4372
self._distancesmap = {}
4373
self.get_attrsman().do_not_save_attrs(['_fstarmap', '_timesmap', '_distancesmap'])
4374
self._init_constants_specific()
4375
4376
def _init_constants_specific(self):
4377
# to be overridden
4378
pass
4379
4380
def get_plans(self):
4381
return self.parent
4382
4383
def get_ids_from_ids_plan(self, ids_plan):
4384
"""
4385
Returns only stage IDs which are part of the given plans IDs.
4386
"""
4387
# print 'get_ids_from_ids_plan for',type(ids_plan),ids_plan
4388
4389
ids = self.get_ids()
4390
#ids_plan_part = self.ids_plan[ids]
4391
are_selected = np.zeros(len(ids), dtype=np.bool)
4392
for ind, id_plan_part in zip(xrange(len(ids)), self.ids_plan[ids]):
4393
are_selected[ind] = id_plan_part in ids_plan
4394
return ids[are_selected]
4395
# print ' ids_plan_part',type(ids_plan_part),ids_plan_part
4396
# print ' ids_selected',type(ids_plan_part.intersection(ids_plan)),ids_plan_part.intersection(ids_plan)
4397
# return np.array(list(ids_plan_part.intersection(ids_plan)), dtype = np.int32)
4398
4399
def get_virtualpop(self):
4400
# print 'get_virtualpop '
4401
return self.parent.parent
4402
4403
def prepare_planning(self):
4404
pass
4405
4406
def append_stage(self, id_plan, time_start, **kwargs):
4407
4408
# try to fix timing
4409
# if time_start<0:
4410
# time_start_prev, duration_prev = self.parent.plans.get_timing_laststage(id_plan)
4411
# if (duration_prev>=0)&(time_start_prev>=0):
4412
# time_start = time_start_prev+duration_prev
4413
4414
id_stage = self.add_row(ids_plan=id_plan, times_start=time_start, **kwargs)
4415
# print 'STAGE.appended stage %s id_plan=%d, id_stage=%d, t=%d'%(self.get_name(),id_plan,id_stage,time_start)
4416
# for key in kwargs.keys():
4417
# print ' %s=%s'%(key,kwargs[key])
4418
# print ' --id_plan, self, id_stage',id_plan, self, id_stage#,self.ids_plan.get_linktab()
4419
4420
self.parent.append_stage(id_plan, self, id_stage)
4421
# print ' plan appended',id_plan, self, id_stage
4422
4423
return id_stage, time_start+self.durations[id_stage]
4424
4425
def modify_stage(self, id_stage, time_start=None, **kwargs):
4426
if time_start is None:
4427
time_start = self.times_start[id_stage]
4428
self.set_row(id_stage, **kwargs)
4429
return time_start+self.durations[id_stage]
4430
4431
def get_timing(self, id_stage):
4432
#ind = self.get_ind(id_stage)
4433
return self.times_start[id_stage], self.durations[id_stage]
4434
4435
def get_times(self, id_mode):
4436
"""
4437
Returns a vector mapping id_edge to edge travel times
4438
for given mode id_mode
4439
"""
4440
print 'get_times', self._timesmap.keys()
4441
4442
if not self._timesmap.has_key(id_mode):
4443
edges = self.get_virtualpop().get_scenario().net.edges
4444
self._timesmap[id_mode] = edges.get_times(id_mode=id_mode,
4445
is_check_lanes=True,
4446
)
4447
4448
return self._timesmap[id_mode]
4449
4450
def get_distances(self, id_mode):
4451
"""
4452
Returns a vector mapping id_edge to edge distances
4453
for given mode id_mode
4454
"""
4455
print 'get_distances', self._distancesmap.keys()
4456
4457
if not self._distancesmap.has_key(id_mode):
4458
edges = self.get_virtualpop().get_scenario().net.edges
4459
self._distancesmap[id_mode] = edges.get_distances(id_mode=id_mode,
4460
is_check_lanes=True,
4461
)
4462
4463
return self._distancesmap[id_mode]
4464
4465
def get_fstar(self, id_mode, is_return_arrays=True, is_ignor_connections=False):
4466
"""
4467
Returns a fstar
4468
for given mode id_mode
4469
"""
4470
print 'get_fstar', self._fstarmap.keys()
4471
4472
if not self._fstarmap.has_key(id_mode):
4473
edges = self.get_virtualpop().get_scenario().net.edges
4474
self._fstarmap[id_mode] = edges.get_fstar(id_mode=id_mode,
4475
is_ignor_connections=is_ignor_connections,
4476
is_return_arrays=is_return_arrays,
4477
)
4478
return self._fstarmap[id_mode]
4479
4480
def to_xml(self, id_stage, fd, indent=0):
4481
"""
4482
To be overridden by specific stage class.
4483
"""
4484
pass
4485
4486
4487
class TransitStages(StageTypeMixin):
4488
def __init__(self, ident, stages, name='Transit rides', info='Ride on a single public transport line (no transfers).'):
4489
self.init_stagetable(ident,
4490
stages, name=name,
4491
info=info,
4492
)
4493
self._init_attributes()
4494
4495
def _init_attributes(self):
4496
#ptstops = self.parent.get_ptstops()
4497
edges = self.get_virtualpop().get_net().edges
4498
if hasattr(self, 'ids_fromstop'):
4499
self.delete('ids_fromstop')
4500
self.delete('ids_tostop')
4501
4502
self.add_col(am.IdsArrayConf('ids_line', self.get_virtualpop().get_ptlines(),
4503
groupnames=['parameters'],
4504
name='ID line',
4505
info='ID of public transport line.',
4506
))
4507
4508
self.add_col(am.IdsArrayConf('ids_fromedge', edges,
4509
groupnames=['parameters'],
4510
name='Edge ID from',
4511
info='Edge ID of departure bus stop or station.',
4512
))
4513
4514
self.add_col(am.IdsArrayConf('ids_toedge', edges,
4515
groupnames=['parameters'],
4516
name='Edge ID to',
4517
info='Edge ID of destination bus stop or station.',
4518
))
4519
4520
def _init_constants_specific(self):
4521
self.get_attrsman().do_not_save_attrs(['_costs', '_fstar', ])
4522
4523
def prepare_planning(self):
4524
ptlinks = self.ids_line.get_linktab().ptlinks.get_value()
4525
if len(ptlinks) == 0:
4526
# no links built...built them
4527
ptlinks.build()
4528
4529
self._costs = ptlinks.get_times()
4530
self._fstar = ptlinks.get_fstar()
4531
4532
def append_stage(self, id_plan, time_start=-1.0,
4533
id_line=-1, duration=0.0,
4534
id_fromedge=-1, id_toedge=-1, **kwargs):
4535
"""
4536
Appends a transit stage to plan id_plan.
4537
4538
"""
4539
# print 'TransitStages.append_stage',id_stage
4540
4541
id_stage, time_end = StageTypeMixin.append_stage(self,
4542
id_plan,
4543
time_start,
4544
durations=duration,
4545
ids_line=id_line,
4546
ids_fromedge=id_fromedge,
4547
ids_toedge=id_toedge,
4548
)
4549
4550
# add this stage to the vehicle database
4551
# ind_ride gives the index of this ride (within the same plan??)
4552
#ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage)
4553
return id_stage, time_end
4554
4555
def to_xml(self, id_stage, fd, indent=0):
4556
# <ride from="1/3to0/3" to="0/4to1/4" lines="train0"/>
4557
net = self.get_virtualpop().get_net()
4558
#ids_stoplane = net.ptstops.ids_lane
4559
#ids_laneedge = net.lanes.ids_edge
4560
ids_sumoedge = net.edges.ids_sumo
4561
4562
#ind = self.get_ind(id_stage)
4563
fd.write(xm.start('ride', indent=indent))
4564
fd.write(xm.num('from', ids_sumoedge[self.ids_fromedge[id_stage]]))
4565
fd.write(xm.num('to', ids_sumoedge[self.ids_toedge[id_stage]]))
4566
fd.write(xm.num('lines', self.ids_line.get_linktab().linenames[self.ids_line[id_stage]]))
4567
# if self.cols.pos_edge_from[ind]>0:
4568
# fd.write(xm.num('departPos', self.cols.pos_edge_from[ind]))
4569
# if self.cols.pos_edge_to[ind]>0:
4570
# fd.write(xm.num('arrivalPos', self.cols.pos_edge_to[ind]))
4571
4572
fd.write(xm.stopit()) # ends stage
4573
4574
4575
class AutorideStages(StageTypeMixin):
4576
4577
def __init__(self, ident, population,
4578
name='Auto rides',
4579
info='Rides with privately owned auto.',
4580
version=1.1,
4581
):
4582
4583
self.init_stagetable(ident, population, name=name, info=info)
4584
# print 'Rides.__init__',self.get_name()
4585
self._init_attributes()
4586
4587
def _init_attributes(self):
4588
# TODO: this structure needs review: the private vehicle is part of a person, not a stage
4589
# street parking at home and work could be in stage. Private garage is part of person...
4590
# print '_init_attributes',self.parent.get_iautos(), self.ident,self.parent.get_landuse().parking
4591
4592
self.add_col(am.IdsArrayConf('ids_iauto', self.get_virtualpop().get_iautos(),
4593
groupnames=['parameter'],
4594
name='ID vehicle',
4595
info='ID of private vehicle.',
4596
))
4597
4598
self.add_col(am.ArrayConf('times_init', -1.0,
4599
groupnames=['parameter'],
4600
name='Init. time',
4601
unit='s',
4602
info='Initialization time, which is the time when the vehicle appears in the scenario. Value -1 means unknown.',
4603
))
4604
4605
self.add_col(am.IdsArrayConf('ids_parking_from', self.get_virtualpop().get_landuse().parking,
4606
groupnames=['parameter'],
4607
name='ID dep. parking',
4608
info='Parking ID at the departure of the ride starts.',
4609
))
4610
4611
self.add_col(am.IdsArrayConf('ids_parking_to', self.get_virtualpop().get_landuse().parking,
4612
groupnames=['parameter'],
4613
name='ID arr. parking',
4614
info='Parking ID at the arrival of the ride.',
4615
))
4616
4617
self.add_col(am.IdlistsArrayConf('ids_edges', self.get_virtualpop().get_net().edges,
4618
groupnames=['parameter'],
4619
name='Route',
4620
info="The vehicle's route as a sequence of edge IDs.",
4621
))
4622
4623
if self.get_version() < 1.1:
4624
self.ids_edges.del_groupname('_private')
4625
4626
self.add(cm.AttrConf('dist_ride_min', 400.0,
4627
groupnames=['options'],
4628
perm='rw',
4629
name='Min ride dist.',
4630
info='Minimum ride distance. If the distanve between parkings is less, then the person will walk.',
4631
))
4632
4633
self.set_version(1.1)
4634
# if hasattr(self,'parking'):
4635
# self.delete('parking')
4636
4637
def prepare_planning(self):
4638
# now in _init_constants
4639
pass
4640
#net = self.get_virtualpop().get_net()
4641
#id_mode = net.modes.get_id_mode('passenger')
4642
#self._costs = {}
4643
# self._costs[id_mode] = net.edges.get_times( id_mode = id_mode,
4644
# is_check_lanes = True)
4645
#self._fstars = {}
4646
#self._fstars[id_mode] = net.edges.get_fstar(is_ignor_connections = False, id_mode = id_mode)
4647
#self._fstar = net.edges.get_fstar(is_ignor_connections = False)
4648
4649
def append_stage(self, id_plan, id_mode,
4650
is_fallback=False, id_mode_fallback=None,
4651
time_start=-1.0, id_veh=-1, time_init=-1,
4652
id_parking_from=.1, id_parking_to=-1, **kwargs):
4653
"""
4654
Appends a ride stage to plan id_plan in case the ride is feasible.
4655
The ride is feasible if from parking and to parking are connected.
4656
4657
If feasible, the stage ID and estimated time when stage is finished
4658
will be returned.
4659
4660
If not feasible -1 and start time will be returned.
4661
"""
4662
print 'Rides.append_stage id_plan', id_plan, is_fallback
4663
4664
route, dist, duration, is_fallback = self.get_route_between_parking(
4665
id_parking_from, id_parking_to, id_mode,
4666
is_fallback, id_mode_fallback,)
4667
4668
print ' after routing: is_fallback', is_fallback, 'route', route
4669
4670
if (len(route) > 0): # |(dist > self.dist_ride_min.get_value()): # is there a connection
4671
# create stage
4672
id_stage, time_end = StageTypeMixin.append_stage(self,
4673
id_plan,
4674
time_start,
4675
durations=duration,
4676
times_init=time_init,
4677
ids_iauto=id_veh,
4678
ids_parking_from=id_parking_from,
4679
ids_parking_to=id_parking_to,
4680
ids_edges=route,
4681
)
4682
4683
# add this stage to the vehicle database
4684
# ind_ride gives the index of this ride (within the same plan??)
4685
#ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage)
4686
return id_stage, time_end, is_fallback
4687
4688
else:
4689
# not connected or too short of a distance
4690
return -1, time_start, is_fallback # no stage creation took place
4691
4692
def get_route_between_parking(self, id_parking_from, id_parking_to, id_mode,
4693
is_fallback=False, id_mode_fallback=None):
4694
"""
4695
Return route and distance of ride with vehicle type vtype
4696
between id_parking_from and id_parking_to
4697
4698
4699
"""
4700
print 'get_route_between_parking', id_parking_from, id_parking_to, 'is_fallback', is_fallback, 'id_mode_fallback', id_mode_fallback
4701
scenario = self.get_virtualpop().get_scenario()
4702
edges = scenario.net.edges
4703
lanes = scenario.net.lanes
4704
4705
# print self.get_demand().getVehicles().cols.maxSpeed
4706
#v_max = self.get_demand().getVehicles().maxSpeed.get(vtype)
4707
parking = scenario.landuse.parking
4708
4709
ids_lanes = parking.ids_lane[[id_parking_from, id_parking_to]]
4710
id_edge_from, id_edge_to = lanes.ids_edge[ids_lanes]
4711
pos_from, pos_to = parking.positions[[id_parking_from, id_parking_to]]
4712
4713
if is_fallback & (id_mode_fallback is not None):
4714
print ' use id_mode_fallback', id_mode_fallback
4715
id_mode_current = id_mode_fallback
4716
4717
else:
4718
print ' use id_mode', id_mode
4719
id_mode_current = id_mode
4720
4721
# print ' id_edge_from, id_edge_to=',id_edge_from, id_edge_to
4722
duration_approx, route = routing.get_mincostroute_edge2edge(
4723
id_edge_from,
4724
id_edge_to,
4725
weights=self.get_times(id_mode_current),
4726
fstar=self.get_fstar(id_mode_current),
4727
)
4728
4729
if (len(route) == 0) & (not is_fallback) & (id_mode_fallback is not None):
4730
is_fallback = True
4731
id_mode_current = id_mode_fallback
4732
print ' no route found with normal mode, try fallback', is_fallback
4733
# now retry with fallback
4734
duration_approx, route = routing.get_mincostroute_edge2edge(
4735
id_edge_from,
4736
id_edge_to,
4737
weights=self.get_times(id_mode_current),
4738
fstar=self.get_fstar(id_mode_current),
4739
)
4740
if len(route) > 0:
4741
print ' fallback has been successful'
4742
4743
# here is a big problem: starting with the successive node of edge_from
4744
# may result that the first edge of the route is not connected with edge_from
4745
# And arriving at the preceding node of edge_to may result that from
4746
# the last edge in route the edge_to is not connected.
4747
4748
#route = [edge_from]+route+[edge_to]
4749
dist = np.sum(edges.lengths[route])
4750
dist = dist - pos_from - (edges.lengths[id_edge_to] - pos_to)
4751
# if 0:
4752
# if len(route)>0:
4753
# print ' dist,duration',dist,duration_approx
4754
# else:
4755
# print ' no route found'
4756
4757
return route, dist, duration_approx, is_fallback
4758
4759
# def make_id_veh_ride(self, id_stage, i_ride):
4760
# # make a unique vehicle ID for this stage
4761
# self.inds_ride[id_stage] = i_ride
4762
# return str(self.ids_veh[id_stage])+'.'+str(i_ride)
4763
4764
def get_writexmlinfo(self, ids_plan, is_route=True, is_plain=False):
4765
print 'AutorideStages.get_writexmlinfo', len(ids_plan), is_route, 'is_plain', is_plain
4766
iautos = self.get_virtualpop().get_iautos()
4767
writefunc = iautos.prepare_write_xml(is_route, is_plain)
4768
4769
# not all auto plans contain autoride stages!
4770
ids = self.get_ids_from_ids_plan(ids_plan)
4771
writefuncs = np.zeros(len(ids), dtype=np.object)
4772
writefuncs[:] = writefunc
4773
return self.times_init[ids], writefuncs, ids
4774
4775
def to_xml(self, id_stage, fd, indent=0):
4776
#lanes = self.parent.get_scenario().net.lanes
4777
scenario = self.get_virtualpop().get_scenario()
4778
4779
edges = scenario.net.edges
4780
edgeindex = edges.ids_sumo
4781
parking = scenario.landuse.parking
4782
4783
ind = self.get_ind(id_stage)
4784
fd.write(xm.start('ride', indent=indent))
4785
4786
id_edge_from, pos_from = parking.get_edge_pos_parking(self.ids_parking_from.value[ind])
4787
id_edge_to, pos_to = parking.get_edge_pos_parking(self.ids_parking_to.value[ind])
4788
4789
# edgeindex.get_index_from_id(self.ids_edge_to.value[ind])
4790
fd.write(xm.num('from', edgeindex[id_edge_from]))
4791
fd.write(xm.num('to', edgeindex[id_edge_to]))
4792
fd.write(xm.num('lines', self.ids_iauto.get_linktab().get_id_line_xml(
4793
self.ids_iauto[id_stage]))) # mode specific
4794
4795
fd.write(xm.stopit()) # ends stage
4796
4797
4798
class BikerideStages(StageTypeMixin):
4799
4800
def __init__(self, ident, population,
4801
name='Bike rides',
4802
info='Rides with privately owned bike.',
4803
version=1.0,
4804
):
4805
4806
self.init_stagetable(ident, population, name=name, info=info)
4807
# print 'Rides.__init__',self.get_name()
4808
self._init_attributes()
4809
4810
def _init_attributes(self):
4811
# TODO: this structure needs review: the private vehicle is part of a person, not a stage
4812
# street parking at home and work could be in stage. Private garage is part of person...
4813
# print '_init_attributes',self.parent.get_iautos(), self.ident,self.parent.get_landuse().parking
4814
4815
self.add_col(am.IdsArrayConf('ids_ibike', self.get_virtualpop().get_ibikes(),
4816
groupnames=['state'],
4817
name='ID bike',
4818
info='ID of private, individual bike.',
4819
))
4820
4821
self.add_col(am.ArrayConf('times_init', -1.0,
4822
name='Init. time',
4823
unit='s',
4824
info='Initialization time, which is the time when the vehicle appears in the scenario. Value -1 means unknown.',
4825
))
4826
4827
edges = self.get_virtualpop().get_net().edges
4828
4829
self.add_col(am.IdsArrayConf('ids_edge_from', edges,
4830
groupnames=['state'],
4831
name='ID Dep. edge',
4832
info='Edge ID at departure of walk.',
4833
))
4834
4835
self.add_col(am.IdsArrayConf('ids_edge_to', edges,
4836
groupnames=['state'],
4837
name='ID Arr. edge',
4838
info='Edge ID where walk finishes.',
4839
))
4840
4841
self.add_col(am.ArrayConf('positions_from', 0.0,
4842
dtype=np.float32,
4843
#choices = OPTIONMAP_POS_DEPARTURE,
4844
perm='r',
4845
name='Depart pos',
4846
unit='m',
4847
info="Position on edge at the moment of departure.",
4848
#xmltag = 'departPos',
4849
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
4850
))
4851
4852
self.add_col(am.ArrayConf('positions_to', 0.0,
4853
dtype=np.float32,
4854
#choices = OPTIONMAP_POS_ARRIVAL,
4855
perm='r',
4856
name='Arrival pos',
4857
unit='m',
4858
info="Position on edge at the moment of arrival.",
4859
#xmltag = 'arrivalPos',
4860
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
4861
))
4862
4863
self.add_col(am.IdlistsArrayConf('ids_edges', self.get_virtualpop().get_net().edges,
4864
groupnames=['_private'],
4865
name='Route',
4866
info="The vehicle's route as a sequence of edge IDs.",
4867
))
4868
4869
def _init_constants_specific(self):
4870
net = self.get_virtualpop().get_net()
4871
self.id_mode_bike = net.modes.get_id_mode('bicycle')
4872
self.get_attrsman().do_not_save_attrs(['id_mode_bike', ])
4873
4874
def prepare_planning(self):
4875
pass
4876
4877
def append_stage(self, id_plan, time_start=-1.0, id_veh=-1,
4878
time_init=-1,
4879
id_edge_from=-1, id_edge_to=-1,
4880
position_edge_from=0.0, position_edge_to=0.0,
4881
is_route=True, route=-1, duration_approx=-1,
4882
**kwargs):
4883
"""
4884
Appends a ride stage to plan id_plan in case the ride is feasible.
4885
The ride is feasible if from parking and to parking are connected.
4886
4887
If feasible, the stage ID and estimated time when stage is finished
4888
will be returned.
4889
4890
If not feasible -1 and start time will be returned.
4891
"""
4892
# print 'BikeRides.append_stage',id_plan,time_start,time_init
4893
#edges = self.get_virtualpop().get_net().edges
4894
# check feasibility
4895
#route, dist, duration = self.get_route_between_parking(id_parking_from, id_parking_to)
4896
4897
# print ' id_edge_from, id_edge_to=',id_edge_from, id_edge_to
4898
4899
if is_route:
4900
duration_approx, route = routing.get_mincostroute_edge2edge(
4901
id_edge_from,
4902
id_edge_to,
4903
weights=self.get_times(self.id_mode_bike),
4904
fstar=self.get_fstar(self.id_mode_bike),
4905
)
4906
4907
#route = [edge_from]+route+[edge_to]
4908
4909
#dist = np.sum(edges.lengths[route])
4910
#dist = dist - pos_from - ( edges.lengths[id_edge_to] - pos_to)
4911
4912
if (len(route) > 0): # |(dist > self.dist_ride_min.get_value()): # is there a connection
4913
# create stage
4914
id_stage, time_end = StageTypeMixin.append_stage(self,
4915
id_plan,
4916
time_start,
4917
durations=duration_approx,
4918
times_init=time_init,
4919
ids_ibike=id_veh,
4920
ids_edge_from=id_edge_from,
4921
positions_from=position_edge_from,
4922
ids_edge_to=id_edge_to,
4923
positions_to=position_edge_to,
4924
ids_edges=route,
4925
)
4926
4927
# print ' route = ',route
4928
# print ' ids_edges = ',self.ids_edges[id_stage]
4929
# add this stage to the vehicle database
4930
# ind_ride gives the index of this ride (within the same plan??)
4931
#ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage)
4932
return id_stage, time_end
4933
4934
else:
4935
# not connected or too short of a distance
4936
return -1, time_start # no stage creation took place
4937
4938
def get_writexmlinfo(self, ids_plan, is_route=True, is_plain=False):
4939
print 'BikerideStages.get_writexmlinfo', len(ids_plan), is_plain
4940
ibikes = self.get_virtualpop().get_ibikes()
4941
bikewritefunc = ibikes.prepare_write_xml(is_plain=is_plain)
4942
ids = self.get_ids_from_ids_plan(ids_plan)
4943
4944
bikewritefuncs = np.zeros(len(ids), dtype=np.object)
4945
bikewritefuncs[:] = bikewritefunc
4946
return self.times_init[ids], bikewritefuncs, ids
4947
4948
def to_xml(self, id_stage, fd, indent=0):
4949
#lanes = self.parent.get_scenario().net.lanes
4950
scenario = self.get_virtualpop().get_scenario()
4951
4952
edges = scenario.net.edges
4953
edgeindex = edges.ids_sumo
4954
4955
#parking = scenario.landuse.parking
4956
4957
#ind = self.get_ind(id_stage)
4958
fd.write(xm.start('ride', indent=indent))
4959
4960
#id_edge_from, pos_from = parking.get_edge_pos_parking(self.ids_parking_from.value[ind])
4961
#id_edge_to, pos_to = parking.get_edge_pos_parking(self.ids_parking_to.value[ind])
4962
4963
# edgeindex.get_index_from_id(self.ids_edge_to.value[ind])
4964
id_edge_from = self.ids_edge_from[id_stage]
4965
fd.write(xm.num('from', edgeindex[self.ids_edge_from[id_stage]]))
4966
fd.write(xm.num('to', edgeindex[self.ids_edge_to[id_stage]]))
4967
fd.write(xm.num('lines', self.ids_ibike.get_linktab().get_id_line_xml(
4968
self.ids_ibike[id_stage]))) # mode specific
4969
4970
fd.write(xm.stopit()) # ends stage
4971
4972
4973
class MotorcyclerideStages(StageTypeMixin):
4974
4975
def __init__(self, ident, population,
4976
name='Motorcycle rides',
4977
info='Rides with privately owned motorcycle.',
4978
version=1.0,
4979
):
4980
4981
self.init_stagetable(ident, population, name=name, info=info)
4982
# print 'Rides.__init__',self.get_name()
4983
self._init_attributes()
4984
4985
def _init_attributes(self):
4986
# TODO: this structure needs review: the private vehicle is part of a person, not a stage
4987
# street parking at home and work could be in stage. Private garage is part of person...
4988
# print '_init_attributes',self.parent.get_iautos(), self.ident,self.parent.get_landuse().parking
4989
4990
self.add_col(am.IdsArrayConf('ids_imoto', self.get_virtualpop().get_imotos(),
4991
groupnames=['state'],
4992
name='ID moto',
4993
info='ID of private, individual motorcycle.',
4994
))
4995
4996
self.add_col(am.ArrayConf('times_init', -1.0,
4997
name='Init. time',
4998
unit='s',
4999
info='Initialization time, which is the time when the vehicle appears in the scenario. Value -1 means unknown.',
5000
))
5001
5002
edges = self.get_virtualpop().get_net().edges
5003
5004
self.add_col(am.IdsArrayConf('ids_edge_from', edges,
5005
groupnames=['state'],
5006
name='ID Dep. edge',
5007
info='Edge ID at departure of walk.',
5008
))
5009
5010
self.add_col(am.IdsArrayConf('ids_edge_to', edges,
5011
groupnames=['state'],
5012
name='ID Arr. edge',
5013
info='Edge ID where walk finishes.',
5014
))
5015
5016
self.add_col(am.ArrayConf('positions_from', 0.0,
5017
dtype=np.float32,
5018
#choices = OPTIONMAP_POS_DEPARTURE,
5019
perm='r',
5020
name='Depart pos',
5021
unit='m',
5022
info="Position on edge at the moment of departure.",
5023
#xmltag = 'departPos',
5024
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5025
))
5026
5027
self.add_col(am.ArrayConf('positions_to', 0.0,
5028
dtype=np.float32,
5029
#choices = OPTIONMAP_POS_ARRIVAL,
5030
perm='r',
5031
name='Arrival pos',
5032
unit='m',
5033
info="Position on edge at the moment of arrival.",
5034
#xmltag = 'arrivalPos',
5035
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5036
))
5037
5038
self.add_col(am.IdlistsArrayConf('ids_edges', self.get_virtualpop().get_net().edges,
5039
groupnames=['_private'],
5040
name='Route',
5041
info="The vehicle's route as a sequence of edge IDs.",
5042
))
5043
5044
def _init_constants_specific(self):
5045
net = self.get_virtualpop().get_net()
5046
self.id_mode_moto = net.modes.get_id_mode('motorcycle')
5047
self.get_attrsman().do_not_save_attrs(['id_mode_moto', ])
5048
5049
def prepare_planning(self):
5050
pass
5051
5052
def append_stage(self, id_plan, time_start=-1.0, id_veh=-1,
5053
time_init=-1,
5054
id_edge_from=-1, id_edge_to=-1,
5055
position_edge_from=0.0, position_edge_to=0.0,
5056
is_route=True, route=-1, duration_approx=-1,
5057
**kwargs):
5058
"""
5059
Appends a ride stage to plan id_plan in case the ride is feasible.
5060
The ride is feasible if from parking and to parking are connected.
5061
5062
If feasible, the stage ID and estimated time when stage is finished
5063
will be returned.
5064
5065
If not feasible -1 and start time will be returned.
5066
"""
5067
# print 'BikeRides.append_stage',id_plan,time_start,time_init
5068
#edges = self.get_virtualpop().get_net().edges
5069
# check feasibility
5070
#route, dist, duration = self.get_route_between_parking(id_parking_from, id_parking_to)
5071
5072
# print ' id_edge_from, id_edge_to=',id_edge_from, id_edge_to
5073
if is_route:
5074
duration_approx, route = routing.get_mincostroute_edge2edge(
5075
id_edge_from,
5076
id_edge_to,
5077
weights=self.get_times(self.id_mode_moto),
5078
fstar=self.get_fstar(self.id_mode_moto),
5079
)
5080
5081
#route = [edge_from]+route+[edge_to]
5082
5083
#dist = np.sum(edges.lengths[route])
5084
#dist = dist - pos_from - ( edges.lengths[id_edge_to] - pos_to)
5085
5086
if (len(route) > 0): # |(dist > self.dist_ride_min.get_value()): # is there a connection
5087
# create stage
5088
id_stage, time_end = StageTypeMixin.append_stage(self,
5089
id_plan,
5090
time_start,
5091
durations=duration_approx,
5092
times_init=time_init,
5093
ids_imoto=id_veh,
5094
ids_edge_from=id_edge_from,
5095
positions_from=position_edge_from,
5096
ids_edge_to=id_edge_to,
5097
positions_to=position_edge_to,
5098
ids_edges=route,
5099
)
5100
5101
# print ' route = ',route
5102
# print ' ids_edges = ',self.ids_edges[id_stage]
5103
# add this stage to the vehicle database
5104
# ind_ride gives the index of this ride (within the same plan??)
5105
#ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage)
5106
return id_stage, time_end
5107
5108
else:
5109
# not connected or too short of a distance
5110
return -1, time_start # no stage creation took place
5111
5112
def get_writexmlinfo(self, ids_plan, is_route=True, is_plain=False):
5113
print 'MotorcyclerideStages.get_writexmlinfo', len(ids_plan), is_plain
5114
imotos = self.get_virtualpop().get_imotos()
5115
motowritefunc = imotos.prepare_write_xml(is_plain=is_plain)
5116
ids = self.get_ids_from_ids_plan(ids_plan)
5117
5118
motowritefuncs = np.zeros(len(ids), dtype=np.object)
5119
motowritefuncs[:] = motowritefunc
5120
return self.times_init[ids], motowritefuncs, ids
5121
5122
def to_xml(self, id_stage, fd, indent=0):
5123
#lanes = self.parent.get_scenario().net.lanes
5124
scenario = self.get_virtualpop().get_scenario()
5125
5126
edges = scenario.net.edges
5127
edgeindex = edges.ids_sumo
5128
5129
#parking = scenario.landuse.parking
5130
5131
#ind = self.get_ind(id_stage)
5132
fd.write(xm.start('ride', indent=indent))
5133
5134
#id_edge_from, pos_from = parking.get_edge_pos_parking(self.ids_parking_from.value[ind])
5135
#id_edge_to, pos_to = parking.get_edge_pos_parking(self.ids_parking_to.value[ind])
5136
5137
# edgeindex.get_index_from_id(self.ids_edge_to.value[ind])
5138
id_edge_from = self.ids_edge_from[id_stage]
5139
fd.write(xm.num('from', edgeindex[self.ids_edge_from[id_stage]]))
5140
fd.write(xm.num('to', edgeindex[self.ids_edge_to[id_stage]]))
5141
fd.write(xm.num('lines', self.ids_imoto.get_linktab().get_id_line_xml(
5142
self.ids_imoto[id_stage]))) # mode specific
5143
5144
fd.write(xm.stopit()) # ends stage
5145
5146
5147
class TaxirideStages(StageTypeMixin):
5148
5149
def __init__(self, ident, population,
5150
name='Taxi rides',
5151
info='Rides with Taxi.',
5152
version=1.0,
5153
):
5154
5155
self.init_stagetable(ident, population, name=name, info=info)
5156
# print 'Rides.__init__',self.get_name()
5157
self._init_attributes()
5158
5159
def _init_attributes(self):
5160
5161
self.add_col(am.ArrayConf('times_init', -1.0,
5162
name='Init. time',
5163
unit='s',
5164
info='Initialization time, which is the time when the vehicle appears in the scenario. Value -1 means unknown.',
5165
))
5166
5167
edges = self.get_virtualpop().get_net().edges
5168
5169
self.add_col(am.IdsArrayConf('ids_edge_from', edges,
5170
groupnames=['state'],
5171
name='ID Dep. edge',
5172
info='Edge ID at departure of walk.',
5173
))
5174
5175
self.add_col(am.IdsArrayConf('ids_edge_to', edges,
5176
groupnames=['state'],
5177
name='ID Arr. edge',
5178
info='Edge ID where walk finishes.',
5179
))
5180
5181
self.add_col(am.ArrayConf('positions_from', 0.0,
5182
dtype=np.float32,
5183
#choices = OPTIONMAP_POS_DEPARTURE,
5184
perm='r',
5185
name='Depart pos',
5186
unit='m',
5187
info="Position on edge at the moment of departure.",
5188
#xmltag = 'departPos',
5189
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5190
))
5191
5192
self.add_col(am.ArrayConf('positions_to', 0.0,
5193
dtype=np.float32,
5194
#choices = OPTIONMAP_POS_ARRIVAL,
5195
perm='r',
5196
name='Arrival pos',
5197
unit='m',
5198
info="Position on edge at the moment of arrival.",
5199
#xmltag = 'arrivalPos',
5200
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5201
))
5202
5203
def _init_constants_specific(self):
5204
net = self.get_virtualpop().get_net()
5205
self.id_mode_taxi = net.modes.get_id_mode('taxi')
5206
self.get_attrsman().do_not_save_attrs(['id_mode_taxi', ])
5207
5208
def prepare_planning(self):
5209
pass
5210
5211
def append_stage(self, id_plan, time_start=-1.0,
5212
time_init=-1,
5213
id_edge_from=-1, id_edge_to=-1,
5214
position_edge_from=0.0, position_edge_to=0.0,
5215
duration_approx=-1,
5216
is_route=True,
5217
route=[],
5218
**kwargs):
5219
"""
5220
Appends a ride stage to plan id_plan in case the ride is feasible.
5221
5222
5223
If feasible, the stage ID and estimated time when stage is finished
5224
will be returned.
5225
5226
If not feasible -1 and start time will be returned.
5227
"""
5228
5229
# print ' id_edge_from, id_edge_to=',id_edge_from, id_edge_to
5230
if is_route:
5231
duration_approx, route = routing.get_mincostroute_edge2edge(
5232
id_edge_from,
5233
id_edge_to,
5234
weights=self.get_times(self.id_mode_taxi),
5235
fstar=self.get_fstar(self.id_mode_taxi),
5236
)
5237
5238
if (len(route) > 0): # |(dist > self.dist_ride_min.get_value()): # is there a connection
5239
# create stage
5240
id_stage, time_end = StageTypeMixin.append_stage(self,
5241
id_plan,
5242
time_start,
5243
durations=duration_approx,
5244
times_init=time_init,
5245
ids_edge_from=id_edge_from,
5246
positions_from=position_edge_from,
5247
ids_edge_to=id_edge_to,
5248
positions_to=position_edge_to,
5249
)
5250
5251
# print ' route = ',route
5252
# print ' ids_edges = ',self.ids_edges[id_stage]
5253
# add this stage to the vehicle database
5254
# ind_ride gives the index of this ride (within the same plan??)
5255
#ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage)
5256
return id_stage, time_end
5257
5258
else:
5259
# not connected or too short of a distance
5260
return -1, time_start # no stage creation took place
5261
5262
def to_xml(self, id_stage, fd, indent=0):
5263
scenario = self.get_virtualpop().get_scenario()
5264
5265
edges = scenario.net.edges
5266
edgeindex = edges.ids_sumo
5267
5268
fd.write(xm.start('ride', indent=indent))
5269
5270
id_edge_from = self.ids_edge_from[id_stage]
5271
fd.write(xm.num('from', edgeindex[self.ids_edge_from[id_stage]]))
5272
fd.write(xm.num('to', edgeindex[self.ids_edge_to[id_stage]]))
5273
fd.write(xm.num('lines', 'taxi')) # mode specific
5274
5275
fd.write(xm.stopit()) # ends stage
5276
5277
5278
class WalkStages(StageTypeMixin):
5279
def __init__(self, ident, stages, name='WalkStages',
5280
info='walk from a position on a lane to another position of another lane.'):
5281
5282
self.init_stagetable(ident, stages, name=name, info=info)
5283
5284
edges = self.get_virtualpop().get_scenario().net.edges
5285
self.add_col(am.IdsArrayConf('ids_edge_from', edges,
5286
groupnames=['state'],
5287
name='ID Dep. edge',
5288
info='Edge ID at departure of walk.',
5289
))
5290
5291
self.add_col(am.IdsArrayConf('ids_edge_to', edges,
5292
groupnames=['state'],
5293
name='ID Arr. edge',
5294
info='Edge ID where walk finishes.',
5295
))
5296
5297
self.add_col(am.ArrayConf('positions_from', 0.0,
5298
dtype=np.float32,
5299
#choices = OPTIONMAP_POS_DEPARTURE,
5300
perm='r',
5301
name='Depart pos',
5302
unit='m',
5303
info="Position on edge at the moment of departure.",
5304
#xmltag = 'departPos',
5305
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5306
))
5307
self.positions_from.set_xmltag(None)
5308
5309
self.add_col(am.ArrayConf('positions_to', 0.0,
5310
dtype=np.float32,
5311
#choices = OPTIONMAP_POS_ARRIVAL,
5312
perm='r',
5313
name='Arrival pos',
5314
unit='m',
5315
info="Position on edge at the moment of arrival.",
5316
#xmltag = 'arrivalPos',
5317
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5318
))
5319
5320
self.positions_to.set_xmltag(None)
5321
5322
def append_stage(self, id_plan, time_start=-1.0,
5323
id_edge_from=-1, id_edge_to=-1,
5324
position_edge_from=0.1, position_edge_to=0.0,
5325
**kwargs):
5326
# print 'WalkStages.append_stage',id_stage
5327
if kwargs.has_key('duration'):
5328
duration = kwargs['duration']
5329
else:
5330
dist, duration = self.plan_walk(id_edge_from, id_edge_to,
5331
position_edge_from, position_edge_to)
5332
5333
id_stage, time_end = StageTypeMixin.append_stage(self,
5334
id_plan,
5335
time_start,
5336
durations=duration,
5337
ids_edge_from=id_edge_from,
5338
ids_edge_to=id_edge_to,
5339
positions_from=position_edge_from,
5340
positions_to=position_edge_to,
5341
)
5342
5343
return id_stage, time_end
5344
5345
def modify_stage(self, id_stage, time_start=None,
5346
id_edge_from=-1, id_edge_to=-1,
5347
position_edge_from=0.1, position_edge_to=0.0):
5348
5349
dist, duration = self.plan_walk(id_edge_from, id_edge_to,
5350
position_edge_from, position_edge_to)
5351
5352
time_end = StageTypeMixin.modify_stage(self, id_stage, time_start,
5353
durations=duration,
5354
ids_edge_from=id_edge_from,
5355
ids_edge_to=id_edge_to,
5356
positions_from=position_edge_from,
5357
positions_to=position_edge_to,
5358
)
5359
5360
return time_end
5361
5362
def plan_walk(self, id_edge_from, id_edge_to, pos_from, pos_to, id_mode=1):
5363
"""
5364
Routing for pedestrians.
5365
Currently limited to estimation of line of sight distance
5366
and walk time.
5367
"""
5368
# print 'plan_walk',id_edge_from, id_edge_to,id_mode, pos_from, pos_to
5369
scenario = self.get_virtualpop().get_scenario()
5370
edges = scenario.net.edges
5371
5372
coord_from = edges.get_coord_from_pos(id_edge_from, pos_from)
5373
coord_to = edges.get_coord_from_pos(id_edge_to, pos_to)
5374
5375
# from lanes, more precis, but less efficient and less robust
5376
# lanes = scenario.net.lanes
5377
#coord_from = lanes.get_coord_from_pos(edges.ids_lane[id_edge_from][0], pos_from)
5378
#coord_to = lanes.get_coord_from_pos(edges.ids_lane[id_edge_to][0], pos_to)
5379
5380
# print ' coord_from',coord_from,type(coord_from)
5381
# print ' coord_to',coord_from,type(coord_to)
5382
# print ' delta',coord_to-coord_from
5383
# line of sight distance
5384
dist = np.sqrt(np.sum((coord_to-coord_from)**2))
5385
5386
duration_approx = dist/scenario.net.modes.speeds_max[id_mode]
5387
# print ' dist,duration',dist,duration_approx,scenario.net.modes.speeds_max[id_mode]
5388
5389
return dist, duration_approx
5390
5391
def to_xml(self, id_stage, fd, indent=0):
5392
#scenario = self.parent.get_scenario()
5393
#edges = scenario.net.edges
5394
edges = self.ids_edge_from.get_linktab()
5395
edgeindex = edges.ids_sumo
5396
5397
ind = self.get_ind(id_stage)
5398
5399
id_edge_from = self.ids_edge_from.value[ind]
5400
id_edge_to = self.ids_edge_to.value[ind]
5401
fd.write(xm.start('walk', indent=indent))
5402
fd.write(xm.num('from', edgeindex[id_edge_from]))
5403
fd.write(xm.num('to', edgeindex[id_edge_to]))
5404
5405
pos = self.positions_from.value[ind]
5406
length = max(edges.lengths[id_edge_from]-4.0, 0.0)
5407
5408
# depricated
5409
# if (pos>0) & (pos < length ):
5410
# fd.write(xm.num('departPos', pos))
5411
#
5412
# elif pos < 0:
5413
# fd.write(xm.num('departPos', 0.0))
5414
#
5415
# else:
5416
# fd.write(xm.num('departPos', length))
5417
5418
pos = self.positions_to.value[ind]
5419
length = max(edges.lengths[id_edge_to]-4.0, 0.0)
5420
if (pos > 0) & (pos < length):
5421
fd.write(xm.num('arrivalPos', pos))
5422
5423
elif pos < 0:
5424
fd.write(xm.num('arrivalPos', 0.0))
5425
5426
else:
5427
fd.write(xm.num('arrivalPos', length))
5428
5429
fd.write(xm.stopit()) # ends walk
5430
5431
5432
class ActivityStages(StageTypeMixin):
5433
def __init__(self, ident, stages, name='Activities'):
5434
self.init_stagetable(ident, stages, name=name, info='Do some activity at a position of a lane.')
5435
5436
self._init_attributes()
5437
5438
def _init_attributes(self):
5439
5440
# TODO: this structure needs review: the private vehicle is part of a person, not a stage
5441
# street parking at home and work could be in stage. Private garage is part of person...
5442
5443
activities = self.get_virtualpop().get_activities()
5444
self.add_col(am.IdsArrayConf('ids_activity', activities,
5445
groupnames=['parameters'],
5446
name='Activity ID',
5447
info='Scheduled activity ID. This is the activity which schould be carried out in this stage.',
5448
))
5449
5450
# this is redundant information but here for speed when writing xml
5451
self.add_col(am.ArrayConf('names_activitytype', '',
5452
groupnames=['parameters'],
5453
dtype=np.object,
5454
perm='r',
5455
name='Type name',
5456
info="Name of activity type.",
5457
xmltag='actType',
5458
#xmlmap = get_inversemap( activitytypes.names.get_indexmap()),
5459
))
5460
5461
# self.add_col(am.IdsArrayConf( 'ids_facility', self.get_virtualpop().get_landuse().facilities,
5462
# groupnames = ['parameters'],
5463
# name = 'ID facility',
5464
# info = 'Facility where activity takes place.',
5465
# ))
5466
5467
# lane and position can be computed from facility
5468
self.add_col(am.IdsArrayConf('ids_lane', self.get_virtualpop().get_net().lanes,
5469
groupnames=['parameters'],
5470
name='Lane ID',
5471
info='Lane ID where activity takes place.',
5472
#xmltag = 'lane',
5473
))
5474
# for update..can be removed
5475
self.ids_lane.set_xmltag(None)
5476
5477
self.add_col(am.ArrayConf('positions', 0.0,
5478
groupnames=['parameters'],
5479
dtype=np.float32,
5480
perm='r',
5481
name='Lane pos',
5482
unit='m',
5483
info="Position on lane nearby where activity takes place.",
5484
#xmltag = 'startPos',
5485
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5486
))
5487
5488
self.positions.set_xmltag(None)
5489
5490
self.add_col(am.ArrayConf('durations', 0.0,
5491
groupnames=['parameters'],
5492
dtype=np.int32,
5493
perm='r',
5494
name='Duration',
5495
unit='s',
5496
info="Duration of activity.",
5497
xmltag='duration',
5498
#xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL),
5499
))
5500
5501
self.durations.set_xmltag('duration')
5502
5503
def get_edges_positions(self, ids_stage):
5504
"""
5505
Returns road edge and positions of activity.
5506
"""
5507
return self.ids_lane.get_linktab().ids_edge[self.ids_lane[ids_stage]],\
5508
self.positions[ids_stage]
5509
5510
def _init_constants(self):
5511
#self._activities = self.get_virtualpop().get_activities()
5512
#self._activitytypes = self.get_virtualpop().get_demand().activitytypes
5513
# self.do_not_save_attrs(['_activities','_activitytypes'])
5514
pass
5515
5516
# def del_row(self, id_stage):
5517
# # actually this should no happen, activities should not be
5518
# # copied for each plan
5519
# print 'ActivityStages.del_row id_stage',id_stage,'id_activity',self.ids_activity[id_stage]
5520
# self.get_virtualpop().get_activities().del_row(self.ids_activity[id_stage])
5521
# am.ArrayObjman.del_row(self, id_stage)
5522
5523
def to_xml(self, id_stage, fd, indent=0):
5524
5525
# <stop lane="1/4to2/4_0" duration="20" startPos="40" actType="singing"/>
5526
5527
#ind = self.get_ind(id_stage)
5528
fd.write(xm.start('stop', indent=indent))
5529
5530
lanes = self.get_virtualpop().get_net().lanes
5531
id_lane = self.ids_lane[id_stage]
5532
# get all xml configs and damp to fd
5533
for attrconf in self.get_group('parameters'):
5534
# this will write only if a xmltag is defined
5535
attrconf.write_xml(fd, id_stage)
5536
fd.write(xm.num('lane', lanes.get_id_sumo(id_lane)))
5537
#fd.write(xm.num('duration', self.durations[id_stage]))
5538
5539
pos = self.positions[id_stage]
5540
length = max(lanes.get_lengths(id_lane)-4.0, 0.0)
5541
5542
if (pos > 0) & (pos < length):
5543
fd.write(xm.num('startPos', pos))
5544
5545
elif pos < 0:
5546
fd.write(xm.num('startPos', 0.0))
5547
5548
else:
5549
fd.write(xm.num('startPos', length))
5550
5551
#fd.write(xm.num('lane', self.cols.id_lane[ind]))
5552
#fd.write(xm.num('startPos', self.cols.pos_lane[ind]))
5553
#fd.write(xm.num('duration', self.cols.duration[ind]))
5554
# fd.write(xm.num('actType', self._activitytypes.names[self._activities.)
5555
5556
fd.write(xm.stopit()) # ends activity
5557
5558
5559
class Plans(am.ArrayObjman):
5560
def __init__(self, population, **kwargs):
5561
"""Plans database."""
5562
self._init_objman(ident='plans',
5563
parent=population,
5564
name='Plans',
5565
info='Mobility plan for virtual population.',
5566
#xmltag = ('plans','plan',None),
5567
version=0.1,
5568
**kwargs)
5569
5570
self._init_attributes()
5571
self._init_constants()
5572
5573
def _init_attributes(self):
5574
5575
# upgrade
5576
if self.get_version() < 0.1:
5577
pass
5578
5579
self.set_version(0.1)
5580
persons = self.parent
5581
5582
#self.add(cm.ObjConf(StageTables('stagetables',self)) )
5583
5584
self.add_stagetable('walks', WalkStages)
5585
self.add_stagetable('autorides', AutorideStages)
5586
self.add_stagetable('bikerides', BikerideStages)
5587
self.add_stagetable('motorides', MotorcyclerideStages)
5588
self.add_stagetable('transits', TransitStages)
5589
self.add_stagetable('taxirides', TaxirideStages)
5590
self.add_stagetable('activities', ActivityStages)
5591
5592
self.add_col(am.IdsArrayConf('ids_person', persons,
5593
groupnames=['links'],
5594
name='Person ID',
5595
info='Person ID to who this plan belongs to.',
5596
))
5597
5598
self.add_col(am.IdsArrayConf('ids_strategy', persons.get_strategies(),
5599
groupnames=['links'],
5600
name='Stategy ID',
5601
info='Stategy ID with which this plan has been generated.',
5602
))
5603
5604
self.add_col(am.ArrayConf('times_begin', -np.inf,
5605
dtype=np.float32,
5606
name='Begin time',
5607
info='Time when active travelling begins. This is the time in the simulation when the person appears. The first activity is not simulated.',
5608
unit='s',
5609
))
5610
5611
self.add_col(am.ArrayConf('times_end', -np.inf,
5612
dtype=np.float32,
5613
name='End time',
5614
info='Time when active travelling ends. This is the time in the simulation when the person disappears. The last activity is not simulated.',
5615
unit='s',
5616
))
5617
5618
self.add_col(am.ArrayConf('times_est', 0.0,
5619
dtype=np.float32,
5620
name='Estim. time',
5621
info='Estimated time duration to execute travel plan. Activity times are excluded.',
5622
unit='s',
5623
))
5624
5625
self.add_col(am.ArrayConf('times_exec', 0.0,
5626
dtype=np.float32,
5627
name='Exec. time',
5628
info='Last plan execution time from simulation run.',
5629
unit='s',
5630
))
5631
5632
self.add_col(am.ArrayConf('utilities', 0.0,
5633
dtype=np.float32,
5634
name='utility',
5635
info='Utility of plan.',
5636
))
5637
5638
self.add_col(am.ArrayConf('probabilities', 1.0,
5639
dtype=np.float32,
5640
name='Probability',
5641
info='Probability that the plan is selected out of all plans available for one person.',
5642
))
5643
5644
self.add_col(am.TabIdListArrayConf('stagelists',
5645
name='Stages',
5646
info='Sequence of stages of this plan.',
5647
))
5648
5649
def _init_constants(self):
5650
#self._id_mode_bike = self.parent.get_scenario().net.modes.get_id_mode('bicycle')
5651
# self.do_not_save_attrs([])
5652
pass
5653
5654
def clear_plans(self):
5655
print 'Plans.clear_plans'
5656
for stagetable in self.get_stagetables():
5657
# print ' stagetable',stagetable
5658
stagetable.clear()
5659
5660
self.clear_rows()
5661
# for attrconfig in self.get_attrsman().get_colconfigs():
5662
# print ' clear attrconfig',attrconfig.attrname
5663
# attrconfig.clear()
5664
# no: self.clear()
5665
5666
def add_stagetable(self, ident, StagesClass, **kwargs):
5667
if not hasattr(self, ident):
5668
self.add(cm.ObjConf(StagesClass(ident, self, **kwargs),
5669
groupnames=['stagetables']))
5670
return getattr(self, ident).get_value()
5671
5672
def get_stagetable(self, ident):
5673
return getattr(self, ident).get_value()
5674
5675
def get_stagetables(self):
5676
"""Return a list of with all stage objects"""
5677
stageobjs = []
5678
# print 'get_stagetables',self.get_group('stagetables')
5679
for stageobj in self.get_group('stagetables'):
5680
stageobjs.append(stageobj)
5681
return stageobjs
5682
5683
def prepare_stagetables(self, idents_stagetable):
5684
# print 'prepare_stages',stagenames
5685
#ids = self.names.get_ids_from_indices_save(stagenames)
5686
# print ' ids',ids
5687
# print ' self.stagetables[ids]',self.stagetables[ids]
5688
for indent in idents_stagetable:
5689
self.get_stagetable(indent).prepare_planning()
5690
5691
def get_stages(self, id_plan):
5692
stages = self.stagelists[id_plan]
5693
if stages is None:
5694
return []
5695
else:
5696
return stages
5697
5698
def append_stage(self, id_plan, stage, id_stage):
5699
# test: stage = cm.TableEntry(stagetable, id_plan)
5700
# print 'Plans.append_stage',self,id_plan, stage, id_stage
5701
5702
if self.stagelists[id_plan] is None:
5703
self.stagelists[id_plan] = [(stage, id_stage)]
5704
else:
5705
self.stagelists[id_plan].append((stage, id_stage))
5706
# print ' after append stagelists[id_plan]',type(self.stagelists[id_plan]),self.stagelists[id_plan]
5707
5708
# def prepare_stages(self,stagenames):
5709
# self.get_stagetables().prepare_stages(stagenames)
5710
5711
def get_timing_laststage(self, id_plan):
5712
"""
5713
Return time_start and duration of last stage of plan id_plan
5714
"""
5715
stages_current = self.stagelists[id_plan]
5716
5717
if stages_current is not None:
5718
stage_last, id_stage_last = stages_current[-1]
5719
return stage_last.get_timing(id_stage_last)
5720
else:
5721
return -1, -1
5722
5723
5724
class Virtualpopulation(DemandobjMixin, am.ArrayObjman):
5725
def __init__(self, ident, demand, **kwargs):
5726
self._init_objman(ident=ident,
5727
parent=demand,
5728
name='Virtual population',
5729
info='Contains information of each individual of the virtual population.',
5730
version=0.2, # only for new scenarios
5731
**kwargs)
5732
self._init_attributes()
5733
self._init_constants()
5734
5735
def _init_attributes(self):
5736
5737
# update here
5738
5739
#
5740
self.set_version(0.2)
5741
5742
demand = self.parent
5743
scenario = demand.get_scenario()
5744
5745
# --------------------------------------------------------------------
5746
# individual vehicles tables
5747
5748
self.add(cm.ObjConf(IndividualAutos('iautos', self)))
5749
self.add(cm.ObjConf(IndividualBikes('ibikes', self)))
5750
self.add(cm.ObjConf(IndividualMotorcycles('imotos', self)))
5751
5752
# --------------------------------------------------------------------
5753
# activity table
5754
#self.add(cm.ObjConf(ActivityTypes('activitytypes', self)) )
5755
self.add(cm.ObjConf(Activities('activities', self)))
5756
5757
# --------------------------------------------------------------------
5758
# strategies table (must be before plans)
5759
5760
self.add(cm.ObjConf(Strategies('strategies', self)))
5761
5762
# --------------------------------------------------------------------
5763
# plans table
5764
self.add(cm.ObjConf(Plans(self)))
5765
5766
self.get_strategies().add_default()
5767
5768
# ===================================================================
5769
# Add person attributes
5770
5771
# --------------------------------------------------------------------
5772
# socio economic parameters
5773
self.add_col(am.ArrayConf('identifications', '',
5774
dtype=np.object,
5775
groupnames=['socioeconomic'],
5776
name='Name',
5777
info='Identification or name of person. Does not need to be unique.',
5778
))
5779
5780
self.add_col(am.ArrayConf('ids_gender', default=-1,
5781
dtype=np.int32,
5782
groupnames=['socioeconomic'],
5783
choices=GENDERS,
5784
name='Gender',
5785
info='Gender of person.',
5786
))
5787
5788
self.add_col(am.ArrayConf('years_birth', default=-1,
5789
dtype=np.int32,
5790
groupnames=['socioeconomic'],
5791
name='Birth year',
5792
info='Year when person has been born.',
5793
))
5794
5795
self.add_col(am.ArrayConf('ids_occupation', default=OCCUPATIONS['unknown'],
5796
dtype=np.int32,
5797
choices=OCCUPATIONS,
5798
groupnames=['socioeconomic'],
5799
name='Occupation',
5800
info='Type of occupation.',
5801
))
5802
5803
# --------------------------------------------------------------------
5804
# household parameters
5805
self.add_col(am.ArrayConf('numbers_houehold', default=1,
5806
dtype=np.int32,
5807
groupnames=['household'],
5808
name='Number in household',
5809
info='Number of persons in household.',
5810
))
5811
5812
self.add_col(am.ArrayConf('numbers_minor', default=0,
5813
dtype=np.int32,
5814
groupnames=['household'],
5815
name='Number minors',
5816
info='Number of minor in household. In the context of traffic simulations minors are persons who need to be accompaigned by adulds when travelling.',
5817
))
5818
5819
# --------------------------------------------------------------------
5820
# activity parameters
5821
# lists with activity patterns
5822
5823
self.add_col(am.IdlistsArrayConf('activitypatterns', self.activities.get_value(),
5824
groupnames=['activity'],
5825
name='Activity IDs',
5826
info="Sequence of activity IDs to be accomplished by the person.",
5827
))
5828
5829
# --------------------------------------------------------------------
5830
# mobility parameters
5831
# --------------------------------------------------------------------
5832
5833
# give a pedestrian vtype to each person
5834
vtypes = self.get_demand().vtypes
5835
self.add_col(am.IdsArrayConf('ids_vtype', vtypes,
5836
id_default=vtypes.select_by_mode(mode='pedestrian')[0],
5837
groupnames=['mobility'],
5838
name='Ped. type',
5839
info='The pedestrian type ID specifies the walking characteristics and visual representation of the person. In SUMO terminology, this is the vehicle type.',
5840
#xmltag = 'type',
5841
))
5842
5843
self.add_col(am.ArrayConf('traveltimebudgets', default=55*60,
5844
dtype=np.int32,
5845
groupnames=['mobility'],
5846
name='time budget',
5847
unit='s',
5848
info='Daily time budget used for traveling.',
5849
))
5850
5851
self.add_col(am.IdsArrayConf('ids_mode_preferred', scenario.net.modes,
5852
groupnames=['mobility'],
5853
name='ID preferred mode',
5854
info='ID of preferred transport mode of person.',
5855
))
5856
5857
self.add_col(am.IdsArrayConf('ids_iauto', self.get_iautos(),
5858
groupnames=['mobility'],
5859
name='ID auto',
5860
info='ID of individual auto. Negative value means no bile available.',
5861
))
5862
5863
self.add_col(am.IdsArrayConf('ids_ibike', self.get_ibikes(),
5864
groupnames=['mobility'],
5865
name='ID bike',
5866
info='ID of individual bicycle. Negative value means no bike available.',
5867
))
5868
5869
self.add_col(am.IdsArrayConf('ids_imoto', self.get_imotos(),
5870
groupnames=['mobility'],
5871
name='ID motorcycle',
5872
info='ID of individual motorcycle. Negative value means no motorcycle available.',
5873
))
5874
5875
self.add_col(am.ArrayConf('dists_walk_max', default=400.0,
5876
dtype=np.float32,
5877
groupnames=['mobility'],
5878
name='Max. walk dist',
5879
info='Maximum acceptable walking distance between origin and destination or for transfers between modes.',
5880
))
5881
5882
# --------------------------------------------------------------------
5883
# plans
5884
self.add_col(am.IdsArrayConf('ids_plan', self.get_plans(),
5885
groupnames=['plans'],
5886
name='ID Plan',
5887
info='Currently selected mobility plan ID of person. This is the plan which will be simulated.',
5888
))
5889
5890
self.add_col(am.IdlistsArrayConf('lists_ids_plan', self.get_plans(),
5891
groupnames=['plans'],
5892
name='Plan IDs',
5893
info='List with alternative, feasible mobility plan IDs for each person.',
5894
))
5895
5896
def _init_constants(self):
5897
modes = self.get_scenario().net.modes
5898
self.id_mode_bike = modes.get_id_mode('bicycle')
5899
self.id_mode_auto = modes.get_id_mode('passenger')
5900
self.id_mode_moto = modes.get_id_mode('motorcycle')
5901
self._edges = self.get_net().edges
5902
self.do_not_save_attrs(['id_mode_bike', 'id_mode_auto', 'id_mode_moto',
5903
'_edges'])
5904
5905
def get_demand(self):
5906
return self.parent
5907
5908
def clear_population(self):
5909
# self.clear()
5910
self.clear_plans()
5911
self.clear_ivehicles()
5912
self.get_activities().clear_rows()
5913
# TODO: this should disappear
5914
self.get_landuse().parking.clear_booking()
5915
5916
# for attrconfig in self.get_attrsman().get_colconfigs():
5917
# attrconfig.clear()
5918
self.clear_rows()
5919
5920
def del_persons(self, ids_pers_delete):
5921
print 'delete', len(ids_pers_delete), 'persons'
5922
ids_plans_all = set()
5923
ids_activity_del = set()
5924
lists_ids_plan = self.lists_ids_plan[ids_pers_delete]
5925
for id_pers, ids_plan in zip(ids_pers_delete, self.lists_ids_plan[ids_pers_delete]):
5926
ids_plans_all.update(ids_plan)
5927
for stageinfo in self.get_plans().stagelists[ids_plan]:
5928
for stages, id_stage in stageinfo:
5929
# print ' id_pers ',id_pers,'del',stages,'id_stage',id_stage,stages.__class__,id_stage,stages.__class__== ActivityStages
5930
5931
# if stages.__class__ == ActivityStages:
5932
# print ' ids_activity',stages.ids_activity[id_stage]
5933
# ids_activity_del.add(stages.ids_activity[id_stage])
5934
5935
stages.del_row(id_stage)
5936
# print ' check',id_stage in stages
5937
5938
ids_plans_delete_all = list(ids_plans_all)
5939
# print 'len(plans)', len(plans),'delete ',len(ids_plans_delete_all)
5940
self.get_plans().del_rows(ids_plans_delete_all)
5941
# print ' ',len(self.get_activities()),'activities'
5942
#ids_activity_del = []
5943
for ids_activity in self.activitypatterns[ids_pers_delete]:
5944
ids_activity_del.update(ids_activity)
5945
5946
ids_activity_del = list(ids_activity_del)
5947
# print ' del',len(ids_activity_del),'of',len(self.get_activities()),'activities'
5948
self.get_activities().del_rows(ids_activity_del)
5949
5950
self.get_iautos().del_rows(self.ids_iauto[ids_pers_delete])
5951
self.get_ibikes().del_rows(self.ids_ibike[ids_pers_delete])
5952
self.get_imotos().del_rows(self.ids_imoto[ids_pers_delete])
5953
5954
# print 'len(virtualpop)', len(virtualpop),'delete ',len(ids_pers_delete)
5955
self.del_rows(ids_pers_delete)
5956
5957
def clear_plans(self):
5958
# print 'clear_plans',self.get_stagetables()
5959
self.ids_plan.reset()
5960
self.lists_ids_plan.reset()
5961
self.get_plans().clear_plans()
5962
5963
# TODO: this should disappear
5964
self.get_landuse().parking.clear_booking()
5965
5966
def clear_ivehicles(self):
5967
"""
5968
Clear all individually owned vehicles.
5969
"""
5970
print 'clear_ivehicles'
5971
self.get_iautos().clear_vehicles()
5972
self.get_ibikes().clear_vehicles()
5973
self.get_imotos().clear_vehicles()
5974
5975
def get_activities(self):
5976
return self.activities.get_value()
5977
5978
def get_strategies(self):
5979
return self.strategies.get_value()
5980
5981
def get_plans(self):
5982
return self.plans.get_value()
5983
5984
def get_iautos(self):
5985
return self.iautos.get_value()
5986
5987
def get_ibikes(self):
5988
return self.ibikes.get_value()
5989
5990
def get_imotos(self):
5991
return self.imotos.get_value()
5992
5993
def get_stagetables(self):
5994
return self.get_plans().get_stagetables()
5995
5996
def get_landuse(self):
5997
return self.parent.get_scenario().landuse
5998
5999
def get_scenario(self):
6000
return self.parent.get_scenario()
6001
6002
def get_net(self):
6003
return self.parent.get_scenario().net
6004
6005
def get_ptlines(self):
6006
return self.get_demand().ptlines
6007
6008
def get_ptstops(self):
6009
return self.get_net().ptstops
6010
6011
def get_id_sumo_from_id(self, id_sumo):
6012
return u'vp.%s' % id_sumo
6013
6014
def get_id_from_id_sumo(self, id_veh_sumo):
6015
if len(id_veh_sumo.split('.')) == 2:
6016
prefix, id_pers = id_veh_sumo.split('.')
6017
if prefix == 'vp':
6018
return int(id_pers)
6019
else:
6020
return -1
6021
return -1
6022
6023
def get_ids_from_ids_sumo(self, ids_sumo):
6024
ids = np.zeros(len(ids_sumo), dtype=int32)
6025
for id_sumo in ids_sumo:
6026
ids[i] = self.get_id_from_id_sumo(id_sumo)
6027
return ids
6028
6029
def get_time_depart_first(self):
6030
# print 'Virtualpop.get_time_depart_first'
6031
if len(self.get_plans()) > 0:
6032
plans = self.get_plans()
6033
ids = self.select_ids(self.ids_plan.get_value() >= 0)
6034
# print ' ids',ids
6035
return float(np.min(plans.times_begin[self.ids_plan[ids]]))
6036
else:
6037
return 0.0
6038
6039
def get_time_depart_last(self):
6040
if len(self.get_plans()) > 0:
6041
# todo: this can be improved by adding plan execution time
6042
plans = self.get_plans()
6043
ids = self.select_ids(self.ids_plan.get_value() >= 0)
6044
6045
return float(np.max(plans.times_end[self.ids_plan[ids]]))
6046
else:
6047
return 0.0
6048
6049
# def add_stagetable(self,ident,StageClass, **kwargs):
6050
# print 'add_stagetable',ident,StageClass#,kwargs
6051
# if not hasattr(self,ident):
6052
# #print ' StageClass',StageClass(ident, self, **kwargs)
6053
# #print ' ObjConf',cm.ObjConf(StageClass(ident, self, **kwargs), goupnames = ['stages'])
6054
# self.add(cm.ObjConf(StageClass(ident, self, **kwargs), goupnames = ['stages']) )
6055
# return getattr(self, ident).get_value()
6056
6057
# def get_stagetable(self, ident):
6058
# return getattr(self, ident).get_value()
6059
6060
# def get_stagetables(self):
6061
# """Return a list of with all stage objects"""
6062
# stageobjs = []
6063
# #print 'get_stagetables',self.get_group('stages')
6064
# for stageobj in self.get_group('stages'):
6065
# stageobjs.append(stageobj)
6066
# return stageobjs
6067
6068
def make_multiple(self, n, **kwargs):
6069
return self.add_rows(n=n, **kwargs)
6070
6071
def disaggregate_odflow(self, time_start, time_end, id_mode,
6072
ids_fac,
6073
probs_fac_orig, probs_fac_dest,
6074
tripnumber_tot,
6075
id_activitytype_orig,
6076
id_activitytype_dest,
6077
hour_begin_earliest_orig,
6078
hour_begin_earliest_dest,
6079
hour_begin_latest_orig,
6080
hour_begin_latest_dest,
6081
duration_min_orig,
6082
duration_min_dest,
6083
duration_max_orig,
6084
duration_max_dest,
6085
scale=1.0,
6086
hour_offset=8.0, # 08:00
6087
hour_tripbudget=25.0/60, # 25min
6088
dist_walk_max=400, # scalar!
6089
**kwargs
6090
):
6091
"""
6092
Disaggregation of demand dem from taz id_zone_orig to id_zone_dest with id_mode
6093
during time interval time_start,time_end, and creation of persons
6094
which are parameterized accordingly.
6095
The facility type at origin will be landusetype_orig
6096
and at destination landusetype_dest.
6097
6098
6099
"""
6100
tripnumber = int(scale*tripnumber_tot)
6101
print 'disaggregate_odflow', time_start, time_end, id_mode, tripnumber
6102
6103
print ' id_activitytype_orig,id_activitytype_dest', id_activitytype_orig, id_activitytype_dest
6104
6105
# print ' probs_orig',sum(probs_fac_orig)#,'\n',probs_fac_orig
6106
# print ' probs_dest',sum(probs_fac_dest)#,'\n',probs_fac_dest
6107
6108
# is there a chance to find facilities to locate persons in
6109
# origin and destination zone
6110
6111
#activitytypes= self.get_scenario().demand.activitytypes
6112
#ctivitynames = self.activitytypes.names
6113
#get_id_act = activitynames.get_id_from_index
6114
6115
if (np.sum(probs_fac_orig) > 0) & (np.sum(probs_fac_dest) > 0):
6116
# if id_mode == self._id_mode_bike:
6117
# are_bikeowner = np.ones(tripnumber, dtype=np.bool)
6118
# else:
6119
# # TODO: assign a default percentage of bike owners
6120
# are_bikeowner = np.zeros(tripnumber, dtype=np.bool)
6121
#times_start = np.random.randint(time_start,time_end,tripnumber)
6122
ids_person = self.make_multiple(tripnumber,
6123
ids_mode_preferred=id_mode * np.ones(tripnumber, dtype=np.int32),
6124
dists_walk_max=dist_walk_max * np.ones(tripnumber, dtype=np.int32),
6125
#times_start = times_start,
6126
)
6127
6128
unitvec_int = np.ones(tripnumber, dtype=np.int32)
6129
unitvec_float = np.ones(tripnumber, dtype=np.int32)
6130
6131
# activity timing
6132
#hours_start = hour_offset + np.array(times_start,dtype = np.float32)/3600
6133
#tol_orig = hour_begin_latest_orig+duration_max_orig-(hour_begin_earliest_orig+duration_min_orig)
6134
6135
# print ' hours_start[:3]',hours_start[:3]
6136
# print ' tol_orig',tol_orig
6137
6138
#hours_end_est = hours_start + hour_tripbudget
6139
#tol_dest = hour_begin_latest_dest-hour_begin_earliest_dest
6140
6141
# print ' hours_end_est[:3]',hours_end_est[:3]
6142
# print ' tol_dest',tol_dest
6143
6144
#self.map_id_act_to_ids_facattrconf[id_activitytype_orig][ids_person] = ids_fac[random_choice(tripnumber, probs_fac_orig)]
6145
#self.map_id_act_to_ids_facattrconf[id_activitytype_dest][ids_person] = ids_fac[random_choice(tripnumber, probs_fac_dest)]
6146
activities = self.get_activities()
6147
6148
# fix first departure hours for first activity imposed by
6149
# OD flow data
6150
hours_end_earliest_orig = (hour_offset+float(time_start)/3600)*unitvec_float
6151
hours_end_latest_orig = (hour_offset+float(time_end)/3600)*unitvec_float
6152
6153
duration_mean_orig = 0.5 * duration_min_orig+duration_max_orig
6154
hours_begin_earliest_orig = hours_end_earliest_orig-duration_mean_orig
6155
hours_begin_latest_orig = hours_end_latest_orig-duration_mean_orig
6156
6157
# this estimate could be *optionally* replaced by preliminary routing
6158
hours_begin_earliest_dest = hours_end_earliest_orig+hour_tripbudget
6159
hours_begin_latest_dest = hours_end_latest_orig+hour_tripbudget
6160
6161
#hours_end_earliest_dest = hours_begin_earliest_dest+duration_min_dest
6162
#hours_end_latest_dest = hours_begin_latest_dest+duration_max_dest
6163
6164
ids_activity_orig = activities.add_rows(
6165
n=tripnumber,
6166
ids_activitytype=id_activitytype_orig * unitvec_int,
6167
ids_facility=ids_fac[random_choice(tripnumber, probs_fac_orig)],
6168
hours_begin_earliest=hours_begin_earliest_orig,
6169
hours_begin_latest=hours_begin_latest_orig,
6170
durations_min=duration_mean_orig-1.0/60.0 * unitvec_float, # min mast be less than max to prevent crash
6171
durations_max=duration_mean_orig * unitvec_float,
6172
)
6173
6174
ids_activity_dest = activities.add_rows(
6175
n=tripnumber,
6176
ids_activitytype=id_activitytype_dest * unitvec_int,
6177
ids_facility=ids_fac[random_choice(tripnumber, probs_fac_dest)],
6178
hours_begin_earliest=hours_begin_earliest_dest,
6179
hours_begin_latest=hours_begin_latest_dest,
6180
durations_min=duration_min_dest*unitvec_float,
6181
durations_max=duration_max_dest*unitvec_float,
6182
)
6183
6184
for id_person, id_activity_orig, id_activity_dest in zip(ids_person, ids_activity_orig, ids_activity_dest):
6185
self.activitypatterns[id_person] = [id_activity_orig, id_activity_dest]
6186
6187
#activitypatterns = np.zeros((tripnumber,2), dtype = np.int32)
6188
#activitypatterns[:,0]= ids_activity_orig
6189
#activitypatterns[:,1]= ids_activity_dest
6190
# try convert in this way to lists
6191
# print ' activitypatterns',activitypatterns.tolist()
6192
#self.activitypatterns[ids_person] = activitypatterns.tolist()
6193
# for id_person, act_pattern in zip(ids_person,activitypatterns.tolist()):
6194
# self.activitypatterns[id_person] = act_pattern
6195
6196
return ids_person
6197
else:
6198
print 'WARNING in disaggregate_odflow: no probabilities', np.sum(probs_fac_orig), np.sum(probs_fac_dest)
6199
6200
return []
6201
6202
def create_pop_from_odflows(self, is_use_landusetypes=False, **kwargs):
6203
"""
6204
Creates a population and defines home and activity facility
6205
according to OD matrix defined in odflows.
6206
The population is distributed within the zones according to
6207
the area of the facility.
6208
if landusetype_orig and landusetype_dest also landuse types
6209
of facilities of origin and destination are taken into account.
6210
"""
6211
print 'create_pop_from_odflows'
6212
6213
demand = self.parent
6214
odflowtab = demand.odintervals.generate_odflows()
6215
landuse = self.get_landuse()
6216
activitytypes = demand.activitytypes
6217
log = kwargs.get('logger', self.get_logger())
6218
6219
# self._make_map_id_act_to_ids_facattrconf()
6220
ids_flow = odflowtab.get_ids()
6221
n_flows = len(ids_flow)
6222
6223
ids_activitytype_orig = odflowtab.ids_activitytype_orig[ids_flow]
6224
ids_activitytype_dest = odflowtab.ids_activitytype_dest[ids_flow]
6225
6226
if is_use_landusetypes:
6227
6228
# TODO: not tested and works only for one landusetype per activity
6229
#activitytypes = self.activitytypes.get_value()
6230
#id_landusetype_orig = activitytypes.ids_landusetypes[kwargs['id_activitytype_orig']][0]
6231
#id_landusetype_dest = activitytypes.ids_landusetypes[kwargs['id_activitytype_dest']][0]
6232
6233
# TODO: get activitypes from activity
6234
#probs_fac, ids_fac = self.get_landuse().facilities.get_departure_probabilities_landuse()
6235
probs_activitytype_fac_area = {}
6236
ids_acttype = activitytypes.get_ids()
6237
for id_acttype, ids_landusetype in zip(ids_acttype, activitytypes.ids_landusetypes[ids_acttype]):
6238
# print 50*'-'
6239
# print ' id_acttype',id_acttype,'ids_landusetype',ids_landusetype
6240
probs_activitytype, ids_fac = landuse.facilities.get_departure_probabilities_landuse2(ids_landusetype)
6241
probs_activitytype_fac_area[id_acttype] = probs_activitytype
6242
# print ' probs_activitytype_fac_area',probs_activitytype_fac_area[id_acttype]
6243
else:
6244
probs_fac_area, ids_fac = landuse.facilities.get_departure_probabilities()
6245
6246
i = 0.0
6247
for id_flow,\
6248
id_orig,\
6249
id_dest,\
6250
id_mode,\
6251
time_start,\
6252
time_end,\
6253
tripnumber,\
6254
id_activitytype_orig,\
6255
id_activitytype_dest,\
6256
hour_begin_earliest_orig,\
6257
hour_begin_earliest_dest,\
6258
hour_begin_latest_orig,\
6259
hour_begin_latest_dest,\
6260
duration_min_orig,\
6261
duration_min_dest,\
6262
duration_max_orig,\
6263
duration_max_dest\
6264
in zip(ids_flow,
6265
odflowtab.ids_orig[ids_flow],
6266
odflowtab.ids_dest[ids_flow],
6267
odflowtab.ids_mode[ids_flow],
6268
odflowtab.times_start[ids_flow],
6269
odflowtab.times_end[ids_flow],
6270
odflowtab.tripnumbers[ids_flow],
6271
ids_activitytype_orig,
6272
ids_activitytype_dest,
6273
activitytypes.hours_begin_earliest[ids_activitytype_orig],
6274
activitytypes.hours_begin_earliest[ids_activitytype_dest],
6275
activitytypes.hours_begin_latest[ids_activitytype_orig],
6276
activitytypes.hours_begin_latest[ids_activitytype_dest],
6277
activitytypes.durations_min[ids_activitytype_orig],
6278
activitytypes.durations_min[ids_activitytype_dest],
6279
activitytypes.durations_max[ids_activitytype_orig],
6280
activitytypes.durations_max[ids_activitytype_dest],
6281
):
6282
6283
log.progress(i/n_flows*100)
6284
# print ' disagg between zones',id_orig,id_dest
6285
i += 1
6286
if is_use_landusetypes:
6287
# TODO: not tested and works only for one landusetype per activity
6288
# but in activity typrs several landuse types are defined
6289
6290
# idea: add the probabilities for landuse types of origin and dest
6291
#probs_fac_orig = probs_fac[id_orig][id_landusetype_orig]
6292
#probs_fac_dest = probs_fac[id_dest][id_landusetype_dest]
6293
probs_fac_orig = probs_activitytype_fac_area[id_activitytype_orig][id_orig]
6294
probs_fac_dest = probs_activitytype_fac_area[id_activitytype_dest][id_dest]
6295
6296
else:
6297
probs_fac_orig = probs_fac_area[id_orig]
6298
probs_fac_dest = probs_fac_area[id_dest]
6299
6300
self.disaggregate_odflow(time_start,
6301
time_end,
6302
id_mode,
6303
ids_fac,
6304
probs_fac_orig,
6305
probs_fac_dest,
6306
tripnumber,
6307
id_activitytype_orig,
6308
id_activitytype_dest,
6309
hour_begin_earliest_orig,
6310
hour_begin_earliest_dest,
6311
hour_begin_latest_orig,
6312
hour_begin_latest_dest,
6313
duration_min_orig,
6314
duration_min_dest,
6315
duration_max_orig,
6316
duration_max_dest,
6317
**kwargs
6318
)
6319
6320
# return odflowtab
6321
6322
def add_plans(self, ids_person, id_strategy=-1):
6323
print 'add_plans n, id_strategy', len(ids_person), id_strategy
6324
n_plans = len(ids_person)
6325
# print ' get_plans',self.get_plans()
6326
# print ' stagetables',self.get_plans().get_stagetables().get_ident_abs()
6327
# print ' stagetables',self.get_plans().get_stagetables().stagetables.get_value()
6328
ids_plan = self.get_plans().add_rows(n=n_plans,
6329
ids_person=ids_person,
6330
ids_strategy=id_strategy*np.ones(n_plans, dtype=np.int32),
6331
)
6332
6333
# print ' post stagetables',self.get_plans().get_stagetables().get_ident_abs()
6334
# print ' post stagetables',self.get_plans().get_stagetables().stagetables.get_value()
6335
6336
# return ids_plan
6337
self.ids_plan[ids_person] = 1*ids_plan
6338
6339
for id_person, id_plan in zip(ids_person, ids_plan):
6340
if self.lists_ids_plan[id_person] is None:
6341
self.lists_ids_plan[id_person] = [id_plan]
6342
else:
6343
self.lists_ids_plan[id_person].append(id_plan)
6344
return ids_plan
6345
6346
def plan_with_strategy(self, id_strategy, evalcrit=0, is_plan_no_preferred=False, is_substitute=False, logger=None):
6347
strategy = self.get_strategies().strategies[id_strategy]
6348
plans = self.get_plans()
6349
6350
ids_person = self.get_ids()
6351
6352
evals = strategy.preevaluate(ids_person)
6353
6354
if is_plan_no_preferred: # considering only people with vehicle but with another preferred mode
6355
inds_preeval = (evals == 0) | (evals == 1)
6356
else:
6357
inds_preeval = evals >= evalcrit
6358
6359
# if is_substitute:
6360
# for i, id_strat_pers in zip(xrange(len(inds_preeval)), self.plans.ids_strategy[ids_person[inds_preeval]]):
6361
# if id_strat_pers
6362
6363
ids_person_preeval = ids_person[inds_preeval]
6364
print 'plan_with_strategy', strategy.ident, 'n_pers', len(ids_person_preeval)
6365
6366
# TODO: is_substitute = is_substitute could be an argument to plan()
6367
# and then passed to the centralized add_plan() method of the VP.
6368
6369
strategy.plan(ids_person_preeval, logger=logger)
6370
6371
# def get_times(self, ind, ids_person = None, pdf = 'unit'):
6372
# """
6373
# Returns person IDs, activity IDs and initial times
6374
# for persons with at least one acivity.
6375
#
6376
# ids_person: array of preselected person IDs
6377
#
6378
# pdf: gives the probability density function to be chosen to determin
6379
# the departure times within the initial time intervals given by
6380
# initial activity attributes.
6381
# """
6382
# ids_person, ids_activity = self.get_activity_from_pattern(0,ids_person)
6383
# times_init = self.get_activities().get_times_init(ids_activity, pdf)
6384
#
6385
# return ids_person, ids_activity, times_init
6386
6387
def get_activities_from_pattern(self, ind, ids_person=None):
6388
"""
6389
Returns person IDs and from/to activity IDs for persons who perform an activity
6390
at the given activity index ind.
6391
Returns arrays: ids_person, ids_activity_from, ids_activity_to
6392
6393
ind: index of activity in activity pattern, starting with 0
6394
ids_person: array of preselected person IDs
6395
6396
6397
"""
6398
6399
ids_person_activity = []
6400
ids_activity_from = []
6401
ids_activity_to = []
6402
if ids_person is None:
6403
ids_person = self.get_ids()
6404
6405
for id_person, activitypattern in zip(ids_person, self.activitypatterns[ids_person]):
6406
# has person activity at index ind?
6407
if len(activitypattern) > ind+1:
6408
ids_person_activity.append(id_person)
6409
ids_activity_from.append(activitypattern[ind])
6410
ids_activity_to.append(activitypattern[ind+1])
6411
6412
return ids_person_activity, ids_activity_from, ids_activity_to
6413
6414
# activities.hours_begin_earliest[ids_person_activity],
6415
# activities.hours_begin_latest[ids_person_activity],
6416
# activities.durations_min[ids_person_activity],
6417
# activities.durations_max[ids_person_activity],
6418
6419
def get_vtypes(self):
6420
6421
ids_vtypes = set()
6422
# get individual vehicle types
6423
ids_vtypes.update(self.get_iautos().ids_vtype.get_value())
6424
ids_vtypes.update(self.get_imotos().ids_vtype.get_value())
6425
ids_vtypes.update(self.get_ibikes().ids_vtype.get_value())
6426
6427
# add public transport
6428
ids_vtypes.update(self.get_ptlines().ids_vtype.get_value())
6429
6430
# add pedestrian types
6431
ids_vtypes.update(self.ids_vtype.get_value())
6432
6433
return ids_vtypes
6434
6435
def select_plans_preferred_mode(self, fraction=0.1, **kwargs):
6436
"""
6437
Selects current plant to satisfy best the preferred mode.
6438
"""
6439
6440
strategies = self.get_strategies()
6441
ids_strat = strategies.get_ids()
6442
n_strat = len(ids_strat)
6443
ids_pers_all = self.get_ids()
6444
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6445
n_pers = len(ids_pers)
6446
preevals = -1*np.ones((np.max(ids_pers)+1, np.max(ids_strat)+1), dtype=np.int32)
6447
for ind, id_strategy, strategy in zip(range(n_strat), ids_strat, strategies.strategies[ids_strat]):
6448
preevals[ids_pers, id_strategy] = strategy.preevaluate(ids_pers)
6449
6450
preferred = 2
6451
plans = self.get_plans()
6452
self.ids_plan.reset()
6453
for id_pers, ids_plan in zip(ids_pers, self.lists_ids_plan[ids_pers]):
6454
if ids_plan is not None:
6455
if len(ids_plan) > 0:
6456
print ' id_pers,ids_plan', id_pers, ids_plan
6457
print ' ids_strat, preeval', plans.ids_strategy[ids_plan], preevals[id_pers, plans.ids_strategy[ids_plan]]
6458
inds_sel = np.flatnonzero(preevals[id_pers, plans.ids_strategy[ids_plan]] == preferred)
6459
print ' inds_sel', inds_sel, inds_sel.dtype
6460
if len(inds_sel) > 0:
6461
#ids_plan_sel = np.array(ids_plan)[inds_sel]
6462
# print ' ids_plan_sel',ids_plan_sel
6463
# at least one plan contains preferred mode
6464
self.ids_plan[id_pers] = np.array(ids_plan)[inds_sel][0] # whu [1]?
6465
# else:
6466
# assumption: a plan for the preferred mode always exists
6467
# # no preferred mode found try to satisfy best possible
6468
# #ids_plan[preevals[id_pers,plans.ids_strategy[ids_plan]] == preferred]
6469
# self.ids_plan[id_pers] = -1
6470
return True
6471
6472
def select_plans_min_time_est(self, fraction=1.0, timedev=-1.0, c_probit=-1.0, **kwargs):
6473
"""
6474
Select plan with minimum estimated travel time as current plant.
6475
"""
6476
ids_pers_all = self.get_ids()
6477
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6478
times_est = self.get_plans().times_est
6479
# self.ids_plan.reset()
6480
for id_pers, ids_plan_all in zip(ids_pers, self.lists_ids_plan[ids_pers]):
6481
ids_plan = np.array(ids_plan_all, dtype=np.int32)[times_est[ids_plan_all] > 0.1]
6482
if len(ids_plan) > 0:
6483
# print ' id_pers,ids_plan',id_pers,ids_plan
6484
if timedev > 0.1:
6485
times_rand = np.random.normal(0.0, timedev, len(ids_plan))
6486
elif c_probit > 0:
6487
times_rand = np.zeros(len(ids_plan), dtype=np.float32)
6488
for i, t in zip(xrange(len(ids_plan)), times_est[ids_plan]):
6489
times_rand[i] = np.random.normal(0.0, c_probit * t, 1)
6490
6491
else:
6492
times_rand = np.zeros(len(ids_plan), dtype=np.float32)
6493
self.ids_plan[id_pers] = np.array(ids_plan)[np.argmin(times_est[ids_plan]+times_rand)]
6494
return True
6495
6496
def select_plans_random(self, fraction=0.1, **kwargs):
6497
"""
6498
A fraction of the population changes a plan.
6499
The new plans are chosen randomly.
6500
"""
6501
6502
ids_pers_all = self.get_ids()
6503
print 'select_plans_random', len(ids_pers_all), fraction
6504
times_est = self.get_plans().times_est
6505
# self.ids_plan.reset()
6506
# ids_mode[random_choice(n,shares/np.sum(shares))]
6507
6508
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6509
print ' ids_pers', ids_pers
6510
for id_pers, ids_plan in zip(ids_pers, self.lists_ids_plan[ids_pers]):
6511
if len(ids_plan) > 0:
6512
# print ' id_pers,ids_plan',id_pers,ids_plan
6513
self.ids_plan[id_pers] = ids_plan[np.random.randint(len(ids_plan))]
6514
return True
6515
6516
def select_plans_min_time_exec(self, fraction=0.1, timedev=-1, c_probit=-1, **kwargs):
6517
"""
6518
Select plan with minimum executed travel time as current plant.
6519
"""
6520
ids_pers_all = self.get_ids()
6521
# print 'select_plans_random',len(ids_pers_all),fraction
6522
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6523
times_exec = self.get_plans().times_exec
6524
# self.ids_plan.reset()
6525
for id_pers, ids_plan_all in zip(ids_pers, self.lists_ids_plan[ids_pers]):
6526
# print ' ids_plan_all',ids_plan_all,type(ids_plan_all)
6527
ids_plan = np.array(ids_plan_all, dtype=np.int32)[times_exec[ids_plan_all] > 0.1]
6528
if len(ids_plan) > 0:
6529
# print ' id_pers,ids_plan',id_pers,ids_plan
6530
if timedev > 0.1:
6531
times_rand = np.random.normal(0.0, timedev, len(ids_plan))
6532
elif c_probit > 0:
6533
times_rand = np.zeros(len(ids_plan), dtype=np.float32)
6534
for i, t in zip(xrange(len(ids_plan)), times_exec[ids_plan]):
6535
times_rand[i] = np.random.normal(0.0, c_probit * t, 1)
6536
6537
else:
6538
times_rand = np.zeros(len(ids_plan), dtype=np.float32)
6539
6540
self.ids_plan[id_pers] = np.array(ids_plan)[np.argmin(times_exec[ids_plan]+times_rand)]
6541
return True
6542
6543
def select_plans_min_time_exec_est(self, fraction=0.1, timedev=-1, c_probit=-1, **kwargs):
6544
"""
6545
Select plan with minimum executed or estimated (if executed doesn't exist) travel time as current plant.
6546
"""
6547
n_analyzed_persons = 0
6548
ids_pers_all = self.get_ids()
6549
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6550
times_exec = self.get_plans().times_exec
6551
times_est = self.get_plans().times_est
6552
ids_plans = self.get_plans().get_ids()
6553
for id_pers, ids_plan_all in zip(ids_pers, self.lists_ids_plan[ids_pers]):
6554
ids_plan_est = np.array(ids_plan_all, dtype=np.int32)[times_est[ids_plan_all] > 0.1]
6555
ids_plan_exec = np.array(ids_plan_all, dtype=np.int32)[times_exec[ids_plan_all] > 0.1]
6556
if len(ids_plan_est) > 0:
6557
if len(ids_plan_est) == len(ids_plan_exec):
6558
ids_plan_est = []
6559
else:
6560
c = np.zeros(len(ids_plan_est))
6561
for x in range(len(ids_plan_est)):
6562
for y in range(len(ids_plan_exec)):
6563
if ids_plan_est[x] == ids_plan_exec[y]:
6564
c[x] = 1
6565
d = np.delete(ids_plan_est, np.flatnonzero(c))
6566
ids_plan_est = d
6567
6568
n_analyzed_persons += 1
6569
6570
if timedev > 0.1:
6571
if len(ids_plan_est) > 0:
6572
times_rand_est = np.random.normal(0.0, timedev, len(ids_plan_est))
6573
if len(ids_plan_exec) > 0:
6574
times_rand_exec = np.random.normal(0.0, timedev, len(ids_plan_exec))
6575
6576
elif c_probit > 0:
6577
if len(ids_plan_est) > 0:
6578
times_rand_est = np.zeros(len(ids_plan_est), dtype=np.float32)
6579
for i, t in zip(xrange(len(ids_plan_est)), times_est[ids_plan_est]):
6580
times_rand_est[i] = np.random.normal(0.0, c_probit * t, 1)
6581
if len(ids_plan_exec) > 0:
6582
times_rand_exec = np.zeros(len(ids_plan_exec), dtype=np.float32)
6583
for i, t in zip(xrange(len(ids_plan_exec)), times_exec[ids_plan_exec]):
6584
times_rand_exec[i] = np.random.normal(0.0, c_probit * t, 1)
6585
6586
else:
6587
if len(ids_plan_exec) > 0:
6588
times_rand_exec = np.zeros(len(ids_plan_exec), dtype=np.float32)
6589
if len(ids_plan_est) > 0:
6590
times_rand_est = np.zeros(len(ids_plan_est), dtype=np.float32)
6591
6592
if len(ids_plan_exec) > 0 and len(ids_plan_est) > 0:
6593
if min(times_exec[ids_plan_exec]+times_rand_exec) < min(times_est[ids_plan_est]+times_rand_est):
6594
self.ids_plan[id_pers] = np.array(ids_plan_exec)[np.argmin(
6595
times_exec[ids_plan_exec]+times_rand_exec)]
6596
else:
6597
self.ids_plan[id_pers] = np.array(
6598
ids_plan_est)[np.argmin(times_est[ids_plan_est]+times_rand_est)]
6599
elif len(ids_plan_exec) == 0:
6600
self.ids_plan[id_pers] = np.array(ids_plan_est)[np.argmin(times_est[ids_plan_est]+times_rand_est)]
6601
6602
else:
6603
6604
self.ids_plan[id_pers] = np.array(ids_plan_exec)[np.argmin(
6605
times_exec[ids_plan_exec]+times_rand_exec)]
6606
6607
print 'were analyzed %d persons' % (n_analyzed_persons)
6608
return True
6609
6610
def select_plans_next(self, fraction=0.1, **kwargs):
6611
"""
6612
Select next plan in the plan list as current plant.
6613
"""
6614
# print 'select_plans_next'
6615
ids_pers_all = self.get_ids()
6616
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6617
for id_pers, id_plan_current, ids_plan in zip(ids_pers, self.ids_plan[ids_pers], self.lists_ids_plan[ids_pers]):
6618
n_plan = len(ids_plan)
6619
if n_plan > 0:
6620
# print ' id_pers,id_plan_current',id_pers,id_plan_current,ids_plan,id_plan_current != -1
6621
if id_plan_current != -1:
6622
ind = ids_plan.index(id_plan_current)
6623
# print ' ind',ind,ind +1 < n_plan
6624
if ind + 1 < n_plan:
6625
ind += 1
6626
else:
6627
ind = 0
6628
else:
6629
ind = 0
6630
6631
# print ' ind,n_plan',ind,n_plan,'ids_plan[ind]', ids_plan[ind]
6632
self.ids_plan[id_pers] = ids_plan[ind]
6633
# print ' finally: ids_plan=',self.ids_plan.get_value()
6634
return True
6635
6636
def select_plans_utility_function(self, fraction=0.1, timedev=-1, c_probit=-1, **kwargs):
6637
"""
6638
Select plan with utility function, which is based on the minimum executed travel time selection method
6639
but considering also a constant (different for each plan strategy) and a multiplicative parameter (the
6640
same for every strategy).
6641
"""
6642
strategies = self.get_strategies()
6643
value_of_time = strategies.value_of_time.get_value()
6644
6645
plans = self.get_plans()
6646
ids_pers_all = self.get_ids()
6647
6648
print 'select_plans_utility_function', len(ids_pers_all)
6649
6650
ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)]
6651
times_exec = self.get_plans().times_exec
6652
times_est = self.get_plans().times_est
6653
ids_plans_all = self.lists_ids_plan[ids_pers]
6654
6655
for id_pers, ids_plan_all in zip(ids_pers, ids_plans_all):
6656
6657
# print ' ids_plan_all',ids_plan_all,type(ids_plan_all)
6658
n_plan = len(ids_plan)
6659
6660
# if cycle necessary to apply a casual variation on plans executive times (in addition or in reduction)
6661
if n_plan > 0:
6662
traveltimes = np.zeros(n_plan, dtype=np.float32)
6663
traveltimes_noise = np.zeros(n_plan, dtype=np.float32)
6664
6665
inds_exec = times_exec[ids_plan_all] > 0.
6666
inds_est = times_exec[ids_plan_all] <= 0.
6667
6668
traveltimes[inds_exec] = times_exec[ids_plan_all[inds_exec]]
6669
traveltimes[inds_est] = times_est[ids_plan_all[inds_est]]
6670
6671
if timedev > 0:
6672
# noise is normal distributed with deviation timedev
6673
traveltimes_noise = np.random.normal(0.0, timedev, n_plan)
6674
6675
elif c_probit > 0:
6676
# noise is normal distributed with deviation c_probit *traveltimes
6677
traveltimes_noise = np.random.normal(0.0, c_probit * traveltimes, n_plan)
6678
6679
else:
6680
# no travel time noise
6681
traveltimes_noise = np.zeros(n_plan, dtype=np.float32)
6682
6683
for id_plan, strategy, traveltime, timetime_noise in zip(ids_plan_all,
6684
strategies.strategies[plans.ids_strategy[ids_plan_all]],
6685
traveltimes,
6686
traveltimes_noise):
6687
6688
utility = strategy.get_utility_specific(id_plan) - value_of_time * (traveltime + timetime_noise)
6689
6690
plans.utilities[id_plan] = utility
6691
6692
# set current plan of person to the one with the maximum utility
6693
self.ids_plan[id_pers] = ids_plan_all[np.argmax(plans.utilities[ids_plan_all])]
6694
6695
return True
6696
6697
def prepare_sim(self, process):
6698
return [] # [(steptime1,func1),(steptime2,func2),...]
6699
6700
def get_trips(self):
6701
# returns trip object, method common to all demand objects
6702
return self.get_iautos()
6703
6704
def get_writexmlinfo(self, is_route=False, is_plain=False, **kwargs):
6705
"""
6706
Returns three array where the first array is the
6707
begin time of the first vehicle and the second array is the
6708
write function to be called for the respectice vehicle and
6709
the third array contains the vehicle ids
6710
6711
Method used to sort trips when exporting to route or trip xml file
6712
"""
6713
print 'Virtualpop.get_writexmlinfo is_plain', is_plain
6714
plans = self.get_plans()
6715
6716
ids_pers = self.select_ids(self.ids_plan.get_value() >= 0)
6717
n_pers = len(ids_pers)
6718
ids_plans = self.ids_plan[ids_pers]
6719
6720
# get vehicle trip info
6721
times_depart_bike, writefuncs_bike, ids_rides_bike = plans.get_stagetable(
6722
'bikerides').get_writexmlinfo(ids_plans, is_route, is_plain)
6723
times_depart_auto, writefuncs_auto, ids_rides_auto = plans.get_stagetable(
6724
'autorides').get_writexmlinfo(ids_plans, is_route, is_plain)
6725
times_depart_moto, writefuncs_moto, ids_rides_moto = plans.get_stagetable(
6726
'motorides').get_writexmlinfo(ids_plans, is_route, is_plain)
6727
6728
#self.add_stagetable('walks', WalkStages)
6729
#self.add_stagetable('autorides', AutorideStages)
6730
#self.add_stagetable('bikerides', BikerideStages)
6731
#self.add_stagetable('transits', TransitStages)
6732
#self.add_stagetable('activities', ActivityStages)
6733
6734
#rides = plans.get_stagetable('autorides')
6735
6736
if not is_plain:
6737
# do persons
6738
6739
times_depart_pers = plans.times_begin[ids_plans]
6740
writefuncs_pers = np.zeros(n_pers, dtype=np.object)
6741
writefuncs_pers[:] = self.write_person_xml
6742
6743
# assemble vectors
6744
print ' times_depart_pers.shape', times_depart_pers.shape
6745
print ' times_depart_bike.shape', times_depart_bike.shape
6746
print ' times_depart_auto.shape', times_depart_auto.shape
6747
times_depart = np.concatenate((times_depart_pers,
6748
times_depart_auto,
6749
times_depart_bike,
6750
times_depart_moto,
6751
))
6752
6753
writefuncs = np.concatenate((writefuncs_pers,
6754
writefuncs_auto,
6755
writefuncs_bike,
6756
writefuncs_moto,
6757
))
6758
6759
ids = np.concatenate((ids_pers,
6760
ids_rides_auto,
6761
ids_rides_bike,
6762
ids_rides_moto,
6763
))
6764
else:
6765
times_depart = np.concatenate((times_depart_auto,
6766
times_depart_bike,
6767
times_depart_moto,
6768
))
6769
6770
writefuncs = np.concatenate((writefuncs_auto,
6771
writefuncs_bike,
6772
writefuncs_moto,
6773
))
6774
6775
ids = np.concatenate((ids_rides_auto,
6776
ids_rides_bike,
6777
ids_rides_moto,
6778
))
6779
6780
return times_depart, writefuncs, ids
6781
6782
def write_person_xml(self, fd, id_pers, time_begin, indent=2):
6783
6784
stages = self.get_plans().get_stages(self.ids_plan[id_pers])
6785
6786
fd.write(xm.start('person', indent=indent+2))
6787
fd.write(xm.num('id', self.get_id_sumo_from_id(id_pers)))
6788
# fd.write(xm.num('depart',self.times_start[id_pers]))
6789
fd.write(xm.num('depart', time_begin))
6790
fd.write(xm.num('type', self.parent.vtypes.ids_sumo[self.ids_vtype[id_pers]]))
6791
6792
activity_init, id_stage_init = stages[0]
6793
id_edge_init, pos_init = activity_init.get_edges_positions(id_stage_init)
6794
6795
# self.ids_edge_depart.write_xml(fd,id_trip)
6796
# self.positions_depart.write_xml(fd,id_trip)
6797
fd.write(xm.num('from', self._edges.ids_sumo[id_edge_init]))
6798
fd.write(xm.num('departPos', pos_init))
6799
6800
fd.write(xm.stop())
6801
6802
# write stages of this person.
6803
# Attention!! first and last stage, which are activities,
6804
# will NOT be exportes , therefore [1:-1]
6805
for stage, id_stage in stages[1:-1]:
6806
stage.to_xml(id_stage, fd, indent+4)
6807
6808
fd.write(xm.end('person', indent=indent+2))
6809
6810
def config_results(self, results):
6811
6812
results.add_resultobj(res.Personresults('virtualpersonresults', results,
6813
self,
6814
self.get_net().edges,
6815
name='Virtual person results',
6816
info='Table with simulation results for person of the virtual population. The results refer to all trips made by the person during the entire simulation period.',
6817
), groupnames=['Trip results'])
6818
6819
results.add_resultobj(res.Vehicleresults('iautotripresults', results,
6820
self.get_iautos(),
6821
self.get_net().edges,
6822
name='Auto trip results',
6823
info='Table with trip results made by individual autos. The results refer to all trips made by a specific vehicle during the entire simulation period.',
6824
), groupnames=['Trip results'])
6825
6826
results.add_resultobj(res.Vehicleresults('ibiketripresults', results,
6827
self.get_ibikes(),
6828
self.get_net().edges,
6829
name='Bike trip results',
6830
info='Table with trip results made by individual bikes. The results refer to all trips made by a specific vehicle during the entire simulation period.',
6831
), groupnames=['Trip results'])
6832
6833
results.add_resultobj(res.Vehicleresults('imototripresults', results,
6834
self.get_imotos(),
6835
self.get_net().edges,
6836
name='Motorcycle trip results',
6837
info='Table with trip results made by individual motorcycles. The results refer to all trips made by a specific vehicle during the entire simulation period.',
6838
), groupnames=['Trip results'])
6839
6840
# def process_results(self, results, process = None):
6841
# print 'process_results'
6842
# ## copy total travel into plan execution time
6843
# personresults = results.virtualpersonresults
6844
# self.update_plans(personresults)
6845
6846
def update_results(self, personresults):
6847
"""
6848
Updates plans with results from previous
6849
simulation run, and updates plan choice
6850
"""
6851
6852
ids_res = personresults.get_ids()
6853
print 'update_results', len(ids_res)
6854
ids_person = personresults.ids_person[ids_res]
6855
ids_plan = self.ids_plan[ids_person]
6856
self.get_plans().times_exec[ids_plan] = personresults.times_travel_total[ids_res]
6857
# change mobility plan based on updated travel times
6858
pass
6859
6860
def import_routes_xml(self, filepath, is_clear_trips=False,
6861
ids_strategy=None,
6862
is_generate_ids=True, is_add=False,
6863
is_overwrite_only=True):
6864
"""Reads route information of vehicles, and overwrites existing routes in stages.
6865
Used for example read results from Duaiterate process.
6866
"""
6867
print 'Virtualop.import_routes_xml from %s' % (filepath)
6868
if is_clear_trips:
6869
self.clear_trips()
6870
6871
counter = RouteCounter()
6872
parse(filepath, counter)
6873
reader = RouteReaderVp(self, counter)
6874
if 1: # try:
6875
parse(filepath, reader)
6876
print ' call make_routes', is_generate_ids, 'is_add', is_add
6877
reader.insert_routes(ids_strategy=ids_strategy)
6878
6879
else: # except KeyError:
6880
print >> sys.stderr, "Error: Problems with reading routes!"
6881
raise
6882
6883
6884
class DuarouterVp(routing.RouterMixin):
6885
def __init__(self, ident='vpduarouter', virtualpop=None,
6886
netfilepath=None,
6887
routefilepaths=None,
6888
outfilepath=None,
6889
is_export_net=True,
6890
is_export_trips=True,
6891
logger=None,
6892
**kwargs):
6893
print 'DuarouterVp.__init__ '
6894
6895
self._init_common(ident, name='Virtual Population DUA router',
6896
parent=virtualpop,
6897
logger=logger,
6898
info='DUA router for virtual population.',
6899
)
6900
cml = 'duarouter'
6901
self.init_cml(cml) # pass main shell command
6902
6903
scenario = virtualpop.get_scenario()
6904
demand = virtualpop.parent
6905
net = scenario.net
6906
attrsman = self.get_attrsman()
6907
6908
if routefilepaths is None:
6909
routefilepaths = demand.get_routefilepath()
6910
6911
print ' default routefilepaths', routefilepaths
6912
self.add_option('routefilepaths', routefilepaths,
6913
groupnames=['files'],
6914
cml='--route-files',
6915
perm='rw',
6916
name='Route file(s)',
6917
wildcards='Route XML files (*.rou.xml)|*.rou.xml',
6918
metatype='filepaths',
6919
info='SUMO route files in XML format.',
6920
)
6921
6922
self.is_virtualpop_only = attrsman.add(cm.AttrConf('is_virtualpop_only', kwargs.get('is_virtualpop_only', False),
6923
groupnames=['options'],
6924
name='Consider only virtualpop demand',
6925
info="""Consider only virtualpop demand.""",
6926
))
6927
6928
#strategychoices = {}
6929
strategies = virtualpop.get_strategies()
6930
#ids_strat = strategies.get_ids()
6931
# for id_strat, name_strat in zip(ids_strat, strategies.names[ids_strat]):
6932
# strategychoices[name_strat] = id_strat
6933
strategychoices = strategies.names.get_indexmap()
6934
self.ids_strategy = attrsman.add(cm.ListConf('ids_strategy', kwargs.get('ids_strategy', strategychoices.values()),
6935
choices=strategychoices,
6936
groupnames=['options'],
6937
name='Rerouted strategies',
6938
info="""Strategies to be rerouted. Note that the entire demand will be used for routing, but only the selected routes will be reimported in the virtual population.""",
6939
))
6940
6941
self.is_export_net = is_export_net
6942
6943
if netfilepath is None:
6944
netfilepath = net.get_filepath()
6945
6946
self.add_option('netfilepath', netfilepath,
6947
groupnames=['_private'],
6948
cml='--net-file',
6949
perm='r',
6950
name='Net file',
6951
wildcards='Net XML files (*.net.xml)|*.net.xml',
6952
metatype='filepath',
6953
info='SUMO Net file in XML format.',
6954
)
6955
6956
if outfilepath is None:
6957
outfilepath = scenario.get_rootfilepath()+'.dua.rou.xml'
6958
6959
self.add_option('outfilepath', outfilepath,
6960
groupnames=['_private'],
6961
cml='--output-file',
6962
perm='r',
6963
name='Output routefile',
6964
wildcards='Route XML files (*.rou.xml)|*.rou.xml',
6965
metatype='filepath',
6966
info='Output file of the routing process, which is a SUMO route file in XML format.',
6967
)
6968
6969
self.init_options_time(**kwargs)
6970
self.init_options_methods(**kwargs)
6971
self.init_options_processing_common(**kwargs)
6972
self.init_options_processing_dua(**kwargs)
6973
routing.init_random(self, **kwargs)
6974
6975
def do(self):
6976
virtualpop = self.parent
6977
scenario = virtualpop.get_scenario()
6978
demand = virtualpop.parent
6979
net = scenario.net
6980
6981
if self.is_export_net:
6982
net.export_netxml(self.netfilepath)
6983
6984
if self.is_virtualpop_only:
6985
demandobjects = [virtualpop]
6986
else:
6987
demandobjects = None # means entire demand is exported by default
6988
6989
demand.export_routes_xml(filepath=self.routefilepaths,
6990
encoding='UTF-8',
6991
demandobjects=demandobjects,
6992
is_route=False, # allow True if route export is implemened in virtual population self.is_skip_first_routing,# produce routes only if first dua routing is skipped
6993
vtypeattrs_excluded=['times_boarding', 'times_loading'], # bug of duaiterate!!
6994
is_plain=True, # this will prevent exporting stops and plans which causes routing errors with stops
6995
)
6996
6997
self.update_params()
6998
cml = self.get_cml()
6999
7000
self.run_cml(cml)
7001
if self.status == 'success':
7002
print ' DUA routing done.'
7003
if os.path.isfile(self.outfilepath):
7004
print ' outfile exists, start importing routes'
7005
virtualpop.import_routes_xml(self.outfilepath, ids_strategy=self.ids_strategy)
7006
7007
return True
7008
else:
7009
return False
7010
return False
7011
7012
7013
class RouteReaderVp(RouteReader):
7014
def insert_routes(self, ids_strategy=None):
7015
7016
virtualpop = self._trips # parent is called trips here need to be changed
7017
print 'RouteReaderVp.insert_routes found %d routes.' % (len(self.ids_sumo))
7018
plans = virtualpop.get_plans()
7019
strategies = virtualpop.get_strategies()
7020
id_strat_auto = strategies.names.get_id_from_index('auto')
7021
id_strat_bike = strategies.names.get_id_from_index('bike')
7022
id_strat_motorcycle = strategies.names.get_id_from_index('motorcycle')
7023
n_change_route = 0
7024
if (ids_strategy is None):
7025
ids_strategy = [id_strat_auto, id_strat_bike, id_strat_motorcycle]
7026
7027
if id_strat_auto in ids_strategy:
7028
iautos = virtualpop.get_iautos()
7029
stages = iautos.get_stagetable()
7030
for id_sumo, ids_edge in zip(self.ids_sumo, self.routes):
7031
id_veh, id_stage = iautos.get_info_from_id_sumo(id_sumo)
7032
if (id_veh > -1) & (id_stage > 1):
7033
# print ' iauto: id_sumo %s id_veh %d id_stage %d'%(id_sumo,id_veh,id_stage)
7034
# print ' before:',stages.ids_edges[id_stage]
7035
if stages.ids_edges[id_stage] != ids_edge:
7036
n_change_route += 1
7037
print ' route change of id_veh', id_veh, 'id_stage', id_stage
7038
stages.ids_edges[id_stage] = ids_edge
7039
# print ' after :',stages.ids_edges[id_stage]
7040
7041
if id_strat_bike in ids_strategy:
7042
ibikes = virtualpop.get_ibikes()
7043
stages = ibikes.get_stagetable()
7044
for id_sumo, ids_edge in zip(self.ids_sumo, self.routes):
7045
id_veh, id_stage = ibikes.get_info_from_id_sumo(id_sumo)
7046
if (id_veh > -1) & (id_stage > 1):
7047
# print ' ibike: id_sumo %s id_veh %d id_stage %d'%(id_sumo,id_veh,id_stage)
7048
# print ' before:',stages.ids_edges[id_stage]
7049
if stages.ids_edges[id_stage] != ids_edge:
7050
n_change_route += 1
7051
print ' route change of id_veh', id_veh, 'id_stage', id_stage
7052
stages.ids_edges[id_stage] = ids_edge
7053
# print ' after :',stages.ids_edges[id_stage]
7054
7055
if id_strat_motorcycle in ids_strategy:
7056
imotos = virtualpop.get_imotos()
7057
stages = imotos.get_stagetable()
7058
for id_sumo, ids_edge in zip(self.ids_sumo, self.routes):
7059
id_veh, id_stage = imotos.get_info_from_id_sumo(id_sumo)
7060
if (id_veh > -1) & (id_stage > 1):
7061
# print ' ibike: id_sumo %s id_veh %d id_stage %d'%(id_sumo,id_veh,id_stage)
7062
# print ' before:',stages.ids_edges[id_stage]
7063
if stages.ids_edges[id_stage] != ids_edge:
7064
n_change_route += 1
7065
print ' route change of id_veh', id_veh, 'id_stage', id_stage
7066
stages.ids_edges[id_stage] = ids_edge
7067
# print ' after :',stages.ids_edges[id_stage]
7068
print ' RouteReaderVp: Total number of changed routes:', n_change_route
7069
7070
7071
class PopGenerator(Process):
7072
def __init__(self, ident='virtualpopgenerator', virtualpop=None, logger=None, **kwargs):
7073
print 'PopFromOdfGenerator.__init__ ', ident, virtualpop
7074
7075
# TODO: let this be independent, link to it or child??
7076
#
7077
scenario = virtualpop.get_scenario()
7078
self._init_common(ident,
7079
parent=virtualpop,
7080
name='Population generator',
7081
logger=logger,
7082
info='Create virtual population from basic statistical data.',
7083
)
7084
7085
attrsman = self.set_attrsman(cm.Attrsman(self))
7086
7087
# make for each possible pattern a field for prob
7088
activitytypes = self.parent.get_scenario().demand.activitytypes
7089
7090
self.n_person = attrsman.add(cm.AttrConf('n_person', kwargs.get('n_person', 1000),
7091
groupnames=['options'],
7092
perm='rw',
7093
name='Number of person',
7094
info='Number of adult persons.',
7095
))
7096
7097
self.ids_acttype_default = activitytypes.get_ids_from_formatted('home,work')
7098
# self.ids_acttype = attrsman.add(cm.AttrConf( 'ids_acttype',kwargs.get('id_acttype',activitytypes.get_id_from_formatted('home')),
7099
# groupnames = ['options'],
7100
# choices = activitytypes.names.get_indexmap(),
7101
# perm='rw',
7102
# name = 'Activity type',
7103
# info = 'Initial activity type.',
7104
# ))
7105
7106
self.ttb_mean = attrsman.add(cm.AttrConf('ttb_mean', kwargs.get('ttb_mean', 55*60),
7107
groupnames=['options'],
7108
perm='rw',
7109
name='Avg. of 24h travel time budget',
7110
unit='s',
7111
info="""Average travel time budget for one day.
7112
This time excludes time for activities.
7113
""",
7114
))
7115
self.ttb_dev = attrsman.add(cm.AttrConf('ttb_dev', kwargs.get('ttb_dev', 10*60),
7116
groupnames=['options'],
7117
perm='rw',
7118
name='Std. of 24h travel time budget',
7119
unit='s',
7120
info="""Standard deviation of travel time budget for one day.
7121
""",
7122
))
7123
7124
mode_to_id = self.parent.get_scenario().net.modes.get_id_mode
7125
self.share_pedestrian = attrsman.add(cm.AttrConf('share_pedestrian', kwargs.get('share_pedestrian', 0.1),
7126
groupnames=['options', 'modal split'],
7127
perm='rw',
7128
id_mode=mode_to_id('pedestrian'),
7129
name='Pedestrian share',
7130
info="""Share of pedestrians.""",
7131
))
7132
7133
self.share_autouser = attrsman.add(cm.AttrConf('share_autouser', kwargs.get('share_autouser', 0.5),
7134
groupnames=['options', 'modal split'],
7135
perm='rw',
7136
id_mode=mode_to_id('passenger'),
7137
name='Auto user share',
7138
info="""Share of auto users.""",
7139
))
7140
7141
self.share_motorcycleuser = attrsman.add(cm.AttrConf('share_motorcycleuser', kwargs.get('share_motorcycleuser', 0.1),
7142
groupnames=['options', 'modal split'],
7143
perm='rw',
7144
id_mode=mode_to_id('motorcycle'),
7145
name='Motorcycle user share',
7146
info="""Share of Motorcycle users.""",
7147
))
7148
7149
self.share_bikeuser = attrsman.add(cm.AttrConf('share_bikeuser', kwargs.get('share_bikeuser', 0.1),
7150
groupnames=['options', 'modal split'],
7151
perm='rw',
7152
id_mode=mode_to_id('bicycle'),
7153
name='Bike user share',
7154
info="""Share of bike users.""",
7155
))
7156
7157
self.share_ptuser = attrsman.add(cm.AttrConf('share_ptuser', kwargs.get('share_ptuser', 0.2),
7158
groupnames=['options', 'modal split'],
7159
id_mode=mode_to_id('bus'),
7160
perm='rw',
7161
name='PT share',
7162
info="""Share of public transport user.""",
7163
))
7164
self.is_delete_existing_pop = attrsman.add(cm.AttrConf('is_delete_existing_pop', kwargs.get('is_delete_existing_pop', True),
7165
groupnames=['options'],
7166
name='Delete existing Virtual Population',
7167
info='If it is True: Delete existing virtual population. If it is False: keep existing virtual population',
7168
))
7169
7170
#self.modeshares = attrsman.add( cm.ObjConf(ModeShares('modeshares',self,scenario.net.modes),groupnames = ['options']) )
7171
7172
def do(self):
7173
print 'PopGenerator.do'
7174
# links
7175
7176
virtualpop = self.parent
7177
if self.is_delete_existing_pop == True:
7178
virtualpop.clear_population()
7179
logger = self.get_logger()
7180
#logger.w('Update Landuse...')
7181
scenario = virtualpop.get_scenario()
7182
activitytypes = scenario.demand.activitytypes
7183
facilities = scenario.landuse.facilities
7184
edges = scenario.net.edges
7185
7186
ids_fac = facilities.get_ids()
7187
map_id_edge_to_ids_fac = {}
7188
for id_fac, id_edge in zip(ids_fac, facilities.ids_roadedge_closest[ids_fac]):
7189
if map_id_edge_to_ids_fac.has_key(id_edge):
7190
map_id_edge_to_ids_fac[id_edge].append(id_fac)
7191
else:
7192
map_id_edge_to_ids_fac[id_edge] = [id_fac, ]
7193
7194
n_pers = self.n_person
7195
unitvec_int = np.ones(n_pers, dtype=np.int32)
7196
7197
ids_person = virtualpop.make_multiple(n_pers)
7198
virtualpop.traveltimebudgets[ids_person] = self.get_ttb(ids_person)
7199
7200
virtualpop.ids_mode_preferred[ids_person] = self.get_modes_random(n_pers)
7201
7202
# here we could preselect correct landuse based on
7203
# percentage of workers, students, employees
7204
prob_fac_to = facilities.capacities[ids_fac].astype(np.float32)
7205
prob_fac_to /= np.sum(prob_fac_to)
7206
# print ' np.sum(prob_fac_to)',np.sum(prob_fac_to)
7207
ids_fac_to = ids_fac[random_choice(n_pers, prob_fac_to)]
7208
7209
# determine id_fac_from by backward routing from id_fac_to
7210
ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to]
7211
7212
# pre calculate backward star and mode dependent link travel times
7213
bstar = edges.get_bstar()
7214
edgetimes = {}
7215
ids_mode = self.get_ids_mode()
7216
# idea: do also consider gradient of house prices
7217
for id_mode, speed_max in zip(ids_mode, scenario.net.modes.speeds_max[ids_mode]):
7218
edgetimes[id_mode] = edges.get_times(id_mode=id_mode,
7219
speed_max=speed_max,
7220
is_check_lanes=True
7221
)
7222
# determine home facilities by backwards tracking from work facility
7223
ids_fac_from = np.ones(n_pers, dtype=np.int32)
7224
i = 0
7225
for id_person, id_edge_to, id_mode, ttb\
7226
in zip(ids_person,
7227
ids_edge_to,
7228
virtualpop.ids_mode_preferred[ids_person],
7229
virtualpop.traveltimebudgets[ids_person],
7230
):
7231
7232
# print ' Backsearch',id_person,'id_edge_to',id_edge_to,edges.ids_sumo[id_edge_to],'ttb[s]',0.5*ttb
7233
ids_edge_from, costs, btree = routing.edgedijkstra_backwards(id_edge_to,
7234
0.5*ttb, # to be specified better
7235
weights=edgetimes[id_mode],
7236
bstar=bstar,
7237
)
7238
if len(ids_edge_from) == 0:
7239
# routing failed to deliver edges of origins
7240
# put work and home on same edge
7241
ids_edge_from = [id_edge_to, ]
7242
7243
# look at all edges of origin and pick most likely facility
7244
ids_fac_lim = []
7245
for id_edge_from in ids_edge_from:
7246
7247
#id_from_check = id_edge_from
7248
# print ' check from',id_from_check,'back to',id_edge_to,'time =%.2fs'%costs[id_from_check]
7249
# while id_from_check != id_edge_to:
7250
# id_from_check = btree[id_from_check]
7251
# #print ' id_edge = ',id_from_check
7252
# print ' success = ',id_from_check==id_edge_to
7253
if map_id_edge_to_ids_fac.has_key(id_edge_from):
7254
ids_fac_lim += map_id_edge_to_ids_fac[id_edge_from]
7255
7256
if len(ids_fac_lim) == 0:
7257
# no facilities at all destinations found
7258
# go edges backawards and search there
7259
# this will reduce travel time
7260
for id_edge_from in ids_edge_from:
7261
# verify if id_edge_from has facilities.
7262
while not map_id_edge_to_ids_fac.has_key(id_edge_from):
7263
# print ' no facility, go backward'
7264
id_edge_from = btree[id_edge_from]
7265
7266
ids_fac_lim = np.array(ids_fac_lim, dtype=np.int32)
7267
7268
prob_fac_from = facilities.capacities[ids_fac_lim].astype(np.float32)
7269
prob_fac_from /= np.sum(prob_fac_from)
7270
# print ' np.sum(prob_fac_to)',np.sum(prob_fac_to)
7271
ids_fac_from[i] = ids_fac[random_choice(1, prob_fac_to)]
7272
i += 1
7273
7274
# idea: adjust wake-up time with employment type
7275
activities = virtualpop.get_activities()
7276
ids_activity_from = activities.add_activities(
7277
self.ids_acttype_default[0] * unitvec_int,
7278
ids_fac_from,
7279
# use default
7280
#hours_begin_earliest = None,
7281
#hours_begin_latest = None,
7282
#durations_min = None,
7283
#durations_max = None,
7284
)
7285
7286
ids_activity_to = activities.add_activities(
7287
self.ids_acttype_default[1] * unitvec_int,
7288
ids_fac_to,
7289
# use default
7290
#hours_begin_earliest = None,
7291
#hours_begin_latest = None,
7292
#durations_min = None,
7293
#durations_max = None,
7294
)
7295
7296
for id_person, id_activity_from, ids_activity_to in zip(ids_person, ids_activity_from, ids_activity_to):
7297
virtualpop.activitypatterns[id_person] = [id_activity_from, ids_activity_to, ]
7298
7299
return True
7300
7301
def get_ids_mode(self):
7302
modesplitconfigs = self.get_attrsman().get_group('modal split')
7303
ids_mode = np.zeros(len(modesplitconfigs), dtype=np.int32)
7304
i = 0
7305
for modeconfig in modesplitconfigs:
7306
ids_mode[i] = modeconfig.id_mode
7307
i += 1
7308
return ids_mode
7309
7310
def get_modes_random(self, n):
7311
"""
7312
Return a vector with mode IDs of length n.
7313
"""
7314
# print 'get_modes_random',n
7315
modesplitconfigs = self.get_attrsman().get_group('modal split')
7316
ids_mode = np.zeros(len(modesplitconfigs), dtype=np.int32)
7317
shares = np.zeros(len(modesplitconfigs), dtype=np.float32)
7318
i = 0
7319
for modeconfig in modesplitconfigs:
7320
ids_mode[i] = modeconfig.id_mode
7321
shares[i] = modeconfig.get_value()
7322
i += 1
7323
# print ' ids_mode',ids_mode
7324
# print ' shares',shares
7325
return ids_mode[random_choice(n, shares/np.sum(shares))]
7326
7327
def get_ttb(self, ids_pers):
7328
n_pers = len(ids_pers)
7329
7330
# Truncated Normal dist with scipy
7331
# load libraries
7332
#import scipy.stats as stats
7333
# lower, upper, mu, and sigma are four parameters
7334
#lower, upper = 0.5, 1
7335
#mu, sigma = 0.6, 0.1
7336
# instantiate an object X using the above four parameters,
7337
#X = stats.truncnorm((lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma)
7338
# generate 1000 sample data
7339
#samples = X.rvs(1000)
7340
7341
return np.random.normal(self.ttb_mean, self.ttb_dev, n_pers).clip(0, 2*3600)
7342
7343
7344
class PopFromOdfGenerator(Process):
7345
def __init__(self, ident, virtualpop, logger=None, **kwargs):
7346
print 'PopFromOdfGenerator.__init__'
7347
7348
# TODO: let this be independent, link to it or child??
7349
7350
self._init_common(ident,
7351
parent=virtualpop,
7352
name='Pop from OD-flow generator',
7353
logger=logger,
7354
info='Create virtual population from origin-to-destination zone flows by disaggregation.',
7355
)
7356
7357
attrsman = self.set_attrsman(cm.Attrsman(self))
7358
7359
# make for each possible pattern a field for prob
7360
activitytypes = self.parent.get_scenario().demand.activitytypes
7361
7362
self.hour_offset = attrsman.add(cm.AttrConf('hour_offset', kwargs.get('hour_offset', 8.0),
7363
groupnames=['options'],
7364
perm='rw',
7365
name='Offset hours',
7366
unit='h',
7367
info='Hour when simulation starts. This is the hour (of the day) when simulation time shows zero seconds.',
7368
))
7369
7370
self.dist_walk_max = attrsman.add(cm.AttrConf('dist_walk_max', kwargs.get('dist_walk_max', 400),
7371
groupnames=['options'],
7372
perm='rw',
7373
name='Max. walking dist',
7374
unit='m',
7375
info="""Maximum distance that a person accepts to walk,
7376
either to reach the destination or to access any sort of vehicle (tranfers at bus stops, walking to carparking, etc).
7377
""",
7378
))
7379
7380
self.hour_tripbudget = attrsman.add(cm.AttrConf('hour_tripbudget', kwargs.get('hour_tripbudget', 0.5),
7381
groupnames=['options'],
7382
perm='rw',
7383
name='Triptime budget',
7384
unit='h',
7385
info="""Time budget for this trip. This time is used
7386
to initially estimate the time in hours between
7387
the activity at origin and the activity
7388
at destination.
7389
""",
7390
))
7391
7392
self.scale = attrsman.add(cm.AttrConf('scale', kwargs.get('scale', 1.0),
7393
groupnames=['options'],
7394
perm='rw',
7395
name='Scale',
7396
info='Global scale factor. Scales the number of all OD trips.',
7397
))
7398
7399
self.is_use_landusetypes = attrsman.add(cm.AttrConf('is_use_landusetypes', kwargs.get('is_use_landusetypes', False),
7400
groupnames=['options'],
7401
perm='rw',
7402
name='use landuse types',
7403
info="""If True, use the landuse type of
7404
facilities when assigning the origin and destination facility.
7405
The landuse type is selected according to the activity type.
7406
Use this option only if landuse types have been correctly defined for
7407
all facilities.
7408
""",
7409
))
7410
7411
self.is_update_landuse = attrsman.add(cm.AttrConf('is_update_landuse', kwargs.get('is_update_landuse', True),
7412
groupnames=['options'],
7413
perm='rw',
7414
name='update Landuse',
7415
info="""If True, update land use database (zones, facilities, parking) before generating the population. Updating means identifying edges and facilities within zones.
7416
""",
7417
))
7418
7419
def do(self):
7420
print 'PopFromOdfGenerator.do'
7421
# links
7422
7423
virtualpop = self.parent
7424
logger = self.get_logger()
7425
if self.is_update_landuse:
7426
logger.w('Update Landuse...')
7427
scenario = virtualpop.get_scenario()
7428
scenario.landuse.zones.refresh_zoneedges()
7429
scenario.landuse.facilities.identify_taz()
7430
scenario.landuse.facilities.identify_closest_edge()
7431
scenario.landuse.facilities.update()
7432
7433
logger.w('Create population...')
7434
virtualpop.create_pop_from_odflows(logger=logger, **self.get_kwoptions())
7435
#activitytypes = virtualpop.activitytypes
7436
return True
7437
7438
7439
class Planner(Process):
7440
def __init__(self, ident='planner', virtualpop=None, ids_strategy=None, logger=None, **kwargs):
7441
print 'Planner.__init__'
7442
# TODO: let this be independent, link to it or child??
7443
7444
self._init_common(ident,
7445
parent=virtualpop,
7446
name='Planner',
7447
logger=logger,
7448
info='Generates mobility plan for population for a specific mobility strategy. Plans are only generated for persons for whome the strategy is applicable.',
7449
)
7450
7451
attrsman = self.set_attrsman(cm.Attrsman(self))
7452
7453
# make for each possible pattern a field for prob
7454
strategies = virtualpop.get_strategies()
7455
7456
strategychoices = strategies.names.get_indexmap()
7457
7458
if (ids_strategy is None):
7459
# no info given, select all
7460
ids_strategy_default = strategychoices.values()
7461
7462
elif ids_strategy is not None:
7463
ids_strategy_default = ids_strategy
7464
7465
print ' ids_strategy_default', ids_strategy_default
7466
self.ids_strategy = attrsman.add(cm.ListConf('ids_strategy', ids_strategy_default,
7467
groupnames=['options'],
7468
choices=strategychoices,
7469
perm='rw',
7470
name='Strategies',
7471
info='Strategies to be used to create mobility plans.',
7472
))
7473
7474
evalcrits = {'apply to all persons if feasible': 0,
7475
'apply only if preferred mode is used': 1,
7476
'apply only if exclusively preferred mode is used': 2,
7477
}
7478
self.evalcrit = attrsman.add(cm.AttrConf('evalcrit', kwargs.get('evalcrit', evalcrits['apply to all persons if feasible']),
7479
groupnames=['options'],
7480
choices=evalcrits,
7481
perm='rw',
7482
name='Application criteria',
7483
info=""" Value that determines for which persons the plans will be generated.
7484
Apply to all persons if feasible:0
7485
Apply only if preferred mode is used:1
7486
Apply only if exclusively preferred mode is used:2
7487
""",
7488
))
7489
7490
self.is_plan_no_preferred = attrsman.add(cm.AttrConf('is_plan_no_preferred', kwargs.get('is_plan_no_preferred', False),
7491
groupnames=['options'],
7492
name='Plan for no preferred',
7493
info=""" If it is True: Generate new plans only for strategies that are different from the preferred strategies.
7494
If it is False: Generate new plans for all strategies
7495
""",
7496
))
7497
7498
def do(self):
7499
print 'Planner.do', len(self.ids_strategy)
7500
# links
7501
7502
virtualpop = self.parent
7503
logger = self.get_logger()
7504
#logger.w('Check applicability')
7505
#strategies = virtualpop.strategies.get_value()
7506
7507
# if self.id_strategy != -1:
7508
# virtualpop.plan_with_strategy(self.id_strategy, evalcrit = self.evalcrit, is_npm = self.is_new_planner_method, logger = logger)
7509
#
7510
# else: #plan with all strategies
7511
7512
i = 1
7513
strategies = virtualpop.get_strategies()
7514
print ' strategies:', self.ids_strategy, strategies.names[self.ids_strategy]
7515
print ' instances', strategies.strategies[self.ids_strategy]
7516
7517
n_strat = len(self.ids_strategy)
7518
for id_strategy, strategy in zip(self.ids_strategy, strategies.strategies[self.ids_strategy]):
7519
print ' current strategy', strategy, id(strategy)
7520
logger.w('Plan with '+strategy.get_name()+' (%d/%d)' % (i, n_strat))
7521
virtualpop.plan_with_strategy(id_strategy, evalcrit=self.evalcrit,
7522
is_plan_no_preferred=self.is_plan_no_preferred, logger=logger)
7523
i += 1
7524
7525
return True
7526
7527
7528
class PlanSelector(Process):
7529
def __init__(self, ident='planselector', virtualpop=None,
7530
ids_strategy=None, # not yet implemeted
7531
methodname='plan with shortest estim. time',
7532
logger=None, **kwargs):
7533
7534
print 'PlanSelector.__init__'
7535
7536
# TODO: let this be independent, link to it or child??
7537
7538
self._init_common(ident,
7539
parent=virtualpop,
7540
name='Plan Selector',
7541
logger=logger,
7542
info='Selects the plan for each person which will be executed during the next simulation run according to a defined selection method.',
7543
)
7544
7545
attrsman = self.set_attrsman(cm.Attrsman(self))
7546
7547
# make for each possible pattern a field for prob
7548
strategies = virtualpop.get_strategies()
7549
# strategychoices.update(strategies.names.get_indexmap())
7550
7551
strategychoices = strategies.names.get_indexmap()
7552
7553
# if (ids_strategy is None):
7554
# # no info given, select all
7555
# ids_strategy_default = strategychoices.values()
7556
#
7557
# elif ids_strategy is not None:
7558
# ids_strategy_default = ids_strategy
7559
7560
# print ' ids_strategy_default',ids_strategy_default
7561
# self.ids_strategy = attrsman.add(cm.ListConf( 'ids_strategy',ids_strategy_default,
7562
# groupnames = ['options'],
7563
# choices = strategychoices,
7564
# perm='rw',
7565
# name = 'Strategies',
7566
# info = 'Set of strategies from which one is selected per person for the next simulation run.',
7567
# ))
7568
7569
methods = {'plan with shortest estim. time': virtualpop.select_plans_min_time_est,
7570
'plan with shortest exec. time': virtualpop.select_plans_min_time_exec,
7571
'plan with preferred mode': virtualpop.select_plans_preferred_mode,
7572
'next plan in list': virtualpop.select_plans_next,
7573
'random plan': virtualpop.select_plans_random,
7574
'plan with shortest exec. time or est. time': virtualpop.select_plans_min_time_exec_est,
7575
'plan with utility function': virtualpop.select_plans_utility_function
7576
}
7577
7578
self.method = attrsman.add(cm.AttrConf('method', methods[methodname],
7579
groupnames=['options'],
7580
choices=methods,
7581
perm='rw',
7582
name='Selection method',
7583
info='Selection method used to select current plans.',
7584
))
7585
7586
self.fraction = attrsman.add(cm.AttrConf('fraction', kwargs.get('fraction', 1.0),
7587
groupnames=['options'],
7588
perm='rw',
7589
name='Change fraction',
7590
info="""Fraction of persons that are randomly chosen to change plans according to the defined method.
7591
A value of 1.0 mens that the plans of oll persons will be changed.""",
7592
))
7593
7594
self.timedev = attrsman.add(cm.AttrConf('timedev', kwargs.get('timedev', 0.0),
7595
groupnames=['options'],
7596
perm='rw',
7597
name='Time deviation',
7598
info="""Time deviation of random time component of estimated or effective time. If zero, no random time is added.
7599
Alternatively the probit constant can be given to quantify the amount of noise.
7600
""",
7601
))
7602
7603
self.c_probit = attrsman.add(cm.AttrConf('c_probit', kwargs.get('c_probit', 0.0),
7604
groupnames=['options'],
7605
perm='rw',
7606
name='Probit const',
7607
info="""Probit constant used to determine the deviation of the normal distributed random time component.
7608
The deviation is the product of this constant and the travel time. If zero, no random time is added.
7609
This is an alternative to explicitely giving the time deviation.""",
7610
))
7611
7612
def do(self):
7613
print 'Planner.do'
7614
# links
7615
7616
#virtualpop = self.parent
7617
logger = self.get_logger()
7618
#logger.w('Check applicability')
7619
return self.method(logger=logger,
7620
#ids_strategy = self.ids_strategy,
7621
**self.get_kwoptions()
7622
)
7623
7624
7625
class VehicleProvider(Process):
7626
def __init__(self, ident='vehicleprovider', virtualpop=None, logger=None, **kwargs):
7627
print 'VehicleProvider.__init__'
7628
7629
# TODO: let this be independent, link to it or child??
7630
7631
self._init_common(ident,
7632
parent=virtualpop,
7633
name='Vehicle Provider',
7634
logger=logger,
7635
info='Provides individual vehicles to persons according to preferred mode and giveb statistical data.',
7636
)
7637
7638
attrsman = self.set_attrsman(cm.Attrsman(self))
7639
7640
# make for each possible pattern a field for prob
7641
7642
self.share_autoowner = attrsman.add(cm.AttrConf('share_autoowner', kwargs.get('share_autoowner', 0.8),
7643
groupnames=['options'],
7644
perm='rw',
7645
name='Car auto share',
7646
info="""Share of auto owners. This specifies the share of auto owners and a car will be created for each car owner.
7647
Attention if prefeered mode has been already defined: persons who have bicicle as preferred mode get automatically a bike assigned.
7648
""",
7649
))
7650
7651
self.share_motorcycleowner = attrsman.add(cm.AttrConf('share_motorcycleowner', kwargs.get('share_motorcycleowner', 0.3),
7652
groupnames=['options'],
7653
perm='rw',
7654
name='Motorcycle owner share',
7655
info="""Share of Motorcycle owners. This specifies the share of Motorcycle owners and a bike will be created for each Motorcycle owner.
7656
Attention if prefeered mode has been already defined: persons who have Motorcycle as preferred mode get automatically a Motorcycle assigned.
7657
""",
7658
))
7659
7660
self.share_bikeowner = attrsman.add(cm.AttrConf('share_bikeowner', kwargs.get('share_bikeowner', 0.5),
7661
groupnames=['options'],
7662
perm='rw',
7663
name='Bike owner share',
7664
info="""Share of bike owners. This specifies the share of bike owners and a bike will be created for each bike owner.
7665
Attention if prefeered mode has been already defined: persons who have bicicle as preferred mode get automatically a bike assigned.
7666
""",
7667
))
7668
7669
def do(self):
7670
print 'VehicleProvider.do'
7671
# links
7672
7673
virtualpop = self.parent
7674
logger = self.get_logger()
7675
logger.w('Provide vehicles...')
7676
7677
ids_person = virtualpop.get_ids()
7678
n_person = len(ids_person)
7679
modes = virtualpop.get_scenario().net.modes
7680
id_mode_bike = modes.get_id_mode('bicycle')
7681
id_mode_auto = modes.get_id_mode('passenger')
7682
id_mode_moto = modes.get_id_mode('motorcycle')
7683
7684
iautos = virtualpop.get_iautos()
7685
ibikes = virtualpop.get_ibikes()
7686
imotos = virtualpop.get_imotos()
7687
7688
logger.w('generate individual vehicles for prefered modes')
7689
ids_prefer_auto = virtualpop.select_ids(
7690
(virtualpop.ids_mode_preferred.get_value() == id_mode_auto) & (virtualpop.ids_iauto.get_value() == -1))
7691
ids_iauto = iautos.assign_to_persons(ids_prefer_auto)
7692
7693
n_current = iautos.get_share(is_abs=True)
7694
#n_none = int(self.share_autoowner*n_person)-(n_person-n_current)
7695
n_need = int(self.share_autoowner*n_person)-n_current
7696
if n_need > 0:
7697
ids_pers_miss = np.flatnonzero(virtualpop.ids_iauto.get_value() == -1)+1
7698
# print ' n_person,n_current,n_target,n_need,len(ids_pers_miss)',n_person,n_current,int(self.share_autoowner*n_person),n_need,len(ids_pers_miss)
7699
ids_pers_assign = np.random.choice(ids_pers_miss, n_need, replace=False)
7700
ids_iauto = iautos.assign_to_persons(ids_pers_assign)
7701
7702
print ' created %d autos, target share=%.2f, share = %.2f' % (iautos.get_share(is_abs=True), iautos.get_share(), self.share_autoowner)
7703
7704
ids_prefer_bike = virtualpop.select_ids(
7705
(virtualpop.ids_mode_preferred.get_value() == id_mode_bike) & (virtualpop.ids_ibike.get_value() == -1))
7706
ids_ibikes = ibikes.assign_to_persons(ids_prefer_bike)
7707
7708
n_current = ibikes.get_share(is_abs=True)
7709
n_need = int(self.share_bikeowner*n_person)-n_current
7710
if n_need > 0:
7711
ids_pers_miss = np.flatnonzero(virtualpop.ids_ibike.get_value() == -1)+1
7712
# print ' n_person,n_current,n_target,n_need,len(ids_pers_miss)',n_person,n_current,int(self.share_autoowner*n_person),n_need,len(ids_pers_miss)
7713
ids_pers_assign = np.random.choice(ids_pers_miss, n_need, replace=False)
7714
ids_ibike = ibikes.assign_to_persons(ids_pers_assign)
7715
7716
print ' created %d bikes, target share=%.2f, share = %.2f' % (ibikes.get_share(is_abs=True), ibikes.get_share(), self.share_bikeowner)
7717
7718
ids_prefer_moto = virtualpop.select_ids(
7719
(virtualpop.ids_mode_preferred.get_value() == id_mode_moto) & (virtualpop.ids_imoto.get_value() == -1))
7720
ids_imoto = imotos.assign_to_persons(ids_prefer_moto)
7721
7722
n_current = imotos.get_share(is_abs=True)
7723
n_need = int(self.share_motorcycleowner*n_person)-n_current
7724
if n_need > 0:
7725
ids_pers_miss = np.flatnonzero(virtualpop.ids_imoto.get_value() == -1)+1
7726
ids_pers_assign = np.random.choice(ids_pers_miss, n_need, replace=False)
7727
ids_imoto = imotos.assign_to_persons(ids_pers_assign)
7728
7729
print ' created %d moto, target share=%.2f, share = %.2f' % (imotos.get_share(is_abs=True), imotos.get_share(), self.share_motorcycleowner)
7730
return True
7731
7732
# TODO: generate and assign additional vehicles
7733
# to satisfy prescribes ownership
7734
7735