为什么Castalia中的物理过程输出错误的数据?

时间:2018-10-06 04:24:28

标签: omnet++

我正在尝试在Castalia中模拟一个传感器阵列,该传感器阵列每个节点可以使用多个传感器,但是当我运行模拟时,它将传感器名称作为一项,最后显示传感器索引和传感器值首先提到。请帮忙!!如何获取每个节点检测多个传感器的信息 omn​​etpp.ini(值报告)

[General]

# ==========================================================
# Always include the main Castalia.ini file
# ==========================================================

include ../Parameters/Castalia.ini

sim-time-limit = 600s

SN.field_x = 100                    # meters
SN.field_y = 100                    # meters

SN.numNodes = 36
SN.deployment = "6x6"

SN.node[*].Communication.Radio.RadioParametersFile = "../Parameters/Radio/CC2420.txt"

SN.node[*].Communication.MACProtocolName = "TMAC"

SN.node[*].Communication.RoutingProtocolName = "MultipathRingsRouting"
#SN.node[*].Communication.Routing.collectTraceInfo = true

SN.node[*].ApplicationName = "ValueReporting"
SN.node[3].Application.isSink = true

# test 2 physical processes
SN.numPhysicalProcesses = 2  
SN.physicalProcess[0].printDebugInfo = true 
SN.physicalProcess[1].printDebugInfo = true 
SN.physicalProcess[0].description = "Degrees Celsius"  
SN.physicalProcess[1].description = "Blood Glucose"     
SN.physicalProcess[0].inputType = 1         
SN.physicalProcess[1].inputType = 1         
#SN.physicalProcess[0].directNodeValueAssignment = "(0) 0:25 1:23 2:21 3:24 4:26"
#SN.physicalProcess[1].directNodeValueAssignment = "(0) 0:360 1:380 2:375 3:390 4:390"
SN.node[*].SensorManager.​numSensingDevices = 2 
SN.node[*].SensorManager.​sensorTypes = "Temperature Bloodglucose" 
SN.node[*].SensorManager.​corrPhyProcess = "0 1"

在SensorManager.ned文件中,我更改了这些行,因为文件的其余部分一切都保持不变

string sensorTypes = default ("Temperature,Bloodglucose");
    // string array of comma-separated Names for the sensing devices

string corrPhyProcess = default ("0,1");

现在温度物理过程文件 TemperaturePhysicalProcess.ned

package physicalProcess.temperaturePhysicalProcess;

simple TemperaturePhysicalProcess like physicalProcess.iPhysicalProcess {
 parameters:
    bool collectTraceInfo = default (true);

    double temperature = default (37); //normal body temperature is 37 degrees celcius


    string description = default ("Degrees Celsius");

 gates:
    output toNode[];
    input fromNode[];
}

TemperaturePhysicalProcess.h

#ifndef _TEMPERATUREPHYSICALPROCESS_H_
#define _TEMPERATUREPHYSICALPROCESS_H_

#define SIMTIME_STEP 0.01

#include "CastaliaModule.h"
#include "PhysicalProcessMessage_m.h"

using namespace std;

typedef struct {
    simtime_t time;
    double x;
    double y;
} sourceSnapshot;

class TemperaturePhysicalProcess: public CastaliaModule {
 private:
    bool printDebugInfo;

    int temperature; 

    const char *description;
protected:
    virtual void initialize();
    virtual void handleMessage(cMessage * msg);
    virtual void finishSpecific();
};

#endif

TemperaturePhysicalProcess.cc

#include "TemperaturePhysicalProcess.h"

Define_Module(TemperaturePhysicalProcess);

void TemperaturePhysicalProcess::initialize()
{

    temperature=37;  
    //Search for snapshots in castalia manual
}

void TemperaturePhysicalProcess::handleMessage(cMessage * msg)
{
    if (msg->getKind() != PHYSICAL_PROCESS_SAMPLING)
    {
        opp_error("Physical Process received message other than PHYSICAL_PROCESS_SAMPLING");
    }

    PhysicalProcessMessage *receivedMsg = check_and_cast < PhysicalProcessMessage * >(msg);
    int nodeIndex = receivedMsg->getSrcID();

    // Send reply back to the node who made the request
    receivedMsg->setValue(temperature);
    send(receivedMsg, "toNode", nodeIndex);
}

void TemperaturePhysicalProcess::finishSpecific() {}

现在我们将进入血糖物理过程 BloodGlucoseLevelPhysicalProcess.ned

package physicalProcess.bloodGlucoseLevelPhysicalProcess;

simple BloodGlucoseLevelPhysicalProcess like physicalProcess.iPhysicalProcess {
 parameters:
    bool collectTraceInfo = default (false);
    int averagebloodglucose = default (100); // the amount is in mg per dL
    int age = default (20);
    string description = default ("Blood Glucose");

 gates:
    output toNode[];
    input fromNode[];
}   

BloodGlucoseLevelPhysicalProcess.h

#ifndef _BLOOODGLUCOSELEVELPHYSICALPROCESS_H_
#define _BLOOODGLUCOSELEVELPHYSICALPROCESS_H_

#define SIMTIME_STEP 0.01

#include "CastaliaModule.h"
#include "PhysicalProcessMessage_m.h"

using namespace std;

typedef struct {
    simtime_t time;
    double x;
    double y;
} sourceSnapshot;

class BloodGlucoseLevelPhysicalProcess: public CastaliaModule {
 private:
    bool printDebugInfo;
    int averagebloodglucose;
    double A1c;
    const char *description;
protected:
    virtual void initialize();
    virtual void handleMessage(cMessage * msg);
    virtual void finishSpecific();
};

#endif

BloodGlucoseLevelLevelPhysicalProcess.cc

#include "BloodGlucoseLevelPhysicalProcess.h"

Define_Module(BloodGlucoseLevelPhysicalProcess);

void BloodGlucoseLevelPhysicalProcess::initialize()
{
    averagebloodglucose = par("averagebloodglucose");
    description = par("description").stringValue();
    A1c = (46.7 + averagebloodglucose) / 28.7;
    //Search for snapshots in castalia manual

}

void BloodGlucoseLevelPhysicalProcess::handleMessage(cMessage * msg)
{
    if (msg->getKind() != PHYSICAL_PROCESS_SAMPLING)
        opp_error("Physical Process received message other than PHYSICAL_PROCESS_SAMPLING");

    PhysicalProcessMessage *receivedMsg = check_and_cast < PhysicalProcessMessage * >(msg);
    int nodeIndex = receivedMsg->getSrcID();
    //int sensorIndex = receivedMsg->getSensorIndex();
    double returnValue;

    // Send reply back to the node who made the request
    //receivedMsg->setValue(returnValue);
    receivedMsg->setValue(A1c);
    send(receivedMsg, "toNode", nodeIndex);

}

void BloodGlucoseLevelPhysicalProcess::finishSpecific() {

}

由于我正在使用ValueReporting应用程序运行模拟 ValueReporting.h

#define _VALUEREPORTING_H_

#include "VirtualApplication.h"
#include "ValueReportingPacket_m.h"

using namespace std;

enum ValueReportingTimers {
    REQUEST_SAMPLE = 1,
    SEND_DATA = 2,

};

class ValueReporting: public VirtualApplication {
 private:
    double maxSampleInterval;
    double minSampleInterval;

    int routingLevel;
    double lastSensedValue;
    int currSentSampleSN;

    double randomBackoffIntervalFraction;
    bool sentOnce;

    int recipientId;
    string recipientAddress;

 protected:
    void startup();
    void fromNetworkLayer(ApplicationPacket *, const char *, double, double);
    void handleSensorReading(SensorReadingMessage *);
    void timerFiredCallback(int);
    void requestSensorReading(const char *);


};

#endif              // _VALUEREPORTING_APPLICATIONMODULE_H_

ValueReporting.cc

#include "ValueReporting.h"
#include <iostream>   // std::cout
#include <iomanip>
#include <string>     // std::string, std::to_string
#include <stdlib.h>     /* atof */
#include <math.h>
#include<sstream>
#include <cstring>
#include <vector>
#include <array>
#include <string>
#include <algorithm>

Define_Module(ValueReporting);

void ValueReporting::startup()
{
    maxSampleInterval = ((double)par("maxSampleInterval")) / 1000.0;
    minSampleInterval = ((double)par("minSampleInterval")) / 1000.0;
    currSentSampleSN = 0;
    randomBackoffIntervalFraction = genk_dblrand(0);
    sentOnce = false;
    setTimer(REQUEST_SAMPLE, maxSampleInterval * randomBackoffIntervalFraction);
}

void ValueReporting::timerFiredCallback(int index)
{
    switch (index) {

        case REQUEST_SAMPLE:{
            requestSensorReading("Temperature");
            //requestSensorReading("Urine");

            setTimer(REQUEST_SAMPLE, maxSampleInterval);

            break; 
        }      
    }
}

void ValueReporting::fromNetworkLayer(ApplicationPacket * genericPacket,
         const char *source, double rssi, double lqi)
{
    ValueReportingDataPacket *rcvPacket = check_and_cast<ValueReportingDataPacket*>(genericPacket);
    ValueReportData theData = rcvPacket->getExtraData();

        trace() << "Sink received from: " << theData.nodeID << " \tvalue=" << rcvPacket->getData();

}
void ValueReporting::handleSensorReading(SensorReadingMessage * rcvReading)
{
    int sensIndex =  rcvReading->getSensorIndex();

     string sensType(rcvReading->getSensorType());

    double sensValue = rcvReading->getSensedValue();

    double x_coor = mobilityModule->getLocation().x; 
    double y_coor = mobilityModule->getLocation().y;
string sensorindex = to_string(sensIndex);
    string sensvalue = to_string(sensValue);
    string xcoor = to_string(x_coor);
    string ycoor = to_string(y_coor);


    string sensorinfo= sensorindex + " " + sensvalue + " " + xcoor + " " + ycoor + " " + sensType;
    trace() << sensorinfo; 
ValueReportData tmpData;
    tmpData.nodeID = (unsigned short)self;
    tmpData.locX = mobilityModule->getLocation().x;
    tmpData.locY = mobilityModule->getLocation().y;

    ValueReportingDataPacket *packet2Net =
        new ValueReportingDataPacket("Value reporting pck", APPLICATION_PACKET);
    packet2Net->setExtraData(tmpData);
    packet2Net->setData(sensValue);
    packet2Net->setSequenceNumber(currSentSampleSN);
    currSentSampleSN++;

    toNetworkLayer(packet2Net, SINK_NETWORK_ADDRESS);
    //toNetworkLayer(packet2Net, "6");
    sentOnce = true;
}
void ValueReporting::requestSensorReading(const char * type){
    SensorReadingMessage *reqMsg =
        new SensorReadingMessage("App to Sensor Mgr: sample request", SENSOR_READING_MESSAGE);

    if(type == "Temperature"){
    reqMsg->setSensorType(type);
    reqMsg->setSensorIndex(0);
    }
if(type =="BloodGlucose"){
    reqMsg->setSensorType(type);
    reqMsg->setSensorIndex(1);
    }
    send(reqMsg, "toSensorDeviceManager");
}

1 个答案:

答案 0 :(得分:0)

我注意到的一些事情

PhysicalProcess模块​​中没有printDebugInfo参数。可能您追捕的是collectTraceInfo

如果您只想更新某些参数所取的值,那么编辑ned文件不是一个好主意。这就是ini文件的用途。因此,无需更改ned文件中的默认值,只需在ini文件中分配这些值即可。例如,您已经在ini文件中分配了以下参数:

SN.node[*].SensorManager.​sensorTypes = "Temperature Bloodglucose" 
SN.node[*].SensorManager.​corrPhyProcess = "0 1"

您也不需要在ned文件中设置它们。还要注意,在ned文件中,您将第二个字符串设置为“ 0,1”而不是“ 0 1”。 ini文件将覆盖ned文件的值,因此您将得到“ 0 1”。幸运的是,空格分隔的值是正确的语法。

然后,您开始定义新的.ned .cc和.h文件。为什么?这些没有任何作用。您尚未在ini文件中设置变量SN.physicalProcessName。这意味着它将采用默认值CustomizablePhysicalProcess。您似乎将物理过程模块视为CustomizablePhysicalProcess,因为我看到您定义了它们的参数inputTypedirectNodeValueAssignment,它们仅在CustomizablePhysicalProcess模块中存在。因此,我不理解尝试完全定义新的物理过程模块会得到什么。

由于您有2个物理过程,这意味着每个节点中的SensorManager需要连接到这2个物理过程(定义您的物理过程的2个模块)。为此,只需将SensorManager的所有参数设置为2个项的数组即可(定义为一个数组(格式为以空格分隔的字符串))。

您可以在SensorManager.ned中找到所有相关参数(但不要编辑ned文件,只需在ini文件中进行设置即可)。以下是仅供参考的参数(请注意,您已经在ini文件中设置了sensorTypescorrPhyProcess ,您只需还要设置其余的):

string pwrConsumptionPerDevice = default ("0.02");
string sensorTypes = default ("Temperature");   // Humidity OR Temperature OR Light
string corrPhyProcess = default ("0");      //holds the indexes of the corresponding phy processes for
                                            //each sensor (usually it should be : "0 1 2 3")
string maxSampleRates = default ("1");      //number of samples per second for each sensor
string devicesBias = default ("0.1");       //If the output signal is not zero when the measured property is zero
string devicesDrift = default ("");         //If the output signal slowly changes independent of the 
                                            //measured property                     
string devicesNoise = default ("0.1");      //random deviation of the signal that varies in time
string devicesHysterisis = default ("");    //the sensor not instantly follows the change of the property 
                                            //being measured and therefore involves the history of the 
                                            //measured property
string devicesSensitivity = default ("0");  //holds the minimum value which can be sensed by each sensing device.
string devicesResolution = default ("0.001");   //holds the sensing resolution for each device 

我不确定多个phyProcesses和多种感应方式是否存在其他问题,因为此功能尚未在2.0之后的版本中进行过测试,因此可能根本无法使用(但希望它做了一些小的调整才能使其正常工作)。