buildings allocator and position allocator
authorNicola Baldo <nbaldo@cttc.es>
Wed, 29 Feb 2012 12:28:16 +0100
changeset 8651 c333744c3ee1
parent 8650 9e372de3b581
child 8652 ca97a8d27544
buildings allocator and position allocator
src/buildings/helper/building-allocator.cc
src/buildings/helper/building-allocator.h
src/buildings/helper/building-container.cc
src/buildings/helper/building-container.h
src/buildings/helper/building-position-allocator.cc
src/buildings/helper/building-position-allocator.h
src/buildings/model/building.cc
src/buildings/model/hybrid-buildings-propagation-loss-model.cc
src/buildings/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/building-allocator.cc	Wed Feb 29 12:28:16 2012 +0100
@@ -0,0 +1,203 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ *
+ * 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 "building-allocator.h"
+#include "ns3/building.h"
+#include "ns3/random-variable.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "ns3/enum.h"
+#include "ns3/log.h"
+#include <cmath>
+
+NS_LOG_COMPONENT_DEFINE ("BuildingAllocator");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (GridBuildingAllocator);
+
+GridBuildingAllocator::GridBuildingAllocator ()
+  : m_current (0)
+{
+  m_buildingFactory.SetTypeId ("ns3::Building");
+}
+
+GridBuildingAllocator::~GridBuildingAllocator ()
+{
+}
+
+TypeId 
+GridBuildingAllocator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::GridBuildingAllocator")
+    .SetParent<Object> ()
+    .AddConstructor<GridBuildingAllocator> ()
+    .AddAttribute ("GridWidth", "The number of objects layed out on a line.",
+                   UintegerValue (10),
+                   MakeUintegerAccessor (&GridBuildingAllocator::m_n),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("MinX", "The x coordinate where the grid starts.",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_xMin),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("MinY", "The y coordinate where the grid starts.",
+                   DoubleValue (0.0),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_yMin),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("LengthX", " the length of the wall of each building along the X axis.",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_lengthX),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("LengthY", " the length of the wall of each building along the X axis.",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_lengthY),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("DeltaX", "The x space between objects.",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_deltaX),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("DeltaY", "The y space between objects.",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_deltaY),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("Height", "The height of the building (roof level)",
+                   DoubleValue (10),
+                   MakeDoubleAccessor (&GridBuildingAllocator::m_height),
+                   MakeDoubleChecker<double> ())
+    .AddAttribute ("LayoutType", "The type of layout.",
+                   EnumValue (ROW_FIRST),
+                   MakeEnumAccessor (&GridBuildingAllocator::m_layoutType),
+                   MakeEnumChecker (ROW_FIRST, "RowFirst",
+                                    COLUMN_FIRST, "ColumnFirst"))
+  ;
+  return tid;
+}
+
+void
+GridBuildingAllocator::SetMinX (double xMin)
+{
+  m_xMin = xMin;
+}
+void
+GridBuildingAllocator::SetMinY (double yMin)
+{
+  m_yMin = yMin;
+}
+void
+GridBuildingAllocator::SetLengthX (double lengthX)
+{
+  m_lengthX = lengthX;
+}
+void
+GridBuildingAllocator::SetLengthY (double lengthY)
+{
+  m_lengthY = lengthY;
+}
+
+void
+GridBuildingAllocator::SetDeltaX (double deltaX)
+{
+  m_deltaX = deltaX;
+}
+void
+GridBuildingAllocator::SetDeltaY (double deltaY)
+{
+  m_deltaY = deltaY;
+}
+void
+GridBuildingAllocator::SetN (uint32_t n)
+{
+  m_n = n;
+}
+void
+GridBuildingAllocator::SetLayoutType (enum LayoutType layoutType)
+{
+  m_layoutType = layoutType;
+}
+
+double
+GridBuildingAllocator::GetMinX (void) const
+{
+  return m_xMin;
+}
+double
+GridBuildingAllocator::GetMinY (void) const
+{
+  return m_yMin;
+}
+double
+GridBuildingAllocator::GetDeltaX (void) const
+{
+  return m_deltaX;
+}
+double
+GridBuildingAllocator::GetDeltaY (void) const
+{
+  return m_deltaY;
+}
+uint32_t
+GridBuildingAllocator::GetN (void) const
+{
+  return m_n;
+}
+enum GridBuildingAllocator::LayoutType
+GridBuildingAllocator::GetLayoutType (void) const
+{
+  return m_layoutType;
+}
+
+void
+GridBuildingAllocator::SetBuildingAttribute (std::string n, const AttributeValue &v)
+{
+  NS_LOG_FUNCTION (this);
+  m_buildingFactory.Set (n, v);
+}
+
+BuildingContainer
+GridBuildingAllocator::Create (uint32_t n) const
+{
+  BuildingContainer bc;
+  uint32_t limit = n + m_current;
+  for (; m_current < limit; ++m_current)
+    {
+      double bxmin = 0.0;
+      double bymin = 0.0;
+      switch (m_layoutType) {
+      case ROW_FIRST:
+        bxmin = m_xMin + (m_deltaX + m_lengthX) * (m_current % m_n);
+        bymin = m_yMin + (m_deltaY + m_lengthY) * (m_current / m_n);
+        break;
+      case COLUMN_FIRST:
+        bxmin = m_xMin + (m_deltaX + m_lengthX) * (m_current / m_n);
+        bymin = m_yMin + (m_deltaY + m_lengthY) * (m_current % m_n);
+        break;
+      }
+      double bxmax = bxmin + m_lengthX;
+      double bymax = bymin + m_lengthY;
+      BoxValue boxValue (Box (bxmin, bxmax, bymin, bymax, 0, m_height));
+      m_buildingFactory.Set ("Boundaries", boxValue);
+      Ptr<Building> b  = m_buildingFactory.Create<Building> ();
+      //b->SetAttribute ("Boundaries", boxValue);
+      bc.Add (b);     
+    }
+  return bc;
+}
+
+
+} // namespace ns3 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/building-allocator.h	Wed Feb 29 12:28:16 2012 +0100
@@ -0,0 +1,168 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * Copyright (C) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * 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>
+ * Author: Nicola Baldo <nbaldo@cttc.es> (took position-allocator and turned it into building-allocator)
+ */
+#ifndef BUILDING_ALLOCATOR_H
+#define BUILDING_ALLOCATOR_H
+
+#include "ns3/object.h"
+#include "ns3/object-factory.h"
+#include "ns3/random-variable.h"
+#include "ns3/vector.h"
+#include "ns3/building-container.h"
+
+namespace ns3 {
+
+class Building;
+
+
+/**
+ * \ingroup buildings
+ * \brief Allocate buildings on a rectangular 2d grid.
+ */
+class GridBuildingAllocator : public Object
+{
+public:
+  GridBuildingAllocator ();
+  virtual ~GridBuildingAllocator ();
+
+  // inherited from Object
+  static TypeId GetTypeId (void);
+
+  /**
+   * Determine whether buildings are allocated row first or column first.
+   */
+  enum LayoutType {
+    /**
+     * In row-first mode, buildings are allocated on the first row until
+     * N buildings have been allocated. Then, the second row located a yMin + yDelta
+     * is used to allocate buildings.
+     */
+    ROW_FIRST,
+    /**
+     * In column-first mode, buildings are allocated on the first column until
+     * N buildings have been allocated. Then, the second column located a xMin + xDelta
+     * is used to allocate buildings.
+     */
+    COLUMN_FIRST
+  };
+
+  /**
+   * \param xMin the x coordinate where layout will start.
+   */
+  void SetMinX (double xMin);
+  /**
+   * \param yMin the y coordinate where layout will start
+   */
+  void SetMinY (double yMin);
+  /**
+   * \param lengthX the length of the wall of each building along the X axis.
+   */
+  void SetLengthX (double lengthX);
+  /**
+   * \param lengthY the length of the wall of each building along the X axis.
+   */
+  void SetLengthY (double lengthY);
+  /**
+   * \param deltaX the x interval between two x-consecutive buildings.
+   */
+  void SetDeltaX (double deltaX);
+  /**
+   * \param deltaY the y interval between two y-consecutive buildings.
+   */
+  void SetDeltaY (double deltaY);
+  /**
+   * \param n the number of buildings allocated on each row (or each column)
+   *        before switching to the next column (or row).
+   */
+  void SetN (uint32_t n);
+  /**
+   * \param layoutType the type of layout to use (row first or column first).
+   */
+  void SetLayoutType (enum LayoutType layoutType);
+
+  /**
+   * \return the x coordinate of the first allocated building.
+   */
+  double GetMinX (void) const;
+  /**
+   * \return the y coordinate of the first allocated building.
+   */
+  double GetMinY (void) const;
+  /**
+   * \return the length of the wall along the X axis
+   */
+  double GetLengthX (void) const;
+  /**
+   * \return the length of the wall along the Y axis
+   */
+  double GetLengthY (void) const;
+  /**
+   * \return the x interval between two x-consecutive buildings.
+   */
+  double GetDeltaX (void) const;
+  /**
+   * \return the y interval between two y-consecutive buildings.
+   */
+  double GetDeltaY (void) const;
+  /**
+   * \return the number of buildings to allocate on each row or each column.
+   */
+  uint32_t GetN (void) const;
+  /**
+   * \return the currently-selected layout type.
+   */
+  enum LayoutType GetLayoutType (void) const;
+
+  /** 
+   * Set an attribute to be used for each new building to be created
+   * 
+   * \param n attribute name
+   * \param v attribute value
+   */
+  void SetBuildingAttribute (std::string n, const AttributeValue &v);
+
+  /** 
+   * Create a set of buildings allocated on a grid
+   * 
+   * \param n the number of buildings to create
+   * 
+   * \return the BuildingContainer that contains the newly created buildings
+   */
+  BuildingContainer Create (uint32_t n) const;
+
+private:
+  mutable uint32_t m_current;
+  enum LayoutType m_layoutType;
+  double m_xMin;
+  double m_yMin;
+  uint32_t m_n;
+  double m_lengthX;
+  double m_lengthY;
+  double m_deltaX;
+  double m_deltaY;
+  double m_height;
+
+  mutable ObjectFactory m_buildingFactory;
+};
+
+} // namespace ns3
+
+#endif /* BUILDING_ALLOCATOR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/building-container.cc	Wed Feb 29 12:28:16 2012 +0100
@@ -0,0 +1,102 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * 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> (original node-container.cc)
+ *         Nicola Baldo (wrote building-container.cc based on node-container.cc)
+ */
+#include "building-container.h"
+#include "ns3/building-list.h"
+#include "ns3/names.h"
+
+namespace ns3 {
+
+BuildingContainer::BuildingContainer ()
+{
+}
+
+BuildingContainer::BuildingContainer (Ptr<Building> building)
+{
+  m_buildings.push_back (building);
+}
+BuildingContainer::BuildingContainer (std::string buildingName)
+{
+  Ptr<Building> building = Names::Find<Building> (buildingName);
+  m_buildings.push_back (building);
+}
+
+BuildingContainer::Iterator 
+BuildingContainer::Begin (void) const
+{
+  return m_buildings.begin ();
+}
+BuildingContainer::Iterator 
+BuildingContainer::End (void) const
+{
+  return m_buildings.end ();
+}
+
+uint32_t 
+BuildingContainer::GetN (void) const
+{
+  return m_buildings.size ();
+}
+Ptr<Building> 
+BuildingContainer::Get (uint32_t i) const
+{
+  return m_buildings[i];
+}
+void 
+BuildingContainer::Create (uint32_t n)
+{
+  for (uint32_t i = 0; i < n; i++)
+    {
+      m_buildings.push_back (CreateObject<Building> ());
+    }
+}
+void 
+BuildingContainer::Add (BuildingContainer other)
+{
+  for (Iterator i = other.Begin (); i != other.End (); i++)
+    {
+      m_buildings.push_back (*i);
+    }
+}
+void 
+BuildingContainer::Add (Ptr<Building> building)
+{
+  m_buildings.push_back (building);
+}
+void 
+BuildingContainer::Add (std::string buildingName)
+{
+  Ptr<Building> building = Names::Find<Building> (buildingName);
+  m_buildings.push_back (building);
+}
+
+BuildingContainer 
+BuildingContainer::GetGlobal (void)
+{
+  BuildingContainer c;
+  for (BuildingList::Iterator i = BuildingList::Begin (); i != BuildingList::End (); ++i)
+    {
+      c.Add (*i);
+    }
+  return c;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/building-container.h	Wed Feb 29 12:28:16 2012 +0100
@@ -0,0 +1,208 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * 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> (original node-container.h)
+ *         Nicola Baldo (wrote building-container.h based on node-container.h)
+ */
+#ifndef BUILDING_CONTAINER_H
+#define BUILDING_CONTAINER_H
+
+#include <stdint.h>
+#include <vector>
+#include <ns3/building.h>
+
+namespace ns3 {
+
+/**
+ * \brief keep track of a set of building pointers.
+ *
+ * Some ns-3 helpers operate on more than one building at a time.  For example
+ * a PositionAllocator may want to position nodes on a set of buildings.
+ * The helper methods will then usually take a BuildingContainer as a
+ * parameter.  BuildingContainers hold the multiple Ptr<Building> which are used
+ * to refer to the buildings.
+ */
+class BuildingContainer
+{
+public:
+  typedef std::vector<Ptr<Building> >::const_iterator Iterator;
+
+  /**
+   * Create an empty BuildingContainer.
+   */
+  BuildingContainer ();
+
+  /**
+   * Create a BuildingContainer with exactly one building which has been previously
+   * instantiated.  The single Building is specified by a smart pointer.
+   *
+   * \param building The Ptr<Building> to add to the container.
+   */
+  BuildingContainer (Ptr<Building> building);
+
+  /**
+   * Create a BuildingContainer with exactly one building which has been previously 
+   * instantiated and assigned a name using the Object Name Service.  This 
+   * Building is then specified by its assigned name. 
+   *
+   * \param buildingName The name of the Building Object to add to the container.
+   */
+  BuildingContainer (std::string buildingName);
+
+  /**
+   * \brief Get an iterator which refers to the first Building in the 
+   * container.
+   *
+   * Buildings can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the iterator method and is typically used in a 
+   * for-loop to run through the Buildings
+   *
+   * \code
+   *   BuildingContainer::Iterator i;
+   *   for (i = container.Begin (); i != container.End (); ++i)
+   *     {
+   *       (*i)->method ();  // some Building method
+   *     }
+   * \endcode
+   *
+   * \returns an iterator which refers to the first Building in the container.
+   */
+  Iterator Begin (void) const;
+
+  /**
+   * \brief Get an iterator which indicates past-the-last Building in the 
+   * container.
+   *
+   * Buildings can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the iterator method and is typically used in a 
+   * for-loop to run through the Buildings
+   *
+   * \code
+   *   BuildingContainer::Iterator i;
+   *   for (i = container.Begin (); i != container.End (); ++i)
+   *     {
+   *       (*i)->method ();  // some Building method
+   *     }
+   * \endcode
+   *
+   * \returns an iterator which indicates an ending condition for a loop.
+   */
+  Iterator End (void) const;
+
+  /**
+   * \brief Get the number of Ptr<Building> stored in this container.
+   *
+   * Buildings can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the direct method and is typically used to
+   * define an ending condition in a for-loop that runs through the stored
+   * Buildings
+   *
+   * \code
+   *   uint32_t nBuildings = container.GetN ();
+   *   for (uint32_t i = 0 i < nBuildings; ++i)
+   *     {
+   *       Ptr<Building> p = container.Get (i)
+   *       i->method ();  // some Building method
+   *     }
+   * \endcode
+   *
+   * \returns the number of Ptr<Building> stored in this container.
+   */
+  uint32_t GetN (void) const;
+
+  /**
+   * \brief Get the Ptr<Building> stored in this container at a given
+   * index.
+   *
+   * Buildings can be retrieved from the container in two ways.  First,
+   * directly by an index into the container, and second, using an iterator.
+   * This method is used in the direct method and is used to retrieve the
+   * indexed Ptr<Appliation>.
+   *
+   * \code
+   *   uint32_t nBuildings = container.GetN ();
+   *   for (uint32_t i = 0 i < nBuildings; ++i)
+   *     {
+   *       Ptr<Building> p = container.Get (i)
+   *       i->method ();  // some Building method
+   *     }
+   * \endcode
+   *
+   * \param i the index of the requested building pointer.
+   * \returns the requested building pointer.
+   */
+  Ptr<Building> Get (uint32_t i) const;
+
+  /**
+   * \brief Create n buildings and append pointers to them to the end of this 
+   * BuildingContainer.
+   *
+   * Buildings are at the heart of any ns-3 simulation.  One of the first tasks that
+   * any simulation needs to do is to create a number of buildings.  This method
+   * automates that task.
+   *
+   * \param n The number of Buildings to create
+   */
+  void Create (uint32_t n);
+
+  /**
+   * \brief Append the contents of another BuildingContainer to the end of
+   * this container.
+   *
+   * \param other The BuildingContainer to append.
+   */
+  void Add (BuildingContainer other);
+
+  /**
+   * \brief Append a single Ptr<Building> to this container.
+   *
+   * \param building The Ptr<Building> to append.
+   */
+  void Add (Ptr<Building> building);
+
+  /**
+   * \brief Append to this container the single Ptr<Building> referred to
+   * via its object name service registered name.
+   *
+   * \param buildingName The name of the Building Object to add to the container.
+   */
+  void Add (std::string buildingName);
+
+  /**
+   * \brief Create a BuildingContainer that contains a list of _all_ buildings
+   * stored in the ns3::BuildingList.
+   *
+   * Whenever a Building is created, a Ptr<Building> is added to a global list of all
+   * buildings in the system.  It is sometimes useful to be able to get to all
+   * buildings in one place.  This method creates a BuildingContainer that is 
+   * initialized to contain all of the simulation buildings,
+   *
+   * \returns a BuildingContainer which contains a list of all Buildings.
+   */
+  static BuildingContainer GetGlobal (void);
+
+private:
+  std::vector<Ptr<Building> > m_buildings;
+};
+
+} // namespace ns3
+
+#endif /* BUILDING_CONTAINER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/building-position-allocator.cc	Wed Feb 29 12:28:16 2012 +0100
@@ -0,0 +1,180 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (C)  2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+#include "building-position-allocator.h"
+#include "ns3/random-variable.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "ns3/enum.h"
+#include "ns3/boolean.h"
+#include "ns3/log.h"
+#include "ns3/box.h"
+#include "ns3/building.h"
+#include <cmath>
+
+#include "ns3/building-list.h"
+
+NS_LOG_COMPONENT_DEFINE ("BuildingPositionAllocator");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (RandomBuildingPositionAllocator);
+
+
+RandomBuildingPositionAllocator::RandomBuildingPositionAllocator ()
+{
+}
+
+TypeId
+RandomBuildingPositionAllocator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RandomBuildingPositionAllocator")
+    .SetParent<PositionAllocator> ()
+    .SetGroupName ("Mobility")
+    .AddConstructor<RandomBuildingPositionAllocator> ()
+    .AddAttribute ("WithReplacement",
+                   "If true, the building will be randomly selected with replacement. "
+                   "If false, no replacement will occur, until the list of buildings "
+                   "to select becomes empty, at which point it will be filled again "
+                   "with the list of all buildings.",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&RandomBuildingPositionAllocator::m_withReplacement),
+                   MakeBooleanChecker ());
+  return tid;
+}
+
+Vector 
+RandomBuildingPositionAllocator::GetNext () const
+{
+  UniformVariable rand;
+  NS_ASSERT_MSG (BuildingList::GetNBuildings () > 0, "no building found");
+  Ptr<Building> b;
+  if (m_withReplacement)
+    {
+      uint32_t n = rand.GetInteger (0, BuildingList::GetNBuildings () - 1);
+      b = BuildingList::GetBuilding (n);
+    }
+  else
+    {
+      if (m_buildingListWithoutReplacement.empty ())
+        {
+            for (BuildingList::Iterator bit = BuildingList::Begin (); bit != BuildingList::End (); ++bit)
+              {
+                m_buildingListWithoutReplacement.push_back (*bit);
+              }
+        }
+      uint32_t n = rand.GetInteger (0, m_buildingListWithoutReplacement.size () - 1);
+      b = m_buildingListWithoutReplacement.at (n);      
+      m_buildingListWithoutReplacement.erase (m_buildingListWithoutReplacement.begin () + n);
+    }
+
+  Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator> ();
+  UniformVariable v;
+  BoxValue bv;
+  b->GetAttribute ("Boundaries", bv);
+  double x = v.GetValue (bv.Get ().xMin, bv.Get ().xMax);
+  double y = v.GetValue (bv.Get ().yMin, bv.Get ().yMax);
+  double z = v.GetValue (bv.Get ().zMin, bv.Get ().zMax);
+  return Vector (x, y, z);
+}
+
+
+
+
+NS_OBJECT_ENSURE_REGISTERED (RandomRoomPositionAllocator);
+
+
+RandomRoomPositionAllocator::RandomRoomPositionAllocator ()
+{
+}
+
+TypeId
+RandomRoomPositionAllocator::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RandomRoomPositionAllocator")
+    .SetParent<PositionAllocator> ()
+    .SetGroupName ("Mobility")
+    .AddConstructor<RandomRoomPositionAllocator> ();
+  return tid;
+}
+
+Vector 
+RandomRoomPositionAllocator::GetNext () const
+{
+  NS_LOG_FUNCTION (this);
+  UniformVariable rand;
+  NS_ASSERT_MSG (BuildingList::GetNBuildings () > 0, "no building found");
+ 
+  if (m_roomListWithoutReplacement.empty ())
+    {
+      for (BuildingList::Iterator bit = BuildingList::Begin (); bit != BuildingList::End (); ++bit)
+        {
+          NS_LOG_LOGIC ("building " << (*bit)->GetId ());
+          for (uint32_t rx = 0; rx < (*bit)->GetNRoomsX (); ++rx)
+            {
+              for (uint32_t ry = 0; ry < (*bit)->GetNRoomsY (); ++ry)
+                {
+                  for (uint32_t f = 0; f < (*bit)->GetNFloors (); ++f)
+                    {
+                      RoomInfo i;
+                      i.roomx = rx;
+                      i.roomy = ry;
+                      i.floor = f; 
+                      i.b = *bit;
+                      NS_LOG_LOGIC ("adding room (" << rx << ", " << ry << ", " << f << ")");
+                      m_roomListWithoutReplacement.push_back (i);
+                    }
+                }
+            }
+        }
+    }
+  uint32_t n = rand.GetInteger (0,m_roomListWithoutReplacement.size () - 1);
+  RoomInfo r = m_roomListWithoutReplacement.at (n);      
+  m_roomListWithoutReplacement.erase (m_roomListWithoutReplacement.begin () + n);  
+  NS_LOG_LOGIC ("considering room (" << r.roomx << ", " << r.roomy << ", " << r.floor << ")");
+
+  Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator> ();
+  UniformVariable v;
+  BoxValue bv;
+  r.b->GetAttribute ("Boundaries", bv);
+  Box box = bv.Get ();
+  double rdx =  (box.xMax - box.xMin) / r.b->GetNRoomsX ();
+  double rdy =  (box.yMax - box.yMin) / r.b->GetNRoomsY ();
+  double rdz =  (box.zMax - box.zMin) / r.b->GetNFloors ();
+  double x1 = box.xMin + rdx * r.roomx;
+  double x2 = box.xMin + rdx * (r.roomx + 1);
+  double y1 = box.yMin + rdy * r.roomy;
+  double y2 = box.yMin + rdy * (r.roomy + 1);
+  double z1 = box.zMin + rdz * r.floor;
+  double z2 = box.zMin + rdz * (r.floor + 1);
+  NS_LOG_LOGIC ("randomly allocating position in "
+                << " (" << x1 << "," << x2 << ") "
+                << "x (" << y1 << "," << y2 << ") "
+                << "x (" << z1 << "," << z2 << ") ");
+
+  double x = v.GetValue (x1, x2);
+  double y = v.GetValue (y1, y2);
+  double z = v.GetValue (z1, z2);
+  
+  return Vector (x, y, z);
+}
+
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/building-position-allocator.h	Wed Feb 29 12:28:16 2012 +0100
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (C) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * 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: Nicola Baldo <nbaldo@cttc.es>
+ */
+#ifndef BUILDING_POSITION_ALLOCATOR_H
+#define BUILDING_POSITION_ALLOCATOR_H
+
+#include <ns3/ptr.h>
+#include <ns3/position-allocator.h>
+
+namespace ns3 {
+
+class Building;
+
+
+/**
+ * Allocate each position by randomly chosing a building from the list
+ * of all buildings, and then randomly chosing a position inside the building.
+ * 
+ */
+class RandomBuildingPositionAllocator : public PositionAllocator
+{
+public:
+  RandomBuildingPositionAllocator ();
+
+  // inherited from Object
+  static TypeId GetTypeId (void);
+
+  // inherited from PositionAllocator
+  virtual Vector GetNext (void) const;
+
+private:
+  
+  bool m_withReplacement;
+  mutable std::vector< Ptr<Building> > m_buildingListWithoutReplacement;
+};
+
+
+/**
+ * Allocate each position by randomly chosing a room from the list
+ * of all buildings, and then randomly chosing a position inside the room.
+ * The selection of the room is always done without replacement.
+ * 
+ */
+class RandomRoomPositionAllocator : public PositionAllocator
+{
+public:
+  RandomRoomPositionAllocator ();
+
+  // inherited from Object
+  static TypeId GetTypeId (void);
+
+  // inherited from PositionAllocator
+  virtual Vector GetNext (void) const;
+
+private:
+  
+  bool m_withReplacement;
+  struct RoomInfo 
+  {
+    Ptr<Building> b;
+    uint32_t roomx;
+    uint32_t roomy;
+    uint32_t floor;
+  };
+  mutable std::vector<RoomInfo> m_roomListWithoutReplacement;
+};
+
+
+
+} // namespace ns3
+
+#endif /* BUILDING_POSITION_ALLOCATOR_H */
--- a/src/buildings/model/building.cc	Mon Feb 27 16:08:22 2012 +0100
+++ b/src/buildings/model/building.cc	Wed Feb 29 12:28:16 2012 +0100
@@ -34,6 +34,8 @@
 namespace ns3 {
 
 
+NS_OBJECT_ENSURE_REGISTERED (Building);
+
 TypeId
 Building::GetTypeId (void)
 {
@@ -41,25 +43,40 @@
     .SetParent<Object> ()
     .AddConstructor<Building> ()
     .AddAttribute ("roomX", "The number of rooms in the X axis.",
-                   TypeId::ATTR_GET, // allow only getting it.
                    UintegerValue (4),
                    MakeUintegerAccessor (&Building::m_roomsX),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("roomY", "The number of rooms in the Y axis.",
-                   TypeId::ATTR_GET, // allow only getting it.
                    UintegerValue (1),
                    MakeUintegerAccessor (&Building::m_roomsY),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("nFloor", "The number of floors of this building.",
-                   TypeId::ATTR_GET, // allow only getting it.
                    UintegerValue (1),
                    MakeUintegerAccessor (&Building::m_floors),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("Id", "The id (unique integer) of this Building.",
-                   TypeId::ATTR_GET, // allow only getting it.
                    UintegerValue (0),
                    MakeUintegerAccessor (&Building::m_buildingId),
                    MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Boundaries", "The boundaries of this Building as a value of type ns3::Box",
+                   BoxValue (),
+                   MakeBoxAccessor (&Building::m_buildingBounds),
+                   MakeBoxChecker ())
+    .AddAttribute ("Type",
+                   "The type of building",
+                   EnumValue (Building::Residential),
+                   MakeEnumAccessor (&Building::m_buildingType),
+                   MakeEnumChecker (Building::Residential, "Residential",
+                                    Building::Office, "Office",
+                                    Building::Commercial, "Commercial"))
+    .AddAttribute ("ExternalWallsType",
+                   "The type of material of which the external walls are made",
+                   EnumValue (Building::ConcreteWithWindows),
+                   MakeEnumAccessor (&Building::m_externalWalls),
+                   MakeEnumChecker (Building::Wood, "Wood",
+                                    Building::ConcreteWithWindows, "ConcreteWithWindows",
+                                    Building::ConcreteWithoutWindows, "ConcreteWithoutWindows",
+                                    Building::StoneBlocks, "StoneBlocks"))
   ;
   return tid;
 }
@@ -90,7 +107,6 @@
     m_externalWalls (ConcreteWithWindows)
 {
   NS_LOG_FUNCTION (this);
-  m_buildingBounds = Box ();
   Construct();
 }
 
--- a/src/buildings/model/hybrid-buildings-propagation-loss-model.cc	Mon Feb 27 16:08:22 2012 +0100
+++ b/src/buildings/model/hybrid-buildings-propagation-loss-model.cc	Wed Feb 29 12:28:16 2012 +0100
@@ -63,7 +63,7 @@
 double
 HybridBuildingsPropagationLossModel::GetLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
 {
-  NS_ASSERT_MSG ((a->GetPosition ().z > 0) && (b->GetPosition ().z > 0), "HybridBuildingsPropagationLossModel does not support underground nodes (placed at z < 0)");
+  NS_ASSERT_MSG ((a->GetPosition ().z >= 0) && (b->GetPosition ().z >= 0), "HybridBuildingsPropagationLossModel does not support underground nodes (placed at z < 0)");
 
   
   double distance = a->GetDistanceFrom (b);
--- a/src/buildings/wscript	Mon Feb 27 16:08:22 2012 +0100
+++ b/src/buildings/wscript	Wed Feb 29 12:28:16 2012 +0100
@@ -10,6 +10,9 @@
         'model/buildings-propagation-loss-model.cc',
         'model/hybrid-buildings-propagation-loss-model.cc',
         'model/oh-buildings-propagation-loss-model.cc',
+        'helper/building-container.cc',
+        'helper/building-position-allocator.cc',
+        'helper/building-allocator.cc',
         'helper/buildings-helper.cc',
         ]
 
@@ -29,6 +32,9 @@
         'model/buildings-propagation-loss-model.h',
         'model/hybrid-buildings-propagation-loss-model.h',
         'model/oh-buildings-propagation-loss-model.h',
+        'helper/building-container.h',
+        'helper/building-allocator.h',
+        'helper/building-position-allocator.h',
         'helper/buildings-helper.h',
         'test/buildings-pathloss-test.h',
         'test/buildings-shadowing-test.h',