61#include "pybind11/pybind11.h"
63#include "ns3/channel-condition-model.h"
64#include "ns3/constant-position-mobility-model.h"
65#include "ns3/constant-velocity-mobility-model.h"
66#include "ns3/core-module.h"
67#include "ns3/lte-spectrum-value-helper.h"
68#include "ns3/mobility-model.h"
69#include "ns3/net-device.h"
70#include "ns3/node-container.h"
72#include "ns3/output-stream-wrapper.h"
73#include "ns3/simple-net-device.h"
74#include "ns3/sionna-rt-channel-model.h"
75#include "ns3/sionna-rt-spectrum-propagation-loss-model.h"
76#include "ns3/spectrum-signal-parameters.h"
77#include "ns3/three-gpp-antenna-model.h"
78#include "ns3/uniform-planar-array.h"
84namespace py = pybind11;
120 Vector aPos = thisDevice->GetNode()->GetObject<
MobilityModel>()->GetPosition();
121 Vector bPos = otherDevice->GetNode()->GetObject<
MobilityModel>()->GetPosition();
124 Angles completeAngle(bPos, aPos);
125 double hAngleRadian = completeAngle.
GetAzimuth();
130 uint64_t totNoArrayElements = thisAntenna->GetNumElems();
134 double power = 1.0 / sqrt(totNoArrayElements);
137 const double sinVAngleRadian = sin(vAngleRadian);
138 const double cosVAngleRadian = cos(vAngleRadian);
139 const double sinHAngleRadian = sin(hAngleRadian);
140 const double cosHAngleRadian = cos(hAngleRadian);
142 for (uint64_t ind = 0; ind < totNoArrayElements; ind++)
144 Vector loc = thisAntenna->GetElementLocation(ind);
145 double phase = -2 * M_PI *
146 (sinVAngleRadian * cosHAngleRadian * loc.x +
147 sinVAngleRadian * sinHAngleRadian * loc.y + cosVAngleRadian * loc.z);
148 antennaWeights[ind] = exp(std::complex<double>(0, phase)) * power;
152 thisAntenna->SetBeamformingVector(antennaWeights);
161 py::object sys = py::module_::import(
"sys");
162 py::print(
"Python executable:", sys.attr(
"executable"));
163 py::print(
"Python version:", sys.attr(
"version"));
177 std::vector<int> activeRbs0(100);
178 for (
int i = 0; i < 100; i++)
185 txParams->psd = txPsd->Copy();
186 NS_LOG_DEBUG(
"Average tx power " << 10 * log10(
Sum(*txPsd) * 180e3) <<
" dB");
191 NS_LOG_DEBUG(
"Average noise power " << 10 * log10(
Sum(*noisePsd) * 180e3) <<
" dB");
196 NS_ASSERT_MSG(params.txAntenna,
"params.txAntenna is nullptr!");
197 NS_ASSERT_MSG(params.rxAntenna,
"params.rxAntenna is nullptr!");
205 auto rxPsd = rxParams->psd;
206 double rxPowDb = 10 * log10(
Sum(*rxPsd) * 180e3);
207 double snrDb = 10 * log10(
Sum(*rxPsd) /
Sum(*noisePsd));
216 <<
" SNR = " << std::setprecision(2) << snrDb <<
" dB"
217 <<
" | Rx power = " << rxPowDb <<
" dBm" << std::endl;
220 auto* stream = params.stream->GetStream();
225main(
int argc,
char* argv[])
227 py::scoped_interpreter guard{};
232 std::cout <<
"\n--- Sionna-RT Channel Example ---\n" << std::endl;
234 double frequency = 30e9;
236 double noiseFigure = 9.0;
237 double distance = 50.0;
241 std::string Scenario =
"simple_street_canyon_with_cars";
243 bool enableGnbIso =
false;
244 bool enableUeIso =
false;
245 bool enableGnbDualPolarized =
true;
246 bool enableUeDualPolarized =
true;
248 bool IsImageRenderedEnabled =
false;
249 Vector CameraPosition(Vector(70.0, -20.0, 190.0));
250 Vector CameraLookAt(Vector(0.0, 0.0, 4.0));
251 std::string filenamePrefix =
"sionna-rt-scene-";
252 std::string filedirectory =
"sionna-rt-images";
257 RtPathSolverConfig.
los =
true;
264 RtPathSolverConfig.
seed = 41;
267 cmd.AddValue(
"Scenario",
"Propagation scenario", Scenario);
269 cmd.AddValue(
"frequency",
"Operating frequency in Hz", frequency);
271 cmd.AddValue(
"enableGnbIso",
"Enable isotropic elements at gNB", enableGnbIso);
272 cmd.AddValue(
"enableUeIso",
"Enable isotropic elements at UE", enableUeIso);
273 cmd.AddValue(
"enableGnbDualPolarized",
274 "Enable dual-polarized elements at gNB",
275 enableGnbDualPolarized);
276 cmd.AddValue(
"enableUeDualPolarized",
277 "Enable dual-polarized elements at UE",
278 enableUeDualPolarized);
280 cmd.AddValue(
"IsImageRenderedEnabled",
281 "Enable rendering of scene images to file",
282 IsImageRenderedEnabled);
283 cmd.AddValue(
"outputFileName",
"Output file name for scene images", filenamePrefix);
284 cmd.AddValue(
"outputFileDirectory",
"Output file directory for scene images", filedirectory);
285 cmd.AddValue(
"cameraPosition",
"Camera position for scene rendering", CameraPosition);
286 cmd.AddValue(
"cameraLookAt",
"Camera look-at point for scene rendering", CameraLookAt);
288 cmd.AddValue(
"txPow",
"Tx power in dBm", txPow);
289 cmd.AddValue(
"noiseFigure",
"Noise figure in dB", noiseFigure);
290 cmd.AddValue(
"distance",
"Distance between tx and rx nodes in meters", distance);
292 cmd.AddValue(
"simTime",
"Simulation time in milliseconds", simTime);
293 cmd.AddValue(
"timeRes",
"Time resolution in milliseconds", timeRes);
295 cmd.AddValue(
"maxDepth",
296 "Maximum reflection/refraction depth for sionna-rt configuration",
299 "Include line-of-sight path for sionna-rt configuration",
300 RtPathSolverConfig.
los);
301 cmd.AddValue(
"specularReflection",
302 "Enable specular reflections for sionna-rt configuration",
304 cmd.AddValue(
"diffuseReflection",
305 "Enable diffuse reflections for sionna-rt configuration",
307 cmd.AddValue(
"refraction",
308 "Enable refractions for sionna-rt configuration",
310 cmd.AddValue(
"syntheticArray",
311 "Use synthetic array processing for sionna-rt configuration",
313 cmd.AddValue(
"diffraction",
314 "Enable diffraction for sionna-rt configuration",
316 cmd.AddValue(
"edgeDiffraction",
317 "Enable edge diffraction for sionna-rt configuration",
319 cmd.AddValue(
"seed",
"Random seed", RtPathSolverConfig.
seed);
321 cmd.Parse(argc, argv);
339 "IsImageRenderedEnabled",
342 "OutputImageDirectory",
349 m_spectrumLossModel->SetChannelModelAttribute(
"CameraPosition", VectorValue(CameraPosition));
364 nodes.Get(0)->AddDevice(txDev);
365 txDev->SetNode(
nodes.Get(0));
366 nodes.Get(1)->AddDevice(rxDev);
367 rxDev->SetNode(
nodes.Get(1));
371 txMob->SetPosition(Vector(-20.0, 00.0, 0.0));
374 rxMob->SetPosition(Vector(distance - 20.0, 00.0, 0));
375 rxMob->SetVelocity(Vector(00.0, -20.0, 0.0));
378 nodes.Get(0)->AggregateObject(txMob);
379 nodes.Get(1)->AggregateObject(rxMob);
389 txAntenna->SetAttribute(
"AntennaElement",
393 txAntenna->SetAttribute(
"IsDualPolarized",
BooleanValue(enableGnbDualPolarized));
402 rxAntenna->SetAttribute(
"AntennaElement",
406 rxAntenna->SetAttribute(
"IsDualPolarized",
BooleanValue(enableUeDualPolarized));
416 for (
int i = 0; i < floor(simTime / timeRes); i++)
419 params{txMob, rxMob, txPow, noiseFigure, txAntenna, rxAntenna, snrOutputStream};
428 catch (
const py::error_already_set& e)
430 std::cerr <<
"\n[FAILURE] Sionna/Python error during simulation:\n"
431 <<
" " << e.what() <<
"\n"
432 <<
" Check that the Sionna virtual environment is active and the\n"
433 <<
" scene name (--Scenario) is correct.\n"
437 catch (
const std::exception& e)
439 std::cerr <<
"\n[FAILURE] Simulation error:\n"
440 <<
" " << e.what() <<
"\n"
447 std::cout <<
"\n[SUCCESS] Simulation completed successfully.\n"
449 <<
"average SNR = " << std::fixed << std::setprecision(2)
451 <<
" Results written to snr-trace.txt\n"
456 std::cerr <<
"\n[FAILURE] Simulation ran but no SNR samples were produced.\n"
457 <<
" Check that simTime > 0 and the channel model is configured correctly.\n"
Class holding the azimuth and inclination angles of spherical coordinates.
double GetInclination() const
Getter for inclination angle.
double GetAzimuth() const
Getter for azimuth angle.
Parse command-line arguments.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
static Ptr< SpectrumValue > CreateNoisePowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double noiseFigure)
create a SpectrumValue that models the power spectral density of AWGN
static Ptr< SpectrumValue > CreateTxPowerSpectralDensity(uint32_t earfcn, uint16_t bandwidth, double powerTx, std::vector< int > activeRbs)
create a spectrum value representing the power spectral density of a signal to be transmitted.
Keep track of the current position and velocity of an object.
keep track of a set of node pointers.
ComplexMatrixArray ComplexVector
the underlying Valarray
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
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.
Hold variables of type string.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
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...
void SetDefault(std::string name, const AttributeValue &value)
#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.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double Sum(const SpectrumValue &x)
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
static int g_snrSamples
number of SNR samples computed
static void DoBeamforming(Ptr< NetDevice > thisDevice, Ptr< PhasedArrayModel > thisAntenna, Ptr< NetDevice > otherDevice)
Perform the beamforming using the DFT beamforming method.
static void ComputeSnr(const ComputeSnrParams ¶ms)
Compute the average SNR.
static double g_snrSumDb
running sum of SNR values in dB
static void PrintPythonExecutable()
Print the python executable and version.
A structure that holds the parameters for the ComputeSnr function.
Ptr< PhasedArrayModel > txAntenna
the tx antenna array
Ptr< MobilityModel > rxMob
the rx mobility model
double noiseFigure
the noise figure in dB
double txPow
the tx power in dBm
Ptr< OutputStreamWrapper > stream
output stream wrapper for SNR trace
Ptr< PhasedArrayModel > rxAntenna
the rx antenna array
Ptr< MobilityModel > txMob
the tx mobility model
Configuration for the Sionna RT PathSolver.
bool diffuseReflection
Enable diffuse reflections (scattering).
bool syntheticArray
Use synthetic array processing (if supported by scene factory).
bool specularReflection
Enable specular reflections (mirror-like).
bool los
Include direct line-of-sight (LOS) path when true It only controls whether the solver should include ...
int seed
Random seed for stochastic components (e.g., diffuse scattering).
int maxDepth
Maximum number of interactions (reflection/refraction depth).
bool edgeDiffraction
Enable edge diffraction (alternative diffraction handling).
bool diffraction
Enable diffraction.
bool refraction
Enable refraction through transparent bodies / materials.
static void ComputeSnr(const ComputeSnrParams ¶ms)
Compute the average SNR.
static Ptr< ThreeGppSpectrumPropagationLossModel > m_spectrumLossModel
the SpectrumPropagationLossModel object