Omnet++ error when simulating multiple submodules - simulation

I am trying to simulate 10 submodules. But omnet++ gives an error when the number of submodules are greater than five. here is the error:
(omnetpp::cMessage)sampleEvent: par(int): Has no parameter #4 -- in module (Sam1) Net.sampler1[4] (id=6), during network initialization
My .ned file
simple Sam1
{
parameters:
#display("i=block/routing");
gates:
inout gate[]; // declare two way connections
}
simple Svr1
{
parameters:
#display("i=block/process");
gates:
inout gate[]; // declare two way connections
}
network Net
{
#display("bgb=670.56,274.32");
types:
channel Ch extends ned.DelayChannel
{
delay = 100ns;
}
submodules:
sampler1[10]: Sam1 {
#display("p=334,127;is=l");
}
server: Svr1 {
parameters:
#display("i=,gold;p=109.21999,88.899994");
}
connections:
for i=0..9 {
server.gate++ <--> Ch <--> sampler1[i].gate++;
}
}
omnetpp.ini file
[General]
[Config Net]
network = Net
record-eventlog = true
sam1 class
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
class Sam1 : public cSimpleModule
{
private:
simtime_t timeout; // timeout
cMessage *sampleEvent; // holds pointer to the self-message
int seq; // message sequ ence number
cMessage *message; // message that has to be re-sent on timeout
double vK;
double vM;
double threshold = 1.0;
int counter;
double xmean = 0.01;
double xsigma = 1;
double sensigma = 0.1;
double x;
double zOut = 0.0;
double previousSentTime = 0.0;
int samplerID;
double xSum;
long numSent;
long numReceived;
long totalEvents;
cLongHistogram SampleStats;
cOutVector SampleVector;
cLongHistogram interSampleStats;
cOutVector interSampleVector;
cLongHistogram sentSampleStats;
cOutVector sentSampleVector;
cOutVector constructedSignal;
public:
Sam1();
virtual ~Sam1();
protected:
virtual cMessage *generateNewMessage();
virtual void sampleAndSend(cMessage *msg);
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
// The finish() function is called by OMNeT++ at the end of the simulation:
virtual void finish();
};
Define_Module(Sam1);
Sam1::Sam1()
{
sampleEvent = message = nullptr;
}
Sam1::~Sam1()
{
cancelAndDelete(sampleEvent);
delete message;
}
void Sam1::initialize()
{
// Initialize variables.
vM = 0;
seq = 0;
timeout = 100.0; // in every 100 second
sampleEvent = new cMessage("sampleEvent");
xSum = 0.0;
counter = 1;
numSent = 0;
numReceived = 0;
totalEvents = 0;
WATCH(numSent);
WATCH(totalEvents);
samplerID = getIndex();
interSampleStats.setName("interSampleStats");
interSampleStats.setRangeAutoUpper(0, 10, 1.5);
interSampleVector.setName("interSample");
SampleStats.setName("SampleStats");
// interSampleStats.setRangeAutoUpper(0, 10, 1.5);
SampleVector.setName("Sample");
sentSampleStats.setName("sentSampleStats");
// interSampleStats.setRangeAutoUpper(0, 10, 1.5);
sentSampleVector.setName("sentSample");
constructedSignal.setName("constructedSignal");
// Generate and send initial message.
EV << "Sending initial message\n";
message = generateNewMessage();
sampleAndSend(message);
// scheduleAt(simTime()+timeout, sampleEvent);
}
void Sam1::handleMessage(cMessage *msg)
{
if (msg == sampleEvent) {
// EV << "sampling Again\n";
// Ready to send another one.
message = generateNewMessage();
sampleAndSend(message);
}
}
cMessage *Sam1::generateNewMessage()
{
// Generate a message
cMessage *msg = new cMessage("sampleEvent");
double t1 = simTime().dbl() * 1000;
msg->addPar("sampleValue");
x = normal(xmean, xsigma) + normal(xmean, sensigma);
xSum = x + xSum;
msg->par("sampleValue").setDoubleValue(xSum);
msg->addPar("counter");
msg->par("counter").setLongValue(counter);
msg->addPar("generatedTimestamp");
msg->par("generatedTimestamp").setDoubleValue(t1);
msg->addPar("samplerName");
msg->par(samplerID);
counter = counter +1;
totalEvents++;
return msg;
}
void Sam1::sampleAndSend(cMessage *msg)
{
double sampleValue = msg->par("sampleValue").doubleValue();
double genTimestamp = msg->par("generatedTimestamp").doubleValue();
cMessage *copy = (cMessage *)msg->dup();
vK = sampleValue-vM;
// EV << vK << " vK \n";
if(fabs(sampleValue-vM) > threshold){
vM = sampleValue;
zOut = sampleValue;
// 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("gate");
int k = intuniform(0, n-1);
send(copy, "gate$o", k);
double t2 = simTime().dbl() * 1000; // sample time in milli seconds
double interSample = t2 - previousSentTime;
previousSentTime = genTimestamp;
numSent++;
interSampleVector.record(interSample);
interSampleStats.collect(interSample);
sentSampleVector.record(1);
sentSampleStats.collect(1);
}else{
zOut = vM;
sentSampleVector.record(0);
sentSampleStats.collect(0);
}
EV << "vM " << vM << endl;
// EV << "sampling Again. node " << simTime() << endl;
SampleVector.record(sampleValue);
SampleStats.collect(sampleValue);
constructedSignal.record(zOut);
scheduleAt(simTime()+timeout, sampleEvent);
}
void Sam1::finish(){
// This function is called by OMNeT++ at the end of the simulation.
EV << "Sent: " << numSent << endl;
EV << "Total Events: " << totalEvents << endl;
float rate = (float)numSent/totalEvents;
EV << "Traffic Reduction: " << rate << endl;
EV << "Threshold: " << threshold << endl;
EV << "Signal Mean: " << xmean << endl;
EV << "Signam sigma: " << xsigma << endl;
EV << "Sensor Sigma: " << sensigma << endl;
EV << "Inter Sample Time, min: " << interSampleStats.getMin() << endl;
EV << "Inter Sample Time, max: " << interSampleStats.getMax() << endl;
EV << "Inter Sample Time, mean: " << interSampleStats.getMean() << endl;
EV << "Inter Sample Time, stddev: " << interSampleStats.getStddev() << endl;
recordScalar("#sent", numSent);
recordScalar("#total", totalEvents);
interSampleStats.recordAs("inter sample");
SampleStats.recordAs("sample");
sentSampleStats.recordAs("sent sample");
}
/**
* Sends back an acknowledgement -- or not.
*/
class Svr1 : public cSimpleModule
{
protected:
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(Svr1);
void Svr1::handleMessage(cMessage *msg)
{
double sampleValue = msg->par("sampleValue").doubleValue();
long counter = msg->par("counter").longValue();
long samplerID = msg->par("samplerName").longValue();
EV << sampleValue << " received, sending back an acknowledgment from sampler "<< samplerID << ". counter " << counter << "\n";
delete 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("gate");
int k = msg->getArrivalGate()->getIndex();
EV << "n: " << n << "k: " << k << endl;
// send(new cMessage("ack"), "gate$o", k);
}

Related

how to point at multiply struct with one struct pointer in c++

Write a assign_obj.h file so that the assign_driver file will output the
following. When implementing assign_obj.h think about how efficient your program will run. You must
implement your assign_obj class using a dynamic array.
assign_obj:: assign_obj() function will just set size to zero
assign_obj:: assign_obj(std::string s) function will go through each character of string and convert it to uppercase and push it the last of A
std::ostream& operator<<(std::ostream & out, assign_obj & obj) function will go through each data in obj.A vector and convert integer into string and
than output the data in this format [value:count value:count ....]
class assign_obj{
private:
struct item{
char value;
int count;
};
item *A;
int size;
public:
assign_obj();
assign_obj(std::string);
friend std::ostream& operator<<(std::ostream & out, assign_obj & obj);
}
int main(){
assign_obj ao1("dsdfdf");
std::cout << ao1 << std::endl;
}
This is the output that I want
[ D:1 S:1 D:1 F:1 D:1 F:1 ]
assign_obj:: assign_obj(){
size = 0;
}
assign_obj:: assign_obj(std::string s){
size = s.size();
for(int i = 0; i < s.size(); i++){
char c = std::toupper(s[i]);
A = new item{c,1};
}
}
# std::ostream& operator<<(std::ostream & out, assign_obj & obj){
std::cout<< "size: " << obj.size <<std::endl;
out << "[ ";
for(int i = 0; i < obj.size; i++){
out << obj.A[i].value << ":" << std::to_string(obj.A[i].count) << " ";
}
out << "]" << "\n";
return out;
}

Finding the smallest and largest numbers by single linked list and two classes

I got several numbers from user by single linked list and my program's task is finding the smallest and largest number in the linked list by two classes and print them on the sreen. But after a time, my program got closed and i didn't see anything. What went wrong?
#include<iostream>
using namespace std;
struct Node
{
double Number;
struct Node *Point;
} *End = nullptr;
typedef struct Node node;
namespace Min_Max
{
class Min
{
node *Result = End;
public: Min()
{
if(Result == nullptr)
{
cout << "You didn\'t enter anything!\a";
system("pause");
exit(EXIT_FAILURE);
}
node *Counter = Result->Point;
while(Counter != nullptr)
{
if(Counter->Number < Result->Number)
Result = Counter;
Result = Result->Point;
}
}
node* Show()
{
return Result;
}
};
class Max
{
private:
node *Result = End;
public:
Max()
{
if(Result == nullptr)
{
cout << "You didn\'t enter anything!\a";
system("pause");
exit(EXIT_FAILURE);
}
node *Counter = Result->Point;
while(Counter != nullptr)
{
if(Counter->Number > Result->Number)
Result = Counter;
Result = Result->Point;
}
}
node* Show()
{
return Result;
}
};
};
int main()
{
node *linker = nullptr;
register short int Counter = 1;
while(1)
{
linker = new node;
if(linker == nullptr)
{
cout << "An error occurred during allocating memory." << endl << endl;
system("pause");
return 0;
}
cout << "Number " << Counter << ": Enter your number: ";
cin >> linker->Number;
system("cls");
if(linker->Number == 0)
{
delete linker;
break;
}
linker->Point = End;
End = linker;
Counter++;
}
Min_Max::Min Min;
Min_Max::Max Max;
cout << "The smallest number is " << (Min.Show())->Number << endl;
cout << "The largest number is " << (Max.Show())->Number << endl;
return 0;
}
My C++ compiler is GCC-C++11 and my operating system is Windows 10.

How do I change a pointer variable's value and keep the changes outside of a function without pass-by-reference?

I am doing a project for a class writing C-String-editing functions. 3/5 of the functions I have to write change the size of the char arrays I have to use, and they are being read through an ifstream input. Here is the program:
#include <iostream>
#include <fstream>
using namespace std;
void stringCopy(char *A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *A, char *B); //added const to make sure b is never changed
int stringPosition(char *A, char B);
int stringLength(char *A);
//-------------------MY-FUNCTIONS----------------------
int cStringLen(const char*); //finds string length, but doesn't account for null char
void reSize(char*&, int len, int newLen);
void input(char*& A, istream& is);
void printMessage(const char* word1, const char* word2, const char* message);
int main()
{
ifstream ifs{"input.txt"};
ofstream ofs{"output.txt"};
char* word1 = "";
char* word2 = "";
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringCopy()");
stringCopy(word1, word2);
printMessage(word1, word2, "after stringCopy()");
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringCompare()");
if(stringCompare(word1, word2))
{
cout << "They match!" << endl;
}
else
{
cout << "They don't match!" << endl;
}
stringCopy(word1, word2);
printMessage(word1, word2, "comparing after stringCopy()");
if(stringCompare(word1, word2))
{
cout << "They match!" << endl;
}
else
{
cout << "They don't match!" << endl;
}
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringConcatenation()");
stringConcatenation(word1, word2);
printMessage(word1, word2, "after stringConcatenation()");
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringPosition()");
cout << "Searching for 'm' in word1..." << endl << "position returned is: " << stringPosition(word1, 'm') << endl;
cout << "Searching for 'n' in word2..." << endl << "position returned is: " << stringPosition(word2, 'n') << endl;
cout << endl;
input(word1, ifs);
cout << "stringLength()" << endl;
cout << "word1: " << word1 << endl;
cout << "The length of word1 is: " << stringLength(word1) << endl;
cout << "after stringLength()" << endl;
cout << "word1: " << word1 << endl;
return 0;
}
void stringCopy(char *A, char *B)
{
///GETTING THE SIZES OF BOTH ARRAYS
int counterA = cStringLen(A) + 1;
int counterB = cStringLen(B) + 1;
///MAKES SURE BOTH ARE THE SAME SIZE BEFORE COPYING
if(counterA < counterB)
{
reSize(A, counterA, counterB);
}
else
{
reSize(A, counterB, counterA);
}
///THE COPY
for(int i = 0; i < counterB; i++) *(A + i) = *(B + i); //each character is copied to A from B
}
bool stringCompare(char *A, char *B)
{
///getting length of one string
int counter = cStringLen(A);
///will move through string until diff char found
for(int i = 0; i < counter + 1; i++)
{
if(*(A + i) != *(B + i))
{
return false;
}
}
return true;
}
void stringConcatenation(char *A, char *B) //added const to make sure b is never changed
{
///getting length of both strings
int counterA = cStringLen(A)+1;
int counterB = cStringLen(B)+1;
///putting the length of both together for new string
const int COUNTERS = counterA + counterB - 1;
///making A the size of both strings - 1
reSize(A, counterA, COUNTERS);
///copying b to the parts of a past the original
for(int i = 0; i < counterB; i++)
{
*(A + (counterA - 1) + i) = *(B + i); //will override the '/0' char of A
}
}
int stringPosition(char *A, char B)
{
int counter = cStringLen(A) + 1;
///searching through string for char
for(int i = 0; i < counter; i++)
{
if(*(A + i) == B)
{
return i; //found!
}
}
///checking if b == '\0' and a '\0' isn't found somewhere before last spot of A
if(B == '\0')
{
return counter;
}
return -1; //not found
}
int stringLength(char *A)
{
int counter = cStringLen(A) + 1;
char* car = new char[counter + 1];
for(int i = 0; i < counter; i++)
{
*(car + 1 + i) = *(A + i);
}
*(car + 0) = counter;
delete[] A;
A = car;
/**
* Will take string as param.
* Shifts all characters to the right by one and store the length of the string in position 0.
- Length doesn't include position 0.
*/
return counter; //temp
}
//-----------------------------------------MY FUNCTIONS---------------------------------------------------------------------------
int cStringLen(const char* A) //finds string length, but doesn't account for null char
{
int counter = 0;
while(*(A + counter) != '\0')
{
counter++;
}
return counter;
}
void reSize(char*& A, int len, int newLen)
{
char* car = new char[newLen];
for(int i = 0; i < newLen; i++)
{
if(i < len)
{
*(car + i) = *(A + i);
}
else if(i >= len && i < newLen)
{
*(car + i) = '\0';
}
}
delete[] A;
A = car;
}
void input(char*& A, istream& is)
{
int wordSize = 0;
int arrSize = 1;
char c = 'o'; //checking char
char* car = new char[arrSize];
while((!(is.eof())) && (c != ' ' && c != '\t' && c != '\n'))
{
is.unsetf(ios_base::skipws);
is >> c;
if(is.eof())
{
delete[] A;
A = car;
return;
}
if(c != ' ' && c != '\t' && c != '\n')
{
if(wordSize == arrSize)
{
reSize(car, arrSize, arrSize * 2);
}
*(car + wordSize) = c;
}
wordSize++;
}
is.setf(ios_base::skipws);
delete[] A;
A = car;
}
void printMessage(const char* word1, const char* word2, const char* message)
{
cout << message << endl;
cout << "word1: " << word1 << endl << "word2: " << word2 << endl;
}
I thought I got it all done just fine. Keep in mind that I added the "&" operator after each of the pointer parameters already. Here is how they were before:
void stringCopy(char *&A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *&A, char *B); //added const to make sure b
is never changed
int stringPosition(char *A, char B);
int stringLength(char *&A);
But, when I got to class, my teacher said we weren't allowed to change the function headers in any way. So, I am stuck passing by value for the assignment. The problem is that I have no way of changing the c-strings outside the editing functions now. Any changes I do to them stay inside there.
It all compiles just fine, and, if I make the pointers pass-by-reference, the program runs flawlessly. I am just wondering how I could change the values of the c-strings outside of the editing functions. This assignment is starting to become a pain (so many f***ing restrictions).
I think what your teacher wants you to do is to change the value at the character pointer instead of creating a new string.
So instead trying to reassigning parameter A to a new char* you change the value that A points to in memory. That way the method that called your function still points to that same memory and when they access that location the get the value you changed from within your function.

changing variables within loop from outside class

I have a time class and a Build class. The harvest function increases the minerals count for the entire time, but the nunmber of minerals depends on the number of available workers. As soon as a build starts, the number of workers decreases.
So, how can i decrease the number of workers, within the loop, and not after the loop has finished.
I want minerals to keep increasing, but the number of workers should increase and decrease based on the Build call.
class Time {
private:
int minerals = 50;
int workers = 6;
int vespene = 0;
int supply = 6;
int time = 0;
public:
Time ();
int Time_counter();
void harvest();
int mineral_count();
int worker_count();
int supply_count();
void update(int m, int w, int s, int t);
void Display();
};
Time::Time ()
{
for (int i =0; i<9; i++)
{
update(minerals, workers, supply, time);
harvest();
time = i;
// Time_counter();
}
}
int Time::Time_counter() {
return time;
}
void Time::harvest() {
minerals+= workers * (0.7);
}
int Time:: mineral_count() {
return minerals;
}
int Time::worker_count() {
//return workers.size();
return workers;
}
int Time::supply_count() {
return supply;
}
void Time:: update(int m, int w, int s, int t) {
minerals = m;
workers = w;
supply = s;
time = t;
cout << "No. of Minerals: " <<minerals <<"\n" <<"No.of Workers: " <<workers <<"\n"
<< "No. of Supply: " <<supply <<"\n" <<"Current Time: " <<time << endl;
}
void Time:: Display ()
{
cout << "No. of Minerals: " <<minerals <<"\n" <<"No.of Workers: " <<workers <<"\n"
<< "No. of Supply: " <<supply <<"\n" <<"Current Time: " <<time << endl;
}
class Build: public Time {
public:
void Build_create();
};
void Build::Build_create() {
int build_count=0;
SCV obj;
int m = obj.mineral_count();
int w = obj.worker_count();
int s = obj.supply_count();
int t; // = obj.Time_counter();
if (m >= 50 && biuld_count<2)
{
cout << "Build start....";
m-= 50;
obj.update(m,w,s,t);
obj.Display ();
w-=1;
for (t = obj.Time_counter(); t <obj.Time_counter()+ 10; t++)
{cout<< "Building...";}
cout << " Build complete" << endl;
scv_count++;
w += 1;
s += 1;
t = obj.Time_counter();
obj.update(m, w, s, t);
obj.Display ();
}
else if (m<50)
{
cout << "Cannot build " << endl;
}
else if (build_count==2)
{
cout<<"two already built.." <<endl;
}

Undefined reference to a method in another class file, how to fix?

I've been working on a program that will do a couple of equations in regards to audio, SPL, etc.
I decided to have the main class file present the user with an option to choose what equation he wants to do, while the equations are housed in another class file.
Atm, the main class file is setup just to test maxPeakSPL(), yet I can't get it to run.
main.cpp
//Kh[a]os
#include "equations.h"
#include <iostream>
void mainLoop();
int maxSPL = 0;
int main()
{
std::cout << "Created by Kh[a]os" << std::endl << std::endl;
mainLoop();
return 0;
}
void mainLoop()
{
std::cout << "hi";
maxSPL = equations::maxPeakSPL();
std::cout << std::endl << maxSPL << "db" << std::endl << std::endl;
}
equations.h
#ifndef EQUATIONS_H
#define EQUATIONS_H
#include <string>
class equations
{
public:
equations();
static int maxPeakSPL();
protected:
private:
};
#endif // EQUATIONS_H
equations.cpp
#include "equations.h"
#include <iostream>
#include <string>
equations::equations()
{
}
static int maxPeakSPL()
{
int Sens = 0;
double Distance = 0;
int Watts = 0;
int sWatts = 2;
int eWatts = 0;
double maxSPL = 0;
double counter = 0;
double wall = 0;
std::string corner = "";
bool v = true;
std::cout << "Sensitivity (db): " << std::endl;
std::cin >> Sens;
std::cout << "Amplification (watts): " << std::endl;
std::cin >> Watts;
std::cout << "Listening Distance (meters): " << std::endl;
std::cin >> Distance;
std::cout << "Distance from Wall (ft): " << std::endl;
std::cin >> wall;
std::cout << "Are you they in a corner? (y/n): " << std::endl;
std::cin >> corner;
maxSPL = Sens - (Distance*3 - 3);
while(v == true)
{
if (sWatts > Watts)
{
v = false;
eWatts = sWatts;
sWatts = sWatts/2;
Watts = Watts-sWatts;
counter = (double)Watts/(double)eWatts;
counter = counter*3;
maxSPL = maxSPL + counter;
}
if (v == true)
{
maxSPL = maxSPL + 3;
sWatts = sWatts*2;
}
}
if (wall <= 4)
maxSPL = maxSPL + 3;
if (corner == "Y" || corner == "YES" || corner == "y" || corner == "yes")
maxSPL = maxSPL + 3;
return maxSPL;
}
The error I get when I run it is: undefined reference to `equations::maxPeakSPL()'
I haven't a clue how to fix this, any assistance would be great. Thank you.
In your main, try putting the function before the main block. Include an underscore before the name of your directives/flags.