00001
00002
00009
00010 typedef struct Map__Struct *Map_Doxygen_Fake_Out;
00011
00012 #include <assert.h>
00013 #include <angles/angles.h>
00014
00015 #include "Arc.hpp"
00016 #include "CV.hpp"
00017 #include "Camera_Tag.hpp"
00018 #include "File.hpp"
00019 #include "Location.hpp"
00020 #include "Map.hpp"
00021 #include "Tag.hpp"
00022
00023
00024
00033
00034 void Map__arc_announce(Map map,
00035 Arc *arc, CV_Image image, unsigned int sequence_number) {
00036 Tag *from_tag = arc->from_tag;
00037 Tag *to_tag = arc->to_tag;
00038 map->arc_announce_routine(map->announce_object,
00039 from_tag->id, from_tag->x, from_tag->y, from_tag->z,
00040 to_tag->id, to_tag->x, to_tag->y, to_tag->z,
00041 arc->goodness, arc->in_tree);
00042 Map__image_log(map, image, sequence_number);
00043 }
00044
00050
00051 void Map__arc_append(Map map, Arc *arc) {
00052 map->all_arcs.push_back(arc);
00053 map->changes_count += 1;
00054 map->is_changed = (bool)1;
00055 map->is_saved = (bool)0;
00056 }
00057
00066
00067 Arc *Map__arc_lookup(Map map, Tag *from_tag, Tag *to_tag) {
00068
00069 if (from_tag->id > to_tag->id) {
00070 Tag *temporary_tag = from_tag;
00071 from_tag = to_tag;
00072 to_tag = temporary_tag;
00073 }
00074
00075
00076 std::pair<unsigned int, unsigned int> id(from_tag->id, to_tag->id);
00077 Arc *arc;
00078 if( map->arcs_.count(id) == 0 ) {
00079
00080 arc = new Arc(from_tag, 0.0, 0.0, to_tag, 0.0, 123456789.0);
00081 map->arcs_[id] = arc;
00082 } else {
00083 arc = map->arcs_[id];
00084 }
00085 return arc;
00086 }
00087
00098
00099 unsigned int Map__arc_update(Map map, CameraTag *camera_from, CameraTag *camera_to,
00100 CV_Image image, unsigned int sequence_number) {
00101
00102 int rows = CV_Image__height_get(image);
00103 int columns = CV_Image__width_get(image);
00104 double height = (double)rows;
00105 double width = (double)columns;
00106
00107
00108 double half_width = width / 2.0;
00109 double half_height = height / 2.0;
00110 double pi = 3.14159265358979323846264;
00111 double r2d = 180.0 / pi;
00112
00113
00114 Tag *from_tag = camera_from->tag;
00115 double camera_from_twist = camera_from->twist;
00116 double camera_from_x = camera_from->x;
00117 double camera_from_y = camera_from->y;
00118
00119
00120 Tag *to_tag = camera_to->tag;
00121 double camera_to_twist = camera_to->twist;
00122 double camera_to_x = camera_to->x;
00123 double camera_to_y = camera_to->y;
00124
00125
00126 Arc *arc = Map__arc_lookup(map, from_tag, to_tag);
00127
00128
00129
00130 double camera_from_dx = camera_from->x - half_width;
00131 double camera_from_dy = camera_from->y - half_height;
00132 double camera_from_polar_distance = hypot(camera_from_dx, camera_from_dy);
00133 double camera_from_polar_angle = atan2(camera_from_dy, camera_from_dx);
00134
00135
00136
00137 double camera_to_dx = camera_to_x - half_width;
00138 double camera_to_dy = camera_to_y - half_height;
00139 double camera_to_polar_distance = hypot(camera_to_dx, camera_to_dy);
00140 double camera_to_polar_angle = atan2(camera_to_dy, camera_to_dx);
00141
00142
00143
00144
00145 double goodness = std::abs(camera_from_polar_distance - camera_to_polar_distance);
00146
00147
00148
00149
00150 unsigned int changed = 0;
00151 if (goodness < arc->goodness) {
00152
00153
00154
00155
00156
00157 double from_distance_per_pixel =
00158 from_tag->world_diagonal / from_tag->diagonal;
00159 double to_distance_per_pixel =
00160 to_tag->world_diagonal / to_tag->diagonal;
00161
00162
00163
00164
00165 double from_floor_x = from_distance_per_pixel *
00166 camera_from_polar_distance * cos(camera_from_polar_angle);
00167 double from_floor_y = from_distance_per_pixel *
00168 camera_from_polar_distance * sin(camera_from_polar_angle);
00169 double to_floor_x = to_distance_per_pixel *
00170 camera_to_polar_distance * cos(camera_to_polar_angle);
00171 double to_floor_y = to_distance_per_pixel *
00172 camera_to_polar_distance * sin(camera_to_polar_angle);
00173
00174
00175
00176 double floor_dx = from_floor_x - to_floor_x;
00177 double floor_dy = from_floor_y - to_floor_y;
00178 double floor_distance = hypot(floor_dx, floor_dy);
00179
00180
00181 double camera_dx = camera_to_x - camera_from_x;
00182 double camera_dy = camera_to_y - camera_from_y;
00183 double arc_angle = atan2(camera_dy, camera_dx);
00184 double from_twist =
00185 angles::normalize_angle(camera_from_twist - arc_angle);
00186 double to_twist =
00187 angles::normalize_angle(camera_to_twist + pi - arc_angle);
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 arc->update(from_twist, floor_distance, to_twist, goodness);
00206 map->changes_count += 1;
00207 map->is_changed = (bool)1;
00208 map->is_saved = (bool)0;
00209
00210
00211 Map__arc_announce(map, arc, image, sequence_number);
00212
00213 changed = 1;
00214 }
00215 return changed;
00216 }
00217
00227
00228 bool Map__equals(Map map1, Map map2) {
00229
00230 unsigned int all_tags1_size = map1->all_tags.size();
00231 unsigned int all_tags2_size = map2->all_tags.size();
00232 if (all_tags1_size == all_tags2_size) {
00233
00234 for (unsigned int index = 0; index < all_tags1_size; index++) {
00235 Tag *tag1 = map1->all_tags[index];
00236 Tag *tag2 = map2->all_tags[index];
00237 if (!Tag::equal(tag1, tag2)) {
00238 return false;
00239 }
00240 }
00241 } else {
00242 return false;
00243 }
00244
00245
00246 unsigned int all_arcs1_size = map1->all_arcs.size();
00247 unsigned int all_arcs2_size = map2->all_arcs.size();
00248 if (all_arcs1_size == all_arcs2_size) {
00249
00250 for (unsigned int index = 0; index < all_arcs1_size; index++) {
00251 Arc * arc1 = map1->all_arcs[index];
00252 Arc * arc2 = map2->all_arcs[index];
00253 if( !Arc::equal(arc1, arc2)) {
00254 return false;
00255 }
00256 }
00257 } else {
00258 return false;
00259 }
00260 return true;
00261 }
00262
00275
00276 Map Map__create(String_Const file_path, String_Const file_base,
00277 void *announce_object, Fiducials_Arc_Announce_Routine arc_announce_routine,
00278 Fiducials_Tag_Announce_Routine tag_announce_routine,
00279 String_Const tag_heights_file_name, String_Const from) {
00280
00281 Map map = Memory__new(Map, from);
00282 map = new(map) Map__Struct();
00283 map->arc_announce_routine = arc_announce_routine;
00284 map->announce_object = announce_object;
00285 map->changes_count = 0;
00286 map->file_base = file_base;
00287 map->file_path = file_path;
00288 map->is_changed = (bool)0;
00289 map->is_saved = (bool)1;
00290 map->image_log = (bool)0;
00291 map->tag_announce_routine = tag_announce_routine;
00292 map->temporary_arc = new Arc();
00293 map->visit = 0;
00294
00295
00296 Map__tag_heights_xml_read(map, tag_heights_file_name);
00297
00298
00299
00300 String full_map_file_name =
00301 String__format("%s/%s1.xml", file_path, file_base);
00302 File in_file = File__open(full_map_file_name, "r");
00303 if (in_file == (File)0) {
00304
00305 String__free(full_map_file_name);
00306 String full_map_file_name =
00307 String__format("%s/%s0.xml", file_path, file_base);
00308 in_file = File__open(full_map_file_name, "r");
00309 if (in_file != (File)0) {
00310
00311 Map__restore(map, in_file);
00312 File__close(in_file);
00313 }
00314 } else {
00315
00316 printf("Reading %s\n", full_map_file_name);
00317 Map__restore(map, in_file);
00318 File__close(in_file);
00319 }
00320 return map;
00321 }
00322
00327
00328 void Map__free(Map map) {
00329
00330 Map__save(map);
00331
00332
00333 unsigned int arcs_size = map->all_arcs.size();
00334 for (unsigned int index = 0; index < arcs_size; index++) {
00335 delete map->all_arcs[index];
00336 }
00337 delete map->temporary_arc;
00338
00339
00340 unsigned int tags_size = map->all_tags.size();
00341 for (unsigned int index = 0; index < tags_size; index++) {
00342 delete map->all_tags[index];
00343 }
00344
00345
00346 unsigned int tag_heights_size = map->tag_heights.size();
00347 for (unsigned int index = 0; index < tag_heights_size; index++) {
00348 delete map->tag_heights[index];
00349 }
00350
00351 Memory__free((Memory)map);
00352 }
00353
00359
00360 static int last_sequence_number = 0xffffffff;
00361
00362 void Map__image_log(Map map, CV_Image image, unsigned int sequence_number) {
00363 if (image != (CV_Image)0 && map->image_log &&
00364 sequence_number != last_sequence_number) {
00365
00366 String file_name = String__format("log%05d.tga", sequence_number);
00367 CV_Image__tga_write(image, file_name);
00368 last_sequence_number = sequence_number;
00369 }
00370 }
00371
00378
00379 void Map__restore(Map map, File in_file) {
00380
00381 File__tag_match(in_file, "Map");
00382 unsigned int all_tags_size =
00383 (unsigned int)File__integer_attribute_read(in_file, "Tags_Count");
00384 unsigned int all_arcs_size =
00385 (unsigned int)File__integer_attribute_read(in_file, "Arcs_Count");
00386 File__string_match(in_file, ">\n");
00387
00388
00389 for (unsigned int index = 0; index < all_tags_size; index++) {
00390 Tag * tag = Tag::read(in_file, map);
00391
00392 map->tag_announce_routine(map->announce_object,
00393 tag->id, tag->x, tag->y, tag->z, tag->twist,
00394 tag->diagonal, tag->world_diagonal/tag->diagonal,
00395 0, tag->hop_count);
00396 }
00397
00398
00399 for (unsigned int index = 0; index < all_arcs_size; index++) {
00400 Arc * arc = Arc::read(in_file, map);
00401 }
00402
00403
00404 File__tag_match(in_file, "/Map");
00405 File__string_match(in_file, ">\n");
00406
00407
00408 assert (map->all_arcs.size() == all_arcs_size);
00409 assert (map->all_tags.size() == all_tags_size);
00410 }
00411
00416
00417 void Map__save(Map map) {
00418 File__format(stderr, "**********Map__save************\n");
00419 if (!map->is_saved) {
00420 String full_map_file_name =
00421 String__format("%s/%s", map->file_path, map->file_base);
00422 File out_file = File__open(full_map_file_name, "w");
00423 assert (out_file != (File)0);
00424 String__free(full_map_file_name);
00425 Map__write(map, out_file);
00426 File__close(out_file);
00427 map->is_saved = (bool)1;
00428 }
00429 }
00430
00436
00437 void Map__sort(Map map) {
00438 std::sort(map->all_tags.begin(), map->all_tags.end(), Tag::less);
00439 std::sort(map->all_arcs.begin(), map->all_arcs.end(), Arc::less);
00440 }
00441
00448
00449 void Map__svg_write(Map map, String_Const svg_base_name,
00450 std::vector<Location*> &locations) {
00451
00452 unsigned int all_tags_size = map->all_tags.size();
00453 unsigned int all_arcs_size = map->all_arcs.size();
00454
00455
00456 BoundingBox * bounding_box = new BoundingBox();
00457 for (unsigned int index = 0; index < all_tags_size; index++) {
00458 Tag * tag = map->all_tags[index];
00459 tag->bounding_box_update(bounding_box);
00460 }
00461
00462
00463 SVG * svg = new SVG(svg_base_name, 8.0, 10.5, 1.0, 1.0, "in");
00464
00465 svg->cartesian_scale(8.0, 10.5, bounding_box);
00466
00467
00468 String_Const color = "cyan";
00469 svg->line(bounding_box->min_x(), 0.0, bounding_box->max_x(), 0.0, color);
00470 svg->line(0.0, bounding_box->min_y(), 0.0, bounding_box->max_y(), color);
00471
00472
00473 double world_diagonal = 0.1;
00474 for (unsigned int index = 0; index < all_tags_size; index++) {
00475 Tag * tag = map->all_tags[index];
00476 world_diagonal = tag->world_diagonal;
00477 tag->svg_write(svg);
00478 }
00479
00480
00481 for (unsigned int index = 0; index < all_arcs_size; index++) {
00482 Arc *arc = map->all_arcs[index];
00483 arc->svg_write(svg);
00484
00485
00486 }
00487
00488 unsigned int locations_size = locations.size();
00489 double last_x = 0.0;
00490 double last_y = 0.0;
00491 for (unsigned int index = 0; index < locations_size; index++) {
00492 Location * location = locations[index];
00493 double x = location->x;
00494 double y = location->y;
00495 double bearing = location->bearing;
00496
00497
00498
00499
00500 double k1 = world_diagonal / 2.0;
00501 double k2 = k1 / 2.0;
00502 double angle = 3.14159 * 0.75;
00503 double x0 = x + k1 * cos(bearing);
00504 double y0 = y + k1 * sin(bearing);
00505 double x1 = x + k2 * cos(bearing + angle);
00506 double y1 = y + k2 * sin(bearing + angle);
00507 double x2 = x + k2 * cos(bearing - angle);
00508 double y2 = y + k2 * sin(bearing - angle);
00509 svg->line(x0, y0, x1, y1, "black");
00510 svg->line(x1, y1, x2, y2, "black");
00511 svg->line(x2, y2, x0, y0, "black");
00512
00513
00514 if (index > 0) {
00515 svg->line(last_x, last_y, x, y, "purple");
00516 }
00517 last_x = x;
00518 last_y = y;
00519 }
00520
00521
00522 delete svg;
00523
00524 delete bounding_box;
00525 }
00526
00536
00537 void Map__tag_announce(Map map,
00538 Tag * tag, bool visible, CV_Image image, unsigned int sequence_number) {
00539 map->tag_announce_routine(map->announce_object,
00540 tag->id, tag->x, tag->y, tag->z, tag->twist,
00541 tag->diagonal, tag->world_diagonal/tag->diagonal,
00542 visible, tag->hop_count);
00543 if (visible) {
00544
00545 }
00546 }
00547
00557
00558 TagHeight * Map__tag_height_lookup(Map map, unsigned int id) {
00559
00560 TagHeight * tag_height = NULL;
00561 unsigned int size = map->tag_heights.size();
00562 for (unsigned int index = 0; index < size; index++) {
00563 tag_height = map->tag_heights[index];
00564 if (tag_height->first_id <= id && id <= tag_height->last_id) {
00565
00566
00567 break;
00568 }
00569 tag_height = NULL;
00570 }
00571 return tag_height;
00572 }
00573
00580
00581 void Map__tag_heights_xml_read(Map map, String_Const tag_heights_file_name) {
00582
00583 File xml_in_file = File__open(tag_heights_file_name, "r");
00584 if (xml_in_file == (File)0) {
00585 File__format(stderr, "Could not open '%s'\n", tag_heights_file_name);
00586 assert(0);
00587 }
00588
00589
00590 File__tag_match(xml_in_file, "Map_Tag_Heights");
00591 unsigned int count =
00592 (unsigned int)File__integer_attribute_read(xml_in_file, "Count");
00593 File__string_match(xml_in_file, ">\n");
00594
00595
00596 for (unsigned int index = 0; index < count; index++) {
00597 TagHeight * tag_height = TagHeight::xml_read(xml_in_file);
00598 map->tag_heights.push_back(tag_height);
00599 }
00600
00601
00602 File__tag_match(xml_in_file, "/Map_Tag_Heights");
00603 File__string_match(xml_in_file, ">\n");
00604
00605
00606 File__close(xml_in_file);
00607
00608
00609 std::sort(map->tag_heights.begin(), map->tag_heights.end(),
00610 TagHeight::less);
00611 }
00612
00621
00622 Tag * Map__tag_lookup(Map map, unsigned int tag_id) {
00623 if( map->tags_.count(tag_id) == 0 ) {
00624 Tag * tag = new Tag(tag_id, map);
00625 map->tags_[tag_id] = tag;
00626 map->all_tags.push_back(tag);
00627 map->changes_count += 1;
00628 map->is_changed = (bool)1;
00629 map->is_saved = (bool)0;
00630 }
00631 return map->tags_[tag_id];
00632 }
00633
00639
00640 void Map__write(Map map, File out_file) {
00641
00642 unsigned int all_tags_size = map->all_tags.size();
00643 unsigned int all_arcs_size = map->all_arcs.size();
00644
00645
00646 File__format(out_file, "<Map");
00647 File__format(out_file, " Tags_Count=\"%d\"", all_tags_size);
00648 File__format(out_file, " Arcs_Count=\"%d\"", all_arcs_size);
00649 File__format(out_file, ">\n");
00650
00651
00652 Map__sort(map);
00653
00654
00655 for (unsigned int index = 0; index < all_tags_size; index++) {
00656 Tag * tag = map->all_tags[index];
00657 tag->write(out_file);
00658 }
00659
00660
00661 for (unsigned int index = 0; index < all_arcs_size; index++) {
00662 map->all_arcs[index]->write(out_file);
00663 }
00664
00665
00666 File__format(out_file, "</Map>\n");
00667 }
00668
00675
00676 void Map__update(Map map, CV_Image image, unsigned int sequence_number) {
00677 if (map->is_changed) {
00678
00679 unsigned int visit = map->visit + 1;
00680 map->visit = visit;
00681
00682
00683
00684 std::sort(map->all_tags.begin(), map->all_tags.end(), Tag::less);
00685
00686
00687
00688 Tag * origin_tag = map->all_tags[0];
00689 origin_tag->visit = visit;
00690 origin_tag->hop_count = 0;
00691
00692
00693
00694
00695
00696 map->pending_arcs.insert(map->pending_arcs.end(),
00697 origin_tag->arcs_.begin(), origin_tag->arcs_.end());
00698
00699
00700
00701 std::sort(map->pending_arcs.begin(), map->pending_arcs.end(),
00702 Arc::distance_less);
00703
00704
00705
00706
00707
00708 while (map->pending_arcs.size() != 0) {
00709
00710 Arc * arc = map->pending_arcs.back();
00711 map->pending_arcs.pop_back();
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 if (arc->visit != visit) {
00725
00726
00727 arc->visit = visit;
00728
00729
00730
00731 Tag * from_tag = arc->from_tag;
00732 Tag * to_tag = arc->to_tag;
00733 bool from_is_new = (bool)(from_tag->visit != visit);
00734 bool to_is_new = (bool)(to_tag->visit != visit);
00735
00736 if (from_is_new || to_is_new) {
00737 if (from_is_new) {
00738
00739 assert (!to_is_new);
00740 from_tag->hop_count = to_tag->hop_count + 1;
00741 map->pending_arcs.insert(map->pending_arcs.end(),
00742 from_tag->arcs_.begin(), from_tag->arcs_.end());
00743 from_tag->visit = visit;
00744 from_tag->update_via_arc(arc, image, sequence_number);
00745 } else {
00746
00747 assert (!from_is_new);
00748 to_tag->hop_count = from_tag->hop_count + 1;
00749 map->pending_arcs.insert(map->pending_arcs.end(),
00750 to_tag->arcs_.begin(), to_tag->arcs_.end());
00751 to_tag->visit = visit;
00752 to_tag->update_via_arc(arc, image, sequence_number);
00753 }
00754
00755
00756 arc->in_tree = (bool)1;
00757
00758
00759
00760 std::sort(map->pending_arcs.begin(),
00761 map->pending_arcs.end(), Arc::distance_less);
00762 } else {
00763
00764 arc->in_tree = (bool)0;
00765 }
00766 }
00767 }
00768
00769 if (map->is_changed) {
00770 Map__save(map);
00771 }
00772
00773
00774 map->is_changed = (bool)0;
00775 map->is_saved = (bool)0;
00776 }
00777 }
00778