From 194604236de6fa90a75034e1e0236c2cb43965ce Mon Sep 17 00:00:00 2001 From: Christoph Sprunk <sprunkc@informatik.uni-freiburg.de> Date: Thu, 8 Aug 2013 14:46:18 +0200 Subject: [PATCH] changing from c/gsl to cpp/Eigen, stripping a lot of components in the process --- CMakeLists.txt | 34 - Doxyfile | 1218 ---- TODO.txt | 3 - csm_manual.html | 675 --- csm_manual.pdf | Bin 152698 -> 0 bytes docs/Makefile | 39 - docs/TODO.txt | 1 - docs/description.lyx | 167 - docs/embedding.txt | 133 - docs/example-linking-cmake/CMakeLists.txt | 23 - docs/example-linking-cmake/myprogram.c | 5 - docs/example-linking-make/Makefile | 4 - docs/example-linking-make/myprogram.c | 5 - docs/examples.txt | 60 - docs/formats.txt | 63 - docs/inline_style.css | 16 - docs/install-ruby.txt | 71 - docs/install.txt | 96 - docs/laserdata.lyx | 285 - docs/laserdata.txt | 83 - docs/misc.txt | 3 - docs/optimization-notes.txt | 130 - docs/optimizations.txt | 14 - docs/other.txt | 21 - docs/preamble.tex | 5 - docs/preamble.txt | 6 - docs/readme.txt | 127 - docs/references.txt | 3 - docs/style.css | 106 - docs/todo.mm | 38 - docs/troubleshootings.txt | 8 - {sm => include}/csm/algos.h | 23 +- include/csm/csm.h | 7 + {sm => include}/csm/laser_data.h | 7 + {sm => include}/csm/laser_data_inline.h | 9 +- {sm => include}/csm/restrict.h | 2 - include/gsl_eigen/gsl_eigen.h | 80 + install_quickstart.sh | 8 - local_config/icc-warnings.txt | 216 - local_config/local-Melania.cmake | 32 - local_config/local-linuxserv-icc.cmake | 15 - local_config/local-linuxserv.cmake | 9 - local_config/local-lisablack.cmake | 9 - local_config/local-overlook.cmake | 27 - local_config/local-pammela.cmake | 24 - local_config/local-pdelapuente.cmake | 4 - local_config/local-sorchetta.cmake | 3 - misc/matlab/appunti/MMt.png | Bin 75939 -> 0 bytes misc/matlab/appunti/problem.eps | 4973 ----------------- misc/matlab/appunti/problem.fig | Bin 80227 -> 0 bytes misc/matlab/carmen/convertFile.m | 12 - misc/matlab/carmen/convertLine.m | 25 - misc/matlab/carmen/readFileInCells.m | 44 - misc/matlab/carmen/reading.m | 44 - misc/matlab/ci.m | 11 - misc/matlab/cramer_rao/compute_bounds.m | 40 - misc/matlab/cramer_rao/plot_bounds.m | 80 - misc/matlab/cramer_rao/square.pdf | Bin 7149 -> 0 bytes misc/matlab/cramer_rao/test_bounds_circle.m | 39 - misc/matlab/cramer_rao/test_bounds_oval.m | 45 - misc/matlab/cramer_rao/test_bounds_square.m | 35 - .../cramer_rao/test_bounds_square2_tmp.m | 28 - misc/matlab/cramer_rao/test_unstructured.m | 140 - .../cramer_rao/test_unstructured_print.m | 20 - misc/matlab/gpm/go.sh | 3 - misc/matlab/gpm/gpm.m | 265 - misc/matlab/gpm/gpmSample.m | 44 - misc/matlab/gpm/gpm_plot_res.m | 32 - misc/matlab/gpm/gpm_test.m | 45 - misc/matlab/gpm/gpm_test2.m | 40 - misc/matlab/gpm/test.tex | 26 - misc/matlab/gpm/test_gpm.m | 258 - misc/matlab/gpm/yasmine.m | 157 - misc/matlab/gpm/yasmine2.m | 227 - misc/matlab/icp/closest_point_on_segment.m | 45 - misc/matlab/icp/exact_minimization.m | 46 - misc/matlab/icp/icp.m | 139 - misc/matlab/icp/icp_covariance.m | 154 - misc/matlab/icp/icp_get_correspondences.m | 70 - misc/matlab/icp/icp_possible_interval.m | 22 - misc/matlab/icp/test_icp_1.m | 5 - misc/matlab/icpcov/derivn.m | 10 - misc/matlab/matlab_new/display/display_cov.m | 10 - misc/matlab/matlab_new/ld_fisher0.m | 33 - misc/matlab/matlab_new/ld_fisher_ext.m | 48 - misc/matlab/matlab_new/ld_fisher_ext2.m | 40 - misc/matlab/matlab_new/structs/collect.m | 12 - misc/matlab/matlab_new/structs/join.m | 13 - misc/matlab/mbicp/MbICP.m | 271 - misc/matlab/mbicp/datos.off | 3 - misc/matlab/mbicp/testMbICP.m | 18 - misc/matlab/msm/ld_alloc.m | 45 - misc/matlab/msm/ld_clustering.m | 1 - misc/matlab/msm/ld_to_json.m | 8 - misc/matlab/msm/matlab_to_json.m | 61 - misc/matlab/octave_compat/deg2rad.m | 2 - misc/matlab/orientation/arras_fit.m | 35 - .../orientation/computeSurfaceNormals.m | 59 - .../orientation/computeSurfaceNormals_sound.m | 114 - misc/matlab/orientation/estimate_derivative.m | 66 - .../orientation/estimate_derivative_single.m | 37 - .../orientation/ld_compute_orientation.m | 131 - .../orientation/ld_quality_of_orientation.m | 20 - misc/matlab/orientation/regression.m | 35 - misc/matlab/orientation/test_deriv.m | 96 - misc/matlab/orientation/test_est_deriv_log.m | 84 - misc/matlab/point-to-line/deg2rad.m | 2 - .../point-to-line/general_minimization.m | 88 - misc/matlab/point-to-line/gm_test.m | 19 - misc/matlab/point-to-line/icp2.m | 213 - misc/matlab/point-to-line/polyadd.m | 16 - misc/matlab/point-to-line/rad2deg.m | 2 - misc/matlab/point-to-line/rot.m | 3 - misc/matlab/point-to-line/test_icp2.m | 32 - misc/matlab/point-to-line/vers.m | 4 - misc/matlab/ray_tracing/countour_circle.m | 18 - misc/matlab/ray_tracing/countour_flower.m | 13 - misc/matlab/ray_tracing/countour_sine.m | 24 - misc/matlab/ray_tracing/countour_straight.m | 45 - misc/matlab/ray_tracing/ld_circle.m | 10 - misc/matlab/ray_tracing/ld_oval.m | 10 - misc/matlab/ray_tracing/ld_sine.m | 9 - misc/matlab/ray_tracing/ld_square.m | 12 - misc/matlab/ray_tracing/ray_tracing.m | 130 - misc/matlab/ray_tracing/ray_tracing_polygon.m | 96 - misc/matlab/ray_tracing/ts_flower.m | 15 - misc/matlab/ray_tracing/ts_square.m | 23 - misc/matlab/ray_tracing/ts_square2.m | 23 - misc/matlab/scripts/collate.rb | 37 - misc/matlab/scripts/create_package.rb | 113 - misc/matlab/scripts/find_dependencies.rb | 170 - misc/matlab/scripts/matlab2pdf.rb | 36 - misc/matlab/setall.m | 2 - misc/matlab/show_ci.m | 12 - misc/matlab/test_ci.m | 21 - misc/matlab/unsorted/mdisplay.m | 2 - misc/matlab/unsorted/normalize.m | 6 - misc/matlab/unsorted/prepareSampling.m | 26 - misc/matlab/unsorted/randf2.m | 29 - misc/matlab/unsorted/rtcat.m | 7 - misc/matlab/unsorted/sampleIndex.m | 4 - misc/matlab/unsorted/sample_normal.m | 7 - misc/matlab/unsorted/simpleLowPassFilter.m | 5 - misc/matlab/unsorted/simpleLowPassFilter2.m | 13 - .../unsorted/simpleLowPassFilterCircular.m | 7 - misc/matlab/unsorted/test_boh.m | 21 - misc/matlab/unsorted/test_inversa.m | 25 - misc/matlab/unsorted/test_lag.m | 168 - misc/matlab/unsorted/test_yasmine.m | 28 - misc/matlab/unsorted/test_yasmine2.m | 56 - misc/matlab/unsorted/test_yasmine3.m | 42 - misc/matlab/unsorted/test_yasmine3_an.m | 8 - misc/matlab/utils/deriv.m | 10 - misc/matlab/utils/file_exists.m | 8 - misc/matlab/utils/normAngle.m | 13 - misc/matlab/utils/params_required.m | 6 - misc/matlab/utils/params_set_default.m | 10 - misc/matlab/utils/pv.m | 15 - misc/matlab/utils/rot.m | 3 - misc/matlab/utils/transform.m | 5 - misc/matlab/utils/vers.m | 4 - misc/matlab/vis/createAnimation.m | 41 - misc/matlab/vis/ld_plot.m | 135 - misc/matlab/vis/plot3bars.m | 18 - misc/matlab/vis/plotGPM1.m | 25 - misc/matlab/vis/plotGauss2Db.m | 30 - misc/matlab/vis/plotLaserData.m | 52 - misc/matlab/vis/plotVectors.m | 15 - misc/matlab/vis/plot_xyt.m | 126 - misc/matlab/vis/plot_yasmine.m | 32 - misc/rsm/carmen2pic.rb | 168 - misc/rsm/fix_json.rb | 65 - misc/rsm/json_utils.rb | 18 - misc/rsm/lib/gpc.rb | 124 - misc/rsm/logreader.rb | 41 - misc/rsm/matlab_to_rbgsl.txt | 7 - misc/rsm/mt/mt.rb | 180 - misc/rsm/mt/mt.sh | 5 - misc/rsm/options.rb | 113 - misc/rsm/rsm.rb | 12 - misc/rsm/rsm_clustering.rb | 24 - misc/rsm/rsm_gpm.rb | 195 - misc/rsm/rsm_gpmicp.rb | 50 - misc/rsm/rsm_icp.rb | 174 - misc/rsm/rsm_icp_corr_dumb.rb | 98 - misc/rsm/rsm_icp_corr_tricks.rb | 292 - misc/rsm/rsm_icp_cov_exact.rb | 161 - misc/rsm/rsm_icp_cov_numeric.rb | 106 - misc/rsm/rsm_icp_outliers.rb | 44 - misc/rsm/rsm_journal.rb | 63 - misc/rsm/rsm_json_journal.rb | 28 - misc/rsm/rsm_laserdata.rb | 170 - misc/rsm/rsm_laserdata_carmen.rb | 67 - misc/rsm/rsm_laserdata_json.rb | 103 - misc/rsm/rsm_laserdata_ops.rb | 29 - misc/rsm/rsm_mathutils.rb | 148 - misc/rsm/rsm_misc.rb | 9 - misc/rsm/rsm_orientation.rb | 104 - misc/rsm/rsm_sm.rb | 32 - misc/rsm/rsm_sm_cov.rb | 106 - misc/rsm/rsm_sm_loop.rb | 85 - misc/rsm/sm_display.m | 156 - misc/rsm/test_json.rb | 0 misc/rsm/test_mathutils.rb | 14 - misc/rsm/tmp.rb | 3 - misc/sm_ruby_wrapper/extconf.rb | 63 - misc/sm_ruby_wrapper/go.sh | 6 - misc/sm_ruby_wrapper/lib/sm_gpm.rb | 41 - misc/sm_ruby_wrapper/lib/sm_icp.rb | 104 - misc/sm_ruby_wrapper/rb_sm.c | 96 - misc/sm_ruby_wrapper/rb_sm.h | 37 - misc/sm_ruby_wrapper/sm.i | 83 - misc/tests/failure1/Makefile | 20 - misc/tests/failure1/hokuyo.config | 29 - misc/tests/failure1/stallo2.log | 2 - misc/tests/failure2.json | 3 - scripts/cmd_utils.rb | 43 - scripts/create_video.rb | 98 - scripts/fig2pics.rb | 228 - scripts/hash_options.rb | 45 - scripts/json2matlab.rb | 145 - scripts/parser.rb.mine | 215 - sm/.gitignore | 8 - sm/AUTHORS | 10 - sm/CMakeLists.txt | 239 - sm/FindCairo.cmake | 69 - sm/FindGSL.cmake | 130 - sm/apps/carmen2json.c | 21 - sm/apps/carmen2pdf.c | 400 -- sm/apps/gtk_viewer/Makefile | 16 - sm/apps/gtk_viewer/goo_laser_data.c | 147 - sm/apps/gtk_viewer/goo_laser_data.h | 37 - sm/apps/gtk_viewer/gtk_viewer-readme.txt | 10 - sm/apps/gtk_viewer/gtk_viewer.h | 32 - sm/apps/gtk_viewer/gtk_viewer1.c | 264 - sm/apps/json2carmen.c | 21 - sm/apps/json2matlab.c | 286 - sm/apps/json_decimate.c | 54 - sm/apps/json_extract.c | 45 - sm/apps/json_extract_field.c | 103 - sm/apps/json_pipe.c | 35 - sm/apps/json_split.c | 58 - sm/apps/ld_alternate.c | 32 - sm/apps/ld_cluster_curv.c | 222 - sm/apps/ld_correct.c | 97 - sm/apps/ld_exp_tro1.c | 113 - sm/apps/ld_fisher.c | 46 - sm/apps/ld_linearize.c | 94 - sm/apps/ld_noise.c | 113 - sm/apps/ld_purify.c | 87 - sm/apps/ld_recover.c | 92 - sm/apps/ld_remove_doubles.c | 86 - sm/apps/ld_resample.c | 103 - sm/apps/ld_select.c | 4 - sm/apps/ld_slip.c | 105 - sm/apps/ld_smooth.c | 103 - sm/apps/ld_stats.c | 87 - sm/apps/log2pdf.c | 196 - sm/apps/map/CMakeLists.txt | 31 - sm/apps/map/many_points.config | 9 - sm/apps/map/map1.cpp | 128 - sm/apps/map/pan.cpp | 10 - sm/apps/map/pan.h | 19 - sm/apps/map/test_01.sh | 5 - sm/apps/qtv/CMakeLists.txt | 46 - sm/apps/qtv/design.txt | 68 - sm/apps/qtv/main.cpp | 71 - sm/apps/qtv/mouse.cpp | 176 - sm/apps/qtv/mouse.h | 65 - sm/apps/qtv/qfilereader.cpp | 30 - sm/apps/qtv/qfilereader.h | 22 - sm/apps/qtv/qlaserdata.cpp | 77 - sm/apps/qtv/qlaserdata.h | 28 - sm/apps/qtv/qmapview.cpp | 62 - sm/apps/qtv/qmapview.h | 24 - sm/apps/qtv/qparser.cpp | 11 - sm/apps/qtv/qparser.h | 22 - sm/apps/qtv/qscene.cpp | 20 - sm/apps/qtv/qscene.h | 24 - sm/apps/qtv/qtv.cpp | 32 - sm/apps/qtv/qtv.h | 22 - sm/apps/raytracer/CMakeLists.txt | 33 - sm/apps/raytracer/raytracer.cpp | 197 - sm/apps/raytracer/raytracer.h | 18 - sm/apps/raytracer/simplemap.cpp | 56 - sm/apps/raytracer/simplemap.h | 63 - sm/apps/raytracer/simplemap_obst.cpp | 17 - sm/apps/raytracer/test01-map.json | 5 - sm/apps/raytracer/test01-scans.json.expected | 1 - sm/apps/raytracer/test01.sh | 4 - sm/apps/raytracer/tests/example-map.json | 15 - sm/apps/sm0.c | 95 - sm/apps/sm1.c | 206 - sm/apps/sm2.c | 190 - sm/apps/sm3.c | 89 - sm/apps/sm_animate.c | 229 - sm/apps/test_json.c | 11 - sm/apps/test_json_ld.c | 22 - sm/csm/CMakeLists.txt | 51 - sm/csm/csm.h | 21 - sm/csm/gpm/gpm.c | 286 - sm/csm/gpm/gpm.h | 17 - sm/csm/gpm/gpm_readme.txt | 7 - sm/csm/hsm/CMakeLists.txt | 10 - sm/csm/hsm/hsm.c | 596 -- sm/csm/hsm/hsm.h | 160 - sm/csm/hsm/hsm_interface.c | 126 - sm/csm/hsm/hsm_interface.h | 17 - sm/csm/hsm/hsm_test00.c | 185 - sm/csm/hsm/hsm_test01.c | 0 sm/csm/hsm/tests/hsmtest.sh | 18 - sm/csm/hsm/tests/hsmtest2.sh | 19 - sm/csm/hsm/tests/tunnel1.png | Bin 33064 -> 0 bytes sm/csm/hsm/tests/tunnel2.png | Bin 44606 -> 0 bytes sm/csm/icp/fast_math.h | 0 sm/csm/json_journal.c | 115 - sm/csm/json_journal.h | 53 - sm/csm/laser_data_bbox.c | 260 - sm/csm/laser_data_cairo.c | 397 -- sm/csm/laser_data_cairo.h | 65 - sm/csm/laser_data_carmen.c | 223 - sm/csm/laser_data_drawing.c | 144 - sm/csm/laser_data_drawing.h | 74 - sm/csm/laser_data_fisher.c | 43 - sm/csm/laser_data_json.c | 268 - sm/csm/laser_data_json.h | 32 - sm/csm/laser_data_load.c | 189 - sm/csm/math_utils_gsl.c | 104 - sm/csm/math_utils_gsl.h | 41 - sm/csm/math_utils_test.c | 155 - sm/csm/mbicp/MbICP.c | 678 --- sm/csm/mbicp/MbICP.h | 163 - sm/csm/mbicp/MbICP2.h | 138 - sm/csm/mbicp/TData.h | 68 - sm/csm/mbicp/calcul.c | 187 - sm/csm/mbicp/calcul.h | 118 - sm/csm/mbicp/mbicp_driver.cc | 693 --- sm/csm/mbicp/mbicp_interface.c | 24 - sm/csm/mbicp/percolate.c | 37 - sm/csm/mbicp/percolate.h | 18 - sm/csm/mbicp/sp_matrix.c | 253 - sm/csm/mbicp/sp_matrix.h | 76 - sm/csm/test_math_utils_sanity.c | 24 - sm/header_test.c.in | 3 - sm/lib/egsl/CMakeLists.txt | 22 - sm/lib/egsl/docs/Makefile | 21 - sm/lib/egsl/docs/egsl.html | 293 - sm/lib/egsl/docs/egsl.md | 216 - sm/lib/egsl/docs/egsl.txt | 218 - sm/lib/egsl/docs/footer.html_frag | 2 - sm/lib/egsl/docs/header.html_frag | 33 - sm/lib/egsl/docs/htmlsection | 1022 ---- sm/lib/egsl/docs/htmlsection.txt | 358 -- sm/lib/egsl/egsl_conversions.c | 64 - sm/lib/egsl/egsl_ops.c | 172 - sm/lib/egsl/egsl_test.c | 41 - sm/lib/egsl/egsl_test_allocation.c | 23 - sm/lib/gpc/CMakeLists.txt | 7 - sm/lib/gpc/gpc_test.c | 52 - sm/lib/gpc/gpc_utils.c | 134 - sm/lib/json-c/CMakeLists.txt | 81 - sm/lib/json-c/JSON_checker.c | 414 -- sm/lib/json-c/JSON_checker.h | 10 - sm/lib/json-c/arraylist.c | 93 - sm/lib/json-c/arraylist.h | 45 - sm/lib/json-c/bits.h | 27 - sm/lib/json-c/config.h.cmake | 101 - sm/lib/json-c/debug.c | 94 - sm/lib/json-c/debug.h | 24 - sm/lib/json-c/json.h | 32 - sm/lib/json-c/json_more_utils.c | 331 -- sm/lib/json-c/json_more_utils.h | 77 - sm/lib/json-c/json_object.c | 541 -- sm/lib/json-c/json_object.h | 315 -- sm/lib/json-c/json_object_private.h | 46 - sm/lib/json-c/json_tokener.c | 517 -- sm/lib/json-c/json_tokener.h | 89 - sm/lib/json-c/json_util.c | 121 - sm/lib/json-c/json_util.h | 23 - sm/lib/json-c/linkhash.c | 217 - sm/lib/json-c/linkhash.h | 261 - sm/lib/json-c/printbuf.c | 144 - sm/lib/json-c/printbuf.h | 38 - sm/lib/json-c/test1.c | 181 - sm/lib/json-c/test2.c | 20 - sm/lib/options/CMakeLists.txt | 12 - sm/lib/options/ruby/options.rb | 143 - sm/lib/options/test_options.c | 42 - sm/pkg-config/CMakeLists.txt | 4 - sm/pkg-config/csm.pc.in | 10 - src/CMakeLists.txt | 64 + src/cmake/.svn/all-wcprops | 11 + src/cmake/.svn/entries | 62 + .../.svn/text-base/FindEigen3.cmake.svn-base | 81 + src/cmake/FindEigen3.cmake | 81 + sm/csm/clustering.c => src/csm/clustering.cpp | 0 {sm => src}/csm/csm_all.h | 8 +- sm/csm/laser_data.c => src/csm/laser_data.cpp | 26 +- sm/csm/logging.c => src/csm/logging.cpp | 2 +- {sm => src}/csm/logging.h | 0 sm/csm/math_utils.c => src/csm/math_utils.cpp | 10 +- {sm => src}/csm/math_utils.h | 0 src/csm/math_utils_gsl.cpp | 104 + src/csm/math_utils_gsl.h | 41 + .../orientation.c => src/csm/orientation.cpp | 47 +- sm/csm/sm_options.c => src/csm/sm_options.cpp | 17 +- src/csm/sm_options.h | 9 + sm/csm/utils.c => src/csm/utils.cpp | 2 + {sm => src}/csm/utils.h | 0 sm/lib/egsl/egsl.c => src/egsl/egsl.cpp | 133 +- {sm/lib => src}/egsl/egsl.h | 42 +- src/egsl/egsl_conversions.cpp | 64 + {sm/lib => src}/egsl/egsl_imp.h | 0 {sm/lib => src}/egsl/egsl_macros.h | 0 .../egsl_misc.c => src/egsl/egsl_misc.cpp | 32 +- src/egsl/egsl_ops.cpp | 185 + sm/lib/gpc/gpc.c => src/gpc/gpc.cpp | 114 +- {sm/lib => src}/gpc/gpc.h | 6 +- src/gpc/gpc_utils.cpp | 170 + {sm/lib => src}/gpc/gpc_utils.h | 14 +- sm/csm/icp/icp.c => src/icp/icp.cpp | 31 +- {sm/csm => src}/icp/icp.h | 4 +- .../icp/icp_corr_dumb.cpp | 7 +- .../icp/icp_corr_tricks.cpp | 12 +- .../icp/icp_covariance.cpp | 7 +- .../icp/icp_debug.c => src/icp/icp_debug.cpp | 9 +- sm/csm/icp/icp_loop.c => src/icp/icp_loop.cpp | 42 +- .../icp/icp_outliers.cpp | 51 +- .../options.c => src/options/options.cpp | 197 +- {sm/lib => src}/options/options.h | 16 +- .../options/options_interface.cpp | 2 +- website/.gitignore | 1 - website/Makefile | 5 - website/init_website.sh | 8 - website/source/a.gif | Bin 109136 -> 0 bytes website/source/index.html | 53 - website/source/index.md | 57 - website/source/sm_icp_zoom_crop.gif | Bin 381500 -> 0 bytes website/source/sm_plicp_zoom_crop.gif | Bin 97030 -> 0 bytes 439 files changed, 1408 insertions(+), 37859 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 Doxyfile delete mode 100644 TODO.txt delete mode 100644 csm_manual.html delete mode 100644 csm_manual.pdf delete mode 100644 docs/Makefile delete mode 100644 docs/TODO.txt delete mode 100644 docs/description.lyx delete mode 100644 docs/embedding.txt delete mode 100644 docs/example-linking-cmake/CMakeLists.txt delete mode 100644 docs/example-linking-cmake/myprogram.c delete mode 100644 docs/example-linking-make/Makefile delete mode 100644 docs/example-linking-make/myprogram.c delete mode 100644 docs/examples.txt delete mode 100644 docs/formats.txt delete mode 100644 docs/inline_style.css delete mode 100644 docs/install-ruby.txt delete mode 100644 docs/install.txt delete mode 100644 docs/laserdata.lyx delete mode 100644 docs/laserdata.txt delete mode 100644 docs/misc.txt delete mode 100644 docs/optimization-notes.txt delete mode 100644 docs/optimizations.txt delete mode 100644 docs/other.txt delete mode 100644 docs/preamble.tex delete mode 100644 docs/preamble.txt delete mode 100644 docs/readme.txt delete mode 100644 docs/references.txt delete mode 100644 docs/style.css delete mode 100644 docs/todo.mm delete mode 100644 docs/troubleshootings.txt rename {sm => include}/csm/algos.h (89%) create mode 100644 include/csm/csm.h rename {sm => include}/csm/laser_data.h (97%) rename {sm => include}/csm/laser_data_inline.h (85%) rename {sm => include}/csm/restrict.h (95%) create mode 100644 include/gsl_eigen/gsl_eigen.h delete mode 100755 install_quickstart.sh delete mode 100644 local_config/icc-warnings.txt delete mode 100644 local_config/local-Melania.cmake delete mode 100644 local_config/local-linuxserv-icc.cmake delete mode 100644 local_config/local-linuxserv.cmake delete mode 100644 local_config/local-lisablack.cmake delete mode 100644 local_config/local-overlook.cmake delete mode 100644 local_config/local-pammela.cmake delete mode 100644 local_config/local-pdelapuente.cmake delete mode 100644 local_config/local-sorchetta.cmake delete mode 100644 misc/matlab/appunti/MMt.png delete mode 100644 misc/matlab/appunti/problem.eps delete mode 100644 misc/matlab/appunti/problem.fig delete mode 100644 misc/matlab/carmen/convertFile.m delete mode 100644 misc/matlab/carmen/convertLine.m delete mode 100644 misc/matlab/carmen/readFileInCells.m delete mode 100644 misc/matlab/carmen/reading.m delete mode 100644 misc/matlab/ci.m delete mode 100644 misc/matlab/cramer_rao/compute_bounds.m delete mode 100644 misc/matlab/cramer_rao/plot_bounds.m delete mode 100644 misc/matlab/cramer_rao/square.pdf delete mode 100644 misc/matlab/cramer_rao/test_bounds_circle.m delete mode 100644 misc/matlab/cramer_rao/test_bounds_oval.m delete mode 100644 misc/matlab/cramer_rao/test_bounds_square.m delete mode 100644 misc/matlab/cramer_rao/test_bounds_square2_tmp.m delete mode 100644 misc/matlab/cramer_rao/test_unstructured.m delete mode 100644 misc/matlab/cramer_rao/test_unstructured_print.m delete mode 100755 misc/matlab/gpm/go.sh delete mode 100644 misc/matlab/gpm/gpm.m delete mode 100644 misc/matlab/gpm/gpmSample.m delete mode 100644 misc/matlab/gpm/gpm_plot_res.m delete mode 100644 misc/matlab/gpm/gpm_test.m delete mode 100644 misc/matlab/gpm/gpm_test2.m delete mode 100644 misc/matlab/gpm/test.tex delete mode 100644 misc/matlab/gpm/test_gpm.m delete mode 100644 misc/matlab/gpm/yasmine.m delete mode 100644 misc/matlab/gpm/yasmine2.m delete mode 100644 misc/matlab/icp/closest_point_on_segment.m delete mode 100644 misc/matlab/icp/exact_minimization.m delete mode 100644 misc/matlab/icp/icp.m delete mode 100644 misc/matlab/icp/icp_covariance.m delete mode 100644 misc/matlab/icp/icp_get_correspondences.m delete mode 100644 misc/matlab/icp/icp_possible_interval.m delete mode 100644 misc/matlab/icp/test_icp_1.m delete mode 100644 misc/matlab/icpcov/derivn.m delete mode 100644 misc/matlab/matlab_new/display/display_cov.m delete mode 100644 misc/matlab/matlab_new/ld_fisher0.m delete mode 100644 misc/matlab/matlab_new/ld_fisher_ext.m delete mode 100644 misc/matlab/matlab_new/ld_fisher_ext2.m delete mode 100644 misc/matlab/matlab_new/structs/collect.m delete mode 100644 misc/matlab/matlab_new/structs/join.m delete mode 100644 misc/matlab/mbicp/MbICP.m delete mode 100644 misc/matlab/mbicp/datos.off delete mode 100644 misc/matlab/mbicp/testMbICP.m delete mode 100644 misc/matlab/msm/ld_alloc.m delete mode 100644 misc/matlab/msm/ld_clustering.m delete mode 100644 misc/matlab/msm/ld_to_json.m delete mode 100644 misc/matlab/msm/matlab_to_json.m delete mode 100644 misc/matlab/octave_compat/deg2rad.m delete mode 100644 misc/matlab/orientation/arras_fit.m delete mode 100644 misc/matlab/orientation/computeSurfaceNormals.m delete mode 100644 misc/matlab/orientation/computeSurfaceNormals_sound.m delete mode 100644 misc/matlab/orientation/estimate_derivative.m delete mode 100644 misc/matlab/orientation/estimate_derivative_single.m delete mode 100644 misc/matlab/orientation/ld_compute_orientation.m delete mode 100644 misc/matlab/orientation/ld_quality_of_orientation.m delete mode 100644 misc/matlab/orientation/regression.m delete mode 100644 misc/matlab/orientation/test_deriv.m delete mode 100644 misc/matlab/orientation/test_est_deriv_log.m delete mode 100644 misc/matlab/point-to-line/deg2rad.m delete mode 100644 misc/matlab/point-to-line/general_minimization.m delete mode 100644 misc/matlab/point-to-line/gm_test.m delete mode 100644 misc/matlab/point-to-line/icp2.m delete mode 100644 misc/matlab/point-to-line/polyadd.m delete mode 100644 misc/matlab/point-to-line/rad2deg.m delete mode 100644 misc/matlab/point-to-line/rot.m delete mode 100644 misc/matlab/point-to-line/test_icp2.m delete mode 100644 misc/matlab/point-to-line/vers.m delete mode 100644 misc/matlab/ray_tracing/countour_circle.m delete mode 100644 misc/matlab/ray_tracing/countour_flower.m delete mode 100644 misc/matlab/ray_tracing/countour_sine.m delete mode 100644 misc/matlab/ray_tracing/countour_straight.m delete mode 100644 misc/matlab/ray_tracing/ld_circle.m delete mode 100644 misc/matlab/ray_tracing/ld_oval.m delete mode 100644 misc/matlab/ray_tracing/ld_sine.m delete mode 100644 misc/matlab/ray_tracing/ld_square.m delete mode 100644 misc/matlab/ray_tracing/ray_tracing.m delete mode 100644 misc/matlab/ray_tracing/ray_tracing_polygon.m delete mode 100644 misc/matlab/ray_tracing/ts_flower.m delete mode 100644 misc/matlab/ray_tracing/ts_square.m delete mode 100644 misc/matlab/ray_tracing/ts_square2.m delete mode 100755 misc/matlab/scripts/collate.rb delete mode 100755 misc/matlab/scripts/create_package.rb delete mode 100755 misc/matlab/scripts/find_dependencies.rb delete mode 100644 misc/matlab/scripts/matlab2pdf.rb delete mode 100644 misc/matlab/setall.m delete mode 100644 misc/matlab/show_ci.m delete mode 100644 misc/matlab/test_ci.m delete mode 100644 misc/matlab/unsorted/mdisplay.m delete mode 100755 misc/matlab/unsorted/normalize.m delete mode 100644 misc/matlab/unsorted/prepareSampling.m delete mode 100644 misc/matlab/unsorted/randf2.m delete mode 100644 misc/matlab/unsorted/rtcat.m delete mode 100644 misc/matlab/unsorted/sampleIndex.m delete mode 100644 misc/matlab/unsorted/sample_normal.m delete mode 100755 misc/matlab/unsorted/simpleLowPassFilter.m delete mode 100755 misc/matlab/unsorted/simpleLowPassFilter2.m delete mode 100755 misc/matlab/unsorted/simpleLowPassFilterCircular.m delete mode 100644 misc/matlab/unsorted/test_boh.m delete mode 100644 misc/matlab/unsorted/test_inversa.m delete mode 100644 misc/matlab/unsorted/test_lag.m delete mode 100644 misc/matlab/unsorted/test_yasmine.m delete mode 100644 misc/matlab/unsorted/test_yasmine2.m delete mode 100644 misc/matlab/unsorted/test_yasmine3.m delete mode 100644 misc/matlab/unsorted/test_yasmine3_an.m delete mode 100644 misc/matlab/utils/deriv.m delete mode 100644 misc/matlab/utils/file_exists.m delete mode 100644 misc/matlab/utils/normAngle.m delete mode 100644 misc/matlab/utils/params_required.m delete mode 100644 misc/matlab/utils/params_set_default.m delete mode 100644 misc/matlab/utils/pv.m delete mode 100644 misc/matlab/utils/rot.m delete mode 100644 misc/matlab/utils/transform.m delete mode 100644 misc/matlab/utils/vers.m delete mode 100644 misc/matlab/vis/createAnimation.m delete mode 100644 misc/matlab/vis/ld_plot.m delete mode 100644 misc/matlab/vis/plot3bars.m delete mode 100644 misc/matlab/vis/plotGPM1.m delete mode 100644 misc/matlab/vis/plotGauss2Db.m delete mode 100644 misc/matlab/vis/plotLaserData.m delete mode 100644 misc/matlab/vis/plotVectors.m delete mode 100644 misc/matlab/vis/plot_xyt.m delete mode 100644 misc/matlab/vis/plot_yasmine.m delete mode 100644 misc/rsm/carmen2pic.rb delete mode 100644 misc/rsm/fix_json.rb delete mode 100644 misc/rsm/json_utils.rb delete mode 100644 misc/rsm/lib/gpc.rb delete mode 100755 misc/rsm/logreader.rb delete mode 100644 misc/rsm/matlab_to_rbgsl.txt delete mode 100755 misc/rsm/mt/mt.rb delete mode 100755 misc/rsm/mt/mt.sh delete mode 100644 misc/rsm/options.rb delete mode 100644 misc/rsm/rsm.rb delete mode 100644 misc/rsm/rsm_clustering.rb delete mode 100644 misc/rsm/rsm_gpm.rb delete mode 100644 misc/rsm/rsm_gpmicp.rb delete mode 100644 misc/rsm/rsm_icp.rb delete mode 100644 misc/rsm/rsm_icp_corr_dumb.rb delete mode 100644 misc/rsm/rsm_icp_corr_tricks.rb delete mode 100644 misc/rsm/rsm_icp_cov_exact.rb delete mode 100644 misc/rsm/rsm_icp_cov_numeric.rb delete mode 100644 misc/rsm/rsm_icp_outliers.rb delete mode 100644 misc/rsm/rsm_journal.rb delete mode 100644 misc/rsm/rsm_json_journal.rb delete mode 100644 misc/rsm/rsm_laserdata.rb delete mode 100644 misc/rsm/rsm_laserdata_carmen.rb delete mode 100644 misc/rsm/rsm_laserdata_json.rb delete mode 100644 misc/rsm/rsm_laserdata_ops.rb delete mode 100644 misc/rsm/rsm_mathutils.rb delete mode 100755 misc/rsm/rsm_misc.rb delete mode 100644 misc/rsm/rsm_orientation.rb delete mode 100755 misc/rsm/rsm_sm.rb delete mode 100755 misc/rsm/rsm_sm_cov.rb delete mode 100644 misc/rsm/rsm_sm_loop.rb delete mode 100644 misc/rsm/sm_display.m delete mode 100644 misc/rsm/test_json.rb delete mode 100644 misc/rsm/test_mathutils.rb delete mode 100644 misc/rsm/tmp.rb delete mode 100644 misc/sm_ruby_wrapper/extconf.rb delete mode 100755 misc/sm_ruby_wrapper/go.sh delete mode 100644 misc/sm_ruby_wrapper/lib/sm_gpm.rb delete mode 100644 misc/sm_ruby_wrapper/lib/sm_icp.rb delete mode 100644 misc/sm_ruby_wrapper/rb_sm.c delete mode 100644 misc/sm_ruby_wrapper/rb_sm.h delete mode 100644 misc/sm_ruby_wrapper/sm.i delete mode 100644 misc/tests/failure1/Makefile delete mode 100644 misc/tests/failure1/hokuyo.config delete mode 100644 misc/tests/failure1/stallo2.log delete mode 100644 misc/tests/failure2.json delete mode 100644 scripts/cmd_utils.rb delete mode 100755 scripts/create_video.rb delete mode 100755 scripts/fig2pics.rb delete mode 100644 scripts/hash_options.rb delete mode 100755 scripts/json2matlab.rb delete mode 100644 scripts/parser.rb.mine delete mode 100644 sm/.gitignore delete mode 100644 sm/AUTHORS delete mode 100644 sm/CMakeLists.txt delete mode 100644 sm/FindCairo.cmake delete mode 100644 sm/FindGSL.cmake delete mode 100644 sm/apps/carmen2json.c delete mode 100644 sm/apps/carmen2pdf.c delete mode 100644 sm/apps/gtk_viewer/Makefile delete mode 100644 sm/apps/gtk_viewer/goo_laser_data.c delete mode 100644 sm/apps/gtk_viewer/goo_laser_data.h delete mode 100644 sm/apps/gtk_viewer/gtk_viewer-readme.txt delete mode 100644 sm/apps/gtk_viewer/gtk_viewer.h delete mode 100644 sm/apps/gtk_viewer/gtk_viewer1.c delete mode 100644 sm/apps/json2carmen.c delete mode 100644 sm/apps/json2matlab.c delete mode 100644 sm/apps/json_decimate.c delete mode 100644 sm/apps/json_extract.c delete mode 100644 sm/apps/json_extract_field.c delete mode 100644 sm/apps/json_pipe.c delete mode 100644 sm/apps/json_split.c delete mode 100644 sm/apps/ld_alternate.c delete mode 100644 sm/apps/ld_cluster_curv.c delete mode 100644 sm/apps/ld_correct.c delete mode 100644 sm/apps/ld_exp_tro1.c delete mode 100644 sm/apps/ld_fisher.c delete mode 100644 sm/apps/ld_linearize.c delete mode 100644 sm/apps/ld_noise.c delete mode 100644 sm/apps/ld_purify.c delete mode 100644 sm/apps/ld_recover.c delete mode 100644 sm/apps/ld_remove_doubles.c delete mode 100644 sm/apps/ld_resample.c delete mode 100644 sm/apps/ld_select.c delete mode 100644 sm/apps/ld_slip.c delete mode 100644 sm/apps/ld_smooth.c delete mode 100644 sm/apps/ld_stats.c delete mode 100644 sm/apps/log2pdf.c delete mode 100644 sm/apps/map/CMakeLists.txt delete mode 100644 sm/apps/map/many_points.config delete mode 100644 sm/apps/map/map1.cpp delete mode 100644 sm/apps/map/pan.cpp delete mode 100644 sm/apps/map/pan.h delete mode 100755 sm/apps/map/test_01.sh delete mode 100644 sm/apps/qtv/CMakeLists.txt delete mode 100644 sm/apps/qtv/design.txt delete mode 100644 sm/apps/qtv/main.cpp delete mode 100644 sm/apps/qtv/mouse.cpp delete mode 100644 sm/apps/qtv/mouse.h delete mode 100644 sm/apps/qtv/qfilereader.cpp delete mode 100644 sm/apps/qtv/qfilereader.h delete mode 100644 sm/apps/qtv/qlaserdata.cpp delete mode 100644 sm/apps/qtv/qlaserdata.h delete mode 100644 sm/apps/qtv/qmapview.cpp delete mode 100644 sm/apps/qtv/qmapview.h delete mode 100644 sm/apps/qtv/qparser.cpp delete mode 100644 sm/apps/qtv/qparser.h delete mode 100644 sm/apps/qtv/qscene.cpp delete mode 100644 sm/apps/qtv/qscene.h delete mode 100644 sm/apps/qtv/qtv.cpp delete mode 100644 sm/apps/qtv/qtv.h delete mode 100644 sm/apps/raytracer/CMakeLists.txt delete mode 100644 sm/apps/raytracer/raytracer.cpp delete mode 100644 sm/apps/raytracer/raytracer.h delete mode 100644 sm/apps/raytracer/simplemap.cpp delete mode 100644 sm/apps/raytracer/simplemap.h delete mode 100644 sm/apps/raytracer/simplemap_obst.cpp delete mode 100644 sm/apps/raytracer/test01-map.json delete mode 100644 sm/apps/raytracer/test01-scans.json.expected delete mode 100755 sm/apps/raytracer/test01.sh delete mode 100644 sm/apps/raytracer/tests/example-map.json delete mode 100644 sm/apps/sm0.c delete mode 100644 sm/apps/sm1.c delete mode 100644 sm/apps/sm2.c delete mode 100644 sm/apps/sm3.c delete mode 100644 sm/apps/sm_animate.c delete mode 100644 sm/apps/test_json.c delete mode 100644 sm/apps/test_json_ld.c delete mode 100644 sm/csm/CMakeLists.txt delete mode 100644 sm/csm/csm.h delete mode 100644 sm/csm/gpm/gpm.c delete mode 100644 sm/csm/gpm/gpm.h delete mode 100644 sm/csm/gpm/gpm_readme.txt delete mode 100644 sm/csm/hsm/CMakeLists.txt delete mode 100644 sm/csm/hsm/hsm.c delete mode 100644 sm/csm/hsm/hsm.h delete mode 100644 sm/csm/hsm/hsm_interface.c delete mode 100644 sm/csm/hsm/hsm_interface.h delete mode 100644 sm/csm/hsm/hsm_test00.c delete mode 100644 sm/csm/hsm/hsm_test01.c delete mode 100755 sm/csm/hsm/tests/hsmtest.sh delete mode 100755 sm/csm/hsm/tests/hsmtest2.sh delete mode 100644 sm/csm/hsm/tests/tunnel1.png delete mode 100644 sm/csm/hsm/tests/tunnel2.png delete mode 100644 sm/csm/icp/fast_math.h delete mode 100644 sm/csm/json_journal.c delete mode 100644 sm/csm/json_journal.h delete mode 100644 sm/csm/laser_data_bbox.c delete mode 100644 sm/csm/laser_data_cairo.c delete mode 100644 sm/csm/laser_data_cairo.h delete mode 100644 sm/csm/laser_data_carmen.c delete mode 100644 sm/csm/laser_data_drawing.c delete mode 100644 sm/csm/laser_data_drawing.h delete mode 100644 sm/csm/laser_data_fisher.c delete mode 100644 sm/csm/laser_data_json.c delete mode 100644 sm/csm/laser_data_json.h delete mode 100644 sm/csm/laser_data_load.c delete mode 100644 sm/csm/math_utils_gsl.c delete mode 100644 sm/csm/math_utils_gsl.h delete mode 100644 sm/csm/math_utils_test.c delete mode 100644 sm/csm/mbicp/MbICP.c delete mode 100644 sm/csm/mbicp/MbICP.h delete mode 100644 sm/csm/mbicp/MbICP2.h delete mode 100644 sm/csm/mbicp/TData.h delete mode 100644 sm/csm/mbicp/calcul.c delete mode 100644 sm/csm/mbicp/calcul.h delete mode 100644 sm/csm/mbicp/mbicp_driver.cc delete mode 100644 sm/csm/mbicp/mbicp_interface.c delete mode 100644 sm/csm/mbicp/percolate.c delete mode 100644 sm/csm/mbicp/percolate.h delete mode 100644 sm/csm/mbicp/sp_matrix.c delete mode 100644 sm/csm/mbicp/sp_matrix.h delete mode 100644 sm/csm/test_math_utils_sanity.c delete mode 100644 sm/header_test.c.in delete mode 100644 sm/lib/egsl/CMakeLists.txt delete mode 100644 sm/lib/egsl/docs/Makefile delete mode 100644 sm/lib/egsl/docs/egsl.html delete mode 100644 sm/lib/egsl/docs/egsl.md delete mode 100644 sm/lib/egsl/docs/egsl.txt delete mode 100644 sm/lib/egsl/docs/footer.html_frag delete mode 100644 sm/lib/egsl/docs/header.html_frag delete mode 100755 sm/lib/egsl/docs/htmlsection delete mode 100755 sm/lib/egsl/docs/htmlsection.txt delete mode 100644 sm/lib/egsl/egsl_conversions.c delete mode 100644 sm/lib/egsl/egsl_ops.c delete mode 100644 sm/lib/egsl/egsl_test.c delete mode 100644 sm/lib/egsl/egsl_test_allocation.c delete mode 100644 sm/lib/gpc/CMakeLists.txt delete mode 100644 sm/lib/gpc/gpc_test.c delete mode 100644 sm/lib/gpc/gpc_utils.c delete mode 100644 sm/lib/json-c/CMakeLists.txt delete mode 100644 sm/lib/json-c/JSON_checker.c delete mode 100644 sm/lib/json-c/JSON_checker.h delete mode 100644 sm/lib/json-c/arraylist.c delete mode 100644 sm/lib/json-c/arraylist.h delete mode 100644 sm/lib/json-c/bits.h delete mode 100644 sm/lib/json-c/config.h.cmake delete mode 100644 sm/lib/json-c/debug.c delete mode 100644 sm/lib/json-c/debug.h delete mode 100644 sm/lib/json-c/json.h delete mode 100644 sm/lib/json-c/json_more_utils.c delete mode 100644 sm/lib/json-c/json_more_utils.h delete mode 100644 sm/lib/json-c/json_object.c delete mode 100644 sm/lib/json-c/json_object.h delete mode 100644 sm/lib/json-c/json_object_private.h delete mode 100644 sm/lib/json-c/json_tokener.c delete mode 100644 sm/lib/json-c/json_tokener.h delete mode 100644 sm/lib/json-c/json_util.c delete mode 100644 sm/lib/json-c/json_util.h delete mode 100644 sm/lib/json-c/linkhash.c delete mode 100644 sm/lib/json-c/linkhash.h delete mode 100644 sm/lib/json-c/printbuf.c delete mode 100644 sm/lib/json-c/printbuf.h delete mode 100644 sm/lib/json-c/test1.c delete mode 100644 sm/lib/json-c/test2.c delete mode 100644 sm/lib/options/CMakeLists.txt delete mode 100644 sm/lib/options/ruby/options.rb delete mode 100644 sm/lib/options/test_options.c delete mode 100644 sm/pkg-config/CMakeLists.txt delete mode 100644 sm/pkg-config/csm.pc.in create mode 100644 src/CMakeLists.txt create mode 100644 src/cmake/.svn/all-wcprops create mode 100644 src/cmake/.svn/entries create mode 100644 src/cmake/.svn/text-base/FindEigen3.cmake.svn-base create mode 100644 src/cmake/FindEigen3.cmake rename sm/csm/clustering.c => src/csm/clustering.cpp (100%) rename {sm => src}/csm/csm_all.h (73%) rename sm/csm/laser_data.c => src/csm/laser_data.cpp (86%) rename sm/csm/logging.c => src/csm/logging.cpp (99%) rename {sm => src}/csm/logging.h (100%) rename sm/csm/math_utils.c => src/csm/math_utils.cpp (96%) rename {sm => src}/csm/math_utils.h (100%) create mode 100644 src/csm/math_utils_gsl.cpp create mode 100644 src/csm/math_utils_gsl.h rename sm/csm/orientation.c => src/csm/orientation.cpp (73%) rename sm/csm/sm_options.c => src/csm/sm_options.cpp (88%) create mode 100644 src/csm/sm_options.h rename sm/csm/utils.c => src/csm/utils.cpp (98%) rename {sm => src}/csm/utils.h (100%) rename sm/lib/egsl/egsl.c => src/egsl/egsl.cpp (70%) rename {sm/lib => src}/egsl/egsl.h (71%) create mode 100644 src/egsl/egsl_conversions.cpp rename {sm/lib => src}/egsl/egsl_imp.h (100%) rename {sm/lib => src}/egsl/egsl_macros.h (100%) rename sm/lib/egsl/egsl_misc.c => src/egsl/egsl_misc.cpp (52%) create mode 100644 src/egsl/egsl_ops.cpp rename sm/lib/gpc/gpc.c => src/gpc/gpc.cpp (87%) rename {sm/lib => src}/gpc/gpc.h (91%) create mode 100644 src/gpc/gpc_utils.cpp rename {sm/lib => src}/gpc/gpc_utils.h (74%) rename sm/csm/icp/icp.c => src/icp/icp.cpp (89%) rename {sm/csm => src}/icp/icp.h (97%) rename sm/csm/icp/icp_corr_dumb.c => src/icp/icp_corr_dumb.cpp (93%) rename sm/csm/icp/icp_corr_tricks.c => src/icp/icp_corr_tricks.cpp (96%) rename sm/csm/icp/icp_covariance.c => src/icp/icp_covariance.cpp (97%) rename sm/csm/icp/icp_debug.c => src/icp/icp_debug.cpp (78%) rename sm/csm/icp/icp_loop.c => src/icp/icp_loop.cpp (91%) rename sm/csm/icp/icp_outliers.c => src/icp/icp_outliers.cpp (79%) rename sm/lib/options/options.c => src/options/options.cpp (74%) rename {sm/lib => src}/options/options.h (93%) rename sm/lib/options/options_interface.c => src/options/options_interface.cpp (96%) delete mode 100644 website/.gitignore delete mode 100644 website/Makefile delete mode 100755 website/init_website.sh delete mode 100644 website/source/a.gif delete mode 100644 website/source/index.html delete mode 100644 website/source/index.md delete mode 100644 website/source/sm_icp_zoom_crop.gif delete mode 100644 website/source/sm_plicp_zoom_crop.gif diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 32297b8..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 2.4) -cmake_policy(SET CMP0004 OLD) -SET(local_prefix "local_config/local-") -FIND_PROGRAM(HOSTNAME hostname PATHS $ENV{PATH}) -IF(HOSTNAME) - # TODO: hostname does not accept -s on cygwin - IF(CYGWIN OR WIN32) - SET(hostname_params "") - ELSE(CYGWIN OR WIN32) - SET(hostname_params "-s") - ENDIF(CYGWIN OR WIN32) - - EXEC_PROGRAM(${HOSTNAME} ARGS ${hostname_params} OUTPUT_VARIABLE host) - - SET(local "${local_prefix}${host}.cmake") - - SET(extension "$ENV{CSM_CONF}") - IF(extension) - SET(local "${local_prefix}${host}-${extension}.cmake") - ENDIF(extension) - - IF(EXISTS ${local}) - MESSAGE(STATUS "Including local configuration ${local}.") - INCLUDE(${local}) - ELSE(EXISTS ${local}) - MESSAGE(STATUS "Create a file named '${local}' if you want to add options.") - ENDIF(EXISTS ${local}) -ELSE(HOSTNAME) - MESSAGE(STATUS "Program `hostname` not found. (don't worry)") -ENDIF(HOSTNAME) - - -ENABLE_TESTING() -SUBDIRS(sm) diff --git a/Doxyfile b/Doxyfile deleted file mode 100644 index 46d2d74..0000000 --- a/Doxyfile +++ /dev/null @@ -1,1218 +0,0 @@ -# Doxyfile 1.4.2 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = CSM - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doxy - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, -# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, -# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, -# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, -# Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. - -SHOW_DIRECTORIES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the progam writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = sm/ - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = YES - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index 6bf8842..0000000 --- a/TODO.txt +++ /dev/null @@ -1,3 +0,0 @@ -* add FAQ from email w/Tarek -* add link to algos.h in the manual -* publish gh-pages diff --git a/csm_manual.html b/csm_manual.html deleted file mode 100644 index 77bd28b..0000000 --- a/csm_manual.html +++ /dev/null @@ -1,675 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC - "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" - "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> -<html xmlns:svg='http://www.w3.org/2000/svg' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'> -<head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>The C(anonical) Scan Matcher</title><link href='style.css' rel='stylesheet' type='text/css' /> -</head> -<body><style> -body { padding-left: 3em;} -body p, body ul { max-width: 35em;} -pre { margin-left: 2em; background-color: #bbf; border: solid 1px black; - padding: 10px;} - -code { background-color: #ddf; padding: 3px; color: #008;} -pre code { background-color: #bbf;} -p, pre { max-width: 40em; } -h2 { - border-left: solid 2px #b00; - border-top: solid 2px #b00; - margin-top: 4em; - padding: 1em; margin-left: -1em;} -</style> -<h1 id='the_canonical_scan_matcher'>The C(anonical) Scan Matcher</h1> -<div class='maruku_toc'><ul style='list-style: none;'><li><span class='maruku_section_number'>1. </span><a href='#introduction'>Introduction</a></li><li><span class='maruku_section_number'>2. </span><a href='#content_of_this_package'>Content of this package</a><ul style='list-style: none;'><li><span class='maruku_section_number'>2.1. </span><a href='#stable_things_c_scan_matching_library'>Stable things: C scan matching library</a></li><li><span class='maruku_section_number'>2.2. </span><a href='#stable_things_applications'>Stable things: applications</a></li><li><span class='maruku_section_number'>2.3. </span><a href='#unstable_things_scripts'>Unstable things: scripts</a></li><li><span class='maruku_section_number'>2.4. </span><a href='#unstable_things_ruby_and_matlab_implementations'>Unstable things: Ruby and Matlab implementations</a></li></ul></li><li><span class='maruku_section_number'>3. </span><a href='#installation'>Installation</a><ul style='list-style: none;'><li><span class='maruku_section_number'>3.1. </span><a href='#required_software_dependencies'>Required software dependencies</a></li><li><span class='maruku_section_number'>3.2. </span><a href='#compiling'>Compiling</a></li><li><span class='maruku_section_number'>3.3. </span><a href='#getting_started'>Getting started</a></li><li><span class='maruku_section_number'>3.4. </span><a href='#installing_ruby_libraries_and_wrapper_optional'>Installing Ruby libraries and wrapper (optional)</a></li></ul></li><li><span class='maruku_section_number'>4. </span><a href='#the__data_structure'>The <code>laser_data</code> data structure</a></li><li><span class='maruku_section_number'>5. </span><a href='#input_and_output_formats'>Input and output formats</a><ul style='list-style: none;'><li><span class='maruku_section_number'>5.1. </span><a href='#the_json_log_format'>The JSON log format</a></li><li><span class='maruku_section_number'>5.2. </span><a href='#the_carmen_log_format'>The Carmen log format</a><ul style='list-style: none;'><li><span class='maruku_section_number'>5.2.1. </span><a href='#regarding_the_timestamp'>Regarding the timestamp</a></li></ul></li></ul></li><li><span class='maruku_section_number'>6. </span><a href='#examples'>Examples</a><ul style='list-style: none;'><li><span class='maruku_section_number'>6.1. </span><a href='#simple_scan_matching'>Simple scan matching</a></li><li><span class='maruku_section_number'>6.2. </span><a href='#creating_a_pdf'>Creating a PDF</a></li><li><span class='maruku_section_number'>6.3. </span><a href='#examining_one_particular_matching_video'>Examining one particular matching (video)</a></li><li><span class='maruku_section_number'>6.4. </span><a href='#help_icp_doesnt_work'>Help! ICP doesn’t work</a></li></ul></li><li><span class='maruku_section_number'>7. </span><a href='#embedding_csm_in_your_programs'>Embedding CSM in your programs</a><ul style='list-style: none;'><li><span class='maruku_section_number'>7.1. </span><a href='#linking_to_csm'>Linking to CSM</a></li><li><span class='maruku_section_number'>7.2. </span><a href='#accessing_csm_functions_from_your_applications'>Accessing CSM functions from your applications</a></li><li><span class='maruku_section_number'>7.3. </span><a href='#orienting_oneself_in_the_source_code'>Orienting oneself in the source code</a></li></ul></li></ul></div> -<h2 id='introduction'><span class='maruku_section_number'>1. </span>Introduction</h2> - -<p>I created this package:</p> - -<ul> -<li> -<p>To have a well-documented reference implementation of <a href='http://purl.org/censi/2007/plicp'>PL-ICP</a>. If you are only interested in the core algorithm of PL-ICP, a <a href='http://purl.org/censi/2007/plicp'>separate concise implementation in C/Matlab/Ruby</a> is available.</p> -</li> - -<li> -<p>To have a <strong>trustworthy</strong> scan matcher to be used in the experiments for some papers on <a href='http://purl.org/censi/2006/icpcov'>ICP covariance</a>, <a href='http://purl.org/censi/2006/accuracy'>the Cramer-Rao bound for range finders</a>, and <a href='http://purl.org/censi/2007/calib'>robot calibration</a>. For batch experiments, it’s also useful that it’s pretty fast.</p> -</li> - -<li> -<p>To have a collection of utilies for command line (UNIX-style) manipulation of laser data, and creating beautiful maps and animations.</p> -</li> -</ul> - -<h2 id='content_of_this_package'><span class='maruku_section_number'>2. </span>Content of this package</h2> - -<p>The core content is the C scan matching library which is quite polished, but this package contains a lot of software, only some of that in an usable state. In general, I am not ashamed of the prototypical code I write.</p> - -<h3 id='stable_things_c_scan_matching_library'><span class='maruku_section_number'>2.1. </span>Stable things: C scan matching library</h3> - -<p>The directory <code>sm/csm</code> contains a scan matcher written in C, plus associated tools and apps. This is stable and reasonably bug-free.</p> - -<p>There are many libraries in the <code>sm/lib</code> directory:</p> - -<ul> -<li> -<p>Directory <code>egsl</code>: a light wrapper for GSL that makes manipulating matrices easy and efficient. This is documented in another file: see <code>sm/lib/egsl/docs</code>.</p> -</li> - -<li> -<p>Directory <code>options</code>: for processing command-line arguments and configuration files.</p> -</li> - -<li> -<p>Directory <code>json-c</code>: a library for JSON input/output. This is a slightly modified version of the original <a href='http://www.json.org'><code>json-c</code></a> library released under the <a href='http://en.wikipedia.org/wiki/MIT_License'>MIT license</a>.</p> -</li> -</ul> - -<h3 id='stable_things_applications'><span class='maruku_section_number'>2.2. </span>Stable things: applications</h3> - -<p>There are many applications in the <code>sm/apps</code> directory:</p> - -<ul> -<li> -<p>Application <code>sm2</code>: standard scan-matching. Reads a log, runs ICP, and writes the scan-matched output. Input can be both Carmen and JSON.</p> -</li> - -<li> -<p>Application <code>sm3</code>: like sm2, but instead of actual output it measures the performance. This is the application that produced the stats found in the paper submitted to ICRA’08.</p> -</li> - -<li> -<p>Application <code>sm1</code>: useful for running experiments. Reads scans from two different files, and outputs statistics.</p> -</li> -</ul> - -<p>Visualization apps:</p> - -<ul> -<li> -<p>Application <code>log2pdf</code>: converts a laser log to a PDF map. To build this application, it is needed to install the <a href='http://cairographics.org'>Cairo</a> graphics library.</p> -</li> - -<li> -<p>Application <code>sm_animate</code>: creates an animation for the ICP process, displaying the correspondences, etc. This application reads the output created by <code>sm2</code> with the <code>-file_jj</code> option. To build this application, it is needed to install the <a href='http://cairographics.org'>Cairo</a> graphics library.</p> -</li> -</ul> - -<p>Miscellaneous Unix-style processing for laser data:</p> - -<ul> -<li> -<p>Application <code>carmen2json</code>: converts a Carmen log to the JSON format.</p> -</li> - -<li> -<p>Application <code>ld_fisher</code>: computes the Fisher’s information matrix. See <a href='http://purl.org/censi/2006/accuracy'>http://purl.org/censi/2006/accuracy</a> for details.</p> -</li> - -<li> -<p>Application <code>json_extract</code>: extract the n-th object from a JSON stream.</p> -</li> - -<li> -<p>Application <code>ld_slip</code>: adds some noise to the odometry field.</p> -</li> - -<li> -<p>Application <code>ld_smooth</code>: smooths the readings data.</p> -</li> - -<li> -<p>Application <code>ld_noise</code>: adds sensor noise.</p> -</li> - -<li> -<p>Application <code>ld_cluster_curv</code>: clusterize the rays based on the analysis of the curvature.</p> -</li> - -<li> -<p>Application <code>ld_linearize</code>: fits a line to each cluster (data must have been previously clustered, for example by <code>ld_cluster_curv</code>).</p> -</li> -</ul> - -<p>GUI apps:</p> - -<ul> -<li><code>apps/gtk_viewer</code> contains the prototype of a viewer using GTK. It does not work yet.</li> -</ul> - -<h3 id='unstable_things_scripts'><span class='maruku_section_number'>2.3. </span>Unstable things: scripts</h3> - -<p>In the <code>scripts/</code> directory you can find:</p> - -<ul> -<li> -<p>Script <code>json2matlab.rb</code>: converts a JSON object in a Matlab scripts. This is the holy grail of data exchange.</p> - -<p>Warning: at the moment, this script relies on some patches to the Ruby JSON library. Without them, it is limited to only 1 JSON object in each file.</p> -</li> - -<li> -<p>Script <code>fig2pics.rb</code>: used for converting FIG files to PDF. It has many more options than <a href='http://www.xfig.org'><code>fig2dev</code></a> (that is being used internally), including the ability to use a LaTeX preamble and to change the resulting bounding box.</p> -</li> - -<li> -<p>Script <code>create_video.rb</code>: displays the scan-matching process. This reads the journal files written by applications <code>sm1</code> and <code>sm2</code>. <strong>Made obsolete by <code>sm_animate</code></strong></p> -</li> -</ul> - -<h3 id='unstable_things_ruby_and_matlab_implementations'><span class='maruku_section_number'>2.4. </span>Unstable things: Ruby and Matlab implementations</h3> - -<p>Unstable things include:</p> - -<ul> -<li> -<p>Directory <code>sm_ruby_wrapper/</code>: a ruby wrapper for the <code>sm</code> C library. This wrapper is used for running some of the experiments. It is not documented and it needs tidying a little.</p> -</li> - -<li> -<p>Directory <code>rsm/</code>: a Ruby implementation of the same algorithms used in the <code>sm</code> library. Some times ago, the C and Matlab implementation were perfectly in sync. Now they differ a little. However, in the future I will try to get them back in sync, as the only way of having a good chance of making a bug-free implementation, is to make it twice.</p> -</li> - -<li> -<p>Directory <code>matlab/</code> and <code>matlab_new/</code>. The Matlab scripts are a mess that needs tidying. There’s a lot in there. They are kept here because they are used for creating some of the figures in the submitted papers. Also, the first PLICP implementation was written in Matlab and is buried there, somewhere.</p> - -<p>Also, I occasionally tried to make sure that the scripts run fine in <a href='http://www.octave.org'>Octave</a>. They do, except for the plotting.</p> -</li> -</ul> - -<h2 id='installation'><span class='maruku_section_number'>3. </span>Installation</h2> -<!-- -### Downloading ### - -Download with SVN, using the following: - - $ svn checkout --username ANTANI svn://net143-184.mclink.it/csm - -where `ANTANI` is your surname (you should have received a password). - -This will checkout both the source code -and some files used for experiments, that might be slightly slow to download. -If you are only interested in the source code, use: - - $ svn checkout --username ANTANI svn://net143-184.mclink.it/csm/csm ---> -<h3 id='required_software_dependencies'><span class='maruku_section_number'>3.1. </span>Required software dependencies</h3> - -<p>This software has been tested on Mac OS X, Linux, and Windows XP (using Cygwin). It compiles with GCC (3.3 or 4.x) and the Intel C++ Compiler (ICC).</p> - -<p>Required software:</p> - -<ul> -<li>The build system is based on <code>cmake</code>, which is available at <a href='http://www.cmake.org/'>http://www.cmake.org/</a>.</li> - -<li>The GSL, Gnu Scientific Library, available at <a href='http://www.gnu.org/software/gsl/'>http://www.gnu.org/software/gsl/</a>.</li> - -<li>(optional) For <code>log2pdf</code> and other visualization applications, you will need the Cairo graphics library, available at <a href='http://cairographics.org'>http://cairographics.org</a>. The recommended version is the stable 1.4.12.</li> -</ul> - -<p><strong>Linux</strong>. CMake, Cairo, and GSL are probably already packaged for your Linux distribution. For example, in Ubuntu, you can simply enter this command to install all dependencies:</p> - -<pre><code>$ sudo apt-get install build-essential cmake libgsl0-dev libcairo2-dev </code></pre> - -<p><strong>OS X</strong>. You can install GSL using <a href='http://finkproject.org/'>Fink</a>. You have to install Cairo manually.</p> - -<p><strong>Windows XP, using Cygwin</strong>. CSM runs fine on Cygwin, but very slow compared to Linux/OS X. Make sure you install the Cygwin packages <code>cairo</code>, <code>gsl</code>, <code>gsl-apps</code>, <code>gsl-devel</code>.</p> - -<p><strong>Windows XP, using Visual Studio</strong>. CSM doesn’t compile yet on this platform. CMake can theoretically create Visual Studio projects, but I could not manage to do it. Also, some CMake code is probably Unix-specific.</p> - -<h3 id='compiling'><span class='maruku_section_number'>3.2. </span>Compiling</h3> - -<p>If you are lucky, this should be it:</p> - -<pre><code>$ cmake . -$ make</code></pre> - -<p>If you want to install this library system-wide, you could use:</p> - -<pre><code>$ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local . -$ make -$ make install</code></pre> - -<p>as the first step.</p> - -<p>For installing the Ruby wrapper, refer to the separate instructions. If you want to use the Ruby wrapper, I suggest to install the source code in a <code>deploy</code> sub-directory of <code>csm</code>:</p> - -<pre><code>csm/ - docs/ - csm/ - rsm/ - deploy/ <--- here</code></pre> - -<p>To do this, use:</p> - -<pre><code>$ cmake -DCMAKE_INSTALL_PREFIX:PATH=`pwd`/deploy . -$ make -$ make install</code></pre> - -<p>(you have to give a complete path to <code>-DCMAKE_INSTALL_PREFIX:PATH</code>).</p> - -<p>Later, remember to set your <code>PATH</code> variable to <code>csm/deploy/bin</code>.</p> - -<h3 id='getting_started'><span class='maruku_section_number'>3.3. </span>Getting started</h3> - -<p>You might get started by doing this:</p> - -<pre><code>$ sm2 < in.log > out.log</code></pre> - -<p>where <code>in.log</code> is a Carmen-format log file.</p> - -<p>You can find one in the top-level <code>experiments</code> directory: it is called <code>laserazosSM3.log</code>. So, if you installed the Cairo library, you can see the result with:</p> - -<pre><code>$ sm2 < in.log > out.log -$ log2pdf -use odometry -in out.log -out out-odometry.pdf -$ log2pdf -use estimate -in out.log -out out-estimate.pdf</code></pre> - -<h3 id='installing_ruby_libraries_and_wrapper_optional'><span class='maruku_section_number'>3.4. </span>Installing Ruby libraries and wrapper (optional)</h3> - -<p>This step-by-step guide is written by me, for me.</p> - -<p>Installing with cmake:</p> - -<pre><code>$ cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr/local</code></pre> - -<p>First, set up some directories</p> - -<pre><code>$ export SMLIB= -$ cd $SMLIB -$ ls -...................</code></pre> - -<p>Create installation directory:</p> - -<pre><code>$ mkdir deploy -$ mkdir deploy/bin -$ export PATH=$PATH $SMLIB/deploy/bin</code></pre> - -<p>Create a new ruby installation</p> - -<pre><code>$ mkdir my_ruby -$ cd my_ruby</code></pre> - -<p>Download ruby:</p> - -<pre><code>$ wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz -$ tar xvzf ruby-1.8.5.tar.gz -$ ./configure --prefix=$SMLIB/deploy -$ make -$ make install</code></pre> - -<p>Now you should be able to use the new ruby installation</p> - -<pre><code>$ which ruby -<SMLIB>/deploy/bin/ruby -$ ruby --version -ruby 1.8.5 (2006-08-25)</code></pre> - -<p>Instructions for installing rb-gsl:</p> - -<ol> -<li>Get and install GSL. Make sure the command “gsl-config” is in command search path.</li> - -<li>Download Ruby/GSL, ungzip and untar the archive rb-gsl-xxx.tar.gz.</li> - -<li>Use: % cd rb-gsl-xxx/ % ruby setup.rb config % ruby setup.rb setup % ruby setup.rb install (as root)</li> -</ol> - -<p>Download rubygems:</p> - -<pre><code>$ cd $SMLIB/my_ruby -$ wget http://rubyforge.org/frs/download.php/11289/rubygems-0.9.0.tgz -$ tar xvzf rubygems-0.9.0.tgz -$ cd rubygems-0.9.0 -$ ruby setup.rb</code></pre> - -<p>Now you should have the “gem” command installed:</p> - -<pre><code>$ which gem -<SMLIB>/deploy/bin/gem</code></pre> -<!-- -/path/to/cmake . -DCMAKE_INSTALL_PREFIX:PATH=/path/to/install/to/scribuscmake/ - -#export PKG_CONFIG_PATH=/Users/andrea/06MELANIA/censi-2006/Matlab-yasmine/deploy/lib/pkgconfig/ - ---> -<h2 id='the__data_structure'><span class='maruku_section_number'>4. </span>The <code>laser_data</code> data structure</h2> - -<p>Laser data is passed around in a structure which is quite rich and in some ways redundant to achieve ease of use.</p> - -<p>In C, the structure’s name is <code>struct laser_data</code>. In Ruby, it is <code>class LaserData</code>. In Matlab, it’s a generic structure.</p> - -<p>A description of the fields follows (assume the structure is called <code>ld</code>).</p> - -<p>Regarding the pose of the robot:</p> - -<dl> -<dt><code>ld.true_pose</code></dt> - -<dd>Pose of the robot (m,m,rad), in world coordinates.</dd> - -<dt><code>ld.odometry</code></dt> - -<dd>Odometry (<code>true_pose</code> corrupted by noise).</dd> - -<dt><code>ld.estimate</code></dt> - -<dd>Estimate of <code>true_pose</code>.</dd> -</dl> - -<p>Regarding the rays:</p> - -<dl> -<dt><code>ld.nrays</code></dt> - -<dd> -<p>Number of rays.</p> -</dd> - -<dt><code>ld.min_theta</code> and <code>ld.max_theta</code></dt> - -<dd> -<p>Minimum and maximum theta (radians).</p> -</dd> - -<dt><code>ld.theta[i]</code></dt> - -<dd> -<p>Direction of i-th ray with respect to the robot (radians).</p> -</dd> - -<dt><code>ld.readings[i]</code></dt> - -<dd> -<p>Sensor reading (meters). If the reading is not valid, then <code>ld.readings(i) == NAN</code>.</p> -</dd> - -<dt><code>ld.valid[i]</code></dt> - -<dd> -<p>In C, it assumes values <code>0</code> and <code>1</code>. In Ruby, it assumes values <code>true</code> or <code>false</code>. (<strong>TODO</strong>: choose how to serialize).</p> - -<p>This field is true if this ray is valid, and, in particular, <code>ld.readings[i]</code> is valid. Invalid rays occur when the obstacle is farther than the sensor horizon.</p> -</dd> - -<dt><code>ld.true_alpha[i]</code></dt> - -<dd> -<p>Orientation of the normal of the surface (radians, relative to robot). It is <code>NAN</code> if not valid.</p> -</dd> - -<dt><code>ld.alpha[i]</code></dt> - -<dd> -<p>Estimated orientation of the surface (radians, relative to robot). It is an estimate of <code>ld.true_alpha[i]</code>.</p> -</dd> - -<dt><code>ld.alpha_valid[i]</code></dt> - -<dd> -<p>True if previous field is valid.</p> -</dd> - -<dt><code>ld.cov_alpha[i]</code></dt> - -<dd> -<p>Estimated covariance of <code>ld.alpha[i]</code>.</p> -</dd> -</dl> - -<p>Additional fields used during the computation:</p> - -<dl> -<dt><code>ld.cluster[i]</code></dt> - -<dd>Cluster to which point i belongs. This is used for computing the orientation (at the moment a really dumb algorithm is used for clustering). If <code>cluster[i] == -1</code>, the point does not belong to any cluster.</dd> - -<dt><code>ld.points[i].p</code></dt> - -<dd>Point coordinates (cartesian). Computed from the polar coordinates <code>theta[i]</code> and <code>readings[i]</code>.</dd> - -<dt><code>ld.points_w[i].p</code></dt> - -<dd>Point coordinates (cartesian) in a “world” reference frame. Computed with the function <code>ld_compute_world_coords(LDP, double pose[3])</code>.</dd> - -<dt><code>ld.hostname</code></dt> - -<dd>This is parsed from the Carmen data field.</dd> - -<dt><code>ld.tv</code></dt> - -<dd>This is a <code>struct timeval</code> field giving a timestamp for the laser scan. Please see the section on parsing to learn how this is parsed from the Carmen log.</dd> -</dl> - -<h2 id='input_and_output_formats'><span class='maruku_section_number'>5. </span>Input and output formats</h2> - -<p>The library understands two formats: a rich JSON format, and the old good Carmen format.</p> - -<h3 id='the_json_log_format'><span class='maruku_section_number'>5.1. </span>The JSON log format</h3> - -<p>See this site: <a href='http://www.json.org'>http://www.json.org</a> for general information about JSON.</p> - -<p>This is a sample laser data structure. It has only 5 rays (which all happen to be invalid), and it has no <code>alpha</code>, <code>true_alpha</code>, <code>cluster</code> fields:</p> - -<pre><code>{ - "nrays": 5, - "min_theta": null, - "max_theta": null, - "theta": [ null, null, null, null, null ], - "readings": [ null, null, null, null, null], - "valid": [ 0, 0, 0, 0, 0], - - "odometry": [ null, null, null ], - "estimate": [ null, null, null ], - "true_pose": [ null, null, null ] -}</code></pre> - -<p>Note that <code>NAN</code> is represented with <code>null</code> in the JSON format.</p> - -<h3 id='the_carmen_log_format'><span class='maruku_section_number'>5.2. </span>The Carmen log format</h3> - -<p>The 6 pose values in the log are interpreted as follows:</p> - -<pre><code>estimate.x estimate.y estimate.theta .... -odometry.x odometry.y odometry.theta </code></pre> -<!--diego: - quindi tu alla fine - leggi il secondo campo - e scrivi il secondo campo - (e scrivi, per sicurezza, il primo campo)--> -<h4 id='regarding_the_timestamp'><span class='maruku_section_number'>5.2.1. </span>Regarding the timestamp</h4> - -<p>Regarding the timestamp “fields”. The last three fields in a Carmen log can be:</p> - -<pre><code>integer string integer</code></pre> - -<p>This is interpreted as seconds, hostname, microseconds. This is good if you want to write a <code>timeval</code> struct to the log and <em>be sure</em> it won’t be modified by precision problems when writing, and parsing, as a <code>double</code>.</p> - -<p>If it doesn’t look like a timestamp, then it is assumed that the fields are:</p> - -<pre><code>double string double</code></pre> - -<p>In this case, the first double is interpreted as the timestamp in seconds, while the second double is discarded.</p> - -<p>The library will warn the user about these decisions by writing on the console this message:</p> - -<pre><code>sm2:inf: Reading timestamp as 'sec hostname usec'.</code></pre> - -<p>or this one:</p> - -<pre><code>sm2:inf: Reading timestamp as doubles (discarding second one).</code></pre> - -<h2 id='examples'><span class='maruku_section_number'>6. </span>Examples</h2> - -<h3 id='simple_scan_matching'><span class='maruku_section_number'>6.1. </span>Simple scan matching</h3> - -<p>Simple scan-matching:</p> - -<pre><code>$ sm2 < in.log > out.log</code></pre> - -<p>where <code>in.log</code> may be in either Carmen or JSON format.</p> - -<h3 id='creating_a_pdf'><span class='maruku_section_number'>6.2. </span>Creating a PDF</h3> - -<p>Creating a PDF:</p> - -<pre><code>$ log2pdf -use odometry -in in.log -out out_odometry.pdf -$ log2pdf -use estimate -in in.log -out out_estimate.pdf</code></pre> - -<h3 id='examining_one_particular_matching_video'><span class='maruku_section_number'>6.3. </span>Examining one particular matching (video)</h3> - -<p>To zoom on one particular matching, write a “journal” using the <code>-file_jj</code> option of <code>sm2</code>:</p> - -<pre><code>$ sm2 -file_jj journal.txt < in.log > out.log</code></pre> - -<p>Extract what you are interested in from the journal. In this example, the 13th matching:</p> - -<pre><code>$ json_extract -nth 13 < journal.txt > matching13.txt</code></pre> - -<p>Create the animation:</p> - -<pre><code>$ sm_animate -in matching13.txt</code></pre> - -<h3 id='help_icp_doesnt_work'><span class='maruku_section_number'>6.4. </span>Help! ICP doesn’t work</h3> - -<p>Actually, there are a million reasons for which it shouldn’t work. If it gives strange results, try the following:</p> - -<ol> -<li> -<p>Plot the data! Plot the input and plot the output using <code>log2pdf</code>.</p> -</li> - -<li> -<p>Plot the animation! Use the procedure above and inspect the resulting videos.</p> -</li> - -<li> -<p>Double-check the parameters you are using. Note that there are some like <code>max_correspondence_dist</code> which depend on the scale of your data. A value of 2m might work for a big robot making large movements, but not for a little Khepera.</p> -</li> - -<li> -<p>Smooth your data – if your sensor is very noisy, like an Hokuyo, it’s worth to do simple low-pass filtering. Especially for PLICP which uses the orientation information.</p> -</li> -</ol> - -<h2 id='embedding_csm_in_your_programs'><span class='maruku_section_number'>7. </span>Embedding CSM in your programs</h2> - -<h3 id='linking_to_csm'><span class='maruku_section_number'>7.1. </span>Linking to CSM</h3> - -<p>When CSM is installed, a <a href='http://pkg-config.freedesktop.org/wiki/'>pkgconfig</a> <code>csm.pc</code> file is installed as well. This makes it easy to link to CSM.</p> - -<p>For example, on my system, after installing CSM, I can run <code>pkgconfig</code> to get the C preprocessors and linker flags.</p> - -<p>This is what I get on my system (on yours, paths will be different, of course).</p> - -<pre><code> $ pkg-config --cflags csm - -I/sw/include -I/Users/andrea/svn/cds/csm/deploy/include/cairo - -I/Users/andrea/svn/cds/csm/deploy/include - - $ pkg-config --libs csm - -L/sw/lib -L/Users/andrea/svn/cds/csm/deploy/lib - -lcsm-static -lgsl -lgslcblas -lm</code></pre> - -<p>If you use GNU Make, a basic Makefile for your program linking to CSM would be something like:</p> - -<pre><code>CSM_FLAGS=`pkg-config --libs --cflags csm` - -myprogram: myprogram.c - gcc $(CSM_FLAGS) -o myprogram myprogram.c</code></pre> - -<p>You can download the sources for this example in the repository (directory <code>docs/example-linking-make</code>).</p> - -<p>If you use <a href='http://www.cmake.org/'>CMake</a> — and you should! — it is reccomended that you use something like the following in your <code>CMakeLists.txt</code>.</p> - -<pre><code>cmake_minimum_required(VERSION 2.4) -project(myproject) - -# Require we have pkgconfig installed -find_package(PkgConfig REQUIRED) -# Tell pkgconfig to look for CSM -pkg_check_modules(CSM REQUIRED csm) - -IF(${CSM_FOUND}) - MESSAGE("CSM_LIBRARY_DIRS: ${CSM_LIBRARY_DIRS}") - MESSAGE("CSM_LIBRARIES: ${CSM_LIBRARIES}") - MESSAGE("CSM_INCLUDE_DIRS: ${CSM_INCLUDE_DIRS}") - - INCLUDE_DIRECTORIES(${CSM_INCLUDE_DIRS}) # important! - LINK_DIRECTORIES(${CSM_LIBRARY_DIRS}) # important! -ELSE(${CSM_FOUND}) - MESSAGE(FATAL_ERROR "CSM not found. Check that the environment \ - variable PKG_CONFIG_PATH includes the path containing the file 'csm.pc'.") -ENDIF(${CSM_FOUND}) - -add_executable(myprogram myprogram.c) - -target_link_libraries(myprogram ${CSM_LIBRARIES}) # important! </code></pre> - -<p>You can download the sources for this example in the repository (directory <code>docs/example-linking-cmake</code>).</p> - -<h3 id='accessing_csm_functions_from_your_applications'><span class='maruku_section_number'>7.2. </span>Accessing CSM functions from your applications</h3> - -<p>All functions that you would be interested in using are accessible by including one header:</p> - -<pre><code>#include <csm/csm_all.h></code></pre> - -<p>If you are linking from C++, as opposed to C, all functions are enclosed in the <code>CSM</code> namespace. Therefore, you need something like the following.</p> - -<pre><code>#include <csm/csm_all.h> -using namespace CSM;</code></pre> - -<h3 id='orienting_oneself_in_the_source_code'><span class='maruku_section_number'>7.3. </span>Orienting oneself in the source code</h3> - -<p>The main function to call is the following:</p> - -<pre><code>void sm_icp(struct sm_params*params, struct sm_result*result);</code></pre> - -<p>This implements matching between two laser scans. All the applications discussed above (<code>sm1</code>, <code>sm2</code>, etc.) are essentially wrapper of <code>sm_icp</code>: they fill in the <code>params</code> structure, and read from the <code>result</code> structure.</p> - -<p>The <code>sm_params</code> structure is described in the <code><csm/algos.h></code> header file. It contains parameters for both ICP and other algorithms (like HSM; however, only (PL)ICP is considered stable in CSM)</p> - -<p>Note that many of the parameters greatly influence the behavior of PLICP, so it is worth reading them all. If you run <code>sm2 -help</code> you will see the default values, which are reasonable as a starting point.</p> - -<p>We now briefly discuss the main parameters.</p> - -<ul> -<li><code>params->laser_ref</code>: pointer of a structure of type <code>laser_data</code> (described before in this document) representing the “ref”erence scan (first scan).</li> - -<li><code>params->laser_sens</code>: pointer of a structure of type <code>laser_data</code> representing the second scan.</li> - -<li><code>params->first_guess</code>: first guess (x,y,theta).</li> - -<li><code>use_point_to_line_distance</code>: 1 for PLICP, 0 for ICP.</li> - -<li><code>use_corr_tricks</code>: use the tricks described in the PLICP paper.</li> -</ul> - -<p>Parameters that influence stopping and restarting:</p> - -<ul> -<li><code>max_iterations</code>: maximum number of iterations</li> - -<li><code>epsilon_xy</code>, <code>epsilon_theta</code>: stop if change below these thresholds</li> - -<li><code>restart*</code>: whether to add some noise and restart if the match is not satisfactory. Useful for getting out of local minima but expensive.</li> -</ul> - -<p>Parameters that influence correspondence establishment:</p> - -<ul> -<li><code>max_angular_correction_deg</code>, <code>max_linear_correction</code>.</li> - -<li><code>max_correspondence_dist</code></li> -</ul> - -<p>Parameters that influence correspondence pruning:</p> - -<ul> -<li><code>outliers_maxPerc</code></li> - -<li><code>outliers_adaptive_*</code></li> - -<li><code>outliers_remove_doubles</code></li> -</ul> - -<p>See the file <code><csm/algos.h></code> for a description of the above parameters, and the other minor parameters.</p> -</body></html> diff --git a/csm_manual.pdf b/csm_manual.pdf deleted file mode 100644 index 9701afe5ea5362037d70972280b02fab7b9692db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152698 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 VnBMRiFu)9C3fy91>UtX7{|_V}3C92c diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index e1457cd..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,39 +0,0 @@ - -#maruku=ruby -I~/maruku/lib ~/maruku/bin/maruku -maruku=maruku - -out=csm_manual.pdf csm_manual.html - -all: $(out) - cp $(out) .. - -src=\ - preamble.txt \ - inline_style.css \ - readme.txt \ - install.txt \ - install-ruby.txt \ - laserdata.txt \ - formats.txt \ - examples.txt \ - embedding.txt - - -%: tmp_% - cp $< $@ - -csm_manual.txt: $(src) - cat $^ > $@ - -%.pdf: %.txt - $(maruku) --pdf -o $@ $< - -%.html: %.txt - $(maruku) --html $< - -clean: - rm $(out) - -copy: out/csm_manual.html - cp $< ../CSM_MANUAL.html - diff --git a/docs/TODO.txt b/docs/TODO.txt deleted file mode 100644 index 8b13789..0000000 --- a/docs/TODO.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/description.lyx b/docs/description.lyx deleted file mode 100644 index 3ccd224..0000000 --- a/docs/description.lyx +++ /dev/null @@ -1,167 +0,0 @@ -#LyX 1.4.2 created this file. For more info see http://www.lyx.org/ -\lyxformat 245 -\begin_document -\begin_header -\textclass article -\language english -\inputencoding auto -\fontscheme default -\graphics default -\paperfontsize default -\papersize default -\use_geometry false -\use_amsmath 1 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\end_header - -\begin_body - -\begin_layout Section -HSM -\end_layout - -\begin_layout Standard -Filtering orientation -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -f'(\theta_{0})=\frac{f(\theta_{i})-f(\theta_{0})}{\theta_{i}-\theta_{0}}+f''(\xi)\frac{\left(\theta_{i}-\theta_{0}\right)^{2}}{2}\] - -\end_inset - - -\begin_inset Formula \[ -f'(\theta_{0})=\frac{\rho_{i}-\rho_{0}}{\theta_{i}-\theta_{0}}+\left(\frac{1}{\theta_{i}-\theta_{0}}\right)\epsilon_{i}+\left(\frac{-1}{\theta_{i}-\theta_{0}}\right)\epsilon_{0}+\frac{\left(\theta_{i}-\theta_{0}\right)^{2}}{2}c_{i}\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -Y=LX+R\epsilon\] - -\end_inset - - -\begin_inset Formula \[ -Y=\left[\begin{array}{c} -\frac{\rho_{1}-\rho_{0}}{\theta_{1}-\theta_{0}}\\ -\vdots\\ -\frac{\rho_{n}-\rho_{0}}{\theta_{n}-\theta_{0}}\end{array}\right]\quad\qquad L=\left[\begin{array}{c} -1\\ -\vdots\\ -1\end{array}\right]\quad X=f'(\theta_{0})\qquad R\epsilon=\left[\begin{array}{cccc} -\frac{-1}{\theta_{1}-\theta_{0}} & \frac{1}{\theta_{1}-\theta_{0}} & 0 & 0\\ -\vdots & & \ddots\\ -\frac{-1}{\theta_{n}-\theta_{0}} & 0 & 0 & \frac{1}{\theta_{n}-\theta_{0}}\end{array}\right]\left[\begin{array}{c} -\underbar{\epsilon_{0}}\\ -\epsilon_{1}\\ -\vdots\\ -\epsilon_{n}\end{array}\right]\] - -\end_inset - - -\end_layout - -\begin_layout Standard -\begin_inset Formula \[ -\alpha=\theta_{0}-\mbox{atan}\left(\frac{f'(\theta_{0})}{f(\theta_{0})}\right)\] - -\end_inset - - -\begin_inset Formula \[ -\frac{\partial\alpha}{\partial f'}=\frac{1}{1+\left(f'/f\right)^{2}}\frac{1}{f}=\frac{f}{f^{2}+f'^{2}}\] - -\end_inset - - -\begin_inset Formula \[ -\frac{\partial\alpha}{\partial f}=\frac{1}{1+\left(f'/f\right)^{2}}\frac{-f'}{f^{2}}=\frac{-f'}{f^{2}+f'^{2}}\] - -\end_inset - - -\family roman -\series medium -\shape up -\size normal -\emph off -\bar no -\noun off -\color none - -\backslash -frac{f}{f^{2}+f'^{2}} -\end_layout - -\begin_layout Section -ICP -\end_layout - -\begin_layout Subsection -Tricks -\end_layout - -\begin_layout Standard -Tutti esatti -\end_layout - -\begin_layout Subsubsection -The from-to trick -\end_layout - -\begin_layout Subsubsection -Going up and going down -\end_layout - -\begin_layout Subsubsection -Start at last cell -\end_layout - -\begin_layout Subsubsection -Early stop -\end_layout - -\begin_layout Subsubsection -Use jumps -\end_layout - -\begin_layout Subsection -Code optimizations -\end_layout - -\begin_layout Standard -no sin() con tables o similari -\end_layout - -\begin_layout Subsection -Minimizzazione -\end_layout - -\begin_layout Subsection -Trimming -\end_layout - -\begin_layout Section -Evolution -\end_layout - -\end_body -\end_document diff --git a/docs/embedding.txt b/docs/embedding.txt deleted file mode 100644 index b647c28..0000000 --- a/docs/embedding.txt +++ /dev/null @@ -1,133 +0,0 @@ - -## Embedding CSM in your programs ## - -### Linking to CSM ### - -When CSM is installed, a [pkgconfig] ``csm.pc`` file is installed as well. -This makes it easy to link to CSM. - -[pkgconfig]: http://pkg-config.freedesktop.org/wiki/ - -For example, on my system, after installing CSM, I can run ``pkgconfig`` to -get the C preprocessors and linker flags. - -This is what I get on my system (on yours, paths will be different, of course). - - $ pkg-config --cflags csm - -I/sw/include -I/Users/andrea/svn/cds/csm/deploy/include/cairo - -I/Users/andrea/svn/cds/csm/deploy/include - - $ pkg-config --libs csm - -L/sw/lib -L/Users/andrea/svn/cds/csm/deploy/lib - -lcsm-static -lgsl -lgslcblas -lm - -If you use GNU Make, a basic Makefile for your program linking to CSM -would be something like: - - CSM_FLAGS=`pkg-config --libs --cflags csm` - - myprogram: myprogram.c - gcc $(CSM_FLAGS) -o myprogram myprogram.c - -You can download the sources for this example in the repository (directory `docs/example-linking-make`). - -If you use [CMake] --- and you should! --- it is reccomended that -you use something like the following in your ``CMakeLists.txt``. - - cmake_minimum_required(VERSION 2.4) - project(myproject) - - # Require we have pkgconfig installed - find_package(PkgConfig REQUIRED) - # Tell pkgconfig to look for CSM - pkg_check_modules(CSM REQUIRED csm) - - IF(${CSM_FOUND}) - MESSAGE("CSM_LIBRARY_DIRS: ${CSM_LIBRARY_DIRS}") - MESSAGE("CSM_LIBRARIES: ${CSM_LIBRARIES}") - MESSAGE("CSM_INCLUDE_DIRS: ${CSM_INCLUDE_DIRS}") - - INCLUDE_DIRECTORIES(${CSM_INCLUDE_DIRS}) # important! - LINK_DIRECTORIES(${CSM_LIBRARY_DIRS}) # important! - ELSE(${CSM_FOUND}) - MESSAGE(FATAL_ERROR "CSM not found. Check that the environment \ - variable PKG_CONFIG_PATH includes the path containing the file 'csm.pc'.") - ENDIF(${CSM_FOUND}) - - add_executable(myprogram myprogram.c) - - target_link_libraries(myprogram ${CSM_LIBRARIES}) # important! - -You can download the sources for this example in the repository (directory `docs/example-linking-cmake`). - -[CMake]: http://www.cmake.org/ - - -### Accessing CSM functions from your applications ### - -All functions that you would be interested in using are accessible by including one header: - - #include <csm/csm_all.h> - -If you are linking from C++, as opposed to C, all functions are enclosed -in the `CSM` namespace. Therefore, you need something like the following. - - #include <csm/csm_all.h> - using namespace CSM; - - -### Orienting oneself in the source code ### - -The main function to call is the following: - - void sm_icp(struct sm_params*params, struct sm_result*result); - -This implements matching between two laser scans. -All the applications discussed above (``sm1``, ``sm2``, etc.) are essentially -wrapper of ``sm_icp``: they fill in the ``params`` structure, and read from the ``result`` structure. - -The ``sm_params`` structure is described in the ``<csm/algos.h>`` header file. -It contains parameters for both ICP and other algorithms (like HSM; however, only (PL)ICP is considered stable in CSM) - -Note that many of the parameters greatly influence the behavior of PLICP, so it -is worth reading them all. If you run ``sm2 -help`` you will see the default -values, which are reasonable as a starting point. - -We now briefly discuss the main parameters. - -* ``params->laser_ref``: pointer of a structure of type ``laser_data`` (described before in this document) representing - the "ref"erence scan (first scan). -* ``params->laser_sens``: pointer of a structure of type ``laser_data`` representing - the second scan. -* ``params->first_guess``: first guess (x,y,theta). -* ``use_point_to_line_distance``: 1 for PLICP, 0 for ICP. -* ``use_corr_tricks``: use the tricks described in the PLICP paper. - -Parameters that influence stopping and restarting: - -* ``max_iterations``: maximum number of iterations -* ``epsilon_xy``, ``epsilon_theta``: stop if change below these thresholds -* ``restart*``: whether to add some noise and restart if the match - is not satisfactory. Useful for getting out of local minima but - expensive. - -Parameters that influence correspondence establishment: - -* ``max_angular_correction_deg``, ``max_linear_correction``. -* ``max_correspondence_dist`` - -Parameters that influence correspondence pruning: - -* ``outliers_maxPerc`` -* ``outliers_adaptive_*`` -* ``outliers_remove_doubles`` - -See the file ``<csm/algos.h>`` for a description of the above parameters, -and the other minor parameters. - - - - - - - diff --git a/docs/example-linking-cmake/CMakeLists.txt b/docs/example-linking-cmake/CMakeLists.txt deleted file mode 100644 index c9bae75..0000000 --- a/docs/example-linking-cmake/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 2.4) -project(myproject) - -# Require we have pkgconfig installed -find_package(PkgConfig REQUIRED) -# Tell pkgconfig to look for CSM -pkg_check_modules(CSM REQUIRED csm) - -IF(${CSM_FOUND}) - MESSAGE("CSM_LIBRARY_DIRS: ${CSM_LIBRARY_DIRS}") - MESSAGE("CSM_LIBRARIES: ${CSM_LIBRARIES}") - MESSAGE("CSM_INCLUDE_DIRS: ${CSM_INCLUDE_DIRS}") - - INCLUDE_DIRECTORIES(${CSM_INCLUDE_DIRS}) # important! - LINK_DIRECTORIES(${CSM_LIBRARY_DIRS}) # important! -ELSE(${CSM_FOUND}) - MESSAGE(FATAL_ERROR "CSM not found. Check that the environment variable PKG_CONFIG_PATH includes the path containing the file 'csm.pc'.") -ENDIF(${CSM_FOUND}) - -add_executable(myprogram myprogram.c) - -target_link_libraries(myprogram ${CSM_LIBRARIES}) # important! - diff --git a/docs/example-linking-cmake/myprogram.c b/docs/example-linking-cmake/myprogram.c deleted file mode 100644 index d07f1f0..0000000 --- a/docs/example-linking-cmake/myprogram.c +++ /dev/null @@ -1,5 +0,0 @@ -#include <csm/csm_all.h> - -int main() { - -} \ No newline at end of file diff --git a/docs/example-linking-make/Makefile b/docs/example-linking-make/Makefile deleted file mode 100644 index c32cba3..0000000 --- a/docs/example-linking-make/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -CSM_FLAGS=`pkg-config --libs --cflags csm` - -myprogram: myprogram.c - gcc $(CSM_FLAGS) -o myprogram myprogram.c diff --git a/docs/example-linking-make/myprogram.c b/docs/example-linking-make/myprogram.c deleted file mode 100644 index d07f1f0..0000000 --- a/docs/example-linking-make/myprogram.c +++ /dev/null @@ -1,5 +0,0 @@ -#include <csm/csm_all.h> - -int main() { - -} \ No newline at end of file diff --git a/docs/examples.txt b/docs/examples.txt deleted file mode 100644 index 0b4321f..0000000 --- a/docs/examples.txt +++ /dev/null @@ -1,60 +0,0 @@ - -## Examples ## - - -### Simple scan matching ### - -Simple scan-matching: - - $ sm2 < in.log > out.log - -where `in.log` may be in either Carmen or JSON format. - -### Creating a PDF ### - -Creating a PDF: - - $ log2pdf -use odometry -in in.log -out out_odometry.pdf - $ log2pdf -use estimate -in in.log -out out_estimate.pdf - -### Examining one particular matching (video) ### - -To zoom on one particular matching, write a "journal" -using the `-file_jj` option of `sm2`: - - $ sm2 -file_jj journal.txt < in.log > out.log - -Extract what you are interested in from the journal. -In this example, the 13th matching: - - $ json_extract -nth 13 < journal.txt > matching13.txt - -Create the animation: - - $ sm_animate -in matching13.txt - -### Help! ICP doesn't work ### - -Actually, there are a million reasons for which it shouldn't work. -If it gives strange results, try the following: - -1. Plot the data! Plot the input and plot the output using `log2pdf`. - -2. Plot the animation! Use the procedure above and inspect the resulting videos. - -3. Double-check the parameters you are using. Note that there are some like - `max_correspondence_dist` which depend on the scale of your data. A value - of 2m might work for a big robot making large movements, but not for a little - Khepera. - -4. Smooth your data -- if your sensor is very noisy, like an Hokuyo, it's worth - to do simple low-pass filtering. Especially for PLICP which uses the orientation - information. - - - - - - - - diff --git a/docs/formats.txt b/docs/formats.txt deleted file mode 100644 index a8da310..0000000 --- a/docs/formats.txt +++ /dev/null @@ -1,63 +0,0 @@ -Input and output formats ------------------------- - -The library understands two formats: a rich JSON format, and the old good Carmen format. - -### The JSON log format ### - -See this site: <http://www.json.org> for general information about JSON. - -This is a sample laser data structure. It has only 5 rays (which all -happen to be invalid), and it has no `alpha`, `true_alpha`, `cluster` fields: - - { - "nrays": 5, - "min_theta": null, - "max_theta": null, - "theta": [ null, null, null, null, null ], - "readings": [ null, null, null, null, null], - "valid": [ 0, 0, 0, 0, 0], - - "odometry": [ null, null, null ], - "estimate": [ null, null, null ], - "true_pose": [ null, null, null ] - } - -Note that `NAN` is represented with `null` in the JSON format. - - -### The Carmen log format ### - -The 6 pose values in the log are interpreted as follows: - - estimate.x estimate.y estimate.theta .... - odometry.x odometry.y odometry.theta - -<!--diego: - quindi tu alla fine - leggi il secondo campo - e scrivi il secondo campo - (e scrivi, per sicurezza, il primo campo)--> - -#### Regarding the timestamp #### - -Regarding the timestamp "fields". The last three fields in a Carmen log can be: - - integer string integer - -This is interpreted as seconds, hostname, microseconds. This is good if you want to write a `timeval` struct to the log and *be sure* it won't be modified by precision problems when writing, and parsing, as a `double`. - -If it doesn't look like a timestamp, then it is assumed that the fields are: - - double string double - -In this case, the first double is interpreted as the timestamp in seconds, while the second double is discarded. - -The library will warn the user about these decisions by writing on the console this message: - - sm2:inf: Reading timestamp as 'sec hostname usec'. - -or this one: - - sm2:inf: Reading timestamp as doubles (discarding second one). - diff --git a/docs/inline_style.css b/docs/inline_style.css deleted file mode 100644 index 4e66f2d..0000000 --- a/docs/inline_style.css +++ /dev/null @@ -1,16 +0,0 @@ - -<style> -body { padding-left: 3em;} -body p, body ul { max-width: 35em;} -pre { margin-left: 2em; background-color: #bbf; border: solid 1px black; - padding: 10px;} - -code { background-color: #ddf; padding: 3px; color: #008;} -pre code { background-color: #bbf;} -p, pre { max-width: 40em; } -h2 { - border-left: solid 2px #b00; - border-top: solid 2px #b00; - margin-top: 4em; - padding: 1em; margin-left: -1em;} -</style> diff --git a/docs/install-ruby.txt b/docs/install-ruby.txt deleted file mode 100644 index b653299..0000000 --- a/docs/install-ruby.txt +++ /dev/null @@ -1,71 +0,0 @@ -### Installing Ruby libraries and wrapper (optional) ### - -This step-by-step guide is written by me, for me. - -Installing with cmake: - - $ cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr/local - -First, set up some directories - - $ export SMLIB= - $ cd $SMLIB - $ ls - ................... - -Create installation directory: - - $ mkdir deploy - $ mkdir deploy/bin - $ export PATH=$PATH $SMLIB/deploy/bin - -Create a new ruby installation - - $ mkdir my_ruby - $ cd my_ruby - -Download ruby: - - $ wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz - $ tar xvzf ruby-1.8.5.tar.gz - $ ./configure --prefix=$SMLIB/deploy - $ make - $ make install - -Now you should be able to use the new ruby installation - - $ which ruby - <SMLIB>/deploy/bin/ruby - $ ruby --version - ruby 1.8.5 (2006-08-25) - -Instructions for installing rb-gsl: - -1. Get and install GSL. Make sure the command "gsl-config" is in command search path. -2. Download Ruby/GSL, ungzip and untar the archive rb-gsl-xxx.tar.gz. -3. Use: - % cd rb-gsl-xxx/ - % ruby setup.rb config - % ruby setup.rb setup - % ruby setup.rb install (as root) - -Download rubygems: - - $ cd $SMLIB/my_ruby - $ wget http://rubyforge.org/frs/download.php/11289/rubygems-0.9.0.tgz - $ tar xvzf rubygems-0.9.0.tgz - $ cd rubygems-0.9.0 - $ ruby setup.rb - -Now you should have the "gem" command installed: - - $ which gem - <SMLIB>/deploy/bin/gem - - -<!-- -/path/to/cmake . -DCMAKE_INSTALL_PREFIX:PATH=/path/to/install/to/scribuscmake/ - -#export PKG_CONFIG_PATH=/Users/andrea/06MELANIA/censi-2006/Matlab-yasmine/deploy/lib/pkgconfig/ - ---> \ No newline at end of file diff --git a/docs/install.txt b/docs/install.txt deleted file mode 100644 index 9e1f9b0..0000000 --- a/docs/install.txt +++ /dev/null @@ -1,96 +0,0 @@ - -Installation ------------- - -<!-- -### Downloading ### - -Download with SVN, using the following: - - $ svn checkout --username ANTANI svn://net143-184.mclink.it/csm - -where `ANTANI` is your surname (you should have received a password). - -This will checkout both the source code -and some files used for experiments, that might be slightly slow to download. -If you are only interested in the source code, use: - - $ svn checkout --username ANTANI svn://net143-184.mclink.it/csm/csm ---> - -### Required software dependencies ### - -This software has been tested on Mac OS X, Linux, and Windows XP (using Cygwin). -It compiles with GCC (3.3 or 4.x) and the Intel C++ Compiler (ICC). - -Required software: -* The build system is based on `cmake`, which is available at <http://www.cmake.org/>. -* The GSL, Gnu Scientific Library, available at <http://www.gnu.org/software/gsl/>. -* (optional) For `log2pdf` and other visualization applications, you will need the Cairo graphics library, available at <http://cairographics.org>. The recommended version is the stable 1.4.12. - -**Linux**. CMake, Cairo, and GSL are probably already packaged for your Linux distribution. For example, in Ubuntu, you can simply enter this command to install all dependencies: - - $ sudo apt-get install build-essential cmake libgsl0-dev libcairo2-dev - -**OS X**. You can install GSL using [Fink](http://finkproject.org/). You have to install Cairo manually. - -**Windows XP, using Cygwin**. CSM runs fine on Cygwin, but very slow compared to Linux/OS X. -Make sure you install the Cygwin packages `cairo`, `gsl`, `gsl-apps`, `gsl-devel`. - -**Windows XP, using Visual Studio**. CSM doesn't compile yet on this platform. CMake can theoretically create -Visual Studio projects, but I could not manage to do it. Also, some CMake code is probably Unix-specific. - -### Compiling ### - -If you are lucky, this should be it: - - $ cmake . - $ make - -If you want to install this library system-wide, you could use: - - $ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local . - $ make - $ make install - -as the first step. - - -For installing the Ruby wrapper, refer to the separate instructions. -If you want to use the Ruby wrapper, I suggest to install the source -code in a `deploy` sub-directory of `csm`: - - csm/ - docs/ - csm/ - rsm/ - deploy/ <--- here - -To do this, use: - - $ cmake -DCMAKE_INSTALL_PREFIX:PATH=`pwd`/deploy . - $ make - $ make install - -(you have to give a complete path to `-DCMAKE_INSTALL_PREFIX:PATH`). - -Later, remember to set your `PATH` variable to `csm/deploy/bin`. - -### Getting started ### - -You might get started by doing this: - - $ sm2 < in.log > out.log - -where `in.log` is a Carmen-format log file. - -You can find one in the top-level `experiments` directory: it is called `laserazosSM3.log`. -So, if you installed the Cairo library, you can see the result with: - - $ sm2 < in.log > out.log - $ log2pdf -use odometry -in out.log -out out-odometry.pdf - $ log2pdf -use estimate -in out.log -out out-estimate.pdf - - - - diff --git a/docs/laserdata.lyx b/docs/laserdata.lyx deleted file mode 100644 index 25afd35..0000000 --- a/docs/laserdata.lyx +++ /dev/null @@ -1,285 +0,0 @@ -#LyX 1.4.4 created this file. For more info see http://www.lyx.org/ -\lyxformat 245 -\begin_document -\begin_header -\textclass article -\begin_preamble -\usepackage{verbatim} -\end_preamble -\language english -\inputencoding auto -\fontscheme default -\graphics default -\paperfontsize default -\spacing single -\papersize default -\use_geometry false -\use_amsmath 1 -\cite_engine basic -\use_bibtopic false -\paperorientation portrait -\secnumdepth 3 -\tocdepth 3 -\paragraph_separation indent -\defskip medskip -\quotes_language english -\papercolumns 1 -\papersides 1 -\paperpagestyle default -\tracking_changes false -\output_changes false -\end_header - -\begin_body - -\begin_layout Section -The laser data data structure -\end_layout - -\begin_layout Standard -Laser data is passed around in a Matlab structure, which is quite rich and - in some ways redundant to achieve ease of use. - -\end_layout - -\begin_layout Standard -A description of the fields follows. -\end_layout - -\begin_layout Description - -\family typewriter -ld.nrays -\end_layout - -\begin_deeper -\begin_layout Standard -Number of rays. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.theta(i) -\end_layout - -\begin_deeper -\begin_layout Standard -Direction of -\begin_inset Formula $i$ -\end_inset - --th ray with respect to the robot. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.readings(i) -\end_layout - -\begin_deeper -\begin_layout Standard -Sensor reading (meters). - If the reading is not valid, then -\family typewriter -ld.readings(i) == nan -\family default -. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.readings_valid(i)\InsetSpace ~ -or\InsetSpace ~ -ld.valid(i) -\end_layout - -\begin_deeper -\begin_layout Standard -This field is true if this ray is valid. - Invalid rays occur when the obstacle is farther than the sensor horizon. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.true_alpha(i) -\end_layout - -\begin_deeper -\begin_layout Standard -Orientation of the surface (radians, relative to robot). - It is -\family typewriter - nan -\family default -if not valid. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.true_alpha_abs(i) -\end_layout - -\begin_deeper -\begin_layout Standard -(eliminated in new version) Orientation of the surface (radians, relative - to -\series bold -world -\series default -). - It is -\family typewriter - nan -\family default -if not valid. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.alpha(i) -\end_layout - -\begin_deeper -\begin_layout Standard -Estimated orientation of the surface (radians, relative to robot). - It is an estimation of ld.true_alpha(i) -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.alpha_valid(i) -\end_layout - -\begin_deeper -\begin_layout Standard -True if previous field is valid. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.alpha_error(i) -\end_layout - -\begin_layout Standard -True if previous field is valid. -\end_layout - -\begin_layout Description - -\family typewriter -ld.true_pose -\end_layout - -\begin_deeper -\begin_layout Standard -Pose of the robot (m,m,rad), in world coordinates. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.odometry -\end_layout - -\begin_deeper -\begin_layout Standard -Corrupted true_pose. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.estimate -\end_layout - -\begin_deeper -\begin_layout Standard -Estimate of true_pose. -\end_layout - -\end_deeper -\begin_layout Description - -\family typewriter -ld.points -\end_layout - -\begin_layout Description - -\family typewriter -ld.hostname -\end_layout - -\begin_layout Description - -\family typewriter -ld.timestamp1,\InsetSpace ~ -ld.timestamp2 -\end_layout - -\begin_layout Section -Featured functions -\end_layout - -\begin_layout Description -ld_fisher This function computes Fisher's information matrix, in robot coordinat -es. - -\end_layout - -\begin_deeper -\begin_layout Standard -Uses field 'true_alpha' (and 'theta', 'readings'). - -\end_layout - -\begin_layout Standard -For details about the Fisher's information matrix for localization, please - see this paper: http://purl.org/censi/2006/accuracy -\end_layout - -\end_deeper -\begin_layout Standard -Available as matlab function -\emph on -ld_fisher0.m -\emph default -, C function ld -\emph on -_ -\emph default -fisher0 and command line ld_fisher. -\end_layout - -\begin_layout Section -Other utilities -\end_layout - -\begin_layout Subsection -Reading from file -\end_layout - -\begin_layout Subsection -Displaying laserdata -\end_layout - -\end_body -\end_document diff --git a/docs/laserdata.txt b/docs/laserdata.txt deleted file mode 100644 index 5ad81d1..0000000 --- a/docs/laserdata.txt +++ /dev/null @@ -1,83 +0,0 @@ - -## The `laser_data` data structure ## - -Laser data is passed around in a structure which is quite -rich and in some ways redundant to achieve ease of use. - -In C, the structure's name is `struct laser_data`. In Ruby, -it is `class LaserData`. In Matlab, it's a generic structure. - -A description of the fields follows (assume the structure is -called `ld`). - -Regarding the pose of the robot: - -`ld.true_pose` -: Pose of the robot (m,m,rad), in world coordinates. - -`ld.odometry` -: Odometry (`true_pose` corrupted by noise). - -`ld.estimate` -: Estimate of `true_pose`. - -Regarding the rays: - -`ld.nrays` -: Number of rays. - -`ld.min_theta` and `ld.max_theta` -: Minimum and maximum theta (radians). - -`ld.theta[i]` -: Direction of i-th ray with respect to the robot (radians). - -`ld.readings[i]` -: Sensor reading (meters). If the reading is not valid, - then `ld.readings(i) == NAN`. - -`ld.valid[i]` -: In C, it assumes values `0` and `1`. - In Ruby, it assumes values `true` or `false`. - (**TODO**: choose how to serialize). - - This field is true if this ray is valid, and, in particular, - `ld.readings[i]` is valid. Invalid rays - occur when the obstacle is farther than the sensor horizon. - -`ld.true_alpha[i]` -: Orientation of the normal of the surface (radians, relative to -robot). It is `NAN` if not valid. - -`ld.alpha[i]` -: Estimated orientation of the surface (radians, -relative to robot). It is an estimate of `ld.true_alpha[i]`. - -`ld.alpha_valid[i]` -: True if previous field is valid. - -`ld.cov_alpha[i]` -: Estimated covariance of `ld.alpha[i]`. - -Additional fields used during the computation: - -`ld.cluster[i]` -: Cluster to which point i belongs. This is used for computing -the orientation (at the moment a really dumb algorithm is used -for clustering). If `cluster[i] == -1`, the point does not belong -to any cluster. - -`ld.points[i].p` -: Point coordinates (cartesian). Computed from the polar coordinates -`theta[i]` and `readings[i]`. - -`ld.points_w[i].p` -: Point coordinates (cartesian) in a "world" reference frame. Computed with the function `ld_compute_world_coords(LDP, double pose[3])`. - -`ld.hostname` -: This is parsed from the Carmen data field. - -`ld.tv` -: This is a `struct timeval` field giving a timestamp for the laser scan. Please see the section on parsing to learn how this is parsed from the Carmen log. - - diff --git a/docs/misc.txt b/docs/misc.txt deleted file mode 100644 index 6100344..0000000 --- a/docs/misc.txt +++ /dev/null @@ -1,3 +0,0 @@ -Installing GSL: - - export CFLAGS="-Wno-long-double -mtune=7450 -mcpu=7450 -fomit-frame-pointer -O3"; ./configure --disable-shared --prefix=/Volumes/Alter/07repo/csm/csm/deploy \ No newline at end of file diff --git a/docs/optimization-notes.txt b/docs/optimization-notes.txt deleted file mode 100644 index aff9a7f..0000000 --- a/docs/optimization-notes.txt +++ /dev/null @@ -1,130 +0,0 @@ -2007-06-08 - - -Prima di ottimizzare, compilato con -O3 -fomit-frame-pointer -mcpu - - time = 23.719999 (seconds) (start=104 end=2476) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5774 -sm0: Avg. iterations per matching = 7.431146 -sm0: Avg. seconds per matching = 0.030528 -sm0: that is, 32 matchings per second -sm0: Avg. seconds per iteration = 0.004108 (note: very imprecise) -sm0: Number of comparisons = 15708338 -sm0: Avg. comparisons per ray = 7.536093 - -dopo aver cambiato outliers, togliendo i gsl_vector (ma tenendo sqrt) - -sm0: CPU time = 16.620001 (seconds) (start=103 end=1765) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5774 -sm0: Avg. iterations per matching = 7.431146 -sm0: Avg. seconds per matching = 0.021390 -sm0: that is, 46 matchings per second -sm0: Avg. seconds per iteration = 0.002878 (note: very imprecise) -sm0: Number of comparisons = 15708328 -sm0: Avg. comparisons per ray = 7.536088 - -in tricks: dopo aver tolto gsl_vector_get da distance in tricks: - -sm0: CPU time = 14.390000 (seconds) (start=103 end=1542) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5774 -sm0: Avg. iterations per matching = 7.431146 -sm0: Avg. seconds per matching = 0.018520 -sm0: that is, 53 matchings per second -sm0: Avg. seconds per iteration = 0.002492 (note: very imprecise) -sm0: Number of comparisons = 15708328 -sm0: Avg. comparisons per ray = 7.536088 - -1.0% 46.8% sm3 compute_next_estimate -6.4% 26.1% sm3 find_correspondences_tricks -0.5% 13.2% sm3 kill_outliers_trim -0.6% 10.2% sm3 kill_outliers_double - -Dopo aver cambiato distance_d, distance_squared in kill_outliers_double: - -sm0: CPU time = 13.310000 (seconds) (start=105 end=1436) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5774 -sm0: Avg. iterations per matching = 7.431146 -sm0: Avg. seconds per matching = 0.017130 -sm0: that is, 58 matchings per second -sm0: Avg. seconds per iteration = 0.002305 (note: very imprecise) -sm0: Number of comparisons = 15708328 -sm0: Avg. comparisons per ray = 7.536088 - -1.0% 50.6% sm3 compute_next_estimate -6.8% 28.3% sm3 find_correspondences_tricks -0.6% 14.3% sm3 kill_outliers_trim -0.6% 3.4% sm3 kill_outliers_double - -Dopo aver tolto cos(alpha)*cos(alpha): - -sm0: CPU time = 12.590000 (seconds) (start=104 end=1363) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5774 -sm0: Avg. iterations per matching = 7.431146 -sm0: Avg. seconds per matching = 0.016203 -sm0: that is, 61 matchings per second -sm0: Avg. seconds per iteration = 0.002180 (note: very imprecise) -sm0: Number of comparisons = 15708328 -sm0: Avg. comparisons per ray = 7.536088 - -0.7% 48.4% sm3 compute_next_estimate -7.4% 29.8% sm3 find_correspondences_tricks -0.5% 14.7% sm3 kill_outliers_trim -0.7% 3.8% sm3 kill_outliers_double - -Dopo aver linkato a GSL 1.9 con 03 e mtune: - -sm0: CPU time = 10.270000 (seconds) (start=104 end=1131) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5774 -sm0: Avg. iterations per matching = 7.431146 -sm0: Avg. seconds per matching = 0.013218 -sm0: that is, 75 matchings per second -sm0: Avg. seconds per iteration = 0.001779 (note: very imprecise) -sm0: Number of comparisons = 15706493 -sm0: Avg. comparisons per ray = 7.535208 - -1.1% 49.2% sm3 compute_next_estimate -9.9% 23.4% sm3 find_correspondences_tricks -0.8% 19.3% sm3 kill_outliers_trim -0.9% 4.6% sm3 kill_outliers_double - -Dopo aver messo le costanti C0,C1 in tricks: - -sm0: CPU time = 9.530000 (seconds) (start=105 end=1058) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5822 -sm0: Avg. iterations per matching = 7.492921 -sm0: Avg. seconds per matching = 0.012265 -sm0: that is, 81 matchings per second -sm0: Avg. seconds per iteration = 0.001637 (note: very imprecise) -sm0: Number of comparisons = 15837504 -sm0: Avg. comparisons per ray = 7.535418 - -1.6% 48.0% sm3 compute_next_estimate -8.4% 22.3% sm3 find_correspondences_tricks -0.8% 20.9% sm3 kill_outliers_trim -0.9% 5.0% sm3 kill_outliers_double - -Dopo aver tolto gsl_matrix in GPC: - -sm0: CPU time = 6.740000 (seconds) (start=104 end=778) -sm0: Total number of matchings = 777 -sm0: Total number of iterations = 5822 -sm0: Avg. iterations per matching = 7.492921 -sm0: Avg. seconds per matching = 0.008674 -sm0: that is, 115 matchings per second -sm0: Avg. seconds per iteration = 0.001158 (note: very imprecise) -sm0: Number of comparisons = 15837504 -sm0: Avg. comparisons per ray = 7.535418 - -11.8% 31.9% sm3 find_correspondences_tricks -1.2% 30.6% sm3 kill_outliers_trim -2.3% 24.8% sm3 compute_next_estimate -1.4% 7.4% sm3 kill_outliers_double - - diff --git a/docs/optimizations.txt b/docs/optimizations.txt deleted file mode 100644 index aa3b205..0000000 --- a/docs/optimizations.txt +++ /dev/null @@ -1,14 +0,0 @@ - -Optimizations -------------- - -The ICP code is reasonably optimized (the correspondence search in particular). -But only algorithmic optimization were used. In particular, the following were *not* used: - -- look-up tables -- fixed-point math -- chipset-specific extensions for vectorizations (altivec, etc) -- optimizations that would give an approximation to the answer -- assembler in general - -All computations done in *double* precision (*float* would be more than enough). diff --git a/docs/other.txt b/docs/other.txt deleted file mode 100644 index 94b5d1e..0000000 --- a/docs/other.txt +++ /dev/null @@ -1,21 +0,0 @@ -Misc documentation ------------------- - -**Do not believe anything you read here** - -### Featured functions ### - -`ld_fisher ` -: This function computes Fisher's information - matrix, in robot coordinates. - - It uses field `true_alpha` (and `theta`, `readings`). - - For details about the Fisher's information matrix for - localization, please see this paper: - - <http://purl.org/censi/2006/accuracy> - - Available as matlab function `ld_fisher0.m`, C function - `ld_fisher0` and command line `ld_fisher`. - diff --git a/docs/preamble.tex b/docs/preamble.tex deleted file mode 100644 index 62fd1ab..0000000 --- a/docs/preamble.tex +++ /dev/null @@ -1,5 +0,0 @@ -\setlength\parindent{0pt} -\setlength\parskip{5pt} -%\usepackage[textwidth=72ex]{geometry} -\usepackage[vmargin={1in,1in},hmargin={1in,2in}]{geometry} -%\usepackage[margin=1in]{geometry} diff --git a/docs/preamble.txt b/docs/preamble.txt deleted file mode 100644 index 0c23de1..0000000 --- a/docs/preamble.txt +++ /dev/null @@ -1,6 +0,0 @@ -CSS: style.css -Use numbered headers: true -HTML use syntax: true -LaTeX use listings: true -LaTeX CJK: false -LaTeX preamble: preamble.tex diff --git a/docs/readme.txt b/docs/readme.txt deleted file mode 100644 index c54130d..0000000 --- a/docs/readme.txt +++ /dev/null @@ -1,127 +0,0 @@ - -The C(anonical) Scan Matcher -================================ - -* TOC -{:toc} - -## Introduction ## - -I created this package: - -- To have a well-documented reference implementation of [PL-ICP](http://purl.org/censi/2007/plicp). If you are only interested in the core algorithm of PL-ICP, a [separate concise implementation in C/Matlab/Ruby](http://purl.org/censi/2007/plicp) is available. - -- To have a **trustworthy** scan matcher to be used in the experiments for some papers on [ICP covariance](http://purl.org/censi/2006/icpcov), [the Cramer-Rao bound for range finders](http://purl.org/censi/2006/accuracy), and [robot calibration](http://purl.org/censi/2007/calib). For batch experiments, it's also useful that it's pretty fast. - -- To have a collection of utilies for command line (UNIX-style) manipulation of laser data, and creating beautiful maps and animations. - -## Content of this package ## - -The core content is the C scan matching library which is quite polished, but this package contains a lot of software, only some of that in an usable state. -In general, I am not ashamed of the prototypical code I write. - -### Stable things: C scan matching library ### - -The directory `sm/csm` contains a scan matcher written in C, plus -associated tools and apps. This is stable and reasonably bug-free. - -There are many libraries in the `sm/lib` directory: - -- Directory `egsl`: a light wrapper for GSL that makes manipulating - matrices easy and efficient. This is documented in another file: - see `sm/lib/egsl/docs`. - -- Directory `options`: for processing command-line arguments and - configuration files. - -- Directory `json-c`: a library for JSON input/output. This is a - slightly modified version of the original [`json-c`][json-c] - library released under the [MIT license]. - -### Stable things: applications ### - -There are many applications in the `sm/apps` directory: - -- Application `sm2`: standard scan-matching. Reads a log, runs ICP, and writes the scan-matched output. Input can be both Carmen and JSON. - -- Application `sm3`: like sm2, but instead of actual output it measures the performance. This is the application that produced the stats found in the paper submitted to ICRA'08. - -- Application `sm1`: useful for running experiments. Reads scans - from two different files, and outputs statistics. - -Visualization apps: - -- Application `log2pdf`: converts a laser log to a PDF map. - To build this application, it is needed to install the [Cairo] graphics - library. - -- Application `sm_animate`: creates an animation for the ICP process, displaying the correspondences, etc. This application reads the output created by `sm2` with the `-file_jj` option. To build this application, it is needed to install the [Cairo] graphics -library. - -Miscellaneous Unix-style processing for laser data: - -- Application `carmen2json`: converts a Carmen log to the JSON format. - -- Application `ld_fisher`: computes the Fisher's information matrix. See <http://purl.org/censi/2006/accuracy> for details. - -- Application `json_extract`: extract the n-th object from a JSON stream. - -- Application `ld_slip`: adds some noise to the odometry field. - -- Application `ld_smooth`: smooths the readings data. - -- Application `ld_noise`: adds sensor noise. - -- Application `ld_cluster_curv`: clusterize the rays based on the analysis of the curvature. - -- Application `ld_linearize`: fits a line to each cluster (data must have been previously clustered, for example by `ld_cluster_curv`). - - -GUI apps: - -- `apps/gtk_viewer` contains the prototype of a viewer using GTK. It does not work yet. - -### Unstable things: scripts ### - -In the `scripts/` directory you can find: - -- Script `json2matlab.rb`: converts a JSON object in a Matlab scripts. - This is the holy grail of data exchange. - - Warning: at the moment, this script relies on some patches to - the Ruby JSON library. Without them, it is limited to only - 1 JSON object in each file. - -- Script `fig2pics.rb`: used for converting FIG files to PDF. - It has many more options than [`fig2dev`][fig2dev] (that is being used internally), - including the ability to use a LaTeX preamble and to change - the resulting bounding box. - -- Script `create_video.rb`: displays the scan-matching process. - This reads the journal files written by applications `sm1` and `sm2`. - **Made obsolete by `sm_animate`** - -### Unstable things: Ruby and Matlab implementations ### - -Unstable things include: - -- Directory `sm_ruby_wrapper/`: a ruby wrapper for the `sm` C library. This wrapper is used for running some of the experiments. It is not documented and it needs tidying a little. - -- Directory `rsm/`: a Ruby implementation of the same algorithms used - in the `sm` library. Some times ago, the C and Matlab implementation - were perfectly in sync. Now they differ a little. However, in the future - I will try to get them back in sync, as the only way of having a good - chance of making a bug-free implementation, is to make it twice. - -- Directory `matlab/` and `matlab_new/`. The Matlab scripts are a mess that needs tidying. There's a lot in there. They are kept here because they are used for creating some of the figures in the submitted papers. Also, the first PLICP implementation was written in Matlab and is buried there, somewhere. - - Also, I occasionally tried to make sure that the scripts run fine - in [Octave]. They do, except for the plotting. - - -[octave]: http://www.octave.org -[cairo]: http://cairographics.org -[json-c]: http://www.json.org -[fig2dev]: http://www.xfig.org -[MIT license]: http://en.wikipedia.org/wiki/MIT_License - diff --git a/docs/references.txt b/docs/references.txt deleted file mode 100644 index 8f632b1..0000000 --- a/docs/references.txt +++ /dev/null @@ -1,3 +0,0 @@ -Fast atan2: - -http://lists.apple.com/archives/PerfOptimization-dev/2005/Jan/threads.html#00032 \ No newline at end of file diff --git a/docs/style.css b/docs/style.css deleted file mode 100644 index 4e563b3..0000000 --- a/docs/style.css +++ /dev/null @@ -1,106 +0,0 @@ - -body { - font-family: Georgia; - max-width: 40em; - padding-left: 3em; -} - -#news { - background-color: #fee; - border: solid 2px red; - padding: 0.3em; - margin: 0.3em; - width: 50%; -} - -h1 { margin-left: -1em;} -h2 { margin-left: -1em;} - -pre { - margin-left: 2em; - background-color: #eff; - border: solid 1px #bdd; - padding: 4px; -} - -/*code {background-color: #eff;}*/ -h1 strong { color: red;} - -table.example TD, -table.example TR, -table.example TH { - border: solid 1px #555; - padding: 4px; - -} - -img#logo { - float: right; -} - -/*pre SPAN { border: solid 1px black; }*/ - -.ruby .normal {} -.ruby .comment { color: #005; font-style: italic; } -.ruby .keyword { color: #A00; font-weight: bold; } -.ruby .method { color: #077; } -.ruby .class { color: #074; } -.ruby .module { color: #050; } -.ruby .punct { color: #447; font-weight: bold; } -.ruby .symbol { color: #099; } -.ruby .string { color: #944; background: #FFE; } -.ruby .char { color: #F07; } -.ruby .ident { color: #004; } -.ruby .constant { color: #07F; } -.ruby .regex { color: #B66; background: #FEF; } -.ruby .number { color: #F99; } -.ruby .attribute { color: #7BB; } -.ruby .global { color: #7FB; } -.ruby .expr { color: #227; } -.ruby .escape { color: #277; } - -.xml .normal {} -.xml .namespace { color: #B66; font-weight: bold; } -.xml .tag { color: #F88; } -.xml .comment { color: #005; font-style: italic; } -.xml .punct { color: #447; font-weight: bold; } -.xml .string { color: #944; } -.xml .number { color: #F99; } -.xml .attribute { color: #BB7; } - -.html .normal {} -.html .namespace { color: #B66; font-weight: bold; } -.html .tag { color: #F88; } -.html .comment { color: #005; font-style: italic; } -.html .punct { color: #447; font-weight: bold; } -.html .string { color: #944; } -.html .number { color: #F99; } -.html .attribute { color: #BB7; } - -.maruku-att-origin { - padding-left: 30px; - margin-top: -1em; - font-size: 70%; - color: grey; -} - -.maruku-att-default { - padding-left: 30px; - margin-top: -1.4em; - margin-bottom: +1em; - font-size: 90%; -} - -a.maruku-link-samedoc { - color: red; -} - -a.maruku-link-local { - color: green; -} - -a.maruku-link-external { - color: blue; -} - - diff --git a/docs/todo.mm b/docs/todo.mm deleted file mode 100644 index 064a42d..0000000 --- a/docs/todo.mm +++ /dev/null @@ -1,38 +0,0 @@ -<map version="0.9.0_Beta_8" background_color="#ffffff"> -<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net --> -<node CREATED="1185522662655" ID="Freemind_Link_697017692" MODIFIED="1185522662655" TEXT="New Mindmap"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180440171456" HGAP="13" ID="Freemind_Link_1536550240" MODIFIED="1185522671080" POSITION="right" TEXT="icp" VSHIFT="-71"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181117607993" ID="Freemind_Link_1092514301" MODIFIED="1181117725197" TEXT="sm_icp_animation"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180597650306" ID="Freemind_Link_771510588" MODIFIED="1180605225798" TEXT="fare demo carina con animation"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181117621181" ID="Freemind_Link_755242794" MODIFIED="1181117705322" TEXT="creare default configurations (many_points)"/> -</node> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181117849182" ID="Freemind_Link_305830794" MODIFIED="1181117852985" TEXT="formati"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180735952196" ID="Freemind_Link_770251969" MODIFIED="1180735957333" TEXT="togliere theta da json"/> -</node> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181117858778" ID="Freemind_Link_1547450624" MODIFIED="1181117861394" TEXT="libcsm"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180772534386" ID="Freemind_Link_82493141" MODIFIED="1180772537900" TEXT="output CARMEN"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180772538326" ID="Freemind_Link_1186113497" MODIFIED="1180772543140" TEXT="opzione output_format"/> -</node> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180520218191" ID="Freemind_Link_1659736302" MODIFIED="1180520224162" TEXT="cambiare nomi maxPerc e *Deg"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180519409707" ID="Freemind_Link_1896482752" MODIFIED="1180519416420" TEXT="fare check memoria con valgrind"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180520392227" ID="Freemind_Link_1281566208" MODIFIED="1180520396890" TEXT="togliere assert da journal"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180520568815" ID="Freemind_Link_150033155" MODIFIED="1180520575765" TEXT="opzioni set in options"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180809994085" ID="Freemind_Link_648038378" MODIFIED="1180810000814" TEXT="quoted strings"/> -</node> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180448230938" ID="Freemind_Link_442257989" MODIFIED="1180448237104" TEXT="mettere misc_apps di là"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180440303009" ID="Freemind_Link_1454958561" MODIFIED="1180440309734" TEXT="sei sicuro della precisione json?"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181889593162" ID="Freemind_Link_1035409220" MODIFIED="1181889629303" TEXT="isnan con fast-math"/> -</node> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181117893258" ID="Freemind_Link_942437306" MODIFIED="1181117895596" TEXT="raytracer"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180776125485" ID="Freemind_Link_391369505" MODIFIED="1180776136422" TEXT="fare raytracer che legge le pose da file (non da cin)"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180440764465" ID="Freemind_Link_368708750" MODIFIED="1180440770287" TEXT="fare raytracing circles"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180775902928" ID="Freemind_Link_732352514" MODIFIED="1180775916533" TEXT="fare FIG.read(FILE*) e cambiare "raytracer.cpp""/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181656906861" ID="Freemind_Link_411765945" MODIFIED="1181656912316" TEXT="aggiungere real-cluster"/> -</node> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181117946781" ID="Freemind_Link_39490840" MODIFIED="1181117950748" TEXT="esperimenti"> -<node BACKGROUND_COLOR="#ffff00" CREATED="1180451745014" ID="Freemind_Link_514348022" MODIFIED="1180451751115" TEXT="disegnare altri ambienti"/> -<node BACKGROUND_COLOR="#ffff00" CREATED="1181118007333" ID="Freemind_Link_1940417774" MODIFIED="1181118012234" TEXT="rimetti a posto esperimenti"/> -</node> -</node> -</node> -</map> diff --git a/docs/troubleshootings.txt b/docs/troubleshootings.txt deleted file mode 100644 index 0c9b539..0000000 --- a/docs/troubleshootings.txt +++ /dev/null @@ -1,8 +0,0 @@ -## Known problems and troubleshootings ## - -### Usage of `-ffast-math` ### - -Use of `-ffast-math` is ok for computations. However, output routines do not work as expected. In particular, invalid JSON is generated, because it can't distinguish `NaN` values. - -To make sure that it's all ok, there is a test program called `test_math_utils_sanity` that checks for good behaviour with NaN values. - diff --git a/sm/csm/algos.h b/include/csm/algos.h similarity index 89% rename from sm/csm/algos.h rename to include/csm/algos.h index abcbd10..4f7fe3c 100644 --- a/sm/csm/algos.h +++ b/include/csm/algos.h @@ -1,11 +1,10 @@ #ifndef H_SCAN_MATCHING_LIB #define H_SCAN_MATCHING_LIB -#include <gsl/gsl_vector.h> -#include <gsl/gsl_matrix.h> +//#include <gsl/gsl_vector.h> +//#include <gsl/gsl_matrix.h> +#include <gsl_eigen/gsl_eigen.h> -#include "hsm/hsm.h" -#include "hsm/hsm_interface.h" #include "laser_data.h" @@ -125,13 +124,6 @@ struct sm_params { /** mark as invalid ( = don't use ) rays outside of this interval */ double min_reading, max_reading; - - /* Parameters specific to GPM (unfinished :-/ ) */ - double gpm_theta_bin_size_deg; - double gpm_extend_range_deg; - int gpm_interval; - /* Parameter specific to HSM (unfinished :-/ ) */ - struct hsm_params hsm; }; @@ -159,14 +151,9 @@ struct sm_result { void sm_icp(struct sm_params*input, struct sm_result*output); -void sm_gpm(struct sm_params*input, struct sm_result*output); -void sm_hsm(struct sm_params*input, struct sm_result*output); - -/* Unfinished, untested :-/ */ -void sm_mbcip(struct sm_params*input, struct sm_result*output); - - void sm_journal_open(const char* file); +void csm_free_unused_memory(); + #endif diff --git a/include/csm/csm.h b/include/csm/csm.h new file mode 100644 index 0000000..9320b33 --- /dev/null +++ b/include/csm/csm.h @@ -0,0 +1,7 @@ +#ifndef H_CSM_H +#define H_CSM_H + +#include <csm/laser_data.h> +#include <csm/algos.h> + +#endif diff --git a/sm/csm/laser_data.h b/include/csm/laser_data.h similarity index 97% rename from sm/csm/laser_data.h rename to include/csm/laser_data.h index 15645d1..3e8c483 100644 --- a/sm/csm/laser_data.h +++ b/include/csm/laser_data.h @@ -1,7 +1,14 @@ #ifndef H_LASER_DATA #define H_LASER_DATA +// KUKA: WINDOWS COMPILATION +#ifndef WINDOWS #include <sys/time.h> +#else +#include <time.h> +#include <windows.h> +#endif + #include <stdio.h> #include "restrict.h" diff --git a/sm/csm/laser_data_inline.h b/include/csm/laser_data_inline.h similarity index 85% rename from sm/csm/laser_data_inline.h rename to include/csm/laser_data_inline.h index b258651..d351c62 100644 --- a/sm/csm/laser_data_inline.h +++ b/include/csm/laser_data_inline.h @@ -1,10 +1,11 @@ #ifndef H_LASER_DATA_INLINE #define H_LASER_DATA_INLINE -#include <gsl/gsl_math.h> -#include <gsl/gsl_vector.h> +//#include <gsl/gsl_math.h> +//#include <gsl/gsl_vector.h> +#include <limits> -#include "csm.h" +//#include "csm.h" /* Simple inline functions */ @@ -22,7 +23,7 @@ INLINE void ld_set_null_correspondence(LDP ld, int i) { ld->corr[i].valid = 0; ld->corr[i].j1 = -1; ld->corr[i].j2 = -1; - ld->corr[i].dist2_j1 = GSL_NAN; + ld->corr[i].dist2_j1 = std::numeric_limits<double>::quiet_NaN(); //GSL_NAN; } INLINE void ld_set_correspondence(LDP ld, int i, int j1, int j2) { diff --git a/sm/csm/restrict.h b/include/csm/restrict.h similarity index 95% rename from sm/csm/restrict.h rename to include/csm/restrict.h index 5582dd5..786aadf 100644 --- a/sm/csm/restrict.h +++ b/include/csm/restrict.h @@ -1,6 +1,4 @@ /* Some preprocessor magic for having fast inline functions. */ -#include <gsl/gsl_matrix.h> - #ifndef INLINE #define INLINE static inline #endif diff --git a/include/gsl_eigen/gsl_eigen.h b/include/gsl_eigen/gsl_eigen.h new file mode 100644 index 0000000..b427953 --- /dev/null +++ b/include/gsl_eigen/gsl_eigen.h @@ -0,0 +1,80 @@ +/* + * gsl_eigen.h + * + * Created on: Oct 11, 2012 + * Author: sprunkc + */ + +#ifndef GSL_EIGEN_H_ +#define GSL_EIGEN_H_ + +#include <Eigen/Core> +#include <Eigen/Geometry> + +typedef Eigen::VectorXd gsl_vector; +typedef Eigen::MatrixXd gsl_matrix; + +inline gsl_vector *gsl_vector_alloc (const size_t n){ + return new Eigen::VectorXd(n); +} + +inline void gsl_vector_free (gsl_vector * v){ + delete v; +} + +inline void gsl_vector_memcpy (gsl_vector * dest, const gsl_vector * src){ + *dest = *src; +} + + +inline double gsl_vector_get (const gsl_vector * v, const size_t i){ + return (*v)(i); +} + +inline void gsl_vector_set (gsl_vector * v, const size_t i, double x){ + (*v)(i) = x; +} + + +inline gsl_matrix* gsl_matrix_alloc(const size_t rows, const size_t cols){ + return new Eigen::MatrixXd(rows, cols); +} + +inline void gsl_matrix_free(gsl_matrix* m){ + delete m; +} + +inline void gsl_matrix_memcpy(gsl_matrix* m2, const gsl_matrix* m){ + *m2 = *m; +} + +inline void gsl_matrix_set(gsl_matrix * m, const size_t i, const size_t j, const double x){ + (*m)(i,j) = x; +} + +inline void gsl_matrix_set_zero (gsl_matrix * m){ + m->setZero(); +} + + +inline double gsl_matrix_get(const gsl_matrix * m, const size_t i, const size_t j){ + return (*m)(i,j); +} + +inline double * gsl_matrix_ptr(gsl_matrix * m, const size_t i, const size_t j){ + return &(*m)(i,j); +} + +inline void gsl_matrix_set_all (gsl_matrix * m, double x){ + m->setConstant(x); +} + +inline void gsl_matrix_add (gsl_matrix * a, const gsl_matrix * b){ + *a += *b; +} + +inline void gsl_matrix_scale (gsl_matrix * a, const double x){ + *a *=x; +} + +#endif /* GSL_EIGEN_H_ */ diff --git a/install_quickstart.sh b/install_quickstart.sh deleted file mode 100755 index 3e9e727..0000000 --- a/install_quickstart.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -echo "If you are lucky, this is it. (press ENTER)" -read -mkdir -p deploy -cmake -DCMAKE_INSTALL_PREFIX:PATH=`pwd`/deploy . -make -make install - diff --git a/local_config/icc-warnings.txt b/local_config/icc-warnings.txt deleted file mode 100644 index cbad50e..0000000 --- a/local_config/icc-warnings.txt +++ /dev/null @@ -1,216 +0,0 @@ -/home/acensi/src/csm/csm/sm/csm/icp/icp.c(3): remark #869: parameter "file" was never referenced - void sm_journal_open(const char* file) { - ^ - -/home/acensi/src/csm/csm/sm/csm/laser_data_json.c(97): remark #1572: floating-point equality and inequality comparisons are unreliable - int i; for(i=0;i<n;i++) if(v[i]==v[i]) return 0; - ^ - -/home/acensi/src/csm/csm/sm/csm/logging.c(20): remark #593: parameter "msg" was set but never used - void sm_debug(const char *msg, ...) - ^ - -/home/acensi/src/csm/csm/sm/csm/math_utils.c(76): remark #1572: floating-point equality and inequality comparisons are unreliable - return v == v ? 0 : 1; - ^ - -/home/acensi/src/csm/csm/sm/lib/gpc/gpc.c(33): remark #869: parameter "x0" was never referenced - const double*x0, const double *cov_x0, - ^ - -/home/acensi/src/csm/csm/sm/lib/gpc/gpc.c(33): remark #869: parameter "cov_x0" was never referenced - const double*x0, const double *cov_x0, - ^ - -/home/acensi/src/csm/csm/sm/lib/gpc/gpc_utils.c(70): remark #1572: floating-point equality and inequality comparisons are unreliable - if( (z[2*i+1]==0) && (z[2*i]>lambda)) - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(50): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_ERR, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(65): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_DEBUG, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(78): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_ERR, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(90): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_INFO, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_more_utils.c(184): remark #1572: floating-point equality and inequality comparisons are unreliable - return (v == v) ? /* NAN is null */ - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_object.c(271): warning #266: function "strdup" declared implicitly - lh_table_insert(this->o.c_object, strdup(key), val); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_object.c(271): warning #167: argument of type "const char *" is incompatible with parameter of type "void *" - lh_table_insert(this->o.c_object, strdup(key), val); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_object.c(312): remark #1572: floating-point equality and inequality comparisons are unreliable - return (this->o.c_double != 0); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(334): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[0] = tok->ucs_char; - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(337): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[0] = 0xc0 | (tok->ucs_char >> 6); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(338): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[1] = 0x80 | (tok->ucs_char & 0x3f); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(341): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[0] = 0xe0 | (tok->ucs_char >> 12); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(342): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(343): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[2] = 0x80 | (tok->ucs_char & 0x3f); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(451): warning #266: function "strdup" declared implicitly - obj_field_name = strdup(tok->pb->buf); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/linkhash.c(170): remark #111: statement is unreachable - return NULL; - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/printbuf.c(122): warning #266: function "vasprintf" declared implicitly - if((size = vasprintf(&t, msg, ap)) == -1) return -1; - ^ - -/home/acensi/src/csm/csm/sm/lib/gpc/gpc.c(33): remark #869: parameter "x0" was never referenced - const double*x0, const double *cov_x0, - ^ - -/home/acensi/src/csm/csm/sm/lib/gpc/gpc.c(33): remark #869: parameter "cov_x0" was never referenced - const double*x0, const double *cov_x0, - ^ - -/home/acensi/src/csm/csm/sm/lib/gpc/gpc_utils.c(70): remark #1572: floating-point equality and inequality comparisons are unreliable - if( (z[2*i+1]==0) && (z[2*i]>lambda)) - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(50): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_ERR, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(65): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_DEBUG, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(78): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_ERR, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/debug.c(90): warning #266: function "vsyslog" declared implicitly - vsyslog(LOG_INFO, msg, ap); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_object.c(271): warning #266: function "strdup" declared implicitly - lh_table_insert(this->o.c_object, strdup(key), val); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_object.c(271): warning #167: argument of type "const char *" is incompatible with parameter of type "void *" - lh_table_insert(this->o.c_object, strdup(key), val); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_object.c(312): remark #1572: floating-point equality and inequality comparisons are unreliable - return (this->o.c_double != 0); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(334): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[0] = tok->ucs_char; - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(337): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[0] = 0xc0 | (tok->ucs_char >> 6); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(338): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[1] = 0x80 | (tok->ucs_char & 0x3f); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(341): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[0] = 0xe0 | (tok->ucs_char >> 12); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(342): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(343): remark #810: conversion from "unsigned int" to "unsigned char" may lose significant bits - utf_out[2] = 0x80 | (tok->ucs_char & 0x3f); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_tokener.c(451): warning #266: function "strdup" declared implicitly - obj_field_name = strdup(tok->pb->buf); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/linkhash.c(170): remark #111: statement is unreachable - return NULL; - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/printbuf.c(122): warning #266: function "vasprintf" declared implicitly - if((size = vasprintf(&t, msg, ap)) == -1) return -1; - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/json_more_utils.c(184): remark #1572: floating-point equality and inequality comparisons are unreliable - return (v == v) ? /* NAN is null */ - ^ - -/home/acensi/src/csm/csm/sm/csm/laser_data_json.c(97): remark #1572: floating-point equality and inequality comparisons are unreliable - int i; for(i=0;i<n;i++) if(v[i]==v[i]) return 0; - ^ - -/home/acensi/src/csm/csm/sm/csm/math_utils.c(76): remark #1572: floating-point equality and inequality comparisons are unreliable - return v == v ? 0 : 1; - ^ - -/home/acensi/src/csm/csm/sm/csm/logging.c(20): remark #593: parameter "msg" was set but never used - void sm_debug(const char *msg, ...) - ^ - -/home/acensi/src/csm/csm/sm/csm/icp/icp.c(3): remark #869: parameter "file" was never referenced - void sm_journal_open(const char* file) { - ^ - -/home/acensi/src/csm/csm/sm/csm/math_utils_test.c(12): remark #177: variable "A" was declared but never referenced - gsl_vector * A = vector_from_array(2,a); - ^ - -/home/acensi/src/csm/csm/sm/csm/math_utils_test.c(13): remark #177: variable "B" was declared but never referenced - gsl_vector * B = vector_from_array(2,b); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/test1.c(167): remark #1599: declaration hides variable "my_array" (declared at line 11) - struct json_object *my_array = json_object_new_array(); - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/test1.c(168): remark #1599: declaration hides variable "i" (declared at line 13) - int i; for(i=0;i<20;i++) { - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/test1.c(7): remark #593: parameter "argc" was set but never used - int main(int argc, char **argv) - ^ - -/home/acensi/src/csm/csm/sm/lib/json-c/test1.c(7): remark #593: parameter "argv" was set but never used - int main(int argc, char **argv) - ^ - diff --git a/local_config/local-Melania.cmake b/local_config/local-Melania.cmake deleted file mode 100644 index da025b0..0000000 --- a/local_config/local-Melania.cmake +++ /dev/null @@ -1,32 +0,0 @@ - -# Melania is a 1.4GhZ PPC Powerbook - -SET(GSL_CONFIG_PREFER_PATH /Users/andrea/csm/csm/deploy/bin) -SET(GSL_CONFIG /Users/andrea/csm/csm/deploy/bin/gsl-config) - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-double") -SET(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-double") - -# -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mtune=7450 -mcpu=7450 -fomit-frame-pointer -O3") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mtune=7450 -mcpu=7450 -O2") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -gfull") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -fno-trapping-math -fno-signaling-nans") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -funsafe-math-optimizations -fno-trapping-math -fno-signaling-nans") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wmissing-prototypes -Wconversion -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wnested-externs -fshort-enums -fno-common -Winline" ) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unreachable-code") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstrict-aliasing") - -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -funroll-loops") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -falign-loops=16") - - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-prototypes ") - - -SET(COMPILE_HSM 0) diff --git a/local_config/local-linuxserv-icc.cmake b/local_config/local-linuxserv-icc.cmake deleted file mode 100644 index 38e3a6e..0000000 --- a/local_config/local-linuxserv-icc.cmake +++ /dev/null @@ -1,15 +0,0 @@ - -# linuxserv is a 4 x Xeon 1.8Gh - -#icc -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 ") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=pentium4 ") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd981 ") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd1418 -wd1419") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fp-model fast ") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall ") - - - - - diff --git a/local_config/local-linuxserv.cmake b/local_config/local-linuxserv.cmake deleted file mode 100644 index c777a72..0000000 --- a/local_config/local-linuxserv.cmake +++ /dev/null @@ -1,9 +0,0 @@ - -# linuxserv is a 4 x Xeon 1.8Gh - -#gcc -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer -O3") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=pentium4 -msse2 -mfpmath=sse -mmmx -funroll-loops") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftree-vectorize -ftree-vectorizer-verbose=5") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") - diff --git a/local_config/local-lisablack.cmake b/local_config/local-lisablack.cmake deleted file mode 100644 index c2512c1..0000000 --- a/local_config/local-lisablack.cmake +++ /dev/null @@ -1,9 +0,0 @@ - -# Lisablack is a Pentium 3 - - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer -O3") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=pentium3 -msse -O3 -pipe") - - -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") diff --git a/local_config/local-overlook.cmake b/local_config/local-overlook.cmake deleted file mode 100644 index 3696f15..0000000 --- a/local_config/local-overlook.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# overlook is a MacBook with Leopard - -#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-double") -#SET(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-double") - -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=pentium4 -pipe") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -gfull") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -fno-trapping-math -fno-signaling-nans") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -funsafe-math-optimizations -fno-trapping-math -fno-signaling-nans") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wmissing-prototypes -Wconversion -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wnested-externs -fshort-enums -fno-common -Winline" ) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unreachable-code") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstrict-aliasing") - -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -funroll-loops") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -falign-loops=16") - - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wmissing-prototypes ") - -#£SET(COMPILE_HSM 1) diff --git a/local_config/local-pammela.cmake b/local_config/local-pammela.cmake deleted file mode 100644 index 5bd204f..0000000 --- a/local_config/local-pammela.cmake +++ /dev/null @@ -1,24 +0,0 @@ - -# Melania is a 1.4GhZ PPC Powerbook - -#SET(GSL_CONFIG_PREFER_PATH /Users/andrea/csm/csm/deploy/bin) -#SET(GSL_CONFIG /Users/andrea/csm/csm/deploy/bin/gsl-config) - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-double") -SET(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-double") - -# -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mtune=7450 -mcpu=7450 -fomit-frame-pointer -O3") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -funsafe-math-optimizations -fno-trapping-math -fno-signaling-nans") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -Wmissing-prototypes -Wconversion -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wnested-externs -fshort-enums -fno-common -Winline" ) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unreachable-code") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstrict-aliasing") - -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -funroll-loops") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -falign-loops=16") - diff --git a/local_config/local-pdelapuente.cmake b/local_config/local-pdelapuente.cmake deleted file mode 100644 index 8fed575..0000000 --- a/local_config/local-pdelapuente.cmake +++ /dev/null @@ -1,4 +0,0 @@ - - -SET(COMPILE_HSM 0) -SET(COMPILE_STRUCTPRIOR 1) diff --git a/local_config/local-sorchetta.cmake b/local_config/local-sorchetta.cmake deleted file mode 100644 index 471ca6a..0000000 --- a/local_config/local-sorchetta.cmake +++ /dev/null @@ -1,3 +0,0 @@ -# sorchetta is an Intel Duo 2 with 2.0 Ghz for core - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=prescott -fomit-frame-pointer -O3 -msse3 -mfpmath=sse -pipe") diff --git a/misc/matlab/appunti/MMt.png b/misc/matlab/appunti/MMt.png deleted file mode 100644 index 9b4a3d4beb45d55f09a5cd440a2f278908dd8598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75939 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 diff --git a/misc/matlab/appunti/problem.eps b/misc/matlab/appunti/problem.eps deleted file mode 100644 index 9a24412..0000000 --- a/misc/matlab/appunti/problem.eps +++ /dev/null @@ -1,4973 +0,0 @@ -%!PS-Adobe-3.0 EPSF-3.0 -%%Creator: MATLAB, The Mathworks, Inc. -%%Title: /Users/andrea-base/repositories/alessia.svn/repository-andrea/years/2005/matlab-yasmine/problem.eps -%%CreationDate: 10/16/2005 21:51:51 -%%DocumentNeededFonts: Helvetica -%%DocumentProcessColors: Cyan Magenta Yellow Black -%%LanguageLevel: 2 -%%Pages: 1 -%%BoundingBox: 59 211 550 580 -%%EndComments - -%%BeginProlog -% MathWorks dictionary -/MathWorks 160 dict begin -% definition operators -/bdef {bind def} bind def -/ldef {load def} bind def -/xdef {exch def} bdef -/xstore {exch store} bdef -% operator abbreviations -/c /clip ldef -/cc /concat ldef -/cp /closepath ldef -/gr /grestore ldef -/gs /gsave ldef -/mt /moveto ldef -/np /newpath ldef -/cm /currentmatrix ldef -/sm /setmatrix ldef -/rm /rmoveto ldef -/rl /rlineto ldef -/s {show newpath} bdef -/sc {setcmykcolor} bdef -/sr /setrgbcolor ldef -/sg /setgray ldef -/w /setlinewidth ldef -/j /setlinejoin ldef -/cap /setlinecap ldef -/rc {rectclip} bdef -/rf {rectfill} bdef -% page state control -/pgsv () def -/bpage {/pgsv save def} bdef -/epage {pgsv restore} bdef -/bplot /gsave ldef -/eplot {stroke grestore} bdef -% orientation switch -/portraitMode 0 def /landscapeMode 1 def /rotateMode 2 def -% coordinate system mappings -/dpi2point 0 def -% font control -/FontSize 0 def -/FMS {/FontSize xstore findfont [FontSize 0 0 FontSize neg 0 0] - makefont setfont} bdef -/reencode {exch dup where {pop load} {pop StandardEncoding} ifelse - exch dup 3 1 roll findfont dup length dict begin - { 1 index /FID ne {def}{pop pop} ifelse } forall - /Encoding exch def currentdict end definefont pop} bdef -/isroman {findfont /CharStrings get /Agrave known} bdef -/FMSR {3 1 roll 1 index dup isroman {reencode} {pop pop} ifelse - exch FMS} bdef -/csm {1 dpi2point div -1 dpi2point div scale neg translate - dup landscapeMode eq {pop -90 rotate} - {rotateMode eq {90 rotate} if} ifelse} bdef -% line types: solid, dotted, dashed, dotdash -/SO { [] 0 setdash } bdef -/DO { [.5 dpi2point mul 4 dpi2point mul] 0 setdash } bdef -/DA { [6 dpi2point mul] 0 setdash } bdef -/DD { [.5 dpi2point mul 4 dpi2point mul 6 dpi2point mul 4 - dpi2point mul] 0 setdash } bdef -% macros for lines and objects -/L {lineto stroke} bdef -/MP {3 1 roll moveto 1 sub {rlineto} repeat} bdef -/AP {{rlineto} repeat} bdef -/PDlw -1 def -/W {/PDlw currentlinewidth def setlinewidth} def -/PP {closepath eofill} bdef -/DP {closepath stroke} bdef -/MR {4 -2 roll moveto dup 0 exch rlineto exch 0 rlineto - neg 0 exch rlineto closepath} bdef -/FR {MR stroke} bdef -/PR {MR fill} bdef -/L1i {{currentfile picstr readhexstring pop} image} bdef -/tMatrix matrix def -/MakeOval {newpath tMatrix currentmatrix pop translate scale -0 0 1 0 360 arc tMatrix setmatrix} bdef -/FO {MakeOval stroke} bdef -/PO {MakeOval fill} bdef -/PD {currentlinewidth 2 div 0 360 arc fill - PDlw -1 eq not {PDlw w /PDlw -1 def} if} def -/FA {newpath tMatrix currentmatrix pop translate scale - 0 0 1 5 -2 roll arc tMatrix setmatrix stroke} bdef -/PA {newpath tMatrix currentmatrix pop translate 0 0 moveto scale - 0 0 1 5 -2 roll arc closepath tMatrix setmatrix fill} bdef -/FAn {newpath tMatrix currentmatrix pop translate scale - 0 0 1 5 -2 roll arcn tMatrix setmatrix stroke} bdef -/PAn {newpath tMatrix currentmatrix pop translate 0 0 moveto scale - 0 0 1 5 -2 roll arcn closepath tMatrix setmatrix fill} bdef -/vradius 0 def /hradius 0 def /lry 0 def -/lrx 0 def /uly 0 def /ulx 0 def /rad 0 def -/MRR {/vradius xdef /hradius xdef /lry xdef /lrx xdef /uly xdef - /ulx xdef newpath tMatrix currentmatrix pop ulx hradius add uly - vradius add translate hradius vradius scale 0 0 1 180 270 arc - tMatrix setmatrix lrx hradius sub uly vradius add translate - hradius vradius scale 0 0 1 270 360 arc tMatrix setmatrix - lrx hradius sub lry vradius sub translate hradius vradius scale - 0 0 1 0 90 arc tMatrix setmatrix ulx hradius add lry vradius sub - translate hradius vradius scale 0 0 1 90 180 arc tMatrix setmatrix - closepath} bdef -/FRR {MRR stroke } bdef -/PRR {MRR fill } bdef -/MlrRR {/lry xdef /lrx xdef /uly xdef /ulx xdef /rad lry uly sub 2 div def - newpath tMatrix currentmatrix pop ulx rad add uly rad add translate - rad rad scale 0 0 1 90 270 arc tMatrix setmatrix lrx rad sub lry rad - sub translate rad rad scale 0 0 1 270 90 arc tMatrix setmatrix - closepath} bdef -/FlrRR {MlrRR stroke } bdef -/PlrRR {MlrRR fill } bdef -/MtbRR {/lry xdef /lrx xdef /uly xdef /ulx xdef /rad lrx ulx sub 2 div def - newpath tMatrix currentmatrix pop ulx rad add uly rad add translate - rad rad scale 0 0 1 180 360 arc tMatrix setmatrix lrx rad sub lry rad - sub translate rad rad scale 0 0 1 0 180 arc tMatrix setmatrix - closepath} bdef -/FtbRR {MtbRR stroke } bdef -/PtbRR {MtbRR fill } bdef -/stri 6 array def /dtri 6 array def -/smat 6 array def /dmat 6 array def -/tmat1 6 array def /tmat2 6 array def /dif 3 array def -/asub {/ind2 exch def /ind1 exch def dup dup - ind1 get exch ind2 get sub exch } bdef -/tri_to_matrix { - 2 0 asub 3 1 asub 4 0 asub 5 1 asub - dup 0 get exch 1 get 7 -1 roll astore } bdef -/compute_transform { - dmat dtri tri_to_matrix tmat1 invertmatrix - smat stri tri_to_matrix tmat2 concatmatrix } bdef -/ds {stri astore pop} bdef -/dt {dtri astore pop} bdef -/db {2 copy /cols xdef /rows xdef mul dup 3 mul string - currentfile - 3 index 0 eq {/ASCIIHexDecode filter} - {/ASCII85Decode filter 3 index 2 eq {/RunLengthDecode filter} if } - ifelse exch readstring pop - dup 0 3 index getinterval /rbmap xdef - dup 2 index dup getinterval /gbmap xdef - 1 index dup 2 mul exch getinterval /bbmap xdef pop pop}bdef -/it {gs np dtri aload pop moveto lineto lineto cp c - cols rows 8 compute_transform - rbmap gbmap bbmap true 3 colorimage gr}bdef -/il {newpath moveto lineto stroke}bdef -currentdict end def -%%EndProlog - -%%BeginSetup -MathWorks begin - -0 cap - -end -%%EndSetup - -%%Page: 1 1 -%%BeginPageSetup -%%PageBoundingBox: 59 211 550 580 -MathWorks begin -bpage -%%EndPageSetup - -%%BeginObject: obj1 -bplot - -/dpi2point 12 def -portraitMode 0708 6960 csm - - 0 0 5903 4424 rc -125 dict begin %Colortable dictionary -/c0 { 0.000000 0.000000 0.000000 sr} bdef -/c1 { 1.000000 1.000000 1.000000 sr} bdef -/c2 { 0.900000 0.000000 0.000000 sr} bdef -/c3 { 0.000000 0.820000 0.000000 sr} bdef -/c4 { 0.000000 0.000000 0.800000 sr} bdef -/c5 { 0.910000 0.820000 0.320000 sr} bdef -/c6 { 1.000000 0.260000 0.820000 sr} bdef -/c7 { 0.000000 0.820000 0.820000 sr} bdef -c0 -1 j -1 sg - 0 0 5904 4425 rf -6 w -0 3605 4575 0 0 -3605 767 3937 4 MP -PP --4575 0 0 3605 4575 0 0 -3605 767 3937 5 MP stroke -4 w -DO -SO -6 w -0 sg - 767 3937 mt 5342 3937 L - 767 332 mt 5342 332 L - 767 3937 mt 767 332 L -5342 3937 mt 5342 332 L - 767 3937 mt 5342 3937 L - 767 3937 mt 767 332 L - 767 3937 mt 767 3891 L - 767 332 mt 767 377 L -%%IncludeResource: font Helvetica -/Helvetica /ISOLatin1Encoding 120 FMSR - - 597 4082 mt -(-100) s -1338 3937 mt 1338 3891 L -1338 332 mt 1338 377 L -1202 4082 mt -(-50) s -1910 3937 mt 1910 3891 L -1910 332 mt 1910 377 L -1877 4082 mt -(0) s -2482 3937 mt 2482 3891 L -2482 332 mt 2482 377 L -2416 4082 mt -(50) s -3054 3937 mt 3054 3891 L -3054 332 mt 3054 377 L -2954 4082 mt -(100) s -3626 3937 mt 3626 3891 L -3626 332 mt 3626 377 L -3526 4082 mt -(150) s -4198 3937 mt 4198 3891 L -4198 332 mt 4198 377 L -4098 4082 mt -(200) s -4770 3937 mt 4770 3891 L -4770 332 mt 4770 377 L -4670 4082 mt -(250) s -5342 3937 mt 5342 3891 L -5342 332 mt 5342 377 L -5242 4082 mt -(300) s - 767 3937 mt 812 3937 L -5342 3937 mt 5296 3937 L - 666 3981 mt -(0) s - 767 3576 mt 812 3576 L -5342 3576 mt 5296 3576 L - 566 3620 mt -(0.1) s - 767 3216 mt 812 3216 L -5342 3216 mt 5296 3216 L - 566 3260 mt -(0.2) s - 767 2855 mt 812 2855 L -5342 2855 mt 5296 2855 L - 566 2899 mt -(0.3) s - 767 2495 mt 812 2495 L -5342 2495 mt 5296 2495 L - 566 2539 mt -(0.4) s - 767 2134 mt 812 2134 L -5342 2134 mt 5296 2134 L - 566 2178 mt -(0.5) s - 767 1773 mt 812 1773 L -5342 1773 mt 5296 1773 L - 566 1817 mt -(0.6) s - 767 1413 mt 812 1413 L -5342 1413 mt 5296 1413 L - 566 1457 mt -(0.7) s - 767 1053 mt 812 1053 L -5342 1053 mt 5296 1053 L - 566 1097 mt -(0.8) s - 767 692 mt 812 692 L -5342 692 mt 5296 692 L - 566 736 mt -(0.9) s - 767 332 mt 812 332 L -5342 332 mt 5296 332 L - 666 376 mt -(1) s - 767 3937 mt 5342 3937 L - 767 332 mt 5342 332 L - 767 3937 mt 767 332 L -5342 3937 mt 5342 332 L -gs 767 332 4576 3606 rc -gr - -gs 866 259 4198 3752 rc -24 W -/c8 { 0.000000 0.000000 1.000000 sr} bdef -c8 -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3869 PD -24 W -3008 3872 PD -24 W -3008 3877 PD -24 W -3008 3881 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3876 PD -24 W -3008 3881 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3876 PD -24 W -3008 3881 PD -24 W -3008 3869 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3876 PD -24 W -3008 3881 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3876 PD -24 W -3008 3881 PD -24 W -3008 3877 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3876 PD -24 W -3008 3881 PD -24 W -3008 3876 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3877 PD -24 W -3008 3881 PD -24 W -3008 3876 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3868 PD -24 W -3008 3872 PD -24 W -3008 3877 PD -24 W -3008 3881 PD -24 W -3008 3876 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3869 PD -24 W -3008 3872 PD -24 W -3008 3881 PD -24 W -3008 3876 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3869 PD -24 W -3008 3877 PD -24 W -3008 3822 PD -24 W -3008 3881 PD -24 W -3008 3876 PD -24 W -3008 3872 PD -24 W -3008 3868 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3872 PD -24 W -3008 3881 PD -24 W -3008 3814 PD -24 W -3008 3881 PD -24 W -3008 3877 PD -24 W -3008 3872 PD -24 W -3008 3869 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3868 PD -24 W -3008 3876 PD -24 W -3008 3803 PD -24 W -3008 3881 PD -24 W -3008 3877 PD -24 W -3008 3872 PD -24 W -3008 3869 PD -24 W -3008 3866 PD -24 W -3008 3864 PD -24 W -3008 3866 PD -24 W -3008 3871 PD -24 W -3008 3877 PD -24 W -3008 3798 PD -24 W -2996 3877 PD -24 W -2996 3872 PD -24 W -2996 3868 PD -24 W -2996 3866 PD -24 W -2996 3863 PD -24 W -2996 3865 PD -24 W -2996 3868 PD -24 W -2996 3879 PD -24 W -2996 3793 PD -24 W -2986 3881 PD -24 W -2986 3876 PD -24 W -2986 3871 PD -24 W -2986 3865 PD -24 W -2986 3863 PD -24 W -2986 3870 PD -24 W -2986 3877 PD -24 W -2986 3794 PD -24 W -2982 3877 PD -24 W -2982 3868 PD -24 W -2982 3863 PD -24 W -2982 3862 PD -24 W -2982 3865 PD -24 W -2982 3870 PD -24 W -2982 3873 PD -24 W -2968 3879 PD -24 W -2968 3870 PD -24 W -2968 3865 PD -24 W -2968 3862 PD -24 W -2968 3863 PD -24 W -2968 3864 PD -24 W -2968 3869 PD -24 W -2968 3873 PD -24 W -2968 3870 PD -24 W -2968 3877 PD -24 W -2968 3850 PD -24 W -2962 3877 PD -24 W -2962 3870 PD -24 W -2962 3863 PD -24 W -2962 3862 PD -24 W -2962 3861 PD -24 W -2962 3863 PD -24 W -2962 3864 PD -24 W -2962 3866 PD -24 W -2962 3864 PD -24 W -2962 3869 PD -24 W -2962 3868 PD -24 W -2962 3869 PD -24 W -2962 3871 PD -24 W -2962 3840 PD -24 W -2964 3873 PD -24 W -2964 3864 PD -24 W -2964 3861 PD -24 W -2964 3860 PD -24 W -2964 3861 PD -24 W -2964 3863 PD -24 W -2964 3861 PD -24 W -2964 3865 PD -24 W -2964 3864 PD -24 W -2964 3865 PD -24 W -2964 3864 PD -24 W -2964 3867 PD -24 W -2964 3835 PD -24 W -2961 3869 PD -24 W -2961 3863 PD -24 W -2961 3861 PD -24 W -2961 3860 PD -24 W -2961 3859 PD -24 W -2961 3858 PD -24 W -2961 3860 PD -24 W -2961 3859 PD -24 W -2961 3858 PD -24 W -2961 3860 PD -24 W -2961 3868 PD -24 W -2961 3828 PD -24 W -2969 3869 PD -24 W -2969 3864 PD -24 W -2969 3861 PD -24 W -2969 3859 PD -24 W -2969 3858 PD -24 W -2969 3857 PD -24 W -2969 3859 PD -24 W -2969 3858 PD -24 W -2969 3856 PD -24 W -2969 3858 PD -24 W -2969 3865 PD -24 W -2969 3826 PD -24 W -2972 3873 PD -24 W -2972 3866 PD -24 W -2972 3863 PD -24 W -2972 3859 PD -24 W -2972 3858 PD -24 W -2972 3857 PD -24 W -2972 3856 PD -24 W -2972 3855 PD -24 W -2972 3853 PD -24 W -2972 3854 PD -24 W -2972 3860 PD -24 W -2972 3866 PD -24 W -2972 3822 PD -24 W -2988 3870 PD -24 W -2988 3864 PD -24 W -2988 3861 PD -24 W -2988 3858 PD -24 W -2988 3857 PD -24 W -2988 3856 PD -24 W -2988 3855 PD -24 W -2988 3856 PD -24 W -2988 3855 PD -24 W -2988 3854 PD -24 W -2988 3853 PD -24 W -2988 3854 PD -24 W -2988 3861 PD -24 W -2988 3868 PD -24 W -2988 3821 PD -24 W -2986 3877 PD -24 W -2986 3869 PD -24 W -2986 3865 PD -24 W -2986 3860 PD -24 W -2986 3859 PD -24 W -2986 3856 PD -24 W -2986 3854 PD -24 W -2986 3853 PD -24 W -2986 3852 PD -24 W -2986 3850 PD -24 W -2986 3849 PD -24 W -2986 3853 PD -24 W -2986 3859 PD -24 W -2986 3861 PD -24 W -2986 3863 PD -24 W -2986 3818 PD -24 W -2996 3868 PD -24 W -2996 3864 PD -24 W -2996 3859 PD -24 W -2996 3858 PD -24 W -2996 3855 PD -24 W -2996 3853 PD -24 W -2996 3851 PD -24 W -2996 3850 PD -24 W -2996 3848 PD -24 W -2996 3852 PD -24 W -2996 3857 PD -24 W -2996 3859 PD -24 W -2996 3861 PD -24 W -2996 3856 PD -24 W -2996 3816 PD -24 W -3006 3869 PD -24 W -3006 3865 PD -24 W -3006 3859 PD -24 W -3006 3858 PD -24 W -3006 3855 PD -24 W -3006 3854 PD -24 W -3006 3852 PD -24 W -3006 3850 PD -24 W -3006 3849 PD -24 W -3006 3847 PD -24 W -3006 3846 PD -24 W -3006 3849 PD -24 W -3006 3854 PD -24 W -3006 3856 PD -24 W -3006 3858 PD -24 W -3006 3852 PD -24 W -3006 3814 PD -24 W -3015 3869 PD -24 W -3015 3864 PD -24 W -3015 3858 PD -24 W -3015 3856 PD -24 W -3015 3853 PD -24 W -3015 3850 PD -24 W -3015 3848 PD -24 W -3015 3847 PD -24 W -3015 3845 PD -24 W -3015 3844 PD -24 W -3015 3846 PD -24 W -3015 3851 PD -24 W -3015 3853 PD -24 W -3015 3855 PD -24 W -3015 3849 PD -24 W -3015 3812 PD -24 W -3023 3871 PD -24 W -3023 3867 PD -24 W -3023 3860 PD -24 W -3023 3858 PD -24 W -3023 3854 PD -24 W -3023 3849 PD -24 W -3023 3848 PD -24 W -3023 3846 PD -24 W -3023 3844 PD -24 W -3023 3842 PD -24 W -3023 3843 PD -24 W -3023 3847 PD -24 W -3023 3849 PD -24 W -3023 3850 PD -24 W -3023 3843 PD -24 W -3023 3810 PD -24 W -3015 3868 PD -24 W -3015 3865 PD -24 W -3015 3860 PD -24 W -3015 3861 PD -24 W -3015 3853 PD -24 W -3015 3852 PD -24 W -3015 3849 PD -24 W -3015 3846 PD -24 W -3015 3843 PD -24 W -3015 3839 PD -24 W -3015 3840 PD -24 W -3015 3848 PD -24 W -3015 3854 PD -24 W -3015 3831 PD -24 W -3015 3816 PD -24 W -3015 3866 PD -24 W -3015 3868 PD -24 W -3015 3859 PD -24 W -3015 3857 PD -24 W -3015 3854 PD -24 W -3015 3851 PD -24 W -3015 3847 PD -24 W -3015 3840 PD -24 W -3015 3838 PD -24 W -3015 3837 PD -24 W -3015 3835 PD -24 W -3015 3840 PD -24 W -3015 3845 PD -24 W -3015 3857 PD -24 W -3015 3825 PD -24 W -3015 3824 PD -24 W -3018 3861 PD -24 W -3018 3859 PD -24 W -3018 3856 PD -24 W -3018 3853 PD -24 W -3018 3849 PD -24 W -3018 3840 PD -24 W -3018 3837 PD -24 W -3018 3834 PD -24 W -3018 3833 PD -24 W -3018 3836 PD -24 W -3018 3839 PD -24 W -3018 3850 PD -24 W -3018 3821 PD -24 W -3018 3828 PD -24 W -3026 3863 PD -24 W -3026 3861 PD -24 W -3026 3858 PD -24 W -3026 3855 PD -24 W -3026 3850 PD -24 W -3026 3840 PD -24 W -3026 3835 PD -24 W -3026 3833 PD -24 W -3026 3830 PD -24 W -3026 3832 PD -24 W -3026 3835 PD -24 W -3026 3845 PD -24 W -3026 3818 PD -24 W -3026 3831 PD -24 W -3021 3848 PD -24 W -3021 3840 PD -24 W -3021 3836 PD -24 W -3021 3832 PD -24 W -3021 3828 PD -24 W -3021 3833 PD -24 W -3021 3819 PD -24 W -3022 3854 PD -24 W -3022 3845 PD -24 W -3022 3839 PD -24 W -3022 3835 PD -24 W -3022 3828 PD -24 W -3022 3826 PD -24 W -3022 3828 PD -24 W -3022 3821 PD -24 W -3016 3857 PD -24 W -3016 3850 PD -24 W -3016 3845 PD -24 W -3016 3833 PD -24 W -3016 3828 PD -24 W -3016 3824 PD -24 W -3016 3831 PD -24 W -3067 3856 PD -24 W -3067 3852 PD -24 W -3067 3849 PD -24 W -3067 3843 PD -24 W -3067 3831 PD -24 W -3067 3825 PD -24 W -3067 3821 PD -24 W -3067 3818 PD -24 W -3067 3819 PD -24 W -3067 3821 PD -24 W -3067 3831 PD -24 W -3067 3804 PD -24 W -3139 3850 PD -24 W -3139 3840 PD -24 W -3139 3835 PD -24 W -3139 3828 PD -24 W -3139 3826 PD -24 W -3139 3822 PD -24 W -3139 3821 PD -24 W -3139 3818 PD -24 W -3139 3816 PD -24 W -3139 3814 PD -24 W -3139 3812 PD -24 W -3139 3810 PD -24 W -3139 3816 PD -24 W -3139 3824 PD -24 W -3139 3828 PD -24 W -3139 3831 PD -24 W -3139 3762 PD -24 W -3269 3822 PD -24 W -3269 3814 PD -24 W -3269 3803 PD -24 W -3269 3798 PD -24 W -3269 3793 PD -24 W -3269 3794 PD -24 W -3269 3628 PD -24 W -3482 3165 PD -24 W -3817 1475 PD -24 W -4038 822 PD -24 W -4038 874 PD -24 W -4038 1011 PD -24 W -4038 1260 PD -24 W -4038 1558 PD -24 W -4043 874 PD -24 W -4043 836 PD -24 W -4043 881 PD -24 W -4043 1045 PD -24 W -4043 1289 PD -24 W -4042 1011 PD -24 W -4042 881 PD -24 W -4042 813 PD -24 W -4042 860 PD -24 W -4042 1019 PD -24 W -4042 1251 PD -24 W -4042 1477 PD -24 W -4039 1260 PD -24 W -4039 1045 PD -24 W -4039 860 PD -24 W -4039 770 PD -24 W -4039 818 PD -24 W -4039 960 PD -24 W -4039 1124 PD -24 W -4039 1439 PD -24 W -4039 1558 PD -24 W -4039 1289 PD -24 W -4039 1019 PD -24 W -4039 818 PD -24 W -4039 762 PD -24 W -4039 807 PD -24 W -4039 902 PD -24 W -4039 1138 PD -24 W -4039 1364 PD -24 W -4040 1251 PD -24 W -4040 960 PD -24 W -4040 807 PD -24 W -4040 752 PD -24 W -4040 773 PD -24 W -4040 911 PD -24 W -4040 1085 PD -24 W -4040 1245 PD -24 W -4040 1490 PD -24 W -4038 1477 PD -24 W -4038 1124 PD -24 W -4038 902 PD -24 W -4038 773 PD -24 W -4038 721 PD -24 W -4038 769 PD -24 W -4038 903 PD -24 W -4038 1027 PD -24 W -4038 1229 PD -24 W -4038 1487 PD -24 W -4034 1439 PD -24 W -4034 1138 PD -24 W -4034 911 PD -24 W -4034 769 PD -24 W -4034 681 PD -24 W -4034 734 PD -24 W -4034 796 PD -24 W -4034 921 PD -24 W -4034 1128 PD -24 W -4034 1308 PD -24 W -4041 1364 PD -24 W -4041 1085 PD -24 W -4041 903 PD -24 W -4041 734 PD -24 W -4041 715 PD -24 W -4041 733 PD -24 W -4041 809 PD -24 W -4041 954 PD -24 W -4041 1102 PD -24 W -4041 1291 PD -24 W -4044 1245 PD -24 W -4044 1027 PD -24 W -4044 796 PD -24 W -4044 733 PD -24 W -4044 713 PD -24 W -4044 736 PD -24 W -4044 839 PD -24 W -4044 957 PD -24 W -4044 1117 PD -24 W -4044 1327 PD -24 W -4039 1490 PD -24 W -4039 1229 PD -24 W -4039 921 PD -24 W -4039 809 PD -24 W -4039 736 PD -24 W -4039 680 PD -24 W -4039 727 PD -24 W -4039 796 PD -24 W -4039 905 PD -24 W -4039 1072 PD -24 W -4039 1269 PD -24 W -4044 1487 PD -24 W -4044 1128 PD -24 W -4044 954 PD -24 W -4044 839 PD -24 W -4044 727 PD -24 W -4044 693 PD -24 W -4044 711 PD -24 W -4044 771 PD -24 W -4044 892 PD -24 W -4044 1052 PD -24 W -4044 1248 PD -24 W -4044 1436 PD -24 W -4046 1308 PD -24 W -4046 1102 PD -24 W -4046 957 PD -24 W -4046 796 PD -24 W -4046 711 PD -24 W -4046 686 PD -24 W -4046 701 PD -24 W -4046 777 PD -24 W -4046 899 PD -24 W -4046 1064 PD -24 W -4046 1231 PD -24 W -4044 1291 PD -24 W -4044 1117 PD -24 W -4044 905 PD -24 W -4044 771 PD -24 W -4044 701 PD -24 W -4044 663 PD -24 W -4044 685 PD -24 W -4044 757 PD -24 W -4044 880 PD -24 W -4044 1020 PD -24 W -4044 1232 PD -24 W -4044 1418 PD -24 W -4042 1327 PD -24 W -4042 1072 PD -24 W -4042 892 PD -24 W -4042 777 PD -24 W -4042 685 PD -24 W -4042 648 PD -24 W -4042 664 PD -24 W -4042 737 PD -24 W -4042 840 PD -24 W -4042 1010 PD -24 W -4042 1174 PD -24 W -4042 1335 PD -24 W -4040 1269 PD -24 W -4040 1052 PD -24 W -4040 899 PD -24 W -4040 757 PD -24 W -4040 664 PD -24 W -4040 622 PD -24 W -4040 642 PD -24 W -4040 704 PD -24 W -4040 824 PD -24 W -4040 958 PD -24 W -4040 1100 PD -24 W -4040 1211 PD -24 W -4040 1347 PD -24 W -4038 1248 PD -24 W -4038 1064 PD -24 W -4038 880 PD -24 W -4038 737 PD -24 W -4038 642 PD -24 W -4038 609 PD -24 W -4038 626 PD -24 W -4038 693 PD -24 W -4038 791 PD -24 W -4038 908 PD -24 W -4038 1007 PD -24 W -4038 1120 PD -24 W -4038 1347 PD -24 W -4040 1436 PD -24 W -4040 1231 PD -24 W -4040 1020 PD -24 W -4040 840 PD -24 W -4040 704 PD -24 W -4040 626 PD -24 W -4040 604 PD -24 W -4040 622 PD -24 W -4040 685 PD -24 W -4040 774 PD -24 W -4040 856 PD -24 W -4040 951 PD -24 W -4040 1150 PD -24 W -4040 1309 PD -24 W -4035 1232 PD -24 W -4035 1010 PD -24 W -4035 824 PD -24 W -4035 693 PD -24 W -4035 622 PD -24 W -4035 574 PD -24 W -4035 589 PD -24 W -4035 641 PD -24 W -4035 704 PD -24 W -4035 763 PD -24 W -4035 919 PD -24 W -4035 1058 PD -24 W -4035 1159 PD -24 W -4035 1347 PD -24 W -4036 1418 PD -24 W -4036 1174 PD -24 W -4036 958 PD -24 W -4036 791 PD -24 W -4036 685 PD -24 W -4036 589 PD -24 W -4036 566 PD -24 W -4036 586 PD -24 W -4036 630 PD -24 W -4036 662 PD -24 W -4036 779 PD -24 W -4036 896 PD -24 W -4036 982 PD -24 W -4036 1152 PD -24 W -4036 1278 PD -24 W -4040 1335 PD -24 W -4040 1100 PD -24 W -4040 908 PD -24 W -4040 774 PD -24 W -4040 641 PD -24 W -4040 586 PD -24 W -4040 577 PD -24 W -4040 599 PD -24 W -4040 611 PD -24 W -4040 690 PD -24 W -4040 783 PD -24 W -4040 858 PD -24 W -4040 1006 PD -24 W -4040 1119 PD -24 W -4040 1234 PD -24 W -4049 1211 PD -24 W -4049 1007 PD -24 W -4049 856 PD -24 W -4049 704 PD -24 W -4049 630 PD -24 W -4049 599 PD -24 W -4049 601 PD -24 W -4049 608 PD -24 W -4049 662 PD -24 W -4049 735 PD -24 W -4049 806 PD -24 W -4049 935 PD -24 W -4049 1033 PD -24 W -4049 1146 PD -24 W -4049 1293 PD -24 W -4046 1347 PD -24 W -4046 1120 PD -24 W -4046 951 PD -24 W -4046 763 PD -24 W -4046 662 PD -24 W -4046 611 PD -24 W -4046 608 PD -24 W -4046 577 PD -24 W -4046 595 PD -24 W -4046 652 PD -24 W -4046 699 PD -24 W -4046 809 PD -24 W -4046 904 PD -24 W -4046 997 PD -24 W -4046 1138 PD -24 W -4046 1278 PD -24 W -4042 1347 PD -24 W -4042 1150 PD -24 W -4042 919 PD -24 W -4042 779 PD -24 W -4042 690 PD -24 W -4042 662 PD -24 W -4042 595 PD -24 W -4042 553 PD -24 W -4042 571 PD -24 W -4042 591 PD -24 W -4042 659 PD -24 W -4042 731 PD -24 W -4042 799 PD -24 W -4042 916 PD -24 W -4042 1035 PD -24 W -4042 1194 PD -24 W -4042 1356 PD -24 W -4046 1309 PD -24 W -4046 1058 PD -24 W -4046 896 PD -24 W -4046 783 PD -24 W -4046 735 PD -24 W -4046 652 PD -24 W -4046 571 PD -24 W -4046 561 PD -24 W -4046 566 PD -24 W -4046 603 PD -24 W -4046 652 PD -24 W -4046 707 PD -24 W -4046 801 PD -24 W -4046 906 PD -24 W -4046 1047 PD -24 W -4046 1200 PD -24 W -4046 1159 PD -24 W -4046 982 PD -24 W -4046 858 PD -24 W -4046 806 PD -24 W -4046 699 PD -24 W -4046 591 PD -24 W -4046 566 PD -24 W -4046 551 PD -24 W -4046 569 PD -24 W -4046 611 PD -24 W -4046 645 PD -24 W -4046 728 PD -24 W -4046 813 PD -24 W -4046 943 PD -24 W -4046 1079 PD -24 W -4046 1257 PD -24 W -4047 1347 PD -24 W -4047 1152 PD -24 W -4047 1006 PD -24 W -4047 935 PD -24 W -4047 809 PD -24 W -4047 659 PD -24 W -4047 603 PD -24 W -4047 569 PD -24 W -4047 548 PD -24 W -4047 565 PD -24 W -4047 578 PD -24 W -4047 630 PD -24 W -4047 693 PD -24 W -4047 796 PD -24 W -4047 912 PD -24 W -4047 1074 PD -24 W -4047 1254 PD -24 W -4054 1278 PD -24 W -4054 1119 PD -24 W -4054 1033 PD -24 W -4054 904 PD -24 W -4054 731 PD -24 W -4054 652 PD -24 W -4054 611 PD -24 W -4054 565 PD -24 W -4054 559 PD -24 W -4054 564 PD -24 W -4054 592 PD -24 W -4054 646 PD -24 W -4054 726 PD -24 W -4054 833 PD -24 W -4054 987 PD -24 W -4054 1149 PD -24 W -4054 1325 PD -24 W -4053 1234 PD -24 W -4053 1146 PD -24 W -4053 997 PD -24 W -4053 799 PD -24 W -4053 707 PD -24 W -4053 645 PD -24 W -4053 578 PD -24 W -4053 564 PD -24 W -4053 545 PD -24 W -4053 559 PD -24 W -4053 585 PD -24 W -4053 649 PD -24 W -4053 732 PD -24 W -4053 861 PD -24 W -4053 1012 PD -24 W -4053 1174 PD -24 W -4053 1315 PD -24 W -4056 1293 PD -24 W -4056 1138 PD -24 W -4056 916 PD -24 W -4056 801 PD -24 W -4056 728 PD -24 W -4056 630 PD -24 W -4056 592 PD -24 W -4056 559 PD -24 W -4056 543 PD -24 W -4056 552 PD -24 W -4056 586 PD -24 W -4056 651 PD -24 W -4056 762 PD -24 W -4056 887 PD -24 W -4056 1037 PD -24 W -4056 1161 PD -24 W -4056 1288 PD -24 W -4053 1278 PD -24 W -4053 1035 PD -24 W -4053 906 PD -24 W -4053 813 PD -24 W -4053 693 PD -24 W -4053 646 PD -24 W -4053 585 PD -24 W -4053 552 PD -24 W -4053 530 PD -24 W -4053 542 PD -24 W -4053 574 PD -24 W -4053 652 PD -24 W -4053 758 PD -24 W -4053 885 PD -24 W -4053 1003 PD -24 W -4053 1119 PD -24 W -4053 1267 PD -24 W -4054 1194 PD -24 W -4054 1047 PD -24 W -4054 943 PD -24 W -4054 796 PD -24 W -4054 726 PD -24 W -4054 649 PD -24 W -4054 586 PD -24 W -4054 542 PD -24 W -4054 521 PD -24 W -4054 528 PD -24 W -4054 580 PD -24 W -4054 652 PD -24 W -4054 759 PD -24 W -4054 854 PD -24 W -4054 960 PD -24 W -4054 1098 PD -24 W -4054 1173 PD -24 W -4049 1356 PD -24 W -4049 1200 PD -24 W -4049 1079 PD -24 W -4049 912 PD -24 W -4049 833 PD -24 W -4049 732 PD -24 W -4049 651 PD -24 W -4049 574 PD -24 W -4049 528 PD -24 W -4049 499 PD -24 W -4049 511 PD -24 W -4049 558 PD -24 W -4049 633 PD -24 W -4049 716 PD -24 W -4049 803 PD -24 W -4049 922 PD -24 W -4049 998 PD -24 W -4049 1136 PD -24 W -4049 1276 PD -24 W -4043 1257 PD -24 W -4043 1074 PD -24 W -4043 987 PD -24 W -4043 861 PD -24 W -4043 762 PD -24 W -4043 652 PD -24 W -4043 580 PD -24 W -4043 511 PD -24 W -4043 480 PD -24 W -4043 495 PD -24 W -4043 533 PD -24 W -4043 599 PD -24 W -4043 663 PD -24 W -4043 757 PD -24 W -4043 833 PD -24 W -4043 950 PD -24 W -4043 1074 PD -24 W -4043 1238 PD -24 W -4042 1254 PD -24 W -4042 1149 PD -24 W -4042 1012 PD -24 W -4042 887 PD -24 W -4042 758 PD -24 W -4042 652 PD -24 W -4042 558 PD -24 W -4042 495 PD -24 W -4042 467 PD -24 W -4042 476 PD -24 W -4042 508 PD -24 W -4042 554 PD -24 W -4042 626 PD -24 W -4042 681 PD -24 W -4042 780 PD -24 W -4042 890 PD -24 W -4042 1038 PD -24 W -4042 1122 PD -24 W -4042 1263 PD -24 W -4037 1325 PD -24 W -4037 1174 PD -24 W -4037 1037 PD -24 W -4037 885 PD -24 W -4037 759 PD -24 W -4037 633 PD -24 W -4037 533 PD -24 W -4037 476 PD -24 W -4037 448 PD -24 W -4037 462 PD -24 W -4037 483 PD -24 W -4037 527 PD -24 W -4037 578 PD -24 W -4037 652 PD -24 W -4037 741 PD -24 W -4037 868 PD -24 W -4037 951 PD -24 W -4037 1078 PD -24 W -4037 1203 PD -24 W -4040 1315 PD -24 W -4040 1161 PD -24 W -4040 1003 PD -24 W -4040 854 PD -24 W -4040 716 PD -24 W -4040 599 PD -24 W -4040 508 PD -24 W -4040 462 PD -24 W -4040 446 PD -24 W -4040 453 PD -24 W -4040 481 PD -24 W -4040 508 PD -24 W -4040 566 PD -24 W -4040 642 PD -24 W -4040 754 PD -24 W -4040 819 PD -24 W -4040 937 PD -24 W -4040 1054 PD -24 W -4040 1195 PD -24 W -4040 1288 PD -24 W -4040 1119 PD -24 W -4040 960 PD -24 W -4040 803 PD -24 W -4040 663 PD -24 W -4040 554 PD -24 W -4040 483 PD -24 W -4040 453 PD -24 W -4040 443 PD -24 W -4040 449 PD -24 W -4040 472 PD -24 W -4040 510 PD -24 W -4040 569 PD -24 W -4040 662 PD -24 W -4040 724 PD -24 W -4040 828 PD -24 W -4040 935 PD -24 W -4040 1067 PD -24 W -4040 1181 PD -24 W -4038 1267 PD -24 W -4038 1098 PD -24 W -4038 922 PD -24 W -4038 757 PD -24 W -4038 626 PD -24 W -4038 527 PD -24 W -4038 481 PD -24 W -4038 449 PD -24 W -4038 431 PD -24 W -4038 446 PD -24 W -4038 460 PD -24 W -4038 497 PD -24 W -4038 566 PD -24 W -4038 623 PD -24 W -4038 709 PD -24 W -4038 802 PD -24 W -4038 920 PD -24 W -4038 1024 PD -24 W -4038 1200 PD -24 W -4046 1173 PD -24 W -4046 998 PD -24 W -4046 833 PD -24 W -4046 681 PD -24 W -4046 578 PD -24 W -4046 508 PD -24 W -4046 472 PD -24 W -4046 446 PD -24 W -4046 438 PD -24 W -4046 444 PD -24 W -4046 475 PD -24 W -4046 536 PD -24 W -4046 571 PD -24 W -4046 651 PD -24 W -4046 739 PD -24 W -4046 851 PD -24 W -4046 952 PD -24 W -4046 1123 PD -24 W -4043 1136 PD -24 W -4043 950 PD -24 W -4043 780 PD -24 W -4043 652 PD -24 W -4043 566 PD -24 W -4043 510 PD -24 W -4043 460 PD -24 W -4043 444 PD -24 W -4043 425 PD -24 W -4043 433 PD -24 W -4043 467 PD -24 W -4043 495 PD -24 W -4043 555 PD -24 W -4043 626 PD -24 W -4043 721 PD -24 W -4043 809 PD -24 W -4043 964 PD -24 W -4043 1129 PD -24 W -4043 1191 PD -24 W -4042 1276 PD -24 W -4042 1074 PD -24 W -4042 890 PD -24 W -4042 741 PD -24 W -4042 642 PD -24 W -4042 569 PD -24 W -4042 497 PD -24 W -4042 475 PD -24 W -4042 433 PD -24 W -4042 420 PD -24 W -4042 429 PD -24 W -4042 451 PD -24 W -4042 490 PD -24 W -4042 545 PD -24 W -4042 622 PD -24 W -4042 698 PD -24 W -4042 835 PD -24 W -4042 986 PD -24 W -4042 1049 PD -24 W -4042 1153 PD -24 W -4042 1224 PD -24 W -4038 1238 PD -24 W -4038 1038 PD -24 W -4038 868 PD -24 W -4038 754 PD -24 W -4038 662 PD -24 W -4038 566 PD -24 W -4038 536 PD -24 W -4038 467 PD -24 W -4038 429 PD -24 W -4038 406 PD -24 W -4038 419 PD -24 W -4038 433 PD -24 W -4038 466 PD -24 W -4038 521 PD -24 W -4038 579 PD -24 W -4038 693 PD -24 W -4038 825 PD -24 W -4038 886 PD -24 W -4038 980 PD -24 W -4038 1046 PD -24 W -4038 1163 PD -24 W -4045 1122 PD -24 W -4045 951 PD -24 W -4045 819 PD -24 W -4045 724 PD -24 W -4045 623 PD -24 W -4045 571 PD -24 W -4045 495 PD -24 W -4045 451 PD -24 W -4045 419 PD -24 W -4045 410 PD -24 W -4045 416 PD -24 W -4045 442 PD -24 W -4045 488 PD -24 W -4045 540 PD -24 W -4045 643 PD -24 W -4045 766 PD -24 W -4045 810 PD -24 W -4045 900 PD -24 W -4045 963 PD -24 W -4045 1075 PD -24 W -4045 1248 PD -24 W -4043 1263 PD -24 W -4043 1078 PD -24 W -4043 937 PD -24 W -4043 828 PD -24 W -4043 709 PD -24 W -4043 651 PD -24 W -4043 555 PD -24 W -4043 490 PD -24 W -4043 433 PD -24 W -4043 416 PD -24 W -4043 400 PD -24 W -4043 407 PD -24 W -4043 432 PD -24 W -4043 468 PD -24 W -4043 548 PD -24 W -4043 651 PD -24 W -4043 692 PD -24 W -4043 771 PD -24 W -4043 828 PD -24 W -4043 931 PD -24 W -4043 1093 PD -24 W -4043 1222 PD -24 W -4043 1203 PD -24 W -4043 1054 PD -24 W -4043 935 PD -24 W -4043 802 PD -24 W -4043 739 PD -24 W -4043 626 PD -24 W -4043 545 PD -24 W -4043 466 PD -24 W -4043 442 PD -24 W -4043 407 PD -24 W -4043 397 PD -24 W -4043 403 PD -24 W -4043 424 PD -24 W -4043 482 PD -24 W -4043 567 PD -24 W -4043 604 PD -24 W -4043 673 PD -24 W -4043 724 PD -24 W -4043 817 PD -24 W -4043 966 PD -24 W -4043 1089 PD -24 W -4043 1209 PD -24 W -4042 1195 PD -24 W -4042 1067 PD -24 W -4042 920 PD -24 W -4042 851 PD -24 W -4042 721 PD -24 W -4042 622 PD -24 W -4042 521 PD -24 W -4042 488 PD -24 W -4042 432 PD -24 W -4042 403 PD -24 W -4042 388 PD -24 W -4042 392 PD -24 W -4042 424 PD -24 W -4042 486 PD -24 W -4042 518 PD -24 W -4042 574 PD -24 W -4042 617 PD -24 W -4042 697 PD -24 W -4042 831 PD -24 W -4042 943 PD -24 W -4042 1056 PD -24 W -4042 1215 PD -24 W -4043 1181 PD -24 W -4043 1024 PD -24 W -4043 952 PD -24 W -4043 809 PD -24 W -4043 698 PD -24 W -4043 579 PD -24 W -4043 540 PD -24 W -4043 468 PD -24 W -4043 424 PD -24 W -4043 392 PD -24 W -4043 382 PD -24 W -4043 393 PD -24 W -4043 435 PD -24 W -4043 463 PD -24 W -4043 509 PD -24 W -4043 545 PD -24 W -4043 614 PD -24 W -4043 733 PD -24 W -4043 836 PD -24 W -4043 942 PD -24 W -4043 1092 PD -24 W -4043 1189 PD -24 W -4038 1200 PD -24 W -4038 1123 PD -24 W -4038 964 PD -24 W -4038 835 PD -24 W -4038 693 PD -24 W -4038 643 PD -24 W -4038 548 PD -24 W -4038 482 PD -24 W -4038 424 PD -24 W -4038 393 PD -24 W -4038 370 PD -24 W -4038 382 PD -24 W -4038 402 PD -24 W -4038 429 PD -24 W -4038 453 PD -24 W -4038 503 PD -24 W -4038 598 PD -24 W -4038 685 PD -24 W -4038 777 PD -24 W -4038 911 PD -24 W -4038 1000 PD -24 W -4038 1122 PD -24 W -4035 1129 PD -24 W -4035 986 PD -24 W -4035 825 PD -24 W -4035 766 PD -24 W -4035 651 PD -24 W -4035 567 PD -24 W -4035 486 PD -24 W -4035 435 PD -24 W -4035 382 PD -24 W -4035 364 PD -24 W -4035 376 PD -24 W -4035 385 PD -24 W -4035 398 PD -24 W -4035 429 PD -24 W -4035 497 PD -24 W -4035 567 PD -24 W -4035 643 PD -24 W -4035 760 PD -24 W -4035 840 PD -24 W -4035 951 PD -24 W -4035 1099 PD -24 W -4035 1173 PD -24 W -4042 1191 PD -24 W -4042 1049 PD -24 W -4042 886 PD -24 W -4042 810 PD -24 W -4042 692 PD -24 W -4042 604 PD -24 W -4042 518 PD -24 W -4042 463 PD -24 W -4042 402 PD -24 W -4042 376 PD -24 W -4042 366 PD -24 W -4042 369 PD -24 W -4042 378 PD -24 W -4042 403 PD -24 W -4042 463 PD -24 W -4042 526 PD -24 W -4042 596 PD -24 W -4042 706 PD -24 W -4042 781 PD -24 W -4042 887 PD -24 W -4042 1029 PD -24 W -4042 1101 PD -24 W -4042 1194 PD -24 W -4044 1153 PD -24 W -4044 980 PD -24 W -4044 900 PD -24 W -4044 771 PD -24 W -4044 673 PD -24 W -4044 574 PD -24 W -4044 509 PD -24 W -4044 429 PD -24 W -4044 385 PD -24 W -4044 369 PD -24 W -4044 362 PD -24 W -4044 363 PD -24 W -4044 376 PD -24 W -4044 418 PD -24 W -4044 469 PD -24 W -4044 529 PD -24 W -4044 625 PD -24 W -4044 694 PD -24 W -4044 791 PD -24 W -4044 925 PD -24 W -4044 993 PD -24 W -4044 1083 PD -24 W -4049 1224 PD -24 W -4049 1046 PD -24 W -4049 963 PD -24 W -4049 828 PD -24 W -4049 724 PD -24 W -4049 617 PD -24 W -4049 545 PD -24 W -4049 453 PD -24 W -4049 398 PD -24 W -4049 378 PD -24 W -4049 363 PD -24 W -4049 360 PD -24 W -4049 365 PD -24 W -4049 395 PD -24 W -4049 438 PD -24 W -4049 490 PD -24 W -4049 578 PD -24 W -4049 641 PD -24 W -4049 733 PD -24 W -4049 860 PD -24 W -4049 926 PD -24 W -4049 1012 PD -24 W -4050 1163 PD -24 W -4050 1075 PD -24 W -4050 931 PD -24 W -4050 817 PD -24 W -4050 697 PD -24 W -4050 614 PD -24 W -4050 503 PD -24 W -4050 429 PD -24 W -4050 403 PD -24 W -4050 376 PD -24 W -4050 365 PD -24 W -4050 355 PD -24 W -4050 365 PD -24 W -4050 394 PD -24 W -4050 433 PD -24 W -4050 505 PD -24 W -4050 559 PD -24 W -4050 640 PD -24 W -4050 755 PD -24 W -4050 816 PD -24 W -4050 897 PD -24 W -4050 1114 PD -24 W -4046 1248 PD -24 W -4046 1093 PD -24 W -4046 966 PD -24 W -4046 831 PD -24 W -4046 733 PD -24 W -4046 598 PD -24 W -4046 497 PD -24 W -4046 463 PD -24 W -4046 418 PD -24 W -4046 395 PD -24 W -4046 365 PD -24 W -4046 346 PD -24 W -4046 354 PD -24 W -4046 374 PD -24 W -4046 420 PD -24 W -4046 460 PD -24 W -4046 524 PD -24 W -4046 620 PD -24 W -4046 673 PD -24 W -4046 744 PD -24 W -4046 940 PD -24 W -4046 1153 PD -24 W -4046 1222 PD -24 W -4046 1089 PD -24 W -4046 943 PD -24 W -4046 836 PD -24 W -4046 685 PD -24 W -4046 567 PD -24 W -4046 526 PD -24 W -4046 469 PD -24 W -4046 438 PD -24 W -4046 394 PD -24 W -4046 354 PD -24 W -4046 346 PD -24 W -4046 351 PD -24 W -4046 378 PD -24 W -4046 408 PD -24 W -4046 457 PD -24 W -4046 537 PD -24 W -4046 583 PD -24 W -4046 647 PD -24 W -4046 825 PD -24 W -4046 1025 PD -24 W -4046 1147 PD -24 W -4047 1209 PD -24 W -4047 1056 PD -24 W -4047 942 PD -24 W -4047 777 PD -24 W -4047 643 PD -24 W -4047 596 PD -24 W -4047 529 PD -24 W -4047 490 PD -24 W -4047 433 PD -24 W -4047 374 PD -24 W -4047 351 PD -24 W -4047 342 PD -24 W -4047 351 PD -24 W -4047 369 PD -24 W -4047 406 PD -24 W -4047 470 PD -24 W -4047 509 PD -24 W -4047 564 PD -24 W -4047 724 PD -24 W -4047 908 PD -24 W -4047 1025 PD -24 W -4047 1147 PD -24 W -4044 1215 PD -24 W -4044 1092 PD -24 W -4044 911 PD -24 W -4044 760 PD -24 W -4044 706 PD -24 W -4044 625 PD -24 W -4044 578 PD -24 W -4044 505 PD -24 W -4044 420 PD -24 W -4044 378 PD -24 W -4044 351 PD -24 W -4044 336 PD -24 W -4044 340 PD -24 W -4044 358 PD -24 W -4044 400 PD -24 W -4044 429 PD -24 W -4044 472 PD -24 W -4044 605 PD -24 W -4044 767 PD -24 W -4044 873 PD -24 W -4044 987 PD -24 W -4044 1108 PD -24 W -4047 1189 PD -24 W -4047 1000 PD -24 W -4047 840 PD -24 W -4047 781 PD -24 W -4047 694 PD -24 W -4047 641 PD -24 W -4047 559 PD -24 W -4047 460 PD -24 W -4047 408 PD -24 W -4047 369 PD -24 W -4047 340 PD -24 W -4047 335 PD -24 W -4047 342 PD -24 W -4047 370 PD -24 W -4047 393 PD -24 W -4047 428 PD -24 W -4047 544 PD -24 W -4047 691 PD -24 W -4047 790 PD -24 W -4047 897 PD -24 W -4047 1013 PD -24 W -4047 1135 PD -24 W -4048 1122 PD -24 W -4048 951 PD -24 W -4048 887 PD -24 W -4048 791 PD -24 W -4048 733 PD -24 W -4048 640 PD -24 W -4048 524 PD -24 W -4048 457 PD -24 W -4048 406 PD -24 W -4048 358 PD -24 W -4048 342 PD -24 W -4048 334 PD -24 W -4048 344 PD -24 W -4048 358 PD -24 W -4048 383 PD -24 W -4048 476 PD -24 W -4048 602 PD -24 W -4048 690 PD -24 W -4048 788 PD -24 W -4048 896 PD -24 W -4048 1012 PD -24 W -4046 1099 PD -24 W -4046 1029 PD -24 W -4046 925 PD -24 W -4046 860 PD -24 W -4046 755 PD -24 W -4046 620 PD -24 W -4046 537 PD -24 W -4046 470 PD -24 W -4046 400 PD -24 W -4046 370 PD -24 W -4046 344 PD -24 W -4046 332 PD -24 W -4046 336 PD -24 W -4046 347 PD -24 W -4046 410 PD -24 W -4046 507 PD -24 W -4046 581 PD -24 W -4046 667 PD -24 W -4046 763 PD -24 W -4046 868 PD -24 W -4046 1109 PD -24 W -4051 1173 PD -24 W -4051 1101 PD -24 W -4051 993 PD -24 W -4051 926 PD -24 W -4051 816 PD -24 W -4051 673 PD -24 W -4051 583 PD -24 W -4051 509 PD -24 W -4051 429 PD -24 W -4051 393 PD -24 W -4051 358 PD -24 W -4051 336 PD -24 W -4051 335 PD -24 W -4051 340 PD -24 W -4051 389 PD -24 W -4051 472 PD -24 W -4051 539 PD -24 W -4051 617 PD -24 W -4051 707 PD -24 W -4051 807 PD -24 W -4051 1039 PD -24 W -4055 1194 PD -24 W -4055 1083 PD -24 W -4055 1012 PD -24 W -4055 897 PD -24 W -4055 744 PD -24 W -4055 647 PD -24 W -4055 564 PD -24 W -4055 472 PD -24 W -4055 428 PD -24 W -4055 383 PD -24 W -4055 347 PD -24 W -4055 340 PD -24 W -4055 338 PD -24 W -4055 369 PD -24 W -4055 434 PD -24 W -4055 491 PD -24 W -4055 561 PD -24 W -4055 643 PD -24 W -4055 735 PD -24 W -4055 955 PD -24 W -4055 1156 PD -24 W -4048 1114 PD -24 W -4048 940 PD -24 W -4048 825 PD -24 W -4048 724 PD -24 W -4048 605 PD -24 W -4048 544 PD -24 W -4048 476 PD -24 W -4048 410 PD -24 W -4048 389 PD -24 W -4048 369 PD -24 W -4048 337 PD -24 W -4048 360 PD -24 W -4048 395 PD -24 W -4048 444 PD -24 W -4048 507 PD -24 W -4048 582 PD -24 W -4048 757 PD -24 W -4048 939 PD -24 W -4048 1135 PD -24 W -4048 1224 PD -24 W -4041 1153 PD -24 W -4041 1025 PD -24 W -4041 908 PD -24 W -4041 767 PD -24 W -4041 691 PD -24 W -4041 602 PD -24 W -4041 507 PD -24 W -4041 472 PD -24 W -4041 434 PD -24 W -4041 360 PD -24 W -4041 336 PD -24 W -4041 345 PD -24 W -4041 369 PD -24 W -4041 408 PD -24 W -4041 460 PD -24 W -4041 595 PD -24 W -4041 747 PD -24 W -4041 919 PD -24 W -4041 1001 PD -24 W -4041 1205 PD -24 W -4042 1147 PD -24 W -4042 1025 PD -24 W -4042 873 PD -24 W -4042 790 PD -24 W -4042 690 PD -24 W -4042 581 PD -24 W -4042 539 PD -24 W -4042 491 PD -24 W -4042 395 PD -24 W -4042 345 PD -24 W -4042 340 PD -24 W -4042 350 PD -24 W -4042 374 PD -24 W -4042 413 PD -24 W -4042 523 PD -24 W -4042 655 PD -24 W -4042 812 PD -24 W -4042 888 PD -24 W -4042 1083 PD -24 W -4042 1222 PD -24 W -4042 1147 PD -24 W -4042 987 PD -24 W -4042 897 PD -24 W -4042 788 PD -24 W -4042 667 PD -24 W -4042 617 PD -24 W -4042 561 PD -24 W -4042 444 PD -24 W -4042 369 PD -24 W -4042 350 PD -24 W -4042 345 PD -24 W -4042 355 PD -24 W -4042 379 PD -24 W -4042 465 PD -24 W -4042 576 PD -24 W -4042 714 PD -24 W -4042 784 PD -24 W -4042 967 PD -24 W -4042 1099 PD -24 W -4042 1210 PD -24 W -4043 1108 PD -24 W -4043 1013 PD -24 W -4043 896 PD -24 W -4043 763 PD -24 W -4043 707 PD -24 W -4043 643 PD -24 W -4043 507 PD -24 W -4043 408 PD -24 W -4043 374 PD -24 W -4043 355 PD -24 W -4043 350 PD -24 W -4043 361 PD -24 W -4043 420 PD -24 W -4043 508 PD -24 W -4043 628 PD -24 W -4043 691 PD -24 W -4043 860 PD -24 W -4043 983 PD -24 W -4043 1088 PD -24 W -4044 1135 PD -24 W -4044 1012 PD -24 W -4044 868 PD -24 W -4044 807 PD -24 W -4044 735 PD -24 W -4044 582 PD -24 W -4044 460 PD -24 W -4044 413 PD -24 W -4044 379 PD -24 W -4044 361 PD -24 W -4044 356 PD -24 W -4044 389 PD -24 W -4044 454 PD -24 W -4044 553 PD -24 W -4044 608 PD -24 W -4044 762 PD -24 W -4044 875 PD -24 W -4044 974 PD -24 W -4044 1190 PD -24 W -4037 1109 PD -24 W -4037 1039 PD -24 W -4037 955 PD -24 W -4037 757 PD -24 W -4037 595 PD -24 W -4037 523 PD -24 W -4037 465 PD -24 W -4037 420 PD -24 W -4037 389 PD -24 W -4037 355 PD -24 W -4037 376 PD -24 W -4037 436 PD -24 W -4037 476 PD -24 W -4037 582 PD -24 W -4037 676 PD -24 W -4037 762 PD -24 W -4037 945 PD -24 W -4037 1074 PD -24 W -4037 1174 PD -24 W -4030 1156 PD -24 W -4030 939 PD -24 W -4030 747 PD -24 W -4030 655 PD -24 W -4030 576 PD -24 W -4030 508 PD -24 W -4030 454 PD -24 W -4030 376 PD -24 W -4030 353 PD -24 W -4030 372 PD -24 W -4030 396 PD -24 W -4030 469 PD -24 W -4030 539 PD -24 W -4030 607 PD -24 W -4030 764 PD -24 W -4030 876 PD -24 W -4030 966 PD -24 W -4030 1161 PD -24 W -4024 1135 PD -24 W -4024 919 PD -24 W -4024 812 PD -24 W -4024 714 PD -24 W -4024 628 PD -24 W -4024 553 PD -24 W -4024 436 PD -24 W -4024 372 PD -24 W -4024 351 PD -24 W -4024 359 PD -24 W -4024 399 PD -24 W -4024 443 PD -24 W -4024 493 PD -24 W -4024 621 PD -24 W -4024 713 PD -24 W -4024 791 PD -24 W -4024 969 PD -24 W -4024 1059 PD -24 W -4024 1250 PD -24 W -4029 1224 PD -24 W -4029 1001 PD -24 W -4029 888 PD -24 W -4029 784 PD -24 W -4029 691 PD -24 W -4029 608 PD -24 W -4029 476 PD -24 W -4029 396 PD -24 W -4029 359 PD -24 W -4029 360 PD -24 W -4029 386 PD -24 W -4029 420 PD -24 W -4029 462 PD -24 W -4029 576 PD -24 W -4029 660 PD -24 W -4029 732 PD -24 W -4029 901 PD -24 W -4029 987 PD -24 W -4029 1172 PD -24 W -4029 1248 PD -24 W -4026 1205 PD -24 W -4026 1083 PD -24 W -4026 967 PD -24 W -4026 860 PD -24 W -4026 762 PD -24 W -4026 582 PD -24 W -4026 469 PD -24 W -4026 399 PD -24 W -4026 386 PD -24 W -4026 362 PD -24 W -4026 374 PD -24 W -4026 398 PD -24 W -4026 466 PD -24 W -4026 533 PD -24 W -4026 594 PD -24 W -4026 729 PD -24 W -4026 807 PD -24 W -4026 968 PD -24 W -4026 1041 PD -24 W -4026 1247 PD -24 W -4026 1222 PD -24 W -4026 1099 PD -24 W -4026 983 PD -24 W -4026 875 PD -24 W -4026 676 PD -24 W -4026 539 PD -24 W -4026 443 PD -24 W -4026 420 PD -24 W -4026 374 PD -24 W -4026 367 PD -24 W -4026 377 PD -24 W -4026 421 PD -24 W -4026 470 PD -24 W -4026 519 PD -24 W -4026 637 PD -24 W -4026 705 PD -24 W -4026 853 PD -24 W -4026 920 PD -24 W -4026 1116 PD -24 W -4026 1247 PD -24 W -4028 1210 PD -24 W -4028 1088 PD -24 W -4028 974 PD -24 W -4028 762 PD -24 W -4028 607 PD -24 W -4028 493 PD -24 W -4028 462 PD -24 W -4028 398 PD -24 W -4028 377 PD -24 W -4028 375 PD -24 W -4028 400 PD -24 W -4028 435 PD -24 W -4028 474 PD -24 W -4028 577 PD -24 W -4028 637 PD -24 W -4028 774 PD -24 W -4028 836 PD -24 W -4028 1022 PD -24 W -4028 1146 PD -24 W -4025 1190 PD -24 W -4025 945 PD -24 W -4025 764 PD -24 W -4025 621 PD -24 W -4025 576 PD -24 W -4025 466 PD -24 W -4025 421 PD -24 W -4025 400 PD -24 W -4025 375 PD -24 W -4025 387 PD -24 W -4025 410 PD -24 W -4025 470 PD -24 W -4025 516 PD -24 W -4025 619 PD -24 W -4025 672 PD -24 W -4025 828 PD -24 W -4025 941 PD -24 W -4025 1157 PD -24 W -4025 1251 PD -24 W -4025 1074 PD -24 W -4025 876 PD -24 W -4025 713 PD -24 W -4025 660 PD -24 W -4025 533 PD -24 W -4025 470 PD -24 W -4025 435 PD -24 W -4025 387 PD -24 W -4025 380 PD -24 W -4025 390 PD -24 W -4025 430 PD -24 W -4025 464 PD -24 W -4025 549 PD -24 W -4025 594 PD -24 W -4025 733 PD -24 W -4025 833 PD -24 W -4025 1035 PD -24 W -4025 1123 PD -24 W -4025 1263 PD -24 W -4028 1174 PD -24 W -4028 966 PD -24 W -4028 791 PD -24 W -4028 732 PD -24 W -4028 594 PD -24 W -4028 519 PD -24 W -4028 474 PD -24 W -4028 410 PD -24 W -4028 390 PD -24 W -4028 391 PD -24 W -4028 415 PD -24 W -4028 440 PD -24 W -4028 513 PD -24 W -4028 551 PD -24 W -4028 678 PD -24 W -4028 767 PD -24 W -4028 957 PD -24 W -4028 1040 PD -24 W -4028 1178 PD -24 W -4027 1161 PD -24 W -4027 969 PD -24 W -4027 901 PD -24 W -4027 729 PD -24 W -4027 637 PD -24 W -4027 577 PD -24 W -4027 470 PD -24 W -4027 430 PD -24 W -4027 415 PD -24 W -4027 397 PD -24 W -4027 408 PD -24 W -4027 442 PD -24 W -4027 471 PD -24 W -4027 559 PD -24 W -4027 633 PD -24 W -4027 791 PD -24 W -4027 867 PD -24 W -4027 988 PD -24 W -4027 1248 PD -24 W -4031 1059 PD -24 W -4031 987 PD -24 W -4031 807 PD -24 W -4031 705 PD -24 W -4031 637 PD -24 W -4031 516 PD -24 W -4031 464 PD -24 W -4031 440 PD -24 W -4031 408 PD -24 W -4031 409 PD -24 W -4031 430 PD -24 W -4031 452 PD -24 W -4031 526 PD -24 W -4031 588 PD -24 W -4031 731 PD -24 W -4031 800 PD -24 W -4031 919 PD -24 W -4031 1166 PD -24 W -4031 1274 PD -24 W -4031 1250 PD -24 W -4031 1172 PD -24 W -4031 968 PD -24 W -4031 853 PD -24 W -4031 774 PD -24 W -4031 619 PD -24 W -4031 549 PD -24 W -4031 513 PD -24 W -4031 442 PD -24 W -4031 430 PD -24 W -4031 416 PD -24 W -4031 427 PD -24 W -4031 464 PD -24 W -4031 508 PD -24 W -4031 615 PD -24 W -4031 676 PD -24 W -4031 774 PD -24 W -4031 993 PD -24 W -4031 1096 PD -24 W -4031 1253 PD -24 W -4036 1248 PD -24 W -4036 1041 PD -24 W -4036 920 PD -24 W -4036 836 PD -24 W -4036 672 PD -24 W -4036 594 PD -24 W -4036 551 PD -24 W -4036 471 PD -24 W -4036 452 PD -24 W -4036 427 PD -24 W -4036 433 PD -24 W -4036 458 PD -24 W -4036 492 PD -24 W -4036 587 PD -24 W -4036 641 PD -24 W -4036 735 PD -24 W -4036 942 PD -24 W -4036 1039 PD -24 W -4036 1194 PD -24 W -4036 1247 PD -24 W -4036 1116 PD -24 W -4036 1022 PD -24 W -4036 828 PD -24 W -4036 733 PD -24 W -4036 678 PD -24 W -4036 559 PD -24 W -4036 526 PD -24 W -4036 464 PD -24 W -4036 458 PD -24 W -4036 441 PD -24 W -4036 454 PD -24 W -4036 504 PD -24 W -4036 547 PD -24 W -4036 616 PD -24 W -4036 782 PD -24 W -4036 869 PD -24 W -4036 1006 PD -24 W -4036 1263 PD -24 W -4036 1247 PD -24 W -4036 1146 PD -24 W -4036 941 PD -24 W -4036 833 PD -24 W -4036 767 PD -24 W -4036 633 PD -24 W -4036 588 PD -24 W -4036 508 PD -24 W -4036 492 PD -24 W -4036 454 PD -24 W -4036 447 PD -24 W -4036 473 PD -24 W -4036 502 PD -24 W -4036 563 PD -24 W -4036 701 PD -24 W -4036 775 PD -24 W -4036 905 PD -24 W -4036 1143 PD -24 W -4033 1157 PD -24 W -4033 1035 PD -24 W -4033 957 PD -24 W -4033 791 PD -24 W -4033 731 PD -24 W -4033 615 PD -24 W -4033 587 PD -24 W -4033 504 PD -24 W -4033 473 PD -24 W -4033 448 PD -24 W -4033 461 PD -24 W -4033 492 PD -24 W -4033 577 PD -24 W -4033 634 PD -24 W -4033 737 PD -24 W -4033 938 PD -24 W -4033 1153 PD -24 W -4033 1242 PD -24 W -4037 1251 PD -24 W -4037 1123 PD -24 W -4037 1040 PD -24 W -4037 867 PD -24 W -4037 800 PD -24 W -4037 676 PD -24 W -4037 641 PD -24 W -4037 547 PD -24 W -4037 502 PD -24 W -4037 461 PD -24 W -4037 464 PD -24 W -4037 490 PD -24 W -4037 553 PD -24 W -4037 600 PD -24 W -4037 696 PD -24 W -4037 880 PD -24 W -4037 1083 PD -24 W -4037 1166 PD -24 W -4044 1263 PD -24 W -4044 1178 PD -24 W -4044 988 PD -24 W -4044 919 PD -24 W -4044 774 PD -24 W -4044 735 PD -24 W -4044 616 PD -24 W -4044 563 PD -24 W -4044 492 PD -24 W -4044 490 PD -24 W -4044 493 PD -24 W -4044 524 PD -24 W -4044 564 PD -24 W -4044 638 PD -24 W -4044 796 PD -24 W -4044 980 PD -24 W -4044 1063 PD -24 W -4038 1248 PD -24 W -4038 1166 PD -24 W -4038 993 PD -24 W -4038 942 PD -24 W -4038 782 PD -24 W -4038 701 PD -24 W -4038 577 PD -24 W -4038 553 PD -24 W -4038 524 PD -24 W -4038 484 PD -24 W -4038 498 PD -24 W -4038 535 PD -24 W -4038 630 PD -24 W -4038 769 PD -24 W -4038 837 PD -24 W -4040 1274 PD -24 W -4040 1096 PD -24 W -4040 1039 PD -24 W -4040 869 PD -24 W -4040 775 PD -24 W -4040 634 PD -24 W -4040 600 PD -24 W -4040 564 PD -24 W -4040 498 PD -24 W -4040 497 PD -24 W -4040 525 PD -24 W -4040 593 PD -24 W -4040 712 PD -24 W -4040 770 PD -24 W -4040 1259 PD -24 W -4046 1253 PD -24 W -4046 1194 PD -24 W -4046 1006 PD -24 W -4046 905 PD -24 W -4046 737 PD -24 W -4046 696 PD -24 W -4046 638 PD -24 W -4046 535 PD -24 W -4046 525 PD -24 W -4046 526 PD -24 W -4046 557 PD -24 W -4046 645 PD -24 W -4046 698 PD -24 W -4046 1125 PD -24 W -4046 1329 PD -24 W -4040 1263 PD -24 W -4040 1143 PD -24 W -4040 938 PD -24 W -4040 880 PD -24 W -4040 796 PD -24 W -4040 630 PD -24 W -4040 593 PD -24 W -4040 557 PD -24 W -4040 516 PD -24 W -4040 545 PD -24 W -4040 577 PD -24 W -4040 884 PD -24 W -4040 1059 PD -24 W -4040 1287 PD -24 W -4038 1153 PD -24 W -4038 1083 PD -24 W -4038 980 PD -24 W -4038 769 PD -24 W -4038 712 PD -24 W -4038 645 PD -24 W -4038 545 PD -24 W -4038 521 PD -24 W -4038 536 PD -24 W -4038 722 PD -24 W -4038 866 PD -24 W -4038 1066 PD -24 W -4042 1242 PD -24 W -4042 1166 PD -24 W -4042 1063 PD -24 W -4042 837 PD -24 W -4042 770 PD -24 W -4042 698 PD -24 W -4042 577 PD -24 W -4042 536 PD -24 W -4042 539 PD -24 W -4042 684 PD -24 W -4042 805 PD -24 W -4042 992 PD -24 W -4024 1259 PD -24 W -4024 1125 PD -24 W -4024 884 PD -24 W -4024 722 PD -24 W -4024 684 PD -24 W -4024 489 PD -24 W -4024 514 PD -24 W -4024 589 PD -24 W -4024 870 PD -24 W -4024 1191 PD -24 W -4017 1329 PD -24 W -4017 1059 PD -24 W -4017 866 PD -24 W -4017 805 PD -24 W -4017 514 PD -24 W -4017 470 PD -24 W -4017 498 PD -24 W -4017 689 PD -24 W -4017 951 PD -24 W -4017 1228 PD -24 W -4015 1287 PD -24 W -4015 1066 PD -24 W -4015 992 PD -24 W -4015 589 PD -24 W -4015 498 PD -24 W -4015 471 PD -24 W -4015 558 PD -24 W -4015 758 PD -24 W -4015 998 PD -24 W -4015 1152 PD -24 W -4001 870 PD -24 W -4001 689 PD -24 W -4001 558 PD -24 W -4001 420 PD -24 W -4001 467 PD -24 W -4001 600 PD -24 W -4001 709 PD -24 W -4001 892 PD -24 W -4001 1114 PD -24 W -4001 1269 PD -24 W -3990 1191 PD -24 W -3990 951 PD -24 W -3990 758 PD -24 W -3990 467 PD -24 W -3990 379 PD -24 W -3990 413 PD -24 W -3990 481 PD -24 W -3990 604 PD -24 W -3990 797 PD -24 W -3990 939 PD -24 W -3990 1157 PD -24 W -3990 1334 PD -24 W -3985 1228 PD -24 W -3985 998 PD -24 W -3985 600 PD -24 W -3985 413 PD -24 W -3985 362 PD -24 W -3985 389 PD -24 W -3985 453 PD -24 W -3985 604 PD -24 W -3985 724 PD -24 W -3985 955 PD -24 W -3985 1105 PD -24 W -3991 1152 PD -24 W -3991 709 PD -24 W -3991 481 PD -24 W -3991 389 PD -24 W -3991 392 PD -24 W -3991 422 PD -24 W -3991 535 PD -24 W -3991 637 PD -24 W -3991 854 PD -24 W -3991 985 PD -24 W -3991 1290 PD -24 W -3992 892 PD -24 W -3992 604 PD -24 W -3992 453 PD -24 W -3992 422 PD -24 W -3992 402 PD -24 W -3992 468 PD -24 W -3992 544 PD -24 W -3992 754 PD -24 W -3992 855 PD -24 W -3992 1114 PD -24 W -4001 1114 PD -24 W -4001 797 PD -24 W -4001 604 PD -24 W -4001 535 PD -24 W -4001 468 PD -24 W -4001 454 PD -24 W -4001 490 PD -24 W -4001 636 PD -24 W -4001 703 PD -24 W -4001 901 PD -24 W -4001 1178 PD -24 W -4001 1354 PD -24 W -4010 1269 PD -24 W -4010 939 PD -24 W -4010 724 PD -24 W -4010 637 PD -24 W -4010 544 PD -24 W -4010 490 PD -24 W -4010 505 PD -24 W -4010 620 PD -24 W -4010 666 PD -24 W -4010 824 PD -24 W -4010 1070 PD -24 W -4010 1234 PD -24 W -4031 1157 PD -24 W -4031 955 PD -24 W -4031 854 PD -24 W -4031 754 PD -24 W -4031 636 PD -24 W -4031 620 PD -24 W -4031 631 PD -24 W -4031 661 PD -24 W -4031 779 PD -24 W -4031 980 PD -24 W -4031 1144 PD -24 W -4031 1461 PD -24 W -4036 1334 PD -24 W -4036 1105 PD -24 W -4036 985 PD -24 W -4036 855 PD -24 W -4036 703 PD -24 W -4036 666 PD -24 W -4036 661 PD -24 W -4036 662 PD -24 W -4036 725 PD -24 W -4036 883 PD -24 W -4036 1022 PD -24 W -4036 1308 PD -24 W -4036 1290 PD -24 W -4036 1114 PD -24 W -4036 901 PD -24 W -4036 824 PD -24 W -4036 779 PD -24 W -4036 725 PD -24 W -4036 681 PD -24 W -4036 746 PD -24 W -4036 832 PD -24 W -4036 1042 PD -24 W -4036 1450 PD -24 W -4040 1178 PD -24 W -4040 1070 PD -24 W -4040 980 PD -24 W -4040 883 PD -24 W -4040 746 PD -24 W -4040 718 PD -24 W -4040 752 PD -24 W -4040 877 PD -24 W -4040 1193 PD -24 W -4043 1354 PD -24 W -4043 1234 PD -24 W -4043 1144 PD -24 W -4043 1022 PD -24 W -4043 832 PD -24 W -4043 752 PD -24 W -4043 746 PD -24 W -4043 811 PD -24 W -4043 1060 PD -24 W -4043 1375 PD -24 W -4044 1461 PD -24 W -4044 1308 PD -24 W -4044 1042 PD -24 W -4044 877 PD -24 W -4044 811 PD -24 W -4044 774 PD -24 W -4044 888 PD -24 W -4044 1113 PD -24 W -4044 1384 PD -24 W -4045 1450 PD -24 W -4045 1193 PD -24 W -4045 1060 PD -24 W -4045 888 PD -24 W -4045 800 PD -24 W -4045 873 PD -24 W -4045 1045 PD -24 W -4045 1482 PD -24 W -4039 1375 PD -24 W -4039 1113 PD -24 W -4039 873 PD -24 W -4039 776 PD -24 W -4039 843 PD -24 W -4039 1118 PD -24 W -4043 1384 PD -24 W -4043 1045 PD -24 W -4043 843 PD -24 W -4043 820 PD -24 W -4043 951 PD -24 W -4043 1332 PD -24 W -4036 1482 PD -24 W -4036 1118 PD -24 W -4036 951 PD -24 W -4036 795 PD -24 W -4036 924 PD -24 W -4036 1142 PD -24 W -4028 1332 PD -24 W -4028 924 PD -24 W -4028 757 PD -24 W -4028 832 PD -24 W -4028 1154 PD -24 W -4033 1142 PD -24 W -4033 832 PD -24 W -4033 817 PD -24 W -4033 990 PD -24 W -4033 1352 PD -24 W -4037 1154 PD -24 W -4037 990 PD -24 W -4037 867 PD -24 W -4037 1002 PD -24 W -4037 1413 PD -24 W -4031 1352 PD -24 W -4031 1002 PD -24 W -4031 847 PD -24 W -4031 1022 PD -24 W -4031 1340 PD -24 W -4031 1464 PD -24 W -4034 1413 PD -24 W -4034 1022 PD -24 W -4034 891 PD -24 W -4034 1015 PD -24 W -4034 1248 PD -24 W -4041 1340 PD -24 W -4041 1015 PD -24 W -4041 978 PD -24 W -4041 1263 PD -24 W -4074 1464 PD -24 W -4074 1248 PD -24 W -4074 1263 PD -24 W -4074 1292 PD -24 W -4074 1925 PD -24 W -4130 1925 PD -24 W -4130 1781 PD -24 W -4130 2371 PD -24 W -4188 2371 PD -24 W -4188 2229 PD -24 W -4188 2806 PD -24 W -4255 2806 PD -24 W -4255 2659 PD -24 W -4459 3535 PD -24 W -4566 3756 PD -24 W -4664 3865 PD -24 W -4862 3934 PD -24 W -4990 3937 PD -24 W -948 3936 PD -24 W -957 3936 PD -24 W -959 3937 PD -24 W -959 3936 PD -24 W -953 3937 PD -24 W -953 3936 PD -24 W -940 3937 PD -24 W -940 3936 PD -24 W -941 3937 PD -24 W -941 3936 PD -24 W -939 3937 PD -24 W -939 3936 PD -24 W -948 3937 PD -24 W -948 3936 PD -24 W -948 3935 PD -24 W -948 3936 PD -24 W -948 3935 PD -24 W -955 3937 PD -24 W -955 3936 PD -24 W -955 3935 PD -24 W -948 3937 PD -24 W -948 3936 PD -24 W -948 3935 PD -24 W -945 3937 PD -24 W -945 3936 PD -24 W -945 3935 PD -24 W -946 3936 PD -24 W -946 3935 PD -gr - -c8 -gs 767 332 4576 3606 rc -gr - -0 sg -11 -2134 253 3548 2 MP stroke --45 42 -45 -42 44 120 46 -120 219 1456 5 MP -PP - 81 3659 mt -(weight) s -1755 0 1302 4262 2 MP stroke --42 -45 42 -45 -120 45 120 45 3015 4217 5 MP -PP -1011 4304 mt -(angle) s -0 2731 2997 1059 2 MP stroke -0 2293 4035 1543 2 MP stroke -614 0 3262 944 2 MP stroke --42 -45 42 -45 -120 45 120 45 3834 899 5 MP -PP -2931 986 mt -(90deg) s -4277 1047 mt 5365 1047 L -5365 1047 mt 5365 649 L -4277 1047 mt 4277 649 L -4277 649 mt 5365 649 L -4337 798 mt -(many observation) s -4337 936 mt -(with high weight) s -1740 3709 mt 2778 3709 L -2778 3709 mt 2778 3449 L -1740 3709 mt 1740 3449 L -1740 3449 mt 2778 3449 L -1801 3598 mt -(few, low weight) s - -end %%Color Dict - -eplot -%%EndObject - -epage -end - -showpage - -%%Trailer -%%EOF diff --git a/misc/matlab/appunti/problem.fig b/misc/matlab/appunti/problem.fig deleted file mode 100644 index bb099555584a89c1a073fa9c463846ab710de28e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80227 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� zL1*)mDGP2_8N1UaOa-$+a#1XmbcPUi7o3$Lr4MFx>UMQWV~U@5Y)t@8Fz(;c36^|S zsaG<pJ;jRQzArweb8N-%BoDDyin8LJ5<@6$)nhV^b9-?55}5pa-BEk{<e9hWS=vY@ zk!u(6aV^%_pWArB2!kv2K`(sl1HP@VgCDy}^J-@ao2n6Go#Nf@Z~g`VN4j(laBKZV zF1z1VpkW6;#{VB6=0||8A(X7k)3^6Wv47^Q5F(cl`&|u~R_0q_P$p*q*dzDE|Md&S z+}}n6f{G5+T(TXLO-9&NY+fX7XS=gJzOzzQdOm<@6ZtU)-<{F&cjslsCeJW0VO@o~ zCT%ytCV6u!L7TGy*j19Y=lp=KdlUVjpsxGC%BG-J=MA5ZNbj?VaovN<FZhjC;Hp5M zXH9N<Y5Y~Lp(b_XJd&h(ExN3}vwT%C!DzS537#qw)T!hK;ttq#e=)ZnmX?d>kNsbp zsQG^&#%)W@q|L3iD8;+xFt7<JC_<b5ABZ0_GSz}YLPBQ*{#fkb2*aj9%+K&&kp+9N z^^^GnPsL7C4>5AjEZAOr+A(@2qprCTKAiKWiAo#9p;gHANJ;%<<i;W7Gx7{iRMqJ^ zZy<&u%S)ZI!^&_zz!=@^1b?1=6=^H%mYC)J#vYdSXfbElJ(s-xRoi}K1)vPjpKV&4 zk+H?IUZa1ou}#S$2g&+2a7UL8Gy>^8d(r)F6pi*+bd&k6@H55FY7lZSf$1>1)oszJ z*OE;t^*Q$;!4_z&Xr7+Mt)L$>C!EApmmf#gZ`bt1r1zM?=kb{fpOyKU;95Pr_j@Mc zww?B_>ch59L#qLmB#<Vd^$f0)(B`WTy5F8%&&_E6lM~kI#GW9j-=C^*w*BB2Dt1$~ zanF#LFF7q$5uowmo1qu@qPu({kG-nZ2c>M{G0t;SHPNi=ysdND`U9zTVA3}2^E;qw zAl3A2oASTUUQN0CJyo#jl%6{~=%7qtK+7w>*@Yed$3cQf1!>od7h!v2#R?~ie1K4e z6a2C7WTqnjEX9+auXQAiShipL4B};B1mpd}AuHSdxZe_BoaoL7Z#FbmTl~Gm^!wLg z)>Wf-hK?cfo@ete&A<8^^QWT>`{*(pE%n+rJYP3tsNBB4a4CNJ-Hk$&=8R9xsk+Bd z^&>z!7sjm~(WRPCz=5Hj;&&SSWknwLrVx2MBs)=^$T}$db;&34?^5t)k%$k&%x%F~ zD)D6=kkr2_%ie&0rz;ttFi&S)tFImCkS`qIY;@u{e}`;#$_@TwDXSq>%H<ri0`%MJ zOC{KBO*0~_vhYi2bKRZg@|y)#-8Mt2+F~liE{4){IjVK<kaqh3i3Acu(BUknNyJ%G ze#W>;bsmi4;-{O&hr_`OKN+$6Dl=e$tOgsLAgBZdm2ey^U&yzt%JmVkuDXFed(hom zDOb5D3o<$N`R!K4>2CsGD-VJW(){lo^#4mglHc~*P-xds54(GK{NvK645h=i_0!sx zi;gfm7<fF`Pw?a7B(V}Z*pup&e0hI0I?9!~q^nQn-7dpofrD=`9IWayvU2n#gz5Vn z*)Mr5Fvea=o%Y|5OiDZtC_h}s;)i<@t{z@CfEZGuN<t-y2iNm*fE~L6fk}O?nq&4r z-p2c*l_1fKQZ1IFmrskrpQy`E$tq#lypmpI520jr?%Kf8ZtWtQ1zdp`w(2x#2Q3S6 zI?N|%8Wj5&JxH*{#~Z}=;II^NZ&_f1<}P7o1*9_J97ydUG^qx+331%_X!id-wk$G# z_iz34D(oRC6?13Xu@fcCHS6N4<UVJ#N?~-pE52JMRLPW8z6-L-xI2pDS=Z|~(&?KO zcAJ%~{B^MyXk)|8=vMbsm*3yC49v6p<w(rON_`GYSqAmOMS@;!Z?`S9_^aEGi8;pb ztQ-CRwRr!z_R6@>vr_6m^Y&gAH#cd$Z`wjnF}tB~|LgYy+@=L+KTjpu57*gHKl#N( zNobUao0;;xp62)~!5!ag9fw(J(UkFz+Ec&Tfx#h|ABLFCgMl3*7_Sc*==JI;RnnIi z`pz3o++pIrhYG&yy1qYk`7q4pT6WvY;l`<JI+)T;RC6k8BIIk={6}lIB1usSmzQ|0 zEm&2#9X!N7&zKY8y(h>eMo6Mv3EM)U;CU#=f+=7+5aXAqiOuuq8(zrR-a}gTy=$u3 z9Ii~0h9f+t<EguvDvnuRQ)VXCM0ij2B=zyu+j_x+ut?~FUKEk`Uwk?oGfe&Js0h!y z496E2MLn$CfjX=t&#NS;QYS*ZZ&SBkCO}!#ZM{F<Di;_j?{X~ioIQ5CX{}LzIz5<M znwm&=$9(XUHt&$2bt<csq1o;yEZ##WvvRk;x!Jq<73n&^-{aWs|Bt~fjg2LZ<HuD7 zo68cvDqx?rPBb^iF7Hui(7GG@W^QOG=hflljmCKXjP9Q;kUF)_qWJZdxD=mXZRD+H zMz5y)r$GINg0QzY39pNzG7B6X1XN@U`QX1bME{Q62nxO$4mS0q3eQ-TbH}zYJc=)} zTMqNGlE}t?US`E$9DIY6-^M?3b&vP_cmTRxwO%juHErO2`<dOH4z5^l8T{6vKa`@( zw{w!CTlFjJBB96YTQ71!tA$Hi=0TEjLMJj|XFL9;>e$bv<m6Y9_GH4;!U>gK>VJ$A z%GyBg^ybqkoMx%bR|9@nN0ISrQ_|tUH5oqS?$2<Jg7yefeA!AU8^U>n&?@S5Qe^0M zkgv#pTP=f$%#zG6fpg>~saj@$r1el^MDe$~5~)xiBUFPD?pbg|9Ll<w?6oTSWO1$} zt6GZkPsYDHqWv(?crIR~Wf~`mc8#cNG-2ID&@QU^VrNG5z7`?!Zu-*8;Qk|XXY3Zk z)$dvLQ01exZRZP5DaW&^vVcoO&W8V1J}2og#pOuzQC(ZawkI1f4+6ftOPMmY%}<-| zSK3meqF;aQdu0j>bI)h{ULYB$4vW(;$=?8ToJ{313ymYYzjBTDl3tW_U7^VRtxUhN zwM2Qp#f;o>?%Q9vn<uAxA=z}r=s;^Ol%Y?05<K}`k{f(-v1J4rYpD$RVv_6&bPV8j zH6AuY#Mh3^o{5PMO!GydBwmZd_3v$H9!j8EQCzE~gzkjPk+I&d<~))Tx(9RmP3TFX zInb3>uH2k*{Rf1o=(xnGYJh?$`s^=#IWT&bhJ+SLGIE~u`e3Etire5?$YafCrDZ+v zci!zS3Oajga_ku@dHnHcIjXAG8Em4lAC(Cq4E)52YvONu7Vz+2FGCODJpG<l>K(|S z?A6eOGE1bg>N9NXFaoZ^e~bnnxiyEP<QQSuxi0>F?Qd*(3P~IU1O%!-m4$yLm+eh7 z+vKli{TSXe^&2i%V~O?$ReCU#JxwwlR5pRFRl$ze9^2JnU^b@UvebPIvOcsK2y|WZ zo1DhoJ?+;Jfa0k$fSn-YKECahWNO?ww3PD$p^+A^aB@24Jwn|}eO~D~?Y)xL3o_C^ zk9pE|WfmC?-tA$wJoB(fRKo3^NGcO;e{EaoVpFf#`r!amm;DwOh0nr;vdt**>`KhM zBKErpPsGFcG8@eFK@r)$sJC>*trMdy#Rf?xQ)f@N`yup4R;&9N*$mwd7yVgk-6w|* z<)n&tzn*QD(4J{;kLAb-%ndbiG?gp4rlu27R=mVfb|BV;chGRPclOYTp2{BF&YZN2 zT@A|h0AQ`-sT_B-ekM#7FG*{RI@JKxLD*Xr?;w@QS}pmul<$bB6|5hKQF`O8WAJf< zx?&o1hP-+}+cr&p$%&0aD^WzLNP9pcif+W8c-L|cdf6XunD(kQT4af|gsM)Z;XO;O zXYK1`9SCMH?pKN)BJQ{Noi{(*Xn%d;lD3vmdnJb{uc!T)%mXn$ej#FV$DJJ%Gk3}5 z`O&);xw8=6_5Ky_8T4#dV)U_IQbPi0x#a43CUNEgYvO<~G6An<jWWE9oX?{8X?kvV zv3<}RC$NKfjvKTI(rSP5qso0?1Mk_|&~Yz)6!dJZ#CdTvD&uxt8esv;xj=5C_<{4` z^R@tjs<80+2O$$1AGS@DX5hzGrt)#h1-4vC-#_+YJIF?lINuxU;nnsLGs+5cKcGD> zu@0)at*%qDo^17F{`YUu=XNC(!-zjt@A@Suc6}5?jmEp{OxJct6`r_PuE*Jx5UJUX zU!YT=%}7_1K(86<Yqy-w&Qb8v5bppM&wI6RWg=a@@iyaI>Ff(9hZIbto7pGcUC;;G z#M)ajNMcg(03{RRV!jjl{KsXT)b9SXVJKSg-~_$ZFOVp4dF)pz)A~Tvk!v9pGJ>H? z>V&LhTG^%H=4o*S{_JmS;AbIB+lOEn<!T_M)*@<e{f`dLkN3p;+e_}u0FDc7HIP<Z zX;HLqgM>?hGa}z~*BI^2#ISxjRbUU~fQ8@(4f?Q%k>;NI1n*=G+`pq8vYZgw4=Koy z>Z_c_Wc`MQfY~ip8&1ytI@8=sb|d>gyWT5~F_)Mk)bYk@j)MLd5kQ<CZM6d^VQZjC zl~w517lY}A&6yH9L-I-HmAu1ticv~xuEcPA{eD+m523&Xx%XorErmsCamc<QY6I(b zwPUVRj5&TW+&+D|zK-~^9t$ox#R#T;-$uDgKUqg<O#QkqJ$ruE;4jnQ{2IFt7rXP$ z0D{#A{rTFr^|;i>M){}0O$eE5A(a*wM=k~<MJyvuTSLv<y$>&i;ND#3YNBWe$iVu5 zVt8nIxz>a*Za6?Q(I+)kOaPAC16Bdv*}K?i+>7*Uy^Y48-}6eSKc?9zztUYlB>={D zv4&23W=Z}JgAXWn=s)$m(5vh$aglE6jvII79XTTNESu!K&wc7V4ESJ@jLBD7`XPB? zad}}Ym%GZWt?ijju}-cu(k+1<W6?kP#x@73QUos%-FAGgH?4nf0J5IXaRZr0<|WQz zswT!`EhQ-XJ!#LQwnDjX8a13RokJY??*cK~q}1S(lF<h)wBLl8HJQFG=cRafcc0!u z9j4I!Nbg5NfYsJ;`#M{o{cnF_2EpeXzU9aA7b$IC_uGo%sbW6g%ZGb)XP7V2tQnbp zUzcc)eZl|QN@dba*ALCavFw}diYB6EE{Z7fwh!!=nX_R^%?Qp6kbe;^@Qc!QENN9w zbg@qJF6O2cGw8ynn<lOtXXsok5UiB<@4EV!41v76NJ?<KgP*S(qXV@YucKQ1yIc2; z?ISbnyeDr=>@wzsb3gSBitKK;Sl>sc+KKM7wh68OHZbxSKA@|71%*d#!XKbR>N`i@ z%AITh-8xoAt7eszBFJ|}I^DB4=Z!)SYL^jJbeV3ED5RBl)4NvD-CXm#*2nMhu%C|i zQFG%;r2A>tPQoxE`k`6p|GMgWZO$)5s4fE|UTps;7PS*sS6un<22aO2qorCgL%VU? zm4Ntk%-e>j_Tp<_OM@S7GevaD6V_MHNv;%LzAXJp!1$y20izGOe=53o`h`I8<mYIg z^WEX4pK0J*3^VrIKlDgOEQ_Tl1=p5WZGG39C0QpDgN>~I7+)1`byH4l67j7u$@Yxl zTBctPW!L-U%ov22DGkktSZj>j<FF;W_^b&hE+uJllFXHlWu9QtvfzzXS3A8~l;4tK z!1FfjnEbq<H|&Bjv16HNk%F;tCJ}m@Ez_Ph*dQdKlRSJhk1_gz&x><FgfEQ;QPed* zvinZDVZG`#*A{&0RL^Ss6^Qk~Pv^SXcX)kx&X&;Eoi1BA;ywc{GRz}8QVte5eE{p0 z5Axvc?WDbJ_wqEUO{$ndLNZPJQaqYd?wUjPq2$e@+Qc_f0Y5sl1=mT!{g<gxr51_0 zP|(2vKv|C)_CBlI_S+)))65=T4qdq@lJkklE}maA0jd+04uT~efRo8Tw}dc;zY*WR z7rT;8Dn)nie;NdYF7P7yns(}@o8$qJ_y$&^qFxxI8pmuJdKqraQy7f?EaQxPl6HKm z85Rf9W2<4Dui(k9=t@`zRzuvQJX^os0#_vFFaM9GZwvCC;j}<rEIyjG1#9!K>qzt9 zi{EL4C!z<GhJWc`Qo)qA#$*4vSt5CTo(u-b??iAU<b4CeB1e^M6Uh9SnGn?9;BHKg zL{LWhk1K4N63FlWjBX_5jty-a*vW4Q5a;-8=QpM!_h~>!j=4d9(3zlOi$N%Tz*+e$ zC;WzTFH*hwsqaih&Umm%Kyz}Oa}O#dLF$7w-0LV%;8f?CgoC2z0vTalHN>-R4FH)) z5Qm|KR(=>=j>6H#Gf}iE+pZG*qAe{zx=FLk1}u|1kM`^QX|MfvjZ7`N`~B{Rm3a-d zAN3U1w1#xM(ZixYV!R1KbAOylLXGU}E@lU#g6t)!j&;H*KH<Tv)zC9(lqVH8Oq1lh zNKr&bD@|z{*Xi{?As@?V|9vA`Hm^wUcbG!WG2lu@NVMY8$xI5^Y*?A0G>_C}=&O8_ z43Ip(x9-rWp%Sxh<rVVo$IaiN=3j+~1AZK_CJmmoBB<2S&KLiv9bEvIZ(#I2${&9E ziypVbz1sfzTZ2VNlxi-HGh={p?qWk<+qG)ryQ%;m0uvq6>@^smNgGIh+@7mmd>S?7 zEnxM!RbZOy%lP)w!G^sl!dc*Ke_l{0x{BGZs^}P+zDb7m!c_1xPD&jwrfPBFt5XlZ zHtv-=yEQB@k))*@FcLlER&(OUJS!m8-|b-e(_p?}Ee*`4NR>brNg6g9M{b-+HgfL` zU$!q&VsY&qT_zr1;&};4`Ucon{mM-q6bYRFXX=Y+O<TeaZcT{;EwP2y6CL3lji~og z+||F3aO}MtAg~}&bN;6@x0pV+NHS9WL%*qhF!wse<H?jbcJaDzoR*gytW7lAw`K}3 z-Y-0$snO%&ho!ZJ_S@KM)kN8s|6PA}P!+f?`nM}3YxrOeK{Y>T9u5P5)d7<UGWQh+ z?cE=s8nCfN82{Sd%ad83l5|Mj(T=pWxZQQkm1L(WKV7!>)XkM@;A+ac*tMQND1Ds= z+R)-ZBmxEp=`wTO#14BrAN|}?w5D5v@DChp&kJp@0mE8gC5bZP>g$ewL9X{UQ0Jh# zRBg}7AQaw1V19h+y0k}gy4xN9|7e13kIpp}5LRAn`siEV5<HU~ePWoZxkOU&i5qu` zfNxAh%*DSlfcw9WwfmPp3uf={-X&deH49#7bQ}j<xq@mKm7koXs*km-pj-VAcNiFH zW@>ol7_@0(&Mygrr$z(QkabKy-#Yk&YjSS0)A%M)km9cuE=a$%>6BitdC568%;&!J z_GtrkXx;Ax{@w-Cl#8q*j@skLT9R4m@VkbC7DH4Y`$bSG!aTJ7B@_0iQNbNMt+A^t z!64yWQ|fDsV5XLDF#P3P-K1fbplWvHCzTUt_2KDUXP?Fh-*28u^l~81ef^2^*H_e_ zj}m9;V7eE3wqJdp*IZg_$sAJCWgd!Tjo413PRM@_e6rNr$CNG%(5-RqS$OyTu4QE1 zQeK0j^SI3g^42BKa2tC2(mwFJq2t+H^foZW0io6-GT$0))6E{BJ6fa_G|dfN1bw<+ zEkMJ&QDLsC{<gQ%2&D(kSu3SU-QutBEpHX+=CfQi(hlN4uU+q<lorEGFTbXGUxnkK z9OfNYK)%wpVT@ar`X6(%XS&sG^y()|zKhy-vg<YUm=}MaV~IFqfOoM=T8Q%{g05c< zdB+H?y+PDrMXuZTJ`I)4|E`NhBaZ(1H9~Ik1k1sY$aDGFBErA30lU6o>I!c*-?zUZ zc52}A*FAi8`5ig?<soL61q`{q9fcuGb0K!7<7?wz-vlGCCCZ$?-Y-daN1w7=8Nr4C zYF2rWAN(e8q!-W0KCaU=AFQG9@(DK{?ZdxSY1Nd|gNd!%{M_oeN8cVie&a9)J99gP zrhgSa^<naoDj7n;(W&L}&aoweXTRZ{z(c$?kR*h-JJY`vXt$BL&CWov74p2X4UyKN z2-xvvkv2`hbCnb@mn;~|>bZYcd@Z=+M?v;;-x4mtOPjnJ#HjFMwrXj;e0$^l!2UYH zR$?qe(DoJd7~1xH$SnaVx^u<e&-}o3uL&FZa;m`kHwT*NekJQ~PjF-1c>);yd-=DE zHF_rXt}WN(6{6TXUy%O?&{Wb*03|J#lX=VrRyOG;9_4eNtaOlP7q#w}Re+mZwJ0TW z{G9+zFwy=B5RkDwdws*PQ8Oyqb0AF*F1Sd_2O%Daz6>KIVX(!3)H(Yv(LaBk7O|k7 zVF7bzT)iUwf-wJ^wHkGr5g@y`_uL0xyeDmyj*#oFSjpxq=GEe1tt;lGIpJKZWX-|p zH@qqO!PE%a97yJRAMn_{VWTS``8_;Yfkj^;8X9Sx+V%A7>!xG5{L>NGV~b_qO1#^* z`xh-vRn2XE3ROCdMr6&G4SL_^dARmw5k&2e3QeAn9~&jv1-eA%7>%13H%1yqg!h?? zW7i)bqj@#Si%nL9o-rwmz$exvD-TkAJNnJe>{1Y7wN<lFwb%6IG0E8f-oAAYRlO{? zWG9xDJqHq8{;hUe?cm(<y`<P8xw8Vz&va`G8#OGoyjUxhiftI%fuhsR$;s*~a1{$# zoK?;!m7LtU>qc-7(wa(rNC0oR*?!t<uN+#wb6$Qj$I^TJLZdch$%RHC{g(O6$*n_F zMnYaN!BuU7N6~lE|7e`wkpOuhcrbu0k*>ehlt_ABt@Juphy!mi>HTwuf-qJ1FOUnq zfw4C7E!x)GSJEiGa|dRjd@^t7r%X=K|M4?yUU!$iR$6i&o|E!XgZTU@jQf;+=j`8O z0B&w&Yi{y6IJP*Jd4<45i}IE}!{xcxo6wxnu&>Kg(zG@yc}jz0KZ}~4sgt(txLr^j zzIh=LzYw5ZYDK4JuVKFUQ=sHo&W5pKGFzX(G-e=jj^?1zpU>j#wqet&*Oy^35n04` z{m~ZgL_my6J^S=0%A<Vt47C>K?gNJkw$JsON9!5W<Ad;F^>0~7xPHBatl0zo&`?i~ zCmGVWsh7G;QQqr;)E5ouZ%H8e`9qgSF$dF}bGA9d<w>pYyKp#x6JBJ~U(VQO8gt!E zO;Le?ag0*JUv-<Rw4qX$yBh~n{W(#BHz2ez?xdTJhl%Iv^PEwHOrgN7cTww$w)>`m zu;Eu%9(S+92w^<1X9O3nCdtScR^-#uHKjj6>?zFbBm|kg;9J0E^I7tr#sMgqk19V* z@U#&ox$C?oXd{+LJ~!^8I%atfVq#yD=-v_Rby>~rztv}gCfbDp9@={C*X|Q)By%=r zIIB~o#uL=TC3)IZqGL_xfex9O;w%osnU(BOPyUX)n_HUraIgtY9*JTi|Hl)Eyf-aE zW3o4$kYN9Cq&NB+wsAPG-(g8F!aEi6MC!e7kNVsl@X7v3-o_cuvUB-0gRN9)*cEF# zcqT$z^3A=!<C+bm_Whk;ZJx8~g2W;hd4v6ll;8KGfD5kw{{QKZJ_f90CM`<znmV}A zYkq%3H`ao+r!|+@>Poa;8g)cB3_kUmuY1RVd+N3k+(YQHO`yqK*aq6}YExtZZIkOs z+|xNX)a89IRWz~PiK`QqKpu@8X5i>(K4bkvqfLoiHMSO};jr{u+~!PT{(mF55Vdj7 zYAfJze6@}KZaIG>miy1)^)^R;jneYA-0L%uoJRZO)R}Z)3%+k++}6DQH$~5f+QF2Y z(+@wf+df3*GaazH_a^$CK59MX#tV;bZ`*egd!ZY7>B0#;2_(?cnc#fRefb*u!JBBu z>h{V71rs3Y+ySgo1Eyd(zg@rRN(aT}AeH!Ke|CidP!%g&Na$GEpR5mB&}iYT3njvL z(Z@#XQlZDOg6`UEh?7L~YiiET0)G4OBydI44w+CSM#B4&eB<>r(8gqt@<K`G%@8u6 zi_16inr;m&l@Rb^G|2AD)jQtJH%E2GQ(Y~YURe<-qP2%3ik{Z3Z{4cXydPVG+AP>A zdu9*035!~K#-ie--_l{15chMSIs2c)ZSL~LL_#28W0i#R`KGji4U^X%M3*SEbj9h- zxBSAYv!YkmA0737L~!2d`#eRP=N%o&`GPfTB;!vq*N9y7JoLw<Sx7V+>T*RHv|d8? zy}$vtZbfAs9Em|^*F)p4b6<6stWw7-Zz_y6wuc}qp2f4nOBBumTKN2Z<zBB5?+{N1 zBy@&`_>aRkLU!Mq2rd`qdYC5q0)a0~8ikmOR^}r>rv49S{qT%~Dyo|@WWL;fbN2a# z?~i^GSi>({XyUt3m6(I5)-MI7wgt6l8{E9IsubNX3p_sZgFJmBJR5DPix0nE0Dnoo zv!?dBp&ijSR=ME4{+69c6dQZXz@8|^?GyL>GNs>$lgTYEIB?KXQ=D0uN&77GA+Eo} z&!$!KgT@7~&j@5k(C4W5il{%J@*6udpEIen$v&8H%Z2wl(BWej04GxQF)2F5O4Yis z%~!~HV!``$A9I@J?IvD{;^2M|km}zT(ZCG>nQn{^O|YoDK+T192|_pO<CmAbDM3ZM zcUHf11m_5E^9=Zx=7)TnGJUywYIn~L(mY(vJ+OkjCLz>u4^wl4|LyB@s5kDk{Fb)l z=!MGPHzy>kO%2a*KjXEy19~r(X0Wq=*#CXIYE{hf!Gb3hOTGm}YMh9DfhBQB;JIXZ z*f{Nk{kJ>#C|x156hbxF^TWa&+W;$}OXD_qJtz>2fnk5@47jfdcK>6I{CrWFHrZmq zq^0WpeWU@po)B&-ydi<xj=i*q7H|9<VjtpJ-UCQ=sUQU1h;d$TyETX1i0W7J0i?!2 zV3o#tOx^s3lnI?c{#fUsh8v@Q<1sx78AX&%8xIyOSk<h1cL;SQA1Ab~$~ACkcRfhW zWjB5CD)h<s!SH|qN!1r!m^PW-6y`Y5^acH*U6u@HQg~qkMAg`0zqU!X$%0wWHi=Zw zoUzz1z(xC;#&PAIHSLU#wUf8U0Y<#Mm1EnDH=|njm!P`b#<LJ(BmH47KUj9GBs&;k z;g6y@oYpy?k7tPN-}{9xGC&((n^a=b+9rBev~6j)Ta+Lrr4GvjU%cEj7{SbA>%&LN zQh_4MaCL=9{Aqu5`{)t>MrRgqE$jqF+$0rd-G9&|xiTV9=4E^VRV?~;I->{(7oE_c z{1kxjcT7tp53L-_Dj+FDZjn4K4!}i`$4_)u&D0h7DCRX$Y930x{Ova(ts~_MXTcB9 zD}-y|!;R;K56#kL8sz^{lUFILzv!zf!#aq5H>-cR<V6=ZA?2YGd{T>fN|i?d#}@r~ z@$A#x8|i@1YM3sAiyU3xGe}4$O9xXH3!4e>LtMX<ej!~cL6j*)g5H4Ut!}bRi!BA5 zeTdSgN-JUq@S&t<)PukDNn*_JCkRUM>BIDRs}<Qh+$%L)h|<fP4wko}hMPsUYyQ}W zXVYm8fgGb5?zaqLO{*0Log<$;&Z`Ue%w^SQrmp9%eJ{_A081-~&v!c|sBwuZl70S; zG+*_d!{hsF6`{pD9-NFN7?>Uyn+)t+p7hJ}9r=Km14+>LM{f(Wx97J)n7N96wLSyd z&(CY)&g)kOI&N(~z)92EV>Cmv2bvZ&foh->|KVfy&&8;&ab0J`wxe9Fs1l;2coR){ zveYIZ(@7L<heZVy^7K78llZoctHFMY)8h1bM86+9*VTYh_czy8OJj0=&aQ}AAFuG* z_%Q$Qh&}afpeyI*jCjS8LW##x)Z#5Qzaap4eVcMiFZ4X-2fcj9DQH9Jg>ubHIg+v5 z1_B5s-?{zzJG}SsocX}k_a@rL*_X&dgWt?bZB?`yY1i+D{6%*poig`T{=)F{N{#<r zM8JXNP;u8gD@bBfg5irOBZ!LYpFb+1D3c+pjN{_5<bUn<q6)@AjBk)p_c&)533SE! z85D(NLIZ@@A3*K#tMx87P;O9o4TQHye$NVrFCna)0<v{j4j2UeSi9dixi|AJPwKC9 zIuhwY5gHvhtK97bz)(ia7~iwDX<=YO3*)|<Fq6WPd#w9<Du82gz%~vDyvyjA7f_!T zP|waa_SI?7v3~bUr<AM}xNy=5pl&Phi>qxW$CrD$EoqZ(yOe9##SQC>b&Rz08f0EJ zpI!`6*)>HsgAV(+YkQV=5k{32VRHF?aq2t)WmG{2_3P%T*9Vjji=;O1J`<mbT&q_| zRiK{99A8=ctN9tH9-^ezwelr_?Sl}fyZ^Gj^fjEP1*p81e$ju;_FZ_9z)-@NzWV4N zU@ep6gukJM_DuCTRuqHM8;j_%jyi~?Fqknx?<LNjUE$<%I#Q(8FSlbZ#6ufxm);aT z$2xn#6Oa$STSKCewYym0&vD}Z-*{gmnec5H7hO^r^pcQ<6C8>LT1RA|M+#SIZCVZ7 zrXU8wS>n*WpVCB{5xkbn(MNQnQ#Gmz$qBaiRzF=$3fadYhq_K!u9uYCpIGsHUCUC2 zX=bk62nEk@SxqrG=$Dg*1D=B_mrD3C8us?mgZ%yaO8t+|Ic23DvXVFW*KfakYBxHE z@wX#=#*mP((`dLM{yEWM3X0fWrweuMXdA%Y$3KZ8oVr;VKt-(iM<acgS<*kc339e4 z;W2iLe8YcDx)dH+_KbFVZ^45)oZm3g@n&-P*pfJ|z28U4)bpa16Zc<<<EQ*e-LlJY zKs1PasVF$bQ%%fxfSZQ<&MOB=7y`s#!6VVwee!fF`zGaP{OeQTKEchX-0d6atnsHX zM@54LoWeXM^vH*cEEIep#JZH%bXskp<oROBb3f<joeO1~mAeY5yF3+Qd`s`}XTH#< zFR`$Awqr-a<W+MuMuL<)RHQOy6Kz+U{e<MC)JdC;1pzbJN-91tAIN{kHgr^GjphT& z`Hn^ZG8f<GFpcN0PE%$DEju2yLJU4x9?~m7_5kvb-*CwgV~V2w%*&rDm!DddZTlHu zz=1Z20+GWXvZ~0%GQCpU23xx@t_4}PB2h;Qn#Iw;#jijcs-yijkFWqhff8z8^npe? zsFnI)Ms)9~Pg8rM)I20gVrRMvz`2)0E@8l8yjC*SfH%zP@bvo6!-v~c)cT)?d#gKL zjp-mfI2{4K%UlrN<-q}jnga31eq}nrT|?Uz?W{?YSag@smH}o@{U-`BZ*0*t*gz(Z zat3*z{jZ*`Q!~z$(2z?V`S}t0lyaINY6A1OC44)^cf6u(%1w7o`UeuzNY_lF=K2oy zD_#zbF8g^B1*%B(uo98(nR&1B1c&$!oxJY~q+=R5=^%!N<h}7Wd-bFLJM8Iu0d>Yy z=$n#o*!_Vh8+XvojY(Jh2Ns&UHI{qPp%aBjAg43J$28yiDoi^PD0F)ow3S!{j0C!F zHqqVFk_O?J0?Z+qlIDR177r-}n7kKs&-o$$%i51Rvx`u9{ZfMLeHJ@pV`cpgeHyLi zylf~%-7IZ4854Q8A(PjWB`8r-!c?Lbivw_x-HH<hJ&8s#iMsG8+~Z8J)lkTU(kmQZ zpNpniTmSvUV8P9JJqsL1j*lbmBr$?h&Qcv^Z|8EXj~WUfysE%xSlPc=F!=(HG%%Xq z?;<B~ePOXEJm|fEm-Nbcy947$%fJqS;V{TyC5l1&?CthMEu+DN^r|o(H<U?}W?1@F zJuzBC?L+?;m&B#-KJ|bF1>WVF0wE`6%5!|u#^QxFy3Cg!dZ8rOS@9H5fvC1{0)~#k z-}P^7YkxUpswQ@SvCBP<Y9JYrz|WyZOz~x3<tpVH_Na=oJ0dzib^&cAdSKf13Txpt z6|!_vG@f4@92`=}*^K^#Wr=nQVIZ_gJdR1lx_eX;{4!j67$SSt2QJ72`7U&Q!sg{# zLyXD#4aI0H`<7pQgVw!5lk~p8e--UK*6D0_r6#k8zZ9A&y`7(HV>2enGbzbapd8gr z=7o8dmq9Q65V>sA81)rlIYa8j9?SgU4Vd+oCCkTX+FK9GR^aPSvBmuIYL?2M?gjEg z#VI;r-nO-|7JWOs3X31Ef;>BF>8pkCn*!VY*`dB$KEnmdFQvH~-vn8hsC2ySy*;w- z!@aILCB!#OzbpfpjdT=OXrmf#K6|eGxf>fx#2o4)o&QFOJ~i-^irsqDL`))u)1q!A zDK>N5PUxQp7KI&BzNlsUX5iHR)^g>?Jxsjh?ejCX`_E4+wKri|p**&t>><PT{5tU& zaQu|o=SNN7^1@M-6OtvFh9W96OG~zTAh&tC<f7@T?8GAVV864X(CGthJ^I<3bL9!h zu;sp$v=IJzWOpfhteC6xde=oTt5VWIffPw70o5Oc<4ocR2bFG{A*fpI@4bb(s!BaC z17ng$N{3%E7AmKboZ0>%=m!cobE6e|JdA<=UCVEzDXHoF`yq<ME8oPzGRo4_3~taE z|Jpm0a;lmP2);}0pc$>w-N(T$y?*5LZX(BZ1M<iu3CHQ-3BZfQ$3}u^y1A^}hTQUm zkqO=%4*>~aMDD9=+npMr_UtpJfLlk+*OfW!1C9%p-=Ek`%aeRbQV7|3s?S#`HOb19 zpk(@FQ{i+!qt$))<gs`CII5zVV#4XJV0P8H4q*)wE6jo8f=2OmeUnom0t#y+*BC5g zak301-8dPcz^@-9MPOGA#i##v*6|)mi*H)9zGT@L=GZJB#S#I&wGsEJ?v6~)?b?<c z8|G=-#Tv@4CjM$hxUZV)QK@{=op-Up>Ec{R1TVtaIL1t$2NBLCH+lT|as6?hSk5l- zR34G$bD%rWKUdh_9q^%_M02h%cNrBYDYqWcdS60$uonwi`}6Z8r56|wgtC#ki!SoB z2)P4jU3lHG!Nj}#Z`_u=*iq;y%r6>g8Z6Sl&y<0tW!Mm~uI}qHb|woNd+<N%N!)A1 zDj59W`+&{?|J)E>HC=($3^euL@}()yL)P9uQ1#i&i|DR^htvclNHe6*+EfDm&Tz46 zs05rrCb<-R&Iiu{Ir2}fk`aGYj8iM^W6pj6t3Hw%zebVi!3*sl_nkwJYmwgd`|kZO zF8ci63<H<?b4{vi41n7o(V4bndi9sQibv6qF5I~b&U%;D$~Hc3#Zo*c#ayuqA`0i= z8HEk<7=vin_gmz8{XvGqGYPR2+=t3MHo14!?OBY7Knx7>@FHoOSoM&xgGpgpEwf=j ze~l_J1?6&n>#ASl?7{le2gF3v2OHro*fk|Z5LVK5j3`GZfelfmC#!mHE9Chi5BB<8 zC<6uyn&fE+_H<03*o6Gs5Lqgu_S366VGldMZ2PjW;om|$l6LjCOHxm#Pv0D}0IcXM z=xDC?ZEnxqF4Z_`4PP-0vn#$X9b&az1dRd|lSX!{#j#HDw<J{kS-ILfS|2h{2SS0_ zxS%Q=MA~NOzUhgNWV(=Kx}@&xDUU>7ZGbPxA9Kde_R(}Jxf;cjPRz)lQla}d5|x(d z&Yyufd>4!z+d=%O`B(Z7`jS6)o(`?v4`^%ll6<SH$2K2!#(&4zfNb5ee^u#sPWbf` zWq*MU@U(aN<u4i}7P|Np`>A)%duF1^7ndgjqBC(H6Z_0R$mo{nHDeF+JQP`=2;08E z^cu7j>w-y1MOz{6YQQ?@fJZ=7CVZRhOF}Hc-$bHDn_u6Vb4>mT(OI>VdIIf<oZtbC zcgLv9QU3Y0?G5AwWN;%4@YT0P3IHuXrN%M8xV|^Im+OZOUDeJW4@Mm;DXqcAYQ8s= z3N#)z@rNQo`!_cvwI;7N=>C{u&bD)Lw00WBDdC@ywRN*9J)bMO6uayBGk|j%f3p%? z@5FH_=_ch0=s``e!3(>a_6vQVXB-qpOv)-4kz!UxS?41XMO?Tg=VgsZK>#ZBbs}nF za^*ZJvv0@utNHna;Jj?`L17lmPaklOJSZ~zzCDT}`_GSge=>>Z=P=p*1T`^b*D&4u zk8B0`Pd!Mg!S=bPj(({;5mB<<tH|tlC(*)x@^&0Qr?ki@+FsD0KlQ_wGMITOEX-uF zqN5?0Kh=p|zkY3eO;hIilH~=p=h*3DyQpnmqfTs$M)Qkt-}P0$^+yr{6-Ebsj@Vm{ zx5Br}cO3K!a)<MxIl>OsO{Ub|vOP+eB*7}jZaR2)E7n&lDwsg`*HY7gd~WDvV+%6+ zaLeT0b9~*>u_KPJ&McjswFsRz+pGXTlJusww}jkObAAjpV7Wt!JS~f{lwV@HZ?gi{ ze-6|iQ1^0lbCj6rKjD*&$x4lV&BplFh4$=~XQPdPk(6`qi5SC)Aj3)89>a0#(pt`X zmiHPqct2$PsrMz(-!W^(rI-3EDKGK@+JR1g8rcQ!VOzV$sL@p^D9LFGt=ETVE?PJl zn0aWShfR@A(}d`06c}spMyW#Dt|LVaAN8K(ZvnBbW;KZrx4mFkPJzL@VJ8r9x={ZV zzOZA3$zZCGT2Pz7`K<6GgVpa7mm1Ah#_j1&w<?rez7+?nI<d>tX7H`??#1_UJPh~Y zEl1<tz%XGxx*$zLZ!OC$`q+~<yWbs+WJKgVv@p%{K?iXPb97!qJu+zm2FKGe`X#jb zB@4(ED&=n<*?4=)IeQ5WY8+OAskkjjrbRYLy@CiCR%rn6+nFngO*GHN8bf@KAbg?t zsh{oDRmgF&L!+}%K<wo&)iNFCOD3Yv>r#o9!;bg6j#>@DNstLd)BV--8Qzb(AH`LW z`vA9}c;LGpnu^$;t#T0PoR~b|y9SC(5jBwoLm$BL-b!)y1wF9Ae}5t^_I)`k`%ug@ z1kPc4PJF3`ns{8!c4blT%c904*HiC-?xKL&2WxA{c%wGpJG}4{sj(v9=i_1>ia`JJ z-D94TrK<ayc!mB`;_;Dm5PLT$Vj28dRh5w?p;X4so`pDPD;2M&vlB4EG(6Myi}U6W zTh8AP@18!H8+qQ+*ZfbT;bwmhSfGN5%bt8+jsMoCi))e`8wIA?qPB3^3|td4)uu<R zN#)%jbv&{qD3|@*l5c@wMF<G%gfYyH$W&-=TcuLkjYmV7<S%^^*!zb^b|&11(cZT` zdZEPh5*x+HK|Ri%imd=UveW`lZM*sU?)|UanmMWt6(H*`Dg1Q!RA-0SSB_y|%`;KW zi$gT{9|bc^ykglv*^)<4lkXcl1%F4f!XkTO2o7F?B$iUnzuLu5pqRSQq4YEJ;fJi# zFM-Kc7<!47@q1+jJniocQfW#R@-p`HRd)5KH*uTcUvBNE){nv0#)FNdEd026PthYP zYd8d@{DZ-qfdvt_pWJR8#%?j*Yy~b5XR0WCBJm-$KBZpzZF4x&%}4X^UE<p;VZQ3= zu?5@Z1Tv<Blm+Fl%;Noc>gX0;u}dSVdIdS(p1Kn0Wi~UIoECkRxfhOY>>c4YBn1iy z?eo}0;QiI+IYDzUITK5a6Q28kW`sa9KbN62$krg9iK@|a`-zRaz_OMwSC8ynOXSy- zsJ37*!TW;+@ba?eaCgCV99kD@4!iKM0dVoZI<<lze%O3$FB@=@ovIm$RydU~EqdJT zk*_Jg;%5+OOPCJJ4%pO>E$N~diiw=;kUI5a0$8!SW%X}A_B#zES7N)_OUf1gVl5<g zxA@cX_YGC<wNl5TKWvA1-X@#o8RPwfL7KlY9n+ejGh&vX-s|F;`H>km@3r`#WU&5D zW#%%OC=>V|JNs$ivxB>;0A+1so5xM22AM|&Wd~98>gO&~(&A}%=G>JG9(kL}^ty?W z<+ISC?9m3cN(QUP5gJ`0BHi*{ou!kTPwtUC6-FZ9-M~?wj?mUDWUz+eI<L|CuH=U0 zoWxuf62n8{x!As$`p7*TiKx2Y9Qrs<SNRX*;n-*ZsFWJ<>7f5_h?Lp(ANfr`ztev- z2=pgdig9r`|J9@sKWfsFDT}F@4Hq8?c1%&p$>h-y$;rw8M*Dw9Yeg9p65H%kU2j8< zT2?ebL>TlnM}5}4bMf(=|0*~Fu<3%uPGNVy1M&7pDFV3Y*D)pbF11$=-PR;Im!f#v zB=r9VmAgJ*99TXu1>FzKTk(rP*Hv#4Z9<1x3p~lLq{A8eo!)F<iK$!l^kRr57=d>D zVEzOAjpI82QS&{ditgEahUO{Uh0DrS`h?v)q6<K)IxDHwb*(1TAqYs+sECz08l=y3 z>ZgkQ`C}MqgCXo{Ou8SZyn1`1NS~k~ud4%&bv=D(eBS1i_}61mY4l3F(kZAjjWh0Z z3VRu%4~{0DztkSR+HaXuZL`d4E3RZ${|7ot5GzE^!ogKfjl|&MTaOrldvwr^7K`50 zZaXgzzVSF31(53=ZM||7m3qbqDo!hRZYI@he_$_jHb&iHxHDJZq7ojZ(FIb8AJm)O z+i(2TeH9z_uFE>oiYnP3@v)-RJ%X0ipo5wJ2M<IeOp~miRGHqG$SEO?kCRb?+QUUq zP*9vEjX8si<tTRVS58o9QBhFj;~D!9HS^xD9*5}yciNX<Y@nr;A938M;f;y$#scGs zd(a4`rx5*@xnTz$VZfyqvMH`z<NQN(yRhLprtn3pOoMloUxM_OK!hKc@)km;kF*+q zB4xfLVX{WU5yZ&#QJ4k|c?>}kh$`wdQ(Qf-CXpPJ8!Pxh3Y054skUdbg;OOU2O{-M z3HLt2k1MiN5XFdc+E`)pIlkPQC`P}YE&LM*(86;Q*RY5?!=XMf{j6}q6e~Wsw~Ly7 zKfl{dK53iQd~^Tu$*9H$-C1zC>nUl|-<P^J#7O=|<wtDT;^tD=j}db>e&CBsx9;2P zmPvJpcAo9vK_;bD?)kMp>M}R(o6{_EmO{6_HK9qXZ#KATNwV^M(H8(6N}m(d9cp|o zq?^;LBltB?NPJhBL-%+X=5KmeXMR7D_PjDu<TRV`G@JWTU@<}ZXJ)jr7j5HY0Nssu z?S7!U0%E&q4GrS$gpWHO1UVUQ4W-Wu>XtR0J>CMNvi-ksWp%2Dy(f#rGoWvy^~W~p z=qXarByG#gqy=OcJk8mV+51)3;EN=e^gaLI=M;dWJRF|Vm0jmJlB8<Rg+`2xoZ;?a zb(mP7qiv)2uf^Jg93)!ARS#d(sIOHKBe4$*RE!DZTttob)RWb#CTvxVC6F|ZA~)-O z#!~a~(;q;zT>)gzPQB*(NL`X{DhjWSN6LegcZ0q+fSp7s+28m3(1r_o8j08Ri@F-c zW`an?nn{>(j(O>8qzE%JLmA~UTikF6uOrwQf`uO?;Y9H{9wbJR<I0R>@OfzufhkWa zp?ogQ${-!aQ*l1{jGXR_2DUMeJNcBYy$ACCvs&N>ZXk4RQ(O2jam71#wwBFg%fW*o zB3D1N)@JZFT394kslsbWRhAL-BQBL`cUwm&XiJWm>$6(xx&NY=ll8ZpbnYx5s3<b$ z-A^7!|9-VESYPB?WJlFEmw>W;UwHf-m(y8GBjVe9{OOI%c+(NmZnj5d<&fbW;+(NA zzzIG_e?U~*lpy-CZ;)npTlT-x10LrhO`liG=4ok4Xw>RW!|R!SfW}-D){o9wUV7K( zW?U2oUle|;1#TWb1=U|a5Cr`fQGK;UdJ)=-5zbZ8`f`RP*<!YxjzXD#+$9(FO3Dq= zOY+YM?l!R0x4x{XAO7xN{6a$z+Cv;oPoWTqxz&hAqNw-}kK`E;;~A=p+==1T-!FG@ zL}BS!lwP*#;nis?!V*%&tP#obidXT5vpLFfrI&M8p}<_9^H@58+lSN@|2-w$37Iyv z%*q%img^$<yc#Hvaz3(AInZyh%KqLtd))*Cr|u13X1#9?2WAAD5}w+>&&bb-oR-Ob z;?CQZrzon{xi6SI56Ry$l|QW#3f(SMZh31F#Rrz}&oXoRL@fEHjPiw)Pw2W5biiL{ z&y4Jfbv!jcIQEvW>F5>d@K)?n#oDy@%17^&8b2bhNs)wKttuta_peQW7!Kk`D1ME~ zF&T-sHe%O}8?&ebzwalB_!qJrJa((xydx3=yEXMq0?&#a-xGQyycT<d(4t4%^S@SG z@RR)Fu6ol@x{r6kbXXW^OQ#8MNF-=ZM6V<*IbBA*l##z%x_y~W;dCh&rJODrJRQB2 zJ#9TwXD+l(n%Wdt##qUm*|5U0Kar4WQ>AvY!qS~7sJ@KnLRC9%YY&As)uW|nu8ZaA zq^OT395THXKYVl9#G~J$9meoi6#LZV>=rpFu!aceBCn;T0GlrZdKxoL_X(VQp83@0 zhpua#7>55Pe}gM{H_>Xf<^ANWci0CKxE5==6cFy)>F}jSmb8C5g7JlL;=xnW1FbEW z6R*y#){j`HtshtK?*5Ofw}6VO`@)A&Koq1EL<WWwk&<o@kd_jV4oQ*j1_h);32BfV zLQ0erh8}w8hJm5G8JJ+cd4KQw|7z{EX5BmI+_UbQd*+_ApJ(r9e>pc>#B6SCii%o< zw4(NhG42RRXr6h<*~Liw?d$dLufAx9QMvhFbuQhwA_(sfRxUKApi>X4Oh*zWo!jfr zi^7v{C+XllL8gPF_By8H{?DJvdiwVdu`;*g?oIC`o5zNcg@Y@sc4NzttBc1mv|3Df zoJqB@WWj`Y2h@|qzNVL3+2_j~Eb%JEw?aQf^ZOWxrO|FvII-w^QlMCx+g>}>fx}t* zS)>KHlXbwR3Bru1>@C}L>gvBIjh`JHnN#9wQWk|##3Mdpy~-esSW@e<pURh2M|xsf z2}3vzL7nK}P%gbhbDclS_?w6*HH>x1(TDzE`#aafAn`5Jeq9OXK<Ow+gYDY7Ud(z? z#rti|EW(=`IP6LL2XoWk;Qd#laeKFnOW3l$qc0HBi!Rq=35hkHKY5+d>!uRZ8|<St zodrD5cG@Rh&YGXnUy%k>c|}*?yRlXK$on4DK6EARYQMh`(rv7D{rZwaqx}74G?Dd$ zC(Rm%&V}UP-*5ezpU>}0p{z8F$9xWdjL*9Yx!P=tm->DrbibqkVbW5-Ov>gDuJM=# z<M9E2{C`j>v4{Q@pt;7Xli!EC*Oc&kq?(Tiq30|L2v$do%w(#2)}Yu(kAJ1RnnuBu z<I2Yhf2CRONOERn;rS>>R*KZwI+)$2>p(D@H;^m5iDA>lqWJ2*#f4OcFP8Xv&ZSjq z>AjcJofslc7tynJsQZ4tR)QAz7Io-xmrrrUw;U1FLK(H)diNalCJUBeq$wK~gp}G1 zPC}dS;QfM3RFZ%h%OBJnmEqUq;c%!*Rw{E`L0giu{B*Fy?fED<t&Dnyy@c<aRv*hY zO})wF?|Q`Stn8Q5dGC=hPpxt?O=veeMd*=Q{?7~5j!CtAwClw{y%f^sHfKcs%dcV7 zcv`i88+JXnfH9zbLZJ|iOOeM(qP+XZi+>``;X<$d$o~gDKEA>ig2)&bHWvrEj~pS7 zBM9tK6NX|kh#<~8Y<g@WY)U;AolCjQBnrJ#4<38(_IHhn%PblUO=-r4-S?dsxcQ0m z-UDxr&RdTO5_egc;_qb}%;(tF_vPb+x$C;@(qy|W9^Yv+{G>|-z_af{h_1Aw+mX9V zm4Lrl;rWkGjGqvhNUMzb{e7&MiS`GZ;h~rPuK8x~Z8zSdRX@`_jqNvaCKh84*A+zl zx|}9`-}bIU&=kz{vnHp>oS}WzZ|OjOPd>%+4XgI2AQh%wf}T2M2J&Vpg2Oy}9il)j ziLv@32{P|yLe1(Tf49GhTbJLDTN4SpO+UA<w6x9$RCC~Fkf*tfj=ctudiIUm;CM7L zck@*KClTJo7if+5Vho?yWb!VND0OZYA$pH4cki<zfZCh#(2~A*n|pAwf5U-*=IUGS zuT4iJp?~}vMpgta&a<yN1{I*E5%Ag=5mQgfIngU<x*O&ffkLe!5G<fkY(@wx;`3H^ z+mPhVwG^W#9i!(RerNPj+$rnjH?<a5o#41&-R?u5c+`ER%40(aGPfY4k^m9Jw8OE4 zFjmF*SYskj_d~XKTY>3z9v9r*d?vK(d&$8xn>uoX3Z6#R!)q3AlY$HKK1#CY$sWN1 z)#o$<yv1gofQS+`B&E!wHt48mUY}|NQY-d9H~&nNB>J8Ci+p=j=C#f<k$_Yy*UYr5 z*vIb>&Pgot0WzDs${%PIia$%ZEvj;=%U&ei6hK>}j%mqdQ#W`pUoR9U$TdoU3s}dH zvaBO6%-Ga*0sd~(rwavY+2dJ!ykcN-hzgQ<H)=u(gbvY|Aur!;$6b*Clt>P_uOcgS zdY(5!P8zaez3#5MGC{5?dtq@?@E<;E2z8{Edz3fgS`xu@wbdCO#j>+Eu=2*r`LQv@ zN5{u<90P20O9xK&9KtVD9=V1opVpjg6!?;#u67o2$OY{3(-tV(r_3)8*m;X`7E{?< zK5+Ge1;YON3!Z;#-7h&4&ZV@{Q&D!6v+Ia;G2pCbS}yb>7hoHvvC??kx^(xb{~QXp zhzu3Kb+D4*na>hBzNTfz>P2J2HZ0tn#2X*k8^xx?^al=R^0iC+og#%qo%Y}JvvD>q z{{||J15-(Y?@>9(*2I$xWnZ|dYBOE7#G#nhs6t25pANTro6Z5IToaNT2#b-+XX~3* zGp?{ISVzdbgG|UGID@R*9uU&mp3%VD2`dxhj8X3Fct*SitY-`^&-Yk<Fl#|^)kxpN z^yu0;*Rv(c@h9g2sY*W604~Mhr|=ks_-}*v`g4+8U*$MgFrP3?mg$S}l%8K2uW-W4 zM~lxCQX6<8xgvFQl5Odli0QU8$$rIWxsjt%8|!$a+9+`j87lLu8})Jbr6@GCI#>$D zLI7;Q(mgmnkn3A<R){TKuX0#8m_@ab^elN@*BAtD`vlTjoiR2;f>z24BS=<IoG-J| zQ5?Q(Sa||1Na%w%zIm~@lpw0ENG5utuku^MKNH^cC1o(b(RR(&2Q>qQ3ykQm+*d;$ z9u_ISTu_c{@zQn*E)w!HXuEv9qVADPf=q2HjG83l_z81(&)0m3_er|Gr>@!>@#)<7 z4A~iJ0J0(gHy!)y<peQlu2fTzOb0b|fv71#fM{K^<wmSL`K8tya$EFYHS&=JMv1op z_n%7(onPLHk$1RXXdlng0LiV--UX=aGM7Ycy(MSJ&0riv`lm5w(Mn%DeJ)Lq%9wQ% zkc7gHZDYcHhlq~<pUyhu34bl>rxnCyYbF%1Um2~+y5+AS2cVoOt$9A`YHWP1taE0@ z{3}MeFG6FlNSy`+eWMfF0xe&P(Dm9WT+J(`o`$=mK3sZff__RrDYL$3Z;JiIPq>j# zei5Zu%SjUiU^rD?`aju9T5&i4Hve}1ZAq%1;as*fjZVENB15l}(NwzvKBBqcAo<l! zUZC~R{57H682PI5e2P7J9{N!jt!$WTmTEq~^R3X{+pSKa%#)CsW6Tz&bdo9Jh2?er z^fc+mz@p=XNYSjd>Bexkqt<B_fc)%V_hPzyzI?QwuP!}KB57Xqw}@;WDO{fluHWGa zv%tT-BnTzEMj-|xxLtfDo|$;jL}=Pe#e3#Z*_$boa^}phA!f5bc(&igKdWlPyHyJa z{=<7x<8oO;1XXNX0C-Z<lUWB5dc-6!3}=S-EWxK(N|{1E>=MLmXNKq+`kqmuyDl~0 zn=kv03n~^HRF&tFHY-5LN#%fJb3LsW&|2uDKTMi&ZfVEjH?54LtzqO5*IzW`6U*pU z{7nPUYYsgr-;*u4`gDgF#HW}%yX>9fXS_>$9U$=E%arv4e!0#&^|*@kalO0j)!Bn| zf}{<42Fu0O$?u$_@~k!W47-=bsjfu5a?-%mzk_ANVEf0)8i&s3qx&{NZy6H|8A)B@ z=dDHptAisnp4~+}*xc9cRCc5|IT?FzFLGB3Z&{@N^knPp3B|Alk9{|}tSbZCNisY5 z8tKwfda6(4{#f(76_~enl-O{4Z$0O7>Hc<{J<TTXU7!5S@zSSroIa&fcgc~RiO8Im zsUOcaY458X-r1Vd1!k^!5_b`dTGdm&E0c9rs(QI523riRairuka?2hiQoO8n1Ruuo zW%;6!<S5krE8i8&>k9<xE=GEl>`&>coGK|e33IzBUXsGV;r%vCQ$m}=!efTd`)#6T zBwqSvP=>lefKSepzC+8Nn%QA~b;Y;P>B+P_Iu39Btm?#)>MM1FF3Vsex3>l*dwZ|j z$(sVONj9PBGq9{6pxY&i0ltCybl|QwrHYe;yanUNY}~)uBRAWfcYkZZZ-)6-nC)MD z>Qk=J|0I+C;!&}(-nmCptaiWW3BH3kr$^xw+`iIsw|@?YOnp;cty5WGlNQ$57kQ`K zW%P^1<OTrSm6;Z{b`m{Oc6WsYO9nr4=3<~P<8bE4lnprqJbbpEAsR~II=WePiZ+*E zG=K0lIC8;Zm54I0X;p`uAgd{rGMX_<Y#Y9Us4gIHTn!I;ulWS&24N?F$E%Od#UMI> zcd8^q<`E~p#QwEv@DD{&a|2=zUlreBL$8HNHF&hAZL5CC-hx_|@^6~<(0Mk)eFx!! z=Liiu$wYyu^<UvGjokS!y!l&U73d07UNEmQL>^UJg5Xxas@a()^`GXh`4zdYyVlQ@ zYu-j$Ymm#n4*eTo+{vZ!6r-9{);{|VreF#yVqXWr5-z7Cw+@266Q#zt1|)N9_7FXa zrqk#8om|Q|QJCNU!Ynme+mDxtrjDkG{$Jx(nFmh<cWhx~3z0MLU=}!#>gF<0yoFrb zLb-?o=G9&Sqo#G&hZ+#p0KAW2{+Iu0S#_#)zkKp(vYM<-B`93x6Mhn-!R4wV#p~0# z3TN8qhjU@m+3;TF6Uv}?2H%UF@giklr<Y@EeuL94jmW#(S0AWx!Bf~xYvzcr3_8Aw z)31dm?9Y^%Q9Zqj?PZX{hDmp40iLgu9*JMuioqz6y}xf3!)76$X1CA!im^=2V2h}D z@(0gBIuxXqkS~HKM)xJEuRnc}*%9;Yit1>4uiyi@+m|0ReN1$)vc^pe1sqX$z^`(Y z@3l+P0h-+M-ZI9=iY+ja3ppTIX-aVqYyAH_tjO$5E!Gy1b*Byo&*n2J{nOnWzg+F1 z<Sk26p|iggL4yZz@Bo9&bTi-6<{e4mwx>k~BWEwTUdqsswY}Y&roGtvWrxl*IHfY@ zocO>c-Gymuz+gxb2<4IM(@<+^6obc9>h>75Z612{=Hq$Z+$WREApNt!<n1voTXRgI z!N@uBF}}#rG%(<wM}K!c1*e{rX5O~qqjd8ZX+Ls3&LwQ_P5U#QW=36FR7PloDRyMe zHiQp_8PERXZ>`{Zl6U8rZY)JjD`1RTs?izST(yzL4t2(%K>tCC{956!9zlS=*;_Ks z=}+!B!FTTOt-@`*c#VJjgDCdSRP~kMz&l7{2!XO}7_e98d1|{Qk1|`>NbAO3Uw>>X zf)SzKM1)7&Q$?D4Ax(!5c#RR;GoC_xr%~N6UZ1N@n{WI?m{>otnXkD2`y24h9QC(7 z&99n^Ke}&^Am@G7bHPJb`mk^2%N1I1**B1S$NV_TA3ijGofKN8#tP}E4{)`I&Bui? zBtyr6SERsGlOuOr<((%1=us-E6DZI7J2^NR#=Ii$^uD|V#Lf38jhjhrMnfqw{3Fnv zjdL(((zRsu8C#Lbw$>eeqx}FCkkj-)F1c{M!RO4<-#9t`m~&1~-m}}=cUbb~EX!&c zwLUFeZm|CS%_ae2xOMY&hILYs*D^^Ta&GI$(%T#d3avZEikqay=ZjTF3Kn%(z)Rhi zhF^-FC!bP_PP^$|wACf<o=L!q1vK+^L-b@hq>EE-lDK-)IBQsO8Oa|tO%E9j^nA;5 zD`_hvr=X9g8GQ2U38xwMwuhgeq&GPLL~C%Z`ScZ%Lb)j*=#kK3`jPV3SJe1_Izfgb znv1U}^2C^lt3K(ypn?D@E1Uz0I8tAc>)kD<Dw(yhc1?ave>}L7>Q*jx@o6f3b<P_2 z*&0|tL?$Jl)HeQSJwL%3AZhqfhhZR$;ffv_Bq@j@#54S+r6I$<=`OQ>=FgK~fk4FC zC&4Vj0wkrY0jq=B_L%mhz@pXPJqUf%K%o^BJUu}Y>G>@`mP*-dH6}U+ob^Puqr%!X z_;dPpXW$<o-FYayiZ4-v#YtNxFkV1i7{KEA>P@d38@CnNqiz`i(pXul?2G&C@P`XI zx`nKA88<W!2x{Y^cBpmGE!mv!V1f_@K&bwgsFwPz_zd&AI=Ab7deHH0PEyS(->OIO z7UJsEXmtaiajiv4@U&(E7xG18dqsKhrJ(h#qQ&N<0pQoAzN1{orAo-9j7;$O2W_7P zv0j^(7yBhU^{vpMV}4n(s<#t^UlXyy8JnTbZ@laz5+u5|#PXuNFcpo}-PZ;%`;GCM zxIV_h-%%IT<btq|)z}5!rdHmem%hB4u7kJ8u%H}F3j4Zi!q*>V_WaLEndm)jm?`7$ z(PxKcWFT)YA*Dxbvve&AecPeHWT-o}9n`(PoWfR=d=W^t(7GrmGw)^NscOpA;b4T? z`PLY+b$*9wv`JJJ)stVGtUdsITD;}J)ip_DD^UnpdUY2FUd;Y}yY~BH@&X#r18b=g zOiXzBF(W_QJ;aA4#K#I+!}+90TEs!KvO>I;0!X#&GI;V$roqWBA>*?}LKwna?(FZ3 zW$7qZCbT}2z@0PX<G{Ic_}O6<DqAv2Mk{i;2Ao&(2BXKzWWpeGIWx;DRP<m8Dm0qN zGuoAHwlX>gXLu3#)Tmwr66Wkm_M~U4US)b_tv~xg>_~wUg^_B@7xv|~h2<#D_U>mK zWv-2Pw8ZLP3#ELr-$c`%NXc$nUz_(?h}ws4i=$eH=VAJzw=QRw_OC{7pNgY~ns4KC z_Ms|2!GU{2DcJ-;!uPOqCazJ9oDpjHP3*3G>J(1lGHg>{8!LY=0QLz8scg%Sd911K z53*m{7)+;t1<z=9>dNw@UbSflb^dM7K|M3r8IgCT38){-{<6Y-VOJnZ(somOVMmg@ zy&egNW+u@q{{k&nmbh<_CxxzJE3(rc`0?Dse)2x{F9^i4E~Ea%Ju<*r^!&K@<DJ4+ zgoE0}YTTml7y_1eA`*cLT;GUeCWOU&BMrSrzaQ$oFPC_?Hz8YK4Y_@QW`2l%z|g7# z++Grge7h*rEvV4)=np(aEgbhsg+9VFoL&FIs3C0}z%7U5rVs3VI^Za&B0KAzkp9lp z`s30>Lg@6ImR6K|+5NaXQ{oVZRnCGf2IadD;@tQ3WPh{jz#Q`uc!xcu+^;V(lvUQ& zX9Kz4`4vluF+Odxj9dwjb2W>MUw;n!li6**<3#J#fMFQre4tavf{TA!49{KWvEWw< zblM>QT3EK7|DXrOmfF4|LmVY9z;8(zBGW(9Ry$+%+^F&W4e&MQnc%>c?e6a^c8QxC zhYtAV<w$GV#(7fF?Lc}y^t*0u2~_(KAR}_MiTCXZu~rMTT5o&({QfI1LW1MBRMu?I zf@6r((~vAIH#WtG`yP+1jZfH1bYABdYg?KfEwyL<Gh3pbGoaX4DedJS3l8i#1!D#G zoc8D=I!m0jW&#=8QnD^(rhg);?Aqe8F01#Z<9^sl*VwgXK`r#oZ{kYxz<4jNAY}Av z2MhwL&yLb75S49E33yznbK9@KSzrEUDF~>zCM=%nWBI(%A4w`UCq;Z}L9MprUyd~% z0)Ch;M2}dT4WU{<UA#v{<Pi@XW6i;r_($!&w63$Rr>(+ZX;zrc?S~cgTMvr(OvzVP zBibsq4^&2U*+z94Q{FTt!J}{a?VUR|5Uo0cf<`jaO%wToy!~)M(&(7G)SlneY1z6C zqzFr!#MpIl+vKpzj&VPKuC$~(9GD_P&G(t*n1QC{ILm=NS!>7(O9e7F%xO8Rv@%cB zeeWcx$y1)ct_LYk)a`Vy_~&5q^439<)G{E{wEiObwyB{8bw_b~MQ25V5ii{(D3=QM zJSNoUpbGsiD#z~=NpKvoVr@jN)`wzO|HCvu6oGA-m)26CEmnr)@%~m5ZQm8f?f5@0 zF+=X3xO7Nc!+r}x1wbOkI`J`81bt4aS1v`0NCW}(l7#4~v7?I<JMaEKp#&CTtjaQ7 zGW}#h5y9bWLO9BU&Y|>WfLrnJ%Ssq5gzqR&_A%ZVjj!?&4~1E_$KQgbwaWL3FyCHG zVQhZxwXiv7NCFu7=ld0d_)-3dbd>epoen;_SOE0pxBMp;-ymxQy{JIlUto>_3A`t3 z8QMh2)LZh2nq*N^>mNFkzKNy>_{5ltf@VnpgI}|cj7Q(IO9YDNN;`Hu=_Groe|O*S zWbH#Ob^@N7%x`8W*#7`vLJj=I>2p`z2`J$y`{OpgW#@+52%%==TV%N$X=M?Iwq;el zD%tT`Ae7j>arm@#cz8DHbB#&wy|_S)Opd64E=lzyqol>#^W+XbFFii=d~`B&Ep_*k z;=LddmN|tn=z=^6v7e2nd&jT53g@05Q7WS}rIFU|$pB!C7ifJ`>h+kkh>D66IiB&$ zz4IV8)x5NAi)8yui^aN{X?GDA`M6}2(Xr!5fb7Sa)(WFz-?jkWG9&0uqnfSr?U|t4 zC4H#H```o40Nh7#Po6s8umWEPuYkq+z)}*IN}0hQXa%aOTNYcr_qca<w0Aad-Dpbs z2x%Z)(-n#;wUUYiEGp;-L&n6@WmfMe7KL&1l}H1l7l^OMABFTy8I(p}N`gBum_~om z(2@MXpdz*vw_A9@sUpFe?u$UVPXy|6c?1;qtGmpfdb|-T;=C~ZCE$7(c5uGTvysJ? z_c5rvS<iFVdQ;1@d}|`$QYif+ubBxi&w2xoBHzy>6QW)6AO`W@Du{1>Q+j@0+q%6? zR_1{QeMQHf=+Ya#^YSg-5s>9{`w!f)gOV2ReDcqxZdy_7p0&j|$-Z@H6Z$aQb^Hsb z&a__5oi%7=p=(a~G}7A`OW&c5oNjSH4qY`f*)%J%l0sq)D3Y)|u-kvLqjB?k0XMHL zI2D(RSxT!X63aM#<Ig)w>T73Asa6R&>^IO0$C&)g5{uPP<eN-PxnlQOssk1Pi=%>Z zGka7sXSF!>QL2OVT=E@yFc_1^00!Rg3OWLK%QE^PEEM$iezhn6dA48rbGnIM#4B*5 zZ12z7&kwVzhc8?owhqd-ew@PUHJX5^Vfr$7(L;EUNKnL{)*a$HzA-w@8DH(%cG_Jj zJksgXVZ{rvldm0+<A7mWzZZ$Mvf}}{ciRFqYevmzEL|HuN<Vu(Hb1m`Aim7>qen3l z<4Iuc)n7XL<UwrYs8MtnrF%1LdeV|=zmb?7qf64He@%k_?AEXeKN6^j{*_m}FW@EO z=;>v*4Z6GE*f<X2*hAG!jt?Zs@`+mI?)e%X0c2(mv-w$MHq`!(-l0t&@F!prxcmO) zj~>YL;j41SVa26wN=6%=k#@OHL2o>RUkHWur))$TMh4C#_Pvii-c?9_h5?)iSr+sM zCil(HVZ+4suYHzA6Xr+z0w1@fBwx0t{Y2E;wCyKfhNM?+%MApKBwwn@gqja*Lrwf{ z+dJT>I@_IcRNZt^-maZ1RmJe^0R-wj`TX>L71(J-c-A5^_;z_Jd)t*~+tpdV&t0V1 z5quCbWBt=`FhA18H{gthfdyf@*ung?kM=jOQp>x*yC}a1-uom8%pSKRTurjT8dw4h z$!8se+p`OYv{Z!h>qNxwE_Kw|aIw85YLas9$#2e~7`2QDN|MO{`!KbFB|XJCE+HN- z3^o7cw5UKlDmL|o%D?Mkc|bJFjf;_aEx<-$kPoNEleGOBo^*MUm00x=*qtG_MHCA! z=IgrHKb?6%#+qNEwut^Y77Y03T*g?F2Px}4JEn_RKU&<m(Z_-YD>>w+OD#vB+)~?j zJltECBa5ZjETBhNVxjn;%Q?T<3s#_S|GdG&R?W{?ljds|jc9s~x<}~-8@BFg8zc^3 zeq#Yfs8?(Lwyjun(+TyOjmmS%bl>~_IBsyitYI~TQDw9%baMmzUtj`MYw@4|gj#tE zv$ju0Mo)?IZ~ROjPKbOU-UBu^%Y`aWs&qqjYc6-A<^w4Q?C>qYZ3O0l<WavnM0|u# zloY3ZXwdNb*W1<*KB$E(n7kmhd*ke-0xx{(OWCm-+*0zO%W~sMjyA}Z8S=YM_BZ>& zw-2P_S%uTx<@@g~C=YG@5PZ|ejzsbEJ+IpNv?QgQ#Kgs%h+wGOm5pm%t5D*yg)pDo zx#|YK`RT2NX^wSh_pM7Y5gz!x*i`h~8b?9N7`a)mMDAu!W6Feseb1X7cbK4Qp>?<f zAnArevZ%d4*#wR{+_+v=yIDSaI9Qwc8aP_#f&Q%<vXF@?b60cDP5i?Q7n%6OMa#cm zRnDL7;Y8IADcoLGgX#+88Km?9b-@?_cqA2O_xn-C0M?GR+x*)>{>?f=$W}iFYQ5h* z+d8|i&7CxB73%n7qLayyLGjEmaUXh^hM55b3U`OF9yF#*;;Y);*^1@%7Vl(yLQ|*V zp4C$Zsg=_<O^!XVz%NDA@Uw)_*euX4ffqkuBQQua)n)Stj2!KJLt=c=xYa7buIiu5 znxYuMakR3R6?F(c?GAA%@9zC83T3>gIr&+(>NVAz%MZau+dLAEZ)JW4f7_}QZ@E5) zrB5*r#%OADnj-T(cl1>;G@IHS9PJ~in%Q!94(VAL4Msu3xvtuYlH?_`DO+!Rd)`w@ z#%TF(drJPfJv@&|OouGvErSX_06nFKCp>TdX18Gp$%1Rd^xStWHns1`hP9~8Yv>tr zk)_S<m%EpdskWD!)n$bFJdXO_R{#`<3Q057>Me*>s2pZ~T<ZO{yXB)5y(d6#CRSnd z(pZ=*tvb7HAk50_1+Hdj(h(b@#v8^M<?Zr8DUvcOsgIqQ?U#eOsOz^8%B}3)Wqv}v ztef_#nD1zFoBny^SE;Al*SjU?3*yt~_l>Q2o0R~Lla6!r^1mz|Zk=<Qg?=xA4P!B1 z_b0T1l>j8Hf-&0#;%T(A_ufGMxGUw*fOv%Z7*!-TbHgK0!kt{8+U1Y8GQxotGU-Z8 zxZOsmZ`#_#=G|jePyP#BP#li=%vjc3eEB5O3|Z8mLJ>g$*rGW6vF0TCP@C=Rt1P8V zAEn$WT*98uhD1ru!95@R)*Q1@GT#U46X++C@Zz7;Sx%g4&NqP=<T<qH-i9sFr!2a5 z`nAc2`Dzp9T6@#QRmq5&5K1KdTkK%+Ekqt$MT?q+`>>WTQuj;myi~hk`4Ah_&jfl{ z?A^sLXD*TX{*`GWXERVi;6z(Mrs+{%4G$gm)d_t<uw^c?J<9BfgGN>M<jUplJjzLC z^>sly6m<8Y<A|7KTqXKNCfMh#tmgS0ywD4sWYz<AaF=Q1O?VNvRznvoF%^_sK2#fS zy5mpg1r9UV(FT%wG^*w|%Y(Rfz0#|*dpR!w5{)#i1I8H*L6P=fS@(AV64YO7(#hZD z$FZZ(`J1i=6Z2o<$D>f6t~25(0mTws?XDt^ZcTJrM`Wq$Zk=V0La~_Yyq#d}>k9Su zJ>PFdQnD2oixGHb$B*v!PdO4zY_LQ7XA6EeRf7r&g9@x2)UU%zPJ3tAUru;GSl^db zAGPNzhvmje^1PTG8*qh|nfB3c+e`J5UA+t?=!)5sC%Yr2U@g`?|2T(cgmUEDRDRV7 zNc>DhY~s7u0!iXS>4Wg!PGPJSp1+CmkPD~?yJ(GX^Suu@)w6FVO^vd-N;}e&z#Bmm z-T~U4o9|lO^TSJtlvh<bl^91DMsoi*TJyO`leLP(J!Mas&4($JPc4rmECrWzZa%8E z8`Boh*VAU<8*zG&H3;NZeHATsTY8~cK8h{aK%Iz~r?*ymsufPHM0{<6e@NbQI3na= zL4>5{Kuy-nfj?zn!YACvS%JjTBhn*n8e6U=6Z1ah%9+qIAS>VG&EgUlX8B0!EDfd8 zD_U}GheNWxK5cD=cBz|el=!s|o_I9%At1u1PtH$E0$-i${Lkw8#TU|p4wXY6K)W&% zo{;vx`eDo8#;SV!d_vGuuAWU+-SdR}-zDKY*mVJi1LlAJ`c<!=p|F~+h)kqPuf&8| zPM?Lc{H?-bm3TI5PQcvvV5VPs3|!s=`D6T{@A~2yB(EOcy88g)b@0ktQZ%=Q+qMzy zAtCwrcweBjozuVy@a>0|o{r^u>P0KRuF*PS32VO{ti|>@Prkm4?=?4}k4dL7<+E3| z0Tz^K*)PG!7syJR>&nuz%EbP!pi~EoTzc|XBVZUHxE8)`FdcRyMLvU}eqH`~*p(uY zOyDKq`y7@^<x>tgWw>@%_1axCIji4*C@N}xD--7)iVl9pAN+O88zPMMo3Ek;hdJWw zACi0VhEiVr^PWVJlkEMtx4%WfANz2&VSc#3o6LhU&f}!EH~KNxB+#fd|75mPFK_k6 zjre@u5}52=TSEf(NBZv<PD;qco_$tI1d9O)^@3Gf?QB3xv{SC4hQP=Gyjn*hqNkKk z(QsoA%$R<$t{_KyfEuVp^pL33uu2_S$FLMvM0)k+zt!ki!@fa-G_Vj_p_)%vCCN+2 z8hL3$wm<<#Y<8@}6qRyoG{9}C`E4@CkVHqxJcmydN!kd>xJy2o%bHyz%Es+xA3DTi z_%q)H1YZb&u1^T@#B<c#4t)!z(`$u6`&lP7Jt|&;cnLK*anjfi#HY;|zSAJdx@2hg zel4!O6uW*C;Pmx`b>HP93?m7-HHr+Lvrn`Nc=hJpi6og1T_<A(zI<TLGj#Q~Wy+7T z7b1GFL_e}t&a%bQ(f5rfVy*%!AgQR$>y+)6{$wU4A%9ZyvtX2v=sr;GbWS%hWYd#B zrgsy$*V-Bp%v>$<TU31>1C|PLTgKxEjm|+Ez0B8eKND5aRQsP*N2S1hU&`_ls;M=Y z@ot+tB$OPm0SyKq^aINO8H59F&AG^%?pebQob7}B2V<vcxIFy_rdd-cAbCxzQ%&Lh zEoKVJ&c;m@qmq^ta$pR#4AZwZ5xn<JV<s&i22h~9Ly0T%(0V|*_c^oE(B+x7UY(!T zuMSphJ`9y4EsOV|gJsX|AX}$S>FLOYzr6>?FaIHxcAFM2%t{+_0e!RXBqPO|6UByn z=zpQAB5vre+4E`Am-{{Q`Wsls<L1b;ofo}EIP|MfS?G>f39EpufVr97-p^$t?=8%R z_e`$L2y&0eF}SrS-3v3GCG)%9-~Npd$9wJ)^JuCHl{a4F3i4m<tagXpSPFlyB^5PG z&)>Sa99o<ogj!B#9|cnwZn1aTA}V0g!A2MO9PBsWF?v53oXYkewG7q>V**o0l00Pb zE)ohemE-NP@#%fC9%k25oaHr}*HdbR8DE5cY3)b)7Z--x{+Z7*Qq9Xt0c{7ne*T^u z<w3)(sayM8LYqIEN+W!lF%eQ5WI=oz!Y8$j2H(tjoeAl4Pp6(dk6_911Y>KD(?fU; zZVsI;cK44tE;aV|vWIT+NH0G8;YBenSr`yrRfOcaVm}sC%A<Bq2b3hl0RiaqJ+j;o za@a6zdofOsQz&;={lzodti<!68q2o8gS?v1=~l3hj72CZ2;3KuprLM#!N0jCy@?Kb zEyDu*mSh6A9;xBlToT+^Cp$ZpJfr-trLhOnVqq}Yyxk9B*jOjuVEwPfB_@d!T%GF4 z_cckfAClj%jB9Zp3PS&zo|LA6^ADduGz#eSs0YdPYb4)E3pu6xG>%=3sp)0?Za-)c z?|kI=ERiaF$97v4MTPQ{ykZ@`Lk$?JB2h3dk^ato{`ywdb?%lq;^_yOhE1nIqm=VE zRlO%9k~^iGMf^0W9R6<eZF}BYiFZ52<F19Cyzg{-wBfGAN>xmkYblpXXWhpF2$ckI zhB}Muic9n4(Sb{Y`L3cCLQLA7Sz$iHSM`|R4`r)_)^`c&#pE}iqjUH$Lek2&U!Zo+ zWuCQQf+f(%^EJ!B<-Y+!%#FYKBB%dKWaWd-D+;O%d~$h0+NP$zg?h~ysY8hH)v-TY zq>EPCwCb_vNO&qo*qdH<)jry=c$(Wp;ZPH;ndOXNQRpmeZ$uwqUkMf5JMZ(t$*=6? z`?mLy$DOlZt|UF)_b)o=EDy1c9q*=muR^~qwkznN;Q3TXsaLwC%ePG6HwgZaB!27x z9sI$jk$3iR{V9p`Etw(G6#MfK!4S-ObzCz?WHG;nRvZ$e_0-XPoAX|0=4;C9el9~F zyO)~q!d1R*qd>i&ZE=|5v}dhju>DX#4nhMA3#l#T<@Wvq<GONHo=3%nFtHu!76!b| zM6w5RqN0umWxgb$MK0S-&?l)E>GKuRx>3N@_0SGTsoD0%6938R=Bazwr=$+$Rn`;A z>n3KIh64$XZJfY@1rsp%f8X5?B9L*3PLllRSHtHy{*0{_#AiEkFBhG~jneqvh4+J& zD1a7=-YzojL^4m2karv$*nihhLk&mVPBG+MbwcihtYo&6*ZOPAL2{k$#MPKQ@s|ec zM#Y9S!#8#DRjC^SJ}}@sbU|xQD<j9S;h?xK#hc5E>i(v1zy>1tLWP_RPtS7t;dr*7 zK<|nZo$u>Vpfq*c<0Ku&9(ToE9Y<v-3c+CxAPL$8h1Iz9&Za{x`c9WAj55L|c)xCI zqrXM;u%w<4E)_noS?EA;)=_c{ODY5I<XF)zQ`6Xhc=q?W{HH}XyuYq*TB=B)_agb8 zkN)(0TdT=q1iE*RK8gLP5YIO?5Idg0KtTdC%i~X47Y9>idkviGRfCRn>GGz70}0Uk zS|%q6q}R0WOY0;S0(-o^em9fk8A<q>ZucA1%cxgX^a_%k!>IH(&R2S@sTs{+!HO^q zU*(nJc8GoSTatMT8~zgn0pHnAXquF*v;b7%=b^nuuIr-{su6=r(?}xLM3in1=dZhc z*Tj#kfP~Q;!Vz=p@E!Kyc>6qt$7peV^~`gx`$i0aEMorxf8izuGEJPS@)umr6X<Sa zGe>p)Y6Z_+f~>!6+qWRRVh)El8$9eykI)6GUAp7`4zIq0l%kuROD-=-PI3Y5)C+Jn zNr&&JfJVz)bC=weK8%34^^}#TX9<fZ6%#CYJ4416AQ=HfodwITzQ-6?jRIT95o_i5 zVS{TX0=9;eo|Q{&JvGw8w-Ua}u+TQ=SIxnW+h-2SA?bfwmoJww)G~DJnm34B4w+UF zna^0W%3INeI>y7$1?+FE12(YwHvP=-@$D>6LZw25Yqwm12^A>#IR9ov1(kOteHgfa z_<ig=q`rev@Hg!P=S<uF2<GeEhH#unTVP@3!CL?JTJ(!=M<gP)S&>`&)ep5%7O~JI zt<_Li-lZ?>KcM&B(8tABkJ=J}bDU3nDSz>J=@M6|i5yKNaRc0#zCs!pRIMF%{OrE= z^{u2HweJ2J!mW}V7u3iHn1~R0<vOKgTlQbp@^>@uFq`pjw|jX(@m^8?kTO7Iwe0PE z?DWuQZB1=qT98#agtdC(<Qsyyeo0cZasCP(-K2VC`8kNKnS8-6`Q;l{Y9-w*m9BXr za{hGqbD83G0}nW`_>9yVXlTa#++BNzt5&m>w%etKVHW?G7|ni}`ongaayG_2@RA4B z2%N9+lEvGQUoBIPP|~VMuL%7BK<oy~g-pN6uekF)F?VW~vqMzy+HTeD^D^7eha`hl zQ10pED8~HzM$STz3y+aaLNME3)>*1l^#iJ#cRPNvx~FR5r&pF=ppuC4`xemEeF<B` zb<ei%;ab?xgp*+9yt>~Q|D#|u^4R;a2+AeljZ8uTa(8r7o?3NQzvq~kP0E>n^aPh$ z!e9N6N9O6SRNPkQ`_h$ePY8!dyVS1dvs2SND-r2$eubD4@b)vTy`9WaJb2f<r{1`9 zbRqSPo<sBXh@S|m)W7tk1Z*;MDfNpls$VlQpy}T1IXaf0=UHk$q3I9)pFgJv#FVJ+ zT+~L{v3)0Q6IpA`%WvUB;m0r0Rz`@T<4*a&u&|n~)qF)CNgZ~TNAwXjdY$P6M5}%g zEovoGi?1xBeq=l*?>Po?hRpVS51vFbUQ(8bc*yKpt=`_RIr|y(Ir~xrI&<Mal5;$K zGn#XpcXGo!)tYm@JQGa$h_V6y*6Fe9#npJuc?cbYki-YCv7H~|o!+vJ=RP!K%|)&2 zH7gevsX`JNtMv$?u}+v0Q3Bc1|8;a*hA#Z|_L=HzAMaGI2oH@Xlexoy#<?IkKRbQI zW#JVCBntY9i#Z_LV}yT?xjNvvxO~@Vl^DI4;=L-fMUtN_emsH9V+v`37C(~4AcJ)f zDS2n7^*{V`&)CZLj0NmQZhh_h)^AAhw7o~OJim8JzPN2-$~m&vJq>Xc+isO=xq55x z^Fa$-$;{s!n<gtm_vT>&wH@9`bBy%bCv9wY47Zb;P|xRJd(JEU?<hQ><+_CC(#YFC zx)%u<?e86jdjdX`$l9m=(&TE;RNu{b#{Sg9pe}8HbVPsqZ;4x9*`VFv6Zcp>+Yij1 z7v=_U2E}F`$O?yJLP$`Lsjj$)5x$flp<tfU8p3BNq<LA5KJ^8moQ3ak<BhTc0GpA} zej5~I^4SSm#aIto=~g*D_s5mX#YjX~dH$dlvWsm0(@sAPYO^RQX(!MSc|y=)9((k> z;aJC_K04Nwk1wP1G~UA6+GF5UY#@pIxbph1PeGE!B-}XR#vu1=-TK=?8IyJmU|5jn zg}xw2))jradRM1{<&d5L^7t)3;o1(f0_d8$E=KM7nrD-oLNq|$VTUCVZ}jxO#)JC8 zNr2=KqPCqZ^*#G&N#;v%CKau3dxpIceCz_^ToYy#@2+KI4f0`azv%SY6XWmdCwP20 z^nsEw6gwp)8}We=@N8zfME1t-nfP;@HARMJcqrv{be5TWyvz(YT1P#U3VP&c=-0n% z(9ylP-3`0C30>lVS>N!TyB4^*!h@ydunWLOc{Mo|x0gIoR5ToO_ncps9cd3WJ7ycQ ze#m@`8aS4uK((QA+!qbN2$Gp|-ZlU4G9>5q7l9n&>rALN6|li|ieSj%Rp8+x6ctjq z@#uq9!_lwf?2@08300FLQwV=0u2RL)XlwSp?%gL{+w8X%>U;R>-e)E7#x7tZizX#$ zz@TNW8RAPbYD&>!=RJQOHv5qCRozqMxBa%8uV#q+6W`4iB3==8+W%wu{k_IJ%GHQ1 z?p95Y)7~aO?&jys*HDjBzW)Mn#y{e)*vL&bVF$WwA}(83Z6AL7FLh=T&b)6wydQHp za7kk*q15HJ<}zxD8%MQwFuJD)Mi|AgaQ0QM6LdXMwgk{&l(*5}FV>hMme3!!4M=zv z^7bTeF7=je&uwJm-abvfFGvI5*+(}6sHc*;sRf>B!d0{x_r>aC#oFX^@?aWNO03*P zHn+A2WMLq3ls2dSD-_L7^Dyd`#X(ke_Yn!aX67W|Cw$<B+A#!V69Nfnf4@wB(`XT0 zpI<DMX+`rzMU)QYii?koMcWShFv;}zU?EOk=O?J?yjVm#3*RC~ra`OL$!cr}hZ?Nz zB58a5N8ji2?wPca#j%!qXDePaGs1tWW29sN->=_QNWPfz_Yw|G0z#pF-2HD%ll?q+ z`~B#kS5>DUmaA^g;VldAEdCm_DK~28OBSsEEq;p$*xxg;Z?5)e3$&=u+pdt6s`rg` zq7`F%XjGN7eup*xgOb8vS(C!-HBFV!e)P`!&y*7EtWqUXIA3^s9vO4nj#UqG32DGF z747|}5aHkxJz2vX8_sPj=0TM(U2ZQ@x){QQ1i_&c+>CZf$^v`j0t=_T-3$ZT_X1uZ zvfIGYp$cX{yhm%YZW+pM>zEUo)T7U$1unS|0tj;0$NaEZ^ryIv-dy+7nDQb<TCJIx zJG8!iy?9OcO$m7K(teIJ@i@)=rv+ABh0l8w9~WSDhjzqomBoz`*X3t#FKua}v8mK& ztPWO=cLfi3L5Cu)(OsRlUC4WC9Uh8qyZ$d;K^lkSJb?hs317>3MgP*L(<y<gR81vn zcD*WQV*d7Sd2k-E_GrC+_%!+9<G^$re&cfh*_%t!rbl}K?pY@%tF@*4T>qLMg*^vD z5cqgZq;cOotHV4?nn;)=LuF0zQ(3nVqiG0uJ>|`rX;80OQa@gHQU5hsNg7WP5$tW1 zxwgG+Z;IQ8|2>&$Be8k%bi%b0XrR)4&#mb5aP?=|WajZ`xj6>YB6`E8_TOzO82IH! zB&_bQ0ubXF+JQGB%Jx_EpvfA@EZv&t7PW6Edmk<0_M<%T#fmWllO5AYX(~@x<ea>S zl^m&plYmv^=!H`05e>Rowh@8~`p~f@BNnzPBlcG8JW}oa0J(R7Hq$20>DwULSCvzo z=hq~KzXekv4bEotVdQu|_V1yrR(>@AJ_hWV#%jvbq8jdNJ;pte@!C<}{Y3w=FRcZ} z$9WEK@>;%v7@J**i>AhQ^o+bxeo<5zir|o%w9Tg<@$Vys!Y-kTuk(*bz=dByALgf? zvMS6nJ&}jeHb{aEhc;#{N-?9euo{orW&c6c#@-8|mwOEZ(vj1*u%8@+yXo&4+@Ts0 z(dr7DBfB&1nM}O+j~Dh8uW9Ifxu^V>@{ZS|hDbgNNZD!-v7|pFM+g0NZFM`WJB6bk zn&znTs{Lm&$#K)QiLXtAxSF3pddvO>!q@Sk5Y4WZAQ?^g%^Z!&sZEEMzyIBRC?Occ z#upyI#wT}nChl)Ub(U&s4(ELjc!|Box9-J2+(Kqj&6`ar^>g}TLG^3&I#TZJIDc)$ zcc5)VM)m0M3Fw}Ca-icGx@O7bCRglLqu-Co>PDOdSg_~ut1<7fqsal)bK#md9>=@Q zkbDSSChqj8{hj_yW^0AOP`3RFdUZr<HaQeVM;W|k`e~NoMglXi+kZ)o+&cf$-ZlF; zz~!c9FDzXO+T+=IY?c=)%S6X_<EeEfz|S|SnqOn)KW_{={tvdqrP$(v;UXc-uN^4+ zrI}t_CbRC{F=&ghW)lBIKt-i}`Mvs()O`B1`hb)zJ&)_s7I|Mv9#{Zj6u&Z*G+%Ut ztcsN|>owRIIUdH_hd_sE@$sJD-YA)dE0E5x+OZ^}^46#r=%?2FhNI@_E=kRt!g;U< z*Y@4A*|$cth}m9a%0L^iNuC^?2oWn}HA12eSlOW^xelsgcxgwCPiQW6c(DrKSgo!4 z|4~kD|6j_<14lU>5uu>Oa1%W+<}P?79%h#sTPv$}kevVsRQwf6xpW*41^8oZoq~}* z2p_ZSKm!V>@qsI;p2U-lO`X7(iO7p~z$|Q$3spsQFbzPF*14QN=(YlX0Zfw74qsMI zZ4v}p8uo~o0iw6~ohWR&rQNr8r$1ew9OG5A37fAx+rf)Fn47D8Uv}?6_L*?rU(O74 z`9(H34oXauM=Y__BZ!G{JVxW1fOqV1F<CibU^MF|1*ZZ>`Q-}{+0lSh3v;ky+q3EJ z1p^1L@elP{thFjbVb)GWN>@p0loF#|zoOJ=XEzy#X5ky5W~AyL8|2GIvIb@|qQ&NO zu2E1ec}mbD?LUNv5_M*W-l`b$*h?3IffUWB6yr*(j=TF&)mFI@gs0ASUJDP2KER%w z`gzFM9|c8uEctV{<q6xju#&~isRq5+gXX@umE6{4;7e*{ZqdRN1P`CS)PioFyIdg& z07xD8GWZyFumBJe;hFYJRp?&|tN9-atF7EjHdFlY1sP9*f~+kWhBx#7rm!X?%B`xi z=K26pDSzPF{%!9P6iT-3T(h))s`nP9t&QjQ6qOIi!pHsX1fX{-2$GE5LV-$uJb@Nl zYvV4e3@;c<{EE>p%3;aixQETgz!c^6yRvQZ`75SU#Njg;>eZAGV~MCXX13$F&hDVW z(R|xo(Q{wfjh2g2Xtecvn`fs|BA{6K!Y40Ndix#+_XT<DgU`jfIzYCinw!5KTMZ^7 zSgjHBbZE(gewganakYSHi|MMQgXTkhKp4mB81TQH1`J1JJ?bMLdq>Dd6G35mMRi!X z=F<9bOqJ=g5NU=Fk>*~*%v(t{(+{p!cLP65k22chb{gU%va`R%IPnWczRSD!-=J@D z0NB@ee%u=<i>u_Ue!LqSYOHyN;Nibvm!aSFtW4^gE=7n=+{n4UmezbixSE2;@mU%U z0uw&(NiCAmoV}xLY@Y|N3Sz+H%2PI1F+E_0`F=w@&im1QcZp}I6dErq!Jr7T1`>YO zl6qA6`l@$)`eyu8GFxz~)yavR67kKEqx6u8%{SUQ(1-kxdBZ>Im2s%;D3WUelRgZi zSKKBgR`3ZGEWA^IAK#KW>QFH0^Z{K1LFAq)zkq@hh#Fy`;3`nSv2godYz@-;psXKS z@GOKU$pSy_GQcS3uS+JvqH0KYeOk+m@u?c)Q&xc<FCo!(Q?qC9-qBK8V2#{m7kAOf z*CCT|_e9f!a3M{~L*%t!OtgAX7YCEK9+5kNTRhQDVl9PT)QP@hCp=`}BiE+)Vcf;v zk^u!YTCO+PWOqqbLe?gpLynTh9tgjA#^O#!Wo*MD8RK$q(yMrX2qV;Z)cVo{vE00^ z(++f&9X{zW7Z@E_f2d5egRTM0YkP@MC0+zky%Na_XKj&Lh%~ZT%s*iuV_n+&N<mvP zf}yMC9!dM&lh)_li?Q);nf2U!EA9>q+akVvZ<orNw3fK0xdk1+7F_aYSgL!(5Vy{s z<frlh==%U+>c@Dr6I8|3J|lZyw2JFJ*_lo$`8&^C{Z4vg2^UI`7X}QvUTMvl*+d>h zjEnuDy-Q^eAQzPGZW|~VZUa6>oEta!lEk4}?~$LmG=atimjssrN72qNB(fRLjh;ks zXRz?i;>fH@blbA(LFGwNoa>9z5r?4G<$K*jp%Lkc!|Ki8ij!ZBJ%}WAxceXkGJ2<5 z`F{ox2>xAky%2+Cm!gr}k8*n5O2sp@d&m`lsxz;oaMIrZt*yqnzYI;XA~SxBNcn%5 zE$F`iK%XWiG@}_R%maV=sLU0Yw~`tQ{h>;GR^`-MrTMZqOSQ0vsp*ZR=0ZuRd=jcY zV5ttmnEon6EK~hH{Y#C+h_EU|9t?%-1?ID;dD{d<o;a{F=&t4o+W2sWXqgsLtIZMc zjtjHpl{)KMF)4A^e|d6OtTR}M<$H=y<=s@WHs5*Fp`R>!28_6`*HSa)Fb*h=G9EOi zoCCUFeQCZb*$v`(B6=@cr&#iPubn1u!?$olz3?~<rD4O&l`$c7nCvC!j9|Z;t}#Tl z_Esjn27J}t7qk75c4Wxsd_$}Pr{#GH4|r7OppFz~k=?Y{#Q21t>XZ@TWzUI?MUSoK zgGxZamPD_QHX8;SyL#TFQ9E<1t=<D--xFHh8$OSSv1)QX2C*-RCK%C7SJjE^KXd;6 z+fLFZ;>k?1a2b9yVki;<CXvhkhmF$9Y0I+}SgdoJ9s4{KwU5g6P`Z5_+Rh*1c(%^B zemjjo*_+7yHK6l%2AwU0tZ$Z7e9X{#hoxo3vP}In*V2v}J7)TG)Y)2IoqMk9imQo9 zI|s-Ul)Aru>dk#7U4ppL!b~1>n+=sC2XQpF8WobS0h&_jmXA5#<h7U93U{~nHZ<Om zybo>GPG4>y3hyQ_9zw>5{W>na&5aVj)griE6ZZs6;#>U+3x!)oQ67YibNt>P@5%Od zcA|LX-5ZHq+(NbnrRX-+f&(4fqcEQ!{;YFa{^Uc^9LMj^7#q|uFUrLpV_yT9pTfG{ zd6Ez1rbBz#XwoGOEMV+tPxn97?WTjr*v(VdV^X&>F6e-(`2PGO4p%vkxBoK_>6{I4 z_>DiOwsucQW=>%BO!`?$kSRORl?}-LpJAzhBv#-zqitV<&_p+WTsKX3Wp4k?a{7<V zlD?x<Od@2a*DOD!`0Q=Ah`Nd)8`ZZL!p`;T(%}!@4bMG&_*BG5d5}FIg7F_dtL5OA zav7=JOIA@`l}80vM!zEM(V-#7H|r4gtOjOEvEF3R2N#ayXAyMNmrAPKoLamnv0Z_} zsHYYAWk;3f25lcpXW|dbZ@YrLNq#dlL|6*-EzG`@a?JHLR(7?=I)<XyZ~rdkM}@g* zm<i7M%knJGw6*Mcp)>1zw=Z9*XcF)X7Y?J}{?WVaHt^5QVm}oo_Wt;AJynUVFJ4is zU5Wgpn{b!6P}uVqmF!_yeuF1Wen33VkA|$)MvT~AE{dhZnp?Fgr+WpD=StmhKQQr9 z+7ZpU-)MGH&-0eIFQb=o&}40C7L$Da2O1z4m_B!<F@p_4?AtmoH%aVygcO?1TO<y( z6Cog*1y!*o+s5GJ{TI*u{xpKWCn5q8k>cKxUxIvBv=HaryZl;g0~>UzN}%M2TeoE6 z9}!J{?Ti(CA<m)IXtaFDZ8VvlnkEL8TQe|wbMrO;>(d*QN8jq}1beb9A!e-osxgHV zPiBHS;dzlq*y!nF<Bv1C<9$@DUaygUZ#)~g;Xgy<LPLlE-qogt=i$k?SkqRn8RnNh zo>zq>fb07~Ue|a2FQ(2roXz)r|5{a5YFDXMMNz9tZBf+TRIL)TC`#;^v{hT}U3=81 zQG2i2wf7bTv13O><d^o{&+quU{%{=kb0hyekNY{V*LhxmYeK)0M)&+Q-+O+GF9BeD zz)j{)f0`38)}xBe=>(Spyo>rzepjTpp2XiPy^3qOh(GK14neqn7(VXT{JDbV0$ktz zE1)H4;;1g#9_Z+J!u#S%{I%Z{`!5?!%<8Cp@QRe;K04M7DVw|>`kLESszWNFIiEDE zxB$X2ylI=6-{@q2I5_`gA8_A**FZVSG58<LwraO{#};x#SnL+I7s>rO7-8>vPFRi( z6`!wB^%*l1aCF;ot<icj;MbZKx))>U8_I5Mj+r~LGSWv0E*S=XD33=h=hKrD0y8t8 zN5MjXW=^;WKcR3>p6&&oXNb*Xh+G&jxK;A^(Q8zV3aaLv)l(gv9p>vuWyk9M?sWY< z=w<6WK>0Z8f?9j$5t7@=F@!-)=DkfHz4q0oFI_CS?#A0}dILLuXhD~J+B2t*qPWK` zl@JGyfytBMxht-8!2u45f?x0+4!ah^Rn_KeGj--cw-1^W1${)cuu#q}z+LhY*E<!x z-S-F6=|&_)G%il8>@*u8*6D~}?-}=uV!gB7$J!pAYepXXJw<%;Yg4zEOHbd8fZAWq zD8mU;nDP8pVUw(~6Tn}ptIUo4{*~OrGrXwDdr62--1@sgpyVjUZo7#W+VW{KT*EI> zOFYB0?gm!uQ&#N3wO1bpDSD^hlLqT@wkDAwp~Uj(SP|^?S~T-BNMzye%ViaJD0mTl zzXiFDs<S=b=v~^~S0B+MWL|i0!VZso!JNs=>?HG#^3Xo1cmg;mbWce0EkIq6plsg* z{#Vmoy^%%*^KC@kQqQ2Li61BZcuqHth%V~OQHB4?fQlJd>^|k^_XA}x4iy31;P9p7 z_zJY&OaL8ULd}n~&oWx7Qux#Bmy!Ia$G+y--!IYsf*l9KaOcSu@7QYc#qLqEt?$&& z`IhqB5(eD_@abri?Y7He9NB5~c+9!w#&N*vm6CLMrk3{=j*F~_1IUKol6|WP-&xM( zW~9cmm7O%I^t3APzm{a`eD~%2>pm4Rq+Ze{qg@pg*wUTfesYM+*mJUW>b>y!)Mm6( zj=E?`Ji^i+@&oqU>+T+ETKYbE!_a$TvMwg{ynaOVoS@^zEMInHloaa4%IuSnUy1eM zUJh_C2mZddI{G0_h(Y=+dN4DX(dRv;wu!@O#KPAnlCvfn!>)Y0r|*~Dd-Eo*JQyoc zh&(3+cfGuzfj#RmS4GUDLEorbH$^-78d(Q{nNMI2e1f1SC^nF=xurDy97=(RfAuO{ z%KMpxuc+eZ#{)KMud?u5*I8pW$;~v$H3bAsygZT*ZS;6o0q<t`ivy?($^)nb<xI^? zzkcY=t&&M4YvwyDI4=5R&J;rbz21lL9EMPKXj8ku)8epGS+l(L#}t&BFPV^@L{oAy zdH3f}-UR5+ThM`3-%q@nmAN?)@OpOeZ87P9Uzq0vxaO6rVDV$uP1b`}keWtHJ1Iqh zq#;7Wp&V;8h^j>&l4tz>)A)+}LPCGGSmeRaTi#NFaopBm0yn>xsqx?4T-%P^$Zn$e zkry4?d|r&WE<fz&1QnMrC>`B<HtUwU^7|kVqGlt~!@31^e}jGEyP12YxtlpHT?)be zxaMNo)xlmSfYi0l97Q>ux!0->FfW$A*)B~q7PxEfW=yx3fch`N`iynoff{afwoAGf zS6;W4V3$~pQePuv^?}{eLbv6`vV>Gx)Zx%f)Ge*u%wO<c+}~;eBkeF~%S$BH-^bpY zmJbWh$N|05KXu!+f*;v`;*<aMMxMs=RP#2W^G7_Cp|MI1Z%#F*lAD<)XQSu#Y=vbn z0H*;&jVf-j##hRRCMKw8Sg_#}kdISbMK;3<(4=_hW@nS#wqe@Zw_iGnwJ|U7_Xv(` ze)0Zu%iniav%T8L#q(uQPkd(_QD-4!(N>e@zta!EQ?Lq7UYPzJdAM}bPa?o6SoowO zF5|f=jOJq7>dI{}1EFh?+ox)qan7gE0`6Up&<-CO;##9N++=&%>bw45f3fX+11uen zc`An9=Q=^g6g>753~>6*+IwLh<|OQLc%J|ow%K$ds97UDw1fm+x0c8?_}W_!Pdua` z%RC8Wi;dV-|CISKPx6K2<|-qsn5gV7uARFf7EDmzsn#3}_jt+U=l$G_sn-=8)-p%b ztGlh)GV&Z-;3JLv)V6KXRi*G`xF<qQ-nQYwMG}3XcdWL;4XKUTwQ~SQMh9|nj*xqk zcI&gT(PV$&U%9Dnwy*uPU104_R+NdGy1~!Z5^AV5Cf<9F*<xMNn4@_U_!)A&FMZ)d zdadl>siTMUi*^oZN|P6pJAan@X(G#*tz#j4TA{A>D~xar=@|&U2N`Hq21gP8=?*hn zJ^Lx~E8KM&&^dJZ#Quj%=2S!FGH0J^wdsayiX?5tk_ne<J1y{&ERPRmR~)VESmvD~ z<>#ytfu3B(zppe2e+~x(EP`1=3l7^fU_~Fzmnmn|oqg43`5=vL6PP7j?4%OH<+7>t zWKH)~v&72C^pTMhvw9{{cQ<QVrZm8au!i)*<y>LijCPDfqtx||9`KEFX#f`h4aQ@< z%6HfL-!>79!=y1fQe1RY{6fk7u<pMf_ACkbhXv>l;To>wOxT_eEcL<B_L14ag{NBZ zLN<VC^ve$A?NSrvU9W8;?!2!Rx||J2g3CMpB@DiUtgkE2s*DC=)~}MsO$@riPzr*X z3MXIjvTlY?9eL_YxG<=wbrDrb?O$!J?QPZn0QD4he4ocPpGfw9%MWk0<cr0F94Npm zw=NtZ*mKVbC~t?8oTz>v`V%JG3^?-BN$Kc?<e+-4Xe;}wv34JBz}1TJ5Q(3BdtCtf z@-&w>1EQt~ge<o?ez`tP^P1O@+y^L3e;nZq^19z|uX<c%O(FEIwnn%$si$qAW5&Yo zp16Z(gfoU=vFvnl>C-kPJ}@KW**6%Mbnp2YS1+tYvY75V7O5L$Z>{HF8jw`(-7K7c zl{#a!R}de{|HetgQ@aIq@m=?MrpT(d*JsWb(WrYl?m;AKG6w!u#?+9<Oagb<{chs` zXdPACds1B#IJ7UD$o#|nU{n>D_y_tWW1?4?IssaPl>bwUfsMS^))yQ9v5vPr7dO|< z2^&Is#k^)WyEKyNOc&loA0~~Z;d+`4?ydOS;<NpGKR|#6sBx?&f%tr?s8o-hu~uZ8 z{;Ie18ve(Tw4ZkOlqXyL`24R&^#&&_(M=fv(8R-qjD7|OcI_bHTn1^A{;2T|h#sN9 zMuem+;e=Oyz?`^2Jk(~i(^rO!+mrny?DX&$weEzugwjXT7hUUNhK?@fe4xYaZKNYh zuks&hJ3GGxvcJ{%Nw^uJHK5On{R`XGKNZ%6LS@pBA5@QPi@XsJN~W74kcMcU*#{}e zbJgRl&6de#eUxr&n>$=eila5cn|DhBhZt&#A=O>4PT8beWL=?;ZHGYpw?HNNuA;PZ z$E{u1ni4UsgE;<fXzcYZM$l(lAzcM<h7TW)RKYO(S0K;tGpw`Z{X*e5Nfmz)<}lbb z6~?6T!^;N}Di0F)o|?RFEOa}HX`EF#<~&<spy}l@@e?pv)Wxl8Z|976*Ic0g<pDtd zbhUakuZ6s<t(dCgTV&?C)9&|pY*#lZWe3VMRW#{D&(d?~%<8Bl?4`LC<hAL=lG z>uPy?sZ@T%K;YjC_Y*&lx`lV?(&%!&UcJ8e%V)39U3FM-CzV9P@Fe<(J*Sm$PH8RT zMD$JhV-3~txUTBO3&*VTww|gVh_(zwp_kM9<I1e$q!&H5E;0bid}iCrg%dj&Uy*XT z8NH>t^zC`GHU@{1U8_dYSqJgb!%`hjt>TlFUu2=d(DaO-FINoGU}m7Fhmv0l(9^9o z2M0U8n77wKt$w8vy{1L2%by3Wl@l&;DBr-NeeNQJzrDeTZcRqUBNeH2$Y-}S7Bbz@ z9$EsbFlbze*B43<e$v*%yOw=o>;TFy1gva0JT)Vm-P|06W2De>1A?U-Lsh@v!-S4) zCNR}X?9XhnTB9acHqK+&o-QM5^GI2?%7>2`?oh4|t3CLXNqq&XtyElUs~tgR&k~{| z-<htbk@1fN^_Expyw4QDplZ`4b{5rUF6TzuOlkmX7(8+j2JWakdYO4i<I-;FsP*af z8Gh7c)Efjo5HT&$W6q#?>@by4|75t3+UB+Qhe)#sA0ChCrS+0H4=<%eC9?v9&Tz4H zc=zhah`fBJ(@-1sb9mH=cq-_~)-ru{ZMuHzA>aRMIWAoD_|K)O9`VlZQjowdcW1X> z+iK3=vS8&q*l-tGTZ=(4pWSdd`t3aSuZ}X_`X$bcMTBo6*YMXLV>#+C{$cns|9Mu3 zUlZKgAq~MF@2W_xzU>${EAW!+(Wfu3h4*i3tm%Xc)#^O>^+bKqbG058iKa!1;`qSC zY7L9UQ6Yjx<*NMO?z_mVW$4KD3xbb<hkEz@m78;F?><9v?QyT6Q!gYlfWMQ0Nt;Q% z!<o!}rc{<y;q~D>nK}TW9rGZ+t|GFdSy)$R8Ley+VlGV!Q5_)J+il@Ln>3v{VgOMO z6EX4~nl&F}7Y_3~i^xrn>r7wTXJelIeU!AR`#Du0KRsnO0gMBMl_Pd5nDDMr&9f;$ z-A!5pTGDPATUMK0b;VoN^Hu&9=D63Xz&&EGFU-Gx#wl=b-Vy_+hGo9nY^6)nnaTMi zQ1Zl*wz|X5B~(=S06w}U+Xz%MYKyOE)qx96IB6eM_4)ngi?KJ37Ro>Pk&t%5nyDu! zdcJ-%ljVB8e=zm=5DDPmGc4dN+W{zOg!}b8Gs41PTrw!@RK?{6E)Eat!j`4f*$;db z-vS;w)(N@|R2%CbzjeBIe$?5)bS6rAL2-Ub$lz%Ssr(R^2COM#vM)dPMjL1!|2S0^ zQRA8bS2kX{P|fJs0vouJM~DSJAo@Aj-v{@pIAII-$@s3L@)UX2D8ctQa1rS*w!>_3 zkbwt?&?NQ?mtEQkbanNlyrJ-KiMsMlPe|Sc9i?wtFg>Wc8V-r7d(J#^ck}+q(bLQ* z-au;2+k+uV-wqF3$Y<g=tz)A$*=<d))lK=hz=@AdErOkil1DlQn(N=h*T0F(t@qP# zE+4ba1KnTCd`*@L!IB`swg+EllwF-vBm^ra7Jb`Cu)kYk;9Y!;?Iz#EEi5git2UP_ zDQ8@M$dwC6nGVF*9Y{$b*U<(`HdBE4nMS&_d#_*MKe?nIgNB)I8XZ9;{4K~5R1d{@ zfrva&8gT;maMV1*>h2vWjw^llKGhVP9o#1^8*Izeiby(cDeyK-PTI(U+Z&lO!Mp0R zx2nf%G(ysJLHh-Y>q7o!-YQ@Zmn#Qua4p9gydlZ}{?+nX((#u0kB+r7aEF&^;;L!7 z^fxf#-$^5-O%sQ9^#Z|R!Z#c6b1W4mZ{+fACr6XuZjf8Am&U97I|{^G<NQCpDizn? zk?tIoE@rjtoj)qCf^~u7pKw*O54?4Q!dehZzL~UmSqC`j)`S32jDp1;y7Bij3I@28 zP#j$Ott`T0z~vb^{6v@f2k`xJ&F`YufN5#0A6WlnMq((WfU->gMkwj+m0iG{#^Yb2 z#S<gl_0w5c_m-Dfae3%rFE7A+HnW^nSFrg;6=&xkl0%Op=$-kD&^PmhNBEmv>6`kD zYiNDu7#3m0qRWkQ1pO^Ee9L}B%-<IlMQCD0dsnCJR)0IYj&pLVZ@T9Gg_1)KdB7pj zVvcW!31bgQ&SQ<jIXN8fXwE1_{=U0F4D=@8s_TTI%P=SfQ*uSVsY=&ce<HncDs$Ys z&$4z~hexG>qf$VQX3d;bSXfMe)#f&<t~=F%Vgb8$a1nfkd=0*$MKf5n@nd-38eVdL zGtMwr8^9jDe&2mxOCS7gqAlxtB)&9Wj><#wwuttl@guUOU_g!F+JfdqwbKt8ZD%0k zQETxl?{}rH(FXALH|b&1Ikp%vpC0kjF7eVy|2VPyAlcqZ&(w8aVgXFc6T+d(F9dA} zqRkl@q8uZGI-sHd`vS2EMv#F#$064bKolj4c}dN`xoJx$4kpm%l6p?i+bJYn*WQ!@ zrx9hl&+t_AR7WiS7g>3^jxf<f`;P1@Fvf|YSk`ShuPkmbw(+wZJxoh?eKa!-MUC5B zJ-`tA=pb$#sdtY)*|NNfhT%72rVPaC3Efkty6ey7RV^qfe&0(d;fj@MiB0^3C(Grq z5H~#cnW)6cMI}j8r0b>DA!kqSI3n%Z@uEfPzUHpDx6rUbL6Sj19d%T5mi4<B!mbL2 zkyWcZV_*S;!2&DnTs%Y&f|N^?XGTXPiz^sWk2H!U+}Fon1HC8<om;OC?U}vZQBWct zQV;a-vgRvY7{fKWB<tGqYcDd`z=+?S`Azqi;}W~HI#@VGsk>%|LlE80|4YSBY;k%h zK-=T*M-=;%MJ~R^a`IEIT*8OI_GqP7#qpya#I2p{B~0*%be318#gPe(R(rVDLTuh2 z9HNBmpp)Ujpf=}wSe%C0z=&@-bKCidfn4$a3QL}nyL<2pciYs5lh8MpX2*L!XWlt| zYLP#G3Wj9ZbH8m9Y3=zs!X5!#?MZ4mKdpNZSw$aSMa&rd7D&oNZ+!dn(xYKz>H-7u zb>Q)(J)+gv58c_f<#&x@L-hLc^>H%~a6`|Zhg}ujJ)P6aB(NUeB@n-EN@+Oh3luxt zJubMsDDMlF9Sr`3hm3ilG|6AfhXCH*{dF41&jqi7*Ok-z<$G%qzwf)X=o;y;^-?7* z3wF!MgsSBi-}KMW?R)hf_04vQ7HUJ?l>{nMqh;|TV{QbC-lbSi-~EV2>XHs#WcYV} z<tO$#?qU9Zn!i_P@2{j@DE4JEwC`)f%HwbgZkJ+_pKeaLL;oxz7JUU)EeZF3X7T|2 z6rTPgV~XGC43_H*_=TYyQoLd9u57|P$tA6GS+`L~hPyekM1+r}etpMAdG}uh=x1xb zkOBV?=b&06r+3eFzzDF)q`l+O5Cko~RtYJJi4iY)!pwtxZc}Rss&%)Z?DYsKwf{I^ z152~>@|H)1oOUO-icaf4z5jFey8p{13GDT2#erjWw+{?m$5Nuq<u>SQ8J;kO(}<3Z z_#E)~6*DKl1OtCUQ~U{$*IY&itk|}G_L_Kjrah^YCSVjcQ?L59NVM{x=kmN<>{5~F za>Y*~tdQVw4n87Fj<mavpz+fXUoP#gyJMau?VIkP9o#6ufI2RJ;+-arR<g2^l@>Hq z#910nIjy^ly>+yX(Okw(Zv(k#3f9v@<ZKn{+RhfSI`9n;=wbLk`Vant@25reMx~O* zDoE_H*QO_a+Et(HvF>k_Ls%T}(|X?DT8FN(wUKSY^FKz!mQcAI*yT6IYaD~p{hAZ} z;{TSPmfzLA|FmBzoCreQyUpLRZ&oN5&3%h5CkvXJ?xloh^FGzho+~9XbUf$LSWo~> zI`KNCm~7N2>**aj!Sg%$4q@N*giG$#9Uk5prM!2Yxs2Y`mj0q8|L2rVCJjW|s`1$Y zNn)6I#mF{J*By%O0T17s2)w&CE}eIG4=?-f{$gEPO7tzxTo54Zxi-3=xU=L>l`q8R zq#5PS)Au?p#>?+%UttJxK1ARD=fUM3HjDy7b$L7$fwLEIPr<)#D<xV@NnbI+TgDt9 ztzRFEAY01}MyP6-7%Y2a8T?;$Z>>f@vx=Z%K+-j2(cR<9U3-`g<E|DGSN>)Dg<u2p z0B1Fz_+vHLJ{C@~!A$p66&CbOthw%|S3o^4Vi8c|F+yPJ0xJ(KsqS$1+xVDU1qNFW zpHmWh->MM|05NP3v@s9wX^-IMGmsh`1f;h=<0l>#hqnxmahpV)G^fB9$fhT2YRX*N zav)JtKIMn_ETDAq4GQZW4IeH{r~Z6FEo<AG{(?8cXr@>1>dNSXIr7^2-t4D{ueqs$ z8mEyocZLo73Obs<efA!gi5(}RVKXROHTyz?;Ff^^9wY*=PS=>8Y_^U5TUDH|eBv)# zQJ&CpO{j${##;Q!`NXxY;)Ch870aPASC<32Ll7~l5KVkhKTGznFCcHqeN^#bMobLJ za8V!lfBOaZjw;Omtl#{*e&hf55$+w0Rqdvw`4agp$^w>eFk^2p|C=PA@K;Lf)vU;! zrz3Iatb9iz{^}s!t%{0_Xhlt3x;8O(JDHRB?sG>`rG<u<ra3qScPCkqlYN4c_ow#$ zEyq!&8?t~@ENtlr#=&OgC~Fx@&P8c3A7e$aG5=*%=q@|e7@8vVcG`D2-YHEzPd%qX z(;3~mn*G9SHORzfel7H?<*;n*W$FcdDIAQva6W?Ul$)%M^kc+UQ1m<E4Z|q&t=fah zsj4GJM+E=wjYs7c#r9qG*ZJ>@b`<$e#ND5+*(dBwrhXwJwp9`(Q@WrySXJzD(|Yv- zKFED_ssi?z_CLudmn3(EsIhT;YP&NZMJ3D{d-+3*AtHOWeAWP3QG%d_K`OyRv6=7E zLcA2bXmMIRymj?WSLUUITUndpcZ@aQ(%BX5=Q~k<x#QAmjW1^Ob)cEhvv;F?nyP8I z7R);{)h;1v>y$^;nVk=Qv-E)rx}-k`ZUsnC#N@epYvgXH<iYaWSPc+NNh34<XB*|) zBZ-;Dzemz5D^&W6u`MTO+aBJn@ynRTcL2>ADM<k*wfRdnPR{7s2@*V~*)IeUg5CrV z)+yhl9=$#dVZ-Znd-aaTMwP+_Lw|M2_;a%1d^j1QH_4vf*7lB3($SNK-{^64RG(rv z^ZFk*Opu9we*^0}4EJU8@~@!^=ZJ#gA63}R=(!xQA0JU1kIDU?bx?0vRVgrdjme9D zp6*dhRAB2BhS+cM-<DoTSd{dCNgKFv%@fZUJT5iOvz{`1H;Ji#lqYPR^jKrN$2?A) z$d2AQS7S|>#*~ts?|tA3ffq%jBxO`P>xvL)&B`v$<EM(5YU1v1+?$#I^&USFUe-Wy z$NONtgejU3Rf%ox5`fZtp{+I~!sL{6Ve*Du=o-lv(ezkRm4}KqzAA3iSE7u$$_T0- z^kQVx-wJlW__V2B;MZDpcTt-Knybp){-hBgefBnt=JaO6iEG#gujVA#=ANEr;~&`j zEZ3Rs<@Vk6*4`d>y*)NBg7V*lL7Oux6kfvy+J`pv!5>m)V0jR!peK)Ca@vg65c!15 zIaqw&rhMB$*Ow53pmLB2lS018BmYRX-mW=IeBAkd8<W*OAd`pWNODuw;)|TbjZQno z-1cj_g?+Y7wmlAy5dXnwiaEs}QM}R3c`Gp>lrig%S%!y1S8q=l8kB{ItYUY13!Tta z3Lz?ulBC1gWJadvjPC5NqYmAVoAhQ!zKfdvSYdz2ztccUW;8DH;Su{NiDXny7CGwK zN1-8>SA5or{MPTpJxe)P$x@7V(hB6FXF9U^q95!$$o+A&WtF_C>s=<#JaNhhQV6pz zG?Tc#z??>$+<55``#l+|6QSC}oR%-Cm!2ftcQQ#zQ8UORoqH3?yV8{1tx=g?`kW5- zx{HoxjYJixT9Bcr=9Jz0blm2~X}YB`GE_0<s~r@6;!n7HR?e1I-bCiPT6DLZ=I|-- zd40Z3&2q~rDwzAcjW4ag4mh%~LOSB<-Lzl|ZD~5(rf`_aL`omc8SgV)A---w;&@MD zt~oH8mzk$+kSXkQCi+3FPYtL6K`%^_o+`TSi`?|3+V&ks<{^}!ajkWBCTh^~9hl3t zb#KzA(-sn-19HW;^=g^RU-L5KRBGGzn^(j#^0MiK0(YBP;5X}I(f|DeP5Bpzp=zA) zSj+R}BhYHdlhPEA?Z_KGxJZn=O1ru>Hogj_I8IRZolhQV)dSaGaLGkKr9VoWLw-d{ z9CPqwgVq|Qap|V_a}rC|I7hq@yKrQvoCz`{NSg6LLb#jJCu0AcrJMK8ywRxi?H2M= zi_xl4N0e>as`$%;ZJ*~Eku4VkBT4knfS;=PgJHsU1T6Qe`6EsV&BU6^mccb~@CU<e zFmI}_-_U)PLU}+udqt&A8s~kyxu8I4s!ZFi$EOc9#>7smO=fCBA~`{O4|DFAk$u~W z6*WaTe#&ehg>!@lqf!C@=}8yp0j|a`NM@xSt;nAD#M;Dm8L-i^m?)EVmWRD7mft8P zw7<{Qo;_O$La}L{`mJP2bCOMGi;zv<*N_B?ElWwwFa78_YDdSTV!fVgy?IitYuV&L zv3|-e4`cjJh}Yr)%A=^rX}igbj~VqY(VYkP%av<*Gvj8`uj%UU&D=u20D8W4U^7)f zCUc#<4)iX@pHa<@w6xPu+<q71a=<ckWyV>yq2)ks1e!ZJF!#E)c{~(6Rix~uQpJDw zTz>QU>4qz)xzX)pV6)eg@njDTTab*X`!MiXdO)$``;Q6xL?xcG>Z@Uy*aGW?iX*`V z-fj<7Ess?7O&cSrS@N|dFY`ruAw<Ll((>U|lL{PY@~C6-Bki#>eb5YkqOK&g^&<nB zC!4$B;m_dU6iDo)`fs@x-EB7{iFdyY+aQD*W|dP4o($^JhliUK+@E1h3bDu+2~r`B zJ##S^;^=M^;>M`_l4PGDK4TSdGY2fby?<pSMT9x#>;UKMC|{{85cZ=Lg;$cLYM1Oc zpbYg$*N&Dkao&27?DU5VxNlY&GrwC}T@8s%RuT_re>FHvFB(%^85MmSo;p90Sgs;K zejkwn06^*8myBh*-+fLF^NM{=I4&^*Ahm1EclFaU9RUrFjcr!A;&S|C=u!1_?*zao z5|vOrpqK%)U^Hv^eR9CGe$hA6K){@jN={hPj5|JJ>u%$fDJZSAzZGKl${H~D`0M(| z<Jh)LK)Wp<462!_+BOH#Z(;23R~CC=Q+5TQGY3928}S0Fdyugu5G-Cy5;rRIu+FM? z=s~;1WkAZQxN$6`Uc-_qJHqAInTm^^jZu+k7&)ZO*jXt<?py4o)Qngu0#joAlHTWA zPl9fk1omHK)4zKWQcRy?Mc5T7mBV;vK9CWA{{~xhbk@X&ZXCzJi{lsqU1)KRT*7mk zL!13S$uy2>qS@WbQx(s<V-v)G`+^blX#X9&k3GH<b%o*RfC@_iS;jj?aYz<~`!apA zzWMa~)%q^9j91|3$S3etqi}`RO83kNDZeIJ6sem+k>hwMKz2~!J9wYP^P-}>N!Yqx zb2fu}(>HpPdnl!xXNfFBg!;(w``W@OZ&Y%<%~!*b=a$l$)Zm9)()TEQY#|H_B0H{o zs<D`FE3HTS9WlMgxYensUb31|XzSw)mG$zQM!th)bQ0pUcbY5%mo%PY)5D7*m*Rxo zX)}Hb?nP+QG7U{sU6n9RZTlN$>dh9E7bA@|H}sj~C^YTL{A-cE<)O%defub}6YmF+ zgpO7VPbynK+ZOb72`lZ>iuuz+o&W?w)p4+Wj=hqQovH`99G;?A$cH;;u~A2&KOVPv zqc!)Wl;OWUx4qS~RS&O{(!_07XOs0vqjZD?k1N6@yK)%(_MWYE{SHx?rq|dYg6o%^ zI4YF|>^Ge8{8ns$uKB5CZL7}H#h9S{H89ITu%-ISDv1Zd4=E(Bx@*=ivv-v^<S2lG z`MSE3dOORZzZ&y0v9WT7XFiTNF`{|7T3GW*u1QDs1DKZT<|yKy7%|K+{-`L9W_k)x zE6`c>+sK)-&2+aXd(pj0P@Qu;e`Rd`&=$BhHo4A!wDnjoCG+M}!YHGkUd&-NRU!O_ zUe(`pgFh=0F(rUECJ})n@`=qx`u(|~zce{E3gSW)tFqi@SVcn2rBXVV@8D7vex3NK z%w#5wBl>a3t@mjyoYE#lTRPHaDov-mCML`tmL|%pU~K!@KiW-aKOh-xJ<QEfwe)!S z{@X^8b=TOdHg2+{M%A>q=N5%4<kSq5M|5EqcS%bLgKKrbweJ`nN>GMgcY7Dz?yrBp z^eD$5^E0ce>-t*&^lC6AYNc=g>9B|@_#?5XD?vCi?qbu}`N?ninak!sz8x3Kfy-|1 z9YN*i$#atE>Gy<nkSY~Au&D>VQQ>%KmTLnaPphBhKvU-9-)E&%#eRv5xKd`MqoWg( zxCRM7c~Fpd!;K?7w(80sj96+yOSbpkp}O^1COh2WHvi`hIlzM7^hL>up<y$A@v0Fq zbnF*g9kOr8CmcgSB#?c^wAc|TH|8u<!yCjXQ7f1<yKTL98bO+W%XqYIjjkZQ3Jl*G zHH(x}v-zO*h;>wmMuUE`Td*%WCQ>Hz%lQ>TcNJ|kjC`?*^51k4v9y_S34!U%WG52c zf<#hDoTYYQgRsq*)gQcN<(sgR5oqRXIbVJ@u$~}Tuc;LnD*fDFDz}`_$7Dv%Up0rn z`;yZ3t~=XAf~85yu0n3w)yB@b;PpY<-E&vxad(HH%{}V5396tc-bYD^2Z}h4ngP&r z$_8SM)*k56|F%X%#--n8<ZqI$c-DP3@7UqR6u2wHoEm~>&LHQjG-|(RPDM4y*Fo2e zSH!YNBGvZ@PtlgdM)c{3SBcBD$8+zwZA*G7a6qs_T4nAI-zXWFXH2?pOcA-j(v-*Y zqg`}%b)_6K#*$>de#1VZKUz0J`i!&kS;P+u)id?L%QBM(gT}9+xn)YXAP!|K4Vel2 zE6B8gxshYzRm^ub{%bTL!O1Ae%sxSdNv}C^Ot9C;O+$u&Ui1U->Du5c#;&G3qc>uj zzK=`@eH;8=F+`od<v6m<vMVXF?-k!S?zoaiPRNXFvvVk)L9l+<nZ8-O3z0RF*gW)t z8diUnKQr8pr_8gwwOM_e7*vxl4OGPm4;M*LUgzW7zJ5&t*c=Uq)5o>EzqO8W){!I} zz>L3C9+*)UL%wz@&DZr?WMeMB&-}l_k~6EK#JS)ZIQ%TouUXsgHLiGU;T-?5=KtO# zi)P=XlLm?3@(#?BqkiN#p{?<p?W5oe%q*qKcgsIaM)fMm(AzBjF&v6<N^yAymnK7@ zG9MvJq-NX1B)NFwi`z|XZxdBNFy;_<5P}I|+TDn=GDv@$q~rP_Yr-S>4#+bO7g zi82=%pjH1Frt{^&(ts)Qf|EL}Dp|9Wf`+8mJZ4?!iFx7#5zVV6qIWz!{cuc7WWn@E z#F^B<WyX=oP!t2o<2}lw*q)!krisQzV!&ItgC|tm?&<KHTv{!n57_OX2n6SShlntm zLeS{Sn)jwssj*RigBD05L^a_!+%U+*#<)#;=OL%)qO^hXzo3OBqn0MbJM0MtMWjiP z5=I;wIYL0U)az^Cwct~Eu({{!55bhTUJJqIc24ZiP?qAc?1pFI`{hk85akxEd%usV zEyUR(gVtJ#fhveZqSG!jhO9bE!20!Kj;de4(|2$07Z{j*iR>rW<Q(}iVU;n2*gEoU zAIC9omf)4G@YJ?CE9RT~iYN5E@VA5V1pUsD@`iFUIxJCUb17*0^Y^0mQKry_5l=05 z<~;+%TqP6STX4jaysR)>B^_zge=Rk0y^Ig)a#V1O;+$}*Osa%jeBaYu?{hLiHnEf9 zG8Am#mJ@$uiTi(vM5=#8;-@J4HOqlN>o5MU6aSy}T&F*Z#O=Ri<Guf{NW3^YO8Jw~ zKye5%2VDP0mnHtoZM^%s{Yg9y+veWa*&qFBGQX6yF{*Mp>9OnR`q{1|g-wOzvs}|| zo_{DVt}&0%b5AiDU&G>Y5}u_sp>bsdD>fZ@?R`#$$Jtq;=T(0E;jopvr#|J#PwDn7 zy$1Z=vSwFmG3|+u-1y8Iyfj!*bFcx7{FVnbEacbBY@<B6rpuXB7=EB+^k6Re^W<>M zOzs7KXoxzeIaR%a=d+o4nU|pfv_~zZI0GAXlkKZ3XE0q<)s<YBU_VD_RqQ}qIscN% z?$Ax(+F3C7rCFG_{YP4Pk1e#rlQ8FxvR&g0kM{)DtcOp7GpIPO`qSrGm&xGcXg&9z zgeUGlZIn0Vr>)VA3jisNlTYtDz=nX^$<wKgZ;A!M<y%0LK{6_7yjiyPU#zm-{0Hnv zvZZ`L&D}Nob-(woG?X0n`lcE;0pO3mhSe5B^=6qGA2K74n+yk$Mf*{uhA#}OvPvJZ zv3C7@k=Z$hSBbdaJ^`22hL3CldFwQJ?_kWn6k5v7ySM{Q4z3%q+x;iO6=)P1_U(5g z$Q`wMrQ|c19;FH(42L~8D=3~WS_Z1Pvp>^}Ots&>0s~hwb?Pz)JhAUDrJVSN{i0R{ zn%18+n0ZC-ahzDCxTcktw@twnz1!fcF#S=#$$y2*)v$kW!UA8m2V4jH3B6$cUy0z7 zU5pBRAas?kX047IH;Pcn+b1}z$}8*tV~n^skJi__VW<m@6M+KA`^B3a-~M2X+?xr` z$D2@dP?3-3!CY68&szkczC-Nd&#Ya|@wQfzta8p%{;n(0+y_=x!57n=EUcn8d)cdd z?Rqj5Zg|{L`SbW*ip3H(%C}<vJDesh;ZzRlUd_w=`0%H1)qDxQOcH=}yY!ks70T&f zsyleyDeEenVVodsUx5`cf2AtZSH*U_*0)rN)d|VBY9|}ZhNS`UOxP7Q-m^z^j9Xy{ z_?!>;6Q_GLn(kOYp7i^pud38u)DSiS5Ds|3ud}@&VM!SjUmrq6)BLBUWy$Q%!ZUx5 zK4fUd;vh82a2<caZ_x4GHbj9Anh4`%UoH%3i(fO2>L~yi%=t9GN_)&<5mAssiyNcY zT*%UMgF|L}(C>b|a!2M>DK1p#5dvB?i+%N5WDebxI2gXa+rRJT0(iRfN&m$R_pU&D zCE4UxVv~Wzi8h<LOZfvrJm?qElaSH9q(hyHV46Tp9AL5g6yR<-Xi`w(^fs57^HOH7 zlHAui(J%t&njYhluDyY=X+e_>}_NB-kh3wC<STp#3$qYn+$qwPyBF{(i!GQS! z@s^^kAxZ0t(##>#KvMt&vyMGlih5}ZF+o?MGx?iF_gc>q{4RAtTOTf-IOXBy+h6*6 zMPx=$mZMttWudpjhu{rm2Mx}}d%iv}g{}_fGCqU$qf{Ww%)R@lvN-Yy{I$0RQ>i{& z9O$d!-*VqDEcWTy(B<9&x_RVFtH?qX(~$JvYJ(&|@}qb=+RQCY2!CJKN>Zcmxu^O< zzWNH{lG*;NmfmAZ45qf>Lom?v^4aJj_u0<Xtwmz%gMPTatLEQAKsJ{T(93hHU^awb zC-uivNWN)$=0^zh%r|rMPeEm_aIyP;69)gMJrrHA{2%RstM}!fIL^P?!*`taK*jBz z#V}hI=P{Sr4pRIZ$%(JT;JL18Fy0lqoA|x|?)}G!Ig>HaU0>h=f{GB&<)DUqvE|M2 z<>XJ=4-}i%rtanb$fuVuny`*~?+!kWS$?09sa<2;J;?5MfiyF8gz$Q@kC|HG!Z?1- zP?GIQSrs?F+^nQDv*i`FtTX{<N@8f{+y}nuZvnAWA5KJ(mV49relxqN>ZuneGE>j# z4k}n3#0g0}>)RMRfZ#np>dTRCR7wy=*K-U}C>gGkAs_6vIH@qNSv%Z{UE3Y3;m>$7 zxN9=nR`R&h_VGT0m&7Y|hmWH>$&cv;1~$pgW9FV8J{V_Lw;=Z*;MgL$J<peadyJel z(NK=$#-2H&Npv4URMSuPuAvhc=;Q_amNZh278o|xPv4fVm83JOFA+jlXlG1w^0hJc zu8G5QPx~O18b;ldW5+Fj_s`fU6RiESdcJ9DnWi$AYG0T7CVirl&?Q`BSB#U3YkzW- z4=IujR+WK#+r80VW~<da|0PL4UsYe)jb<mWr>pMicJ=)J43YZV7A}kdbzP2afItha z^oxE?$Mt5e!ODp5Q@U4Ec^5L=lTRLmm|H&!b|K6`<s6>2(pC%u)!NwmM<{EgFn1<W z+ZTB18y<Jpxa@UX3x00ea1jgR{=mF0C+(eNx!L96lmHQ2Syu09ITE*CRJAJz@}NUz z9G<*s5OL$%&2n8FD@k<Y^R+wRRR!_RxbM2`ZUxX9_OxufY7S~<*ffBBPa3mLp=Ww} z<=9(D!cUg{P$z~QluDqedcQ7g6A)%;s#!<{w{r|BkgHB3i3Bqc!~k6wSM2rHmz<P( z6f1_U{nQ3~{l+oziBY`*M~*7uj^foDkH1sIqin;4a`1l(c^CCw6e)q9QXL%+D!j%{ z>Rj~pJ>S5362ef)!Jpi(9WJ|Dko-zuEVgL})!8zeB$|?_TeYF`!Nxwq-|mYP+@F13 zid>H-YqjWsP&zHIr$~cl6Se)VKz2J}xG+p(eb7>NNz`Wk2wrQ)IC06ahEo5X%^V#e zx7NT1({dqoWSc}Z4BN>eY``}hZApo_;r5%uylk-H>QkSov?6hm@!6Ja*GUr5(`XPU zOzYsEA2Q`1QKV|@{^$_{xx{&h$D;|pJ%cPlT(IYDwWj+V?nUwsjYEkyKH~&G{)(ud zQSA>>s$r252lYasRK476+jr%@u{M0oy~>38)<VmbZ)Dvh2S0r0b(34hm#$i2G*#w@ zd{Q<Ol3Rz^egBodKi_sSa_9Z(S$BQg9CL#($0WhZ42j||0B+iNkmR0=TVx<)p8@+O z7K9g}46T#0SS?eZbDybQA=}dm@-3=6k_upuSO`mZbPW~=p0%~;7K!rEAocX9Q`ac6 z9IFs}wJ4M5eZV5@H6@rLCw4&5+TG;^%sYCj+w((Z2A)zrBj%ABmj2yYY8p{+`OY$| z_3?J5dRZNRtA7Go1lBQEz|6m+<&Zx8$i%6~lw3__NjAqAFW?;g_!`5o6hw*b0VVfN z1W4_;NNy_5GBP?#rX`L%M#~S6NS^L^E?)`9U*PPLB(kZ+{K9Q=<R|o7xWvw$DjFo( zw-3Z)1^g&V8WYGE9qGS*&TtiZ(e;>gb;kMgFpH~_ab<w$&Dm~zH|4^l7T&|ECu`qo zv0ck?$IXY@jnKaSf%R)7`-xc>#^be^q>4A&F-S{-Let_fKwM=}NH8bXozUE8?Z|Zo zC2lp-aXIOe*rglEfh7+n>D%lN*?mtYkqj%Wd{3G%GNTLA+HRa9!dE%Y@jkWknvC_L zR$&TJ>{YS8X4GQ$n*7{^%r=nlJj%ZlC9JwBbHdq~`x_aH@?D2NHa0CiSsxSa)ljUM z;Offlvy1ayrvy2?vz&b>D-I+%fX5j@n7APWVd>U58KHO}M54Vg=~B>1V*^!_cTsa1 zRL`qnY#ZSpeH>p$rgNZ=Z`u&(?g`Rx?Z-Tl=IC#0`t7{!76i}xOgqkSbBJXXDA6lD zlwHt~t=B#LzAHP1J7&vCl7EV2S0CfHrk%<>6q6!$Y`EFy*zYBz_+P!22oFo|4q^2V z#tm_ob7pg5E|r-suc^DB^aXry4+)+qQoovbo07s^ckEkL6?+uo-I&_zTSbSRMe#SB z{6}skHT~%%2SxdX$597`Whp5{$q@c97N4&$W_$U(+pcLUUTxu(m3H*jq~YaF6Y+D3 zOC5se9yoj=zJz#aK5;4!#83T_)8Z5>E-5aVNrGn$DE71UlMEg1$R?ao7;tyAU{NT9 z(Zfp*40kVV&#@1gM=lCqUFzgfVXC_{@s}>-O$5j6fCMJy`DN6@h*vYg0il)z_IPF@ zd>KSIG4R?YCYUiONHnrMg#xJlTX(2V(!zpxt~RuUyFP%-9VGo#xX~tcbt1-3oEZA8 zgR@3m{6$a5T%XW88TvBCGK$WgtA`IQm7q!7l0f4_KlNlt-_>?()bL?EYLIo997$9) z*av4jD|+*M4NAKCO}`G<wTqn4Ms(H{Y`lQYC*ndjJ93LWy`7^OcJ~5g*L3kr3WIq} z1jg<+e0Ub(&Oz7c&vk$aKWurMQCmcncg`RYryJB;0d?)GW8M&N_+bhN2ZvAV$4u*| zL<<1NWidYPYi#bn&Jr}mW==#K!80`6(xSuBp^oH{#Dh)L7L(x|8qpJVN8D>vakF2R zUOu>Ien9T?l28EWGgjP6&7%P=<}>j?q3jo2h;ETz7$1d<&uB8&P4?xPA;W@W&ac9e z{MH?C|8Jsp-`9pw9@OtRe8BIPxDRljQhjkD!Ow&Dz3#|aA^l_iqXwq~>$92XgS~nm z2toNrR@*;fTOaPwf4$9VdQIP)_vlz>5$NqD*0;Igzbdc}D+Xj;6#lLHVZeOc+B`9s zlIbMjo|HJ~@+R-hiA3}j>CHBu_XZ>Vn%y0QFf)_&tPEGFZ);|Zi3nu92Q^{b87JxI zwH4;>jvI*H8@Dk-*BXnlYx6$+uvBvukjm%){GM|$m$ORKP(wztZc-bWs{MXI{Yba> zoEYp`VcQdb;nWjt_Xj)tZRMlVMp;qlL2VT>rT)7zy&X)fvxN4q_5cM$nP(;r6!EWd z)J78rIM{zMrB2;H*gt5a+3*lB<!KNEg`gSF|Aj&R*8t~QphzPP{3}}oY=E<u-g7Wf zwx^_m9eCL%1SpKC+2)-Svn)TgzG7nMr)>XYC*k@Q!}aN&;}pTo^*iL#6j#iM;dKnT ztmejE-}djh_^MBdmWp$c^RPm9{;G-SUaMzmud=fwjY@2M-_c07#AasTTHgwCY2M11 zi37tn--~Hn2+zmAAv}cOhfjnafzw90XkMkTyyIzKmA5asvWEB0qas)R6phQ1>%iyp zU=LNW2kc9)?%*%H4b~Ia=Hm%B-Xj~pxAbsS=?CDD0u+1=Zq<EJ2Kd@%BTk-c@fIN@ zZQp$cHXW_w1x>p8GkWh&e^U_$Fg)C`o!n14UdH~s07_>t94SSoh_a8ZzlyHl!p^s# zL}+$5e9y}-kIN56;{SH7M=R9&3xSA?BZMbXZD)y@e)B|au9FqBVU-(&|0`NJ5+r1{ zPNi=5lJ0)e7D;CAuTdifG90wQLbuAbp$z&KQ3d*Xy-Y^pUIrOE_f2fHLX!!X1QhHI zS5~p7h39j!3uyf8b5&AiTh|@rcAc?ni^L7Ag&QMKOiz~sq%7NpPAXdK^Z=yCS7D7B zWv*aHgEo%e0D~CCw>__>a2Y)8_FTKcBRDvK=g9HL2tEh12*;VHGvqC4vDmxx1Xq5e zeHHN)7<L`@0;g#F=c&XciKZIbY%Hp-!0^{$_x|sC<DYfzzw3XDod0<<afzgzB~>m5 zXRK?me}{{Nf39;C^Pl+t#fnM@y{$c`H6ks2rMX+XEY6W^G1c|Pg1qH5&T}qZ0dW|Q zlsMP4eI)JtII5b&(bgxi<gguxZgI*$;eE_k|7cS9z~W==syD-kg5)=1`R6-!4*6}? zKE6zvv&pxqa$C(ucj0xL&?d^y{3z7d@>H-*KA;G$_mE7J2+nlm#6s`CrcF98%G&X9 zB8ta?38uEx!QSxc*Op3uiY7IcOcdu$XIVw7->(eb(!d+gCIf;$I0hzGT=!Lso%AoB z10jcM%zHu}y{|xPfwG0KsI`@4bB-TAe#l9~lTN2`6JmOJW^1nL14!%G0n7$iFz<<_ zddIkqwd{G~43s`ux)sn$CSnI%yyLgs65z-w!ulbz6&SBjLRmM8R#Up$wC6hJ+agEZ z<2H}}0+03J!Q9s6Qu_l|Hb$N*^_jt^=i3SA+jP)xxnEW?lEsuo#FWP)N#^1?cc|?} z89I;sl`k+Y&rVUmlXAWJ0(Lo;f-h*M_1sD1Pyq(AbbXcGi>w-hJCQl<>~2m)@xwWU zwQ?;?FQp99lL#c-tA^eFQX61jTu3TMkX!&nVF_Hcj6sGYaZ1PQTVcbK@+5Jt^1X9l zam@^ur~%Ab!R7G@^Wm7n|K}uvE@q$YJ{3cfqHqw7-`9UpwSB$!j*bEi{{t>)jw=HG z&w7R3G>*5R{j=XKCaSL&8yOY#pLqIa<j*J`k4se(nZmyyg_@F(Wzw(GC7;<m4cYnI zP1+nF`ah$1K1`X8Mk>9%pb|aSWZCbFk^YpYs>4yQ9(OP73$I}rD+Gb^_Xk7q@ocaC zD9bu*Z~Kn8ReVxY3b`?~+l^dN>&<)tnZ_6rjp%n`?n=b7*o%VHB8#XNQmkjU^Y>0q z`7CdJd-ii}+vX3BQ&{S%5-MYJN$Ya+9_C<N-1UgsC6B|>_N$!lC&-hF8Mf;etG*re z#7A{;l~tW@e}9ioz8#`y2Dh>+Fde9em{lz|v|{)Uq=)x9;F<iz@`$NkQlBW^4;%>h zN3(_y{(JEr>!K-Gmk92F&2Q5(EDVgK>{rSl-y$#M@B=J-V_U#oH1$YuT}?ymq2jqI z@wtjUtc<6%;AFS;;`Hf!T(`bzxBj=43g%eqHbZbl-LU#z+c}qwq-H1P(7;ciV@nR7 z;!y<Emcgx-PA1`J9e$*ID|gs}w4VAz%i%>v-z!LN?6<s@;s$o?h(B6w@MBMNdUr^f z1|8{_6I}E>c$%up)rRjKBJ<!_^fsB;BIL7xpmrd}jDL#=W3!3kQ`+n(s~+w-vT7AM z@)tS#T(1!^0bXA(r#L_+g>}M70vXIHua6r}ae4d61sXk=c)(NttKG}lXqeSCw;75w zwVagZX3;4qRI}W8wD;4vVt$kga{_LY-y?rNo?h!+SoU}?HF&C#Al>S-#``)kSeV=K z@ksxg0*YyBE+k1I8Zk1Ak}UrDas#I_fNO386IPf5(dRlX?K*QZT4&J%0>>ZiEG<y) zHz8-V&jli?EL2hctmmIRG?r_p2*Z57O*a+RhWV#^f#U#LgEmuyn+N!+?$J?gIsRtT zzD1weH1)`i3XxuY*CWF}Cp6~loF=hf-}ddvsoH#Tu`*w_h-q^&bHBD{f&bVsr^u*0 zJfm)9GNHSY!<gtC9K(?V=tE_qT45wQb8F9Om*x}^UI+<DJL1IXUKX4pZk!?hH{b9- zj0juIsB@omqAU)F5%GnnQWSW=MwOTB==C?*K3EQYE$x!ux1LXbu+j%oWcsAILJ*Bh zcDhNb&cKn!#`{pdnAb2S7m5sr00C%M*-&}-Cbi2=Ue`6b%~lsR1x`iMO%9TfX$p+Y z>35vXo!e~c;qUt5MKTzW`{*p~B8bxI3k(mm@HEQF`mogNHw8EuXO3g=lkceOL}L~< zJl*|7Je>g7USlE0XT+Nm!-EA<znB`=i9dgIFwaOL@TO$?(Z1!O3frO7Ck(>JuVX8F z0(xOKdL#;7{)r3LEkbUMpH~Eyjf@obj->$~;jHmvLc;~EBkwg@*Zn8+g{Qae=>5)( z^2*<RZ`~x(lvl>tF)uALTYOPhn?pfol3#mZf=VF-`^MyT6xHN6ROn?#Shg5Re+Ck5 z5<3%cJes;4LE#`5S%jo<xzo<&vP!6iaZ66N@h6=wM;o}_9eMF$nRA6bLf`!jE@k&2 zQePrblMDFiW>*$jLkY`ErU$B8&jmBQJq!+gkq@NCPKe#XcgDp<h3+5UJh5<o@i6V& zN-A)dw+J^{!d3MxaIKj4Cmn=v?81AH5YMk8NBw;SY+uEh>mq=ve*$^{$K3Se2teEt zw(e7YN7r3X;O&zl*|LbVb}9Bpv>ms^w?gB4^REUB9dFMgDgDkH@uBFP%Zx^F4Z;pO z(OTf|l<CipY4NO-VqO&idRl*+$Nt@gMHjcB|77P*To+&vNXa5>BGcI@E9`s<d3=1$ ziba3F09rSgn^a&;q%)Qh#(kS1J<SXx6mF3dpJy)PE^IQdKRT_iWWIu#uBki%Ikfw& z-Uak>;?;(Svc6SWyhmFp5MMkS)0(t{igfH-C>!=fnzgiTpQHnz+b2sIX$bJYxQ>5s zOqRyl60|$yRzn8Vw)d?-iooZhFK^y*j;+aOn|~r3Uh<02Bj~X&FpppFQB<^I$lLJ7 zg367&L);#jk64zG@?0E!h5sg(PE9Jg#;lciX5(2R`i8==77u5TZS`l=i)5oh?y!l$ zE<2a7kfy-v=cUqoV>7J&j3mMjm6x(!c_ud?oo#))e$CkUZ{C%B@L)DQok)`Rw`KVw zQ{J$d5SQ2^pj@WOfZx<}l%3%7dpb`i?Xi9%#cxhYAuh~0=ohW#0Ontq!YG^%-k;bd zjg?qeDdL6;W0+HjCXZ~WLHqrOa_`;53c3_NKSNRz-5Twra#KuB0?;&99YuQ;3@Wx( z-4M&%J?Zk!?Mm7}S*4f40w@k7blEs7C40J5)-59?+5X@Jch`D`Bi@y@s9h|qmrJc; z^4-CB+v1|ns5ViX^2nX$1$#wQ{IwGZ@Z#AZ?nIZjFkvo;T@FS^jg#S3teE4R&U39d z`SG!%qQ`bHz`CWmF$kPa>Cc_(gc63$h63p_QsTSpY}TrY+mdhtF=@Vi`|<R7FVk8a zRquK{(H{9x-~bxjIdBFfmVy*%>KzrSmD`*)`aNIYF$Ch;HGpg71IRE36e8vS{+ADQ zzeY59x6X6miKmVU<fMV4>Hjr#)?rQkVH-yURJxG{0Z~y}7%d<ztpd{0AxJY~bax}E z)IjO((IF*B*JzL$W59q7_D+Ak@AdB4Upr^lwe9+zb9SElxj%Q|x@p;X1tu?8`lYkx zzv5%znsqvSE;^^nxTHlw9~Jz+bqPRy2B1h}bhgD(&%n0r>#Jj*j+OrZ`^IHn<FOlj z;w#r>e73#Xa?^2(G@eqTOwutUeRJ(>ajnw(nuU1CulUBZ<0kh%1tRsYpLk%vL{>do zi<GUBjG%myIg@d#_wHSa#~jbwUvLAddG+lZCl>&cR8Z7yzh>EZ$#e3j^3ZP|l*yaY zsh?Sm+~^|mawbS|#6IKw442`-e{i|qYZ3){<L_R8xvOO;=k&U9H=OgzTFdv@k!alc zc%oo|S*KBdHTS*q&P+-%*Xj+-KGt6RYAvx1#R=s8EK$#DoP_6*R^)B@9riQa&X+%1 z?F3}`tICl#e@;p+C3CPPdbATy!1=>-uVT`z3nhsU6e_)vh6M(LlIB>nLIUf^XVyR* zbvR@BJy*mcS^_040PF{?OQ;^zBA?Wnd@sQg<*Lk>>K+TzC}~=>#6)Utn#CD%P>?cv z;5twKm{T1fAo5pl<!l;oz@(maNo}IACTFVgU%Ugev>U%RdPy1IW~X2M4k(t^vgT+R zgN2<fMz8lYG2{H^nCGBpKeqopOS=5XUEt{n1NENJ$+Pr~xgQ?;l;dzN?=&lhLw((B z!6(>fyND5=f?C5&kK<%dq5Dx1HHF@|k5_xZX$L?;ik8!_qxOoJaEB<Ecb!0MIArt5 zY5RK^${o3HEqv3E3-!eyTyV}h!1H2wz*3zUE8R`*Fn^T4j}+7H)6#eaS42feMf$Gy z7yd<_QiIZ?FRO^vy)|a(>^y$O)%vDWHW!}bhf<ZC(gyp{5KLe+?0*@voU{fmT55hm znOVtKVncs0qY5rs|Eijk7OBnh*7cW~o6*k|#_1X5KYUTc|GzyCEQK{{e*BoTxn9xK z6sViEd7Tu^+B_E({ckQj{V&*lfQ75n*>hJy&(@PpJgjT`sK{ZUaFi|de9G~lVJL1X zLM*L1HQ|WQ1x7oU&T!DQA=Q1LS5Lh$1}FL&qiA|Cu#0KapCrB0NfL0*-LVh1?A0Zl ztmgcv){G-Ij3g~wb_aK`KS18<b$_Yzby(t(Dk0%2$dG3gKysS$XVh0*pAko}nw`r+ z*gaxrzPC9DALR8?5!m1|*491#W!2jBEV$F0M7izNj6P<)&i{0bBHKqe&w%ow#0LZ0 z$#-NmbmUX-%h$GEU8%0$Rq-w7=qPT3T3{LoK@GtPcLmo)g)P|Of+N=tyyb5qH3~e> z5aD+IS@Do1G^m5~y1jBx^-w1%oxjk+ZLCAPR9f@Ye_Szmrl*bMtu9St>hJfa9b$$C zvtw=_`I`6BPRrjk>Xx{|d@q@#vl(4Yel`ONZcbnQ94eQtciKOIuD95I<6ZgQQD9u6 zkyoQ^s9g$bcdzF&epYjFm2V{(UwFv;U7V8++*{22*jx#ns3=_%F+XCyPR}#QSw^%K z@qkPQCvG=m<N>KJxDV*j(X)(#6pkNi{P3;K=N&>jj!I=r9u;xv4>l{wlgEy`JglM5 zzc920t$bcgK0|oTGt*%qwy^F!vAO4xCbfScwk;5~eHQoj*Wre3J)|yh>FxE6HY{}3 z*RQI9q`8ToCv#AK^PvlQbA+M8U>_Hd>8vRN6OBxWM*aWS!9b?^rVD%wEsTvekBv4l z`tQbSHrm#|8$5yy|HW=({HJ-bd@LonH^W4h+;pm^mM_!lHh?4f2i)nfP~KF!=v5e- z3ee=C98g9ndMsfzFLI7TwS_qJebohk^D>KV{%!MUPHy)>A0W&g<@W*S%kFtB<>*6V z^pWZKfxwcvV$(h&-;y&1*WS^8|GaIH&~d!;%k!%ZysvjQuaG@(-vcfqc}O!q2oc1> zJKiQI=4fYrh|t-%t#@+teRivSfA#vZHUrpxI*{%&$Vaaves_gL>kb2J9p&r9&<tBR z1FB?E=-B5&GCu#k)*zj!u&)hrr7}Xj5%cA2VK^SuaXd=9K?6D5_ni@FuO<Bl6Vlje z!;S}Elaaon#XR!<WgcXLnmqz)!hAKH)DBCQg$z%pU0O2Jos3}LHy|wMW>+nG;cM>I z755hAe@u-1UK?|KF?hFu9UXf4?4_2n4H(~p5MsX9co08qh^5)eS67nrqfIK(DnKPn zyM+q9jgNlUSt0jB9#yP_fL=#snbqA0w%_}!Q5|44Dxui0c^&-k%5=Epn$d==VX143 zPnquRM0aoc@mu9cXM%>4@+|FuSLDSn0z_<=X|29n?|3$@U+8E^qg*iF&izgAikjZV zw>Ldgs4^;j)7_MRF7xO(IWWJ9Isc$0&}gRKzP^8#Z^ltB3e^mU-EV5ladB!<e}be~ zC=E3F(S9FvqkHsR8I&fr%jhXo`&;7~5;3=AkhuO{bYgUPaw6@4{*U%cSB<iP6N%yT zmA16Ecdig+^qiP)SF?f`Z$It}UG`Ik%N6GcVNIS+d)bbpEEY4yXz$m{026z5U#71+ z4pof3iIl)cvv?gI@;82=UTswS#y^JV+D3YpO_YH^MsjFz;jd!3EFPCV&^&3QlB7h{ zNOGQcNZz+iuo$KEB2E5PR<SH`GBCWHU<=k7_`7YS^QV|U-*x`jExaM8K=5tl=6RlL zssRd-WS9L&QN%uq3Po#vAd30Eb`)4ugF~#|_2qZ3O-t)gyS+{sIaNv_7@G(!o+yaq zcgLF9<nuPR-5vH_BX&f%!=>aTNFt%sPr}!+p?$BfnfI22PyB=*e{ml*liBheTe`%D zHwp6op`D&H;wvBA6u3@rxbCtSGOCE4R=U`9V<3Ax@)cfY*W7^9|7g&k|La1HYE-|q ztCgE(5`8Bwgq64+5G0pOsieLyUhce)zl0~Q@|rN+7JHC!U2z?lWY+ckQMhnVdX(ju z1b<{usggTyB2QLC&QTm;W-5$l`9QxFiH{{Q+B#rC_uHTEySrP+*`uw#ynkeA6EGi% zx6}Y*hAtKCF~2}Q4zT?G>H4APGDD^F#_*F3WHUT!){}@~zr<S8ens%~=eR*&-urIs zyvcGS?A3X_U6fy7t^c;stil<KFXorS66R|EZ66Z(o=ijZR2N@mSPeTa`lOEgRwzlh z%neiEverXP!S~R(<ysm}qR~0Lhra~F9@%=+uuK=UHI41p-bZa#?q0s5ynGAxS}#tq z%R9VWnSv-HE755qJE2gPhA*~zKQHbDd62kU+^%qErOVir^r(tc8`)l^k9%46;`wkd z{%M*8g8=p}ioVC-_2C7d$e2rl$-))k3^UmEH=&3z`R;lwhP5<!9a(R=RrSPDmHn>% z&#-4BT{0nN6i)=RDSA|!M2rVFpeBHEQW;-n#&6kPW|D*m@`}dCdABvEUL4l_thmtD zhU|bafS-48gc}no$%U^4|0vA>0{2N=_!HKO<n`I<TLR>A!#`TA{EBJlUrk(@_urO| z4arm3b47VF{`iJ<>ngQ4HqhP=ZP}DqpkuZ*Sf6;CFCdMZf*XI~oo*Q3wWQyd{!BtF zZHjG2D@HLi4?BNN9sjOvhXL)d%n@&OTlz30&*KsE^Wb;S8KAOZQ(h!olw^{;gc4(5 zi|hFm(1~w%p*8zP=>^9RdtUPK70yTQ3j3eJ7(0KnXJW`<(L7)!tJb%^!$7xRJHTFu z)6j8AYd=y;0sZVk=dP%~%grWwp86&N&B%dfd>yIyrAP$%?6~$2R!9&r@b))_bY?cY z|4`yMqvE&pq)S}J=EYvm(M$#>QEQhmT)1t}h0E9hzBTi~4lqldq?Vr!*y_9nS}7J~ zKZE>iwK4g$2o=dc%Y{LeU5|2imf9_(TDzO2^xAWSo3mVbMs_e;OaD5v`fAwj+5?ZP z#E-Ad<$u-L$5V#mJ3kpXx>KjT7)k7Gjx{M+**b6@O&L8pLX(5=rHhmp0VkB77C6q^ zQaG5(ut~rS^Cze_7SOenI)T@|IZL2z0pF`z!NI?eMPZUFYAdrqr;(WeD*@r87YYK< zsDVVv4-BF|kso&rgB4fFqLywRe|qppCQOj0Q}o@ZxbizHeg~ZoIBUj8dB#XcT4~sO z8;7u(;<nskCf&ygGU&^&GL)2C*nQ)&Je8|h#_KR4ObUGQ%_m`|_2h)G5HaC|15t9o zzE$8g1Kii?=gpINSpUlOER;9v{z}&E*32lQ(So^(6ZpLLW+TtfjCwF@j=JJ%+tbcc zOTdetNhhUB6}dyx&4!RX$^pY>$-bj@<S)N=3CV}IHh8iNOx=F`<m*e`&>QZeL`@EU zc)BxhzBO$<(UBSDzkQFiS+)6O>*N4|WRZpZetWtjFL1;%#Kq-k{Zm0IVc|ZJA&Xxp zc|&#l{PU)OJD)0*IX50)4<@#gRbq97@W-XGFbD8^Qu<Yy?0uG^v+|%Otk}lg|1~wn zr}hU8MYokK`FcH5%}98}ERZo`urT#JS%g?4AHp~8*>x>3H(K8KSvqt_?ZP}Dt^SK4 zFE-raZ49*5qK!8re0eg2>4k<}?npI+NP}j+zI?9UZ?K&{#Dc1c&OA*tUYuYou2V}- z2LX+OLtkw}zDM2I-26g=FEtP*<YV7XpkW_o`wct;3O)O3ZX~@-Vw`EbOs3k9Z`wSG zAIU=IzwM6KcvTW_=fQ+Lg<zK0g!ns|$ahi5t2X9=I@;$*)Nba7*#&V&-R?J;;E=W} z!`mA5T(S`U(p`-oI_a4BG#c@{VBgluYf`ugo#M{&8_+B&+E-FhD%MH2>Mq#`!Fp7% zY?u}<BPoi<no^2EYtuBtvM=eRRfPOXtvRmpMDl<zV_XCX#rDykxsoO$^r1aZp*?o{ zU*4l>+QZ-8un5RLv%K*KVonG?wGgN`PF>rR$?mm#Jl~@XGaL~Unnn_jjQigi#Q2Ow z{`z-py!#7~0I{*De2JR8RV|RO(pREQ-S8-ZEwTHJO>1hcYovzZL9*YMD%O4#qbn}H z^YK+)TRJf}tp025vSY#zh?7ky(P#l!FC&lIVYyHwj_KQxs0_SIsE>ESQMu6wv0qI^ zWHXnQ{t@qxpP4UbSS6pG>k^mYy7;XQZS_uC*^6(;4$-A6YGaeQ(d0^h<8l?BQ7Zo# z^P4iy=W$Hirf_cTecdb-FO{=|F(XI>&*T&?U$Ph+*zK<UDXZF51j;}%0e41r(!7ef zWNR2}VT?~&*Hf;dUD6neSDrV)mAZMoQO_7%>8qgdu<#Yy;nKtVL=XV+P2$f@caa3V zOxYU*;Jxrx8laLb2riTAV~J38lf4fKU>6D*wBc8X3<Ok{3$NcZWy#vjo>O<rI<6HW zxh!4R0;QQo?R@a^mkgzK@&}Att$pR09VK6<`W^QXaeuInNHhY)-!!-0OOQdAtsh2v zY>kLx27>Hzon8u&3fGYVD?H}J_Ug|WKoX@;12T<Udkfi3#qkEEFNJSrHoXntw>o(r zq%o2|#oXt?^S9YWq%@QC?fD4enMAMISC|Pdk+!Ayj8KWkX5=WW``Iovlsd-OE7RD@ z-Q`E9nds!#^h^PvYd2_Kr7_rd9mMgep*vqPi87u6J<n|Wz*PHpmafa@Bbf@H=A*5a z^!*iFlOR@&{j`s3iv8D>E$J4X%2%FDlaTI@{Y@!1Owzeaqbaa&pr^(&-m(@AQb|%G z>>elR)*cp&9}ec>t;#)Rc1_NER16vHZ@SiSTTL@U&O=oq8+m&0WkByFv_Q}hRI3vm z(C6FD5u2ZC)A&00=Z*eV>tT$<=Cx5Fgd06J2yMGI66}M7+>Cq|R{$8$&hNzP9MqY6 zEC`+fDZwwc6I^?%X=2T+al8EZn=q|PgNP!yZtQ%iH#MA5Yg+E9`0&vkF#5!e|7kR0 zdfKy*-1m{u@-k4I_ULjCKIM8T2CPS3^-Dw0oaPc5Mai=X`xX_+&Fb4?pS8ID8IiEr zfY?jLKu*W2P`N+7XhtrMH25Pxg8^yIl(G`hT&!s6;`=7&l%}_yGK`5A6uwkaM0ewS zahGP`OQu%u<x9c`l2QRDm>~oj0l=E-b;i=NbF-0C?xI0k-Y+Rna!LAde@~<#Ua6b> z_B~sQ+4v1${s#0g>dF6ZZ^VSB5vSoX37;tWdB)Vzqun0vv>v0dd3Z^ufvX=um^3nm z_n8K6Ob55~oLSbBM8;ga-5u5y%q^FKyvdU;(9utN>yPv_L@InoG$SrrK@g1Pus3tb z*)EYF&DsU~(|#Pq5H|BuX90^%rcv8hbkrid6!8=N{~KB;`HW8%Y!S4RVx6^UksIrz zkSi}KpG%XsuiJmqxi;*AnMjkuwOjuDq3ctMGtW$Zb|IigcJ@z<AA3m--Dr}R{&D!w z59TwFbso!?Q7OPZV#LXDzK`f`ZpYLaU_1-h5&TKfNO8X{&)~|_q&%KLnv6o^i59a~ z@zEbXmBfscJL6@&s#HB<8pA5w>OKIF;Otq%@~J}E)hnsM*4K_-SF`1P$tzl)7;-Tc z)8&}UbdS=<fp^b+igsZ;-IF_*QHV4k#Y!T_oJLV8UK`qYbBK8Xy67?VfB(7ya^pR< z^rG_Vh2CE;Ji#AB^Z8%??w@c#J#v<PkDO%J@ql=r!GYQTOa3d1h$n6x8*1L^9FW}H zp#DE$n0x)dL3q4lXVObAV&5{XZ1S&J_uoW8>73Rf)(AnRFOH8#Z)rC<sxI-L5#qf{ zF&0j#G+6ibnN0s}zep(+mSQ>VK!I{rnr&dc9oOTSa}w6gf=lU@9HnaoJpo3`Y*nFJ zesVxhlC{kmIH@><j+Xe5Etcji%>g(R%m=@>Gb~yAKA~CQn0CYf)!8To+7Z^Vc>JL` zi_HMq_6(6?)?5gTd)r2omofRcoJ><uh0$&sOPZrod4*J#zXQ5QUYaaPBq)Pf%L-I# z{OxAVYy#{d4=UHrd%poFAdloXCy$f<>eIUxgiTq@d;yftc6_2fd%5zL=FB{%p##tm zqoT|Cpxix8AE#h**%49?*_ngZZey%4nMDA#L}&iKXK|WlMXu0e?vq)5hQqa5Sc88S z7YhXK+X4A#Ea@%^o#=S|4p9T^x@wcC+i7*LxV8_i2n$MA95DEOVY<4Tr-KExAy>~1 z{5qN?c1k&#+aCVj)J~dsxbkG-;GeG^%ryQs&*a;9-p|CRL#3EngnN41#k&KT|4LOZ z7uMdqD579Ms;Ej})0%N>^*Ph82!W?gKVLBCQ`bsS8$IKfwdUy3d0%BY55CepMZp3J z#_N$YS6}jZy|358{O-j-@v-#f+1|e(XWz{~S}yKIQ?M`9|1B0@Rw?177L~D_+bo_5 z@uL5?SXd(B)fy|3Tq^_q<dKU1OP)k?U0nP(fu+a)hvEbxQBIj8D7y1OelO@Lo=)1E z912sM`;Wd@a$BP)^7gQvua{;rF-k^a9u}L{r(n0;pViV|t=C(#V<{J(aF(1YbM2I& zR@#x5%cxuz(K-!jjJMI908S}!-<eB?WBt&H5_$XBaq9^|#?eph8iwdVy%Bs-S#gG_ z9PcP5wS|c<H5qZL;*h7#Z*4l}^`L{11_@1gHs0;I04I?<jY$!nTR%@D1LKhmlId$~ z;+;qH%sqF^VC5ew1zsHOE&HfdW5_Nxb?Vb;OeD!ou49P2lu9ptL!DC?V#lW4_p>A* zAS1rq^of?nSjK^u+gxPkEOc|XEDs*ex*YpZkOc!mj5^8p<Q&|dxJN`jfG;s&!<=av zCPd-r3*jT{GX=O#FFX468gT8^JalB0a|!Y;A>69&h=|NJVa<n`A@KI=#Q2ODwoaZ6 zT}^>s;;y57tMTVdk`tGofgMC}3B4JtmUaEbrw+PoH|!+<%kqX~UBxuT_1a1ko-{rv zpT%XtIS5*hU|)X)0i<V3Po+z^3!n{Dj_atFrtj#C&d?otQ5l#!6-f3FiHqMC7cYgX zS?BINSkYv$OqOza50(;DB-)2Rn7PY$V@&l38l58HFLZPCo9s-|JC5-ejwl5XI;ab| z`Yt_nrt@=v_IHzm-_o-){=mG`>|k|}mYX)pn2+ac@_@evjq6rxNo`PiA0JegbUw7C zN^?6e$lqN6&qTFLI)3J`+Ph0{o~_J#&Kmcw=|XRHQzpFeR^KBT0q*S-s0kL_hHf!R zXat@Gep`8TratwqzETId^ZU-UFAu7-+t0M<R^LTdJ?Tgb?~4e;8$v$H_5rzbe~+*n zk8X8wUCb<!yk6vaju>+fjoJR2Y)`^ugh@02OHZ?2dqN0RT4m_A^pd?cGCYdf@!Z$A zIA#2>C5@DxnD-eM-G#<}^9SQ?JUOeJf@ot@u2H&YP9x@_`zG8XJm;9O(A(l%6;ths zzuFhIkt)mF?v+#R+Q{O|J_O1LWcV6Vrp50?w*1eZpYacECQE@wHprwo8&jga{*91{ z*a8O|@GSe?adf_;my0pa(uDQdJ@-TD?mv{@8#W>)6xY<F8)s2*0Bup-Q>ovZ*&BcU zn6|fSFyfSSl}!h)5P5U%@)p?7rF>cvk;vabf(NF|yncAkea;q;Ab~)MuNJ?EJVe>W zK~&Z&&p$!BFHOSRy|%8mwr0sr>|YN8l%C9Xz-=UOvex_#&+SpdpCM+-+lYtsr16O# z_XnE-nsV5f7CY-HH#3B9Ui#)!W>wh(6xlQE!z=75@9@j!@L;V&_Y8KEG@Wj$S+O~g z(Sl=Kakcn#IU*N3ske=~cQiQMHS?>56-E?V6rW_#UCzlfe^4fo@_68^Z5c+1^>f}> zNDfktlA_VT|9nGWm-S0K*fILxc$anPt}*R}Dxx$XzrqI0=`sCi@OLA1EYe&OXRbb) zJvM^LkD!j|RIcC^IR9EZ9GJ5wWfhjY4W^!h5uCSn$QU^kYblKD;ekkSrSCTH7YV3* z%u%1#r!HkDZJuG!asT+EN?C6pcBeJC@604p$iz*(JYOf#Pp8VMpG~efH)}XYwO~e4 zy5sZvU|xvvv{|$JBGvl51fj4|p3y)k)y~^D(9*cKnhQD8XMBlH^=kC{T0$^|50F~~ zOe7n?=&{fw|4B5eAK}FMSz`#2<j;vwxw)=Hf0ua=j*??Shacv0BTvv$<d}}iV1L~{ z^gbbn9s`*ibAu@yNH$9~-Wbn1(Br3Uq{2J~uR77uhP(xqQ1_<y)E;N^UF;cg(Sq?n zEkSul+J@P9<t@z3uZX@QMBVxmD$)t#U9~0Bb5$VEyT;S@L$4BXTaG=On%R5n5j-)& z=D4UFb*@;|z4pZK;Yoivf+<TrhTtS0?giUOqoH;@5cZP^z%0$(0tfJ4gd%Ie+ba!Z zvmVfV-E!ls__EEFt7dT52gkQ;tz%Kblgu;vwfIOv^s}>8E7_ROviB8qH+Oe#4NSCf zmTHVlIEEF_sqkFFc4ML?8hfvK_vl@YNH&`W^PD(oi<<RPmlf%F{)GVi<5(<fe{;N- zhV83+{3chU|HH9({?|PpVB0vRZ1~~%pZSR`f$E%u^YMd0XUwR_X46JCRGnVQkovLC zL;X^A2rZ-%>XY{lFTh9>7i}L>eoPrkQbQ+!05kY9!Y4Kh`V`sq?!4;(#>UUCEw@rR zNqxn)u-V-snMqK02rG7oIT+HM?Y8WIItD^xW1z&kTvT)gk>!G~59Z?aSHa2fUs^sX z@AblSX>}zJau`oN#GkVFP7c0dlCzRglXPW$0cChve@_nIN?gbr%Dd)QpN*Uj-9eT@ z!*4^%W1#P-RBRyWbB&pz=P$Z$J|o*uhgXM1d>FA8(wHV-E&Y{`ZdG3D9F#zF&?bde z@p{Zp2)(o3L1T(RU6G(@MbGWm+LGUp@_qdng7=Ckw}_+%%lL|X9;{30zo%VjZWCy5 zo&(mUEF7;C?J}m>Tu2v(z^vRrOQ16a?Z)&q->LAlBAIJdDk4AteUu!cLeeBIey)$c zfv**Z>zJsJ=PT~r1Q{HU#QWp?&XdCz*xPqs;2F(y=BHe4-EQxqm$XjTT*^!-pH_&) zLgnre#u)bca9KDL@xTh^)KenGX8DHFUNdcPcRf<t>9TUfL~T4N>*2_y*PIePY^gT7 zPAvqD_gs2R4yihq7*s*dV$}C#?lA39(s+)6M{@FB#)(Hy?kl?%OPiT8iwA1RpEajO z`tQ%p!rdS&Ur-4mhkjxGKyRtrFsq~ZPPX^|7m9`Jm-;ihr1~9W((HbzbIGkFU!5z7 zj3f{0aOM~}okTf*&W%#Q8)uu(qJ;r<>MC=(#1?E}L1XWom5eJbHxk^Sj2E~1THZ*! zr)M^jB8!g`%mLD9Qb<ssj2cJ^mYQREExqcVm&)}OP{rH%bDa6CLgiaB%A+?Y>N>|+ zH>@?Iu=tL*d#kR437K(b)<j8&{8dLOOVoJ&Y4Q$bLpaGKELua}xjgU`G!s{~Y*k1M z9>fchlE2J5?idrbOm8rl#1#GcN(J1BitEVdbj&$pa8wBg$oHmBrZ2Dg0)e&FW20s> zhSeGPslsx;E0Ob2%R1=itBktM^0>;~zF(*k@=bjGGazz0QZmz-)!|#(M-d~Bp&BeK zey=88b9|ZqYi?je;WtGW0S{kLo~!TWCJxRwR&TquGPpK{%CT+61T3qqZMBFQsk2b8 z-8$*nRe@G*wVS))sDQ;=^;%_6;LN2)KkOm*SQnx7j^G0*MEXAu_0ReZz<D6E+$ib5 z#vm4lcj&o#OKeKMXJoNy-0<tKWH)cCMRz8Lo|k<h8VlDO9y>)tkKLb%iGUMCe+saJ z)n<EW6WCn&!?vj`5L*Nr>1i=06bl%un+A@Yayn;z(fFwggM8PF-(}O(HzGmjGXqZJ z()Z4gh@sVA@z(Wvu+;9#%uU_HnBJ9515D~v$891pdQOk^Cg2Q2f|s;D{m*$*6<9KU zOqDpVjq*jfT#J6Dbu{tE{)GcOU)OL~)UAq!(YOR0XFmizeW}o1xJH)rHF(98#bB=M zfZ%lP!83{O+<h7RTf1NGw{?DgweIOoy40SR)J%I~4CFo)p#l<I!DvUK$!85FhE}zH zJY+Zd5i~xo{JQ2fC)e~P$B4Q_M-w!yBAThHiN_-?SJzge&+DsbvZA7E@yi<`<pEQh zG2d-70R_1c2SPO6SjmhNwZ;BVz-sPh9XHs+axC591~$w&4T7egH2Tnw^~`IfC$Xk- zF%l>esZmOfHt+L3+;Jr6uYH=$5YUQrt?_uVGwCI?6R^Ex?&4@Psoz*CCplZ-7}4}* zX9A|P+*ygfoKH9qxndOa`KnYqKZ4B&!vGyuB9^kLVz}0}l}1OQp+gDD`FWYi|J5*{ z^kjbq^OcEtdagiF;C19@YiUPSvBl4Euhd2%)EiLUME~F*xXq32-zs%`m+DVERN3G4 zDJG=#!^(x@GVPrlpCwuh!_hVF-$kqkaiZj>0?l%Kv?<zq@U4Q0o5Ll7Gv+tx+wv*( zx=sZ@TClaVsDY<?Do;t(Nj#r`hsEE=rbegof%uO1?=9J1?@U$Gd*dKGNGWNQ&wZS- z?h@h^lL%`q33vFLEibk6=a)I01BWsY#TLN9);g{0aax$a&;utw^vS7!zW>C`F`>x% z_a68_4Rl^cX7wSAsl+3~kTGE9Tx*Wxn45w!9XG_JlV2>jx}i_+r9|(2Vo!2KoW(iC zoe+hMUm<zZ#G@M2@h7!Okvb!lZ4=vzcx^=6PHCH6Y1i*);W*9YMZUOE{Bq>$%0&Dm zqW5*I#M*x{;G$<(CfR4h{hCBcXG|qXXBcDK=0q37q?Q&OAHh3oZ~NFv(9Dg+G`$O| z1*L8}>7R>Gv*4hE%!bJCZ*p}Nt&-+&O4Jje4Mvaa=zYkYtHIX$F&>Y54yO!6!6v5G zSWtzCCzMg$c6G8t@W&(T&AOh4E^z>lesdc)wq;)Y<Z*fRTqvDCH=Q^)6TJ(K7L5;& z&5aGvB=6|v>Qm8Cr5VN#DtQYJ2L)kqfrJwLn;p^pta0YAoY-|x6Bj5XM<5B8N? z&lvfOZk}zLDwf5g&`O4TSfX;Oq-31!n2tvth9=JsayO@C((T8Uz5sKP4i_T1Xnw3K zaPBBVUaxJ><Mj$L-2R66LWRT_zW93jj<#iJS8Oo5`X{1Xji3fiN`8951M(D$KFKYl zZac{@7(CoC+^E~4y|lajx@`9fpvF|ZQ(M}jGHXWY{&)ad=B_sZEbRhl)IV@7LO1IB zU*dUW(ut3j?p4;_<HrCO&2DWqsd)vLo=Np=q8mAOl8<`yy`FZ@3SP9h&~59OV1Llh z?_eqjiU`>ze;==cM$+OjRPp|*?U2`z>Ropu!T*g3Z^j%Y6L?qy3VaY#?Jxyo%n{wP zV2iaItR?4ZA<!;dsMqyx$I%)YcM2PT9Ai3Kq^Ws_!(}amjgy6u0|y+J$p6I6)L};~ z8zn40dCCq)-bxEjKuzI{^R<TEw$`S|O`h<;^dM%RJnrLs^5f+<hQdk?Ubtxzx8r|V zreja&fQ~F%LxZoeKVyWV1~M_5*-+Q*I{`Ey=E0+C!kofc6Hdp4fG~0i_qio&ow#$j zTRa6*07aR}KJ&yeyerpSM*<u^m&>dv5xLPm(rf=|U0JzpX1zTn5_0<*K233bC+-GR zxAGOt6L+39$ZW9Iea1-ZlVZx^maJz^x_D3y`;fy*STU5fQ($<km78?GHtu_R`V8?; zk`*K*Tlz8u4M7*=JCPRDSBF1SmAe{fdhmdan5ziS+}~_~VVyEoFC@2{Tr6<uK~sgi z+p9=(QgV5m*11=L>t2^1pN-E{zRq=)bjFS-&ikg%SEgK096&2}gDJ{Ul&_u_0^{W5 z{<6L@r~b0O-1{>Yyfu$er*%t(c@3=oBn?wBzz%N!fS%aHGs*jlE(LG7;%)iz(tR$m z-}(9e$ow;pgS#&ml<^}M?q#HpNV_FnOz{p?>KvDD@E$Qq`n<RA$AXvDYh%wxRM&|J zox_%3#o7baLe>>wU}fUucSi9eWPNrWVMn-=u&wShzb;X%bHSvQ49v6?A!zZNo}=K? zk%*IrzuyfL)Fk?BehGbieF9flZc``|g(mU8Kmgx%=$hp0oLc&&Y}i$z^3#s6S!^Z{ z&(5LfXIzlCWjhssOG;cWyualXo;)w5mz$1D99hY|we-ueGEMy$ZgK+GKGynI&howv z$A6-@9$hqr`L<#Exc|zKoF&WG2unF3l&WB1fds8?(8J;X&^)O!f2Q;YOlE}L7{7gb zxzV&C6lr<alyR{<Ty0N1ri(axO8@!NoXXO-R#q}vj*ea_e3nRdmRn$DK@kDM!$(s+ zwH8IZXPC=&TGTbpmx7(r+=|?fl35Ay@65!#rJm=`9}6tPl!x?{s3@KH@{m0E?HdJX z%m~yhRvLV|6R=ZRx}PStlm2zFMQ1h};%_+TGr>Vp%ZM{oU)ap|q3wcGS=L;>V)tQ( zqndAyN{*OqMpZyq2qGXPZ<QGoQrNR-6aAu=UivyJuj8!sQso|V#AoS8QOTX-!RMCU z#jmvdMZ<&nmq5I>2Qa;J&ln`87PLq$y(mELqJqU@iay=xIGpLtyL9k`-1y$~RY{L4 zu=t}_oXQzy1Nu&x7`{!o7;Z~8iSyiT$n?nhh*2oD4?wQ3etMo0@lf@;tR+XKL)>W_ zia4B)jG)dbb*0xBqhjJkw}(w1IiLA1>zepw-Z)$~r=pkcGwi37UHOZfKo_DBMQ2Ay zY6MVwZXyzBUc=9NYs)l7hk{hJ-Qo%11M5BPd=&LF;)1uQkq`fXF^gYw3=g|yk1|~N zuwcoU@D)AS^c1H7r11k&Tldj6({pm!t^Aa|T=h4f<-Va>JAy1NX_(G?Y>ab1_;0eG zkYDOiV){?2EoZ0ypfRzzYrAYLShI#Ab{jnKVt2v4KHDesPkx)!|3_xR6OD9-|1dW3 zPn>BlBmS8_7XFb<-f8?<IQ~YM5~h-;;gQ@F=>)c_^F<poj*@QLo>+TFU~*GzD1$+y zNPYVKUc5-&uEhAxfwjTJ_?MG?r3{lrPePAORZI5=vDa-75Cjon<pIe#ti6=j>-t5I zt8)CNK$LOI#z-^w*b|%?$6d4<#b0qRwjg-sJwTXI#ZdYVQmFryQ1@B$7CGggkQUw5 zNI=igS!t)aEljDp(bZ|GXdV^x!JqPCvur^%x-u!E(nYOb2HU?wLD*kD_k~_gEn&#= zOfItpbGatG|Ae(9o-uDeV5QX2RKVJr`zj+fUdu*ibmP%?b?>^UM~32>Ig;MT`W2bn z<T4tYum<1Lw{V?)_UqSc&0a+ZP8P=$M^4+DU&+hG%{d+mNcQ(K4Gu5@m3sLv=BT@< zV?NUvx4wIDY+$XR;RdqGg>`*kKA<B2b~w+pKX8j*be8yxRBMM4o2wae^;3hkH=RV@ zi*T~weE8wqOa65N5-=PfEffXZv$)XJIDUh)KI_!3bypLQG50z8SZAGN22QW~rF!ic zW*U>}@L|a^*?Fg~OVTA6SD3~e@Sq3n<E#hb)jmN(;JT`FrOxqihF8xi*AoX(dv<60 z8=m?QtNq1D#L;ji?UwuXLWtDNr1NJnq{{xrovDGe8O8GW_bl~Nc796<Qb)xblViMH zXl5bf2CLhpXU=gNV_2^T`~U7Tb=Ab?=bIfjJTo9y9)BNQ10)oi*K(^lX16xf=HkWV zJgZ27)r_ead-VAFd+-$3bO((|<6+Qy%)X*{n8)uMclPjHEyJt!%rwXjg15-*?%L6` zoryNwi~8gBSk^_o<l=H#+`IF(U2QL?tlZ87d}LBY`Uato3~WYq<~-fpa9Wn)+wVv* zO9a=%haN}@&tpXCJQnVYAEsVG62qHZZ5Xlz0zW<^X_A03JR8Tz_FmR_H<4)QU)bF? zN#*Ievj?Nu;=yK4Vu-O|4xcku%+Gn~zwluVYziwjobXuVj~{NjLi}B_O|emiN03MO zyZlLxmeR&Gjxaq!=T{>H>9)V(P!Cb}P)g!Q>?60too@@>sy@>+s0m`1uDq54Zsgs@ zsRKeb+q-;{k@RH-Mlr-Id6D)@BVH12R=xeON*<fe;~=9AQ&8VA)vLBym9`&gUJ4YI z4J}TO;qhO`O{TpTPwY2O>_>)Dz;$n-O`g&?<rg3rs&#DE;=12v+&4E0esTM<BQ{%u zbrENN?rxD$e&-qdE(LkkMac6td^OfzS7y7Ecll+58za~PTo1mEhm6(yx{$Ibw9FG= zX&$F{xG;RXlZDsOi<lPU-Uxou-~Qx-RE>2?P5t9;woJCPO|rFsL{@hz3DRu9TKvin z=4y}`_O`u&MEzM`+hEHPl;~<_nS;ekpNw~O0OyyO=B%n)>Z5}lC?&sCDhQ{_G9py5 zmlo2Lz9cP#4ZZd@*-JPpWj5QMvjw%^_7ev?DUuLZXB}yezzNpfT%B7C^3wYrpM7kp znt5xXX7%{gxcS|#PMA^mm~8Wk#+(r*?AUi!)ICB&{>n-nnqm+Z>+P5(p5Aetv@>ak zwp@z^p@CZAF5~5?iyHQwCM|3RKV*}D)YG1O=6ECO;JONYTfZ!xsJ5gQyZrA#$^+)j zx!Wrf&7R+z!T-t=+TrB~c~UuiJZ!{*pXpO7<?n}c6#M3=6jr&N`?priw~fzzU<aS1 z*PS}X=&`_*zdPLkuUa(_|CN)V`nLaY0R9EbJ~KD6q3>D)O&H$=Y5j0R?8*V4Co^Z3 z3SZs{EPImb)L6wrs)0O}NAUH?Z6I@Rs85c0|E|Qtw|^&3Jr*eHS&I(>np|Ef3AJ|d zhcds+pTwe8L_TS!zXxC?T_Hm<={Qul$5LKTqO_TZ9ajY{jo70?WxbjO<R<dcC(mT% z&SjKY&_jIQ1U{+bL-<F;@^<SB={xTVKMo0|or-s>2jik12ZUVkHQ`ove&wf+1#5Nk z#S&zf;e(x4PnV4uDH&e|Cba~w{8omUj$5Ws<XJi1qYLa1=Q`}a-w{OA94+c57s+)L zUymw}LOmbFq+ONM1HL;yJneaQ9QgkBPD!ur;tRBRH*EQOu6_C-%faR5+SYn2v~7mi zcs~!XGQ=#!qjfoH7EGV55cmrx?j6=1Kl-p@Xrq6Ffa&RmF!4%O589}Mk!3RCYYefb zkfhb)H(n@u<Bj;11{a7vS7oe-zkAy^v;(`ePn2A)wk3LaZ<9^Oy?f&j!HKwhd^rEr z`0_)}OBV7k<!tLl1Ol0l2gqX-aQ*t8obz`b&}VlOR#nw8{|qO({VCwlF+n<6l&3wR z1jg_C`$;z^(62G^7h;i!Mb*7^rNu1IZz0;kq$<SJ+AEFDZ=M#3?aXuNDz2CqAQ?=n zd4!*$tP?d3k-FRFw+60<0hJN8%;{4aXMKk*Nmcs~lw<i4F)KSO{$fZme08pn^v6WI zN>XLr!2RY%tK;_!>bnm1Ro?}D@_aC$BjD;~^E3_wQoFHyJp!F?b+Shg2AEv<Pdxk| D_q^H? diff --git a/misc/matlab/carmen/convertFile.m b/misc/matlab/carmen/convertFile.m deleted file mode 100644 index bda5d66..0000000 --- a/misc/matlab/carmen/convertFile.m +++ /dev/null @@ -1,12 +0,0 @@ -function lds = convertFile(file) -Output = readFileInCells(file); - -k=1; - -for i=1:size(Output) - line = Output(i,:); - if 1==strcmp(line(1), 'FLASER') - lds{k} = convertLine(line); - k = k + 1; - end -end diff --git a/misc/matlab/carmen/convertLine.m b/misc/matlab/carmen/convertLine.m deleted file mode 100644 index 5265c14..0000000 --- a/misc/matlab/carmen/convertLine.m +++ /dev/null @@ -1,25 +0,0 @@ -function laserData = convertLine(lineCells) - if 0==strcmp(lineCells(1),'FLASER') - error('Not a FLASER line'); - end - - laserData.nrays = str2double( lineCells(2) ); - laserData.readings = str2double( lineCells(3:3+laserData.nrays-1) ); - laserData.odometry = str2double( lineCells(laserData.nrays+2+1: laserData.nrays+2+3)); - laserData.estimate = str2double( lineCells(laserData.nrays+2+4: laserData.nrays+2+6)); - laserData.timestamp1 = lineCells(laserData.nrays+2+7); - laserData.hostname = lineCells(laserData.nrays+2+8); - laserData.timestamp2 = lineCells(laserData.nrays+2+9); - - % Theta array - for i=1:laserData.nrays - % Maybe this is not so precise - laserData.theta(i) = (i - laserData.nrays/2) * pi / laserData.nrays; - end - - % Cartesian points corrisponding to readings - for i=1:laserData.nrays - theta = laserData.theta(i); - rho = laserData.readings(i); - laserData.points(:,i) = [cos(theta); sin(theta)] * rho; - end \ No newline at end of file diff --git a/misc/matlab/carmen/readFileInCells.m b/misc/matlab/carmen/readFileInCells.m deleted file mode 100644 index d84b5ce..0000000 --- a/misc/matlab/carmen/readFileInCells.m +++ /dev/null @@ -1,44 +0,0 @@ -% I got this code from Matlab file exchange -% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=7933&objectType=file -% Author: John McArthur (University of Southern California) -% his email: johnnyfisma@hotmail.com -% http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&objectId=1094612 - -function Output = readFileInCells(file) - -%Location of Data File -root=file; - -%Open File and count the number of rows in the file -fid=fopen(root); -nRows=0; -while 1 - iString=fgetl(fid); - if ~ischar(iString) - break - end - nRows=nRows+1; -end - -%Return to beginning of file -fseek(fid,0,'bof'); - -%For each row, assign each space delimitted object to a cell in the "Output" matrix -for iRow=1:nRows - iCol=1; - %Temporary storage of the first object - % Note: the space delimitter used here can be replaced by any delimitter - [TempOutput,Rem]=strtok(fgetl(fid),' '); - %If there is now data on this row, then assign the first object to be an underscore - if (length(TempOutput) == 0) - TempOutput='_'; - end - %Build the "Output" matrix this will be the first column of the iRow-th row - Output(iRow,iCol)=cellstr(TempOutput); - %Repeat this only using Rem as the total string and incrementing the iCol counter - while length(Rem) > 0 - iCol=iCol+1; - [TempOutput,Rem]=strtok(Rem,' '); - Output(iRow,iCol)=cellstr(TempOutput); - end -end diff --git a/misc/matlab/carmen/reading.m b/misc/matlab/carmen/reading.m deleted file mode 100644 index d84b5ce..0000000 --- a/misc/matlab/carmen/reading.m +++ /dev/null @@ -1,44 +0,0 @@ -% I got this code from Matlab file exchange -% http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=7933&objectType=file -% Author: John McArthur (University of Southern California) -% his email: johnnyfisma@hotmail.com -% http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&objectId=1094612 - -function Output = readFileInCells(file) - -%Location of Data File -root=file; - -%Open File and count the number of rows in the file -fid=fopen(root); -nRows=0; -while 1 - iString=fgetl(fid); - if ~ischar(iString) - break - end - nRows=nRows+1; -end - -%Return to beginning of file -fseek(fid,0,'bof'); - -%For each row, assign each space delimitted object to a cell in the "Output" matrix -for iRow=1:nRows - iCol=1; - %Temporary storage of the first object - % Note: the space delimitter used here can be replaced by any delimitter - [TempOutput,Rem]=strtok(fgetl(fid),' '); - %If there is now data on this row, then assign the first object to be an underscore - if (length(TempOutput) == 0) - TempOutput='_'; - end - %Build the "Output" matrix this will be the first column of the iRow-th row - Output(iRow,iCol)=cellstr(TempOutput); - %Repeat this only using Rem as the total string and incrementing the iCol counter - while length(Rem) > 0 - iCol=iCol+1; - [TempOutput,Rem]=strtok(Rem,' '); - Output(iRow,iCol)=cellstr(TempOutput); - end -end diff --git a/misc/matlab/ci.m b/misc/matlab/ci.m deleted file mode 100644 index cf454c6..0000000 --- a/misc/matlab/ci.m +++ /dev/null @@ -1,11 +0,0 @@ -function M = ci(matrices) - - s = zeros(size(matrices{1})); - - n = size(matrices,2); - for i=1:n - s = s + inv(matrices{i}); - end - - s = s / n; - M = inv(s); \ No newline at end of file diff --git a/misc/matlab/cramer_rao/compute_bounds.m b/misc/matlab/cramer_rao/compute_bounds.m deleted file mode 100644 index 5d585dc..0000000 --- a/misc/matlab/cramer_rao/compute_bounds.m +++ /dev/null @@ -1,40 +0,0 @@ -function bounds = compute_bounds(ld) -% bounds = compute_bounds(ld) -% ld: laserdata -% return bounds.I0 -% bounds.C0 if I0 is invertible - - -I0 = zeros(3,3); - -for i=1:ld.nrays - r = ld.readings(i); - alpha_i = ld.true_alpha_abs(i); - - if isnan(alpha_i) | isnan(r) - continue; - end - - phi_i = ld.theta(i); - theta = ld.odometry(3); - beta_i = alpha_i - (theta+phi_i); - - % dr_dt = v(beta_i)' / cos(beta_i); - dr_dt = (v(theta+phi_i) + v(theta+phi_i+pi/2) * tan(beta_i))'; - dr_dt = v(alpha_i)' / cos(beta_i); - dr_dtheta = r * tan(beta_i); - - - I0(1:2,1:2) = I0(1:2,1:2) + (dr_dt' * dr_dt); - I0(1:2,3) = I0(1:2,3) + (dr_dt' * dr_dtheta); - I0(3,1:2) = I0(3,1:2) + (dr_dt * dr_dtheta); - I0(3,3) = I0(3,3) + dr_dtheta * dr_dtheta; -end - - -bounds.I0 = I0; -bounds.C0 = inv(bounds.I0); - - -function res = v(a) - res = [cos(a); sin(a)]; diff --git a/misc/matlab/cramer_rao/plot_bounds.m b/misc/matlab/cramer_rao/plot_bounds.m deleted file mode 100644 index 7eb9a3f..0000000 --- a/misc/matlab/cramer_rao/plot_bounds.m +++ /dev/null @@ -1,80 +0,0 @@ -function f = plot_bound(res) - -prefix = 'tbs' - - -s = size(res.etmin,2); - -if false -res.eth(1,1) = 0; -res.eth(size(res.etmin,1)-3,size(res.etmin,2)-3) = 0; -res.eth(1,size(res.etmin,2)-10) = 0; -end - -f= figure -subplot(1,5,1) -etmax = good_direction(res.etmax); -writeToFile(etmax,strcat(prefix, '_max.png')); -imagesc(etmax) -AXIS('image'); -AXIS('off'); -title('\sigma_1 = max \sigma Cov(t)') - - -subplot(1,5,2) -etmin=good_direction(res.etmin); -writeToFile(etmax,strcat(prefix, '_min.png')); -imagesc(etmin) -AXIS('image'); -AXIS('off'); -title('\sigma_2 = min \sigma Cov(t)') - -subplot(1,5,3) -mea = good_direction(sqrt(res.etmin.*res.etmax)); -imagesc(mea) -writeToFile(mea,strcat(prefix, '_mean.png')); -AXIS('image'); -AXIS('off'); -title('sqrt(\sigma_1 \sigma_2)') - -subplot(1,5,4) -eth = good_direction(sqrt(res.eth)); -imagesc(eth) -writeToFile(eth,strcat(prefix, '_th.png')); -AXIS('image'); -AXIS('off'); -title('var(\phi)'); - - -tot = good_direction((res.eth.*res.etmin.*res.etmax).^(1/6)); -subplot(1,5,5) -imagesc(tot) -AXIS('image'); -AXIS('off'); -title('det'); - -print(gcf,'-dpng', 'bounds.png') -%colormap('prism') - -f = figure -imagesc(tot) -writeToFile(tot,strcat(prefix, '_tot.png')); -AXIS('image'); -AXIS('off'); -title('det'); - -%colormap('pink') - -function writeToFile(image, file) - -%map = colormap -%ind2rgb(mat2gray(etmax)*255,map) -%imwrite(, - -function res = good_direction(x) - for i=1:size(x,1) - for j=1:size(x,2) - res(i,j) = real(x(j,size(x,2)-i+1)); - % res(i,j) = x(i,j); - end - end diff --git a/misc/matlab/cramer_rao/square.pdf b/misc/matlab/cramer_rao/square.pdf deleted file mode 100644 index 1679b71aad811e95f890d546e2161a447be4aab8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7149 zcmd5>XH-+$5=NwkCMZRugeD3?5=aOg0V#sgQIr}WKm-yXp@d$fD4{7;MZ};qL69aL zL;;nebU_h8>AiPeV!QV~-~Ip2IxE?0&XmmTJ>Sfkh!~vHlz>P|0YqA6;~oN_Krj$v zdkvtd2)ckoJK~&xFcQTGq=|CDAw7T~O&0_Xc@AlZu}3N^1F$#`B*GQobFV$^BIX4A zNW{X9xDO6+{Tn<b(qcR0{wKiXs}x|tU8+lz3aWz{p9NBQm~%fRY0!o6%09G?i-_A? z>*xyAJvmyxyFD+fq*t-HHzAywY*Zu!ZDWjye0{#R+_<4>HE<hxe*J`hP%0zKBCI6n zOLp9C&sgWp^CuiDnJxfkk`M0h-`{WLRXsvw#$fsCaj}uA(NrRO@U;EZth<h!pxd<` z^po)YvFyzy@0P$VMkRuOs+RWMk_khE3NP>*Pk57(e`)_zMVmO^8Jx?#Q7alR*<pXY z=O$fd$QG1Mx!HVPqV$7vlTyu9ugw|F<mV!f#!F%aghOi)EfojFB89jDcJCu}wdyZZ zWN2|?$<{>~DnZrNTfQ4&G`qew6$)6pC%4?uvF@qt@KcHnjB7`uR5c!`!i*2fxq6YG z+i~IZ4y-VJBhy#rl0!Ln^2Lmr%Z?Gt`_yHxutan!hdQ-?d&ZZQg9TE&de3tCIv`O* zN=JjMAwg}CMw6ARfDxlvMMve3KzD&v(<X7u%8>h_(;3F}OsEDB8hy^`CRoi*#JhbU zRVPgRLOU{i%csaBT+)g0mY!4Lom9sau2-fX`)O#*GM?~IvAuhQ4t}N<0?wgGNR1A8 zV9sYf)ElPIp};$lP01ck(ffe$oSh_XsCxfq;30wda6YxeiR^&us?<?0Etu_jD!i~v zwGYNjp9P&f?sCsy^^JesSI(kuJNz8dDx8;R6=*mP^jyzIJuV2Bx>zl}nCN(XLIm57 zkaFi*&ad8leNOCKW%xI3%iX1^nNJs;YXLWf{cLLs+7$#=@pm_3+AC@s3?F+{%jOFA ze9*D2U_Lcwb(y*C(jXJ=(Rzt7@unKFRcv;cleoRRQ(5?)cq{X*Y0@>YMt)_Ulnq3O zTXN*VRS->Lv9gz1yn%rB6(Q{$0&wccL?BVvz$#P&uAOrv>j|r{iDtab3hi;3X-f94 z(|QTNIjN6tywh|K7BAcmbW`@!B=GmkYN7-#a6d{|KKsItFf7J$Bv(F2Rj@Bkn=4#f zh+0kcD(HwC=cR>C?VeqCEjtrcZZXy)sIqfsv!?f{Zw#miB8~~h9HWmay((NYP{IkI zE^swlO>*3@5T0#Lq!ge@q7*1wF|LJl!RFFMcL!M|n0vf^UiNbU&hg*hh+2?@I{3VF zY+=ce^lR4NQ`~{n6D-o*xSWST#ess(#|rrMv1<#_h5`F~7X6c~S(2Ac^K_5Jd{sj> zh?K&L_dgeTD;<99@>e9<bI*M$@)klWGrPSs%+=NqDv5kUaf`JO6xy2Lf>RC_XA`43 z?My|V#40RNIZ*0t;okeaj3IYausOz=hd2`N-LziVO*{0=`&?eLWqg#o5SykzS5z%$ zmZx8frCE%Ekl|P}Z;T-|s&$wZ)jQ0Z%k8a7lKmd6^;qrv^?jqxVW)+ndSTC=0>9uA z_gCX~HpN>#9i97L$=GgXEXzCZ=VrBA%o`LOe0GGmB7xomaN6f#<+Xl_BUI+l>Xm?* zjwKJ1djX@88SxgAZESqg;|^C=#|(&0kG$^W2U%CCO)oD@RB6VYY*0V8b-OL$)K~jX z?$_aOT3_=)j}4jkFI+nGI7{1<?7Vt7$@!!Z=W0)SOu;dWza0)j_)V|jBKw)K%n!g! zwfJY6@dn3Lm%%R(GxB_wEnwyg_L$etn_oW)SS`dastw;T%f^^V37VEjXuot}y<sur zn3XBMMJPqTe$J5p!9n<1`E%myS9_sQuhZ7?mn4oS<bB`}wk?l3S2!=-^{&ic^=jGI z6yNn>y@SIv&c<(%X#1a_OIneEnhek6Z-}%k9PpDS{TsvqAQQYB5(qLtI3fX{i%5GE zLJi{sGzXJ7WFS&NxSW(Ffb`S@iN*n?$Vd+W86mM4PY*jJ7O1F5lJvmX86$B(a}cRe z072(nNt)DwAQPkyjwETOZ+i`Cha*)BBM1}#Ay*G0(ozaQ(*0uz20+NhNK_es40%B+ z8z4;#$(*7h$(9^Yj!Y!2WP!5ZSET1;7IhK}=|^FK-*u8nKb<4<|Ey4C-@fYt=^<Q^ zBxN9DPg@+BNPYqVsUfgPvMG=@(!~pjL)jtzQbRWOFKT4}O^q?$)fVIOmkzRzKXi}+ z@;lC0AV?Qwj|G|o$opUfumqBv@gzA6`I{GzKSb3LID`wv@yA|ae{RNKwjku-{W7Lb zD!Vuo27QiHjDe@l$xDI3GGJ*bn3OaaCIvZ7+EEXTy{8?iV4u>`GX-inVX!!?od?Pd z2ZTw&z^DKAL;kMzhYvsZ6!<-;K+?Vef5qeH_5**l2Jr9xk-T%kco@4O>_`Xg9MTJA zhcwbs16@Yhlez~egcN*~qZ5w2QbXae21pNejH??4O+In5Kl_Tmw-qE6<nDrWCS9?l zb7kN`I<$5;j0X?`BU|!xMU&11<cCo#P?{7W(*3&;DM(@PoB=aNh)_Yok{f{*bYTW` zoN5Bce%vqQsXSRH<=v-u%k4!z6?W=PM?TR9`O#ZP2}&^S_->*Z_7Kx6p4&Ih-UJ^# zQ-d-H?xpYxyK_c&7m4Z#=%y<XFfxw_;4t83A5&?rDMk@08I3p2o5(wl(A~6cF+8dd zi~dFodx1y}?4xWNtZBE7IFsRQlYXQ3u{z?*mHk5AXWorUie-I8JeEbD?<wA`@on`e zJReKczDBh=)t5g_D6vSAq^;qm&z>~hzJk8FWVdL(nXqS&BDU;1B9T3Gx&n2Bf92b) zi0P|KM?VMqrAg)`f09nXbbn)`U^`>;?9AM0{kQiIA#IfH!&x^gJ1=jAvGKZ{q0E=i z)f8vKKg$^{;qm2rD(J`9P3L-)-#R6lc?Z*=#HYHr1-6uAk_9;zbxL1OA6dz^$mytH z@e+Lhwsc(~dP%Pi@S2J<i)O>2lvTs^bj5qjEnGti0Mk=z`o%%GG!ws^w);5JKB|r? z!n#IEq!+(aQg<o-74GQK*-w{{^+B)4k{rLJNrLK6^fLSSVHb&?MYjZeqGx&%((D2g zZ`y~tV^^%HMC@7~IE<HtPXWyvV>Ed$NR0V*t_tuyHyk{(=1@M;a&<_xz?Eua8#9`w zoxHJ=$)S<eQAn&xIhm&{%(jC_M;ifrhttY8cg+U+nN#~dLh-Sz63WG$MWQ)elQ;X9 zz>y4x<xPu4*6B@X<LRENthBA&9~?7#s!7<QZ<s_ME*wjHi`7~!P|--Zx%rG6GEOH> z*b7DZ>xpknr6ql~mX4Wt%el<^!m1d=AxltBQ;rO*x%)Nwh`*3eqv(18HA{3SyQg&% zP8`vY_HkYWB%%z-z}&Ikj2t8w2<-_nys_j(iLF6eEF83oOCeKC6p?=7?J?C<dvv$; zw`rGfrLkm;`zO4UQ;eMTa4_r_0Di~QUr6x3Q<lW?Z#fGgBM%90|DTdJJmrw*7%6Gl zNlBZk+GK+S)6pW1(2(vgz$cM5r$goFI#fq)pV7VKQjwA}G4a@3C8+*uR(fF9D6q<{ zfoXDJ`G!{T^RTy1ZR_3<eB_T?)(sHE>#Hd?{ZZ|re3zpFV@Dn@;I4epOF^q4{hOP^ zQXmcRNWp;p!_AeIho8Reh=04PP;2!?bNG_)+q31IHMilGfm7|1_SE^oD3c=ih$4O9 z2b=V|E(Qm^=}UJ|E<u<_Vdu@YK8psu#ymOfnfSQvy<a<&e?8CHHrt(lWDoDss7pKk znw_$YB7Q^5SACs*-z00aNqV=$%GeDWvXd7WmU6-(yK`0i>G=5AFlV)%ykZoDvC+y$ zKB3|LPV$bcul@qv_(1O19owPT?v!ELGwzhmBNJcUy<PF_U-!fVq^f62Ph!hd#&idz z=P08iKe$La^Ei(TI7Nxd_?AFpk5%ii*g5XHXzGTuni24!A=0T*K^N;`Sf0~f;jXuy zylO%Fp+?KU)ud@ZMUA}Lkq7{nHS<*s5SPkFfDdn8#xTf;Of=xByLGn(Evsse3^!Tj z%6K_yPR_e7@jMTOZ6&Fo48eHNRAg?d;;^$$uLOG=Qve+^n~%Q*##*dBWJS)htAgXM z{`R6z>E=l<%$uhxEyD@-#gg8vp!9+yU@d$WiCVf)@plcG&J|k2k_%Ie%p>NQHj76I zSLf%VShRLlnTcM0T~38i?sD%|XN3P8Onb^U=UJ%V^|Zx<wM$^_4#x!=f{+(`toN#> z%)2qPvFEz-m!`_jxd79+1b8Sf&-16;3w}%c=S$*rdcR^jKWE_KBecVG&9EX!oW-(` ztnC;>b4D$yJ8az_!*ekuX14OxJJp2gn337NBm*z^M&B8LPN#X%XxN8QKws&jiln@N z*xO3JxX#%&`x?{!8;7?#`nWdy+L9jGJT=SHEFj6HZ8}7|e6or0l}Y&O=LTXrj9NSC z6+GMSa%rK4nh;cHJfwxcraTEFa9_T$F_#Luf^t|GSsQv!g}K4^xUR^xx3b@ddh-fw z_axr&sbSA%oX)q(a&rWxEl_{m{9_k2x}ms~l_xReIQ6WL%OZDhQnT)d6W3jPP88`0 zk41sf&+)&q%x!8b>v|EGn}&_HHN|6xG|W7e7IktI7$dswY_X<ucjML9^X-|D)UC>M znB1yR{OP<{J18tDQLY&NA*Xlf_=11OmBGBbw*B|+a^YAB{cTGkpYDfp^|z&%G_onU zZgkTyaI_swLUUgfFF1Ow*i9-~IYU3ds@L+9&CS_HnFvJ27`u-7qefr#hx`ObH~f^| zx)*i%^dMS&t^8G}|61MAok*d1yNMSpGoNzcCI#LS(sW5J=~hBJcNfN$%rY9^9@tix z+&74sE2(cBW0Eha_pwt#VCOQlH>M-eQ53GlhihY`9UME5RO@TSvMR~t(;|+t2dU3C z{VK1|cJ6+-ELKTvUY@q7--%yMFW40}{Tg4pvNF*;%Ys!{lNjjFmTD&w&`=s_!}3?0 zc6@M$9qxH4<{C@Y&e#_x@-X<ius!@93$<*W|DTZj9YM+X3xUW={|4nhd%^$iqew0B zzk>3QPVxT=lw(ptJU;>%BfincGPTjnojfiegu6~~BY(uR-eP)l@rdFf_Et6(O6#}P z6OqO3*#{|%bup8AWf~9P$!D&aJBq$>JzE%WRiW2MEM=@f)@~OuoL8t^Lpje*E>)bR zH7&outF^n5JlK9dgZ*OyZ)#lgzT8=KLG;79#MNdhtwcTwOm?JYva|JzeJ6F5PC2t; ze2|EI=+GgGfn{N(Xy3}D52^#xTY3y`eKWX(S>&5;uK4g};OcHkf4_1bA(%yc&7s<O z_MX;mliJ(1edX}k+J?wmEwhrnoj1o)Jt!xPpZYtbSY2V2XI7c9Du-U8NG>M~j0nsI zBszsFO$?XS09qGyi(akTtXoy}MpZPrC9FX;!qUnUM4qp~w+(BW21M5yki5}6>@Cr3 zCCsVC?{(!I>z^sTRZC$3RIH!!_R?Xw>D9&^`Vsr}U6?v}y0C2hYE5s)`u2412fVU! z^ZLE?!Q$7k9=@q3`Xk_<URZtTxH`r2mhd$<BlwZf#$vHTLQ~gbbKO(V=vqa~;Mge{ znr8bd>NC82UurBS>-;{Qx$I-e&>T`0(O1O^Is~caY<#doe9(LAs>8YVVr5m?(PP9n zS;$Z!He(n?8)jBEwXHimJA#Pj9_sR%(q%PSYs3X*RBc2M9+=xBGUY^zBs{CTZg=F~ z=e~QCaMiIXr7C4E@8k7r<0}bF1MADQ1<4-@)VmoR3aDT5ABKyIH&yqyO_g`Q;mEu+ zG+xshzW)WfU0Zg4uG7<8a<if~(Yut}czCUsGpitvu6*rdxhz4bNA@0?c)!Z}Er!ak zDJ?~mZ(cmNY4?&ju})z47OBNG$2Se4N3@b_o5s`OE%_YT1u}hfveqt#PgeT|g6a*t zhYE3P@S@wPnRbl9=^MnO(;;8PcWP@+ZBAxUiFIem#@yFhmI&P{9vc#?y*oFQ@$5E7 zA}z7EWL5U0AIC+pfR`nQvgfNx--Vd_T6?%oU#TjkMM)g!LN&YfDznO$nG~GwC}!La zz=0l??3NoXEV@-Cv7}GwE?IB8q2EmJSDad*fK5O*q$)roSqD`)o}tA|yRd<~nVW*o z)%!g;#tEOHIS*`JVZJdBJM_wrhiKkFS#%pf^WwPM@u<iy1<(3ee&aaiw~HYf##E)- z&LhL?6#E%ID?mDhkSd}OFK7m*S9~Ik^8~{~4kC4z=LEgrO4-%?{Mf8^ucIeQi6>I- zdV^`h<UQ*P6g~4FuLxN18>0H!K%a7EH?l`6_e4*GH8^eWXt}zoUg&a8wQ_7=k7x#3 z(AytuV=}(c2Bv*Y&fmW=ns;huNF_SfZYxIMP3h+Opn1DznVOsRL}~j<d;Xj2O!nF9 zL1&L60*|!J+1-i@I)ubXeFwXLwx^I^qXq~VD)So){~99ydN2M13!(pxh2ICx|6dL2 zqst-gLIRA(*m-z2<y*bu*(_e9#Iw~=kv@z<b=~N{h=U7*Bgf)7&)X<;+H(m|<y%s5 zDm*-zG=4*Hu04zuaf-XMSv5E{34w0v<C;xt>J-pw*g0mWKeA>pJHJ*}(EsA2((xVV z3-0Fz%@?n3(Yry!WW*FHeae(53h!9^66km1{I1vQo4N#)o~%J*>uKhxS_dxc4)I5Q ztO%csu%oxYTh9?Kw`<XFR%%w7b8(LEi#Vfl#I-oJWHq`IW*he^hTq?cV4v&tdhc<k zfpQq&hSOGP`}$6_;ppaRa8kv$i%a84`pfraD=Y3X?Hu6iPi;m7@T~MXE-BVDl;HVK zU<mhD0(0p`-%U;GPXn?1ISS#C+C&$sg|ey7lrk<BaqSykKJ$Un5y71KfQ3%sB|)yb z3ZeEvs?^@la>P!cHKw>nLsUxU$}OY2k;--%v<r7yn@t8x1g|=mF>0(VtZo`z42J1S zqh@+|Ei*gd!QrD4+gsG)kgvu3atjJY?Vfd6&P;2^>=+P3hjU$MujY$(_Hi+`HYHKE zn6S(zhcF*|X36?VAYjF+hL;&~V%BeK?!&d{)68xQQ-mpLxi(AVW6L(u32m*Ru2K$D z?*cUsbJTCYZ*E)8*wGeEc#>B3phL$)#&+fgjmvZ6?IU^58r2O|Szr@B<?i|s-WgNy zOKaD+o5Jq36dA@nSggx}OBTLHI8WoBCr5glIrYqQjUr^It7+?~<x8m!(BdhxPXZ2` z`QroE>k=ZaM8yr&*N&d`Za1FhSM)#7?3|t?jt<QZDr<1%0xhaeJ*7Y1b6eSWnsw+p z=5!TqUd7eW(7FI)TjYD;#YWG2Csd_JZFp<zjS%ACWg9J+_{jP3FI|R^$AO2~?!;Ts zCg@yqSm>(mswqUooysw!QFDvPHBN1@#O?-YR)<_!MsMg0D0fs%4Yu$sMmp@3E1bce ze8Qr%>au1^mv_n&ztqv|WqonVx-XNsE+1x-#Jy&p$GSb54>_QqnVH!7A3e~ou_GJ~ z{+0GV9!LiO7zlv_z`rk`3=Ad>13CbI(jao=?umQ>(Z6Z3FjDjMUo@!PA2cu+LbCeb zeDFW`q`*+paPOadQgZM=W#O_Up!z2t1Wrb@f6}Dn<o@7;LcxF7g+itNkcG+oDGP)D z>4yxQ{8s-@yAU~<ztM0W2$T!bgY?H72{}=|NK%|hvpEcgG*%?P(33`UXa@}N`;^e= X$3zU_f&0ECGH_`yKtx1CUlZ^jAdPCP diff --git a/misc/matlab/cramer_rao/test_bounds_circle.m b/misc/matlab/cramer_rao/test_bounds_circle.m deleted file mode 100644 index fcb948d..0000000 --- a/misc/matlab/cramer_rao/test_bounds_circle.m +++ /dev/null @@ -1,39 +0,0 @@ -function res = test_bounds_circle - -% grid -side = 5; -cell=0.1; -x=-side*0.5:cell:side*0.5; -y=-side*0.5:cell:side*0.5; - -% -radius = 0.5 * side * sqrt(2) + 1; -fov = pi; -rays = 91; - -for i=1:size(x,2) -for j=1:size(y,2) - - pose = [x(i); y(j); 0]; - ld = ld_circle(radius, pose, rays, fov); - bounds = compute_bounds(ld); - - etmax(i,j) = max(sqrt(eig(bounds.C0(1:2,1:2)))); - etmin(i,j) = min(sqrt(eig(bounds.C0(1:2,1:2)))); - eth(i,j) = rad2deg(sqrt(bounds.C0(3,3))); - - sigma = 0.01; - [etmax(i,j) * sigma etmin(i,j) * sigma eth(i,j) * sigma] - - data{i,j}.bounds = bounds; - data{i,j}.ld = ld; -end - fprintf('%d\n',i); -end - -%res.bounds = bounds; -res.etmax = etmax; -res.etmin = etmin; -res.eth = eth; -res.data = data; - diff --git a/misc/matlab/cramer_rao/test_bounds_oval.m b/misc/matlab/cramer_rao/test_bounds_oval.m deleted file mode 100644 index e93e905..0000000 --- a/misc/matlab/cramer_rao/test_bounds_oval.m +++ /dev/null @@ -1,45 +0,0 @@ -function res = test_bounds_oval - -% grid -side = 5; -cell=0.1; -x=-side*0.5:cell:side*0.5; -y=-side*0.5:cell:side*0.5; - -% -x_radius = 5.5; -y_radius = 5.2; - -fov = pi; -rays = 91; - -for i=1:size(x,2) -for j=1:size(y,2) - - pose = [x(i); y(j); 0]; - ld = ld_oval(x_radius, y_radius, pose, rays, fov); - bounds = compute_bounds(ld); - - etmax(i,j) = max(sqrt(eig(bounds.C0(1:2,1:2)))); - etmin(i,j) = min(sqrt(eig(bounds.C0(1:2,1:2)))); - eth(i,j) = rad2deg(sqrt(bounds.C0(3,3))); - - sigma = 0.01; - %[etmax(i,j) * sigma etmin(i,j) * sigma eth(i,j) * sigma] - - data{i,j}.bounds = bounds; - data{i,j}.ld = ld; -end - fprintf('%d\n',i); -end - -%res.bounds = bounds; -res.etmax = etmax; -res.etmin = etmin; -res.eth = eth; -res.data = data; - -test_bounds_oval_result2 = res; -save 'test_bounds_oval_2.mat' test_bounds_oval_result2; -% 1 = 5.5, 4.5 -% 2 = 5.5, 5.2 diff --git a/misc/matlab/cramer_rao/test_bounds_square.m b/misc/matlab/cramer_rao/test_bounds_square.m deleted file mode 100644 index 19e177f..0000000 --- a/misc/matlab/cramer_rao/test_bounds_square.m +++ /dev/null @@ -1,35 +0,0 @@ -function res = test_bounds_square(theta) - -side = 5; -cell=0.1; -x=-side*0.4:cell:side*0.4; -y=-side*0.4:cell:side*0.4; - -fov = pi; -rays = 91; - -for i=1:size(x,2) -for j=1:size(y,2) - - pose = [x(i); y(j); theta] - ld = ld_square(side, pose, rays, fov); - bounds = compute_bounds(ld); - - etmax(i,j) = max(sqrt(eig(bounds.C0(1:2,1:2)))); - etmin(i,j) = min(sqrt(eig(bounds.C0(1:2,1:2)))); - eth(i,j) = rad2deg(sqrt(bounds.C0(3,3))); - - sigma = 0.01; - [etmax(i,j) * sigma etmin(i,j) * sigma eth(i,j) * sigma] - - data{i,j}.bounds = bounds; - data{i,j}.ld = ld; -end -end - -%res.bounds = bounds; -res.etmax = etmax; -res.etmin = etmin; -res.eth = eth; -res.data = data; - diff --git a/misc/matlab/cramer_rao/test_bounds_square2_tmp.m b/misc/matlab/cramer_rao/test_bounds_square2_tmp.m deleted file mode 100644 index ab03355..0000000 --- a/misc/matlab/cramer_rao/test_bounds_square2_tmp.m +++ /dev/null @@ -1,28 +0,0 @@ -function res = test_bounds_square2_tmp(stuff) - -for i=1:size(stuff,1) -for j=1:size(stuff,2) - - ld = stuff{i,j}.ld; - bounds = compute_bounds(ld); - - etmax(i,j) = max(sqrt(eig(bounds.C0(1:2,1:2)))); - etmin(i,j) = min(sqrt(eig(bounds.C0(1:2,1:2)))); - eth(i,j) = rad2deg(sqrt(bounds.C0(3,3))); - - data{i,j}.bounds = bounds; - data{i,j}.ld = ld; - - if rand>0.95 - pause(0.01) - end -end -fprintf('%d\n', i); -end - -%res.bounds = bounds; -res.etmax = etmax; -res.etmin = etmin; -res.eth = eth; -res.data = data; - diff --git a/misc/matlab/cramer_rao/test_unstructured.m b/misc/matlab/cramer_rao/test_unstructured.m deleted file mode 100644 index 1d6b733..0000000 --- a/misc/matlab/cramer_rao/test_unstructured.m +++ /dev/null @@ -1,140 +0,0 @@ -function test_unstructured(res) - % analyzes result of the test_unstructured - - rho = 5; - amp = 0.2; - N = 30; - - nrays = 181; - fov = pi; - - ld2 = ld_sine(rho, amp, N, [0;0;0], nrays, fov); - - crb = compute_bounds(ld2); - - eig(crb.I0) - - % C of the f function in ld_sine - C = amp^2 * N^2 / (2 * rho^2); - D = amp^2 * N^4 / rho^4; - fprintf('Real information matrix:\n'); - crb.I0 - fprintf('Approximated information matrix:\n'); - I = cramer_rao_approximation(ld2, rho, C) - C - - - truth =[0;0;0]; - - for i=1:size(res,2) - points(:,i) = res{i}.X - truth; - end - - - bias = mean(points,2); - sample_cov = cov(points'); - - sigma = 0.01; - - if false - - m.datasets{1}.points = points; - m.datasets{1}.color = 'r.'; - m.covariances{1}.mean = bias; - m.covariances{1}.cov = sample_cov; - m.covariances{1}.color = 'r-'; - m.covariances{2}.mean = [0;0;0]; - m.covariances{2}.cov = crb.C0 * (sigma^2); - m.covariances{2}.color = 'b--'; - m.covariances{3}.mean = [0;0;0]; - m.covariances{3}.cov = inv(I) * (sigma^2); - m.covariances{3}.color = 'k-.'; - m.legend = {'Samples'; 'Sample \Sigma'; 'Cramer-Rao'; ... - 'Approximated\newline Cramer-Rao'}; - m.format = '-depsc2'; - m.prefix = 'icp_un'; - m.extension = 'eps'; - m.title = 'ICP, Unstructured env. -'; - fs = plot_xyt(m); - end - - e_th = points(3,:); - - real_std_th = sqrt(var(e_th')); - crb_std_th = sqrt(inv(crb.I0(3,3)))*sigma; - - batta = ((sigma/rho)^2 / (nrays * C)) * (1 + sigma * D / (2* C^2)); - approx_crb_std_th = sigma*sqrt(inv(nrays*(rho^2)*C)) - - batta_std_th = sqrt(batta); - - fprintf('Sample std: %f\n', rad2deg(real_std_th)); - fprintf('Cramer-Rao std: %f\n', rad2deg(crb_std_th)); - fprintf('Cramer-Rao (approx) std: %f\n', rad2deg(approx_crb_std_th)); - fprintf('Battacharya std: %f\n', rad2deg(batta_std_th)); - - ib=0; - n = 1; - - for theta=ld2.theta - s = rho * theta; - f = f(amp, N, rho, s); - f1 = f_dot(amp, N, rho, s); - f2 = f_ddot(amp, N, rho, s); - % ib = ib + (nf_dot^2) / (sigma^2) * inv(1+((sigma^2)/2)*( (nf_ddot^2)/(nf_dot^4))); - - inf = 2*(f1^6) / ( ((sigma/rho)^2)*(2*f1^4+(f2*sigma)^2)); - - if (f1^2) < 0.001 - n = n+1; - continue - end - - inf = (f1*rho/sigma)^2 * inv(1+0.5*(f2*sigma/(f1^2))^2); - ib = ib + inf; - - m(1,n)=f1; m(2,n)=f2; m(3,n)=inf; - m(4,n)=f; m(5,n)=ld2.readings(n); - n = n+1; - end - - mb = inv(ib); - figure - subplot(4,1,1); plot(m(1,:)); - subplot(4,1,2); plot(m(2,:)); - subplot(4,1,3); plot(m(3,:)); - subplot(4,1,4); - hold on; plot(m(4,:),'r-'); - plot(m(5,:),'b.'); - - fprintf('Battacharya real: %f\n', rad2deg(sqrt(mb))); - -function res = f(amp,N,rho,s) - res = rho+amp * cos( (N/rho) * s); - -function res = f_dot(amp, N, rho, s) - res = -amp * (N/rho) * sin ( (N/rho) * s); -function res = f_ddot(amp, N, rho, s) - res = -amp * ((N/rho)^2) * cos ( (N/rho) * s); - -function I = cramer_rao_approximation(ld, rho, C) - fov = max(ld.theta)-min(ld.theta); - - if (abs(fov - pi) < deg2rad(1)) - I_xy_th = [0; C*rho*(ld.nrays/pi)*2]; - else - if abs(fov - 2*pi) < deg2rad(1) - I_xy_th = [0; 0]; - else - error(sprintf('detected fov: %f', rad2deg(fov))); - end - end - lambda_I_t = (ld.nrays/2) * (1+C); - I_th = ld.nrays*(rho^2)*C; - - - I_t = [lambda_I_t 0; ... - 0 lambda_I_t]; - - I = [I_t I_xy_th; ... - I_xy_th' I_th]; diff --git a/misc/matlab/cramer_rao/test_unstructured_print.m b/misc/matlab/cramer_rao/test_unstructured_print.m deleted file mode 100644 index a17202e..0000000 --- a/misc/matlab/cramer_rao/test_unstructured_print.m +++ /dev/null @@ -1,20 +0,0 @@ -function test_unstructured_print - % prints the test environment - - rho = 5; - amp = 0.2; - N = 30; - - nrays = 181; - fov = pi; - - ld2 = ld_sine(rho, amp, N, [0;0;pi/2], nrays, fov); - - f=figure;hold on; - params.color = 'b-'; - ld_plot(ld2, params); - - ld = ld_add_noise(ld2, 0.01); - params.color = 'r.'; - ld_plot(ld, params) - axis('equal'); diff --git a/misc/matlab/gpm/go.sh b/misc/matlab/gpm/go.sh deleted file mode 100755 index eeadd4f..0000000 --- a/misc/matlab/gpm/go.sh +++ /dev/null @@ -1,3 +0,0 @@ -../scripts/collate.rb < gpm.m > test_gpm.m -pdflatex test - diff --git a/misc/matlab/gpm/gpm.m b/misc/matlab/gpm/gpm.m deleted file mode 100644 index 923b9d8..0000000 --- a/misc/matlab/gpm/gpm.m +++ /dev/null @@ -1,265 +0,0 @@ -function res = gpm(params) -% params.laser_ref The #first scan $\frac{pi}{4}$# -% params.laser_sens -% params.maxAngularCorrectionDeg -% params.maxLinearCorrection -% params.sigma - - - params_required(params, 'laser_sens'); - params_required(params, 'laser_ref'); - params = params_set_default(params, 'maxAngularCorrectionDeg', 25); - params = params_set_default(params, 'maxLinearCorrection', 0.4); - params = params_set_default(params, 'maxIterations', 20); - params = params_set_default(params, 'sigma', 0.01); - params = params_set_default(params, 'interactive', false); - - %% Compute surface orientation for \verb|params.laser_ref| and \verb|params.laser_sens| - params = compute_surface_orientation(params); - - %% Number of constraints generated (total) - k=1; - - %% \verb| ngenerated(a)|: number of constraints generated by point $a$ in \verb|laser_ref|. - ngenerated = zeros(1, params.laser_ref.nrays); - - %% \verb|ngeneratedb(b)|: number of constraints generated by $b$ in \verb|laser_sens|. - ngeneratedb = zeros(1, params.laser_sens.nrays); - - %% Iterate only on points which have a valid orientation. - for j=find(params.laser_ref.alpha_valid) - - alpha_j = params.laser_ref.alpha(j); - p_j = params.laser_ref.points(:,j); - - %% This finds a bound for the maximum variation of $\theta$ for - %% a rototranslation such that - %% \[|t|\leq|t|_{\text{max}}=\verb|maxLinearCorrection|\] - %% and - %% \[|\varphi|\leq|\varphi|_{\text{max}}=\verb|maxAngularCorrectionDeg|\] - %% - %% The bound is given by - %% \[ |\delta| \leq |\varphi|_{\text{max}} + \text{atan}{\frac{|t|_{\text{max}}}{|p_j|}}\] - - delta = abs(deg2rad(params.maxAngularCorrectionDeg)) + ... - abs(atan(params.maxLinearCorrection/norm(p_j))); - - angleRes = pi / size(params.laser_sens.points,2); - range = ceil(delta/angleRes); - from = j-range; - to = j+range; - from = max(from, 1); - to = min(to, size(params.laser_sens.points,2)); - - - for i=from:to - - if params.laser_sens.alpha_valid(i)==0 - continue; - end - - alpha_i = params.laser_sens.alpha(i); - phi = alpha_j - alpha_i; - phi = normAngle(phi); - - if abs(phi) > deg2rad(params.maxAngularCorrectionDeg) - continue - end - - p_i = params.laser_sens.points(:,i); - %% \newcommand{\fp}{\mathbf{p}} - %% $\hat{T} = \fp_j - R_\phi \fp_j$ - T = p_j - rot(phi) * p_i; - - - if norm(T) > params.maxLinearCorrection - continue - end - - weight=1; - weight = weight * sqrt(params.laser_ref.alpha_error(j)); - weight = weight * sqrt(params.laser_sens.alpha_error(i)); - weight=sqrt(weight); - - - C{k}.T = T; - C{k}.phi = phi; - % Surface normal - C{k}.alpha = alpha_j; - C{k}.weight = 1/weight; - C{k}.i = i; - C{k}.j = j; - - %% Keep track of how many generated particles per point - ngenerated(j) = ngenerated(j) + 1; - ngeneratedb(i) = ngeneratedb(i) + 1; - %% Keep track of how many generated particles. - k=k+1; - end - end - - %% Number of correspondences. - N = size(C,2); - fprintf('Number of corr.: %d\n', N); - - % build L matrix (Nx2) - L = zeros(N,2); L2 = zeros(2*N,3); - Y = zeros(N,1); Y2 = zeros(2*N,1); - W = zeros(N,1); W2 = zeros(2*N,1); - Phi = zeros(N,1); - samples = zeros(3,N); - for k=1:N - L(k,:) = vers(C{k}.alpha)'; - Y(k,1) = vers(C{k}.alpha)' * C{k}.T; - W(k,1) = C{k}.weight; - Phi(k,1) = C{k}.phi; - block = [vers(C{k}.alpha)' 0; 0 0 1]; - L2((k-1)*2+1:(k-1)*2+2,1:3) = block; - Y2((k-1)*2+1:(k-1)*2+2,1) = [Y(k,1); C{k}.phi]; - W2((k-1)*2+1:(k-1)*2+2,1) = [C{k}.weight;C{k}.weight]; - - samples(:,k) = [C{k}.T; C{k}.phi]; - end - - theta = hill_climbing(Phi, W, deg2rad(20), mean(Phi), 20, deg2rad(0.001)); - fprintf('Theta: %f\n', rad2deg(theta)); - - - Inf3 = zeros(3,3); - - for k=1:N - C{k}.v_alpha = vers(C{k}.alpha); - C{k}.v_dot_alpha = vers(C{k}.alpha + pi/2); - C{k}.R_phi = rot(C{k}.phi); - C{k}.R_dot_phi = rot(C{k}.phi + pi/2); - C{k}.v_j = vers(params.laser_ref.theta(C{k}.j)); - C{k}.v_i = vers(params.laser_sens.theta(C{k}.i)); - C{k}.cos_beta = C{k}.v_alpha' * C{k}.v_i; - C{k}.p_j = params.laser_ref.points(:,C{k}.j); - C{k}.p_i = params.laser_sens.points(:,C{k}.i); - C{k}.ngi = 1; %ngeneratedb(C{k}.i); - C{k}.ngj = 1; %ngenerated(C{k}.j); - - sigma_alpha = deg2rad(6.4); - sigma = params.sigma; - noises = diag([C{k}.ngi*sigma_alpha^2 C{k}.ngj*sigma_alpha^2 ... - C{k}.ngi*sigma^2 C{k}.ngj*sigma^2]); - - n_alpha_i = -C{k}.v_alpha'*C{k}.R_dot_phi*C{k}.p_i; - n_alpha_j = C{k}.v_dot_alpha'*(C{k}.T)+ C{k}.v_alpha'*C{k}.R_dot_phi*C{k}.p_i; - n_sigma_i = C{k}.v_alpha'* C{k}.R_phi * C{k}.v_i + C{k}.cos_beta; - n_sigma_j = - C{k}.v_alpha'* C{k}.v_j; - - L_k = [C{k}.v_alpha' 0; 0 0 1]; - Y_k = [C{k}.v_alpha'*C{k}.T; C{k}.phi]; - M_k = [ n_alpha_i n_alpha_j n_sigma_i n_sigma_j; -1 1 0 0 ]; - R_k = M_k * noises * M_k'; - C{k}.I = L_k' * inv(R_k) * L_k; - C{k}.M = L_k' * inv(R_k) * Y_k; - Inf3 = Inf3 + C{k}.I; - end - - Inf3 - Inf3(1:2,1:2) - Cov = inv(Inf3(1:2,1:2)); - - X = mean(samples,2); - X2 = mean(samples,2); - -% X(3) = theta; - for it=1:params.maxIterations - fprintf(strcat(' X : ',pv(X),'\n')) - fprintf(strcat(' X2: ',pv(X2),'\n')) - Sigma = diag([0.5 0.5 deg2rad(40)].^2); - - M1 = zeros(3,3); M2 = zeros(3,1); block=zeros(3,2); by=zeros(2,1); - T1 = zeros(3,3); T2 = zeros(3,1); - % update weights - for k=1:N - myX = [C{k}.T; C{k}.phi]; - weight = W(k,1) * mynormpdf( myX-X, [0;0;0], Sigma); - %we = exp(-norm(myX-X2)); - we = weight ; - va = vers(C{k}.alpha); - block = [va' 0; 0 0 1]; - by = [va' * C{k}.T; C{k}.phi]; - M1 = M1 + block' * weight * block; - M2 = M2 + block' * weight * by; - - T1 = T1 + C{k}.I * we; - T2 = T2 + C{k}.M * we; - end - Xhat = inv(M1) * M2; - Xhat2 = inv(T1) * T2; - - delta = X-Xhat; - delta = X2-Xhat2; - X = Xhat;% X(3) = theta; - X2 = Xhat2; - if norm(delta(1:2)) < 0.00001 - break - end - pause(0.1) - end - - res.X = X2; - res.Phi = Phi; - res.W = W; - res.samples = samples; - res.laser_ref=params.laser_ref; - res.laser_sens=params.laser_sens; - res.Inf = Inf; - res.Cov = Cov; - res.Cov3 = inv(Inf3); - res.corr = C; - - -function p = mynormpdf(x, mu, sigma); - mahal = (x-mu)' * inv(sigma) * (x-mu); - p = (1 / sqrt(2*pi * det(sigma))) * exp(-0.5*mahal); % XXX - -function res = hill_climbing(x, weight, sigma, x0, iterations, precision) -% hill_climbing(x, weight, sigma, x0, iterations, precision) - for i=1:iterations - for j=1:size(x) - updated_weight(j) = weight(j) * mynormpdf(x(j), x0, sigma^2); - %updated\_weight(j) = weight(j) * exp( -abs(x(j)- x0)/ (sigma)); - end - - x0new = sum(x .* updated_weight') / sum(updated_weight); - delta = abs(x0-x0new); - x0 = x0new; - - fprintf(' - %f \n', rad2deg(x0)); - - if delta < precision - break - end - end - - res = x0; - -function res = compute_surface_orientation(params) - %% Find a parameter of scale - n = params.laser_ref.nrays-1; - for i=1:n - dists(i) = norm( params.laser_ref.points(:,i)-params.laser_ref.points(:,i+1)); - end - dists=sort(dists); - - %params.scale = mean(dists(n/2:n-n/5))*2; - params.scale = max(dists(1:n-5))*2; - fprintf('scale: %f\n', params.scale); - - if not(isfield(params.laser_ref, 'alpha_valid')) - fprintf('Computing surface normals for ld1.\n'); - params.laser_ref = computeSurfaceNormals(params.laser_ref, params.scale); - end - - if not(isfield(params.laser_sens, 'alpha_valid')) - fprintf('Computing surface normals for ld2.\n'); - params.laser_sens = computeSurfaceNormals(params.laser_sens, params.scale); - end - - res = params; - diff --git a/misc/matlab/gpm/gpmSample.m b/misc/matlab/gpm/gpmSample.m deleted file mode 100644 index eaf2154..0000000 --- a/misc/matlab/gpm/gpmSample.m +++ /dev/null @@ -1,44 +0,0 @@ -function res = gpmSample(gpmres,n) - -m = size(gpmres.T, 2); -prepared = prepareSampling(1:m, gpmres.weight); -fprintf('Prepared\n'); -i=1; - -while i<n - - i1 = sampleIndex(prepared); - i2 = sampleIndex(prepared); - - alpha1 = gpmres.alpha(i1); - alpha2 = gpmres.alpha(i2); - rho1 = vers(alpha1)' * gpmres.T(:,i1); - rho2 = vers(alpha2)' * gpmres.T(:,i2); - - A = [vers(alpha1)'; vers(alpha2)']; - b = [rho1; rho2]; - - if det(A) == 0 - fprintf('No. det = %f\n', det(A)); - continue; - end - - W = diag([gpmres.weight(i1) gpmres.weight(i2)]); - C = inv(A' * inv(W) * A); - - e = eigs(C); - if min(e) / max(e) < 0.5 - fprintf('No.\n'); - continue - end - - T = A\b - res(:, i) = T; - i = i + 1; - pause(0.0001); -end - - -function v = vers(theta) - v = [cos(theta) sin(theta)]'; - diff --git a/misc/matlab/gpm/gpm_plot_res.m b/misc/matlab/gpm/gpm_plot_res.m deleted file mode 100644 index 22b3d66..0000000 --- a/misc/matlab/gpm/gpm_plot_res.m +++ /dev/null @@ -1,32 +0,0 @@ -function gpm_plot_res(res, mmin, mmax) - - - side = 2; - length = sqrt(2)*side; - hold on - - % number of correspondences - Ktot = size(res.corr, 2); - - drawn=0; - for k=1:Ktot - - - drawn = drawn + 1; - - T = res.corr{k}.T; - alpha = res.corr{k}.alpha; - - p1 = T + vers(alpha-pi/2) * length * 0.5; - p2 = T + vers(alpha+pi/2) * length * 0.5; - - reference = [0;0;0;]; % f.ts.laser_ref.estimate; - plotVectors(reference, [p1 p2], 'b-'); - - axis([-side side -side side]/2); - end - - fprintf('drawn %d/%d\n', drawn, Ktot); - -function v = vers(theta) - v = [cos(theta) sin(theta)]'; diff --git a/misc/matlab/gpm/gpm_test.m b/misc/matlab/gpm/gpm_test.m deleted file mode 100644 index 6ce49fb..0000000 --- a/misc/matlab/gpm/gpm_test.m +++ /dev/null @@ -1,45 +0,0 @@ -function doScanMatch(log) - -params.maxAngularCorrectionDeg = 25; % degrees -params.maxLinearCorrection = 0.15; % meters -params.emXYsigma = 0.2; - -f=figure; - set(f,'DoubleBuffer','on'); - set(f, 'NextPlot', 'replacechildren'); - -k=1; -for i=2:size(log,2) - if i>1 & ( vectorNorm2(log(i).odometry-log(i-1).odometry) < 0.01 ) - continue - end - - params.laserData1 = log(i-1); - params.laserData2 = log(i); - - res(k) = gpm(params); - - clf; - subplot(3,1,1) - hold off; - plotLaserData(log(i)); - axis('equal'); - - subplot(3,1,2); - hold off; - l = params.maxLinearCorrection; - axis([-l l -l l]); - plot( res(k).T(1,:),res(k).T(2,:), 'b.'); - axis('equal'); - - subplot(3,1,3); - hold off; - l = params.maxLinearCorrection; - axis([-l l -l l]); - plotGPM1(res(k)); - axis('equal'); - - - k=k+1; - drawnow; -end diff --git a/misc/matlab/gpm/gpm_test2.m b/misc/matlab/gpm/gpm_test2.m deleted file mode 100644 index 991f7bd..0000000 --- a/misc/matlab/gpm/gpm_test2.m +++ /dev/null @@ -1,40 +0,0 @@ - -params.maxAngularCorrectionDeg = 25; % degrees -params.maxLinearCorrection = 0.15; % meters -params.emXYsigma = 0.2; - - i=3; - params.laserData1 = log_bighouse(i-1); - params.laserData2 = log_bighouse(i); - - fprintf('executing gpm\n'); - %res = gpm(params); - - %fprintf('sampling\n'); - %r = gpmSample(res, 500); - - - % Densità - d = zeros(1,360); - for m=1:size(res.weight,2) - th = ceil(mod(rad2deg(res.alpha(m)),360)); - d(th) = d(th) + res.weight(m); - end - - d2 = simpleLowPassFilterCircular(d, 30); - %d = hist( mod(rad2deg(res.alpha),360), 1:360); - %mask = exp(-d2); - - for m=1:size(res.weight,2) - k = ceil( mod(rad2deg(res.alpha(m)), 360)); - - w(m) = res.weight(m) / d2(k ); - end - - - % Densità - d3 = zeros(1,360); - for m=1:size(res.weight,2) - th = ceil(mod(rad2deg(res.alpha(m)),360)); - d3(th) = d3(th) + w(m); - end diff --git a/misc/matlab/gpm/test.tex b/misc/matlab/gpm/test.tex deleted file mode 100644 index 498ccd2..0000000 --- a/misc/matlab/gpm/test.tex +++ /dev/null @@ -1,26 +0,0 @@ -\documentclass{article} -\usepackage{amsmath} -\usepackage{xcolor} -\usepackage{listings} - -\begin{document} -\lstset{% general command to set parameter(s) - basicstyle=\footnotesize\ttfamily, % print whole listing small - keywordstyle=\color{blue}\bfseries, - % underlined bold black keywords - identifierstyle=, % nothing happens - commentstyle=\color{green}, % white comments - stringstyle=\color{red}\ttfamily, % typewriter type for strings - tabsize=4, - language=matlab, - escapeinside={\%\%}{\^^M}, - %escapeinside={\%\%\%}{M\%\%\%}, - escapebegin=\begin{commentline}, - escapeend=\end{commentline}, - showstringspaces=false} % no special string spaces - -\newenvironment{commentline}{\begin{minipage}{\textwidth}\color{violet}\rmfamily}{\end{minipage}} - -\lstinputlisting[tabsize=4,language=matlab]{test_gpm.m} -\end{document} - diff --git a/misc/matlab/gpm/test_gpm.m b/misc/matlab/gpm/test_gpm.m deleted file mode 100644 index 6f687f6..0000000 --- a/misc/matlab/gpm/test_gpm.m +++ /dev/null @@ -1,258 +0,0 @@ -function res = gpm(params) -% params.laser_ref The #first scan $\frac{pi}{4}$# -% params.laser_sens -% params.maxAngularCorrectionDeg -% params.maxLinearCorrection -% params.sigma - - - params_required(params, 'laser_sens'); - params_required(params, 'laser_ref'); - params = params_set_default(params, 'maxAngularCorrectionDeg', 25); - params = params_set_default(params, 'maxLinearCorrection', 0.4); - params = params_set_default(params, 'maxIterations', 20); - params = params_set_default(params, 'sigma', 0.01); - params = params_set_default(params, 'interactive', false); - - %% Compute surface orientation for \verb|params.laser_ref| and \verb|params.laser_sens| - params = compute_surface_orientation(params); - - %% Number of constraints generated (total) - k=1; - - %% \verb| ngenerated(a)|: number of constraints generated by point $a$ in \verb|laser_ref|. - ngenerated = zeros(1, params.laser_ref.nrays); - - %% \verb|ngeneratedb(b)|: number of constraints generated by $b$ in \verb|laser_sens|. - ngeneratedb = zeros(1, params.laser_sens.nrays); - - %% Iterate only on points which have a valid orientation. - for j=find(params.laser_ref.alpha_valid) - - alpha_j = params.laser_ref.alpha(j); - p_j = params.laser_ref.points(:,j); - - %% This finds a bound for the maximum variation of $\theta$ for a rototranslation such that \[|t|\leq|t|_{\text{max}}=\verb|maxLinearCorrection|\] and \[|\varphi|\leq|\varphi|_{\text{max}}=\verb|maxAngularCorrectionDeg|\] - %% The bound is given by \[ |\delta| \leq |\varphi|_{\text{max}} + \text{atan}{\frac{|t|_{\text{max}}}{|p_j|}}\] - - delta = abs(deg2rad(params.maxAngularCorrectionDeg)) + ... - abs(atan(params.maxLinearCorrection/norm(p_j))); - - angleRes = pi / size(params.laser_sens.points,2); - range = ceil(delta/angleRes); - from = j-range; - to = j+range; - from = max(from, 1); - to = min(to, size(params.laser_sens.points,2)); - - - for i=from:to - - if params.laser_sens.alpha_valid(i)==0 - continue; - end - - alpha_i = params.laser_sens.alpha(i); - phi = alpha_j - alpha_i; - phi = normAngle(phi); - - if abs(phi) > deg2rad(params.maxAngularCorrectionDeg) - continue - end - - p_i = params.laser_sens.points(:,i); - %% \newcommand{\fp}{\mathbf{p}} $\hat{T} = \fp_j - R_\phi \fp_j$ - T = p_j - rot(phi) * p_i; - - - if norm(T) > params.maxLinearCorrection - continue - end - - weight=1; - weight = weight * sqrt(params.laser_ref.alpha_error(j)); - weight = weight * sqrt(params.laser_sens.alpha_error(i)); - weight=sqrt(weight); - - - C{k}.T = T; - C{k}.phi = phi; - % Surface normal - C{k}.alpha = alpha_j; - C{k}.weight = 1/weight; - C{k}.i = i; - C{k}.j = j; - - %% Keep track of how many generated particles per point - ngenerated(j) = ngenerated(j) + 1; - ngeneratedb(i) = ngeneratedb(i) + 1; - %% Keep track of how many generated particles. - k=k+1; - end - end - - %% Number of correspondences. - N = size(C,2); - fprintf('Number of corr.: %d\n', N); - - % build L matrix (Nx2) - L = zeros(N,2); L2 = zeros(2*N,3); - Y = zeros(N,1); Y2 = zeros(2*N,1); - W = zeros(N,1); W2 = zeros(2*N,1); - Phi = zeros(N,1); - samples = zeros(3,N); - for k=1:N - L(k,:) = vers(C{k}.alpha)'; - Y(k,1) = vers(C{k}.alpha)' * C{k}.T; - W(k,1) = C{k}.weight; - Phi(k,1) = C{k}.phi; - block = [vers(C{k}.alpha)' 0; 0 0 1]; - L2((k-1)*2+1:(k-1)*2+2,1:3) = block; - Y2((k-1)*2+1:(k-1)*2+2,1) = [Y(k,1); C{k}.phi]; - W2((k-1)*2+1:(k-1)*2+2,1) = [C{k}.weight;C{k}.weight]; - - samples(:,k) = [C{k}.T; C{k}.phi]; - end - - theta = hill_climbing(Phi, W, deg2rad(20), mean(Phi), 20, deg2rad(0.001)); - fprintf('Theta: %f\n', rad2deg(theta)); - - - Inf3 = zeros(3,3); - - for k=1:N - C{k}.v_alpha = vers(C{k}.alpha); - C{k}.v_dot_alpha = vers(C{k}.alpha + pi/2); - C{k}.R_phi = rot(C{k}.phi); - C{k}.R_dot_phi = rot(C{k}.phi + pi/2); - C{k}.v_j = vers(params.laser_ref.theta(C{k}.j)); - C{k}.v_i = vers(params.laser_sens.theta(C{k}.i)); - C{k}.cos_beta = C{k}.v_alpha' * C{k}.v_i; - C{k}.p_j = params.laser_ref.points(:,C{k}.j); - C{k}.p_i = params.laser_sens.points(:,C{k}.i); - C{k}.ngi = 1; %ngeneratedb(C{k}.i); - C{k}.ngj = 1; %ngenerated(C{k}.j); - - sigma_alpha = deg2rad(6.4); - sigma = params.sigma; - noises = diag([C{k}.ngi*sigma_alpha^2 C{k}.ngj*sigma_alpha^2 ... - C{k}.ngi*sigma^2 C{k}.ngj*sigma^2]); - - n_alpha_i = -C{k}.v_alpha'*C{k}.R_dot_phi*C{k}.p_i; - n_alpha_j = C{k}.v_dot_alpha'*(C{k}.T)+ C{k}.v_alpha'*C{k}.R_dot_phi*C{k}.p_i; - n_sigma_i = C{k}.v_alpha'* C{k}.R_phi * C{k}.v_i + C{k}.cos_beta; - n_sigma_j = - C{k}.v_alpha'* C{k}.v_j; - - L_k = [C{k}.v_alpha' 0; 0 0 1]; - Y_k = [C{k}.v_alpha'*C{k}.T; C{k}.phi]; - M_k = [ n_alpha_i n_alpha_j n_sigma_i n_sigma_j; -1 1 0 0 ]; - R_k = M_k * noises * M_k'; - C{k}.I = L_k' * inv(R_k) * L_k; - C{k}.M = L_k' * inv(R_k) * Y_k; - Inf3 = Inf3 + C{k}.I; - end - - Inf3 - Inf3(1:2,1:2) - Cov = inv(Inf3(1:2,1:2)); - - X = mean(samples,2); - X2 = mean(samples,2); - -% X(3) = theta; - for it=1:params.maxIterations - fprintf(strcat(' X : ',pv(X),'\n')) - fprintf(strcat(' X2: ',pv(X2),'\n')) - Sigma = diag([0.5 0.5 deg2rad(40)].^2); - - M1 = zeros(3,3); M2 = zeros(3,1); block=zeros(3,2); by=zeros(2,1); - T1 = zeros(3,3); T2 = zeros(3,1); - % update weights - for k=1:N - myX = [C{k}.T; C{k}.phi]; - weight = W(k,1) * mynormpdf( myX-X, [0;0;0], Sigma); - %we = exp(-norm(myX-X2)); - we = weight ; - va = vers(C{k}.alpha); - block = [va' 0; 0 0 1]; - by = [va' * C{k}.T; C{k}.phi]; - M1 = M1 + block' * weight * block; - M2 = M2 + block' * weight * by; - - T1 = T1 + C{k}.I * we; - T2 = T2 + C{k}.M * we; - end - Xhat = inv(M1) * M2; - Xhat2 = inv(T1) * T2; - - delta = X-Xhat; - delta = X2-Xhat2; - X = Xhat;% X(3) = theta; - X2 = Xhat2; - if norm(delta(1:2)) < 0.00001 - break - end - pause(0.1) - end - - res.X = X2; - res.Phi = Phi; - res.W = W; - res.samples = samples; - res.laser_ref=params.laser_ref; - res.laser_sens=params.laser_sens; - res.Inf = Inf; - res.Cov = Cov; - res.Cov3 = inv(Inf3); - res.corr = C; - - -function p = mynormpdf(x, mu, sigma); - mahal = (x-mu)' * inv(sigma) * (x-mu); - p = (1 / sqrt(2*pi * det(sigma))) * exp(-0.5*mahal); % XXX - -function res = hill_climbing(x, weight, sigma, x0, iterations, precision) -% hill_climbing(x, weight, sigma, x0, iterations, precision) - for i=1:iterations - for j=1:size(x) - updated_weight(j) = weight(j) * mynormpdf(x(j), x0, sigma^2); - %updated\_weight(j) = weight(j) * exp( -abs(x(j)- x0)/ (sigma)); - end - - x0new = sum(x .* updated_weight') / sum(updated_weight); - delta = abs(x0-x0new); - x0 = x0new; - - fprintf(' - %f \n', rad2deg(x0)); - - if delta < precision - break - end - end - - res = x0; - -function res = compute_surface_orientation(params) - %% Find a parameter of scale - n = params.laser_ref.nrays-1; - for i=1:n - dists(i) = norm( params.laser_ref.points(:,i)-params.laser_ref.points(:,i+1)); - end - dists=sort(dists); - - %params.scale = mean(dists(n/2:n-n/5))*2; - params.scale = max(dists(1:n-5))*2; - fprintf('scale: %f\n', params.scale); - - if not(isfield(params.laser_ref, 'alpha_valid')) - fprintf('Computing surface normals for ld1.\n'); - params.laser_ref = computeSurfaceNormals(params.laser_ref, params.scale); - end - - if not(isfield(params.laser_sens, 'alpha_valid')) - fprintf('Computing surface normals for ld2.\n'); - params.laser_sens = computeSurfaceNormals(params.laser_sens, params.scale); - end - - res = params; - diff --git a/misc/matlab/gpm/yasmine.m b/misc/matlab/gpm/yasmine.m deleted file mode 100644 index 103d14c..0000000 --- a/misc/matlab/gpm/yasmine.m +++ /dev/null @@ -1,157 +0,0 @@ -function res = yasmine(params) -% params.sigma -% params.laser_sens % sensor (indexed by i) -% params.laser_ref % map (indexed by j) laser_sens * (x,y,theta) = laser_ref -% params.maxAngularCorrectionDeg -% params.maxLinearCorrection - - % readings for which a valid alpha was computed - valid1 = find(params.laser_sens.alpha_valid); - - ktot = 1; - - num_noises = params.laser_sens.nrays*2 + params.laser_ref.nrays *2; - num_corr = 50 *params.laser_sens.nrays; - res.M = zeros(num_corr*2, num_noises); - res.Y = zeros(num_corr*2, 1); - res.L = zeros(num_corr*2, 3); - - for i=valid1 - - fprintf('%d / %d \n', i, params.laser_sens.nrays); - - theta_i = params.laser_sens.theta(i); - p_i = params.laser_sens.readings(i) * vers(theta_i); - alpha_i = params.laser_sens.alpha(i); - alpha_i_var = params.laser_sens.alpha_error(i); - - % estimate other interval - delta = abs(deg2rad(params.maxAngularCorrectionDeg)) ... - +abs(atan(params.maxLinearCorrection/norm(p_i))); - angleRes = pi / params.laser_ref.nrays; - range = ceil(delta/angleRes); - from = i-range; - to = i+range; - from = max(from, 1); - to = min(to, params.laser_ref.nrays); - - %from = 1; - %to = params.laser_ref.nrays; - % putting all correespondences in "corre" - k = 1; - corre={}; - for j=from:to - if params.laser_ref.alpha_valid(j)==0 - continue; - end - - p_j = params.laser_ref.readings(j) * vers(params.laser_ref.theta(j)); - alpha_j = params.laser_ref.alpha(j); - - phi_hat = normAngle(alpha_j - alpha_i); - T_hat = p_j - rot(phi_hat) * p_i; - - if abs(phi_hat) > deg2rad(params.maxAngularCorrectionDeg) - continue - end - if norm(T_hat) > params.maxLinearCorrection - continue - end - - corre{k}.j = j; - corre{k}.alpha_j = alpha_j; - corre{k}.phi_hat = phi_hat; - corre{k}.T_hat = T_hat; - k = k+1; - end - - for k=1:size(corre,2) - % regressore - j = corre{k}.j ; - theta_j = params.laser_ref.theta(j); - alpha_j = params.laser_ref.alpha(j);; - alpha_j_var = params.laser_ref.alpha_error(j); - alpha_i_var = params.laser_sens.alpha_error(i); - phi_hat = corre{k}.phi_hat; - T_hat = corre{k}.T_hat; - proj = vers(alpha_j)'; - % Lk * (T phi) = yk - - Lk = [ proj 0; 0 0 1]; - Yk = [ proj*T_hat; phi_hat]; - - res.L((ktot-1)*2+1:(ktot-1)*2+2,1:3) = Lk; - res.Y((ktot-1)*2+1:(ktot-1)*2+2,1) = Yk; - - index_e_i = (i-1)*4 + 1; - index_w_i = (i-1)*4 + 2; - index_e_j = (j-1)*4 + 3; - index_w_j = (j-1)*4 + 4; - - v_i = vers(theta_i); - v_j = vers(theta_j); - - % incertezza proj - C = sqrt(size(corre,2)); - res.M((ktot-1)*2+1, index_e_i) = C * (- proj * rot(phi_hat) * v_i); - res.M((ktot-1)*2+1, index_e_j) = C * ( proj * v_j); - res.M((ktot-1)*2+1, index_w_i) = C * ( ... - vers(alpha_j+pi/2)'*T_hat + ... - proj * rot(phi_hat+pi/2) * p_i ); - res.M((ktot-1)*2+1, index_w_j) = C * (- proj * rot(phi_hat+pi/2) * p_i); - % incertezza angolo - res.M((ktot-1)*2+2, index_w_i) = C * -1; - res.M((ktot-1)*2+2, index_w_j) = C * 1; - - Rk = [res.M((ktot-1)*2+1, index_e_i) ... - res.M((ktot-1)*2+1, index_e_j) ... - res.M((ktot-1)*2+1, index_w_i) ... - res.M((ktot-1)*2+1, index_w_j);... - 0 0 ... - res.M((ktot-1)*2+2, index_w_i) ... - res.M((ktot-1)*2+2, index_w_j)]; - - Zk = diag([ params.sigma params.sigma alpha_i_var alpha_j_var]); - - Covk = Rk * Zk * Rk'; - - - Lk = [ proj 0; 0 0 1]; - Yk = [ proj*T_hat; phi_hat]; - - res.s{ktot}.Lk = Lk; - res.s{ktot}.Yk = Yk; - res.s{ktot}.Rk = Rk; - res.s{ktot}.Covk = Covk; - - ktot = ktot+1; - end - -% fprintf('corr = %d \n', size(corre,2)); - - end - - num_corr = ktot-1; - res.M = res.M(1:num_corr*2, 1:num_noises); - res.Y = res.Y(1:num_corr*2, 1); - res.L = res.L(1:num_corr*2, 1:3); - - % trova soluzione singola - I = zeros(3,3); - A = zeros(3,1); - for i=1:num_corr - I = I + res.s{i}.Lk' * inv(res.s{i}.Covk) * res.s{i}.Lk; - A = A + res.s{i}.Lk' * inv(res.s{i}.Covk) * res.s{i}.Yk; - end - - res.I = I; - res.Cov = inv(I); - res.x_hat = res.Cov * A; - -function res = rot(phi) - % Rotation matrix - res = [cos(phi) -sin(phi); sin(phi) cos(phi)]; - -function v = vers(theta) - v = [cos(theta) sin(theta)]'; - diff --git a/misc/matlab/gpm/yasmine2.m b/misc/matlab/gpm/yasmine2.m deleted file mode 100644 index 5108728..0000000 --- a/misc/matlab/gpm/yasmine2.m +++ /dev/null @@ -1,227 +0,0 @@ -% params.sigma -% params.laser_sens % sensor (indexed by i) -% params.laser_ref % map (indexed by j) laser_sens * (x,y,theta) = laser_ref -% params.maxAngularCorreectionDeg -% params.maxLinearCorreection - -function res = yasmine2(params) - - % readings for which a valid alpha was computed - valid1 = find(params.laser_sens.alpha_valid); - n_i = sum(params.laser_sens.alpha_valid) - - ktot = 1; - - for i=valid1 - - theta_i = params.laser_sens.theta(i); - p_i = params.laser_sens.readings(i) * vers(theta_i); - alpha_i = params.laser_sens.alpha(i); - alpha_i_var = params.laser_sens.alpha_error(i); - - % estimate other interval - delta = abs(deg2rad(params.maxAngularCorrectionDeg)) ... - +abs(atan(params.maxLinearCorrection/norm(p_i))); - angleRes = pi / params.laser_ref.nrays; - range = ceil(delta/angleRes); - from = i-range; - to = i+range; - from = max(from, 1); - to = min(to, params.laser_ref.nrays); - - - % putting all correespondences in "corre" - k = 1; - corre={}; - for j=from:to - if params.laser_ref.alpha_valid(j)==0 - continue; - end - - p_j = params.laser_ref.readings(j) * vers(params.laser_ref.theta(j)); - alpha_j = params.laser_ref.alpha(j); - - phi_hat = normAngle(alpha_j - alpha_i); - T_hat = p_j - rot(phi_hat) * p_i; - - - if abs(phi_hat) > deg2rad(params.maxAngularCorrectionDeg) - continue - end - if norm(T_hat) > params.maxLinearCorrection - continue - end - - corre{k}.j = j; - corre{k}.alpha_j = alpha_j; - corre{k}.phi_hat = phi_hat; - corre{k}.T_hat = T_hat; - k = k+1; - end - - for k=1:size(corre,2) - % regressore - j = corre{k}.j ; - theta_j = params.laser_ref.theta(j); - alpha_j = params.laser_ref.alpha(j);; - alpha_j_var = params.laser_ref.alpha_error(j); - alpha_i_var = params.laser_sens.alpha_error(i); - phi_hat = corre{k}.phi_hat; - T_hat = corre{k}.T_hat; - proj = vers(alpha_j)'; - % Lk * (T phi) = yk - - Lk = [ proj 0; 0 0 1]; - Yk = [ proj*T_hat; phi_hat]; - -% res.L((ktot-1)*2+1:(ktot-1)*2+2,1:3) = Lk; -% res.Y((ktot-1)*2+1:(ktot-1)*2+2,1) = Yk; - - index_e_i = (i-1)*4 + 1; - index_w_i = (i-1)*4 + 2; - index_e_j = (j-1)*4 + 3; - index_w_j = (j-1)*4 + 4; - - v_i = vers(theta_i); - v_j = vers(theta_j); - - % incertezza proj - C = sqrt(size(corre,2)); - C = 1; - r_e_i = C * (- proj * rot(phi_hat) * v_i); - r_e_j = C * ( proj * v_j); - r_w_i = C * ( ... - vers(alpha_j+pi/2)'*T_hat + ... - proj * rot(phi_hat+pi/2) * p_i ); - r_w_j = C * (- proj * rot(phi_hat+pi/2) * p_i); - % incertezza angolo - s_w_i = C * -1; - s_w_j = C * 1; - - Rk = [r_e_i r_e_j r_w_i r_w_j;... - 0 0 s_w_i s_w_j]; - - Zk = diag([ params.sigma params.sigma alpha_i_var alpha_j_var]); - - Covk = Rk * Zk * Rk'; - - Lk = [ proj 0; 0 0 1]; - Yk = [ proj*T_hat; phi_hat]; - - maha = compute_ma(Lk,Yk,Covk, params.odometry, params.odometry_cov); - if(maha>params.chi_limit) - continue - end - - res.s{ktot}.Lk = Lk; - res.s{ktot}.Yk = Yk; - res.s{ktot}.Rk = Rk; - res.s{ktot}.Covk = Covk; - res.s{ktot}.alpha = alpha_j; - res.s{ktot}.T = T_hat; - res.s{ktot}.phi = phi_hat; - - ktot = ktot+1; - end - -% fprintf('corr = %d \n', size(corre,2)); - - end - - - trim = params.trim; - chi_perc = params.chi_perc; - chi_limit = params.chi_limit; - - valids = ones(1,ktot-1); valids_i = find(valids>0); nvalids = sum(valids); - [x, Cov] = find_solution(res.s, valids_i, params.odometry, params.odometry_cov); - - limit = 2.3 * n_i - while true - if nvalids < limit - res.x_hat = x; - res.Cov = Cov; - fprintf('Terminated reaching limit \n'); - break; - end - - ms = compute_m(res.s, valids_i, x, Cov); - - fprintf(' valid = %d min %f mean %f max %f \n', nvalids, min(ms(valids_i)), ... - mean(ms(valids_i)),max(ms(valids_i))); - - s = sum( ms(valids_i) <chi_limit ); - low_perc = s / nvalids; - -% fprintf(' low perc: %f \n', low_perc); - if low_perc > chi_perc - res.x_hat = x; - res.Cov = Cov; - break; - end - - - - Y = sort(ms(valids_i),2,'descend'); - threshold = Y( ceil( trim *nvalids) ); - -% fprintf(' threshold: %f \n', threshold); - for i=valids_i - if(ms(i)>threshold) - valids(i) = 0; - end - end - - valids_i = find(valids>0); nvalids = sum(valids); - - [x, Cov] = find_solution(res.s, valids_i, params.odometry, params.odometry_cov); - fprintf(' x = %f %f %f \n ', x(1),x(2),rad2deg(x(3))); - - end - - - xy=sqrt(eig(Cov(1:2,1:2))); - et=rad2deg(sqrt(Cov(3,3))); - fprintf(' x = %f %f %f \n ', x(1),x(2),rad2deg(x(3))); - fprintf(' eig xy: %f %f \n ', xy(1), xy(2)); - fprintf(' eig theta: %f \n ', et(1)); - -function ms = compute_m(s, valids_i, x_hat, x_cov) - for k=valids_i - L = s{k}.Lk; - Y = s{k}.Yk; - Cov = s{k}.Covk; - ms(k) = compute_ma(L,Y,Cov, x_hat, x_cov); - end - -function ma = compute_ma(L,Y,C, x_hat, x_cov) - Ctot = C + L * x_cov * L'; - e = L * x_hat - Y; - ma = e' * inv(Ctot) * e; - -function [x, Cov] = find_solution(s, valids_i, odometry, odometry_cov) - % trova soluzione singola - I = zeros(3,3); - A = zeros(3,1); - used = 0; - for i=valids_i - used = used +1; - I = I + s{i}.Lk' * inv(s{i}.Covk) *s{i}.Lk; - A = A + s{i}.Lk' * inv(s{i}.Covk) *s{i}.Yk; - end - - I = I + inv(odometry_cov); - A = A + inv(odometry_cov) * odometry; - - Cov = inv(I); - x = Cov * A; - %fprintf('used %d / %d \n', used, size(valids,2)); - - -function res = rot(phi) - % Rotation matrix - res = [cos(phi) -sin(phi); sin(phi) cos(phi)]; - -function v = vers(theta) - v = [cos(theta) sin(theta)]'; - diff --git a/misc/matlab/icp/closest_point_on_segment.m b/misc/matlab/icp/closest_point_on_segment.m deleted file mode 100644 index da212f2..0000000 --- a/misc/matlab/icp/closest_point_on_segment.m +++ /dev/null @@ -1,45 +0,0 @@ - -function res = closest_point_on_segment(A,B,p) -% closest_point_on_segment(A,B,p) -% find closest point to p on segment A-B - projection = projection_on_line_seg(A,B,p); - -% fprintf('Closest(%s,%s;%s)\n', pv(A), pv(B), pv(p)); -% fprintf(' projection: \n', pv(projection)); - -% fprintf('A: %s B: %s p: %s proj: %s\n',pv(A),pv(B),pv(p),pv(projection)); - - %res = projection; - %return; - - % check whether projection is inside the segment - if (projection-A)'*(projection-B)<0 - res = projection; - else - if norm(p-A) < norm(p-B) - res = A; - else - res = B; - end - end - -function res = projection_on_line_seg(A,B,p) -% projection_on_line_seg(A,B,p) -% finds projection of p on line through A,B - - % find polar representation - v_alpha = rot(pi/2) * (A-B) / norm(A-B); - alpha = atan2(v_alpha(2),v_alpha(1)); - rho = v_alpha' * A; - res = projection_on_line(alpha, rho, p); -% fprintf('alpha = %f v_alpha = %s rho = %f\n', alpha, pv(v_alpha), rho); - -function res = projection_on_line(alpha, rho, p) -% projection_on_line(alpha, rho, p) -% finds projection of p on line whose polar representation is (alpha,rho) - - res = vers(alpha) * rho + (p-(vers(alpha)'*p)*vers(alpha)); - - % 0 == vers(alpha)' * res - rho - - diff --git a/misc/matlab/icp/exact_minimization.m b/misc/matlab/icp/exact_minimization.m deleted file mode 100644 index b0c8199..0000000 --- a/misc/matlab/icp/exact_minimization.m +++ /dev/null @@ -1,46 +0,0 @@ -function [pose, L, Y] = exact_minimization(points1, points2) - [L,Y] = create_system(points1,points2); - - B = L'*Y; - x1 = B(1:2); - x2 = B(3:4); - - A = (L'*L); - lB = A(1:2,3:4); - bt=lB'*lB; - b=bt(1,1); - - % closed form solution - n = A(1,1); - c = A(3,3); - - pol = [ (b* x1'*x1+n^2 * x2'*x2 -2*n*x1'*lB*x2) 0 (-1)]; - r = roots(pol); - la1 = (1/n) * (1/r(1) -n*c+b); - la2 = (1/n) * (1/r(2) -n*c+b); - - M = diag([0 0 1 1]); - L2 = (L'*L + la1 * M); - Y2 = L'*Y; - x_hat = inv(L2) * Y2; - - theta_hat = atan2(x_hat(4),x_hat(3)); - pose = [x_hat(1); x_hat(2); theta_hat]; - - -function [L,Y] = create_system(points1, points2) - N = size(points1,2); - L = zeros(2*N,4); - Y = zeros(2*N,1); - for i=1:N - for j=max(1,i):min(i,N) - p_i = points1(:,i); - p_j = points2(:,j); - Lk = [ eye(2) p_i rot(pi/2)*p_i ]; - Yk = p_j; - - L((i-1)*2+1:(i-1)*2+2,1:4) = Lk; - Y((i-1)*2+1:(i-1)*2+2,1) = Yk; - end - end - diff --git a/misc/matlab/icp/icp.m b/misc/matlab/icp/icp.m deleted file mode 100644 index 9879db4..0000000 --- a/misc/matlab/icp/icp.m +++ /dev/null @@ -1,139 +0,0 @@ -% Dependences of this script: -% Requires: params_required, params_set_default, icp_get_correspondences -% Requires: ld_plot, icp_covariance, exact_minimization, transform -% Requires: icp_possible_interval - -function res = icp(params) -% Note: it is assumed that params.laser_ref has a radial uniform scan -% params.laser_ref - first scan -% params.laser_sens - second scan -% params.maxAngularCorrectionDeg - search space bound for phi, in degrees -% params.maxLinearCorrection - search space bound for |t|, in degrees - - - params_required(params, 'laser_sens'); - params_required(params, 'laser_ref'); - params = params_set_default(params, 'maxAngularCorrectionDeg', 105); - params = params_set_default(params, 'maxCorrespondenceDist', 4); - params = params_set_default(params, 'maxLinearCorrection', 2); - params = params_set_default(params, 'maxIterations', 40); - params = params_set_default(params, 'firstGuess', [0;0;0]); - params = params_set_default(params, 'interactive', false); - params = params_set_default(params, 'epsilon_xy', 0.0001); - params = params_set_default(params, 'epsilon_theta', deg2rad(0.001)); - params = params_set_default(params, 'sigma', 0.01); - params = params_set_default(params, 'do_covariance', false); - - %% If true, consider as null correspondences with first or last point - %% in the reference scan. - params = params_set_default(params, 'dont_consider_extrema', false); - - - current_estimate = params.firstGuess; - params.laser_sens.estimate = current_estimate; - - if params.interactive - f = figure; hold on - end - - - estimated_cov = eye(3); - - for n=1:params.maxIterations - estimates{n} = current_estimate; - - - [P, valids, jindexes] = icp_get_correspondences(params, current_estimate); - - fprintf('Valid corr.: %d\n', sum(valids)); - next_estimate = next_estimate(params, current_estimate, P, valids); - - delta = next_estimate-current_estimate; - - - %% If in interactive mode, show partial solution. - if params.interactive - clf - pl.color = 'b.'; - ld_plot(params.laser_ref,pl); - pl.color = 'r.'; - params.laser_sens.estimate = rtcat(params.laser_ref.estimate, current_estimate); - ld_plot(params.laser_sens,pl); - axis('equal'); - - - for i=find(valids) - - plotVectors(params.laser_sens.estimate, [params.laser_sens.points(:,i) P(:,i)] , 'k'); - - end - - % pause - end - - current_estimate = next_estimate; - - fprintf('Delta: %s\n', pv(delta)); - fprintf('Estimate: %s\n', pv(current_estimate)); - - if (norm(delta(1:2)) < params.epsilon_xy) & ... - (norm(delta(3)) < params.epsilon_theta) - - break; - end - - pause(0.01) - end % iterations -fprintf('Converged at iteration %d.\n', n); - - res = params; - - if(params.do_covariance) - estimated_cov = icp_covariance(params, current_estimate, P, valids, jindexes); - res.sm_cov_bengtsson = estimated_cov.sm_cov_bengtsson; - res.loc_cov_censi = estimated_cov.loc_cov_censi; - res.sm_cov_censi = estimated_cov.sm_cov_censi; - end - - - res.X = current_estimate; - res.iteration = n; - estimates{n+1} = current_estimate; - res.estimates = estimates; - - -function next = next_estimate(params, current_estimate, P, valids) -% Requires: transform - if sum(valids) < 2 - error('icp:run', sprintf('Only %d correspondences found.',sum(valids))); - end - - next = current_estimate; - - k=1; e = 0; - for a=find(valids) - points1(:,k) = transform(params.laser_sens.points(:,a), current_estimate); - points2(:,k) = P(:,a); - - if params.interactive - plot_line(points1(:,k),points2(:,k),'g-'); - end - - e = e + norm(points1(:,k)-points2(:,k)); - k=k+1; - end - - [pose, L, Y] = exact_minimization(points1, points2); - - fprintf('exact_min: %s ', pv(pose)); - - next_phi = current_estimate(3) + pose(3); - next_t = transform(current_estimate(1:2,1), pose); - next = [next_t; next_phi]; - - fprintf('Pose: %s error: %f\n', pv(next), e); - -function plot_line(a,b,color) - plot([a(1) b(1)],[a(2) b(2)], color); - - diff --git a/misc/matlab/icp/icp_covariance.m b/misc/matlab/icp/icp_covariance.m deleted file mode 100644 index ad2732d..0000000 --- a/misc/matlab/icp/icp_covariance.m +++ /dev/null @@ -1,154 +0,0 @@ - -function res = icp_covariance(params, current_estimate, P, valids, jindexes) - % res = icp_covariance(params, current_estimate, P, valids, jindexes) - % - % Compute the covariance of the ICP estimate. - % - % params.laser_sens laser data structure describing sensor scan - % params.laser_ref laser data structure describing reference scan - % - % Fields used: - % laser_*.nrays number of rays - % laser_*.points 2xnrays vector of readings in cartesian coordinates - % - % params.sigma sigma of noise on readings - % current_estimate solution found by ICP: pose of laser_sens in laser_ref reference frame - % valids nrays x 1 vector: valids(i) == 1 if the i-th point in laser_sens has valid correspondences - % jindexes nrays x 2 correspondences: jindexes(i,1), jindexes(i,2) are the indices - % of the closest points in laser_ref of the i-th point in laser_sens - % - % P unused (probably legacy from some old code) - % - k=1; - - Etot = 0; - Gtot = [0;0;0]; - G2tot = zeros(3,3); - MMtot = zeros(3,3); - - x=current_estimate(1); - y=current_estimate(2); - theta=current_estimate(3); - - %% These are the interval to approximate the derivatives with - %% the increments. - eps_xy = 0.000001; - eps_t = deg2rad(0.01); - - center = zeros(3); - - dgE_di = zeros(3, params.laser_sens.nrays); - dgE_dj = zeros(3, params.laser_ref.nrays); - - % let's iterate on the "valid" points of laser_sens - for a=find(valids) - % index of point in laser_sens - i = a; - % indices of the two corresponding points in laser_ref - j1 = jindexes(i,1); - j2 = jindexes(i,2); - - p_i = params.laser_sens.points(:,a); - p_j1 = params.laser_ref.points(:,j1); - p_j2 = params.laser_ref.points(:,j2); - - rho_i = norm(p_i); - rho_j1 = norm(p_j1); - rho_j2 = norm(p_j2); - v_i = p_i / norm(p_i); - v_j1 = p_j1 / norm(p_j1); - v_j2 = p_j2 / norm(p_j2); - - %% The following is ugly but conceptually simple: - %% we define an error function E_k and then we derive it numerically. - - %% Note that we use the Matlab lambda-notation - %% func = @(x) x^2 - %% who would have thought that also Matlab can be Lispy? :-) - - %% The error function is the traditional point-to-segment distance (squared) - E_k = @(rho_i_, rho_j1_, rho_j2_, x_, y_, theta_) ... - norm(... - transform(v_i*rho_i_, [x_;y_;theta_]) ... - - ... - closest_point_on_segment(v_j1*rho_j1_, v_j2*rho_j2_, ... - transform(v_i*rho_i_, [x_;y_;theta_])) ... - )^(2); - %% first point p_i transformed by current estimate - %% and the closest point on the segment - - %% First derivative - gradEk = @(rho_i_, rho_j1_, rho_j2_, x_, y_, theta_) ... - [ deriv(@(xx)E_k(rho_i_,rho_j1_,rho_j2_,xx,y_,theta_), x_, eps_xy); ... - deriv(@(yy)E_k(rho_i_,rho_j1_,rho_j2_,x_,yy,theta_), y_, eps_xy); ... - deriv(@(tt)E_k(rho_i_,rho_j1_,rho_j2_,x_,y_,tt), theta_, eps_t)]; - - %% Second derivative - d2Ek_dx2 = @(rho_i_, rho_j1_, rho_j2_, x_, y_, theta_) ... - [ deriv(@(xx)gradEk(rho_i_,rho_j1_,rho_j2_,xx,y_,theta_), x_, eps_xy) ... - deriv(@(yy)gradEk(rho_i_,rho_j1_,rho_j2_,x_,yy,theta_), y_, eps_xy) ... - deriv(@(tt)gradEk(rho_i_,rho_j1_,rho_j2_,x_,y_,tt), theta_, eps_t)]; - - %% The noise has three components: epsilon_i, epsilon_j1, epsilon_j2 - d2Ek_dxdei = @(rho_i_, rho_j1_, rho_j2_, x_, y_, theta_) ... - deriv(@(ei)gradEk(ei,rho_j1_,rho_j2_,x_,y_,theta_), rho_i_, eps_xy); - - d2Ek_dxdej1 = @(rho_i_, rho_j1_, rho_j2_, x_, y_, theta_) ... - deriv(@(ej1)gradEk(rho_i_,ej1,rho_j2_,x_,y_,theta_), rho_j1_, eps_xy); - - d2Ek_dxdej2 = @(rho_i_, rho_j1_, rho_j2_, x_, y_, theta_) ... - deriv(@(ej2)gradEk(rho_i_,rho_j1_,ej2,x_,y_,theta_), rho_j2_, eps_xy); - - Etot = Etot + E_k(rho_i, rho_j1, rho_j2, x,y,theta); - - Gtot = Gtot+ gradEk(rho_i, rho_j1, rho_j2, x,y,theta); - G2tot = G2tot+ d2Ek_dx2(rho_i, rho_j1, rho_j2, x,y,theta); - - di = d2Ek_dxdei(rho_i, rho_j1, rho_j2, x,y,theta); - dj1 = d2Ek_dxdej1(rho_i, rho_j1, rho_j2, x,y,theta); - dj2 = d2Ek_dxdej2(rho_i, rho_j1, rho_j2, x,y,theta); - - dgE_di(:,i) = dgE_di(:,i) + di; - dgE_dj(:,j1) = dgE_dj(:,j1) + dj1; - dgE_dj(:,j2) = dgE_dj(:,j2) + dj2; - - Mk = [eye(2) (rot(theta+pi/2)*p_i)] ; - MMtot = MMtot + Mk' * Mk; - - k=k+1; - end - - dA_dz = inv(G2tot) * [dgE_di dgE_dj]; - - %Etot - %Gtot - %G2tot - - - sigma = params.sigma; - % dgE_di - % dgE_dj - % dA_dz - - fprintf('icp_covariance: Using sigma: %f', sigma); - - R = sigma^2 * eye(params.laser_ref.nrays+params.laser_sens.nrays); - - res.sm_cov_censi = dA_dz * R * dA_dz'; - - s2 = Etot / (k-3); - res.sm_cov_bengtsson = 2 * s2 * inv(G2tot); - - - dA_dz1 = inv(G2tot) * [dgE_di ]; - R1 = sigma^2 * eye(params.laser_sens.nrays); - res.loc_cov_censi = dA_dz1 * R1 * dA_dz1'; - - res.sm_cov_bengtsson_improved = s2 * inv( MMtot ); - - fprintf('Bengtsson, improved:'); - res.sm_cov_bengtsson_improved - fprintf('Bengtsson, original:') - res.sm_cov_bengtsson - - %res diff --git a/misc/matlab/icp/icp_get_correspondences.m b/misc/matlab/icp/icp_get_correspondences.m deleted file mode 100644 index ae81b06..0000000 --- a/misc/matlab/icp/icp_get_correspondences.m +++ /dev/null @@ -1,70 +0,0 @@ - -function [P,valid,jindexes] = icp_get_correspondences(params,current_estimate) - debug = 0; - for i=1:params.laser_sens.nrays - p_i = params.laser_sens.points(:,i); - p_i_w = transform(p_i, current_estimate); - - [from, to] = icp_possible_interval(p_i_w, params.laser_ref,... - params.maxAngularCorrectionDeg, params.maxLinearCorrection); - - %% Find best correspondence - best_j = 0; best_dist = 0; - for j=from:to - % Find compatible interval in the other scan. - p_j = params.laser_ref.points(:,j); - - dist = norm( p_i_w - p_j); - if dist < params.maxCorrespondenceDist - if (best_j==0) || (dist < best_dist) - best_j = j; best_dist = dist; - end - end - end - - if (best_j == 0) || ... - (params.dont_consider_extrema && ... - ((best_j==1) || (best_j==params.laser_ref.nrays))) - P(:,i) = [nan;nan]; - valid(i) = 0; - jindexes(i,:)=[nan;nan]; - else - %% Find other point to interpolate - if best_j==1 - other_j = best_j + 1; - other = params.laser_ref.points(:,best_j+1); - elseif best_j == params.laser_ref.nrays - other_j = best_j - 1; - other = params.laser_ref.points(:,best_j-1); - else - p_prev = params.laser_ref.points(:,best_j-1); - p_next = params.laser_ref.points(:,best_j+1); - dist_prev = norm( p_prev-p_i_w); - dist_next = norm( p_next-p_i_w); - if dist_prev < dist_next - other_j = best_j -1; - other = p_prev; - else - other_j = best_j +1; - other = p_next; - end - end - - %% Find the point which is closest to segment. - interpolate = closest_point_on_segment(... - params.laser_ref.points(:,best_j),other, p_i_w); - - dist = norm(interpolate-p_i_w); - if dist < params.maxCorrespondenceDist - P(:,i) = interpolate; - valid(i) = 1; - jindexes(i,:) = [best_j;other_j]; - else - P(:,i) = [nan;nan]; - valid(i) = 0; - jindexes(i,:) = [nan;nan]; - end - end - - end % i in first scan - diff --git a/misc/matlab/icp/icp_possible_interval.m b/misc/matlab/icp/icp_possible_interval.m deleted file mode 100644 index 084758f..0000000 --- a/misc/matlab/icp/icp_possible_interval.m +++ /dev/null @@ -1,22 +0,0 @@ - -function [from, to] = icp_possible_interval(P, ld, maxAngularCorrectionDeg, maxLinearCorrection) - debug = 0; - - delta = abs(deg2rad(maxAngularCorrectionDeg)) + ... - abs(atan(maxLinearCorrection/norm(P))); - - n = ld.nrays; - fov = abs(ld.theta(n)-ld.theta(1)); - angleRes = fov/n; - start_theta = atan2(P(2),P(1)); - start_cell = ((start_theta - ld.theta(1)) / fov) * n; - range = ceil(delta/angleRes); - - from = min(n, max( floor(start_cell-range),1)); - to = max(1, min(ceil(start_cell+range),n)); - - if debug - fprintf('start_theta: %f delta: %f start_cell: %d from: %d to: %d\n',... - rad2deg(start_theta), rad2deg(delta), start_cell, from, to); - pause(0.001); - end diff --git a/misc/matlab/icp/test_icp_1.m b/misc/matlab/icp/test_icp_1.m deleted file mode 100644 index 6919b7d..0000000 --- a/misc/matlab/icp/test_icp_1.m +++ /dev/null @@ -1,5 +0,0 @@ - - step = [0.1;0;0] - params1 = ts_square([5], [0;0;0], step); - res = icp(params1); - diff --git a/misc/matlab/icpcov/derivn.m b/misc/matlab/icpcov/derivn.m deleted file mode 100644 index 9f37d19..0000000 --- a/misc/matlab/icpcov/derivn.m +++ /dev/null @@ -1,10 +0,0 @@ -%% Numerical derivation with step \verb|epsilon| -function res = deriv(fh, x, epsilon) - % deriv(fh, x, epsilon) - % fh: function handle - % x: point to derive - % epsilon: interval - f1 = fh(x+epsilon/2); - f0 = fh(x-epsilon/2); - res= (f1-f0)/epsilon; - diff --git a/misc/matlab/matlab_new/display/display_cov.m b/misc/matlab/matlab_new/display/display_cov.m deleted file mode 100644 index 3898395..0000000 --- a/misc/matlab/matlab_new/display/display_cov.m +++ /dev/null @@ -1,10 +0,0 @@ -function res = display_cov(cov) - - std_x = sqrt(cov(1,1)); - std_y = sqrt(cov(2,2)); - std_th = sqrt(cov(3,3)); - rho_xy = cov(1,2) / (std_x * std_y); - rho_xth = cov(1,3) / (std_x * std_th); - rho_yth = cov(2,3) / (std_y * std_th); - - res = [std_x, std_y, std_th, rho_xy, rho_xth, rho_yth]; \ No newline at end of file diff --git a/misc/matlab/matlab_new/ld_fisher0.m b/misc/matlab/matlab_new/ld_fisher0.m deleted file mode 100644 index 2d5e527..0000000 --- a/misc/matlab/matlab_new/ld_fisher0.m +++ /dev/null @@ -1,33 +0,0 @@ -function I0 = ld_fisher0(ld) -% This function computes Fisher's information matrix, in robot coordinates. -% Uses field 'true_alpha' (and 'theta', 'readings'). -% -% For details about the Fisher's information matrix for localization, -% please see this paper: http://purl.org/censi/2006/accuracy - -I0 = zeros(3,3); - -for i=1:ld.nrays - alpha_i = ld.true_alpha(i); - r = ld.readings(i); - - if isnan(alpha_i) | isnan(r) - continue; - end - - phi_i = ld.theta(i); - beta_i = alpha_i - (phi_i); - - % dr_dt = v(beta_i)' / cos(beta_i); - dr_dt = (v(phi_i) + v(phi_i+pi/2) * tan(beta_i))'; - dr_dt = v(alpha_i)' / cos(beta_i); - dr_dtheta = r * tan(beta_i); - - I0(1:2,1:2) = I0(1:2,1:2) + (dr_dt' * dr_dt); - I0(1:2,3) = I0(1:2,3) + (dr_dt' * dr_dtheta); - I0(3,1:2) = I0(3,1:2) + (dr_dt * dr_dtheta); - I0(3,3) = I0(3,3) + dr_dtheta * dr_dtheta; -end - -function res = v(a) - res = [cos(a); sin(a)]; diff --git a/misc/matlab/matlab_new/ld_fisher_ext.m b/misc/matlab/matlab_new/ld_fisher_ext.m deleted file mode 100644 index da9a9c8..0000000 --- a/misc/matlab/matlab_new/ld_fisher_ext.m +++ /dev/null @@ -1,48 +0,0 @@ -function I0 = ld_fisher_ext(ld, vars) -% This is an extension of function ld_fisher0 which takes into account -% different variances for each ray. It also does not count rays -% for which ld.valid(i) is set to 0. -% -% This function computes Fisher's information matrix, in robot coordinates. -% Uses field 'true_alpha' (and 'theta', 'readings'). -% If true_alpha is NAN, it tries to use alpha. -% -% For details about the Fisher's information matrix for localization, -% please see this paper: http://purl.org/censi/2006/accuracy - -I0 = zeros(3,3); - -nused = 0; -for i=1:ld.nrays - alpha_i = NaN; - if isfield(ld, 'true_alpha') - alpha_i = ld.true_alpha(i); - end - if isnan(alpha_i) - alpha_i = ld.alpha(i); - end - - r = ld.readings(i); - - if isnan(alpha_i) | isnan(r) | not(ld.valid(i)) - continue; - end - - phi_i = ld.theta(i); - beta_i = alpha_i - (phi_i); - - dr_dt = v(alpha_i)' / cos(beta_i); - dr_dtheta = r * tan(beta_i); - - mult = 1 / vars(i); - I0(1:2,1:2) = I0(1:2,1:2) + mult * (dr_dt' * dr_dt); - I0(1:2,3) = I0(1:2,3) + mult * (dr_dt' * dr_dtheta); - I0(3,1:2) = I0(3,1:2) + mult *(dr_dt * dr_dtheta); - I0(3,3) = I0(3,3) + mult * (dr_dtheta * dr_dtheta); - - nused = nused +1; -end -fprintf('FIM computed using %d rays.\n', nused); - -function res = v(a) - res = [cos(a); sin(a)]; diff --git a/misc/matlab/matlab_new/ld_fisher_ext2.m b/misc/matlab/matlab_new/ld_fisher_ext2.m deleted file mode 100644 index 42cae0f..0000000 --- a/misc/matlab/matlab_new/ld_fisher_ext2.m +++ /dev/null @@ -1,40 +0,0 @@ -function I0 = ld_fisher_ext(ld) -% This is an extension of function ld_fisher0 which does not use the -% (1/cos(beta)) factor. -% -% This function computes Fisher's information matrix, in robot coordinates. -% Uses field 'true_alpha' (and 'theta', 'readings'). -% -% For details about the Fisher's information matrix for localization, -% please see this paper: http://purl.org/censi/2006/accuracy - - -I0 = zeros(3,3); - -nused = 0; -for i=1:ld.nrays - alpha_i = ld.true_alpha(i); - r = ld.readings(i); - - if isnan(alpha_i) | isnan(r) | not(ld.valid(i)) - continue; - end - - phi_i = ld.theta(i); - beta_i = alpha_i - (phi_i); - - % do not use the 1/cos(beta) - dr_dt = v(alpha_i)'; - dr_dtheta = r * sin(beta_i); - - I0(1:2,1:2) = I0(1:2,1:2) + (dr_dt' * dr_dt); - I0(1:2,3) = I0(1:2,3) + (dr_dt' * dr_dtheta); - I0(3,1:2) = I0(3,1:2) + (dr_dt * dr_dtheta); - I0(3,3) = I0(3,3) + (dr_dtheta * dr_dtheta); - - nused = nused +1; -end -fprintf('FIM computed using %d rays.\n', nused); - -function res = v(a) - res = [cos(a); sin(a)]; diff --git a/misc/matlab/matlab_new/structs/collect.m b/misc/matlab/matlab_new/structs/collect.m deleted file mode 100644 index 2801b9f..0000000 --- a/misc/matlab/matlab_new/structs/collect.m +++ /dev/null @@ -1,12 +0,0 @@ -function res = collect(cells, field) - res = {}; - k = 1; - for i=1:size(cells,2) - s = cells{i}; - if isfield(s, field) - res{k} = s.(field); - else - ref{k} = nan; - end - k = k + 1; - end \ No newline at end of file diff --git a/misc/matlab/matlab_new/structs/join.m b/misc/matlab/matlab_new/structs/join.m deleted file mode 100644 index a551ebb..0000000 --- a/misc/matlab/matlab_new/structs/join.m +++ /dev/null @@ -1,13 +0,0 @@ -function res = join(cells) - columns = size(cells,2); - rows = size(cells{1},1); - res = zeros(rows, columns); - for j=1:columns - if size(cells{j},1) > 0 - res(1:rows,j) = cells{j}; - else - fprintf('No value for cell %d\n', j); - pause(0.01); - res(1:rows,j) = zeros(rows,1) * NaN; - end - end diff --git a/misc/matlab/mbicp/MbICP.m b/misc/matlab/mbicp/MbICP.m deleted file mode 100644 index 93206c6..0000000 --- a/misc/matlab/mbicp/MbICP.m +++ /dev/null @@ -1,271 +0,0 @@ -% Test implementation of Minguez et al Metric Based ICP -% by Patric Jensfelt, 2006-03-28 -% -% refScan - 361 range readings from reference scan -% newScan - 361 range readings from reference scan -% initQ - initial estimate of transformation from ref to new scan -% -function transf = MbICP(refScan, newScan, initQ, interactive) - - global ang; - global cx; - global cy; - global assoc; - global n_assoc; - - % Parameters - global L; - global Max_Dist; - global Min_error; - - % Values of the parameters - L = 3.0; - Max_Dist = 1; - Min_error = 1e-4; - - nrays = length(refScan) - %ang = (0:0.5:180)*pi/180; - ang = (1:nrays)*(pi/nrays); - ang = (1:nrays)*(pi/nrays)-pi/2; - - if nargin < 3 - disp('Usgae: MbICP(refScan, newScan, initQ)'); - return - end - - if checkArgs(refScan, newScan, initQ) - return - end - - px = refScan .* cos(ang); - py = refScan .* sin(ang); - - % Define array to hold Cartesian coordinates for transformed new scan - cx = zeros(1,nrays); - cy = zeros(1,nrays); - - % The transformation from the reference scan to the new scan - q = initQ; - - for k = 1:500 - disp(sprintf('Iteration %d', k)) - - calcTransfNewScanPts(newScan, q); - clf, hold on - dispScan(px,py,'r') - dispScan(cx,cy,'b') - drawnow - - if interactive - disp('Get associations') - end - - n_assoc = 0; - getAssociations(px,py,cx,cy); - - if interactive - dispAssociations(px,py,cx,cy,assoc,n_assoc); - disp('Getting best transformation') - end - - q_min = getQmin(px,py,cx,cy,assoc, n_assoc) - - q = compound(q_min, q) - - if (max(abs(q_min)) < Min_error) - disp(sprintf('Converged in iteration %d', k)) - break - end - - if interactive - disp(sprintf('Press enter for iteration %d', k+1)) - pause - end - end - - dispAssociations(px,py,cx,cy,assoc,n_assoc); - disp('Final transformation:'); - q - - transf=q; - - return; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function err = checkArgs(refScan, newScan, initQ) - - err = 0 - - if length(refScan) < 10 - disp('Need at least 10 ranges for ref scan'); - err = 1; - return; - end - - if not(length(newScan) == length(refScan)) - disp('Need ref scan and new scan of same size'); - err = 1; - return; - end - - if length(initQ) < 3 - disp('Need 3 values for initial transformation'); - err = 1; - return; - end - - return; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function calcTransfNewScanPts(newScan, q) - global cx; - global cy; - global ang; - - R = [cos(q(3)) -sin(q(3)); sin(q(3)) cos(q(3))]; - xy = R * [newScan .* cos(ang); newScan .* sin(ang)]; - cx = xy(1,:) + q(1); - cy = xy(2,:) + q(2); - - return; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function dispScan(x,y,col) - plot(x,y,[col '.']) -return - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function getAssociations(px,py,cx,cy) - global assoc - global n_assoc - global Max_Dist - - for ic = 1:length(cx) - - minD2 = 1e10; - minIndex = -1; - - for ip = 1:length(px) - - d2 = getMbDistSqr(px(ip),py(ip),cx(ic),cy(ic)); - if d2 < minD2 - minD2 = d2; - minIndex = ip; - end - end - - % Add this association (not very clever to reallocate every time...) - if minD2 < Max_Dist, - n_assoc = n_assoc + 1; - assoc(n_assoc,1) = minIndex; - assoc(n_assoc,2) = ic; - end - - end - - return - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function d2 = getMbDistSqr(p2x, p2y, p1x, p1y) - global L; - - dx = p2x - p1x; - dy = p2y - p1y; - - tmp = dx * p1y - dy * p1x; - d2 = dx*dx + dy*dy - (tmp * tmp / (p1y*p1y + p1x*p1x + L*L)); - - return - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function dispAssociations(px,py,cx,cy,assoc, n_assoc) - - for k=1:n_assoc - plot([px(assoc(k,1)) cx(assoc(k,2))], [py(assoc(k,1)) cy(assoc(k,2))]) - end - - return - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function q_min = getQmin(px,py,cx,cy,assoc, n_assoc) - - global L; - - A = zeros(3,3); - b = zeros(3,1); - - for k = 1:n_assoc - pix = px(assoc(k,1)); - piy = py(assoc(k,1)); - cix = cx(assoc(k,2)); - ciy = cy(assoc(k,2)); - - ki = pix * pix + piy * piy + L * L; - - cxpxPcypy = cix * pix + ciy * piy; - cxpyMcypx = cix * piy - ciy * pix; - - A(1,1) = A(1,1) + 1.0 - piy * piy / ki; - A(1,2) = A(1,2) + pix * piy / ki; - A(1,3) = A(1,3) - ciy + piy / ki * cxpxPcypy; - A(2,2) = A(2,2) + 1.0 - pix * pix / ki; - A(2,3) = A(2,3) + cix - pix / ki * cxpxPcypy; - A(3,3) = A(3,3) + cix*cix + ciy*ciy - cxpxPcypy*cxpxPcypy / ki; - - b(1,1) = b(1,1) + cix - pix - piy / ki * cxpyMcypx; - b(2,1) = b(2,1) + ciy - piy + pix / ki * cxpyMcypx; - b(3,1) = b(3,1) + (cxpxPcypy / ki - 1.0) * cxpyMcypx; - end - - % Complete the A-matrix by assigning the symmetric portions of it - A(2,1) = A(1,2); - A(3,1) = A(1,3); - A(3,2) = A(2,3); - - q_min = - inv(A) * b; - - - return - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function t_ret = compound(t1, t2) - - t_ret = zeros(3,1); - - t_ret(1) = t2(1) * cos(t1(3)) - t2(2) * sin(t1(3)) + t1(1); - t_ret(2) = t2(1) * sin(t1(3)) + t2(2) * cos(t1(3)) + t1(2); - t_ret(3) = t1(3) + t2(3); - - % Make angle [-pi,pi) - while (t_ret(3) >= pi) - t_ret(3) = t_ret(3) - 2*pi; - end - while (t_ret(3) < -pi) - t_ret(3) = t_ret(3) + 2*pi; - end - - return; - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -function t_ret = inv_compound(t) - - t_ret = zeros(3,1); - - t_ret(1) = -t(1) * cos(t(3)) - t(2) * sin(t(3)); - t_ret(2) = t(1) * sin(t(3)) - t(3) * cos(t(3)); - t_ret(3) = -t(3); - - return - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - diff --git a/misc/matlab/mbicp/datos.off b/misc/matlab/mbicp/datos.off deleted file mode 100644 index df1164d..0000000 --- a/misc/matlab/mbicp/datos.off +++ /dev/null @@ -1,3 +0,0 @@ -6.247 6.239 6.255 6.249 6.256 6.261 6.265 6.269 6.279 6.284 6.285 6.298 6.296 6.302 6.302 6.313 6.339 5.976 5.926 5.896 5.891 5.888 5.902 5.937 6.061 6.27 6.262 6.281 6.301 6.311 5.305 4.809 4.585 4.41 4.278 4.155 4.055 3.967 3.882 3.801 3.733 3.672 3.61 3.55 3.499 3.45 3.41 3.358 3.313 3.284 3.25 3.211 3.182 3.14 3.115 3.081 3.053 3.02 2.997 3.013 3.041 3.07 4.434 4.31 4.253 4.205 4.177 4.128 4.078 4.032 3.977 3.931 3.893 3.865 3.869 3.9 3.922 3.964 3.988 4.025 4.051 4.1 4.129 4.189 4.171 4.207 4.241 4.491 4.472 4.441 2.175 2.155 2.135 2.125 2.107 2.088 2.068 2.059 2.039 2.029 2.01 2 1.991 1.981 1.961 1.951 1.941 1.921 1.911 1.902 1.892 1.882 1.873 1.862 1.852 1.841 1.755 1.744 1.734 1.725 1.725 1.715 1.705 1.695 1.695 1.686 1.676 1.676 1.665 1.655 1.645 1.645 1.635 1.635 1.625 1.617 1.617 1.607 1.608 1.598 1.598 1.587 1.6 1.654 1.695 1.687 1.68 1.68 1.679 1.669 1.672 1.662 1.663 1.663 1.655 1.656 1.657 1.647 1.649 1.648 1.639 1.639 1.64 1.639 1.64 1.64 1.64 1.63 1.631 1.631 1.632 1.622 1.632 1.622 1.622 1.621 1.573 1.572 1.573 1.582 1.573 1.574 1.583 1.574 1.575 1.575 1.585 1.585 1.585 1.584 1.584 1.584 1.594 1.594 1.594 1.594 1.604 1.593 1.604 1.603 1.613 1.613 1.613 1.623 1.622 1.622 1.631 1.635 1.636 1.585 1.581 1.595 1.598 1.607 1.605 1.614 1.613 1.624 1.623 1.631 1.631 1.641 1.64 1.648 1.657 1.654 1.667 1.677 1.675 1.685 1.687 1.7 1.712 1.716 1.731 1.729 1.742 1.752 1.765 1.777 1.787 1.797 1.798 1.814 1.813 1.823 1.837 1.843 1.862 1.863 1.865 1.893 1.906 1.926 1.938 1.947 1.967 1.976 1.986 2.005 2.024 2.035 2.053 2.063 2.081 2.101 2.12 2.128 2.148 2.167 2.186 2.215 2.234 2.244 2.274 2.294 2.313 2.335 2.356 2.384 2.404 2.434 2.462 2.491 2.52 2.539 2.577 2.617 2.647 2.687 2.719 2.759 2.787 2.837 2.876 2.913 2.96 3.017 3.065 3.121 3.169 3.164 3.144 3.163 3.323 3.438 3.497 3.562 3.624 3.694 3.764 3.852 3.908 4.084 3.96 4.028 4.931 4.913 4.895 4.874 4.868 4.863 4.868 4.864 5.277 5.435 5.613 5.804 5.987 6.171 6.424 6.647 6.883 7.766 7.757 7.789 8.148 8.188 4.804 5.022 5.289 5.603 5.965 6.374 6.805 7.349 7.991 8.188 8.188 8.188 8.188 8.188 8.191 8.191 8.188 8.191 8.188 2.835 2.396 2.316 1.987 -6.241 6.235 6.253 8.191 8.191 8.191 8.191 8.191 8.191 8.191 8.191 8.191 8.191 6.351 8.191 6.291 6.293 6.296 5.97 5.906 5.873 5.859 5.852 5.857 5.887 5.926 6.295 6.226 6.24 6.25 6.269 5.259 4.759 4.516 4.32 4.2 4.065 3.968 3.871 3.792 3.713 3.64 3.57 3.509 3.458 3.408 3.351 3.312 3.272 3.228 3.191 3.15 3.111 3.081 3.052 3.014 2.989 2.963 2.941 2.967 2.984 3.016 4.431 4.373 4.243 4.192 4.141 4.116 4.053 4.005 3.953 3.908 3.861 3.813 3.789 3.799 3.83 3.848 3.887 3.904 3.933 3.972 4.005 4.046 4.103 4.13 4.117 4.147 4.208 2.141 2.066 2.057 2.037 2.017 1.998 1.989 1.968 1.959 1.939 1.929 1.919 1.899 1.889 1.869 1.858 1.839 1.839 1.818 1.807 1.798 1.788 1.777 1.767 1.757 1.746 1.68 1.658 1.649 1.64 1.629 1.619 1.609 1.599 1.6 1.589 1.58 1.57 1.56 1.56 1.551 1.541 1.541 1.531 1.531 1.521 1.512 1.512 1.503 1.502 1.494 1.484 1.482 1.482 1.472 1.547 1.557 1.574 1.563 1.552 1.552 1.543 1.544 1.544 1.532 1.533 1.526 1.527 1.528 1.53 1.524 1.524 1.515 1.515 1.519 1.515 1.508 1.507 1.507 1.508 1.508 1.509 1.5 1.509 1.502 1.51 1.5 1.498 1.5 1.497 1.467 1.459 1.459 1.451 1.462 1.452 1.461 1.461 1.463 1.462 1.463 1.462 1.463 1.461 1.461 1.469 1.461 1.468 1.468 1.467 1.468 1.477 1.478 1.475 1.478 1.484 1.485 1.484 1.493 1.491 1.491 1.5 1.5 1.498 1.508 1.498 1.462 1.462 1.463 1.465 1.465 1.475 1.485 1.484 1.485 1.494 1.505 1.504 1.514 1.524 1.524 1.533 1.533 1.543 1.553 1.562 1.572 1.572 1.582 1.592 1.592 1.603 1.613 1.612 1.623 1.633 1.644 1.654 1.653 1.675 1.675 1.684 1.694 1.705 1.724 1.735 1.744 1.755 1.764 1.783 1.798 1.822 1.824 1.836 1.856 1.866 1.876 1.896 1.905 1.925 1.935 1.964 1.974 1.993 2.002 2.032 2.041 2.06 2.079 2.099 2.126 2.144 2.163 2.182 2.2 2.23 2.249 2.279 2.299 2.332 2.352 2.381 2.409 2.439 2.469 2.513 2.533 2.573 2.614 2.664 2.695 2.735 2.774 2.833 2.871 2.918 2.965 3.032 3.08 3.134 3.093 3.08 3.134 3.36 3.43 3.503 3.549 3.642 3.71 3.814 3.856 4.031 3.914 4.026 4.876 4.866 4.847 4.839 4.821 4.838 4.83 5.182 5.053 5.565 5.752 5.989 6.136 6.453 6.674 7.46 7.743 7.703 7.953 8.188 8.188 8.188 4.81 5.209 5.514 5.955 6.388 7.02 7.631 8.188 8.188 8.188 8.188 8.188 8.191 8.188 8.191 8.191 - diff --git a/misc/matlab/mbicp/testMbICP.m b/misc/matlab/mbicp/testMbICP.m deleted file mode 100644 index c809188..0000000 --- a/misc/matlab/mbicp/testMbICP.m +++ /dev/null @@ -1,18 +0,0 @@ -clear all -close all -disp('hola') - -load datos.off -ascii - -% ---------- -% Try same scans -%scanRef=datos(1,:); -%scanNew=datos(1,:); - -% ---------- -% Try different scans -scanRef=datos(1,:); -scanNew=datos(2,:); - -transf = MbICP(scanRef, scanNew, [0.3,0.3,0.7], false) - diff --git a/misc/matlab/msm/ld_alloc.m b/misc/matlab/msm/ld_alloc.m deleted file mode 100644 index 791e4b4..0000000 --- a/misc/matlab/msm/ld_alloc.m +++ /dev/null @@ -1,45 +0,0 @@ -function ld = ld_alloc(min_max_theta, readings) - % Fills default fields of a LaserData struct - ld.nrays = size(readings, 1); - - - ld.min_theta = min_max_theta(1); - ld.max_theta = min_max_theta(2); - for i=1:ld.nrays - ld.theta(i,1) = ld.min_theta + (i-1) / (ld.nrays-1) * (ld.max_theta-ld.min_theta); - end - - for i=1:ld.nrays - if isnan(readings(i)) || (readings(i)==0) - ld.valid(i,1) = uint8(0); - ld.readings(i,1) = nan; - else - ld.valid(i,1) = uint8(1); - ld.readings(i,1) = readings(i); - end - end - - ld.odometry = [nan; nan; nan]; - ld.estimate = [nan; nan; nan]; - -% @nrays = nrays -% @valid = [false ] * nrays -% @readings = [GSL::NAN] * nrays -% @theta = [GSL::NAN] * nrays -% @alpha_valid = [false ] * nrays -% @alpha = [GSL::NAN] * nrays -% @cov_alpha = [GSL::NAN] * nrays -% @cluster = [-1] * nrays - -% @odometry = Vector[GSL::NAN,GSL::NAN,GSL::NAN].col -% @estimate = Vector[GSL::NAN,GSL::NAN,GSL::NAN].col -% @p = []; @corr = []; -% for i in 0..nrays-1 -% @p[i] = Vector[GSL::NAN,GSL::NAN].col -% @corr[i] = Correspondence.new; -% @corr[i].valid = false; -% @corr[i].j1 = -1; -% @corr[i].j2 = -1; -% end - -% \ No newline at end of file diff --git a/misc/matlab/msm/ld_clustering.m b/misc/matlab/msm/ld_clustering.m deleted file mode 100644 index 8b13789..0000000 --- a/misc/matlab/msm/ld_clustering.m +++ /dev/null @@ -1 +0,0 @@ - diff --git a/misc/matlab/msm/ld_to_json.m b/misc/matlab/msm/ld_to_json.m deleted file mode 100644 index 9859ad7..0000000 --- a/misc/matlab/msm/ld_to_json.m +++ /dev/null @@ -1,8 +0,0 @@ -function s = ld_to_json(ld, pretty) - - ld.nrays = uint16(ld.nrays); - ld.valid = uint16(ld.valid); - s = matlab_to_json(ld, pretty); - - - diff --git a/misc/matlab/msm/matlab_to_json.m b/misc/matlab/msm/matlab_to_json.m deleted file mode 100644 index 3a8ae9a..0000000 --- a/misc/matlab/msm/matlab_to_json.m +++ /dev/null @@ -1,61 +0,0 @@ -function s = matlab_to_json(ob, pretty) - s = '!'; - - if isnumeric(ob) - if (size(ob,1) == 1) && (size(ob,2) == 1) - if isnan(ob) - s = 'null'; - else - if isinteger(ob) - s = sprintf('%d', ob); - else - s = sprintf('%f', ob); - end - end - else - % XXXXXXX non funziona se row=1 col>1 - % array - s = '['; - rows = size(ob, 1); - for row=1:rows - v = ob(row,:); - s = strcat(s, matlab_to_json(v) ); - if row < rows - s = strcat(s, ', '); - end - - if (rows>1) && (size(ob,2) >1) && pretty - s = strcat(s, '\n'); - end - - end - s = strcat(s, ']'); - end - return; - end - - if isstruct(ob) - s = '{ '; - names = fieldnames(ob); - for i=1:size(names,1) - key = names{i}; - value = matlab_to_json( getfield(ob, key) ); - s = strcat(s, '"', key, '": ', value); - if i < size(names, 1) - s = strcat(s, ', '); - - if pretty - s = strcat(s, '\n'); - end - end - end - s = strcat(s, '}'); - return; - end - - s = '?'; - - - - - diff --git a/misc/matlab/octave_compat/deg2rad.m b/misc/matlab/octave_compat/deg2rad.m deleted file mode 100644 index e71b279..0000000 --- a/misc/matlab/octave_compat/deg2rad.m +++ /dev/null @@ -1,2 +0,0 @@ -function r = deg2rad(d) - r = pi * d / 180; diff --git a/misc/matlab/orientation/arras_fit.m b/misc/matlab/orientation/arras_fit.m deleted file mode 100644 index 05307fe..0000000 --- a/misc/matlab/orientation/arras_fit.m +++ /dev/null @@ -1,35 +0,0 @@ -function [alpha,alpha_var] = arras_fit( thetas , rhos , var) - - n = size(thetas,2); - - xw=0; yw=0; - - for i=1:n - w(i) = 1/var; - end - - - for i=1:n - - end - - x = rhos .* cos(thetas); - y = rhos .* sin(thetas); - - xw = sum( w.*x) / sum(w); - yw = sum( w.*y) / sum(w); - - num = -2 * sum((yw-y).*(xw-x).*w); - den = sum( w.* ( (yw-y).^2 -(xw-x).^2 ) ); - - alpha = 0.5 * atan(num/den); - r = xw * cos(alpha)+yw*sin(alpha); - - if r<0 - alpha = alpha- pi; - end - - - alpha_var = 1; - - diff --git a/misc/matlab/orientation/computeSurfaceNormals.m b/misc/matlab/orientation/computeSurfaceNormals.m deleted file mode 100644 index 57d18c6..0000000 --- a/misc/matlab/orientation/computeSurfaceNormals.m +++ /dev/null @@ -1,59 +0,0 @@ -function ld = computeSurfaceNormals(ld, maxDist) - -n = size(ld.points,2); - -for i=1:n - - % consider all points in a ball of radius maxDist - imin=i; stop=0; - while stop == 0 & imin>1 - if norm(ld.points(:,i)-ld.points(:,imin-1)) < maxDist - imin = imin -1; - else - stop=1; - end - end - - imax=i; stop=0; - while stop==0 & imax<n - if norm(ld.points(:,i)-ld.points(:,imax+1)) < maxDist - imax=imax+1; - else - stop = 1; - end - end - - num=imax-imin+1; - - if num>1 - %[theta; rho; error] - [alpha,rho,error] = regression(ld.points(:,imin:imax)); - - ld.alpha(i) = normalize(alpha); - ld.alpha_valid(i) = 1; - ld.alpha_error(i) = sqrt(error/num); - - if num==2 - ld.alpha_error(i) = 0.1; - end - - %fprintf('n = %d alpha %3.3f rho %5.5f error %f\n', ... - %imax-imin+1, alpha,rho,ld.alpha_error(i)); - else - fprintf('ops! %d\n',i); - ld.alpha(i) = nan; - ld.alpha_valid(i) = 0; - ld.alpha_error(i) = nan; - end - -end - -function res = normalize(alpha) - while alpha > 2*pi - alpha = alpha - 2*pi; - end - while alpha < 0 - alpha = alpha + 2*pi; - end - res = alpha; - diff --git a/misc/matlab/orientation/computeSurfaceNormals_sound.m b/misc/matlab/orientation/computeSurfaceNormals_sound.m deleted file mode 100644 index c5872b2..0000000 --- a/misc/matlab/orientation/computeSurfaceNormals_sound.m +++ /dev/null @@ -1,114 +0,0 @@ -% params.sigma -% params.curv -% params.max_points -% params.threshold -% params.min_dist - -function ld = computeSurfaceNormals_sound(ld) - - params.max_points=10; - params.threshold=2; - params.min_dist = 0.24; - params.curv = 0; - params.sigma = 0.01; - -curv = params.curv; -var = params.sigma ^ 2; -MAX = params.max_points; -MIN_DIST = params.min_dist; -THRESHOLD = params.threshold; - -n = size(ld.points,2); - -for i=1:n - - - if i==1 - min_dist = norm(ld.points(:,i)-ld.points(:,i+1)); - else - if i==n - min_dist = norm(ld.points(:,i)-ld.points(:,i-1)); - else - min_dist = min( norm(ld.points(:,i)-ld.points(:,i-1)), ... - norm(ld.points(:,i)-ld.points(:,i+1))); - end - end - - min_dist = max(min_dist,MIN_DIST); - - imax=i; - % vediamo quanto allungare - for j=min(i+1,n):min(i+MAX,n) - d = norm( ld.points(:,j)- ld.points(:,j-1) ); - if d > THRESHOLD * min_dist - break; - end - imax = j; - end - - imin=i; - for j=max(1,i-1):-1:max(1,i-MAX) - d = norm( ld.points(:,j)- ld.points(:,j+1) ); - if d > THRESHOLD * min_dist - break; - end - imin=j; - end - -% imin = max(1, i-3); -% imax = min(n, i+3); - - ni=imax-imin+1; - - if ni>2 - indexes=[imin:i-1 i+1:imax]; - - t = ld.theta(indexes); - f = ld.readings(indexes); - fvar = ones(1,ni) * var; - fd_guess = zeros(1,ni); - - t0 = ld.theta(i); - f0 = ld.readings(i); - fvar0 = var; - fd_guess0 = 0; - - curvf = 0; - - [fd0,fd0_var] = estimate_derivative_single( ... - t,f,fvar,fd_guess, ... - t0,f0,fvar0,fd_guess0,curvf); - - alpha = t0 - atan(fd0/f0); - curvf = curv *(abs(f0 * tan(t0-alpha))^2); - - [fd0,fd0_var] = estimate_derivative_single( ... - t,f,fvar,fd_guess, ... - t0,f0,fvar0,fd_guess0,curvf); - - - theta = t0; - - %q = fd0 / f0; - %alpha = atan( (cos(theta)+q*sin(theta)) / (-sin(theta)+q*cos(theta)) ); - - alpha = theta - atan(fd0/f0); - alpha_var = fd0_var * (( f0 / (f0.^2 + fd0.^2) ).^2) ... - + var * (( fd0 / (f0.^2 + fd0.^2) ).^2) ; - - ld.alpha(i) = alpha-pi; % rivolta verso dentro - ld.alpha_valid(i) = 1; - ld.alpha_error(i) = alpha_var; - - - indexes=[imin:imax]; - [ld.ar_alpha(i), ld.ar_alpha_error(i)] = ... - arras_fit( ld.theta(indexes), ld.readings(indexes), var); - else - ld.alpha(i) = nan; - ld.alpha_valid(i) = 0; - ld.alpha_error(i) = nan; - end - -end - diff --git a/misc/matlab/orientation/estimate_derivative.m b/misc/matlab/orientation/estimate_derivative.m deleted file mode 100644 index 1f5d147..0000000 --- a/misc/matlab/orientation/estimate_derivative.m +++ /dev/null @@ -1,66 +0,0 @@ -function [f1_guess, f1_var] = estimate_derivative(t, f0, f0cov, curv, f1guess, interval) - -left=interval; right=interval; - -N = size(f0,2); -% for each point -for k=1:N - start = max(k-left,1); - stop = min(k+right,N); - - % number of observations - n = stop-start+1 -1; - % 2*n+1 noises - R = zeros(n,2*n+1); - Z = zeros(2*n+1,2*n+1); - Y = zeros(n,1); - L = zeros(n,1); - - index=1; - for i=start:1:stop - if i==k - continue - end - - d = t(k)-t(i); - - % stima derivata seconda - f2 = (f1guess(k)-f1guess(i)) / d; - Y(index, 1) = (f0(k)-f0(i)) / d + d.^2 * f2 / 2; - L(index, 1) = 1; - - % rumore con i-esimo - R(index, index) = 1 / d; - Z(index, index) = f0cov(i); - % rumore con me - R(index, 2*n +1 ) = 1 / d; - % rumore con curvatura - R(index, index+n) = d.^2 / 2; - Z(index+n, index+n) = curv; - index = index +1; - end - - Z(2*n+1,2*n+1) = f0cov(k); - - % rumore - qR = R*Z*R'; - iR = inv(qR); - - f1_guess(k) = inv(L' * iR * L) * L' * iR * Y; - f1_var(k) = inv(L' * iR * L); - - if k == 2 - n - L - Z - Y - R - qR - f1_var(k) - f1_guess(k) - iR - f0(start:stop) - end -end - - diff --git a/misc/matlab/orientation/estimate_derivative_single.m b/misc/matlab/orientation/estimate_derivative_single.m deleted file mode 100644 index 1e7d9eb..0000000 --- a/misc/matlab/orientation/estimate_derivative_single.m +++ /dev/null @@ -1,37 +0,0 @@ -function [fd0,fd0_var] = estimate_derivative_single(t,f,fvar,fd_guess, t0,f0,fvar0,fd_guess0,curv) - % number of observations - n = size(t,2); - % 2*n+1 noises - R = zeros(n,2*n+1); - Z = zeros(2*n+1,2*n+1); - Y = zeros(n,1); - L = zeros(n,1); - - for i=1:n - - d = t0-t(i); - - % stima derivata seconda - f2 = (fd_guess0-fd_guess(i)) / d; - Y(i, 1) = (f0-f(i)) / d + d.^2 * f2 / 2; - L(i, 1) = 1; - - % rumore con i-esimo - R(i, i) = 1 / d; - Z(i, i) = fvar(i); - % rumore con me - R(i, 2*n +1 ) = 1 / d; - % rumore con curvatura - R(i, i+n) = d.^2 / 2; - Z(i+n, i+n) = curv; - end - - Z(2*n+1,2*n+1) = fvar0; - - % rumore - qR = R*Z*R'; - iR = inv(qR); - - fd0 = inv(L' * iR * L) * L' * iR * Y; - fd0_var = inv(L' * iR * L); - diff --git a/misc/matlab/orientation/ld_compute_orientation.m b/misc/matlab/orientation/ld_compute_orientation.m deleted file mode 100644 index dba7628..0000000 --- a/misc/matlab/orientation/ld_compute_orientation.m +++ /dev/null @@ -1,131 +0,0 @@ -% params.sigma -% params.curv -% params.max_points -% params.threshold -% params.min_dist - -function ld = ld_compute_orientation(ld) - - params.max_points=10; - params.threshold=2; - params.min_dist = 0.24; - params.curv = 0; - params.sigma = 0.01; - -curv = params.curv; -var = params.sigma ^ 2; -MAX = params.max_points; -MIN_DIST = params.min_dist; -THRESHOLD = params.threshold; - -ld.points = [ cos(ld.theta') .* ld.readings'; sin(ld.theta').* ld.readings']; -n = size(ld.points,2); - -for i=1:n - if ld.valid(i) == 0 - ld.alpha(i) = nan; - ld.alpha_valid(i) = 0; - ld.alpha_error(i) = nan; - continue; - end - - if i==1 - min_dist = norm(ld.points(:,i)-ld.points(:,i+1)); - else - if i==n - min_dist = norm(ld.points(:,i)-ld.points(:,i-1)); - else - min_dist = min( norm(ld.points(:,i)-ld.points(:,i-1)), ... - norm(ld.points(:,i)-ld.points(:,i+1))); - end - end - - min_dist = max(min_dist,MIN_DIST); - - imax=i; - % vediamo quanto allungare - for j=min(i+1,n):min(i+MAX,n) - d = norm( ld.points(:,j)- ld.points(:,j-1) ); - if d > THRESHOLD * min_dist - break; - end - imax = j; - end - - imin=i; - for j=max(1,i-1):-1:max(1,i-MAX) - - d = norm( ld.points(:,j)- ld.points(:,j+1) ); - if d > THRESHOLD * min_dist - break; - end - imin=j; - end - - - ni=imax-imin+1; - - if ni>2 - indexes=[imin:i-1 i+1:imax]; - - t = ld.theta(indexes); - f = ld.readings(indexes); - fvar = ones(1,ni) * var; - fd_guess = zeros(1,ni); - - t0 = ld.theta(i); - f0 = ld.readings(i); - fvar0 = var; - fd_guess0 = 0; - - curvf = 0; - - [fd0,fd0_var] = estimate_derivative_single( ... - t,f,fvar,fd_guess, ... - t0,f0,fvar0,fd_guess0,curvf); - - alpha = t0 - atan(fd0/f0); - curvf = curv *(abs(f0 * tan(t0-alpha))^2); - - [fd0,fd0_var] = estimate_derivative_single( ... - t,f,fvar,fd_guess, ... - t0,f0,fvar0,fd_guess0,curvf); - - - theta = t0; - - %q = fd0 / f0; - %alpha = atan( (cos(theta)+q*sin(theta)) / (-sin(theta)+q*cos(theta)) ); - - alpha = theta - atan(fd0/f0); - alpha_var = fd0_var * (( f0 / (f0.^2 + fd0.^2) ).^2) ... - + var * (( fd0 / (f0.^2 + fd0.^2) ).^2) ; - - if isnan(alpha) - fprintf('bug here... \n') - pause - end - - ld.alpha(i) = alpha-pi; % rivolta verso dentro - ld.alpha_valid(i) = 1; - ld.alpha_error(i) = alpha_var; - - - indexes=[imin:imax]; - [ld.ar_alpha(i), ld.ar_alpha_error(i)] = ... - arras_fit( ld.theta(indexes), ld.readings(indexes), var); - else - ld.alpha(i) = nan; - ld.alpha_valid(i) = 0; - ld.alpha_error(i) = nan; - end - -end - -ld.alpha = ld.alpha'; -ld.alpha_valid = ld.alpha_valid'; -ld.alpha_error = ld.alpha_error'; -ld.ar_alpha = ld.ar_alpha'; -ld.ar_alpha_error = ld.ar_alpha_error'; - - diff --git a/misc/matlab/orientation/ld_quality_of_orientation.m b/misc/matlab/orientation/ld_quality_of_orientation.m deleted file mode 100644 index 57ecf2e..0000000 --- a/misc/matlab/orientation/ld_quality_of_orientation.m +++ /dev/null @@ -1,20 +0,0 @@ -function ld_quality_of_orientation(ld) - - e = rad2deg(normAngle(ld.alpha-ld.true_alpha)); - - for i=1:size(e,2) - if abs(e(1)) > 10 - e(i) = 0; - end - end - - fprintf('Bias: %f deg \n', mean(e)); - fprintf('Deviation: %f deg \n', sqrt(var(e))); - - - fprintf('Mean error: %f deg \n', rad2deg(sqrt(max(ld.alpha_error)))); - - - figure - plot(e,'r.') - title('errors (degree)'); diff --git a/misc/matlab/orientation/regression.m b/misc/matlab/orientation/regression.m deleted file mode 100644 index 0ada1a7..0000000 --- a/misc/matlab/orientation/regression.m +++ /dev/null @@ -1,35 +0,0 @@ - -function [theta, rho, sumOfSqError] = regression(points) - - n = size(points,2); - if n<2 - error('I need at least 2 points'); - end - - mu = mean(points,2); - - s_x2 = 0; - s_y2 = 0; - s_xy = 0; - - for i=1:n - s_x2 = s_x2 + (points(1,i)-mu(1))*(points(1,i)-mu(1)); - s_y2 = s_y2 + (points(2,i)-mu(2))*(points(2,i)-mu(2)); - s_xy = s_xy + (points(1,i)-mu(1))*(points(2,i)-mu(2)); - end - - theta = 0.5 * atan2(-2*s_xy, s_y2-s_x2); - rho = mu(1) * cos(theta) + mu(2) * sin(theta); - - if rho>0 - rho = - rho; - theta = theta + pi; - end - - % compute error - sumOfSqError = 0; - for i=1:n - % distance to line - dist = rho - (cos(theta) * points(1,i) + sin(theta) * points(2,i)); - sumOfSqError = sumOfSqError + dist*dist; - end diff --git a/misc/matlab/orientation/test_deriv.m b/misc/matlab/orientation/test_deriv.m deleted file mode 100644 index d16a699..0000000 --- a/misc/matlab/orientation/test_deriv.m +++ /dev/null @@ -1,96 +0,0 @@ -function test_deriv - -% punti casuali -pt=[-1 -0.3 0 0.1 0.3 1]; -rand('seed',8); -st=cos(15.32*pt); -%rand(1, size(pt,2))*4; - -% polinomio casuale -P = polyfit(pt,st, min(3,size(pt,2)-1) ); -Pd = polyder(P); -Pdd = polyder(Pd); - -t=-1:0.01:1; -f0=polyval(P,t); -fd=polyval(Pd,t); -f2=polyval(Pdd,t); - -if true - vu = 7; - - f0 = sin(vu*t) + 0 * sin(vu*10*t)*0.1; - fd = vu * cos(vu*t)+ 0 * cos(vu*10*t); - f2 = - vu * vu * sin(vu*t); -end - -if false - W = 100; - [f0,fd,f2] = randf2(t, W); -end -if false - f0 = zeros(1,size(t,2)); - fd = zeros(1,size(t,2)); - f2 = zeros(1,size(t,2)); -end - -if false - f0 = t; % zeros(1,size(t,2)); - fd = 1 * ones(1,size(t,2)); - f2 = zeros(1,size(t,2)); -end - -curv= sum(f2.*f2) / size(f2,2); - -curv=0; -sigma=0.1; -randn('seed',4); -y= f0 + sigma*randn(1,size(t,2)); - -f0cov = ones(1,size(t,2)) * sigma*sigma; -myf1guess = zeros(1,size(t,2)); -interval = 4; -[est_fd, est_var] = estimate_derivative(t, y, f0cov, curv, myf1guess, interval); -[est_fd2, est_var2] = estimate_derivative(t, y, f0cov, curv, est_fd, interval); - - -% percentuale entro 95% -white = (est_fd-fd) ./ sqrt(est_var); - -fprintf('Curv: %f\n',curv); - -for p=1:3 - perc = sum( abs(white) < p ) / size(white,2); - fprintf('Perc: %d %f\n',p,perc); -end - - -fprintf('mean sigma= %f \n',mean(sqrt(est_var))); - -% errore - -fprintf('errore quadr. medio 1: %f \n', norm(est_fd-fd)); -fprintf('errore quadr. medio 2: %f \n', norm(est_fd2-fd)); - - -f=figure; -subplot(3,1,1); -hold on; -plot(t,f0,'r.'); -plot(t,y,'bd'); - -subplot(3,1,2); -hold on; -U = sqrt(est_var)*3; -%plot(t,est_fd,'kd'); -errorbar(t,est_fd,U,U,'k'); -plot(t,fd,'g.'); -%plot(t,est_fd2,'b.'); - -subplot(3,1,3); -plot(t, white); - -%plot(t,f2,'b.'); -hold off; - -%legend('poli', 'deriv', 'misure', 'stima deriv'); diff --git a/misc/matlab/orientation/test_est_deriv_log.m b/misc/matlab/orientation/test_est_deriv_log.m deleted file mode 100644 index 9ecebfd..0000000 --- a/misc/matlab/orientation/test_est_deriv_log.m +++ /dev/null @@ -1,84 +0,0 @@ -function sd = test_est_deriv_log(k) - -sigma=0.02; - -if true - S=load('logs/bighouse_half.mat'); - log = S.log_bighouse_half; - sd = log{k} - sd.readings = sd.readings + sigma * randn(1,sd.nrays); - sd.points = [sd.readings .* cos(sd.theta); sd.readings .* sin(sd.theta)]; -end - - - -%sd = straight(150, pi*0.5, 5, sigma); -sd = circ(150, pi*0.9, 5, sigma); - - -var = sigma^2; -curv = 10; -maxDist = 0.15; - - -sd = computeSurfaceNormals_sound(sd, var, curv, maxDist); - -f = figure; -params.plotNormals = true; -plotLaserData(sd,params); -axis('equal'); - -f = figure; -subplot(3,1,1); -hold on -U = 3*rad2deg(sqrt(sd.alpha_error)); -errorbar(rad2deg(sd.theta),rad2deg(sd.alpha),U,U,'k.'); -plot(rad2deg(sd.theta),rad2deg(sd.ar_alpha),'g.'); - -subplot(3,1,2); - -plot(rad2deg(sd.theta),U/3); - -subplot(3,1,3); - -plot(rad2deg(sd.theta),rad2deg(sd.alpha-sd.true_alpha)./U); - -indexes=10:140; -writeStats(sd.alpha(indexes),sd.true_alpha(indexes),sd.alpha_error(indexes)); - -function writeStats(x,tr,var) - % percentuale entro 95% - white = (x-tr) ./ sqrt(var); - for p=1:3 - perc = sum( abs(white) < p ) / size(white,2); - fprintf('Perc: %d %f\n',p,perc); - end - - - - - -function ld=straight(nrays,fov, dist, sigma) - - ld.nrays=nrays; - - for i=1:nrays - ld.theta(i) = -fov/2 + fov * i / nrays; - ld.readings(i) = dist / cos(ld.theta(i)); - ld.readings(i) = ld.readings(i) + sigma * randn(1,1); - ld.points(:,i) = [cos(ld.theta(i)) sin(ld.theta(i))]' * ld.readings(i); - ld.true_alpha(i) = 0; - end - -function ld=circ(nrays,fov, dist, sigma) - - ld.nrays=nrays; - - for i=1:nrays - ld.theta(i) = -fov/2 + fov * i / nrays; - ld.readings(i) = dist; - ld.readings(i) = ld.readings(i) + sigma * randn(1,1); - ld.points(:,i) = [cos(ld.theta(i)) sin(ld.theta(i))]' * ld.readings(i); - ld.true_alpha(i) = ld.theta(i); - end - diff --git a/misc/matlab/point-to-line/deg2rad.m b/misc/matlab/point-to-line/deg2rad.m deleted file mode 100644 index e71b279..0000000 --- a/misc/matlab/point-to-line/deg2rad.m +++ /dev/null @@ -1,2 +0,0 @@ -function r = deg2rad(d) - r = pi * d / 180; diff --git a/misc/matlab/point-to-line/general_minimization.m b/misc/matlab/point-to-line/general_minimization.m deleted file mode 100644 index eb947c2..0000000 --- a/misc/matlab/point-to-line/general_minimization.m +++ /dev/null @@ -1,88 +0,0 @@ - -function res = general_minimization(corr) - % Input is: - % corr{k}.C - % corr{k}.p - % corr{k}.q - - - %% First we put the problem in a quadratic+constraint form. - M = zeros(4,4); - g = zeros(4,1); - - for k=1:size(corr,2) - M_k = [eye(2) [corr{k}.p (rot(pi/2)*corr{k}.p)]]; - M = M + M_k'* corr{k}.C *M_k; - g = g + (- 2 * corr{k}.q' * corr{k}.C * M_k)'; - end - - W = [ zeros(2,2) zeros(2,2); zeros(2,2) eye(2)]; - - %% This is the function that we want to minimize - h = @(l) g' * inv(M+2*l*W) * W * inv(M+2*l*W)' * g - 1; - - %% Partition M in 4 submatrixes: - - M = 2*M; - % M = [A B; C D] - A = M(1:2,1:2) - B = M(1:2,3:4) - D = M(3:4,3:4) - - S = D - B' * inv(A) * B; - Sa = inv(S) * det(S); - - g1 = g(1:2); g2=g(3:4); - - p7 = [( g1'*(inv(A)*B* 4 *B'*inv(A))*g1 + 2*g1'*(-inv(A)*B* 4 )*g2 + g2'*( 4 )*g2) ... - ( g1'*(inv(A)*B* 4*Sa *B'*inv(A))*g1 + 2*g1'*(-inv(A)*B* 4*Sa)*g2 + g2'*( 4*Sa)*g2) ... - ( g1'*(inv(A)*B* Sa*Sa *B'*inv(A))*g1 + 2*g1'*(-inv(A)*B* Sa*Sa)*g2 + g2'*(Sa*Sa)*g2)]; - - p_lambda = [4 (2*S(1,1)+2*S(2,2)) (S(1,1)*S(2,2)-S(2,1)*S(1,2))]; - Ptot = polyadd(p7, -conv(p_lambda,p_lambda)) ; - - % Find largest real root of Ptot - r = roots(Ptot); - lambda = 0; - for i=1:4 - if isreal(r(i)) & (r(i)>0) - lambda = max(lambda, r(i)); - end - end - - x = -inv(M + 2 * lambda * W) * g; - theta = atan2(x(4),x(3)); - - - res.x = [x(1); x(2); theta] - - - - -% Q = @(l) (S+2*l*eye(2)) -% h2 = @(l) g' * [ inv(A)*B*inv(Q(l))*inv(Q(l))*B'*inv(A)' -inv(A)*B*inv(Q(l))*inv(Q(l)); ... -% (-inv(A)*B*inv(Q(l))*inv(Q(l)))' inv(Q(l))*inv(Q(l))] * g - 1; - - -% h8 = @(l) polyval(p7,l)- polyval(p_lambda,l)^2; - - %QQ = @(l) (Sa*Sa+4*(l^2)*eye(2)+4*l*Sa) / ( polyval(p_lambda,l)^2) - - - %h3 = @(l) g' * [ inv(A)*B*QQ(l)*B'*inv(A)' -inv(A)*B*QQ(l); ... - % (-inv(A)*B*QQ(l))' QQ(l)] * g - 1; - -% h4 = @(l) g1'* inv(A)*B*QQ(l)*B'*inv(A)'*g1 + g1'*-inv(A)*B*QQ(l)*g2 + ... -% g2' * (-inv(A)*B*QQ(l))'*g1 +g2'*QQ(l)*g2 - 1; - -% h5 = @(l) g1'* inv(A)*B*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa)*B'*inv(A)'*g1 + g1'*-inv(A)*B*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa)*g2 + ... -% g2' * (-inv(A)*B*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa))'*g1 +g2'*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa)*g2 - polyval(p_lambda,l)^2; - -% h6 = @(l) g1'* inv(A)*B*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa)*B'*inv(A)*g1 ... -% + 2*g1'*-inv(A)*B*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa)*g2 + ... -% +g2'*(Sa*Sa+4*(l^2)*eye(2)+4*l*Sa)*g2 - polyval(p_lambda,l)^2; - -% h7 = @(l) (l^2) * ( g1'*(inv(A)*B* 4 *B'*inv(A))*g1 + 2*g1'*(-inv(A)*B* 4 )*g2 + g2'*( 4 )*g2) + ... -% (l) * ( g1'*(inv(A)*B* 4*Sa *B'*inv(A))*g1 + 2*g1'*(-inv(A)*B* 4*Sa)*g2 + g2'*( 4*Sa)*g2) + ... -% ( g1'*(inv(A)*B* Sa*Sa *B'*inv(A))*g1 + 2*g1'*(-inv(A)*B* Sa*Sa)*g2 + g2'*(Sa*Sa)*g2) - polyval(p_lambda,l)^2; - diff --git a/misc/matlab/point-to-line/gm_test.m b/misc/matlab/point-to-line/gm_test.m deleted file mode 100644 index 705698d..0000000 --- a/misc/matlab/point-to-line/gm_test.m +++ /dev/null @@ -1,19 +0,0 @@ -theta = deg2rad(4); -t = [0.3; -0.2]; - -p = [1 0; 0 1; -1 0; 2 1; 4 2]'; -alpha = [deg2rad(0);deg2rad(10);deg2rad(20);deg2rad(50);deg2rad(-20);]; - -noise = 0 -for i=1:size(p,2) - corr{i}.p = p(:,i); - corr{i}.q = (rot(theta)*p(:,i)+t) + randn(2,1)*noise; - corr{i}.C = vers(alpha(i))*vers(alpha(i))'; -% corr{i}.C = eye(2); -end - -res = general_minimization(corr); - -res.x - - diff --git a/misc/matlab/point-to-line/icp2.m b/misc/matlab/point-to-line/icp2.m deleted file mode 100644 index 1a6bc6d..0000000 --- a/misc/matlab/point-to-line/icp2.m +++ /dev/null @@ -1,213 +0,0 @@ -% Dependences of this script: -% Requires: params_required, params_set_default, icp_get_correspondences -% Requires: ld_plot, icp_covariance, exact_minimization, transform -% Requires: icp_possible_interval - -function res = icp2(params) -% Note: it is assumed that params.laser_ref has a radial uniform scan -% params.laser_ref - first scan -% params.laser_sens - second scan -% params.maxAngularCorrectionDeg - search space bound for phi, in degrees -% params.maxLinearCorrection - search space bound for |t|, in degrees - - - params_required(params, 'laser_sens'); - params_required(params, 'laser_ref'); - params = params_set_default(params, 'maxAngularCorrectionDeg', 105); - params = params_set_default(params, 'maxCorrespondenceDist', 4); - params = params_set_default(params, 'maxLinearCorrection', 2); - params = params_set_default(params, 'maxIterations', 40); - params = params_set_default(params, 'firstGuess', [0;0;0]); - params = params_set_default(params, 'interactive', false); - params = params_set_default(params, 'epsilon_xy', 0.0001); - params = params_set_default(params, 'epsilon_theta', deg2rad(0.001)); - params = params_set_default(params, 'sigma', 0.01); - params = params_set_default(params, 'do_covariance', false); - - %% If true, consider as null correspondences with first or last point - %% in the reference scan. - params = params_set_default(params, 'dont_consider_extrema', true); - - %params.laser_ref = computeSurfaceNormals(params.laser_ref); - - current_estimate = params.firstGuess; - params.laser_sens.estimate = current_estimate; - - if params.interactive - f = figure; hold on - end - - - estimated_cov = eye(3); - - for n=1:params.maxIterations - estimates{n} = current_estimate; - - %% If in interactive mode, show partial solution. - if params.interactive - clf - pl.color = 'b.'; - ld_plot(params.laser_ref,pl); - pl.color = 'r.'; - params.laser_sens.estimate = ... - rtcat(params.laser_ref.estimate, current_estimate); - ld_plot(params.laser_sens,pl); - axis('equal'); - - - %for i=find(valids) - - % plotVectors(params.laser_sens.estimate, [params.laser_sens.points(:,i) P(:,i)] , 'k'); - - %end - end - - - [P, valids, jindexes] = icp_get_correspondences(params, current_estimate); - - fprintf('Valid corr.: %d\n', sum(valids)); - next_estimate = next_estimate(params, current_estimate, P, valids, jindexes); - - delta = next_estimate-current_estimate; - - - current_estimate = next_estimate; - - fprintf('Delta: %s\n', pv(delta)); - fprintf('Estimate: %s\n', pv(current_estimate)); - - if (norm(delta(1:2)) < params.epsilon_xy) & ... - (norm(delta(3)) < params.epsilon_theta) - - break; - end - - if params.interactive - pause - end - - pause(0.01) - end % iterations -fprintf('Converged at iteration %d.\n', n); - - res = params; - - if(params.do_covariance) - estimated_cov = icp_covariance(params, current_estimate, P, valids, jindexes); - res.sm_cov_bengtsson = estimated_cov.sm_cov_bengtsson; - res.loc_cov_censi = estimated_cov.loc_cov_censi; - res.sm_cov_censi = estimated_cov.sm_cov_censi; - end - - - res.X = current_estimate; - res.iteration = n; - estimates{n+1} = current_estimate; - res.estimates = estimates; - - -function next = next_estimate(params, current_estimate, P, valids, jindexes) -% Requires: transform - if sum(valids) < 2 - error('icp:run', sprintf('Only %d correspondences found.',sum(valids))); - end - - next = current_estimate; - - corr={}; - k=0; e = 0; - for i=find(valids) - k=k+1; - p_k = transform(params.laser_sens.points(:,i), current_estimate); - q_k = P(:,i); - - j1 = jindexes(i,1); - j2 = jindexes(i,2); - - p_j1 = params.laser_ref.points(:,j1); - p_j2 = params.laser_ref.points(:,j2); - - v_alpha = rot(pi/2) * (p_j1-p_j2); - v_alpha = v_alpha / norm(v_alpha); - - corr{k}.p = p_k; - corr{k}.q = q_k; - corr{k}.C = v_alpha * v_alpha'; - %% For point-to-point: - % corr{k}.C = eye(2); - - - - if params.interactive - a = transform(params.laser_sens.points(:,i), ... - rtcat(params.laser_ref.estimate, current_estimate)); - b = transform(q_k, ... - params.laser_ref.estimate); - - plot_line(a,b,'g-'); - end - - e = e + norm(p_k-q_k); - end - - - res = general_minimization(corr); - pose = res.x; - - fprintf('exact min. (p2l): %s \n', pv(pose)); - - if true - npos = 0; nneg = 0; - k2 = 0; corr2={}; - k3 = 0; corr3={}; - - for k=1:size(corr,2) - theta = pose(3); t =pose(1:2); - grad = (rot(theta)*corr{k}.p + t - corr{k}.q)' * ... - corr{k}.C * [eye(2) (rot(theta+pi/2) * corr{k}.p)]; - - if grad * pose < 0 - k2 = k2 +1; - corr2{k2} = corr{k}; - nneg = nneg + 1; - else - k3 = k3 +1; - corr3{k3} = corr{k}; - npos = npos + 1; - if params.interactive - a = transform(corr{k}.p, params.laser_ref.estimate); - b = transform(corr{k}.q, params.laser_ref.estimate); - plot_line(a,b,'k-'); - end - end - end - - fprintf('pos: %d neg: %d\n', npos, nneg); - threshold = 0.1; - if npos < threshold * nneg - fprintf('Doing the trick!\n') - res = general_minimization(corr2); - pose = res.x; - fprintf('exact min. after trick (p2l): %s \n', pv(pose)); - end - if nneg < threshold * npos - fprintf('Doing the trick! (other) \n') - res = general_minimization(corr3); - pose = res.x; - fprintf('exact min. after trick (p2l): %s \n', pv(pose)); - end - if npos > nneg - fprintf('Finished trick!\n') - end - end - - next_phi = current_estimate(3) + pose(3); - next_t = transform(current_estimate(1:2,1), pose); - next = [next_t; next_phi]; - - fprintf('Pose: %s error: %f\n', pv(next), e); - -function plot_line(a,b,color) - plot([a(1) b(1)],[a(2) b(2)], color); - - diff --git a/misc/matlab/point-to-line/polyadd.m b/misc/matlab/point-to-line/polyadd.m deleted file mode 100644 index 1233d9f..0000000 --- a/misc/matlab/point-to-line/polyadd.m +++ /dev/null @@ -1,16 +0,0 @@ -function[poly]=polyadd(poly1,poly2) -%Copyright 1996 Justin Shriver -%polyadd(poly1,poly2) adds two polynominals possibly of uneven length -if length(poly1)<length(poly2) - short=poly1; - long=poly2; -else - short=poly2; - long=poly1; -end -mz=length(long)-length(short); -if mz>0 - poly=[zeros(1,mz),short]+long; -else - poly=long+short; -end diff --git a/misc/matlab/point-to-line/rad2deg.m b/misc/matlab/point-to-line/rad2deg.m deleted file mode 100644 index 1195b0f..0000000 --- a/misc/matlab/point-to-line/rad2deg.m +++ /dev/null @@ -1,2 +0,0 @@ -function r = rad2deg(d) - r = d * 180 / pi; diff --git a/misc/matlab/point-to-line/rot.m b/misc/matlab/point-to-line/rot.m deleted file mode 100644 index 06ea72f..0000000 --- a/misc/matlab/point-to-line/rot.m +++ /dev/null @@ -1,3 +0,0 @@ -function r=rot(theta) -% rot(theta) rotation matrix of order two - r = [cos(theta) -sin(theta); sin(theta) cos(theta)]; diff --git a/misc/matlab/point-to-line/test_icp2.m b/misc/matlab/point-to-line/test_icp2.m deleted file mode 100644 index 716f80a..0000000 --- a/misc/matlab/point-to-line/test_icp2.m +++ /dev/null @@ -1,32 +0,0 @@ -% Requires: rtcat - - %% First pose. - params.position = [-0.3;0.1;deg2rad(10)]; - %% Step. - truth_cov = diag([0.35^2 0.35^2 deg2rad(17.5)^2]); - params.truth = sample_normal([0;0;0], truth_cov, 1); - %% Covariance of the first guess. - params.guess_cov = diag([0.35^2 0.35^2 deg2rad(7.5)^2]); - params.fov = 1.4*pi; - params.nrays = 180; - params.sigma = 0.01; - - %% Second pose. - params.position2 = rtcat(params.position, params.truth); - - L = 5; - seglist = { 0.4*L*[-1.2 1; -1 -1]', L*[1.5 1; 1 -1]', ... - 0.3*L*[1 -1.3; -1 -1]', L*[1.4 1; -1 1]'} - - params.laser_ref = ... - ray_tracing_polygon(seglist, params.position, 180, params.fov, inf); - params.laser_sens = ... - ray_tracing_polygon(seglist, params.position2, params.nrays, params.fov, inf); - - params.interactive = false; - - params.laser_sens = ld_add_noise(params.laser_sens, params.sigma); - params.laser_ref = ld_add_noise(params.laser_ref, params.sigma); - - - res = icp2(params); diff --git a/misc/matlab/point-to-line/vers.m b/misc/matlab/point-to-line/vers.m deleted file mode 100644 index 3c3c2fd..0000000 --- a/misc/matlab/point-to-line/vers.m +++ /dev/null @@ -1,4 +0,0 @@ -function v = vers(theta) -% returns 2d versor of direction theta - v = [cos(theta); sin(theta)]; - diff --git a/misc/matlab/ray_tracing/countour_circle.m b/misc/matlab/ray_tracing/countour_circle.m deleted file mode 100644 index 301c07c..0000000 --- a/misc/matlab/ray_tracing/countour_circle.m +++ /dev/null @@ -1,18 +0,0 @@ -function [p, alpha] = countour_circle(params, tau) - radius = params{1}; - - if size(radius,2) == 2 - x_radius = radius(1); - y_radius = radius(2); - else - x_radius = radius; - y_radius = radius; - end - - theta = 2 * pi * tau; - - p = [x_radius*cos(theta); y_radius*sin(theta)]; - - alpha = atan2(x_radius*sin(theta),y_radius*cos(theta)); - - diff --git a/misc/matlab/ray_tracing/countour_flower.m b/misc/matlab/ray_tracing/countour_flower.m deleted file mode 100644 index 45f8e0a..0000000 --- a/misc/matlab/ray_tracing/countour_flower.m +++ /dev/null @@ -1,13 +0,0 @@ -function [p, alpha] = countour_flower(params, tau) - r1 = params{1}; - r2 = params{2}; - v = params{3}; - - theta = -pi + 2 * pi * tau; - rho = r1 + r2 * cos(theta*v); - - p = rho * [cos(theta);sin(theta)]; - - alpha = nan; - - diff --git a/misc/matlab/ray_tracing/countour_sine.m b/misc/matlab/ray_tracing/countour_sine.m deleted file mode 100644 index 718011d..0000000 --- a/misc/matlab/ray_tracing/countour_sine.m +++ /dev/null @@ -1,24 +0,0 @@ -function [p, alpha] = countour_sine(params, tau) - % params = {rho, amplitude, periods_in_circle} - - rho = params{1}; - amplitude = params{2}; - periods = params{3}; - - theta = 2 * pi * tau; - - p = sine(theta,rho,amplitude, periods); - - epsilon = 0.001; - p1 = sine(theta-epsilon,rho,amplitude, periods); - p2 = sine(theta+epsilon,rho,amplitude, periods); - - v_alpha = rot(pi/2)*(p2-p1); - alpha = atan2(v_alpha(2),v_alpha(1)); - - -function p = sine(theta, rho, amplitude, periods) - s = theta * rho; - dist = rho + amplitude * cos(s * periods/rho ); - p = dist * [cos(theta);sin(theta)]; - diff --git a/misc/matlab/ray_tracing/countour_straight.m b/misc/matlab/ray_tracing/countour_straight.m deleted file mode 100644 index b9f1654..0000000 --- a/misc/matlab/ray_tracing/countour_straight.m +++ /dev/null @@ -1,45 +0,0 @@ -function [p, alpha] = countour_straight(params, tau) - -points = params{1}; - K = size(points,2); - - if K < 2 - error('2 points needed'); - end - - - if tau>1 - while tau>1 - tau = tau -1; - end - end - - if tau<0 - while tau<0 - tau = tau +1; - end - end - - if tau==0 - p = points(:,1); - return - end - - if tau==1 - p = points(:,K); - return; - end - - - index = ceil(tau * (K-1)); - - - index_tau = (index-1.0) / (K-1); - tau2 = (tau-index_tau) * (K-1); - - p1 = points(:,index); - p2 = points(:,index+1); - - p = p2 * tau2 + (1-tau2) * p1; - alpha = pi/2 + atan2( p1(2)-p2(2), p1(1)-p2(1)); - diff --git a/misc/matlab/ray_tracing/ld_circle.m b/misc/matlab/ray_tracing/ld_circle.m deleted file mode 100644 index 8721e71..0000000 --- a/misc/matlab/ray_tracing/ld_circle.m +++ /dev/null @@ -1,10 +0,0 @@ -function ld = ld_circle(radius, pose, rays, fov) -% ld = ld_circle(radius, pose, rays, fov) -% Circle at (0,0) - - ld = ray_tracing( pose, fov, rays, 'countour_circle', {radius},0.001); - - - - - diff --git a/misc/matlab/ray_tracing/ld_oval.m b/misc/matlab/ray_tracing/ld_oval.m deleted file mode 100644 index aaca1f5..0000000 --- a/misc/matlab/ray_tracing/ld_oval.m +++ /dev/null @@ -1,10 +0,0 @@ -function ld = ld_circle(x_radius, y_radius, pose, rays, fov) -% ld = ld_circle(x_radius, y_radius, pose, rays, fov) -% Oval at (0,0) - - ld = ray_tracing( pose, fov, rays, 'countour_circle', {[x_radius y_radius]},0.001); - - - - - diff --git a/misc/matlab/ray_tracing/ld_sine.m b/misc/matlab/ray_tracing/ld_sine.m deleted file mode 100644 index e63ddad..0000000 --- a/misc/matlab/ray_tracing/ld_sine.m +++ /dev/null @@ -1,9 +0,0 @@ -function ld = ld_sine(rho, amplitude, periods, pose, rays, fov) -% ld = ld_sine(rho, amplitude, periods, pose, rays, fov) - - ld = ray_tracing( pose, fov, rays, 'countour_sine', {rho, amplitude, periods},0.00001); - - - - - diff --git a/misc/matlab/ray_tracing/ld_square.m b/misc/matlab/ray_tracing/ld_square.m deleted file mode 100644 index 0d19788..0000000 --- a/misc/matlab/ray_tracing/ld_square.m +++ /dev/null @@ -1,12 +0,0 @@ -function ld = ld_square(L, pose, rays, fov) -% ld = ld_square(L, pose, rays, fov) -% L: length of square side - - square = [-1 -1; 1 -1; 1 1; -1 1; -1 -1]' * L; - - ld = ray_tracing( pose, fov, rays, 'countour_straight', {square},0.00001); - - - - - diff --git a/misc/matlab/ray_tracing/ray_tracing.m b/misc/matlab/ray_tracing/ray_tracing.m deleted file mode 100644 index deca81d..0000000 --- a/misc/matlab/ray_tracing/ray_tracing.m +++ /dev/null @@ -1,130 +0,0 @@ -function ld = ray_tracing(pose, fov, nrays, countour, countour_params, precision) - - debug = true; - - t = pose(1:2); - ld.nrays = nrays; - for i=1:nrays - if(debug) - fprintf('@'); - if 0 == mod(i,32) - fprintf(' %d \n', i); - end - end - - theta = -fov/2 + fov * (i-1)/(nrays-1); - ld.theta(i) = theta; - params = {t, pose(3)+ld.theta(i), countour, countour_params}; - - % cerchiamo approssimativamente quello che gli si avvicina di più - % e sarà il nostro a di partenza - delta_a = 0.05; - test_a = 0.001:delta_a:0.99; - - for j =1:size(test_a,2) - test_a_theta(j) = feval('eval_delta', params, test_a(j)); - end - - [Y,index] = min(abs(test_a_theta)); - best_a = test_a(index(1)); - best_a_val = test_a_theta(index(1)); - - % una volta trovato a cerchiamo un b - - good_b = best_a; - while true - good_b = good_b - sign(best_a_val)*delta_a; - val = feval('eval_delta', params, good_b); - if sign(val) * sign(best_a_val) < 0 - break - end - end - - if best_a > good_b - a = good_b; - b = best_a; - else - b = good_b; - a = best_a; - end - - % do the rest with bisection - tau = rfBisection( 'eval_delta', params, a, b,precision); - [point, alpha] = feval(countour, countour_params, tau); - ld.readings(i) = norm(point-t); - %fprintf('i=%d theta=%d° reading=%f\n', i, rad2deg(ld.theta(i)), ld.readings(i)); - - if cos(alpha - (pose(3)+ld.theta(i)) ) > 0 - alpha = alpha + pi; - end - - ld.true_alpha(i) = alpha-pose(3); % local coordinates - ld.true_alpha_abs(i) = alpha; % local coordinates - - if rand>0.95 - pause(0.02) - end - end - if debug - fprintf('\n'); - end - - ld.odometry = pose; - ld.estimate = pose; - ld.timestamp1 = '0'; - ld.timestamp2 = '0'; - ld.hostname = 'matlab'; - ld.points = [ cos(ld.theta) .* ld.readings; sin(ld.theta).* ld.readings]; - -function delta = eval_delta(params, tau) - - % secondo parametro: t - t = params{1}; - theta = params{2}; - curve = params{3}; - curve_params = params{4}; - point = feval(curve, curve_params, tau); - phi = angle(point-t); - delta = normAngle(phi-theta); - -% fprintf('tau = %f point = %f %f theta=%f phi=%d delta=%f\n', ... -% tau, point(1), point(2), theta, phi, delta); - -function a = angle(v) - a = atan2(v(2),v(1)); - -function root = rfBisection( func, func_params, a, b, epsilon) - - f_a = feval(func, func_params, a); - f_b = feval(func, func_params, b); - - s = sign(f_a) * sign(f_b); - if not ( s == -1 ) - error('Sign is equal for a = %g ( f(a)=%g ) and b = %g ( f(b)=%g ) ', a, f_a, b, f_b); - end - - % fprintf('Root finding (Bisection method)\n'); - % fprintf(' k\t a \t b \t c \t b-c \t f(c)\n'); - k = 1; - while 1 - c = a + (b-a)/2; - - f_b = feval(func, func_params, b); - f_c = feval(func, func_params, c); - % fprintf(' %d\t%.6g\t%.6g\t%.6g\t%.6g\t%.6g\n',... - % k, a, b, c, b-c, f_c) - - if b - c <= epsilon - root = c; - break - end - - if sign(f_b) * sign(f_c) <= 0 - a = c; - else - b = c; - end - - k = k+1; - end - diff --git a/misc/matlab/ray_tracing/ray_tracing_polygon.m b/misc/matlab/ray_tracing/ray_tracing_polygon.m deleted file mode 100644 index 07f39a7..0000000 --- a/misc/matlab/ray_tracing/ray_tracing_polygon.m +++ /dev/null @@ -1,96 +0,0 @@ -% polylist = { [p0;p1], [p1;p2] } -function ld = ray_tracing_polygon(seglist, pose, nrays, fov, max_reading) - - t = pose(1:2); - ld.nrays = nrays; - for i=1:nrays - theta = -fov/2 + fov * (i-1)/(nrays-1); - ld.theta(i) = theta; - - [valid, reading, alpha] = try_segment_list(seglist, pose(1:2), pose(3)+theta, max_reading); - - if valid - ld.readings(i) = reading; - ld.readings_valid(i) = true; - ld.true_alpha(i) = alpha-pose(3); - ld.true_alpha_abs(i) = alpha; - else - ld.readings(i) = nan; - ld.readings_valid(i) = false; - ld.true_alpha(i) = nan; - ld.true_alpha_abs(i) = nan; - end - - ld.true_alpha(i) = alpha-pose(3); % local coordinates - ld.true_alpha_abs(i) = alpha; % local coordinates - - if rand>0.95 - pause(0.02) - end - end - - - ld.odometry = pose; - ld.estimate = pose; - ld.timestamp1 = '0'; - ld.timestamp2 = '0'; - ld.hostname = 'matlab'; - ld.points = [ cos(ld.theta) .* ld.readings; sin(ld.theta).* ld.readings]; - -function [valid, reading, alpha] = try_segment_list(seglist, position, direction, max_reading) - valid = false; - reading = nan; - alpha = nan; - for i=1:size(seglist,2) - AB = seglist{i}; - [valid_i, reading_i, alpha_i] = try_segment(AB(:,1),AB(:,2),position, direction, max_reading); - better = valid_i & ( (~valid) | (reading_i < reading)); - if better - valid = true; - reading = reading_i; - alpha = alpha_i; - end - end - -function [valid, reading, alpha] = try_segment(A, B, position, direction, max_reading) - valid = false; - reading = nan; - alpha = nan; - - % Direction of view - N = vers(direction); - - % normal to segment - S = rot(pi/2) * (A-B); - - epsilon = 0.0000001; - if abs(S'*N) < epsilon - return; - end - - dist = (S'*(A-position)) / (S'*N); - if dist < 0 - return - end - - % Now we check whether the crossing point - % with the line lies within the segment - crossingPoint = position + N * dist; - % distance from segment center to crossing point - rad = norm(crossingPoint - ( 0.5*A + 0.5*B)); - if rad > norm(A-B)/2 - return; - end - - if(max_reading == 0) | (dist < max_reading) - reading = dist; - valid = true; - alpha = atan2(S(2),S(1)); - if vers(alpha)' * N > 0 - alpha = alpha + pi; - end - if alpha > 2*pi - alpha = alpha - 2*pi; - end - end - diff --git a/misc/matlab/ray_tracing/ts_flower.m b/misc/matlab/ray_tracing/ts_flower.m deleted file mode 100644 index aacbd3f..0000000 --- a/misc/matlab/ray_tracing/ts_flower.m +++ /dev/null @@ -1,15 +0,0 @@ -function ts = ts_flower(r1, r2, v, pose, step) -% ts = ts_flower(r1,r2,v,pose,step) -% -% returns ts.laser_ref and ts.laser_sens -% -% r1,r2,v give the flower shape -% pose2 = pose (+) step - - pose1 = pose; - pose2 = rtcat(pose1,step); - - ts.laser_ref = ray_tracing( pose1, pi, 181, 'countour_flower', {r1,r2,v},0.000001); - ts.laser_sens = ray_tracing( pose2, pi, 181, 'countour_flower', {r1,r2,v},0.000001); - - diff --git a/misc/matlab/ray_tracing/ts_square.m b/misc/matlab/ray_tracing/ts_square.m deleted file mode 100644 index c1c7c18..0000000 --- a/misc/matlab/ray_tracing/ts_square.m +++ /dev/null @@ -1,23 +0,0 @@ -function ts = ts_square(L, pose, step) -% ts = ts_square(L, pose, step) -% L: length of square side or if size(L)=2 then it is [Lx Ly] -% pose2 = pose (+) step - - if size(L) == 1 - M = L; - else - M = diag(L); - end - - square = M * [-1 -1; 1 -1; 1 1; -1 1; -1 -1]'; - - pose1 = pose; - pose2 = rtcat(pose1,step); - - ts.laser_ref = ray_tracing( pose1, pi, 181, 'countour_straight', {square},0.00001); - ts.laser_sens = ray_tracing( pose2, pi, 181, 'countour_straight', {square},0.00001); - - - - - diff --git a/misc/matlab/ray_tracing/ts_square2.m b/misc/matlab/ray_tracing/ts_square2.m deleted file mode 100644 index 4b19b2b..0000000 --- a/misc/matlab/ray_tracing/ts_square2.m +++ /dev/null @@ -1,23 +0,0 @@ -function ts = ts_square(L, pose, step, nrays, fov) -% ts = ts_square(L, pose, step) -% L: length of square side or if size(L)=2 then it is [Lx Ly] -% pose2 = pose (+) step - - if size(L) == 1 - M = L; - else - M = diag(L); - end - - square = M * [-1 -1; 1 -1; 1 1; -1 1; -1 -1]'; - - pose1 = pose; - pose2 = rtcat(pose1,step); - - ts.laser_ref = ray_tracing( pose1, fov, nrays, 'countour_straight', {square},0.00001); - ts.laser_sens = ray_tracing( pose2, fov, nrays, 'countour_straight', {square},0.00001); - - - - - diff --git a/misc/matlab/scripts/collate.rb b/misc/matlab/scripts/collate.rb deleted file mode 100755 index b850431..0000000 --- a/misc/matlab/scripts/collate.rb +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env ruby - -block = Array.new -block_indent = ''; - -$stdin.each_line do |l| - if l =~ /^(\s*)%%(.*)$/ - if block.size == 0 - block_indent = $1; - end - block.push $2 - else - # flush block - if block.size > 0 - sub_blocks = Array.new - sub_blocks.push Array.new - - block.each do |m| - if m.strip.size == 0 - sub_blocks.push Array.new - else - sub_blocks.last.push m - end - end - - sub_blocks.each do |s| - if s.size>0 - $stdout.puts block_indent + "%% " + s.join; - end - end - - block.clear - end - # and write last line - $stdout.puts l - end -end diff --git a/misc/matlab/scripts/create_package.rb b/misc/matlab/scripts/create_package.rb deleted file mode 100755 index 2897ec6..0000000 --- a/misc/matlab/scripts/create_package.rb +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env ruby - -require 'getoptlong' - -class DB - attr_accessor :required - - def initialize() - @name2file = Hash.new - @required = Array.new - end - - def explore_directory(d) - pwd = Dir.pwd - Dir.chdir(d) - Dir.glob('**/*.m').each do |x| - name = File.basename(x,'.m'); - @name2file[name]=File.join(d, x); - # puts "Found function #{name} in file #{x}." - end - Dir.chdir(pwd) - end - - def need_function(n) - return if @required.include?(@name2file[n]) - - if @name2file.has_key?(n) - @required.push @name2file[n] - parse_file(@name2file[n]); - else - $stderr.puts "Dependency '#{n}' not found." - end - end - - def parse_file(file) - # TODO: se e' directory falli tutti - File.open(file,'r') do |f| parse_io(f) end - end - - def parse_io(io) - io.each_line do |l| - if l =~ /^\s*%\s*Requires:\s*(.*)$/ - $1.split(",").each do |x| - need_function(x.strip) - end - end - end - end -end - -def print_usage(error) - puts "create_package [--directory <dir1>,<dir2>,...]*" - -end - -def go - version = 0.1; - - opts = GetoptLong.new( - [ "--directory", "-d", GetoptLong::REQUIRED_ARGUMENT ], - [ "--help", "-h", GetoptLong::NO_ARGUMENT ], - [ "--version", "-v", GetoptLong::NO_ARGUMENT ] - ) - - - directories = Array.new - begin - ndirectory = 0; - opts.each do |opt, arg| - case opt - when "--directory" - arg.split(",").each do |single| - directories.push(File.expand_path(single)) - end - ndirectory += 1 - when "--help" - print_usage(0); exit(0); - when "--usage" - print_usage(0); exit(0); - when "--version" - print "csvt, version ", version, "\n" - exit(0) - end - end - - rescue - print_usage(1) - end - - directories.push File.expand_path('.') if directories.size == 0 - - db = DB.new - directories.each do |d| - db.explore_directory(d) - end - - files = ARGV; - - if files.empty? - db.parse_io($stdin); - else - files.each do |x| - db.parse_file(x) - end - end - - db.required.each do|r| - puts r - end - -end - -go diff --git a/misc/matlab/scripts/find_dependencies.rb b/misc/matlab/scripts/find_dependencies.rb deleted file mode 100755 index 729285f..0000000 --- a/misc/matlab/scripts/find_dependencies.rb +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env ruby - -require 'getoptlong' - -def help -<<EOF - - This script parses a Matlab script and finds its dependencies on - other scripts. - -EOF -end - -class DB - # Files required (full path) - attr_accessor :required - # Functione whose file was not found - attr_accessor :notfound - - def initialize() - @name2file = Hash.new - @required = Array.new - @notfound = Array.new - end - - def explore_directory(d) - pwd = Dir.pwd - Dir.chdir(d) - Dir.glob('**/*.m').each do |x| - name = File.basename(x,'.m'); - @name2file[name]=File.join(d, x); -# puts "Found function '#{name}' in file #{x}." - end - Dir.chdir(pwd) - end - - def need_function(n) - if @required.include?(@name2file[n]) -# $stderr.puts "Dependency '#{n}' already got." - return - end - - if @name2file.has_key?(n) -# $stderr.puts "Dependency '#{n}' Found!" - @required.push @name2file[n] - parse_file(@name2file[n]); - else - @notfound.push n if not @notfound.include? n -# $stderr.puts "Dependency '#{n}' not found." - end - end - - def parse_file(file) - # TODO: se e' directory falli tutti - File.open(file,'r') do |f| parse_io(f) end - end - - def parse_io(io) - # variables used - variables = Array.new - # functions defined in file - functions = Array.new - - # add built-ins - functions.push(*['find','if','eye','fprintf','sum','axis', - 'norm','error','plot','pause','sprintf']) - - doRequires = true - io.each_line do |l| - if false - if l =~ /\s*function .*=\s*(\w+)/ || - l =~ /\s*function\s*(\w+)/ - # puts "Defined function #{$1}" - functions.push $1 - end - l.split(';').each do |statement| - if statement =~ %r|\s*(\w+)\s*=| || - statement =~ %r|(\w+)(\(.*\))*\s*=| - # puts "Is #{$1} a variable in this? #{statement}" - variables.push $1 - end - end - - # TODO: ignore after comments - # TODO: parse strings (ex: fprintf('False(%s,%s;%s)')) - l.scan(/(\w+)\(/) { |a| f=a[0]; - need_function(f) unless variables.include?(f) or - functions.include?(f) - } - - if l =~ /^\s*%\s*Requires:\s*(.*)$/ - $1.split(",").each do |x| - need_function(x.strip) - end - end - end - l.scan(/([A-Za-z_]\w*)/) { |a| f=a[0]; - need_function(f) - } - end - end -end - -def print_usage(error) - puts "create_package [--directory <dir1>,<dir2>,...]*" - puts help -end - -def go - version = 0.1; - - opts = GetoptLong.new( - [ "--directory", "-d", GetoptLong::REQUIRED_ARGUMENT ], - [ "--help", "-h", GetoptLong::NO_ARGUMENT ], - [ "--version", "-v", GetoptLong::NO_ARGUMENT ] - ) - - - directories = Array.new - begin - ndirectory = 0; - opts.each do |opt, arg| - case opt - when "--directory" - arg.split(",").each do |single| - directories.push(File.expand_path(single)) - end - ndirectory += 1 - when "--help" - print_usage(0); exit(0); - when "--usage" - print_usage(0); exit(0); - when "--version" - print "csvt, version ", version, "\n" - exit(0) - end - end - - rescue - print_usage(1) - end - - directories.push File.expand_path('.') if directories.size == 0 - - db = DB.new - directories.each do |d| - db.explore_directory(d) - end - - files = ARGV; - - if files.empty? - db.parse_io($stdin); - else - files.each do |x| - db.required.push(Filename.expand(x)) - db.parse_file(x) - end - end - - db.required.each do|r| - puts r - end - -# $stderr.puts "Found #{db.required.size} deps. Not found: " + -# db.notfound.join(", ") + "." - -end - -go diff --git a/misc/matlab/scripts/matlab2pdf.rb b/misc/matlab/scripts/matlab2pdf.rb deleted file mode 100644 index 80ba031..0000000 --- a/misc/matlab/scripts/matlab2pdf.rb +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env ruby - -def go(filename) - - latex=<<EOF -\documentclass{article} -\usepackage{amsmath} -\usepackage{xcolor} -\usepackage{listings} - -\begin{document} -\lstset{% general command to set parameter(s) - basicstyle=\footnotesize\ttfamily, % print whole listing small - keywordstyle=\color{blue}\bfseries, - % underlined bold black keywords - identifierstyle=, % nothing happens - commentstyle=\color{green}, % white comments - stringstyle=\color{red}\ttfamily, % typewriter type for strings - tabsize=4, - language=matlab, - escapeinside={\%\%}{\^^M}, - %escapeinside={\%\%\%}{M\%\%\%}, - escapebegin=\begin{commentline}, - escapeend=\end{commentline}, - showstringspaces=false} % no special string spaces - -\newenvironment{commentline}{\begin{minipage}{\textwidth}\color{violet}\rmfamily}{\end{minipage}} - -\lstinputlisting[tabsize=4,language=matlab]{test_gpm.m} -\end{document} -EOF - - - temp_dir = ... - temp_file = Fi -end diff --git a/misc/matlab/setall.m b/misc/matlab/setall.m deleted file mode 100644 index 9cf6cfe..0000000 --- a/misc/matlab/setall.m +++ /dev/null @@ -1,2 +0,0 @@ - -path(path,genpath(pwd)); diff --git a/misc/matlab/show_ci.m b/misc/matlab/show_ci.m deleted file mode 100644 index 4356549..0000000 --- a/misc/matlab/show_ci.m +++ /dev/null @@ -1,12 +0,0 @@ -function show_ci(matrices) - - cim = ci(matrices); - - figure; hold on; - - for i=1:size(matrices,2) - plotGauss2Db([0;0], matrices{i}, 'k'); - end - - plotGauss2Db([0;0], cim, 'r'); - diff --git a/misc/matlab/test_ci.m b/misc/matlab/test_ci.m deleted file mode 100644 index 0ccb464..0000000 --- a/misc/matlab/test_ci.m +++ /dev/null @@ -1,21 +0,0 @@ - - -M = {{[0.0229765, -0.0149166; -0.0149166, 0.0656807], [0.0282244, -0.03318; -0.03318, 0.0462785], [0.0636718, -0.0203679; -0.0203679, 0.027945]},{[0.0716384, -0.000573107; -0.000573107, 0.0433797], [0.0255015, -0.0149166; -0.0149166, 0.0682057], [0.0365894, -0.040821; -0.040821, 0.0588011]}, {[0.0714078, -0.00365251; -0.00365251, 0.0165718], [0.0505588, -0.0316832; -0.0316832, 0.0240555], [0.0365894, -0.040821; -0.040821, 0.0588011]},{[0.0626201, -0.0246348; -0.0246348, 0.0138652], [0.0348738, 0.0339196; 0.0339196, 0.0426435], [0.00283792, 0; 0, 0.0729]},{[0.0503681, -0.0317826; -0.0317826, 0.0241856], [0.0375459, 0.0341964; 0.0341964, 0.0373611], [0.00145432, 0; 0, 0.07165]},{[0.00145432, 0; 0, 0.0729], [0.0729, 0; 0, 0.000957015], [0.0519886, 0.0324478; 0.0324478, 0.0225514]},{[0.0628428, -0.0244156; -0.0244156, 0.013627], [0.0564294, 0.0292007; 0.0292007, 0.02113], [0.00362348, 0; 0, 0.0711234]},{[0.0348738, 0.0339196; 0.0339196, 0.0426435], [0.00283792, 0; 0, 0.0729], [0.0365894, -0.040821; -0.040821, 0.0588011]},{[0.0264557, -0.033174; -0.033174, 0.0445065], [0.0237598, -0.0150674; -0.0150674, 0.0668957], [0.0636718, -0.0203679; -0.0203679, 0.027945]},{[0.0448063, -0.0346394; -0.0346394, 0.0301898], [0.0365894, -0.040821; -0.040821, 0.0588011]}}; - -M2 = {{[0.0622859, 0; 0, 0.0188791], [0.0134384, 0.011938; 0.011938, 0.0607043]}, {[0.0622859, 0; 0, 0.0188791], [0.013466, 0.0120539; 0.0120539, 0.0611908], [0.0541466, 0.0225964; 0.0225964, 0.019648]}}; - -M = M2; - -figure; hold on; - -colors = {'b','r','g','k','m'} -n = min(size(colors,2),size(M,2)); -n = 1; -for node=1:n - covs = M{node}; - - for i = 1:size(covs,2) - covs{i} - plotGauss2Db([0;0], covs{i}, colors{node}); - end -end diff --git a/misc/matlab/unsorted/mdisplay.m b/misc/matlab/unsorted/mdisplay.m deleted file mode 100644 index 2eea636..0000000 --- a/misc/matlab/unsorted/mdisplay.m +++ /dev/null @@ -1,2 +0,0 @@ -function mdisplay(m) - image(255* abs(m) / max(max(abs(m)))); diff --git a/misc/matlab/unsorted/normalize.m b/misc/matlab/unsorted/normalize.m deleted file mode 100755 index b8861b4..0000000 --- a/misc/matlab/unsorted/normalize.m +++ /dev/null @@ -1,6 +0,0 @@ -% Normalizes a vector in the [0,1] range -function b = normalize(a) - minimum = min(a); - maximum = max(a); - b = (a - minimum) / (maximum-minimum); - diff --git a/misc/matlab/unsorted/prepareSampling.m b/misc/matlab/unsorted/prepareSampling.m deleted file mode 100644 index f1e873f..0000000 --- a/misc/matlab/unsorted/prepareSampling.m +++ /dev/null @@ -1,26 +0,0 @@ -function result = prepareSampling(set, weights) - threshold=0.1; - resolution = min(weights(find(weights>threshold))) / 5 - totWeight = sum(weights); - spaces = ceil(totWeight/resolution) - fprintf('prepareSampling: n=%d', spaces); - setIndex = 1; - setTotal = weights(1); - myTotal = 0; - - for i=1:spaces - result(i) = setIndex; - - if myTotal>setTotal & setIndex < size(weights,2) - setIndex = setIndex +1 ; - setTotal = setTotal + weights(setIndex); - end - - myTotal = myTotal + resolution; - - end - - myTotal - setTotal - - diff --git a/misc/matlab/unsorted/randf2.m b/misc/matlab/unsorted/randf2.m deleted file mode 100644 index b1bad16..0000000 --- a/misc/matlab/unsorted/randf2.m +++ /dev/null @@ -1,29 +0,0 @@ -function [f0,f1,f2] = randf2(t,w) - - n = size(t,2); - f2 = w * randn(1,n+2); - - f1(1)=0; - for i=2:n - f1(i) = f1(i-1) + f2(i-1) * (t(i)-t(i-1)); - end - - f0(1)=0; - for i=2:n - f0(i) = f0(i-1) + f1(i-1) * (t(i)-t(i-1)); - end - - f2 = f2(1:n); - f1 = f1(1:n); - f0 = f0(1:n); - - - - figure - hold on - - plot(1:n, f0, 'r.'); - plot(1:n, f1, 'g.'); - plot(1:n, f2, 'b.'); - - hold off diff --git a/misc/matlab/unsorted/rtcat.m b/misc/matlab/unsorted/rtcat.m deleted file mode 100644 index 5eb277c..0000000 --- a/misc/matlab/unsorted/rtcat.m +++ /dev/null @@ -1,7 +0,0 @@ -function d = rtcat(ref, delta) - %% Adds a rototranslation. ref is the starting point and - %% delta is (x,y,theta). - d(1:2) = ref(1:2) + rot(ref(3)) * delta(1:2); - d(3) = ref(3) + delta(3); - d = d'; - diff --git a/misc/matlab/unsorted/sampleIndex.m b/misc/matlab/unsorted/sampleIndex.m deleted file mode 100644 index b9a8916..0000000 --- a/misc/matlab/unsorted/sampleIndex.m +++ /dev/null @@ -1,4 +0,0 @@ -function index = sampleIndex(prepared) - n = size(prepared,2); - i = min(max(1, floor(rand*(n-1))), n); - index = prepared(i); diff --git a/misc/matlab/unsorted/sample_normal.m b/misc/matlab/unsorted/sample_normal.m deleted file mode 100644 index ea1791d..0000000 --- a/misc/matlab/unsorted/sample_normal.m +++ /dev/null @@ -1,7 +0,0 @@ -function rnorm = sample_normal(mean,Sigma,N) -% sample_normal(mean,Sigma,N) -% sampleNormal generates a pxN array of normal draws -% from the p-dim N(mean,Sigma) - p=length(mean); - rnorm = repmat(reshape(mean,p,1),1,N) +chol(Sigma)'*randn(p,N); - diff --git a/misc/matlab/unsorted/simpleLowPassFilter.m b/misc/matlab/unsorted/simpleLowPassFilter.m deleted file mode 100755 index c608dc1..0000000 --- a/misc/matlab/unsorted/simpleLowPassFilter.m +++ /dev/null @@ -1,5 +0,0 @@ -% Simple low-pass filter with a gaussian mask -function b = simpleLowPassFilter(a, sigma) - amp=2*sigma; filter=exp(-((-amp:amp).^2)/sigma^2); - b = normalize(convn(a,filter,'same')); - diff --git a/misc/matlab/unsorted/simpleLowPassFilter2.m b/misc/matlab/unsorted/simpleLowPassFilter2.m deleted file mode 100755 index 47a1f9f..0000000 --- a/misc/matlab/unsorted/simpleLowPassFilter2.m +++ /dev/null @@ -1,13 +0,0 @@ -% Simple low-pass filter with a gaussian mask (bidimensional version) -function b = simpleLowPassFilter2(a, sigma) - amp=2*sigma+1; - mask=zeros(amp,amp); - - for i=1:amp - for j=1:amp - mask(i,j) = exp(-((i-sigma-1)^2+(j-sigma-1)^2)/sigma^2); - end - end - - b = conv2(a,mask,'same'); - diff --git a/misc/matlab/unsorted/simpleLowPassFilterCircular.m b/misc/matlab/unsorted/simpleLowPassFilterCircular.m deleted file mode 100755 index d711d41..0000000 --- a/misc/matlab/unsorted/simpleLowPassFilterCircular.m +++ /dev/null @@ -1,7 +0,0 @@ -% Simple low-pass filter with a gaussian mask, for a circular buffer -function b = simpleLowPassFilterCircular(a, sigma) - extended=[a a a]; - extendedb=simpleLowPassFilter(extended,sigma); - b = extendedb(size(a,2)+1:end-size(a,2)); - b = normalize(b); - diff --git a/misc/matlab/unsorted/test_boh.m b/misc/matlab/unsorted/test_boh.m deleted file mode 100644 index 88d904c..0000000 --- a/misc/matlab/unsorted/test_boh.m +++ /dev/null @@ -1,21 +0,0 @@ -function f = test_boh - -th=0:0.001:2*pi; - -G = [.5 4; 0 .5]; rand(2,2); -k = 100*rand(2,1); -k =[-1;0]; - -for i=1:size(th,2) - - f(i) = vers(th(i))' * G * vers(th(i)) + k'*vers(th(i)); - -end - -fi=figure; -plot(rad2deg(th),f); - - - -function v = vers(t) - v=[cos(t);sin(t)]; diff --git a/misc/matlab/unsorted/test_inversa.m b/misc/matlab/unsorted/test_inversa.m deleted file mode 100644 index ff6de9a..0000000 --- a/misc/matlab/unsorted/test_inversa.m +++ /dev/null @@ -1,25 +0,0 @@ - n = 360; m = rand(n,n); P = m * m'; - - Q = P; - G = rand(n,n); - H = G; - - band=30; - - for i=1:n - for j=1:n - if abs(i-j)>band - Q(i,j)=0; G(i,j)=0; - end; - end; -end - - - - tic; inv(P); toc - tic; inv(Q); toc - -tic; inv(G); toc - -tic; inv(H); toc - diff --git a/misc/matlab/unsorted/test_lag.m b/misc/matlab/unsorted/test_lag.m deleted file mode 100644 index ced6576..0000000 --- a/misc/matlab/unsorted/test_lag.m +++ /dev/null @@ -1,168 +0,0 @@ -function test_lag - - t_true = randn(2,1)*4; - theta_true = deg2rad(rand*90-45); - theta_true = deg2rad(170); - pose_true = [t_true; theta_true]; - - x_true = [t_true; cos(theta_true); sin(theta_true)]; - - N=400 - points1 = rand(2,N); - %points1 = [-1 -1; -1 1; 1 1; 1 -1]'; - points2 = rot(theta_true) * points1 + repmat(t_true,1,N) ; - points2 = points2 + 0.01*randn(2,N); - - f=figure; - plot_lambda(points1,points2,-70:0.1:20); - - - f = figure; - hold on - plotVectors([0;0;0], points1, 'k.'); - plotVectors([0;0;0], points2, 'g.'); - axis('equal'); - - tic - [pose, L, Y] = exact_minimization_cf(points1,points2); - toc - - e_t = pose(1:2)-t_true - e_th = rad2deg(pose(3)-theta_true) - - plotVectors(pose, points1, 'r.'); - hold off; - -function plot_lambda(points1,points2,interval) - [L,Y] = create_system(points1, points2); - ls = interval; - size(ls,2) - for i=1:size(ls,2) - fu(i) = constraint({L'*L,L'*Y}, ls(i)); - end - - pos_index = find(fu>0); - neg_index = find(fu<0); - - f = figure; - hold on - plot(ls(pos_index), fu(pos_index), 'b.'); - plot(ls(neg_index),fu(neg_index),'r.'); - hold off; - - -function pose = exact_minimization(points1, points2) - [L,Y] = create_system(points1,points2); - - M = diag([0 0 1 1]); - A = (L'*L); - B = L'*Y; - lA = A(1:2,1:2); - lB = A(1:2,3:4); - lC = A(3:4,3:4); - - S = lC - lB' * inv(lA) * lB - e = eig(S); - start = - e(1) - big_interval = 20; - small_interval = 0.01; - - lambda_right = rfBisection('constraint', {L'*L,L'*Y}, ... - start+small_interval, start+big_interval, 0.00000001) - lambda_left = rfBisection('constraint', {L'*L,L'*Y}, ... - start-big_interval, start-small_interval, 0.00000001) - - L2 = (L'*L + lambda_right * M); - Y2 = L'*Y; - x_hat = inv(L2) * Y2; - - theta_hat = atan2(x_hat(4),x_hat(3)); - pose = [x_hat(1); x_hat(2); theta_hat]; - - -function [L,Y] = create_system(points1, points2) - N = size(points1,2); - L = zeros(2*N,4); - Y = zeros(2*N,1); - for i=1:N - for j=max(1,i):min(i,N) - p_i = points1(:,i); - p_j = points2(:,j); - Lk = [ eye(2) p_i rot(pi/2)*p_i ]; - Yk = p_j; - - L((i-1)*2+1:(i-1)*2+2,1:4) = Lk; - Y((i-1)*2+1:(i-1)*2+2,1) = Yk; - end - end - -function [pose, L, Y] = exact_minimization_cf(points1, points2) - [L,Y] = create_system(points1,points2); - - B = L'*Y; - x1 = B(1:2); - x2 = B(3:4); - - A = (L'*L); - lB = A(1:2,3:4); - bt=lB'*lB; - b=bt(1,1); - - % closed form solution - n = A(1,1); - c = A(3,3); - - pol = [ (b* x1'*x1+n^2 * x2'*x2 -2*n*x1'*lB*x2) 0 (-1)]; - r = roots(pol); - la1 = (1/n) * (1/r(1) -n*c+b); - la2 = (1/n) * (1/r(2) -n*c+b); - - M = diag([0 0 1 1]); - L2 = (L'*L + la1 * M); - Y2 = L'*Y; - x_hat = inv(L2) * Y2; - - theta_hat = atan2(x_hat(4),x_hat(3)); - pose = [x_hat(1); x_hat(2); theta_hat]; - - -function m = constraint(params, la) - A = params{1}; - B = params{2}; - M = diag([0 0 1 1]); - m = B' * inv(A+la*M)'*M*inv(A+la*M)*B - 1; - -function root = rfBisection( func, func_params, a, b, epsilon) - - f_a = feval(func, func_params, a); - f_b = feval(func, func_params, b); - - s = sign(f_a) * sign(f_b); - if not ( s == -1 ) - error('Sign is equal for a = %g ( f(a)=%g ) and b = %g ( f(b)=%g ) ', a, f_a, b, f_b); - end - - fprintf('Root finding (Bisection method)\n'); - fprintf(' k\t a \t b \t c \t b-c \t f(c)\n'); - k = 1; - while 1 - c = a + (b-a)/2; - - f_b = feval(func, func_params, b); - f_c = feval(func, func_params, c); - fprintf(' %d\t%.6g\t%.6g\t%.6g\t%.6g\t%.6g\n', k, a, b, c, b-c, f_c) - - if b - c <= epsilon - root = c; - break - end - - if sign(f_b) * sign(f_c) <= 0 - a = c; - else - b = c; - end - - k = k+1; - end - diff --git a/misc/matlab/unsorted/test_yasmine.m b/misc/matlab/unsorted/test_yasmine.m deleted file mode 100644 index 2bb1959..0000000 --- a/misc/matlab/unsorted/test_yasmine.m +++ /dev/null @@ -1,28 +0,0 @@ -function res = test_yasmine(k) - -sigma=0.00001; - - S=load('logs/bighouse_half.mat'); - log = S.log_bighouse_half; - - params.laser_ref = log{k}; - params.laser_ref = add_noise(params.laser_ref, sigma); - params.laser_sens = log{k}; - params.laser_sens = add_noise(params.laser_sens, sigma); - params.maxAngularCorrectionDeg = 15; - params.maxLinearCorrection = 0.5; - params.sigma = sigma; - res.params = params; - - tic - result = yasmine2(params); - toc - - res.result = result; - - -function res = add_noise(ld, sigma) - res = ld; - res.readings = res.readings + sigma * randn(1,res.nrays); - res.points = [res.readings .* cos(res.theta); res.readings .* sin(res.theta)]; - res = computeSurfaceNormals_sound(res); diff --git a/misc/matlab/unsorted/test_yasmine2.m b/misc/matlab/unsorted/test_yasmine2.m deleted file mode 100644 index 35328b5..0000000 --- a/misc/matlab/unsorted/test_yasmine2.m +++ /dev/null @@ -1,56 +0,0 @@ -function res = test_yasmine2(k) - - %x_true = [1;-2;deg2rad(-10.5)]; - %x_true = [0.2;0;deg2rad(5.5)]; - %ts = ts_square(8, [1;-4;0], x_true); - %ts = ts_flower(4, 1, 10, [0;0;0], x_true); - - x_true = [1;0;0]; - ts = ts_flower(4, .5, 10, [0;0;0], x_true); - sigma=0.005; - odometry_cov = diag( [0.2 0.2 deg2rad(5)].^2 ); - - ts.laser_ref = add_noise(ts.laser_ref, sigma); - ts.laser_sens = add_noise(ts.laser_sens, sigma); - ts.laser_sens.estimate = [0;0;0]; - ts.laser_sens.odometry = [0;0;0]; - - - ts.maxAngularCorrectionDeg = 40; - ts.maxLinearCorrection = 2; - ts.sigma = sigma; - - ts.odometry = sample_normal(x_true, odometry_cov, 1) - ts.odometry_cov = odometry_cov; - - ts.trim = 0.05; - ts.chi_perc = 0.95; - ts.chi_limit = 20; - - tic - result = yasmine2(ts); - toc - - res.result = result; - res.ts = ts; - - e = res.result.x_hat - x_true - - f = figure; - params.plotNormals = true; - params.rototranslated = true; - - params.color = 'b.'; - plotLaserData(ts.laser_ref, params); - params.color = 'r.'; - ld2 = ts.laser_sens; - ld2.estimate = rtcat(ts.laser_ref.estimate, result.x_hat); - plotLaserData(ld2, params); - - axis('equal'); - -function res = add_noise(ld, sigma) - res = ld; - res.readings = res.readings + sigma * randn(1,res.nrays); - res.points = [res.readings .* cos(res.theta); res.readings .* sin(res.theta)]; - res = computeSurfaceNormals_sound(res); diff --git a/misc/matlab/unsorted/test_yasmine3.m b/misc/matlab/unsorted/test_yasmine3.m deleted file mode 100644 index ba0ba63..0000000 --- a/misc/matlab/unsorted/test_yasmine3.m +++ /dev/null @@ -1,42 +0,0 @@ -function res = test_yasmine3(k) - % systematic experiments - - x_true = [1;0;deg2rad(-10.5)]; - ts0 = ts_square(8, [1;-2;deg2rad(10)], x_true ); -% ts0 = ts_flower(8, 2, 10, [0;0;0], x_true); - sigma=0.005; - odometry_cov = diag( [0.2 0.2 deg2rad(5)].^2 ); - - odometry_cov = diag( [0.5 0.5 deg2rad(5)].^2 ); - - N = 50; - - for i=1:N - ts{i} = ts0; - - ts{i}.input.laser_ref = add_noise(ts0.laser_ref, sigma); - ts{i}.input.laser_sens = add_noise(ts0.laser_sens, sigma); - - ts{i}.input.maxAngularCorrectionDeg = 40; - ts{i}.input.maxLinearCorrection = 2; - ts{i}.input.sigma = sigma; - - ts{i}.input.trim = 0.05; - ts{i}.input.chi_perc = 0.95; - ts{i}.input.chi_limit = 50; - ts{i}.input.odometry = sample_normal(x_true, odometry_cov, 1); - ts{i}.input.odometry_cov = odometry_cov; - - tic - ts{i}.output = yasmine2(ts{i}.input); - toc - - end - - res = ts; - -function res = add_noise(ld, sigma) - res = ld; - res.readings = res.readings + sigma * randn(1,res.nrays); - res.points = [res.readings .* cos(res.theta); res.readings .* sin(res.theta)]; - res = computeSurfaceNormals_sound(res); diff --git a/misc/matlab/unsorted/test_yasmine3_an.m b/misc/matlab/unsorted/test_yasmine3_an.m deleted file mode 100644 index 0312274..0000000 --- a/misc/matlab/unsorted/test_yasmine3_an.m +++ /dev/null @@ -1,8 +0,0 @@ -function [dist,white] = test_yasmine3_an(f) - - for i=1:size(f,2) - dist(:,i) = f{i}.output.x_hat; - cov = f{i}.output.Cov; - A = inv(chol(cov))'; - white(:,i) = A * (f{i}.output.x_hat-[1;0;-10.5]); - end diff --git a/misc/matlab/utils/deriv.m b/misc/matlab/utils/deriv.m deleted file mode 100644 index 9f37d19..0000000 --- a/misc/matlab/utils/deriv.m +++ /dev/null @@ -1,10 +0,0 @@ -%% Numerical derivation with step \verb|epsilon| -function res = deriv(fh, x, epsilon) - % deriv(fh, x, epsilon) - % fh: function handle - % x: point to derive - % epsilon: interval - f1 = fh(x+epsilon/2); - f0 = fh(x-epsilon/2); - res= (f1-f0)/epsilon; - diff --git a/misc/matlab/utils/file_exists.m b/misc/matlab/utils/file_exists.m deleted file mode 100644 index 6b2c36c..0000000 --- a/misc/matlab/utils/file_exists.m +++ /dev/null @@ -1,8 +0,0 @@ -function res = file_exists(filename) - fid = fopen(filename); - if -1 == fid - res = false; - else - res = true; - fclose(fid); - end diff --git a/misc/matlab/utils/normAngle.m b/misc/matlab/utils/normAngle.m deleted file mode 100644 index 24cdc60..0000000 --- a/misc/matlab/utils/normAngle.m +++ /dev/null @@ -1,13 +0,0 @@ -function res = normAngle(theta) - - for i=1:size(theta,2) - while theta(i)>pi - theta(i) = theta(i) - 2*pi; - end - - while theta(i)<-pi - theta(i) = theta(i) + 2*pi; - end - end - -res = theta; \ No newline at end of file diff --git a/misc/matlab/utils/params_required.m b/misc/matlab/utils/params_required.m deleted file mode 100644 index 77f7a7e..0000000 --- a/misc/matlab/utils/params_required.m +++ /dev/null @@ -1,6 +0,0 @@ - -function params_required(p, field) - if not(isfield(p, field)) - error('icp:bad_paramater',sprintf('I need field %s.', field)); - end - diff --git a/misc/matlab/utils/params_set_default.m b/misc/matlab/utils/params_set_default.m deleted file mode 100644 index d1f3a62..0000000 --- a/misc/matlab/utils/params_set_default.m +++ /dev/null @@ -1,10 +0,0 @@ -function res = params_set_default(p, field, default_value) - % Checks whether the field is contained in p; if not, it adds the default_value. - if not(isfield(p, field)) - p = setfield(p, field, default_value); - % fprintf('Setting default for %s = ', field); - % fprintf('%f ', default_value); - % fprintf('\n'); - end - res = p; - diff --git a/misc/matlab/utils/pv.m b/misc/matlab/utils/pv.m deleted file mode 100644 index 0f5630c..0000000 --- a/misc/matlab/utils/pv.m +++ /dev/null @@ -1,15 +0,0 @@ -function s = pv(v) -% prints v=(x,y,theta) as a string, with theta in degrees - -if size(v,1)==3 -s= sprintf('(%f,%f,%f)', v(1), v(2), rad2deg(v(3))); -end - -if size(v,1)==2 -s= sprintf('(%f,%f)', v(1), v(2)); -end - -if size(v,1)==1 -s= sprintf('(%f)', v(1)); -end - diff --git a/misc/matlab/utils/rot.m b/misc/matlab/utils/rot.m deleted file mode 100644 index 06ea72f..0000000 --- a/misc/matlab/utils/rot.m +++ /dev/null @@ -1,3 +0,0 @@ -function r=rot(theta) -% rot(theta) rotation matrix of order two - r = [cos(theta) -sin(theta); sin(theta) cos(theta)]; diff --git a/misc/matlab/utils/transform.m b/misc/matlab/utils/transform.m deleted file mode 100644 index c471b33..0000000 --- a/misc/matlab/utils/transform.m +++ /dev/null @@ -1,5 +0,0 @@ - -function point = transform(point, dx) -% rotate then translate point - point = dx(1:2,1) + rot(dx(3)) * point; - diff --git a/misc/matlab/utils/vers.m b/misc/matlab/utils/vers.m deleted file mode 100644 index 3c3c2fd..0000000 --- a/misc/matlab/utils/vers.m +++ /dev/null @@ -1,4 +0,0 @@ -function v = vers(theta) -% returns 2d versor of direction theta - v = [cos(theta); sin(theta)]; - diff --git a/misc/matlab/vis/createAnimation.m b/misc/matlab/vis/createAnimation.m deleted file mode 100644 index a7699e0..0000000 --- a/misc/matlab/vis/createAnimation.m +++ /dev/null @@ -1,41 +0,0 @@ -function createAnimation0(lds, filename, makeVideo) - - horizon = 3; - fps=5; - - % Settings for video - fig1=figure; - winsize= get(fig1,'Position'); - winsize(1:2) = [0 0]; - outfile=sprintf('%s',filename); - mov=avifile(outfile, 'fps', fps, 'quality', 75); - %set(fig1, 'NextPlot', 'replacechildren'); - - set(fig1,'DoubleBuffer','on'); - - n = size(lds,2); - for i=1:n - if i>1 & ( vectorNorm2(lds(i).odometry-lds(i-1).odometry) < 0.01 ) - continue - end - - clf - hold on; - plotLaserData(lds(i)); - axis('equal'); - hold off - - %axis([0 horizon -horizon horizon]); - - if makeVideo - % Add frame to movie - mov = addframe(mov,getframe); - end - - % update the screen - drawnow - end - - - % That's all, folks! - mov = close(mov); diff --git a/misc/matlab/vis/ld_plot.m b/misc/matlab/vis/ld_plot.m deleted file mode 100644 index 3a6a424..0000000 --- a/misc/matlab/vis/ld_plot.m +++ /dev/null @@ -1,135 +0,0 @@ - -function res = ld_plot(ld, params) -% plotLaserData(ld, params) -% Draws on current figure -% -% params.plotNormals = false; -% params.color = 'r.'; -% params.rototranslated (= true); if true, the scan is drawn -% rototranslated at ld.estimate, else is drawn at 0; -% params.rototranstated_odometry = false; -% -% ld.dr -> tangent vector - - ld.points = [ cos(ld.theta') .* ld.readings'; sin(ld.theta').* ld.readings']; - - if(nargin==1) - params.auto = false; - end - - - params = params_set_default(params, 'plotNormals', false); - params = params_set_default(params, 'color', 'r.'); - - params = params_set_default(params, 'rototranslated', true); - params = params_set_default(params, 'rototranslated_odometry', false); - - params = params_set_default(params, 'plot_true_alpha', false); - params = params_set_default(params, 'plot_true_alpha_length', 0.4); - params = params_set_default(params, 'plot_true_alpha_color', 'g-'); - - params = params_set_default(params, 'plot_rays', false); - params = params_set_default(params, 'plot_rays_color', 'b-'); - params = params_set_default(params, 'plot_rays_interval', 10); - - if(params.rototranslated_odometry) - reference = ld.odometry; - else - if(params.rototranslated) - reference = ld.estimate; - else - reference = [0 0 0]'; - end - end - - if isnan(reference(1)) || isnan(reference(2)) || isnan(reference(3)) - fprintf('ld_plot: Invalid reference.\n'); - return; - end - - hold on - - if isfield(ld,'valid') == 0 - ld.valid = ones(ld.nrays,1); - end - - for i=1:ld.nrays - if 0 == ld.valid(i) - continue - end - theta = ld.theta(i); - readings = ld.readings(i); - p = readings*[cos(theta);sin(theta)]; - plotVectors(reference, p, params.color); - end - -% res.points = plotVectors(reference, ld.points, params.color); - - if params.plot_rays - for i=1:params.plot_rays_interval:ld.nrays - plotVectors(reference, [0 0; ld.points(:,i)']', params.plot_rays_color); - end - end - - if params.plotNormals - % disegno normali - maxLength = 0.1; - - valids = find(ld.alpha_valid); - if not(isfield(ld,'alpha_error')) - ld.alpha_error = ones(1, ld.nrays); - end - - valid_points = ld.points(:,valids); - valid_alpha = ld.alpha(valids); - valid_errors = rad2deg(sqrt(ld.alpha_error(valids)));; - emin = min(valid_errors); - emax = max(valid_errors); - - for i=1:size(valids,1) - %weight = 1 + valid_errors(i) * maxLength; - weight = maxLength; - - alpha = valid_alpha(i); - v = [cos(alpha); sin(alpha)] * weight; - from = valid_points(:,i); - to = from + v; - plotVectors( reference, [from to] , 'g-'); - end - end - - if params.plot_true_alpha - % disegno normali - length = params.plot_true_alpha_length; - color = params.plot_true_alpha_color; - - for i=1:ld.nrays - v = [cos(ld.true_alpha(i)); sin(ld.true_alpha(i))] * length; - from = ld.points(:,i); - to = from + v; - plotVectors( reference, [from to] , color); - end - end - - if isfield(ld,'dr') - % disegno normali - maxLength = 0.3; - - dr = ld.dr / max(abs(ld.dr)) * maxLength; - - for i=1:ld.nrays - theta = ld.theta(i); - readings = ld.readings(i); - alpha = ld.alpha(i); - - %len = [cos(theta);sin(theta)]' * [cos(alpha);sin(alpha)] * dr(i); - %dir = alpha; - len = dr(i); - dir = theta; - - from = readings*[cos(theta);sin(theta)]; - to = from + [cos(dir);sin(dir)] * len; - plotVectors( reference, [from to] , 'g-'); - end - end - diff --git a/misc/matlab/vis/plot3bars.m b/misc/matlab/vis/plot3bars.m deleted file mode 100644 index 2049cb5..0000000 --- a/misc/matlab/vis/plot3bars.m +++ /dev/null @@ -1,18 +0,0 @@ -function plot3bars(x,col1,v_alpha,d,col2,col3) - -col1 -col2 -col3 - hold on; - plot3(x(1,:),x(2,:),x(3,:),col1); - - %% Now project x along plane - - y = repmat(d*v_alpha,1,size(x,2)) + (eye(3)-v_alpha*v_alpha') * x; - size(y,2) - - for i=1:size(y,2) - plot3( [x(1,i) y(1,i)],[x(2,i) y(2,i)],[x(3,i) y(3,i)],col3); - plot3( y(1,i),y(2,i), y(3,i),col2); - - end diff --git a/misc/matlab/vis/plotGPM1.m b/misc/matlab/vis/plotGPM1.m deleted file mode 100644 index e97301f..0000000 --- a/misc/matlab/vis/plotGPM1.m +++ /dev/null @@ -1,25 +0,0 @@ -function plotGPM1(result) - hold on - - n = size(result.T, 2); - - for i=1:n - if result.weight(i) < 0.8 - continue - end - - T = result.T(:, i); - phi = result.phi(i); - gamma = result.alpha(i); - - length = 0.5; - p1 = T + vers(gamma-pi/2) * length; - p2 = T + vers(gamma+pi/2) * length; - - plot([p1(1) p2(1)],[p1(2) p2(2)],'b-'); - %plot(T(1),T(2),'r.'); - - end - -function v = vers(theta) - v = [cos(theta) sin(theta)]'; diff --git a/misc/matlab/vis/plotGauss2Db.m b/misc/matlab/vis/plotGauss2Db.m deleted file mode 100644 index ab786c9..0000000 --- a/misc/matlab/vis/plotGauss2Db.m +++ /dev/null @@ -1,30 +0,0 @@ -% Non disegna il punto -function res = plotGauss2Db(mu,sigma,color) - -if (size(mu,2) ~= 1) - mu = mu'; - if (size(mu,2) ~= 1) - error('mu deve essere un vettore'); - end -end -if (size(mu,2) ~= 1) - error('mu deve essere un vettore bidimensionale'); -end -if (size(sigma,1) ~= size(sigma,2)) - error('sigma deve essere quadrata'); -end -if (size(sigma,1) ~= 2) - error('la funzione plotGauss2D serve solo per plottare in 2 dimensioni'); -end - -res = ellipse(mu,sigma,color); - -function res = ellipse(mean,Sigma,color) - MahlDist = 6; - npoints = 100; - % Prende un cerchio e fa una trasformazione affine - theta=(0:1:npoints)*(2*pi/npoints); - [V,D] = eig(Sigma); - points= repmat(mean,1,npoints+1) + ... - V * sqrt(D) * sqrt(MahlDist) * [cos(theta); sin(theta)]; - res = plot(points(1,:),points(2,:),color); diff --git a/misc/matlab/vis/plotLaserData.m b/misc/matlab/vis/plotLaserData.m deleted file mode 100644 index 9239b1b..0000000 --- a/misc/matlab/vis/plotLaserData.m +++ /dev/null @@ -1,52 +0,0 @@ -function plotLaserData(ld, params) -% plotLaserData(ld, params) -% Draws on current figure -% -% params.plotNormals = false; -% params.color = 'r.'; -% params.rototranslated (= true); if true, the scan is drawn -% rototranslated at ld.estimate, else is drawn at 0; -% params.rototranstated_odometry = false; - - if(nargin==1) - params.plotNormals = false; - params.color = 'r.'; - params.rototranslated = true; - params.rototranslated_odometry = false; - end - - if(params.rototranslated_odometry) - reference = ld.odometry; - else - if(params.rototranslated) - reference = ld.estimate; - else - reference = [0 0 0]'; - end - end - - hold on - - plotVectors(reference, ld.points, params.color); - - if params.plotNormals - % disegno normali - maxLength = 0.05; - - valids = find(ld.alpha_valid); - - valid_points = ld.points(:,valids); - valid_alpha = ld.alpha(valids); - valid_errors = rad2deg(sqrt(ld.alpha_error(valids)));; - emin = min(valid_errors); - emax = max(valid_errors); - - for i=1:size(valids,2) - weight = 1 + valid_errors(i) * maxLength; - - v = [cos(valid_alpha(i)); sin(valid_alpha(i))] * weight; - from = valid_points(:,i); - to = from + v; - plotVectors( reference, [from to] , 'g-'); - end - end diff --git a/misc/matlab/vis/plotVectors.m b/misc/matlab/vis/plotVectors.m deleted file mode 100644 index e839aa2..0000000 --- a/misc/matlab/vis/plotVectors.m +++ /dev/null @@ -1,15 +0,0 @@ - -function handle = plotVectors(ref, points, color) - % TODO: add check on dimensions - t = ref(1:2); - points2 = rot(ref(3)) * points; - - %size(points) - %t - %repmat(t,1,size(points,2)) - %size(repmat(t,1,size(points,2))) - %size(points2) - - points2 = points2 + repmat(t,1,size(points,2)); - handle = plot(points2(1,:),points2(2,:),color); - diff --git a/misc/matlab/vis/plot_xyt.m b/misc/matlab/vis/plot_xyt.m deleted file mode 100644 index ef0591a..0000000 --- a/misc/matlab/vis/plot_xyt.m +++ /dev/null @@ -1,126 +0,0 @@ - -function fs = plot_xyt(m) - - p.datasets = m.datasets; - p.covariances = m.covariances; - p.scale = diag([1000 1000 180/pi]); - p.format = m.format; - p.legend = m.legend; - - - p.use_legend = true; - - p.select = [1 0 0; 0 1 0];; - p.equal = true; - p.xlabel = 'x (mm)'; - p.ylabel = 'y (mm)'; - p.title = sprintf('%s x, y',m.title); - p.filename = sprintf('%s_xy.%s',m.prefix,m.extension); - f1= draw_data_single(p); - - p.use_legend = false; - - p.select = [1 0 0; 0 0 1]; - p.equal = false; - p.xlabel = 'x (mm)'; - p.ylabel = '\theta (deg)'; - p.title = sprintf('%s x, \\theta',m.title); - p.filename = sprintf('%s_xt.%s',m.prefix,m.extension); - f2=draw_data_single(p); - - p.select = [0 0 1; 0 1 0]; - p.equal = false; - p.xlabel = '\theta (deg)'; - p.ylabel = 'y (mm)'; - p.title = sprintf('%s \\theta, y',m.title); - p.filename = sprintf('%s_ty.%s',m.prefix,m.extension); - - f3=draw_data_single(p); - - fs=[f1 f2 f3]; - -function f = draw_data_single(p) - f = figure; - - fsize = 7; - set(f,'Units','centimeters'); - set(f,'Position',[0 0 fsize fsize]); - set(f,'PaperUnits','centimeters'); - set(f,'PaperPosition',[0 0 fsize fsize]); - set(f,'PaperSize',[fsize fsize]) - - hold on; - select = p.select; - scale = p.scale; - for i=1:size(p.datasets,2) - points = p.datasets{i}.points; - color = p.datasets{i}.color; - my_points(plot_points( select*scale*points, color )); - end - - for i=1:size(p.covariances,2) - mean = p.covariances{i}.mean; - cov = p.covariances{i}.cov; - color = p.covariances{i}.color; - bold_lines(plotGauss2Db(select*scale*mean, ... - select*scale*cov*scale'*select', color)); - end - - if p.use_legend - l = legend(p.legend); - set(l, 'Orientation', 'vertical'); - set(l, 'Location','NorthWest'); - %get(l) - my_fonts(l); - end - - if p.equal - axis('equal'); - end - - my_fonts(xlabel(p.xlabel)); - my_fonts(ylabel(p.ylabel)); - my_fonts_large(title(p.title)); - my_fonts_small(gca); - - for i=1:size(p.covariances,2) - mean = p.covariances{i}.mean; - color = p.covariances{i}.color; - bold_lines(plot_cross(select*scale*mean,color)); - end - - print(p.format,p.filename); - -function res = plot_points(points, color) - res = plot(points(1,:),points(2,:),color); - -function res = plot_cross(mean, color) - A = axis; - res(1) = plot([A(1) A(2)],[mean(2) mean(2)],color); - res(2) = plot([mean(1) mean(1)], [A(3) A(4)],color); - %res - %size(res) - -function bold_lines(h) - for i=1:size(h,2) - set(h(i), 'LineWidth', 2); - end - -function my_fonts(h) - set(h, 'fontunits', 'points'); - set(h, 'fontsize', 10); - set(h, 'fontname', 'Times'); - -function my_fonts_large(h) - set(h, 'fontunits', 'points'); - set(h, 'fontsize', 10); - set(h, 'fontname', 'Times'); - -function my_fonts_small(h) - set(h, 'fontunits', 'points'); - set(h, 'fontsize', 9); - set(h, 'fontname', 'Times'); - -function my_points(h) - set(h,'MarkerSize',10); - diff --git a/misc/matlab/vis/plot_yasmine.m b/misc/matlab/vis/plot_yasmine.m deleted file mode 100644 index 0bde370..0000000 --- a/misc/matlab/vis/plot_yasmine.m +++ /dev/null @@ -1,32 +0,0 @@ -function plot_yasmine(f, mmin, mmax) - - - length = 0.5; - hold on - - % number of correspondences - Ktot = size(f.result.s, 2); - - drawn=0; - for k=1:Ktot - % if f.result.s{k}.m > mmax - % continue - % end - - drawn = drawn + 1; - - T = f.result.s{k}.T; - alpha = f.result.s{k}.alpha; - - p1 = T + vers(alpha-pi/2) * length; - p2 = T + vers(alpha+pi/2) * length; - - reference = f.ts.laser_ref.estimate; - plotVectors(reference, [p1 p2], 'b-'); - - end - - fprintf('drawn %d/%d\n', drawn, Ktot); - -function v = vers(theta) - v = [cos(theta) sin(theta)]'; diff --git a/misc/rsm/carmen2pic.rb b/misc/rsm/carmen2pic.rb deleted file mode 100644 index a29be0c..0000000 --- a/misc/rsm/carmen2pic.rb +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env ruby -require 'rsm' -require 'logreader' -require 'stringio' - -class LaserData - def valid_cartesian_points - (0..nrays-1).map{|i| - valid[i] ? p[i] : nil - }.compact - end -end - -module MathUtils - def transform_vector(v, x) - v.map{|p| transform(p,x) } - end - - def compute_bbox(points) - points = points.compact - bmin = Vector[points[0][0],points[0][1]].col - bmax = Vector[points[0][0],points[0][1]].col - points.each {|p| - bmin[0] = min(bmin[0], p[0]) - bmin[1] = min(bmin[1], p[1]) - bmax[0] = max(bmax[0], p[0]) - bmax[1] = max(bmax[1], p[1]) - } - return bmin, bmax - end -end - -require 'cairo' - -class Canvas - def initialize(output, bbox_min, bbox_max) - @bmin = bbox_min - @bmax = bbox_max - - format = Cairo::FORMAT_ARGB32 - @width = 500 - @height = @width *( @bmax[1]-@bmin[1])/( @bmax[0]-@bmin[0]) - @output = StringIO.new - surface = Cairo::PDFSurface.new(output, @width, @height) - @cr = Cairo::Context.new(surface) - - # fill background with white - @cr.set_source_rgba(1.0, 1.0, 1.0, 0.8) - @cr.paint - - @cr.set_line_join(Cairo::LINE_JOIN_MITER) - @cr.set_line_width 1 - - @colors = [ - [1,0,0],[0.8,0,0],[0.7,0,0],[0.6,0,0],[0.5,0,0], - [0,1,0],[0,0.8,0],[0,0.7,0],[0,0.6,0],[0,0.5,0], - ] - @current_color = 0 - next_color - end - - def save - @cr.show_page - - @cr.target.finish -# @cr.target.write_to_png(file) - end - - def w2b(p) - x = (p[0] - @bmin[0]) / (@bmax[0]-@bmin[0]) * @width - y = (p[1] - @bmin[1]) / (@bmax[1]-@bmin[1]) * @height - [x, y] - end - - def move_to(p) - buf = w2b(p) - @cr.move_to(buf[0],buf[1]) - end - - def line_to(p) - buf = w2b(p) - @cr.line_to(buf[0],buf[1]) - end - - def next_color - @current_color = (@current_color+1) % @colors.size - rgb = @colors[@current_color] - @cr.set_source_rgb(rgb[0],rgb[1],rgb[2]) - end - - def write_points(points) - return if points.empty? - @cr.set_line_cap(Cairo::LINE_CAP_ROUND) - @cr.set_line_width(1) - next_color - move_to(w2b(points[0])) - points.each do |p| - b = w2b(p) -# @cr.arc( b[0], b[1], 1, 0, 2*M_PI); -# @cr.fill - @cr.move_to(b[0],b[1]) - @cr.close_path - @cr.stroke - end - end - def cr; @cr end -end - -def carmen2pic(input,output_file) - include MathUtils - - count = 0; interval = 10 - lds = [] - until input.eof? - ld = LogReader.shift_laser(input) - - break if ld.nil? - - if count%interval == 0 - puts count - lds.push ld - end - count+=1 - end - - puts "Read #{lds.size} laser scans." - - bbox_min = nil - bbox_max = nil - all_points = [] - - lds.each_index do |i| - ld = lds[i] - ld.compute_cartesian - points = ld.valid_cartesian_points - points = transform_vector(points, ld.estimate) - bbox_min, bbox_max = compute_bbox(points+[bbox_min,bbox_max]) - all_points << points - end - puts "bbox: #{bbox_min.row} to #{bbox_max}" - - output = File.open(output_file ,"wb") - ca = Canvas.new(output, bbox_min, bbox_max) - - ca.cr.set_line_width(2) - ca.move_to(lds[0].estimate) - lds.each_index do |i| - ca.line_to(lds[i].estimate) - end - ca.cr.stroke - - lds.each_index do |i| - ca.write_points(all_points[i]) - end - - ca.save() -end - -if ARGV.size < 2 - puts "carmen2pic <input> <output> " - exit 1 -end - - -input = File.open ARGV[0] -output_file = ARGV[1] - -carmen2pic(input,output_file) diff --git a/misc/rsm/fix_json.rb b/misc/rsm/fix_json.rb deleted file mode 100644 index 6b1414f..0000000 --- a/misc/rsm/fix_json.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'strscan' - -require 'json/pure' - -# This allows to parse multiple objects from the same stream. - -class Float - - def to_json(*) - return 'null' if nan? - if not inf = infinite? - return to_s - else - return to_s.to_json - end - end -end - -module JSON - module Pure - - class Parser - def initialize(source, opts = {}) - super - if !opts.key?(:max_nesting) # defaults to 19 - @max_nesting = 19 - elsif opts[:max_nesting] - @max_nesting = opts[:max_nesting] - else - @max_nesting = 0 - end - @create_id = JSON.create_id - reset - end - - - # Parses the current JSON string _source_ and returns the complete data - # structure as a result. - def parse - obj = nil - until eos? || obj - case - when scan(OBJECT_OPEN) - obj and raise ParserError, "source '#{peek(20)}' not in JSON!" - @current_nesting = 1 - obj = parse_object - when scan(ARRAY_OPEN) - obj and raise ParserError, "source '#{peek(20)}' not in JSON!" - @current_nesting = 1 - obj = parse_array - when skip(IGNORE) - ; - else - raise ParserError, "source '#{peek(20)}' not in JSON!" - end - end - obj or raise ParserError, "source did not contain any JSON!" - obj - end - - end - - end -end - diff --git a/misc/rsm/json_utils.rb b/misc/rsm/json_utils.rb deleted file mode 100644 index 2e02c93..0000000 --- a/misc/rsm/json_utils.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'fix_json' - -def read_all_objects(string, progress_string=nil) - a = [] - j = JSON::Pure::Parser.new(string) - while true - j.scan(/\s*/) - break if j.eos? - begin - a.push j.parse - $stderr.write progress_string if progress_string - rescue Exception => e - $stderr.puts "After #{a.size} objects: #{e}" - return a - end - end - a -end diff --git a/misc/rsm/lib/gpc.rb b/misc/rsm/lib/gpc.rb deleted file mode 100644 index f483247..0000000 --- a/misc/rsm/lib/gpc.rb +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env ruby - -# GPC: A library for the solution of General Point Correspondence problems. -# Copyright (C) 2006 Andrea Censi (andrea at censi dot org) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -require 'gsl' - -module GPC - include Math - include GSL - - class PointCorrespondence - attr_accessor :p - attr_accessor :q - attr_accessor :C - end - - DEBUG = false - - def GPC.gpc(corr) - - # First we put the problem in a quadratic+constraint form. - bigM = Matrix.alloc(4, 4).set_zero - g = Matrix.alloc(4, 1).set_zero - - for c in corr - bigM_k = Matrix[[1, 0, c.p[0], -c.p[1]], - [0, 1, c.p[1], c.p[0]]] - - bigM = bigM + 2*bigM_k.trans * c.C * bigM_k; - g = g - 2 * (c.q.trans.to_m(1,2) * c.C * bigM_k).trans; - if DEBUG - puts "M_k=\n#{bigM_k}\n" - puts "q_k=\n#{c.q}\n" - puts "C_k=\n#{c.C}\n" - puts "now M is \n#{bigM}\n" - puts "now g is \n#{g}\n" - end - end - - if DEBUG - puts "M=#{bigM}" - end - - # Partition M in 4 submatrixes: - # M = [A B; B' D] - mA = bigM.submatrix(0,0,2,2) - mB = bigM.submatrix(0,2,2,2) - mD = bigM.submatrix(2,2,2,2) - - mS = mD - mB.trans * mA.inv * mB; - mSa = mS.inv * mS.det; - - if DEBUG - puts "mA=#{mA}" - puts "mB=#{mB}" - puts "mD=#{mD}" - puts "mS=#{mS}" - puts "mSa=#{mSa}" - end - - # split g in two - g1 = g.submatrix(0,0,2,1) - g2 = g.submatrix(2,0,2,1) - - p2 = g1.trans*mA.inv*mB*4*mB.trans*mA.inv*g1 - - 2*g1.trans*mA.inv*mB*4*g2 + g2.trans*4*g2 - p1 = g1.trans*mA.inv*mB*4*mSa*mB.trans*mA.inv*g1 - - 2*g1.trans*mA.inv*mB*4*mSa*g2 +g2.trans*4*mSa*g2 - p0 = g1.trans*mA.inv*mB*mSa*mSa*mB.trans*mA.inv*g1 - - 2*g1.trans*mA.inv*mB*mSa*mSa*g2 + g2.trans*mSa*mSa*g2 - - - p_lambda = Poly[mS[0,0]*mS[1,1]-mS[1,0]*mS[0,1], 2*mS[0,0]+2*mS[1,1], 4] - - - p7 = Poly.alloc(p0[0,0],p1[0,0],p2[0,0]) - ptot = p7 - p_lambda * p_lambda - - r = ptot.roots - lambda = 0 - ## Find greatest real root - for i in 0..3 - root = r[i] - next if root.im!=0 - lambda = [lambda, root.real].max - end - - if DEBUG - puts "p = [#{p2} #{p1} #{p0}]" - puts "p_l = [#{p_lambda[2]} #{p_lambda[1]} #{p_lambda[0]}]" - q = p_lambda * p_lambda; - puts "p_l*p_l = #{q[4]}*x^4 +#{q[3]}*x^3 +#{q[2]}*x^2 +#{q[1]}*x +#{q[0]} " - puts "ptot = #{ptot}" - puts "roots = #{r[0]} #{r[1]} " - puts "lambda = #{lambda}" - end - - mW = Matrix[[0,0,0,0], - [0,0,0,0], - [0,0,1,0], - [0,0,0,1]] - x = -(bigM + 2 * lambda * mW).inv * g; - theta = Math.atan2(x[3,0],x[2,0]); - - return Vector.alloc(x[0,0],x[1,0],theta).col - end - -end - diff --git a/misc/rsm/logreader.rb b/misc/rsm/logreader.rb deleted file mode 100755 index b4493b6..0000000 --- a/misc/rsm/logreader.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'rsm_laserdata' - -class LogReader - QUIET = true - ShowProgress = true - - def LogReader.read_log(io) - events = Array.new - io.each_line do |l| - e = convert_line(l) - events.push(e) if not e.nil? - if ShowProgress then $stderr.write '.' end - end - events - end - - def LogReader.shift_laser(io) - until io.eof? - e = convert_line(io.gets) - return e if e.kind_of? LaserData - end - nil - end - - def LogReader.convert_line(l) - type = l.split[0] - - case type - when 'FLASER' - $stderr.write 'l' - ld = LaserData.convert_line(l); - return ld - else - unless QUIET then $stderr.puts "Type '#{type}' not found." end - return nil - end - end - -end - -#LogReader.read_log($stdin) diff --git a/misc/rsm/matlab_to_rbgsl.txt b/misc/rsm/matlab_to_rbgsl.txt deleted file mode 100644 index 27d1c12..0000000 --- a/misc/rsm/matlab_to_rbgsl.txt +++ /dev/null @@ -1,7 +0,0 @@ - - -I vettori sono righe, usare col. - -Bug bug_gsl.rb - -Si conta da 0 e non da 1 \ No newline at end of file diff --git a/misc/rsm/mt/mt.rb b/misc/rsm/mt/mt.rb deleted file mode 100755 index a869bc8..0000000 --- a/misc/rsm/mt/mt.rb +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env ruby - -require 'rsm_sm_loop' - - -class Panorama < LaserData - SIGMA = 0.005 - COMP_THRESHOLD = SIGMA * 5 - SCALE = 1 - - attr_accessor :parent - - def angle2ray(phi) - i = (phi-@min_theta) / (@max_theta-@min_theta) * @nrays - i = i.round - i < 0 || i >= @nrays ? nil : i - end - - def initialize(estimate, odometry) - super(721) - - @min_theta = -Math::PI - @max_theta = +Math::PI - for i in 0..@nrays-1 - @theta[i] = @min_theta + (@max_theta-@min_theta) * - i / (@nrays-1); - end - @estimate = estimate.clone - @odometry = odometry.clone - end - - def merge(ld) - count = 0 - ld.compute_cartesian - # pose of second scan in first scan's frame - diff = pose_diff(ld.estimate, self.estimate) - for i in 0 ... ld.nrays-1 - if not ld.valid? i -# $stderr.puts "Skipping #{i}" - next - end - # coordinates of point i of second scan - # relative to first scan frame - p = transform(ld.p[i], diff) - - phi = atan2(p[1], p[0]) - rho = p.nrm2 - - if j = angle2ray(phi) - old_rho = @readings[j] - new_rho = nil - - if old_rho.nan? - @readings[j] = rho - @cov_readings[j] = SIGMA**2; - @valid[j] = true -# $stderr.puts "#{i}: Init #{j}" - count += 1 - next - end - - compatible = (rho-old_rho).abs < COMP_THRESHOLD - if compatible - - dist = sin( (phi-@theta[j]).abs ) * rho - - cov_rho = (SIGMA**2) + (dist**2) / SCALE - cov_old_rho = @cov_readings[j] - cov_new_rho = 1 /( 1 / cov_old_rho + 1 / cov_rho) - new_rho = cov_new_rho * (old_rho / cov_old_rho + rho / cov_rho); - - @readings[j] = new_rho - @cov_readings[j] = cov_new_rho - count += 1 - end -# $stderr.puts "#{i} #{j}, #{old_rho} => #{new_rho}" - else -# $stderr.puts "#{i} no index for phi = #{phi}" - end - end - count - end - -end - - - -def quick_match(scan_matcher_klass, params, ref, sens, guess) - sm = scan_matcher_klass.new - sm.params = params - sm.params = params - sm.params[:laser_ref] = ref; - sm.params[:laser_sens] = sens; - sm.params[:firstGuess] = guess - res = sm.scan_matching - res -end - -def go_mt - if ARGV.size < 3 - puts "sm <SCANMATCHER> '[]' <input> <output> " - exit 1 - end - - scan_matcher_klass = eval ARGV[0] - scan_list = eval ARGV[1] - - #puts "Scan_list = #{scan_list}" - - input = File.open ARGV[2] - output = File.open(ARGV[3], "w") - output_scans = File.open(File.basename(ARGV[3]) + "_scans.log", "w") - - params = standard_parameters - - include MathUtils - - first = LogReader.shift_laser(input) - first.estimate = first.odometry - panorama = Panorama.new(first.estimate, first.odometry) - panorama.merge(first) - laser_ref = first - - results = [] - count = 0 - - until input.eof? - laser_sens = LogReader.shift_laser(input) - - res = quick_match(scan_matcher_klass, params, laser_ref, laser_sens, - pose_diff(laser_sens.odometry, laser_ref.odometry)) - break if not res[:valid] - error = res[:error] - - puts "mt: match laser_ref #{res[:nvalid]} #{res[:avg_error] } #{pv(res[:x])} " - - laser_sens.estimate = oplus(laser_ref.estimate, res[:x]) - - n = panorama.merge(laser_sens) - - if n < 200 - if parent = panorama.parent - guess = pose_diff(panorama.estimate, parent.estimate); - res = quick_match(scan_matcher_klass, params, parent, panorama, - guess) - if res[:valid] - delta = pose_diff(res[:x], guess) - puts "mt: Match with parent: #{res[:avg_error]} #{res[:nvalid]} #{pv(delta)}" - if (res[:avg_error] < 1) && (res[:nvalid] > 150) - puts "mt: parent-correct!" - panorama.estimate = oplus(panorama.estimate, delta) - laser_sens.estimate = oplus(laser_sens.estimate, delta) - end - end - end - - output.puts panorama.to_json - new_panorama = Panorama.new(laser_sens.estimate, laser_sens.odometry) - new_panorama.parent = panorama - new_panorama.merge(laser_sens) - panorama = new_panorama - count = 0 - puts "mt: new panorama ##{count}: error #{error}" - else - puts "mt: continuing ##{count}: error #{error}" - end - output_scans.puts laser_sens.to_json - - puts "mt: merged #{n}" - - laser_ref = laser_sens - count += 1 - end - -end - - -go_mt - - diff --git a/misc/rsm/mt/mt.sh b/misc/rsm/mt/mt.sh deleted file mode 100755 index a0042de..0000000 --- a/misc/rsm/mt/mt.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -inl=../../../experiments/mbicp_tro_experiment/laserazosSM3.log - -ruby -I.. -rrubygems -rsm -rsm_icp mt.rb Sm::ICPC '[]' $inl out.log 2>&1 diff --git a/misc/rsm/options.rb b/misc/rsm/options.rb deleted file mode 100644 index 09417e6..0000000 --- a/misc/rsm/options.rb +++ /dev/null @@ -1,113 +0,0 @@ - -require 'ostruct' -require 'optparse' - -class Options - Option = Struct.new(:name, :default, :description, :value) - - def initialize - @hash = {} - @order = [] - end - - def add(name, default, description) - @hash[name] = Option.new(name, default, description, nil) - @order.push @hash[name] - end - - - def populate(opts) - - opts.on("--config FILE", "Load config from file") do |file| - load_config_from_file(file) - end - - opts.on("--config_dump", "Dump config on stdout") do - $stdout.puts self.config_dump - exit 0 - end - - @order.each do |o| - s = o.default.inspect.ljust(25) - opts.on("--#{o.name} VALUE", "#{s} #{o.description}") do |s| - value = s - begin value = eval(s) - rescue SyntaxError => ex - rescue => ex - end - - @hash[o.name].value = value - end - end - - end - - def get_ostruct - r = {} - @hash.each do |k, v| - r[k] = v.value || v.default - end - OpenStruct.new r - end - - def config_dump - s = "" - max_size = @hash.keys.map{|x|x.to_s.size}.max + 2 - for o in @order - s += o.name.to_s.ljust(max_size) + (o.value || o.default).inspect + "\n" - end - s - end - - RegComment = /^\s*\#/ - RegOption = /^\s*(\w+)\s*=?\s*(.+)$/ - RegLoad = /^\s*(?:<|source)\s*(.*)$/ - - def load_config_from_file(file) - load_config_from_string(File.open(file).read, File.dirname(file)) - end - - def load_config_from_string(string, dir) - string.split("\n").each do |line| - next if (line.strip.size == 0) || line =~ RegComment - if m = RegOption.match(line) - name = m[1].to_sym - value = m[2].strip - - begin - value = eval(value) - rescue - end - - if o = @hash[name] - o.value = value -# $stderr.puts "#{name} = #{value}" - else - $stderr.puts "Unknown key #{name.inspect} (#{@hash.keys.inspect})" - end - elsif m = RegLoad.match(line) - filename = m[1] - filename = File.expand_path(File.join(dir, filename)) - read_conf(File.open(filename), File.dirname(filename)) - else - $stderr.puts "Line #{line.inspect} is malformed" - exit -1 - end - end - end - - def parse_cmd_line! - opt = OptionParser.new do |opts| - self.populate(opts) - end - - begin opt.parse! - rescue OptionParser::InvalidOption=>e - $stderr.puts e - $stderr.puts opt - exit -1 - end - end - - -end \ No newline at end of file diff --git a/misc/rsm/rsm.rb b/misc/rsm/rsm.rb deleted file mode 100644 index 8e9a7dc..0000000 --- a/misc/rsm/rsm.rb +++ /dev/null @@ -1,12 +0,0 @@ -#require 'gsl' - -require 'rsm_journal' -require 'rsm_mathutils' -require 'rsm_misc' -require 'rsm_orientation' -require 'rsm_laserdata' -require 'rsm_laserdata_ops' -require 'rsm_gpm' -require 'rsm_gpmicp' -require 'rsm_icp' - diff --git a/misc/rsm/rsm_clustering.rb b/misc/rsm/rsm_clustering.rb deleted file mode 100644 index f4c0514..0000000 --- a/misc/rsm/rsm_clustering.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'rsm' - -class LaserData - -def simple_clustering(threshold) - count = 0; - last_reading = nil; - for i in 0..nrays-1 - if not valid? i - @cluster[i] = -1 - next - end - - if (not last_reading.nil?) and - (last_reading-@readings[i]).abs > threshold - count += 1 - end - - @cluster[i] = count; - last_reading = @readings[i] - end -end - -end \ No newline at end of file diff --git a/misc/rsm/rsm_gpm.rb b/misc/rsm/rsm_gpm.rb deleted file mode 100644 index be5e5a5..0000000 --- a/misc/rsm/rsm_gpm.rb +++ /dev/null @@ -1,195 +0,0 @@ -require 'rsm' -require 'rsm_clustering' -require 'rsm_orientation' - -class GPM - include MathUtils - include Math - include Journal - attr_accessor :params - - def name; "GPM" end - - def scan_matching - laser_ref = params[:laser_ref] - laser_sens = params[:laser_sens] - u = params[:firstGuess] - - laser_ref.compute_cartesian - laser_ref.simple_clustering(params[:clustering_threshold]) - laser_ref.compute_orientation(params[:orientation_neighbourhood],params[:sigma]) - - laser_sens.compute_cartesian - laser_sens.simple_clustering(params[:clustering_threshold]) - laser_sens.compute_orientation(params[:orientation_neighbourhood],params[:sigma]) - - journal_laser 'laser_ref', laser_ref - journal_laser 'laser_sens',laser_sens - journal "odometry #{to_j(u)}" -# journal "odometry_cov #{to_j(params[:firstGuessCov])}" - - max_angular_correction_deg = params[:max_angular_correction_deg] - max_linear_correction =params[:max_linear_correction] - - theta_bin_size = deg2rad(5) - extend_range = deg2rad(15) - # Find multiple solutions for theta - hist = GSL::Histogram.alloc((2*PI/theta_bin_size).ceil, -PI, PI) - - ght_only_theta(u, max_linear_correction, max_angular_correction_deg, hist) - - hist.fprintf($stdout) - # find mode - max_bin = hist.max_bin - new_range = hist.get_range(max_bin) - new_range[0] += -extend_range - new_range[1] += +extend_range - puts "New extension: #{rad2deg(new_range[0])}° to #{rad2deg(new_range[1])}°" - u2 = u.clone; u2[2] = 0.5*(new_range[1]+new_range[0]); - - newAngularCorrectionDeg = rad2deg(0.5*(new_range[1]-new_range[0])) - matches2 = ght(u2, max_linear_correction,newAngularCorrectionDeg) - puts "Found #{matches2.size} matches." - result = solve_lse(matches2, u2, 6) - puts "Result #{pv(result)}." - - - - journal "iteration 0" - journal "x_old #{to_j(u)}" - journal "iteration 1" - journal "x_old #{to_j(u2)}" - journal "iteration 2" - journal "x_old #{to_j(result)}" - - - res = Hash.new - res[:x] = result - res[:iterations] = 0 - #res[:dx_dy1] = dx_dy1 - #res[:dx_dy2] = dx_dy2 - - return res - end - - def solve_lse(matches, x_old, iterations) - iterations.times do - z = Matrix.alloc(3,1); z.set_all(0); - w = Matrix.alloc(3,3); w.set_all(0); - for m in matches - v_alpha = vers(m.alpha) - # Y = L x - y = Matrix[ [v_alpha.trans * m.t], - [m.theta]]; - l = Matrix[ - [ v_alpha[0], v_alpha[1], 0], - [0, 0, 1]]; - weight = m.weight * exp(-(m.t-x_old[0,1]).nrm2**2 - 5 * (m.theta-x_old[2]).abs**2) - z = z + weight * l.trans * y; - w = w + weight * l.trans * l; - end - x = w.inv * z - x_old = Vector.alloc(x[0,0],x[1,0],x[2,0]) - puts "Iteration: #{pv(x_old)}" - end - x_old - end - - - - - class Match - attr_accessor :t - attr_accessor :theta - attr_accessor :alpha - attr_accessor :weight - end - - - def ght(x0,max_linear_correction,max_angular_correction_deg) - puts "ght: x0=#{x0}, limits: #{max_linear_correction}, #{max_angular_correction_deg}°" - laser_ref = params[:laser_ref]; - laser_sens = params[:laser_sens]; - - t0 = Vector[x0[0],x0[1]] - matches = Array.new - for i in 0..laser_sens.nrays-1 - next if not laser_sens.alpha_valid? i - - p_i = laser_sens.p[i] - alpha_i = laser_sens.alpha[i] - - from, to = possible_interval(p_i, laser_ref, - max_angular_correction_deg, max_linear_correction) - - for j in from..to - next if not laser_ref.alpha_valid? j - - p_j = laser_ref.p[j] - alpha_j = laser_ref.alpha[j] - - theta = angleDiff(alpha_j, alpha_i) - - next if (theta-x0[2]).abs > deg2rad(max_angular_correction_deg) - - t = p_j - rot(theta) * p_i; - - next if (t-t0).nrm2 > max_linear_correction - - m = Match.new - m.t = t; - m.theta=theta; - m.alpha = alpha_j - w = laser_ref.cov_alpha[j] + laser_sens.cov_alpha[i] - m.weight = 1/w - matches.push m - end - - end - - matches - end - - def ght_only_theta(x0,max_linear_correction,max_angular_correction_deg,hist) - laser_ref = params[:laser_ref]; - laser_sens = params[:laser_sens]; - - t0 = Vector[x0[0],x0[1]] - for i in 0..laser_sens.nrays-1 - next if not laser_sens.alpha_valid? i - - p_i = laser_sens.p[i] - alpha_i = laser_sens.alpha[i] - - from, to = possible_interval(p_i, laser_ref, - max_angular_correction_deg, max_linear_correction) - - for j in from..to - next if not laser_ref.alpha_valid? j - - p_j = laser_ref.p[j] - alpha_j = laser_ref.alpha[j] - - theta = angleDiff(alpha_j, alpha_i) - - next if (theta-x0[2]).abs > deg2rad(max_angular_correction_deg) - - t = p_j - rot(theta) * p_i; - - next if (t-t0).nrm2 > max_linear_correction - - hist.increment(theta) - end - - end - end - -end - - - - - - - - diff --git a/misc/rsm/rsm_gpmicp.rb b/misc/rsm/rsm_gpmicp.rb deleted file mode 100644 index ade8636..0000000 --- a/misc/rsm/rsm_gpmicp.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'sm_icp' -require 'sm_gpm' - -class GPM_then_ICP - attr_accessor :params - - def initialize - @params = Hash.new - @journal = nil - end - - def name - 'GPM+ICP' - end - - def journal_open(file) - @journal = file - end - - def scan_matching - gpm = Sm::GPMC.new - gpm.params = params - if not @journal.nil? - gpm.journal_open(@journal+"_gpm") - end - - res_gpm =gpm.scan_matching - - if not res_gpm[:valid] - $stderr.puts "GPM was not successful" - return res_gpm - end - gpm_x = res_gpm[:x] - - p res_gpm - puts "GPM_then_ICP: gpm res is #{pv(gpm_x)}" - icpc = Sm::ICPC.new - icpc.params = params; - icpc.params[:firstGuess] = gpm_x - - if not @journal.nil? - puts "opening" - icpc.journal_open(@journal+"_icp") - end - - res = icpc.scan_matching; - - res - end -end \ No newline at end of file diff --git a/misc/rsm/rsm_icp.rb b/misc/rsm/rsm_icp.rb deleted file mode 100644 index d147d26..0000000 --- a/misc/rsm/rsm_icp.rb +++ /dev/null @@ -1,174 +0,0 @@ - -require 'rsm' -require 'rsm_icp_corr_dumb' -require 'rsm_icp_corr_tricks' -require 'rsm_icp_cov_numeric' -require 'rsm_icp_cov_exact' -require 'lib/gpc.rb' - -class ICP - include GSL - include MathUtils - include Journal - include Math - - attr_accessor :params - - def initialize - @params = standard_parameters - end - - def name; "ICP" end - - def scan_matching - laser_ref = params[:laser_ref] - laser_sens = params[:laser_sens] - - laser_ref.compute_cartesian - laser_ref.simple_clustering(params[:clustering_threshold]) - laser_ref.compute_orientation(params[:orientation_neighbourhood],params[:sigma]) - - laser_sens.compute_cartesian - laser_sens.simple_clustering(params[:clustering_threshold]) - laser_sens.compute_orientation(params[:orientation_neighbourhood],params[:sigma]) - - laser_ref.create_jump_tables - - journal_laser 'laser_ref', laser_ref - journal_laser 'laser_sens', laser_sens - journal "odometry #{to_j(params[:firstGuess])}" - journal "odometry_cov #{to_j(params[:firstGuessCov])}" - - x_old = params[:firstGuess] - delta = Vector.alloc(0,0,0).col - - hashes = [] - for iteration in 1..params[:max_iterations] - journal "iteration #{iteration}" - journal "x_old #{to_j(x_old)}" - - if params[:use_corr_tricks] == 1 - find_correspondences_tricks(x_old) - else - find_correspondences(x_old) - end - - x_new = compute_next_estimate(x_old) - - sigma = params[:sigma] - - - journal "x_new #{to_j(x_new)}" - - new_delta = pose_diff(x_new, x_old) - journal "delta #{to_j(new_delta)}" - - puts "#{iteration} x_old = #{pv(x_old)} x_new = #{pv(x_new)} " - - delta = new_delta - - if delta[0,1].nrm2 < params[:epsilon_xy] && - delta[2].abs < params[:epsilon_theta] - break - end - - hash = laser_sens.correspondences_hash - if hashes.include? hash - cycle = hashes.size-hashes.find{|h|h==hash} - puts "Found cycle lenght = #{cycle}" - break - else - hashes.push hash - end - - x_old = x_new - end - - - dx_dy1=Matrix.alloc(3,laser_ref.nrays) - dx_dy2=Matrix.alloc(3,laser_sens.nrays) - - - if 1 == params[:do_compute_covariance] - dx_dy1, dx_dy2 = - compute_covariance_exact(laser_ref, laser_sens, x_new) - - end - - cov_x = (sigma*sigma) * dx_dy1 * (dx_dy1.trans) + - (sigma*sigma) * dx_dy2 * (dx_dy2.trans); - - puts "sigma : #{sigma}" - # puts "dx_dy1 : #{dx_dy1}" - # puts "dx_dy2 : #{dx_dy2}" - puts "cov_x : #{cov_x}" - - if false - - num_dx_dy1, num_dx_dy2 = - compute_covariance(laser_ref, laser_sens, x_new) - - num_cov_x = (sigma*sigma) * num_dx_dy1 * (num_dx_dy1.trans) + - (sigma*sigma) * num_dx_dy2 * (num_dx_dy2.trans) - - puts "num_dx_dy1 : #{num_dx_dy1}" - puts "num_dx_dy2 : #{num_dx_dy2}" - puts "num_cov_x : #{num_cov_x}" - end - - res = Hash.new - res[:x] = x_new - res[:iterations] = iteration - res[:dx_dy1] = dx_dy1 - res[:dx_dy2] = dx_dy2 - - return res - end - - - # f should be a Proc -# def deriv(f, x,eps) -# (f.call(x+eps)-f.call(x-eps))/(2*eps) - #end - - def compute_next_estimate(x_old) - - laser_ref = params[:laser_ref]; - laser_sens = params[:laser_sens]; - - ## current distances - dists = [] - @total_error = 0 - corrs = [] - for i in 0..laser_sens.nrays-1 - next if not laser_sens.corr[i].valid - p_i = laser_sens.p[i ] - p_j1 = laser_ref.p[laser_sens.corr[i].j1] - p_j2 = laser_ref.p[laser_sens.corr[i].j2] - - c2 = GPC::PointCorrespondence.new - c2.p = p_i - c2.q = p_j1 - v_alpha = rot(PI/2) * (p_j1-p_j2) - v_alpha = v_alpha / v_alpha.nrm2 - c2.C = v_alpha*v_alpha.trans - - corrs[i] = c2 - - dists[i] = - (transform(c2.p, x_old)-c2.q).trans * c2.C * - (transform(c2.p, x_old)-c2.q) - @total_error += dists[i] - # dists[c.i] = sqrt(dists[c.i]) - end - -# journal_correspondences("candidate", correspondences) - journal_correspondences("correspondences", laser_sens.corr) - - corrs = corrs.compact - puts "Found #{corrs.size} correspondences." - x_new = GPC.gpc(corrs) - return x_new - end - -end diff --git a/misc/rsm/rsm_icp_corr_dumb.rb b/misc/rsm/rsm_icp_corr_dumb.rb deleted file mode 100644 index b9ece7e..0000000 --- a/misc/rsm/rsm_icp_corr_dumb.rb +++ /dev/null @@ -1,98 +0,0 @@ - -class ICP - - def find_correspondences(x_old) - correspondences = Array.new - max_angular_correction_deg = params[:max_angular_correction_deg] - max_linear_correction=params[:max_linear_correction] - maxDist = params[:max_correspondence_dist] - laser_ref = params[:laser_ref]; - laser_sens = params[:laser_sens]; - - for i in 0..laser_sens.nrays-1 - if not laser_sens.valid? i - laser_sens.set_null_corr(i) - next - end - - p_i = laser_sens.p[i] - p_i_w = transform(p_i, x_old); - p_i_w_nrm2 = p_i_w.nrm2 - - # puts "p_i = #{p_i.trans}" - from, to = - possible_interval(p_i_w, laser_sens, - max_angular_correction_deg, max_linear_correction) - - ## Find best correspondence by considering all points in (from, to) - best_j = nil; - best_j_dist = 0; - $stderr.write "#{i}: " if DESCRIBE - for j in from..to - $stderr.write "#{j}" if DESCRIBE - if not laser_ref.valid? j - $stderr.write "N" if DESCRIBE - next - end - - ## Find compatible interval in the other scan. - dist = (p_i_w - laser_ref.p[j]).nrm2 - # puts "j = #{j} p_j = #{p_j[j].trans} dist = #{dist}" - if dist > maxDist - $stderr.write "M" if DESCRIBE - next - end - if (best_j.nil?) || (dist < best_j_dist) - $stderr.write "*" if DESCRIBE - best_j = j; best_j_dist = dist; - end - end - - if best_j.nil? - $stderr.write " -> NO CORR. \n" if DESCRIBE - else - $stderr.write " -> #{best_j} (#{i-best_j})\n" if DESCRIBE -# puts " #{i} -> #{best_j} (#{best_j_dist}) p_j = #{p_j[best_j].trans} p_i_w = #{p_i_w.trans}" - end - - # - ## If no point is close enough, or closest point is one - ## of the extrema, then discard - if [nil, 0, laser_ref.nrays-1].include? best_j - laser_sens.set_null_corr(i) - next - else - ## Find other point to interpolate. See if we are closed - ## to prev or next - - # FIXME: here we assume that all points are valid - j_up = laser_ref.next_valid_up(best_j) - j_down = laser_ref.next_valid_down(best_j) - if j_up.nil? and j_down.nil? - laser_sens.set_null_corr(i) - else - other_j = - if j_up.nil? or j_down.nil? - [j_up,j_down].compact[0] - else - p_prev = laser_ref.p[j_up] - p_next = laser_ref.p[j_down] - dist_prev = (p_prev-p_i_w).nrm2; - dist_next = (p_next-p_i_w).nrm2; - if dist_prev < dist_next then j_down else j_up end - end - laser_sens.corr[i].valid = true - laser_sens.corr[i].j1 = best_j - laser_sens.corr[i].j2 = other_j - end - end - end # i in first scan - end - - - - - - - -end \ No newline at end of file diff --git a/misc/rsm/rsm_icp_corr_tricks.rb b/misc/rsm/rsm_icp_corr_tricks.rb deleted file mode 100644 index 6cce4b3..0000000 --- a/misc/rsm/rsm_icp_corr_tricks.rb +++ /dev/null @@ -1,292 +0,0 @@ - -class ICP - DESCRIBE = false - VERIFY_EXACT = true - JUMP_TRICK = true - - # log search into journal - JOURNAL_SEARCH = false - - def find_correspondences_tricks(x_old) - # Some parameters - max_angular_correction_deg = params[:max_angular_correction_deg] - max_linear_correction=params[:max_linear_correction] - maxDist = params[:max_correspondence_dist] - - journal "param max_correspondence_dist #{maxDist}" - journal "param max_angular_correction_deg #{max_angular_correction_deg}" - journal "param max_linear_correction #{max_linear_correction}" - - laser_ref = params[:laser_ref]; - laser_sens = params[:laser_sens]; - - down_bigger = laser_sens.down_bigger - up_bigger = laser_sens.up_bigger - down_smaller = laser_sens.down_smaller - up_smaller = laser_sens.up_smaller - - - # If true, we compare the result with the slow algorithm, for correctness - if VERIFY_EXACT - find_correspondences(x_old) - exact = laser_sens.corr.clone - end - - dbg_num_a1 = 0 - last_best = nil - for i in 0..laser_sens.nrays-1 - if not laser_sens.valid? i - laser_sens.set_null_corr(i) - next - end - - p_i = laser_sens.p[i] - p_i_w = transform(p_i, x_old); - p_i_w_nrm2 = p_i_w.nrm2 - - from, to, start_cell = - possible_interval(p_i_w, laser_sens, - max_angular_correction_deg, max_linear_correction) - - we_start_at = last_best.nil? ? start_cell : last_best - - we_start_at = [from, we_start_at].max - we_start_at = [to, we_start_at].min - - up = we_start_at+1; up_stopped = false; - down = we_start_at; down_stopped = false; - last_dist_up = -1; # first is up - last_dist_down = 0; - best = nil - best_dist = 1000 - - @js_string = "" - def js(s) - @js_string << s - # $stderr.puts '>>>>>>>>>' if @js_string.size == 0 - # $stderr.write s - end - - js "[from #{from} down #{down} mid #{start_cell} up #{up} to #{to}]" - - while (not up_stopped) or (not down_stopped) - - now_up = up_stopped ? false : - down_stopped ? true : last_dist_up < last_dist_down - - js(" |") - - if now_up then js "up=#{up} " - if up > to then js "down:stop" - up_stopped = true; next - end - if laser_ref.p[up].nil? then js "invalid" - up+=1; next - end - - dbg_num_a1 += 1 - last_dist_up = (p_i_w - laser_ref.p[up]).nrm2 - - if (last_dist_up<maxDist) && (last_dist_up < best_dist) then js "*" - best = up; best_dist = last_dist_up; - end - - if JUMP_TRICK && (up>start_cell) - if laser_ref.readings[up] < p_i_w_nrm2 && - (not up_bigger[up].nil?) then js " J+(#{up_bigger[up]})" - up += up_bigger[up] - next - else - if laser_ref.readings[up] > p_i_w_nrm2 && - (not up_smaller[up].nil?) then js " J-(#{up_smaller[up]})" - up += up_smaller[up] - next - else - up+=1 - end - end - else - up+= 1 - end - - delta_theta = ([up-start_cell,0].max).abs * (PI/laser_ref.nrays) - min_dist_up = sin(delta_theta) * p_i_w_nrm2 - if min_dist_up > best_dist then js "up:early_stop" - up_stopped = true - next - end - - else js "dn=#{down} " - if down < from then - js "down:stop" - down_stopped = true; - next - end - if not laser_ref.valid? down then - js "invalid" - down-=1; - next - end - - dbg_num_a1 += 1 - last_dist_down = (p_i_w - laser_ref.p[down]).nrm2 - if (last_dist_down<maxDist) && (last_dist_down < best_dist) - js "*" - best = down; - best_dist = last_dist_down; - end - - delta_theta = ([start_cell-down,0].max).abs*(PI/laser_ref.nrays) - min_dist_down = sin(delta_theta) * p_i_w_nrm2 - if min_dist_down > best_dist then - js "down:early_stop" - down_stopped = true - next - end - - if JUMP_TRICK && (down<start_cell) - if laser_ref.readings[down] < p_i_w_nrm2 && - (not down_bigger[down].nil?) then - js " Jump+(#{down_bigger[down]})" - down += down_bigger[down] - else - if laser_ref.readings[down] > p_i_w_nrm2 && - (not down_smaller[down].nil?) then - js " Jump-(#{down_smaller[down]})" - down += down_smaller[down] - next - else - down-= 1 - end - end - else - js "$" - down-= 1 - end - - end - end - - last_best = best; - - js " FINAL #{i} --> #{best} " - - if JOURNAL_SEARCH - journal "tricks #{i} #{@js_string}" - end - - # - ## If no point is close enough, or closest point is one - ## of the extrema, then discard - if [nil, 0, laser_ref.nrays-1].include? best - laser_sens.set_null_corr(i) - next - else - ## Find other point to interpolate. See if we are closed - ## to prev or next - - # FIXME: here we assume that all points are valid - j_up = laser_ref.next_valid_up(best) - j_down = laser_ref.next_valid_down(best) - if j_up.nil? and j_down.nil? - laser_sens.set_null_corr(i) - else - other_j = - if j_up.nil? or j_down.nil? - [j_up,j_down].compact[0] - else - p_prev = laser_ref.p[j_down] - p_next = laser_ref.p[j_up] - dist_prev = (p_prev-p_i_w).nrm2; - dist_next = (p_next-p_i_w).nrm2; - if dist_prev < dist_next then j_down else j_up end - end - laser_sens.corr[i].valid = true - laser_sens.corr[i].j1 = best - laser_sens.corr[i].j2 = other_j - end - end - - # This checks whether the solution is the same without tricks - if VERIFY_EXACT - - if (not exact[i].valid) and (laser_sens.corr[i].valid) - $stderr.puts "He did not find a correspondence!" - puts "exact = " + (exact.map{|c| c.nil? ? 'NIL': c.j1 }.join(',')) - - puts "i = #{i}, best = #{correspondences[i].j1}, dist = #{best_dist}" - puts "#{js}" - exit - end - - if (exact[i].valid) and (not laser_sens.corr[i].valid) - $stderr.puts "I did not find a correspondence!" - exit - end - - if exact[i].j1 != laser_sens.corr[i].j1 - - my_corr = laser_ref.p[j1] - my_dist = (my_corr - p_i_w).nrm2 - his_corr = laser_ref.p[exact[i].j1] - his_dist = (his_corr - p_i_w).nrm2 - - if his_dist < my_dist - $stderr.puts "Optimal is #{exact[i].j1} (dist= #{his_dist}), " + - ", while I found #{correspondences[i].j1} (dist = #{my_dist})" - $stderr.puts "Search was: #{@js_string}" - end - -# for j in ([best_j-15,0].max)..([best_j+15,laser_ref.nrays].min) -# puts "ray #{j} reading #{@p_j[j].nil? ? 'nil' : @p_j[j].nrm2}"+ -# " upBig #{@up_bigger[j]} upS #{@up_smaller[j]} "+ -# " dnBig #{@down_bigger[j]} dnS #{@down_smaller[j]} " -# end - - end - end - - end # i in first scan - - # puts "Total number: #{dbg_num_a1}" - end -end - -class LaserData - def create_jump_tables - - for i in 0..nrays-1 - j = i + 1; - while (valid? j) and readings[j]<=readings[i] - j += 1; - end - @up_bigger[i] = j-i; - - j = i + 1; - while (valid? j) and readings[j]>=readings[i] - j += 1; - end - @up_smaller[i] = j-i; - - j = i - 1; - while (valid? j) and readings[j]>=readings[i] - j -= 1; - end - @down_smaller[i] = j-i; - - j = i - 1; - while (valid? j) and readings[j]<=readings[i] - j -= 1; - end - @down_bigger[i] = j-i; - end - end -=begin - if JOURNAL_SEARCH - journal "down_bigger #{@down_bigger. join(' ')}" - journal "down_smaller #{@down_smaller.join(' ')}" - journal "up_bigger #{ @up_bigger .join(' ')}" - journal "up_smaller #{ @up_smaller.join(' ')}" - end -=end -end \ No newline at end of file diff --git a/misc/rsm/rsm_icp_cov_exact.rb b/misc/rsm/rsm_icp_cov_exact.rb deleted file mode 100644 index 1fcf10f..0000000 --- a/misc/rsm/rsm_icp_cov_exact.rb +++ /dev/null @@ -1,161 +0,0 @@ -class ICP - def compute_covariance_exact(laser_ref, laser_sens, x) - y1 = Vector.alloc(laser_ref.readings).col - y2 = Vector.alloc(laser_sens.readings).col - - d2J_dxdy2 = Matrix.alloc(3, laser_sens.nrays) - d2J_dxdy1 = Matrix.alloc(3, laser_ref.nrays) - - t = Vector.alloc(x[0],x[1]).col - theta = x[2].to_f; - - # the three pieces of d2J_dx2 - d2J_dt2 = Matrix.alloc(2,2) - d2J_dt_dtheta = Vector.alloc(0,0).col - d2J_dtheta2 = 0 - - for i in 0..laser_sens.nrays-1 - next if not laser_sens.corr[i].valid - j1 = laser_sens.corr[i].j1 - j2 = laser_sens.corr[i].j2 - - p_k = laser_sens.p[i ] - q_k = laser_ref .p[j1] - - other = laser_ref.p[j2] - v_alpha = rot(PI/2) * (q_k-other) - v_alpha = v_alpha / v_alpha.nrm2 - m = v_alpha*v_alpha.trans - - d2J_dt2_k = 2*m - d2J_dt_dtheta_k = 2 * (rot(theta+PI/2)*p_k).trans * m - d2J_dtheta2_k = 2 * (rot(theta)*p_k+t-q_k).trans * - m * rot(theta+PI/2) * p_k + 2 * (rot(theta+PI/2)*p_k).trans * m * - rot(theta+PI/2) * p_k - - if i == 45 - d2J_dtheta2_k_1 = 2 * (rot(theta)*p_k+t-q_k).trans * - m * rot(theta+PI/2) * p_k; - d2J_dtheta2_k_2 = 2 * (rot(theta+PI/2)*p_k).trans * m * - rot(theta+PI/2) * p_k; - - puts "d2J_dtheta2_k =\n #{d2J_dtheta2_k}" - puts "d2J_dtheta2_k_1 =\n #{d2J_dtheta2_k_1}" - puts "d2J_dtheta2_k_2 =\n #{d2J_dtheta2_k_2}" - - puts "t = #{t}" - puts "theta = #{theta}" - puts "p_k = #{p_k}" - puts "q_k = #{q_k}" - - - puts "v2 = #{(rot(theta)*p_k+t-q_k)}" - end - - d2J_dt2 += d2J_dt2_k - d2J_dt_dtheta += d2J_dt_dtheta_k - d2J_dtheta2 += d2J_dtheta2_k - - ########### - - - # for measurement rho_i in the second scan - v_i = laser_sens.v(i) - d2Jk_dtdrho_i = 2 * (rot(theta)*v_i).trans * m - d2Jk_dtheta_drho_i = 2*(rot(theta)*p_k+t-q_k).trans*m*rot(theta+PI/2)*v_i + - 2 *(rot(theta)*v_i).trans*m*rot(theta+PI/2)*p_k - - d2J_dxdy2.col(i)[0] += d2Jk_dtdrho_i[0] - d2J_dxdy2.col(i)[1] += d2Jk_dtdrho_i[1] - d2J_dxdy2.col(i)[2] += d2Jk_dtheta_drho_i - - # for measurements rho_j1, rho_j2 in the first scan - dC_drho_j1, dC_drho_j2 = dC_drho_j12(laser_ref, laser_sens, j1, j2) - - v_j1 = laser_ref.v(j1) - - d2Jk_dtheta_drho_j1 = - 2*( -v_j1.trans*m+(rot(theta)*p_k+t-q_k).trans*dC_drho_j1)*rot(theta+PI/2)*p_k - d2Jk_dt_drho_j1 = 2 * (-v_j1.trans*m+(rot(theta)*p_k+t-q_k).trans*dC_drho_j1) - - d2J_dxdy1.col(j1)[0] += d2Jk_dt_drho_j1[0] - d2J_dxdy1.col(j1)[1] += d2Jk_dt_drho_j1[1] - d2J_dxdy1.col(j1)[2] += d2Jk_dtheta_drho_j1 - - # for measurement rho_j2 - d2Jk_dtheta_drho_j2 = 2*(rot(theta)*p_k+t-q_k).trans * dC_drho_j2 * - rot(theta+PI/2)*p_k; - - d2Jk_dt_drho_j2 = 2*(rot(theta)*p_k+t-q_k).trans * dC_drho_j2 - - d2J_dxdy1.col(j2)[0] += d2Jk_dt_drho_j2[0] - d2J_dxdy1.col(j2)[1] += d2Jk_dt_drho_j2[1] - d2J_dxdy1.col(j2)[2] += d2Jk_dtheta_drho_j2 - - if i==45 then - puts "Corr i=#{i} j1=#{j1} j2=#{j2}" - puts "C_k=\n#{m}"; - puts "dC_drho_j1=\n#{dC_drho_j1}" - puts "dC_drho_j2=\n#{dC_drho_j2}" - d = - 2 * (rot(theta)*p_k+t-q_k).trans * - m * rot(theta+PI/2) * p_k + 2 * (rot(theta+PI/2)*p_k).trans * m * - rot(theta+PI/2) * p_k - puts "Contribution = \n#{d}" - end - end - - # put the pieces together - d2J_dx2 = Matrix.alloc(3,3) - d2J_dx2[0,0]=d2J_dt2[0,0] - d2J_dx2[1,0]=d2J_dt2[1,0] - d2J_dx2[1,1]=d2J_dt2[1,1] - d2J_dx2[0,1]=d2J_dt2[0,1] - d2J_dx2[2,0]=d2J_dx2[0,2]=d2J_dt_dtheta[0] - d2J_dx2[2,1]=d2J_dx2[1,2]=d2J_dt_dtheta[1] - d2J_dx2[2,2] = d2J_dtheta2 - - puts "d2J_dx2 = #{d2J_dx2}" - puts "inv(d2J_dx2) = #{d2J_dx2.inv}" - - dx_dy1 = -d2J_dx2.inv * d2J_dxdy1 - dx_dy2 = -d2J_dx2.inv * d2J_dxdy2 - - j1=laser_sens.corr[24].j1 - j2=laser_sens.corr[24].j2 - - puts "cov0_x = #{dx_dy1*dx_dy1.trans+dx_dy2*dx_dy2.trans}" - - return dx_dy1, dx_dy2 - end - - def getC(rho_j1,v_j1,rho_j2,v_j2) - p_j1 = v_j1 * rho_j1 - p_j2 = v_j2 * rho_j2 - v_alpha = rot(PI/2) * (p_j1-p_j2) - v_alpha = v_alpha / v_alpha.nrm2 - m = v_alpha*(v_alpha.trans) - m - end - - def dC_drho_j12(laser_ref, laser_sens, j1, j2) - - rho_j1 = laser_ref.readings[j1] - v_j1 = laser_ref.v(j1) - rho_j2 = laser_ref.readings[j2] - v_j2 = laser_ref.v(j2) - - eps = 0.001; - - dC_drho_j1 = - (getC(rho_j1+eps,v_j1,rho_j2,v_j2)- - getC(rho_j1 ,v_j1,rho_j2,v_j2))/eps; - - dC_drho_j2 = - (getC(rho_j1,v_j1,rho_j2+eps,v_j2)- - getC(rho_j1,v_j1,rho_j2 ,v_j2))/eps; - - return dC_drho_j1, dC_drho_j2 - - end -end \ No newline at end of file diff --git a/misc/rsm/rsm_icp_cov_numeric.rb b/misc/rsm/rsm_icp_cov_numeric.rb deleted file mode 100644 index d33ed82..0000000 --- a/misc/rsm/rsm_icp_cov_numeric.rb +++ /dev/null @@ -1,106 +0,0 @@ -class ICP - def compute_covariance(laser_ref, laser_sens, x_new) - fJ = create_J_function(laser_ref, laser_sens) - - mx = x_new - my1 = Vector.alloc(laser_ref.readings).col - my2 = Vector.alloc(laser_sens.readings).col - -# tot = fJ.call(x,y1,y2) -# puts "tot= #{tot} , total_error = #{@total_error}" - - eps_x =0.001; eps_th = deg2rad(0.00001) - d0 = Vector[eps_x,0, 0].col; - d1 = Vector[0,eps_x, 0].col; - d2 = Vector[0,0,eps_th].col; - - dJ_dx = Proc.new { |x,y1,y2| - dJ_dx0 = (fJ.call(x,y1,y2)-fJ.call(x-d0,y1,y2))/(eps_x) - dJ_dx1 = (fJ.call(x,y1,y2)-fJ.call(x-d1,y1,y2))/(eps_x) - dJ_dx2 = (fJ.call(x,y1,y2)-fJ.call(x-d2,y1,y2))/(eps_th) - Vector.alloc(dJ_dx0,dJ_dx1,dJ_dx2).col - } - d2J_dx2 = Proc.new { |x,y1,y2| - d2J_dx0 = (dJ_dx.call(x,y1,y2)-dJ_dx.call(x-d0,y1,y2))/(eps_x); - d2J_dx1 = (dJ_dx.call(x,y1,y2)-dJ_dx.call(x-d1,y1,y2))/(eps_x); - d2J_dx2 = (dJ_dx.call(x,y1,y2)-dJ_dx.call(x-d2,y1,y2))/(eps_th); - m = Matrix.alloc(3,3) - m.set_col(0, d2J_dx0) - m.set_col(1, d2J_dx1) - m.set_col(2, d2J_dx2) - m - } - - d2J_dxdi = Proc.new { |x,y1,y2,i| - delta_i = Vector.alloc(laser_sens.nrays).col - delta_i.set_basis(i) - delta_i = delta_i*eps_x; - d = (dJ_dx.call(x,y1,y2+delta_i)- - dJ_dx.call(x,y1,y2))/(eps_x); - - puts "d=#{d}" - d - } - - d2J_dxdj = Proc.new { |x,y1,y2,j| - delta_j = Vector.alloc(laser_ref.nrays).col - delta_j.set_basis(j) - delta_j = delta_j *eps_x; - # puts "delta_j=#{delta_j}" - x = (dJ_dx.call(x,y1+delta_j,y2)- - dJ_dx.call(x,y1,y2))/(eps_x); - - puts "x= #{x}" - x - } - - d2J_dxdy2 = Matrix.alloc(3, laser_sens.nrays) - for i in 0..laser_sens.nrays-1 - d2J_dxdy2.set_column(i, d2J_dxdi.call(mx,my1,my2,i)) - end - - d2J_dxdy1 = Matrix.alloc(3, laser_ref.nrays) - for j in 0..laser_sens.nrays-1 - d2J_dxdy1.set_column(j, d2J_dxdj.call(mx,my1,my2,j)) - end - - dJ_dxee= dJ_dx.call(mx,my1,my2) - puts "deriv= #{dJ_dxee}" - - d2 = d2J_dx2.call(mx,my1,my2) - puts "d2J_dx2 =\n #{d2}" - - d2 = 0.5*(d2.trans + d2) - puts "sane =\n #{d2}" - - puts "d2J_dxdy1 = #{d2J_dxdy1.trans}" - puts "d2J_dxdy2 = #{d2J_dxdy2.trans}" - - dx_dy1 = - d2.inv * d2J_dxdy1 - dx_dy2 = - d2.inv * d2J_dxdy2 - - return dx_dy1, dx_dy2 - end - - def create_J_function(laser_ref, laser_sens) - Proc.new { |x,y1,y2| - fJtot = 0; - - for i in 0..laser_sens.nrays-1 - next if not laser_sens.corr[i].valid - j1 = laser_sens.corr[i].j1 - j2 = laser_sens.corr[i].j2 - p_i = laser_sens.v(i) * y2[i] - p_j1 = laser_ref.v(j1) * y1[j1] - p_j2 = laser_ref.v(j2) * y1[j2] - - v_alpha = rot(PI/2) * (p_j1-p_j2) - v_alpha = v_alpha / v_alpha.nrm2 - m = v_alpha*v_alpha.trans - p_i_w = transform(p_i, x) - fJtot += (p_i_w-p_j1).trans * m * (p_i_w-p_j1) - end - fJtot - } - end -end \ No newline at end of file diff --git a/misc/rsm/rsm_icp_outliers.rb b/misc/rsm/rsm_icp_outliers.rb deleted file mode 100644 index 70783d7..0000000 --- a/misc/rsm/rsm_icp_outliers.rb +++ /dev/null @@ -1,44 +0,0 @@ -class ICP - def kill_outliers(laser_ref, laser_sens) - - dists = (0..laser_ref.nrays-1).map { |i| - if - } - max_bin = 0.5; - bins = 100 - perc = 0.4 - safe_level = 5 - - hist = GSL::Histogram.alloc(bins, 0, max_bin) - dists.each do |d| hist.fill2 d unless d.nil? end - int = hist.integrate.scale(1.0/dists.compact.size) - # XXX sono - #puts "Histo:" - -# for i in 0..bins-1 -# $stdout.write " #{hist[i]} " -# end - - for i in 0..bins-1 - if int[i] > perc - superato = i - break - end - end - - nkilled = 0 - dists.each_index do |i| - next if corrs[i].nil? - bin = (dists[i]/max_bin)*bins; - # puts "#{i} bin=#{bin} dist=#{dists[i]}" - if bin > (superato+1) * safe_level -# puts "kill #{i} (d=#{dists[i]})" - corrs[i] = nil; - correspondences[i] = nil; - nkilled += 1 - end - end - - puts "killed #{nkilled}/#{corrs.size}" - end -end \ No newline at end of file diff --git a/misc/rsm/rsm_journal.rb b/misc/rsm/rsm_journal.rb deleted file mode 100644 index 5cd7e38..0000000 --- a/misc/rsm/rsm_journal.rb +++ /dev/null @@ -1,63 +0,0 @@ - -module Journal - def initialized - @open = false - end - - def journal_laser(which, ld) - return if not @open - journal "laser #{which} nrays #{ld.nrays}" - journal "laser #{which} min_theta #{ld.min_theta}" - journal "laser #{which} max_theta #{ld.max_theta}" - journal "laser #{which} valid " + ld.valid.map{|x| x ? 1 : 0}.join(" ") - journal "laser #{which} readings " + ld.readings.join(" ") - journal "laser #{which} cluster " + ld.cluster.join(" ") - journal "laser #{which} alpha_valid " + ld.alpha_valid.map{|x| x ? 1 : 0}.join(" ") - journal "laser #{which} alpha " + ld.alpha.join(" ") - journal "laser #{which} cov_alpha " + ld.cov_alpha.join(" ") - end - - def journal_comment(line) - return if not @open - journal "# "+ line - end - - def journal(line) - return if not @open - @file.puts line - end - - def journal_open(fileName) - @file = File.open( fileName, "w" ) - @open = true - #$stderr.puts "Opened journal #{fileName}." - end - - def journal_correspondences(s, corrs) - return if not @open - journal "#{s} " + - corrs.map{ |c| c.nil? ? '-1' : c.j1}.join(" ") - end - - def journal_array(s, a) - return if not @open - journal "#{s} " + - a.map{ |c| c.nil? ? '-1' : c.j1}.join(" ") - end - - def to_j(x) - return "undefined" if x.nil? - - if x.kind_of? GSL::Matrix - out = "" - x.each_row do |r| - r.each do |e| - out << e << " " - end - out << " " - end - end - - "#{x[0]} #{x[1]} #{x[2]}" - end -end diff --git a/misc/rsm/rsm_json_journal.rb b/misc/rsm/rsm_json_journal.rb deleted file mode 100644 index 971234a..0000000 --- a/misc/rsm/rsm_json_journal.rb +++ /dev/null @@ -1,28 +0,0 @@ - -module JSON_journal - def jj_context_enter(name) - - end - - def jj_context_exit() - - end - - def jj_loop_enter(name) - - end - - def jj_loop_iteration(name) - - end - - def jj_loop_exit() - - end - # - # void jj_add_int(const char*name, int); - # void jj_add_double(const char*name, double); - # void jj_add_double_array(const char*name, double*,int); - # void jj_add_int_array(const char*name, int*,int); - # void jj_add(const char*name, JO); -end \ No newline at end of file diff --git a/misc/rsm/rsm_laserdata.rb b/misc/rsm/rsm_laserdata.rb deleted file mode 100644 index 0f5addd..0000000 --- a/misc/rsm/rsm_laserdata.rb +++ /dev/null @@ -1,170 +0,0 @@ -require 'rsm_mathutils' - -class Correspondence - attr_accessor :valid - attr_accessor :j1 - attr_accessor :j2 -end - -class LaserData - include Math - - attr_accessor :nrays - attr_accessor :min_reading - attr_accessor :max_reading - attr_accessor :min_theta - attr_accessor :max_theta - - attr_accessor :readings - attr_accessor :valid - attr_accessor :theta - - attr_reader :alpha - attr_accessor :alpha_valid - attr_accessor :cov_alpha - - attr_accessor :cluster - attr_accessor :p - - attr_accessor :cov_readings - - attr_accessor :odometry - attr_accessor :estimate - attr_accessor :true_pose - - attr_accessor :timestamp - attr_accessor :ipc_timestamp - attr_accessor :hostname - - attr_accessor :up_bigger - attr_accessor :up_smaller - attr_accessor :down_bigger - attr_accessor :down_smaller - - attr_accessor :corr - - def initialize(nrays) - @nrays = nrays - @valid = [false ] * nrays - @readings = [GSL::NAN] * nrays - @theta = [GSL::NAN] * nrays - @alpha_valid = [false ] * nrays - @alpha = [GSL::NAN] * nrays - @cov_alpha = [GSL::NAN] * nrays - @cluster = [-1] * nrays - @cov_readings = [GSL::NAN]* nrays - - @odometry = [GSL::NAN,GSL::NAN,GSL::NAN].to_gv.col - @estimate = [GSL::NAN,GSL::NAN,GSL::NAN].to_gv.col - @true_pose = [GSL::NAN,GSL::NAN,GSL::NAN].to_gv.col - - @p = []; @corr = []; - for i in 0..nrays-1 - @p[i] = Vector[GSL::NAN,GSL::NAN].col - @corr[i] = Correspondence.new; - @corr[i].valid = false - @corr[i].j1 = -1 - @corr[i].j2 = -1 - end - - # jump tables - @up_bigger = [nil]*nrays - @up_smaller = [nil]*nrays - @down_bigger = [nil]*nrays - @down_smaller = [nil]*nrays - - # min_theta ? - end - - def alpha_valid?(i); i>=0 && i<nrays && @alpha_valid[i] end - def valid?(i); i>=0 && i<nrays && @valid[i] end - def v(i); MathUtils.vers(theta[i]) end -# def cartesian; MathUtils.vers(theta[i])*reading; end - - def set_null_corr(i) - @corr[i].valid = false - @corr[i].j1 = -1 - @corr[i].j2 = -1 - end - - def next_valid_down(i); next_valid(i,-1) end - def next_valid_up (i); next_valid(i,+1) end - def next_valid(i, direction) - i += direction - while i>=0 && i<nrays - return i if valid? i - i += direction - end - nil - end - - def correspondences_hash - indexes = @corr.map{|c| c.j1} - indexes.hash - end -end - -def standard_parameters - p = Hash.new - p[:max_angular_correction_deg]= 90 - p[:max_linear_correction]= 2 - p[:max_correspondence_dist]= 2 - p[:max_iterations]= 40 - p[:epsilon_xy]= 0.0001 - p[:epsilon_theta]= 0.0001 - p[:sigma]= 0.01 - p[:restart]= 1 - p[:restart_threshold_mean_error] = 3.0 / 300.0 - p[:restart_dt]= 0.1 - p[:restart_dtheta]= 0.026;# 1.5 * 3.14 /180 - - p[:clustering_threshold] = 0.05 - p[:orientation_neighbourhood] = 3 - p[:use_corr_tricks] = 1; - p[:do_compute_covariance] = 0; - - p[:do_alpha_test] = 0 - p[:do_alpha_test_thresholdDeg]=20 - - p[:outliers_maxPerc] = 0.95; - p[:outliers_adaptive_order] = 0.7; - p[:outliers_adaptive_mult] = 2; - - p[:do_visibility_test] = 0 - p -end - - -def tro_parameters - p = Hash.new - p[:max_angular_correction_deg]= 30 - p[:max_linear_correction]= 0.5 - p[:max_correspondence_dist]= 2 - p[:max_iterations]= 40 - p[:epsilon_xy]= 0.0001 - p[:epsilon_theta]= 0.0001 - p[:sigma]= 0.01 - p[:restart]= 1 - p[:restart_threshold_mean_error] = 3.0 / 300.0 - p[:restart_dt]= 0.01 - p[:restart_dtheta]= 0.027 #1.5 * 3.14 /180 - - p[:clustering_threshold] = 0.05 - p[:orientation_neighbourhood] = 3 - p[:use_corr_tricks] = 1; - p[:do_compute_covariance] = 0; - - p[:do_alpha_test] = 0 - p[:do_alpha_test_thresholdDeg]=20 - - p[:outliers_maxPerc] = 0.95; - p[:outliers_adaptive_order] = 0.7; - p[:outliers_adaptive_mult] = 2; - - p[:do_visibility_test] = 0 - p -end - -require 'rsm_laserdata_ops' -require 'rsm_laserdata_carmen' -require 'rsm_laserdata_json' diff --git a/misc/rsm/rsm_laserdata_carmen.rb b/misc/rsm/rsm_laserdata_carmen.rb deleted file mode 100644 index 839836b..0000000 --- a/misc/rsm/rsm_laserdata_carmen.rb +++ /dev/null @@ -1,67 +0,0 @@ - -class LaserData - # Parses a CARMEN line - def LaserData.convert_line(l) - tokens = l.split - tokens.shift - nrays = tokens.shift.to_i - - if nrays <= 0 - raise "Bad no. of rays (#{ld.nrays}) in '#{l}'" end - if tokens.size < nrays+9 - then raise "Line incomplete: '#{l}'" end - - ld = LaserData.new(nrays) - - ld.min_reading = 0.001; - ld.max_reading = 49; - ld.min_theta = -PI/2; - ld.max_theta = PI/2; - - for i in 0..nrays-1 - if tokens.empty? - raise "Could not read ray#{a} in '#{l}'" end - - reading = tokens.shift.to_f - - - if (not reading) || (reading<0) - raise "Bad value (#{p.reading}) for ray#{a} in '#{l}'" - end - - ld.theta[i] = ld.min_theta + i * (ld.max_theta) / (ld.nrays-1) - ld.valid[i] = (reading < ld.max_reading) && (reading > ld.min_reading) - ld.readings[i] = ld.valid[i] ? reading : GSL::NAN - - end - - ld.estimate = parse_tokens(tokens); - ld.odometry = parse_tokens(tokens); - ld.ipc_timestamp = tokens.shift - ld.timestamp = tokens.shift - ld.hostname = tokens.shift - ld - end - - def to_carmen - line = "FLASER #{nrays} " + readings.join(' ') + - "\t #{estimate[0]} #{estimate[1]} #{estimate[2]} "+ - "\t #{odometry[0]} #{odometry[1]} #{odometry[2]} "+ - "\t #{ipc_timestamp} #{timestamp} #{hostname}" - end - -end - -def parse_tokens(tokens) - v = GSL::Vector.alloc(GSL::NAN,GSL::NAN,GSL::NAN).col - v[0] = tokens.shift.to_f - v[1] = tokens.shift.to_f - v[2] = tokens.shift.to_f - v -end - - - - - - diff --git a/misc/rsm/rsm_laserdata_json.rb b/misc/rsm/rsm_laserdata_json.rb deleted file mode 100644 index b216baa..0000000 --- a/misc/rsm/rsm_laserdata_json.rb +++ /dev/null @@ -1,103 +0,0 @@ -begin -require 'rubygems' -rescue => ex - $stderr.puts "Rubygems not available" -end - -require 'json/pure' - -class Array - def nan_to_nil! - for i in 0..size-1 - v = self[i] - self[i] = nil if v.kind_of? Float and v.nan? - self[i] = self[i].to_f if self[i] - end - self - end - - def nil_to_nan! - for i in 0..size-1 - self[i] = self[i] || GSL::NAN - end - self - end - - def all_nan? - all? {|v| v.kind_of? Float and v.nan?} - end -end - -class GSL::Vector - def to_json(*a) - to_a.nan_to_nil!.to_json(*a) - end -end - -class LaserData - - def to_json(*a) -# puts @odometry.to_s - h = { - 'nrays' => @nrays, - 'min_theta' => @min_theta, - 'max_theta' => @max_theta, - - 'valid' => @valid.map{|x| x ? 1 : 0}, - 'readings' => @readings.clone.nan_to_nil!, - 'theta' => @theta .clone.nan_to_nil!, - - 'odometry' => @odometry, - 'estimate' => @estimate, - 'true_pose' => @true_pose - } - - h['cluster'] = @cluster unless @cluster.all?{|x| x == -1} - h['alpha_valid'] = @alpha_valid.map{|x| x ? 1 : 0} unless @alpha_valid.all?{|x| not x} - h['alpha'] = @alpha.clone.nan_to_nil! unless @alpha.all_nan? - h['cov_alpha'] = @cov_alpha.clone.nan_to_nil! unless @cov_alpha.all_nan? - h['cov_readings'] = @cov_readings.clone.nan_to_nil! unless @cov_readings.all_nan? - -# corrd = corr.map{|x| x.valid ? [x.j1, x.j2] : nil } -# h['corresponde] = c - h.to_json(*a) - end - - def from_hash(h) - self.min_theta = h['min_theta'].to_f - self.max_theta = h['max_theta'].to_f - self.valid = h['valid'].map{ |x| (x == 0 || !x ) ? false : true } - self.readings = h['readings'].clone.nil_to_nan! - self.theta = h['theta'].clone.nil_to_nan! - - self.cluster = h['cluster'].clone if h['cluster'] - self.alpha_valid = h['alpha_valid'].clone if h['alpha_valid'] - self.alpha = h['alpha'].clone.nil_to_nan! if h['alpha'] - self.cov_alpha = h['cov_alpha'].clone.nil_to_nan! if h['cov_alpha'] - self.cov_readings = h['cov_readings'].clone.nil_to_nan! if h['cov_readings'] - end -end - - -if File.basename($0) == 'rsm_laserdata_json.rb' - # testing - ld = LaserData.new(10) - ld.readings[8] = 42 - # ld.corr[i].valid = true - # ld.corr[i].j1 = 12 - # ld.corr[i].j2 = 13 - - require 'sm' - include Sm - json = ld.to_json - puts "\nLaserData.to_json:\n" - p json - c_jo = json_parse(json) - puts "\nLaserData.to_json -> c_jo = json_parse -> json_write(c_jo) :\n" - p json_write(c_jo) - c_ld = json_to_ld(c_jo) - puts "\nLaserData.to_json -> json_parse -> json_to_ld -> ld_to_json: \n" - c_jo2 = ld_to_json(c_ld) - p json_write(c_jo2) - -end \ No newline at end of file diff --git a/misc/rsm/rsm_laserdata_ops.rb b/misc/rsm/rsm_laserdata_ops.rb deleted file mode 100644 index b5348cc..0000000 --- a/misc/rsm/rsm_laserdata_ops.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'rsm_laserdata' - - -class LaserData - - def add_noise!(sigma, rng) - readings.map! { |x| - x + rng.gaussian(sigma) - } - end - - def LaserData.from_json(json_string) - h = JSON.parse(json_string) - ld = LaserData.new(h['nrays']) - ld.from_hash(h) - ld - end - - def deep_copy - LaserData.from_json(self.to_json) - end - - def compute_cartesian - for i in 0..nrays-1 - next if not valid? i - @p[i] = v(i) * readings[i] - end - end -end diff --git a/misc/rsm/rsm_mathutils.rb b/misc/rsm/rsm_mathutils.rb deleted file mode 100644 index f5e6057..0000000 --- a/misc/rsm/rsm_mathutils.rb +++ /dev/null @@ -1,148 +0,0 @@ -require 'gsl' - -module GSL - class Vector - def marshal_dump - to_a - end - - def marshal_load(a) - # puts "A is a #{a.class}: #{a}" - a.each_index { |i| - # puts "i=#{i.class} a(i) = #{a[i].class}" - } - end - - def any_nan? - for i in 0..size-1 - return true if self[i].nan? - end - false - end - - end -end - -module MathUtils - public - def deg2rad(d) - d * Math::PI / 180 - end - - def rad2deg(d) - d / Math::PI * 180 - end - - ## versor - def vers(a) - GSL::Vector.alloc(Math.cos(a), Math.sin(a)).col - end - - def two_decimals(x) - x.nan? ? GSL::NAN : (x*100).round/100.0; - end - - def pv(x) - "[#{two_decimals(x[0]*1000) }mm,#{two_decimals(x[1]*1000)}mm,"+ - "#{two_decimals(rad2deg(x[2]))}deg]" - end - - def pm(m) - std_x = (sqrt(m[0,0])*100000).round/100.0 # in mm - std_y = (sqrt(m[1,1])*100000).round/100.0 # in mm - std_th = (rad2deg(sqrt(m[2,2]))*100).round/100.0 - "[+-#{2*std_x}mm,+-#{2*std_y}mm,+-#{2*std_th}]deg" - end - ## 2x2 rotation matrix - def rot(a) - GSL::Matrix[[Math.cos(a), -Math.sin(a)], [Math.sin(a), Math.cos(a)]] - end - - def transform(point, x) - t = x[0,1]; theta = x[2]; - rot(theta)*point + t - end - - - def pose_diff(to,from) - oplus(ominus(from), to) - end - - def oplus(x1,x2) - theta = x1[2]; - GSL::Vector.alloc( - x1[0] + x2[0]*Math.cos(theta) - x2[1]*Math.sin(theta), - x1[1] + x2[0]*Math.sin(theta) + x2[1]*Math.cos(theta), - x1[2] + x2[2]).col - end - - def ominus(x) - th = x[2] - GSL::Vector.alloc( - -x[0]*Math.cos(th) - x[1]*Math.sin(th), - x[0]*Math.sin(th) - x[1]*Math.cos(th), - -x[2]).col - end - - def J1(x1,x2) - Matrix[ - [1, 0, -x2[0]*sin(x1[2])-x2[1]*cos(x1[2])], - [0, 1, x2[0]*cos(x1[2])-x2[1]*sin(x1[2])], - [0, 0, 1] - ] - end - - def J2(x1,x2) - Matrix[ - [cos(x1[2]), -sin(x1[2]), 0], - [sin(x1[2]), cos(x1[2]), 0], - [0, 0, 1] - ] - end - - - def angleDiff(a,b) - d = a - b - - while d < -PI; d+=2*PI; end - while d > PI; d-=2*PI; end - d - end - - # from, to, start_cell, range = - def possible_interval(point, ld, max_angular_correction_deg, - max_linear_correction) - - angleRes = (ld.max_theta-ld.min_theta)/ld.nrays; - - # Delta for the angle - delta = deg2rad(max_angular_correction_deg).abs + - Math.atan(max_linear_correction/point.nrm2).abs; - - # Dimension of the cell range - range = (delta/angleRes).ceil; - - # To be turned into an interval of cells - start_theta = Math.atan2(point[1],point[0]); - - start_cell = - (start_theta - ld.min_theta) / (ld.max_theta-ld.min_theta) * ld.nrays; - - start_cell = start_cell.ceil - - # Pay attention to minimum and maximum - from = min(ld.nrays-1, max( (start_cell-range).floor,0)); - to = max(0, min((start_cell+range).ceil,ld.nrays-1)); - - if false - puts "start_theta=#{rad2deg(start_theta)}°, "+ - "range = #{range} cells,"+ - "start_cell=#{rad2deg(start_cell)},"+ - "fromto=#{from}->#{to}" - end - - return from, to, start_cell, range - end - - -end \ No newline at end of file diff --git a/misc/rsm/rsm_misc.rb b/misc/rsm/rsm_misc.rb deleted file mode 100755 index 841b72f..0000000 --- a/misc/rsm/rsm_misc.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rsm_mathutils' - - -module Pose - - -end - - diff --git a/misc/rsm/rsm_orientation.rb b/misc/rsm/rsm_orientation.rb deleted file mode 100644 index dc73f31..0000000 --- a/misc/rsm/rsm_orientation.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'rsm' - -class LaserData - # Computes alpha for each point - def compute_orientation(neighbourhood, sigma) - for i in 0..nrays-1 - - if not valid? i - @alpha[i] = GSL::NAN - @alpha_valid[i]= false - @cov_alpha[i] = GSL::NAN - next - end - - # list of index - neighbours = find_neighbours(i,neighbourhood) - -# puts "i = #{i} neigbours = #{neighbours.join(', ')}" - - if neighbours.size == 0 - @alpha_valid[i]= false - @alpha[i] = GSL::NAN - @cov_alpha[i] = GSL::NAN - next - end - -# puts "neighbours for i=#{i} = #{neighbours.join(', ')}" - thetas = neighbours.map{|j| @theta[j]} - readings = neighbours.map{|j| @readings[j]} - - @alpha[i], @cov_alpha[i] = filter_orientation(@theta[i],@readings[i],thetas,readings,1); - @cov_alpha[i] *= sigma**2 - -# puts "------- i = #{i} alpha = #{}" - @alpha_valid[i] = @alpha[i].nan? ? false : true - if @alpha[i].nan? -# puts "We have a problem.." - end - end - end - - def filter_orientation(theta0, rho0, thetas, rhos, curv) - n = thetas.size - # y = l x + r epsilon - y = Matrix.alloc(n, 1) - l = Matrix.alloc(n, 1) - r = Matrix.alloc(n, n+1) - - r.set_all(0.0) - l.set_all(1.0); - - for i in 0..n-1 - # puts "theta0 = #{theta0} thetas[i] = #{thetas[i]}" - y[i,0] = (rhos[i]-rho0)/(thetas[i]-theta0) - r[i,0] = -1/(thetas[i]-theta0); - r[i,i+1] = 1/(thetas[i]-theta0); - end - -# puts "y = \n#{y}" -# puts "l = \n#{l}" -# puts "r = \n#{r}" - - bigR = r*r.trans; - # x = (l^t R^-1 l)^-1 l^t R^-1 y - cov_f1 = ((l.trans * bigR.inv * l).inv)[0,0] - f1 = (cov_f1 * l.trans * bigR.inv * y)[0,0] - -# puts "f1 = #{f1}" - #alpha = theta0 + PI/2 + Math.atan(rho0/f1) - alpha = theta0 - Math.atan(f1/rho0) - - - dalpha_df1 = rho0 / (rho0**2 + f1**2) - dalpha_drho = -f1 / (rho0**2 + f1**2) - cov0_alpha = (dalpha_df1**2) * cov_f1 + (dalpha_drho**2) - - -# puts " cov_f1 = #{cov_f1} dalpha_df1 #{dalpha_df1**2} dalpha_drho #{dalpha_drho**2} "+ -# " cov0_alpha = #{cov0_alpha}" -# puts "sotto = #{(rho0**2 + f1**2)}" - - if cos(alpha)*cos(theta0)+sin(alpha)*sin(theta0)>0 - alpha = alpha + PI - end - - return alpha, cov0_alpha - end - - # uses params[:gpm_neighbours]? - def find_neighbours(i, neighbourhood) - up = i; - while (up+1 <= i+neighbourhood) and (up+1<nrays) and (valid? up+1) and - (cluster[up+1] == cluster[i]) - up+=1; - end - down = i; - while (down >= i-neighbourhood) and (down-1>=0) and (valid? down-1) and - (cluster[down-1] == cluster[i]) - down-=1; - end - (down..(i-1)).to_a + ((i+1)..up).to_a - end - -end \ No newline at end of file diff --git a/misc/rsm/rsm_sm.rb b/misc/rsm/rsm_sm.rb deleted file mode 100755 index e9c11cf..0000000 --- a/misc/rsm/rsm_sm.rb +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env ruby - -require 'rsm_sm_loop' - - - if ARGV.size < 3 - puts "sm <SCANMATCHER> '[]' <input> <output> " - exit 1 - end - - scan_matcher = eval ARGV[0] - scan_list = eval ARGV[1] - - puts "Scan_list = #{scan_list}" - -# Read from standard input if no arguments are passed -#io = ARGV.size>0 ? File.open(ARGV[0]) : $stdin - - input = File.open ARGV[2] - output = File.open ARGV[3], "w" - - params = standard_parameters - -# begin - scan_matching(scan_matcher,scan_list,input,output,params) - # rescue => ex - # puts "bam" - # puts ex, ex.backtrace - # end - - - diff --git a/misc/rsm/rsm_sm_cov.rb b/misc/rsm/rsm_sm_cov.rb deleted file mode 100755 index 3d4a127..0000000 --- a/misc/rsm/rsm_sm_cov.rb +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env ruby -require 'rsm' - -class Matching - attr_accessor :x - attr_accessor :cov_x - - attr_accessor :dx_dy1 - attr_accessor :dx_dy2 - - attr_accessor :J1 - attr_accessor :J2 -end - -def scan_matching(io, scan_matcher) - include MathUtils - - laser_ref = LogReader.shift_laser(io) - - count = 0 - - pose = Vector[0,0,0].col - cov_pose = Matrix[[0,0,0],[0,0,0],[0,0,0]] - cov_pose_b = cov_pose - sigma = 0.01; - - history = Array.new - until io.eof? - count+=1 - laser_sens = LogReader.shift_laser(io) - min_step = -0.001 - min_theta_step_deg =- 0.01 - - u = pose_diff(laser_sens.odometry, laser_ref.odometry) - # puts "u: #{pv(u)}" - - if (u[0,1]).nrm2 <= min_step && (u[2].abs <deg2rad(min_theta_step_deg)) - - # todo: merge readings - #puts "Skipping (same odometry)" - next - end - - # puts "Ref: #{pv(laser_ref.odometry)}" - # puts "New: #{pv(laser_sens.odometry)}" - - icp = scan_matcher.new - # Write log of the icp operation - # icp.journal_open("icp_sm.rb-sm#{count}.txt") - - icp.params[:max_angular_correction_deg]= 10 - icp.params[:max_linear_correction]= 2 - icp.params[:laser_ref] = laser_ref; - icp.params[:laser_sens] = laser_sens; - icp.params[:firstGuess] = u - icp.params[:max_iterations] = 20 - - - m = Matching.new - - m.x, m.dx_dy1, m.dx_dy2 = icp.scan_matching - m.J1 = J1(pose,m.x); - m.J2 = J2(pose,m.x); - - - pose_new = oplus(pose, m.x); - m.cov_x = (sigma*sigma) * m.dx_dy1 * (m.dx_dy1.trans) + - (sigma*sigma) * m.dx_dy2 * (m.dx_dy2.trans); - - - cov_pose_new = m.J1 * cov_pose * m.J1.trans + m.J2 * m.cov_x * m.J2.trans - - if true - if history.empty? - cov_pose_b_new = m.J1 * cov_pose_b * m.J1.trans + m.J2 * m.cov_x * m.J2.trans - else - d = (sigma*sigma) * m.J1 * history[-1].J2 * history[-1].dx_dy2 * m.dx_dy1.trans * m.J2.trans; - puts " D = \nd" - cov_pose_b_new = m.J1 * cov_pose_b * m.J1.trans + m.J2 * m.cov_x * m.J2.trans + d + d.trans - end - end - - -# puts "j1 =\n #{j1}" -# puts "j2 =\n #{j2}" -# puts "j1*j1' =\n #{j1*j1.trans}" -# puts "j2*j2' =\n #{j2*j2.trans}" - puts "PPP pose = #{pv(pose)} \ncov = #{pm(cov_pose_new)}" - puts "cov2 = #{pm(cov_pose_b_new)}" - puts "cov = \n#{cov_pose_new}" - puts "cov2= \n#{cov_pose_b_new}" - puts "cov-cov2 = \n#{cov_pose_new-cov_pose_b_new}" - - history.push m - pose = pose_new; - cov_pose = cov_pose_new; - cov_pose_b = cov_pose_b_new; - laser_ref = laser_sens; - end -end - -# Read from standard input if no arguments are passed -io = ARGV.size>0 ? File.open(ARGV[0]) : $stdin - -scan_matching(io) - diff --git a/misc/rsm/rsm_sm_loop.rb b/misc/rsm/rsm_sm_loop.rb deleted file mode 100644 index 9a33999..0000000 --- a/misc/rsm/rsm_sm_loop.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'logreader' -require 'benchmark' - -def scan_matching(klass,scan_list,input,output,params) - include MathUtils - - laser_ref = LogReader.shift_laser(input) - laser_ref.estimate = Vector[0,0,0].col - output.puts laser_ref.to_json - - results = [] - count = 0 - until input.eof? - - laser_sens = LogReader.shift_laser(input) - min_step = -0 - min_theta_step_deg = -5; - - u = pose_diff(laser_sens.odometry, laser_ref.odometry) - - if (u[0,1]).nrm2 <= min_step && (u[2].abs <deg2rad(min_theta_step_deg)) - - # todo: merge readings - #puts "Skipping (same odometry)" - next - end - -# puts "Ref: #{pv(laser_ref.odometry)}" -# puts "New: #{pv(laser_sens.odometry)}" - - if (not scan_list.empty?) && (not scan_list.include? count) - break if count > scan_list.max - count+=1 - laser_ref = laser_sens; - next - end - - sm = klass.new - # Write log of the icp operation - - if scan_list.include? count - sm.journal_open("rsm_sm.#{sm.name}.#{count}.txt") - end - - sm.params = params - sm.params[:laser_ref] = laser_ref; - sm.params[:laser_sens] = laser_sens; - sm.params[:firstGuess] = u - - if false - sm.params[:laser_sens] = laser_ref; - sm.params[:firstGuess] = GSL::Vector.alloc(0,0,0) - end - - res = nil - realtime = Benchmark.realtime do - res = sm.scan_matching - end - res[:u] = u - res[:time] = realtime - results.push res - - if not res[:valid] - break - end - - x = res[:x] - if x.any_nan? - raise "Found nans in answer x = #{x.inspect}" - end - error = res[:error] - iterations = res[:iterations] - - laser_sens.estimate = oplus(laser_ref.estimate, x) - output.puts laser_sens.to_json - - q = laser_sens.estimate - $stderr.puts "rsm_sm.rb: #{count} time=#{realtime} error = #{error} it = #{iterations} x = #{pv(x)} u = #{pv(u)} q = #{pv(q)}" - - - laser_ref = laser_sens; - count += 1 - end - results -end diff --git a/misc/rsm/sm_display.m b/misc/rsm/sm_display.m deleted file mode 100644 index db08fdd..0000000 --- a/misc/rsm/sm_display.m +++ /dev/null @@ -1,156 +0,0 @@ -function [laser_ref, laser_sens] = sm_display(file) - -cells = readFileInCells(file); -%global cells -[rows, columns] = size(cells) - -% todo: remove comments - -r = 1 - -r = skip_to(cells, r,'laser') -[r, laser_ref] = read_laser_data(cells, r); - -r = skip_to(cells, r,'laser') -[r, laser_sens] = read_laser_data(cells, r); - -f = figure; hold on; axis('equal') - -while true - r = skip_to(cells, r,'iteration'); - if r > rows - break - end - - r = skip_to(cells, r,'x_old'); - x_old = cells_to_vector(cells, r, 2); - - [corr_exist, r] = exist_this_iteration(cells, r,'correspondences'); - if corr_exist - for i=1:laser_sens.nrays - corr(i) = str2num(cells{r,1+i}); - if corr(i) == -1 - corr(i) = nan; - else - % matlab counts from 1.. (yuk!) - corr(i) = corr(i) + 1; - end - end - end - - laser_ref.estimate = [0;0;0]; - laser_sens.estimate = x_old; - - params.plotNormals = true; - params.color = 'r.'; - ld_plot(laser_ref, params); - - params.plotNormals = true; - params.color = 'g.'; - ld_plot(laser_sens, params); - - if corr_exist - for i=1:size(corr,2) - if isnan(corr(i)) - continue - end - plot_line(transform(laser_sens.points(:,i),x_old), ... - laser_ref.points(:,corr(i)),'k-'); - end - end - - pause - old_axis = axis - clf - axis(old_axis) - - %r = skip_to(cells, r,'x_new'); - %x_new = cells_to_vector(cells, r, 2) - -end - -function plot_line(a,b,color) - plot([a(1) b(1)],[a(2) b(2)],color); - -function x = cells_to_vector(cells, r, cell) - for i=1:3 - x(i,1) = str2double(cells{r, cell+i-1}); - end - -% Finds next row in cells whose first cell is equal to "cellname" -function r = skip_to(cells, r, cellname) - while (r<=size(cells,1)) && (0==strcmp(cells{r,1}, cellname)) - r = r +1; - end - -function [exist, r] = exist_this_iteration(cells, r, cellname); - start =r; - next_iteration = skip_to(cells, r, 'iteration'); - r = skip_to(cells, r, cellname) - if r < next_iteration - exist = true; - else - r = start; - exist = false; - end - - -function [next_r, laser_data] = read_laser_data(cells, r) - - name = cells{r, 2} - ld = struct; - ld.estimate = [0;0;0] - ld.odometry = [0;0;0] - while (r<=size(cells,1)) && strcmp(cells{r, 1},'laser') && strcmp(cells{r, 2},name) - fprintf('at %s %s %s\n',cells{r,1},cells{r,2},cells{r,3}) - if strcmp(cells{r, 3}, 'min_theta') - min_theta = str2double(cells{r,4}); - end - if strcmp(cells{r, 3}, 'max_theta') - max_theta = str2double(cells{r,4}); - end - if strcmp(cells{r, 3}, 'nrays') - ld.nrays = str2double(cells{r,4}); - end - if strcmp(cells{r, 3}, 'valid') - for i=1:ld.nrays - ld.valid(i) = str2num(cells{r,3+i}); - end - end - if strcmp(cells{r, 3}, 'readings') - for i=1:ld.nrays - ld.readings(i) = str2double(cells{r,3+i}); - ld.theta(i) = min_theta + (max_theta-min_theta)*i/ld.nrays; - end - end - if strcmp(cells{r, 3}, 'alpha_valid') - for i=1:ld.nrays - ld.alpha_valid(i) = str2num(cells{r,3+i}); - end - end - if strcmp(cells{r, 3}, 'alpha') - for i=1:ld.nrays - ld.alpha(i) = str2double(cells{r,3+i}); - end - end - if strcmp(cells{r, 3}, 'cov_alpha') - for i=1:ld.nrays - ld.cov_alpha(i) = str2double(cells{r,3+i}); - end - end - if strcmp(cells{r, 3}, 'cluster') - for i=1:ld.nrays - ld.cluster(i) = str2num(cells{r,3+i}); - end - end - r = r+1; - end - - ld.points = [cos(ld.theta) .* ld.readings; sin(ld.theta) .* ld.readings]; - - next_r = r; - laser_data =ld; - - - - \ No newline at end of file diff --git a/misc/rsm/test_json.rb b/misc/rsm/test_json.rb deleted file mode 100644 index e69de29..0000000 diff --git a/misc/rsm/test_mathutils.rb b/misc/rsm/test_mathutils.rb deleted file mode 100644 index 05dd2de..0000000 --- a/misc/rsm/test_mathutils.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'rsm_mathutils' - -include MathUtils -include GSL - -pose1 = Vector[1, 2, 3] -pose2 = Vector[1.5, 2.1, 2.4] - -puts "pose1\t #{pv(pose1)}" -puts "pose2\t #{pv(pose2)}" -diff = pose_diff(pose2, pose1) -puts "diff\t #{pv(diff)}" -pose2b = oplus(pose1, diff) -puts "pose2b\t #{pv(pose2b)}" diff --git a/misc/rsm/tmp.rb b/misc/rsm/tmp.rb deleted file mode 100644 index 8b7ef91..0000000 --- a/misc/rsm/tmp.rb +++ /dev/null @@ -1,3 +0,0 @@ - require 'point2line' -include MathUtils - test_gm2 diff --git a/misc/sm_ruby_wrapper/extconf.rb b/misc/sm_ruby_wrapper/extconf.rb deleted file mode 100644 index f0c2497..0000000 --- a/misc/sm_ruby_wrapper/extconf.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'mkmf' - -GSL_CONFIG = "gsl-config" - -# Taken from rb-gsl -def gsl_config() - print("checking gsl cflags... ") - IO.popen("#{GSL_CONFIG} --cflags") do |f| - cflags = f.gets.chomp - puts(cflags) - $CFLAGS += " " + cflags - end - - IO.popen("#{GSL_CONFIG} --libs") do |f| - libs = f.gets.chomp - dir_config("cblas") - dir_config("atlas") - if have_library("cblas") and have_library("atlas") - libs.gsub!("-lgslcblas", "-lcblas -latlas") - $LOCAL_LIBS += " " + libs.gsub(" -lgslcblas", "") - print("checking gsl libs... ") - puts(libs) - else - print("checking gsl libs... ") - puts(libs) - $LOCAL_LIBS += " " + libs - end - end - -end - -def crash(str) - print " extconf failure: #{str}\n" - exit 1 -end - - -if (not have_library('csm')) #or (not find_header('icp.h','/usr/local/include')) - $stderr.puts "Error: not having library 'csm'" - exit -else - $LOCAL_LIBS += ' -lcsm' -end - -$CPPFLAGS += " -Wall -W -Wmissing-prototypes -Wconversion " -$CPPFLAGS += " -Wunreachable-code " -$CPPFLAGS += " -DRUBY" -gsl_config(); - -srcs = %w(rb_sm sm_wrap) -$objs = srcs.collect{|i| i+".o"} - -create_makefile('sm') -if false -File.open("Makefile","a") do |f| - f.puts <<-EOF -# Copy other sources from other directory -%.o: ../%.o - cp $< $@ - -EOF - -end end diff --git a/misc/sm_ruby_wrapper/go.sh b/misc/sm_ruby_wrapper/go.sh deleted file mode 100755 index f8440d5..0000000 --- a/misc/sm_ruby_wrapper/go.sh +++ /dev/null @@ -1,6 +0,0 @@ -swig -ruby sm.i -ruby extconf.rb --with-opt-dir=../deploy -make clean -make 2>&1 | egrep -v 'never|function|argv|self' -make install -echo "puts require('sm')" | ruby diff --git a/misc/sm_ruby_wrapper/lib/sm_gpm.rb b/misc/sm_ruby_wrapper/lib/sm_gpm.rb deleted file mode 100644 index 5090bdb..0000000 --- a/misc/sm_ruby_wrapper/lib/sm_gpm.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'sm' -require 'sm_icp' - -require 'rsm' - -module Sm - - class GPMC - include MathUtils - include Math - - attr_accessor :params - - def initialize - @params = standard_parameters - end - - def name - "GPMC" - end - - def scan_matching - - Sm.put_params_in_c_structures(params) - - Sm::rb_sm_gpm() - - res = Sm.get_result_from_c_structures() - - Sm::rb_sm_cleanup() - - res - end - - - def journal_open(filename) - Sm::rb_sm_init_journal(filename) - end - end - -end \ No newline at end of file diff --git a/misc/sm_ruby_wrapper/lib/sm_icp.rb b/misc/sm_ruby_wrapper/lib/sm_icp.rb deleted file mode 100644 index cae9f35..0000000 --- a/misc/sm_ruby_wrapper/lib/sm_icp.rb +++ /dev/null @@ -1,104 +0,0 @@ -#begin - require 'sm' - require 'rsm' -# rescue => ex -# puts ex, ex.backtrace -# end - -module Sm - -# pass parameters -def Sm.params2method(params, ob) - params.keys.map{|x|x.to_s}.sort.map{|x|x.to_sym}. - each { |param| value = params[param] - method = "#{param}=" - if ob.methods.include? method - old_value = ob.__send__(param.to_s) -# ob.__send__(method, value) - if old_value != value - $stderr.puts "Setting #{method} #{value} (#{old_value})" - - if 0 == rb_sm_set_configuration(param.to_s, value.to_s); - raise "Error setting #{param.inspect}" - end - end - else - raise "Structure does not have method #{method}" - end - } -end - -def Sm.put_params_in_c_structures(params) -# pass all parameters to extension library - - s = params[:laser_ref].to_json - rb_set_laser_ref(s); - - s = params[:laser_sens].to_json - rb_set_laser_sens(s); - - u = params[:firstGuess]; - rb_sm_odometry(u[0],u[1],u[2]); - - remove = [:laser_ref, :firstGuess, :laser_sens] - filtered = params.clone.delete_if {|k,v| remove.include? k } - Sm.params2method(filtered, Sm::rb_sm_params) -end - -def Sm.get_result_from_c_structures() - -# ld_free(rb_sm_params.laser_sens); -# ld_free(rb_sm_params.laser_ref); - - - res = JSON.parse(rb_result_to_json) - - res2 = {} - res.keys.each do |k| - res2[k.to_sym] = res[k] - end - res = res2 - -# p res - res[:valid] = res[:valid] == 1 - if res[:valid] - res[:x] = Vector[*res[:x]].col - res[:avg_error] = res[:error] / res[:nvalid] - end - res - -end - - class ICPC - include MathUtils - include Math - - attr_accessor :params - - def initialize - @params = standard_parameters - end - - def name - "ICPC" - end - - def scan_matching - Sm.put_params_in_c_structures(params) - - Sm::rb_sm_icp() - - res = Sm.get_result_from_c_structures() - - Sm::rb_sm_cleanup - - res - end - - - def journal_open(filename) - Sm::rb_sm_init_journal(filename) - end - end - -end \ No newline at end of file diff --git a/misc/sm_ruby_wrapper/rb_sm.c b/misc/sm_ruby_wrapper/rb_sm.c deleted file mode 100644 index 53da151..0000000 --- a/misc/sm_ruby_wrapper/rb_sm.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "rb_sm.h" -#include <stdio.h> -#include <gsl/gsl_nan.h> -#include <options/options.h> - -struct sm_params rb_sm_params; -struct sm_result rb_sm_result; - -void rb_sm_init_journal(const char*journal_file) { - jj_set_stream(open_file_for_writing(journal_file)); -/* sm_journal_open(journal_file);*/ -} - -void rb_sm_close_journal() { - FILE * s = jj_get_stream(); - if(s) fclose(s); - - jj_set_stream(0); -} - -void rb_sm_odometry(double x, double y, double theta){ - rb_sm_params.first_guess[0]=x; - rb_sm_params.first_guess[1]=y; - rb_sm_params.first_guess[2]=theta; -} - -void rb_sm_odometry_cov(double cov_x, double cov_y, double cov_theta){ - -} - -struct option* ops = 0; - -int rb_sm_set_configuration(const char*name, const char*value) { - if(!ops) { - ops = options_allocate(30); - sm_options(&rb_sm_params, ops); - } - - if(!options_try_pair(ops, name, value)) { - - return 0; - } else - return 1; -} - -const char *rb_result_to_json() { - static char buf[5000]; - JO jo = result_to_json(&rb_sm_params, &rb_sm_result); - strcpy(buf, jo_to_string(jo)); - jo_free(jo); - return buf; -} - -int rb_sm_icp() { - sm_icp(&rb_sm_params, &rb_sm_result); - return rb_sm_result.valid; -} - -int rb_sm_gpm() { - sm_gpm(&rb_sm_params, &rb_sm_result); - return rb_sm_result.valid; -} - -void rb_set_laser_ref(const char*s) { - rb_sm_params.laser_ref = string_to_ld(s); -/* fprintf(stderr, "Set laser_ref to %p\n ", rb_sm_params.laser_ref );*/ -} - -void rb_set_laser_sens(const char*s) { - rb_sm_params.laser_sens = string_to_ld(s); -/* fprintf(stderr, "Set laser_sens to %p\n ", rb_sm_params.laser_sens );*/ -} - -void rb_sm_cleanup() { - if(rb_sm_params.laser_ref) - ld_free(rb_sm_params.laser_ref); - if(rb_sm_params.laser_sens) - ld_free(rb_sm_params.laser_sens); -} - -LDP string_to_ld(const char*s) { - JO jo = json_parse(s); - if(!jo) { - fprintf(stderr, "String passed from Ruby is invalid JSON: \n\n%s\n", s); - return 0; - } - LDP ld = json_to_ld(jo); - if(!ld) { - fprintf(stderr, "String passed from Ruby is valid JSON, " - "but can't load laser_data. \n\n%s\n", s); - return 0; - } - jo_free(jo); - return ld; -} - diff --git a/misc/sm_ruby_wrapper/rb_sm.h b/misc/sm_ruby_wrapper/rb_sm.h deleted file mode 100644 index 898b61d..0000000 --- a/misc/sm_ruby_wrapper/rb_sm.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef H_SM_RUBY_WRAPPER -#define H_SM_RUBY_WRAPPER - -#include <csm/csm.h> - -/** Interface for Ruby: there are no pointers around. */ - -int rb_sm_set_configuration(const char*name, const char*value); - - -void rb_sm_odometry(double x, double y, double theta); -void rb_sm_odometry_cov(double cov_x, double cov_y, double cov_theta); - -int rb_sm_icp(); -int rb_sm_gpm(); - -const char *rb_result_to_json(); - -LDP string_to_ld(const char*s); - - -void rb_set_laser_ref(const char*s); -void rb_set_laser_sens(const char*s); - -void rb_sm_cleanup(); - - - -void rb_sm_init_journal(const char*journal_file); -void rb_sm_close_journal(); - -#include <csm/csm.h> - -extern struct sm_params rb_sm_params; -extern struct sm_result rb_sm_result; - -#endif diff --git a/misc/sm_ruby_wrapper/sm.i b/misc/sm_ruby_wrapper/sm.i deleted file mode 100644 index 8af4e0d..0000000 --- a/misc/sm_ruby_wrapper/sm.i +++ /dev/null @@ -1,83 +0,0 @@ -%module sm - -%header %{ - #include "rb_sm.h" -%} - -struct sm_params { - LDP laser_ref; - LDP laser_sens; - - double max_angular_correction_deg; - double max_linear_correction; - int max_iterations; - double epsilon_xy; - double epsilon_theta; - double max_correspondence_dist; - - int restart; - double restart_threshold_mean_error; - double restart_dt; - double restart_dtheta; - - double sigma; - - double clustering_threshold; - int orientation_neighbourhood; - - int do_alpha_test; - double do_alpha_test_thresholdDeg; - - double outliers_maxPerc; - double outliers_adaptive_order; - double outliers_adaptive_mult; - - int do_visibility_test; - int use_corr_tricks; - int do_compute_covariance; - -}; - -struct sm_result { - int valid; - - double x[3]; - int iterations; - double error; - int nvalid; -}; - - -JO ld_to_json(LDP); -LDP json_to_ld(JO); - -const char *rb_result_to_json(); - -LDP string_to_ld(const char*s); -void ld_free(LDP); -void jo_free(JO); - -JO json_parse(const char*str); -const char* json_write(JO jo); - - -int rb_sm_set_configuration(const char*name, const char*value); -void rb_sm_init_journal(const char*journal_file); -void rb_sm_close_journal(); - - -void rb_set_laser_ref(const char*); -void rb_set_laser_sens(const char*); - -void rb_sm_odometry(double x, double y, double theta); -void rb_sm_odometry_cov(double cov_x, double cov_y, double cov_theta); - -int rb_sm_icp(); -int rb_sm_gpm(); - -void rb_sm_cleanup(); - -%inline { -extern struct sm_params rb_sm_params; -extern struct sm_result rb_sm_result; -} \ No newline at end of file diff --git a/misc/tests/failure1/Makefile b/misc/tests/failure1/Makefile deleted file mode 100644 index 4b042b2..0000000 --- a/misc/tests/failure1/Makefile +++ /dev/null @@ -1,20 +0,0 @@ - -only_corr=-sens_countour_draw 0 -ref_countour_draw 0 -sens_points_draw 0 -ref_points_draw 0 -sens_rays_draw 0 -ref_rays_draw 0 -write_info 1 - -all: - json_extract -nth 0 -in stallo2.log -out stallo2-0.json - json_extract -nth 1 -in stallo2.log -out stallo2-1.json - log2pdf -config hokuyo.config -use odometry -in stallo2-0.json - log2pdf -config hokuyo.config -use odometry -in stallo2-1.json - log2pdf -config hokuyo.config -use odometry -in stallo2.log -distance_xy 0 - sm2 -restart 0 -in stallo2.log -out stallo2_plicp.log -max_iterations 10 -file_jj stallo2_plicp.journal - sm_animate $(only_corr) -in stallo2_plicp.journal -out 'stallo2_plicp_%02d.pdf' - sm2 -restart 0 -in stallo2.log -out stallo2_icp.log -use_point_to_line_distance 0 -max_iterations 10 -file_jj stallo2_icp.journal - sm_animate $(only_corr) -in stallo2_icp.journal -out 'stallo2_icp_%02d.pdf' - sm2 -in stallo2.log -out stallo2_gpm.log -algo 1 -file_jj stallo2_gpm.journal - log2pdf -config hokuyo.config -use estimate -in stallo2_gpm.log - sm2 -restart 0 -max_correspondence_dist 0.2 -in stallo2.log -out stallo2_plicp2.log -max_iterations 10 -file_jj stallo2_plicp2.journal - sm_animate $(only_corr) -in stallo2_plicp2.journal -out 'stallo2_plicp2_%02d.pdf' - sm2 -restart 0 -max_correspondence_dist 0.2 -in stallo2.log -out stallo2_icp2.log -max_iterations 10 -file_jj stallo2_icp2.journal -use_point_to_line_distance 0 - sm_animate $(only_corr) -in stallo2_icp2.journal -out 'stallo2_icp2_%02d.pdf' - diff --git a/misc/tests/failure1/hokuyo.config b/misc/tests/failure1/hokuyo.config deleted file mode 100644 index 5647a0e..0000000 --- a/misc/tests/failure1/hokuyo.config +++ /dev/null @@ -1,29 +0,0 @@ -padding 0.2 -dimension 500 -offset_theta_deg 0 -distance_xy 5 -distance_th_deg 45 -start_pose_width 0.01 -laser_rays_draw 1 -laser_rays_color #f00 -laser_rays_width 0.0002 -laser_countour_draw 1 -laser_countour_color black -laser_countour_width 0.002 -laser_points_draw 0 -laser_points_color #f00 -laser_points_width 0.002 -laser_points_radius 0.003 -laser_pose_draw 1 -laser_pose_color #f73 -laser_pose_width 0.002 -laser_pose_radius 0.01 -laser_normals_draw 0 -laser_normals_color black -laser_normals_width 0.002 -laser_normals_length 0.1 -laser_connect_threshold 0.4 -laser_horizon 10 -path_draw 1 -path_color #f00 -path_width 0.01 diff --git a/misc/tests/failure1/stallo2.log b/misc/tests/failure1/stallo2.log deleted file mode 100644 index 541f57a..0000000 --- a/misc/tests/failure1/stallo2.log +++ /dev/null @@ -1,2 +0,0 @@ -{ "nrays": 1024, "min_theta": 0.003100, "max_theta": 6.280100, "theta": [ 0.003100, 0.009236, 0.015372, 0.021508, 0.027643, 0.033779, 0.039915, 0.046051, 0.052187, 0.058323, 0.064459, 0.070595, 0.076730, 0.082866, 0.089002, 0.095138, 0.101274, 0.107410, 0.113546, 0.119682, 0.125817, 0.131953, 0.138089, 0.144225, 0.150361, 0.156497, 0.162633, 0.168769, 0.174904, 0.181040, 0.187176, 0.193312, 0.199448, 0.205584, 0.211720, 0.217856, 0.223991, 0.230127, 0.236263, 0.242399, 0.248535, 0.254671, 0.260807, 0.266943, 0.273078, 0.279214, 0.285350, 0.291486, 0.297622, 0.303758, 0.309894, 0.316030, 0.322165, 0.328301, 0.334437, 0.340573, 0.346709, 0.352845, 0.358981, 0.365117, 0.371252, 0.377388, 0.383524, 0.389660, 0.395796, 0.401932, 0.408068, 0.414204, 0.420339, 0.426475, 0.432611, 0.438747, 0.444883, 0.451019, 0.457155, 0.463291, 0.469426, 0.475562, 0.481698, 0.487834, 0.493970, 0.500106, 0.506242, 0.512378, 0.518513, 0.524649, 0.530785, 0.536921, 0.543057, 0.549193, 0.555329, 0.561465, 0.567600, 0.573736, 0.579872, 0.586008, 0.592144, 0.598280, 0.604416, 0.610552, 0.616687, 0.622823, 0.628959, 0.635095, 0.641231, 0.647367, 0.653503, 0.659639, 0.665774, 0.671910, 0.678046, 0.684182, 0.690318, 0.696454, 0.702590, 0.708726, 0.714861, 0.720997, 0.727133, 0.733269, 0.739405, 0.745541, 0.751677, 0.757813, 0.763948, 0.770084, 0.776220, 0.782356, 0.788492, 0.794628, 0.800764, 0.806900, 0.813035, 0.819171, 0.825307, 0.831443, 0.837579, 0.843715, 0.849851, 0.855987, 0.862122, 0.868258, 0.874394, 0.880530, 0.886666, 0.892802, 0.898938, 0.905074, 0.911209, 0.917345, 0.923481, 0.929617, 0.935753, 0.941889, 0.948025, 0.954161, 0.960296, 0.966432, 0.972568, 0.978704, 0.984840, 0.990976, 0.997112, 1.003248, 1.009383, 1.015519, 1.021655, 1.027791, 1.033927, 1.040063, 1.046199, 1.052335, 1.058470, 1.064606, 1.070742, 1.076878, 1.083014, 1.089150, 1.095286, 1.101422, 1.107557, 1.113693, 1.119829, 1.125965, 1.132101, 1.138237, 1.144373, 1.150509, 1.156644, 1.162780, 1.168916, 1.175052, 1.181188, 1.187324, 1.193460, 1.199596, 1.205731, 1.211867, 1.218003, 1.224139, 1.230275, 1.236411, 1.242547, 1.248683, 1.254818, 1.260954, 1.267090, 1.273226, 1.279362, 1.285498, 1.291634, 1.297770, 1.303905, 1.310041, 1.316177, 1.322313, 1.328449, 1.334585, 1.340721, 1.346857, 1.352992, 1.359128, 1.365264, 1.371400, 1.377536, 1.383672, 1.389808, 1.395944, 1.402079, 1.408215, 1.414351, 1.420487, 1.426623, 1.432759, 1.438895, 1.445031, 1.451166, 1.457302, 1.463438, 1.469574, 1.475710, 1.481846, 1.487982, 1.494118, 1.500253, 1.506389, 1.512525, 1.518661, 1.524797, 1.530933, 1.537069, 1.543205, 1.549340, 1.555476, 1.561612, 1.567748, 1.573884, 1.580020, 1.586156, 1.592292, 1.598427, 1.604563, 1.610699, 1.616835, 1.622971, 1.629107, 1.635243, 1.641379, 1.647514, 1.653650, 1.659786, 1.665922, 1.672058, 1.678194, 1.684330, 1.690466, 1.696601, 1.702737, 1.708873, 1.715009, 1.721145, 1.727281, 1.733417, 1.739553, 1.745688, 1.751824, 1.757960, 1.764096, 1.770232, 1.776368, 1.782504, 1.788640, 1.794775, 1.800911, 1.807047, 1.813183, 1.819319, 1.825455, 1.831591, 1.837727, 1.843862, 1.849998, 1.856134, 1.862270, 1.868406, 1.874542, 1.880678, 1.886814, 1.892949, 1.899085, 1.905221, 1.911357, 1.917493, 1.923629, 1.929765, 1.935901, 1.942036, 1.948172, 1.954308, 1.960444, 1.966580, 1.972716, 1.978852, 1.984988, 1.991123, 1.997259, 2.003395, 2.009531, 2.015667, 2.021803, 2.027939, 2.034075, 2.040210, 2.046346, 2.052482, 2.058618, 2.064754, 2.070890, 2.077026, 2.083162, 2.089297, 2.095433, 2.101569, 2.107705, 2.113841, 2.119977, 2.126113, 2.132249, 2.138384, 2.144520, 2.150656, 2.156792, 2.162928, 2.169064, 2.175200, 2.181336, 2.187471, 2.193607, 2.199743, 2.205879, 2.212015, 2.218151, 2.224287, 2.230423, 2.236558, 2.242694, 2.248830, 2.254966, 2.261102, 2.267238, 2.273374, 2.279510, 2.285645, 2.291781, 2.297917, 2.304053, 2.310189, 2.316325, 2.322461, 2.328597, 2.334732, 2.340868, 2.347004, 2.353140, 2.359276, 2.365412, 2.371548, 2.377684, 2.383819, 2.389955, 2.396091, 2.402227, 2.408363, 2.414499, 2.420635, 2.426771, 2.432906, 2.439042, 2.445178, 2.451314, 2.457450, 2.463586, 2.469722, 2.475858, 2.481993, 2.488129, 2.494265, 2.500401, 2.506537, 2.512673, 2.518809, 2.524945, 2.531080, 2.537216, 2.543352, 2.549488, 2.555624, 2.561760, 2.567896, 2.574032, 2.580167, 2.586303, 2.592439, 2.598575, 2.604711, 2.610847, 2.616983, 2.623119, 2.629254, 2.635390, 2.641526, 2.647662, 2.653798, 2.659934, 2.666070, 2.672206, 2.678341, 2.684477, 2.690613, 2.696749, 2.702885, 2.709021, 2.715157, 2.721293, 2.727428, 2.733564, 2.739700, 2.745836, 2.751972, 2.758108, 2.764244, 2.770380, 2.776515, 2.782651, 2.788787, 2.794923, 2.801059, 2.807195, 2.813331, 2.819467, 2.825602, 2.831738, 2.837874, 2.844010, 2.850146, 2.856282, 2.862418, 2.868554, 2.874689, 2.880825, 2.886961, 2.893097, 2.899233, 2.905369, 2.911505, 2.917641, 2.923776, 2.929912, 2.936048, 2.942184, 2.948320, 2.954456, 2.960592, 2.966728, 2.972863, 2.978999, 2.985135, 2.991271, 2.997407, 3.003543, 3.009679, 3.015815, 3.021950, 3.028086, 3.034222, 3.040358, 3.046494, 3.052630, 3.058766, 3.064902, 3.071037, 3.077173, 3.083309, 3.089445, 3.095581, 3.101717, 3.107853, 3.113989, 3.120124, 3.126260, 3.132396, 3.138532, 3.144668, 3.150804, 3.156940, 3.163076, 3.169211, 3.175347, 3.181483, 3.187619, 3.193755, 3.199891, 3.206027, 3.212163, 3.218298, 3.224434, 3.230570, 3.236706, 3.242842, 3.248978, 3.255114, 3.261250, 3.267385, 3.273521, 3.279657, 3.285793, 3.291929, 3.298065, 3.304201, 3.310337, 3.316472, 3.322608, 3.328744, 3.334880, 3.341016, 3.347152, 3.353288, 3.359424, 3.365559, 3.371695, 3.377831, 3.383967, 3.390103, 3.396239, 3.402375, 3.408511, 3.414646, 3.420782, 3.426918, 3.433054, 3.439190, 3.445326, 3.451462, 3.457598, 3.463733, 3.469869, 3.476005, 3.482141, 3.488277, 3.494413, 3.500549, 3.506685, 3.512820, 3.518956, 3.525092, 3.531228, 3.537364, 3.543500, 3.549636, 3.555772, 3.561907, 3.568043, 3.574179, 3.580315, 3.586451, 3.592587, 3.598723, 3.604859, 3.610994, 3.617130, 3.623266, 3.629402, 3.635538, 3.641674, 3.647810, 3.653946, 3.660081, 3.666217, 3.672353, 3.678489, 3.684625, 3.690761, 3.696897, 3.703033, 3.709168, 3.715304, 3.721440, 3.727576, 3.733712, 3.739848, 3.745984, 3.752120, 3.758255, 3.764391, 3.770527, 3.776663, 3.782799, 3.788935, 3.795071, 3.801207, 3.807342, 3.813478, 3.819614, 3.825750, 3.831886, 3.838022, 3.844158, 3.850294, 3.856429, 3.862565, 3.868701, 3.874837, 3.880973, 3.887109, 3.893245, 3.899381, 3.905516, 3.911652, 3.917788, 3.923924, 3.930060, 3.936196, 3.942332, 3.948468, 3.954603, 3.960739, 3.966875, 3.973011, 3.979147, 3.985283, 3.991419, 3.997555, 4.003690, 4.009826, 4.015962, 4.022098, 4.028234, 4.034370, 4.040506, 4.046642, 4.052777, 4.058913, 4.065049, 4.071185, 4.077321, 4.083457, 4.089593, 4.095729, 4.101864, 4.108000, 4.114136, 4.120272, 4.126408, 4.132544, 4.138680, 4.144816, 4.150951, 4.157087, 4.163223, 4.169359, 4.175495, 4.181631, 4.187767, 4.193903, 4.200038, 4.206174, 4.212310, 4.218446, 4.224582, 4.230718, 4.236854, 4.242990, 4.249125, 4.255261, 4.261397, 4.267533, 4.273669, 4.279805, 4.285941, 4.292077, 4.298212, 4.304348, 4.310484, 4.316620, 4.322756, 4.328892, 4.335028, 4.341164, 4.347299, 4.353435, 4.359571, 4.365707, 4.371843, 4.377979, 4.384115, 4.390251, 4.396386, 4.402522, 4.408658, 4.414794, 4.420930, 4.427066, 4.433202, 4.439338, 4.445473, 4.451609, 4.457745, 4.463881, 4.470017, 4.476153, 4.482289, 4.488425, 4.494560, 4.500696, 4.506832, 4.512968, 4.519104, 4.525240, 4.531376, 4.537512, 4.543647, 4.549783, 4.555919, 4.562055, 4.568191, 4.574327, 4.580463, 4.586599, 4.592734, 4.598870, 4.605006, 4.611142, 4.617278, 4.623414, 4.629550, 4.635686, 4.641821, 4.647957, 4.654093, 4.660229, 4.666365, 4.672501, 4.678637, 4.684773, 4.690908, 4.697044, 4.703180, 4.709316, 4.715452, 4.721588, 4.727724, 4.733860, 4.739995, 4.746131, 4.752267, 4.758403, 4.764539, 4.770675, 4.776811, 4.782947, 4.789082, 4.795218, 4.801354, 4.807490, 4.813626, 4.819762, 4.825898, 4.832034, 4.838169, 4.844305, 4.850441, 4.856577, 4.862713, 4.868849, 4.874985, 4.881121, 4.887256, 4.893392, 4.899528, 4.905664, 4.911800, 4.917936, 4.924072, 4.930208, 4.936343, 4.942479, 4.948615, 4.954751, 4.960887, 4.967023, 4.973159, 4.979295, 4.985430, 4.991566, 4.997702, 5.003838, 5.009974, 5.016110, 5.022246, 5.028382, 5.034517, 5.040653, 5.046789, 5.052925, 5.059061, 5.065197, 5.071333, 5.077469, 5.083604, 5.089740, 5.095876, 5.102012, 5.108148, 5.114284, 5.120420, 5.126556, 5.132691, 5.138827, 5.144963, 5.151099, 5.157235, 5.163371, 5.169507, 5.175643, 5.181778, 5.187914, 5.194050, 5.200186, 5.206322, 5.212458, 5.218594, 5.224730, 5.230865, 5.237001, 5.243137, 5.249273, 5.255409, 5.261545, 5.267681, 5.273817, 5.279952, 5.286088, 5.292224, 5.298360, 5.304496, 5.310632, 5.316768, 5.322904, 5.329039, 5.335175, 5.341311, 5.347447, 5.353583, 5.359719, 5.365855, 5.371991, 5.378126, 5.384262, 5.390398, 5.396534, 5.402670, 5.408806, 5.414942, 5.421078, 5.427213, 5.433349, 5.439485, 5.445621, 5.451757, 5.457893, 5.464029, 5.470165, 5.476300, 5.482436, 5.488572, 5.494708, 5.500844, 5.506980, 5.513116, 5.519252, 5.525387, 5.531523, 5.537659, 5.543795, 5.549931, 5.556067, 5.562203, 5.568339, 5.574474, 5.580610, 5.586746, 5.592882, 5.599018, 5.605154, 5.611290, 5.617426, 5.623561, 5.629697, 5.635833, 5.641969, 5.648105, 5.654241, 5.660377, 5.666513, 5.672648, 5.678784, 5.684920, 5.691056, 5.697192, 5.703328, 5.709464, 5.715600, 5.721735, 5.727871, 5.734007, 5.740143, 5.746279, 5.752415, 5.758551, 5.764687, 5.770822, 5.776958, 5.783094, 5.789230, 5.795366, 5.801502, 5.807638, 5.813774, 5.819909, 5.826045, 5.832181, 5.838317, 5.844453, 5.850589, 5.856725, 5.862861, 5.868996, 5.875132, 5.881268, 5.887404, 5.893540, 5.899676, 5.905812, 5.911948, 5.918083, 5.924219, 5.930355, 5.936491, 5.942627, 5.948763, 5.954899, 5.961035, 5.967170, 5.973306, 5.979442, 5.985578, 5.991714, 5.997850, 6.003986, 6.010122, 6.016257, 6.022393, 6.028529, 6.034665, 6.040801, 6.046937, 6.053073, 6.059209, 6.065344, 6.071480, 6.077616, 6.083752, 6.089888, 6.096024, 6.102160, 6.108296, 6.114431, 6.120567, 6.126703, 6.132839, 6.138975, 6.145111, 6.151247, 6.157383, 6.163518, 6.169654, 6.175790, 6.181926, 6.188062, 6.194198, 6.200334, 6.206470, 6.212605, 6.218741, 6.224877, 6.231013, 6.237149, 6.243285, 6.249421, 6.255557, 6.261692, 6.267828, 6.273964, 6.280100 ], "readings": [ 0.653740, 0.655940, 0.654140, 0.657610, 0.659990, 0.661120, 0.665500, 0.665920, 0.666580, 0.672090, 0.669020, 0.676430, 0.677770, 0.678930, 0.680820, 0.683360, 0.686250, 0.688910, 0.690010, 0.693820, 0.692510, 0.695700, 0.702650, 0.700860, 0.705410, 0.706910, 0.716390, 0.717180, 0.717330, 0.721380, 0.720940, 0.729810, 0.730530, 0.732310, 0.734860, 0.743450, 0.746830, 0.748300, 0.753110, 0.755920, 0.758180, 0.763210, 0.765080, 0.768400, 0.773240, 0.774460, 0.781750, 0.787740, 0.790240, 0.793180, 0.799000, 0.806090, 0.808760, 0.808790, 0.813450, 0.820290, 0.827070, 0.832550, 0.836450, 0.841030, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.166720, 0.164870, 0.166580, 0.163650, 0.162140, 0.166100, 0.161530, 0.161070, 0.161740, 0.160590, 0.162720, 0.161770, 0.159530, 0.156740, 0.156790, 0.153970, 0.155820, 0.156710, 0.155970, 0.154660, 0.155960, 0.154230, 0.151930, 0.155930, 0.151950, 0.153930, 0.149430, 0.152420, 0.152510, 0.147780, 0.146880, 0.152120, 0.146600, 0.148850, 0.146490, 0.147780, 0.146200, 0.148180, 0.145120, 0.149800, 0.144440, 0.147840, 0.142480, 0.143730, 0.142380, 0.144560, 0.144120, 0.143000, 0.140390, 0.144910, 0.145640, 0.143960, 0.142240, 0.144650, 0.145480, 0.142390, 0.137550, 0.138480, 0.142130, 0.140180, 0.142430, 0.138650, 0.137120, 0.139520, 0.142810, 0.138060, 0.140300, 0.136980, 0.135890, 0.136960, 0.140430, 0.136270, 0.136460, 0.138380, 0.141030, 0.140850, 0.137620, 0.139100, 0.137950, 0.136090, 0.140620, 0.137760, 0.138120, 0.137940, 0.135240, 0.139050, 0.138380, 0.137380, 0.137650, 0.137390, 0.137840, 0.136580, 0.138990, 0.136360, 0.133460, 0.137560, 0.135530, 0.135800, 0.136980, 0.139160, 0.134780, 0.137100, 0.133810, 0.136000, 0.133380, 0.138440, 0.139400, 0.137070, 0.137700, 0.137720, 0.137430, 0.135180, 0.135750, 0.138580, 0.137550, 0.139680, 0.136420, 0.137350, 0.136710, 0.139700, 0.140950, 0.136520, 0.135140, 0.138560, 0.137110, 0.136600, 0.138640, 0.137360, 0.139100, 0.139380, 0.140620, 0.143290, 0.143310, 0.140890, 0.141010, 0.141310, 0.142430, 0.142260, 0.141740, 0.139100, 0.140280, 0.140310, 0.140270, 0.142780, 0.141320, 0.142340, 0.144620, 0.143950, 0.143830, 0.141390, 0.143320, 0.141600, 0.143770, 0.142360, 0.146020, 0.144460, 0.143800, 0.145640, 0.144590, 0.145450, 0.147950, 0.148930, 0.146590, 0.146300, 0.148950, 0.148920, 0.147020, 0.146930, 0.150160, 0.150220, 0.151460, 0.148300, 0.151300, 0.152620, 0.153110, 0.153960, 0.152080, 0.154270, 0.154650, 0.157240, 0.154830, 0.156920, 0.152800, 0.157990, 0.159560, 0.155490, 0.158150, 0.158470, 0.162400, 0.162520, 0.161650, 0.161670, 0.160940, 0.163620, 0.166920, 0.164190, 0.163010, 0.165510, 0.169120, 0.167690, 0.167930, 0.167620, 0.170210, 0.172010, 0.170320, 0.176060, 0.171760, 0.173430, 0.174130, 0.176800, 0.178630, 0.174460, 0.177180, 0.179200, 0.176480, 0.183870, 0.183560, 0.181400, 0.184930, 0.184290, 0.185390, 0.186900, 0.187900, 0.185810, 0.192360, 0.193170, 0.418620, 0.419770, 0.424890, 0.426030, 0.428280, 0.432960, 0.437440, 0.439390, 0.443400, 0.444610, 0.446980, 0.449370, 0.451180, 0.454420, 0.459970, 0.464370, 0.466860, 0.470490, 0.472150, 0.477200, 0.479250, 0.482620, 0.488110, 0.494070, 0.495930, 0.501940, 0.504930, 0.507840, 0.513410, 0.519440, 0.522410, 0.525360, 0.532870, 0.536180, 0.538670, 0.546350, 0.549030, 0.556250, 0.565750, 0.567960, 0.571460, 0.578370, 0.586410, 0.590720, 0.601750, 0.604190, 0.612450, 0.620800, 0.622370, 0.635590, 0.639990, 0.645070, 0.653040, 0.661490, 0.671410, 0.680640, 0.686810, 0.697850, 0.708520, 0.717260, 0.728880, 0.735500, 0.743570, 0.758790, 0.765370, 0.782990, 0.789270, 0.804380, 0.814880, 0.828450, 0.847700, 0.860240, 0.876100, 0.888090, 0.905020, 0.918670, 0.936810, 0.952870, 0.971690, 0.991730, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.204720, 0.202570, 0.204860, 0.203350, 0.198920, 0.200580, 0.195210, 0.196810, 0.197820, 0.194420, 0.192770, 0.195310, 0.191210, 0.188460, 0.191240, 0.191690, 0.189610, 0.188470, 0.187080, 0.183440, 0.182270, 0.185850, 0.183740, 0.179370, 0.184090, 0.182800, 0.181720, 0.183450, 0.181730, 0.177150, 0.179000, 0.175710, 0.176080, 0.174820, 0.174550, 0.177730, 0.176130, 0.173240, 0.171330, 0.174500, 0.172350, 0.168770, 0.170970, 0.172350, 0.170620, 0.167830, 0.167470, 0.171560, 0.166380, 0.164000, 0.170620, 0.165350, 0.168140, 0.163570, 0.166190, 0.162390, 0.162590, 0.160660, 0.163550, 0.167100, 0.161980, 0.166410, 0.160700, 0.159030, 0.160480, 0.162950, 0.161740, 0.161260, 0.163240, 0.158440, 0.161040, 0.157610, 0.159490, 0.159340, 0.162310, 0.160510, 0.155730, 0.158890, 0.158990, 0.155450, 0.159140, 0.156230, 0.156770, 0.158860, 0.157360, 0.153550, 0.152440, 0.153090, 0.157250, 0.157320, 0.154700, 0.153720, 0.151470, 0.157830, 0.154220, 0.156430, 0.152990, 0.153840, 0.152560, 0.158200, 0.152010, 0.152030, 0.153290, 0.150390, 0.152700, 0.155750, 0.156230, 0.150960, 0.153920, 0.155140, 0.154540, 0.156740, 0.152070, 0.152530, 0.150320, 0.154510, 0.156910, 0.155280, 0.152640, 0.150670, 0.154030, 0.151460, 0.153670, 0.149720, 0.152590, 0.155550, 0.153660, 0.149730, 0.151040, 0.153050, 0.154030, 0.155910, 0.154310, 0.154090, 0.153810, 0.157480, 0.151700, 0.156200, 0.155220, 0.157460, 0.157170, 0.152590, 0.155910, 0.156300, 0.157020, 0.154680, 0.154310, 0.155540, 0.153810, 0.156770, 0.156410, 0.157930, 0.158880, 0.157930, 0.158540, 0.158240, 0.161640, 0.158740, 0.158340, 0.158360, 0.159190, 0.161380, 0.162330, 0.158950, 0.162280, 0.160820, 0.161190, 0.160910, 0.158430, 0.160020, 0.162940, 0.162920, 0.161910, 0.164350, 0.161400, 0.163220, 0.166680, 0.162490, 0.164790, 0.165130, 0.166740, 0.167600, 0.165860, 0.164920, 0.166540, 0.167260, 0.170500, 0.169190, 0.168190, 0.170820, 0.170110, 0.170530, 0.172040, 0.170600, 0.174530, 0.172260, 0.173980, 0.172810, 0.174880, 0.174430, 0.177340, 0.179920, 0.176880, 0.179140, 0.175580, 0.179170, 0.181050, 0.181890, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.990140, 0.982070, 0.973160, 0.968150, 0.961540, 0.950540, 0.945040, 0.940500, 0.929700, 0.924980, 0.920310, 0.909460, 0.905400, 0.897430, 0.891940, 0.887590, 0.882750, 0.876900, 0.870910, 0.865300, 0.861540, 0.851240, 0.848690, 0.841240, 0.836340, 0.829880, 0.826040, 0.819970, 0.817150, 0.810050, 0.806410, 0.804370, 0.801010, 0.791060, 0.791070, 0.784540, 0.781070, 0.774100, 0.776010, 0.769570, 0.766640, 0.761060, 0.756260, 0.754170, 0.752260, 0.748410, 0.744440, 0.740900, 0.737540, 0.734800, 0.733580, 0.725500, 0.721530, 0.720960, 0.716050, 0.711990, 0.712510, 0.713440, 0.706800, 0.704860, 0.700360, 0.697840, 0.695090, 0.693490, 0.688950, 0.687890, 0.689540, 0.687360, 0.681070, 0.678640, 0.676890, 0.676220, 0.674970, 0.670380, 0.669220, 0.664220, 0.663570, 0.661690, 0.663610, 0.659170, 0.657790, 0.654520, 0.651720, 0.649440, 0.646070, 0.649310, 0.642800, 0.643150, 0.641780, 0.644320, 0.637580, 0.636980, 0.636720, 0.637150, 0.634830, 0.630200, 0.628850, 0.627710, 0.628390, 0.624680, 0.624320, 0.627350, 0.622510, 0.618340, 0.621800, 0.616200, 0.621580, 0.613810, 0.615050, 0.612270, 0.616950, 0.630860, 0.648730, 0.662330, 0.682180, 0.698120, 0.720660, 0.743120, 0.765000, 0.785090, 0.812900, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.795830, 0.770900, 0.748170, 0.721550, 0.700320, 0.681730, 0.659260, 0.639870, 0.621370, 0.608260, 0.609500, 0.611740, 0.612290, 0.617690, 0.613110, 0.617960, 0.617930, 0.617780, 0.620670, 0.621870, 0.621270, 0.619540, 0.626280, 0.628310, 0.623570, 0.626170, 0.632610, 0.630980, 0.628560, 0.632960, 0.636120, 0.635080, 0.635730, 0.641060, 0.640170, 0.642670, 0.641800, 0.645030, 0.649650, 0.650340, 0.652180 ], "valid": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "odometry": [ -0.275, -0.3696, 1.9638 ], "estimate": [ null, null, null ], "true_pose": [ null, null, null ] } -{ "nrays": 1024, "min_theta": 0.003100, "max_theta": 6.280100, "theta": [ 0.003100, 0.009236, 0.015372, 0.021508, 0.027643, 0.033779, 0.039915, 0.046051, 0.052187, 0.058323, 0.064459, 0.070595, 0.076730, 0.082866, 0.089002, 0.095138, 0.101274, 0.107410, 0.113546, 0.119682, 0.125817, 0.131953, 0.138089, 0.144225, 0.150361, 0.156497, 0.162633, 0.168769, 0.174904, 0.181040, 0.187176, 0.193312, 0.199448, 0.205584, 0.211720, 0.217856, 0.223991, 0.230127, 0.236263, 0.242399, 0.248535, 0.254671, 0.260807, 0.266943, 0.273078, 0.279214, 0.285350, 0.291486, 0.297622, 0.303758, 0.309894, 0.316030, 0.322165, 0.328301, 0.334437, 0.340573, 0.346709, 0.352845, 0.358981, 0.365117, 0.371252, 0.377388, 0.383524, 0.389660, 0.395796, 0.401932, 0.408068, 0.414204, 0.420339, 0.426475, 0.432611, 0.438747, 0.444883, 0.451019, 0.457155, 0.463291, 0.469426, 0.475562, 0.481698, 0.487834, 0.493970, 0.500106, 0.506242, 0.512378, 0.518513, 0.524649, 0.530785, 0.536921, 0.543057, 0.549193, 0.555329, 0.561465, 0.567600, 0.573736, 0.579872, 0.586008, 0.592144, 0.598280, 0.604416, 0.610552, 0.616687, 0.622823, 0.628959, 0.635095, 0.641231, 0.647367, 0.653503, 0.659639, 0.665774, 0.671910, 0.678046, 0.684182, 0.690318, 0.696454, 0.702590, 0.708726, 0.714861, 0.720997, 0.727133, 0.733269, 0.739405, 0.745541, 0.751677, 0.757813, 0.763948, 0.770084, 0.776220, 0.782356, 0.788492, 0.794628, 0.800764, 0.806900, 0.813035, 0.819171, 0.825307, 0.831443, 0.837579, 0.843715, 0.849851, 0.855987, 0.862122, 0.868258, 0.874394, 0.880530, 0.886666, 0.892802, 0.898938, 0.905074, 0.911209, 0.917345, 0.923481, 0.929617, 0.935753, 0.941889, 0.948025, 0.954161, 0.960296, 0.966432, 0.972568, 0.978704, 0.984840, 0.990976, 0.997112, 1.003248, 1.009383, 1.015519, 1.021655, 1.027791, 1.033927, 1.040063, 1.046199, 1.052335, 1.058470, 1.064606, 1.070742, 1.076878, 1.083014, 1.089150, 1.095286, 1.101422, 1.107557, 1.113693, 1.119829, 1.125965, 1.132101, 1.138237, 1.144373, 1.150509, 1.156644, 1.162780, 1.168916, 1.175052, 1.181188, 1.187324, 1.193460, 1.199596, 1.205731, 1.211867, 1.218003, 1.224139, 1.230275, 1.236411, 1.242547, 1.248683, 1.254818, 1.260954, 1.267090, 1.273226, 1.279362, 1.285498, 1.291634, 1.297770, 1.303905, 1.310041, 1.316177, 1.322313, 1.328449, 1.334585, 1.340721, 1.346857, 1.352992, 1.359128, 1.365264, 1.371400, 1.377536, 1.383672, 1.389808, 1.395944, 1.402079, 1.408215, 1.414351, 1.420487, 1.426623, 1.432759, 1.438895, 1.445031, 1.451166, 1.457302, 1.463438, 1.469574, 1.475710, 1.481846, 1.487982, 1.494118, 1.500253, 1.506389, 1.512525, 1.518661, 1.524797, 1.530933, 1.537069, 1.543205, 1.549340, 1.555476, 1.561612, 1.567748, 1.573884, 1.580020, 1.586156, 1.592292, 1.598427, 1.604563, 1.610699, 1.616835, 1.622971, 1.629107, 1.635243, 1.641379, 1.647514, 1.653650, 1.659786, 1.665922, 1.672058, 1.678194, 1.684330, 1.690466, 1.696601, 1.702737, 1.708873, 1.715009, 1.721145, 1.727281, 1.733417, 1.739553, 1.745688, 1.751824, 1.757960, 1.764096, 1.770232, 1.776368, 1.782504, 1.788640, 1.794775, 1.800911, 1.807047, 1.813183, 1.819319, 1.825455, 1.831591, 1.837727, 1.843862, 1.849998, 1.856134, 1.862270, 1.868406, 1.874542, 1.880678, 1.886814, 1.892949, 1.899085, 1.905221, 1.911357, 1.917493, 1.923629, 1.929765, 1.935901, 1.942036, 1.948172, 1.954308, 1.960444, 1.966580, 1.972716, 1.978852, 1.984988, 1.991123, 1.997259, 2.003395, 2.009531, 2.015667, 2.021803, 2.027939, 2.034075, 2.040210, 2.046346, 2.052482, 2.058618, 2.064754, 2.070890, 2.077026, 2.083162, 2.089297, 2.095433, 2.101569, 2.107705, 2.113841, 2.119977, 2.126113, 2.132249, 2.138384, 2.144520, 2.150656, 2.156792, 2.162928, 2.169064, 2.175200, 2.181336, 2.187471, 2.193607, 2.199743, 2.205879, 2.212015, 2.218151, 2.224287, 2.230423, 2.236558, 2.242694, 2.248830, 2.254966, 2.261102, 2.267238, 2.273374, 2.279510, 2.285645, 2.291781, 2.297917, 2.304053, 2.310189, 2.316325, 2.322461, 2.328597, 2.334732, 2.340868, 2.347004, 2.353140, 2.359276, 2.365412, 2.371548, 2.377684, 2.383819, 2.389955, 2.396091, 2.402227, 2.408363, 2.414499, 2.420635, 2.426771, 2.432906, 2.439042, 2.445178, 2.451314, 2.457450, 2.463586, 2.469722, 2.475858, 2.481993, 2.488129, 2.494265, 2.500401, 2.506537, 2.512673, 2.518809, 2.524945, 2.531080, 2.537216, 2.543352, 2.549488, 2.555624, 2.561760, 2.567896, 2.574032, 2.580167, 2.586303, 2.592439, 2.598575, 2.604711, 2.610847, 2.616983, 2.623119, 2.629254, 2.635390, 2.641526, 2.647662, 2.653798, 2.659934, 2.666070, 2.672206, 2.678341, 2.684477, 2.690613, 2.696749, 2.702885, 2.709021, 2.715157, 2.721293, 2.727428, 2.733564, 2.739700, 2.745836, 2.751972, 2.758108, 2.764244, 2.770380, 2.776515, 2.782651, 2.788787, 2.794923, 2.801059, 2.807195, 2.813331, 2.819467, 2.825602, 2.831738, 2.837874, 2.844010, 2.850146, 2.856282, 2.862418, 2.868554, 2.874689, 2.880825, 2.886961, 2.893097, 2.899233, 2.905369, 2.911505, 2.917641, 2.923776, 2.929912, 2.936048, 2.942184, 2.948320, 2.954456, 2.960592, 2.966728, 2.972863, 2.978999, 2.985135, 2.991271, 2.997407, 3.003543, 3.009679, 3.015815, 3.021950, 3.028086, 3.034222, 3.040358, 3.046494, 3.052630, 3.058766, 3.064902, 3.071037, 3.077173, 3.083309, 3.089445, 3.095581, 3.101717, 3.107853, 3.113989, 3.120124, 3.126260, 3.132396, 3.138532, 3.144668, 3.150804, 3.156940, 3.163076, 3.169211, 3.175347, 3.181483, 3.187619, 3.193755, 3.199891, 3.206027, 3.212163, 3.218298, 3.224434, 3.230570, 3.236706, 3.242842, 3.248978, 3.255114, 3.261250, 3.267385, 3.273521, 3.279657, 3.285793, 3.291929, 3.298065, 3.304201, 3.310337, 3.316472, 3.322608, 3.328744, 3.334880, 3.341016, 3.347152, 3.353288, 3.359424, 3.365559, 3.371695, 3.377831, 3.383967, 3.390103, 3.396239, 3.402375, 3.408511, 3.414646, 3.420782, 3.426918, 3.433054, 3.439190, 3.445326, 3.451462, 3.457598, 3.463733, 3.469869, 3.476005, 3.482141, 3.488277, 3.494413, 3.500549, 3.506685, 3.512820, 3.518956, 3.525092, 3.531228, 3.537364, 3.543500, 3.549636, 3.555772, 3.561907, 3.568043, 3.574179, 3.580315, 3.586451, 3.592587, 3.598723, 3.604859, 3.610994, 3.617130, 3.623266, 3.629402, 3.635538, 3.641674, 3.647810, 3.653946, 3.660081, 3.666217, 3.672353, 3.678489, 3.684625, 3.690761, 3.696897, 3.703033, 3.709168, 3.715304, 3.721440, 3.727576, 3.733712, 3.739848, 3.745984, 3.752120, 3.758255, 3.764391, 3.770527, 3.776663, 3.782799, 3.788935, 3.795071, 3.801207, 3.807342, 3.813478, 3.819614, 3.825750, 3.831886, 3.838022, 3.844158, 3.850294, 3.856429, 3.862565, 3.868701, 3.874837, 3.880973, 3.887109, 3.893245, 3.899381, 3.905516, 3.911652, 3.917788, 3.923924, 3.930060, 3.936196, 3.942332, 3.948468, 3.954603, 3.960739, 3.966875, 3.973011, 3.979147, 3.985283, 3.991419, 3.997555, 4.003690, 4.009826, 4.015962, 4.022098, 4.028234, 4.034370, 4.040506, 4.046642, 4.052777, 4.058913, 4.065049, 4.071185, 4.077321, 4.083457, 4.089593, 4.095729, 4.101864, 4.108000, 4.114136, 4.120272, 4.126408, 4.132544, 4.138680, 4.144816, 4.150951, 4.157087, 4.163223, 4.169359, 4.175495, 4.181631, 4.187767, 4.193903, 4.200038, 4.206174, 4.212310, 4.218446, 4.224582, 4.230718, 4.236854, 4.242990, 4.249125, 4.255261, 4.261397, 4.267533, 4.273669, 4.279805, 4.285941, 4.292077, 4.298212, 4.304348, 4.310484, 4.316620, 4.322756, 4.328892, 4.335028, 4.341164, 4.347299, 4.353435, 4.359571, 4.365707, 4.371843, 4.377979, 4.384115, 4.390251, 4.396386, 4.402522, 4.408658, 4.414794, 4.420930, 4.427066, 4.433202, 4.439338, 4.445473, 4.451609, 4.457745, 4.463881, 4.470017, 4.476153, 4.482289, 4.488425, 4.494560, 4.500696, 4.506832, 4.512968, 4.519104, 4.525240, 4.531376, 4.537512, 4.543647, 4.549783, 4.555919, 4.562055, 4.568191, 4.574327, 4.580463, 4.586599, 4.592734, 4.598870, 4.605006, 4.611142, 4.617278, 4.623414, 4.629550, 4.635686, 4.641821, 4.647957, 4.654093, 4.660229, 4.666365, 4.672501, 4.678637, 4.684773, 4.690908, 4.697044, 4.703180, 4.709316, 4.715452, 4.721588, 4.727724, 4.733860, 4.739995, 4.746131, 4.752267, 4.758403, 4.764539, 4.770675, 4.776811, 4.782947, 4.789082, 4.795218, 4.801354, 4.807490, 4.813626, 4.819762, 4.825898, 4.832034, 4.838169, 4.844305, 4.850441, 4.856577, 4.862713, 4.868849, 4.874985, 4.881121, 4.887256, 4.893392, 4.899528, 4.905664, 4.911800, 4.917936, 4.924072, 4.930208, 4.936343, 4.942479, 4.948615, 4.954751, 4.960887, 4.967023, 4.973159, 4.979295, 4.985430, 4.991566, 4.997702, 5.003838, 5.009974, 5.016110, 5.022246, 5.028382, 5.034517, 5.040653, 5.046789, 5.052925, 5.059061, 5.065197, 5.071333, 5.077469, 5.083604, 5.089740, 5.095876, 5.102012, 5.108148, 5.114284, 5.120420, 5.126556, 5.132691, 5.138827, 5.144963, 5.151099, 5.157235, 5.163371, 5.169507, 5.175643, 5.181778, 5.187914, 5.194050, 5.200186, 5.206322, 5.212458, 5.218594, 5.224730, 5.230865, 5.237001, 5.243137, 5.249273, 5.255409, 5.261545, 5.267681, 5.273817, 5.279952, 5.286088, 5.292224, 5.298360, 5.304496, 5.310632, 5.316768, 5.322904, 5.329039, 5.335175, 5.341311, 5.347447, 5.353583, 5.359719, 5.365855, 5.371991, 5.378126, 5.384262, 5.390398, 5.396534, 5.402670, 5.408806, 5.414942, 5.421078, 5.427213, 5.433349, 5.439485, 5.445621, 5.451757, 5.457893, 5.464029, 5.470165, 5.476300, 5.482436, 5.488572, 5.494708, 5.500844, 5.506980, 5.513116, 5.519252, 5.525387, 5.531523, 5.537659, 5.543795, 5.549931, 5.556067, 5.562203, 5.568339, 5.574474, 5.580610, 5.586746, 5.592882, 5.599018, 5.605154, 5.611290, 5.617426, 5.623561, 5.629697, 5.635833, 5.641969, 5.648105, 5.654241, 5.660377, 5.666513, 5.672648, 5.678784, 5.684920, 5.691056, 5.697192, 5.703328, 5.709464, 5.715600, 5.721735, 5.727871, 5.734007, 5.740143, 5.746279, 5.752415, 5.758551, 5.764687, 5.770822, 5.776958, 5.783094, 5.789230, 5.795366, 5.801502, 5.807638, 5.813774, 5.819909, 5.826045, 5.832181, 5.838317, 5.844453, 5.850589, 5.856725, 5.862861, 5.868996, 5.875132, 5.881268, 5.887404, 5.893540, 5.899676, 5.905812, 5.911948, 5.918083, 5.924219, 5.930355, 5.936491, 5.942627, 5.948763, 5.954899, 5.961035, 5.967170, 5.973306, 5.979442, 5.985578, 5.991714, 5.997850, 6.003986, 6.010122, 6.016257, 6.022393, 6.028529, 6.034665, 6.040801, 6.046937, 6.053073, 6.059209, 6.065344, 6.071480, 6.077616, 6.083752, 6.089888, 6.096024, 6.102160, 6.108296, 6.114431, 6.120567, 6.126703, 6.132839, 6.138975, 6.145111, 6.151247, 6.157383, 6.163518, 6.169654, 6.175790, 6.181926, 6.188062, 6.194198, 6.200334, 6.206470, 6.212605, 6.218741, 6.224877, 6.231013, 6.237149, 6.243285, 6.249421, 6.255557, 6.261692, 6.267828, 6.273964, 6.280100 ], "readings": [ 0.455580, 0.457450, 0.457360, 0.459330, 0.464180, 0.464420, 0.466860, 0.463460, 0.468730, 0.471080, 0.473120, 0.474470, 0.473560, 0.476140, 0.473910, 0.480080, 0.481610, 0.483900, 0.481230, 0.483490, 0.488250, 0.487980, 0.492440, 0.492720, 0.496720, 0.499550, 0.497520, 0.500540, 0.505780, 0.505060, 0.509890, 0.509660, 0.514800, 0.513940, 0.517710, 0.521770, 0.519920, 0.525700, 0.525960, 0.529320, 0.531360, 0.536360, 0.538810, 0.541510, 0.541340, 0.548970, 0.550160, 0.550230, 0.555310, 0.556560, 0.558230, 0.564240, 0.565090, 0.569970, 0.572210, 0.576880, 0.578510, 0.583280, 0.585430, 0.590390, 0.594940, 0.596820, 0.603090, 0.608430, 0.606560, 0.613840, 0.617560, 0.622030, 0.626090, 0.630580, 0.638160, 0.642280, 0.646540, 0.650380, 0.651450, 0.663040, null, null, null, null, null, null, null, 0.999610, 0.994010, 0.992320, 0.985100, 0.984520, 0.976920, 0.972890, 0.970400, 0.963920, 0.958370, 0.957020, 0.956400, 0.950390, 0.948800, 0.947060, 0.939820, 0.936310, 0.936330, 0.929100, 0.928540, 0.921890, 0.917780, 0.915810, 0.913420, 0.910920, 0.908720, 0.912710, 0.924270, 0.937450, 0.943710, 0.959190, 0.972890, 0.982550, 0.996560, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.984390, 0.919780, 0.859150, 0.809710, 0.813990, 0.811490, 0.810280, 0.810370, 0.814410, 0.813500, 0.812820, 0.815380, 0.815030, 0.512350, 0.493270, 0.473510, 0.461800, 0.446340, 0.430590, 0.421220, 0.408200, 0.396850, 0.385780, 0.376700, 0.366180, 0.356780, 0.344960, 0.337190, 0.331140, 0.325540, 0.314810, 0.308830, 0.302910, 0.297510, 0.290810, 0.282380, 0.278640, 0.270300, 0.269450, 0.262180, 0.259340, 0.254170, 0.249140, 0.245790, 0.242740, 0.240120, 0.234850, 0.231130, 0.229600, 0.220430, 0.218640, 0.213300, 0.214770, 0.211270, 0.207630, 0.207790, 0.202320, 0.199420, 0.196790, 0.195970, 0.190320, 0.190110, 0.189850, 0.183510, 0.183490, 0.179770, 0.179150, 0.177760, 0.175900, 0.171990, 0.166850, 0.167150, 0.167270, 0.166620, 0.165760, 0.161740, 0.159810, 0.160110, 0.158600, 0.154820, 0.153500, 0.150830, 0.153150, 0.151990, 0.145550, 0.146900, 0.144550, 0.145510, 0.143460, 0.145720, 0.142170, 0.138920, 0.136530, 0.137850, 0.134800, 0.135030, 0.135010, 0.132630, 0.130660, 0.134800, 0.129870, 0.130190, 0.129720, 0.125710, 0.129510, 0.126350, 0.126150, 0.124360, 0.122400, 0.121400, 0.123390, 0.123040, 0.121330, 0.121170, 0.120140, 0.119740, 0.121170, 0.116560, 0.112430, 0.115610, 0.115070, 0.111880, 0.113610, 0.112520, 0.110530, 0.110380, 0.113080, 0.113760, 0.110460, 0.109060, 0.107450, 0.109640, 0.105230, 0.104690, 0.106060, 0.105070, 0.105800, 0.107610, 0.103360, 0.106590, 0.105280, 0.103150, 0.101940, 0.105480, 0.099900, 0.102900, 0.101350, 0.102170, 0.099780, 0.105160, 0.104480, 0.106540, 0.107900, 0.107770, 0.110620, 0.113350, 0.112260, 0.116130, 0.112030, 0.115660, 0.115260, 0.121190, 0.118600, 0.120670, 0.123800, 0.122160, 0.127090, 0.126550, 0.128330, 0.131600, 0.134740, 0.132720, 0.135000, 0.137410, 0.141640, 0.137500, 0.143370, 0.145820, 0.144950, 0.150860, 0.148700, 0.154690, 0.157040, 0.156710, 0.161060, 0.167360, 0.170040, 0.172390, 0.173710, 0.176100, 0.183420, 0.186020, 0.188380, 0.187630, 0.194360, 0.200850, 0.201850, 0.204660, 0.207610, 0.220210, 0.220760, 0.227410, 0.229850, 0.239280, 0.244230, 0.252130, 0.258680, 0.264110, 0.273210, 0.280400, 0.286630, 0.300190, 0.309670, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.394340, 0.389420, 0.385840, 0.382730, 0.382130, 0.373990, 0.373940, 0.372710, 0.367130, 0.363880, 0.359790, 0.363040, 0.357090, 0.351930, 0.354660, 0.346290, 0.348570, 0.343750, 0.340510, 0.338660, 0.340600, 0.334330, 0.335610, 0.331980, 0.332160, 0.329640, 0.326960, 0.324260, 0.322170, 0.321600, 0.318120, 0.315270, 0.314730, 0.313640, 0.314450, 0.310200, 0.309210, 0.304440, 0.302930, 0.300160, 0.300880, 0.299760, 0.301000, 0.296020, 0.296160, 0.291460, 0.295530, 0.291840, 0.289070, 0.291450, 0.289020, 0.285280, 0.287800, 0.283590, 0.286600, 0.281470, 0.279750, 0.279660, 0.276000, 0.277760, 0.277540, 0.274720, 0.273510, 0.271300, 0.275840, 0.269160, 0.272100, 0.268270, 0.267680, 0.267660, 0.269110, 0.267260, 0.264000, 0.265180, 0.262970, 0.260230, 0.263500, 0.260260, 0.256950, 0.260270, 0.256150, 0.254840, 0.256580, 0.258010, 0.256600, 0.255550, 0.254350, 0.252730, 0.250490, 0.255090, 0.251430, 0.253590, 0.248180, 0.251660, 0.249860, 0.250790, 0.249580, 0.254520, 0.261970, 0.268940, 0.272150, 0.273890, 0.284410, 0.286890, 0.291780, 0.298070, 0.307710, 0.313620, 0.315290, 0.329040, 0.332030, 0.343130, 0.349860, 0.362780, 0.367050, 0.379840, 0.389880, 0.399280, 0.410500, 0.423270, 0.438510, 0.454820, 0.466380, 0.481460, 0.503250, 0.515940, 0.538450, 0.564280, 0.587540, 0.608270, 0.641560, 0.671730, 0.704770, 0.741850, 0.785480, 0.830280, 0.884610, 0.947750, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.991480, 0.977300, 0.969500, 0.953000, 0.943940, 0.928640, 0.915150, 0.907480, 0.895190, 0.885780, 0.877160, 0.869560, 0.858050, 0.850150, 0.838270, 0.831380, 0.819780, 0.812790, 0.804400, 0.793400, 0.784830, 0.781010, 0.770460, 0.766220, 0.757470, 0.751790, 0.747710, 0.737070, 0.731860, 0.725130, 0.720280, 0.712970, 0.705800, 0.700270, 0.692560, 0.688450, 0.683800, 0.677900, 0.670930, 0.669260, 0.664560, 0.657130, 0.652630, 0.648510, 0.642980, 0.637810, 0.632830, 0.627010, 0.623000, 0.624080, 0.615690, 0.613170, 0.607170, 0.605680, 0.597280, 0.598700, 0.593150, 0.588800, 0.585870, 0.581000, 0.577710, 0.576150, 0.572090, 0.569270, 0.566410, 0.561920, 0.559880, 0.557150, 0.554630, 0.549700, 0.547480, 0.545560, 0.540480, 0.539660, 0.537200, 0.530080, 0.532730, 0.530650, 0.525350, 0.519400, 0.523210, 0.516350, 0.519940, 0.515850, 0.511050, 0.511080, 0.508200, 0.503800, 0.504430, 0.498310, 0.496240, 0.496340, 0.494430, 0.491180, 0.490760, 0.489400, 0.488100, 0.486830, 0.484100, 0.480840, 0.481710, 0.480960, 0.477170, 0.484330, 0.484780, 0.495110, 0.498520, 0.505280, 0.508240, 0.520280, 0.525700, 0.532420, 0.533900, 0.547790, 0.551190, 0.557690, 0.563580, 0.575960, 0.586240, 0.589810, 0.600870, 0.607240, 0.616710, 0.624180, 0.637350, 0.648320, 0.656010, 0.664550, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0.621070, 0.580260, 0.547730, 0.516890, 0.486470, 0.464000, 0.442220, 0.423310, 0.422620, 0.422810, 0.419680, 0.422980, 0.422670, 0.421460, 0.423370, 0.423520, 0.421160, 0.424520, 0.426340, 0.424230, 0.428010, 0.428110, 0.428710, 0.426130, 0.428130, 0.426070, 0.431080, 0.431670, 0.428150, 0.430560, 0.433100, 0.432360, 0.433470, 0.431770, 0.433580, 0.439450, 0.438530, 0.436090, 0.442210, 0.438140, 0.438880, 0.443420, 0.442580, 0.443360, 0.442350, 0.443820, 0.444750, 0.450800, 0.446290, 0.450820, 0.451600, 0.451210, 0.451710, 0.454390, 0.454430 ], "valid": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "odometry": [ -0.3522, -0.1848, 1.9681 ], "estimate": [ null, null, null ], "true_pose": [ null, null, null ] } diff --git a/misc/tests/failure2.json b/misc/tests/failure2.json deleted file mode 100644 index 161f333..0000000 --- a/misc/tests/failure2.json +++ /dev/null @@ -1,3 +0,0 @@ -{ "nrays": 30, "min_theta": -1.570796, "max_theta": 1.570796, "odometry": [ 0.000000, 0.000000, 0.000000 ], "estimate": [ null, null, null ], "true_pose": [ 0.000000, 0.000000, 0.000000 ], "theta": [ -1.570796, -1.462466, -1.354135, -1.245804, -1.137473, -1.029142, -0.920812, -0.812481, -0.704150, -0.595819, -0.487489, -0.379158, -0.270827, -0.162496, -0.054165, 0.054165, 0.162496, 0.270827, 0.379158, 0.487489, 0.595819, 0.704150, 0.812481, 0.920812, 1.029142, 1.137473, 1.245804, 1.354135, 1.462466, 1.570796 ], "readings": [ 5.000779, 5.019853, 5.116651, 5.256418, 5.504004, 5.844980, 6.273660, 6.884493, 6.555530, 6.039816, 5.661363, 5.396162, 5.171709, 5.060509, 5.001907, 5.016016, 5.056834, 5.195163, 5.379970, 5.653023, 6.042297, 6.551263, 6.892441, 6.273115, 5.829970, 5.486435, 5.254229, 5.104061, 5.041641, 4.998651 ], "valid": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "true_alpha": [ 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796 ], "timestamp": [ 46, 0 ] } -{ "nrays": 30, "min_theta": -1.570796, "max_theta": 1.570796, "odometry": [ 0.921193, -0.029529, 0.760407 ], "estimate": [ null, null, null ], "true_pose": [ 1.000000, 0.000000, 0.785398 ], "theta": [ -1.570796, -1.462466, -1.354135, -1.245804, -1.137473, -1.029142, -0.920812, -0.812481, -0.704150, -0.595819, -0.487489, -0.379158, -0.270827, -0.162496, -0.054165, 0.054165, 0.162496, 0.270827, 0.379158, 0.487489, 0.595819, 0.704150, 0.812481, 0.920812, 1.029142, 1.137473, 1.245804, 1.354135, 1.462466, 1.570796 ], "readings": [ 5.639745, 5.147953, 4.745922, 4.463843, 4.254572, 4.112768, 4.019830, 4.007804, 4.016081, 4.079111, 4.189281, 4.362703, 4.580223, 4.918687, 5.373213, 5.993529, 6.157613, 5.734605, 5.436404, 5.217013, 5.081848, 5.023669, 5.008782, 5.052871, 5.164381, 5.336770, 5.575088, 5.943600, 6.412568, 7.069774 ], "valid": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "true_alpha": [ 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 2.356194, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398, 0.785398 ], "timestamp": [ 46, 0 ] } - diff --git a/scripts/cmd_utils.rb b/scripts/cmd_utils.rb deleted file mode 100644 index 870996a..0000000 --- a/scripts/cmd_utils.rb +++ /dev/null @@ -1,43 +0,0 @@ -def execute_cmd_verb(cmd, verbose, exit_on_error) - $stderr.puts "$ " + cmd - - if verbose - system cmd - else - output = `#{cmd}` - end - - if exit_on_error && $?.exitstatus != 0 - $stderr.puts "\n\n\t command:\n\n\t#{cmd.inspect}\n\n\tFAILED, exit status = #{$?.exitstatus}\n\n" - exit($?.exitstatus || -1) - end - - $?.exitstatus -end - -def execute_cmd(m, exit_on_error=true); execute_cmd_verb(m, true, exit_on_error); end - -def search_cmd(program, additional_paths = nil) - if File.exists? program - return program - end - - path = ENV['PATH'].split(":") - path.push File.dirname($0) - path.push Dir.pwd - path = path + [*additional_paths] if additional_paths - for dir in path - p = File.join(dir, program) - if File.exists? p -# $stderr.puts "Using #{p.inspect}" - return p - end - end - $stderr.puts "Could not find program #{program.inspect}" - $stderr.puts "Searched in #{path.inspect}" - exit -1 -end - -alias find_cmd search_cmd - - diff --git a/scripts/create_video.rb b/scripts/create_video.rb deleted file mode 100755 index 7dddefb..0000000 --- a/scripts/create_video.rb +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env ruby -require 'rubygems' -require 'json' -require 'fileutils' -require 'optparse' - -$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) -require 'cmd_utils' - -def show_help() - cmd = File.basename($0) - description= <<-EOF -#{cmd}: creates an animation from a JSON file describing the animation. - -Usage: - - #{cmd} [options] file.desc - -Example animation description file: - - { - "fig": "figure.fig", - "common_depths": [ 100] - "frames": [ - { "depths": [ 1,2 ] }, - { "depths": [ 3,4 ] } - ], - } - -This is a movie created from "figure.fig", consisting of -two frames. Depth 100 is shown in both. Frame#1 is created -from depth 1,2 and frame #2 is created from depths 3,4. - -EOF - $stderr.puts description -end - -FIG2PICS = find_cmd('fig2pics.rb') -PDF2SWF = find_cmd('pdf2swf') -GS = find_cmd('gs') - - verbose = false - opt = OptionParser.new do |opts| - opts.on("-v", "--verbose", " be verbose") do |s| verbose=true; end - opts.on_tail("-h", "--help", "Show this message") do - show_help() - $stderr.puts "Options: " - $stderr.puts opts - exit 0 - end - end - begin opt.parse! - rescue OptionParser::InvalidOption=>e - $stderr.puts e - $stderr.puts opt - exit - end - -if(ARGV.size != 1) - show_help() - exit -1 -end - -spec = ARGV[0] - -spec_content = File.open(spec).read - -h = JSON.parse(spec_content) - -fig = File.join(File.dirname(spec), h['fig']) -frames = h['frames'].map {|f| f['depths'] + h['common_depths']} - -dir=File.dirname(spec) -basename=File.basename(spec,".fig.desc").sub(/^\.\//,""); -output_pdf = "#{dir}/#{basename}.pdf" -output_swf = "#{dir}/#{basename}.swf" -temp_dir = "#{dir}/#{basename}" -FileUtils.mkdir_p(temp_dir) if not File.exists? temp_dir - -filenames = [] -frames.each_with_index do |depths, i | - depths = depths.map {|x| x == -1 ? nil : x}.compact.uniq - opt_depths = "+" + depths.join(',') - filename = sprintf("#{temp_dir}/video%04d.pdf", i) - other = ARGV[1, ARGV.size].map{|x|x.inspect }.join(' ') - execute_cmd_verb("#{FIG2PICS} -f '-D #{opt_depths}' -o #{filename} #{other} #{fig}",verbose) - filenames.push filename -end - - -filenames = filenames.join(' ') -cmd = "#{GS} -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=#{output_pdf} -dBATCH #{filenames}" -execute_cmd_verb(cmd, verbose) - -cmd = "#{PDF2SWF} -L /usr/local/share/swftools/swfs/swft_loader.swf "+ - " -B /usr/local/share/swftools/swfs/keyboard_viewer.swf " + - " #{output_pdf} -o #{output_swf}" -execute_cmd_verb(cmd, verbose) diff --git a/scripts/fig2pics.rb b/scripts/fig2pics.rb deleted file mode 100755 index 14b51de..0000000 --- a/scripts/fig2pics.rb +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env ruby - -# 2009-05-03: starting tagging versions before copying over -# -# 2007-08-22: sostituto \usepackage{times} a \usepackage{ae,aecompl} -# - -require 'tempfile' -require 'optparse' -require 'fileutils' -require 'pathname' - -$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) -require 'cmd_utils' - -SCALE=4 - -BBOX = /^%%BoundingBox: (\d+) (\d+) (\d+) (\d+)$/ - -def eps_get_bounds(epsfile) - File.open(epsfile) do |f| - f.each do |line| - if line =~ BBOX then - bounds = [$1, $2, $3, $4].map{|x| x.to_i} - puts "Found #{line}" + bounds.inspect - f.close - return bounds - end - end - end - nil -end - -def eps_substitute_first_line(input, output, line_reg, replacement) - done = false - input.each do |line| - if not done and line =~ line_reg - output.puts replacement - else - output.puts line - end - end -end - -def change_bounds(eps, limits) - bounds = eps_get_bounds(eps) - if not bounds - $stderr.puts "Could not find bounding box in file #{eps.inspect}" - exit 1 - end - - corner_x = bounds[0] - corner_y = bounds[1] - width = bounds[2] - bounds[0] - height = bounds[3] - bounds[1] - - new_bounds = [ - corner_x + width * limits[0], - corner_y + height * limits[1], - corner_x + width * limits[2], - corner_y + height * limits[3]] - - $stderr.puts "New bounds: #{new_bounds.inspect}" - temp_file = Tempfile.new('change_bounds') - eps_substitute_first_line(File.open(eps), temp_file, BBOX, - '%%BoundingBox: '+new_bounds.join(' ')) - temp_file.close - FileUtils.cp(temp_file.path, eps) - temp_file.unlink -end - -def fig2pics() - opt_preamble = nil - opt_fig2dev = nil - opt_output = nil - opt_bounds = nil - opt_verbose = false - opt_debug = false - - opt = OptionParser.new do |opts| -# opts.banner = "Usage: maruku [options] [file1.md [file2.md ..." -# opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| -# MaRuKu::Globals[:verbose] = v end - opts.on("-v", "--verbose", "Be verbose") do opt_verbose = true; end - - opts.on("-p", "--preamble PREAMBLE", "LaTeX preamble file") do |s| - opt_preamble = s - if ! File.exists?(opt_preamble) - puts "Error: file #{opt_preamble.inspect} does not exist." - exit 2 - end - $stderr.puts "Using LaTeX preamble #{s}." - end - - opts.on("-f", "--fig-options OPTIONS", "Options to pass to fig2dev") do |s| - opt_fig2dev = s - end - - opts.on("-o", "--output FILE", "Output filename") do |s| - opt_output = s - end - - opts.on("-b", "--bbox BBOX", "Bounding box (4 numbers like '0 0 1 0.50')") do |s| - opt_bounds = s.strip.split.map{|x|x.to_f}.compact - if opt_bounds.size != 4 - $stderr.puts "Malformed bounds: #{s.inspect} -> #{opt_bounds.inspect}" - exit 4 - end - if (opt_bounds[0] >= opt_bounds[2]) || (opt_bounds[1] >= opt_bounds[3]) || - opt_bounds.any?{|x| x < 0 || x > 1 } then - $stderr.puts "Bounds #{opt_bounds.inspect} should respect constraints" - exit 4 - end - end - - opts.on_tail("-h", "--help", "Show this message") do - puts opts - exit - end - - end - - begin - opt.parse! - rescue OptionParser::InvalidOption=>e - $stderr.puts e - $stderr.puts opt - exit - end - - if ARGV.size == 0 - puts "Error: need filename" - exit 1 - end - - input=ARGV[0] - if !File.exists?(input) - puts "Error: file #{input} does not exist." - exit 1 - end - -# -# if ARGV.size >= 5 -# puts "Error: fig2pics.rb <file.fig> [<preamble.tex>] [params to fig2dev] '0 0 0.4 0'" -# exit 3 -# end - -programs=["latex", "dvips", "fig2dev", "epstopdf"]; - -programs.each do |p| - abs = `which #{p}`.chop - $stderr.puts "Using " + abs.inspect if opt_debug - if not FileTest.exists?(abs) then - $stderr.puts "Error: command #{p} not available (abs=#{abs.inspect})" - exit - end -end - -dir=File.dirname(input) - -basename=File.basename(input,".fig").sub(/^\.\//,""); -$stderr.puts "dir #{basename}" if opt_debug -$stderr.puts "basename #{basename}" if opt_debug -outpng="#{dir}/#{basename}.png" -outpdf="#{dir}/#{basename}.pdf" -temp="#{dir}/#{basename}_tmp" - -slideprefix="#{dir}/#{basename}_slide" -slide="#{dir}/#{basename}_slide.tex" -slidedvi="#{dir}/#{basename}_slide.dvi" -slideps="#{dir}/#{basename}_slide.ps" -slidepdf="#{dir}/#{basename}_slide.pdf" - -abs_dir = Pathname.new("#{dir}").realpath -absolute_img = abs_dir + "#{basename}_tmp.eps" - -execute_cmd "fig2dev -L pstex_t #{opt_fig2dev} -p #{absolute_img} #{input} #{temp}.tex" -execute_cmd "fig2dev -L pstex #{opt_fig2dev} #{input} #{temp}.eps" - -preamble_text = opt_preamble ? "\\input{#{opt_preamble}}" : "%" - -slidecontent=<<EOF - \\documentclass{article} - \\usepackage{amsmath} - \\usepackage{amsthm} - \\usepackage{amssymb} - \\usepackage{color} - \\usepackage{epsfig} - \\usepackage[T1]{fontenc} - \\usepackage{times} -% \\usepackage{ae,aecompl,aeguill} - #{preamble_text} - \\begin{document}\\thispagestyle{empty} - \\input{#{abs_dir}/#{basename}_tmp.tex} - \\end{document} -EOF - -File.open(slide,"w") do |f| - f.puts slidecontent -end - -execute_cmd "latex -output-directory=#{abs_dir} #{slide}" -execute_cmd "dvips -q -Ppdf -E #{slidedvi} -o #{slideps}" - -if opt_bounds then change_bounds(slideps, opt_bounds) end - -if opt_output then outpdf = opt_output end - - -execute_cmd("epstopdf #{slideps} --outfile=#{outpdf} --debug", exit_on_error=true) - -execute_cmd "rm -f #{slide} #{slidedvi} #{slideps} #{temp}.* #{slideprefix}.*" - -#execute_cmd "pstoimg -antialias -aaliastext -scale #{SCALE} -out #{outpng} #{slideps}" -# epstopdf #{figureeps} $WHERE/figure-$basename.eps -#execute_cmd "convert -density 600x600 #{slidepdf} -resize 640 #{outpng}" -#execute_cmd "eps2eps #{basename}_tmp.eps temp.eps" -#execute_cmd "epstopdf temp.eps " -#execute_cmd "cp temp.pdf #{basename}_tmp.pdf " -end - - -fig2pics - - - - - diff --git a/scripts/hash_options.rb b/scripts/hash_options.rb deleted file mode 100644 index b73219b..0000000 --- a/scripts/hash_options.rb +++ /dev/null @@ -1,45 +0,0 @@ - -class Hash - Comment = /^\s*\#/ - Option = /^\s*(\w+)\s*=?\s*(.+)$/ - - def read_conf(io, dir) - io.each do |line| - next if (line.strip.size == 0) || line =~ Comment - if m = Option.match(line) - name = m[1] - value = m[2].strip - - begin - value = eval(value) - rescue - - end - self[name] = value -# $stderr.puts "#{name} = #{value}" - elsif m = /^\s*<\s*(.*)$/.match(line) - filename = m[1] - filename = File.expand_path(File.join(dir, filename)) - read_conf(File.open(filename), File.dirname(filename)) - else - $stderr.puts "Line #{line.inspect} is malformed" - exit -1 - end - end - end - - def config_dump - s = "" - max_size = keys.map{|x|x.to_s.size}.max + 2 - for k in keys.sort - s += "#{k} " + " " * (max_size - k.to_s.size) + self[k].inspect + "\n" - end - s - end -end - -if File.basename($0) == 'hash_options.rb' - h = Hash.new - h.read_conf $stdin - p h -end \ No newline at end of file diff --git a/scripts/json2matlab.rb b/scripts/json2matlab.rb deleted file mode 100755 index ae60e01..0000000 --- a/scripts/json2matlab.rb +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env ruby -for s in ['../rsm', '.'] - $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), s)) -end - -require 'rubygems' -require 'json/pure' - -require 'fix_json' -require 'json_utils' - -class Array - def matrix_size?(x) [9].include?x end - - def to_matlab - if is_matrix? - write_as_matrix - elsif all_numbers? - "[ "+map{|x| x.to_matlab }.join("; ")+"]" - else - "{ ... \n "+map{|x| x.to_matlab }.join(", ... \n")+"}" - end - end - - def all_numbers? - all? {|x| x.kind_of?(Numeric) or x.nil? } - end - - def is_matrix? - return false if empty? or not all? {|x| x.kind_of?(Array) && x.all_numbers?} - columns = first.size - return false if not all? {|x| x.size==columns} - true - end - - def write_as_matrix - "[ " + map{|row| row.join(", ")}.join("; ... \n") + "]" - end -end - -class Hash - def to_matlab - " struct(" + - keys.map{ |k| - v = self[k] - if v.kind_of?(Array) and (not v.all_numbers?) and (not v.is_matrix?) - "'#{k}', {#{v.to_matlab}}" - elsif v.kind_of?(Hash) - "'#{k}', {#{v.to_matlab}}" - else - "'#{k}', #{v.to_matlab}" - end - }.join(", ... \n\t") + - ")" - end -end - -class Object - def to_matlab(); to_s; end -end - -class String - def to_matlab(); "'" + to_s + "'"; end -end - -class Object - def recurse_json(&block) end -end - -class Hash - def recurse_json(&block) - each do |k, v| - self[k]=block.call(v, self) - self[k].recurse_json(&block) - end - end -end - -class Array - def recurse_json(&block) - each_index do |i| - self[i] = block.call(self[i], self) - self[i].recurse_json(&block) - end - end -end - -class NilClass - def to_matlab - "NaN" - end -end - -def main_json2matlab - if ARGV.any? {|x| x =~ /help/} - $stderr.puts "Three usages:" - $stderr.puts " 1) without parameters, it acts as a filter; out is a Matlab structure " - $stderr.puts " $ json2matlab.rb < in.json > out.m " - $stderr.puts " 2) with one parameter, it creates <in>.m (a function named <in>) " - $stderr.puts " $ json2matlab.rb in.json " - $stderr.puts " 3) with two parameters, it creates `f.m` (a function named 'f') " - $stderr.puts " $ json2matlab.rb in.json f " - $stderr.puts " $ json2matlab.rb - f reading from stdin" - exit 0 - end - - - io = if ( (file = ARGV[0]) && (file != '-') ) then File.open(file) else $stdin end - complete_file = io.read - - a = read_all_objects(complete_file) - $stderr.write "json2matlab: Found #{a.size} JSON objects. " - a = a[0] if a.size == 1 - - a.recurse_json do |child, parent| - if parent.kind_of?(Array) and child.nil? then - (0.0/0.0) - else - child - end - end - - - if file = ARGV[0] - basename = File.basename(file).gsub(/\.\w*$/,'') - if ARGV[1] - basename = ARGV[1] - end - - output_file = File.join(File.dirname(file), basename + ".m") - $stderr.puts "Writing to #{output_file.inspect}." - File.open(output_file, 'w') do |f| - f.puts "function res = #{basename}" - f.puts "res = ..." - f.puts(a.to_matlab + ";") - end - else - $stdout.puts(a.to_matlab + ";") - end - -end - - -main_json2matlab if File.basename($0) == 'json2matlab.rb' - diff --git a/scripts/parser.rb.mine b/scripts/parser.rb.mine deleted file mode 100644 index 190b15e..0000000 --- a/scripts/parser.rb.mine +++ /dev/null @@ -1,215 +0,0 @@ -require 'strscan' - -module JSON - module Pure - # This class implements the JSON parser that is used to parse a JSON string - # into a Ruby data structure. - class Parser < StringScanner - STRING = /" ((?:[^\x0-\x1f"\\] | - \\["\\\/bfnrt] | - \\u[0-9a-fA-F]{4})*) - "/x - INTEGER = /(-?0|-?[1-9]\d*)/ - FLOAT = /(-? - (?:0|[1-9]\d*) - (?: - \.\d+(?i:e[+-]?\d+) | - \.\d+ | - (?i:e[+-]?\d+) - ) - )/x - OBJECT_OPEN = /\{/ - OBJECT_CLOSE = /\}/ - ARRAY_OPEN = /\[/ - ARRAY_CLOSE = /\]/ - PAIR_DELIMITER = /:/ - COLLECTION_DELIMITER = /,/ - TRUE = /true/ - FALSE = /false/ - NULL = /null/ - IGNORE = %r( - (?: - //[^\n\r]*[\n\r]| # line comments - /\* # c-style comments - (?: - [^*/]| # normal chars - /[^*]| # slashes that do not start a nested comment - \*[^/]| # asterisks that do not end this comment - /(?=\*/) # single slash before this comment's end - )* - \*/ # the End of this comment - |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr - )+ - )mx - - UNPARSED = Object.new - - # Creates a new JSON::Pure::Parser instance for the string _source_. - def initialize(source) - super - @create_id = JSON.create_id - reset # added - end - - alias source string - - # Parses the current JSON string _source_ and returns the complete data - # structure as a result. - def parse -# reset - obj = nil - until eos? || obj # added obj - case - when scan(OBJECT_OPEN) - obj and raise ParserError, "source '#{peek(20)}' not in JSON!" - obj = parse_object - when scan(ARRAY_OPEN) - obj and raise ParserError, "source '#{peek(20)}' not in JSON!" - obj = parse_array - when skip(IGNORE) - ; - else - raise ParserError, "source '#{peek(20)}' not in JSON!" - end - end - obj or raise ParserError, "source did not contain any JSON!" - obj - end - - private - - # Unescape characters in strings. - UNESCAPE_MAP = { - ?" => '"', - ?\\ => '\\', - ?/ => '/', - ?b => "\b", - ?f => "\f", - ?n => "\n", - ?r => "\r", - ?t => "\t", - } - - def parse_string - if scan(STRING) - return '' if self[1].empty? - self[1].gsub(%r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+))) do |c| - if u = UNESCAPE_MAP[c[1]] - u - else # \uXXXX - bytes = '' - i = 0 - while c[6 * i] == ?\\ && c[6 * i + 1] == ?u - bytes << c[6 * i + 2, 2].to_i(16) << c[6 * i + 4, 2].to_i(16) - i += 1 - end - JSON::UTF16toUTF8.iconv(bytes) - end - end - else - UNPARSED - end - rescue Iconv::Failure => e - raise GeneratorError, "Caught #{e.class}: #{e}" - end - - def parse_value - case - when scan(FLOAT) - Float(self[1]) - when scan(INTEGER) - Integer(self[1]) - when scan(TRUE) - true - when scan(FALSE) - false - when scan(NULL) - nil - when (string = parse_string) != UNPARSED - string - when scan(ARRAY_OPEN) - parse_array - when scan(OBJECT_OPEN) - parse_object - else - UNPARSED - end - end - - def parse_array - result = [] - delim = false - until eos? - case - when (value = parse_value) != UNPARSED - delim = false - result << value - skip(IGNORE) - if scan(COLLECTION_DELIMITER) - delim = true - elsif match?(ARRAY_CLOSE) - ; - else - raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!" - end - when scan(ARRAY_CLOSE) - if delim - raise ParserError, "expected next element in array at '#{peek(20)}'!" - end - break - when skip(IGNORE) - ; - else - raise ParserError, "unexpected token in array at '#{peek(20)}'!" - end - end - result - end - - def parse_object - result = {} - delim = false - until eos? - case - when (string = parse_string) != UNPARSED - skip(IGNORE) - unless scan(PAIR_DELIMITER) - raise ParserError, "expected ':' in object at '#{peek(20)}'!" - end - skip(IGNORE) - unless (value = parse_value).equal? UNPARSED - result[string] = value - delim = false - skip(IGNORE) - if scan(COLLECTION_DELIMITER) - delim = true - elsif match?(OBJECT_CLOSE) - ; - else - raise ParserError, "expected ',' or '}' in object at '#{peek(20)}'!" - end - else - raise ParserError, "expected value in object at '#{peek(20)}'!" - end - when scan(OBJECT_CLOSE) - if delim - raise ParserError, "expected next name, value pair in object at '#{peek(20)}'!" - end - if klassname = result[@create_id] - klass = JSON.deep_const_get klassname - break unless klass and klass.json_creatable? - result = klass.json_create(result) - result - end - break - when skip(IGNORE) - ; - else - raise ParserError, "unexpected token in object at '#{peek(20)}'!" - end - end - result - end - end - end -end diff --git a/sm/.gitignore b/sm/.gitignore deleted file mode 100644 index a4ce1b2..0000000 --- a/sm/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -ld_* -sm1 -sm2 -sm3 -test_json -test_json_ld -test_math_utils_sanity -sm_animate diff --git a/sm/AUTHORS b/sm/AUTHORS deleted file mode 100644 index e698f83..0000000 --- a/sm/AUTHORS +++ /dev/null @@ -1,10 +0,0 @@ -Most of the blame is on Andrea Censi (http://www.dis.uniroma1.it/~censi/). - -The json-c library is (c) Michael Clark, released under the MIT license. - http://oss.metaparadigm.com/json-c/ -The copy in lib/json-c is based on version 0.7. - -Bounding box algorithm in file laser_data_bbox.c created by Cyrill Stachniss (http://www.informatik.uni-freiburg.de/~stachnis/). - -ICP covariance bug fixes by Gian Diego Tipaldi (http://www.dis.uniroma1.it/~tipaldi/). - diff --git a/sm/CMakeLists.txt b/sm/CMakeLists.txt deleted file mode 100644 index 19b9951..0000000 --- a/sm/CMakeLists.txt +++ /dev/null @@ -1,239 +0,0 @@ -PROJECT (CSM C CXX) - - -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/lib) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -cmake_minimum_required(VERSION 2.4) -set(csm_link_flags "-L.") - -SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) - -FIND_PACKAGE(GSL REQUIRED) -IF(GSL_FOUND) - MESSAGE(STATUS "Found GSL:") - MESSAGE(STATUS " GSL_LIBRARIES = ${GSL_LIBRARIES}") - MESSAGE(STATUS " GSL_INCLUDE_DIR = ${GSL_INCLUDE_DIR}") - MESSAGE(STATUS " CMAKE_GSL_CXX_FLAGS = ${CMAKE_GSL_CXX_FLAGS}") - MESSAGE(STATUS " GSL_LINK_DIRECTORIES = '${GSL_LINK_DIRECTORIES}'") - - - set(csm_c_flags "${csm_c_flags} -I${GSL_INCLUDE_DIR}") - if(GSL_LINK_DIRECTORIES) -# set(csm_link_flags "${csm_link_flags} - set(csm_link_flags "${csm_link_flags} -L${GSL_LINK_DIRECTORIES}") - endif(GSL_LINK_DIRECTORIES) - - set(csm_link_flags "${csm_link_flags} ${GSL_LIBRARIES}") - -ELSE(GSL_FOUND) - MESSAGE(FATAL_ERROR "GSL not found.") -ENDIF(GSL_FOUND) - -FIND_PACKAGE(Cairo) -IF(CAIRO_FOUND) - MESSAGE(STATUS "Found Cairo at.") - MESSAGE(STATUS " PREFIX_CAIRO= ${PREFIX_CAIRO}") - MESSAGE(STATUS " CAIRO_CFLAGS = ${CAIRO_CFLAGS}") - MESSAGE(STATUS " CAIRO_LIBRARY = ${CAIRO_LIBRARY}") - MESSAGE(STATUS " CAIRO_INCLUDE_DIR = ${CAIRO_INCLUDE_DIR}") - - set(csm_link_flags "${csm_link_flags} ${CAIRO_LIBRARY}") - SET(csm_c_flags "${csm_c_flags} ${CAIRO_CFLAGS} -I${CAIRO_INCLUDE_DIR}") - -ELSE(CAIRO_FOUND) - MESSAGE(WARNING "* Cairo not found: plotting programs (e.g., 'log2pdf') will not be built.") - MESSAGE(WARNING "* install Cairo from http://cairographics.org ") -ENDIF(CAIRO_FOUND) - - - - - -MESSAGE(STATUS "csm_c_flags = ${csm_c_flags}") -MESSAGE(STATUS "csm_link_flags = ${csm_link_flags}") - - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${csm_c_flags}") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -Wall") - - -# for realpath -IF("${CMAKE_SYSTEM}" MATCHES "Linux") - ADD_DEFINITIONS(-DLINUX) -ENDIF("${CMAKE_SYSTEM}" MATCHES "Linux") - -########### Options ########## - -SUBDIRS(lib/options) -SUBDIRS(lib/json-c) -SUBDIRS(lib/egsl) -SUBDIRS(lib/gpc) -SUBDIRS(csm) - - - - - -########### SM applications ########## - -MACRO(new_executable exec) - ADD_EXECUTABLE(${exec} apps/${exec}.c) - TARGET_LINK_LIBRARIES(${exec} csm-static ${csm_link_flags}) - INSTALL(PROGRAMS ${exec} DESTINATION bin) -ENDMACRO(new_executable exec) - -# new_executable(sm0) -new_executable(sm1) -new_executable(sm2) -new_executable(sm3) -new_executable(json_extract) -new_executable(json_extract_field) -new_executable(json_decimate) -new_executable(json_split) -new_executable(json_pipe) -new_executable(carmen2json) -new_executable(json2carmen) -new_executable(ld_noise) -new_executable(ld_slip) -new_executable(ld_fisher) -new_executable(ld_smooth) -new_executable(ld_resample) -new_executable(ld_remove_doubles) -new_executable(ld_alternate) -new_executable(ld_recover) - -new_executable(ld_purify) -new_executable(ld_select) -new_executable(ld_cluster_curv) -new_executable(ld_linearize) - -new_executable(json2matlab) - -new_executable(ld_exp_tro1) - -# this are some random tests -# new_executable(ld_stats) -# new_executable(ld_correct) - -new_executable(test_json_ld) -new_executable(test_json) - - - -IF(CAIRO_FOUND) - new_executable(sm_animate) - new_executable(log2pdf) -ENDIF(CAIRO_FOUND) - - -ADD_EXECUTABLE(test_math_utils_sanity csm/test_math_utils_sanity.c) -TARGET_LINK_LIBRARIES(test_math_utils_sanity csm-static ${GSL_LIBRARIES}) - -ENABLE_TESTING() -ADD_TEST(test_math_utils_sanity test_math_utils_sanity) - - -SET(csm_sources -./csm/clustering.c -./csm/gpm/gpm.c -./csm/icp/icp.c -./csm/icp/icp_corr_dumb.c -./csm/icp/icp_corr_tricks.c -./csm/icp/icp_covariance.c -./csm/icp/icp_loop.c -./csm/icp/icp_outliers.c -./csm/icp/icp_debug.c -./csm/mbicp/mbicp_interface.c -./csm/mbicp/MbICP.c -./csm/mbicp/calcul.c -./csm/mbicp/percolate.c -./csm/mbicp/sp_matrix.c -./csm/hsm/hsm.c -./csm/hsm/hsm_interface.c -./csm/json_journal.c -./csm/laser_data.c -./csm/laser_data_carmen.c -./csm/laser_data_fisher.c -./csm/laser_data_json.c -./csm/laser_data_load.c -./csm/laser_data_drawing.c -./csm/laser_data_bbox.c -./csm/logging.c -./csm/math_utils.c -./csm/math_utils_gsl.c -./csm/orientation.c -./csm/sm_options.c -./csm/utils.c -./lib/egsl/egsl.c -./lib/egsl/egsl_conversions.c -./lib/egsl/egsl_misc.c -./lib/egsl/egsl_ops.c -./lib/gpc/gpc.c -./lib/gpc/gpc_utils.c -./lib/json-c/arraylist.c -./lib/json-c/debug.c -./lib/json-c/JSON_checker.c -./lib/json-c/json_more_utils.c -./lib/json-c/json_object.c -./lib/json-c/json_tokener.c -./lib/json-c/json_util.c -./lib/json-c/linkhash.c -./lib/json-c/printbuf.c -./lib/options/options.c -./lib/options/options_interface.c -) - -IF(CAIRO_FOUND) -SET(csm_sources ${csm_sources} csm/laser_data_cairo.c) -ENDIF(CAIRO_FOUND) - -ADD_LIBRARY(csm-static STATIC ${csm_sources}) -TARGET_LINK_LIBRARIES(csm-static ${csm_link_flags}) -INSTALL(TARGETS csm-static ARCHIVE DESTINATION lib) - -ADD_LIBRARY(csm SHARED ${csm_sources}) -TARGET_LINK_LIBRARIES(csm ${csm_link_flags}) -INSTALL(TARGETS csm ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) - - -IF(COMPILE_HSM) - -INCLUDE_DIRECTORIES(/sw/include) -LINK_DIRECTORIES(/sw/lib) - -ADD_EXECUTABLE(hsm_test00 ./csm/hsm/hsm_test00.c ./csm/hsm/hsm.c) -#TARGET_LINK_LIBRARIES(hsm_test00 csm-static ${csm_link_flags} pgm pnm pbm) - TARGET_LINK_LIBRARIES(hsm_test00 csm-static ${csm_link_flags} netpbm) -INSTALL(PROGRAMS hsm_test00 DESTINATION bin) - -ENDIF(COMPILE_HSM) - - -SUBDIRS(pkg-config) - -if(0) -# -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${csm_c_flags} -Wall") - -FILE(GLOB_RECURSE csm_headers csm/*.h) -FILE(GLOB_RECURSE lib_headers lib/*.h) - -foreach(header ${csm_headers} ${lib_headers}) - GET_FILENAME_COMPONENT(header_base ${header} NAME_WE) - GET_FILENAME_COMPONENT(header_dir ${header} PATH) - -# MESSAGE("Ciao ${header_base} ${header_dir}") - - CONFIGURE_FILE(header_test.c.in ${header_dir}/${header_base}_header_test.cpp @ONLY) - ADD_EXECUTABLE(${header_base}_header_test ${header_dir}/${header_base}_header_test.cpp) - SET_TARGET_PROPERTIES(${header_base}_header_test PROPERTIES LINKER_LANGUAGE CXX) - TARGET_LINK_LIBRARIES(${header_base}_header_test csm-static ${csm_link_flags}) - - CONFIGURE_FILE(header_test.c.in ${header_dir}/${header_base}_header_test2.c @ONLY) - ADD_EXECUTABLE(${header_base}_header_test2 ${header_dir}/${header_base}_header_test2.c) - TARGET_LINK_LIBRARIES(${header_base}_header_test2 csm-static ${csm_link_flags}) - -endforeach(header ${csm_headers} ${lib_headers}) -endif(0) diff --git a/sm/FindCairo.cmake b/sm/FindCairo.cmake deleted file mode 100644 index 46e443a..0000000 --- a/sm/FindCairo.cmake +++ /dev/null @@ -1,69 +0,0 @@ -# -# Find the native cairo includes and library -# - -# This module defines -# CAIRO_INCLUDE_DIR, where to find art*.h etc -# CAIRO_LIBRARY, the libraries to link against to use cairo -# CAIRO_FOUND, If false, do not try to use LIBART. -# CAIRO_LIBS, link information -# CAIRO_CFLAGS, cflags for include information - - -INCLUDE(UsePkgConfig) - -# use pkg-config to get the directories and then use these values -# in the FIND_PATH() and FIND_LIBRARY() calls -PKGCONFIG(cairo _libCairoIncDir _libCairoLinkDir _libCairoLinkFlags _libCairoCflags) - -SET(CAIRO_LIBS ${_libCairoCflags}) - -IF(PREFIX_CAIRO) - SET(PREFIX_CAIRO_INCLUDE "${PREFIX_CAIRO}/include") - SET(PREFIX_CAIRO_LIB "${PREFIX_CAIRO}/lib") - SET(PREFIX_CAIRO_BIN "${PREFIX_CAIRO}/bin") -ENDIF(PREFIX_CAIRO) - -FIND_PATH(CAIRO_INCLUDE_DIR -NAMES cairo.h -PATHS ${PREFIX_CAIRO_INCLUDE} ${_libCairoIncDir} /usr/local/include /usr/include -PATH_SUFFIXES cairo -NO_DEFAULT_PATH -) - -FIND_LIBRARY(CAIRO_LIBRARY -NAMES cairo -PATHS ${PREFIX_CAIRO_LIB} ${_libCairoLinkDir} /usr/local/lib /usr/lib -NO_DEFAULT_PATH -) - -#If we had no cairo prefix specify it, set PREFIX_CAIRO_LIB most importantly, for the -# IF(NOT PREFIX_CAIRO) -# GET_FILENAME_COMPONENT(CAIRO_DIR ${CAIRO_LIBRARY} PATH) -# GET_FILENAME_COMPONENT(CAIRO_DIR ${CAIRO_DIR} PATH) -# SET(PREFIX_CAIRO ${CAIRO_DIR}) -# IF(PREFIX_CAIRO) -# SET(PREFIX_CAIRO_INCLUDE "${PREFIX_CAIRO}/include") -# SET(PREFIX_CAIRO_LIB "${PREFIX_CAIRO}/lib") -# SET(PREFIX_CAIRO_BIN "${PREFIX_CAIRO}/bin") -# ENDIF(PREFIX_CAIRO) -# ENDIF(NOT PREFIX_CAIRO) - -SET(CAIRO_FIND_QUIETLY 0) - -IF (CAIRO_LIBRARY) - IF (CAIRO_INCLUDE_DIR) - SET( CAIRO_FOUND "YES" ) - IF(NOT CAIRO_FIND_QUIETLY) - MESSAGE(STATUS "Found cairo: ${CAIRO_LIBRARY}") - ENDIF(NOT CAIRO_FIND_QUIETLY) - SET( CAIRO_LIBRARIES ${CAIRO_LIBRARY} ) -# CB: We dont use this yet anyway - # FIND_PROGRAM(CAIRO_CONFIG - # NAMES pkg-config - # PATHS ${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin /usr/bin /usr/nekoware/bin /usr/X11/bin - # ) - # EXEC_PROGRAM(${CAIRO_CONFIG} ARGS "--libs cairo" OUTPUT_VARIABLE CAIRO_LIBS) - # EXEC_PROGRAM(${CAIRO_CONFIG} ARGS "--cflags cairo" OUTPUT_VARIABLE CAIRO_CFLAGS) - ENDIF (CAIRO_INCLUDE_DIR) -ENDIF (CAIRO_LIBRARY) diff --git a/sm/FindGSL.cmake b/sm/FindGSL.cmake deleted file mode 100644 index 9e02e77..0000000 --- a/sm/FindGSL.cmake +++ /dev/null @@ -1,130 +0,0 @@ -## -## Try to find gnu scientific library GSL -## (see http://www.gnu.org/software/gsl/) -## Once run this will define: -## -## GSL_FOUND = system has GSL lib -## -## GSL_LIBRARIES = full path to the libraries -## on Unix/Linux with additional linker flags from "gsl-config --libs" -## -## CMAKE_GSL_CXX_FLAGS = Unix compiler flags for GSL, essentially "`gsl-config --cxxflags`" -## -## GSL_INCLUDE_DIR = where to find headers -## -## GSL_LINK_DIRECTORIES = link directories, useful for rpath on Unix -## GSL_EXE_LINKER_FLAGS = rpath on Unix -## -## Felix Woelk 07/2004 -## www.mip.informatik.uni-kiel.de -## -------------------------------- - - IF(WIN32 AND NOT CYGWIN) - MESSAGE(STATUS, "Finding GSL using the WIN32 code.") - FIND_LIBRARY(GSL_gsl_LIBRARY - NAMES gsl - PATHS "$ENV{GSL_HOME}/lib" - DOC "Where can the GSL (gsl.lib) library be found" - ) - FIND_LIBRARY(GSL_cblas_LIBRARY - NAMES cblas - PATHS "$ENV{GSL_HOME}/lib" - DOC "Where can the GSL (cblas.lib) library be found" - ) - SET(GSL_LIBRARIES "${GSL_cblas_LIBRARY} ${GSL_gsl_LIBRARY}") - - FIND_PATH(GSL_INCLUDE_DIR gsl/gsl_linalg.h - $ENV{GSL_HOME}/include - ) - - IF(GSL_INCLUDE_DIR AND GSL_LIBRARIES) - SET(GSL_FOUND TRUE) - ELSE(GSL_INCLUDE_DIR AND GSL_LIBRARIES) - SET(GSL_FOUND FALSE) - ENDIF(GSL_INCLUDE_DIR AND GSL_LIBRARIES) - - MARK_AS_ADVANCED( - GSL_gsl_LIBRARY - GSL_cblas_LIBRARY - GSL_INCLUDE_DIR - GSL_LIBRARIES - GSL_LINK_DIRECTORIES - ) -ELSE(WIN32 AND NOT CYGWIN) - MESSAGE("gsl home: $ENV{GSL_HOME}") -# IF(UNIX) - SET(GSL_CONFIG_PREFER_PATH "$ENV{GSL_HOME}/bin" CACHE STRING "preferred path to GSL (gsl-config)") - IF(NOT GSL_CONFIG) - FIND_PROGRAM(GSL_CONFIG gsl-config - ${GSL_CONFIG_PREFER_PATH} - /usr/bin/ - ) - ENDIF(NOT GSL_CONFIG) - - MESSAGE("DBG GSL_CONFIG ${GSL_CONFIG}") - - IF (GSL_CONFIG) - # set CXXFLAGS to be fed into CXX_FLAGS by the user: - # SET(GSL_CXX_FLAGS "`${GSL_CONFIG} --cflags`") - EXEC_PROGRAM(${GSL_CONFIG} ARGS --cflags OUTPUT_VARIABLE GSL_CXX_FLAGS) - - # set INCLUDE_DIRS to prefix+include - EXEC_PROGRAM(${GSL_CONFIG} - ARGS --prefix - OUTPUT_VARIABLE GSL_PREFIX) - SET(GSL_INCLUDE_DIR ${GSL_PREFIX}/include CACHE STRING INTERNAL) - - # set link libraries and link flags - # SET(GSL_LIBRARIES "`${GSL_CONFIG} --libs`") - EXEC_PROGRAM(${GSL_CONFIG} ARGS --libs OUTPUT_VARIABLE GSL_LIBRARIES) - - ## extract link dirs for rpath - EXEC_PROGRAM(${GSL_CONFIG} - ARGS --libs - OUTPUT_VARIABLE GSL_CONFIG_LIBS ) - - ## split off the link dirs (for rpath) - ## use regular expression to match wildcard equivalent "-L*<endchar>" - ## with <endchar> is a space or a semicolon - STRING(REGEX MATCHALL "[-][L]([^ ;])+" - GSL_LINK_DIRECTORIES_WITH_PREFIX - "${GSL_CONFIG_LIBS}" ) -# MESSAGE("DBG GSL_LINK_DIRECTORIES_WITH_PREFIX=${GSL_LINK_DIRECTORIES_WITH_PREFIX}") - - ## remove prefix -L because we need the pure directory for LINK_DIRECTORIES - - IF (GSL_LINK_DIRECTORIES_WITH_PREFIX) - STRING(REGEX REPLACE "[-][L]" "" GSL_LINK_DIRECTORIES ${GSL_LINK_DIRECTORIES_WITH_PREFIX} ) - ENDIF (GSL_LINK_DIRECTORIES_WITH_PREFIX) - SET(GSL_EXE_LINKER_FLAGS "-Wl,-rpath,${GSL_LINK_DIRECTORIES}" CACHE STRING INTERNAL) -# MESSAGE("DBG GSL_LINK_DIRECTORIES=${GSL_LINK_DIRECTORIES}") -# MESSAGE("DBG GSL_EXE_LINKER_FLAGS=${GSL_EXE_LINKER_FLAGS}") - - ADD_DEFINITIONS("-DHAVE_GSL") - SET(GSL_DEFINITIONS "-DHAVE_GSL") - MARK_AS_ADVANCED( - GSL_CXX_FLAGS - GSL_INCLUDE_DIR - GSL_LIBRARIES - GSL_LINK_DIRECTORIES - GSL_DEFINITIONS - ) - MESSAGE(STATUS "Using GSL from ${GSL_PREFIX}") - - ELSE(GSL_CONFIG) - MESSAGE(FATAL_ERROR, "FindGSL.cmake: gsl-config not found. Please set it manually. GSL_CONFIG=${GSL_CONFIG}") - ENDIF(GSL_CONFIG) - -# ENDIF(UNIX) -ENDIF(WIN32 AND NOT CYGWIN) - - -IF(GSL_LIBRARIES) - IF(GSL_INCLUDE_DIR OR GSL_CXX_FLAGS) - - SET(GSL_FOUND 1) - - ENDIF(GSL_INCLUDE_DIR OR GSL_CXX_FLAGS) -ENDIF(GSL_LIBRARIES) - - diff --git a/sm/apps/carmen2json.c b/sm/apps/carmen2json.c deleted file mode 100644 index ef8b00e..0000000 --- a/sm/apps/carmen2json.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../csm/csm_all.h" - -int main(int argc, char * argv[]) { - sm_set_program_name(argv[0]); - - LDP ld; int count=0, errors=0; - while((ld = ld_read_smart(stdin))) { - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - errors++; - continue; - } - - ld_write_as_json(ld, stdout); - - ld_free(ld); - count++; - } - - return errors; -} diff --git a/sm/apps/carmen2pdf.c b/sm/apps/carmen2pdf.c deleted file mode 100644 index c1be940..0000000 --- a/sm/apps/carmen2pdf.c +++ /dev/null @@ -1,400 +0,0 @@ -#include <time.h> -#include <string.h> - -#ifdef LINUX -#include <linux/limits.h> -#endif - - -#include <cairo.h> -#include <cairo-pdf.h> - -#include <options/options.h> - -#include "../csm/csm_all.h" - - -typedef enum { Invalid = 0, Odometry = 1, Estimate = 2, True_pose = 3 } reference; -const char*reference_name[4] = { "invalid","odometry","estimate","true_pose"}; - -struct params { - int interval; - const char*use; - double padding; - double horizon; - double line_threshold; - double dimension; - - int draw_confidence; - double confidence_mult; - - const char*output_filename; - const char*input_filename; - - /**/ - FILE*input_file; - reference use_reference; - - double offset_theta_deg; -}; - -void carmen2pdf(struct params p); - -double offset_theta = 0; -void ld_getbb(LDP ld, double*x0, double*y0, double*x1, double*y1, - reference use_reference, double horizon); - -int main(int argc, const char*argv[]) { - sm_set_program_name(argv[0]); - fprintf(stderr, "carmen2pdf:\t *** Please use log2pdf instead. ***\n\n"); - - struct params p; - - struct option * ops = options_allocate(12); - options_int(ops, "interval", &p.interval, 10, "how many to ignore"); - options_string(ops, "in", &p.input_filename, "stdin", "input file (Carmen or JSON)"); - options_string(ops, "out", &p.output_filename, "", "output file (if empty, input file + '.pdf')"); - options_double(ops, "lt", &p.line_threshold, 0.2, "threshold for linking points (m)"); - options_double(ops, "horizon", &p.horizon, 8.0, "horizon of the laser (m)"); - options_double(ops, "padding", &p.padding, 0.2, "padding around bounding box (m)"); - options_double(ops, "dimension", &p.dimension, 500.0, "dimension of the image (points)"); - options_int(ops, "draw_confidence", &p.draw_confidence, 0, " Draws confidence (readings_sigma[i]) "); - options_double(ops, "confidence_mult", &p.confidence_mult, 3.0, " 3-sigma "); - options_double(ops, "offset_theta_deg", &p.offset_theta_deg, 0.0, " rotate entire map by this angle (deg) "); - - options_string(ops, "use", &p.use, "estimate", "One in 'odometry','estimate','true_pose'"); - - if(!options_parse_args(ops, argc, argv)) { - sm_error("Could not parse arguments.\n"); - options_print_help(ops, stderr); - return -1; - } - - /* If out not specified */ - if(strlen(p.output_filename)==0) { - char buf[PATH_MAX]; - sprintf(buf, "%s.pdf", p.input_filename); - p.output_filename = strdup(buf); - sm_info("Writing on file '%s'.\n", p.output_filename); - } - - p.use_reference = Invalid; - int i; for(i=1;i<=3;i++) - if(!strcmp(p.use, reference_name[i])) - p.use_reference = (reference) i; - if(Invalid == p.use_reference) { - sm_error("Invalid reference '%s'. " - "Use one in 'odometry','estimate','true_pose'.\n", p.use); - return -1; - } - - - - - p.input_file = open_file_for_reading(p.input_filename); - if(!p.input_file) return -1; - - carmen2pdf(p); - return 0; -} - -int should_consider(struct params *p, int counter) { - return counter%p->interval == 0; -} - -void ld_get_world(LDP ld, int i, double*x, double*y, reference use_reference); - -struct bounding_box { - /** World frame */ - double x0,y0,x1,y1; - /* Paper size */ - double width, height; -}; - -void bb_w2b(struct bounding_box*bb, double wx, double wy, double*bx, double*by){ - double scale = GSL_MIN(bb->width / (bb->x1-bb->x0), bb->height / (bb->y1-bb->y0)); - *bx = (wx-bb->x0) * scale; - *by = bb->height- (wy-bb->y0) * scale; -} - -void ld_get_buffer_polar(double phi, double rho, const double*pose, - double*x, double*y, - struct bounding_box*bb, double*bx,double *by); - - -/** Reads all file to find bounding box */ -void get_bb(struct params*p, struct bounding_box*bb) { - LDP ld; - int counter = -1, - considered = 0; - - while((ld = ld_read_smart(p->input_file))) { - counter++; - if(should_consider(p, counter)) { - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", counter); - continue; - } - - double x0,y0,x1,y1; - ld_getbb(ld,&x0,&y0,&x1,&y1, p->use_reference, p->horizon); - if(considered > 0) { - bb->x0 = GSL_MIN(x0, bb->x0); - bb->x1 = GSL_MAX(x1, bb->x1); - bb->y0 = GSL_MIN(y0, bb->y0); - bb->y1 = GSL_MAX(y1, bb->y1); - } else { - /* this is the first one */ - bb->x0 = x0; - bb->x1 = x1; - bb->y0 = y0; - bb->y1 = y1; - } - - considered++; - } - ld_free(ld); - } - sm_info("Considering %d of %d scans.\n", considered, counter+1); - rewind(p->input_file); - - bb->x0 -= p->padding; - bb->x1 += p->padding; - bb->y0 -= p->padding; - bb->y1 += p->padding; -} - - -double * ld_get_reference(LDP ld, reference use_reference) { - double * pose; - switch(use_reference) { - case Odometry: pose = ld->odometry; break; - case Estimate: pose = ld->estimate; break; - case True_pose: pose = ld->true_pose; break; - default: exit(-1); - } - if(any_nan(pose, 3)) { - sm_error("Required field '%s' not set in laser scan.\n", - reference_name[use_reference] ); - sm_error("I will abruptly exit() because of a panic attack.\n"); - exit(-1); - } - return pose; -} - - -void carmen2pdf(struct params p) { - - offset_theta += deg2rad(p.offset_theta_deg); - - struct bounding_box bb; - get_bb(&p, &bb); - - double wwidth = bb.x1-bb.x0; - double wheight= bb.y1-bb.y0; - if(wwidth > wheight) { - bb.width = p.dimension; - bb.height = bb.width / wwidth * wheight; - } else { - bb.height = p.dimension; - bb.width = bb.height / wheight * wwidth; - } - - sm_info("Bounding box: %f %f, %f %f\n",bb.x0,bb.y0,bb.x1,bb.y1); - - cairo_surface_t *surface; - cairo_t *cr; - cairo_status_t status; - - surface = cairo_pdf_surface_create(p.output_filename, bb.width, bb.height); - cr = cairo_create (surface); - status = cairo_status (cr); - - if (status) { - sm_error("Failed to create pdf surface for file %s: %s\n", - p.output_filename, cairo_status_to_string (status)); - return; - } - - int counter=0; - int first_pose=1; double old_pose_bx=0,old_pose_by=0; - LDP ld; - while((ld = ld_read_smart(p.input_file))) { - - double *pose = ld_get_reference(ld, p.use_reference); - - /* Draw pose */ - { - double bx,by; - ld_get_buffer_polar(0.0,0.0,pose, 0,0, &bb, &bx, &by); - if(first_pose) { - first_pose = 0; - } else { - cairo_set_line_width(cr, 0.5); - cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); - cairo_move_to(cr, old_pose_bx, old_pose_by); - cairo_line_to(cr, bx, by); - cairo_close_path(cr); - cairo_stroke(cr); - } - - old_pose_bx = bx; - old_pose_by = by; - } - - - /* If should we draw this sensor scan */ - if(should_consider(&p, counter)) { - - /* Firstly, find buffer coordinates and whether to cut the stroke */ - struct { - double w[2]; /* world coordinates */ - double b[2]; /* buffer coordinates */ - int begin_new_stroke; - int end_stroke; - int valid; - } draw_info[ld->nrays]; - - { - int last_valid = -1; int first = 1; - int i; for(i=0;i<ld->nrays;i++) { - - if( (!ld->valid[i]) || ld->readings[i]>p.horizon) { - draw_info[i].valid = 0; - continue; - } - draw_info[i].valid = 1; - - ld_get_buffer_polar(ld->theta[i], ld->readings[i], - pose, &(draw_info[i].w[0]), &(draw_info[i].w[1]), - &bb, &(draw_info[i].b[0]), &(draw_info[i].b[1])); - - if(first) { - first = 0; - draw_info[i].begin_new_stroke = 1; - draw_info[i].end_stroke = 0; - } else { - int near = square(p.line_threshold) > - distance_squared_d(draw_info[last_valid].w, draw_info[i].w); - draw_info[i].begin_new_stroke = near ? 0 : 1; - draw_info[i].end_stroke = 0; - draw_info[last_valid].end_stroke = draw_info[i].begin_new_stroke; - } - last_valid = i; - } /*for */ - if(last_valid >= 0) - draw_info[last_valid].end_stroke = 1; - } /* find buff .. */ - - - if(p.draw_confidence) { - int i; - /* Compute interval */ - double interval[ld->nrays]; - double big_interval = 0.3; - for(i=0;i<ld->nrays;i++) { if(draw_info[i].valid==0) continue; - double sigma = ld->readings_sigma[i]; - if(!is_nan(cov)) { - interval[i] = p.confidence_mult * sigma; - } else interval[i] = big_interval; - } - - cairo_set_source_rgb(cr, 1.0, 0.5, 0.5); - cairo_set_line_width(cr, 0.1); - /* draw one */ - int j=0; for(j=0;j<2;j++) - for(i=0;i<ld->nrays;i++) { if(draw_info[i].valid==0) continue; - double b[2]; - ld_get_buffer_polar(ld->theta[i], - ld->readings[i] + (j ? interval[i] : -interval[i]), - pose, 0, 0, &bb, &(b[0]), &(b[1])); - - if(draw_info[i].begin_new_stroke) - cairo_move_to(cr, b[0], b[1]); - else - cairo_line_to(cr, b[0], b[1]); - if(draw_info[i].end_stroke) - cairo_stroke(cr); - } - } /* draw confidence */ - - /* draw contour: begin_new_stroke and end_stroke tell - when to interrupt the stroke */ - int i; - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - cairo_set_line_width(cr, 0.5); - for(i=0;i<ld->nrays;i++) { - if(draw_info[i].valid==0) continue; - double *b = draw_info[i].b; - if(draw_info[i].begin_new_stroke) - cairo_move_to(cr, b[0], b[1]); - else - cairo_line_to(cr, b[0], b[1]); - if(draw_info[i].end_stroke) - cairo_stroke(cr); - } - - - - } - counter++; - ld_free(ld); - } - - cairo_show_page (cr); - - cairo_destroy (cr); - cairo_surface_destroy (surface); -} - -void ld_get_buffer_polar(double phi, double rho, const double*pose, - double*x, double*y, - struct bounding_box*bb, double*bx,double *by) { - - double point[2]; - point[0] = cos(phi) * rho; - point[1] = sin(phi) * rho; - - double frame[3] = { 0, 0, offset_theta}; - double pose2[3]; - oplus_d(frame, pose, pose2); - double pw[2]; - transform_d(point, pose2, pw); - - if( (bb!=0) & (bx!=0) & (by!=0) ) - bb_w2b(bb, pw[0], pw[1], bx, by); - - if((x!=0) && (y!=0)) { - *x = pw[0]; *y = pw[1]; - } -} - -void ld_getbb(LDP ld, double*x0, double*y0, double*x1, double*y1, - reference use_reference, double horizon) { - double *pose = ld_get_reference(ld, use_reference); - - int nrays_used = 0; - int first=1; - int i; for(i=0;i<ld->nrays;i++) { - if(!ld->valid[i]) continue; - if(ld->readings[i]>horizon) continue; - double x,y; - ld_get_buffer_polar(ld->theta[i], ld->readings[i], pose, &x, &y, 0, 0,0); - - if(first) { - *x0 = *x1 = x; - *y0 = *y1 = y; - first = 0; - } else { - *x0 = GSL_MIN(*x0, x); - *y0 = GSL_MIN(*y0, y); - *x1 = GSL_MAX(*x1, x); - *y1 = GSL_MAX(*y1, y); - } - nrays_used++; - } -} - - - - diff --git a/sm/apps/gtk_viewer/Makefile b/sm/apps/gtk_viewer/Makefile deleted file mode 100644 index 7b87b12..0000000 --- a/sm/apps/gtk_viewer/Makefile +++ /dev/null @@ -1,16 +0,0 @@ - -all_targets=gtk_viewer1 - -all: $(all_targets) - -GOO_FLAGS=-I/usr/local/include/goocanvas-1.0/ -lgoocanvas -GTK_FLAGS=`pkg-config --libs --cflags gtk+-2.0 gthread-2.0` -CSM_FLAGS=`pkg-config --libs --cflags csm` - -FLAGS=$(GTK_FLAGS) $(GOO_FLAGS) $(CSM_FLAGS) -Wno-long-double -O3 -%: %.c goo_laser_data.c - gcc -g $(FLAGS) -o $@ $^ - - -clean: - rm $(all_targets) \ No newline at end of file diff --git a/sm/apps/gtk_viewer/goo_laser_data.c b/sm/apps/gtk_viewer/goo_laser_data.c deleted file mode 100644 index f6b4fd6..0000000 --- a/sm/apps/gtk_viewer/goo_laser_data.c +++ /dev/null @@ -1,147 +0,0 @@ - -#include "goo_laser_data.h" - -/* Use the GLib convenience macro to define the type. GooLaserData is the - class struct, goo_laser_data is the function prefix, and our class is a - subclass of GOO_TYPE_CANVAS_ITEM_SIMPLE. */ -G_DEFINE_TYPE (GooLaserData, goo_laser_data, GOO_TYPE_CANVAS_ITEM_SIMPLE) - - -/* The standard object initialization function. */ -static void -goo_laser_data_init (GooLaserData *gld) -{ - -} - - -/* The convenience function to create new items. This should start with a - parent argument and end with a variable list of object properties to fit - in with the standard canvas items. */ -GooCanvasItem* -goo_laser_data_new (GooCanvasItem *parent, viewer_params *p, LDP ld) -{ - GooCanvasItem *item; - GooLaserData *gld; - - item = g_object_new (goo_laser_data_get_type(), NULL); - - gld = (GooLaserData*) item; - - ld_get_bounding_box(ld, gld->bb_min, gld->bb_max, ld->estimate, 10); - double padding = 1; - gld->bb_min[0] -= padding; - gld->bb_min[1] -= padding; - gld->bb_max[0] += padding; - gld->bb_max[1] += padding; - - - gld->p = p; - gld->ld = ld; - - ld_get_oriented_bbox(ld, 20, &(gld->obbox) ); - oplus_d(ld->estimate, gld->obbox.pose, gld->obbox.pose); - -/* va_start (var_args, height); - first_property = va_arg (var_args, char*); - if (first_property) - g_object_set_valist ((GObject*) item, first_property, var_args); - va_end (var_args); -*/ - if (parent) - { - goo_canvas_item_add_child (parent, item, -1); - g_object_unref (item); - } - - return item; -} - - -/* The update method. This is called when the canvas is initially shown and - also whenever the object is updated and needs to change its size and/or - shape. It should calculate its new bounds in its own coordinate space, - storing them in simple->bounds. */ -static void -goo_laser_data_update (GooCanvasItemSimple *simple, - cairo_t *cr) -{ - GooLaserData *gld = (GooLaserData*) simple; - -double padding = 0; - /* Compute the new bounds. */ - simple->bounds.x1 = gld->bb_min[0] - padding; - simple->bounds.y1 = gld->bb_min[1] - padding; - simple->bounds.x2 = gld->bb_max[0] + padding; - simple->bounds.y2 = gld->bb_max[1] + padding; - -/*sm_debug("Bound %f %f %f %f\n", gld->bb_min[0], -gld->bb_min[1], gld->bb_max[0], -gld->bb_max[1]);*/ - -} - -/* The paint method. This should draw the item on the given cairo_t, using - the item's own coordinate space. */ -static void -goo_laser_data_paint (GooCanvasItemSimple *simple, - cairo_t *cr, - const GooCanvasBounds *bounds) -{ - GooLaserData *gld = (GooLaserData*) simple; -/* - cairo_set_line_width (cr, 0.01); - cairo_move_to (cr, gld->bb_min[0], gld->bb_min[1]); - cairo_line_to (cr, gld->bb_max[0], gld->bb_min[1]); - cairo_line_to (cr, gld->bb_max[0], gld->bb_max[0]); - cairo_line_to (cr, gld->bb_min[0], gld->bb_max[0]); - cairo_line_to (cr, gld->bb_min[0], gld->bb_min[1]); - cairo_close_path (cr); - cairo_set_source_rgb(cr, 0.8, 0.9, 0.8); - cairo_stroke (cr); -*/ - - cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE ); - - - cairo_set_source_rgb(cr, 0.3, 0, 1.0); - cairo_arc(cr, 0,0, 0.4, 0.0, 2*M_PI); - cairo_fill(cr); - - cr_ld_draw(cr, gld->ld, &(gld->p->laser)); -} - - -/* Hit detection. This should check if the given coordinate (in the item's - coordinate space) is within the item. If it is it should return TRUE, - otherwises it should return FALSE. */ -static gboolean -goo_laser_data_is_item_at (GooCanvasItemSimple *simple, - gdouble x, - gdouble y, - cairo_t *cr, - gboolean is_pointer_event) -{ - GooLaserData *gld = (GooLaserData*) simple; - -/* if (x < gld->x || (x > gld->x + gld->width) - || y < gld->y || (y > gld->y + gld->height))*/ - return FALSE; - - return TRUE; -} - - -/* The class initialization function. Here we set the class' update(), paint() - and is_item_at() methods. */ -static void -goo_laser_data_class_init (GooLaserDataClass *klass) -{ - GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass; - - simple_class->simple_update = goo_laser_data_update; - simple_class->simple_paint = goo_laser_data_paint; - simple_class->simple_is_item_at = goo_laser_data_is_item_at; -} - - diff --git a/sm/apps/gtk_viewer/goo_laser_data.h b/sm/apps/gtk_viewer/goo_laser_data.h deleted file mode 100644 index 9565f09..0000000 --- a/sm/apps/gtk_viewer/goo_laser_data.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef H_GOO_LASER_DATA -#define H_GOO_LASER_DATA - -#include <gtk/gtk.h> -#include "goocanvasitemsimple.h" - -#include <csm/csm.h> - -#include "gtk_viewer.h" - -G_BEGIN_DECLS - -typedef struct _GooDemoItem GooDemoItem; -typedef struct _GooDemoItemClass GooDemoItemClass; - -typedef struct { - GooCanvasItemSimple parent_object; - - double bb_min[2], bb_max[2]; - oriented_bbox obbox; - - LDP ld; - - viewer_params *p; -} GooLaserData; - -typedef struct { - GooCanvasItemSimpleClass parent_class; -} GooLaserDataClass; - -GType goo_laser_data_get_type (void) G_GNUC_CONST; -GooCanvasItem* goo_laser_data_new (GooCanvasItem *parent, viewer_params *p, -LDP ld); - -G_END_DECLS - -#endif diff --git a/sm/apps/gtk_viewer/gtk_viewer-readme.txt b/sm/apps/gtk_viewer/gtk_viewer-readme.txt deleted file mode 100644 index 82e31a2..0000000 --- a/sm/apps/gtk_viewer/gtk_viewer-readme.txt +++ /dev/null @@ -1,10 +0,0 @@ - -# GTK Viewer # - -Just an experiment. - -Software prerequisites: - -* a recent version of GTK -* GooCanvas: http://sourceforge.net/projects/goocanvas - diff --git a/sm/apps/gtk_viewer/gtk_viewer.h b/sm/apps/gtk_viewer/gtk_viewer.h deleted file mode 100644 index 522cbc5..0000000 --- a/sm/apps/gtk_viewer/gtk_viewer.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef H_GTK_VIEWER -#define H_GTK_VIEWER - -#include <csm/csm_all.h> -#include <csm/laser_data_cairo.h> - -struct GooLaserData; - -typedef struct { - ld_style laser; - line_style pose_path; - - const char *use; - ld_reference use_reference; - const char * input_filename; - - oriented_bbox viewport; - - LDP* scans; - struct GooLaserData** scans_items; - int scans_size; - int scans_num; - - double device_size[2]; - - GooCanvasItem *root; - GooCanvas*canvas; -} viewer_params; - -void compute_transformations(viewer_params*p); - -#endif diff --git a/sm/apps/gtk_viewer/gtk_viewer1.c b/sm/apps/gtk_viewer/gtk_viewer1.c deleted file mode 100644 index fd0ad50..0000000 --- a/sm/apps/gtk_viewer/gtk_viewer1.c +++ /dev/null @@ -1,264 +0,0 @@ -#include <stdlib.h> -#include <goocanvas.h> -#include "goo_laser_data.h" -#include "gtk_viewer.h" - -static gboolean on_rect_button_press (GooCanvasItem *view, - GooCanvasItem *target, - GdkEventButton *event, - gpointer data); - -static gboolean on_delete_event (GtkWidget *window, - GdkEvent *event, - gpointer unused_data); - -void* reading_thread(void *data); - -GooCanvasItem* text_item; -GooCanvasItem* rect_item; - -int main (int argc, char **argv) -{ - sm_set_program_name(basename(argv[0])); - - viewer_params *p = (viewer_params*) malloc(sizeof(viewer_params)); - lds_set_defaults(&(p->laser)); - ls_set_defaults(&(p->pose_path)); - - p->laser.rays.draw = 0; - p->laser.points.draw = 0; - p->laser.normals.draw = 0; - p->laser.countour.width = 0.1; - p->pose_path.width = 0.1; - p->pose_path.color = "#f00"; - - struct option * ops = options_allocate(100); - options_string(ops, "in", &(p->input_filename), "stdin", "input file (Carmen or JSON)"); - options_string(ops, "use", &(p->use), "estimate", "One in 'odometry','estimate','true_pose'"); - - lds_add_options(&(p->laser), ops, "laser_", ""); - ls_add_options(&(p->pose_path), ops, "path_", ""); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "A simple experimental GTK viewer.\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - /* init threads */ - g_thread_init(NULL); - gdk_threads_init(); - - - GtkWidget *window, *scrolled_win, *canvas; -GooCanvasItem *root; - - /* Initialize GTK+. */ - gtk_set_locale (); - gtk_init (&argc, &argv); - - /* Create the window and widgets. */ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size (GTK_WINDOW (window), 640, 600); - gtk_widget_show (window); - g_signal_connect (window, "delete_event", (GtkSignalFunc) on_delete_event, - NULL); - - scrolled_win = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), - GTK_SHADOW_IN); - gtk_widget_show (scrolled_win); - gtk_container_add (GTK_CONTAINER (window), scrolled_win); - - canvas = goo_canvas_new (); - - root = goo_canvas_get_root_item (GOO_CANVAS (canvas)); - - p->device_size[0] = 800; - p->device_size[1] = 600; - - gtk_widget_set_size_request (canvas, p->device_size[0], p->device_size[1]); - goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, p->device_size[0], p->device_size[1]); - gtk_widget_show (canvas); - gtk_container_add (GTK_CONTAINER (scrolled_win), canvas); - - p->root = root; - p->canvas = canvas; - - - /* Add a few simple items. */ -rect_item = goo_canvas_rect_new (root, 0, 0, 50, 50, - "line-width", 10.0, - "radius-x", 20.0, - "radius-y", 10.0, - "stroke-color", "yellow", - "fill-color", "red", - NULL); - -/*text_item = goo_canvas_text_new (root, "Hello World", 300, 300, -1, - GTK_ANCHOR_CENTER, - "font", "Sans 1", - NULL); - goo_canvas_item_rotate (text_item, 45, 300, 300); - */ - - - GError * error; - if (!g_thread_create(reading_thread, p, FALSE, &error)) { - g_printerr ("Failed to create YES thread: %s\n", error->message); - return 1; - } - /* Pass control to the GTK+ main event loop. */ - gtk_main (); - -} - -void* reading_thread(void *data) { - viewer_params * p = (viewer_params*) data; - - FILE * input = open_file_for_reading(p->input_filename); - if(!input) return 0; - - p->scans = malloc(1); - p->scans_items = malloc(1); - p->scans_size = 0; - p->scans_num = 0; - - LDP ld; - while( (ld = ld_read_smart(input)) ) { - - if(p->scans_num >= p->scans_size) { - p->scans_size = 2* p->scans_size +10; - p->scans = realloc(p->scans, sizeof(LDP) * p->scans_size); - p->scans_items = realloc(p->scans_items, sizeof(LDP) * p->scans_size); - } - - gdk_threads_enter(); - - if(1) { - GooCanvasItem * gld = goo_laser_data_new (p->root, p, ld); - g_signal_connect (gld, "button_press_event", - (GtkSignalFunc) on_rect_button_press, NULL); - p->scans[p->scans_num] = ld; - p->scans_items[p->scans_num] = gld; - p->scans_num++; - } else { - - } - compute_transformations(p); - goo_canvas_update(p->canvas); -/* gdk_flush ();*/ - - gdk_threads_leave(); - /* sleep a while */ - usleep(20); -/* sleep(g_random_int_range (1, 4));*/ - } - - return 0; -} - -void world_to_viewport( - const oriented_bbox*obbox, const double device_size[2], cairo_matrix_t*m) { - - cairo_matrix_init_identity(m); - - double scale[2] = { - device_size[0] / obbox->size[0], - device_size[1] / obbox->size[1]}; - - double s = scale[0] < scale[1] ? scale[0] : scale[1]; - cairo_matrix_scale(m, s, s); - cairo_matrix_scale(m, 1, -1); - cairo_matrix_rotate(m, -obbox->pose[2]); - cairo_matrix_translate(m, -obbox->pose[0], -obbox->pose[1]); - -} - -void item_to_world(const double pose[3], cairo_matrix_t*m) { - cairo_matrix_init_identity(m); - cairo_matrix_translate(m, pose[0], pose[1]); - cairo_matrix_rotate(m, pose[2]); -} - -void compute_transformations(viewer_params*p) { - int k; - oriented_bbox global; - - if(0) { - bbfind * bbf = bbfind_new(); - int n = p->scans_num; -/* if(n>20) n = 20;*/ - - for(k=0;k<n;k++) { - GooLaserData * gld = (GooLaserData*) p->scans_items[k]; - bbfind_add_bbox(bbf, &gld->obbox); - } - - - if(bbfind_compute(bbf, &global)) { - sm_debug("%d Global: %s size %f %f\n", p->scans_num, friendly_pose(global.pose), - global.size[0], global.size[1]); - } else { - sm_error("%d Could not compute global bounding box.\n", p->scans_num); - } - bbfind_free(bbf); - }else{ - - global.pose[0] = -22; - global.pose[1] = -41; - global.pose[2] = M_PI/2; - global.size[0] = 106; - global.size[1] = 46; -} - cairo_matrix_t m_world_to_viewport; - world_to_viewport(&global, p->device_size, &(m_world_to_viewport)); - - cairo_matrix_t *m = &m_world_to_viewport; - sm_info("Matrix: %f %f %f %f %f %f\n", m->xx,m->yx,m->xy,m->yy, m->x0, m->y0); - - cairo_matrix_t mm; - cairo_matrix_init_identity(&mm); -/* cairo_matrix_translate(&mm, 300, 600);*/ - cairo_matrix_translate(&mm, 300, 600); - cairo_matrix_rotate(&mm, deg2rad(p->scans_num)); - goo_canvas_item_set_transform(rect_item, &mm); - - /* - goo_canvas_item_set_transform(text_item, &m_world_to_viewport); -*/ - for(k=0;k<p->scans_num;k++) { - GooCanvasItem * gld = p->scans_items[k]; - - double * pose = p->scans[k]->estimate; - cairo_matrix_t m_item_to_world; - item_to_world(pose, &m_item_to_world); - - cairo_matrix_t transform; - cairo_matrix_multiply(&transform, &m_item_to_world, &m_world_to_viewport); - goo_canvas_item_set_transform(gld, &transform); - } -} - -/* This handles button presses in item views. We simply output a message to - the console. */ -static gboolean -on_rect_button_press (GooCanvasItem *item, - GooCanvasItem *target, - GdkEventButton *event, - gpointer data) -{ - g_print ("rect item received button press event\n"); - return TRUE; -} - - -/* This is our handler for the "delete-event" signal of the window, which - is emitted when the 'x' close button is clicked. We just exit here. */ -static gboolean -on_delete_event (GtkWidget *window, - GdkEvent *event, - gpointer unused_data) -{ - exit (0); -} diff --git a/sm/apps/json2carmen.c b/sm/apps/json2carmen.c deleted file mode 100644 index d4cd4b1..0000000 --- a/sm/apps/json2carmen.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "../csm/csm_all.h" - -int main(int argc, char * argv[]) { - sm_set_program_name(argv[0]); - - LDP ld; int count=0, errors=0; - while((ld = ld_read_smart(stdin))) { - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - errors++; - continue; - } - - ld_write_as_carmen(ld, stdout); - - ld_free(ld); - count++; - } - - return errors; -} diff --git a/sm/apps/json2matlab.c b/sm/apps/json2matlab.c deleted file mode 100644 index e24941e..0000000 --- a/sm/apps/json2matlab.c +++ /dev/null @@ -1,286 +0,0 @@ -#include <assert.h> -#include <string.h> -#include "../csm/csm_all.h" -#include <options/options.h> - -#include <json-c/json.h> -#include <json-c/json_object_private.h> - -void jo_write_as_matlab(JO jo, FILE*out); - -void jo_write_as_matrix(JO jo, FILE*out); -void jo_write_as_column_vector(JO jo, FILE* out); - -void jo_write_as_cell_array(JO jo, FILE* out); -int jo_is_numeric_matrix(JO jo); -int jo_is_numeric_array(JO jo); -void jo_write_as_matlab_object(JO jo, FILE*out); - - -const char * banner = -"Converts JSON stream to Matlab file. \n" -"There are three usages: \n" -" 1) with only one parameter, \n" -" $ json2matlab dir/mydata.json \n" -" creates a Matlab function 'mydata' inside the file 'dir/mydata.m' \n" -" 2) with two parameters, \n" -" $ json2matlab dir/mydata.json dir/out.m \n" -" creates a Matlab function 'out' inside the file 'dir/out.m'. \n" -" 3) otherwise, use the options switches. \n" -" \n" -" By default it creates a complete script of the kind:\n" -" \n" -" function res = function_name()\n" -" res = \n" -" { ...}\n" -" \n" -" If complete_script is set to 0, it just outputs the meat: \n" -" \n" -" { ...}\n" -" \n"; - - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - const char * input_filename; - const char * out_filename; - const char * function; - int complete_script; - int debug; - - options_banner(banner); - - struct option* ops = options_allocate(8); - options_string(ops, "in", &input_filename, "stdin", "input file (JSON)"); - options_string(ops, "out", &out_filename, "stdout", "output file (MATLAB)"); - options_string(ops, "function", &function, "", "Matlab function name (if empty, use basename of out)"); - options_int(ops, "complete_script", &complete_script, 1, "Write complete script 'function res = ...'"); - options_int(ops, "debug", &debug, 1, "Shows debug information"); - - if(argc == 2 && (argv[1][0] != '-')) { - /* one parameter */ - input_filename = argv[1]; int len = strlen(input_filename) + 4; - char base[len], no_suffix[len], out[len]; - my_no_suffix(input_filename, no_suffix); - sprintf(out, "%s.m", no_suffix); - my_basename_no_suffix(input_filename, base); - out_filename = my_strdup(out); - function = my_strdup(base); - } else if(argc == 3 && (argv[1][0] != '-') && (argv[2][0] != '-')) { - input_filename = argv[1]; - out_filename = argv[2]; - } else { - /* FIXME help not shown */ - if(!options_parse_args(ops, argc, argv)) - return -1; - } - - sm_debug_write(debug); - - if(!strcmp(function,"")) { - int len = strlen(out_filename) + 4; - char base[len]; - my_basename_no_suffix(out_filename, base); - function = my_strdup(base); - } - - - FILE * out = open_file_for_writing(out_filename); - if(!out) return -2; - - FILE * in = open_file_for_reading(input_filename); - if(!in) return -3; - - if(complete_script) { - fprintf(out, "function res = %s\n", function); - fprintf(out, " res = ... \n"); - } - fprintf(out, " { ... \n\t"); - - JO jo; - int i = 0; - while((jo = json_read_stream(in))) { - if(i>0) fprintf(out, ", ...\n\t"); - jo_write_as_matlab(jo, out); - jo_free(jo); - i++; - } - - fprintf(out, "... \n }; \n"); - return 0; -} - - -void jo_write_as_matlab(JO jo, FILE*out) { - if(!jo) { fprintf(out, "NaN"); return; } - - switch(json_object_get_type(jo)) { - case json_type_null: - fprintf(out, "NaN"); - return; - - case json_type_boolean: - fprintf(out, json_object_get_boolean(jo) ? "true" : "false" ); - return; - - case json_type_int: - fprintf(out, "%d", json_object_get_int(jo)); - return; - - case json_type_double: - fprintf(out, "%lg", json_object_get_double(jo)); - return; - - case json_type_object: - jo_write_as_matlab_object(jo, out); - return; - - case json_type_array: - if(jo_is_numeric_matrix(jo)) - jo_write_as_matrix(jo, out); - else - if(jo_is_numeric_array(jo)) - jo_write_as_column_vector(jo, out); - else - jo_write_as_cell_array(jo, out); - return; - - case json_type_string: - fprintf(out, "'"); - const char* s = json_object_get_string(jo); - while(*s) { - if(*s==39) - fputc('"', out); - else - fputc(*s, out); - s++; - } - - fprintf(out, "'"); - return; - } - - -} - - - -void jo_write_as_matlab_object(JO jo, FILE*out) { - int i=0; - struct json_object_iter iter; - fprintf(out, "struct("); - - json_object_object_foreachC(jo, iter) { - if(i) fprintf(out, ", ... \n\t "); - fprintf(out, "'%s', ", iter.key); - - enum json_type t = json_object_get_type(iter.val); - if( (t == json_type_array) && (!jo_is_numeric_matrix(iter.val)) && (!jo_is_numeric_array(iter.val))) { - fprintf(out, "{"); - jo_write_as_matlab(iter.val, out); - fprintf(out, "}"); - } else if(t == json_type_object) { - fprintf(out, "{ "); - jo_write_as_matlab(iter.val, out); - fprintf(out, " }"); - } else jo_write_as_matlab(iter.val, out); - - i++; - } - fprintf(out, ")"); -} - - -int jo_is_numeric_matrix(JO jo) { - /* null is not a matrix */ - if(!jo) return 0; - if(json_object_get_type(jo) != json_type_array) return 0; - int len = json_object_array_length(jo); - int ncolumns = -1; - for(int i=0;i<len;i++){ - JO row = json_object_array_get_idx(jo, i); - if(!jo_is_numeric_array(row)) return 0; - if(i==0) - ncolumns = json_object_array_length(row); - else - if(ncolumns != json_object_array_length(row)) - return 0; - } - if(ncolumns==0) return 0; - return 1; -} - -int jo_is_numeric_array(JO jo) { - /* null is not an array */ - if(!jo) return 0; - if(json_object_get_type(jo) != json_type_array) return 0; - int len = json_object_array_length(jo); - for(int i=0;i<len;i++){ - JO elem = json_object_array_get_idx(jo, i); - - /* I consider null elements as numeric values because they can be - converted into NaN */ - if(elem==0) - continue; - - switch(json_object_get_type(elem)) { - case json_type_null: - case json_type_boolean: - case json_type_int: - case json_type_double: - continue; - default: - return 0; - } - } - return 1; -} - -void jo_write_as_matrix(JO jo, FILE*out) { -// "[ " + map{|row| row.join(", ")}.join("; ... \n") + "]" - assert(json_object_get_type(jo) == json_type_array); - fprintf(out, "["); - int len = json_object_array_length(jo); - for(int i=0;i<len;i++){ - if(i>0) fprintf(out, "; "); - JO row = json_object_array_get_idx(jo, i); - int n = json_object_array_length(row); - for(int j=0;j<n;j++) { - if(j>0) fprintf(out, ", "); - jo_write_as_matlab(json_object_array_get_idx(row, j), out); - } - } - fprintf(out, "]"); -} - -void jo_write_as_column_vector(JO jo, FILE* out) { -// "[ "+map{|x| x.to_matlab }.join("; ")+"]" - assert(json_object_get_type(jo) == json_type_array); - fprintf(out, "["); - int len = json_object_array_length(jo); - for(int i=0;i<len;i++){ - if(i>0) fprintf(out, "; "); - JO elem = json_object_array_get_idx(jo, i); - jo_write_as_matlab(elem, out); - } - fprintf(out, "]"); -} - -void jo_write_as_cell_array(JO jo, FILE* out) { - assert(json_object_get_type(jo) == json_type_array); - int len = json_object_array_length(jo); - if(len==0) { - fprintf(out, "{}"); - return; - } else { - fprintf(out, "{ "); - for(int i=0;i<len;i++){ - if(i>0) fprintf(out, ", "); - JO elem = json_object_array_get_idx(jo, i); - jo_write_as_matlab(elem, out); - } - fprintf(out, "}"); - } -// "{ ... \n "+map{|x| x.to_matlab }.join(", ... \n")+"}" -} diff --git a/sm/apps/json_decimate.c b/sm/apps/json_decimate.c deleted file mode 100644 index 5a39946..0000000 --- a/sm/apps/json_decimate.c +++ /dev/null @@ -1,54 +0,0 @@ -#include <options/options.h> -#include "../csm/csm_all.h" - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - int period; int phase; - const char*input_filename; - const char*output_filename; - - struct option* ops = options_allocate(3); - options_int(ops, "period", &period, 1, "Period of objects to extract."); - options_int(ops, "phase", &phase, 0, "Phase (=0 starts with the first object)"); - options_string(ops, "in", &input_filename, "stdin", "input file (JSON)"); - options_string(ops, "out", &output_filename, "stdout", "output file (JSON)"); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "%s : decimates a JSON stream." - "\n\nOptions:\n", argv[0]); - options_print_help(ops, stderr); - return -1; - } - - if(period < 1) { - sm_error("Period must be >= 1.\n"); - return 2; - } - - FILE * input_stream = open_file_for_reading(input_filename); - FILE *output_stream = open_file_for_writing(output_filename); - - if(!input_stream || !output_stream) return -1; - - - int count = 0; - while(1) { - JO jo = json_read_stream(input_stream); - if(!jo) { - if(feof(input_stream)) break; - sm_error("Malformed JSON\n"); - return -1; - } - - if( (count - phase) % period == 0) { - const char * s = json_object_to_json_string(jo); - fputs(s,output_stream); fputs("\n",output_stream); - } - - jo_free(jo); - count++; - } - - return 0; -} diff --git a/sm/apps/json_extract.c b/sm/apps/json_extract.c deleted file mode 100644 index e3c012e..0000000 --- a/sm/apps/json_extract.c +++ /dev/null @@ -1,45 +0,0 @@ -#include <options/options.h> -#include "../csm/csm_all.h" - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - int nth; - const char*input_filename; - const char*output_filename; - - struct option* ops = options_allocate(3); - options_int(ops, "nth", &nth, 0, "Index of object to extract."); - options_string(ops, "in", &input_filename, "stdin", "input file (JSON)"); - options_string(ops, "out", &output_filename, "stdout", "output file (JSON)"); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "%s : extracts n-th JSON object from stream." - "\n\nOptions:\n", argv[0]); - options_print_help(ops, stderr); - return -1; - } - - FILE * input_stream = open_file_for_reading(input_filename); - FILE *output_stream = open_file_for_writing(output_filename); - - if(!input_stream || !output_stream) return -1; - - int i; for(i=0;i<nth;i++) { - if(!json_stream_skip(input_stream)) { - sm_error("Could not skip %d-th object\n", i); - return -2; - } - } - - JO jo = json_read_stream(input_stream); - if(!jo) { - fprintf(stderr, "Could not read %d-th object (after skipping %d)\n", - nth, i); - return -2; - } - - fputs(json_object_to_json_string(jo), output_stream); - fputs("\n", output_stream); - return 0; -} diff --git a/sm/apps/json_extract_field.c b/sm/apps/json_extract_field.c deleted file mode 100644 index 8ebda07..0000000 --- a/sm/apps/json_extract_field.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <options/options.h> -#include "../csm/csm_all.h" - -void jo_write_plain(JO jo, FILE* out); - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - const char*input_filename; - const char*output_filename; - const char*field; - int exit_on_error; - - struct option* ops = options_allocate(3); - options_string(ops, "in", &input_filename, "stdin", "input file (JSON)"); - options_string(ops, "out", &output_filename, "stdout", "output file (JSON)"); - options_int(ops, "exit_on_error", &exit_on_error, 0, "if true, exit if object has no field"); - options_string(ops, "field", &field, "field_name", "field to extract from structure"); - - if(!options_parse_args(ops, argc, argv)) { - sm_info("Extracts a field from JSON object." - "\n\nOptions:\n"); - options_print_help(ops, stderr); - return -1; - } - - FILE * input_stream = open_file_for_reading(input_filename); - FILE *output_stream = open_file_for_writing(output_filename); - - if(!input_stream || !output_stream) return -1; - - int n=0; - while(1) { - n++; - - JO jo = json_read_stream(input_stream); - if(!jo) { - if(feof(input_stream)) break; - sm_error("Error while reading stream.\n"); - return -2; - } - - JO jo_field = jo_get(jo, field); - if(!jo_field) { - if(exit_on_error) { - sm_error("object #%d: field '%s' not found in structure.\n", n, field); - return -1; - } else { - sm_error("object #%d: field '%s' not found in structure.\n", n, field); - continue; - } - } - - jo_write_plain(jo_field, output_stream); - fputs("\n", output_stream); - jo_free(jo); - }; - - return 0; -} - -void jo_write_plain(JO jo, FILE* out) { - switch(json_object_get_type(jo)) { - case json_type_boolean: { - int v = (int) json_object_get_boolean(jo); - fprintf(out, "%d", v); - break; - } - case json_type_int: { - int v = json_object_get_int(jo); - fprintf(out, "%d", v); - break; - } - case json_type_double: { - double v = json_object_get_double(jo); - fprintf(out, "%g", v); - break; - } - case json_type_string: { - const char * s = json_object_get_string(jo); - fputs(s, out); - break; - } - case json_type_object: { - fputs("{object}", out); - break; - } - case json_type_array: { - int k, len = json_object_array_length(jo); - for(k=0; k<len; k++) { - JO v = json_object_array_get_idx(jo, k); - jo_write_plain(v, out); - if(k!=len-1) fputs(" ", out); - } - break; - } - - default: - sm_error("Unknown JSON type %d.\n", json_object_get_type(jo) ); - } - -} - diff --git a/sm/apps/json_pipe.c b/sm/apps/json_pipe.c deleted file mode 100644 index 9c5ef4c..0000000 --- a/sm/apps/json_pipe.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "../csm/csm_all.h" -#include <options/options.h> - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - int n; - - struct option* ops = options_allocate(3); - options_int(ops, "n", &n, 1, "Number of copies"); - if(!options_parse_args(ops, argc, argv)) { - sm_info("%s : reads a JSON stream and copies it multiplied by n." - "\n\nOptions:\n", (char*)argv[0]); - options_print_help(ops, stderr); - return -1; - } - - - while(1) { - JO jo = json_read_stream(stdin); - if(!jo) { - if(feof(stdin)) break; - sm_error("Malformed JSON\n"); - return -1; - } - - const char * s = json_object_to_json_string(jo); - int i; for(i=0;i<n;i++) { - puts(s); puts("\n"); - } - jo_free(jo); - } - - return 0; -} diff --git a/sm/apps/json_split.c b/sm/apps/json_split.c deleted file mode 100644 index 3d32713..0000000 --- a/sm/apps/json_split.c +++ /dev/null @@ -1,58 +0,0 @@ -#include <options/options.h> -#include <string.h> -#include "../csm/csm_all.h" - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - const char*input_filename; - const char*output_pattern_op; - - struct option* ops = options_allocate(3); - options_string(ops, "in", &input_filename, "stdin", "input file (JSON)"); - options_string(ops, "out", &output_pattern_op, "./ld_split^02d.json", "output pattern; printf() pattern, but write '^' instead of '%'"); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "%s : splits a JSON file into many files." - "\n\nOptions:\n", argv[0]); - options_print_help(ops, stderr); - return -1; - } - - - /* Substitute "$" with "%" */ - - char output_pattern[256]; strcpy(output_pattern, output_pattern_op); - char *f = output_pattern; - while(*f) { - if(*f=='^') *f='%'; - f++; - } - - fputs(output_pattern, stderr); - - FILE * input_stream = open_file_for_reading(input_filename); - - int count = 0; - - JO jo; - while( (jo = json_read_stream(input_stream)) ) { - char filename[1000]; - sprintf(filename, output_pattern, count); - if(!count) { - - } - - sm_debug("Writing to file (%s) %s\n", output_pattern, filename); - FILE * f = open_file_for_writing(filename); - if(!f) return -1; - fputs(json_object_to_json_string(jo), f); - jo_free(jo); - fclose(f); - - count++; - } - - - return 0; -} diff --git a/sm/apps/ld_alternate.c b/sm/apps/ld_alternate.c deleted file mode 100644 index 925c5e1..0000000 --- a/sm/apps/ld_alternate.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "../csm/csm_all.h" - -int main(int argc, const char ** argv) { - sm_set_program_name(argv[0]); - - int every = 5; - int count = 0; - LDP ld; - while( (ld = ld_read_smart(stdin))) { - count++; - - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - continue; - } - - int i; - for(i=0;i<ld->nrays;i++) { - if( (i % every) != 0 ) { - ld->valid[i] = 0; - ld->readings[i] = NAN; - } - } - - ld_write_as_json(ld, stdout); - ld_free(ld); - - count++; - } - - return 0; -} diff --git a/sm/apps/ld_cluster_curv.c b/sm/apps/ld_cluster_curv.c deleted file mode 100644 index 6cc5d96..0000000 --- a/sm/apps/ld_cluster_curv.c +++ /dev/null @@ -1,222 +0,0 @@ -#include <options/options.h> -#include "../csm/csm_all.h" - -struct { - /** Scale factor */ - double scale_deg; - - /** How many neighbours to consider */ - int neighbours; -} p; - -void ld_cluster_curv(LDP ld) ; - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); -/* - struct option* ops = options_allocate(3); - options_double(ops, "scale_deg", &p.scale_deg, 0.0, "Scale factor (degrees) "); - options_int(ops, "neighbours", &p.neighbours, 1, "How many neighbours to consider (regardless of scale)."); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "A simple program for smoothing a sensor scan.\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } -*/ -/* jj_set_stream(open_file_for_writing("ld_cluster_curv.txt")); */ - - int errors = 0; - int count = -1; - LDP ld; - while( (ld = ld_read_smart(stdin)) ) { - count++; - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - return -1; - } - - ld_cluster_curv(ld); - - ld_write_as_json(ld, stdout); - - ld_free(ld); - } - - return errors; -} - -void cluster_convolve(const int*cluster,const double*original, int n, double*dest, double*filter, int filter_len, int negate_negative) -{ - int i; /* index on the points */ - int j; /* index on the filter */ - - for(i=0;i<n;i++) { - if(cluster[i] == -1) { - dest[i] = GSL_NAN; - continue; - } - - dest[i] = 0; - for(j=-(filter_len-1);j<=(filter_len-1);j++) { - int i2 = i + j; - if(i2<0) i2=0; if(i2>=n) i2=n-1; - if(cluster[i2] != cluster[i]) i2 = i; - double coeff = filter[abs(j)]; - if(j<0 && negate_negative) coeff *= -1; - dest[i] += original[i2] * coeff; - - if(is_nan(dest[i])) - sm_error("i: %d; something wrong after processing i2: %d cluster[i2]=%d original[i2] = %f \n", i, i2, cluster[i2], original[i2]); - - } - - } -} - -int cluster_find_max(int*cluster, double*v, int n) { - int i, max = -1; - for(i=0;i<n;i++) { - if(cluster[i] == -1) continue; - if( (max == -1) || (v[i] > v[max]) ) - max = i; - } - return max; -} - -int find_max(int *v, int n) { - int i, max = -1; - for(i=0;i<n;i++) { - if( (max == -1) || (v[i] > v[max]) ) - max = i; - } - return max; -} - -int ld_max_cluster_id(LDP ld) { - return ld->cluster[ find_max(ld->cluster, ld->nrays)]; -} - -int ld_cluster_size(LDP ld, int i0) { - int this_cluster = ld->cluster[i0]; - int num = 0; int i; - - for(i=i0;i<ld->nrays;i++) - if(ld->cluster[i] == this_cluster) - num++; - else if(ld->cluster[i] != -1) break; - - return num; -} - -void ld_remove_small_clusters(LDP ld, int min_size) { - int i; - for(i=0;i<ld->nrays;) { - int this_cluster = ld->cluster[i]; - - if(this_cluster == -1) { i++; continue; } - int cluster_size = ld_cluster_size(ld, i); - - if(cluster_size < min_size) { - for(;i<ld->nrays;i++) - if(ld->cluster[i] == this_cluster) - ld->cluster[i] = -1; - else if(ld->cluster[i] != -1) break; - } else i++; - } -} - -void ld_mark_cluster_as_invalid(LDP ld, int cluster) { - int i; - for(i=0;i<ld->nrays;i++) { - if(ld->cluster[i] == cluster) - ld->valid[i] = 0; - } -} - -void array_abs(double*v, int n) { - int i=0; for(i=0;i<n;i++) v[i] = fabs(v[i]); -} - - -void ld_cluster_curv(LDP ld) { - int min_cluster_size = 10; - double sigma = 0.005; - int orientation_neighbours = 4; - int npeaks = 5; - double near_peak_threshold = 0.4; - - if(JJ) jj_context_enter("ld_cluster_curv"); - int n = ld->nrays; - - - if(JJ) jj_add_int_array("a00valid", ld->valid, n); - if(JJ) jj_add_double_array("a01theta", ld->theta, n); - if(JJ) jj_add_double_array("a02readings", ld->readings, n); - - - ld_simple_clustering(ld, sigma*5); -/* int i=0; for(i=0;i<n;i++) - ld->cluster[i] = ld->valid[i] ? 1 : -1;*/ - - - if(JJ) jj_add_int_array("a04cluster", ld->cluster, n); - ld_remove_small_clusters(ld, min_cluster_size); - ld_mark_cluster_as_invalid(ld, -1); - if(JJ) jj_add_int_array("a06cluster", ld->cluster, n); - - double filter[10] = {.5, .4, .3, .2, .2, .2, .2, .2, .2, .2}; - double deriv_filter[7] = {0, .6, .3, .2, .2, .2, .1}; - double smooth_alpha[n]; - double deriv_alpha[n]; - - int p; - if(JJ) jj_loop_enter("it"); - - for(p=0;p<npeaks;p++) { if(JJ) jj_loop_iteration(); - - if(JJ) jj_add_int_array("cluster", ld->cluster, n); - - ld_compute_orientation(ld, orientation_neighbours, sigma); - - int i; - for(i=0;i<ld->nrays;i++) - if(!ld->alpha_valid[i]) - ld->cluster[i] = -1; - - if(JJ) jj_add_double_array("alpha", ld->alpha, n); - cluster_convolve(ld->cluster, ld->alpha, n, smooth_alpha, filter, 10, 0); - if(JJ) jj_add_int_array("alpha_valid", ld->alpha_valid, n); - - if(JJ) jj_add_double_array("smooth_alpha", smooth_alpha, n); - cluster_convolve(ld->cluster, smooth_alpha, n, deriv_alpha, deriv_filter, 7, 1); - if(JJ) jj_add_double_array("deriv_alpha", deriv_alpha, n); - array_abs(deriv_alpha, n); - - int peak = cluster_find_max(ld->cluster, deriv_alpha, n); - if(JJ) jj_add_int("peak", peak); - - int peak_cluster = ld->cluster[peak]; - int up = peak; double threshold = near_peak_threshold * deriv_alpha[peak]; - while(up<n-1 && (ld->cluster[up]==peak_cluster) && deriv_alpha[up+1] > threshold) up++; - int down = peak; - while(down>1 && (ld->cluster[up]==peak_cluster) && deriv_alpha[down-1] > threshold) down--; - int j; - for(j=down;j<=up;j++) { - ld->cluster[j] = -1; - ld->valid[j] = 0; - ld->readings[j] = NAN; - } - - int next_cluster = ld_max_cluster_id(ld) + 1; - for(j = up+1; j<ld->nrays; j++) { - if(ld->cluster[j] == peak_cluster) - ld->cluster[j] = next_cluster; - } - } - if(JJ) jj_loop_exit(); - - if(JJ) jj_context_exit(); -} - - diff --git a/sm/apps/ld_correct.c b/sm/apps/ld_correct.c deleted file mode 100644 index 5b4e74f..0000000 --- a/sm/apps/ld_correct.c +++ /dev/null @@ -1,97 +0,0 @@ -#include <math.h> -#include <gsl/gsl_math.h> - -#include <options/options.h> - -#include "../csm/csm_all.h" - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - - const char*input_filename; - const char*output_filename; - double diff[3] = {0, 0, 0}; - - double laser[3] ={0,0,0}; - - double omega[2] ={0,0}; - double omega_vel = 0; - double vel[2] ={0,0}; - double vel_omega = 0; - - - struct option* ops = options_allocate(15); - options_string(ops, "in", &input_filename, "stdin", "input file"); - options_string(ops, "out", &output_filename, "stdout", "output file"); - options_double(ops, "l_x", &(laser[0]), 0.0, "laser x (m)"); - options_double(ops, "l_y", &(laser[1]), 0.0, "laser y (m)"); - options_double(ops, "l_theta", &(laser[2]), 0.0, "laser theta (rad)"); - - options_double(ops, "omega0", &(omega[0]), 0.0, "omega (rad)"); - options_double(ops, "omega1", &(omega[1]), 0.0, "omega (linear)"); - options_double(ops, "omega_vel", &(omega_vel), 0.0, "omega x vel"); - options_double(ops, "vel0", &(vel[0]), 0.0, "vel (m)"); - options_double(ops, "vel1", &(vel[1]), 0.0, "vel (linear)"); - options_double(ops, "vel_omega", &(vel_omega), 0.0, "vel x omega"); - - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, " Corrects bias in odometry.\n"); - options_print_help(ops, stderr); - return -1; - } - - FILE * input_stream = open_file_for_reading(input_filename); - FILE *output_stream = open_file_for_writing(output_filename); - - if(!input_stream || !output_stream) return -1; - - LDP laser_ref = ld_read_smart(input_stream); - if(!laser_ref) { - sm_error("Cannot read first scan.\n"); - return -2; - } - - copy_d(laser_ref->odometry, 3, laser_ref->estimate); - - double old_odometry[3]; - copy_d(laser_ref->odometry, 3, old_odometry); - - LDP laser_sens; - ld_write_as_json(laser_ref, output_stream); - - while((laser_sens = ld_read_smart(input_stream))) { - double guess[3], old_guess[3]; - pose_diff_d(laser_sens->odometry, old_odometry, guess); - pose_diff_d(laser_sens->odometry, old_odometry, old_guess); - copy_d(laser_sens->odometry, 3, old_odometry); - - if(fabs(guess[2]) > 1e-7) - guess[2] = old_guess[2] * omega[1] + omega_vel * guess[0] + omega[0]; - - if(fabs(guess[0]) > 1e-7) - guess[0] = old_guess[0] * vel[1] + vel_omega * guess[2] + vel[0]; - - fprintf(stderr, "odo: %f %f %f Corr: %f rad \t%f m \n", guess[0], guess[1], guess[2], guess[2]-old_guess[2], guess[0]-old_guess[0]); - - oplus_d(laser_ref->odometry, guess, laser_sens->odometry); - oplus_d(laser_sens->odometry, laser, laser_sens->estimate); - - fprintf(stderr, "ref odo: %s ref est: %s \n", - friendly_pose(laser_ref->odometry), - friendly_pose(laser_ref->estimate)); - fprintf(stderr, "sens odo: %s sens est: %s \n", - friendly_pose(laser_sens->odometry), - friendly_pose(laser_sens->estimate)); - - - - ld_write_as_json(laser_sens, output_stream); - - ld_free(laser_ref); - laser_ref = laser_sens; - } - - return 0; -} diff --git a/sm/apps/ld_exp_tro1.c b/sm/apps/ld_exp_tro1.c deleted file mode 100644 index 6ec0ff8..0000000 --- a/sm/apps/ld_exp_tro1.c +++ /dev/null @@ -1,113 +0,0 @@ -#include <string.h> -#include <gsl/gsl_rng.h> -#include <gsl/gsl_randist.h> -#include <gsl/gsl_math.h> -#include <math.h> -#include <options/options.h> - -#include "../csm/csm_all.h" - -struct ld_exp_tro1_params { - int seed; - - double max_xy_error; - double max_theta_error_deg; - - const char* file_input; - const char* file_output1; - const char* file_output2; - - int num_per_scan; - - int debug; -}; - -const char * banner = - "This program prepares the data for one of the experiments. \n\n" - "The input is any sensor log (Carmen or JSON format) \n" - "The output are two files that contain laser_ref and laser_sens\n" - "(you have to match the i-th scan in the first file with the i-th\n" - " in the second).\n\n" - "The two files contain exactly the same date but for the 'odometry' field\n" - "The odometry error is uniform in the intervals given.\n"; - -int main(int argc, const char ** argv) { - sm_set_program_name(argv[0]); - - struct ld_exp_tro1_params p; - - options_banner(banner); - - struct option* ops = options_allocate(10); - options_double(ops, "max_xy_error", &p.max_xy_error, 10.0, "Maximum error for x,y (m)"); - options_double(ops, "max_theta_error_deg", &p.max_theta_error_deg, 10.0, "Maximum error for orientation (deg)"); - options_int (ops, "seed", &p.seed, 0, "Seed for random number generator (if 0, use GSL_RNG_SEED env. variable)."); - - options_int(ops, "num_per_scan", &p.num_per_scan, 10, "Number of trials for each scan."); - - options_string(ops, "in", &p.file_input, "stdin", "Input file "); - options_string(ops, "out1", &p.file_output1, "stdout", "Output file for first scan"); - options_string(ops, "out2", &p.file_output2, "stdout", "Output file for second scan"); - - options_int(ops, "debug", &p.debug, 0, "Shows debug information"); - - if(!options_parse_args(ops, argc, argv)) { - options_print_help(ops, stderr); - return -1; - } - - sm_debug_write(p.debug); - - gsl_rng_env_setup(); - gsl_rng * rng = gsl_rng_alloc (gsl_rng_ranlxs0); - if(p.seed != 0) - gsl_rng_set(rng, (unsigned int) p.seed); - - /* Open the two output files (possibly the same one) */ - - FILE * in = open_file_for_reading(p.file_input); - if(!in) return -3; - - FILE * out1 = open_file_for_writing(p.file_output1); - if(!out1) return -2; - - FILE * out2; - if(!strcmp(p.file_output1, p.file_output2)) { - out1 = out2; - } else { - out2 = open_file_for_writing(p.file_output2); - if(!out2) return -2; - } - - /* Read laser data from input file */ - LDP ld; int count=0; - while( (ld = ld_read_smart(in))) { - count++; - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - continue; - } - - for(int n=0; n < p.num_per_scan; n++) { - ld->true_pose[0] = 0; - ld->true_pose[1] = 0; - ld->true_pose[2] = 0; - - ld->odometry[0] = 0; - ld->odometry[1] = 0; - ld->odometry[2] = 0; - - ld_write_as_json(ld, out1); - - ld->odometry[0] = 2*(gsl_rng_uniform(rng)-0.5) * p.max_xy_error; - ld->odometry[1] = 2*(gsl_rng_uniform(rng)-0.5) * p.max_xy_error; - ld->odometry[2] = 2*(gsl_rng_uniform(rng)-0.5) * deg2rad(p.max_theta_error_deg); - - ld_write_as_json(ld, out2); - } - - ld_free(ld); - } - - return 0; -} diff --git a/sm/apps/ld_fisher.c b/sm/apps/ld_fisher.c deleted file mode 100644 index 4d9f00c..0000000 --- a/sm/apps/ld_fisher.c +++ /dev/null @@ -1,46 +0,0 @@ -#include <libgen.h> -#include <math.h> - -#include <options/options.h> -#include "../csm/csm_all.h" - - -struct ld_fisher_params { - double sigma; -}; - -val ld_fisher0(LDP ld); - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - struct ld_fisher_params p; - - struct option* ops = options_allocate(3); - options_double(ops, "sigma", &p.sigma, 0.01, - "Std deviation of gaussian noise"); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "Writes Fisher's information matrix.\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - egsl_push(); - - LDP ld; - while( (ld = ld_from_json_stream(stdin))) { - egsl_push(); - val fisher = egsl_scale( square(p.sigma), ld_fisher0(ld) ); - - JO jo = matrix_to_json(egsl_gslm(fisher)); - printf("%s\n", json_object_to_json_string(jo)); - jo_free(jo); - egsl_pop(); - ld_free(ld); - } - - egsl_pop(); - - return 0; -} diff --git a/sm/apps/ld_linearize.c b/sm/apps/ld_linearize.c deleted file mode 100644 index a992107..0000000 --- a/sm/apps/ld_linearize.c +++ /dev/null @@ -1,94 +0,0 @@ -#include <options/options.h> -#include "../csm/csm_all.h" - -void ld_linearize(LDP ld); -double weighted_mean(double *x, double *weight, int n); - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - int errors = 0; - int count = -1; - LDP ld; - while( (ld = ld_read_smart(stdin)) ) { - count++; - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - errors++; - continue; - } - - ld_linearize(ld); - - ld_write_as_json(ld, stdout); - - ld_free(ld); - } - - return errors; -} - -double weighted_mean(double *x, double *weight, int n) { - double sum_weight = 0; - double sum_x = 0; - int i; - for(i=0;i<n;i++) { - sum_x += weight[i] * x[i]; - sum_weight += weight[i]; - } - return sum_x / sum_weight; -} - - -void ld_linearize(LDP ld) { - int i; - for(i=0;i<ld->nrays;i++) { - if(-1 == ld->cluster[i]) continue; - - int this_cluster = ld->cluster[i]; - int indexes[ld->nrays]; - int nindexes = 0; - - int j; - for(j=i;j<ld->nrays;j++) - if(ld->cluster[j]==this_cluster) - indexes[nindexes++] = j; - - double alpha[nindexes]; - double alpha_weight[nindexes]; - for(j=0;j<nindexes;j++) { - alpha[j] = ld->alpha[indexes[j]]; - alpha_weight[j] = 1 / ld->cov_alpha[indexes[j]]; - } - - double est_alpha = weighted_mean(alpha, alpha_weight, nindexes); - - double rho[nindexes]; - double rho_weight[nindexes]; - for(j=0;j<nindexes;j++) { - int i = indexes[j]; - double theta = ld->theta[i]; - double x = cos(theta) * ld->readings[i]; - double y = sin(theta) * ld->readings[i]; - rho[j] = cos(est_alpha) * x + sin(est_alpha) * y; - rho_weight[j] = 1 / ( cos(est_alpha) * cos(theta) - + sin(est_alpha) * sin(theta) ); - } - - double est_rho = weighted_mean(rho, rho_weight, nindexes); - - for(j=0;j<nindexes;j++) { - int i = indexes[j]; - double theta = ld->theta[i]; - ld->readings[i] = est_rho / (cos(est_alpha) * cos(theta) - + sin(est_alpha) * sin(theta)); - } - - i = indexes[nindexes-1]; - } - -} - - - - diff --git a/sm/apps/ld_noise.c b/sm/apps/ld_noise.c deleted file mode 100644 index 9bc4181..0000000 --- a/sm/apps/ld_noise.c +++ /dev/null @@ -1,113 +0,0 @@ -#include <gsl/gsl_rng.h> -#include <gsl/gsl_randist.h> - -#include <math.h> -#include <libgen.h> - -#include <options/options.h> -#include "../csm/csm_all.h" - -struct ld_noise_params { - int seed; - double discretization; - double sigma; - const char* file_input; - const char* file_output; - int lambertian; -}; - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - options_banner("ld_noise: Adds noise to readings in a scan"); - - struct ld_noise_params p; - - struct option* ops = options_allocate(20); - options_double(ops, "discretization", &p.discretization, 0.0, - "Size of discretization (disabled if 0)"); - options_double(ops, "sigma", &p.sigma, 0.0, - "Std deviation of gaussian noise (disabled if 0)"); - options_int(ops, "lambertian", &p.lambertian, 0, - "Use lambertian model cov = sigma^2 / cos(beta^2) where beta is the incidence. Need have alpha or true_alpha."); - options_int(ops, "seed", &p.seed, 0, - "Seed for random number generator (if 0, use GSL_RNG_SEED env. variable)."); - options_string(ops, "in", &p.file_input, "stdin", "Input file "); - options_string(ops, "out", &p.file_output, "stdout", "Output file "); - - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "A simple program for adding noise to sensor scans.\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - FILE * in = open_file_for_reading(p.file_input); - if(!in) return -3; - - FILE * out = open_file_for_writing(p.file_output); - if(!out) return -2; - - - gsl_rng_env_setup(); - gsl_rng * rng = gsl_rng_alloc (gsl_rng_ranlxs0); - if(p.seed != 0) - gsl_rng_set(rng, (unsigned int) p.seed); - - LDP ld; int count = 0; - while( (ld = ld_from_json_stream(in))) { - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - continue; - } - - int i; - for(i=0;i<ld->nrays;i++) { - if(!ld->valid[i]) continue; - - double * reading = ld->readings + i; - if(p.sigma > 0) { - double add_sigma = p.sigma; - - if(p.lambertian) { - - int have_alpha = 0; - double alpha = 0; - if(!is_nan(ld->true_alpha[i])) { - alpha = ld->true_alpha[i]; - have_alpha = 1; - } else if(ld->alpha_valid[i]) { - alpha = ld->alpha[i];; - have_alpha = 1; - } else have_alpha = 0; - - if(have_alpha) { - /* Recall that alpha points outside the surface */ - double beta = (alpha+M_PI) - ld->theta[i]; - add_sigma = p.sigma / cos(beta); - } else { - sm_error("Because lambertian is active, I need either true_alpha[] or alpha[]"); - ld_write_as_json(ld, stderr); - return -1; - } - - } - - *reading += gsl_ran_gaussian(rng, add_sigma); - - if(is_nan(ld->readings_sigma[i])) { - ld->readings_sigma[i] = add_sigma; - } else { - ld->readings_sigma[i] = sqrt(square(add_sigma) + square(ld->readings_sigma[i])); - } - } - if(p.discretization > 0) - *reading -= fmod(*reading , p.discretization); - } - - ld_write_as_json(ld, out); - ld_free(ld); - } - - return 0; -} diff --git a/sm/apps/ld_purify.c b/sm/apps/ld_purify.c deleted file mode 100644 index 53de455..0000000 --- a/sm/apps/ld_purify.c +++ /dev/null @@ -1,87 +0,0 @@ -#include <gsl/gsl_rng.h> -#include <gsl/gsl_randist.h> - -#include <math.h> -#include <libgen.h> - -#include <options/options.h> -#include "../csm/csm_all.h" - -void purify(LDP ld, double threshold_min, double threshold_max); - - -struct ld_purify_params { - double threshold_min, threshold_max; - const char* file_input; - const char* file_output; -}; - - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - - options_banner("ld_purify: Makes sure that the file format is valid. \n * Sets valid=0 if reading is outside interval "); - - struct ld_purify_params p; - - struct option* ops = options_allocate(20); - options_double(ops, "threshold_min", &p.threshold_min, 0.01, - "Sets valid=0 if readings are less than this threshold."); - options_double(ops, "threshold_max", &p.threshold_max, 79.0, - "Sets valid=0 if readings are more than this threshold."); - - options_string(ops, "in", &p.file_input, "stdin", "Input file "); - options_string(ops, "out", &p.file_output, "stdout", "Output file "); - - - if(!options_parse_args(ops, argc, argv)) { - options_print_help(ops, stderr); - return -1; - } - - FILE * in = open_file_for_reading(p.file_input); - if(!in) return -3; - - FILE * out = open_file_for_writing(p.file_output); - if(!out) return -2; - - - - LDP ld; int count = -1; - while( (ld = ld_from_json_stream(in))) { - - purify(ld, p.threshold_min, p.threshold_max); - - if(!ld_valid_fields(ld)) { - sm_error("Wait, we didn't purify enough (#%d in file)\n", count); - continue; - } - - ld_write_as_json(ld, out); - ld_free(ld); - } - - return 0; -} - - - -void purify(LDP ld, double threshold_min, double threshold_max) { - for(int i=0;i<ld->nrays;i++) { - if(!ld->valid[i]) continue; - - double rho = ld->readings[i]; - if( is_nan(rho) | (rho < threshold_min) | (rho > threshold_max) ) { - ld->readings[i] = GSL_NAN; - ld->valid[i] = 0; - ld->alpha[i] = GSL_NAN; - ld->alpha_valid[i] = 0; - } - - } - -} - - - diff --git a/sm/apps/ld_recover.c b/sm/apps/ld_recover.c deleted file mode 100644 index 89f4e40..0000000 --- a/sm/apps/ld_recover.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <math.h> -#include <options/options.h> - -#include "../csm/csm_all.h" -#include "../csm/laser_data_drawing.h" - -/** Two scans are the same if they have the same timestamp. */ -int same_scan(LDP ld1, LDP ld2); -/** Short description for a scan. */ -const char * short_desc(LDP ld); - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - const char *in_filename; - const char *ref_filename; - const char *out_filename; - const char *ref_field_string; ld_reference ref_field; - const char *out_field_string; ld_reference out_field; - - struct option* ops = options_allocate(15); - options_string(ops, "in", &in_filename, "stdin", "scan matching log"); - options_string(ops, "ref", &ref_filename, "ref.log", "slam log"); - options_string(ops, "out", &out_filename, "stdout", "output file"); - - options_string(ops, "ref_field", &ref_field_string, "estimate", "What field to find in ref."); - options_string(ops, "out_field", &out_field_string, "true_pose", "What field to copy to."); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, " This program works on two logs: A and B. " - "For each scan in A, the program searches for the scan in B having the same timestamp. " - "Then, the true_pose field in B is copied to the scan form A, and it is written to the output.\n"); - options_print_help(ops, stderr); - return -1; - } - - ref_field = ld_string_to_reference(ref_field_string); - out_field = ld_string_to_reference(out_field_string); - - - FILE * in_stream = open_file_for_reading(in_filename); - FILE * ref_stream = open_file_for_reading(ref_filename); - FILE * out_stream = open_file_for_writing(out_filename); - - if(!in_stream || !ref_stream || !out_stream) return -1; - - LDP ld_in; - while((ld_in = ld_read_smart(in_stream))) { - int matched = 0; - while(1) { - LDP ld_ref = ld_read_smart(ref_stream); - if(!ld_ref) break; - if(same_scan(ld_in, ld_ref)) { - matched = 1; - const double *ref_pose = ld_get_reference_pose(ld_ref, ref_field); - double *out_pose = ld_get_reference_pose_silent(ld_in, out_field); - copy_d(ref_pose, 3, out_pose); - ld_write_as_json(ld_in, out_stream); - fputs("\n", out_stream); - break; - } - ld_free(ld_ref); - } - - if(!matched) { - sm_error("Could not match %s. \n", short_desc(ld_in)); - if(feof(ref_stream)) { - sm_error("..because ref stream has ended.\n"); - break; - } - continue; - } - - ld_free(ld_in); - } - - return 0; -} - - -/** Two scans are the same if they have the same timestamp. */ -int same_scan(LDP ld1, LDP ld2) { - return (ld1->tv.tv_sec == ld2->tv.tv_sec) && - (ld1->tv.tv_usec == ld2->tv.tv_usec); -} - -char buf[100]; -const char * short_desc(LDP ld) { - sprintf(buf, "LD, tv=%d,%d", (int) ld->tv.tv_sec, (int) ld->tv.tv_usec); - return buf; -} - diff --git a/sm/apps/ld_remove_doubles.c b/sm/apps/ld_remove_doubles.c deleted file mode 100644 index 73d594f..0000000 --- a/sm/apps/ld_remove_doubles.c +++ /dev/null @@ -1,86 +0,0 @@ -#include <time.h> - -#include <options/options.h> - -#include "../csm/csm_all.h" - -int ld_equal_readings(LDP ld1, LDP ld2, double epsilon); - -int main(int argc, const char*argv[]) { - sm_set_program_name(argv[0]); - - double epsilon; - int debug; - - - struct option* ops = options_allocate(3); - options_double(ops, "epsilon", &epsilon, 0.0001, "minimum difference between rays to be used"); - - - if(!options_parse_args(ops, argc, argv)) { - options_print_help(ops, stderr); - return -1; - } - - sm_debug_write(debug); - - - /* Read first scan */ - LDP laser_ref=0, laser_sens; - - int count = -1; - int num_discarded = 0; - int num_invalid = 0; - int ref_index = 0; - - while( (laser_sens = ld_read_smart(stdin)) ) { - count++; - - if(!ld_valid_fields(laser_sens)) { - sm_error("Invalid laser data (#%d in file)\n", count); - num_invalid++; - continue; - } - - if(!laser_ref) { - laser_ref = laser_sens; - ld_write_as_json(laser_sens, stdout); - count++; - continue; - } - - if(ld_equal_readings(laser_ref, laser_sens, epsilon)) { - sm_debug("Ignoring scan #%d, too similar to #%d.\n", count, ref_index); - num_discarded++; - } else { - ld_write_as_json(laser_sens, stdout); - ld_free(laser_ref); - laser_ref = laser_sens; - ref_index = count; - } - - } - if(laser_ref) ld_free(laser_ref); - - sm_info("# epsilon: %f m\n", epsilon); - sm_info("# scans: %d\n", count); - if(count>0) { - sm_info("# invalid: %d\n", num_invalid); - sm_info("# discarded: %d (%d%%)\n", num_discarded, num_discarded * 100 / count); - } - - return num_invalid; -} - - - -int ld_equal_readings(LDP ld1, LDP ld2, double epsilon) { - int i; - for(i=0;i<ld1->nrays;i++) { - if(!ld_valid_ray(ld1,i) || !ld_valid_ray(ld2,i)) continue; - - if(fabs(ld1->readings[i]-ld2->readings[i]) > epsilon) - return 0; - } - return 1; -} diff --git a/sm/apps/ld_resample.c b/sm/apps/ld_resample.c deleted file mode 100644 index 95b8620..0000000 --- a/sm/apps/ld_resample.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <gsl/gsl_rng.h> -#include <gsl/gsl_randist.h> -#include <gsl/gsl_math.h> - -#include <math.h> -#include <options/options.h> - - -#include "../csm/csm_all.h" - -struct { - double interval; - int seed; -}p ; - -LDP ld_resample(LDP ld); - -gsl_rng * rng; - -int main(int argc, const char ** argv) { - sm_set_program_name(argv[0]); - - - struct option* ops = options_allocate(3); - options_double(ops, "interval", &p.interval, sqrt(2.0), " 1 = no resampling"); - - if(!options_parse_args(ops, argc, argv)) { - options_print_help(ops, stderr); - return -1; - } - - int count = -1; - LDP ld; - while( (ld = ld_read_smart(stdin))) { - count++; - - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - continue; - } - -/* if(count & 1) {*/ - LDP ld2 = ld_resample(ld); - ld_write_as_json(ld2, stdout); - ld_free(ld2); - ld_free(ld); -/* } else { - ld_write_as_json(ld, stdout); - ld_free(ld); - }*/ - - count++; - } - - return 0; -} - -LDP ld_resample(LDP ld) { - /* FIXME magic number */ - int n = (int) (floor(ld->nrays / p.interval)); - - LDP ld2 = ld_alloc_new(n); - int k; - for(k=0;k<n;k++) { - double index = k * p.interval; - int i = (int) floor(index); - int j = i + 1; - double a = 1 - (index - i); - - - if( (j>= ld->nrays) || !ld->valid[i] || !ld->valid[j]) { - ld2->valid[k] = 0; - ld2->readings[k] = NAN; - ld2->alpha_valid[k] = 0; - ld2->alpha[k] = NAN; - ld2->theta[k] = ld->theta[i]; - } else { - ld2->theta[k] = a * ld->theta[i] + (1-a) * ld->theta[j]; - - - if(is_nan(ld2->theta[k])) { - sm_debug("Hey, k=%d theta[%d]=%f theta[%d]=%f\n", - k,i,ld->theta[i],j,ld->theta[j]); - } - - ld2->readings[k] = a * ld->readings[i] + (1-a) * ld->readings[j]; - ld2->valid[k] = 1; - } - -/* sm_debug("k=%d index=%f i=%d a=%f valid %d reading %f\n", k,index,i,a,ld2->valid[k],ld2->readings[k]);*/ - } - - ld2->min_theta = ld2->theta[0]; - ld2->max_theta = ld2->theta[n-1]; - ld2->tv = ld->tv; - - copy_d(ld->odometry, 3, ld2->odometry); - copy_d(ld->estimate, 3, ld2->estimate); - - - return ld2; -} - diff --git a/sm/apps/ld_select.c b/sm/apps/ld_select.c deleted file mode 100644 index bf6b9fa..0000000 --- a/sm/apps/ld_select.c +++ /dev/null @@ -1,4 +0,0 @@ - -int main() { - -} diff --git a/sm/apps/ld_slip.c b/sm/apps/ld_slip.c deleted file mode 100644 index 4b83482..0000000 --- a/sm/apps/ld_slip.c +++ /dev/null @@ -1,105 +0,0 @@ -#include <gsl/gsl_rng.h> -#include <gsl/gsl_randist.h> -#include <gsl/gsl_math.h> - -#include <math.h> -#include <options/options.h> - -#include "../csm/csm_all.h" - -struct ld_noise_params { - int seed; - - double sigma_xy; - double sigma_theta_deg; - - const char* file_input; - const char* file_output; - - int debug; -}; - -const char * banner = - "A simple program for adding slip to odometry \n\n" - "The 'odometry' field is set to 'true_pose' + noise.\n" - "If 'true_pose' is not available, then the 'odometry' \n" - "field is set to 'odometry' + noise.\n\n" - "Note: this program does *not* simulate the effect of \n" - "slip or odometry error in a realistic way; each scan \n" - "in the file is considered separately, the error does \n" - "not depend on the traveled distance, etc.\n\n"; - -int main(int argc, const char ** argv) { - sm_set_program_name(argv[0]); - - struct ld_noise_params p; - - options_banner(banner); - - struct option* ops = options_allocate(10); - options_double(ops, "sigma_theta_deg", &p.sigma_theta_deg, 0.0, - "Std deviation of gaussian noise for theta (deg) (disabled if 0)"); - options_double(ops, "sigma_xy", &p.sigma_xy, 0.0, - "Std deviation of gaussian noise for x,y (disabled if 0)"); - options_int(ops, "seed", &p.seed, 0, - "Seed for random number generator (if 0, use GSL_RNG_SEED env. variable)."); - options_string(ops, "in", &p.file_input, "stdin", "Input file "); - options_string(ops, "out", &p.file_output, "stdout", "Output file "); - - options_int(ops, "debug", &p.debug, 0, "Shows debug information"); - - - if(!options_parse_args(ops, argc, argv)) { - options_print_help(ops, stderr); - return -1; - } - - sm_debug_write(p.debug); - - gsl_rng_env_setup(); - gsl_rng * rng = gsl_rng_alloc (gsl_rng_ranlxs0); - if(p.seed != 0) - gsl_rng_set(rng, (unsigned int) p.seed); - - - FILE * in = open_file_for_reading(p.file_input); - if(!in) return -3; - - FILE * out = open_file_for_writing(p.file_output); - if(!out) return -2; - - LDP ld; int count=0; - while( (ld = ld_read_smart(in))) { - count++; - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - continue; - } - - if(!any_nan(ld->true_pose, 3)) - copy_d( (const double*) ld->true_pose, 3, ld->odometry); - - double e[3] = {0,0,0}; - - if(p.sigma_xy > 0) { - e[0] = gsl_ran_gaussian(rng, p.sigma_xy); - e[1] = gsl_ran_gaussian(rng, p.sigma_xy); - } - - if(p.sigma_theta_deg > 0) { - e[2] = gsl_ran_gaussian(rng, deg2rad(p.sigma_theta_deg)); - } - - ld->odometry[0] += e[0]; - ld->odometry[1] += e[1]; - ld->odometry[2] += e[2]; - - sm_debug("Adding noise %s.\n", friendly_pose(e)); - - ld_write_as_json(ld, out); - - ld_free(ld); - } - - return 0; -} diff --git a/sm/apps/ld_smooth.c b/sm/apps/ld_smooth.c deleted file mode 100644 index 348a7af..0000000 --- a/sm/apps/ld_smooth.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <options/options.h> - -#include "../csm/csm_all.h" - -struct { - /** Scale factor */ - double scale_deg; - - /** How many neighbours to consider */ - int neighbours; -} p; - -void ld_smooth(LDP ld, int neighbours, double scale_rad); -void convolve(const int*valid,const double*original, int n, double*dest, double*filter, int filter_len); - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - struct option* ops = options_allocate(3); - options_double(ops, "scale_deg", &p.scale_deg, 0.0, "Scale factor (degrees) "); - options_int(ops, "neighbours", &p.neighbours, 1, "How many neighbours to consider (regardless of scale)."); - - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "A simple program for smoothing a sensor scan.\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - int errors = 0; - int count = -1; - LDP ld; - while( (ld = ld_read_smart(stdin)) ) { - count++; - if(!ld_valid_fields(ld)) { - sm_error("Invalid laser data (#%d in file)\n", count); - errors++; - continue; - } - - ld_smooth(ld, p.neighbours, deg2rad(p.scale_deg) ); - - ld_write_as_json(ld, stdout); - - ld_free(ld); - } - - return errors; -} - -void convolve(const int*valid,const double*original, int n, double*dest, double*filter, int filter_len) -{ - int i; /* index on the points */ - int j; /* index on the filter */ - - for(i=0;i<n;i++) { - if(!valid[i]) { - dest[i] = GSL_NAN; - continue; - } - - dest[i] = 0; - for(j=-(filter_len-1);j<=(filter_len-1);j++) { - int i2 = i + j; - if(i2<0) i2=0; if(i2>=n) i2=n-1; - if(!valid[i2]) i2 = i; - dest[i] += original[i2] * filter[abs(j)]; - } - } -} - -void ld_smooth(LDP ld, int neighbours, double scale_rad) { - int len = neighbours + 1; - double filter[len]; - int j; - static int once = 1; - for(j=0;j<len;j++) { - double dist_rad = j * ((ld->max_theta-ld->min_theta)/ld->nrays); - double mahal = square(dist_rad / scale_rad); - filter[j] = exp(-mahal); - - if(once) - sm_info("filter[%d] = %f mahal = %f dist_rad = %f scale_rad = %f \n", j, filter[j], mahal, dist_rad, scale_rad); - - } - - once = 0; - - /* find total filter */ - double filter_tot = filter[0]; - for(j=1;j<len;j++) filter_tot+=filter[j]; - /* and normalize */ - for(j=0;j<len;j++) filter[j]/=filter_tot; - - double new_readings[ld->nrays]; - convolve(ld->valid, ld->readings, ld->nrays, new_readings, filter, len); - copy_d(new_readings, ld->nrays, ld->readings); - - for(j=0;j<len;j++) { - - } -} - - diff --git a/sm/apps/ld_stats.c b/sm/apps/ld_stats.c deleted file mode 100644 index e9979f0..0000000 --- a/sm/apps/ld_stats.c +++ /dev/null @@ -1,87 +0,0 @@ -#include <options/options.h> - -#include <csm/csm_all.h> - -int main(int argc, const char * argv[]) { - sm_set_program_name(argv[0]); - - const char*input_filename; - const char*output_filename; - double max_xy; - double max_theta_deg; - - struct option* ops = options_allocate(10); - options_string(ops, "in", &input_filename, "stdin", "input file (log)"); - options_string(ops, "out", &output_filename, "stdout", "output file "); - options_double(ops, "max_xy", &max_xy, 100.0, "Max admissible xy displacement"); - options_double(ops, "max_theta_deg", &max_theta_deg, 360.0, - "Max admissible theta displacement (deg)"); - - if(!options_parse_args(ops, argc, argv)) { - sm_info("computes odometry statistics.\n\nOptions:\n"); - options_print_help(ops, stderr); - return -1; - } - - FILE * input_stream = open_file_for_reading(input_filename); - FILE *output_stream = open_file_for_writing(output_filename); - - if(!input_stream || !output_stream) return -1; - - LDP laser_ref = ld_read_smart(input_stream); - if(!laser_ref) { - sm_error("Cannot read first scan.\n."); - return -2; - } - - int count = 0, valid = 0; - LDP laser_sens; - - double avg_correction[3] = {0,0,0}; - double max_correction[3] = {0,0,0}; - while((laser_sens = ld_read_smart(input_stream))) { - double diff_true_pose[3], diff_odometry[3], diff_estimate[3]; - pose_diff_d(laser_sens->odometry, laser_ref->odometry, diff_odometry); - pose_diff_d(laser_sens->true_pose, laser_ref->true_pose, diff_true_pose); - pose_diff_d(laser_sens->estimate, laser_ref->estimate, diff_estimate); - double diff[3]; - pose_diff_d(diff_estimate, diff_odometry, diff); - - JO jo = jo_new(); - jo_add_double_array(jo, "diff_odometry", diff_odometry, 3); - jo_add_double_array(jo, "diff_true_pose", diff_true_pose, 3); - jo_add_double_array(jo, "diff_estimate", diff_estimate, 3); - jo_add_double_array(jo, "correction", diff, 3); - - fputs(jo_to_string(jo), output_stream); - fputs("\n", output_stream); - jo_free(jo); - ld_free(laser_ref); - laser_ref = laser_sens; - - int use_it = (fabs(diff[0]) < max_xy) && (fabs(diff[1]) < max_xy) && - (fabs(diff[2]) < deg2rad(max_theta_deg)); - - if(use_it) { - int i; for(i=0;i<3;i++) { - avg_correction[i] += diff[i]; - max_correction[i] = GSL_MAX(max_correction[i], fabs(diff[i])); - } - valid ++; - } - - count ++; - } - - int i; for(i=0;i<3;i++) - avg_correction[i] /= valid; - - fprintf(stderr, "Used %d/%d rays (%.1f %%)\n", valid, count, (100.0 *valid)/count); - - fprintf(stderr, "Avg: %f %f %f = %fdeg \n", - avg_correction[0], avg_correction[1], avg_correction[2], rad2deg(avg_correction[2])); - fprintf(stderr, "Max: %f %f %f = %fdeg \n", - max_correction[0], max_correction[1], max_correction[2], rad2deg(max_correction[2])); - - return 0; -} diff --git a/sm/apps/log2pdf.c b/sm/apps/log2pdf.c deleted file mode 100644 index c5ce454..0000000 --- a/sm/apps/log2pdf.c +++ /dev/null @@ -1,196 +0,0 @@ -#include <time.h> -#include <string.h> - - -#ifdef LINUX -#include <linux/limits.h> -#endif - -#include <cairo.h> -#include <cairo-pdf.h> - -#include <options/options.h> - -#include "../csm/csm_all.h" -#include "../csm/laser_data_drawing.h" -#include "../csm/laser_data_cairo.h" - - -typedef struct { - const char*use; - double padding; - double dimension; - - int draw_confidence; - double confidence_mult; - - const char*output_filename; - const char*input_filename; - - ld_reference use_reference; - - double offset_theta_deg; - - /* Drawing style for scans */ - ld_style laser; - /* Drawing style for robot path */ - line_style pose_path; - double start_pose_width; - - double distance_xy, distance_th_deg; -} log2pdf_params; - -int log2pdf(log2pdf_params *p); - -double offset_theta = 0; - -const char* banner = - "This program draws laser scans.\n" - "\n" - "IMPORTANT: it is likely you have to set one or more parameters. \n" - " the default parameters are OK to draw very long laser logs\n\n"; - -int main(int argc, const char* argv[]) { - sm_set_program_name(argv[0]); - - log2pdf_params p; - - lds_set_defaults(&(p.laser)); - ls_set_defaults(&(p.pose_path)); - - p.laser.rays.draw = 0; - p.laser.points.draw = 0; - p.laser.normals.draw = 0; - p.laser.countour.width = 0.1; - p.pose_path.width = 0.1; - p.pose_path.color = "#f00"; - - options_banner(banner); - struct option * ops = options_allocate(100); - options_string(ops, "in", &p.input_filename, "stdin", "input file (Carmen or JSON)"); - options_string(ops, "out", &p.output_filename, "", "output file (if empty, input file + '.pdf')"); - options_double(ops, "padding", &p.padding, 0.2, "padding around bounding box (m)"); - options_double(ops, "dimension", &p.dimension, 500.0, "dimension of the image (points)"); - options_double(ops, "offset_theta_deg", &p.offset_theta_deg, 0.0, " rotate entire map by this angle (deg) "); - - options_string(ops, "use", &p.use, "estimate", "One in 'odometry','estimate','true_pose'"); - options_double(ops, "distance_xy", &p.distance_xy, 5.0, " Minimum distance between scans (m) "); - options_double(ops, "distance_th_deg", &p.distance_th_deg, 45.0, " Minimum distance between scans (deg) "); - options_double(ops, "start_pose_width", &p.start_pose_width, 0.4, "First pose | Circle width"); - lds_add_options(&(p.laser), ops, "laser_", ""); - ls_add_options(&(p.pose_path), ops, "path_", ""); - - if(!options_parse_args(ops, argc, argv)) { - sm_error("Could not parse arguments.\n"); - options_print_help(ops, stderr); - return -1; - } - - /* If out not specified */ - if(strlen(p.output_filename)==0) { - char buf[PATH_MAX]; - sprintf(buf, "%s.pdf", p.input_filename); - p.output_filename = my_strdup(buf); -/* sm_info("Writing on file '%s'.\n", p.output_filename);*/ - } - - p.use_reference = ld_string_to_reference(p.use); - if(Invalid == p.use_reference) { - sm_error("Invalid reference '%s'. " - "Use one in 'odometry','estimate','true_pose'.\n", p.use); - return -1; - } -/* sm_info("Using reference: %s.\n", ld_reference_to_string(p.use_reference));*/ - - return !log2pdf(&p); -} - - -int log2pdf(log2pdf_params *p) { - - /** First of all, we read the entire map into memory */ - FILE *input_file = open_file_for_reading(p->input_filename); - if(!input_file) return 0; - - LDP*scans; int nscans; - - if(!ld_read_some_scans_distance(input_file, &scans, &nscans, - p->use_reference, p->distance_xy, deg2rad(p->distance_th_deg) ) ){ - sm_error("Could not read map from file '%s'.\n", p->input_filename); - return 0; - } - - if(nscans == 0) { - sm_error("I could not read any scan from file '%s'.\n", p->input_filename); - return 0; - } - - sm_debug("Read map: %d scans in total.\n", nscans); - - /** Let's find the bounding box for the map */ - double bb_min[2], bb_max[2]; - double offset[3] = {0,0,0}; - lda_get_bounding_box(scans, nscans, bb_min, bb_max, offset, p->use_reference, p->laser.horizon); - - bb_min[0] -= p->padding; - bb_min[1] -= p->padding; - bb_max[0] += p->padding; - bb_max[1] += p->padding; - - - sm_debug("Bounding box: %f %f -- %f %f.\n", bb_min[0], bb_min[1], - bb_max[0], bb_max[1]); - - - /* Create PDF surface and setup paper size and transformations */ - int max_width_points = p->dimension; - int max_height_points = p->dimension; - cairo_surface_t *surface; - cairo_t *cr; - - if(!create_pdf_surface(p->output_filename, max_width_points, max_height_points, - bb_min, bb_max, &surface, &cr)) return 0; - - /* Draw pose path */ - if(p->pose_path.draw) { - cairo_save(cr); - - cr_set_style(cr, &(p->pose_path)); - cr_lda_draw_pose_path(cr, scans, nscans, p->use_reference); - - if(nscans > 0 && p->laser.pose.draw) { - cairo_set_source_rgb(cr, 0.3, 0.0, 1.0); - double *pose0 = ld_get_reference_pose(scans[0], p->use_reference); - cairo_arc(cr, pose0[0], pose0[1], p->start_pose_width, 0.0, 2*M_PI); - cairo_fill(cr); - } - - cairo_restore(cr); - } - - /* Draw map */ - int k; for(k=0;k<nscans;k++) { - LDP ld = scans[k]; - double *pose = ld_get_reference_pose(ld, p->use_reference); - if(!pose) continue; - - double offset[3] = {0,0, deg2rad(p->offset_theta_deg) }; - double world_pose[3]; - oplus_d(offset, pose, world_pose); - - cairo_save(cr); - cr_set_reference(cr, world_pose); - cr_ld_draw(cr, ld, &(p->laser)); - cairo_restore(cr); - } - - cairo_show_page (cr); - - cairo_destroy (cr); - cairo_surface_destroy (surface); - return 1; -} - - - - diff --git a/sm/apps/map/CMakeLists.txt b/sm/apps/map/CMakeLists.txt deleted file mode 100644 index cde2600..0000000 --- a/sm/apps/map/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 2.4) - -project(map) - - -find_package(PkgConfig REQUIRED) -pkg_check_modules(CSM REQUIRED csm) - -IF(${CSM_FOUND}) - MESSAGE("CSM_LIBRARY_DIRS: ${CSM_LIBRARY_DIRS}") - MESSAGE("CSM_LIBRARIES: ${CSM_LIBRARIES}") - MESSAGE("CSM_INCLUDE_DIRS: ${CSM_INCLUDE_DIRS}") - - INCLUDE_DIRECTORIES(${CSM_INCLUDE_DIRS}) - LINK_DIRECTORIES(${CSM_LIBRARY_DIRS}) - -ELSE(${CSM_FOUND}) - MESSAGE(FATAL_ERROR "CSM not found. Check that the environment variable PKG_CONFIG_PATH includes the path containing the file 'csm.pc'.") -ENDIF(${CSM_FOUND}) - - - -set(map1_SRCS - map1.cpp -) - - -add_executable(map1 ${map1_SRCS}) - -target_link_libraries(map1 ${CSM_LIBRARIES}) - diff --git a/sm/apps/map/many_points.config b/sm/apps/map/many_points.config deleted file mode 100644 index 1dbb2f2..0000000 --- a/sm/apps/map/many_points.config +++ /dev/null @@ -1,9 +0,0 @@ -laser_countour_draw 1 -laser_countour_width 0.002 - -path_width 0.002 - -distance_xy 0.05 -distance_th_deg 5 - -laser_pose_draw 0 diff --git a/sm/apps/map/map1.cpp b/sm/apps/map/map1.cpp deleted file mode 100644 index 9d52b2f..0000000 --- a/sm/apps/map/map1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include <string.h> -#include "pan.h" -#include <options/options.h> - -struct myparams { - const char * file_in; - const char * file_out; - const char * file_out_stats; - const char * file_jj; - int format; - - /* which algorithm to run */ - int algo; -} p; - -extern "C" void sm_options(struct sm_params*p, struct option*ops); - - -int main(int argc, const char*argv[]) { - sm_set_program_name(argv[0]); - - struct sm_params params; - struct sm_result result; - - struct option* ops = options_allocate(100); - options_string(ops, "in", &p.file_in, "stdin", "Input file "); - options_string(ops, "out", &p.file_out, "stdout", "Output file "); - options_string(ops, "out_stats", &p.file_out_stats, "", "Output file (stats) "); - options_string(ops, "file_jj", &p.file_jj, "", - "File for journaling -- if left empty, journal not open."); - options_int(ops, "algo", &p.algo, 0, "Which algorithm to use (0:icp 1:gpm-stripped) "); - p.format = 0; -/* options_int(ops, "format", &p.format, 0, - "Output format (0: log in JSON format, 1: log in Carmen format (not implemented))");*/ - - sm_options(¶ms, ops); - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - /* Open input and output files */ - - FILE * file_in = open_file_for_reading(p.file_in); - if(!file_in) return -1; - FILE * file_out = open_file_for_writing(p.file_out); - if(!file_out) return -1; - - if(strcmp(p.file_jj, "")) { - FILE * jj = open_file_for_writing(p.file_jj); - if(!jj) return -1; - jj_set_stream(jj); - } - - FILE * file_out_stats = 0; - if(strcmp(p.file_out_stats, "")) { - file_out_stats = open_file_for_writing(p.file_out_stats); - if(!file_out_stats) return -1; - } - - /* Read first scan */ - LDP laser_ref; - if(!(laser_ref = ld_read_smart(file_in))) { - sm_error("Could not read first scan.\n"); - return -1; - } - if(!ld_valid_fields(laser_ref)) { - sm_error("Invalid laser data in first scan.\n"); - return -2; - } - - - /* For the first scan, set estimate = odometry */ - copy_d(laser_ref->odometry, 3, laser_ref->estimate); - - ld_write_as_json(laser_ref, file_out); - int count=-1; - LDP laser_sens; - while( (laser_sens = ld_read_smart(file_in)) ) { - count++; - if(!ld_valid_fields(laser_sens)) { - sm_error("Invalid laser data in (#%d in file).\n", count); - return -(count+2); - } - - params.laser_ref = laser_ref; - params.laser_sens = laser_sens; - - /* Set first guess as the difference in odometry */ - double odometry[3]; - pose_diff_d(laser_sens->odometry, laser_ref->odometry, odometry); - double ominus_laser[3], temp[3]; - ominus_d(params.laser, ominus_laser); - oplus_d(ominus_laser, odometry, temp); - oplus_d(temp, params.laser, params.first_guess); - - /* Do the actual work */ - switch(p.algo) { - case(0): - sm_icp(¶ms, &result); break; - case(1): - sm_gpm(¶ms, &result); break; - default: - sm_error("Unknown algorithm to run: %d.\n",p.algo); - return -1; - } - - /* Add the result to the previous estimate */ - oplus_d(laser_ref->estimate, result.x, laser_sens->estimate); - - /* Write the corrected log */ - ld_write_as_json(laser_sens, file_out); - - /* Write the statistics (if required) */ - if(file_out_stats) { - JO jo = result_to_json(¶ms, &result); - fputs(jo_to_string(jo), file_out_stats); - fputs("\n", file_out_stats); - jo_free(jo); - } - - ld_free(laser_ref); laser_ref = laser_sens; - } - ld_free(laser_ref); - - return 0; -} diff --git a/sm/apps/map/pan.cpp b/sm/apps/map/pan.cpp deleted file mode 100644 index a5a00a7..0000000 --- a/sm/apps/map/pan.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "pan.h" - -LDP pan_new(int nrays) { - -} - -void pan_merge(LDP pan, LDP ld) { - -} - diff --git a/sm/apps/map/pan.h b/sm/apps/map/pan.h deleted file mode 100644 index e398e78..0000000 --- a/sm/apps/map/pan.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef H_MAP_PAN -#define H_MAP_PAN - -#include <csm/csm_all.h> - -using namespace CSM; - -struct merge_params { - -}; - - -LDP pan_new(int nrays); - -void pan_merge(LDP pan, LDP ld); - - - -#endif diff --git a/sm/apps/map/test_01.sh b/sm/apps/map/test_01.sh deleted file mode 100755 index 981a93d..0000000 --- a/sm/apps/map/test_01.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -head -n 100 k15l.log | ./map1 > out.log -log2pdf -config many_points.config -distance_xy 0 -in out.log - \ No newline at end of file diff --git a/sm/apps/qtv/CMakeLists.txt b/sm/apps/qtv/CMakeLists.txt deleted file mode 100644 index e81e127..0000000 --- a/sm/apps/qtv/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -project(qtv) - -macro(join ret list) - SET(res "") - FOREACH(e ${list}) - SET(res "${res} ${e}") - ENDFOREACH(e ${list}) - SET(${ret} ${res}) -endmacro(join list) - - -set(QT_USE_QTOPENGL 1) -find_package(Qt4 REQUIRED) - -find_package(PkgConfig REQUIRED) -pkg_check_modules(CSM REQUIRED csm) - -#join(CSM_LDFLAGS "${CSM_LDFLAGS}") -join(CSM_CFLAGS "${CSM_CFLAGS}") - -MESSAGE("CSM_CFLAGS: ${CSM_CFLAGS}") -MESSAGE("CSM_LDFLAGS: ${CSM_LDFLAGS}") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CSM_CFLAGS}") -SET(LDFLAGS ${CSM_LDFLAGS}) - - -include(${QT_USE_FILE}) - -# the variable "qtproject_SRCS" contains all .cpp files of this project -set(qtv_SRCS - qtv.cpp - mouse.cpp - qlaserdata.cpp - qfilereader.cpp - qparser.cpp - qscene.cpp - qmapview.cpp -) - -qt4_automoc(${qtv_SRCS}) - -add_executable(qtv ${qtv_SRCS}) - -target_link_libraries(qtv ${QT_LIBRARIES}) -target_link_libraries(qtv ${CSM_LDFLAGS}) - diff --git a/sm/apps/qtv/design.txt b/sm/apps/qtv/design.txt deleted file mode 100644 index df9059a..0000000 --- a/sm/apps/qtv/design.txt +++ /dev/null @@ -1,68 +0,0 @@ - - -Modalità --------- - -1) Singolo visore - - Visualizza l'ultimo laserdata. - -2) Visore continuo. - - Ogni laserdata ha un ID. Se l'ID si ripresenta, si aggiorna. - Ogni laserdata ricorda la storia (opzionale) - - -Tipi di dato ------------- - -0) Comandi - CLEAR cancella tutto - -Oggetti: -1) Laserdata -2) Punti grafo -3) Connessioni grafo (either tra laserdata o punti grafo) -4) Labels - text - x,y,theta - min_zoom Visibile solo sotto una certa distanza - -5) Log - messaggio di log - -Campi comuni: - text - -Grafica: - color - -Parametri ---------- - -follow_last Segui l'ultimo scan -follow_zoom Ampiezza per seguire -follow_smooth Smoothness per seguire - - -Multiple viewpoints -------------------- - - - -Architettura -------------- -- Widgets -- Containers - - log - - graphics scene -- Parser/demux: trasla stringhe/json in oggetti -- Input threads (stdin, file, tcp) - - - - - - - - diff --git a/sm/apps/qtv/main.cpp b/sm/apps/qtv/main.cpp deleted file mode 100644 index 873e0e7..0000000 --- a/sm/apps/qtv/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "mouse.h" - -#include <QtGui> - -#include <math.h> - -static const int MouseCount = 7; - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - - QGraphicsScene scene; - scene.setSceneRect(-300, -300, 600, 600); - scene.setItemIndexMethod(QGraphicsScene::NoIndex); - - for (int i = 0; i < MouseCount; ++i) { - Mouse *mouse = new Mouse; - mouse->setPos(::sin((i * 6.28) / MouseCount) * 200, - ::cos((i * 6.28) / MouseCount) * 200); - scene.addItem(mouse); - } - - QGraphicsView view(&scene); - view.setRenderHint(QPainter::Antialiasing); - view.setBackgroundBrush(QPixmap(":/images/cheese.jpg")); - view.setCacheMode(QGraphicsView::CacheBackground); - view.setDragMode(QGraphicsView::ScrollHandDrag); - view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice")); - view.resize(400, 300); - view.show(); - - return app.exec(); -} diff --git a/sm/apps/qtv/mouse.cpp b/sm/apps/qtv/mouse.cpp deleted file mode 100644 index 4fc49cb..0000000 --- a/sm/apps/qtv/mouse.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "mouse.h" - -#include "mouse.moc" - -#include <QGraphicsScene> -#include <QPainter> -#include <QStyleOption> - -#include <math.h> - -static const double Pi = 3.14159265358979323846264338327950288419717; -static double TwoPi = 2.0 * Pi; - -static qreal normalizeAngle(qreal angle) -{ - while (angle < 0) - angle += TwoPi; - while (angle > TwoPi) - angle -= TwoPi; - return angle; -} - -Mouse::Mouse() - : angle(0), speed(0), mouseEyeDirection(0), - color(qrand() % 256, qrand() % 256, qrand() % 256) -{ - rotate(qrand() % (360 * 16)); - startTimer(1000 / 33); -} - -QRectF Mouse::boundingRect() const -{ - qreal adjust = 0.5; - return QRectF(-18 - adjust, -22 - adjust, - 36 + adjust, 60 + adjust); -} - -QPainterPath Mouse::shape() const -{ - QPainterPath path; - path.addRect(-10, -20, 20, 40); - return path; -} - -void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - // Body - painter->setBrush(color); - painter->drawEllipse(-10, -20, 20, 40); - - // Eyes - painter->setBrush(Qt::white); - painter->drawEllipse(-10, -17, 8, 8); - painter->drawEllipse(2, -17, 8, 8); - - // Nose - painter->setBrush(Qt::black); - painter->drawEllipse(QRectF(-2, -22, 4, 4)); - - // Pupils - painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4)); - painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4)); - - // Ears - painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red); - painter->drawEllipse(-17, -12, 16, 16); - painter->drawEllipse(1, -12, 16, 16); - - // Tail - QPainterPath path(QPointF(0, 20)); - path.cubicTo(-5, 22, -5, 22, 0, 25); - path.cubicTo(5, 27, 5, 32, 0, 30); - path.cubicTo(-5, 32, -5, 42, 0, 35); - painter->setBrush(Qt::NoBrush); - painter->drawPath(path); -} - -void Mouse::timerEvent(QTimerEvent *) -{ - // Don't move too far away - QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0)); - if (lineToCenter.length() > 150) { - qreal angleToCenter = ::acos(lineToCenter.dx() / lineToCenter.length()); - if (lineToCenter.dy() < 0) - angleToCenter = TwoPi - angleToCenter; - angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2); - - if (angleToCenter < Pi && angleToCenter > Pi / 4) { - // Rotate left - angle += (angle < -Pi / 2) ? 0.25 : -0.25; - } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) { - // Rotate right - angle += (angle < Pi / 2) ? 0.25 : -0.25; - } - } else if (::sin(angle) < 0) { - angle += 0.25; - } else if (::sin(angle) > 0) { - angle -= 0.25; - } - - // Try not to crash with any other mice - QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF() - << mapToScene(0, 0) - << mapToScene(-30, -50) - << mapToScene(30, -50)); - foreach (QGraphicsItem *item, dangerMice) { - if (item == this) - continue; - - QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0)); - qreal angleToMouse = ::acos(lineToMouse.dx() / lineToMouse.length()); - if (lineToMouse.dy() < 0) - angleToMouse = TwoPi - angleToMouse; - angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2); - - if (angleToMouse >= 0 && angleToMouse < Pi / 2) { - // Rotate right - angle += 0.5; - } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) { - // Rotate left - angle -= 0.5; - } - } - - // Add some random movement - if (dangerMice.size() > 1 && (qrand() % 10) == 0) { - if (qrand() % 1) - angle += (qrand() % 100) / 500.0; - else - angle -= (qrand() % 100) / 500.0; - } - - speed += (-50 + qrand() % 100) / 100.0; - - qreal dx = ::sin(angle) * 10; - mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5; - - rotate(dx); - setPos(mapToParent(0, -(3 + sin(speed) * 3))); -} diff --git a/sm/apps/qtv/mouse.h b/sm/apps/qtv/mouse.h deleted file mode 100644 index 948c644..0000000 --- a/sm/apps/qtv/mouse.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef MOUSE_H -#define MOUSE_H - -#include <QGraphicsItem> -#include <QObject> - -class Mouse : public QObject, public QGraphicsItem -{ - Q_OBJECT - -public: - Mouse(); - - QRectF boundingRect() const; - QPainterPath shape() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - -protected: - void timerEvent(QTimerEvent *event); - -private: - qreal angle; - qreal speed; - qreal mouseEyeDirection; - QColor color; -}; - -#endif diff --git a/sm/apps/qtv/qfilereader.cpp b/sm/apps/qtv/qfilereader.cpp deleted file mode 100644 index 6e6dd6b..0000000 --- a/sm/apps/qtv/qfilereader.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "qfilereader.h" -#include "qfilereader.moc" - -QFileReader::QFileReader(QIODevice * source) : - source(source) { - -} - -void QFileReader::run() { - printf("Running\n"); - - while(1) { - char buf[10024]; - qint64 lineLength = source->readLine(buf, sizeof(buf)); - if (lineLength == -1) break; - emit new_line(QString(buf)); - -/* source->waitForBytesWritten(-1); - if(source->canReadLine()) { - printf("can\n"); - QByteArray data = source->readLine(); - emit new_line(QString(data)); - } else { - printf("."); - }*/ - } - - emit eof(); -} - diff --git a/sm/apps/qtv/qfilereader.h b/sm/apps/qtv/qfilereader.h deleted file mode 100644 index c2936ee..0000000 --- a/sm/apps/qtv/qfilereader.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef QFILEREADER_H -#define QFILEREADER_H - -#include <QThread> -#include <QIODevice> - -class QFileReader : public QThread -{ - Q_OBJECT - - QIODevice * source; - -public: - QFileReader(QIODevice * source); - void run(); - -signals: - void new_line(QString); - void eof(); -}; - -#endif diff --git a/sm/apps/qtv/qlaserdata.cpp b/sm/apps/qtv/qlaserdata.cpp deleted file mode 100644 index ee6d94c..0000000 --- a/sm/apps/qtv/qlaserdata.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include <QGraphicsScene> -#include <QPainter> -#include <QStyleOption> - -#include "qlaserdata.h" -#include "qlaserdata.moc" - - -QLaserData::QLaserData(LDP ld): ld(ld) -{ - this->countour = createCountour(); - double *p = ld->estimate; - setPos(QPointF(p[0],p[1])); - rotate(CSM::rad2deg(p[2])); -} - -QRectF QLaserData::boundingRect() const -{ - return countour.boundingRect(); -} - -QPainterPath QLaserData::shape() const -{ - return countour; -} - -QPainterPath QLaserData::createCountour() { - ld_compute_cartesian(ld); - struct stroke_sequence sequence[ld->nrays]; - compute_stroke_sequence(ld, sequence, 100, 0.1); - - QPainterPath path; - for(int i=0;i<ld->nrays;i++) { - if(sequence[i].valid==0) continue; - double *p = sequence[i].p; - if(sequence[i].begin_new_stroke) - path.moveTo(p[0], p[1]); - else - path.lineTo(p[0], p[1]); - } - return path; -} - -void QLaserData::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - // Body -// painter->setBrush(color); -/* painter->drawEllipse(-10, -20, 20, 40); - - // Eyes - painter->setBrush(Qt::white); - painter->drawEllipse(-10, -17, 8, 8); - painter->drawEllipse(2, -17, 8, 8); - - // Nose - painter->setBrush(Qt::black); - painter->drawEllipse(QRectF(-2, -22, 4, 4)); - - - // Ears - painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red); - painter->drawEllipse(-17, -12, 16, 16); - painter->drawEllipse(1, -12, 16, 16); -*/ - // Tail - painter->setPen(Qt::black); - painter->setBrush(Qt::NoBrush); -/* painter->setBrush(Qt::red);*/ - painter->drawPath(countour); -} - -void QLaserData::timerEvent(QTimerEvent *) -{ - - // rotate(dx); -// setPos(mapToParent(0, -(3 + sin(speed) * 3))); -} diff --git a/sm/apps/qtv/qlaserdata.h b/sm/apps/qtv/qlaserdata.h deleted file mode 100644 index fc71aa3..0000000 --- a/sm/apps/qtv/qlaserdata.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef QLASERDATA_H -#define QLASERDATA_H - -#include "qtv.h" - -class QLaserData : public QObject, public QGraphicsItem -{ - Q_OBJECT - -public: - QLaserData(LDP ld); - - QPainterPath createCountour(); - - QRectF boundingRect() const; - QPainterPath shape() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - -protected: - void timerEvent(QTimerEvent *event); - -private: - LDP ld; - QPainterPath countour; -}; - -#endif diff --git a/sm/apps/qtv/qmapview.cpp b/sm/apps/qtv/qmapview.cpp deleted file mode 100644 index dddf653..0000000 --- a/sm/apps/qtv/qmapview.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "qmapview.h" -#include "qmapview.moc" - - -#include <QDebug> -#include <QGraphicsScene> -#include <QWheelEvent> - -#include <math.h> - -QMapView::QMapView() -{ - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); - - setCacheMode(CacheBackground); - setRenderHint(QPainter::Antialiasing); - setTransformationAnchor(AnchorUnderMouse); - setResizeAnchor(AnchorViewCenter); - - scale(0.8, 0.8); - setMinimumSize(400, 400); - setWindowTitle(tr("QMapView")); -} - -void QMapView::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Up: - break; - case Qt::Key_Down: - break; - case Qt::Key_Left: - break; - case Qt::Key_Right: - break; - case Qt::Key_Plus: - scaleView(1.2); - break; - case Qt::Key_Minus: - scaleView(1 / 1.2); - break; - case Qt::Key_Space: - default: - QGraphicsView::keyPressEvent(event); - } -} - - -void QMapView::wheelEvent(QWheelEvent *event) -{ - scaleView(pow((double)2, -event->delta() / 240.0)); -} - - -void QMapView::scaleView(qreal scaleFactor) -{ - qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); - if (factor < 0.07 || factor > 100) - return; - - scale(scaleFactor, scaleFactor); -} diff --git a/sm/apps/qtv/qmapview.h b/sm/apps/qtv/qmapview.h deleted file mode 100644 index 5f22f3d..0000000 --- a/sm/apps/qtv/qmapview.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GRAPHWIDGET_H -#define GRAPHWIDGET_H - - -#include <QtGui/QGraphicsView> - -#include <QtOpenGL/QtOpenGL> - - -class QMapView : public QGraphicsView -{ - Q_OBJECT - -public: - QMapView(); - -protected: - void keyPressEvent(QKeyEvent *event); - void wheelEvent(QWheelEvent *event); - void scaleView(qreal scaleFactor); - -}; - -#endif diff --git a/sm/apps/qtv/qparser.cpp b/sm/apps/qtv/qparser.cpp deleted file mode 100644 index dee450f..0000000 --- a/sm/apps/qtv/qparser.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "qparser.h" -#include "qparser.moc" - -void QParser::new_line(QString qqs) { - const char * s = strdup(qqs.toAscii().constData()); - LDP ld = ld_read_smart_string(s); - if(ld) { - emit parsed_laser_data(ld); - } -} - diff --git a/sm/apps/qtv/qparser.h b/sm/apps/qtv/qparser.h deleted file mode 100644 index ce943e5..0000000 --- a/sm/apps/qtv/qparser.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef QPARSER_H -#define QPARSER_H - -#include "qtv.h" - -class QParser : public QObject -{ - Q_OBJECT - -public: - -signals: - void parsed_laser_data(LDP ld); - -public slots: - - void new_line(QString); - - -}; - -#endif diff --git a/sm/apps/qtv/qscene.cpp b/sm/apps/qtv/qscene.cpp deleted file mode 100644 index 9689846..0000000 --- a/sm/apps/qtv/qscene.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "qscene.h" -#include "qscene.moc" - -#include "qlaserdata.h" - -QScene::QScene() { - setSceneRect(-20, -20, 20, 20); - setItemIndexMethod(QGraphicsScene::NoIndex); -} - - -void QScene::new_laser_data(LDP ld) { - addItem(new QLaserData(ld)); -} - -void QScene::adjust() { - setSceneRect(itemsBoundingRect()); -} - - diff --git a/sm/apps/qtv/qscene.h b/sm/apps/qtv/qscene.h deleted file mode 100644 index 8f0c501..0000000 --- a/sm/apps/qtv/qscene.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef QSCENE_H -#define QSCENE_H - -#include "qtv.h" - -class QScene : public QGraphicsScene -{ - Q_OBJECT - - -public: - QScene(); - -signals: - - -public slots: - - void new_laser_data(LDP); - void adjust(); - -}; - -#endif diff --git a/sm/apps/qtv/qtv.cpp b/sm/apps/qtv/qtv.cpp deleted file mode 100644 index b68c876..0000000 --- a/sm/apps/qtv/qtv.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "qtv.h" - -int main(int argc, char*argv[]) { - - QApplication app(argc, argv); - - QFile *qin = new QFile(); - if(!qin->open(stdin, QIODevice::ReadOnly)) { - printf("Could not open stding as QFile.\n"); - exit(1); - } - QFileReader *qfr = new QFileReader(qin); - QParser *qp = new QParser; - - QScene * qscene = new QScene(); - - QObject::connect(qfr, SIGNAL(new_line(QString)), qp, SLOT(new_line(QString))); - QObject::connect(qfr, SIGNAL(eof()), qscene, SLOT(adjust())); - - QObject::connect(qp, SIGNAL(parsed_laser_data(LDP)), qscene, SLOT(new_laser_data(LDP))); - - - QMapView view; - view.setScene(qscene); - view.setCacheMode(QGraphicsView::CacheBackground); - view.setDragMode(QGraphicsView::ScrollHandDrag); - view.scale(10,10); - view.show(); - qfr->start(); - - return app.exec(); -} \ No newline at end of file diff --git a/sm/apps/qtv/qtv.h b/sm/apps/qtv/qtv.h deleted file mode 100644 index 3da4317..0000000 --- a/sm/apps/qtv/qtv.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef H_QTV -#define H_QTV - -#include <iostream> - -#include <QtGui> -#include <QThread> -#include <QIODevice> - -#include <csm/csm.h> -#include <csm/csm_all.h> -using namespace CSM; - -#include "qfilereader.h" -#include "qparser.h" -#include "qscene.h" -#include "qmapview.h" - -using namespace std; - -#endif - diff --git a/sm/apps/raytracer/CMakeLists.txt b/sm/apps/raytracer/CMakeLists.txt deleted file mode 100644 index 5fdfbcc..0000000 --- a/sm/apps/raytracer/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 2.4) - -project(raytracer) - - -find_package(PkgConfig REQUIRED) -pkg_check_modules(CSM REQUIRED csm) - -IF(${CSM_FOUND}) - MESSAGE("CSM_LIBRARY_DIRS: ${CSM_LIBRARY_DIRS}") - MESSAGE("CSM_LIBRARIES: ${CSM_LIBRARIES}") - MESSAGE("CSM_INCLUDE_DIRS: ${CSM_INCLUDE_DIRS}") - - INCLUDE_DIRECTORIES(${CSM_INCLUDE_DIRS}) - LINK_DIRECTORIES(${CSM_LIBRARY_DIRS}) - -ELSE(${CSM_FOUND}) - MESSAGE(FATAL_ERROR "CSM not found. Check that the environment variable PKG_CONFIG_PATH includes the path containing the file 'csm.pc'.") -ENDIF(${CSM_FOUND}) - - -set(raytracer_SRCS - raytracer.cpp - simplemap.cpp -) - - -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -Wall") - -add_executable(raytracer ${raytracer_SRCS}) - -target_link_libraries(raytracer ${CSM_LIBRARIES}) - diff --git a/sm/apps/raytracer/raytracer.cpp b/sm/apps/raytracer/raytracer.cpp deleted file mode 100644 index 745b25a..0000000 --- a/sm/apps/raytracer/raytracer.cpp +++ /dev/null @@ -1,197 +0,0 @@ -#include "raytracer.h" - -struct raytracer_params { - const char * file_map; - const char * file_poses; - const char * file_output; - double fov_deg; - int nrays; - double max_reading; -}; - - -bool load_env_from_json(Environment& env, JO jo); -double cosine_between_angles(double a1, double a2); - - -int main(int argc, const char** argv) -{ - sm_set_program_name(argv[0]); - struct raytracer_params p; - - struct option* ops = options_allocate(60); - options_string(ops, "map", &p.file_map, "map.json", "Environment description"); - options_string(ops, "poses", &p.file_poses, "-", "List of poses"); - options_string(ops, "out", &p.file_output, "stdout", "Output file "); - options_int(ops, "nrays", &p.nrays, 181, "Number of rays"); - options_double(ops, "fov_deg", &p.fov_deg, 180.0, "Field of view (degrees)"); - options_double(ops, "max_reading", &p.max_reading, 80.0, "Sensor horizon (meters)"); - - if(!options_parse_args(ops, argc, argv)) { - sm_info(" simulats one scan from map. \n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - - FILE * file_map = open_file_for_reading(p.file_map); - if(!file_map) return -2; - - JO jo_map = json_read_stream(file_map); - if(!jo_map) { - sm_error("Could not read JSON from file '%s'\n", p.file_map); - return -3; - } - if(json_read_stream(file_map)) { - sm_error("I expect only 1 JSON object in file '%s'\n", p.file_map); - return -4; - } - - Environment env; - - load_env_from_json(env, jo_map); - - - FILE * file_output = open_file_for_writing(p.file_output); - if(!file_output) return -1; - - - FILE * file_poses = open_file_for_reading(p.file_poses); - if(!file_poses) return -2; - - JO jo_pose; int num = 0; - while( (jo_pose = json_read_stream(file_poses)) ) - { - num++; - - LDP ld = ld_alloc_new(p.nrays); - - if(!jo_read_from_double_array (jo_pose, ld->true_pose, 3, GSL_NAN) || any_nan(ld->true_pose, 3)) { - sm_error("Bad pose: '%s'.\n", jo_to_string(jo_pose)); - return -5; - } - - - double fov = deg2rad(p.fov_deg); - - ld->min_theta = -fov/2; - ld->max_theta = +fov/2; - - for(int i=0;i<ld->nrays;i++) { - ld->theta[i] = - fov/2 + fov * i / (ld->nrays-1);; - - double rho, alpha; int stuff_id; - if(env.ray_tracing(ld->true_pose, ld->theta[i] + ld->true_pose[2], rho, alpha, &stuff_id) && (rho<p.max_reading)) { - - ld->valid[i] = 1; - ld->readings[i] = rho; - - double relative_alpha = alpha-ld->true_pose[2]; - - /* Make sure alpha points out of the wall */ - if( cosine_between_angles(relative_alpha, ld->theta[i]) > 0) { - relative_alpha += M_PI; - } - - ld->true_alpha[i] = normalize_0_2PI(relative_alpha); - - } else { - ld->valid[i] = 0; - } - - } - - ld->tv.tv_sec = num; - - - JO jo = ld_to_json(ld); - fputs(jo_to_string(jo), file_output); - fputs("\n", file_output); - jo_free(jo); - - ld_free(ld); - } - - if(num == 0) { - sm_error("It looks like there wasn't any pose in the file '%s'\n", p.file_poses); - return -4; - } - - jo_free(jo_map); -} - - - -#define jo_expect_array(a) (a!=0 && json_object_is_type(a, json_type_array)) -#define jo_expect_object(a) (a!=0 && json_object_is_type(a, json_type_object)) -#define jo_expect_string(a) (a!=0 && json_object_is_type(a, json_type_string)) -#define jo_expect_array_size(a,n) ( (a!=0) && (json_object_is_type(a, json_type_array)&& (jo_array_length(a)==n))) -#define jo_expect_array_size_min(a,n) ( (a!=0) && (json_object_is_type(a, json_type_array)&& (jo_array_length(a)>=n))) - - -#define expect(a) if(!a) { \ - sm_error("Invalid format: \n\t %s \n", #a); \ - return false; \ - } - -#define expect_s(a, s) if(!a) { \ - sm_error("Invalid format: %s \n\t %s \n", s, #a); \ - return false; \ - } - -double cosine_between_angles(double a1, double a2) { - return cos(a1)*cos(a2)+sin(a1)*sin(a2); -} - - -bool load_env_from_json(Environment& env, JO jo_map) { - jo_expect_object(jo_map); - - JO jo_objects = json_object_object_get(jo_map, "objects"); - expect(jo_expect_array(jo_objects)); - - for(int i=0; i < jo_array_length(jo_objects); i++) { - JO jo = jo_array_get(jo_objects, i); - expect(jo_expect_object(jo)); - - JO jo_type = jo_get(jo, "type"); - expect(jo_expect_string(jo_type)); - - if(!strcmp(jo_get_string(jo_type), "line")) { - - JO points = jo_get(jo, "points"); - expect(jo_expect_array_size_min(points, 2)); - - - for(int p=0;p<jo_array_length(points)-1;p++) { - Segment * s = new Segment(); - expect(jo_read_from_double_array (jo_array_get(points, p ), s->p0, 2, NAN)); - expect(jo_read_from_double_array (jo_array_get(points, p+1), s->p1, 2, NAN)); - env.stuff.push_back(s); - } - - } else if(!strcmp(jo_get_string(jo_type), "square")) { - - JO corners = jo_get(jo, "corners"); - expect_s(jo_expect_array_size(corners, 2), jo_to_string(corners)); - - double pmin[2],pmax[2]; - - expect(jo_read_from_double_array (jo_array_get(corners, 0 ), pmin, 2, NAN)); - expect(jo_read_from_double_array (jo_array_get(corners, 1), pmax, 2, NAN)); - - env.stuff.push_back(new Segment(pmin[0],pmin[1],pmax[0],pmin[1])); - env.stuff.push_back(new Segment(pmax[0],pmax[1],pmax[0],pmin[1])); - env.stuff.push_back(new Segment(pmax[0],pmax[1],pmin[0],pmax[1])); - env.stuff.push_back(new Segment(pmin[0],pmin[1],pmin[0],pmax[1])); - - } else { - sm_error("unknown object type: '%s'\n", jo_get_string(jo_type)); - return false; - } - } - - return true; -} - - diff --git a/sm/apps/raytracer/raytracer.h b/sm/apps/raytracer/raytracer.h deleted file mode 100644 index 7f53726..0000000 --- a/sm/apps/raytracer/raytracer.h +++ /dev/null @@ -1,18 +0,0 @@ - -#ifndef H_RAYTRACER -#define H_RAYTRACER - - -#include <json-c/json.h> - -#include "simplemap.h" -using namespace RayTracer; - -#include <csm/csm_all.h> -using namespace CSM; - -#include <options/options.h> - - -#endif - diff --git a/sm/apps/raytracer/simplemap.cpp b/sm/apps/raytracer/simplemap.cpp deleted file mode 100644 index 30ff25f..0000000 --- a/sm/apps/raytracer/simplemap.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "raytracer.h" - -namespace RayTracer { - using namespace std; - - - bool Segment::ray_tracing(const double p[2], const double direction, - double& range, double &alpha) const { - - int found = segment_ray_tracing(this->p0, this->p1, p, direction, &range); - - if(found) { - alpha = segment_alpha(this->p0, this->p1); - - /* alpha and direction should have versors with negative dot product */ - if( cos(alpha)*cos(direction) + sin(alpha)*sin(direction) > 0 ) - alpha = alpha + M_PI; - - alpha = normalize_0_2PI(alpha); - - return true; - } else { - alpha = NAN; - return false; - } - }; - - bool Environment::ray_tracing(const double p[2], const double direction, double& out_distance, double &out_alpha, int*stuff_id) const { - - int champion = -1; - double champion_range, champion_alpha; - for(size_t i=0;i<stuff.size();i++) { - Stuff * s = stuff.at(i); - - double range, alpha; - if(s->ray_tracing(p,direction,range,alpha)){ - if(champion==-1 || range<champion_range) { - champion = i; - champion_range = range; - champion_alpha = alpha; - } - } - - } - - if(champion != -1) { - *stuff_id = champion; - out_distance = champion_range; - out_alpha = champion_alpha; - - return true; - } else { - return false; - } - } -} // namespace SimpleMap diff --git a/sm/apps/raytracer/simplemap.h b/sm/apps/raytracer/simplemap.h deleted file mode 100644 index c2e391f..0000000 --- a/sm/apps/raytracer/simplemap.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef MAPAC_H -#define MAPAC_H - -#include <iostream> -#include <vector> -#include <string> - -namespace RayTracer { - - using namespace std; - - struct Material { - string name; - - /* 0: transparent; 1: solid; in between: randomly */ - double infrared_solid; - }; - - struct Stuff { - int group; - - Material * material; - - /** Ray tracing with incidence. */ - virtual bool ray_tracing(const double p[2], const double direction, double& out_distance, double &out_alpha) const = 0; - virtual ~Stuff(){}; - }; - - struct Segment: public Stuff { - double p0[2], p1[2]; - - Segment() {} - virtual ~Segment(){}; - - Segment(double x0,double y0,double x1,double y1) { - p0[0] = x0; p0[1] = y0; - p1[0] = x1; p1[1] = y1; - } - - - bool ray_tracing(const double p[2], const double direction, double& out_distance, double &out_alpha) const; - }; - - struct Circle: public Stuff { - virtual ~Circle(){}; - - double p[2], radius; - - bool ray_tracing(const double p[2], const double direction, double& out_distance, double &out_alpha) const; - }; - - struct Environment { - std::vector<Stuff*> stuff; - - bool ray_tracing(const double p[2], const double direction, double& out_distance, double &out_alpha, int*stuff_id) const ; - - }; - - - -} - -#endif diff --git a/sm/apps/raytracer/simplemap_obst.cpp b/sm/apps/raytracer/simplemap_obst.cpp deleted file mode 100644 index ab61e4c..0000000 --- a/sm/apps/raytracer/simplemap_obst.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "simplemap.h" - -namespace PPU { - - bool Map::isCellObst(const Viewport& cbb) const { - for (unsigned int i = 0; i < size(); i++) { - const Segment& s = at(i); - if(s.obstType != ObstSolid) continue; - - if(cbb.crossesSegment(s.p[0], s.p[1])) - return true; - } - return false; - } - - -} diff --git a/sm/apps/raytracer/test01-map.json b/sm/apps/raytracer/test01-map.json deleted file mode 100644 index c8204f9..0000000 --- a/sm/apps/raytracer/test01-map.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "objects": [ - { "type": "square", "corners": [ [-5.0, -5.0], [5.0, 5.0] ]} - ] -} diff --git a/sm/apps/raytracer/test01-scans.json.expected b/sm/apps/raytracer/test01-scans.json.expected deleted file mode 100644 index c2dd634..0000000 --- a/sm/apps/raytracer/test01-scans.json.expected +++ /dev/null @@ -1 +0,0 @@ -{ "nrays": 181, "min_theta": -1.570796, "max_theta": 1.570796, "odometry": [ null, null, null ], "estimate": [ null, null, null ], "true_pose": [ 0.000000, 0.000000, 0.000000 ], "theta": [ -1.570796, -1.553343, -1.535890, -1.518436, -1.500983, -1.483530, -1.466077, -1.448623, -1.431170, -1.413717, -1.396263, -1.378810, -1.361357, -1.343904, -1.326450, -1.308997, -1.291544, -1.274090, -1.256637, -1.239184, -1.221730, -1.204277, -1.186824, -1.169371, -1.151917, -1.134464, -1.117011, -1.099557, -1.082104, -1.064651, -1.047198, -1.029744, -1.012291, -0.994838, -0.977384, -0.959931, -0.942478, -0.925025, -0.907571, -0.890118, -0.872665, -0.855211, -0.837758, -0.820305, -0.802851, -0.785398, -0.767945, -0.750492, -0.733038, -0.715585, -0.698132, -0.680678, -0.663225, -0.645772, -0.628319, -0.610865, -0.593412, -0.575959, -0.558505, -0.541052, -0.523599, -0.506145, -0.488692, -0.471239, -0.453786, -0.436332, -0.418879, -0.401426, -0.383972, -0.366519, -0.349066, -0.331613, -0.314159, -0.296706, -0.279253, -0.261799, -0.244346, -0.226893, -0.209440, -0.191986, -0.174533, -0.157080, -0.139626, -0.122173, -0.104720, -0.087266, -0.069813, -0.052360, -0.034907, -0.017453, 0.000000, 0.017453, 0.034907, 0.052360, 0.069813, 0.087266, 0.104720, 0.122173, 0.139626, 0.157080, 0.174533, 0.191986, 0.209440, 0.226893, 0.244346, 0.261799, 0.279253, 0.296706, 0.314159, 0.331613, 0.349066, 0.366519, 0.383972, 0.401426, 0.418879, 0.436332, 0.453786, 0.471239, 0.488692, 0.506145, 0.523599, 0.541052, 0.558505, 0.575959, 0.593412, 0.610865, 0.628319, 0.645772, 0.663225, 0.680678, 0.698132, 0.715585, 0.733038, 0.750492, 0.767945, 0.785398, 0.802851, 0.820305, 0.837758, 0.855211, 0.872665, 0.890118, 0.907571, 0.925025, 0.942478, 0.959931, 0.977384, 0.994838, 1.012291, 1.029744, 1.047198, 1.064651, 1.082104, 1.099557, 1.117011, 1.134464, 1.151917, 1.169371, 1.186824, 1.204277, 1.221730, 1.239184, 1.256637, 1.274090, 1.291544, 1.308997, 1.326450, 1.343904, 1.361357, 1.378810, 1.396263, 1.413717, 1.431170, 1.448623, 1.466077, 1.483530, 1.500983, 1.518436, 1.535890, 1.553343, 1.570796 ], "readings": [ 5.000000, 5.000762, 5.003048, 5.006862, 5.012209, 5.019099, 5.027541, 5.037549, 5.049138, 5.062326, 5.077133, 5.093583, 5.111703, 5.131521, 5.153068, 5.176381, 5.201497, 5.228459, 5.257311, 5.288103, 5.320889, 5.355725, 5.392674, 5.431802, 5.473181, 5.516890, 5.563010, 5.611631, 5.662850, 5.716770, 5.773503, 5.833167, 5.895892, 5.961816, 6.031090, 6.103873, 6.180340, 6.260678, 6.345091, 6.433798, 6.527036, 6.625065, 6.728164, 6.836637, 6.950818, 7.071068, 6.950818, 6.836637, 6.728164, 6.625065, 6.527036, 6.433798, 6.345091, 6.260678, 6.180340, 6.103873, 6.031090, 5.961816, 5.895892, 5.833167, 5.773503, 5.716770, 5.662850, 5.611631, 5.563010, 5.516890, 5.473181, 5.431802, 5.392674, 5.355725, 5.320889, 5.288103, 5.257311, 5.228459, 5.201497, 5.176381, 5.153068, 5.131521, 5.111703, 5.093583, 5.077133, 5.062326, 5.049138, 5.037549, 5.027541, 5.019099, 5.012209, 5.006862, 5.003048, 5.000762, 5.000000, 5.000762, 5.003048, 5.006862, 5.012209, 5.019099, 5.027541, 5.037549, 5.049138, 5.062326, 5.077133, 5.093583, 5.111703, 5.131521, 5.153068, 5.176381, 5.201497, 5.228459, 5.257311, 5.288103, 5.320889, 5.355725, 5.392674, 5.431802, 5.473181, 5.516890, 5.563010, 5.611631, 5.662850, 5.716770, 5.773503, 5.833167, 5.895892, 5.961816, 6.031090, 6.103873, 6.180340, 6.260678, 6.345091, 6.433798, 6.527036, 6.625065, 6.728164, 6.836637, 6.950818, 7.071068, 6.950818, 6.836637, 6.728164, 6.625065, 6.527036, 6.433798, 6.345091, 6.260678, 6.180340, 6.103873, 6.031090, 5.961816, 5.895892, 5.833167, 5.773503, 5.716770, 5.662850, 5.611631, 5.563010, 5.516890, 5.473181, 5.431802, 5.392674, 5.355725, 5.320889, 5.288103, 5.257311, 5.228459, 5.201497, 5.176381, 5.153068, 5.131521, 5.111703, 5.093583, 5.077133, 5.062326, 5.049138, 5.037549, 5.027541, 5.019099, 5.012209, 5.006862, 5.003048, 5.000762, 5.000000 ], "valid": [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], "true_alpha": [ 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 1.570796, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 3.141593, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389, 4.712389 ], "timestamp": [ 1, 0 ] } diff --git a/sm/apps/raytracer/test01.sh b/sm/apps/raytracer/test01.sh deleted file mode 100755 index 4620e6e..0000000 --- a/sm/apps/raytracer/test01.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -echo '[0,0,0]' | ./raytracer -map test01-map.json > test01-scans.json -diff test01-scans.json{,.expected} diff --git a/sm/apps/raytracer/tests/example-map.json b/sm/apps/raytracer/tests/example-map.json deleted file mode 100644 index 66df7eb..0000000 --- a/sm/apps/raytracer/tests/example-map.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "objects": [ - { "type": "square", "corners": [ [0.0, 0.0], [1.0, 1.0] ]}, - { "type": "line", "points": [ [0.0, 0.0], [0.0, 0.4], [0.1, 0.4] ]} - ], - - "materials": { - "default": {}, - "glass": {} - }, - - "sensors": { - "bias": [] - } -} \ No newline at end of file diff --git a/sm/apps/sm0.c b/sm/apps/sm0.c deleted file mode 100644 index 23b73a1..0000000 --- a/sm/apps/sm0.c +++ /dev/null @@ -1,95 +0,0 @@ -#include <time.h> - -#include "../csm/csm_all.h" - - -extern int distance_counter; -int main(int argc, const char*argv[]) { - FILE * file; - if(argc==1) { - file = stdin; - } else { - const char * filename = argv[1]; - file = fopen(filename,"r"); - if(file==NULL) { - fprintf(stderr, "Could not open '%s'.\n", filename); - return -1; - } - } - - struct sm_params params; - struct sm_result result; - - params.max_angular_correction_deg = 5; - params.max_linear_correction = 0.2; - params.max_iterations = 30; - params.epsilon_xy = 0.001; - params.epsilon_theta = 0.001; - params.max_correspondence_dist = 2; - params.sigma = 0.01; - params.restart = 1; - params.restart_threshold_mean_error = 3.0 / 300.0; - params.restart_dt= 0.1; - params.restart_dtheta= 1.5 * 3.14 /180; - - params.clustering_threshold = 0.05; - params.orientation_neighbourhood = 3; - params.use_corr_tricks = 1; - - params.do_alpha_test = 0; - params.outliers_maxPerc = 0.85; - - params.outliers_adaptive_order =0.7; - params.outliers_adaptive_mult=2; - params.do_visibility_test = 1; - params.do_compute_covariance = 0; - - int num_matchings = 0; - int num_iterations = 0; - clock_t start = clock(); - - if(!(params.laser_ref = ld_read_smart(file)) ) { - printf("Could not read first scan.\n"); - return -1; - } - - gsl_vector *u = gsl_vector_alloc(3); - gsl_vector *x_old = gsl_vector_alloc(3); - gsl_vector *x_new = gsl_vector_alloc(3); - while(! (params.laser_sens = ld_read_smart(file)) ) { - copy_from_array(x_old, params.laser_ref->odometry); - copy_from_array(x_new, params.laser_sens->odometry); - pose_diff(x_new,x_old,u); - vector_to_array(u, params.first_guess); - - sm_gpm(¶ms,&result); - /* sm_icp(¶ms,&result); */ - - num_matchings++; - num_iterations += result.iterations; - - ld_free(params.laser_ref); - params.laser_ref = params.laser_sens; - } - - clock_t end = clock(); - float seconds = (end-start)/((float)CLOCKS_PER_SEC); - - sm_debug("sm0: CPU time = %f (seconds) (start=%d end=%d)\n", seconds,(int)start,(int)end); - sm_debug("sm0: Total number of matchings = %d\n", num_matchings); - sm_debug("sm0: Total number of iterations = %d\n", num_iterations); - sm_debug("sm0: Avg. iterations per matching = %f\n", num_iterations/((float)num_matchings)); - sm_debug("sm0: Avg. seconds per matching = %f\n", seconds/num_matchings); - sm_debug("sm0: that is, %d matchings per second\n", (int)floor(num_matchings/seconds)); - sm_debug("sm0: Avg. seconds per iteration = %f (note: very imprecise)\n", seconds/num_iterations); - sm_debug("sm0: Number of comparisons = %d \n", distance_counter); - sm_debug("sm0: Avg. comparisons per ray = %f \n", - (distance_counter/((float)num_iterations*params.laser_ref->nrays))); - - ld_free(params.laser_ref); - - gsl_vector_free(u); - gsl_vector_free(x_old); - gsl_vector_free(x_new); - return 0; -} diff --git a/sm/apps/sm1.c b/sm/apps/sm1.c deleted file mode 100644 index f89ef64..0000000 --- a/sm/apps/sm1.c +++ /dev/null @@ -1,206 +0,0 @@ -#include <time.h> -#include <string.h> - -#include "../csm/csm_all.h" - -#include <options/options.h> - -struct sm1_params { - const char * file1; - const char * file2; - const char * file_jj; - const char * file_output; - int debug; - - int algo; - int write_post_mortem; -} p; - - -extern int distance_counter; -extern void sm_options(struct sm_params*p, struct option*ops); - - -const char *sm1_banner = - -"There are TWO ways to define the input to this program.\n" -" \n" -"Say that in file A there are the scans \n" -" \n" -" A1 A2 A3 A4 ... \n" -" \n" -"and in file B there are the scans \n" -" \n" -" B1 B2 B3 B4 ... \n" -" \n" -"With this command line: \n" -" \n" -" sm1 --file1 A --file2 B \n" -" \n" -"the matchings will be: \n" -" \n" -" (A1, B1), (A2, B2), etc.\n" -" \n" -"While with this command line:\n" -" \n" -" sm1 --file1 A --file2 A\n" -" \n" -"the matchings will be \n" -" \n" -" (A1, A2), (A3, A4), (A5, A6), ... \n" -" \n"; - - -int main(int argc, const char*argv[]) { - sm_set_program_name(argv[0]); - options_banner(sm1_banner); - - struct sm_params params; - struct sm_result result; - - struct option* ops = options_allocate(100); - options_string(ops, "file1", &p.file1, "file1.txt", - "File with first series of scans (at pose1)"); - options_string(ops, "file2", &p.file2, "file2.txt", - "File with second series of scans (at pose2)"); - options_string(ops, "file_jj", &p.file_jj, "", - "File for journaling -- if left empty, journal not open."); - options_string(ops, "out", &p.file_output, "stdout", "Output file (JSON structs)"); - options_int(ops, "algo", &p.algo, 0, "Which algorithm to use (0:(pl)ICP 1:gpm-stripped 2:HSM) "); - - options_int(ops, "debug", &p.debug, 0, "Shows debug information"); - options_int(ops, "write_post_mortem", &p.write_post_mortem, 1, "In case of failure, writes a post mortem."); - - sm_options(¶ms, ops); - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - sm_debug_write(p.debug); - - FILE * file1 = open_file_for_reading(p.file1); - FILE * file2 = !strcmp(p.file1, p.file2) ? file1 - : open_file_for_reading(p.file2); - if(!file1 || !file2) return -1; - - FILE * out = open_file_for_writing(p.file_output); - if(!out) return -2; - - if(strcmp(p.file_jj, "")) { - FILE * jj = open_file_for_writing(p.file_jj); - if(!jj) return -1; - jj_set_stream(jj); - } - - LDP ld1, ld2; - int count = 0; - while(1) { - count++; - - ld1 = ld_from_json_stream(file1); - if(!ld1) { - if(feof(file1)) break; - sm_error("Invalid data in file1 '%s' \n", p.file1); - return 2; - } - ld2 = ld_from_json_stream(file2); - if(!ld2) { - if(feof(file2)) break; - sm_error("Invalid data in file2 '%s' \n", p.file2); - return 3; - } - - params.laser_ref = ld1; - params.laser_sens = ld2; - - if( any_nan(params.laser_ref->odometry,3) || - any_nan(params.laser_sens->odometry,3) ) { - sm_error("The 'odometry' field is set to NaN so I don't know how to get an initial guess. I usually use the difference in the odometry fields to obtain the initial guess.\n"); - sm_error(" (file %s) laser_ref->odometry = %s \n", p.file1, friendly_pose(params.laser_ref->odometry) ); - sm_error(" (file %s) laser_sens->odometry = %s \n", p.file2, friendly_pose(params.laser_sens->odometry) ); - sm_error(" I will quit it here. \n"); - return 3; - } - - pose_diff_d( params.laser_sens->odometry, - /* o minus */ params.laser_ref->odometry, - /* = */ params.first_guess); - - /* Do the actual work */ - switch(p.algo) { - case(0): - sm_icp(¶ms, &result); break; - case(1): - sm_gpm(¶ms, &result); break; - case(2): - sm_hsm(¶ms, &result); break; - default: - sm_error("Unknown algorithm to run: %d.\n",p.algo); - return -1; - } - - if(p.write_post_mortem && !result.valid) { - char casename[256]; - sprintf(casename, "sm1_failure_matching%d", count); - sm_error("sm1: matching #%d failed. Writing a special case %s.\n", count, casename ); -// save_testcase(¶ms) - - char file_config[256],file1[256],file2[256],file_jj[256],script[256]; - - sprintf(file_config, "%s.config", casename); - sprintf(file1, "%s_laser_ref.json", casename); - sprintf(file2, "%s_laser_sens.json", casename); - sprintf(file_jj, "%s.journal", casename); - sprintf(script, "%s.sh", casename); - - FILE * f = fopen(file_config, "w"); - options_dump(ops,f,0); - fclose(f); - - f = fopen(file1, "w"); - ld_write_as_json(params.laser_ref,f); - fclose(f); - - f = fopen(file2, "w"); - ld_write_as_json(params.laser_sens,f); - fclose(f); - - f = fopen(script, "w"); - fprintf(f, "#!/bin/bash\n"); - fprintf(f, "%s -config %s -file1 %s -file2 %s -debug 1 -file_jj %s -write_post_mortem 0 \n", - argv[0], file_config, file1, file2, file_jj); - fprintf(f, "sm_animate -in %s -out %s_anim.pdf \n", file_jj, casename); - fclose(f); - } - - - JO jo = result_to_json(¶ms, &result); - - double true_x[3]; - pose_diff_d(params.laser_sens->true_pose, - params.laser_ref->true_pose, true_x); - double true_e[3]; - - pose_diff_d(result.x, true_x, true_e); - /* int i=0;for(;i<3;i++) true_e[i] = result.x[i] - true_x[i];*/ - - jo_add_double_array(jo, "true_x", true_x, 3); - jo_add_double_array(jo, "true_e", true_e, 3); - - fputs(json_object_to_json_string(jo), out); - fputs("\n",out); - - jo_free(jo); - ld_free(ld1); - ld_free(ld2); - } - - fclose(file1); - if(file2 != file1) fclose(file2); - fclose(out); - - - return 0; -} diff --git a/sm/apps/sm2.c b/sm/apps/sm2.c deleted file mode 100644 index b8f282a..0000000 --- a/sm/apps/sm2.c +++ /dev/null @@ -1,190 +0,0 @@ -#include <time.h> -#include <string.h> -#include <libgen.h> - -#include <options/options.h> -#include "../csm/csm_all.h" - -struct { - const char * file_in; - const char * file_out; - const char * file_out_stats; - const char * file_jj; - int format; - - /* which algorithm to run */ - int algo; - - int recover_from_error; - - int debug; -} p; - -extern void sm_options(struct sm_params*p, struct option*ops); - -void spit(LDP ld, FILE * stream); - -int main(int argc, const char*argv[]) { - sm_set_program_name(argv[0]); - - struct sm_params params; - struct sm_result result; - - struct option* ops = options_allocate(100); - options_string(ops, "in", &p.file_in, "stdin", "Input file "); - options_string(ops, "out", &p.file_out, "stdout", "Output file "); - options_string(ops, "out_stats", &p.file_out_stats, "", "Output file (stats) "); - options_string(ops, "file_jj", &p.file_jj, "", - "File for journaling -- if left empty, journal not open."); - options_int(ops, "algo", &p.algo, 0, "Which algorithm to use (0:(pl)ICP 1:gpm-stripped 2:HSM) "); - - options_int(ops, "debug", &p.debug, 0, "Shows debug information"); - options_int(ops, "recover_from_error", &p.recover_from_error, 0, "If true, tries to recover from an ICP matching error"); - - - p.format = 0; -/* options_int(ops, "format", &p.format, 0, - "Output format (0: log in JSON format, 1: log in Carmen format (not implemented))");*/ - - sm_options(¶ms, ops); - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - sm_debug_write(p.debug); - - /* Open input and output files */ - - FILE * file_in = open_file_for_reading(p.file_in); - if(!file_in) return -1; - FILE * file_out = open_file_for_writing(p.file_out); - if(!file_out) return -1; - - if(strcmp(p.file_jj, "")) { - FILE * jj = open_file_for_writing(p.file_jj); - if(!jj) return -1; - jj_set_stream(jj); - } - - FILE * file_out_stats = 0; - if(strcmp(p.file_out_stats, "")) { - file_out_stats = open_file_for_writing(p.file_out_stats); - if(!file_out_stats) return -1; - } - - /* Read first scan */ - LDP laser_ref; - if(!(laser_ref = ld_read_smart(file_in))) { - sm_error("Could not read first scan.\n"); - return -1; - } - if(!ld_valid_fields(laser_ref)) { - sm_error("Invalid laser data in first scan.\n"); - return -2; - } - - - /* For the first scan, set estimate = odometry */ - copy_d(laser_ref->odometry, 3, laser_ref->estimate); - - spit(laser_ref, file_out); - int count=-1; - LDP laser_sens; - while( (laser_sens = ld_read_smart(file_in)) ) { - - count++; - if(!ld_valid_fields(laser_sens)) { - sm_error("Invalid laser data in (#%d in file).\n", count); - return -(count+2); - } - - params.laser_ref = laser_ref; - params.laser_sens = laser_sens; - - /* Set first guess as the difference in odometry */ - - if( any_nan(params.laser_ref->odometry,3) || - any_nan(params.laser_sens->odometry,3) ) { - sm_error("The 'odometry' field is set to NaN so I don't know how to get an initial guess. I usually use the difference in the odometry fields to obtain the initial guess.\n"); - sm_error(" laser_ref->odometry = %s \n", friendly_pose(params.laser_ref->odometry) ); - sm_error(" laser_sens->odometry = %s \n", friendly_pose(params.laser_sens->odometry) ); - sm_error(" I will quit it here. \n"); - return -3; - } - - double odometry[3]; - pose_diff_d(laser_sens->odometry, laser_ref->odometry, odometry); - double ominus_laser[3], temp[3]; - ominus_d(params.laser, ominus_laser); - oplus_d(ominus_laser, odometry, temp); - oplus_d(temp, params.laser, params.first_guess); - - /* Do the actual work */ - switch(p.algo) { - case(0): - sm_icp(¶ms, &result); break; - case(1): - sm_gpm(¶ms, &result); break; - case(2): - sm_hsm(¶ms, &result); break; - default: - sm_error("Unknown algorithm to run: %d.\n",p.algo); - return -1; - } - - if(!result.valid){ - if(p.recover_from_error) { - sm_info("One ICP matching failed. Because you passed -recover_from_error, I will try to recover." - " Note, however, that this might not be good in some cases. \n"); - sm_info("The recover is that the displacement is set to 0. No result stats is output. \n"); - - /* For the first scan, set estimate = odometry */ - copy_d(laser_ref->estimate, 3, laser_sens->estimate); - - ld_free(laser_ref); laser_ref = laser_sens; - - } else { - sm_error("One ICP matching failed. Because I process recursively, I will stop here.\n"); - sm_error("Use the option -recover_from_error if you want to try to recover.\n"); - ld_free(laser_ref); - return 2; - } - } else { - - /* Add the result to the previous estimate */ - oplus_d(laser_ref->estimate, result.x, laser_sens->estimate); - - /* Write the corrected log */ - spit(laser_sens, file_out); - - /* Write the statistics (if required) */ - if(file_out_stats) { - JO jo = result_to_json(¶ms, &result); - fputs(jo_to_string(jo), file_out_stats); - fputs("\n", file_out_stats); - jo_free(jo); - } - - ld_free(laser_ref); laser_ref = laser_sens; - } - } - ld_free(laser_ref); - - return 0; -} - - -void spit(LDP ld, FILE * stream) { - switch(p.format) { - case(0): { - ld_write_as_json(ld, stream); - break; - } - case(1): { - /* XXX: to implement */ - break; - } - } -} diff --git a/sm/apps/sm3.c b/sm/apps/sm3.c deleted file mode 100644 index a7c94b2..0000000 --- a/sm/apps/sm3.c +++ /dev/null @@ -1,89 +0,0 @@ -#include <time.h> -#include <string.h> - -#include "../csm/csm_all.h" - -#include <options/options.h> - -struct sm3_params { - const char * input_filename; - -} p; -extern void sm_options(struct sm_params*p, struct option*ops); - -extern int distance_counter; - - -int main(int argc, const char*argv[]) { - sm_set_program_name(argv[0]); - - struct sm_params params; - struct sm_result result; - - struct option* ops = options_allocate(100); - options_string(ops, "in", &p.input_filename, "stdin", - "Log file"); - - sm_options(¶ms, ops); - if(!options_parse_args(ops, argc, argv)) { - fprintf(stderr, "\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - FILE * file = open_file_for_reading(p.input_filename); - if(!file) return -1; - - LDP *lds; int lds_size; - if(!ld_read_all(file, &lds, &lds_size)) { - sm_error("Cannot read all laser scans.\n"); - return -1; - } - - sm_debug("Read %d scans.\n", lds_size); - - - int num_matchings = 0; - int num_iterations = 0; - clock_t start = clock(); - - int i; - for(i=0;i<lds_size-1;i++) { - params.laser_ref = lds[i]; - params.laser_sens = lds[i+1]; - - double odometry[3]; - pose_diff_d(params.laser_sens->odometry, params.laser_ref->odometry, odometry); - double ominus_laser[3], temp[3]; - ominus_d(params.laser, ominus_laser); - oplus_d(ominus_laser, odometry, temp); - oplus_d(temp, params.laser, params.first_guess); - - sm_icp(¶ms,&result); - - num_matchings++; - num_iterations += result.iterations; - - fprintf(stderr, "."); - } - - clock_t end = clock(); - float seconds = (end-start)/((float)CLOCKS_PER_SEC); - - if(num_matchings>0) { - printf("sm3: CPU time = %f (seconds) (start=%d end=%d)\n", seconds,(int)start,(int)end); - printf("sm3: Total number of matchings = %d\n", num_matchings); - printf("sm3: Total number of iterations = %d\n", num_iterations); - printf("sm3: Avg. iterations per matching = %f\n", num_iterations/((float)num_matchings)); - printf("sm3: Avg. seconds per matching = %f\n", seconds/num_matchings); - printf("sm3: that is, %d matchings per second\n", (int)floor(num_matchings/seconds)); - printf("sm3: Avg. seconds per iteration = %f (note: very imprecise)\n", seconds/num_iterations); - printf("sm3: Number of comparisons = %d \n", distance_counter); - printf("sm3: Avg. comparisons per ray per iteration = %f \n", - (distance_counter/((float)num_iterations*params.laser_ref->nrays))); - } else { - sm_error("Empty file?\n"); - return 1; - } - return 0; -} diff --git a/sm/apps/sm_animate.c b/sm/apps/sm_animate.c deleted file mode 100644 index 7b0ad3b..0000000 --- a/sm/apps/sm_animate.c +++ /dev/null @@ -1,229 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <float.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <cairo-pdf.h> - -#include <options/options.h> - -#include "../csm/csm_all.h" -#include "../csm/laser_data_drawing.h" -#include "../csm/laser_data_cairo.h" - -typedef struct { - const char * file_input; - - const char * file_output; - - ld_style laser_ref_s, laser_sens_s; - /* Drawing style for correspondences */ - line_style corr; - - - double max_width_cm; - double max_height_cm; - - int max_iterations; - int zoom_ray; - - /* maximum size, in points, of the output pdf */ - int width_pt, height_pt; - - /* Padding, in meters, to be added */ - double padding; - - int write_info; -} anim_params ; - -int draw_animation( anim_params* p, JO jo, const char*filename); -void set_defaults(anim_params *p); - - -int main(int argc, const char** argv) -{ - sm_set_program_name(argv[0]); - - anim_params p; - set_defaults(&p); - - struct option* ops = options_allocate(100); - options_string(ops, "in", &p.file_input, "stdin", "Input file (defaults to stdin)"); - options_string(ops, "out", &p.file_output, "sm_animate_%02d.pdf", "Output file "); - - options_int(ops, "write_info", &p.write_info, 0, "Writes informations and statistics in the picture."); - options_int(ops, "max_iterations", &p.max_iterations, 10, "Maximum number of iterations"); - options_int(ops, "zoom_ray", &p.zoom_ray, -1, "If >= 0, the action is zoomed on a particular ray."); - options_int(ops, "width_pt", &p.width_pt, 500, "Maximum width, in points, of the PDF."); - options_int(ops, "height_pt", &p.height_pt, 500, "Maximum height, in points, of the PDF."); - options_double(ops, "padding", &p.padding, 0.2, "Padding, in meters, to be added around figure."); - - lds_add_options(&(p.laser_ref_s), ops, "ref_", ""); - lds_add_options(&(p.laser_sens_s), ops, "sens_", ""); - ls_add_options(&(p.corr), ops, "corr_", ""); - - if(!options_parse_args(ops, argc, argv)) { - sm_info("Draws ICP animation. It reads the output created by sm2 when given the 'file_jj' switch. \n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - FILE * input = open_file_for_reading(p.file_input); - if(!input) return -1; - - JO jo; int count = 0; - while( (jo = json_read_stream(input)) ) { - char filename[100]; - sprintf(filename, p.file_output, count); - sm_info("Writing frame %s \n", p.file_output); - if(!draw_animation(&p, jo, filename)) - return -2; - count++; - } - - return 0; -} - -/** Returns an array with depths */ -int draw_animation(anim_params* p, JO jo, const char*filename) { - JO jo_ref = jo_get(jo, "laser_ref"); - JO jo_sens = jo_get(jo, "laser_sens"); - if(!jo_ref || !jo_sens) { - sm_error("Could not get laser_ref/laser_sens.\n"); - return 0; - } - - LDP laser_ref = json_to_ld(jo_ref); - LDP laser_sens = json_to_ld(jo_sens); - if(!laser_ref || !laser_sens) { - sm_error("Could not read laser_ref/laser_sens from JSON representation.\n"); - return 0; - } - - ld_compute_cartesian(laser_ref); - ld_compute_cartesian(laser_sens); - - double ld_min[2], ld_max[2]; - if(p->zoom_ray == -1) { - double zero[3] = {0,0,0}; - if(!ld_get_bounding_box(laser_ref, ld_min, ld_max, zero, p->laser_ref_s.horizon)){ - sm_error("Not enough good points to establish bounding box.\n"); - return 0; - } - } else { - if(p->zoom_ray < 0 || p->zoom_ray >= laser_ref->nrays || !ld_valid_ray(laser_ref, p->zoom_ray)) { - sm_error("Ray index #%d is not valid in laser_ref.\n", p->zoom_ray); - return 0; - } - - ld_min[0] = ld_max[0] = laser_ref->points[p->zoom_ray].p[0]; - ld_min[1] = ld_max[1] = laser_ref->points[p->zoom_ray].p[1]; - } - - ld_min[0] -= p->padding; - ld_min[1] -= p->padding; - ld_max[0] += p->padding; - ld_max[1] += p->padding; - - sm_info("Bounding box: %f %f -- %f %f\n", ld_min[0], ld_min[1], ld_max[0], ld_max[1]); - - cairo_surface_t *surface; - cairo_t *cr; - - if(!create_pdf_surface(filename, p->width_pt, p->height_pt, - ld_min, ld_max, &surface, &cr)) return 0; - - JO iterations = jo_get(jo, "iterations"); - if(!iterations || !json_object_is_type(iterations, json_type_array)) { - fprintf(stderr, "Could not read iterations.\n"); - return 0; - } - - int niterations = json_object_array_length(iterations); - if(niterations>p->max_iterations) niterations = p->max_iterations; - sm_info("Displaying %d iterations.\n", niterations); - - int it; - for(it=0;it<niterations;it++) { - JO iteration = json_object_array_get_idx(iterations, it); - - double x_old[3], x_new[3]; - jo_read_double_array(iteration, "x_old", x_old, 3, NAN); - jo_read_double_array(iteration, "x_new", x_new, 3, NAN); - - - cairo_save(cr); - cr_ld_draw(cr, laser_ref, &(p->laser_ref_s)); - - ld_compute_world_coords(laser_sens, x_old); - - - JO corr0 = jo_get(iteration, "corr0"); - JO corr1 = jo_get(iteration, "corr1"); - JO corr2 = jo_get(iteration, "corr2"); - if(!corr1 || !corr2 || !corr0) { - sm_error("Iteration %d: could not read correspondences (field 'corr<i>'). Probably ICP failed here?\n", it); - } else { - cr_set_style(cr, &(p->corr)); - cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); - json_to_corr(corr0, laser_sens->corr, laser_sens->nrays); - cr_ld_draw_corr(cr, laser_ref, laser_sens); - - cairo_set_source_rgb (cr, 1.0, 0.0, 1.0); - json_to_corr(corr1, laser_sens->corr, laser_sens->nrays); - cr_ld_draw_corr(cr, laser_ref, laser_sens); - - cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); - json_to_corr(corr2, laser_sens->corr, laser_sens->nrays); - cr_ld_draw_corr(cr, laser_ref, laser_sens); - } - - cr_set_reference(cr, x_old); - cr_ld_draw(cr, laser_sens, &(p->laser_sens_s)); - - cairo_restore(cr); - - if(p->write_info) { - cairo_save(cr); - cairo_identity_matrix(cr); - cairo_set_font_size (cr, 20.0f); - cairo_select_font_face (cr, "Sans", - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_NORMAL); - - char text[100]; - sprintf(text, "Iteration #%d: x_old: %s", it, friendly_pose(x_old)); - cairo_move_to(cr, 0.0, -20.0 ); - cairo_show_text(cr, text); - - sm_info("%s\n",text); - cairo_restore(cr); - } - - cairo_show_page (cr); - } - - ld_free(laser_ref); - ld_free(laser_sens); - - cairo_destroy (cr); - cairo_surface_destroy (surface); - - return 1; -} - - -void set_defaults(anim_params *p) { - lds_set_defaults(&(p->laser_ref_s)); - lds_set_defaults(&(p->laser_sens_s)); - ls_set_defaults(&(p->corr)); - p->laser_ref_s.points.color = "#00f"; - p->laser_sens_s.points.color = "#f00"; - p->laser_ref_s.pose.color = p->laser_ref_s.points.color; - p->laser_sens_s.pose.color = p->laser_sens_s.points.color; - p->laser_sens_s.pose_radius = - p->laser_ref_s.pose_radius = 0.015; - -} - diff --git a/sm/apps/test_json.c b/sm/apps/test_json.c deleted file mode 100644 index f74e64c..0000000 --- a/sm/apps/test_json.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "../csm/csm.h" - -int main() { - - LDP ld = ld_alloc_new(50); - JO jo = ld_to_json(ld); - - printf(json_object_to_json_string(jo)); - - return 0; -} diff --git a/sm/apps/test_json_ld.c b/sm/apps/test_json_ld.c deleted file mode 100644 index 0d10899..0000000 --- a/sm/apps/test_json_ld.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "../csm/csm_all.h" - -int main() { - JO jo; /* the monkey */ - LDP ld; - - while((jo = json_read_stream(stdin))) { - if(!(ld = json_to_ld(jo))) { - fprintf(stderr, "Could not transform to laser_data:\n\n"); - fprintf(stderr, "-----\n"); - fprintf(stderr, json_object_to_json_string(jo)); - fprintf(stderr, "-----\n"); - continue; - } - - jo = ld_to_json(ld); - printf(json_object_to_json_string(jo)); - printf("\n"); - } - - return 0; -} diff --git a/sm/csm/CMakeLists.txt b/sm/csm/CMakeLists.txt deleted file mode 100644 index d87efe9..0000000 --- a/sm/csm/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -SET(csm_sources - laser_data.c - laser_data_fisher.c - laser_data_json.c - laser_data_carmen.c - laser_data_load.c - laser_data_drawing.c - laser_data_bbox.c - - json_journal.c - math_utils.c - math_utils_gsl.c - utils.c - orientation.c - clustering.c - logging.c - sm_options.c - - icp/icp.c - icp/icp_loop.c - icp/icp_corr_dumb.c - icp/icp_corr_tricks.c - icp/icp_outliers.c - icp/icp_covariance.c - icp/icp_debug.c - - mbicp/mbicp_interface.c - mbicp/MbICP.c - mbicp/calcul.c - mbicp/percolate.c - mbicp/sp_matrix.c - hsm/hsm.c - hsm/hsm_interface.c - - gpm/gpm.c -) - -IF(CAIRO_FOUND) - SET(csm_sources ${csm_sources} laser_data_cairo.c) -ENDIF(CAIRO_FOUND) - - -foreach(dir . hsm mbicp icp gpm structprior) -FILE(GLOB csm_headers "${dir}/*.h") -foreach(header ${csm_headers} ) - INSTALL(FILES ${header} DESTINATION include/csm/${dir}) -endforeach(header ${csm_headers}) -endforeach(dir . csm) - - - diff --git a/sm/csm/csm.h b/sm/csm/csm.h deleted file mode 100644 index 56f1919..0000000 --- a/sm/csm/csm.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef H_CSM_H -#define H_CSM_H - -/* Some preprocessor magic for calling this library from C++ */ - -#ifdef __cplusplus - namespace CSM {} - extern "C" { -#endif - -#include "laser_data.h" -#include "laser_data_drawing.h" -#include "laser_data_json.h" -#include "algos.h" -#include "utils.h" - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/sm/csm/gpm/gpm.c b/sm/csm/gpm/gpm.c deleted file mode 100644 index cf88254..0000000 --- a/sm/csm/gpm/gpm.c +++ /dev/null @@ -1,286 +0,0 @@ -#include <gsl/gsl_histogram.h> -#include <gsl/gsl_matrix.h> - - -#include "../csm_all.h" -#include "gpm.h" - -#include <egsl/egsl_macros.h> - - -void sm_gpm(struct sm_params*params, struct sm_result*res) { - res->valid = 0; - /* Check for well-formedness of the input data */ - if(!ld_valid_fields(params->laser_ref) || - !ld_valid_fields(params->laser_sens)) { - return; - } - - LDP laser_ref = params->laser_ref; - LDP laser_sens = params->laser_sens; - - /* We need to compute cartesian points */ - ld_compute_cartesian(laser_ref); - /* ... and orientation */ - ld_simple_clustering(laser_ref, params->clustering_threshold); - ld_compute_orientation(laser_ref, params->orientation_neighbourhood, params->sigma); - /* ... for both scans. */ - ld_compute_cartesian(laser_sens); - ld_simple_clustering(laser_sens, params->clustering_threshold); - ld_compute_orientation(laser_sens, params->orientation_neighbourhood, params->sigma); - - /* Create an histogram whose bin is large `theta_bin_size` */ - double theta_bin_size = deg2rad(params->gpm_theta_bin_size_deg); - double hist_min = -M_PI-theta_bin_size; /* be robust */ - double hist_max = +M_PI+theta_bin_size; - size_t nbins = (size_t) ceil( (hist_max-hist_min) / theta_bin_size); - gsl_histogram*hist = gsl_histogram_alloc(nbins); - gsl_histogram_set_ranges_uniform(hist, hist_min, hist_max); - - /* Fill the histogram with samples */ - double u[3]; copy_d(params->first_guess, 3, u); - sm_debug("gpm 1/2: old u = : %s \n", friendly_pose(u) ); - - int interval = params->gpm_interval; - - int num_correspondences_theta=-1; - - - ght_find_theta_range(laser_ref, laser_sens, - u, params->max_linear_correction, - params->max_angular_correction_deg, interval, hist, &num_correspondences_theta); - - if(num_correspondences_theta < laser_ref->nrays) { - sm_error("sm_gpm(): I found only %d correspondences in the first pass of GPM. I consider it a failure.\n", - num_correspondences_theta); - return; - } - - /* Find the bin with most samples */ - size_t max_bin = gsl_histogram_max_bin(hist); - - /* Around that value will be the range admissible for theta */ - double min_range, max_range; - gsl_histogram_get_range(hist,max_bin,&min_range,&max_range); - - /* Extend the range of the search */ - double extend_range = deg2rad(params->gpm_extend_range_deg); - min_range += -extend_range; - max_range += +extend_range; - - /* if(jf()) fprintf(jf(), "iteration 0\n"); - journal_pose("x_old", u);*/ - - - /* if(jf()) fprintf(jf(), "iteration 1\n"); - journal_pose("x_old", u);*/ - - - /* Now repeat the samples generation with a smaller domain */ - u[2] = 0.5 * (max_range + min_range); - double new_range_deg = rad2deg( 0.5*(max_range - min_range) ); - - double x_new[3]; - int num_correspondences=-1; - ght_one_shot(laser_ref, laser_sens, - u, params->max_linear_correction*2, - new_range_deg, interval, x_new, &num_correspondences) ; - - if(num_correspondences < laser_ref->nrays) { - sm_error("sm_gpm(): I found only %d correspondences in the second pass of GPM. I consider it a failure.\n", - num_correspondences); - return; - } - - /* Et voila, in x_new we have the answer */ - - { - sm_debug("gpm : max_correction_lin %f def %f\n", params->max_linear_correction, params->max_angular_correction_deg); - sm_debug("gpm : acceptable range for theta: [%f, %f]\n", min_range,max_range); - sm_debug("gpm : 1) Num correspondences for theta: %d\n", num_correspondences_theta); - - sm_debug("gpm 1/2: new u = : %s \n", friendly_pose(u) ); - sm_debug("gpm 1/2: New range: %f to %f\n",rad2deg(min_range),rad2deg(max_range)); - - sm_debug("gpm 2/2: Solution: %s \n", friendly_pose(x_new)); - /* if(jf()) fprintf(jf(), "iteration 2\n"); - journal_pose("x_old", x_new); */ - } - - /* Administrivia */ - - res->valid = 1; - copy_d(x_new, 3, res->x); - - res->iterations = 0; - - gsl_histogram_free(hist); -} - -void ght_find_theta_range(LDP laser_ref, LDP laser_sens, - const double*x0, double max_linear_correction, - double max_angular_correction_deg, int interval, gsl_histogram*hist, int*num_correspondences) -{ - /** Compute laser_sens's points in laser_ref's coordinates by roto-translating by x0 */ - ld_compute_world_coords(laser_sens, x0); - - int count = 0; - int i; - for(i=0;i<laser_sens->nrays;i++) { - if(!laser_sens->alpha_valid[i]) continue; - if(i % interval) continue; - - const double * p_i = laser_sens->points[i].p; - - const double * p_i_w = laser_sens->points_w[i].p; - int from; int to; int start_cell; - possible_interval(p_i_w, laser_ref, max_angular_correction_deg, - max_linear_correction, &from, &to, &start_cell); - -// printf("\n i=%d interval = [%d,%d] ", i, from, to); - int j; - for(j=from;j<=to;j++) { - if(!laser_ref->alpha_valid[j]) continue; - if(j % interval) continue; - - double theta = angleDiff(laser_ref->alpha[j], laser_sens->alpha[i]); - double theta_diff = angleDiff(theta,x0[2]); - if( fabs(theta_diff) > deg2rad(max_angular_correction_deg) ) - continue; - theta = x0[2] + theta_diff; // otherwise problems near +- PI - - const double * p_j = laser_ref->points[j].p; - - double c = cos(theta); double s = sin(theta); - double t_x = p_j[0] - (c*p_i[0]-s*p_i[1]); - double t_y = p_j[1] - (s*p_i[0]+c*p_i[1]); - double t_dist = sqrt( square(t_x-x0[0]) + square(t_y-x0[1]) ); - - if(t_dist > max_linear_correction) - continue; - - /*double weight = 1/(laser_sens->cov_alpha[i]+laser_ref->cov_alpha[j]);*/ - double weight = 1; - gsl_histogram_accumulate(hist, theta, weight); - gsl_histogram_accumulate(hist, theta+2*M_PI, weight); /* be robust */ - gsl_histogram_accumulate(hist, theta-2*M_PI, weight); - count ++; - } - } - *num_correspondences = count; - sm_debug(" correspondences = %d\n",count); -} - -void ght_one_shot(LDP laser_ref, LDP laser_sens, - const double*x0, double max_linear_correction, - double max_angular_correction_deg, int interval, double*x, int*num_correspondences) -{ - /** Compute laser_sens's points in laser_ref's coordinates by roto-translating by x0 */ - ld_compute_world_coords(laser_sens, x0); - - double L[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; - double z[3] = {0,0,0}; - - int count = 0; - int i; - for(i=0;i<laser_sens->nrays;i++) { - if(!laser_sens->alpha_valid[i]) continue; - if(i % interval) continue; - - - const double * p_i = laser_sens->points_w[i].p; - - const double * p_i_w = laser_sens->points_w[i].p; - int from; int to; int start_cell; - possible_interval(p_i_w, laser_ref, max_angular_correction_deg, - max_linear_correction, &from, &to, &start_cell); -// from = 0; to = laser_ref->nrays-1; - - - int j; - for(j=from;j<=to;j++) { - if(j % interval) continue; - if(!laser_ref->alpha_valid[j]) continue; - - double theta = angleDiff(laser_ref->alpha[j], laser_sens->alpha[i]); - double theta_diff = angleDiff(theta,x0[2]); - if( fabs(theta_diff) > deg2rad(max_angular_correction_deg) ) - continue; - theta = x0[2] + theta_diff; // otherwise problems near +- PI - - const double * p_j = laser_ref->points[j].p; - - double c = cos(theta); double s = sin(theta); - double t_x = p_j[0] - (c*p_i[0]-s*p_i[1]); - double t_y = p_j[1] - (s*p_i[0]+c*p_i[1]); - double t_dist = sqrt( square(t_x-x0[0]) + square(t_y-x0[1]) ); - - if(t_dist > max_linear_correction) - continue; - - /*double weight = 1/(laser_sens->cov_alpha[i]+laser_ref->cov_alpha[j]); - double weight = exp( -square(t_dist) - 5 * square(theta-x0[2]) );*/ - - double weight = 1; - - double alpha = laser_ref->alpha[j]; - double ca = cos(alpha); double sa=sin(alpha); - -// printf("%d ", (int) rad2deg(theta)); - -/* printf("valid %d alpha %f weight %f t_x %f t_y %f\n", - laser_ref->alpha_valid[j],alpha,weight, - t_x, t_y); */ - z[0] += weight*(ca*ca*t_x + sa*ca*t_y); - z[1] += weight*(sa*ca*t_x + sa*sa*t_y); - z[2] += weight*theta; - L[0][0] += weight* ca * ca; - L[0][1] += weight* sa * ca; - L[1][0] += weight* sa * ca; - L[1][1] += weight* sa * sa; - L[2][2] += weight; - - count += 1; - } - } - - *num_correspondences = count; - - if(1) { - - double weight = 0.5 * count; - z[0] += x0[0] * weight; - z[1] += x0[1] * weight; - L[0][0] += weight; - L[0][1] += 0; - L[1][0] += 0; - L[1][1] += weight; - } - - - egsl_push(); - val eL = egsl_alloc(3,3); - size_t a,b; - for(a=0;a<3;a++) - for(b=0;b<3;b++) - *egsl_atmp(eL,a,b) = L[a][b]; - -/* egsl_print("eL", eL);*/ - val ez = egsl_vFa(3,z); - - val ex = m(inv(eL), ez); - - egsl_v2a(ex, x); - - -/* egsl_print("eL", eL); - egsl_print("ez", ez); - egsl_print("ex", ex); */ - - egsl_pop(); - -// sm_debug("gpm: second step: theta = %f %f / %d = %f \n", rad2deg(x[2]), rad2deg(z[2]), count, rad2deg(z[2]) / count); - sm_debug("gpm: second step: found %d correspondences\n",count); - -} - diff --git a/sm/csm/gpm/gpm.h b/sm/csm/gpm/gpm.h deleted file mode 100644 index b8d6a29..0000000 --- a/sm/csm/gpm/gpm.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef H_GPM_STRIPPED_DOWN -#define H_GPM_STRIPPED_DOWN - -#include <gsl/gsl_vector.h> -#include <gsl/gsl_histogram.h> -#include "../csm_all.h" - -void ght_find_theta_range(LDP laser_ref, LDP laser_sens, - const double*x0, double max_linear_correction, - double max_angular_correction_deg, int interval, gsl_histogram*hist, int*num_correspondences); - -void ght_one_shot(LDP laser_ref, LDP laser_sens, - const double*x0, double max_linear_correction, - double max_angular_correction_deg, int interval, double*x, int*num_correspondences) ; - -#endif - diff --git a/sm/csm/gpm/gpm_readme.txt b/sm/csm/gpm/gpm_readme.txt deleted file mode 100644 index 60c6cbe..0000000 --- a/sm/csm/gpm/gpm_readme.txt +++ /dev/null @@ -1,7 +0,0 @@ - -This is a stripped-down version of GPM. -It is used here as a first guess to be refined by ICP, so it does not iterate. - -Please see the corresponding paper: - - http://purl.org/censi/2006/gpm \ No newline at end of file diff --git a/sm/csm/hsm/CMakeLists.txt b/sm/csm/hsm/CMakeLists.txt deleted file mode 100644 index 508f2f7..0000000 --- a/sm/csm/hsm/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# This builds the code as itself - -cmake_minimum_required(VERSION 2.4) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -std=c99") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") - - -ADD_EXECUTABLE(hsm_test00 hsm_test00.c hsm.c) diff --git a/sm/csm/hsm/hsm.c b/sm/csm/hsm/hsm.c deleted file mode 100644 index d36881c..0000000 --- a/sm/csm/hsm/hsm.c +++ /dev/null @@ -1,596 +0,0 @@ -#include <stdlib.h> -#include <math.h> -#include <time.h> -#include <assert.h> -#include <time.h> -#include "../csm_all.h" - -#include "hsm.h" - -hsm_buffer hsm_buffer_alloc(struct hsm_params*p) { - assert(p->max_norm>0); - assert(p->linear_cell_size>0); - assert(p->angular_cell_size_deg>0); - assert(p->num_angular_hypotheses >0); - assert(p->linear_xc_max_npeaks>0); - assert(p->xc_ndirections>0); - - hsm_buffer b = (hsm_buffer) malloc(sizeof(struct hsm_buffer_struct)); - - b->num_angular_cells = (int) ceil(360.0 / p->angular_cell_size_deg); - b->num_linear_cells = 1 + 2 * (int) ceil(p->max_norm / p->linear_cell_size); - b->linear_cell_size = p->linear_cell_size; - b->rho_min = - p->max_norm; - b->rho_max = + p->max_norm; - - b->hs = (double*) calloc((size_t)b->num_angular_cells, sizeof(double)); - b->hs_cross_corr = (double*) calloc((size_t)b->num_angular_cells, sizeof(double)); - b->ht = (double**) calloc((size_t)b->num_angular_cells, sizeof(double*)); - - for(int i=0; i<b->num_angular_cells; i++) { - b->ht[i] = (double*) calloc((size_t)b->num_linear_cells, sizeof(double)); - for(int r=0;r<b->num_linear_cells;r++) - b->ht[i][r] = 0; - } - - b->theta = (double*) calloc((size_t)b->num_angular_cells, sizeof(double)); - b->sint = (double*) calloc((size_t)b->num_angular_cells, sizeof(double)); - b->cost = (double*) calloc((size_t)b->num_angular_cells, sizeof(double)); - for(int i=0; i<b->num_angular_cells; i++) { - b->theta[i] = (2 * M_PI * i) / b->num_angular_cells; - b->sint[i] = sin(b->theta[i]); - b->cost[i] = cos(b->theta[i]); - } - - b->hs_cross_corr = (double*) calloc((size_t)b->num_angular_cells, sizeof(double)); - - b->max_num_results = (int) p->num_angular_hypotheses * pow( (float) p->linear_xc_max_npeaks, (float) p->xc_ndirections); - - b->num_valid_results = 0; - b->results = (double**) calloc((size_t)b->max_num_results, sizeof(double*)); - for(int i=0;i<b->max_num_results; i++) - b->results[i] = (double*) calloc(3, sizeof(double)); - - b->results_quality = (double*) calloc((size_t)b->max_num_results, sizeof(double)); - - double zero[3] = {0,0,0}; - hsm_compute_ht_base(b, zero); - - return b; -} - -void hsm_buffer_free(hsm_buffer b) { - - free(b->hs); - for(int i=0; i<b->num_angular_cells; i++) - free(b->ht[i]); - free(b->ht); - - free(b->theta); - free(b->sint); - free(b->cost); - - free(b->hs_cross_corr); - for(int i=0;i<b->max_num_results; i++) - free(b->results[i]); - free(b->results); - - free(b->results_quality); - free(b); -} - -void hsm_compute_ht_base(hsm_buffer b, const double base_pose[3]) { - b->disp[0] = base_pose[0]; - b->disp[1] = base_pose[1]; - b->disp[2] = base_pose[2]; - b->disp_th_cos = cos(base_pose[2]); - b->disp_th_sin = sin(base_pose[2]); -} - -void hsm_compute_ht_point(hsm_buffer b, double x0, double y0, double weight) { - - double x1 = x0 * b->disp_th_cos - y0 * b->disp_th_sin + b->disp[0]; - double y1 = x0 * b->disp_th_sin + y0 * b->disp_th_cos + b->disp[1]; - - for(int i=0; i<b->num_angular_cells; i++) { - double rho = x1 * b->cost[i] + y1 * b->sint[i]; - int rho_index; - double alpha; - if(!hsm_rho2index(b, rho, &rho_index, &alpha)) { - continue; - } - - b->ht[i][rho_index] += (1-fabs(alpha)) * weight; - - if( (alpha > 0) && (rho_index < b->num_linear_cells - 1)) - b->ht[i][rho_index+1] += (fabs(alpha)) * weight; - - if( (alpha < 0) && (rho_index > 0)) - b->ht[i][rho_index-1] += (fabs(alpha)) * weight; - } -} - -double mdax(double a, double b) { - return a>b?a:b; -} - -/** Returns 0 if out of the buffer. rho_index is the closest cell, - alpha between -0.5 and 0.5 specifies the distance from the center of the cell. */ -int hsm_rho2index(hsm_buffer b, double rho, int *rho_index, double *alpha) { - *rho_index = 0; *alpha = NAN; - if ( (rho <= b->rho_min) || (rho >= b->rho_max) ) - return 0; - - /* x belongs to [0, n) */ - double x = b->num_linear_cells * (rho-b->rho_min) / (b->rho_max-b->rho_min); - - if(x==b->num_linear_cells) x*=0.99999; - - *rho_index = (int) floor( x ); - *alpha = (*rho_index+0.5)-x; - - assert(fabs(*alpha) <= 0.5001); - assert(*rho_index >= 0); - assert(*rho_index < b->num_linear_cells); - - return 1; -} - - -void hsm_compute_spectrum(hsm_buffer b) { - for(int t=0; t<b->num_angular_cells; t++) { - b->hs[t] = 0; - for(int r=0;r<b->num_linear_cells;r++) - b->hs[t] = max(b->hs[t], b->ht[t][r]); - } -} - -void hsm_compute_spectrum_norm(hsm_buffer b) { - for(int t=0; t<b->num_angular_cells; t++) { - b->hs[t] = 0; - for(int r=0;r<b->num_linear_cells;r++) - b->hs[t] += b->ht[t][r] * b->ht[t][r]; - } -} - -void hsm_match(struct hsm_params*p, hsm_buffer b1, hsm_buffer b2) { - sm_log_push("hsm_match"); - /* Let's measure the time */ - clock_t hsm_match_start = clock(); - - assert(b1->num_angular_cells == b2->num_angular_cells); - assert(p->max_translation > 0); - assert(b1->linear_cell_size > 0); - - b1->num_valid_results = 0; - - /* Compute cross-correlation of spectra */ - hsm_circular_cross_corr_stupid(b1->num_angular_cells, b2->hs, b1->hs, b1->hs_cross_corr); - - /* Find peaks in cross-correlation */ - int peaks[p->num_angular_hypotheses], npeaks; - hsm_find_peaks_circ(b1->num_angular_cells, b1->hs_cross_corr, p->angular_hyp_min_distance_deg, 0, p->num_angular_hypotheses, peaks, &npeaks); - - sm_debug("Found %d peaks (max %d) in cross correlation.\n", npeaks, p->num_angular_hypotheses); - - if(npeaks == 0) { - sm_error("Cross correlation of spectra has 0 peaks.\n"); - sm_log_pop(); - return; - } - - sm_log_push("loop on theta hypotheses"); - /* lag e' quanto 2 si sposta a destra rispetto a 1 */ - for(int np=0;np<npeaks;np++) { - int lag = peaks[np]; - double theta_hypothesis = lag * (2*M_PI/b1->num_angular_cells); - - sm_debug("Theta hyp#%d: lag %d, angle %fdeg\n", np, lag, rad2deg(theta_hypothesis)); - - /* Superimpose the two spectra */ - double mult[b1->num_angular_cells]; - for(int r=0;r<b1->num_angular_cells;r++) - mult[r] = b1->hs[r] * b2->hs[pos_mod(r-lag, b1->num_angular_cells)]; - - /* Find directions where both are intense */ - int directions[p->xc_ndirections], ndirections; - hsm_find_peaks_circ(b1->num_angular_cells, b1->hs_cross_corr, p->xc_directions_min_distance_deg, 1, p->xc_ndirections, directions, &ndirections); - - if(ndirections<2) { - sm_error("Too few directions.\n"); - } - - #define MAX_NPEAKS 1024 - assert(p->linear_xc_max_npeaks<MAX_NPEAKS); - - struct { - /* Direction of cross correlation */ - double angle; - int nhypotheses; - struct { - double delta; - double value; - // } hypotheses[p->linear_xc_max_npeaks]; - } hypotheses[MAX_NPEAKS]; - } dirs[ndirections]; - - - sm_debug("Using %d (max %d) correlations directions.\n", ndirections, p->xc_ndirections); - - int max_lag = (int) ceil(p->max_translation / b1->linear_cell_size); - int min_lag = -max_lag; - sm_debug("Max lag: %d cells (max t: %f, cell size: %f)\n", - max_lag, p->max_translation, b1->linear_cell_size); - - sm_log_push("loop on xc direction"); - /* For each correlation direction */ - for(int cd=0;cd<ndirections;cd++) { - - dirs[cd].angle = theta_hypothesis + (directions[cd]) * (2*M_PI/b1->num_angular_cells); - - printf(" cd %d angle = %d deg\n", cd, (int) rad2deg(dirs[cd].angle)); - - /* Do correlation */ - int lags [2*max_lag + 1]; - double xcorr [2*max_lag + 1]; - - int i1 = pos_mod(directions[cd] , b1->num_angular_cells); - int i2 = pos_mod(directions[cd] + lag , b1->num_angular_cells); - double *f1 = b1->ht[i1]; - double *f2 = b2->ht[i2]; - - hsm_linear_cross_corr_stupid( - b2->num_linear_cells,f2, - b1->num_linear_cells,f1, - xcorr, lags, min_lag, max_lag); - - /* Find peaks of cross-correlation */ - int linear_peaks[p->linear_xc_max_npeaks], linear_npeaks; - - hsm_find_peaks_linear( - 2*max_lag + 1, xcorr, p->linear_xc_peaks_min_distance/b1->linear_cell_size, - p->linear_xc_max_npeaks, linear_peaks, &linear_npeaks); - - sm_debug("theta hyp #%d: Found %d (max %d) peaks for correlation.\n", - cd, linear_npeaks, p->linear_xc_max_npeaks); - - dirs[cd].nhypotheses = linear_npeaks; - sm_log_push("Considering each peak of linear xc"); - for(int lp=0;lp<linear_npeaks;lp++) { - int linear_xc_lag = lags[linear_peaks[lp]]; - double value = xcorr[linear_peaks[lp]]; - double linear_xc_lag_m = linear_xc_lag * b1->linear_cell_size; - sm_debug("lag: %d delta: %f value: %f \n", linear_xc_lag, linear_xc_lag_m, value); - dirs[cd].hypotheses[lp].delta = linear_xc_lag_m; - dirs[cd].hypotheses[lp].value = value; - } - sm_log_pop(); - - if(p->debug_true_x_valid) { - double true_delta = cos(dirs[cd].angle) * p->debug_true_x[0] + - sin(dirs[cd].angle) * p->debug_true_x[1]; - sm_debug("true_x delta = %f \n", true_delta ); - } - - } /* xc direction */ - sm_log_pop(); - - sm_debug("Now doing all combinations. How many are there?\n"); - int possible_choices[ndirections]; - int num_combinations = 1; - for(int cd=0;cd<ndirections;cd++) { - possible_choices[cd] = dirs[cd].nhypotheses; - num_combinations *= dirs[cd].nhypotheses; - } - sm_debug("Total: %d combinations\n", num_combinations); - sm_log_push("For each combination.."); - for(int comb=0;comb<num_combinations;comb++) { - int choices[ndirections]; - hsm_generate_combinations(ndirections, possible_choices, comb, choices); - - /* Linear least squares */ - double M[2][2]={{0,0},{0,0}}; double Z[2]={0,0}; - /* heuristic quality value */ - double sum_values = 0; - for(int cd=0;cd<ndirections;cd++) { - double angle = dirs[cd].angle; - double c = cos(angle), s = sin(angle); - double w = dirs[cd].hypotheses[choices[cd]].value; - double y = dirs[cd].hypotheses[choices[cd]].delta; - - M[0][0] += c * c * w; - M[1][0] += c * s * w; - M[0][1] += c * s * w; - M[1][1] += s * s * w; - Z[0] += w * c * y; - Z[1] += w * s * y; - - sum_values += w; - } - - double det = M[0][0]*M[1][1]-M[0][1]*M[1][0]; - double Minv[2][2]; - Minv[0][0] = M[1][1] * (1/det); - Minv[1][1] = M[0][0] * (1/det); - Minv[0][1] = -M[0][1] * (1/det); - Minv[1][0] = -M[1][0] * (1/det); - - double t[2] = { - Minv[0][0]*Z[0] + Minv[0][1]*Z[1], - Minv[1][0]*Z[0] + Minv[1][1]*Z[1]}; - - /* copy result in results slot */ - - int k = b1->num_valid_results; - b1->results[k][0] = t[0]; - b1->results[k][1] = t[1]; - b1->results[k][2] = theta_hypothesis; - b1->results_quality[k] = sum_values; - b1->num_valid_results++; - } - sm_log_pop(); - - } /* theta hypothesis */ - sm_log_pop(); - -/* for(int i=0;i<b1->num_valid_results;i++) { - printf("#%d %.0fdeg %.1fm %.1fm quality %f \n",i, - rad2deg(b1->results[i][2]), - b1->results[i][0], - b1->results[i][1], - b1->results_quality[i]); - }*/ - - - /* Sorting based on values */ - int indexes[b1->num_valid_results]; - for(int i=0;i<b1->num_valid_results;i++) - indexes[i] = i; - - qsort_descending(indexes, (size_t) b1->num_valid_results, b1->results_quality); - - /* copy in the correct order*/ - double*results_tmp[b1->num_valid_results]; - double results_quality_tmp[b1->num_valid_results]; - for(int i=0;i<b1->num_valid_results;i++) { - results_tmp[i] = b1->results[i]; - results_quality_tmp[i] = b1->results_quality[i]; - } - - for(int i=0;i<b1->num_valid_results;i++) { - b1->results[i] = results_tmp[indexes[i]]; - b1->results_quality[i] = results_quality_tmp[indexes[i]]; - } - - for(int i=0;i<b1->num_valid_results;i++) { - char near[256]=""; - double *x = b1->results[i]; - if(p->debug_true_x_valid) { - double err_th = rad2deg(fabs(angleDiff(p->debug_true_x[2],x[2]))); - double err_m = hypot(p->debug_true_x[0]-x[0], - p->debug_true_x[1]-x[1]); - const char * ast = (i == 0) && (err_th > 2) ? " ***** " : ""; - sprintf(near, "th err %4d err_m %5f %s",(int)err_th ,err_m,ast); - } - if(i<10) - printf("after #%d %3.1fm %.1fm %3.0fdeg quality %5.0f \t%s\n",i, - x[0], - x[1], rad2deg(x[2]), b1->results_quality[i], near); - } - - - /* How long did it take? */ - clock_t hsm_match_stop = clock(); - int ticks = hsm_match_stop-hsm_match_start; - double ctime = ((double)ticks) / CLOCKS_PER_SEC; - sm_debug("Time: %f sec (%d ticks)\n", ctime, ticks); - - sm_log_pop(); -} - - -void hsm_generate_combinations(int nslots, const int possible_choices[], - int i, int i_choice[]) -{ - for(int slot=0;slot<nslots;slot++) { - i_choice[slot] = i % possible_choices[slot]; - i = (i - i % possible_choices[slot]) / possible_choices[slot]; - } -} - -void hsm_find_peaks_circ(int n, const double*f, double min_angle_deg, int unidir, int max_peaks, - int*peaks, int* npeaks) -{ - sm_log_push("hsm_find_peaks_circ"); - - assert(max_peaks>0); - - /* Find all local maxima for the function */ - int maxima[n], nmaxima; - hsm_find_local_maxima_circ(n, f, maxima, &nmaxima); - - sm_debug("Found %d of %d are local maxima.\n", nmaxima, n); - - /* Sort based on value */ - qsort_descending(maxima, (size_t) nmaxima, f); - - *npeaks = 0; - - sm_log_push("For each maximum"); - /* Only retain a subset of these */ - for(int m=0;m<nmaxima;m++) { - /* Here's a candidate maximum */ - int candidate = maxima[m]; - double candidate_angle = candidate * (2*M_PI/n); - /* Check that is not too close to the already accepted maxima */ - int acceptable = 1; - for(int a=0;a<*npeaks;a++) { - int other = peaks[a]; - double other_angle = other * (2*M_PI/n); - - if(hsm_is_angle_between_smaller_than_deg(candidate_angle,other_angle,min_angle_deg)) { - acceptable = 0; break; - } - - /* If unidir, check also +M_PI */ - if(unidir) - if(hsm_is_angle_between_smaller_than_deg(candidate_angle+M_PI,other_angle,min_angle_deg)) { - acceptable = 0; break; - } - - } - - sm_debug("%saccepting candidate %d; lag = %d value = %f\n", - acceptable?"":"not ", m, maxima[m], f[maxima[m]]); - - if(acceptable) { - peaks[*npeaks] = candidate; - (*npeaks) ++; - } - - if(*npeaks>=max_peaks) break; - } - sm_log_pop(); - - sm_debug("found %d (max %d) maxima.\n", *npeaks, max_peaks); - sm_log_pop(); -} - - -void hsm_find_peaks_linear(int n, const double*f, double min_dist, int max_peaks, - int*peaks, int* npeaks) -{ - sm_log_push("hsm_find_peaks_linear"); - - assert(max_peaks>0); - - /* Find all local maxima for the function */ - int maxima[n], nmaxima; - hsm_find_local_maxima_linear(n,f,maxima,&nmaxima); - - sm_debug("Found %d of %d are local maxima.\n", nmaxima, n); - - /* Sort based on value */ - qsort_descending(maxima, (size_t) nmaxima, f); - - *npeaks = 0; - sm_log_push("for each maximum"); - /* Only retain a subset of these */ - for(int m=0;m<nmaxima;m++) { - /* Here's a candidate maximum */ - int candidate = maxima[m]; - /* Check that is not too close to the already accepted maxima */ - int acceptable = 1; - for(int a=0;a<*npeaks;a++) { - int other = peaks[a]; - - if(abs(other-candidate) < min_dist) { - acceptable = 0; break; - } - } - - sm_debug("%s accepting candidate %d; lag = %d value = %f\n", - acceptable?"":"not", m, maxima[m], f[maxima[m]]); - - if(acceptable) { - peaks[*npeaks] = candidate; - (*npeaks) ++; - } - - if(*npeaks >= max_peaks) break; - } - sm_log_pop(""); - sm_debug("Found %d (max %d) maxima.\n", *npeaks, max_peaks); - - sm_log_pop(); -} - - -int hsm_is_angle_between_smaller_than_deg(double angle1, double angle2, double threshold_deg) { - double dot = cos(angle1)*cos(angle2) + sin(angle1)*sin(angle2); - return (dot > cos(threshold_deg * M_PI/180)); -} - -void hsm_find_local_maxima_circ(int n, const double*f, int*maxima, int*nmaxima) { - *nmaxima = 0; - for(int i=0;i<n;i++) { - double val = f[i]; - double left = f[ pos_mod(i-1,n) ]; - double right = f[ pos_mod(i+1,n) ]; - if( (val>0) && (val>left) && (val>right)) - maxima[(*nmaxima)++] = i; - } -} - - -void hsm_find_local_maxima_linear(int n, const double*f, int*maxima, int*nmaxima) { - *nmaxima = 0; - for(int i=1;i<n-1;i++) { - double val = f[i]; - double left = f[i-1]; - double right = f[i+1]; - if( (val>0) && (val>left) && (val>right)) - maxima[(*nmaxima)++] = i; - } -} - - - -void hsm_circular_cross_corr_stupid(int n, const double *a, const double *b, double*res) { - /* Two copies of f1 */ - double aa[2*n]; - for(int i=0;i<2*n;i++) aa[i] = a[i%n]; - for(int lag=0;lag<n;lag++) { - res[lag] = 0; - for(int j=0;j<n;j++) - res[lag] += b[j] * aa[j+lag]; - } -} - - -void hsm_linear_cross_corr_stupid(int na, const double *a, int nb, const double *b, double*res, int*lags, int min_lag, int max_lag) { - assert(a); - assert(b); - assert(res); - assert(lags); - - for(int l=min_lag;l<=max_lag;l++) { - lags[l-min_lag] = l; - - double r = 0; - for(int j=0; (j<nb) && (j+l<na);j++) { - // j + l >= 0 - if(j+l>=0) - r += b[j] * a[j+l]; - } - - res[l-min_lag] = r; - - } -} - - -const double *qsort_descending_values = 0; - -int compare_descending(const void *index_pt1, const void *index_pt2) { - int i1 = *( (const int*) index_pt1); - int i2 = *( (const int*) index_pt2); - const double * f = qsort_descending_values; - return f[i1] < f[i2] ? +1 : f[i1] == f[i2] ? 0 : -1; -} - -void qsort_descending(int *indexes, size_t nmemb, const double*values) -{ - qsort_descending_values = values; - qsort(indexes, nmemb, sizeof(int), compare_descending); -} - - - -/** Positive modulo */ -int pos_mod(int a, int b) { - return ((a%b)+b)%b; -} - - - diff --git a/sm/csm/hsm/hsm.h b/sm/csm/hsm/hsm.h deleted file mode 100644 index 3caed06..0000000 --- a/sm/csm/hsm/hsm.h +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef H_CSM_HSM -#define H_CSM_HSM - -#include <stdlib.h> -/** Public interface */ - -struct hsm_params { - /** Max norm for the points (m) (used to define Hough domain) */ - double max_norm; - /** Size of a linear cell (m)*/ - double linear_cell_size; - /** Size of an angular cell (deg)*/ - double angular_cell_size_deg; - - /** Number of hypotheses for theta */ - int num_angular_hypotheses; - - /** Minimum distance between angular hypotheses */ - double angular_hyp_min_distance_deg; - - - /** Number of directions to consider to execute crosscorrelation to find T */ - int xc_ndirections; - - /** Minimum distance between said directions */ - double xc_directions_min_distance_deg; - - - /** Number of peakks to consider for each linear correlation */ - int linear_xc_max_npeaks; - - /** Minimum distance between said peaks */ - double linear_xc_peaks_min_distance; - - - - double max_translation; - - /** For debugging purpose, set this to 1 and fill next field */ - int debug_true_x_valid; - /** True result, used for debugging purposes */ - double debug_true_x[3]; -}; - - -struct hsm_buffer_struct { - /** Fields used for computing */ - - /** Length of hs,theta,sint,cost,etc.*/ - int num_angular_cells; - - /** Num of cells for rho */ - int num_linear_cells; - - /** Size of a cell for rho */ - double linear_cell_size; - - /** Interval for rho */ - double rho_min, rho_max; - - /** Hough Transform. Access as: ht[theta][rho] */ - double **ht; - - /** Hough Spectrum */ - double *hs; - - /** Results */ - - /** Size of results array */ - int max_num_results; - - /** Number of valid entries in the results array */ - int num_valid_results; - - /** List of poses; theta = results[i][2] */ - double **results; - - /** Quality of results */ - double *results_quality; - - - /** Private fields */ - double *theta; - - /** Used during computation of HT */ - double *sint,*cost; - - /** Used during matching */ - double *hs_cross_corr; - - /** Displacement to be added. See function hsm_compute_ht_base */ - double disp[3]; - double disp_th_cos, disp_th_sin; -}; - -typedef struct hsm_buffer_struct* hsm_buffer; - - - /** Allocates the buffer structures. Remember to call hsm_buffer_free afterwards */ - hsm_buffer hsm_buffer_alloc(struct hsm_params*); - - /** Frees the buffer structure */ - void hsm_buffer_free(hsm_buffer); - - /** Adds a point to the Hough Transform */ - void hsm_compute_ht_point(hsm_buffer, double x, double y, double weight); - - - void hsm_match(struct hsm_params*p, hsm_buffer b1, hsm_buffer b2); - - /** Private interface */ - - /** This adds a base displacement to the point added by hsm_compute_ht_point */ - void hsm_compute_ht_base(hsm_buffer, const double base_pose[3]); - - /** Computes the spectrum in the buffer */ - void hsm_compute_spectrum(hsm_buffer); - - void hsm_compute_spectrum_norm(hsm_buffer b); - - /** Finds the local maxima for a circular function. - @maxima is a pointer to a struct of size n - @nmaxima returns the number of maxima found */ - void hsm_find_local_maxima_circ(int n, const double*f, int*maxima, int*nmaxima); - - /** Returns true if @angle1 (rad) and @angle2 (rad) are closer than @threshold_deg (degrees!) */ - int hsm_is_angle_between_smaller_than_deg(double angle1, double angle2, double threshold_deg); - - - /** Returns 0 if out of the buffer. rho_index is the closest cell, - alpha between -0.5 and 0.5 specifies the distance from the center of the cell. */ - int hsm_rho2index(hsm_buffer b, double rho, int *rho_index, double *alpha); - - /** Creates circular cross-correlation in a stupid way */ - void hsm_circular_cross_corr_stupid(int n, const double *a, const double *b, double*res); - - /** Finds the peaks of a circular function @f of length @n. */ - void hsm_find_peaks_circ(int n, const double*f, double min_angle_deg, int unidir, int max_peaks, - int*peaks, int* npeaks) ; - - void hsm_find_peaks_linear(int n, const double*f, double min_dist, int max_peaks, - int*peaks, int* npeaks); - void hsm_find_local_maxima_linear(int n, const double*f, int*maxima, int*nmaxima); - - void hsm_linear_cross_corr_stupid(int na, const double *a, int nb, const double *b, double*res, int*lags, int min_lag, int max_lag); - - void hsm_generate_combinations(int nslots, const int possible_choices[], - int i, int i_choice[]) ; - - /* a mod b >= 0 */ - int pos_mod(int a, int b); - - /** Sorts the indexes based on the values */ - void qsort_descending(int *indexes, size_t nmemb, const double*values); - - /* used by qsort_descending */ - int compare_descending(const void *index_pt1, const void *index_pt2); - - -#endif diff --git a/sm/csm/hsm/hsm_interface.c b/sm/csm/hsm/hsm_interface.c deleted file mode 100644 index 2022bf6..0000000 --- a/sm/csm/hsm/hsm_interface.c +++ /dev/null @@ -1,126 +0,0 @@ -#include <options/options.h> -#include <assert.h> - -#include "../csm_all.h" - -void hsm_add_options(struct option* ops, struct hsm_params*p) { - options_double(ops, "hsm_linear_cell_size", &p->linear_cell_size, 0.03, "HSM: Size of a rho cell"); - options_double(ops, "hsm_angular_cell_size_deg", &p->angular_cell_size_deg, 1.0, "HSM: Size of angualar cell (deg)"); - options_int(ops, "hsm_num_angular_hypotheses", &p->num_angular_hypotheses, 8, "HSM: Number of angular hypotheses."); - options_double(ops, "hsm_xc_directions_min_distance_deg", &p->xc_directions_min_distance_deg, 10.0, "HSM: Min distance between directions for cross corr (deg)"); - options_int(ops, "hsm_xc_ndirections", &p->xc_ndirections, 3, "HSM: Number of directions for cross corr (deg)"); - options_double(ops, "hsm_angular_hyp_min_distance_deg", &p->angular_hyp_min_distance_deg, 10.0, "HSM: Min distance between different angular hypotheses (deg)"); - - options_int(ops, "hsm_linear_xc_max_npeaks", &p->linear_xc_max_npeaks, 5, "HSM: Number of peaks per direction for linear translation"); - options_double(ops, "hsm_linear_xc_peaks_min_distance", &p->linear_xc_peaks_min_distance, 5.0, "HSM: Min distance between different peaks in linear correlation"); -} - -int hsm_compute_ht_for_scan(LDP ld, struct hsm_params*p, const double base[3], hsm_buffer *b); - -int hsm_compute_ht_for_scan(LDP ld, struct hsm_params*p, const double base[3], hsm_buffer *b) { - *b = 0; - - /** Find maximum reading for the points */ - double max_reading = max_in_array(ld->readings, ld->nrays); - - if(!(max_reading>0)) { - sm_error("No valid points.\n"); - return 0; - } - - p->max_norm = norm_d(base) + max_reading; - - *b = hsm_buffer_alloc(p); - hsm_compute_ht_base(*b, base); - - ld_compute_cartesian(ld); - int np = 0; - for(int i=0; i<ld->nrays; i++) { - if(!ld_valid_ray(ld, i)) continue; - - hsm_compute_ht_point(*b, ld->points[i].p[0], ld->points[i].p[1], 1.0); - - np++; - } - - sm_debug("Computed HT with %d points.\n", np); - if(np<5) { - hsm_buffer_free(*b); - *b = 0; - return 0; - } else { - return 1; - } -} - -void sm_hsm(struct sm_params* params, struct sm_result* res) { - res->valid = 0; - - params->first_guess[0]=0.2; - params->first_guess[1]=0; - params->first_guess[2]=0; - - - /* use true information if present */ - int has_true1 = !any_nan(params->laser_ref->true_pose, 3); - int has_true2 = !any_nan(params->laser_sens->true_pose, 3); - if(has_true1 && has_true2) { - params->hsm.debug_true_x_valid = 1; - - double true_x[3]; - pose_diff_d(params->laser_sens->true_pose, params->laser_ref->true_pose, true_x); - - /* This is the difference between results and true_x */ - pose_diff_d(true_x, params->first_guess, params->hsm.debug_true_x); - - } else { - params->hsm.debug_true_x_valid = 0; - } - - double zero[3] = {0,0,0}; - hsm_buffer b1, b2; - int ok1 = hsm_compute_ht_for_scan(params->laser_ref, &(params->hsm), zero, &b1); - int ok2 = hsm_compute_ht_for_scan(params->laser_sens,&(params->hsm), params->first_guess, &b2); - - if(!ok1 || !ok2) { - sm_error("Could not compute buffers (too few points?).\n"); - if(b1) hsm_buffer_free(b1); - if(b2) hsm_buffer_free(b2); - return; - } - - hsm_compute_spectrum(b1); - hsm_compute_spectrum(b2); - - params->hsm.max_translation = max(b1->rho_max, b2->rho_max); - - hsm_match(&(params->hsm),b1,b2); - - - if(b1->num_valid_results) { - res->valid = 1; - double pl[3]; - double d2[3]; - - pose_diff_d(params->first_guess, b1->results[0], res->x); - pose_diff_d(b1->results[0], params->first_guess, d2); - oplus_d(params->first_guess, b1->results[0], pl); - - sm_info("hsm: odo = %s\n", friendly_pose(params->first_guess)); - sm_info("hsm: res = %s\n", friendly_pose(b1->results[0])); - sm_info("hsm: plus = %s\n", friendly_pose(pl)); - sm_info("hsm: d2 = %s\n", friendly_pose(d2)); - sm_info("hsm: xmin = %s\n", friendly_pose(res->x)); - res->error = 0; - res->iterations = 0; - res->nvalid = 0; - } else { - sm_error("HSM did not produce any result.\n"); - res->valid = 0; - } - - - hsm_buffer_free(b1); - hsm_buffer_free(b2); -} - diff --git a/sm/csm/hsm/hsm_interface.h b/sm/csm/hsm/hsm_interface.h deleted file mode 100644 index b914501..0000000 --- a/sm/csm/hsm/hsm_interface.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef H_HSM_INTERFACE -#define H_HSM_INTERFACE - -#include <options/options.h> - -#include "hsm.h" - -struct sm_params; -struct sm_result; - -/* Interface of HSM for CSM */ -void sm_hsm(struct sm_params* params, struct sm_result* res); - -/** Adds options related to HSM */ -void hsm_add_options(struct option* ops, struct hsm_params*p); - -#endif diff --git a/sm/csm/hsm/hsm_test00.c b/sm/csm/hsm/hsm_test00.c deleted file mode 100644 index e110e25..0000000 --- a/sm/csm/hsm/hsm_test00.c +++ /dev/null @@ -1,185 +0,0 @@ -#include <string.h> -#include <pgm.h> -#include <options/options.h> - -#include <csm/csm_all.h> - -#include "hsm.h" -#include "hsm_interface.h" - -const char * banner = - "Reads an image, computes HT, de-computes it \n\n"; - -struct { - const char * file_input1; - const char * file_input2; - - const char * prefix; - int debug; - - struct hsm_params hsmp; - -} p; - -hsm_buffer create_ht_for_image(struct hsm_params*p, FILE*in, const double base[3]); -void write_ht_on_image(hsm_buffer b, FILE*out); -void write_function_on_image(int n, const double*f, int rows, FILE*out); - - -int main(int argc, const char**argv) { - pgm_init(&argc, argv); - options_banner(banner); - - - struct option* ops = options_allocate(20); - options_string(ops, "in1", &p.file_input1, "stdin", "Input file 1"); - options_string(ops, "in2", &p.file_input2, "", "Input file 2"); - options_string(ops, "out", &p.prefix, "test00", "Output file prefix "); - - hsm_add_options(ops, &p.hsmp); - p.hsmp.linear_cell_size = 1; /* 1 pixel */ - - options_int(ops, "debug", &p.debug, 0, "Shows debug information"); - - if(!options_parse_args(ops, argc, argv)) { - options_print_help(ops, stderr); - return -1; - } - - sm_debug_write(p.debug); - - - FILE * in1 = open_file_for_reading(p.file_input1); if(!in1) return -2; - - sm_debug("Computing HT for image %s.\n", p.file_input1); - - hsm_buffer b1 = create_ht_for_image(&(p.hsmp), in1, 0); if(!b1) return -3; - hsm_compute_spectrum(b1); - - - if(!strcmp(p.file_input2,"")) { - p.file_input2 = p.file_input1; - p.hsmp.debug_true_x_valid = 1; - p.hsmp.debug_true_x[0] = 20; - p.hsmp.debug_true_x[1] = 50; - p.hsmp.debug_true_x[2] = 0; /*deg2rad(40.0);*/ - } else { - p.hsmp.debug_true_x_valid = 0; - } - - FILE * in2 = open_file_for_reading(p.file_input2); if(!in2 ) return -2; - sm_debug("Computing HT for image %s.\n", p.file_input2); - double *base = p.hsmp.debug_true_x_valid ? p.hsmp.debug_true_x : 0; - hsm_buffer b2 = create_ht_for_image(&(p.hsmp), in2, base); if(!b2) return -3; - hsm_compute_spectrum(b2); - - - - sm_debug("Doing scan-matching..\n"); - p.hsmp.max_translation = max(b1->rho_max, b2->rho_max); - - hsm_match(&(p.hsmp),b1,b2); - - char filename_ht1[256]; sprintf(filename_ht1, "%s_ht1.pgm", p.prefix); - char filename_ht2[256]; sprintf(filename_ht2, "%s_ht2.pgm", p.prefix); - char filename_hs1[256]; sprintf(filename_hs1, "%s_hs1.pgm", p.prefix); - char filename_hs2[256]; sprintf(filename_hs2, "%s_hs2.pgm", p.prefix); - char filename_hs_xc[256]; sprintf(filename_hs_xc, "%s_hs_xc.pgm", p.prefix); - - FILE * file_ht1 = open_file_for_writing(filename_ht1); - FILE * file_ht2 = open_file_for_writing(filename_ht2); - FILE * file_hs1 = open_file_for_writing(filename_hs1); - FILE * file_hs2 = open_file_for_writing(filename_hs2); - FILE * file_hs_xc = open_file_for_writing(filename_hs_xc); - - if(!file_ht1 | !file_ht2) return -4; - if(!file_hs1 | !file_hs2) return -4; - if(!file_hs_xc) return -5; - - write_ht_on_image(b1,file_ht1); - write_ht_on_image(b2,file_ht2); - write_function_on_image(b1->num_angular_cells, b1->hs, 200, file_hs1); - write_function_on_image(b2->num_angular_cells, b2->hs, 200, file_hs2); - write_function_on_image(b1->num_angular_cells, b1->hs_cross_corr, 200, file_hs_xc); - - -} - - -void write_function_on_image(int n, const double*f, int rows, FILE*out) { - int cols = n; - gray ** grays = pgm_allocarray(cols, rows); - - double maxvalue=0; - for(int i=0;i<n;i++) - if(f[i]>0) /* case NAN */ - maxvalue = GSL_MAX(maxvalue, f[i]); - if(maxvalue==0)maxvalue=1; - - gray maxgray = 255; - - for(int y=0;y<rows;y++) - for(int x=0;x<cols;x++) - grays[y][x] = 0; - - for(int x=0;x<cols;x++) { - int y = round((rows-2)*f[x]/maxvalue); - y = (rows-1) - y; - if(y>=0 && y<rows ) - grays[y][x] = maxgray; - } - - pgm_writepgm(out,grays,cols,rows,maxgray,0); - - pgm_freearray(grays,rows); -} - - -void write_ht_on_image(hsm_buffer b, FILE*out) { - int rows = b->num_angular_cells; - int cols = b->num_linear_cells; - gray ** grays = pgm_allocarray(cols, rows); - - double maxvalue=0; - for(int t=0;t<b->num_angular_cells;t++) - for(int r=0;r<b->num_linear_cells;r++) - maxvalue = GSL_MAX(maxvalue, b->ht[t][r]); - - gray maxgray = 255; - - for(int t=0;t<b->num_angular_cells;t++) - for(int r=0;r<b->num_linear_cells;r++) - grays[t][r] = (gray) ceil(b->ht[t][r] * (maxgray-1) / maxvalue); - - pgm_writepgm(out,grays,cols,rows,maxgray,0); - - pgm_freearray(grays,rows); -} - -hsm_buffer create_ht_for_image(struct hsm_params*p, FILE*in, const double base[3]) { - int cols, rows; gray max; - gray **image = pgm_readpgm(in, &cols, &rows, &max); - if(!image) { return 0; } - - p->max_norm = 1.1 * hypot(cols/2.0, rows/2.0); - hsm_buffer b = hsm_buffer_alloc(p); - - /** Add base displacement if specified */ - if(base) - hsm_compute_ht_base(b, base); - - int npoints = 0; - for (int v=0; v<rows; v++) - for (int u=0; u<cols; u++) { - double x = u - cols/2; - double y = v - rows/2; - if(image[v][u]==0) continue; - hsm_compute_ht_point(b, x, y, ((double)image[v][u])/max); - npoints ++; - } - sm_debug("Used %d points.\n", npoints); - /* write the modified image to stdout */ -/* pgm_writepgm(stdout, image, cols, rows, max, 1); */ - pgm_freearray(image, rows); - return b; -} diff --git a/sm/csm/hsm/hsm_test01.c b/sm/csm/hsm/hsm_test01.c deleted file mode 100644 index e69de29..0000000 diff --git a/sm/csm/hsm/tests/hsmtest.sh b/sm/csm/hsm/tests/hsmtest.sh deleted file mode 100755 index 0c3d4a5..0000000 --- a/sm/csm/hsm/tests/hsmtest.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e # exit on error - - -make -C ../../../ - -convert tunnel1.png tunnel1.pgm -convert tunnel2.png tunnel2.pgm - -rm hsm0* - -../../../hsm_test00 -debug 1 -in1 tunnel2.pgm -in2 tunnel1.pgm -out hsm0 - -for a in hsm0*pgm; do convert $a $a.png; done - - -open hsm0*png - diff --git a/sm/csm/hsm/tests/hsmtest2.sh b/sm/csm/hsm/tests/hsmtest2.sh deleted file mode 100755 index 89e539c..0000000 --- a/sm/csm/hsm/tests/hsmtest2.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -e # exit on error - - -make -C ../../../ - -convert tunnel1.png tunnel1.pgm -convert tunnel2.png tunnel2.pgm - -rm -f hsm2* - -echo Self test -../../../hsm_test00 -debug 1 -in1 tunnel2.pgm -out hsm2 -hsm_num_angular_hypotheses 2 - -for a in hsm2*pgm; do convert $a $a.png; done - - -open hsm2*png - diff --git a/sm/csm/hsm/tests/tunnel1.png b/sm/csm/hsm/tests/tunnel1.png deleted file mode 100644 index 3d63985fef639603edc67f75183b0a1eeb04cff9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33064 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 diff --git a/sm/csm/hsm/tests/tunnel2.png b/sm/csm/hsm/tests/tunnel2.png deleted file mode 100644 index 7ffeca4239105a79b7b93854175cea8b2937c9f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44606 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 V@&|8f1$+`AFQf7REB)-v{{Z?IcgFw# diff --git a/sm/csm/icp/fast_math.h b/sm/csm/icp/fast_math.h deleted file mode 100644 index e69de29..0000000 diff --git a/sm/csm/json_journal.c b/sm/csm/json_journal.c deleted file mode 100644 index dec197a..0000000 --- a/sm/csm/json_journal.c +++ /dev/null @@ -1,115 +0,0 @@ -#include <assert.h> -#include "json_journal.h" - - -#define MAX_STACK 1000 - -static JO jj_stack[MAX_STACK]; -static int jj_stack_index = -1; -static FILE * jj_file = 0; - - -int jj_enabled() { - return jj_file != 0; -} - -JO jj_stack_top() { - assert(jj_stack_index>=0); - return jj_stack[jj_stack_index]; -} - -void jj_stack_push(JO jo) { - assert(jj_stack_index<MAX_STACK); - jj_stack[++jj_stack_index] = jo; -} - -void jj_stack_pop() { -/* fprintf(stderr, "jj_stack_pop %d\n", jj_stack_index); */ - assert(jj_stack_index>=0); - if(jj_stack_index == 0 && jj_file) { - fprintf(jj_file, "%s\n", json_object_to_json_string(jj_stack_top())); - jo_free(jj_stack_top()); - } - jj_stack_index--; -} - -void jj_context_enter(const char*context_name) { -/* fprintf(stderr, "jj_context_enter('%s') %d\n", context_name, jj_stack_index); */ - - JO jo = json_object_new_object(); - if(jj_stack_index>=0) - jo_add(jj_stack_top(), context_name, jo); - - jj_stack_push(jo); -} - - - -void jj_must_be_hash() { - assert(json_object_is_type(jj_stack_top(), (enum json_type) json_type_object)); -} - -void jj_must_be_array() { - assert(json_object_is_type(jj_stack_top(), (enum json_type) json_type_array)); -} - -void jj_context_exit() { - jj_must_be_hash(); - jj_stack_pop(); -} - -void jj_loop_enter(const char*loop_name) { - jj_must_be_hash(); - JO jo = json_object_new_array(); - jo_add(jj_stack_top(), loop_name, jo); - jj_stack_push(jo); -} - -void jj_loop_iteration() { - JO this_iteration = json_object_new_object(); - if(!json_object_is_type(jj_stack_top(), (enum json_type) json_type_array)) { - jj_stack_pop(); - jj_must_be_array(); - } - json_object_array_add(jj_stack_top(), this_iteration); - jj_stack_push(this_iteration); -} - -void jj_loop_exit() { - if(!json_object_is_type(jj_stack_top(), (enum json_type) json_type_array)) - jj_stack_pop(); - - jj_must_be_array(); - jj_stack_pop(); -} - -void jj_add_int(const char*name, int v) { - jj_must_be_hash(); - jo_add(jj_stack_top(), name, jo_new_int(v)); -} - -void jj_add_double(const char*name, double v) { - jj_must_be_hash(); - jo_add(jj_stack_top(), name, jo_double_or_null(v)); -} - -void jj_add_double_array(const char *name, double *v, int n) { - jj_add(name, jo_new_double_array(v, n)); -} - -void jj_add_int_array(const char*name, int* v, int n) { - jj_add(name, jo_new_int_array(v, n)); -} - -void jj_add(const char*name, JO jo) { - jj_must_be_hash(); - jo_add(jj_stack_top(), name, jo); -} - -void jj_set_stream(FILE* f) { - jj_file = f; -} - -FILE * jj_get_stream() { - return jj_file; -} diff --git a/sm/csm/json_journal.h b/sm/csm/json_journal.h deleted file mode 100644 index a93afa9..0000000 --- a/sm/csm/json_journal.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef H_JSON_JOURNAL -#define H_JSON_JOURNAL - -#include <stdio.h> - -#include <json-c/json.h> -#include <json-c/json_more_utils.h> - -#include "laser_data_json.h" - - -/** This is a collection of functions for debugging purposes only. - It's a little cryptic, but if you don't understand them, don't worry. - - The information used by this is used primarily to create the - icp animation videos. -*/ - -/** Public interface */ - - #define JJ jj_enabled() - int jj_enabled(void); - - void jj_context_enter(const char*context_name); - void jj_context_exit(void); - - void jj_loop_enter(const char*loop_name); - void jj_loop_iteration(void); - void jj_loop_exit(void); - - void jj_add_int(const char*name, int); - void jj_add_double(const char*name, double); - void jj_add_double_array(const char*name, double*,int); - void jj_add_int_array(const char*name, int*,int); - void jj_add(const char*name, JO); - - void jj_set_stream(FILE*); - FILE* jj_get_stream(void); - -/**** Private functions */ - - /** (private) Gets the top of the stack. */ - JO jj_stack_top(void); - /** (private) Pushes an object onto the stack. */ - void jj_stack_push(JO jo); - void jj_stack_pop(void); - /** (private) Asserts if the stack top is not an hash. */ - void jj_must_be_hash(void); - /** (private) Asserts if the stack top is not an array. */ - void jj_must_be_array(void); - - -#endif diff --git a/sm/csm/laser_data_bbox.c b/sm/csm/laser_data_bbox.c deleted file mode 100644 index 1e5f777..0000000 --- a/sm/csm/laser_data_bbox.c +++ /dev/null @@ -1,260 +0,0 @@ -/* This algorithm was created by Cyrill Stachniss - http://www.informatik.uni-freiburg.de/~stachnis/ */ -#include "laser_data_drawing.h" -#include "math_utils.h" -#include "logging.h" - -// the 2d-point structure for the input -typedef struct { - double x; - double y; -} BB_Point; - -// computes the area of minimal bounding box for a set of 2d-points -double getBoundingBoxArea(BB_Point* p, int nOfPoints); - -// computes the minimal bounding box for a set of 2d-points -// ul = upper left point, ll = lower left point, -// ur = upper right point, ul = upper left point -int getBoundingBox(BB_Point* p, int nOfPoints, - double ul[2], double ur[2], double ll[2], double lr[2]); - -struct bbfind_imp { - int num; - - int buf_size; - BB_Point * buf; -}; - -/* Initialize structure */ -bbfind * bbfind_new(void); - -/* -------------------------------------- */ - -bbfind * bbfind_new() { - bbfind * bbf = malloc(sizeof(bbfind)); - bbf->buf_size = 1000; - bbf->buf = malloc(sizeof(BB_Point)*bbf->buf_size); - bbf->num = 0; - return bbf; -} - -int bbfind_add_point(bbfind*bbf, double point[2]) { - return bbfind_add_point2(bbf, point[0], point[1]); -} - -int bbfind_add_point2(bbfind*bbf, double x, double y) { - if(bbf->num > bbf->buf_size - 2) { - bbf->buf_size *= 2; - if(! (bbf->buf = (BB_Point*) realloc(bbf->buf, sizeof(BB_Point)*bbf->buf_size)) ) { - sm_error("Cannot allocate (size=%d)\n", bbf->buf_size); - return 0; - } - } - bbf->buf[bbf->num].x = x; - bbf->buf[bbf->num].y = y; - bbf->num++; - return 1; -} - -void oriented_bbox_compute_corners(const BB2 obbox, - double ul[2], double ur[2], double ll[2], double lr[2]) { - - ll[0] = obbox->pose[0]; - ll[1] = obbox->pose[1]; - lr[0] = obbox->pose[0] + obbox->size[0] * cos(obbox->pose[2]); - lr[1] = obbox->pose[1] + obbox->size[0] * sin(obbox->pose[2]); - ul[0] = obbox->pose[0] + obbox->size[1] * cos(obbox->pose[2] + M_PI/2); - ul[1] = obbox->pose[1] + obbox->size[1] * sin(obbox->pose[2] + M_PI/2); - ur[0] = ul[0] + obbox->size[0] * cos(obbox->pose[2]); - ur[1] = ul[1] + obbox->size[0] * sin(obbox->pose[2]); - -} - -int bbfind_add_bbox(bbfind*bbf, const BB2 bbox) { - double ul[2], ur[2], ll[2], lr[2]; - oriented_bbox_compute_corners(bbox, ul, ur, ll, lr); - return - bbfind_add_point(bbf, ul) && - bbfind_add_point(bbf, ur) && - bbfind_add_point(bbf, ll) && - bbfind_add_point(bbf, lr); -} - - -int bbfind_compute(bbfind*bbf, BB2 bbox) { - double ul[2], ur[2], ll[2], lr[2]; - - if(1) { - if(!getBoundingBox(bbf->buf, bbf->num, ul, ur, ll, lr)) { - sm_error("Could not compute bounding box.\n"); - return 0; - } - bbox->pose[0] = ll[0]; - bbox->pose[1] = ll[1]; - bbox->pose[2] = atan2(lr[1]-ll[1], lr[0]-ll[0]); - bbox->size[0] = distance_d(lr, ll); - bbox->size[1] = distance_d(ll, ul); - } else { - double bb_min[2] = {bbf->buf[0].x,bbf->buf[0].y}, - bb_max[2] = {bbf->buf[0].x,bbf->buf[0].y}; - int i; for(i=0;i<bbf->num; i++) { - bb_min[0] = GSL_MIN(bb_min[0], bbf->buf[i].x); - bb_min[1] = GSL_MIN(bb_min[1], bbf->buf[i].y); - bb_max[0] = GSL_MAX(bb_max[0], bbf->buf[i].x); - bb_max[1] = GSL_MAX(bb_max[1], bbf->buf[i].y); - } - bbox->pose[0] = bb_min[0]; - bbox->pose[1] = bb_min[1]; - bbox->pose[2] = 0; - bbox->size[0] = bb_max[0] - bb_min[0]; - bbox->size[1] = bb_max[1] - bb_min[1]; - } - return 1; -} - -void bbfind_free(bbfind* bbf) { - free(bbf->buf); - free(bbf); -} - -void ld_get_oriented_bbox(LDP ld, double horizon, oriented_bbox*obbox) { - bbfind * bbf = bbfind_new(); - int i; for(i=0;i<ld->nrays;i++) { - if(!ld->valid[i]) continue; - if(ld->readings[i]>horizon) continue; - - double p0[2] = { - cos(ld->theta[i]) * ld->readings[i], - sin(ld->theta[i]) * ld->readings[i] - }; - - bbfind_add_point(bbf, p0); - } - bbfind_compute(bbf, obbox); - bbfind_free(bbf); -} - -// computes the area of minimal bounding box for a set of 2d-points -double getBoundingBoxArea(BB_Point* p, int nOfPoints) { - double ul[2], ur[2], ll[2], lr[2]; - - int wasOk = getBoundingBox(p, nOfPoints, ul, ur, ll, lr); - double vol = (!wasOk) ? -1.0 : distance_d(ul,ll)*distance_d(ul,ur); - return vol; -} - -// computes the minimal bounding box for a set of 2d-points -// ul = upper left point, ll = lower left point, -// ur = upper right point, ul = upper left point -int getBoundingBox(BB_Point* p, int nOfPoints, - double ul[2], double ur[2], double ll[2], double lr[2]) { - - // calculate the center of all points (schwerpunkt) - // ------------------------------------------------- - double centerx = 0; - double centery = 0; - for (int i=0; i < nOfPoints; i++) { - centerx += p[i].x; - centery += p[i].y; - } - centerx /= (double) nOfPoints; - centery /= (double) nOfPoints; - - - - // calcutae the covariance matrix - // ------------------------------- - // covariance matrix (x1 x2, x3 x4) - double x1 = 0.0; - double x2 = 0.0; - double x3 = 0.0; - double x4 = 0.0; - - for (int i=0; i < nOfPoints; i++) { - double cix = p[i].x - centerx; - double ciy = p[i].y - centery; - - x1 += cix*cix; - x2 += cix*ciy; - x4 += ciy*ciy; - } - x1 /= (double) nOfPoints; - x2 /= (double) nOfPoints; - x3 = x2; - x4 /= (double) nOfPoints; - // covariance & center done - - - // calculate the eigenvectors - // --------------------------- - // catch 1/0 or sqrt(<0) - if ((x3 == 0) || (x2 == 0)|| (x4*x4-2*x1*x4+x1*x1+4*x2*x3 < 0 )) { - sm_error("Cyrill: Could not compute bounding box.\n"); - return 0; -} - - // eigenvalues - double lamda1 = 0.5* (x4 + x1 + sqrt(x4*x4 - 2.0*x1*x4 + x1*x1 + 4.0*x2*x3)); - double lamda2 = 0.5* (x4 + x1 - sqrt(x4*x4 - 2.0*x1*x4 + x1*x1 + 4.0*x2*x3)); - - // eigenvector 1 with (x,y) - double v1x = - (x4-lamda1) * (x4-lamda1) * (x1-lamda1) / (x2 * x3 * x3); - double v1y = (x4-lamda1) * (x1-lamda1) / (x2 * x3); - // eigenvector 2 with (x,y) - double v2x = - (x4-lamda2) * (x4-lamda2) * (x1-lamda2) / (x2 * x3 * x3); - double v2y = (x4-lamda2) * (x1-lamda2) / (x2 * x3); - - // norm the eigenvectors - double lv1 = sqrt ( (v1x*v1x) + (v1y*v1y) ); - double lv2 = sqrt ( (v2x*v2x) + (v2y*v2y) ); - v1x /= lv1; - v1y /= lv1; - v2x /= lv2; - v2y /= lv2; - // eigenvectors done - - // get the points with maximal dot-product - double x = 0.0; - double y = 0.0; - double xmin = 1e20; - double xmax = -1e20; - double ymin = 1e20; - double ymax = -1e20; - for(int i = 0; i< nOfPoints; i++) { - // dot-product of relativ coordinates of every point - x = (p[i].x - centerx) * v1x + (p[i].y - centery) * v1y; - y = (p[i].x - centerx) * v2x + (p[i].y - centery) * v2y; - - if( x > xmax) xmax = x; - if( x < xmin) xmin = x; - if( y > ymax) ymax = y; - if( y < ymin) ymin = y; - } - - // now we can compute the corners of the bounding box - if(ul) { - ul[0] = centerx + xmin * v1x + ymin * v2x; - ul[1] = centery + xmin * v1y + ymin * v2y; - } - - if(ur) { - ur[0] = centerx + xmax * v1x + ymin * v2x; - ur[1] = centery + xmax * v1y + ymin * v2y; - } - - if(ll) { - ll[0] = centerx + xmin * v1x + ymax * v2x; - ll[1] = centery + xmin * v1y + ymax * v2y; - } - - if(lr) { - lr[0] = centerx + xmax * v1x + ymax * v2x; - lr[1] = centery + xmax * v1y + ymax * v2y; - } - return 1; -} - - - - diff --git a/sm/csm/laser_data_cairo.c b/sm/csm/laser_data_cairo.c deleted file mode 100644 index 92b468d..0000000 --- a/sm/csm/laser_data_cairo.c +++ /dev/null @@ -1,397 +0,0 @@ - -#include <string.h> - -#include <cairo-pdf.h> -#include <stdlib.h> -#include <limits.h> - -#include "laser_data_cairo.h" - -const char* cat(const char*a, const char*b); -void cr_ld_draw_rays(cairo_t*, LDP); -void cr_ld_draw_countour(cairo_t*, LDP, double, double); -void cr_ld_draw_points(cairo_t*, LDP, double radius); -void cr_ld_draw_normals(cairo_t*cr, LDP ld, double length); - - - -/* ----------------------------------------------- */ - -void cr_ld_draw_corr(cairo_t*cr, LDP laser_ref, LDP laser_sens) { - int i; - for(i=0; i < laser_sens->nrays; i++) { - if(!ld_valid_corr(laser_sens, i)) continue; - - if(!laser_sens->corr[i].valid) continue; - - int j1 = laser_sens->corr[i].j1; - int j2 = laser_sens->corr[i].j2; - - const double *p_j1 = laser_ref->points[j1].p; - const double *p_j2 = laser_ref->points[j2].p; - const double *p_i_w = laser_sens->points_w[i].p; - double proj[2]; - - if(laser_sens->corr[i].type == corr_pl) - projection_on_line_d(p_j1, p_j2, p_i_w, proj, 0); - else - projection_on_segment_d(p_j1, p_j2, p_i_w, proj); - - cairo_move_to(cr, p_i_w[0], p_i_w[1]); - cairo_line_to(cr, proj[0], proj[1]); - cairo_stroke(cr); - } -} - -const char* cat(const char*a, const char*b) { - size_t la = strlen(a); - size_t lb = strlen(b); - char* buf = malloc(la+lb+3); - strcpy(buf, a); - strcpy(buf+la, b); - return buf; -} - -void ls_add_options(line_style*ls, struct option*ops, - const char*prefix, const char*desc_prefix) -{ - options_int(ops, cat(prefix, "draw"), &(ls->draw), - ls->draw, cat(desc_prefix, "Whether to draw it (0,1)")); - - options_string(ops, cat(prefix, "color"), &(ls->color), - ls->color, cat(desc_prefix, "Color ('red', '#f00')")); - - options_double(ops, cat(prefix, "width"), &(ls->width), - ls->width, cat(desc_prefix, "line width (meters)")); - -} - - -void lds_add_options(ld_style*lds, struct option*ops, - const char*prefix, const char*desc_prefix) -{ - ls_add_options(&(lds->rays), ops, cat(prefix, "rays_"), cat(desc_prefix, "Rays | ")); - ls_add_options(&(lds->countour), ops, cat(prefix, "countour_"), cat(desc_prefix, "Countour | ")); - ls_add_options(&(lds->points), ops, cat(prefix, "points_"), cat(desc_prefix, "Points | ")); - - options_double(ops, cat(prefix, "points_radius"), &(lds->points_radius), - lds->points_radius, cat(desc_prefix, "Point radius")); - - - ls_add_options(&(lds->pose), ops, cat(prefix, "pose_"), cat(desc_prefix, "PoseMarker | ")); - - options_double(ops, cat(prefix, "pose_radius"), &(lds->pose_radius), - lds->pose_radius, cat(desc_prefix, "Point radius")); - - ls_add_options(&(lds->normals), ops, cat(prefix, "normals_"), cat(desc_prefix, "Normals | ")); - - options_double(ops, cat(prefix, "normals_length"), &(lds->normals_length), - lds->normals_length, cat(desc_prefix, "Length of normals sticks (meters)")); - - ls_add_options(&(lds->sigma), ops, cat(prefix, "sigma_"), cat(desc_prefix, "Sigma | ")); - - options_double(ops, cat(prefix, "sigma_multiplier"), &(lds->sigma_multiplier), - lds->sigma_multiplier, cat(desc_prefix, "Multiplier for sigma")); - - - options_double(ops, cat(prefix, "connect_threshold"), &(lds->connect_threshold), - lds->connect_threshold, cat(desc_prefix, "Threshold under which points are connected (m).")); - options_double(ops, cat(prefix, "horizon"), &(lds->horizon), - lds->horizon, cat(desc_prefix, "Maximum distance to plot (m).")); -} - -void cr_set_color(cairo_t *cr, const char* color) { - if(strlen(color) == 4 && color[0] == '#') { - char buf[2] = {0, 0}; - double rgb[3]; - int i; for(i=0;i<3;i++) { - buf[0] = color[1+i]; - char* endptr; - rgb[i] = (1/15.0) * strtol(buf, &endptr, 16); - if(endptr == buf) { - sm_error("Unknown color component: %s.\n", buf); - } - } - cairo_set_source_rgb (cr, rgb[0], rgb[1], rgb[2]); - } else if(strlen(color) == 5 && color[0] == '#') { - char buf[2] = {0, 0}; - double rgba[4]; - int i; for(i=0;i<4;i++) { - buf[0] = color[1+i]; - char* endptr; - rgba[i] = (1/15.0) * strtol(buf, &endptr, 16); - if(endptr == buf) { - sm_error("Unknown color component: %s.\n", buf); - } - } - cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]); - } else { - if(!strcmp(color, "black")) { - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - } else { - sm_error("Unknown color: %s.\n", color); - cairo_set_source_rgb (cr, 0.0, 1.0, 1.0); - } - } -} - -void cr_set_style(cairo_t *cr, line_style *ls) { - cr_set_color(cr, ls->color); - cairo_set_line_width(cr, ls->width); -} - -void cr_lda_draw_pose_path(cairo_t*cr, LDP*scans, int nscans, ld_reference use_reference) { - int k; int first_pose=1; - for(k=0;k<nscans;k++) { - LDP ld = scans[k]; - double *pose = ld_get_reference_pose(ld, use_reference); - if(!pose) { - sm_error("No '%s' pose specified for scan #%d, continuing.\n", - ld_reference_to_string(use_reference)); - continue; - } - - if(first_pose) { - first_pose = 0; - cairo_move_to(cr, pose[0], pose[1]); - } else { - cairo_line_to(cr, pose[0], pose[1]); - } - } - cairo_stroke(cr); -} - - - -void cr_ld_draw_rays(cairo_t*cr, LDP ld) { - int i; for(i=0;i<ld->nrays;i++) { - if(!ld_valid_ray(ld, i)) continue; - - double threshold = 0.03; - -/* if(ld->readings[i]<2) continue;*/ - - double x1 = threshold * cos(ld->theta[i]); - double y1 = threshold * sin(ld->theta[i]); - double x2 = ld->readings[i] * cos(ld->theta[i]); - double y2 = ld->readings[i] * sin(ld->theta[i]); - - cairo_move_to(cr,x1,y1); - cairo_line_to(cr,x2,y2); - cairo_stroke(cr); - } -} - -void cr_ld_draw_countour(cairo_t*cr, LDP ld, double horizon, double connect_threshold) { - struct stroke_sequence draw_info[ld->nrays]; - compute_stroke_sequence(ld, draw_info, horizon, connect_threshold); - - /* draw contour: begin_new_stroke and end_stroke tell - when to interrupt the stroke */ - int i; - for(i=0;i<ld->nrays;i++) { - - if(draw_info[i].valid==0) continue; - - double *p = draw_info[i].p; - - if(draw_info[i].begin_new_stroke) - cairo_move_to(cr, p[0], p[1]); - else - cairo_line_to(cr, p[0], p[1]); -/* if(draw_info[i].end_stroke)*/ - } - cairo_stroke(cr); -} - -void cr_ld_draw_points(cairo_t*cr, LDP ld, double radius) { - int i; for(i=0;i<ld->nrays;i++) { - if(!ld_valid_ray(ld, i)) continue; - - double x = ld->readings[i] * cos(ld->theta[i]); - double y = ld->readings[i] * sin(ld->theta[i]); - - cairo_arc (cr, x, y, radius, 0.0, 2*M_PI); - cairo_fill(cr); - } -} - -void cr_ld_draw_normals(cairo_t*cr, LDP ld, double length) { - int i; for(i=0;i<ld->nrays;i++) { - if(!ld_valid_ray(ld, i) || !ld_valid_alpha(ld, i)) continue; - - double alpha = ld->alpha[i]; - double x1 = ld->readings[i] * cos(ld->theta[i]); - double y1 = ld->readings[i] * sin(ld->theta[i]); - double x2 = x1 + cos(alpha) * length; - double y2 = y1 + sin(alpha) * length; - - cairo_move_to(cr, x1, y1); - cairo_line_to(cr, x2, y2); - } - cairo_stroke (cr); -} - -void cr_ld_draw_sigma(cairo_t*cr, LDP ld, double multiplier) { - int i; for(i=0;i<ld->nrays;i++) { - if(!ld_valid_ray(ld, i) || is_nan(ld->readings_sigma[i])) continue; - - double theta = ld->theta[i]; - double length = ld->readings_sigma[i] * multiplier; - - double x0 = ld->readings[i] * cos(theta); - double y0 = ld->readings[i] * sin(theta); - double x1 = x0 + cos(theta) * length; - double y1 = y0 + sin(theta) * length; - double x2 = x0 - cos(theta) * length; - double y2 = y0 - sin(theta) * length; - - cairo_move_to(cr, x1, y1); - cairo_line_to(cr, x2, y2); - } - cairo_stroke (cr); -} - - -void cr_ld_draw(cairo_t* cr, LDP ld, ld_style *p) { - if(p->rays.draw) { - cr_set_style(cr, &(p->rays)); - cr_ld_draw_rays(cr, ld); - } - - if(p->countour.draw) { - cr_set_style(cr, &(p->countour)); - cr_ld_draw_countour(cr, ld, p->horizon, p->connect_threshold); - } - - if(p->points.draw) { - cr_set_style(cr, &(p->points)); - cr_ld_draw_points(cr, ld, p->points_radius); - } - - if(p->normals.draw) { - cr_set_style(cr, &(p->normals)); - cr_ld_draw_normals(cr, ld, p->normals_length); - } - - if(p->sigma.draw) { - cr_set_style(cr, &(p->sigma)); - cr_ld_draw_sigma(cr, ld, p->sigma_multiplier); - } - - if(p->pose.draw) { - cr_set_style(cr, &(p->pose)); - cairo_move_to(cr, 0.0, 0.0); - cairo_arc (cr, 0.0, 0.0, p->pose_radius, 0.0, 2*M_PI); - cairo_fill (cr); - } -} - -void cr_set_reference(cairo_t*cr, double*pose) { - cairo_translate(cr,pose[0],pose[1]); - cairo_rotate(cr,pose[2]); -} - -void ls_set_defaults(line_style*ls) { - ls->draw = 1; - ls->color = "black"; - ls->width = 0.002; -} - -void lds_set_defaults(ld_style*lds) { - ls_set_defaults(&(lds->rays)); - lds->rays.color = "#f00"; - lds->rays.width = 0.0002; - - ls_set_defaults(&(lds->countour)); - ls_set_defaults(&(lds->points)); - lds->points_radius = 0.003; - lds->points.color = "#f00"; - - ls_set_defaults(&(lds->pose)); - lds->pose.color = "#f73"; - lds->pose_radius = 0.24; - - lds->normals_length = 0.10; - ls_set_defaults(&(lds->normals)); - - lds->sigma_multiplier = 3; - ls_set_defaults(&(lds->sigma)); - lds->sigma.draw = 0; - - lds->connect_threshold = 0.20; - lds->horizon = 10; -} - -int create_pdf_surface(const char*file, int max_width_points, int max_height_points, - double bb_min[2], double bb_max[2], cairo_surface_t**surface_p, cairo_t **cr) { - double bb_width = bb_max[0] - bb_min[0], bb_height = bb_max[1] - bb_min[1]; - - - double surface_width, surface_height; - if( bb_width > bb_height ) { - /* largo e basso */ - surface_width = max_width_points; - surface_height = (surface_width / bb_width) * bb_height; - } else { - /* stretto e alto */ - surface_height = max_height_points; - surface_width = (surface_height / bb_height) * bb_width; - } - - sm_debug("bb: %f %f\n", bb_width, bb_height); - sm_debug("surface: %f %f\n", surface_width, surface_height); - - *surface_p = cairo_pdf_surface_create(file, surface_width, surface_height); - *cr = cairo_create (*surface_p); - cairo_status_t status = cairo_status (*cr); - - if (status) { - sm_error("Failed to create pdf surface for file %s: %s\n", - file, cairo_status_to_string (status)); - return 0; - } - - double world_to_surface = surface_width / bb_width; - cairo_scale(*cr, world_to_surface, -world_to_surface ); - cairo_translate(*cr, -bb_min[0], -bb_max[1]); - - return 1; -} - -int create_image_surface(int max_width_pixels, int max_height_pixels, - double bb_min[2], double bb_max[2], cairo_surface_t**surface_p, cairo_t **cr) { - double bb_width = bb_max[0] - bb_min[0], bb_height = bb_max[1] - bb_min[1]; - - double surface_width, surface_height; - if( bb_width > bb_height ) { - /* largo e basso */ - surface_width = max_width_pixels; - surface_height = (surface_width / bb_width) * bb_height; - } else { - /* stretto e alto */ - surface_height = max_height_pixels; - surface_width = (surface_height / bb_height) * bb_width; - } - - sm_debug("bb: %f %f\n", bb_width, bb_height); - sm_debug("surface: %f %f\n", surface_width, surface_height); - - *surface_p = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, (int) surface_width, (int)surface_height); - *cr = cairo_create (*surface_p); - cairo_status_t status = cairo_status (*cr); - - if (status) { - sm_error("Failed to create image surface: %s\n", - cairo_status_to_string (status)); - return 0; - } - - double world_to_surface = surface_width / bb_width; - cairo_scale(*cr, world_to_surface, -world_to_surface ); - cairo_translate(*cr, -bb_min[0], -bb_max[1]); - - return 1; -} - - diff --git a/sm/csm/laser_data_cairo.h b/sm/csm/laser_data_cairo.h deleted file mode 100644 index 0215948..0000000 --- a/sm/csm/laser_data_cairo.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef H_LASER_DATA_CAIRO -#define H_LASER_DATA_CAIRO - -#include <cairo.h> -#include <options/options.h> -#include "../csm/csm_all.h" -#include "../csm/laser_data_drawing.h" - -typedef struct { - /* should we draw it? */ - int draw; - - double width; - const char* color; - -} line_style ; - -typedef struct { - line_style rays, countour; - line_style points; - double points_radius; - - line_style normals; - double normals_length; - - /* A circle at the pose */ - line_style pose; - double pose_radius; - - - line_style sigma; - double sigma_multiplier; - - double connect_threshold; - double horizon; -} ld_style; - -void ls_set_defaults(line_style*ls); -void lds_set_defaults(ld_style*lds); - -void ls_add_options(line_style*ls, struct option*ops, - const char*prefix, const char*desc_prefix); - -void lds_add_options(ld_style*lds, struct option*ops, - const char*prefix, const char*desc_prefix); - -void cr_set_color(cairo_t *cr, const char* color); -void cr_set_style(cairo_t*cr, line_style*); -void cr_ld_draw(cairo_t* cr, LDP ld, ld_style *p); -void cr_ld_draw_corr(cairo_t*cr, LDP laser_ref, LDP laser_sens); -void cr_ld_draw_sigma(cairo_t*cr, LDP ld, double multiplier); -void cr_set_reference(cairo_t*cr,double*pose); - -void cr_lda_draw_pose_path(cairo_t*cr, LDP*lda, int nscans, ld_reference use_reference); - -int create_pdf_surface(const char*file, int max_width_points, int max_height_points, - double bb_min[2], double bb_max[2], cairo_surface_t**surface_p, cairo_t **cr); - -int create_image_surface(int width, int height, - double bb_min[2], double bb_max[2], cairo_surface_t**surface_p, cairo_t **cr); - - - -#endif - diff --git a/sm/csm/laser_data_carmen.c b/sm/csm/laser_data_carmen.c deleted file mode 100644 index a6566a1..0000000 --- a/sm/csm/laser_data_carmen.c +++ /dev/null @@ -1,223 +0,0 @@ -#include <string.h> -#include <math.h> -#include <ctype.h> - -#include "csm_all.h" - -const char * carmen_prefix = "FLASER "; - -/** Returns 0 on success */ -int read_next_double(const char*line, size_t*cur, double*d); - -/** Returns 0 on success */ -int read_next_integer(const char*line, size_t*cur, int*d); - -/** Always returns 0 */ -int read_next_string(const char*line, size_t*cur, char*buf, size_t buf_len); - - -/** Returns 0 on success */ -int read_next_double(const char*line, size_t*cur, double*d) { - int inc; - int ret = sscanf(line+*cur, " %lf %n", d, &inc); - if(1 != ret) { - sm_error("Could not read double at %p + %d '%s'. ret: %d.\n", line, *cur, line+*cur, ret); - return -1; - } - *cur += inc; - return 0; -} - -/** Returns 0 on success */ -int read_next_integer(const char*line, size_t*cur, int*d) { - int inc; - if(1 != sscanf(line+*cur, " %d %n", d, &inc)) { - /* sm_error("Could not read integer.\n");*/ - return -1; - } - *cur += inc; - return 0; -} - -/** Always returns 0 */ -int read_next_string(const char*line, size_t*cur, char*buf, size_t buf_len) { - int from = *cur; while(isspace(line[from])) from++; - size_t len = 0; while(!isspace(line[from+len])) len++; - if(len > buf_len ) len = buf_len; - strncpy(buf, line+from, len); - *cur += len; - return 0; -} - -LDP ld_from_carmen_string(const char*line) { - - if(0 != strncmp(line, carmen_prefix, strlen(carmen_prefix))) { - sm_error("This is not a Carmen line: \n-> %s\n", line); - return 0; - } - - size_t cur = strlen(carmen_prefix); - - - int nrays=-1; - if(read_next_integer(line, &cur, &nrays)) { - sm_error("Could not get number of rays.\n"); - goto error; - } - - LDP ld = ld_alloc_new(nrays); - - - double fov = M_PI; - double min_reading = 0; - double max_reading = 80; - - if(nrays == 769) { - min_reading = 0.001; - max_reading = 4; - fov = deg2rad(270.0); - - static int print = 0; - if(!print) { print = 1; - sm_info("Assuming that 769 rays is an Hokuyo " - "with fov = %f deg, min_reading = %f m, max_reading = %fm\n", - rad2deg(fov), min_reading, max_reading); - } - } - - ld->min_theta = -fov/2; - ld->max_theta = +fov/2; - - int on_error = 0; - int i; - for(i=0;i<nrays;i++) { - double reading; - if(read_next_double(line,&cur,&reading)) { - sm_error("Could not read ray #%d / %d, \n", i, nrays); - on_error = 1; - break; - } - - ld->valid[i] = (reading > min_reading) && (reading < max_reading); - ld->readings[i] = ld->valid[i] ? reading : NAN; - ld->theta[i] = ld->min_theta + i * - (ld->max_theta-ld->min_theta) / (ld->nrays-1); - - /* bad hokuyo!! */ - if(nrays == 769) { - if(i>725 || i<44) { - ld->valid[i] = 0; - ld->readings[i] = NAN; - } - } - - } - - if(on_error) goto error; - - if(read_next_double(line,&cur,ld->estimate+0)) goto error; - if(read_next_double(line,&cur,ld->estimate+1)) goto error; - if(read_next_double(line,&cur,ld->estimate+2)) goto error; - if(read_next_double(line,&cur,ld->odometry+0)) goto error; - if(read_next_double(line,&cur,ld->odometry+1)) goto error; - if(read_next_double(line,&cur,ld->odometry+2)) goto error; - - /* Following: ipc_timestamp hostname timestamp */ - /* Two options: - double string double: - the first is timestamp in seconds, the second is discarded - int string int: - the first is sec, the second is usec - */ - static int warn_format = 1; - - int inc; int sec=-1, usec=-1; - int res = sscanf(line + cur, "%d %s %d%n", &sec, ld->hostname, &usec, &inc); - if(3 == res) { - ld->tv.tv_sec = sec; - ld->tv.tv_usec = usec; - if(warn_format) - sm_info("Reading timestamp as 'sec hostname usec'.\n"); - } else { - double v1=-1, v2=-1; - res = sscanf(line + cur, "%lf %s %lf%n", &v1, ld->hostname, &v2, &inc); - if(3 == res) { - ld->tv.tv_sec = (int) floor(v1); - ld->tv.tv_usec = floor( (v1 - floor(v1)) * 1e6 ); - - if(warn_format) - sm_info("Reading timestamp as doubles (discarding second one).\n"); - - } else { - ld->tv.tv_sec = 0; - ld->tv.tv_usec = 0; - if(warn_format) - sm_info("I could not read timestamp+hostname; ignoring (I will warn only once for this).\n"); - } - } - - warn_format = 0; - - fprintf(stderr, "l"); - return ld; - - error: - printf("Malformed line: '%s'\nat cur = %d\n\t-> '%s'\n", line,(int)cur,line+cur); - return 0; -} - -/** Read next FLASER line in file, or NULL on error */ -int ld_read_next_laser_carmen(FILE*file, LDP*ld) { - *ld = 0; - #define MAX_LINE_LENGTH 10000 - char line[MAX_LINE_LENGTH]; - - while(fgets(line, MAX_LINE_LENGTH-1, file)) { - if(0 != strncmp(line, carmen_prefix, strlen(carmen_prefix))) { - sm_debug("Skipping line: \n-> %s\n", line); - continue; - } - - *ld = ld_from_carmen_string(line); - if(!*ld) { - printf("Malformed line? \n-> '%s'", line); - return 0; - } else { - return 1; - } - } - return 1; -} - -/** Write the laser data in CARMEN format */ -void ld_write_as_carmen(LDP ld, FILE * stream) { - int i; - double timestamp; - if(!ld_valid_fields(ld)) { - sm_error("Writing bad data to the stream.\n"); - } - fprintf(stream, "FLASER %d ", ld->nrays); - for(i=0; i<ld->nrays; i++){ - fprintf(stream, "%g ", ld->readings[i]); - } - fprintf(stream, "%g %g %g ", ld->estimate[0], ld->estimate[1], ld->estimate[2]); - fprintf(stream, "%g %g %g ", ld->odometry[0], ld->odometry[1], ld->odometry[2]); - - timestamp = ld->tv.tv_sec + ((double)ld->tv.tv_sec)/1e6; - - fprintf(stream, "%g %s %g", timestamp, ld->hostname, timestamp); - - fputs("\n", stream); -} - -void ld_write_format(LDP ld, FILE*f, const char * out_format) { - if(!strncmp(out_format, "carmen", 6)) - ld_write_as_carmen(ld, f); - else - ld_write_as_json(ld, f); - /* XXX: check validity of format string */ -} - - - - diff --git a/sm/csm/laser_data_drawing.c b/sm/csm/laser_data_drawing.c deleted file mode 100644 index eae942c..0000000 --- a/sm/csm/laser_data_drawing.c +++ /dev/null @@ -1,144 +0,0 @@ -#include <string.h> -#include <strings.h> -#include "laser_data_drawing.h" -#include "logging.h" -#include "math_utils.h" - -const char*ld_reference_name[4] = { "invalid","odometry","estimate","true_pose"}; - -const char*ld_reference_to_string(ld_reference r) { - return ld_reference_name[r]; -} - -ld_reference ld_string_to_reference(const char*s) { - int i; for(i=1;i<=3;i++) - if(!strcasecmp(s, ld_reference_to_string( (ld_reference) i) )) - return (ld_reference) i; - - sm_error("Could not translate string '%s' to a reference name.\n", s); - return Invalid; -} - -int ld_get_bounding_box(LDP ld, double bb_min[2], double bb_max[2], - double pose[3], double horizon) { - - int rays_used = 0; - int i; for(i=0;i<ld->nrays;i++) { - if(!ld->valid[i]) continue; - if(ld->readings[i]>horizon) continue; - - double p0[2] = { - cos(ld->theta[i]) * ld->readings[i], - sin(ld->theta[i]) * ld->readings[i] - }; - - double p[2]; - transform_d(p0,pose,p); - - if(0 == rays_used) { - bb_min[0] = bb_max[0] = p[0]; - bb_min[1] = bb_max[1] = p[1]; - } else { - int j=0; for(j=0;j<2;j++) { - bb_min[j] = GSL_MIN(bb_min[j], p[j]); - bb_max[j] = GSL_MAX(bb_max[j], p[j]); - } - } - - rays_used++; - } - - return rays_used > 3; -} - -/*void lda_get_bb2(LDP *ld, int nld, BB2 bb2, ld_reference use_reference, double horizon) { - double bb_min[2], bb_max[2], offset[3] = {0,0,0}; - lda_get_bounding_box(ld,nld, bb2->bb_) -}*/ - - -void lda_get_bounding_box(LDP *lda, int nld, double bb_min[2], double bb_max[2], - double offset[3], ld_reference use_reference, double horizon) { - - int k; - for(k=0;k<nld;k++) { - LDP ld = lda[k]; - - double *ref = ld_get_reference_pose(ld, use_reference); - if(!ref) { - sm_error("Pose %s not set in scan #%d.\n", - ld_reference_to_string(use_reference), k); - continue; - } - - double pose[3]; - oplus_d(offset, ref, pose); - - if(k==0) - ld_get_bounding_box(ld, bb_min, bb_max, pose, horizon); - else { - double this_min[2], this_max[2]; - ld_get_bounding_box(ld, this_min, this_max, pose, horizon); - int i; for(i=0;i<2;i++) { - bb_min[i] = GSL_MIN(bb_min[i], this_min[i]); - bb_max[i] = GSL_MAX(bb_max[i], this_max[i]); - } - } - } -} - -double * ld_get_reference_pose_silent(LDP ld, ld_reference use_reference) { - double * pose; - switch(use_reference) { - case Odometry: pose = ld->odometry; break; - case Estimate: pose = ld->estimate; break; - case True_pose: pose = ld->true_pose; break; - default: - sm_error("Could not find pose identified by %d.\n", (int) use_reference); - return 0; - } - return pose; -} - -double * ld_get_reference_pose(LDP ld, ld_reference use_reference) { - double * pose = ld_get_reference_pose_silent(ld, use_reference); - if(any_nan(pose, 3)) { - sm_error("Required field '%s' not set in laser scan.\n", - ld_reference_to_string(use_reference) ); - return 0; - } - return pose; -} - - -void compute_stroke_sequence(LDP ld, struct stroke_sequence*draw_info, - double horizon, double connect_threshold) { - int last_valid = -1; int first = 1; - int i; for(i=0;i<ld->nrays;i++) { - if( (!ld_valid_ray(ld,i)) || (ld->readings[i] > horizon) ) { - draw_info[i].valid = 0; - continue; - } - draw_info[i].valid = 1; - draw_info[i].p[0] = ld->readings[i] * cos(ld->theta[i]); - draw_info[i].p[1] = ld->readings[i] * sin(ld->theta[i]); - - if(first) { - first = 0; - draw_info[i].begin_new_stroke = 1; - draw_info[i].end_stroke = 0; - } else { - int near = square(connect_threshold) > - distance_squared_d(draw_info[last_valid].p, draw_info[i].p); - draw_info[i].begin_new_stroke = near ? 0 : 1; - draw_info[i].end_stroke = 0; - draw_info[last_valid].end_stroke = draw_info[i].begin_new_stroke; - } - last_valid = i; - } /*for */ - if(last_valid >= 0) - draw_info[last_valid].end_stroke = 1; -} /* find buff .. */ - - - diff --git a/sm/csm/laser_data_drawing.h b/sm/csm/laser_data_drawing.h deleted file mode 100644 index fd9ca1a..0000000 --- a/sm/csm/laser_data_drawing.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef H_LASER_DATA_DRAWING -#define H_LASER_DATA_DRAWING - -#include "laser_data.h" - -typedef enum { Invalid = 0, Odometry = 1, Estimate = 2, True_pose = 3 } ld_reference; - -const char*ld_reference_to_string(ld_reference); -ld_reference ld_string_to_reference(const char*string); - -/** Gets a pointer to the pose specified by 'use_reference', - or 0 if use_reference is invalid. */ -double * ld_get_reference_pose_silent(LDP ld, ld_reference use_reference); -/** Same as ld_get_reference_pose_silent(), but it also checks - that the pose is valid (no NANs inside). */ -double * ld_get_reference_pose(LDP ld, ld_reference use_reference); - - - -int ld_read_some_scans_distance(FILE*file, LDP **array, int*num, - ld_reference which, double d_xy, double d_th); - -typedef struct { - /** lower left point */ - double pose[3]; - /** width, height; */ - double size[2]; -} oriented_bbox; - -typedef oriented_bbox* BB2; - - -/** Returns != 0 if enough points were found */ -int ld_get_bounding_box(LDP ld, double bb_min[2], double bb_max[2], - double pose[3], double horizon); - -void lda_get_bounding_box(LDP *ld, int nld, double bb_min[2], double bb_max[2], - double offset[3], ld_reference use_reference, double horizon); - -/*void lda_get_bb2(LDP *ld, int nld, BB2 bb2, ld_reference use_reference, double horizon);*/ - - -void oriented_bbox_compute_corners(const BB2, - double ul[2], double ur[2], double ll[2], double lr[2]); - -void ld_get_oriented_bbox(LDP ld, double horizon, BB2); - -/* Simple API for finding bounding box */ -struct bbfind_imp; -typedef struct bbfind_imp bbfind; -bbfind * bbfind_new(); - -int bbfind_add_point(bbfind*, double point[2]); -int bbfind_add_point2(bbfind*, double x, double y); -int bbfind_add_bbox(bbfind*, const BB2); - -int bbfind_compute(bbfind*, BB2); -void bbfind_free(bbfind*); - -/* For drawing stroke */ - -struct stroke_sequence { - int begin_new_stroke; - int end_stroke; - int valid; - - double p[2]; -}; - -void compute_stroke_sequence(LDP ld, struct stroke_sequence*, - double horizon, double connect_threshold); - - -#endif diff --git a/sm/csm/laser_data_fisher.c b/sm/csm/laser_data_fisher.c deleted file mode 100644 index 87f8262..0000000 --- a/sm/csm/laser_data_fisher.c +++ /dev/null @@ -1,43 +0,0 @@ -#include <math.h> -#include <egsl/egsl_macros.h> - -#include "csm_all.h" - -/** - This computes the Fisher Information Matrix, in robot coordinates. - Uses field 'true_alpha' (and 'theta', 'readings'). - - For details about the the Fisher Information Matrix, - please see this paper: http://purl.org/censi/2006/accuracy -*/ - -val ld_fisher0(LDP ld) { - val fim = zeros(3,3); - int i; - for(i=0;i<ld->nrays;i++) { - double alpha = ld->true_alpha[i]; - if(is_nan(alpha)) continue; - - double theta = ld->theta[i]; - double beta = alpha-theta; - - double r = ld->readings[i]; - double c = cos(alpha); - double s = sin(alpha); - - double z = 1 / cos(beta); - double t = tan(beta); - - double fim_k[9] ={ - c*c*z*z, c*s*z*z, c*z *t*r, - c*s*z*z, s*s*z*z, s*z *t*r, - c*z*t*r, s*z*t*r, t*r *t*r - }; - - egsl_push(); - val k = egsl_vFda(3,3,fim_k); - add_to(fim, k); - egsl_pop(); - } - return fim; -} diff --git a/sm/csm/laser_data_json.c b/sm/csm/laser_data_json.c deleted file mode 100644 index 318c170..0000000 --- a/sm/csm/laser_data_json.c +++ /dev/null @@ -1,268 +0,0 @@ -#include <errno.h> -#include <string.h> -#include <math.h> -#include <ctype.h> - -#include "csm_all.h" - -void jo_add_timestamp(JO jo, const char*name, struct timeval*tv); -int is_all_nan(const double *v, int n ); -void jo_add_double_array_if_not_nan(JO jo, const char*name, const double *v, int n); -int all_is(int *a, int n, int v); - -/* -------------------------------------------- */ - - -JO matrix_to_json(gsl_matrix*m) { - JO jo = jo_new_array(); - if(m->size1>1) { - size_t i,j; - for(i=0;i<m->size1;i++) { - JO row = json_object_new_array(); - for(j=0;j<m->size2;j++) { - double v = gsl_matrix_get(m,i,j); - json_object_array_add(row, jo_double_or_null(v)); - } - json_object_array_add(jo, row); - } - } else { - size_t i = 1, j; - JO row = jo; - for(j=0;j<m->size2;j++) { - double v = gsl_matrix_get(m,i,j); - json_object_array_add(row, jo_double_or_null(v)); - } - } - return jo; -} - -int json_to_corr(JO array, struct correspondence*corr, int n) { - /** XXX : check it's an array and its size is good */ - int i; - for(i=0;i<n;i++) { - JO element = json_object_array_get_idx(array, i); - if(element == NULL) { - corr[i].valid = 0; - corr[i].j1 = -1; - corr[i].j2 = -1; - } else { - corr[i].valid = 1; - jo_read_int(element, "j1", &(corr[i].j1)); - jo_read_int(element, "j2", &(corr[i].j2)); - int type; - jo_read_int(element, "type", &(type)); - corr[i].type = type; - } - } - return 1; -} - -JO corr_to_json(struct correspondence*corr, int n) { - JO jo = jo_new_array(); - int i; - for(i=0;i<n;i++) { - if(corr[i].valid) { - JO c = jo_new(); - jo_add_int(c, "j1", corr[i].j1); - jo_add_int(c, "j2", corr[i].j2); - jo_add_int(c, "type", (int) corr[i].type); - jo_array_add(jo, c); - } else { - jo_array_add(jo, jo_new_null()); - } - } - return jo; -} - - -JO vector_to_json(gsl_vector*vec) { - JO jo = json_object_new_array(); - size_t j; - for(j=0;j<vec->size;j++) { - double v = gsl_vector_get(vec,j); - jo_array_add(jo, jo_double_or_null(v)); - } - return jo; -} - - -void jo_add_timestamp(JO jo, const char*name, struct timeval*tv) { - int array[2] = {tv->tv_sec, tv->tv_usec}; - jo_add_int_array(jo, name, array, 2); -} - -JO result_to_json(struct sm_params*p, struct sm_result *r) { - JO jo = json_object_new_object(); - jo_add_int(jo, "valid", r->valid); - - if(r->valid) { - jo_add_double_array(jo, "x", r->x, 3); - - if(p->do_compute_covariance) { - jo_add(jo, "cov_x", matrix_to_json(r->cov_x_m ) ); - jo_add(jo, "dx_dy1", matrix_to_json(r->dx_dy1_m) ); - jo_add(jo, "dx_dy2", matrix_to_json(r->dx_dy2_m) ); - } - } - jo_add_int(jo, "iterations", r->iterations); - jo_add_int(jo, "nvalid", r->nvalid); - jo_add_double(jo, "error", r->error); - - jo_add_timestamp(jo, "laser_ref_timestamp", &(p->laser_ref->tv)); - jo_add_timestamp(jo, "laser_sens_timestamp", &(p->laser_sens->tv)); - - return jo; -} - -int is_all_nan(const double *v, int n ) { - int i; for(i=0;i<n;i++) if(v[i]==v[i]) return 0; - return 1; -} - -/** Adds unless it's all NAN */ -void jo_add_double_array_if_not_nan(JO jo, const char*name, const double *v, int n) { - if(is_all_nan(v,n)) return; - jo_add_double_array(jo, name, v, n); -} - -/** true if all values are equal to v */ -int all_is(int *a, int n, int v) { - int i; for(i=0;i<n;i++) if(a[i]!=v) return 0; - return 1; -} - -JO ld_to_json(LDP ld) { - JO jo = json_object_new_object(); - int n = ld->nrays; - - jo_add_int(jo, "nrays", ld->nrays); - jo_add_double(jo, "min_theta", ld->min_theta); - jo_add_double(jo, "max_theta", ld->max_theta); - - jo_add_double_array(jo, "odometry", ld->odometry, 3); - jo_add_double_array(jo, "estimate", ld->estimate, 3); - jo_add_double_array(jo, "true_pose", ld->true_pose, 3); - - jo_add_double_array(jo, "theta", ld->theta, n); - jo_add_double_array(jo, "readings", ld->readings, n); - jo_add_double_array_if_not_nan(jo, "readings_sigma", ld->readings_sigma, n); - - jo_add_int_array(jo, "valid", ld->valid, n); - - if(!all_is(ld->cluster, n, -1)) - jo_add_int_array(jo, "cluster", ld->cluster, n); - - jo_add_double_array_if_not_nan(jo, "alpha", ld->alpha, n); - jo_add_double_array_if_not_nan(jo, "cov_alpha", ld->cov_alpha, n); - - if(!all_is(ld->alpha_valid, n, 0)) - jo_add_int_array(jo, "alpha_valid", ld->alpha_valid, n); - - jo_add_double_array_if_not_nan(jo, "true_alpha", ld->true_alpha, n); - - int timeval[2] = {ld->tv.tv_sec, ld->tv.tv_usec}; - jo_add_int_array(jo, "timestamp", timeval, 2); - - return jo; -} - -/* TODO: add some checks */ -LDP json_to_ld(JO jo) { - int n; - if(!jo_read_int(jo, "nrays", &n)) { - sm_error("Could not read nrays.\n"); - return 0; - } - - LDP ld = ld_alloc_new(n); - - jo_read_double(jo, "min_theta", &ld->min_theta); - jo_read_double(jo, "max_theta", &ld->max_theta); - /* XXX add more checks */ - jo_read_double_array(jo, "theta", ld->theta, n, NAN); - jo_read_double_array(jo, "readings", ld->readings, n, NAN); - - if(jo_has_field(jo,"readings_sigma") && !jo_read_double_array(jo, "readings_sigma", ld->readings_sigma, n, NAN)) - { sm_error("Error while reading field 'readings_sigma'.\n"); return 0; } - - jo_read_int_array(jo, "valid", ld->valid, n, 0); - jo_read_int_array(jo, "cluster", ld->cluster, n, -1); - - if(jo_has_field(jo,"alpha") && !jo_read_double_array(jo, "alpha",ld->alpha, n, NAN)) - { sm_error("Error while reading field alpha.\n"); return 0; } - - if(jo_has_field(jo,"cov_alpha") && !jo_read_double_array(jo, "cov_alpha", ld->cov_alpha, n, NAN)) - { sm_error("Error while reading field cov_alpha.\n"); return 0; } - - if(jo_has_field(jo,"alpha_valid") && !jo_read_int_array(jo, "alpha_valid", ld->alpha_valid, n, 0)) - { sm_error("Error while reading field alpha_valid.\n"); return 0; } - - if(jo_has_field(jo,"true_alpha") && !jo_read_double_array(jo, "true_alpha", ld->true_alpha, n, NAN)) - { sm_error("Error while reading field true_alpha.\n"); return 0; } - - - jo_read_double_array(jo, "odometry", ld->odometry, 3, NAN); - jo_read_double_array(jo, "estimate", ld->estimate, 3, NAN); - jo_read_double_array(jo, "true_pose", ld->true_pose, 3, NAN); - - int array[2] = {-1,-1}; - jo_read_int_array(jo, "timestamp", array, 2,-1); - ld->tv.tv_sec = array[0]; - ld->tv.tv_usec = array[1]; - - return ld; -} - -LDP ld_from_json_string(const char*s) { - JO jo = json_parse(s); - if(!jo) { - sm_error("Invalid JSON found.\n"); - return 0; - } - LDP ld = json_to_ld(jo); - if(!ld) { - sm_error("Could not read laser_data:\n\n%s\n", json_object_to_json_string(jo)); - return 0; - } - jo_free(jo); - return ld; -} - -LDP ld_from_json_stream(FILE*file) { - JO jo; /* the monkey */ - LDP ld; - - jo = json_read_stream(file); - if(!jo) { - if(!feof(file)) { - fprintf(stderr, " (!)\n"); - sm_error("Invalid JSON found.\n"); - } - fprintf(stderr, " EOF\n"); - - return 0; - } - - ld = json_to_ld(jo); - if(!ld) { - sm_error("Could not read laser_data:\n\n%s\n", json_object_to_json_string(jo)); - return 0; - } - jo_free(jo); - - fprintf(stderr, "l"); - - return ld; -} - -void ld_write_as_json(LDP ld, FILE * stream) { - if(!ld_valid_fields(ld)) { - sm_error("Writing bad data to the stream.\n"); - } - - JO jo = ld_to_json(ld); - fputs(json_object_to_json_string(jo), stream); - fputs("\n", stream); - jo_free(jo); -} - diff --git a/sm/csm/laser_data_json.h b/sm/csm/laser_data_json.h deleted file mode 100644 index 8e1dfe5..0000000 --- a/sm/csm/laser_data_json.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef H_LASER_DATA_JSON -#define H_LASER_DATA_JSON - -#include <gsl/gsl_matrix.h> -#include <gsl/gsl_vector.h> - -#include <json-c/json.h> -#include <json-c/json_more_utils.h> - -#include "laser_data.h" -#include "algos.h" - -/* Laserdata to/from json */ - -JO ld_to_json(LDP); -LDP json_to_ld(JO); - -JO corr_to_json(struct correspondence*, int n); -int json_to_corr(JO jo, struct correspondence*, int n); - -LDP ld_from_json_stream(FILE*); -LDP ld_from_json_string(const char*s); -void ld_write_as_json(LDP ld, FILE * stream); - - -/* Other stuff to/from json */ - -JO matrix_to_json(gsl_matrix*m); -JO vector_to_json(gsl_vector*v); -JO result_to_json(struct sm_params*p, struct sm_result *r); - -#endif diff --git a/sm/csm/laser_data_load.c b/sm/csm/laser_data_load.c deleted file mode 100644 index 5c65c96..0000000 --- a/sm/csm/laser_data_load.c +++ /dev/null @@ -1,189 +0,0 @@ -#include <ctype.h> - -#include "csm_all.h" -#include "laser_data_drawing.h" - -/** Loads *some* data based on an acceptance criterion. */ -int ld_read_some(FILE*file, LDP **array, int*num, int (*accept)(LDP)); - - /* Every n scans */ - int interval_accept(LDP ld); - int interval_count = 0; - int interval_interval = 10; - - /* Every one */ - int always(LDP ld); - - /* Read according to distance */ - int distance_accept(LDP ld); - static int distance_count; - static double distance_last_pose[3]; - static double distance_interval_xy = 10; - static double distance_interval_th = 10; - static ld_reference distance_reference; - void distance_accept_reset(ld_reference, double interval_xy, double interval_th); - - - -/* ---------------------------------------- */ - -int ld_read_some(FILE*file, LDP **array, int*num, int (*accept)(LDP)) { - *array = 0; *num = 0; - int size = 10; - LDP * ar = (LDP*) malloc(sizeof(LDP)*size); - - while(1) { - LDP ld = ld_read_smart(file); - - if(!ld) break; - - if( ! (*accept)(ld) ) { - ld_free(ld); - continue; - } - - - ar[(*num)++] = ld; - - if(*num > size - 1) { - size *= 2; - if(! (ar = (LDP*) realloc(ar, sizeof(LDP)*size)) ) { - sm_error("Cannot allocate (size=%d)\n", size); - return 0; - } - } - } - - *array = ar; - - return feof(file); -} - - -/* Read every tot scans */ -int interval_accept(LDP ld) { - ld=ld; - int accept = interval_count % interval_interval == 0; - interval_count++; - return accept; -} - -int ld_read_some_scans(FILE*file, LDP **array, int*num, int interval) { - interval_count = 0; - interval_interval = interval; - return ld_read_some(file, array, num, interval_accept); -} - -/* Read all scans */ -int always(LDP ld) { ld=ld; return 1; } -int ld_read_all(FILE*file, LDP **array, int*num) { - return ld_read_some(file, array, num, always); -} - -void distance_accept_reset(ld_reference which, double interval_xy, double interval_th) { - distance_count = 0; - distance_interval_xy = interval_xy; - distance_interval_th = interval_th; - distance_reference = which; -} - -int distance_accept(LDP ld) { - double * this_pose = ld_get_reference_pose(ld, distance_reference); - if(!this_pose) return 0; - - distance_count++; - if(distance_count == 1) { - copy_d(this_pose, 3, distance_last_pose); - return 1; - } else { - double diff[3]; - pose_diff_d(distance_last_pose, this_pose, diff); - double distance = norm_d(diff); - - if(distance >= distance_interval_xy || - fabs(diff[2]) >= distance_interval_th ) - { - copy_d(this_pose, 3, distance_last_pose); - /* sm_debug("Accepting #%d, %f\n", distance_count, distance);*/ - return 1; - } - else - return 0; - } -} - -int ld_read_some_scans_distance(FILE*file, LDP **array, int*num, - ld_reference which, double d_xy, double d_th) { - distance_accept_reset(which, d_xy, d_th); - return ld_read_some(file, array, num, distance_accept); -} - - - -/** - Tries to read a laser scan from file. If error or EOF, it returns 0. - Whitespace is skipped. If first valid char is '{', it tries to read - it as JSON. If next char is 'F' (first character of "FLASER"), - it tries to read in Carmen format. Other lines are discarded. - 0 is returned on error or feof -*/ -LDP ld_read_smart(FILE*f) { - while(1) { - int c; - while(1) { - c = fgetc(f); - if(feof(f)) { - /* sm_debug("eof\n"); */ - return 0; - } - if(!isspace(c)) break; - } - ungetc(c, f); - - switch(c) { - case '{': { -/* sm_debug("Reading JSON\n"); */ - return ld_from_json_stream(f); - } - case 'F': { -/* sm_debug("Reading Carmen\n"); */ - LDP ld; - if(!ld_read_next_laser_carmen(f, &ld)) { - sm_error("bad carmen\n"); - return 0; - } - return ld; - } - default: { - /*sm_error("Could not read ld. First char is '%c'. ", c);*/ - char max_line[10000]; - char * res = fgets(max_line, 10000-2, f); - if(!res) { - sm_error("Could not skip line. \n"); - return 0; - } else { - fprintf(stderr, "s"); -/* sm_error("Skipped '%s'\n", res);*/ - } - } - } - } -} - -LDP ld_read_smart_string(const char*line) { - switch(*line) { - case '{': - return ld_from_json_string(line); - - case 'F': - return ld_from_carmen_string(line); - - default: - sm_error("Invalid laserdata format: '%s'.", line); - return 0; - } -} - - - - diff --git a/sm/csm/math_utils_gsl.c b/sm/csm/math_utils_gsl.c deleted file mode 100644 index 1bb120c..0000000 --- a/sm/csm/math_utils_gsl.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "csm_all.h" - -void transform(const gsl_vector* p, const gsl_vector* x, gsl_vector*res) { - double theta = gvg(x,2); - double c = cos(theta); double s = sin(theta); - gsl_vector_set(res, 0, c * gvg(p,0) -s*gvg(p,1) + gvg(x,0)); - gsl_vector_set(res, 1, s * gvg(p,0) +c*gvg(p,1) + gvg(x,1)); -} - -void gsl_vector_set_nan(gsl_vector*v) { - gvs(v,0,GSL_NAN); - gvs(v,1,GSL_NAN); -} - -double norm(const gsl_vector*a){ - double x = gvg(a,0); - double y = gvg(a,1); - return sqrt(x*x+y*y); -} - -gsl_vector * vector_from_array(unsigned int n, double *x) { - gsl_vector * v = gsl_vector_alloc(n); - unsigned int i; - for(i=0;i<n;i++) - gvs(v,i,x[i]); - - return v; -} - -void copy_from_array(gsl_vector*v, double*x) { - size_t i; - for(i=0;i<v->size;i++) - gsl_vector_set(v,i, x[i]); -} - -void vector_to_array(const gsl_vector*v, double*x){ - size_t i; - for(i=0;i<v->size;i++) - x[i] = gvg(v,i); -} - -void oplus(const gsl_vector*x1,const gsl_vector*x2, gsl_vector*res) { - double c = cos(gvg(x1,2)); - double s = sin(gvg(x1,2)); - gvs(res,0, gvg(x1,0)+c*gvg(x2,0)-s*gvg(x2,1)); - gvs(res,1, gvg(x1,1)+s*gvg(x2,0)+c*gvg(x2,1)); - gvs(res,2, gvg(x1,2)+gvg(x2,2)); -} - -void ominus(const gsl_vector*x, gsl_vector*res) { - double c = cos(gvg(x,2)); - double s = sin(gvg(x,2)); - gvs(res,0, -c*gvg(x,0)-s*gvg(x,1)); - gvs(res,1, s*gvg(x,0)-c*gvg(x,1)); - gvs(res,2, -gvg(x,2)); -} - -void pose_diff(const gsl_vector*pose2,const gsl_vector*pose1,gsl_vector*res) { - gsl_vector* temp = gsl_vector_alloc(3); - ominus(pose1, temp); - oplus(temp, pose2, res); - gsl_vector_free(temp); -} - -const char* gsl_friendly_pose(gsl_vector*v) { - return friendly_pose(v->data); -} - -static char egsl_tmp_buf[1024]; -const char* egsl_friendly_pose(val v) { - sprintf(egsl_tmp_buf, "(%4.2f mm, %4.2f mm, %4.4f deg)", - 1000*egsl_atv(v,0), - 1000*egsl_atv(v,1), - rad2deg(egsl_atv(v,2))); - return egsl_tmp_buf; -} - -const char* egsl_friendly_cov(val cov) { - - double limit_x = 2 * sqrt(egsl_atm(cov, 0, 0)); - double limit_y = 2 * sqrt(egsl_atm(cov, 1, 1)); - double limit_th = 2 * sqrt(egsl_atm(cov, 2, 2)); - - sprintf(egsl_tmp_buf, "(+- %4.2f mm,+- %4.2f mm,+- %4.4f deg)", - 1000*limit_x, - 1000*limit_y, - rad2deg(limit_th)); - return egsl_tmp_buf; -} - - -/*double distance(const gsl_vector* a, const gsl_vector* b) { - distance_counter++; - double x = gvg(a,0)-gvg(b,0); - double y = gvg(a,1)-gvg(b,1); - return sqrt(x*x+y*y); -} - -double distance_squared(const gsl_vector* a, const gsl_vector* b) { - distance_counter++; - double x = gvg(a,0)-gvg(b,0); - double y = gvg(a,1)-gvg(b,1); - return x*x+y*y; -}*/ diff --git a/sm/csm/math_utils_gsl.h b/sm/csm/math_utils_gsl.h deleted file mode 100644 index 6b30b78..0000000 --- a/sm/csm/math_utils_gsl.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef H_MATH_UTILS_GSL -#define H_MATH_UTILS_GSL - -#include <gsl/gsl_math.h> -#include <egsl/egsl.h> - -#include "laser_data.h" - -#define gvg gsl_vector_get -#define gvs gsl_vector_set - - -/* GSL stuff */ - const char* gsl_friendly_pose(gsl_vector*v); - gsl_vector * vector_from_array(unsigned int n, double *x); - void vector_to_array(const gsl_vector*v, double*); - void copy_from_array(gsl_vector*v, double*); - - void oplus(const gsl_vector*x1,const gsl_vector*x2, gsl_vector*res); - void ominus(const gsl_vector*x, gsl_vector*res); - void pose_diff(const gsl_vector*pose2,const gsl_vector*pose1,gsl_vector*res); - - void transform(const gsl_vector* point2d, const gsl_vector* pose, gsl_vector*result2d); - void gsl_vector_set_nan(gsl_vector*v); - - double distance(const gsl_vector* a,const gsl_vector* b); - double distance_squared(const gsl_vector* a,const gsl_vector* b); - - /** Returns norm of 2D point p */ - double norm(const gsl_vector*p); - const char* egsl_friendly_pose(val pose); - const char* egsl_friendly_cov(val cov); - -/** Returns Fisher's information matrix. You still have to multiply - it by (1/sigma^2). */ -val ld_fisher0(LDP ld); - - -#endif - - diff --git a/sm/csm/math_utils_test.c b/sm/csm/math_utils_test.c deleted file mode 100644 index d8ad866..0000000 --- a/sm/csm/math_utils_test.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "csm_all.h" -#include <time.h> - -#include "math_utils.h" - - -inline float myasin(float x) { - const float threshold = .52; - if(x > threshold) { - static float z, der0, der1,der2,der3; - static int first = 1; - if(first) { - z = 0.5* (threshold + 0.707); - der0 = asin(z); - float M = 1-z*z; - der1 = 1 / sqrt(M); - der2 = (sqrt(M) * z) / (M*M); - der3 = (sqrt(M) / ( M * M ) + (3 * (z*z) * sqrt(M) ) / (M * M * M) ) ; - first = 0; - printf("%f %f %f %f \n", der0, der1, der2, der3); - } - float m = x-z; - return der0 + m * ( der1 + m * ( (der2/2) + m * (der3/6) ) ); - } - else{ - float x2 = x * x; - float der1 = 1; - float der3 = 1.0f/6; - float der5 = 3.0f/40; - float der7 = 15.0f/ (48*7); - return x * ( der1 + x2 *( der3 + x2 * (der5 + der7 * x2 ))); - } -} - -#define myacos(x) ( ((float) (M_PI/2) ) - myasin(x)) -inline void polar(float x, float y, double* restrict rho, double* restrict theta) { - *rho = sqrtf(x*x+y*y); - if(x > 0) { - if(y > 0) { - if(x < y) - *theta = myacos(x / *rho); - else - *theta = myasin(y / *rho); - } else { - if( x < -y ) - *theta = - myacos(x / *rho); - else - *theta = - myasin( (-y) / *rho) ; - } - } else { - if(y > 0) { - if( (-x) < y) - *theta = ((float)M_PI) - myacos(-x / *rho); - else - *theta = ((float)M_PI) - myasin( y / *rho); - } else { - if ( (-x) < (-y) ) - *theta = ((float)M_PI) + myacos(-x / *rho); - else - *theta = ((float)M_PI) + myasin(-y / *rho); - } - } -} - -inline void polar2(double x, double y, double* restrict rho, double* restrict theta) { - *rho = sqrt(x*x+y*y); - *theta = atan2(y,x); -} - -int main() { - double a[2] = {0, 0}; - double b[2] = {5, 5}; - double x[5][2] = { - {0, -10}, - { 2, 1}, - {100, 1}, - {0,0},{5,5}}; - - gsl_vector * A = vector_from_array(2,a); - gsl_vector * B = vector_from_array(2,b); - - gsl_vector * res = gsl_vector_alloc(2); - - int i; - #if 0 - for(i=0;i<5;i++){ - gsl_vector * X = vector_from_array(2,x[i]); - -/* projection_on_segment(A,B,X,res);*/ - - printf("Projection of %f %f is %f %f \n", gvg(X,0),gvg(X,1), - gvg(res,0),gvg(res,1)); - } - #endif - - int errors = 0; - double should_be_nan[2] = { 0.0 / 0.0, GSL_NAN }; - for(i=0;i<2;i++) { - if(!isnan(should_be_nan[i])) { - printf("#%d: isnan(%f) failed \n", i, should_be_nan[i]); - errors++; - } - if(!is_nan(should_be_nan[i])) { - printf("#%d: is_nan(%f) failed \n", i, should_be_nan[i]); - errors++; - } - } - - double max_error = 0; - int num = 10000; - for(i=0;i<num;i++) { - double theta = (i * 2 * M_PI) / (num-1); - double x = cos(theta), y = sin(theta); - - double theta_est, rho; - polar(x,y,&rho,&theta_est); - double error = fabs( angleDiff(theta_est,theta) ); - if(error > max_error) - printf("%d x %f y %f theta %f theta_est %f error %f \n", i, x, y, theta, theta_est, error); - max_error = GSL_MAX(error, max_error); - } - - int NUM2 = 1000; int k; - float c[num], s[num]; - for(i=0;i<num;i++) { - double theta = (i * 2 * M_PI) / (num-1); - c[i]= cos(theta); s[i] = sin(theta); - } - - clock_t start1 = clock(); - double thetaf,rhof; - for(k=0;k<NUM2;k++) - for(i=0;i<num;i++) { - polar(c[i],s[i],&rhof, &thetaf); - } - clock_t end1 = clock(); - - clock_t start2 = clock(); - double rho,theta; - for(k=0;k<NUM2;k++) - for(i=0;i<num;i++) { - polar2(c[i],s[i],&rho, &theta); - } - clock_t end2 = clock(); - - float seconds1 = (end1-start1)/((float)CLOCKS_PER_SEC); - float seconds2 = (end2-start2)/((float)CLOCKS_PER_SEC); - - printf(" polar: %f polar2: %f\n", seconds1, seconds2); - - printf("Maximum error for polar(): %lf rad = %lf deg\n", max_error, rad2deg(max_error)); -/* printf("Acos() called for %f %f\n", min_acos, max_acos); - printf("Asin() called for %f %f\n", min_asin, max_asin); -*/ return errors; -} diff --git a/sm/csm/mbicp/MbICP.c b/sm/csm/mbicp/MbICP.c deleted file mode 100644 index e0b45ef..0000000 --- a/sm/csm/mbicp/MbICP.c +++ /dev/null @@ -1,678 +0,0 @@ -/*************************************************************************************/ -/* */ -/* File: MbICP.h */ -/* Authors: Luis Montesano and Javier Minguez */ -/* Modified: 1/3/2006 */ -/* */ -/* This library implements the: */ -/* */ -/* J. Minguez, F. Lamiraux and L. Montesano */ -/* Metric-Based Iterative Closest Point, */ -/* Scan Matching for Mobile Robot Displacement Estimation */ -/* IEEE Transactions on Roboticics (2006) */ -/* */ -/*************************************************************************************/ - - -#include "MbICP.h" -#include "MbICP2.h" -#include "calcul.h" -#include "sp_matrix.h" -#include <stdio.h> -#include <math.h> -#include "percolate.h" - -#ifndef M_PI - #define M_PI 3.14159265358979323846 -#endif - -// Initial error to compute error ratio -#define BIG_INITIAL_ERROR 1000000.0F - -// Debugging flag. Print sm info in the screen. -// #define INTMATSM_DEB - - -// --------------------------------------------------------------- -// --------------------------------------------------------------- -// Types definition -// --------------------------------------------------------------- -// --------------------------------------------------------------- - - - -// --------------------------------------------------------------- -// --------------------------------------------------------------- -// Variables definition -// --------------------------------------------------------------- -// --------------------------------------------------------------- - -float MAXLASERRANGE; - - -// ************************ -// Extern variables - -// structure to initialize the SM parameters -TSMparams params; - -// Original points to be aligned -Tscan ptosRef; -Tscan ptosNew; - -// Structure of the associations before filtering -TAsoc cp_associations[MAXLASERPOINTS]; -int cntAssociationsT; - -// Filtered Associations -TAsoc cp_associationsTemp[MAXLASERPOINTS]; -int cntAssociationsTemp; - -// Those points removed by the projection filter -Tscan ptosNoView; - -// Current motion estimation -Tsc motion2; - - -// ************************ -// Some precomputations for each scan to speed up -static float refdqx[MAXLASERPOINTS]; -static float refdqx2[MAXLASERPOINTS]; -static float refdqy[MAXLASERPOINTS]; -static float refdqy2[MAXLASERPOINTS]; -static float distref[MAXLASERPOINTS]; -static float refdqxdqy[MAXLASERPOINTS]; - - -// value of errors -static float error_k1; -static int numConverged; - - -// --------------------------------------------------------------- -// --------------------------------------------------------------- -// Protos of the functions -// --------------------------------------------------------------- -// --------------------------------------------------------------- - -// Function for compatibility with the scans -static void preProcessingLib(Tpfp *laserK, Tpfp *laserK1, - Tsc *initialMotion); - -// Function that does the association step of the MbICP -static int EStep(); - -// Function that does the minimization step of the MbICP -static int MStep(Tsc *solucion); - -// Function to do the least-squares but optimized for the metric -static int computeMatrixLMSOpt(TAsoc *cp_ass, int cnt, Tsc *estimacion); - -// --------------------------------------------------------------- -// --------------------------------------------------------------- -// External functions -// --------------------------------------------------------------- -// --------------------------------------------------------------- - -// ************************ -// Function that initializes the SM parameters -// ************************ - -void Init_MbICP_ScanMatching(float max_laser_range,float Bw, float Br, - float L, int laserStep, - float MaxDistInter, - float filter, - int ProjectionFilter, - float AsocError, - int MaxIter, float error_ratio, - float error_x, float error_y, float error_t, int IterSmoothConv){ - - #ifdef INTMATSM_DEB - printf("-- Init EM params . . "); - #endif - - MAXLASERRANGE = max_laser_range; - params.Bw = Bw; - params.Br = Br*Br; - params.error_th=error_ratio; - params.MaxIter=MaxIter; - params.LMET=L; - params.laserStep=laserStep; - params.MaxDistInter=MaxDistInter; - params.filter=filter; - params.ProjectionFilter=ProjectionFilter; - params.AsocError=AsocError; - params.errx_out=error_x; - params.erry_out=error_y; - params.errt_out=error_t; - params.IterSmoothConv=IterSmoothConv; - - #ifdef INTMATSM_DEB - printf(". OK!\n"); - #endif - -} - - -// ************************ -// Function that initializes the SM parameters -// ************************ - -int MbICPmatcher(Tpfp *laserK, Tpfp *laserK1, - Tsc *sensorMotion, Tsc *solution){ - - int resEStep=1; - int resMStep=1; - int numIteration=0; - - // Preprocess both scans - preProcessingLib(laserK,laserK1,sensorMotion); - - while (numIteration<params.MaxIter){ - - // Compute the correspondences of the MbICP - resEStep=EStep();; - - if (resEStep!=1) - return -1; - - // Minize and compute the solution - resMStep=MStep(solution); - - if (resMStep==1) - return 1; - else if (resMStep==-1) - return -2; - else - numIteration++; - } - - return 2; - -} - - - -// --------------------------------------------------------------- -// --------------------------------------------------------------- -// Inner functions -// --------------------------------------------------------------- -// --------------------------------------------------------------- - -// ************************ -// Function that does the association step of the MbICP -// ************************ - -static int EStep() -{ - int cnt; - int i,J; - - static Tscan ptosNewRef; - static int indexPtosNewRef[MAXLASERPOINTS]; - - int L,R,Io; - float dist; - float cp_ass_ptX,cp_ass_ptY,cp_ass_ptD; - float tmp_cp_indD; - - float q1x, q1y, q2x,q2y,p2x,p2y, dqx, dqy, dqpx, dqpy, qx, qy,dx,dy; - float landaMin; - float A,B,C,D; - float LMET2; - - LMET2=params.LMET*params.LMET; - - - // Transform the points according to the current pose estimation - - ptosNewRef.numPuntos=0; - for (i=0; i<ptosNew.numPuntos; i++){ - transfor_directa_p ( ptosNew.laserC[i].x, ptosNew.laserC[i].y, - &motion2, &ptosNewRef.laserC[ptosNewRef.numPuntos]); - car2pol(&ptosNewRef.laserC[ptosNewRef.numPuntos],&ptosNewRef.laserP[ptosNewRef.numPuntos]); - ptosNewRef.numPuntos++; - } - - // ---- - /* Projection Filter */ - /* Eliminate the points that cannot be seen */ - /* Furthermore it orders the points with the angle */ - - cnt = 1; /* Becarefull with this filter (order) when the angles are big >90 */ - ptosNoView.numPuntos=0; - if (params.ProjectionFilter==1){ - for (i=1;i<ptosNewRef.numPuntos;i++){ - if (ptosNewRef.laserP[i].t>=ptosNewRef.laserP[cnt-1].t){ - ptosNewRef.laserP[cnt]=ptosNewRef.laserP[i]; - ptosNewRef.laserC[cnt]=ptosNewRef.laserC[i]; - cnt++; - } - else{ - ptosNoView.laserP[ptosNoView.numPuntos]=ptosNewRef.laserP[i]; - ptosNoView.laserC[ptosNoView.numPuntos]=ptosNewRef.laserC[i]; - ptosNoView.numPuntos++; - } - } - ptosNewRef.numPuntos=cnt; - } - - - // ---- - /* Build the index for the windows (this is the role of the Bw parameter */ - /* The correspondences are searched between windows in both scans */ - /* Like this you speed up the algorithm */ - - L=0; R=0; /* index of the window for ptoRef */ - Io=0; /* index of the window for ptoNewRef */ - - if (ptosNewRef.laserP[Io].t<ptosRef.laserP[L].t) { - if (ptosNewRef.laserP[Io].t + params.Bw < ptosRef.laserP[L].t){ - while (Io<ptosNewRef.numPuntos-1 && ptosNewRef.laserP[Io].t + params.Bw < ptosRef.laserP[L].t) { - Io++; - } - } - else{ - while (R<ptosRef.numPuntos-1 && ptosNewRef.laserP[Io].t + params.Bw > ptosRef.laserP[R+1].t) - R++; - } - } - else{ - while (L<ptosRef.numPuntos-1 && ptosNewRef.laserP[Io].t - params.Bw > ptosRef.laserP[L].t) - L++; - R=L; - while (R<ptosRef.numPuntos-1 && ptosNewRef.laserP[Io].t + params.Bw > ptosRef.laserP[R+1].t) - R++; - } - - // ---- - /* Look for potential correspondences between the scans */ - /* Here is where we use the windows */ - - cnt=0; - for (i=Io;i<ptosNewRef.numPuntos;i++){ - - // Keep the index of the original scan ordering - cp_associations[cnt].index=indexPtosNewRef[i]; - - // Move the window - while (L < ptosRef.numPuntos-1 && ptosNewRef.laserP[i].t - params.Bw > ptosRef.laserP[L].t) - L = L + 1; - while (R <ptosRef.numPuntos-1 && ptosNewRef.laserP[i].t + params.Bw > ptosRef.laserP[R+1].t) - R = R + 1; - - cp_associations[cnt].L=L; - cp_associations[cnt].R=R; - - if (L==R){ - // Just one possible correspondence - - // precompute stuff to speed up - qx=ptosRef.laserC[R].x; qy=ptosRef.laserC[R].y; - p2x=ptosNewRef.laserC[i].x; p2y=ptosNewRef.laserC[i].y; - dx=p2x-qx; dy=p2y-qy; - dist=dx*dx+dy*dy-(dx*qy-dy*qx)*(dx*qy-dy*qx)/(qx*qx+qy*qy+LMET2); - - if (dist<params.Br){ - cp_associations[cnt].nx=ptosNewRef.laserC[i].x; - cp_associations[cnt].ny=ptosNewRef.laserC[i].y; - cp_associations[cnt].rx=ptosRef.laserC[R].x; - cp_associations[cnt].ry=ptosRef.laserC[R].y; - cp_associations[cnt].dist=dist; - cnt++; - } - } - else if (L<R) - { - // More possible correspondences - - cp_ass_ptX=0; - cp_ass_ptY=0; - cp_ass_ptD=100000; - - /* Metric based Closest point rule */ - for (J=L+1;J<=R;J++){ - - // Precompute stuff to speed up - q1x=ptosRef.laserC[J-1].x; q1y=ptosRef.laserC[J-1].y; - q2x=ptosRef.laserC[J].x; q2y=ptosRef.laserC[J].y; - p2x=ptosNewRef.laserC[i].x; p2y=ptosNewRef.laserC[i].y; - - dqx=refdqx[J-1]; dqy=refdqy[J-1]; - dqpx=q1x-p2x; dqpy=q1y-p2y; - A=1/(p2x*p2x+p2y*p2y+LMET2); - B=(1-A*p2y*p2y); - C=(1-A*p2x*p2x); - D=A*p2x*p2y; - - landaMin=(D*(dqx*dqpy+dqy*dqpx)+B*dqx*dqpx+C*dqy*dqpy)/(B*refdqx2[J-1]+C*refdqy2[J-1]+2*D*refdqxdqy[J-1]); - - if (landaMin<0){ // Out of the segment on one side - qx=q1x; qy=q1y;} - else if (landaMin>1){ // Out of the segment on the other side - qx=q2x; qy=q2y;} - else if (distref[J-1]<params.MaxDistInter) { // Within the segment and interpotation OK - qx=(1-landaMin)*q1x+landaMin*q2x; - qy=(1-landaMin)*q1y+landaMin*q2y; - } - else{ // Segment too big do not interpolate - if (landaMin<0.5){ - qx=q1x; qy=q1y;} - else{ - qx=q2x; qy=q2y;} - } - - // Precompute stuff to see if we save the association - dx=p2x-qx; - dy=p2y-qy; - tmp_cp_indD=dx*dx+dy*dy-(dx*qy-dy*qx)*(dx*qy-dy*qx)/(qx*qx+qy*qy+LMET2); - - // Check if the association is the best up to now - if (tmp_cp_indD < cp_ass_ptD){ - cp_ass_ptX=qx; - cp_ass_ptY=qy; - cp_ass_ptD=tmp_cp_indD; - } - } - - // Association compatible in distance (Br parameter) - if (cp_ass_ptD< params.Br){ - cp_associations[cnt].nx=ptosNewRef.laserC[i].x; - cp_associations[cnt].ny=ptosNewRef.laserC[i].y; - cp_associations[cnt].rx=cp_ass_ptX; - cp_associations[cnt].ry=cp_ass_ptY; - cp_associations[cnt].dist=cp_ass_ptD; - - cnt++; - } - } - else { // This cannot happen but just in case ... - cp_associations[cnt].nx=ptosNewRef.laserC[i].x; - cp_associations[cnt].ny=ptosNewRef.laserC[i].y; - cp_associations[cnt].rx=0; - cp_associations[cnt].ry=0; - cp_associations[cnt].dist=params.Br; - cnt++; - } - } // End for (i=Io;i<ptosNewRef.numPuntos;i++){ - - cntAssociationsT=cnt; - - // Check if the number of associations is ok - if (cntAssociationsT<ptosNewRef.numPuntos*params.AsocError){ - #ifdef INTMATSM_DEB - printf("Number of associations too low <%d out of %f>\n", - cntAssociationsT,ptosNewRef.numPuntos*params.AsocError); - #endif - return 0; - } - - return 1; -} - - -// ************************ -// Function that does the minimization step of the MbICP -// ************************ - -static int MStep(Tsc *solucion){ - - Tsc estim_cp; - int i,cnt,res; - float error_ratio, error; - float cosw, sinw, dtx, dty, tmp1, tmp2; - static TAsoc cp_tmp[MAXLASERPOINTS+1]; - - // Filtering of the spurious data - // Used the trimmed versions that orders the point by distance between associations - - if (params.filter<1){ - - // Add Null element in array position 0 (this is because heapsort requirement) - for (i=0;i<cntAssociationsT;i++){ - cp_tmp[i+1]=cp_associations[i]; - } - cp_tmp[0].dist=-1; - // Sort array - heapsort(cp_tmp, cntAssociationsT); - // Filter out big distances - cnt=((int)(cntAssociationsT*100*params.filter))/100; - // Remove Null element - for (i=0;i<cnt;i++){ - cp_associationsTemp[i]=cp_tmp[i+1]; - } - } - else{ // Just build the Temp array to minimize - cnt=0; - for (i=0; i<cntAssociationsT;i++){ - if (cp_associations[i].dist<params.Br){ - cp_associationsTemp[cnt]=cp_associations[i]; - cnt++; - } - } - } - - cntAssociationsTemp=cnt; - - #ifdef INTMATSM_DEB - printf("All assoc: %d Filtered: %d Percentage: %f\n", - cntAssociationsT, cntAssociationsTemp, cntAssociationsTemp*100.0/cntAssociationsT); - #endif - - // --- - /* Do de minimization Minimize Metric-based distance */ - /* This function is optimized to speed up */ - - res=computeMatrixLMSOpt(cp_associationsTemp,cnt,&estim_cp); - if (res==-1) - return -1; - - #ifdef INTMATSM_DEB - printf("estim_cp: <%f %f %f>\n",estim_cp.x, estim_cp.y,estim_cp.tita); - printf("New impl: <%f %f %f>\n",estim_cp.x, estim_cp.y,estim_cp.tita); - #endif - - cosw=(float)cos(estim_cp.tita); sinw=(float)sin(estim_cp.tita); - dtx=estim_cp.x; dty=estim_cp.y; - - - // ------ - /* Compute the error of the associations */ - - error=0; - for (i = 0; i<cnt;i++){ - tmp1=cp_associationsTemp[i].nx * cosw - cp_associationsTemp[i].ny * sinw + dtx - cp_associationsTemp[i].rx;tmp1*=tmp1; - tmp2=cp_associationsTemp[i].nx * sinw + cp_associationsTemp[i].ny * cosw + dty - cp_associationsTemp[i].ry;tmp2*=tmp2; - error = error+ tmp1+tmp2; - } - - error_ratio = error / error_k1; - - #ifdef INTMATSM_DEB - printf("<err,errk1,errRatio>=<%f,%f,%f>\n estim=<%f,%f,%f>\n", - error,error_k1,error_ratio, estim_cp.x,estim_cp.y, estim_cp.tita); - #endif - - // ---- - /* Check the exit criteria */ - /* Error ratio */ - if (fabs(1.0-error_ratio)<=params.error_th || - (fabs(estim_cp.x)<params.errx_out && fabs(estim_cp.y)<params.erry_out - && fabs(estim_cp.tita)<params.errt_out) ){ - numConverged++; - } - else - numConverged=0; - - //-- - /* Build the solution */ - composicion_sis(&estim_cp, &motion2, solucion); - motion2=*solucion; - error_k1=error; - - /* Number of iterations doing convergence (smooth criterion of convergence) */ - if (numConverged>params.IterSmoothConv) - return 1; - else - return 0; -} - - -// ************************ -// Function to do the least-squares but optimized for the metric -// ************************ - -static int computeMatrixLMSOpt(TAsoc *cp_ass, int cnt, Tsc *estimacion) { - - int i; - float LMETRICA2; - float X1[MAXLASERPOINTS], Y1[MAXLASERPOINTS]; - float X2[MAXLASERPOINTS],Y2[MAXLASERPOINTS]; - float X2Y2[MAXLASERPOINTS],X1X2[MAXLASERPOINTS]; - float X1Y2[MAXLASERPOINTS], Y1X2[MAXLASERPOINTS]; - float Y1Y2[MAXLASERPOINTS]; - float K[MAXLASERPOINTS], DS[MAXLASERPOINTS]; - float DsD[MAXLASERPOINTS], X2DsD[MAXLASERPOINTS], Y2DsD[MAXLASERPOINTS]; - float Bs[MAXLASERPOINTS], BsD[MAXLASERPOINTS]; - float A1, A2, A3, B1, B2, B3, C1, C2, C3, D1, D2, D3; - MATRIX matA,invMatA; - VECTOR vecB,vecSol; - - A1=0;A2=0;A3=0;B1=0;B2=0;B3=0; - C1=0;C2=0;C3=0;D1=0;D2=0;D3=0; - - - LMETRICA2=params.LMET*params.LMET; - - for (i=0; i<cnt; i++){ - X1[i]=cp_ass[i].nx*cp_ass[i].nx; - Y1[i]=cp_ass[i].ny*cp_ass[i].ny; - X2[i]=cp_ass[i].rx*cp_ass[i].rx; - Y2[i]=cp_ass[i].ry*cp_ass[i].ry; - X2Y2[i]=cp_ass[i].rx*cp_ass[i].ry; - - X1X2[i]=cp_ass[i].nx*cp_ass[i].rx; - X1Y2[i]=cp_ass[i].nx*cp_ass[i].ry; - Y1X2[i]=cp_ass[i].ny*cp_ass[i].rx; - Y1Y2[i]=cp_ass[i].ny*cp_ass[i].ry; - - K[i]=X2[i]+Y2[i] + LMETRICA2; - DS[i]=Y1Y2[i] + X1X2[i]; - DsD[i]=DS[i]/K[i]; - X2DsD[i]=cp_ass[i].rx*DsD[i]; - Y2DsD[i]=cp_ass[i].ry*DsD[i]; - - Bs[i]=X1Y2[i]-Y1X2[i]; - BsD[i]=Bs[i]/K[i]; - - A1=A1 + (1-Y2[i]/K[i]); - B1=B1 + X2Y2[i]/K[i]; - C1=C1 + (-cp_ass[i].ny + Y2DsD[i]); - D1=D1 + (cp_ass[i].nx - cp_ass[i].rx -cp_ass[i].ry*BsD[i]); - - A2=B1; - B2=B2 + (1-X2[i]/K[i]); - C2=C2 + (cp_ass[i].nx-X2DsD[i]); - D2=D2 + (cp_ass[i].ny -cp_ass[i].ry +cp_ass[i].rx*BsD[i]); - - A3=C1; - B3=C2; - C3=C3 + (X1[i] + Y1[i] - DS[i]*DS[i]/K[i]); - D3=D3 + (Bs[i]*(-1+DsD[i])); - } - - - initialize_matrix(&matA,3,3); - MDATA(matA,0,0)=A1; MDATA(matA,0,1)=B1; MDATA(matA,0,2)=C1; - MDATA(matA,1,0)=A2; MDATA(matA,1,1)=B2; MDATA(matA,1,2)=C2; - MDATA(matA,2,0)=A3; MDATA(matA,2,1)=B3; MDATA(matA,2,2)=C3; - - if (inverse_matrix (&matA, &invMatA)==-1) - return -1; - -#ifdef INTMATSM_DEB - print_matrix("inverted matrix", &invMatA); -#endif - - initialize_vector(&vecB,3); - VDATA(vecB,0)=D1; VDATA(vecB,1)=D2; VDATA(vecB,2)=D3; - multiply_matrix_vector (&invMatA, &vecB, &vecSol); - - estimacion->x=-VDATA(vecSol,0); - estimacion->y=-VDATA(vecSol,1); - estimacion->tita=-VDATA(vecSol,2); - - return 1; -} - - -// ------------------------------------ -// Function added by Javi for compatibility -// ------------------------------------ - -static void preProcessingLib(Tpfp *laserK, Tpfp *laserK1, - Tsc *initialMotion) -{ - - int i,j; - - motion2=*initialMotion; - - // ------------------------------------------------// - // Compute xy coordinates of the points in laserK1 - ptosNew.numPuntos=0; - for (i=0; i<MAXLASERPOINTS; i++) { - if (laserK1[i].r <MAXLASERRANGE){ - ptosNew.laserP[ptosNew.numPuntos].r=laserK1[i].r; - ptosNew.laserP[ptosNew.numPuntos].t=laserK1[i].t; - ptosNew.laserC[ptosNew.numPuntos].x=(float)(laserK1[i].r * cos(laserK1[i].t)); - ptosNew.laserC[ptosNew.numPuntos].y=(float)(laserK1[i].r * sin(laserK1[i].t)); - ptosNew.numPuntos++; - } - } - - // Choose one point out of params.laserStep points - j=0; - for (i=0; i<ptosNew.numPuntos; i+=params.laserStep) { - ptosNew.laserC[j]=ptosNew.laserC[i]; - j++; - } - ptosNew.numPuntos=j; - - // Compute xy coordinates of the points in laserK - ptosRef.numPuntos=0; - for (i=0; i<MAXLASERPOINTS; i++) { - if (laserK[i].r <MAXLASERRANGE){ - ptosRef.laserP[ptosRef.numPuntos].r=laserK[i].r; - ptosRef.laserP[ptosRef.numPuntos].t=laserK[i].t; - ptosRef.laserC[ptosRef.numPuntos].x=(float)(laserK[i].r * cos(laserK1[i].t)); - ptosRef.laserC[ptosRef.numPuntos].y=(float)(laserK[i].r * sin(laserK1[i].t)); - ptosRef.numPuntos++; - } - } - - // Choose one point out of params.laserStep points - j=0; - for (i=0; i<ptosRef.numPuntos; i+=params.laserStep) { - ptosRef.laserC[j]=ptosRef.laserC[i]; - j++; - } - ptosRef.numPuntos=j; - // ------------------------------------------------// - - // Preprocess reference points - for (i=0;i<ptosRef.numPuntos-1;i++) { - car2pol(&ptosRef.laserC[i],&ptosRef.laserP[i]); - refdqx[i]=ptosRef.laserC[i].x - ptosRef.laserC[i+1].x; - refdqy[i]=ptosRef.laserC[i].y - ptosRef.laserC[i+1].y; - refdqx2[i]=refdqx[i]*refdqx[i]; - refdqy2[i]=refdqy[i]*refdqy[i]; - distref[i]=refdqx2[i] + refdqy2[i]; - refdqxdqy[i]=refdqx[i]*refdqy[i]; - } - car2pol(&ptosRef.laserC[ptosRef.numPuntos-1],&ptosRef.laserP[ptosRef.numPuntos-1]); - - error_k1=BIG_INITIAL_ERROR; - numConverged=0; -} diff --git a/sm/csm/mbicp/MbICP.h b/sm/csm/mbicp/MbICP.h deleted file mode 100644 index 1e27740..0000000 --- a/sm/csm/mbicp/MbICP.h +++ /dev/null @@ -1,163 +0,0 @@ -/*************************************************************************************/ -/* */ -/* File: MbICP.h */ -/* Authors: Luis Montesano and Javier Minguez */ -/* Modified: 1/3/2006 */ -/* */ -/* This library implements the: */ -/* */ -/* */ -/* J. Minguez, L. Montesano, and F. Lamiraux, "Metric-based iterative */ -/* closest point scan matching for sensor displacement estimation," IEEE */ -/* Transactions on Robotics, vol. 22, no. 5, pp. 1047 \u2013 1054, 2006. */ -/*************************************************************************************/ - - -/*****************************************************************************/ -// -// EVERYTHING IN THE INTERNATIONAL SYSTEM (METERS AND RADIANS) -// -/*****************************************************************************/ - -#ifndef MbICP -#define MbICP -#include "TData.h" - -#ifdef __cplusplus -extern "C" { -#endif - - - -// ---------------------------------------------------------------------------- -// GLOBAL FUNCTIONS -// ---------------------------------------------------------------------------- - - -// ************************ -// Function that initializes the SM parameters -// ************************ - -/* void InitScanMatching(float Bw, float Br, - float L, int laserStep,float MaxDistInter, float filtrado, - int MaxIter, float error_th, float exo, float eyo, float etitao, int IterSmoothConv); */ -// in::: - - /* --------------------- */ - /* --- Thresold parameters */ - /* --------------------- */ - /* Bw: maximum angle diference between points of different scans */ - /* Points with greater Bw cannot be correspondent (eliminate spurius asoc.) */ - /* This is a speed up parameter */ - //float Bw; - - /* Br: maximum distance difference between points of different scans */ - /* Points with greater Br cannot be correspondent (eliminate spurius asoc.) */ - //float Br; - - /* --------------------- */ - /* --- Inner parameters */ - /* --------------------- */ - /* L: value of the metric */ - /* When L tends to infinity you are using the standart ICP */ - /* When L tends to 0 you use the metric (more importance to rotation) */ - //float L; - - /* laserStep: selects points of each scan with an step laserStep */ - /* When laserStep=1 uses all the points of the scans */ - /* When laserStep=2 uses one each two ... */ - /* This is an speed up parameter */ - //int laserStep; - - /* ProjectionFilter: */ - /* Eliminate the points that cannot be seen given the two scans (see Lu&Millios 97) */ - /* It works well for angles < 45 \circ*/ - /* 1 : activates the filter */ - /* 0 : desactivates the filter */ - // int ProjectionFilter; - - /* MaxDistInter: maximum distance to interpolate between points in the ref scan */ - /* Consecutive points with less Euclidean distance than MaxDistInter are considered to be a segment */ - //float MaxDistInter; - - /* filter: in [0,1] sets the % of asociations NOT considered spurious */ - /* E.g. if filter=0.9 you use 90% of the associations */ - /* The associations are ordered by distance and the (1-filter) with greater distance are not used */ - /* This type of filtering is called "trimmed-ICP" */ - //float filter; - - /* AsocError: in [0,1] */ - /* One way to check if the algorithm diverges if to supervise if the number of associatios goes below a thresold */ - /* When the number of associations is below AsocError, the main function will return error in associations step */ - // float AsocError; - - /* --------------------- */ - /* --- Exit parameters */ - /* --------------------- */ - /* MaxIter: sets the maximum number of iterations for the algorithm to exit */ - /* The more iterations, the more chance you give the algorithm to be more accurate */ - //int MaxIter; - - /* errorRatio: in [0,1] sets the maximum error ratio between iterations to exit */ - /* In iteration K, let be errorK the residual of the minimization */ - /* Error_th=(errorK-1/errorK). When error_th tends to 1 more precise is the solution of the scan matching */ - //float error_th; - - /* errx_out,erry_out, errt_out: minimum error of the asociations to exit */ - /* In each iteration, the error is the residual of the minimization in each component */ - /* The condition is (errorKx<errx_out && errorKx<erry_out && errorKx<errt_out) */ - /* When errorK tends to 0 the more precise is the solution of the scan matching */ - //float errx_out,erry_out, errt_out; - - /* IterSmoothConv: number of consecutive iterations that satisfity the error criteria (the two above criteria) */ - /* (error_th) OR (errorx_out && errory_out && errt_out) */ - /* With this parameter >1 avoids random solutions and estabilices the algorithm */ - //int IterSmoothConv; - - - -void Init_MbICP_ScanMatching( - float max_laser_range, - float Bw, - float Br, - float L, - int laserStep, - float MaxDistInter, - float filter, - int ProjectionFilter, - float AsocError, - int MaxIter, - float errorRatio, - float errx_out, - float erry_out, - float errt_out, - int IterSmoothConv); - -// ------------------------------------------------------------- - -// ************************ -// Function that does the scan matching -// ************************ - -/* int MbICPmatcher(Tpfp *laserK, Tpfp *laserK1, - Tsc *sensorMotion, Tsc *solution); */ - -// in::: -// laserK: is the reference scan in polar coordinates (max. num points is MAXLASERPOINTS) -// laserK1: is the new scan in polar coordinates (max. num points is MAXLASERPOINTS) -// sensorMotion: initial SENSOR motion estimation from location K to location K1 -// solution: SENSOR motion solution from location K to location K1 -// out::: -// 1 : Everything OK in less that the Maximum number of iterations -// 2 : Everything OK but reached the Maximum number of iterations -// -1: Failure in the association step -// -2: Failure in the minimization step - -int MbICPmatcher(Tpfp *laserK, Tpfp *laserK1, - Tsc *sensorMotion, Tsc *solution); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/sm/csm/mbicp/MbICP2.h b/sm/csm/mbicp/MbICP2.h deleted file mode 100644 index 66d1f27..0000000 --- a/sm/csm/mbicp/MbICP2.h +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************************/ -/* */ -/* File: MbICP.h */ -/* Authors: Luis Montesano and Javier Minguez */ -/* Modified: 1/3/2006 */ -/* */ -/* This library implements the: */ -/* */ -/* J. Minguez, F. Lamiraux and L. Montesano */ -/* Metric-Based Iterative Closest Point, */ -/* Scan Matching for Mobile Robot Displacement Estimation */ -/* IEEE Transactions on Roboticics (2006) */ -/* */ -/*************************************************************************************/ - - -/* **************************************************************************************** */ -// This file contains inner information of the MbICP that you want to see from the outside -/* **************************************************************************************** */ - -#ifndef MbICP2 -#define MbICP2 - -#include "TData.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -// ************************ -// Scan inner matching parameters -typedef struct{ - /* --------------------- */ - /* --- Thresold parameters */ - /* Bw: maximum angle diference between points of different scans */ - /* Points with greater Bw cannot be correspondent (eliminate spurius asoc.) */ - /* This is a speed up parameter */ - float Bw; - - /* Br: maximum distance difference between points of different scans */ - /* Points with greater Br cannot be correspondent (eliminate spurius asoc.) */ - float Br; - - /* --------------------- */ - /* --- Inner parameters */ - - /* L: value of the metric */ - /* When L tends to infinity you are using the standart ICP */ - /* When L tends to 0 you use the metric (more importance to rotation */ - float LMET; - - /* laserStep: selects points of each scan with an step laserStep */ - /* When laserStep=1 uses all the points of the scans */ - /* When laserStep=2 uses one each two ... */ - /* This is an speed up parameter */ - int laserStep; - - /* ProjectionFilter: */ - /* Eliminate the points that cannot be seen given the two scans (see Lu&Millios 97) */ - /* It works well for angles < 45 \circ*/ - /* 1 : activates the filter */ - /* 0 : desactivates the filter */ - int ProjectionFilter; - - /* MaxDistInter: maximum distance to interpolate between points in the ref scan */ - /* Consecutive points with less Euclidean distance than MaxDistInter are considered to be a segment */ - float MaxDistInter; - - /* filtrado: in [0,1] sets the % of asociations NOT considered spurious */ - float filter; - - /* AsocError: in [0,1] */ - /* One way to check if the algorithm diverges if to supervise if the number of associatios goes below a thresold */ - /* When the number of associations is below AsocError, the main function will return error in associations step */ - float AsocError; - - /* --------------------- */ - /* --- Exit parameters */ - /* MaxIter: sets the maximum number of iterations for the algorithm to exit */ - /* More iterations more chance you give the algorithm to be more accurate */ - int MaxIter; - - /* error_th: in [0,1] sets the maximum error ratio between iterations to exit */ - /* In each iteration, the error is the residual of the minimization */ - /* When error_th tends to 1 more precise is the solution of the scan matching */ - float error_th; - - /* errx_out,erry_out, errt_out: minimum error of the asociations to exit */ - /* In each iteration, the error is the residual of the minimization in each component */ - /* The condition is (lower than errx_out && lower than erry_out && lower than errt_out */ - /* When error_XXX tend to 0 more precise is the solution of the scan matching */ - float errx_out,erry_out, errt_out; - - /* IterSmoothConv: number of consecutive iterations that satisfity the error criteria */ - /* (error_th) OR (errorx_out && errory_out && errt_out) */ - /* With this parameter >1 avoids random solutions */ - int IterSmoothConv; - -}TSMparams; - - -// --------------------------------------------------------------- -// --------------------------------------------------------------- -// Variables definition -// --------------------------------------------------------------- -// --------------------------------------------------------------- - - -// ************************ -// Static structure to initialize the SM parameters -extern TSMparams params; - -// Original points to be aligned -extern Tscan ptosRef; -extern Tscan ptosNew; - -// At each step:: - -// Those points removed by the projection filter (see Lu&Millios -- IDC) -extern Tscan ptosNoView; // Only with ProjectionFilter=1; - -// Structure of the associations before filtering -extern TAsoc cp_associations[MAXLASERPOINTS]; -extern int cntAssociationsT; - -// Filtered Associations -extern TAsoc cp_associationsTemp[MAXLASERPOINTS]; -extern int cntAssociationsTemp; - -// Current motion estimation -extern Tsc motion2; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/sm/csm/mbicp/TData.h b/sm/csm/mbicp/TData.h deleted file mode 100644 index 3390dbe..0000000 --- a/sm/csm/mbicp/TData.h +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************/ -/* Last Revised: -$Id: TData.h 4129 2007-08-21 23:16:24Z gerkey $ -*/ -/***************************************************/ - -#ifndef TData -#define TData - -#ifdef __cplusplus -extern "C" { -#endif - -/* - Este fichero contiene los tipos de datos utilizados por todos -*/ - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#define MAXLASERPOINTS 361 - -#define RADIO 0.4F /* Radio del robot */ - -typedef struct { - float x; - float y; -}Tpf; - - -typedef struct { - float r; - float t; -}Tpfp; - -typedef struct { - int x; - int y; -}Tpi; - -typedef struct { - float x; - float y; - float tita; -}Tsc; - -typedef struct { - int numPuntos; - Tpf laserC[MAXLASERPOINTS]; // Cartesian coordinates - Tpfp laserP[MAXLASERPOINTS]; // Polar coordinates -}Tscan; - - -// Associations information -typedef struct{ - float rx,ry,nx,ny,dist; // Point (nx,ny), static corr (rx,ry), dist - int numDyn; // Number of dynamic associations - float unknown; // Unknown weight - int index; // Index within the original scan - int L,R; -}TAsoc; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/sm/csm/mbicp/calcul.c b/sm/csm/mbicp/calcul.c deleted file mode 100644 index c070208..0000000 --- a/sm/csm/mbicp/calcul.c +++ /dev/null @@ -1,187 +0,0 @@ -/***************************************************/ -/* Last Revised: -$Id: calcul.c 4129 2007-08-21 23:16:24Z gerkey $ -*/ -/***************************************************/ - - -#include "calcul.h" - - - -void transfor_directa_p(float x, float y, - Tsc *sistema, Tpf *sol){ - - /* Esta funcion transforma el punto x,y en el sistema de coordenadas mas global*/ - /* Es decir las coordenadas x y son vistas desde el sistema de coordenadas sistema*/ - /* Y se las quiere transformar en el sistema de ref desde el que se sistema*/ - /* Es la transformacion directa */ - - float SinT,CosT; - - SinT=(float)sin(sistema->tita); - CosT=(float)cos(sistema->tita); - - sol->x=x*CosT-y*SinT+sistema->x; - sol->y=x*SinT+y*CosT+sistema->y; - - //fprintf(stderr,"input:<%f,%f> sis:<%f %f %f> sol:<%f %f>\n",x,y,sistema->x, sistema->y, sistema->tita,sol->x, sol->y); - -} - -void transfor_directa_pt0(float x, float y, - Tsc *sistema, Tpf *sol){ - - /* Esta funcion transforma el punto x,y en el sistema de coordenadas mas global*/ - /* Es decir las coordenadas x y son vistas desde el sistema de coordenadas sistema*/ - /* Y se las quiere transformar en el sistema de ref desde el que se sistema*/ - /* Es la transformacion directa */ - - sol->x=x+sistema->x; - sol->y=y+sistema->y; - -} - - -void transfor_inversa_p(float x,float y, - Tsc *sistema, Tpf *sol){ - - /* Esta funcion transforma el punto x,y en el sistema de coordenadas que entra*/ - /* Las coordenadas x y se ven desde el sistema de coordenadas desde el que se tienen las */ - /* las coordenadas de sistema */ - /* Es la transformacion directa */ - - float a13, a23; - float SinT,CosT; - - SinT=(float)sin(sistema->tita); - CosT=(float)cos(sistema->tita); - - - a13=-sistema->y*SinT-sistema->x*CosT; - a23=-sistema->y*CosT+sistema->x*SinT; - - sol->x=x*CosT+y*SinT+a13; - sol->y=-x*SinT+y*CosT+a23; -} - -float NormalizarPI(float ang){ - - return (float)(ang+(2*M_PI)*floor((M_PI-ang)/(2*M_PI))); -} - -void inversion_sis(Tsc *sisIn, Tsc *sisOut){ - - float c,s; - - c=(float)cos(sisIn->tita); - s=(float)sin(sisIn->tita); - sisOut->x =-c*sisIn->x-s*sisIn->y; - sisOut->y = s*sisIn->x-c*sisIn->y; - sisOut->tita = NormalizarPI(-sisIn->tita); -} - -void composicion_sis(Tsc *sis1,Tsc *sis2,Tsc *sisOut){ - - Tpf sol; - - transfor_directa_p(sis2->x, sis2->y, - sis1, &sol); - sisOut->x=sol.x; - sisOut->y=sol.y; - sisOut->tita = NormalizarPI(sis1->tita+sis2->tita); - -} - -void car2pol(Tpf *in, Tpfp *out){ - - out->r=(float)sqrt(in->x*in->x+in->y*in->y); - out->t=(float)atan2(in->y,in->x); -} - -void pol2car(Tpfp *in, Tpf *out){ - - out->x=in->r*(float)cos(in->t); - out->y=in->r*(float)sin(in->t); -} - - - - -int corte_segmentos(float x1,float y1,float x2,float y2, - float x3,float y3,float x4,float y4, - Tpf *sol){ -/* corte de segmentos */ -/* TE DEVUELVE EL PUNTO DE CORTE EN EL SISTEMA QUE ESTEN LOS SEGMENTOS */ - - float a1,a2,b1,b2,c1,c2,xm,ym,denominador,max1_x,max1_y,min1_x,min1_y; - float xerr,yerr; - int si1; - float error_redondeo; - - error_redondeo=(float)0.00001F; - - /* primera recta */ - a1=y2-y1; - b1=x1-x2; - c1=y1*(-b1)-x1*a1; - - /* segunda recta */ - a2=y4-y3; - b2=x3-x4; - c2=y3*(-b2)-x3*a2; - - - denominador=a1*b2-a2*b1; - if (denominador==0) - return 0; - else{ - xm=(b1*c2-b2*c1)/denominador; - ym=(c1*a2-c2*a1)/denominador; - - xerr=xm+error_redondeo; - yerr=ym+error_redondeo; - - /* Comprobamos que cae entre los segmantos */ - if (x1>x2){ - max1_x=x1; min1_x=x2; - } - else{ - max1_x=x2; min1_x=x1; - } - if (y1>y2){ - max1_y=y1; min1_y=y2; - } - else{ - max1_y=y2; min1_y=y1; - } - si1=0; - if (max1_x+error_redondeo>=xm && xerr>=min1_x && max1_y+error_redondeo>=ym && yerr>=min1_y) - si1=1; - - - if (si1){ - - if (x3>x4){ - max1_x=x3; min1_x=x4; - } - else{ - max1_x=x4; min1_x=x3; - } - if (y3>y4){ - max1_y=y3; min1_y=y4; - } - else{ - max1_y=y4; min1_y=y3; - } - - if (max1_x+error_redondeo>=xm && xerr>=min1_x && max1_y+error_redondeo>=ym && yerr>=min1_y){ - sol->x=xm; - sol->y=ym; - return 1; - } - } - return 0; - } -} - diff --git a/sm/csm/mbicp/calcul.h b/sm/csm/mbicp/calcul.h deleted file mode 100644 index 48845b7..0000000 --- a/sm/csm/mbicp/calcul.h +++ /dev/null @@ -1,118 +0,0 @@ -/***************************************************/ -/* Last Revised: -$Id: calcul.h 4129 2007-08-21 23:16:24Z gerkey $ -*/ -/***************************************************/ - -#ifndef Calcul -#define Calcul - -#include <stdio.h> -#include <math.h> -#include "TData.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - Este fichero tiene operaciones de transformacion de sistemas de referencia, - transformaciones de puntos entre sistemas, de paso de coordenadadas polares, - a cartesianas y de corte de segmentos - -*/ - -/* --------------------------------------------------------------------------------------- */ -/* TRANSFORMACIONES DE PUNTO DE UN SISTEMA DE REFERENCIA A OTRO */ -/* --------------------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------------------------- */ -/* transfor_directa_p */ -/* .... Hace la transformacion directa de un punto a un sistema a otro */ -/* .... In: (x,y) las coordenadas del punto, sistema es el sistema de referencia */ -/* .... Out: en sol se devuelve las coordenadas del punto en el nuevo sistema */ - -void transfor_directa_p ( float x, float y, Tsc *sistema, Tpf *sol ); - -/* --------------------------------------------------------------------------------------- */ -/* transfor_directa_p */ -/* .... Hace la transformacion directa de un punto a un sistema a otro */ -/* .... La diferencia es que aqui el punto de entrada es el (0,0) (optimiza la anterior) */ -/* .... In: (x,y) las coordenadas del punto, sistema es el sistema de referencia */ -/* .... Out: en sol se devuelve las coordenadas del punto en el nuevo sistema */ - -void transfor_directa_pt0(float x, float y, - Tsc *sistema, Tpf *sol); - -/* --------------------------------------------------------------------------------------- */ -/* transfor_inversa_p */ -/* .... Hace la transformacion inversa de un punto a un sistema a otro */ -/* .... In: (x,y) las coordenadas del punto, sistema es el sistema de referencia */ -/* .... Out: en sol se devuelve las coordenadas del punto en el nuevo sistema */ - -void transfor_inversa_p ( float x, float y, Tsc *sistema, Tpf *sol ); - -/* --------------------------------------------------------------------------------------- */ -/* TRANSFORMACIONES DE COMPOSICION E INVERSION DE SISTEMAS DE REFERENCIA */ -/* --------------------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------------------------- */ -/* composicion_sis */ -/* .... Realiza la composicion de sistemas de referencia en otro sistema */ -/* .... In: compone sis1 y sis2 */ -/* .... Out: la salida sisOut es el resultado de la composicion de los sistemas */ -/* .... Nota: resulta muy importante el orden de las entradas en la composicion */ - -void composicion_sis(Tsc *sis1,Tsc *sis2,Tsc *sisOut); - -/* --------------------------------------------------------------------------------------- */ -/* inversion_sis */ -/* .... Realiza la inversion de un sistema de referencia */ -/* .... In: sisIn es el sistema a invertir */ -/* .... Out: sisOut es el sistema invertido */ - -void inversion_sis(Tsc *sisIn, Tsc *sisOut); - -/* --------------------------------------------------------------------------------------- */ -/* TRANSFORMACIONES DE PUNTO DE UN SISTEMA DE REFERENCIA A OTRO */ -/* --------------------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------------------------- */ -/* car2pol */ -/* .... Transforma un punto de coordenadas cartesianas a polares */ -/* .... In: el punto en coordenadas cartesianas a transformar */ -/* .... Out: el punto salida en coordenadas polares */ - -void car2pol(Tpf *in, Tpfp *out); - -/* --------------------------------------------------------------------------------------- */ -/* pol2car */ -/* .... Transforma un punto de coordenadas polares a cartesianas */ -/* .... In: el punto entrada en coordenadas polares a transformar */ -/* .... Out: el punto en coordenadas cartesianas transformado */ - -void pol2car(Tpfp *in, Tpf *out); - -/* --------------------------------------------------------------------------------------- */ -/* TRANSFORMACIONES DE PUNTO DE UN SISTEMA DE REFERENCIA A OTRO */ -/* --------------------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------------------------- */ -/* corte_segmentos */ -/* .... Calcula el punto de corte entre dos segmentos */ -/* .... In: las coordenadas de los puntos extremos (x1,y1)-(x2,y2) y (x3,y3)-(x4,y4) */ -/* .... Out: sol son las coordenadas del punto de corte. return --> 1 si hay corte. -->0 no */ - -int corte_segmentos ( float x1, float y1, float x2, float y2, - float x3, float y3, float x4, float y4, - Tpf *sol ); - - -/* Normaliza el angulo entre [-PI, PI] */ -float NormalizarPI(float ang); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/sm/csm/mbicp/mbicp_driver.cc b/sm/csm/mbicp/mbicp_driver.cc deleted file mode 100644 index e84971d..0000000 --- a/sm/csm/mbicp/mbicp_driver.cc +++ /dev/null @@ -1,693 +0,0 @@ -/** @ingroup drivers */ -/** @{ */ -/** @defgroup driver_mbicp mbicp - * @brief ScanMatching - -This driver implements the metric-based ICP scan-matching algorithm. - -J. Minguez, L. Montesano, and F. Lamiraux, "Metric-based iterative -closest point scan matching for sensor displacement estimation," IEEE -Transactions on Robotics, vol. 22, no. 5, pp. 1047 \u2013 1054, 2006. - -@par Compile-time dependencies - -- none - -@par Provides - -- @ref interface_position2d - -@par Requires - -- @ref interface_position2d : source of pose and velocity information -- @ref interface_laser : Pose-stamped laser scans (subtype -PLAYER_LASER_DATA_SCANPOSE) - -@par Configuration requests - -- none - -@par Configuration file options - -- max_laser_range (float) - - Default: 7.9 m - - Maximum laser range. - -- laserPose_x (float) - - Default: 0.16 m - - Offset of the laser on the edge x (in the robot's system of reference). - -- laserPose_y (float) - - Default: 0.0 m - - Offset of the laser on the edge y (in the robot's system of reference). - -- laserPose_th (float) - - Default: 0.0 rad - - Offset of the laser on th (in the robot's system of reference). - -- radial_window (float) - - Default: 0.3 m - - Maximum distance difference between points of different scans. Points - with greater Br cannot be correspondent (eliminate spurius asoc.). - -- angular_window (float) - - Default: 0.523333333 rad - - Maximum angle diference between points of different scans. Points - with greater Bw cannot be correspondent (eliminate spurius asoc.). - -- L (float) - - Default: 3.00 - - Value of the metric. When L tends to infinity you are using the - standart ICP. When L tends to 0 you use the metric (more importance - to rotation), when L tends to infinity you are using Euclidian metric. - -- laserStep (integer) - - Default: 1 - - Selects points of each scan with an step laserStep. - When laserStep=1 uses all the points of the scans - When laserStep=2 uses one each two ... - This is an speed up parameter. - -- MaxDistInter (float) - - Default: 0.5 m - - Maximum distance to interpolate between points in the ref scan. Consecutive - points with less Euclidean distance than MaxDistInter are considered - to be a segment. - -- filter (float) - - Default: 0.95 - - In [0,1] sets the % of asociations NOT considered spurious. E.g. if - filter=0.9 you use 90% of the associations. The associations - are ordered by distance and the (1-filter) with greater distance - are not used. This type of filtering is called "trimmed-ICP". - -- ProjectionFilter (int) - - Default: 1 - - Eliminate the points that cannot be seen given the two scans - (see Lu&Millios 97). It works well for angles < 45 deg. - 1 : activates the filter. - 0 : desactivates the filter. - -- AsocError (float) - - Default: 0.1 - - In [0,1]. Sets the % of minimun associations to run the algorithm. - One way to check if the algorithm diverges is to supervise - if the number of associatios goes below a thresold. When the number - of associations is below AsocError, the main function will return - error in associations step. - -- MaxIter (int) - - Default: 50 - - Sets the maximum number of iterations for the algorithm to exit. The - more iterations, the more chance you give the algorithm to be more accurate. - -- errorRatio (float) - - Default: 0.0001 m - - In [0,1] sets the maximum error ratio between iterations to exit. In - iteration K, let be errorK the residual of the minimization. - Error_th=(errorK-1/errorK). When error_th tends to 1 more precise is - the solution of the scan matching. - -- IterSmoothConv (int) - - Default: 2 - - Number of consecutive iterations that satisfity the error criteria - (the two above criteria) (error_th) OR (errorx_out && errory_out && errt_out). - With this parameter >1 avoids random solutions and estabilices the algorithm. - -- errx_out (float) - - Default: 0.0001 m - - Minimum error in x of the asociations to exit. In each iteration, the error - is the residual of the minimization in each component. The condition is - (errorKx<errx_out && errorKx<erry_out && errorKx<errt_out). When errorK - tends to 0 the more precise is the solution of the scan matching - -- erry_out (float) - - Default: 0.0001 m - - Minimum error in x of the asociations to exit. In each iteration, the error - is the residual of the minimization in each component. The condition is - (errorKx<errx_out && errorKx<erry_out && errorKx<errt_out). When errorK - tends to 0 the more precise is the solution of the scan matching - -- errt_out (float) - - Default: 0.0001 m - - Minimum error in x of the asociations to exit. In each iteration, the error - is the residual of the minimization in each component. The condition is - (errorKx<errx_out && errorKx<erry_out && errorKx<errt_out). When errorK - tends to 0 the more precise is the solution of the scan matching - -@par Example - -@verbatim -driver -( - name "mbicp" - provides ["position2d:1"] - requires ["position2d:0" "laser:1"] - - max_laser_range 7.9 - laserPose_x 0.16 - laserPose_y 0 - laserPose_th 0 - - radial_window 0.3 - angular_window 0.523333333 - - L 3.00 - laserStep 1 - MaxDistInter 0.5 - filter 0.95 - ProjectionFilter 1 - AsocError 0.1 - MaxIter 50 - - errorRatio 0.0001 - errx_out 0.0001 - erry_out 0.0001 - errt_out 0.0001 - IterSmoothConv 2 -) - -@endverbatim - -@author Javier Minguez (underlying algorithm) -*/ -/** @} */ - - -#include <libplayercore/playercore.h> - -#include "calcul.h" -#include "MbICP.h" - -#define LASER_MAX_SAMPLES 1024 - -class mbicp : public Driver -{ - -public: - - mbicp( ConfigFile* cf, int section); - virtual ~mbicp(); - - virtual int Setup(); - virtual int Shutdown(); - - virtual int ProcessMessage(QueuePointer &resp_queue, - player_msghdr * hdr, - void * data); -private: - - float max_laser_range; - float Bw; - float Br; - float L; - int laserStep; - float MaxDistInter; - float filter; - int ProjectionFilter; - float AsocError; - int MaxIter; - float errorRatio; - float errx_out; - float erry_out; - float errt_out; - int IterSmoothConv; - Tsc laserPoseTsc; - - player_pose2d_t lastPoseOdom, - currentPose, - previousPose, - scanmatchingPose; - - player_laser_data_t currentScan, - previousScan; - - bool havePrevious; - - //Compute scanMatching - void compute(); - - //Transform structures between player and Tdata - Tsc playerPose2Tsc(player_pose2d_t posicion); - player_pose2d_t Tsc2playerPose(Tsc posicion); - void playerLaser2Tpfp(player_laser_data_t laserData,Tpfp *laserDataTpfp); - - // Main function for device thread. - virtual void Main(); - - int SetupDevice(); - int ShutdownDevice(); - - // Odometry. - void ProcessOdom(player_msghdr_t* hdr, player_position2d_data_t &data); - - // SubtypeLaser - void ProcessSubtypeLaser(player_msghdr_t* hdr, player_laser_data_scanpose_t &data); - - // Check for new commands from server - void ProcessCommand(player_msghdr_t* hdr, player_position2d_cmd_pos_t &); - - // Setup ScanMatching - void setupScanMatching(); - - // Position - player_devaddr_t posicion_addr; - - // Odometry and laser - Device *odom; - player_devaddr_t odom_addr; - - Device *laser; - player_devaddr_t laser_addr; - -}; - -//////////////////////////////////////////////////////////////////////////////// -Driver* mbicp_Init(ConfigFile* cf, int section){ - - return((Driver*)(new mbicp(cf, section))); - -} - - -//////////////////////////////////////////////////////////////////////////////// -void mbicp_Register(DriverTable* table){ - - table->AddDriver("mbicp", mbicp_Init); - -} - - -//////////////////////////////////////////////////////////////////////////////// -int mbicp::Setup(){ - - havePrevious = false; - - // Initialise the underlying position device. - if(SetupDevice() != 0) - return -1; - - setupScanMatching(); - - puts("Setup Scanmatching"); - // Start the driver thread. - StartThread(); - return 0; - -} - - -//////////////////////////////////////////////////////////////////////////////// -void mbicp::setupScanMatching(){ - -Init_MbICP_ScanMatching( - this->max_laser_range, - this->Bw, - this->Br, - this->L, - this->laserStep, - this->MaxDistInter, - this->filter, - this->ProjectionFilter, - this->AsocError, - this->MaxIter, - this->errorRatio, - this->errx_out, - this->erry_out, - this->errt_out, - this->IterSmoothConv); -} - - -//////////////////////////////////////////////////////////////////////////////// -int mbicp::Shutdown(){ - // Stop the driver thread. - StopThread(); - - // Stop the odom device. - ShutdownDevice(); - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////// -mbicp::mbicp( ConfigFile* cf, int section) - : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, - PLAYER_POSITION2D_CODE){ - - - this->max_laser_range = cf->ReadFloat(section, "max_laser_range", 7.9); - this->Bw = cf->ReadFloat(section, "angular_window", 1.57/3.0); - this->Br = cf->ReadFloat(section, "radial_window", 0.3); - this->L = cf->ReadFloat(section, "L", 3.00); - this->laserStep = cf->ReadInt(section, "laserStep", 1); - this->MaxDistInter = cf->ReadFloat(section, "MaxDistInter", 0.5); - this->filter = cf->ReadFloat(section, "filter", 0.85); - this->ProjectionFilter = cf->ReadInt(section, "ProjectionFilter", 1); - this->AsocError = cf->ReadFloat(section, "AsocError", 0.1); - this->MaxIter = cf->ReadInt(section, "MaxIter", 50); - this->errorRatio = cf->ReadFloat(section, "errorRatio", 0.0001); - this->errx_out = cf->ReadFloat(section, "errx_out", 0.0001); - this->erry_out = cf->ReadFloat(section, "erry_out", 0.0001); - this->errt_out = cf->ReadFloat(section, "errt_out", 0.0001); - this->IterSmoothConv = cf->ReadInt(section, "IterSmoothConv", 2); - this->laserPoseTsc.x = cf->ReadFloat(section, "laserPose_x", 0.16); - this->laserPoseTsc.y = cf->ReadFloat(section, "laserPose_y", 0); - this->laserPoseTsc.tita = cf->ReadFloat(section, "laserPose_th", 0); - - - if(cf->ReadDeviceAddr(&(posicion_addr), section, "provides", - PLAYER_POSITION2D_CODE, -1, NULL) != 0){ - this->SetError(-1); - return; - } - - odom = NULL; - if(cf->ReadDeviceAddr(&odom_addr, section, "requires", - PLAYER_POSITION2D_CODE, -1, NULL) != 0){ - SetError(-1); - return; - } - - laser = NULL; - if(cf->ReadDeviceAddr(&laser_addr, section, "requires", - PLAYER_LASER_CODE, -1, NULL) != 0){ - SetError(-1); - } - - return; -} - - -//////////////////////////////////////////////////////////////////////////////// -mbicp::~mbicp(){ - return; -} - - -//////////////////////////////////////////////////////////////////////////////// -int mbicp::SetupDevice(){ - - if(!(odom = deviceTable->GetDevice(odom_addr))){ - PLAYER_ERROR("Unable to locate suitable position device"); - return -1; - } - if(odom->Subscribe(InQueue) != 0){ - PLAYER_ERROR("Unable to subscribe to position device"); - return -1; - } - - if(!(laser = deviceTable->GetDevice(laser_addr))){ - PLAYER_ERROR("Unable to locate suitable laser device"); - return -1; - } - if(laser->Subscribe(InQueue) != 0){ - PLAYER_ERROR("Unable to subscribe to laser device"); - return -1; - } - - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////// -int mbicp::ShutdownDevice(){ - player_position2d_cmd_vel_t cmd; - - memset(&cmd, 0, sizeof(cmd)); - // Stop the robot (locks the motors) if the motor state is set to - // disabled. The P2OS driver does not respect the motor state. - cmd.vel.px = 0; - cmd.vel.py = 0; - cmd.vel.pa = 0; - - odom->PutMsg(InQueue, PLAYER_MSGTYPE_CMD, PLAYER_POSITION2D_CMD_VEL, - (void*)&cmd,sizeof(cmd),NULL); - - odom->Unsubscribe(InQueue); - laser->Unsubscribe(InQueue); - puts("Shutdown mbicp"); - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////// -void mbicp::Main(){ - while (true){ - // Wait till we get new data - Wait(); - - // Test if we are supposed to cancel this thread. - pthread_testcancel(); - - // Process any pending requests. - ProcessMessages(); - } -} - - -//////////////////////////////////////////////////////////////////////////////// -int mbicp::ProcessMessage(QueuePointer &resp_queue,player_msghdr * hdr, void * data){ - - // PLAYER_LASER_DATA_SCANPOSE - if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,PLAYER_LASER_DATA_SCANPOSE, laser_addr)) - { - assert(hdr->size == sizeof(player_laser_data_scanpose_t)); - ProcessSubtypeLaser(hdr, *reinterpret_cast<player_laser_data_scanpose_t *> (data)); - }else - - // PLAYER_POSITION2D_DATA_STATE - if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,PLAYER_POSITION2D_DATA_STATE, odom_addr)) - { - assert(hdr->size == sizeof(player_position2d_data_t)); - ProcessOdom(hdr, *reinterpret_cast<player_position2d_data_t *> (data)); - }else - - if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_DATA,PLAYER_POSITION2D_DATA_GEOM, odom_addr)) - { - assert(hdr->size == sizeof(player_position2d_data_t)); - player_msghdr_t newhdr = *hdr; - newhdr.addr = device_addr; - Publish(&newhdr, (void*)&data); - }else - - if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,/*PLAYER_POSITION2D_CMD_VEL*/ -1, device_addr)) - { - assert(hdr->size == sizeof(player_position2d_cmd_vel_t)); - // make a copy of the header and change the address - player_msghdr_t newhdr = *hdr; - newhdr.addr = odom_addr; - odom->PutMsg(InQueue, &newhdr, (void*)data); - }else - { - if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ, -1, device_addr)){ - // Pass the request on to the underlying position device and wait for - // the reply. - Message* msg; - - if(!(msg = odom->Request(InQueue, hdr->type, hdr->subtype, (void*)data,hdr->size, &hdr->timestamp))) - { - PLAYER_WARN1("failed to forward config request with subtype: %d\n",hdr->subtype); - return(-1); - } - player_msghdr_t* rephdr = msg->GetHeader(); - void* repdata = msg->GetPayload(); - // Copy in our address and forward the response - rephdr->addr = device_addr; - Publish(resp_queue, rephdr, repdata); - delete msg; - } - } - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -void mbicp::ProcessOdom(player_msghdr_t* hdr,player_position2d_data_t &data) -{ - - - Tsc outComposicion1, - outComposicion2, - outInversion1; - - Tsc lastPoseOdomTsc, - previousPoseTsc, - scanmatchingPoseTsc; - - - lastPoseOdom.px = data.pos.px; - lastPoseOdom.py = data.pos.py; - lastPoseOdom.pa = data.pos.pa; - - if (havePrevious) - { - lastPoseOdomTsc = playerPose2Tsc(lastPoseOdom); - previousPoseTsc = playerPose2Tsc(previousPose); - scanmatchingPoseTsc = playerPose2Tsc(scanmatchingPose); - - inversion_sis(&previousPoseTsc, &outInversion1); - composicion_sis(&outInversion1, &lastPoseOdomTsc, &outComposicion1); - composicion_sis(&scanmatchingPoseTsc, &outComposicion1, &outComposicion2); - - - data.pos.px = outComposicion2.x; - data.pos.py = outComposicion2.y; - data.pos.pa = outComposicion2.tita; - - - } - - player_msghdr_t newhdr = *hdr; - newhdr.addr = device_addr; - Publish(&newhdr, (void*)&data); -} - - -//////////////////////////////////////////////////////////////////////////////// -void mbicp::ProcessSubtypeLaser(player_msghdr_t* hdr,player_laser_data_scanpose_t &data){ - - lastPoseOdom.px = data.pose.px; - lastPoseOdom.py = data.pose.py; - lastPoseOdom.pa = data.pose.pa; - - currentPose = lastPoseOdom; - - currentScan.min_angle = data.scan.min_angle; - currentScan.max_angle = data.scan.max_angle; - currentScan.resolution = data.scan.resolution; - currentScan.max_range = data.scan.max_range; - currentScan.ranges_count = data.scan.ranges_count; - currentScan.intensity_count = data.scan.intensity_count; - currentScan.id = data.scan.id; - - for (unsigned int i=0; i < currentScan.ranges_count; i++){ - currentScan.ranges[i] = data.scan.ranges[i]; - currentScan.intensity[i] = data.scan.intensity[i]; - } - - if (havePrevious && ( currentPose.px != previousPose.px || - currentPose.py != previousPose.py || - currentPose.pa != previousPose.pa)) - { - compute(); - } - - else if (!havePrevious) - { - previousScan = currentScan; - previousPose = currentPose; - scanmatchingPose = currentPose; - havePrevious = true; - } -} - - -//////////////////////////////////////////////////////////////////////////////// -void mbicp::compute() -{ - Tsc previousPoseTsc, - currentPoseTsc, - scanmatchingPoseTsc, - solutionTsc; - - Tsc outComposicion1, - outComposicion2, - outComposicion3, - outComposicion9, - outComposicion10, - outComposicion11, - outInversion1, - outInversion4; - - Tpfp previousScanTpfp[LASER_MAX_SAMPLES], - currentScanTpfp[LASER_MAX_SAMPLES]; - - int salidaMbicp; - - - currentPoseTsc = playerPose2Tsc(currentPose); - previousPoseTsc = playerPose2Tsc(previousPose); - scanmatchingPoseTsc = playerPose2Tsc(scanmatchingPose); - - - composicion_sis(&previousPoseTsc, &laserPoseTsc, &outComposicion1); - composicion_sis(¤tPoseTsc, &laserPoseTsc, &outComposicion2); - inversion_sis(&outComposicion1, &outInversion1); - composicion_sis(&outInversion1, &outComposicion2, &outComposicion3); - - playerLaser2Tpfp(previousScan,previousScanTpfp); - playerLaser2Tpfp(currentScan,currentScanTpfp); - - salidaMbicp = MbICPmatcher(previousScanTpfp,currentScanTpfp,&outComposicion3, &solutionTsc); - - if (salidaMbicp == 1){ - - composicion_sis(&laserPoseTsc,&solutionTsc,&outComposicion9); - inversion_sis(&laserPoseTsc, &outInversion4); - composicion_sis(&outComposicion9,&outInversion4,&outComposicion10); - composicion_sis(&scanmatchingPoseTsc, &outComposicion10, &outComposicion11); - - scanmatchingPoseTsc.x = outComposicion11.x; - scanmatchingPoseTsc.y = outComposicion11.y; - scanmatchingPoseTsc.tita = outComposicion11.tita; - - } - else{ - - if (salidaMbicp == 2) - fprintf(stderr,"2 : Everything OK but reached the Maximum number of iterations\n"); - else{ - if (salidaMbicp == -1) - fprintf(stderr,"Failure in the association step\n"); - if (salidaMbicp == -2) - fprintf(stderr,"Failure in the minimization step\n"); - } - composicion_sis(&laserPoseTsc,&outComposicion3,&outComposicion9); - inversion_sis(&laserPoseTsc, &outInversion4); - composicion_sis(&outComposicion9,&outInversion4,&outComposicion10); - composicion_sis(&scanmatchingPoseTsc, &outComposicion10, &outComposicion11); - - scanmatchingPoseTsc.x = outComposicion11.x; - scanmatchingPoseTsc.y = outComposicion11.y; - scanmatchingPoseTsc.tita = outComposicion11.tita; - - } - - scanmatchingPose = Tsc2playerPose(scanmatchingPoseTsc); - previousScan = currentScan; - previousPose = currentPose; -} - - -//////////////////////////////////////////////////////////////////////////////// -Tsc mbicp::playerPose2Tsc(player_pose2d_t posicion) -{ - Tsc posicionTsc; - - posicionTsc.x = posicion.px; - posicionTsc.y = posicion.py; - posicionTsc.tita = posicion.pa; - return(posicionTsc); -} - - -//////////////////////////////////////////////////////////////////////////////// -player_pose2d_t mbicp::Tsc2playerPose(Tsc posicion) -{ - player_pose2d_t posicionPlayer; - - posicionPlayer.px = posicion.x; - posicionPlayer.py = posicion.y; - posicionPlayer.pa = posicion.tita; - return(posicionPlayer); -} - - -//////////////////////////////////////////////////////////////////////////////// -void mbicp::playerLaser2Tpfp(player_laser_data_t laserData,Tpfp *laserDataTpfp) -{ - for(unsigned int i=0; i< laserData.ranges_count; i++){ - laserDataTpfp[i].r = laserData.ranges[i]; - laserDataTpfp[i].t = laserData.min_angle + (i*laserData.resolution); - } -} diff --git a/sm/csm/mbicp/mbicp_interface.c b/sm/csm/mbicp/mbicp_interface.c deleted file mode 100644 index 724d38e..0000000 --- a/sm/csm/mbicp/mbicp_interface.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "../csm_all.h" - -void sm_mbcip(struct sm_params*input, struct sm_result*output) { - -} - -/* -void mbicp_add_options(struct option* ops, struct hsm_params*p) { - #define prefix "mbicp_" - - options_double(ops, "hsm_linear_cell_size", &p->linear_cell_size, 0.03, "HSM: Size of a rho cell"); - options_double(ops, "hsm_angular_cell_size_deg", &p->angular_cell_size_deg, 1.0, "HSM: Size of angualar cell (deg)"); - options_int(ops, "hsm_num_angular_hypotheses", &p->num_angular_hypotheses, 8, "HSM: Number of angular hypotheses."); - options_double(ops, "hsm_xc_directions_min_distance_deg", &p->xc_directions_min_distance_deg, 10.0, "HSM: Min distance between directions for cross corr (deg)"); - options_int(ops, "hsm_xc_ndirections", &p->xc_ndirections, 3, "HSM: Number of directions for cross corr (deg)"); - options_double(ops, "hsm_angular_hyp_min_distance_deg", &p->angular_hyp_min_distance_deg, 10.0, "HSM: Min distance between different angular hypotheses (deg)"); - - options_int(ops, "hsm_linear_xc_max_npeaks", &p->linear_xc_max_npeaks, 5, "HSM: Number of peaks per direction for linear translation"); - options_double(ops, "hsm_linear_xc_peaks_min_distance", &p->linear_xc_peaks_min_distance, 5.0, "HSM: Min distance between different peaks in linear correlation"); -} - -*/ - - diff --git a/sm/csm/mbicp/percolate.c b/sm/csm/mbicp/percolate.c deleted file mode 100644 index a4a79c5..0000000 --- a/sm/csm/mbicp/percolate.c +++ /dev/null @@ -1,37 +0,0 @@ -#include <stdio.h> -#include "percolate.h" - - -void swapItem(TAsoc *a, TAsoc *b){ - TAsoc c; - - c=*a; - *a=*b; - *b=c; -} - -void perc_down(TAsoc a[], int i, int n) { - int child; TAsoc tmp; - for (tmp=a[i]; i*2 <= n; i=child) { - child = i*2; - if ((child != n) && (a[child+1].dist > a[child].dist)) - child++; - if (tmp.dist < a[child].dist) - a[i] = a[child]; - else - break; - } - a[i] = tmp; -} - -void heapsort(TAsoc a[], int n) { - int i, j; - j = n; - for (i=n/2; i>0; i--) /* BuildHeap */ - perc_down(a,i,j); - i = 1; - for (j=n; j>=2; j--) { - swapItem(&a[i],&a[j]); /* DeleteMax */ - perc_down(a,i,j-1); - } -} diff --git a/sm/csm/mbicp/percolate.h b/sm/csm/mbicp/percolate.h deleted file mode 100644 index 3d36a93..0000000 --- a/sm/csm/mbicp/percolate.h +++ /dev/null @@ -1,18 +0,0 @@ - -#ifndef percolate -#define percolate - -#include "MbICP2.h" -#include "TData.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void heapsort(TAsoc a[], int n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/sm/csm/mbicp/sp_matrix.c b/sm/csm/mbicp/sp_matrix.c deleted file mode 100644 index 168e2f0..0000000 --- a/sm/csm/mbicp/sp_matrix.c +++ /dev/null @@ -1,253 +0,0 @@ -#include <stdio.h> -#include "sp_matrix.h" - -/*****************************************************************************/ - MATRIX create_matrix (int rows, int cols) - -/***************************************************************************** - Creates a MATRIX of dimensions (rows, cols) and initializaes it to zeros. -******************************************************************************/ -{ - MATRIX m; - - MROWS (m) = rows; - MCOLS (m) = cols; - - { - int i, j; - - for (i = 0; i < MROWS (m); i++) - for (j = 0; j < MCOLS (m); j++) - MDATA (m, i, j) = 0; - } - - return m; -} - -/*****************************************************************************/ - void initialize_matrix (MATRIX *m, int rows, int cols) - -/***************************************************************************** - Initializes a MATRIX to dimensions (rows, cols) and content zeros. -******************************************************************************/ -{ - MROWS (*m) = rows; - MCOLS (*m) = cols; - - { - int i, j; - - for (i = 0; i < MROWS (*m); i++) - for (j = 0; j < MCOLS (*m); j++) - MDATA (*m, i, j) = 0; - } - -} - - -/*****************************************************************************/ - void print_matrix (char *message, MATRIX const *m) - -/***************************************************************************** - Print to stdout the contents of MATRIX m. -******************************************************************************/ -{ - int i, j; - - printf ("%s\n",message); - printf("%d %d \n",MROWS (*m),MCOLS (*m)); - if ((MROWS (*m) <= MAX_ROWS) && (MCOLS (*m) <= MAX_COLS)) - for (i = 0; i < MROWS (*m); i++) - { - for (j = 0; j < MCOLS (*m); j++) - printf ("%10.5f ", MDATA (*m, i, j)); - printf ("\n"); - } - else printf ("Dimension incorrecta!"); - printf ("\n"); -} - -/*****************************************************************************/ - VECTOR create_vector (int elements) - -/***************************************************************************** - Initializes a VECTOR to dimension (elements) and its contents to zeros. -******************************************************************************/ -{ - VECTOR v; - - VELEMENTS (v) = elements; - - { - int i; - - for (i = 0; i < VELEMENTS (v); i++) - VDATA (v, i) = 0; - } - - return v; -} - -/*****************************************************************************/ - void initialize_vector (VECTOR *v, int elements) - -/***************************************************************************** - Initializes a VECTOR to dimension (elements) and its contents to zeros. -******************************************************************************/ -{ - VELEMENTS (*v) = elements; - - { - int i; - - for (i = 0; i < VELEMENTS (*v); i++) - VDATA (*v, i) = 0; - } -} - -/*****************************************************************************/ - void print_vector (char *message, VECTOR const *v) - -/***************************************************************************** - Print to stdout the contents of VECTOR m. -******************************************************************************/ -{ - int i; - - printf ("%s\n",message); - if (VELEMENTS (*v) <= MAX_ROWS) - for (i = 0; i < VELEMENTS (*v); i++) - { - printf ("%f ", VDATA (*v, i)); - printf ("\n"); - } - else printf ("Dimension incorrecta!"); - printf ("\n"); -} - -/*****************************************************************************/ - float cross_product (MATRIX const *m, int f1, int c1, int f2, int c2) - -/***************************************************************************** -******************************************************************************/ -{ - return MDATA (*m, f1, c1) * MDATA (*m, f2, c2) - MDATA (*m, f1, c2) * MDATA (*m, f2, c1); -} - -/*****************************************************************************/ -int determinant (MATRIX const *m, float *result) -/***************************************************************************** -******************************************************************************/ -{ - if (!M_SQUARE (*m)) - { - printf ("ERROR (determinant): MATRIX must be square!\n"); - print_matrix ("MATRIX:", m); - return -1; - } - else - { - - if (MROWS (*m) == 1) - *result = MDATA (*m, 0, 0); - else if (MROWS (*m) == 2) - *result = cross_product (m, 0, 0, 1, 1); - else - *result = MDATA (*m, 0, 0) * cross_product (m, 1, 1, 2, 2) - - MDATA (*m, 0, 1) * cross_product (m, 1, 0, 2, 2) - + MDATA (*m, 0, 2) * cross_product (m, 1, 0, 2, 1); - - - return 1; - } -} - -/*****************************************************************************/ - int inverse_matrix (MATRIX const *m, MATRIX *n) - -/***************************************************************************** -******************************************************************************/ -{ - if (!M_SQUARE (*m)) - { - printf ("ERROR (inverse_matrix): MATRIX must be square!\n"); - print_matrix ("MATRIX:", m); - n->cols=0; n->rows=0; - return -1; - } - else - { - float det; - int res; - - res = determinant (m,&det); - - if (res == -1) - { - printf ("ERROR (inverse_matrix): singular MATRIX!\n"); - print_matrix ("MATRIX:", m); - return -1; - } - else - { - initialize_matrix (n, MROWS (*m), MCOLS (*m)); - if (MROWS (*m) == 1) - { - MDATA (*n, 0, 0) = 1 / det ; - } - else if (MROWS (*m) == 2) - { - MDATA (*n, 0, 0) = MDATA (*m, 1, 1) / det ; - MDATA (*n, 0, 1) = -MDATA (*m, 0, 1) / det ; - MDATA (*n, 1, 0) = -MDATA (*m, 1, 0) / det ; - MDATA (*n, 1, 1) = MDATA (*m, 0, 0) / det ; - } - else - { - MDATA (*n, 0, 0) = cross_product (m, 1, 1, 2, 2) / det ; - MDATA (*n, 0, 1) = -cross_product (m, 0, 1, 2, 2) / det ; - MDATA (*n, 0, 2) = cross_product (m, 0, 1, 1, 2) / det ; - MDATA (*n, 1, 0) = -cross_product (m, 1, 0, 2, 2) / det ; - MDATA (*n, 1, 1) = cross_product (m, 0, 0, 2, 2) / det ; - MDATA (*n, 1, 2) = -cross_product (m, 0, 0, 1, 2) / det ; - MDATA (*n, 2, 0) = cross_product (m, 1, 0, 2, 1) / det ; - MDATA (*n, 2, 1) = -cross_product (m, 0, 0, 2, 1) / det ; - MDATA (*n, 2, 2) = cross_product (m, 0, 0, 1, 1) / det ; - } - } - } - return 1; -} - -/*****************************************************************************/ - int multiply_matrix_vector (MATRIX const *m, VECTOR const *v, VECTOR *r) - -/***************************************************************************** - Returns the VECTOR-MATRIX product of m and v in r. -******************************************************************************/ -{ - if (! (MV_COMPAT_DIM (*m, *v))) - { - printf ("ERROR (multiply_matrix_vector): MATRIX and VECTOR dimensions incompatible!\n"); - print_matrix ("MATRIX:", m); - print_vector ("VECTOR:", v); - return -1; /*added 1996-07*/ - } - else - { - int i, j; - float datum; - - VELEMENTS (*r) = MROWS (*m); - - for (i = 0; i < MROWS (*m); i++) - { - datum = 0; - for (j = 0; j < VELEMENTS (*v); j++) - datum = datum + MDATA (*m, i, j) * VDATA (*v, j); - VDATA (*r, i) = datum; - } - } - return 1; -} - diff --git a/sm/csm/mbicp/sp_matrix.h b/sm/csm/mbicp/sp_matrix.h deleted file mode 100644 index 648ae69..0000000 --- a/sm/csm/mbicp/sp_matrix.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - J. Neira - J. A. Castellanos - Robotics and Real Time Group - University of Zaragoza - - sp_matrix.h - Implements basic MATRIX operations -*/ - -#ifndef _SP_MATRIX_H -#define _SP_MATRIX_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_ROWS (7) -#define MAX_COLS (7) - -typedef struct { - int rows; - int cols; - float data[MAX_ROWS][MAX_COLS]; -} MATRIX; - -typedef struct { - int elements; - float data[MAX_ROWS]; -} VECTOR; - -#define DOF (3) - -typedef struct { - int mat[DOF]; - int range; -} BMAT; - -#define MROWS(m) ((m).rows) -#define MCOLS(m) ((m).cols) -#define MDATA(m,i,j) ((m).data[i][j]) - -#define VELEMENTS(v) ((v).elements) -#define VDATA(v,i) ((v).data[i]) - -#define M_SQUARE(m) ((m).rows == (m).cols) -#define M_COMPAT_DIM(m, n) ((m).cols == (n).rows) -#define M_EQUAL_DIM(m, n) (((m).rows == (n).rows) && ((m).cols == (n).cols)) -#define V_EQUAL_DIM(v, w) (((v).elements == (w).elements)) -#define MV_COMPAT_DIM(m, v) ((m).cols == (v).elements) - -#define FIRST(b) ((b).mat[0]) -#define SECOND(b) ((b).mat[1]) -#define THIRD(b) ((b).mat[2]) -#define RANGE(b) ((b).range) - -#define SQUARE(x) ((x)*(x)) - -MATRIX create_matrix (int rows, int cols); -void initialize_matrix (MATRIX *m, int rows, int cols); -void diagonal_matrix (MATRIX *m, int dim, float el1, float el2, float el3); -void print_matrix (char *message, MATRIX const *m); -VECTOR create_vector (int elements); -void initialize_vector (VECTOR *v, int elements); -void print_vector (char *message, VECTOR const *v); -float cross_product (MATRIX const *m, int f1, int c1, int f2, int c2); -int determinant (MATRIX const *m, float *result); -int inverse_matrix (MATRIX const *m, MATRIX *n); -int multiply_matrix_vector (MATRIX const *m, VECTOR const *v, VECTOR *r); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/sm/csm/test_math_utils_sanity.c b/sm/csm/test_math_utils_sanity.c deleted file mode 100644 index 5c7bef0..0000000 --- a/sm/csm/test_math_utils_sanity.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "csm_all.h" -#include <time.h> - -#include "math_utils.h" - -int main() { - - int errors = 0; - double should_be_nan[2] = { 0.0 / 0.0, GSL_NAN }; - - int i; - for(i=0;i<2;i++) { - if(!isnan(should_be_nan[i])) { - printf("#%d: isnan(%f) failed \n", i, should_be_nan[i]); - errors++; - } - if(!is_nan(should_be_nan[i])) { - printf("#%d: is_nan(%f) failed \n", i, should_be_nan[i]); - errors++; - } - } - - return errors; -} diff --git a/sm/header_test.c.in b/sm/header_test.c.in deleted file mode 100644 index d4d891c..0000000 --- a/sm/header_test.c.in +++ /dev/null @@ -1,3 +0,0 @@ -#include "@header@" - -int main() {} \ No newline at end of file diff --git a/sm/lib/egsl/CMakeLists.txt b/sm/lib/egsl/CMakeLists.txt deleted file mode 100644 index 7daa48f..0000000 --- a/sm/lib/egsl/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ - -SET(egsl_sources - egsl.c - egsl_ops.c - egsl_conversions.c - egsl_misc.c -) - -ADD_LIBRARY(egsl STATIC ${egsl_sources}) - -ADD_EXECUTABLE(egsl_test egsl_test.c) -TARGET_LINK_LIBRARIES(egsl_test egsl ${GSL_LIBRARIES}) - -ADD_EXECUTABLE(egsl_test_allocation egsl_test_allocation.c) -TARGET_LINK_LIBRARIES(egsl_test_allocation egsl ${GSL_LIBRARIES}) - - -# installation - -FILE(GLOB headers "*.h") -INSTALL(FILES ${headers} DESTINATION include/egsl) -INSTALL(TARGETS egsl ARCHIVE DESTINATION lib) diff --git a/sm/lib/egsl/docs/Makefile b/sm/lib/egsl/docs/Makefile deleted file mode 100644 index d7c49f0..0000000 --- a/sm/lib/egsl/docs/Makefile +++ /dev/null @@ -1,21 +0,0 @@ - -input=egsl.txt -output=egsl.html - -htmlsection=./htmlsection -no-spacer -markdown=Markdown.pl - -header=header.html_frag -footer=footer.html_frag -tmp=tmp - - -all: $(output) - -$(output): $(input) $(header) $(footer) - $(markdown) $(input) | $(htmlsection) > $(tmp) - cat $(header) $(tmp) $(footer) > $@ - -rm $(tmp) - -clean: - -rm $(output) \ No newline at end of file diff --git a/sm/lib/egsl/docs/egsl.html b/sm/lib/egsl/docs/egsl.html deleted file mode 100644 index 1dcc4ae..0000000 --- a/sm/lib/egsl/docs/egsl.html +++ /dev/null @@ -1,293 +0,0 @@ -<html> -<head> - <title>Easy GSL</title> - <style type="text/css"> - body * { - max-width: 35em; - } - body { - padding-left: 3cm; - } - h1 { margin-left: -1cm;} - h2 { - margin-left: -1cm; margin-top: +1em; - } - h3 { margin-left: -0.5cm;} - - /* Colors */ - body { font-family: Georgia, serif; - background-color: white; - color: #333;} - h1, h2 { color: darkblue;} - h3 { color: #333; } - pre { - margin-left: +1em; - padding: +5px; - background-color: #eee; - color: #00e; - } - </style> - <link rel="stylesheet" type="text/css" href="style.css" /> -</head> -<body> - <h1>Easy GSL: Making GSL easy for simple tasks.</h1> - -<p>This is a small C library for <em>making</em> <strong>simple</strong> <em>matrix -computations</em> <strong>easy</strong>. It is built on top of -<a href="http://www.gnu.org/software/gsl/">the GNU Scientific Library</a>.</p> - -<p> - -<ul compact> -<ul compact> -<li><a href="#subsection_toc1">Introduction</a></li> -<ul compact> -<li><a href="#subsubsection_toc2">Download</a></li> -<li><a href="#subsubsection_toc3">License</a></li> -<li><a href="#subsubsection_toc4">Acknowledgements</a></li> -</ul> -<li><a href="#subsection_toc5">The two main features of <tt>EGSL</tt></a></li> -<ul compact> -<li><a href="#subsubsection_toc6">Feature #1: Automatic (de)allocation of matrices</a></li> -<li><a href="#subsubsection_toc7">Feature #2: Caching of matrices</a></li> -</ul> -<li><a href="#subsection_toc8">Usage</a></li> -<ul compact> -<li><a href="#subsubsection_toc9">Start with a <tt>egsl_push()</tt>, end with a <tt>egsl_pop()</tt></a></li> -<li><a href="#subsubsection_toc10">Promotion of <code>val</code>s to previous contexts</a></li> -<li><a href="#subsubsection_toc11">Useful macros</a></li> -</ul> -<li><a href="#subsection_toc12">Library reference</a></li> -<ul compact> -<li><a href="#subsubsection_toc13">Allocation of matrices</a></li> -<li><a href="#subsubsection_toc14">Operation with matrices</a></li> -<li><a href="#subsubsection_toc15">Accessing matrix elements</a></li> -<li><a href="#subsubsection_toc16">Eigenvalues and eigenvectors</a></li> -<li><a href="#subsubsection_toc17">Conversions</a></li> -<li><a href="#subsubsection_toc18">Printing</a></li> -</ul> -</ul> -</ul> -</p> - -<p><h2><a name="subsection_toc1">Introduction</a></h2></p> - -<p>Albeit very powerful, the GSL is definitely not user-friendly for -making simple matrix computations. -Instead, <code>EGSL</code> will try to <em>fool you into thinking that you are using Matlab</em>.</p> - -<p>Yes, it's that easy! You can forget all of that <code>gsl_matrix_alloc</code> -and <code>gsl_matrix_free</code>.</p> - -<p><h3><a name="subsubsection_toc2">Download</a></h3></p> - -<p>Download from <a href="http://purl.org/censi/2006/egsl">here</a>.</p> - -<p><h3><a name="subsubsection_toc3">License</a></h3></p> - -<p><h3><a name="subsubsection_toc4">Acknowledgements</a></h3></p> - -<p>This documentation is written using <a href="http://daringfireball.net/projects/markdown/">Markdown</a> and a tool called <a href="http://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/htmlsection.html">htmlsection</a>.</p> - -<p><h2><a name="subsection_toc5">The two main features of <tt>EGSL</tt></a></h2></p> - -<p><h3><a name="subsubsection_toc6">Feature #1: Automatic (de)allocation of matrices</a></h3></p> - -<p>Its main feature is that matrices are automatically allocated and -deallocated. For example, you can write:</p> - -<pre><code>egsl_push(); - - val v1 = zeros(10,10); - val v2 = ones(10,10); - - egsl_print("v1+v2=", sum(v1, v2) ); - -egsl_pop(); -</code></pre> - -<p>and not worry about (de)allocation.</p> - -<p><h3><a name="subsubsection_toc7">Feature #2: Caching of matrices</a></h3></p> - -<p>This feature makes <code>EGSL</code> faster than any other C++ equivalent that -uses objects. Consider this code:</p> - -<pre><code>egsl_push(); - -val v1 = zeros(10,10); - -for(int i=0;i<1000000;i++) { - - egsl_push(); - - val v2 = zeros(10,10); - // make some operation on v2 - .... - // add v2 to v1 - add_to(v1, v2); - - egsl_pop(); - -} - -egsl_pop(); - - -// Prints statistics about EGSL's usage of memory -egsl_print_stats(); -</code></pre> - -<p>The output of this program is:</p> - -<pre><code>egsl: total allocations: 2 cache hits: 999999 -</code></pre> - -<p>Even though the loop executes one million times, the total number -of matrix allocations is 2. Note that there is an inner context. -When the loop runs the first time, the <code>gsl_matrix</code> for <code>v2</code> is allocated. -However, when the <code>egsl_pop()</code> is reached, this matrix is not deallocated. -When the loop runs the second time, <code>EGSL</code> detects that you already -allocated a matrix of the requested size and re-utilizes the memory.</p> - -<p><h2><a name="subsection_toc8">Usage</a></h2></p> - -<p>For <code>EGSL</code> to work, you must remember some simple rules:</p> - -<ol> -<li>Always include your code between a pair of <code>egsl_push</code>/<code>egsl_pop</code> calls.</li> -<li>All values are returned as <code>val</code> structs: <code>val</code> object are not valid outside of the context they are created into (unless you tell <code>EGSL</code>).</li> -</ol> - -<p><h3><a name="subsubsection_toc9">Start with a <tt>egsl_push()</tt>, end with a <tt>egsl_pop()</tt></a></h3></p> - -<p>A first, simple program may look like this:</p> - -<pre><code>#include <egsl.h> - -int main() { - // First of all, push a context - egsl_push(); - - // Allocates a matrix - val m1 = egsl_zeros(10, 10); - - // Print it - egsl_print("Your first matrix:", m1); - - egsl_pop(); - - // Wrong: you can't use m1 after egsl_pop() - // egsl_print("Your first matrix:", m1); -} -</code></pre> - -<p><h3><a name="subsubsection_toc10">Promotion of <code>val</code>s to previous contexts</a></h3></p> - -<p>If you want to make a matrix valid also for the previous context, -you may use the <code>egsl_promote(val)</code> function.</p> - -<pre><code>#include <egsl.h> - -int main() { - // First of all, push a context - egsl_push(); - - // push another - egsl_push(); - - // Allocates a matrix - val m1 = egsl_zeros(10, 10); - - val m2 = egsl_promote(m1); - - egsl_pop(); - - // ok, m2 is valid - egsl_print("m2 is valid here", m2); - // error: m1 is not valid here - // egsl_print("m1 is not valid here!", m1); - - - egsl_pop(); -} -</code></pre> - -<p><h3><a name="subsubsection_toc11">Useful macros</a></h3></p> - -<p>If you use the include </p> - -<pre><code>#include <egsl_macros.h> -</code></pre> - -<p>you can use a number of short macros instead of the long-named functions -<code>egsl_*</code>. Most of these macros are inspired by Matlab syntax.</p> - -<p>For example, consider this line of Matlab code (taken from an actual program):</p> - -<pre><code>a = -2 * C_k * v_j1 + 2 * dC_drho_j1 * v2' -</code></pre> - -<p>Translated into EGSL, with macros defined in <code><egsl_macros.h></code>, it turns -into:</p> - -<pre><code>val a = sum(sc(-2,m(C_k,v_j1)), sc(2,m(dC_drho_j1,tr(v2)))); -</code></pre> - -<p>where</p> - -<ul> -<li><code>sum(A, B)</code> is equivalent to <code>A + B</code></li> -<li><code>sc(a, B)</code> is scalar--matrix multiplication: <code>a * B</code></li> -<li><code>m(A, B)</code> is matrix--matrix multiplication; <code>A + B</code></li> -</ul> - -<p>This is the best that we can do without operator overloading. </p> - -<p>Notice that for evaluating this expression <code>EGSL</code> needs a lot of -intermediate matrices, and it's managing all memory allocations for you. -How many <code>egsl_matrix_alloc</code> would you need to write the same code in <code>GSL</code>?</p> - -<p><h2><a name="subsection_toc12">Library reference</a></h2></p> - -<p>This is a summary of available operations. It is shown both the -extended function name (beginning with <code>egsl_</code>) and the macro -defined in <code><egsl_macros.h></code></p> - -<p><h3><a name="subsubsection_toc13">Allocation of matrices</a></h3></p> - -<ul> -<li><code>zeros(rows, cols)</code> (<code>egsl_zeros</code>): Allocates a matrix with all zeros.</li> -<li><code>ones(rows, cols)</code> (<code>egsl_ones</code>): Allocates a matrix with all zeros.</li> -</ul> - -<p><h3><a name="subsubsection_toc14">Operation with matrices</a></h3></p> - -<p>All this functions return a new <code>val</code>:</p> - -<ul> -<li><code>sum(A, B)</code> (<code>egsl_sum</code>): Sums two matrices.</li> -<li><code>sc(a, B)</code> (<code>egsl_scale</code>): Represents scalar--matrix multiplication: <code>a * B</code></li> -<li><code>m(A, B)</code> (<code>egsl_mult</code>): Represents matrix--matrix multiplication; <code>A * B</code></li> -<li><code>inv(A)</code> (<code>egsl_inverse</code>): Returns the inverse of <code>A</code>.</li> -</ul> - -<p><h3><a name="subsubsection_toc15">Accessing matrix elements</a></h3></p> - -<ul> -<li><p><code>egsl_glsm(v)</code> will return you the underlying <code>gsl_matrix</code> for <code>v</code>. -For example:</p> - -<pre><code>val v = egsl_zeros(10,10); -gsl_matrix* m = egsl_gslm(v); -// now do whatever you want with m -</code></pre></li> -</ul> - -<p><h3><a name="subsubsection_toc16">Eigenvalues and eigenvectors</a></h3></p> - -<p><h3><a name="subsubsection_toc17">Conversions</a></h3></p> - -<p><h3><a name="subsubsection_toc18">Printing</a></h3></p> - -</body></html> \ No newline at end of file diff --git a/sm/lib/egsl/docs/egsl.md b/sm/lib/egsl/docs/egsl.md deleted file mode 100644 index 9c05881..0000000 --- a/sm/lib/egsl/docs/egsl.md +++ /dev/null @@ -1,216 +0,0 @@ -Easy GSL: Making GSL easy for simple tasks. -======================================= - -This is a small C library for _making_ **simple** _matrix -computations_ **easy**. It is built on top of -[the GNU Scientific Library](http://www.gnu.org/software/gsl/). - -@toc -* toc - -Introduction ------------- - -Albeit very powerful, the GSL is definitely not user-friendly for -making simple matrix computations. -Instead, `EGSL` will try to *fool you into thinking that you are using Matlab*. - -Yes, it's that easy! You can forget all of that `gsl_matrix_alloc` -and `gsl_matrix_free`. - -### Download ### - -Download from [here](http://purl.org/censi/2006/egsl). - - -The two main features of <tt>EGSL</tt> --------------------------------------- - -### Feature #1: Automatic (de)allocation of matrices ### - -Its main feature is that matrices are automatically allocated and -deallocated. For example, you can write: - - egsl_push(); - - val v1 = zeros(10,10); - val v2 = ones(10,10); - - egsl_print("v1+v2=", sum(v1, v2) ); - - egsl_pop(); - -and not worry about (de)allocation. - - -### Feature #2: Caching of matrices</subsubsection number=no> - -This feature makes `EGSL` faster than any other C++ equivalent that -uses objects. Consider this code: - - egsl_push(); - - val v1 = zeros(10,10); - - for(int i=0;i<1000000;i++) { - - egsl_push(); - - val v2 = zeros(10,10); - // make some operation on v2 - .... - // add v2 to v1 - add_to(v1, v2); - - egsl_pop(); - - } - - egsl_pop(); - - - // Prints statistics about EGSL's usage of memory - egsl_print_stats(); - -The output of this program is: - - egsl: total allocations: 2 cache hits: 999999 - -Even though the loop executes one million times, the total number -of matrix allocations is 2. Note that there is an inner context. -When the loop runs the first time, the `gsl_matrix` for `v2` is allocated. -However, when the `egsl_pop()` is reached, this matrix is not deallocated. -When the loop runs the second time, `EGSL` detects that you already -allocated a matrix of the requested size and re-utilizes the memory. - -## Usage</subsection> - -For `EGSL` to work, you must remember some simple rules: - -1. Always include your code between a pair of `egsl_push`/`egsl_pop` calls. -2. All values are returned as `val` structs: `val` object are not valid outside of the context they are created into (unless you tell `EGSL`). - - -### Start with a <tt>egsl\_push()</tt>, end with a <tt>egsl\_pop()</tt> - -A first, simple program may look like this: - - #include <egsl.h> - - int main() { - // First of all, push a context - egsl_push(); - - // Allocates a matrix - val m1 = egsl_zeros(10, 10); - - // Print it - egsl_print("Your first matrix:", m1); - - egsl_pop(); - - // Wrong: you can't use m1 after egsl_pop() - // egsl_print("Your first matrix:", m1); - } - -### Promotion of `val`s to previous contexts - -If you want to make a matrix valid also for the previous context, -you may use the `egsl_promote(val)` function. - - #include <egsl.h> - - int main() { - // First of all, push a context - egsl_push(); - - // push another - egsl_push(); - - // Allocates a matrix - val m1 = egsl_zeros(10, 10); - - val m2 = egsl_promote(m1); - - egsl_pop(); - - // ok, m2 is valid - egsl_print("m2 is valid here", m2); - // error: m1 is not valid here - // egsl_print("m1 is not valid here!", m1); - - - egsl_pop(); - } - -### Useful macros - -If you use the include - - #include <egsl_macros.h> - -you can use a number of short macros instead of the long-named functions -`egsl_*`. Most of these macros are inspired by Matlab syntax. - -For example, consider this line of Matlab code (taken from an actual program): - - a = -2 * C_k * v_j1 + 2 * dC_drho_j1 * v2' - -Translated into EGSL, with macros defined in `<egsl_macros.h>`, it turns -into: - - val a = sum(sc(-2,m(C_k,v_j1)), sc(2,m(dC_drho_j1,tr(v2)))); - -where - -* `sum(A, B)` is equivalent to `A + B` -* `sc(a, B)` is scalar--matrix multiplication: `a * B` -* `m(A, B)` is matrix--matrix multiplication; `A + B` - -This is the best that we can do without operator overloading. - -Notice that for evaluating this expression `EGSL` needs a lot of -intermediate matrices, and it's managing all memory allocations for you. -How many `egsl_matrix_alloc` would you need to write the same code in `GSL`? - -## Library reference</subsection> - -This is a summary of available operations. It is shown both the -extended function name (beginning with `egsl_`) and the macro -defined in `<egsl_macros.h>` - -### Allocation of matrices - -* `zeros(rows, cols)` (`egsl_zeros`): Allocates a matrix with all zeros. -* `ones(rows, cols)` (`egsl_ones`): Allocates a matrix with all zeros. - -### Operation with matrices - -All this functions return a new `val`: - -* `sum(A, B)` (`egsl_sum`): Sums two matrices. -* `sc(a, B)` (`egsl_scale`): Represents scalar--matrix multiplication: `a * B` -* `m(A, B)` (`egsl_mult`): Represents matrix--matrix multiplication; `A * B` -* `inv(A)` (`egsl_inverse`): Returns the inverse of `A`. - -### Accessing matrix elements - -* `egsl_glsm(v)` will return you the underlying `gsl_matrix` for `v`. - For example: - - val v = egsl_zeros(10,10); - gsl_matrix* m = egsl_gslm(v); - // now do whatever you want with m - - -### Eigenvalues and eigenvectors - -### Conversions - -### Printing - - - - - - diff --git a/sm/lib/egsl/docs/egsl.txt b/sm/lib/egsl/docs/egsl.txt deleted file mode 100644 index 0b8e1a8..0000000 --- a/sm/lib/egsl/docs/egsl.txt +++ /dev/null @@ -1,218 +0,0 @@ -Easy GSL: Making GSL easy for simple tasks. -======================================= - -This is a small C library for _making_ **simple** _matrix -computations_ **easy**. It is built on top of -[the GNU Scientific Library](http://www.gnu.org/software/gsl/). - -<tableofcontents></tableofcontents> - -<subsection number=no>Introduction</subsection> - -Albeit very powerful, the GSL is definitely not user-friendly for -making simple matrix computations. -Instead, `EGSL` will try to *fool you into thinking that you are using Matlab*. - -Yes, it's that easy! You can forget all of that `gsl_matrix_alloc` -and `gsl_matrix_free`. - -<subsubsection number=no>Download</subsubsection> - -Download from [here](http://purl.org/censi/2006/egsl). - -<subsubsection number=no>License</subsubsection> - -<subsubsection number=no>Acknowledgements</subsubsection> - -This documentation is written using [Markdown](http://daringfireball.net/projects/markdown/) and a tool called [htmlsection](http://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/htmlsection.html). - -<subsection number=no>The two main features of <tt>EGSL</tt></subsection> - -<subsubsection number=no>Feature #1: Automatic (de)allocation of matrices</subsubsection number=no> - -Its main feature is that matrices are automatically allocated and -deallocated. For example, you can write: - - egsl_push(); - - val v1 = zeros(10,10); - val v2 = ones(10,10); - - egsl_print("v1+v2=", sum(v1, v2) ); - - egsl_pop(); - -and not worry about (de)allocation. - - -<subsubsection number=no>Feature #2: Caching of matrices</subsubsection number=no> - -This feature makes `EGSL` faster than any other C++ equivalent that -uses objects. Consider this code: - - egsl_push(); - - val v1 = zeros(10,10); - - for(int i=0;i<1000000;i++) { - - egsl_push(); - - val v2 = zeros(10,10); - // make some operation on v2 - .... - // add v2 to v1 - add_to(v1, v2); - - egsl_pop(); - - } - - egsl_pop(); - - - // Prints statistics about EGSL's usage of memory - egsl_print_stats(); - -The output of this program is: - - egsl: total allocations: 2 cache hits: 999999 - -Even though the loop executes one million times, the total number -of matrix allocations is 2. Note that there is an inner context. -When the loop runs the first time, the `gsl_matrix` for `v2` is allocated. -However, when the `egsl_pop()` is reached, this matrix is not deallocated. -When the loop runs the second time, `EGSL` detects that you already -allocated a matrix of the requested size and re-utilizes the memory. - -<subsection number=no>Usage</subsection> - -For `EGSL` to work, you must remember some simple rules: - -1. Always include your code between a pair of `egsl_push`/`egsl_pop` calls. -2. All values are returned as `val` structs: `val` object are not valid outside of the context they are created into (unless you tell `EGSL`). - - -<subsubsection number=no>Start with a <tt>egsl\_push()</tt>, end with a <tt>egsl\_pop()</tt></subsubsection> - -A first, simple program may look like this: - - #include <egsl.h> - - int main() { - // First of all, push a context - egsl_push(); - - // Allocates a matrix - val m1 = egsl_zeros(10, 10); - - // Print it - egsl_print("Your first matrix:", m1); - - egsl_pop(); - - // Wrong: you can't use m1 after egsl_pop() - // egsl_print("Your first matrix:", m1); - } - -<subsubsection number=no>Promotion of `val`s to previous contexts</subsubsection> - -If you want to make a matrix valid also for the previous context, -you may use the `egsl_promote(val)` function. - - #include <egsl.h> - - int main() { - // First of all, push a context - egsl_push(); - - // push another - egsl_push(); - - // Allocates a matrix - val m1 = egsl_zeros(10, 10); - - val m2 = egsl_promote(m1); - - egsl_pop(); - - // ok, m2 is valid - egsl_print("m2 is valid here", m2); - // error: m1 is not valid here - // egsl_print("m1 is not valid here!", m1); - - - egsl_pop(); - } - -<subsubsection number=no>Useful macros</subsubsection> - -If you use the include - - #include <egsl_macros.h> - -you can use a number of short macros instead of the long-named functions -`egsl_*`. Most of these macros are inspired by Matlab syntax. - -For example, consider this line of Matlab code (taken from an actual program): - - a = -2 * C_k * v_j1 + 2 * dC_drho_j1 * v2' - -Translated into EGSL, with macros defined in `<egsl_macros.h>`, it turns -into: - - val a = sum(sc(-2,m(C_k,v_j1)), sc(2,m(dC_drho_j1,tr(v2)))); - -where - -* `sum(A, B)` is equivalent to `A + B` -* `sc(a, B)` is scalar--matrix multiplication: `a * B` -* `m(A, B)` is matrix--matrix multiplication; `A + B` - -This is the best that we can do without operator overloading. - -Notice that for evaluating this expression `EGSL` needs a lot of -intermediate matrices, and it's managing all memory allocations for you. -How many `egsl_matrix_alloc` would you need to write the same code in `GSL`? - -<subsection number=no>Library reference</subsection> - -This is a summary of available operations. It is shown both the -extended function name (beginning with `egsl_`) and the macro -defined in `<egsl_macros.h>` - -<subsubsection number=no>Allocation of matrices</subsubsection> - -* `zeros(rows, cols)` (`egsl_zeros`): Allocates a matrix with all zeros. -* `ones(rows, cols)` (`egsl_ones`): Allocates a matrix with all zeros. - -<subsubsection number=no>Operation with matrices</subsubsection> - -All this functions return a new `val`: - -* `sum(A, B)` (`egsl_sum`): Sums two matrices. -* `sc(a, B)` (`egsl_scale`): Represents scalar--matrix multiplication: `a * B` -* `m(A, B)` (`egsl_mult`): Represents matrix--matrix multiplication; `A * B` -* `inv(A)` (`egsl_inverse`): Returns the inverse of `A`. - -<subsubsection number=no>Accessing matrix elements</subsubsection> - -* `egsl_glsm(v)` will return you the underlying `gsl_matrix` for `v`. - For example: - - val v = egsl_zeros(10,10); - gsl_matrix* m = egsl_gslm(v); - // now do whatever you want with m - - -<subsubsection number=no>Eigenvalues and eigenvectors</subsubsection> - -<subsubsection number=no>Conversions</subsubsection> - -<subsubsection number=no>Printing</subsubsection> - - - - - - diff --git a/sm/lib/egsl/docs/footer.html_frag b/sm/lib/egsl/docs/footer.html_frag deleted file mode 100644 index c20b863..0000000 --- a/sm/lib/egsl/docs/footer.html_frag +++ /dev/null @@ -1,2 +0,0 @@ - -</body></html> \ No newline at end of file diff --git a/sm/lib/egsl/docs/header.html_frag b/sm/lib/egsl/docs/header.html_frag deleted file mode 100644 index 07a541b..0000000 --- a/sm/lib/egsl/docs/header.html_frag +++ /dev/null @@ -1,33 +0,0 @@ -<html> -<head> - <title>Easy GSL</title> - <style type="text/css"> - body * { - max-width: 35em; - } - body { - padding-left: 3cm; - } - h1 { margin-left: -1cm;} - h2 { - margin-left: -1cm; margin-top: +1em; - } - h3 { margin-left: -0.5cm;} - - /* Colors */ - body { font-family: Georgia, serif; - background-color: white; - color: #333;} - h1, h2 { color: darkblue;} - h3 { color: #333; } - pre { - margin-left: +1em; - padding: +5px; - background-color: #eee; - color: #00e; - } - </style> - <link rel="stylesheet" type="text/css" href="style.css" /> -</head> -<body> - \ No newline at end of file diff --git a/sm/lib/egsl/docs/htmlsection b/sm/lib/egsl/docs/htmlsection deleted file mode 100755 index 9928096..0000000 --- a/sm/lib/egsl/docs/htmlsection +++ /dev/null @@ -1,1022 +0,0 @@ -#!/usr/bin/perl - -# htmlsection-1.0 -# -# htmlsection - insert section number in HTML and make the table of contents. -# -# * Insert section number in HTML and make links to the section. -# * Make the table of contents. -# * Insert table, figure, and program-list number and make links. -# * Make the index of tables, figures, and program-lists. -# * Insert reference number and make links. -# -# htmlsection Copyright (C) 2001 SAKAI Hiroaki. -# All Rights Reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# SYNOPSIS -# -# htmlsection [-options] [files ...] -# -# DESCRIPTION -# -# htmlsection is a perl script to insert section number in HTML. When you use -# htmlsection, you don't have to manage section, table, figure, program-list, -# and reference numbers and you don't have to make the table of contents, -# table index, figure index, and program-list index. -# -# If files are specified, htmlsection reads HTML from these files. But, if -# files are not specified, htmlsection reads HTML from standard input. -# -# EXAMPLES -# -# * Insert section number in HTML and make links to the section. -# -# htmlsection changes <section></section> tag to <h1></h1> tag and section -# number. You can use tag <section>, <subsection>, ..., and -# <subsubsubsubsubsection>. -# If name option is specified, htmlsection changes <sectionref> tag to the -# number and title of the section and make link to the section. -# If you want not to use number, use number option as <section number=no>. -# -# Example: -# -# For example, make the file example.html as below, -# -------- begin of example -------- -# <section name="intro" number=no>Introduction</section> -# -# This is introduction. -# -# <section name="howto">How to use htmlsection</section> -# -# <subsection name="howtouse">Let's use htmlsection!</subsection> -# -# If you want to know about htmlsection, see -# <sectionref name="howto">, and -# <subsectionref name="howtouse" title=no>. -# -# <section number=no>Ending</section> -# -------- end of example -------- -# -# And execute, -# > cat example.html | htmlsection -# htmlsection will output as, -# -------- begin of example -------- -# <spacer type=vertical size=70> -# <h1><a name="section_intro">Introduction</a></h1> -# <spacer type=vertical size=30> -# -# This is introduction. -# -# <spacer type=vertical size=70> -# <h1><a name="section_howto">1 How to use htmlsection</a></h1> -# <spacer type=vertical size=30> -# -# <spacer type=vertical size=50> -# <h2><a name="subsection_howtouse">1.1 Let's use htmlsection!</a></h2> -# <spacer type=vertical size=25> -# -# If you want to know about htmlsection, see -# <a href="#section_howto">1 How to use htmlsection</a>, and -# <a href="#subsection_howtouse">1.1</a>. -# -# <spacer type=vertical size=70> -# <h1><a name="section_toc2">Ending</a></h1> -# <spacer type=vertical size=30> -# -------- end of example -------- -# -# * Make the table of contents. -# -# htmlsection inserts the table of contents at -# <tableofcontents></tableofcontents> tag. -# -# * Insert table, figure, and program-list number and make links. -# -# htmlsection inserts the number at <tablereference> tag. -# -# Example: -# -# Before convertion -# -------- begin of example -------- -# <center> -# <tablereference name="sample_table">Sample Table</tablereference> -# <table border=1> -# <tr><td align=center>name</td><td align=center>function</td></tr> -# <tr><td>printf</td><td>print strings by a format.</td></tr> -# </table> -# </center> -# -# <p> -# <center> -# <img src="picture/sample.jpg"> -# <br> -# <figurereference name="sample_figure">Sample Figure</figurereference> -# </center> -# -# <p> -# <pre> -# <listreference name="sample_list">Sample List</listreference> -# -# int main() -# { -# int i; -# for (i = 0; i < 10; i++) -# printf("%d\n", i); -# exit (0); -# } -# </pre> -# -# <p> -# See <tableref name="sample_table">. -# See <figureref name="sample_figure">. -# See <listref name="sample_list">. -# -------- end of example -------- -# -# After convertion by htmlsection -# -------- begin of example -------- -# <center> -# <a name="tbl_sample_table">table1: Sample Table</a> -# <table border=1> -# <tr><td align=center>name</td><td align=center>function</td></tr> -# <tr><td>printf</td><td>print strings by a format.</td></tr> -# </table> -# </center> -# -# <p> -# <center> -# <img src="picture/sample.jpg"> -# <br> -# <a name="fig_sample_figure">figure1: Sample Figure</a> -# </center> -# -# <p> -# <pre> -# <a name="lst_sample_list">list1: Sample List</a> -# -# int main() -# { -# int i; -# for (i = 0; i < 10; i++) -# printf("%d\n", i); -# exit (0); -# } -# </pre> -# -# <p> -# See <a href="#tbl_sample_table">table1</a>. -# See <a href="#fig_sample_figure">figure1</a>. -# See <a href="#lst_sample_list">list1</a>. -# -------- end of example -------- -# -# * Make the index of tables, figures, and program-lists. -# -# htmlsection inserts the index of table, figure, and list at -# <tableindex></tableindex>, <figureindex></figureindex>, and -# <listindex></listindex> tag. -# -# * Insert reference number and make links. -# -# htmlsention makes reference table. -# -# Example: -# -# Before convertion -# -------- begin of example -------- -# See <ref name="KandR2">. -# -# <references> -# <reference name="KandR">Brian W. Kernighan and Dennis M. Ritchie, -# "The C Programming Language", Prentice-Hall, 1978. -# <reference name="KandR2">Brian W. Kernighan and Dennis M. Ritchie, -# "The C Programming Language", Second Edition, Prentice Hall, 1988. -# <reference name="NumericalRecipe">William H. Press, Saul A. Teukolsky, -# William T. Vetterling, and Brian P.Flannery, -# "Numerical Recipes in C", Second Edition, Cambridge University Press, 1992. -# </references> -# -------- end of example -------- -# -# After convertion by htmlsection -# -------- begin of example -------- -# See <a href="#ref_KandR2">[2]</a>. -# -# <ul> -# <li><a name="ref_KandR">[1]</a>Brian W. Kernighan and Dennis M. Ritchie, -# "The C Programming Language", Prentice-Hall, 1978. -# <li><a name="ref_KandR2">[2]</a>Brian W. Kernighan and Dennis M. Ritchie, -# "The C Programming Language", Second Edition, Prentice Hall, 1988. -# <li><a name="ref_NumericalRecipe">[3]</a>William H. Press, Saul A. Teukolsky, -# William T. Vetterling, and Brian P.Flannery, -# "Numerical Recipes in C", Second Edition, Cambridge University Press, 1992. -# </ul> -# -------- end of example -------- -# -# OPTIONS -# -# The following options are available: -# -# -h, -help -# Output help messages. -# -# -max-depth [depth] -# Specify the max depth of subsection of section tag. If you specify -# -max-depth 10, you can use <subsubsubsubsubsubsubsubsubsection> tag. -# -# -spacer -# Spacing <section>, <subsection> and <subsubsection> tag. -# -# -no-spacer -# No spacing. -# -# -english, -japanese -# Specify the language. If you don't specify these options, htmlsection -# sees environment variable LANG. -# -# -start-section [section] -# Specify the section number at start. For example, if you specify -# -start-section 3.5.6, htmlsection sets the section number to it at start. -# -# -toc-section [section] -# Specify the section depth to make the table of contents. If you -# specify -toc-section 2, htmlsection makes the table of contents -# by section and subsection only. -# -# -table-section [section] -# Specify the section number at beginning of table number. -# If you specify -table-section 2, format of table number is -# [section_number].[subsection_number].[table_number]. -# If you specify -table-section 0, format of table number is -# [table_number] only. -# -# -figure-section [section], -list-section [section] -# Same as -table-section option. -# -# -start-table [number] -# Specify the table number at start. -# -# -start-figure [number], -start-list [number], -start-ref [number] -# Same as -start-table option. -# -# -toc-file [filename] -# If you specify -toc-file, output the table of contents to the file. -# -# -table-file [filename] -# If you specify -table-file, output the table index to the file. -# -# -figure-file [filename], -list-file [filename] -# Same as -table-file option. -# -# -o [filename] -# Specify the output file. If you don't specify the filename, htmlsection -# outputs HTML to the standard output. -# -# ENVIRONMENT VARIABLES -# -# LANG -# Specify the language. -# -# TAGS -# -# <section>Title</section>, <subsection>Title</subsection>, ... -# options: -# name="section_name" -# number=yes or no -# -# <sectionref>, <subsectionref>, ... -# options: -# name="section_name" -# title=yes or no -# -# <tablereference>Title</tablereference> -# options: -# name="table_name" -# number=yes or no -# -# <figurereference>Title</figurereference> -# options: -# name="figure_name" -# number=yes or no -# -# <listreference>Title</listreference> -# options: -# name="list_name" -# number=yes or no -# -# <tableref>Title</tableref> -# options: -# name="table_name" -# title=yes or no -# -# <figureref>Title</figureref> -# options: -# name="figure_name" -# title=yes or no -# -# <listref>Title</listref> -# options: -# name="list_name" -# title=yes or no -# -# <references></references> -# -# <reference> -# options: -# name="reference_name" -# -# <ref> -# options: -# name="reference_name" -# title=yes or no -# -# <tableofcontents></tableofcontents> -# <tableindex></tableindex> -# <figureindex></figureindex> -# <listindex></listindex> -# -# SEE ALSO -# -# perl(1) -# -# If you want to see more detail information, See, -# Comments at the head of htmlsection script. -# /usr/local/share/doc/htmlsection - Documents. -# /usr/local/share/doc/htmlsection/README - Readme file. -# /usr/local/share/doc/htmlsection/htmlsection.html -# - Sample HTML file and description about htmlsection. -# http://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/htmlsection.html -# -# AUTHOR -# -# Programmed by SAKAI Hiroaki. -# E-Mail: sakai@seki.ee.kagu.sut.ac.jp, hsakai@m8.people.or.jp, -# hsakai@pfu.fujitsu.com -# Web site: -# http://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/index.html -# Mirror site: -# http://hp.vector.co.jp/authors/VA014157/myfreesoft/index.html -# http://www.people.or.jp/~hsakai/myfreesoft/index.html -# - -#use IO::Handle; - -$help_message = " -htmlsection-1.0 - -\thtmlsection [-options] [files ...] - -htmlsection is a perl script to insert section number in HTML. When you use -htmlsection, you don't have to manage section, table, figure, program-list, -and reference numbers and you don't have to make the table of contents, -table index, figure index, and program-list index. - -* Insert section number in HTML and make links to the section. -* Make the table of contents. -* Insert table, figure, and program-list number and make links. -* Make the index of tables, figures, and program-lists. -* Insert reference number and make links. - -If you want to see more detail information, See htmlsection(1), -documents in /usr/local/share/doc/htmlsection, and comments -at the head of htmlsection script. And see, - -\thttp://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/htmlsection.html - -htmlsection Copyright (C) 2001 SAKAI Hiroaki. -All Rights Reserved. - -"; - -$max_depth = 6; -$spacer = 1; -@prev_space = (70, 50, 30); -@next_space = (30, 25, 20); - -for ($i = 0; $i < $max_depth; $i++) { - $section[$i] = 0; -} - -# This is for temporary files. But, temporary files are not used. -# -# -tmpdir [directry] -# Specify the directry to make temporary file. If you don't specify -# -tmpdir option, environment variable TMPDIR will be used. -# -# TMPDIR -# Directry to make the temporary file. If you don't specify environment -# variable TMPDIR and -tmpdir option, /tmp will be used. -# -#$tmpdir = $ENV{"TMPDIR"}; -#if ($tmpdir eq "") { $tmpdir = "/tmp"; } - -$lang = $ENV{"LANG"}; -if (($lang eq "ja_JP.EUC") || ($lang eq "japanese")) { - $lang = "japanese"; -} else { - $lang = "english"; -} - -$table_section_num = 1; -$figure_section_num = 1; -$list_section_num = 1; -$tablenum = 0; -$figurenum = 0; -$listnum = 0; -$refnum = 0; -$toc_filename = ""; -$table_filename = ""; -$figure_filename = ""; -$list_filename = ""; -$output_filename = ""; - -$toc_section = 4; - -while ($_ = shift(@ARGV)) { - - if (($_ eq "-h") || ($_ eq "-help")) { - print "$help_message"; - exit (0); - } - - elsif ($_ eq "-max-depth") { $max_depth = shift(@ARGV); } - elsif ($_ eq "-spacer") { $spacer = 1; } - elsif ($_ eq "-no-spacer") { $spacer = 0; } - elsif ($_ eq "-english" ) { $lang = "english"; } - elsif ($_ eq "-japanese") { $lang = "japanese"; } - elsif ($_ eq "-start-section") { - $sec = shift(@ARGV); - for ($i = 0; $i < $max_depth; $i++) { - ($n) = $sec =~ /^(\d*)/; - $sec =~ s/^(\d*)(\D*)//; - if ($n ne "") { $section[$i] = $n; } - } - } - elsif ($_ eq "-toc-section" ) { $toc_section = shift(@ARGV); } - elsif ($_ eq "-table-section" ) { $table_section_num = shift(@ARGV); } - elsif ($_ eq "-figure-section") { $figure_section_num = shift(@ARGV); } - elsif ($_ eq "-list-section" ) { $list_section_num = shift(@ARGV); } - elsif ($_ eq "-start-table" ) { $tablenum = shift(@ARGV); } - elsif ($_ eq "-start-figure") { $figurenum = shift(@ARGV); } - elsif ($_ eq "-start-list" ) { $listnum = shift(@ARGV); } - elsif ($_ eq "-start-ref" ) { $refnum = shift(@ARGV); } - elsif ($_ eq "-toc-file" ) { $toc_filename = shift(@ARGV); } - elsif ($_ eq "-table-file" ) { $table_filename = shift(@ARGV); } - elsif ($_ eq "-figure-file" ) { $figure_filename = shift(@ARGV); } - elsif ($_ eq "-list-file" ) { $list_filename = shift(@ARGV); } - elsif ($_ eq "-o" ) { $output_filename = shift(@ARGV); } -# This is for temporary files. But, temporary files are not used. -# elsif ($_ eq "-tmpdir") { $tmpdir = shift(@ARGV); } -} - -# This is for temporary files. But, temporary files are not used. -##system ("rm -f $tmpdir/htmlsection.tmp.*"); -#$r = rand(); -#($filename) = $r =~ /(........)$/; -#$filename = "$tmpdir/htmlsection.tmp.$filename"; - -if ($lang eq "japanese") { - $table_string = "ɽ"; - $figure_string = "¿Þ"; - $list_string = "¥ê¥¹¥È"; - $reference_string = "ʸ¸¥"; - $toc_string = "Ìܼ¡"; - $table_index_string = "ɽÌܼ¡"; - $figure_index_string = "¿ÞÌܼ¡"; - $list_index_string = "¥ê¥¹¥ÈÌܼ¡"; - $references_string = "»²¹Íʸ¸¥"; -} else { - $table_string = "table"; - $figure_string = "figure"; - $list_string = "list"; - $reference_string = "Reference"; - $toc_string = "Table of Contents"; - $table_index_string = "Table Index"; - $figure_index_string = "Figure Index"; - $list_index_string = "List Index"; - $references_string = "References"; -} - -@table_toc = (); -@figure_toc = (); -@list_toc = (); - -# This is for temporary files. But, temporary files are not used. -#$filename_num = 0; -#$filename_num++; -#open (WFILE, "> $filename.$filename_num"); - -# This is for debug -#WFILE->autoflush(1); - -$no_space = 0; -$toc_num = 0; -$table_num = 0; -$figure_num = 0; -$list_num = 0; -$ref_num = 0; -$toc = ""; -$depth = 0; -$line = 0; -@lines = (); - -while(<>) { - $line++; - $prev = ""; - $next = ""; - - $sec_flag = 0; - - if (/section/i) { - for ($i = 0; $i < $max_depth; $i++) { - $sub = "sub" x $i; - $sec = $sub . "section"; - while (($tag) = /(<$sec[^>]*?>.*?<\/$sec[^>]*?>)/i) { - $sec_flag = 1; -# if (($i > $depth) && ($i - $depth > 1)) { -# die "line$line: invalid section.\n"; -# } - - ($title) = $tag =~ /<$sec[^>]*?>(.*?)<\/$sec[^>]*?>/i; - ($n) = $tag =~ /<$sec[^>]*?number\s*=\s*([^\s>]*)[\s>]/i; - if ($n =~ /\".*\"/) { ($n) = $n =~ /\"(.*)\"/; } - $number_flag = 1; - if ($n =~ /^yes$/i) { $number_flag = 1; } - elsif ($n =~ /^on$/i ) { $number_flag = 1; } - elsif ($n =~ /^no$/i ) { $number_flag = 0; } - elsif ($n =~ /^off$/i) { $number_flag = 0; } - - if ($number_flag) { - $section[$i]++; - for ($j = $i+1; $j < $max_depth; $j++) { - $section[$j] = 0; - } - - $t = ""; - for ($j = 0; $j <= $i; $j++) { - $t = "$t$section[$j]"; - if ($j < $i) { - $t = "$t."; - } - } - $title = "$t $title"; - } else { - $toc_num++; - $t = "toc$toc_num"; - } - - ($name) = $tag =~ /<$sec[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($name =~ /\".*\"/) { ($name) = $name =~ /\"(.*)\"/; } - $name =~ s/\//\_/g; - if ($name eq "") { $name = "$t"; } - $name = "$sec\_$name"; - if ($sectionref[$i]{$name} ne "") { - die "line$line: duplicate section name: $name\n"; - } - $sectionref[$i]{$name} = $t; - $sectionref_title[$i]{$name} = $title; - $t = "<a name=\"$name\">$title</a>"; - $n = $i+1; - unless (s/\Q$tag/<h$n>$t<\/h$n>/i) { - die "line$line: fail to parse: $_\n"; - } - - if ($n <= $toc_section) { - if ($n > $depth) { - $toc = $toc . "<ul compact>\n" x ($n - $depth); - } elsif ($n < $depth) { - $toc = $toc . "</ul>\n" x ($depth - $n); - } - $toc = $toc . "<li><a href=\"#$name\">$title</a></li>\n"; - $depth = $n; - - } - - if ($n <= $table_section_num ) { $tablenum = 0; } - if ($n <= $figure_section_num) { $figurenum = 0; } - if ($n <= $list_section_num ) { $listnum = 0; } - - if (($prev_space[$i] != 0) && ($no_space == 0)) { - $prev = "<spacer type=vertical size=$prev_space[$i]>\n"; - } - if ($next_space[$i] != 0) { - $next = "<spacer type=vertical size=$next_space[$i]>\n"; - $no_space = 1; - } - } - } - } - - if ($sec_flag == 0) { - unless (/^\s*$/) { - $no_space = 0; - } - } - - while (($tag) = /(<tablereference[^>]*?>.*?<\/tablereference[^>]*?>)/i) { - ($title) = $tag =~ /<tablereference[^>]*?>(.*?)<\/tablereference[^>]*?>/i; - ($num) = $tag =~ /<tablereference[^>]*?number\s*=\s*([^\s>]*)[\s>]/i; - if ($num =~ /\".*\"/) { ($num) = $num =~ /\"(.*)\"/; } - $number_flag = 1; - if ($num =~ /^yes$/i) { $number_flag = 1; } - elsif ($num =~ /^on$/i ) { $number_flag = 1; } - elsif ($num =~ /^no$/i ) { $number_flag = 0; } - elsif ($num =~ /^off$/i) { $number_flag = 0; } - ($name) = $tag =~ /<tablereference[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($name =~ /\".*\"/) { ($name) = $name =~ /\"(.*)\"/; } - $name =~ s/\//\_/g; - if ($number_flag) { - $tablenum++; - $r = ""; - for ($i = 0; $i < $table_section_num; $i++) { - if ($section[$i] < 1) { last; } - $r = "$r$section[$i]."; - } - $r = "$r$tablenum"; - if ($name eq "") { $name = "$r"; } - } else { - $table_num++; - $r = ""; - if ($name eq "") { $name = "num$table_num"; } - } - $name = "tbl_$name"; - $r = "$table_string$r"; - $ref = "$r: $title"; - if ($tableref{$name} ne "") { - die "line$line: duplicate table name: $name\n"; - } - $tableref{$name} = $r; - $tableref_title{$name} = $ref; - $t = "<li><a href=\"#$name\">$ref</a>\n"; - push(@table_toc, $t); - unless (s/\Q$tag/<a name=\"$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } - - while (($tag) = /(<figurereference[^>]*?>.*?<\/figurereference[^>]*?>)/i) { - ($title) = $tag =~ /<figurereference[^>]*?>(.*?)<\/figurereference[^>]*?>/i; - ($num) = $tag =~ /<figurereference[^>]*?number\s*=\s*([^\s>]*)[\s>]/i; - if ($num =~ /\".*\"/) { ($num) = $num =~ /\"(.*)\"/; } - $number_flag = 1; - if ($num =~ /^yes$/i) { $number_flag = 1; } - elsif ($num =~ /^on$/i ) { $number_flag = 1; } - elsif ($num =~ /^no$/i ) { $number_flag = 0; } - elsif ($num =~ /^off$/i) { $number_flag = 0; } - ($name) = $tag =~ /<figurereference[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($name =~ /\".*\"/) { ($name) = $name =~ /\"(.*)\"/; } - $name =~ s/\//\_/g; - if ($number_flag) { - $figurenum++; - $r = ""; - for ($i = 0; $i < $figure_section_num; $i++) { - if ($section[$i] < 1) { last; } - $r = "$r$section[$i]."; - } - $r = "$r$figurenum"; - if ($name eq "") { $name = "$r"; } - } else { - $figure_num++; - $r = ""; - if ($name eq "") { $name = "num$figure_num"; } - } - $name = "fig_$name"; - $r = "$figure_string$r"; - $ref = "$r: $title"; - if ($figureref{$name} ne "") { - die "line$line: duplicate figure name: $name\n"; - } - $figureref{$name} = $r; - $figureref_title{$name} = $ref; - $t = "<li><a href=\"#$name\">$ref</a>\n"; - push(@figure_toc, $t); - unless (s/\Q$tag/<a name=\"$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } - - while (($tag) = /(<listreference[^>]*?>.*?<\/listreference[^>]*?>)/i) { - ($title) = $tag =~ /<listreference[^>]*?>(.*?)<\/listreference[^>]*?>/i; - ($num) = $tag =~ /<listreference[^>]*?number\s*=\s*([^\s>]*)[\s>]/i; - if ($num =~ /\".*\"/) { ($num) = $num =~ /\"(.*)\"/; } - $number_flag = 1; - if ($num =~ /^yes$/i) { $number_flag = 1; } - elsif ($num =~ /^on$/i ) { $number_flag = 1; } - elsif ($num =~ /^no$/i ) { $number_flag = 0; } - elsif ($num =~ /^off$/i) { $number_flag = 0; } - ($name) = $tag =~ /<listreference[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($name =~ /\".*\"/) { ($name) = $name =~ /\"(.*)\"/; } - $name =~ s/\//\_/g; - if ($number_flag) { - $listnum++; - $r = ""; - for ($i = 0; $i < $list_section_num; $i++) { - if ($section[$i] < 1) { last; } - $r = "$r$section[$i]."; - } - $r = "$r$listnum"; - if ($name eq "") { $name = "$r"; } - } else { - $list_num++; - $r = ""; - if ($name eq "") { $name = "num$list_num"; } - } - $name = "lst_$name"; - $r = "$list_string$r"; - $ref = "$r: $title"; - if ($listref{$name} ne "") { - die "line$line: duplicate list name: $name\n"; - } - $listref{$name} = $r; - $listref_title{$name} = $ref; - $t = "<li><a href=\"#$name\">$ref</a>\n"; - push(@list_toc, $t); - unless (s/\Q$tag/<a name=\"$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } - - if (($spacer) && ($prev ne "")) { -# This is for temporary files. But, temporary files are not used. -# print WFILE $prev; - push(@lines, $prev); - } -# This is for temporary files. But, temporary files are not used. -# print WFILE $_; - push(@lines, $_); - if (($spacer) && ($next ne "")) { -# This is for temporary files. But, temporary files are not used. -# print WFILE $next; - push(@lines, $next); - } -} - -$toc = $toc . "</ul>\n" x ($depth); - -# This is for temporary files. But, temporary files are not used. -#close (WFILE); -#open (RFILE, "< $filename.$filename_num"); -#$filename_num++; -#open (WFILE, "> $filename.$filename_num"); - -$line = 0; -@lines2 = (); - -# This is for temporary files. But, temporary files are not used. -#while (<RFILE>) -while ($_ = shift(@lines)) -{ - $line++; - - if (/sectionref/i) { - for ($i = 0; $i < $max_depth; $i++) { - $sub = "sub" x $i; - $sec = $sub . "sectionref"; - - while (($tag) = /(<$sec[^>]*?>)/i) { - ($t) = $tag =~ /<$sec[^>]*?title\s*=\s*([^\s>]*)[\s>]/i; - if ($t =~ /\".*\"/) { ($t) = $t =~ /\"(.*)\"/; } - ($n) = $tag =~ /<$sec[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($n =~ /\".*\"/) { ($n) = $n =~ /\"(.*)\"/; } - $title_flag = 1; - if ($t =~ /^yes$/i) { $title_flag = 1; } - elsif ($t =~ /^on$/i ) { $title_flag = 1; } - elsif ($t =~ /^no$/i ) { $title_flag = 0; } - elsif ($t =~ /^off$/i) { $title_flag = 0; } - $n =~ s/\//\_/g; - if ($n eq "") { die "line$line: $_:no name.\n"; } - $name = "$sub" . "section\_$n"; - if ($title_flag) { $ref = $sectionref_title[$i]{$name}; } - else { $ref = $sectionref[$i]{$name}; } - if ($ref eq "") { die "line$line: $_$n: not found.\n"; } - unless (s/\Q$tag/<a href=\"\#$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } - } - } - - while (($tag) = /(<tableref[^>]*?>)/i) { - ($t) = $tag =~ /<tableref[^>]*?title\s*=\s*([^\s>]*)[\s>]/i; - if ($t =~ /\".*\"/) { ($t) = $t =~ /\"(.*)\"/; } - ($n) = $tag =~ /<tableref[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($n =~ /\".*\"/) { ($n) = $n =~ /\"(.*)\"/; } - $title_flag = 0; - if ($t =~ /^yes$/i) { $title_flag = 1; } - elsif ($t =~ /^on$/i ) { $title_flag = 1; } - elsif ($t =~ /^no$/i ) { $title_flag = 0; } - elsif ($t =~ /^off$/i) { $title_flag = 0; } - $n =~ s/\//\_/g; - if ($n eq "") { die "line$line: $_:no name.\n"; } - $name = "tbl_$n"; - if ($title_flag) { $ref = $tableref_title{$name}; } - else { $ref = $tableref{$name}; } - if ($ref eq "") { die "line$line: $_$n: not found.\n"; } - unless (s/\Q$tag/<a href=\"\#$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } - while (($tag) = /(<figureref[^>]*?>)/i) { - ($t) = $tag =~ /<figureref[^>]*?title\s*=\s*([^\s>]*)[\s>]/i; - if ($t =~ /\".*\"/) { ($t) = $t =~ /\"(.*)\"/; } - ($n) = $tag =~ /<figureref[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($n =~ /\".*\"/) { ($n) = $n =~ /\"(.*)\"/; } - $title_flag = 0; - if ($t =~ /^yes$/i) { $title_flag = 1; } - elsif ($t =~ /^on$/i ) { $title_flag = 1; } - elsif ($t =~ /^no$/i ) { $title_flag = 0; } - elsif ($t =~ /^off$/i) { $title_flag = 0; } - $n =~ s/\//\_/g; - if ($n eq "") { die "line$line: $_:no name.\n"; } - $name = "fig_$n"; - if ($title_flag) { $ref = $figureref_title{$name}; } - else { $ref = $figureref{$name}; } - if ($ref eq "") { die "line$line: $_$n: not found.\n"; } - unless (s/\Q$tag/<a href=\"\#$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } - while (($tag) = /(<listref[^>]*?>)/i) { - ($t) = $tag =~ /<listref[^>]*?title\s*=\s*([^\s>]*)[\s>]/i; - if ($t =~ /\".*\"/) { ($t) = $t =~ /\"(.*)\"/; } - ($n) = $tag =~ /<listref[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($n =~ /\".*\"/) { ($n) = $n =~ /\"(.*)\"/; } - $title_flag = 0; - if ($t =~ /^yes$/i) { $title_flag = 1; } - elsif ($t =~ /^on$/i ) { $title_flag = 1; } - elsif ($t =~ /^no$/i ) { $title_flag = 0; } - elsif ($t =~ /^off$/i) { $title_flag = 0; } - $n =~ s/\//\_/g; - if ($n eq "") { die "line$line: $_:no name.\n"; } - $name = "lst_$n"; - if ($title_flag) { $ref = $listref_title{$name}; } - else { $ref = $listref{$name}; } - if ($ref eq "") { die "line$line: $_$n: not found.\n"; } - unless (s/\Q$tag/<a href=\"\#$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } -# This is for temporary files. But, temporary files are not used. -# print WFILE $_; - push(@lines2, $_); -} - -# This is for temporary files. But, temporary files are not used. -#close (RFILE); -#close (WFILE); -#open (RFILE, "< $filename.$filename_num"); -#$filename_num++; -#open (WFILE, "> $filename.$filename_num"); - -@lines = (); - -# This is for temporary files. But, temporary files are not used. -#while (<RFILE>) -while ($_ = shift(@lines2)) -{ - if (/<references>/i) { - s/<references>/<h1>$references_string<\/h1>\n\n<ul>/i; - while (!(/<\/references>/i)) { - if (($tag) = /(<reference[^>]*?>)/i) { - $refnum++; - ($name) = $tag =~ /<reference[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($name =~ /\".*\"/) { ($name) = $name =~ /\"(.*)\"/; } - $name =~ s/\//\_/g; - if ($name eq "") { $name = "$refnum"; } - $name = "ref_$name"; - if ($reference{$name} ne "") { - die "line$line: duplicate reference name: $name\n"; - } - $reference{$name} = $refnum; - unless (s/\Q$tag/<li><a name=\"$name\">\[$refnum\]<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } -# This is for temporary files. But, temporary files are not used. -# print WFILE $_; -# unless ($_ = <RFILE>) { last; } - push(@lines, $_); - unless ($_ = shift(@lines2)) { last; } - } - s/<\/references>/<\/ul>/i; - } -# This is for temporary files. But, temporary files are not used. -# print WFILE $_; - push(@lines, $_); -} - -# This is for temporary files. But, temporary files are not used. -#close (RFILE); -#close (WFILE); -#open (RFILE, "< $filename.$filename_num"); -#$filename_num++; -#open (WFILE, "> $filename.$filename_num"); - -$line = 0; -@lines2 = (); - -# This is for temporary files. But, temporary files are not used. -#while (<RFILE>) -while ($_ = shift(@lines)) -{ - $line++; - while (($tag) = /(<ref[^>]*?>)/i) { - ($t) = $tag =~ /<ref[^>]*?title\s*=\s*([^\s>]*)[\s>]/i; - if ($t =~ /\".*\"/) { ($t) = $t =~ /\"(.*)\"/; } - ($n) = $tag =~ /<ref[^>]*?name\s*=\s*([^\s>]*)[\s>]/i; - if ($n =~ /\".*\"/) { ($n) = $n =~ /\"(.*)\"/; } - $title_flag = 0; - if ($t =~ /^yes$/i) { $title_flag = 1; } - elsif ($t =~ /^on$/i ) { $title_flag = 1; } - elsif ($t =~ /^no$/i ) { $title_flag = 0; } - elsif ($t =~ /^off$/i) { $title_flag = 0; } - $n =~ s/\//\_/g; - if ($n eq "") { die "line$line: $_:no name.\n"; } - $name = "ref_$n"; - $ref = $reference{$name}; - if ($ref eq "") { die "line$line: $_$n: not found.\n"; } - if ($title_flag) { $ref = "$reference_string\[$ref\]"; } - else { $ref = "\[$ref\]"; } - unless (s/\Q$tag/<a href=\"\#$name\">$ref<\/a>/i) { - die "line$line: fail to parse: $_\n"; - } - } -# This is for temporary files. But, temporary files are not used. -# print WFILE $_; - push(@lines2, $_); -} - -# This is for temporary files. But, temporary files are not used. -#close (RFILE); -#close (WFILE); -#open (RFILE, "< $filename.$filename_num"); - -if ($output_filename ne "") { - open (WFILE, "> $output_filename") || die "cannot open: $output_filename\n"; -} - -$toc_string = "\n\n$toc"; -#AC $toc_string = "<h1>$toc_string<\/h1>\n\n$toc"; -$table_index_string = "<h1>$table_index_string<\/h1>\n\n<ul>\n@table_toc<\/ul>"; -$figure_index_string = "<h1>$figure_index_string<\/h1>\n\n<ul>\n@figure_toc<\/ul>"; -$list_index_string = "<h1>$list_index_string<\/h1>\n\n<ul>\n@list_toc<\/ul>"; - -# This is for temporary files. But, temporary files are not used. -#while (<RFILE>) -while ($_ = shift(@lines2)) -{ - if (/<tableofcontents>.*<\/tableofcontents>/i) { - s/<tableofcontents>.*?<\/tableofcontents>/$toc_string/i; - } - if (/<tableindex>.*<\/tableindex>/i) { - s/<tableindex>.*?<\/tableindex>/$table_index_string/i; - } - if (/<figureindex>.*<\/figureindex>/i) { - s/<figureindex>.*?<\/figureindex>/$figure_index_string/i; - } - if (/<listindex>.*<\/listindex>/i) { - s/<listindex>.*?<\/listindex>/$list_index_string/i; - } - if ($output_filename ne "") { - print WFILE $_; - } else { - print $_; - } -} - -# This is for temporary files. But, temporary files are not used. -#close (RFILE); - -if ($output_filename ne "") { - close (WFILE); -} - -if ($toc_filename ne "") { - open (WFILE, "> $toc_filename"); - print WFILE "$toc_string"; - close (WFILE); -} -if ($table_filename ne "") { - open (WFILE, "> $table_filename"); - print WFILE "$table_index_string"; - close (WFILE); -} -if ($figure_filename ne "") { - open (WFILE, "> $figure_filename"); - print WFILE "$figure_index_string"; - close (WFILE); -} -if ($list_filename ne "") { - open (WFILE, "> $list_filename"); - print WFILE "$list_index_string"; - close (WFILE); -} - -# This is for temporary files. But, temporary files are not used. -#system ("rm -f $filename.*"); - -exit (0); - -############################################################################### -# htmlsection-1.0 diff --git a/sm/lib/egsl/docs/htmlsection.txt b/sm/lib/egsl/docs/htmlsection.txt deleted file mode 100755 index 0435e84..0000000 --- a/sm/lib/egsl/docs/htmlsection.txt +++ /dev/null @@ -1,358 +0,0 @@ - -htmlsection - insert section number in HTML and make the table of contents. - -* Insert section number in HTML and make links to the section. -* Make the table of contents. -* Insert table, figure, and program-list number and make links. -* Make the index of tables, figures, and program-lists. -* Insert reference number and make links. - -htmlsection Copyright (C) 2001 SAKAI Hiroaki. -All Rights Reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -SYNOPSIS - - htmlsection [-options] [files ...] - -DESCRIPTION - -htmlsection is a perl script to insert section number in HTML. When you use -htmlsection, you don't have to manage section, table, figure, program-list, -and reference numbers and you don't have to make the table of contents, -table index, figure index, and program-list index. - -If files are specified, htmlsection reads HTML from these files. But, if -files are not specified, htmlsection reads HTML from standard input. - -EXAMPLES - -* Insert section number in HTML and make links to the section. - -htmlsection changes <section></section> tag to <h1></h1> tag and section -number. You can use tag <section>, <subsection>, ..., and -<subsubsubsubsubsection>. -If name option is specified, htmlsection changes <sectionref> tag to the -number and title of the section and make link to the section. -If you want not to use number, use number option as <section number=no>. - -Example: - -For example, make the file example.html as below, --------- begin of example -------- -<section name="intro" number=no>Introduction</section> - - This is introduction. - -<section name="howto">How to use htmlsection</section> - -<subsection name="howtouse">Let's use htmlsection!</subsection> - - If you want to know about htmlsection, see -<sectionref name="howto">, and -<subsectionref name="howtouse" title=no>. - -<section number=no>Ending</section> --------- end of example -------- - -And execute, -> cat example.html | htmlsection -htmlsection will output as, --------- begin of example -------- -<spacer type=vertical size=70> -<h1><a name="section_intro">Introduction</a></h1> -<spacer type=vertical size=30> - - This is introduction. - -<spacer type=vertical size=70> -<h1><a name="section_howto">1 How to use htmlsection</a></h1> -<spacer type=vertical size=30> - -<spacer type=vertical size=50> -<h2><a name="subsection_howtouse">1.1 Let's use htmlsection!</a></h2> -<spacer type=vertical size=25> - - If you want to know about htmlsection, see -<a href="#section_howto">1 How to use htmlsection</a>, and -<a href="#subsection_howtouse">1.1</a>. - -<spacer type=vertical size=70> -<h1><a name="section_toc2">Ending</a></h1> -<spacer type=vertical size=30> --------- end of example -------- - -* Make the table of contents. - -htmlsection inserts the table of contents at -<tableofcontents></tableofcontents> tag. - -* Insert table, figure, and program-list number and make links. - -htmlsection inserts the number at <tablereference> tag. - -Example: - -Before convertion --------- begin of example -------- -<center> -<tablereference name="sample_table">Sample Table</tablereference> -<table border=1> -<tr><td align=center>name</td><td align=center>function</td></tr> -<tr><td>printf</td><td>print strings by a format.</td></tr> -</table> -</center> - -<p> -<center> -<img src="picture/sample.jpg"> -<br> -<figurereference name="sample_figure">Sample Figure</figurereference> -</center> - -<p> -<pre> -<listreference name="sample_list">Sample List</listreference> - -int main() -{ - int i; - for (i = 0; i < 10; i++) - printf("%d\n", i); - exit (0); -} -</pre> - -<p> -See <tableref name="sample_table">. -See <figureref name="sample_figure">. -See <listref name="sample_list">. --------- end of example -------- - -After convertion by htmlsection --------- begin of example -------- -<center> -<a name="tbl_sample_table">table1: Sample Table</a> -<table border=1> -<tr><td align=center>name</td><td align=center>function</td></tr> -<tr><td>printf</td><td>print strings by a format.</td></tr> -</table> -</center> - -<p> -<center> -<img src="picture/sample.jpg"> -<br> -<a name="fig_sample_figure">figure1: Sample Figure</a> -</center> - -<p> -<pre> -<a name="lst_sample_list">list1: Sample List</a> - -int main() -{ - int i; - for (i = 0; i < 10; i++) - printf("%d\n", i); - exit (0); -} -</pre> - -<p> -See <a href="#tbl_sample_table">table1</a>. -See <a href="#fig_sample_figure">figure1</a>. -See <a href="#lst_sample_list">list1</a>. --------- end of example -------- - -* Make the index of tables, figures, and program-lists. - -htmlsection inserts the index of table, figure, and list at -<tableindex></tableindex>, <figureindex></figureindex>, and -<listindex></listindex> tag. - -* Insert reference number and make links. - -htmlsention makes reference table. - -Example: - -Before convertion --------- begin of example -------- -See <ref name="KandR2">. - -<references> -<reference name="KandR">Brian W. Kernighan and Dennis M. Ritchie, -"The C Programming Language", Prentice-Hall, 1978. -<reference name="KandR2">Brian W. Kernighan and Dennis M. Ritchie, -"The C Programming Language", Second Edition, Prentice Hall, 1988. -<reference name="NumericalRecipe">William H. Press, Saul A. Teukolsky, -William T. Vetterling, and Brian P.Flannery, -"Numerical Recipes in C", Second Edition, Cambridge University Press, 1992. -</references> --------- end of example -------- - -After convertion by htmlsection --------- begin of example -------- -See <a href="#ref_KandR2">[2]</a>. - -<ul> -<li><a name="ref_KandR">[1]</a>Brian W. Kernighan and Dennis M. Ritchie, -"The C Programming Language", Prentice-Hall, 1978. -<li><a name="ref_KandR2">[2]</a>Brian W. Kernighan and Dennis M. Ritchie, -"The C Programming Language", Second Edition, Prentice Hall, 1988. -<li><a name="ref_NumericalRecipe">[3]</a>William H. Press, Saul A. Teukolsky, -William T. Vetterling, and Brian P.Flannery, -"Numerical Recipes in C", Second Edition, Cambridge University Press, 1992. -</ul> --------- end of example -------- - -OPTIONS - -The following options are available: - --h, -help - Output help messages. - --max-depth [depth] - Specify the max depth of subsection of section tag. If you specify - -max-depth 10, you can use <subsubsubsubsubsubsubsubsubsection> tag. - --spacer - Spacing <section>, <subsection> and <subsubsection> tag. - --no-spacer - No spacing. - --english, -japanese - Specify the language. If you don't specify these options, htmlsection - sees environment variable LANG. - --start-section [section] - Specify the section number at start. For example, if you specify - -start-section 3.5.6, htmlsection sets the section number to it at start. - --toc-section [section] - Specify the section depth to make the table of contents. If you - specify -toc-section 2, htmlsection makes the table of contents - by section and subsection only. - --table-section [section] - Specify the section number at beginning of table number. - If you specify -table-section 2, format of table number is - [section_number].[subsection_number].[table_number]. - If you specify -table-section 0, format of table number is - [table_number] only. - --figure-section [section], -list-section [section] - Same as -table-section option. - --start-table [number] - Specify the table number at start. - --start-figure [number], -start-list [number], -start-ref [number] - Same as -start-table option. - --toc-file [filename] - If you specify -toc-file, output the table of contents to the file. - --table-file [filename] - If you specify -table-file, output the table index to the file. - --figure-file [filename], -list-file [filename] - Same as -table-file option. - --o [filename] - Specify the output file. If you don't specify the filename, htmlsection - outputs HTML to the standard output. - -ENVIRONMENT VARIABLES - - LANG - Specify the language. - -TAGS - - <section>Title</section>, <subsection>Title</subsection>, ... - options: - name="section_name" - number=yes or no - - <sectionref>, <subsectionref>, ... - options: - name="section_name" - title=yes or no - - <tablereference>Title</tablereference> - options: - name="table_name" - number=yes or no - - <figurereference>Title</figurereference> - options: - name="figure_name" - number=yes or no - - <listreference>Title</listreference> - options: - name="list_name" - number=yes or no - - <tableref>Title</tableref> - options: - name="table_name" - title=yes or no - - <figureref>Title</figureref> - options: - name="figure_name" - title=yes or no - - <listref>Title</listref> - options: - name="list_name" - title=yes or no - - <references></references> - - <reference> - options: - name="reference_name" - - <ref> - options: - name="reference_name" - title=yes or no - - <tableofcontents></tableofcontents> - <tableindex></tableindex> - <figureindex></figureindex> - <listindex></listindex> - -SEE ALSO - - perl(1) - - If you want to see more detail information, See, - Comments at the head of htmlsection script. - HTMLSECTION_PREFIX/share/doc/htmlsection - Documents. - HTMLSECTION_PREFIX/share/doc/htmlsection/README - Readme file. - HTMLSECTION_PREFIX/share/doc/htmlsection/htmlsection.html - - Sample HTML file and description about htmlsection. - http://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/htmlsection.html - -AUTHOR - - Programmed by SAKAI Hiroaki. - E-Mail: sakai@seki.ee.kagu.sut.ac.jp, hsakai@m8.people.or.jp, - hsakai@pfu.fujitsu.com - Web site: - http://www.seki.ee.kagu.sut.ac.jp/~sakai/myfreesoft/index.html - Mirror site: - http://hp.vector.co.jp/authors/VA014157/myfreesoft/index.html - http://www.people.or.jp/~hsakai/myfreesoft/index.html - diff --git a/sm/lib/egsl/egsl_conversions.c b/sm/lib/egsl/egsl_conversions.c deleted file mode 100644 index 2d81c09..0000000 --- a/sm/lib/egsl/egsl_conversions.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "egsl.h" - -val egsl_vFda(size_t rows, size_t cols, const double *a) { - val v = egsl_alloc(rows, cols); - - size_t i; size_t j; - for(i=0;i<rows;i++) - for(j=0;j<cols;j++) { - *egsl_atmp(v,i,j) = a[j+i*cols]; - } - return v; -} - -val egsl_vFa(size_t rows, const double*a) { - val v = egsl_alloc(rows,1); - size_t i; - for(i=0;i<rows;i++) - *egsl_atmp(v,i,0) = a[i]; - return v; -} - -void egsl_v2a(val v, double*vec) { - gsl_matrix *m = egsl_gslm(v); - size_t i; - for(i=0; i < m->size1; i++) - vec[i] = gsl_matrix_get(m,i,0); -} - -void egsl_v2da(val v, double*a){ - gsl_matrix *m = egsl_gslm(v); - size_t i,j; - for(i=0;i<m->size1;i++) - for(j=0;j<m->size2;j++) - a[j*m->size1 +i] = gsl_matrix_get(m,i,j); -} - -void egsl_v2vec(val v, gsl_vector*vec) { - size_t i; - for(i=0;i<vec->size;i++) - gsl_vector_set(vec,i, *egsl_atmp(v,i,0)); -} - - -val egsl_vFgslv(const gsl_vector*vec){ - val v = egsl_alloc(vec->size,1); - size_t i; - for(i=0;i<vec->size;i++) - *egsl_atmp(v,i,0) = gsl_vector_get(vec,i); - return v; -} - -val egsl_vFgslm(const gsl_matrix*m){ - val v = egsl_alloc(m->size1,m->size2); - gsl_matrix * m2 = egsl_gslm(v); - gsl_matrix_memcpy(m2,m); - return v; -} - -gsl_matrix* egsl_v2gslm(val v){ - gsl_matrix * m = egsl_gslm(v); - gsl_matrix * m2 = gsl_matrix_alloc(m->size1,m->size2); - gsl_matrix_memcpy(m2,m); - return m2; -} diff --git a/sm/lib/egsl/egsl_ops.c b/sm/lib/egsl/egsl_ops.c deleted file mode 100644 index aeceb54..0000000 --- a/sm/lib/egsl/egsl_ops.c +++ /dev/null @@ -1,172 +0,0 @@ -#include <gsl/gsl_matrix.h> -#include <gsl/gsl_blas.h> -#include <gsl/gsl_linalg.h> -#include <gsl/gsl_eigen.h> - -#include "egsl.h" - - - -val egsl_sub(val v1,val v2){ - return egsl_sum(v1, egsl_scale(-1.0,v2)); -} - -val egsl_compose_col(val v1, val v2){ - gsl_matrix *m1 = egsl_gslm(v1); - gsl_matrix *m2 = egsl_gslm(v2); - egsl_expect_size(v2, 0, m1->size2); - val v3 = egsl_alloc(m1->size1+m2->size1,m1->size2); - gsl_matrix *m3 = egsl_gslm(v3); - size_t i,j; - for(j=0;j<m1->size2;j++) { - for(i=0;i<m1->size1;i++) - gsl_matrix_set(m3, i, j, gsl_matrix_get(m1,i,j)); - - for(i=0;i<m2->size1;i++) - gsl_matrix_set(m3, m1->size1+i, j, gsl_matrix_get(m2,i,j)); - } - return v3; -} - -val egsl_compose_row(val v1, val v2){ - gsl_matrix *m1 = egsl_gslm(v1); - gsl_matrix *m2 = egsl_gslm(v2); - egsl_expect_size(v2, m1->size1, 0); - val v3 = egsl_alloc(m1->size1, m1->size2 + m2->size2); - gsl_matrix *m3 = egsl_gslm(v3); - size_t i,j; - for(i=0;i<m1->size1;i++) { - for(j=0;j<m1->size2;j++) - gsl_matrix_set(m3, i, j, gsl_matrix_get(m1,i,j)); - - for(j=0;j<m2->size2;j++) - gsl_matrix_set(m3, i, m1->size2+j, gsl_matrix_get(m2,i,j)); - } - return v3; -} - -void egsl_add_to(val v1, val v2) { - gsl_matrix * m1 = egsl_gslm(v1); - gsl_matrix * m2 = egsl_gslm(v2); - gsl_matrix_add(m1,m2); -} - -void egsl_add_to_col(val v1, size_t j, val v2) { -/* egsl_print("m1",v1); - egsl_print("m2",v2); */ - gsl_matrix * m1 = egsl_gslm(v1); - gsl_matrix * m2 = egsl_gslm(v2); - -/* printf("m1 size = %d,%d j = %d\n",m1->size1,m1->size2,j); */ - egsl_expect_size(v2, m1->size1, 1); - size_t i; - for(i=0;i<m1->size1;i++) { - *gsl_matrix_ptr(m1, i, j) += gsl_matrix_get(m2,i,0); - } -} - - -val egsl_copy_val(val v1) { - gsl_matrix * m1 = egsl_gslm(v1); - val v2 = egsl_alloc(m1->size1,m1->size2); - gsl_matrix * m2 = egsl_gslm(v2); - gsl_matrix_memcpy(m2,m1); - return v2; -} - -val egsl_scale(double s, val v1){ - val v2 = egsl_copy_val(v1); - gsl_matrix * m2 = egsl_gslm(v2); - gsl_matrix_scale(m2, s); - return v2; -} - -val egsl_sum(val v1, val v2){ - gsl_matrix * m1 = egsl_gslm(v1); - gsl_matrix * m2 = egsl_gslm(v2); - val v3 = egsl_alloc(m1->size1,m1->size2); - gsl_matrix * m3 = egsl_gslm(v3); - gsl_matrix_memcpy(m3,m1); - gsl_matrix_add(m3,m2); - return v3; -} - -val egsl_sum3(val v1, val v2, val v3){ - return egsl_sum(v1, egsl_sum(v2,v3)); -} - -val egsl_mult(val v1, val v2){ - gsl_matrix * a = egsl_gslm(v1); - gsl_matrix * b = egsl_gslm(v2); - val v = egsl_alloc(a->size1,b->size2); - gsl_matrix * ab = egsl_gslm(v); - gsl_blas_dgemm(CblasNoTrans,CblasNoTrans,1.0,a,b,0.0,ab); - return v; -} - -val egsl_transpose(val v1){ - gsl_matrix * m1 = egsl_gslm(v1); - val v2 = egsl_alloc(m1->size2,m1->size1); - gsl_matrix * m2 = egsl_gslm(v2); - gsl_matrix_transpose_memcpy(m2,m1); - return v2; -} - -val egsl_inverse(val v1){ - gsl_matrix*A = egsl_gslm(v1); - val v2 = egsl_alloc(A->size1,A->size1); - gsl_matrix*invA = egsl_gslm(v2); - size_t n = A->size1; - gsl_matrix * m = gsl_matrix_alloc(n,n); - gsl_matrix_memcpy(m,A); - gsl_permutation * perm = gsl_permutation_alloc (n); - /* Make LU decomposition of matrix m */ - int s; - gsl_linalg_LU_decomp (m, perm, &s); - /* Invert the matrix m */ - gsl_linalg_LU_invert (m, perm, invA); - gsl_permutation_free(perm); - gsl_matrix_free(m); - return v2; -} - -void egsl_symm_eig(val v, double* eigenvalues, val* eigenvectors) { - gsl_matrix *m = egsl_gslm(v); - size_t N = m->size1; - /* Check for v to be square */ - - gsl_matrix *A = gsl_matrix_alloc(N,N); - gsl_matrix_memcpy(A, m); - - gsl_vector *eval = gsl_vector_alloc(N); - gsl_matrix *evec = gsl_matrix_alloc(N,N); - - gsl_eigen_symmv_workspace * ws = gsl_eigen_symmv_alloc(N); - gsl_eigen_symmv(A, eval, evec, ws); - gsl_eigen_symmv_free(ws); - - - gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_DESC); - - size_t j; - for(j=0;j<N;j++) { - eigenvalues[j] = gsl_vector_get(eval, j); - eigenvectors[j] = egsl_alloc(N,1); - size_t i; - for(i=0;i<N;i++) - *egsl_atmp(eigenvectors[j],i,0) = gsl_matrix_get(evec,i,j); - } - - - gsl_vector_free(eval); - gsl_matrix_free(evec); - gsl_matrix_free(A); -} - - - - - - - - diff --git a/sm/lib/egsl/egsl_test.c b/sm/lib/egsl/egsl_test.c deleted file mode 100644 index 8439a5d..0000000 --- a/sm/lib/egsl/egsl_test.c +++ /dev/null @@ -1,41 +0,0 @@ -#include <math.h> -#include <gsl/gsl_math.h> -#include "egsl_macros.h" - -int main() { - egsl_push(); - - /* Creates a vector from a double array */ - double p[2] = {1,2}; - val vp = egsl_vFa(2,p); - - /* Creates a matrix from a double array */ - double md[4] = { - 1, 2, - 0, -1 - }; - val m = egsl_vFda(2,2,md); - - /* Creates a rotation matrix */ - val R = rot(M_PI/2); - - /* Multiplies the three together */ - val vrot = m3(R, m, vp); - - /* Displays the results */ - egsl_print("R", R); - egsl_print("vp", vp); - egsl_print("vrot", vrot); - - /* Create a semidifinite matrix (symmetric part of R) */ - val A = sc(0.5, sum(m, tr(m)) ); - - /* Displays spectrum */ - egsl_print("A",A); - egsl_print_spectrum("A",A); - - egsl_pop(); - - return 0; -} - diff --git a/sm/lib/egsl/egsl_test_allocation.c b/sm/lib/egsl/egsl_test_allocation.c deleted file mode 100644 index 201bbe3..0000000 --- a/sm/lib/egsl/egsl_test_allocation.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "egsl.h" -#include "egsl_macros.h" - -int main() { - egsl_push(); - - val v1 = zeros(10,10); - - int i; - for(i=0;i<1000000;i++) { - egsl_push(); - val v2 = zeros(10,10); - - add_to(v1, v2); - - egsl_pop(); - } - - egsl_pop(); - egsl_print_stats(); - - return 0; -} diff --git a/sm/lib/gpc/CMakeLists.txt b/sm/lib/gpc/CMakeLists.txt deleted file mode 100644 index 782609a..0000000 --- a/sm/lib/gpc/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ - -SET(gpc_sources - gpc.c - gpc_utils.c -) - -ADD_LIBRARY(gpc STATIC ${gpc_sources}) diff --git a/sm/lib/gpc/gpc_test.c b/sm/lib/gpc/gpc_test.c deleted file mode 100644 index ed76ec4..0000000 --- a/sm/lib/gpc/gpc_test.c +++ /dev/null @@ -1,52 +0,0 @@ -// GPC: A library for the solution of General Point Correspondence problems. -// Copyright (C) 2006 Andrea Censi (andrea at censi dot org) - -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -#include <stdio.h> -#include <math.h> -#include "gpc.h" - -#define deg2rad(x) (x*M_PI/180) - -int main() { - // This is the true roto-translation - double theta = deg2rad(4); - double t[2] = {0.3,-0.2}; - printf("x_true = %f %f %f deg\n", t[0], t[1], theta*180/M_PI); - - double p[5][2] = {{1,0},{0,1},{-1,0},{2,1},{4,2}}; - double alpha[5] = {deg2rad(0), - deg2rad(10), deg2rad(20), deg2rad(50),deg2rad(-20)}; - - struct gpc_corr c[5]; - int k; - for(k=0;k<5;k++) { - c[k].p[0] = p[k][0]; - c[k].p[1] = p[k][1]; - c[k].q[0] = t[0] + p[k][0]*cos(theta) - p[k][1]*sin(theta); - c[k].q[1] = t[1] + p[k][0]*sin(theta) + p[k][1]*cos(theta); - c[k].C[0][0] = cos(alpha[k])*cos(alpha[k]); - c[k].C[0][1] = c[k].C[1][0] = cos(alpha[k])*sin(alpha[k]); - c[k].C[1][1] = sin(alpha[k])*sin(alpha[k]); - } - - double x[3]; - gpc_solve(5,c,x); - - printf("estimated x = %f %f %f deg\n", x[0], x[1],x[2]*180/M_PI); - return 0; -} - diff --git a/sm/lib/gpc/gpc_utils.c b/sm/lib/gpc/gpc_utils.c deleted file mode 100644 index b743f4c..0000000 --- a/sm/lib/gpc/gpc_utils.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "gpc.h" -#include "gpc_utils.h" - -void m_trans(const gsl_matrix*A, gsl_matrix*A_t){ - gsl_matrix_transpose_memcpy(A_t,A); -} - -void m_mult(const gsl_matrix*A, const gsl_matrix*B, gsl_matrix*AB){ - gsl_blas_dgemm(CblasNoTrans,CblasNoTrans,1.0,A,B,0.0,AB); -} - -void m_add_to(const gsl_matrix*A, gsl_matrix*B){ - gsl_matrix_add(B, A); -} - -void m_scale(double m, gsl_matrix*A){ - gsl_matrix_scale(A,m); -} - -void m_add (const gsl_matrix*A, const gsl_matrix*B, gsl_matrix*ApB){ - gsl_matrix_memcpy(ApB,A); - gsl_matrix_add(ApB,B); -} - -void m_inv(const gsl_matrix*A, gsl_matrix*invA) { - unsigned int n = A->size1; - gsl_matrix * m = gsl_matrix_alloc(n,n); - gsl_matrix_memcpy(m,A); - gsl_permutation * perm = gsl_permutation_alloc (n); - /* Make LU decomposition of matrix m */ - int s; - gsl_linalg_LU_decomp (m, perm, &s); - /* Invert the matrix m */ - gsl_linalg_LU_invert (m, perm, invA); - gsl_permutation_free(perm); - gsl_matrix_free(m); -} - -double m_det(const gsl_matrix*A) { - unsigned int n = A->size1; - gsl_matrix * m = gsl_matrix_alloc(n,n); - gsl_matrix_memcpy(m,A); - gsl_permutation * perm = gsl_permutation_alloc (n); - int sign; - gsl_linalg_LU_decomp (m, perm, &sign); - double det = gsl_linalg_LU_det(m, sign); - - gsl_permutation_free(perm); - gsl_matrix_free(m); - return det; -} - -double m_dot(const gsl_matrix*A,const gsl_matrix*B) { - double sum = 0; - unsigned int j; - for(j=0;j<A->size2;j++) - sum += gmg(A,0,j)*gmg(B,j,0); - return sum; -} - -int poly_real_roots(unsigned int n, const double*a, double *roots) { - double z[(n-1)*2]; - gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc(n); - if(GSL_SUCCESS != gsl_poly_complex_solve (a, n, w, z)) { - return 0; - } - gsl_poly_complex_workspace_free (w); - - unsigned int i=0; - for(i=0;i<n-1;i++) { - roots[i] = z[2*i]; - } - return 1; -} - - -int poly_greatest_real_root(unsigned int n, const double*a, double *root) { - double z[(n-1)*2]; - gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc(n); - if(GSL_SUCCESS != gsl_poly_complex_solve (a, n, w, z)) { - return 0; - } - gsl_poly_complex_workspace_free (w); - if(TRACE_ALGO) { - printf("Solving the equation\n a = ["); - for(unsigned int i=0;i<n;i++) { - printf("%lf ", a[i]); - } - printf("]\n"); - } - - unsigned int i; - double lambda = 0; int assigned = 0; - for (i = 0; i < n-1; i++) { - if(TRACE_ALGO) { - fprintf (stderr, "root z%d = %+.18f + %+.18f i \n", i, z[2*i], z[2*i+1]); - } -/* XXX ==0 is bad */ - if( z[2*i+1]==0 ) /* real root */ - if(!assigned || (z[2*i]>lambda)) { - assigned = 1; - lambda = z[2*i]; - } - } - if(TRACE_ALGO) - fprintf (stderr, "lambda = %+.18f \n", lambda); - if(!assigned) { - fprintf(stderr, "poly_greatest_real_root: Could not find real root for polynomial.\n"); - fprintf(stderr, "polynomial coefficients : "); - for (i = 0; i < n; i++) - fprintf(stderr, " %lf ", a[i]); - fprintf(stderr, "\nRoots:\n"); - - for (i = 0; i < n-1; i++) - fprintf (stderr, "root z%d = %+.18f + %+.18f i \n", i, z[2*i], z[2*i+1]); - - return 0; - } - - *root = lambda; - return 1; -} - -void m_display(const char*str, gsl_matrix*m) { - printf("%s= \n", str); - unsigned int i,j; - for(i=0;i<m->size1;i++) { - printf(" "); - for(j=0;j<m->size2;j++) - printf("%e ", gmg(m,i,j)); - printf("\n"); - } -} - diff --git a/sm/lib/json-c/CMakeLists.txt b/sm/lib/json-c/CMakeLists.txt deleted file mode 100644 index a75dad6..0000000 --- a/sm/lib/json-c/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") -#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic") - -SET(json-c_sources - arraylist.c - debug.c - json_object.c - json_tokener.c - json_util.c - linkhash.c - printbuf.c - JSON_checker.c - json_more_utils.c -) - -ADD_LIBRARY(json-c STATIC ${json-c_sources}) - -#ADD_EXECUTABLE(test1 test1.c) -ADD_EXECUTABLE(test2 test2.c) - -#TARGET_LINK_LIBRARIES(test1 json-c) -TARGET_LINK_LIBRARIES(test2 json-c) - - -FILE(GLOB json_headers "*.h") -INSTALL(FILES ${json_headers} DESTINATION include/json-c) - - -INCLUDE(CheckIncludeFile) - -MACRO(MY_CHECK_INCLUDE_FILE file VAR) - CHECK_INCLUDE_FILE(${file} ${file}-exists) - IF(${${file}-exists}) - SET(${VAR} 1) - ELSE() - SET(${VAR} 0) - ENDIF(${${file}-exists}) -ENDMACRO(MY_CHECK_INCLUDE_FILE file VAR) - -MY_CHECK_INCLUDE_FILE(fcntl.h HAVE_FCNTL_H) -MY_CHECK_INCLUDE_FILE(inttypes.h HAVE_INTTYPES_H) -MY_CHECK_INCLUDE_FILE(limits.h HAVE_LIMITS_H) -MY_CHECK_INCLUDE_FILE(memory.h HAVE_MEMORY_H) -MY_CHECK_INCLUDE_FILE(stdarg.h HAVE_STDARG_H) -MY_CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H) -MY_CHECK_INCLUDE_FILE(stdlib.h HAVE_STDLIB_H) -MY_CHECK_INCLUDE_FILE(strings.h HAVE_STRINGS_H) -MY_CHECK_INCLUDE_FILE(string.h HAVE_STRING_H) -MY_CHECK_INCLUDE_FILE(syslog.h HAVE_SYSLOG_H) -MY_CHECK_INCLUDE_FILE(sys/param.h HAVE_SYS_PARAM_H) -MY_CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H) -MY_CHECK_INCLUDE_FILE(sys/stat.h HAVE_SYS_STAT_H) -MY_CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H) - -MACRO(MY_CHECK_FUNCTION_EXISTS function VAR) - CHECK_FUNCTION_EXISTS(${function} ${function}-exists) - IF(${${function}-exists}) - # MESSAGE(STATUS "Exists ${function} = ${${function}-exists}") - SET(${VAR} 1) - ELSE() - # MESSAGE(STATUS "NOT Exists ${function} = ${${function}-exists}") - SET(${VAR} 0) - ENDIF(${${function}-exists}) -ENDMACRO(MY_CHECK_FUNCTION_EXISTS function VAR) - -INCLUDE(CheckFunctionExists) - -MY_CHECK_FUNCTION_EXISTS(open HAVE_OPEN) -MY_CHECK_FUNCTION_EXISTS(strubded HAVE_STRUB) -MY_CHECK_FUNCTION_EXISTS(malloc HAVE_MALLOC) -MY_CHECK_FUNCTION_EXISTS(realloc HAVE_REALLOC) -MY_CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) -MY_CHECK_FUNCTION_EXISTS(strncasecmp HAVE_STRNCASECMP) -MY_CHECK_FUNCTION_EXISTS(strndup HAVE_STRNDUP) -MY_CHECK_FUNCTION_EXISTS(vasprintf HAVE_VASPRINTF) -MY_CHECK_FUNCTION_EXISTS(vprintf HAVE_VPRINTF) -MY_CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF) -MY_CHECK_FUNCTION_EXISTS(vsyslog HAVE_VSYSLOG) - -CONFIGURE_FILE(config.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/config.h) diff --git a/sm/lib/json-c/JSON_checker.c b/sm/lib/json-c/JSON_checker.c deleted file mode 100644 index e113821..0000000 --- a/sm/lib/json-c/JSON_checker.c +++ /dev/null @@ -1,414 +0,0 @@ -/* JSON_checker.c */ - - -/* 2005-12-30 */ - -/* -Copyright (c) 2005 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - - -#include "JSON_checker.h" - -#define true 1 -#define false 0 - -/* - Characters are mapped into these 32 symbol classes. This allows for - significant reductions in the size of the state transition table. -*/ - -/* error */ -#define S_ERR -1 - -/* space */ -#define S_SPA 0 - -/* other whitespace */ -#define S_WSP 1 - -/* { */ -#define S_LBE 2 - -/* } */ -#define S_RBE 3 - -/* [ */ -#define S_LBT 4 - -/* ] */ -#define S_RBT 5 - -/* : */ -#define S_COL 6 - -/* , */ -#define S_COM 7 - -/* " */ -#define S_QUO 8 - -/* \ */ -#define S_BAC 9 - -/* / */ -#define S_SLA 10 - -/* + */ -#define S_PLU 11 - -/* - */ -#define S_MIN 12 - -/* . */ -#define S_DOT 13 - -/* 0 */ -#define S_ZER 14 - -/* 123456789 */ -#define S_DIG 15 - -/* a */ -#define S__A_ 16 - -/* b */ -#define S__B_ 17 - -/* c */ -#define S__C_ 18 - -/* d */ -#define S__D_ 19 - -/* e */ -#define S__E_ 20 - -/* f */ -#define S__F_ 21 - -/* l */ -#define S__L_ 22 - -/* n */ -#define S__N_ 23 - -/* r */ -#define S__R_ 24 - -/* s */ -#define S__S_ 25 - -/* t */ -#define S__T_ 26 - -/* u */ -#define S__U_ 27 - -/* ABCDF */ -#define S_A_F 28 - -/* E */ -#define S_E 29 - -/* everything else */ -#define S_ETC 30 - - -/* - This table maps the 128 ASCII characters into the 32 character classes. - The remaining Unicode characters should be mapped to S_ETC. -*/ -static int ascii_class[128] = { - S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, - S_ERR, S_WSP, S_WSP, S_ERR, S_ERR, S_WSP, S_ERR, S_ERR, - S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, - S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, S_ERR, - - S_SPA, S_ETC, S_QUO, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, - S_ETC, S_ETC, S_ETC, S_PLU, S_COM, S_MIN, S_DOT, S_SLA, - S_ZER, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, S_DIG, - S_DIG, S_DIG, S_COL, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, - - S_ETC, S_A_F, S_A_F, S_A_F, S_A_F, S_E , S_A_F, S_ETC, - S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, - S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, S_ETC, - S_ETC, S_ETC, S_ETC, S_LBT, S_BAC, S_RBT, S_ETC, S_ETC, - - S_ETC, S__A_, S__B_, S__C_, S__D_, S__E_, S__F_, S_ETC, - S_ETC, S_ETC, S_ETC, S_ETC, S__L_, S_ETC, S__N_, S_ETC, - S_ETC, S_ETC, S__R_, S__S_, S__T_, S__U_, S_ETC, S_ETC, - S_ETC, S_ETC, S_ETC, S_LBE, S_ETC, S_RBE, S_ETC, S_ETC -}; - - -/* - The state transition table takes the current state and the current symbol, - and returns either a new state or an action. A new state is a number between - 0 and 29. An action is a negative number between -1 and -9. A JSON text is - accepted if the end of the text is in state 9 and mode is MODE_DONE. -*/ -static int state_transition_table[30][31] = { -/* 0*/ { 0, 0,-8,-1,-6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/* 1*/ { 1, 1,-1,-9,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/* 2*/ { 2, 2,-8,-1,-6,-5,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1}, -/* 3*/ { 3,-1, 3, 3, 3, 3, 3, 3,-4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, -/* 4*/ {-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1, 3,-1, 3, 3,-1, 3, 5,-1,-1,-1}, -/* 5*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 6, 6, 6, 6, 6, 6, 6, 6,-1,-1,-1,-1,-1,-1, 6, 6,-1}, -/* 6*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 7, 7, 7, 7, 7, 7, 7, 7,-1,-1,-1,-1,-1,-1, 7, 7,-1}, -/* 7*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 8, 8, 8, 8, 8, 8, 8, 8,-1,-1,-1,-1,-1,-1, 8, 8,-1}, -/* 8*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1,-1,-1,-1, 3, 3,-1}, -/* 9*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*10*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1}, -/*11*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1}, -/*12*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*13*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*14*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,-1,-1,-1,-1,-1,-1,-1,-1}, -/*15*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,-1,-1}, -/*16*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*17*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,18,-1,-1,-1}, -/*18*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,19,-1,-1,-1,-1,-1,-1,-1,-1}, -/*19*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 9,-1,-1,-1,-1,-1,-1,-1,-1}, -/*20*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*21*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*22*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,23,22,22,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1}, -/*23*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,23,23,-1,-1,-1,-1,24,-1,-1,-1,-1,-1,-1,-1,-1,24,-1}, -/*24*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,25,25,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*25*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*26*/ { 9, 9,-1,-7,-1,-5,-1,-3,-1,-1,-1,-1,-1,-1,26,26,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*27*/ {27,27,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, -/*28*/ {28,28,-8,-1,-6,-1,-1,-1, 3,-1,-1,-1,20,-1,21,22,-1,-1,-1,-1,-1,13,-1,17,-1,-1,10,-1,-1,-1,-1}, -/*29*/ {29,29,-1,-1,-1,-1,-1,-1, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} -}; - - - -/* - These modes can be pushed on the PDA stack. -*/ -#define MODE_DONE 1 -#define MODE_KEY 2 -#define MODE_OBJECT 3 -#define MODE_ARRAY 4 - -/* - A stack maintains the states of nested structures. -*/ -#define MAX_DEPTH 20 - -static int the_state; -static int the_stack[MAX_DEPTH]; -static int the_top; - -static int the_index = 0; - -/* - Push a mode onto the stack. Return false if there is overflow. -*/ -static int -push(int mode) -{ - the_top += 1; - if (the_top >= MAX_DEPTH) { - return false; - } - the_stack[the_top] = mode; - return true; -} - - -/* - Pop the stack, assuring that the current mode matches the expectation. - Return false if there is underflow or if the modes mismatch. -*/ -static int -pop(int mode) -{ - if (the_top < 0 || the_stack[the_top] != mode) { - return false; - } - the_stack[the_top] = 0; - the_top -= 1; - return true; -} - -int JSON_checker_push(int b); - -void JSON_checker_init() { - the_state = 0; - the_top = -1; - push(MODE_DONE); -} - -int JSON_checker_finished() { - return the_state == 9 && pop(MODE_DONE); -} - -/* - The JSON_checker takes a UTF-16 encoded string and determines if it is a - syntactically correct JSON text. - - It is implemented as a Pushdown Automaton; that means it is a finite state - machine with a stack. -*/ -int -JSON_checker(unsigned short p[], int length) -{ - JSON_checker_init(); - - for (the_index = 0; the_index < length; the_index += 1) { - if(!(JSON_checker_push(p[the_index]))) return false; - } - - return JSON_checker_finished() ; -} - - -int JSON_checker_push(int b) { - int c; /* the next character class */ - int s; /* the next state */ - if ((b & 127) == b) { - c = ascii_class[b]; - if (c <= S_ERR) { - return false; - } - } else { - c = S_ETC; - } -/* - Get the next state from the transition table. -*/ - s = state_transition_table[the_state][c]; - if (s < 0) { -/* - Perform one of the predefined actions. -*/ - switch (s) { -/* - empty } -*/ - case -9: - if (!pop(MODE_KEY)) { - return false; - } - the_state = 9; - break; -/* - { -*/ - case -8: - if (!push(MODE_KEY)) { - return false; - } - the_state = 1; - break; -/* - } -*/ - case -7: - if (!pop(MODE_OBJECT)) { - return false; - } - the_state = 9; - break; -/* - [ -*/ - case -6: - if (!push(MODE_ARRAY)) { - return false; - } - the_state = 2; - break; -/* - ] -*/ - case -5: - if (!pop(MODE_ARRAY)) { - return false; - } - the_state = 9; - break; -/* - " -*/ - case -4: - switch (the_stack[the_top]) { - case MODE_KEY: - the_state = 27; - break; - case MODE_ARRAY: - case MODE_OBJECT: - the_state = 9; - break; - default: - return false; - } - break; -/* - , -*/ - case -3: - switch (the_stack[the_top]) { - case MODE_OBJECT: - if (pop(MODE_OBJECT) && push(MODE_KEY)) { - the_state = 29; - } - break; - case MODE_ARRAY: - the_state = 28; - break; - default: - return false; - } - break; -/* - : -*/ - case -2: - if (pop(MODE_KEY) && push(MODE_OBJECT)) { - the_state = 28; - break; - } -/* - syntax error -*/ - case -1: - return false; - } - } else { -/* - Change the state and iterate. -*/ - the_state = s; - } - return true; -} -/* - Get the current character number. -*/ -int -JSON_checker_at_character() -{ - return the_index; -} diff --git a/sm/lib/json-c/JSON_checker.h b/sm/lib/json-c/JSON_checker.h deleted file mode 100644 index 4561385..0000000 --- a/sm/lib/json-c/JSON_checker.h +++ /dev/null @@ -1,10 +0,0 @@ -/* JSON_checker.h */ - -extern int JSON_checker(unsigned short p[], int length); -extern int JSON_checker_at_character(void); - - -void JSON_checker_init(void); -int JSON_checker_push(int b); -int JSON_checker_finished(void); - diff --git a/sm/lib/json-c/arraylist.c b/sm/lib/json-c/arraylist.c deleted file mode 100644 index a6db497..0000000 --- a/sm/lib/json-c/arraylist.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include "config.h" - -#if STDC_HEADERS -# include <stdlib.h> -# include <string.h> -#endif /* STDC_HEADERS */ - -#if HAVE_STRINGS_H -# include <strings.h> -#endif /* HAVE_STRINGS_H */ - -#include "bits.h" -#include "arraylist.h" - -struct array_list* -array_list_new(array_list_free_fn *free_fn) -{ - struct array_list *this; - - if(!(this = calloc(1, sizeof(struct array_list)))) return NULL; - this->size = ARRAY_LIST_DEFAULT_SIZE; - this->length = 0; - this->free_fn = free_fn; - if(!(this->array = calloc(sizeof(void*), (size_t) this->size))) { - free(this); - return NULL; - } - return this; -} - -extern void -array_list_free(struct array_list *this) -{ - int i; - for(i = 0; i < this->length; i++) - if(this->array[i]) this->free_fn(this->array[i]); - free(this->array); - free(this); -} - -void* -array_list_get_idx(struct array_list *this, int i) -{ - if(i >= this->length) return NULL; - return this->array[i]; -} - -static int array_list_expand_internal(struct array_list *this, int max) -{ - void *t; - int new_size; - - if(max < this->size) return 0; - new_size = max(this->size << 1, max); - if(!(t = realloc(this->array, new_size*sizeof(void*)))) return -1; - this->array = t; - (void)memset(this->array + this->size, 0, (new_size-this->size)*sizeof(void*)); - this->size = new_size; - return 0; -} - -int -array_list_put_idx(struct array_list *this, int idx, void *data) -{ - if(array_list_expand_internal(this, idx)) return -1; - if(this->array[idx]) this->free_fn(this->array[idx]); - this->array[idx] = data; - if(this->length <= idx) this->length = idx + 1; - return 0; -} - -int -array_list_add(struct array_list *this, void *data) -{ - return array_list_put_idx(this, this->length, data); -} - -int -array_list_length(struct array_list *this) -{ - return this->length; -} diff --git a/sm/lib/json-c/arraylist.h b/sm/lib/json-c/arraylist.h deleted file mode 100644 index 2948e04..0000000 --- a/sm/lib/json-c/arraylist.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _arraylist_h_ -#define _arraylist_h_ - -#define ARRAY_LIST_DEFAULT_SIZE 32 - -typedef void (array_list_free_fn) (void *data); - -struct array_list -{ - void **array; - int length; - int size; - array_list_free_fn *free_fn; -}; - -extern struct array_list* -array_list_new(array_list_free_fn *free_fn); - -extern void -array_list_free(struct array_list *al); - -extern void* -array_list_get_idx(struct array_list *al, int i); - -extern int -array_list_put_idx(struct array_list *al, int i, void *data); - -extern int -array_list_add(struct array_list *al, void *data); - -extern int -array_list_length(struct array_list *al); - -#endif diff --git a/sm/lib/json-c/bits.h b/sm/lib/json-c/bits.h deleted file mode 100644 index 2c107cc..0000000 --- a/sm/lib/json-c/bits.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * $Id: bits.h,v 1.10 2006/01/30 23:07:57 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _bits_h_ -#define _bits_h_ - -#ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#endif - -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif - -#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9) -#define error_ptr(error) ((void*)error) -#define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L) - -#endif diff --git a/sm/lib/json-c/config.h.cmake b/sm/lib/json-c/config.h.cmake deleted file mode 100644 index 7b92061..0000000 --- a/sm/lib/json-c/config.h.cmake +++ /dev/null @@ -1,101 +0,0 @@ -/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ -#define HAVE_DOPRNT ${HAVE_DOPRNT} - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define HAVE_FCNTL_H ${HAVE_FCNTL_H} - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H ${HAVE_INTTYPES_H} - -/* Define to 1 if you have the <limits.h> header file. */ -#define HAVE_LIMITS_H ${HAVE_LIMITS_H} - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define HAVE_MALLOC ${HAVE_MALLOC} - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H ${HAVE_MEMORY_H} - -/* Define to 1 if you have the `open' function. */ -#define HAVE_OPEN ${HAVE_OPEN} - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#define HAVE_REALLOC ${HAVE_REALLOC} - -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H ${HAVE_STDARG_H} - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H ${HAVE_STDINT_H} - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H ${HAVE_STDLIB_H} - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR ${HAVE_STRERROR} - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H ${HAVE_STRINGS_H} - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H ${HAVE_STRING_H} - -/* Define to 1 if you have the `strncasecmp' function. */ -#define HAVE_STRNCASECMP ${HAVE_STRNCASECMP} - -/* Define to 1 if you have the `strndup' function. */ -#define HAVE_STRNDUP ${HAVE_STRNDUP} - -/* Define to 1 if you have the <syslog.h> header file. */ -#define HAVE_SYSLOG_H ${HAVE_SYSLOG_H} - -/* Define to 1 if you have the <sys/param.h> header file. */ -#define HAVE_SYS_PARAM_H ${HAVE_SYS_PARAM_H} - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H ${HAVE_SYS_STAT_H} - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H} - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H ${HAVE_UNISTD_H} - -/* Define to 1 if you have the `vasprintf' function. */ -#define HAVE_VASPRINTF ${HAVE_VASPRINTF} - -/* Define to 1 if you have the `vprintf' function. */ -#define HAVE_VPRINTF ${HAVE_VPRINTF} - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF ${HAVE_VSNPRINTF} - -/* Define to 1 if you have the `vsyslog' function. */ -#define HAVE_VSYSLOG ${HAVE_VSYSLOG} - - -/* Define to rpl_malloc if the replacement function should be used. */ -#if !HAVE_MALLOC -#define malloc rpl_malloc -#endif - -/* Define to rpl_realloc if the replacement function should be used. */ -#if !HAVE_REALLOC -#define realloc rpl_realloc -#endif - - - - - - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to empty if `const' does not conform to ANSI C. */ -#cmakedefine const - -/* Define to `unsigned int' if <sys/types.h> does not define. */ -#cmakedefine size_t diff --git a/sm/lib/json-c/debug.c b/sm/lib/json-c/debug.c deleted file mode 100644 index eaa6fca..0000000 --- a/sm/lib/json-c/debug.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * $Id: debug.c,v 1.5 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> - -#if HAVE_SYSLOG_H -# include <syslog.h> -#endif /* HAVE_SYSLOG_H */ - -#if HAVE_UNISTD_H -# include <unistd.h> -#endif /* HAVE_UNISTD_H */ - -#if HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif /* HAVE_SYS_PARAM_H */ - -#include "debug.h" - -static int _syslog = 0; -static int _debug = 0; - -void mc_set_debug(int debug) { _debug = debug; } -int mc_get_debug() { return _debug; } - -extern void mc_set_syslog(int syslog) -{ - _syslog = syslog; -} - -void mc_abort(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); -#if HAVE_VSYSLOG - if(_syslog) { - vsyslog(LOG_ERR, msg, ap); - } else -#endif - vprintf(msg, ap); - exit(1); -} - - -void mc_debug(const char *msg, ...) -{ - va_list ap; - if(_debug) { - va_start(ap, msg); -#if HAVE_VSYSLOG - if(_syslog) { - vsyslog(LOG_DEBUG, msg, ap); - } else -#endif - vprintf(msg, ap); - } -} - -void mc_error(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); -#if HAVE_VSYSLOG - if(_syslog) { - vsyslog(LOG_ERR, msg, ap); - } else -#endif - vfprintf(stderr, msg, ap); -} - -void mc_info(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); -#if HAVE_VSYSLOG - if(_syslog) { - vsyslog(LOG_INFO, msg, ap); - } else -#endif - vfprintf(stderr, msg, ap); -} diff --git a/sm/lib/json-c/debug.h b/sm/lib/json-c/debug.h deleted file mode 100644 index 03a9b44..0000000 --- a/sm/lib/json-c/debug.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * $Id: debug.h,v 1.5 2006/01/30 23:07:57 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _DEBUG_H_ -#define _DEBUG_H_ - -extern void mc_set_debug(int debug); -extern int mc_get_debug(void); - -extern void mc_set_syslog(int syslog); -extern void mc_abort(const char *msg, ...); -extern void mc_debug(const char *msg, ...); -extern void mc_error(const char *msg, ...); -extern void mc_info(const char *msg, ...); - -#endif diff --git a/sm/lib/json-c/json.h b/sm/lib/json-c/json.h deleted file mode 100644 index e6bfbd7..0000000 --- a/sm/lib/json-c/json.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _json_h_ -#define _json_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "bits.h" -#include "debug.h" -#include "linkhash.h" -#include "arraylist.h" -#include "json_util.h" -#include "json_object.h" -#include "json_tokener.h" -#include "json_more_utils.h" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/sm/lib/json-c/json_more_utils.c b/sm/lib/json-c/json_more_utils.c deleted file mode 100644 index d714daf..0000000 --- a/sm/lib/json-c/json_more_utils.c +++ /dev/null @@ -1,331 +0,0 @@ -#include <string.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <math.h> -#include "debug.h" -#include "bits.h" -#include "json_object.h" -#include "json_more_utils.h" -#include "json_tokener.h" -#include "JSON_checker.h" -#include "linkhash.h" - - -double convert_to_double(JO jo); - -#ifndef NAN -#define NAN strtod("NaN",0) -#endif - -int json_stream_skip(FILE*f) { - int count = 0; - JSON_checker_init(); - while(1) { - char c; - if(1 != fread(&c,1,1,f)) { - if(feof(f)) { - if(count==0) return 0; - mc_error("EOF after %d bytes were read.\n", count); - return 0; - } - mc_error("Reading error: %s\n", strerror(errno)); - return 0; - } else { - if(!JSON_checker_push(c)) { - mc_error("Malformed JSON object. (read %d bytes).\n", count); - return 0; - } - - if(JSON_checker_finished()) - return 1; - } - count++; - } -} - -JO json_read_stream(FILE*f) { - - size_t buf_size = 100000; - char * buf = (char*) malloc(buf_size); - - int count = 0; - - JSON_checker_init(); - while(1) { - if( ((size_t)count) > buf_size - 2) { - buf_size *= 2; - char * new_buf = realloc(buf, buf_size); - if(!new_buf) { - mc_error("Having read %d bytes, cannot allocate a block of size %d.", - count, buf_size); - free(buf); - return 0; - } - buf = new_buf; - } - char c; - if(1 != fread(&c,1,1,f)) { - if(feof(f)) { - if(count==0) { free(buf); return 0; } - mc_error("EOF while %d were read: \n\t'%.*s'. \n", count, count, buf); - free(buf); return 0; - } - mc_error("Reading error: %s\n", strerror(errno)); - return 0; - } else { - if(count==0 && isspace(c)) continue; - - buf[count] = c; - count++; - - if(!JSON_checker_push(c)) { - mc_error("Malformed JSON object: \n'%.*s'\n", count, buf); - free(buf); return 0; - } - - if(JSON_checker_finished()) { -/* sm_de("Found object.\n"); */ - JO jo = json_tokener_parse_len(buf, count); - - free(buf); return jo; - } - - } - } -} - - - -struct json_object* json_tokener_parse_len(const char *str, int len) { - struct json_tokener* tok; - struct json_object* obj; - - tok = json_tokener_new(); - obj = json_tokener_parse_ex(tok, str, len); - if(tok->err != json_tokener_success) { - obj = error_ptr(-tok->err); - json_tokener_free(tok); - mc_error("Malformed JSON object: \n'%.*s'\n", len, str); - return 0; - } - json_tokener_free(tok); - return obj; -} - -int jo_has_field(JO s, const char*name) { - return json_object_object_get(s, name) != 0; -} - - -int jo_read_double_array(JO s, const char*name, double*p, int n, double when_null) { - JO jo = json_object_object_get(s, name); - if(!jo) { -/* mc_error("Field '%s' not found.\n", name); */ - return 0; - } - - return jo_read_from_double_array (jo, p, n, when_null); -} - -/* Returns 0 if jo is not a double array, or its length is not n */ -int jo_read_from_double_array (JO jo, double *p, int n, double when_null) { - if(!json_object_is_type(jo, (enum json_type) json_type_array)) { - mc_error("This is not an array: '%s'\n",json_object_to_json_string(jo)); - return 0; - } - - { - int size = json_object_array_length(jo); - if(size < n) { - mc_error("I expected at least %d elements, got %d. \nArray: '%s'\n", - n, size, json_object_to_json_string(jo)); - return 0; - } - } - - { - int i; for(i=0;i<n;i++) { - JO v = json_object_array_get_idx(jo, i); - if(!v) - p[i] = when_null; - else - if(json_object_is_type(v, (enum json_type) json_type_double)) { - p[i] = json_object_get_double(v); - } else - if(json_object_is_type(v, (enum json_type) json_type_int)) { - p[i] = json_object_get_int(v); - } else - p[i] = when_null; - } - } - return 1; -} - - - - -int jo_read_int_array(JO s, const char*name, int*p, int n, int when_null) { - int size, i; - JO jo = json_object_object_get(s, name); - if(!jo) { -/* mc_error("Field '%s' not found.\n", name); */ - return 0; - } - if(!json_object_is_type(jo, (enum json_type) json_type_array)) { - mc_error("This is not an array: '%s'\n",json_object_to_json_string(jo)); - return 0; - } - size = json_object_array_length(jo); - if(size < n) { - mc_error("I expected at least %d elements, got %d. \nArray: '%s'\n", - n, size, json_object_to_json_string(jo)); - return 0; - } - for(i=0;i<n;i++) { - JO v = json_object_array_get_idx(jo, i); - if(!v || !json_object_is_type(v, (enum json_type) json_type_int)) - p[i] = when_null; - else - p[i] = json_object_get_int(v); - } - return 1; /** XXX should we thro error? */ -} - -JO jo_double_or_null(double v) { - return (v == v) ? /* NAN is null */ - json_object_new_double(v) : jo_new_null() ; -} - -JO jo_new_double_array(const double *v, int n) { - JO array = json_object_new_array(); - int i; for(i=0;i<n;i++) { - json_object_array_add(array, jo_double_or_null(v[i])); - } - return array; -} - -JO jo_new_int_array(const int *v, int n) { - JO array = json_object_new_array(); - int i; for(i=0;i<n;i++) { - json_object_array_add(array, json_object_new_int(v[i])); - } - return array; -} - -/** XXX forse ho fatto casino */ -int json_to_int(JO jo, int*ptr) { - - if(!jo) { -/* mc_error("Field '%s' not found.\n", name); */ - return 0; - } - - if(!json_object_is_type(jo, (enum json_type) json_type_int)) { - mc_error("I was looking for a int, instead got '%s'.\n", - json_object_to_json_string(jo)); - return 0; - } - - *ptr = json_object_get_int(jo); - - return 1; -} - -int json_to_double(JO jo, double*ptr) { - if(json_object_is_type(jo, (enum json_type) json_type_double)) { - *ptr = json_object_get_double(jo); - return 1; - } else if(json_object_is_type(jo, (enum json_type) json_type_int)) { - *ptr = json_object_get_int(jo); - return 1; - } else{ - *ptr = NAN; - return 0; - } -} - -int jo_read_int(JO jo, const char*name, int*p) { - JO v = json_object_object_get(jo, name); - if(!v) { - return 0; - } - return json_to_int(v, p); -} - -double convert_to_double(JO jo) { - if(json_object_is_type(jo, (enum json_type) json_type_double)) - return json_object_get_double(jo); - else if(json_object_is_type(jo, (enum json_type) json_type_int)) { - return json_object_get_int(jo); - } - else - return NAN; -} - -int jo_read_double(JO jo, const char*name, double*p) { - JO v = json_object_object_get(jo, name); - - if(!v) { -/* mc_error("Field '%s' not found.\n", name); */ - return 0; - } - - *p = convert_to_double(v); - return 1; -} - - -int jo_read_string(JO jo, const char*name, char*dest_string, size_t max_len) { - JO v = json_object_object_get(jo, name); - if(!v) return 0; - if(json_object_is_type(v, (enum json_type) json_type_string)) { - strncpy(dest_string, json_object_get_string(v), max_len); - return 1; - } else { - strncpy(dest_string, "<string not found>", max_len); - return 0; - } -} - -void jo_add_string(JO root, const char*name, const char*v) { - jo_add(root, name, jo_new_string(v)); -} - -void jo_add_double_array(JO root, const char*name, const double*v, int n) { - jo_add(root, name, jo_new_double_array(v, n)); -} - -void jo_add_int_array(JO root, const char*name, const int*v, int n) { - jo_add(root, name, jo_new_int_array(v, n)); -} - -void jo_add_int(JO root, const char*name, int v) { - jo_add(root, name, jo_new_int(v)); -} - -void jo_add_double(JO root, const char*name, double v) { - jo_add(root, name, jo_double_or_null(v)); -} - -JO json_parse(const char*str) { - return json_tokener_parse_len(str, (int)strlen(str)); -} - -const char* json_write(JO jo) { - return json_object_to_json_string(jo); -} - -/* -JO find_object_with_name(JO root, const char*name) { - json_object_object_foreach(root, key, val) { - if(!strcmp(key, name)) return root; - if(json_object_is_type(val, json_type_object)) { - JO jo = find_object_with_name(val, name); - if(jo) return jo; - } - } - return 0; -}*/ - diff --git a/sm/lib/json-c/json_more_utils.h b/sm/lib/json-c/json_more_utils.h deleted file mode 100644 index 385ed81..0000000 --- a/sm/lib/json-c/json_more_utils.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef H_JSON_MORE_UTILS -#define H_JSON_MORE_UTILS - -#include <stdio.h> -#include "json_object.h" - -typedef struct json_object* JO; - -#define jo_new_double json_object_new_double -#define jo_new_int json_object_new_int -#define jo_new_array json_object_new_array -#define jo_new_string json_object_new_string -#define jo_new_null() 0 -#define jo_add json_object_object_add -#define jo_del json_object_object_del -#define jo_free json_object_put -#define jo_get json_object_object_get -#define jo_new json_object_new_object -#define jo_array_add json_object_array_add -#define jo_array_get json_object_array_get_idx -#define jo_array_length json_object_array_length -#define jo_get_string json_object_get_string - -/** Reads a JSON object from stream. - Returns 0 on error. XXX: does not support unicode. */ -JO json_read_stream(FILE*); - -/** Skips one object from stream (without parsing it). - Returns 0 on error. XXX: does not support unicode. */ -int json_stream_skip(FILE*); - -/** Return true if there is a field */ -int jo_has_field(JO s, const char*name); - -JO jo_new_double_array(const double *v, int n); -JO jo_new_int_array (const int *v, int n); - -void jo_add_double (JO parent, const char*name, double v); -void jo_add_int (JO parent, const char*name, int v); -void jo_add_double_array (JO parent, const char*name, const double *v, int n); -void jo_add_int_array (JO parent, const char*name, const int *v, int n); - -void jo_add_string (JO parent, const char*name, const char*v); - -/** Return 0 if there isn't a field called 'name' */ -int jo_read_int (JO parent, const char*name, int*p) ; -/** This also tolerates an integer */ -int jo_read_double (JO parent, const char*name, double*p); - -/* Returns 0 if there isn't a field called "name", or it's not an array, or -its length is not at least "n". Else, it returns 1. */ -int jo_read_double_array (JO parent, const char*name, double *p, int n, double when_null); -int jo_read_int_array (JO parent, const char*name, int *p, int n, int when_null); -int jo_read_string (JO parent, const char*name, char*v, size_t max_len); - - -/* Returns 0 if jo is not a double array, or its length is not n */ -int jo_read_from_double_array (JO array, double *p, int n, double when_null); - - -int json_to_int(JO jo, int*ptr); - -/** Converts an integer or a double to a double, - or else *ptr will be set to NAN. */ -int json_to_double(JO jo, double*ptr); - - -/* returns 0 if NAN */ -JO jo_double_or_null(double d); - -/*JO find_object_with_name(JO root, const char*name);*/ -JO json_tokener_parse_len(const char *str, int len); -JO json_parse(const char*str); -const char* json_write(JO jo); -#define jo_to_string json_write - -#endif diff --git a/sm/lib/json-c/json_object.c b/sm/lib/json-c/json_object.c deleted file mode 100644 index b32740e..0000000 --- a/sm/lib/json-c/json_object.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include <assert.h> -#include "config.h" - -/* This is an hack for strndup */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#include <stdio.h> -#include <stdlib.h> - -#include <string.h> -#include <strings.h> - -#include "debug.h" -#include "printbuf.h" -#include "linkhash.h" -#include "arraylist.h" -#include "json_object.h" -#include "json_object_private.h" -#include "json_tokener.h" - -/*#if !HAVE_STRNDUP*/ - char* json_c_strndup(const char* str, size_t n); -/*#endif !HAVE_STRNDUP */ - -/* #define REFCOUNT_DEBUG 1 */ - -const char *json_number_chars = "0123456789.+-e"; -const char *json_hex_chars = "0123456789abcdef"; - -#ifdef REFCOUNT_DEBUG -static const char* json_type_name[] = { - "null", - "boolean", - "double", - "int", - "object", - "array", - "string", -}; -#endif /* REFCOUNT_DEBUG */ - -static void json_object_generic_delete(struct json_object* this); -static struct json_object* json_object_new(enum json_type o_type); - - -/* ref count debugging */ - -#ifdef REFCOUNT_DEBUG - -static struct lh_table *json_object_table; - -static void json_object_init() __attribute__ ((constructor)); -static void json_object_init() { - mc_debug("json_object_init: creating object table\n"); - json_object_table = lh_kptr_table_new(128, "json_object_table", NULL); -} - -static void json_object_fini() __attribute__ ((destructor)); -static void json_object_fini() { - struct lh_entry *ent; - if(mc_get_debug() && json_object_table->count) { - mc_debug("json_object_fini: %d referenced objects at exit\n", - json_object_table->count); - lh_foreach(json_object_table, ent) { - struct json_object* obj = (struct json_object*)ent->v; - mc_debug("\t%s:%p\n", json_type_name[obj->o_type], obj); - } - } - mc_debug("json_object_fini: freeing object table\n"); - lh_table_free(json_object_table); -} -#endif /* REFCOUNT_DEBUG */ - - -/* string escaping */ - -static int json_escape_str(struct printbuf *pb, char *str) -{ - int pos = 0, start_offset = 0; - unsigned char c; - do { - c = str[pos]; - switch(c) { - case '\0': - break; - case '\b': - case '\n': - case '\r': - case '\t': - case '"': - case '\\': - case '/': - if(pos - start_offset > 0) - printbuf_memappend(pb, str + start_offset, pos - start_offset); - if(c == '\b') printbuf_memappend(pb, "\\b", 2); - else if(c == '\n') printbuf_memappend(pb, "\\n", 2); - else if(c == '\r') printbuf_memappend(pb, "\\r", 2); - else if(c == '\t') printbuf_memappend(pb, "\\t", 2); - else if(c == '"') printbuf_memappend(pb, "\\\"", 2); - else if(c == '\\') printbuf_memappend(pb, "\\\\", 2); - else if(c == '/') printbuf_memappend(pb, "\\/", 2); - start_offset = ++pos; - break; - default: - if(c < ' ') { - if(pos - start_offset > 0) - printbuf_memappend(pb, str + start_offset, pos - start_offset); - sprintbuf(pb, "\\u00%c%c", - json_hex_chars[c >> 4], - json_hex_chars[c & 0xf]); - start_offset = ++pos; - } else pos++; - } - } while(c); - if(pos - start_offset > 0) - printbuf_memappend(pb, str + start_offset, pos - start_offset); - return 0; -} - - -/* reference counting */ - -extern struct json_object* json_object_get(struct json_object *this) -{ - if(this) { - this->_ref_count++; - } - return this; -} - -extern void json_object_put(struct json_object *this) -{ - if(this) { - this->_ref_count--; - if(!this->_ref_count) this->_delete(this); - } -} - - -/* generic object construction and destruction parts */ - -static void json_object_generic_delete(struct json_object* this) -{ -#ifdef REFCOUNT_DEBUG - mc_debug("json_object_delete_%s: %p\n", - json_type_name[this->o_type], this); - lh_table_delete(json_object_table, this); -#endif /* REFCOUNT_DEBUG */ - printbuf_free(this->_pb); - free(this); -} - -static struct json_object* json_object_new(enum json_type o_type) -{ - struct json_object *this = calloc(sizeof(struct json_object), 1); - if(!this) return NULL; - this->o_type = o_type; - this->_ref_count = 1; - this->_delete = &json_object_generic_delete; -#ifdef REFCOUNT_DEBUG - lh_table_insert(json_object_table, this, this); - mc_debug("json_object_new_%s: %p\n", json_type_name[this->o_type], this); -#endif /* REFCOUNT_DEBUG */ - return this; -} - - -/* type checking functions */ - -/*int json_object_is_type(struct json_object *this, enum json_type type)*/ -int json_object_is_type(struct json_object *this, int type) -{ - if(!this && json_type_null == type) return 1; - return (this->o_type == type); -} - -enum json_type json_object_get_type(struct json_object *this) -{ - if(!this) return json_type_null; - return this->o_type; -} - - -/* json_object_to_json_string */ - -const char* json_object_to_json_string(struct json_object *this) -{ - if(!this) return "null"; - if(!this->_pb) { - if(!(this->_pb = printbuf_new())) return NULL; - } else { - printbuf_reset(this->_pb); - } - if(this->_to_json_string(this, this->_pb) < 0) return NULL; - return this->_pb->buf; -} - - -/* json_object_object */ - -static int json_object_object_to_json_string(struct json_object* this, - struct printbuf *pb) -{ - int i=0; - struct json_object_iter iter; - sprintbuf(pb, "{"); - - /* CAW: scope operator to make ANSI correctness */ - /* CAW: switched to json_object_object_foreachC which uses an iterator struct */ - json_object_object_foreachC(this, iter) { - if(i) sprintbuf(pb, ","); - sprintbuf(pb, " \""); - json_escape_str(pb, iter.key); - sprintbuf(pb, "\": "); - if(iter.val == NULL) sprintbuf(pb, "null"); - else iter.val->_to_json_string(iter.val, pb); - i++; - } - - return sprintbuf(pb, " }"); -} - -static void json_object_lh_entry_free(struct lh_entry *ent) -{ - free(ent->k); - json_object_put((struct json_object*)ent->v); -} - -static void json_object_object_delete(struct json_object* this) -{ - lh_table_free(this->o.c_object); - json_object_generic_delete(this); -} - -struct json_object* json_object_new_object() -{ - struct json_object *this = json_object_new(json_type_object); - if(!this) return NULL; - this->_delete = &json_object_object_delete; - this->_to_json_string = &json_object_object_to_json_string; - this->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTIRES, - NULL, &json_object_lh_entry_free); - return this; -} - -struct lh_table* json_object_get_object(struct json_object *this) -{ - if(!this) return NULL; - switch(this->o_type) { - case json_type_object: - return this->o.c_object; - default: - return NULL; - } -} - -void json_object_object_add(struct json_object* this, const char *key, - struct json_object *val) -{ - lh_table_delete(this->o.c_object, (char*) key); - lh_table_insert(this->o.c_object, strdup(key), val); -} - -struct json_object* json_object_object_get(struct json_object* this, const char *key) -{ - return (struct json_object*) lh_table_lookup(this->o.c_object, (char*)key); -} - -void json_object_object_del(struct json_object* this, const char *key) -{ - lh_table_delete(this->o.c_object, (char*) key); -} - - -/* json_object_boolean */ - -static int json_object_boolean_to_json_string(struct json_object* this, - struct printbuf *pb) -{ - if(this->o.c_boolean) return sprintbuf(pb, "true"); - else return sprintbuf(pb, "false"); -} - -struct json_object* json_object_new_boolean(boolean b) -{ - struct json_object *this = json_object_new(json_type_boolean); - if(!this) return NULL; - this->_to_json_string = &json_object_boolean_to_json_string; - this->o.c_boolean = b; - return this; -} - -boolean json_object_get_boolean(struct json_object *this) -{ - if(!this) return FALSE; - switch(this->o_type) { - case json_type_boolean: - return this->o.c_boolean; - case json_type_int: - return (this->o.c_int != 0); - case json_type_double: - return (this->o.c_double != 0); - case json_type_string: - if(strlen(this->o.c_string)) return TRUE; - default: - return TRUE; - } -} - - -/* json_object_int */ - -static int json_object_int_to_json_string(struct json_object* this, - struct printbuf *pb) -{ - return sprintbuf(pb, "%d", this->o.c_int); -} - -struct json_object* json_object_new_int(int i) -{ - struct json_object *this = json_object_new(json_type_int); - if(!this) return NULL; - this->_to_json_string = &json_object_int_to_json_string; - this->o.c_int = i; - return this; -} - -int json_object_get_int(struct json_object *this) -{ - int cint; - - if(!this) return 0; - switch(this->o_type) { - case json_type_int: - return this->o.c_int; - case json_type_double: - return (int)this->o.c_double; - case json_type_boolean: - return this->o.c_boolean; - case json_type_string: - if(sscanf(this->o.c_string, "%d", &cint) == 1) return cint; - default: - return 0; - } -} - -const char *float_format = "%e"; - -void json_set_float_format(const char*f) { - float_format = f; -} - -/* json_object_double */ - -static int json_object_double_to_json_string(struct json_object* this, - struct printbuf *pb) -{ -#define AC_BETTER_PRECISION -#ifdef AC_BETTER_PRECISION -//#warning json: Using better precision in printing floats - if( ((int) this->o.c_double) != this->o.c_double) -// return sprintbuf(pb, "%g", this->o.c_double); - return sprintbuf(pb, float_format, this->o.c_double); - else - return sprintbuf(pb, "%d.0", (int) this->o.c_double); -#else - return sprintbuf(pb, "%lf", this->o.c_double); - -#endif - -} - -struct json_object* json_object_new_double(double d) -{ - struct json_object *this = json_object_new(json_type_double); - if(!this) return NULL; - this->_to_json_string = &json_object_double_to_json_string; - this->o.c_double = d; - return this; -} - -double json_object_get_double(struct json_object *this) -{ - double cdouble; - - if(!this) return 0.0; - switch(this->o_type) { - case json_type_double: - return this->o.c_double; - case json_type_int: - return this->o.c_int; - case json_type_boolean: - return this->o.c_boolean; - case json_type_string: - if(sscanf(this->o.c_string, "%lf", &cdouble) == 1) return cdouble; - default: - return 0.0; - } -} - - -/* json_object_string */ - -static int json_object_string_to_json_string(struct json_object* this, - struct printbuf *pb) -{ - sprintbuf(pb, "\""); - json_escape_str(pb, this->o.c_string); - sprintbuf(pb, "\""); - return 0; -} - -static void json_object_string_delete(struct json_object* this) -{ - free(this->o.c_string); - json_object_generic_delete(this); -} - -struct json_object* json_object_new_string(const char *s) -{ - struct json_object *this = json_object_new(json_type_string); - if(!this) return NULL; - this->_delete = &json_object_string_delete; - this->_to_json_string = &json_object_string_to_json_string; - this->o.c_string = json_c_strndup(s, strlen(s)); - return this; -} - -struct json_object* json_object_new_string_len(const char *s, int len) -{ - struct json_object *this = json_object_new(json_type_string); - if(!this) return NULL; - this->_delete = &json_object_string_delete; - this->_to_json_string = &json_object_string_to_json_string; - this->o.c_string = json_c_strndup(s, (size_t)len); - return this; -} - -char* json_object_get_string(struct json_object *this) -{ - if(!this) return NULL; - switch(this->o_type) { - case json_type_string: - return this->o.c_string; - default: - return json_object_to_json_string(this); - } -} - - -/* json_object_array */ - -static int json_object_array_to_json_string(struct json_object* this, - struct printbuf *pb) -{ - int i; - sprintbuf(pb, "["); - for(i=0; i < json_object_array_length(this); i++) { - struct json_object *val; - if(i) { sprintbuf(pb, ", "); } - else { sprintbuf(pb, " "); } - - val = json_object_array_get_idx(this, i); - if(val == NULL) { sprintbuf(pb, "null"); } - else { val->_to_json_string(val, pb); } - } - return sprintbuf(pb, " ]"); -} - -static void json_object_array_entry_free(void *data) -{ - json_object_put((struct json_object*)data); -} - -static void json_object_array_delete(struct json_object* this) -{ - assert(json_object_is_type(this, json_type_array)); - array_list_free(this->o.c_array); - json_object_generic_delete(this); -} - -struct json_object* json_object_new_array() -{ - struct json_object *this = json_object_new(json_type_array); - if(!this) return NULL; - this->_delete = &json_object_array_delete; - this->_to_json_string = &json_object_array_to_json_string; - this->o.c_array = array_list_new(&json_object_array_entry_free); - return this; -} - -struct array_list* json_object_get_array(struct json_object *this) -{ - if(!this) return NULL; - switch(this->o_type) { - case json_type_array: - return this->o.c_array; - default: - return NULL; - } -} - -int json_object_array_length(struct json_object *this) -{ - assert(json_object_is_type(this, json_type_array)); - return array_list_length(this->o.c_array); -} - -int json_object_array_add(struct json_object *this,struct json_object *val) -{ - assert(json_object_is_type(this, json_type_array)); - return array_list_add(this->o.c_array, val); -} - -int json_object_array_put_idx(struct json_object *this, int idx, - struct json_object *val) -{ - assert(json_object_is_type(this, json_type_array)); - return array_list_put_idx(this->o.c_array, idx, val); -} - -struct json_object* json_object_array_get_idx(struct json_object *this, - int idx) -{ - assert(json_object_is_type(this, json_type_array)); - return (struct json_object*)array_list_get_idx(this->o.c_array, idx); -} - diff --git a/sm/lib/json-c/json_object.h b/sm/lib/json-c/json_object.h deleted file mode 100644 index 1d589ca..0000000 --- a/sm/lib/json-c/json_object.h +++ /dev/null @@ -1,315 +0,0 @@ -/* - * $Id: json_object.h,v 1.12 2006/01/30 23:07:57 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _json_object_h_ -#define _json_object_h_ - -#define JSON_OBJECT_DEF_HASH_ENTIRES 16 - -#undef FALSE -#define FALSE ((boolean)0) - -#undef TRUE -#define TRUE ((boolean)1) - -extern const char *json_number_chars; -extern const char *json_hex_chars; - -/* forward structure definitions */ - -typedef int boolean; -struct printbuf; -struct lh_table; -struct array_list; -struct json_object; -struct json_object_iter; - -/* supported object types */ - -enum json_type { - json_type_null, - json_type_boolean, - json_type_double, - json_type_int, - json_type_object, - json_type_array, - json_type_string -}; - -/* reference counting functions */ - - - - -/** - * Increment the reference count of json_object - * @param obj the json_object instance - */ -extern struct json_object* json_object_get(struct json_object *obj); - -/** - * Decrement the reference count of json_object and free if it reaches zero - * @param obj the json_object instance - */ -extern void json_object_put(struct json_object *obj); - - -/** - * Check if the json_object is of a given type - * @param obj the json_object instance - * @param type one of: - json_type_boolean, - json_type_double, - json_type_int, - json_type_object, - json_type_array, - json_type_string, - */ -/*extern int json_object_is_type(struct json_object *obj, enum json_type type);*/ -extern int json_object_is_type(struct json_object *obj, int type); - -/** - * Get the type of the json_object - * @param obj the json_object instance - * @returns type being one of: - json_type_boolean, - json_type_double, - json_type_int, - json_type_object, - json_type_array, - json_type_string, - */ -extern enum json_type json_object_get_type(struct json_object *obj); - - -/** Stringify object to json format - * @param obj the json_object instance - * @returns a string in JSON format - */ -extern const char* json_object_to_json_string(struct json_object *obj); - - -/* object type methods */ - -/** Create a new empty object - * @returns a json_object of type json_type_object - */ -extern struct json_object* json_object_new_object(void); - -/** Get the hashtable of a json_object of type json_type_object - * @param obj the json_object instance - * @returns a linkhash - */ -extern struct lh_table* json_object_get_object(struct json_object *obj); - -/** Add an object field to a json_object of type json_type_object - * - * The reference count will *not* be incremented. This is to make adding - * fields to objects in code more compact. If you want to retain a reference - * to an added object you must wrap the passed object with json_object_get - * - * @param obj the json_object instance - * @param key the object field name (a private copy will be duplicated) - * @param val a json_object or NULL member to associate with the given field - */ -extern void json_object_object_add(struct json_object* obj, const char *key, - struct json_object *val); - -/** Get the json_object associate with a given object field - * @param obj the json_object instance - * @param key the object field name - * @returns the json_object associated with the given field name - */ -extern struct json_object* json_object_object_get(struct json_object* obj, - const char *key); - -/** Delete the given json_object field - * - * The reference count will be decremented for the deleted object - * - * @param obj the json_object instance - * @param key the object field name - */ -extern void json_object_object_del(struct json_object* obj, const char *key); - -/** Iterate through all keys and values of an object - * @param obj the json_object instance - * @param key the local name for the char* key variable defined in the body - * @param val the local name for the json_object* object variable defined in the body - */ -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -# define json_object_object_foreach(obj,key,val) \ - char *key; struct json_object *val; \ - for(struct lh_entry *entry = json_object_get_object(obj)->head; ({ if(entry) { key = (char*)entry->k; val = (struct json_object*)entry->v; } ; entry; }); entry = entry->next ) - -#else /* ANSI C or MSC */ - -# define json_object_object_foreach(obj,key,val) \ - char *key; struct json_object *val; struct lh_entry *entry; \ - for(entry = json_object_get_object(obj)->head; (entry ? (key = (char*)entry->k, val = (struct json_object*)entry->v, entry) : 0); entry = entry->next) - -#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) */ - -/** Iterate through all keys and values of an object (ANSI C Safe) - * @param obj the json_object instance - * @param iter the object iterator - */ -#define json_object_object_foreachC(obj,iter) \ - for(iter.entry = json_object_get_object(obj)->head; (iter.entry ? (iter.key = (char*)iter.entry->k, iter.val = (struct json_object*)iter.entry->v, iter.entry) : 0); iter.entry = iter.entry->next) - -/* Array type methods */ - -/** Create a new empty json_object of type json_type_array - * @returns a json_object of type json_type_array - */ -extern struct json_object* json_object_new_array(void); - -/** Get the arraylist of a json_object of type json_type_array - * @param obj the json_object instance - * @returns an arraylist - */ -extern struct array_list* json_object_get_array(struct json_object *obj); - -/** Get the length of a json_object of type json_type_array - * @param obj the json_object instance - * @returns an int - */ -extern int json_object_array_length(struct json_object *obj); - -/** Add an element to the end of a json_object of type json_type_array - * - * The reference count will *not* be incremented. This is to make adding - * fields to objects in code more compact. If you want to retain a reference - * to an added object you must wrap the passed object with json_object_get - * - * @param obj the json_object instance - * @param val the json_object to be added - */ -extern int json_object_array_add(struct json_object *obj, - struct json_object *val); - -/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array) - * - * The reference count will *not* be incremented. This is to make adding - * fields to objects in code more compact. If you want to retain a reference - * to an added object you must wrap the passed object with json_object_get - * - * The reference count of a replaced object will be decremented. - * - * The array size will be automatically be expanded to the size of the - * index if the index is larger than the current size. - * - * @param obj the json_object instance - * @param idx the index to insert the element at - * @param val the json_object to be added - */ -extern int json_object_array_put_idx(struct json_object *obj, int idx, - struct json_object *val); - -/** Get the element at specificed index of the array (a json_object of type json_type_array) - * @param obj the json_object instance - * @param idx the index to get the element at - * @returns the json_object at the specified index (or NULL) - */ -extern struct json_object* json_object_array_get_idx(struct json_object *obj, - int idx); - -/* boolean type methods */ - -/** Create a new empty json_object of type json_type_boolean - * @param b a boolean TRUE or FALSE (0 or 1) - * @returns a json_object of type json_type_boolean - */ -extern struct json_object* json_object_new_boolean(boolean b); - -/** Get the boolean value of a json_object - * - * The type is coerced to a boolean if the passed object is not a boolean. - * integer and double objects will return FALSE if there value is zero - * or TRUE otherwise. If the passed object is a string it will return - * TRUE if it has a non zero length. If any other object type is passed - * TRUE will be returned if the object is not NULL. - * - * @param obj the json_object instance - * @returns a boolean - */ -extern boolean json_object_get_boolean(struct json_object *obj); - - -/* int type methods */ - -/** Create a new empty json_object of type json_type_int - * @param i the integer - * @returns a json_object of type json_type_int - */ -extern struct json_object* json_object_new_int(int i); - -/** Get the int value of a json_object - * - * The type is coerced to a int if the passed object is not a int. - * double objects will return their integer conversion. Strings will be - * parsed as an integer. If no conversion exists then 0 is returned. - * - * @param obj the json_object instance - * @returns an int - */ -extern int json_object_get_int(struct json_object *obj); - - -/* double type methods */ - -/** Create a new empty json_object of type json_type_double - * @param d the double - * @returns a json_object of type json_type_double - */ -extern struct json_object* json_object_new_double(double d); - -/** Get the double value of a json_object - * - * The type is coerced to a double if the passed object is not a double. - * integer objects will return their dboule conversion. Strings will be - * parsed as a double. If no conversion exists then 0.0 is returned. - * - * @param obj the json_object instance - * @returns an double - */ -extern double json_object_get_double(struct json_object *obj); - - -/* string type methods */ - -/** Create a new empty json_object of type json_type_string - * - * A copy of the string is made and the memory is managed by the json_object - * - * @param s the string - * @returns a json_object of type json_type_string - */ -extern struct json_object* json_object_new_string(const char *s); - -extern struct json_object* json_object_new_string_len(const char *s, int len); - -/** Get the string value of a json_object - * - * If the passed object is not of type json_type_string then the JSON - * representation of the object is returned. - * - * The returned string memory is managed by the json_object and will - * be freed when the reference count of the json_object drops to zero. - * - * @param obj the json_object instance - * @returns a string - */ -extern char* json_object_get_string(struct json_object *obj); - -extern void json_set_float_format(const char*f); - -#endif diff --git a/sm/lib/json-c/json_object_private.h b/sm/lib/json-c/json_object_private.h deleted file mode 100644 index 5e83e90..0000000 --- a/sm/lib/json-c/json_object_private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _json_object_private_h_ -#define _json_object_private_h_ - -#include "json_object.h" - -typedef void (json_object_delete_fn)(struct json_object *o); -typedef int (json_object_to_json_string_fn)(struct json_object *o, - struct printbuf *pb); - -struct json_object -{ - enum json_type o_type; - json_object_delete_fn *_delete; - json_object_to_json_string_fn *_to_json_string; - int _ref_count; - struct printbuf *_pb; - union data { - boolean c_boolean; - double c_double; - int c_int; - struct lh_table *c_object; - struct array_list *c_array; - char *c_string; - } o; -}; - -/* CAW: added for ANSI C iteration correctness */ -struct json_object_iter -{ - char *key; - struct json_object *val; - struct lh_entry *entry; -}; - -#endif diff --git a/sm/lib/json-c/json_tokener.c b/sm/lib/json-c/json_tokener.c deleted file mode 100644 index 3df87be..0000000 --- a/sm/lib/json-c/json_tokener.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <string.h> -#include <strings.h> - -#include "bits.h" -#include "debug.h" -#include "printbuf.h" -#include "arraylist.h" -#include "json_object.h" -#include "json_tokener.h" - - -#if !HAVE_STRNCASECMP && defined(_MSC_VER) - /* MSC has the version as _strnicmp */ -# define strncasecmp _strnicmp -#elif !HAVE_STRNCASECMP -/*# error You do not have strncasecmp on your system.*/ -#endif /* HAVE_STRNCASECMP */ - - -static const char* json_null_str = "null"; -static const char* json_true_str = "true"; -static const char* json_false_str = "false"; - -const char* json_tokener_errors[] = { - "success", - "continue", - "nesting to deep", - "unexpected end of data", - "unexpected character", - "null expected", - "boolean expected", - "number expected", - "array value separator ',' expected", - "quoted object property name expected", - "object property name separator ':' expected", - "object value separator ',' expected", - "invalid string sequence", - "expected comment", -}; - - -struct json_tokener* json_tokener_new() -{ - struct json_tokener *tok = calloc(1, sizeof(struct json_tokener)); - tok->pb = printbuf_new(); - json_tokener_reset(tok); - return tok; -} - -void json_tokener_free(struct json_tokener *tok) -{ - json_tokener_reset(tok); - if(tok) printbuf_free(tok->pb); - free(tok); -} - -static void json_tokener_reset_level(struct json_tokener *tok, int depth) -{ - tok->stack[depth].state = json_tokener_state_eatws; - tok->stack[depth].saved_state = json_tokener_state_start; - json_object_put(tok->stack[depth].current); - tok->stack[depth].current = NULL; - free(tok->stack[depth].obj_field_name); - tok->stack[depth].obj_field_name = NULL; -} - -void json_tokener_reset(struct json_tokener *tok) -{ - int i; - for(i = tok->depth; i >= 0; i--) - json_tokener_reset_level(tok, i); - tok->depth = 0; - tok->err = json_tokener_success; -} - -struct json_object* json_tokener_parse(const char *str) -{ - struct json_tokener* tok; - struct json_object* obj; - - tok = json_tokener_new(); - obj = json_tokener_parse_ex(tok, str, -1); - if(tok->err != json_tokener_success) - obj = error_ptr(-tok->err); - json_tokener_free(tok); - return obj; -} - - -/*#if !HAVE_STRNDUP*/ -/* CAW: compliant version of strndup() */ -char* json_c_strndup(const char* str, size_t n) -{ - if(str) { - size_t len = strlen(str); - size_t nn = min(len,n); - char* s = (char*)malloc(sizeof(char) * (nn + 1)); - - if(s) { - memcpy(s, str, nn); - s[nn] = '\0'; - } - - return s; - } - - return NULL; -} -/*#endif*/ - - -#define state tok->stack[tok->depth].state -#define saved_state tok->stack[tok->depth].saved_state -#define current tok->stack[tok->depth].current -#define obj_field_name tok->stack[tok->depth].obj_field_name - -struct json_object* json_tokener_parse_ex(struct json_tokener *tok, - const char *str, int len) -{ - struct json_object *obj = NULL; - char c; - - tok->char_offset = 0; - tok->err = json_tokener_success; - - do { - if(tok->char_offset == len) { - if(tok->depth == 0 && state == json_tokener_state_eatws && - saved_state == json_tokener_state_finish) - tok->err = json_tokener_success; - else - tok->err = json_tokener_continue; - goto out; - } - - c = *str; - redo_char: - switch(state) { - - case json_tokener_state_eatws: - if(isspace(c)) { - /* okay */ - } else if(c == '/') { - printbuf_reset(tok->pb); - printbuf_memappend(tok->pb, &c, 1); - state = json_tokener_state_comment_start; - } else { - state = saved_state; - goto redo_char; - } - break; - - case json_tokener_state_start: - switch(c) { - case '{': - state = json_tokener_state_eatws; - saved_state = json_tokener_state_object_field_start; - current = json_object_new_object(); - break; - case '[': - state = json_tokener_state_eatws; - saved_state = json_tokener_state_array; - current = json_object_new_array(); - break; - case 'N': - case 'n': - state = json_tokener_state_null; - printbuf_reset(tok->pb); - tok->st_pos = 0; - goto redo_char; - case '"': - case '\'': - state = json_tokener_state_string; - printbuf_reset(tok->pb); - tok->quote_char = c; - break; - case 'T': - case 't': - case 'F': - case 'f': - state = json_tokener_state_boolean; - printbuf_reset(tok->pb); - tok->st_pos = 0; - goto redo_char; -#if 0 /*defined(__GNUC__)*/ - case '0' ... '9': -#else - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': -#endif - case '-': - state = json_tokener_state_number; - printbuf_reset(tok->pb); - tok->is_double = 0; - goto redo_char; - default: - tok->err = json_tokener_error_parse_unexpected; - goto out; - } - break; - - case json_tokener_state_finish: - if(tok->depth == 0) goto out; - obj = json_object_get(current); - json_tokener_reset_level(tok, tok->depth); - tok->depth--; - goto redo_char; - - case json_tokener_state_null: - printbuf_memappend(tok->pb, &c, 1); - if(strncasecmp(json_null_str, tok->pb->buf, - min( (size_t) (tok->st_pos+1), strlen(json_null_str))) == 0) { - if( ((size_t) tok->st_pos) == strlen(json_null_str)) { - current = NULL; - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - } else { - tok->err = json_tokener_error_parse_null; - goto out; - } - tok->st_pos++; - break; - - case json_tokener_state_comment_start: - if(c == '*') { - state = json_tokener_state_comment; - } else if(c == '/') { - state = json_tokener_state_comment_eol; - } else { - tok->err = json_tokener_error_parse_comment; - goto out; - } - printbuf_memappend(tok->pb, &c, 1); - break; - - case json_tokener_state_comment: - if(c == '*') state = json_tokener_state_comment_end; - printbuf_memappend(tok->pb, &c, 1); - break; - - case json_tokener_state_comment_eol: - if(c == '\n') { - mc_debug("json_tokener_comment: %s\n", tok->pb->buf); - state = json_tokener_state_eatws; - } else { - printbuf_memappend(tok->pb, &c, 1); - } - break; - - case json_tokener_state_comment_end: - printbuf_memappend(tok->pb, &c, 1); - if(c == '/') { - mc_debug("json_tokener_comment: %s\n", tok->pb->buf); - state = json_tokener_state_eatws; - } else { - state = json_tokener_state_comment; - } - break; - - case json_tokener_state_string: - if(c == tok->quote_char) { - current = json_object_new_string(tok->pb->buf); - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if(c == '\\') { - saved_state = json_tokener_state_string; - state = json_tokener_state_string_escape; - } else { - printbuf_memappend(tok->pb, &c, 1); - } - break; - - case json_tokener_state_string_escape: - switch(c) { - case '"': - case '\\': - case '/': - printbuf_memappend(tok->pb, &c, 1); - state = saved_state; - break; - case 'b': - case 'n': - case 'r': - case 't': - if(c == 'b') printbuf_memappend(tok->pb, "\b", 1); - else if(c == 'n') printbuf_memappend(tok->pb, "\n", 1); - else if(c == 'r') printbuf_memappend(tok->pb, "\r", 1); - else if(c == 't') printbuf_memappend(tok->pb, "\t", 1); - state = saved_state; - break; - case 'u': - tok->ucs_char = 0; - tok->st_pos = 0; - state = json_tokener_state_escape_unicode; - break; - default: - tok->err = json_tokener_error_parse_string; - goto out; - } - break; - - case json_tokener_state_escape_unicode: - if(strchr(json_hex_chars, c)) { - tok->ucs_char += ((unsigned int)hexdigit(c) << ((3-tok->st_pos++)*4)); - if(tok->st_pos == 4) { - unsigned char utf_out[3]; - if (tok->ucs_char < 0x80) { - utf_out[0] = tok->ucs_char; - printbuf_memappend(tok->pb, (char*)utf_out, 1); - } else if (tok->ucs_char < 0x800) { - utf_out[0] = 0xc0 | (tok->ucs_char >> 6); - utf_out[1] = 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend(tok->pb, (char*)utf_out, 2); - } else { - utf_out[0] = 0xe0 | (tok->ucs_char >> 12); - utf_out[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f); - utf_out[2] = 0x80 | (tok->ucs_char & 0x3f); - printbuf_memappend(tok->pb, (char*)utf_out, 3); - } - state = saved_state; - } - } else { - tok->err = json_tokener_error_parse_string; - goto out; - } - break; - - case json_tokener_state_boolean: - printbuf_memappend(tok->pb, &c, 1); - if(strncasecmp(json_true_str, tok->pb->buf, - min( (size_t)(tok->st_pos+1), strlen(json_true_str))) == 0) { - if(((size_t) tok->st_pos) == strlen(json_true_str)) { - current = json_object_new_boolean(1); - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - } else if(strncasecmp(json_false_str, tok->pb->buf, - min((size_t)(tok->st_pos+1), strlen(json_false_str))) == 0) { - if(( (size_t) tok->st_pos) == strlen(json_false_str)) { - current = json_object_new_boolean(0); - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - } else { - tok->err = json_tokener_error_parse_boolean; - goto out; - } - tok->st_pos++; - break; - - case json_tokener_state_number: - if(c && strchr(json_number_chars, c)) { - printbuf_memappend(tok->pb, &c, 1); - if(c == '.' || c == 'e') tok->is_double = 1; - } else { - int numi; - double numd; - if(!tok->is_double && sscanf(tok->pb->buf, "%d", &numi) == 1) { - current = json_object_new_int(numi); - } else if(tok->is_double && sscanf(tok->pb->buf, "%lf", &numd) == 1) { - current = json_object_new_double(numd); - } else { - tok->err = json_tokener_error_parse_number; - goto out; - } - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - goto redo_char; - } - break; - - case json_tokener_state_array: - if(c == ']') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else { - if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) { - tok->err = json_tokener_error_depth; - goto out; - } - state = json_tokener_state_array_add; - tok->depth++; - json_tokener_reset_level(tok, tok->depth); - goto redo_char; - } - break; - - case json_tokener_state_array_add: - json_object_array_add(current, obj); - saved_state = json_tokener_state_array_sep; - state = json_tokener_state_eatws; - goto redo_char; - - case json_tokener_state_array_sep: - if(c == ']') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if(c == ',') { - saved_state = json_tokener_state_array; - state = json_tokener_state_eatws; - } else { - tok->err = json_tokener_error_parse_array; - goto out; - } - break; - - case json_tokener_state_object_field_start: - if(c == '}') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if (c == '"' || c == '\'') { - tok->quote_char = c; - printbuf_reset(tok->pb); - state = json_tokener_state_object_field; - } else { - tok->err = json_tokener_error_parse_object_key_name; - goto out; - } - break; - - case json_tokener_state_object_field: - if(c == tok->quote_char) { - obj_field_name = strdup(tok->pb->buf); - saved_state = json_tokener_state_object_field_end; - state = json_tokener_state_eatws; - } else if(c == '\\') { - saved_state = json_tokener_state_object_field; - state = json_tokener_state_string_escape; - } else { - printbuf_memappend(tok->pb, &c, 1); - } - break; - - case json_tokener_state_object_field_end: - if(c == ':') { - saved_state = json_tokener_state_object_value; - state = json_tokener_state_eatws; - } else { - tok->err = json_tokener_error_parse_object_key_sep; - goto out; - } - break; - - case json_tokener_state_object_value: - if(tok->depth >= JSON_TOKENER_MAX_DEPTH-1) { - tok->err = json_tokener_error_depth; - goto out; - } - state = json_tokener_state_object_value_add; - tok->depth++; - json_tokener_reset_level(tok, tok->depth); - goto redo_char; - - case json_tokener_state_object_value_add: - json_object_object_add(current, obj_field_name, obj); - free(obj_field_name); - obj_field_name = NULL; - saved_state = json_tokener_state_object_sep; - state = json_tokener_state_eatws; - goto redo_char; - - case json_tokener_state_object_sep: - if(c == '}') { - saved_state = json_tokener_state_finish; - state = json_tokener_state_eatws; - } else if(c == ',') { - saved_state = json_tokener_state_object_field_start; - state = json_tokener_state_eatws; - } else { - tok->err = json_tokener_error_parse_object_value_sep; - goto out; - } - break; - - } - str++; - tok->char_offset++; - } while(c); - - if(state != json_tokener_state_finish && - saved_state != json_tokener_state_finish) - tok->err = json_tokener_error_parse_eof; - - out: - if(tok->err == json_tokener_success) return json_object_get(current); - mc_debug("json_tokener_parse_ex: error %s at offset %d\n", - json_tokener_errors[tok->err], tok->char_offset); - return NULL; -} diff --git a/sm/lib/json-c/json_tokener.h b/sm/lib/json-c/json_tokener.h deleted file mode 100644 index 32330af..0000000 --- a/sm/lib/json-c/json_tokener.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _json_tokener_h_ -#define _json_tokener_h_ - -#include "json_object.h" - -enum json_tokener_error { - json_tokener_success, - json_tokener_continue, - json_tokener_error_depth, - json_tokener_error_parse_eof, - json_tokener_error_parse_unexpected, - json_tokener_error_parse_null, - json_tokener_error_parse_boolean, - json_tokener_error_parse_number, - json_tokener_error_parse_array, - json_tokener_error_parse_object_key_name, - json_tokener_error_parse_object_key_sep, - json_tokener_error_parse_object_value_sep, - json_tokener_error_parse_string, - json_tokener_error_parse_comment -}; - -enum json_tokener_state { - json_tokener_state_eatws, - json_tokener_state_start, - json_tokener_state_finish, - json_tokener_state_null, - json_tokener_state_comment_start, - json_tokener_state_comment, - json_tokener_state_comment_eol, - json_tokener_state_comment_end, - json_tokener_state_string, - json_tokener_state_string_escape, - json_tokener_state_escape_unicode, - json_tokener_state_boolean, - json_tokener_state_number, - json_tokener_state_array, - json_tokener_state_array_add, - json_tokener_state_array_sep, - json_tokener_state_object_field_start, - json_tokener_state_object_field, - json_tokener_state_object_field_end, - json_tokener_state_object_value, - json_tokener_state_object_value_add, - json_tokener_state_object_sep -}; - -struct json_tokener_srec -{ - enum json_tokener_state state, saved_state; - struct json_object *obj; - struct json_object *current; - char *obj_field_name; -}; - -#define JSON_TOKENER_MAX_DEPTH 32 - -struct json_tokener -{ - char *str; - struct printbuf *pb; - int depth, is_double, st_pos, char_offset; - enum json_tokener_error err; - unsigned int ucs_char; - char quote_char; - struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH]; -}; - -extern const char* json_tokener_errors[]; - -extern struct json_tokener* json_tokener_new(void); -extern void json_tokener_free(struct json_tokener *tok); -extern void json_tokener_reset(struct json_tokener *tok); -extern struct json_object* json_tokener_parse(const char *str); -extern struct json_object* json_tokener_parse_ex(struct json_tokener *tok, - const char *str, int len); - -#endif diff --git a/sm/lib/json-c/json_util.c b/sm/lib/json-c/json_util.c deleted file mode 100644 index e20be24..0000000 --- a/sm/lib/json-c/json_util.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <errno.h> - -#if HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif /* HAVE_SYS_TYPES_H */ - -#if HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif /* HAVE_SYS_STAT_H */ - -#if HAVE_FCNTL_H -#include <fcntl.h> -#endif /* HAVE_FCNTL_H */ - -#if HAVE_UNISTD_H -# include <unistd.h> -#endif /* HAVE_UNISTD_H */ - -#ifdef WIN32 -# define WIN32_LEAN_AND_MEAN -# include <windows.h> -# include <io.h> -#endif /* defined(WIN32) */ - -#if !HAVE_OPEN && defined(WIN32) -# define open _open -#endif - - -#include "bits.h" -#include "debug.h" -#include "printbuf.h" -#include "json_object.h" -#include "json_tokener.h" -#include "json_util.h" - -struct json_object* json_object_from_file(char *filename) -{ - struct printbuf *pb; - struct json_object *obj; - char buf[JSON_FILE_BUF_SIZE]; - int fd, ret; - - if((fd = open(filename, O_RDONLY)) < 0) { - mc_error("json_object_from_file: error reading file %s: %s\n", - filename, strerror(errno)); - return error_ptr(-1); - } - if(!(pb = printbuf_new())) { - mc_error("json_object_from_file: printbuf_new failed\n"); - return error_ptr(-1); - } - while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) { - printbuf_memappend(pb, buf, ret); - } - close(fd); - if(ret < 0) { - mc_abort("json_object_from_file: error reading file %s: %s\n", - filename, strerror(errno)); - printbuf_free(pb); - return error_ptr(-1); - } - obj = json_tokener_parse(pb->buf); - printbuf_free(pb); - return obj; -} - -int json_object_to_file(char *filename, struct json_object *obj) -{ - char *json_str; - int fd, ret; - unsigned int wpos, wsize; - - if(!obj) { - mc_error("json_object_to_file: object is null\n"); - return -1; - } - - if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { - mc_error("json_object_to_file: error opening file %s: %s\n", - filename, strerror(errno)); - return -1; - } - - if(!(json_str = json_object_to_json_string(obj))) { return -1; } - - - wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ - wpos = 0; - while(wpos < wsize) { - if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { - close(fd); - mc_error("json_object_to_file: error writing file %s: %s\n", - filename, strerror(errno)); - return -1; - } - - /* because of the above check for ret < 0, we can safely cast and add */ - wpos += (unsigned int)ret; - } - - close(fd); - return 0; -} diff --git a/sm/lib/json-c/json_util.h b/sm/lib/json-c/json_util.h deleted file mode 100644 index 30fe2ab..0000000 --- a/sm/lib/json-c/json_util.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _json_util_h_ -#define _json_util_h_ - -#include "json_object.h" - -#define JSON_FILE_BUF_SIZE 4096 - -/* utlitiy functions */ -extern struct json_object* json_object_from_file(char *filename); -extern int json_object_to_file(char *filename, struct json_object *obj); - -#endif diff --git a/sm/lib/json-c/linkhash.c b/sm/lib/json-c/linkhash.c deleted file mode 100644 index 9227356..0000000 --- a/sm/lib/json-c/linkhash.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * $Id: linkhash.c,v 1.4 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include "config.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> -#include <stddef.h> -#include <limits.h> - -#include "linkhash.h" - -void lh_abort(const char *msg, ...) -{ - va_list ap; - va_start(ap, msg); - vprintf(msg, ap); - exit(1); -} - -unsigned long lh_ptr_hash(void *k) -{ - /* CAW: refactored to be 64bit nice */ - return (unsigned long)((((ptrdiff_t)k * LH_PRIME) >> 4) & ULONG_MAX); -} - -int lh_ptr_equal(void *k1, void *k2) -{ - return (k1 == k2); -} - -unsigned long lh_char_hash(void *k) -{ - unsigned int h = 0; - const char* data = k; - - while( *data!=0 ) h = h*129 + (unsigned int)(*data++) + LH_PRIME; - - return h; -} - -int lh_char_equal(void *k1, void *k2) -{ - return (strcmp((char*)k1, (char*)k2) == 0); -} - -struct lh_table* lh_table_new(int size, char *name, - lh_entry_free_fn *free_fn, - lh_hash_fn *hash_fn, - lh_equal_fn *equal_fn) -{ - int i; - struct lh_table *t; - - t = calloc(1, sizeof(struct lh_table)); - if(!t) lh_abort("lh_table_new: calloc failed\n"); - t->count = 0; - t->size = size; - t->name = name; - t->table = calloc( (size_t) size,sizeof(struct lh_entry)); - if(!t->table) lh_abort("lh_table_new: calloc failed\n"); - t->free_fn = free_fn; - t->hash_fn = hash_fn; - t->equal_fn = equal_fn; - for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY; - return t; -} - -struct lh_table* lh_kchar_table_new(int size, char *name, - lh_entry_free_fn *free_fn) -{ - return lh_table_new(size, name, free_fn, lh_char_hash, lh_char_equal); -} - -struct lh_table* lh_kptr_table_new(int size, char *name, - lh_entry_free_fn *free_fn) -{ - return lh_table_new(size, name, free_fn, lh_ptr_hash, lh_ptr_equal); -} - -void lh_table_resize(struct lh_table *t, int new_size) -{ - struct lh_table *new_t; - struct lh_entry *ent; - - new_t = lh_table_new(new_size, t->name, NULL, t->hash_fn, t->equal_fn); - ent = t->head; - while(ent) { - lh_table_insert(new_t, ent->k, ent->v); - ent = ent->next; - } - free(t->table); - t->table = new_t->table; - t->size = new_size; - t->head = new_t->head; - t->tail = new_t->tail; - t->resizes++; - free(new_t); -} - -void lh_table_free(struct lh_table *t) -{ - struct lh_entry *c; - for(c = t->head; c != NULL; c = c->next) { - if(t->free_fn) { - t->free_fn(c); - } - } - free(t->table); - free(t); -} - - -int lh_table_insert(struct lh_table *t, void *k, void *v) -{ - unsigned long h, n; - - t->inserts++; - if(t->count > t->size * 0.66) lh_table_resize(t, t->size * 2); - - h = t->hash_fn(k); - n = h % t->size; - - while( 1 ) { - if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break; - t->collisions++; - if(++n == (size_t) t->size) n = 0; - } - - t->table[n].k = k; - t->table[n].v = v; - t->count++; - - if(t->head == NULL) { - t->head = t->tail = &t->table[n]; - t->table[n].next = t->table[n].prev = NULL; - } else { - t->tail->next = &t->table[n]; - t->table[n].prev = t->tail; - t->table[n].next = NULL; - t->tail = &t->table[n]; - } - - return 0; -} - - -struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k) -{ - unsigned long h = t->hash_fn(k); - unsigned long n = h % t->size; - - t->lookups++; - while( 1 ) { - if(t->table[n].k == LH_EMPTY) return NULL; - if(t->table[n].k != LH_FREED && - t->equal_fn(t->table[n].k, k)) return &t->table[n]; - if(++n == (size_t) t->size) n = 0; - } - return NULL; -} - - -void* lh_table_lookup(struct lh_table *t, void *k) -{ - struct lh_entry *e = lh_table_lookup_entry(t, k); - if(e) return e->v; - return NULL; -} - - -int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) -{ - ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ - - /* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */ - if(n < 0) { return -2; } - - if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1; - t->count--; - if(t->free_fn) t->free_fn(e); - t->table[n].v = NULL; - t->table[n].k = LH_FREED; - if(t->tail == &t->table[n] && t->head == &t->table[n]) { - t->head = t->tail = NULL; - } else if (t->head == &t->table[n]) { - t->head->next->prev = NULL; - t->head = t->head->next; - } else if (t->tail == &t->table[n]) { - t->tail->prev->next = NULL; - t->tail = t->tail->prev; - } else { - t->table[n].prev->next = t->table[n].next; - t->table[n].next->prev = t->table[n].prev; - } - t->table[n].next = t->table[n].prev = NULL; - return 0; -} - - -int lh_table_delete(struct lh_table *t, void *k) -{ - struct lh_entry *e = lh_table_lookup_entry(t, k); - if(!e) return -1; - return lh_table_delete_entry(t, e); -} - diff --git a/sm/lib/json-c/linkhash.h b/sm/lib/json-c/linkhash.h deleted file mode 100644 index 5c9fa85..0000000 --- a/sm/lib/json-c/linkhash.h +++ /dev/null @@ -1,261 +0,0 @@ -/* - * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _linkhash_h_ -#define _linkhash_h_ - -/** - * golden prime used in hash functions - */ -#define LH_PRIME 0x9e370001UL - -/** - * sentinel pointer value for empty slots - */ -#define LH_EMPTY (void*)-1 - -/** - * sentinel pointer value for freed slots - */ -#define LH_FREED (void*)-2 - -struct lh_entry; - -/** - * callback function prototypes - */ -typedef void (lh_entry_free_fn) (struct lh_entry *e); -/** - * callback function prototypes - */ -typedef unsigned long (lh_hash_fn) (void *k); -/** - * callback function prototypes - */ -typedef int (lh_equal_fn) (void *k1, void *k2); - -/** - * An entry in the hash table - */ -struct lh_entry { - /** - * The key. - */ - void *k; - /** - * The value. - */ - void *v; - /** - * The next entry - */ - struct lh_entry *next; - /** - * The previous entry. - */ - struct lh_entry *prev; -}; - - -/** - * The hash table structure. - */ -struct lh_table { - /** - * Size of our hash. - */ - int size; - /** - * Numbers of entries. - */ - int count; - - /** - * Number of collisions. - */ - int collisions; - - /** - * Number of resizes. - */ - int resizes; - - /** - * Number of lookups. - */ - int lookups; - - /** - * Number of inserts. - */ - int inserts; - - /** - * Number of deletes. - */ - int deletes; - - /** - * Name of the hash table. - */ - char *name; - - /** - * The first entry. - */ - struct lh_entry *head; - - /** - * The last entry. - */ - struct lh_entry *tail; - - struct lh_entry *table; - - /** - * A pointer onto the function responsible for freeing an entry. - */ - lh_entry_free_fn *free_fn; - lh_hash_fn *hash_fn; - lh_equal_fn *equal_fn; -}; - - -/** - * Pre-defined hash and equality functions - */ -extern unsigned long lh_ptr_hash(void *k); -extern int lh_ptr_equal(void *k1, void *k2); - -extern unsigned long lh_char_hash(void *k); -extern int lh_char_equal(void *k1, void *k2); - - -/** - * Convenience list iterator. - */ -#define lh_foreach(table, entry) \ -for(entry = table->head; entry; entry = entry->next) - -/** - * lh_foreach_safe allows calling of deletion routine while iterating. - */ -#define lh_foreach_safe(table, entry, tmp) \ -for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp) - - - -/** - * Create a new linkhash table. - * @param size initial table size. The table is automatically resized - * although this incurs a performance penalty. - * @param name the table name. - * @param free_fn callback function used to free memory for entries - * when lh_table_free or lh_table_delete is called. - * If NULL is provided, then memory for keys and values - * must be freed by the caller. - * @param hash_fn function used to hash keys. 2 standard ones are defined: - * lh_ptr_hash and lh_char_hash for hashing pointer values - * and C strings respectively. - * @param equal_fn comparison function to compare keys. 2 standard ones defined: - * lh_ptr_hash and lh_char_hash for comparing pointer values - * and C strings respectively. - * @return a pointer onto the linkhash table. - */ -extern struct lh_table* lh_table_new(int size, char *name, - lh_entry_free_fn *free_fn, - lh_hash_fn *hash_fn, - lh_equal_fn *equal_fn); - -/** - * Convenience function to create a new linkhash - * table with char keys. - * @param size initial table size. - * @param name table name. - * @param free_fn callback function used to free memory for entries. - * @return a pointer onto the linkhash table. - */ -extern struct lh_table* lh_kchar_table_new(int size, char *name, - lh_entry_free_fn *free_fn); - - -/** - * Convenience function to create a new linkhash - * table with ptr keys. - * @param size initial table size. - * @param name table name. - * @param free_fn callback function used to free memory for entries. - * @return a pointer onto the linkhash table. - */ -extern struct lh_table* lh_kptr_table_new(int size, char *name, - lh_entry_free_fn *free_fn); - - -/** - * Free a linkhash table. - * If a callback free function is provided then it is called for all - * entries in the table. - * @param t table to free. - */ -extern void lh_table_free(struct lh_table *t); - - -/** - * Insert a record into the table. - * @param t the table to insert into. - * @param k a pointer to the key to insert. - * @param v a pointer to the value to insert. - */ -extern int lh_table_insert(struct lh_table *t, void *k, void *v); - - -/** - * Lookup a record into the table. - * @param t the table to lookup - * @param k a pointer to the key to lookup - * @return a pointer to the record structure of the value or NULL if it does not exist. - */ -extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, void *k); - -/** - * Lookup a record into the table - * @param t the table to lookup - * @param k a pointer to the key to lookup - * @return a pointer to the found value or NULL if it does not exist. - */ -extern void* lh_table_lookup(struct lh_table *t, void *k); - - -/** - * Delete a record from the table. - * If a callback free function is provided then it is called for the - * for the item being deleted. - * @param t the table to delete from. - * @param e a pointer to the entry to delete. - * @return 0 if the item was deleted. - * @return -1 if it was not found. - */ -extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e); - - -/** - * Delete a record from the table. - * If a callback free function is provided then it is called for the - * for the item being deleted. - * @param t the table to delete from. - * @param k a pointer to the key to delete. - * @return 0 if the item was deleted. - * @return -1 if it was not found. - */ -extern int lh_table_delete(struct lh_table *t, void *k); - - -#endif diff --git a/sm/lib/json-c/printbuf.c b/sm/lib/json-c/printbuf.c deleted file mode 100644 index 1449577..0000000 --- a/sm/lib/json-c/printbuf.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if HAVE_STDARG_H -# include <stdarg.h> -#else /* !HAVE_STDARG_H */ -# error Not enough var arg support! -#endif /* HAVE_STDARG_H */ - -#include "bits.h" -#include "debug.h" -#include "printbuf.h" - -struct printbuf* printbuf_new() -{ - struct printbuf *p; - - if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL; - p->size = 32; - p->bpos = 0; - if(!(p->buf = malloc( (size_t) p->size))) { - free(p); - return NULL; - } - return p; -} - - -int printbuf_memappend(struct printbuf *p, const char *buf, int size) -{ - char *t; - if(p->size - p->bpos <= size) { - int new_size = max(p->size * 2, p->bpos + size + 8); -#ifdef PRINTBUF_DEBUG - mc_debug("printbuf_memappend: realloc " - "bpos=%d wrsize=%d old_size=%d new_size=%d\n", - p->bpos, size, p->size, new_size); -#endif /* PRINTBUF_DEBUG */ - if(!(t = realloc(p->buf, (size_t) new_size))) return -1; - p->size = new_size; - p->buf = t; - } - memcpy(p->buf + p->bpos, buf, (size_t) size); - p->bpos += size; - p->buf[p->bpos]= '\0'; - return size; -} - -#if !HAVE_VSNPRINTF && defined(WIN32) -# define vsnprintf _vsnprintf -#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */ -# error Need vsnprintf! -#endif /* !HAVE_VSNPRINTF && defined(WIN32) */ - -#if !HAVE_VASPRINTF -/* CAW: compliant version of vasprintf */ -static int vasprintf(char **buf, const char *fmt, va_list ap) -{ -#ifndef WIN32 - static char _T_emptybuffer = '\0'; -#endif /* !defined(WIN32) */ - int chars; - char *b; - - if(!buf) { return -1; } - -#ifdef WIN32 - chars = _vscprintf(fmt, ap)+1; -#else /* !defined(WIN32) */ - /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite - our buffer like on some 64bit sun systems.... but hey, its time to move on */ - chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1; - if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */ -#endif /* defined(WIN32) */ - - b = (char*)malloc(sizeof(char)*chars); - if(!b) { return -1; } - - if((chars = vsprintf(b, fmt, ap)) < 0) - { - free(b); - } else { - *buf = b; - } - - return chars; -} -#endif /* !HAVE_VASPRINTF */ - -int sprintbuf(struct printbuf *p, const char *msg, ...) -{ - va_list ap; - char *t; - int size; - char buf[128]; - - /* user stack buffer first */ - va_start(ap, msg); - size = vsnprintf(buf, 128, msg, ap); - va_end(ap); - /* if string is greater than stack buffer, then use dynamic string - with vasprintf. Note: some implementation of vsnprintf return -1 - if output is truncated whereas some return the number of bytes that - would have been writen - this code handles both cases. */ - if(size == -1 || size > 127) { - int ret; - va_start(ap, msg); - if((size = vasprintf(&t, msg, ap)) == -1) return -1; - va_end(ap); - ret = printbuf_memappend(p, t, size); - free(t); - return ret; - } else { - return printbuf_memappend(p, buf, size); - } -} - -void printbuf_reset(struct printbuf *p) -{ - p->buf[0] = '\0'; - p->bpos = 0; -} - -void printbuf_free(struct printbuf *p) -{ - if(p) { - free(p->buf); - free(p); - } -} diff --git a/sm/lib/json-c/printbuf.h b/sm/lib/json-c/printbuf.h deleted file mode 100644 index 95f7a24..0000000 --- a/sm/lib/json-c/printbuf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * $Id: printbuf.h,v 1.4 2006/01/26 02:16:28 mclark Exp $ - * - * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd. - * Michael Clark <michael@metaparadigm.com> - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the MIT license. See COPYING for details. - * - */ - -#ifndef _printbuf_h_ -#define _printbuf_h_ - -#undef PRINTBUF_DEBUG - -struct printbuf { - char *buf; - int bpos; - int size; -}; - -extern struct printbuf* -printbuf_new(void); - -extern int -printbuf_memappend(struct printbuf *p, const char *buf, int size); - -extern int -sprintbuf(struct printbuf *p, const char *msg, ...); - -extern void -printbuf_reset(struct printbuf *p); - -extern void -printbuf_free(struct printbuf *p); - -#endif diff --git a/sm/lib/json-c/test1.c b/sm/lib/json-c/test1.c deleted file mode 100644 index b6174c3..0000000 --- a/sm/lib/json-c/test1.c +++ /dev/null @@ -1,181 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "json.h" - -int main(int argc, char **argv) -{ - argc = 0; argv = 0; - struct json_tokener *tok; - struct json_object *my_string, *my_int, *my_object, *my_array; - struct json_object *new_obj; - int i; - - mc_set_debug(2); - - my_string = json_object_new_string("\t"); - printf("my_string=%s\n", json_object_get_string(my_string)); - printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); - json_object_put(my_string); - - my_string = json_object_new_string("\\"); - printf("my_string=%s\n", json_object_get_string(my_string)); - printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); - json_object_put(my_string); - - my_string = json_object_new_string("foo"); - printf("my_string=%s\n", json_object_get_string(my_string)); - printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string)); - - my_int = json_object_new_int(9); - printf("my_int=%d\n", json_object_get_int(my_int)); - printf("my_int.to_string()=%s\n", json_object_to_json_string(my_int)); - - my_array = json_object_new_array(); - json_object_array_add(my_array, json_object_new_int(1)); - json_object_array_add(my_array, json_object_new_int(2)); - json_object_array_add(my_array, json_object_new_int(3)); - json_object_array_put_idx(my_array, 4, json_object_new_int(5)); - printf("my_array=\n"); - for(i=0; i < json_object_array_length(my_array); i++) { - struct json_object *obj = json_object_array_get_idx(my_array, i); - printf("\t[%d]=%s\n", i, json_object_to_json_string(obj)); - } - printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array)); - - my_object = json_object_new_object(); - json_object_object_add(my_object, "abc", json_object_new_int(12)); - json_object_object_add(my_object, "foo", json_object_new_string("bar")); - json_object_object_add(my_object, "bool0", json_object_new_boolean(0)); - json_object_object_add(my_object, "bool1", json_object_new_boolean(1)); - json_object_object_add(my_object, "baz", json_object_new_string("bang")); - json_object_object_add(my_object, "baz", json_object_new_string("fark")); - json_object_object_del(my_object, "baz"); - json_object_object_add(my_object, "arr", my_array); - printf("my_object=\n"); - /*json_object_object_foreach(my_object, key, val) { - printf("\t%s: %s\n", key, json_object_to_json_string(val)); - }*/ - printf("my_object.to_string()=%s\n", json_object_to_json_string(my_object)); - - new_obj = json_tokener_parse("\"\003\""); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("/* hello */\"foo\""); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("// hello\n\"foo\""); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\""); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("null"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("True"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("12"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("12.3"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("[\"\\n\"]"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("[\"\\nabc\\n\"]"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("[null]"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("[]"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("[false]"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("{}"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("{ \"foo\": \"bar\" }"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - new_obj = json_tokener_parse("{ foo }"); - if(is_error(new_obj)) printf("got error as expected\n"); - - new_obj = json_tokener_parse("foo"); - if(is_error(new_obj)) printf("got error as expected\n"); - - new_obj = json_tokener_parse("{ \"foo"); - if(is_error(new_obj)) printf("got error as expected\n"); - - /* test incremental parsing */ - -printf("Hello\n"); - tok = json_tokener_new(); - new_obj = json_tokener_parse_ex(tok, "{ \"foo", 6); - if(is_error(new_obj)) printf("got error as expected\n"); - new_obj = json_tokener_parse_ex(tok, "\": {\"bar", 8); - if(is_error(new_obj)) printf("got error as expected\n"); - new_obj = json_tokener_parse_ex(tok, "\":13}}", 6); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - json_tokener_free(tok); - - json_object_put(my_string); - json_object_put(my_int); - json_object_put(my_object); - /*json_object_put(my_array);*/ - - { - struct json_object *laser = json_object_new_object(); - struct json_object *my_array = json_object_new_array(); - int i; for(i=0;i<20;i++) { - json_object_array_add(my_array, - i%5 > 0 ? json_object_new_double((double)i) : - json_tokener_parse("null") - ); - } - json_object_object_add(laser, "readings", my_array); - - printf("new_obj.to_string()=%s\n", json_object_to_json_string(laser)); - json_object_put(laser); -} - - return 0; -} diff --git a/sm/lib/json-c/test2.c b/sm/lib/json-c/test2.c deleted file mode 100644 index 68cd81f..0000000 --- a/sm/lib/json-c/test2.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "json.h" - - -int main(int argc, char **argv) -{ - argc = 0; argv = (char**)0; - struct json_object *new_obj; - - mc_set_debug(1); - - new_obj = json_tokener_parse("/* more difficult test case */ { \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", \"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\": \"A meta-markup language, used to create markup languages such as DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }"); - printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); - json_object_put(new_obj); - - return 0; -} diff --git a/sm/lib/options/CMakeLists.txt b/sm/lib/options/CMakeLists.txt deleted file mode 100644 index 4292eb4..0000000 --- a/sm/lib/options/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -SET(options_sources options.c options_interface.c ) -ADD_LIBRARY(options STATIC ${options_sources}) - -ADD_EXECUTABLE(test_options test_options.c) -TARGET_LINK_LIBRARIES(test_options options) - - -# installation - -FILE(GLOB headers "*.h") -INSTALL(FILES ${headers} DESTINATION include/options) -INSTALL(TARGETS options ARCHIVE DESTINATION lib) diff --git a/sm/lib/options/ruby/options.rb b/sm/lib/options/ruby/options.rb deleted file mode 100644 index 604e208..0000000 --- a/sm/lib/options/ruby/options.rb +++ /dev/null @@ -1,143 +0,0 @@ - -require 'ostruct' -require 'optparse' - -class Options - Option = Struct.new(:name, :default, :description, :value) - - def initialize - @hash = {} - @order = [] - end - - def add(name, default, description) - if name.class == String - name = name.to_sym - end - if name.class != Symbol - raise "This: #{name.inspect} should be a String or Symbol" - end - - @hash[name] = Option.new(name, default, description, nil) - @order.push @hash[name] - end - - def add_required(name, description) - add(name, nil, description) - end - - - def populate(opts) - - opts.on("--help", "shows help") do - $stderr.puts opts.help - exit 0 - end - - opts.on("--config FILE", "Load config from file") do |file| - load_config_from_file(file) - end - - opts.on("--config_dump", "Dump config on stdout") do - $stdout.puts self.config_dump - exit 0 - end - - @order.each do |o| - s = o.default.inspect.ljust(25) - opts.on("--#{o.name} VALUE", "#{s} #{o.description}") do |s| - value = s - begin value = eval(s) - rescue SyntaxError => ex - rescue => ex - end - - @hash[o.name].value = value - end - end - - end - - # Create an ostruct from the data - def get_ostruct - r = {} - @hash.each do |k, v| - r[k] = v.value || v.default - end - OpenStruct.new r - end - - # Warn if some required parameter was not set - # (default and value are nil) - def warn_required - res = false - @order.each do |v| - if v.value.nil? && v.default.nil? - $stderr.puts "Required option '#{v.name}' not set." - res = true - end - end - res - end - - def config_dump - s = "" - max_size = @hash.keys.map{|x|x.to_s.size}.max + 2 - for o in @order - s += o.name.to_s.ljust(max_size) + (o.value || o.default).inspect + "\n" - end - s - end - - RegComment = /^\s*\#/ - RegOption = /^\s*(\w+)\s*=?\s*(.+)$/ - RegLoad = /^\s*(?:<|source)\s*(.*)$/ - - def load_config_from_file(file) - load_config_from_string(File.open(file).read, File.dirname(file)) - end - - def load_config_from_string(string, dir) - string.split("\n").each do |line| - next if (line.strip.size == 0) || line =~ RegComment - if m = RegLoad.match(line) - filename = m[1] - filename = File.expand_path(File.join(dir, filename)) - load_config_from_file(filename) - elsif m = RegOption.match(line) - name = m[1].to_sym - value = m[2].strip - - begin - value = eval(value) - rescue ScriptError,StandardError - end - - if o = @hash[name] - o.value = value -# $stderr.puts "#{name} = #{value}" - else - $stderr.puts "Unknown key #{name.inspect} (#{@hash.keys.inspect})" - end - else - $stderr.puts "Line #{line.inspect} is malformed" - exit -1 - end - end - end - - def parse_cmd_line! - opt = OptionParser.new do |opts| - self.populate(opts) - end - - begin opt.parse! - rescue OptionParser::InvalidOption=>e - $stderr.puts e - $stderr.puts opt - exit -1 - end - end - - -end \ No newline at end of file diff --git a/sm/lib/options/test_options.c b/sm/lib/options/test_options.c deleted file mode 100644 index 1e9e315..0000000 --- a/sm/lib/options/test_options.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "options.h" - - - -struct params { - int a_int; - double a_double; - const char * file; - int algo; -}; - - -struct option_alternative alt[4] = { - {"PLICP", 3, "a new algorithm"}, - {"ICP", 4, "the standard"}, - {"MbICP", 5, "good for rotations"}, {0,0,0} -}; - -int main(int argc, const char*argv[]) { - options_banner("This is a test program for the options library."); - - struct params p; - - struct option* ops = options_allocate(3); - options_int (ops, "i", &p.a_int, 42, "An int parameter"); - options_double (ops, "d", &p.a_double, 0.42, "A double parameter"); - options_string (ops, "s", &p.file , "Hello", "A file parameter"); - options_alternative(ops, "algorith", alt, &p.algo, "which algorithm to use" ); - - - if(!options_parse_args(ops, argc, argv)) { - printf("A simple program.\n\nUsage:\n"); - options_print_help(ops, stderr); - return -1; - } - - printf("i: %d \n", p.a_int); - printf("d: %g \n", p.a_double); - printf("s: %s \n", p.file); - - return 0; -} diff --git a/sm/pkg-config/CMakeLists.txt b/sm/pkg-config/CMakeLists.txt deleted file mode 100644 index 28aa953..0000000 --- a/sm/pkg-config/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -CONFIGURE_FILE(csm.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/csm.pc @ONLY) - -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/csm.pc - DESTINATION lib/pkgconfig) diff --git a/sm/pkg-config/csm.pc.in b/sm/pkg-config/csm.pc.in deleted file mode 100644 index a5e1d0d..0000000 --- a/sm/pkg-config/csm.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: csm -Description: The C(anonical) Scan Matcher -Requires: gsl -Version: @csm_version@ -Libs: @csm_link_flags@ -L${libdir} -lcsm-static -Cflags: @csm_c_flags@ -I${includedir} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..bea18db --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 2.6) + +PROJECT(csm_eigen) + +set(CMAKE_CXX_FLAGS_RELEASE "-O3") +set(CMAKE_C_FLAGS_RELEASE "-O3") + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + + +#SET(CMAKE_BUILD_TYPE Debug) +SET(CMAKE_BUILD_TYPE RelWithDebInfo) +#SET(CMAKE_BUILD_TYPE Release) + +SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../bin ) +SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../lib ) +SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/../lib ) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") +find_package(Eigen3 REQUIRED) +INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIR}) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../include ${CMAKE_SOURCE_DIR}) + +SET(CSM_SRC + csm/laser_data.cpp + csm/math_utils.cpp + csm/math_utils_gsl.cpp + csm/utils.cpp + csm/logging.cpp + csm/sm_options.cpp + csm/orientation.cpp + csm/clustering.cpp) + +SET(EGSL_SRC + egsl/egsl.cpp + egsl/egsl_conversions.cpp + egsl/egsl_misc.cpp + egsl/egsl_ops.cpp) + +SET(GPC_SRC + gpc/gpc.cpp + gpc/gpc_utils.cpp) + +SET(ICP_SRC + icp/icp.cpp + icp/icp_corr_dumb.cpp + icp/icp_corr_tricks.cpp + icp/icp_covariance.cpp + icp/icp_debug.cpp + icp/icp_loop.cpp + icp/icp_outliers.cpp) + +SET(OPTIONS_SRC + options/options.cpp + options/options_interface.cpp) + +ADD_LIBRARY(csm_eigen + ${CSM_SRC} + ${EGSL_SRC} + ${GPC_SRC} + ${ICP_SRC} + ${OPTIONS_SRC}) diff --git a/src/cmake/.svn/all-wcprops b/src/cmake/.svn/all-wcprops new file mode 100644 index 0000000..5a88c60 --- /dev/null +++ b/src/cmake/.svn/all-wcprops @@ -0,0 +1,11 @@ +K 25 +svn:wc:ra_dav:version-url +V 60 +/svn/projects-finepositioning/!svn/ver/1/csm_eigen/src/cmake +END +FindEigen3.cmake +K 25 +svn:wc:ra_dav:version-url +V 77 +/svn/projects-finepositioning/!svn/ver/1/csm_eigen/src/cmake/FindEigen3.cmake +END diff --git a/src/cmake/.svn/entries b/src/cmake/.svn/entries new file mode 100644 index 0000000..cf174ba --- /dev/null +++ b/src/cmake/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +44 +https://aissvn.informatik.uni-freiburg.de/svn/projects-finepositioning/csm_eigen/src/cmake +https://aissvn.informatik.uni-freiburg.de/svn/projects-finepositioning + + + +2012-10-15T16:45:58.517020Z +1 +sprunkc + + + + + + + + + + + + + + +4f0715f2-ee9a-4e3b-b139-986d1b33de6f + +FindEigen3.cmake +file + + + + +2012-10-12T15:29:44.055339Z +911e0662949d9bf6a5845073addb37ec +2012-10-15T16:45:58.517020Z +1 +sprunkc + + + + + + + + + + + + + + + + + + + + + +2995 + diff --git a/src/cmake/.svn/text-base/FindEigen3.cmake.svn-base b/src/cmake/.svn/text-base/FindEigen3.cmake.svn-base new file mode 100644 index 0000000..9c546a0 --- /dev/null +++ b/src/cmake/.svn/text-base/FindEigen3.cmake.svn-base @@ -0,0 +1,81 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org> +# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr> +# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK FALSE) + else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK TRUE) + endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + + if(NOT EIGEN3_VERSION_OK) + + message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " + "but at least version ${Eigen3_FIND_VERSION} is required") + endif(NOT EIGEN3_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + # in cache already + _eigen3_check_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/src/cmake/FindEigen3.cmake b/src/cmake/FindEigen3.cmake new file mode 100644 index 0000000..9c546a0 --- /dev/null +++ b/src/cmake/FindEigen3.cmake @@ -0,0 +1,81 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org> +# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr> +# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK FALSE) + else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK TRUE) + endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + + if(NOT EIGEN3_VERSION_OK) + + message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " + "but at least version ${Eigen3_FIND_VERSION} is required") + endif(NOT EIGEN3_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + # in cache already + _eigen3_check_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/sm/csm/clustering.c b/src/csm/clustering.cpp similarity index 100% rename from sm/csm/clustering.c rename to src/csm/clustering.cpp diff --git a/sm/csm/csm_all.h b/src/csm/csm_all.h similarity index 73% rename from sm/csm/csm_all.h rename to src/csm/csm_all.h index c5e9bb3..daf3e46 100644 --- a/sm/csm/csm_all.h +++ b/src/csm/csm_all.h @@ -1,20 +1,20 @@ #ifndef H_CSM_ALL #define H_CSM_ALL -#include "csm.h" +#include <csm/csm.h> #ifdef __cplusplus namespace CSM {} -extern "C" { +//extern "C" { #endif -#include "json_journal.h" +//#include "json_journal.h" #include "logging.h" #include "math_utils.h" #include "math_utils_gsl.h" #ifdef __cplusplus -} +//} #endif #endif diff --git a/sm/csm/laser_data.c b/src/csm/laser_data.cpp similarity index 86% rename from sm/csm/laser_data.c rename to src/csm/laser_data.cpp index 7f47fb7..ebef822 100644 --- a/sm/csm/laser_data.c +++ b/src/csm/laser_data.cpp @@ -10,7 +10,7 @@ int* alloc_int_array(int n, int def); /* -------------------------------------------------- */ LDP ld_alloc_new(int nrays) { - LDP ld = malloc(sizeof(struct laser_data)); + LDP ld = (LDP) malloc(sizeof(struct laser_data)); ld_alloc(ld, nrays); return ld; } @@ -35,19 +35,19 @@ void ld_alloc(LDP ld, int nrays) { ld->nrays = nrays; ld->valid = alloc_int_array(nrays, 0); - ld->readings = alloc_double_array(nrays, GSL_NAN); - ld->readings_sigma = alloc_double_array(nrays, GSL_NAN); - ld->theta = alloc_double_array(nrays, GSL_NAN); + ld->readings = alloc_double_array(nrays, std::numeric_limits<double>::quiet_NaN()); + ld->readings_sigma = alloc_double_array(nrays, std::numeric_limits<double>::quiet_NaN()); + ld->theta = alloc_double_array(nrays, std::numeric_limits<double>::quiet_NaN()); - ld->min_theta = GSL_NAN; - ld->max_theta = GSL_NAN; + ld->min_theta = std::numeric_limits<double>::quiet_NaN(); + ld->max_theta = std::numeric_limits<double>::quiet_NaN(); ld->cluster = alloc_int_array(nrays, -1); - ld->alpha = alloc_double_array(nrays, GSL_NAN); - ld->cov_alpha = alloc_double_array(nrays, GSL_NAN); + ld->alpha = alloc_double_array(nrays, std::numeric_limits<double>::quiet_NaN()); + ld->cov_alpha = alloc_double_array(nrays, std::numeric_limits<double>::quiet_NaN()); ld->alpha_valid = alloc_int_array(nrays, 0); - ld->true_alpha = alloc_double_array(nrays, GSL_NAN); + ld->true_alpha = alloc_double_array(nrays, std::numeric_limits<double>::quiet_NaN()); ld->up_bigger = alloc_int_array(nrays, 0); ld->up_smaller = alloc_int_array(nrays, 0); @@ -67,7 +67,7 @@ void ld_alloc(LDP ld, int nrays) { for(i=0;i<3;i++) { ld->odometry[i] = ld->estimate[i] = - ld->true_pose[i] = GSL_NAN; + ld->true_pose[i] = std::numeric_limits<double>::quiet_NaN(); } ld->points = (point2d*) malloc(nrays * sizeof(point2d)); @@ -77,7 +77,7 @@ void ld_alloc(LDP ld, int nrays) { ld->points[i].p[0] = ld->points[i].p[1] = ld->points[i].rho = - ld->points[i].phi = GSL_NAN; + ld->points[i].phi = std::numeric_limits<double>::quiet_NaN(); ld->points_w[i] = ld->points[i]; } @@ -124,8 +124,8 @@ void ld_compute_cartesian(LDP ld) { ld->points[i].p[0] = x, ld->points[i].p[1] = y; - ld->points[i].rho = GSL_NAN; - ld->points[i].phi = GSL_NAN; + ld->points[i].rho = std::numeric_limits<double>::quiet_NaN(); + ld->points[i].phi = std::numeric_limits<double>::quiet_NaN(); } } diff --git a/sm/csm/logging.c b/src/csm/logging.cpp similarity index 99% rename from sm/csm/logging.c rename to src/csm/logging.cpp index 647a6db..95da035 100644 --- a/sm/csm/logging.c +++ b/src/csm/logging.cpp @@ -1,4 +1,3 @@ -#include <sys/param.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -7,6 +6,7 @@ #include "logging.h" #include "csm_all.h" +#include "utils.h" int sm_debug_write_flag = 0; diff --git a/sm/csm/logging.h b/src/csm/logging.h similarity index 100% rename from sm/csm/logging.h rename to src/csm/logging.h diff --git a/sm/csm/math_utils.c b/src/csm/math_utils.cpp similarity index 96% rename from sm/csm/math_utils.c rename to src/csm/math_utils.cpp index 275aabf..ba7c6c8 100644 --- a/sm/csm/math_utils.c +++ b/src/csm/math_utils.cpp @@ -1,10 +1,10 @@ #include <assert.h> -#include <gsl/gsl_nan.h> +//#include <gsl/gsl_nan.h> #include "csm_all.h" int minmax(int from, int to, int x) { - return GSL_MAX(GSL_MIN(x,to),from); + return std::max(std::min(x,to),from); } void possible_interval( @@ -186,7 +186,7 @@ double dist_to_segment_d(const double a[2], const double b[2], const double x[2] /* the projection is inside the segment */ return distance; } else - return sqrt(GSL_MIN( distance_squared_d(a,x), distance_squared_d(b,x))); + return sqrt(std::min( distance_squared_d(a,x), distance_squared_d(b,x))); } int count_equal(const int*v, int n, int value) { @@ -198,7 +198,7 @@ int count_equal(const int*v, int n, int value) { double normalize_0_2PI(double t) { if(is_nan(t)) { sm_error("Passed NAN to normalize_0_2PI().\n"); - return GSL_NAN; + return std::numeric_limits<double>::quiet_NaN(); } while(t<0) t+=2*M_PI; while(t>=2*M_PI) t-=2*M_PI; @@ -217,7 +217,7 @@ of the eye, and direction is the direction of the ray coming out of the eye. Ret if the ray intersects the segment, and in that case *range contains the length of the ray. */ int segment_ray_tracing(const double p0[2], const double p1[2], const double eye[2], double direction, double*range) { - *range = NAN; + *range = std::numeric_limits<double>::quiet_NaN(); // p0 - p1 double arrow[2] = {p1[0]-p0[0],p1[1]-p0[1]}; diff --git a/sm/csm/math_utils.h b/src/csm/math_utils.h similarity index 100% rename from sm/csm/math_utils.h rename to src/csm/math_utils.h diff --git a/src/csm/math_utils_gsl.cpp b/src/csm/math_utils_gsl.cpp new file mode 100644 index 0000000..665f987 --- /dev/null +++ b/src/csm/math_utils_gsl.cpp @@ -0,0 +1,104 @@ +#include "csm_all.h" + +//void transform(const gsl_vector* p, const gsl_vector* x, gsl_vector*res) { +// double theta = gvg(x,2); +// double c = cos(theta); double s = sin(theta); +// gsl_vector_set(res, 0, c * gvg(p,0) -s*gvg(p,1) + gvg(x,0)); +// gsl_vector_set(res, 1, s * gvg(p,0) +c*gvg(p,1) + gvg(x,1)); +//} +// +//void gsl_vector_set_nan(gsl_vector*v) { +// gvs(v,0,GSL_NAN); +// gvs(v,1,GSL_NAN); +//} +// +//double norm(const gsl_vector*a){ +// double x = gvg(a,0); +// double y = gvg(a,1); +// return sqrt(x*x+y*y); +//} + +gsl_vector * vector_from_array(unsigned int n, double *x) { + gsl_vector * v = gsl_vector_alloc(n); + unsigned int i; + for(i=0;i<n;i++) + gvs(v,i,x[i]); + + return v; +} + +//void copy_from_array(gsl_vector*v, double*x) { +// size_t i; +// for(i=0;i<v->size;i++) +// gsl_vector_set(v,i, x[i]); +//} + +void vector_to_array(const gsl_vector*v, double*x){ + size_t i; + for(i=0;i<v->size();i++) + x[i] = gvg(v,i); +} + +//void oplus(const gsl_vector*x1,const gsl_vector*x2, gsl_vector*res) { +// double c = cos(gvg(x1,2)); +// double s = sin(gvg(x1,2)); +// gvs(res,0, gvg(x1,0)+c*gvg(x2,0)-s*gvg(x2,1)); +// gvs(res,1, gvg(x1,1)+s*gvg(x2,0)+c*gvg(x2,1)); +// gvs(res,2, gvg(x1,2)+gvg(x2,2)); +//} + +void ominus(const gsl_vector*x, gsl_vector*res) { + double c = cos(gvg(x,2)); + double s = sin(gvg(x,2)); + gvs(res,0, -c*gvg(x,0)-s*gvg(x,1)); + gvs(res,1, s*gvg(x,0)-c*gvg(x,1)); + gvs(res,2, -gvg(x,2)); +} + +//void pose_diff(const gsl_vector*pose2,const gsl_vector*pose1,gsl_vector*res) { +// gsl_vector* temp = gsl_vector_alloc(3); +// ominus(pose1, temp); +// oplus(temp, pose2, res); +// gsl_vector_free(temp); +//} + +const char* gsl_friendly_pose(gsl_vector*v) { + return friendly_pose(v->data()); +} + +//static char egsl_tmp_buf[1024]; +//const char* egsl_friendly_pose(val v) { +// sprintf(egsl_tmp_buf, "(%4.2f mm, %4.2f mm, %4.4f deg)", +// 1000*egsl_atv(v,0), +// 1000*egsl_atv(v,1), +// rad2deg(egsl_atv(v,2))); +// return egsl_tmp_buf; +//} +// +//const char* egsl_friendly_cov(val cov) { +// +// double limit_x = 2 * sqrt(egsl_atm(cov, 0, 0)); +// double limit_y = 2 * sqrt(egsl_atm(cov, 1, 1)); +// double limit_th = 2 * sqrt(egsl_atm(cov, 2, 2)); +// +// sprintf(egsl_tmp_buf, "(+- %4.2f mm,+- %4.2f mm,+- %4.4f deg)", +// 1000*limit_x, +// 1000*limit_y, +// rad2deg(limit_th)); +// return egsl_tmp_buf; +//} + + +/*double distance(const gsl_vector* a, const gsl_vector* b) { + distance_counter++; + double x = gvg(a,0)-gvg(b,0); + double y = gvg(a,1)-gvg(b,1); + return sqrt(x*x+y*y); +} + +double distance_squared(const gsl_vector* a, const gsl_vector* b) { + distance_counter++; + double x = gvg(a,0)-gvg(b,0); + double y = gvg(a,1)-gvg(b,1); + return x*x+y*y; +}*/ diff --git a/src/csm/math_utils_gsl.h b/src/csm/math_utils_gsl.h new file mode 100644 index 0000000..df41637 --- /dev/null +++ b/src/csm/math_utils_gsl.h @@ -0,0 +1,41 @@ +#ifndef H_MATH_UTILS_GSL +#define H_MATH_UTILS_GSL + +//#include <gsl/gsl_math.h> +#include <egsl/egsl.h> + +#include <csm/laser_data.h> + +#define gvg gsl_vector_get +#define gvs gsl_vector_set + + +/* GSL stuff */ + const char* gsl_friendly_pose(gsl_vector*v); + gsl_vector * vector_from_array(unsigned int n, double *x); + void vector_to_array(const gsl_vector*v, double*); + //void copy_from_array(gsl_vector*v, double*); + + //void oplus(const gsl_vector*x1,const gsl_vector*x2, gsl_vector*res); + void ominus(const gsl_vector*x, gsl_vector*res); + //void pose_diff(const gsl_vector*pose2,const gsl_vector*pose1,gsl_vector*res); + + //void transform(const gsl_vector* point2d, const gsl_vector* pose, gsl_vector*result2d); + //void gsl_vector_set_nan(gsl_vector*v); + + //double distance(const gsl_vector* a,const gsl_vector* b); + //double distance_squared(const gsl_vector* a,const gsl_vector* b); + + /** Returns norm of 2D point p */ + //double norm(const gsl_vector*p); + //const char* egsl_friendly_pose(val pose); + //const char* egsl_friendly_cov(val cov); + +/** Returns Fisher's information matrix. You still have to multiply + it by (1/sigma^2). */ +val ld_fisher0(LDP ld); + + +#endif + + diff --git a/sm/csm/orientation.c b/src/csm/orientation.cpp similarity index 73% rename from sm/csm/orientation.c rename to src/csm/orientation.cpp index 5c3eb89..8ad2402 100644 --- a/sm/csm/orientation.c +++ b/src/csm/orientation.cpp @@ -1,40 +1,43 @@ #include <math.h> -#include <gsl/gsl_nan.h> #include "csm_all.h" #include <egsl/egsl_macros.h> +#include <vector> - -void find_neighbours(LDP ld, int i, int max_num, int*indexes, size_t*num_found); + +void find_neighbours(LDP ld, int i, int max_num, std::vector<int>& indexes, size_t*num_found); void filter_orientation(double theta0, double rho0, size_t n, - const double*thetas, const double*rhos, double *alpha, double*cov0_alpha ); + const std::vector<double>& thetas, const std::vector<double>& rhos, double *alpha, double*cov0_alpha ); /** Requires the "cluster" field to be set */ void ld_compute_orientation(LDP ld, int size_neighbourhood, double sigma) { int i; for(i=0;i<ld->nrays;i++){ if(!ld_valid_ray(ld,i) || (ld->cluster[i] == -1)) { - ld->alpha[i] = GSL_NAN; - ld->cov_alpha[i] = GSL_NAN; + ld->alpha[i] = std::numeric_limits<double>::quiet_NaN(); //GSL_NAN; + ld->cov_alpha[i] = std::numeric_limits<double>::quiet_NaN(); //GSL_NAN; ld->alpha_valid[i] = 0; continue; } - int neighbours[size_neighbourhood*2]; + //int neighbours[size_neighbourhood*2]; + std::vector<int> neighbours(size_neighbourhood*2, 0); size_t num_neighbours; find_neighbours(ld, i, size_neighbourhood, neighbours, &num_neighbours); if(0==num_neighbours) { - ld->alpha[i] = GSL_NAN; - ld->cov_alpha[i] = GSL_NAN; + ld->alpha[i] = std::numeric_limits<double>::quiet_NaN(); //GSL_NAN; + ld->cov_alpha[i] = std::numeric_limits<double>::quiet_NaN(); //GSL_NAN; ld->alpha_valid[i] = 0; continue; } /* printf("orientation for i=%d:\n",i); */ - double thetas[num_neighbours]; - double readings[num_neighbours]; + //double thetas[num_neighbours]; + std::vector<double> thetas(num_neighbours, 0.0); + //double readings[num_neighbours]; + std::vector<double> readings(num_neighbours, 0.0); size_t a=0; for(a=0;a<num_neighbours;a++) { thetas[a] = ld->theta[neighbours[a]]; @@ -45,10 +48,13 @@ void ld_compute_orientation(LDP ld, int size_neighbourhood, double sigma) { double alpha=42, cov0_alpha=32; filter_orientation(ld->theta[i],ld->readings[i],num_neighbours, thetas,readings,&alpha,&cov0_alpha); - - if(gsl_isnan(alpha)) { - ld->alpha[i] = GSL_NAN; - ld->cov_alpha[i] = GSL_NAN; +#ifndef WINDOWS + if(std::isnan(alpha)) { +#else + if(_isnan(alpha)) { +#endif + ld->alpha[i] = std::numeric_limits<double>::quiet_NaN(); + ld->cov_alpha[i] = std::numeric_limits<double>::quiet_NaN(); ld->alpha_valid[i] = 0; } else { ld->alpha[i] = alpha; @@ -62,7 +68,7 @@ void ld_compute_orientation(LDP ld, int size_neighbourhood, double sigma) { /** A very cool algorithm for finding the orientation */ void filter_orientation(double theta0, double rho0, size_t n, - const double*thetas, const double*rhos, double *alpha, double*cov0_alpha ) { + const std::vector<double>& thetas, const std::vector<double>& rhos, double *alpha, double*cov0_alpha ) { egsl_push(); /* Y = L x + R epsilon */ @@ -93,8 +99,11 @@ void filter_orientation(double theta0, double rho0, size_t n, *cov0_alpha = square(dalpha_df1) * cov_f1 + square(dalpha_drho); - - if(gsl_isnan(*alpha)) { +#ifndef WINDOWS + if(std::isnan(*alpha)) { +#else + if(_isnan(*alpha)) { +#endif egsl_print("Y",Y); egsl_print("L",L); egsl_print("R",R); @@ -129,7 +138,7 @@ void filter_orientation(double theta0, double rho0, size_t n, } /* indexes: an array of size "max_num*2" */ -void find_neighbours(LDP ld, int i, int max_num, int*indexes, size_t*num_found) { +void find_neighbours(LDP ld, int i, int max_num, std::vector<int>& indexes, size_t*num_found) { *num_found = 0; int up = i; diff --git a/sm/csm/sm_options.c b/src/csm/sm_options.cpp similarity index 88% rename from sm/csm/sm_options.c rename to src/csm/sm_options.cpp index f83adad..083f827 100644 --- a/sm/csm/sm_options.c +++ b/src/csm/sm_options.cpp @@ -1,7 +1,4 @@ -#include <options/options.h> - -#include "csm_all.h" - +#include "sm_options.h" void sm_options(struct sm_params*p, struct option*ops) { @@ -95,11 +92,11 @@ void sm_options(struct sm_params*p, struct option*ops) { &(p->debug_verify_tricks), 0, "Checks that find_correspondences_tricks gives the right answer."); - options_double(ops, "gpm_theta_bin_size_deg", &(p->gpm_theta_bin_size_deg), 5.0, - "GPM: Dimension of bins for finding first theta."); - options_double(ops, "gpm_extend_range_deg", &(p->gpm_extend_range_deg), 15.0, - "GPM: Area around maximum."); - options_int(ops, "gpm_interval", &(p->gpm_interval), 1, "Interval of points to consider (1: all points, 2: every other point, etc.)"); + /*options_double(ops, "gpm_theta_bin_size_deg", &(p->gpm_theta_bin_size_deg), 5.0, */ + /*"GPM: Dimension of bins for finding first theta.");*/ + /*options_double(ops, "gpm_extend_range_deg", &(p->gpm_extend_range_deg), 15.0, */ + /*"GPM: Area around maximum.");*/ + /*options_int(ops, "gpm_interval", &(p->gpm_interval), 1, "Interval of points to consider (1: all points, 2: every other point, etc.)");*/ options_double(ops, "laser_x", &(p->laser[0]), 0.0, "laser.x (m)"); options_double(ops, "laser_y", &(p->laser[1]), 0.0, "laser.y (m)"); @@ -115,5 +112,5 @@ void sm_options(struct sm_params*p, struct option*ops) { "If 1, the field 'readings_sigma' in the second scan is used to weight the correspondence by 1/sigma^2"); - hsm_add_options(ops, &p->hsm); + /*hsm_add_options(ops, &p->hsm);*/ } diff --git a/src/csm/sm_options.h b/src/csm/sm_options.h new file mode 100644 index 0000000..5a1ab6c --- /dev/null +++ b/src/csm/sm_options.h @@ -0,0 +1,9 @@ +#ifndef SM_OPTIONS_H +#define SM_OPTIONS_H + +#include <options/options.h> +#include "csm/csm_all.h" + +void sm_options(struct sm_params*p, struct option*ops); + +#endif diff --git a/sm/csm/utils.c b/src/csm/utils.cpp similarity index 98% rename from sm/csm/utils.c rename to src/csm/utils.cpp index bb373d9..a1145c9 100644 --- a/sm/csm/utils.c +++ b/src/csm/utils.cpp @@ -1,8 +1,10 @@ #include <string.h> #include <errno.h> +#include "utils.h" #include "csm_all.h" + /** Wraps around fopen and provides error message. */ FILE * open_file(const char *filename, const char*mode); diff --git a/sm/csm/utils.h b/src/csm/utils.h similarity index 100% rename from sm/csm/utils.h rename to src/csm/utils.h diff --git a/sm/lib/egsl/egsl.c b/src/egsl/egsl.cpp similarity index 70% rename from sm/lib/egsl/egsl.c rename to src/egsl/egsl.cpp index c4943b4..0b5efe5 100644 --- a/sm/lib/egsl/egsl.c +++ b/src/egsl/egsl.cpp @@ -1,10 +1,12 @@ -#include <gsl/gsl_matrix.h> -#include <gsl/gsl_blas.h> -#include <gsl/gsl_linalg.h> +//#include <gsl/gsl_matrix.h> +//#include <gsl/gsl_blas.h> +//#include <gsl/gsl_linalg.h> #include <assert.h> #include <math.h> #include <string.h> +#include <stdio.h> +using namespace std; #include "egsl.h" #include "egsl_imp.h" @@ -39,9 +41,9 @@ int egsl_cache_hits = 0; void egsl_error(void) { /* TODO: better handling of errors */ - + egsl_print_stats(); - + assert(0); } @@ -99,7 +101,7 @@ void egsl_push_named(const char*name) { egsl_first_time = 0; } cid++; - + if(cid >= MAX_CONTEXTS) { fprintf(stderr, "egsl: maximum number of contexts reached \n"); egsl_print_stats(); @@ -111,7 +113,7 @@ void egsl_push_named(const char*name) { if(name != 0) sprintf(egsl_contexts[cid].name, "%s", name); else - sprintf(egsl_contexts[cid].name, "Unnamed context"); + sprintf(egsl_contexts[cid].name, "Unnamed context"); } void egsl_pop_named(const char*name) { @@ -145,7 +147,7 @@ void egsl_pop_check(int assumed) { }*/ void egsl_print_stats() { - fprintf(stderr, "egsl: total allocations: %d cache hits: %d\n", + fprintf(stderr, "egsl: total allocations: %d cache hits: %d\n", egsl_total_allocations, egsl_cache_hits); /* printf("egsl: sizeof(val) = %d\n",(int)sizeof(val)); */ int c; for(c=0;c<=max_cid&&c<MAX_CONTEXTS;c++) { @@ -169,7 +171,7 @@ val egsl_alloc(size_t rows, size_t columns) { int index = c->nvars; if(index<c->nallocated) { gsl_matrix*m = c->vars[index].gsl_m; - if(m->size1 == rows && m->size2 == columns) { + if(m->rows() == rows && m->cols() == columns) { egsl_cache_hits++; c->nvars++; return assemble_val(cid,index,c->vars[index].gsl_m); @@ -190,34 +192,50 @@ val egsl_alloc(size_t rows, size_t columns) { } val egsl_alloc_in_context(int context, size_t rows, size_t columns) { - struct egsl_context*c = egsl_contexts+context; - - if(c->nvars>=MAX_VALS) { - fprintf(stderr,"Limit reached, in context %d, nvars is %d\n",context,c->nvars); - egsl_error(); - } + struct egsl_context*c = egsl_contexts+context; + +/* if(cid<3) + printf("Alloc cid=%d nvars=%d nalloc=%d\n",cid,c->nvars,c->nallocated); */ + + if(c->nvars>=MAX_VALS) { + fprintf(stderr,"Limit reached, in context %d, nvars is %d\n",context,c->nvars); + egsl_error(); + } + int index = c->nvars; + if(index<c->nallocated) { + gsl_matrix*m = c->vars[index].gsl_m; + if(m->rows() == rows && m->cols() == columns) { + egsl_cache_hits++; + c->nvars++; + return assemble_val(context,index,c->vars[index].gsl_m); + } else { + gsl_matrix_free(m); + egsl_total_allocations++; + c->vars[index].gsl_m = gsl_matrix_alloc((size_t)rows,(size_t)columns); + c->nvars++; + return assemble_val(context,index,c->vars[index].gsl_m); + } + } else { + egsl_total_allocations++; + c->vars[index].gsl_m = gsl_matrix_alloc((size_t)rows,(size_t)columns); + c->nvars++; + c->nallocated++; + return assemble_val(context,index,c->vars[index].gsl_m); + } +} + +/* +val egsl_alloc_in_context(int context, size_t rows, size_t columns) { + egsl_total_allocations++; + struct egsl_context *c = egsl_contexts+context; int index = c->nvars; - if(index<c->nallocated) { - gsl_matrix*m = c->vars[index].gsl_m; - if(m->size1 == rows && m->size2 == columns) { - egsl_cache_hits++; - c->nvars++; - return assemble_val(context,index,c->vars[index].gsl_m); - } else { - gsl_matrix_free(m); - egsl_total_allocations++; - c->vars[index].gsl_m = gsl_matrix_alloc((size_t)rows,(size_t)columns); - c->nvars++; - return assemble_val(context,index,c->vars[index].gsl_m); - } - } else { - egsl_total_allocations++; - c->vars[index].gsl_m = gsl_matrix_alloc((size_t)rows,(size_t)columns); - c->nvars++; - c->nallocated++; - return assemble_val(context,index,c->vars[index].gsl_m); - } + c->vars[index].gsl_m = gsl_matrix_alloc((size_t)rows,(size_t)columns); + c->nvars++; + c->nallocated++; + return assemble_val(context,index,c->vars[index].gsl_m); } +*/ + /** Creates a copy of v in the previous context. */ val egsl_promote(val v) { @@ -226,7 +244,7 @@ val egsl_promote(val v) { } gsl_matrix * m = egsl_gslm(v); - val v2 = egsl_alloc_in_context(cid-1, m->size1, m->size2); + val v2 = egsl_alloc_in_context(cid-1, m->rows(), m->cols()); gsl_matrix * m2 = egsl_gslm(v2); gsl_matrix_memcpy(m2, m); return v2; @@ -237,12 +255,12 @@ val egsl_promote(val v) { void egsl_expect_size(val v, size_t rows, size_t cols) { gsl_matrix * m = egsl_gslm(v); - - int bad = (rows && (m->size1!=rows)) || (cols && (m->size2!=cols)); + + int bad = (rows && (m->rows()!=rows)) || (cols && (m->cols()!=cols)); if(bad) { fprintf(stderr, "Matrix size is %d,%d while I expect %d,%d", - (int)m->size1,(int)m->size2,(int)rows,(int)cols); - + (int)m->rows(),(int)m->cols(),(int)rows,(int)cols); + egsl_error(); } } @@ -254,19 +272,19 @@ void egsl_print(const char*str, val v) { int context = its_context(v); int var_index = its_var_index(v); fprintf(stderr, "%s = (%d x %d) context=%d index=%d\n", - str,(int)m->size1,(int)m->size2, context, var_index); + str,(int)m->rows(),(int)m->cols(), context, var_index); - for(i=0;i<m->size1;i++) { + for(i=0;i<m->rows();i++) { if(i==0) fprintf(stderr, " [ "); else fprintf(stderr, " "); - for(j=0;j<m->size2;j++) + for(j=0;j<m->cols();j++) fprintf(stderr, "%f ", gsl_matrix_get(m,i,j)); - if(i==m->size1-1) + if(i==m->rows()-1) fprintf(stderr, "] \n"); else fprintf(stderr, "; \n"); @@ -284,7 +302,7 @@ double egsl_norm(val v1){ double n=0; size_t i; gsl_matrix * m = egsl_gslm(v1); - for(i=0;i<m->size1;i++) { + for(i=0;i<m->rows();i++) { double v = gsl_matrix_get(m,i,0); n += v * v; } @@ -295,17 +313,18 @@ double egsl_atv(val v1, size_t i){ return *egsl_atmp(v1, i, 0); } -double egsl_atm(val v1, size_t i, size_t j){ - return *egsl_atmp(v1, i, j); -} +//double egsl_atm(val v1, size_t i, size_t j){ +// return *egsl_atmp(v1, i, j); +//} -void egsl_free(void){ - int c; - for(c=0;c<=max_cid;c++) { - for(int i=egsl_contexts[c].nvars; i<egsl_contexts[c].nallocated; i++){ - gsl_matrix_free(egsl_contexts[c].vars[i].gsl_m); - } - egsl_contexts[c].nallocated = egsl_contexts[c].nvars; - } -} +void egsl_free_unused_memory(){ + int c; + int freecounter = 0; + for(c=0;c<=max_cid;c++) { + for(int i=egsl_contexts[c].nvars; i<egsl_contexts[c].nallocated; i++){ + gsl_matrix_free(egsl_contexts[c].vars[i].gsl_m); + } + egsl_contexts[c].nallocated = egsl_contexts[c].nvars; + } +} diff --git a/sm/lib/egsl/egsl.h b/src/egsl/egsl.h similarity index 71% rename from sm/lib/egsl/egsl.h rename to src/egsl/egsl.h index 0b8c17c..3cac81d 100644 --- a/sm/lib/egsl/egsl.h +++ b/src/egsl/egsl.h @@ -1,13 +1,14 @@ #ifndef H_EASY_GSL #define H_EASY_GSL -#include <gsl/gsl_vector.h> -#include <gsl/gsl_matrix.h> +//#include <gsl/gsl_vector.h> +//#include <gsl/gsl_matrix.h> +#include <gsl_eigen/gsl_eigen.h> -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif struct egsl_val { gsl_matrix * gslm; @@ -29,7 +30,7 @@ void egsl_free(void); double* egsl_atmp(val v, size_t i, size_t j); val egsl_alloc(size_t rows, size_t columns); -val egsl_alloc_in_context(int cid, size_t rows, size_t cols); +val egsl_alloc_in_context(int cid, size_t rows, size_t cols); //used by egsl_promote gsl_matrix * egsl_gslm(val v); /** Creates a copy of v in the previous context.*/ val egsl_promote(val v); @@ -37,7 +38,7 @@ val egsl_promote(val v); /** Operations among values */ val egsl_scale(double, val); val egsl_sum(val, val); -val egsl_sum3(val, val, val); +//val egsl_sum3(val, val, val); val egsl_mult(val, val); val egsl_transpose(val); val egsl_inverse(val); @@ -50,10 +51,10 @@ void egsl_add_to_col(val v1, size_t j, val v2); double egsl_norm(val); -void egsl_symm_eig(val v, double* eigenvalues, val* eigenvectors); +//void egsl_symm_eig(val v, double* eigenvalues, val* eigenvectors); double egsl_atv(val, size_t i); -double egsl_atm(val, size_t i, size_t j); +//double egsl_atm(val, size_t i, size_t j); /* File: egsl_conversions.c Conversions */ @@ -62,14 +63,14 @@ val egsl_vFa(size_t rows, const double*); val egsl_vFda(size_t rows, size_t columns, const double*); /** Copies a VECTOR value into array */ -void egsl_v2a(val, double*); +//void egsl_v2a(val, double*); /** Copies a MATRIX value into array (row1 .. rown) */ -void egsl_v2da(val, double*); +//void egsl_v2da(val, double*); /** Copies a vector value into a gsl_vector */ -void egsl_v2vec(val, gsl_vector*); +//void egsl_v2vec(val, gsl_vector*); -val egsl_vFgslv(const gsl_vector*); -val egsl_vFgslm(const gsl_matrix*); +//val egsl_vFgslv(const gsl_vector*); +//val egsl_vFgslm(const gsl_matrix*); gsl_matrix* egsl_v2gslm(val); @@ -82,9 +83,9 @@ val egsl_rot(double theta); /* Misc */ -void egsl_print(const char*str, val); +void egsl_print(const char*str, val); /** Prints eigenvalues and eigenvectors of a symmetric matrix */ -void egsl_print_spectrum(const char*s, val v); +//void egsl_print_spectrum(const char*s, val v); void egsl_print_stats(void); @@ -94,8 +95,11 @@ void egsl_expect_size(val v, size_t rows, size_t cols); void egsl_error(void); -#ifdef __cplusplus -} -#endif +void egsl_free_unused_memory(); + + +//#ifdef __cplusplus +//} +//#endif #endif diff --git a/src/egsl/egsl_conversions.cpp b/src/egsl/egsl_conversions.cpp new file mode 100644 index 0000000..eb38b7e --- /dev/null +++ b/src/egsl/egsl_conversions.cpp @@ -0,0 +1,64 @@ +#include "egsl.h" + +val egsl_vFda(size_t rows, size_t cols, const double *a) { + val v = egsl_alloc(rows, cols); + + size_t i; size_t j; + for(i=0;i<rows;i++) + for(j=0;j<cols;j++) { + *egsl_atmp(v,i,j) = a[j+i*cols]; + } + return v; +} + +val egsl_vFa(size_t rows, const double*a) { + val v = egsl_alloc(rows,1); + size_t i; + for(i=0;i<rows;i++) + *egsl_atmp(v,i,0) = a[i]; + return v; +} + +//void egsl_v2a(val v, double*vec) { +// gsl_matrix *m = egsl_gslm(v); +// size_t i; +// for(i=0; i < m->size1; i++) +// vec[i] = gsl_matrix_get(m,i,0); +//} + +//void egsl_v2da(val v, double*a){ +// gsl_matrix *m = egsl_gslm(v); +// size_t i,j; +// for(i=0;i<m->size1;i++) +// for(j=0;j<m->size2;j++) +// a[j*m->size1 +i] = gsl_matrix_get(m,i,j); +//} + +//void egsl_v2vec(val v, gsl_vector*vec) { +// size_t i; +// for(i=0;i<vec->size;i++) +// gsl_vector_set(vec,i, *egsl_atmp(v,i,0)); +//} + + +//val egsl_vFgslv(const gsl_vector*vec){ +// val v = egsl_alloc(vec->size,1); +// size_t i; +// for(i=0;i<vec->size;i++) +// *egsl_atmp(v,i,0) = gsl_vector_get(vec,i); +// return v; +//} + +//val egsl_vFgslm(const gsl_matrix*m){ +// val v = egsl_alloc(m->size1,m->size2); +// gsl_matrix * m2 = egsl_gslm(v); +// gsl_matrix_memcpy(m2,m); +// return v; +//} + +gsl_matrix* egsl_v2gslm(val v){ + gsl_matrix * m = egsl_gslm(v); + gsl_matrix * m2 = gsl_matrix_alloc(m->rows(),m->cols()); + gsl_matrix_memcpy(m2,m); + return m2; +} diff --git a/sm/lib/egsl/egsl_imp.h b/src/egsl/egsl_imp.h similarity index 100% rename from sm/lib/egsl/egsl_imp.h rename to src/egsl/egsl_imp.h diff --git a/sm/lib/egsl/egsl_macros.h b/src/egsl/egsl_macros.h similarity index 100% rename from sm/lib/egsl/egsl_macros.h rename to src/egsl/egsl_macros.h diff --git a/sm/lib/egsl/egsl_misc.c b/src/egsl/egsl_misc.cpp similarity index 52% rename from sm/lib/egsl/egsl_misc.c rename to src/egsl/egsl_misc.cpp index 2120e23..270db8f 100644 --- a/sm/lib/egsl/egsl_misc.c +++ b/src/egsl/egsl_misc.cpp @@ -1,5 +1,7 @@ #include <math.h> #include "egsl.h" +#include <stdio.h> +using namespace std; val egsl_rot(double theta) { double R[2*2] = { @@ -28,18 +30,18 @@ val egsl_vers(double theta){ return egsl_vFa(2,v); } -void egsl_print_spectrum(const char*s, val v) { - gsl_matrix *m = egsl_gslm(v); - /* expect same size */ - size_t n = m->size1; - double eval[n]; val evec[n]; - egsl_symm_eig(v, eval, evec); - size_t i,j; - for(j=0;j<n;j++) { - fprintf(stderr, "%s | eval[%d] = %+5.5f evec[%d]= ", - s, (int)j, eval[j],(int)j); - for(i=0;i<n;i++) - fprintf(stderr, "%+4.4f ", egsl_atv(evec[j],i)); - fprintf(stderr, " sqrt(eval[%d])=%5.5f \n", (int)j, sqrt(eval[j])); - } -} +//void egsl_print_spectrum(const char*s, val v) { +// gsl_matrix *m = egsl_gslm(v); +// /* expect same size */ +// size_t n = m->rows(); +// double eval[n]; val evec[n]; +// egsl_symm_eig(v, eval, evec); +// size_t i,j; +// for(j=0;j<n;j++) { +// fprintf(stderr, "%s | eval[%d] = %+5.5f evec[%d]= ", +// s, (int)j, eval[j],(int)j); +// for(i=0;i<n;i++) +// fprintf(stderr, "%+4.4f ", egsl_atv(evec[j],i)); +// fprintf(stderr, " sqrt(eval[%d])=%5.5f \n", (int)j, sqrt(eval[j])); +// } +//} diff --git a/src/egsl/egsl_ops.cpp b/src/egsl/egsl_ops.cpp new file mode 100644 index 0000000..1a5e661 --- /dev/null +++ b/src/egsl/egsl_ops.cpp @@ -0,0 +1,185 @@ +//#include <gsl/gsl_matrix.h> +//#include <gsl/gsl_blas.h> +//#include <gsl/gsl_linalg.h> +//#include <gsl/gsl_eigen.h> + +#include "egsl.h" + + + +val egsl_sub(val v1,val v2){ + return egsl_sum(v1, egsl_scale(-1.0,v2)); +} + +val egsl_compose_col(val v1, val v2){ + gsl_matrix *m1 = egsl_gslm(v1); + gsl_matrix *m2 = egsl_gslm(v2); + egsl_expect_size(v2, 0, m1->cols()); + val v3 = egsl_alloc(m1->rows()+m2->rows(),m1->cols()); + gsl_matrix *m3 = egsl_gslm(v3); + size_t i,j; + for(j=0;j<m1->cols();j++) { + for(i=0;i<m1->rows();i++) + gsl_matrix_set(m3, i, j, gsl_matrix_get(m1,i,j)); + + for(i=0;i<m2->rows();i++) + gsl_matrix_set(m3, m1->rows()+i, j, gsl_matrix_get(m2,i,j)); + } + return v3; +} + +val egsl_compose_row(val v1, val v2){ + gsl_matrix *m1 = egsl_gslm(v1); + gsl_matrix *m2 = egsl_gslm(v2); + egsl_expect_size(v2, m1->rows(), 0); + val v3 = egsl_alloc(m1->rows(), m1->cols() + m2->cols()); + gsl_matrix *m3 = egsl_gslm(v3); + size_t i,j; + for(i=0;i<m1->rows();i++) { + for(j=0;j<m1->cols();j++) + gsl_matrix_set(m3, i, j, gsl_matrix_get(m1,i,j)); + + for(j=0;j<m2->cols();j++) + gsl_matrix_set(m3, i, m1->cols()+j, gsl_matrix_get(m2,i,j)); + } + return v3; +} + +void egsl_add_to(val v1, val v2) { + gsl_matrix * m1 = egsl_gslm(v1); + gsl_matrix * m2 = egsl_gslm(v2); + gsl_matrix_add(m1,m2); +} + +void egsl_add_to_col(val v1, size_t j, val v2) { +/* egsl_print("m1",v1); + egsl_print("m2",v2); */ + gsl_matrix * m1 = egsl_gslm(v1); + gsl_matrix * m2 = egsl_gslm(v2); + +/* printf("m1 size = %d,%d j = %d\n",m1->rows(),m1->cols(),j); */ + egsl_expect_size(v2, m1->rows(), 1); + size_t i; + for(i=0;i<m1->rows();i++) { + *gsl_matrix_ptr(m1, i, j) += gsl_matrix_get(m2,i,0); + } +} + + +val egsl_copy_val(val v1) { + gsl_matrix * m1 = egsl_gslm(v1); + val v2 = egsl_alloc(m1->rows(),m1->cols()); + gsl_matrix * m2 = egsl_gslm(v2); + gsl_matrix_memcpy(m2,m1); + return v2; +} + +val egsl_scale(double s, val v1){ + val v2 = egsl_copy_val(v1); + gsl_matrix * m2 = egsl_gslm(v2); + gsl_matrix_scale(m2, s); + return v2; +} + +val egsl_sum(val v1, val v2){ + gsl_matrix * m1 = egsl_gslm(v1); + gsl_matrix * m2 = egsl_gslm(v2); + val v3 = egsl_alloc(m1->rows(),m1->cols()); + gsl_matrix * m3 = egsl_gslm(v3); + gsl_matrix_memcpy(m3,m1); + gsl_matrix_add(m3,m2); + return v3; +} + +//val egsl_sum3(val v1, val v2, val v3){ +// return egsl_sum(v1, egsl_sum(v2,v3)); +//} + +val egsl_mult(val v1, val v2){ + gsl_matrix * a = egsl_gslm(v1); + gsl_matrix * b = egsl_gslm(v2); + val v = egsl_alloc(a->rows(),b->cols()); + gsl_matrix * ab = egsl_gslm(v); + + //gsl_blas_dgemm(CblasNoTrans,CblasNoTrans,1.0,a,b,0.0,ab); + *ab = *a * *b; + + return v; + +} + +val egsl_transpose(val v1){ + gsl_matrix * m1 = egsl_gslm(v1); + val v2 = egsl_alloc(m1->cols(),m1->rows()); + gsl_matrix * m2 = egsl_gslm(v2); + + *m2 = m1->transpose(); + //gsl_matrix_transpose_memcpy(m2,m1); + + return v2; +} + +val egsl_inverse(val v1){ + gsl_matrix*A = egsl_gslm(v1); + val v2 = egsl_alloc(A->rows(),A->rows()); + gsl_matrix*invA = egsl_gslm(v2); + + +// size_t n = A->rows(); +// gsl_matrix * m = gsl_matrix_alloc(n,n); +// +// gsl_matrix_memcpy(m,A); +// gsl_permutation * perm = gsl_permutation_alloc (n); +// /* Make LU decomposition of matrix m */ +// int s; +// gsl_linalg_LU_decomp (m, perm, &s); +// /* Invert the matrix m */ +// gsl_linalg_LU_invert (m, perm, invA); +// gsl_permutation_free(perm); +// gsl_matrix_free(m); + + *invA = A->inverse(); + + return v2; +} + +//void egsl_symm_eig(val v, double* eigenvalues, val* eigenvectors) { +// gsl_matrix *m = egsl_gslm(v); +// size_t N = m->rows(); +// /* Check for v to be square */ +// +// gsl_matrix *A = gsl_matrix_alloc(N,N); +// gsl_matrix_memcpy(A, m); +// +// gsl_vector *eval = gsl_vector_alloc(N); +// gsl_matrix *evec = gsl_matrix_alloc(N,N); +// +// gsl_eigen_symmv_workspace * ws = gsl_eigen_symmv_alloc(N); +// gsl_eigen_symmv(A, eval, evec, ws); +// gsl_eigen_symmv_free(ws); +// +// +// gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_DESC); +// +// size_t j; +// for(j=0;j<N;j++) { +// eigenvalues[j] = gsl_vector_get(eval, j); +// eigenvectors[j] = egsl_alloc(N,1); +// size_t i; +// for(i=0;i<N;i++) +// *egsl_atmp(eigenvectors[j],i,0) = gsl_matrix_get(evec,i,j); +// } +// +// +// gsl_vector_free(eval); +// gsl_matrix_free(evec); +// gsl_matrix_free(A); +//} + + + + + + + + diff --git a/sm/lib/gpc/gpc.c b/src/gpc/gpc.cpp similarity index 87% rename from sm/lib/gpc/gpc.c rename to src/gpc/gpc.cpp index 97cb321..63fa715 100644 --- a/sm/lib/gpc/gpc.c +++ b/src/gpc/gpc.cpp @@ -17,40 +17,57 @@ */ #include <math.h> -#include <gsl/gsl_math.h> +//#include <gsl/gsl_math.h> +//#include <gsl/gsl_matrix.h> #include "gpc.h" #include "gpc_utils.h" +#include <gsl_eigen/gsl_eigen.h> +#include <stdio.h> +#include <vector> +using namespace std; + +//original version /* Note that we use static values here so we don't need to evaluate that all the time */ -#define M(matrix, rows, col) static gsl_matrix*matrix=0; if(!matrix) matrix = gsl_matrix_alloc(rows,col); -#define MF(matrix) /*gsl_matrix_free(matrix)*/ +//#define M(matrix, rows, col) static gsl_matrix*matrix=0; if(!matrix) matrix = gsl_matrix_alloc(rows,col); +//#define MF(matrix) /*gsl_matrix_free(matrix)*/ + +//version to free the memory, slower +//#define M(matrix, rows, col) static gsl_matrix*matrix=0; if(!matrix) matrix = gsl_matrix_alloc(rows,col); +//#define MF(matrix) gsl_matrix_free(matrix); matrix=0; +//New version: have static Eigen variables and use pointers to these for compatibility +#define TAGME(name, tag) name##tag +#define M(matrix, rows, col) static Eigen::MatrixXd TAGME(matrix,_mem)(rows, col); static gsl_matrix* matrix=&TAGME(matrix,_mem); +#define MF(matrix) -int gpc_solve(int K, const struct gpc_corr*c, + +int gpc_solve(int K, const std::vector<gpc_corr>& c, const double*x0, const double *cov_x0, - double *x_out) + double *x_out) { + (void) x0; (void) cov_x0; M(bigM, 4,4); M(g, 4,1); M(bigM_k,2,4); M(bigM_k_t,4,2); M(C_k,2,2); M(q_k, 2,1); M(temp41, 4,1); M(temp22,2,2); M(temp22b,2,2); M(temp42, 4,2); M(temp44,4,4); M(temp21, 2,1); M(temp22c, 2,2); M(temp12,1,2); - + gsl_matrix_set_zero(bigM); gsl_matrix_set_zero(g); gsl_matrix_set_zero(temp42); - + double d_bigM[4][4] = { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}; double d_g[4] = {0, 0, 0, 0}; int k; for(k=0;k<K;k++) { if(!c[k].valid) continue; - + double C00 = c[k].C[0][0]; double C01 = c[k].C[0][1]; double C10 = c[k].C[1][0]; double C11 = c[k].C[1][1]; - + if(C01 != C10) { fprintf(stderr, "k=%d; I expect C to be a symmetric matrix.\n", k); return 0; @@ -65,25 +82,25 @@ int gpc_solve(int K, const struct gpc_corr*c, return 0; } #endif - + double qx = c[k].q[0]; double qy = c[k].q[1]; double px = c[k].p[0]; double py = c[k].p[1]; - + /* [ C00, c01, px C00 + c01 py , c01 px - py C00 ] */ d_bigM[0][0] += C00; d_bigM[0][1] += C01; d_bigM[0][2] += +px * C00 + py * C01; d_bigM[0][3] += -py * C00 + px * C01; - + /* [ C10 , C11 , py C11 + px C10 , px C11 - py C10 ] */ d_bigM[1][0] += C10; d_bigM[1][1] += C11; d_bigM[1][2] += +px * C10 + py * C11; d_bigM[1][3] += +px * C11 - py * C10; - - /*Col 1 = [ py C10 + px C00 ] + + /*Col 1 = [ py C10 + px C00 ] Col 2 = [ py C11 + c01 px ] Col 3 = [ py (py C11 + px C10) + px (px C00 + c01 py) ] Col 4 = [ py (px C11 - py C10) + px (c01 px - py C00) ] @@ -93,7 +110,7 @@ int gpc_solve(int K, const struct gpc_corr*c, d_bigM[2][2] += (px*px)*(+C00) + (px*py)*(+C10+C01) + (py*py)*(+C11); d_bigM[2][3] += (px*px)*(+C01) + (px*py)*(-C00+C11) + (py*py)*(-C10); - /*Col 1 = [ px C10 - py C00 ] + /*Col 1 = [ px C10 - py C00 ] Col 2 = [ px C11 - c01 py ] Col 3 = [ px (py C11 + px C10) - py (px C00 + c01 py) ] Col 4 = [ px (px C11 - py C10) - py (c01 px - py C00) ]*/ @@ -101,7 +118,7 @@ int gpc_solve(int K, const struct gpc_corr*c, d_bigM[3][1] += -py * C01 + px * C11; d_bigM[3][2] += (px*px)*(+C10) + (px*py)*(-C00+C11) + (py*py)*(-C01); d_bigM[3][3] += (px*px)*(+C11) + (px*py)*(-C10-C01) + (py*py)*(+C00); - + d_g[0] += C00*qx+C10*qy; d_g[1] += C01*qx+C11*qy; d_g[2] += qx * (C00*px+C01*py) + qy * (C10*px+C11*py); @@ -111,14 +128,14 @@ int gpc_solve(int K, const struct gpc_corr*c, { unsigned int a,b; - for(a=0;a<4;a++) + for(a=0;a<4;a++) *gsl_matrix_ptr(g, a, 0) = -2 * d_g[a]; - for(a=0;a<4;a++) + for(a=0;a<4;a++) for(b=0;b<4;b++) gsl_matrix_set(bigM, a, b, 2 * d_bigM[a][b]); } - + M(mA,2,2); gms(mA,0,0, gmg(bigM,0,0)); gms(mA,0,1, gmg(bigM,0,1)); gms(mA,1,0, gmg(bigM,1,0)); gms(mA,1,1, gmg(bigM,1,1)); M(mB,2,2); gms(mB,0,0, gmg(bigM,0,2)); gms(mB,0,1, gmg(bigM,0,3)); @@ -128,22 +145,22 @@ int gpc_solve(int K, const struct gpc_corr*c, M(mS,2,2); M(mSa,2,2); - + /* mS = mD - mB.trans * mA.inv * mB; temp22b = inv(A) */ - m_inv(mA, temp22b); + m_inv(mA, temp22b); /* temp22c = inv(A) * mB */ m_mult(temp22b, mB, temp22c); /* temp22 = mB' */ - m_trans(mB, temp22); - m_mult(temp22, temp22c, temp22b); + m_trans(mB, temp22); + m_mult(temp22, temp22c, temp22b); m_scale(-1.0,temp22b); m_add(mD,temp22b,mS); - + /* mSa = mS.inv * mS.det; */ m_inv(mS, mSa); m_scale(m_det(mS), mSa); - + if(TRACE_ALGO) { m_display("mA",mA); m_display("mB",mB); @@ -155,7 +172,7 @@ int gpc_solve(int K, const struct gpc_corr*c, M(g1,2,1); M(g2,2,1); M(g1t,1,2); M(g2t,1,2); M(mAi,2,2); M(mBt,2,2); - + gms(g1,0,0,gmg(g,0,0)); gms(g1,1,0,gmg(g,1,0)); gms(g2,0,0,gmg(g,2,0)); @@ -178,20 +195,20 @@ int gpc_solve(int K, const struct gpc_corr*c, m_mult(m1t,mSa,m2t); m_trans(m2t,m2); /* m3t = g2t*mSa */ - m_mult(g2t,mSa,m3t); + m_mult(g2t,mSa,m3t); m_trans(m3t,m3); - + double p[3] = { m_dot(m2t,m2) - 2*m_dot(m2t,m3) + m_dot(m3t,m3), 4*m_dot(m2t,m1) - 8*m_dot(m2t,g2) + 4*m_dot(g2t,m3), 4*m_dot(m1t,m1) - 8*m_dot(m1t,g2) + 4*m_dot(g2t,g2)}; double l[3] = {m_det(mS), 2*gmg(mS,0,0)+2*gmg(mS,1,1), 4}; - + /* q = p - l^2 */ - double q[5] = {p[0]-(l[0]*l[0]), p[1]-(2*l[1]*l[0]), + double q[5] = {p[0]-(l[0]*l[0]), p[1]-(2*l[1]*l[0]), p[2]-(l[1]*l[1]+2*l[0]*l[2]), -(2*l[2]*l[1]), -(l[2]*l[2])}; - + if(TRACE_ALGO) { fprintf(stderr, "p = %f %f %f \n", p[2], p[1], p[0]); fprintf(stderr, "l = %f %f %f \n", l[2], l[1], l[0]); @@ -207,49 +224,49 @@ int gpc_solve(int K, const struct gpc_corr*c, double lambdas_error[4]; double lambdas_pose[4][3]; - + for(int i=0;i<4;i++) { double lambda = lambdas[i]; - + if(TRACE_ALGO) { fprintf(stderr, "lambda = %f \n", lambda); - } - + } + M(W,4,4); gsl_matrix_set_zero(W); gms(W,2,2,1.0); gms(W,3,3,1.0); M(x,4,1); - + m_scale(2*lambda, W); gsl_matrix_add(bigM,W); m_inv(bigM, temp44); m_mult(temp44, g, x); m_scale(-1.0, x); - + lambdas_pose[i][0] = gmg(x,0,0); lambdas_pose[i][1] = gmg(x,1,0); lambdas_pose[i][2] = atan2(gmg(x,3,0),gmg(x,2,0)); - + lambdas_error[i] = gpc_total_error(c, K, lambdas_pose[i]); } - + int lowest_error = 0; for(int i=0;i<4;i++) { printf("#%d lambda=%lf error=%lf\n",i,lambdas[i],lambdas_error[i]); if(lambdas_error[i] < lambdas_error[lowest_error]) lowest_error = i; } - + double lr; poly_greatest_real_root(5,q,&lr); printf("Choose %d: lambda = %lf bigger real root = %lf \n",lowest_error,lambdas[lowest_error],lr); - + x_out[0]=lambdas_pose[lowest_error][0]; x_out[1]=lambdas_pose[lowest_error][1]; x_out[2]=lambdas_pose[lowest_error][2]; */ - + double lambda; if(!poly_greatest_real_root(5, q, &lambda)) return 0; - + M(W,4,4); gsl_matrix_set_zero(W); gms(W,2,2,1.0); gms(W,3,3,1.0); M(x,4,1); @@ -266,7 +283,7 @@ int gpc_solve(int K, const struct gpc_corr*c, if(TRACE_ALGO) { fprintf(stderr, "x = %f %f %f deg\n", x_out[0], x_out[1],x_out[2]*180/M_PI); } - + MF(mA); MF(mB); MF(mD); MF(mS); MF(mSa); MF(m1t); MF(m1); MF(m2t); MF(m2); MF(m3t); MF(m3); MF(W); MF(x); @@ -289,7 +306,7 @@ double gpc_error(const struct gpc_corr*co, const double*x) { e[0] = c*(co->p[0]) -s*(co->p[1]) + x[0] - co->q[0]; e[1] = s*(co->p[0]) +c*(co->p[1]) + x[1] - co->q[1]; double this_error = e[0]*e[0]*co->C[0][0]+2*e[0]*e[1]*co->C[0][1]+e[1]*e[1]*co->C[1][1]; - + if(0) /* due to limited numerical precision, error might be negative */ if(this_error < 0) { fprintf(stderr, "Something fishy: error = %lf e = [%lf %lf] C = [%lf,%lf;%lf,%lf]\n", this_error, @@ -298,11 +315,12 @@ double gpc_error(const struct gpc_corr*co, const double*x) { return this_error; } -double gpc_total_error(const struct gpc_corr*co, int n, const double*x){ +double gpc_total_error(const std::vector<gpc_corr>& co, int n, const double*x){ + int i; double error = 0; - for(int i=0;i<n;i++) { + for(i=0;i<n;i++) { if(!co[i].valid) continue; - error += gpc_error(co+i,x); + error += gpc_error(&(co.at(i)),x); } if(0) /* due to limited numerical precision, error might be negative */ if(error<0) { diff --git a/sm/lib/gpc/gpc.h b/src/gpc/gpc.h similarity index 91% rename from sm/lib/gpc/gpc.h rename to src/gpc/gpc.h index 5e23614..c524309 100644 --- a/sm/lib/gpc/gpc.h +++ b/src/gpc/gpc.h @@ -20,6 +20,8 @@ #ifndef H_GENERAL_POINT_CORRESPONDENCE #define H_GENERAL_POINT_CORRESPONDENCE +#include <vector> + struct gpc_corr { double p[2]; double q[2]; @@ -46,7 +48,7 @@ struct gpc_corr { #define GPC_CHECK_SEMIDEF 0 /** if c[k].valid is 0, the correspondence is not used */ -int gpc_solve(int K, const struct gpc_corr*, +int gpc_solve(int K, const std::vector<gpc_corr>&, const double*x0, const double *cov_x0, double *x); @@ -55,6 +57,6 @@ int gpc_solve(int K, const struct gpc_corr*, /** Computes error for a single correspondence */ double gpc_error(const struct gpc_corr*co, const double*x); - double gpc_total_error(const struct gpc_corr*co, int n, const double*x); + double gpc_total_error(const std::vector<gpc_corr>& co, int n, const double*x); #endif diff --git a/src/gpc/gpc_utils.cpp b/src/gpc/gpc_utils.cpp new file mode 100644 index 0000000..5051fe0 --- /dev/null +++ b/src/gpc/gpc_utils.cpp @@ -0,0 +1,170 @@ +#include "gpc.h" +#include "gpc_utils.h" +#include <stdio.h> +#include <iostream> +using namespace std; + +#include <unsupported/Eigen/Polynomials> + +void m_trans(const gsl_matrix*A, gsl_matrix*A_t){ + //gsl_matrix_transpose_memcpy(A_t,A); + *A_t = A->transpose(); +} + +void m_mult(const gsl_matrix*A, const gsl_matrix*B, gsl_matrix*AB){ + //gsl_blas_dgemm(CblasNoTrans,CblasNoTrans,1.0,A,B,0.0,AB); + *AB = *A * *B; +} + +//void m_add_to(const gsl_matrix*A, gsl_matrix*B){ +// gsl_matrix_add(B, A); +//} + +void m_scale(double m, gsl_matrix*A){ + gsl_matrix_scale(A,m); +} + +void m_add (const gsl_matrix*A, const gsl_matrix*B, gsl_matrix*ApB){ + gsl_matrix_memcpy(ApB,A); + gsl_matrix_add(ApB,B); +} + +void m_inv(const gsl_matrix*A, gsl_matrix*invA) { +// unsigned int n = A->rows(); +// gsl_matrix * m = gsl_matrix_alloc(n,n); +// gsl_matrix_memcpy(m,A); +// gsl_permutation * perm = gsl_permutation_alloc (n); +// /* Make LU decomposition of matrix m */ +// int s; +// gsl_linalg_LU_decomp (m, perm, &s); +// /* Invert the matrix m */ +// gsl_linalg_LU_invert (m, perm, invA); +// gsl_permutation_free(perm); +// gsl_matrix_free(m); + + *invA = A->inverse(); +} + +double m_det(const gsl_matrix*A) { +// unsigned int n = A->rows(); +// gsl_matrix * m = gsl_matrix_alloc(n,n); +// gsl_matrix_memcpy(m,A); +// gsl_permutation * perm = gsl_permutation_alloc (n); +// int sign; +// gsl_linalg_LU_decomp (m, perm, &sign); +// double det = gsl_linalg_LU_det(m, sign); +// +// gsl_permutation_free(perm); +// gsl_matrix_free(m); +// return det; + return A->determinant(); +} + +double m_dot(const gsl_matrix*A,const gsl_matrix*B) { + double sum = 0; + unsigned int j; + for(j=0;j<A->cols();j++) + sum += gmg(A,0,j)*gmg(B,j,0); + return sum; +} + +//int poly_real_roots(unsigned int n, const double*a, double *roots) { +// double z[(n-1)*2]; +// gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc(n); +// if(GSL_SUCCESS != gsl_poly_complex_solve (a, n, w, z)) { +// return 0; +// } +// gsl_poly_complex_workspace_free (w); +// +// unsigned int i=0; +// for(i=0;i<n-1;i++) { +// roots[i] = z[2*i]; +// } +// return 1; +//} + + +int poly_greatest_real_root(unsigned int n, const double*a, double *root) { +// unsigned int i; +// +// double z[(n-1)*2]; +// gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc(n); +// if(GSL_SUCCESS != gsl_poly_complex_solve (a, n, w, z)) { +// return 0; +// } +// gsl_poly_complex_workspace_free (w); +// if(TRACE_ALGO) { +// printf("Solving the equation\n a = ["); +// for(i=0;i<n;i++) { +// printf("%lf ", a[i]); +// } +// printf("]\n"); +// } +// +// double lambda = 0; int assigned = 0; +// for (i = 0; i < n-1; i++) { +// if(TRACE_ALGO) { +// fprintf (stderr, "root z%d = %+.18f + %+.18f i \n", i, z[2*i], z[2*i+1]); +// } +///* XXX ==0 is bad */ +// if( z[2*i+1]==0 ) /* real root */ +// if(!assigned || (z[2*i]>lambda)) { +// assigned = 1; +// lambda = z[2*i]; +// } +// } + + Eigen::VectorXd poly_coeffs(n); + for(unsigned int i=0; i<n; i++){ + poly_coeffs(i) = a[i]; + } + if(n!=5){ + std::cerr<<"ERROR: WRONG DEGREE POLYNOMIAL TO SOLVE."<<std::endl; + return 0; + } + Eigen::PolynomialSolver<double, 4> psolve(poly_coeffs); + + //std::cerr<<"dims "<<psolve.roots().rows()<<" "<<psolve.roots().cols()<<std::endl; + Eigen::Matrix<std::complex<double>, 4, 1, 0, 4, 1> eigen_roots = psolve.roots(); + + int assigned = 0; + double lambda = 0; + for(unsigned int i=0; i<eigen_roots.size(); i++){ + if(eigen_roots(i).imag() == 0){ + if(!assigned || eigen_roots(i).real() > lambda) { + assigned = 1; + lambda = eigen_roots(i).real(); + } + } + } + + if(TRACE_ALGO) + fprintf (stderr, "lambda = %+.18f \n", lambda); + if(!assigned) { + fprintf(stderr, "poly_greatest_real_root: Could not find real root for polynomial.\n"); + fprintf(stderr, "polynomial coefficients : "); + for (int i = 0; i < n; i++) + fprintf(stderr, " %lf ", a[i]); + fprintf(stderr, "\nRoots:\n"); + + for (int i = 0; i < n-1; i++) + fprintf (stderr, "root z%d = %+.18f + %+.18f i \n", i, eigen_roots(i).real(), eigen_roots(i).imag()); + + return 0; + } + + *root = lambda; + return 1; +} + +void m_display(const char*str, gsl_matrix*m) { + printf("%s= \n", str); + unsigned int i,j; + for(i=0;i<m->rows();i++) { + printf(" "); + for(j=0;j<m->cols();j++) + printf("%e ", gmg(m,i,j)); + printf("\n"); + } +} + diff --git a/sm/lib/gpc/gpc_utils.h b/src/gpc/gpc_utils.h similarity index 74% rename from sm/lib/gpc/gpc_utils.h rename to src/gpc/gpc_utils.h index 40bf032..f08139e 100644 --- a/sm/lib/gpc/gpc_utils.h +++ b/src/gpc/gpc_utils.h @@ -1,10 +1,12 @@ #ifndef H_GPC_UTILS #define H_GPC_UTILS -#include <gsl/gsl_matrix.h> -#include <gsl/gsl_blas.h> -#include <gsl/gsl_linalg.h> -#include <gsl/gsl_poly.h> +//#include <gsl/gsl_matrix.h> +//#include <gsl/gsl_blas.h> +//#include <gsl/gsl_linalg.h> +//#include <gsl/gsl_poly.h> + +#include <gsl_eigen/gsl_eigen.h> /* The GSL is a pain to work with. The library DOES NOT HAVE a determinant() function or an inv() function: you have to write your own routines. */ @@ -15,14 +17,14 @@ void m_trans(const gsl_matrix*A, gsl_matrix*A_t); void m_mult(const gsl_matrix*A, const gsl_matrix*B, gsl_matrix*AB); void m_add(const gsl_matrix*A, const gsl_matrix*B, gsl_matrix*ApB); -void m_add_to(const gsl_matrix*A, gsl_matrix*B); +//void m_add_to(const gsl_matrix*A, gsl_matrix*B); void m_scale(double m, gsl_matrix*A); double m_dot(const gsl_matrix*A,const gsl_matrix*B); void m_inv(const gsl_matrix*A, gsl_matrix*invA); double m_det(const gsl_matrix*A); /* Returns the real part of the roots in roots */ -int poly_real_roots(unsigned int n, const double*a, double *roots); +//int poly_real_roots(unsigned int n, const double*a, double *roots); int poly_greatest_real_root(unsigned int n, const double*a, double *root); diff --git a/sm/csm/icp/icp.c b/src/icp/icp.cpp similarity index 89% rename from sm/csm/icp/icp.c rename to src/icp/icp.cpp index 4472ea2..4d5f987 100644 --- a/sm/csm/icp/icp.c +++ b/src/icp/icp.cpp @@ -1,18 +1,19 @@ #include <math.h> #include <string.h> -#include <gsl/gsl_matrix.h> +//#include <gsl/gsl_matrix.h> +#include <gsl_eigen/gsl_eigen.h> -#include <gpc/gpc.h> +//#include <gpc/gpc.h> #include <egsl/egsl_macros.h> -#include "../csm_all.h" +#include "../csm/csm_all.h" #include "icp.h" void sm_journal_open(const char* file) { - file = 0; + file = 0; (void) file; /* journal_open(file);*/ } @@ -51,8 +52,6 @@ void sm_icp(struct sm_params*params, struct sm_result*res) { count_equal(laser_ref->valid, laser_ref->nrays, 1), laser_ref->nrays, params->min_reading, params->max_reading); - if(JJ) jj_context_enter("sm_icp"); - egsl_push_named("sm_icp"); @@ -69,9 +68,6 @@ void sm_icp(struct sm_params*params, struct sm_result*res) { ld_compute_orientation(laser_sens, params->orientation_neighbourhood, params->sigma); } - if(JJ) jj_add("laser_ref", ld_to_json(laser_ref)); - if(JJ) jj_add("laser_sens", ld_to_json(laser_sens)); - gsl_vector * x_new = gsl_vector_alloc(3); gsl_vector * x_old = vector_from_array(3, params->first_guess); @@ -89,12 +85,11 @@ void sm_icp(struct sm_params*params, struct sm_result*res) { double error; int iterations; int nvalid; - if(!icp_loop(params, x_old->data, x_new->data, &error, &nvalid, &iterations)) { + if(!icp_loop(params, x_old->data(), x_new->data(), &error, &nvalid, &iterations)) { sm_error("icp: ICP failed for some reason. \n"); res->valid = 0; res->iterations = iterations; res->nvalid = 0; - } else { /* It was succesfull */ @@ -124,7 +119,7 @@ void sm_icp(struct sm_params*params, struct sm_result*res) { gvs(start, 2, gvg(x_new,2)+perturb[a][2]); gsl_vector * x_a = gsl_vector_alloc(3); double my_error; int my_valid; int my_iterations; - if(!icp_loop(&my_params, start->data, x_a->data, &my_error, &my_valid, &my_iterations)){ + if(!icp_loop(&my_params, start->data(), x_a->data(), &my_error, &my_valid, &my_iterations)){ sm_error("Error during restart #%d/%d. \n", a, 6); break; } @@ -161,13 +156,13 @@ void sm_icp(struct sm_params*params, struct sm_result*res) { res->dx_dy2_m = egsl_v2gslm(dx_dy2); if(0) { - egsl_print("cov0_x", cov0_x); - egsl_print_spectrum("cov0_x", cov0_x); + //egsl_print("cov0_x", cov0_x); + //egsl_print_spectrum("cov0_x", cov0_x); val fim = ld_fisher0(laser_ref); val ifim = inv(fim); egsl_print("fim", fim); - egsl_print_spectrum("ifim", ifim); + //egsl_print_spectrum("ifim", ifim); } } @@ -180,8 +175,10 @@ void sm_icp(struct sm_params*params, struct sm_result*res) { gsl_vector_free(x_new); gsl_vector_free(x_old); - egsl_pop_named("sm_icp"); - if(JJ) jj_context_exit(); +} + +void csm_free_unused_memory(){ + egsl_free_unused_memory(); } diff --git a/sm/csm/icp/icp.h b/src/icp/icp.h similarity index 97% rename from sm/csm/icp/icp.h rename to src/icp/icp.h index 298bfcd..1b0f6a4 100644 --- a/sm/csm/icp/icp.h +++ b/src/icp/icp.h @@ -1,9 +1,9 @@ #ifndef _H_ICP_ #define _H_ICP_ -#include <gpc/gpc.h> -#include "../csm_all.h" +//#include <gpc/gpc.h> +#include <csm/csm_all.h> /** This sets the stage. */ void sm_icp(struct sm_params*params, struct sm_result*res); diff --git a/sm/csm/icp/icp_corr_dumb.c b/src/icp/icp_corr_dumb.cpp similarity index 93% rename from sm/csm/icp/icp_corr_dumb.c rename to src/icp/icp_corr_dumb.cpp index 025b89a..4cb490a 100644 --- a/sm/csm/icp/icp_corr_dumb.c +++ b/src/icp/icp_corr_dumb.cpp @@ -1,7 +1,8 @@ -#include <gsl/gsl_vector.h> +//#include <gsl/gsl_vector.h> +#include <gsl_eigen/gsl_eigen.h> #include "icp.h" -#include "../csm_all.h" +#include "../csm/csm_all.h" int compatible(struct sm_params*params, int i, int j); @@ -94,7 +95,7 @@ void find_correspondences(struct sm_params*params) { ld_set_correspondence(laser_sens, i, j1, j2); laser_sens->corr[i].dist2_j1 = best_dist; laser_sens->corr[i].type = - params->use_point_to_line_distance ? corr_pl : corr_pp; + params->use_point_to_line_distance ? correspondence::corr_pl : correspondence::corr_pp; } diff --git a/sm/csm/icp/icp_corr_tricks.c b/src/icp/icp_corr_tricks.cpp similarity index 96% rename from sm/csm/icp/icp_corr_tricks.c rename to src/icp/icp_corr_tricks.cpp index 3cdef2d..5d5010d 100644 --- a/sm/csm/icp/icp_corr_tricks.c +++ b/src/icp/icp_corr_tricks.cpp @@ -1,10 +1,11 @@ -#include <gsl/gsl_vector.h> +//#include <gsl/gsl_vector.h> +#include <gsl_eigen/gsl_eigen.h> #include "icp.h" -#include "../csm_all.h" +#include "../csm/csm_all.h" /** This is very close (but *less* than) to sin(x), for - x in (0, PI/2). It's a 5° degree taylor expansion. */ + x in (0, PI/2). It's a 5� degree taylor expansion. */ INLINE double mysin(double x) { const double a = -1.0/6.0; const double b = +1.0/120.0; @@ -47,9 +48,6 @@ INLINE double local_distance_squared_d(const double* a, const double* b) { return x*x + y*y; } -#include "fast_math.h" - - #define SQUARE(a) ((a)*(a)) /* Assumes that points_w is filled. */ @@ -224,7 +222,7 @@ void find_correspondences_tricks(struct sm_params*params) { laser_sens->corr[i].j2 = j2; laser_sens->corr[i].dist2_j1 = best_dist; laser_sens->corr[i].type = - params->use_point_to_line_distance ? corr_pl : corr_pp; + params->use_point_to_line_distance ? correspondence::corr_pl : correspondence::corr_pp; } } diff --git a/sm/csm/icp/icp_covariance.c b/src/icp/icp_covariance.cpp similarity index 97% rename from sm/csm/icp/icp_covariance.c rename to src/icp/icp_covariance.cpp index 3d4db64..c0f3736 100644 --- a/sm/csm/icp/icp_covariance.c +++ b/src/icp/icp_covariance.cpp @@ -1,9 +1,8 @@ #include <math.h> -#include <gsl/gsl_math.h> #include <egsl/egsl_macros.h> #include "icp.h" -#include "../csm_all.h" +#include "../csm/csm_all.h" val compute_C_k(val p_j1, val p_j2); @@ -24,8 +23,8 @@ void compute_covariance_exact( val d2J_dt_dtheta = zeros(2,1); val d2J_dtheta2 = zeros(1,1); - double theta = x->data[2]; - val t = egsl_vFa(2,x->data); + double theta = x->data()[2]; + val t = egsl_vFa(2,x->data()); int i; for(i=0;i<laser_sens->nrays;i++) { diff --git a/sm/csm/icp/icp_debug.c b/src/icp/icp_debug.cpp similarity index 78% rename from sm/csm/icp/icp_debug.c rename to src/icp/icp_debug.cpp index f4d761b..3bd37ca 100644 --- a/sm/csm/icp/icp_debug.c +++ b/src/icp/icp_debug.cpp @@ -1,13 +1,18 @@ #include <string.h> #include "icp.h" +#include <vector> void debug_correspondences(struct sm_params * params) { LDP laser_sens = params->laser_sens; /** Do the test */ find_correspondences_tricks(params); - struct correspondence c1[laser_sens->nrays]; + //struct correspondence c1[laser_sens->nrays]; + std::vector<correspondence> c1; + c1.reserve(laser_sens->nrays); + struct correspondence * c2 = laser_sens->corr; - memcpy(c1, c2, sizeof(struct correspondence) * laser_sens->nrays); + //memcpy(c1, c2, sizeof(struct correspondence) * laser_sens->nrays); + c1.assign(c2, c2+laser_sens->nrays); long hash1 = ld_corr_hash(laser_sens); find_correspondences(params); long hash2 = ld_corr_hash(laser_sens); diff --git a/sm/csm/icp/icp_loop.c b/src/icp/icp_loop.cpp similarity index 91% rename from sm/csm/icp/icp_loop.c rename to src/icp/icp_loop.cpp index f64d17a..4b1b7fd 100644 --- a/sm/csm/icp/icp_loop.c +++ b/src/icp/icp_loop.cpp @@ -1,14 +1,15 @@ #include <math.h> #include <string.h> -#include <gsl/gsl_matrix.h> - +//#include <gsl/gsl_matrix.h> +#include <gsl_eigen/gsl_eigen.h> #include <gpc/gpc.h> #include <egsl/egsl_macros.h> -#include "../csm_all.h" +#include "../csm/csm_all.h" #include "icp.h" +#include <vector> int icp_loop(struct sm_params*params, const double*q0, double*x_new, double*total_error, int*valid, int*iterations) { @@ -21,19 +22,15 @@ int icp_loop(struct sm_params*params, const double*q0, double*x_new, LDP laser_sens = params->laser_sens; double x_old[3], delta[3], delta_old[3] = {0,0,0}; copy_d(q0, 3, x_old); - unsigned int hashes[params->max_iterations]; + //unsigned int hashes[params->max_iterations]; + std::vector<unsigned int> hashes(params->max_iterations, 0); int iteration; sm_debug("icp: starting at q0 = %s \n", friendly_pose(x_old)); - if(JJ) jj_loop_enter("iterations"); - int all_is_okay = 1; for(iteration=0; iteration<params->max_iterations;iteration++) { - if(JJ) jj_loop_iteration(); - if(JJ) jj_add_double_array("x_old", x_old, 3); - egsl_push_named("icp_loop iteration"); sm_debug("== icp_loop: starting iteration. %d \n", iteration); @@ -62,28 +59,17 @@ int icp_loop(struct sm_params*params, const double*q0, double*x_new, break; } - if(JJ) jj_add("corr0", corr_to_json(laser_sens->corr, laser_sens->nrays)); - /* Kill some correspondences (using dubious algorithm) */ if(params->outliers_remove_doubles) kill_outliers_double(params); int num_corr2 = ld_num_valid_correspondences(laser_sens); - if(JJ) jj_add("corr1", corr_to_json(laser_sens->corr, laser_sens->nrays)); - double error=0; /* Trim correspondences */ kill_outliers_trim(params, &error); int num_corr_after = ld_num_valid_correspondences(laser_sens); - if(JJ) { - jj_add("corr2", corr_to_json(laser_sens->corr, laser_sens->nrays)); - jj_add_int("num_corr0", num_corr); - jj_add_int("num_corr1", num_corr2); - jj_add_int("num_corr2", num_corr_after); - } - *total_error = error; *valid = num_corr_after; @@ -109,10 +95,6 @@ int icp_loop(struct sm_params*params, const double*q0, double*x_new, { sm_debug(" icp_loop: killing. laser_sens has %d/%d rays valid, %d corr found -> %d after double cut -> %d after adaptive cut \n", count_equal(laser_sens->valid, laser_sens->nrays, 1), laser_sens->nrays, num_corr, num_corr2, num_corr_after); - if(JJ) { - jj_add_double_array("x_new", x_new, 3); - jj_add_double_array("delta", delta, 3); - } } /** Checks for oscillations */ hashes[iteration] = ld_corr_hash(laser_sens); @@ -155,8 +137,6 @@ int icp_loop(struct sm_params*params, const double*q0, double*x_new, egsl_pop_named("icp_loop iteration"); } - if(JJ) jj_loop_exit(); - *iterations = iteration+1; return all_is_okay; @@ -174,7 +154,9 @@ int compute_next_estimate(struct sm_params*params, LDP laser_ref = params->laser_ref; LDP laser_sens = params->laser_sens; - struct gpc_corr c[laser_sens->nrays]; + //struct gpc_corr c[laser_sens->nrays]; + struct gpc_corr dummy; + std::vector<gpc_corr> c(laser_sens->nrays, dummy); int i; int k=0; for(i=0;i<laser_sens->nrays;i++) { @@ -189,7 +171,7 @@ int compute_next_estimate(struct sm_params*params, c[k].valid = 1; - if(laser_sens->corr[i].type == corr_pl) { + if(laser_sens->corr[i].type == correspondence::corr_pl) { c[k].p[0] = laser_sens->points[i].p[0]; c[k].p[1] = laser_sens->points[i].p[1]; @@ -277,7 +259,7 @@ int compute_next_estimate(struct sm_params*params, sm_error("Param use_ml_weights was active, but not valid alpha[] or true_alpha[]." "Perhaps, if this is a single ray not having alpha, you should mark it as inactive.\n"); sm_error("Writing laser_ref: \n"); - ld_write_as_json(laser_ref, stderr); + /*ld_write_as_json(laser_ref, stderr);*/ warned_before = 1; } } @@ -292,7 +274,7 @@ int compute_next_estimate(struct sm_params*params, if(!warned_before) { sm_error("Param use_sigma_weights was active, but the field readings_sigma[] was not filled in.\n"); sm_error("Writing laser_sens: \n"); - ld_write_as_json(laser_sens, stderr); + /*ld_write_as_json(laser_sens, stderr);*/ } } } diff --git a/sm/csm/icp/icp_outliers.c b/src/icp/icp_outliers.cpp similarity index 79% rename from sm/csm/icp/icp_outliers.c rename to src/icp/icp_outliers.cpp index b4202e3..7c2e32a 100644 --- a/sm/csm/icp/icp_outliers.c +++ b/src/icp/icp_outliers.cpp @@ -1,14 +1,16 @@ #include <math.h> #include "icp.h" +#include <vector> -void quicksort(double *array, int begin, int end); +void quicksort(std::vector<double>& array, int begin, int end); double hoare_selection(double *data, int start, int end, int k); /** expects cartesian valid */ void visibilityTest(LDP laser_ref, const gsl_vector*u) { - double theta_from_u[laser_ref->nrays]; + //double theta_from_u[laser_ref->nrays]; + std::vector<double> theta_from_u(laser_ref->nrays, 0.0); int j; for(j=0;j<laser_ref->nrays;j++) { @@ -45,8 +47,10 @@ void kill_outliers_double(struct sm_params*params) { LDP laser_ref = params->laser_ref; LDP laser_sens = params->laser_sens; - double dist2_i[laser_sens->nrays]; - double dist2_j[laser_ref->nrays]; + //double dist2_i[laser_sens->nrays]; + std::vector<double> dist2_i(laser_sens->nrays, 0.0); + //double dist2_j[laser_ref->nrays]; + std::vector<double> dist2_j(laser_ref->nrays, 0.0); int j; for(j=0;j<laser_ref->nrays;j++) dist2_j[j]= 1000000; @@ -55,7 +59,7 @@ void kill_outliers_double(struct sm_params*params) { if(!ld_valid_corr(laser_sens, i)) continue; int j1 = laser_sens->corr[i].j1; dist2_i[i] = laser_sens->corr[i].dist2_j1; - dist2_j[j1] = GSL_MIN(dist2_j[j1], dist2_i[i]); + dist2_j[j1] = std::min(dist2_j[j1], dist2_i[i]); } int nkilled = 0; @@ -82,21 +86,21 @@ void kill_outliers_double(struct sm_params*params) { */ void kill_outliers_trim(struct sm_params*params, double*total_error) { - if(JJ) jj_context_enter("kill_outliers_trim"); - LDP laser_ref = params->laser_ref; LDP laser_sens = params->laser_sens; /* dist2, indexed by k, contains the error for the k-th correspondence */ int k = 0; - double dist2[laser_sens->nrays]; + //double dist2[laser_sens->nrays]; + std::vector<double> dist2(laser_sens->nrays, 0.0); int i; - double dist[laser_sens->nrays]; + //double dist[laser_sens->nrays]; + std::vector<double> dist(laser_sens->nrays, 0.0); /* for each point in laser_sens */ for(i=0;i<laser_sens->nrays;i++) { /* which has a valid correspondence */ - if(!ld_valid_corr(laser_sens, i)) { dist[i]=NAN; continue; } + if(!ld_valid_corr(laser_sens, i)) { dist[i]=std::numeric_limits<double>::quiet_NaN(); continue; } double *p_i_w = laser_sens->points_w[i].p; int j1 = laser_sens->corr[i].j1; @@ -109,9 +113,6 @@ void kill_outliers_trim(struct sm_params*params, double*total_error) { } - if(JJ) jj_add_int("num_valid_before", k); - if(JJ) jj_add_double_array("dist_points", dist2, laser_sens->nrays); - if(JJ) jj_add_double_array("dist_corr_unsorted", dist2, k); #if 0 double dist2_copy[k]; for(i=0;i<k;i++) dist2_copy[i] = dist2[i]; @@ -120,21 +121,20 @@ void kill_outliers_trim(struct sm_params*params, double*total_error) { /* two errors limits are defined: */ /* In any case, we don't want more than outliers_maxPerc% */ int order = (int)floor(k*(params->outliers_maxPerc)); - order = GSL_MAX(0, GSL_MIN(order, k-1)); + order = std::max(0, std::min(order, k-1)); /* The dists for the correspondence are sorted in ascending order */ quicksort(dist2, 0, k-1); double error_limit1 = dist2[order]; - if(JJ) jj_add_double_array("dist_corr_sorted", dist2, k); /* Then we take a order statics (o*K) */ /* And we say that the error must be less than alpha*dist(o*K) */ int order2 = (int)floor(k*params->outliers_adaptive_order); - order2 = GSL_MAX(0, GSL_MIN(order2, k-1)); + order2 = std::max(0, std::min(order2, k-1)); double error_limit2 = params->outliers_adaptive_mult*dist2[order2]; - double error_limit = GSL_MIN(error_limit1, error_limit2); + double error_limit = std::min(error_limit1, error_limit2); #if 0 double error_limit1_ho = hoare_selection(dist2_copy, 0, k-1, order); @@ -145,11 +145,6 @@ void kill_outliers_trim(struct sm_params*params, double*total_error) { } #endif - if(JJ) jj_add_double_array("dist_corr_sorted", dist2, k); - if(JJ) jj_add_double("error_limit_max_perc", error_limit1); - if(JJ) jj_add_double("error_limit_adaptive", error_limit2); - if(JJ) jj_add_double("error_limit", error_limit); - sm_debug("\ticp_outliers: maxPerc %f error_limit: fix %f adaptive %f \n", params->outliers_maxPerc,error_limit1,error_limit2); @@ -169,12 +164,6 @@ void kill_outliers_trim(struct sm_params*params, double*total_error) { sm_debug("\ticp_outliers: valid %d/%d (limit: %f) mean error = %f \n",nvalid,k,error_limit, *total_error/nvalid); - - if(JJ) jj_add_int("num_valid_after", nvalid); - if(JJ) jj_add_double("total_error", *total_error); - if(JJ) jj_add_double("mean_error", *total_error / nvalid); - - if(JJ) jj_context_exit(); } @@ -183,7 +172,7 @@ void swap_double(double*a,double*b) { } /** Code taken from Wikipedia */ -void quicksort(double *array, int begin, int end) { +void quicksort(std::vector<double>& array, int begin, int end) { if (end > begin) { double pivot = array[begin]; int l = begin + 1; @@ -193,11 +182,11 @@ void quicksort(double *array, int begin, int end) { l++; } else { r--; - swap_double(array+l, array+r); + swap_double(&(array[l]), &(array[r])); } } l--; - swap_double(array+begin, array+l); + swap_double(&(array[begin]), &(array[l])); if(l>begin) quicksort(array, begin, l); if(end>r) diff --git a/sm/lib/options/options.c b/src/options/options.cpp similarity index 74% rename from sm/lib/options/options.c rename to src/options/options.cpp index 04d3338..e61b2c4 100644 --- a/sm/lib/options/options.c +++ b/src/options/options.cpp @@ -15,12 +15,14 @@ #include <limits.h> #include <stdlib.h> #include <stdio.h> -#include <sys/param.h> +//#include <sys/param.h> #include <ctype.h> #include <sys/stat.h> -#include <unistd.h> -#include <libgen.h> +//#include <unistd.h> +//#include <libgen.h> #include <string.h> +#include <algorithm> +#include <vector> #include "options.h" @@ -84,9 +86,9 @@ int options_parse_args(struct option*ops, int argc, const char* argv[]) { fprintf(stderr, "Please specify config file.\n"); if(!options_tolerant) return 0; } - if(!options_parse_file(ops, ".", argv[i+1])) { - if(!options_tolerant) return 0; - } +// if(!options_parse_file(ops, ".", argv[i+1])) { +// if(!options_tolerant) return 0; +// } i++; continue; } @@ -128,91 +130,91 @@ int options_requires_argument(struct option*o) { } -int options_parse_stream(struct option*ops, const char*pwd, FILE*file) { - #define MAX_LINE_LENGTH 10000 - char linesto[MAX_LINE_LENGTH]; - while(fgets(linesto, MAX_LINE_LENGTH-1, file)) { - char *line=linesto; while(*line) { if(*line=='\n') *line=0; line++; } - line = linesto; - while(isspace(*line)) line++; - if(*line == '#') continue; - if(*line == '<') { line++; - while(isspace(*line)) line++; - if(!options_parse_file(ops, pwd, line)) { - if(!options_tolerant) return 0; - } - continue; - } - if(!*line) continue; - /* Here starts the name; later we put a terminating 0 */ - const char * name = line; - /* name continus until nonspace char */ - while(!isspace(*line)) line++; - - char empty[5] = ""; - char * value; - if(*line == 0) value = empty; else { - *line = 0; /* terminating 0 for name */ - line++; - /* ignore spaces */ - while(isspace(*line)) line++; - /* ignore possible "=" */ - if(*line == '=') line++; - /* ignore spaces */ - while(isspace(*line)) line++; - - /* here starts the value */ - value = line; - /* delete final spaces */ - int len = strlen(value); - while(isspace(value[len-1]) && len > 0) { - value[len-1] = 0; len--; - } - } - - if(!options_try_pair(ops, name, value) && !options_tolerant) { - return 0; - } - } - return 1; -} - -int options_parse_file(struct option*ops, const char*pwd, const char*filename) { - char concat[PATH_MAX*2+1]; - - if(filename[0] != '/') { - strcpy(concat, pwd); - strcat(concat, "/"); - strcat(concat, filename); - } else { - strcpy(concat, filename); - } - - char resolved_path[PATH_MAX]; - char *resolved; - if(! (resolved = realpath(concat, resolved_path))) { - fprintf(stderr, "Could not resolve '%s' ('%s').\n", concat, resolved); - return 0; - } - - const char * newdir = dirname(resolved); - if(!newdir) { - fprintf(stderr, "Could not get dirname for '%s'.\n", resolved); - free(resolved); - return 0; - } - - FILE * file; - file = fopen(resolved,"r"); - if(file==NULL) { - fprintf(stderr, "Could not open '%s': %s.\n", resolved, strerror(errno)); - /* free(resolved); */ - return 0; - } - - /* free(resolved); */ - return options_parse_stream(ops, newdir, file); -} +//int options_parse_stream(struct option*ops, const char*pwd, FILE*file) { +// #define MAX_LINE_LENGTH 10000 +// char linesto[MAX_LINE_LENGTH]; +// while(fgets(linesto, MAX_LINE_LENGTH-1, file)) { +// char *line=linesto; while(*line) { if(*line=='\n') *line=0; line++; } +// line = linesto; +// while(isspace(*line)) line++; +// if(*line == '#') continue; +// if(*line == '<') { line++; +// while(isspace(*line)) line++; +// if(!options_parse_file(ops, pwd, line)) { +// if(!options_tolerant) return 0; +// } +// continue; +// } +// if(!*line) continue; +// /* Here starts the name; later we put a terminating 0 */ +// const char * name = line; +// /* name continus until nonspace char */ +// while(!isspace(*line)) line++; +// +// char empty[5] = ""; +// char * value; +// if(*line == 0) value = empty; else { +// *line = 0; /* terminating 0 for name */ +// line++; +// /* ignore spaces */ +// while(isspace(*line)) line++; +// /* ignore possible "=" */ +// if(*line == '=') line++; +// /* ignore spaces */ +// while(isspace(*line)) line++; +// +// /* here starts the value */ +// value = line; +// /* delete final spaces */ +// int len = strlen(value); +// while(isspace(value[len-1]) && len > 0) { +// value[len-1] = 0; len--; +// } +// } +// +// if(!options_try_pair(ops, name, value) && !options_tolerant) { +// return 0; +// } +// } +// return 1; +//} + +//int options_parse_file(struct option*ops, const char*pwd, const char*filename) { +// char concat[PATH_MAX*2+1]; +// +// if(filename[0] != '/') { +// strcpy(concat, pwd); +// strcat(concat, "/"); +// strcat(concat, filename); +// } else { +// strcpy(concat, filename); +// } +// +// char resolved_path[PATH_MAX]; +// char *resolved; +// if(! (resolved = realpath(concat, resolved_path))) { +// fprintf(stderr, "Could not resolve '%s' ('%s').\n", concat, resolved); +// return 0; +// } +// +// const char * newdir = dirname(resolved); +// if(!newdir) { +// fprintf(stderr, "Could not get dirname for '%s'.\n", resolved); +// free(resolved); +// return 0; +// } +// +// FILE * file; +// file = fopen(resolved,"r"); +// if(file==NULL) { +// fprintf(stderr, "Could not open '%s': %s.\n", resolved, strerror(errno)); +// /* free(resolved); */ +// return 0; +// } +// +// /* free(resolved); */ +// return options_parse_stream(ops, newdir, file); +//} /** Finds an option in the array. Returns 0 if not found. */ @@ -275,7 +277,11 @@ int options_set(struct option*o, const char*value) { int * value_pointer = (int*) o->value_pointer; struct option_alternative * a = o->alternative; for(; a->label; a++) { +#ifndef WINDOWS if( !strcasecmp(a->label, value) ) { +#else + if( !stricmp(a->label, value) ) { +#endif *value_pointer = a->value; return 1; } @@ -304,14 +310,15 @@ int options_set(struct option*o, const char*value) { const char*options_value_as_string(struct option*o); void display_table(FILE*f, char**table, int rows, int columns, int padding) { - int col_size[columns]; + //int col_size[columns]; + std::vector<int> col_size(columns, 0); int i,j; for(j=0;j<columns;j++) { col_size[j]=0; for(i=0;i<rows;i++) { const char * s = table[j+i*columns]; - col_size[j] = MAX(col_size[j], (int) strlen(s)); + col_size[j] = (std::max)(col_size[j], (int) strlen(s)); } col_size[j] += padding; } @@ -333,7 +340,7 @@ void options_dump(struct option * options, FILE*f, int write_desc) { int n; for (n=0;options_valid(options+n);n++); int nrows = n + 2; - char**table = malloc(sizeof(char*)*nrows*3); + char**table = (char**) malloc(sizeof(char*)*nrows*3); int row = 0; if(write_desc) { @@ -396,7 +403,7 @@ void options_dump(struct option * options, FILE*f, int write_desc) { } void options_print_help(struct option * options, FILE*f) { - fprintf(f, options_banner_string); + fprintf(f, "%s", options_banner_string); fprintf(f, "Generic options: \n" " -help Displays this help.\n" diff --git a/sm/lib/options/options.h b/src/options/options.h similarity index 93% rename from sm/lib/options/options.h rename to src/options/options.h index 66ede29..335770d 100644 --- a/sm/lib/options/options.h +++ b/src/options/options.h @@ -3,9 +3,9 @@ #include <stdio.h> -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif /** User-friendly interface */ @@ -33,7 +33,7 @@ extern "C" { int options_parse_args(struct option*ops, int argc, const char* argv[]); /** Returns 0 on error */ - int options_parse_file(struct option*ops, const char*pwd, const char*file); + //int options_parse_file(struct option*ops, const char*pwd, const char*file); void options_print_help(struct option*ops, FILE*where); @@ -103,7 +103,7 @@ int options_valid(struct option*op); void options_dump(struct option * options, FILE*f, int write_desc); -int options_parse_stream(struct option*ops, const char*pwd, FILE*file); +//int options_parse_stream(struct option*ops, const char*pwd, FILE*file); /** Our version of strdup. */ char * strdup_(const char *s); @@ -116,9 +116,9 @@ struct option* options_next_empty(struct option*ops); -#ifdef __cplusplus -} -#endif +//#ifdef __cplusplus +//} +//#endif diff --git a/sm/lib/options/options_interface.c b/src/options/options_interface.cpp similarity index 96% rename from sm/lib/options/options_interface.c rename to src/options/options_interface.cpp index 05695ec..d1b5a08 100644 --- a/sm/lib/options/options_interface.c +++ b/src/options/options_interface.cpp @@ -15,7 +15,7 @@ struct option* options_allocate(int n) { n += 2; /* better safe than sorry */ - struct option* ops = malloc(sizeof(struct option)*n); + struct option* ops = (option*) malloc(sizeof(struct option)*n); int i; for(i=0;i<n;i++) { ops[i].name = 0; ops[i].type = (enum option_type) 0xbeef; diff --git a/website/.gitignore b/website/.gitignore deleted file mode 100644 index 53752db..0000000 --- a/website/.gitignore +++ /dev/null @@ -1 +0,0 @@ -output diff --git a/website/Makefile b/website/Makefile deleted file mode 100644 index 9b81763..0000000 --- a/website/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - -all: source/* - maruku source/index.md - cp source/* output - \ No newline at end of file diff --git a/website/init_website.sh b/website/init_website.sh deleted file mode 100755 index 36eb023..0000000 --- a/website/init_website.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -set -e -set -x -git clone git@github.com:AndreaCensi/csm.git output -cd output -git checkout origin/gh-pages -b gh-pages -git branch -D master - diff --git a/website/source/a.gif b/website/source/a.gif deleted file mode 100644 index 5379a170c4d2b6e6583277435c7318ec3cd9ad6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109136 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%0AHM4@fTQ8j3lgBVR|@ZV7=D#67nR9VWM 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 L-A13|;DG-d7!>zZ diff --git a/website/source/index.html b/website/source/index.html deleted file mode 100644 index 525f71b..0000000 --- a/website/source/index.html +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC - "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" - "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd"> -<html xmlns:svg='http://www.w3.org/2000/svg' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'> -<head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>The C(anonical) Scan Matcher</title></head> -<body> -<h1 id='the_canonical_scan_matcher'>The C(anonical) Scan Matcher</h1> - -<p><img src='sm_plicp_zoom_crop.gif' alt='PL-ICP' style='float: right; margin:1em;' /></p> - -<h3 id='news'>News</h3> - -<ul> -<li>Fall 2010: <a href='http://www.ros.org/wiki/canonical_scan_matcher'>CSM has been integrated and packaged</a> for <a href='http://www.ros.org/'>ROS</a> by <a href='http://robotics.ccny.cuny.edu/blog/People/Dryanovski'>Ivan Dryanovski</a>.</li> -</ul> - -<h3 id='download'>Download</h3> - -<ul> -<li> -<p>CSM can be download from GitHub (.zip package available) at the url:</p> - -<p><a href='http://github.com/AndreaCensi/csm'>http://github.com/AndreaCensi/csm</a></p> -</li> -</ul> - -<h3 id='documentation__getting_started'>Documentation / getting started</h3> - -<p>Please see the manual contained in “csm_manual.pdf”. See below for a quick description.</p> - -<p><strong>What is this.</strong> I created this package:</p> - -<ul> -<li> -<p>To have a well-documented reference implementation of <a href='http://purl.org/censi/2007/plicp'>PL-ICP</a>. If you are only interested in the core algorithm of PL-ICP, a <a href='http://purl.org/censi/2007/gpc'>separate concise implementation in C/Matlab/Ruby</a> is available.</p> -</li> - -<li> -<p>To have a <strong>trustworthy</strong> scan matcher to be used in the experiments for some papers on <a href='http://purl.org/censi/2006/icpcov'>ICP covariance</a>, <a href='http://purl.org/censi/2006/accuracy'>the Cramer-Rao bound for range finders</a>, and <a href='http://purl.org/censi/2007/calib'>robot calibration</a>. For batch experiments, it’s also useful that it’s pretty fast.</p> -</li> - -<li> -<p>To have a collection of utilies for command line (UNIX-style) manipulation of laser data, and creating <a href='../plicp/laserazosSM3.log.pdf'>beautiful maps</a> and animations.</p> -</li> -</ul> - -<p>The package contains also a Ruby wrapper for the C library, and additional Ruby and a Matlab implementations of the same algorithm. These are not as usable or documented as the C version.</p> - -<p><strong>What it is NOT</strong>: Note that this is not a full-featured SLAM solution: this only does pairwise scan-matching between scans (but it’s really good at it!). If you are looking for a more complete SLAM solution, please see the projects listed in the <a href='http://www.openslam.org'>OpenSLAM</a> page; in particular you can have a look at <a href='http://www.openslam.org/gmapping.html'>GMapping</a>. Many pointers to other SLAM software can be found on the pages of the Euron SLAM summer schools: <a href='http://www.cas.kth.se/SLAM/'>2002 (Stockholm)</a>, <a href='http://www.laas.fr/SLAM/'>2004 (Toulouse)</a>, <a href='http://www.robots.ox.ac.uk/~SSS06/Website/index.html'>2006 (Oxford)</a>. Other related projects are <a href='http://carmen.sourceforge.net/'>Carmen</a> and <a href='http://playerstage.sourceforge.net/'>Stage</a>.</p> -<hr /> -<p>Please link to this page using the url <a href='http://purl.org/censi/2007/csm'>http://purl.org/censi/2007/csm</a>.</p> -</body></html> diff --git a/website/source/index.md b/website/source/index.md deleted file mode 100644 index 064b082..0000000 --- a/website/source/index.md +++ /dev/null @@ -1,57 +0,0 @@ -The C(anonical) Scan Matcher -============================ - -{:style="float: right; margin:1em;"} - - -### News ### - -* Fall 2010: [CSM has been integrated and packaged][stack] for [ROS] by [Ivan Dryanovski][ivan]. - - -### Download ### - -* CSM can be download from GitHub (.zip package available) at the url: - - [http://github.com/AndreaCensi/csm](http://github.com/AndreaCensi/csm) - -[stack]: http://www.ros.org/wiki/canonical_scan_matcher -[ivan]: http://robotics.ccny.cuny.edu/blog/People/Dryanovski -[ROS]: http://www.ros.org/ - - -### Documentation / getting started ### - -Please see the manual contained in "csm_manual.pdf". See below for a quick description. - - -**What is this.** I created this package: - -- To have a well-documented reference implementation of [PL-ICP](http://purl.org/censi/2007/plicp). If you are only interested in the core algorithm of PL-ICP, a [separate concise implementation in C/Matlab/Ruby](http://purl.org/censi/2007/gpc) is available. - -- To have a **trustworthy** scan matcher to be used in the experiments for some papers on [ICP covariance](http://purl.org/censi/2006/icpcov), [the Cramer-Rao bound for range finders](http://purl.org/censi/2006/accuracy), and [robot calibration](http://purl.org/censi/2007/calib). For batch experiments, it's also useful that it's pretty fast. - -- To have a collection of utilies for command line (UNIX-style) manipulation of laser data, - and creating [beautiful maps][map-example] and animations. - -The package contains also a Ruby wrapper for the C library, and additional Ruby and a Matlab implementations of the same algorithm. These are not as usable or documented as the C version. - -**What it is NOT**: Note that this is not a full-featured SLAM solution: this only does pairwise scan-matching between scans (but it's really good at it!). -If you are looking for a more complete SLAM solution, please see the projects listed in the [OpenSLAM](http://www.openslam.org) page; in particular you can have a look at [GMapping]. -Many pointers to other SLAM software can be found on the pages of the Euron SLAM summer schools: -[2002 (Stockholm)](http://www.cas.kth.se/SLAM/), -[2004 (Toulouse)](http://www.laas.fr/SLAM/), -[2006 (Oxford)](http://www.robots.ox.ac.uk/~SSS06/Website/index.html). -Other related projects are [Carmen] and [Stage]. - -[map-example]: ../plicp/laserazosSM3.log.pdf - -[gmapping]: http://www.openslam.org/gmapping.html -[carmen]: http://carmen.sourceforge.net/ -[stage]: http://playerstage.sourceforge.net/ - - - ------------ - -Please link to this page using the url <http://purl.org/censi/2007/csm>. \ No newline at end of file diff --git a/website/source/sm_icp_zoom_crop.gif b/website/source/sm_icp_zoom_crop.gif deleted file mode 100644 index dda33c638427060efc58bc2691c5f5a68c435e84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 381500 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%0AKD1@O7v6PP>^A77@D!n)lt+EY#V6_)d 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≪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≫C7`g8 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 aaexOCE^PQP;>3y<Gj8noF=WI60RTH^^!FzK diff --git a/website/source/sm_plicp_zoom_crop.gif b/website/source/sm_plicp_zoom_crop.gif deleted file mode 100644 index 3701f9f952e9021e7312d06fcd3b15747d5309e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97030 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�TU(Z<Qi&B!+<%wN3On( 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 Q;9R5L@r83g1WxGx05SdPr~m)} -- GitLab