void MSTLLogicControl::WAUTSwitchProcedure_Stretch::adaptLogic(SUMOTime step, SUMOReal position) { MSSimpleTrafficLightLogic *LogicTo = (MSSimpleTrafficLightLogic*) myTo; size_t cycleTime = LogicTo->getDefaultCycleTime(); // the position, in which the logic has to be switched unsigned int startPos = (unsigned int) position; // this is the position, where the Logic have to be after synchronisation size_t posAfterSyn = LogicTo->getPhaseIndexAtTime(step); // switch the toLogic to the startPosition // fehlt!!!! // erfolgt in cutLogic und/oder stretchLogic! // calculate the difference, that has to be equalized size_t deltaToCut = 0; if (posAfterSyn < startPos) { deltaToCut = posAfterSyn + cycleTime - startPos; } else deltaToCut = posAfterSyn - startPos; // test, wheter cutting of the Signalplan is possible size_t deltaPossible = 0; int noBereiche = getStretchBereicheNo(myTo); for (int i=0; i<noBereiche; i++) { StretchBereichDef def = getStretchBereichDef(myTo, i+1); assert(def.end >= def.begin) ; deltaPossible = deltaPossible + (size_t)(def.end - def.begin); } int stretchUmlaufAnz = (int) TplConvert<char>::_2SUMOReal(LogicTo->getParameterValue("StretchUmlaufAnz").c_str()); deltaPossible = stretchUmlaufAnz * deltaPossible; if ((deltaPossible > deltaToCut)&&(deltaToCut < (cycleTime / 2))) { cutLogic(step, startPos, deltaToCut); } else { size_t deltaToStretch = cycleTime - deltaToCut; if (deltaToStretch == cycleTime) { deltaToStretch = 0; } stretchLogic(step, startPos, deltaToStretch); } }
void MSTLLogicControl::WAUTSwitchProcedure_Stretch::stretchLogic(SUMOTime step, unsigned int startPos, size_t deltaToStretch) { MSSimpleTrafficLightLogic *LogicTo = (MSSimpleTrafficLightLogic*) myTo; unsigned int currPos = startPos; unsigned int currStep = LogicTo->getIndexFromOffset(currPos); unsigned int durOfPhase = LogicTo->getPhase(currStep).duration; size_t allStretchTime = deltaToStretch; size_t remainingStretchTime = allStretchTime; int StretchTimeOfPhase = 0; size_t stretchUmlaufAnz = (size_t) TplConvert<char>::_2SUMOReal(LogicTo->getParameterValue("StretchUmlaufAnz").c_str()); SUMOReal facSum = 0; int noBereiche = getStretchBereicheNo(myTo); int x; for (x=0; x<noBereiche; x++) { StretchBereichDef def = getStretchBereichDef(myTo, x+1); facSum += def.fac; } facSum *= stretchUmlaufAnz; //switch to startPos and stretch this phase, if there is a end of "bereich" between startpos and end of phase size_t diffToStart = getDiffToStartOfPhase(LogicTo, currPos); for (x=0; x<noBereiche; x++) { StretchBereichDef def = getStretchBereichDef(myTo, x+1); size_t end = (size_t) def.end; size_t endOfPhase = (size_t)(currPos + durOfPhase - diffToStart); if (end <= endOfPhase && end >= currPos) { SUMOReal fac = def.fac; SUMOReal actualfac = fac / facSum; facSum = facSum - fac; StretchTimeOfPhase = (int)((float)remainingStretchTime * actualfac + 0.5); remainingStretchTime = allStretchTime - StretchTimeOfPhase; } } durOfPhase = durOfPhase - diffToStart + StretchTimeOfPhase; myTo->changeStepAndDuration(myControl,step,currStep,durOfPhase); currStep ++; if (currStep >= LogicTo->getPhases().size()) { currStep = 0; } // stretch all other phases, if there is a "bereich" while (remainingStretchTime > 0) { for (unsigned int i=currStep; i<LogicTo->getPhases().size() && remainingStretchTime > 0; i++) { durOfPhase = LogicTo->getPhase(i).duration; size_t beginOfPhase = LogicTo->getOffsetFromIndex(i); size_t endOfPhase = beginOfPhase + durOfPhase; for (int j=0; j<noBereiche && remainingStretchTime > 0; j++) { StretchBereichDef def = getStretchBereichDef(myTo, j+1); size_t end = (size_t) def.end; SUMOReal fac = def.fac; if ((beginOfPhase <= end) && (endOfPhase >= end)) { SUMOReal actualfac = fac / facSum; StretchTimeOfPhase = (int)((float)remainingStretchTime * actualfac + 0.5) ; facSum -= fac; durOfPhase += StretchTimeOfPhase; remainingStretchTime -= StretchTimeOfPhase; } } LogicTo->addOverridingDuration(durOfPhase); } currStep = 0; } }