NMPB08 shared libraries
|
00001 00007 #include "../test_mem/safe_new.h" 00008 #include "CalculRoadEmission.h"cd . 00009 #include <stdio.h> 00010 00011 namespace CalculRoadEmissionNMPB 00012 { 00013 00014 // ------------------------------ Global variables and constants --------------------------------------- 00015 00019 const int ThirdOctaveFrequencies[] = {100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000}; 00023 const int OctaveFrequencies[] = {125, 250, 500, 1000, 2000, 4000}; 00027 const int AllFrequencies[] = {0}; 00028 00032 const int frequencyNumber = 18; 00036 //const int NominalMedianFrequency[] = {100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000}; 00037 //const int* NominalMedianFrequency = ThirdOctaveFrequencies ; 00038 #define NominalMedianFrequency ThirdOctaveFrequencies 00039 00042 const double spectralDistribution_draining[] = {-22, -22, -20, -17, -15, -12, -10, -8, -9, -9, -10, -11, -12, -13, -16, -18, -20, -23}; 00046 const double spectralDistribution_nonDraining[] = {-27, -26, -24, -21, -19, -16, -14, -11, -11, -8, -7, -8, -10, -13, -16, -18, -21, -23}; 00050 const double spectralFilterA[] = {-19.1, -16.1, -13.4, -10.9, -8.6, -6.6, -4.8, -3.2, -1.9, -0.8, 0.0, 0.6, 1.0, 1.2, 1.3, 1.2, 1.0, 0.5}; 00051 00052 00056 map<int,RoadSurfaceDescription> RoadSurfaceDescriptionMap; 00057 00058 00059 // ---------------------------- Road surface definition --------------------------- 00060 00082 bool DefineRoadSurfaceType(int idRoadSurface, 00083 double AVL, double BVL, double Vref_VL, 00084 double APL, double BPL, double Vref_PL, 00085 double const* spectrum) 00086 { 00087 if(idRoadSurface < RoadSurface_UserDefined) 00088 { 00089 printf (".ERROR: definition of road surface type with idRoadSurface < RoadSurface_UserDefined \n") ; 00090 return false; 00091 } 00092 00093 double const* spectrumToUse; 00094 bool doNormalization = true; 00095 if(spectrum == NULL) 00096 { 00097 spectrumToUse = spectralDistribution_nonDraining; 00098 doNormalization = false; 00099 } 00100 else 00101 { 00102 spectrumToUse = spectrum; 00103 } 00104 00105 RoadSurfaceDescription roadSurfDesc(AVL, BVL, Vref_VL, APL, BPL, Vref_PL, spectrumToUse, doNormalization); 00106 RoadSurfaceDescriptionMap[idRoadSurface] = roadSurfDesc; 00107 return true; 00108 } 00109 00110 00111 // ------------------------------ CalculRoadEmission Class --------------------------------------- 00112 00118 void CalculRoadEmission::FillRoadSurfaceDescriptionMap(RoadSurfaceType surfType) 00119 { 00120 if(surfType < RoadSurface_UserDefined && RoadSurfaceDescriptionMap.find(static_cast<int>(surfType)) == RoadSurfaceDescriptionMap.end()) 00121 { 00122 double AVL = 0; 00123 double BVL = 0; 00124 double Vref_VL = 90; 00125 double APL = 0; 00126 double BPL = 0; 00127 double Vref_PL = 80; 00128 const double* spectrum = spectralDistribution_nonDraining; 00129 00130 // data from array 2.6 p.21 - § 2.7.2.2 00131 switch(surfType) 00132 { 00133 case RoadSurface_R1: 00134 case RoadSurface_DR1: 00135 AVL = 21.0; 00136 BVL = 53.4; 00137 APL = 20.0; 00138 BPL = 61.5; 00139 break; 00140 /* 00141 AVL = 20.1; 00142 BVL = 55.4; 00143 APL = 20.0; 00144 BPL = 63.4; 00145 break; 00146 */ 00147 case RoadSurface_R3: 00148 case RoadSurface_DR3: 00149 AVL = 21.4; 00150 BVL = 57.5; 00151 APL = 20.0; 00152 BPL = 64.2; 00153 break; 00154 case RoadSurface_R2: 00155 case RoadSurface_DR2: 00156 default: 00157 // like R2 00158 AVL = 20.1; 00159 BVL = 55.4; 00160 APL = 20.0; 00161 BPL = 63.4; 00162 break; 00163 } 00164 00165 if(surfType == RoadSurface_DR1 || surfType == RoadSurface_DR2 || surfType == RoadSurface_DR3) 00166 { 00167 spectrum = spectralDistribution_draining; 00168 } 00169 00170 RoadSurfaceDescription roadSurfDesc(AVL, BVL, Vref_VL, APL, BPL, Vref_PL, spectrum, false); 00171 RoadSurfaceDescriptionMap[surfType] = roadSurfDesc; 00172 } 00173 } 00174 00180 void CalculRoadEmission::FillLinearCorrectionMap() 00181 { 00182 _linearCorrection.clear(); 00183 for(int i = 0; i < frequencyNumber ; i++) 00184 { 00185 // Modification 00186 // DVM 18/11/2011 00187 // Correction for removing dB(A) filtering is equal to minus the value of the filter 00188 // _linearCorrection[NominalMedianFrequency[i]] = spectralFilterA[i]; 00189 _linearCorrection[NominalMedianFrequency[i]] = -spectralFilterA[i]; 00190 } 00191 } 00192 00202 double* CalculRoadEmission::SpectralDistribution(double powerValue, RoadSurfaceType surfaceType) 00203 { 00204 double* specResults = _Lw_band ; 00205 00206 for(int i = 0 ; i < _bandsNumber ; i++) 00207 { 00208 double valToAdd = 0; 00209 00210 // spectral distribution : 00211 if(RoadSurfaceDescriptionMap.find(surfaceType) != RoadSurfaceDescriptionMap.end()) 00212 { 00213 RoadSurfaceDescription roadSurfDesc = RoadSurfaceDescriptionMap[surfaceType]; 00214 map<int,double> specDistrMap = roadSurfDesc.get_spectralDistributionMap(); 00215 if(specDistrMap.find(_usedFrequencies[i])!= specDistrMap.end()) 00216 { 00217 valToAdd = specDistrMap[_usedFrequencies[i]]; 00218 } 00219 } 00220 00221 // linear correction : 00222 if(!_specA && _linearCorrection.find(_usedFrequencies[i]) != _linearCorrection.end()) 00223 { 00224 valToAdd += _linearCorrection[_usedFrequencies[i]]; 00225 } 00226 00227 specResults[i] = powerValue + valToAdd; 00228 } 00229 00230 return specResults; 00231 } 00232 00233 00237 CalculRoadEmission::CalculRoadEmission(void) 00238 { 00239 _Lw_VL = 0; 00240 _Lw_PL = 0; 00241 _QVL = 0; 00242 _QPL = 0; 00243 _Lw_rolling_VL = 0; 00244 _Lw_rolling_PL = 0; 00245 _Lw_traction_VL = 0; 00246 _Lw_traction_PL = 0; 00247 00248 // if SpectrumType non specified, third octave band by default 00249 _bandsNumber = 18; 00250 _Lw_band = 0 ; 00251 _usedFrequencies = ThirdOctaveFrequencies; 00252 _specA = true; 00253 FillLinearCorrectionMap(); 00254 } 00255 00263 CalculRoadEmission::CalculRoadEmission(RoadSpectrumType specType, RoadSurfaceType surfType) 00264 { 00265 _Lw_VL = 0; 00266 _Lw_PL = 0; 00267 _QVL = 0; 00268 _QPL = 0; 00269 _Lw_rolling_VL = 0; 00270 _Lw_rolling_PL = 0; 00271 _Lw_traction_VL = 0; 00272 _Lw_traction_PL = 0; 00273 00274 _bandsNumber = 0; 00275 switch(specType) 00276 { 00277 case Spectrum_dBA: 00278 _bandsNumber = 1; 00279 _specA = true; 00280 _usedFrequencies = AllFrequencies; 00281 break; 00282 case Spectrum_oct_A: 00283 _bandsNumber = 6; 00284 _specA = true; 00285 _usedFrequencies = OctaveFrequencies; 00286 break; 00287 case Spectrum_3oct_A: 00288 _bandsNumber = 18; 00289 _specA = true; 00290 _usedFrequencies = ThirdOctaveFrequencies; 00291 break; 00292 case Spectrum_oct_lin: 00293 _bandsNumber = 6; 00294 _specA = false; 00295 _usedFrequencies = OctaveFrequencies; 00296 break; 00297 case Spectrum_3oct_lin: 00298 _bandsNumber = 18; 00299 _specA = false; 00300 _usedFrequencies = ThirdOctaveFrequencies; 00301 break; 00302 default: 00303 _bandsNumber = 18; 00304 _specA = true; 00305 _usedFrequencies = ThirdOctaveFrequencies; 00306 break; 00307 } 00308 00309 _Lw_band = 0 ; 00310 00311 FillRoadSurfaceDescriptionMap(surfType); 00312 FillLinearCorrectionMap(); 00313 } 00314 00322 double* CalculRoadEmission::SoundPowerLevelPerMeter (RoadTraffic* roadTraffic) 00323 { 00324 if(roadTraffic == NULL) 00325 { 00326 printf("Erreur : le composant RoadTraffic est nul \n"); 00327 return 0; 00328 } 00329 00330 double Lw_total = 0 ; 00331 for(int i = 0 ; i < roadTraffic->nbComponents ; i++) 00332 { 00333 RoadTrafficComponent rtComponent = roadTraffic->traffic[i]; 00334 if (rtComponent.vehicleType == VehicleType_VL) 00335 { 00336 switch (rtComponent.flowType) 00337 { 00338 case FlowType_CONST : 00339 case FlowType_ACC : 00340 case FlowType_DEC : 00341 { 00342 _Lw_rolling_VL = Lw_rolling_VL (rtComponent.trafficSpeed, 00343 roadTraffic->surfaceType, 00344 roadTraffic->surfaceAge); 00345 _Lw_traction_VL = Lw_traction_VL (rtComponent.trafficSpeed, 00346 rtComponent.flowType); 00347 // § 2.7.1.1, formula (19), p. 19 : 00348 _Lw_VL = EnergeticAddition(_Lw_rolling_VL, _Lw_traction_VL); 00349 break ; 00350 } 00351 case FlowType_START : 00352 case FlowType_STOP : 00353 { 00354 _Lw_VL = Lw_startStop (rtComponent.vehicleType, 00355 roadTraffic->ramp, 00356 rtComponent.flowType, 00357 roadTraffic->surfaceAge); 00358 FillRollingAndTractionFromStartStop(_Lw_VL, rtComponent.vehicleType); 00359 break ; 00360 } 00361 default: 00362 printf ("ERREUR : FlowType inconnu \n") ; 00363 return 0 ; 00364 } 00365 _QVL = rtComponent.trafficFlow; 00366 Lw_total += _QVL * pow (10., _Lw_VL / 10.) ; 00367 } 00368 else if (rtComponent.vehicleType == VehicleType_PL) 00369 { 00370 switch (rtComponent.flowType) 00371 { 00372 case FlowType_CONST : 00373 case FlowType_ACC : 00374 case FlowType_DEC : 00375 { 00376 _Lw_rolling_PL = Lw_rolling_PL (rtComponent.trafficSpeed, 00377 roadTraffic->surfaceType, 00378 roadTraffic->surfaceAge); 00379 _Lw_traction_PL = Lw_traction_PL (rtComponent.trafficSpeed, 00380 rtComponent.flowType, 00381 roadTraffic->ramp); 00382 // § 2.7.1.1, formula (19), p. 19 : 00383 _Lw_PL = EnergeticAddition(_Lw_rolling_PL, _Lw_traction_PL); 00384 break ; 00385 } 00386 case FlowType_START : 00387 case FlowType_STOP : 00388 { 00389 _Lw_PL = Lw_startStop (rtComponent.vehicleType, 00390 roadTraffic->ramp, 00391 rtComponent.flowType, 00392 roadTraffic->surfaceAge); 00393 FillRollingAndTractionFromStartStop(_Lw_PL, rtComponent.vehicleType); 00394 break ; 00395 } 00396 default: 00397 printf ("ERREUR : FlowType inconnu \n") ; 00398 return 0 ; 00399 } 00400 _QPL = rtComponent.trafficFlow; 00401 Lw_total += _QPL * pow (10., _Lw_PL / 10.) ; 00402 } 00403 } 00404 00405 // sum on vehicles : 00406 // double Lw = LwTotal(_Lw_VL, _QVL, _Lw_PL, _QPL); 00407 double Lw = (Lw_total > 0) ? 10. * log10(Lw_total) : 0.0 ; 00408 00409 // by frequency bands : 00410 _Lw_band = roadTraffic->_Lw_values ; 00411 return SpectralDistribution(Lw, roadTraffic->surfaceType); 00412 } 00413 00429 double CalculRoadEmission::Lw_startStop (RoadVehicleType vtype, 00430 double ramp, 00431 RoadFlowType flowType, 00432 double surfaceAge) 00433 { 00434 double lwStartStop_new = 0 ; 00435 double lwStartStop_old = 0 ; 00436 00437 // linear interpolation as a function of surface age 00438 // weight = 1 if age < 2 00439 // weight = 0 if age > 10 00440 00441 double weightAge = 1 ; 00442 if (surfaceAge > 10) 00443 weightAge = 0 ; 00444 else if (surfaceAge > 2) 00445 weightAge = (10 - surfaceAge) / 8 ; 00446 00447 if (vtype == VehicleType_VL) 00448 { 00449 if (flowType == FlowType_START) 00450 { 00451 lwStartStop_new = 51.1 ; 00452 lwStartStop_old = 51.3 ; 00453 } 00454 else 00455 { 00456 lwStartStop_new = 44.5 ; 00457 lwStartStop_old = 45.1; 00458 } 00459 } 00460 else 00461 { 00462 // (vtype == VehicleType_PL) 00463 00464 if (flowType == FlowType_START) 00465 { 00466 lwStartStop_new = 62.4 ; 00467 lwStartStop_old = 62.5; 00468 00469 if (ramp > 4.5 && ramp <= 6) 00470 { 00471 lwStartStop_new += 2 * (ramp - 4.5); 00472 lwStartStop_old += 2 * (ramp - 4.5); 00473 } 00474 } 00475 else 00476 { 00477 // (flowType == FlowType_STOP) 00478 00479 lwStartStop_new = 58.0 ; 00480 lwStartStop_old = 58.3 ; 00481 00482 if(ramp >= -6 && ramp <= -2) 00483 { 00484 lwStartStop_new += (ramp + 2) ; // ramp < 0 ! 00485 lwStartStop_old += (ramp + 2) ; // ramp < 0 ! 00486 } 00487 } 00488 } 00489 00490 double lwStartStop = weightAge * lwStartStop_new + (1 - weightAge) * lwStartStop_old ; 00491 00492 return lwStartStop; 00493 } 00494 00502 void CalculRoadEmission::FillRollingAndTractionFromStartStop (double lwStartStop, 00503 RoadVehicleType vtype) 00504 { 00505 // assume Lw is divided in 2 equal parts (rolling and traction), so : 00506 // _Lw_rolling = _Lw_traction = lwStartStop - 10 * log(2) 00507 double meanLw = lwStartStop - 10 * log10(2.); 00508 if(vtype == VehicleType_VL) 00509 { 00510 _Lw_rolling_VL = meanLw; 00511 _Lw_traction_VL = meanLw; 00512 } 00513 else 00514 { 00515 _Lw_rolling_PL = meanLw; 00516 _Lw_traction_PL = meanLw; 00517 } 00518 } 00519 00535 double CalculRoadEmission::LwTotal(double LwVL, double QVL, double LwPL, double QPL) 00536 { 00537 double WVL = QVL * pow (10., LwVL/10) ; 00538 double WPL = QPL * pow (10., LwPL/10) ; 00539 double WTot = WVL + WPL ; 00540 double Lw = (WTot > 0) ? 10 * log10(WTot) : 0.0 ; 00541 return Lw; 00542 } 00543 00555 double CalculRoadEmission::EnergeticAddition(double val1, double val2) 00556 { 00557 return 10.0 * log10(pow(10.,val1 / 10.) + pow(10.,val2 / 10.)); 00558 } 00559 00560 00561 // ---------------------------- Rolling component --------------------------- 00562 00570 double* CalculRoadEmission::Lwm_rolling (RoadTraffic* roadTraffic) 00571 { 00572 if(roadTraffic == NULL) 00573 { 00574 printf("Erreur : le composant RoadTraffic est nul \n"); 00575 return 0; 00576 } 00577 00578 for(int i = 0 ; i < roadTraffic->nbComponents ; i++) 00579 { 00580 RoadTrafficComponent rtComponent = roadTraffic->traffic[i]; 00581 if (rtComponent.vehicleType == VehicleType_VL) 00582 { 00583 if(rtComponent.flowType != FlowType_START && rtComponent.flowType != FlowType_STOP) 00584 { 00585 _Lw_rolling_VL = Lw_rolling_VL (rtComponent.trafficSpeed, roadTraffic->surfaceType, roadTraffic->surfaceAge); 00586 } 00587 else 00588 { 00589 double lw = Lw_startStop(rtComponent.vehicleType, roadTraffic->ramp, rtComponent.flowType, roadTraffic->surfaceAge); 00590 FillRollingAndTractionFromStartStop(lw, rtComponent.vehicleType); 00591 } 00592 00593 _QVL = rtComponent.trafficFlow; 00594 } 00595 else if (rtComponent.vehicleType == VehicleType_PL) 00596 { 00597 if(rtComponent.flowType != FlowType_START && rtComponent.flowType != FlowType_STOP) 00598 { 00599 _Lw_rolling_PL = Lw_rolling_PL (rtComponent.trafficSpeed, roadTraffic->surfaceType, roadTraffic->surfaceAge); 00600 } 00601 else 00602 { 00603 double lw = Lw_startStop(rtComponent.vehicleType, roadTraffic->ramp, rtComponent.flowType, roadTraffic->surfaceAge); 00604 FillRollingAndTractionFromStartStop(lw, rtComponent.vehicleType); 00605 } 00606 00607 _QPL = rtComponent.trafficFlow; 00608 } 00609 } 00610 00611 // sum on vehicles : 00612 double Lw = LwTotal(_Lw_rolling_VL, _QVL, _Lw_rolling_PL, _QPL); 00613 00614 // by frequency bands : 00615 //static double* Lw_rolling_band = SpectralDistribution(Lw, roadTraffic->surfaceType); 00616 //return Lw_rolling_band; 00617 00618 // by frequency bands : 00619 _Lw_band = roadTraffic->_Lw_values ; 00620 return SpectralDistribution(Lw, roadTraffic->surfaceType); 00621 } 00622 00636 double* CalculRoadEmission::Lw_rolling (RoadVehicleType vtype, 00637 double vehicleSpeed, 00638 RoadSurfaceType surfaceType, 00639 double surfaceAge) 00640 { 00641 double Lr_w_veh = 0; 00642 switch(vtype) 00643 { 00644 case VehicleType_VL : 00645 Lr_w_veh = Lw_rolling_VL(vehicleSpeed, surfaceType, surfaceAge); 00646 _Lw_rolling_VL = Lr_w_veh; 00647 break; 00648 case VehicleType_PL: 00649 Lr_w_veh = Lw_rolling_PL(vehicleSpeed, surfaceType, surfaceAge); 00650 _Lw_rolling_PL = Lr_w_veh; 00651 break; 00652 default: 00653 Lr_w_veh = 0; 00654 printf("Erreur lors du calcul de la composante roulement : type de vehicule non reconnu \n"); 00655 break; 00656 } 00657 00658 // Annexe 4, p.113 00659 Lr_w_veh = Lr_w_veh - 10 * log10(vehicleSpeed) - 30; 00660 00661 //static double* lw_rolling = SpectralDistribution(Lr_w_veh, surfaceType); 00662 //return lw_rolling; 00663 _Lw_band = _output_values ; 00664 return SpectralDistribution(Lr_w_veh, surfaceType); 00665 } 00666 00680 double CalculRoadEmission::Lw_rolling_VL (double vehicleSpeed, RoadSurfaceType surfaceType, double surfaceAge) 00681 { 00682 if(vehicleSpeed < 20 || vehicleSpeed > 130) 00683 { 00684 printf("Erreur lors du calcul de la composante roulement : la vitesse %.2f, utilisee pour un vehicule leger, n'est pas comprise entre 20 et 130 km/h \n", vehicleSpeed); 00685 return 0; 00686 } 00687 00688 double Lr_w_veh = 0; 00689 00690 // § 2.7.2.2, array (2.6) p. 21 00691 RoadSurfaceDescription roadSurfdescr = RoadSurfaceDescriptionMap[surfaceType]; 00692 double Vref = 90; 00693 if(roadSurfdescr.get_Vref_VL() != 0) Vref = roadSurfdescr.get_Vref_VL(); 00694 Lr_w_veh = roadSurfdescr.get_BVL() + roadSurfdescr.get_AVL() * log10(vehicleSpeed / Vref); 00695 00696 // Age for R1, R2 or R3 : § 2.7.2.3, array (2.8) p. 22 00697 switch(surfaceType) 00698 { 00699 case RoadSurface_R1: 00700 case RoadSurface_DR1: 00701 if (surfaceAge <= 2) 00702 { 00703 Lr_w_veh += -4; 00704 } 00705 else if(surfaceAge <= 10) 00706 { 00707 Lr_w_veh += 0.5 * (surfaceAge - 10); 00708 } 00709 break; 00710 00711 case RoadSurface_R2: 00712 case RoadSurface_DR2: 00713 if (surfaceAge <= 2) 00714 { 00715 Lr_w_veh += -2; 00716 } 00717 else if(surfaceAge <= 10) 00718 { 00719 Lr_w_veh += 0.25 * (surfaceAge - 10); 00720 } 00721 break; 00722 00723 case RoadSurface_R3: 00724 case RoadSurface_DR3: 00725 if (surfaceAge <= 2) 00726 { 00727 Lr_w_veh += -1.6; 00728 } 00729 else if(surfaceAge <= 10) 00730 { 00731 Lr_w_veh += 0.2 * (surfaceAge - 10); 00732 } 00733 break; 00734 00739 default: 00740 break; 00741 } 00742 00743 return Lr_w_veh; 00744 } 00745 00759 double CalculRoadEmission::Lw_rolling_PL (double vehicleSpeed, RoadSurfaceType surfaceType, double surfaceAge) 00760 { 00761 if(vehicleSpeed < 20 || vehicleSpeed > 100) 00762 { 00763 printf("Erreur lors du calcul de la composante roulement : la vitesse %.2f, utilisee pour un poids lourd, n'est pas comprise entre 20 et 100 km/h \n", vehicleSpeed); 00764 return 0; 00765 } 00766 00767 double Lr_w_veh = 0; 00768 00769 // § 2.7.2.2, array (2.6) p. 21 00770 RoadSurfaceDescription roadSurfdescr = RoadSurfaceDescriptionMap[surfaceType]; 00771 double Vref = 80; 00772 if(roadSurfdescr.get_Vref_PL() != 0) Vref = roadSurfdescr.get_Vref_PL(); 00773 Lr_w_veh = roadSurfdescr.get_BPL() + roadSurfdescr.get_APL() * log10(vehicleSpeed / Vref); 00774 00775 // Age for R1, R2 or R3 : § 2.7.2.3, array (2.8) p. 22 00776 switch(surfaceType) 00777 { 00778 case RoadSurface_R1: 00779 case RoadSurface_DR1: 00780 if (surfaceAge <= 2) 00781 { 00782 Lr_w_veh += -2.4; 00783 } 00784 else if(surfaceAge <= 10) 00785 { 00786 Lr_w_veh += 0.3 * (surfaceAge - 10); 00787 } 00788 break; 00789 00790 case RoadSurface_R2: 00791 case RoadSurface_DR2: 00792 if (surfaceAge <= 2) 00793 { 00794 Lr_w_veh += -1.2; 00795 } 00796 else if(surfaceAge <= 10) 00797 { 00798 Lr_w_veh += 0.15 * (surfaceAge - 10); 00799 } 00800 break; 00801 00802 case RoadSurface_R3: 00803 case RoadSurface_DR3: 00805 if (surfaceAge <= 2) 00806 { 00807 Lr_w_veh += -1.; 00808 } 00809 else if(surfaceAge <= 10) 00810 { 00811 Lr_w_veh += 0.12 * (surfaceAge - 10); 00812 } 00813 00819 break; 00820 default: 00821 break; 00822 } 00823 00824 return Lr_w_veh; 00825 } 00826 00827 00828 // ---------------------------- Traction component --------------------------- 00829 00837 double* CalculRoadEmission::Lwm_traction (RoadTraffic* roadTraffic) 00838 { 00839 if(roadTraffic == NULL) 00840 { 00841 printf("Erreur : le composant RoadTraffic est nul \n"); 00842 return 0; 00843 } 00844 00845 for(int i = 0 ; i < roadTraffic->nbComponents ; i++) 00846 { 00847 RoadTrafficComponent rtComponent = roadTraffic->traffic[i]; 00848 if (rtComponent.vehicleType == VehicleType_VL) 00849 { 00850 if(rtComponent.flowType != FlowType_START && rtComponent.flowType != FlowType_STOP) 00851 { 00852 _Lw_traction_VL = Lw_traction_VL(rtComponent.trafficSpeed, rtComponent.flowType); 00853 } 00854 else 00855 { 00856 double lw = Lw_startStop(rtComponent.vehicleType, roadTraffic->ramp, rtComponent.flowType, roadTraffic->surfaceAge); 00857 FillRollingAndTractionFromStartStop(lw, rtComponent.vehicleType); 00858 } 00859 00860 _QVL = rtComponent.trafficFlow; 00861 } 00862 else if (rtComponent.vehicleType == VehicleType_PL) 00863 { 00864 if(rtComponent.flowType != FlowType_START && rtComponent.flowType != FlowType_STOP) 00865 { 00866 _Lw_traction_PL = Lw_traction_PL(rtComponent.trafficSpeed, rtComponent.flowType, roadTraffic->ramp); 00867 } 00868 else 00869 { 00870 double lw = Lw_startStop(rtComponent.vehicleType, roadTraffic->ramp, rtComponent.flowType, roadTraffic->surfaceAge); 00871 FillRollingAndTractionFromStartStop(lw, rtComponent.vehicleType); 00872 } 00873 00874 _QPL = rtComponent.trafficFlow; 00875 } 00876 } 00877 00878 // sum on vehicles : 00879 double Lw = LwTotal(_Lw_traction_VL, _QVL, _Lw_traction_PL, _QPL); 00880 00881 // by frequency bands : 00882 //static double* Lw_traction_band = SpectralDistribution(Lw, roadTraffic->surfaceType); 00883 //return Lw_traction_band; 00884 00885 // by frequency bands : 00886 _Lw_band = roadTraffic->_Lw_values ; 00887 return SpectralDistribution(Lw, roadTraffic->surfaceType); 00888 } 00889 00903 double* CalculRoadEmission::Lw_traction (RoadVehicleType vtype, 00904 double vehicleSpeed, 00905 RoadFlowType flowType, 00906 double ramp) 00907 { 00908 double Lm_w_veh = 0; 00909 switch(vtype) 00910 { 00911 case VehicleType_VL : 00912 Lm_w_veh = Lw_traction_VL(vehicleSpeed, flowType); 00913 _Lw_traction_VL = Lm_w_veh; 00914 break; 00915 case VehicleType_PL: 00916 Lm_w_veh = Lw_traction_PL(vehicleSpeed, flowType, ramp); 00917 _Lw_traction_PL = Lm_w_veh; 00918 break; 00919 default: 00920 Lm_w_veh = 0; 00921 printf("Erreur lors du calcul de la composante moteur : type de vehicule non reconnu \n"); 00922 break; 00923 } 00924 00925 // Annexe 4, p.113 00926 Lm_w_veh = Lm_w_veh - 10 * log10(vehicleSpeed) - 30; 00927 00928 // road surface chosen is RoadSurface_R3 because it has been decided to take non draining road 00929 00930 //static double* lw_traction = SpectralDistribution(Lm_w_veh, RoadSurface_R3); 00931 //return lw_traction; 00932 00933 _Lw_band = _output_values ; 00934 return SpectralDistribution(Lm_w_veh, RoadSurface_R3); 00935 } 00936 00946 double CalculRoadEmission::Lw_traction_VL (double vehicleSpeed, 00947 RoadFlowType flowType) 00948 { 00949 if(vehicleSpeed < 20 || vehicleSpeed > 130) 00950 { 00951 printf("Erreur lors du calcul de la composante moteur : la vitesse %.2f, utilisee pour un vehicule leger, n'est pas comprise entre 20 et 130 km/h \n", vehicleSpeed); 00952 return 0; 00953 } 00954 00955 double Lm_w_veh = 0; 00956 00957 // § 2.7.3 p. 23-25 00958 switch(flowType) 00959 { 00960 case FlowType_CONST: 00961 // § 2.7.3.1, array (2.9) p. 23 00962 if (vehicleSpeed <= 30) 00963 { 00964 Lm_w_veh = 36.7 - 10. * log10(vehicleSpeed / 90.); 00965 } 00966 else if(vehicleSpeed <= 110) 00967 { 00968 Lm_w_veh = 42.4 + 2. * log10(vehicleSpeed / 90.); 00969 } 00970 else 00971 { 00972 Lm_w_veh = 40.7 + 21.3 * log10(vehicleSpeed / 90.); 00973 } 00974 break; 00975 00976 case FlowType_ACC: 00977 // § 2.7.3.2, array (2.11) p. 24 00978 if (vehicleSpeed < 25) 00979 { 00980 printf("Erreur lors du calcul de la composante moteur : la vitesse %.2f, utilisee en acceleration, est inferieure a 25 km/h \n", vehicleSpeed); 00981 return 0; 00982 } 00983 else if (vehicleSpeed <= 100) 00984 { 00985 Lm_w_veh = 46.1 - 10. * log10(vehicleSpeed / 90.); 00986 } 00987 else 00988 { 00989 Lm_w_veh = 44.3 + 28.6 * log10(vehicleSpeed / 90.); 00990 } 00991 break; 00992 00993 case FlowType_DEC: 00994 // § 2.7.3.3, array (2.13) p. 25 00995 if (vehicleSpeed < 25) 00996 { 00997 printf("Erreur lors du calcul de la composante moteur : la vitesse %.2f, utilisee en deceleration, est inferieure a 25 km/h \n", vehicleSpeed); 00998 return 0; 00999 } 01000 else if (vehicleSpeed <= 80) 01001 { 01002 Lm_w_veh = 42.1 - 4.5 * log10(vehicleSpeed / 90.); 01003 } 01004 else if(vehicleSpeed <= 110) 01005 { 01006 Lm_w_veh = 42.4 + 2. * log10(vehicleSpeed / 90.); 01007 } 01008 else 01009 { 01010 Lm_w_veh = 40.7 + 21.3 * log10(vehicleSpeed / 90.); 01011 } 01012 break; 01013 01014 default: 01015 Lm_w_veh = 0; 01016 break; 01017 } 01018 01019 return Lm_w_veh; 01020 } 01021 01033 double CalculRoadEmission::Lw_traction_PL (double vehicleSpeed, 01034 RoadFlowType flowType, double ramp) 01035 { 01036 if(vehicleSpeed < 20 || vehicleSpeed > 100) 01037 { 01038 printf("Erreur lors du calcul de la composante moteur : la vitesse %.2f, utilisee pour un poids lourd, n'est pas comprise entre 20 et 100 km/h \n", vehicleSpeed); 01039 return 0; 01040 } 01041 01042 // § 2.7.3.4, array (2.15) p. 26 01043 double Lm_w_veh = 0; 01044 if (vehicleSpeed <= 70) 01045 { 01046 Lm_w_veh = 49.6 - 10. * log10(vehicleSpeed / 80.); 01047 } 01048 else 01049 { 01050 Lm_w_veh = 50.4 + 3. * log10(vehicleSpeed / 80.); 01051 } 01052 01053 // § 2.7.3.4, array (2.16) p. 26 01054 double deltaLm = 0; 01055 switch(flowType) 01056 { 01057 case FlowType_CONST: 01058 if (ramp >= -2 && ramp <= 2) 01059 { 01060 deltaLm = 0.; 01061 } 01062 else if(ramp >= 2 && ramp <= 6) 01063 { 01064 deltaLm = 2. * (ramp - 2.); 01065 } 01066 else if(ramp >= -6 && ramp <= -2) 01067 { 01068 deltaLm = (-1.0 * ramp) - 2.; // (-1 * ramp) because ramp < 0 01069 } 01070 break; 01071 01072 case FlowType_ACC: 01073 deltaLm = 5.; 01074 if(ramp > 4.5 && ramp <= 6) 01075 { 01076 deltaLm += 2. * (ramp - 4.5); 01077 } 01078 break; 01079 01080 case FlowType_DEC: 01081 deltaLm = 0.; 01082 if(ramp >= -6 && ramp <= -2) 01083 { 01084 deltaLm = (-1.0 * ramp) - 2.; // (-1 * ramp) because ramp < 0 01085 } 01086 break; 01087 01088 default: 01089 deltaLm = 0; 01090 break; 01091 } 01092 01093 Lm_w_veh += deltaLm; 01094 return Lm_w_veh; 01095 } 01096 01097 }