NMPB08 shared libraries
CalculRoadEmission.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines