c++omnet++veins

Veins handleLower is not called when another node sends WSM


I am currently working on school project regarding to V2X simulations (currently using omnet++ v. 6.0.1 and veins v. 5.2). So far I created simple example with 1 RSU and 3 vehicles. The goal so far is to implement sending particular messages. Therefore I created 1 application for vehicles, which periodically checks for particular conditions and when the conditions are met the message is broadcasted to all other nodes (vehicles and RSU). The sending is working, but receiving is kinda lacking. If I understand correctly, when a message is broadcasted with sendDown(wms) method, all other nodes receiving this message should call onWSM() method. However, this is not happening for some whatever reason. It is only called, when the vehicle is spawned.

Below is the code I am using. Vehicle application:

#include "hradeck17/application/CamTestApp.h"
#include "hradeck17/messages/CAM_m.h"

using namespace veins;
using namespace hradeck17;

Define_Module(hradeck17::CamTestApp);

void CamTestApp::initialize(int stage)
{
    EV << "Initializing CamTestApp " << std::endl;
    DemoBaseApplLayer::initialize(stage);
    if (stage == 0) {
        sentMessage = false;
        lastDroveAt = simTime();
        currentSubscribedServiceId = -1;
        lastCamGeneratedAt = simTime().dbl() * 1000;
        T_GenCamMin = 100;
        T_GenCamMax = 1000;
        T_CheckCamGen = T_GenCamMin;
        T_GenCam_Dcc = T_GenCamMin;
        T_GenCam = 1000;
        N_GenCam = 3;
        lastHeading = traciVehicle->getAngle();
        lastPosition =  mobility->getPositionAt(simTime());
        lastSpeed = traciVehicle->getSpeed();
        conseqCamGenerations = 0;

        /* Schedule a self-message for checking the CAM generation condition */
        scheduleAt(simTime(), new cMessage("checkCAMCondition"));
    }
}

void CamTestApp::onWSA(DemoServiceAdvertisment* wsa)
{

}

void CamTestApp::onWSM(BaseFrame1609_4* frame)
{
    CAM* wsm = check_and_cast<CAM*>(frame);
    findHost()->getDisplayString().setTagArg("i",1,"green");
    EV << "CAM RECEIVED BY CAR" << std::endl;
}

void CamTestApp::handleSelfMsg(cMessage* msg)
{
    if(strcmp(msg->getName(), "checkCAMCondition") == 0){
        double currentTime  = simTime().dbl()*1000;

        /* Check the current state of the vehicle */
        currentHeading = traciVehicle->getAngle();
        currentPosition = mobility->getPositionAt(simTime());
        currentSpeed = traciVehicle->getSpeed();
//        EV << traci->getLonLat(currentPosition).first << std::endl;
//        EV << traci->getLonLat(currentPosition).second << std::endl;


        /* Elapsed T_GenCam_Dcc ms from last CAM generation (condition 1) */
        if(currentTime - lastCamGeneratedAt >= T_GenCam_Dcc){
            /* Heading changed by more than 4 degrees */
            /* Speed changed by more than 0.5 m/s */
            /* Position changed by more than 4 m */
            if(fabs((currentHeading - lastHeading)) * 180 / M_PI > 4 || fabs(currentSpeed - lastSpeed) > 0.5 || currentPosition.distance(lastPosition) > 4){
                findHost()->getDisplayString().setTagArg("i", 1, "red");
                CAM* wsm = new CAM();
                populateWSM(wsm);
                wsm->setSenderAddress(myId);
                wsm->setPosition(currentPosition);
                wsm->setHeading(currentHeading);
                wsm->setSpeed(currentSpeed);
                T_GenCam = currentTime - lastCamGeneratedAt;
                sendDown(wsm);
                lastCamGeneratedAt = currentTime;
            }
        }
        /* Condition 2 */
        else if(currentTime - lastCamGeneratedAt >= T_GenCam && currentTime - lastCamGeneratedAt >= T_GenCam_Dcc){
            /* Trigger CAM generation */
            CAM* wsm = new CAM();
            populateWSM(wsm);
            wsm->setSenderAddress(myId);
            wsm->setPosition(currentPosition);
            wsm->setHeading(currentHeading);
            wsm->setSpeed(currentSpeed);
            T_GenCam = T_GenCamMax;
            sendDown(wsm);
            lastCamGeneratedAt = currentTime;
        }

        /* Update state of the vehicle */
        lastHeading = currentHeading;
        lastPosition = currentPosition;
        lastSpeed = currentSpeed;

        /* Schedule next CAM check message */
        scheduleAt(simTime() + ((double)T_CheckCamGen/1000), new cMessage("checkCAMCondition"));
    }
    else {
        DemoBaseApplLayer::handleSelfMsg(msg);
    }
}

void CamTestApp::handlePositionUpdate(cObject* obj)
{
    DemoBaseApplLayer::handlePositionUpdate(obj);
}

The message:

import veins.base.utils.Coord;
import veins.modules.messages.BaseFrame1609_4;
import veins.base.utils.SimpleAddress;

namespace hradeck17;

//Cooperative awareness message (CAM)
//CAM is always broadcasted, max frequency is 10 Hz
packet CAM extends veins::BaseFrame1609_4 {
    string demoData;
    int ID;
    veins::LAddress::L2Type senderAddress = -1;
    int serial = 0; 
    veins::Coord position;
    double heading;
    double speed;
}

In particular I am not seeing the "CAM RECEIVED BY CAR". I would be grateful for additional help.

I found out, that DemoBaseApplLayer::handleLowerMsg(cMessage* msg) method is not called.


Solution

  • The main reason, why onWSM() method was not called, is because the implementation above exploits sending and receiving message at the same time. Since CSMA/CA is 'not implemented', substituting sendDown(wsm) with sendDelayedDown(wsm, delay) do the job perfectly (adding slight delay).