par() from .ini file unexpected behaviour - omnet++

I am trying to get a value (iatDistribution) from the .ini file to run in the simulation but it will not work.
I have tried hard-coding a value in and it works. But using the variable it won't work.
.cc File
void PacketGen::initialize()
{
int seqno = 0;
int txId = getParentModule()->par("nodeId");
int messageSize = par("messageSize");
double distro = par("iatDistribution");
scheduleAt(simTime(), new cMessage); //sends the initial message!
}
void PacketGen::handleMessage(cMessage *msg)
{
appMessage* message = createMessage();
send(message, "out0");
scheduleAt((distro + simTime()), msg);
}
.ini File
#Gen & Sink
simulation.TXNode[*].packGen.messageSize = 64
simulation.TXNode[*].packGen.iatDistribution = 0.1
packGen.ned file
simple PacketGen
{
parameters:
int messageSize;
double iatDistribution;
gates:
output out0;
}
When a value like 0.1 replaces distro in the scheduleAt((distro + simTime()), msg); line, the simulation time increases but when trying to use the distro variable it does not.

In initialize() you assigned the value of parameter iatDistribution into local variable distro. And probably you have declared variable distro as a member of PacketGen class.
Therefore change the line:
double distro = par("iatDistribution");
into:
distro = par("iatDistribution");

Related

Why is physical process in Castalia outputting wrong data?

I am trying to simulate a sensor array in Castalia capable of using more than one sensor per node but when I run the simulation it takes the names of the sensors as one item and ends up displaying the sensor index and value of the sensor mentioned first. Please help!! how can I get it to detect more than one sensor per node
omnetpp.ini (valueReporting)
[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"
In the SensorManager.ned file, I changed these lines as for the rest of the file everything is left as is
string sensorTypes = default ("Temperature,Bloodglucose");
// string array of comma-separated Names for the sensing devices
string corrPhyProcess = default ("0,1");
Now the temperature physical process files
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() {}
Now we'll go to the Blood Glucose physical process
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() {
}
Since I'm running the simulation using the ValueReporting application
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");
}
Some things I noticed:
There is no printDebugInfo parameter in the PhysicalProcess module. Probably what you are after is collectTraceInfo.
If you just want to update the values some parameters take, it's not a good idea to edit ned files. This is what ini files are for. So instead of changing the default values in ned files, simply assign these values in your ini file. For example, you already assign these parameters in your ini file:
SN.node[*].SensorManager.​sensorTypes = "Temperature Bloodglucose"
SN.node[*].SensorManager.​corrPhyProcess = "0 1"
You do not need to set them in the ned file as well. Also notice that in the ned file you set the second string as "0,1" not "0 1". The ini file will override the value of the ned file, so what you'll get it "0 1". Fortunately, space separated values is the correct syntax.
You then start defining new .ned .cc and .h files. Why? These do not have any effect. You have not set the variable SN.physicalProcessName in your ini file. This means it takes the default value which is CustomizablePhysicalProcess. You seem to be treating your physical process modules as CustomizablePhysicalProcess because I see you define their parameters inputType and directNodeValueAssignment, which only exist for the CustomizablePhysicalProcess module. So I do not understand what you expect to get by trying to define new physical process modules altogether.
Since you have 2 physical processes, it means that the SensorManager in every node needs to connect to these 2 physical process (the 2 modules that define your physical processes). To do this just set all the parameters of your SensorManager that can be defined as an array (formatted as a space-separated string) as arrays of 2 items.
You can find all relevant parameters in the SensorManager.ned (but do NOT edit the ned file, just set them in your ini file). Here are the parameters just for reference (note that you have already set sensorTypes and corrPhyProcess in your ini file, you just need to also set the rest) :
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
I am not sure whether there are other problems with multiple phyProcesses and multiple sensing modalities, because this feature has not been tested in versions after 2.0, so it might not work at all (but hopefully it's a small adjustment to make it work).

Can I use an if statement to compare a string parameter in the .ned file- omnet++?

Can someone help me with the syntax please? I marked the erroneous part
I need to find the correct syntax for if statements in the .ned file of omnet++
simple Source
{
parameters:
#group(Queueing);
#signal[created](type="long");
#statistic[created](title="the number of jobs created"; record=last; interpolationmode=none);
string jobName = default("job");
double startTime #unit(s) = default(interArrivalTime); // when the module sends out the first job
double stopTime #unit(s) = default(-1s); // when the module stops the job generation (-1 means no limit)
if (jobName =="SimpleEvent"){ //syntax here is wrong!
volatile int eventType = default(intuniform(1,3));
}
gates:
inout out; //modified
}
In NED one can use an if condition only for connections and submodules. Parameters have to be declared without condition. So in your code should look like:
double startTime #unit(s) = default(interArrivalTime); // when the module sends out the first job
double stopTime #unit(s) = default(-1s); // when the module stops the job generation (-1 means no limit)
volatile int eventType = default(intuniform(1,3));

Memory allocation of string literal in c

I am having a strange issue with memory allocation in c, the file is fairly complicated so I cannot include it all here but perhaps you can point me in the right direction as to why this may be happening.
I am trying to create a string literal as such:
char * p = "root"
But when i look at the value of this variable at runtime (at the line directly after the declaration) i get this:
$1 = 0x7001260c "me"
and when I look at the contents of the memory at 0x7001260c it indeed holds the string "me".
EDIT:
To give more context when I run the following code the value of p on the last line is "root".
create_directory("root/home");
char * p = "root";
char * q = "foo";
And when I run the following code the value of p is "io"
create_directory("io/home");
char * p = "root";
char * q = "foo";
The create_directory function:
void create_directory(char * path) {
directory d;
directory * dir = &d;
//Browse to closest directory
path = find_directory(path, dir);
//Create remaining directories
char component[20];
path = next_component(path, component);
while (strlen(component) > 0) {
add_dir_entry(dir, component, inode_next);
write_dir_entry(dir, inode_to_loc(dir->inode));
directory new;
new.type = DIRECTORY;
new.inode = inode_next;
write_dir_entry(&new, inode_to_loc(inode_next));
inode_next++;
dir = &new;
path = next_component(path, component);
}
}
Almost certainly, there's a bug somewhere in your program that causes a constant to be modified which is, of course, illegal. Perhaps you're doing something like this:
void to_lower(char *j)
{
while (*j != 0) { *j = tolower(*j); j++; }
}
...
bool is_yes(char *k)
{
to_lower(k);
return strcmp(k, "yes") == 0;
}
void someFunc(char *k)
{
if (is_yes(k)) // ...
...
}
someFunc("testing");
See what this does? We pass a pointer to a constant to sumeFunc, but it flows down to to_lower which modifies the thing it points to -- modifying a constant.
Somehow, your code probably does something like that.
Start by changing code like char * p = "root" to code like char const* p = "root". That will give you a better chance of catching this kind of problem at compile time.

Cannot read and write to the same file in an exported Processing app

I am using an external .txt file to save the incrementing name index for whenever someone "takes a picture" in my app (i.e. image_1.jpg, image_2.jpg, etc...). I am trying to save the data externally so that a user does not overwrite their pictures each time they run the program. However, because of the way that Processing packages its contents for export I cannot both read and write to the same file. It reads the appropriate file located in the apps package contents, however, when it tries to write to that file, it creates a new folder in the same directory as the app itself and writes to a new file with the same name instead.
Essentially, it reads the proper file but refuses to write to it, instead making a copy and writing to that one. The app runs fine but every time you open it and take pictures you overwrite the images you already had.
I have tried naming the "write to" location the explicitly same link as where the exported app stores the data folder inside the package contents (Contents/Resources/Java/data/assets) but this creates a copy of this directory in the same file as the app.
I have also tried excluding the file I am trying to read/write from my data folder when I export the app by changing the read code to ../storage/pictureNumber.txt and then putting this file next to app itself. When I do this the app doesn't launch at all because it is looking in its own data folder for storage and refuses to go outside of itself with ../ . Has anyone had luck both reading from and writing to the same file in an exported processing .app?
Here is the code for the class that is handling the loading and saving of the file:
class Camera {
PImage cameraImage;
int cameraPadding = 10;
int cameraWidth = 60;
int opacity = 0;
int flashDecrementer = 50; //higher number means quicker flash
int pictureName;
Camera() {
String[] pictureIndex = loadStrings("assets/pictureNumber.txt");
pictureName = int(pictureIndex[0]);
cameraImage = loadImage("assets/camera.jpg");
String _pictureName = "" + char(pictureName);
println(pictureName);
}
void display(float mx, float my) {
image(cameraImage, cameraPadding, cameraPadding,
cameraWidth, cameraWidth-cameraWidth/5);
}
boolean isOver(float mx, float my) {
if (mx >= cameraPadding &&
mx <= cameraPadding+cameraWidth &&
my >= cameraPadding &&
my <= cameraPadding+cameraWidth-cameraWidth/5) {
return true;
}
else {
return false;
}
}
void captureImage() {
save("pictures/"+lines.picturePrefix+"_"+pictureName+".jpg");
pictureName++;
String _null = "";
// String _tempPictureName = _null.valueOf(pictureName);
String[] _pictureName = {_null.valueOf(pictureName)};
saveStrings("assets/pictureNumber.txt", _pictureName);
println(_pictureName);
}
void flash() {
fill(255, opacity);
rect(0,0,width,height);
opacity -= flashDecrementer;
if(opacity <= 0) opacity = 0;
}
}
After a lot of searching I found that you have to use savePath() in order to read from a directory outside of the project.jar. The camera class constructor now looks like this:
path = savePath("storage");
println(path);
String[] pictureIndex = loadStrings(path+"/pictureNumber.txt");
pictureName = int(pictureIndex[0]);
cameraImage = loadImage("assets/camera.jpg");
String _pictureName = ""+char(pictureName);
and everything works!

Matlab MEX File: Program Crashes in the second run: Access Violation in Read

I have a C++ code that I am trying to interface with Matlab. My mex file runs fine in the first run but crashes in the second run. However, if I clear all the variables in the Matlab before execution (using clear all) program never crashes. So I have a question in this:
1. Can mex function takes variables from the Matlab workspace without using some special functions? Am I doing it somehow in my code, unintentionally?
I have a posted the mex function that I wrote. It has a one dimensional vector called "block" that is read inside the C++ function called sphere_detector. For the present problem the block size is 1x1920 and it is read in the chunk of 16 elements inside the sphere_detector. Program crashed when I read the SECOND chunk of 16 elements. The first element that I read in the chunk will throw this error:
First-chance exception at 0x000007fefac7206f (sphere_decoder.mexw64) in MATLAB.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
MATLAB.exe has triggered a breakpoint
I checked my block vector, it should have all the values initialized and it has that. So, I am little confused as to why I am facing this problem.
I am using Matlab 2010a and Visual Studio 2010 Professional.
Here is the mex function:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *mod_scheme, *Mt, *Mr, *block_length, *SNR;
mod_scheme = mxGetPr(prhs[0]);
Mt = mxGetPr(prhs[1]);
Mr = mxGetPr(prhs[2]);
block_length = mxGetPr(prhs[3]);
SNR = mxGetPr(prhs[4]);
/* Now take the input block. This is an encoded block and sphere detector will do the transmission too -- I can change it later */
double *block = mxGetPr(prhs[5]);
double *LIST_SIZE = mxGetPr(prhs[6]);
double **cand_sym;
int a = *mod_scheme;
int b = *Mt;
int c = *Mr;
int d = *block_length;
int e = *SNR;
int f = *LIST_SIZE;
int bitSize = (int)(log10(1.0*a)/log10(2.0));
for(int i=0; i<(int)*block_length; ++i)
{
printf("%d\n", (int)block[i]);
}
printf("Hello world %d %d %d %d %d!\n", (int)*mod_scheme, (int)*Mt, (int)*Mr, (int)*block_length, (int)*SNR);
/* Inputs are read correctly now set the outputs */
double *llr, *cand_dist;
/* for llrs */
plhs[0] = mxCreateDoubleMatrix(1, d, mxREAL);
llr = mxGetPr(plhs[0]);
/* for cand_dist */
int no_mimo_sym = d/(b*bitSize);
plhs[1] = mxCreateDoubleMatrix(1, f*no_mimo_sym, mxREAL);
cand_dist = mxGetPr(plhs[1]);
/* for cand_syms */
plhs[2] = mxCreateDoubleMatrix(b*bitSize*no_mimo_sym, f,mxREAL); //transposed version
double *candi;
candi = mxGetPr(plhs[2]);
cand_sym = (double**)mxMalloc(f*sizeof(double*));
if(cand_sym != NULL)
{
for(int i=0;i<f; ++i)
{
cand_sym[i] = candi + i*b*bitSize*no_mimo_sym;
}
}
sphere_decoder(a,b,c,d,e,block,f,llr,cand_dist,cand_sym);
// mxFree(cand_sym);
}
The portion inside the sphere decoder code where I get read exception looks like this:
for(int _block_length=0;_block_length<block_length; _block_length+=Mt*bitSize)
{
printf("Transmitting MIMO Symbol: %d\n", _block_length/(Mt*bitSize));
for(int _antenna = 0; _antenna < Mt; ++_antenna)
for(int _tx_part=0;_tx_part<bitSize; _tx_part++)
{
// PROGRAM CRASHES EXECUTING THIS LINE
bitstream[_antenna][_tx_part] = (int)block_data[_block_length + _antenna*bitSize + _tx_part];
}
............................REST OF THE CODE..................
}
Any help would be appreciated.
With regards,
Newbie
Well I finally managed to solve the problem. It was a very stupid mistake that I made. I had a pointer to a pointer(double *a;) of data type double and by mistake I assigned it memory of integer (I ran a find and replace command where I changed lots of int to double but this one left). Hence heap was getting corrupted. Also I changed my Mex function where I created dynamic variables using calloc and passed them to the C++ function. Once C++ function returned I copied there values to matlab variables and freed them usind free().

Resources