I encounter some trouble when using VEINS. I want to simulate a comunication between RSU and Vehicle.
in the begining of simulation, RSU broadcasts a MsgInit message to all vehicles, after that, the vehicles also broadcasts a Metrics message to RSU.
But RSU cannot received the Metrics message, I dont know the reason, can someone help me? Here is my code (I'm using omnet 5.6.2, sumo 1.8.0 and veins 5.1)
// MyVeinsAppRSU.cc
void MyVeinsAppRSU::initialize(int stage)
{
...
// send message "sendMsgInit" at 70 second of simulation
scheduleAt(simTime()+70,sendMsgInit);
}
void MyVeinsAppRSU::handleSelfMsg(cMessage* msg)
{
MsgInit* msg_init = new MsgInit();
BaseFrame1609_4* WSM = new BaseFrame1609_4();
WSM->encapsulate(msg_init);
populateWSM(WSM);
// send out WSM from lowerLayer of Application of RSU
send(WSM,lowerLayerOut);
}
void MyVeinsAppRSU::handleLowerMsg(cMessage* msg)
{
BaseFrame1609_4* WSM = check_and_cast<BaseFrame1609_4*>(msg);
//Decapsulation packet from WSM
cPacket* pkt = WSM->getEncapsulatedPacket();
// translate packet to Metrics
Metrics* MT = dynamic_cast<Metrics*>(pkt);
EV << "send message Vehicle id: " << MT->getVehicleId() << "Receive successfully !!!!!!!!!!!" << endl;
}
// MyVeinsAppCar.cc
void MyVeinsAppCar::handleLowerMsg(cMessage* msg)
{
BaseFrame1609_4* WSM = check_and_cast<BaseFrame1609_4*>(msg);
cPacket* enc = WSM->getEncapsulatedPacket();
MsgInit* MI = dynamic_cast<MsgInit*>(enc);
// initialize as follower
findHost()->getDisplayString().setTagArg("i", 1, "black");
//after receive MsgInit, send Metrics out(next step: handleSelfMsg)
if (sendMetrics->isScheduled()) {
cancelEvent(sendMetrics);
}
scheduleAt(simTime() + 1,sendMetrics);
}
void MyVeinsAppCar::handleSelfMsg(cMessage* msg)
{
cModule* vehicle = getParentModule();
TraCIMobility* traci = dynamic_cast<TraCIMobility*>(vehicle->getSubmodule("veinsmobility", 0));
TraCICommandInterface::Vehicle* traciVehicle = traci->getVehicleCommandInterface();
if(msg == sendMetrics){
Metrics* msg_metrics = new Metrics();
msg_metrics->setVehicleId(this->getParentModule()->getIndex());
msg_metrics->setSpeed(traci->getSpeed());
BaseFrame1609_4* WSM = new BaseFrame1609_4();
WSM->encapsulate(msg_metrics);
populateWSM(WSM, -1);
send(WSM,lowerLayerOut);
EV << "send Metrics!!"<< endl;
}
}
Thank you in advance.
Related
on my code i can send an sms to my target number but i don't know how to read or receive sms from target number
the tinyGSM library doesn't have the read member function and i don't know how to use AT commands
void setup() {
// Set console baud rate
SerialMon.begin(115200);
// Keep power when running from battery
Wire.begin(I2C_SDA, I2C_SCL);
bool isOk = setPowerBoostKeepOn(1);
SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
// Set GSM module baud rate and UART pins
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
// Restart SIM800 module, it takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
// use modem.init() if you don't need the complete restart
// Unlock your SIM card with a PIN if needed
if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
modem.simUnlock(simPIN);
}
// To send an SMS, call modem.sendSMS(SMS_TARGET, smsMessage)
String smsMessage = "Hello from ESP32!";
/*if(modem.sendSMS(SMS_TARGET, smsMessage))
{
SerialMon.println(smsMessage);
}
else{
SerialMon.println("SMS failed to send");
}*/
SerialAT.println("AT"); //Once the handshake test is successful, it will back to OK
SerialAT.println("AT+CMGF=1"); // Configuring TEXT mode
SerialAT.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
}
void loop()
{
//readSMS(1);
//delay(1);
}
I am trying to make my nodes communicate among themselves without changing any data in the message.
Like node one and two echos tictocMsg with themselves node two and three echos the different message in this case rndMsg.
How ever this did not work with me.
simple Txc1
{
gates:
input in1;
input in2;
output out1;
output out2;
}
//
// Two instances (tic and toc) of Txc1 connected both ways.
// Tic and toc will pass messages to one another.
//
network Tictoc1
{
#display("bgb=628,433");
submodules:
tic: Txc1 {
#display("p=264,321");
}
toc: Txc1;
rnd: Txc1 {
#display("p=474,100");
}
connections allowunconnected:
toc.out1 --> tic.in1;
tic.out1 --> toc.in1;
toc.out2 --> rnd.in1;
rnd.out1 --> toc.in2;
}
I want to make toc node to send tictocMsg to tic node only and rndMsg to rnd node only
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* Derive the Txc1 class from cSimpleModule. In the Tictoc1 network,
* both the `tic' and `toc' modules are Txc1 objects, created by OMNeT++
* at the beginning of the simulation.
*/
class Txc1 : public cSimpleModule
{
protected:
// The following redefined virtual function holds the algorithm.
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
// The module class needs to be registered with OMNeT++
Define_Module(Txc1);
void Txc1::initialize()
{
// Initialize is called at the beginning of the simulation.
// To bootstrap the tic-toc-tic-toc process, one of the modules needs
// to send the first message. Let this be `tic'.
// Am I Tic or Toc?
if (strcmp("tic", getName()) == 0) {
// create and send first message on gate "out". "tictocMsg" is an
// arbitrary string which will be the name of the message object.
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out1");
}
if (strcmp("rnd",getName())==0){
cMessage *msg = new cMessage("rndMsg");
send(msg, "out1");
}
}
void Txc1::handleMessage(cMessage *msg)
{
// The handleMessage() method is called whenever a message arrives
// at the module. Here, we just send it to the other module, through
// gate `out'. Because both `tic' and `toc' does the same, the message
send(msg,"out1");
// send out the message
}
I have tried to change it to
send(msg,"in1","out1") ;
send(msg,"in2","out2") ;
tried
send(msg,out1)}
else{
send(msg,out2)}
}
by far both did not work for me is there any way to make it happen?
The node in the middle (i.e. toc) has to somehow recognize received messages. For example it may check the name of the message. Let's assume that:
toc after receiving message with the name tictocMsg sends it to tic,
toc after receiving message with the name rndMsg sends it to rnd,
tic and rnd after receiving message send it to toc.
The following piece of code performs the above rules:
void Txc1::handleMessage(cMessage *msg) {
if (isName("toc")) {
if (msg->isName("tictocMsg")) {
send(msg,"out1");
} else if (msg->isName("rndMsg")) {
send(msg,"out2");
}
} else {
// other nodes just sends this message back
send(msg,"out1");
}
}
At the moment I try to send packets between one Heltec WIFI LoRa V2 and another by reading the serial-line and sending the input via LoRa.
Small packets (like 30 bytes) work every time, but as bigger the packet gets the packet won't be received every time or even never.
So I write a little sending loop, where my sender sends at every iteration a packet, which gets every time 10 byte bigger, and surprisingly every packet was received by the sender (I tried that until 500 bytes).
After that, I wanted to send a 80 byte serial input message and this did not work. Do you know what's the problem with that?
void setup() {
// ... LoRa.begin(); ....
LoRa.onReceive(onReceive);
// ... LoRa.receive(); ...
}
void onReceive(int packetSize) { // uses the interrupt pin on the dio0
String packet = "";
packSize = String(packetSize,DEC);
for (int i = 0; i < packetSize; i++) {
packet += (char) LoRa.read();
}
Serial.println(packet);
delay(5);
} ```
``` // writer
boolean sendPacket (String packet) {
Serial.println("Send begin");
LoRa.beginPacket(false); // true: optional implicit mode (--> Set everything on both sides?!)
LoRa.setTxPower(14,RF_PACONFIG_PASELECT_PABOOST);
LoRa.print(packet); // also LoRa.write(byte(, length));
LoRa.endPacket(false); // true: async mode: doas not wair until transmission is completed
delay(250);
// put the radio into receive mode
LoRa.receive(); // set redio back in receive mode
delay(750);
Serial.println("Send end");
return true; // will be changed
}
void loop(){
while(Serial.available() > 0 ){
delay(2); //delay to allow byte to arrive in input buffer
String text = Serial.readString();
digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
boolean packetSent = false;
while (!packetSent) {
packetSent = sendPacket(text);
if (packetSent) {
Serial.print("Packet has been sent: ");
Serial.println(text);
} else {
Serial.print("Retry sending packet: ");
Serial.println(text);
}
}
digitalWrite(LED, LOW); // turn the LED off (HIGH is the voltage level)
}
} ```
I am using OMNET 5.0, SUMO-0.25.0 and VEINS-4.4. When a vehicle receive a message; onData() is called. I can get external ID of the current vehicle using mobility->getExternalId(); but how I know the the external ID of wsm message sender
The code for initialize():
void TraCIDemo11p::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
mobility = TraCIMobilityAccess().get(getParentModule());
traci = mobility->getCommandInterface();
traciVehicle = mobility->getVehicleCommandInterface();
annotations = AnnotationManagerAccess().getIfExists();
ASSERT(annotations);
getExternalID = mobility->getExternalId();
sentMessage = false;
lastDroveAt = simTime();
findHost()->subscribe(parkingStateChangedSignal, this);
isParking = false;
sendWhileParking = par("sendWhileParking").boolValue();
}
}
The code for onData():
void TraCIDemo11p::onData(WaveShortMessage* wsm) {
std::cout << " I am "<< getExternalID <<"and I received a message from ???? "<<endl;
findHost()->getDisplayString().updateWith("r=16,green");
annotations->scheduleErase(1, annotations->drawLine(wsm->getSenderPos(), mobility->getPositionAt(simTime()), "blue"));
if (mobility->getRoadId()[0] != ':')
traciVehicle->changeRoute(wsm->getWsmData(), 9999);
if (!sentMessage)
sendMessage(wsm->getWsmData());
}
A vehicle can be represented by two identifiers, either that one gotten from SUMO (i.e., calling getExternalId()) or that one of veins (myId normally), the one used in WaveShortMessage after calling getSenderAddress() is myId so I suggest that you focus on that last one.
Take a look on these two files to get a better idea on the used identifier and the existing methods: "BaseWaveApplLayer.h/.cc" & "WaveShortMessage_m.h/.cc"
I hope this helps.
I am a masters student working on localization, using ranging (time of arrival between vehicle and RSU) and relative location (Using emulated Inertial Navigation System).
I have done an implementation of my kalman filter based localization logic on Matlab, now I would like to implement this on veins. I want only the RSU to send out a message comprising of its location and ID
1) I know that i can use
double Coord = mobility->getCurrentPosition().x;
double Coord = mobility->getCurrentPosition().y;
to the location of RSU(and my vehicle as well), I do not understand how I should assign these coordinates to the message. I cannot use sstream since I understand that the message are supposed to be of type const char *
Thanks for any input
Edit 1: So this is what my new code on RSU looks like:
#include "RsuScOne.h"
#include <sstream>
Define_Module(RsuScOne);
void RsuScOne::initialize(int stage) {
BaseWaveApplLayer::initialize(stage);
if (stage == 0) {
//Initializing members and pointers of your application goes here
//WaveShortMessage* wsm = new WaveShortMessage();
EV << "Initializing " << std::endl;
}
else if (stage == 1) {
//Initializing members that require initialized other modules goes here
}
}
void RsuScOne::finish() {
BaseWaveApplLayer::finish();
//statistics recording goes here
cancelEvent(sendWSAEvt);
}
void RsuScOne::onWSM(WaveShortMessage* wsm) {
//Your application has received a data message from another car or RSU
//code for handling the message goes here, see TraciDemo11p.cc for examples
populateWSM(wsm);
std::stringstream ss;
ss<<mobility->getCurrentPosition().x<<mobility->getCurrentPosition().y;
wsm->setWsmData(ss.str().c_str());
scheduleAt(simTime()+par("beaconInterval").doubleValue(), sendWSAEvt);
EV<<wsm;
}
void RsuScOne::handleSelfMsg(cMessage* msg) {
BaseWaveApplLayer::handleSelfMsg(msg);
}
But I realize that all that being done now is my RSU constantly sending a generic BSM, Why is this so?