Laser Sensing Display for UI interfaces in the real world

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Tue Apr 10 10:45:16 2012 +0000
Revision:
8:5816bb17536b
Parent:
7:0df17f3078bc
Child:
9:3321170d157c
ca marche, mais je vais maintenant appliquer un flag sur la routine d'affichage pour permettre (ou pas) l'update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 0:345b3bc7a0ea 1 #include "mbed.h"
mbedalvaro 0:345b3bc7a0ea 2 #include "hardwareIO.h"
mbedalvaro 0:345b3bc7a0ea 3 #include "mbedOSC.h"
mbedalvaro 0:345b3bc7a0ea 4 #include "blobConfig.h"
mbedalvaro 0:345b3bc7a0ea 5 #include "simpleLaserRenderer.h"
mbedalvaro 0:345b3bc7a0ea 6
mbedalvaro 0:345b3bc7a0ea 7 extern "C" void mbed_reset();
mbedalvaro 0:345b3bc7a0ea 8
mbedalvaro 0:345b3bc7a0ea 9 blobConfig blobconf;
mbedalvaro 0:345b3bc7a0ea 10 simpleLaserSensingRenderer lsr;
mbedalvaro 0:345b3bc7a0ea 11
mbedalvaro 0:345b3bc7a0ea 12 // For tests:
mbedalvaro 0:345b3bc7a0ea 13 DigitalOut myled(LED1);
mbedalvaro 0:345b3bc7a0ea 14 DigitalOut myled2(LED2);
mbedalvaro 0:345b3bc7a0ea 15 //DigitalOut myled3(LED2);
mbedalvaro 0:345b3bc7a0ea 16
mbedalvaro 0:345b3bc7a0ea 17
mbedalvaro 1:a4050fee11f7 18 // To test the time it takes for executing one loop in the main program:
mbedalvaro 7:0df17f3078bc 19 //#define LOOPTIMECOMPUTE
mbedalvaro 1:a4050fee11f7 20
mbedalvaro 1:a4050fee11f7 21 // To get serial commands (for debug, or other things using a Terminal - for instance, a laser scan)
mbedalvaro 1:a4050fee11f7 22 //#define SERIAL_COMMANDS
mbedalvaro 0:345b3bc7a0ea 23
mbedalvaro 0:345b3bc7a0ea 24 //---------- ETHERNET / OSC related (in the future, put somewhere else...): -------------------------------------------
mbedalvaro 0:345b3bc7a0ea 25 // mbed IP address (server):
mbedalvaro 0:345b3bc7a0ea 26 #ifdef DHCP
mbedalvaro 0:345b3bc7a0ea 27 EthernetNetIf eth;
mbedalvaro 0:345b3bc7a0ea 28 #else
mbedalvaro 0:345b3bc7a0ea 29 EthernetNetIf eth(
mbedalvaro 1:a4050fee11f7 30 IpAddr(10,0,0,2), //IP Address
mbedalvaro 1:a4050fee11f7 31 IpAddr(255,255,255,0), //Network Mask
mbedalvaro 1:a4050fee11f7 32 IpAddr(10,0,0,1), //Gateway
mbedalvaro 1:a4050fee11f7 33 IpAddr(10,0,0,1) //DNS
mbedalvaro 0:345b3bc7a0ea 34 );
mbedalvaro 0:345b3bc7a0ea 35 #endif
mbedalvaro 0:345b3bc7a0ea 36
mbedalvaro 0:345b3bc7a0ea 37 //uint8_t serverMac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
mbedalvaro 0:345b3bc7a0ea 38 uint8_t serverIp[] = { 10, 0, 0, 2 }; // not needed perhaps!
mbedalvaro 0:345b3bc7a0ea 39 int serverPort = 10000;
mbedalvaro 1:a4050fee11f7 40
mbedalvaro 0:345b3bc7a0ea 41 uint8_t destIp[] = { 10, 0, 0, 1};
mbedalvaro 0:345b3bc7a0ea 42 int destPort = 12000;
mbedalvaro 1:a4050fee11f7 43
mbedalvaro 0:345b3bc7a0ea 44 char *topAddress="/mbed";
mbedalvaro 0:345b3bc7a0ea 45 char *subAddress[3]={ "/test1" , "/test2" , "/test3" };
mbedalvaro 1:a4050fee11f7 46
mbedalvaro 0:345b3bc7a0ea 47 OSCMessage recMes;
mbedalvaro 0:345b3bc7a0ea 48 OSCMessage sendMes;
mbedalvaro 1:a4050fee11f7 49
mbedalvaro 1:a4050fee11f7 50 OSCClass osc;
mbedalvaro 1:a4050fee11f7 51 //OSCClass osc(&recMes); // instantiate OSC communication object, and set the receiver container from the OSC packets
mbedalvaro 1:a4050fee11f7 52
mbedalvaro 1:a4050fee11f7 53 void processOSC(UDPSocketEvent e);
mbedalvaro 0:345b3bc7a0ea 54 // ----------------------------------------------------------------------------------------------------------------------
mbedalvaro 0:345b3bc7a0ea 55
mbedalvaro 2:34157ebbf56b 56 // Tickers:
mbedalvaro 0:345b3bc7a0ea 57 Ticker timerForRendering;
mbedalvaro 2:34157ebbf56b 58 //Ticker timerForSendingData; // better use a timer, so as not to interrupt the exact laser display ticker
mbedalvaro 2:34157ebbf56b 59
mbedalvaro 2:34157ebbf56b 60 // Timers:
mbedalvaro 0:345b3bc7a0ea 61 Timer measureLoopPeriod;
mbedalvaro 1:a4050fee11f7 62 Timer measureUpdatePeriod;
mbedalvaro 2:34157ebbf56b 63 Timer measureSendPeriod;
mbedalvaro 0:345b3bc7a0ea 64
mbedalvaro 1:a4050fee11f7 65 // to get serial commands (not necessary perhaps)
mbedalvaro 0:345b3bc7a0ea 66 void processSerial();
mbedalvaro 1:a4050fee11f7 67
mbedalvaro 0:345b3bc7a0ea 68 int main() {
mbedalvaro 1:a4050fee11f7 69
mbedalvaro 0:345b3bc7a0ea 70 // Initialize the hardware (laser powers, positions...):
mbedalvaro 0:345b3bc7a0ea 71 IO.init();
mbedalvaro 0:345b3bc7a0ea 72
mbedalvaro 1:a4050fee11f7 73 // -------------------------------
mbedalvaro 1:a4050fee11f7 74 // Set the Ethernet port:
mbedalvaro 1:a4050fee11f7 75 printf("Setting up...\r\n");
mbedalvaro 1:a4050fee11f7 76 EthernetErr ethErr = eth.setup();
mbedalvaro 1:a4050fee11f7 77 if (ethErr) {
mbedalvaro 1:a4050fee11f7 78 printf("Error %d in setup.\r\n", ethErr);
mbedalvaro 1:a4050fee11f7 79 return -1;
mbedalvaro 1:a4050fee11f7 80 }
mbedalvaro 1:a4050fee11f7 81 printf("Setup OK\r\n");
mbedalvaro 1:a4050fee11f7 82
mbedalvaro 1:a4050fee11f7 83 //(1) Sending message:
mbedalvaro 1:a4050fee11f7 84 // Set IP and Port:
mbedalvaro 1:a4050fee11f7 85 sendMes.setIp( destIp );
mbedalvaro 1:a4050fee11f7 86 sendMes.setPort( destPort );
mbedalvaro 1:a4050fee11f7 87 // Set data:
mbedalvaro 1:a4050fee11f7 88 // sendMes.setTopAddress(topAddress);
mbedalvaro 1:a4050fee11f7 89
mbedalvaro 1:a4050fee11f7 90 //setting osc functionnality:
mbedalvaro 1:a4050fee11f7 91 //(2) Receiving:
mbedalvaro 1:a4050fee11f7 92 // recMes.setIp( serverIp ); // not needed?
mbedalvaro 1:a4050fee11f7 93 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)
mbedalvaro 1:a4050fee11f7 94 osc.begin(serverPort, &processOSC); // binds the upd (osc) messages to an arbitrary listening port ("server" port), and callback function
mbedalvaro 1:a4050fee11f7 95 // -------------------------------
mbedalvaro 1:a4050fee11f7 96
mbedalvaro 0:345b3bc7a0ea 97 /* // sending seems not to work right after setting the osc object??
mbedalvaro 0:345b3bc7a0ea 98 wait(1);
mbedalvaro 0:345b3bc7a0ea 99 sendMes.setTopAddress("starting");
mbedalvaro 1:a4050fee11f7 100 sendMes.setSubAddress("");
mbedalvaro 0:345b3bc7a0ea 101 osc.sendOsc( &sendMes );
mbedalvaro 0:345b3bc7a0ea 102 */
mbedalvaro 1:a4050fee11f7 103
mbedalvaro 0:345b3bc7a0ea 104 // initialize with the desired blob configuration:
mbedalvaro 1:a4050fee11f7 105
mbedalvaro 0:345b3bc7a0ea 106 // Tested modes:
mbedalvaro 1:a4050fee11f7 107 blobconf.clearConfig();
mbedalvaro 8:5816bb17536b 108 // blobconf.addOneElasticLoopContractCentral();
mbedalvaro 5:73cd58b58f95 109 // blobconf.addOneElasticContourFollowing();
mbedalvaro 1:a4050fee11f7 110
mbedalvaro 8:5816bb17536b 111 blobconf.addOneRigidLoopBouncing();
mbedalvaro 8:5816bb17536b 112 blobconf.addOneRigidLoopBouncing();
mbedalvaro 5:73cd58b58f95 113 // blobconf.addOneRigidLoopFollowing();
mbedalvaro 2:34157ebbf56b 114
mbedalvaro 7:0df17f3078bc 115
mbedalvaro 5:73cd58b58f95 116 //blobconf.addOneRigidLoopTest();
mbedalvaro 1:a4050fee11f7 117
mbedalvaro 0:345b3bc7a0ea 118 // Important: first, set the initial position for all the blobs, this will be useful because
mbedalvaro 0:345b3bc7a0ea 119 // when changing modes we can use the previous central position...
mbedalvaro 1:a4050fee11f7 120 // blobconf.setInitialPos(CENTER_AD_MIRROR_X, CENTER_AD_MIRROR_Y);
mbedalvaro 1:a4050fee11f7 121
mbedalvaro 5:73cd58b58f95 122 // draw the config once befor activating the laser buffer:
mbedalvaro 5:73cd58b58f95 123 blobconf.draw();
mbedalvaro 1:a4050fee11f7 124
mbedalvaro 0:345b3bc7a0ea 125 // RENRERER (attn: setConfigToRender must be called when the blobconf is set - i.e., the number of blobs and number of points/blob is fixed)
mbedalvaro 1:a4050fee11f7 126 lsr.setConfigToRender(&blobconf);
mbedalvaro 1:a4050fee11f7 127
mbedalvaro 1:a4050fee11f7 128 // Timer on the rendering function of the oneLoop object:
mbedalvaro 7:0df17f3078bc 129 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
mbedalvaro 3:b44ff6de81bd 130 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL); // the address of the object, member function, and interval (in seconds)
mbedalvaro 1:a4050fee11f7 131
mbedalvaro 1:a4050fee11f7 132 // Timer for sending OSC data:
mbedalvaro 2:34157ebbf56b 133 // timerForSendingData.attach(&blobconf, &blobConfig::sendConfData, 0.025); // time in seconds (25ms -> 40Hz)
mbedalvaro 1:a4050fee11f7 134
mbedalvaro 1:a4050fee11f7 135 //========================================== INFINITE LOOP (in USER PROGRAM CONTEXT) ===================================================================
mbedalvaro 1:a4050fee11f7 136 #ifdef LOOPTIMECOMPUTE
mbedalvaro 1:a4050fee11f7 137 int timeCounterNum=1000;
mbedalvaro 1:a4050fee11f7 138 #endif
mbedalvaro 1:a4050fee11f7 139
mbedalvaro 1:a4050fee11f7 140 measureUpdatePeriod.start();
mbedalvaro 2:34157ebbf56b 141 measureSendPeriod.start();
mbedalvaro 1:a4050fee11f7 142
mbedalvaro 1:a4050fee11f7 143 while (true) {
mbedalvaro 1:a4050fee11f7 144
mbedalvaro 7:0df17f3078bc 145 //NOTE: the updating period needs to be calculated as a function of the number of diplays points and the "refresh" rate of the laser.
mbedalvaro 7:0df17f3078bc 146 // THIS IS THE EQUICALENT OF "VERTICAL SYNCH"...
mbedalvaro 8:5816bb17536b 147 if (measureUpdatePeriod.read_ms()>4) { // 4 or 5 ms seems to be the minimum time required for performing one main loop (for a blob of 40 points)
mbedalvaro 2:34157ebbf56b 148 // with laser rendering ISR every 110us (total loop time 4300us, 3100us of effective loop time, and each laser interrupt about 30us)
mbedalvaro 1:a4050fee11f7 149 measureUpdatePeriod.stop();
mbedalvaro 1:a4050fee11f7 150 measureUpdatePeriod.reset();
mbedalvaro 1:a4050fee11f7 151
mbedalvaro 2:34157ebbf56b 152 // __disable_irq();
mbedalvaro 2:34157ebbf56b 153
mbedalvaro 1:a4050fee11f7 154 // update config dynamics (this also could be threaded?):
mbedalvaro 1:a4050fee11f7 155 blobconf.update();
mbedalvaro 1:a4050fee11f7 156
mbedalvaro 1:a4050fee11f7 157 // draw the config (note: each kind of blob renders differently)
mbedalvaro 1:a4050fee11f7 158 blobconf.draw();
mbedalvaro 1:a4050fee11f7 159
mbedalvaro 2:34157ebbf56b 160 // __enable_irq();
mbedalvaro 2:34157ebbf56b 161
mbedalvaro 1:a4050fee11f7 162 measureUpdatePeriod.start();
mbedalvaro 1:a4050fee11f7 163 }
mbedalvaro 0:345b3bc7a0ea 164
mbedalvaro 2:34157ebbf56b 165
mbedalvaro 1:a4050fee11f7 166 // COMMUNICATION:
mbedalvaro 1:a4050fee11f7 167 // (a) Reading commands:
mbedalvaro 1:a4050fee11f7 168 // Ethernet:
mbedalvaro 1:a4050fee11f7 169 Net::poll(); // this will take care of calling processOSC(UDPSocketEvent e) when a new packet arrives.
mbedalvaro 1:a4050fee11f7 170
mbedalvaro 1:a4050fee11f7 171 // Serial:
mbedalvaro 1:a4050fee11f7 172 #ifdef SERIAL_COMMANDS
mbedalvaro 1:a4050fee11f7 173 if (pc.readable()>0) processSerial();
mbedalvaro 1:a4050fee11f7 174 #endif
mbedalvaro 2:34157ebbf56b 175
mbedalvaro 2:34157ebbf56b 176 // (b)Sending Data: // PUT THIS IN AN INTERRUPT OR USE A TIMER!!! it may be TOO FAST...
mbedalvaro 2:34157ebbf56b 177 // 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):
mbedalvaro 2:34157ebbf56b 178 if (measureSendPeriod.read_ms()>25) {
mbedalvaro 2:34157ebbf56b 179 measureSendPeriod.stop();
mbedalvaro 2:34157ebbf56b 180 measureSendPeriod.reset();
mbedalvaro 2:34157ebbf56b 181
mbedalvaro 2:34157ebbf56b 182 blobconf.sendConfData();
mbedalvaro 2:34157ebbf56b 183
mbedalvaro 2:34157ebbf56b 184 measureSendPeriod.start();
mbedalvaro 2:34157ebbf56b 185 }
mbedalvaro 1:a4050fee11f7 186
mbedalvaro 1:a4050fee11f7 187 // text:
mbedalvaro 1:a4050fee11f7 188 /*
mbedalvaro 1:a4050fee11f7 189 sendMes.setTopAddress("/hello");
mbedalvaro 1:a4050fee11f7 190 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...)
mbedalvaro 1:a4050fee11f7 191 int x=(long)10;
mbedalvaro 1:a4050fee11f7 192 sendMes.setArgs( "i", &x);
mbedalvaro 1:a4050fee11f7 193 osc.sendOsc( &sendMes );
mbedalvaro 1:a4050fee11f7 194 */
mbedalvaro 1:a4050fee11f7 195
mbedalvaro 0:345b3bc7a0ea 196 #ifdef LOOPTIMECOMPUTE
mbedalvaro 1:a4050fee11f7 197 if (timeCounterNum>500) myled = 0;
mbedalvaro 1:a4050fee11f7 198 // if (timeCounterNum%10==0) blobconf.sendConfData();
mbedalvaro 1:a4050fee11f7 199 if (timeCounterNum>1000) {
mbedalvaro 1:a4050fee11f7 200 myled = 1;
mbedalvaro 1:a4050fee11f7 201 measureLoopPeriod.stop();
mbedalvaro 1:a4050fee11f7 202 sendMes.setTopAddress("/timeloop");
mbedalvaro 1:a4050fee11f7 203 sendMes.setSubAddress("/");
mbedalvaro 1:a4050fee11f7 204 long x=(long)(int(measureLoopPeriod.read_us()/1000.0));
mbedalvaro 5:73cd58b58f95 205 // long x=(long)(blobconf.blobArray[0]->displaySensingBuffer.lsdTrajectory.size());
mbedalvaro 7:0df17f3078bc 206 // long x=(long)(blobconf.blobArray[0]->normRecenteringVector);
mbedalvaro 1:a4050fee11f7 207 sendMes.setArgs( "i", &x);
mbedalvaro 1:a4050fee11f7 208 osc.sendOsc( &sendMes );
mbedalvaro 1:a4050fee11f7 209 timeCounterNum=0;
mbedalvaro 1:a4050fee11f7 210 measureLoopPeriod.reset();
mbedalvaro 1:a4050fee11f7 211 measureLoopPeriod.start();
mbedalvaro 1:a4050fee11f7 212 } else timeCounterNum++;
mbedalvaro 0:345b3bc7a0ea 213 #endif
mbedalvaro 0:345b3bc7a0ea 214
mbedalvaro 0:345b3bc7a0ea 215 }
mbedalvaro 0:345b3bc7a0ea 216 }
mbedalvaro 0:345b3bc7a0ea 217
mbedalvaro 1:a4050fee11f7 218 // ================= INTERPRET COMMAND =========================
mbedalvaro 0:345b3bc7a0ea 219 // NOTE: the following arrays are GLOBAL (used in processOSC and processSerial, as well as in interpretCommand function):
mbedalvaro 1:a4050fee11f7 220 // max of two addresses (top and sub), of a max length of 24 characters:
mbedalvaro 0:345b3bc7a0ea 221 char address[2][24];
mbedalvaro 0:345b3bc7a0ea 222 //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
mbedalvaro 1:a4050fee11f7 223 int data[2]; // this is to have -1 as NO DATA, to detect errors.
mbedalvaro 1:a4050fee11f7 224
mbedalvaro 1:a4050fee11f7 225 //interpretCommand(const char& address[2][], const int& data[2]) {
mbedalvaro 0:345b3bc7a0ea 226 void interpretCommand() {
mbedalvaro 0:345b3bc7a0ea 227 // (I) =========================================== SPECIAL FUNCTIONS (reset, rescan LUT, etc) ====================================================
mbedalvaro 0:345b3bc7a0ea 228 if ( !strcmp(address[0], "takeSnapshot" ) ) { // will reset all the spots, but the 0, and use it for taking measures:
mbedalvaro 1:a4050fee11f7 229
mbedalvaro 1:a4050fee11f7 230 // for test:
mbedalvaro 1:a4050fee11f7 231 for (int i=0; i<2 ; i++) {
mbedalvaro 1:a4050fee11f7 232 myled = 1;
mbedalvaro 1:a4050fee11f7 233 wait(0.1);
mbedalvaro 1:a4050fee11f7 234 myled = 0;
mbedalvaro 1:a4050fee11f7 235 wait(0.1);
mbedalvaro 1:a4050fee11f7 236 }
mbedalvaro 1:a4050fee11f7 237
mbedalvaro 1:a4050fee11f7 238 // First, we need to disable the threaded display for the loop:
mbedalvaro 1:a4050fee11f7 239 timerForRendering.detach();
mbedalvaro 1:a4050fee11f7 240
mbedalvaro 1:a4050fee11f7 241 // Then, do the scan (sending values on serial port):
mbedalvaro 1:a4050fee11f7 242 IO.scan_serial();
mbedalvaro 1:a4050fee11f7 243
mbedalvaro 1:a4050fee11f7 244 // Finally, start again threaded display:
mbedalvaro 4:f9d364f10335 245 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL);
mbedalvaro 4:f9d364f10335 246 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
mbedalvaro 1:a4050fee11f7 247 }
mbedalvaro 1:a4050fee11f7 248
mbedalvaro 1:a4050fee11f7 249 else if ( !strcmp(address[0], "mbedReset" ) ) mbed_reset();
mbedalvaro 1:a4050fee11f7 250
mbedalvaro 1:a4050fee11f7 251 else if ( !strcmp(address[0], "calibrate" ) ) {
mbedalvaro 1:a4050fee11f7 252 // First, we need to disable the threaded display for the loop:
mbedalvaro 1:a4050fee11f7 253 timerForRendering.detach();
mbedalvaro 1:a4050fee11f7 254 // RESCAN (and save LUT table):
mbedalvaro 1:a4050fee11f7 255 IO.scanLUT();
mbedalvaro 1:a4050fee11f7 256 // Finally, start again threaded display:
mbedalvaro 4:f9d364f10335 257 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL);
mbedalvaro 4:f9d364f10335 258 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
mbedalvaro 1:a4050fee11f7 259 }
mbedalvaro 1:a4050fee11f7 260
mbedalvaro 1:a4050fee11f7 261 // (II) ========================================= GLOBAL CONFIG and HARDWARE COMMANDS ===========================================
mbedalvaro 1:a4050fee11f7 262
mbedalvaro 1:a4050fee11f7 263 else if ( !strcmp(address[0], "setGreenLaser" ) ) {
mbedalvaro 1:a4050fee11f7 264 int value=data[0];
mbedalvaro 1:a4050fee11f7 265 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
mbedalvaro 1:a4050fee11f7 266 if (value==0) IO.setGreenPower(0);
mbedalvaro 1:a4050fee11f7 267 else IO.setGreenPower(1);
mbedalvaro 1:a4050fee11f7 268 }
mbedalvaro 1:a4050fee11f7 269 }
mbedalvaro 1:a4050fee11f7 270
mbedalvaro 1:a4050fee11f7 271 // SIMPLE BEHAVIOUR MODES (to be read from an XML file in the future):
mbedalvaro 1:a4050fee11f7 272 else if (!strcmp(address[0], "crawling")) { //
mbedalvaro 1:a4050fee11f7 273 timerForRendering.detach();
mbedalvaro 0:345b3bc7a0ea 274 // blobconf.computeBoundingBox();
mbedalvaro 1:a4050fee11f7 275 blobconf.clearConfig();
mbedalvaro 1:a4050fee11f7 276 blobconf.addOneElasticContourFollowing();
mbedalvaro 1:a4050fee11f7 277 lsr.setConfigToRender(&blobconf);
mbedalvaro 4:f9d364f10335 278 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL);
mbedalvaro 4:f9d364f10335 279 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
mbedalvaro 1:a4050fee11f7 280 } else if (!strcmp(address[0], "loop")) { //
mbedalvaro 1:a4050fee11f7 281 timerForRendering.detach();
mbedalvaro 1:a4050fee11f7 282 // blobconf.computeBoundingBox();
mbedalvaro 1:a4050fee11f7 283 blobconf.clearConfig();
mbedalvaro 1:a4050fee11f7 284 blobconf.addOneElasticLoopContractCentral();
mbedalvaro 1:a4050fee11f7 285 lsr.setConfigToRender(&blobconf);
mbedalvaro 4:f9d364f10335 286 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL);
mbedalvaro 4:f9d364f10335 287 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
mbedalvaro 1:a4050fee11f7 288 }
mbedalvaro 1:a4050fee11f7 289
mbedalvaro 1:a4050fee11f7 290 else if (!strcmp(address[0], "bouncing")) {
mbedalvaro 0:345b3bc7a0ea 291 timerForRendering.detach();
mbedalvaro 0:345b3bc7a0ea 292 // blobconf.computeBoundingBox();
mbedalvaro 1:a4050fee11f7 293 blobconf.clearConfig();
mbedalvaro 1:a4050fee11f7 294 blobconf.addOneElasticBouncing();
mbedalvaro 1:a4050fee11f7 295 lsr.setConfigToRender(&blobconf);
mbedalvaro 4:f9d364f10335 296 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL);
mbedalvaro 4:f9d364f10335 297 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
mbedalvaro 1:a4050fee11f7 298 }
mbedalvaro 1:a4050fee11f7 299
mbedalvaro 1:a4050fee11f7 300 // other:
mbedalvaro 1:a4050fee11f7 301
mbedalvaro 1:a4050fee11f7 302 else if ( !strcmp(address[0], "standby" ) ) { // will put ALL the spots in stand by mode
mbedalvaro 0:345b3bc7a0ea 303 blobconf.allStandBy(); // will avoid the update function
mbedalvaro 1:a4050fee11f7 304 } else if ( !strcmp(address[0], "resume" ) ) { // will put ALL the spots in stand by mode
mbedalvaro 0:345b3bc7a0ea 305 blobconf.allResume(); // will avoid the update function
mbedalvaro 1:a4050fee11f7 306 }
mbedalvaro 1:a4050fee11f7 307
mbedalvaro 1:a4050fee11f7 308 // (III) ========================================= Loop control (parameters, etc) ===========================================
mbedalvaro 1:a4050fee11f7 309 // NOte: for the time being, we only have ONE loop, so there is no "per loop or per config" mode.
mbedalvaro 1:a4050fee11f7 310
mbedalvaro 1:a4050fee11f7 311 else if (!strcmp( address[0], "sendOSC" ) ) {
mbedalvaro 1:a4050fee11f7 312 int value=data[0];
mbedalvaro 1:a4050fee11f7 313 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
mbedalvaro 1:a4050fee11f7 314 for (int i=0; i< blobconf.numBlobs; i++) {
mbedalvaro 1:a4050fee11f7 315 blobconf.blobArray[i]->sendOSC=(value>0);
mbedalvaro 1:a4050fee11f7 316 }
mbedalvaro 1:a4050fee11f7 317 }
mbedalvaro 1:a4050fee11f7 318 }
mbedalvaro 1:a4050fee11f7 319
mbedalvaro 1:a4050fee11f7 320 else if (!strcmp( address[0], "sendArea" ) ) {
mbedalvaro 1:a4050fee11f7 321 int value=data[0];
mbedalvaro 1:a4050fee11f7 322 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
mbedalvaro 1:a4050fee11f7 323 for (int i=0; i< blobconf.numBlobs; i++) {
mbedalvaro 1:a4050fee11f7 324 blobconf.blobArray[i]->sendingBlobArea=(value>0);
mbedalvaro 1:a4050fee11f7 325 }
mbedalvaro 1:a4050fee11f7 326 }
mbedalvaro 1:a4050fee11f7 327 }
mbedalvaro 1:a4050fee11f7 328
mbedalvaro 1:a4050fee11f7 329 else if (!strcmp( address[0], "sendPos" ) ) {
mbedalvaro 1:a4050fee11f7 330 int value=data[0];
mbedalvaro 1:a4050fee11f7 331 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
mbedalvaro 1:a4050fee11f7 332 for (int i=0; i< blobconf.numBlobs; i++) {
mbedalvaro 1:a4050fee11f7 333 blobconf.blobArray[i]->sendingLoopPositions=(value>0);
mbedalvaro 1:a4050fee11f7 334 }
mbedalvaro 1:a4050fee11f7 335 }
mbedalvaro 1:a4050fee11f7 336 }
mbedalvaro 1:a4050fee11f7 337
mbedalvaro 1:a4050fee11f7 338 else if (!strcmp( address[0], "sendRegions" ) ) {
mbedalvaro 1:a4050fee11f7 339 int value=data[0];
mbedalvaro 1:a4050fee11f7 340 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
mbedalvaro 1:a4050fee11f7 341 for (int i=0; i< blobconf.numBlobs; i++) {
mbedalvaro 1:a4050fee11f7 342 blobconf.blobArray[i]->sendingLoopRegions=(value>0);
mbedalvaro 1:a4050fee11f7 343 }
mbedalvaro 1:a4050fee11f7 344 }
mbedalvaro 1:a4050fee11f7 345 }
mbedalvaro 1:a4050fee11f7 346
mbedalvaro 1:a4050fee11f7 347 else if (!strcmp( address[0], "sendTouched" ) ) {
mbedalvaro 1:a4050fee11f7 348 int value=data[0];
mbedalvaro 1:a4050fee11f7 349 if (value!=-1) { // otherwise do nothing, this is a reception error (there was no data)
mbedalvaro 1:a4050fee11f7 350 for (int i=0; i< blobconf.numBlobs; i++) {
mbedalvaro 1:a4050fee11f7 351 blobconf.blobArray[i]->sendingTouched=(value>0);
mbedalvaro 1:a4050fee11f7 352 }
mbedalvaro 1:a4050fee11f7 353 }
mbedalvaro 1:a4050fee11f7 354 }
mbedalvaro 1:a4050fee11f7 355
mbedalvaro 1:a4050fee11f7 356
mbedalvaro 1:a4050fee11f7 357
mbedalvaro 0:345b3bc7a0ea 358 }
mbedalvaro 0:345b3bc7a0ea 359
mbedalvaro 0:345b3bc7a0ea 360 //============= RECEIVE OSC COMMANDS =========================
mbedalvaro 1:a4050fee11f7 361 // This is the callback function called when there are packets on the listening socket. It is not nice to have it
mbedalvaro 1:a4050fee11f7 362 // here, but for the time being having a "wrapping global" is the simplest solution (we cannot pass a member-function pointer
mbedalvaro 1:a4050fee11f7 363 // as handler to the upd object).
mbedalvaro 0:345b3bc7a0ea 364 void processOSC(UDPSocketEvent e) {
mbedalvaro 0:345b3bc7a0ea 365 osc.onUDPSocketEvent(e);
mbedalvaro 0:345b3bc7a0ea 366
mbedalvaro 0:345b3bc7a0ea 367 if (osc.newMessage) {
mbedalvaro 1:a4050fee11f7 368 // 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
mbedalvaro 1:a4050fee11f7 369 // 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...
mbedalvaro 1:a4050fee11f7 370
mbedalvaro 1:a4050fee11f7 371 // Acquire the addresses and arguments and put them in the GLOBAL variables:
mbedalvaro 1:a4050fee11f7 372 strcpy(address[0],"");
mbedalvaro 1:a4050fee11f7 373 strcpy(address[1],"");
mbedalvaro 1:a4050fee11f7 374 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
mbedalvaro 1:a4050fee11f7 375 // Acquire data:
mbedalvaro 1:a4050fee11f7 376 data[0]=-1;
mbedalvaro 1:a4050fee11f7 377 data[1]=-1;
mbedalvaro 1:a4050fee11f7 378 for (int i=0; i<recMes.getArgNum(); i++) data[i]=(int)recMes.getArgInt(i);
mbedalvaro 1:a4050fee11f7 379
mbedalvaro 1:a4050fee11f7 380 // Finally, interpret the command:
mbedalvaro 1:a4050fee11f7 381 interpretCommand();//address, data);
mbedalvaro 1:a4050fee11f7 382
mbedalvaro 0:345b3bc7a0ea 383 }
mbedalvaro 1:a4050fee11f7 384 }
mbedalvaro 1:a4050fee11f7 385
mbedalvaro 0:345b3bc7a0ea 386 //============= RECEIVE SERIAL COMMANDS =========================
mbedalvaro 0:345b3bc7a0ea 387 //
mbedalvaro 1:a4050fee11f7 388 // NOTE: - NUMERIC PARAMETERS have to be send BEFORE the command word. They must be sent as ASCII DEC, without end character.
mbedalvaro 0:345b3bc7a0ea 389 // - Commands words SHOULD NOT have numbers in it. They should be C compliant STRINGS (ended with character '0')
mbedalvaro 1:a4050fee11f7 390 // - order is irrelevant: we can send 10 RADIUS or RADIUS 10.
mbedalvaro 0:345b3bc7a0ea 391
mbedalvaro 1:a4050fee11f7 392 // String to store ALPHANUMERIC DATA (i.e., integers, floating point numbers, unsigned ints, etc represented as DEC) sent wirelessly:
mbedalvaro 0:345b3bc7a0ea 393 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...
mbedalvaro 0:345b3bc7a0ea 394 int indexStringData=0;//position of the byte in the string
mbedalvaro 0:345b3bc7a0ea 395
mbedalvaro 0:345b3bc7a0ea 396 // String to store COMMAND WORDS:
mbedalvaro 0:345b3bc7a0ea 397 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...
mbedalvaro 0:345b3bc7a0ea 398 int indexStringCommand=0;
mbedalvaro 0:345b3bc7a0ea 399 bool commandReady=false; // will become true when receiving the byte 0 (i.e. the '/0' string terminator)
mbedalvaro 0:345b3bc7a0ea 400
mbedalvaro 0:345b3bc7a0ea 401 void processSerial() {
mbedalvaro 0:345b3bc7a0ea 402
mbedalvaro 1:a4050fee11f7 403 while (pc.readable()>0) {
mbedalvaro 1:a4050fee11f7 404
mbedalvaro 1:a4050fee11f7 405 char val =pc.getc();
mbedalvaro 0:345b3bc7a0ea 406 // pc.printf("Got :%d\n", incomingByte);
mbedalvaro 1:a4050fee11f7 407 //pc.putc(incomingByte);
mbedalvaro 1:a4050fee11f7 408
mbedalvaro 1:a4050fee11f7 409 // Save ASCII numeric characters (ASCII 0 - 9) on stringData:
mbedalvaro 1:a4050fee11f7 410 if ((val >= '0') && (val <= '9')) { // this is 45 to 57 (included)
mbedalvaro 1:a4050fee11f7 411 stringData[indexStringData] = val;
mbedalvaro 1:a4050fee11f7 412 indexStringData++;
mbedalvaro 1:a4050fee11f7 413 }
mbedalvaro 1:a4050fee11f7 414
mbedalvaro 1:a4050fee11f7 415 // Save ASCII letters in stringCommand:
mbedalvaro 1:a4050fee11f7 416 if ((val >= 'A') && (val <= 'z')) { // this is 65 to 122 (included)
mbedalvaro 1:a4050fee11f7 417 stringCommand[indexStringCommand] = val;
mbedalvaro 1:a4050fee11f7 418 indexStringCommand++;
mbedalvaro 1:a4050fee11f7 419 }
mbedalvaro 1:a4050fee11f7 420 // is command ready?
mbedalvaro 1:a4050fee11f7 421 if (val=='/') {
mbedalvaro 1:a4050fee11f7 422 commandReady=true;
mbedalvaro 1:a4050fee11f7 423 stringCommand[indexStringCommand] = 0; // string termination.
mbedalvaro 1:a4050fee11f7 424 indexStringCommand=0; // reset index string for acquiring next command
mbedalvaro 1:a4050fee11f7 425 //Serial.println(stringCommand);
mbedalvaro 1:a4050fee11f7 426 }
mbedalvaro 1:a4050fee11f7 427
mbedalvaro 1:a4050fee11f7 428 // COMMANDS (with or without numeric parameters):
mbedalvaro 1:a4050fee11f7 429 if (commandReady==true) { // it means we can interpret the command string:
mbedalvaro 1:a4050fee11f7 430 commandReady=false;
mbedalvaro 1:a4050fee11f7 431
mbedalvaro 1:a4050fee11f7 432 stringData[indexStringData] = 0 ;// string termination for numeric values;
mbedalvaro 1:a4050fee11f7 433 indexStringData=0;
mbedalvaro 1:a4050fee11f7 434
mbedalvaro 1:a4050fee11f7 435 // PARSE DATA: (TO DO!!!!!!!!!!!!!!):
mbedalvaro 0:345b3bc7a0ea 436
mbedalvaro 1:a4050fee11f7 437 // (a) Parse command (get address[0] and address[1]):
mbedalvaro 1:a4050fee11f7 438 //ex: "/1/standBy" -- > address[0]="1" and address[1]="standBy"
mbedalvaro 1:a4050fee11f7 439 // address[2]
mbedalvaro 1:a4050fee11f7 440
mbedalvaro 1:a4050fee11f7 441 // Serial.println(stringCommand);
mbedalvaro 1:a4050fee11f7 442 // Serial.println(stringData);
mbedalvaro 1:a4050fee11f7 443
mbedalvaro 1:a4050fee11f7 444 // (b) Parse data:
mbedalvaro 1:a4050fee11f7 445
mbedalvaro 1:a4050fee11f7 446 // char address[2][24];
mbedalvaro 1:a4050fee11f7 447 //long auxdata[2]; // to store a max of two arguments (note: we will only use LONGs)
mbedalvaro 1:a4050fee11f7 448 //int data[2]; // this is to have -1 as NO DATA, to detect errors.
mbedalvaro 1:a4050fee11f7 449
mbedalvaro 1:a4050fee11f7 450 // FOR THE TIME BEING there is no parsing for serial commands:
mbedalvaro 1:a4050fee11f7 451
mbedalvaro 1:a4050fee11f7 452 // SCANNING:
mbedalvaro 1:a4050fee11f7 453 if (!strcmp(stringCommand , "takeSnapshot")) {
mbedalvaro 1:a4050fee11f7 454 // First, we need to disable the threaded display for the loop:
mbedalvaro 1:a4050fee11f7 455 timerForRendering.detach();
mbedalvaro 1:a4050fee11f7 456
mbedalvaro 1:a4050fee11f7 457 // Then, do the scan (sending values on serial port):
mbedalvaro 1:a4050fee11f7 458 IO.scan_serial();
mbedalvaro 1:a4050fee11f7 459
mbedalvaro 1:a4050fee11f7 460 // Finally, start again threaded display:
mbedalvaro 4:f9d364f10335 461 timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThread, RENDER_INTERVAL);
mbedalvaro 4:f9d364f10335 462 // timerForRendering.attach(&lsr, &simpleLaserSensingRenderer::laserRenderThreadONEBLOBONLY, RENDER_INTERVAL);
mbedalvaro 1:a4050fee11f7 463 }
mbedalvaro 1:a4050fee11f7 464
mbedalvaro 1:a4050fee11f7 465 if (!strcmp(stringCommand , "REDON")) IO.setRedPower(1); // pc.printf("%d\n",incomingByte);
mbedalvaro 1:a4050fee11f7 466
mbedalvaro 1:a4050fee11f7 467 if (!strcmp(stringCommand , "REDOFF")) IO.setRedPower(0);
mbedalvaro 1:a4050fee11f7 468
mbedalvaro 1:a4050fee11f7 469 if (!strcmp(stringCommand , "READVALUE")) pc.printf("Value read: %f", lockin.getSmoothValue());//lockin.getLastValue());/
mbedalvaro 1:a4050fee11f7 470
mbedalvaro 1:a4050fee11f7 471 // FINALLY, interpret commands (but only after parsing):
mbedalvaro 1:a4050fee11f7 472 // interpretCommand();//address, data);
mbedalvaro 0:345b3bc7a0ea 473
mbedalvaro 0:345b3bc7a0ea 474 }
mbedalvaro 1:a4050fee11f7 475 }
mbedalvaro 1:a4050fee11f7 476 }
mbedalvaro 0:345b3bc7a0ea 477
mbedalvaro 0:345b3bc7a0ea 478
mbedalvaro 0:345b3bc7a0ea 479
mbedalvaro 0:345b3bc7a0ea 480 // ================ MISCELANEA
mbedalvaro 0:345b3bc7a0ea 481
mbedalvaro 0:345b3bc7a0ea 482 /* EXAMPLE SEND/RECEIVE on PROCESSING:
mbedalvaro 0:345b3bc7a0ea 483
mbedalvaro 0:345b3bc7a0ea 484 // oscP5sendreceive by andreas schlegel
mbedalvaro 0:345b3bc7a0ea 485 // example shows how to send and receive osc messages.
mbedalvaro 0:345b3bc7a0ea 486 // oscP5 website at http://www.sojamo.de/oscP5
mbedalvaro 0:345b3bc7a0ea 487
mbedalvaro 0:345b3bc7a0ea 488 import oscP5.*;
mbedalvaro 0:345b3bc7a0ea 489 import netP5.*;
mbedalvaro 1:a4050fee11f7 490
mbedalvaro 0:345b3bc7a0ea 491 OscP5 oscP5;
mbedalvaro 0:345b3bc7a0ea 492 NetAddress myRemoteLocation;
mbedalvaro 0:345b3bc7a0ea 493
mbedalvaro 0:345b3bc7a0ea 494 void setup() {
mbedalvaro 0:345b3bc7a0ea 495 size(400,400);
mbedalvaro 0:345b3bc7a0ea 496 frameRate(25);
mbedalvaro 1:a4050fee11f7 497 // start oscP5, listening for incoming messages at port 12000
mbedalvaro 0:345b3bc7a0ea 498 oscP5 = new OscP5(this,12000);
mbedalvaro 1:a4050fee11f7 499
mbedalvaro 0:345b3bc7a0ea 500 // myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
mbedalvaro 0:345b3bc7a0ea 501 // an ip address and a port number. myRemoteLocation is used as parameter in
mbedalvaro 1:a4050fee11f7 502 // oscP5.send() when sending osc packets to another computer, device,
mbedalvaro 0:345b3bc7a0ea 503 // application. usage see below. for testing purposes the listening port
mbedalvaro 0:345b3bc7a0ea 504 // and the port of the remote location address are the same, hence you will
mbedalvaro 0:345b3bc7a0ea 505 // send messages back to this sketch.
mbedalvaro 0:345b3bc7a0ea 506 myRemoteLocation = new NetAddress("10.0.0.2",10000);
mbedalvaro 0:345b3bc7a0ea 507 }
mbedalvaro 0:345b3bc7a0ea 508
mbedalvaro 0:345b3bc7a0ea 509
mbedalvaro 0:345b3bc7a0ea 510 void draw() {
mbedalvaro 1:a4050fee11f7 511 background(0);
mbedalvaro 0:345b3bc7a0ea 512 }
mbedalvaro 0:345b3bc7a0ea 513
mbedalvaro 0:345b3bc7a0ea 514 void mousePressed() {
mbedalvaro 1:a4050fee11f7 515 // in the following different ways of creating osc messages are shown by example
mbedalvaro 0:345b3bc7a0ea 516 OscMessage myMessage = new OscMessage("/mbed/test1");
mbedalvaro 1:a4050fee11f7 517
mbedalvaro 1:a4050fee11f7 518 myMessage.add(123); // add an int to the osc message
mbedalvaro 0:345b3bc7a0ea 519
mbedalvaro 1:a4050fee11f7 520 // send the message
mbedalvaro 1:a4050fee11f7 521 oscP5.send(myMessage, myRemoteLocation);
mbedalvaro 0:345b3bc7a0ea 522 }
mbedalvaro 0:345b3bc7a0ea 523
mbedalvaro 0:345b3bc7a0ea 524
mbedalvaro 1:a4050fee11f7 525 // incoming osc message are forwarded to the oscEvent method.
mbedalvaro 0:345b3bc7a0ea 526 void oscEvent(OscMessage theOscMessage) {
mbedalvaro 1:a4050fee11f7 527 // print the address pattern and the typetag of the received OscMessage
mbedalvaro 0:345b3bc7a0ea 528 print("### received an osc message.");
mbedalvaro 0:345b3bc7a0ea 529 print(" addrpattern: "+theOscMessage.addrPattern());
mbedalvaro 0:345b3bc7a0ea 530 println(" typetag: "+theOscMessage.typetag());
mbedalvaro 0:345b3bc7a0ea 531 }
mbedalvaro 0:345b3bc7a0ea 532
mbedalvaro 0:345b3bc7a0ea 533 */