00001
00002
00003
00004
00005
00006 #include <iostream>
00007 #include <float.h>
00008
00009 #include <art/UTM.h>
00010 #include <art_map/euclidean_distance.h>
00011 #include <art_map/Graph.h>
00012
00013 WayPointEdgeList Graph::edges_from(const waypt_index_t index) const {
00014 WayPointEdgeList new_edges;
00015 for(uint i=0; i<edges_size; i++) {
00016 if(edges[i].startnode_index == index)
00017 new_edges.push_back(edges[i]);
00018 }
00019 return new_edges;
00020 };
00021
00022 WayPointEdgeList Graph::edges_leaving_segment(const segment_id_t seg) const {
00023 WayPointEdgeList new_edges;
00024 for(uint i=0; i<edges_size; i++) {
00025 if(get_node_by_index(edges[i].startnode_index)->id.seg == seg)
00026 new_edges.push_back(edges[i]);
00027 }
00028 return new_edges;
00029 };
00030
00031 WayPointNode* Graph::get_node_by_index(const waypt_index_t index) const {
00032 for(uint i=0; i<nodes_size; i++)
00033 if(nodes[i].index == index)
00034 return &nodes[i];
00035 return NULL;
00036 };
00037
00038 WayPointNode* Graph::get_node_by_id(const ElementID id) const {
00039 for(uint i=0; i<nodes_size; i++) {
00040 if(nodes[i].id == id)
00041 return &nodes[i];
00042 }
00043 return NULL;
00044 };
00045
00046 WayPointNode* Graph::get_closest_node(const MapXY &p) const {
00047 WayPointNode* closest = NULL;
00048 float distance = 0;
00049 float new_distance = 0;
00050 for(uint i=0; i<nodes_size; i++) {
00051 new_distance = Euclidean::DistanceTo(p, nodes[i].map);
00052 if(closest == NULL || new_distance < distance) {
00053 closest = &nodes[i];
00054 distance = new_distance;
00055 }
00056 }
00057 return closest;
00058 };
00059
00060 WayPointNode* Graph::get_closest_node_within_radius(const MapXY &p) const {
00061 WayPointNode* closest = NULL;
00062 float distance = 0;
00063 float new_distance = 0;
00064 for(uint i=0; i<nodes_size; i++) {
00065 new_distance = Euclidean::DistanceTo(p, nodes[i].map);
00066 if((closest == NULL || new_distance < distance)
00067 && (new_distance < nodes[i].lane_width)) {
00068 closest = &nodes[i];
00069 distance = new_distance;
00070 }
00071 }
00072 return closest;
00073 };
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 void Graph::save(const char* fName){
00117 WayPointNode node;
00118 WayPointEdge edge;
00119 FILE* f = fopen(fName,"wb");
00120 fprintf(f, "GRAPH-STATE\n");
00121 fprintf(f, "Node_Number %d\n", nodes_size);
00122 fprintf(f, "Edge_Number %d\n", edges_size);
00123 for (uint i = 0; i < nodes_size; i++){
00124 node = nodes[i];
00125 fprintf(f, "Node ");
00126
00127 fprintf(f, "%.10lf, %.10lf; ", node.ll.latitude, node.ll.longitude);
00128
00129 fprintf(f, "%f, %f; ", node.map.x, node.map.y);
00130
00131 fprintf(f, "%d, %d, %d; ", node.id.seg, node.id.lane, node.id.pt);
00132
00133 fprintf(f, "%d; ", node.index);
00134
00135 fprintf(f, "%d, %d, %d, %d, %d, %d; ", node.is_entry, node.is_exit, node.is_goal, node.is_spot, node.is_stop, node.is_perimeter);
00136
00137 fprintf(f, "%d; ", node.checkpoint_id);
00138
00139 fprintf(f, "%f; ", node.lane_width);
00140
00141 fprintf(f, "\n");
00142
00143 }
00144 for (uint i = 0; i < edges_size; i++){
00145 edge = edges[i];
00146 fprintf(f, "Edge ");
00147
00148 fprintf(f, "%d, %d; ", edge.startnode_index, edge.endnode_index);
00149
00150 fprintf(f, "%f; ", edge.distance);
00151
00152 fprintf(f, "%f, %f; ", edge.speed_max, edge.speed_min);
00153
00154 fprintf(f, "%d; ", edge.is_exit);
00155
00156 fprintf(f, "%d, %d; ", edge.left_boundary, edge.right_boundary);
00157
00158 fprintf(f, "\n");
00159 }
00160 fclose (f);
00161 }
00162
00163 bool Graph::load(const char* fName){
00164 WayPointNode node;
00165 WayPointEdge edge;
00166 clear();
00167
00168 std::ifstream graph_file;
00169 graph_file.open(fName);
00170 if (!graph_file){
00171 printf("Error in opening Graph Log file\n");
00172 return false;
00173 }
00174
00175
00176 int number_of_nodes = 0, number_of_edges = 0;
00177 int line_number = 0, current_node = 0, current_edge = 0;
00178 bool valid = true;
00179 std::string lineread;
00180 while(getline(graph_file, lineread) )
00181 {
00182 line_number++;
00183 std::string token;
00184 char token_char [lineread.size()+1];
00185
00186 sscanf(lineread.c_str(), "%s", token_char);
00187 token.assign(token_char);
00188
00189
00190
00191 if (line_number == 1){
00192 if (!(token.compare("GRAPH-STATE") == 0)) return false;
00193 }
00194
00195 else if (line_number == 2){
00196 if (!(token.compare("Node_Number") == 0)) {return false;}
00197 else {
00198 number_of_nodes = parse_integer(lineread, std::string("Node_Number"), valid);
00199 }
00200 if (!valid) return false;
00201 else {
00202 nodes_size = number_of_nodes;
00203 nodes = new WayPointNode[nodes_size];
00204 }
00205 }
00206 else if (line_number == 3){
00207 if (!(token.compare("Edge_Number") == 0)) {return false;}
00208 else {
00209 number_of_edges = parse_integer(lineread, std::string("Edge_Number"), valid);
00210 }
00211 if (!valid) return false;
00212 else {
00213 edges_size = number_of_edges;
00214 edges.resize(edges_size);
00215 }
00216 }
00217 else if (token.compare("Node") == 0){
00218 current_node++;
00219 node = parse_node(lineread, valid);
00220 if (!valid) return false;
00221 else nodes[current_node-1] = node;
00222 }
00223 else if (token.compare("Edge") == 0){
00224 current_edge++;
00225 edge = parse_edge(lineread, valid);
00226 if (!valid) return false;
00227 else edges[current_edge-1] = edge;
00228 }
00229 else return false;
00230 }
00231 if (line_number < 3)return false;
00232 else if (current_node != number_of_nodes) return false;
00233 else if (current_edge != number_of_edges) return false;
00234
00235 else return true;
00236 }
00237
00238 void Graph::clear(){
00239 for(uint i = 0; i < nodes_size; i++)
00240 nodes[i].clear();
00241 nodes_size = 0;
00242 for(uint i = 0; i < edges_size; i++)
00243 edges[i].clear();
00244 edges_size = 0;
00245
00246 }
00247
00248 void Graph::printNodes(){
00249 printf("\nNodes: \n");
00250 for(uint i = 0; i < nodes_size; i++){
00251 printf("%2d: ", nodes[i].index);
00252 printf("%2d.%2d.%2d ", nodes[i].id.seg, nodes[i].id.lane, nodes[i].id.pt);
00253
00254
00255 printf(",Width: %2.3f ", nodes[i].lane_width);
00256 printf("CKPT: %s, STOP: %s", nodes[i].is_goal?"true ":"false",
00257 nodes[i].is_stop?"true ":"false");
00258 printf(", ENTRY: %s, EXIT: %s", nodes[i].is_entry?"true ":"false",
00259 nodes[i].is_exit?"true ":"false");
00260 printf(", SPOT: %s\n", nodes[i].is_spot?"true ":"false");
00261 }
00262 };
00263
00264 void Graph::printEdges(){
00265 printf("\nEdges: \n");
00266 for(uint i = 0; i < edges_size; i++){
00267 printf("%3d: ", i);
00268 printf("%3d to %3d ", edges[i].startnode_index, edges[i].endnode_index);
00269 printf("Boundary- Left:%2d, Right:%2d, ",
00270 edges[i].left_boundary, edges[i].right_boundary);
00271 printf("Speed- Min:%f, Max:%f, ",
00272 edges[i].speed_min, edges[i].speed_max);
00273 printf(",EXIT: %s\n", edges[i].is_exit?"true ":"false");
00274 }
00275 };
00276
00277 void Graph::printNodesFile(const char* fName){
00278 FILE* f = fopen(fName,"wb");
00279 fprintf(f,"Nodes: \n");
00280 for(uint i = 0; i < nodes_size; i++){
00281 fprintf(f,"%2d: ", nodes[i].index);
00282 fprintf(f,"%2d.%2d.%2d ", nodes[i].id.seg,
00283 nodes[i].id.lane, nodes[i].id.pt);
00284
00285
00286 fprintf(f,",Width: %2.3f ", nodes[i].lane_width);
00287 fprintf(f,"CKPT: %s, STOP: %s", nodes[i].is_goal?"true ":"false",
00288 nodes[i].is_stop?"true ":"false");
00289 fprintf(f,", ENTRY: %s, EXIT: %s", nodes[i].is_entry?"true ":"false",
00290 nodes[i].is_exit?"true ":"false");
00291 fprintf(f,", SPOT: %s\n", nodes[i].is_spot?"true ":"false");
00292 }
00293 fclose(f);
00294 };
00295
00296 void Graph::printEdgesFile(const char* fName){
00297 FILE* f = fopen(fName,"wb");
00298 fprintf(f,"Edges: \n");
00299 for(uint i = 0; i < edges_size; i++){
00300 fprintf(f,"%3d: ", i);
00301 fprintf(f,"%3d to %3d ", edges[i].startnode_index, edges[i].endnode_index);
00302 fprintf(f,"Boundary- Left:%2d, Right:%2d, ",
00303 edges[i].left_boundary, edges[i].right_boundary);
00304 fprintf(f,",EXIT: %s\n", edges[i].is_exit?"true ":"false");
00305 }
00306 fclose(f);
00307 };
00308
00309 bool Graph::rndf_is_gps() {
00310 double minlat=INFINITY;
00311 double minlong=INFINITY;
00312 double maxlat=-INFINITY;
00313 double maxlong=-INFINITY;
00314
00315 for(uint i = 0; i < nodes_size; i++){
00316 minlat = std::min(minlat,nodes[i].ll.latitude);
00317 minlong = std::min(minlong,nodes[i].ll.longitude);
00318 maxlat = std::max(maxlat,nodes[i].ll.latitude);
00319 maxlong = std::max(maxlong,nodes[i].ll.longitude);
00320 }
00321
00322 if (minlat == INFINITY ||
00323 maxlat == INFINITY ||
00324 minlong == INFINITY ||
00325 maxlong == INFINITY)
00326 return false;
00327
00328 if (maxlat-minlat <= 2 &&
00329 maxlong-minlong <= 2)
00330 return true;
00331
00332 return false;
00333
00334 }
00335
00336 void Graph::xy_rndf() {
00337 for(uint i = 0; i < nodes_size; i++){
00338 nodes[i].map.x = nodes[i].ll.latitude;
00339 nodes[i].map.y = nodes[i].ll.longitude;
00340 }
00341
00342 for(uint i = 0; i < edges_size; i++){
00343 WayPointNode* start=get_node_by_index(edges[i].startnode_index);
00344 WayPointNode* end=get_node_by_index(edges[i].endnode_index);
00345
00346 edges[i].distance=Euclidean::DistanceTo(start->map,end->map);
00347 }
00348 }
00349
00357 void Graph::find_mapxy(void)
00358 {
00359 if (nodes_size < 1)
00360 {
00361 ROS_INFO("No graph nodes available for conversion to MapXY");
00362 return;
00363 }
00364
00365
00366
00367
00368 double tX;
00369 double tY;
00370 UTM::UTM(nodes[0].ll.latitude, nodes[0].ll.longitude, &tX, &tY);
00371
00372
00373
00374 double grid_x = (rint(tX/UTM::grid_size) * UTM::grid_size);
00375 double grid_y = (rint(tY/UTM::grid_size) * UTM::grid_size);
00376 nodes[0].map = MapXY(tX - grid_x, tY - grid_y);
00377 ROS_INFO("UTM grid of first way-point: (%.f, %.f)", grid_x, grid_y);
00378
00379
00380
00381
00382
00383 for(uint i = 1; i < nodes_size; i++)
00384 {
00385 UTM::UTM(nodes[i].ll.latitude, nodes[i].ll.longitude, &tX, &tY);
00386 nodes[i].map = MapXY(tX - grid_x, tY - grid_y);
00387 }
00388
00389 for(uint i = 0; i < edges_size; i++){
00390 WayPointNode* start=get_node_by_index(edges[i].startnode_index);
00391 WayPointNode* end=get_node_by_index(edges[i].endnode_index);
00392
00393 edges[i].distance=Euclidean::DistanceTo(start->map,end->map);
00394
00395
00396 }
00397 }
00398
00399 bool Graph::passing_allowed(int index, int index2, bool left) {
00400 if (index < 0 || index >= (int)nodes_size)
00401 return false;
00402
00403 WayPointNode node1=nodes[index];
00404 WayPointNode node2=nodes[index2];
00405
00406 ElementID ahead=ElementID(node1.id.seg,node1.id.lane,node1.id.pt+1);
00407
00408 bool found_ahead=false;
00409
00410 for (uint i=0; i<nodes_size; i++)
00411 if (nodes[i].id==ahead)
00412 {
00413 found_ahead=true;
00414 break;
00415 }
00416
00417 if (!found_ahead)
00418 return true;
00419
00420
00421
00422 for (uint i=0; i<edges.size(); i++)
00423 {
00424 if (edges.at(i).startnode_index==node1.index)
00425 {
00426 ElementID neighbor_id=nodes[edges.at(i).endnode_index].id;
00427 if (neighbor_id.seg==node1.id.seg &&
00428 neighbor_id.lane==node1.id.lane &&
00429 neighbor_id.pt==node1.id.pt+1) {
00430 if (left)
00431 {
00432 if (edges.at(i).left_boundary==DOUBLE_YELLOW ||
00433 edges.at(i).left_boundary==SOLID_YELLOW ||
00434 edges.at(i).left_boundary==SOLID_WHITE)
00435 return false;
00436 }
00437 else
00438 {
00439 if (edges.at(i).right_boundary==DOUBLE_YELLOW ||
00440 edges.at(i).right_boundary==SOLID_YELLOW ||
00441 edges.at(i).right_boundary==SOLID_WHITE)
00442 return false;
00443 }
00444 }
00445 }
00446 if (edges.at(i).startnode_index==node2.index)
00447 {
00448 ElementID neighbor_id= nodes[edges.at(i).endnode_index].id;
00449 if (neighbor_id.seg==node2.id.seg &&
00450 neighbor_id.lane==node2.id.lane &&
00451 neighbor_id.pt==node2.id.pt+1) {
00452 if (!left)
00453 {
00454 if (edges.at(i).left_boundary==DOUBLE_YELLOW ||
00455 edges.at(i).left_boundary==SOLID_YELLOW ||
00456 edges.at(i).left_boundary==SOLID_WHITE)
00457 return false;
00458 }
00459 else
00460 {
00461 if (edges.at(i).right_boundary==DOUBLE_YELLOW ||
00462 edges.at(i).right_boundary==SOLID_YELLOW ||
00463 edges.at(i).right_boundary==SOLID_WHITE)
00464 return false;
00465 }
00466 }
00467 }
00468 }
00469
00470 return true;
00471
00472 }
00473
00474 bool Graph::lanes_in_same_direction(int index1,int index2, bool& left_lane) {
00475 if (index1<0 || index2<0 ||
00476 index1>=(int)nodes_size ||
00477 index2>=(int)nodes_size)
00478 return false;
00479
00480 ElementID el1=ElementID(nodes[index1].id);
00481 el1.pt+=1;
00482
00483 ElementID el2=ElementID(nodes[index2].id);
00484 el2.pt+=1;
00485
00486 int ind1=-1;
00487 int ind2=-1;
00488
00489 for (uint i=0; i<nodes_size; i++)
00490 {
00491 if (nodes[i].id==el1)
00492 ind1=i;
00493 if (nodes[i].id==el2)
00494 ind2=i;
00495 }
00496
00497 float head1;
00498 float head2;
00499
00500 if (ind1>=0 && ind2>=0)
00501 {
00502 head1=atan2f(nodes[ind1].map.y-nodes[index1].map.y,
00503 nodes[ind1].map.x-nodes[index1].map.x);
00504 head2=atan2f(nodes[ind2].map.y-nodes[index2].map.y,
00505 nodes[ind2].map.x-nodes[index2].map.x);
00506
00507 MapPose p1(nodes[index1].map,head1);
00508
00509 if (Coordinates::bearing(p1,nodes[index2].map) > 0)
00510 left_lane=true;
00511 else left_lane=false;
00512
00513 }
00514 else
00515 {
00516 el1.pt-=2;
00517 el2.pt-=2;
00518 ind1=-1;
00519 ind2=-1;
00520
00521 for (uint i=0; i<nodes_size; i++)
00522 {
00523 if (nodes[i].id==el1)
00524 ind1=i;
00525 if (nodes[i].id==el2)
00526 ind2=i;
00527 }
00528
00529 if (ind1>=0 && ind2>=0)
00530 {
00531 head1=atan2(nodes[ind1].map.y-nodes[index1].map.y,
00532 nodes[ind1].map.x-nodes[index1].map.x);
00533 head2=atan2(nodes[ind2].map.y-nodes[index2].map.y,
00534 nodes[ind2].map.x-nodes[index2].map.x);
00535
00536 MapPose p1(nodes[index1].map,head1);
00537
00538 if (Coordinates::bearing(p1,nodes[index2].map) < 0)
00539 left_lane=true;
00540 else left_lane=false;
00541 }
00542 else return false;
00543 }
00544
00545 if (fabsf(Coordinates::normalize(head1-head2)) < HALFPI)
00546 return true;
00547 else return false;
00548
00549 }
00550
00551 void Graph::find_implicit_edges() {
00552
00553 for (unsigned i=0; i< nodes_size; i++)
00554 {
00555 WayPointNode node1=nodes[i];
00556 if (node1.is_stop || node1.is_perimeter ||
00557 node1.is_spot)
00558 continue;
00559 {
00560 float min_dist=FLT_MAX;
00561 int min_index=-1;
00562 for (unsigned j=0; j< nodes_size; j++)
00563 if (i!=j)
00564 {
00565 WayPointNode node2=nodes[j];
00566 if (node1.id.seg==node2.id.seg &&
00567 node1.id.lane-1==node2.id.lane)
00568 {
00569 float curr_dist=Euclidean::DistanceTo(node1.map,node2.map);
00570 if (curr_dist < min_dist)
00571 {
00572 min_dist=curr_dist;
00573 min_index=j;
00574 }
00575 }
00576 }
00577 if (min_index<0)
00578 continue;
00579 if (nodes[min_index].is_stop || nodes[min_index].is_perimeter ||
00580 nodes[min_index].is_spot)
00581 continue;
00582 bool left_lane;
00583 if (lanes_in_same_direction(i,min_index, left_lane))
00584 {
00585 if (passing_allowed(i,min_index,left_lane))
00586 {
00587 WayPointEdge new_edge;
00588 new_edge.startnode_index=i;
00589 new_edge.endnode_index=min_index;
00590
00591 new_edge.distance=30;
00592 new_edge.speed_max=6.0;
00593 new_edge.blocked=false;
00594 new_edge.is_implicit=true;
00595 edges.push_back(new_edge);
00596 edges_size++;
00597 }
00598 }
00599 }
00600
00601 {
00602 float min_dist=FLT_MAX;
00603 int min_index=-1;
00604 for (unsigned j=0; j< nodes_size; j++)
00605 if (i!=j)
00606 {
00607 WayPointNode node2=nodes[j];
00608 if (node1.id.seg==node2.id.seg &&
00609 node1.id.lane+1==node2.id.lane)
00610 {
00611 float curr_dist=Euclidean::DistanceTo(node1.map,node2.map) < min_dist;
00612 if (curr_dist < min_dist)
00613 {
00614 min_dist=curr_dist;
00615 min_index=j;
00616 }
00617 }
00618 }
00619 if (min_index<0)
00620 continue;
00621 bool left_lane;
00622 if (lanes_in_same_direction(i,min_index, left_lane))
00623 {
00624 if (passing_allowed(i,min_index,left_lane))
00625 {
00626 WayPointEdge new_edge;
00627 new_edge.startnode_index=i;
00628 new_edge.endnode_index=min_index;
00629
00630 new_edge.distance=25;
00631 new_edge.speed_max=6.0;
00632 new_edge.blocked=false;
00633 new_edge.is_implicit=true;
00634 edges.push_back(new_edge);
00635 edges_size++;
00636 }
00637 }
00638 }
00639 }
00640 }
00641
00642
00643 int parse_integer(std::string line, std::string token,
00644 bool& valid){
00645 int integer;
00646 if (!sscanf(line.c_str(), "%*s %d", &integer)){
00647 valid=false;
00648 }
00649 return integer;
00650 };
00651
00652 WayPointNode parse_node(std::string line, bool& valid){
00653 WayPointNode node;
00654 double f1, f2;
00655 float f3, f4, f5;
00656 int d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11;
00657 if (sscanf(line.c_str(),
00658 "Node %lf, %lf; %f, %f; %d, %d, %d; %d; %d, %d, %d, %d, %d, %d; %d; %f;",
00659 &f1, &f2, &f3, &f4, &d1, &d2, &d3, &d4, &d5, &d6, &d7, &d8, &d9, &d10, &d11, &f5)
00660 == 16){
00661 valid = true;
00662 node.ll.latitude = f1;
00663 node.ll.longitude = f2;
00664 node.map.x = f3;
00665 node.map.y = f4;
00666 node.id.seg = d1;
00667 node.id.lane = d2;
00668 node.id.pt = d3;
00669 node.index = d4;
00670 node.is_entry = d5;
00671 node.is_exit = d6;
00672 node.is_goal = d7;
00673 node.is_spot = d8;
00674 node.is_stop = d9;
00675 node.is_perimeter = d10;
00676 node.checkpoint_id = d11;
00677 node.lane_width = f5;
00678 }
00679 else
00680 valid=false;
00681
00682 return node;
00683
00684
00685 };
00686
00687 WayPointEdge parse_edge(std::string line, bool& valid){
00688
00689 WayPointEdge edge;
00690 float f1,f2,f3;
00691 int d1, d2, d6, d7, d8;
00692 if (sscanf(line.c_str(),
00693 "Edge %d, %d; %f; %f, %f; %d; %d, %d; ",
00694 &d1, &d2, &f1, &f2, &f3, &d6, &d7, &d8)
00695 == 8){
00696 valid = true;
00697 edge.startnode_index = d1;
00698 edge.endnode_index = d2;
00699 edge.distance = f1;
00700 edge.speed_max = f2;
00701 edge.speed_min = f3;
00702 edge.is_exit = d6;
00703 edge.left_boundary = static_cast<Lane_marking>(d7);
00704 edge.right_boundary = static_cast<Lane_marking>(d8);
00705 }
00706 else
00707 valid=false;
00708
00709 return edge;
00710
00711 };