omnetpp: reading module parameters - omnet++

I have the following module defined in a ned file:
#namespace(cbsdsim);
simple SASSim {
parameters:
#class(SASSim);
int maxCbsdsPerSas = 10;
}
I create the module by calling the following (from another module):
cModuleType* sasSimModType = cModuleType::find("SASSim");
sasSimModType->setName("SASSim");
char* name = "SAS.1";
SASSim* sasSimMod = (SASSim*) sasSimModType->create(name,parent);
The constructor for SASSim gets called. Here is the constructor:
SASSim::SASSim() {
cout << " SASSim::SASSim" << endl;
//this->finalizeParameters();
int cbsdFanIn = par("maxCbsdPerSas");
.....
}
However omnetpp is unhappy about calling par(...) in the code fragment above. I get an exception and a confusing error message:
what(): (omnetpp::cModule): Object has no associated cComponentType (maybe omnetpp::cModule is not derived from cModule/cChannel?)
Indeed when I add this->getNumParams() in the constructor it returns 0. If I hard code the parameter, the initialization works fine so I assume I need to do something in order to load the parameters. I could, presumably put the parameters in omnetpp.ini or elsewhere but I would like to know why this does not work.Do I have to do something prior to calling create to load the params? Thanks,

You can only access the parameters after initialization - not in the constructor of the Module. This is a bit strange because creating cGates etc. works fine from the constructor.

Related

How to dynamically change a parameter of module from another one in OMNeT++5.5?

I have written a line of codes in omnetpp.ini file like:
S.node[0..4].forwarding = false
What I want to do is change the parameter "forwarding" dynamically (dynamically switching between true and false) in UDPBasicApp module.
void UDPBasicApp::processForwardSwitch(){
if (isSelfish) {
//std::cout << host->par("forwarding").str() << std::endl;
if (rand()%10<5)
host->par("forwarding").setBoolValue(false);
else
host->par("forwarding").setBoolValue(true);
}
scheduleAt(simTime()+forwardSwitchInterval, forwardSwitchTimer);
}
I can confirm the value of the parameter does changes during simulation, but it seems no effect to the modules related to this parameter, e.g. routing modules.
Anyone help?
Thanks in advance!
Usually parameters are read only once, during initialization of a module.

OMNET++ how to access function or variables in another class

I have modified inet NodeStatus.cc with a customized function that return the variable value as follows:
int NodeStatus::getValueA()
{
return ValueA;
}
Then, I created another simple module called simpleNodeB.cc and I wanted to retrieve ValueA from NodeStatus.cc. I tried the following code in simpleNodeB.cc but didn't work:
if(getParentModule()->getSubModule(NodeStatus).getValueA()==test1)
bubble("Value is the same");
The error message I got -> error: expected expected primary-expression before ')' token. I'm not sure if I used the correct way to call getValueA() function. Please enlighten me. thanks a lot.
There are many errors in your code.
The method getSubmodule requires a name of module, not a name of class. Look at your NED file and check the actual name of this module.
getSubmodule returns a pointer to the cModule object. It has to be manually cast into another class.
Assuming that an NodeStatus module in your NED is named fooStatus the correct code should look like:
cModule *mod = getParentModule()->getSubmodule("fooStatus");
NodeStatus *status = check_and_cast<NodeStatus*>(mod);
if(status->getValueA() == test1)
bubble("Value is the same");
Reference: OMNeT++ Manual.

Expected behaviour? MATLAB ignores errors on deserialization, except when in debug mode

I don't understand Matlab's behaviour in the example below. On deserialization, it sets the properties of the object. This causes set.name to be executed. For the purpose of the example, I have constructed a case where an error is thrown in this method. In the first deserialization, the error is ignored and unhandled; the function simply stops execution at the error, code after the error is not executed. On the second deserialization, I have set dbstop if error, and now the error is triggered as I would expect. Questions follow below the example.
>> clear all;
>> dbstatus;
>> type Tester.m;
classdef Tester < handle
properties
name;
end
methods
function self = Tester()
disp('Creating Tester object');
end
function set.name(self, val)
global allnames
if isequal(allnames, [])
allnames = {};
end
if any(strcmp(allnames, val))
fprintf(1, 'Name already exists. Will issue error.\n');
error('Error: duplicate name %s', val);
fprintf(1, 'Still here?\n');
else
self.name = val;
allnames = [allnames self.name];
end
end
end
end
>> t = Tester();
Creating Tester object
>> t.name = 'abc';
>> save('/tmp/fubar.mat', 't');
>> load('/tmp/fubar.mat')
Name already exists. Will issue error.
>> dbstop if error
>> load('/tmp/fubar.mat')
Name already exists. Will issue error.
Error using Tester/set.name (line 18)
Error: duplicate name abc
18 error('Error: duplicate name %s', val);
K>> dbquit
Should I be surprised at this behaviour?
Is this MATLABâ„¢ being strange, or would other programming languages engage similar behaviour?
Is there a good reason to behave like this?
Probably the deserialization code uses a try-catch construct that does not rethrow the errors. I can see some uses for this, as faults in the load code would at least give you partial access to your data. On the other hand, it should warn you when it does something like this.
When it really can't load the data (this happens e.g. when your classdef file is not in the path), it will show a notice.
So IMHO, you should be both happy and sad: an error would at least give you partial results, on the other hand MATLAB should at least throw a warning that such a thing happened.
With regard to your specific code: I think that global variable is not the best way to go, as a global variables is stored independently from your objects. I'd go with a class variable (i.e. static) if possible. Because now you depend on the global variable names in your workspace, which is not saved in the MAT file as far as I know.

Xcode error on using class method by method of the same class

I have a class that have class method "getSimulatedPricesFrom". It will call method "projectFromPrice" from the same class during the execution. However in the line sTPlus1 line, I encounter the 2 errors:
1) Class method "projectFromPrice" not found
2) Pointer cannot be cast to type "double"
Does anyone have idea on why? I have already declare the method in .h file
Below is part of the coding in AmericanOption.m file:
#import "AmericanOption.h"
#implementation AmericanOption
+(NSMutableArray*)getSimulatedPricesFrom:(double)s0 withRate:(double)r0 withVol:(double)v0 withDays:(int)D withPaths:(int)N
{
double daysPerYr = 365.0;
double sT;
double sTPlus1;
sT = s0;
...
sTPlus1 = (double)[AmericanOption projectFromPrice:sT, r0/daysPerYr, v0/daysPerYr, 1/daysPerYr];
...
return arrPricePaths;
}
+(double)projectFromPrice:(double)s0 withRate:(double)r0 withVol:(double)v0 withDt:(double)dt
{
...
}
It looks like you should call the projectFromPrice method as follows:
sTPlus1 = [AmericanOption projectFromPrice:sT
withRate:r0/daysPerYr
withVol:v0/daysPerYr
withDt:1/daysPerYr];
In your example code you are just providing a comma separated list of parameters. You should use the named parameters of the method.
The first of the two errors is because the method projectFromPrice: is not the same as the method projectFromPrice:withRate:withVol:withDt:.
projectFromPrice:withRate:withVol:withDt: is the method that actually exists and is presumably defined in your interface (.h file). projectFromPrice: is the method that you are trying to call but it doesn't exist.
The second error is a result of the compiler assuming that the undefined projectFromPrice: method returns an id (a pointer) which can't be cast to a double.
This is the way you call your second methods that seems to be the problem. Try this, instead :
+(NSMutableArray*)getSimulatedPricesFrom:(double)s0 withRate:(double)r0 withVol:(double)v0 withDays:(int)D withPaths:(int)N
{
double daysPerYr = 365.0;
double sT;
double sTPlus1;
sT = s0;
...
sTPlus1 = (double)[AmericanOption projectFromPrice:sT withRate:r0/daysPerYr withVol:v0/daysPerYr withDt:1/daysPerYr];
...
return arrPricePaths;
}
+(double)projectFromPrice:(double)s0 withRate:(double)r0 withVol:(double)v0 withDt:(double)dt
{
...
}

Passing a boost::bimap between functions

I'm new to the bimap functionality of the Boost libraries, and I'm having trouble passing a bimap into another function. My bimap looks like this:
typedef boost::bimap< int, int > bimap_type;
bimap_type bm;
I have an add_values() function that adds a set of values to the bimap:
add_values(int a, int b)
{
bm.insert(bimap_type::value_type(a, b));
}
I then have a function that is meant to set the values of the bimap by getting them from a Singleton Class:
void set_values()
{
MyClass::instance()->get_values(bm);
}
And, in MyClass, get_values() looks like this:
void get_values(bimap_type myBimap)
{
myBimap.add_values(3, 5);
}
However, MyClass does not recognise 'bimap_type'. I try putting the typedef in a separate header file and including that in MyClass, but I get the error message:
'class bimap_type' has no member named 'add_values'
How can I successfully pass the bimap to this Singleton Class in order to fill it with values from the Class? Does anyone know?
Thanks a lot.
Er, boost::bimap itself doesn't have an add_values method and it's hard to tell from these code fragments why you're suddenly expecting one to appear.
Consider renaming your functions: set_values() that calls get_values() that calls add_values() is one confusing call chain...
When you need to modify an object in a function, you have to take it by reference (or a pointer). The idea is that you must work with the same object inside and outside of the function. If you pass by value, function will see a copy, so anything it does with it does not reflect on original object.
// formerly known as add_values()
void initialize(bimap_type& bm, int a, int b)
{
bm.insert(bimap_type::value_type(a, b));
}
And this is how you will call it:
initialize(myBitmap, 3, 5);
Make sure to update your whole call chain to pass by reference where appropriate, because currently your get_values() works with a copy too.

Resources