Submission for Review: Waypoint Mobility Model

View: New views
2 Messages — Rating Filter:   Alert me  

Submission for Review: Waypoint Mobility Model

by Phillip Sitbon :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi folks,

This is my first time submitting code to ns-3, so I'm doing my best to
go by the book but please let me know if I miss something.

The code submitted here implements a new Object type, "Waypoint", and
a new mobility model "WaypointMobilityModel". Discussion on the
feature can be found here:
http://groups.google.com/group/ns-3-users/browse_thread/thread/f78de8c92bf43e49

In a nutshell, it provides a method to add mobility as a set of (time,
position) pairs. The same functionality is achievable with a
ConstantVelocityMobilityModel by scheduling velocity changes at each
waypoint; however, the specialization here reduces mobility-related
memory usage (by 50%-ish) and provides a very small performance boost
in average use scenarios (the performance benefit is directly
proportional to the number of waypoints).

Files added:

src/mobility/waypoint.h
src/mobility/waypoint.cc
src/mobility/waypoint-mobility-model.h
src/mobility/waypoint-mobility-model.cc

Files modified:

src/mobility/wscript: added relevant file names
src/mobility/mobility.h: added new class description

I'm not sure if including changes to wscript files is proper, but it
allows this patch to compile right out of the box.

I'll write up some tests and examples after the code review is done.
Looking forward to your feedback!

Cheers,

Phillip

P.S. Applying the patch to ns-3-dev:

patch -p2 -d ./ns-3-dev/src/ < waypoint-mobility.patch

[waypoint-mobility.patch]

diff -r c7aa69502cdd src/mobility/mobility.h
--- a/src/mobility/mobility.h Wed Oct 28 18:27:43 2009 +0100
+++ b/src/mobility/mobility.h Thu Oct 29 13:20:07 2009 -0700
@@ -28,4 +28,9 @@
  *   - ns3::RandomDirection2dMobilityModel: a 2d random direction mobility
  *     model where the bounds of the mobility are are a rectangle.
  *
+ *   - ns3::WaypointMobilityModel: A model which determines paths from sets
+ *     of ns3::Waypoint objects, similar to using events to update velocity
+ *     and direction with a ns3::ConstantVelocityMobilityModel. This model
+ *     is slightly faster for this task and uses less memory.
+ *
  */
diff -r c7aa69502cdd src/mobility/waypoint-mobility-model.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint-mobility-model.cc Thu Oct 29 13:20:07 2009 -0700
@@ -0,0 +1,172 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@...>
+ */
+#include <limits>
+#include "ns3/abort.h"
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "ns3/log.h"
+#include "waypoint-mobility-model.h"
+
+NS_LOG_COMPONENT_DEFINE ("WaypointMobilityModel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (WaypointMobilityModel);
+
+
+TypeId
+WaypointMobilityModel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::WaypointMobilityModel")
+    .SetParent<MobilityModel> ()
+    .SetGroupName ("Mobility")
+    .AddConstructor<WaypointMobilityModel> ()
+    .AddAttribute ("NextWaypoint", "The next waypoint used to determine position.",
+                   TypeId::ATTR_GET,
+                   WaypointValue (),
+                   MakeWaypointAccessor (&WaypointMobilityModel::GetNextWaypoint),
+                   MakeWaypointChecker ())
+    .AddAttribute ("WaypointsLeft", "The number of waypoints remaining.",
+                   TypeId::ATTR_GET,
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&WaypointMobilityModel::WaypointsLeft),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+  return tid;
+}
+
+
+WaypointMobilityModel::WaypointMobilityModel ()
+ : m_first (true)
+{
+}
+void
+WaypointMobilityModel::DoDispose (void)
+{
+  MobilityModel::DoDispose ();
+}
+void
+WaypointMobilityModel::AddWaypoint (const Waypoint &waypoint)
+{
+  if ( m_first )
+    {
+      m_first = false;
+      m_current = m_next = waypoint;
+    }
+  else
+    {
+      NS_ABORT_MSG_IF ( !m_waypoints.empty () && (m_waypoints.back ().time >= waypoint.time),
+                        "Waypoints must be added in ascending time order");
+      m_waypoints.push_back (waypoint);
+    }
+}
+Waypoint
+WaypointMobilityModel::GetNextWaypoint (void) const
+{
+  Update ();
+  return m_next;
+}
+uint32_t
+WaypointMobilityModel::WaypointsLeft (void) const
+{
+  Update ();
+  return m_waypoints.size();
+}
+void
+WaypointMobilityModel::Update (void) const
+{
+  const Time now = Simulator::Now ();
+  bool newWaypoint = false;
+
+  if ( now <= m_current.time )
+    return;
+
+  while ( now >= m_next.time  )
+    {
+      if ( m_waypoints.empty () )
+        {
+          if ( m_current.time <= m_next.time )
+            {
+              m_current.position = m_next.position;
+              m_current.time = now;
+              m_velocity = Vector (0,0,0);
+              NotifyCourseChange ();
+            }
+          else
+            m_current.time = now;
+
+          return;
+        }
+
+      m_current = m_next;
+      m_next = m_waypoints.front ();
+      m_waypoints.pop_front ();
+      newWaypoint = true;
+
+      const double t_span = (m_next.time - m_current.time).GetSeconds();
+      m_velocity.x = (m_next.position.x - m_current.position.x) / t_span;
+      m_velocity.y = (m_next.position.y - m_current.position.y) / t_span;
+      m_velocity.z = (m_next.position.z - m_current.position.z) / t_span;
+    }
+
+
+  const double t_diff = (now - m_current.time).GetSeconds();
+  m_current.position.x += m_velocity.x * t_diff;
+  m_current.position.y += m_velocity.y * t_diff;
+  m_current.position.z += m_velocity.z * t_diff;
+  m_current.time = now;
+
+  if ( newWaypoint )
+    NotifyCourseChange ();
+
+  return;
+}
+Vector
+WaypointMobilityModel::DoGetPosition (void) const
+{
+  Update ();
+  return m_current.position;
+}
+void
+WaypointMobilityModel::DoSetPosition (const Vector &position)
+{
+  const Time now = Simulator::Now ();
+  Update ();
+  m_current.time = std::max (now, m_next.time);
+  m_current.position = position;
+  m_velocity = Vector (0,0,0);
+  NotifyCourseChange ();
+}
+void
+WaypointMobilityModel::EndMobility (void)
+{
+  m_waypoints.clear ();
+  m_current.time = Seconds (std::numeric_limits<double>::infinity ());
+  m_next.time = m_current.time;
+  m_first = true;
+}
+Vector
+WaypointMobilityModel::DoGetVelocity (void) const
+{
+  return m_velocity;
+}
+
+} // namespace ns3
+
diff -r c7aa69502cdd src/mobility/waypoint-mobility-model.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint-mobility-model.h Thu Oct 29 13:20:07 2009 -0700
@@ -0,0 +1,107 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@...>
+ */
+#ifndef WAYPOINT_MOBILITY_MODEL_H
+#define WAYPOINT_MOBILITY_MODEL_H
+
+#include <stdint.h>
+#include <deque>
+#include "mobility-model.h"
+#include "ns3/vector.h"
+#include "waypoint.h"
+
+namespace ns3 {
+
+/**
+ * \brief a waypoint-based mobility model
+ *
+ * Each object determines its velocity at a given time from a set of
+ * ns3::Waypoint objects. The position of each object is not updated
+ * unless queried, and past waypoints are discarded after the current
+ * simulation time greater than their time value.
+ *
+ * The intial position of each object corresponds to the position of
+ * the first waypoint, and the initial velocity of each object is zero.
+ * Upon reaching the last waypoint, object positions becomes static and
+ * velocity is zero.
+ *
+ * Waypoints can be added at any time, and setting the current position
+ * of an object will set its velocity to zero until the next waypoint,
+ * unless there are no more waypoints in which case it will not change
+ * without user intervention.
+ *
+ */
+class WaypointMobilityModel : public MobilityModel
+{
+ public:
+  static TypeId GetTypeId (void);
+
+  /**
+   * Create a path with no waypoints at location (0,0,0).
+   */
+  WaypointMobilityModel ();
+
+  /**
+   * \param waypoint waypoint to append to the object path.
+   *
+   * Add a waypoint to the path of the object. The time must
+   * be greater than the previous waypoint added, otherwise
+   * a fatal error occurs. The first waypoint is set as the
+   * current position with a velocity of zero.
+   *
+   */
+  void AddWaypoint (const Waypoint &waypoint);
+
+  /**
+   * Get the waypoint that this object is traveling towards.
+   */
+  Waypoint GetNextWaypoint (void) const;
+
+  /**
+   * Get the number of waypoints left for this object, excluding
+   * the next one.
+   */
+  uint32_t WaypointsLeft (void) const;
+
+  /**
+   * Clear any existing waypoints and set the current waypoint
+   * time to infinity. Calling this is only an optimization and
+   * not required. After calling this function, adding waypoints
+   * behaves as it would for a new object.
+   */
+  void EndMobility (void);
+
+ private:
+  void Update (void) const;
+  virtual void DoDispose (void);
+  virtual Vector DoGetPosition (void) const;
+  virtual void DoSetPosition (const Vector &position);
+  virtual Vector DoGetVelocity (void) const;
+
+  bool m_first;
+  mutable std::deque<Waypoint> m_waypoints;
+  mutable Waypoint m_current;
+  mutable Waypoint m_next;
+  mutable Vector m_velocity;
+};
+
+} // namespace ns3
+
+#endif /* WAYPOINT_MOBILITY_MODEL_H */
+
diff -r c7aa69502cdd src/mobility/waypoint.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint.cc Thu Oct 29 13:20:07 2009 -0700
@@ -0,0 +1,52 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@...>
+ */
+#include "waypoint.h"
+
+namespace ns3 {
+
+ATTRIBUTE_HELPER_CPP (Waypoint);
+
+Waypoint::Waypoint (const Time &_time, const Vector &_position)
+  : time (_time),
+    position (_position)
+{}
+Waypoint::Waypoint ()
+  : time (0.0),
+    position (0,0,0)
+{}
+
+std::ostream &operator << (std::ostream &os, const Waypoint &waypoint)
+{
+  os << waypoint.time.GetSeconds() << "$" << waypoint.position;
+  return os;
+}
+std::istream &operator >> (std::istream &is, Waypoint &waypoint)
+{
+  char separator;
+  is >> waypoint.time >> separator >> waypoint.position;
+  if (separator != '$')
+    {
+      is.setstate (std::ios_base::failbit);
+    }
+  return is;
+}
+
+} // namespace ns3
+
diff -r c7aa69502cdd src/mobility/waypoint.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mobility/waypoint.h Thu Oct 29 13:20:07 2009 -0700
@@ -0,0 +1,68 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 Phillip Sitbon
+ *
+ * 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: Phillip Sitbon <phillip@...>
+ */
+#ifndef WAYPOINT_H
+#define WAYPOINT_H
+
+#include "ns3/attribute.h"
+#include "ns3/attribute-helper.h"
+#include "ns3/nstime.h"
+#include "ns3/vector.h"
+
+namespace ns3 {
+
+/**
+ * \brief a (time, location) pair.
+ *
+ */
+class Waypoint
+{
+public:
+  /**
+   * \param _time time of waypoint.
+   * \param _position position of waypoint corresponding to the given time.
+   *
+   * Create a waypoint.
+   */
+  Waypoint (const Time &_time, const Vector &_position);
+
+  /**
+   * Create a waypoint at time 0 and position (0,0,0).
+   */
+  Waypoint ();
+
+  /* The waypoint time */
+  Time time;
+  /* The position of the waypoint */
+  Vector position;
+};
+
+/**
+ * \class ns3::WaypointValue
+ * \brief hold objects of type ns3::Waypoint
+ */
+ATTRIBUTE_HELPER_HEADER (Waypoint);
+
+std::ostream &operator << (std::ostream &os, const Waypoint &waypoint);
+std::istream &operator >> (std::istream &is, Waypoint &waypoint);
+
+} // namespace ns3
+
+#endif /* WAYPOINT_H */
+
diff -r c7aa69502cdd src/mobility/wscript
--- a/src/mobility/wscript Wed Oct 28 18:27:43 2009 +0100
+++ b/src/mobility/wscript Thu Oct 29 13:20:07 2009 -0700
@@ -14,6 +14,8 @@
         'random-walk-2d-mobility-model.cc',
         'random-direction-2d-mobility-model.cc',
         'constant-acceleration-mobility-model.cc',
+        'waypoint.cc',
+        'waypoint-mobility-model.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -30,4 +32,6 @@
         'random-walk-2d-mobility-model.h',
         'random-direction-2d-mobility-model.h',
         'constant-acceleration-mobility-model.h',
+        'waypoint.h',
+        'waypoint-mobility-model.h',
         ]


Re: Submission for Review: Waypoint Mobility Model

by Tom Henderson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Phillip Sitbon wrote:
> Hi folks,
>
> This is my first time submitting code to ns-3, so I'm doing my best to
> go by the book but please let me know if I miss something.

Thanks for submitting it, I think you followed the book well.

I left comments in Rietveld and added it to the ns-3.7 roadmap wiki page
for possible merge.

- Tom