Line data Source code
1 : /****************************************************************************/ 2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo 3 : // Copyright (C) 2010-2024 German Aerospace Center (DLR) and others. 4 : // activitygen module 5 : // Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/) 6 : // This program and the accompanying materials are made available under the 7 : // terms of the Eclipse Public License 2.0 which is available at 8 : // https://www.eclipse.org/legal/epl-2.0/ 9 : // This Source Code may also be made available under the following Secondary 10 : // Licenses when the conditions for such availability set forth in the Eclipse 11 : // Public License 2.0 are satisfied: GNU General Public License, version 2 12 : // or later which is available at 13 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html 14 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later 15 : /****************************************************************************/ 16 : /// @file AGActivityGen.cpp 17 : /// @author Piotr Woznica 18 : /// @author Daniel Krajzewicz 19 : /// @author Walter Bamberger 20 : /// @author Michael Behrisch 21 : /// @date July 2010 22 : /// 23 : // Main class that handles City, Activities and Trips 24 : /****************************************************************************/ 25 : #include <config.h> 26 : 27 : #include <iostream> 28 : #include <utils/xml/XMLSubSys.h> 29 : #include <utils/common/MsgHandler.h> 30 : #include <utils/common/RandHelper.h> 31 : #include <sstream> 32 : #include "AGActivityGen.h" 33 : #include "AGActivityGenHandler.h" 34 : #include "city/AGPosition.h" 35 : #include "activities/AGActivities.h" 36 : #include "AGActivityTripWriter.h" 37 : #include "city/AGTime.h" 38 : 39 : 40 : // =========================================================================== 41 : // method definitions 42 : // =========================================================================== 43 : void 44 10 : AGActivityGen::importInfoCity() { 45 10 : AGActivityGenHandler handler(city, net); 46 20 : PROGRESS_BEGIN_MESSAGE(TL("Reading input")); 47 10 : if (!XMLSubSys::runParser(handler, inputFile)) { 48 1 : PROGRESS_FAILED_MESSAGE(); 49 1 : throw ProcessError(); 50 : } else { 51 9 : PROGRESS_DONE_MESSAGE(); 52 : } 53 : 54 18 : PROGRESS_BEGIN_MESSAGE(TL("Consolidating statistics")); 55 9 : city.statData.consolidateStat(); //some maps are still not 56 9 : PROGRESS_DONE_MESSAGE(); 57 : 58 18 : PROGRESS_BEGIN_MESSAGE(TL("Building street representation")); 59 9 : city.completeStreets(); 60 9 : PROGRESS_DONE_MESSAGE(); 61 : 62 18 : PROGRESS_BEGIN_MESSAGE(TL("Generating work positions")); 63 9 : city.generateWorkPositions(); 64 9 : PROGRESS_DONE_MESSAGE(); 65 : 66 18 : PROGRESS_BEGIN_MESSAGE(TL("Building bus lines")); 67 9 : city.completeBusLines(); 68 9 : PROGRESS_DONE_MESSAGE(); 69 : 70 : 71 18 : PROGRESS_BEGIN_MESSAGE(TL("Generating population")); 72 9 : city.generatePopulation(); 73 9 : PROGRESS_DONE_MESSAGE(); 74 : 75 18 : PROGRESS_BEGIN_MESSAGE(TL("Allocating schools")); 76 9 : city.schoolAllocation(); 77 9 : PROGRESS_DONE_MESSAGE(); 78 : 79 18 : PROGRESS_BEGIN_MESSAGE(TL("Allocating work places")); 80 9 : city.workAllocation(); 81 9 : PROGRESS_DONE_MESSAGE(); 82 : 83 18 : PROGRESS_BEGIN_MESSAGE(TL("Allocating car places")); 84 9 : city.carAllocation(); 85 9 : PROGRESS_DONE_MESSAGE(); 86 10 : } 87 : 88 : bool 89 7665 : AGActivityGen::timeTripValidation(const AGTrip& trip) const { 90 7665 : if (trip.getDay() > durationInDays + 1) { 91 : return false; 92 : } 93 7624 : if (trip.getDay() == 1) { //first day 94 3814 : if (trip.getTime() < beginTime) { 95 : return false; 96 : } 97 3814 : if (durationInDays == 0 && trip.getTime() > endTime) { 98 : return false; 99 : } 100 : } 101 7624 : if (trip.getDay() == durationInDays + 1) { //last day 102 3810 : if (trip.getTime() > endTime) { 103 : return false; 104 : } 105 0 : if (durationInDays == 0 && trip.getTime() < beginTime) { 106 0 : return false; 107 : } 108 : } 109 : return true; 110 : } 111 : 112 : void 113 7665 : AGActivityGen::varDepTime(AGTrip& trip) const { 114 15330 : if (trip.getType() != "default") { 115 3049 : return; 116 : } 117 : //buses are on time and random are already spread 118 4616 : int variation = (int)RandHelper::randNorm(0, city.statData.departureVariation); 119 4616 : AGTime depTime(trip.getDay(), 0, 0, trip.getTime()); 120 4616 : depTime += variation; 121 4616 : if (depTime.getDay() > 0) { 122 4616 : trip.setDay(depTime.getDay()); 123 4616 : trip.setDepTime(depTime.getSecondsInCurrentDay()); 124 : } else { 125 0 : trip.setDay(1); 126 0 : trip.setDepTime(0); 127 : } 128 : } 129 : 130 : 131 : void 132 8 : AGActivityGen::generateOutputFile(std::list<AGTrip>& trips) { 133 8 : AGActivityTripWriter atw(outputFile); 134 8 : if (trips.size() != 0) { 135 : std::list<AGTrip>::iterator it; 136 : //variables for TESTS: 137 7 : int firstTrip = trips.front().getTime() + trips.front().getDay() * 86400; 138 7 : int lastTrip = trips.front().getTime() + trips.front().getDay() * 86400; 139 : std::map<int, int> histogram; 140 707 : for (int i = 0; i < 100; ++i) { 141 700 : histogram[i] = 0; 142 : } 143 : //END var TESTS 144 3821 : for (it = trips.begin(); it != trips.end(); ++it) { 145 3814 : atw.addTrip(*it); 146 : //TEST 147 3814 : if (it->getTime() + 86400 * it->getDay() > lastTrip) { 148 3198 : lastTrip = it->getTime() + 86400 * it->getDay(); 149 : } 150 3814 : if (it->getTime() + 86400 * it->getDay() < firstTrip) { 151 0 : firstTrip = it->getTime() + 86400 * it->getDay(); 152 : } 153 : //++histogram[((it->getDay()-1)*86400 + it->getTime())/3600]; 154 3814 : ++histogram[(it->getTime()) / 3600]; 155 : //END TEST 156 : } 157 : //PRINT TEST 158 : AGTime first(firstTrip); 159 : AGTime last(lastTrip); 160 28 : std::cout << "first real trip: " << first.getDay() << ", " << first.getHour() << ":" << first.getMinute() << ":" << first.getSecond() << std::endl; 161 28 : std::cout << "last real trip: " << last.getDay() << ", " << last.getHour() << ":" << last.getMinute() << ":" << last.getSecond() << std::endl; 162 707 : for (int i = 0; i < 100; ++i) { 163 700 : if (histogram[i] > 0) { 164 166 : std::cout << "histogram[ hour " << i << " ] = " << histogram[i] << std::endl; 165 : } 166 : } 167 : } else { 168 : std::cout << "No real trips were generated" << std::endl; 169 : } 170 8 : } 171 : 172 : void 173 9 : AGActivityGen::makeActivityTrips(int days, int beginSec, int endSec) { 174 9 : durationInDays = days; 175 9 : beginTime = beginSec; 176 9 : endTime = endSec; 177 : /** 178 : * making the activity trips 179 : */ 180 9 : AGActivities acts(&city, durationInDays + 1); 181 9 : acts.generateActivityTrips(); 182 : 183 : /** 184 : * validating the trips with the simulation's time limits 185 : */ 186 : //list<Trip>* trips = &(acts.trips); 187 : std::list<AGTrip> expTrips; 188 : std::map<std::string, int> carUsed; 189 : std::list<AGTrip>::iterator it; 190 : //multiplication of days 191 4929 : for (it = acts.trips.begin(); it != acts.trips.end(); ++it) { 192 4921 : if (it->isDaily()) { 193 8232 : for (int currday = 1; currday < durationInDays + 2; ++currday) { 194 10976 : AGTrip tr(it->getDep(), it->getArr(), it->getVehicleName(), it->getTime(), currday); 195 10976 : tr.setType(it->getType()); 196 5488 : if (carUsed.find(tr.getVehicleName()) != carUsed.end()) { 197 4469 : ++carUsed.find(tr.getVehicleName())->second; 198 : } else { 199 1019 : carUsed[tr.getVehicleName()] = 1; 200 : } 201 5488 : std::ostringstream os; 202 10976 : os << tr.getVehicleName() << ":" << carUsed.find(tr.getVehicleName())->second; 203 5488 : tr.setVehicleName(os.str()); 204 5488 : tr.addLayOverWithoutDestination(*it); //intermediate destinations are taken in account too 205 5488 : varDepTime(tr); //slight variation on each "default" car 206 5488 : if (timeTripValidation(tr)) { 207 : expTrips.push_back(tr); 208 : } 209 : //else 210 : //std::cout << "trop tard 1 pour " << tr.getVehicleName() << " " << tr.getTime() << " day: " << tr.getDay() << std::endl; 211 5488 : } 212 : } else { 213 4354 : AGTrip tr(it->getDep(), it->getArr(), it->getVehicleName(), it->getTime(), it->getDay()); 214 4354 : tr.setType(it->getType()); 215 2177 : if (carUsed.find(tr.getVehicleName()) != carUsed.end()) { 216 500 : ++carUsed.find(tr.getVehicleName())->second; 217 : } else { 218 1677 : carUsed[tr.getVehicleName()] = 1; 219 : } 220 2177 : std::ostringstream os; 221 4354 : os << tr.getVehicleName() << ":" << carUsed.find(tr.getVehicleName())->second; 222 2177 : tr.setVehicleName(os.str()); 223 2177 : tr.addLayOverWithoutDestination(*it); //intermediate destinations are taken in account too 224 2177 : varDepTime(tr); //slight variation on each "default" car 225 2177 : if (timeTripValidation(tr)) { 226 : expTrips.push_back(tr); 227 : } 228 : //else 229 : //std::cout << "trop tard 2 pour " << tr.getVehicleName() << " " << tr.getTime() << " day: " << tr.getDay() << std::endl; 230 2177 : } 231 : } 232 : 233 : std::cout << "total trips generated: " << acts.trips.size() << std::endl; 234 : std::cout << "total trips finally taken: " << expTrips.size() << std::endl; 235 : 236 : /** 237 : * re-ordering of trips: SUMO needs routes ordered by departure time. 238 : */ 239 8 : expTrips.sort(); //natural order of trips 240 : std::cout << "...sorted by departure time.\n" << std::endl; 241 : 242 : /** 243 : * trip file generation 244 : */ 245 8 : generateOutputFile(expTrips); 246 8 : } 247 : 248 : 249 : /****************************************************************************/