00001
00002
00004
00005 #include "stdafx.h"
00006 #include "Vehicle.h"
00007
00008 #include "ConfigData.h"
00009 extern CConfigData g_ConfigData;
00010
00012 Vehicle::Vehicle()
00013 {
00014 ROAD_END_BUFFER = g_ConfigData.Road.ROAD_END_BUFFER;
00015
00016 T_DELAY = g_ConfigData.IDM.T_DELAY;
00017 MIN_SPACE_FOR_NEXT_VEHICLE = g_ConfigData.IDM.MIN_SPACE_FOR_NEXT_VEHICLE;
00018 SAFE_BRAKING = g_ConfigData.IDM.SAFE_BRAKING;
00019
00020 CRANE_AVERAGE_SPACING = g_ConfigData.VehicleID.CRANE_AVERAGE_SPACING;
00021 CRANE_MAX_SPACING = g_ConfigData.VehicleID.CRANE_MAX_SPACING;
00022 LOWLOADER_MIN_MAX_SPACING = g_ConfigData.VehicleID.LOWLOADER_MIN_MAX_SPACING;
00023 SMALL_TRUCK_NO_AXLES = g_ConfigData.VehicleID.SMALL_TRUCK_NO_AXLES;
00024
00025 DAYS_PER_MT = g_ConfigData.Time.DAYS_PER_MT;
00026 MTS_PER_YR = g_ConfigData.Time.MTS_PER_YR;
00027 }
00028
00030 Vehicle::~Vehicle()
00031 {
00032
00033 }
00034
00038
00049 void Vehicle::update(double step)
00050 {
00051 if( changeTime(step) )
00052 setChangeStatus(true);
00053
00054 double accel = calcAccel();
00055
00056 updateProperties(step, accel);
00057 }
00058
00070 void Vehicle::update(double step, Vehicle *pV)
00071 {
00072 bool change = changeTime(step);
00073
00074 if(change)
00075 setChangeStatus(true);
00076
00077 double accel = calcAccel(pV);
00078
00079 updateProperties(step, accel);
00080 }
00081
00088 double Vehicle::calcAccel()
00089 {
00090 m_pDriver->setVel(m_Velocity);
00091
00092
00093 double accel = m_pDriver->update(m_Velocity, (m_RoadLength + ROAD_END_BUFFER) - m_Position);
00094
00095 return accel;
00096 }
00097
00106 double Vehicle::calcAccel(Vehicle *pV)
00107 {
00108 m_pDriver->setVel(m_Velocity);
00109
00110 double s = pV->getPos() - pV->getLength() - m_Position;
00111
00112 double delta_v = m_Velocity - pV->getVelocity();
00113 double accel = m_pDriver->update(delta_v, s);
00114
00115 return accel;
00116 }
00117
00127 void Vehicle::updateProperties(double step, double accel)
00128 {
00129
00130 double v_old = m_Velocity;
00131 double v_new = m_Velocity + accel*step;
00132
00133
00134
00135 if(v_new < 0)
00136 {
00137
00138 v_new = 0.0;
00139 }
00140
00141 m_Position += 0.5*(v_old + v_new)*step;
00142
00143 m_RoadPosition = m_Position;
00144 m_Velocity = v_new;
00145
00146 m_Acceleration = accel;
00147 }
00148
00154 bool Vehicle::changeTime(double step)
00155 {
00156 m_Tdelay += step;
00157
00158 if (m_Tdelay >= T_DELAY)
00159 {
00160 m_Tdelay = m_Tdelay - T_DELAY;
00161 return true;
00162 }
00163 else {return false;}
00164 }
00165
00169 DriverModel* Vehicle::getDriver()
00170 {
00171 return m_pDriver;
00172 }
00173
00177 void Vehicle::setDriver(IDM driver)
00178 {
00179 m_IDMDriver = driver;
00180 m_pDriver = &m_IDMDriver;
00181 }
00182
00186
00204 int Vehicle::DecideLaneChange( Vehicle* LeftFrontVehicle, Vehicle* LeftBackVehicle,
00205 Vehicle* RightFrontVehicle, Vehicle* RightBackVehicle,
00206 bool LeftLaneExists, bool RightLaneExists)
00207 {
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 double LeftLaneAdvantage = 0.0; double RightLaneAdvantage = 0.0;
00220
00221 if(m_DriveOnRight)
00222 {
00223 if(LeftLaneExists)
00224 LeftLaneAdvantage = LaneChangeAdvantage(LeftFrontVehicle, LeftBackVehicle, true);
00225
00226 if(RightLaneExists)
00227 RightLaneAdvantage = LaneChangeAdvantage(RightFrontVehicle, RightBackVehicle, false);
00228 }
00229 else
00230 {
00231 if(LeftLaneExists)
00232 LeftLaneAdvantage = LaneChangeAdvantage(LeftFrontVehicle, LeftBackVehicle, false);
00233
00234 if(RightLaneExists)
00235 RightLaneAdvantage = LaneChangeAdvantage(RightFrontVehicle, RightBackVehicle, true);
00236 }
00237
00238 const double zero = 0.0001;
00239 if(LeftLaneAdvantage < zero && RightLaneAdvantage < zero)
00240 return 0;
00241 else if(LeftLaneAdvantage > RightLaneAdvantage)
00242 return 1;
00243 else
00244 return 2;
00245 }
00246
00260 double Vehicle::LaneChangeAdvantage(Vehicle* FrontVehicle, Vehicle* BackVehicle, bool overtake)
00261 {
00262
00263 double GapToFront = MIN_SPACE_FOR_NEXT_VEHICLE; double GapToBack = MIN_SPACE_FOR_NEXT_VEHICLE;
00264 double CurrentBackAccel = SAFE_BRAKING; double ProposedBackAccel= SAFE_BRAKING;
00265 double FrontChangeAccel = 0.0;
00266
00267
00268 if(FrontVehicle != NULL)
00269 {
00270 GapToFront = FrontVehicle->getPos() - FrontVehicle->getLength() - this->getPos();
00271 FrontChangeAccel = this->calcAccel(FrontVehicle) - this->getAccel();
00272 }
00273 else
00274 FrontChangeAccel = this->calcAccel() - this->getAccel();
00275
00276 if(BackVehicle != NULL)
00277 {
00278 GapToBack = this->getPos() - this->getLength() - BackVehicle->getPos();
00279 ProposedBackAccel = BackVehicle->calcAccel(this);
00280
00281
00282
00283
00284 if(FrontVehicle != NULL)
00285 CurrentBackAccel = BackVehicle->calcAccel(FrontVehicle);
00286 else
00287 CurrentBackAccel = BackVehicle->getAccel();
00288 }
00289
00290 double advantage = m_pDriver->LaneChange(GapToFront, GapToBack, FrontChangeAccel,
00291 CurrentBackAccel, ProposedBackAccel, overtake);
00292 return advantage;
00293 }
00294
00295
00299
00304 void Vehicle::setVelocity(double vel)
00305 {
00306 m_Velocity = vel;
00307 }
00308
00313 void Vehicle::setLength(double length)
00314 {
00315 m_Length = length;
00316 }
00317
00322 void Vehicle::setAccel(double acc)
00323 {
00324 m_Acceleration = acc;
00325 }
00326
00331 void Vehicle::setLane(int lane)
00332 {
00333 m_Lane = lane;
00334 }
00335
00341 void Vehicle::setDirection(bool DirPos)
00342 {
00343 m_DirPos = DirPos;
00344 }
00345
00346
00351 void Vehicle::setPos(double p)
00352 {
00353 m_Position = p;
00354 }
00355
00360 void Vehicle::setChangeStatus(bool stat)
00361 {
00362 m_bLaneChange = stat;
00363 }
00364
00369 void Vehicle::setRoadPos(double r)
00370 {
00371 m_RoadPosition = r;
00372 }
00373
00374
00379 double Vehicle::getPos()
00380 {
00381 return m_Position;
00382 }
00383
00388 double Vehicle::getDesiredVel()
00389 {
00390 return m_pDriver->getDesiredVel();
00391 }
00392
00397 double Vehicle::getRoadPos()
00398 {
00399 return m_RoadPosition;
00400 }
00401
00406 WORD Vehicle::getID()
00407 {
00408 return m_ID;
00409 }
00410
00415 bool Vehicle::getChangeStatus()
00416 {
00417 return m_bLaneChange;
00418 }
00419
00424 double Vehicle::getVelocity()
00425 {
00426 return m_Velocity;
00427 }
00428
00433 double Vehicle::getLength()
00434 {
00435 return m_Length;
00436 }
00437
00442 double Vehicle::getAccel()
00443 {
00444 return m_Acceleration;
00445 }
00446
00451 int Vehicle::getLane()
00452 {
00453 return m_Lane;
00454 }
00455
00460 bool Vehicle::getDirection()
00461 {
00462 return m_DirPos;
00463 }
00464
00469 double Vehicle::getGVW()
00470 {
00471 return m_GVW;
00472 }
00473
00477 void Vehicle::setGVW(double weight)
00478 {
00479 m_GVW = weight;
00480 }
00481
00482 WORD Vehicle::setID()
00483 {
00484
00485 m_ID = (m_NoAxles <= SMALL_TRUCK_NO_AXLES) ?
00486 VEH_ID_SMALLTRUCK : VEH_ID_LARGETRUCK;
00487
00488
00489 double averageSpace = getAS(0);
00490 double maxSpace = 0;
00491
00492
00493 for(int i = 1; i < m_NoAxles; i++)
00494 {
00495
00496 averageSpace += getAS(i);
00497
00498
00499 if(getAS(i) > getAS(i-1))
00500 maxSpace = getAS(i);
00501 }
00502
00503
00504 if(maxSpace < CRANE_MAX_SPACING && m_NoAxles > 2)
00505 {
00506 if(averageSpace / m_vAxles.size() < CRANE_AVERAGE_SPACING)
00507 m_ID = VEH_ID_CRANE;
00508 }
00509
00510
00511 if(maxSpace >= LOWLOADER_MIN_MAX_SPACING && m_NoAxles > 2)
00512 m_ID = VEH_ID_LOWLOADER;
00513
00514 return m_ID;
00515 }
00516
00522 double Vehicle::getTime() const
00523 {
00524
00525 int s_per_hr = SECS_PER_HOUR;
00526 int s_per_day = SECS_PER_HOUR*HOURS_PER_DAY;
00527
00528 int no_days = (m_Year - 5) * MTS_PER_YR * DAYS_PER_MT + (m_Month - 1) * DAYS_PER_MT + (m_Day-1);
00529 double time = no_days * s_per_day + m_Hour * s_per_hr + m_Min * SECS_PER_MIN + m_Sec + (double)m_Hndt/100;
00530
00531 return time;
00532 }
00533
00534 void Vehicle::setTime(double time)
00535 {
00536 double temp = time;
00537 const int mpy = MTS_PER_YR; const int dpm = DAYS_PER_MT;
00538
00539 m_Year = (int)(temp/(MTS_PER_YR * DAYS_PER_MT * HOURS_PER_DAY * SECS_PER_HOUR));
00540
00541 temp = time - m_Year * MTS_PER_YR * DAYS_PER_MT * HOURS_PER_DAY * SECS_PER_HOUR;
00542 m_Month = (int)(temp/(DAYS_PER_MT * HOURS_PER_DAY * SECS_PER_HOUR));
00543
00544 temp = temp - m_Month * DAYS_PER_MT * HOURS_PER_DAY * SECS_PER_HOUR;
00545 m_Day = (int)(temp/(HOURS_PER_DAY * SECS_PER_HOUR));
00546
00547 temp = temp - m_Day * HOURS_PER_DAY * SECS_PER_HOUR;
00548 m_Hour = (int)(temp/(SECS_PER_HOUR));
00549
00550 temp = temp - m_Hour * SECS_PER_HOUR;
00551 m_Min = (int)(temp/(MINS_PER_HOUR));
00552
00553 temp = temp - m_Min * MINS_PER_HOUR;
00554 m_Sec = (int)(temp);
00555
00556 temp = temp - m_Sec;
00557 m_Hndt = (int)(100 * temp);
00558
00559 }
00560
00561 void Vehicle::init(int RoadLength, bool DriveOnRight)
00562 {
00563 m_RoadLength = RoadLength;
00564 m_DriveOnRight = DriveOnRight;
00565 }
00566
00567 void Vehicle::setRoadLength(int length)
00568 {
00569 m_RoadLength = length;
00570 }
00571
00576 int Vehicle::getNoAxles()
00577 {
00578 return m_NoAxles;
00579 }
00580
00588 void Vehicle::setAS(int i, double s)
00589 {
00590 m_vAxles.at(i)->setSpacing(s);
00591 }
00592
00597 void Vehicle::setAW(int i, double w)
00598 {
00599 m_vAxles.at(i)->setWeight(w);
00600 }
00601
00607 void Vehicle::setAxles()
00608 {
00609 for(int i = 0; i < m_NoAxles; i++)
00610 {
00611 Axle* axle = new Axle();
00612 m_vAxles.push_back(axle);
00613 }
00614 }
00615
00623 double Vehicle::getAS(int i)
00624 {
00625 return m_vAxles.at(i)->getSpacing();
00626 }
00627
00633 double Vehicle::getAW(int i)
00634 {
00635 return m_vAxles.at(i)->getWeight();
00636 }
00637
00638
00639 void Vehicle::setTotalNoLanesInRoad(int nLanes)
00640 {
00641 m_TotalNoLanesInRoad = nLanes;
00642 }
00643
00644
00645 int Vehicle::getLaneNoInDirection()
00646 {
00647 if(m_DirPos)
00648 return m_Lane;
00649 else
00650 {
00651 ASSERT(m_Lane <= m_TotalNoLanesInRoad);
00652 int iLocalLane = m_TotalNoLanesInRoad - m_Lane + 1;
00653 return iLocalLane;
00654 }
00655 }
00656
00660
00661 void Vehicle::createCASTORVehicle(std::string data)
00662 {
00663 m_Position = 0.0;
00664 m_RoadPosition = m_Position;
00665
00666 m_Head = atoi( data.substr(0,4).c_str() );
00667 m_Day = atoi( data.substr(4,2).c_str() );
00668 m_Month = atoi( data.substr(6,2).c_str() );
00669 m_Year = atoi( data.substr(8,2).c_str() );
00670 m_Hour = atoi( data.substr(10,2).c_str() );
00671 m_Min = atoi( data.substr(12,2).c_str() );
00672 m_Sec = atoi( data.substr(14,2).c_str() );
00673 m_Hndt = atoi( data.substr(16,2).c_str() );
00674 m_Velocity = atoi( data.substr(18,3).c_str() );
00675 m_GVW = atoi( data.substr(21,4).c_str() );
00676 m_Length = atoi( data.substr(25,3).c_str() );
00677 m_NoAxles = atoi( data.substr(28,1).c_str() );
00678 m_intDir = atoi( data.substr(29,1).c_str() );
00679 m_Lane = atoi( data.substr(30,1).c_str() );
00680 m_Trns = atoi( data.substr(31,3).c_str() );
00681
00682 m_DirPos = m_intDir == 1 ? true : false;
00683
00684
00685
00686
00687
00688
00689 m_Length /= 10;
00690 m_Velocity /= 10;
00691 m_GVW *= KG100_TO_KN;
00692 m_Trns /= 10;
00693
00694 m_Tdelay = 0.0;
00695
00696 setAxles();
00697 double W;
00698 double S;
00699 int j = 32;
00700
00701 for(int i = 0; i < m_NoAxles; i++)
00702 {
00703 j += 2;
00704 W = atoi( data.substr(j,3).c_str() );
00705 W *= KG100_TO_KN;
00706 setAW(i, W);
00707
00708 j += 3;
00709 S = atoi( data.substr(j,2).c_str() );
00710 S /= 10;
00711 setAS(i, S);
00712 }
00713
00714 m_ID = setID();
00715 }
00716
00717 void Vehicle::createSAFTVehicle(std::string data)
00718 {
00719 m_Position = 0.0;
00720 m_RoadPosition = m_Position;
00721
00722 m_Order = atoi( data.substr(0,5).c_str() );
00723 m_Head = 20005;
00724 m_Day = atoi( data.substr(10,2).c_str() );
00725 m_Month = atoi( data.substr(12,2).c_str() );
00726 m_Year = atoi( data.substr(14,2).c_str() );
00727 m_Hour = atoi( data.substr(16,2).c_str() );
00728 m_Min = atoi( data.substr(18,2).c_str() );
00729 m_Sec = atoi( data.substr(20,2).c_str() );
00730 m_Hndt = atoi( data.substr(22,2).c_str() );
00731 m_Velocity = atoi( data.substr(24,3).c_str() );
00732 m_GVW = atoi( data.substr(27,4).c_str() );
00733 m_Length = atoi( data.substr(31,3).c_str() );
00734 m_NoAxles = atoi( data.substr(34,1).c_str() );
00735
00736 m_Lane = 1;
00737 m_intDir = 1;
00738
00739
00740
00741 m_Length /= 10;
00742 m_Velocity /= 10;
00743
00744 m_Tdelay = 0.0;
00745
00746 setAxles();
00747 double W;
00748 double S;
00749 int j = 33;
00750
00751 for(int i = 0; i < m_NoAxles; i++)
00752 {
00753 j += 2;
00754 W = atoi( data.substr(j,3).c_str() );
00755 setAW(i, W);
00756
00757 if(i == m_NoAxles-1) break;
00758
00759 j += 3;
00760 S = atoi( data.substr(j,2).c_str() );
00761 S /= 10;
00762 setAS(i, S);
00763 }
00764
00765 m_ID = setID();
00766 }
00767
00776 void Vehicle::writeCASTORData(char* pVehChar)
00777 {
00778
00779
00780
00781
00782
00783 int velocity = Round(m_Velocity*10);
00784 int grossWeight = Round(m_GVW/KG100_TO_KN);
00785 int length = Round(m_Length*10);
00786 int transPos = Round(m_Trns*10);
00787
00788 ostrstream oFile( pVehChar, sizeof(pVehChar)*78 );
00789
00790 oFile.width(4); oFile << m_Head;
00791 oFile.width(2); oFile << m_Day;
00792 oFile.width(2); oFile << m_Month;
00793 oFile.width(2); oFile << m_Year;
00794 oFile.width(2); oFile << m_Hour;
00795 oFile.width(2); oFile << m_Min;
00796 oFile.width(2); oFile << m_Sec;
00797 oFile.width(2); oFile << m_Hndt;
00798 oFile.width(3); oFile << velocity;
00799 oFile.width(4); oFile << grossWeight;
00800 oFile.width(3); oFile << length;
00801 oFile.width(1); oFile << m_NoAxles;
00802 oFile.width(1); oFile << m_intDir;
00803 oFile.width(1); oFile << getLaneNoInDirection();
00804 oFile.width(3); oFile << transPos;
00805
00806 int j = 3;
00807 for(int i = 0; i < m_NoAxles; i++)
00808 {
00809 oFile.width(j); oFile << Round(this->getAW(i)/KG100_TO_KN);
00810 j = 2;
00811
00812 if(i == 8) break;
00813
00814 oFile.width(j); oFile << Round(this->getAS(i)*10);
00815 j = 3;
00816 }
00817
00818 for(i = m_NoAxles; i < CASTOR_MAX_AXLES; i++)
00819 {
00820 oFile.width(j); oFile << "0";
00821 j = 2;
00822
00823 if(i == 8) break;
00824
00825 oFile.width(j); oFile << "0";
00826 j = 3;
00827 }
00828
00829 oFile << ends;
00830 }
00839 void Vehicle::writeSAFTData(char *pVehChar)
00840 {
00841
00842
00843
00844 int velocity = Round(m_Velocity*10);
00845 int length = Round(m_Length*10);
00846
00847 ostrstream oFile( pVehChar, sizeof(pVehChar)*78 );
00848
00849 oFile.fill('0');
00850 oFile.width(5); oFile << m_Order;
00851 oFile.width(5); oFile << m_Head;
00852 oFile.width(2); oFile << m_Day;
00853 oFile.width(2); oFile << m_Month;
00854 oFile.width(2); oFile << m_Year;
00855 oFile.width(2); oFile << m_Hour;
00856 oFile.width(2); oFile << m_Min;
00857 oFile.width(2); oFile << m_Sec;
00858 oFile.width(2); oFile << m_Hndt;
00859 oFile.fill(' ');
00860 oFile.width(3); oFile << velocity;
00861 oFile.width(4); oFile << m_GVW;
00862 oFile.width(3); oFile << length;
00863 oFile.width(1); oFile << m_NoAxles;
00864
00865 int j = 3;
00866 for(int i = 0; i < m_NoAxles; i++)
00867 {
00868 oFile.width(j); oFile << Round(this->getAW(i)/KG100_TO_KN);
00869 j = 2;
00870
00871 if(i == m_NoAxles-1)
00872 break;
00873
00874 oFile.width(j); oFile << Round(this->getAS(i)*10);
00875 j = 3;
00876 }
00877
00878 oFile << ends;
00879 }
00880
00881 CString Vehicle::getDataString()
00882 {
00883 CString dataStr, tempStr, strSplitter;
00884 strSplitter = "-----------------------------------\n";
00885
00886 dataStr = "Vehicle Data:\n";
00887 dataStr += strSplitter;
00888 dataStr += "Direction: \t";
00889 tempStr = m_DirPos ? "Positive\n" : "Negative\n";
00890 dataStr += tempStr;
00891
00892 tempStr.Format("Lane: \t%d\n", m_Lane); dataStr += tempStr;
00893 tempStr.Format("Position: \t%4.1f m\n", m_RoadPosition); dataStr += tempStr;
00894 tempStr.Format("Velocity: \t%3.1f km/h\n", m_Velocity*M_PER_S_TO_KM_PER_H); dataStr += tempStr;
00895 tempStr.Format("Acceleration:\t%2.2f m/s^2\n", m_Acceleration); dataStr += tempStr;
00896 tempStr.Format("Desired Vel.:\t%3.1f km/h\n", m_pDriver->getDesiredVel()*M_PER_S_TO_KM_PER_H); dataStr += tempStr;
00897
00898 dataStr += strSplitter;
00899
00900 tempStr.Format("IDM T: \t\t%1.2f s\n", m_IDMDriver.get_T() ); dataStr += tempStr;
00901 tempStr.Format("IDM A: \t\t%2.2f m/s^2\n", m_IDMDriver.get_A() ); dataStr += tempStr;
00902 tempStr.Format("IDM B: \t\t%2.2f m/s^2\n", m_IDMDriver.get_B() ); dataStr += tempStr;
00903 tempStr.Format("IDM S0:\t\t%2.2f m\n", m_IDMDriver.get_S0() ); dataStr += tempStr;
00904 tempStr.Format("IDM S1:\t\t%2.2f m\n", m_IDMDriver.get_S1() ); dataStr += tempStr;
00905 tempStr.Format("IDM V0:\t\t%3.1f m/s\n", m_IDMDriver.get_V0() ); dataStr += tempStr;
00906 tempStr.Format("IDM Delta:\t%2.1f\n", m_IDMDriver.get_Delta() ); dataStr += tempStr;
00907 tempStr.Format("IDM Polite:\t%2.1f\n", m_IDMDriver.get_Polite() ); dataStr += tempStr;
00908 tempStr.Format("IDM Bias:\t%2.1f\n", m_IDMDriver.get_Bias() ); dataStr += tempStr;
00909 tempStr.Format("IDM DeltaAth:\t%2.1f\n", m_IDMDriver.get_DeltaAth() ); dataStr += tempStr;
00910
00911 dataStr += strSplitter;
00912
00913 tempStr.Format("GVW: \t%3.1f kN\n", m_GVW); dataStr += tempStr;
00914 tempStr.Format("Length: \t%2.1f m\n", m_Length); dataStr += tempStr;
00915 tempStr.Format("No of Axles: \t%d\n", m_NoAxles); dataStr += tempStr;
00916
00917 for(int i = 0; i < m_NoAxles; i++)
00918 {
00919 tempStr.Format("Axle %d:\t", i+1); dataStr += tempStr;
00920 tempStr.Format("%2.1f kN", getAW(i) ); dataStr += tempStr;
00921 if(i < m_NoAxles - 1)
00922 {
00923 tempStr.Format(" | %2.1f m\n",getAS(i) ); dataStr += tempStr;
00924 }
00925 }
00926
00927 return dataStr;
00928 }