⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clnnm.nc

📁 主要用于无线传感网络的编写的书籍.对于初学者有着很大的用处
💻 NC
字号:
/* CLNN implmentation *//* Written by Tatiana Bokareva, Kin Sun Ho (tbokareva,ksho@cse) *//* Last Modified: 09 September 2005 */includes Sasha;module CLNNM{  provides interface CLNNlib;  provides interface StdControl;  uses {    interface Timer;    interface Leds;    interface Anycastlib;    interface StdControl as SensorControl;    interface StdControl as CommControl;    interface ADC as Sensor;  }}implementation{  uint8_t reading;             // raw reading taken to fill buffer <= buffer  uint8_t training;            // number of training done  uint16_t buffer[NUM_UNITS];  // buffer to store raw sensor data  struct clnn *ptnn;	       // neural network structure  uint16_t epocht = -1;        // current epoch  uint16_t verify;              // verify or training  struct Anycast *vdata;        // storing the content of verify broadcast  uint16_t num_verify;          // num of verify  uint16_t verify_fault;        // number of fault discovered  uint16_t c_min;               // current verify min  uint16_t c_max;               // current verify max    /*      The following print statement is for debugging in tossim     To run the program in tossim:     # make pc     # export DBG=usr1     # ./build/pc/main.exe 1  */    /* prints raw sensor data received */  void print_raw() {    uint8_t i=0;    dbg(DBG_USR1, "Input Vector: ");    for(i=0; i<NUM_UNITS; i++) {      dbg(DBG_USR1, "%d ", buffer[i]);    }    dbg(DBG_USR1, "\n");  }  /* prints the weight matrix which is used for training */   void print_weights(){    uint8_t i=0;    uint8_t j=0;    for(i=0; i<NUM_UNITS; i++){      atomic {	dbg(DBG_USR1, "WEIGHTS: %u - ", i);      }      for(j=0; j< NUM_UNITS; j++){	dbg(DBG_USR1, "%u ", ptnn->weights[i][j]);      }      dbg(DBG_USR1, "\n");    }  }    /* prints the clusters */   void print_clusters() {    uint8_t i=0;    for(i=0; i<NUM_UNITS; i++){      dbg(DBG_USR1, "CLUSTERS: %u %u %u %u\n", i, ptnn->clusters[i][0],	  ptnn->clusters[i][1],ptnn->clusters[i][2]);    }  }    /* asks CLNN reset its weight matrix and all information it have */  command result_t CLNNlib.reset() {    /* parameters to assign the weight array */    uint8_t i=0;    uint8_t j=0;    uint16_t step=100;    uint8_t inc=100;        dbg(DBG_USR1, "CLNN reinitialized\n");    atomic {      reading = 0;      training = 0;      //initilise the weights and clusters      for(i=0; i<NUM_UNITS; i++){		for(j=0; j< NUM_UNITS; j++){	  ptnn->weights[i][j]=step;	  ptnn->clusters[i][0]=NEGDIST;	  ptnn->clusters[i][1]=NEGDIST;	  ptnn->clusters[i][2]=0;	}	step=step+inc;      }    }    print_weights();    return SUCCESS;  }    // ask CLNN to start training  command result_t CLNNlib.start_training() {    verify = 0;    return call Timer.start(TIMER_REPEAT,SENSOR_PERIOD);  }    // ask CLNN to start verify  command result_t CLNNlib.start_verify(struct Anycast *pt) {    atomic {      verify = 1;      vdata->min = pt->min;   // stoare min/max values in vdata      vdata->max = pt->max;   // for use in ADC      vdata->min1 = pt->min1;      vdata->max1 = pt->max1;      vdata->min2 = pt->min2;      vdata->max2 = pt->max2;      vdata->min3 = pt->min3;      vdata->max3 = pt->max3;      vdata->nintervals = pt->nintervals;      num_verify = 0;      verify_fault = 0;      c_min = 0;      c_max = 0;    }    return call Timer.start(TIMER_REPEAT,SENSOR_PERIOD);  }  /* Function to be called from Anycast to request for Marzullo intersection */  command result_t CLNNlib.request(Cluster_Msg *datat) {    uint16_t trained;           // number of times trained so far    uint16_t values[NUM_UNITS]; //number of time units won      uint16_t ind[NUM_UNITS];    //index of the clusters    uint16_t tmp_v;    uint16_t tmp_i;    uint8_t i;    uint8_t j;        atomic {      trained = training;    }        if(trained != MAX_TRAIN)      return FAIL;        for(i=0; i<NUM_UNITS; i++) {      values[i]=ptnn->clusters[i][2];      ind[i]=i;    }        // sort the clusters based on the number of won competions	     for(i=0; i<NUM_UNITS-1; i++) {      for(j=0; j<NUM_UNITS-1-i; j++) {	if(values[j+1]>values[j]){/* compare the two neighbors */	  tmp_v=values[j];	  tmp_i=ind[j];	  values[j]=values[j+1];	  values[j+1]=tmp_v;	  ind[j]=ind[j+1];	  ind[j+1]=tmp_i;	}      }                         	            }    atomic {      datat->win1 = ptnn->clusters[ind[0]][2]; // storing results      datat->win2 = ptnn->clusters[ind[1]][2];      datat->win3 = ptnn->clusters[ind[2]][2]; // # of times win      datat->win4 = ptnn->clusters[ind[3]][2];      datat->min1 = ptnn->clusters[ind[0]][0];      datat->min2 = ptnn->clusters[ind[1]][0];      datat->min3 = ptnn->clusters[ind[2]][0]; // minimum      datat->min4 = ptnn->clusters[ind[3]][0];      datat->max1 = ptnn->clusters[ind[0]][1];      datat->max2 = ptnn->clusters[ind[1]][1];      datat->max3 = ptnn->clusters[ind[2]][1]; // maximum of each clusters      datat->max4 = ptnn->clusters[ind[3]][1];      datat->train = training; // # of training    }    return SUCCESS;  }   /**  * Used to initialize this component.  */  command result_t StdControl.init() {    /* parameters to assign the weight array */    uint8_t i=0;    uint8_t j=0;    uint16_t step=100;    uint8_t inc=100;    call Leds.init();    call SensorControl.init();    atomic {      ptnn =(struct clnn*) malloc(sizeof(struct clnn));      vdata = (struct Anycast*) malloc(sizeof(struct Anycast));       reading = 0;      training = 0;            //initilise the weights and clusters      for(i=0; i<NUM_UNITS; i++){		for(j=0; j< NUM_UNITS; j++){	  ptnn->weights[i][j]=step;	  ptnn->clusters[i][0]=NEGDIST;	  ptnn->clusters[i][1]=NEGDIST;	  ptnn->clusters[i][2]=0;	}	step=step+inc;      }    }    print_weights();    return SUCCESS;  }  /**   * Starts the SensorControl and CommControl components.   * @return Always returns SUCCESS.   */  command result_t StdControl.start() {    call SensorControl.start();    return SUCCESS;  }  /**   * Stops the SensorControl and CommControl components.   * @return Always returns SUCCESS.   */  command result_t StdControl.stop() {    call SensorControl.stop();    call Timer.stop();    return SUCCESS;  }  /* Trains raw sensor data with CLNN clustering */  void clnn_train() {    /* varibles for indexing into arrays */    uint8_t i = 0;    uint8_t j = 0;    uint8_t k = 0;    /* varibles for storing local temp values */    uint32_t temp  = 0;    uint32_t temp2 = 0;    uint32_t sum   = 0;    uint16_t trained;    /* minimum distance beween the winner and input vector */    uint32_t min_dist = NEGDIST;    /* minimum distance beween the lossers and input vector */    uint32_t min_distL = NEGDIST;        /* current training winner */    uint8_t winner = NEGDIST;    /* number of current epochs trained */    uint8_t e=0;        /* number of iterations done */    uint8_t iterations=0;        /* Calculate the Euclidean distance        from the input vector unit to all weights */    for(i=0; i<NUM_UNITS ;i++) {      for(j=0; j<NUM_UNITS; j++) {	temp = ptnn->weights[i][j] - buffer[j];	sum += temp*temp;      }      if(sum <= min_dist || min_dist == -1) {	min_dist = sum;	winner = i;      }      sum = 0;    }        print_raw(); // for debug        atomic {      /* Update the winning cluster interval and the number of won times */      if(ptnn->clusters[winner][2] == 0) {	ptnn->clusters[winner][0] = ptnn->clusters[winner][1] = buffer[0];       }      ptnn->clusters[winner][2]++;    }        for(i=0;i<NUM_UNITS;i++){      atomic {	if(buffer[i] < ptnn->clusters[winner][0]){ 	  ptnn->clusters[winner][0]= buffer[i];	}	if(buffer[i] > ptnn->clusters[winner][1]){ 	  ptnn->clusters[winner][1]= buffer[i];	}      }    }        dbg(DBG_USR1, "(%d,%d,%d)\n", ptnn->clusters[winner][0],	ptnn->clusters[winner][1],ptnn->clusters[winner][2]);    /*      Update the weights of the winner and perform the       leaky learning on other neurons. 	      Do that until one of the following has happend:      1) reach maximum number of EPOCHS      2) the distance between the weight and the input vector       Cannot be improved anymore. This is due to the resolution       of the division operator on modes. I.e no floating points division :(     */        for(e=0; e<MAX_EPOCH; e++){       sum = 0;      for(i=0; i<NUM_UNITS; i++) {	if(i == winner) { 	  for(j=0;j<NUM_UNITS;j++) { 	    atomic {	      temp2 = (buffer[j]- ptnn->weights[winner][j]) >> 3;	      ptnn->weights[winner][j] += temp2;	    }	  }	  /* Calculate the new distance between 	     the input and the weight vector*/	  sum = 0;	  for(k=0;k<NUM_UNITS;k++){	    atomic {	      temp = ptnn->weights[winner][k] - buffer[k];	    }            	    sum += temp*temp;	  }	  	  /* the distance between the weight and the vector 	  cannot be improved anymore. 	  I.e previous distance = currently calculated */	  sum = sqrt(sum);	  if(min_dist == sum) { 	    //call Leds.redOn();	    iterations = e;	    e = MAX_EPOCH;	  }	  else{ 	    min_dist = sum;	  }	}	else {	  for(j =0; j<NUM_UNITS;j++) {	    atomic {	      temp2 = (buffer[j]-ptnn->weights[i][j]) >> 8;	      ptnn->weights[i][j] += temp2;	    }	    sum = 0;	    	    for(k=0;k<NUM_UNITS;k++){	      atomic {		temp = ptnn->weights[j][k] - buffer[k];	      }	      sum += temp*temp;	    }	    sum = sqrt(sum);	    /* the distance between the weight and the input vector 	       can not be improuved anymore. 	       I.e previous distance = currently calculated */	    if(min_distL == sum) {	      //call Leds.redOn();	      continue;	    }	    else{ 	      min_distL = sum;	    }	  }	}      }    }        atomic {      // update the training count      trained = ++training;      call Leds.yellowToggle();      dbg(DBG_USR1, "Training number %d finished with %d interations\n",	  trained, iterations);      print_raw();      print_weights();      print_clusters();    }        if(trained < MAX_TRAIN)      call Timer.start(TIMER_REPEAT,SENSOR_PERIOD);    if(trained == MAX_TRAIN) {      call Leds.greenOn();      call Leds.yellowOn();      call Anycastlib.start_timer();    }  }  /**   * Signalled when data is ready from the ADC. Stuffs the sensor   * reading into the current packet, and call train task when   * BUFFER_SIZE readings have been taken.   * @return Always returns SUCCESS.   */  async event result_t Sensor.dataReady(uint16_t data) {    uint16_t trained;    uint16_t Nfinals;    uint8_t is_fault = 1;    Nfinals = vdata->nintervals;    // do Verify ADC operation    if(verify == 1) {      atomic {	num_verify++; // increment # of verify count	//[tb] Send packet every 1000 readings.	if(num_verify >= 1000) {	  call Timer.stop();	  /* [KS] Include buffer ADC */	  call Anycastlib.start_verify(verify_fault,c_min,c_max,buffer);	}	// put data into buffer	/* [KS] Include buffer ADC */	buffer[reading++] = data; // store data into the buffer	if(reading == NUM_UNITS) {	  reading = 0;	}	// check for each intervals	if(Nfinals >= 1) {	  if(data <= vdata->max && data >= vdata->min) {	    is_fault = 0;	  }	}		if(Nfinals >= 2) {	  if(data <= vdata->max1 && data >= vdata->min1) {	    is_fault = 0;	  }	}	if(Nfinals >= 3) {	  if(data <= vdata->max2 && data >= vdata->min2) {	    is_fault = 0;	  }	}	if(Nfinals >= 4) {	  if(data <= vdata->max3 && data >= vdata->min3) {	    is_fault = 0;	  }	}	// if there is a fault, increase the fault count	if(is_fault == 1) {	  call Leds.greenToggle();	  verify_fault++;	  // if the min/max count haven't been set before	  if(c_min == 0 && c_max == 0) {	    c_min = data; c_max = 0;	  }	  if(data < c_min)	    c_min = data;	  if(data > c_max)	    c_max = data;	}	// else decrease the fault count if > 0	else {	  call Leds.redToggle();	  if(verify_fault > 0)	    verify_fault--;	}	// Enable the lines for immediate sending of fault if > MAX_FAULTS	/*	//[tb] MAXIMUM FAULTS reached the threshold. Send falty notification	if(verify_fault >= MAX_FAULTS) {	call Timer.stop();        // [KS] Include buffer ADC 	call Anycastlib.start_verify(verify_fault,c_min,c_max,buffer);	}	*/      }      return SUCCESS;    }        ///////    // below is for CLNN training operation    //////    atomic {      trained = training;    }        // check if we have reached MAX_TRAIN    if(trained >= MAX_TRAIN) {      call Timer.stop();      return SUCCESS;    }    atomic {      buffer[reading++] = data; // store data into the buffer      call Leds.greenToggle();      if(reading == NUM_UNITS) {	reading = 0;	call Timer.stop(); // stop the timer during training	clnn_train(); // if bbuffer is full do a clnn training      }    }    return SUCCESS;  }  /**   * Signalled when the clock ticks.   * @return The result of calling Photo.getData().   */  event result_t Timer.fired() {    return call Sensor.getData();  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -