示例#1
0
SUMOReal
MSEdge::getCurrentTravelTime(SUMOReal minSpeed) const {
    assert(minSpeed > 0);
    if (!myAmDelayed) {
        return myEmptyTraveltime;
    }
    SUMOReal v = 0;
#ifdef HAVE_INTERNAL
    if (MSGlobals::gUseMesoSim) {
        MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(*this);
        unsigned segments = 0;
        do {
            v += first->getMeanSpeed();
            first = first->getNextSegment();
            segments++;
        } while (first != 0);
        v /= (SUMOReal) segments;
    } else {
#endif
        for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
            v += (*i)->getMeanSpeed();
        }
        v /= (SUMOReal) myLanes->size();
#ifdef HAVE_INTERNAL
    }
#endif
    return getLength() / MAX2(minSpeed, v);
}
示例#2
0
SUMOReal
MSEdge::getMeanSpeed() const {
    SUMOReal v = 0;
    SUMOReal no = 0;
    if (MSGlobals::gUseMesoSim) {
        for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
            const SUMOReal vehNo = (SUMOReal) segment->getCarNumber();
            v += vehNo * segment->getMeanSpeed();
            no += vehNo;
        }
        if (no == 0) {
            return getLength() / myEmptyTraveltime; // may include tls-penalty
        }
    } else {
        for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
            const SUMOReal vehNo = (SUMOReal)(*i)->getVehicleNumber();
            v += vehNo * (*i)->getMeanSpeed();
            no += vehNo;
        }
        if (no == 0) {
            return getSpeedLimit();
        }
    }
    return v / no;
}
示例#3
0
SUMOTime
MSLaneSpeedTrigger::processCommand(bool move2next, SUMOTime currentTime) {
    UNUSED_PARAMETER(currentTime);
    std::vector<MSLane*>::iterator i;
    const SUMOReal speed = getCurrentSpeed();
    for (i = myDestLanes.begin(); i != myDestLanes.end(); ++i) {
#ifdef HAVE_INTERNAL
        if (MSGlobals::gUseMesoSim) {
            MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge((*i)->getEdge());
            while (first != 0) {
                first->setSpeed(speed, currentTime, -1);
                first = first->getNextSegment();
            }
            continue;
        }
#endif
        (*i)->setMaxSpeed(speed);
    }
    if (!move2next) {
        // changed from the gui
        return 0;
    }
    if (myCurrentEntry != myLoadedSpeeds.end()) {
        ++myCurrentEntry;
    }
    if (myCurrentEntry != myLoadedSpeeds.end()) {
        return ((*myCurrentEntry).first) - ((*(myCurrentEntry - 1)).first);
    } else {
        return 0;
    }
}
示例#4
0
GUIParameterTableWindow*
GUIEdge::getParameterWindow(GUIMainWindow& app,
                            GUISUMOAbstractView& parent) {
    GUIParameterTableWindow* ret = 0;
#ifdef HAVE_INTERNAL
    ret = new GUIParameterTableWindow(app, *this, 16);
    // add edge items
    ret->mkItem("length [m]", false, (*myLanes)[0]->getLength());
    ret->mkItem("allowed speed [m/s]", false, getAllowedSpeed());
    ret->mkItem("occupancy [%]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getBruttoOccupancy, 100.));
    ret->mkItem("mean vehicle speed [m/s]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getMeanSpeed));
    ret->mkItem("flow [veh/h/lane]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getFlow));
    ret->mkItem("#vehicles", true, new CastingFunctionBinding<GUIEdge, SUMOReal, unsigned int>(this, &GUIEdge::getVehicleNo));
    ret->mkItem("vehicle ids", false, getVehicleIDs());
    // add segment items
    MESegment* segment = getSegmentAtPosition(parent.getPositionInformation());
    ret->mkItem("segment index", false, segment->getIndex());
    ret->mkItem("segment length [m]", false, segment->getLength());
    ret->mkItem("segment allowed speed [m/s]", false, segment->getMaxSpeed());
    ret->mkItem("segment jam threshold [%]", false, segment->getRelativeJamThreshold());
    ret->mkItem("segment occupancy [%]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getRelativeOccupancy));
    ret->mkItem("segment mean vehicle speed [m/s]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getMeanSpeed));
    ret->mkItem("segment flow [veh/h/lane]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getFlow));
    ret->mkItem("segment #vehicles", true, new CastingFunctionBinding<MESegment, SUMOReal, size_t>(segment, &MESegment::getCarNumber));
    ret->mkItem("segment leader leave time", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getEventTimeSeconds));

    // close building
    ret->closeBuilding();
#else
    UNUSED_PARAMETER(app);
    UNUSED_PARAMETER(parent);
#endif
    return ret;
}
/* -------------------------------------------------------------------------
 * MSTriggeredRerouter - methods
 * ----------------------------------------------------------------------- */
MSTriggeredRerouter::MSTriggeredRerouter(const std::string &id,
        const std::vector<MSEdge*> &edges,
        SUMOReal prob, const std::string &file, bool off)
        : MSTrigger(id), SUMOSAXHandler(file),
        myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
    // read in the trigger description
    if (!XMLSubSys::runParser(*this, file)) {
        throw ProcessError();
    }
    // build actors
#ifdef HAVE_MESOSIM
    if (MSGlobals::gUseMesoSim) {
        for (std::vector<MSEdge*>::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
            MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(**j);
            s->addRerouter(this);
        }
    } else {
#endif
        for (std::vector<MSEdge*>::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
            const std::vector<MSLane*> &destLanes = (*j)->getLanes();
            for (std::vector<MSLane*>::const_iterator i=destLanes.begin(); i!=destLanes.end(); ++i) {
                mySetter.push_back(new Setter(this, (*i)));
            }
        }
#ifdef HAVE_MESOSIM
    }
#endif
    if (off) {
        setUserMode(true);
        setUserUsageProbability(0);
    }
}
示例#6
0
// ===========================================================================
// method definitions
// ===========================================================================
MSTriggeredRerouter::MSTriggeredRerouter(const std::string& id,
        const std::vector<MSEdge*>& edges,
        SUMOReal prob, const std::string& file, bool off) :
    MSTrigger(id),
    MSMoveReminder(id),
    SUMOSAXHandler(file),
    myProbability(prob), myUserProbability(prob), myAmInUserMode(false) {
    // read in the trigger description
    if (file != "" && !XMLSubSys::runParser(*this, file)) {
        throw ProcessError();
    }
    // build actors
    for (std::vector<MSEdge*>::const_iterator j = edges.begin(); j != edges.end(); ++j) {
#ifdef HAVE_INTERNAL
        if (MSGlobals::gUseMesoSim) {
            MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(**j);
            s->addDetector(this);
            continue;
        }
#endif
        const std::vector<MSLane*>& destLanes = (*j)->getLanes();
        for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
            (*i)->addMoveReminder(this);
        }
    }
    if (off) {
        setUserMode(true);
        setUserUsageProbability(0);
    }
}
示例#7
0
unsigned int
GUIEdge::getVehicleNo() const {
    size_t vehNo = 0;
    for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
        vehNo += segment->getCarNumber();
    }
    return (unsigned int)vehNo;
}
示例#8
0
SUMOReal
GUIEdge::getFlow() const {
    SUMOReal flow = 0;
    for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
        flow += (SUMOReal) segment->getCarNumber() * segment->getMeanSpeed();
    }
    return 3600 * flow / (*myLanes)[0]->getLength();
}
示例#9
0
SUMOReal
GUIEdge::getBruttoOccupancy() const {
    SUMOReal occ = 0;
    for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
        occ += segment->getBruttoOccupancy();
    }
    return occ / (*myLanes)[0]->getLength() / (SUMOReal)(myLanes->size());
}
示例#10
0
文件: MELoop.cpp 项目: cbrafter/sumo
MELoop::~MELoop() {
    for (std::vector<MESegment*>::const_iterator j = myEdges2FirstSegments.begin(); j != myEdges2FirstSegments.end(); ++j) {
        for (MESegment* s = *j; s != 0;) {
            MESegment* n = s->getNextSegment();
            delete s;
            s = n;
        }
    }
}
示例#11
0
文件: MELoop.cpp 项目: cbrafter/sumo
MESegment*
MELoop::getSegmentForEdge(const MSEdge& e, SUMOReal pos) {
    MESegment* s = myEdges2FirstSegments[e.getNumericalID()];
    if (pos > 0) {
        SUMOReal cpos = 0;
        while (s->getNextSegment() != 0 && cpos + s->getLength() < pos) {
            cpos += s->getLength();
            s = s->getNextSegment();
        }
    }
    return s;
}
示例#12
0
std::string
GUIEdge::getVehicleIDs() const {
    std::string result = " ";
    std::vector<const MEVehicle*> vehs;
    for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
        std::vector<const MEVehicle*> segmentVehs = segment->getVehicles();
        vehs.insert(vehs.end(), segmentVehs.begin(), segmentVehs.end());
    }
    for (std::vector<const MEVehicle*>::const_iterator it = vehs.begin(); it != vehs.end(); it++) {
        result += (*it)->getID() + " ";
    }
    return result;
}
示例#13
0
SUMOReal
GUIEdge::getMeanSpeed() const {
    SUMOReal v = 0;
    SUMOReal no = 0;
    for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) {
        SUMOReal vehNo = (SUMOReal) segment->getCarNumber();
        v += vehNo * segment->getMeanSpeed();
        no += vehNo;
    }
    if (no == 0) {
        return getSpeedLimit();
    }
    return v / no;
}
示例#14
0
文件: MSEdge.cpp 项目: harora/ITS
bool
MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time) const {
    // when vaporizing, no vehicles are inserted...
    if (isVaporizing()) {
        return false;
    }
#ifdef HAVE_INTERNAL
    if (MSGlobals::gUseMesoSim) {
        const SUMOVehicleParameter& pars = v.getParameter();
        SUMOReal pos = 0.0;
        switch (pars.departPosProcedure) {
            case DEPART_POS_GIVEN:
                if (pars.departPos >= 0.) {
                    pos = pars.departPos;
                } else {
                    pos = pars.departPos + getLength();
                }
                if (pos < 0 || pos > getLength()) {
                    WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
                                  v.getID() + "'. Inserting at lane end instead.");
                    pos = getLength();
                }
                break;
            case DEPART_POS_RANDOM:
            case DEPART_POS_RANDOM_FREE:
                pos = RandHelper::rand(getLength());
                break;
            default:
                break;
        }
        bool result = false;
        MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
        MEVehicle* veh = static_cast<MEVehicle*>(&v);
        if (pars.departPosProcedure == DEPART_POS_FREE) {
            while (segment != 0 && !result) {
                result = segment->initialise(veh, time);
                segment = segment->getNextSegment();
            }
        } else {
            result = segment->initialise(veh, time);
        }
        return result;
    }
#else
    UNUSED_PARAMETER(time);
#endif
    MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
    return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
}
示例#15
0
void
GUIEdge::drawMesoVehicles(const GUIVisualizationSettings& s) const {
    GUIMEVehicleControl* vehicleControl = GUINet::getGUIInstance()->getGUIMEVehicleControl();
    if (vehicleControl != 0) {
        // draw the meso vehicles
        vehicleControl->secureVehicles();
        AbstractMutex::ScopedLocker locker(myLock);
        size_t laneIndex = 0;
        MESegment::Queue queue;
        for (std::vector<MSLane*>::const_iterator msl = myLanes->begin(); msl != myLanes->end(); ++msl, ++laneIndex) {
            GUILane* l = static_cast<GUILane*>(*msl);
            // go through the vehicles
            SUMOReal segmentOffset = 0; // offset at start of current segment
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                const SUMOReal length = segment->getLength();
                if (laneIndex < segment->numQueues()) {
                    // make a copy so we don't have to worry about synchronization
                    queue = segment->getQueue(laneIndex);
                    const size_t queueSize = queue.size();
                    SUMOReal vehiclePosition = segmentOffset + length;
                    // draw vehicles beginning with the leader at the end of the segment
                    SUMOReal xOff = 0;
                    for (size_t i = 0; i < queueSize; ++i) {
                        GUIMEVehicle* veh = static_cast<GUIMEVehicle*>(queue[queueSize - i - 1]);
                        const SUMOReal vehLength = veh->getVehicleType().getLengthWithGap();
                        while (vehiclePosition < segmentOffset) {
                            // if there is only a single queue for a
                            // multi-lane edge shift vehicles and start
                            // drawing again from the end of the segment
                            vehiclePosition += length;
                            xOff += 2;
                        }
                        const Position p = l->geometryPositionAtOffset(vehiclePosition);
                        const SUMOReal angle = l->getShape().rotationAtOffset(l->interpolateLanePosToGeometryPos(vehiclePosition));
                        veh->setPositionAndAngle(p, angle);
                        veh->drawGL(s);
                        vehiclePosition -= vehLength;
                    }
                }
                segmentOffset += length;
            }
            glPopMatrix();
        }
        vehicleControl->releaseVehicles();
    }
}
示例#16
0
GUIParameterTableWindow*
GUIEdge::getParameterWindow(GUIMainWindow& app,
                            GUISUMOAbstractView& parent) {
    GUIParameterTableWindow* ret = 0;
    ret = new GUIParameterTableWindow(app, *this, 18);
    // add edge items
    ret->mkItem("length [m]", false, (*myLanes)[0]->getLength());
    ret->mkItem("allowed speed [m/s]", false, getAllowedSpeed());
    ret->mkItem("brutto occupancy [%]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getBruttoOccupancy, 100.));
    ret->mkItem("mean vehicle speed [m/s]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getMeanSpeed));
    ret->mkItem("flow [veh/h/lane]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getFlow));
    ret->mkItem("routing speed [m/s]", true, new FunctionBinding<MSEdge, SUMOReal>(this, &MSEdge::getRoutingSpeed));
    ret->mkItem("#vehicles", true, new CastingFunctionBinding<GUIEdge, SUMOReal, int>(this, &GUIEdge::getVehicleNo));
    ret->mkItem("vehicle ids", false, getVehicleIDs());
    // add segment items
    MESegment* segment = getSegmentAtPosition(parent.getPositionInformation());
    ret->mkItem("segment index", false, segment->getIndex());
    ret->mkItem("segment queues", false, segment->numQueues());
    ret->mkItem("segment length [m]", false, segment->getLength());
    ret->mkItem("segment allowed speed [m/s]", false, segment->getEdge().getSpeedLimit());
    ret->mkItem("segment jam threshold [%]", false, segment->getRelativeJamThreshold() * 100);
    ret->mkItem("segment brutto occupancy [%]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getRelativeOccupancy, 100));
    ret->mkItem("segment mean vehicle speed [m/s]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getMeanSpeed));
    ret->mkItem("segment flow [veh/h/lane]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getFlow));
    ret->mkItem("segment #vehicles", true, new CastingFunctionBinding<MESegment, SUMOReal, int>(segment, &MESegment::getCarNumber));
    ret->mkItem("segment leader leave time", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getEventTimeSeconds));
    ret->mkItem("segment headway [s]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getLastHeadwaySeconds));

    // close building
    ret->closeBuilding();
    return ret;
}
示例#17
0
// ===========================================================================
// method definitions
// ===========================================================================
MSRouteProbe::MSRouteProbe(const std::string& id, const MSEdge* edge, const std::string& distID, const std::string& lastID) :
    MSDetectorFileOutput(id), MSMoveReminder(id) {
    myCurrentRouteDistribution = std::make_pair(distID, MSRoute::distDictionary(distID));
    if (myCurrentRouteDistribution.second == 0) {
        myCurrentRouteDistribution.second = new RandomDistributor<const MSRoute*>();
        MSRoute::dictionary(distID, myCurrentRouteDistribution.second, false);
    }
    myLastRouteDistribution = std::make_pair(lastID, MSRoute::distDictionary(lastID));
#ifdef HAVE_INTERNAL
    if (MSGlobals::gUseMesoSim) {
        MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
        while (seg != 0) {
            seg->addDetector(this);
            seg = seg->getNextSegment();
        }
        return;
    }
#endif
    for (std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); it != edge->getLanes().end(); ++it) {
        (*it)->addMoveReminder(this);
    }
}
// ===========================================================================
// method definitions
// ===========================================================================
MSRouteProbe::MSRouteProbe(const std::string& id, const MSEdge* edge, SUMOTime begin)
    : MSDetectorFileOutput(id), myCurrentRouteDistribution(0) {
    const std::string distID = id + "_" + toString(begin);
    myCurrentRouteDistribution = MSRoute::distDictionary(distID);
    if (myCurrentRouteDistribution == 0) {
        myCurrentRouteDistribution = new RandomDistributor<const MSRoute*>(MSRoute::getMaxRouteDistSize(), &MSRoute::releaseRoute);
        MSRoute::dictionary(distID, myCurrentRouteDistribution);
    }
#ifdef HAVE_INTERNAL
    if (MSGlobals::gUseMesoSim) {
        MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
        while (seg != 0) {
            seg->addDetector(this);
            seg = seg->getNextSegment();
        }
        return;
    }
#endif
    for (std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); it != edge->getLanes().end(); ++it) {
        (*it)->addMoveReminder(this);
    }
}
示例#19
0
void
MSStateHandler::saveState(const std::string& file, SUMOTime step) {
    OutputDevice& out = OutputDevice::getDevice(file);
    out.writeHeader<MSEdge>(SUMO_TAG_SNAPSHOT);
    out.writeAttr(SUMO_ATTR_VERSION, VERSION_STRING).writeAttr(SUMO_ATTR_TIME, step);
    MSRoute::dict_saveState(out);
    MSNet::getInstance()->getVehicleControl().saveState(out);
    if (MSGlobals::gUseMesoSim) {
#ifdef HAVE_INTERNAL
        for (size_t i = 0; i < MSEdge::dictSize(); i++) {
            for (MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(*MSEdge::dictionary(i)); s != 0; s = s->getNextSegment()) {
                s->saveState(out);
            }
        }
#endif
    } else {
        for (size_t i = 0; i < MSEdge::dictSize(); i++) {
            const std::vector<MSLane*>& lanes = MSEdge::dictionary(i)->getLanes();
            for (std::vector<MSLane*>::const_iterator it = lanes.begin(); it != lanes.end(); ++it) {
                (*it)->saveState(out);
            }
        }
    }
}
MSRouteProbe::MSRouteProbe(const std::string &id, const MSEdge *edge, SUMOTime begin) throw()
        : Named(id), myCurrentRouteDistribution(0) {
    const std::string distID = id + "_" + toString(begin);
    myCurrentRouteDistribution = MSRoute::distDictionary(distID);
    if (myCurrentRouteDistribution == 0) {
        myCurrentRouteDistribution = new RandomDistributor<const MSRoute*>();
        MSRoute::dictionary(distID, myCurrentRouteDistribution);
    }
#ifdef HAVE_MESOSIM
    if (MSGlobals::gUseMesoSim) {
        MESegment *seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
        while (seg!=0) {
            seg->setRouteProbe(this);
            seg = seg->getNextSegment();
        }
        return;
    }
#endif
    std::vector<MSLane*>::const_iterator it = edge->getLanes().begin();
    myEntryReminder = new MSRouteProbe::EntryReminder(*it, *this);
    for (++it; it!=edge->getLanes().end(); ++it) {
        (*it)->addMoveReminder(myEntryReminder);
    }
}
void
NLDetectorBuilder::buildInductLoop(const std::string &id,
                                   const std::string &lane, SUMOReal pos, int splInterval,
                                   OutputDevice& device, bool friendlyPos) throw(InvalidArgument) {
    if (splInterval<0) {
        throw InvalidArgument("Negative sampling frequency (in e1-detector '" + id + "').");
    }
    if (splInterval==0) {
        throw InvalidArgument("Sampling frequency must not be zero (in e1-detector '" + id + "').");
    }
    // get and check the lane
    MSLane *clane = getLaneChecking(lane, id);
    if (pos<0) {
        pos = clane->getLength() + pos;
    }
#ifdef HAVE_MESOSIM
    if (!MSGlobals::gUseMesoSim) {
#endif
        // get and check the position
        pos = getPositionChecking(pos, clane, friendlyPos, id);
        // build the loop
        MSInductLoop *loop = createInductLoop(id, clane, pos);
        // add the file output
        myNet.getDetectorControl().add(loop, device, splInterval);
#ifdef HAVE_MESOSIM
    } else {
        if (pos<0) {
            pos = clane->getLength() + pos;
        }
        MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(clane->getEdge());
        MESegment *prev = s;
        SUMOReal cpos = 0;
        while (cpos+prev->getLength()<pos&&s!=0) {
            prev = s;
            cpos += s->getLength();
            s = s->getNextSegment();
        }
        SUMOReal rpos = pos-cpos;//-prev->getLength();
        if (rpos>prev->getLength()||rpos<0) {
            if (friendlyPos) {
                rpos = prev->getLength() - (SUMOReal) 0.1;
            } else {
                throw InvalidArgument("The position of detector '" + id + "' lies beyond the lane's '" + lane + "' length.");
            }
        }
        MEInductLoop *loop =
            createMEInductLoop(id, prev, rpos);
        myNet.getDetectorControl().add(loop, device, splInterval);
    }
#endif
}
示例#22
0
文件: MELoop.cpp 项目: cbrafter/sumo
void
MELoop::teleportVehicle(MEVehicle* veh, MESegment* const toSegment) {
    const SUMOTime leaveTime = veh->getEventTime();
    MESegment* const onSegment = veh->getSegment();
    const bool teleporting = (onSegment == 0); // is the vehicle already teleporting?
    // try to find a place on the current edge
    MESegment* teleSegment = toSegment->getNextSegment();
    while (teleSegment != 0 && !teleSegment->hasSpaceFor(veh, leaveTime)) {
        // @caution the time to get to the next segment here is ignored XXX
        teleSegment = teleSegment->getNextSegment();
    }
    if (teleSegment != 0) {
        if (!teleporting) {
            // we managed to teleport in a single jump
            WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, from edge '" + onSegment->getEdge().getID()
                          + "':" + toString(onSegment->getIndex())
                          + " to edge '" + teleSegment->getEdge().getID()
                          + "':" + toString(teleSegment->getIndex())
                          + ", time " + time2string(leaveTime) + ".");
            MSNet::getInstance()->getVehicleControl().registerTeleportJam();
        }
        changeSegment(veh, leaveTime, teleSegment, true);
        teleSegment->setEntryBlockTime(leaveTime); // teleports should not block normal flow
    } else {
        // teleport across the current edge and try insertion later
        if (!teleporting) {
            // announce start of multi-step teleport, arrival will be announced in changeSegment()
            WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, from edge '" + onSegment->getEdge().getID()
                          + "':" + toString(onSegment->getIndex()) + ", time " + time2string(leaveTime) + ".");
            MSNet::getInstance()->getVehicleControl().registerTeleportJam();
            // remove from current segment
            onSegment->send(veh, 0, leaveTime);
            // mark veh as teleporting
            veh->setSegment(0, 0);
        }
        // @caution microsim uses current travel time teleport duration
        const SUMOTime teleArrival = leaveTime + TIME2STEPS(veh->getEdge()->getLength() / veh->getEdge()->getSpeedLimit());
        const bool atDest = veh->moveRoutePointer();
        if (atDest) {
            // teleporting to end of route
            changeSegment(veh, teleArrival, 0, true);
        } else {
            veh->setEventTime(teleArrival);
            addLeaderCar(veh, 0);
            // teleporting vehicles must react to rerouters
            getSegmentForEdge(*veh->getEdge())->addReminders(veh);
            veh->activateReminders(MSMoveReminder::NOTIFICATION_JUNCTION);
        }
    }
}
void
NLDetectorBuilder::buildInductLoop(const std::string& id,
                                   const std::string& lane, SUMOReal pos, int splInterval,
                                   const std::string& device, bool friendlyPos, bool splitByType) {
    checkSampleInterval(splInterval, SUMO_TAG_E1DETECTOR, id);
    // get and check the lane
    MSLane* clane = getLaneChecking(lane, SUMO_TAG_E1DETECTOR, id);
    if (!MSGlobals::gUseMesoSim) {
        // get and check the position
        pos = getPositionChecking(pos, clane, friendlyPos, id);
        // build the loop
        MSDetectorFileOutput* loop = createInductLoop(id, clane, pos, splitByType);
        // add the file output
        myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval);
    } else {
#ifdef HAVE_INTERNAL
        if (pos < 0) {
            pos = clane->getLength() + pos;
        }
        MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(clane->getEdge());
        MESegment* prev = s;
        SUMOReal cpos = 0;
        while (cpos + prev->getLength() < pos && s != 0) {
            prev = s;
            cpos += s->getLength();
            s = s->getNextSegment();
        }
        SUMOReal rpos = pos - cpos; //-prev->getLength();
        if (rpos > prev->getLength() || rpos < 0) {
            if (friendlyPos) {
                rpos = prev->getLength() - (SUMOReal) 0.1;
            } else {
                throw InvalidArgument("The position of detector '" + id + "' lies beyond the lane's '" + lane + "' length.");
            }
        }
        MEInductLoop* loop =
            createMEInductLoop(id, prev, rpos);
        myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval);
#endif
    }
}
示例#24
0
bool
GUIEdge::setMultiColor(const GUIColorer& c) const {
    const int activeScheme = c.getActive();
    mySegmentColors.clear();
    switch (activeScheme) {
        case 10: // alternating segments
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                mySegmentColors.push_back(c.getScheme().getColor(segment->getIndex() % 2));
            }
            //std::cout << getID() << " scheme=" << c.getScheme().getName() << " schemeCols=" << c.getScheme().getColors().size() << " thresh=" << toString(c.getScheme().getThresholds()) << " segmentColors=" << mySegmentColors.size() << " [0]=" << mySegmentColors[0] << " [1]=" << mySegmentColors[1] <<  "\n";
            return true;
        case 11: // by segment jammed state
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                mySegmentColors.push_back(c.getScheme().getColor(segment->free() ? 0 : 1));
            }
            return true;
        case 12: // by segment occupancy
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                mySegmentColors.push_back(c.getScheme().getColor(segment->getRelativeOccupancy()));
            }
            return true;
        case 13: // by segment speed
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                mySegmentColors.push_back(c.getScheme().getColor(segment->getMeanSpeed()));
            }
            return true;
        case 14: // by segment flow
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                mySegmentColors.push_back(c.getScheme().getColor(3600 * segment->getCarNumber() * segment->getMeanSpeed() / segment->getLength()));
            }
            return true;
        case 15: // by segment relative speed
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                mySegmentColors.push_back(c.getScheme().getColor(segment->getMeanSpeed() / getAllowedSpeed()));
            }
            return true;
        default:
            return false;
    }
}
示例#25
0
void
GUIEdge::drawGL(const GUIVisualizationSettings& s) const {
    if (s.hideConnectors && myFunction == MSEdge::EDGEFUNCTION_CONNECTOR) {
        return;
    }
    if (MSGlobals::gUseMesoSim) {
        glPushName(getGlID());
    }
    // draw the lanes
    for (LaneWrapperVector::const_iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) {
#ifdef HAVE_INTERNAL
        if (MSGlobals::gUseMesoSim) {
            setColor(s);
        }
#endif
        (*i)->drawGL(s);
    }
#ifdef HAVE_INTERNAL
    if (MSGlobals::gUseMesoSim) {
        const GUIVisualizationTextSettings& nameSettings = s.vehicleName;
        GUIMEVehicleControl* vehicleControl = GUINet::getGUIInstance()->getGUIMEVehicleControl();
        if (vehicleControl != 0) {
            // draw the meso vehicles
            vehicleControl->secureVehicles();
            size_t laneIndex = 0;
            MESegment::Queue queue;
            for (LaneWrapperVector::const_iterator l = myLaneGeoms.begin(); l != myLaneGeoms.end(); ++l, ++laneIndex) {
                const PositionVector& shape = (*l)->getShape();
                const std::vector<SUMOReal>& shapeRotations = (*l)->getShapeRotations();
                const std::vector<SUMOReal>& shapeLengths = (*l)->getShapeLengths();
                const Position& laneBeg = shape[0];
                glPushMatrix();
                glTranslated(laneBeg.x(), laneBeg.y(), 0);
                glRotated(shapeRotations[0], 0, 0, 1);
                // go through the vehicles
                int shapeIndex = 0;
                SUMOReal shapeOffset = 0; // ofset at start of current shape
                SUMOReal segmentOffset = 0; // offset at start of current segment
                for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                        segment != 0; segment = segment->getNextSegment()) {
                    const SUMOReal length = segment->getLength();
                    if (laneIndex < segment->numQueues()) {
                        // make a copy so we don't have to worry about synchronization
                        queue = segment->getQueue(laneIndex);
                        const SUMOReal avgCarSize = segment->getOccupancy() / segment->getCarNumber();
                        const size_t queueSize = queue.size();
                        for (size_t i = 0; i < queueSize; i++) {
                            MSBaseVehicle* veh = queue[queueSize - i - 1];
                            setVehicleColor(s, veh);
                            SUMOReal vehiclePosition = segmentOffset + length - i * avgCarSize;
                            SUMOReal xOff = 0.f;
                            while (vehiclePosition < segmentOffset) {
                                // if there is only a single queue for a
                                // multi-lane edge shift vehicles and start
                                // drawing again from the end of the segment
                                vehiclePosition += length;
                                xOff += 0.5f;
                            }
                            while (shapeIndex < (int)shapeRotations.size() - 1 && vehiclePosition > shapeOffset + shapeLengths[shapeIndex]) {
                                glPopMatrix();
                                shapeOffset += shapeLengths[shapeIndex];
                                shapeIndex++;
                                glPushMatrix();
                                glTranslated(shape[shapeIndex].x(), shape[shapeIndex].y(), 0);
                                glRotated(shapeRotations[shapeIndex], 0, 0, 1);
                            }
                            glPushMatrix();
                            glTranslated(xOff, -(vehiclePosition - shapeOffset), GLO_VEHICLE);
                            glPushMatrix();
                            glScaled(1, avgCarSize, 1);
                            glBegin(GL_TRIANGLES);
                            glVertex2d(0, 0);
                            glVertex2d(0 - 1.25, 1);
                            glVertex2d(0 + 1.25, 1);
                            glEnd();
                            glPopMatrix();
                            glPopMatrix();
                            if (nameSettings.show) {
                                GLHelper::drawText(veh->getID(),
                                                   Position(xOff, -(vehiclePosition - shapeOffset)),
                                                   GLO_MAX, nameSettings.size / s.scale, nameSettings.color, 0);
                            }
                        }
                    }
                    segmentOffset += length;
                }
                glPopMatrix();
            }
            vehicleControl->releaseVehicles();
        }
        glPopName();
    }
#endif
    // (optionally) draw the name and/or the street name
    const bool drawEdgeName = s.edgeName.show && myFunction == EDGEFUNCTION_NORMAL;
    const bool drawInternalEdgeName = s.internalEdgeName.show && myFunction != EDGEFUNCTION_NORMAL;
    const bool drawStreetName = s.streetName.show && myStreetName != "";
    if (drawEdgeName || drawInternalEdgeName || drawStreetName) {
        GUILaneWrapper* lane1 = myLaneGeoms[0];
        GUILaneWrapper* lane2 = myLaneGeoms[myLaneGeoms.size() - 1];
        Position p = lane1->getShape().positionAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.);
        p.add(lane2->getShape().positionAtLengthPosition(lane2->getShape().length() / (SUMOReal) 2.));
        p.mul(.5);
        SUMOReal angle = lane1->getShape().rotationDegreeAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.);
        angle += 90;
        if (angle > 90 && angle < 270) {
            angle -= 180;
        }
        if (drawEdgeName) {
            drawName(p, s.scale, s.edgeName, angle);
        } else if (drawInternalEdgeName) {
            drawName(p, s.scale, s.internalEdgeName, angle);
        }
        if (drawStreetName) {
            GLHelper::drawText(getStreetName(), p, GLO_MAX,
                               s.streetName.size / s.scale, s.streetName.color, angle);
        }
    }
    myLock.lock();
    for (std::set<MSPerson*>::const_iterator i = myPersons.begin(); i != myPersons.end(); ++i) {
        GUIPerson* person = dynamic_cast<GUIPerson*>(*i);
        assert(person != 0);
        person->drawGL(s);
    }
    myLock.unlock();
}
示例#26
0
void
MSXMLRawOut::writeEdge(OutputDevice& of, const MSEdge& edge, SUMOTime timestep) {
    //en
    bool dump = !MSGlobals::gOmitEmptyEdgesOnDump;
    if (!dump) {
#ifdef HAVE_INTERNAL
        if (MSGlobals::gUseMesoSim) {
            MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(edge);
            while (seg != 0) {
                if (seg->getCarNumber() != 0) {
                    dump = true;
                    break;
                }
                seg = seg->getNextSegment();
            }
        } else {
#endif
            const std::vector<MSLane*>& lanes = edge.getLanes();
            for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
                if (((**lane).getVehicleNumber() != 0)) {
                    dump = true;
                    break;
                }
            }
#ifdef HAVE_INTERNAL
        }
#endif
    }
    //en
    const std::vector<MSPerson*>& persons = edge.getSortedPersons(timestep);
    if (dump || persons.size() > 0) {
        of.openTag("edge") << " id=\"" << edge.getID() << "\"";
        if (dump) {
#ifdef HAVE_INTERNAL
            if (MSGlobals::gUseMesoSim) {
                MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(edge);
                while (seg != 0) {
                    seg->writeVehicles(of);
                    seg = seg->getNextSegment();
                }
            } else {
#endif
                const std::vector<MSLane*>& lanes = edge.getLanes();
                for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
                    writeLane(of, **lane);
                }
#ifdef HAVE_INTERNAL
            }
#endif
        }
        // write persons
        for (std::vector<MSPerson*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
            of.openTag(SUMO_TAG_PERSON);
            of.writeAttr(SUMO_ATTR_ID, (*it_p)->getID());
            of.writeAttr(SUMO_ATTR_POSITION, (*it_p)->getEdgePos());
            of.writeAttr(SUMO_ATTR_ANGLE, (*it_p)->getAngle());
            of.writeAttr("stage", (*it_p)->getCurrentStageDescription());
            of.closeTag();
        }
        of.closeTag();
    }
}
示例#27
0
void
GUIEdge::drawMesoVehicles(const GUIVisualizationSettings& s) const {
    const GUIVisualizationTextSettings& nameSettings = s.vehicleName;
    const SUMOReal exaggeration = s.vehicleSize.getExaggeration(s);
    GUIMEVehicleControl* vehicleControl = GUINet::getGUIInstance()->getGUIMEVehicleControl();
    if (vehicleControl != 0) {
        // draw the meso vehicles
        vehicleControl->secureVehicles();
        size_t laneIndex = 0;
        MESegment::Queue queue;
        for (std::vector<MSLane*>::const_iterator msl = myLanes->begin(); msl != myLanes->end(); ++msl, ++laneIndex) {
            GUILane* l = static_cast<GUILane*>(*msl);
            // go through the vehicles
            SUMOReal segmentOffset = 0; // offset at start of current segment
            for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this);
                    segment != 0; segment = segment->getNextSegment()) {
                const SUMOReal length = segment->getLength() * segment->getLengthGeometryFactor();
                if (laneIndex < segment->numQueues()) {
                    // make a copy so we don't have to worry about synchronization
                    queue = segment->getQueue(laneIndex);
                    const SUMOReal avgCarSize = segment->getBruttoOccupancy() / segment->getCarNumber();
                    const SUMOReal avgCarHalfSize = 0.5 * avgCarSize;
                    const size_t queueSize = queue.size();
                    SUMOReal vehiclePosition = segmentOffset + length;
                    // draw vehicles beginning with the leader at the end of the segment
                    SUMOReal xOff = 0;
                    for (size_t i = 0; i < queueSize; ++i) {
                        MSBaseVehicle* veh = queue[queueSize - i - 1];
                        const SUMOReal vehLength = veh->getVehicleType().getLengthWithGap();
                        setVehicleColor(s, veh);
                        while (vehiclePosition < segmentOffset) {
                            // if there is only a single queue for a
                            // multi-lane edge shift vehicles and start
                            // drawing again from the end of the segment
                            vehiclePosition += length;
                            xOff += 2;
                        }
                        const Position p = l->geometryPositionAtOffset(vehiclePosition);
                        const SUMOReal angle = -l->getShape().rotationDegreeAtOffset(l->interpolateLanePosToGeometryPos(vehiclePosition));
                        glPushMatrix();
                        glTranslated(p.x(), p.y(), 0);
                        glRotated(angle, 0, 0, 1);
                        glTranslated(xOff, 0, GLO_VEHICLE);
                        glScaled(exaggeration, vehLength * exaggeration, 1);
                        glBegin(GL_TRIANGLES);
                        glVertex2d(0, 0);
                        glVertex2d(0 - 1.25, 1);
                        glVertex2d(0 + 1.25, 1);
                        glEnd();
                        glPopMatrix();
                        if (nameSettings.show) {
                            glPushMatrix();
                            glRotated(angle, 0, 0, 1);
                            glTranslated(xOff, 0, 0);
                            glRotated(-angle, 0, 0, 1);
                            GLHelper::drawText(veh->getID(),
                                               l->geometryPositionAtOffset(vehiclePosition - 0.5 * vehLength),
                                               GLO_MAX, nameSettings.size / s.scale, nameSettings.color);
                            glPopMatrix();
                        }
                        vehiclePosition -= vehLength;
                    }
                }
                segmentOffset += length;
            }
            glPopMatrix();
        }
        vehicleControl->releaseVehicles();
    }
}
示例#28
0
bool
MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly) const {
    // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
    if (isVaporizing()) {
        return checkOnly;
    }
    const SUMOVehicleParameter& pars = v.getParameter();
    const MSVehicleType& type = v.getVehicleType();
    if (pars.departSpeedProcedure == DEPART_SPEED_GIVEN && pars.departSpeed > getVehicleMaxSpeed(&v)) {
        if (type.getSpeedDeviation() > 0 && pars.departSpeed <= type.getSpeedFactor() * getSpeedLimit() * (2 * type.getSpeedDeviation() + 1.)) {
            WRITE_WARNING("Choosing new speed factor for vehicle '" + pars.id + "' to match departure speed.");
            v.setChosenSpeedFactor(type.computeChosenSpeedDeviation(0, pars.departSpeed / (type.getSpeedFactor() * getSpeedLimit())));
        } else {
            throw ProcessError("Departure speed for vehicle '" + pars.id +
                               "' is too high for the departure edge '" + getID() + "'.");
        }
    }
    if (checkOnly && v.getEdge()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
        return true;
    }
    if (!checkOnly) {
        std::string msg;
        if (!v.hasValidRoute(msg)) {
            if (MSGlobals::gCheckRoutes) {
                throw ProcessError("Vehicle '" + v.getID() + "' has no valid route. " + msg);
            } else if (v.getEdge()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) {
                WRITE_WARNING("Removing vehicle '" + pars.id + "' which has no valid route.");
                MSNet::getInstance()->getInsertionControl().descheduleDeparture(&v);
                return false;
            }
        }
    }
    if (MSGlobals::gUseMesoSim) {
        SUMOReal pos = 0.0;
        switch (pars.departPosProcedure) {
            case DEPART_POS_GIVEN:
                if (pars.departPos >= 0.) {
                    pos = pars.departPos;
                } else {
                    pos = pars.departPos + getLength();
                }
                if (pos < 0 || pos > getLength()) {
                    WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
                                  v.getID() + "'. Inserting at lane end instead.");
                    pos = getLength();
                }
                break;
            case DEPART_POS_RANDOM:
            case DEPART_POS_RANDOM_FREE:
                pos = RandHelper::rand(getLength());
                break;
            default:
                break;
        }
        bool result = false;
        MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
        MEVehicle* veh = static_cast<MEVehicle*>(&v);
        if (pars.departPosProcedure == DEPART_POS_FREE) {
            while (segment != 0 && !result) {
                if (checkOnly) {
                    result = segment->hasSpaceFor(veh, time, true);
                } else {
                    result = segment->initialise(veh, time);
                }
                segment = segment->getNextSegment();
            }
        } else {
            if (checkOnly) {
                result = segment->hasSpaceFor(veh, time, true);
            } else {
                result = segment->initialise(veh, time);
            }
        }
        return result;
    }
    if (checkOnly) {
        switch (v.getParameter().departLaneProcedure) {
            case DEPART_LANE_GIVEN:
            case DEPART_LANE_DEFAULT:
            case DEPART_LANE_FIRST_ALLOWED: {
                const SUMOReal occupancy = getDepartLane(static_cast<MSVehicle&>(v))->getBruttoOccupancy();
                return occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
            }
            default:
                for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
                    const SUMOReal occupancy = (*i)->getBruttoOccupancy();
                    if (occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
                        return true;
                    }
                }
        }
        return false;
    }
    MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
    return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
}
示例#29
0
SUMOTime
METriggeredCalibrator::execute(SUMOTime currentTime) {
    // get current simulation values (valid for the last simulation second)
    // XXX could we miss vehicle movements if this is called less often than every DELTA_T (default) ?
    mySegment->prepareDetectorForWriting(myEdgeMeanData);

    // check whether an adaptation value exists
    if (isCurrentStateActive(currentTime)) {
        // all happens in isCurrentStateActive()
    } else {
        myEdgeMeanData.reset(); // discard collected values
        if (!mySpeedIsDefault) {
            // if not, reset adaptation values
            mySegment->getEdge().setMaxSpeed(myDefaultSpeed);
            MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(mySegment->getEdge());
            const SUMOReal jamThresh = OptionsCont::getOptions().getFloat("meso-jam-threshold");
            while (first != 0) {
                first->setSpeed(myDefaultSpeed, currentTime, jamThresh);
                first = first->getNextSegment();
            }
            mySpeedIsDefault = true;
        }
        if (myCurrentStateInterval == myIntervals.end()) {
            // keep calibrator alive but do not call again
            return TIME2STEPS(86400);
        }
        return myFrequency;
    }
    // we are active
    if (!myDidSpeedAdaption && myCurrentStateInterval->v >= 0 && myCurrentStateInterval->v != mySegment->getEdge().getSpeedLimit()) {
        mySegment->getEdge().setMaxSpeed(myCurrentStateInterval->v);
        MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(mySegment->getEdge());
        while (first != 0) {
            first->setSpeed(myCurrentStateInterval->v, currentTime, -1);
            first = first->getNextSegment();
        }
        mySpeedIsDefault = false;
        myDidSpeedAdaption = true;
    }
    // clear invalid jams
    bool hadInvalidJam = false;
    while (invalidJam()) {
        hadInvalidJam = true;
        if (!myHaveWarnedAboutClearingJam) {
            WRITE_WARNING("Clearing jam at calibrator '" + myID + "' at time " + time2string(currentTime));
        }
        // remove one vehicle currently on the segment
        if (mySegment->vaporizeAnyCar(currentTime)) {
            myClearedInJam++;
        } else {
            if (!myHaveWarnedAboutClearingJam) {
                // this frequenly happens for very short edges
                WRITE_WARNING("Could not clear jam at calibrator '" + myID + "' at time " + time2string(currentTime));
            }
            break;
        }
        myHaveWarnedAboutClearingJam = true;
    }
    if (myCurrentStateInterval->q >= 0) {
        // flow calibration starts here ...
        // compute the number of vehicles that should have passed the calibrator within the time
        // rom begin of the interval
        const SUMOReal totalHourFraction = STEPS2TIME(myCurrentStateInterval->end - myCurrentStateInterval->begin) / (SUMOReal) 3600.;
        const int totalWishedNum = (int)std::floor(myCurrentStateInterval->q * totalHourFraction + 0.5); // round to closest int
        int adaptedNum = passed() + myClearedInJam;
        if (!hadInvalidJam) {
            // only add vehicles if we do not have an invalid upstream jam to prevent spill-back
            const SUMOReal hourFraction = STEPS2TIME(currentTime - myCurrentStateInterval->begin + DELTA_T) / (SUMOReal) 3600.;
            const int wishedNum = (int)std::floor(myCurrentStateInterval->q * hourFraction + 0.5); // round to closest int
            // only the difference between inflow and aspiredFlow should be added, thus
            // we should not count vehicles vaporized from a jam here
            // if we have enough time left we can add missing vehicles later
            const int relaxedInsertion = (int)std::floor(STEPS2TIME(myCurrentStateInterval->end - currentTime) / 3);
            const int insertionSlack = MAX2(0, adaptedNum + relaxedInsertion - totalWishedNum);
            // increase number of vehicles
            //std::cout << "time:" << STEPS2TIME(currentTime) << " w:" << wishedNum << " s:" << insertionSlack << " before:" << adaptedNum;
            while (wishedNum > adaptedNum + insertionSlack && remainingVehicleCapacity() > maximumInflow()) {
                SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
                const MSRoute* route = myProbe != 0 ? myProbe->getRoute() : 0;
                if (route == 0) {
                    route = MSRoute::dictionary(pars->routeid);
                }
                if (route == 0) {
                    WRITE_WARNING("No valid routes in calibrator '" + myID + "'.");
                    break;
                }
                if (!route->contains(myEdge)) {
                    WRITE_WARNING("Route '" + route->getID() + "' in calibrator '" + myID + "' does not contain edge '" + myEdge->getID() + "'.");
                    break;
                }
                MSVehicleType* vtype = MSNet::getInstance()->getVehicleControl().getVType(pars->vtypeid);
                assert(route != 0 && vtype != 0);
                // build the vehicle
                const SUMOTime depart = mySegment->getNextInsertionTime(currentTime);
                SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
                newPars->id = myID + "." + toString(depart) + "." + toString(myInserted);
                newPars->depart = depart;
                newPars->routeid = route->getID();
                MEVehicle* vehicle = static_cast<MEVehicle*>(MSNet::getInstance()->getVehicleControl().buildVehicle(
                                         newPars, route, vtype, false, false));
                vehicle->setSegment(mySegment); // needed or vehicle will not be registered (XXX why?)
                vehicle->setEventTime(currentTime); // XXX superfluous?
                // move vehicle forward when the route does not begin at the calibrator's edge
                const MSEdge* myedge = &mySegment->getEdge();
                bool atDest = false;
                while (vehicle->getEdge() != myedge) {
                    // let the vehicle move to the next edge
                    atDest = vehicle->moveRoutePointer();
                }
                // insert vehicle into the net
                if (atDest || !tryEmit(mySegment, vehicle)) {
                    //std::cout << "F ";
                    MSNet::getInstance()->getVehicleControl().deleteVehicle(vehicle, true);
                    break;
                }
                //std::cout << "I ";
                myInserted++;
                adaptedNum++;
            }
        }
        //std::cout << " after:" << adaptedNum << "\n";
        // we only remove vehicles once we really have to
        while (totalWishedNum < adaptedNum) {
            if (!mySegment->vaporizeAnyCar(currentTime)) {
                // @bug: short edges may be jumped in a single step, giving us no chance to remove a vehicle
                break;
            }
            myRemoved++;
            adaptedNum--;
        }
    }
    if (myCurrentStateInterval->end <= currentTime + myFrequency) {
        writeXMLOutput();
    }
    assert(!invalidJam());
    return myFrequency;
}