我正在尝试在Castalia中模拟一个传感器阵列,该传感器阵列每个节点可以使用多个传感器,但是当我运行模拟时,它将传感器名称作为一项,最后显示传感器索引和传感器值首先提到。请帮忙!!如何获取每个节点检测多个传感器的信息 omnetpp.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");
}
答案 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
,因为我看到您定义了它们的参数inputType
和directNodeValueAssignment
,它们仅在CustomizablePhysicalProcess
模块中存在。因此,我不理解尝试完全定义新的物理过程模块会得到什么。
由于您有2个物理过程,这意味着每个节点中的SensorManager需要连接到这2个物理过程(定义您的物理过程的2个模块)。为此,只需将SensorManager的所有参数设置为2个项的数组即可(定义为一个数组(格式为以空格分隔的字符串))。
您可以在SensorManager.ned中找到所有相关参数(但不要编辑ned文件,只需在ini文件中进行设置即可)。以下是仅供参考的参数(请注意,您已经在ini文件中设置了sensorTypes
和corrPhyProcess
,您只需还要设置其余的):
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之后的版本中进行过测试,因此可能根本无法使用(但希望它做了一些小的调整才能使其正常工作)。