diff --git a/model/leo-circular-orbit-mobility-model.cc b/model/leo-circular-orbit-mobility-model.cc index 116e28a..9e8730f 100644 --- a/model/leo-circular-orbit-mobility-model.cc +++ b/model/leo-circular-orbit-mobility-model.cc @@ -19,6 +19,7 @@ LeoCircularOrbitMobilityModel::GetTypeId () static TypeId tid = TypeId ("ns3::LeoCircularOrbitMobilityModel") .SetParent () .SetGroupName ("Leo") + .AddConstructor () .AddAttribute ("Altitude", "A height from the earth's surface in meters", DoubleValue (1000.0), @@ -32,11 +33,16 @@ LeoCircularOrbitMobilityModel::GetTypeId () MakeDoubleAccessor (&LeoCircularOrbitMobilityModel::SetInclination, &LeoCircularOrbitMobilityModel::GetInclination), MakeDoubleChecker ()) + .AddAttribute ("Precision", + "The time precision with which to compute position updates. 0 means arbitrary precision", + TimeValue (Seconds (1)), + MakeTimeAccessor (&LeoCircularOrbitMobilityModel::m_precision), + MakeTimeChecker ()) ; return tid; } -LeoCircularOrbitMobilityModel::LeoCircularOrbitMobilityModel() : MobilityModel (), m_latitude (0.0), m_offset (0.0) +LeoCircularOrbitMobilityModel::LeoCircularOrbitMobilityModel() : MobilityModel (), m_latitude (0.0), m_offset (0.0), m_position () { NS_LOG_FUNCTION_NOARGS (); } @@ -107,13 +113,39 @@ LeoCircularOrbitMobilityModel::RotatePlane (double a, const Vector3D &x) const } Vector -LeoCircularOrbitMobilityModel::DoGetPosition (void) const +LeoCircularOrbitMobilityModel::CalcPosition (Time t) const { Vector3D x = Product (m_orbitHeight, Vector3D (cos (m_inclination) * cos (m_latitude), cos (m_inclination) * sin (m_latitude), sin (m_inclination))); - return RotatePlane (GetProgress (Simulator::Now ()), x); + return RotatePlane (GetProgress (t), x); +} + +Vector LeoCircularOrbitMobilityModel::Update () +{ + m_plane = PlaneNorm (); + + m_position = CalcPosition (Simulator::Now ()); + NotifyCourseChange (); + + if (m_precision > Seconds (0)) + { + Simulator::Schedule (m_precision, &LeoCircularOrbitMobilityModel::Update, this); + } + + return m_position; +} + +Vector +LeoCircularOrbitMobilityModel::DoGetPosition (void) const +{ + if (m_precision == Time (0)) + { + // Notice: NotifyCourseChange () will not be called + return CalcPosition (Simulator::Now ()); + } + return m_position; } void @@ -125,7 +157,7 @@ LeoCircularOrbitMobilityModel::DoSetPosition (const Vector &position) // SetPostion m_latitude = position.x; m_offset = position.y; - m_plane = PlaneNorm (); + Update (); } double LeoCircularOrbitMobilityModel::GetAltitude () const @@ -136,7 +168,7 @@ double LeoCircularOrbitMobilityModel::GetAltitude () const void LeoCircularOrbitMobilityModel::SetAltitude (double h) { m_orbitHeight = LEO_EARTH_RAD_M + h; - m_plane = PlaneNorm (); + Update (); } double LeoCircularOrbitMobilityModel::GetInclination () const @@ -148,7 +180,7 @@ void LeoCircularOrbitMobilityModel::SetInclination (double incl) { NS_ASSERT_MSG (incl != 0.0, "Plane must not be orthogonal to axis"); m_inclination = (incl / 180) * M_PI; - m_plane = PlaneNorm (); + Update (); } }; diff --git a/model/leo-circular-orbit-mobility-model.h b/model/leo-circular-orbit-mobility-model.h index c23993d..f8df411 100644 --- a/model/leo-circular-orbit-mobility-model.h +++ b/model/leo-circular-orbit-mobility-model.h @@ -70,6 +70,16 @@ private: */ Vector3D m_plane; + /** + * Current position + */ + Vector3D m_position; + + /** + * Time precision for positions + */ + Time m_precision; + /** * \return the current position. */ @@ -94,6 +104,15 @@ private: * Advances a satellite by a degrees on the orbital plane */ Vector3D RotatePlane (double a, const Vector3D &x) const; + + /** + * Calculate the position at time + * + * \param t time + */ + Vector CalcPosition (Time t) const; + + Vector Update (); }; } diff --git a/model/leo-circular-orbit-position-allocator.cc b/model/leo-circular-orbit-position-allocator.cc index 04fc183..529ff66 100644 --- a/model/leo-circular-orbit-position-allocator.cc +++ b/model/leo-circular-orbit-position-allocator.cc @@ -1,5 +1,7 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +#include "math.h" + #include "ns3/integer.h" #include "leo-circular-orbit-position-allocator.h" @@ -25,12 +27,12 @@ LeoCircularOrbitAllocator::GetTypeId (void) "The number of orbits", IntegerValue (1), MakeIntegerAccessor (&LeoCircularOrbitAllocator::m_numOrbits), - MakeIntegerChecker ()) + MakeIntegerChecker ()) .AddAttribute ("NumSatellites", "The number of satellites per orbit", IntegerValue (1), MakeIntegerAccessor (&LeoCircularOrbitAllocator::m_numSatellites), - MakeIntegerChecker ()) + MakeIntegerChecker ()) ; return tid; } @@ -44,9 +46,17 @@ LeoCircularOrbitAllocator::AssignStreams (int64_t stream) Vector LeoCircularOrbitAllocator::GetNext () const { - return Vector (180 * ((double) m_lastOrbit / (double) m_numOrbits), - 360.0 * ((double) m_lastSatellite / (double) m_numSatellites), + Vector next = Vector (M_PI * (m_lastOrbit / (double) m_numOrbits), + 2 * M_PI * (m_lastSatellite / (double) m_numSatellites), 0); + + m_lastSatellite = (m_lastSatellite + 1) % m_numSatellites; + if (m_lastSatellite >= m_numSatellites) + { + m_lastOrbit = (m_lastOrbit + 1) % m_numOrbits; + } + + return next; } }; diff --git a/test/leo-orbit-test-suite.cc b/test/leo-orbit-test-suite.cc index b6da59b..a8c7359 100644 --- a/test/leo-orbit-test-suite.cc +++ b/test/leo-orbit-test-suite.cc @@ -2,7 +2,10 @@ #include "ns3/core-module.h" #include "ns3/node-container.h" +#include "ns3/mobility-helper.h" #include "ns3/test.h" +#include "ns3/integer.h" +#include "ns3/nstime.h" #include "../model/leo-circular-orbit-mobility-model.h" @@ -60,6 +63,7 @@ private: Vector pos = mob->GetPosition (); Simulator::Schedule (Seconds (100.0), &LeoOrbitProgressTestCase::TestLengthPosition, this, LEO_EARTH_RAD_M, pos.x, mob); + Simulator::Stop (Seconds (101.0)); Simulator::Run (); Simulator::Destroy (); } @@ -107,6 +111,45 @@ private: } }; +class LeoOrbitTracingTestCase : public TestCase +{ +public: + LeoOrbitTracingTestCase () : TestCase ("Test tracing of position changes") {} + virtual ~LeoOrbitTracingTestCase () {} + static void CourseChange (std::string context, Ptr position) + { + Vector pos = position->GetPosition (); + std::cout << Simulator::Now () << ", pos=" << position << ", x=" << pos.x << ", y=" << pos.y + << ", z=" << pos.z << std::endl; + } +private: + virtual void DoRun (void) + { + Ptr mob = CreateObject (); + mob->SetAttribute ("Altitude", DoubleValue (1000.0)); + mob->SetAttribute ("Inclination", DoubleValue (20.0)); + mob->SetAttribute ("Precision", TimeValue (Seconds (10))); + + NodeContainer c; + c.Create (10000); + + MobilityHelper mobility; + mobility.SetPositionAllocator ("ns3::LeoCircularOrbitPostionAllocator", + "NumOrbits", IntegerValue (100), + "NumSatellites", IntegerValue (100)); + mobility.SetMobilityModel ("ns3::LeoCircularOrbitMobilityModel"); + mobility.Install (c); + + Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", + MakeCallback (&CourseChange)); + + Simulator::Stop (Seconds (100.0)); + Simulator::Run (); + Simulator::Destroy (); + } +}; + + class LeoOrbitTestSuite : TestSuite { public: @@ -116,6 +159,7 @@ public: AddTestCase (new LeoOrbitProgressTestCase, TestCase::QUICK); AddTestCase (new LeoOrbitLatitudeTestCase, TestCase::QUICK); AddTestCase (new LeoOrbitOffsetTestCase, TestCase::QUICK); + AddTestCase (new LeoOrbitTracingTestCase, TestCase::EXTENSIVE); } };