diff --git a/activitygen.py b/activitygen.py
index 371b997..ddfb96f 100755
--- a/activitygen.py
+++ b/activitygen.py
@@ -68,7 +68,7 @@ class ModeShare(Enum):
PROBABILITY = 1
WEIGHT = 2
- LAST_STOP_PLACEHOLDER = -42.42
+ # LAST_STOP_PLACEHOLDER = -42.42
def _configure_loggers(self):
""" Setup the console and file logger. """
@@ -174,7 +174,7 @@ def _load_vtypes_distributions(self, filename):
elif child.tag == 'vTypeDistribution':
for subchild in child:
self._vtype_to_vclasses[child.attrib['id']].append(subchild.attrib['vClass'])
- self.logger.debug('vTypes loaded: \n%s', pformat(self._vtype_to_vclasses))
+ self.logger.debug('vTypes loaded: ' + os.linesep + '%s', pformat(self._vtype_to_vclasses))
## ---------------------------------------------------------------------------------------- ##
## Mobility Generation ##
@@ -467,8 +467,10 @@ def _generate_intermodal_trip_traci(self, from_area, to_area, activity_chain, mo
mode, route,
self._conf['intermodalOptions']['vehicleAllowedParking']) and
route[-1].type == tc.STAGE_DRIVING):
- route[-1].destStop = p_id
- route[-1].arrivalPos = self._env.get_parking_position(p_id)
+ # Additional parking tag to be added to the stage.
+ parking_stage = route[-1]
+ parking_stage.arrivalPos = self._env.get_parking_position(p_id)
+ route[-1] = (parking_stage, {'parkingArea': p_id})
route.extend(_last_mile)
else:
route = None
@@ -535,7 +537,7 @@ def _generate_intermodal_trip_traci(self, from_area, to_area, activity_chain, mo
# check if it's required to add the walk back to the vehicle and
# change the stage.fromEdge of the next stage.
self.logger.debug(
- 'Check walking back requirements for route \n%s', pformat(route))
+ 'Check walking back requirements for route ' + os.linesep + '%s', pformat(route))
if route[-2].type == tc.STAGE_WALKING:
# generate the walk back
from_edge = route[-2].edges[-1] # end ow the walking stage
@@ -557,7 +559,7 @@ def _generate_intermodal_trip_traci(self, from_area, to_area, activity_chain, mo
raise sagaexceptions.TripGenerationRouteError(
'Route not found for the walk back from {} to {}.'.format(
from_edge, to_edge))
- self.logger.debug('Walk back: \n%s', pformat(walk_back))
+ self.logger.debug('Walk back: ' + os.linesep + '%s', pformat(walk_back))
if walk_back and not isinstance(walk_back, list):
# list in until SUMO 1.4.0 included, tuple onward
walk_back = list(walk_back)
@@ -574,16 +576,16 @@ def _generate_intermodal_trip_traci(self, from_area, to_area, activity_chain, mo
else:
raise sagaexceptions.TripGenerationInconsistencyError(
'Final route misses last waiting stage.', _person_stages)
- ## change the last triggered ride with LAST_STOP_PLACEHOLDER to fix the last stop
+ ## Adding to the last triggered ride the lastStop=True flag to fix the last stop
if _mode not in ['public', 'taxi'] and _ptype not in ['pedestrian']:
_pos = len(route) - 1
while _pos >= 0:
if route[_pos].type == tc.STAGE_DRIVING:
- route[_pos].destStop = self.LAST_STOP_PLACEHOLDER
+ route[_pos] = (route[_pos], {'lastStop': True})
break
_pos -= 1
- self.logger.debug('Route: \n%s', pformat(route))
+ self.logger.debug('Route: ' + os.linesep +' %s', pformat(route))
if route is None:
raise sagaexceptions.TripGenerationRouteError(
@@ -591,7 +593,11 @@ def _generate_intermodal_trip_traci(self, from_area, to_area, activity_chain, mo
## Add the stage to the full planned trip.
for step in route:
- _current_depart_time += step.travelTime
+ if isinstance(step, tuple):
+ _sumo_step, _flags = sumoutils.unpack_stage(step) # handle flags
+ _current_depart_time += _sumo_step.travelTime
+ else:
+ _current_depart_time += step.travelTime
_person_steps.append(step)
self.logger.debug('====================== Stage done. ======================')
@@ -656,9 +662,12 @@ def _generate_waiting_stage(self, stage):
RIDE_BUS = """
"""
- RIDE_TRIGGERED = """
+ RIDE_TRIGGERED_TO = """
"""
+ RIDE_TRIGGERED_BUSSTOP = """
+ """
+
VEHICLE_TRIGGERED = """
{route}{stops}
"""
@@ -681,7 +690,7 @@ def _generate_stop_position(self, edge, position):
def _generate_sumo_trip_from_activitygen(self, person):
""" Generate the XML string for SUMO route file from a person-trip. """
self.logger.debug(' ............... _generate_sumo_trip_from_activitygen ............... ')
- self.logger.debug('\n%s', pformat(person))
+ self.logger.debug('' + os.linesep + '%s', pformat(person))
self.logger.debug(' ............... computation ............... ')
complete_trip = ''
triggered = ''
@@ -693,38 +702,27 @@ def _generate_sumo_trip_from_activitygen(self, person):
_last_arrival_pos = None
_internal_consistency_check = []
_waiting_stages = []
+ _is_first_stage = True
+ _is_parking_area = False
for stage in person['stages']:
- self.logger.debug('Stage \n%s', pformat(stage))
+ stage, flags = sumoutils.unpack_stage(stage)
+ self.logger.debug('Stage ' + os.linesep + '%s', pformat(stage))
+ self.logger.debug('Associated flags ' + os.linesep + '%s', pformat(flags))
if stage.type == tc.STAGE_WAITING:
_waiting_stages.append(stage)
stages += self.WAIT.format(lane=stage.edges,
duration=stage.travelTime,
action=stage.description)
elif stage.type == tc.STAGE_WALKING:
- if stage.destStop:
- stages += self.WALK_BUS.format(
- edges=' '.join(stage.edges), busStop=stage.destStop)
- else:
- if stage.arrivalPos:
- stages += self.WALK_W_ARRIVAL.format(
- edges=' '.join(stage.edges), arrival=stage.arrivalPos)
- _last_arrival_pos = stage.arrivalPos
- else:
- stages += self.WALK.format(edges=' '.join(stage.edges))
+ if stage.arrivalPos:
+ _last_arrival_pos = stage.arrivalPos
+ stages += os.linesep + "\t" + stage.toXML(_is_first_stage)
elif stage.type == tc.STAGE_DRIVING:
if stage.line != stage.intended:
# Public Transports
- # !!! vType MISSING !!! line=164:0, intended=pt_bus_164:0.50
- # intended is the transport id, so it must be different
- stages += self.RIDE_BUS.format(
- busStop=stage.destStop, lines=stage.line,
- intended=stage.intended, depart=stage.depart)
+ stages += os.linesep + "\t" + stage.toXML(_is_first_stage)
else:
# Triggered vehicle (vTyep == line == intended)
- # vType=bicycle, line=bicycle, intended=bicycle
- # vType=passenger, line=passenger, intended=passenger
- # vType=motorcycle, line=motorcycle, intended=motorcycle
- # vType=on-demand, line=on-demand, intended=on-demand
_ride_id = None
if stage.intended == 'on-demand':
_ride_id = 'taxi'
@@ -748,18 +746,18 @@ def _generate_sumo_trip_from_activitygen(self, person):
_triggered_vtype = stage.vType
_stop = ''
self.logger.debug(
- 'travelTime: %f - destStop: %s', stage.travelTime, stage.destStop)
- if stage.destStop == self.LAST_STOP_PLACEHOLDER:
+ 'travelTime: %f - destStop: %s', stage.travelTime, stage.destStop) # this many need fixing
+ if 'lastStop' in flags:
self.logger.debug('Final stop reached.')
_stop = self.FINAL_STOP.format(
lane=self._env.get_stopping_lane(
stage.edges[-1], self._vtype_to_vclasses[_triggered_vtype]))
else:
- if stage.destStop and stage.vType in self._conf[
- 'intermodalOptions']['vehicleAllowedParking']:
+ if 'parkingArea' in flags:
self.logger.debug('Generate the stop in a parking area.')
_stop = self.STOP_PARKING_TRIGGERED.format(
- id=stage.destStop, person=person['id'])
+ id=flags['parkingArea'], person=person['id'])
+ _is_parking_area = True
else:
self.logger.debug('Generate the stop on the side of the road.')
start, end = self._generate_stop_position(
@@ -774,12 +772,12 @@ def _generate_sumo_trip_from_activitygen(self, person):
self.logger.debug('_triggered_stops: %s', _triggered_stops)
- stages += self.RIDE_TRIGGERED.format(
- from_edge=stage.edges[0], to_edge=stage.edges[-1], vehicle_id=_ride_id,
- arrival=stage.arrivalPos)
-
+ stage.line = _ride_id
+ stage.intended = _ride_id
+ stages += os.linesep + "\t" + stage.toXML(_is_first_stage)
self.logger.debug('Stages: %s', stages)
+ _is_first_stage = False
self.logger.debug(' -- Next stage -- ')
## fixing the personal triggered vehicles
@@ -801,7 +799,7 @@ def _generate_sumo_trip_from_activitygen(self, person):
complete_trip += self.PERSON.format(
id=person['id'], depart=person['depart'], stages=stages)
- self.logger.debug('Complete trip: \n%s', complete_trip)
+ self.logger.debug('Complete trip: ' + os.linesep + '%s', complete_trip)
return complete_trip
## ---------------------------------------------------------------------------------------- ##
diff --git a/agsrc/sumoutils.py b/agsrc/sumoutils.py
index 057d931..c81ecd4 100644
--- a/agsrc/sumoutils.py
+++ b/agsrc/sumoutils.py
@@ -23,14 +23,16 @@ def cost_from_route(route):
""" Compute the route cost. """
cost = 0.0
for stage in route:
- cost += stage.cost
+ _stage, _ = unpack_stage(stage)
+ cost += _stage.cost
return cost
def ett_from_route(route):
""" Compute the route etimated travel time. """
ett = 0.0
for stage in route:
- ett += stage.travelTime
+ _stage, _ = unpack_stage(stage)
+ ett += _stage.travelTime
return ett
def get_intermodal_mode_parameters(mode, parking_requirements):
@@ -62,14 +64,24 @@ def is_valid_route(mode, route, parking_requirements):
return True
elif _mode == 'public':
for stage in route:
- if stage.line:
+ _stage, _ = unpack_stage(stage)
+ if _stage.line:
return True
elif _mode in ('car', 'bicycle') or _vtype in parking_requirements:
for stage in route:
- if stage.type == tc.STAGE_DRIVING and len(stage.edges) >= 2:
+ _stage, _ = unpack_stage(stage)
+ if _stage.type == tc.STAGE_DRIVING and len(_stage.edges) >= 2:
return True
else:
for stage in route:
- if len(stage.edges) >= 2:
+ _stage, _ = unpack_stage(stage)
+ if len(_stage.edges) >= 2:
return True
return False
+
+def unpack_stage(stage):
+ _stage = stage
+ _flags = {}
+ if isinstance(stage, tuple):
+ _stage, _flags = stage
+ return _stage, _flags