Move from BuildingsMobilityModel to BuildingMobilityInfo source, tests and examples
/* -*- 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/buildings-mobility-model.h"
#include "ns3/mobility-model.h"
#include "ns3/buildings-helper.h"
#include "ns3/random-variable-stream.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 ()
{
m_rand = CreateObject<UniformRandomVariable> ();
}
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
{
NS_ASSERT_MSG (BuildingList::GetNBuildings () > 0, "no building found");
Ptr<Building> b;
if (m_withReplacement)
{
uint32_t n = m_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 = m_rand->GetInteger (0, m_buildingListWithoutReplacement.size () - 1);
b = m_buildingListWithoutReplacement.at (n);
m_buildingListWithoutReplacement.erase (m_buildingListWithoutReplacement.begin () + n);
}
Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator> ();
BoxValue bv;
b->GetAttribute ("Boundaries", bv);
double x = m_rand->GetValue (bv.Get ().xMin, bv.Get ().xMax);
double y = m_rand->GetValue (bv.Get ().yMin, bv.Get ().yMax);
double z = m_rand->GetValue (bv.Get ().zMin, bv.Get ().zMax);
return Vector (x, y, z);
}
int64_t
RandomBuildingPositionAllocator::AssignStreams (int64_t stream)
{
m_rand->SetStream (stream);
return 1;
}
NS_OBJECT_ENSURE_REGISTERED (RandomRoomPositionAllocator);
RandomRoomPositionAllocator::RandomRoomPositionAllocator ()
{
m_rand = CreateObject<UniformRandomVariable> ();
}
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);
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 = 1; rx <= (*bit)->GetNRoomsX (); ++rx)
{
for (uint32_t ry = 1; ry <= (*bit)->GetNRoomsY (); ++ry)
{
for (uint32_t f = 1; 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 = m_rand->GetInteger (0,m_roomListWithoutReplacement.size () - 1);
RoomInfo r = m_roomListWithoutReplacement.at (n);
m_roomListWithoutReplacement.erase (m_roomListWithoutReplacement.begin () + n);
NS_LOG_LOGIC ("considering building " << r.b->GetId () << " room (" << r.roomx << ", " << r.roomy << ", " << r.floor << ")");
Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator> ();
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 - 1);
double x2 = box.xMin + rdx * r.roomx;
double y1 = box.yMin + rdy * (r.roomy -1);
double y2 = box.yMin + rdy * r.roomy;
double z1 = box.zMin + rdz * (r.floor - 1);
double z2 = box.zMin + rdz * r.floor;
NS_LOG_LOGIC ("randomly allocating position in "
<< " (" << x1 << "," << x2 << ") "
<< "x (" << y1 << "," << y2 << ") "
<< "x (" << z1 << "," << z2 << ") ");
double x = m_rand->GetValue (x1, x2);
double y = m_rand->GetValue (y1, y2);
double z = m_rand->GetValue (z1, z2);
return Vector (x, y, z);
}
int64_t
RandomRoomPositionAllocator::AssignStreams (int64_t stream)
{
m_rand->SetStream (stream);
return 1;
}
NS_OBJECT_ENSURE_REGISTERED (SameRoomPositionAllocator);
SameRoomPositionAllocator::SameRoomPositionAllocator ()
{
NS_FATAL_ERROR (" Constructor \"SameRoomPositionAllocator ()\" should not be used");
}
SameRoomPositionAllocator::SameRoomPositionAllocator (NodeContainer c)
: m_nodes (c)
{
m_rand = CreateObject<UniformRandomVariable> ();
m_nodeIt = m_nodes.Begin ();
// this is needed to make sure the building models associated with c have been initialized
for (NodeContainer::Iterator it = m_nodes.Begin (); it != m_nodes.End (); ++it)
{
Ptr<MobilityModel> mm = (*it)->GetObject<MobilityModel> ();
NS_ASSERT_MSG (mm, "no mobility model aggregated to this node");
Ptr<MobilityBuildingInfo> bmm = mm->GetObject <MobilityBuildingInfo> ();
NS_ASSERT_MSG (bmm, "MobilityBuildingInfo has not been aggregated to this node mobility model");
BuildingsHelper::MakeConsistent (mm);
}
}
TypeId
SameRoomPositionAllocator::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::SameRoomPositionAllocator")
.SetParent<PositionAllocator> ()
.SetGroupName ("Mobility")
.AddConstructor<SameRoomPositionAllocator> ();
return tid;
}
Vector
SameRoomPositionAllocator::GetNext () const
{
NS_LOG_FUNCTION (this);
if (m_nodeIt == m_nodes.End ())
{
m_nodeIt = m_nodes.Begin ();
}
NS_ASSERT_MSG (m_nodeIt != m_nodes.End (), "no node in container");
NS_LOG_LOGIC ("considering node " << (*m_nodeIt)->GetId ());
Ptr<MobilityModel> mm = (*m_nodeIt)->GetObject<MobilityModel> ();
NS_ASSERT_MSG (mm, "no mobility model aggregated to this node");
Ptr<MobilityBuildingInfo> bmm = mm->GetObject<MobilityBuildingInfo> ();
NS_ASSERT_MSG (bmm, "MobilityBuildingInfo has not been aggregated to this node mobility model");
++m_nodeIt;
uint32_t roomx = bmm->GetRoomNumberX ();
uint32_t roomy = bmm->GetRoomNumberY ();
uint32_t floor = bmm->GetFloorNumber ();
NS_LOG_LOGIC ("considering building " << bmm->GetBuilding ()->GetId () << " room (" << roomx << ", " << roomy << ", " << floor << ")");
Ptr<Building> b = bmm->GetBuilding ();
Ptr<RandomBoxPositionAllocator> pa = CreateObject<RandomBoxPositionAllocator> ();
BoxValue bv;
b->GetAttribute ("Boundaries", bv);
Box box = bv.Get ();
double rdx = (box.xMax - box.xMin) / b->GetNRoomsX ();
double rdy = (box.yMax - box.yMin) / b->GetNRoomsY ();
double rdz = (box.zMax - box.zMin) / b->GetNFloors ();
double x1 = box.xMin + rdx * (roomx - 1);
double x2 = box.xMin + rdx * roomx;
double y1 = box.yMin + rdy * (roomy -1);
double y2 = box.yMin + rdy * roomy;
double z1 = box.zMin + rdz * (floor - 1);
double z2 = box.zMin + rdz * floor;
NS_LOG_LOGIC ("randomly allocating position in "
<< " (" << x1 << "," << x2 << ") "
<< "x (" << y1 << "," << y2 << ") "
<< "x (" << z1 << "," << z2 << ") ");
double x = m_rand->GetValue (x1, x2);
double y = m_rand->GetValue (y1, y2);
double z = m_rand->GetValue (z1, z2);
return Vector (x, y, z);
}
int64_t
SameRoomPositionAllocator::AssignStreams (int64_t stream)
{
m_rand->SetStream (stream);
return 1;
}
} // namespace ns3