just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Revision:
0:345b3bc7a0ea
Child:
1:a4050fee11f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Mar 28 14:40:01 2012 +0000
@@ -0,0 +1,473 @@
+#include "mbed.h"
+#include "hardwareIO.h"
+#include "mbedOSC.h"
+#include "blobConfig.h"
+#include "simpleLaserRenderer.h"
+
+extern "C" void mbed_reset();
+
+blobConfig blobconf;
+simpleLaserSensingRenderer lsr;
+
+// For tests:
+DigitalOut myled(LED1);
+DigitalOut myled2(LED2);
+//DigitalOut myled3(LED2);
+
+
+// To test the time it takes for executing one loop in the main program: 
+//#define LOOPTIMECOMPUTE
+
+//----------  ETHERNET / OSC related (in the future, put somewhere else...): -------------------------------------------
+// mbed IP address (server):
+#ifdef DHCP
+EthernetNetIf eth;
+#else
+EthernetNetIf eth(
+  IpAddr(10,0,0,2), //IP Address
+  IpAddr(255,255,255,0), //Network Mask
+  IpAddr(10,0,0,1), //Gateway
+  IpAddr(10,0,0,1)  //DNS
+);
+#endif
+
+//uint8_t serverMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+uint8_t serverIp[]  = { 10, 0, 0, 2 }; // not needed perhaps!
+int  serverPort  = 10000;
+  
+uint8_t destIp[]  = { 10, 0, 0, 1};
+int  destPort = 12000;
+  
+char *topAddress="/mbed";
+char *subAddress[3]={ "/test1" , "/test2" , "/test3" };
+  
+OSCMessage recMes;
+OSCMessage sendMes;
+  
+OSCClass osc;    
+//OSCClass osc(&recMes);  // instantiate OSC communication object, and set the receiver container from the OSC packets  
+ 
+void processOSC(UDPSocketEvent e); 
+// ----------------------------------------------------------------------------------------------------------------------
+
+Ticker timerForRendering;
+Timer measureLoopPeriod;
+
+void  processSerial();
+ 
+int main() {
+    
+    // Initialize the hardware (laser powers, positions...):
+    IO.init();
+
+  // -------------------------------
+  // Set the Ethernet port: 
+  printf("Setting up...\r\n");
+  EthernetErr ethErr = eth.setup();
+  if(ethErr)
+  {
+    printf("Error %d in setup.\r\n", ethErr);
+    return -1;
+  }
+  printf("Setup OK\r\n");
+    
+   //(1) Sending message:
+   // Set IP and Port: 
+   sendMes.setIp( destIp );
+   sendMes.setPort( destPort );
+   // Set data: 
+   // sendMes.setTopAddress(topAddress);
+   
+   //setting osc functionnality:
+   //(2) Receiving: 
+  // recMes.setIp( serverIp ); // not needed?
+   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)
+   osc.begin(serverPort, &processOSC); // binds the upd (osc) messages to an arbitrary listening port ("server" port), and callback function
+   // -------------------------------
+    
+    /* // sending seems not to work right after setting the osc object??
+    wait(1);
+    sendMes.setTopAddress("starting");
+    sendMes.setSubAddress(""); 
+    osc.sendOsc( &sendMes );
+    */
+    
+    // initialize with the desired blob configuration:
+   
+    // Tested modes:
+    //blobconf.oneElasticLoopContractCentral();
+    blobconf.addOneElasticContourFollowing();
+    // Important: first, set the initial position for all the blobs, this will be useful because
+    // when changing modes we can use the previous central position...
+   // blobconf.setInitialPos(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y);
+     
+    
+    // RENRERER (attn: setConfigToRender must be called when the blobconf is set - i.e., the number of blobs and number of points/blob is fixed)
+   lsr.setConfigToRender(&blobconf);
+    
+    // Timer on the rendering function of the oneLoop object: 
+     timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+  //  timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+
+     //==========================================   INFINITE LOOP (in USER PROGRAM CONTEXT) ===================================================================
+   #ifdef LOOPTIMECOMPUTE
+    int timeCounterNum=100000;
+    #endif
+    
+    
+    while(true) {
+      
+      // update config dynamics (this also could be threaded?):
+      blobconf.update();
+      
+      // draw the config (note: each kind of blob renders differently)
+     // blobconf.draw();
+    
+      // COMMUNICATION:
+      // (a) Reading commands:  
+      // Ethernet:
+      Net::poll(); // this will take care of calling processOSC(UDPSocketEvent e) when a new packet arrives.
+    
+      // Serial: 
+      if(pc.readable()>0) processSerial();
+      
+      // (b)Sending Data: // PUT THIS IN AN INTERRUPT OR A TIMER!!! it may be TOO FAST...
+      blobconf.sendConfData();
+      
+      // text:
+      /*
+       sendMes.setTopAddress("/hello"); 
+       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...)
+       int x=(long)10;
+       sendMes.setArgs( "i", &x);
+       osc.sendOsc( &sendMes );
+       */
+       
+#ifdef LOOPTIMECOMPUTE
+      if (timeCounterNum>50000)  myled = 0;
+      //if (timeCounterNum%100==0) blobconf.sendConfData();
+      if (timeCounterNum>100000) {
+      myled = 1;
+      measureLoopPeriod.stop();
+      sendMes.setTopAddress("/timeloop");
+      sendMes.setSubAddress("/"); 
+      long x=(long)(int(measureLoopPeriod.read_us()/100000));     
+      sendMes.setArgs( "i", &x);
+      osc.sendOsc( &sendMes );
+      timeCounterNum=0;
+      measureLoopPeriod.reset();
+      measureLoopPeriod.start();
+      } else timeCounterNum++;
+#endif
+
+    }
+}
+
+ // ================= INTERPRET COMMAND =========================
+// NOTE: the following arrays are GLOBAL (used in processOSC and processSerial, as well as in interpretCommand function):
+ // max of two addresses (top and sub), of a max length of 24 characters:
+char address[2][24];
+//long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
+int data[2]; // this is to have -1 as NO DATA, to detect errors. 
+ 
+//interpretCommand(const char& address[2][], const int& data[2]) {  
+void interpretCommand() {
+    // (I) =========================================== SPECIAL FUNCTIONS (reset, rescan LUT, etc) ====================================================
+    if ( !strcmp(address[0], "takeSnapshot" ) ) { // will reset all the spots, but the 0, and use it for taking measures:
+       
+       // for test:
+       for (int i=0; i<2 ; i++) {
+             myled = 1;  wait(0.1); myled = 0;  wait(0.1);
+             }
+       
+        // First, we need to disable the threaded display for the loop: 
+         timerForRendering.detach(); 
+         
+        // Then, do the scan (sending values on serial port):  
+         IO.scan_serial();
+        
+        // Finally, start again threaded display: 
+         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+        }  
+        
+      else if ( !strcmp(address[0], "mbedReset" ) ) mbed_reset();
+      
+      else if ( !strcmp(address[0], "calibrate" ) ) {
+      // First, we need to disable the threaded display for the loop: 
+         timerForRendering.detach(); 
+       // RESCAN (and save LUT table):
+       IO.scanLUT();
+       // Finally, start again threaded display: 
+         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
+       }
+        
+      // (II) ========================================= GLOBAL CONFIG and HARDWARE COMMANDS ===========================================
+      
+      else if ( !strcmp(address[0], "setGreenLaser" ) ) { 
+       int value=data[0];
+       if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+        if (value==0) IO.setGreenPower(0); else IO.setGreenPower(1); 
+       }
+     } 
+      
+      // SIMPLE BEHAVIOUR MODES (to be read from an XML file in the future): 
+      else if (!strcmp(address[0], "crawling")) { // 
+          timerForRendering.detach(); 
+        // blobconf.computeBoundingBox();
+         blobconf.clearConfig();      
+         blobconf.addOneElasticContourFollowing();
+         lsr.setConfigToRender(&blobconf);        
+        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
+      }
+       else if (!strcmp(address[0], "loop")) { // 
+        timerForRendering.detach();
+        // blobconf.computeBoundingBox();
+         blobconf.clearConfig();  
+         blobconf.addOneElasticLoopContractCentral();
+          lsr.setConfigToRender(&blobconf);
+        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
+      }
+      
+      else if (!strcmp(address[0], "bouncing")) {
+       timerForRendering.detach(); 
+        // blobconf.computeBoundingBox();
+         blobconf.clearConfig(); 
+         blobconf.addOneElasticBouncing();
+          lsr.setConfigToRender(&blobconf);
+        timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
+      }
+      
+      // other: 
+      
+      else if ( !strcmp(address[0], "standby" ) ) { // will put ALL the spots in stand by mode
+        blobconf.allStandBy(); // will avoid the update function
+      }        
+      else if ( !strcmp(address[0], "resume" ) ) { // will put ALL the spots in stand by mode
+        blobconf.allResume(); // will avoid the update function
+      }    
+      
+      // (III) ========================================= Loop control (parameters, etc) =========================================== 
+      // NOte: for the time being, we only have ONE loop, so there is no "per loop or per config" mode.
+      
+      else if (!strcmp( address[0], "sendOSC" ) ) { 
+           int value=data[0];
+           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+               for (int i=0; i< blobconf.numBlobs; i++) {
+                  blobconf.blobArray[i]->sendOSC=(value>0);
+               }
+           }
+     }
+     
+      else if (!strcmp( address[0], "sendArea" ) ) { 
+           int value=data[0];
+           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+               for (int i=0; i< blobconf.numBlobs; i++) {
+                  blobconf.blobArray[i]->sendingBlobArea=(value>0);
+               }
+           }
+     }
+      
+    else if (!strcmp( address[0], "sendPos" ) ) { 
+           int value=data[0];
+           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+               for (int i=0; i< blobconf.numBlobs; i++) {
+                  blobconf.blobArray[i]->sendingLoopPositions=(value>0);
+               }
+           }
+     } 
+     
+     else if (!strcmp( address[0], "sendRegions" ) ) { 
+           int value=data[0];
+           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+               for (int i=0; i< blobconf.numBlobs; i++) {
+                  blobconf.blobArray[i]->sendingLoopRegions=(value>0);
+               }
+           }
+     } 
+     
+     else if (!strcmp( address[0], "sendTouched" ) ) { 
+           int value=data[0];
+           if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
+               for (int i=0; i< blobconf.numBlobs; i++) {
+                  blobconf.blobArray[i]->sendingTouched=(value>0);
+               }
+           }
+     } 
+     
+     
+     
+}
+
+//============= RECEIVE OSC COMMANDS =========================
+// This is the callback function called when there are packets on the listening socket. It is not nice to have it 
+// here, but for the time being having a "wrapping global" is the simplest solution (we cannot pass a member-function pointer 
+// as handler to the upd object).  
+void processOSC(UDPSocketEvent e) {
+    osc.onUDPSocketEvent(e);
+
+    if (osc.newMessage) {
+     // 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 
+     // 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...
+        
+     // Acquire the addresses and arguments and put them in the GLOBAL variables:
+      strcpy(address[0],""); strcpy(address[1],"");
+      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
+      // Acquire data:
+      data[0]=-1;  data[1]=-1; 
+      for (int i=0; i<recMes.getArgNum(); i++) data[i]=(int)recMes.getArgInt(i);
+  
+      // Finally, interpret the command:
+      interpretCommand();//address, data);
+      
+    }
+ }
+ 
+//============= RECEIVE SERIAL COMMANDS =========================
+//
+// NOTE: - NUMERIC PARAMETERS have to be send BEFORE the command word. They must be sent as ASCII DEC, without end character. 
+//       - Commands words SHOULD NOT have numbers in it. They should be C compliant STRINGS (ended with character '0')
+//       - order is irrelevant: we can send 10 RADIUS or RADIUS 10. 
+
+// String to store ALPHANUMERIC DATA (i.e., integers, floating point numbers, unsigned ints, etc represented as DEC) sent wirelessly: 
+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...
+int indexStringData=0;//position of the byte in the string
+
+// String to store COMMAND WORDS:
+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...
+int indexStringCommand=0;
+bool commandReady=false; // will become true when receiving the byte 0 (i.e. the '/0' string terminator)
+
+void processSerial() {
+
+ while(pc.readable()>0){
+        
+       char val =pc.getc();
+        // pc.printf("Got :%d\n", incomingByte);
+         //pc.putc(incomingByte);
+  
+  // Save ASCII numeric characters (ASCII 0 - 9) on stringData:
+    if ((val >= '0') && (val <= '9')){ // this is 45 to 57 (included)
+      stringData[indexStringData] = val;
+      indexStringData++;
+    }
+    
+  // Save ASCII letters in stringCommand:
+    if ((val >= 'A') && (val <= 'z')){ // this is 65 to 122 (included)
+      stringCommand[indexStringCommand] = val;
+      indexStringCommand++;
+    }
+   // is command ready?
+   if (val=='/') {
+     commandReady=true; 
+     stringCommand[indexStringCommand] = 0; // string termination.
+     indexStringCommand=0; // reset index string for acquiring next command
+     //Serial.println(stringCommand);
+   }
+    
+    // COMMANDS (with or without numeric parameters):
+    if (commandReady==true) { // it means we can interpret the command string:
+      commandReady=false;
+     
+      stringData[indexStringData] = 0 ;// string termination for numeric values;
+      indexStringData=0;
+     
+   // PARSE DATA: (TO DO!!!!!!!!!!!!!!): 
+   
+    // (a) Parse command (get address[0] and address[1]):
+    //ex:  "/1/standBy" -- > address[0]="1" and address[1]="standBy"
+    // address[2]
+     
+    // Serial.println(stringCommand);
+    // Serial.println(stringData);
+      
+     // (b) Parse data:
+     
+    // char address[2][24];
+    //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
+    //int data[2]; // this is to have -1 as NO DATA, to detect errors. 
+
+     // FOR THE TIME BEING there is no parsing for serial commands:
+   
+     // SCANNING: 
+      if (!strcmp(stringCommand , "takeSnapshot")) {
+        // First, we need to disable the threaded display for the loop: 
+         timerForRendering.detach(); 
+         
+        // Then, do the scan (sending values on serial port):  
+         IO.scan_serial();
+        
+        // Finally, start again threaded display: 
+         timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
+
+        }
+        
+     if (!strcmp(stringCommand , "REDON"))   IO.setRedPower(1); // pc.printf("%d\n",incomingByte);
+
+     if (!strcmp(stringCommand , "REDOFF"))  IO.setRedPower(0);
+       
+     if  (!strcmp(stringCommand , "READVALUE")) pc.printf("Value read: %f", lockin.getSmoothValue());//lockin.getLastValue());/
+        
+      // FINALLY, interpret commands (but only after parsing): 
+      //  interpretCommand();//address, data);
+      
+    }
+    }
+ }
+ 
+
+
+// ================ MISCELANEA
+
+/* EXAMPLE SEND/RECEIVE on PROCESSING:
+
+// oscP5sendreceive by andreas schlegel
+// example shows how to send and receive osc messages.
+// oscP5 website at http://www.sojamo.de/oscP5
+
+import oscP5.*;
+import netP5.*;
+  
+OscP5 oscP5;
+NetAddress myRemoteLocation;
+
+void setup() {
+  size(400,400);
+  frameRate(25);
+  // start oscP5, listening for incoming messages at port 12000 
+  oscP5 = new OscP5(this,12000);
+  
+  // myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
+  // an ip address and a port number. myRemoteLocation is used as parameter in
+  // oscP5.send() when sending osc packets to another computer, device, 
+  // application. usage see below. for testing purposes the listening port
+  // and the port of the remote location address are the same, hence you will
+  // send messages back to this sketch.
+  myRemoteLocation = new NetAddress("10.0.0.2",10000);
+}
+
+
+void draw() {
+  background(0);  
+}
+
+void mousePressed() {
+  // in the following different ways of creating osc messages are shown by example 
+  OscMessage myMessage = new OscMessage("/mbed/test1");
+  
+  myMessage.add(123); // add an int to the osc message 
+
+  // send the message 
+  oscP5.send(myMessage, myRemoteLocation); 
+}
+
+
+// incoming osc message are forwarded to the oscEvent method. 
+void oscEvent(OscMessage theOscMessage) {
+  // print the address pattern and the typetag of the received OscMessage 
+  print("### received an osc message.");
+  print(" addrpattern: "+theOscMessage.addrPattern());
+  println(" typetag: "+theOscMessage.typetag());
+}
+
+*/
+   
\ No newline at end of file