00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ns3/mobility-helper.h"
00021 #include "ns3/mobility-model.h"
00022 #include "ns3/position-allocator.h"
00023 #include "ns3/hierarchical-mobility-model.h"
00024 #include "ns3/log.h"
00025 #include "ns3/pointer.h"
00026 #include "ns3/config.h"
00027 #include "ns3/simulator.h"
00028 #include <iostream>
00029
00030 namespace ns3 {
00031
00032 NS_LOG_COMPONENT_DEFINE ("MobilityHelper");
00033
00034 MobilityHelper::MobilityHelper ()
00035 {
00036 m_position = CreateObject<RandomRectanglePositionAllocator>
00037 ("X", RandomVariableValue (ConstantVariable (0.0)),
00038 "Y", RandomVariableValue (ConstantVariable (0.0)));
00039 m_mobility.SetTypeId ("ns3::StaticMobilityModel");
00040 }
00041 MobilityHelper::~MobilityHelper ()
00042 {}
00043 void
00044 MobilityHelper::SetPositionAllocator (Ptr<PositionAllocator> allocator)
00045 {
00046 m_position = allocator;
00047 }
00048 void
00049 MobilityHelper::SetPositionAllocator (std::string type,
00050 std::string n1, const AttributeValue &v1,
00051 std::string n2, const AttributeValue &v2,
00052 std::string n3, const AttributeValue &v3,
00053 std::string n4, const AttributeValue &v4,
00054 std::string n5, const AttributeValue &v5,
00055 std::string n6, const AttributeValue &v6,
00056 std::string n7, const AttributeValue &v7,
00057 std::string n8, const AttributeValue &v8,
00058 std::string n9, const AttributeValue &v9)
00059 {
00060 ObjectFactory pos;
00061 pos.SetTypeId (type);
00062 pos.Set (n1, v1);
00063 pos.Set (n2, v2);
00064 pos.Set (n3, v3);
00065 pos.Set (n4, v4);
00066 pos.Set (n5, v5);
00067 pos.Set (n6, v6);
00068 pos.Set (n7, v7);
00069 pos.Set (n8, v8);
00070 pos.Set (n9, v9);
00071 m_position = pos.Create ()->GetObject<PositionAllocator> ();
00072 }
00073
00074 void
00075 MobilityHelper::SetMobilityModel (std::string type,
00076 std::string n1, const AttributeValue &v1,
00077 std::string n2, const AttributeValue &v2,
00078 std::string n3, const AttributeValue &v3,
00079 std::string n4, const AttributeValue &v4,
00080 std::string n5, const AttributeValue &v5,
00081 std::string n6, const AttributeValue &v6,
00082 std::string n7, const AttributeValue &v7,
00083 std::string n8, const AttributeValue &v8,
00084 std::string n9, const AttributeValue &v9)
00085 {
00086 m_mobility.SetTypeId (type);
00087 m_mobility.Set (n1, v1);
00088 m_mobility.Set (n2, v2);
00089 m_mobility.Set (n3, v3);
00090 m_mobility.Set (n4, v4);
00091 m_mobility.Set (n5, v5);
00092 m_mobility.Set (n6, v6);
00093 m_mobility.Set (n7, v7);
00094 m_mobility.Set (n8, v8);
00095 m_mobility.Set (n9, v9);
00096 }
00097
00098 void
00099 MobilityHelper::PushReferenceMobilityModel (Ptr<Object> reference)
00100 {
00101 Ptr<MobilityModel> mobility = reference->GetObject<MobilityModel> ();
00102 m_mobilityStack.push_back (mobility);
00103 }
00104 void
00105 MobilityHelper::PopReferenceMobilityModel (void)
00106 {
00107 m_mobilityStack.pop_back ();
00108 }
00109
00110
00111 std::string
00112 MobilityHelper::GetMobilityModelType (void) const
00113 {
00114 return m_mobility.GetTypeId ().GetName ();
00115 }
00116
00117 void
00118 MobilityHelper::Install (Ptr<Node> node) const
00119 {
00120 Ptr<Object> object = node;
00121 Ptr<MobilityModel> model = object->GetObject<MobilityModel> ();
00122 if (model == 0)
00123 {
00124 model = m_mobility.Create ()->GetObject<MobilityModel> ();
00125 if (model == 0)
00126 {
00127 NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<<
00128 m_mobility.GetTypeId ().GetName ()<<"\"");
00129 }
00130 if (m_mobilityStack.empty ())
00131 {
00132 NS_LOG_DEBUG ("node="<<object<<", mob="<<model);
00133 object->AggregateObject (model);
00134 }
00135 else
00136 {
00137
00138 Ptr<MobilityModel> parent = m_mobilityStack.back ();
00139 Ptr<MobilityModel> hierarchical =
00140 CreateObject<HierarchicalMobilityModel> ("Child", PointerValue (model),
00141 "Parent", PointerValue (parent));
00142 object->AggregateObject (hierarchical);
00143 NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
00144 }
00145 }
00146 Vector position = m_position->GetNext ();
00147 model->SetPosition (position);
00148 }
00149
00150 void
00151 MobilityHelper::Install (NodeContainer c) const
00152 {
00153 for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
00154 {
00155 Install (*i);
00156 }
00157 }
00158
00159 void
00160 MobilityHelper::InstallAll (void)
00161 {
00162 Install (NodeContainer::GetGlobal ());
00163 }
00164 static double
00165 DoRound (double v)
00166 {
00167 if (v <= 1e-4 && v >= -1e-4)
00168 {
00169 return 0.0;
00170 }
00171 else if (v <= 1e-3 && v >= 0)
00172 {
00173 return 1e-3;
00174 }
00175 else if (v >= -1e-3 && v <= 0)
00176 {
00177 return -1e-3;
00178 }
00179 else
00180 {
00181 return v;
00182 }
00183 }
00184 void
00185 MobilityHelper::CourseChanged (std::ostream *os, Ptr<const MobilityModel> mobility)
00186 {
00187 Ptr<Node> node = mobility->GetObject<Node> ();
00188 *os << "now=" << Simulator::Now ()
00189 << " node=" << node->GetId ();
00190 Vector pos = mobility->GetPosition ();
00191 pos.x = DoRound (pos.x);
00192 pos.y = DoRound (pos.y);
00193 pos.z = DoRound (pos.z);
00194 Vector vel = mobility->GetVelocity ();
00195 vel.x = DoRound (vel.x);
00196 vel.y = DoRound (vel.y);
00197 vel.z = DoRound (vel.z);
00198 std::streamsize saved_precision = os->precision ();
00199 std::ios::fmtflags saved_flags = os->flags ();
00200 os->precision (3);
00201 os->setf (std::ios::fixed,std::ios::floatfield);
00202 *os << " pos=" << pos.x << ":" << pos.y << ":" << pos.z
00203 << " vel=" << vel.x << ":" << vel.y << ":" << vel.z
00204 << std::endl;
00205 os->flags (saved_flags);
00206 os->precision (saved_precision);
00207 }
00208
00209 void
00210 MobilityHelper::EnableAscii (std::ostream &os, uint32_t nodeid)
00211 {
00212 std::ostringstream oss;
00213 oss << "/NodeList/" << nodeid << "/$ns3::MobilityModel/CourseChange";
00214 Config::ConnectWithoutContext (oss.str (),
00215 MakeBoundCallback (&MobilityHelper::CourseChanged, &os));
00216 }
00217 void
00218 MobilityHelper::EnableAscii (std::ostream &os, NodeContainer n)
00219 {
00220 for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
00221 {
00222 EnableAscii (os, (*i)->GetId ());
00223 }
00224 }
00225 void
00226 MobilityHelper::EnableAsciiAll (std::ostream &os)
00227 {
00228 EnableAscii (os, NodeContainer::GetGlobal ());
00229 }
00230
00231
00232 }