I use veins-4a2. First, I have executed a scnario with only vehicles. Now I have added RSU in my example. I need that every RSU receives data, displays a message in the module log of Omnet++. Like I did for nodes when they receives data, I have add the bold line in onData() function of the TraCIDemp11p like this:
void TraCIDemoRSU11p::onData(WaveShortMessage* wsm) {
findHost()->getDisplayString().updateWith("r=16,green");
annotations->scheduleErase(1, annotations->drawLine(wsm->getSenderPos(), mobi->getCurrentPosition(), "blue"));
**EV << " I am an RSU and I have received a data ! \n";**
//if (!sentMessage) sendMessage(wsm->getWsmData());
}
My problem is that "I am an RSU and I have received a data ! " isn't displayed in the log module.
When an RSU receives a data, this is what is displayed in the log module of omnet++:
** Event #4802 t=9.004337832007 RSUExampleScenario.node[4].nic.phy80211p (PhyLayer80211p, id=161), on `data' (Mac80211Pkt, id=669)
node[4]::PhyLayer80211p: AirFrame encapsulated, length: 1326
Make sure that is going in the onData function.
You can use ASSERT or exit function for that.
Print the message with DBG, EV or cout
DBG << "Test_DBG: I am an RSU and I have received a data!\n";
EV << "Test_EV: I am an RSU and I have received a data!\n";
std::cout << "Test_cout: I am an RSU and I have received a data!\n"
After set on print message, use one code to terminate the simulation
// terminate the simulation with error code 3
exit(3);
or use ASSERT
ASSERT2(0,"Test: I'm RSU");
If the simulation terminate with error, you will have sure that the onData is executed, if not, the onData is not called in any part of your code.
-Sorry, I don't have reputation to add just one comment- Good luck!
I don't know if you are aware of how onData works.
In the default veins, the onData is only called where one package with name data arrived in one car/node or RSU (through the handleLowerMsg).
In your case in a RSU, so are needed:
The cars/nodes need the appl.sendData with true
Calls for send packages with name data
Range of communication with the cars/nodes and the RSU. The default is 1 km of diameter.
A good test is create a small grid with the randomTrips.py and set the RSU in center, where all nodes can achieve it.
-Big for one comment, so I make a new answer - Good luck!
Related
I have to send the same message to multiple modules. I used the following code:
cMessage *msg=new cMessage("Broadcast");
msg->setKind(SENDTOALL);
cTopology topo;
topo.extractByModulePath(cStringTokenizer("**.router*.app[0]").asVector());
cTopology::Node *thisNode = topo.getNodeFor(this);
for (int i = 0; i < topo.getNumNodes(); i++) {
if (topo.getNode(i) == thisNode) continue; // skip ourselves
cModule *targetModule =topo.getNode(i)->getModule();
EV_INFO << "Get Full Name ------------------- "<<i<< topo.getNode(i)->getModule()->getFullPath()<<endl;
sendDirect(msg,targetModule,"in");
after sending the message to the first module and trying to send to the next module, I get the following error that the message already scheduled and the simulation stops at this point.
Can I get any advice? I will be really thankful.
Thank you in advance.
The message cannot be sent more than once. To send the same message to many modules, every time copy of this message must be created. dup() is the convenient method to make a copy, for example:
cMessage *copyMsg = msg->dup();
sendDirect(copyMsg ,targetModule,"in");
Reference: Simulation Manual - Broadcasting messages
I'm trying to learn veins, this is the initialization in the RSU application class :
void rsuApp::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if(stage == 0){
event = new cMessage("event");
EV << "Scheduling first send to t=5.0s\n";
scheduleAt(200.0, event);
}
}
I scheduled a self-message at second 200
this is the handleSelfMsg() function code:
void rsuApp::handleSelfMsg(cMessage* msg) {
BaseWaveApplLayer::handleSelfMsg(msg);
findHost()->getDisplayString().updateWith("r=360,pink");
}
during simulation before the rsu receives the selfMsg (before second 200 ) nothing happened but when the RSU receives the self message at second 200 it starts to sends BSM to other nodes even though i didn't implement any BSM sending
I don't know if BSM and beacons are the same things but I set the sendBeacons parameter in omnetpp.ini to false but the RSU still send BSM messages after receiving the self message
*.rsu[*].appl.sendBeacons = false
so I want to know why the RSU start sending BSM to other nodes after receiving the self message
is there a relation between scheduled events and BSM?
In your method handleSelfMsg you call BaseWaveApplLayer::handleSelfMsg(msg). This method is populating and transmitting a Basic Safety Message (BSM) as a broadcast to all other nodes in the scenario.
sendBeacons just controls whether this is being done regularly in order to send periodic beacons. If enabled, the same method as above is called and a BSM is transmitted (see here).
I am doing development for WSN in Omnet. I want to sniff a unicast message but I don't have an idea how can i do it in Omnet. I made some research but i couldn't found any method for that
When I send data to another node, I am sending it as an unicast with this method :
cModule *nodeIndex = flatTopolojiModulu->getSubmodule("n", i);//n is array
sendDirect(new cMessage("msg"), nodeIndex, "in");
I am using sendDirect method because I am working on wireless network. According to this description : https://stackoverflow.com/a/36082721/5736731
sendDirect method is usually the case in wireless networks.
But when send message with sendDirect, a message is being handled by receiver node. For example, according to code example above:
if i=2, message that is sent only can handle by node which has index "2" from
void AnyClassName::handleMessage(cMessage *msg) function
An example of broadcasting messages can be found in OMNeT++ Manual.
You should create only one instance of message that all nodes have to receive, and then send a new copy of this message to each node in loop. The dup() method has to be used to create the copy of a message.
cMessage * msg = new cMessage("msg");
// totalN is the total number of nodes
for (int i = 0; i < totalN; ++i) {
cModule *nodeIndex = flatTopolojiModulu->getSubmodule("n", i);
sendDirect(msg->dup(), nodeIndex, "in");
}
// original message is no longer needed
delete msg;
I am using omnet++-5.4.1, veins-4.7.1 and sumo-0.25.0 to simulate vehicle frame transmission.
About the behavior of the EDCA in the mac layer in WAVE, in my understanding the waiting time to send can be obtained by the following calculation.
waiting time = AIFS[AC] + backoff
AIFS[AC] = SIFS + AIFSN[AC] * slotlength
However, in the startContent function of Mac 1609_4.cc, it is written as follows
if (idleTime > possibleNextEvent) {
DBG_MAC << "Could have already send if we had it earlier" << std::endl;
//we could have already sent. round up to next boundary
simtime_t base = idleSince + DIFS;
possibleNextEvent = simTime() - simtime_t().setRaw((simTime() - base).raw() % SLOTLENGTH_11P.raw()) + SLOTLENGTH_11P;
}
Even during simulation, transmission is performed without waiting for the time calculated just after the transmission request has occurred.
As described above, it is considered that the operation of the original EDCA (CSMA / CA) has not been performed and the busyness of the channel is not sensed.
I do not understand enough about this Mac layer? Please let me know if I missed some information.
Thank you.
I have developed a scenario where at first the vehicles send a self messsage and upon reception of the self message vehicles send a message to RSU.
The self message code is written in the initialize() method. But during simulation the vehicles send the message to RSU every second.
I want the message to be sent only once. What should I do?
I have attached the handleSelfmessage method of my TraCIDemo11p.cc class.
if(msg->isSelfMessage()==true)
{
cModule *tmpMobility = getParentModule()->getSubmodule("veinsmobility");
mobility = dynamic_cast<Veins::TraCIMobility*>(tmpMobility);
ASSERT(mobility);
t_channel channel = dataOnSch ? type_SCH : type_CCH;
WaveShortMessage* wsm = prepareWSM("data", dataLengthBits, channel, dataPriority, -1,2);
wsm->setSenderAddress(myAddress);
wsm->setRecipientAddress(1001);
sendMessage(wsm->getWsmData());
}
Your approach seems right, but obviously you have some problem in your implementation.
Alternatively you can create a new message and send it to yourself
myOneTimeMsg = new cMessage("OneTimeMsg");
scheduleAt(simTime()+1.0, myOneTimeMsg); // this will send the message at t=currentTime+1.0 seconds
Then you can handle that message as follows:
if(msg->isSelfMessage()==true){
if (msg == myOneTimeMsg) {
// do what you need next...
Amending the answer of #user4786271:
The handleSelfMsg method of TraCIDemo11p.cc obviously is executed for every self-message which this module receives - possibly also non WSMs. So if you just added the given code there, it will send a WSM for every of those self-messages. Thus, only checking for self-message type is not enough. You need to create a new message type and check for that type as shown by #user4786271.