Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2013-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file MSTransportableDevice_FCDReplay.cpp
15 : /// @author Michael Behrisch
16 : /// @date 04.03.2024
17 : ///
18 : // A device which replays recorded floating car data
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <utils/options/OptionsCont.h>
23 : #include <libsumo/Person.h>
24 : #include <microsim/MSEdge.h>
25 : #include <microsim/MSEventControl.h>
26 : #include <microsim/MSLane.h>
27 : #include <microsim/MSNet.h>
28 : #include <microsim/devices/MSDevice_Transportable.h>
29 : #include <microsim/transportables/MSPerson.h>
30 : #include <microsim/transportables/MSStageWalking.h>
31 : #include <microsim/transportables/MSTransportable.h>
32 : #include <microsim/transportables/MSTransportableControl.h>
33 : #include "MSTransportableDevice_FCDReplay.h"
34 :
35 :
36 : // ===========================================================================
37 : // static member initializations
38 : // ===========================================================================
39 : bool MSTransportableDevice_FCDReplay::myAmActive = false;
40 :
41 :
42 : // ===========================================================================
43 : // method definitions
44 : // ===========================================================================
45 : // ---------------------------------------------------------------------------
46 : // static initialisation methods
47 : // ---------------------------------------------------------------------------
48 : void
49 0 : MSTransportableDevice_FCDReplay::insertOptions(OptionsCont& oc) {
50 0 : insertDefaultAssignmentOptions("fcd-replay", "FCD Replay Device", oc, true);
51 0 : }
52 :
53 :
54 : void
55 513493 : MSTransportableDevice_FCDReplay::buildDevices(MSTransportable& t, std::vector<MSTransportableDevice*>& into) {
56 513493 : OptionsCont& oc = OptionsCont::getOptions();
57 1026986 : if (equippedByDefaultAssignmentOptions(oc, "fcd-replay", t, oc.isSet("device.fcd-replay.file"), true)) {
58 164 : MSTransportableDevice_FCDReplay* device = new MSTransportableDevice_FCDReplay(t, "fcdReplay_" + t.getID());
59 164 : into.push_back(device);
60 164 : if (!myAmActive) {
61 8 : MSNet::getInstance()->getBeginOfTimestepEvents()->addEvent(new MovePedestrians(), SIMSTEP + DELTA_T);
62 8 : myAmActive = true;
63 : }
64 : }
65 513493 : }
66 :
67 :
68 : // ---------------------------------------------------------------------------
69 : // MSTransportableDevice_FCDReplay-methods
70 : // ---------------------------------------------------------------------------
71 164 : MSTransportableDevice_FCDReplay::MSTransportableDevice_FCDReplay(MSTransportable& holder, const std::string& id) :
72 164 : MSTransportableDevice(holder, id) {
73 164 : }
74 :
75 :
76 328 : MSTransportableDevice_FCDReplay::~MSTransportableDevice_FCDReplay() {
77 328 : }
78 :
79 :
80 : bool
81 22764 : MSTransportableDevice_FCDReplay::move(SUMOTime currentTime) {
82 22764 : if (!myHolder.hasDeparted()) { // need to check this first for trajectories of size 1
83 : return false;
84 : }
85 17244 : if (myTrajectory == nullptr || myTrajectoryIndex == (int)myTrajectory->size()) {
86 : // removing person
87 : return true;
88 : }
89 17080 : MSPerson* person = dynamic_cast<MSPerson*>(&myHolder);
90 17080 : const auto& te = myTrajectory->at(myTrajectoryIndex);
91 17080 : if (person == nullptr || te.time > currentTime) {
92 : return false;
93 : }
94 17080 : if (person->getCurrentStageType() == MSStageType::DRIVING) {
95 4428 : if (person->getVehicle() == nullptr) { // entering the vehicle
96 1528 : const MSEdge* const edge = person->getEdge();
97 1820 : for (const SUMOVehicle* v : edge->getVehicles()) {
98 292 : if (v->getSpeed() == 0. && fabs(v->getPositionOnLane() - te.lanePos) < POSITION_EPS) {
99 40 : v->getLane()->getVehiclesSecure(); // lock the lane
100 40 : SUMOTime dummy = -1; // boarding- and loading-time are not considered
101 40 : MSNet::getInstance()->getPersonControl().loadAnyWaiting(edge, const_cast<SUMOVehicle*>(v), dummy, dummy, person);
102 40 : v->getLane()->releaseVehicles(); // unlock the lane
103 : }
104 1528 : }
105 : } else {
106 : SUMOVehicle* v = person->getVehicle();
107 2900 : if (te.speed == 0. && fabs(v->getPositionOnLane() - te.lanePos) >= POSITION_EPS) { // leaving the vehicle
108 40 : v->getLane()->getVehiclesSecure(); // lock the lane
109 40 : MSDevice_Transportable* transDev = static_cast<MSDevice_Transportable*>(v->getDevice(typeid(MSDevice_Transportable)));
110 40 : transDev->removeTransportable(person);
111 40 : person->proceed(MSNet::getInstance(), currentTime);
112 40 : v->getLane()->releaseVehicles(); // unlock the lane
113 : }
114 : }
115 : }
116 17080 : if (person->getCurrentStageType() == MSStageType::WALKING) {
117 : try {
118 11572 : libsumo::Person::moveToXY(person->getID(), te.edgeOrLane, te.pos.x(), te.pos.y(), te.angle, 7, 0.1);
119 0 : } catch (const libsumo::TraCIException& e) {
120 0 : WRITE_WARNING(e.what());
121 0 : }
122 : MSStageWalking* walk = static_cast<MSStageWalking*>(person->getCurrentStage());
123 11572 : if (myTrajectoryIndex > 0 && myTrajectory->at(myTrajectoryIndex - 1).edgeOrLane != te.edgeOrLane) {
124 316 : walk->moveToNextEdge(person, currentTime, 1, nullptr, true);
125 : }
126 : }
127 : // person->setPreviousSpeed(std::get<3>(p), std::numeric_limits<double>::min());
128 17080 : myTrajectoryIndex++;
129 17080 : return false;
130 : }
131 :
132 :
133 8 : MSTransportableDevice_FCDReplay::MovePedestrians::MovePedestrians() {
134 : // higher than default command priority of 0
135 8 : priority = 1;
136 8 : }
137 :
138 :
139 : SUMOTime
140 2136 : MSTransportableDevice_FCDReplay::MovePedestrians::execute(SUMOTime currentTime) {
141 2136 : MSTransportableControl& c = MSNet::getInstance()->getPersonControl();
142 : std::vector<MSTransportableDevice_FCDReplay*> devices;
143 24900 : for (MSTransportableControl::constVehIt i = c.loadedBegin(); i != c.loadedEnd(); ++i) {
144 22764 : MSTransportableDevice_FCDReplay* device = static_cast<MSTransportableDevice_FCDReplay*>(i->second->getDevice(typeid(MSTransportableDevice_FCDReplay)));
145 22764 : if (device != nullptr) {
146 22764 : devices.push_back(device);
147 : }
148 : }
149 24900 : for (MSTransportableDevice_FCDReplay* d : devices) {
150 22764 : if (d->move(currentTime)) {
151 164 : d->getHolder().removeStage(0, false);
152 : }
153 : }
154 2136 : return DELTA_T;
155 2136 : }
156 :
157 :
158 : /****************************************************************************/
|