00001
00006 #include <iostream>
00007 #include <fstream>
00008 #include <time.h>
00009 #include <stdlib.h>
00010 using namespace std;
00011
00012 #include "Fahrzeug.h"
00013 #include "Fehler.h"
00014 #include "Konstanten.h"
00015
00022 Fahrzeug::Fahrzeug( ){
00023 clear();
00024 }
00025
00044 Fahrzeug::Fahrzeug( int typ,
00045 double laenge,
00046 Koordinaten farbe,
00047 double beschleunigungPositiv,
00048 double beschleunigungNegativ,
00049 double hoechstgeschwindigkeit,
00050 Spur *spur,
00051 double lebensdauer,
00052 long int id){
00053 clear();
00054 id_ = id;
00055 typ_ = typ;
00056 laenge_ = laenge;
00057 farbe_ = farbe;
00058 beschleunigungPositiv_ = beschleunigungPositiv;
00059 beschleunigungNegativ_ = beschleunigungNegativ;
00060 hoechstgeschwindigkeit_ = hoechstgeschwindigkeit;
00061
00062
00063 if( lebensdauer == -1 )
00064 lebensdauer_ = lebensdauer;
00065 else
00066 lebensdauer_ = lebensdauer + 1;
00067
00068 try{
00069 wechselSpur( spur );
00070 }
00071 catch( Fehler *fehler ){
00072 throw(fehler);
00073 }
00074 }
00075
00076
00084 void Fahrzeug::aufraeumen(){
00085 try{
00086 if( aktuelleSpur_ != 0 ){
00087 aktuelleSpur_->abmelden( this );
00088 aktuelleSpur_ = 0;
00089 }
00090 }
00091 catch( Fehler *fehler ){
00092 throw( fehler );
00093 }
00094 }
00095
00108 void Fahrzeug::takt( double zeitintervall ){
00109 try{
00110 fahren( zeitintervall );
00111 }
00112 catch( Fehler *fehler ){
00113 throw( fehler );
00114 }
00115 }
00116
00117
00128 void Fahrzeug::fahren( double zeitintervall ){
00129 double abstandVorgaenger(0), bremsweg(0), abstandEndeSpur(0), abstandHindernis(0);
00130 double temp(0), bremsIntensivitaet(0);
00131 int ueberAmpel(0);
00132
00133 if( aktuelleSpur_ == 0 ){
00134 Fehler *fehler = new Fehler( "Ein Fahrzeug befindet sich nicht mehr auf einer Spur.");
00135 throw(fehler);
00136 return;
00137 }
00138
00139
00140 alter_ = alter_ + zeitintervall;
00141
00142
00143 bremsweg = gibBremsweg();
00144
00145 abstandVorgaenger = gibAbstandZumVordermann();
00146
00147 abstandEndeSpur = gibAbstandZurKreuzung();
00148
00149
00150
00151
00152 if( abstandVorgaenger < -1 ){
00153 beschleunigeNegativ(zeitintervall, 1);
00154 return;
00155 }
00156
00157
00158 if( abstandEndeSpur > abstandVorgaenger && abstandVorgaenger != -1 ){
00159 abstandHindernis = abstandVorgaenger;
00160 }
00161 else{
00162 if( aktuelleSpur_->istRot() && bremsweg <= abstandEndeSpur ){
00163 abstandHindernis = abstandEndeSpur;
00164 }
00165 else if( aktuelleSpur_->istGruen() || aktuelleSpur_->istSackgasse() ){
00166 abstandHindernis = abstandVorgaenger;
00167 ueberAmpel = 1;
00168 }
00169 else if( (aktuelleSpur_->istGelb() || aktuelleSpur_->istRot()) && bremsweg > abstandEndeSpur ){
00170 abstandHindernis = abstandVorgaenger;
00171 ueberAmpel = 1;
00172 }
00173 else if( aktuelleSpur_->istGelb() && bremsweg <= abstandEndeSpur ){
00174 abstandHindernis = abstandEndeSpur;
00175 }
00176 }
00177
00178
00179 if( abstandHindernis == -1)
00180 abstandHindernis = bremsweg*3 + 10;
00181
00182
00183 bremsIntensivitaet = (bremsweg+0.5) / abstandHindernis;
00184 if( bremsIntensivitaet >= 0.5 ){
00185 beschleunigeNegativ(zeitintervall, bremsIntensivitaet);
00186 }
00187 else{
00188 if( geschwindigkeit_ < aktuelleSpur_->gibMaximaleGeschwindigkeit() ){
00189 beschleunigePositiv(zeitintervall);
00190 }
00191 if( geschwindigkeit_ > aktuelleSpur_->gibMaximaleGeschwindigkeit() ){
00192 beschleunigeNegativ(zeitintervall, 0.5);
00193 }
00194 if( geschwindigkeit_ == aktuelleSpur_->gibMaximaleGeschwindigkeit() ){
00195 beschleunigeNicht(zeitintervall);
00196 }
00197 }
00198
00199 if( aktuelleSpur_->istSackgasse() && gibAbstandZurKreuzung() < 1 ){
00200 loescheMich_ = 1;
00201 }
00202
00203
00204 if( (gibAbstandZurKreuzung() <= 0) && (ueberAmpel == 1) && ( !aktuelleSpur_->istSackgasse() ) ){
00205 temp = gibAbstandZurKreuzung() * -1;
00206 wechselSpur();
00207 aktuellePosition_ = temp;
00208 }
00209 }
00210
00211
00224 void Fahrzeug::setzeFahrtenbuch(int *fahrtenbuch, int anzahlWegpunkte){
00225 if( anzahlWegpunkte != 0 && fahrtenbuch == 0 ){
00226 Fehler *fehler = new Fehler("Parameterfehler: Es wurde einem Fahrzeug ein ungueltiges Fahrtenbuch uebergeben.");
00227 throw( fehler );
00228 }
00229 fahrtenbuch_ = fahrtenbuch;
00230 anzahlWegpunkte_ = anzahlWegpunkte;
00231 }
00232
00233
00242 double Fahrzeug::gibPosition( ){
00243 return aktuellePosition_;
00244 }
00245
00246
00255 Koordinaten Fahrzeug::gibFarbe( ){
00256 return farbe_;
00257 }
00258
00259
00269 double Fahrzeug::gibAbstandZumVordermann( ){
00270 double abstand(0);
00271 Fahrzeug* vorgaenger(0);
00272 vorgaenger = aktuelleSpur_->gibVorgaenger( this );
00273
00274 if( vorgaenger == 0 ){
00275
00276 if( naechsteSpur_ != 0 ){
00277 vorgaenger = naechsteSpur_->gibLetztes();
00278 if( vorgaenger == 0 ){
00279 if( naechsteSpur_->istRot() || naechsteSpur_->istGelb() ){
00280
00281
00282 abstand = aktuelleSpur_->gibLaenge() + naechsteSpur_->gibLaenge() - this->gibPosition();
00283
00284 abstand = abstand - laenge_;
00285 return abstand;
00286 }
00287 else
00288 return -1;
00289 }
00290 else{
00291
00292 abstand = aktuelleSpur_->gibLaenge() - this->gibPosition();
00293 abstand = abstand + vorgaenger->gibPosition();
00294
00295 abstand = abstand - laenge_;
00296 return abstand;
00297 }
00298 }
00299 else{
00300 return -1;
00301 }
00302 }
00303
00304 else{
00305 abstand = vorgaenger->gibPosition() - this->gibPosition() - laenge_;
00306 return abstand;
00307 }
00308 return abstand;
00309 }
00310
00311
00321 double Fahrzeug::gibAbstandZurKreuzung(){
00322 double abstand(0);
00323 abstand = aktuelleSpur_->gibLaenge() - aktuellePosition_ - laenge_;
00324 return abstand;
00325 }
00326
00327
00338 void Fahrzeug::beschleunigePositiv( double zeitintervall ){
00339 double wegstrecke(0);
00340 double vBegin(0);
00341 vBegin = geschwindigkeit_;
00342 geschwindigkeit_ = geschwindigkeit_ + ( beschleunigungPositiv_ * zeitintervall ) * 3.6;
00343
00344
00345
00346
00347 if( geschwindigkeit_ >= hoechstgeschwindigkeit_ ){
00348 geschwindigkeit_ = hoechstgeschwindigkeit_;
00349 wegstrecke = geschwindigkeit_ / 3.6 * zeitintervall;
00350
00351 }
00352 else{
00353 wegstrecke = ( beschleunigungPositiv_ / 2 ) * zeitintervall * zeitintervall + ( vBegin / 3.6 * zeitintervall);
00354
00355 }
00356 aktuellePosition_ = wegstrecke + aktuellePosition_;
00357
00358 kilometerstand_ = (wegstrecke/1000) + kilometerstand_;
00359 bremst_ = -5;
00360 }
00361
00362
00373 void Fahrzeug::beschleunigeNicht( double zeitintervall ){
00374 double wegstrecke(0);
00375 wegstrecke = geschwindigkeit_ / 3.6 * zeitintervall;
00376 aktuellePosition_ = aktuellePosition_ + wegstrecke;
00377 kilometerstand_ = kilometerstand_ + (wegstrecke / 1000);
00378 bremst_ = 0;
00379 }
00380
00393 void Fahrzeug::beschleunigeNegativ( double zeitintervall, double intensivitaet ){
00394 if( intensivitaet < 0.5 || intensivitaet > 1 )
00395 return;
00396
00397 double wegstrecke(0);
00398 double vBegin(0);
00399 vBegin = geschwindigkeit_;
00400 geschwindigkeit_ = geschwindigkeit_ + ( intensivitaet * beschleunigungNegativ_ * zeitintervall ) * 3.6;
00401
00402
00403
00404
00405 if( geschwindigkeit_ <= 0 ){
00406 geschwindigkeit_ = 0;
00407 wegstrecke = 0;
00408
00409 }
00410 else{
00411 wegstrecke = ( intensivitaet * beschleunigungNegativ_ / 2 ) * zeitintervall * zeitintervall + ( vBegin / 3.6 * zeitintervall);
00412
00413 }
00414 aktuellePosition_ = wegstrecke + aktuellePosition_;
00415
00416 kilometerstand_ = (wegstrecke/1000) + kilometerstand_;
00417 bremst_++;
00418 }
00419
00420
00430 void Fahrzeug::wechselSpur( Spur *spur ){
00431 srand((unsigned)time(NULL));
00432 int zufall(0);
00433 int richtung[3];
00434 int grenze[3][2];
00435 int neueSpur(-1);
00436
00437 try{
00438
00439 if( aktuelleSpur_ != 0 ){
00440 aktuelleSpur_->abmelden( this );
00441 aktuelleSpur_ = 0;
00442 }
00443
00444
00445 if( lebensdauer_ == 0 ){
00446 naechsteRichtung_ = MITTE;
00447 loescheMich_ = 1;
00448 return;
00449 }
00450 }
00451 catch( Fehler *fehler ){
00452 throw( fehler );
00453 }
00454
00455
00456 if( spur != 0 ){
00457 aktuelleSpur_ = spur;
00458 }
00459 else{
00460 aktuelleSpur_ = naechsteSpur_;
00461 }
00462
00463 if( aktuelleSpur_ == 0 ){
00464 loescheMich_ = 1;
00465 return;
00466 }
00467
00468 if( aktuelleSpur_->istSackgasse() ){
00469 naechsteSpur_ = 0;
00470 naechsteRichtung_ = MITTE;
00471 aktuelleSpur_->anmelden( this );
00472 lebensdauer_ = 0;
00473
00474 aktuellePosition_ = 0;
00475 return;
00476 }
00477
00478 richtung[0] = (int) (aktuelleSpur_->gibWahrscheinlichkeit(1) * 100);
00479 richtung[1] = (int) (aktuelleSpur_->gibWahrscheinlichkeit(2) * 100);
00480 richtung[2] = (int) (aktuelleSpur_->gibWahrscheinlichkeit(3) * 100);
00481
00482
00483 if( anzahlWegpunkte_ != 0 ){
00484 while( (neueSpur < 1 || neueSpur > 3) && anzahlWegpunkte_ != 0 ){
00485
00486 if( aktuellerWegpunkt_ > ( anzahlWegpunkte_ - 1 ) ){
00487 anzahlWegpunkte_ = 0;
00488 break;
00489 }
00490
00491
00492 if( richtung[fahrtenbuch_[aktuellerWegpunkt_]] != 0 ){
00493 neueSpur = fahrtenbuch_[aktuellerWegpunkt_];
00494 aktuellerWegpunkt_++;
00495 }
00496
00497 else{
00498 aktuellerWegpunkt_++;
00499 neueSpur = -1;
00500 }
00501 }
00502 }
00503
00504
00505 if( anzahlWegpunkte_ == 0 ){
00506 while( neueSpur < 1 || neueSpur > 3 ){
00507 grenze[0][0] = 0;
00508 grenze[0][1] = richtung[0];
00509 grenze[1][0] = richtung[0];
00510 grenze[1][1] = grenze[1][0] + richtung[1];
00511 grenze[2][0] = richtung[0] + richtung[1];
00512 grenze[2][1] = grenze[2][0] + richtung[2];
00513
00514 zufall = rand()%100 + 1;
00515
00516
00517 if( zufall > grenze[0][0] && zufall <= grenze[0][1] )
00518 neueSpur = LINKS;
00519 else if( zufall > grenze[1][0] && zufall <= grenze[1][1] )
00520 neueSpur = MITTE;
00521 else if( zufall > grenze[2][0] && zufall <= grenze[2][1] )
00522 neueSpur = RECHTS;
00523 else
00524 neueSpur = -1;
00525 }
00526 }
00527
00528 try{
00529 naechsteSpur_ = aktuelleSpur_->gibNaechsteSpur(neueSpur);
00530 naechsteRichtung_ = neueSpur;
00531 }
00532 catch( Fehler *fehler ){
00533 throw( fehler );
00534 }
00535
00536 if( lebensdauer_ != -1 )
00537 lebensdauer_--;
00538
00539 aktuelleSpur_->anmelden( this );
00540
00541 aktuellePosition_ = 0;
00542 }
00543
00544
00553 double Fahrzeug::gibBremsweg( ){
00554 double bremsweg(0);
00555 bremsweg = ( (geschwindigkeit_ / 3.6) * (geschwindigkeit_ / 3.6) ) / ( 2 * beschleunigungNegativ_ ) * -1;
00556
00557
00558 return bremsweg;
00559 }
00560
00561
00570 bool Fahrzeug::istBremsend(){
00571 if( bremst_ < 1 )
00572 return 0;
00573 else
00574 return 1;
00575 }
00576
00577
00586 bool Fahrzeug::sollEntferntWerden(){
00587 return loescheMich_;
00588 }
00589
00598 double Fahrzeug::gibLaenge(){
00599 return laenge_;
00600 }
00601
00610 Spur *Fahrzeug::gibSpur( ){
00611 return aktuelleSpur_;
00612 }
00613
00614
00623 int Fahrzeug::gibTyp (){
00624 return typ_;
00625 }
00626
00627
00628
00629
00630
00631
00632
00633 void Fahrzeug::inString( ){
00634 cout << this;
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 int Fahrzeug::gibNaechsteRichtung(){
00646 return naechsteRichtung_;
00647 }
00648
00657 ostream &operator<< ( ostream &os, Fahrzeug *fahrzeug ){
00658 os << "----------Fahrzeug----------" << endl;
00659 os << "ID: " << fahrzeug->id_ << endl;
00660 os << "Beschleunigung: " << fahrzeug->beschleunigungPositiv_ << " m/s^2" << endl;
00661 os << "Bremsen: " << fahrzeug->beschleunigungNegativ_ << " m/s^2" << endl;
00662 os << "max. Geschwindigkeit: " << fahrzeug->hoechstgeschwindigkeit_ << " km/h" << endl;
00663 os << "Typ: " << fahrzeug->typ_ << " ( 1 = Motorrad | 2 = Pkw | 3 = Lkw | 4 = Bus )" << endl;
00664 os << "Farbe: " << fahrzeug->farbe_ << endl;
00665 os << "Laenge: " << fahrzeug->laenge_ << " m" << endl;
00666 os << endl;
00667 os << "akt. Geschwindigkeit: " << fahrzeug->geschwindigkeit_ << " km/h" << endl;
00668 os << "Kilometerstand: " << fahrzeug->kilometerstand_ << " km" << endl;
00669 os << "akt. Position: " << fahrzeug->aktuellePosition_ << " m auf Spur ??" << endl;
00670 os << "akt. Bremsweg: " << fahrzeug->gibBremsweg() << " m bis auf 0 km/h" << endl;
00671 if( fahrzeug->aktuelleSpur_ != 0 ){
00672 os << "Abstand. Vordermann: " << fahrzeug->gibAbstandZumVordermann( ) << " m" << endl;
00673 os << "Abstand. Kreuzung: " << fahrzeug->gibAbstandZurKreuzung( ) << " m" << endl;
00674 }
00675 os << "Lebensdauer: " << fahrzeug->lebensdauer_ << endl;
00676
00677 os << "aktuelle Spur:" << endl;
00678 if( fahrzeug->aktuelleSpur_ != 0 )
00679 os << fahrzeug->aktuelleSpur_ << endl;
00680 else
00681 os << "leer" << endl;
00682
00683 os << "naechste Spur:" << endl;
00684 if( fahrzeug->naechsteSpur_ != 0 );
00685
00686 else
00687 os << "leer" << endl;
00688 return os;
00689 }
00690
00691
00698 void Fahrzeug::clear(){
00699 id_ = 0;
00700 typ_ = 2;
00701 beschleunigungPositiv_ = 2.3;
00702 beschleunigungNegativ_ = -11.0;
00703 aktuellePosition_ = 0;
00704 lebensdauer_ = -1;
00705 laenge_ = 4.5;
00706 farbe_ = Koordinaten(125,125,125);
00707 geschwindigkeit_ = 0;
00708 hoechstgeschwindigkeit_ = 250;
00709 kilometerstand_ = 0;
00710 aktuelleSpur_ = 0;
00711 naechsteSpur_ = 0;
00712 fahrtenbuch_ = 0;
00713 loescheMich_ = 0;
00714 bremst_ = 0;
00715 alter_ = 0;
00716 naechsteRichtung_ = 0;
00717 fahrtenbuch_ = 0;
00718 anzahlWegpunkte_ = 0;
00719 aktuellerWegpunkt_ = 0;
00720 }
00721
00730 void Fahrzeug::exportieren( string cvsDateiname ){
00731 string dateiname = cvsDateiname;
00732 ofstream cvsDatei;
00733
00734 cvsDatei.open( dateiname.c_str(), ios::app );
00735 if( !cvsDatei ){
00736 Fehler *fehler = new Fehler( "Die CVS-Datei fuer Fahrzeuge konnte nicht geoeffnet werden.\n");
00737 fehler->ergaenzeMeldung( dateiname );
00738 throw(fehler);
00739 return;
00740 }
00741
00742
00743
00744 cvsDatei << "\"" << id_ << "\";\"" << typ_ << "\";\"" << alter_ << "\";\"" << kilometerstand_ << "\"" << endl;
00745
00746
00747 cvsDatei.close();
00748 }