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

📄 cpmmodelc.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 *
 * CPM (closest-pattern matching) is a wireless noise simulation model
 * based on statistical extraction from empirical noise data.  This
 * model provides far more precise software simulation environment by
 * exploiting time-correlated noise characteristics. For details,
 * please refer to the paper
 *
 * "Improving Wireless Simulation through Noise Modeling." HyungJune
 * Lee and Philip Levis, IPSN 2007. You can find a copy at
 * http://sing.stanford.edu.
 * 
 * @author Hyungjune Lee, Philip Levis
 * @date   Oct 12 2006
 */ 

#include <sim_gain.h>
#include <sim_noise.h>
#include <randomlib.h>

module CpmModelC {
  provides interface GainRadioModel as Model;
}

implementation {
  
  message_t* outgoing; // If I'm sending, this is my outgoing packet
  bool requestAck;
  bool receiving = 0;  // Whether or not I think I'm receiving a packet
  bool transmitting = 0; // Whether or not I think I'm tranmitting a packet
  sim_time_t transmissionEndTime; // to check pending transmission
  struct receive_message;
  typedef struct receive_message receive_message_t;

  struct receive_message {
    int source;
    sim_time_t start;
    sim_time_t end;
    double power;
    double reversePower;
    int8_t strength;
    bool lost;
    bool ack;
    message_t* msg;
    receive_message_t* next;
  };

  receive_message_t* outstandingReceptionHead = NULL;

  receive_message_t* allocate_receive_message();
  void free_receive_message(receive_message_t* msg);
  sim_event_t* allocate_receive_event(sim_time_t t, receive_message_t* m);

  bool shouldReceive(double SNR);
  bool checkReceive(receive_message_t* msg);
  double packetNoise(receive_message_t* msg);
  double checkPrr(receive_message_t* msg);
  
  double timeInMs()   {
    sim_time_t ftime = sim_time();
    int hours, minutes, seconds;
    sim_time_t secondBillionths;
    int temp_time;
    double ms_time;

    secondBillionths = (ftime % sim_ticks_per_sec());
    if (sim_ticks_per_sec() > (sim_time_t)1000000000) {
	secondBillionths /= (sim_ticks_per_sec() / (sim_time_t)1000000000);
    }
    else {
      secondBillionths *= ((sim_time_t)1000000000 / sim_ticks_per_sec());
    }
    temp_time = (int)(secondBillionths/10000);
    
    if (temp_time % 10 >= 5) {
	temp_time += (10-(temp_time%10));
    }
    else {
      temp_time -= (temp_time%10);
    }
    ms_time = (float)(temp_time/100.0);

    seconds = (int)(ftime / sim_ticks_per_sec());
    minutes = seconds / 60;
    hours = minutes / 60;
    seconds %= 60;
    minutes %= 60;
	
    ms_time += (hours*3600+minutes*60+seconds)*1000;

    return ms_time;
  }
	
  //Generate a CPM noise reading
  double noise_hash_generation()   {
    double CT = timeInMs(); 
    uint32_t quotient = ((sim_time_t)(CT*10))/10;
    uint8_t remain = (uint8_t)(((sim_time_t)(CT*10))%10);
    double noise_val;
    uint16_t node_id = sim_node();

    dbg("CpmModelC", "IN: noise_hash_generation()\n");
    if (5 <= remain && remain < 10) {
	noise_val = (double)sim_noise_generate(node_id, quotient+1);
      }
    else {
      noise_val = (double)sim_noise_generate(node_id, quotient);
    }
    dbg("CpmModelC,Tal", "%s: OUT: noise_hash_generation(): %lf\n", sim_time_string(), noise_val);

    return noise_val;
  }

  double packetSnr(receive_message_t* msg) {
    double signalStr = msg->power;
    double noise = noise_hash_generation();
    return (signalStr - noise);
  }
  
  double arr_estimate_from_snr(double SNR) {
    double beta1 = 0.9794;
    double beta2 = 2.3851;
    double X = SNR-beta2;
    double PSE = 0.5*erfc(beta1*X/sqrt(2));
    double prr_hat = pow(1-PSE, 23*2);
    dbg("CpmModelC,SNRLoss", "SNR is %lf, ARR is %lf\n", SNR, prr_hat);
    if (prr_hat > 1)
      prr_hat = 1.1;
    else if (prr_hat < 0)
      prr_hat = -0.1;
	
    return prr_hat;
  }
  
  int shouldAckReceive(double snr) {
    double prr = arr_estimate_from_snr(snr);
    double coin = RandomUniform();
    if ( (prr >= 0) && (prr <= 1) ) {
      if (coin < prr)
	prr = 1.0;
      else
	prr = 0.0;
    }
    return (int)prr;
  }
  
  void sim_gain_ack_handle(sim_event_t* evt)  {
    // Four conditions must hold for an ack to be issued:
    // 1) Transmitter is still sending a packet (i.e., not cancelled)
    // 2) The packet requested an acknowledgment
    // 3) The transmitter is on
    // 4) The packet passes the SNR/ARR curve
    if (requestAck && // This 
	outgoing != NULL &&
	sim_mote_is_on(sim_node())) {
      receive_message_t* rcv = (receive_message_t*)evt->data;
      double power = rcv->reversePower;
      double noise = packetNoise(rcv);
      double snr = power - noise;
      if (shouldAckReceive(snr)) {
	signal Model.acked(outgoing);
      }
    }
    free_receive_message((receive_message_t*)evt->data);
  }

  sim_event_t receiveEvent;
  // This clear threshold comes from the CC2420 data sheet
  double clearThreshold = -72.0;
  bool collision = FALSE;
  message_t* incoming = NULL;
  int incomingSource;

  command void Model.setClearValue(double value) {
    clearThreshold = value;
    dbg("CpmModelC", "Setting clear threshold to %f\n", clearThreshold);
	
  }
  
  command bool Model.clearChannel() {
    dbg("CpmModelC", "Checking clear channel @ %s: %f <= %f \n", sim_time_string(), (double)packetNoise(NULL), clearThreshold);
    return packetNoise(NULL) < clearThreshold;
  }

  void sim_gain_schedule_ack(int source, sim_time_t t, receive_message_t* r) {
    sim_event_t* ackEvent = (sim_event_t*)malloc(sizeof(sim_event_t));
    
    ackEvent->mote = source;
    ackEvent->force = 1;
    ackEvent->cancelled = 0;
    ackEvent->time = t;
    ackEvent->handle = sim_gain_ack_handle;
    ackEvent->cleanup = sim_queue_cleanup_event;
    ackEvent->data = r;
    
    sim_queue_insert(ackEvent);
  }

  double prr_estimate_from_snr(double SNR) {
    // Based on CC2420 measurement by Kannan.
    // The updated function below fixes the problem of non-zero PRR
    // at very low SNR. With this function PRR is 0 for SNR <= 3.
    double beta1 = 0.9794;
    double beta2 = 2.3851;
    double X = SNR-beta2;
    double PSE = 0.5*erfc(beta1*X/sqrt(2));
    double prr_hat = pow(1-PSE, 23*2);
    dbg("CpmModelC,SNR", "SNR is %lf, PRR is %lf\n", SNR, prr_hat);
    if (prr_hat > 1)
      prr_hat = 1.1;
    else if (prr_hat < 0)
      prr_hat = -0.1;
	
    return prr_hat;
  }

  bool shouldReceive(double SNR) {

⌨️ 快捷键说明

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