#!/usr/bin/perl -T #!/usr/local/bin/perl -T ## --> Urban Area Path Loss, urban.cgi ## --> Green Bay Professional Packet Radio, www.gbppr.org ## This file Copyright 2003 under the GPL ## NO WARRANTY. Please send bug reports / patches / reports. # Setup # use Math::Complex; select STDOUT; $| = 1; my $pic = "pics/urban.png"; # Print MIME # print "Content-type:text/html\n\n"; # Read environment # read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } my $frq = $FORM{'frq'}; my $frq_val = $FORM{'frq_val'}; my $pt = $FORM{'pt'}; my $pt_val = $FORM{'pt_val'}; my $ht = $FORM{'ht'}; my $ht_val = $FORM{'ht_val'}; my $hr = $FORM{'hr'}; my $hr_val = $FORM{'hr_val'}; my $dis = $FORM{'dis'}; my $dis_val = $FORM{'dis_val'}; my $env = $FORM{'env'}; # Clean up user input data # #Frequency # $frq =~ tr/0-9.//csd; if ($frq_val eq "GHz") { $frq_mhz = $frq * 1000; # convert to MHz $frq_ghz = $frq; } else { $frq_mhz = $frq; $frq_ghz = $frq / 1000; } if (!$frq_mhz || !$frq_ghz || $frq_mhz < 100) { print "You need a enter a frequency above 100 MHz."; exit; } # Power # $pt =~ tr/0-9.-//csd; if ($pt == 0) { $pt = 0.001; } if ($pt_val eq "dBm") { $pt = 10 ** (($pt - 30) / 10); # dBm to W } $pt_w = sprintf "%.3f", $pt; $pt_dbm = sprintf "%.3f", (10 * log10($pt_w)) + 30; # Elevation # $ht =~ tr/0-9.//csd; if (!$ht) { $ht = 50; # 50 meters } if ($ht_val eq "feet") { $ht = $ht * 0.3048; # ft to m } $ht_m = sprintf "%.3f", $ht; $ht_ft = sprintf "%.3f", $ht * 3.2808399; $hr =~ tr/0-9.//csd; if (!$hr) { $hr = 1.5; # 1.5 meters } if ($hr_val eq "feet") { $hr = $hr * 0.3048; # ft to m } $hr_m = sprintf "%.3f", $hr; $hr_ft = sprintf "%.3f", $hr * 3.2808399; # Distance # $dis =~ tr/0-9.//csd; if (!$dis) { $dis = 5; # 5 kilometers } if ($dis_val eq "miles") { $dis = $dis * 1.609344; # mi to km } $dis_km = sprintf "%.3f", $dis; $dis_mi = sprintf "%.3f", $dis * 0.62137119; # Start calculations # if ($frq_mhz <= 1000) { if ($env eq "Urban Indoor - Large City") { $K = 0; if ($frq_mhz <= 200) { $ah2 = 8.29 * log10(1.54 * $hr_m) ** 2 - 1.1 - 15.0; } if ($frq_mhz >= 200.1) { $ah2 = 3.2 * log10(11.75 * $hr_m) ** 2 - 4.97 - 15.0; } } elsif ($env eq "Urban - Large City") { $K = 0; if ($frq_mhz <= 200) { $ah2 = 8.29 * log10(1.54 * $hr_m) ** 2 - 1.1; } if ($frq_mhz >= 200.1) { $ah2 = 3.2 * log10(11.75 * $hr_m) ** 2 - 4.97; } } elsif ($env eq "Urban - Small City") { $K = 0; $ah2 = (((1.1 * log10($frq_mhz)) - 0.7) * $hr_m) - ((1.56 * log10($frq_mhz)) - 0.8); } elsif ($env eq "Suburban") { $K = (((log10($frq_mhz / 28)) ** 2) * 2) + 5.4; $ah2 = 0; } elsif ($env eq "Rural Indoor - Quasi Open") { $K = (4.78 * (log10($frq_mhz) ** 2)) - (18.33 * (log10($frq_mhz))) + 35.94 - 10; $ah2 = 0; } elsif ($env eq "Rural Country Side - Quasi Open") { $K = (4.78 * (log10($frq_mhz) ** 2)) - (18.33 * (log10($frq_mhz))) + 35.94; $ah2 = 0; } elsif ($env eq "Rural Desert - Open") { $K = (4.78 * (log10($frq_mhz) ** 2)) - (18.33 * (log10($frq_mhz))) + 40.94; $ah2 = 0; } $ur = 69.55 + (26.16 * log10($frq_mhz)) - (13.82 * log10($ht_m)) - $ah2 + ((44.9 - (6.55 * log10($ht_m))) * log10($dis_km)) - $K; $urban_loss = sprintf "%.3f", $ur; } else { if ($env eq "Urban Indoor - Large City") { $K = -3; $ah2 = (((1.1 * log10($frq_mhz)) - 0.7) * $hr_m) - ((1.56 * log10($frq_mhz)) - 0.8) - 15; } elsif ($env eq "Urban - Large City") { $K = -3; $ah2 = (((1.1 * log10($frq_mhz)) - 0.7) * $hr_m) - ((1.56 * log10($frq_mhz)) - 0.8); } elsif ($env eq "Urban - Small City") { $K = 0; $ah2 = (((1.1 * log10($frq_mhz)) - 0.7) * $hr_m) - ((1.56 * log10($frq_mhz)) - 0.8); } elsif ($env eq "Suburban") { $K = 0; $ah2 = (((1.1 * log10($frq_mhz)) - 0.7) * $hr_m) - ((1.56 * log10($frq_mhz)) - 0.8); } elsif ($env eq "Rural Indoor - Quasi Open") { $K = (4.78 * (log10($frq_mhz) ** 2)) - (18.33 * (log10($frq_mhz))) + 35.94 - 10; $ah2 = 0; } elsif ($env eq "Rural Country Side - Quasi Open") { $K = (4.78 * (log10($frq_mhz) ** 2)) - (18.33 * (log10($frq_mhz))) + 35.94; $ah2 = 0; } elsif ($env eq "Rural Desert - Open") { $K = (4.78 * (log10($frq_mhz) ** 2)) - (18.33 * (log10($frq_mhz))) + 40.94; $ah2 = 0; } $ur = 46.3 + (33.9 * log10($frq_mhz)) - (13.82 * log10($ht_m)) - $ah2 + ((44.9 - (6.55 * log10($ht_m))) * log10($dis_km)) - $K; $urban_loss = sprintf "%.3f", $ur; } $free_space_loss = 32.447782 + (20 * log10($dis_km)) + (20 * log10($frq_mhz)); $free_space_loss = sprintf "%.3f", $free_space_loss; $rx_dbm = sprintf "%.3f", $pt_dbm - $urban_loss; $graze = atan2(($ht_m - $hr_m), ($dis_km * 1000)); $graze_d = sprintf "%.3f", $graze * 57.29578; # Make all pretty # $date = scalar gmtime; # Draw me a web page # $g = ""; $r = ""; $b = ""; $e = ""; print < Urban Area Path Loss Results

Urban Area Path Loss Results


[urban]

	             $r Frequency of the Transmitter : $e$frq_mhz$r MHz ($e$frq_ghz$r GHz) $e
                  $r Power Output of the Transmitter : $e$pt_w$r Watts ($e$pt_dbm$r dBm) $e
               $r Height of the Transmitter Location : $e$ht_m$r meters ($e$ht_ft$r feet) $e
                  $r Height of the Receiver Location : $e$hr_m$r meters ($e$hr_ft$r feet) $e
$r Distance Between Transmitter & Receiver Locations : $e$dis_km$r kilometers ($e$dis_mi$r miles) $e
                                 $r Environment Type : $e$env

$b Free Space Path Loss : $e$free_space_loss$b dB $e $b Urban Area Path Loss : $e$urban_loss$b dB $e $b Grazing Angle : $e$graze_d$b degrees $e $b Approximate Received Power Level : $e$rx_dbm$b dBm $e

Based on Hata/COST231-Hata formulas for urban area path losses.

Grazing Angle Notes

  • At grazing angles below about 1° there is good reflection when vertically polarized waves are used.
  • At these low angles the electric vector undergoes a phase reversal of 180°.
  • At moderate grazing angles vertically polarized waves are markedly attenuated, but suffer less phase reversal.
  • Horizontally polarized signals do not show the same variation, being generally well reflected, but again with a phase reversal of the reflected component.

Calculated on $date GMT

EOF