00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "random-walk-2d-mobility-model.h"
00021 #include "ns3/enum.h"
00022 #include "ns3/double.h"
00023 #include "ns3/simulator.h"
00024 #include "ns3/log.h"
00025 #include <cmath>
00026
00027 NS_LOG_COMPONENT_DEFINE ("RandomWalk2d");
00028
00029 namespace ns3 {
00030
00031 NS_OBJECT_ENSURE_REGISTERED (RandomWalk2dMobilityModel);
00032
00033 TypeId
00034 RandomWalk2dMobilityModel::GetTypeId (void)
00035 {
00036 static TypeId tid = TypeId ("ns3::RandomWalk2dMobilityModel")
00037 .SetParent<MobilityModel> ()
00038 .SetGroupName ("Mobility")
00039 .AddConstructor<RandomWalk2dMobilityModel> ()
00040 .AddAttribute ("Bounds",
00041 "Bounds of the area to cruise.",
00042 RectangleValue (Rectangle (0.0, 0.0, 100.0, 100.0)),
00043 MakeRectangleAccessor (&RandomWalk2dMobilityModel::m_bounds),
00044 MakeRectangleChecker ())
00045 .AddAttribute ("Time",
00046 "Change current direction and speed after moving for this delay.",
00047 TimeValue (Seconds (1.0)),
00048 MakeTimeAccessor (&RandomWalk2dMobilityModel::m_modeTime),
00049 MakeTimeChecker ())
00050 .AddAttribute ("Distance",
00051 "Change current direction and speed after moving for this distance.",
00052 DoubleValue (1.0),
00053 MakeDoubleAccessor (&RandomWalk2dMobilityModel::m_modeDistance),
00054 MakeDoubleChecker<double> ())
00055 .AddAttribute ("Mode",
00056 "The mode indicates the condition used to "
00057 "change the current speed and direction",
00058 EnumValue (RandomWalk2dMobilityModel::MODE_DISTANCE),
00059 MakeEnumAccessor (&RandomWalk2dMobilityModel::m_mode),
00060 MakeEnumChecker (RandomWalk2dMobilityModel::MODE_DISTANCE, "Distance",
00061 RandomWalk2dMobilityModel::MODE_TIME, "Time"))
00062 .AddAttribute ("Direction",
00063 "A random variable used to pick the direction (gradients).",
00064 RandomVariableValue (UniformVariable (0.0, 6.283184)),
00065 MakeRandomVariableAccessor (&RandomWalk2dMobilityModel::m_direction),
00066 MakeRandomVariableChecker ())
00067 .AddAttribute ("Speed",
00068 "A random variable used to pick the speed (m/s).",
00069 RandomVariableValue (UniformVariable (2.0, 4.0)),
00070 MakeRandomVariableAccessor (&RandomWalk2dMobilityModel::m_speed),
00071 MakeRandomVariableChecker ());
00072 return tid;
00073 }
00074
00075 RandomWalk2dMobilityModel::RandomWalk2dMobilityModel ()
00076 {
00077 m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
00078 }
00079
00080 void
00081 RandomWalk2dMobilityModel::Start (void)
00082 {
00083 m_helper.Update ();
00084 double speed = m_speed.GetValue ();
00085 double direction = m_direction.GetValue ();
00086 Vector vector (std::cos (direction) * speed,
00087 std::sin (direction) * speed,
00088 0.0);
00089 m_helper.SetVelocity (vector);
00090 m_helper.Unpause ();
00091
00092 Time delayLeft;
00093 if (m_mode == RandomWalk2dMobilityModel::MODE_TIME)
00094 {
00095 delayLeft = m_modeTime;
00096 }
00097 else
00098 {
00099 delayLeft = Seconds (m_modeDistance / speed);
00100 }
00101 DoWalk (delayLeft);
00102 }
00103
00104 void
00105 RandomWalk2dMobilityModel::DoWalk (Time delayLeft)
00106 {
00107 Vector position = m_helper.GetCurrentPosition ();
00108 Vector speed = m_helper.GetVelocity ();
00109 Vector nextPosition = position;
00110 nextPosition.x += speed.x * delayLeft.GetSeconds ();
00111 nextPosition.y += speed.y * delayLeft.GetSeconds ();
00112 if (m_bounds.IsInside (nextPosition))
00113 {
00114 m_event = Simulator::Schedule (delayLeft, &RandomWalk2dMobilityModel::Start, this);
00115 }
00116 else
00117 {
00118 nextPosition = m_bounds.CalculateIntersection (position, speed);
00119 Time delay = Seconds ((nextPosition.x - position.x) / speed.x);
00120 m_event = Simulator::Schedule (delay, &RandomWalk2dMobilityModel::Rebound, this,
00121 delayLeft - delay);
00122 }
00123 NotifyCourseChange ();
00124 }
00125
00126 void
00127 RandomWalk2dMobilityModel::Rebound (Time delayLeft)
00128 {
00129 m_helper.UpdateWithBounds (m_bounds);
00130 Vector position = m_helper.GetCurrentPosition ();
00131 Vector speed = m_helper.GetVelocity ();
00132 switch (m_bounds.GetClosestSide (position))
00133 {
00134 case Rectangle::RIGHT:
00135 case Rectangle::LEFT:
00136 speed.x = - speed.x;
00137 break;
00138 case Rectangle::TOP:
00139 case Rectangle::BOTTOM:
00140 speed.y = - speed.y;
00141 break;
00142 }
00143 m_helper.SetVelocity (speed);
00144 m_helper.Unpause ();
00145 DoWalk (delayLeft);
00146 }
00147
00148 void
00149 RandomWalk2dMobilityModel::DoDispose (void)
00150 {
00151
00152 MobilityModel::DoDispose ();
00153 }
00154 Vector
00155 RandomWalk2dMobilityModel::DoGetPosition (void) const
00156 {
00157 m_helper.UpdateWithBounds (m_bounds);
00158 return m_helper.GetCurrentPosition ();
00159 }
00160 void
00161 RandomWalk2dMobilityModel::DoSetPosition (const Vector &position)
00162 {
00163 NS_ASSERT (m_bounds.IsInside (position));
00164 m_helper.SetPosition (position);
00165 Simulator::Remove (m_event);
00166 m_event = Simulator::ScheduleNow (&RandomWalk2dMobilityModel::Start, this);
00167 }
00168 Vector
00169 RandomWalk2dMobilityModel::DoGetVelocity (void) const
00170 {
00171 return m_helper.GetVelocity ();
00172 }
00173
00174
00175
00176 }