00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "simlpy/interpreter_defs.h"
00032 #include "simlpy/interpreter_hooks.h"
00033
00034 #include "RandomWaypointNode.h"
00035 #include "WaypointRange.h"
00036 #include "RectangularAlignedWaypointRange.h"
00037 #include "ParallelogramWaypointRange.h"
00038 #include "simlpy/Clock.h"
00039 #include "simlpy/SimulationException.h"
00040
00041 #include <iostream>
00042 #include <stdlib.h>
00043
00044 using namespace Mobility;
00045
00046 const std::string
00047 RandomWaypointNode::kIdentifier( "node:mobile:random_waypoint" );
00048
00049 RandomWaypointNode::RandomWaypointNode() :
00050 m_range( 0 ),
00051 m_speedMin( 0.001 ),
00052 m_speedMax( 299792458.0 )
00053 {
00054 }
00055
00056 RandomWaypointNode::~RandomWaypointNode()
00057 {
00058 if ( 0 != m_range ) delete m_range;
00059 }
00060
00061 Entity*
00062 RandomWaypointNode::create() const
00063 {
00064 RandomWaypointNode* n = new RandomWaypointNode;
00065 n->trigger();
00066 return n;
00067 }
00068
00069 void
00070 RandomWaypointNode::configure( const ArgList& args )
00071 {
00072 unsigned int nargs = args.size();
00073 if ( 0 == nargs )
00074 {
00075 std::cerr << "no arguments passed to config()" << std::endl;
00076 throw SimulationException( __FILE__ , __LINE__ );
00077 }
00078 std::string command = parse_string(args[0]);
00079 if ( "range" == command )
00080 {
00081
00082 if ( nargs < 3 )
00083 {
00084 std::cerr << "config('range') requires at least two arguments"
00085 << std::endl;
00086 throw SimulationException( __FILE__ , __LINE__ );
00087 }
00088 if ( 3 == nargs )
00089 {
00090
00091 try
00092 {
00093 Position ll = parse_position( args[1] );
00094 Position ur = parse_position( args[2] );
00095 if ( 0 != m_range ) delete m_range;
00096 m_range = new RectangularAlignedWaypointRange( ll, ur );
00097 return;
00098 }
00099 catch ( ... )
00100 {
00101 }
00102 }
00103 if ( 4 == nargs )
00104 {
00105
00106 try
00107 {
00108 Position a = parse_position( args[1] );
00109 Position b = parse_position( args[2] );
00110 Position c = parse_position( args[3] );
00111 if ( 0 != m_range ) delete m_range;
00112 m_range = new ParallelogramWaypointRange( a, b, c, a );
00113 return;
00114 }
00115 catch ( ... )
00116 {
00117 }
00118 }
00119 if ( 5 == nargs )
00120 {
00121
00122 try
00123 {
00124 Position a = parse_position( args[1] );
00125 Position b = parse_position( args[2] );
00126 Position c = parse_position( args[3] );
00127 Position d = parse_position( args[4] );
00128 if ( 0 != m_range ) delete m_range;
00129 m_range = new ParallelogramWaypointRange( a, b, c, d );
00130 return;
00131 }
00132 catch ( ... )
00133 {
00134 }
00135 }
00136 std::cerr << "Could not understand argument list" << std::endl;
00137 throw SimulationException( __FILE__ , __LINE__ );
00138 }
00139 if ( "speed" == command )
00140 {
00141 if ( nargs < 2 )
00142 {
00143 std::cerr << "config('speed') requires at least one speed"
00144 << std::endl;
00145 throw SimulationException( __FILE__ , __LINE__ );
00146 }
00147 double minSpeed = parse_double( args[1] );
00148 double maxSpeed = minSpeed;
00149 if ( nargs > 2 )
00150 {
00151 maxSpeed = parse_double( args[2] );
00152 }
00153 setSpeed( minSpeed, maxSpeed );
00154 return;
00155 }
00156 MobileNode::configure(args);
00157 }
00158
00159 void
00160 RandomWaypointNode::emit( const ArgList& args )
00161 {
00162 MobileNode::emit(args);
00163 }
00164
00165 InterpreterItem
00166 RandomWaypointNode::get( const ArgList& args )
00167 {
00168 unsigned int nargs = args.size();
00169 if ( 0 == nargs )
00170 {
00171 std::cerr << "No attribute specified" << std::endl;
00172 throw SimulationException( __FILE__ , __LINE__ );
00173 }
00174
00175 std::string attr = parse_string(args[0]);
00176
00177 if ( "speed_range" == attr )
00178 {
00179 ArgList alist;
00180 alist.push_back( construct_double( m_speedMin ) );
00181 alist.push_back( construct_double( m_speedMax ) );
00182 return construct_list( alist );
00183 }
00184
00185 return MobileNode::get(args);
00186 }
00187
00188 bool
00189 RandomWaypointNode::handler( WaypointEvent& event )
00190 {
00191 setWaypoint( event.waypoint() );
00192 return true;
00193 }
00194
00195 void
00196 RandomWaypointNode::setWaypoint( const Presence& wp )
00197 {
00198 if ( 0 != m_range )
00199 {
00200 Position p = m_range->next( wp.position() );
00201 Position delta = p - wp.position();
00202 double dist = delta.length();
00203 double speed = m_speedMin +
00204 ( m_speedMax - m_speedMin ) * prng();
00205 double dt = dist / speed;
00206 long int dts = (long int) ::floor(dt);
00207 long int dtus = (long int)( Time::MILLION * ( dt - ::floor(dt) ) );
00208 Time t( dts, dtus );
00209 t += wp.time();
00210 t += wp.duration();
00211 Clock::tentative( new WaypointEvent(this,
00212 this,
00213 wp.time(),
00214 Presence(t,p,Time())) );
00215 }
00216 MobileNode::setWaypoint(wp);
00217 }
00218
00219 void
00220 RandomWaypointNode::setRange( WaypointRange* r )
00221 {
00222 if ( 0 != r )
00223 {
00224 if ( 0 != m_range ) delete m_range;
00225 m_range = r;
00226 }
00227 }
00228
00229 void
00230 RandomWaypointNode::setSpeed( double min_speed, double max_speed )
00231 {
00232 if ( max_speed < min_speed )
00233 {
00234 std::cerr
00235 << "The node maximum speed must be at least the node minimum speed."
00236 << std::endl;
00237 throw SimulationException( __FILE__ , __LINE__ );
00238 }
00239 if ( min_speed <= 0 )
00240 {
00241 std::cerr << "The node minimum speed must be greater than zero."
00242 << std::endl;
00243 }
00244 m_speedMin = min_speed;
00245 m_speedMax = max_speed;
00246 }