SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSDevice_BTreceiver.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A BT sender
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
10 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #ifdef _MSC_VER
25 #include <windows_config.h>
26 #else
27 #include <config.h>
28 #endif
29 
34 #include <utils/geom/Position.h>
35 #include <utils/geom/Line.h>
36 #include <utils/geom/GeomHelper.h>
37 #include <microsim/MSNet.h>
38 #include <microsim/MSLane.h>
39 #include <microsim/MSEdge.h>
40 #include <microsim/MSVehicle.h>
41 #include "MSDevice_Tripinfo.h"
42 #include "MSDevice_BTreceiver.h"
43 #include "MSDevice_BTsender.h"
44 
45 #ifdef CHECK_MEMORY_LEAKS
46 #include <foreign/nvwa/debug_new.h>
47 #endif // CHECK_MEMORY_LEAKS
48 
49 
50 // ===========================================================================
51 // static members
52 // ===========================================================================
55 std::map<std::string, MSDevice_BTreceiver::VehicleInformation*> MSDevice_BTreceiver::sVehicles;
56 
57 
58 // ===========================================================================
59 // method definitions
60 // ===========================================================================
61 // ---------------------------------------------------------------------------
62 // static initialisation methods
63 // ---------------------------------------------------------------------------
64 void
66  insertDefaultAssignmentOptions("btreceiver", "Communication", oc);
67 
68  oc.doRegister("device.btreceiver.range", new Option_Float(300));
69  oc.addDescription("device.btreceiver.range", "Communication", "The range of the bt receiver");
70 
71  oc.doRegister("device.btreceiver.all-recognitions", new Option_Bool(false));
72  oc.addDescription("device.btreceiver.all-recognitions", "Communication", "Whether all recognition point shall be written");
73 }
74 
75 
76 void
77 MSDevice_BTreceiver::buildVehicleDevices(SUMOVehicle& v, std::vector<MSDevice*>& into) {
79  if (equippedByDefaultAssignmentOptions(oc, "btreceiver", v)) {
80  MSDevice_BTreceiver* device = new MSDevice_BTreceiver(v, "btreceiver_" + v.getID(), oc.getFloat("device.btreceiver.range"));
81  into.push_back(device);
82  if (!myWasInitialised) {
83  new BTreceiverUpdate();
84  myWasInitialised = true;
85  sRecognitionRNG.seed(oc.getInt("seed"));
86  }
87  }
88 }
89 
90 
91 // ---------------------------------------------------------------------------
92 // MSDevice_BTreceiver::BTreceiverUpdate-methods
93 // ---------------------------------------------------------------------------
96 }
97 
98 
100  for (std::map<std::string, MSDevice_BTsender::VehicleInformation*>::const_iterator i = MSDevice_BTsender::sVehicles.begin(); i != MSDevice_BTsender::sVehicles.end(); ++i) {
101  (*i).second->amOnNet = false;
102  (*i).second->haveArrived = true;
103  }
104  for (std::map<std::string, MSDevice_BTreceiver::VehicleInformation*>::const_iterator i = MSDevice_BTreceiver::sVehicles.begin(); i != MSDevice_BTreceiver::sVehicles.end(); ++i) {
105  (*i).second->amOnNet = false;
106  (*i).second->haveArrived = true;
107  }
108  execute(MSNet::getInstance()->getCurrentTimeStep());
109 }
110 
111 
112 SUMOTime
114  // build rtree with senders
115  NamedRTree rt;
116  for (std::map<std::string, MSDevice_BTsender::VehicleInformation*>::const_iterator i = MSDevice_BTsender::sVehicles.begin(); i != MSDevice_BTsender::sVehicles.end(); ++i) {
117  MSDevice_BTsender::VehicleInformation* vi = (*i).second;
118  Boundary b = vi->getBoxBoundary();
119  b.grow(3.);
120  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
121  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
122  rt.Insert(cmin, cmax, vi);
123  }
124 
125  // check visibility for all receivers
127  bool allRecognitions = oc.getBool("device.btreceiver.all-recognitions");
128  bool haveOutput = oc.isSet("bt-output");
129  for (std::map<std::string, MSDevice_BTreceiver::VehicleInformation*>::iterator i = MSDevice_BTreceiver::sVehicles.begin(); i != MSDevice_BTreceiver::sVehicles.end();) {
130  // compute own direction vector
131  MSDevice_BTreceiver::VehicleState& state = (*i).second->updates.back();
132  Position egoPosition = state.position;
133  SUMOReal angle = state.angle * M_PI / 180.;
134  SUMOReal speed = state.speed;
135  SUMOReal dist = SPEED2DIST(speed);
136  Position egoP2 = egoPosition;
137  Position egoP1(egoP2.x() - sin(angle)*dist, egoP2.y() + cos(angle)*dist);
138  Position egoD = egoP2 - egoP1;
139 
140  // collect surrounding vehicles
141  MSDevice_BTreceiver::VehicleInformation* vi = (*i).second;
142  Boundary b = vi->getBoxBoundary();
143  b.grow(vi->range + 500 / 3.6); // two vehicles passing at 250*2 km/h
144  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
145  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
146  std::set<std::string> surroundingVehicles;
147  Named::StoringVisitor sv(surroundingVehicles);
148  rt.Search(cmin, cmax, sv);
149 
150  // loop over surrounding vehicles, check visibility status
151  for (std::set<std::string>::const_iterator j = surroundingVehicles.begin(); j != surroundingVehicles.end(); ++j) {
152  if ((*i).first == *j) {
153  // seeing oneself? skip
154  continue;
155  }
156  updateVisibility(*vi, *MSDevice_BTsender::sVehicles.find(*j)->second, egoP1, egoD);
157  }
158 
159  if (vi->haveArrived) {
160  // vehicle has left the simulation; remove
161  if (haveOutput) {
162  writeOutput((*i).first, vi->seen, allRecognitions);
163  }
164  delete(*i).second;
166  } else {
167  // vehicle is still in the simulation; reset state
168  VehicleState last = (*i).second->updates.back();
169  (*i).second->updates.clear();
170  (*i).second->updates.push_back(last);
171  ++i;
172  }
173  }
174 
175  // remove arrived senders / reset state
176  for (std::map<std::string, MSDevice_BTsender::VehicleInformation*>::iterator i = MSDevice_BTsender::sVehicles.begin(); i != MSDevice_BTsender::sVehicles.end();) {
177  if ((*i).second->haveArrived) {
178  delete(*i).second;
179  MSDevice_BTsender::sVehicles.erase(i++);
180  } else {
181  MSDevice_BTsender::VehicleState last = (*i).second->updates.back();
182  (*i).second->updates.clear();
183  (*i).second->updates.push_back(last);
184  ++i;
185  }
186  }
187  return DELTA_T;
188 }
189 
190 
191 void
193  const Position& receiverStartPos, const Position& receiverD) {
194  Position receiverPos = receiver.updates.back().position;
195  std::vector<SUMOReal> intersections;
196  if (!receiver.amOnNet || !sender.amOnNet) {
197  // at least one of the vehicles has left the simulation area for any reason
198  if (receiver.currentlySeen.find(sender.getID()) != receiver.currentlySeen.end()) {
199  leaveRange(receiver.currentlySeen, receiver.seen, receiverPos, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
200  sender.getID(), sender.updates.back().position, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, 0);
201  }
202  }
203 
204  // get the encountered vehicle's current and prior position (based on speed and direction)
205  Position otherPosition = sender.updates.back().position;
206  Position otherP2 = otherPosition;
207  SUMOReal angle = sender.updates.back().angle * M_PI / 180.;
208  SUMOReal speed = sender.updates.back().speed;
209  SUMOReal dist = SPEED2DIST(speed);
210 
211  // let the other's current position be the one obtained by applying the relative direction vector to the initial position
212  Position otherP1(otherPosition.x() - sin(angle)*dist, otherPosition.y() + cos(angle)*dist);
213  Position otherD = otherP2 - otherP1;
214  otherP2 = otherP1 - receiverD + otherD;
215  // find crossing points
216  GeomHelper::FindLineCircleIntersections(receiverStartPos, receiver.range, otherP1, otherP2, intersections);
217  int count = (int) intersections.size();
218  switch (count) {
219  case 0:
220  // no intersections -> other vehicle either stays within or beyond range
221  if (receiver.amOnNet && sender.amOnNet && receiverPos.distanceTo(otherPosition) < receiver.range) {
222  if (receiver.currentlySeen.find(sender.getID()) == receiver.currentlySeen.end()) {
223  SUMOReal atOffset = 0;
224  enterRange(atOffset, receiverPos, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
225  sender.getID(), otherPosition, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, receiver.currentlySeen);
226  } else {
227  addRecognitionPoint(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), receiverPos, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
228  sender.getID(), otherPosition, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, receiver.currentlySeen);
229  }
230  } else {
231  if (receiver.currentlySeen.find(sender.getID()) != receiver.currentlySeen.end()) {
232  leaveRange(receiver.currentlySeen, receiver.seen, receiverPos, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
233  sender.getID(), otherPosition, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, 0);
234  }
235  }
236  break;
237  case 1: {
238  // one intersection -> other vehicle either enters or leaves the range
239  Position intersection1Other = otherP1 + otherD * intersections.front();
240  Position intersection1Ego = receiverStartPos + receiverD * intersections.front();
241  if (receiver.currentlySeen.find(sender.getID()) != receiver.currentlySeen.end()) {
242  leaveRange(receiver.currentlySeen, receiver.seen, intersection1Ego, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
243  sender.getID(), intersection1Other, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, -1. + intersections.front());
244  } else {
245  enterRange(-1. + intersections.front(), intersection1Ego, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
246  sender.getID(), intersection1Other, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, receiver.currentlySeen);
247  }
248  }
249  break;
250  case 2:
251  // two intersections -> other vehicle enters and leaves the range
252  if (receiver.currentlySeen.find(sender.getID()) == receiver.currentlySeen.end()) {
253  Position intersection1Other = otherP1 + otherD * intersections.front();
254  Position intersection1Ego = receiverStartPos + receiverD * intersections.front();
255  enterRange(-1. + intersections.front(), intersection1Ego, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
256  sender.getID(), intersection1Other, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, receiver.currentlySeen);
257  Position intersection2Other = otherP1 + otherD * intersections[1];
258  Position intersection2Ego = receiverStartPos + receiverD * intersections[1];
259  leaveRange(receiver.currentlySeen, receiver.seen, intersection2Ego, receiver.updates.back().speed, receiver.updates.back().laneID, receiver.updates.back().lanePos,
260  sender.getID(), intersection2Other, sender.updates.back().speed, sender.updates.back().laneID, sender.updates.back().lanePos, -1. + intersections.front());
261  } else {
262  WRITE_WARNING("Nope, a vehicle cannot be in the range, leave, and enter it in one step.");
263  }
264  break;
265  default:
266  WRITE_WARNING("Nope, a circle cannot be crossed more often than twice by a line.");
267  break;
268  }
269 }
270 
271 
272 void
274  const Position& thisPos, SUMOReal thisSpeed, const std::string& thisLaneID, SUMOReal thisLanePos,
275  const std::string& otherID, const Position& otherPos, SUMOReal otherSpeed, const std::string& otherLaneID, SUMOReal otherLanePos,
276  std::map<std::string, SeenDevice*>& currentlySeen) {
277  MeetingPoint mp(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) + atOffset, thisPos, thisSpeed, thisLaneID, thisLanePos, otherPos, otherSpeed, otherLaneID, otherLanePos);
278  SeenDevice* sd = new SeenDevice(mp);
279  currentlySeen[otherID] = sd;
280  addRecognitionPoint(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), thisPos, thisSpeed, thisLaneID, thisLanePos,
281  otherID, otherPos, otherSpeed, otherLaneID, otherLanePos, currentlySeen);
282 }
283 
284 
285 void
286 MSDevice_BTreceiver::BTreceiverUpdate::leaveRange(std::map<std::string, SeenDevice*>& currentlySeen, std::map<std::string, std::vector<SeenDevice*> >& seen,
287  const Position& thisPos, SUMOReal thisSpeed, const std::string& thisLaneID, SUMOReal thisLanePos,
288  const std::string& otherID, const Position& otherPos, SUMOReal otherSpeed, const std::string& otherLaneID, SUMOReal otherLanePos,
289  SUMOReal tOffset) {
290  // check whether the other was recognized
291  addRecognitionPoint(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) + tOffset, thisPos, thisSpeed, thisLaneID, thisLanePos,
292  otherID, otherPos, otherSpeed, otherLaneID, otherLanePos, currentlySeen);
293  // build leaving point
294  MeetingPoint mp(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) + tOffset, thisPos, thisSpeed, thisLaneID, thisLanePos, otherPos, otherSpeed, otherLaneID, otherLanePos);
295  std::map<std::string, SeenDevice*>::iterator i = currentlySeen.find(otherID);
296  (*i).second->meetingEnd = mp;
297  if (seen.find(otherID) == seen.end()) {
298  seen[otherID] = std::vector<SeenDevice*>();
299  }
300  seen[otherID].push_back((*i).second);
301  currentlySeen.erase(i);
302 }
303 
304 
305 void
306 MSDevice_BTreceiver::BTreceiverUpdate::addRecognitionPoint(SUMOReal tEnd, const Position& thisPos, SUMOReal thisSpeed, const std::string& thisLaneID, SUMOReal thisLanePos,
307  const std::string& otherID, const Position& otherPos, SUMOReal otherSpeed, const std::string& otherLaneID, SUMOReal otherLanePos,
308  std::map<std::string, SeenDevice*>& currentlySeen) {
309  SUMOReal t = tEnd - currentlySeen.find(otherID)->second->lastView;
310  if (sRecognitionRNG.rand() <= 1 - exp(-0.24 * pow(t, 2.68))) {
311  currentlySeen.find(otherID)->second->lastView = tEnd;
312  MeetingPoint* mp = new MeetingPoint(tEnd, thisPos, thisSpeed, thisLaneID, thisLanePos, otherPos, otherSpeed, otherLaneID, otherLanePos);
313  std::map<std::string, SeenDevice*>::iterator i = currentlySeen.find(otherID);
314  if (i != currentlySeen.end()) {
315  (*i).second->recognitionPoints.push_back(mp);
316  } else {
317  WRITE_WARNING("Could not add a recognition point as the sender '" + otherID + "' is not currently seen.");
318  }
319  }
320 }
321 
322 
323 void
324 MSDevice_BTreceiver::BTreceiverUpdate::writeOutput(const std::string& id, const std::map<std::string, std::vector<SeenDevice*> >& seen, bool allRecognitions) {
326  os.openTag("bt").writeAttr("id", id);
327  for (std::map<std::string, std::vector<SeenDevice*> >::const_iterator j = seen.begin(); j != seen.end(); ++j) {
328  const std::vector<SeenDevice*>& sts = (*j).second;
329  for (std::vector<SeenDevice*>::const_iterator k = sts.begin(); k != sts.end(); ++k) {
330  os.openTag("seen").writeAttr("id", (*j).first);
331  os.writeAttr("tBeg", (*k)->meetingBegin.t)
332  .writeAttr("observerPosBeg", (*k)->meetingBegin.observerPos).writeAttr("observerSpeedBeg", (*k)->meetingBegin.observerSpeed)
333  .writeAttr("observerLaneIDBeg", (*k)->meetingBegin.observerLaneID).writeAttr("observerLanePosBeg", (*k)->meetingBegin.observerLanePos)
334  .writeAttr("seenPosBeg", (*k)->meetingBegin.seenPos).writeAttr("seenSpeedBeg", (*k)->meetingBegin.seenSpeed)
335  .writeAttr("seenLaneIDBeg", (*k)->meetingBegin.seenLaneID).writeAttr("seenLanePosBeg", (*k)->meetingBegin.seenLanePos);
336  os.writeAttr("tEnd", (*k)->meetingEnd.t)
337  .writeAttr("observerPosEnd", (*k)->meetingEnd.observerPos).writeAttr("observerSpeedEnd", (*k)->meetingEnd.observerSpeed)
338  .writeAttr("observerLaneIDEnd", (*k)->meetingEnd.observerLaneID).writeAttr("observerLanePosEnd", (*k)->meetingEnd.observerLanePos)
339  .writeAttr("seenPosEnd", (*k)->meetingEnd.seenPos).writeAttr("seenSpeedEnd", (*k)->meetingEnd.seenSpeed)
340  .writeAttr("seenLaneIDEnd", (*k)->meetingEnd.seenLaneID).writeAttr("seenLanePosEnd", (*k)->meetingEnd.seenLanePos);
341  for (std::vector<MeetingPoint*>::iterator l = (*k)->recognitionPoints.begin(); l != (*k)->recognitionPoints.end(); ++l) {
342  os.openTag("recognitionPoint").writeAttr("t", (*l)->t)
343  .writeAttr("observerPos", (*l)->observerPos).writeAttr("observerSpeed", (*l)->observerSpeed)
344  .writeAttr("observerLaneID", (*l)->observerLaneID).writeAttr("observerLanePos", (*l)->observerLanePos)
345  .writeAttr("seenPos", (*l)->seenPos).writeAttr("seenSpeed", (*l)->seenSpeed)
346  .writeAttr("seenLaneID", (*l)->seenLaneID).writeAttr("seenLanePos", (*l)->seenLanePos)
347  .closeTag();
348  if (!allRecognitions) {
349  break;
350  }
351  }
352  os.closeTag();
353  }
354  }
355  os.closeTag();
356 }
357 
358 
359 
360 
361 // ---------------------------------------------------------------------------
362 // MSDevice_BTreceiver-methods
363 // ---------------------------------------------------------------------------
364 MSDevice_BTreceiver::MSDevice_BTreceiver(SUMOVehicle& holder, const std::string& id, SUMOReal range)
365  : MSDevice(holder, id), myRange(range) {
366 }
367 
368 
370 }
371 
372 
373 bool
375  if (reason == MSMoveReminder::NOTIFICATION_DEPARTED && sVehicles.find(veh.getID()) == sVehicles.end()) {
376  sVehicles[veh.getID()] = new VehicleInformation(veh.getID(), myRange);
377  }
378  sVehicles[veh.getID()]->updates.push_back(VehicleState(
379  MSNet::getInstance()->getCurrentTimeStep(), veh.getSpeed(), static_cast<MSVehicle&>(veh).getAngle(), static_cast<MSVehicle&>(veh).getPosition(), static_cast<MSVehicle&>(veh).getLane()->getID(), veh.getPositionOnLane()
380  ));
381  return true;
382 }
383 
384 
385 bool
387  if (sVehicles.find(veh.getID()) == sVehicles.end()) {
388  WRITE_WARNING("btreceiver: Can not update position of a vehicle that is not within the road network (" + veh.getID() + ").");
389  return true;
390  }
391  sVehicles[veh.getID()]->updates.push_back(VehicleState(
392  MSNet::getInstance()->getCurrentTimeStep(), newSpeed, static_cast<MSVehicle&>(veh).getAngle(), static_cast<MSVehicle&>(veh).getPosition(), static_cast<MSVehicle&>(veh).getLane()->getID(), newPos
393  ));
394  return true;
395 }
396 
397 
398 bool
401  return true;
402  }
403  if (sVehicles.find(veh.getID()) == sVehicles.end()) {
404  WRITE_WARNING("btreceiver: Can not update position of a vehicle that is not within the road network (" + veh.getID() + ").");
405  return true;
406  }
407  sVehicles[veh.getID()]->updates.push_back(VehicleState(
408  MSNet::getInstance()->getCurrentTimeStep(), veh.getSpeed(), static_cast<MSVehicle&>(veh).getAngle(), static_cast<MSVehicle&>(veh).getPosition(), static_cast<MSVehicle&>(veh).getLane()->getID(), veh.getPositionOnLane()
409  ));
411  sVehicles[veh.getID()]->amOnNet = false;
412  }
413  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
414  sVehicles[veh.getID()]->haveArrived = true;
415  }
416  return true;
417 }
418 
419 
420 
421 
422 
423 /****************************************************************************/
424