I'm developing a network model in OMNeT++ in which I have introduced a custom channel type to represent links in my network. For one property of this channel type's instances, I'd like to assign a random parameter. However, the random number should be the same for connected gates.
My node definition has the following gates definition:
simple GridAgent
{
/* ... other paramters/definitions omitted ... */
gates:
inout agentConnections[];
}
In my network configuration, I connect nodes using the simple <--> syntax, e.g.:
someSwitchyard.agentConnections++ <--> AgentConnectionChannel <--> someWindfarm.agentConnections++;
Now, this AgentConnectionChannel has a property called impedance, which I'd like to randomly assign. This impedance property should be the same for both A -> B and B -> A. I have tried to add { impedance = default(unitform(1, 10)) } to the network definition, as well as putting **.agentConnections$o[*].channel.impedance = uniform(1, 10) into omnetpp.ini. In both cases, however, A -> B has a different value assigned than B -> A.
As indicated on the OMNet++ mailing list, this happens because the <--> syntax is actually a shorthand for creating two distinct connections, hence two drawings from the random number distribution happen.
How can I assign a random parameter to a connection's property and have the same value for both directions of two connected gates? Is there a way to do this in the omnetpp.ini file, or do I need to create a script in, e.g., Perl, Ruby, or Python to generate the omnetpp.ini for my runs?
There is no simple solution of your problem, and it could not be resolved manipulating omnetpp.ini file merely.
I propose manual rewriting a parameter value for the second direction. It requires preparing a C++ class for a channel (which you have probably done).
Assuming that your channel definition in NED is following:
channel AgentConnectionChannel extends ned.DatarateChannel {
#class(AgentConnectionChannel);
double impedance;
}
and in omnetpp.ini you has:
**.agentConnections$o[*].channel.impedance = uniform(1, 10)
you should prepare C++ class AgentConnectionChannel:
class AgentConnectionChannel: public cDatarateChannel {
public:
AgentConnectionChannel() : parAlreadyRewritten(false) {}
void setParAlreadyRewritten() {parAlreadyRewritten=true;}
protected:
virtual void initialize();
private:
bool parAlreadyRewritten;
private:
double impedance;
};
Define_Channel(AgentConnectionChannel);
void AgentConnectionChannel::initialize() {
if (parAlreadyRewritten == false) {
parAlreadyRewritten = true;
cGate * srcOut = this->getSourceGate();
cModule *owner = srcOut->getOwnerModule();
int index = srcOut->isVector() ? srcOut->getIndex() : -1;
cGate *srcIn = owner->gateHalf(srcOut->getBaseName(), cGate::INPUT,
index);
cChannel * channel = srcIn->findIncomingTransmissionChannel();
AgentConnectionChannel * reverseChan =
dynamic_cast<AgentConnectionChannel*>(channel);
if (reverseChan) {
reverseChan->setParAlreadyRewritten();
// assigning a value from forward direction channel
reverseChan->par("impedance") = this->par("impedance");
}
}
// and now read a parameter as usual
impedance = par("impedance").doubleValue();
EV << getFullPath() << ", impedance=" << impedance << endl;
}
Related
[RESOLVED]
I'm building a game engine that uses LuaBridge in order to read components for entities. In my engine, an entity file looks like this, where "Components" is a list of the components that my entity has and the rest of parameters are used to setup the values for each individual component:
-- myEntity.lua
Components = {"MeshRenderer", "Transform", "Rigidbody"}
MeshRenderer = {
Type = "Sphere",
Position = {0,300,0}
}
Transform = {
Position = {0,150,0},
Scale = {1,1,1},
Rotation = {0,0,0}
}
Rigidbody = {
Type = "Sphere",
Mass = 1
}
I'm currently using this function (in C++) in order to read the value from a parameter (given its name) inside a LuaRef.
template<class T>
T readParameter(LuaRef& table, const std::string& parameterName)
{
try {
return table.rawget(parameterName).cast<T>();
}
catch (std::exception e) {
// std::cout ...
return NULL;
}
}
For example, when calling readVariable<std::string>(myRigidbodyTable, "Type"), with myRigidbodyTable being a LuaRef with the values of Rigidbody, this function should return an std::string with the value "Sphere".
My problem is that when I finish reading and storing the values of my Transform component, when I want to read the values for "Ridigbody" and my engine reads the value "Type", an unhandled exception is thrown at Stack::push(lua_State* L, const std::string& str, std::error_code&).
I am pretty sure that this has to do with the fact that my component Transform stores a list of values for parameters like "Position", because I've had no problems while reading components that only had a single value for each parameter. What's the right way to do this, in case I am doing something wrong?
I'd also like to point out that I am new to LuaBridge, so this might be a beginner problem with a solution that I've been unable to find. Any help is appreciated :)
Found the problem, I wasn't reading the table properly. Instead of
LuaRef myTable = getGlobal(state, tableName.c_str());
I was using the following
LuaRef myTable = getGlobal(state, tableName.c_str()).getMetatable();
I wanted to know if there is a way to check and validate a field when using the CsvRoutines package. Basically I want to process a row if the first column has only numbers and skip/possibly throw an exception otherwise. I'm guessing #Validate annotation released in 2.7.0 can be used to achieve this. But I would like to know if there is any other way to achieve the same with earlier versions like 2.5.9?
Author of the library here. There's no other way other than updating to the latest version. Is there any reason in particular why you can't upgrade?
Update: you can put the #Parsed annotations on the class' getters or setters and perform the validations in them. That is probably the cleanest way to go about it. For example:
class Test {
private Integer number;
//accepts a String here... so this is straight from the parser before it tries to convert anything into an integer - which lets you validate or throw a custom exception
#Parsed
void setNumber(String number){
try{
this.number = Integer.valueOf(number);
} catch(NumberFormatException e){
throw new IllegalArgumentException(number + " is not a valid integer");
}
}
}
Another alternative is to use a custom conversion class. Copy the code of class ValidatedConversion, used in the newest version, then create subclass like:
public static class RangeLimiter extends ValidatedConversion {
int min;
int max;
public RangeLimiter(String[] args) {
super(false, false); //not null, not blank
min = Integer.parseInt(args[0]);
max = Integer.parseInt(args[1]);
}
protected void validate(Object value) {
super.validate(value); //runs the existing validations for not null and not blank
int v = ((Number) value).intValue();
if (v < min || v > max) {
throw new DataValidationException("out of range: " + min + " >= " + value + " <=" + max);
}
}
}
Now on your code, use this:
#Parsed(field = "number")
#Convert(conversionClass = RangeLimiter.class, args = {"1", "10"}) //min = 1, max = 10
public int number;
I didn't test this against an old version. I think you may need to set flag applyDefaultConversion=false in the #Parsed annotation, and make your conversion class convert a String into an int in addition to run the validations.
All in all, that's quite a bit of work that can easily be avoided just by upgrading to the latest version.
About:
p.s.I know this is a specific question, but I am at a loss, and have no idea why this is happening
The algorithm below should add a struct to a list. Each struct is a server_connection object, and the receiving list, is contained within another struct named VPN_Server.
When adding the struct to the list, it holds only the very first struct added, and does not add any more.
This is confirmed by the debugger window:
for each new IP, a new VPN_Server struct is created and a new server_connection is created and push_back'ed onto the ServerInstancesList list. But when in the foreach loop, attempting to add the object is fruitless.
Problem:
When pushing a server_connection object onto a specific VPN_Server struct, it holds this data in the temporary foreach container, but does not apply it.
I Have tried:
adding a custom addConnection() method to the VPN_Server struct
void addConnection(server_connection s_con){
ServerInstancesList.push_back(s_con);
}
Creating a temporary list, adding the server_connection and creating a new VPN_server object, and setting that equal to the current foreach container.
None of these help.
Testing & Indepth description:
In the algorithm, my 1st and 3rd vpn_connection struct have the same IP. On the third iteration, the foreach loop is executed and the following occurs.
VPN_Server ser contains info of the 1st struct info, i.e. an IP and one object in its QList<server_connection> called ServerInstancesList.
ser has an object added, via the addConnection(s_con). Afterwards, the loop is terminated with the return. However ser registered the added object, while outside the foreach loop, no new object was added. Not even to any struct within the list.
It seems to be an easy fix, but I just cannot find it,
help would be appreciated!
Code:
server_connection
struct server_connection{
//Is a connection contained by IP
QString cipher,protocol;
int port;
bool lzo_compression;
server_connection(){}
server_connection(QString _cipher, QString _protocol, int _port, bool _comp){
cipher = _cipher;
protocol = _protocol;
port = _port;
lzo_compression = _comp;
}
};
VPN_Server
struct VPN_Server{
//Holds IP as sort value and list of connection info
QString VPN_IP;
QList<server_connection> ServerInstancesList;
VPN_Server(){
ServerInstancesList = QList<server_connection>();
}
VPN_Server(QString ip, QList<server_connection> server_con_list){
VPN_IP = ip;
ServerInstancesList = server_con_list;
}
void addConnection(server_connection s_con){
ServerInstancesList.push_back(s_con);
}
};
Algorithm:
QList<VPN_Server> data_mananger::parseVPNConnections(QList<VPNConnection> l){
//Init var
QList<VPN_Server> server_list = QList<VPN_Server>();
VPNConnection v_con;
bool bAdded = false;
server_connection s_con;
//processing all vpn_connections, this is raw form sent, contains as fields, ip, cipher, protocol, port, compression
foreach (v_con, l) {
//create server_connection - data sorted by ip
s_con = server_connection(v_con.cipher, v_con.protocol, v_con.port, v_con.lzo_compression);
//pass through existing data, checking for a matching ip
foreach (VPN_Server ser, server_list) {
if (ser.VPN_IP == v_con.ip) {
//ip match found -> there already exists and ip with a server connection, adding another one with s_con
ser.addConnection(s_con);
bAdded = true;
//break current loop short searching for a matching ip
break;
}
}
//bAdded = false -> no matching IP has been found, thus creating a nw VPNServer
if (!bAdded) {
VPN_Server serv;
//creating new connection list and adding s_con to this list
QList<server_connection> list = QList<server_connection>();
list.push_back(s_con);
//adding VPNServer to list containing VPNServers
serv = VPN_Server(v_con.ip, list);
server_list.push_back(serv);
}
else
//data has been added, reseting add flag
bAdded = false;
}
return server_list;
}
Thanks to all who helped!
Please visit the link to the QT forums below and give a thumbs up to VRonin for his solution.
Also kudo's to #YuriyIvaskevych for helping me here on SO!
So to reiterate (budum tsss*) the doc page
Qt automatically takes a copy of the container when it enters a
foreach loop. If you modify the container as you are iterating, that
won't affect the loop. [...] using a non-const reference for the
variable does not allow you to modify the original container
Solution: created by #VRonin from forum.qt.io
for (auto serIter= server_list.begin(); serIter!=server_list.end(); ++serIter) {
if (serIter->VPN_IP == v_con.ip) {
//ip match found -> there already exists and ip with a server connection, adding another one with s_con
serIter->addConnection(s_con);
bAdded = true;
//break current loop short searching for a matching ip
break;
}
}
I have a C++ program that sends out various events, e.g. StatusEvent and DetectionEvent with different proto message definitions to a message service (currently Active MQ, via activemq-cpp APU). I want to write a message listener that receives these messages, parses them and writes them to cout, for debugging purposes. The listener has status_event_pb.h and detection_event_pb.h linked.
My question is: How can I parse the received event without knowing its type? I want to do something like (in pseudo code)
receive event
type = parseEventType(event);
if( type == events::StatusEventType) {
events::StatusEvent se = parseEvent(event);
// do stuff with se
}
else {
// handle the case when the event is a DetectionEvent
}
I looked at this question but I'm not sure if extensions are the right way to go here. A short code snippet pointing the way will be much appreciated. Examples on protobuf are so rare!
Thanks!
It seems extensions are indeed the way to go but I've got one last point to clear up. Here's the proto definition that I have so far:
// A general event, can be thought as base Event class for other event types.
message Event {
required int64 task_id = 1;
required string module_name = 2; // module that sent the event
extensions 100 to 199; // for different event types
}
// Extend the base Event with additional types of events.
extend Event {
optional StatusEvent statusEvent = 100;
optional DetectionEvent detectionEvent = 101;
}
// Contains one bounding box detected in a video frame,
// representing a region of interest.
message DetectionEvent {
optional int64 frame = 2;
optional int64 time = 4;
optional string label = 6;
}
// Indicate status change of current module to other modules in same service.
// In addition, parameter information that is to be used to other modules can
// be passed, e.g. the video frame dimensions.
message StatusEvent {
enum EventType {
MODULE_START = 1;
MODULE_END = 2;
MODULE_FATAL = 3;
}
required EventType type = 1;
required string module_name = 2; // module that sent the event
// Optional key-value pairs for data to be passed on.
message Data {
required string key = 1;
required string value = 2;
}
repeated Data data = 3;
}
My problem now is (1) how to know which specific event that the Event message contains and (2) make sure that it contains only one such event (according to the definition, it can contain both a StatusEvent and a DetectionEvent).
I would not use Protocol Buffers for that, but that's perhaps a combination of little use and other habits.
Anyway, I think I would use an abstract class here, to ease general handling and to contain routing information. Class that would not be defined using protobuf, and would contain a protobuf message.
class Message
{
public:
Type const& GetType() const;
Origin const& GetOrigin() const;
Destination const& GetDestination() const;
// ... other informations
template <class T>
void GetContent(T& proto) const
{
proto.ParseFromIstream(&mContent); // perhaps a try/catch ?
}
private:
// ...
std::stringstream mContent;
};
With this structure, you have both general and specific handling at the tip of your fingers:
void receive(Message const& message)
{
LOG("receive - " << message.GetType() << " from " << message.GetOrigin()
<< " to " << message.GetDestination());
if (message.GetType() == "StatusEvent")
{
StatusEvent statusEvent;
message.Decode(statusEvent);
// do something
}
else if (message.GetType() == "DetectionEvent")
{
DetectionEvent detectionEvent;
message.Decode(detectionEvent);
// do something
}
else
{
LOG("receive - Unhandled type");
}
}
Of course, it would be prettier if you used a std::unordered_map<Type,Handler> instead of a hardcoded if / else if + / else chain, but the principle remains identical:
Encode the type of message sent in the header
Decode only the header upon reception and dispatch based on this type
Decode the protobuf message in a part of the code where the type is known statically
I have written an ASP.NET web service.
It looks like this:
WebServices.logic pLogic = new WebServices.logic();
WebServices.manager[] pManager = new PowerManager[1];
pManager[0] = new PowerManager();
pManager[0].CustomerId = "sjsjshd";
pManager[0].state = pLogic.getState("sasj");
return pManager[0];
The pManager class looks like this:
public string _CustomerId;
public int PowerStatus;
public List<ArrayList> _Power;
public string CustomerId
{
get
{
return _CustomerId;
}
set
{
_CustomerId = value;
}
}
public List<ArrayList> Power
{
get
{
return _Power;
}
set
{
_Power = value;
}
}
When I run it, I get a repetition of the results, like so:
<p>
<_CustomerId>sjsjshd</_CustomerId>
<pStatus>0</PowerStatus>
−
<_p>
−
<ArrayOfAnyType>
<anyType xsi:type="xsd:int">1</anyType>
</ArrayOfAnyType>
<ArrayOfAnyType/>
</_p>
<CustomerId>sjsjshd</CustomerId>
−
<p>
−
<ArrayOfAnyType>
<anyType xsi:type="xsd:int">1</anyType>
</ArrayOfAnyType>
<ArrayOfAnyType/>
</p>
</pManager>
However, there is no duplicate values stored (Eg. I store client name in a collection, but only once - count of 1). There are no duplicates stored when I call getState(). This method returns a collection and it contains one value, but the results in XML has a repetition of this.
How comes the results appear to repeat themselves? When running the system, I only get one error.
Thanks
OK, looks like your XML serialization is giving you all the public members of your PowerManager class. Based on the naming convention of starting with an underscore, those members should be private, like this:
private string _CustomerId;
private List<ArrayList> _Power;
You also state "When running the system, I only get one error." What error are you getting?