Base module for all mobility modules. More...
#include <BaseMobility.h>
Inherits BatteryAccess.
Inherited by CircleMobility, ConstSpeedMobility, LinearMobility, LineSegmentsMobilityBase, MassMobility, MoBANLocal, RectangleMobility, and TractorMobility.
Public Types | |
enum | BorderPolicy { REFLECT, WRAP, PLACERANDOMLY, RAISEERROR } |
Selects how a node should behave if it reaches the edge of the playground. More... | |
enum | BaseMobilityMsgKinds { MOVE_HOST = 21311, MOVE_TO_BORDER, LAST_BASE_MOBILITY_KIND } |
The kind field of messages. More... | |
enum | BorderHandling { NOWHERE, X_SMALLER, X_BIGGER, Y_SMALLER, Y_BIGGER, Z_SMALLER, Z_BIGGER } |
Specifies which border actually has been reached. More... | |
Public Member Functions | |
void | handleMessage (cMessage *msg) |
This modules should only receive self-messages. | |
virtual void | initialize (int) |
Initializes mobility model parameters. | |
virtual void | finish () |
Delete dynamically allocated objects. | |
Protected Member Functions | |
virtual int | iconSizeTagToSize (const char *tag) |
Maps the passed icon size tag (is) to an actual size in pixels. | |
virtual const char * | iconSizeToTag (double size) |
Maps the passed size in pixels to an appropriate icon size tag (is). | |
virtual void | handleSelfMsg (cMessage *) |
Called upon arrival of a self messages. | |
virtual void | handleBorderMsg (cMessage *) |
Called upon arrival of a border messages. | |
virtual void | makeMove () |
Moves the host. | |
virtual void | updatePosition () |
Update the position information for this node. | |
double | playgroundSizeX () const |
Returns the width of the playground. | |
double | playgroundSizeY () const |
Returns the height of the playground. | |
double | playgroundSizeZ () const |
Returns the height of the playground. | |
Coord | getRandomPosition () |
Random position somewhere in the playground. DEPRECATED: Use BaseWorldUtility::getRandomPosition() instead. | |
Border handling | |
bool | handleIfOutside (BorderPolicy, Coord &, Coord &, Coord &, double &) |
Main border handling function. | |
virtual void | fixIfHostGetsOutside () |
Should be redefined in subclasses. | |
BorderHandling | checkIfOutside (Coord, Coord &) |
Checks whether the host is outside the playground and returns where. | |
void | goToBorder (BorderPolicy, BorderHandling, Coord &, Coord &) |
calculate the step to reach the border | |
void | reflectCoordinate (BorderHandling border, Coord &c) |
helperfunction for reflectIfOutside() to reflect a Coordinate at a given border | |
void | reflectIfOutside (BorderHandling, Coord &, Coord &, Coord &, double &) |
Utility function to reflect the node if it goes outside the playground. | |
void | wrapIfOutside (BorderHandling, Coord &, Coord &) |
Utility function to wrap the node to the opposite edge (torus) if it goes outside the playground. | |
void | placeRandomlyIfOutside (Coord &) |
Utility function to place the node randomly if it goes outside the playground. | |
Protected Attributes | |
BaseWorldUtility * | world |
Pointer to BaseWorldUtility -- these two must know each other. | |
cModule * | hostPtr |
Pointer to host module, to speed up repeated access. | |
int | hostId |
The hosts id. | |
Move | move |
Stores the current position and move pattern of the host. | |
int | moveCategory |
Store the category of HostMove. | |
simtime_t | updateInterval |
Time interval (in seconds) to update the hosts position. | |
cMessage * | moveMsg |
Self message to trigger movement. | |
bool | coreDebug |
debug this core module? | |
bool | scaleNodeByDepth |
Enable depth dependent scaling of nodes when 3d and tkenv is used. | |
double | playgroundScaleX |
Scaling of the playground in X direction. | |
double | playgroundScaleY |
Scaling of the playground in Y direction. | |
double | origDisplayWidth |
The original width the node is displayed width. | |
double | origDisplayHeight |
The original height the node is displayed width. | |
double | origIconSize |
The original size of the icon of the node. |
Base module for all mobility modules.
It does not provide mobility at all, so you can use it if you only want to simulate static networks.
BaseMobility provides random placement of hosts and display updates. Change notifications about position changes are also posted to the Blackboard.
Another service provided by BaseMobility is border handling. If a host wants to move outside the playground, this situation has to be handled somehow. BaseMobility provides handling for the 4 most common ways for that: reflection, wrapping, random placement and raising an error. The only thing you have to do is to specify your desired border handling in fixIfHostGetsOutside and call it in makeMove.
For most mobility modules the only two functions you need to implement to define your own mobility module are makeMove and fixIfHostGetsOutside..
This file contains 3D implementations from Michael Swigulski.
Definition at line 60 of file BaseMobility.h.
The kind field of messages.
that are used internally by this class have one of these values
LAST_BASE_MOBILITY_KIND |
Stores the id on which classes extending BaseMobility should continue their own kinds. |
Definition at line 81 of file BaseMobility.h.
{ MOVE_HOST = 21311, MOVE_TO_BORDER, LAST_BASE_MOBILITY_KIND, };
Specifies which border actually has been reached.
Definition at line 92 of file BaseMobility.h.
{ NOWHERE, X_SMALLER, X_BIGGER, Y_SMALLER, Y_BIGGER, Z_SMALLER, Z_BIGGER };
Selects how a node should behave if it reaches the edge of the playground.
REFLECT |
reflect off the wall |
WRAP |
reappear at the opposite edge (torus) |
PLACERANDOMLY |
placed at a randomly chosen position on the playground |
RAISEERROR |
stop the simulation with error |
Definition at line 69 of file BaseMobility.h.
{ REFLECT, WRAP, PLACERANDOMLY, RAISEERROR };
BaseMobility::BorderHandling BaseMobility::checkIfOutside | ( | Coord | targetPos, | |
Coord & | borderStep | |||
) | [protected] |
Checks whether the host is outside the playground and returns where.
Checks whether the host moved outside and return the border it crossed.
Additionally the calculation of the step to reach the border is started.
Definition at line 419 of file BaseMobility.cc.
References Move::getDirection(), Move::getStartPos(), Coord::getX(), Coord::getY(), Coord::getZ(), Coord::info(), move, NOWHERE, playgroundSizeX(), playgroundSizeY(), playgroundSizeZ(), Coord::setX(), Coord::setY(), Coord::setZ(), BaseWorldUtility::use2D(), world, X_BIGGER, X_SMALLER, Y_BIGGER, and Y_SMALLER.
Referenced by handleIfOutside().
{ BorderHandling outside = NOWHERE; // Testing x-value if (targetPos.getX() < 0){ borderStep.setX(-move.getStartPos().getX()); outside = X_SMALLER; } else if (targetPos.getX() >= playgroundSizeX()){ borderStep.setX(playgroundSizeX() - move.getStartPos().getX()); outside = X_BIGGER; } // Testing y-value if (targetPos.getY() < 0){ borderStep.setY(-move.getStartPos().getY()); if( outside == NOWHERE || fabs(borderStep.getX()/move.getDirection().getX()) > fabs(borderStep.getY()/move.getDirection().getY()) ) { outside = Y_SMALLER; } } else if (targetPos.getY() >= playgroundSizeY()){ borderStep.setY(playgroundSizeY() - move.getStartPos().getY()); if( outside == NOWHERE || fabs(borderStep.getX()/move.getDirection().getX()) > fabs(borderStep.getY()/move.getDirection().getY()) ) { outside = Y_BIGGER; } } // Testing z-value if (!world->use2D()) { // going to reach the lower z-border if (targetPos.getZ() < 0) { borderStep.setZ(-move.getStartPos().getZ()); // no border reached so far if( outside==NOWHERE ) { outside = Z_SMALLER; } // an y-border is reached earliest so far, test whether z-border // is reached even earlier else if( (outside == Y_SMALLER || outside == Y_BIGGER) && fabs(borderStep.getY()/move.getDirection().getY()) > fabs(borderStep.getZ()/move.getDirection().getZ()) ) { outside = Z_SMALLER; } // an x-border is reached earliest so far, test whether z-border // is reached even earlier else if( (outside == X_SMALLER || outside == X_BIGGER) && fabs(borderStep.getX()/move.getDirection().getX()) > fabs(borderStep.getZ()/move.getDirection().getZ()) ) { outside = Z_SMALLER; } } // going to reach the upper z-border else if (targetPos.getZ() >= playgroundSizeZ()) { borderStep.setZ(playgroundSizeZ() - move.getStartPos().getZ()); // no border reached so far if( outside==NOWHERE ) { outside = Z_BIGGER; } // an y-border is reached earliest so far, test whether z-border // is reached even earlier else if( (outside==Y_SMALLER || outside==Y_BIGGER) && fabs(borderStep.getY()/move.getDirection().getY()) > fabs(borderStep.getZ()/move.getDirection().getZ()) ) { outside = Z_BIGGER; } // an x-border is reached earliest so far, test whether z-border // is reached even earlier else if( (outside==X_SMALLER || outside==X_BIGGER) && fabs(borderStep.getX()/move.getDirection().getX()) > fabs(borderStep.getZ()/move.getDirection().getZ()) ) { outside = Z_BIGGER; } } } coreEV << "checkIfOutside, outside="<<outside<<" borderStep: " << borderStep.info() << endl; return outside; }
virtual void BaseMobility::fixIfHostGetsOutside | ( | ) | [inline, protected, virtual] |
Should be redefined in subclasses.
Should invoke handleIfOutside() and pass the references to the parameters to be modified.
Additional action after border handling (such as choosing a new target position if the BorderPolicy is PLACERANDOMLY) should be implemented here.
Reimplemented in ANSimMobility, BonnMotionMobility, CircleMobility, LinearMobility, MassMobility, RectangleMobility, TractorMobility, and TurtleMobility.
Definition at line 298 of file BaseMobility.h.
Referenced by handleBorderMsg(), and LineSegmentsMobilityBase::handleSelfMsg().
{
error("fixIfHostGetsOutside has to be redefined by the user");
};
void BaseMobility::goToBorder | ( | BorderPolicy | policy, | |
BorderHandling | wo, | |||
Coord & | borderStep, | |||
Coord & | borderStart | |||
) | [protected] |
calculate the step to reach the border
Calculate the step to reach the border. Additionally for the WRAP policy the new start position after reaching the border is calculated.
Definition at line 525 of file BaseMobility.cc.
References Move::getDirection(), Move::getStartPos(), Coord::getX(), Coord::getY(), Coord::getZ(), Coord::info(), move, playgroundSizeX(), playgroundSizeY(), playgroundSizeZ(), Coord::setX(), Coord::setY(), Coord::setZ(), BaseWorldUtility::use2D(), world, WRAP, X_BIGGER, X_SMALLER, Y_BIGGER, Y_SMALLER, Z_BIGGER, and Z_SMALLER.
Referenced by handleIfOutside().
{ double factor; coreEV << "goToBorder: startPos: " << move.getStartPos().info() << " borderStep: " << borderStep.info() << " BorderPolicy: " << policy << " BorderHandling: " << wo << endl; switch( wo ) { case X_SMALLER: factor = borderStep.getX() / move.getDirection().getX(); borderStep.setY(factor * move.getDirection().getY()); if (!world->use2D()) { borderStep.setZ(factor * move.getDirection().getZ()); // 3D case } if( policy == WRAP ) { borderStart.setX(playgroundSizeX()); borderStart.setY(move.getStartPos().getY() + borderStep.getY()); if (!world->use2D()) { borderStart.setZ(move.getStartPos().getZ() + borderStep.getZ()); // 3D case } } break; case X_BIGGER: factor = borderStep.getX() / move.getDirection().getX(); borderStep.setY(factor * move.getDirection().getY()); if (!world->use2D()) { borderStep.setZ(factor * move.getDirection().getZ()); // 3D case } if( policy == WRAP ) { borderStart.setX(0); borderStart.setY(move.getStartPos().getY() + borderStep.getY()); if (!world->use2D()) { borderStart.setZ(move.getStartPos().getZ() + borderStep.getZ()); // 3D case } } break; case Y_SMALLER: factor = borderStep.getY() / move.getDirection().getY(); borderStep.setX(factor * move.getDirection().getX()); if (!world->use2D()) { borderStep.setZ(factor * move.getDirection().getZ()); // 3D case } if( policy == WRAP ) { borderStart.setY(playgroundSizeY()); borderStart.setX(move.getStartPos().getX() + borderStep.getX()); if (!world->use2D()) { borderStart.setZ(move.getStartPos().getZ() + borderStep.getZ()); // 3D case } } break; case Y_BIGGER: factor = borderStep.getY() / move.getDirection().getY(); borderStep.setX(factor * move.getDirection().getX()); if (!world->use2D()) { borderStep.setZ(factor * move.getDirection().getZ()); // 3D case } if( policy == WRAP ) { borderStart.setY(0); borderStart.setX(move.getStartPos().getX() + borderStep.getX()); if (!world->use2D()) { borderStart.setZ(move.getStartPos().getZ() + borderStep.getZ()); // 3D case } } break; case Z_SMALLER: // here we are definitely in 3D factor = borderStep.getZ() / move.getDirection().getZ(); borderStep.setX(factor * move.getDirection().getX()); borderStep.setY(factor * move.getDirection().getY()); if( policy == WRAP ) { borderStart.setZ(playgroundSizeZ()); borderStart.setX(move.getStartPos().getX() + borderStep.getX()); borderStart.setY(move.getStartPos().getY() + borderStep.getY()); } break; case Z_BIGGER: // here we are definitely in 3D factor = borderStep.getZ() / move.getDirection().getZ(); borderStep.setX(factor * move.getDirection().getX()); borderStep.setY(factor * move.getDirection().getY()); if( policy == WRAP ) { borderStart.setZ(0); borderStart.setX(move.getStartPos().getX() + borderStep.getX()); borderStart.setY(move.getStartPos().getY() + borderStep.getY()); } break; default: factor = 0; error("invalid state in goToBorder switch!"); } coreEV << "goToBorder: startPos: " << move.getStartPos().info() << " borderStep: " << borderStep.info() << " borderStart: " << borderStart.info() << " factor: " << factor << endl; }
void BaseMobility::handleBorderMsg | ( | cMessage * | msg | ) | [protected, virtual] |
Called upon arrival of a border messages.
The host actually reached the border, so the startPos and startTime has to be updated.
Additionally fixIfHostGetsOutside has to be called again to catch cases where the host moved in both (x and y) direction outside the playground.
Definition at line 221 of file BaseMobility.cc.
References fixIfHostGetsOutside(), Move::getStartPos(), Coord::info(), Move::info(), move, PLACERANDOMLY, RAISEERROR, REFLECT, Move::setDirectionByVector(), Move::setStart(), updatePosition(), and WRAP.
Referenced by handleMessage().
{ coreEV << "start MOVE_TO_BORDER:" << move.info() << endl; BorderMsg* bMsg = static_cast<BorderMsg*>(msg); switch( bMsg->getPolicy() ){ case REFLECT: move.setStart(bMsg->getStartPos()); move.setDirectionByVector(bMsg->getDirection()); break; case WRAP: move.setStart(bMsg->getStartPos()); break; case PLACERANDOMLY: move.setStart(bMsg->getStartPos()); coreEV << "new random position: " << move.getStartPos().info() << endl; break; case RAISEERROR: error("node moved outside the playground"); break; default: error("Unknown BorderPolicy!"); } fixIfHostGetsOutside(); updatePosition(); delete bMsg; coreEV << "end MOVE_TO_BORDER:" << move.info() << endl; }
bool BaseMobility::handleIfOutside | ( | BorderPolicy | policy, | |
Coord & | stepTarget, | |||
Coord & | targetPos, | |||
Coord & | step, | |||
double & | angle | |||
) | [protected] |
Main border handling function.
This function takes the BorderPolicy and all variables to be modified in case a border is reached and invokes the appropriate action. Pass dummy variables if you do not need them.
The supported border policies are REFLECT, WRAP, PLACERANDOMLY, and RAISEERROR.
The policy and stepTarget are mandatory parameters to pass. stepTarget is used to check whether the host actually moved outside the playground.
Additional parameters to pass (in case of non atomic movements) can be targetPos (the target the host is moving to) and step (the size of a step).
Angle is the direction in which the host is moving.
policy | BorderPolicy to use | |
stepTarget | target position of the next step of the host | |
targetPos | target position of the host (for non atomic movement) | |
step | step size of the host (for non atomic movement) | |
angle | direction in which the host is moving |
Definition at line 655 of file BaseMobility.cc.
References checkIfOutside(), Coord::distance(), Move::getSpeed(), Move::getStartPos(), goToBorder(), Coord::info(), move, NOWHERE, PLACERANDOMLY, placeRandomlyIfOutside(), RAISEERROR, REFLECT, reflectIfOutside(), BaseWorldUtility::use2D(), world, WRAP, and wrapIfOutside().
Referenced by TurtleMobility::fixIfHostGetsOutside(), TractorMobility::fixIfHostGetsOutside(), RectangleMobility::fixIfHostGetsOutside(), MassMobility::fixIfHostGetsOutside(), LinearMobility::fixIfHostGetsOutside(), CircleMobility::fixIfHostGetsOutside(), BonnMotionMobility::fixIfHostGetsOutside(), and ANSimMobility::fixIfHostGetsOutside().
{ // where did the host leave the playground? BorderHandling wo; // step to reach the border Coord borderStep(world->use2D()); wo = checkIfOutside(stepTarget, borderStep); // just return if the next step is not outside the playground if( wo == NOWHERE ) return false; coreEV << "handleIfOutside:stepTarget = " << stepTarget.info() << endl; // new start position after the host reaches the border Coord borderStart(world->use2D()); // new direction the host has to move to Coord borderDirection(world->use2D()); // time to reach the border simtime_t borderInterval; coreEV << "old values: stepTarget: " << stepTarget.info() << " step: " << step.info() << " targetPos: " << targetPos.info() << " angle: " << angle << endl; // which border policy is to be followed switch (policy){ case REFLECT: reflectIfOutside( wo, stepTarget, targetPos, step, angle ); break; case WRAP: wrapIfOutside( wo, stepTarget, targetPos ); break; case PLACERANDOMLY: placeRandomlyIfOutside( targetPos ); break; case RAISEERROR: break; } coreEV << "new values: stepTarget: " << stepTarget.info() << " step: " << step.info() << " angle: " << angle << endl; // calculate the step to reach the border goToBorder(policy, wo, borderStep, borderStart); // calculate the time to reach the border borderInterval = (borderStep.length()) / move.getSpeed(); // calculate new start position // NOTE: for WRAP this is done in goToBorder switch( policy ){ case REFLECT: { borderStart = move.getStartPos() + borderStep; double d = stepTarget.distance( borderStart ); borderDirection = (stepTarget - borderStart) / d; break; } case PLACERANDOMLY: borderStart = targetPos; stepTarget = targetPos; break; case WRAP: case RAISEERROR: break; default: error("unknown BorderPolicy"); } coreEV << "border handled, borderStep: "<< borderStep.info() << "borderStart: " << borderStart.info() << " stepTarget " << stepTarget.info() << endl; // create a border self message and schedule it appropriately BorderMsg *bMsg = new BorderMsg("borderMove", MOVE_TO_BORDER); bMsg->setPolicy(policy); bMsg->setStartPos(borderStart); bMsg->setDirection(borderDirection); scheduleAt(simTime() + borderInterval, bMsg); return true; }
void BaseMobility::handleMessage | ( | cMessage * | msg | ) |
This modules should only receive self-messages.
Dispatches border messages to handleBorderMsg() and all other self-messages to handleSelfMsg()
Definition at line 192 of file BaseMobility.cc.
References handleBorderMsg(), and handleSelfMsg().
{ if (!msg->isSelfMessage()) error("mobility modules can only receive self messages"); if(msg->getKind() == MOVE_TO_BORDER){ handleBorderMsg(msg); } else { handleSelfMsg(msg); } }
void BaseMobility::handleSelfMsg | ( | cMessage * | msg | ) | [protected, virtual] |
Called upon arrival of a self messages.
The only self message possible is to indicate a new movement. If the host is stationary this function is never called.
every time a self message arrives makeMove is called to handle the movement. Afterward updatePosition updates the position with the blackboard and the display.
Reimplemented in LineSegmentsMobilityBase, and MassMobility.
Definition at line 206 of file BaseMobility.cc.
References Move::getSpeed(), makeMove(), move, moveMsg, updateInterval, and updatePosition().
Referenced by handleMessage().
{ makeMove(); updatePosition(); if( !moveMsg->isScheduled() && move.getSpeed() > 0) { scheduleAt(simTime() + updateInterval, msg); } else { delete msg; moveMsg = NULL; } }
int BaseMobility::iconSizeTagToSize | ( | const char * | tag | ) | [protected, virtual] |
Maps the passed icon size tag (is) to an actual size in pixels.
tag | - the icon size tag to get the pixel size for |
Definition at line 158 of file BaseMobility.cc.
Referenced by initialize().
{ if(strcmp(tag, "vs") == 0) { return 16; } else if(strcmp(tag, "s") == 0) { return 24; } else if(strcmp(tag, "n") == 0 || strcmp(tag, "") == 0) { return 40; } else if(strcmp(tag, "l") == 0) { return 60; } else if(strcmp(tag, "vl") == 0) { return 100; } return -1; }
const char * BaseMobility::iconSizeToTag | ( | double | size | ) | [protected, virtual] |
Maps the passed size in pixels to an appropriate icon size tag (is).
size | - the icon size to get an appropriate tag for |
Definition at line 175 of file BaseMobility.cc.
Referenced by updatePosition().
{ //returns the biggest icon smaller than the passed size (except sizes //smaller than the smallest icon if(size < 24) { return "vs"; } else if(size < 40) { return "s"; } else if(size < 60) { return "n"; } else if(size < 100) { return "l"; } else { return "vl"; } }
void BaseMobility::initialize | ( | int | stage | ) | [virtual] |
Initializes mobility model parameters.
Assigns a pointer to ConnectionManager and gets a pointer to its host.
Creates a random position for a host if the position is not given as a parameter in "omnetpp.ini".
Additionally the registration with ConnectionManager is done and it is assured that the position display string tag (p) exists and contains the exact (x) tag.
If the speed of the host is bigger than 0 a first MOVE_HOST self message is scheduled in stage 1
Reimplemented from BaseModule.
Reimplemented in ANSimMobility, BonnMotionMobility, CircleMobility, ConstSpeedMobility, LinearMobility, LineSegmentsMobilityBase, MassMobility, MoBANLocal, RectangleMobility, TractorMobility, and TurtleMobility.
Definition at line 38 of file BaseMobility.cc.
References coreDebug, BaseModule::findHost(), Blackboard::getCategory(), BaseWorldUtility::getPgs(), BaseWorldUtility::getRandomPosition(), Move::getSpeed(), Move::getStartPos(), hostId, hostPtr, iconSizeTagToSize(), Coord::info(), Coord::isInRectangle(), move, moveCategory, moveMsg, origDisplayHeight, origDisplayWidth, origIconSize, playgroundScaleX, playgroundScaleY, playgroundSizeX(), playgroundSizeY(), scaleNodeByDepth, Move::setDirectionByVector(), Move::setSpeed(), Move::setStart(), Coord::setX(), Coord::setY(), Coord::setZ(), updateInterval, updatePosition(), BaseWorldUtility::use2D(), BaseModule::utility, and world.
{ BaseModule::initialize(stage); if (stage == 0){ hasPar("coreDebug") ? coreDebug = par("coreDebug").boolValue() : coreDebug = false; coreEV << "initializing BaseMobility stage " << stage << endl; hasPar("scaleNodeByDepth") ? scaleNodeByDepth = par("scaleNodeByDepth").boolValue() : scaleNodeByDepth = true; // get utility pointers (world and host) world = FindModule<BaseWorldUtility*>::findGlobalModule(); if (world == NULL) error("Could not find BaseWorldUtility module"); coreEV << "initializing BaseUtility stage " << stage << endl; // for node position //get a pointer to the host hostPtr = findHost(); hostId = hostPtr->getId(); if (hasPar("updateInterval")) { updateInterval = par("updateInterval"); } else { updateInterval = 0; } // initialize Move parameter bool use2D = world->use2D(); //initalize position with random values Coord pos = world->getRandomPosition(); //read coordinates from parameters if available double x = hasPar("x") ? par("x").doubleValue() : -1; double y = hasPar("y") ? par("y").doubleValue() : -1; double z = hasPar("z") ? par("z").doubleValue() : -1; //set position with values from parameters if available if(x > -1) pos.setX(x); if(y > -1) pos.setY(y); if(!use2D && z > -1) pos.setZ(z); // set start-position and start-time (i.e. current simulation-time) of the Move move.setStart(pos); coreEV << "start pos: " << move.getStartPos().info() << endl; //check whether position is within the playground if (!move.getStartPos().isInRectangle(Coord(use2D), world->getPgs())) { error("node position specified in omnetpp.ini exceeds playgroundsize"); } // set speed and direction of the Move move.setSpeed(0); move.setDirectionByVector(Coord(use2D)); //get BBItem category for Move moveCategory = utility->getCategory(&move); } else if (stage == 1){ coreEV << "initializing BaseMobility stage " << stage << endl; //get playground scaling if (world->getParentModule() != NULL ) { const cDisplayString& dispWorldOwner = world->getParentModule()->getDisplayString(); if( dispWorldOwner.containsTag("bgb") ) { double origPGWidth; double origPGHeight; // normally this should be equal to playground size std::istringstream(dispWorldOwner.getTagArg("bgb", 0)) >> origPGWidth; std::istringstream(dispWorldOwner.getTagArg("bgb", 1)) >> origPGHeight; //bgb of zero means size isn't set manually if(origPGWidth > 0) { playgroundScaleX = origPGWidth / playgroundSizeX(); } if(origPGHeight > 0) { playgroundScaleY = origPGHeight / playgroundSizeY(); } } } //get original display of host cDisplayString& disp = hostPtr->getDisplayString(); //get host width and height if (disp.containsTag("b")) { std::istringstream(disp.getTagArg("b", 0)) >> origDisplayWidth; std::istringstream(disp.getTagArg("b", 1)) >> origDisplayHeight; } //get hosts icon size if (disp.containsTag("i")) { // choose a appropriate icon size (only if a icon is specified) origIconSize = iconSizeTagToSize(disp.getTagArg("is", 0)); } // print new host position on the screen and update bb info updatePosition(); if (move.getSpeed() > 0 && updateInterval > 0) { coreEV << "Host is moving, speed=" << move.getSpeed() << " updateInterval=" << updateInterval << endl; moveMsg = new cMessage("move", MOVE_HOST); //host moves the first time after some random delay to avoid synchronized movements scheduleAt(simTime() + uniform(0, updateInterval), moveMsg); } } }
virtual void BaseMobility::makeMove | ( | ) | [inline, protected, virtual] |
Moves the host.
This function is called every time a MOVE_HOST self message arrives. Here you can define the movement pattern for your host.
You should call fixIfHostGetsOutside here for border handling
Reimplemented in CircleMobility, ConstSpeedMobility, LinearMobility, MassMobility, MoBANLocal, RectangleMobility, and TractorMobility.
Definition at line 221 of file BaseMobility.h.
Referenced by handleSelfMsg().
{
error("BaseMobility does not move the host");
};
void BaseMobility::placeRandomlyIfOutside | ( | Coord & | targetPos | ) | [protected] |
Utility function to place the node randomly if it goes outside the playground.
Start the host at a new random position. Here the target position is set to the new start position.
You have to define a new target postion in fixIfHostGetsOutside to keep the host moving.
Definition at line 412 of file BaseMobility.cc.
References BaseWorldUtility::getRandomPosition(), and world.
Referenced by handleIfOutside().
{ targetPos = world->getRandomPosition(); }
void BaseMobility::reflectCoordinate | ( | BorderHandling | border, | |
Coord & | c | |||
) | [protected] |
helperfunction for reflectIfOutside() to reflect a Coordinate at a given border
Helper function for BaseMobility::reflectIfOutside().
Reflects a given coordinate according to the given BorderHandling.
Definition at line 319 of file BaseMobility.cc.
References Coord::getX(), Coord::getY(), Coord::getZ(), NOWHERE, playgroundSizeX(), playgroundSizeY(), playgroundSizeZ(), Coord::setX(), Coord::setY(), Coord::setZ(), X_BIGGER, X_SMALLER, Y_BIGGER, Y_SMALLER, Z_BIGGER, and Z_SMALLER.
Referenced by reflectIfOutside().
{ switch( border ) { case X_SMALLER: c.setX(-c.getX()); break; case X_BIGGER: c.setX(2 * playgroundSizeX() - c.getX()); break; case Y_SMALLER: c.setY(-c.getY()); break; case Y_BIGGER: c.setY(2 * playgroundSizeY() - c.getY()); break; case Z_SMALLER: c.setZ(-c.getZ()); break; case Z_BIGGER: c.setZ(2 * playgroundSizeZ() - c.getZ()); break; case NOWHERE: default: error("wrong border handling case!"); } }
void BaseMobility::reflectIfOutside | ( | BorderHandling | wo, | |
Coord & | stepTarget, | |||
Coord & | targetPos, | |||
Coord & | step, | |||
double & | angle | |||
) | [protected] |
Utility function to reflect the node if it goes outside the playground.
Reflects the host from the playground border.
This function can update the target position, the step (for non atomic movements) and the angle.
wo | defines the border at which to reflect | |
stepTarget | target position of the current step of the host | |
targetPos | target position of the host (for non atomic movements) | |
step | step size and direction of the host (for non atomic movements) | |
angle | direction to which the host is moving |
Definition at line 350 of file BaseMobility.cc.
References Coord::getX(), Coord::getY(), Coord::getZ(), NOWHERE, reflectCoordinate(), Coord::setX(), Coord::setY(), Coord::setZ(), X_BIGGER, X_SMALLER, Y_BIGGER, Y_SMALLER, Z_BIGGER, and Z_SMALLER.
Referenced by handleIfOutside().
{ reflectCoordinate(wo, targetPos); reflectCoordinate(wo, stepTarget); switch( wo ) { case X_SMALLER: case X_BIGGER: step.setX(-step.getX()); angle = 180 - angle; break; case Y_SMALLER: case Y_BIGGER: step.setY(-step.getY()); angle = -angle; break; case Z_SMALLER: case Z_BIGGER: step.setZ(-step.getZ()); angle = -angle; break; case NOWHERE: default: error("wrong border handling case!"); } }
void BaseMobility::updatePosition | ( | ) | [protected, virtual] |
Update the position information for this node.
This function tells the Blackboard that the position has changed, and it also moves the host's icon to the new position on the screen.
This function has to be called every time the position of the host changes!
Definition at line 261 of file BaseMobility.cc.
References Move::getStartPos(), Coord::getX(), Coord::getY(), Coord::getZ(), hostId, hostPtr, iconSizeToTag(), Move::info(), move, moveCategory, origDisplayHeight, origDisplayWidth, origIconSize, playgroundScaleX, playgroundScaleY, playgroundSizeZ(), Blackboard::publishBBItem(), scaleNodeByDepth, BaseWorldUtility::use2D(), BaseModule::utility, and world.
Referenced by handleBorderMsg(), LineSegmentsMobilityBase::handleSelfMsg(), handleSelfMsg(), and initialize().
{ EV << "updatePosition: " << move.info() << endl; //publish the the new move utility->publishBBItem(moveCategory, &move, hostId); if(ev.isGUI()) { std::ostringstream osDisplayTag; const int iPrecis = 5; cDisplayString& disp = hostPtr->getDisplayString(); // setup output stream osDisplayTag << std::fixed; osDisplayTag.precision(iPrecis); osDisplayTag << (move.getStartPos().getX() * playgroundScaleX); disp.setTagArg("p", 0, osDisplayTag.str().data()); osDisplayTag.str(""); // reset osDisplayTag << (move.getStartPos().getY() * playgroundScaleY); disp.setTagArg("p", 1, osDisplayTag.str().data()); if(!world->use2D() && scaleNodeByDepth) { const double minScale = 0.25; const double maxScale = 1.0; //scale host dependent on their z coordinate to simulate a depth //effect //z-coordinate of zero maps to a scale of maxScale (very close) //z-coordinate of playground size z maps to size of minScale (far away) double depthScale = minScale + (maxScale - minScale) * (1.0 - move.getStartPos().getZ() / playgroundSizeZ()); if (origDisplayWidth > 0.0 && origDisplayHeight > 0.0) { osDisplayTag.str(""); // reset osDisplayTag << (origDisplayWidth * depthScale); disp.setTagArg("b", 0, osDisplayTag.str().data()); osDisplayTag.str(""); // reset osDisplayTag << (origDisplayHeight * depthScale); disp.setTagArg("b", 1, osDisplayTag.str().data()); } if (origIconSize > 0) { // choose a appropriate icon size (only if a icon is specified) disp.setTagArg("is", 0, iconSizeToTag(origIconSize * depthScale)); } } } }
void BaseMobility::wrapIfOutside | ( | BorderHandling | wo, | |
Coord & | stepTarget, | |||
Coord & | targetPos | |||
) | [protected] |
Utility function to wrap the node to the opposite edge (torus) if it goes outside the playground.
Wraps the host to the other playground size. Updates the target position.
wo | defines the border at which to reflect | |
stepTarget | target position of the current step of the host | |
targetPos | target position of the host (for non atomic movements) |
Definition at line 384 of file BaseMobility.cc.
References Coord::getX(), Coord::getY(), Coord::getZ(), FWMath::modulo(), NOWHERE, playgroundSizeX(), playgroundSizeY(), playgroundSizeZ(), Coord::setX(), Coord::setY(), Coord::setZ(), X_BIGGER, X_SMALLER, Y_BIGGER, Y_SMALLER, Z_BIGGER, and Z_SMALLER.
Referenced by handleIfOutside().
{ switch( wo ) { case X_SMALLER: case X_BIGGER: targetPos.setX(FWMath::modulo(targetPos.getX(), playgroundSizeX())); stepTarget.setX(FWMath::modulo(stepTarget.getX(), playgroundSizeX())); break; case Y_SMALLER: case Y_BIGGER: targetPos.setY(FWMath::modulo(targetPos.getY(), playgroundSizeY())); stepTarget.setY(FWMath::modulo(stepTarget.getY(), playgroundSizeY())); break; case Z_SMALLER: case Z_BIGGER: targetPos.setZ(FWMath::modulo(targetPos.getZ(), playgroundSizeZ())); stepTarget.setZ(FWMath::modulo(stepTarget.getZ(), playgroundSizeZ())); break; case NOWHERE: default: error("wrong border handling case!"); } }