Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2013-2024 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 MSDevice_BTreceiver.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date 14.08.2013
19 : ///
20 : // A BT Receiver
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <utils/common/MsgHandler.h>
25 : #include <utils/options/OptionsCont.h>
26 : #include <utils/iodevices/OutputDevice.h>
27 : #include <utils/vehicle/SUMOVehicle.h>
28 : #include <utils/geom/Position.h>
29 : #include <utils/geom/GeomHelper.h>
30 : #include <microsim/MSNet.h>
31 : #include <microsim/MSLane.h>
32 : #include <microsim/MSEdge.h>
33 : #include <microsim/MSVehicle.h>
34 : #include <microsim/transportables/MSTransportable.h>
35 : #include <microsim/transportables/MSTransportableControl.h>
36 : #include <microsim/MSEventControl.h>
37 : #include "MSDevice_Tripinfo.h"
38 : #include "MSDevice_BTreceiver.h"
39 : #include "MSDevice_BTsender.h"
40 :
41 :
42 : // ===========================================================================
43 : // static members
44 : // ===========================================================================
45 : bool MSDevice_BTreceiver::myWasInitialised = false;
46 : bool MSDevice_BTreceiver::myHasPersons = true;
47 : double MSDevice_BTreceiver::myRange = -1.;
48 : double MSDevice_BTreceiver::myOffTime = -1.;
49 : SumoRNG MSDevice_BTreceiver::sRecognitionRNG("btreceiver");
50 : std::map<std::string, MSDevice_BTreceiver::VehicleInformation*> MSDevice_BTreceiver::sVehicles;
51 :
52 :
53 : // ===========================================================================
54 : // method definitions
55 : // ===========================================================================
56 : // ---------------------------------------------------------------------------
57 : // static initialisation methods
58 : // ---------------------------------------------------------------------------
59 :
60 : void
61 43644 : MSVehicleDevice_BTreceiver::insertOptions(OptionsCont& oc) {
62 87288 : insertDefaultAssignmentOptions("btreceiver", "Communication", oc);
63 :
64 43644 : oc.doRegister("device.btreceiver.range", new Option_Float(300));
65 87288 : oc.addDescription("device.btreceiver.range", "Communication", TL("The range of the bt receiver"));
66 :
67 43644 : oc.doRegister("device.btreceiver.all-recognitions", new Option_Bool(false));
68 87288 : oc.addDescription("device.btreceiver.all-recognitions", "Communication", TL("Whether all recognition point shall be written"));
69 :
70 43644 : oc.doRegister("device.btreceiver.offtime", new Option_Float(0.64));
71 87288 : oc.addDescription("device.btreceiver.offtime", "Communication", TL("The offtime used for calculating detection probability (in seconds)"));
72 :
73 43644 : myWasInitialised = false;
74 43644 : myHasPersons = false;
75 43644 : }
76 :
77 :
78 : void
79 5104373 : MSVehicleDevice_BTreceiver::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
80 5104373 : OptionsCont& oc = OptionsCont::getOptions();
81 10208746 : if (equippedByDefaultAssignmentOptions(oc, "btreceiver", v, false)) {
82 456 : MSVehicleDevice_BTreceiver* device = new MSVehicleDevice_BTreceiver(v, "btreceiver_" + v.getID());
83 456 : into.push_back(device);
84 456 : if (!myWasInitialised) {
85 168 : new BTreceiverUpdate();
86 168 : myWasInitialised = true;
87 168 : myRange = oc.getFloat("device.btreceiver.range");
88 168 : myOffTime = oc.getFloat("device.btreceiver.offtime");
89 336 : sRecognitionRNG.seed(oc.getInt("seed"));
90 : }
91 : }
92 5104373 : }
93 :
94 : void
95 43644 : MSTransportableDevice_BTreceiver::insertOptions(OptionsCont& oc) {
96 87288 : insertDefaultAssignmentOptions("btreceiver", "Communication", oc, true);
97 43644 : }
98 :
99 :
100 : void
101 501966 : MSTransportableDevice_BTreceiver::buildDevices(MSTransportable& t, std::vector<MSTransportableDevice*>& into) {
102 501966 : OptionsCont& oc = OptionsCont::getOptions();
103 1003932 : if (equippedByDefaultAssignmentOptions(oc, "btreceiver", t, false, true)) {
104 132 : MSTransportableDevice_BTreceiver* device = new MSTransportableDevice_BTreceiver(t, "btreceiver_" + t.getID());
105 132 : into.push_back(device);
106 132 : myHasPersons = true;
107 132 : if (!myWasInitialised) {
108 72 : new BTreceiverUpdate();
109 72 : myWasInitialised = true;
110 72 : myRange = oc.getFloat("device.btreceiver.range");
111 72 : myOffTime = oc.getFloat("device.btreceiver.offtime");
112 144 : sRecognitionRNG.seed(oc.getInt("seed"));
113 : }
114 : }
115 501966 : }
116 :
117 :
118 : // ---------------------------------------------------------------------------
119 : // MSDevice_BTreceiver::BTreceiverUpdate-methods
120 : // ---------------------------------------------------------------------------
121 240 : MSDevice_BTreceiver::BTreceiverUpdate::BTreceiverUpdate() {
122 240 : MSNet::getInstance()->getEndOfTimestepEvents()->addEvent(this);
123 240 : }
124 :
125 :
126 480 : MSDevice_BTreceiver::BTreceiverUpdate::~BTreceiverUpdate() {
127 420 : for (const auto& vehicleInfo : MSDevice_BTsender::sVehicles) {
128 180 : vehicleInfo.second->amOnNet = false;
129 180 : vehicleInfo.second->haveArrived = true;
130 : }
131 420 : for (const auto& vehicleInfo : MSDevice_BTreceiver::sVehicles) {
132 180 : vehicleInfo.second->amOnNet = false;
133 180 : vehicleInfo.second->haveArrived = true;
134 : }
135 240 : execute(MSNet::getInstance()->getCurrentTimeStep());
136 480 : }
137 :
138 :
139 : SUMOTime
140 137624 : MSDevice_BTreceiver::BTreceiverUpdate::execute(SUMOTime /*currentTime*/) {
141 : // loop over equipped persons to update their positions
142 137624 : if (myHasPersons && MSNet::getInstance()->hasPersons()) { // the check whether the net has persons is only important in the final cleanup
143 98116 : MSTransportableControl& c = MSNet::getInstance()->getPersonControl();
144 287840 : for (MSTransportableControl::constVehIt i = c.loadedBegin(); i != c.loadedEnd(); ++i) {
145 189724 : MSTransportable* t = i->second;
146 189724 : if (t->getCurrentStageType() != MSStageType::WAITING_FOR_DEPART) {
147 189556 : MSDevice_BTsender* snd = dynamic_cast<MSDevice_BTsender*>(t->getDevice(typeid(MSTransportableDevice_BTsender)));
148 189556 : MSDevice_BTreceiver* rec = dynamic_cast<MSDevice_BTreceiver*>(t->getDevice(typeid(MSTransportableDevice_BTreceiver)));
149 189556 : if (snd) {
150 129152 : snd->notifyMove(*t, t->getPositionOnLane(), t->getPositionOnLane(), t->getSpeed());
151 129152 : if (MSDevice_BTsender::sVehicles[t->getID()]->route.back() != t->getEdge()) {
152 240 : MSDevice_BTsender::sVehicles[t->getID()]->route.push_back(t->getEdge());
153 : }
154 : }
155 189556 : if (rec) {
156 129152 : rec->notifyMove(*t, t->getPositionOnLane(), t->getPositionOnLane(), t->getSpeed());
157 129152 : if (sVehicles[t->getID()]->route.back() != t->getEdge()) {
158 240 : sVehicles[t->getID()]->route.push_back(t->getEdge());
159 : }
160 : }
161 : }
162 : }
163 : }
164 :
165 : // build rtree with senders
166 : NamedRTree rt;
167 292514 : for (std::map<std::string, MSDevice_BTsender::VehicleInformation*>::const_iterator i = MSDevice_BTsender::sVehicles.begin(); i != MSDevice_BTsender::sVehicles.end(); ++i) {
168 154890 : MSDevice_BTsender::VehicleInformation* vi = (*i).second;
169 154890 : Boundary b = vi->getBoxBoundary();
170 154890 : b.grow(POSITION_EPS);
171 154890 : const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
172 154890 : const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
173 154890 : rt.Insert(cmin, cmax, vi);
174 154890 : }
175 :
176 : // check visibility for all receivers
177 137624 : OptionsCont& oc = OptionsCont::getOptions();
178 137624 : bool allRecognitions = oc.getBool("device.btreceiver.all-recognitions");
179 275248 : bool haveOutput = oc.isSet("bt-output");
180 359482 : for (std::map<std::string, MSDevice_BTreceiver::VehicleInformation*>::iterator i = MSDevice_BTreceiver::sVehicles.begin(); i != MSDevice_BTreceiver::sVehicles.end();) {
181 : // collect surrounding vehicles
182 221858 : MSDevice_BTreceiver::VehicleInformation* vi = (*i).second;
183 221858 : Boundary b = vi->getBoxBoundary();
184 221858 : b.grow(vi->range);
185 221858 : const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
186 221858 : const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
187 : std::set<const Named*> surroundingVehicles;
188 : Named::StoringVisitor sv(surroundingVehicles);
189 : rt.Search(cmin, cmax, sv);
190 :
191 : // loop over surrounding vehicles, check visibility status
192 362886 : for (const Named* vehicle : surroundingVehicles) {
193 141028 : if ((*i).first == vehicle->getID()) {
194 : // seeing oneself? skip
195 82412 : continue;
196 : }
197 58616 : updateVisibility(*vi, *MSDevice_BTsender::sVehicles.find(vehicle->getID())->second);
198 : }
199 :
200 221858 : if (vi->haveArrived) {
201 : // vehicle has left the simulation; remove
202 588 : if (haveOutput) {
203 324 : writeOutput((*i).first, vi->seen, allRecognitions);
204 : }
205 588 : delete vi;
206 : MSDevice_BTreceiver::sVehicles.erase(i++);
207 : } else {
208 : // vehicle is still in the simulation; reset state
209 221270 : vi->updates.erase(vi->updates.begin(), vi->updates.end() - 1);
210 : ++i;
211 : }
212 221858 : }
213 :
214 : // remove arrived senders / reset state
215 292514 : for (std::map<std::string, MSDevice_BTsender::VehicleInformation*>::iterator i = MSDevice_BTsender::sVehicles.begin(); i != MSDevice_BTsender::sVehicles.end();) {
216 154890 : MSDevice_BTsender::VehicleInformation* vi = (*i).second;
217 154890 : if (vi->haveArrived) {
218 324 : delete vi;
219 : MSDevice_BTsender::sVehicles.erase(i++);
220 : } else {
221 154566 : vi->updates.erase(vi->updates.begin(), vi->updates.end() - 1);
222 : ++i;
223 : }
224 : }
225 137624 : return DELTA_T;
226 : }
227 :
228 :
229 : void
230 58616 : MSDevice_BTreceiver::BTreceiverUpdate::updateVisibility(MSDevice_BTreceiver::VehicleInformation& receiver,
231 : MSDevice_BTsender::VehicleInformation& sender) {
232 : const MSDevice_BTsender::VehicleState& receiverData = receiver.updates.back();
233 : const MSDevice_BTsender::VehicleState& senderData = sender.updates.back();
234 58616 : if (!receiver.amOnNet || !sender.amOnNet) {
235 : // at least one of the vehicles has left the simulation area for any reason
236 232 : if (receiver.currentlySeen.find(sender.getID()) != receiver.currentlySeen.end()) {
237 200 : leaveRange(receiver, receiverData, sender, senderData, 0);
238 : }
239 : }
240 :
241 58616 : const Position& oldReceiverPosition = receiver.updates.front().position;
242 58616 : const Position& oldSenderPosition = sender.updates.front().position;
243 :
244 : // let the other's current position be the one obtained by applying the relative direction vector to the initial position
245 : const Position senderDelta = senderData.position - oldSenderPosition;
246 : const Position receiverDelta = receiverData.position - oldReceiverPosition;
247 : const Position translatedSender = senderData.position - receiverDelta;
248 : // find crossing points
249 : std::vector<double> intersections;
250 58616 : GeomHelper::findLineCircleIntersections(oldReceiverPosition, receiver.range, oldSenderPosition, translatedSender, intersections);
251 58616 : switch (intersections.size()) {
252 57604 : case 0:
253 : // no intersections -> other vehicle either stays within or beyond range
254 57604 : if (receiver.amOnNet && sender.amOnNet && receiverData.position.distanceTo(senderData.position) < receiver.range) {
255 55212 : if (receiver.currentlySeen.find(sender.getID()) == receiver.currentlySeen.end()) {
256 156 : enterRange(0., receiverData, sender.getID(), senderData, receiver.currentlySeen);
257 : } else {
258 55056 : addRecognitionPoint(SIMTIME, receiverData, senderData, receiver.currentlySeen[sender.getID()]);
259 : }
260 : } else {
261 2392 : if (receiver.currentlySeen.find(sender.getID()) != receiver.currentlySeen.end()) {
262 24 : leaveRange(receiver, receiverData, sender, senderData, 0.);
263 : }
264 : }
265 : break;
266 1012 : case 1: {
267 : // one intersection -> other vehicle either enters or leaves the range
268 1012 : MSDevice_BTsender::VehicleState intersection1ReceiverData(receiverData);
269 1012 : intersection1ReceiverData.position = oldReceiverPosition + receiverDelta * intersections.front();
270 1012 : MSDevice_BTsender::VehicleState intersection1SenderData(senderData);
271 1012 : intersection1SenderData.position = oldSenderPosition + senderDelta * intersections.front();
272 1012 : if (receiver.currentlySeen.find(sender.getID()) != receiver.currentlySeen.end()) {
273 444 : leaveRange(receiver, intersection1ReceiverData,
274 444 : sender, intersection1SenderData, (intersections.front() - 1.) * TS);
275 : } else {
276 568 : enterRange((intersections.front() - 1.) * TS, intersection1ReceiverData,
277 568 : sender.getID(), intersection1SenderData, receiver.currentlySeen);
278 : }
279 : }
280 1012 : break;
281 0 : case 2:
282 : // two intersections -> other vehicle enters and leaves the range
283 0 : if (receiver.currentlySeen.find(sender.getID()) == receiver.currentlySeen.end()) {
284 0 : MSDevice_BTsender::VehicleState intersectionReceiverData(receiverData);
285 0 : intersectionReceiverData.position = oldReceiverPosition + receiverDelta * intersections.front();
286 0 : MSDevice_BTsender::VehicleState intersectionSenderData(senderData);
287 0 : intersectionSenderData.position = oldSenderPosition + senderDelta * intersections.front();
288 0 : enterRange((intersections.front() - 1.) * TS, intersectionReceiverData,
289 0 : sender.getID(), intersectionSenderData, receiver.currentlySeen);
290 0 : intersectionReceiverData.position = oldReceiverPosition + receiverDelta * intersections.back();
291 0 : intersectionSenderData.position = oldSenderPosition + senderDelta * intersections.back();
292 0 : leaveRange(receiver, intersectionReceiverData,
293 0 : sender, intersectionSenderData, (intersections.back() - 1.) * TS);
294 : } else {
295 0 : WRITE_WARNINGF(TL("The vehicle '%' cannot be in the range of vehicle '%', leave, and enter it in one step."), sender.getID(), receiver.getID());
296 : }
297 : break;
298 0 : default:
299 0 : WRITE_WARNING("Nope, a circle cannot be crossed more often than twice by a line.");
300 0 : break;
301 : }
302 58616 : }
303 :
304 :
305 : void
306 724 : MSDevice_BTreceiver::BTreceiverUpdate::enterRange(double atOffset, const MSDevice_BTsender::VehicleState& receiverState,
307 : const std::string& senderID, const MSDevice_BTsender::VehicleState& senderState,
308 : std::map<std::string, SeenDevice*>& currentlySeen) {
309 724 : MeetingPoint mp(SIMTIME + atOffset, receiverState, senderState);
310 724 : SeenDevice* sd = new SeenDevice(mp);
311 724 : currentlySeen[senderID] = sd;
312 724 : addRecognitionPoint(SIMTIME, receiverState, senderState, sd);
313 724 : }
314 :
315 :
316 : void
317 668 : MSDevice_BTreceiver::BTreceiverUpdate::leaveRange(VehicleInformation& receiverInfo, const MSDevice_BTsender::VehicleState& receiverState,
318 : MSDevice_BTsender::VehicleInformation& senderInfo, const MSDevice_BTsender::VehicleState& senderState,
319 : double tOffset) {
320 : std::map<std::string, SeenDevice*>::iterator i = receiverInfo.currentlySeen.find(senderInfo.getID());
321 : // check whether the other was recognized
322 668 : addRecognitionPoint(SIMTIME + tOffset, receiverState, senderState, i->second);
323 : // build leaving point
324 668 : i->second->meetingEnd = new MeetingPoint(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) + tOffset, receiverState, senderState);
325 668 : ConstMSEdgeVector::const_iterator begin = receiverInfo.route.begin() + i->second->meetingBegin.observerState.routePos;
326 668 : ConstMSEdgeVector::const_iterator end = receiverInfo.route.begin() + receiverState.routePos + 1;
327 668 : i->second->receiverRoute = toString<const MSEdge>(begin, end);
328 668 : begin = senderInfo.route.begin() + i->second->meetingBegin.seenState.routePos;
329 668 : end = senderInfo.route.begin() + senderState.routePos + 1;
330 668 : i->second->senderRoute = toString<const MSEdge>(begin, end);
331 668 : receiverInfo.seen[senderInfo.getID()].push_back(i->second);
332 : receiverInfo.currentlySeen.erase(i);
333 668 : }
334 :
335 :
336 : void
337 56448 : MSDevice_BTreceiver::BTreceiverUpdate::addRecognitionPoint(const double tEnd, const MSDevice_BTsender::VehicleState& receiverState,
338 : const MSDevice_BTsender::VehicleState& senderState,
339 : SeenDevice* senderDevice) const {
340 56448 : if (senderDevice->nextView == -1.) {
341 724 : senderDevice->nextView = senderDevice->lastView + inquiryDelaySlots(int(myOffTime / 0.000625 + .5)) * 0.000625;
342 : }
343 56448 : if (tEnd > senderDevice->nextView) {
344 55996 : senderDevice->lastView = senderDevice->nextView;
345 55996 : MeetingPoint* mp = new MeetingPoint(tEnd, receiverState, senderState);
346 55996 : senderDevice->recognitionPoints.push_back(mp);
347 55996 : senderDevice->nextView = senderDevice->lastView + inquiryDelaySlots(int(myOffTime / 0.000625 + .5)) * 0.000625;
348 : }
349 56448 : }
350 :
351 :
352 : void
353 324 : MSDevice_BTreceiver::BTreceiverUpdate::writeOutput(const std::string& id, const std::map<std::string, std::vector<SeenDevice*> >& seen, bool allRecognitions) {
354 324 : OutputDevice& os = OutputDevice::getDeviceByOption("bt-output");
355 648 : os.openTag("bt").writeAttr("id", id);
356 632 : for (std::map<std::string, std::vector<SeenDevice*> >::const_iterator j = seen.begin(); j != seen.end(); ++j) {
357 : const std::vector<SeenDevice*>& sts = (*j).second;
358 976 : for (std::vector<SeenDevice*>::const_iterator k = sts.begin(); k != sts.end(); ++k) {
359 1336 : os.openTag("seen").writeAttr("id", (*j).first);
360 668 : const MSDevice_BTsender::VehicleState& obsBeg = (*k)->meetingBegin.observerState;
361 : const MSDevice_BTsender::VehicleState& seenBeg = (*k)->meetingBegin.seenState;
362 668 : os.writeAttr("tBeg", (*k)->meetingBegin.t)
363 2004 : .writeAttr("observerPosBeg", obsBeg.position).writeAttr("observerSpeedBeg", obsBeg.speed)
364 2004 : .writeAttr("observerLaneIDBeg", obsBeg.laneID).writeAttr("observerLanePosBeg", obsBeg.lanePos)
365 2004 : .writeAttr("seenPosBeg", seenBeg.position).writeAttr("seenSpeedBeg", seenBeg.speed)
366 2004 : .writeAttr("seenLaneIDBeg", seenBeg.laneID).writeAttr("seenLanePosBeg", seenBeg.lanePos);
367 668 : const MSDevice_BTsender::VehicleState& obsEnd = (*k)->meetingEnd->observerState;
368 : const MSDevice_BTsender::VehicleState& seenEnd = (*k)->meetingEnd->seenState;
369 668 : os.writeAttr("tEnd", (*k)->meetingEnd->t)
370 2004 : .writeAttr("observerPosEnd", obsEnd.position).writeAttr("observerSpeedEnd", obsEnd.speed)
371 2004 : .writeAttr("observerLaneIDEnd", obsEnd.laneID).writeAttr("observerLanePosEnd", obsEnd.lanePos)
372 2004 : .writeAttr("seenPosEnd", seenEnd.position).writeAttr("seenSpeedEnd", seenEnd.speed)
373 2004 : .writeAttr("seenLaneIDEnd", seenEnd.laneID).writeAttr("seenLanePosEnd", seenEnd.lanePos)
374 2004 : .writeAttr("observerRoute", (*k)->receiverRoute).writeAttr("seenRoute", (*k)->senderRoute);
375 28644 : for (std::vector<MeetingPoint*>::iterator l = (*k)->recognitionPoints.begin(); l != (*k)->recognitionPoints.end(); ++l) {
376 56632 : os.openTag("recognitionPoint").writeAttr("t", (*l)->t)
377 84948 : .writeAttr("observerPos", (*l)->observerState.position).writeAttr("observerSpeed", (*l)->observerState.speed)
378 84948 : .writeAttr("observerLaneID", (*l)->observerState.laneID).writeAttr("observerLanePos", (*l)->observerState.lanePos)
379 84948 : .writeAttr("seenPos", (*l)->seenState.position).writeAttr("seenSpeed", (*l)->seenState.speed)
380 84948 : .writeAttr("seenLaneID", (*l)->seenState.laneID).writeAttr("seenLanePos", (*l)->seenState.lanePos)
381 56632 : .closeTag();
382 28316 : if (!allRecognitions) {
383 : break;
384 : }
385 : }
386 1336 : os.closeTag();
387 : }
388 : }
389 324 : os.closeTag();
390 324 : }
391 :
392 :
393 : // ---------------------------------------------------------------------------
394 : // MSDevice_BTreceiver-methods
395 : // ---------------------------------------------------------------------------
396 588 : MSDevice_BTreceiver::~MSDevice_BTreceiver() {
397 588 : }
398 :
399 :
400 : bool
401 5592 : MSDevice_BTreceiver::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
402 5592 : if (reason == MSMoveReminder::NOTIFICATION_DEPARTED && sVehicles.find(veh.getID()) == sVehicles.end()) {
403 588 : sVehicles[veh.getID()] = new VehicleInformation(veh.getID(), myRange);
404 588 : sVehicles[veh.getID()]->route.push_back(veh.getEdge());
405 : }
406 5592 : if (reason == MSMoveReminder::NOTIFICATION_TELEPORT && sVehicles.find(veh.getID()) != sVehicles.end()) {
407 0 : sVehicles[veh.getID()]->amOnNet = true;
408 : }
409 5592 : if (reason == MSMoveReminder::NOTIFICATION_TELEPORT || reason == MSMoveReminder::NOTIFICATION_JUNCTION) {
410 1640 : sVehicles[veh.getID()]->route.push_back(veh.getEdge());
411 : }
412 5592 : const std::string location = MSDevice_BTsender::getLocation(veh);
413 11184 : sVehicles[veh.getID()]->updates.push_back(MSDevice_BTsender::VehicleState(veh.getSpeed(), veh.getPosition(), location, veh.getPositionOnLane(), veh.getRoutePosition()));
414 5592 : return true;
415 : }
416 :
417 :
418 : bool
419 189308 : MSDevice_BTreceiver::notifyMove(SUMOTrafficObject& veh, double /* oldPos */, double newPos, double newSpeed) {
420 189308 : if (sVehicles.find(veh.getID()) == sVehicles.end()) {
421 0 : WRITE_WARNINGF(TL("btreceiver: Can not update position of vehicle '%' which is not on the road."), veh.getID());
422 0 : return true;
423 : }
424 189308 : const std::string location = MSDevice_BTsender::getLocation(veh);
425 378616 : sVehicles[veh.getID()]->updates.push_back(MSDevice_BTsender::VehicleState(newSpeed, veh.getPosition(), location, newPos, veh.getRoutePosition()));
426 : return true;
427 : }
428 :
429 :
430 : bool
431 5412 : MSDevice_BTreceiver::notifyLeave(SUMOTrafficObject& veh, double /* lastPos */, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
432 5412 : if (reason < MSMoveReminder::NOTIFICATION_TELEPORT) {
433 : return true;
434 : }
435 408 : if (sVehicles.find(veh.getID()) == sVehicles.end()) {
436 0 : WRITE_WARNINGF(TL("btreceiver: Can not update position of vehicle '%' which is not on the road."), veh.getID());
437 0 : return true;
438 : }
439 408 : const std::string location = MSDevice_BTsender::getLocation(veh);
440 408 : sVehicles[veh.getID()]->updates.push_back(MSDevice_BTsender::VehicleState(veh.getSpeed(), veh.getPosition(), location, veh.getPositionOnLane(), veh.getRoutePosition()));
441 408 : if (reason == MSMoveReminder::NOTIFICATION_TELEPORT) {
442 0 : sVehicles[veh.getID()]->amOnNet = false;
443 : }
444 408 : if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
445 408 : sVehicles[veh.getID()]->amOnNet = false;
446 408 : sVehicles[veh.getID()]->haveArrived = true;
447 : }
448 : return true;
449 : }
450 :
451 :
452 : double
453 56720 : MSDevice_BTreceiver::inquiryDelaySlots(const int backoffLimit) {
454 : const int phaseOffset = RandHelper::rand(2047, &sRecognitionRNG);
455 56720 : const bool interlaced = RandHelper::rand(&sRecognitionRNG) < 0.7;
456 56720 : const double delaySlots = RandHelper::rand(&sRecognitionRNG) * 15;
457 56720 : const int backoff = RandHelper::rand(backoffLimit, &sRecognitionRNG);
458 56720 : if (interlaced) {
459 39724 : return RandHelper::rand(&sRecognitionRNG) * 31 + backoff;
460 : }
461 16996 : if (RandHelper::rand(31, &sRecognitionRNG) < 16) {
462 : // correct train for f0
463 8656 : return delaySlots + backoff;
464 : }
465 8340 : if (RandHelper::rand(30, &sRecognitionRNG) < 16) {
466 : // correct train for f1
467 4536 : return 2048 - phaseOffset + delaySlots + backoff;
468 : }
469 3804 : if (RandHelper::rand(29, &sRecognitionRNG) < 16) {
470 : // f2 is in train A but has overlap with both trains
471 2312 : if (2 * 2048 - phaseOffset + backoff < 4096) {
472 1696 : return 2 * 2048 - phaseOffset + delaySlots + backoff;
473 : }
474 : // the following is wrong but should only happen in about 3% of the non-interlaced cases
475 616 : return 2 * 2048 - phaseOffset + delaySlots + backoff;
476 : }
477 1492 : return 2 * 2048 + delaySlots + backoff;
478 : }
479 :
480 :
481 : /****************************************************************************/
|