00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns3/simulator.h"
00022 #include "ns3/uinteger.h"
00023 #include "ns3/double.h"
00024 #include "ns3/random-variable.h"
00025 #include "ns3/mobility-model.h"
00026 #include "ns3/log.h"
00027 #include "jakes-propagation-loss-model.h"
00028 #include <math.h>
00029
00030 NS_LOG_COMPONENT_DEFINE ("Jakes");
00031
00032 namespace ns3 {
00033
00034 class JakesPropagationLossModel::PathCoefficients
00035 {
00036 public:
00037 PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
00038 Ptr<MobilityModel> receiver,
00039 uint8_t nRays,
00040 uint8_t nOscillators);
00041 ~PathCoefficients ();
00042 double GetLoss (void);
00043 Ptr<MobilityModel> GetReceiver (void);
00044 private:
00045 void DoConstruct (void);
00046 Ptr<MobilityModel> m_receiver;
00047 uint8_t m_nOscillators;
00048 uint8_t m_nRays;
00049 double **m_phases;
00050 Time m_lastUpdate;
00051 Ptr<const JakesPropagationLossModel> m_jakes;
00052 };
00053
00054
00055 JakesPropagationLossModel::PathCoefficients::PathCoefficients (Ptr<const JakesPropagationLossModel> jakes,
00056 Ptr<MobilityModel> receiver,
00057 uint8_t nRays,
00058 uint8_t nOscillators)
00059 : m_receiver (receiver),
00060 m_nOscillators (nOscillators),
00061 m_nRays (nRays),
00062 m_jakes(jakes)
00063 {
00064 DoConstruct ();
00065 }
00066
00067 JakesPropagationLossModel::PathCoefficients::~PathCoefficients ()
00068 {
00069 for (uint8_t i = 0; i < m_nRays; i++)
00070 {
00071 delete [] m_phases[i];
00072 }
00073 delete [] m_phases;
00074 }
00075
00076 void
00077 JakesPropagationLossModel::PathCoefficients::DoConstruct ()
00078 {
00079 m_phases = new double*[m_nRays];
00080 for (uint8_t i = 0; i < m_nRays; i++)
00081 {
00082 m_phases[i] = new double[m_nOscillators + 1];
00083 for (uint8_t j = 0; j <= m_nOscillators; j++)
00084 {
00085 m_phases[i][j] = 2.0 * JakesPropagationLossModel::PI * m_jakes->m_variable.GetValue ();
00086 }
00087 }
00088 m_lastUpdate = Simulator::Now ();
00089 }
00090
00091 Ptr<MobilityModel>
00092 JakesPropagationLossModel::PathCoefficients::GetReceiver ()
00093 {
00094 return m_receiver;
00095 }
00096
00097 double
00098 JakesPropagationLossModel::PathCoefficients::GetLoss (void)
00099 {
00100 uint16_t N = 4 * m_nOscillators + 2;
00101 Time interval = Simulator::Now () - m_lastUpdate;
00102 ComplexNumber coef= {0.0, 0.0};
00103 ComplexNumber fading;
00104 double norm = 0.0;
00105 for (uint8_t i = 0; i < m_nRays; i++)
00106 {
00107 fading.real = 0.0;
00108 fading.imag = 0.0;
00109 for (uint8_t j = 0; j <= m_nOscillators; j++)
00110 {
00111 m_phases[i][j] += 2.0 * JakesPropagationLossModel::PI *
00112 cos (2.0 * JakesPropagationLossModel::PI * j / N) * m_jakes->m_fd * interval.GetSeconds ();
00113 m_phases[i][j] -= 2.0 * JakesPropagationLossModel::PI *
00114 floor (m_phases[i][j] / 2.0 / JakesPropagationLossModel::PI);
00115 fading.real += m_jakes->m_amp[j].real * cos (m_phases[i][j]);
00116 fading.imag += m_jakes->m_amp[j].imag * cos (m_phases[i][j]);
00117 norm += sqrt(pow (m_jakes->m_amp[j].real, 2) + pow(m_jakes->m_amp[j].imag, 2));
00118 }
00119 coef.real += fading.real;
00120 coef.imag += fading.imag;
00121 }
00122 m_lastUpdate = Simulator::Now ();
00123 double k = sqrt (pow (coef.real, 2) + pow (coef.imag, 2)) / norm;
00124 NS_LOG_DEBUG ("Jakes coef "<< k << " (" << 10 * log10 (k) << "dB)");
00125 return 10 * log10 (k);
00126 }
00127
00128 NS_OBJECT_ENSURE_REGISTERED (JakesPropagationLossModel);
00129
00130 const double JakesPropagationLossModel::PI = 3.1415;
00131
00132 TypeId
00133 JakesPropagationLossModel::GetTypeId (void)
00134 {
00135 static TypeId tid = TypeId ("ns3::JakesPropagationLossModel")
00136 .SetParent<PropagationLossModel> ()
00137 .AddConstructor<JakesPropagationLossModel> ()
00138 .AddAttribute ("NumberOfRaysPerPath",
00139 "The number of rays to use by default for compute the fading coeficent for a given path (default is 1)",
00140 UintegerValue (1),
00141 MakeUintegerAccessor (&JakesPropagationLossModel::m_nRays),
00142 MakeUintegerChecker<uint8_t> ())
00143 .AddAttribute ("NumberOfOscillatorsPerRay",
00144 "The number of oscillators to use by default for compute the coeficent for a given ray of a given "
00145 "path (default is 4)",
00146 UintegerValue (4),
00147 MakeUintegerAccessor (&JakesPropagationLossModel::m_nOscillators),
00148 MakeUintegerChecker<uint8_t> ())
00149 .AddAttribute ("DopplerFreq",
00150 "The doppler frequency in Hz (f_d = v / lambda = v * f / c), the default is 0)",
00151 DoubleValue (0.0),
00152 MakeDoubleAccessor (&JakesPropagationLossModel::m_fd),
00153 MakeDoubleChecker<double> ())
00154 .AddAttribute ("Distribution",
00155 "The distribution to choose the initial phases.",
00156 RandomVariableValue (ConstantVariable (1.0)),
00157 MakeRandomVariableAccessor (&JakesPropagationLossModel::m_variable),
00158 MakeRandomVariableChecker ())
00159 ;
00160 return tid;
00161 }
00162
00163 JakesPropagationLossModel::JakesPropagationLossModel ()
00164 {
00165 DoConstruct ();
00166 }
00167
00168 JakesPropagationLossModel::~JakesPropagationLossModel ()
00169 {
00170 delete [] m_amp;
00171 for (PathsList::iterator i = m_paths.end (); i != m_paths.begin (); i--)
00172 {
00173 PathsSet *ps = *i;
00174 for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++)
00175 {
00176 PathCoefficients *pc = *r;
00177 delete pc;
00178 }
00179 delete ps;
00180 }
00181 }
00182
00183 void
00184 JakesPropagationLossModel::DoConstruct ()
00185 {
00186 uint16_t N = 4 * m_nOscillators + 2;
00187 m_amp = new ComplexNumber[m_nOscillators + 1];
00188 m_amp[0].real = 2.0 * sqrt(2.0 / N) * cos (PI / 4.0);
00189 m_amp[0].imag = 2.0 * sqrt(2.0 / N) * sin (PI / 4.0);
00190 for (uint8_t i = 1; i <= m_nOscillators; i++)
00191 {
00192 double beta = PI * (double)i / m_nOscillators;
00193 m_amp[i].real = 4.0 * cos (beta) / sqrt(N);
00194 m_amp[i].imag = 4.0 * sin (beta) / sqrt(N);
00195 }
00196 }
00197
00198 void
00199 JakesPropagationLossModel::SetNRays (uint8_t nRays)
00200 {
00201 m_nRays = nRays;
00202 }
00203
00204 void
00205 JakesPropagationLossModel::SetNOscillators (uint8_t nOscillators)
00206 {
00207 m_nOscillators = nOscillators;
00208 }
00209
00210 double
00211 JakesPropagationLossModel::DoCalcRxPower (double txPowerDbm,
00212 Ptr<MobilityModel> a,
00213 Ptr<MobilityModel> b) const
00214 {
00215 PathsList::iterator i = m_paths.end ();
00216 while (i != m_paths.begin ())
00217 {
00218 i--;
00219 PathsSet *ps = *i;
00220 if (ps->sender == a)
00221 {
00222 m_paths.erase (i);
00223 m_paths.push_back (ps);
00224 for (DestinationList::iterator r = ps->receivers.begin (); r != ps->receivers.end (); r++)
00225 {
00226 PathCoefficients *pc = *r;
00227 if (pc->GetReceiver () == b)
00228 {
00229 ps->receivers.erase (r);
00230 ps->receivers.push_back (pc);
00231 return txPowerDbm + pc->GetLoss ();
00232 }
00233 }
00234 PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
00235 ps->receivers.push_back (pc);
00236 return txPowerDbm + pc->GetLoss ();
00237 }
00238 }
00239 PathsSet *ps = new PathsSet;
00240 ps->sender = a;
00241 PathCoefficients *pc = new PathCoefficients (this, b, m_nRays, m_nOscillators);
00242 ps->receivers.push_back (pc);
00243 m_paths.push_back (ps);
00244 return txPowerDbm + pc->GetLoss ();
00245 }
00246
00247 }
00248