My omnett++ simulation is stuck in a loop - omnet++

Whenever I run my simulation the msg that is initial created at rdrchk1 gets stuck going between
rdrchk1 and rdrsucess1.
Here is my C++ code:
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
class rdr : 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(rdr);
void rdr::initialize()
{
int v1 = rand() % 100;
int v2 = rand() % 100;
int v3 = rand() % 100;
if (strcmp("rdrchk1", getName()) == 0) {
cMessage *msg = new cMessage("objectcheck");
if (v1<78|| v2 < 82 || v3 <69){
int n = 0;
send(msg, "out", n);
}
else{
int d=1;
send(msg, "out", d);
}
}
}
void rdr::handleMessage(cMessage *msg)
{
int t = 0;
send(msg, "out",t);
}
Here is my NED code:
simple rdr
{
parameters:
#display("i=block/routing");
gates:
input in[4];
output out[4];
}
//
network radr
{
#display("bgb=356,232");
submodules:
rdrchk1: rdr {
#display("p=85,67");
}
rdrfail1: rdr {
#display("p=275,133;i=block/wheelbarrow");
}
rdrsucess1: rdr {
#display("p=291,61");
}
connections allowunconnected:
rdrchk1.out[1] --> rdrfail1.in++;
rdrchk1.out[0] --> rdrsucess1.in++;
rdrchk1.in[2] <-- rdrfail1.out++;
rdrchk1.in[3] <-- rdrsucess1.out++;
}
I know it's stuck because whenever I edit my code so that it is guaranteed to go to rdrfail1 the next step it is stuck going between rdrchk1 and rdrsucess1. Can any one tell me why it is doing that and what I could do to fix it. Thank you for your time.

Here is what is happening in your model.
In initialize() of rdrchk1 a new message is created. Then that message is sent:
a. to rdrsucess1 when the condition if (v1<78|| v2 < 82 || v3 <69) is true
or
b. to rdrfail1 otherwise
If rdrsucess1 receives the message, it immediately sends that message to rdrchk1 (because in your network port with index 0 of gate out of rdrsucess1 is connected to rdrchk1).
If rdrfail1 receives the message, it immediately sends that message to rdrchk1 (because in your network port with index 0 of gate out of rdrfail1 is connected to rdrchk1).
Then rdrchk1 receives the message and sends it immediately to rdrsucess1.
Then points 2 and 4 are repeated endlessly.

Related

Omnet++ No Gate Index specified when accessing vector gate

I'm asking about a ring topology network, I'm looking to send a message from the node to hub and then to another node then back to the hub but when it simulates there is an error that pops up. I'm not sure what is the issue.
send()/sendDelayed(): No gate index specified when accessing vector gate 'out' -- in module (node) Startop.node[0] (id=2), during network initialization
Here is my .ned file:
package startop;
simple node
{
parameters:
#display("i=device/pc2_s");
gates:
input in[];
output out[];
}
simple hub
{
parameters:
#display("i=device/switch");
gates:
input in[];
output out[];
}
network Startop
{
parameters:
int n #prompt("Number of stations") = default(2);
submodules:
node[n]: node;
hub: hub {
#display("p=222,170");
}
connections allowunconnected:
for i=0..n-1 {
node[i].out++ --> hub.in++;
hub.out++ --> node[i].in++;
}
}
This is the .cc file:
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
class node : public cSimpleModule
{
private:
simtime_t timeout; // timeout
cMessage *timeoutEvent; // holds pointer to the timeout self-message
public:
node();
virtual ~node();
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(node);
node::node()
{
timeoutEvent = nullptr;
}
node::~node()
{
cancelAndDelete(timeoutEvent);
}
void node::initialize()
{
// Initialize variables.
timeout = 1.0;
timeoutEvent = new cMessage("timeoutEvent");
// Generate and send initial message.
EV << "Sending initial message\n";
cMessage *msg = new cMessage("StarMsg");
send(msg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);
}
void node::handleMessage(cMessage *msg)
{
if (msg == timeoutEvent) {
// If we receive the timeout event, that means the packet hasn't
// arrived in time and we have to re-send it.
EV << "Timeout expired, resending message and restarting timer\n";
cMessage *newMsg = new cMessage("StarMsg");
send(newMsg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);
}
else { // message arrived
// Acknowledgement received -- delete the received message and cancel
// the timeout event.
EV << "Timer cancelled.\n";
cancelEvent(timeoutEvent);
delete msg;
// Ready to send another one.
cMessage *newMsg = new cMessage("starMsg");
send(newMsg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);
}
}
class hub : public cSimpleModule
{
protected:
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(hub);
void hub::handleMessage(cMessage *msg)
{
if (uniform(0, 1) < 0.1) {
EV << "\"Losing\" message.\n";
bubble("message lost"); // making animation more informative...
delete msg;
}
else {
EV << "Sending back same message as acknowledgement.\n";
send(msg, "out");
}
}
May I know how to solve this problem?
The issue is exactly what the error message said. The NED file defines the out gate a vector both in node and hub:
output out[];
However your c++ code always uses the send method send(msg, "out") without specifying which out gate should be used. i.e. it never specifies the index. You must use the send(msg, "out", getIndex) for this.

Omnet++ Gate Index out of range

I'm making a randomly generated network where the node will send an update massage after asking if the other node already know the update. Currently the update status is still predefined. I'm getting this error message when running the simulation:
send()/sendDelayed(): Gate index 1048576 out of range when accessing vector gate 'out[]' with size 1 -- in module (Sg1) Simplegossip1.node[2] (id=4), at t=0s event #1
Here's my code:
simplegossip1.ned
simple Sg1
{
parameters:
#display("i=block/routing");
bool updated;
gates:
input in[]; // declare in[] and out[] to be vector gates
output out[];
}
network Simplegossip1
{
parameters:
int count;
double connectedness; // 0.0<x<1.0
#display("bgb=640,444");
submodules:
node[count]: Sg1 {
gates:
in[]; // removed the size of gate
out[];
}
connections allowunconnected:
for i=0..count-2, for j=i+1..count-1, if uniform(0,1)<connectedness {
node[i].out++ --> node[j].in++;
node[i].in++ <-- node[j].out++;
}
}
Here's the cc file.
sg1.cc
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* First attempt for gossip protocol
*/
class Sg1 : public cSimpleModule
{
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(Sg1);
void Sg1::initialize()
{
if (getIndex() == 0) {
cMessage *askupdated = new cMessage("Ask Update");
int m = gateSize("out");
int l = intuniform(0, m-1);
send(askupdated, "out",l);
}
}
void Sg1::handleMessage(cMessage *msg)
{
//gate randomizer
int n = gateSize("out");
int k = intuniform(0, n-1);
int sid = msg->getArrivalGateId();
bool updatestatus = par("updated");
EV << "Received message `" << msg->getName() << "', sending it out again\n";
if (strncmp (msg->getName(),"Ask Update",2) == 0) {
if (updatestatus == true){
delete msg;
cMessage *updated = new cMessage("Updated");
send(updated, "out", sid);
}
else {
delete msg;
cMessage *unupdated = new cMessage("Unupdated");
send(unupdated, "out", sid);
}
}
else if (strncmp (msg->getName(),"Unupdated",2) == 0) {
delete msg;
cMessage *update = new cMessage("Here is the update");
send(update, "out", sid);
}
else {
delete msg;
cMessage *askupdated = new cMessage("Ask Update");
send(askupdated, "out", sid);
}
}
And an omnet.ini file that only calling the Simplegossip1 network.
How do I solve this? Thanks in advance.
In the line:
int sid = msg->getArrivalGateId();
you read the gate ID. Then you use this value as a gate index:
send(updated, "out", sid);
However, a gate ID is not the same as gate index. Therefore there is an error during send().
In the simulation every object (e.g. module, gate, message) has a unique number (i.e. ID). It is clearly mentioned in
OMNeT++ Simulation Library.
You should check the current size of the gate and be sure that you do not try to send via index out of scope.

Omnet++ Unknown Parameter in Module Error

I'm making a randomly generated network where the node will send an update massage after asking if the other node already know the update. Currently the update status is still predefined. I'm getting this error message when running the simulation:
"(omnetpp::cModule)Simplegossip1: Unknown parameter 'updated' -- in module (Sg1) Simplegossip1.node[0] (id=2), at t=0s, event #1"
Here's my code:
simplegossip1.ned (I'm using code from here How to create a randomly connected graph in OMNeT++?)
simple Sg1
{
parameters:
#display("i=block/routing");
bool updated;
gates:
input in[]; // declare in[] and out[] to be vector gates
output out[];
}
network Simplegossip1
{
parameters:
int count;
double connectedness; // 0.0<x<1.0
submodules:
node[count]: Sg1 {
gates:
in[]; // removed the size of gate
out[];
}
connections allowunconnected:
for i=0..count-2, for j=i+1..count-1, if uniform(0,1)<connectedness {
node[i].out++ --> node[j].in++;
node[i].in++ <-- node[j].out++;
}
}
sg1.cc
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* First attempt for gossip protocol
*/
class Sg1 : public cSimpleModule
{
public:
cMessage *askupdated = new cMessage("Ask Update");
cMessage *updated = new cMessage("Updated");
cMessage *unupdated = new cMessage("Unupdated");
cMessage *update = new cMessage("Here is the update");
protected:
virtual void forwardMessage(cMessage *msg, int dest);
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(Sg1);
void Sg1::initialize()
{
if (getIndex() == 0) {
// Boot the process scheduling the initial message as a self-message.
char msgname[20];
sprintf(msgname, "tic-%d", getIndex());
cMessage *msg = new cMessage(msgname);
scheduleAt(0.0, msg);
}
}
void Sg1::handleMessage(cMessage *msg)
{
int n = gateSize("out");
int k = intuniform(0, n-1);
int sid = msg->getArrivalGateId();
bool updatestatus = getParentModule()->par("updated");
if (msg == askupdated) {
if (updatestatus == true){
forwardMessage(updated,sid);
}
else {
forwardMessage(unupdated,sid);
}
}
else if (msg == unupdated) {
forwardMessage(update,sid);
}
else {
forwardMessage(askupdated,k);
}
}
void Sg1::forwardMessage(cMessage *msg, int dest)
{
// In this example, we just pick a random gate to send it on.
// We draw a random number between 0 and the size of gate `out[]'.
EV << "Forwarding message " << msg << " on port out[" << dest << "]\n";
send(msg, "out", dest);
}
And an omnet.ini file that only calling the Simplegossip1 network.
How do I solve this? Thanks in advance.
You have to change the line
bool updatestatus = getParentModule()->par("updated");
into
bool updatestatus = par("updated");
because updated is the parameter of Sg1 not of the parent of Sg1.

send packet on specific gate omnet++

In omnet ++ while programing tic toc , if there are three nodes and all are connected to one another then how to send tic toc message to a specific node. for example i want to send message first to node A and then Node B and then Node C ; how would i code this.
#include <string.h>
#include <omnetpp.h>
int x=0;
class computerf : public cSimpleModule
{
protected:
virtual void initialize();
virtual void handleMessage(cMessage *msg);virtual void forwardMessage(cMessage *msg);
};
Define_Module(computerf);
void computerf::initialize()
{
if (strcmp("computer1", getName()) == 0)
{
cMessage *msg = new cMessage("tictocMsg");
forwardMessage(msg);
}
}
void computerf::handleMessage(cMessage *msg)
{
{
forwardMessage(msg);
}
}
void computerf::forwardMessage(cMessage *msg)
{
// In this example, we just pick a random gate to send it on.
// We draw a random number between 0 and the size of gate `out[]'.
int n = gateSize("out");
int k = intuniform(0,n-1);
EV << "Forwarding message " << msg << " on port out[" << k << "]\n";
send(msg, "out", 1);
EV <<"n is "<<n;
}
here in this code forwardMessage function sends message on random gate but i want to send message on specific gate.
this is the .ned file
simple computer
{
gates:
input in[2];
output out[2];
}
//
// TODO documentation
//
network Network
{
#display("bgb=545,242");
submodules:
A: computer {
#display("p=52,86");
}
B: computer {
#display("p=311,83");
}
C: computer {
#display("p=175,189");
}
connections:
A.out[0] --> B.in[0];
B.out[0] --> A.in[0];
A.out[1] --> C.in[1];
C.out[1] --> A.in[1];
C.out[0] --> B.in[1];
B.out[1] --> C.in[0];
}
basically i want node A to send message to node C and Node A to send message to node B simultaneously
if i use the hanlde message function
void computer::handleMessage(cMessage *msg)
{
send(msg, "out",0); //send(msg, "out",0);
}
now here in out send(msg, "out",0); i want to specify which "out" i want send message to node C and then to Node B but how?
The third parameter of the send(msg, "gate", index) is the actual gate index you can use while sending out messages on a vector gate. According to your NED file, send(msg, "out",0); sends the message to B while send(msg, "out",1); sends it to C.
You need to create those gates in Your ned file:
simple Txc
{
parameters:
#display("i=block/routing"); // add a default icon
gates:
input in1;
output out1;
input in2;
output out2;
}
network Tictoc
{
submodules:
tic: Txc {
parameters:
#display("i=,cyan");
}
toc: Txc {
parameters:
#display("i=,cyan");
}
toctic: Txc {
parameters:
#display("i=,cyan");
}
connections:
tic.out --> { delay = 100ms; } --> toc.in;
tic.in <-- { delay = 100ms; } <-- toc.out;
toctic.out2 --> { delay = 100ms; } --> toc.in2;
toctic.in2 <-- { delay = 100ms; } <-- toc.out2;
//....
}
With this You could send messages like this:
void computerf::forwardMessage(cMessage *msg)
{
int n = gateSize("out");
int k = intuniform(0,n-1);
send(msg, "out1", 1);
//Second message
send(msg, "out2", 1);
}
Hope this helps.
Best

Measuring Time of Flight with Arduino Uno

I am trying to implement a master/slave setup to determine the time of flight between two Arduino Uno boards and ultimately use that as a measure of distance between the two. Using the standard 16MHz crystal and the APC220 from DFRobot communicating between the two is easy but getting a time of flight reading is where I get stuck.
I use the following code on the master side to send the first signal and receive the echo from the slave:
// set pins:
const int switchPin = 3; // pin number of the switch
// variables:
int switchState = 0; // variable for reading switch status
int iDisplay = 1;
unsigned long start, finished, elapsed;
// initialize
void setup()
{
// initialize switch pin as input:
pinMode(switchPin, INPUT);
// initialize serial wireless communication:
Serial.begin(9600);
// read initial state of switch
switchState = digitalRead(switchPin);
}
void displayResult()
{
float h,m,s,ms;
unsigned long over;
elapsed=finished-start;
h=int(elapsed/3600000);
over=elapsed%3600000;
m=int(over/60000);
over=over%60000;
s=int(over/1000);
ms=over%1000;
Serial.print("Raw elapsed time: ");
Serial.println(elapsed);
Serial.print("Elapsed time: ");
Serial.print(h,0);
Serial.print("h ");
Serial.print(m,0);
Serial.print("m ");
Serial.print(s,0);
Serial.print("s ");
Serial.print(ms,0);
Serial.println("ms");
Serial.println();
}
// program loop
void loop()
{
if (Serial.available()>0 && iDisplay == 1)
{
finished=millis();
displayResult();
iDisplay = 0;//Only once
}
// read switch state and print line if state has changed
switch (digitalRead(switchPin)) { // read pin status
case HIGH:
if (switchState == LOW)
{ // check if message has to be sent
start=millis();
delay(200); // for debounce
iDisplay = 1;//Only once
Serial.println(100); // send message about switch
switchState = HIGH; // message has been sent
}
break;
case LOW:
if (switchState == HIGH)
{ // check if message has to be sent
start=millis();
delay(200); // for debounce
iDisplay = 1;//Only once
Serial.println(100); // send message about switch
switchState = LOW; // message has been sent
}
break;
}
}
And the following code for the slave:
// variables:
int intTime = 0;
// initialize
void setup()
{
// initialize serial wireless communication:
Serial.begin(9600);
}
// program loop
void loop()
{
if (Serial.available()>0)
{
intTime = Serial.parseInt();
if (intTime > 1)
{
Serial.println(intTime);
}
intTime = 0;
}
}
Yet this only returns the 200 Milliseconds from the debounce delay, can this be done with the Arduino? Am I getting the math or the code wrong?

Resources