From a12e6a18c2aa1e79a2d98793d95489feadd592a1 Mon Sep 17 00:00:00 2001 From: Phillip Sitbon Date: Tue, 10 Nov 2009 12:10:35 +0100 Subject: [PATCH] Add Waypoint Mobility model to mainstream --- src/mobility/mobility.h | 5 + src/mobility/waypoint-mobility-model.cc | 182 ++++++++++++++++++++++++ src/mobility/waypoint-mobility-model.h | 115 +++++++++++++++ src/mobility/waypoint.cc | 74 ++++++++++ src/mobility/waypoint.h | 74 ++++++++++ src/mobility/wscript | 4 + 6 files changed, 454 insertions(+) create mode 100644 src/mobility/waypoint-mobility-model.cc create mode 100644 src/mobility/waypoint-mobility-model.h create mode 100644 src/mobility/waypoint.cc create mode 100644 src/mobility/waypoint.h diff --git a/src/mobility/mobility.h b/src/mobility/mobility.h index 98e2f37e1..05cf769e7 100644 --- a/src/mobility/mobility.h +++ b/src/mobility/mobility.h @@ -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 --git a/src/mobility/waypoint-mobility-model.cc b/src/mobility/waypoint-mobility-model.cc new file mode 100644 index 000000000..06a9d7326 --- /dev/null +++ b/src/mobility/waypoint-mobility-model.cc @@ -0,0 +1,182 @@ +/* -*- 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 + */ +#include +#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 () + .SetGroupName ("Mobility") + .AddConstructor () + .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 ()) + ; + return tid; +} + + +WaypointMobilityModel::WaypointMobilityModel () + : m_first (true) +{ +} +WaypointMobilityModel::~WaypointMobilityModel () +{ +} +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 ().GetTime () >= waypoint.GetTime ()), + "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.GetTime () ) + { + return; + } + + while ( now >= m_next.GetTime () ) + { + if ( m_waypoints.empty () ) + { + if ( m_current.GetTime () <= m_next.GetTime () ) + { + m_current.SetPosition(m_next.GetPosition ()); + m_current.SetTime (now); + m_velocity = Vector (0,0,0); + NotifyCourseChange (); + } + else + { + m_current.SetTime (now); + } + + return; + } + + m_current = m_next; + m_next = m_waypoints.front (); + m_waypoints.pop_front (); + newWaypoint = true; + + const double t_span = (m_next.GetTime () - m_current.GetTime ()).GetSeconds (); + NS_ASSERT (t_span > 0); + m_velocity.x = (m_next.GetPosition ().x - m_current.GetPosition ().x) / t_span; + m_velocity.y = (m_next.GetPosition ().y - m_current.GetPosition ().y) / t_span; + m_velocity.z = (m_next.GetPosition ().z - m_current.GetPosition ().z) / t_span; + } + + + const double t_diff = (now - m_current.GetTime ()).GetSeconds(); + Vector pos; + pos.x = m_current.GetPosition ().x + m_velocity.x * t_diff; + pos.y = m_current.GetPosition ().y + m_velocity.y * t_diff; + pos.z = m_current.GetPosition ().z + m_velocity.z * t_diff; + m_current.SetPosition (pos); + m_current.SetTime (now); + + if ( newWaypoint ) + { + NotifyCourseChange (); + } +} +Vector +WaypointMobilityModel::DoGetPosition (void) const +{ + Update (); + return m_current.GetPosition (); +} +void +WaypointMobilityModel::DoSetPosition (const Vector &position) +{ + const Time now = Simulator::Now (); + Update (); + m_current.SetTime (std::max (now, m_next.GetTime ())); + m_current.SetPosition (position); + m_velocity = Vector (0,0,0); + NotifyCourseChange (); +} +void +WaypointMobilityModel::EndMobility (void) +{ + m_waypoints.clear (); + m_current.SetTime (Seconds (std::numeric_limits::infinity ())); + m_next.SetTime (m_current.GetTime ()); + m_first = true; +} +Vector +WaypointMobilityModel::DoGetVelocity (void) const +{ + return m_velocity; +} + +} // namespace ns3 + diff --git a/src/mobility/waypoint-mobility-model.h b/src/mobility/waypoint-mobility-model.h new file mode 100644 index 000000000..7504efbbd --- /dev/null +++ b/src/mobility/waypoint-mobility-model.h @@ -0,0 +1,115 @@ +/* -*- 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 + */ +#ifndef WAYPOINT_MOBILITY_MODEL_H +#define WAYPOINT_MOBILITY_MODEL_H + +#include +#include +#include "mobility-model.h" +#include "ns3/vector.h" +#include "waypoint.h" + +namespace ns3 { + +/** + * \brief a waypoint-based mobility model + * + * Each object determines its velocity and position 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 initial 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. + * + * When a node is in between waypoints (in time), it moves with a constant + * velocity between the position at the previous waypoint and the position + * at the current waypoint. To make a node hold a certain position for a + * time interval, two waypoints with the same position (but different times) + * should be inserted sequentially. + * + * 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 time + * (at which time the object jumps to 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 (); + virtual ~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 m_waypoints; + mutable Waypoint m_current; + mutable Waypoint m_next; + mutable Vector m_velocity; +}; + +} // namespace ns3 + +#endif /* WAYPOINT_MOBILITY_MODEL_H */ + diff --git a/src/mobility/waypoint.cc b/src/mobility/waypoint.cc new file mode 100644 index 000000000..28efd05fe --- /dev/null +++ b/src/mobility/waypoint.cc @@ -0,0 +1,74 @@ +/* -*- 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 + */ +#include "waypoint.h" + +namespace ns3 { + +ATTRIBUTE_HELPER_CPP (Waypoint); + +Waypoint::Waypoint (const Time &waypointTime, const Vector &waypointPosition) + : m_time (waypointTime), + m_position (waypointPosition) +{} +Waypoint::Waypoint () + : m_time (0.0), + m_position (0,0,0) +{} + +Time Waypoint::GetTime () const +{ + return m_time; +} + +void Waypoint::SetTime (Time time) +{ + m_time = time; +} + +Vector Waypoint::GetPosition () const +{ + return m_position; +} + +void Waypoint::SetPosition (Vector pos) +{ + m_position = pos; +} + +std::ostream &operator << (std::ostream &os, const Waypoint &waypoint) +{ + os << waypoint.GetTime ().GetSeconds () << "$" << waypoint.GetPosition (); + return os; +} +std::istream &operator >> (std::istream &is, Waypoint &waypoint) +{ + char separator; + Time time = waypoint.GetTime (); + Vector pos = waypoint.GetPosition (); + is >> time >> separator >> pos; + if (separator != '$') + { + is.setstate (std::ios_base::failbit); + } + return is; +} + +} // namespace ns3 + diff --git a/src/mobility/waypoint.h b/src/mobility/waypoint.h new file mode 100644 index 000000000..af3e9ab43 --- /dev/null +++ b/src/mobility/waypoint.h @@ -0,0 +1,74 @@ +/* -*- 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 + */ +#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 &waypointTime, const Vector &waypointPosition); + + /** + * Create a waypoint at time 0 and position (0,0,0). + */ + Waypoint (); + Time GetTime () const; + void SetTime (Time time); + Vector GetPosition () const; + void SetPosition (Vector vec); +private: + /* The waypoint time */ + Time m_time; + /* The position of the waypoint */ + Vector m_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 --git a/src/mobility/wscript b/src/mobility/wscript index 6bcfd2e5c..b78c3163c 100644 --- a/src/mobility/wscript +++ b/src/mobility/wscript @@ -14,6 +14,8 @@ def build(bld): '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 @@ def build(bld): 'random-walk-2d-mobility-model.h', 'random-direction-2d-mobility-model.h', 'constant-acceleration-mobility-model.h', + 'waypoint.h', + 'waypoint-mobility-model.h', ]