Created
March 20, 2015 12:53
-
-
Save cilliand/f716c92933a28b0bcfa4 to your computer and use it in GitHub Desktop.
P300
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "testApp.h" | |
| #include <sstream> | |
| #include "filters.cpp" | |
| #define SETTINGSTAG "SETTINGS" | |
| int index = -1; | |
| //-------------------------------------------------------------- | |
| void testApp::setup(){ | |
| oscIn.setup(7400); | |
| oscStim.setup(7401); | |
| returnResult.setup("localhost",7402); | |
| wekinator.setup("localhost", 6448); | |
| stimCount = 3; | |
| stimIndexes.resize(stimCount); | |
| recentEEG.resize(400); | |
| ofSetVerticalSync(true); | |
| for(int i=0; i < stimCount * 2; i++) { | |
| cols.push_back(ofColor(ofRandom(200), ofRandom(200), ofRandom(200))); | |
| } | |
| for(int i=0; i < stimCount; i++) { | |
| stimIndexes[i].clear(); | |
| } | |
| eeg.clear(); | |
| appPhase = RECORDING; | |
| // std::cout << "Start receiving EEG Data! Press any key to stop logging...\n" << std::endl; | |
| } | |
| maxiFFT FFT; | |
| //-------------------------------------------------------------- | |
| void testApp::update(){ | |
| if( oscIn.hasWaitingMessages()) { | |
| ofxOscMessage msg; | |
| while(oscIn.getNextMessage(&msg)) { | |
| //cout << msg.getAddress() << endl; | |
| if (msg.getAddress() == "/d" && RECORDING == appPhase) { | |
| float val = msg.getArgAsFloat(0); | |
| val = dcBlocker.play(val, 0.92); | |
| val = filterNotch50Hz(val); | |
| val = lpfilter45(val); | |
| // std::cout << val << std::endl; | |
| // std::cout << val << std::endl; | |
| eeg.push_back(val); | |
| recentEEG.push_back(val); | |
| recentEEG.pop_front(); | |
| } | |
| else if (msg.getAddress() == "/st" && RECORDING == appPhase) { | |
| int idx = msg.getArgAsInt32(0); | |
| stimIndexes[idx].push_back(MAX(0,eeg.size()-1)); | |
| // cout << "Stim: " << idx << endl; | |
| } | |
| else if (msg.getAddress() == "/start") { | |
| for(int i=0; i < stimCount; i++) { | |
| stimIndexes[i].clear(); | |
| } | |
| index++; | |
| eeg.clear(); | |
| appPhase = RECORDING; | |
| } | |
| else if (msg.getAddress() == "/end" && RECORDING == appPhase) { | |
| //analyse | |
| analyse(); | |
| } | |
| } | |
| while(oscStim.getNextMessage(&msg)) { | |
| // cout << msg.getAddress() << endl; | |
| if (msg.getAddress() == "/d" && RECORDING == appPhase) { | |
| float val = msg.getArgAsFloat(0); | |
| val = dcBlocker.play(val, 0.92); | |
| val = filterNotch50Hz(val); | |
| val = lpfilter45(val); | |
| // std::cout << val << std::endl; | |
| eeg.push_back(val); | |
| recentEEG.push_back(val); | |
| recentEEG.pop_front(); | |
| } | |
| else if (msg.getAddress() == "/st" && RECORDING == appPhase) { | |
| int idx = msg.getArgAsInt32(0); | |
| stimIndexes[idx].push_back(MAX(0,eeg.size()-1)); | |
| cout << "Stim: " << idx << endl; | |
| } | |
| else if (msg.getAddress() == "/start") { | |
| for(int i=0; i < stimCount; i++) { | |
| stimIndexes[i].clear(); | |
| } | |
| eeg.clear(); | |
| } | |
| else if (msg.getAddress() == "/end" && RECORDING == appPhase) { | |
| //analyse | |
| analyse(); | |
| } | |
| } | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void testApp::draw(){ | |
| ofBackground(255); | |
| ofEnableSmoothing(); | |
| switch(appPhase) { | |
| case RECORDING: | |
| { | |
| ofSetColor(0,0,200); | |
| list<float>::iterator it = recentEEG.begin(); | |
| float inc = ofGetWidth() / (float) recentEEG.size(); | |
| float mid = ofGetHeight() / 2.0; | |
| int i=0; | |
| float last = *it; | |
| it++; | |
| while(it != recentEEG.end()) { | |
| //ofCircle(i*inc, mid - (last * mid), 3); | |
| ofLine(i*inc, mid - (last * mid), (i+1) * inc, mid - (*it * mid)); | |
| last = *it; | |
| i++; | |
| it++; | |
| } | |
| } | |
| break; | |
| case ANALYSING: | |
| ofBackground(ofRandomuf() * 255, ofRandomuf() * 255, ofRandomuf() * 255); | |
| break; | |
| case DONE: | |
| for(int s=0; s < stimCount; s++) { | |
| ofSetColor(cols[s]); | |
| vector<float>::iterator it = stimAvgWindows[s].begin(); | |
| float inc = ofGetWidth() / (float) stimAvgWindows[s].size(); | |
| float mid = ofGetHeight() / 2.0; | |
| int i=0; | |
| float last = *it; | |
| it++; | |
| while(it != stimAvgWindows[s].end()) { | |
| ofLine(i*inc, mid - (last * mid), (i+1) * inc, mid - (*it * mid)); | |
| last = *it; | |
| i++; | |
| it++; | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| void testApp::analyseSignal(vector<float> &sig, int winStart, int winLen, vector<vector<float> > &stimAvgWins) { | |
| stimAvgWins.resize(stimCount); | |
| for(int i=0; i < stimCount; i++) { | |
| stimAvgWins[i].resize(winLen, 0); | |
| } | |
| vector<int> validWindowCount(stimCount,0); | |
| //sum area of each stimulus | |
| for(int s=0; s < stimCount; s++){ | |
| for(int i=0; i < stimIndexes[s].size(); i++) { | |
| int eegIdx = stimIndexes[s][i]; | |
| ofxOscMessage wek; | |
| wek.setAddress("/oscCustomFeatures"); | |
| if (eegIdx + winStart + winLen < sig.size()) { | |
| int winIdx = 0; | |
| for(int e=eegIdx + winStart; e < eegIdx + winStart + winLen; e++) { | |
| wek.addFloatArg(sig[e]); | |
| //stimAvgWins[s][winIdx++] += sig[e]; | |
| } | |
| validWindowCount[s]++; | |
| } | |
| std::cout << "Num args: " << wek.getNumArgs() << std::endl; | |
| wekinator.sendMessage(wek); | |
| } | |
| } | |
| vector<float> totalArea(stimCount,0); | |
| for(int s=0; s < stimCount; s++) { | |
| if (validWindowCount[s] > 0) { | |
| for(int i=0; i < stimAvgWins[s].size(); i++) { | |
| stimAvgWins[s][i] /= validWindowCount[s]; | |
| totalArea[s] += fabs(stimAvgWins[s][i]); | |
| } | |
| } | |
| } | |
| int lastArea = -1; | |
| int best = -1; | |
| for(int s=0; s < stimCount; s++) { | |
| cout << ", " << s << ":"; | |
| cout << ", " << validWindowCount[s]; | |
| cout << ", " << totalArea[s]; | |
| if(totalArea[s] > lastArea){ | |
| best = s; | |
| lastArea = totalArea[s]; | |
| } | |
| } | |
| ofxOscMessage m; | |
| m.setAddress("/r"); | |
| m.addFloatArg(best); | |
| returnResult.sendMessage(m); | |
| cout << ", " << best << ", " << std::endl; | |
| } | |
| void testApp::analyse() { | |
| appPhase = ANALYSING; | |
| int sampleRate = 128; | |
| float winLenMs = 500; | |
| float winStartMs = 100; | |
| int winLen = (winLenMs / 1000.0 * sampleRate); | |
| int winStart = (winStartMs / 1000.0 * sampleRate); | |
| log.addTag(SETTINGSTAG); | |
| log.pushTag(SETTINGSTAG, 0); | |
| log.addAttribute(SETTINGSTAG, "STIMCOUNT", stimCount, 0); | |
| log.addAttribute(SETTINGSTAG, "SAMPLERATE", sampleRate, 0); | |
| log.popTag(); | |
| stringstream data; | |
| for(int e=0; e < eeg.size(); e++) | |
| data << eeg[e] << ","; | |
| log.addValue("RAW", data.str()); | |
| for(int s=0; s < stimCount; s++) { | |
| data.str(""); | |
| for(int i=0; i < stimIndexes[s].size(); i++) { | |
| data << stimIndexes[s][i] << ","; | |
| } | |
| log.addValue("INDEXES_"+ofToString(index), data.str()); | |
| log.addAttribute("INDEXES_"+ofToString(index), "STIM", s, s); | |
| } | |
| cout << winLen << ", " << winStart; | |
| analyseSignal(eeg, winStart, winLen, stimAvgWindows); | |
| stringstream filename; | |
| filename << "eegLog-"; | |
| filename << ofGetSystemTime() << ".xml"; | |
| log.saveFile(ofToDataPath(filename.str())); | |
| appPhase = DONE; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "ofApp.h" | |
| EmoEngineEventHandle eEvent = EE_EmoEngineEventCreate(); | |
| EmoStateHandle eState = EE_EmoStateCreate(); | |
| unsigned int userID = 0; | |
| const unsigned short composerPort = 1726; | |
| float secs = 1; | |
| unsigned int datarate = 0; | |
| bool readytocollect = false; | |
| int option = 0; | |
| int state = 0; | |
| int stimIndex = 0; | |
| EE_DataChannel_t targetChannelList[] = { | |
| ED_O1 | |
| }; | |
| const char header[] = "O1, STIM,"; | |
| ofImage upArrow, leftArrow, rightArrow; | |
| ofImage gUpArrow, gLeftArrow, gRightArrow; | |
| ofxXmlSettings settings; | |
| string com, stream = ""; | |
| bool startAgain, resultReceived, start, moveable = false; | |
| bool stimChanged = true; | |
| int result = -1; | |
| clock_t t1, t2; | |
| clock_t stimTimer1, stimTimer2; | |
| int stimNumber = 0; | |
| int lastStim = -1; | |
| float feedbackX, feedbackY, moveX, moveY; | |
| std::ofstream ofs("eegLog.csv",std::ios::trunc); | |
| //-------------------------------------------------------------- | |
| void ofApp::setup(){ | |
| ofs << header << std::endl; | |
| moveX = 0; | |
| moveY = 0; | |
| settings.loadFile("settings.xml"); | |
| stream = settings.getValue("settings:stream","stream"); | |
| com = settings.getValue("settings:com","comport"); | |
| font.loadFont("font.ttf", 32); | |
| upArrow.loadImage("images/up.png"); | |
| leftArrow.loadImage("images/left.png"); | |
| rightArrow.loadImage("images/right.png"); | |
| gUpArrow.loadImage("images/gup.png"); | |
| gLeftArrow.loadImage("images/gleft.png"); | |
| gRightArrow.loadImage("images/gright.png"); | |
| ofBackground(255); | |
| if (EE_EngineConnect() != EDK_OK) { | |
| throw "Emotiv Engine start up failed."; | |
| } | |
| // open an outgoing connection to HOST:PORT | |
| sender.setup(HOST, PORT); | |
| stimSender.setup(HOST, 7401); | |
| receiver.setup(7402); | |
| ofSetLogLevel(OF_LOG_VERBOSE); | |
| ofSetFrameRate(30); | |
| loadCameras(); | |
| ofSetVerticalSync(true); | |
| bSendSerialMessage = false; | |
| serial.listDevices(); | |
| vector <ofSerialDeviceInfo> deviceList = serial.getDeviceList(); | |
| // this should be set to whatever com port your serial device is connected to. | |
| // (ie, COM4 on a pc, /dev/tty.... on linux, /dev/tty... on a mac) | |
| // arduino users check in arduino app.... | |
| int baud = 9600; | |
| serial.setup(com, baud); // connect to COM port at 9600 | |
| nTimesRead = 0; | |
| nBytesRead = 0; | |
| readTime = 0; | |
| memset(bytesReadString, 0, 4); | |
| hData = EE_DataCreate(); | |
| EE_DataSetBufferSizeInSec(secs); | |
| ofxOscMessage m; | |
| m.setAddress("/start"); | |
| sender.sendMessage(m); | |
| t1 = clock(); | |
| } | |
| //------------------------------------------------------------------------------ | |
| IPCameraDef& ofApp::getNextCamera() | |
| { | |
| nextCamera = (nextCamera + 1) % ipcams.size(); | |
| return ipcams[nextCamera]; | |
| } | |
| //------------------------------------------------------------------------------ | |
| void ofApp::loadCameras() | |
| { | |
| // all of these cameras were found using this google query | |
| // http://www.google.com/search?q=inurl%3A%22axis-cgi%2Fmjpg%22 | |
| // some of the cameras below may no longer be valid. | |
| // to define a camera with a username / password | |
| //ipcams.push_back(IPCameraDef("http://148.61.142.228/axis-cgi/mjpg/video.cgi", "username", "password")); | |
| ofLog(OF_LOG_NOTICE, "---------------Loading Streams---------------"); | |
| std::cout << "Connecting to: " << stream << std::endl; | |
| ipcams.push_back(IPCameraDef(stream)); // home | |
| ofLog(OF_LOG_NOTICE, "-----------Loading Streams Complete----------"); | |
| IPCameraDef& cam = getNextCamera(); | |
| SharedIPVideoGrabber c = IPVideoGrabber::makeShared(); | |
| c->setCameraName(cam.getName()); | |
| c->setURI(cam.getURL()); | |
| c->connect(); // connect immediately | |
| // if desired, set up a video resize listener | |
| ofAddListener(c->videoResized, this, &ofApp::videoResized); | |
| grabbers.push_back(c); | |
| } | |
| //------------------------------------------------------------------------------ | |
| void ofApp::videoResized(const void* sender, ofResizeEventArgs& arg) | |
| { | |
| // find the camera that sent the resize event changed | |
| for(std::size_t i = 0; i < NUM_CAMERAS; i++) | |
| { | |
| if(sender == &grabbers[i]) | |
| { | |
| std::stringstream ss; | |
| ss << "videoResized: "; | |
| ss << "Camera connected to: " << grabbers[i]->getURI() + " "; | |
| ss << "New DIM = " << arg.width << "/" << arg.height; | |
| ofLogVerbose("ofApp") << ss.str(); | |
| } | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::update(){ | |
| if(receiver.hasWaitingMessages()){ | |
| ofxOscMessage msg; | |
| while(receiver.getNextMessage(&msg)) { | |
| // if (msg.getAddress() == "/r"){ | |
| // resultReceived = true; | |
| // result = msg.getArgAsFloat(0); | |
| // std::cout << result << std::endl; | |
| // } | |
| std::cout << "Wek Args: " << msg.getNumArgs() << std::endl; | |
| if (msg.getAddress() == "/OSCSynth/params"){ | |
| resultReceived = true; | |
| if(msg.getArgAsFloat(0) == 1){ | |
| result = 0; | |
| } else if(msg.getArgAsFloat(1) == 1){ | |
| result = 1; | |
| } else if(msg.getArgAsFloat(2) == 1){ | |
| result = 2; | |
| }:r | |
| std::cout << "Wek Result: " << result << std::endl; | |
| } | |
| } | |
| } | |
| if(startAgain){ | |
| ofxOscMessage m; | |
| m.setAddress("/start"); | |
| sender.sendMessage(m); | |
| t1 = clock(); | |
| startAgain = false; | |
| } | |
| if(start){ | |
| //camAndSerialUpdate(); | |
| t2=clock(); | |
| if((t2-t1)/CLOCKS_PER_SEC < 10.0){ | |
| state = EE_EngineGetNextEvent(eEvent); | |
| if (state == EDK_OK) { | |
| EE_Event_t eventType = EE_EmoEngineEventGetType(eEvent); | |
| EE_EmoEngineEventGetUserId(eEvent, &userID); | |
| // Log the EmoState if it has been updated | |
| if (eventType == EE_UserAdded) { | |
| std::cout << "User added"; | |
| EE_DataAcquisitionEnable(userID,true); | |
| readytocollect = true; | |
| } | |
| } | |
| if (readytocollect) { | |
| stimTimer2 = clock(); | |
| if((stimTimer2-stimTimer1) / CLOCKS_PER_SEC > .25){ | |
| stimNumber++; | |
| if(stimNumber >= 3){ | |
| stimNumber = 0; | |
| } | |
| stimChanged = true; | |
| stimTimer1 = clock(); | |
| } | |
| if(stimChanged){ | |
| ofxOscMessage m; | |
| m.setAddress("/st"); | |
| m.addIntArg(stimNumber); | |
| stimSender.sendMessage(m); | |
| stimChanged = false; | |
| } | |
| EE_DataUpdateHandle(0, hData); | |
| unsigned int nSamplesTaken=0; | |
| EE_DataGetNumberOfSample(hData,&nSamplesTaken); | |
| //std::cout << "Updated " << nSamplesTaken << std::endl; | |
| if (nSamplesTaken != 0) { | |
| unsigned int channelCount = sizeof(targetChannelList)/sizeof(EE_DataChannel_t); | |
| double ** buffer = new double*[channelCount]; | |
| for (int i=0; i<channelCount; i++) | |
| buffer[i] = new double[nSamplesTaken]; | |
| EE_DataGetMultiChannels(hData, targetChannelList, channelCount, buffer, nSamplesTaken); | |
| for (int sampleIdx=0 ; sampleIdx<(int)nSamplesTaken ; ++sampleIdx) { | |
| for (int i = 0 ; i<sizeof(targetChannelList)/sizeof(EE_DataChannel_t) ; i++) { | |
| //std::cout << buffer[i][sampleIdx] << std::endl; | |
| ofxOscMessage m; | |
| m.setAddress("/d"); | |
| //std::cout <<"1: "<< buffer[i][sampleIdx] << " 2: " << buffer[i][sampleIdx+1] << " SUM: " << buffer[i][sampleIdx]+buffer[i][sampleIdx+1] << " AVG: " << (buffer[i][sampleIdx]+buffer[i][sampleIdx+1])/2 << std::endl; | |
| ofs << buffer[i][sampleIdx] << ", " << ofToString(stimNumber) << ", " << std::endl; | |
| m.addFloatArg(buffer[i][sampleIdx]); | |
| sender.sendMessage(m); | |
| } | |
| } | |
| for (int i=0; i<channelCount; i++) | |
| delete buffer[i]; | |
| delete buffer; | |
| } | |
| } | |
| //Sleep(100); | |
| } else { | |
| ofxOscMessage m; | |
| m.setAddress("/end"); | |
| sender.sendMessage(m); | |
| startAgain = true; | |
| } | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::draw(){ | |
| feedbackX = ofGetWidth()/2 + moveX; | |
| feedbackY = ofGetHeight() - 100 + moveY; | |
| if(!start){ | |
| string welcome = "Emotiv EPOC Controlled RC Car"; | |
| ofBackground(0); | |
| font.drawString(welcome, (ofGetWidth()/2)-font.stringWidth(welcome)/2,(ofGetHeight()/2)-font.stringHeight(welcome)/2); | |
| font.drawString("PRESS SPACE TO BEGIN", (ofGetWidth()/2)-font.stringWidth("PRESS SPACE TO BEGIN")/2,20+(ofGetHeight()/2)+font.stringHeight(welcome)/2); | |
| } else { | |
| ofBackground(0); | |
| // display instructions | |
| ofPushStyle(); | |
| ofSetColor(255); | |
| string buf; | |
| buf = "sending osc:" + string(HOST) + " " + ofToString(PORT); | |
| ofDrawBitmapString(buf, 10, 20); | |
| ofCircle(feedbackX,feedbackY,100); | |
| ofPopStyle(); | |
| gLeftArrow.draw((ofGetHeight()/2)-256,0,256, 256); | |
| gUpArrow.draw((ofGetWidth()/2)-128,0, 256, 256); | |
| gRightArrow.draw((ofGetHeight()/2)+192, 0, 256, 256); | |
| //camAndSerialDraw(); | |
| if(resultReceived == false){ | |
| if(stimNumber == 0){ //up arrow | |
| leftArrow.draw((ofGetHeight()/2)-256, 0, 256, 256); | |
| } else if(stimNumber == 1){ //left arrow | |
| upArrow.draw((ofGetWidth()/2)-128,0, 256, 256); | |
| } else if(stimNumber == 2){ //right arrow | |
| rightArrow.draw((ofGetHeight()/2)+192, 0, 256, 256); | |
| } | |
| } else { | |
| string decision; | |
| decision = "Moving: "; | |
| if(result == 1){ | |
| decision += "FORWARD."; | |
| moveY -= 50; | |
| if(moveable) | |
| moveForward(); | |
| //upArrow.draw((ofGetWidth()/2)-32,0, 64, 64); | |
| } else if(result == 0){ | |
| decision += "LEFT."; | |
| moveX -= 50; | |
| if(moveable) | |
| moveForwardLeft(); | |
| //leftArrow.draw(0,ofGetHeight()/2, 64, 64); | |
| } else if(result == 2){ | |
| decision += "RIGHT."; | |
| moveX += 50; | |
| if(moveable) | |
| moveForwardRight(); | |
| //rightArrow.draw(ofGetWidth()-64,ofGetHeight()/2, 64, 64); | |
| } | |
| ofPushStyle(); | |
| ofSetColor(255); | |
| ofDrawBitmapString(decision, 10, ofGetHeight()-20); | |
| std::cout << "Result: " << decision << std::endl; | |
| ofPopStyle(); | |
| resultReceived = false; | |
| startAgain = true; | |
| } | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::keyPressed(int key){ | |
| if(key == 'N'){ | |
| ofxOscMessage m; | |
| m.setAddress("/end"); | |
| sender.sendMessage(m); | |
| } | |
| //camera refresh | |
| if(key == 'R' || key == 'r') | |
| { | |
| // initialize connection | |
| for(std::size_t i = 0; i < NUM_CAMERAS; i++) | |
| { | |
| ofRemoveListener(grabbers[i]->videoResized, this, &ofApp::videoResized); | |
| SharedIPVideoGrabber c = IPVideoGrabber::makeShared(); | |
| IPCameraDef& cam = getNextCamera(); | |
| c->setUsername(cam.getUsername()); | |
| c->setPassword(cam.getPassword()); | |
| Poco::URI uri(cam.getURL()); | |
| c->setURI(uri); | |
| c->connect(); | |
| grabbers[i] = c; | |
| } | |
| } | |
| if(key == ' ' && !start){ | |
| start = true; | |
| stimTimer1 = clock(); | |
| } | |
| if(key == ' ' && start){ | |
| moveable = true; | |
| } | |
| } | |
| void ofApp::exit(){ | |
| EE_DataFree(hData); | |
| EE_EngineDisconnect(); | |
| EE_EmoStateFree(eState); | |
| EE_EmoEngineEventFree(eEvent); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::camAndSerialUpdate(){ | |
| // update the cameras | |
| for(std::size_t i = 0; i < grabbers.size(); i++) | |
| { | |
| grabbers[i]->update(); | |
| } | |
| //serial | |
| if (bSendSerialMessage){ | |
| // (1) write the letter "a" to serial: | |
| serial.writeByte('a'); | |
| // (2) read | |
| // now we try to read 3 bytes | |
| // since we might not get them all the time 3 - but sometimes 0, 6, or something else, | |
| // we will try to read three bytes, as much as we can | |
| // otherwise, we may have a "lag" if we don't read fast enough | |
| // or just read three every time. now, we will be sure to | |
| // read as much as we can in groups of three... | |
| nTimesRead = 0; | |
| nBytesRead = 0; | |
| int nRead = 0; // a temp variable to keep count per read | |
| unsigned char bytesReturned[3]; | |
| memset(bytesReadString, 0, 4); | |
| memset(bytesReturned, 0, 3); | |
| while( (nRead = serial.readBytes( bytesReturned, 3)) > 0){ | |
| nTimesRead++; | |
| nBytesRead = nRead; | |
| }; | |
| memcpy(bytesReadString, bytesReturned, 3); | |
| bSendSerialMessage = false; | |
| readTime = ofGetElapsedTimef(); | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::camAndSerialDraw(){ | |
| ofBackground(0,0,0); | |
| ofSetHexColor(0xffffff); | |
| int row = 0; | |
| int col = 1; | |
| int x = 64; | |
| int y = 64; | |
| int w = ofGetWidth() - 128 / NUM_COLS; | |
| int h = ofGetHeight() - 64 / NUM_ROWS; | |
| float totalKbps = 0; | |
| float totalFPS = 0; | |
| for(std::size_t i = 0; i < grabbers.size(); i++) | |
| { | |
| ofPushMatrix(); | |
| ofTranslate(x,y); | |
| ofSetColor(255,255,255,255); | |
| grabbers[i]->draw(0,0,w,h); // draw the camera | |
| ofEnableAlphaBlending(); | |
| float kbps = grabbers[i]->getBitRate() / 1000.0f; // kilobits / second, not kibibits / second | |
| totalKbps+=kbps; | |
| float fps = grabbers[i]->getFrameRate(); | |
| totalFPS+=fps; | |
| ofPopMatrix(); | |
| } | |
| // keep track of some totals | |
| float avgFPS = totalFPS / NUM_CAMERAS; | |
| float avgKbps = totalKbps / NUM_CAMERAS; | |
| ofEnableAlphaBlending(); | |
| ofSetColor(255); | |
| // ofToString formatting available in 0072+ | |
| ofDrawBitmapString(" AVG FPS: " + ofToString(avgFPS,2/*,7,' '*/), 10,17); | |
| ofDrawBitmapString("AVG Kb/S: " + ofToString(avgKbps,2/*,7,' '*/), 10,29); | |
| ofDrawBitmapString("TOT Kb/S: " + ofToString(totalKbps,2/*,7,' '*/), 10,41); | |
| string buf; | |
| buf = "listening for osc messages on port" + ofToString(PORT); | |
| ofDrawBitmapString(buf, 10, 53); | |
| ofDisableAlphaBlending(); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::keyReleased(int key){ | |
| if(key == ' ' && start){ | |
| moveable = false; | |
| } | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveForwardLeft(){ | |
| serial.writeByte('q'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveForwardRight(){ | |
| serial.writeByte('e'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveForward(){ | |
| serial.writeByte('w'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveBackwards(){ | |
| serial.writeByte('x'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveBackwardsRight(){ | |
| serial.writeByte('c'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveBackwardsLeft(){ | |
| serial.writeByte('z'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveRight(){ | |
| serial.writeByte('d'); | |
| } | |
| //-------------------------------------------------------------- | |
| void ofApp::moveLeft(){ | |
| serial.writeByte('a'); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment