Eclipse SUMO - Simulation of Urban MObility
MSPModel_Remote.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2014-2023 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/****************************************************************************/
18// The pedestrian following model for remote controlled pedestrian movement
19/****************************************************************************/
20
21#include <jps.h>
22#include "microsim/MSEdge.h"
23#include "microsim/MSLane.h"
26#include "microsim/MSGlobals.h"
27#include "utils/geom/Position.h"
29#include "MSPModel_Remote.h"
30
31
32MSPModel_Remote::MSPModel_Remote(const OptionsCont& oc, MSNet* net) : myNet(net) {
33 initialize();
34 Event* e = new Event(this);
36}
37
38
41 assert(person->getCurrentStageType() == MSTransportable::MOVING_WITHOUT_VEHICLE);
42
43 PState* state = new PState(static_cast<MSPerson*>(person), stage);
44
45 JPS_Agent req;
46 int id = myLastId++;
47 remoteIdPStateMapping[id] = state;
48 /* req.set_id(id);
49
50 MSLane* departureLane = getFirstPedestrianLane(*(stage->getRoute().begin()));
51 double departureOffsetAlongLane = stage->getDepartPos();
52
53 //TODO fix this on casim side [GL]
54 double offset = departureOffsetAlongLane == 0 ? 0.4 : -0.4;
55 departureOffsetAlongLane += offset;
56
57 Position departurePos = departureLane->getShape().positionAtOffset(departureOffsetAlongLane);
58 hybridsim::Coordinate* departureCoordinate = req.mutable_enterlocation();
59 departureCoordinate->set_x(departurePos.x());
60 departureCoordinate->set_y(departurePos.y());
61
62 MSLane* arrivalLane = getFirstPedestrianLane(*(stage->getRoute().end() - 1));
63 double arrivalOffsetAlongLange = stage->getArrivalPos();
64 Position arrivalPos = arrivalLane->getShape().positionAtOffset(arrivalOffsetAlongLange);
65 hybridsim::Coordinate* arrivalCoordinate = req.mutable_leavelocation();
66 arrivalCoordinate->set_x(arrivalPos.x());
67 arrivalCoordinate->set_y(arrivalPos.y());
68
69
70 const MSEdge* prv = 0;
71 for (ConstMSEdgeVector::const_iterator it = stage->getRoute().begin(); it != stage->getRoute().end(); it++) {
72 const MSEdge* edge = *it;
73 int dir = FORWARD;//default
74 if (prv == 0) {
75 if (stage->getRoute().size() > 1) {
76 const MSEdge* nxt = *(it + 1);
77 dir = (edge->getFromJunction() == nxt->getFromJunction()
78 || edge->getFromJunction() == nxt->getToJunction()) ? BACKWARD : FORWARD;
79 } else {
80 dir = stage->getDepartPos() == 0 ? FORWARD : BACKWARD;
81 }
82 } else {
83 dir = (edge->getFromJunction() == prv->getToJunction()
84 || edge->getFromJunction() == prv->getFromJunction()) ? FORWARD : BACKWARD;
85 }
86 if (edgesTransitionsMapping.find(edge) == edgesTransitionsMapping.end()) {
87 throw ProcessError(TLF("Cannot map edge : % to remote simulation", edge->getID()));
88 };
89 std::tuple<int, int> transitions = edgesTransitionsMapping[edge];
90
91 int frId = dir == FORWARD ? std::get<0>(transitions) : std::get<1>(transitions);
92 int toId = dir == FORWARD ? std::get<1>(transitions) : std::get<0>(transitions);
93 hybridsim::Destination* destFr = req.add_dests();
94 destFr->set_id(frId);
95 hybridsim::Destination* destTo = req.add_dests();
96 destTo->set_id(toId);
97 prv = edge;
98 }
99
100 hybridsim::Boolean rpl;
101 ClientContext context;
102 Status st = myHybridsimStub->transferAgent(&context, req, &rpl);
103 if (!st.ok()) {
104 throw ProcessError(TLF("Person: % could not be transferred to remote simulation", person->getID()));
105 }
106 if (!rpl.val()) {
107 //TODO not yet implemented
108 throw ProcessError(TLF("Remote simulation declined to accept person: %.", person->getID()));
109 }
110 */
111 return state;
112}
113
115 /*
116 hybridsim::Empty req;
117 hybridsim::Empty rpl;
118 ClientContext context1;
119 Status st = myHybridsimStub->shutdown(&context1, req, &rpl);
120 if (!st.ok()) {
121 throw ProcessError(TL("Could not shutdown remote server"));
122 }
123
124 */
125}
126
127
130 /*
131 hybridsim::LeftClosedRightOpenTimeInterval interval;
132 interval.set_fromtimeincluding(time / DELTA_T);
133 interval.set_totimeexcluding((time + DELTA_T) / DELTA_T);
134
135
136 //1. simulate time interval
137 hybridsim::Empty rpl;
138 ClientContext context1;
139 Status st = myHybridsimStub->simulatedTimeInerval(&context1, interval, &rpl);
140 if (!st.ok()) {
141 throw ProcessError("Could not simulated time interval from: " + toString(time) + " to: " + toString(time + DELTA_T));
142 }
143
144 //2. receive trajectories
145 hybridsim::Empty req2;
146 hybridsim::Trajectories trajectories;
147 ClientContext context2;
148 Status st2 = myHybridsimStub->receiveTrajectories(&context2, req2, &trajectories);
149 if (!st2.ok()) {
150 throw ProcessError(TL("Could not receive trajectories from remote simulation"));
151 }
152 for (hybridsim::Trajectory trajectory : trajectories.trajectories()) {
153 if (remoteIdPStateMapping.find(trajectory.id()) != remoteIdPStateMapping.end()) {
154 PState* pState = remoteIdPStateMapping[trajectory.id()];
155 pState->setPosition(trajectory.x(), trajectory.y());
156 pState->setPhi(trajectory.phi());
157 if (transitionsEdgesMapping.find(trajectory.currentdest().id()) != transitionsEdgesMapping.end()) {
158 const MSEdge* nextTargetEdge = transitionsEdgesMapping[trajectory.currentdest().id()];
159 const MSEdge* nextStageEdge = pState->getStage()->getNextRouteEdge();
160 // const MSEdge* currentStageEdge = pState->getStage()->getEdge();
161 if (nextTargetEdge == nextStageEdge) {
162 const bool arrived = pState->getStage()->moveToNextEdge(pState->getPerson(), time);
163 std::cout << "next edge" << std::endl;
164 }
165 }
166 // pState.
167 } else {
168 throw ProcessError(TLF("Pedestrian with id: % is not known.", toString(trajectory.id())));
169 }
170 }
171
172 //3. retrieve agents that are ready to come back home to SUMO
173 hybridsim::Empty req3;
174 hybridsim::Agents agents;
175 ClientContext context3;
176 Status st3 = myHybridsimStub->queryRetrievableAgents(&context3, req3, &agents);
177 if (!st3.ok()) {
178 throw ProcessError(TL("Could not query retrievable agents"));
179 }
180 //TODO check whether agents can be retrieved
181 for (hybridsim::Agent agent : agents.agents()) {
182 if (remoteIdPStateMapping.find(agent.id()) != remoteIdPStateMapping.end()) {
183 PState* pState = remoteIdPStateMapping[agent.id()];
184 while (!pState->getStage()->moveToNextEdge(pState->getPerson(), time)) {
185 remoteIdPStateMapping.erase(agent.id());
186 }
187 }
188 }
189
190 //4. confirm transferred agents
191 hybridsim::Empty rpl2;
192 ClientContext context4;
193 Status st4 = myHybridsimStub->confirmRetrievedAgents(&context4, agents, &rpl2);
194 if (!st4.ok()) {
195 throw ProcessError(TL("Could not confirm retrieved agents"));
196 }
197 */
198 return DELTA_T;
199}
200
201
202MSLane*
204 for (MSLane* lane : edge->getLanes()) {
205 if (lane->getPermissions() == SVC_PEDESTRIAN) {
206 return lane;
207 }
208 }
209 throw ProcessError(TLF("Edge: % does not allow pedestrians.", edge->getID()));
210}
211
212
213void
215 // XXX do something here
216
217}
218
219
220void
222 JPS_SimulationContext* context = JPS_initialize("geometry_file");
223}
224
225
226
227// ===========================================================================
228// MSPModel_Remote::PState method definitions
229// ===========================================================================
231 : myPerson(person), myPhi(0), myPosition(0, 0), myStage(stage) {
232}
233
234
236}
237
238
240 return 0;
241}
242
244 return UNDEFINED_DIRECTION;
245}
246
248 return myPosition;
249}
250
251
253 return myPhi;
254}
255
256
258 return 0;
259}
260
261
263 return 0;
264}
265
266
268 return nullptr;
269}
270
271
272void MSPModel_Remote::PState::setPosition(double x, double y) {
273 myPosition.set(x, y);
274}
275
276
278 myPhi = phi;
279}
280
281
283 return myStage;
284}
285
286
288 return myPerson;
289}
290
291
292bool
295}
296
297void
299 throw ProcessError(TL("Pedestrian model 'remote' does not support simulation.loadState state\n"));
300}
long long int SUMOTime
Definition: GUI.h:36
#define TL(string)
Definition: MsgHandler.h:287
#define TLF(string,...)
Definition: MsgHandler.h:288
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
@ SVC_PEDESTRIAN
pedestrian
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
The simulated network and simulation perfomer.
Definition: MSNet.h:88
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:473
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:322
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:778
Container for pedestrian state and individual position update function.
const MSEdge * getNextEdge(const MSStageMoving &stage) const override
return the list of internal edges if the transportable is on an intersection
int getDirection(const MSStageMoving &stage, SUMOTime now) const override
return the walking direction (FORWARD, BACKWARD)
void setPosition(double x, double y)
Position getPosition(const MSStageMoving &stage, SUMOTime now) const override
return the network coordinate of the transportable
double getSpeed(const MSStageMoving &stage) const override
return the current speed of the transportable
double getAngle(const MSStageMoving &stage, SUMOTime now) const override
return the direction in which the transportable faces in degrees
double getEdgePos(const MSStageMoving &stage, SUMOTime now) const override
return the offset from the start of the current edge measured in its natural direction
PState(MSPerson *person, MSStageMoving *stage)
SUMOTime getWaitingTime(const MSStageMoving &stage, SUMOTime now) const override
return the time the transportable spent standing
MSStageMoving * getStage()
MSLane * getFirstPedestrianLane(const MSEdge *const &edge)
MSTransportableStateAdapter * add(MSTransportable *person, MSStageMoving *stage, SUMOTime now) override
register the given person as a pedestrian
std::map< int, PState * > remoteIdPStateMapping
void remove(MSTransportableStateAdapter *state) override
remove the specified person from the pedestrian simulation
SUMOTime execute(SUMOTime time)
void clearState()
Resets pedestrians when quick-loading state.
MSPModel_Remote(const OptionsCont &oc, MSNet *net)
bool usingInternalLanes()
whether movements on intersections are modelled
static const int UNDEFINED_DIRECTION
Definition: MSPModel.h:121
MSStageType getCurrentStageType() const
the current stage type of the transportable
abstract base class for managing callbacks to retrieve various state information from the model
Definition: MSPModel.h:150
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37