BuildingsMobilityModel instances automatically placed in appropriated Building
authorNicola Baldo <nbaldo@cttc.es>
Fri, 13 Jan 2012 20:48:20 +0100
changeset 8556 f859539f5dd3
parent 8555 2d4c2747a344
child 8557 3b41fe3d7a5a
BuildingsMobilityModel instances automatically placed in appropriated Building
src/buildings/doc/source/buildings-testing.rst
src/buildings/helper/buildings-helper.cc
src/buildings/helper/buildings-helper.h
src/buildings/model/building-list.h
src/buildings/model/building.cc
src/buildings/model/building.h
src/buildings/model/buildings-mobility-model.cc
src/buildings/model/buildings-mobility-model.h
src/buildings/model/buildings-propagation-loss-model.cc
src/buildings/wscript
src/lte/doc/source/lte-user.rst
src/lte/examples/lena-profiling.cc
--- a/src/buildings/doc/source/buildings-testing.rst	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/doc/source/buildings-testing.rst	Fri Jan 13 20:48:20 2012 +0100
@@ -30,6 +30,13 @@
 Description of the test suites
 ******************************
 
+
+BuildingsHelper test
+~~~~~~~~~~~~~~~~~~~~
+
+The test suite ``buildings-helper`` checks that the method ``BuildingsHelper::MakeAllInstancesConsistent ()`` works properly, i.e., that the BuildingsHelper is successful in locating if nodes are outdoor or indoor, and if indoor that they are located in the correct building, room and floor. Several test cases are provided with different buildings (having different size, position, rooms and floors) and different node positions. The test passes if each every node is located correctly.
+
+
 Pathloss tests
 ~~~~~~~~~~~~~~
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/buildings-helper.cc	Fri Jan 13 20:48:20 2012 +0100
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 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 "buildings-helper.h"
+
+#include <ns3/node-list.h>
+#include <ns3/building.h>
+#include <ns3/building-list.h>
+#include <ns3/mobility-model.h>
+#include <ns3/buildings-mobility-model.h>
+#include <ns3/abort.h>
+#include <ns3/log.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("BuildingsHelper");
+
+namespace ns3 {
+
+void
+BuildingsHelper::MakeAllInstancesConsistent ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (NodeList::Iterator nit = NodeList::Begin (); nit != NodeList::End (); ++nit)
+    {
+      Ptr<BuildingsMobilityModel> bmm = (*nit)->GetObject<BuildingsMobilityModel> ();
+      NS_ABORT_MSG_UNLESS (0 != bmm, "node " << (*nit)->GetId () << " does not have a BuildingsMobilityModel");
+      bool found = false;
+      for (BuildingList::Iterator bit = BuildingList::Begin (); bit != BuildingList::End (); ++bit)
+	{
+	  Vector pos = bmm->GetPosition ();
+	  if ((*bit)->IsInside (pos))
+	    {
+	      NS_LOG_LOGIC ("node " << (*nit)->GetId () << " falls inside building " << (*bit)->GetId ());
+	      NS_ABORT_MSG_UNLESS (found == false, "node already inside another building!");		
+	      found = true;
+	      uint16_t floor = (*bit)->GetFloor (pos);
+	      uint16_t roomX = (*bit)->GetRoomX (pos);
+	      uint16_t roomY = (*bit)->GetRoomY (pos);	   
+	      bmm->SetIndoor (*bit, floor, roomX, roomY);	      
+	    }		    	  
+	}
+      if (!found)
+	{
+	  NS_LOG_LOGIC ("node " << (*nit)->GetId () << " is outdoor");
+	  bmm->SetOutdoor ();
+	}
+    }
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/buildings/helper/buildings-helper.h	Fri Jan 13 20:48:20 2012 +0100
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 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 BUILDINGS_HELPER_H
+#define BUILDINGS_HELPER_H
+
+#include <string>
+#include <ns3/attribute.h>
+#include <ns3/object-factory.h>
+#include <ns3/node-container.h>
+
+
+namespace ns3 {
+
+
+class BuildingsHelper
+{
+public:  
+  static void MakeAllInstancesConsistent ();
+  
+};
+
+
+}
+
+#endif /* BUILDINGS_HELPER_H */
--- a/src/buildings/model/building-list.h	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/model/building-list.h	Fri Jan 13 20:48:20 2012 +0100
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Jaume Nin <jaume.nin@cttc,cat>
- * Based on NodeList implemenation by Mathieu Lacage  <mathieu.lacage@sophia.inria.fr>
+ * Based on NodeList implementation by Mathieu Lacage  <mathieu.lacage@sophia.inria.fr>
  *
  */
 
--- a/src/buildings/model/building.cc	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/model/building.cc	Fri Jan 13 20:48:20 2012 +0100
@@ -15,15 +15,21 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Marco Miozzo  <marco.miozzo@cttc.es>
+ * Authors: Marco Miozzo  <marco.miozzo@cttc.es>
+ *          Nicola Baldo <nbaldo@cttc.es>
  * 
  */
 
+#include "building.h"
+#include "building-list.h"
 
-#include <ns3/building.h>
-#include <ns3/building-list.h>
 #include <ns3/enum.h>
-#include "ns3/uinteger.h"
+#include <ns3/uinteger.h>
+#include <ns3/log.h>
+#include <ns3/assert.h>
+#include <math.h>
+
+NS_LOG_COMPONENT_DEFINE ("Building");
 
 namespace ns3 {
 
@@ -37,17 +43,17 @@
     .AddAttribute ("roomX", "The number of rooms in the X axis.",
                    TypeId::ATTR_GET, // allow only getting it.
                    UintegerValue (4),
-                   MakeUintegerAccessor (&Building::m_roomX),
+                   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_roomY),
+                   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_floor),
+                   MakeUintegerAccessor (&Building::m_floors),
                    MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("Id", "The id (unique integer) of this Building.",
                    TypeId::ATTR_GET, // allow only getting it.
@@ -58,104 +64,195 @@
   return tid;
 }
 
-Building::Building (double _xMin, double _xMax,
-                    double _yMin, double _yMax,
-                    double _zMin, double _zMax/*,
-          uint8_t _nFloors, uint8_t _nRoomX, uint8_t _nRoomY*/)
-  : m_floor (1),
-    m_roomX (1),
-    m_roomY (1),
+Building::Building (double xMin, 
+                    double xMax,
+                    double yMin, 
+                    double yMax,
+                    double zMin, 
+                    double zMax)
+  : m_buildingBounds (xMin, xMax, yMin, yMax, zMin, zMax),
+    m_floors (1),
+    m_roomsX (1),
+    m_roomsY (1),
     m_buildingType (Residential),
     m_externalWalls (ConcreteWithWindows)
-
 {
-  m_buldingBounds = Box (_xMin, _xMax, _yMin, _yMax, _zMin, _zMax);
+  NS_LOG_FUNCTION (this);
   Construct();
 }
 
 
 Building::Building () 
-  : m_floor (1), 
-    m_roomX (1), 
-    m_roomY (1),
+  : m_floors (1), 
+    m_roomsX (1), 
+    m_roomsY (1),
     m_buildingType (Residential),
     m_externalWalls (ConcreteWithWindows)
 {
-  m_buldingBounds = Box ();
+  NS_LOG_FUNCTION (this);
+  m_buildingBounds = Box ();
   Construct();
 }
 
+Building::~Building () 
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+Building::DoDispose () 
+{
+  NS_LOG_FUNCTION (this);
+}
+
 void
 Building::Construct ()
 {
+  NS_LOG_FUNCTION (this);
   m_buildingId = BuildingList::Add(this);
 }
 
+uint32_t
+Building::GetId (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_buildingId;
+}
+
 void
 Building::SetBuildingType (Building::BuildingType_t t)
 {
+  NS_LOG_FUNCTION (this << t);
   m_buildingType = t;
 }
 
 void 
 Building::SetExtWallsType (Building::ExtWallsType_t t)
 {
+  NS_LOG_FUNCTION (this << t);
   m_externalWalls = t;
 }
 
 void
-Building::SetFloorsNumber (uint8_t nfloors)
+Building::SetNFloors (uint16_t nfloors)
 {
-  m_floor = nfloors;
+  NS_LOG_FUNCTION (this << nfloors);
+  m_floors = nfloors;
 }
 
 void
-Building::SetNumberRoomX (uint8_t nroomx)
+Building::SetNRoomsX (uint16_t nroomx)
 {
-  m_roomX = nroomx;
+  NS_LOG_FUNCTION (this << nroomx);
+  m_roomsX = nroomx;
 }
 
 void
-Building::SetNumberRoomY (uint8_t nroomy)
+Building::SetNRoomsY (uint16_t nroomy)
 {
-  m_roomY = nroomy;
+  NS_LOG_FUNCTION (this << nroomy);
+  m_roomsY = nroomy;
 }
 
 
 Building::BuildingType_t 
-Building::GetBuildingType ()
+Building::GetBuildingType () const
 {
   return (m_buildingType);
 }
 
 Building::ExtWallsType_t
-Building::GetExtWallsType ()
+Building::GetExtWallsType () const
 {
   return (m_externalWalls);
 }
 
-uint8_t 
-Building::GetNumberFloors ()
+uint16_t 
+Building::GetNFloors () const
+{
+  return (m_floors);
+}
+
+uint16_t 
+Building::GetNRoomsX () const
 {
-  return (m_floor);
+  return (m_roomsX);
+}
+
+uint16_t 
+Building::GetNRoomsY () const
+{
+  return (m_roomsY);
+}
+
+bool 
+Building::IsInside (Vector position) const
+{
+  return m_buildingBounds.IsInside (position);
 }
 
-uint8_t 
-Building::GetNumberRoomX ()
+
+uint16_t 
+Building::GetRoomX (Vector position) const
 {
-  return (m_roomX);
+  NS_ASSERT (IsInside (position));
+  uint16_t n;
+
+  if (position.x ==  m_buildingBounds.xMax)
+    {
+      n = m_roomsX;
+    }                                                                   
+  else
+    {
+      double xLength = m_buildingBounds.xMax - m_buildingBounds.xMin;
+      double x = position.x - m_buildingBounds.xMin;
+      n = floor (m_roomsX * x/xLength) + 1;
+      NS_LOG_LOGIC ("xLength=" << xLength << ", x=" << x << ", m_roomsX=" << m_roomsX);
+    }
+  NS_LOG_LOGIC ("RoomX: " << n);
+  return n;
 }
 
-uint8_t 
-Building::GetNumberRoomY ()
+uint16_t 
+Building::GetRoomY (Vector position) const
 {
-  return (m_roomY);
+  NS_ASSERT (IsInside (position));
+  uint16_t n;
+
+  if (position.y ==  m_buildingBounds.yMax)
+    {
+      n = m_roomsY;
+    }                                                                   
+  else
+    {
+      double yLength = m_buildingBounds.yMax - m_buildingBounds.yMin;
+      double y = position.y - m_buildingBounds.yMin;
+      n = floor (m_roomsY * y/yLength) + 1;
+      NS_LOG_LOGIC ("yLength=" << yLength << ", y=" << y << ", m_roomsY=" << m_roomsY);
+    }
+  NS_LOG_LOGIC ("RoomY: " << n);
+  return n;
 }
 
-Box
-Building::GetBuildingBounds ()
+uint16_t 
+Building::GetFloor (Vector position) const
 {
-  return (m_buldingBounds);
+  NS_ASSERT (IsInside (position));
+  uint16_t n;
+
+  if (position.z ==  m_buildingBounds.zMax)
+    {
+      n = m_floors;
+    }                                                                   
+  else
+    {
+      double zLength = m_buildingBounds.zMax - m_buildingBounds.zMin;
+      double z = position.z - m_buildingBounds.zMin;
+      n = floor (m_floors * z/zLength) + 1;
+      NS_LOG_LOGIC ("zLength=" << zLength << ", z=" << z << ", m_floors=" << m_floors);
+    }
+  NS_LOG_LOGIC ("floor: " << n);
+  return n;
 }
 
 
--- a/src/buildings/model/building.h	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/model/building.h	Fri Jan 13 20:48:20 2012 +0100
@@ -37,7 +37,11 @@
 class Building : public Object
 {
 public:
+
+  // inherited from Object
   static TypeId GetTypeId (void);
+  virtual void DoDispose ();
+
 
   enum BuildingType_t
     {
@@ -49,6 +53,8 @@
     };
   
   /**
+   * Construct a simple building with 1 room and 1 floor
+   * 
    * \param xMin x coordinates of left boundary.
    * \param xMax x coordinates of right boundary.
    * \param yMin y coordinates of bottom boundary.
@@ -56,7 +62,6 @@
    * \param zMin z coordinates of down boundary.
    * \param zMax z coordinates of up boundary.
    *
-   * Create a building.
    */
   Building (double xMin, 
             double xMax,
@@ -71,6 +76,18 @@
    */
   Building ();
 
+  /** 
+   * Destructor
+   * 
+   */
+  virtual ~Building ();
+
+  /**
+   * \return the unique id of this Building. This unique id happens to
+   * be also the index of the Building into the BuildingList. 
+   */
+  uint32_t GetId (void) const;
+
   /**
    * \param t the type of building (i.e., Residential, Office, Commercial)
    *
@@ -93,68 +110,102 @@
    * This method allows to set the number of floors in the building
    * (default is 1)
    */
-  void SetFloorsNumber (uint8_t nfloors);
+  void SetNFloors (uint16_t nfloors);
 
   /**
    * \param nroomx the number of rooms along the x axis
    *
    * This method allows to set the number of rooms along the x-axis
    */
-  void SetNumberRoomX (uint8_t nroomx);
+  void SetNRoomsX (uint16_t nroomx);
 
   /**
    * \param nroomy the number of floors in the building
    *
    * This method allows to set the number of rooms along the y-axis
    */
-  void SetNumberRoomY (uint8_t nroomy);
+  void SetNRoomsY (uint16_t nroomy);
 
 
   /**
    * \return the type of building
    * Return the type of building (i.e., Residential, Office, Commercial)
    */
-  BuildingType_t GetBuildingType ();
+  BuildingType_t GetBuildingType () const;
 
   /**
    * \return the type of external walls of the building
    */
-  ExtWallsType_t GetExtWallsType ();
+  ExtWallsType_t GetExtWallsType () const;
 
   /**
    * \return the number of floors of the building
    */
-  uint8_t GetNumberFloors ();
+  uint16_t GetNFloors () const;
 
   /**
    * \return the number of rooms along the x-axis of the building
    */
-  uint8_t GetNumberRoomX ();
+  uint16_t GetNRoomsX () const;
 
   /**
    * \return the number of rooms along the y-axis
    */
-  uint8_t GetNumberRoomY ();
+  uint16_t GetNRoomsY () const;
   
-  /**
-   * \return the bounds of the building as Box class
+  /** 
+   * 
+   * 
+   * \param position some position
+   * 
+   * \return true if the position fall inside the building, false otherwise
+   */
+  bool IsInside (Vector position) const;
+ 
+  /** 
+   * 
+   * 
+   * \param position a position inside the building
+   * 
+   * \return the number of the room along the X axis where the
+   * position falls
    */
-  Box GetBuildingBounds ();
+  uint16_t GetRoomX (Vector position) const;
 
- 
+  /** 
+   * 
+   * 
+   * \param position a position inside the building
+   * 
+   * \return  the number of the room along the Y axis where the
+   * position falls
+   */
+  uint16_t GetRoomY (Vector position) const;
+
+  /** 
+   * 
+   * \param position a position inside the building 
+   * 
+   * \return  the floor where the position falls
+   */
+  uint16_t GetFloor (Vector position) const;
+
+
+
 
 private:
 
   void Construct ();
 
-  Box m_buldingBounds;
+  Box m_buildingBounds;
+
   /**
    * number of floors, must be greater than 0, and 1 means only one floor
    * (i.e., groundfloor)
    */
-  uint8_t m_floor;
-  uint8_t m_roomX;
-  uint8_t m_roomY;
+  uint16_t m_floors;
+  uint16_t m_roomsX;
+  uint16_t m_roomsY;
 
   uint32_t m_buildingId;
   BuildingType_t m_buildingType;
@@ -166,7 +217,7 @@
 //std::istream &operator >> (std::istream &is, Box &box);
 
 
-ATTRIBUTE_HELPER_HEADER (Building);
+//ATTRIBUTE_HELPER_HEADER (Building);
 
 } // namespace ns3
 
--- a/src/buildings/model/buildings-mobility-model.cc	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/model/buildings-mobility-model.cc	Fri Jan 13 20:48:20 2012 +0100
@@ -22,8 +22,10 @@
 #include <ns3/simulator.h>
 #include <ns3/position-allocator.h>
 #include <ns3/buildings-mobility-model.h>
-#include "ns3/pointer.h"
+#include <ns3/pointer.h>
+#include <ns3/log.h>
 
+NS_LOG_COMPONENT_DEFINE ("BuildingsMobilityModel");
 
 namespace ns3 {
 
@@ -35,12 +37,7 @@
   static TypeId tid = TypeId ("ns3::BuildingsMobilityModel")
     .SetParent<MobilityModel> ()
     .SetGroupName ("Mobility")
-    .AddConstructor<BuildingsMobilityModel> ()
-    .AddAttribute ("Bounds",
-                   "Bounds of the area to cruise.",
-                   BoxValue (Box (-100.0, 100.0, -100.0, 100.0, 0.0, 100.0)),
-                   MakeBoxAccessor (&BuildingsMobilityModel::m_bounds),
-                   MakeBoxChecker ());
+    .AddConstructor<BuildingsMobilityModel> ();
 
   return tid;
 }
@@ -48,6 +45,7 @@
 
 BuildingsMobilityModel::BuildingsMobilityModel ()
 {
+  NS_LOG_FUNCTION (this);
   m_indoor = false;
   m_nFloor = 0;
   m_roomX = 1;
@@ -57,43 +55,48 @@
 void
 BuildingsMobilityModel::DoDispose (void)
 {
-  // chain up
-  m_surroudingBuildings.clear ();
+  NS_LOG_FUNCTION (this);
   MobilityModel::DoDispose ();
 }
 
 Vector
 BuildingsMobilityModel::DoGetPosition (void) const
 {
+  NS_LOG_FUNCTION (this);
   m_helper.Update ();
   return m_helper.GetCurrentPosition ();
 }
 void 
 BuildingsMobilityModel::DoSetPosition (const Vector &position)
 {
+  NS_LOG_FUNCTION (this);
   m_helper.SetPosition (position);
 }
 Vector
 BuildingsMobilityModel::DoGetVelocity (void) const
 {
+  NS_LOG_FUNCTION (this);
   return m_helper.GetVelocity ();
 }
 
 bool
 BuildingsMobilityModel::IsIndoor (void)
 {
+  NS_LOG_FUNCTION (this);
   return (m_indoor);
 }
 
 bool
 BuildingsMobilityModel::IsOutdoor (void)
 {
+  NS_LOG_FUNCTION (this);
   return (!m_indoor);
 }
 
 void
 BuildingsMobilityModel::SetIndoor (Ptr<Building> building)
 {
+  NS_LOG_FUNCTION (this);
   m_indoor = true;
   m_myBuilding = building;
 }
@@ -101,13 +104,14 @@
 void
 BuildingsMobilityModel::SetIndoor (Ptr<Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy)
 {
+  NS_LOG_FUNCTION (this);
   m_indoor = true;
   m_myBuilding = building;
   m_nFloor = nfloor;
   m_roomX = nroomx;
   m_roomY = nroomy;
   
-  if (!building->GetBuildingBounds ().IsInside (m_helper.GetCurrentPosition ()))
+  if (!building->IsInside (m_helper.GetCurrentPosition ()))
     {
       NS_FATAL_ERROR ("Position of the node is inconsistent with building bounds");
     }
@@ -117,12 +121,14 @@
 void
 BuildingsMobilityModel::SetOutdoor (void)
 {
+  NS_LOG_FUNCTION (this);
   m_indoor = false;
 }
 
 void
 BuildingsMobilityModel::SetFloorNumber (uint8_t nfloor)
 {
+  NS_LOG_FUNCTION (this);
   m_nFloor = nfloor;
 }
 
@@ -135,31 +141,28 @@
 void
 BuildingsMobilityModel::SetRoomNumberY (uint8_t nroomy)
 {
+  NS_LOG_FUNCTION (this);
   m_roomY = nroomy;
 }
 
-
-void
-BuildingsMobilityModel::SetSurroudingBuilding (Ptr<Building> building)
-{
-  m_surroudingBuildings.push_back (building);
-}
-
 uint8_t
 BuildingsMobilityModel::GetFloorNumber (void)
 {
+  NS_LOG_FUNCTION (this);
   return (m_nFloor);
 }
 
 uint8_t
 BuildingsMobilityModel::GetRoomNumberX (void)
 {
+  NS_LOG_FUNCTION (this);
   return (m_roomX);
 }
 
 uint8_t
 BuildingsMobilityModel::GetRoomNumberY (void)
 {
+  NS_LOG_FUNCTION (this);
   return (m_roomY);
 }
 
@@ -167,8 +170,9 @@
 Ptr<Building>
 BuildingsMobilityModel::GetBuilding ()
 {
+  NS_LOG_FUNCTION (this);
   return (m_myBuilding);
 }
 
   
-} // namespace
\ No newline at end of file
+} // namespace
--- a/src/buildings/model/buildings-mobility-model.h	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/model/buildings-mobility-model.h	Fri Jan 13 20:48:20 2012 +0100
@@ -59,8 +59,6 @@
   void SetIndoor (Ptr<Building> building, uint8_t nfloor, uint8_t nroomx, uint8_t nroomy);
   void SetOutdoor (void);
 
-  void SetSurroudingBuilding (Ptr<Building> building);
-
   void SetFloorNumber (uint8_t nfloor);
   void SetRoomNumberX (uint8_t nroomx);
   void SetRoomNumberY (uint8_t nroomy);
@@ -79,8 +77,7 @@
   virtual void DoSetPosition (const Vector &position);
   virtual Vector DoGetVelocity (void) const;
   ConstantVelocityHelper m_helper;
-  Box m_bounds;     // bounds of the simulation field (if needed)
-  std::list < Ptr<Building> > m_surroudingBuildings;    // buildings blocks
+
   Ptr<Building> m_myBuilding;
   bool m_indoor;
   /**
--- a/src/buildings/model/buildings-propagation-loss-model.cc	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/model/buildings-propagation-loss-model.cc	Fri Jan 13 20:48:20 2012 +0100
@@ -29,9 +29,6 @@
 #include "ns3/buildings-mobility-model.h"
 #include "ns3/enum.h"
 
-//#include <ns3/shadowing-loss-model.h>
-//#include <ns3/jakes-fading-loss-model.h>
-
 
 NS_LOG_COMPONENT_DEFINE ("BuildingsPropagationLossModel");
 
@@ -624,7 +621,9 @@
 double
 BuildingsPropagationLossModel::GetLoss (Ptr<MobilityModel> a, Ptr<MobilityModel> b) const
 {
+  NS_ASSERT_MSG ((a->GetPosition ().z > 0) && (b->GetPosition ().z > 0), "BuildingsPropagationLossModel does not support underground nodes (placed at z < 0)");
 
+  
   double distance = a->GetDistanceFrom (b);
   if (distance <= m_minDistance)
     {
@@ -634,6 +633,7 @@
   // get the BuildingsMobilityModel pointers
   Ptr<BuildingsMobilityModel> a1 = DynamicCast<BuildingsMobilityModel> (a);
   Ptr<BuildingsMobilityModel> b1 = DynamicCast<BuildingsMobilityModel> (b);
+  NS_ASSERT_MSG ((a1 != 0) && (b1 != 0), "BuildingsPropagationLossModel only works with BuildingsMobilityModel");
 
   double loss = 0.0;
 
--- a/src/buildings/wscript	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/buildings/wscript	Fri Jan 13 20:48:20 2012 +0100
@@ -8,10 +8,12 @@
         'model/building-list.cc',
         'model/buildings-mobility-model.cc',
         'model/buildings-propagation-loss-model.cc',
+        'helper/buildings-helper.cc',
         ]
 
     module_test = bld.create_ns3_module_test_library('buildings')
     module_test.source = [
+        'test/buildings-helper-test.cc',
         'test/buildings-pathloss-test.cc',
         'test/buildings-shadowing-test.cc',
         ]
@@ -23,6 +25,7 @@
         'model/building-list.h',
         'model/buildings-mobility-model.h',
         'model/buildings-propagation-loss-model.h',
+        'helper/buildings-helper.h',
         'test/buildings-pathloss-test.h',
         'test/buildings-shadowing-test.h',
         ]
--- a/src/lte/doc/source/lte-user.rst	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/lte/doc/source/lte-user.rst	Fri Jan 13 20:48:20 2012 +0100
@@ -403,18 +403,6 @@
     MobilityHelper mobility;
     mobility.SetMobilityModel ("ns3::BuildingsMobilityModel");
 
-#. Node creation and positioning::
-
-    ueNodes.Create (1);
-    mobility.Install (ueNodes);
-    NetDeviceContainer ueDevs;
-    ueDevs = lteHelper->InstallUeDevice (ueNodes);
-    Ptr<BuildingsMobilityModel> mm = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
-    double x_axis = 0.0;
-    double y_axis = 0.0;
-    double z_axis = 0.0;
-    mm->SetPosition (Vector (x_axis, y_axis, z_axis));
-
 #. Building creation::
 
     double x_min = 0.0;
@@ -423,29 +411,33 @@
     double y_max = 20.0;
     double z_min = 0.0;
     double z_max = 10.0;
-    Ptr<Building> building = Create<Building> (x_min, x_max, y_min, y_max, z_min, z_max);
+    Ptr<Building> building = CreateObject <Building> (x_min, x_max, y_min, y_max, z_min, z_max);
     building->SetBuildingType (Building::Residential);
     building->SetExtWallsType (Building::ConcreteWithWindows);
-    building->SetFloorsNumber (3);
-    building->SetNumberRoomX (3);
-    building->SetNumberRoomY (2);
+    building->SetNFloors (3);
+    building->SetNRoomsX (3);
+    building->SetNRoomsY (2);
 
    This will instantiate a residential building with base of 10 x 20 meters and height of 10 meters whose external walls are of concrete with windows; the building has three floors and has an internal 3 x 2  grid of rooms of equal size.
 
-#. Building and nodes interactions::
-
-    mm->SetIndoor (building, 2, 1, 1);
-
-   which is equivalent to the form::
+#. Node creation and positioning::
 
-    mm->SetIndoor (building);
-    mm->SetFloorNumber (2);
-    mm->SetRoomNumberX (1);
-    mm->SetRoomNumberY (1);
+    ueNodes.Create (2);
+    mobility.Install (ueNodes);
+    NetDeviceContainer ueDevs;
+    ueDevs = lteHelper->InstallUeDevice (ueNodes);
+    Ptr<BuildingsMobilityModel> mm0 = enbNodes.Get (0)->GetObject<BuildingsMobilityModel> ();
+    Ptr<BuildingsMobilityModel> mm1 = enbNodes.Get (1)->GetObject<BuildingsMobilityModel> ();   
+    mm0->SetPosition (Vector (5.0, 5.0, 1.5));
+    mm1->SetPosition (Vector (30.0, 40.0, 1.5));
 
-   This informs the node's mobility model that the node is located inside the building on the second floor in the corner room of the 3 x 2 grid.
-   We suggest the usage of the first form since it performs a consistency check of the node position with the building bounds.
-   It has to be noted that the simulator does not check the consistence between the node's position (x,y,z coordinates) and the building position and size for outdoor nodes. The responsibility of this consistency is completely left to the user.
+This positions the node on the scenario. Note that, in this example, node 0 will be in the building, and node 1 will be out of the building. Note that this alone is not sufficient to setup the topology correctly. What is left to be done is to issue the following command after we have placed all nodes in the simulation::
+
+      BuildingsHelper::MakeAllInstancesConsistent ();
+
+This command will go through the lists of all nodes and of all buildings, determine for each user if it is indoor or outdoor, and if indoor it will also determine the building in which the user is located and the corresponding floor and number inside the building.
+
+
 
 
 
--- a/src/lte/examples/lena-profiling.cc	Fri Jan 13 13:10:41 2012 +0100
+++ b/src/lte/examples/lena-profiling.cc	Fri Jan 13 20:48:20 2012 +0100
@@ -141,9 +141,9 @@
                                                     0.0, nFloors* roomHeight);
       building->SetBuildingType(Building::Residential);
       building->SetExtWallsType(Building::ConcreteWithWindows);
-      building->SetFloorsNumber(nFloors);
-      building->SetNumberRoomX(nRooms);
-      building->SetNumberRoomY(nRooms);
+      building->SetNFloors (nFloors);
+      building->SetNRoomsX (nRooms);
+      building->SetNRoomsY (nRooms);
       mobility.SetMobilityModel("ns3::BuildingsMobilityModel");
       mobility.Install (enbNodes);
       uint32_t plantedEnb = 0;