MoBANLocal.cc

00001 /* -*- mode:c++ -*- ********************************************************
00002  * file:        MoBANLocal.cc
00003  *
00004  * author:      Majid Nabi <m.nabi@tue.nl>
00005  *
00006  *
00007  *              http://www.es.ele.tue.nl/nes
00008  *
00009  * copyright:   (C) 2010 Electronic Systems group(ES),
00010  *              Eindhoven University of Technology (TU/e), the Netherlands.
00011  *
00012  *
00013  *              This program is free software; you can redistribute it
00014  *              and/or modify it under the terms of the GNU General Public
00015  *              License as published by the Free Software Foundation; either
00016  *              version 2 of the License, or (at your option) any later
00017  *              version.
00018  *              For further information see file COPYING
00019  *              in the top level directory
00020  ***************************************************************************
00021  * part of:    MoBAN (Mobility Model for wireless Body Area Networks)
00022  * description:     Implementation of the local module of the MoBAN mobility model
00023  ***************************************************************************
00024  * Citation of the following publication is appreciated if you use MoBAN for
00025  * a publication of your own.
00026  *
00027  * M. Nabi, M. Geilen, T. Basten. MoBAN: A Configurable Mobility Model for Wireless Body Area Networks.
00028  * In Proc. of the 4th Int'l Conf. on Simulation Tools and Techniques, SIMUTools 2011, Barcelona, Spain, 2011.
00029  *
00030  * BibTeX:
00031  *    @inproceedings{MoBAN,
00032  *    author = "M. Nabi and M. Geilen and T. Basten.",
00033  *    title = "{MoBAN}: A Configurable Mobility Model for Wireless Body Area Networks.",
00034  *      booktitle = "Proceedings of the 4th Int'l Conf. on Simulation Tools and Techniques.",
00035  *      series = {SIMUTools '11},
00036  *      isbn = {978-963-9799-41-7},
00037  *      year = {2011},
00038  *      location = {Barcelona, Spain},
00039  *      publisher = {ICST} }
00040  *
00041  **************************************************************************/
00042 
00043 
00044 #include <FWMath.h>
00045 #include "MoBANLocal.h"
00046 
00047 Define_Module(MoBANLocal);
00048 
00049 void MoBANLocal::initialize(int stage)
00050 {
00051     BaseMobility::initialize(stage);
00052 
00053     if (stage == 0) {
00054 
00055     speed = 1;
00056       move.setSpeed(speed);//It should be done in the first stage for sure. If it is not set, then no move message will be initiated. Any value is okay, but Zero!
00057       numSteps = 0;
00058         step = -1;
00059         stepSize = Coord(0,0,0);
00060 
00061         BBMoBANMessage groupMove;        // subscribe to blackboard to receive items published by the MoBAN coordinator
00062         catRefMove = utility->subscribe(this, &groupMove, findHost()->getId());
00063     }
00064     else if( stage == 1 ){
00065       referencePoint = move.getStartPos();
00066     }
00067 }
00068 
00073 void MoBANLocal::setTargetPosition()
00074 {
00075   Coord currentRelativePosition;
00076 
00077   if (speed != 0)
00078   {
00079     // Find a uniformly random position within a sphere around the reference point
00080     double x  = uniform(-1*radius, radius);
00081     double y  = uniform(-1*radius, radius);
00082     double z =  uniform(-1*radius, radius);
00083     while (x*x+y*y+z*z > radius*radius)
00084     {
00085       x  = uniform(-1*radius, radius);
00086       y  = uniform(-1*radius, radius);
00087       z =  uniform(-1*radius, radius);
00088     }
00089 
00090     targetPos.setX(x);
00091     targetPos.setY(y);
00092     targetPos.setZ(z);
00093 
00094     currentRelativePosition = move.getStartPos()- referencePoint;
00095     double distance = currentRelativePosition.distance(targetPos);
00096 
00097     simtime_t totalTime = distance / move.getSpeed();
00098     if (totalTime >= updateInterval)
00099       numSteps = FWMath::round(totalTime / updateInterval);
00100     else
00101       numSteps = 1; //The selected target position is quite close so that in less than one step, it will be reached with the given velocity.
00102 
00103     stepSize = (targetPos - currentRelativePosition)/numSteps;
00104     stepTarget = (move.getStartPos()-referencePoint) + stepSize;
00105   }
00106   else
00107   {
00108     numSteps = 1;
00109     targetPos = referencePoint;
00110     stepSize = Coord(0,0,0);
00111     stepTarget = Coord(0,0,0);
00112   }
00113 
00114 
00115   move.setStart(insideWorld(stepTarget + referencePoint),simTime());
00116 
00117     step = 0;
00118 
00119   EV << "new targetPos: " << targetPos.info() << " numSteps=" << numSteps << endl;
00120 
00121 }
00122 
00128 void MoBANLocal::makeMove()
00129 {
00130     // increment number of steps
00131     step++;
00132 
00133     if( step == numSteps ){
00134       EV << "destination reached. " << move.info() << endl;
00135       setTargetPosition();
00136   }
00137     else if( step < numSteps ){
00138       // step forward
00139       stepTarget += stepSize;
00140       move.setStart(insideWorld(stepTarget+referencePoint),simTime());
00141     }
00142     else{
00143       error("step cannot be bigger than numSteps");
00144     }
00145 
00146 }
00147 
00152 void MoBANLocal::receiveBBItem(int category, const BBItem *details, int scopeModuleId)
00153 {
00154     if(category == catRefMove)
00155     {
00156       BBMoBANMessage m(*static_cast<const BBMoBANMessage*>(details));
00157       referencePoint= m.position;
00158 
00159       speed = m.speed;
00160       if ( !FWMath::close(speed,0.0) )
00161          move.setSpeed(speed); // IF WE SET ZERO, it is not going to move anymore
00162 
00163         radius = m.radius;
00164 
00165       move.setStart(insideWorld(stepTarget+referencePoint),simTime());
00166 
00167         EV<<"Node "<< getParentModule()->getIndex() <<" received new reference point."<<endl;
00168         EV<< "New speed:" << speed <<" , new radius: "<< radius <<endl;
00169 
00170     }
00171 }
00172 
00176 Coord MoBANLocal::insideWorld(Coord apoint)
00177 {
00178   double xmax, ymax, zmax;
00179 
00180   Coord NearestBorder = apoint;
00181 
00182   xmax = world->getPgs()->getX();
00183   ymax = world->getPgs()->getY();
00184   zmax = world->getPgs()->getZ();
00185 
00186   if (NearestBorder.getX() < 0)
00187     NearestBorder.setX(0.0);
00188 
00189   if (NearestBorder.getY() < 0)
00190     NearestBorder.setY(0.0);
00191 
00192   if (NearestBorder.getZ() < 0)
00193     NearestBorder.setZ(0.0);
00194 
00195   if (NearestBorder.getX() > xmax)
00196     NearestBorder.setX(xmax);
00197 
00198   if (NearestBorder.getY() > ymax)
00199     NearestBorder.setY(ymax);
00200 
00201   if (NearestBorder.getZ() > zmax)
00202     NearestBorder.setZ(zmax);
00203 
00204   return NearestBorder;
00205 
00206 }
00207