LineSegmentsMobilityBase.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 "LineSegmentsMobilityBase.h"
00020 
00021 #include <FWMath.h>
00022 
00023 void LineSegmentsMobilityBase::initialize(int stage) {
00024   BaseMobility::initialize(stage);
00025 
00026   if(stage == 1) {
00027     if(!world->use2D()) {
00028       opp_warning("This mobility module does not yet support 3-dimensional movement."\
00029             "Movements will probably be incorrect.");
00030     }
00031   }
00032 }
00033 
00034 void LineSegmentsMobilityBase::beginNextMove(cMessage *msg)
00035 {
00036   debugEV << "beginNextMove, startPos: " << move.getStartPos().info() << " stepTarget: " << stepTarget.info() << " targetPos: "
00037        << targetPos.info() << endl << "simTime: " << simTime() << " targetTime: " << targetTime << endl;;
00038 
00039     // go to exact position where previous statement was supposed to finish
00040     move.setStart(targetPos, simTime());
00041     stepTarget = targetPos;
00042     simtime_t now = targetTime;
00043 
00044     // choose new targetTime and targetPos
00045     setTargetPosition();
00046 
00047 
00048     debugEV << "startPos: " << move.getStartPos().info() << " targetPos: " << targetPos.info() << endl;
00049 
00050     if (targetTime<now)
00051         error("LineSegmentsMobilityBase: targetTime<now was set in %s's beginNextMove()", getClassName());
00052 
00053     if( move.getSpeed() <= 0 ){
00054         // end of movement
00055         stepSize.setX(0);
00056         stepSize.setY(0);
00057         debugEV << "speed < 0; stop moving!\n";
00058         delete msg;
00059     }
00060     else if (targetPos==move.getStartPos()){
00061         // no movement, just wait
00062       debugEV << "warning, we are not moving!\n";
00063         stepSize.setX(0);
00064         stepSize.setY(0);
00065         scheduleAt(std::max(targetTime,simTime()), msg);
00066     }
00067     else{
00068         // keep moving
00069         double numIntervals = (targetTime-now) / updateInterval;
00070         // int numSteps = floor(numIntervals); -- currently unused,
00071         // although we could use step counting instead of comparing
00072         // simTime() to targetTime each step.
00073 
00074         // Note: step = speed*updateInterval = distance/time*updateInterval =
00075         //        = (targetPos-pos) / (targetTime-now) * updateInterval =
00076         //        = (targetPos-pos) / numIntervals
00077         stepSize = (targetPos - move.getStartPos());
00078 
00079   move.setDirectionByTarget( targetPos );
00080 
00081   stepSize = stepSize / numIntervals;
00082   stepTarget += stepSize;
00083 
00084   move.setSpeed(move.getStartPos().distance( targetPos ) / (targetTime - now ));
00085 
00086   debugEV << "numIntervals: " << numIntervals << " now: " << now << " simTime " << simTime() << " stepTarget: "
00087      << stepTarget.info() << " speed: " << move.getSpeed() << endl;
00088 
00089         scheduleAt(simTime() + updateInterval, msg);
00090     }
00091 }
00092 
00093 void LineSegmentsMobilityBase::handleSelfMsg(cMessage *msg)
00094 {
00095     if( move.getSpeed() <= 0 ){
00096         delete msg;
00097         return;
00098     }
00099     else if (simTime()+updateInterval >= targetTime){
00100         beginNextMove(msg);
00101     }
00102     else{
00103       debugEV << "make next step\n";
00104 
00105         scheduleAt(simTime() + updateInterval, msg);
00106 
00107     // update position
00108     move.setStart(stepTarget, simTime());
00109     stepTarget += stepSize;
00110     }
00111 
00112     // do something if we reach the wall
00113     fixIfHostGetsOutside();
00114 
00115     updatePosition();
00116 }
00117 
00118