diff --git a/src/mobility/helper/mobility-helper.cc b/src/mobility/helper/mobility-helper.cc index 7f74536b6..9faca446f 100644 --- a/src/mobility/helper/mobility-helper.cc +++ b/src/mobility/helper/mobility-helper.cc @@ -270,4 +270,22 @@ MobilityHelper::AssignStreams (NodeContainer c, int64_t stream) return (currentStream - stream); } +double +MobilityHelper::GetDistanceSquaredBetween (Ptr n1, Ptr n2) +{ + NS_LOG_FUNCTION_NOARGS (); + double distSq = 0.0; + + Ptr rxPosition = n1->GetObject (); + NS_ASSERT (rxPosition != 0); + + Ptr txPosition = n2->GetObject (); + NS_ASSERT (txPosition != 0); + + double dist = rxPosition -> GetDistanceFrom (txPosition); + distSq = dist * dist; + + return distSq; +} + } // namespace ns3 diff --git a/src/mobility/helper/mobility-helper.h b/src/mobility/helper/mobility-helper.h index 635dc2b8e..63693921f 100644 --- a/src/mobility/helper/mobility-helper.h +++ b/src/mobility/helper/mobility-helper.h @@ -260,6 +260,13 @@ public: */ int64_t AssignStreams (NodeContainer c, int64_t stream); + /** + * \param n1 node 1 + * \param n2 node 2 + * \return the distance (squared), in meters, between two nodes + */ + static double GetDistanceSquaredBetween (Ptr n1, Ptr n2); + private: /** diff --git a/src/wave/examples/low99-ct-unterstrass-1day.filt.7.adj.mob b/src/wave/examples/low99-ct-unterstrass-1day.filt.7.adj.mob new file mode 100644 index 000000000..55d581063 --- /dev/null +++ b/src/wave/examples/low99-ct-unterstrass-1day.filt.7.adj.mob @@ -0,0 +1,1515 @@ +# Statistics: +# T_min: 0.000000 T_max: 300.010000 +# X_min: 10 X_max: 4660 +# Y_min: 10 Y_max: 3010 +# V_min: 9.937942 V_max: 32.054187 V_avg: 15.446680 +# nn: 99 area: 13950000.000000 +# events: 792 hosts/area: 0.070968 +# Last mov would end time at (time): 351.020 +# +# Processed from file: ct-unterstrass-1day.filt.7.mov +# ADJUSTMENT: X_min=679990.0 Y_min=247490.0 T_min=36610.980000 T_max= T_scalar=1 +# +# Statistics: +# T_min: 36610.980000 T_max: 36910.990000 +# X_min: 680000 X_max: 684650 +# Y_min: 247500 Y_max: 250500 +# V_min: 9.937942 V_max: 32.054187 V_avg: 15.446680 +# nn: 99 area: 13950000.000000 +# events: 792 hosts/area: 0.070968 +# Last mov would end time at (time): 36962.000 +# +# Processed from file: ct-unterstrass-1day.filt.mov +# FILTERING: X_min=0 X_max=999999999 Y_min=0 Y_max=999999999 T_min=36610.990000 T_max=36910.990000 V_min=0 +# +# Statistics: +# T_min: 35560.990000 T_max: 37461.000000 +# X_min: 680000 X_max: 684650 +# Y_min: 247500 Y_max: 250500 +# V_min: 7.806775 V_max: 32.386778 V_avg: 15.496693 +# nn: 505 area: 13950000.000000 +# events: 5174 hosts/area: 0.362007 +# Last mov would end time at (time): 37484.000 +# +# Processed from file: ct-unterstrass-1day.mov +# FILTERING: X_min=0 X_max=999999999 Y_min=0 Y_max=999999999 T_min=35561 T_max=37461 V_min=0 +# +# +# VANET traces; ns-2 movement file +# Parser: car-xml2ns +# +# City region: Unterstrass +# Statistics: +# T_min: 16392.990000 T_max: 88387.766811 +# X_min: 680000 X_max: 685000 +# Y_min: 247500 Y_max: 250500 +# V_min: 1.279985 V_max: 32.641710 V_avg: 14.853009 +# nn: 96934 area: 15000000.000000 +# events: 1973502 hosts/area: 64.622667 +# Last mov would end time at (time): 88387.767 +# +# Processed from file: VANET-traces-ns2.mov +# X_min=680000 X_max=685000 Y_min=247500 Y_max=250500 T_min=0 T_max=999999999 V_min=0 +# +# +# VANET traces; ns-2 movement file +# Parser: car-xml2ns +# +# Statistic for VANET-traces-ns2.mov +# T_min: 14208.990000 T_max: 90811.692948 +# X_min: 486740 X_max: 840500 +# Y_min: 46000 Y_max: 309000 +# V_min: 0.787110 V_max: 32.679368 V_avg: 20.536439 +# nn: 259978 +# events: 27609858 +# +# More information on VANET traces can be found in the MobiHoc 2006 paper: +# Val Naumov, Rainer Baumann, Thomas Gross "An Evaluation of Inter-Vehicle Ad Hoc Networks Based on Realistic Vehicular Traces" +# (http://www.lst.inf.ethz.ch/research) +# +# The speed of 10^9 m/s is used to initially place nodes +# from (0,0) to their trip starting points, e.g.: +# $node_(12345) set X_ 0.0 +# $node_(12345) set Y_ 0.0 +# $node_(12345) set Z_ 0.0 +# $ns_ at 10000.990000 "$node_(12345) setdest 710130.000000 91630.000000 1000000000.0" +# + +$ns_ at 0.0 "$node_(0) switch OFF" ;# set_X,Y,Z +$node_(0) set X_ 0.000000 +$node_(0) set Y_ 0.000000 +$node_(0) set Z_ 0.0 +$ns_ at 0.000000 "$node_(0) setdest 1335.996339 1004.578227 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(0) switch ON" ;# inside +$ns_ at 0.010000 "$node_(0) setdest 1290.000000 1090.000000 16.142807" ;# +$ns_ at 0.0 "$node_(1) switch OFF" ;# set_X,Y,Z +$node_(1) set X_ 0.000000 +$node_(1) set Y_ 0.000000 +$node_(1) set Z_ 0.0 +$ns_ at 0.000000 "$node_(1) setdest 3386.590740 102.881482 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(1) switch ON" ;# inside +$ns_ at 0.010000 "$node_(1) setdest 3310.000000 160.000000 13.629680" ;# +$ns_ at 0.0 "$node_(2) switch OFF" ;# set_X,Y,Z +$node_(2) set X_ 0.000000 +$node_(2) set Y_ 0.000000 +$node_(2) set Z_ 0.0 +$ns_ at 0.000000 "$node_(2) setdest 1151.671243 2088.378976 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(2) switch ON" ;# inside +$ns_ at 0.010000 "$node_(2) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 0.0 "$node_(3) switch OFF" ;# set_X,Y,Z +$node_(3) set X_ 0.000000 +$node_(3) set Y_ 0.000000 +$node_(3) set Z_ 0.0 +$ns_ at 0.000000 "$node_(3) setdest 2145.733295 1665.474912 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(3) switch ON" ;# inside +$ns_ at 0.010000 "$node_(3) setdest 2145.139452 1666.087027 12.762536" ;# +$ns_ at 0.0 "$node_(4) switch OFF" ;# set_X,Y,Z +$node_(4) set X_ 0.000000 +$node_(4) set Y_ 0.000000 +$node_(4) set Z_ 0.0 +$ns_ at 0.000000 "$node_(4) setdest 1344.895727 2053.358569 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(4) switch ON" ;# inside +$ns_ at 0.010000 "$node_(4) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 0.0 "$node_(5) switch OFF" ;# set_X,Y,Z +$node_(5) set X_ 0.000000 +$node_(5) set Y_ 0.000000 +$node_(5) set Z_ 0.0 +$ns_ at 0.000000 "$node_(5) setdest 1302.721238 2548.142173 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(5) switch ON" ;# inside +$ns_ at 0.010000 "$node_(5) setdest 1265.525646 2567.811046 15.943000" ;# +$ns_ at 0.0 "$node_(6) switch OFF" ;# set_X,Y,Z +$node_(6) set X_ 0.000000 +$node_(6) set Y_ 0.000000 +$node_(6) set Z_ 0.0 +$ns_ at 0.000000 "$node_(6) setdest 3014.330992 373.464793 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(6) switch ON" ;# inside +$ns_ at 0.010000 "$node_(6) setdest 2560.000000 10.000000 13.527727" ;# +$ns_ at 0.0 "$node_(7) switch OFF" ;# set_X,Y,Z +$node_(7) set X_ 0.000000 +$node_(7) set Y_ 0.000000 +$node_(7) set Z_ 0.0 +$ns_ at 0.000000 "$node_(7) setdest 3827.411664 1295.726554 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(7) switch ON" ;# inside +$ns_ at 0.010000 "$node_(7) setdest 3810.000000 1480.000000 13.211580" ;# +$ns_ at 0.0 "$node_(8) switch OFF" ;# set_X,Y,Z +$node_(8) set X_ 0.000000 +$node_(8) set Y_ 0.000000 +$node_(8) set Z_ 0.0 +$ns_ at 0.000000 "$node_(8) setdest 3902.621739 499.753269 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(8) switch ON" ;# inside +$ns_ at 0.010000 "$node_(8) setdest 3878.703961 752.883083 13.865834" ;# +$ns_ at 0.0 "$node_(9) switch OFF" ;# set_X,Y,Z +$node_(9) set X_ 0.000000 +$node_(9) set Y_ 0.000000 +$node_(9) set Z_ 0.0 +$ns_ at 0.000000 "$node_(9) setdest 2967.771730 91.554346 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(9) switch ON" ;# inside +$ns_ at 0.010000 "$node_(9) setdest 2560.000000 10.000000 16.627238" ;# +$ns_ at 0.0 "$node_(10) switch OFF" ;# set_X,Y,Z +$node_(10) set X_ 0.000000 +$node_(10) set Y_ 0.000000 +$node_(10) set Z_ 0.0 +$ns_ at 0.000000 "$node_(10) setdest 2318.919116 1486.960295 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(10) switch ON" ;# inside +$ns_ at 0.010000 "$node_(10) setdest 2291.086492 1515.649308 13.727766" ;# +$ns_ at 0.0 "$node_(11) switch OFF" ;# set_X,Y,Z +$node_(11) set X_ 0.000000 +$node_(11) set Y_ 0.000000 +$node_(11) set Z_ 0.0 +$ns_ at 0.000000 "$node_(11) setdest 1419.066610 2039.915684 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(11) switch ON" ;# inside +$ns_ at 0.010000 "$node_(11) setdest 1384.989853 2046.091826 15.647451" ;# +$ns_ at 0.0 "$node_(12) switch OFF" ;# set_X,Y,Z +$node_(12) set X_ 0.000000 +$node_(12) set Y_ 0.000000 +$node_(12) set Z_ 0.0 +$ns_ at 0.000000 "$node_(12) setdest 3124.161401 1857.484928 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(12) switch ON" ;# inside +$ns_ at 0.010000 "$node_(12) setdest 3111.196216 1922.959110 13.728154" ;# +$ns_ at 0.0 "$node_(13) switch OFF" ;# set_X,Y,Z +$node_(13) set X_ 0.000000 +$node_(13) set Y_ 0.000000 +$node_(13) set Z_ 0.0 +$ns_ at 0.000000 "$node_(13) setdest 1765.904200 206.177913 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(13) switch ON" ;# inside +$ns_ at 0.010000 "$node_(13) setdest 1575.313011 560.132979 16.252872" ;# +$ns_ at 0.0 "$node_(14) switch OFF" ;# set_X,Y,Z +$node_(14) set X_ 0.000000 +$node_(14) set Y_ 0.000000 +$node_(14) set Z_ 0.0 +$ns_ at 0.000000 "$node_(14) setdest 2644.602103 77.681682 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(14) switch ON" ;# inside +$ns_ at 0.010000 "$node_(14) setdest 2560.000000 10.000000 13.526031" ;# +$ns_ at 0.0 "$node_(15) switch OFF" ;# set_X,Y,Z +$node_(15) set X_ 0.000000 +$node_(15) set Y_ 0.000000 +$node_(15) set Z_ 0.0 +$ns_ at 0.000000 "$node_(15) setdest 1412.404730 1269.781947 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(15) switch ON" ;# inside +$ns_ at 0.010000 "$node_(15) setdest 1450.191974 1325.281961 13.601995" ;# +$ns_ at 0.0 "$node_(16) switch OFF" ;# set_X,Y,Z +$node_(16) set X_ 0.000000 +$node_(16) set Y_ 0.000000 +$node_(16) set Z_ 0.0 +$ns_ at 0.000000 "$node_(16) setdest 3808.631535 1683.901279 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(16) switch ON" ;# inside +$ns_ at 0.010000 "$node_(16) setdest 3802.025034 2668.269892 12.752087" ;# +$ns_ at 0.0 "$node_(17) switch OFF" ;# set_X,Y,Z +$node_(17) set X_ 0.000000 +$node_(17) set Y_ 0.000000 +$node_(17) set Z_ 0.0 +$ns_ at 0.000000 "$node_(17) setdest 2168.625696 1641.878129 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(17) switch ON" ;# inside +$ns_ at 0.010000 "$node_(17) setdest 2077.481811 1735.826441 12.043499" ;# +$ns_ at 0.0 "$node_(18) switch OFF" ;# set_X,Y,Z +$node_(18) set X_ 0.000000 +$node_(18) set Y_ 0.000000 +$node_(18) set Z_ 0.0 +$ns_ at 0.000000 "$node_(18) setdest 1487.721647 2027.472503 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(18) switch ON" ;# inside +$ns_ at 0.010000 "$node_(18) setdest 1444.642737 2035.280214 15.606334" ;# +$ns_ at 0.0 "$node_(19) switch OFF" ;# set_X,Y,Z +$node_(19) set X_ 0.000000 +$node_(19) set Y_ 0.000000 +$node_(19) set Z_ 0.0 +$ns_ at 0.000000 "$node_(19) setdest 2522.490892 1279.382742 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(19) switch ON" ;# inside +$ns_ at 0.010000 "$node_(19) setdest 2510.000000 1290.000000 16.231244" ;# +$ns_ at 0.0 "$node_(20) switch OFF" ;# set_X,Y,Z +$node_(20) set X_ 0.000000 +$node_(20) set Y_ 0.000000 +$node_(20) set Z_ 0.0 +$ns_ at 0.000000 "$node_(20) setdest 3808.901377 1643.694814 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(20) switch ON" ;# inside +$ns_ at 0.010000 "$node_(20) setdest 3805.915125 2088.646417 11.701108" ;# +$ns_ at 0.0 "$node_(21) switch OFF" ;# set_X,Y,Z +$node_(21) set X_ 0.000000 +$node_(21) set Y_ 0.000000 +$node_(21) set Z_ 0.0 +$ns_ at 0.000000 "$node_(21) setdest 3310.000000 343.829579 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(21) switch ON" ;# inside +$ns_ at 0.010000 "$node_(21) setdest 3310.000000 417.405846 13.140070" ;# +$ns_ at 0.0 "$node_(22) switch OFF" ;# set_X,Y,Z +$node_(22) set X_ 0.000000 +$node_(22) set Y_ 0.000000 +$node_(22) set Z_ 0.0 +$ns_ at 0.000000 "$node_(22) setdest 2855.036555 1507.937286 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(22) switch ON" ;# inside +$ns_ at 0.010000 "$node_(22) setdest 2651.364951 1666.692719 16.038021" ;# +$ns_ at 0.0 "$node_(23) switch OFF" ;# set_X,Y,Z +$node_(23) set X_ 0.000000 +$node_(23) set Y_ 0.000000 +$node_(23) set Z_ 0.0 +$ns_ at 0.000000 "$node_(23) setdest 1592.382893 1534.124874 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(23) switch ON" ;# inside +$ns_ at 0.010000 "$node_(23) setdest 1610.000000 1560.000000 15.573683" ;# +$ns_ at 0.0 "$node_(24) switch OFF" ;# set_X,Y,Z +$node_(24) set X_ 0.000000 +$node_(24) set Y_ 0.000000 +$node_(24) set Z_ 0.0 +$ns_ at 8.316123 "$node_(24) setdest 3917.755102 10.000000 1000000000.000000" ;# init_node +$ns_ at 8.326123 "$node_(24) switch ON" ;# inside +$ns_ at 8.326123 "$node_(24) setdest 3930.000000 210.000000 13.636597" ;# +$ns_ at 0.0 "$node_(25) switch OFF" ;# set_X,Y,Z +$node_(25) set X_ 0.000000 +$node_(25) set Y_ 0.000000 +$node_(25) set Z_ 0.0 +$ns_ at 0.000000 "$node_(25) setdest 2260.037210 1971.720046 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(25) switch ON" ;# inside +$ns_ at 0.010000 "$node_(25) setdest 1980.000000 2190.000000 16.131718" ;# +$ns_ at 0.0 "$node_(26) switch OFF" ;# set_X,Y,Z +$node_(26) set X_ 0.000000 +$node_(26) set Y_ 0.000000 +$node_(26) set Z_ 0.0 +$ns_ at 0.000000 "$node_(26) setdest 3296.991650 876.671168 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(26) switch ON" ;# inside +$ns_ at 0.010000 "$node_(26) setdest 3290.000000 1020.000000 13.033539" ;# +$ns_ at 0.0 "$node_(27) switch OFF" ;# set_X,Y,Z +$node_(27) set X_ 0.000000 +$node_(27) set Y_ 0.000000 +$node_(27) set Z_ 0.0 +$ns_ at 0.000000 "$node_(27) setdest 3175.428887 1175.425929 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(27) switch ON" ;# inside +$ns_ at 0.010000 "$node_(27) setdest 3032.000000 1370.000000 16.104256" ;# +$ns_ at 0.0 "$node_(28) switch OFF" ;# set_X,Y,Z +$node_(28) set X_ 0.000000 +$node_(28) set Y_ 0.000000 +$node_(28) set Z_ 0.0 +$ns_ at 0.000000 "$node_(28) setdest 2409.695914 1393.390366 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(28) switch ON" ;# inside +$ns_ at 0.010000 "$node_(28) setdest 2179.032149 1631.151477 13.107394" ;# +$ns_ at 0.0 "$node_(29) switch OFF" ;# set_X,Y,Z +$node_(29) set X_ 0.000000 +$node_(29) set Y_ 0.000000 +$node_(29) set Z_ 0.0 +$ns_ at 0.000000 "$node_(29) setdest 3452.084028 54.039030 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(29) switch ON" ;# inside +$ns_ at 0.010000 "$node_(29) setdest 3431.218482 69.599776 13.629680" ;# +$ns_ at 0.0 "$node_(30) switch OFF" ;# set_X,Y,Z +$node_(30) set X_ 0.000000 +$node_(30) set Y_ 0.000000 +$node_(30) set Z_ 0.0 +$ns_ at 0.000000 "$node_(30) setdest 1115.272435 1128.723407 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(30) switch ON" ;# inside +$ns_ at 0.010000 "$node_(30) setdest 1049.135457 1143.380791 17.914625" ;# +$ns_ at 0.0 "$node_(31) switch OFF" ;# set_X,Y,Z +$node_(31) set X_ 0.000000 +$node_(31) set Y_ 0.000000 +$node_(31) set Z_ 0.0 +$ns_ at 0.000000 "$node_(31) setdest 3917.389929 343.456587 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(31) switch ON" ;# inside +$ns_ at 0.010000 "$node_(31) setdest 3854.700880 1006.915687 13.418520" ;# +$ns_ at 0.0 "$node_(32) switch OFF" ;# set_X,Y,Z +$node_(32) set X_ 0.000000 +$node_(32) set Y_ 0.000000 +$node_(32) set Z_ 0.0 +$ns_ at 0.000000 "$node_(32) setdest 1916.905265 2069.068425 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(32) switch ON" ;# inside +$ns_ at 0.010000 "$node_(32) setdest 1860.000000 1960.000000 13.653812" ;# +$ns_ at 0.0 "$node_(33) switch OFF" ;# set_X,Y,Z +$node_(33) set X_ 0.000000 +$node_(33) set Y_ 0.000000 +$node_(33) set Z_ 0.0 +$ns_ at 25.600909 "$node_(33) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 25.610909 "$node_(33) switch ON" ;# inside +$ns_ at 25.610909 "$node_(33) setdest 3310.000000 160.000000 13.629680" ;# +$ns_ at 0.0 "$node_(34) switch OFF" ;# set_X,Y,Z +$node_(34) set X_ 0.000000 +$node_(34) set Y_ 0.000000 +$node_(34) set Z_ 0.0 +$ns_ at 0.000000 "$node_(34) setdest 3322.430436 150.729845 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(34) switch ON" ;# inside +$ns_ at 0.010000 "$node_(34) setdest 3310.000000 160.000000 15.352977" ;# +$ns_ at 0.0 "$node_(35) switch OFF" ;# set_X,Y,Z +$node_(35) set X_ 0.000000 +$node_(35) set Y_ 0.000000 +$node_(35) set Z_ 0.0 +$ns_ at 0.000000 "$node_(35) setdest 1489.808529 718.927017 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(35) switch ON" ;# inside +$ns_ at 0.010000 "$node_(35) setdest 1290.000000 1090.000000 16.203316" ;# +$ns_ at 0.0 "$node_(36) switch OFF" ;# set_X,Y,Z +$node_(36) set X_ 0.000000 +$node_(36) set Y_ 0.000000 +$node_(36) set Z_ 0.0 +$ns_ at 0.000000 "$node_(36) setdest 3217.224801 688.858919 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(36) switch ON" ;# inside +$ns_ at 0.010000 "$node_(36) setdest 2696.443341 1131.523160 13.544152" ;# +$ns_ at 0.0 "$node_(37) switch OFF" ;# set_X,Y,Z +$node_(37) set X_ 0.000000 +$node_(37) set Y_ 0.000000 +$node_(37) set Z_ 0.0 +$ns_ at 0.000000 "$node_(37) setdest 3310.000000 367.414167 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(37) switch ON" ;# inside +$ns_ at 0.010000 "$node_(37) setdest 3310.000000 610.000000 13.469508" ;# +$ns_ at 0.0 "$node_(38) switch OFF" ;# set_X,Y,Z +$node_(38) set X_ 0.000000 +$node_(38) set Y_ 0.000000 +$node_(38) set Z_ 0.0 +$ns_ at 0.000000 "$node_(38) setdest 3304.673333 719.196665 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(38) switch ON" ;# inside +$ns_ at 0.010000 "$node_(38) setdest 3290.000000 1020.000000 13.682917" ;# +$ns_ at 0.0 "$node_(39) switch OFF" ;# set_X,Y,Z +$node_(39) set X_ 0.000000 +$node_(39) set Y_ 0.000000 +$node_(39) set Z_ 0.0 +$ns_ at 26.010001 "$node_(39) setdest 2560.000000 10.000000 1000000000.000000" ;# init_node +$ns_ at 26.020001 "$node_(39) switch ON" ;# inside +$ns_ at 26.020001 "$node_(39) setdest 2560.000000 10.000000 16.187162" ;# +$ns_ at 0.0 "$node_(40) switch OFF" ;# set_X,Y,Z +$node_(40) set X_ 0.000000 +$node_(40) set Y_ 0.000000 +$node_(40) set Z_ 0.0 +$ns_ at 0.000000 "$node_(40) setdest 3447.779989 57.248822 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(40) switch ON" ;# inside +$ns_ at 0.010000 "$node_(40) setdest 3310.000000 160.000000 13.211017" ;# +$ns_ at 0.0 "$node_(41) switch OFF" ;# set_X,Y,Z +$node_(41) set X_ 0.000000 +$node_(41) set Y_ 0.000000 +$node_(41) set Z_ 0.0 +$ns_ at 13.039465 "$node_(41) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 13.049465 "$node_(41) switch ON" ;# inside +$ns_ at 13.049465 "$node_(41) setdest 3310.000000 160.000000 13.226301" ;# +$ns_ at 0.0 "$node_(42) switch OFF" ;# set_X,Y,Z +$node_(42) set X_ 0.000000 +$node_(42) set Y_ 0.000000 +$node_(42) set Z_ 0.0 +$ns_ at 4.811641 "$node_(42) setdest 3917.755102 10.000000 1000000000.000000" ;# init_node +$ns_ at 4.821641 "$node_(42) switch ON" ;# inside +$ns_ at 4.821641 "$node_(42) setdest 3930.000000 210.000000 12.370050" ;# +$ns_ at 0.0 "$node_(43) switch OFF" ;# set_X,Y,Z +$node_(43) set X_ 0.000000 +$node_(43) set Y_ 0.000000 +$node_(43) set Z_ 0.0 +$ns_ at 0.000000 "$node_(43) setdest 3926.546213 153.588154 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(43) switch ON" ;# inside +$ns_ at 0.010000 "$node_(43) setdest 3930.000000 210.000000 11.280936" ;# +$ns_ at 0.0 "$node_(44) switch OFF" ;# set_X,Y,Z +$node_(44) set X_ 0.000000 +$node_(44) set Y_ 0.000000 +$node_(44) set Z_ 0.0 +$ns_ at 0.000000 "$node_(44) setdest 3237.376624 671.729869 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(44) switch ON" ;# inside +$ns_ at 0.010000 "$node_(44) setdest 2887.075383 969.485924 13.635745" ;# +$ns_ at 0.0 "$node_(45) switch OFF" ;# set_X,Y,Z +$node_(45) set X_ 0.000000 +$node_(45) set Y_ 0.000000 +$node_(45) set Z_ 0.0 +$ns_ at 0.000000 "$node_(45) setdest 2447.488785 1354.434637 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(45) switch ON" ;# inside +$ns_ at 0.010000 "$node_(45) setdest 2140.491793 1670.877690 12.843287" ;# +$ns_ at 0.0 "$node_(46) switch OFF" ;# set_X,Y,Z +$node_(46) set X_ 0.000000 +$node_(46) set Y_ 0.000000 +$node_(46) set Z_ 0.0 +$ns_ at 0.000000 "$node_(46) setdest 607.861722 2915.580975 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(46) switch ON" ;# inside +$ns_ at 0.010000 "$node_(46) setdest 429.306931 3010.000000 16.007155" ;# +$ns_ at 12.628238 "$node_(46) switch OFF" ;# leaving_area +$ns_ at 0.0 "$node_(47) switch OFF" ;# set_X,Y,Z +$node_(47) set X_ 0.000000 +$node_(47) set Y_ 0.000000 +$node_(47) set Z_ 0.0 +$ns_ at 0.000000 "$node_(47) setdest 3247.678772 560.143018 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(47) switch ON" ;# inside +$ns_ at 0.010000 "$node_(47) setdest 2934.323476 309.458781 13.323892" ;# +$ns_ at 0.0 "$node_(48) switch OFF" ;# set_X,Y,Z +$node_(48) set X_ 0.000000 +$node_(48) set Y_ 0.000000 +$node_(48) set Z_ 0.0 +$ns_ at 0.000000 "$node_(48) setdest 3230.522293 1783.588111 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(48) switch ON" ;# inside +$ns_ at 0.010000 "$node_(48) setdest 3432.713282 2204.819337 15.937765" ;# +$ns_ at 0.0 "$node_(49) switch OFF" ;# set_X,Y,Z +$node_(49) set X_ 0.000000 +$node_(49) set Y_ 0.000000 +$node_(49) set Z_ 0.0 +$ns_ at 0.000000 "$node_(49) setdest 2880.947177 974.694900 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(49) switch ON" ;# inside +$ns_ at 0.010000 "$node_(49) setdest 2510.000000 1290.000000 12.480033" ;# +$ns_ at 0.0 "$node_(50) switch OFF" ;# set_X,Y,Z +$node_(50) set X_ 0.000000 +$node_(50) set Y_ 0.000000 +$node_(50) set Z_ 0.0 +$ns_ at 0.000000 "$node_(50) setdest 3263.335772 649.664594 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(50) switch ON" ;# inside +$ns_ at 0.010000 "$node_(50) setdest 2799.701274 1043.753917 12.273351" ;# +$ns_ at 0.0 "$node_(51) switch OFF" ;# set_X,Y,Z +$node_(51) set X_ 0.000000 +$node_(51) set Y_ 0.000000 +$node_(51) set Z_ 0.0 +$ns_ at 0.000000 "$node_(51) setdest 474.355810 2204.848463 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(51) switch ON" ;# inside +$ns_ at 0.010000 "$node_(51) setdest 682.726230 2169.279179 15.059437" ;# +$ns_ at 0.0 "$node_(52) switch OFF" ;# set_X,Y,Z +$node_(52) set X_ 0.000000 +$node_(52) set Y_ 0.000000 +$node_(52) set Z_ 0.0 +$ns_ at 0.000000 "$node_(52) setdest 2947.761957 2261.550302 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(52) switch ON" ;# inside +$ns_ at 0.010000 "$node_(52) setdest 2789.626910 2518.979448 9.937942" ;# +$ns_ at 0.0 "$node_(53) switch OFF" ;# set_X,Y,Z +$node_(53) set X_ 0.000000 +$node_(53) set Y_ 0.000000 +$node_(53) set Z_ 0.0 +$ns_ at 0.000000 "$node_(53) setdest 2192.087846 1617.694066 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(53) switch ON" ;# inside +$ns_ at 0.010000 "$node_(53) setdest 2038.935574 1775.558716 13.528813" ;# +$ns_ at 0.0 "$node_(54) switch OFF" ;# set_X,Y,Z +$node_(54) set X_ 0.000000 +$node_(54) set Y_ 0.000000 +$node_(54) set Z_ 0.0 +$ns_ at 0.000000 "$node_(54) setdest 3199.841733 2703.083238 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(54) switch ON" ;# inside +$ns_ at 0.010000 "$node_(54) setdest 3161.675427 2757.606532 17.588560" ;# +$ns_ at 0.0 "$node_(55) switch OFF" ;# set_X,Y,Z +$node_(55) set X_ 0.000000 +$node_(55) set Y_ 0.000000 +$node_(55) set Z_ 0.0 +$ns_ at 0.000000 "$node_(55) setdest 3295.830375 900.477312 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(55) switch ON" ;# inside +$ns_ at 0.010000 "$node_(55) setdest 3290.000000 1020.000000 14.939426" ;# +$ns_ at 0.0 "$node_(56) switch OFF" ;# set_X,Y,Z +$node_(56) set X_ 0.000000 +$node_(56) set Y_ 0.000000 +$node_(56) set Z_ 0.0 +$ns_ at 27.328226 "$node_(56) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 27.338226 "$node_(56) switch ON" ;# inside +$ns_ at 27.338226 "$node_(56) setdest 3310.000000 160.000000 13.430737" ;# +$ns_ at 0.0 "$node_(57) switch OFF" ;# set_X,Y,Z +$node_(57) set X_ 0.000000 +$node_(57) set Y_ 0.000000 +$node_(57) set Z_ 0.0 +$ns_ at 34.730846 "$node_(57) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 34.740846 "$node_(57) switch ON" ;# inside +$ns_ at 34.740846 "$node_(57) setdest 3479.270091 33.764678 13.210281" ;# +$ns_ at 0.0 "$node_(58) switch OFF" ;# set_X,Y,Z +$node_(58) set X_ 0.000000 +$node_(58) set Y_ 0.000000 +$node_(58) set Z_ 0.0 +$ns_ at 0.000000 "$node_(58) setdest 2502.168218 1298.072760 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(58) switch ON" ;# inside +$ns_ at 0.010000 "$node_(58) setdest 2113.048299 1699.165600 11.361111" ;# +$ns_ at 0.0 "$node_(59) switch OFF" ;# set_X,Y,Z +$node_(59) set X_ 0.000000 +$node_(59) set Y_ 0.000000 +$node_(59) set Z_ 0.0 +$ns_ at 0.000000 "$node_(59) setdest 3180.760450 2438.422024 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(59) switch ON" ;# inside +$ns_ at 0.010000 "$node_(59) setdest 3230.000000 2660.000000 12.603172" ;# +$ns_ at 0.0 "$node_(60) switch OFF" ;# set_X,Y,Z +$node_(60) set X_ 0.000000 +$node_(60) set Y_ 0.000000 +$node_(60) set Z_ 0.0 +$ns_ at 0.000000 "$node_(60) setdest 3298.426977 847.246971 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(60) switch ON" ;# inside +$ns_ at 0.010000 "$node_(60) setdest 3290.000000 1020.000000 13.294269" ;# +$ns_ at 0.0 "$node_(61) switch OFF" ;# set_X,Y,Z +$node_(61) set X_ 0.000000 +$node_(61) set Y_ 0.000000 +$node_(61) set Z_ 0.0 +$ns_ at 0.000000 "$node_(61) setdest 1517.875494 666.802655 1000000000.000000" ;# init_node +$ns_ at 0.010000 "$node_(61) switch ON" ;# inside +$ns_ at 0.010000 "$node_(61) setdest 1417.806992 852.644157 17.696076" ;# +$ns_ at 0.076824 "$node_(3) setdest 1860.000000 1960.000000 15.198613" ;# +$ns_ at 1.919728 "$node_(29) setdest 3310.000000 160.000000 14.971426" ;# +$ns_ at 2.020000 "$node_(34) setdest 3060.137172 110.027434 18.021479" ;# +$ns_ at 2.020000 "$node_(19) setdest 2050.787795 1763.341811 11.429272" ;# +$ns_ at 2.223263 "$node_(11) setdest 1178.615011 2083.495632 17.638126" ;# +$ns_ at 2.649143 "$node_(5) setdest 655.054915 2890.625411 16.620014" ;# +$ns_ at 2.815319 "$node_(18) setdest 1272.682302 2066.446680 18.024390" ;# +$ns_ at 2.921721 "$node_(10) setdest 2125.369766 1686.465011 15.334893" ;# +$ns_ at 3.020000 "$node_(23) setdest 1727.986402 1748.778243 13.637945" ;# +$ns_ at 3.791364 "$node_(30) setdest 400.780217 1287.070330 16.187840" ;# +$ns_ at 3.793946 "$node_(54) setdest 3090.000000 2860.000000 15.194059" ;# +$ns_ at 4.871944 "$node_(12) setdest 3090.000000 2030.000000 15.265594" ;# +$ns_ at 4.946232 "$node_(15) setdest 1565.819542 1495.109953 13.868165" ;# +$ns_ at 5.609381 "$node_(21) setdest 3310.000000 520.726879 13.636364" ;# +$ns_ at 6.020000 "$node_(2) setdest 986.595609 2117.408013 17.746939" ;# +$ns_ at 6.020000 "$node_(43) setdest 4184.308366 276.189849 10.624238" ;# +$ns_ at 0.0 "$node_(62) switch OFF" ;# set_X,Y,Z +$node_(62) set X_ 0.000000 +$node_(62) set Y_ 0.000000 +$node_(62) set Z_ 0.0 +$ns_ at 21.663345 "$node_(62) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 21.673345 "$node_(62) switch ON" ;# inside +$ns_ at 21.673345 "$node_(62) setdest 1624.591870 468.615099 15.962482" ;# +$ns_ at 7.020000 "$node_(0) setdest 1144.244259 860.324287 13.686075" ;# +$ns_ at 8.020000 "$node_(1) setdest 3310.000000 406.390980 13.636364" ;# +$ns_ at 9.020000 "$node_(14) setdest 2560.000000 10.000000 12.232374" ;# +$ns_ at 9.020000 "$node_(14) switch OFF" ;# leaving_area +$ns_ at 9.020000 "$node_(55) setdest 3267.610092 1133.069036 15.548435" ;# +#$ns_ at 10.020000 $node_(32) arrived_to 1860.000000 1960.000000 +$ns_ at 10.020000 "$node_(32) switch OFF" ;# arrived_to +$ns_ at 11.020000 "$node_(32) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 11.030000 "$node_(32) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 10.844793 "$node_(2) setdest 245.000000 2244.000000 16.292787" ;# +$ns_ at 10.878517 "$node_(17) setdest 1944.619748 1872.776568 14.878609" ;# +$ns_ at 11.937533 "$node_(61) setdest 1290.000000 1090.000000 15.780990" ;# +$ns_ at 12.020000 "$node_(26) setdest 3184.747598 1551.524630 13.728154" ;# +$ns_ at 12.511178 "$node_(18) setdest 1071.000000 2103.000000 15.172901" ;# +$ns_ at 13.020000 "$node_(54) setdest 2856.135371 2789.296740 15.963316" ;# +$ns_ at 13.020000 "$node_(12) setdest 2660.000000 2730.000000 10.953640" ;# +$ns_ at 13.020000 "$node_(29) setdest 3310.000000 610.000000 13.636364" ;# +$ns_ at 13.186257 "$node_(21) setdest 3310.000000 610.000000 15.302890" ;# +$ns_ at 0.0 "$node_(63) switch OFF" ;# set_X,Y,Z +$node_(63) set X_ 0.000000 +$node_(63) set Y_ 0.000000 +$node_(63) set Z_ 0.0 +$ns_ at 40.472571 "$node_(63) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 40.482571 "$node_(63) switch ON" ;# inside +$ns_ at 40.482571 "$node_(63) setdest 3506.004290 13.827309 13.160959" ;# +$ns_ at 14.020000 "$node_(60) setdest 3095.122467 1284.368746 15.380819" ;# +$ns_ at 14.020000 "$node_(40) setdest 3310.000000 610.000000 13.636364" ;# +$ns_ at 14.046680 "$node_(51) setdest 809.510897 2147.636760 17.612676" ;# +$ns_ at 14.114380 "$node_(11) setdest 1071.000000 2103.000000 18.519346" ;# +$ns_ at 15.020000 "$node_(7) setdest 3806.412901 2014.477749 13.272601" ;# +$ns_ at 0.0 "$node_(64) switch OFF" ;# set_X,Y,Z +$node_(64) set X_ 0.000000 +$node_(64) set Y_ 0.000000 +$node_(64) set Z_ 0.0 +$ns_ at 19.911426 "$node_(64) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 19.921426 "$node_(64) switch ON" ;# inside +$ns_ at 19.921426 "$node_(64) setdest 3362.802632 120.621766 13.629680" ;# +$ns_ at 16.020000 "$node_(27) setdest 2490.547415 1792.044791 15.855134" ;# +$ns_ at 0.0 "$node_(65) switch OFF" ;# set_X,Y,Z +$node_(65) set X_ 0.000000 +$node_(65) set Y_ 0.000000 +$node_(65) set Z_ 0.0 +$ns_ at 51.600909 "$node_(65) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 51.610909 "$node_(65) switch ON" ;# inside +$ns_ at 51.610909 "$node_(65) setdest 3310.000000 160.000000 13.629680" ;# +$ns_ at 16.111438 "$node_(22) setdest 2371.972360 1884.470213 14.981457" ;# +$ns_ at 16.159300 "$node_(34) setdest 2560.000000 10.000000 16.008495" ;# +$ns_ at 16.267702 "$node_(53) setdest 1860.000000 1960.000000 15.339731" ;# +$ns_ at 16.433257 "$node_(55) setdest 3195.265097 1498.411260 13.248144" ;# +$ns_ at 18.020000 "$node_(4) setdest 675.293496 2170.547962 18.050376" ;# +$ns_ at 18.346962 "$node_(8) setdest 3850.356305 1052.895768 15.199614" ;# +$ns_ at 18.441338 "$node_(10) setdest 1860.000000 1960.000000 12.884523" ;# +$ns_ at 19.020000 "$node_(37) setdest 3019.273244 857.117743 12.352381" ;# +$ns_ at 19.020000 "$node_(59) setdest 3090.000000 2860.000000 16.275407" ;# +$ns_ at 19.343302 "$node_(23) setdest 1822.317642 1899.708228 13.873502" ;# +$ns_ at 19.761014 "$node_(15) setdest 1610.000000 1560.000000 14.927294" ;# +$ns_ at 20.020000 "$node_(21) setdest 3044.211745 835.920017 10.938056" ;# +$ns_ at 0.0 "$node_(66) switch OFF" ;# set_X,Y,Z +$node_(66) set X_ 0.000000 +$node_(66) set Y_ 0.000000 +$node_(66) set Z_ 0.0 +$ns_ at 35.071538 "$node_(66) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 35.081538 "$node_(66) switch ON" ;# inside +$ns_ at 35.081538 "$node_(66) setdest 1740.185930 253.940416 16.589689" ;# +$ns_ at 0.0 "$node_(67) switch OFF" ;# set_X,Y,Z +$node_(67) set X_ 0.000000 +$node_(67) set Y_ 0.000000 +$node_(67) set Z_ 0.0 +$ns_ at 55.600909 "$node_(67) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 55.610909 "$node_(67) switch ON" ;# inside +$ns_ at 55.610909 "$node_(67) setdest 3310.000000 160.000000 13.629680" ;# +$ns_ at 21.020000 "$node_(11) setdest 622.932312 2179.486131 16.430355" ;# +$ns_ at 21.349295 "$node_(51) setdest 1071.000000 2103.000000 15.912438" ;# +#$ns_ at 22.020000 $node_(42) arrived_to 3930.000000 210.000000 +$ns_ at 22.020000 "$node_(42) switch OFF" ;# arrived_to +$ns_ at 23.020000 "$node_(42) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 23.030000 "$node_(42) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 23.020000 $node_(25) arrived_to 1980.000000 2190.000000 +$ns_ at 23.020000 "$node_(25) switch OFF" ;# arrived_to +$ns_ at 24.020000 "$node_(25) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 24.030000 "$node_(25) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 23.020000 "$node_(38) setdest 3213.718018 1405.224010 13.728154" ;# +$ns_ at 23.702829 "$node_(17) setdest 1860.000000 1960.000000 14.611387" ;# +$ns_ at 24.020000 "$node_(24) setdest 3886.630839 668.990288 13.427965" ;# +$ns_ at 24.744488 "$node_(13) setdest 1485.096514 727.677903 19.049920" ;# +$ns_ at 25.283097 "$node_(28) setdest 1999.747898 1815.952167 13.727766" ;# +$ns_ at 26.020000 "$node_(15) setdest 1319.230885 1852.926956 15.221304" ;# +#$ns_ at 26.020000 $node_(9) arrived_to 2560.000000 10.000000 +$ns_ at 26.020000 "$node_(9) switch OFF" ;# arrived_to +$ns_ at 27.020000 "$node_(9) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 27.030000 "$node_(9) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 26.088671 "$node_(1) setdest 3310.000000 501.409247 15.578368" ;# +$ns_ at 26.895783 "$node_(0) setdest 1111.751489 809.123558 14.424040" ;# +$ns_ at 27.020000 "$node_(18) setdest 793.293376 2150.405126 16.430355" ;# +$ns_ at 27.020000 "$node_(35) setdest 1218.992860 978.109962 14.247854" ;# +$ns_ at 27.020000 "$node_(39) setdest 2945.432575 318.346060 13.527727" ;# +$ns_ at 0.0 "$node_(68) switch OFF" ;# set_X,Y,Z +$node_(68) set X_ 0.000000 +$node_(68) set Y_ 0.000000 +$node_(68) set Z_ 0.0 +$ns_ at 43.372761 "$node_(68) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 43.382761 "$node_(68) switch ON" ;# inside +$ns_ at 43.382761 "$node_(68) setdest 1626.443588 465.176194 16.264410" ;# +#$ns_ at 28.020000 $node_(3) arrived_to 1860.000000 1960.000000 +$ns_ at 28.020000 "$node_(3) switch OFF" ;# arrived_to +$ns_ at 29.020000 "$node_(3) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 29.030000 "$node_(3) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 28.325008 "$node_(54) setdest 2728.508244 2750.711795 16.637835" ;# +$ns_ at 0.0 "$node_(69) switch OFF" ;# set_X,Y,Z +$node_(69) set X_ 0.000000 +$node_(69) set Y_ 0.000000 +$node_(69) set Z_ 0.0 +$ns_ at 29.354827 "$node_(69) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 29.364827 "$node_(69) switch ON" ;# inside +$ns_ at 29.364827 "$node_(69) setdest 3310.000000 160.000000 12.765598" ;# +$ns_ at 29.326782 "$node_(48) setdest 3579.061480 2509.711417 18.214880" ;# +$ns_ at 30.020000 "$node_(61) setdest 1344.994298 1170.772875 16.003152" ;# +$ns_ at 30.128119 "$node_(47) setdest 2671.108075 98.886460 13.527727" ;# +$ns_ at 30.410654 "$node_(52) setdest 2760.657979 2566.138174 11.977805" ;# +$ns_ at 30.754101 "$node_(43) setdest 4346.804596 318.483388 11.379102" ;# +$ns_ at 31.099924 "$node_(0) setdest 960.000000 570.000000 13.537772" ;# +$ns_ at 32.172350 "$node_(23) setdest 1860.000000 1960.000000 14.666683" ;# +$ns_ at 32.188044 "$node_(1) setdest 3310.000000 610.000000 12.295211" ;# +$ns_ at 33.020000 "$node_(41) setdest 3310.000000 368.122809 14.621366" ;# +#$ns_ at 33.020000 $node_(17) arrived_to 1860.000000 1960.000000 +$ns_ at 33.020000 "$node_(17) switch OFF" ;# arrived_to +$ns_ at 34.020000 "$node_(17) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 34.030000 "$node_(17) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 33.497734 "$node_(64) setdest 3310.000000 160.000000 14.565550" ;# +$ns_ at 33.726495 "$node_(44) setdest 2825.150685 1022.121917 15.219462" ;# +$ns_ at 34.020000 "$node_(53) setdest 1444.491111 2035.307695 15.517953" ;# +$ns_ at 34.338383 "$node_(45) setdest 1983.675546 1832.519053 13.147719" ;# +$ns_ at 34.733511 "$node_(13) setdest 1290.000000 1090.000000 15.654787" ;# +#$ns_ at 35.020000 $node_(59) arrived_to 3090.000000 2860.000000 +$ns_ at 35.020000 "$node_(59) switch OFF" ;# arrived_to +$ns_ at 36.020000 "$node_(59) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 36.030000 "$node_(59) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 35.031340 "$node_(52) setdest 2660.000000 2730.000000 10.690566" ;# +$ns_ at 35.373400 "$node_(60) setdest 3032.000000 1370.000000 18.840035" ;# +$ns_ at 36.126115 "$node_(61) setdest 1610.000000 1560.000000 13.494562" ;# +$ns_ at 36.321008 "$node_(35) setdest 960.000000 570.000000 13.170769" ;# +$ns_ at 36.338804 "$node_(54) setdest 2660.000000 2730.000000 19.442226" ;# +$ns_ at 37.750015 "$node_(57) setdest 3310.000000 160.000000 14.797356" ;# +$ns_ at 38.020000 "$node_(23) setdest 1980.000000 2190.000000 13.653812" ;# +$ns_ at 38.037306 "$node_(20) setdest 3802.957225 2529.373416 12.845117" ;# +$ns_ at 38.173057 "$node_(8) setdest 3810.000000 1480.000000 13.060778" ;# +$ns_ at 39.020000 "$node_(51) setdest 1437.648683 2036.547831 15.741164" ;# +$ns_ at 39.020000 "$node_(64) setdest 3310.000000 610.000000 13.636364" ;# +$ns_ at 39.066531 "$node_(44) setdest 2510.000000 1290.000000 13.362525" ;# +$ns_ at 0.0 "$node_(70) switch OFF" ;# set_X,Y,Z +$node_(70) set X_ 0.000000 +$node_(70) set Y_ 0.000000 +$node_(70) set Z_ 0.0 +$ns_ at 40.803139 "$node_(70) setdest 3917.755102 10.000000 1000000000.000000" ;# init_node +$ns_ at 40.813139 "$node_(70) switch ON" ;# inside +$ns_ at 40.813139 "$node_(70) setdest 3921.897255 77.655162 14.231013" ;# +$ns_ at 39.756789 "$node_(22) setdest 2132.313140 2071.276830 18.619493" ;# +$ns_ at 40.020000 "$node_(49) setdest 2411.643775 1391.382570 14.280623" ;# +$ns_ at 40.259448 "$node_(4) setdest 245.000000 2244.000000 15.177654" ;# +$ns_ at 40.969015 "$node_(63) setdest 3379.387957 108.253049 14.844106" ;# +#$ns_ at 41.020000 $node_(54) arrived_to 2660.000000 2730.000000 +$ns_ at 41.020000 "$node_(54) switch OFF" ;# arrived_to +$ns_ at 42.020000 "$node_(54) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 42.030000 "$node_(54) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 42.020000 "$node_(60) setdest 2648.452720 1668.962709 15.306413" ;# +$ns_ at 42.020000 "$node_(1) setdest 2860.842523 991.783855 12.842619" ;# +$ns_ at 44.020000 "$node_(6) setdest 2560.000000 10.000000 15.881382" ;# +$ns_ at 44.020000 "$node_(6) switch OFF" ;# leaving_area +$ns_ at 44.038988 "$node_(28) setdest 1860.000000 1960.000000 15.460807" ;# +$ns_ at 44.166535 "$node_(18) setdest 705.713161 2165.355259 18.400794" ;# +$ns_ at 44.199506 "$node_(5) setdest 443.743582 3002.365959 18.819432" ;# +$ns_ at 44.545590 "$node_(55) setdest 3177.366049 1588.801450 14.749930" ;# +$ns_ at 0.0 "$node_(71) switch OFF" ;# set_X,Y,Z +$node_(71) set X_ 0.000000 +$node_(71) set Y_ 0.000000 +$node_(71) set Z_ 0.0 +$ns_ at 48.463739 "$node_(71) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 48.473739 "$node_(71) switch ON" ;# inside +$ns_ at 48.473739 "$node_(71) setdest 1290.000000 1090.000000 16.454428" ;# +$ns_ at 44.815166 "$node_(30) setdest 10.000000 1373.675675 19.086673" ;# +$ns_ at 65.785924 "$node_(30) switch OFF" ;# leaving_area +$ns_ at 45.020000 "$node_(33) setdest 3310.000000 435.072554 13.066308" ;# +$ns_ at 45.510099 "$node_(43) setdest 4660.000000 400.000000 10.270737" ;# +$ns_ at 45.576106 "$node_(70) setdest 3930.000000 210.000000 12.695710" ;# +$ns_ at 0.0 "$node_(72) switch OFF" ;# set_X,Y,Z +$node_(72) set X_ 0.000000 +$node_(72) set Y_ 0.000000 +$node_(72) set Z_ 0.0 +$ns_ at 67.289997 "$node_(72) setdest 10.000000 518.541114 1000000000.000000" ;# init_node +$ns_ at 67.299997 "$node_(72) switch ON" ;# inside +$ns_ at 67.299997 "$node_(72) setdest 100.000000 470.000000 13.245560" ;# +$ns_ at 47.020000 "$node_(56) setdest 3100.811579 118.162316 14.610681" ;# +$ns_ at 47.020000 "$node_(29) setdest 2871.215338 982.966963 12.885176" ;# +$ns_ at 47.254156 "$node_(41) setdest 3310.000000 610.000000 12.889226" ;# +$ns_ at 0.0 "$node_(73) switch OFF" ;# set_X,Y,Z +$node_(73) set X_ 0.000000 +$node_(73) set Y_ 0.000000 +$node_(73) set Z_ 0.0 +$ns_ at 50.986223 "$node_(73) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 50.996223 "$node_(73) switch ON" ;# inside +$ns_ at 50.996223 "$node_(73) setdest 3310.000000 160.000000 14.738798" ;# +$ns_ at 47.893835 "$node_(48) setdest 3800.000000 2970.000000 15.892582" ;# +#$ns_ at 48.020000 $node_(40) arrived_to 3310.000000 610.000000 +$ns_ at 48.020000 "$node_(40) switch OFF" ;# arrived_to +$ns_ at 49.020000 "$node_(40) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 49.030000 "$node_(40) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 48.685196 "$node_(11) setdest 494.489546 2201.411591 17.638474" ;# +$ns_ at 48.994971 "$node_(18) setdest 245.000000 2244.000000 16.102564" ;# +$ns_ at 49.020000 "$node_(34) setdest 2560.000000 10.000000 14.572952" ;# +$ns_ at 49.020000 "$node_(34) switch OFF" ;# leaving_area +$ns_ at 49.020000 "$node_(10) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 49.197879 "$node_(58) setdest 1860.000000 1960.000000 14.073656" ;# +$ns_ at 49.588366 "$node_(50) setdest 2510.000000 1290.000000 13.372981" ;# +$ns_ at 49.673763 "$node_(31) setdest 3810.000000 1480.000000 14.690782" ;# +$ns_ at 49.909718 "$node_(37) setdest 2895.038572 962.717214 13.832905" ;# +$ns_ at 49.911226 "$node_(49) setdest 2167.765222 1642.765079 12.740107" ;# +$ns_ at 50.020000 "$node_(69) setdest 3310.000000 394.728837 13.636364" ;# +$ns_ at 50.474190 "$node_(36) setdest 2510.000000 1290.000000 14.788989" ;# +$ns_ at 50.792760 "$node_(55) setdest 3090.000000 2030.000000 13.536046" ;# +$ns_ at 0.0 "$node_(74) switch OFF" ;# set_X,Y,Z +$node_(74) set X_ 0.000000 +$node_(74) set Y_ 0.000000 +$node_(74) set Z_ 0.0 +$ns_ at 66.494791 "$node_(74) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 66.504791 "$node_(74) switch ON" ;# inside +$ns_ at 66.504791 "$node_(74) setdest 1473.664290 748.909176 16.136236" ;# +$ns_ at 51.467543 "$node_(45) setdest 1860.000000 1960.000000 14.149804" ;# +$ns_ at 51.489652 "$node_(26) setdest 3150.170530 1726.138824 15.687276" ;# +$ns_ at 51.609540 "$node_(63) setdest 3310.000000 160.000000 15.998430" ;# +$ns_ at 51.625744 "$node_(38) setdest 3166.147644 1645.454398 15.199707" ;# +$ns_ at 51.782074 "$node_(66) setdest 1604.241888 506.407922 17.882141" ;# +$ns_ at 51.911523 "$node_(21) setdest 2745.055228 1090.203056 11.797218" ;# +#$ns_ at 53.020000 $node_(0) arrived_to 960.000000 570.000000 +$ns_ at 53.020000 "$node_(0) switch OFF" ;# arrived_to +$ns_ at 54.020000 "$node_(0) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 54.030000 "$node_(0) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 53.020000 "$node_(57) setdest 3310.000000 610.000000 13.636364" ;# +$ns_ at 53.135829 "$node_(15) setdest 1071.000000 2103.000000 18.658828" ;# +$ns_ at 54.020000 "$node_(52) setdest 2682.314562 2813.307698 18.212495" ;# +$ns_ at 54.304528 "$node_(62) setdest 1421.963170 844.925541 16.589689" ;# +$ns_ at 0.0 "$node_(75) switch OFF" ;# set_X,Y,Z +$node_(75) set X_ 0.000000 +$node_(75) set Y_ 0.000000 +$node_(75) set Z_ 0.0 +$ns_ at 89.010001 "$node_(75) setdest 2560.000000 10.000000 1000000000.000000" ;# init_node +$ns_ at 89.020001 "$node_(75) switch ON" ;# inside +$ns_ at 89.020001 "$node_(75) setdest 2560.000000 10.000000 16.187162" ;# +$ns_ at 55.045844 "$node_(47) setdest 2560.000000 10.000000 14.265643" ;# +$ns_ at 55.290162 "$node_(7) setdest 3803.495480 2449.173521 12.392857" ;# +$ns_ at 56.072495 "$node_(11) setdest 245.000000 2244.000000 15.870723" ;# +$ns_ at 56.076454 "$node_(22) setdest 1980.000000 2190.000000 17.646729" ;# +$ns_ at 56.901083 "$node_(5) setdest 429.306930 3010.000000 15.589882" ;# +$ns_ at 57.948609 "$node_(5) switch OFF" ;# leaving_area +#$ns_ at 57.020000 $node_(70) arrived_to 3930.000000 210.000000 +$ns_ at 57.020000 "$node_(70) switch OFF" ;# arrived_to +$ns_ at 58.020000 "$node_(70) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 58.030000 "$node_(70) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 0.0 "$node_(76) switch OFF" ;# set_X,Y,Z +$node_(76) set X_ 0.000000 +$node_(76) set Y_ 0.000000 +$node_(76) set Z_ 0.0 +$ns_ at 68.010000 "$node_(76) setdest 3838.461538 3010.000000 1000000000.000000" ;# init_node +$ns_ at 68.020000 "$node_(76) switch ON" ;# inside +$ns_ at 68.020000 "$node_(76) setdest 3800.000000 2970.000000 27.745675" ;# +$ns_ at 58.020000 "$node_(2) setdest 10.000000 2297.153203 27.467800" ;# +$ns_ at 66.791588 "$node_(2) switch OFF" ;# leaving_area +$ns_ at 58.020000 "$node_(28) setdest 1749.929190 1783.886705 13.873502" ;# +$ns_ at 58.020000 "$node_(63) setdest 3310.000000 327.330076 13.636364" ;# +$ns_ at 58.020000 "$node_(23) setdest 2196.975090 2362.303748 14.877269" ;# +$ns_ at 58.353920 "$node_(24) setdest 3860.098415 949.791769 15.165341" ;# +$ns_ at 58.755457 "$node_(52) setdest 2735.000000 3010.000000 16.082464" ;# +$ns_ at 71.416836 "$node_(52) switch OFF" ;# leaving_area +$ns_ at 0.0 "$node_(77) switch OFF" ;# set_X,Y,Z +$node_(77) set X_ 0.000000 +$node_(77) set Y_ 0.000000 +$node_(77) set Z_ 0.0 +$ns_ at 86.590419 "$node_(77) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 86.600419 "$node_(77) switch ON" ;# inside +$ns_ at 86.600419 "$node_(77) setdest 3507.896464 12.416196 13.163994" ;# +$ns_ at 59.318759 "$node_(27) setdest 2209.659280 2010.988013 16.467044" ;# +$ns_ at 59.721921 "$node_(19) setdest 1860.000000 1960.000000 13.498673" ;# +$ns_ at 0.0 "$node_(78) switch OFF" ;# set_X,Y,Z +$node_(78) set X_ 0.000000 +$node_(78) set Y_ 0.000000 +$node_(78) set Z_ 0.0 +$ns_ at 76.468432 "$node_(78) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 76.478432 "$node_(78) switch ON" ;# inside +$ns_ at 76.478432 "$node_(78) setdest 3310.000000 160.000000 12.839810" ;# +$ns_ at 61.232236 "$node_(53) setdest 1071.000000 2103.000000 17.421516" ;# +$ns_ at 61.621042 "$node_(56) setdest 2898.815759 77.763152 19.400182" ;# +$ns_ at 61.696874 "$node_(37) setdest 2510.000000 1290.000000 11.940049" ;# +$ns_ at 62.020000 "$node_(13) setdest 1100.568594 791.502028 13.103689" ;# +$ns_ at 62.691820 "$node_(51) setdest 1742.898093 1981.223793 16.364369" ;# +$ns_ at 62.836730 "$node_(26) setdest 3090.000000 2030.000000 12.808911" ;# +$ns_ at 63.507618 "$node_(39) setdest 3058.719372 408.975498 14.499594" ;# +$ns_ at 0.0 "$node_(79) switch OFF" ;# set_X,Y,Z +$node_(79) set X_ 0.000000 +$node_(79) set Y_ 0.000000 +$node_(79) set Z_ 0.0 +$ns_ at 73.701755 "$node_(79) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 73.711755 "$node_(79) switch ON" ;# inside +$ns_ at 73.711755 "$node_(79) setdest 3310.000000 160.000000 12.355081" ;# +$ns_ at 65.020000 "$node_(45) setdest 1433.581205 2037.285029 16.364369" ;# +#$ns_ at 66.020000 $node_(47) arrived_to 2560.000000 10.000000 +$ns_ at 66.020000 "$node_(47) switch OFF" ;# arrived_to +$ns_ at 67.020000 "$node_(47) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 67.030000 "$node_(47) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 66.072048 "$node_(33) setdest 3310.000000 610.000000 14.640790" ;# +$ns_ at 67.020000 "$node_(41) setdest 3303.787354 737.359240 13.682917" ;# +$ns_ at 67.233448 "$node_(69) setdest 3310.000000 480.277751 15.860949" ;# +$ns_ at 67.737571 "$node_(38) setdest 3090.000000 2030.000000 12.945212" ;# +$ns_ at 67.817144 "$node_(66) setdest 1290.000000 1090.000000 16.086701" ;# +#$ns_ at 68.020000 $node_(22) arrived_to 1980.000000 2190.000000 +$ns_ at 68.020000 "$node_(22) switch OFF" ;# arrived_to +$ns_ at 69.020000 "$node_(22) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 69.030000 "$node_(22) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 68.020000 "$node_(36) setdest 2035.070740 1779.542468 13.169265" ;# +$ns_ at 69.020000 "$node_(73) setdest 3310.000000 610.000000 13.636364" ;# +$ns_ at 70.020000 "$node_(4) setdest 10.000000 2297.153203 26.882564" ;# +$ns_ at 78.982546 "$node_(4) switch OFF" ;# leaving_area +$ns_ at 70.290872 "$node_(63) setdest 3310.000000 393.291200 15.612614" ;# +$ns_ at 71.020000 "$node_(76) setdest 3682.872943 2725.985298 18.171700" ;# +$ns_ at 71.020000 "$node_(65) setdest 3310.000000 249.628909 15.700741" ;# +$ns_ at 71.020000 "$node_(44) setdest 1860.000000 1960.000000 13.727766" ;# +$ns_ at 0.0 "$node_(80) switch OFF" ;# set_X,Y,Z +$node_(80) set X_ 0.000000 +$node_(80) set Y_ 0.000000 +$node_(80) set Z_ 0.0 +$ns_ at 77.881324 "$node_(80) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 77.891324 "$node_(80) switch ON" ;# inside +$ns_ at 77.891324 "$node_(80) setdest 3310.000000 160.000000 14.648535" ;# +$ns_ at 72.020000 "$node_(8) setdest 3803.933314 2383.936182 12.715764" ;# +$ns_ at 72.020000 "$node_(61) setdest 1071.000000 2103.000000 16.632495" ;# +$ns_ at 72.239299 "$node_(56) setdest 2849.588535 67.917707 19.419495" ;# +$ns_ at 72.348937 "$node_(20) setdest 3800.000000 2970.000000 14.850716" ;# +$ns_ at 72.627130 "$node_(69) setdest 3310.000000 610.000000 12.481851" ;# +$ns_ at 72.989630 "$node_(28) setdest 1710.732502 1721.172003 15.240545" ;# +#$ns_ at 73.020000 $node_(15) arrived_to 1071.000000 2103.000000 +$ns_ at 73.020000 "$node_(15) switch OFF" ;# arrived_to +$ns_ at 74.020000 "$node_(15) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 74.030000 "$node_(15) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 73.020000 "$node_(11) setdest 10.000000 2297.153203 32.054187" ;# +$ns_ at 80.536529 "$node_(11) switch OFF" ;# leaving_area +#$ns_ at 73.020000 $node_(64) arrived_to 3310.000000 610.000000 +$ns_ at 73.020000 "$node_(64) switch OFF" ;# arrived_to +$ns_ at 74.020000 "$node_(64) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 74.030000 "$node_(64) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 73.513269 "$node_(39) setdest 3310.000000 610.000000 13.130931" ;# +$ns_ at 73.790965 "$node_(60) setdest 2288.942757 1949.189106 16.467044" ;# +#$ns_ at 74.020000 $node_(35) arrived_to 960.000000 570.000000 +$ns_ at 74.020000 "$node_(35) switch OFF" ;# arrived_to +$ns_ at 75.020000 "$node_(35) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 75.030000 "$node_(35) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 74.515733 "$node_(63) setdest 3310.000000 610.000000 13.130472" ;# +$ns_ at 74.824440 "$node_(56) setdest 2560.000000 10.000000 16.230527" ;# +$ns_ at 75.020000 "$node_(67) setdest 3310.000000 377.483559 13.636364" ;# +$ns_ at 75.168046 "$node_(68) setdest 1429.744513 830.474476 16.589689" ;# +#$ns_ at 76.020000 $node_(72) arrived_to 100.000000 470.000000 +$ns_ at 76.020000 "$node_(72) switch OFF" ;# arrived_to +$ns_ at 77.020000 "$node_(72) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 77.030000 "$node_(72) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 76.020000 "$node_(58) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 76.338969 "$node_(41) setdest 3298.983616 835.835864 15.904662" ;# +$ns_ at 76.643591 "$node_(23) setdest 2382.278109 2509.456145 18.587284" ;# +$ns_ at 76.728578 "$node_(65) setdest 3310.000000 610.000000 13.204556" ;# +$ns_ at 76.952393 "$node_(24) setdest 3810.000000 1480.000000 12.659855" ;# +$ns_ at 77.204488 "$node_(16) setdest 3800.000000 2970.000000 13.831303" ;# +$ns_ at 77.402569 "$node_(49) setdest 2082.185204 1730.978328 15.039381" ;# +$ns_ at 77.842223 "$node_(28) setdest 1610.000000 1560.000000 13.405608" ;# +#$ns_ at 78.020000 $node_(43) arrived_to 4660.000000 400.000000 +$ns_ at 78.020000 "$node_(43) switch OFF" ;# arrived_to +$ns_ at 79.020000 "$node_(43) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 79.030000 "$node_(43) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 79.020000 $node_(18) arrived_to 245.000000 2244.000000 +$ns_ at 79.020000 "$node_(18) switch OFF" ;# arrived_to +$ns_ at 80.020000 "$node_(18) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 80.030000 "$node_(18) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 79.020000 "$node_(50) setdest 2232.243741 1576.302606 12.801209" ;# +$ns_ at 79.020000 "$node_(33) setdest 3068.928899 814.910436 12.447342" ;# +$ns_ at 80.067320 "$node_(62) setdest 1290.000000 1090.000000 18.615038" ;# +$ns_ at 0.0 "$node_(81) switch OFF" ;# set_X,Y,Z +$node_(81) set X_ 0.000000 +$node_(81) set Y_ 0.000000 +$node_(81) set Z_ 0.0 +$ns_ at 81.503502 "$node_(81) setdest 3917.755102 10.000000 1000000000.000000" ;# init_node +$ns_ at 81.513502 "$node_(81) switch ON" ;# inside +$ns_ at 81.513502 "$node_(81) setdest 3930.000000 210.000000 12.921969" ;# +$ns_ at 80.946077 "$node_(27) setdest 1980.000000 2190.000000 18.115363" ;# +$ns_ at 81.020000 "$node_(48) setdest 3838.461538 3010.000000 29.888688" ;# +$ns_ at 82.876600 "$node_(48) switch OFF" ;# leaving_area +$ns_ at 81.020000 "$node_(19) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 81.649008 "$node_(51) setdest 1860.000000 1960.000000 18.679926" ;# +$ns_ at 82.538014 "$node_(41) setdest 3290.000000 1020.000000 12.731894" ;# +#$ns_ at 83.020000 $node_(31) arrived_to 3810.000000 1480.000000 +$ns_ at 83.020000 "$node_(31) switch OFF" ;# arrived_to +$ns_ at 84.020000 "$node_(31) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 84.030000 "$node_(31) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 0.0 "$node_(82) switch OFF" ;# set_X,Y,Z +$node_(82) set X_ 0.000000 +$node_(82) set Y_ 0.000000 +$node_(82) set Z_ 0.0 +$ns_ at 89.213655 "$node_(82) setdest 3511.136363 10.000000 1000000000.000000" ;# init_node +$ns_ at 89.223655 "$node_(82) switch ON" ;# inside +$ns_ at 89.223655 "$node_(82) setdest 3310.000000 160.000000 13.348873" ;# +$ns_ at 0.0 "$node_(83) switch OFF" ;# set_X,Y,Z +$node_(83) set X_ 0.000000 +$node_(83) set Y_ 0.000000 +$node_(83) set Z_ 0.0 +$ns_ at 111.088639 "$node_(83) setdest 565.476191 10.000000 1000000000.000000" ;# init_node +$ns_ at 111.098639 "$node_(83) switch ON" ;# inside +$ns_ at 111.098639 "$node_(83) setdest 100.000000 470.000000 12.851619" ;# +$ns_ at 84.020000 "$node_(69) setdest 2946.763505 918.751021 13.460928" ;# +$ns_ at 84.020000 "$node_(53) setdest 759.665364 2156.145501 18.893733" ;# +$ns_ at 85.020000 "$node_(55) setdest 2660.000000 2730.000000 11.101662" ;# +$ns_ at 85.192685 "$node_(21) setdest 2510.000000 1290.000000 12.947158" ;# +$ns_ at 85.574748 "$node_(49) setdest 1860.000000 1960.000000 12.540179" ;# +$ns_ at 85.915106 "$node_(76) setdest 3471.121930 2284.837355 16.045433" ;# +$ns_ at 86.907442 "$node_(77) setdest 3429.356254 70.988556 15.578326" ;# +$ns_ at 87.020000 "$node_(57) setdest 2948.388016 917.370186 13.815163" ;# +$ns_ at 87.921266 "$node_(1) setdest 2510.000000 1290.000000 14.806388" ;# +#$ns_ at 88.020000 $node_(26) arrived_to 3090.000000 2030.000000 +$ns_ at 88.020000 "$node_(26) switch OFF" ;# arrived_to +$ns_ at 89.020000 "$node_(26) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 89.030000 "$node_(26) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 88.999624 "$node_(13) setdest 1031.332476 682.402690 14.209679" ;# +#$ns_ at 89.020000 $node_(12) arrived_to 2660.000000 2730.000000 +$ns_ at 89.020000 "$node_(12) switch OFF" ;# arrived_to +$ns_ at 90.020000 "$node_(12) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 90.030000 "$node_(12) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 89.020000 "$node_(51) setdest 1980.000000 2190.000000 13.653812" ;# +$ns_ at 89.374028 "$node_(23) setdest 2507.500076 2608.897119 18.743439" ;# +$ns_ at 90.020000 "$node_(75) setdest 3064.341849 413.473479 13.129175" ;# +$ns_ at 90.367268 "$node_(7) setdest 3801.239648 2785.292469 16.164570" ;# +$ns_ at 90.968794 "$node_(67) setdest 3310.000000 427.728101 15.991769" ;# +$ns_ at 91.502283 "$node_(45) setdest 1369.887024 2048.829094 18.088682" ;# +$ns_ at 91.713123 "$node_(29) setdest 2510.000000 1290.000000 14.674077" ;# +$ns_ at 92.020000 "$node_(63) setdest 3044.881012 835.351140 13.124405" ;# +$ns_ at 0.0 "$node_(84) switch OFF" ;# set_X,Y,Z +$node_(84) set X_ 0.000000 +$node_(84) set Y_ 0.000000 +$node_(84) set Z_ 0.0 +$ns_ at 98.711006 "$node_(84) setdest 3511.136364 10.000000 1000000000.000000" ;# init_node +$ns_ at 98.721006 "$node_(84) switch ON" ;# inside +$ns_ at 98.721006 "$node_(84) setdest 3466.202399 43.510075 15.509769" ;# +#$ns_ at 93.020000 $node_(28) arrived_to 1610.000000 1560.000000 +$ns_ at 93.020000 "$node_(28) switch OFF" ;# arrived_to +$ns_ at 94.020000 "$node_(28) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 94.030000 "$node_(28) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 93.196690 "$node_(77) setdest 3310.000000 160.000000 12.593125" ;# +#$ns_ at 94.020000 $node_(56) arrived_to 2560.000000 10.000000 +$ns_ at 94.020000 "$node_(56) switch OFF" ;# arrived_to +$ns_ at 95.020000 "$node_(56) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 95.030000 "$node_(56) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 94.110694 "$node_(67) setdest 3310.000000 610.000000 13.104314" ;# +$ns_ at 95.020000 "$node_(79) setdest 3310.000000 326.832286 12.456113" ;# +$ns_ at 95.080867 "$node_(45) setdest 1071.000000 2103.000000 16.038557" ;# +$ns_ at 0.0 "$node_(85) switch OFF" ;# set_X,Y,Z +$node_(85) set X_ 0.000000 +$node_(85) set Y_ 0.000000 +$node_(85) set Z_ 0.0 +$ns_ at 107.010001 "$node_(85) setdest 2560.000000 10.000000 1000000000.000000" ;# init_node +$ns_ at 107.020001 "$node_(85) switch ON" ;# inside +$ns_ at 107.020001 "$node_(85) setdest 2560.000000 10.000000 15.432186" ;# +$ns_ at 96.020000 "$node_(80) setdest 3310.000000 264.084004 14.479894" ;# +#$ns_ at 96.020000 $node_(62) arrived_to 1290.000000 1090.000000 +$ns_ at 96.020000 "$node_(62) switch OFF" ;# arrived_to +$ns_ at 97.020000 "$node_(62) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 97.030000 "$node_(62) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 97.020000 "$node_(78) setdest 2873.391011 72.678202 15.284245" ;# +$ns_ at 97.905187 "$node_(23) setdest 2660.000000 2730.000000 14.848559" ;# +$ns_ at 98.020000 "$node_(41) setdest 3207.358318 1437.340495 15.535574" ;# +$ns_ at 98.020000 "$node_(27) setdest 851.301630 2786.850971 16.620014" ;# +$ns_ at 98.020000 "$node_(81) setdest 4246.010292 292.249254 10.932187" ;# +$ns_ at 98.093016 "$node_(13) setdest 960.000000 570.000000 12.183288" ;# +$ns_ at 99.020000 "$node_(10) setdest 825.195870 2144.959301 18.438249" ;# +$ns_ at 99.020000 "$node_(38) setdest 2867.393542 2392.382607 10.669130" ;# +$ns_ at 99.020000 "$node_(39) setdest 3290.000000 1020.000000 13.682917" ;# +$ns_ at 100.020000 "$node_(16) setdest 3802.644628 3010.000000 14.410845" ;# +$ns_ at 102.801747 "$node_(16) switch OFF" ;# leaving_area +$ns_ at 100.176928 "$node_(68) setdest 1290.000000 1090.000000 17.500228" ;# +$ns_ at 100.736553 "$node_(53) setdest 245.000000 2244.000000 15.229216" ;# +$ns_ at 101.471866 "$node_(60) setdest 1980.000000 2190.000000 18.178300" ;# +$ns_ at 102.335078 "$node_(84) setdest 3310.000000 160.000000 12.423179" ;# +$ns_ at 103.020000 "$node_(20) setdest 3838.461538 3010.000000 31.691224" ;# +$ns_ at 104.771001 "$node_(20) switch OFF" ;# leaving_area +$ns_ at 103.020000 "$node_(73) setdest 3301.533898 783.555084 13.682917" ;# +$ns_ at 103.208174 "$node_(80) setdest 3310.000000 610.000000 13.401455" ;# +$ns_ at 104.438397 "$node_(33) setdest 2879.338395 976.062364 14.543216" ;# +$ns_ at 105.020000 "$node_(37) setdest 2261.715038 1545.924499 12.202857" ;# +$ns_ at 105.020000 "$node_(65) setdest 3301.141878 791.591494 13.682917" ;# +$ns_ at 106.020000 "$node_(77) setdest 3310.000000 406.827472 12.451045" ;# +$ns_ at 108.020000 "$node_(85) setdest 3055.111374 406.089099 12.993422" ;# +$ns_ at 108.413608 "$node_(79) setdest 3310.000000 478.314095 13.636364" ;# +$ns_ at 109.020000 "$node_(51) setdest 2123.704561 2304.118328 17.343151" ;# +$ns_ at 109.020000 "$node_(67) setdest 3300.899735 796.555442 13.682917" ;# +$ns_ at 109.020000 "$node_(82) setdest 3310.000000 510.344385 13.220467" ;# +$ns_ at 110.020000 "$node_(21) setdest 2052.051993 1762.038715 13.218839" ;# +#$ns_ at 110.020000 $node_(13) arrived_to 960.000000 570.000000 +$ns_ at 110.020000 "$node_(13) switch OFF" ;# arrived_to +$ns_ at 111.020000 "$node_(13) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 111.030000 "$node_(13) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 110.020000 "$node_(66) setdest 1390.631497 1237.802511 13.489251" ;# +$ns_ at 110.180777 "$node_(50) setdest 2018.905962 1796.204624 13.528813" ;# +$ns_ at 0.0 "$node_(86) switch OFF" ;# set_X,Y,Z +$node_(86) set X_ 0.000000 +$node_(86) set Y_ 0.000000 +$node_(86) set Z_ 0.0 +$ns_ at 116.580034 "$node_(86) setdest 1871.538461 10.000000 1000000000.000000" ;# init_node +$ns_ at 116.590034 "$node_(86) switch ON" ;# inside +$ns_ at 116.590034 "$node_(86) setdest 1595.895451 521.908448 16.360244" ;# +$ns_ at 111.161296 "$node_(7) setdest 3800.000000 2970.000000 15.576043" ;# +$ns_ at 112.020000 "$node_(49) setdest 1447.048442 2034.844199 16.364369" ;# +$ns_ at 112.020000 "$node_(23) setdest 2735.000000 3010.000000 16.564038" ;# +$ns_ at 129.520000 "$node_(23) switch OFF" ;# leaving_area +$ns_ at 112.544044 "$node_(10) setdest 245.000000 2244.000000 15.705761" ;# +$ns_ at 115.020000 "$node_(45) setdest 800.877206 2149.110550 15.532960" ;# +$ns_ at 115.719153 "$node_(73) setdest 3298.548961 844.746298 14.406345" ;# +$ns_ at 116.412026 "$node_(76) setdest 3315.478202 1960.579587 18.536554" ;# +$ns_ at 118.020000 "$node_(68) setdest 398.108304 1287.662484 16.621823" ;# +$ns_ at 118.307183 "$node_(65) setdest 3299.114853 833.145514 14.465543" ;# +$ns_ at 118.513219 "$node_(74) setdest 1290.000000 1090.000000 18.012730" ;# +$ns_ at 118.531898 "$node_(63) setdest 2958.817947 908.504745 14.362559" ;# +$ns_ at 119.020000 "$node_(61) setdest 747.339233 2158.249598 16.430355" ;# +#$ns_ at 119.020000 $node_(84) arrived_to 3310.000000 160.000000 +$ns_ at 119.020000 "$node_(84) switch OFF" ;# arrived_to +$ns_ at 120.020000 "$node_(84) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 120.030000 "$node_(84) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 119.435558 "$node_(69) setdest 2773.538937 1065.991904 14.458335" ;# +$ns_ at 119.522273 "$node_(79) setdest 3310.000000 610.000000 15.496606" ;# +$ns_ at 119.600819 "$node_(51) setdest 2660.000000 2730.000000 16.144277" ;# +$ns_ at 119.812016 "$node_(36) setdest 1860.000000 1960.000000 15.512436" ;# +$ns_ at 119.971721 "$node_(73) setdest 3290.000000 1020.000000 13.447144" ;# +$ns_ at 120.020000 "$node_(24) setdest 3808.480944 1706.339332 14.637236" ;# +$ns_ at 120.020000 "$node_(1) setdest 2405.157699 1398.068218 14.457381" ;# +$ns_ at 121.183219 "$node_(65) setdest 3290.000000 1020.000000 13.520245" ;# +$ns_ at 121.373138 "$node_(57) setdest 2805.464211 1038.855421 15.476236" ;# +$ns_ at 121.547835 "$node_(33) setdest 2831.663988 1016.585611 14.964355" ;# +$ns_ at 122.670398 "$node_(67) setdest 3297.875780 858.546515 15.283891" ;# +$ns_ at 123.275587 "$node_(66) setdest 1517.151500 1423.628766 12.841373" ;# +$ns_ at 124.020000 "$node_(60) setdest 1269.458678 2565.731275 14.975446" ;# +#$ns_ at 124.020000 $node_(71) arrived_to 1290.000000 1090.000000 +$ns_ at 124.020000 "$node_(71) switch OFF" ;# arrived_to +$ns_ at 125.020000 "$node_(71) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 125.030000 "$node_(71) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 124.020000 "$node_(7) setdest 3838.461538 3010.000000 27.745675" ;# +$ns_ at 126.020000 "$node_(7) switch OFF" ;# leaving_area +$ns_ at 125.020000 "$node_(29) setdest 2314.893745 1491.109525 12.787508" ;# +$ns_ at 125.405158 "$node_(41) setdest 3090.000000 2030.000000 12.688636" ;# +$ns_ at 125.729092 "$node_(33) setdest 2510.000000 1290.000000 13.073798" ;# +$ns_ at 125.843836 "$node_(77) setdest 3310.000000 610.000000 15.419704" ;# +$ns_ at 126.020000 "$node_(58) setdest 764.196652 2155.372000 16.430355" ;# +$ns_ at 126.151669 "$node_(78) setdest 2560.000000 10.000000 18.946593" ;# +$ns_ at 126.396280 "$node_(63) setdest 2510.000000 1290.000000 12.910978" ;# +$ns_ at 126.731196 "$node_(67) setdest 3290.000000 1020.000000 13.153880" ;# +$ns_ at 0.0 "$node_(87) switch OFF" ;# set_X,Y,Z +$node_(87) set X_ 0.000000 +$node_(87) set Y_ 0.000000 +$node_(87) set Z_ 0.0 +$ns_ at 140.829201 "$node_(87) setdest 1871.538461 10.000000 1000000000.000000" ;# init_node +$ns_ at 140.839201 "$node_(87) switch ON" ;# inside +$ns_ at 140.839201 "$node_(87) setdest 1864.515162 23.043270 18.081091" ;# +$ns_ at 127.889465 "$node_(81) setdest 4348.345188 318.884364 12.272889" ;# +$ns_ at 129.020000 "$node_(79) setdest 3296.280996 891.239581 13.369011" ;# +$ns_ at 130.020000 "$node_(80) setdest 2871.249270 982.938121 13.608044" ;# +$ns_ at 130.020000 "$node_(39) setdest 3195.904728 1495.181122 15.338174" ;# +$ns_ at 130.434594 "$node_(1) setdest 1860.000000 1960.000000 13.363744" ;# +$ns_ at 131.020000 "$node_(19) setdest 245.000000 2244.000000 16.430355" ;# +$ns_ at 132.661848 "$node_(45) setdest 576.051317 2187.488819 17.655915" ;# +$ns_ at 132.827402 "$node_(50) setdest 1860.000000 1960.000000 15.021165" ;# +$ns_ at 0.0 "$node_(88) switch OFF" ;# set_X,Y,Z +$node_(88) set X_ 0.000000 +$node_(88) set Y_ 0.000000 +$node_(88) set Z_ 0.0 +$ns_ at 157.137696 "$node_(88) setdest 565.476191 10.000000 1000000000.000000" ;# init_node +$ns_ at 157.147696 "$node_(88) switch ON" ;# inside +$ns_ at 157.147696 "$node_(88) setdest 447.380636 126.706195 12.862592" ;# +$ns_ at 133.493591 "$node_(57) setdest 2510.000000 1290.000000 13.133300" ;# +$ns_ at 134.020000 "$node_(73) setdest 3245.511748 1080.352279 17.620032" ;# +$ns_ at 134.240277 "$node_(37) setdest 2044.074180 1770.261999 16.010145" ;# +$ns_ at 135.159840 "$node_(69) setdest 2510.000000 1290.000000 12.877033" ;# +$ns_ at 135.483604 "$node_(24) setdest 3805.479210 2153.597670 12.883208" ;# +$ns_ at 135.520151 "$node_(82) setdest 3310.000000 610.000000 15.331992" ;# +$ns_ at 135.815726 "$node_(76) setdest 3032.000000 1370.000000 15.898616" ;# +$ns_ at 136.020000 "$node_(53) setdest 10.000000 2297.153203 27.467800" ;# +$ns_ at 144.791588 "$node_(53) switch OFF" ;# leaving_area +$ns_ at 136.020000 "$node_(65) setdest 3201.793172 1465.444479 13.547521" ;# +$ns_ at 136.505555 "$node_(81) setdest 4660.000000 400.000000 10.553625" ;# +$ns_ at 137.020000 "$node_(36) setdest 1533.412123 2019.191466 16.364369" ;# +$ns_ at 137.665915 "$node_(49) setdest 1399.568575 2043.449549 17.235207" ;# +$ns_ at 138.275233 "$node_(73) setdest 3032.000000 1370.000000 15.820675" ;# +$ns_ at 138.882085 "$node_(38) setdest 2791.267225 2516.309168 11.748791" ;# +$ns_ at 139.003897 "$node_(61) setdest 532.623433 2194.902053 18.223602" ;# +$ns_ at 139.213699 "$node_(75) setdest 3310.000000 610.000000 15.120226" ;# +$ns_ at 140.020000 "$node_(44) setdest 1271.772161 2066.611636 15.916303" ;# +$ns_ at 140.020000 "$node_(77) setdest 2885.061120 971.198048 13.815163" ;# +$ns_ at 140.020000 "$node_(67) setdest 3207.216219 1438.058096 13.371579" ;# +$ns_ at 140.465614 "$node_(49) setdest 1071.000000 2103.000000 16.245753" ;# +$ns_ at 140.782139 "$node_(66) setdest 1586.789557 1525.909662 16.225247" ;# +#$ns_ at 141.020000 $node_(74) arrived_to 1290.000000 1090.000000 +$ns_ at 141.020000 "$node_(74) switch OFF" ;# arrived_to +$ns_ at 142.020000 "$node_(74) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 142.030000 "$node_(74) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 141.658508 "$node_(87) setdest 1290.000000 1090.000000 16.296098" ;# +$ns_ at 143.020000 "$node_(82) setdest 3032.404943 845.955798 13.815163" ;# +$ns_ at 143.109439 "$node_(8) setdest 3800.000000 2970.000000 15.062159" ;# +#$ns_ at 144.020000 $node_(78) arrived_to 2560.000000 10.000000 +$ns_ at 144.020000 "$node_(78) switch OFF" ;# arrived_to +$ns_ at 145.020000 "$node_(78) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 145.030000 "$node_(78) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 0.0 "$node_(89) switch OFF" ;# set_X,Y,Z +$node_(89) set X_ 0.000000 +$node_(89) set Y_ 0.000000 +$node_(89) set Z_ 0.0 +$ns_ at 153.222693 "$node_(89) setdest 565.476191 10.000000 1000000000.000000" ;# init_node +$ns_ at 153.232693 "$node_(89) switch ON" ;# inside +$ns_ at 153.232693 "$node_(89) setdest 344.127931 228.744163 13.735993" ;# +$ns_ at 144.963064 "$node_(58) setdest 611.323732 2181.467741 17.409286" ;# +$ns_ at 145.579785 "$node_(45) setdest 496.265112 2201.108498 18.301437" ;# +$ns_ at 146.931933 "$node_(29) setdest 2187.073134 1622.863078 14.945523" ;# +$ns_ at 148.408339 "$node_(66) setdest 1610.000000 1560.000000 15.791359" ;# +$ns_ at 149.020000 "$node_(50) setdest 1566.539209 2013.187444 15.277260" ;# +$ns_ at 150.002406 "$node_(45) setdest 245.000000 2244.000000 15.913730" ;# +$ns_ at 150.081692 "$node_(79) setdest 3290.000000 1020.000000 14.422586" ;# +$ns_ at 150.956620 "$node_(61) setdest 245.000000 2244.000000 15.305991" ;# +$ns_ at 151.020000 "$node_(10) setdest 10.000000 2297.153203 27.031537" ;# +$ns_ at 159.933153 "$node_(10) switch OFF" ;# leaving_area +$ns_ at 151.261294 "$node_(38) setdest 2660.000000 2730.000000 10.129306" ;# +$ns_ at 152.020000 "$node_(66) setdest 1686.208867 1681.934187 14.721891" ;# +$ns_ at 152.127578 "$node_(86) setdest 1424.637256 839.959382 15.416120" ;# +$ns_ at 0.0 "$node_(90) switch OFF" ;# set_X,Y,Z +$node_(90) set X_ 0.000000 +$node_(90) set Y_ 0.000000 +$node_(90) set Z_ 0.0 +$ns_ at 169.168944 "$node_(90) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 169.178944 "$node_(90) switch ON" ;# inside +$ns_ at 169.178944 "$node_(90) setdest 1629.907162 458.743842 15.463030" ;# +$ns_ at 153.763009 "$node_(37) setdest 1981.588388 1834.670431 14.570408" ;# +$ns_ at 153.871196 "$node_(58) setdest 245.000000 2244.000000 16.053642" ;# +$ns_ at 0.0 "$node_(91) switch OFF" ;# set_X,Y,Z +$node_(91) set X_ 0.000000 +$node_(91) set Y_ 0.000000 +$node_(91) set Z_ 0.0 +$ns_ at 170.418030 "$node_(91) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 170.428030 "$node_(91) switch ON" ;# inside +$ns_ at 170.428030 "$node_(91) setdest 1630.537227 457.573722 16.216624" ;# +$ns_ at 156.817916 "$node_(85) setdest 3310.000000 610.000000 14.702074" ;# +$ns_ at 157.302391 "$node_(36) setdest 1393.080306 2044.625496 17.971882" ;# +$ns_ at 159.020000 "$node_(33) setdest 1860.000000 1960.000000 13.528813" ;# +$ns_ at 159.214389 "$node_(29) setdest 1860.000000 1960.000000 12.104470" ;# +$ns_ at 159.772887 "$node_(21) setdest 1860.000000 1960.000000 15.115415" ;# +$ns_ at 159.921934 "$node_(37) setdest 1860.000000 1960.000000 13.331542" ;# +#$ns_ at 160.020000 $node_(55) arrived_to 2660.000000 2730.000000 +$ns_ at 160.020000 "$node_(55) switch OFF" ;# arrived_to +$ns_ at 161.020000 "$node_(55) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 161.030000 "$node_(55) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 160.020000 "$node_(79) setdest 3244.927850 1081.144389 17.520934" ;# +$ns_ at 161.020000 "$node_(75) setdest 3298.796385 839.674115 13.400949" ;# +$ns_ at 161.601850 "$node_(39) setdest 3090.000000 2030.000000 12.557045" ;# +$ns_ at 161.787129 "$node_(66) setdest 1860.000000 1960.000000 13.531556" ;# +$ns_ at 162.020000 "$node_(73) setdest 2448.642014 1824.708696 16.241331" ;# +$ns_ at 162.020000 "$node_(49) setdest 245.000000 2244.000000 16.430355" ;# +$ns_ at 163.020000 "$node_(51) setdest 2841.276329 2784.804471 15.762089" ;# +$ns_ at 163.020000 "$node_(69) setdest 2192.066548 1617.716019 12.965112" ;# +#$ns_ at 163.020000 $node_(83) arrived_to 100.000000 470.000000 +$ns_ at 163.020000 "$node_(83) switch OFF" ;# arrived_to +$ns_ at 164.020000 "$node_(83) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 164.030000 "$node_(83) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 164.020000 "$node_(57) setdest 2196.107831 1613.550389 14.321469" ;# +$ns_ at 164.355465 "$node_(79) setdest 3032.000000 1370.000000 15.833262" ;# +$ns_ at 165.238012 "$node_(36) setdest 1071.000000 2103.000000 15.750539" ;# +#$ns_ at 167.020000 $node_(45) arrived_to 245.000000 2244.000000 +$ns_ at 167.020000 "$node_(45) switch OFF" ;# arrived_to +$ns_ at 168.020000 "$node_(45) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 168.030000 "$node_(45) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 168.020000 $node_(81) arrived_to 4660.000000 400.000000 +$ns_ at 168.020000 "$node_(81) switch OFF" ;# arrived_to +$ns_ at 169.020000 "$node_(81) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 169.030000 "$node_(81) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 168.541939 "$node_(50) setdest 1303.139455 2060.926563 17.773443" ;# +$ns_ at 169.391530 "$node_(82) setdest 2894.107066 963.508994 14.864930" ;# +$ns_ at 169.538594 "$node_(65) setdest 3168.634794 1632.894289 14.854433" ;# +$ns_ at 170.055887 "$node_(88) setdest 359.817155 213.239517 15.485932" ;# +$ns_ at 170.200765 "$node_(24) setdest 3803.601631 2433.357008 15.356627" ;# +#$ns_ at 171.020000 $node_(61) arrived_to 245.000000 2244.000000 +$ns_ at 171.020000 "$node_(61) switch OFF" ;# arrived_to +$ns_ at 172.020000 "$node_(61) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 172.030000 "$node_(61) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 0.0 "$node_(92) switch OFF" ;# set_X,Y,Z +$node_(92) set X_ 0.000000 +$node_(92) set Y_ 0.000000 +$node_(92) set Z_ 0.0 +$ns_ at 186.522795 "$node_(92) setdest 1871.538461 10.000000 1000000000.000000" ;# init_node +$ns_ at 186.532795 "$node_(92) switch ON" ;# inside +$ns_ at 186.532795 "$node_(92) setdest 1757.062373 222.598450 16.107106" ;# +$ns_ at 171.891756 "$node_(67) setdest 3158.620839 1683.464762 14.102316" ;# +$ns_ at 172.335722 "$node_(80) setdest 2604.125521 1209.993307 13.815163" ;# +$ns_ at 172.979814 "$node_(68) setdest 40.534746 1366.908516 18.195136" ;# +$ns_ at 173.020000 "$node_(63) setdest 2347.931038 1457.055700 14.766618" ;# +$ns_ at 0.0 "$node_(93) switch OFF" ;# set_X,Y,Z +$node_(93) set X_ 0.000000 +$node_(93) set Y_ 0.000000 +$node_(93) set Z_ 0.0 +$ns_ at 207.010001 "$node_(93) setdest 2560.000000 10.000000 1000000000.000000" ;# init_node +$ns_ at 207.020001 "$node_(93) switch ON" ;# inside +$ns_ at 207.020001 "$node_(93) setdest 2560.000000 10.000000 16.187162" ;# +#$ns_ at 174.020000 $node_(41) arrived_to 3090.000000 2030.000000 +$ns_ at 174.020000 "$node_(41) switch OFF" ;# arrived_to +$ns_ at 175.020000 "$node_(41) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 175.030000 "$node_(41) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 174.020000 $node_(37) arrived_to 1860.000000 1960.000000 +$ns_ at 174.020000 "$node_(37) switch OFF" ;# arrived_to +$ns_ at 175.020000 "$node_(37) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 175.030000 "$node_(37) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 174.842400 "$node_(27) setdest 625.319656 2906.349292 19.152866" ;# +$ns_ at 175.034880 "$node_(51) setdest 3007.934440 2835.189482 16.637835" ;# +$ns_ at 175.559423 "$node_(86) setdest 1290.000000 1090.000000 18.368335" ;# +$ns_ at 175.888338 "$node_(89) setdest 100.000000 470.000000 15.508288" ;# +#$ns_ at 177.020000 $node_(38) arrived_to 2660.000000 2730.000000 +$ns_ at 177.020000 "$node_(38) switch OFF" ;# arrived_to +$ns_ at 178.020000 "$node_(38) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 178.030000 "$node_(38) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 177.579667 "$node_(44) setdest 1071.000000 2103.000000 17.835412" ;# +$ns_ at 177.692389 "$node_(60) setdest 651.781274 2892.356499 16.620014" ;# +$ns_ at 178.005501 "$node_(88) setdest 100.000000 470.000000 13.039032" ;# +$ns_ at 178.020000 "$node_(76) setdest 3152.346236 1206.739603 16.104256" ;# +$ns_ at 178.020000 "$node_(58) setdest 46.380318 2288.924563 31.751156" ;# +$ns_ at 178.179025 "$node_(75) setdest 3293.177795 954.855207 13.682917" ;# +$ns_ at 179.020000 "$node_(21) setdest 1734.363809 1982.770564 17.710129" ;# +$ns_ at 180.020000 "$node_(85) setdest 2946.994541 918.554640 13.815163" ;# +$ns_ at 180.389193 "$node_(77) setdest 2733.002404 1100.447957 15.201584" ;# +$ns_ at 181.030197 "$node_(65) setdest 3090.000000 2030.000000 13.062893" ;# +$ns_ at 181.601997 "$node_(82) setdest 2510.000000 1290.000000 13.472597" ;# +$ns_ at 183.020000 "$node_(8) setdest 3802.644628 3010.000000 14.845359" ;# +$ns_ at 185.720327 "$node_(8) switch OFF" ;# leaving_area +$ns_ at 183.020000 "$node_(19) setdest 10.000000 2297.153203 32.044586" ;# +$ns_ at 190.538781 "$node_(19) switch OFF" ;# leaving_area +$ns_ at 183.603229 "$node_(50) setdest 1235.530927 2073.180073 17.527362" ;# +$ns_ at 184.433528 "$node_(58) setdest 10.000000 2297.153203 24.610297" ;# +$ns_ at 185.949125 "$node_(58) switch OFF" ;# leaving_area +$ns_ at 185.499459 "$node_(51) setdest 3090.000000 2860.000000 18.965428" ;# +$ns_ at 0.0 "$node_(94) switch OFF" ;# set_X,Y,Z +$node_(94) set X_ 0.000000 +$node_(94) set Y_ 0.000000 +$node_(94) set Z_ 0.0 +$ns_ at 200.082699 "$node_(94) setdest 1871.538462 10.000000 1000000000.000000" ;# init_node +$ns_ at 200.092699 "$node_(94) switch ON" ;# inside +$ns_ at 200.092699 "$node_(94) setdest 1847.554641 54.541381 17.755388" ;# +$ns_ at 186.229604 "$node_(21) setdest 1071.000000 2103.000000 16.132201" ;# +$ns_ at 186.606909 "$node_(75) setdest 3290.000000 1020.000000 14.779268" ;# +$ns_ at 187.020000 "$node_(66) setdest 1900.692120 2037.993230 15.154980" ;# +$ns_ at 187.020000 "$node_(36) setdest 719.708692 2162.966192 17.382919" ;# +$ns_ at 187.523384 "$node_(50) setdest 1071.000000 2103.000000 15.930028" ;# +$ns_ at 188.020000 "$node_(79) setdest 2665.592034 1655.603167 16.467044" ;# +$ns_ at 188.189331 "$node_(27) setdest 429.306931 3010.000000 15.771276" ;# +$ns_ at 202.248472 "$node_(27) switch OFF" ;# leaving_area +$ns_ at 188.418674 "$node_(24) setdest 3800.000000 2970.000000 12.597146" ;# +$ns_ at 188.782106 "$node_(63) setdest 2146.724027 1664.453696 12.991574" ;# +$ns_ at 189.631525 "$node_(67) setdest 3090.000000 2030.000000 12.898274" ;# +$ns_ at 190.020000 "$node_(44) setdest 776.761613 2153.227134 16.430355" ;# +$ns_ at 190.020000 "$node_(1) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 190.614373 "$node_(76) setdest 3199.271293 1143.081579 18.258249" ;# +#$ns_ at 191.020000 $node_(51) arrived_to 3090.000000 2860.000000 +$ns_ at 191.020000 "$node_(51) switch OFF" ;# arrived_to +$ns_ at 192.020000 "$node_(51) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 192.030000 "$node_(51) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 192.020000 "$node_(75) setdest 3216.505296 1119.702118 17.758994" ;# +$ns_ at 192.020000 "$node_(86) setdest 1610.000000 1560.000000 13.868165" ;# +$ns_ at 192.824720 "$node_(66) setdest 1980.000000 2190.000000 12.993435" ;# +$ns_ at 193.108798 "$node_(68) setdest 10.000000 1373.675676 15.807939" ;# +$ns_ at 195.087274 "$node_(68) switch OFF" ;# leaving_area +$ns_ at 193.517299 "$node_(77) setdest 2510.000000 1290.000000 13.006323" ;# +$ns_ at 194.945794 "$node_(76) setdest 3290.000000 1020.000000 15.178143" ;# +$ns_ at 195.496637 "$node_(57) setdest 1860.000000 1960.000000 11.624694" ;# +$ns_ at 0.0 "$node_(95) switch OFF" ;# set_X,Y,Z +$node_(95) set X_ 0.000000 +$node_(95) set Y_ 0.000000 +$node_(95) set Z_ 0.0 +$ns_ at 200.540141 "$node_(95) setdest 3917.755102 10.000000 1000000000.000000" ;# init_node +$ns_ at 200.550141 "$node_(95) switch ON" ;# inside +$ns_ at 200.550141 "$node_(95) setdest 3930.000000 210.000000 11.469727" ;# +$ns_ at 197.712478 "$node_(80) setdest 2510.000000 1290.000000 14.870156" ;# +$ns_ at 198.237245 "$node_(69) setdest 2043.885022 1770.456977 15.035831" ;# +$ns_ at 198.994650 "$node_(75) setdest 3032.000000 1370.000000 15.527926" ;# +$ns_ at 199.020000 "$node_(50) setdest 851.594504 2140.452996 18.543827" ;# +#$ns_ at 199.020000 $node_(89) arrived_to 100.000000 470.000000 +$ns_ at 199.020000 "$node_(89) switch OFF" ;# arrived_to +$ns_ at 200.020000 "$node_(89) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 200.030000 "$node_(89) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 199.020000 "$node_(29) setdest 1776.442635 1975.144111 19.043520" ;# +$ns_ at 201.523686 "$node_(92) setdest 1522.902019 657.467680 15.764942" ;# +$ns_ at 201.774529 "$node_(91) setdest 1388.150347 907.720784 16.589689" ;# +$ns_ at 202.139067 "$node_(90) setdest 1290.000000 1090.000000 17.977331" ;# +$ns_ at 202.941870 "$node_(94) setdest 1290.000000 1090.000000 16.316016" ;# +$ns_ at 203.479189 "$node_(29) setdest 1506.457950 2024.076696 15.681582" ;# +#$ns_ at 206.020000 $node_(76) arrived_to 3290.000000 1020.000000 +$ns_ at 206.020000 "$node_(76) switch OFF" ;# arrived_to +$ns_ at 207.020000 "$node_(76) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 207.030000 "$node_(76) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 206.020000 $node_(39) arrived_to 3090.000000 2030.000000 +$ns_ at 206.020000 "$node_(39) switch OFF" ;# arrived_to +$ns_ at 207.020000 "$node_(39) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 207.030000 "$node_(39) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 207.020000 $node_(66) arrived_to 1980.000000 2190.000000 +$ns_ at 207.020000 "$node_(66) switch OFF" ;# arrived_to +$ns_ at 208.020000 "$node_(66) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 208.030000 "$node_(66) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 207.020000 "$node_(80) setdest 2324.258074 1481.457062 11.783104" ;# +#$ns_ at 207.020000 $node_(88) arrived_to 100.000000 470.000000 +$ns_ at 207.020000 "$node_(88) switch OFF" ;# arrived_to +$ns_ at 208.020000 "$node_(88) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 208.030000 "$node_(88) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 207.521317 "$node_(36) setdest 245.000000 2244.000000 15.790038" ;# +$ns_ at 207.560570 "$node_(73) setdest 2119.973365 2080.895286 16.467044" ;# +$ns_ at 208.020000 "$node_(93) setdest 2989.140807 353.312646 13.088646" ;# +$ns_ at 208.187261 "$node_(44) setdest 623.790512 2179.339634 18.470348" ;# +$ns_ at 211.022873 "$node_(50) setdest 245.000000 2244.000000 15.779852" ;# +$ns_ at 211.024255 "$node_(63) setdest 2056.747297 1757.198940 14.688254" ;# +$ns_ at 212.390686 "$node_(69) setdest 1860.000000 1960.000000 11.669987" ;# +#$ns_ at 213.020000 $node_(65) arrived_to 3090.000000 2030.000000 +$ns_ at 213.020000 "$node_(65) switch OFF" ;# arrived_to +$ns_ at 214.020000 "$node_(65) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 214.030000 "$node_(65) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 214.020000 "$node_(49) setdest 10.000000 2297.153203 25.061238" ;# +$ns_ at 223.633899 "$node_(49) switch OFF" ;# leaving_area +$ns_ at 214.505518 "$node_(85) setdest 2880.706633 974.899362 15.931866" ;# +$ns_ at 216.232020 "$node_(79) setdest 2341.346270 1908.342261 17.761994" ;# +$ns_ at 216.589042 "$node_(44) setdest 245.000000 2244.000000 15.728803" ;# +$ns_ at 217.020000 "$node_(87) setdest 1440.191417 1310.593644 15.030777" ;# +$ns_ at 217.020000 "$node_(77) setdest 1860.000000 1960.000000 13.528813" ;# +$ns_ at 218.020000 "$node_(67) setdest 2974.599224 2217.861728 11.270777" ;# +$ns_ at 219.020000 "$node_(95) setdest 4660.000000 400.000000 10.932187" ;# +$ns_ at 219.733258 "$node_(60) setdest 429.306931 3010.000000 19.194417" ;# +$ns_ at 232.844577 "$node_(60) switch OFF" ;# leaving_area +$ns_ at 219.821678 "$node_(63) setdest 1860.000000 1960.000000 13.329158" ;# +$ns_ at 219.966205 "$node_(85) setdest 2510.000000 1290.000000 13.494568" ;# +$ns_ at 220.020000 "$node_(75) setdest 3335.449131 2002.185689 16.743154" ;# +$ns_ at 220.020000 "$node_(82) setdest 2225.249532 1583.512021 13.528813" ;# +$ns_ at 220.976351 "$node_(29) setdest 1447.052342 2034.843492 19.129141" ;# +$ns_ at 224.132448 "$node_(29) setdest 1071.000000 2103.000000 15.999079" ;# +$ns_ at 229.020000 "$node_(21) setdest 892.985050 2133.387540 18.885850" ;# +$ns_ at 229.020000 "$node_(33) setdest 1598.308715 2007.429472 15.682055" ;# +$ns_ at 229.658395 "$node_(80) setdest 2153.802027 1657.157910 13.260012" ;# +$ns_ at 232.020000 "$node_(24) setdest 3838.461538 3010.000000 30.389856" ;# +$ns_ at 233.845983 "$node_(24) switch OFF" ;# leaving_area +$ns_ at 232.592289 "$node_(91) setdest 1290.000000 1090.000000 18.116021" ;# +$ns_ at 232.853023 "$node_(92) setdest 1356.793484 965.954958 17.910555" ;# +$ns_ at 232.866807 "$node_(73) setdest 1980.000000 2190.000000 17.479445" ;# +$ns_ at 234.020000 "$node_(86) setdest 1786.643491 1842.629586 13.424032" ;# +$ns_ at 234.774832 "$node_(87) setdest 1610.000000 1560.000000 12.980153" ;# +$ns_ at 236.020000 "$node_(69) setdest 1071.000000 2103.000000 16.364369" ;# +$ns_ at 237.581680 "$node_(67) setdest 2818.392033 2472.152504 10.264343" ;# +$ns_ at 238.020000 "$node_(57) setdest 1707.400414 1987.657466 19.200321" ;# +$ns_ at 238.582182 "$node_(21) setdest 685.403262 2168.822203 14.782163" ;# +$ns_ at 239.020000 "$node_(36) setdest 10.000000 2297.153204 29.240031" ;# +$ns_ at 247.259944 "$node_(36) switch OFF" ;# leaving_area +$ns_ at 239.377571 "$node_(79) setdest 1980.000000 2190.000000 15.455914" ;# +$ns_ at 240.020000 "$node_(1) setdest 602.456318 2182.981427 16.430355" ;# +$ns_ at 242.020000 "$node_(44) setdest 10.000000 2297.153203 26.264286" ;# +$ns_ at 251.193530 "$node_(44) switch OFF" ;# leaving_area +#$ns_ at 242.020000 $node_(63) arrived_to 1860.000000 1960.000000 +$ns_ at 242.020000 "$node_(63) switch OFF" ;# arrived_to +$ns_ at 243.020000 "$node_(63) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 243.030000 "$node_(63) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 243.020000 $node_(90) arrived_to 1290.000000 1090.000000 +$ns_ at 243.020000 "$node_(90) switch OFF" ;# arrived_to +$ns_ at 244.020000 "$node_(90) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 244.030000 "$node_(90) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +#$ns_ at 244.020000 $node_(73) arrived_to 1980.000000 2190.000000 +$ns_ at 244.020000 "$node_(73) switch OFF" ;# arrived_to +$ns_ at 245.020000 "$node_(73) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 245.030000 "$node_(73) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 245.020000 "$node_(91) setdest 652.346233 1231.317862 16.621823" ;# +$ns_ at 245.979172 "$node_(33) setdest 1347.377906 2052.908694 15.278138" ;# +$ns_ at 246.097244 "$node_(57) setdest 1477.003253 2029.415127 14.906121" ;# +$ns_ at 248.119765 "$node_(80) setdest 2022.303833 1792.702203 13.262811" ;# +$ns_ at 249.020000 "$node_(29) setdest 788.024513 2151.304532 17.646027" ;# +$ns_ at 250.008177 "$node_(93) setdest 3310.000000 610.000000 14.668817" ;# +$ns_ at 250.247357 "$node_(82) setdest 2091.946353 1720.916836 15.145760" ;# +$ns_ at 251.020000 "$node_(50) setdest 10.000000 2297.153203 31.914843" ;# +$ns_ at 258.569347 "$node_(50) switch OFF" ;# leaving_area +$ns_ at 252.415016 "$node_(92) setdest 1290.000000 1090.000000 18.525334" ;# +$ns_ at 252.828031 "$node_(21) setdest 444.675750 2209.914914 15.036167" ;# +#$ns_ at 257.020000 $node_(85) arrived_to 2510.000000 1290.000000 +$ns_ at 257.020000 "$node_(85) switch OFF" ;# arrived_to +$ns_ at 258.020000 "$node_(85) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 258.030000 "$node_(85) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 258.847881 "$node_(86) setdest 1860.000000 1960.000000 15.090166" ;# +$ns_ at 259.020000 "$node_(87) setdest 1294.979871 1877.357940 16.121572" ;# +#$ns_ at 261.020000 $node_(92) arrived_to 1290.000000 1090.000000 +$ns_ at 261.020000 "$node_(92) switch OFF" ;# arrived_to +$ns_ at 262.020000 "$node_(92) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 262.030000 "$node_(92) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 261.805603 "$node_(57) setdest 1282.120421 2064.736096 17.465197" ;# +$ns_ at 261.902303 "$node_(75) setdest 3558.437585 2466.744969 17.642329" ;# +$ns_ at 262.358770 "$node_(80) setdest 1860.000000 1960.000000 11.855327" ;# +$ns_ at 262.670923 "$node_(33) setdest 1148.444158 2088.963860 17.976508" ;# +$ns_ at 262.887292 "$node_(82) setdest 1860.000000 1960.000000 12.746724" ;# +$ns_ at 265.288179 "$node_(29) setdest 245.000000 2244.000000 15.860941" ;# +$ns_ at 300.010000 "$node_(29) switch OFF" ;# T_max_OFF +$ns_ at 266.656773 "$node_(67) setdest 2784.048966 2528.059823 11.611108" ;# +$ns_ at 0.0 "$node_(96) switch OFF" ;# set_X,Y,Z +$node_(96) set X_ 0.000000 +$node_(96) set Y_ 0.000000 +$node_(96) set Z_ 0.0 +$ns_ at 272.965033 "$node_(96) setdest 3838.461539 3010.000000 1000000000.000000" ;# init_node +$ns_ at 272.975033 "$node_(96) switch ON" ;# inside +$ns_ at 272.975033 "$node_(96) setdest 3800.000000 2970.000000 27.135580" ;# +$ns_ at 268.949452 "$node_(1) setdest 557.162097 2190.713250 17.426686" ;# +$ns_ at 269.020000 "$node_(86) setdest 1949.861359 2132.234271 13.400689" ;# +$ns_ at 269.069512 "$node_(21) setdest 245.000000 2244.000000 18.498178" ;# +$ns_ at 270.020000 "$node_(79) setdest 1527.825258 2429.108110 15.340410" ;# +$ns_ at 300.010000 "$node_(79) switch OFF" ;# T_max_OFF +$ns_ at 271.586178 "$node_(1) setdest 245.000000 2244.000000 16.295176" ;# +$ns_ at 272.307661 "$node_(67) setdest 2660.000000 2730.000000 10.434763" ;# +$ns_ at 273.145744 "$node_(57) setdest 1071.000000 2103.000000 15.464606" ;# +$ns_ at 0.0 "$node_(97) switch OFF" ;# set_X,Y,Z +$node_(97) set X_ 0.000000 +$node_(97) set Y_ 0.000000 +$node_(97) set Z_ 0.0 +$ns_ at 279.010000 "$node_(97) setdest 2560.000000 10.000000 1000000000.000000" ;# init_node +$ns_ at 279.020000 "$node_(97) switch ON" ;# inside +$ns_ at 279.020000 "$node_(97) setdest 2560.000000 10.000000 14.938944" ;# +$ns_ at 273.917529 "$node_(33) setdest 1071.000000 2103.000000 19.184982" ;# +$ns_ at 0.0 "$node_(98) switch OFF" ;# set_X,Y,Z +$node_(98) set X_ 0.000000 +$node_(98) set Y_ 0.000000 +$node_(98) set Z_ 0.0 +$ns_ at 282.925931 "$node_(98) setdest 3838.461539 3010.000000 1000000000.000000" ;# init_node +$ns_ at 282.935931 "$node_(98) switch ON" ;# inside +$ns_ at 282.935931 "$node_(98) setdest 3800.000000 2970.000000 26.626446" ;# +$ns_ at 276.020000 "$node_(96) setdest 3474.475390 2291.823728 16.199655" ;# +$ns_ at 300.010000 "$node_(96) switch OFF" ;# T_max_OFF +$ns_ at 276.020000 "$node_(94) setdest 1339.605990 1162.858798 15.675509" ;# +$ns_ at 279.020000 "$node_(93) setdest 3298.774462 840.123521 13.682917" ;# +$ns_ at 279.020000 "$node_(33) setdest 758.868100 2156.281595 15.403528" ;# +$ns_ at 280.020000 "$node_(97) setdest 3310.000000 610.000000 13.527727" ;# +$ns_ at 300.010000 "$node_(97) switch OFF" ;# T_max_OFF +$ns_ at 281.020000 "$node_(21) setdest 10.000000 2297.153203 30.398557" ;# +$ns_ at 288.945910 "$node_(21) switch OFF" ;# leaving_area +$ns_ at 281.642965 "$node_(94) setdest 1484.258241 1375.316791 13.340685" ;# +$ns_ at 300.010000 "$node_(94) switch OFF" ;# T_max_OFF +$ns_ at 283.020000 "$node_(80) setdest 1502.174391 2024.853057 16.364369" ;# +$ns_ at 300.010000 "$node_(80) switch OFF" ;# T_max_OFF +$ns_ at 283.516799 "$node_(86) setdest 1980.000000 2190.000000 14.468669" ;# +$ns_ at 284.313260 "$node_(91) setdest 431.300048 1280.306476 17.867474" ;# +$ns_ at 286.020000 "$node_(98) setdest 3801.473672 2750.422828 15.669625" ;# +$ns_ at 300.010000 "$node_(98) switch OFF" ;# T_max_OFF +$ns_ at 286.020000 "$node_(69) setdest 918.365533 2129.055036 18.384042" ;# +$ns_ at 286.756865 "$node_(87) setdest 1142.462024 2031.007645 16.632495" ;# +$ns_ at 287.020000 "$node_(77) setdest 1551.772884 2015.863723 14.961985" ;# +$ns_ at 300.010000 "$node_(77) switch OFF" ;# T_max_OFF +$ns_ at 288.020000 "$node_(57) setdest 803.748295 2148.620448 15.729994" ;# +$ns_ at 300.010000 "$node_(57) switch OFF" ;# T_max_OFF +$ns_ at 289.020000 "$node_(86) setdest 2353.960580 2486.968696 16.383618" ;# +$ns_ at 300.010000 "$node_(86) switch OFF" ;# T_max_OFF +#$ns_ at 289.020000 $node_(95) arrived_to 4660.000000 400.000000 +$ns_ at 289.020000 "$node_(95) switch OFF" ;# arrived_to +$ns_ at 290.020000 "$node_(95) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 290.030000 "$node_(95) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 290.020000 "$node_(82) setdest 1540.540627 2017.899481 16.364369" ;# +$ns_ at 300.010000 "$node_(82) switch OFF" ;# T_max_OFF +$ns_ at 291.110744 "$node_(75) setdest 3800.000000 2970.000000 15.990818" ;# +$ns_ at 300.010000 "$node_(75) switch OFF" ;# T_max_OFF +$ns_ at 292.020000 "$node_(1) setdest 10.000000 2297.153204 31.068618" ;# +$ns_ at 299.774971 "$node_(1) switch OFF" ;# leaving_area +$ns_ at 294.442649 "$node_(69) setdest 667.501399 2171.878090 15.432507" ;# +$ns_ at 300.010000 "$node_(69) switch OFF" ;# T_max_OFF +$ns_ at 295.858307 "$node_(93) setdest 3296.273248 891.398413 15.927207" ;# +#$ns_ at 296.020000 $node_(67) arrived_to 2660.000000 2730.000000 +$ns_ at 296.020000 "$node_(67) switch OFF" ;# arrived_to +$ns_ at 297.020000 "$node_(67) setdest 0.010000 0.010000 1000000001.000000" ;# remove_from_area_upon__arrived_to +$ns_ at 297.030000 "$node_(67) setdest 0.020000 0.020000 1000000001.000000" ;# nam_hack__force_remove +$ns_ at 296.984866 "$node_(91) setdest 10.000000 1373.675676 16.367380" ;# +$ns_ at 300.010000 "$node_(91) switch OFF" ;# T_max_OFF +$ns_ at 299.081462 "$node_(93) setdest 3290.000000 1020.000000 12.955074" ;# +$ns_ at 300.010000 "$node_(93) switch OFF" ;# T_max_OFF +$ns_ at 299.576777 "$node_(33) setdest 597.299018 2183.861790 18.859074" ;# +$ns_ at 300.010000 "$node_(33) switch OFF" ;# T_max_OFF +$ns_ at 299.773230 "$node_(87) setdest 1071.000000 2103.000000 19.333470" ;# +$ns_ at 300.010000 "$node_(87) switch OFF" ;# T_max_OFF diff --git a/src/wave/examples/vanet-routing-compare.cc b/src/wave/examples/vanet-routing-compare.cc new file mode 100644 index 000000000..177699495 --- /dev/null +++ b/src/wave/examples/vanet-routing-compare.cc @@ -0,0 +1,2450 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + +/* + * This example program allows one to run vehicular ad hoc + * network (VANET) simulation scenarios in ns-3 to assess + * performance by evaluating different 802.11p MAC/PHY + * characteristics, propagation loss models (e.g. Friss, + * Two-Ray Ground, or ITU R-P.1411), and application traffic + * (e.g. Basic Safety Message) and/or routing traffic (e.g. + * DSDV, AODV, OLSR, or DSR) under either a synthetic highway + * scenario (i.e. a random waypoint mobility model) or by + * playing back mobility trace files (i.e. ns-2 movement files). + * + * The script draws from several ns-3 examples, including: + * /examples/routing/manet-routing-compare.cc + * /src/propagation/model/itu-r-1411-los-propagation-loss-model.cc + * /src/mobility/examples/ns2-mobility-trace.cc + * /src/wave/examples/wave-simple-80211p.cc + * + * The script allows many parameters to be modified and + * includes two predefined scenarios. By default + * scenario=1 runs for 10 simulated seconds with 40 nodes + * (i.e. vehicles) moving according to RandomWaypointMobilityModel + * with a speed of 20 m/s and no pause time within a 300x1500 m + * region. The WiFi is 802.11p with continuous access to a 10 MHz + * Control Channel (CH) for all traffic. All nodes transmit a + * 200-byte safety message 10 times per second at 6 Mbps. + * Additionally, all nodes (optionally) attempt to + * continuously route 64-byte packets at an application + * rate of 2.048 Kbps to one of 10 other nodes, + * selected as sink nodes. The default routing protocol is AODV + * and the Two-Ray Ground loss model is used. + * The transmit power is set to 20 dBm and the transmission range + * for safety message packet delivery is 145 m. + * + * Scenario 2 plays back vehicular trace files in + * ns-2 movement format, and are taken from: + * http://www.lst.inf.ethz.ch/research/ad-hoc/car-traces/ + * This scenario is 300 simulation seconds of 99 + * vehicles respectively within the Unterstrass + * section of Zurich Switzerland that travel based on + * models derived from real traffic data. Note that these + * scenarios can require a lot of clock time to complete. + * + * All parameters can be changed from their defaults (see + * --help) and changing simulation parameters can have dramatic + * impact on network performance. + * + * Several items can be output: + * - a CSV file of data reception statistics, output once per + * second + * - final statistics, in a CSV file + * - dump of routing tables at 5 seconds into the simulation + * - ASCII trace file + * - PCAP trace files for each node + * + * Simulation scenarios can be defined and configuration + * settings can be saved using config-store (raw text) + * which can they be replayed again. This is an easy way + * to define and save the settings for a scenario, and then + * re-execute the same scenario exactly, or to set up + * several different simulation scenarios. + * For example, to set up a scenario and save the configuration + * as "scenario1.txt": + * ./waf --run "vanet-routing-compare --scenario=1 --saveconfig=scenario1.txt" + * Then, to re-play the scenario using the save configuration + * settings: + * ./waf --run "vanet-routing-compare --loadconfig=scenario1.txt" + * + * Class Diagram: + * main() + * +--uses-- VanetRoutingExperiment + * +--is_a--- WifiApp + * +--uses--- ConfigStoreHelper + * +--has_a-- WaveBsmHelper + * | +--has_a-- WaveBsmStats + * +--has_a-- RoutingHelper + * | +--has_a--RoutingStats + * +--has_a-- WifiPhyStats + * + */ + +#include +#include +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/internet-module.h" +#include "ns3/mobility-module.h" +#include "ns3/wifi-module.h" +#include "ns3/aodv-module.h" +#include "ns3/olsr-module.h" +#include "ns3/dsdv-module.h" +#include "ns3/dsr-module.h" +#include "ns3/applications-module.h" +#include "ns3/itu-r-1411-los-propagation-loss-model.h" +#include "ns3/ocb-wifi-mac.h" +#include "ns3/wifi-80211p-helper.h" +#include "ns3/wave-mac-helper.h" +#include "ns3/flow-monitor-module.h" +#include "ns3/config-store-module.h" +#include "ns3/integer.h" +#include "ns3/wave-bsm-helper.h" +#include "ns3/wave-helper.h" +// future #include "ns3/topology.h" + +using namespace ns3; +using namespace dsr; + +NS_LOG_COMPONENT_DEFINE ("vanet-routing-compare"); + +/** + * \ingroup wave + * \brief The RoutingStats class manages collects statistics + * on routing data (application-data packet and byte counts) + * for the vehicular network + */ +class RoutingStats +{ +public: + /** + * \brief Constructor + * \return none + */ + RoutingStats (); + + /** + * \brief Returns the number of bytes received + * \return the number of bytes received + */ + uint32_t GetRxBytes (); + + /** + * \brief Returns the cumulative number of bytes received + * \return the cumulative number of bytes received + */ + uint32_t GetCumulativeRxBytes (); + + /** + * \brief Returns the count of packets received + * \return the count of packets received + */ + uint32_t GetRxPkts (); + + /** + * \brief Returns the cumulative count of packets received + * \return the cumulative count of packets received + */ + uint32_t GetCumulativeRxPkts (); + + /** + * \brief Increments the number of (application-data) + * bytes received, not including MAC/PHY overhead + * \param rxBytes the number of bytes received + * \return none + */ + void IncRxBytes (uint32_t rxBytes); + + /** + * \brief Increments the count of packets received + * \return none + */ + void IncRxPkts (); + + /** + * \brief Sets the number of bytes received. + * \param rxBytes the number of bytes received + * \return none + */ + void SetRxBytes (uint32_t rxBytes); + + /** + * \brief Sets the number of packets received + * \param rxPkts the number of packets received + * \return none + */ + void SetRxPkts (uint32_t rxPkts); + + /** + * \brief Returns the number of bytes transmitted + * \return the number of bytes transmitted + */ + uint32_t GetTxBytes (); + + /** + * \brief Returns the cumulative number of bytes transmitted + * \param socket the receiving socket + * \return none + */ + uint32_t GetCumulativeTxBytes (); + + /** + * \brief Returns the number of packets transmitted + * \return the number of packets transmitted + */ + uint32_t GetTxPkts (); + + /** + * \brief Returns the cumulative number of packets transmitted + * \return the cumulative number of packets transmitted + */ + uint32_t GetCumulativeTxPkts (); + + /** + * \brief Increment the number of bytes transmitted + * \param txBytes the number of addtional bytes transmitted + * \return none + */ + void IncTxBytes (uint32_t txBytes); + + /** + * \brief Increment the count of packets transmitted + * \return none + */ + void IncTxPkts (); + + /** + * \brief Sets the number of bytes transmitted + * \param txBytes the number of bytes transmitted + * \return none + */ + void SetTxBytes (uint32_t txBytes); + + /** + * \brief Sets the number of packets transmitted + * \param txPkts the number of packets transmitted + * \return none + */ + void SetTxPkts (uint32_t txPkts); + +private: + uint32_t m_RxBytes; + uint32_t m_cumulativeRxBytes; + uint32_t m_RxPkts; + uint32_t m_cumulativeRxPkts; + uint32_t m_TxBytes; + uint32_t m_cumulativeTxBytes; + uint32_t m_TxPkts; + uint32_t m_cumulativeTxPkts; +}; + +RoutingStats::RoutingStats () + : m_RxBytes (0), + m_cumulativeRxBytes (0), + m_RxPkts (0), + m_cumulativeRxPkts (0) +{ +} + +uint32_t +RoutingStats::GetRxBytes () +{ + return m_RxBytes; +} + +uint32_t +RoutingStats::GetCumulativeRxBytes () +{ + return m_cumulativeRxBytes; +} + +uint32_t +RoutingStats::GetRxPkts () +{ + return m_RxPkts; +} + +uint32_t +RoutingStats::GetCumulativeRxPkts () +{ + return m_cumulativeRxPkts; +} + +void +RoutingStats::IncRxBytes (uint32_t rxBytes) +{ + m_RxBytes += rxBytes; + m_cumulativeRxBytes += rxBytes; +} + +void +RoutingStats::IncRxPkts () +{ + m_RxPkts++; + m_cumulativeRxPkts++; +} + +void +RoutingStats::SetRxBytes (uint32_t rxBytes) +{ + m_RxBytes = rxBytes; +} + +void +RoutingStats::SetRxPkts (uint32_t rxPkts) +{ + m_RxPkts = rxPkts; +} + +uint32_t +RoutingStats::GetTxBytes () +{ + return m_TxBytes; +} + +uint32_t +RoutingStats::GetCumulativeTxBytes () +{ + return m_cumulativeTxBytes; +} + +uint32_t +RoutingStats::GetTxPkts () +{ + return m_TxPkts; +} + +uint32_t +RoutingStats::GetCumulativeTxPkts () +{ + return m_cumulativeTxPkts; +} + +void +RoutingStats::IncTxBytes (uint32_t txBytes) +{ + m_TxBytes += txBytes; + m_cumulativeTxBytes += txBytes; +} + +void +RoutingStats::IncTxPkts () +{ + m_TxPkts++; + m_cumulativeTxPkts++; +} + +void +RoutingStats::SetTxBytes (uint32_t txBytes) +{ + m_TxBytes = txBytes; +} + +void +RoutingStats::SetTxPkts (uint32_t txPkts) +{ + m_TxPkts = txPkts; +} + +/** + * \ingroup wave + * \brief The RoutingHelper class generates routing data between + * nodes (vehicles) and uses the RoutingStats class to collect statistics + * on routing data (application-data packet and byte counts). + * A routing protocol is configured, and all nodes attempt to send + * (i.e. route) small packets to another node, which acts as + * data sinks. Not all nodes act as data sinks. + * for the vehicular network + */ +class RoutingHelper : public Object +{ +public: + /** + * \brief Get class TypeId + * \return the TypeId for the class + */ + static TypeId GetTypeId (void); + + /** + * \brief Constructor + * \return none + */ + RoutingHelper (); + + /** + * \brief Destructor + * \return none + */ + virtual ~RoutingHelper (); + + /** + * \brief Installs routing funcationality on nodes and their + * devices and interfaces. + * \param c node container + * \param d net device container + * \param i IPv4 interface container + * \param totalTime the total time that nodes should attempt to + * route data + * \param protocol the routing protocol (1=OLSR;2=AODV;3=DSDV;4=DSR) + * \param nSinks the number of nodes which will act as data sinks + * \param routingTables dump routing tables at t=5 seconds (0=no;1=yes) + * \return none + */ + void Install (NodeContainer & c, + NetDeviceContainer & d, + Ipv4InterfaceContainer & i, + double totalTime, + int protocol, + int nSinks, + int routingTables); + + /** + * \brief Trace the receipt of an on-off-application generated packet + * \param context this object + * \param packet a received packet + * \return none + */ + void OnOffTrace (std::string context, Ptr packet); + + /** + * \brief Returns the RoutingStats instance + * \return the RoutingStats instance + */ + RoutingStats & GetRoutingStats (); + + /** + * \brief Enable/disable logging + * \param log non-zero to enable logging + * \return none + */ + void SetLogging (int log); + +private: + /** + * \brief Sets up the protocol protocol on the nodes + * \param c node container + * \return none + */ + void SetupRoutingProtocol (NodeContainer & c); + + /** + * \brief Assigns IPv4 addresses to net devices and their interfaces + * \param d net device container + * \param adhocTxInterfaces IPv4 interface container + * \return none + */ + void AssignIpAddresses (NetDeviceContainer & d, + Ipv4InterfaceContainer & adhocTxInterfaces); + + /** + * \brief Sets up routing messages on the nodes and their interfaces + * \param c node container + * \param adhocTxInterfaces IPv4 interface container + * \return none + */ + void SetupRoutingMessages (NodeContainer & c, + Ipv4InterfaceContainer & adhocTxInterfaces); + + /** + * \brief Sets up a routing packet for tranmission + * \param addr destination address + * \parm node source node + * \return Socket to be used for sending/receiving a routed data packet + */ + Ptr SetupRoutingPacketReceive (Ipv4Address addr, Ptr node); + + /** + * \brief Process a received routing packet + * \param socket the receiving socket + * \return none + */ + void ReceiveRoutingPacket (Ptr socket); + + double m_TotalSimTime; // seconds + uint32_t m_protocol; // routing protocol; 0=NONE, 1=OLSR, 2=AODV, 3=DSDV, 4=DSR + uint32_t m_port; + int m_nSinks; // number of sink nodes (< all nodes) + int m_routingTables; // dump routing table (at t=5 sec). 0=No, 1=Yes + RoutingStats routingStats; + std::string m_protocolName; + int m_log; +}; + +NS_OBJECT_ENSURE_REGISTERED (RoutingHelper); + +TypeId +RoutingHelper::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::RoutingHelper") + .SetParent () + .AddConstructor (); + return tid; +} + +RoutingHelper::RoutingHelper () + : m_TotalSimTime (300.01), + m_protocol (0), + m_port (9), + m_nSinks (0), + m_routingTables (0), + m_log (0) +{ +} + +RoutingHelper::~RoutingHelper () +{ +} + +void +RoutingHelper::Install (NodeContainer & c, + NetDeviceContainer & d, + Ipv4InterfaceContainer & i, + double totalTime, + int protocol, + int nSinks, + int routingTables) +{ + m_TotalSimTime = totalTime; + m_protocol = protocol; + m_nSinks = nSinks; + m_routingTables = routingTables; + + SetupRoutingProtocol (c); + AssignIpAddresses (d, i); + SetupRoutingMessages (c, i); +} + +Ptr +RoutingHelper::SetupRoutingPacketReceive (Ipv4Address addr, Ptr node) +{ + TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); + Ptr sink = Socket::CreateSocket (node, tid); + InetSocketAddress local = InetSocketAddress (addr, m_port); + sink->Bind (local); + sink->SetRecvCallback (MakeCallback (&RoutingHelper::ReceiveRoutingPacket, this)); + + return sink; +} + +void +RoutingHelper::SetupRoutingProtocol (NodeContainer & c) +{ + AodvHelper aodv; + OlsrHelper olsr; + DsdvHelper dsdv; + DsrHelper dsr; + DsrMainHelper dsrMain; + Ipv4ListRoutingHelper list; + InternetStackHelper internet; + + Time rtt = Time (5.0); + AsciiTraceHelper ascii; + Ptr rtw = ascii.CreateFileStream ("routing_table"); + + switch (m_protocol) + { + case 1: + if (m_routingTables != 0) + { + olsr.PrintRoutingTableAllAt (rtt, rtw); + } + list.Add (olsr, 100); + m_protocolName = "OLSR"; + break; + case 0: + case 2: + if (m_routingTables != 0) + { + aodv.PrintRoutingTableAllAt (rtt, rtw); + } + list.Add (aodv, 100); + if (m_protocol == 0) + { + m_protocolName = "NONE"; + } + else + { + m_protocolName = "AODV"; + } + break; + case 3: + if (m_routingTables != 0) + { + dsdv.PrintRoutingTableAllAt (rtt, rtw); + } + list.Add (dsdv, 100); + m_protocolName = "DSDV"; + break; + case 4: + m_protocolName = "DSR"; + break; + default: + NS_FATAL_ERROR ("No such protocol:" << m_protocol); + } + + if (m_protocol < 4) + { + internet.SetRoutingHelper (list); + internet.Install (c); + } + else if (m_protocol == 4) + { + internet.Install (c); + dsrMain.Install (dsr, c); + } + + if (m_log != 0) + { + NS_LOG_UNCOND ("Routing Setup for " << m_protocolName); + } +} + +void +RoutingHelper::AssignIpAddresses (NetDeviceContainer & d, + Ipv4InterfaceContainer & adhocTxInterfaces) +{ + NS_LOG_INFO ("Assigning IP addresses"); + Ipv4AddressHelper addressAdhoc; + // we may have a lot of nodes, and want them all + // in same subnet, to support broadcast + addressAdhoc.SetBase ("10.1.0.0", "255.255.0.0"); + adhocTxInterfaces = addressAdhoc.Assign (d); +} + +void +RoutingHelper::SetupRoutingMessages (NodeContainer & c, + Ipv4InterfaceContainer & adhocTxInterfaces) +{ + // Setup routing transmissions + OnOffHelper onoff1 ("ns3::UdpSocketFactory",Address ()); + onoff1.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]")); + onoff1.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]")); + + Ptr var = CreateObject (); + int64_t stream = 2; + var->SetStream (stream); + for (int i = 0; i <= m_nSinks - 1; i++) + { + // protocol == 0 means no routing data, WAVE BSM only + // so do not set up sink + if (m_protocol != 0) + { + Ptr sink = SetupRoutingPacketReceive (adhocTxInterfaces.GetAddress (i), c.Get (i)); + } + + AddressValue remoteAddress (InetSocketAddress (adhocTxInterfaces.GetAddress (i), m_port)); + onoff1.SetAttribute ("Remote", remoteAddress); + + ApplicationContainer temp = onoff1.Install (c.Get (i + m_nSinks)); + temp.Start (Seconds (var->GetValue (1.0,2.0))); + temp.Stop (Seconds (m_TotalSimTime)); + } +} + +static inline std::string +PrintReceivedRoutingPacket (Ptr socket, Ptr packet) +{ + SocketAddressTag tag; + bool found; + found = packet->PeekPacketTag (tag); + std::ostringstream oss; + + oss << Simulator::Now ().GetSeconds () << " " << socket->GetNode ()->GetId (); + + if (found) + { + InetSocketAddress addr = InetSocketAddress::ConvertFrom (tag.GetAddress ()); + oss << " received one packet from " << addr.GetIpv4 (); + } + else + { + oss << " received one packet!"; + } + return oss.str (); +} + +void +RoutingHelper::ReceiveRoutingPacket (Ptr socket) +{ + Ptr packet; + while ((packet = socket->Recv ())) + { + // application data, for goodput + uint32_t RxRoutingBytes = packet->GetSize (); + GetRoutingStats ().IncRxBytes (RxRoutingBytes); + GetRoutingStats ().IncRxPkts (); + if (m_log != 0) + { + NS_LOG_UNCOND (m_protocolName + " " + PrintReceivedRoutingPacket (socket, packet)); + } + } +} + +void +RoutingHelper::OnOffTrace (std::string context, Ptr packet) +{ + uint32_t pktBytes = packet->GetSize (); + routingStats.IncTxBytes (pktBytes); +} + +RoutingStats & +RoutingHelper::GetRoutingStats () +{ + return routingStats; +} + +void +RoutingHelper::SetLogging (int log) +{ + m_log = log; +} + +/** + * \ingroup wave + * \brief The WifiPhyStats class collects Wifi MAC/PHY statistics + */ +class WifiPhyStats : public Object +{ +public: + /** + * \brief Gets the class TypeId + * \return the class TypeId + */ + static TypeId GetTypeId (void); + + /** + * \brief Constructor + * \return none + */ + WifiPhyStats (); + + /** + * \brief Destructor + * \return none + */ + virtual ~WifiPhyStats (); + + /** + * \brief Returns the number of bytes that have been transmitted + * (this includes MAC/PHY overhead) + * \return the number of bytes transmitted + */ + uint32_t GetTxBytes (); + + /** + * \brief Callback signiture for Phy/Tx trace + * \param context this object + * \param packet packet transmitted + * \param mode wifi mode + * \param preamble wifi preamble + * \param txPower transmission power + * \return none + */ + void PhyTxTrace (std::string context, Ptr packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower); + + /** + * \brief Callback signiture for Phy/TxDrop + * \param context this object + * \param packet the tx packet being dropped + * \return none + */ + void PhyTxDrop (std::string context, Ptr packet); + + /** + * \brief Callback signiture for Phy/RxDrop + * \param context this object + * \param packet the rx packet being dropped + * \return none + */ + void PhyRxDrop (std::string context, Ptr packet); + +private: + uint32_t m_phyTxPkts; + uint32_t m_phyTxBytes; +}; + +NS_OBJECT_ENSURE_REGISTERED (WifiPhyStats); + +TypeId +WifiPhyStats::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::WifiPhyStats") + .SetParent () + .AddConstructor (); + return tid; +} + +WifiPhyStats::WifiPhyStats () + : m_phyTxPkts (0), + m_phyTxBytes (0) +{ +} + +WifiPhyStats::~WifiPhyStats () +{ +} + +void +WifiPhyStats::PhyTxTrace (std::string context, Ptr packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower) +{ + NS_LOG_FUNCTION (this << context << packet << "PHYTX mode=" << mode ); + ++m_phyTxPkts; + uint32_t pktSize = packet->GetSize (); + m_phyTxBytes += pktSize; + + //NS_LOG_UNCOND ("Received PHY size=" << pktSize); +} + +void +WifiPhyStats::PhyTxDrop (std::string context, Ptr packet) +{ + NS_LOG_UNCOND ("PHY Tx Drop"); +} + +void +WifiPhyStats::PhyRxDrop (std::string context, Ptr packet) +{ + NS_LOG_UNCOND ("PHY Rx Drop"); +} + +uint32_t +WifiPhyStats::GetTxBytes () +{ + return m_phyTxBytes; +} + +/** + * \ingroup wave + * \brief The WifiApp class enforces program flow for ns-3 wifi applications + */ +class WifiApp +{ +public: + /** + * \brief Constructor + * \return none + */ + WifiApp (); + + /** + * \brief Destructor + * \return none + */ + virtual ~WifiApp (); + + /** + * \brief Enacts simulation of an ns-3 wifi application + * \param argc program arguments count + * \param argv program arguments + * \return none + */ + void Simulate (int argc, char **argv); + +protected: + /** + * \brief Sets default attribute values + * \return none + */ + virtual void SetDefaultAttributeValues (); + + /** + * \brief Process command line arguments + * \param argc program arguments count + * \param argv program arguments + * \return none + */ + virtual void ParseCommandLineArguments (int argc, char **argv); + + /** + * \brief Configure nodes + * \return none + */ + virtual void ConfigureNodes (); + + /** + * \brief Configure channels + * \return none + */ + virtual void ConfigureChannels (); + + /** + * \brief Configure devices + * \return none + */ + virtual void ConfigureDevices (); + + /** + * \brief Configure mobility + * \return none + */ + virtual void ConfigureMobility (); + + /** + * \brief Configure applications + * \return none + */ + virtual void ConfigureApplications (); + + /** + * \brief Configure tracing + * \return none + */ + virtual void ConfigureTracing (); + + /** + * \brief Run the simulation + * \return none + */ + virtual void RunSimulation (); + + /** + * \brief Process outputs + * \return none + */ + virtual void ProcessOutputs (); +}; + +WifiApp::WifiApp () +{ +} + +WifiApp::~WifiApp () +{ +} + +void +WifiApp::Simulate (int argc, char **argv) +{ + // Simulator Program Flow: + // (source: NS-3 Annual Meeting, May, 2014, session 2 slides 6, 28) + // (HandleProgramInputs:) + // SetDefaultAttributeValues + // ParseCommandLineArguments + // (ConfigureTopology:) + // ConfigureNodes + // ConfigureChannels + // ConfigureDevices + // ConfigureMobility + // ConfigureApplications + // e.g AddInternetStackToNodes + // ConfigureIpAddressingAndRouting + // configureSendMessages + // ConfigureTracing + // RunSimulation + // ProcessOutputs + + SetDefaultAttributeValues (); + ParseCommandLineArguments (argc, argv); + ConfigureNodes (); + ConfigureChannels (); + ConfigureDevices (); + ConfigureMobility (); + ConfigureApplications (); + ConfigureTracing (); + RunSimulation (); + ProcessOutputs (); +} + +void +WifiApp::SetDefaultAttributeValues () +{ +} + +void +WifiApp::ParseCommandLineArguments (int argc, char **argv) +{ +} + +void +WifiApp::ConfigureNodes () +{ +} + +void +WifiApp::ConfigureChannels () +{ +} + +void +WifiApp::ConfigureDevices () +{ +} + +void +WifiApp::ConfigureMobility () +{ +} + +void +WifiApp::ConfigureApplications () +{ +} + +void +WifiApp::ConfigureTracing () +{ +} + +void +WifiApp::RunSimulation () +{ +} + +void +WifiApp::ProcessOutputs () +{ +} + +/** + * \ingroup wave + * \brief The ConfigStoreHelper class simplifies config-store raw text load and save + */ +class ConfigStoreHelper +{ +public: + /** + * \brief Constructor + * \return none + */ + ConfigStoreHelper (); + + /** + * \brief Loads a saved config-store raw text configuration from a given named file + * \param configFilename the name of the config-store raw text file + * \return none + */ + void LoadConfig (std::string configFilename); + + /** + * \brief Saves a configuration to a given named config-store raw text configuration file + * \param configFilename the name of the config-store raw text file + * \return none + */ + void SaveConfig (std::string configFilename); +}; + +ConfigStoreHelper::ConfigStoreHelper () +{ +} + +void +ConfigStoreHelper::LoadConfig (std::string configFilename) +{ + // Input config store from txt format + Config::SetDefault ("ns3::ConfigStore::Filename", StringValue (configFilename)); + Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText")); + Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Load")); + ConfigStore inputConfig; + inputConfig.ConfigureDefaults (); + //inputConfig.ConfigureAttributes (); +} + +void +ConfigStoreHelper::SaveConfig (std::string configFilename) +{ + // only save if a non-empty filename has been specified + if (configFilename.compare ("") != 0) + { + // Output config store to txt format + Config::SetDefault ("ns3::ConfigStore::Filename", StringValue (configFilename)); + Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText")); + Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save")); + ConfigStore outputConfig; + outputConfig.ConfigureDefaults (); + //outputConfig.ConfigureAttributes (); + } +} + +/** + * \ingroup wave + * \brief The VanetRoutingExperiment class implements a wifi app that + * allows VANET routing experiments to be simulated + */ +class VanetRoutingExperiment : public WifiApp +{ +public: + /** + * \brief Constructor + * \return none + */ + VanetRoutingExperiment (); + +protected: + /** + * \brief Sets default attribute values + * \return none + */ + virtual void SetDefaultAttributeValues (); + + /** + * \brief Process command line arguments + * \param argc program arguments count + * \param argv program arguments + * \return none + */ + virtual void ParseCommandLineArguments (int argc, char **argv); + + /** + * \brief Configure nodes + * \return none + */ + virtual void ConfigureNodes (); + + /** + * \brief Configure channels + * \return none + */ + virtual void ConfigureChannels (); + + /** + * \brief Configure devices + * \return none + */ + virtual void ConfigureDevices (); + + /** + * \brief Configure mobility + * \return none + */ + virtual void ConfigureMobility (); + + /** + * \brief Configure applications + * \return none + */ + virtual void ConfigureApplications (); + + /** + * \brief Configure tracing + * \return none + */ + virtual void ConfigureTracing (); + + /** + * \brief Run the simulation + * \return none + */ + virtual void RunSimulation (); + + /** + * \brief Process outputs + * \return none + */ + virtual void ProcessOutputs (); + +private: + /** + * \brief Run the simulation + * \return none + */ + void Run (); + + /** + * \brief Run the simulation + * \return none + */ + void CommandSetup (int argc, char **argv); + + /** + * \brief Checks the throughput and outputs summary to CSV file1. + * This is scheduled and called once per second + * \return none + */ + void CheckThroughput (); + + /** + * \brief Set up log file + * \return none + */ + void SetupLogFile (); + + /** + * \brief Set up logging + * \return none + */ + void SetupLogging (); + + /** + * \brief Configure default attributes + * \return none + */ + void ConfigureDefaults (); + + /** + * \brief Set up the adhoc mobility nodes + * \return none + */ + void SetupAdhocMobilityNodes (); + + /** + * \brief Set up the adhoc devices + * \return none + */ + void SetupAdhocDevices (); + + /** + * \brief Set up generation of IEEE 1609 WAVE messages, + * as a Basic Safety Message (BSM). The BSM is typically + * a ~200-byte packets broadcast by all vehicles at a nominal + * rate of 10 Hz + * \return none + */ + void SetupWaveMessages (); + + /** + * \brief Set up generation of packets to be routed + * through the vehicular network + * \return none + */ + void SetupRoutingMessages (); + + /** + * \brief Set up a prescribed scenario + * \return none + */ + void SetupScenario (); + + /** + * \brief Write the header line to the CSV file1 + * \return none + */ + void WriteCsvHeader (); + + /** + * \brief Set up configuration parameter from the global variables + * \return none + */ + void SetConfigFromGlobals (); + + /** + * \brief Set up the global variables from the configuration parameters + * \return none + */ + void SetGlobalsFromConfig (); + + static void + CourseChange (std::ostream *os, std::string foo, Ptr mobility); + + uint32_t m_port; + std::string m_CSVfileName; + std::string m_CSVfileName2; + int m_nSinks; + std::string m_protocolName; + double m_txp; + bool m_traceMobility; + uint32_t m_protocol; + + uint32_t m_lossModel; + uint32_t m_fading; + std::string m_lossModelName; + + std::string m_phyMode; + uint32_t m_80211mode; + + std::string m_traceFile; + std::string m_logFile; + uint32_t m_mobility; + uint32_t m_nNodes; + double m_TotalSimTime; + std::string m_rate; + std::string m_phyModeB; + std::string m_trName; + int m_nodeSpeed; //in m/s + int m_nodePause; //in s + uint32_t m_wavePacketSize; // bytes + double m_waveInterval; // seconds + int m_verbose; + std::ofstream m_os; + NetDeviceContainer m_adhocTxDevices; + Ipv4InterfaceContainer m_adhocTxInterfaces; + uint32_t m_scenario; + double m_gpsAccuracyNs; + double m_txMaxDelayMs; + int m_routingTables; + int m_asciiTrace; + int m_pcap; + std::string m_loadConfigFilename; + std::string m_saveConfigFilename; + + WaveBsmHelper m_waveBsmHelper; + Ptr m_routingHelper; + Ptr m_wifiPhyStats; + int m_log; + // used to get consistent random numbers across scenarios + int64_t m_streamIndex; + NodeContainer m_adhocTxNodes; + double m_txSafetyRange1; + double m_txSafetyRange2; + double m_txSafetyRange3; + double m_txSafetyRange4; + double m_txSafetyRange5; + double m_txSafetyRange6; + double m_txSafetyRange7; + double m_txSafetyRange8; + double m_txSafetyRange9; + double m_txSafetyRange10; + std::vector m_txSafetyRanges; + std::string m_exp; + int m_cumulativeBsmCaptureStart; +}; + +VanetRoutingExperiment::VanetRoutingExperiment () + : m_port (9), + m_CSVfileName ("vanet-routing.output.csv"), + m_CSVfileName2 ("vanet-routing.output2.csv"), + m_nSinks (10), + m_protocolName ("protocol"), + m_txp (20), + m_traceMobility (false), + // AODV + m_protocol (2), + // Two-Ray ground + m_lossModel (3), + m_fading (0), + m_lossModelName (""), + m_phyMode ("OfdmRate6MbpsBW10MHz"), + // 1=802.11p + m_80211mode (1), + m_traceFile (""), + m_logFile ("low_ct-unterstrass-1day.filt.5.adj.log"), + m_mobility (1), + m_nNodes (156), + m_TotalSimTime (300.01), + m_rate ("2048bps"), + m_phyModeB ("DsssRate11Mbps"), + m_trName ("vanet-routing-compare"), + m_nodeSpeed (20), + m_nodePause (0), + m_wavePacketSize (200), + m_waveInterval (0.1), + m_verbose (0), + m_scenario (1), + m_gpsAccuracyNs (40), + m_txMaxDelayMs (10), + m_routingTables (0), + m_asciiTrace (0), + m_pcap (0), + m_loadConfigFilename ("load-config.txt"), + m_saveConfigFilename (""), + m_log (0), + m_streamIndex (0), + m_adhocTxNodes (), + m_txSafetyRange1 (50.0), + m_txSafetyRange2 (100.0), + m_txSafetyRange3 (150.0), + m_txSafetyRange4 (200.0), + m_txSafetyRange5 (250.0), + m_txSafetyRange6 (300.0), + m_txSafetyRange7 (350.0), + m_txSafetyRange8 (400.0), + m_txSafetyRange9 (450.0), + m_txSafetyRange10 (500.0), + m_txSafetyRanges (), + m_exp (""), + m_cumulativeBsmCaptureStart (0) +{ + m_wifiPhyStats = CreateObject (); + m_routingHelper = CreateObject (); + + // set to non-zero value to enable + // simply uncond logging during simulation run + m_log = 1; +} + +void +VanetRoutingExperiment::SetDefaultAttributeValues () +{ + // handled in constructor +} + +// important configuration items stored in global values +static ns3::GlobalValue g_port ("VRCport", + "Port", + ns3::UintegerValue (9), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_nSinks ("VRCnSinks", + "Number of sink nodes for routing non-BSM traffic", + ns3::UintegerValue (10), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_traceMobility ("VRCtraceMobility", + "Trace mobility 1=yes;0=no", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_protocol ("VRCprotocol", + "Routing protocol", + ns3::UintegerValue (2), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_lossModel ("VRClossModel", + "Propagation Loss Model", + ns3::UintegerValue (3), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_fading ("VRCfading", + "Fast Fading Model", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_80211mode ("VRC80211mode", + "802.11 mode (0=802.11a;1=802.11p)", + ns3::UintegerValue (1), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_mobility ("VRCmobility", + "Mobility mode 0=random waypoint;1=mobility trace file", + ns3::UintegerValue (1), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_nNodes ("VRCnNodes", + "Number of nodes (vehicles)", + ns3::UintegerValue (156), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_nodeSpeed ("VRCnodeSpeed", + "Node speed (m/s) for RWP model", + ns3::UintegerValue (20), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_nodePause ("VRCnodePause", + "Node pause time (s) for RWP model", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_wavePacketSize ("VRCwavePacketSize", + "Size in bytes of WAVE BSM", + ns3::UintegerValue (200), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_verbose ("VRCverbose", + "Verbose 0=no;1=yes", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_scenario ("VRCscenario", + "Scenario", + ns3::UintegerValue (1), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_routingTables ("VRCroutingTables", + "Dump routing tables at t=5 seconds 0=no;1=yes", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_asciiTrace ("VRCasciiTrace", + "Dump ASCII trace 0=no;1=yes", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_pcap ("VRCpcap", + "Generate PCAP files 0=no;1=yes", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); +static ns3::GlobalValue g_cumulativeBsmCaptureStart ("VRCcumulativeBsmCaptureStart", + "Simulation starte time for capturing cumulative BSM", + ns3::UintegerValue (0), + ns3::MakeUintegerChecker ()); + +static ns3::GlobalValue g_txSafetyRange1 ("VRCtxSafetyRange1", + "BSM range for PDR inclusion", + ns3::DoubleValue (50.0), + ns3::MakeDoubleChecker ()); + +static ns3::GlobalValue g_txSafetyRange2 ("VRCtxSafetyRange2", + "BSM range for PDR inclusion", + ns3::DoubleValue (100.0), + ns3::MakeDoubleChecker ()); + +static ns3::GlobalValue g_txSafetyRange3 ("VRCtxSafetyRange3", + "BSM range for PDR inclusion", + ns3::DoubleValue (150.0), + ns3::MakeDoubleChecker ()); + +static ns3::GlobalValue g_txSafetyRange4 ("VRCtxSafetyRange4", + "BSM range for PDR inclusion", + ns3::DoubleValue (200.0), + ns3::MakeDoubleChecker ()); + +static ns3::GlobalValue g_txSafetyRange5 ("VRCtxSafetyRange5", + "BSM range for PDR inclusion", + ns3::DoubleValue (250.0), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txSafetyRange6 ("VRCtxSafetyRange6", + "BSM range for PDR inclusion", + ns3::DoubleValue (300.0), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txSafetyRange7 ("VRCtxSafetyRange7", + "BSM range for PDR inclusion", + ns3::DoubleValue (350.0), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txSafetyRange8 ("VRCtxSafetyRange8", + "BSM range for PDR inclusion", + ns3::DoubleValue (400.0), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txSafetyRange9 ("VRCtxSafetyRange9", + "BSM range for PDR inclusion", + ns3::DoubleValue (450.0), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txSafetyRange10 ("VRCtxSafetyRange10", + "BSM range for PDR inclusion", + ns3::DoubleValue (500.0), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txp ("VRCtxp", + "Transmission power dBm", + ns3::DoubleValue (7.5), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_totalTime ("VRCtotalTime", + "Total simulation time (s)", + ns3::DoubleValue (300.01), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_waveInterval ("VRCwaveInterval", + "Interval (s) between WAVE BSMs", + ns3::DoubleValue (0.1), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_gpsAccuracyNs ("VRCgpsAccuracyNs", + "GPS sync accuracy (ns)", + ns3::DoubleValue (40), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_txMaxDelayMs ("VRCtxMaxDelayMs", + "Tx May Delay (ms)", + ns3::DoubleValue (10), + ns3::MakeDoubleChecker ()); +static ns3::GlobalValue g_CSVfileName ("VRCCSVfileName", + "CSV filename (for time series data)", + ns3::StringValue ("vanet-routing.output.csv"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_CSVfileName2 ("VRCCSVfileName2", + "CSV filename 2 (for overall simulation scenario results)", + ns3::StringValue ("vanet-routing.output2.csv"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_phyMode ("VRCphyMode", + "PHY mode (802.11p)", + ns3::StringValue ("OfdmRate6MbpsBW10MHz"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_traceFile ("VRCtraceFile", + "Mobility trace filename", + ns3::StringValue ("./src/wave/examples/low_ct-unterstrass-1day.filt.5.adj.mob"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_logFile ("VRClogFile", + "Log filename", + ns3::StringValue ("low_ct-unterstrass-1day.filt.5.adj.log"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_rate ("VRCrate", + "Data rate", + ns3::StringValue ("2048bps"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_phyModeB ("VRCphyModeB", + "PHY mode (802.11a)", + ns3::StringValue ("DsssRate11Mbps"), + ns3::MakeStringChecker ()); +static ns3::GlobalValue g_trName ("VRCtrName", + "Trace name", + ns3::StringValue ("vanet-routing-compare"), + ns3::MakeStringChecker ()); + +void +VanetRoutingExperiment::ParseCommandLineArguments (int argc, char **argv) +{ + CommandSetup (argc, argv); + SetupScenario (); + + // user may specify up to 10 different tx distances + // to be used for calculating different values of Packet + // Delivery Ratio (PDR). Used to see the effects of + // fading over distance + m_txSafetyRanges.resize (10, 0); + m_txSafetyRanges[0] = m_txSafetyRange1; + m_txSafetyRanges[1] = m_txSafetyRange2; + m_txSafetyRanges[2] = m_txSafetyRange3; + m_txSafetyRanges[3] = m_txSafetyRange4; + m_txSafetyRanges[4] = m_txSafetyRange5; + m_txSafetyRanges[5] = m_txSafetyRange6; + m_txSafetyRanges[6] = m_txSafetyRange7; + m_txSafetyRanges[7] = m_txSafetyRange8; + m_txSafetyRanges[8] = m_txSafetyRange9; + m_txSafetyRanges[9] = m_txSafetyRange10; + + ConfigureDefaults (); + + // we are done with all configuration + // save config-store, if requested + SetGlobalsFromConfig (); + ConfigStoreHelper configStoreHelper; + configStoreHelper.SaveConfig (m_saveConfigFilename); + + m_waveBsmHelper.GetWaveBsmStats ()->SetLogging (m_log); + m_routingHelper->SetLogging (m_log); +} + +void +VanetRoutingExperiment::ConfigureNodes () +{ + m_adhocTxNodes.Create (m_nNodes); +} + +void +VanetRoutingExperiment::ConfigureChannels () +{ + // set up channel and devices + SetupAdhocDevices (); +} + +void +VanetRoutingExperiment::ConfigureDevices () +{ + // devices are set up in SetupAdhocDevices(), + // called by ConfigureChannels() + + // every device will have PHY callback for tracing + // which is used to determine the total amount of + // data transmitted, and then used to calculate + // the MAC/PHY overhead beyond the app-data + Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback (&WifiPhyStats::PhyTxTrace, m_wifiPhyStats)); + // TxDrop, RxDrop not working yet. Not sure what I'm doing wrong. + Config::Connect ("/NodeList/*/DeviceList/*/ns3::WifiNetDevice/Phy/PhyTxDrop", MakeCallback (&WifiPhyStats::PhyTxDrop, m_wifiPhyStats)); + Config::Connect ("/NodeList/*/DeviceList/*/ns3::WifiNetDevice/Phy/PhyRxDrop", MakeCallback (&WifiPhyStats::PhyRxDrop, m_wifiPhyStats)); +} + +void +VanetRoutingExperiment::ConfigureMobility () +{ + SetupAdhocMobilityNodes (); +} + +void +VanetRoutingExperiment::ConfigureApplications () +{ + // Traffic mix consists of: + // 1. routing data + // 2. Broadcasting of Basic Safety Message (BSM) + SetupRoutingMessages (); + SetupWaveMessages (); + + // config trace to capture app-data (bytes) for + // routing data, subtracted and used for + // routing overhead + std::ostringstream oss; + oss.str (""); + oss << "/NodeList/*/ApplicationList/*/$ns3::OnOffApplication/Tx"; + Config::Connect (oss.str (), MakeCallback (&RoutingHelper::OnOffTrace, m_routingHelper)); +} + +void +VanetRoutingExperiment::ConfigureTracing () +{ + WriteCsvHeader (); + SetupLogFile (); + SetupLogging (); + + AsciiTraceHelper ascii; + MobilityHelper::EnableAsciiAll (ascii.CreateFileStream (m_trName + ".mob")); +} + +void +VanetRoutingExperiment::RunSimulation () +{ + Run (); +} + +void +VanetRoutingExperiment::ProcessOutputs () +{ + // calculate and output final results + double bsm_pdr1 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (1); + double bsm_pdr2 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (2); + double bsm_pdr3 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (3); + double bsm_pdr4 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (4); + double bsm_pdr5 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (5); + double bsm_pdr6 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (6); + double bsm_pdr7 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (7); + double bsm_pdr8 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (8); + double bsm_pdr9 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (9); + double bsm_pdr10 = m_waveBsmHelper.GetWaveBsmStats ()->GetCumulativeBsmPdr (10); + + double averageRoutingGoodputKbps = 0.0; + uint32_t totalBytesTotal = m_routingHelper->GetRoutingStats ().GetCumulativeRxBytes (); + averageRoutingGoodputKbps = (((double) totalBytesTotal * 8.0) / m_TotalSimTime) / 1000.0; + + // calculate MAC/PHY overhead (mac-phy-oh) + // total WAVE BSM bytes sent + uint32_t cumulativeWaveBsmBytes = m_waveBsmHelper.GetWaveBsmStats ()->GetTxByteCount (); + uint32_t cumulativeRoutingBytes = m_routingHelper->GetRoutingStats ().GetCumulativeTxBytes (); + uint32_t totalAppBytes = cumulativeWaveBsmBytes + cumulativeRoutingBytes; + uint32_t totalPhyBytes = m_wifiPhyStats->GetTxBytes (); + // mac-phy-oh = (total-phy-bytes - total-app-bytes) / total-phy-bytes + double mac_phy_oh = 0.0; + if (totalPhyBytes > 0) + { + mac_phy_oh = (double) (totalPhyBytes - totalAppBytes) / (double) totalPhyBytes; + } + + if (m_log != 0) + { + NS_LOG_UNCOND ("BSM_PDR1=" << bsm_pdr1 << " BSM_PDR2=" << bsm_pdr2 << " BSM_PDR3=" << bsm_pdr3 << " BSM_PDR4=" << bsm_pdr4 << " BSM_PDR5=" << bsm_pdr5 << " BSM_PDR6=" << bsm_pdr6 << " BSM_PDR7=" << bsm_pdr7 << " BSM_PDR8=" << bsm_pdr8 << " BSM_PDR9=" << bsm_pdr9 << " BSM_PDR10=" << bsm_pdr10 << " Goodput=" << averageRoutingGoodputKbps << "Kbps MAC/PHY-oh=" << mac_phy_oh); + + } + + std::ofstream out (m_CSVfileName2.c_str (), std::ios::app); + + out << bsm_pdr1 << "," + << bsm_pdr2 << "," + << bsm_pdr3 << "," + << bsm_pdr4 << "," + << bsm_pdr5 << "," + << bsm_pdr6 << "," + << bsm_pdr7 << "," + << bsm_pdr8 << "," + << bsm_pdr9 << "," + << bsm_pdr10 << "," + << averageRoutingGoodputKbps << "," + << mac_phy_oh << "" + << std::endl; + + out.close (); + + m_os.close (); // close log file +} + +void +VanetRoutingExperiment::Run () +{ + NS_LOG_INFO ("Run Simulation."); + + CheckThroughput (); + + Simulator::Stop (Seconds (m_TotalSimTime)); + Simulator::Run (); + Simulator::Destroy (); +} + +// Prints actual position and velocity when a course change event occurs +void +VanetRoutingExperiment:: +CourseChange (std::ostream *os, std::string foo, Ptr mobility) +{ + Vector pos = mobility->GetPosition (); // Get position + Vector vel = mobility->GetVelocity (); // Get velocity + + pos.z = 1.5; + + int nodeId = mobility->GetObject ()->GetId (); + double t = (Simulator::Now ()).GetSeconds (); + if (t >= 1.0) + { + WaveBsmHelper::GetNodesMoving ()[nodeId] = 1; + } + + //NS_LOG_UNCOND ("Changing pos for node=" << nodeId << " at " << Simulator::Now () ); + + // Prints position and velocities + *os << Simulator::Now () << " POS: x=" << pos.x << ", y=" << pos.y + << ", z=" << pos.z << "; VEL:" << vel.x << ", y=" << vel.y + << ", z=" << vel.z << std::endl; +} + +void +VanetRoutingExperiment::CheckThroughput () +{ + uint32_t bytesTotal = m_routingHelper->GetRoutingStats ().GetRxBytes (); + uint32_t packetsReceived = m_routingHelper->GetRoutingStats ().GetRxPkts (); + double kbps = (bytesTotal * 8.0) / 1000; + double wavePDR = 0.0; + int wavePktsSent = m_waveBsmHelper.GetWaveBsmStats ()->GetTxPktCount (); + int wavePktsReceived = m_waveBsmHelper.GetWaveBsmStats ()->GetRxPktCount (); + if (wavePktsSent > 0) + { + int wavePktsReceived = m_waveBsmHelper.GetWaveBsmStats ()->GetRxPktCount (); + wavePDR = (double) wavePktsReceived / (double) wavePktsSent; + } + + int waveExpectedRxPktCount = m_waveBsmHelper.GetWaveBsmStats ()->GetExpectedRxPktCount (1); + int waveRxPktInRangeCount = m_waveBsmHelper.GetWaveBsmStats ()->GetRxPktInRangeCount (1); + double wavePDR1_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (1); + double wavePDR2_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (2); + double wavePDR3_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (3); + double wavePDR4_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (4); + double wavePDR5_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (5); + double wavePDR6_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (6); + double wavePDR7_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (7); + double wavePDR8_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (8); + double wavePDR9_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (9); + double wavePDR10_2 = m_waveBsmHelper.GetWaveBsmStats ()->GetBsmPdr (10); + + // calculate MAC/PHY overhead (mac-phy-oh) + // total WAVE BSM bytes sent + uint32_t cumulativeWaveBsmBytes = m_waveBsmHelper.GetWaveBsmStats ()->GetTxByteCount (); + uint32_t cumulativeRoutingBytes = m_routingHelper->GetRoutingStats ().GetCumulativeTxBytes (); + uint32_t totalAppBytes = cumulativeWaveBsmBytes + cumulativeRoutingBytes; + uint32_t totalPhyBytes = m_wifiPhyStats->GetTxBytes (); + // mac-phy-oh = (total-phy-bytes - total-app-bytes) / total-phy-bytes + double mac_phy_oh = 0.0; + if (totalPhyBytes > 0) + { + mac_phy_oh = (double) (totalPhyBytes - totalAppBytes) / (double) totalPhyBytes; + } + + std::ofstream out (m_CSVfileName.c_str (), std::ios::app); + + if (m_log != 0 ) + { + NS_LOG_UNCOND ("At t=" << (Simulator::Now ()).GetSeconds () << "s BSM_PDR1=" << wavePDR1_2 << " BSM_PDR1=" << wavePDR2_2 << " BSM_PDR3=" << wavePDR3_2 << " BSM_PDR4=" << wavePDR4_2 << " BSM_PDR5=" << wavePDR5_2 << " BSM_PDR6=" << wavePDR6_2 << " BSM_PDR7=" << wavePDR7_2 << " BSM_PDR8=" << wavePDR8_2 << " BSM_PDR9=" << wavePDR9_2 << " BSM_PDR10=" << wavePDR10_2 << " Goodput=" << kbps << "Kbps" /*<< " MAC/PHY-OH=" << mac_phy_oh*/); + } + + out << (Simulator::Now ()).GetSeconds () << "," + << kbps << "," + << packetsReceived << "," + << m_nSinks << "," + << m_protocolName << "," + << m_txp << "," + << wavePktsSent << "," + << wavePktsReceived << "," + << wavePDR << "," + << waveExpectedRxPktCount << "," + << waveRxPktInRangeCount << "," + << wavePDR1_2 << "," + << wavePDR2_2 << "," + << wavePDR3_2 << "," + << wavePDR4_2 << "," + << wavePDR5_2 << "," + << wavePDR6_2 << "," + << wavePDR7_2 << "," + << wavePDR8_2 << "," + << wavePDR9_2 << "," + << wavePDR10_2 << "," + << mac_phy_oh << "" + << std::endl; + + out.close (); + + m_routingHelper->GetRoutingStats ().SetRxBytes (0); + m_routingHelper->GetRoutingStats ().SetRxPkts (0); + m_waveBsmHelper.GetWaveBsmStats ()->SetRxPktCount (0); + m_waveBsmHelper.GetWaveBsmStats ()->SetTxPktCount (0); + for (int index = 1; index <= 10; index++) + { + m_waveBsmHelper.GetWaveBsmStats ()->SetExpectedRxPktCount (index, 0); + m_waveBsmHelper.GetWaveBsmStats ()->SetRxPktInRangeCount (index, 0); + } + + double currentTime = (Simulator::Now ()).GetSeconds (); + if (currentTime <= (double) m_cumulativeBsmCaptureStart) + { + for (int index = 1; index <= 10; index++) + { + m_waveBsmHelper.GetWaveBsmStats ()->ResetTotalRxPktCounts (index); + } + } + + Simulator::Schedule (Seconds (1.0), &VanetRoutingExperiment::CheckThroughput, this); +} + +void +VanetRoutingExperiment::SetConfigFromGlobals () +{ + // get settings saved from config-store + UintegerValue uintegerValue; + DoubleValue doubleValue; + StringValue stringValue; + + // This may not be the best way to manage program configuration + // (directing them through global values), but management + // through the config-store here is copied from + // src/lte/examples/lena-dual-stripe.cc + + GlobalValue::GetValueByName ("VRCport", uintegerValue); + m_port = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCnSinks", uintegerValue); + m_nSinks = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCtraceMobility", uintegerValue); + m_traceMobility = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCprotocol", uintegerValue); + m_protocol = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRClossModel", uintegerValue); + m_lossModel = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCfading", uintegerValue); + m_fading = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRC80211mode", uintegerValue); + m_80211mode = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCmobility", uintegerValue); + m_mobility = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCnNodes", uintegerValue); + m_nNodes = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCnodeSpeed", uintegerValue); + m_nodeSpeed = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCnodePause", uintegerValue); + m_nodePause = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCwavePacketSize", uintegerValue); + m_wavePacketSize = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCverbose", uintegerValue); + m_verbose = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCscenario", uintegerValue); + m_scenario = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCroutingTables", uintegerValue); + m_routingTables = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCasciiTrace", uintegerValue); + m_asciiTrace = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCpcap", uintegerValue); + m_pcap = uintegerValue.Get (); + GlobalValue::GetValueByName ("VRCcumulativeBsmCaptureStart", uintegerValue); + m_cumulativeBsmCaptureStart = uintegerValue.Get (); + + GlobalValue::GetValueByName ("VRCtxSafetyRange1", doubleValue); + m_txSafetyRange1 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange2", doubleValue); + m_txSafetyRange2 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange3", doubleValue); + m_txSafetyRange3 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange4", doubleValue); + m_txSafetyRange4 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange5", doubleValue); + m_txSafetyRange5 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange6", doubleValue); + m_txSafetyRange6 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange7", doubleValue); + m_txSafetyRange7 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange8", doubleValue); + m_txSafetyRange8 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange9", doubleValue); + m_txSafetyRange9 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxSafetyRange10", doubleValue); + m_txSafetyRange10 = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxp", doubleValue); + m_txp = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtotalTime", doubleValue); + m_TotalSimTime = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCwaveInterval", doubleValue); + m_waveInterval = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCgpsAccuracyNs", doubleValue); + m_gpsAccuracyNs = doubleValue.Get (); + GlobalValue::GetValueByName ("VRCtxMaxDelayMs", doubleValue); + m_txMaxDelayMs = doubleValue.Get (); + + GlobalValue::GetValueByName ("VRCCSVfileName", stringValue); + m_CSVfileName = stringValue.Get (); + GlobalValue::GetValueByName ("VRCCSVfileName2", stringValue); + m_CSVfileName2 = stringValue.Get (); + GlobalValue::GetValueByName ("VRCphyMode", stringValue); + m_phyMode = stringValue.Get (); + GlobalValue::GetValueByName ("VRCtraceFile", stringValue); + m_traceFile = stringValue.Get (); + GlobalValue::GetValueByName ("VRClogFile", stringValue); + m_logFile = stringValue.Get (); + GlobalValue::GetValueByName ("VRCrate", stringValue); + m_rate = stringValue.Get (); + GlobalValue::GetValueByName ("VRCphyModeB", stringValue); + m_phyModeB = stringValue.Get (); + GlobalValue::GetValueByName ("VRCtrName", stringValue); + m_trName = stringValue.Get (); +} + +void +VanetRoutingExperiment::SetGlobalsFromConfig () +{ + // get settings saved from config-store + UintegerValue uintegerValue; + DoubleValue doubleValue; + StringValue stringValue; + + g_port.SetValue (UintegerValue (m_port)); + g_nSinks.SetValue (UintegerValue (m_nSinks)); + g_traceMobility.SetValue (UintegerValue (m_traceMobility)); + g_protocol.SetValue (UintegerValue (m_protocol)); + g_lossModel.SetValue (UintegerValue (m_lossModel)); + g_fading.SetValue (UintegerValue (m_fading)); + g_80211mode.SetValue (UintegerValue (m_80211mode)); + g_mobility.SetValue (UintegerValue (m_mobility)); + g_nNodes.SetValue (UintegerValue (m_nNodes)); + g_nodeSpeed.SetValue (UintegerValue (m_nodeSpeed)); + g_nodePause.SetValue (UintegerValue (m_nodePause)); + g_wavePacketSize.SetValue (UintegerValue (m_wavePacketSize)); + g_verbose.SetValue (UintegerValue (m_verbose)); + g_scenario.SetValue (UintegerValue (m_scenario)); + g_routingTables.SetValue (UintegerValue (m_routingTables)); + g_asciiTrace.SetValue (UintegerValue (m_asciiTrace)); + g_pcap.SetValue (UintegerValue (m_pcap)); + g_cumulativeBsmCaptureStart.SetValue (UintegerValue (m_cumulativeBsmCaptureStart)); + + g_txSafetyRange1.SetValue (DoubleValue (m_txSafetyRange1)); + g_txSafetyRange2.SetValue (DoubleValue (m_txSafetyRange2)); + g_txSafetyRange3.SetValue (DoubleValue (m_txSafetyRange3)); + g_txSafetyRange4.SetValue (DoubleValue (m_txSafetyRange4)); + g_txSafetyRange5.SetValue (DoubleValue (m_txSafetyRange5)); + g_txSafetyRange6.SetValue (DoubleValue (m_txSafetyRange6)); + g_txSafetyRange7.SetValue (DoubleValue (m_txSafetyRange7)); + g_txSafetyRange8.SetValue (DoubleValue (m_txSafetyRange8)); + g_txSafetyRange9.SetValue (DoubleValue (m_txSafetyRange9)); + g_txSafetyRange10.SetValue (DoubleValue (m_txSafetyRange10)); + g_txp.SetValue (DoubleValue (m_txp)); + g_totalTime.SetValue (DoubleValue (m_TotalSimTime)); + g_waveInterval.SetValue (DoubleValue (m_waveInterval)); + g_gpsAccuracyNs.SetValue (DoubleValue (m_gpsAccuracyNs)); + g_txMaxDelayMs.SetValue (DoubleValue (m_txMaxDelayMs)); + + g_CSVfileName.SetValue (StringValue (m_CSVfileName)); + g_CSVfileName2.SetValue (StringValue (m_CSVfileName2)); + g_phyMode.SetValue (StringValue (m_phyMode)); + g_traceFile.SetValue (StringValue (m_traceFile)); + g_logFile.SetValue (StringValue (m_logFile)); + g_rate.SetValue (StringValue (m_rate)); + g_phyModeB.SetValue (StringValue (m_phyModeB)); + g_trName.SetValue (StringValue (m_trName)); + GlobalValue::GetValueByName ("VRCtrName", stringValue); + m_trName = stringValue.Get (); +} + +void +VanetRoutingExperiment::CommandSetup (int argc, char **argv) +{ + CommandLine cmd; + double txDist1 = 50.0; + double txDist2 = 100.0; + double txDist3 = 150.0; + double txDist4 = 200.0; + double txDist5 = 250.0; + double txDist6 = 300.0; + double txDist7 = 350.0; + double txDist8 = 350.0; + double txDist9 = 350.0; + double txDist10 = 350.0; + + // allow command line overrides + cmd.AddValue ("CSVfileName", "The name of the CSV output file name", m_CSVfileName); + cmd.AddValue ("CSVfileName2", "The name of the CSV output file name2", m_CSVfileName2); + cmd.AddValue ("totaltime", "Simulation end time", m_TotalSimTime); + cmd.AddValue ("nodes", "Number of nodes (i.e. vehicles)", m_nNodes); + cmd.AddValue ("sinks", "Number of routing sinks", m_nSinks); + cmd.AddValue ("txp", "Transmit power (dB), e.g. txp=7.5", m_txp); + cmd.AddValue ("traceMobility", "Enable mobility tracing", m_traceMobility); + cmd.AddValue ("protocol", "1=OLSR;2=AODV;3=DSDV;4=DSR", m_protocol); + cmd.AddValue ("lossModel", "1=Friis;2=ItuR1411Los;3=TwoRayGround;4=LogDistance", m_lossModel); + cmd.AddValue ("fading", "0=None;1=Nakagami;(buildings=1 overrides)", m_fading); + cmd.AddValue ("phyMode", "Wifi Phy mode", m_phyMode); + cmd.AddValue ("80211Mode", "1=802.11p; 2=802.11b; 3=WAVE-PHY", m_80211mode); + cmd.AddValue ("traceFile", "Ns2 movement trace file", m_traceFile); + cmd.AddValue ("logFile", "Log file", m_logFile); + cmd.AddValue ("mobility", "1=trace;2=RWP", m_mobility); + cmd.AddValue ("rate", "Rate", m_rate); + cmd.AddValue ("phyModeB", "Phy mode 802.11b", m_phyModeB); + cmd.AddValue ("speed", "Node speed (m/s)", m_nodeSpeed); + cmd.AddValue ("pause", "Node pause (s)", m_nodePause); + cmd.AddValue ("verbose", "0=quiet;1=verbose", m_verbose); + cmd.AddValue ("bsm", "(WAVE) BSM size (bytes)", m_wavePacketSize); + cmd.AddValue ("interval", "(WAVE) BSM interval (s)", m_waveInterval); + cmd.AddValue ("scenario", "1=synthetic, 2=playback-trace", m_scenario); + // User is allowed to have up to 10 different PDRs (Packet + // Delivery Ratios) calculate, and so can specify up to + // 10 different tx distances. + cmd.AddValue ("txdist1", "Expected BSM tx range, m", txDist1); + cmd.AddValue ("txdist2", "Expected BSM tx range, m", txDist2); + cmd.AddValue ("txdist3", "Expected BSM tx range, m", txDist3); + cmd.AddValue ("txdist4", "Expected BSM tx range, m", txDist4); + cmd.AddValue ("txdist5", "Expected BSM tx range, m", txDist5); + cmd.AddValue ("txdist6", "Expected BSM tx range, m", txDist6); + cmd.AddValue ("txdist7", "Expected BSM tx range, m", txDist7); + cmd.AddValue ("txdist8", "Expected BSM tx range, m", txDist8); + cmd.AddValue ("txdist9", "Expected BSM tx range, m", txDist9); + cmd.AddValue ("txdist10", "Expected BSM tx range, m", txDist10); + cmd.AddValue ("gpsaccuracy", "GPS time accuracy, in ns", m_gpsAccuracyNs); + cmd.AddValue ("txmaxdelay", "Tx max delay, in ms", m_txMaxDelayMs); + cmd.AddValue ("routingTables", "Dump routing tables at t=5 seconds", m_routingTables); + cmd.AddValue ("asciiTrace", "Dump ASCII Trace data", m_asciiTrace); + cmd.AddValue ("pcap", "Create PCAP files for all nodes", m_pcap); + cmd.AddValue ("loadconfig", "Config-store filename to load", m_loadConfigFilename); + cmd.AddValue ("saveconfig", "Config-store filename to save", m_saveConfigFilename); + cmd.AddValue ("exp", "Experiment", m_exp); + cmd.AddValue ("BsmCaptureStart", "Start time to begin capturing pkts for cumulative Bsm", m_cumulativeBsmCaptureStart); + cmd.Parse (argc, argv); + + m_txSafetyRange1 = txDist1; + m_txSafetyRange2 = txDist2; + m_txSafetyRange3 = txDist3; + m_txSafetyRange4 = txDist4; + m_txSafetyRange5 = txDist5; + m_txSafetyRange6 = txDist6; + m_txSafetyRange7 = txDist7; + m_txSafetyRange8 = txDist8; + m_txSafetyRange9 = txDist9; + m_txSafetyRange10 = txDist10; + // load configuration info from config-store + ConfigStoreHelper configStoreHelper; + configStoreHelper.LoadConfig (m_loadConfigFilename); + // transfer config-store values to config parameters + SetConfigFromGlobals (); + + // parse again so you can override input file default values via command line + cmd.Parse (argc, argv); + + m_txSafetyRange1 = txDist1; + m_txSafetyRange2 = txDist2; + m_txSafetyRange3 = txDist3; + m_txSafetyRange4 = txDist4; + m_txSafetyRange5 = txDist5; + m_txSafetyRange6 = txDist6; + m_txSafetyRange7 = txDist7; + m_txSafetyRange8 = txDist8; + m_txSafetyRange9 = txDist9; + m_txSafetyRange10 = txDist10; +} + +void +VanetRoutingExperiment::SetupLogFile () +{ + // open log file for output + m_os.open (m_logFile.c_str ()); +} + +void VanetRoutingExperiment::SetupLogging () +{ + + // Enable logging from the ns2 helper + LogComponentEnable ("Ns2MobilityHelper",LOG_LEVEL_DEBUG); + + Packet::EnablePrinting (); +} + +void +VanetRoutingExperiment::ConfigureDefaults () +{ + Config::SetDefault ("ns3::OnOffApplication::PacketSize",StringValue ("64")); + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (m_rate)); + + //Set Non-unicastMode rate to unicast mode + if (m_80211mode == 2) + { + Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",StringValue (m_phyModeB)); + } + else + { + Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",StringValue (m_phyMode)); + } +} + +void +VanetRoutingExperiment::SetupAdhocMobilityNodes () +{ + if (m_mobility == 1) + { + // Create Ns2MobilityHelper with the specified trace log file as parameter + Ns2MobilityHelper ns2 = Ns2MobilityHelper (m_traceFile); + ns2.Install (); // configure movements for each node, while reading trace file + // initially assume all nodes are not moving + WaveBsmHelper::GetNodesMoving ().resize (m_nNodes, 0); + } + else if (m_mobility == 2) + { + MobilityHelper mobilityAdhoc; + + ObjectFactory pos; + pos.SetTypeId ("ns3::RandomBoxPositionAllocator"); + pos.Set ("X", StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=1500.0]")); + pos.Set ("Y", StringValue ("ns3::UniformRandomVariable[Min=0.0|Max=300.0]")); + // we need antenna height uniform [1.0 .. 2.0] for loss model + pos.Set ("Z", StringValue ("ns3::UniformRandomVariable[Min=1.0|Max=2.0]")); + + Ptr taPositionAlloc = pos.Create ()->GetObject (); + m_streamIndex += taPositionAlloc->AssignStreams (m_streamIndex); + + std::stringstream ssSpeed; + ssSpeed << "ns3::UniformRandomVariable[Min=0.0|Max=" << m_nodeSpeed << "]"; + std::stringstream ssPause; + ssPause << "ns3::ConstantRandomVariable[Constant=" << m_nodePause << "]"; + mobilityAdhoc.SetMobilityModel ("ns3::RandomWaypointMobilityModel", + "Speed", StringValue (ssSpeed.str ()), + "Pause", StringValue (ssPause.str ()), + "PositionAllocator", PointerValue (taPositionAlloc)); + mobilityAdhoc.SetPositionAllocator (taPositionAlloc); + mobilityAdhoc.Install (m_adhocTxNodes); + m_streamIndex += mobilityAdhoc.AssignStreams (m_adhocTxNodes, m_streamIndex); + + // initially assume all nodes are moving + WaveBsmHelper::GetNodesMoving ().resize (m_nNodes, 1); + } + + // Configure callback for logging + Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", + MakeBoundCallback (&VanetRoutingExperiment::CourseChange, &m_os)); +} + +void +VanetRoutingExperiment::SetupAdhocDevices () +{ + if (m_lossModel == 1) + { + m_lossModelName = "ns3::FriisPropagationLossModel"; + } + else if (m_lossModel == 2) + { + m_lossModelName = "ns3::ItuR1411LosPropagationLossModel"; + } + else if (m_lossModel == 3) + { + m_lossModelName = "ns3::TwoRayGroundPropagationLossModel"; + } + else if (m_lossModel == 4) + { + m_lossModelName = "ns3::LogDistancePropagationLossModel"; + } + else + { + // Unsupported propagation loss model. + // Treating as ERROR + NS_LOG_ERROR ("Invalid propagation loss model specified. Values must be [1-4], where 1=Friis;2=ItuR1411Los;3=TwoRayGround;4=LogDistance"); + } + + // frequency + double freq = 0.0; + if ((m_80211mode == 1) + || (m_80211mode == 3)) + { + // 802.11p 5.9 GHz + freq = 5.9e9; + } + else + { + // 802.11b 2.4 GHz + freq = 2.4e9; + } + + // Setup propagation models + YansWifiChannelHelper wifiChannel; + wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel"); + if (m_lossModel == 3) + { + // two-ray requires antenna height (else defaults to Friss) + wifiChannel.AddPropagationLoss (m_lossModelName, "Frequency", DoubleValue (freq), "HeightAboveZ", DoubleValue (1.5)); + } + else + { + wifiChannel.AddPropagationLoss (m_lossModelName, "Frequency", DoubleValue (freq)); + } + + // Propagation loss models are additive. + if (m_fading != 0) + { + // if no obstacle model, then use Nakagami fading if requested + wifiChannel.AddPropagationLoss ("ns3::NakagamiPropagationLossModel"); + } + + // the channel + Ptr channel = wifiChannel.Create (); + + // The below set of helpers will help us to put together the wifi NICs we want + YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); + wifiPhy.SetChannel (channel); + // ns-3 supports generate a pcap trace + wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11); + + YansWavePhyHelper wavePhy = YansWavePhyHelper::Default (); + wavePhy.SetChannel (channel); + wavePhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11); + + // Setup WAVE PHY and MAC + NqosWaveMacHelper wifi80211pMac = NqosWaveMacHelper::Default (); + WaveHelper waveHelper = WaveHelper::Default (); + Wifi80211pHelper wifi80211p = Wifi80211pHelper::Default (); + if (m_verbose) + { + wifi80211p.EnableLogComponents (); // Turn on all Wifi 802.11p logging + // likewise, turn on WAVE PHY logging + waveHelper.EnableLogComponents (); + } + + WifiHelper wifi; + + // Setup 802.11b stuff + wifi.SetStandard (WIFI_PHY_STANDARD_80211b); + + wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", + "DataMode",StringValue (m_phyModeB), + "ControlMode",StringValue (m_phyModeB)); + + // Setup 802.11p stuff + wifi80211p.SetRemoteStationManager ("ns3::ConstantRateWifiManager", + "DataMode",StringValue (m_phyMode), + "ControlMode",StringValue (m_phyMode)); + + // Setup WAVE-PHY stuff + waveHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager", + "DataMode",StringValue (m_phyMode), + "ControlMode",StringValue (m_phyMode)); + + // Set Tx Power + wifiPhy.Set ("TxPowerStart",DoubleValue (m_txp)); + wifiPhy.Set ("TxPowerEnd", DoubleValue (m_txp)); + wavePhy.Set ("TxPowerStart",DoubleValue (m_txp)); + wavePhy.Set ("TxPowerEnd", DoubleValue (m_txp)); + + // Add a non-QoS upper mac, and disable rate control + NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default (); + wifiMac.SetType ("ns3::AdhocWifiMac"); + QosWaveMacHelper waveMac = QosWaveMacHelper::Default (); + + // Setup net devices + + if (m_80211mode == 3) + { + m_adhocTxDevices = waveHelper.Install (wavePhy, waveMac, m_adhocTxNodes); + } + else if (m_80211mode == 1) + { + m_adhocTxDevices = wifi80211p.Install (wifiPhy, wifi80211pMac, m_adhocTxNodes); + } + else + { + m_adhocTxDevices = wifi.Install (wifiPhy, wifiMac, m_adhocTxNodes); + } + + if (m_asciiTrace != 0) + { + AsciiTraceHelper ascii; + Ptr osw = ascii.CreateFileStream ( (m_trName + ".tr").c_str ()); + wifiPhy.EnableAsciiAll (osw); + wavePhy.EnableAsciiAll (osw); + } + if (m_pcap != 0) + { + wifiPhy.EnablePcapAll ("vanet-routing-compare-pcap"); + wavePhy.EnablePcapAll ("vanet-routing-compare-pcap"); + } +} + +void +VanetRoutingExperiment::SetupWaveMessages () +{ + // WAVE PHY mode + // 0=continuous channel; 1=channel-switching + int chAccessMode = 0; + if (m_80211mode == 3) + { + chAccessMode = 1; + } + + m_waveBsmHelper.Install (m_adhocTxInterfaces, + Seconds (m_TotalSimTime), + m_wavePacketSize, + Seconds (m_waveInterval), + // GPS accuracy (i.e, clock drift), in number of ns + m_gpsAccuracyNs, + m_txSafetyRanges, + chAccessMode, + // tx max delay before transmit, in ms + MilliSeconds (m_txMaxDelayMs)); + + // fix random number streams + m_streamIndex += m_waveBsmHelper.AssignStreams (m_adhocTxNodes, m_streamIndex); +} + +void +VanetRoutingExperiment::SetupRoutingMessages () +{ + m_routingHelper->Install (m_adhocTxNodes, + m_adhocTxDevices, + m_adhocTxInterfaces, + m_TotalSimTime, + m_protocol, + m_nSinks, + m_routingTables); +} + +void +VanetRoutingExperiment::SetupScenario () +{ + // member variable parameter use + // defaults or command line overrides, + // except where scenario={1,2,3,...} + // have been specified, in which case + // specify parameters are overwritten + // here to setup for specific scenarios + + // certain parameters may be further overridden + // i.e. specify a scenario, override tx power. + + if (m_scenario == 1) + { + // 40 nodes in RWP 300 m x 1500 m synthetic highway, 10s + m_traceFile = ""; + m_logFile = ""; + m_mobility = 2; + if (m_nNodes == 156) + { + m_nNodes = 40; + } + if (m_TotalSimTime == 300.01) + { + m_TotalSimTime = 10.0; + } + } + else if (m_scenario == 2) + { + // Realistic vehicular trace in 4.6 km x 3.0 km suburban Zurich + // "low density, 99 total vehicles" + m_traceFile = "src/wave/examples/low99-ct-unterstrass-1day.filt.7.adj.mob"; + m_logFile = "low99-ct-unterstrass-1day.filt.7.adj.log"; + m_mobility = 1; + m_nNodes = 99; + m_TotalSimTime = 300.01; + m_nodeSpeed = 0; + m_nodePause = 0; + m_CSVfileName = "low_vanet-routing-compare.csv"; + m_CSVfileName = "low_vanet-routing-compare2.csv"; + } +} + +void +VanetRoutingExperiment::WriteCsvHeader () +{ + //blank out the last output file and write the column headers + std::ofstream out (m_CSVfileName.c_str ()); + out << "SimulationSecond," << + "ReceiveRate," << + "PacketsReceived," << + "NumberOfSinks," << + "RoutingProtocol," << + "TransmissionPower," << + "WavePktsSent," << + "WavePtksReceived," << + "WavePktsPpr," << + "ExpectedWavePktsReceived," << + "ExpectedWavePktsInCoverageReceived," << + "BSM_PDR1," << + "BSM_PDR2," << + "BSM_PDR3," << + "BSM_PDR4," << + "BSM_PDR5," << + "BSM_PDR6," << + "BSM_PDR7," << + "BSM_PDR8," << + "BSM_PDR9," << + "BSM_PDR10," << + "MacPhyOverhead" << + std::endl; + out.close (); + + std::ofstream out2 (m_CSVfileName2.c_str ()); + out2 << "BSM_PDR1," + << "BSM_PDR2," + << "BSM_PDR3," + << "BSM_PDR4," + << "BSM_PDR5," + << "BSM_PDR6," + << "BSM_PDR7," + << "BSM_PDR8," + << "BSM_PDR9," + << "BSM_PDR10," + << "AverageRoutingGoodputKbps," + << "MacPhyOverhead" + << std::endl; + out2.close (); +} + +int +main (int argc, char *argv[]) +{ + VanetRoutingExperiment experiment; + experiment.Simulate (argc, argv); +} diff --git a/src/wave/helper/wave-bsm-helper.cc b/src/wave/helper/wave-bsm-helper.cc new file mode 100644 index 000000000..e5a298d15 --- /dev/null +++ b/src/wave/helper/wave-bsm-helper.cc @@ -0,0 +1,164 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + +#include "ns3/wave-bsm-helper.h" +#include "ns3/log.h" + +NS_LOG_COMPONENT_DEFINE ("WaveBsmHelper"); + +namespace ns3 { + +std::vector WaveBsmHelper::nodesMoving; + +WaveBsmHelper::WaveBsmHelper () + : m_waveBsmStats () +{ + m_txSafetyRangesSq.resize (10, 0); + m_txSafetyRangesSq[0] = 50.0 * 50.0; + m_txSafetyRangesSq[1] = 100.0 * 100.0; + m_txSafetyRangesSq[2] = 200.0 * 200.0; + m_txSafetyRangesSq[3] = 300.0 * 300.0; + m_txSafetyRangesSq[4] = 400.0 * 400.0; + m_txSafetyRangesSq[5] = 500.0 * 500.0; + m_txSafetyRangesSq[6] = 600.0 * 600.0; + m_txSafetyRangesSq[7] = 800.0 * 800.0; + m_txSafetyRangesSq[8] = 1000.0 * 1000.0; + m_txSafetyRangesSq[9] = 1500.0 * 1500.0; + + m_factory.SetTypeId ("ns3::BsmApplication"); +} + +void +WaveBsmHelper::SetAttribute (std::string name, const AttributeValue &value) +{ + m_factory.Set (name, value); +} + +ApplicationContainer +WaveBsmHelper::Install (Ptr node) const +{ + return ApplicationContainer (InstallPriv (node)); +} + +ApplicationContainer +WaveBsmHelper::Install (Ipv4InterfaceContainer i) const +{ + ApplicationContainer apps; + for (Ipv4InterfaceContainer::Iterator itr = i.Begin (); itr != i.End (); ++itr) + { + std::pair, uint32_t> interface = (*itr); + Ptr pp = interface.first; + Ptr node = pp->GetObject (); + apps.Add (InstallPriv (node)); + } + + return apps; +} + +Ptr +WaveBsmHelper::InstallPriv (Ptr node) const +{ + Ptr app = m_factory.Create (); + node->AddApplication (app); + + return app; +} + +void +WaveBsmHelper::Install (Ipv4InterfaceContainer & i, + Time totalTime, // seconds + uint32_t wavePacketSize, // bytes + Time waveInterval, // seconds + double gpsAccuracyNs, // clock drift range in number of ns + std::vector ranges, // m + int chAccessMode, // channel access mode + Time txMaxDelay) // max delay prior to transmit +{ + int size = ranges.size (); + m_txSafetyRangesSq.clear (); + m_txSafetyRangesSq.resize (size, 0); + for (int index = 0; index < size; index++) + { + // stored as square of value, for optimization + m_txSafetyRangesSq[index] = ranges[index] * ranges[index]; + } + + // install a BsmApplication on each node + ApplicationContainer bsmApps = Install (i); + // start BSM app immediately (BsmApplication will + // delay transmission of first BSM by 1.0 seconds) + bsmApps.Start (Seconds (0)); + bsmApps.Stop (totalTime); + + // for each app, setup the app parameters + ApplicationContainer::Iterator aci; + int nodeId = 0; + for (aci = bsmApps.Begin (); aci != bsmApps.End (); ++aci) + { + Ptr bsmApp = DynamicCast (*aci); + bsmApp->Setup (i, + nodeId, + totalTime, + wavePacketSize, + waveInterval, + gpsAccuracyNs, + m_txSafetyRangesSq, + GetWaveBsmStats (), + &nodesMoving, + chAccessMode, + txMaxDelay); + nodeId++; + } +} + +Ptr +WaveBsmHelper::GetWaveBsmStats () +{ + return &m_waveBsmStats; +} + +int64_t +WaveBsmHelper::AssignStreams (NodeContainer c, int64_t stream) +{ + int64_t currentStream = stream; + Ptr node; + for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) + { + node = (*i); + for (uint32_t j = 0; j < node->GetNApplications (); j++) + { + Ptr bsmApp = DynamicCast (node->GetApplication (j)); + if (bsmApp) + { + currentStream += bsmApp->AssignStreams (currentStream); + } + } + } + return (currentStream - stream); +} + +std::vector& +WaveBsmHelper::GetNodesMoving () +{ + return nodesMoving; +} + +} // namespace ns3 diff --git a/src/wave/helper/wave-bsm-helper.h b/src/wave/helper/wave-bsm-helper.h new file mode 100644 index 000000000..1ffd87ed4 --- /dev/null +++ b/src/wave/helper/wave-bsm-helper.h @@ -0,0 +1,147 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + +#ifndef WAVE_BSM_HELPER_H +#define WAVE_BSM_HELPER_H + +#include +#include "ns3/wave-bsm-stats.h" +#include "ns3/bsm-application.h" +#include "ns3/object-factory.h" +#include "ns3/application-container.h" +#include "ns3/nstime.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/mobility-model.h" + +namespace ns3 { +/** + * \ingroup wave + * \brief The WaveBsmHelper class manages + * IEEE 1609 WAVE (Wireless Access in Vehicular Environments) + * Basic Safety Messages (BSMs) and uses the WaveBsmStats class + * to manage statistics about BSMs transmitted and received + * The BSM is a ~200-byte packet that is + * generally broadcast from every vehicle at a nominal rate of 10 Hz. + */ +class WaveBsmHelper +{ +public: + /** + * \brief Constructor + * \return none + */ + WaveBsmHelper (); + + /** + * Helper function used to set the underlying application attributes. + * + * \param name the name of the application attribute to set + * \param value the value of the application attribute to set + */ + void SetAttribute (std::string name, const AttributeValue &value); + + /** + * Install an ns3::BsmApplication on each node of the input container + * configured with all the attributes set with SetAttribute. + * + * \param i Ipv4InterfaceContainer of the set of interfaces on which an BsmApplication + * will be installed on the nodes. + * \returns Container of Ptr to the applications installed. + */ + ApplicationContainer Install (Ipv4InterfaceContainer i) const; + + /** + * Install an ns3::BsmApplication on the node configured with all the + * attributes set with SetAttribute. + * + * \param node The node on which an BsmApplication will be installed. + * \returns Container of Ptr to the applications installed. + */ + ApplicationContainer Install (Ptr node) const; + + /** + * \brief Installs BSM generation on devices for nodes + * and their interfaces + * \param i IPv4 interface container + * \param totalTime total amount of time that BSM packets should be transmitted + * \param wavePacketSize the size, in bytes, of a WAVE BSM + * \param waveInterval the time, in seconds, between each WAVE BSM transmission, + * typically 10 Hz (0.1 second) + * \param gpsAccuracy the timing synchronization accuracy of GPS time, in seconds. + * GPS time-sync is ~40-100 ns. Universally synchronized time among all vehicles + * will result in all vehicles transmitting safety messages simultaneously, leading + * to excessive wireless collisions. + * \param range the expected transmission range, in m. + * \return none + */ + void Install (Ipv4InterfaceContainer & i, + Time totalTime, // seconds + uint32_t wavePacketSize, // bytes + Time waveInterval, // seconds + double gpsAccuracyNs, // clock drift range in number of ns + std::vector ranges, // m + int chAccessMode, // channel access mode (0=continuous; 1=switching) + Time txMaxDelay); // max delay prior to transmit + + /** + * \brief Returns the WaveBsmStats instance + * \return the WaveBsmStats instance + */ + Ptr GetWaveBsmStats (); + + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. The Install() method should have previously been + * called by the user. + * + * \param stream first stream index to use + * \param c NodeContainer of the set of nodes for which the BsmApplication + * should be modified to use a fixed stream + * \return the number of stream indices assigned by this helper + */ + int64_t AssignStreams (NodeContainer c, int64_t stream); + + /** + * \brief Returns the list of moving nove indicators + * \return the list of moving node indicators + */ + static std::vector& GetNodesMoving (); + +private: + /** + * Install an ns3::BsmApplication on the node + * + * \param node The node on which an BsmApplication will be installed. + * \returns Ptr to the application installed. + */ + Ptr InstallPriv (Ptr node) const; + + ObjectFactory m_factory; //!< Object factory. + WaveBsmStats m_waveBsmStats; + // tx safety range squared, for optimization + std::vector m_txSafetyRangesSq; + static std::vector nodesMoving; +}; + +} // namespace ns3 + +#endif /* WAVE_BSM_HELPER_H*/ diff --git a/src/wave/helper/wave-bsm-stats.cc b/src/wave/helper/wave-bsm-stats.cc new file mode 100644 index 000000000..50497d8ed --- /dev/null +++ b/src/wave/helper/wave-bsm-stats.cc @@ -0,0 +1,190 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + + +#include "ns3/wave-bsm-stats.h" +#include "ns3/integer.h" +#include "ns3/log.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("WaveBsmStats"); + +WaveBsmStats::WaveBsmStats () + : m_wavePktSendCount (0), + m_waveByteSendCount (0), + m_wavePktReceiveCount (0), + m_log (0) +{ + m_wavePktExpectedReceiveCounts.resize (10, 0); + m_wavePktInCoverageReceiveCounts.resize (10, 0); + m_waveTotalPktExpectedReceiveCounts.resize (10, 0); + m_waveTotalPktInCoverageReceiveCounts.resize (10, 0); +} + +void +WaveBsmStats::IncTxPktCount () +{ + m_wavePktSendCount++; +} + +int +WaveBsmStats::GetTxPktCount () +{ + return m_wavePktSendCount; +} + +void +WaveBsmStats::IncExpectedRxPktCount (int index) +{ + m_wavePktExpectedReceiveCounts[index - 1]++; + m_waveTotalPktExpectedReceiveCounts[index - 1]++; +} + +void +WaveBsmStats::IncRxPktCount () +{ + m_wavePktReceiveCount++; +} + +void +WaveBsmStats::IncRxPktInRangeCount (int index) +{ + m_wavePktInCoverageReceiveCounts[index - 1]++; + m_waveTotalPktInCoverageReceiveCounts[index - 1]++; +} + +int +WaveBsmStats::GetRxPktCount () +{ + return m_wavePktReceiveCount; +} + +int +WaveBsmStats::GetExpectedRxPktCount (int index) +{ + return m_wavePktExpectedReceiveCounts[index - 1]; +} + +int +WaveBsmStats::GetRxPktInRangeCount (int index) +{ + return m_wavePktInCoverageReceiveCounts[index - 1]; +} + +void +WaveBsmStats::SetTxPktCount (int count) +{ + m_wavePktSendCount = count; +} + +void +WaveBsmStats::SetRxPktCount (int count) +{ + m_wavePktReceiveCount = count; +} + +void +WaveBsmStats::IncTxByteCount (int bytes) +{ + m_waveByteSendCount += bytes; +} + +int +WaveBsmStats::GetTxByteCount () +{ + return m_waveByteSendCount; +} + +double +WaveBsmStats::GetBsmPdr (int index) +{ + double pdr = 0.0; + + if (m_wavePktExpectedReceiveCounts[index - 1] > 0) + { + pdr = (double) m_wavePktInCoverageReceiveCounts[index - 1] / (double) m_wavePktExpectedReceiveCounts[index - 1]; + // due to node movement, it is + // possible to receive a packet that is not slightly "within range" that was + // transmitted at the time when the nodes were slightly "out of range" + // thus, prevent overflow of PDR > 100% + if (pdr > 1.0) + { + pdr = 1.0; + } + } + + return pdr; +} + +double +WaveBsmStats::GetCumulativeBsmPdr (int index) +{ + double pdr = 0.0; + + if (m_waveTotalPktExpectedReceiveCounts[index - 1] > 0) + { + pdr = (double) m_waveTotalPktInCoverageReceiveCounts[index - 1] / (double) m_waveTotalPktExpectedReceiveCounts[index - 1]; + // due to node movement, it is + // possible to receive a packet that is not slightly "within range" that was + // transmitted at the time when the nodes were slightly "out of range" + // thus, prevent overflow of PDR > 100% + if (pdr > 1.0) + { + pdr = 1.0; + } + } + + return pdr; +} + +void +WaveBsmStats::SetLogging (int log) +{ + m_log = log; +} + +int +WaveBsmStats::GetLogging () +{ + return m_log; +} + +void +WaveBsmStats::SetExpectedRxPktCount (int index, int count) +{ + m_wavePktExpectedReceiveCounts[index - 1] = count; +} + +void +WaveBsmStats::SetRxPktInRangeCount (int index, int count) +{ + m_wavePktInCoverageReceiveCounts[index - 1] = count; +} + +void +WaveBsmStats::ResetTotalRxPktCounts (int index) +{ + m_waveTotalPktInCoverageReceiveCounts[index - 1] = 0; + m_waveTotalPktExpectedReceiveCounts[index - 1] = 0; +} + +} // namespace ns3 diff --git a/src/wave/helper/wave-bsm-stats.h b/src/wave/helper/wave-bsm-stats.h new file mode 100644 index 000000000..fd38fd38c --- /dev/null +++ b/src/wave/helper/wave-bsm-stats.h @@ -0,0 +1,235 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + +#ifndef WAVE_BSM_STATS_H +#define WAVE_BSM_STATS_H + +#include "ns3/object.h" +#include + +namespace ns3 { +class WaveBsmStats : public Object +/** + * \ingroup wave + * \brief The WaveBsmStats class implements a stats collector for + * IEEE 1609 WAVE (Wireless Access in Vehicular Environments) + * Basic Safety Messages (BSMs). The BSM is a ~200-byte packet that is + * generally broadcast from every vehicle at a nominal rate of 10 Hz. + */ +/* + * Note: This class collects data elements and accessors + * along with methods that calculate metrics from the data + * elements. The data and metrics calculation algorithms + * are collected together here purely to keep them together. + * Future work may need to add additional metric calculations, + * and for now, we are trying to keep all related data and + * algorithms together, although these could easily be + * refactored in the future and moved to separate classes. + * However, it seems that for now, moving the data elements + * or the algorithms separately into different classes could + * lead to confusion over usage. + */ +{ +public: + /** + * \brief Constructor + * \return none + */ + WaveBsmStats (); + + /** + * \brief Increments the count of transmitted packets + * \return none + */ + void IncTxPktCount (); + + /** + * \brief Returns the count of transmitted packets + * \return count of packets transmitted + */ + int GetTxPktCount (); + + /* + * Note: + * The WAVE Basic Safety Message (BSM) is broadcast and + * unacknowledged. In order to calculate packet delivery + * ratio (PDR), we must count i) the packets that are + * actually received and ii) the transmitted packets that + * are expected to be received. Both are relative to a + * specified (circular) coverage area. + * + * For example: Say we have three nodes, A, B, and C, each + * separated by 40m, as follows: + * + * A --<40m>-- B --<40m>-- C + * + * Let's assume that the transmission range is 50m, and only + * A is transmitting (i.e. broadcasting). B can receive A's + * broadcasts, while C cannot. Let's assume no dropped packets. + * If we set the coverage area to 100m, then the PDR is 50%, + * because B receives every transmission from A, while C receives + * none of them. However, if we change the effective + * coverage area to 75m then the PDR improves to 100%, because + * B receives 100% of A's transmissions, and C is outside of the + * coverage area, and so does not factor in to the PDR. + */ + + /** + * \brief Increments the count of (broadcast) packets expected + * to be received within the coverage area1. Broadcast packets + * (i.e. WAVE Basic Safety Messages) are not ACK'd. For packet + * delivery ratio (PDR), we need to count transmitted packets that + * are expected to be received within the coverage area, even + * though they may not be physically received (due to collisions + * or receiver power thresholds). + * \return none + */ + void IncExpectedRxPktCount (int index); + + /** + * \brief Increments the count of actual packets received + * (regardless of coverage area). + * \return none + */ + void IncRxPktCount (); + + /** + * \brief Increments the count of actual packets received within + * the coverage area(index). Broadcast packets + * (i.e. WAVE Basic Safety Messages) are not ACK'd. For packet + * delivery ratio (PDR), we need to count only those received packets + * that are actually received within the (circular) coverage area. + * \return none + */ + void IncRxPktInRangeCount (int index); + + /** + * \brief Returns the count of packets received + * \return the count of packets received + */ + int GetRxPktCount (); + + /** + * \brief Returns the count of expected packets received within range(index) + * \return the count of expected packets received within range(index) + */ + int GetExpectedRxPktCount (int index); + + /** + * \brief Increments the count of actual packets recevied within range(index) + * \return the count of actual packets received within range(index) + */ + int GetRxPktInRangeCount (int index); + + /** + * \brief Sets the count of packets expected to received + * \param range index + * \param count the count of packets + * \return none + */ + void SetExpectedRxPktCount (int index, int count); + + /** + * \brief Sets the count of packets within range that are received + * \param range index + * \param count the count of packets + * \return none + */ + void SetRxPktInRangeCount (int index, int count); + + /** + * \brief Resets the count of total packets + * expected and/or within range(index) that are received + * \return none + */ + void ResetTotalRxPktCounts (int index); + + /** + * \brief Sets the count of packets transmitted + * \param count the count of packets transmitted + * \return none + */ + void SetTxPktCount (int count); + + /** + * \brief Sets the count of packets received + * \param count the count of packets received + * \return none + */ + void SetRxPktCount (int count); + + /** + * \brief Increments the count of (application data) bytes transmitted + * not including MAC/PHY overhead + * \param bytes the bytes of application-data transmitted + * \return none + */ + void IncTxByteCount (int bytes); + + /** + * \brief Returns the count of (application data) bytes transmitted + * not include MAC/PHY overhead + * \return number of bytes of application-data transmitted + */ + int GetTxByteCount (); + + /** + * \brief Returns the BSM Packet Delivery Ratio (PDR) + * which is the percent of expected packets within range(index) that + * are actually received + * \return the packet delivery ratio (PDR) of BSMs. + */ + double GetBsmPdr (int index); + + /** + * \brief Returns the cumulative BSM Packet Delivery Ratio (PDR) + * which is the percent of cumulative expected packets within range(index) + * that are actually received + * \return the packet delivery ratio (PDR) of BSMs. + */ + double GetCumulativeBsmPdr (int index); + + /** + * \brief Enables/disables logging + * \return none + */ + void SetLogging (int log); + + /** + * \brief Gets logging state + * \return logging state + */ + int GetLogging (); + +private: + int m_wavePktSendCount; + int m_waveByteSendCount; + int m_wavePktReceiveCount; + std::vector m_wavePktInCoverageReceiveCounts; + std::vector m_wavePktExpectedReceiveCounts; + std::vector m_waveTotalPktInCoverageReceiveCounts; + std::vector m_waveTotalPktExpectedReceiveCounts; + int m_log; +}; + +} // namespace ns3 + +#endif /* WAVE_BSM_STATS_H*/ diff --git a/src/wave/model/bsm-application.cc b/src/wave/model/bsm-application.cc new file mode 100644 index 000000000..8c49aa3f6 --- /dev/null +++ b/src/wave/model/bsm-application.cc @@ -0,0 +1,413 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + +#include "ns3/bsm-application.h" +#include "ns3/log.h" +#include "ns3/seq-ts-header.h" +#include "ns3/wave-net-device.h" +#include "ns3/wave-mac-helper.h" +#include "ns3/wave-helper.h" +#include "ns3/mobility-model.h" +#include "ns3/mobility-helper.h" + +NS_LOG_COMPONENT_DEFINE ("BsmApplication"); + +namespace ns3 { + +// (Arbitrary) port for establishing socket to transmit WAVE BSMs +int BsmApplication::wavePort = 9080; + +NS_OBJECT_ENSURE_REGISTERED (BsmApplication); + +TypeId +BsmApplication::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::BsmApplication") + .SetParent () + .AddConstructor () + ; + return tid; +} + +BsmApplication::BsmApplication () + : m_waveBsmStats (0), + m_txSafetyRangesSq (), + m_TotalSimTime (Seconds (10)), + m_wavePacketSize (200), + m_numWavePackets (1), + m_waveInterval (MilliSeconds (100)), + m_gpsAccuracyNs (10000), + m_adhocTxInterfaces (0), + m_nodesMoving (0), + m_unirv (0), + m_nodeId (0), + m_chAccessMode (0), + m_txMaxDelay (MilliSeconds (10)), + m_prevTxDelay (MilliSeconds (0)) +{ + NS_LOG_FUNCTION (this); +} + +BsmApplication::~BsmApplication () +{ + NS_LOG_FUNCTION (this); +} + +void +BsmApplication::DoDispose (void) +{ + NS_LOG_FUNCTION (this); + + // chain up + Application::DoDispose (); +} + +// Application Methods +void BsmApplication::StartApplication () // Called at time specified by Start +{ + NS_LOG_FUNCTION (this); + + // setup generation of WAVE BSM messages + Time waveInterPacketInterval = m_waveInterval; + + // BSMs are not transmitted for the first second + Time startTime = Seconds (1.0); + // total length of time transmitting WAVE packets + Time totalTxTime = m_TotalSimTime - startTime; + // total WAVE packets needing to be sent + m_numWavePackets = (uint32_t) (totalTxTime.GetDouble () / m_waveInterval.GetDouble ()); + + TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory"); + + // every node broadcasts WAVE BSM to potentially all other nodes + Ptr recvSink = Socket::CreateSocket (GetNode (m_nodeId), tid); + recvSink->SetRecvCallback (MakeCallback (&BsmApplication::ReceiveWavePacket, this)); + InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), wavePort); + recvSink->Bind (local); + recvSink->BindToNetDevice (GetNetDevice (m_nodeId)); + recvSink->SetAllowBroadcast (true); + + // dest is broadcast address + InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), wavePort); + recvSink->Connect (remote); + + // Transmission start time for each BSM: + // We assume that the start transmission time + // for the first packet will be on a ns-3 time + // "Second" boundary - e.g., 1.0 s. + // However, the actual transmit time must reflect + // additional effects of 1) clock drift and + // 2) transmit delay requirements. + // 1) Clock drift - clocks are not perfectly + // synchronized across all nodes. In a VANET + // we assume all nodes sync to GPS time, which + // itself is assumed accurate to, say, 40-100 ns. + // Thus, the start transmission time must be adjusted + // by some value, t_drift. + // 2) Transmit delay requirements - The US + // minimum performance requirements for V2V + // BSM transmission expect a random delay of + // +/- 5 ms, to avoid simultanous transmissions + // by all vehicles congesting the channel. Thus, + // we need to adjust the start trasmission time by + // some value, t_tx_delay. + // Therefore, the actual transmit time should be: + // t_start = t_time + t_drift + t_tx_delay + // t_drift is always added to t_time. + // t_tx_delay is supposed to be +/- 5ms, but if we + // allow negative numbers the time could drift to a value + // BEFORE the interval start time (i.e., at 100 ms + // boundaries, we do not want to drift into the + // previous interval, such as at 95 ms. Instead, + // we always want to be at the 100 ms interval boundary, + // plus [0..10] ms tx delay. + // Thus, the average t_tx_delay will be + // within the desired range of [0..10] ms of + // (t_time + t_drift) + + // WAVE devices sync to GPS time + // and all devices would like to begin broadcasting + // their safety messages immediately at the start of + // the CCH interval. However, if all do so, then + // significant collisions occur. Thus, we assume there + // is some GPS sync accuracy on GPS devices, + // typically 40-100 ns. + // Get a uniformly random number for GPS sync accuracy, in ns. + Time tDrift = NanoSeconds (m_unirv->GetInteger (0, m_gpsAccuracyNs)); + + // When transmitting at a default rate of 10 Hz, + // the subsystem shall transmit every 100 ms +/- + // a random value between 0 and 5 ms. [MPR-BSMTX-TXTIM-002] + // Source: CAMP Vehicle Safety Communications 4 Consortium + // On-board Minimum Performance Requirements + // for V2V Safety Systems Version 1.0, December 17, 2014 + // max transmit delay (default 10ms) + // get value for transmit delay, as number of ns + uint32_t d_ns = static_cast (m_txMaxDelay.GetInteger ()); + // convert random tx delay to ns-3 time + // see note above regarding centering tx delay + // offset by 5ms + a random value. + Time txDelay = NanoSeconds (m_unirv->GetInteger (0, d_ns)); + m_prevTxDelay = txDelay; + + Time txTime = startTime + tDrift + txDelay; + // schedule transmission of first packet + Simulator::ScheduleWithContext (recvSink->GetNode ()->GetId (), + txTime, &BsmApplication::GenerateWaveTraffic, this, + recvSink, m_wavePacketSize, m_numWavePackets, waveInterPacketInterval, m_nodeId); +} + +void BsmApplication::StopApplication () // Called at time specified by Stop +{ + NS_LOG_FUNCTION (this); +} + +void +BsmApplication::Setup (Ipv4InterfaceContainer & i, + int nodeId, + Time totalTime, + uint32_t wavePacketSize, // bytes + Time waveInterval, + double gpsAccuracyNs, + std::vector rangesSq, // m ^2 + Ptr waveBsmStats, + std::vector * nodesMoving, + int chAccessMode, + Time txMaxDelay) +{ + NS_LOG_FUNCTION (this); + + m_unirv = CreateObject (); + + m_TotalSimTime = totalTime; + m_wavePacketSize = wavePacketSize; + m_waveInterval = waveInterval; + m_gpsAccuracyNs = gpsAccuracyNs; + int size = rangesSq.size (); + m_waveBsmStats = waveBsmStats; + m_nodesMoving = nodesMoving; + m_chAccessMode = chAccessMode; + m_txSafetyRangesSq.clear (); + m_txSafetyRangesSq.resize (size, 0); + + for (int index = 0; index < size; index++) + { + // stored as square of value, for optimization + m_txSafetyRangesSq[index] = rangesSq[index]; + } + + m_adhocTxInterfaces = &i; + m_nodeId = nodeId; + m_txMaxDelay = txMaxDelay; +} + +void +BsmApplication::GenerateWaveTraffic (Ptr socket, uint32_t pktSize, + uint32_t pktCount, Time pktInterval, + uint32_t sendingNodeId) +{ + NS_LOG_FUNCTION (this); + + // more packets to send? + if (pktCount > 0) + { + // for now, we cannot tell if each node has + // started mobility. so, as an optimization + // only send if this node is moving + // if not, then skip + int txNodeId = sendingNodeId; + Ptr txNode = GetNode (txNodeId); + Ptr txPosition = txNode->GetObject (); + NS_ASSERT (txPosition != 0); + + int senderMoving = m_nodesMoving->at (txNodeId); + if (senderMoving != 0) + { + // send it! + socket->Send (Create (pktSize)); + // count it + m_waveBsmStats->IncTxPktCount (); + m_waveBsmStats->IncTxByteCount (pktSize); + int wavePktsSent = m_waveBsmStats->GetTxPktCount (); + if ((m_waveBsmStats->GetLogging () != 0) && ((wavePktsSent % 1000) == 0)) + { + NS_LOG_UNCOND ("Sending WAVE pkt # " << wavePktsSent ); + } + + // find other nodes within range that would be + // expected to receive this broadbast + int nRxNodes = m_adhocTxInterfaces->GetN (); + for (int i = 0; i < nRxNodes; i++) + { + Ptr rxNode = GetNode (i); + int rxNodeId = rxNode->GetId (); + + if (rxNodeId != txNodeId) + { + Ptr rxPosition = rxNode->GetObject (); + NS_ASSERT (rxPosition != 0); + // confirm that the receiving node + // has also started moving in the scenario + // if it has not started moving, then + // it is not a candidate to receive a packet + int receiverMoving = m_nodesMoving->at (rxNodeId); + if (receiverMoving == 1) + { + double distSq = MobilityHelper::GetDistanceSquaredBetween (txNode, rxNode); + if (distSq > 0.0) + { + // dest node within range? + int rangeCount = m_txSafetyRangesSq.size (); + for (int index = 1; index <= rangeCount; index++) + { + if (distSq <= m_txSafetyRangesSq[index - 1]) + { + // we should expect dest node to receive broadcast pkt + m_waveBsmStats->IncExpectedRxPktCount (index); + } + } + } + } + } + } + } + + // every BSM must be scheduled with a tx time delay + // of +/- (5) ms. See comments in StartApplication(). + // we handle this as a tx delay of [0..10] ms + // from the start of the pktInterval boundary + uint32_t d_ns = static_cast (m_txMaxDelay.GetInteger ()); + Time txDelay = NanoSeconds (m_unirv->GetInteger (0, d_ns)); + + // do not want the tx delay to be cumulative, so + // deduct the previous delay value. thus we adjust + // to schedule the next event at the next pktInterval, + // plus some new [0..10] ms tx delay + Time txTime = pktInterval - m_prevTxDelay + txDelay; + m_prevTxDelay = txDelay; + + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), + txTime, &BsmApplication::GenerateWaveTraffic, this, + socket, pktSize, pktCount - 1, pktInterval, socket->GetNode ()->GetId ()); + } + else + { + socket->Close (); + } +} + +void BsmApplication::ReceiveWavePacket (Ptr socket) +{ + NS_LOG_FUNCTION (this); + + Ptr packet; + while ((packet = socket->Recv ())) + { + Ptr rxNode = socket->GetNode (); + + SocketAddressTag tag; + bool found; + found = packet->PeekPacketTag (tag); + + if (found) + { + InetSocketAddress addr = InetSocketAddress::ConvertFrom (tag.GetAddress ()); + int nodes = m_adhocTxInterfaces->GetN (); + for (int i = 0; i < nodes; i++) + { + if (addr.GetIpv4 () == m_adhocTxInterfaces->GetAddress (i) ) + { + Ptr txNode = GetNode (i); + HandleReceivedBsmPacket (txNode, rxNode); + } + } + } + } +} + +void BsmApplication::HandleReceivedBsmPacket (Ptr txNode, + Ptr rxNode) +{ + NS_LOG_FUNCTION (this); + + m_waveBsmStats->IncRxPktCount (); + + Ptr rxPosition = rxNode->GetObject (); + NS_ASSERT (rxPosition != 0); + // confirm that the receiving node + // has also started moving in the scenario + // if it has not started moving, then + // it is not a candidate to receive a packet + int rxNodeId = rxNode->GetId (); + int receiverMoving = m_nodesMoving->at (rxNodeId); + if (receiverMoving == 1) + { + double rxDistSq = MobilityHelper::GetDistanceSquaredBetween (rxNode, txNode); + if (rxDistSq > 0.0) + { + int rangeCount = m_txSafetyRangesSq.size (); + for (int index = 1; index <= rangeCount; index++) + { + if (rxDistSq <= m_txSafetyRangesSq[index - 1]) + { + m_waveBsmStats->IncRxPktInRangeCount (index); + } + } + } + } +} + +int64_t +BsmApplication::AssignStreams (int64_t streamIndex) +{ + NS_LOG_FUNCTION (this); + + NS_ASSERT (m_unirv); // should be set by Setup() prevoiusly + m_unirv->SetStream (streamIndex); + + return 1; +} + +Ptr +BsmApplication::GetNode (int id) +{ + NS_LOG_FUNCTION (this); + + std::pair, uint32_t> interface = m_adhocTxInterfaces->Get (id); + Ptr pp = interface.first; + Ptr node = pp->GetObject (); + + return node; +} + +Ptr +BsmApplication::GetNetDevice (int id) +{ + NS_LOG_FUNCTION (this); + + std::pair, uint32_t> interface = m_adhocTxInterfaces->Get (id); + Ptr pp = interface.first; + Ptr device = pp->GetObject (); + + return device; +} + +} // namespace ns3 diff --git a/src/wave/model/bsm-application.h b/src/wave/model/bsm-application.h new file mode 100644 index 000000000..f57f5aebf --- /dev/null +++ b/src/wave/model/bsm-application.h @@ -0,0 +1,175 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2014 North Carolina State University + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Scott E. Carpenter + * + */ + +#ifndef BSM_APPLICATION_H +#define BSM_APPLICATION_H + +#include "ns3/application.h" +#include "ns3/wave-bsm-stats.h" +#include "ns3/random-variable-stream.h" +#include "ns3/internet-stack-helper.h" + +namespace ns3 { +/** + * \ingroup wave + * \brief The BsmApplication class sends and receives the + * IEEE 1609 WAVE (Wireless Access in Vehicular Environments) + * Basic Safety Messages (BSMs) and uses the WaveBsmStats class + * to manage statistics about BSMs transmitted and received + * The BSM is a ~200-byte packet that is + * generally broadcast from every vehicle at a nominal rate of 10 Hz. + */ +class BsmApplication : public Application +{ +public: + static TypeId GetTypeId (void); + + /** + * \brief Constructor + * \return none + */ + BsmApplication (); + virtual ~BsmApplication (); + + /** + * \brief Setup BSM generation parameters for a node + * \param i IPv4 interface container + * \param nodeId identifier of the node (index into container) + * \param totalTime total amount of time that BSM packets should be transmitted + * \param wavePacketSize the size, in bytes, of a WAVE BSM + * \param waveInterval the time, in seconds, between each WAVE BSM transmission, + * typically 10 Hz (0.1 second) + * \param gpsAccuracy the timing synchronization accuracy of GPS time, in seconds. + * GPS time-sync is ~40-100 ns. Universally synchronized time among all vehicles + * will result in all vehicles transmitting safety messages simultaneously, leading + * to excessive wireless collisions. + * \param range the expected transmission range, in m ^ 2. + * \param collection class for WAVE BSM statistics + * \param indicators of whether or not node(s) are moving + * \return none + */ + void Setup (Ipv4InterfaceContainer & i, + int nodeId, + Time totalTime, + uint32_t wavePacketSize, // bytes + Time waveInterval, + double gpsAccuracyNs, + std::vector rangesSq, // m ^ 2 + Ptr waveBsmStats, + std::vector * nodesMoving, + int mode, + Time txDelay); + + /** + * Assign a fixed random variable stream number to the random variables + * used by this model. Return the number of streams (possibly zero) that + * have been assigned. The Install() method should have previously been + * called by the user. + * + * \param stream first stream index to use + * \return the number of stream indices assigned by this helper + */ + int64_t AssignStreams (int64_t streamIndex); + + /** + * (Arbitrary) port number that is used to create a socket for transmitting WAVE BSMs. + */ + static int wavePort; + +protected: + virtual void DoDispose (void); + +private: + // inherited from Application base class. + virtual void StartApplication (void); // Called at time specified by Start + virtual void StopApplication (void); // Called at time specified by Stop + + /** + * \brief Creates and transmits a WAVE BSM packet + * \param socket socket to use for transmission + * \param pktSize the size, in bytes, of the WAVE BSM packet + * \param pktCount the number of remaining WAVE BSM packets to be transmitted + * \param pktInterval the interval, in seconds, until the next packet + * should be transmitted + * \return none + */ + void GenerateWaveTraffic (Ptr socket, uint32_t pktSize, + uint32_t pktCount, Time pktInterval, + uint32_t sendingNodeId); + + /** + * \brief Receive a WAVE BSM packet + * \param socket the receiving socket + * \return none + */ + void ReceiveWavePacket (Ptr socket); + + /** + * \brief Handle the receipt of a WAVE BSM packet from sender to receiver + * \param txNode the sending node + * \param rxNode the receiving node + * \return none + */ + void HandleReceivedBsmPacket (Ptr txNode, + Ptr rxNode); + + /** + * \brief Get the node for the desired id + * \param id the id of the desired node + * \return ptr to the desired node + */ + Ptr GetNode (int id); + + /** + * \brief Get the net device for the desired id + * \param id the id of the desired net device + * \return ptr to the desired net device + */ + Ptr GetNetDevice (int id); + + Ptr m_waveBsmStats; + // tx safety range squared, for optimization + std::vector m_txSafetyRangesSq; + Time m_TotalSimTime; + uint32_t m_wavePacketSize; // bytes + uint32_t m_numWavePackets; + Time m_waveInterval; + double m_gpsAccuracyNs; + Ipv4InterfaceContainer * m_adhocTxInterfaces; + std::vector * m_nodesMoving; + Ptr m_unirv; + int m_nodeId; + // WAVE channel access mode. 0=continuous PHY; 1=channel-switching + int m_chAccessMode; + // When transmitting at a default rate of 10 Hz, + // the subsystem shall transmit every 100 ms +/- + // a random value between 0 and 5 ms. [MPR-BSMTX-TXTIM-002] + // Source: CAMP Vehicle Safety Communications 4 Consortium + // On-board Minimum Performance Requirements + // for V2V Safety Systems Version 1.0, December 17, 2014 + // max transmit delay (default 10ms) + Time m_txMaxDelay; + Time m_prevTxDelay; +}; + +} // namespace ns3 + +#endif /* BSM_APPLICATION_H*/