// Run the IHK line void runLine(){ LCDClear(); static const uint8_t forwardDirection = 0; // Start speed, current speed. uint8_t currentSpeed = SPEED_CREEP; setDirectionMotorL(forwardDirection); setDirectionMotorR(forwardDirection); // Run until end of track. while(stopFlag == FLAG_NOT_SET) { if(getSensorUpdateFlag()) { // When a line is lost after driving straight, go in search mode if(lostLineFlag == FLAG_SET) { searchMode(); lostLineFlag = FLAG_NOT_SET; } // When line is found, make a Right turn // Increase speed and follow the line. if(foundLineFlag == FLAG_SET) { go(150,DIRECTION_RIGHT,SPEED_CREEP); setDirectionMotorL(forwardDirection); setDirectionMotorR(forwardDirection); currentSpeed = SPEED_CREEP; foundLineFlag = FLAG_USED; } // When following the line, // if front sensor detects obstacle, // exit line following loop if (foundLineFlag == FLAG_USED) { uint16_t distance = AdcConvert(1); if (distance > (uint16_t)500) { setStopFlag(FLAG_SET); } } // Calculate and set new duty cycle. calcDuty(currentSpeed, calcFloorErrorAndFlagControl()); clearSensorUpdateFlag(); } } // Stop the robot at end mark. setDutyCycleMotorL(0); setDutyCycleMotorR(0); }
void MidiDevice::handleStop() { // If the device is not in use by a port, don't bother it. if(_port == -1) return; MidiPort* mp = &MusEGlobal::midiPorts[_port]; //--------------------------------------------------- // send midi stop //--------------------------------------------------- // Don't send if external sync is on. The master, and our sync routing system will take care of that. if(!MusEGlobal::extSyncFlag.value()) { // Shall we check open flags? DELETETHIS 4? //if(!(dev->rwFlags() & 0x1) || !(dev->openFlags() & 1)) //if(!(dev->openFlags() & 1)) // return; MidiSyncInfo& si = mp->syncInfo(); if(si.MMCOut()) mp->sendMMCStop(); if(si.MRTOut()) { mp->sendStop(); //DELETETHIS 5? // Added check of option send continue not start. Hmm, is this required? Seems to make other devices unhappy. // (Could try now that this is in MidiDevice.) //if(!si.sendContNotStart()) // mp->sendSongpos(MusEGlobal::audio->tickPos() * 4 / MusEGlobal::config.division); } } //--------------------------------------------------- // Clear all notes and flush out any stuck notes // which were put directly to the device //--------------------------------------------------- setStopFlag(true); for(iMPEvent i = _stuckNotes.begin(); i != _stuckNotes.end(); ++i) { MidiPlayEvent ev(*i); ev.setTime(0); // Immediate processing. TODO Use curFrame? //ev.setTime(MusEGlobal::audio->midiQueueTimeStamp(ev.time())); putEvent(ev, MidiDevice::NotLate); } _stuckNotes.clear(); //------------------------------------------------------------ // Flush out any track-related playback stuck notes (NOT 'live' notes) // which were not put directly to the device //------------------------------------------------------------ for(ciMidiTrack imt = MusEGlobal::song->midis()->begin(); imt != MusEGlobal::song->midis()->end(); ++imt) { MPEventList& mel = (*imt)->stuckNotes; for(iMPEvent i = mel.begin(), i_next = i; i != mel.end(); i = i_next) { ++i_next; if((*i).port() != _port) continue; MidiPlayEvent ev(*i); ev.setTime(0); // Immediate processing. TODO Use curFrame? //ev.setTime(MusEGlobal::audio->midiQueueTimeStamp(ev.time())); putEvent(ev, MidiDevice::NotLate); mel.erase(i); } } //--------------------------------------------------- // reset sustain //--------------------------------------------------- for(int ch = 0; ch < MusECore::MUSE_MIDI_CHANNELS; ++ch) { if(mp->hwCtrlState(ch, CTRL_SUSTAIN) == 127) { MidiPlayEvent ev(0, _port, ch, ME_CONTROLLER, CTRL_SUSTAIN, 0); // Immediate processing. TODO Use curFrame? //ev.setTime(MusEGlobal::audio->midiQueueTimeStamp(ev.time())); putEvent(ev, MidiDevice::NotLate); } } }