add mobility model test suite with more waypoint mobility model tests
This commit is contained in:
376
src/test/mobility-test-suite.cc
Normal file
376
src/test/mobility-test-suite.cc
Normal file
@@ -0,0 +1,376 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2010 University of Washington
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test suite is intended to test mobility use cases in general,
|
||||
* as typically used by user programs (i.e. with the helper layer
|
||||
* involved).
|
||||
*/
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/scheduler.h"
|
||||
#include "ns3/vector.h"
|
||||
#include "ns3/mobility-model.h"
|
||||
#include "ns3/waypoint-mobility-model.h"
|
||||
#include "ns3/mobility-helper.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
// Test whether course change notifications occur regardless of calls
|
||||
// to Update() position (which are triggered by calls to GetPosition())
|
||||
class WaypointLazyNotifyFalse : public TestCase
|
||||
{
|
||||
public:
|
||||
WaypointLazyNotifyFalse ();
|
||||
virtual ~WaypointLazyNotifyFalse ();
|
||||
|
||||
private:
|
||||
void TestXPosition (double expectedXPos);
|
||||
void CourseChangeCallback (std::string path, Ptr<const MobilityModel> model);
|
||||
virtual bool DoRun (void);
|
||||
Ptr<Node> m_node;
|
||||
Ptr<WaypointMobilityModel> m_mob;
|
||||
int m_courseChanges;
|
||||
};
|
||||
|
||||
WaypointLazyNotifyFalse::WaypointLazyNotifyFalse ()
|
||||
: TestCase ("Test behavior when LazyNotify is false"),
|
||||
m_courseChanges (0)
|
||||
{
|
||||
}
|
||||
|
||||
WaypointLazyNotifyFalse::~WaypointLazyNotifyFalse ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WaypointLazyNotifyFalse::TestXPosition (double expectedXPos)
|
||||
{
|
||||
Vector pos = m_mob->GetPosition ();
|
||||
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void
|
||||
WaypointLazyNotifyFalse::CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
|
||||
{
|
||||
// All waypoints (at 10 second intervals) should trigger a course change
|
||||
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (m_courseChanges * 10.0, Simulator::Now ().GetSeconds (), 0.001, "Course change not notified correctly", __FILE__, __LINE__);
|
||||
m_courseChanges++;
|
||||
}
|
||||
|
||||
bool
|
||||
WaypointLazyNotifyFalse::DoRun (void)
|
||||
{
|
||||
m_node = CreateObject<Node> ();
|
||||
m_mob = CreateObject<WaypointMobilityModel> ();
|
||||
// LazyNotify should by default be false
|
||||
m_node->AggregateObject (m_mob);
|
||||
Waypoint wpt (Seconds (0.0), Vector (0.0, 0.0, 0.0));
|
||||
m_mob->AddWaypoint (wpt);
|
||||
Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0));
|
||||
m_mob->AddWaypoint (wpt2);
|
||||
Waypoint wpt3 (Seconds (20.0), Vector (20.0, 20.0, 20.0));
|
||||
m_mob->AddWaypoint (wpt3);
|
||||
|
||||
Simulator::Schedule (Seconds (5.0), &WaypointLazyNotifyFalse::TestXPosition, this, 5);
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class WaypointLazyNotifyTrue : public TestCase
|
||||
{
|
||||
public:
|
||||
WaypointLazyNotifyTrue ();
|
||||
virtual ~WaypointLazyNotifyTrue ();
|
||||
|
||||
private:
|
||||
void TestXPosition (double expectedXPos);
|
||||
void CourseChangeCallback (std::string path, Ptr<const MobilityModel> model);
|
||||
virtual bool DoRun (void);
|
||||
Ptr<Node> m_node;
|
||||
Ptr<WaypointMobilityModel> m_mob;
|
||||
};
|
||||
|
||||
WaypointLazyNotifyTrue::WaypointLazyNotifyTrue ()
|
||||
: TestCase ("Test behavior when LazyNotify is true")
|
||||
{
|
||||
}
|
||||
|
||||
WaypointLazyNotifyTrue::~WaypointLazyNotifyTrue ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WaypointLazyNotifyTrue::TestXPosition (double expectedXPos)
|
||||
{
|
||||
Vector pos = m_mob->GetPosition ();
|
||||
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void
|
||||
WaypointLazyNotifyTrue::CourseChangeCallback (std::string path, Ptr<const MobilityModel> model)
|
||||
{
|
||||
// This should trigger at time 15 only, since that is the first time that
|
||||
// position is updated due to LazyNotify
|
||||
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (15, Simulator::Now ().GetSeconds (), 0.001, "Course change not notified correctly", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
bool
|
||||
WaypointLazyNotifyTrue::DoRun (void)
|
||||
{
|
||||
m_node = CreateObject<Node> ();
|
||||
m_mob = CreateObject<WaypointMobilityModel> ();
|
||||
m_mob->SetAttributeFailSafe ("LazyNotify", BooleanValue (true));
|
||||
m_node->AggregateObject (m_mob);
|
||||
Waypoint wpt (Seconds (0.0), Vector (0.0, 0.0, 0.0));
|
||||
m_mob->AddWaypoint (wpt);
|
||||
Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0));
|
||||
m_mob->AddWaypoint (wpt2);
|
||||
Waypoint wpt3 (Seconds (20.0), Vector (20.0, 20.0, 20.0));
|
||||
m_mob->AddWaypoint (wpt3);
|
||||
|
||||
Simulator::Schedule (Seconds (15.0), &WaypointLazyNotifyTrue::TestXPosition, this, 15);
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class WaypointInitialPositionIsWaypoint : public TestCase
|
||||
{
|
||||
public:
|
||||
WaypointInitialPositionIsWaypoint ();
|
||||
virtual ~WaypointInitialPositionIsWaypoint ();
|
||||
|
||||
private:
|
||||
void TestXPosition (Ptr<const WaypointMobilityModel> model, double expectedXPos);
|
||||
void TestNumWaypoints (Ptr<const WaypointMobilityModel> model, uint32_t num);
|
||||
virtual bool DoRun (void);
|
||||
Ptr<WaypointMobilityModel> m_mob1;
|
||||
Ptr<WaypointMobilityModel> m_mob2;
|
||||
Ptr<WaypointMobilityModel> m_mob3;
|
||||
Ptr<WaypointMobilityModel> m_mob4;
|
||||
Ptr<WaypointMobilityModel> m_mob5;
|
||||
};
|
||||
|
||||
WaypointInitialPositionIsWaypoint::WaypointInitialPositionIsWaypoint ()
|
||||
: TestCase ("Test behavior of Waypoint InitialPositionIsWaypoint")
|
||||
{
|
||||
}
|
||||
|
||||
WaypointInitialPositionIsWaypoint::~WaypointInitialPositionIsWaypoint ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WaypointInitialPositionIsWaypoint::TestXPosition (Ptr<const WaypointMobilityModel> model, double expectedXPos)
|
||||
{
|
||||
Vector pos = model->GetPosition ();
|
||||
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void
|
||||
WaypointInitialPositionIsWaypoint::TestNumWaypoints (Ptr<const WaypointMobilityModel> model, uint32_t num)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ (model->WaypointsLeft (), num, "Unexpected number of waypoints left");
|
||||
}
|
||||
|
||||
bool
|
||||
WaypointInitialPositionIsWaypoint::DoRun (void)
|
||||
{
|
||||
// Case 1: InitialPositionIsWaypoint == false, and we call SetPosition
|
||||
// without any waypoints added. There should be no waypoints after
|
||||
// time 0
|
||||
m_mob1 = CreateObject<WaypointMobilityModel> ();
|
||||
m_mob1->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (false));
|
||||
m_mob1->SetPosition (Vector (10.0, 10.0, 10.0));
|
||||
// At time 1s, there should be no waypoints
|
||||
Simulator::Schedule (Seconds (1.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob1, 0);
|
||||
// At time 15s, the model should still be at x position 10.0
|
||||
Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob1, 10.0);
|
||||
|
||||
// Case 2: InitialPositionIsWaypoint == false, and we call SetPosition
|
||||
// after adding a waypoint.
|
||||
m_mob2 = CreateObject<WaypointMobilityModel> ();
|
||||
m_mob2->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (false));
|
||||
Waypoint wpt21 (Seconds (5.0), Vector (15.0, 15.0, 15.0));
|
||||
m_mob2->AddWaypoint (wpt21);
|
||||
Waypoint wpt22 (Seconds (10.0), Vector (20.0, 20.0, 20.0));
|
||||
m_mob2->AddWaypoint (wpt22);
|
||||
m_mob2->SetPosition (Vector (10.0, 10.0, 10.0));
|
||||
// At time 3, no waypoints have been hit, so position should be 10 and
|
||||
// numWaypoints should be 2, or 1 excluding the next one
|
||||
Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob2, 10.0);
|
||||
Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob2, 1);
|
||||
// At time 8, check that X position is 18 (i.e. position is interpolating
|
||||
// between 15 and 20) and there is one waypoint left, but we exclude
|
||||
// the next one so we test for zero waypoints
|
||||
Simulator::Schedule (Seconds (8.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob2, 18.0);
|
||||
Simulator::Schedule (Seconds (8.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob2, 0);
|
||||
|
||||
// Case 3: InitialPositionIsWaypoint == true, and we call SetPosition
|
||||
// without any waypoints added.
|
||||
m_mob3 = CreateObject<WaypointMobilityModel> ();
|
||||
m_mob3->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true));
|
||||
m_mob3->SetPosition (Vector (10.0, 10.0, 10.0));
|
||||
// At time 1s, there should be zero waypoints not counting the next one
|
||||
Simulator::Schedule (Seconds (1.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob3, 0);
|
||||
// At time 15s, the model should still be at x position 10.0
|
||||
Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob3, 10.0);
|
||||
|
||||
// Case 4: InitialPositionIsWaypoint == true, and we call SetPosition
|
||||
// after adding a waypoint.
|
||||
m_mob4 = CreateObject<WaypointMobilityModel> ();
|
||||
m_mob4->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true));
|
||||
Waypoint wpt41 (Seconds (5.0), Vector (15.0, 15.0, 15.0));
|
||||
m_mob4->AddWaypoint (wpt41);
|
||||
Waypoint wpt42 (Seconds (10.0), Vector (20.0, 20.0, 20.0));
|
||||
m_mob4->AddWaypoint (wpt42);
|
||||
// Here, SetPosition() is called after waypoints have been added. In
|
||||
// this case, the initial position is set until the time of the first
|
||||
// waypoint, at which time it jumps to the waypoint and begins moving
|
||||
m_mob4->SetPosition (Vector (10.0, 10.0, 10.0));
|
||||
// At time 3, position should be fixed still at 10
|
||||
Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 10.0);
|
||||
Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestNumWaypoints, this, m_mob4, 1);
|
||||
// At time 6, we should be moving between 15 and 20
|
||||
Simulator::Schedule (Seconds (6.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 16.0);
|
||||
// At time 15, we should be fixed at 20
|
||||
Simulator::Schedule (Seconds (15.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob4, 20.0);
|
||||
|
||||
// case 5: If waypoint and SetPosition both called at time 0,
|
||||
// SetPosition takes precedence
|
||||
m_mob5 = CreateObject<WaypointMobilityModel> ();
|
||||
m_mob5->SetAttributeFailSafe ("InitialPositionIsWaypoint", BooleanValue (true));
|
||||
// Note: The below statement would result in a crash, because it would
|
||||
// violate the rule that waypoints must increase in start time
|
||||
// m_mob5->SetPosition (Vector (10.0, 10.0, 10.0));
|
||||
Waypoint wpt51 (Seconds (0.0), Vector (200.0, 200.0, 200.0));
|
||||
m_mob5->AddWaypoint (wpt51);
|
||||
Waypoint wpt52 (Seconds (5.0), Vector (15.0, 15.0, 15.0));
|
||||
m_mob5->AddWaypoint (wpt52);
|
||||
Waypoint wpt53 (Seconds (10.0), Vector (20.0, 20.0, 20.0));
|
||||
m_mob5->AddWaypoint (wpt53);
|
||||
// Here, since waypoints already exist, the below SetPosition will cancel
|
||||
// out wpt51 above, and model will stay at initial position until time 5
|
||||
m_mob5->SetPosition (Vector (10.0, 10.0, 10.0));
|
||||
Simulator::Schedule (Seconds (3.0), &WaypointInitialPositionIsWaypoint::TestXPosition, this, m_mob5, 10.0);
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class WaypointMobilityModelViaHelper : public TestCase
|
||||
{
|
||||
public:
|
||||
WaypointMobilityModelViaHelper ();
|
||||
virtual ~WaypointMobilityModelViaHelper ();
|
||||
|
||||
private:
|
||||
void TestXPosition (Ptr<const WaypointMobilityModel> mob, double expectedXPos);
|
||||
virtual bool DoRun (void);
|
||||
};
|
||||
|
||||
WaypointMobilityModelViaHelper::WaypointMobilityModelViaHelper ()
|
||||
: TestCase ("Test behavior using MobilityHelper and PositionAllocator")
|
||||
{
|
||||
}
|
||||
|
||||
WaypointMobilityModelViaHelper::~WaypointMobilityModelViaHelper ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WaypointMobilityModelViaHelper::TestXPosition (Ptr<const WaypointMobilityModel> mob, double expectedXPos)
|
||||
{
|
||||
Vector pos = mob->GetPosition ();
|
||||
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (pos.x, expectedXPos, 0.001, "Position not equal", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// WaypointMobilityModel tests using the helper
|
||||
bool
|
||||
WaypointMobilityModelViaHelper::DoRun (void)
|
||||
{
|
||||
NodeContainer c;
|
||||
c.Create (1);
|
||||
MobilityHelper mobility;
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
|
||||
mobility.SetPositionAllocator (positionAlloc);
|
||||
// When InitialPositionIsWaypoint is false (default), the position
|
||||
// set by the position allocator is ignored. The first waypoint set will
|
||||
// set the initial position (with velocity 0 until first waypoint time)
|
||||
mobility.SetMobilityModel ("ns3::WaypointMobilityModel",
|
||||
"InitialPositionIsWaypoint", BooleanValue (false));
|
||||
mobility.Install (c);
|
||||
|
||||
// Get back a pointer to this
|
||||
Ptr<WaypointMobilityModel> mob = c.Get (0)->GetObject<WaypointMobilityModel> ();
|
||||
// Waypoint added at time 0 will override initial position
|
||||
Waypoint wpt (Seconds (5.0), Vector (20.0, 20.0, 20.0));
|
||||
Waypoint wpt2 (Seconds (10.0), Vector (10.0, 10.0, 10.0));
|
||||
mob->AddWaypoint (wpt);
|
||||
mob->AddWaypoint (wpt2);
|
||||
// At time 3 (before first waypoint, position is 20
|
||||
Simulator::Schedule (Seconds (3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 20);
|
||||
// At time 7.5 (midway between points 1 and 2, position is 15
|
||||
Simulator::Schedule (Seconds (7.5), &WaypointMobilityModelViaHelper::TestXPosition, this, mob, 15);
|
||||
|
||||
// When InitialPositionIsWaypoint is true, the position allocator creates
|
||||
// the first waypoint, and movement occurs between this origin and the
|
||||
// initial waypoint below at 5 seconds
|
||||
NodeContainer c2;
|
||||
c2.Create (1);
|
||||
MobilityHelper mobility2;
|
||||
Ptr<ListPositionAllocator> positionAlloc2 = CreateObject<ListPositionAllocator> ();
|
||||
positionAlloc2->Add (Vector (0.0, 0.0, 0.0));
|
||||
mobility2.SetPositionAllocator (positionAlloc2);
|
||||
mobility2.SetMobilityModel ("ns3::WaypointMobilityModel",
|
||||
"InitialPositionIsWaypoint", BooleanValue (true));
|
||||
mobility2.Install (c2);
|
||||
Ptr<WaypointMobilityModel> mob2 = c2.Get (0)->GetObject<WaypointMobilityModel> ();
|
||||
Waypoint wpt3 (Seconds (5.0), Vector (20.0, 20.0, 20.0));
|
||||
mob2->AddWaypoint (wpt3);
|
||||
// Move to position 12 at 3 seconds
|
||||
Simulator::Schedule (Seconds (3), &WaypointMobilityModelViaHelper::TestXPosition, this, mob2, 12);
|
||||
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
return GetErrorStatus ();
|
||||
}
|
||||
|
||||
class MobilityTestSuite : public TestSuite
|
||||
{
|
||||
public:
|
||||
MobilityTestSuite ();
|
||||
};
|
||||
|
||||
MobilityTestSuite::MobilityTestSuite ()
|
||||
: TestSuite ("mobility", BVT)
|
||||
{
|
||||
AddTestCase (new WaypointLazyNotifyFalse);
|
||||
AddTestCase (new WaypointLazyNotifyTrue);
|
||||
AddTestCase (new WaypointInitialPositionIsWaypoint);
|
||||
AddTestCase (new WaypointMobilityModelViaHelper);
|
||||
}
|
||||
|
||||
static MobilityTestSuite mobilityTestSuite;
|
||||
@@ -8,6 +8,7 @@ def build(bld):
|
||||
test.source = [
|
||||
'sample-test-suite.cc',
|
||||
'error-model-test-suite.cc',
|
||||
'mobility-test-suite.cc',
|
||||
]
|
||||
|
||||
headers = bld.new_task_gen('ns3header')
|
||||
|
||||
Reference in New Issue
Block a user