Untitled

Ahmad avatar
Ahmad
plain_text
01/21/2026 11:25 AM
4.5 KB
18
Indexable
#include "veins/base/utils/FindModule.h"
#include "veins/modules/mac/ieee80211p/Mac1609_4.h"

#include "SimplePlatooningBeaconing.h"

namespace plexe {

Define_Module(SimplePlatooningBeaconing)

void SimplePlatooningBeaconing::initialize(int stage)
{
    BaseProtocol::initialize(stage);

    if (stage == 0) {

        checkShift = 0;
        checkShift = new cMessage("checkShift");
        beaconingIntervalOut.setName("BI");
        cbrOut.setName("CBR");

        // shift-time vector
        shiftTimeOut.setName("shift_time");
        chanStateOut.setName("chan_state");   // step plot
        shiftDirOut.setName("shift_dir");     // optional
        sendTimeOut.setName("send_time");
        lastWasCCH_valid = false;

        numCars = par("numberOfCars").intValue();



        if (beaconingInterval > 0) {
            SimTime beginTime = SimTime(uniform(0.001, beaconingInterval));
            scheduleAt(simTime() + beaconingInterval + beginTime, sendBeacon);
        }
        scheduleAt(simTime() + 0.001, checkShift);

    }
}

simtime_t SimplePlatooningBeaconing::persistentOffset()
{
    int carIndex = getParentModule()->getIndex();
    int half = numCars / 2;

    return (carIndex < half) ? 0 : 0.05;
}






void SimplePlatooningBeaconing::handleSelfMsg(cMessage* msg)
{
    BaseProtocol::handleSelfMsg(msg);

    if (msg == checkShift){


            auto* mac = veins::FindModule<veins::Mac1609_4*>::findSubModule(getParentModule());
            // current channel (Veins built-in)
            bool nowCCH = mac->isCurrentChannelCCH();

            // OPTION A: record channel state as 1=CCH, 0=SCH (gives step plot)
            chanStateOut.record(nowCCH ? 1 : 0);


            // OPTIONAL: record shift event time + direction (only when change happens)
            if (lastWasCCH_valid && nowCCH != lastWasCCH) {
                shiftTimeOut.record(simTime().dbl());          // still ok if you want it
                //shiftDirOut.record(lastWasCCH ? 0 : 1);      // 0=CCH->SCH, 1=SCH->CCH
            }

            lastWasCCH = nowCCH;
            lastWasCCH_valid = true;

            scheduleAt(simTime() + shiftCheckInterval, checkShift);

    }

    if(msg == sendBeacon){
        // count messages per channel (your original goal)
        auto* mac = veins::FindModule<veins::Mac1609_4*>::findSubModule(getParentModule());
        // current channel (Veins built-in)
        bool nowCCH = mac->isCurrentChannelCCH();

        if (nowCCH) CCH_counter++;
           else        SCH_counter++;

        sendPlatooningMessage(-1);
        sendTimeOut.record(simTime().dbl());


        cancelEvent(sendBeacon);
        //scheduleAt(simTime() + beaconingInterval, sendBeacon);
        simtime_t cycle = 0.1; // 100 ms (CCH+SCH)
        simtime_t base  = persistentOffset();

        simtime_t next =
            floor((simTime() + beaconingInterval) / cycle) * cycle
            + base;

        scheduleAt(next, sendBeacon);



        beaconingIntervalOut.record(beaconingInterval);
    }

}



void SimplePlatooningBeaconing::finish()
{
    BaseProtocol::finish();
    recordScalar("CCH_counter", CCH_counter);
    recordScalar("SCH_counter", SCH_counter);
}

SimplePlatooningBeaconing::SimplePlatooningBeaconing() {}
SimplePlatooningBeaconing::~SimplePlatooningBeaconing() {
    if (checkShift) {
            cancelAndDelete(checkShift);
            checkShift = nullptr;
}
}
} // namespace plexe
Editor is loading...
Leave a Comment