ANSimMobility.cc

00001 //
00002 // Copyright (C) 2005 Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00019 #include "ANSimMobility.h"
00020 #include "FWMath.h"
00021 
00022 
00023 Define_Module(ANSimMobility);
00024 
00025 
00026 static cXMLElement *firstChildWithTag(cXMLElement *node, const char *tagname)
00027 {
00028     cXMLElement *child = node->getFirstChild();
00029     while (child && strcmp(child->getTagName(), tagname)!=0)
00030         child = child->getNextSibling();
00031     if (!child)
00032         opp_error("element <%s> has no <%s> child at %s", node->getTagName(), tagname, node->getSourceLocation());
00033     return child;
00034 }
00035 
00036 
00037 void ANSimMobility::initialize(int stage)
00038 {
00039     LineSegmentsMobilityBase::initialize(stage);
00040 
00041     debugEV << "initializing ANSimMobility stage " << stage << endl;
00042 
00043     if (stage == 0)
00044     {
00045         nodeId = par("nodeId");
00046         if (nodeId == -1)
00047             nodeId = getParentModule()->getIndex();
00048 
00049         // get script: param should point to <simulation> element
00050         cXMLElement *rootElem = par("ansimTrace");
00051         if (strcmp(rootElem->getTagName(),"simulation")!=0)
00052             error("ansimTrace: <simulation> is expected as root element not <%s> at %s",
00053                   rootElem->getTagName(), rootElem->getSourceLocation());
00054         nextPosChange = rootElem->getElementByPath("mobility/position_change");
00055         if (!nextPosChange)
00056             error("element doesn't have <mobility> child or <position_change> grandchild at %s",
00057                   rootElem->getSourceLocation());
00058 
00059         // set initial position;
00060         setTargetPosition();
00061         move.setStart(targetPos, simTime());
00062         stepTarget = move.getStartPos();
00063 
00064     targetTime = simTime();
00065 
00066     // dummy value; speed not used in ansim
00067     move.setSpeed(1);
00068     }
00069     else
00070     {
00071       if(!world->use2D()) {
00072       opp_warning("This mobility module does not yet support 3 dimensional movement."\
00073             "Movements will probably be incorrect.");
00074     }
00075     }
00076 }
00077 
00078 
00079 void ANSimMobility::setTargetPosition()
00080 {
00081     // find next <position_update> element with matching <node_id> tag (current one also OK)
00082     while (nextPosChange)
00083     {
00084         const char *nodeIdStr = firstChildWithTag(nextPosChange, "node_id")->getNodeValue();
00085         if (nodeIdStr && atoi(nodeIdStr)==nodeId)
00086             break;
00087         nextPosChange = nextPosChange->getNextSibling();
00088     }
00089 
00090     if (!nextPosChange)
00091     {
00092         move.setSpeed(0);
00093         return;
00094     }
00095 
00096     // extract data from it
00097     extractDataFrom(nextPosChange);
00098 
00099     // skip this one
00100     nextPosChange = nextPosChange->getNextSibling();
00101 }
00102 
00103 void ANSimMobility::extractDataFrom(cXMLElement *node)
00104 {
00105     // extract data from <position_update> element
00106     //const char *startTimeStr = firstChildWithTag(node, "start_time")->getNodeValue();
00107     const char *endTimeStr = firstChildWithTag(node, "end_time")->getNodeValue();
00108     cXMLElement *destElem = firstChildWithTag(node, "destination");
00109     const char *xStr = firstChildWithTag(destElem, "xpos")->getNodeValue();
00110     const char *yStr = firstChildWithTag(destElem, "ypos")->getNodeValue();
00111 
00112     if (!endTimeStr || !xStr || !yStr)
00113         error("no content in <end_time>, <destination>/<xpos> or <ypos> element at %s", node->getSourceLocation());
00114 
00115     targetTime = atof(endTimeStr);
00116     targetPos.setX(atof(xStr));
00117     targetPos.setY(atof(yStr));
00118 }
00119 
00120 void ANSimMobility::fixIfHostGetsOutside()
00121 {
00122     Coord dummy(world->use2D());
00123     double dum;
00124     handleIfOutside( RAISEERROR, stepTarget, dummy, dummy, dum );
00125 }
00126