1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 2# Copyright (C) 2016-2019 German Aerospace Center (DLR) and others. 3# SUMOPy module 4# Copyright (C) 2012-2017 University of Bologna - DICAM 5# This program and the accompanying materials 6# are made available under the terms of the Eclipse Public License v2.0 7# which accompanies this distribution, and is available at 8# http://www.eclipse.org/legal/epl-v20.html 9# SPDX-License-Identifier: EPL-2.0 10 11# @file demandbase.py 12# @author Joerg Schweizer 13# @date 14# @version $Id$ 15 16 17import numpy as np 18import agilepy.lib_base.classman as cm 19import agilepy.lib_base.arrayman as am 20import agilepy.lib_base.xmlman as xm 21from agilepy.lib_base.misc import random_choice, get_inversemap 22 23OPTIONMAP_POS_DEPARTURE = {"random": -1, "free": -2, 24 "random_free": -3, "base": -4, "last": -5, "first": -6} 25OPTIONMAP_POS_ARRIVAL = {"random": -1, "max": -2} 26OPTIONMAP_SPEED_DEPARTURE = {"random": -1, "max": -2} 27OPTIONMAP_SPEED_ARRIVAL = {"current": -1} 28OPTIONMAP_LANE_DEPART = {"random": -1, "free": 2, 29 "allowed": -3, "best": -4, "first": -5} 30OPTIONMAP_LANE_ARRIVAL = {"current": -1} 31 32 33class ModeShares(am.ArrayObjman): 34 """ 35 Utility table with some default mode shares. 36 """ 37 38 def __init__(self, ident, parent, modes, **kwargs): 39 40 self._init_objman(ident, parent=parent, name='Mode shares', 41 version=0.0, 42 **kwargs) 43 44 self.add_col(am.IdsArrayConf('ids_mode', modes, 45 groupnames=['parameters'], 46 name='Mode ID', 47 info='Transport Mode ID.', 48 )) 49 50 self.add_col(am.ArrayConf('shares', '', 51 dtype=np.float32, 52 is_index=True, 53 groupnames=['parameters'], 54 perm='rw', 55 name='Share', 56 info='Mode share.', 57 )) 58 59 # self.add_col(am.ArrayConf( 'speeds_max', 50.0/3.6, 60 # dtype = np.float32, 61 # groupnames = ['parameters'], 62 # perm='rw', 63 # name = 'Max. Speed', 64 # unit = 'm/s', 65 # info = 'Maximum possible speed for this mode. Speed is used to estimate free flow link travel times, mainly for routig purposes. Note that speeds are usully limited by the lane speed attribute', 66 # )) 67 self._init_attributes() 68 self.add_default() 69 70 def _init_attributes(self, landuse=None): 71 # self.add_col(SumoIdsConf('Activitytypes')) 72 pass 73 74 def add_share(self, mode, share): 75 modes = self.ids_mode.get_linktab() 76 return self.add_row(ids_mode=modes.get_id_from_formatted(mode), 77 shares=share) 78 79 def add_default(self): 80 """ 81 Sets the default maximum possible speed for certain modes. 82 """ 83 self.add_share("pedestrian", 0.1) 84 self.add_share("bicycle", 0.1) 85 self.add_share("motorcycle", 0.1) 86 self.add_share("passenger", 0.5) 87 self.add_share("bus", 0.2) 88 89 def get_modes_random(self, n): 90 """ 91 Return a vector with mode IDs of length n. 92 """ 93 ids = self.get_ids() 94 ids_modes_all = self.ids_mode[ids] 95 return ids_modes_all[random_choice(n, self.shares[ids])] 96 97 98class ActivityTypes(am.ArrayObjman): 99 # http://www.sumo.dlr.de/userdoc/Networks/Building_Networks_from_own_XML-descriptions.html#Edge_Descriptions 100 def __init__(self, ident, demand, **kwargs): 101 102 self._init_objman(ident, parent=demand, name='Activity Types', 103 version=0.0, 104 xmltag=('actTypes', 'actType', 'names'), 105 **kwargs) 106 107 self._init_attributes() 108 self.add_default() 109 110 def _init_attributes(self, landuse=None): 111 # self.add_col(SumoIdsConf('Activitytypes')) 112 113 self.add_col(am.ArrayConf('names', '', 114 dtype=np.object, 115 is_index=True, 116 groupnames=['parameters'], 117 perm='rw', 118 name='Type name', 119 info='Human readable name of activity type.', 120 )) 121 122 self.add_col(am.ArrayConf('symbols', '', 123 dtype=np.object, 124 perm='rw', 125 is_index=True, 126 name='Type symbol', 127 info='Symbol of activity type name. Used to represent activity sequences.', 128 )) 129 130 self.add_col(am.ArrayConf('descriptions', '', 131 dtype=np.object, 132 perm='rw', 133 name='Description', 134 info='Description of activity.', 135 )) 136 137 # this works only for first init 138 # if landuse is not None: 139 self.add_col(am.IdlistsArrayConf('ids_landusetypes', self.parent.get_scenario().landuse.landusetypes, 140 name='Landuse types', 141 info="Landuse type IDs, eher this activity type can take place.", 142 )) 143 144 self.add_col(am.ArrayConf('hours_begin_earliest', 0.0, 145 dtype=np.float32, 146 groupnames=['parameters'], 147 perm='rw', 148 name='Earliest hour begin', 149 unit='h', 150 info='Default value for earliest hour when this activity can begin.', 151 )) 152 153 self.add_col(am.ArrayConf('hours_begin_latest', 1.0, 154 dtype=np.float32, 155 groupnames=['parameters'], 156 perm='rw', 157 name='Latest begin hour', 158 unit='h', 159 info='Default value for latest hour when this activity can begin.', 160 )) 161 162 self.add_col(am.ArrayConf('durations_min', 6.0, 163 dtype=np.float32, 164 groupnames=['parameters'], 165 perm='rw', 166 name='Min. Duration', 167 unit='h', 168 info='Default value for minimum activity duration for a person within a day.', 169 )) 170 171 self.add_col(am.ArrayConf('durations_max', 8.0, 172 dtype=np.float32, 173 groupnames=['parameters'], 174 perm='rw', 175 name='Max. Duration', 176 unit='h', 177 info='Default value for maximum activity duration for a person within a day.', 178 )) 179 180 def format_ids(self, ids): 181 return ', '.join(self.names[ids]) 182 183 def get_id_from_formatted(self, idstr): 184 return self.names.get_id_from_index(idstr) 185 186 def get_ids_from_formatted(self, idstrs): 187 return self.names.get_ids_from_indices_save(idstrs.split(',')) 188 189 def get_id_from_name(self, activitytypename): 190 return self.names.get_id_from_index(activitytypename) 191 192 def get_id_from_symbol(self, activitytypesymbol): 193 return self.symbols.get_id_from_index(activitytypesymbol) 194 195 def add_default(self): 196 """ 197 Sets the default maximum possible speed for certain modes. 198 """ 199 landusetypekeys = self.parent.get_scenario().landuse.landusetypes.typekeys 200 self.add_row(names='none', 201 descriptions='None activity type. Will be skipped when planning.', 202 ids_landusetypes=landusetypekeys.get_ids_from_indices([]), 203 symbols='n', 204 hours_begin_earliest=0.0, 205 hours_begin_latest=0.0, 206 durations_min=0.0, 207 durations_max=0.0, 208 ) 209 210 self.add_row(names='home', 211 descriptions='General home activity, like sleeping, eating, watching TV, etc.', 212 ids_landusetypes=landusetypekeys.get_ids_from_indices( 213 ['residential', 'mixed']), 214 symbols='h', 215 hours_begin_earliest=-1.0, 216 hours_begin_latest=-1.0, 217 durations_min=7.0, 218 durations_max=8.0, 219 ) 220 221 self.add_row(names='work', 222 descriptions="""Work activity, for example work in 223 industry, offices or as employee at 224 educational facilities.""", 225 ids_landusetypes=landusetypekeys.get_ids_from_indices( 226 ['industrial', 'commercial', 'education', 'mixed']), 227 symbols='w', 228 hours_begin_earliest=8.5, 229 hours_begin_latest=9.0, 230 durations_min=6.0, 231 durations_max=9.0, 232 ) 233 234 self.add_row(names='education', 235 descriptions='Education activity, for example visiting courses at schools or at universities.', 236 ids_landusetypes=landusetypekeys.get_ids_from_indices( 237 ['education', ]), 238 symbols='e', 239 hours_begin_earliest=8.0, 240 hours_begin_latest=10.0, 241 durations_min=4.0, 242 durations_max=6.0, 243 ) 244 245 self.add_row(names='shopping', 246 descriptions='Shopping activity', 247 ids_landusetypes=landusetypekeys.get_ids_from_indices( 248 ['commercial', 'mixed']), 249 symbols='s', 250 hours_begin_earliest=16.0, 251 hours_begin_latest=19.0, 252 durations_min=0.2, 253 durations_max=2.0, 254 ) 255 256 self.add_row(names='leisure', 257 descriptions='Leisure activity', 258 ids_landusetypes=landusetypekeys.get_ids_from_indices( 259 ['leisure', 'mixed']), 260 symbols='l', 261 hours_begin_earliest=12.0, 262 hours_begin_latest=15.0, 263 durations_min=1.0, 264 durations_max=3.0, 265 ) 266 267 268class DemandobjMixin: 269 def export_trips_xml(self, filepath=None, encoding='UTF-8', 270 ids_vtype_exclude=[]): 271 """ 272 Export trips to SUMO xml file. 273 Method takes care of sorting trips by departure time. 274 """ 275 return False 276 277 def get_writexmlinfo(self, is_route=False): 278 """ 279 Returns three array where the first array is the 280 begin time of the first vehicle and the second array is the 281 write function to be called for the respectice vehicle and 282 the third array contains the vehicle ids 283 284 Method used to sort trips when exporting to route or trip xml file 285 """ 286 return [], [], [] 287 288 def config_results(self, results): 289 # tripresults = res.Tripresults( 'tripresults', results, 290 # self, 291 # self.get_net().edges 292 # ) 293 # 294 # 295 #results.add_resultobj(tripresults, groupnames = ['Trip results']) 296 pass 297 298 def process_results(self, results, process=None): 299 pass 300 301 def get_time_depart_first(self): 302 return np.inf 303 304 def get_time_depart_last(self): 305 return 0.0 306