LCOV - code coverage report
Current view: top level - src/microsim/devices - MSDevice_BTreceiver.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 91.0 % 245 223
Test Date: 2024-11-22 15:46:21 Functions: 100.0 % 18 18

            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              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1