Path: blob/main/src/activitygen/activities/AGFreeTime.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2010-2025 German Aerospace Center (DLR) and others.3// activitygen module4// Copyright 2010 TUM (Technische Universitaet Muenchen, http://www.tum.de/)5// This program and the accompanying materials are made available under the6// terms of the Eclipse Public License 2.0 which is available at7// https://www.eclipse.org/legal/epl-2.0/8// This Source Code may also be made available under the following Secondary9// Licenses when the conditions for such availability set forth in the Eclipse10// Public License 2.0 are satisfied: GNU General Public License, version 211// or later which is available at12// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html13// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later14/****************************************************************************/15/// @file AGFreeTime.cpp16/// @author Piotr Woznica17/// @author Daniel Krajzewicz18/// @author Walter Bamberger19/// @author Michael Behrisch20/// @date July 201021///22// Generates trips related to after-work activities23// like visiting the family or party.24/****************************************************************************/25#include <config.h>2627#include <cmath>28#include <utils/common/RandHelper.h>29#include <utils/common/StdDefs.h>30#include <activitygen/city/AGCity.h>31#include <activitygen/city/AGTime.h>32#include "AGFreeTime.h"333435// ===========================================================================36// static member definitions37// ===========================================================================38const int AGFreeTime::DAY = 1;39const int AGFreeTime::EVENING = 2;40const int AGFreeTime::NIGHT = 4;4142const int AGFreeTime::TB_DAY = AGTime(0, 8, 0).getTime();43const int AGFreeTime::TE_DAY = AGTime(0, 18, 0).getTime();44const int AGFreeTime::TB_EVENING = AGTime(0, 19, 0).getTime();45const int AGFreeTime::TE_EVENING = AGTime(0, 23, 59).getTime();46const int AGFreeTime::TB_NIGHT = AGTime(0, 23, 0).getTime();47const int AGFreeTime::TE_NIGHT = AGTime(1, 5, 0).getTime();484950// ===========================================================================51// method definitions52// ===========================================================================53int54AGFreeTime::decideTypeOfTrip() {55if (myHousehold->getAdults().front().decide(freqOut)) {56int num_poss = 0; //(possibleType % 2) + (possibleType / 4) + ((possibleType / 2) % 2);57if (possibleType & DAY) {58++num_poss;59}60if (possibleType & EVENING) {61++num_poss;62}63if (possibleType & NIGHT) {64++num_poss;65}6667if (num_poss == 0) {68return 0;69}70double alea = RandHelper::rand(); //(float)(rand() % 1000) / 1000.0;71int decision = (int)floor(alea * (double)num_poss);7273if (possibleType & DAY) {74if (decision == 0) {75return DAY;76} else {77--decision;78}79}80if (possibleType & EVENING) {81if (decision == 0) {82return EVENING;83} else {84--decision;85}86}87if (possibleType & NIGHT) {88if (decision == 0) {89return NIGHT;90}91}92}93return 0;94}9596int97AGFreeTime::possibleTypeOfTrip() {98int val = 0;99if (myHousehold->getAdults().front().getAge() >= myStatData->limitAgeRetirement && tReady == 0) {100val += DAY + EVENING;101} else {102if (myHousehold->getPeopleNbr() > myHousehold->getAdultNbr()) {103val += NIGHT;104}105106std::list<AGAdult>::const_iterator itA;107bool noBodyWorks = true;108for (itA = myHousehold->getAdults().begin(); itA != myHousehold->getAdults().end(); ++itA) {109if (itA->isWorking()) {110noBodyWorks = false;111}112}113if (noBodyWorks) {114val += DAY;115}116117if (tReady < AGTime(0, 22, 0).getTime()) {118val += EVENING;119}120}121return val;122}123124bool125AGFreeTime::typeFromHomeDay(int day) {126int backHome = whenBackHomeThisDay(day);127if (myHousehold->getCars().empty()) {128return true;129}130AGPosition destination(myHousehold->getTheCity()->getRandomStreet());131int depTime = randomTimeBetween(MAX2(backHome, TB_DAY), (TB_DAY + TE_DAY) / 2);132int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);133int retTime = randomTimeBetween(arrTime, TE_DAY);134if (depTime < 0 || retTime < 0) {135return true; // not enough time during the day136}137AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), depTime, day);138AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), retTime, day);139140myPartialActivityTrips.push_back(depTrip);141myPartialActivityTrips.push_back(retTrip);142return true;143}144145bool146AGFreeTime::typeFromHomeEvening(int day) {147int backHome = whenBackHomeThisDay(day);148if (myHousehold->getCars().empty()) {149return true;150}151AGPosition destination(myHousehold->getTheCity()->getRandomStreet());152int depTime = randomTimeBetween(MAX2(backHome, TB_EVENING), TE_EVENING);153int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);154int retTime = randomTimeBetween(arrTime, TE_EVENING);155if (depTime < 0 || retTime < 0) {156return true; // not enough time during the day157}158AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), depTime, day);159AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), retTime, day);160161myPartialActivityTrips.push_back(depTrip);162myPartialActivityTrips.push_back(retTrip);163return true;164}165166bool167AGFreeTime::typeFromHomeNight(int day) {168int backHome = whenBackHomeThisDay(day);169int ActivitiesNextDay = whenBeginActivityNextDay(day); // is equal to 2 days if there is nothing the next day170int nextDay = 0;171if (myHousehold->getCars().empty()) {172return true;173}174AGPosition destination(myHousehold->getTheCity()->getRandomStreet());175176int depTime = randomTimeBetween(MAX2(backHome, TB_NIGHT), TE_NIGHT);177int arrTime = this->arrHour(myHousehold->getPosition(), destination, depTime);178//we have to go back home before the beginning of next day activities.179int lastRetTime = this->depHour(destination, myHousehold->getPosition(), MIN2(TE_NIGHT, ActivitiesNextDay));180int retTime = randomTimeBetween(arrTime, lastRetTime);181if (depTime < 0 || retTime < 0) {182return true; // not enough time during the day183}184185AGTime departureTime(depTime);186nextDay = departureTime.getDay();187departureTime.setDay(0);188AGTrip depTrip(myHousehold->getPosition(), destination, myHousehold->getCars().front().getName(), departureTime.getTime(), day + nextDay);189190AGTime returnTime(depTime);191nextDay = returnTime.getDay();192returnTime.setDay(0);193AGTrip retTrip(destination, myHousehold->getPosition(), myHousehold->getCars().front().getName(), returnTime.getTime(), day + nextDay);194195myPartialActivityTrips.push_back(depTrip);196myPartialActivityTrips.push_back(retTrip);197return true;198}199200bool201AGFreeTime::generateTrips() {202tReady = whenBackHome();203possibleType = possibleTypeOfTrip();204int type;205206for (int day = 1; day <= nbrDays; ++day) {207type = decideTypeOfTrip();208if (type == 0) {209continue;210} else if (type == DAY) {211if (!typeFromHomeDay(day)) {212return false;213}214} else if (type == EVENING) {215if (!typeFromHomeEvening(day)) {216return false;217}218} else if (type == NIGHT) {219if (!typeFromHomeNight(day)) {220return false;221}222}223}224genDone = true;225return genDone;226}227228int229AGFreeTime::whenBackHome() {230int timeBack = 0;231for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {232if (timeBack < itT->getArrTime(this->timePerKm) && itT->isDaily()) {233timeBack = itT->getArrTime(this->timePerKm);234}235}236return timeBack;237}238239int240AGFreeTime::whenBackHomeThisDay(int day) {241int timeBack = 0;242for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {243if (timeBack < itT->getArrTime(this->timePerKm) && (itT->getDay() == day || itT->isDaily())) {244timeBack = itT->getArrTime(this->timePerKm);245}246}247return timeBack;248}249250int251AGFreeTime::whenBeginActivityNextDay(int day) {252AGTime timeBack(1, 0, 0);253for (std::list<AGTrip>::iterator itT = myPreviousTrips->begin(); itT != myPreviousTrips->end(); ++itT) {254if (timeBack.getTime() > itT->getTime() && (itT->getDay() == (day + 1) || itT->isDaily())) {255timeBack.setTime(itT->getTime());256}257}258timeBack.addDays(1); // this the beginning of activities of the next day259return timeBack.getTime();260}261262263/****************************************************************************/264265266