예제 #1
0
void
GUIVehicle::drawAction_drawLinkItems(const GUIVisualizationSettings& s) const {
    glTranslated(0, 0, getType() + .2); // draw on top of cars
    for (DriveItemVector::const_iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
        if ((*i).myLink == nullptr) {
            continue;
        }
        MSLink* link = (*i).myLink;
        MSLane* via = link->getViaLaneOrLane();
        if (via != nullptr) {
            Position p = via->getShape()[0];
            if ((*i).mySetRequest) {
                glColor3d(0, .8, 0);
            } else {
                glColor3d(.8, 0, 0);
            }
            const SUMOTime leaveTime = (*i).myLink->getLeaveTime(
                                           (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(), getVehicleType().getLength());
            drawLinkItem(p, (*i).myArrivalTime, leaveTime, s.vehicleName.size / s.scale);
            // the time slot that ego vehicle uses when checking opened may
            // differ from the one it requests in setApproaching
            MSLink::ApproachingVehicleInformation avi = (*i).myLink->getApproaching(this);
            assert(avi.arrivalTime == (*i).myArrivalTime && avi.leavingTime == leaveTime);
            UNUSED_PARAMETER(avi); // only used for assertion
        }
    }
    glTranslated(0, 0, getType() - .2); // draw on top of cars
}
예제 #2
0
// ===========================================================================
// method definitions
// ===========================================================================
GUIContainerStop::GUIContainerStop(const std::string& id, const std::vector<std::string>& lines, MSLane& lane,
                                   SUMOReal frompos, SUMOReal topos)
    : MSStoppingPlace(id, lines, lane, frompos, topos),
      GUIGlObject_AbstractAdd("containerStop", GLO_TRIGGER, id) {
    myFGShape = lane.getShape();
    myFGShape.move2side((SUMOReal) 1.65);
    myFGShape = myFGShape.getSubpart(frompos, topos);
    myFGShapeRotations.reserve(myFGShape.size() - 1);
    myFGShapeLengths.reserve(myFGShape.size() - 1);
    int e = (int) myFGShape.size() - 1;
    for (int i = 0; i < e; ++i) {
        const Position& f = myFGShape[i];
        const Position& s = myFGShape[i + 1];
        myFGShapeLengths.push_back(f.distanceTo(s));
        myFGShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI);
    }
    PositionVector tmp = myFGShape;
    tmp.move2side(1.5);
    myFGSignPos = tmp.getLineCenter();
    myFGSignRot = 0;
    if (tmp.length() != 0) {
        myFGSignRot = myFGShape.rotationDegreeAtOffset(SUMOReal((myFGShape.length() / 2.)));
        myFGSignRot -= 90;
    }
}
예제 #3
0
// ===========================================================================
// method definitions
// ===========================================================================
MSParkingArea::MSParkingArea(const std::string& id,
                             const std::vector<std::string>& lines,
                             MSLane& lane,
                             double begPos, double endPos,
                             unsigned int capacity,
                             double width, double length, double angle, const std::string& name) :
    MSStoppingPlace(id, lines, lane, begPos, endPos, name),
    myCapacity(capacity),
    myWidth(width),
    myLength(length),
    myAngle(angle) {
    // initialize unspecified defaults
    if (myWidth == 0) {
        myWidth = SUMO_const_laneWidth;
    }
    if (myLength == 0) {
        myLength = getSpaceDim();
    }

    const double offset = MSNet::getInstance()->lefthand() ? -1 : 1;
    myShape = lane.getShape().getSubpart(
                  lane.interpolateLanePosToGeometryPos(begPos),
                  lane.interpolateLanePosToGeometryPos(endPos));
    myShape.move2side((lane.getWidth() / 2. + myWidth / 2.) * offset);
    // Initialize space occupancies if there is a road-side capacity
    // The overall number of lots is fixed and each lot accepts one vehicle regardless of size
    if (myCapacity > 0) {
        for (int i = 1; i <= myCapacity; ++i) {
            mySpaceOccupancies[i] = LotSpaceDefinition();
            mySpaceOccupancies[i].index = i;
            mySpaceOccupancies[i].vehicle = 0;
            mySpaceOccupancies[i].myWidth = myWidth;
            mySpaceOccupancies[i].myLength = myLength;
            mySpaceOccupancies[i].myEndPos = myBegPos + getSpaceDim() * i;

            const Position& f = myShape.positionAtOffset(getSpaceDim() * (i - 1));
            const Position& s = myShape.positionAtOffset(getSpaceDim() * (i));
            double lot_angle = ((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI) + myAngle;
            mySpaceOccupancies[i].myRotation = lot_angle;
            if (myAngle == 0) {
                // parking parallel to the road
                mySpaceOccupancies[i].myPosition = s;
            } else {
                // angled parking
                mySpaceOccupancies[i].myPosition = (f + s) * 0.5;
            }

        }
    }
    computeLastFreePos();
}
예제 #4
0
Position2D
NLGeomShapeBuilder::getPointPosition(SUMOReal x, SUMOReal y,
                                     const std::string &laneID,
                                     SUMOReal posOnLane) const throw(InvalidArgument) {
    if (x!=INVALID_POSITION&&y!=INVALID_POSITION) {
        return Position2D(x,y);
    }
    MSLane *lane = MSLane::dictionary(laneID);
    if (lane==0) {
        throw InvalidArgument("Lane '" + laneID + "' to place a poi on is not known.");
    }
    if (posOnLane<0) {
        posOnLane = lane->getLength() + posOnLane;
    }
    return lane->getShape().positionAtLengthPosition(posOnLane);
}
예제 #5
0
// ===========================================================================
// method definitions
// ===========================================================================
GUIChargingStation::GUIChargingStation(const std::string& id, MSLane& lane, SUMOReal frompos, SUMOReal topos,  SUMOReal chargingPower, SUMOReal efficiency, bool chargeInTransit, int chargeDelay) :
    MSChargingStation(id, lane, frompos, topos, chargingPower, efficiency, chargeInTransit, chargeDelay),
    GUIGlObject_AbstractAdd("chargingStation", GLO_TRIGGER, id) {
    myFGShape = lane.getShape();
    myFGShape = myFGShape.getSubpart(frompos, topos);
    myFGShapeRotations.reserve(myFGShape.size() - 1);
    myFGShapeLengths.reserve(myFGShape.size() - 1);
    int e = (int) myFGShape.size() - 1;
    for (int i = 0; i < e; ++i) {
        const Position& f = myFGShape[i];
        const Position& s = myFGShape[i + 1];
        myFGShapeLengths.push_back(f.distanceTo(s));
        myFGShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI);
    }
    PositionVector tmp = myFGShape;
    tmp.move2side(1.5);
    myFGSignPos = tmp.getLineCenter();
    myFGSignRot = 0;
    if (tmp.length() != 0) {
        myFGSignRot = myFGShape.rotationDegreeAtOffset(SUMOReal((myFGShape.length() / 2.)));
        myFGSignRot -= 90;
    }
}
예제 #6
0
void
NLHandler::addConnection(const SUMOSAXAttributes& attrs) {
    bool ok = true;
    std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
    if (!MSGlobals::gUsingInternalLanes && fromID[0] == ':') {
        return;
    }

    try {
        bool ok = true;
        const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
        const int fromLaneIdx = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok);
        const int toLaneIdx = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok);
        LinkDirection dir = parseLinkDir(attrs.get<std::string>(SUMO_ATTR_DIR, 0, ok));
        LinkState state = parseLinkState(attrs.get<std::string>(SUMO_ATTR_STATE, 0, ok));
        std::string tlID = attrs.getOpt<std::string>(SUMO_ATTR_TLID, 0, ok, "");
#ifdef HAVE_INTERNAL_LANES
        std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, 0, ok, "");
#endif

        MSEdge* from = MSEdge::dictionary(fromID);
        if (from == 0) {
            WRITE_ERROR("Unknown from-edge '" + fromID + "' in connection");
            return;
        }
        MSEdge* to = MSEdge::dictionary(toID);
        if (to == 0) {
            WRITE_ERROR("Unknown to-edge '" + toID + "' in connection");
            return;
        }
        if (fromLaneIdx < 0 || static_cast<unsigned int>(fromLaneIdx) >= from->getLanes().size() ||
                toLaneIdx < 0 || static_cast<unsigned int>(toLaneIdx) >= to->getLanes().size()) {
            WRITE_ERROR("Invalid lane index in connection from '" + from->getID() + "' to '" + to->getID() + "'.");
            return;
        }
        MSLane* fromLane = from->getLanes()[fromLaneIdx];
        MSLane* toLane = to->getLanes()[toLaneIdx];
        assert(fromLane);
        assert(toLane);

        int tlLinkIdx = -1;
        if (tlID != "") {
            tlLinkIdx = attrs.get<int>(SUMO_ATTR_TLLINKINDEX, 0, ok);
            // make sure that the index is in range
            MSTrafficLightLogic* logic = myJunctionControlBuilder.getTLLogic(tlID).getActive();
            if (tlLinkIdx < 0 || tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size()) {
                WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
                            "' in connection controlled by '" + tlID + "'");
                return;
            }
            if (!ok) {
                return;
            }
        }
        SUMOReal length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
        MSLink* link = 0;

        // build the link
#ifdef HAVE_INTERNAL_LANES
        MSLane* via = 0;
        if (viaID != "" && MSGlobals::gUsingInternalLanes) {
            via = MSLane::dictionary(viaID);
            if (via == 0) {
                WRITE_ERROR("An unknown lane ('" + viaID +
                            "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
                return;
            }
            length = via->getLength();
        }
        link = new MSLink(toLane, via, dir, state, length);
        if (via != 0) {
            via->addIncomingLane(fromLane, link);
        } else {
            toLane->addIncomingLane(fromLane, link);
        }
#else
        link = new MSLink(toLane, dir, state, length);
        toLane->addIncomingLane(fromLane, link);
#endif
        toLane->addApproachingLane(fromLane);

        // if a traffic light is responsible for it, inform the traffic light
        // check whether this link is controlled by a traffic light
        if (tlID != "") {
            myJunctionControlBuilder.getTLLogic(tlID).addLink(link, fromLane, tlLinkIdx);
        }
        // add the link
        fromLane->addLink(link);

    } catch (InvalidArgument& e) {
        WRITE_ERROR(e.what());
    }
}
// ===========================================================================
// method definitions
// ===========================================================================
bool
TraCIServerAPI_Lane::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
                                tcpip::Storage& outputStorage) {
    // variable
    int variable = inputStorage.readUnsignedByte();
    std::string id = inputStorage.readString();
    // check variable
    if (variable != ID_LIST && variable != LANE_LINK_NUMBER && variable != LANE_EDGE_ID && variable != VAR_LENGTH
            && variable != VAR_MAXSPEED && variable != LANE_LINKS && variable != VAR_SHAPE
            && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
            && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION && variable != VAR_WAITING_TIME
            && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_VEHICLE_NUMBER
            && variable != LAST_STEP_VEHICLE_ID_LIST && variable != LAST_STEP_OCCUPANCY && variable != LAST_STEP_VEHICLE_HALTING_NUMBER
            && variable != LAST_STEP_LENGTH && variable != VAR_CURRENT_TRAVELTIME
            && variable != LANE_ALLOWED && variable != LANE_DISALLOWED && variable != VAR_WIDTH && variable != ID_COUNT
       ) {
        return server.writeErrorStatusCmd(CMD_GET_LANE_VARIABLE, "Get Lane Variable: unsupported variable specified", outputStorage);
    }
    // begin response building
    tcpip::Storage tempMsg;
    //  response-code, variableID, objectID
    tempMsg.writeUnsignedByte(RESPONSE_GET_LANE_VARIABLE);
    tempMsg.writeUnsignedByte(variable);
    tempMsg.writeString(id);
    if (variable == ID_LIST) {
        std::vector<std::string> ids;
        MSLane::insertIDs(ids);
        tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
        tempMsg.writeStringList(ids);
    } else if (variable == ID_COUNT) {
        std::vector<std::string> ids;
        MSLane::insertIDs(ids);
        tempMsg.writeUnsignedByte(TYPE_INTEGER);
        tempMsg.writeInt((int) ids.size());
    } else {
        MSLane* lane = MSLane::dictionary(id);
        if (lane == 0) {
            return server.writeErrorStatusCmd(CMD_GET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage);
        }
        switch (variable) {
            case LANE_LINK_NUMBER:
                tempMsg.writeUnsignedByte(TYPE_UBYTE);
                tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
                break;
            case LANE_EDGE_ID:
                tempMsg.writeUnsignedByte(TYPE_STRING);
                tempMsg.writeString(lane->getEdge().getID());
                break;
            case VAR_LENGTH:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getLength());
                break;
            case VAR_MAXSPEED:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getSpeedLimit());
                break;
            case LANE_LINKS: {
                tempMsg.writeUnsignedByte(TYPE_COMPOUND);
                tcpip::Storage tempContent;
                unsigned int cnt = 0;
                tempContent.writeUnsignedByte(TYPE_INTEGER);
                const MSLinkCont& links = lane->getLinkCont();
                tempContent.writeInt((int) links.size());
                ++cnt;
                const SUMOTime currTime = MSNet::getInstance()->getCurrentTimeStep();
                for (MSLinkCont::const_iterator i = links.begin(); i != links.end(); ++i) {
                    MSLink* link = (*i);
                    // approached non-internal lane (if any)
                    tempContent.writeUnsignedByte(TYPE_STRING);
                    tempContent.writeString(link->getLane() != 0 ? link->getLane()->getID() : "");
                    ++cnt;
                    // approached "via", internal lane (if any)
                    tempContent.writeUnsignedByte(TYPE_STRING);
#ifdef HAVE_INTERNAL_LANES
                    tempContent.writeString(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
#else
                    tempContent.writeString("");
#endif
                    ++cnt;
                    // priority
                    tempContent.writeUnsignedByte(TYPE_UBYTE);
                    tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
                    ++cnt;
                    // opened
                    tempContent.writeUnsignedByte(TYPE_UBYTE);
                    const SUMOReal speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
                    tempContent.writeUnsignedByte(link->opened(currTime, speed, speed, DEFAULT_VEH_LENGTH, 0.0, DEFAULT_VEH_DECEL, 0) ? 1 : 0);
                    ++cnt;
                    // approaching foe
                    tempContent.writeUnsignedByte(TYPE_UBYTE);
                    tempContent.writeUnsignedByte(link->hasApproachingFoe(currTime, currTime, 0) ? 1 : 0);
                    ++cnt;
                    // state (not implemented, yet)
                    tempContent.writeUnsignedByte(TYPE_STRING);
                    tempContent.writeString(SUMOXMLDefinitions::LinkStates.getString(link->getState()));
                    ++cnt;
                    // direction
                    tempContent.writeUnsignedByte(TYPE_STRING);
                    tempContent.writeString(SUMOXMLDefinitions::LinkDirections.getString(link->getDirection()));
                    ++cnt;
                    // length
                    tempContent.writeUnsignedByte(TYPE_DOUBLE);
                    tempContent.writeDouble(link->getLength());
                    ++cnt;
                }
                tempMsg.writeInt((int) cnt);
                tempMsg.writeStorage(tempContent);
            }
            break;
            case LANE_ALLOWED: {
                tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
                SVCPermissions permissions = lane->getPermissions();
                if (permissions == SVCFreeForAll) {  // special case: write nothing
                    permissions = 0;
                }
                tempMsg.writeStringList(getAllowedVehicleClassNamesList(permissions));
            }
            case LANE_DISALLOWED: {
                tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
                tempMsg.writeStringList(getAllowedVehicleClassNamesList(~(lane->getPermissions()))); // negation yields disallowed
            }
            break;
            case VAR_SHAPE:
                tempMsg.writeUnsignedByte(TYPE_POLYGON);
                tempMsg.writeUnsignedByte((int)MIN2(static_cast<size_t>(255), lane->getShape().size()));
                for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), lane->getShape().size()); ++iPoint) {
                    tempMsg.writeDouble(lane->getShape()[iPoint].x());
                    tempMsg.writeDouble(lane->getShape()[iPoint].y());
                }
                break;
            case VAR_CO2EMISSION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getCO2Emissions());
                break;
            case VAR_COEMISSION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getCOEmissions());
                break;
            case VAR_HCEMISSION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getHCEmissions());
                break;
            case VAR_PMXEMISSION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getPMxEmissions());
                break;
            case VAR_NOXEMISSION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getNOxEmissions());
                break;
            case VAR_FUELCONSUMPTION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getFuelConsumption());
                break;
            case VAR_NOISEEMISSION:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getHarmonoise_NoiseEmissions());
                break;
            case LAST_STEP_VEHICLE_NUMBER:
                tempMsg.writeUnsignedByte(TYPE_INTEGER);
                tempMsg.writeInt((int) lane->getVehicleNumber());
                break;
            case LAST_STEP_MEAN_SPEED:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getMeanSpeed());
                break;
            case LAST_STEP_VEHICLE_ID_LIST: {
                std::vector<std::string> vehIDs;
                const MSLane::VehCont& vehs = lane->getVehiclesSecure();
                for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
                    vehIDs.push_back((*j)->getID());
                }
                lane->releaseVehicles();
                tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
                tempMsg.writeStringList(vehIDs);
            }
            break;
            case LAST_STEP_OCCUPANCY:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getNettoOccupancy());
                break;
            case LAST_STEP_VEHICLE_HALTING_NUMBER: {
                int halting = 0;
                const MSLane::VehCont& vehs = lane->getVehiclesSecure();
                for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
                    if ((*j)->getSpeed() < SUMO_const_haltingSpeed) {
                        ++halting;
                    }
                }
                lane->releaseVehicles();
                tempMsg.writeUnsignedByte(TYPE_INTEGER);
                tempMsg.writeInt(halting);
            }
            break;
            case LAST_STEP_LENGTH: {
                SUMOReal lengthSum = 0;
                const MSLane::VehCont& vehs = lane->getVehiclesSecure();
                for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
                    lengthSum += (*j)->getVehicleType().getLength();
                }
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                if (vehs.size() == 0) {
                    tempMsg.writeDouble(0);
                } else {
                    tempMsg.writeDouble(lengthSum / (SUMOReal) vehs.size());
                }
                lane->releaseVehicles();
            }
            break;
            case VAR_WAITING_TIME: {
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getWaitingSeconds());
            }
            break;
            case VAR_CURRENT_TRAVELTIME: {
                SUMOReal meanSpeed = lane->getMeanSpeed();
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                if (meanSpeed != 0) {
                    tempMsg.writeDouble(lane->getLength() / meanSpeed);
                } else {
                    tempMsg.writeDouble(1000000.);
                }
            }
            break;
            case VAR_WIDTH:
                tempMsg.writeUnsignedByte(TYPE_DOUBLE);
                tempMsg.writeDouble(lane->getWidth());
                break;
            default:
                break;
        }
    }
    server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, "", outputStorage);
    server.writeResponseWithLength(outputStorage, tempMsg);
    return true;
}
예제 #8
0
void
Person::moveToXY(const std::string& personID, const std::string& edgeID, const double x, const double y, double angle, const int keepRouteFlag) {
    MSPerson* p = getPerson(personID);
    bool keepRoute = (keepRouteFlag == 1);
    bool mayLeaveNetwork = (keepRouteFlag == 2);
    Position pos(x, y);
#ifdef DEBUG_MOVEXY
    const double origAngle = angle;
#endif
    // angle must be in [0,360] because it will be compared against those returned by naviDegree()
    // angle set to INVALID_DOUBLE_VALUE is ignored in the evaluated and later set to the angle of the matched lane
    if (angle != INVALID_DOUBLE_VALUE) {
        while (angle >= 360.) {
            angle -= 360.;
        }
        while (angle < 0.) {
            angle += 360.;
        }
    }
    Position currentPos = p->getPosition();
#ifdef DEBUG_MOVEXY
    std::cout << std::endl << "begin person " << p->getID() << " lanePos:" << p->getEdgePos() << " edge:" << Named::getIDSecure(p->getEdge()) << "\n";
    std::cout << " want pos:" << pos << " edgeID:" << edgeID <<  " origAngle:" << origAngle << " angle:" << angle << " keepRoute:" << keepRoute << std::endl;
#endif

    ConstMSEdgeVector edges;
    MSLane* lane = nullptr;
    double lanePos;
    double lanePosLat = 0;
    double bestDistance = std::numeric_limits<double>::max();
    int routeOffset = 0;
    bool found = false;
    double maxRouteDistance = 100;

    ConstMSEdgeVector ev;
    ev.push_back(p->getEdge());
    int routeIndex = 0;
    MSLane* currentLane = const_cast<MSLane*>(getSidewalk<MSEdge, MSLane>(p->getEdge()));
    switch (p->getStageType(0)) {
        case MSTransportable::MOVING_WITHOUT_VEHICLE: {
            MSPerson::MSPersonStage_Walking* s = dynamic_cast<MSPerson::MSPersonStage_Walking*>(p->getCurrentStage());
            assert(s != 0);
            ev = s->getEdges();
            routeIndex = (int)(s->getRouteStep() - s->getRoute().begin());
        }
        break;
        default:
            break;
    }
    if (keepRoute) {
        // case a): vehicle is on its earlier route
        //  we additionally assume it is moving forward (SUMO-limit);
        //  note that the route ("edges") is not changed in this case
        found = Helper::moveToXYMap_matchingRoutePosition(pos, edgeID,
                ev, routeIndex,
                bestDistance, &lane, lanePos, routeOffset);
    } else {
        double speed = pos.distanceTo2D(p->getPosition()); // !!!veh->getSpeed();
        found = Helper::moveToXYMap(pos, maxRouteDistance, mayLeaveNetwork, edgeID, angle,
                                    speed, ev, routeIndex, currentLane, p->getEdgePos(), true,
                                    bestDistance, &lane, lanePos, routeOffset, edges);
    }
    if ((found && bestDistance <= maxRouteDistance) || mayLeaveNetwork) {
        // compute lateral offset
        if (found) {
            const double perpDist = lane->getShape().distance2D(pos, false);
            if (perpDist != GeomHelper::INVALID_OFFSET) {
                lanePosLat = perpDist;
                if (!mayLeaveNetwork) {
                    lanePosLat = MIN2(lanePosLat, 0.5 * (lane->getWidth() + p->getVehicleType().getWidth()));
                }
                // figure out whether the offset is to the left or to the right
                PositionVector tmp = lane->getShape();
                try {
                    tmp.move2side(-lanePosLat); // moved to left
                } catch (ProcessError&) {
                    WRITE_WARNING("Could not determine position on lane '" + lane->getID() + " at lateral position " + toString(-lanePosLat) + ".");
                }
                //std::cout << " lane=" << lane->getID() << " posLat=" << lanePosLat << " shape=" << lane->getShape() << " tmp=" << tmp << " tmpDist=" << tmp.distance2D(pos) << "\n";
                if (tmp.distance2D(pos) > perpDist) {
                    lanePosLat = -lanePosLat;
                }
            }
        }
        if (found && !mayLeaveNetwork && MSGlobals::gLateralResolution < 0) {
            // mapped position may differ from pos
            pos = lane->geometryPositionAtOffset(lanePos, -lanePosLat);
        }
        assert((found && lane != 0) || (!found && lane == 0));
        if (angle == INVALID_DOUBLE_VALUE) {
            if (lane != nullptr) {
                angle = GeomHelper::naviDegree(lane->getShape().rotationAtOffset(lanePos));
            } else {
                // compute angle outside road network from old and new position
                angle = GeomHelper::naviDegree(p->getPosition().angleTo2D(pos));
            }
        }
        switch (p->getStageType(0)) {
            case MSTransportable::MOVING_WITHOUT_VEHICLE: {
                Helper::setRemoteControlled(p, pos, lane, lanePos, lanePosLat, angle, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
                break;
            }
            default:
                throw TraCIException("Command moveToXY is not supported for person '" + personID + "' while " + p->getCurrentStageDescription() + ".");
        }
    } else {
        if (lane == nullptr) {
            throw TraCIException("Could not map person '" + personID + "' no road found within " + toString(maxRouteDistance) + "m.");
        } else {
            throw TraCIException("Could not map person '" + personID + "' distance to road is " + toString(bestDistance) + ".");
        }
    }
}
void
NLSucceedingLaneBuilder::addSuccLane(bool yield, const std::string &laneId,
#ifdef HAVE_INTERNAL_LANES
                                     const std::string &viaID,
                                     SUMOReal pass,
#endif
                                     MSLink::LinkDirection dir,
                                     MSLink::LinkState state,
                                     bool internalEnd,
                                     const std::string &tlid, unsigned int linkNo) throw(InvalidArgument) {
    // check whether the link is a dead link
    if (laneId=="SUMO_NO_DESTINATION") {
        // build the dead link and add it to the container
#ifdef HAVE_INTERNAL_LANES
        MSLink *link = new MSLink(0, 0, yield, MSLink::LINKDIR_NODIR, MSLink::LINKSTATE_DEADEND, false, 0.);
#else
        MSLink *link = new MSLink(0, yield, MSLink::LINKDIR_NODIR, MSLink::LINKSTATE_DEADEND, 0.);
#endif
        mySuccLanes->push_back(link);
        if (tlid!="") {
            MSTLLogicControl::TLSLogicVariants &logics = myJunctionControlBuilder.getTLLogic(tlid);
            MSLane *current = MSLane::dictionary(myCurrentLane);
            if (current==0) {
                throw InvalidArgument("An unknown lane ('" + myCurrentLane + "') should be assigned to a tl-logic.");
            }
            logics.addLink(link, current, linkNo);
        }
        return;
    }

    // get the lane the link belongs to
    MSLane *lane = MSLane::dictionary(laneId);
    if (lane==0) {
        throw InvalidArgument("An unknown lane ('" + laneId + "') should be set as a follower for lane '" + myCurrentLane + "'.");
    }
#ifdef HAVE_INTERNAL_LANES
    MSLane *via = 0;
    if (viaID!="" && MSGlobals::gUsingInternalLanes) {
        via = MSLane::dictionary(viaID);
        if (via==0) {
            throw InvalidArgument("An unknown lane ('" + viaID + "') should be set as a via-lane for lane '" + myCurrentLane + "'.");
        }
    }
    if (pass>=0) {
        static_cast<MSInternalLane*>(lane)->setPassPosition(pass);
    }
#endif
    MSLane *orig = MSLane::dictionary(myCurrentLane);
    if (orig==0) {
        return;
    }


    // build the link
    SUMOReal length = orig!=0&&lane!=0
                      ? orig->getShape()[-1].distanceTo(lane->getShape()[0])
                      : 0;
#ifdef HAVE_INTERNAL_LANES
    if (via!=0) {
        length = via->getLength();
    }
    MSLink *link = new MSLink(lane, via, yield, dir, state, internalEnd, length);
#else
    MSLink *link = new MSLink(lane, yield, dir, state, length);
#endif

    if (MSLane::dictionary(myCurrentLane)!=0) {
#ifdef HAVE_INTERNAL_LANES
        if (via!=0) {
            // from a normal in to a normal out via
            //  --> via incomes in out
            lane->addIncomingLane(via, link);
            //  --> in incomes in via
            via->addIncomingLane(MSLane::dictionary(myCurrentLane), link);
        } else {
            if (myCurrentLane[0]!=':') {
                // internal not wished; other case already set
                lane->addIncomingLane(MSLane::dictionary(myCurrentLane), link);
            }
        }
#else
        lane->addIncomingLane(MSLane::dictionary(myCurrentLane), link);
#endif
    }
    // if a traffic light is responsible for it, inform the traffic light
    // check whether this link is controlled by a traffic light
    if (tlid!="") {
        MSTLLogicControl::TLSLogicVariants &logics = myJunctionControlBuilder.getTLLogic(tlid);
        MSLane *current = MSLane::dictionary(myCurrentLane);
        if (current==0) {
            throw InvalidArgument("An unknown lane ('" + myCurrentLane + "') should be assigned to a tl-logic.");
        }
        logics.addLink(link, current, linkNo);
    }
    // add the link to the container
    mySuccLanes->push_back(link);
}
예제 #10
0
// ===========================================================================
// method definitions
// ===========================================================================
bool
TraCIServerAPI_Lane::processGet(TraCIServer &server, tcpip::Storage &inputStorage,
                                tcpip::Storage &outputStorage) {
    Storage tmpResult;
    std::string warning = "";	// additional description for response
    // variable
    int variable = inputStorage.readUnsignedByte();
    std::string id = inputStorage.readString();
    // check variable
    if (variable!=ID_LIST&&variable!=LANE_LINK_NUMBER&&variable!=LANE_EDGE_ID&&variable!=VAR_LENGTH
            &&variable!=VAR_MAXSPEED&&variable!=LANE_LINKS&&variable!=VAR_SHAPE
            &&variable!=VAR_CO2EMISSION&&variable!=VAR_COEMISSION&&variable!=VAR_HCEMISSION&&variable!=VAR_PMXEMISSION
            &&variable!=VAR_NOXEMISSION&&variable!=VAR_FUELCONSUMPTION&&variable!=VAR_NOISEEMISSION
            &&variable!=LAST_STEP_MEAN_SPEED&&variable!=LAST_STEP_VEHICLE_NUMBER
            &&variable!=LAST_STEP_VEHICLE_ID_LIST&&variable!=LAST_STEP_OCCUPANCY&&variable!=LAST_STEP_VEHICLE_HALTING_NUMBER
            &&variable!=LAST_STEP_LENGTH&&variable!=VAR_CURRENT_TRAVELTIME
            &&variable!=LANE_ALLOWED&&variable!=LANE_DISALLOWED) {
        server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Get Lane Variable: unsupported variable specified", outputStorage);
        return false;
    }
    // begin response building
    Storage tempMsg;
    //  response-code, variableID, objectID
    tempMsg.writeUnsignedByte(RESPONSE_GET_LANE_VARIABLE);
    tempMsg.writeUnsignedByte(variable);
    tempMsg.writeString(id);
    if (variable==ID_LIST) {
        std::vector<std::string> ids;
        MSLane::insertIDs(ids);
        tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
        tempMsg.writeStringList(ids);
    } else {
        MSLane *lane = MSLane::dictionary(id);
        if (lane==0) {
            server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
            return false;
        }
        switch (variable) {
        case LANE_LINK_NUMBER:
            tempMsg.writeUnsignedByte(TYPE_UBYTE);
            tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
            break;
        case LANE_EDGE_ID:
            tempMsg.writeUnsignedByte(TYPE_STRING);
            tempMsg.writeString(lane->getEdge().getID());
            break;
        case VAR_LENGTH:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getLength());
            break;
        case VAR_MAXSPEED:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getMaxSpeed());
            break;
        case LANE_LINKS: {
            tempMsg.writeUnsignedByte(TYPE_COMPOUND);
            Storage tempContent;
            unsigned int cnt = 0;
            tempContent.writeUnsignedByte(TYPE_INTEGER);
            const MSLinkCont &links = lane->getLinkCont();
            tempContent.writeInt((int) links.size());
            ++cnt;
            for (MSLinkCont::const_iterator i=links.begin(); i!=links.end(); ++i) {
                MSLink *link = (*i);
                // approached non-internal lane (if any)
                tempContent.writeUnsignedByte(TYPE_STRING);
                tempContent.writeString(link->getLane()!=0 ? link->getLane()->getID() : "");
                ++cnt;
                // approached "via", internal lane (if any)
                tempContent.writeUnsignedByte(TYPE_STRING);
#ifdef HAVE_INTERNAL_LANES
                tempContent.writeString(link->getViaLane()!=0 ? link->getViaLane()->getID() : "");
#else
                tempContent.writeString("");
#endif
                ++cnt;
                // priority
                tempContent.writeUnsignedByte(TYPE_UBYTE);
                tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
                ++cnt;
                // opened
                tempContent.writeUnsignedByte(TYPE_UBYTE);
                tempContent.writeUnsignedByte(link->opened(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getCurrentTimeStep(), 0.) ? 1 : 0);
                ++cnt;
                // approaching foe
                tempContent.writeUnsignedByte(TYPE_UBYTE);
                tempContent.writeUnsignedByte(link->hasApproachingFoe(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getCurrentTimeStep()) ? 1 : 0);
                ++cnt;
                // state (not implemented, yet)
                tempContent.writeUnsignedByte(TYPE_STRING);
                tempContent.writeString("");
                ++cnt;
                // direction (not implemented, yet)
                tempContent.writeUnsignedByte(TYPE_STRING);
                tempContent.writeString("");
                ++cnt;
                // length
                tempContent.writeUnsignedByte(TYPE_FLOAT);
                tempContent.writeFloat(link->getLength());
                ++cnt;
            }
            tempMsg.writeInt((int) cnt);
            tempMsg.writeStorage(tempContent);
        }
        break;
        case LANE_ALLOWED: {
            const std::vector<SUMOVehicleClass> &allowed = lane->getAllowedClasses();
            std::vector<std::string> allowedS;
            for (std::vector<SUMOVehicleClass>::const_iterator i=allowed.begin(); i!=allowed.end(); ++i) {
                allowedS.push_back(getVehicleClassName(*i));
            }
            tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
            tempMsg.writeStringList(allowedS);
        }
        case LANE_DISALLOWED: {
            const std::vector<SUMOVehicleClass> &disallowed = lane->getNotAllowedClasses();
            std::vector<std::string> disallowedS;
            for (std::vector<SUMOVehicleClass>::const_iterator i=disallowed.begin(); i!=disallowed.end(); ++i) {
                disallowedS.push_back(getVehicleClassName(*i));
            }
            tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
            tempMsg.writeStringList(disallowedS);
        }
        break;
        case VAR_SHAPE:
            tempMsg.writeUnsignedByte(TYPE_POLYGON);
            tempMsg.writeUnsignedByte(MIN2(static_cast<size_t>(255),lane->getShape().size()));
            for (int iPoint=0; iPoint < MIN2(static_cast<size_t>(255),lane->getShape().size()); ++iPoint) {
                tempMsg.writeFloat(lane->getShape()[iPoint].x());
                tempMsg.writeFloat(lane->getShape()[iPoint].y());
            }
            break;
        case VAR_CO2EMISSION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHBEFA_CO2Emissions());
            break;
        case VAR_COEMISSION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHBEFA_COEmissions());
            break;
        case VAR_HCEMISSION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHBEFA_HCEmissions());
            break;
        case VAR_PMXEMISSION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHBEFA_PMxEmissions());
            break;
        case VAR_NOXEMISSION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHBEFA_NOxEmissions());
            break;
        case VAR_FUELCONSUMPTION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHBEFA_FuelConsumption());
            break;
        case VAR_NOISEEMISSION:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getHarmonoise_NoiseEmissions());
            break;
        case LAST_STEP_VEHICLE_NUMBER:
            tempMsg.writeUnsignedByte(TYPE_INTEGER);
            tempMsg.writeInt((int) lane->getVehicleNumber());
            break;
        case LAST_STEP_MEAN_SPEED:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getMeanSpeed());
            break;
        case LAST_STEP_VEHICLE_ID_LIST: {
            std::vector<std::string> vehIDs;
            const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
            for (std::deque<MSVehicle*>::const_iterator j=vehs.begin(); j!=vehs.end(); ++j) {
                vehIDs.push_back((*j)->getID());
            }
            lane->releaseVehicles();
            tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
            tempMsg.writeStringList(vehIDs);
        }
        break;
        case LAST_STEP_OCCUPANCY:
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            tempMsg.writeFloat(lane->getOccupancy());
            break;
        case LAST_STEP_VEHICLE_HALTING_NUMBER: {
            int halting = 0;
            const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
            for (std::deque<MSVehicle*>::const_iterator j=vehs.begin(); j!=vehs.end(); ++j) {
                if ((*j)->getSpeed()<0.1) {
                    ++halting;
                }
            }
            lane->releaseVehicles();
            tempMsg.writeUnsignedByte(TYPE_INTEGER);
            tempMsg.writeInt(halting);
        }
        break;
        case LAST_STEP_LENGTH: {
            SUMOReal lengthSum = 0;
            const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
            for (std::deque<MSVehicle*>::const_iterator j=vehs.begin(); j!=vehs.end(); ++j) {
                lengthSum += (*j)->getVehicleType().getLength();
            }
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            if (vehs.size()==0) {
                tempMsg.writeFloat(0);
            } else {
                tempMsg.writeFloat(lengthSum / (SUMOReal) vehs.size());
            }
            lane->releaseVehicles();
        }
        break;
        case VAR_CURRENT_TRAVELTIME: {
            SUMOReal meanSpeed = lane->getMeanSpeed();
            tempMsg.writeUnsignedByte(TYPE_FLOAT);
            if (meanSpeed!=0) {
                tempMsg.writeFloat(lane->getLength() / meanSpeed);
            } else {
                tempMsg.writeFloat(1000000.);
            }
        }
        break;
        default:
            break;
        }
    }
    server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
    // send response
    outputStorage.writeUnsignedByte(0); // command length -> extended
    outputStorage.writeInt(1 + 4 + tempMsg.size());
    outputStorage.writeStorage(tempMsg);
    return true;
}