00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <math.h>
00039
00040 #include <delay.h>
00041 #include <packet.h>
00042
00043 #include <packet-stamp.h>
00044 #include <antenna.h>
00045 #include <mobilenode.h>
00046 #include <propagation.h>
00047 #include <wireless-phy.h>
00048 #include <tworayground.h>
00049
00050 static class TwoRayGroundClass: public TclClass {
00051 public:
00052 TwoRayGroundClass() : TclClass("Propagation/TwoRayGround") {}
00053 TclObject* create(int, const char*const*) {
00054 return (new TwoRayGround);
00055 }
00056 } class_tworayground;
00057
00058 TwoRayGround::TwoRayGround()
00059 {
00060 last_hr = last_ht = 0.0;
00061 crossover_dist = 0.0;
00062 }
00063
00064
00065
00066
00067 double TwoRayGround::TwoRay(double Pt, double Gt, double Gr, double ht, double hr, double L, double d)
00068 {
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 return Pt * Gt * Gr * (hr * hr * ht * ht) / (d * d * d * d * L);
00080 }
00081
00082 double
00083 TwoRayGround::Pr(PacketStamp *t, PacketStamp *r, WirelessPhy *ifp)
00084 {
00085 double rX, rY, rZ;
00086 double tX, tY, tZ;
00087 double d;
00088 double hr, ht;
00089 double Pr;
00090
00091 double L = ifp->getL();
00092 double lambda = ifp->getLambda();
00093
00094 r->getNode()->getLoc(&rX, &rY, &rZ);
00095 t->getNode()->getLoc(&tX, &tY, &tZ);
00096
00097 rX += r->getAntenna()->getX();
00098 rY += r->getAntenna()->getY();
00099 tX += t->getAntenna()->getX();
00100 tY += t->getAntenna()->getY();
00101
00102 d = sqrt((rX - tX) * (rX - tX)
00103 + (rY - tY) * (rY - tY)
00104 + (rZ - tZ) * (rZ - tZ));
00105
00106
00107
00108
00109
00110 if (rZ != tZ) {
00111 printf("%s: TwoRayGround propagation model assume flat ground\n",
00112 __FILE__);
00113 }
00114
00115 hr = rZ + r->getAntenna()->getZ();
00116 ht = tZ + t->getAntenna()->getZ();
00117
00118 if (hr != last_hr || ht != last_ht)
00119 {
00120
00121
00122
00123
00124
00125
00126
00127
00128 crossover_dist = (4 * PI * ht * hr) / lambda;
00129 last_hr = hr; last_ht = ht;
00130 #if DEBUG > 3
00131 printf("TRG: xover %e.10 hr %f ht %f\n",
00132 crossover_dist, hr, ht);
00133 #endif
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 double Gt = t->getAntenna()->getTxGain(rX - tX, rY - tY, rZ - tZ,
00143 t->getLambda());
00144 double Gr = r->getAntenna()->getRxGain(tX - rX, tY - rY, tZ - rZ,
00145 r->getLambda());
00146
00147 #if DEBUG > 3
00148 printf("TRG %.9f %d(%d,%d)@%d(%d,%d) d=%f xo=%f :",
00149 Scheduler::instance().clock(),
00150 t->getNode()->index(), (int)tX, (int)tY,
00151 r->getNode()->index(), (int)rX, (int)rY,
00152 d, crossover_dist);
00153
00154
00155 #endif
00156
00157 if(d <= crossover_dist) {
00158 Pr = Friis(t->getTxPr(), Gt, Gr, lambda, L, d);
00159 #if DEBUG > 3
00160 printf("Friis %e\n",Pr);
00161 #endif
00162 return Pr;
00163 }
00164 else {
00165 Pr = TwoRay(t->getTxPr(), Gt, Gr, ht, hr, L, d);
00166 #if DEBUG > 3
00167 printf("TwoRay %e\n",Pr);
00168 #endif
00169 return Pr;
00170 }
00171 }
00172
00173 double TwoRayGround::getDist(double Pr, double Pt, double Gt, double Gr, double hr, double ht, double L, double lambda)
00174 {
00175
00176 return sqrt(sqrt(Pt * Gt * Gr * (hr * hr * ht * ht) / Pr));
00177 }