AcceleratedMobileNode.cc

00001 // Copyright 2008 Michael Marsh, University of Maryland.
00002 //
00003 // This file is part of pydtn.
00004 //
00005 // pydtn is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // pydtn is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with pydtn.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // The views and conclusions contained in the software and documentation
00019 // are those of the authors and should not be interpreted as representing
00020 // official policies, either expressed or implied, of the University
00021 // of Maryland.
00022 //
00023 // pydtn extends and embeds the Python interpreter, which is
00024 // Copyright 2001-2006 Python Software Foundation, All Rights Reserved,
00025 // and is released under the PSF License Agreement.
00026 //
00027 // RANLUX random number generation uses the Boost library,
00028 // Copyright 1994-2006 by various authors (details in individual files),
00029 // which is released under the Boost Software License, Version 1.0.
00030 
00031 #include "AcceleratedMobileNode.h"
00032 
00033 using namespace AccelNode;
00034 
00035 const std::string AcceleratedMobileNode::kIdentifier( "node:mobile:accel" );
00036 
00037 AcceleratedMobileNode::AcceleratedMobileNode() :
00038    Mobility::MobileNode()
00039 {
00040 }
00041 
00042 AcceleratedMobileNode::~AcceleratedMobileNode()
00043 {
00044 }
00045 
00046 Entity*
00047 AcceleratedMobileNode::create() const
00048 {
00049    AcceleratedMobileNode* n = new AcceleratedMobileNode;
00050    n->trigger();
00051    return n;
00052 }
00053 
00054 Mobility::Position
00055 AcceleratedMobileNode::position( const Time& t ) const
00056 {
00057    // We need at least one actual point for this to be meaningful.
00058    if ( 0 == m_waypoints.size() ) return Mobility::Position();
00059 
00060    Mobility::Presence key( t, Mobility::Position(), Time() );
00061    PresenceSet::const_iterator after = m_waypoints.lower_bound(key);
00062    PresenceSet::const_iterator before = after;
00063    --before;
00064 
00065    // The specified time is after the last movement completed.
00066    if ( m_waypoints.end() == after )
00067    {
00068       return before->position();
00069    }
00070 
00071    // We're exactly at a waypoint.
00072    if ( *after == t )
00073    {
00074       return after->position();
00075    }
00076    // Or we're paused at a waypoint.
00077    if ( ( t - before->time() ) < before->duration() )
00078    {
00079       return before->position();
00080    }
00081 
00082    // We're before the first waypoint (which shouldn't generally happen).
00083    if ( m_waypoints.begin() == after )
00084    {
00085       return Mobility::Position();
00086    }
00087 
00088    // The normal case.  We need to interpolate the position.
00089    Time t0 = before->time() + before->duration();
00090    Time totalT = after->time() - t0;
00091    Time currT = t - t0;
00092    // This is the fraction of the allocated time to which we're interpolating
00093    double r = ( 1.0*currT.tv.tv_sec*Time::MILLION + currT.tv.tv_usec ) /
00094       ( 1.0*totalT.tv.tv_sec*Time::MILLION + totalT.tv.tv_usec );
00095    // The halfway point is where we switch from positive to negative
00096    // acceleration
00097    double a = ( r < 0.5 ) ? (2*r*r) : (-1 + 4*r - 2*r*r);
00098    return before->position() * ( 1.0 - a ) + after->position() * a;
00099 }

Generated on Mon Mar 24 11:15:45 2008 for Pydtn Simulator by  doxygen 1.5.4