Message reception error in aggregator module in omnet++ - omnet++

Hey guys I have this code (Aggregator.cc) that is supposed to receive the messages sent from Temperature.cc and Heartrate.cc and concatenate them together however it is not doing so please help. In aggregator.cc it keeps telling me that tmsg and hmasg are not defined in the scope. Isn't aggregator supposed to have received the messages.
Temperature.cc
#include "Temperature.h"
Define_Module(Temperature);
void Temperature::initialize()
{
// TODO - Generated method body
cMessage *tmsg = new cMessage("hi");
send(tmsg,"temperatured");
}
void Temperature::handleMessage(cMessage *msg)
{
// TODO - Generated method body
}
Heartrate.cc
#include "Heartrate.h"
Define_Module(Heartrate);
void Heartrate::initialize()
{
// TODO - Generated method body
cMessage *hmsg = new cMessage("hello");
send(hmsg,"heartrateexit");
}
void Heartrate::handleMessage(cMessage *msg)
{
// TODO - Generated method body
}
Aggregator.cc
#include "Aggregator.h"
#include "Temperature.h"
#include "Heartrate.h"
Define_Module(Aggregator);
void Aggregator::initialize()
{
// TODO - Generated method body
}
void Aggregator::handleMessage(cMessage *msg)
{
// TODO - Generated method body
cPacket *data = new cPacket("data");
data ->addPar(tmsg); // added parameter of type cMessage
data ->addPar(hmsg); // added parameter of type cMessage
data->setByteLength(20);
cPacket *udp = new cPacket("data1"); // subclassed from cPacket
udp->setByteLength(30);
udp->encapsulate(data);
EV << udp->getByteLength();
EV << udp;
cPacket *payload = udp->decapsulate();
EV << payload;
}
network.ned
network Network
{
submodules:
aggregator: Aggregator {
#display("p=128,147");
}
heartrate: Heartrate {
#display("p=40,112");
}
temperature: Temperature {
#display("p=40,173");
}
connections:
temperature.tempexit --> aggregator.data;
heartrate.heartrateexit --> aggregator.data1;
}

You're trying to access local variables from another method. tmsg and hmsg are defined in the local scope of Temperature::initialize and Heartrate::initialize, respectively.
You'll need to add something to the payload of these messages, so that when you receive one at Aggregator::handleMessage(cMessage *msg), you know whether the msg argument is from Temperature or from Heartrate.
Also, in Temperature::initialize, the name of your gate doesn't match the one in your .ned file.

Related

How to make one node communicate with multiple nodes?

I am trying to make my nodes communicate among themselves without changing any data in the message.
Like node one and two echos tictocMsg with themselves node two and three echos the different message in this case rndMsg.
How ever this did not work with me.
simple Txc1
{
gates:
input in1;
input in2;
output out1;
output out2;
}
//
// Two instances (tic and toc) of Txc1 connected both ways.
// Tic and toc will pass messages to one another.
//
network Tictoc1
{
#display("bgb=628,433");
submodules:
tic: Txc1 {
#display("p=264,321");
}
toc: Txc1;
rnd: Txc1 {
#display("p=474,100");
}
connections allowunconnected:
toc.out1 --> tic.in1;
tic.out1 --> toc.in1;
toc.out2 --> rnd.in1;
rnd.out1 --> toc.in2;
}
I want to make toc node to send tictocMsg to tic node only and rndMsg to rnd node only
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* Derive the Txc1 class from cSimpleModule. In the Tictoc1 network,
* both the `tic' and `toc' modules are Txc1 objects, created by OMNeT++
* at the beginning of the simulation.
*/
class Txc1 : public cSimpleModule
{
protected:
// The following redefined virtual function holds the algorithm.
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
// The module class needs to be registered with OMNeT++
Define_Module(Txc1);
void Txc1::initialize()
{
// Initialize is called at the beginning of the simulation.
// To bootstrap the tic-toc-tic-toc process, one of the modules needs
// to send the first message. Let this be `tic'.
// Am I Tic or Toc?
if (strcmp("tic", getName()) == 0) {
// create and send first message on gate "out". "tictocMsg" is an
// arbitrary string which will be the name of the message object.
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out1");
}
if (strcmp("rnd",getName())==0){
cMessage *msg = new cMessage("rndMsg");
send(msg, "out1");
}
}
void Txc1::handleMessage(cMessage *msg)
{
// The handleMessage() method is called whenever a message arrives
// at the module. Here, we just send it to the other module, through
// gate `out'. Because both `tic' and `toc' does the same, the message
send(msg,"out1");
// send out the message
}
I have tried to change it to
send(msg,"in1","out1") ;
send(msg,"in2","out2") ;
tried
send(msg,out1)}
else{
send(msg,out2)}
}
by far both did not work for me is there any way to make it happen?
The node in the middle (i.e. toc) has to somehow recognize received messages. For example it may check the name of the message. Let's assume that:
toc after receiving message with the name tictocMsg sends it to tic,
toc after receiving message with the name rndMsg sends it to rnd,
tic and rnd after receiving message send it to toc.
The following piece of code performs the above rules:
void Txc1::handleMessage(cMessage *msg) {
if (isName("toc")) {
if (msg->isName("tictocMsg")) {
send(msg,"out1");
} else if (msg->isName("rndMsg")) {
send(msg,"out2");
}
} else {
// other nodes just sends this message back
send(msg,"out1");
}
}

Instant Veins 4.7-i1 Localization Time of Arrival

I am a masters student working on localization, using ranging (time of arrival between vehicle and RSU) and relative location (Using emulated Inertial Navigation System).
I have done an implementation of my kalman filter based localization logic on Matlab, now I would like to implement this on veins. I want only the RSU to send out a message comprising of its location and ID
1) I know that i can use
double Coord = mobility->getCurrentPosition().x;
double Coord = mobility->getCurrentPosition().y;
to the location of RSU(and my vehicle as well), I do not understand how I should assign these coordinates to the message. I cannot use sstream since I understand that the message are supposed to be of type const char *
Thanks for any input
Edit 1: So this is what my new code on RSU looks like:
#include "RsuScOne.h"
#include <sstream>
Define_Module(RsuScOne);
void RsuScOne::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
//Initializing members and pointers of your application goes here
//WaveShortMessage* wsm = new WaveShortMessage();
EV << "Initializing " << std::endl;
}
else if (stage == 1) {
//Initializing members that require initialized other modules goes here
}
}
void RsuScOne::finish() {
BaseWaveApplLayer::finish();
//statistics recording goes here
cancelEvent(sendWSAEvt);
}
void RsuScOne::onWSM(WaveShortMessage* wsm) {
//Your application has received a data message from another car or RSU
//code for handling the message goes here, see TraciDemo11p.cc for examples
populateWSM(wsm);
std::stringstream ss;
ss<<mobility->getCurrentPosition().x<<mobility->getCurrentPosition().y;
wsm->setWsmData(ss.str().c_str());
scheduleAt(simTime()+par("beaconInterval").doubleValue(), sendWSAEvt);
EV<<wsm;
}
void RsuScOne::handleSelfMsg(cMessage* msg) {
BaseWaveApplLayer::handleSelfMsg(msg);
}
But I realize that all that being done now is my RSU constantly sending a generic BSM, Why is this so?

ZeroMQ XSUB/XPUB proxy() API is not returning

I have written a demo Windows service using POCO library.
As per POCO API the function waitForTerminationRequest() waits for a service termination request.
Now, in this POCO based windows service, I want to start a ZeroMQ library based Message Queue proxy to implement an XSUB/XPUB message queue.
More can be learnt here http://zguide.zeromq.org/page:all.
For this I wrote another class ZeroMQProxy, which starts the proxy in the service's main function.
class ZeroMQProxy
{
private:
zmq::context_t context;
zmq::socket_t xsub;
zmq::socket_t xpub;
public:
ZeroMQProxy()
: context(1),
xsub(context, ZMQ_XSUB), // Publisher End Proxy Sockets
xpub(context, ZMQ_XPUB) // Subscriber End Proxy Sockets
{
}
~ZeroMQProxy()
{
}
void proxyopen()
{
xsub.bind("tcp://*:5559");
xpub.bind("tcp://*:5560");
zmq::proxy(xsub, xpub, nullptr);
}
void proxyclose()
{
}
};
class demopocoservice : public ServerApplication
{
private:
bool _helpRequested;
public:
demopocoservice() : _helpRequested(false)
{
}
~demopocoservice()
{
}
protected:
void initialize(Application& self)
{
loadConfiguration();
ServerApplication::initialize(self);
}
void uninitialize()
{
ServerApplication::uninitialize();
}
void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);
options.addOption(
Option("help", "h", "poco display help")
.required(false)
.repeatable(false)
.callback(OptionCallback<demopocoservice>(
this, &demopocoservice::handleHelp)));
}
void handleHelp(const std::string& name,
const std::string& value)
{
_helpRequested = true;
displayHelp();
stopOptionsProcessing();
}
void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("poco: Zero message Queue.");
helpFormatter.format(std::cout);
}
int main(const ArgVec& args)
{
if (!_helpRequested)
{
ZeroMQProxy zmqproxyObj;
zmqproxyObj.proxyopen();
waitForTerminationRequest();
zmqproxyObj.proxyclose();
}
return Application::EXIT_OK;
}
};
int main(int argc, char** argv)
{
cout << "Hello Poco ZMQ\n";
demopocoservice pobj;
pobj.run(argc, argv);
return 0;
}
My aim was when I start the service then the zmq::proxy() should have started the proxy and when I stop the service then proxy should be closed along with the sockets.
Problem is zmq::proxy() does not return back.
So I am not able to stop the service.
Even if I do net stop <service name> the waitForTerminationRequest() does not receive termination request because of zmq::proxy().
What should I do to stop/close the proxy when I stop the service?
ZeroMQ API confirms this:
Description
The zmq_proxy() function starts the built-in ØMQ proxy in the current application thread.
...
Before calling zmq_proxy() you must set any socket options, and connect or bind both frontend and backend sockets. The two conventional proxy models are:
zmq_proxy() runs in the current thread and returns only if/when the current context is closed.
Given this fact, best instantiate an independent thread for leaving the proxy operate there and let the caller return so as to continue your other code-execution flows remain independent from the independent zmq_proxy() execution.
Another fair move would be to ( always ) set LINGER == 0, before any further steps and/or measures are with a newly instantiated sockets taken.

Custom Event Handling in GStreamer 1.0

I am having a hard time wrapping my head around GStreamer event sending and handling. I understand the process, but can not achieve my desired outcome. I am developing a series of GStreamer plugins in tandem with a GStreamer main application. I have 3 plugins my_src which inherits from GstPushSrc, my_transform which inherits from GstBaseTransform and my_sink which inherits from GstBaseSink, and a main application my_app.
I am trying to send a custom event from my_app to all elements in the pipeline telling them to reconfigure the processing parameters. This is different from GST_EVENT_RECONFIGURE because it does not involve any renegotiation of caps. I am sending the event from my_app with the following:
// my_app.c
GstStructure *reconfigureStructure = gst_structure_new("reconfigure", NULL);
GstEvent *reconfigureEvent = gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM,
reconfigureStructure);
gst_element_send_event(pipeline, reconfigureEvent);
I have overridden the GstBaseSrc event() method as follows:
// my_src.c
static gboolean my_src_event(GstBaseSrc *bs, GstEvent *event);
static void
my_src_class_init(MySrcClass *msc)
{
GstBaseSrcClass *bsc = GST_BASE_SRC_CLASS(msc);
bsc->event = my_src_event;
}
static gboolean
my_src_event(GstBaseSrc *bs, GstEvent *event)
{
switch (GST_EVENT_TYPE(event)) {
case GST_EVENT_CUSTOM_DOWNSTREAM: {
const GstStructure *structure = gst_event_get_structure(event);
if (gst_structure_has_name(structure, "reconfigure")) {
g_print("MY SRC RECONFIGURE\n");
// do reconfigure things
}
break;
}
}
return GST_BASE_SRC_CLASS(parent_class)->event(bs, event);
}
Similarly, I have overridden the GstBaseSink event handler as follows:
// my_sink.c
static gboolean my_sink_event(GstBaseSink *bs, GstEvent *event);
static void
my_sink_class_init(MySinkClass *msc)
{
GstBaseSinkClass *bsc = GST_BASE_SINK_CLASS(msc);
bsc->event = my_sink_event;
}
static gboolean
my_sink_event(GstBaseSink *bs, GstEvent *event)
{
switch (GST_EVENT_TYPE(event)) {
case GST_EVENT_CUSTOM_DOWNSTREAM: {
const GstStructure *structure = gst_event_get_structure(event);
if (gst_structure_has_name(structure, "reconfigure")) {
g_print("MY SINK RECONFIGURE\n");
// do reconfigure things
}
break;
}
}
return GST_BASE_SINK_CLASS(parent_class)->event(bs, event);
}
Lastly, I have overridden the GstBaseTransform sink_event() method as follows:
// my_transform.c
static gboolean my_transform_sink_event(GstBaseTransform *bt, GstEvent *event);
static void
my_transform_class_init(MyTransformClass *mtc)
{
GstBaseTransformClass *btc = GST_BASE_TRANDFORM_CLASS(mtc);
btc->sink_event = my_transform_sink_event;
}
static gboolean
my_transform_sink_event(GstBaseTransfor *bt, GstEvent *event)
{
switch (GST_EVENT_TYPE(event)) {
case GST_EVENT_CUSTOM_DOWNSTREAM: {
const GstStructure *structure = gst_event_get_structure(event);
if (gst_structure_has_name(structure, "reconfigure")) {
g_print("MY TRANSFORM RECONFIGURE\n");
// do reconfigure things
}
break;
}
}
return GST_BASE_TRANSFORM_CLASS(parent_class)->sink_event(bt, event);
}
When I run my_app I would expect the output to be:
MY SRC RECONFIGURE
MY TRANSFORM RECONFIGURE
MY SINK RECONFIGURE
However, I am only getting:
MY SINK RECONFIGURE
Any ideas what I am doing wrong here?

Proper way of raising events from C++/CLI?

I was wondering what's the proper way of raising events from C++/CLI. In C# one should first make a copy of the handler, check if it's not null, and then call it. Is there a similar practice for C++/CLI?
This isn't the whole story! You don't usually have to worry about null event handlers in C++/CLI. The code for these checks is generated for you. Consider the following trivial C++/CLI class.
public ref class MyClass
{
public:
event System::EventHandler ^ MyEvent;
};
If you compile this class, and disassemble it using Reflector, you get the following c# code.
public class MyClass
{
// Fields
private EventHandler <backing_store>MyEvent;
// Events
public event EventHandler MyEvent
{
[MethodImpl(MethodImplOptions.Synchronized)] add
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value);
}
[MethodImpl(MethodImplOptions.Synchronized)] remove
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value);
}
raise
{
EventHandler <tmp> = null;
<tmp> = this.<backing_store>MyEvent;
if (<tmp> != null)
{
<tmp>(value0, value1);
}
}
}
}
The usual checks are being done in the raise method. Unless you really want custom behavior, you should feel comfortable declaring your event as in the above class, and raising it without fear of a null handler.
C++/CLI allows you to override raise in custom event handlers so you don't have to test for null or copy when raising the event. Of course, inside your custom raise you still have to do this.
Example, adapted from the MSDN for correctness:
public delegate void f(int);
public ref struct E {
f ^ _E;
public:
void handler(int i) {
System::Console::WriteLine(i);
}
E() {
_E = nullptr;
}
event f^ Event {
void add(f ^ d) {
_E += d;
}
void remove(f ^ d) {
_E -= d;
}
void raise(int i) {
f^ tmp = _E;
if (tmp) {
tmp->Invoke(i);
}
}
}
static void Go() {
E^ pE = gcnew E;
pE->Event += gcnew f(pE, &E::handler);
pE->Event(17);
}
};
int main() {
E::Go();
}
If your issue is that raise isn't private, then explicitly implement it like the docs say:
http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx
In summary:
If you just use the event keyword, you create a "trivial" event. The compiler generates add/remove/raise and the delegate member for you. The generated raise function (as the docs say) checks for nullptr. Trivial events are documented here:
http://msdn.microsoft.com/en-us/library/4b612y2s.aspx
If you want "more control", for example to make raise private, then you have to explicitly implement the members as shown in the link. You must explicitly declare a data member for the delegate type. Then you use the event keyword to declare the event-related members, as in the Microsoft example:
// event keyword introduces the scope wherein I'm defining the required methods
// "f" is my delegate type
// "Event" is the unrealistic name of the event itself
event f^ Event
{
// add is public (because the event block is public)
// "_E" is the private delegate data member of type "f"
void add(f ^ d) { _E += d; }
// making remove private
private:
void remove(f ^ d) { _E -= d; }
// making raise protected
protected:
void raise(int i)
{
// check for nullptr
if (_E)
{
_E->Invoke(i);
}
}
}// end event block
Wordy, but there it is.
-reilly.

Resources