Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/activitygen/activities/AGFreeTime.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2010-2025 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 AGFreeTime.cpp
17
/// @author Piotr Woznica
18
/// @author Daniel Krajzewicz
19
/// @author Walter Bamberger
20
/// @author Michael Behrisch
21
/// @date July 2010
22
///
23
// Generates trips related to after-work activities
24
// like visiting the family or party.
25
/****************************************************************************/
26
#include <config.h>
27
28
#include <cmath>
29
#include <utils/common/RandHelper.h>
30
#include <utils/common/StdDefs.h>
31
#include <activitygen/city/AGCity.h>
32
#include <activitygen/city/AGTime.h>
33
#include "AGFreeTime.h"
34
35
36
// ===========================================================================
37
// static member definitions
38
// ===========================================================================
39
const int AGFreeTime::DAY = 1;
40
const int AGFreeTime::EVENING = 2;
41
const int AGFreeTime::NIGHT = 4;
42
43
const int AGFreeTime::TB_DAY = AGTime(0, 8, 0).getTime();
44
const int AGFreeTime::TE_DAY = AGTime(0, 18, 0).getTime();
45
const int AGFreeTime::TB_EVENING = AGTime(0, 19, 0).getTime();
46
const int AGFreeTime::TE_EVENING = AGTime(0, 23, 59).getTime();
47
const int AGFreeTime::TB_NIGHT = AGTime(0, 23, 0).getTime();
48
const int AGFreeTime::TE_NIGHT = AGTime(1, 5, 0).getTime();
49
50
51
// ===========================================================================
52
// method definitions
53
// ===========================================================================
54
int
55
AGFreeTime::decideTypeOfTrip() {
56
if (myHousehold->getAdults().front().decide(freqOut)) {
57
int num_poss = 0; //(possibleType % 2) + (possibleType / 4) + ((possibleType / 2) % 2);
58
if (possibleType & DAY) {
59
++num_poss;
60
}
61
if (possibleType & EVENING) {
62
++num_poss;
63
}
64
if (possibleType & NIGHT) {
65
++num_poss;
66
}
67
68
if (num_poss == 0) {
69
return 0;
70
}
71
double alea = RandHelper::rand(); //(float)(rand() % 1000) / 1000.0;
72
int decision = (int)floor(alea * (double)num_poss);
73
74
if (possibleType & DAY) {
75
if (decision == 0) {
76
return DAY;
77
} else {
78
--decision;
79
}
80
}
81
if (possibleType & EVENING) {
82
if (decision == 0) {
83
return EVENING;
84
} else {
85
--decision;
86
}
87
}
88
if (possibleType & NIGHT) {
89
if (decision == 0) {
90
return NIGHT;
91
}
92
}
93
}
94
return 0;
95
}
96
97
int
98
AGFreeTime::possibleTypeOfTrip() {
99
int val = 0;
100
if (myHousehold->getAdults().front().getAge() >= myStatData->limitAgeRetirement && tReady == 0) {
101
val += DAY + EVENING;
102
} else {
103
if (myHousehold->getPeopleNbr() > myHousehold->getAdultNbr()) {
104
val += NIGHT;
105
}
106
107
std::list<AGAdult>::const_iterator itA;
108
bool noBodyWorks = true;
109
for (itA = myHousehold->getAdults().begin(); itA != myHousehold->getAdults().end(); ++itA) {
110
if (itA->isWorking()) {
111
noBodyWorks = false;
112
}
113
}
114
if (noBodyWorks) {
115
val += DAY;
116
}
117
118
if (tReady < AGTime(0, 22, 0).getTime()) {
119
val += EVENING;
120
}
121
}
122
return val;
123
}
124
125
bool
126
AGFreeTime::typeFromHomeDay(int day) {
127
int backHome = whenBackHomeThisDay(day);
128
if (myHousehold->getCars().empty()) {
129
return true;
130
}
131
AGPosition destination(myHousehold->getTheCity()->getRandomStreet());
132
int depTime = randomTimeBetween(MAX2(backHome, TB_DAY), (TB_DAY + TE_DAY) / 2);
133
int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);
134
int retTime = randomTimeBetween(arrTime, TE_DAY);
135
if (depTime < 0 || retTime < 0) {
136
return true; // not enough time during the day
137
}
138
AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), depTime, day);
139
AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), retTime, day);
140
141
myPartialActivityTrips.push_back(depTrip);
142
myPartialActivityTrips.push_back(retTrip);
143
return true;
144
}
145
146
bool
147
AGFreeTime::typeFromHomeEvening(int day) {
148
int backHome = whenBackHomeThisDay(day);
149
if (myHousehold->getCars().empty()) {
150
return true;
151
}
152
AGPosition destination(myHousehold->getTheCity()->getRandomStreet());
153
int depTime = randomTimeBetween(MAX2(backHome, TB_EVENING), TE_EVENING);
154
int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);
155
int retTime = randomTimeBetween(arrTime, TE_EVENING);
156
if (depTime < 0 || retTime < 0) {
157
return true; // not enough time during the day
158
}
159
AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), depTime, day);
160
AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), retTime, day);
161
162
myPartialActivityTrips.push_back(depTrip);
163
myPartialActivityTrips.push_back(retTrip);
164
return true;
165
}
166
167
bool
168
AGFreeTime::typeFromHomeNight(int day) {
169
int backHome = whenBackHomeThisDay(day);
170
int ActivitiesNextDay = whenBeginActivityNextDay(day); // is equal to 2 days if there is nothing the next day
171
int nextDay = 0;
172
if (myHousehold->getCars().empty()) {
173
return true;
174
}
175
AGPosition destination(myHousehold->getTheCity()->getRandomStreet());
176
177
int depTime = randomTimeBetween(MAX2(backHome, TB_NIGHT), TE_NIGHT);
178
int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);
179
//we have to go back home before the beginning of next day activities.
180
int lastRetTime = this->depHour(destination, myHousehold->getPosition(), MIN2(TE_NIGHT, ActivitiesNextDay));
181
int retTime = randomTimeBetween(arrTime, lastRetTime);
182
if (depTime < 0 || retTime < 0) {
183
return true; // not enough time during the day
184
}
185
186
AGTime departureTime(depTime);
187
nextDay = departureTime.getDay();
188
departureTime.setDay(0);
189
AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), departureTime.getTime(), day + nextDay);
190
191
AGTime returnTime(depTime);
192
nextDay = returnTime.getDay();
193
returnTime.setDay(0);
194
AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), returnTime.getTime(), day + nextDay);
195
196
myPartialActivityTrips.push_back(depTrip);
197
myPartialActivityTrips.push_back(retTrip);
198
return true;
199
}
200
201
bool
202
AGFreeTime::generateTrips() {
203
tReady = whenBackHome();
204
possibleType = possibleTypeOfTrip();
205
int type;
206
207
for (int day = 1; day <= nbrDays; ++day) {
208
type = decideTypeOfTrip();
209
if (type == 0) {
210
continue;
211
} else if (type == DAY) {
212
if (!typeFromHomeDay(day)) {
213
return false;
214
}
215
} else if (type == EVENING) {
216
if (!typeFromHomeEvening(day)) {
217
return false;
218
}
219
} else if (type == NIGHT) {
220
if (!typeFromHomeNight(day)) {
221
return false;
222
}
223
}
224
}
225
genDone = true;
226
return genDone;
227
}
228
229
int
230
AGFreeTime::whenBackHome() {
231
int timeBack = 0;
232
for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {
233
if (timeBack < itT->getArrTime(this->timePerKm) && itT->isDaily()) {
234
timeBack = itT->getArrTime(this->timePerKm);
235
}
236
}
237
return timeBack;
238
}
239
240
int
241
AGFreeTime::whenBackHomeThisDay(int day) {
242
int timeBack = 0;
243
for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {
244
if (timeBack < itT->getArrTime(this->timePerKm) && (itT->getDay() == day || itT->isDaily())) {
245
timeBack = itT->getArrTime(this->timePerKm);
246
}
247
}
248
return timeBack;
249
}
250
251
int
252
AGFreeTime::whenBeginActivityNextDay(int day) {
253
AGTime timeBack(1, 0, 0);
254
for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {
255
if (timeBack.getTime() > itT->getTime() && (itT->getDay() == (day + 1) || itT->isDaily())) {
256
timeBack.setTime(itT->getTime());
257
}
258
}
259
timeBack.addDays(1); // this the beginning of activities of the next day
260
return timeBack.getTime();
261
}
262
263
264
/****************************************************************************/
265
266