A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
mobility-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "ns3/mobility-helper.h"
21 #include "ns3/mobility-model.h"
22 #include "ns3/position-allocator.h"
23 #include "ns3/hierarchical-mobility-model.h"
24 #include "ns3/log.h"
25 #include "ns3/pointer.h"
26 #include "ns3/config.h"
27 #include "ns3/simulator.h"
28 #include "ns3/names.h"
29 #include "ns3/string.h"
30 #include <iostream>
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("MobilityHelper");
35 
37 {
38  m_position = CreateObjectWithAttributes<RandomRectanglePositionAllocator>
39  ("X", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]"),
40  "Y", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]"));
41  m_mobility.SetTypeId ("ns3::ConstantPositionMobilityModel");
42 }
44 {
45 }
46 void
48 {
49  m_position = allocator;
50 }
51 
52 void
54  std::string n1, const AttributeValue &v1,
55  std::string n2, const AttributeValue &v2,
56  std::string n3, const AttributeValue &v3,
57  std::string n4, const AttributeValue &v4,
58  std::string n5, const AttributeValue &v5,
59  std::string n6, const AttributeValue &v6,
60  std::string n7, const AttributeValue &v7,
61  std::string n8, const AttributeValue &v8,
62  std::string n9, const AttributeValue &v9)
63 {
64  ObjectFactory pos;
65  pos.SetTypeId (type);
66  pos.Set (n1, v1);
67  pos.Set (n2, v2);
68  pos.Set (n3, v3);
69  pos.Set (n4, v4);
70  pos.Set (n5, v5);
71  pos.Set (n6, v6);
72  pos.Set (n7, v7);
73  pos.Set (n8, v8);
74  pos.Set (n9, v9);
76 }
77 
78 void
80  std::string n1, const AttributeValue &v1,
81  std::string n2, const AttributeValue &v2,
82  std::string n3, const AttributeValue &v3,
83  std::string n4, const AttributeValue &v4,
84  std::string n5, const AttributeValue &v5,
85  std::string n6, const AttributeValue &v6,
86  std::string n7, const AttributeValue &v7,
87  std::string n8, const AttributeValue &v8,
88  std::string n9, const AttributeValue &v9)
89 {
90  m_mobility.SetTypeId (type);
91  m_mobility.Set (n1, v1);
92  m_mobility.Set (n2, v2);
93  m_mobility.Set (n3, v3);
94  m_mobility.Set (n4, v4);
95  m_mobility.Set (n5, v5);
96  m_mobility.Set (n6, v6);
97  m_mobility.Set (n7, v7);
98  m_mobility.Set (n8, v8);
99  m_mobility.Set (n9, v9);
100 }
101 
102 void
104 {
105  Ptr<MobilityModel> mobility = reference->GetObject<MobilityModel> ();
106  m_mobilityStack.push_back (mobility);
107 }
108 
109 void
111 {
112  Ptr<MobilityModel> mobility = Names::Find<MobilityModel> (referenceName);
113  m_mobilityStack.push_back (mobility);
114 }
115 
116 void
118 {
119  m_mobilityStack.pop_back ();
120 }
121 
122 
123 std::string
125 {
126  return m_mobility.GetTypeId ().GetName ();
127 }
128 
129 void
131 {
132  Ptr<Object> object = node;
133  Ptr<MobilityModel> model = object->GetObject<MobilityModel> ();
134  if (model == 0)
135  {
136  model = m_mobility.Create ()->GetObject<MobilityModel> ();
137  if (model == 0)
138  {
139  NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<<
140  m_mobility.GetTypeId ().GetName ()<<"\"");
141  }
142  if (m_mobilityStack.empty ())
143  {
144  NS_LOG_DEBUG ("node="<<object<<", mob="<<model);
145  object->AggregateObject (model);
146  }
147  else
148  {
149  // we need to setup a hierarchical mobility model
150  Ptr<MobilityModel> parent = m_mobilityStack.back ();
151  Ptr<MobilityModel> hierarchical =
152  CreateObjectWithAttributes<HierarchicalMobilityModel> ("Child", PointerValue (model),
153  "Parent", PointerValue (parent));
154  object->AggregateObject (hierarchical);
155  NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
156  }
157  }
158  Vector position = m_position->GetNext ();
159  model->SetPosition (position);
160 }
161 
162 void
163 MobilityHelper::Install (std::string nodeName) const
164 {
165  Ptr<Node> node = Names::Find<Node> (nodeName);
166  Install (node);
167 }
168 void
170 {
171  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
172  {
173  Install (*i);
174  }
175 }
176 
177 void
179 {
181 }
182 static double
183 DoRound (double v)
184 {
185  if (v <= 1e-4 && v >= -1e-4)
186  {
187  return 0.0;
188  }
189  else if (v <= 1e-3 && v >= 0)
190  {
191  return 1e-3;
192  }
193  else if (v >= -1e-3 && v <= 0)
194  {
195  return -1e-3;
196  }
197  else
198  {
199  return v;
200  }
201 }
202 void
204 {
205  Ptr<Node> node = mobility->GetObject<Node> ();
206  *os << "now=" << Simulator::Now ()
207  << " node=" << node->GetId ();
208  Vector pos = mobility->GetPosition ();
209  pos.x = DoRound (pos.x);
210  pos.y = DoRound (pos.y);
211  pos.z = DoRound (pos.z);
212  Vector vel = mobility->GetVelocity ();
213  vel.x = DoRound (vel.x);
214  vel.y = DoRound (vel.y);
215  vel.z = DoRound (vel.z);
216  std::streamsize saved_precision = os->precision ();
217  std::ios::fmtflags saved_flags = os->flags ();
218  os->precision (3);
219  os->setf (std::ios::fixed,std::ios::floatfield);
220  *os << " pos=" << pos.x << ":" << pos.y << ":" << pos.z
221  << " vel=" << vel.x << ":" << vel.y << ":" << vel.z
222  << std::endl;
223  os->flags (saved_flags);
224  os->precision (saved_precision);
225 }
226 
227 void
228 MobilityHelper::EnableAscii (std::ostream &os, uint32_t nodeid)
229 {
230  std::ostringstream oss;
231  oss << "/NodeList/" << nodeid << "/$ns3::MobilityModel/CourseChange";
232  Config::ConnectWithoutContext (oss.str (),
234 }
235 void
237 {
238  for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
239  {
240  EnableAscii (os, (*i)->GetId ());
241  }
242 }
243 void
245 {
247 }
248 int64_t
250 {
251  int64_t currentStream = stream;
252  Ptr<Node> node;
253  Ptr<MobilityModel> mobility;
254  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
255  {
256  node = (*i);
257  mobility = node->GetObject<MobilityModel> ();
258  if (mobility)
259  {
260  currentStream += mobility->AssignStreams (currentStream);
261  }
262  }
263  return (currentStream - stream);
264 }
265 
266 } // namespace ns3