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.org/sumo
3 // Copyright (C) 2014-2020 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"
24 #include "microsim/MSEdgeControl.h"
26 #include "microsim/MSGlobals.h"
27 #include "utils/geom/Position.h"
29 #include "MSPModel_Remote.h"
30 
31 
32 MSPModel_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("Cannot map edge : " + edge->getID() + " to remote simulation");
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("Person: " + person->getID() + " could not be transferred to remote simulation");
105  }
106  if (!rpl.val()) {
107  //TODO not yet implemented
108  throw ProcessError("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("Could not shutdown remote server");
122  }
123 
124  */
125 }
126 
127 
128 SUMOTime
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("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("Pedestrian with id: " + toString(trajectory.id()) + " is not known.");
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("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("Could not confirm retrieved agents");
196  }
197  */
198  return DELTA_T;
199 }
200 
201 
202 MSLane*
204  for (MSLane* lane : edge->getLanes()) {
205  if (lane->getPermissions() == SVC_PEDESTRIAN) {
206  return lane;
207  }
208  }
209  throw ProcessError("Edge: " + edge->getID() + " does not allow pedestrians.");
210 }
211 
212 
213 void
215  // XXX do something here
216 
217 }
218 
219 
220 void
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 
243 
245  return myPosition;
246 }
247 
248 
250  return myPhi;
251 }
252 
253 
255  return 0;
256 }
257 
258 
260  return 0;
261 }
262 
263 
265  return nullptr;
266 }
267 
268 
269 void MSPModel_Remote::PState::setPosition(double x, double y) {
270  myPosition.set(x, y);
271 }
272 
273 
275  myPhi = phi;
276 }
277 
278 
280  return myStage;
281 }
282 
283 
285  return myPerson;
286 }
287 
288 
289 bool
292 }
293 
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
long long int SUMOTime
Definition: SUMOTime.h:31
@ 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:166
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:66
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
The simulated network and simulation perfomer.
Definition: MSNet.h:89
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:464
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:695
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
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)
MSPModel_Remote(const OptionsCont &oc, MSNet *net)
bool usingInternalLanes()
whether movements on intersections are modelled
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:130
const std::string & getID() const
Returns the id.
Definition: Named.h:73
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:36