From d7335e9783966d2b505268a1208a67648446a551 Mon Sep 17 00:00:00 2001 From: Lara CODECA Date: Tue, 27 Apr 2021 08:15:16 +0100 Subject: [PATCH 1/3] additional flags added to some stage --- activitygen.py | 102 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 21 deletions(-) diff --git a/activitygen.py b/activitygen.py index 371b997..f196e81 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,6 +593,8 @@ 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: + if isinstance(step, tuple): + step, _ = step # handle flags _current_depart_time += step.travelTime _person_steps.append(step) @@ -656,9 +660,12 @@ def _generate_waiting_stage(self, stage): RIDE_BUS = """ """ - RIDE_TRIGGERED = """ + RIDE_TRIGGERED_TO = """ """ + RIDE_TRIGGERED_BUSSTOP = """ + """ + VEHICLE_TRIGGERED = """ {route}{stops} """ @@ -681,7 +688,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,29 +700,60 @@ 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)) + flags = {} + if isinstance(stage, tuple): + # we have additionals associated to the stage + stage, flags = 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: + # print(os.linesep, stage) + # print('Expectation:', self.WAIT.format(lane=stage.edges, duration=stage.travelTime, action=stage.description)) + # print("FLAG True", stage.toXML(True)) + # print("FLAG False", stage.toXML(False)) + # print(os.linesep) _waiting_stages.append(stage) stages += self.WAIT.format(lane=stage.edges, duration=stage.travelTime, action=stage.description) elif stage.type == tc.STAGE_WALKING: + # print(os.linesep, stage) + + # stages += stage.toXML(_is_first_stage) + # if stage.arrivalPos: + # _last_arrival_pos = stage.arrivalPos + if stage.destStop: stages += self.WALK_BUS.format( edges=' '.join(stage.edges), busStop=stage.destStop) + # print('Expectation:', 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) + # print('Expectation:', 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)) + # print('Expectation:', self.WALK.format(edges=' '.join(stage.edges))) + # print("FLAG True", stage.toXML(True)) + # print("FLAG False", stage.toXML(False)) + # print(os.linesep) 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 + # print(os.linesep, stage) + # print('Expectation:', self.RIDE_BUS.format(busStop=stage.destStop, lines=stage.line, intended=stage.intended, depart=stage.depart)) + # print("FLAG True", stage.toXML(True)) + # print("FLAG False", stage.toXML(False)) + # stages += os.linesep + "\t" + stage.toXML(_is_first_stage).rstrip() + "/>" + # print("Generated: ", os.linesep + "\t\t" + stage.toXML(_is_first_stage).rstrip() + "/>") + # print(os.linesep) stages += self.RIDE_BUS.format( busStop=stage.destStop, lines=stage.line, intended=stage.intended, depart=stage.depart) @@ -748,18 +786,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 +812,34 @@ 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) + # print(os.linesep + "ORIGINAL:", stage) + # print('Expectation:', self.RIDE_TRIGGERED.format(from_edge=stage.edges[0], to_edge=stage.edges[-1], vehicle_id=_ride_id, arrival=stage.arrivalPos)) + # print("FLAG True", stage.toXML(True)) + # print("FLAG False", stage.toXML(False)) + # stage.line = _ride_id + # stage.intended = _ride_id + # print(os.linesep + "FIXED:", stage) + # print("FLAG True", stage.toXML(True)) + # print("FLAG False", stage.toXML(False)) + # stages += os.linesep + "\t" + stage.toXML(_is_first_stage).rstrip() + " arrivalPos=\"{}\"/>".format(stage.arrivalPos) + # print("Generated: ", os.linesep + "\t" + stage.toXML(_is_first_stage).rstrip() + " arrivalPos=\"{}\"/>".format(stage.arrivalPos)) + # print(os.linesep) + # print(stage.destStop, stage) + if stage.destStop: #and stage.destStop != self.LAST_STOP_PLACEHOLDER and not _is_parking_area: + # print('RIDE_TRIGGERED_BUSSTOP!') + stages += self.RIDE_TRIGGERED_BUSSTOP.format( + from_edge=stage.edges[0], busStop=stage.destStop, + vehicle_id=_ride_id, arrival=stage.arrivalPos) + else: + # print('RIDE_TRIGGERED_TO!') + stages += self.RIDE_TRIGGERED_TO.format( + from_edge=stage.edges[0], to_edge=stage.edges[-1], + vehicle_id=_ride_id, arrival=stage.arrivalPos) self.logger.debug('Stages: %s', stages) + _is_first_stage = False + # input() self.logger.debug(' -- Next stage -- ') ## fixing the personal triggered vehicles @@ -801,7 +861,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 ## ---------------------------------------------------------------------------------------- ## From 121f6934a840dc6bc63249f3f8e7d083f769aad8 Mon Sep 17 00:00:00 2001 From: Lara CODECA Date: Tue, 27 Apr 2021 19:03:21 +0100 Subject: [PATCH 2/3] First implementation for https://github.com/eclipse/sumo/issues/8517 --- activitygen.py | 75 +++++--------------------------------------------- 1 file changed, 7 insertions(+), 68 deletions(-) diff --git a/activitygen.py b/activitygen.py index f196e81..36d4515 100755 --- a/activitygen.py +++ b/activitygen.py @@ -710,59 +710,20 @@ def _generate_sumo_trip_from_activitygen(self, person): 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: - # print(os.linesep, stage) - # print('Expectation:', self.WAIT.format(lane=stage.edges, duration=stage.travelTime, action=stage.description)) - # print("FLAG True", stage.toXML(True)) - # print("FLAG False", stage.toXML(False)) - # print(os.linesep) _waiting_stages.append(stage) stages += self.WAIT.format(lane=stage.edges, duration=stage.travelTime, action=stage.description) elif stage.type == tc.STAGE_WALKING: - # print(os.linesep, stage) - - # stages += stage.toXML(_is_first_stage) - # if stage.arrivalPos: - # _last_arrival_pos = stage.arrivalPos - - if stage.destStop: - stages += self.WALK_BUS.format( - edges=' '.join(stage.edges), busStop=stage.destStop) - # print('Expectation:', 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) - # print('Expectation:', 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)) - # print('Expectation:', self.WALK.format(edges=' '.join(stage.edges))) - # print("FLAG True", stage.toXML(True)) - # print("FLAG False", stage.toXML(False)) - # print(os.linesep) + 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 - # print(os.linesep, stage) - # print('Expectation:', self.RIDE_BUS.format(busStop=stage.destStop, lines=stage.line, intended=stage.intended, depart=stage.depart)) - # print("FLAG True", stage.toXML(True)) - # print("FLAG False", stage.toXML(False)) - # stages += os.linesep + "\t" + stage.toXML(_is_first_stage).rstrip() + "/>" - # print("Generated: ", os.linesep + "\t\t" + stage.toXML(_is_first_stage).rstrip() + "/>") - # print(os.linesep) - 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' @@ -812,34 +773,12 @@ def _generate_sumo_trip_from_activitygen(self, person): self.logger.debug('_triggered_stops: %s', _triggered_stops) - # print(os.linesep + "ORIGINAL:", stage) - # print('Expectation:', self.RIDE_TRIGGERED.format(from_edge=stage.edges[0], to_edge=stage.edges[-1], vehicle_id=_ride_id, arrival=stage.arrivalPos)) - # print("FLAG True", stage.toXML(True)) - # print("FLAG False", stage.toXML(False)) - # stage.line = _ride_id - # stage.intended = _ride_id - # print(os.linesep + "FIXED:", stage) - # print("FLAG True", stage.toXML(True)) - # print("FLAG False", stage.toXML(False)) - # stages += os.linesep + "\t" + stage.toXML(_is_first_stage).rstrip() + " arrivalPos=\"{}\"/>".format(stage.arrivalPos) - # print("Generated: ", os.linesep + "\t" + stage.toXML(_is_first_stage).rstrip() + " arrivalPos=\"{}\"/>".format(stage.arrivalPos)) - # print(os.linesep) - # print(stage.destStop, stage) - if stage.destStop: #and stage.destStop != self.LAST_STOP_PLACEHOLDER and not _is_parking_area: - # print('RIDE_TRIGGERED_BUSSTOP!') - stages += self.RIDE_TRIGGERED_BUSSTOP.format( - from_edge=stage.edges[0], busStop=stage.destStop, - vehicle_id=_ride_id, arrival=stage.arrivalPos) - else: - # print('RIDE_TRIGGERED_TO!') - stages += self.RIDE_TRIGGERED_TO.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 - # input() self.logger.debug(' -- Next stage -- ') ## fixing the personal triggered vehicles From b996db04c08523f633e225ceda9a5ee82e2264aa Mon Sep 17 00:00:00 2001 From: Lara CODECA Date: Tue, 27 Apr 2021 23:36:17 +0100 Subject: [PATCH 3/3] addressing the {stage, flags} bug --- activitygen.py | 11 +++++------ agsrc/sumoutils.py | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/activitygen.py b/activitygen.py index 36d4515..ddfb96f 100755 --- a/activitygen.py +++ b/activitygen.py @@ -594,8 +594,10 @@ 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: if isinstance(step, tuple): - step, _ = step # handle flags - _current_depart_time += step.travelTime + _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. ======================') @@ -703,10 +705,7 @@ def _generate_sumo_trip_from_activitygen(self, person): _is_first_stage = True _is_parking_area = False for stage in person['stages']: - flags = {} - if isinstance(stage, tuple): - # we have additionals associated to the stage - stage, flags = 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: 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