⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 physic.cpp

📁 OMNET++仿真三色算法的源码,三色算法是无线传感器中一个典型的分簇算法
💻 CPP
字号:
#include "h/physic.h"#include <string.h>//define the sting that define the host displayDefine_Module(Physic);cNeighbour::cNeighbour(){};cNeighbour::~cNeighbour(){};void Physic::initialize(){	hosts.setName("hosts");	nbList.setName("nblist");	hosts.takeOwnership(false); // FIXME this is a terrible hack to prevent crash on exit because of double deletion --Andras	nbList.takeOwnership(false);	cModule *parent = parentModule();	cModule *mod;	char str[90];	posX = (int)parent->par("x");	posY = (int)parent->par("y");	numHost = (int)parent->par("numHost");	power = (double) par("txPower");	rxThreshold =  (double) par("rxThreshold"); 	delay = &par("channelDelay");	error = &par("channelError");	dataRate = &par("channelDatarate");	gatesNum = 0;	nbCount = 0;	msgWithErr =0;	//show the node on the map	//sprintf(str,displayS,posX,posY,"red");
	sprintf(str, displayS, posX, posY, IDLE_COLOR);	parentModule()->setDisplayString(0,str,true);	//fullfill the hosts vector	detectNeighbours();}void Physic::handleMessage(cMessage* msg){	d("\t--- physic ---");	char str[50];	//update position and go on/*
	if ( msg->arrivedOn("fromMobility") )	{		d("msg from mobility");		posX = (int)msg->par("x");		posY= (int)msg->par("y");		   update the position		sprintf(str,displayS,posX, posY,"red");		parentModule()->setDisplayString(0,str,true);		  compute the trasmission range that might have been changed		range = sqrt(power/rxThreshold);		  check which hosts are reachable		updateConnections();		delete msg;	}	else*/	//send the messages to the neighbours
		
	range = sqrt(power/rxThreshold);
	updateConnections();

	if ( msg->arrivedOn("fromMac") )	{		d("msg from Mac");
		Log("physic: message from Mac\n");
		//compute the trasmission range		range = sqrt(power/rxThreshold);		//send the message to all the neighbouts		broadcast(msg);		if( msg!= NULL );			delete msg;	}	else	{		//arrived from outside the module		d("msg from outside");		if(msg->hasBitError())		{			d("received message with errors...discarding!");			msgWithErr++;			delete msg;		}		else		{			d("got message from "<<msg->par("source"));			send(msg,"toMac"); // FIXME it is illegal to send a msg object and keep referencing it!!! -Andras		}	}}void Physic::broadcast(cMessage*msg){	cNeighbour* n = NULL;	d("broadcast Out");	for(int i =0; i < nbList.items() ;i++)	{		if(nbList[i])		{			//a new copy of message has to be made			cMessage* m = new cMessage(*msg);			n = (cNeighbour*) nbList[i];			send(m,n->gateIndex);		}	}}void Physic::detectNeighbours(){	//pointer to the modules that are to be scanned	cModule* mod;	//stores the index returned by cArray.add()	int pos = 0;
	char tmpstr[128];
	memset(tmpstr, 0x00, sizeof(tmpstr));
	d("detectNeigh");
	Log("Physic:detect Neighbours::\n");	for(int i=1; i<= simulation.lastModuleId(); i++)  	{		//scan the simulation module vector		mod = (cModule*)simulation.module(i);	   	if( strcmp(mod->name(), "physic")  == 0)	   	{		   cNeighbour *n = new cNeighbour;					   		   n->ph = mod->id();
		   //remember its parent module too		   n->mobHost = mod->parentModule()->id();		   n->gateIndex = -1;//not connected		   pos =  hosts.add(n);		   if(i == id())			   myI = pos;	   	}	}}void Physic::updateConnections(){	d("updateConnections");	cNeighbour* n;	for(int i=0; i< numHost ; i++)	{		//check the link avoiding to analyze itself		if ( ( i != myI) && checkConnection(i)){			n = (cNeighbour*)hosts[i];			d("link changed between this host and:"<<n->mobHost);			//make the other node do the check			if (n->mobHost < parentModule()->id())			{				d("notify the disconnection to the remote node-");				Physic* remote = (Physic*)simulation.module(n->ph);				// the index of this host on the remote hosts vector				remote->checkConnection( myI );			}		}	}}//returns true if the connection has changed statebool Physic::checkConnection(int i){	d("checkConnection");	cNeighbour* n = (cNeighbour*)hosts[i];
	int band;	//avoid the parent to this module parent	if( (n->ph != id()) &&  isReachable(id(),n->ph, band))	{		//if it is not known		if (nbList.find(n) == -1 )		{			nbList.add(n);			nbCount++;			d("connecting to"<<n->mobHost);			n->gateIndex= connectModules(n->ph,n->mobHost);		}		return true;	}	else	{		//check if it was connected	 	int a = nbList.find(n);		d("host not reachable "<<n->mobHost);		if(a!= -1)		{			d("diconnect from neighbour:"<<n->mobHost);			cNeighbour* tmp;			//remove do not delete the object from the			//memory! the list stores only a pointer to the			//original host object.			nbList.remove(a);			//avoid holes in the array			if( (nbCount>1) && (a!=nbCount-1))			{				tmp = (cNeighbour*)nbList.remove(nbCount-1);				nbList.addAt(a,tmp);			}			nbCount--;			n->gateIndex = -1;				//disconnect			disconnectFrom(n->ph,n->mobHost);			return true;		}		else		{			d("but "<<n->ph<<" was not connected");			return false;		}	}}int Physic::connectModules(int rPhysic,int rMod){	d("connectModules");	//a->b->c->d	int a,b,c,d;	//pointer to the remote physical layer	Physic *ph = (Physic*)simulation.module(rPhysic);	//pointer to the remote host object	cModule* mod = (cModule*) simulation.module(rMod);	//create the gates and the connection whithin these modules	setUpConn('O',a,b);	//do the same for the remote node. Note that 'c' will be used later for the conn	//between the two mobile hosts.	ph->setUpConn('I',d,c);	if( (a == -1) || (b == -1) || (c == -1) || (d == -1) )	{		ev << "Error in the connectModules function \n";		wait(2);	}	d(a<<"->"<<b<<"-->"<<c<<"->"<<d<<" OK!");	cBasicChannel *channel = new cSimpleChannel("channel");	channel->setDelay(delay->doubleValue());	channel->setDatarate(dataRate->doubleValue());	channel->setError(error->doubleValue());	parentModule()->gate(b)->connectTo(mod->gate(c), channel);	//draw the link	cGate *g = parentModule()->gate(b);	g->setDisplayString( g->displayString(), true);	d("b-->c connected --> end actual connect");	return a;}//kind = 'O' || 'I'void Physic::setUpConn(char kind,int& a,int& b){	char s[20],t[20];	cModule* parent = parentModule();	//a is the gate on the physic module,	//b is on the compound module	d("setUpConn");	//define the gate's name	if(kind == 'I')		strcpy(t,"Rx%d\0");	else		strcpy(t,"Tx%d\0");	//create the gates to this module and its parent	gatesNum++;	sprintf(s,t,gatesNum);	a = addNewGate(this,s,kind);	b = addNewGate(parent,s,kind);	d("added gate 'b' :"<<s);	if( (a == -1)||(b == -1))	{		d("Error in the addGateVector function ");		wait(2);	}	//connect the gates	if(kind == 'O')	{	    this->gate(a)->connectTo(parent->gate(b));	    //connect((cModule*)this,a,(cLinkType *)NULL,(cModule*)parent,b);	    d("ph->comp conneected!");	}	else	{	   //connect((cModule*)parent,b,(cLinkType *)NULL,(cModule*)this,a);	   parent->gate(b)->connectTo(this->gate(a));	   d("comp->ph connected!");	}}int Physic::addNewGate(cModule *mod, char* gname, char type){	cGate* g;	int index = 0,	    gateNum = 0;	bool found = false;	int i = 0;	d("gates number before connection:"<<mod->gates());	//look for a free entry	while((i< mod->gatev.items()) && (!found))	{		g = (cGate*) mod->gate(i);		d("gate: "<<i);		if(g == NULL)		{			d("found a null gate vector place. Use it !");			g = new cGate(gname,type);			mod->gatev.addAt(i,g);			g->setOwnerModule( mod, i);			index = i;			found = true;		}		else		if(!g->isConnected())		{			d("found a not connected gate. recycling :"<<g->name());			delete g;			g = new cGate(gname,type);			mod->gatev.addAt(i,g);			g->setOwnerModule( mod, i);			found = true;			index = i;		}		else			i++;	}	//all the entries are used, add a new gate	if(!found)	{		d("free place not found, adding a new one ");		mod->addGate(gname,type);		gateNum = mod->gates();		if(mod->hasGate(gname))		{			d("has gate ok !");			index = mod->findGate(gname);		}		else		{			d("--- ERROR new gate not found!");		}	}	//mod->setGateSize(gname,mod->gates());	g = (cGate*) mod->gate(index);	//g->setIndex(index,gateNum);	//g->setIndex(index,mod->gates());	g->setOwnerModule(mod,index);	//cGate* newGate = new cGate(gname, type);	return index;}bool Physic::disconnectFrom(int rPhysic, int rMob){	int parent =(int) parentModule()->id();	int me = id();	d("-----diconnect------");	//disconect the link between the two nodes	putDownConn(me,parent,rMob,rPhysic);	d("Diconnection successfull!");	return true;}//           Left -------> arrow -------> Rightbool Physic::putDownConn(int lph,int leftId, int rightId,int rph){	cModule *left = (cModule*)simulation.module(leftId);	cModule *right = (cModule*)simulation.module(rightId);	cModule *lPhysic = (cModule*)simulation.module(lph);	cModule *rPhysic = (cModule*)simulation.module(rph);	//a->b-->c->d	int a =-1,	    b =-1,	    c =-1,	    d =-1;	cGate *g;	d("put down Connection between:"<<left->name()<<","<<left->id()<<" - "<<right->name()<<","<<right->id());	//look for the connection gate to delete	if(!getGateIndex(left,right,a,b,c,d)  )	{		d("PutDown: gateindex retured false! ******************************");		return false;	}	d("deleting  gates a:"<<a<<" b:"<<b<<" c"<<c<<" d"<<d);	//tryal....//	left->setDisplayString(left->displayString(),true);//	right->setDisplayString(right->displayString(),true);//	lPhysic->setDisplayString(lPhysic->displayString(),true);//	rPhysic->setDisplayString(rPhysic->displayString(),true);	g = (cGate*)lPhysic->gate(a);	g->setTo(NULL);	lPhysic->gatev.remove(a);	delete g;	//get rid of the old gate	g = (cGate*)left->gatev.get(b);	g->setTo(NULL);	g->setFrom(NULL);	left->gatev.remove(b);	d(g->name());	delete g;	g = (cGate*)right->gatev.get(c);	right->gatev.remove(c);	g->setTo(NULL);	g->setFrom(NULL);	d(g->name());	delete g;	g = (cGate*)rPhysic->gatev.get(d);	rPhysic->gatev.remove(d);	g->setFrom(NULL);	d(g->name());	delete g;	// this was suggested by Varga to avoid the errors that come out using TkEnv	// but it doesn't seem to work...	//left->setDisplayString(left->displayString());	return true;}bool Physic::getGateIndex(cModule* left,cModule *right,int& a,int&b, int& c, int& d){	int gateNum = left->gates();	cGate *g,*farGate;	bool found = false;	int i = 0;	d("In GetGateIndex from "<<left->name()<<" to "<<right->name());	while( (i< left->gatev.items()) &&( !found ))	{		d(i);		g = (cGate *)left->gatev.get(i);		if ((g != NULL) &&(g->type()== 'O') && (g->isConnected()))		{			d("maybe.... "<<g->name());			if(g->toGate()->ownerModule()->id() == right->id())			{				//it's the right gate				farGate = (cGate*) g->toGate();				d("gates to disconnect found");				a = g->fromGate()->id();				b = i;				c = g->toGate()->id();				d = farGate->toGate()->id();				found = true;			}		}		i++;	}	return found;}void Physic::finish(){	d("Physic  says bye");	 FILE* fout = fopen("collectedData.dat","a");	 d("Messages with errors..."<<msgWithErr);	 fprintf(fout,"Messages with errors........ %d\n",msgWithErr);	 fclose(fout);}/* modify the function to check if reachable , in which band 
   i_band 0..0.5 Range  or o_band 0.5--1
 */bool Physic::isReachable(int from, int to, int& band){	Physic *s = (Physic*) simulation.module(from);	Physic *d = (Physic*) simulation.module(to);	int x,y;	double dist,a;	bool r;	d->getPos(x,y);	//Pitagora @ work...	dist = sqrt( (double) ((x - s->posX ) * (x - s->posX )) +		    ((y - s->posY ) * (y - s->posY )) );	a = sqrt( (double) ((d->posX - s->posX ) * (d->posX - s->posX )) +		   ((d->posY - s->posY ) * (d->posY - s->posY )) );

	r = ( dist <= range);

	if(r) 
	{
		if (dist <= range/2)  band=I_BAND;
		else band=O_BAND;
	}	return r;}void Physic::getVect(int i, int& ph, int& mh){	cNeighbour * n = NULL;	n = (cNeighbour*)hosts[i];	ph = n->ph;	mh = n->mobHost;}void Physic::setPos(int x, int y){	posX = x;	posY = y;}void Physic::getPos(int &x, int &y){	//x = posX;	//y = posY;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -