$search
00001 //Tarun Nimmagadda 00002 //The University of Texas, Austin 00003 00004 //This file defines the RNDF structure as specified by the DARPA 00005 //specification. It parses the RNDF file into the RNDF data structure 00006 00007 #include <cstdio> 00008 #include <iostream> 00009 #include <fstream> 00010 #include <string> 00011 #include <cstdlib> 00012 #include <art/conversions.h> 00013 #include <art_msgs/ArtVehicle.h> 00014 #include <art/epsilon.h> 00015 #include <art_map/RNDF.h> 00016 00017 #define DEFAULT_LANE_WIDTH (art_msgs::ArtVehicle::width+1) 00018 #define DEFAULT_SPOT_WIDTH (art_msgs::ArtVehicle::width+1) 00019 #define DEFAULT_LANE_SPEED mph2mps(30) 00020 00021 enum RNDF_PARSE_STATE {COMMENT, GENERAL, SEGMENTS, LANES, 00022 ZONES, PERIMETER, PARKING_SPOT, UNKNOWN}; 00023 00024 enum MDF_PARSE_STATE {MDF_COMMENT, MDF_GENERAL, MDF_CHECKPOINTS, 00025 MDF_SPEEDLIMITS, MDF_UNKNOWN}; 00026 00027 template <class T> 00028 void change_state(T& previous_state, T& current_state, const T new_state){ 00029 previous_state = current_state; 00030 current_state = new_state; 00031 }; 00032 00033 00034 RNDF::RNDF(std::string rndfname, bool verbose) 00035 { 00036 number_of_segments = number_of_zones = -1; 00037 is_valid=true; 00038 00039 std::ifstream rndf_file; 00040 rndf_file.open(rndfname.c_str()); 00041 if (!rndf_file) 00042 { 00043 ROS_ERROR_STREAM("Error opening RNDF \"" << rndfname << "\""); 00044 is_valid = false; 00045 return; 00046 } 00047 00048 //Parser State 00049 line_number = 0; 00050 RNDF_PARSE_STATE state = UNKNOWN, previous_state = UNKNOWN; 00051 00052 Segment temp_segment; 00053 Lane temp_lane; 00054 Zone temp_zone; 00055 Perimeter temp_perimeter; 00056 Spot temp_spot; 00057 //Clear temp variables 00058 temp_segment.clear(); 00059 temp_lane.clear(); 00060 temp_zone.clear(); 00061 temp_perimeter.clear(); 00062 temp_spot.clear(); 00063 00064 00065 00066 std::string lineread; 00067 while(getline(rndf_file, lineread)) // Read line by line 00068 { 00069 line_number++; 00070 uint real_characters=0; 00071 00072 for (uint ind=0; ind < lineread.length(); ind++) 00073 if (lineread[ind] != '\r' && 00074 lineread[ind] != '\t' && 00075 lineread[ind] != ' ') 00076 real_characters++; 00077 00078 //Blank lines 00079 if (real_characters == 0) { 00080 if (verbose) 00081 printf("%d: Blank Line\n",line_number); 00082 continue; 00083 } 00084 00085 std::string token; 00086 char token_char [lineread.size()+1]; 00087 char temp_char [lineread.size()+1]; 00088 00089 //Read in one line 00090 sscanf(lineread.c_str(), "%s", token_char); 00091 token.assign(token_char); 00092 00093 // printf("Token: |%s|\n", token.c_str()); 00094 00095 if (state != COMMENT){ 00096 if (token.compare("RNDF_name") == 0) 00097 change_state(previous_state, state, GENERAL); 00098 else if (token.compare("segment") == 0) 00099 change_state(previous_state, state, SEGMENTS); 00100 else if (token.compare("lane") == 0) 00101 change_state(previous_state, state, LANES); 00102 else if (token.compare("zone") == 0) 00103 change_state(previous_state, state, ZONES); 00104 else if (token.compare("perimeter") == 0) 00105 change_state(previous_state, state, PERIMETER); 00106 else if (token.compare("spot") == 0) 00107 change_state(previous_state, state, PARKING_SPOT); 00108 else if (token.find("/*") != std::string::npos) 00109 change_state(previous_state, state, COMMENT); 00110 } 00111 00112 bool valid=true; 00113 switch (state){ 00114 case COMMENT: 00115 if (verbose) 00116 printf("%d: COMMENT: %s\n", line_number, lineread.c_str()); 00117 if (lineread.find("*/") != std::string::npos) 00118 state = previous_state; 00119 break; 00120 case GENERAL: 00121 //RNDF_NAME 00122 if (token.compare("RNDF_name") == 0) 00123 filename = 00124 parse_string(lineread, std::string("RNDF_name"), 00125 line_number, valid, verbose); 00126 //NUM_SEGMENTS 00127 else if (token.compare("num_segments") == 0){ 00128 number_of_segments = 00129 parse_integer(lineread, std::string("num_segments"), 00130 line_number, valid, verbose); 00131 if (number_of_segments <= 0) valid = false; 00132 } 00133 //NUM_ZONES 00134 else if (token.compare("num_zones") == 0){ 00135 number_of_zones = 00136 parse_integer(lineread, std::string("num_zones"), 00137 line_number, valid, verbose); 00138 if (number_of_zones < 0) valid = false; 00139 } 00140 //FORMAT_VERSION 00141 else if (token.compare("format_version") == 0) 00142 format_version = 00143 parse_string(lineread, std::string("format_version"), 00144 line_number, valid, verbose); 00145 //CREATION_DATE 00146 else if (token.compare("creation_date") == 0) 00147 creation_date = 00148 parse_string(lineread, std::string("creation_date"), 00149 line_number, valid, verbose); 00150 //END_FILE 00151 else if (token.compare("end_file") == 0){ 00152 if (!isvalid()) 00153 valid = false; 00154 else if (verbose) 00155 printf("%d: RNDF file has finished parsing\n", line_number); 00156 } 00157 //printf("Token: |%s|\n", token.c_str()); 00158 else { 00159 printf("%d: Unexpected token\n", line_number); 00160 valid=false; 00161 } 00162 break; 00163 case SEGMENTS: 00164 //SEGMENT 00165 if(token.compare("segment") == 0){ 00166 temp_segment.segment_id = 00167 parse_integer(lineread, std::string("segment"), 00168 line_number, valid, verbose); 00169 if (temp_segment.segment_id <= 0) valid = false; 00170 } 00171 //NUM_LANES 00172 else if(token.compare("num_lanes") == 0){ 00173 temp_segment.number_of_lanes = 00174 parse_integer(lineread, std::string("num_lanes"), 00175 line_number, valid, verbose); 00176 if (temp_segment.number_of_lanes <= 0) valid = false; 00177 } 00178 //SEGMENT_NAME 00179 else if(token.compare("segment_name") == 0) 00180 temp_segment.segment_name = 00181 parse_string(lineread, std::string("segment_name"), 00182 line_number, valid, verbose); 00183 //END_SEGMENT 00184 else if(token.compare("end_segment") == 0){ 00185 if (!temp_segment.isvalid()) 00186 valid = false; 00187 else{ 00188 segments.push_back(temp_segment); 00189 if (verbose) 00190 printf("%d: segment has ended\n", line_number); 00191 change_state(previous_state, state, GENERAL); 00192 temp_segment.clear(); 00193 } 00194 } 00195 else{ 00196 printf("%d: Unexpected token\n", line_number); 00197 valid=false; 00198 } 00199 break; 00200 case LANES: 00201 //LANE 00202 if(token.compare("lane") == 0){ 00203 sprintf(temp_char, "lane %d.%%d", temp_segment.segment_id); 00204 if (sscanf(lineread.c_str(), temp_char, &temp_lane.lane_id) == 1){ 00205 if (verbose) 00206 printf("%d: Lane number is %d\n", 00207 line_number, temp_lane.lane_id); 00208 } 00209 else valid=false; 00210 if (temp_lane.lane_id <= 0) valid = false; 00211 } 00212 //NUM_WAYPOINTS 00213 else if(token.compare("num_waypoints") == 0){ 00214 temp_lane.number_of_waypoints = 00215 parse_integer(lineread, std::string("num_waypoints"), 00216 line_number, valid, verbose); 00217 if (temp_lane.number_of_waypoints <= 0) valid = false; 00218 } 00219 //LANE_WIDTH 00220 else if(token.compare("lane_width") == 0){ 00221 temp_lane.lane_width = 00222 parse_integer(lineread, std::string("lane_width"), 00223 line_number, valid, verbose); 00224 if (temp_lane.lane_width <= 0) valid = false; 00225 } 00226 //LEFT_BOUNDARY 00227 else if(token.compare("left_boundary") == 0){ 00228 temp_lane.left_boundary = 00229 parse_boundary(lineread, valid); 00230 if (verbose) 00231 printf("%d: left boundary type is %d\n", 00232 line_number, temp_lane.left_boundary); 00233 } 00234 //RIGHT_BOUNDARY 00235 else if(token.compare("right_boundary") == 0){ 00236 temp_lane.right_boundary = 00237 parse_boundary(lineread, valid); 00238 if (verbose) 00239 printf("%d: right boundary type is %d\n", 00240 line_number, temp_lane.right_boundary); 00241 } 00242 //CHECKPOINT 00243 else if(token.compare("checkpoint") == 0){ 00244 Checkpoint checkpoint(lineread, temp_segment.segment_id, 00245 temp_lane.lane_id, line_number, valid, verbose); 00246 temp_lane.checkpoints.push_back(checkpoint); 00247 } 00248 //STOP 00249 else if(token.compare("stop") == 0){ 00250 Stop stop(lineread, temp_segment.segment_id, 00251 temp_lane.lane_id, line_number, valid, verbose); 00252 temp_lane.stops.push_back(stop); 00253 } 00254 //EXIT 00255 else if(token.compare("exit") == 0){ 00256 Exit exit(lineread, temp_segment.segment_id, 00257 temp_lane.lane_id, line_number, valid, verbose); 00258 temp_lane.exits.push_back(exit); 00259 } 00260 //END_LANE 00261 else if(token.compare("end_lane") == 0){ 00262 if(temp_lane.number_of_waypoints != (int)temp_lane.waypoints.size()) 00263 printf("Number of waypoints in lane does not match num_waypoints\n"); 00264 if (!temp_lane.isvalid()) 00265 valid = false; 00266 else{ 00267 temp_segment.lanes.push_back(temp_lane); 00268 if (verbose) 00269 printf("%d: lane has ended\n", line_number); 00270 change_state(previous_state, state, SEGMENTS); 00271 temp_lane.clear(); 00272 } 00273 } 00274 00275 //NO TOKEN 00276 else{ 00277 //WAYPOINT 00278 sprintf(temp_char, "%d.%d.", temp_segment.segment_id, 00279 temp_lane.lane_id); 00280 if(token.find(temp_char) != std::string::npos ){ 00281 LL_Waypoint wp(lineread, temp_segment.segment_id, 00282 temp_lane.lane_id, line_number, valid, verbose); 00283 temp_lane.waypoints.push_back(wp); 00284 } 00285 else{ 00286 printf("%d: Unexpected token\n", line_number); 00287 valid=false; 00288 } 00289 } 00290 break; 00291 case ZONES: 00292 //ZONE 00293 if(token.compare("zone") == 0){ 00294 temp_zone.zone_id = 00295 parse_integer(lineread, std::string("zone"), 00296 line_number, valid, verbose); 00297 if (temp_zone.zone_id <= 0) valid = false; 00298 00299 } 00300 //NUM_SPOTS 00301 else if(token.compare("num_spots") == 0){ 00302 temp_zone.number_of_parking_spots = 00303 parse_integer(lineread, std::string("num_spots"), 00304 line_number, valid, verbose); 00305 if (temp_zone.number_of_parking_spots < 0) valid = false; 00306 } 00307 //ZONE_NAME 00308 else if(token.compare("zone_name") == 0) 00309 temp_zone.zone_name = 00310 parse_string(lineread, std::string("zone_name"), 00311 line_number, valid, verbose); 00312 //END_ZONE 00313 else if(token.compare("end_zone") == 0){ 00314 if(!temp_zone.isvalid()) 00315 valid = false; 00316 else{ 00317 zones.push_back(temp_zone); 00318 if (verbose) 00319 printf("%d: zone has ended\n", line_number); 00320 change_state(previous_state, state, GENERAL); 00321 temp_zone.clear(); 00322 } 00323 } 00324 else { 00325 printf("%d: Unexpected token\n", line_number); 00326 valid=false; 00327 } 00328 break; 00329 case PERIMETER: 00330 //PERIMETER 00331 if(token.compare("perimeter") == 0){ 00332 sprintf(temp_char,"perimeter %d.%%d" , temp_zone.zone_id); 00333 if (sscanf(lineread.c_str(), temp_char, 00334 &temp_perimeter.perimeter_id) == 1){ 00335 if (verbose) 00336 printf("%d: Perimeter id is %d\n", 00337 line_number, temp_perimeter.perimeter_id); 00338 } 00339 else valid=false; 00340 if (temp_perimeter.perimeter_id != 0) 00341 valid = false; 00342 } 00343 //NUM_PERIMETER_POINTS 00344 else if(token.compare("num_perimeterpoints") == 0){ 00345 temp_perimeter.number_of_perimeterpoints = 00346 parse_integer(lineread, std::string("num_perimeterpoints"), 00347 line_number, valid, verbose); 00348 if (temp_perimeter.number_of_perimeterpoints <= 0) 00349 valid = false; 00350 } 00351 //EXIT 00352 else if(token.compare("exit") == 0){ 00353 Exit exit(lineread, temp_zone.zone_id, 0, line_number, valid, 00354 verbose); 00355 temp_perimeter.exits_from_perimeter.push_back(exit); 00356 } 00357 //END_PERIMETER 00358 else if(token.compare("end_perimeter") == 0){ 00359 if(!temp_perimeter.isvalid()) 00360 valid = false; 00361 else{ 00362 temp_zone.perimeter = temp_perimeter; 00363 if (verbose) 00364 printf("%d: perimeter has ended\n", line_number); 00365 change_state(previous_state, state, ZONES); 00366 temp_perimeter.clear(); 00367 } 00368 } 00369 else{ 00370 //WAYPOINT 00371 sprintf(temp_char, "%d.%d.", temp_zone.zone_id, 0); 00372 if(token.find(temp_char) != std::string::npos ){ 00373 LL_Waypoint wp(lineread, temp_zone.zone_id, 0, line_number, 00374 valid, verbose); 00375 temp_perimeter.perimeterpoints.push_back(wp); 00376 } 00377 else valid=false; 00378 } 00379 break; 00380 case PARKING_SPOT: 00381 //SPOT 00382 if(token.compare("spot") == 0){ 00383 sprintf(temp_char,"spot %d.%%d" , temp_zone.zone_id); 00384 if (sscanf(lineread.c_str(), temp_char, &temp_spot.spot_id) == 1){ 00385 if (verbose) 00386 printf("%d: Spot id is %d\n", line_number, temp_spot.spot_id); 00387 } 00388 else valid=false; 00389 if (temp_spot.spot_id <= 0) valid = false; 00390 } 00391 //SPOT_WIDTH 00392 else if(token.compare("spot_width") == 0){ 00393 temp_spot.spot_width = 00394 parse_integer(lineread, std::string("spot_width"), 00395 line_number, valid, verbose); 00396 if (temp_spot.spot_width <= 0) valid = false; 00397 } 00398 //CHECKPOINT 00399 else if(token.compare("checkpoint") == 0) 00400 temp_spot.checkpoint = Checkpoint(lineread, temp_zone.zone_id, 00401 temp_spot.spot_id, 00402 line_number, valid, verbose); 00403 //END_SPOT 00404 else if(token.compare("end_spot") == 0){ 00405 if(!temp_spot.isvalid()) 00406 valid = false; 00407 else{ 00408 temp_zone.spots.push_back(temp_spot); 00409 if (verbose) 00410 printf("%d: spot has ended\n", line_number); 00411 change_state(previous_state, state, ZONES); 00412 temp_spot.clear(); 00413 } 00414 } 00415 else{ 00416 //WAYPOINT 00417 sprintf(temp_char, "%d.%d.", temp_zone.zone_id, temp_spot.spot_id); 00418 if(token.find(temp_char) != std::string::npos ){ 00419 LL_Waypoint wp(lineread, temp_zone.zone_id, 00420 temp_spot.spot_id, line_number, valid, verbose); 00421 temp_spot.waypoints.push_back(wp); 00422 } 00423 else{ 00424 printf("%d: Unexpected token\n", line_number); 00425 valid=false; 00426 } 00427 } 00428 break; 00429 case UNKNOWN: 00430 printf("%d: Unexpected token\n", line_number); 00431 valid=false; 00432 } 00433 if (!valid) { 00434 is_valid=false; 00435 print_error_message(line_number, token); 00436 return; 00437 } 00438 } 00439 prep_graph(); 00440 if (verbose) printf("Parser Finishes\n"); 00441 } 00442 00443 MDF::MDF(std::string mdfname, bool verbose) 00444 { 00445 verbose=verbose; 00446 00447 is_valid=true; 00448 00449 if (verbose) printf("MDF Parser Begins\n"); 00450 00451 std::ifstream mdf_file; 00452 mdf_file.open(mdfname.c_str()); 00453 if (!mdf_file){ 00454 printf("Error in opening MDF file\n"); 00455 is_valid=false; 00456 return; 00457 } 00458 00459 //Parser State 00460 line_number = 0; 00461 MDF_PARSE_STATE state = MDF_UNKNOWN, previous_state = MDF_UNKNOWN; 00462 00463 std::string lineread; 00464 while(getline(mdf_file, lineread) ) // Read line by line 00465 { 00466 00467 line_number++; 00468 00469 uint real_characters=0; 00470 00471 for (uint ind=0; ind < lineread.length(); ind++) 00472 if (lineread[ind] != '\r' && 00473 lineread[ind] != '\t' && 00474 lineread[ind] != ' ') 00475 real_characters++; 00476 00477 00478 //Blank lines 00479 if (real_characters == 0) { 00480 if (verbose) 00481 printf("%d: Blank Line\n",line_number); 00482 continue; 00483 } 00484 00485 std::string token; 00486 char token_char [lineread.size()+1]; 00487 // char temp_char [lineread.size()+1]; 00488 00489 //Read in one line 00490 sscanf(lineread.c_str(), "%s", token_char); 00491 token.assign(token_char); 00492 00493 00494 if (state != MDF_COMMENT){ 00495 if (token.compare("MDF_name") == 0) 00496 change_state(previous_state, state, MDF_GENERAL); 00497 else if (token.compare(0, 11, "checkpoints") == 0) 00498 change_state(previous_state, state, MDF_CHECKPOINTS); 00499 else if (token.compare(0, 12, "speed_limits") == 0) 00500 change_state(previous_state, state, MDF_SPEEDLIMITS); 00501 else if (token.find("/*") != std::string::npos) 00502 change_state(previous_state, state, MDF_COMMENT); 00503 } 00504 00505 bool valid=true; 00506 switch (state){ 00507 case MDF_COMMENT: 00508 if (verbose) 00509 printf("%d: COMMENT: %s\n", line_number, lineread.c_str()); 00510 if (lineread.find("*/") != std::string::npos) 00511 state = previous_state; 00512 break; 00513 case MDF_GENERAL: 00514 if (token.compare("MDF_name") == 0) 00515 filename = 00516 parse_string(lineread, std::string("MDF_name"), 00517 line_number, valid, verbose); 00518 else if (token.compare("RNDF") == 0) 00519 RNDF_name = 00520 parse_string(lineread, std::string("RNDF"), 00521 line_number, valid, verbose); 00522 else if (token.compare("format_version") == 0) 00523 format_version = 00524 parse_string(lineread, std::string("format_version"), 00525 line_number, valid, verbose); 00526 else if (token.compare("creation_date") == 0) 00527 creation_date = 00528 parse_string(lineread, std::string("creation_date"), 00529 line_number, valid, verbose); 00530 else if (token.compare("end_file") == 0){ 00531 if (!isvalid()){ 00532 printf("%d: MDF Properties are not valid\n", line_number); 00533 valid = false; 00534 } 00535 if (verbose) 00536 printf("%d: MDF file has finished parsing\n", line_number); 00537 } 00538 else{ 00539 printf("%d: Unexpected token\n", line_number); 00540 valid=false; 00541 } 00542 break; 00543 case MDF_SPEEDLIMITS: 00544 if(token.compare(0, 12, "speed_limits") == 0){ 00545 if (verbose) 00546 printf("%d: Speed Limits\n", line_number); 00547 } 00548 else if(token.compare(0, 16, "num_speed_limits") == 0){ 00549 number_of_speedlimits = 00550 parse_integer(lineread, std::string("num_speed_limits"), 00551 line_number, valid, verbose); 00552 if (number_of_speedlimits <= 0) valid = false; 00553 } 00554 else if(token.compare("end_speed_limits") == 0){ 00555 if (number_of_speedlimits != (int) speed_limits.size()) 00556 printf("Number of Speed Limits do not match num_speedlimits\n"); 00557 else if (verbose) 00558 printf("%d: End of Speed Limits\n", line_number); 00559 change_state(previous_state, state, MDF_GENERAL); 00560 } 00561 else{ 00562 Speed_Limit speedlimit(lineread, line_number, valid, verbose); 00563 if (valid) speed_limits.push_back(speedlimit); 00564 else { 00565 printf("%d: Unexpected token\n", line_number); 00566 valid = false; 00567 } 00568 } 00569 break; 00570 case MDF_CHECKPOINTS: 00571 if(token.compare(0, 11, "checkpoints") == 0){ 00572 if (verbose) 00573 printf("%d: Checkpoints\n", line_number); 00574 } 00575 else if(token.compare("num_checkpoints") == 0){ 00576 number_of_checkpoints = 00577 parse_integer(lineread, std::string("num_checkpoints"), 00578 line_number, valid, verbose); 00579 if (number_of_checkpoints <= 0) valid = false; 00580 } 00581 else if(token.compare("end_checkpoints") == 0){ 00582 if (number_of_checkpoints != (int) checkpoint_ids.size()) 00583 printf("Number of Checkpoints do not match num_checkpoints\n"); 00584 else if (verbose) 00585 printf("%d: Checkpoints have ended\n", line_number); 00586 change_state(previous_state, state, MDF_GENERAL); 00587 } 00588 //NO TOKEN 00589 else{ 00590 //CHECKPOINT 00591 int checkpoint_id = 00592 parse_integer(lineread, line_number, valid, verbose); 00593 if (valid) checkpoint_ids.push_back(checkpoint_id); 00594 else { 00595 printf("%d: Unexpected token\n", line_number); 00596 valid = false; 00597 } 00598 if (checkpoint_id <= 0) valid = false; 00599 } 00600 break; 00601 case MDF_UNKNOWN: 00602 printf("%d: COULD NOT PARSE: %s\n", line_number, lineread.c_str()); 00603 valid = false; 00604 } 00605 if (!valid) { 00606 is_valid=false; 00607 print_error_message(line_number, token); 00608 return; 00609 } 00610 } 00611 00612 if (verbose) printf("MDF Parser Finishes\n"); 00613 00614 } 00615 00616 Lane_marking RNDF::parse_boundary(std::string line, bool& valid){ 00617 Lane_marking boundary_type = UNDEFINED; 00618 char temp_char [line.size()+1]; 00619 if (!sscanf(line.c_str(), "%*s %s", temp_char) == 1) 00620 valid = false; 00621 if (strcmp(temp_char, "double_yellow") == 0) 00622 boundary_type = DOUBLE_YELLOW; 00623 else if (strcmp(temp_char, "solid_yellow") == 0) 00624 boundary_type = SOLID_YELLOW; 00625 else if (strcmp(temp_char, "solid_white") == 0) 00626 boundary_type = SOLID_WHITE; 00627 else if (strcmp(temp_char, "broken_white") == 0) 00628 boundary_type = BROKEN_WHITE; 00629 else 00630 valid=false; 00631 return boundary_type; 00632 00633 }; 00634 00635 Checkpoint::Checkpoint(std::string line, int x, int y, 00636 int line_number, bool& valid, bool verbose) { 00637 char temp_char [line.size()+1]; 00638 sprintf(temp_char,"checkpoint %d.%d.%%d %%d" ,x, y); 00639 if (sscanf(line.c_str(), temp_char, &waypoint_id, &checkpoint_id) == 2 && 00640 isvalid()){ 00641 if (verbose){ 00642 printf("%d: ", line_number); 00643 print(); 00644 } 00645 } 00646 else{ 00647 // clear(); 00648 valid=false; 00649 } 00650 }; 00651 00652 LL_Waypoint::LL_Waypoint(std::string line, int x, int y, 00653 int line_number, bool& valid, bool verbose) { 00654 00655 char temp_char [line.size()+1]; 00656 sprintf(temp_char, "%d.%d.%%d %%lf %%lf", x, y); 00657 if(sscanf(line.c_str(), temp_char, &waypoint_id, &ll.latitude, &ll.longitude) == 3 && isvalid()){ 00658 if (verbose) { 00659 printf("%d: ", line_number); 00660 print(); 00661 } 00662 } 00663 else{ 00664 // clear(); 00665 valid=false; 00666 } 00667 }; 00668 00669 00670 00671 Exit::Exit(std::string line, int x, int y, int line_number, bool& valid, 00672 bool verbose) { 00673 00674 char temp_char [line.size()+1]; 00675 sprintf(temp_char,"exit %d.%d.%%d %%d.%%d.%%d", x, y); 00676 start_point.segment_id = x; 00677 start_point.lane_id = y; 00678 if (sscanf(line.c_str(), temp_char, &start_point.waypoint_id, 00679 &end_point.segment_id, &end_point.lane_id, 00680 &end_point.waypoint_id) == 4 && isvalid()){ 00681 if (verbose){ 00682 printf("%d: ", line_number); 00683 print(); 00684 } 00685 } 00686 else{ 00687 // clear(); 00688 // start_point.segment_id = x; 00689 // start_point.lane_id = y; 00690 valid=false; 00691 } 00692 }; 00693 00694 Speed_Limit::Speed_Limit(std::string line, int line_number, bool& valid, 00695 bool verbose){ 00696 if (sscanf(line.c_str(), "%d %d %d", &id, &min_speed, &max_speed) == 3 && isvalid()){ 00697 if (verbose){ 00698 printf("%d: ", line_number); 00699 print(); 00700 } 00701 } 00702 else{ 00703 // clear(); 00704 valid=false; 00705 } 00706 }; 00707 00708 Stop::Stop(std::string line, int x, int y, 00709 int line_number, bool& valid, bool verbose){ 00710 // clear() 00711 char temp_char [line.size()+1]; 00712 sprintf(temp_char,"stop %d.%d.%%d" , x, y); 00713 if (sscanf(line.c_str(), temp_char, &waypoint_id) == 1 && isvalid()){ 00714 if (verbose) 00715 printf("%d: Stop at Waypoint %d\n", 00716 line_number, waypoint_id); 00717 } 00718 else{ 00719 // clear(); 00720 valid=false; 00721 } 00722 }; 00723 00724 00725 std::string parse_string(std::string line, std::string token, 00726 int line_number, bool& valid, bool verbose){ 00727 char temp_char [line.size()+1]; 00728 temp_char[0]='\0'; 00729 if (sscanf(line.c_str(), "%*s %s", temp_char)){ 00730 if (verbose) 00731 printf("%d: %s is %s\n", line_number, token.c_str(), temp_char); 00732 } 00733 else 00734 valid=false; 00735 00736 return std::string(temp_char); 00737 }; 00738 00739 //WITH STRING TOKEN 00740 int parse_integer(std::string line, std::string token, 00741 int line_number, bool& valid, bool verbose){ 00742 int integer = INT_MIN; 00743 if (sscanf(line.c_str(), "%*s %d", &integer) == 1){ 00744 if (verbose) 00745 printf("%d: %s is %d\n", line_number, token.c_str(), integer); 00746 } 00747 else 00748 valid=false; 00749 00750 if (integer == INT_MIN) valid = false; 00751 return integer; 00752 }; 00753 00754 //WITHOUT TOKEN 00755 int parse_integer(std::string line, int line_number, bool& valid, 00756 bool verbose){ 00757 int integer = INT_MIN; 00758 if (sscanf(line.c_str(), "%d", &integer) == 1){ 00759 if (verbose) 00760 printf("%d: %d\n", line_number, integer); 00761 } 00762 else 00763 valid=false; 00764 if (integer == INT_MIN) valid = false; 00765 return integer; 00766 }; 00767 00768 void Lane::clear(){ 00769 waypoints.clear(); 00770 checkpoints.clear(); 00771 stops.clear(); 00772 exits.clear(); 00773 left_boundary = right_boundary = UNDEFINED; 00774 lane_id = number_of_waypoints = INT_MIN; 00775 lane_width = 0; 00776 }; 00777 00778 void Segment::clear(){ 00779 lanes.clear(); 00780 segment_name = std::string("default"); 00781 segment_id = number_of_lanes = INT_MIN; 00782 }; 00783 00784 void Zone::clear(){ 00785 zone_id = number_of_parking_spots = INT_MIN; 00786 zone_name = std::string("default"); 00787 perimeter.clear(); 00788 spots.clear(); 00789 }; 00790 00791 void Spot::clear(){ 00792 spot_id = INT_MIN; 00793 spot_width = 0; 00794 checkpoint.clear(); 00795 waypoints.clear(); 00796 }; 00797 00798 void Perimeter::clear(){ 00799 perimeter_id = number_of_perimeterpoints = INT_MIN; 00800 exits_from_perimeter.clear(); 00801 perimeterpoints.clear(); 00802 00803 }; 00804 00805 void RNDF::print(){ 00806 00807 if (!is_valid) { 00808 printf("RNDF not valid\n"); 00809 return; 00810 } 00811 00812 printf("RNDF name is %s\n", filename.c_str()); 00813 printf("Number of segments is %d\n", number_of_segments); 00814 printf("Number of zones is %d\n", number_of_zones); 00815 printf("format version is %s\n", format_version.c_str()); 00816 printf("creation date is %s\n", creation_date.c_str()); 00817 print_vector(segments); 00818 print_vector(zones); 00819 }; 00820 00821 void MDF::print(){ 00822 00823 if (!is_valid) { 00824 printf("MDF not valid\n"); 00825 return; 00826 } 00827 00828 printf("MDF name is %s\n", filename.c_str()); 00829 printf("RNDF name is %s\n", RNDF_name.c_str()); 00830 printf("format version is %s\n", format_version.c_str()); 00831 printf("creation date is %s\n", creation_date.c_str()); 00832 printf("Number of checkpoints is %d\n", number_of_checkpoints); 00833 std::vector<int>::iterator i; 00834 for(i = checkpoint_ids.begin(); i != checkpoint_ids.end(); i++) 00835 printf("Checkpoint id: %d\n", *i); 00836 00837 printf("Number of speedlimits is %d\n", number_of_speedlimits); 00838 print_vector(speed_limits); 00839 }; 00840 00841 void Segment::print(){ 00842 00843 printf("Segment number is %d\n", segment_id); 00844 printf("Number of Lanes in Segment %d\n", number_of_lanes); 00845 printf("segment name is %s\n", segment_name.c_str()); 00846 print_vector(lanes); 00847 }; 00848 00849 void Lane::print(){ 00850 00851 printf("Lane number is %d\n", lane_id); 00852 printf("Number of Waypoints in lane %d\n", number_of_waypoints); 00853 printf("Width of lane %d\n", lane_width); 00854 printf("left boundary type is %d\n", left_boundary); 00855 printf("right boundary type is %d\n", right_boundary); 00856 print_vector(checkpoints); 00857 print_vector(stops); 00858 print_vector(exits); 00859 print_vector(waypoints); 00860 }; 00861 00862 void Exit::print(){ 00863 00864 printf("Exit from "); 00865 start_point.print(); 00866 00867 printf(" to "); 00868 end_point.print(); 00869 00870 printf("\n"); 00871 }; 00872 00873 void Spot::print(){ 00874 00875 printf("Spot id is %d\n", spot_id); 00876 printf("Spot width is %d\n", spot_width); 00877 printf("Spot Checkpoint is: "); 00878 checkpoint.print(); 00879 printf("Spot - First waypoint: "); 00880 waypoints[0].print_without_newline(); 00881 printf(",Second waypoint: "); 00882 waypoints[1].print_without_newline(); 00883 printf("\n"); 00884 }; 00885 00886 void Zone::print(){ 00887 00888 printf("Zone number is %d\n", zone_id); 00889 printf("Number of parking spots is %d\n", 00890 number_of_parking_spots); //integer >= 0 00891 printf("Zone name is %s\n", zone_name.c_str()); //Designate the 00892 //zone, such as 00893 //"North_Parking_Lot" 00894 perimeter.print(); 00895 print_vector(spots); 00896 }; 00897 00898 void Perimeter::print(){ 00899 00900 printf("Perimeter id is %d\n", perimeter_id); //integer ALWAYS 0 00901 00902 printf("Number of perimeter points is %d\n", number_of_perimeterpoints); 00903 print_vector(exits_from_perimeter); 00904 print_vector(perimeterpoints); 00905 }; 00906 00907 void Speed_Limit::print(){ 00908 00909 printf("Speed Limit id: %d", id); //integer > 0 00910 printf(", min_speed is %d", min_speed); //integer >= 0 00911 printf(", max_speed is %d\n", max_speed); //integer >= 0 00912 } 00913 00914 template <class T> 00915 void print_vector (std::vector<T> vec) { 00916 typename std::vector<T>::iterator i; 00917 for(i = vec.begin(); i != vec.end(); i++) 00918 i->print(); 00919 }; 00920 00921 00922 void RNDF::prep_graph(){ 00923 00924 int index = 0; 00925 std::vector<Segment>::iterator si; 00926 std::vector<Lane>::iterator li; 00927 std::vector<LL_Waypoint>::iterator wi; 00928 std::vector<Checkpoint>::iterator ci; 00929 std::vector<Stop>::iterator stops_i; 00930 std::vector<Exit>::iterator exits_i; 00931 std::vector<Zone>::iterator zones_i; 00932 std::vector<Spot>::iterator spots_i; 00933 std::vector<Perimeter_Point>::iterator peri_i; 00934 std::vector<WayPointNode>::iterator wpni; 00935 std::vector<ElementID>::iterator eid_i; 00936 00937 //-----VERTICES------- 00938 for(si = segments.begin(); si != segments.end(); si++){ 00939 for(li = si->lanes.begin(); li != si->lanes.end(); li++){ 00940 for(wi = li->waypoints.begin(); wi != li->waypoints.end(); wi++){ 00941 WayPointNode wpn; 00942 wpn.ll = wi->ll; 00943 if (li->lane_width == 0) 00944 wpn.lane_width = DEFAULT_LANE_WIDTH; 00945 else wpn.lane_width = feet2meters(li->lane_width); 00946 wpn.id = ElementID(si->segment_id, li->lane_id, wi->waypoint_id); 00947 wpn.index = index; 00948 index++; 00949 id_map[wpn.id] = (wpn); 00950 } 00951 } 00952 } 00953 00954 for(zones_i = zones.begin(); zones_i != zones.end(); zones_i++){ 00955 for(spots_i = zones_i->spots.begin(); 00956 spots_i != zones_i->spots.end(); spots_i++){ 00957 for(wi = spots_i->waypoints.begin(); 00958 wi != spots_i->waypoints.end(); wi++){ 00959 WayPointNode wpn; 00960 wpn.ll = wi->ll; 00961 wpn.id = ElementID(zones_i->zone_id, spots_i->spot_id, 00962 wi->waypoint_id); 00963 if (spots_i->checkpoint.waypoint_id == wi->waypoint_id){ 00964 wpn.is_goal = true; 00965 wpn.checkpoint_id = spots_i->checkpoint.checkpoint_id; 00966 } 00967 else wpn.is_goal = false; 00968 wpn.is_spot = true; 00969 if (spots_i->spot_width == 0) 00970 wpn.lane_width = DEFAULT_SPOT_WIDTH; 00971 else wpn.lane_width = feet2meters(spots_i->spot_width); 00972 wpn.is_stop = wpn.is_exit = wpn.is_entry = false; 00973 wpn.index = index; 00974 index++; 00975 id_map[wpn.id] = (wpn); 00976 } 00977 } 00978 } 00979 00980 00981 for(zones_i = zones.begin(); zones_i != zones.end(); zones_i++){ 00982 for(peri_i = zones_i->perimeter.perimeterpoints.begin(); 00983 peri_i != zones_i->perimeter.perimeterpoints.end(); peri_i++){ 00984 WayPointNode wpn; 00985 wpn.ll = peri_i->ll; 00986 wpn.id = ElementID(zones_i->zone_id, zones_i->perimeter.perimeter_id, 00987 peri_i->waypoint_id); 00988 wpn.is_perimeter = true; 00989 wpn.lane_width = DEFAULT_LANE_WIDTH; 00990 wpn.is_stop = wpn.is_exit = wpn.is_entry = false; 00991 wpn.index = index; 00992 index++; 00993 id_map[wpn.id] = (wpn); 00994 } 00995 } 00996 00997 for(zones_i = zones.begin(); zones_i != zones.end(); zones_i++){ 00998 for(exits_i = zones_i->perimeter.exits_from_perimeter.begin(); 00999 exits_i != zones_i->perimeter.exits_from_perimeter.end(); exits_i++){ 01000 ElementID id_start (exits_i->start_point.segment_id, 01001 exits_i->start_point.lane_id, 01002 exits_i->start_point.waypoint_id); 01003 ElementID id_end (exits_i->end_point.segment_id, 01004 exits_i->end_point.lane_id, 01005 exits_i->end_point.waypoint_id); 01006 if (id_map.find(id_start) == id_map.end() || 01007 id_map.find(id_end) == id_map.end()) { 01008 exit_error(*exits_i); 01009 is_valid=false; 01010 return; 01011 } 01012 id_map[id_start].is_exit = true; 01013 id_map[id_end].is_entry = true; 01014 } 01015 } 01016 01017 for(si = segments.begin(); si != segments.end(); si++){ 01018 for(li = si->lanes.begin(); li != si->lanes.end(); li++){ 01019 for(ci = li->checkpoints.begin(); ci != li->checkpoints.end(); ci++){ 01020 ElementID id (si->segment_id, li->lane_id, ci->waypoint_id); 01021 if (id_map.find(id) == id_map.end()) { 01022 checkpoint_error(si->segment_id, li->lane_id, ci->waypoint_id); 01023 is_valid=false; 01024 return; 01025 } 01026 id_map[id].checkpoint_id = ci->checkpoint_id; 01027 id_map[id].is_goal = false; 01028 } 01029 for(stops_i = li->stops.begin(); stops_i != li->stops.end(); stops_i++){ 01030 ElementID id (si->segment_id, li->lane_id, stops_i->waypoint_id); 01031 if (id_map.find(id) == id_map.end()) { 01032 stop_error(si->segment_id, li->lane_id, stops_i->waypoint_id); 01033 is_valid=false; 01034 return; 01035 } 01036 id_map[id].is_stop = true; 01037 } 01038 for(exits_i = li->exits.begin(); exits_i != li->exits.end(); exits_i++){ 01039 ElementID id_start (exits_i->start_point.segment_id, 01040 exits_i->start_point.lane_id, 01041 exits_i->start_point.waypoint_id); 01042 ElementID id_end (exits_i->end_point.segment_id, 01043 exits_i->end_point.lane_id, 01044 exits_i->end_point.waypoint_id); 01045 if (id_map.find(id_start) == id_map.end() || id_map.find(id_end) == 01046 id_map.end()) { 01047 exit_error(*exits_i); 01048 is_valid=false; 01049 return; 01050 } 01051 id_map[id_start].is_exit = true; 01052 id_map[id_end].is_entry = true; 01053 } 01054 } 01055 } 01056 01057 //-----EDGES------- 01058 //-----LANES 01059 for(si = segments.begin(); si != segments.end(); si++){ 01060 for(li = si->lanes.begin(); li != si->lanes.end(); li++){ 01061 for(wi = li->waypoints.begin(); wi != li->waypoints.end() -1; wi++){ 01062 ElementID id_start (si->segment_id, li->lane_id, wi->waypoint_id); 01063 ElementID id_end (si->segment_id, li->lane_id, (wi+1)->waypoint_id); 01064 if (id_map.find(id_start) == id_map.end() || 01065 id_map.find(id_end) == id_map.end()) { 01066 exit_error(*exits_i); 01067 is_valid=false; 01068 return; 01069 } 01070 edges.push_back( WayPointEdge(id_map[id_start], id_map[id_end], 01071 li->left_boundary, 01072 li->right_boundary, false)); 01073 } 01074 } 01075 } 01076 //-----EXITS 01077 for(si = segments.begin(); si != segments.end(); si++){ 01078 for(li = si->lanes.begin(); li != si->lanes.end(); li++){ 01079 for(exits_i = li->exits.begin(); exits_i != li->exits.end(); exits_i++){ 01080 ElementID id_start (exits_i->start_point.segment_id, 01081 exits_i->start_point.lane_id, 01082 exits_i->start_point.waypoint_id); 01083 ElementID id_end (exits_i->end_point.segment_id, 01084 exits_i->end_point.lane_id, 01085 exits_i->end_point.waypoint_id); 01086 if (id_map.find(id_start) == id_map.end() || 01087 id_map.find(id_end) == id_map.end()) { 01088 exit_error(*exits_i); 01089 is_valid=false; 01090 return; 01091 } 01092 if (id_start.seg==id_end.seg && 01093 id_start.lane==id_end.lane && 01094 id_start.pt+1==id_end.pt) 01095 for (uint i=0; i<edges.size(); i++) 01096 { 01097 if (edges.at(i).startnode_index==id_map[id_start].index && 01098 edges.at(i).endnode_index==id_map[id_end].index) 01099 { 01100 edges.at(i).is_exit=true; 01101 break; 01102 } 01103 } 01104 else 01105 edges.push_back(WayPointEdge(id_map[id_start], id_map[id_end], 01106 li->left_boundary, 01107 li->right_boundary, true)); 01108 } 01109 } 01110 } 01111 01112 //-----ZONES 01113 std::vector<ElementID> zone_exits; 01114 for(zones_i = zones.begin(); zones_i != zones.end(); zones_i++){ 01115 for(exits_i = zones_i->perimeter.exits_from_perimeter.begin(); 01116 exits_i != zones_i->perimeter.exits_from_perimeter.end(); exits_i++){ 01117 ElementID id_start (exits_i->start_point.segment_id, 01118 exits_i->start_point.lane_id, 01119 exits_i->start_point.waypoint_id); 01120 ElementID id_end (exits_i->end_point.segment_id, 01121 exits_i->end_point.lane_id, 01122 exits_i->end_point.waypoint_id); 01123 if (id_map.find(id_start) == id_map.end() || 01124 id_map.find(id_end) == id_map.end()) { 01125 exit_error(*exits_i); 01126 is_valid=false; 01127 return; 01128 } 01129 edges.push_back( WayPointEdge(id_map[id_start], id_map[id_end], 01130 UNDEFINED, UNDEFINED, true)); 01131 zone_exits.push_back(id_map[id_start].id); 01132 } 01133 } 01134 01135 01136 //HANDLING EDGES FROM ZONE START TO ZONE END 01137 id_to_waypoint_map::iterator node_itr, node_itr2; 01138 for(node_itr = id_map.begin(); node_itr != id_map.end(); node_itr++){ 01139 //If the node is an entry 01140 if (node_itr->second.is_entry && node_itr->second.is_perimeter) { 01141 for(node_itr2 = id_map.begin(); node_itr2 != id_map.end(); node_itr2++){ 01142 if (node_itr2->second.id!=node_itr->second.id && node_itr2->second.is_perimeter && 01143 node_itr2->second.is_exit) 01144 //Check if they are in the same zone 01145 if(node_itr2->second.id.seg == node_itr->second.id.seg && 01146 node_itr2->second.id.pt != node_itr->second.id.pt) { 01147 edges.push_back(WayPointEdge(node_itr->second, node_itr2->second, 01148 UNDEFINED, UNDEFINED, false)); 01149 } 01150 } 01151 } 01152 } 01153 for(node_itr = id_map.begin(); node_itr != id_map.end(); node_itr++){ 01154 if (node_itr->second.is_exit || node_itr->second.is_entry) 01155 for(node_itr2 = id_map.begin(); node_itr2 != id_map.end(); node_itr2++){ 01156 if (node_itr2->second.id != node_itr->second.id) 01157 if (node_itr2->second.is_spot) 01158 if ((node_itr->second.id.seg == 01159 node_itr2->second.id.seg) && 01160 (node_itr2->second.id.pt==1)) 01161 { 01162 if (node_itr->second.is_exit) 01163 edges.push_back( WayPointEdge(node_itr2->second, node_itr->second, 01164 UNDEFINED, UNDEFINED, false)); 01165 if (node_itr->second.is_entry) 01166 edges.push_back 01167 (WayPointEdge(node_itr->second, node_itr2->second, 01168 UNDEFINED, UNDEFINED, false)); 01169 } 01170 } 01171 } 01172 01173 for(node_itr = id_map.begin(); node_itr != id_map.end(); node_itr++){ 01174 //If the node is an entry 01175 if (node_itr->second.is_spot) 01176 for(node_itr2 = id_map.begin(); node_itr2 != id_map.end(); node_itr2++){ 01177 if (node_itr2->second.id != node_itr->second.id) 01178 if (node_itr2->second.is_spot) { 01179 if ((node_itr->second.id.seg== 01180 node_itr2->second.id.seg) && 01181 (node_itr->second.id.lane== 01182 node_itr2->second.id.lane) && 01183 (node_itr->second.id.pt==1) && 01184 (node_itr2->second.id.pt==2)) 01185 { 01186 edges.push_back( WayPointEdge(node_itr->second, node_itr2->second, 01187 UNDEFINED, UNDEFINED, false)); 01188 edges.push_back( WayPointEdge(node_itr2->second, node_itr->second, 01189 UNDEFINED, UNDEFINED, false)); 01190 } 01191 if ((node_itr->second.id.seg== 01192 node_itr2->second.id.seg) && 01193 (node_itr->second.id.lane!= 01194 node_itr2->second.id.lane) && 01195 (node_itr->second.id.pt==1) && 01196 (node_itr2->second.id.pt==1)) 01197 { 01198 edges.push_back( WayPointEdge(node_itr->second, node_itr2->second, 01199 UNDEFINED, UNDEFINED, false)); 01200 edges.push_back( WayPointEdge(node_itr2->second, node_itr->second, 01201 UNDEFINED, UNDEFINED, false)); 01202 } 01203 } 01204 } 01205 } 01206 } 01207 01213 void RNDF::populate_graph(Graph& graph) 01214 { 01215 graph.nodes_size = id_map.size(); 01216 graph.nodes = new WayPointNode[graph.nodes_size]; 01217 id_to_waypoint_map::iterator node_itr; 01218 for(node_itr = id_map.begin(); node_itr != id_map.end(); node_itr++){ 01219 graph.nodes[(node_itr->second).index] = (node_itr->second); 01220 } 01221 01222 graph.edges_size = edges.size(); 01223 graph.edges = edges; 01224 /* 01225 std::vector<WayPointEdge>::iterator edge_itr; 01226 int edge_index = 0; 01227 for(edge_itr = edges.begin(); edge_itr != edges.end(); edge_itr++){ 01228 graph.edges[edge_index] = (*edge_itr); 01229 edge_index++; 01230 } 01231 */ 01232 } 01233 01234 01235 //ISSUE: What should the SpeedLimits of Exits be 01236 bool MDF::add_speed_limits(Graph& graph){ 01237 std::vector<Speed_Limit>::iterator itr; 01238 int num_speed_limits = (int)speed_limits.size(); 01239 int matches = 0; 01240 Speed_Limit matched, current; 01241 01242 for (uint i = 0; i < graph.edges_size; i++){ 01243 graph.edges[i].speed_min = 0.0; 01244 graph.edges[i].speed_max = DEFAULT_LANE_SPEED; 01245 } 01246 01247 for(itr = speed_limits.begin(); itr != speed_limits.end(); itr++){ 01248 current = *itr; 01249 for (uint i = 0; i < graph.edges_size; i++){ 01250 int index = graph.edges[i].startnode_index; 01251 // assert(index < graph.nodes_size); 01252 01253 if(graph.nodes[index].id.seg == itr->id){ 01254 if (itr->min_speed < Epsilon::speed) 01255 graph.edges[i].speed_min = 0.0; 01256 else 01257 graph.edges[i].speed_min = mph2mps(itr->min_speed); 01258 01259 if (itr->max_speed < Epsilon::speed) 01260 graph.edges[i].speed_max = fmax(graph.edges[i].speed_min, 01261 DEFAULT_LANE_SPEED); 01262 else 01263 graph.edges[i].speed_max = fmax(graph.edges[i].speed_min, 01264 mph2mps(itr->max_speed)); 01265 01266 if (!(matched == current)){ 01267 matches++; 01268 matched = current; 01269 } 01270 } 01271 } 01272 } 01273 01274 #if 0 01275 for (uint i = 0; i < graph.edges_size; i++){ 01276 std::cerr << graph.nodes[graph.edges[i].startnode_index].id.seg 01277 <<" "<<graph.edges[i].speed_min<<" " 01278 <<graph.edges[i].speed_max<<std::endl; 01279 } 01280 #endif 01281 01282 if (matches == num_speed_limits) 01283 return true; 01284 else{ 01285 //printf("[%d] != [%d]\n", matches, num_speed_limits); 01286 return false; 01287 } 01288 } 01289 01290 void exit_error(Exit& ex){ 01291 01292 printf("ERROR: In Exit from %d.%d.%d to %d.%d.%d.", 01293 ex.start_point.segment_id, ex.start_point.lane_id, 01294 ex.start_point.waypoint_id, 01295 ex.end_point.segment_id, ex.end_point.lane_id, 01296 ex.end_point.waypoint_id); 01297 printf(" One of the WayPoints is not defined.\n"); 01298 } 01299 01300 void stop_error(int seg, int lane, int way){ 01301 01302 printf("ERROR: In Stop %d.%d.%d - The WayPoint is not defined\n", 01303 seg, lane, way); 01304 } 01305 01306 void checkpoint_error(int seg, int lane, int way){ 01307 01308 printf("ERROR: In Checkpoint %d.%d.%d - The WayPoint is not defined\n", 01309 seg, lane, way); 01310 } 01311 01312 void print_error_message(int line_number, std::string token){ 01313 printf("%d: Invalid %s\n", line_number, token.c_str()); 01314 } 01315