根据Castalia中设备的感应灵敏度计算感应范围?

时间:2017-10-11 11:07:06

标签: wireless omnet++

我正在Castalia中实现WSN算法。我需要计算传感设备的感应范围。我知道我需要使用传感灵敏度参数,但确切的等式是什么?

1 个答案:

答案 0 :(得分:3)

答案将根据所使用的PhysicalProcess模块​​指定的行为而有所不同。由于您在评论中说您可能正在使用CarsPhysicalProcess,因此请以此为例。

应用程序启动的传感器读取请求首先通过SensorReadingMessage消息发送到SensorManager。在SensorManager.cc中,您可以在handleMessage函数中看到如何处理它:

...
case SENSOR_READING_MESSAGE: {
    SensorReadingMessage *rcvPacket =check_and_cast<SensorReadingMessage*>(msg);
    int sensorIndex = rcvPacket->getSensorIndex();

    simtime_t currentTime = simTime();
    simtime_t interval = currentTime - sensorlastSampleTime[sensorIndex];
    int getNewSample = (interval < minSamplingIntervals[sensorIndex]) ? 0 : 1;

    if (getNewSample) { //the last request for sample was more than minSamplingIntervals[sensorIndex] time ago
        PhysicalProcessMessage *requestMsg =
            new PhysicalProcessMessage("sample request", PHYSICAL_PROCESS_SAMPLING);
        requestMsg->setSrcID(self); //insert information about the ID of the node
        requestMsg->setSensorIndex(sensorIndex);    //insert information about the index of the sensor
        requestMsg->setXCoor(nodeMobilityModule->getLocation().x);
        requestMsg->setYCoor(nodeMobilityModule->getLocation().y);

        // send the request to the physical process (using the appropriate 
        // gate index for the respective sensor device )
        send(requestMsg, "toNodeContainerModule", corrPhyProcess[sensorIndex]);

        // update the most recent sample times in sensorlastSampleTime[]
        sensorlastSampleTime[sensorIndex] = currentTime;
    } else {    // send back the old sample value

        rcvPacket->setSensorType(sensorTypes[sensorIndex].c_str());
        rcvPacket->setSensedValue(sensorLastValue[sensorIndex]);
        send(rcvPacket, "toApplicationModule");
        return;
    }
    break;
}
....

正如您所看到的,它所做的是首先计算出自此传感器的最后一次传感器读取请求以来已经过了多长时间。如果它的时间少于此传感器可能的minSamplingInterval指定的时间(这由SensorManager的maxSampleRates NED参数确定),它只返回给定的最后一个传感器读数。如果它更大,则会进行新的传感器读数。

通过向PhysicalProcess模块​​(通过PhysicalProcessMessage门)发送toNodeContainerModule消息来进行新的传感器读取。在消息中,我们传递节点的X和Y坐标。

现在,如果我们已将CarsPhysicalProcess指定为我们的omnetpp.ini文件中使用的物理进程,则CarsPhysicalProcess模块将收到此消息。您可以在CarsPhysicalProcess.cc

中看到这一点
....
case PHYSICAL_PROCESS_SAMPLING: {
    PhysicalProcessMessage *phyMsg = check_and_cast < PhysicalProcessMessage * >(msg);

    // get the sensed value based on node location
    phyMsg->setValue(calculateScenarioReturnValue(
        phyMsg->getXCoor(), phyMsg->getYCoor(), phyMsg->getSendingTime()));
    // Send reply back to the node who made the request
    send(phyMsg, "toNode", phyMsg->getSrcID());
    return;
}
...

您可以看到我们根据节点的X和Y坐标以及传感器读数的时间来计算传感器值。响应通过toNode门发送回SensorManager。因此,我们需要查看calculateScenarioReturnValue函数,以了解正在发生的事情:

double CarsPhysicalProcess::calculateScenarioReturnValue(const double &x_coo,
                    const double &y_coo, const simtime_t &stime)
{
    double retVal = 0.0f;
    int i;
    double linear_coeff, distance, x, y;

    for (i = 0; i < max_num_cars; i++) {
        if (sources_snapshots[i][1].time >= stime) {
            linear_coeff = (stime - sources_snapshots[i][0].time) /
                (sources_snapshots[i][1].time - sources_snapshots[i][0].time);
            x = sources_snapshots[i][0].x + linear_coeff * 
                (sources_snapshots[i][1].x - sources_snapshots[i][0].x);
            y = sources_snapshots[i][0].y + linear_coeff * 
                (sources_snapshots[i][1].y - sources_snapshots[i][0].y);
            distance = sqrt((x_coo - x) * (x_coo - x) +
             (y_coo - y) * (y_coo - y));
            retVal += pow(K_PARAM * distance + 1, -A_PARAM) * car_value;
        }
    }
    return retVal;
}

我们从传感器返回值0开始。然后我们遍历路上的每辆车(如果你查看TIMER_SERVICE函数中的handleMessage case语句,你会看到CarsPhysicalProcess根据car_interarrival速率随机地将汽车放在路上,最多可达max_num_cars辆汽车数量。对于每辆车,我们计​​算汽车沿着道路行驶的距离,然后计算汽车与节点之间的距离。然后,对于每辆车,我们根据公式添加返回值:

pow(K_PARAM * distance + 1, -A_PARAM) * car_value

distance是我们在汽车和节点之间计算的距离,K_PARAM = 0.1A_PARAM = 1(在CarsPhysicalProcess.cc顶部定义)和car_value是CarsPhysicalProcess.ned参数文件中指定的数字(默认为30)。

此值将传递回SensorManager。然后,SensorManager可能会根据传感器的灵敏度,分辨率,噪声和偏差(定义为SensorManager参数)更改此值:

....
case PHYSICAL_PROCESS_SAMPLING:
{
    PhysicalProcessMessage *phyReply = check_and_cast<PhysicalProcessMessage*>(msg);
    int sensorIndex = phyReply->getSensorIndex();
    double theValue = phyReply->getValue();

    // add the sensor's Bias and the random noise 
    theValue += sensorBias[sensorIndex];
    theValue += normal(0, sensorNoiseSigma[sensorIndex], 1);

    // process the limitations of the sensing device (sensitivity, resoultion and saturation)
    if (theValue < sensorSensitivity[sensorIndex])
        theValue = sensorSensitivity[sensorIndex];
    if (theValue > sensorSaturation[sensorIndex])
        theValue = sensorSaturation[sensorIndex];

    theValue = sensorResolution[sensorIndex] * lrint(theValue / sensorResolution[sensorIndex]);
....

因此,您可以看到,如果该值低于传感器的灵敏度,则会返回灵敏度的最低值。

所以基本上你可以看到没有特定的感应范围&#39;在Castalia中 - 这完全取决于特定的PhysicalProcess如何处理消息。在CarsPhysicalProcess的情况下,只要路上有一辆汽车,无论距离如何,它总会返回一个值 - 如果汽车距离节点很远,它可能会非常小。如果该值非常小,则可能会获得最低的传感器灵敏度。您可以增加或减少car_value参数以获得传感器的更强响应(因此这有点像传感器范围)

修改--- 默认灵敏度(您可以在SensorManager.ned中找到)为0.因此,对于CarsPhysicalProcess,任何距离的道路上的任何车辆都应该被检测到并返回为大于0的值。换句话说,无限制范围。如果汽车非常非常远,它可能会返回一个很小的数字,它会被截断为零(这取决于c ++实现中double值精度的限制)

如果您想要实现感应范围,则必须在devicesSensitivity中设置SensorManager.ned的值。然后在您的应用程序中,您将测试返回的值是否大于灵敏度值 - 如果是,则车辆在范围内,如果它(几乎)等于其灵敏度。超出范围。我说几乎因为(正如我们之前看到的那样),SensorManager会将 noise 添加到返回的值中,例如,如果您的敏感度值为5,并且没有汽车,你会得到略微徘徊在5左右的值(例如5.0001,4.99)

设置灵敏度值,计算感应范围(假设道路上只有1辆车),这意味着只需使用最小灵敏度值作为返回值,就上述等式求解距离。即如果我们使用灵敏度值为5:

 5 = pow(K_PARAM * distance + 1, -A_PARAM) * car_value

替换参数的值,并使用代数来求解距离。