--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/random-direction-position.cc Tue Jul 03 17:12:44 2007 +0200
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "ns3/random-variable-default-value.h"
+#include "ns3/rectangle-default-value.h"
+#include "ns3/simulator.h"
+#include <algorithm>
+#include <cmath>
+#include "random-direction-position.h"
+
+namespace ns3 {
+
+const double RandomDirectionPosition::PI = 3.1415;
+const InterfaceId RandomDirectionPosition::iid =
+ MakeInterfaceId ("RandomDirectionPosition", Position::iid);
+const ClassId RandomDirectionPosition::cid =
+ MakeClassId<RandomDirectionPosition,double,double> ("RandomDirectionPosition",
+ RandomDirectionPosition::iid);
+
+
+static RandomVariableDefaultValue
+ g_speedVariable ("RandomDirectionSpeed",
+ "A random variable to control the speed of a RandomDirection mobility model.",
+ "Uniform:1:2");
+
+static RandomVariableDefaultValue
+ g_pauseVariable ("RandomDirectionPause",
+ "A random variable to control the duration of of the pause of a RandomDiretion mobility model.",
+ "Constant:2");
+
+static RectangleDefaultValue
+ g_rectangle ("RandomDirectionArea",
+ "The bounding area for the RandomDirection model.",
+ -100, 100, -100, 100);
+
+
+RandomDirectionParameters::RandomDirectionParameters ()
+ : m_xMin (g_rectangle.GetMinX ()),
+ m_xMax (g_rectangle.GetMaxX ()),
+ m_yMin (g_rectangle.GetMinY ()),
+ m_yMax (g_rectangle.GetMaxY ()),
+ m_speedVariable (g_speedVariable.GetCopy ()),
+ m_pauseVariable (g_pauseVariable.GetCopy ())
+{}
+RandomDirectionParameters::RandomDirectionParameters (double xMin, double xMax, double yMin, double yMax)
+ : m_xMin (xMin),
+ m_xMax (xMax),
+ m_yMin (yMin),
+ m_yMax (yMax),
+ m_speedVariable (g_speedVariable.GetCopy ()),
+ m_pauseVariable (g_pauseVariable.GetCopy ())
+{}
+RandomDirectionParameters::RandomDirectionParameters (double xMin, double xMax, double yMin, double yMax,
+ const RandomVariable &speedVariable,
+ const RandomVariable &pauseVariable)
+ : m_xMin (xMin),
+ m_xMax (xMax),
+ m_yMin (yMin),
+ m_yMax (yMax),
+ m_speedVariable (speedVariable.Copy ()),
+ m_pauseVariable (pauseVariable.Copy ())
+{}
+
+RandomDirectionParameters::~RandomDirectionParameters ()
+{
+ delete m_speedVariable;
+ delete m_pauseVariable;
+ m_speedVariable = 0;
+ m_pauseVariable = 0;
+}
+
+void
+RandomDirectionParameters::SetSpeed (const RandomVariable &speedVariable)
+{
+ delete m_speedVariable;
+ m_speedVariable = speedVariable.Copy ();
+}
+void
+RandomDirectionParameters::SetPause (const RandomVariable &pauseVariable)
+{
+ delete m_pauseVariable;
+ m_pauseVariable = pauseVariable.Copy ();
+}
+void
+RandomDirectionParameters::SetBounds (double xMin, double xMax, double yMin, double yMax)
+{
+ m_xMin = xMin;
+ m_yMin = yMin;
+ m_xMax = xMax;
+ m_yMax = yMax;
+}
+
+Ptr<RandomDirectionParameters>
+RandomDirectionPosition::GetDefaultParameters (void)
+{
+ static Ptr<RandomDirectionParameters> parameters = Create<RandomDirectionParameters> ();
+ if (parameters->m_xMin != g_rectangle.GetMinX () ||
+ parameters->m_yMin != g_rectangle.GetMinY () ||
+ parameters->m_xMax != g_rectangle.GetMaxX () ||
+ parameters->m_yMax != g_rectangle.GetMaxY () ||
+ g_speedVariable.IsDirty () ||
+ g_pauseVariable.IsDirty ())
+ {
+ parameters = Create<RandomDirectionParameters> ();
+ g_speedVariable.ClearDirtyFlag ();
+ g_pauseVariable.ClearDirtyFlag ();
+ }
+ return parameters;
+}
+
+
+RandomDirectionPosition::RandomDirectionPosition ()
+ : m_parameters (GetDefaultParameters ()),
+ m_x (0.0),
+ m_y (0.0),
+ m_dx (0.0),
+ m_dy (0.0),
+ m_prevTime (Simulator::Now ()),
+ m_pauseStart (Simulator::Now ())
+{
+ SetInterfaceId (RandomDirectionPosition::iid);
+ InitializeDirectionAndSpeed ();
+}
+bool
+RandomDirectionPosition::CheckPosition (void) const
+{
+ return
+ m_x <= m_parameters->m_xMax &&
+ m_x >= m_parameters->m_xMin &&
+ m_y <= m_parameters->m_yMax &&
+ m_y >= m_parameters->m_yMin;
+}
+
+RandomDirectionPosition::RandomDirectionPosition (double x, double y)
+ : m_parameters (GetDefaultParameters ()),
+ m_x (x),
+ m_y (y),
+ m_dx (0.0),
+ m_dy (0.0),
+ m_prevTime (Simulator::Now ()),
+ m_pauseStart (Simulator::Now ())
+{
+ SetInterfaceId (RandomDirectionPosition::iid);
+ NS_ASSERT (CheckPosition ());
+ InitializeDirectionAndSpeed ();
+}
+RandomDirectionPosition::RandomDirectionPosition (Ptr<RandomDirectionParameters> parameters)
+ : m_parameters (parameters),
+ m_x (0.0),
+ m_y (0.0),
+ m_dx (0.0),
+ m_dy (0.0),
+ m_prevTime (Simulator::Now ()),
+ m_pauseStart (Simulator::Now ())
+{
+ SetInterfaceId (RandomDirectionPosition::iid);
+ InitializeDirectionAndSpeed ();
+ NS_ASSERT (CheckPosition ());
+}
+RandomDirectionPosition::RandomDirectionPosition (Ptr<RandomDirectionParameters> parameters,
+ double x, double y)
+ : m_parameters (parameters),
+ m_x (x),
+ m_y (y),
+ m_dx (0.0),
+ m_dy (0.0),
+ m_prevTime (Simulator::Now ()),
+ m_pauseStart (Simulator::Now ())
+{
+ SetInterfaceId (RandomDirectionPosition::iid);
+ InitializeDirectionAndSpeed ();
+ NS_ASSERT (CheckPosition ());
+}
+void
+RandomDirectionPosition::DoDispose (void)
+{
+ m_parameters = 0;
+ // chain up.
+ Position::DoDispose ();
+}
+enum RandomDirectionPosition::Side
+RandomDirectionPosition::CalculateIntersection (double &x, double &y)
+{
+ double xMin = m_parameters->m_xMin;
+ double xMax = m_parameters->m_xMax;
+ double yMin = m_parameters->m_yMin;
+ double yMax = m_parameters->m_yMax;
+ double xMaxY = m_y + (xMax - m_x) / m_dx * m_dy;
+ double xMinY = m_y + (xMin - m_x) / m_dx * m_dy;
+ double yMaxX = m_x + (yMax - m_y) / m_dy * m_dx;
+ double yMinX = m_x + (yMin - m_y) / m_dy * m_dx;
+ bool xMaxOk = xMaxY <= yMax && xMaxY >= yMin;
+ bool xMinOk = xMinY <= yMax && xMinY >= yMin;
+ bool yMaxOk = yMaxX <= xMax && yMaxX >= xMin;
+ bool yMinOk = yMinX <= xMax && yMinX >= xMin;
+ if (xMaxOk && m_dx >= 0)
+ {
+ x = xMax;
+ y = xMaxY;
+ return RandomDirectionPosition::RIGHT;
+ }
+ else if (xMinOk && m_dx <= 0)
+ {
+ x = xMin;
+ y = xMinY;
+ return RandomDirectionPosition::LEFT;
+ }
+ else if (yMaxOk && m_dy >= 0)
+ {
+ x = yMaxX;
+ y = yMax;
+ return RandomDirectionPosition::TOP;
+ }
+ else if (yMinOk && m_dy <= 0)
+ {
+ x = yMinX;
+ y = yMin;
+ return RandomDirectionPosition::BOTTOM;
+ }
+ else
+ {
+ NS_ASSERT (false);
+ // quiet compiler
+ return RandomDirectionPosition::RIGHT;
+ }
+}
+void
+RandomDirectionPosition::InitializeDirectionAndSpeed (void)
+{
+ double direction = UniformVariable::GetSingleValue (0, 2 * PI);
+ SetDirectionAndSpeed (direction);
+}
+void
+RandomDirectionPosition::SetDirectionAndSpeed (double direction)
+{
+ double speed = m_parameters->m_speedVariable->GetValue ();
+ m_dx = std::cos (direction) * speed;
+ m_dy = std::sin (direction) * speed;
+ double x, y;
+ m_side = CalculateIntersection (x, y);
+ double deltaX = x - m_x;
+ double deltaY = y - m_y;
+ double distance = sqrt (deltaX * deltaX + deltaY * deltaY);
+ double seconds = distance / speed;
+ double pause = m_parameters->m_pauseVariable->GetValue ();
+ m_pauseStart = Simulator::Now () + Seconds (seconds);
+ m_prevTime = Simulator::Now ();
+ m_event = Simulator::Schedule (Seconds (seconds + pause),
+ &RandomDirectionPosition::ResetDirectionAndSpeed, this);
+}
+void
+RandomDirectionPosition::ResetDirectionAndSpeed (void)
+{
+ Update ();
+ double direction = UniformVariable::GetSingleValue (0, PI);
+ switch (m_side)
+ {
+ case RandomDirectionPosition::RIGHT:
+ direction += PI / 2;
+ break;
+ case RandomDirectionPosition::LEFT:
+ direction += - PI / 2;
+ break;
+ case RandomDirectionPosition::TOP:
+ direction += PI;
+ break;
+ case RandomDirectionPosition::BOTTOM:
+ direction += 0.0;
+ break;
+ }
+ SetDirectionAndSpeed (direction);
+ NotifyCourseChange ();
+}
+void
+RandomDirectionPosition::Update (void) const
+{
+ Time end = std::min (Simulator::Now (), m_pauseStart);
+ if (m_prevTime >= end)
+ {
+ return;
+ }
+ Time deltaTime = end - m_prevTime;
+ m_prevTime = Simulator::Now ();
+ double deltaS = deltaTime.GetSeconds ();
+ NS_ASSERT (CheckPosition ());
+ m_x += m_dx * deltaS;
+ m_y += m_dy * deltaS;
+ // round to closest boundaries.
+ m_x = std::min (m_x, m_parameters->m_xMax);
+ m_x = std::max (m_x, m_parameters->m_xMin);
+ m_y = std::min (m_y, m_parameters->m_yMax);
+ m_y = std::max (m_y, m_parameters->m_yMin);
+ NS_ASSERT (CheckPosition ());
+}
+void
+RandomDirectionPosition::DoGet (double &x, double &y, double &z) const
+{
+ Update ();
+ x = m_x;
+ y = m_y;
+ z = 0;
+}
+void
+RandomDirectionPosition::DoSet (double x, double y, double z)
+{
+ bool changed = false;
+ if (m_x != x || m_y != y)
+ {
+ changed = true;
+ }
+ m_x = x;
+ m_y = y;
+ m_prevTime = Simulator::Now ();
+ m_pauseStart = Simulator::Now ();
+ Simulator::Remove (m_event);
+ InitializeDirectionAndSpeed ();
+ NotifyCourseChange ();
+}
+
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/random-direction-position.h Tue Jul 03 17:12:44 2007 +0200
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef RANDOM_DIRECTION_POSITION_H
+#define RANDOM_DIRECTION_POSITION_H
+
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+#include "ns3/nstime.h"
+#include "ns3/event-id.h"
+#include "ns3/component-manager.h"
+#include "position.h"
+
+namespace ns3 {
+
+class RandomVariable;
+
+class RandomDirectionParameters : public Object
+{
+ public:
+ RandomDirectionParameters ();
+ RandomDirectionParameters (double xMin, double xMax, double yMin, double yMax);
+ RandomDirectionParameters (double xMin, double xMax, double yMin, double yMax,
+ const RandomVariable &speedVariable,
+ const RandomVariable &pauseVariable);
+ virtual ~RandomDirectionParameters ();
+
+ void SetSpeed (const RandomVariable &speedVariable);
+ void SetPause (const RandomVariable &pauseVariable);
+ void SetBounds (double xMin, double xMax, double yMin, double yMax);
+ private:
+ friend class RandomDirectionPosition;
+ double m_xMin;
+ double m_xMax;
+ double m_yMin;
+ double m_yMax;
+ RandomVariable *m_speedVariable;
+ RandomVariable *m_pauseVariable;
+ std::string m_speedVariableValue;
+ std::string m_pauseVariableValue;
+};
+
+class RandomDirectionPosition : public Position
+{
+ public:
+ static const InterfaceId iid;
+ static const ClassId cid;
+
+ RandomDirectionPosition ();
+ RandomDirectionPosition (double x, double y);
+ RandomDirectionPosition (Ptr<RandomDirectionParameters> parameters);
+ RandomDirectionPosition (Ptr<RandomDirectionParameters> parameters,
+ double x, double y);
+ private:
+ enum Side {
+ TOP,
+ BOTTOM,
+ LEFT,
+ RIGHT
+ };
+ static Ptr<RandomDirectionParameters> GetDefaultParameters (void);
+ void ResetDirectionAndSpeed (void);
+ void SetDirectionAndSpeed (double direction);
+ void InitializeDirectionAndSpeed (void);
+ void Update (void) const;
+ bool CheckPosition (void) const;
+ enum RandomDirectionPosition::Side CalculateIntersection (double &x, double &y);
+ virtual void DoDispose (void);
+ virtual void DoGet (double &x, double &y, double &z) const;
+ virtual void DoSet (double x, double y, double z);
+
+ static const double PI;
+ Ptr<RandomDirectionParameters> m_parameters;
+ mutable double m_x;
+ mutable double m_y;
+ double m_dx;
+ double m_dy;
+ mutable Time m_prevTime;
+ Time m_pauseStart;
+ EventId m_event;
+ enum Side m_side;
+};
+
+} // namespace ns3
+
+#endif /* RANDOM_DIRECTION_POSITION_H */