A Discrete-Event Network Simulator
API
mobility-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2010 University of Washington
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  */
18 
19 /*
20  * This test suite is intended to test mobility use cases in general,
21  * as typically used by user programs (i.e. with the helper layer
22  * involved).
23  */
24 
25 #include "ns3/boolean.h"
26 #include "ns3/mobility-helper.h"
27 #include "ns3/mobility-model.h"
28 #include "ns3/scheduler.h"
29 #include "ns3/simulator.h"
30 #include "ns3/test.h"
31 #include "ns3/vector.h"
32 #include "ns3/waypoint-mobility-model.h"
33 
34 using namespace ns3;
35 
43 {
44  public:
46  ~WaypointLazyNotifyFalse() override;
47 
48  private:
53  void TestXPosition(double expectedXPos);
59  void CourseChangeCallback(std::string path, Ptr<const MobilityModel> model);
60  void DoRun() override;
64 };
65 
67  : TestCase("Test behavior when LazyNotify is false"),
68  m_courseChanges(0)
69 {
70 }
71 
73 {
74 }
75 
76 void
78 {
79  Vector pos = m_mob->GetPosition();
80  NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
81 }
82 
83 void
85 {
86  // All waypoints (at 10 second intervals) should trigger a course change
88  Simulator::Now().GetSeconds(),
89  0.001,
90  "Course change not notified correctly");
92 }
93 
94 void
96 {
97  m_node = CreateObject<Node>();
98  m_mob = CreateObject<WaypointMobilityModel>();
99  // LazyNotify should by default be false
101  Waypoint wpt(Seconds(0.0), Vector(0.0, 0.0, 0.0));
102  m_mob->AddWaypoint(wpt);
103  Waypoint wpt2(Seconds(10.0), Vector(10.0, 10.0, 10.0));
104  m_mob->AddWaypoint(wpt2);
105  Waypoint wpt3(Seconds(20.0), Vector(20.0, 20.0, 20.0));
106  m_mob->AddWaypoint(wpt3);
107 
108  Simulator::Schedule(Seconds(5.0), &WaypointLazyNotifyFalse::TestXPosition, this, 5);
109  Simulator::Run();
110  Simulator::Destroy();
111 }
112 
119 {
120  public:
122  ~WaypointLazyNotifyTrue() override;
123 
124  private:
129  void TestXPosition(double expectedXPos);
135  void CourseChangeCallback(std::string path, Ptr<const MobilityModel> model);
136  void DoRun() override;
139 };
140 
142  : TestCase("Test behavior when LazyNotify is true")
143 {
144 }
145 
147 {
148 }
149 
150 void
152 {
153  Vector pos = m_mob->GetPosition();
154  NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
155 }
156 
157 void
159 {
160  // This should trigger at time 15 only, since that is the first time that
161  // position is updated due to LazyNotify
163  Simulator::Now().GetSeconds(),
164  0.001,
165  "Course change not notified correctly");
166 }
167 
168 void
170 {
171  m_node = CreateObject<Node>();
172  m_mob = CreateObject<WaypointMobilityModel>();
173  m_mob->SetAttributeFailSafe("LazyNotify", BooleanValue(true));
175  Waypoint wpt(Seconds(0.0), Vector(0.0, 0.0, 0.0));
176  m_mob->AddWaypoint(wpt);
177  Waypoint wpt2(Seconds(10.0), Vector(10.0, 10.0, 10.0));
178  m_mob->AddWaypoint(wpt2);
179  Waypoint wpt3(Seconds(20.0), Vector(20.0, 20.0, 20.0));
180  m_mob->AddWaypoint(wpt3);
181 
182  Simulator::Schedule(Seconds(15.0), &WaypointLazyNotifyTrue::TestXPosition, this, 15);
183  Simulator::Run();
184  Simulator::Destroy();
185 }
186 
193 {
194  public:
197 
198  private:
204  void TestXPosition(Ptr<const WaypointMobilityModel> model, double expectedXPos);
211  void DoRun() override;
217 };
218 
220  : TestCase("Test behavior of Waypoint InitialPositionIsWaypoint")
221 {
222 }
223 
225 {
226 }
227 
228 void
230  double expectedXPos)
231 {
232  Vector pos = model->GetPosition();
233  NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
234 }
235 
236 void
238  uint32_t num)
239 {
240  NS_TEST_EXPECT_MSG_EQ(model->WaypointsLeft(), num, "Unexpected number of waypoints left");
241 }
242 
243 void
245 {
246  // Case 1: InitialPositionIsWaypoint == false, and we call SetPosition
247  // without any waypoints added. There should be no waypoints after
248  // time 0
249  m_mob1 = CreateObject<WaypointMobilityModel>();
250  m_mob1->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(false));
251  m_mob1->SetPosition(Vector(10.0, 10.0, 10.0));
252  // At time 1s, there should be no waypoints
253  Simulator::Schedule(Seconds(1.0),
255  this,
256  m_mob1,
257  0);
258  // At time 15s, the model should still be at x position 10.0
259  Simulator::Schedule(Seconds(15.0),
261  this,
262  m_mob1,
263  10.0);
264 
265  // Case 2: InitialPositionIsWaypoint == false, and we call SetPosition
266  // after adding a waypoint.
267  m_mob2 = CreateObject<WaypointMobilityModel>();
268  m_mob2->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(false));
269  Waypoint wpt21(Seconds(5.0), Vector(15.0, 15.0, 15.0));
270  m_mob2->AddWaypoint(wpt21);
271  Waypoint wpt22(Seconds(10.0), Vector(20.0, 20.0, 20.0));
272  m_mob2->AddWaypoint(wpt22);
273  m_mob2->SetPosition(Vector(10.0, 10.0, 10.0));
274  // At time 3, no waypoints have been hit, so position should be 10 and
275  // numWaypoints should be 2, or 1 excluding the next one
276  Simulator::Schedule(Seconds(3.0),
278  this,
279  m_mob2,
280  10.0);
281  Simulator::Schedule(Seconds(3.0),
283  this,
284  m_mob2,
285  1);
286  // At time 8, check that X position is 18 (i.e. position is interpolating
287  // between 15 and 20) and there is one waypoint left, but we exclude
288  // the next one so we test for zero waypoints
289  Simulator::Schedule(Seconds(8.0),
291  this,
292  m_mob2,
293  18.0);
294  Simulator::Schedule(Seconds(8.0),
296  this,
297  m_mob2,
298  0);
299 
300  // Case 3: InitialPositionIsWaypoint == true, and we call SetPosition
301  // without any waypoints added.
302  m_mob3 = CreateObject<WaypointMobilityModel>();
303  m_mob3->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(true));
304  m_mob3->SetPosition(Vector(10.0, 10.0, 10.0));
305  // At time 1s, there should be zero waypoints not counting the next one
306  Simulator::Schedule(Seconds(1.0),
308  this,
309  m_mob3,
310  0);
311  // At time 15s, the model should still be at x position 10.0
312  Simulator::Schedule(Seconds(15.0),
314  this,
315  m_mob3,
316  10.0);
317 
318  // Case 4: InitialPositionIsWaypoint == true, and we call SetPosition
319  // after adding a waypoint.
320  m_mob4 = CreateObject<WaypointMobilityModel>();
321  m_mob4->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(true));
322  Waypoint wpt41(Seconds(5.0), Vector(15.0, 15.0, 15.0));
323  m_mob4->AddWaypoint(wpt41);
324  Waypoint wpt42(Seconds(10.0), Vector(20.0, 20.0, 20.0));
325  m_mob4->AddWaypoint(wpt42);
326  // Here, SetPosition() is called after waypoints have been added. In
327  // this case, the initial position is set until the time of the first
328  // waypoint, at which time it jumps to the waypoint and begins moving
329  m_mob4->SetPosition(Vector(10.0, 10.0, 10.0));
330  // At time 3, position should be fixed still at 10
331  Simulator::Schedule(Seconds(3.0),
333  this,
334  m_mob4,
335  10.0);
336  Simulator::Schedule(Seconds(3.0),
338  this,
339  m_mob4,
340  1);
341  // At time 6, we should be moving between 15 and 20
342  Simulator::Schedule(Seconds(6.0),
344  this,
345  m_mob4,
346  16.0);
347  // At time 15, we should be fixed at 20
348  Simulator::Schedule(Seconds(15.0),
350  this,
351  m_mob4,
352  20.0);
353 
354  // case 5: If waypoint and SetPosition both called at time 0,
355  // SetPosition takes precedence
356  m_mob5 = CreateObject<WaypointMobilityModel>();
357  m_mob5->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(true));
358  // Note: The below statement would result in a crash, because it would
359  // violate the rule that waypoints must increase in start time
360  // m_mob5->SetPosition (Vector (10.0, 10.0, 10.0));
361  Waypoint wpt51(Seconds(0.0), Vector(200.0, 200.0, 200.0));
362  m_mob5->AddWaypoint(wpt51);
363  Waypoint wpt52(Seconds(5.0), Vector(15.0, 15.0, 15.0));
364  m_mob5->AddWaypoint(wpt52);
365  Waypoint wpt53(Seconds(10.0), Vector(20.0, 20.0, 20.0));
366  m_mob5->AddWaypoint(wpt53);
367  // Here, since waypoints already exist, the below SetPosition will cancel
368  // out wpt51 above, and model will stay at initial position until time 5
369  m_mob5->SetPosition(Vector(10.0, 10.0, 10.0));
370  Simulator::Schedule(Seconds(3.0),
372  this,
373  m_mob5,
374  10.0);
375 
376  Simulator::Run();
377  Simulator::Destroy();
378 }
379 
386 {
387  public:
390 
391  private:
397  void TestXPosition(Ptr<const WaypointMobilityModel> mob, double expectedXPos);
398  void DoRun() override;
399 };
400 
402  : TestCase("Test behavior using MobilityHelper and PositionAllocator")
403 {
404 }
405 
407 {
408 }
409 
410 void
412  double expectedXPos)
413 {
414  Vector pos = mob->GetPosition();
415  NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
416 }
417 
418 // WaypointMobilityModel tests using the helper
419 void
421 {
422  NodeContainer c;
423  c.Create(1);
425  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
426  positionAlloc->Add(Vector(0.0, 0.0, 0.0));
427  mobility.SetPositionAllocator(positionAlloc);
428  // When InitialPositionIsWaypoint is false (default), the position
429  // set by the position allocator is ignored. The first waypoint set will
430  // set the initial position (with velocity 0 until first waypoint time)
431  mobility.SetMobilityModel("ns3::WaypointMobilityModel",
432  "InitialPositionIsWaypoint",
433  BooleanValue(false));
434  mobility.Install(c);
435 
436  // Get back a pointer to this
438  // Waypoint added at time 0 will override initial position
439  Waypoint wpt(Seconds(5.0), Vector(20.0, 20.0, 20.0));
440  Waypoint wpt2(Seconds(10.0), Vector(10.0, 10.0, 10.0));
441  mob->AddWaypoint(wpt);
442  mob->AddWaypoint(wpt2);
443  // At time 3 (before first waypoint, position is 20
444  Simulator::Schedule(Seconds(3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 20);
445  // At time 7.5 (midway between points 1 and 2, position is 15
446  Simulator::Schedule(Seconds(7.5),
448  this,
449  mob,
450  15);
451 
452  // When InitialPositionIsWaypoint is true, the position allocator creates
453  // the first waypoint, and movement occurs between this origin and the
454  // initial waypoint below at 5 seconds
455  NodeContainer c2;
456  c2.Create(1);
457  MobilityHelper mobility2;
458  Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator>();
459  positionAlloc2->Add(Vector(0.0, 0.0, 0.0));
460  mobility2.SetPositionAllocator(positionAlloc2);
461  mobility2.SetMobilityModel("ns3::WaypointMobilityModel",
462  "InitialPositionIsWaypoint",
463  BooleanValue(true));
464  mobility2.Install(c2);
466  Waypoint wpt3(Seconds(5.0), Vector(20.0, 20.0, 20.0));
467  mob2->AddWaypoint(wpt3);
468  // Move to position 12 at 3 seconds
469  Simulator::Schedule(Seconds(3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob2, 12);
470 
471  Simulator::Run();
472  Simulator::Destroy();
473 }
474 
481 {
482  public:
484 };
485 
487  : TestSuite("mobility", UNIT)
488 {
489  AddTestCase(new WaypointLazyNotifyFalse, TestCase::QUICK);
490  AddTestCase(new WaypointLazyNotifyTrue, TestCase::QUICK);
491  AddTestCase(new WaypointInitialPositionIsWaypoint, TestCase::QUICK);
492  AddTestCase(new WaypointMobilityModelViaHelper, TestCase::QUICK);
493 }
494 
Mobility Test Suite.
Waypoint Initial Position Is Waypoint Test.
Ptr< WaypointMobilityModel > m_mob4
mobility model 4
Ptr< WaypointMobilityModel > m_mob5
mobility model 5
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WaypointMobilityModel > m_mob2
mobility model 2
Ptr< WaypointMobilityModel > m_mob1
mobility model 1
void TestNumWaypoints(Ptr< const WaypointMobilityModel > model, uint32_t num)
Test number of way points.
void TestXPosition(Ptr< const WaypointMobilityModel > model, double expectedXPos)
Text X position function.
Ptr< WaypointMobilityModel > m_mob3
mobility model 3
Test whether course change notifications occur regardless of calls to Update() position (which are tr...
void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)
Course change callback.
void TestXPosition(double expectedXPos)
Test X position function.
int m_courseChanges
course changes
void DoRun() override
Implementation to actually run this TestCase.
Ptr< WaypointMobilityModel > m_mob
modility model
Waypoint Lazy Notify True.
void TestXPosition(double expectedXPos)
Text X position function.
Ptr< WaypointMobilityModel > m_mob
modility model
void DoRun() override
Implementation to actually run this TestCase.
void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)
Course change callback.
Waypoint Mobility Model Via Helper Test.
void DoRun() override
Implementation to actually run this TestCase.
void TestXPosition(Ptr< const WaypointMobilityModel > mob, double expectedXPos)
Text X position function.
Helper class used to assign positions and mobility models to nodes.
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void SetMobilityModel(std::string type, Ts &&... args)
void SetPositionAllocator(Ptr< PositionAllocator > allocator)
Set the position allocator which will be used to allocate the initial position of every node initiali...
Vector GetPosition() const
void SetPosition(const Vector &position)
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
bool SetAttributeFailSafe(std::string name, const AttributeValue &value)
Set a single attribute without raising errors.
Definition: object-base.cc:227
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
a (time, location) pair.
Definition: waypoint.h:36
Waypoint-based mobility model.
void AddWaypoint(const Waypoint &waypoint)
static MobilityTestSuite mobilityTestSuite
Static variable for test initialization.
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
#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:251
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report if ...
Definition: test.h:510
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
static void CourseChangeCallback(std::string path, Ptr< const MobilityModel > model)
This function will be used below as a trace sink, if the command-line argument or default value "useC...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
mobility
Definition: third.py:105