从卡斯塔利亚设备的传感灵敏度计算传感范围?

Calculating sensing range from sensing sensitivity of the device in Castalia?

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

答案将根据所使用的 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 参数确定),则它只是 return 给出的最后一个传感器读数。如果它更大,则会生成新的传感器读数。

通过向 PhysicalProcess 模块(通过 toNodeContainerModule 门)发送 PhysicalProcessMessage 消息来获取新的传感器读数。在消息中我们传递节点的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;
}

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

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]);
....

因此您可以看到,如果该值低于传感器的灵敏度,则灵敏度的下限为 returned。

所以基本上你可以看到 Castalia 中没有特定的 'sensing range' - 这完全取决于特定的 PhysicalProcess 如何处理消息。在 CarsPhysicalProcess 的情况下,只要路上有车,它总是 return 一个值,不管距离有多远——如果汽车离节点很远,它可能会很小.如果该值非常小,您可能会收到最低的传感器灵敏度。您可以增加或减少 car_value 参数以获得更强的传感器响应(所以这有点像传感器范围)

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

如果要实现感应范围,则必须在 SensorManager.ned 中设置 devicesSensitivity 的值。然后在您的应用程序中,您将测试 returned 值是否大于灵敏度值 - 如果是,则汽车是 'in range',如果它(几乎)等于它的灵敏度超出范围。我说 almost 是因为(如我们之前所见)SensorManager 将 noise 添加到值 returned,例如,如果您灵敏度值为 5,并且没有汽车,您将获得略微徘徊在 5 左右的值(例如 5.0001、4.99)

设置灵敏度值后,计算感应范围(假设路上只有一辆车),这意味着简单地求解上面的距离方程,使用最小灵敏度值作为 returned 值.即如果我们使用 5 的灵敏度值:

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

代入参数值,用代数求解距离。