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
34using namespace ns3;
35
44{
45 public:
47 ~WaypointLazyNotifyFalse() override;
48
49 private:
54 void TestXPosition(double expectedXPos);
60 void CourseChangeCallback(std::string path, Ptr<const MobilityModel> model);
61 void DoRun() override;
65};
66
68 : TestCase("Test behavior when LazyNotify is false"),
69 m_courseChanges(0)
70{
71}
72
74{
75}
76
77void
79{
80 Vector pos = m_mob->GetPosition();
81 NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
82}
83
84void
86{
87 // All waypoints (at 10 second intervals) should trigger a course change
89 Simulator::Now().GetSeconds(),
90 0.001,
91 "Course change not notified correctly");
93}
94
95void
97{
98 m_node = CreateObject<Node>();
99 m_mob = CreateObject<WaypointMobilityModel>();
100 // LazyNotify should by default be false
102 Waypoint wpt(Seconds(0.0), Vector(0.0, 0.0, 0.0));
103 m_mob->AddWaypoint(wpt);
104 Waypoint wpt2(Seconds(10.0), Vector(10.0, 10.0, 10.0));
105 m_mob->AddWaypoint(wpt2);
106 Waypoint wpt3(Seconds(20.0), Vector(20.0, 20.0, 20.0));
107 m_mob->AddWaypoint(wpt3);
108
109 Simulator::Schedule(Seconds(5.0), &WaypointLazyNotifyFalse::TestXPosition, this, 5);
110 Simulator::Run();
111 Simulator::Destroy();
112}
113
121{
122 public:
124 ~WaypointLazyNotifyTrue() override;
125
126 private:
131 void TestXPosition(double expectedXPos);
137 void CourseChangeCallback(std::string path, Ptr<const MobilityModel> model);
138 void DoRun() override;
141};
142
144 : TestCase("Test behavior when LazyNotify is true")
145{
146}
147
149{
150}
151
152void
154{
155 Vector pos = m_mob->GetPosition();
156 NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
157}
158
159void
161{
162 // This should trigger at time 15 only, since that is the first time that
163 // position is updated due to LazyNotify
165 Simulator::Now().GetSeconds(),
166 0.001,
167 "Course change not notified correctly");
168}
169
170void
172{
173 m_node = CreateObject<Node>();
174 m_mob = CreateObject<WaypointMobilityModel>();
175 m_mob->SetAttributeFailSafe("LazyNotify", BooleanValue(true));
177 Waypoint wpt(Seconds(0.0), Vector(0.0, 0.0, 0.0));
178 m_mob->AddWaypoint(wpt);
179 Waypoint wpt2(Seconds(10.0), Vector(10.0, 10.0, 10.0));
180 m_mob->AddWaypoint(wpt2);
181 Waypoint wpt3(Seconds(20.0), Vector(20.0, 20.0, 20.0));
182 m_mob->AddWaypoint(wpt3);
183
184 Simulator::Schedule(Seconds(15.0), &WaypointLazyNotifyTrue::TestXPosition, this, 15);
185 Simulator::Run();
186 Simulator::Destroy();
187}
188
196{
197 public:
200
201 private:
207 void TestXPosition(Ptr<const WaypointMobilityModel> model, double expectedXPos);
214 void DoRun() override;
220};
221
223 : TestCase("Test behavior of Waypoint InitialPositionIsWaypoint")
224{
225}
226
228{
229}
230
231void
233 double expectedXPos)
234{
235 Vector pos = model->GetPosition();
236 NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
237}
238
239void
241 uint32_t num)
242{
243 NS_TEST_EXPECT_MSG_EQ(model->WaypointsLeft(), num, "Unexpected number of waypoints left");
244}
245
246void
248{
249 // Case 1: InitialPositionIsWaypoint == false, and we call SetPosition
250 // without any waypoints added. There should be no waypoints after
251 // time 0
252 m_mob1 = CreateObject<WaypointMobilityModel>();
253 m_mob1->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(false));
254 m_mob1->SetPosition(Vector(10.0, 10.0, 10.0));
255 // At time 1s, there should be no waypoints
256 Simulator::Schedule(Seconds(1.0),
258 this,
259 m_mob1,
260 0);
261 // At time 15s, the model should still be at x position 10.0
262 Simulator::Schedule(Seconds(15.0),
264 this,
265 m_mob1,
266 10.0);
267
268 // Case 2: InitialPositionIsWaypoint == false, and we call SetPosition
269 // after adding a waypoint.
270 m_mob2 = CreateObject<WaypointMobilityModel>();
271 m_mob2->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(false));
272 Waypoint wpt21(Seconds(5.0), Vector(15.0, 15.0, 15.0));
273 m_mob2->AddWaypoint(wpt21);
274 Waypoint wpt22(Seconds(10.0), Vector(20.0, 20.0, 20.0));
275 m_mob2->AddWaypoint(wpt22);
276 m_mob2->SetPosition(Vector(10.0, 10.0, 10.0));
277 // At time 3, no waypoints have been hit, so position should be 10 and
278 // numWaypoints should be 2, or 1 excluding the next one
279 Simulator::Schedule(Seconds(3.0),
281 this,
282 m_mob2,
283 10.0);
284 Simulator::Schedule(Seconds(3.0),
286 this,
287 m_mob2,
288 1);
289 // At time 8, check that X position is 18 (i.e. position is interpolating
290 // between 15 and 20) and there is one waypoint left, but we exclude
291 // the next one so we test for zero waypoints
292 Simulator::Schedule(Seconds(8.0),
294 this,
295 m_mob2,
296 18.0);
297 Simulator::Schedule(Seconds(8.0),
299 this,
300 m_mob2,
301 0);
302
303 // Case 3: InitialPositionIsWaypoint == true, and we call SetPosition
304 // without any waypoints added.
305 m_mob3 = CreateObject<WaypointMobilityModel>();
306 m_mob3->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(true));
307 m_mob3->SetPosition(Vector(10.0, 10.0, 10.0));
308 // At time 1s, there should be zero waypoints not counting the next one
309 Simulator::Schedule(Seconds(1.0),
311 this,
312 m_mob3,
313 0);
314 // At time 15s, the model should still be at x position 10.0
315 Simulator::Schedule(Seconds(15.0),
317 this,
318 m_mob3,
319 10.0);
320
321 // Case 4: InitialPositionIsWaypoint == true, and we call SetPosition
322 // after adding a waypoint.
323 m_mob4 = CreateObject<WaypointMobilityModel>();
324 m_mob4->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(true));
325 Waypoint wpt41(Seconds(5.0), Vector(15.0, 15.0, 15.0));
326 m_mob4->AddWaypoint(wpt41);
327 Waypoint wpt42(Seconds(10.0), Vector(20.0, 20.0, 20.0));
328 m_mob4->AddWaypoint(wpt42);
329 // Here, SetPosition() is called after waypoints have been added. In
330 // this case, the initial position is set until the time of the first
331 // waypoint, at which time it jumps to the waypoint and begins moving
332 m_mob4->SetPosition(Vector(10.0, 10.0, 10.0));
333 // At time 3, position should be fixed still at 10
334 Simulator::Schedule(Seconds(3.0),
336 this,
337 m_mob4,
338 10.0);
339 Simulator::Schedule(Seconds(3.0),
341 this,
342 m_mob4,
343 1);
344 // At time 6, we should be moving between 15 and 20
345 Simulator::Schedule(Seconds(6.0),
347 this,
348 m_mob4,
349 16.0);
350 // At time 15, we should be fixed at 20
351 Simulator::Schedule(Seconds(15.0),
353 this,
354 m_mob4,
355 20.0);
356
357 // case 5: If waypoint and SetPosition both called at time 0,
358 // SetPosition takes precedence
359 m_mob5 = CreateObject<WaypointMobilityModel>();
360 m_mob5->SetAttributeFailSafe("InitialPositionIsWaypoint", BooleanValue(true));
361 // Note: The below statement would result in a crash, because it would
362 // violate the rule that waypoints must increase in start time
363 // m_mob5->SetPosition (Vector (10.0, 10.0, 10.0));
364 Waypoint wpt51(Seconds(0.0), Vector(200.0, 200.0, 200.0));
365 m_mob5->AddWaypoint(wpt51);
366 Waypoint wpt52(Seconds(5.0), Vector(15.0, 15.0, 15.0));
367 m_mob5->AddWaypoint(wpt52);
368 Waypoint wpt53(Seconds(10.0), Vector(20.0, 20.0, 20.0));
369 m_mob5->AddWaypoint(wpt53);
370 // Here, since waypoints already exist, the below SetPosition will cancel
371 // out wpt51 above, and model will stay at initial position until time 5
372 m_mob5->SetPosition(Vector(10.0, 10.0, 10.0));
373 Simulator::Schedule(Seconds(3.0),
375 this,
376 m_mob5,
377 10.0);
378
379 Simulator::Run();
380 Simulator::Destroy();
381}
382
390{
391 public:
394
395 private:
401 void TestXPosition(Ptr<const WaypointMobilityModel> mob, double expectedXPos);
402 void DoRun() override;
403};
404
406 : TestCase("Test behavior using MobilityHelper and PositionAllocator")
407{
408}
409
411{
412}
413
414void
416 double expectedXPos)
417{
418 Vector pos = mob->GetPosition();
419 NS_TEST_EXPECT_MSG_EQ_TOL(pos.x, expectedXPos, 0.001, "Position not equal");
420}
421
422// WaypointMobilityModel tests using the helper
423void
425{
427 c.Create(1);
429 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
430 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
431 mobility.SetPositionAllocator(positionAlloc);
432 // When InitialPositionIsWaypoint is false (default), the position
433 // set by the position allocator is ignored. The first waypoint set will
434 // set the initial position (with velocity 0 until first waypoint time)
435 mobility.SetMobilityModel("ns3::WaypointMobilityModel",
436 "InitialPositionIsWaypoint",
437 BooleanValue(false));
438 mobility.Install(c);
439
440 // Get back a pointer to this
442 // Waypoint added at time 0 will override initial position
443 Waypoint wpt(Seconds(5.0), Vector(20.0, 20.0, 20.0));
444 Waypoint wpt2(Seconds(10.0), Vector(10.0, 10.0, 10.0));
445 mob->AddWaypoint(wpt);
446 mob->AddWaypoint(wpt2);
447 // At time 3 (before first waypoint, position is 20
448 Simulator::Schedule(Seconds(3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 20);
449 // At time 7.5 (midway between points 1 and 2, position is 15
450 Simulator::Schedule(Seconds(7.5),
452 this,
453 mob,
454 15);
455
456 // When InitialPositionIsWaypoint is true, the position allocator creates
457 // the first waypoint, and movement occurs between this origin and the
458 // initial waypoint below at 5 seconds
459 NodeContainer c2;
460 c2.Create(1);
461 MobilityHelper mobility2;
462 Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator>();
463 positionAlloc2->Add(Vector(0.0, 0.0, 0.0));
464 mobility2.SetPositionAllocator(positionAlloc2);
465 mobility2.SetMobilityModel("ns3::WaypointMobilityModel",
466 "InitialPositionIsWaypoint",
467 BooleanValue(true));
468 mobility2.Install(c2);
470 Waypoint wpt3(Seconds(5.0), Vector(20.0, 20.0, 20.0));
471 mob2->AddWaypoint(wpt3);
472 // Move to position 12 at 3 seconds
473 Simulator::Schedule(Seconds(3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob2, 12);
474
475 Simulator::Run();
476 Simulator::Destroy();
477}
478
486{
487 public:
489};
490
492 : TestSuite("mobility", UNIT)
493{
494 AddTestCase(new WaypointLazyNotifyFalse, TestCase::QUICK);
495 AddTestCase(new WaypointLazyNotifyTrue, TestCase::QUICK);
497 AddTestCase(new WaypointMobilityModelViaHelper, TestCase::QUICK);
498}
499
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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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:281
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:78
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:305
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)
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
#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:1338
static MobilityTestSuite mobilityTestSuite
the test suite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
mobility
Definition: third.py:96