00001
00002
00003
00004
00005
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
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
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))
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
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
00090 sscanf(lineread.c_str(), "%s", token_char);
00091 token.assign(token_char);
00092
00093
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
00122 if (token.compare("RNDF_name") == 0)
00123 filename =
00124 parse_string(lineread, std::string("RNDF_name"),
00125 line_number, valid, verbose);
00126
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
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
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
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
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
00158 else {
00159 printf("%d: Unexpected token\n", line_number);
00160 valid=false;
00161 }
00162 break;
00163 case SEGMENTS:
00164
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
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
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
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
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
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
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
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
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
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
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
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
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
00276 else{
00277
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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) )
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
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
00488
00489
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
00589 else{
00590
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
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
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
00688
00689
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
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
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
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
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
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);
00891 printf("Zone name is %s\n", zone_name.c_str());
00892
00893
00894 perimeter.print();
00895 print_vector(spots);
00896 };
00897
00898 void Perimeter::print(){
00899
00900 printf("Perimeter id is %d\n", perimeter_id);
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);
00910 printf(", min_speed is %d", min_speed);
00911 printf(", max_speed is %d\n", max_speed);
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
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
01058
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
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
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
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
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
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
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
01226
01227
01228
01229
01230
01231
01232 }
01233
01234
01235
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
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
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