Adding SpringMobilityModel to adjust positions of nodes in large
topologies
Inspired by http://en.wikipedia.org/wiki/Force-based_algorithms_%28graph_drawing%29
diff --git a/model/annotated-topology-reader.cc b/model/annotated-topology-reader.cc
index eb56339..6553f86 100644
--- a/model/annotated-topology-reader.cc
+++ b/model/annotated-topology-reader.cc
@@ -58,6 +58,8 @@
, m_randY (0, 100.0)
{
NS_LOG_FUNCTION (this);
+
+ // SetMobilityModel ("ns3::ConstantPositionMobilityModel");
}
void
@@ -69,6 +71,13 @@
m_randY = UniformVariable (uly, lry);
}
+void
+AnnotatedTopologyReader::SetMobilityModel (const std::string &model)
+{
+ NS_LOG_FUNCTION (this << model);
+ m_mobilityFactory.SetTypeId (model);
+}
+
AnnotatedTopologyReader::~AnnotatedTopologyReader ()
{
NS_LOG_FUNCTION (this);
@@ -77,14 +86,15 @@
Ptr<Node>
AnnotatedTopologyReader::CreateNode (const std::string name)
{
- return CreateNode (name, m_randX.GetValue (), m_randX.GetValue ());
+ return CreateNode (name, m_randX.GetValue (), m_randY.GetValue ());
}
Ptr<Node>
AnnotatedTopologyReader::CreateNode (const std::string name, double posX, double posY)
{
+ NS_LOG_FUNCTION (this << name << posX << posY);
Ptr<Node> node = CreateObject<Node> ();
- Ptr<ConstantPositionMobilityModel> loc = CreateObject<ConstantPositionMobilityModel> ();
+ Ptr<MobilityModel> loc = DynamicCast<MobilityModel> (m_mobilityFactory.Create ());
node->AggregateObject (loc);
loc->SetPosition (Vector (posX, posY, 0));
@@ -144,9 +154,9 @@
// NS_LOG_DEBUG ("Input: [" << line << "]");
istringstream lineBuffer (line);
- string from, to, capacity, metric;
+ string from, to, capacity, metric, delay, queueSizeNode1, queueSizeNode2;
- lineBuffer >> from >> to >> capacity >> metric;
+ lineBuffer >> from >> to >> capacity >> metric >> delay >> queueSizeNode1 >> queueSizeNode2;
if (processedLinks[to].size () != 0 &&
processedLinks[to].find (from) != processedLinks[to].end ())
@@ -164,9 +174,13 @@
link.SetAttribute ("DataRate", capacity);
link.SetAttribute ("OSPF", metric);
- // link.SetAttribute ("Delay", delay);
- // link.SetAttribute ("QueueSizeNode1", queueSizeNode1);
- // link.SetAttribute ("QueueSizeNode2", queueSizeNode2);
+
+ if (!delay.empty ())
+ link.SetAttribute ("Delay", delay);
+ if (!queueSizeNode1.empty ())
+ link.SetAttribute ("QueueSizeNode1", queueSizeNode1);
+ if (!queueSizeNode2.empty ())
+ link.SetAttribute ("QueueSizeNode2", queueSizeNode2);
AddLink (link);
NS_LOG_DEBUG ("New link " << from << " <==> " << to << " / " << capacity << "Kbps with " << metric << " metric");
@@ -202,6 +216,7 @@
{
BOOST_FOREACH (const Link &link, m_linksList)
{
+ NS_LOG_DEBUG ("OSPF: " << link.GetAttribute ("OSPF"));
uint16_t metric = boost::lexical_cast<uint16_t> (link.GetAttribute ("OSPF"));
{
@@ -230,40 +245,33 @@
AnnotatedTopologyReader::ApplySettings ()
{
PointToPointHelper p2p;
-
- // temporary queue, will be changed later
- p2p.SetQueue ("ns3::DropTailQueue",
- "MaxPackets", StringValue("100"));
BOOST_FOREACH (Link &link, m_linksList)
{
string tmp;
- NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate")+"Kbps");
- p2p.SetDeviceAttribute ("DataRate", StringValue(link.GetAttribute("DataRate")+"Kbps"));
+ if (link.GetAttributeFailSafe ("DataRate", tmp))
+ {
+ NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate")+"Kbps");
+ p2p.SetDeviceAttribute ("DataRate", StringValue(link.GetAttribute("DataRate")+"Kbps"));
+ }
if (link.GetAttributeFailSafe("Delay", tmp))
{
NS_LOG_INFO ("Delay = " + link.GetAttribute("Delay")+"ms");
p2p.SetChannelAttribute ("Delay", StringValue(link.GetAttribute("Delay")+"ms"));
}
- else
- {
- NS_LOG_INFO ("Default delay 1ms");
- p2p.SetChannelAttribute ("Delay", StringValue("1ms"));
- }
NetDeviceContainer nd = p2p.Install(link.GetFromNode (), link.GetToNode ());
link.SetNetDevices (nd.Get (0), nd.Get (1));
- // NS_LOG_INFO ("Queue: " << link.GetAttribute("QueueSizeNode1") << " <==> " << link.GetAttribute("QueueSizeNode2"));
-
if (link.GetAttributeFailSafe("QueueSizeNode1", tmp))
{
PointerValue txQueueFrom;
link.GetFromNetDevice ()->GetAttribute ("TxQueue", txQueueFrom);
NS_ASSERT (txQueueFrom.Get<DropTailQueue> () != 0);
+ NS_LOG_INFO ("QueueFrom: " << link.GetAttribute("QueueSizeNode1"));
txQueueFrom.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode1")));
}
@@ -273,6 +281,7 @@
link.GetToNetDevice ()->GetAttribute ("TxQueue", txQueueTo);
NS_ASSERT (txQueueTo.Get<DropTailQueue> () != 0);
+ NS_LOG_INFO ("QueueTo: " << link.GetAttribute("QueueSizeNode2"));
txQueueTo.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode2")));
}
}
diff --git a/model/annotated-topology-reader.h b/model/annotated-topology-reader.h
index 06bbe2a..4bacd2a 100644
--- a/model/annotated-topology-reader.h
+++ b/model/annotated-topology-reader.h
@@ -23,6 +23,7 @@
#include "ns3/topology-reader.h"
#include "ns3/random-variable.h"
+#include "ns3/object-factory.h"
namespace ns3
{
@@ -69,6 +70,9 @@
void
SetBoundingBox (double ulx, double uly, double lrx, double lry);
+ void
+ SetMobilityModel (const std::string &model);
+
protected:
Ptr<Node>
CreateNode (const std::string name);
@@ -76,7 +80,7 @@
Ptr<Node>
CreateNode (const std::string name, double posX, double posY);
-private:
+protected:
/**
* \brief This method applies setting to corresponding nodes and links
* NetDeviceContainer must be allocated
@@ -94,6 +98,8 @@
UniformVariable m_randX;
UniformVariable m_randY;
+
+ ObjectFactory m_mobilityFactory;
};
}
diff --git a/model/rocketfuel-weights-reader.cc b/model/rocketfuel-weights-reader.cc
index ac7f6b1..448464e 100644
--- a/model/rocketfuel-weights-reader.cc
+++ b/model/rocketfuel-weights-reader.cc
@@ -46,6 +46,7 @@
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
+#include "../utils/spring-mobility-helper.h"
#include <iomanip>
#include <set>
@@ -56,9 +57,11 @@
namespace ns3 {
-RocketfuelWeightsReader::RocketfuelWeightsReader ()
+RocketfuelWeightsReader::RocketfuelWeightsReader (const std::string &path/*=""*/)
+ : AnnotatedTopologyReader (path)
{
NS_LOG_FUNCTION (this);
+ SetMobilityModel ("ns3::SpringMobilityModel");
}
RocketfuelWeightsReader::~RocketfuelWeightsReader ()
@@ -138,8 +141,11 @@
switch (m_inputType)
{
case WEIGHTS:
- link->SetAttribute ("OSPF", attribute);
- break;
+ {
+ double metric = boost::lexical_cast<double> (attribute);
+ link->SetAttribute ("OSPF", boost::lexical_cast<string> (metric*2));
+ break;
+ }
case LATENCIES:
link->SetAttribute ("Delay", attribute);
break;
@@ -156,8 +162,34 @@
}
topgen.close ();
- NS_LOG_INFO ("Rocketfuel topology created with " << nodes.GetN () << " nodes and " << LinksSize () << " links");
+
+ if (!repeatedRun)
+ {
+ NS_LOG_INFO ("Rocketfuel topology created with " << nodes.GetN () << " nodes and " << LinksSize () << " links");
+ }
return nodes;
}
-
+
+void
+RocketfuelWeightsReader::Commit ()
+{
+ ApplySettings ();
+
+ SpringMobilityHelper::InstallSprings (LinksBegin (), LinksEnd ());
+}
+
+
+// void
+// RocketfuelWeightsReader::Cheat (NodeContainer &nodes)
+// {
+// double epsilon = 1;
+
+// for (NodeContainer::Iterator i = nodes.Begin ();
+// i != nodes.End ();
+// i++)
+// {
+
+// }
+// }
+
} /* namespace ns3 */
diff --git a/model/rocketfuel-weights-reader.h b/model/rocketfuel-weights-reader.h
index 2b73c11..ecf4905 100644
--- a/model/rocketfuel-weights-reader.h
+++ b/model/rocketfuel-weights-reader.h
@@ -39,7 +39,7 @@
class RocketfuelWeightsReader : public AnnotatedTopologyReader
{
public:
- RocketfuelWeightsReader ();
+ RocketfuelWeightsReader (const std::string &path="");
virtual ~RocketfuelWeightsReader ();
void
@@ -55,7 +55,11 @@
*
* \return the container of the nodes created (or empty container if there was an error)
*/
- virtual NodeContainer Read (void);
+ virtual NodeContainer
+ Read (void);
+
+ void
+ Commit ();
enum
{
@@ -63,6 +67,9 @@
LATENCIES
};
+ // void
+ // Cheat (NodeContainer &nodes);
+
private:
RocketfuelWeightsReader (const RocketfuelWeightsReader&);
RocketfuelWeightsReader& operator= (const RocketfuelWeightsReader&);