Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of scoreLight_Advanced by
main.cpp
00001 #include "mbed.h" 00002 #include "hardwareIO.h" 00003 #include "mbedOSC.h" 00004 #include "blobConfig.h" 00005 #include "simpleLaserRenderer.h" 00006 00007 extern "C" void mbed_reset(); 00008 00009 blobConfig blobconf; 00010 simpleLaserSensingRenderer lsr; 00011 00012 // For tests: 00013 DigitalOut myled(LED1); 00014 DigitalOut myled2(LED2); 00015 DigitalOut myled3(LED3); 00016 DigitalOut ledSwitchOne(LED_SWITCH_ONE); 00017 00018 // To test the time it takes for executing one loop in the main program: 00019 //#define LOOPTIMECOMPUTE 00020 00021 // To get serial commands (for debug, or other things using a Terminal - for instance, a laser scan) 00022 #define SERIAL_COMMANDS 00023 00024 int renderFraction=1;// when 1, the blob needs to be rendered completely before update; 2 means half of it, etc. 0 means render all the time. 00025 00026 // NEW (1.4.2014): change modes by switch for fast demos: 00027 int totalNumberDemos=13; 00028 int currentDemoMode=0; 00029 void changeMode(int mode); 00030 00031 //---------- ETHERNET / OSC related (in the future, put somewhere else...): ------------------------------------------- 00032 // mbed IP address (server): 00033 #ifdef DHCP 00034 EthernetNetIf eth; 00035 #else 00036 EthernetNetIf eth( 00037 IpAddr(10,0,0,2), //IP Address of the mbed 00038 IpAddr(255,255,255,0), //Network Mask 00039 IpAddr(10,0,0,1), //Gateway 00040 IpAddr(10,0,0,1) //DNS 00041 ); 00042 #endif 00043 00044 //uint8_t serverMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 00045 uint8_t serverIp[] = { 10, 0, 0, 2 }; // not needed perhaps! 00046 int serverPort = 10000; 00047 00048 //uint8_t destIp[] = {10, 0, 0, 3}; 00049 uint8_t destIp[] = {255, 255, 255, 255}; // broadcast, so we can use several computers for sound, etc 00050 int destPort = 12000; 00051 00052 char *topAddress="/mbed"; 00053 char *subAddress[3]={ "/test1" , "/test2" , "/test3" }; 00054 00055 OSCMessage recMes; 00056 OSCMessage sendMes; 00057 00058 OSCClass osc; 00059 //OSCClass osc(&recMes); // instantiate OSC communication object, and set the receiver container from the OSC packets 00060 00061 void processOSC(UDPSocketEvent e); 00062 // ---------------------------------------------------------------------------------------------------------------------- 00063 00064 // Tickers: 00065 Ticker timerForRendering; 00066 //Ticker timerForSendingData; // better use a timer, so as not to interrupt the exact laser display ticker 00067 00068 // Timers: 00069 Timer measureLoopPeriod; 00070 00071 Timer measureReadPeriod; // timer for reading hardare or communication data (I will read in ms) 00072 #define periodReadingData 30 00073 00074 //Timer measureUpdatePeriod; 00075 00076 00077 // to get serial commands (not necessary perhaps) 00078 void processSerial(); 00079 00080 int main() { 00081 00082 // Initialize the hardware (laser powers, positions...): 00083 IO.init(); 00084 ledSwitchOne=0; 00085 00086 // ------------------------------- 00087 // Set the Ethernet port: 00088 // pc.printf("Setting up...\r\n"); 00089 //printf("Setting up...\r\n"); 00090 EthernetErr ethErr = eth.setup(); 00091 if (ethErr) { 00092 // pc.printf("Error %d in setup.\r\n", ethErr); 00093 // return -1; 00094 } 00095 // pc.printf("Setup OK\r\n"); 00096 00097 //(1) Sending message: 00098 // Set IP and Port: 00099 sendMes.setIp( destIp ); 00100 sendMes.setPort( destPort ); 00101 // Set data: 00102 // sendMes.setTopAddress(topAddress); 00103 00104 //setting osc functionnality: 00105 //(2) Receiving: 00106 // recMes.setIp( serverIp ); // not needed? 00107 osc.setReceiveMessage(&recMes); // this sets the receiver container for the OSC packets (we can avoid doing this if we use osc.getMessage() to get messages) 00108 osc.begin(serverPort, &processOSC); // binds the upd (osc) messages to an arbitrary listening port ("server" port), and callback function 00109 // ------------------------------- 00110 00111 /* // sending seems not to work right after setting the osc object?? 00112 wait(1); 00113 sendMes.setTopAddress("starting"); 00114 sendMes.setSubAddress(""); 00115 osc.sendOsc( &sendMes ); 00116 */ 00117 00118 // initialize with the desired blob configuration: 00119 00120 // blobconf.initConfig(ONE_ELASTIC_FOLLOWING); 00121 00122 // Tested modes: 00123 // blobconf.clearConfig(); 00124 // blobconf.addOneElasticLoopContractCentral(); 00125 00126 // blobconf.addOneElasticContourFollowing(); 00127 00128 // blobconf.addOneRigidLoopBouncing(); 00129 // blobconf.addOneRigidLoopBouncing(); 00130 //blobconf.addOneRigidLoopFollowing(); 00131 // blobconf.addOneRigidLoopFollowing(); 00132 //blobconf.addOneElasticLoopContractCentralFast(); 00133 //blobconf.addOneRigidLoopTest(); 00134 00135 // START WITH TWO FOLLOWING SPOTS (exhibition Tokyo Design Week): 00136 blobconf.initConfig(FOLLOWING_SPOTS, 1); // value is the nb of spots instantiated 00137 // Make them of different color: 00138 //blobconf.blobArray[0]->setBlueColor(1); 00139 //blobconf.blobArray[1]->setGreenColor(1); 00140 00141 // start in no stand by mode: 00142 blobconf.allResume(); 00143 00144 // Important: first, set the initial position for all the blobs, this will be useful because 00145 // when changing modes we can use the previous central position... 00146 // blobconf.setInitialPos(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y); 00147 00148 // draw the config once before activating the laser buffer: 00149 blobconf.draw(); 00150 lsr.startFullDisplay(); 00151 00152 // RENRERER (attn: setConfigToRender must be called when the blobconf is set - i.e., the number of blobs and number of points/blob is fixed) 00153 lsr.setConfigToRender(&blobconf); 00154 00155 // Timer on the rendering function of the oneLoop object: 00156 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds) 00157 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds) 00158 00159 // Timer for sending OSC data: 00160 // timerForSendingData.attach(&blobconf, &blobConfig::sendConfData, 0.025); // time in seconds (25ms -> 40Hz) 00161 00162 //========================================== INFINITE LOOP (in USER PROGRAM CONTEXT) =================================================================== 00163 #ifdef LOOPTIMECOMPUTE 00164 int timeCounterNum=1000; 00165 #endif 00166 00167 //measureUpdatePeriod.start(); 00168 00169 measureReadPeriod.start(); 00170 00171 while (true) { 00172 00173 // Process sensing buffer and compute light forces (for all blobs here, or in the update function for each one) 00174 blobconf.processSensedData(); 00175 00176 if (lsr.endedFractionDisplay(renderFraction)) {// (lsr.endedFullDisplay()) { 00177 00178 // measureUpdatePeriod.stop(); 00179 // measureUpdatePeriod.reset(); 00180 00181 // __disable_irq(); 00182 00183 // update config dynamics (this also could be threaded?): 00184 blobconf.update(); 00185 00186 00187 // draw the config (note: each kind of blob renders differently) 00188 blobconf.draw(); 00189 00190 00191 // (b)Sending Data: // PUT THIS IN AN INTERRUPT OR USE A TIMER!!! it may be TOO FAST... 00192 // NOTE: better use a timer, so the only ISR "ticker" is the laser rendering (otherwise the laser rendering will be interrupted by the sending of data - the other way is ok): 00193 // NOTE: timer for sending is now not COMMON to all blobs, but depends on the blob (it could depend on the CONFIG only, but this can be simulated by using 00194 // per blob timer counter. 00195 blobconf.sendConfData(); 00196 00197 00198 lsr.startFullDisplay(); // this start the point-display counter (wherever the actual laser is). Before update and draw, the counter needs to be reset. 00199 00200 00201 // __enable_irq(); 00202 00203 // measureUpdatePeriod.start(); 00204 00205 } else { 00206 00207 // do a delay to equilibrate the timings? 00208 //wait_us(6700); 00209 } 00210 00211 00212 // COMMUNICATION and HARDWARE CONTROL: 00213 00214 // (a) Reading commands: 00215 if (measureReadPeriod.read_ms()>periodReadingData) { 00216 measureReadPeriod.stop(); 00217 00218 // Ethernet: 00219 Net::poll(); // this will take care of calling processOSC(UDPSocketEvent e) when a new packet arrives. 00220 00221 // Serial: 00222 #ifdef SERIAL_COMMANDS 00223 if (pc.readable()>0) processSerial(); 00224 #endif 00225 00226 // Potentiometer, switches, etc: 00227 //(1) Check for change of threshold mode button (switch one): 00228 //!!! ATTENTION: this does not work very well to say the truth: bouncing+adc settings problems... better use a TWO STATE SWITCH: 00229 bool stateswitch; 00230 if (IO.switchOneCheck(stateswitch)) { 00231 //if (stateswitch) pc.printf("Setting AUTO threshold mode\n"); else pc.printf("Setting FIXED threshold mode\n"); 00232 // for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setThresholdMode((stateswitch? 1 : 0)); 00233 currentDemoMode=(currentDemoMode+1)%totalNumberDemos; 00234 // ledSwitchOne=(stateswitch? 1 :0); // this switch has a built-in led 00235 ledSwitchOne=1; wait_ms(500) ; ledSwitchOne=0; 00236 changeMode(currentDemoMode); 00237 blobconf.allResume(); 00238 } 00239 if (IO.twoStateSwitchCheck(stateswitch)) { // if there is a change... 00240 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setThresholdMode((stateswitch? 1 : 0)); 00241 } 00242 00243 //(2) in case the the second switch was pressed, check the current pot value and update the fixed threshold (regardless of the threshold mode) 00244 // NOTE: using the potentiometer FAILS because I cannot properly switch back and forth between ADC modes (burst and normal) 00245 if (IO.switchTwoCheck(stateswitch)) { 00246 timerForRendering.detach(); 00247 IO.showLimitsMirrors(5); // in seconds 00248 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00249 00250 // IO.updatePotValue(); 00251 // for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setFixedThreshold(IO.potValue); 00252 // pc.printf("Got :%d\n", IO.potValue); 00253 } 00254 00255 if (rotaryEncoder1.CheckNew()) { 00256 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setFixedThreshold(rotaryEncoder1.Get()); 00257 //pc.printf("Fixed Threshold :%d\n", rotaryEncoder1.Get()); 00258 } 00259 00260 // (3) Change additional mirror delay from rotary encoder: 00261 if (rotaryEncoder2.CheckNew()) { 00262 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setDelayMirrors(rotaryEncoder2.Get()); 00263 // pc.printf("Mirror delay :%d\n", rotaryEncoder2.Get()); 00264 } 00265 00266 00267 // Restart the timer: 00268 measureLoopPeriod.reset(); 00269 measureReadPeriod.start(); 00270 } 00271 00272 // text: 00273 /* 00274 sendMes.setTopAddress("/hello"); 00275 sendMes.setSubAddress("/daito"); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...) 00276 int x=(long)10; 00277 sendMes.setArgs( "i", &x); 00278 osc.sendOsc( &sendMes ); 00279 */ 00280 00281 #ifdef LOOPTIMECOMPUTE 00282 if (timeCounterNum>50) myled = 0; 00283 // if (timeCounterNum%10==0) blobconf.sendConfData(); 00284 if (timeCounterNum>1000) { 00285 myled = 1; 00286 measureLoopPeriod.stop(); 00287 sendMes.setTopAddress("/timeloop"); 00288 sendMes.setSubAddress("/"); 00289 long x=(long)(int(measureLoopPeriod.read_us()/1000.0)); 00290 // long x=(long)(blobconf.blobArray[0]->displaySensingBuffer.lsdTrajectory.size()); 00291 // long x=(long)(blobconf.blobArray[0]->normRecenteringVector); 00292 //long x=(long)(1000*blobconf.blobArray[0]->displaySensingBuffer.lsdTrajectory[0].intensity); 00293 sendMes.setArgs( "i", &x); 00294 osc.sendOsc( &sendMes ); 00295 timeCounterNum=0; 00296 measureLoopPeriod.reset(); 00297 measureLoopPeriod.start(); 00298 } else timeCounterNum++; 00299 #endif 00300 00301 } 00302 } 00303 00304 // ================= INTERPRET COMMAND ========================= 00305 // NOTE: the following arrays are GLOBAL (used in processOSC and processSerial, as well as in interpretCommand function): 00306 // max of two addresses (top and sub), of a max length of 24 characters: 00307 char address[2][24]; 00308 //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs) 00309 int data[2]; // this is to have -1 as NO DATA, to detect errors. 00310 00311 //interpretCommand(const char& address[2][], const int& data[2]) { 00312 void interpretCommand() { 00313 // (I) =========================================== SPECIAL FUNCTIONS (reset, rescan LUT, etc) ==================================================== 00314 if ( !strcmp(address[0], "takeSnapshot" ) ) { 00315 int value=data[0]; 00316 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00317 00318 // for test: 00319 for (int i=0; i<2 ; i++) { 00320 myled = 1; 00321 wait(0.1); 00322 myled = 0; 00323 wait(0.1); 00324 } 00325 00326 // First, we need to disable the threaded display for the loop: 00327 timerForRendering.detach(); 00328 00329 // Then, do the scan (sending values on SERIAL port): 00330 IO.scan_serial(value); 00331 00332 // Finally, start again threaded display: 00333 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00334 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00335 00336 } 00337 } 00338 00339 else if ( !strcmp(address[0], "mbedReset" ) ) mbed_reset(); 00340 00341 else if (!strcmp(address[0], "showMirrorLimits")) { 00342 int value=data[0]; 00343 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00344 timerForRendering.detach(); 00345 IO.showLimitsMirrors(value); 00346 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00347 } 00348 } 00349 00350 else if ( !strcmp(address[0], "calibrate" ) ) { 00351 // First, we need to disable the threaded display for the loop: 00352 timerForRendering.detach(); 00353 // RESCAN (and save LUT table): 00354 IO.scanLUT(); 00355 // Finally, start again threaded display: 00356 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00357 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00358 } 00359 00360 // (II) ========================================= GLOBAL CONFIG and HARDWARE COMMANDS =========================================== 00361 00362 else if ( !strcmp(address[0], "setAllColor" ) ) { 00363 int value=data[0]; // this is the color (RGB bits) 00364 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00365 blobconf.allSetColor(value); 00366 } 00367 } 00368 00369 else if ( !strcmp(address[0], "setAllRandomColor" ) ) { 00370 blobconf.randomizeAllColors(); 00371 } 00372 00373 else if ( !strcmp(address[0], "setAllGreenColor" ) ) { 00374 int value=data[0]; 00375 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00376 if (value==0) 00377 blobconf.allSetGreen(1); 00378 else 00379 blobconf.allSetGreen(0); 00380 } 00381 } 00382 00383 else if ( !strcmp(address[0], "setAllBlueColor" ) ) { 00384 int value=data[0]; 00385 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00386 if (value==0) 00387 blobconf.allSetBlue(1); 00388 else 00389 blobconf.allSetBlue(0); 00390 } 00391 } 00392 00393 // NOTE: RED either afect the lock in, or some other red laser... not yet done. 00394 00395 else if ( !strcmp(address[0], "testPower" ) ) { 00396 // First, we need to disable the threaded display for the loop: 00397 timerForRendering.detach(); 00398 00399 // Note: arguments is first 3 bits to set the laser powers (3 LSB bits to set each color) 00400 // and then the second argument is the number of seconds to wait for the measurment 00401 int value1=data[0], value2=data[1]; 00402 if ((value1!=-1)&&(value2!=-1)) { // otherwise do nothing, this is a reception error (there was no data) 00403 00404 // Set position of mirrors: 00405 IO.writeOutX(CENTER_AD_MIRROR_X); 00406 IO.writeOutY(CENTER_AD_MIRROR_Y); 00407 00408 for (int i=0; i<3 ; i++) { 00409 myled3 = 1; 00410 wait(0.2); 00411 myled3 = 0; 00412 wait(0.2); 00413 } 00414 00415 // Set laser power: 00416 IO.setRGBPower((unsigned char)value1); 00417 00418 // Wait... 00419 wait(value2);// in seconds 00420 //Timer t; 00421 //t.start(); 00422 //while(t.read_ms()<value2*1000); 00423 //t.stop(); 00424 } 00425 00426 // Finally, start again threaded display: 00427 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00428 00429 } 00430 00431 00432 00433 // SIMPLE BEHAVIOUR MODES (to be read from an XML file in the future): 00434 else if (!strcmp(address[0], "elastic_following")) { // 00435 timerForRendering.detach(); 00436 00437 blobconf.initConfig(ONE_ELASTIC_FOLLOWING); 00438 00439 lsr.setConfigToRender(&blobconf); 00440 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00441 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00442 00443 } 00444 00445 else if (!strcmp(address[0], "elastic_mouth")) { // 00446 timerForRendering.detach(); 00447 00448 blobconf.initConfig(ONE_ELASTIC_MOUTH); 00449 00450 lsr.setConfigToRender(&blobconf); 00451 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00452 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00453 00454 } else if (!strcmp(address[0], "elastic_mouth_small")) { // 00455 timerForRendering.detach(); 00456 00457 blobconf.initConfig(ONE_ELASTIC_MOUTH_SMALL); 00458 00459 lsr.setConfigToRender(&blobconf); 00460 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00461 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00462 } 00463 else if (!strcmp(address[0], "spot_bouncing")) { 00464 int value=data[0]; 00465 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00466 timerForRendering.detach(); 00467 00468 blobconf.initConfig(BOUNCING_SPOTS, value); // value is the nb of spots instantiated 00469 00470 lsr.setConfigToRender(&blobconf); 00471 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00472 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00473 } 00474 } 00475 00476 else if (!strcmp(address[0], "spot_lorentz")) { 00477 int value=data[0]; 00478 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00479 timerForRendering.detach(); 00480 00481 blobconf.initConfig(LORENTZ_SPOTS, value); // value is the nb of spots instantiated 00482 00483 lsr.setConfigToRender(&blobconf); 00484 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00485 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00486 } 00487 } 00488 00489 else if (!strcmp(address[0], "air_hockey")) { 00490 int value=data[0]; 00491 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00492 timerForRendering.detach(); 00493 00494 blobconf.initConfig(AIR_HOCKEY_GAME, value); // value is the nb of spots instantiated 00495 00496 lsr.setConfigToRender(&blobconf); 00497 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00498 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00499 } 00500 } 00501 00502 else if (!strcmp(address[0], "rain_mode")) { 00503 int value=data[0]; 00504 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00505 timerForRendering.detach(); 00506 00507 blobconf.initConfig(RAIN_MODE, value); // value is the nb of spots instantiated 00508 00509 lsr.setConfigToRender(&blobconf); 00510 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00511 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00512 } 00513 } 00514 00515 00516 else if (!strcmp(address[0], "spot_following")) { 00517 int value=data[0]; 00518 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00519 00520 timerForRendering.detach(); 00521 00522 blobconf.initConfig(FOLLOWING_SPOTS, value); // value is the nb of spots instantiated 00523 00524 lsr.setConfigToRender(&blobconf); 00525 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00526 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00527 00528 if ( blobconf.numBlobs>1) 00529 for (int i=0; i< blobconf.numBlobs; i++) { 00530 blobconf.blobArray[i]->displaySensingBuffer.setDelayMirrors(2); 00531 blobconf.blobArray[i]->angleCorrectionForceLoop=-8;// in degrees 00532 } 00533 } 00534 } 00535 00536 else if (!strcmp(address[0], "circular_pong")) { 00537 int value=data[0]; 00538 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00539 00540 timerForRendering.detach(); 00541 00542 blobconf.initConfig(CIRCULAR_PONG_GAME, value); // value is the nb of spots instantiated 00543 00544 lsr.setConfigToRender(&blobconf); 00545 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00546 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00547 } 00548 } 00549 00550 else if (!strcmp(address[0], "fish_net")) { 00551 int value=data[0]; 00552 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00553 00554 timerForRendering.detach(); 00555 00556 blobconf.initConfig(FISH_NET_GAME, value); // value is the nb of spots instantiated 00557 00558 lsr.setConfigToRender(&blobconf); 00559 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00560 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00561 } 00562 } 00563 00564 else if (!strcmp(address[0], "vertical_pinball")) { 00565 int value=data[0]; 00566 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00567 00568 timerForRendering.detach(); 00569 00570 blobconf.initConfig(VERTICAL_PINBALL_GAME, value); 00571 00572 lsr.setConfigToRender(&blobconf); 00573 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00574 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00575 } 00576 } 00577 00578 else if (!strcmp(address[0], "pac_man")) { 00579 timerForRendering.detach(); 00580 00581 blobconf.initConfig(PAC_MAN_GAME); 00582 00583 lsr.setConfigToRender(&blobconf); 00584 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00585 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00586 } 00587 00588 else if (!strcmp(address[0], "spot_tracking")) { 00589 timerForRendering.detach(); 00590 00591 blobconf.initConfig(ONE_TRACKING_SPOT); // value is the nb of spots instantiated 00592 00593 lsr.setConfigToRender(&blobconf); 00594 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00595 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00596 } 00597 00598 else if (!strcmp(address[0], "spot_test")) { 00599 timerForRendering.detach(); 00600 // blobconf.computeBoundingBox(); 00601 blobconf.clearConfig(); 00602 blobconf.addOneRigidLoopTest(); 00603 lsr.setConfigToRender(&blobconf); 00604 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00605 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00606 } 00607 00608 // other: 00609 00610 else if ( !strcmp(address[0], "standby" ) ) { // will put ALL the blobs in stand by mode (no update function) 00611 blobconf.allStandBy(); // will avoid the update function 00612 } 00613 else if ( !strcmp(address[0], "resume" ) ) { 00614 blobconf.allResume(); // Update function is called for all the blobs 00615 } 00616 00617 // (III) ========================================= Loop control (parameters, etc) =========================================== 00618 00619 else if (!strcmp( address[0], "setSpeed" ) ) { 00620 int value=data[0]; // value 1 means a speed of 0.1, value 10, a speed of 1, etc. 00621 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00622 for (int i=0; i< blobconf.numBlobs; i++) { 00623 //if ((!strcmp(blobconf.blobArray[i].spotName, "rigid_following"))||(!strcmp(blobconf.blobArray[i].spotName, "rigid_following"))) { 00624 blobconf.blobArray[i]->setSpeed((float)(0.1*value)); 00625 } 00626 } 00627 } 00628 else if (!strcmp( address[0], "speedFactor" ) ) { 00629 int value=data[0]; // value 100 means no change of speed. 200 is twice as fast, 50 is half as fast. 00630 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00631 for (int i=0; i< blobconf.numBlobs; i++) { 00632 //if ((!strcmp(blobconf.blobArray[i].spotName, "rigid_following"))||(!strcmp(blobconf.blobArray[i].spotName, "rigid_following"))) { 00633 blobconf.blobArray[i]->speedFactor((float)(1.0*value/100.0)); 00634 } 00635 } 00636 } 00637 00638 else if (!strcmp( address[0], "setSize" ) ) { 00639 int value=data[0]; // this is the direct size of the scafold 00640 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00641 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->setSize((float)(1.0*value)); 00642 } 00643 } 00644 else if (!strcmp( address[0], "sizeFactor" ) ) { 00645 int value=data[0]; // value 100 means no change of sice. 200 is twice as big, 50 is half as big. 00646 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00647 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->sizeFactor((float)(1.0*value/100.0)); 00648 } 00649 } 00650 00651 // ADJUST MIRROR ANGLE CORRECTION: 00652 else if (!strcmp( address[0], "adjustPlusAngle" ) ) { 00653 int value=data[0]; // this is not a factor, but an additive quantity to the current delay 00654 if (value!=-1) // otherwise do nothing, this is a reception error (there was no data) 00655 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->addAngleCorrection(value); 00656 } 00657 else if (!strcmp( address[0], "adjustMinusAngle" ) ) { 00658 int value=data[0]; // this is not a factor, but an substractive quantity to the current delay 00659 if (value!=-1) // otherwise do nothing, this is a reception error (there was no data) 00660 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->addAngleCorrection(-value); 00661 } 00662 00663 // ADJUST MIRROR DELAY (angle or mirror delay are equivalent in case of circular blobs): 00664 else if (!strcmp( address[0], "adjustPlusDelay" ) ) { 00665 int value=data[0]; // value 100 means no change of speed. 200 is twice as fast, 50 is half as fast. 00666 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00667 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.addDelayMirrors(value); 00668 } 00669 } 00670 else if (!strcmp( address[0], "adjustMinusDelay" ) ) { 00671 int value=data[0]; // value 100 means no change of speed. 200 is twice as fast, 50 is half as fast. 00672 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00673 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.addDelayMirrors(-value); 00674 } 00675 } 00676 00677 else if (!strcmp( address[0], "adjustRenderFraction" ) ) { // for all spots... 00678 int value=data[0]; // value 100 means no change of speed. 200 is twice as fast, 50 is half as fast. 00679 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00680 renderFraction=value; 00681 if (renderFraction>lsr.configTotalPoints) renderFraction=0;// update ALL the time (per-point) 00682 if (renderFraction<1) renderFraction=1; 00683 } 00684 } 00685 00686 else if (!strcmp( address[0], "adjustPlusRenderFraction" ) ) { 00687 int value=data[0]; // value 100 means no change of speed. 200 is twice as fast, 50 is half as fast. 00688 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00689 renderFraction+=value; 00690 if (renderFraction>lsr.configTotalPoints) renderFraction=0;// meaning: update ALL the time (per-point) 00691 } 00692 } 00693 00694 else if (!strcmp( address[0], "adjustMinusRenderFraction" ) ) { 00695 int value=data[0]; // value 100 means no change of speed. 200 is twice as fast, 50 is half as fast. 00696 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00697 renderFraction=((renderFraction-value)>=1? renderFraction-value : 1); 00698 } 00699 } 00700 00701 00702 00703 // THRESHOLD MODE, and PARAMETERS: 00704 //(1) Set the threshold mode: 00705 else if (!strcmp( address[0], "autoThreshold" ) ) { 00706 int value=data[0]; // 1 (auto) or 0 (fixed) 00707 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00708 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setThresholdMode(value); 00709 } 00710 // set led and switch state (global value of threshold): 00711 IO.setSwitchOneState(value>0); 00712 } 00713 00714 // (a) AUTO THRESHOLD: 00715 // MINIMUM CONTRAST RATIO: 00716 // (1) using multiplicative factor: 00717 else if (!strcmp( address[0], "adjustMultContrast" ) ) { 00718 int value=data[0]; // value 100 means no change of the current contrast value. 200 means a min contrast 00719 // that is twice as large and 50 is half as large as before. 00720 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00721 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.multMinContrastRatio((float)(1.0*value/100.0)); 00722 } 00723 } 00724 // (2) directly: 00725 else if (!strcmp( address[0], "adjustContrast" ) ) { 00726 int value=data[0]; // value is in PERCENT (100=1, 50 = 0.5...) 00727 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00728 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setMinContrastRatio((float)(1.0*value/100.0)); 00729 } 00730 } 00731 // THRESHOLD FACTOR: 00732 //(1) using multiplicative factor: 00733 else if (!strcmp( address[0], "adjustMultThreshold" ) ) { 00734 int value=data[0]; // value 100 means no change of the current contrast value. 200 means a min contrast 00735 // that is twice as large and 50 is half as large as before. 00736 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00737 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.multThresholdFactor((float)(1.0*value/100.0)); 00738 } 00739 } 00740 //(2) directly: 00741 else if (!strcmp( address[0], "adjustThresholdFactor" ) ) { 00742 int value=data[0]; // value is in PERCENT (100=1, 50 = 0.5...) 00743 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00744 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setThresholdFactor((float)(1.0*value/100.0)); 00745 } 00746 } 00747 // MINIMUM ACCEPTABLE INTENSITY: 00748 // Adjust minimum acceptable intensity: 00749 else if (!strcmp( address[0], "adjustMinAcceptableIntensity" ) ) { 00750 int value=data[0]; // value is DIRECT value (0 to 255) 00751 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00752 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setMinAcceptableIntensity(value); 00753 } 00754 } 00755 00756 // (b) FIXED THRESHOLD: 00757 // Adjust fixedThreshold (directly): 00758 else if (!strcmp( address[0], "adjustFixedThreshold" ) ) { 00759 int value=data[0]; // value is DIRECT value (0 to 255) 00760 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00761 for (int i=0; i< blobconf.numBlobs; i++) blobconf.blobArray[i]->displaySensingBuffer.setFixedThreshold(value); 00762 } 00763 } 00764 00765 else if (!strcmp( address[0], "printParameters" ) ) { 00766 pc.printf("Fraction display for the config: %d\n", renderFraction); 00767 blobconf.printParameters(); 00768 } 00769 00770 // ===================== SEND DATA MODES ======================= 00771 00772 else if (!strcmp( address[0], "sendOSC" ) ) { 00773 int value=data[0]; 00774 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00775 for (int i=0; i< blobconf.numBlobs; i++) { 00776 blobconf.blobArray[i]->sendOSC=(value>0); 00777 } 00778 } 00779 } 00780 00781 else if (!strcmp( address[0], "sendArea" ) ) { 00782 int value=data[0]; 00783 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00784 for (int i=0; i< blobconf.numBlobs; i++) { 00785 blobconf.blobArray[i]->sendingBlobArea=(value>0); 00786 } 00787 } 00788 } 00789 00790 else if (!strcmp( address[0], "sendPos" ) ) { 00791 int value=data[0]; 00792 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00793 for (int i=0; i< blobconf.numBlobs; i++) { 00794 blobconf.blobArray[i]->sendingLoopPositions=(value>0); 00795 } 00796 } 00797 } 00798 00799 else if (!strcmp( address[0], "sendRegions" ) ) { 00800 int value=data[0]; 00801 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00802 for (int i=0; i< blobconf.numBlobs; i++) { 00803 blobconf.blobArray[i]->sendingLoopRegions=(value>0); 00804 } 00805 } 00806 } 00807 00808 else if (!strcmp( address[0], "sendTouched" ) ) { 00809 int value=data[0]; 00810 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data) 00811 for (int i=0; i< blobconf.numBlobs; i++) { 00812 blobconf.blobArray[i]->sendingTouched=(value>0); 00813 } 00814 } 00815 } 00816 00817 00818 00819 } 00820 00821 //============= RECEIVE OSC COMMANDS ========================= 00822 // This is the callback function called when there are packets on the listening socket. It is not nice to have it 00823 // here, but for the time being having a "wrapping global" is the simplest solution (we cannot pass a member-function pointer 00824 // as handler to the upd object). 00825 void processOSC(UDPSocketEvent e) { 00826 osc.onUDPSocketEvent(e); 00827 00828 if (osc.newMessage) { 00829 // in fact, there is no need to check this if using the method of a global callback function - it is clear this is a new packet... however, it may be 00830 // interesting to use a timer, and process data (answers, etc) only after a certain amount of time, so as to avoid blocking the program in IRQ context... 00831 00832 // Acquire the addresses and arguments and put them in the GLOBAL variables: 00833 strcpy(address[0],""); 00834 strcpy(address[1],""); 00835 for (int i=0; i<recMes.getAddressNum(); i++) strcpy(address[i],recMes.getAddress(i)); // NOTE: up to the rest of the program to check if address[1] is really not null 00836 // Acquire data: 00837 data[0]=-1; 00838 data[1]=-1; 00839 for (int i=0; i<recMes.getArgNum(); i++) data[i]=(int)recMes.getArgInt(i); 00840 00841 // Finally, interpret the command: 00842 interpretCommand();//address, data); 00843 00844 } 00845 } 00846 00847 //============= RECEIVE SERIAL COMMANDS ========================= 00848 // 00849 // NOTE: - NUMERIC PARAMETERS have to be send BEFORE the command word. They must be sent as ASCII DEC, without end character. 00850 // - Commands words SHOULD NOT have numbers in it. They should be C compliant STRINGS (ended with character '0') 00851 // - order is irrelevant: we can send 10 RADIUS or RADIUS 10. 00852 00853 // String to store ALPHANUMERIC DATA (i.e., integers, floating point numbers, unsigned ints, etc represented as DEC) sent wirelessly: 00854 char stringData[24]; // note: an integer is two bytes long, represented with a maximum of 5 digits, but we may send floats or unsigned int... 00855 int indexStringData=0;//position of the byte in the string 00856 00857 // String to store COMMAND WORDS: 00858 char stringCommand[24]; // note: an integer is two bytes long, represented with a maximum of 5 digits, but we may send floats or unsigned int... 00859 int indexStringCommand=0; 00860 bool commandReady=false; // will become true when receiving the byte 0 (i.e. the '/0' string terminator) 00861 00862 void processSerial() { 00863 00864 while (pc.readable()>0) { 00865 00866 00867 char val =pc.getc(); 00868 // pc.printf("Got :%d\n", incomingByte); 00869 //pc.putc(incomingByte); 00870 00871 // Save ASCII numeric characters (ASCII 0 - 9) on stringData: 00872 if ((val >= '0') && (val <= '9')) { // this is 45 to 57 (included) 00873 stringData[indexStringData] = val; 00874 indexStringData++; 00875 } 00876 00877 // Save ASCII letters in stringCommand: 00878 if ((val >= 'A') && (val <= 'z')) { // this is 65 to 122 (included) 00879 stringCommand[indexStringCommand] = val; 00880 indexStringCommand++; 00881 } 00882 // is command ready? 00883 if (val=='/') { 00884 commandReady=true; 00885 stringCommand[indexStringCommand] = 0; // string termination. 00886 indexStringCommand=0; // reset index string for acquiring next command 00887 //Serial.println(stringCommand); 00888 } 00889 00890 // COMMANDS (with or without numeric parameters): 00891 if (commandReady==true) { // it means we can interpret the command string: 00892 commandReady=false; 00893 00894 stringData[indexStringData] = 0 ;// string termination for numeric values; 00895 indexStringData=0; 00896 00897 // PARSE DATA: (TO DO!!!!!!!!!!!!!!): 00898 00899 // (a) Parse command (get address[0] and address[1]): 00900 //ex: "/1/standBy" -- > address[0]="1" and address[1]="standBy" 00901 // address[2] 00902 00903 // Serial.println(stringCommand); 00904 // Serial.println(stringData); 00905 00906 // (b) Parse data: 00907 00908 // char address[2][24]; 00909 //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs) 00910 //int data[2]; // this is to have -1 as NO DATA, to detect errors. 00911 00912 // FOR THE TIME BEING there is no parsing for serial commands: 00913 00914 // SCANNING: 00915 if (!strcmp(stringCommand , "takeSnapshot")) { 00916 // First, we need to disable the threaded display for the loop: 00917 timerForRendering.detach(); 00918 00919 // Then, do the scan (sending values on serial port): 00920 IO.scan_serial(atoi(stringData)); 00921 00922 // Finally, start again threaded display: 00923 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00924 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00925 } else if (!strcmp(stringCommand , "REDON")) IO.setRedPower(1); // pc.printf("%d\n",incomingByte); 00926 00927 else if (!strcmp(stringCommand , "REDOFF")) IO.setRedPower(0); 00928 00929 else if (!strcmp(stringCommand , "READVALUE")) pc.printf("Value read: %f", lockin.getSmoothValue());//lockin.getLastValue());/ 00930 00931 else if (!strcmp(stringCommand , "mbedReset")) mbed_reset(); 00932 00933 else if (!strcmp(stringCommand , "calibrate")) { 00934 // First, we need to disable the threaded display for the loop: 00935 timerForRendering.detach(); 00936 // RESCAN (and save LUT table): 00937 IO.scanLUT(); 00938 // Finally, start again threaded display: 00939 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); 00940 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); 00941 } 00942 00943 // FINALLY, interpret commands (but only after parsing): 00944 // interpretCommand();//address, data); 00945 00946 } 00947 } 00948 } 00949 00950 void changeMode(int mode) { 00951 00952 strcpy(address[0],""); 00953 strcpy(address[1],""); 00954 data[0]=-1; 00955 data[1]=-1; 00956 00957 switch(mode) { 00958 case 0: 00959 strcpy(address[0],"spot_following"); 00960 data[0]=1; 00961 interpretCommand(); 00962 break; 00963 case 1: 00964 strcpy(address[0],"spot_following"); 00965 data[0]=2; 00966 interpretCommand(); 00967 break; 00968 case 2: 00969 strcpy(address[0],"spot_bouncing"); 00970 data[0]=1; 00971 interpretCommand(); 00972 break; 00973 case 3: 00974 strcpy(address[0],"spot_bouncing"); 00975 data[0]=4; 00976 interpretCommand(); 00977 break; 00978 case 4: 00979 strcpy(address[0],"spot_lorentz"); 00980 data[0]=1; 00981 interpretCommand(); 00982 break; 00983 case 5: 00984 strcpy(address[0],"spot_lorentz"); 00985 data[0]=2; 00986 interpretCommand(); 00987 break; 00988 case 6: 00989 strcpy(address[0],"rain_mode"); 00990 data[0]=2; 00991 interpretCommand(); 00992 break; 00993 case 7: 00994 strcpy(address[0],"rain_mode"); 00995 data[0]=5; 00996 interpretCommand(); 00997 break; 00998 case 8: 00999 strcpy(address[0],"air_hockey"); 01000 data[0]=1; 01001 interpretCommand(); 01002 break; 01003 case 9: 01004 strcpy(address[0],"spot_tracking"); 01005 data[0]=1; 01006 interpretCommand(); 01007 // here, let's make the min contrast smaller, for finger tracking: 01008 strcpy(address[0],"adjustContrast"); 01009 data[0]=120; 01010 interpretCommand(); 01011 break; 01012 case 10: 01013 strcpy(address[0],"elastic_mouth"); 01014 interpretCommand(); 01015 break; 01016 case 11: 01017 strcpy(address[0],"elastic_following"); 01018 interpretCommand(); 01019 break; 01020 case 12: 01021 strcpy(address[0],"elastic_mouth_small"); 01022 interpretCommand(); 01023 break; 01024 //case 9: 01025 //strcpy(address[0],"pac_man"); 01026 //interpretCommand(); 01027 //break; 01028 //case 10: 01029 // strcpy(address[0],"circular_pong"); 01030 // data[0]=3; 01031 // interpretCommand(); 01032 //break; 01033 // case 10: 01034 // strcpy(address[0],"vertical_pinball"); 01035 // data[0]=2; 01036 // interpretCommand(); 01037 //pbreak; 01038 //case 11: 01039 //strcpy(address[0],"fish_net"); 01040 // data[0]=3; 01041 // interpretCommand(); 01042 //break; 01043 01044 } 01045 01046 } 01047 01048 01049 01050 // ================ MISCELANEA 01051 01052 /* EXAMPLE SEND/RECEIVE on PROCESSING: 01053 01054 // oscP5sendreceive by andreas schlegel 01055 // example shows how to send and receive osc messages. 01056 // oscP5 website at http://www.sojamo.de/oscP5 01057 01058 import oscP5.*; 01059 import netP5.*; 01060 01061 OscP5 oscP5; 01062 NetAddress myRemoteLocation; 01063 01064 void setup() { 01065 size(400,400); 01066 frameRate(25); 01067 // start oscP5, listening for incoming messages at port 12000 01068 oscP5 = new OscP5(this,12000); 01069 01070 // myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters, 01071 // an ip address and a port number. myRemoteLocation is used as parameter in 01072 // oscP5.send() when sending osc packets to another computer, device, 01073 // application. usage see below. for testing purposes the listening port 01074 // and the port of the remote location address are the same, hence you will 01075 // send messages back to this sketch. 01076 myRemoteLocation = new NetAddress("10.0.0.2",10000); 01077 } 01078 01079 01080 void draw() { 01081 background(0); 01082 } 01083 01084 void mousePressed() { 01085 // in the following different ways of creating osc messages are shown by example 01086 OscMessage myMessage = new OscMessage("/mbed/test1"); 01087 01088 myMessage.add(123); // add an int to the osc message 01089 01090 // send the message 01091 oscP5.send(myMessage, myRemoteLocation); 01092 } 01093 01094 01095 // incoming osc message are forwarded to the oscEvent method. 01096 void oscEvent(OscMessage theOscMessage) { 01097 // print the address pattern and the typetag of the received OscMessage 01098 print("### received an osc message."); 01099 print(" addrpattern: "+theOscMessage.addrPattern()); 01100 println(" typetag: "+theOscMessage.typetag()); 01101 } 01102 01103 */
Generated on Tue Jul 12 2022 18:50:27 by
1.7.2
