You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Veins/Omnet++中实现车辆与RSU的简单通信?

Simple Vehicle-to-Vehicle/Vehicle-to-RSU Messaging in Veins 4.7.1

Hey there! I totally get the confusion—Veins uses a layered approach that hides some of the direct send/receive calls behind its framework, which makes it tricky to spot at first. Let’s walk through building a minimal messaging setup that works for your setup (OMNeT++ 5.5.1, SUMO 0.32.0, Veins 4.7.1).

Key Background First

Veins doesn’t use generic sendMessage()/receiveMessage() functions. Instead, it relies on the BaseWaveApplLayer class (part of Veins’ IEEE 802.11p/WAVE implementation) to handle message framing, scheduling, and transmission. All custom apps should inherit this class to leverage its built-in WAVE logic.


Step 1: Create a Custom Message Type

First, define the structure of the message you want to send. Use OMNeT++’s Message Editor to create a .msg file (e.g., MyMessage.msg):

message MyMessage extends cPacket {
    int senderId;       // Unique ID of the sender (vehicle/RSU)
    string content;     // Your custom message content
}

Save this in your project’s messages folder, then compile it (right-click the file > Build Messages). This generates C++ classes for your message that you can use in your app.


Step 2: Build a Custom Application Layer

Create two files: SimpleMessageApp.h and SimpleMessageApp.cc—this will be your app that handles sending and receiving messages.

Header File (SimpleMessageApp.h)

#ifndef SIMPLEMESSAGEAPP_H_
#define SIMPLEMESSAGEAPP_H_

#include "veins/modules/application/ieee80211p/BaseWaveApplLayer.h"
#include "MyMessage_m.h"

class SimpleMessageApp : public BaseWaveApplLayer {
public:
    virtual void initialize(int stage);
    virtual void handleSelfMsg(cMessage* msg);
    virtual void onWSM(WaveShortMessage* wsm);

private:
    cMessage* sendTimer; // Timer to trigger periodic message sends
};

#endif /* SIMPLEMESSAGEAPP_H_ */

Source File (SimpleMessageApp.cc)

#include "SimpleMessageApp.h"
#include "veins/modules/mac/ieee80211p/Mac1609_4.h"

Define_Module(SimpleMessageApp);

void SimpleMessageApp::initialize(int stage) {
    BaseWaveApplLayer::initialize(stage);
    if (stage == 0) {
        // Set up a timer to send messages periodically
        sendTimer = new cMessage("sendTimer");
        scheduleAt(simTime() + 1.0, sendTimer); // Send first message after 1 second
    }
}

void SimpleMessageApp::handleSelfMsg(cMessage* msg) {
    if (msg == sendTimer) {
        // Create your custom message
        MyMessage* myMsg = new MyMessage("myCustomMessage");
        myMsg->setSenderId(getParentModule()->getId()); // Use module ID as sender ID
        myMsg->setContent("Hello from Vehicle/RSU!");

        // Wrap your message in a Veins WaveShortMessage (required for WAVE transmission)
        WaveShortMessage* wsm = prepareWSM(
            "dataMsg",               // Message name
            myMsg->getByteLength(),  // Message size
            0,                       // Priority
            SCHEDULE_MANUAL          // Transmission mode
        );
        wsm->setWsmData(myMsg->dup()); // Copy your custom message into the WSM

        // Send the message using Veins' built-in method
        sendWSM(wsm);
        EV << "Sent message: " << myMsg->getContent() << " (Sender ID: " << myMsg->getSenderId() << ")\n";

        // Clean up and reschedule the timer
        delete myMsg;
        scheduleAt(simTime() + 5.0, sendTimer); // Send next message in 5 seconds
    }
    else {
        // Pass other self-messages to the parent class
        BaseWaveApplLayer::handleSelfMsg(msg);
    }
}

void SimpleMessageApp::onWSM(WaveShortMessage* wsm) {
    // Extract your custom message from the received WSM
    MyMessage* receivedMsg = check_and_cast<MyMessage*>(wsm->getWsmData());
    EV << "Received message from ID " << receivedMsg->getSenderId() << ": " << receivedMsg->getContent() << "\n";

    // Clean up
    delete receivedMsg;
    delete wsm;
}

Step 3: Update Your NED Files

Replace the default application layer in your car.ned and rsu.ned with your new app. For example:

car.ned

simple CarNode extends BaseMobility {
    parameters:
        @display("i=car/truck");
    submodules:
        nic: IEEE80211p;
        app: SimpleMessageApp; // Replace the default app with yours
    connections:
        app.upperLayerOut --> nic.upperLayerIn;
        nic.upperLayerOut --> app.upperLayerIn;
}

rsu.ned

simple RsuNode extends BaseStationMobility {
    parameters:
        @display("i=block/routing");
    submodules:
        nic: IEEE80211p;
        app: SimpleMessageApp; // Use the same app for RSU
    connections:
        app.upperLayerOut --> nic.upperLayerIn;
        nic.upperLayerOut --> app.upperLayerIn;
}

Step 4: Compile and Run

  1. Make sure your message file is compiled (you should see MyMessage_m.h and MyMessage_m.cc generated).
  2. Build your project (Project > Build Project).
  3. Run your simulation—you’ll see messages being sent and received in the OMNeT++ console (check the EV output).

Why You Didn’t Find sendMessage() in the Examples

Veins examples like TraCIDemo11p use sendWSM() (from BaseWaveApplLayer) instead of a generic sendMessage(). The receive logic is handled in the onWSM() method, which is called automatically when a WaveShortMessage is received. That’s why you didn’t see the direct send/receive calls—they’re abstracted into the framework!

内容的提问来源于stack exchange,提问作者NinjaMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:02:58