void MSTrafficLightLogic::init(NLDetectorBuilder&) { const Phases& phases = getPhases(); if (phases.size() > 1) { bool haveWarnedAboutUnusedStates = false; // warn about transistions from green to red without intermediate yellow for (int i = 0; i < (int)phases.size(); ++i) { const int iNext = (i + 1) % phases.size(); const std::string& state1 = phases[i]->getState(); const std::string& state2 = phases[iNext]->getState(); assert(state1.size() == state2.size()); if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size()) { WRITE_WARNING("Unused states in tlLogic '" + getID() + "', program '" + getProgramID() + "' in phase " + toString(i) + " after tl-index " + toString((int)myLanes.size() - 1)); haveWarnedAboutUnusedStates = true; } for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()); ++j) { if ((LinkState)state2[j] == LINKSTATE_TL_RED && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) { for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) { if ((*it)->getPermissions() != SVC_PEDESTRIAN) { WRITE_WARNING("Missing yellow phase in tlLogic '" + getID() + "', program '" + getProgramID() + "' for tl-index " + toString(j) + " when switching to phase " + toString(iNext)); return; // one warning per program is enough } } } } } } }
bool ShaderProgram::attachShaderToProgram(Shader * shader) { if(programID == 0) { printf("============================================\n"); printf("ATTACHING SHADER TO PROGRAM...\n"); printf("ERROR: SHADER PROGRAM NOT CREATED YET.\n"); printf("NAME: %2s\n", getName()); printf("============================================\n"); return false; } else if(!shader->isLoaded()) { printf("============================================\n"); printf("ATTACHING SHADER TO PROGRAM...\n"); printf("ERROR: SHADER NOT LOADED.\n"); printf("NAME: %2s\n", getName()); printf("============================================\n"); return false; } else { printf("============================================\n"); printf("ATTACHING SHADER TO PROGRAM...\n"); glAttachShader(programID, shader->getShaderID() ); printf("==========\n"); printf("ID: %2d\n", getProgramID()); printf("NAME: %2s\n", getName()); printf("==========\n"); printf("SHADER ID: %2d\n", shader->getShaderID()); printf("TYPE: %2s\n", shader->getShaderType()); printf("============================================\n"); return true; } }
bool OpenGLShaderProgram::addShader (const String& code, GLenum type) { GLuint shaderID = context.extensions.glCreateShader (type); const GLchar* c = code.toRawUTF8(); context.extensions.glShaderSource (shaderID, 1, &c, nullptr); context.extensions.glCompileShader (shaderID); GLint status = GL_FALSE; context.extensions.glGetShaderiv (shaderID, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLchar infoLog [16384]; GLsizei infoLogLength = 0; context.extensions.glGetShaderInfoLog (shaderID, sizeof (infoLog), &infoLogLength, infoLog); errorLog = String (infoLog, (size_t) infoLogLength); #if JUCE_DEBUG && ! JUCE_DONT_ASSERT_ON_GLSL_COMPILE_ERROR // Your GLSL code contained compile errors! // Hopefully this compile log should help to explain what went wrong. DBG (errorLog); jassertfalse; #endif return false; } context.extensions.glAttachShader (getProgramID(), shaderID); context.extensions.glDeleteShader (shaderID); JUCE_CHECK_OPENGL_ERROR return true; }
bool OpenGLShaderProgram::link() noexcept { // This method can only be used when the current thread has an active OpenGL context. jassert (OpenGLHelpers::isContextActive()); GLuint progID = getProgramID(); context.extensions.glLinkProgram (progID); GLint status = GL_FALSE; context.extensions.glGetProgramiv (progID, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLchar infoLog [16384]; GLsizei infoLogLength = 0; context.extensions.glGetProgramInfoLog (progID, sizeof (infoLog), &infoLogLength, infoLog); errorLog = String (infoLog, (size_t) infoLogLength); #if JUCE_DEBUG && ! JUCE_DONT_ASSERT_ON_GLSL_COMPILE_ERROR // Your GLSL code contained link errors! // Hopefully this compile log should help to explain what went wrong. DBG (errorLog); jassertfalse; #endif } JUCE_CHECK_OPENGL_ERROR return status != GL_FALSE; }
void Shader::extractShaderUniforms() { GLuint pId = getProgramID(); const int BUFF_SIZE = 255; int count; glGetProgramiv(pId, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count); for (int i = 0; i < count; ++i) { char name[BUFF_SIZE]; // for holding the variable name GLint size = BUFF_SIZE; GLenum type; GLsizei length; GLsizei bufSize = BUFF_SIZE; glGetActiveUniform(pId, i, bufSize, &length, &size, &type, name); int location = glGetUniformLocation(pId, name); Uniform* uniform = UniformFactory::createUniform(name, type); uniform->addOwner(this,location); uniforms.insert(std::make_pair(uniform->getName(), uniform)); //Borrar const char* uni_types[6] = { "Error", "FLOAT", "FLOAT_VEC3", "FLOAT_VEC4", "FLOAT_MAT3", "FLOAT_MAT4" }; printf("Uniform name: %s. Type: %s.\n", uniform->getName().c_str(), uni_types[uniform->getType()]); } printf("---------------\n"); }
void NBLoadedSUMOTLDef::patchIfCrossingsAdded() { // XXX what to do if crossings are removed during network building? const unsigned int size = myTLLogic->getNumLinks(); unsigned int noLinksAll = 0; for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) { const NBConnection& c = *it; if (c.getTLIndex() != NBConnection::InvalidTlIndex) { noLinksAll = MAX2(noLinksAll, (unsigned int)c.getTLIndex() + 1); } } int oldCrossings = 0; // collect crossings std::vector<NBNode::Crossing> crossings; for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) { const std::vector<NBNode::Crossing>& c = (*i)->getCrossings(); // set tl indices for crossings (*i)->setCrossingTLIndices(noLinksAll); copy(c.begin(), c.end(), std::back_inserter(crossings)); noLinksAll += (unsigned int)c.size(); oldCrossings += (*i)->numCrossingsFromSumoNet(); } const int newCrossings = (int)crossings.size() - oldCrossings; if (newCrossings > 0) { const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases(); if (phases.size() > 0) { if (phases.front().state.size() == noLinksAll - newCrossings) { // patch states for the newly added crossings // collect edges EdgeVector fromEdges(size, 0); EdgeVector toEdges(size, 0); std::vector<int> fromLanes(size, 0); collectEdgeVectors(fromEdges, toEdges, fromLanes); const std::string crossingDefaultState(newCrossings, 'r'); // rebuild the logic (see NBOwnTLDef.cpp::myCompute) const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases(); NBTrafficLightLogic* newLogic = new NBTrafficLightLogic(getID(), getProgramID(), 0, myOffset, myType); SUMOTime brakingTime = TIME2STEPS(3); //std::cout << "patchIfCrossingsAdded for " << getID() << " numPhases=" << phases.size() << "\n"; for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) { if ((*it).state.find_first_of("yY") != std::string::npos) { brakingTime = MAX2(brakingTime, it->duration); } NBOwnTLDef::addPedestrianPhases(newLogic, it->duration, it->state + crossingDefaultState, crossings, fromEdges, toEdges); } NBOwnTLDef::addPedestrianScramble(newLogic, noLinksAll, TIME2STEPS(10), brakingTime, crossings, fromEdges, toEdges); delete myTLLogic; myTLLogic = newLogic; } else if (phases.front().state.size() != noLinksAll) { WRITE_WARNING("Could not patch tlLogic " + getID() + "for new crossings"); } } } }
NBTrafficLightLogic* NBLoadedTLDef::myCompute(const NBEdgeCont& ec, unsigned int brakingTime) { MsgHandler::getWarningInstance()->clear(); // !!! NBLoadedTLDef::SignalGroupCont::const_iterator i; // compute the switching times std::set<SUMOReal> tmpSwitchTimes; for (i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) { NBLoadedTLDef::SignalGroup* group = (*i).second; // needed later group->sortPhases(); // patch the yellow time for this group group->patchTYellow(brakingTime, OptionsCont::getOptions().getBool("tls.yellow.patch-small")); // copy the now valid times into the container // both the given red and green phases are added and also the // yellow times std::vector<SUMOReal> gtimes = group->getTimes(myCycleDuration); for (std::vector<SUMOReal>::const_iterator k = gtimes.begin(); k != gtimes.end(); k++) { tmpSwitchTimes.insert(*k); } } std::vector<SUMOReal> switchTimes; copy(tmpSwitchTimes.begin(), tmpSwitchTimes.end(), back_inserter(switchTimes)); sort(switchTimes.begin(), switchTimes.end()); // count the signals unsigned int noSignals = 0; for (i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) { noSignals += (*i).second->getLinkNo(); } // build the phases NBTrafficLightLogic* logic = new NBTrafficLightLogic(getID(), getProgramID(), noSignals, myOffset, myType); for (std::vector<SUMOReal>::iterator l = switchTimes.begin(); l != switchTimes.end(); l++) { // compute the duration of the current phase unsigned int duration; if (l != switchTimes.end() - 1) { // get from the difference to the next switching time duration = (unsigned int)((*(l + 1)) - (*l)); } else { // get from the differenc to the first switching time duration = (unsigned int)(myCycleDuration - (*l) + * (switchTimes.begin())); } // no information about yellow times will be generated assert((*l) >= 0); logic->addStep(TIME2STEPS(duration), buildPhaseState(ec, (unsigned int)(*l))); } // check whether any warnings were printed if (MsgHandler::getWarningInstance()->wasInformed()) { WRITE_WARNING("During computation of traffic light '" + getID() + "'."); } logic->closeBuilding(); return logic; }
void ShaderProgram::createProgram(void) { // Store the handle ID to our new shader program // given to us by OpenGL. printf("\n\n================================================================\n"); printf("CREATING RAW SHADER PROGRAM...\n"); programID = glCreateProgram(); printf("SUCCESS!\n"); printf("==========\n"); printf("ID: %2d\n", getProgramID()); printf("NAME: %2s\n", getName()); printf("============================================\n"); }
void NBLoadedSUMOTLDef::removeConnection(const NBConnection& conn, bool reconstruct) { NBConnectionVector::iterator it = myControlledLinks.begin(); // find the connection but ignore its TLIndex since it might have been // invalidated by an earlier removal for (; it != myControlledLinks.end(); ++it) { if (it->getFrom() == conn.getFrom() && it->getTo() == conn.getTo() && it->getFromLane() == conn.getFromLane() && it->getToLane() == conn.getToLane()) { break; } } if (it == myControlledLinks.end()) { // a traffic light doesn't always controll all connections at a junction // especially when using the option --tls.join return; } const int removed = it->getTLIndex(); // remove the connection myControlledLinks.erase(it); if (reconstruct) { // updating the edge is only needed for immediate use in NETEDIT. // It may conflict with loading diffs conn.getFrom()->setControllingTLInformation(conn, ""); // shift link numbers down so there is no gap for (NBConnectionVector::iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) { NBConnection& c = *it; if (c.getTLIndex() > removed) { c.setTLIndex(c.getTLIndex() - 1); } } // update controlling information with new link numbers setTLControllingInformation(); // rebuild the logic const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases(); NBTrafficLightLogic* newLogic = new NBTrafficLightLogic(getID(), getProgramID(), 0, myOffset, myType); for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) { std::string newState = it->state; newState.erase(newState.begin() + removed); newLogic->addStep(it->duration, newState); } delete myTLLogic; myTLLogic = newLogic; } }
void NBLoadedSUMOTLDef::patchIfCrossingsAdded() { // XXX what to do if crossings are removed during network building? const unsigned int size = myTLLogic->getNumLinks(); unsigned int noLinksAll = size; // collect crossings std::vector<NBNode::Crossing> crossings; for (std::vector<NBNode*>::iterator i = myControlledNodes.begin(); i != myControlledNodes.end(); i++) { const std::vector<NBNode::Crossing>& c = (*i)->getCrossings(); // set tl indices for crossings (*i)->setCrossingTLIndices(noLinksAll); copy(c.begin(), c.end(), std::back_inserter(crossings)); noLinksAll += (unsigned int)c.size(); } if (crossings.size() > 0) { // collect edges assert(size > 0); EdgeVector fromEdges(size, 0); EdgeVector toEdges(size, 0); for (NBConnectionVector::const_iterator it = myControlledLinks.begin(); it != myControlledLinks.end(); it++) { const NBConnection& c = *it; if (c.getTLIndex() != NBConnection::InvalidTlIndex) { assert(c.getTLIndex() < (int)size); fromEdges[c.getTLIndex()] = c.getFrom(); toEdges[c.getTLIndex()] = c.getTo(); } } /// XXX handle the case where some crossings are already loaded const std::string crossingDefaultState(crossings.size(), 'r'); // rebuild the logic (see NBOwnTLDef.cpp::myCompute) const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = myTLLogic->getPhases(); NBTrafficLightLogic* newLogic = new NBTrafficLightLogic(getID(), getProgramID(), 0, myOffset, myType); //std::cout << "patchIfCrossingsAdded for " << getID() << " numPhases=" << phases.size() << "\n"; for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) { NBOwnTLDef::addPedestrianPhases(newLogic, it->duration, it->state + crossingDefaultState, crossings, fromEdges, toEdges); } delete myTLLogic; myTLLogic = newLogic; } }
bool ShaderProgram::linkProgram(void) { printf("============================================\n"); printf("%2s SHADER PROGRAM STATUS: \n", name); printf("ID: %2d\n", getProgramID()); printf("==========\n"); printf("Linking program...\b\n"); // Tell OpenGL to try to link the various shaders added to this // program into a pipeline. glLinkProgram(programID); printf("==========\n"); printf("LINK ATTEMPT COMPLETE.\n"); // Get the link status of the attempt. int iLinkStatus; glGetProgramiv(programID, GL_LINK_STATUS, &iLinkStatus); linked = iLinkStatus == GL_TRUE; printf("LINK STATUS: %2d\n", linked); printf("================================================================\n"); // Return that link status. return linked; }
void Shader::sendMat4(std::string name, glm::mat4 matrix) { glUniformMatrix4fv(glGetUniformLocation(getProgramID(), name.c_str()), 1, GL_FALSE, glm::value_ptr(matrix)); }
NBTrafficLightLogic* NBLoadedTLDef::myCompute(unsigned int brakingTimeSeconds) { MsgHandler::getWarningInstance()->clear(); // !!! NBLoadedTLDef::SignalGroupCont::const_iterator i; // compute the switching times std::set<SUMOReal> tmpSwitchTimes; for (i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) { NBLoadedTLDef::SignalGroup* group = (*i).second; // needed later group->sortPhases(); // patch the yellow time for this group group->patchTYellow(brakingTimeSeconds, OptionsCont::getOptions().getBool("tls.yellow.patch-small")); // copy the now valid times into the container // both the given red and green phases are added and also the // yellow times std::vector<SUMOReal> gtimes = group->getTimes(myCycleDuration); for (std::vector<SUMOReal>::const_iterator k = gtimes.begin(); k != gtimes.end(); k++) { tmpSwitchTimes.insert(*k); } } std::vector<SUMOReal> switchTimes; copy(tmpSwitchTimes.begin(), tmpSwitchTimes.end(), back_inserter(switchTimes)); sort(switchTimes.begin(), switchTimes.end()); // count the signals unsigned int noSignals = 0; for (i = mySignalGroups.begin(); i != mySignalGroups.end(); i++) { noSignals += (*i).second->getLinkNo(); } // build the phases NBTrafficLightLogic* logic = new NBTrafficLightLogic(getID(), getProgramID(), noSignals, myOffset, myType); for (std::vector<SUMOReal>::iterator l = switchTimes.begin(); l != switchTimes.end(); l++) { // compute the duration of the current phase unsigned int duration; if (l != switchTimes.end() - 1) { // get from the difference to the next switching time duration = (unsigned int)((*(l + 1)) - (*l)); } else { // get from the differenc to the first switching time duration = (unsigned int)(myCycleDuration - (*l) + * (switchTimes.begin())); } // no information about yellow times will be generated assert((*l) >= 0); logic->addStep(TIME2STEPS(duration), buildPhaseState((unsigned int)(*l))); } // check whether any warnings were printed if (MsgHandler::getWarningInstance()->wasInformed()) { WRITE_WARNING("During computation of traffic light '" + getID() + "'."); } logic->closeBuilding(); // initialize myNeedsContRelation myNeedsContRelation.clear(); const bool controlledWithin = !OptionsCont::getOptions().getBool("tls.uncontrolled-within"); const std::vector<NBTrafficLightLogic::PhaseDefinition> phases = logic->getPhases(); for (std::vector<NBTrafficLightLogic::PhaseDefinition>::const_iterator it = phases.begin(); it != phases.end(); it++) { const std::string state = (*it).state; for (NBConnectionVector::const_iterator it1 = myControlledLinks.begin(); it1 != myControlledLinks.end(); it1++) { const NBConnection& c1 = *it1; const int i1 = c1.getTLIndex(); if (i1 == NBConnection::InvalidTlIndex || state[i1] != 'g' || c1.getFrom() == 0 || c1.getTo() == 0) { continue; } for (NBConnectionVector::const_iterator it2 = myControlledLinks.begin(); it2 != myControlledLinks.end(); it2++) { const NBConnection& c2 = *it2; const int i2 = c2.getTLIndex(); if (i2 != NBConnection::InvalidTlIndex && i2 != i1 && (state[i2] == 'G' || state[i2] == 'g') && c2.getFrom() != 0 && c2.getTo() != 0) { const bool rightTurnConflict = NBNode::rightTurnConflict( c1.getFrom(), c1.getTo(), c1.getFromLane(), c2.getFrom(), c2.getTo(), c2.getFromLane()); if (forbids(c2.getFrom(), c2.getTo(), c1.getFrom(), c1.getTo(), true, controlledWithin) || rightTurnConflict) { myNeedsContRelation.insert(StreamPair(c1.getFrom(), c1.getTo(), c2.getFrom(), c2.getTo())); } } } } } myNeedsContRelationReady = true; return logic; }
void ShadowMap::init() { fbo = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenTextures(1, &tex_depth); glBindTexture(GL_TEXTURE_2D, tex_depth); glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, resolution, resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); float bord_color[] = { 1.0f, 0.0f, 0.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bord_color); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); // glFramebufferTexture requires OpenGL 3.2 glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex_depth, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); // Why is this needed? GLenum status; if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) { //fprintf(stderr, "glCheckFramebufferStatus original image: error %p", status); //std::cout<<"\n"; std::cerr<<"glCheckFramebufferStatus original image: error " << status << std::endl; } glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); //Create and compile our GLSL program from the shaders ShaderBase::load("shaders/shadow_map_vert.glsl", "shaders/shadow_map_frag.glsl" ); //Uniforms uniforms.light_mvp_mat = glGetUniformLocation(getProgramID(), "depthMVP"); uniforms.bone_mat = glGetUniformLocation(getProgramID(), "bone_mat"); uniforms.tex = glGetUniformLocation(getProgramID(), "tex"); glUniform1i(uniforms.tex, 0); // ALWAYS CHANNEL 0 //Attributes glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); GLenum errCode; errCode = glGetError(); if (errCode != GL_NO_ERROR) { std::cerr << "glGetError()) != GL_NO_ERROR-----SHADOW------\n"; if (errCode == GL_INVALID_VALUE) { std::cerr << "GL_INVALID_VALUE\n"; } } std::cout << "shadowmap initialized\n"; }
NBTrafficLightLogic* NBOwnTLDef::myCompute(const NBEdgeCont&, unsigned int brakingTimeSeconds) { const SUMOTime brakingTime = TIME2STEPS(brakingTimeSeconds); const SUMOTime leftTurnTime = TIME2STEPS(6); // make configurable ? // build complete lists first const EdgeVector& incoming = getIncomingEdges(); EdgeVector fromEdges, toEdges; std::vector<bool> isLeftMoverV, isTurnaround; unsigned int noLanesAll = 0; unsigned int noLinksAll = 0; for (unsigned int i1 = 0; i1 < incoming.size(); i1++) { unsigned int noLanes = incoming[i1]->getNumLanes(); noLanesAll += noLanes; for (unsigned int i2 = 0; i2 < noLanes; i2++) { NBEdge* fromEdge = incoming[i1]; std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2); noLinksAll += (unsigned int) approached.size(); for (unsigned int i3 = 0; i3 < approached.size(); i3++) { if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) { --noLinksAll; continue; } assert(i3 < approached.size()); NBEdge* toEdge = approached[i3].toEdge; fromEdges.push_back(fromEdge); //myFromLanes.push_back(i2); toEdges.push_back(toEdge); if (toEdge != 0) { isLeftMoverV.push_back( isLeftMover(fromEdge, toEdge) || fromEdge->isTurningDirectionAt(fromEdge->getToNode(), toEdge)); isTurnaround.push_back( fromEdge->isTurningDirectionAt( fromEdge->getToNode(), toEdge)); } else { isLeftMoverV.push_back(true); isTurnaround.push_back(true); } } } } NBTrafficLightLogic* logic = new NBTrafficLightLogic(getID(), getProgramID(), noLinksAll, myOffset, myType); EdgeVector toProc = incoming; const SUMOTime greenTime = TIME2STEPS(OptionsCont::getOptions().getInt("tls.green.time")); // build all phases while (toProc.size() > 0) { std::pair<NBEdge*, NBEdge*> chosen; if (incoming.size() == 2) { chosen = std::pair<NBEdge*, NBEdge*>(toProc[0], static_cast<NBEdge*>(0)); toProc.erase(toProc.begin()); } else { chosen = getBestPair(toProc); } unsigned int pos = 0; std::string state((size_t) noLinksAll, 'o'); // plain straight movers for (unsigned int i1 = 0; i1 < (unsigned int) incoming.size(); ++i1) { NBEdge* fromEdge = incoming[i1]; const bool inChosen = fromEdge == chosen.first || fromEdge == chosen.second; //chosen.find(fromEdge)!=chosen.end(); const unsigned int numLanes = fromEdge->getNumLanes(); for (unsigned int i2 = 0; i2 < numLanes; i2++) { std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2); for (unsigned int i3 = 0; i3 < approached.size(); ++i3) { if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) { continue; } if (inChosen) { state[pos] = 'G'; } else { state[pos] = 'r'; } ++pos; } } } // correct behaviour for those that are not in chosen, but may drive, though for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] == 'G') { continue; } bool isForbidden = false; for (unsigned int i2 = 0; i2 < pos && !isForbidden; ++i2) { if (state[i2] == 'G' && !isTurnaround[i2] && (forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true) || forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2], true))) { isForbidden = true; } } if (!isForbidden) { state[i1] = 'G'; } } // correct behaviour for those that have to wait (mainly left-mover) bool haveForbiddenLeftMover = false; for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] != 'G') { continue; } for (unsigned int i2 = 0; i2 < pos; ++i2) { if ((state[i2] == 'G' || state[i2] == 'g') && forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true)) { state[i1] = 'g'; if (!isTurnaround[i1]) { haveForbiddenLeftMover = true; } } } } // add step logic->addStep(greenTime, state); if (brakingTime > 0) { // build yellow (straight) for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] != 'G' && state[i1] != 'g') { continue; } if ((state[i1] >= 'a' && state[i1] <= 'z') && haveForbiddenLeftMover) { continue; } state[i1] = 'y'; } // add step logic->addStep(brakingTime, state); } if (haveForbiddenLeftMover && !myHaveSinglePhase) { // build left green for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] == 'Y' || state[i1] == 'y') { state[i1] = 'r'; continue; } if (state[i1] == 'g') { state[i1] = 'G'; } } // add step logic->addStep(leftTurnTime, state); // build left yellow if (brakingTime > 0) { for (unsigned int i1 = 0; i1 < pos; ++i1) { if (state[i1] != 'G' && state[i1] != 'g') { continue; } state[i1] = 'y'; } // add step logic->addStep(brakingTime, state); } } } const SUMOTime totalDuration = logic->getDuration(); if (totalDuration > 0) { if (totalDuration > 3 * (greenTime + 2 * brakingTime + leftTurnTime)) { WRITE_WARNING("The traffic light '" + getID() + "' has a high cycle time of " + time2string(totalDuration) + "."); } return logic; } else { delete logic; return 0; } }