Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 40 additions & 42 deletions activitygen.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. """
Expand Down Expand Up @@ -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 ##
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -574,24 +576,28 @@ 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(
'Route not found between {} and {}.'.format(stage.fromEdge, stage.toEdge))

## 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. ======================')
Expand Down Expand Up @@ -656,9 +662,12 @@ def _generate_waiting_stage(self, stage):
RIDE_BUS = """
<ride busStop="{busStop}" lines="{lines}" intended="{intended}" depart="{depart}"/>"""

RIDE_TRIGGERED = """
RIDE_TRIGGERED_TO = """
<ride from="{from_edge}" to="{to_edge}" arrivalPos="{arrival}" lines="{vehicle_id}"/>"""

RIDE_TRIGGERED_BUSSTOP = """
<ride from="{from_edge}" busStop="{busStop}" arrivalPos="{arrival}" lines="{vehicle_id}"/>"""

VEHICLE_TRIGGERED = """
<vehicle id="{id}" type="{v_type}" depart="triggered">{route}{stops}
</vehicle>"""
Expand All @@ -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 = ''
Expand All @@ -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'
Expand All @@ -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(
Expand All @@ -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
Expand All @@ -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

## ---------------------------------------------------------------------------------------- ##
Expand Down
22 changes: 17 additions & 5 deletions agsrc/sumoutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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