Alvaro Cassinelli / Mbed 2 deprecated skinGames_forktest

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 */