43#include "ns3/channel-condition-model.h"
44#include "ns3/core-module.h"
45#include "ns3/geocentric-constant-position-mobility-model.h"
46#include "ns3/geocentric-ecef-mobility-model.h"
47#include "ns3/geographic-positions.h"
48#include "ns3/isotropic-antenna-model.h"
49#include "ns3/leo-orbit-node-helper.h"
50#include "ns3/mobility-module.h"
51#include "ns3/three-gpp-propagation-loss-model.h"
52#include "ns3/uniform-planar-array.h"
111 Vector groundNodePosGEO,
112 Vector groundNodePosECEF,
113 std::ostream* traceStream)
138 const double azimuth,
139 const double inclination)
const;
178 const auto satelliteNodePositionECEF = mobility->GetPosition();
182 const Vector satelliteNodePositionGEO =
187 const Vector translatedTopo =
189 satelliteNodePositionGEO,
193 const Angles angles(translatedTopo);
210 const double azimuth,
211 const double inclination)
const
215 const Vector nodePosGEO =
221 const double orientationVectorLength = (
groundStation.posECEF - nodePosECEF).GetLength();
224 double s = std::sin(inclination);
227 const Vector newPointUnitVectorInTopo(s * std::cos(azimuth),
228 s * std::sin(azimuth),
229 std::cos(inclination));
232 const Vector newPointWithMagnitudeTopo = newPointUnitVectorInTopo * orientationVectorLength;
235 const Vector newPointWithMagnitudeGEO =
241 const Vector newPointWithMagnitudeECEF =
243 newPointWithMagnitudeGEO.y,
244 newPointWithMagnitudeGEO.z,
247 return newPointWithMagnitudeECEF;
259 const Vector satPosECEF = mob->GetPosition();
263 static bool headerPrinted =
false;
269 (*m_traceStream) <<
"Time,Satellite,x,y,z,Speed" << std::endl;
272 (*m_traceStream) <<
"Time,Satellite,x,y,z,x_2,y_2,z_2" << std::endl;
276 <<
"Time,Satellite,x,y,z,x_2,y_2,z_2,PathLoss_dB,SlantDistance_m,ElevationAngle_deg"
280 headerPrinted =
true;
290 newP =
GeneratePoint(satPosECEF, ant->GetAlpha(), ant->GetBeta());
297 (*m_traceStream) <<
Simulator::Now() <<
"," << node->GetId() <<
"," << satPosECEF.x <<
","
298 << satPosECEF.y <<
"," << satPosECEF.z <<
","
299 << mob->GetVelocity().GetLength() << std::endl;
304 (*m_traceStream) <<
Simulator::Now() <<
"," << node->GetId() <<
"," << satPosECEF.x <<
","
305 << satPosECEF.y <<
"," << satPosECEF.z <<
"," << newP.x <<
"," << newP.y
306 <<
"," << newP.z << std::endl;
312 double slantDistance = (satPosECEF -
groundStation.posECEF).GetLength();
327 Angles angles(topoVector);
331 double pathLossDb = 0.0;
338 double txPowerDbm = 0.0;
342 pathLossDb = txPowerDbm - rxPowerDbm;
345 (*m_traceStream) <<
Simulator::Now() <<
"," << node->GetId() <<
"," << satPosECEF.x <<
","
346 << satPosECEF.y <<
"," << satPosECEF.z <<
"," << newP.x <<
"," << newP.y
347 <<
"," << newP.z <<
"," << pathLossDb <<
"," << slantDistance <<
","
348 << elevationAngle << std::endl;
361 std::istringstream iss(locationStr);
363 std::vector<double> values;
364 while (std::getline(iss, token,
','))
366 values.push_back(std::stod(token));
368 NS_ABORT_MSG_IF(values.size() != 3,
"Ground station must be in 'lat,lon,alt' format");
369 return Vector(values[0], values[1], values[2]);
373main(
int argc,
char* argv[])
377 double satAntennaGainDb = 34.6;
380 std::string orbitFile;
381 std::string traceFile;
382 std::string mode =
"antenna";
383 std::string groundStationStr =
"41.275,1.988,14";
384 std::string scenario =
"NTN-Rural";
385 double frequencyHz = 2.0e9;
389 cmd.AddValue(
"orbitFile",
390 "CSV file with orbit parameters. "
391 "See LeoOrbitNodeHelper::CreateNodesAndInstallMobility() for documentation.",
393 cmd.AddValue(
"traceFile",
"CSV file to store trace data in; empty = stdout", traceFile);
394 cmd.AddValue(
"mode",
"Mode: orbit, antenna, channel (default: antenna)", mode);
395 cmd.AddValue(
"groundStation",
396 "Ground station location as 'lat,lon,alt' or 'auto' (default: 41.275,1.988,14)",
398 cmd.AddValue(
"resolution",
399 "Mobility model time resolution step (seconds)",
400 orbitTimeStepResolution);
401 cmd.AddValue(
"duration",
"Duration of the simulation in seconds", duration);
402 cmd.AddValue(
"scenario",
403 "NTN propagation scenario (NTN-DenseUrban, NTN-Urban, NTN-Suburban, NTN-Rural) "
404 "(default: NTN-Rural)",
406 cmd.AddValue(
"frequency",
"Carrier frequency in Hz (default: 2e9 Hz)", frequencyHz);
407 cmd.AddValue(
"antennaGain",
"Satellite antenna gain in dBi (default: 34.6)", satAntennaGainDb);
408 cmd.AddValue(
"antennaUpdatePeriod",
409 "Antenna orientation update period (default: 500 ms)",
410 antennaUpdatePeriod);
411 cmd.Parse(argc, argv);
419 else if (mode ==
"antenna")
423 else if (mode ==
"channel")
429 NS_LOG_WARN(
"Unknown mode: " << mode <<
". Defaulting to antenna.");
436 NS_LOG_WARN(
"Channel mode with groundStation=auto requires a valid orbitFile. "
437 "Setting groundStation to auto will place it beneath the first satellite.");
444 if (!orbitFile.empty())
446 satellites = orbit.CreateNodesAndInstallMobility(orbitFile);
450 satellites = orbit.CreateNodesAndInstallMobility(
LeoOrbitalShell(1180, 30, 1, 16));
455 if (groundStationStr ==
"auto")
460 firstSatelliteMobility->GetPosition(),
462 gsPos = Vector(firstSatellitePositionGEO.x, firstSatellitePositionGEO.y, 0);
473 groundNodeMobility->SetGeographicPosition(gsPos);
475 groundStation.posGEO = groundNodeMobility->GetGeographicPosition();
476 groundStation.posECEF = groundNodeMobility->GetGeocentricPosition();
478 "Ground Node Geocentric Position (ECEF x[m]/y[m]/z[m]): " <<
groundStation.posECEF);
480 "Ground Node GetPosition() (ECEF x[m]/y[m]/z[m]): " << groundNodeMobility->GetPosition());
481 NS_LOG_DEBUG(
"Satellite GetPosition() (ECEF x[m]/y[m]/z[m]): "
484 "ECEF position mismatch. Ensure SetGeographicPosition arguments "
485 "are latitude/longitude/altitude, not cartesian coordinates.");
490 std::ofstream traceOs;
491 if (!traceFile.empty())
493 traceOs.open(traceFile);
495 std::ostream* traceStream = (traceOs.is_open()) ? &traceOs : &std::cout;
502 std::map<std::string, std::pair<TypeId, TypeId>> propTidCondTid{
516 if (propTidCondTid.find(scenario) == propTidCondTid.end())
518 NS_LOG_WARN(
"Unknown NTN scenario: " << scenario <<
". Defaulting to NTN-Rural.");
519 scenario =
"NTN-Rural";
522 auto [propLossTid, chanCondTid] = propTidCondTid[scenario];
524 propagationLossModelFactory.
SetTypeId(propLossTid);
526 propLossModel->SetAttribute(
"Frequency",
DoubleValue(frequencyHz));
527 propLossModel->SetAttribute(
"ShadowingEnabled",
BooleanValue(
true));
530 channelConditionModelFactory.
SetTypeId(chanCondTid);
533 propLossModel->SetChannelConditionModel(condModel);
545 "/NodeList/*/$ns3::MobilityModel/CourseChange",
552 antennaFactory.
SetTypeId(
"ns3::UniformPlanarArray");
557 elementFactory.
SetTypeId(
"ns3::IsotropicAntennaModel");
563 node = satellites.
Get(i);
564 antennaFactory.
Set(
"AntennaElement",
569 tracer.UpdateAntennaOrientation(node, antennaUpdatePeriod);
577 if (traceOs.is_open())
Helper class to trace LEO constellation mobility and/or antenna pointing.
Ptr< ThreeGppPropagationLossModel > m_propagationLossModel
Propagation loss model.
Vector m_groundNodePosGEO
Ground station geodetic position.
Ptr< Node > m_groundNode
Ground station node.
Vector GeneratePoint(const Vector &nodePosECEF, const double azimuth, const double inclination) const
Compute a point along a satellite's antenna pointing direction.
LeoConstellationTracer(Ptr< Node > groundNode, LeoMode mode, Ptr< ThreeGppPropagationLossModel > propagationLossModel, Vector groundNodePosGEO, Vector groundNodePosECEF, std::ostream *traceStream)
Construct a LeoConstellationTracer.
std::ostream * m_traceStream
Output stream for trace data.
Vector m_groundNodePosECEF
Ground station ECEF position.
void UpdateAntennaOrientation(Ptr< Node > node, Time period) const
Periodically steer a satellite node's antenna toward the ground station.
LeoMode m_mode
Simulation mode.
void CourseChange(Ptr< const MobilityModel > mob) const
CourseChange callback that outputs trace data.
Class holding the azimuth and inclination angles of spherical coordinates.
double GetInclination() const
Getter for inclination angle.
double GetAzimuth() const
Getter for azimuth angle.
interface for antenna radiation pattern models
Abstract Channel Base Class.
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
static Vector TopocentricToGeographicCoordinates(Vector pos, Vector refPoint, EarthSpheroidType sphType)
Conversion from topocentric to geographic.
static Vector GeographicToCartesianCoordinates(double latitude, double longitude, double altitude, EarthSpheroidType sphType)
Converts earth geographic/geodetic coordinates (latitude and longitude in degrees) with a given altit...
static Vector GeographicToTopocentricCoordinates(Vector pos, Vector refPoint, EarthSpheroidType sphType)
Conversion from geographic to topocentric coordinates.
static Vector CartesianToGeographicCoordinates(Vector pos, EarthSpheroidType sphType)
Inverse of GeographicToCartesianCoordinates using [1].
Builds a node container of nodes with LEO positions using a list of orbit definitions.
Keep track of the current position and velocity of an object.
Vector GetPosition() const
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Base class for the 3GPP channel condition models.
static TypeId GetTypeId()
Register this type.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Register this type.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Register this type.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Register this type.
static TypeId GetTypeId()
Get the type ID.
Base class for the 3GPP propagation models.
Simulation virtual time values and global simulation resolution.
Hold an unsigned integer type.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
GroundStation groundStation
Global ground station.
LeoMode
Simulation mode selected via –mode.
@ Orbit
Mobility tracing only.
@ Channel
Full 3GPP NTN propagation loss.
@ Antenna
Antenna pointing toward ground station.
Ptr< ThreeGppPropagationLossModel > propagationLossModel
Global propagation loss model (used by tracer).
static Vector ParseGroundStation(const std::string &locationStr)
Parse a ground station location string "lat,lon,alt" into a Vector.
log2() macro definition; to deal with Bug 1467.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > ConstCast(const Ptr< T2 > &p)
Cast a Ptr.
double RadiansToDegrees(double radians)
converts radians to degrees
Ground station definition.
Vector posGEO
Ground station geodetic position (latitude/longitude/altitude).
Vector posECEF
Ground station ECEF position (x/y/z in meters).
Ptr< Node > node
Ground station node.