如何在Veins/Omnet++中实现车辆与RSU的简单通信?
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
- Make sure your message file is compiled (you should see
MyMessage_m.handMyMessage_m.ccgenerated). - Build your project (Project > Build Project).
- 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

