A Discrete-Event Network Simulator
API
mobility-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright 2010 University of Washington
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  */
19 
20 /*
21  * This test suite is intended to test mobility use cases in general,
22  * as typically used by user programs (i.e. with the helper layer
23  * involved).
24  */
25 
26 #include "ns3/test.h"
27 #include "ns3/boolean.h"
28 #include "ns3/simulator.h"
29 #include "ns3/scheduler.h"
30 #include "ns3/vector.h"
31 #include "ns3/mobility-model.h"
32 #include "ns3/waypoint-mobility-model.h"
33 #include "ns3/mobility-helper.h"
34 
35 using namespace ns3;
36 
37 // Test whether course change notifications occur regardless of calls
38 // to Update() position (which are triggered by calls to GetPosition())
40 {
41 public:
43  virtual ~WaypointLazyNotifyFalse ();
44 
45 private:
46  void TestXPosition (double expectedXPos);
47  void CourseChangeCallback (std::string path, Ptr<const MobilityModel> model);
48  virtual void DoRun (void);
52 };
53 
55  : TestCase ("Test behavior when LazyNotify is false"),
56  m_courseChanges (0)
57 {
58 }
59 
61 {
62 }
63 
64 void
66 {
67  Vector pos = m_mob->GetPosition ();
68  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
69 }
70 
71 void
73 {
74  // All waypoints (at 10 second intervals) should trigger a course change
75  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (m_courseChanges * 10.0, Simulator::Now ().GetSeconds (), 0.001, "Course change not notified correctly", __FILE__, __LINE__);
77 }
78 
79 void
81 {
82  m_node = CreateObject<Node> ();
83  m_mob = CreateObject<WaypointMobilityModel> ();
84  // LazyNotify should by default be false
85  m_node->AggregateObject (m_mob);
86  Waypoint wpt (Seconds (0.0), Vector (0.0, 0.0, 0.0));
87  m_mob->AddWaypoint (wpt);
88  Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0));
89  m_mob->AddWaypoint (wpt2);
90  Waypoint wpt3 (Seconds (20.0), Vector (20.0, 20.0, 20.0));
91  m_mob->AddWaypoint (wpt3);
92 
93  Simulator::Schedule (Seconds (5.0), &WaypointLazyNotifyFalse::TestXPosition, this, 5);
94  Simulator::Run ();
95  Simulator::Destroy ();
96 }
97 
99 {
100 public:
102  virtual ~WaypointLazyNotifyTrue ();
103 
104 private:
105  void TestXPosition (double expectedXPos);
106  void CourseChangeCallback (std::string path, Ptr<const MobilityModel> model);
107  virtual void DoRun (void);
110 };
111 
113  : TestCase ("Test behavior when LazyNotify is true")
114 {
115 }
116 
118 {
119 }
120 
121 void
123 {
124  Vector pos = m_mob->GetPosition ();
125  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
126 }
127 
128 void
130 {
131  // This should trigger at time 15 only, since that is the first time that
132  // position is updated due to LazyNotify
133  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (15, Simulator::Now ().GetSeconds (), 0.001, "Course change not notified correctly", __FILE__, __LINE__);
134 }
135 
136 void
138 {
139  m_node = CreateObject<Node> ();
140  m_mob = CreateObject<WaypointMobilityModel> ();
141  m_mob->SetAttributeFailSafe ("LazyNotify", BooleanValue (true));
142  m_node->AggregateObject (m_mob);
143  Waypoint wpt (Seconds (0.0), Vector (0.0, 0.0, 0.0));
144  m_mob->AddWaypoint (wpt);
145  Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0));
146  m_mob->AddWaypoint (wpt2);
147  Waypoint wpt3 (Seconds (20.0), Vector (20.0, 20.0, 20.0));
148  m_mob->AddWaypoint (wpt3);
149 
150  Simulator::Schedule (Seconds (15.0), &WaypointLazyNotifyTrue::TestXPosition, this, 15);
151  Simulator::Run ();
152  Simulator::Destroy ();
153 }
154 
156 {
157 public:
160 
161 private:
162  void TestXPosition (Ptr<const WaypointMobilityModel> model, double expectedXPos);
163  void TestNumWaypoints (Ptr<const WaypointMobilityModel> model, uint32_t num);
164  virtual void DoRun (void);
170 };
171 
173  : TestCase ("Test behavior of Waypoint InitialPositionIsWaypoint")
174 {
175 }
176 
178 {
179 }
180 
181 void
183 {
184  Vector pos = model->GetPosition ();
185  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
186 }
187 
188 void
190 {
191  NS_TEST_EXPECT_MSG_EQ (model->WaypointsLeft (), num, "Unexpected number of waypoints left");
192 }
193 
194 void
196 {
197  // Case 1: InitialPositionIsWaypoint == false, and we call SetPosition
198  // without any waypoints added. There should be no waypoints after
199  // time 0
200  m_mob1 = CreateObject<WaypointMobilityModel> ();
201  m_mob1->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (false));
202  m_mob1->SetPosition (Vector (10.0, 10.0, 10.0));
203  // At time 1s, there should be no waypoints
204  Simulator::Schedule (Seconds (1.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob1, 0);
205  // At time 15s, the model should still be at x position 10.0
206  Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob1, 10.0);
207 
208  // Case 2: InitialPositionIsWaypoint == false, and we call SetPosition
209  // after adding a waypoint.
210  m_mob2 = CreateObject<WaypointMobilityModel> ();
211  m_mob2->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (false));
212  Waypoint wpt21 (Seconds (5.0), Vector (15.0, 15.0, 15.0));
213  m_mob2->AddWaypoint (wpt21);
214  Waypoint wpt22 (Seconds (10.0), Vector (20.0, 20.0, 20.0));
215  m_mob2->AddWaypoint (wpt22);
216  m_mob2->SetPosition (Vector (10.0, 10.0, 10.0));
217  // At time 3, no waypoints have been hit, so position should be 10 and
218  // numWaypoints should be 2, or 1 excluding the next one
219  Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob2, 10.0);
220  Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob2, 1);
221  // At time 8, check that X position is 18 (i.e. position is interpolating
222  // between 15 and 20) and there is one waypoint left, but we exclude
223  // the next one so we test for zero waypoints
224  Simulator::Schedule (Seconds (8.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob2, 18.0);
225  Simulator::Schedule (Seconds (8.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob2, 0);
226 
227  // Case 3: InitialPositionIsWaypoint == true, and we call SetPosition
228  // without any waypoints added.
229  m_mob3 = CreateObject<WaypointMobilityModel> ();
230  m_mob3->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true));
231  m_mob3->SetPosition (Vector (10.0, 10.0, 10.0));
232  // At time 1s, there should be zero waypoints not counting the next one
233  Simulator::Schedule (Seconds (1.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob3, 0);
234  // At time 15s, the model should still be at x position 10.0
235  Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob3, 10.0);
236 
237  // Case 4: InitialPositionIsWaypoint == true, and we call SetPosition
238  // after adding a waypoint.
239  m_mob4 = CreateObject<WaypointMobilityModel> ();
240  m_mob4->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true));
241  Waypoint wpt41 (Seconds (5.0), Vector (15.0, 15.0, 15.0));
242  m_mob4->AddWaypoint (wpt41);
243  Waypoint wpt42 (Seconds (10.0), Vector (20.0, 20.0, 20.0));
244  m_mob4->AddWaypoint (wpt42);
245  // Here, SetPosition() is called after waypoints have been added. In
246  // this case, the initial position is set until the time of the first
247  // waypoint, at which time it jumps to the waypoint and begins moving
248  m_mob4->SetPosition (Vector (10.0, 10.0, 10.0));
249  // At time 3, position should be fixed still at 10
250  Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 10.0);
251  Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob4, 1);
252  // At time 6, we should be moving between 15 and 20
253  Simulator::Schedule (Seconds (6.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 16.0);
254  // At time 15, we should be fixed at 20
255  Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 20.0);
256 
257  // case 5: If waypoint and SetPosition both called at time 0,
258  // SetPosition takes precedence
259  m_mob5 = CreateObject<WaypointMobilityModel> ();
260  m_mob5->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true));
261  // Note: The below statement would result in a crash, because it would
262  // violate the rule that waypoints must increase in start time
263  // m_mob5->SetPosition (Vector (10.0, 10.0, 10.0));
264  Waypoint wpt51 (Seconds (0.0), Vector (200.0, 200.0, 200.0));
265  m_mob5->AddWaypoint (wpt51);
266  Waypoint wpt52 (Seconds (5.0), Vector (15.0, 15.0, 15.0));
267  m_mob5->AddWaypoint (wpt52);
268  Waypoint wpt53 (Seconds (10.0), Vector (20.0, 20.0, 20.0));
269  m_mob5->AddWaypoint (wpt53);
270  // Here, since waypoints already exist, the below SetPosition will cancel
271  // out wpt51 above, and model will stay at initial position until time 5
272  m_mob5->SetPosition (Vector (10.0, 10.0, 10.0));
273  Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob5, 10.0);
274 
275  Simulator::Run ();
276  Simulator::Destroy ();
277 }
278 
280 {
281 public:
284 
285 private:
286  void TestXPosition (Ptr<const WaypointMobilityModel> mob, double expectedXPos);
287  virtual void DoRun (void);
288 };
289 
291  : TestCase ("Test behavior using MobilityHelper and PositionAllocator")
292 {
293 }
294 
296 {
297 }
298 
299 void
301 {
302  Vector pos = mob->GetPosition ();
303  NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
304 }
305 
306 // WaypointMobilityModel tests using the helper
307 void
309 {
310  NodeContainer c;
311  c.Create (1);
313  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
314  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
315  mobility.SetPositionAllocator (positionAlloc);
316  // When InitialPositionIsWaypoint is false (default), the position
317  // set by the position allocator is ignored. The first waypoint set will
318  // set the initial position (with velocity 0 until first waypoint time)
319  mobility.SetMobilityModel ("ns3::WaypointMobilityModel",
320  "InitialPositionIsWaypoint", BooleanValue (false));
321  mobility.Install (c);
322 
323  // Get back a pointer to this
325  // Waypoint added at time 0 will override initial position
326  Waypoint wpt (Seconds (5.0), Vector (20.0, 20.0, 20.0));
327  Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0));
328  mob->AddWaypoint (wpt);
329  mob->AddWaypoint (wpt2);
330  // At time 3 (before first waypoint, position is 20
331  Simulator::Schedule (Seconds (3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 20);
332  // At time 7.5 (midway between points 1 and 2, position is 15
333  Simulator::Schedule (Seconds (7.5), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 15);
334 
335  // When InitialPositionIsWaypoint is true, the position allocator creates
336  // the first waypoint, and movement occurs between this origin and the
337  // initial waypoint below at 5 seconds
338  NodeContainer c2;
339  c2.Create (1);
340  MobilityHelper mobility2;
341  Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator> ();
342  positionAlloc2->Add (Vector (0.0, 0.0, 0.0));
343  mobility2.SetPositionAllocator (positionAlloc2);
344  mobility2.SetMobilityModel ("ns3::WaypointMobilityModel",
345  "InitialPositionIsWaypoint", BooleanValue (true));
346  mobility2.Install (c2);
348  Waypoint wpt3 (Seconds (5.0), Vector (20.0, 20.0, 20.0));
349  mob2->AddWaypoint (wpt3);
350  // Move to position 12 at 3 seconds
351  Simulator::Schedule (Seconds (3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob2, 12);
352 
353  Simulator::Run ();
354  Simulator::Destroy ();
355 }
356 
358 {
359 public:
361 };
362 
364  : TestSuite ("mobility", UNIT)
365 {
366  AddTestCase (new WaypointLazyNotifyFalse, TestCase::QUICK);
367  AddTestCase (new WaypointLazyNotifyTrue, TestCase::QUICK);
368  AddTestCase (new WaypointInitialPositionIsWaypoint, TestCase::QUICK);
369  AddTestCase (new WaypointMobilityModelViaHelper, TestCase::QUICK);
370 }
371 
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:34
void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)
void TestXPosition(Ptr< const WaypointMobilityModel > model, double expectedXPos)
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:462
A suite of tests to run.
Definition: test.h:1333
void AddWaypoint(const Waypoint &waypoint)
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:252
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:278
Ptr< WaypointMobilityModel > m_mob5
Vector GetPosition(void) const
Ptr< WaypointMobilityModel > m_mob3
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:211
Ptr< WaypointMobilityModel > m_mob4
encapsulates test code
Definition: test.h:1147
virtual void DoRun(void)
Implementation to actually run this TestCase.
static void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)
Ptr< WaypointMobilityModel > m_mob
virtual void DoRun(void)
Implementation to actually run this TestCase.
void TestNumWaypoints(Ptr< const WaypointMobilityModel > model, uint32_t num)
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
tuple mobility
Definition: third.py:101
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
void TestXPosition(Ptr< const WaypointMobilityModel > mob, double expectedXPos)
void TestXPosition(double expectedXPos)
static MobilityTestSuite mobilityTestSuite
virtual void DoRun(void)
Implementation to actually run this TestCase.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
void SetPosition(const Vector &position)
Ptr< WaypointMobilityModel > m_mob1
Helper class used to assign positions and mobility models to nodes.
#define NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:477
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
void TestXPosition(double expectedXPos)
Ptr< WaypointMobilityModel > m_mob2
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
void Add(Vector v)
Add a position to the list of positions.
Waypoint-based mobility model.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:340
Ptr< WaypointMobilityModel > m_mob
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
a (time, location) pair.
Definition: waypoint.h:35
uint32_t WaypointsLeft(void) const
Get the number of waypoints left for this object, excluding the next one.
void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)