From 3b993e70b3d3334b35f9090aaad5d691a65b5179 Mon Sep 17 00:00:00 2001 From: Ugo Pattacini Date: Thu, 10 Jul 2014 16:16:48 +0200 Subject: [PATCH] doxygen added --- doxygen/doc/html/bc_s.png | Bin 0 -> 676 bytes doxygen/doc/html/bdwn.png | Bin 0 -> 147 bytes doxygen/doc/html/closed.png | Bin 0 -> 132 bytes .../dir_0485f0c3e5fc27f1b21a0a793d715761.html | 78 + .../dir_29c9db2f94dd348f3d685c9fccd668c5.html | 78 + .../dir_2c4c692e0e93e67fe6dacb9253ee9a1d.html | 78 + .../dir_41f00478989b00c299e09b5f630aa3f5.html | 84 + .../dir_68267d1309a1af8e8297ef4c3efbcdba.html | 86 + .../dir_7487e53a8124ea55fc67b4fc4eb7b40c.html | 78 + .../dir_a61e44ac46e7253a0943cfd762c184f9.html | 78 + .../dir_d5fc9e74ecd446ba07279cb903928e76.html | 84 + .../dir_db5aab25642573dc60c61c7a424e232a.html | 82 + .../dir_f234616accb428072e31fe708f34c8ab.html | 78 + .../dir_fc03fb402f9f2a4202506acbbf0a4b9a.html | 78 + .../dir_fe78f95ef73225985cbb37ca6fe2b4d3.html | 82 + doxygen/doc/html/doc.png | Bin 0 -> 746 bytes doxygen/doc/html/doxygen.css | 1793 ++++++++++++ doxygen/doc/html/doxygen.png | Bin 0 -> 3779 bytes doxygen/doc/html/doxygen.svg | 26 + doxygen/doc/html/dynsections.js | 128 + doxygen/doc/html/files.html | 103 + doxygen/doc/html/folderclosed.png | Bin 0 -> 616 bytes doxygen/doc/html/folderopen.png | Bin 0 -> 597 bytes doxygen/doc/html/form_0.png | Bin 0 -> 229 bytes doxygen/doc/html/formula.repository | 1 + doxygen/doc/html/group__karmaLearn.html | 128 + doxygen/doc/html/group__karmaMotor.html | 132 + doxygen/doc/html/group__karmaToolFinder.html | 139 + .../doc/html/group__karmaToolProjection.html | 102 + doxygen/doc/html/index.html | 74 + doxygen/doc/html/jquery.js | 35 + .../html/karmaLearn_2main_8cpp_source.html | 723 +++++ ...ager_2include_2iCub_2module_8h_source.html | 220 ++ ...nager_2include_2iCub_2utils_8h_source.html | 141 + .../karmaManager_2src_2main_8cpp_source.html | 121 + ...karmaManager_2src_2module_8cpp_source.html | 1771 ++++++++++++ .../karmaManager_2src_2utils_8cpp_source.html | 177 ++ .../html/karmaMotor_2main_8cpp_source.html | 1165 ++++++++ .../karmaToolFinder_2main_8cpp_source.html | 872 ++++++ ...tion_2include_2iCub_2module_8h_source.html | 152 + ...ction_2include_2iCub_2utils_8h_source.html | 138 + ...ToolProjection_2src_2main_8cpp_source.html | 116 + ...olProjection_2src_2module_8cpp_source.html | 402 +++ ...oolProjection_2src_2utils_8cpp_source.html | 124 + doxygen/doc/html/menu.js | 51 + doxygen/doc/html/menudata.js | 29 + doxygen/doc/html/modules.html | 82 + doxygen/doc/html/nav_f.png | Bin 0 -> 153 bytes doxygen/doc/html/nav_g.png | Bin 0 -> 95 bytes doxygen/doc/html/nav_h.png | Bin 0 -> 98 bytes doxygen/doc/html/open.png | Bin 0 -> 123 bytes doxygen/doc/html/search/all_0.html | 37 + doxygen/doc/html/search/all_0.js | 4 + doxygen/doc/html/search/all_1.html | 37 + doxygen/doc/html/search/all_1.js | 4 + doxygen/doc/html/search/all_2.html | 37 + doxygen/doc/html/search/all_2.js | 5 + doxygen/doc/html/search/close.png | Bin 0 -> 273 bytes doxygen/doc/html/search/close.svg | 31 + doxygen/doc/html/search/groups_0.html | 37 + doxygen/doc/html/search/groups_0.js | 4 + doxygen/doc/html/search/groups_1.html | 37 + doxygen/doc/html/search/groups_1.js | 4 + doxygen/doc/html/search/groups_2.html | 37 + doxygen/doc/html/search/groups_2.js | 5 + doxygen/doc/html/search/mag_sel.png | Bin 0 -> 465 bytes doxygen/doc/html/search/mag_sel.svg | 74 + doxygen/doc/html/search/nomatches.html | 13 + doxygen/doc/html/search/search.css | 257 ++ doxygen/doc/html/search/search.js | 816 ++++++ doxygen/doc/html/search/search_l.png | Bin 0 -> 567 bytes doxygen/doc/html/search/search_m.png | Bin 0 -> 158 bytes doxygen/doc/html/search/search_r.png | Bin 0 -> 553 bytes doxygen/doc/html/search/searchdata.js | 18 + doxygen/doc/html/splitbar.png | Bin 0 -> 314 bytes doxygen/doc/html/sync_off.png | Bin 0 -> 853 bytes doxygen/doc/html/sync_on.png | Bin 0 -> 845 bytes doxygen/doc/html/tab_a.png | Bin 0 -> 142 bytes doxygen/doc/html/tab_b.png | Bin 0 -> 169 bytes doxygen/doc/html/tab_h.png | Bin 0 -> 177 bytes doxygen/doc/html/tab_s.png | Bin 0 -> 184 bytes doxygen/doc/html/tabs.css | 1 + doxygen/doc/latex/Makefile | 43 + .../dir_0485f0c3e5fc27f1b21a0a793d715761.tex | 2 + .../dir_29c9db2f94dd348f3d685c9fccd668c5.tex | 2 + .../dir_2c4c692e0e93e67fe6dacb9253ee9a1d.tex | 2 + .../dir_41f00478989b00c299e09b5f630aa3f5.tex | 7 + .../dir_68267d1309a1af8e8297ef4c3efbcdba.tex | 9 + .../dir_7487e53a8124ea55fc67b4fc4eb7b40c.tex | 2 + .../dir_a61e44ac46e7253a0943cfd762c184f9.tex | 2 + .../dir_d5fc9e74ecd446ba07279cb903928e76.tex | 7 + .../dir_db5aab25642573dc60c61c7a424e232a.tex | 5 + .../dir_f234616accb428072e31fe708f34c8ab.tex | 2 + .../dir_fc03fb402f9f2a4202506acbbf0a4b9a.tex | 2 + .../dir_fe78f95ef73225985cbb37ca6fe2b4d3.tex | 5 + doxygen/doc/latex/doxygen.sty | 576 ++++ doxygen/doc/latex/group__karmaLearn.tex | 64 + doxygen/doc/latex/group__karmaMotor.tex | 62 + doxygen/doc/latex/group__karmaToolFinder.tex | 71 + .../doc/latex/group__karmaToolProjection.tex | 29 + doxygen/doc/latex/longtable_doxygen.sty | 448 +++ doxygen/doc/latex/make.bat | 28 + doxygen/doc/latex/modules.tex | 7 + doxygen/doc/latex/refman.tex | 186 ++ doxygen/doc/latex/tabu_doxygen.sty | 2557 +++++++++++++++++ doxygen/generate.txt | 1257 ++++++++ index.html | 15 + 107 files changed, 16757 insertions(+) create mode 100644 doxygen/doc/html/bc_s.png create mode 100644 doxygen/doc/html/bdwn.png create mode 100644 doxygen/doc/html/closed.png create mode 100644 doxygen/doc/html/dir_0485f0c3e5fc27f1b21a0a793d715761.html create mode 100644 doxygen/doc/html/dir_29c9db2f94dd348f3d685c9fccd668c5.html create mode 100644 doxygen/doc/html/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.html create mode 100644 doxygen/doc/html/dir_41f00478989b00c299e09b5f630aa3f5.html create mode 100644 doxygen/doc/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html create mode 100644 doxygen/doc/html/dir_7487e53a8124ea55fc67b4fc4eb7b40c.html create mode 100644 doxygen/doc/html/dir_a61e44ac46e7253a0943cfd762c184f9.html create mode 100644 doxygen/doc/html/dir_d5fc9e74ecd446ba07279cb903928e76.html create mode 100644 doxygen/doc/html/dir_db5aab25642573dc60c61c7a424e232a.html create mode 100644 doxygen/doc/html/dir_f234616accb428072e31fe708f34c8ab.html create mode 100644 doxygen/doc/html/dir_fc03fb402f9f2a4202506acbbf0a4b9a.html create mode 100644 doxygen/doc/html/dir_fe78f95ef73225985cbb37ca6fe2b4d3.html create mode 100644 doxygen/doc/html/doc.png create mode 100644 doxygen/doc/html/doxygen.css create mode 100644 doxygen/doc/html/doxygen.png create mode 100644 doxygen/doc/html/doxygen.svg create mode 100644 doxygen/doc/html/dynsections.js create mode 100644 doxygen/doc/html/files.html create mode 100644 doxygen/doc/html/folderclosed.png create mode 100644 doxygen/doc/html/folderopen.png create mode 100644 doxygen/doc/html/form_0.png create mode 100644 doxygen/doc/html/formula.repository create mode 100644 doxygen/doc/html/group__karmaLearn.html create mode 100644 doxygen/doc/html/group__karmaMotor.html create mode 100644 doxygen/doc/html/group__karmaToolFinder.html create mode 100644 doxygen/doc/html/group__karmaToolProjection.html create mode 100644 doxygen/doc/html/index.html create mode 100644 doxygen/doc/html/jquery.js create mode 100644 doxygen/doc/html/karmaLearn_2main_8cpp_source.html create mode 100644 doxygen/doc/html/karmaManager_2include_2iCub_2module_8h_source.html create mode 100644 doxygen/doc/html/karmaManager_2include_2iCub_2utils_8h_source.html create mode 100644 doxygen/doc/html/karmaManager_2src_2main_8cpp_source.html create mode 100644 doxygen/doc/html/karmaManager_2src_2module_8cpp_source.html create mode 100644 doxygen/doc/html/karmaManager_2src_2utils_8cpp_source.html create mode 100644 doxygen/doc/html/karmaMotor_2main_8cpp_source.html create mode 100644 doxygen/doc/html/karmaToolFinder_2main_8cpp_source.html create mode 100644 doxygen/doc/html/karmaToolProjection_2include_2iCub_2module_8h_source.html create mode 100644 doxygen/doc/html/karmaToolProjection_2include_2iCub_2utils_8h_source.html create mode 100644 doxygen/doc/html/karmaToolProjection_2src_2main_8cpp_source.html create mode 100644 doxygen/doc/html/karmaToolProjection_2src_2module_8cpp_source.html create mode 100644 doxygen/doc/html/karmaToolProjection_2src_2utils_8cpp_source.html create mode 100644 doxygen/doc/html/menu.js create mode 100644 doxygen/doc/html/menudata.js create mode 100644 doxygen/doc/html/modules.html create mode 100644 doxygen/doc/html/nav_f.png create mode 100644 doxygen/doc/html/nav_g.png create mode 100644 doxygen/doc/html/nav_h.png create mode 100644 doxygen/doc/html/open.png create mode 100644 doxygen/doc/html/search/all_0.html create mode 100644 doxygen/doc/html/search/all_0.js create mode 100644 doxygen/doc/html/search/all_1.html create mode 100644 doxygen/doc/html/search/all_1.js create mode 100644 doxygen/doc/html/search/all_2.html create mode 100644 doxygen/doc/html/search/all_2.js create mode 100644 doxygen/doc/html/search/close.png create mode 100644 doxygen/doc/html/search/close.svg create mode 100644 doxygen/doc/html/search/groups_0.html create mode 100644 doxygen/doc/html/search/groups_0.js create mode 100644 doxygen/doc/html/search/groups_1.html create mode 100644 doxygen/doc/html/search/groups_1.js create mode 100644 doxygen/doc/html/search/groups_2.html create mode 100644 doxygen/doc/html/search/groups_2.js create mode 100644 doxygen/doc/html/search/mag_sel.png create mode 100644 doxygen/doc/html/search/mag_sel.svg create mode 100644 doxygen/doc/html/search/nomatches.html create mode 100644 doxygen/doc/html/search/search.css create mode 100644 doxygen/doc/html/search/search.js create mode 100644 doxygen/doc/html/search/search_l.png create mode 100644 doxygen/doc/html/search/search_m.png create mode 100644 doxygen/doc/html/search/search_r.png create mode 100644 doxygen/doc/html/search/searchdata.js create mode 100644 doxygen/doc/html/splitbar.png create mode 100644 doxygen/doc/html/sync_off.png create mode 100644 doxygen/doc/html/sync_on.png create mode 100644 doxygen/doc/html/tab_a.png create mode 100644 doxygen/doc/html/tab_b.png create mode 100644 doxygen/doc/html/tab_h.png create mode 100644 doxygen/doc/html/tab_s.png create mode 100644 doxygen/doc/html/tabs.css create mode 100644 doxygen/doc/latex/Makefile create mode 100644 doxygen/doc/latex/dir_0485f0c3e5fc27f1b21a0a793d715761.tex create mode 100644 doxygen/doc/latex/dir_29c9db2f94dd348f3d685c9fccd668c5.tex create mode 100644 doxygen/doc/latex/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.tex create mode 100644 doxygen/doc/latex/dir_41f00478989b00c299e09b5f630aa3f5.tex create mode 100644 doxygen/doc/latex/dir_68267d1309a1af8e8297ef4c3efbcdba.tex create mode 100644 doxygen/doc/latex/dir_7487e53a8124ea55fc67b4fc4eb7b40c.tex create mode 100644 doxygen/doc/latex/dir_a61e44ac46e7253a0943cfd762c184f9.tex create mode 100644 doxygen/doc/latex/dir_d5fc9e74ecd446ba07279cb903928e76.tex create mode 100644 doxygen/doc/latex/dir_db5aab25642573dc60c61c7a424e232a.tex create mode 100644 doxygen/doc/latex/dir_f234616accb428072e31fe708f34c8ab.tex create mode 100644 doxygen/doc/latex/dir_fc03fb402f9f2a4202506acbbf0a4b9a.tex create mode 100644 doxygen/doc/latex/dir_fe78f95ef73225985cbb37ca6fe2b4d3.tex create mode 100644 doxygen/doc/latex/doxygen.sty create mode 100644 doxygen/doc/latex/group__karmaLearn.tex create mode 100644 doxygen/doc/latex/group__karmaMotor.tex create mode 100644 doxygen/doc/latex/group__karmaToolFinder.tex create mode 100644 doxygen/doc/latex/group__karmaToolProjection.tex create mode 100644 doxygen/doc/latex/longtable_doxygen.sty create mode 100644 doxygen/doc/latex/make.bat create mode 100644 doxygen/doc/latex/modules.tex create mode 100644 doxygen/doc/latex/refman.tex create mode 100644 doxygen/doc/latex/tabu_doxygen.sty create mode 100644 doxygen/generate.txt create mode 100644 index.html diff --git a/doxygen/doc/html/bc_s.png b/doxygen/doc/html/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2 GIT binary patch literal 676 zcmV;V0$crwP)y__>=_9%My z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3 zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o% zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2 zBrW#G7Ss9wvzr@>H*`r>zE z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66 zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000< KMNUMnLSTYoA~SLT literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/bdwn.png b/doxygen/doc/html/bdwn.png new file mode 100644 index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C2wk~_T1|%O$WD@{V-kvUwAr*{o@8{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/dir_0485f0c3e5fc27f1b21a0a793d715761.html b/doxygen/doc/html/dir_0485f0c3e5fc27f1b21a0a793d715761.html new file mode 100644 index 0000000..acb296d --- /dev/null +++ b/doxygen/doc/html/dir_0485f0c3e5fc27f1b21a0a793d715761.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/include/iCub Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
iCub Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_29c9db2f94dd348f3d685c9fccd668c5.html b/doxygen/doc/html/dir_29c9db2f94dd348f3d685c9fccd668c5.html new file mode 100644 index 0000000..e4253b7 --- /dev/null +++ b/doxygen/doc/html/dir_29c9db2f94dd348f3d685c9fccd668c5.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolFinder Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
karmaToolFinder Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.html b/doxygen/doc/html/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.html new file mode 100644 index 0000000..f04a2fc --- /dev/null +++ b/doxygen/doc/html/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/include/iCub Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
iCub Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_41f00478989b00c299e09b5f630aa3f5.html b/doxygen/doc/html/dir_41f00478989b00c299e09b5f630aa3f5.html new file mode 100644 index 0000000..51a8060 --- /dev/null +++ b/doxygen/doc/html/dir_41f00478989b00c299e09b5f630aa3f5.html @@ -0,0 +1,84 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
karmaToolProjection Directory Reference
+
+
+ + + + +

+Directories

directory  include
 
+
+ + + + diff --git a/doxygen/doc/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/doxygen/doc/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html new file mode 100644 index 0000000..0ca7874 --- /dev/null +++ b/doxygen/doc/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -0,0 +1,86 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+ + + + + + +

+Directories

directory  karmaManager
 
directory  karmaToolProjection
 
+
+ + + + diff --git a/doxygen/doc/html/dir_7487e53a8124ea55fc67b4fc4eb7b40c.html b/doxygen/doc/html/dir_7487e53a8124ea55fc67b4fc4eb7b40c.html new file mode 100644 index 0000000..c582ab1 --- /dev/null +++ b/doxygen/doc/html/dir_7487e53a8124ea55fc67b4fc4eb7b40c.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_a61e44ac46e7253a0943cfd762c184f9.html b/doxygen/doc/html/dir_a61e44ac46e7253a0943cfd762c184f9.html new file mode 100644 index 0000000..dba53eb --- /dev/null +++ b/doxygen/doc/html/dir_a61e44ac46e7253a0943cfd762c184f9.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaMotor Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
karmaMotor Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_d5fc9e74ecd446ba07279cb903928e76.html b/doxygen/doc/html/dir_d5fc9e74ecd446ba07279cb903928e76.html new file mode 100644 index 0000000..c02d3d2 --- /dev/null +++ b/doxygen/doc/html/dir_d5fc9e74ecd446ba07279cb903928e76.html @@ -0,0 +1,84 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
karmaManager Directory Reference
+
+
+ + + + +

+Directories

directory  include
 
+
+ + + + diff --git a/doxygen/doc/html/dir_db5aab25642573dc60c61c7a424e232a.html b/doxygen/doc/html/dir_db5aab25642573dc60c61c7a424e232a.html new file mode 100644 index 0000000..2725d66 --- /dev/null +++ b/doxygen/doc/html/dir_db5aab25642573dc60c61c7a424e232a.html @@ -0,0 +1,82 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/include Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
include Directory Reference
+
+
+ + +

+Directories

+
+ + + + diff --git a/doxygen/doc/html/dir_f234616accb428072e31fe708f34c8ab.html b/doxygen/doc/html/dir_f234616accb428072e31fe708f34c8ab.html new file mode 100644 index 0000000..02c4771 --- /dev/null +++ b/doxygen/doc/html/dir_f234616accb428072e31fe708f34c8ab.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaLearn Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
karmaLearn Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_fc03fb402f9f2a4202506acbbf0a4b9a.html b/doxygen/doc/html/dir_fc03fb402f9f2a4202506acbbf0a4b9a.html new file mode 100644 index 0000000..cc6db87 --- /dev/null +++ b/doxygen/doc/html/dir_fc03fb402f9f2a4202506acbbf0a4b9a.html @@ -0,0 +1,78 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+
+ + + + diff --git a/doxygen/doc/html/dir_fe78f95ef73225985cbb37ca6fe2b4d3.html b/doxygen/doc/html/dir_fe78f95ef73225985cbb37ca6fe2b4d3.html new file mode 100644 index 0000000..a42b4b8 --- /dev/null +++ b/doxygen/doc/html/dir_fe78f95ef73225985cbb37ca6fe2b4d3.html @@ -0,0 +1,82 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/include Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
include Directory Reference
+
+
+ + +

+Directories

+
+ + + + diff --git a/doxygen/doc/html/doc.png b/doxygen/doc/html/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501 GIT binary patch literal 746 zcmV7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$)) zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!nw*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=} zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXRbTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$ z8v{MfJbTiiRg4bza<41NAzrl{=3fl_D+$t+^!xlQ8S}{UtY`e z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D? z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3 z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3OR*Hvj+t literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/doxygen.css b/doxygen/doc/html/doxygen.css new file mode 100644 index 0000000..ffbff02 --- /dev/null +++ b/doxygen/doc/html/doxygen.css @@ -0,0 +1,1793 @@ +/* The standard CSS for doxygen 1.9.1 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.navtab { + border-right: 1px solid #A3B4D7; + padding-right: 15px; + text-align: right; + line-height: 110%; +} + +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} +td.navtabHL { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; + width: 100%; + line-height: 140%; + font-size: 130%; + color: #A0A0A0; +} + +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: black; +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.odd { + background-color: #F8F9FC; +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +.contents a.qindexHL:visited { + color: #FFFFFF; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #FFFFFF; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; + text-align:right; + width:52px; +} + +dl.citelist dd { + margin:2px 0 2px 72px; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +.DocNodeRTL { + text-align: right; + direction: rtl; +} + +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/doxygen/doc/html/doxygen.png b/doxygen/doc/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff17d807fd8aa003bed8bb2a69e8f0909592fd1 GIT binary patch literal 3779 zcmV;!4m|ORP)tMIv#Q0*~7*`IBSO7_x;@a8#Zk6_PeKR_s92J&)(m+);m9Iz3blw)z#Gi zP!9lj4$%+*>Hz@HCmM9L9|8c+0u=!H$O3?R0Kgx|#WP<6fKfC8fM-CQZT|_r@`>VO zX^Hgb|9cJqpdJA5$MCEK`F_2@2Y@s>^+;pF`~jdI0Pvr|vl4`=C)EH@1IFe7pdJ8F zH(qGi004~QnF)Ggga~8v08kGAs2hKTATxr7pwfNk|4#_AaT>w8P6TV+R2kbS$v==} zAjf`s0g#V8lB+b3)5oEI*q+{Yt$MZDruD2^;$+(_%Qn+%v0X-bJO=;@kiJ^ygLBnC z?1OVv_%aex1M@jKU|Z~$eI?PoF4Vj>fDzyo zAiLfpXY*a^Sj-S5D0S3@#V$sRW)g)_1e#$%8xdM>Jm7?!h zu0P2X=xoN>^!4DoPRgph2(2va07yfpXF+WH7EOg1GY%Zn z7~1A<(z7Q$ktEXhW_?GMpHp9l_UL18F3KOsxu81pqoBiNbFSGsof-W z6~eloMoz=4?OOnl2J268x5rOY`dCk0us(uS#Ud4yqOr@?=Q57a}tit|BhY>}~frH1sP`ScHS_d)oqH^lYy zZ%VP`#10MlE~P?cE(%(#(AUSv_T{+;t@$U}El}(1ig`vZo`Rm;+5&(AYzJ^Ae=h2X z@Re%vHwZU>|f0NI&%$*4eJweC5OROQrpPMA@*w|o z()A==l}(@bv^&>H1Ob3C=<^|hob?0+xJ?QQ3-ueQC}zy&JQNib!OqSO@-=>XzxlSF zAZ^U*1l6EEmg3r};_HY>&Jo_{dOPEFTWPmt=U&F#+0(O59^UIlHbNX+eF8UzyDR*T z(=5X$VF3!gm@RooS-&iiUYGG^`hMR(07zr_xP`d!^BH?uD>Phl8Rdifx3Af^Zr`Ku ztL+~HkVeL#bJ)7;`=>;{KNRvjmc}1}c58Sr#Treq=4{xo!ATy|c>iRSp4`dzMMVd@ zL8?uwXDY}Wqgh4mH`|$BTXpUIu6A1-cSq%hJw;@^Zr8TP=GMh*p(m(tN7@!^D~sl$ zz^tf4II4|};+irE$Fnm4NTc5%p{PRA`%}Zk`CE5?#h3|xcyQsS#iONZ z6H(@^i9td!$z~bZiJLTax$o>r(p}3o@< zyD7%(>ZYvy=6$U3e!F{Z`uSaYy`xQyl?b{}eg|G3&fz*`QH@mDUn)1%#5u`0m$%D} z?;tZ0u(mWeMV0QtzjgN!lT*pNRj;6510Wwx?Yi_=tYw|J#7@(Xe7ifDzXuK;JB;QO z#bg~K$cgm$@{QiL_3yr}y&~wuv=P=#O&Tj=Sr)aCUlYmZMcw?)T?c%0rUe1cS+o!qs_ zQ6Gp)-{)V!;=q}llyK3|^WeLKyjf%y;xHku;9(vM!j|~<7w1c*Mk-;P{T&yG) z@C-8E?QPynNQ<8f01D`2qexcVEIOU?y}MG)TAE6&VT5`rK8s(4PE;uQ92LTXUQ<>^ ztyQ@=@kRdh@ebUG^Z6NWWIL;_IGJ2ST>$t!$m$qvtj0Qmw8moN6GUV^!QKNK zHBXCtUH8)RY9++gH_TUV4^=-j$t}dD3qsN7GclJ^Zc&(j6&a_!$jCf}%c5ey`pm~1)@{yI3 zTdWyB+*X{JFw#z;PwRr5evb2!ueWF;v`B0HoUu4-(~aL=z;OXUUEtG`_$)Oxw6FKg zEzY`CyKaSBK3xt#8gA|r_|Kehn_HYVBMpEwbn9-fI*!u*eTA1ef8Mkl1=!jV4oYwWYM}i`A>_F4nhmlCIC6WLa zY%;4&@AlnaG11ejl61Jev21|r*m+?Kru3;1tFDl}#!OzUp6c>go4{C|^erwpG*&h6bspUPJag}oOkN2912Y3I?(eRc@U9>z#HPBHC?nps7H5!zP``90!Q1n80jo+B3TWXp!8Pe zwuKuLLI6l3Gv@+QH*Y}2wPLPQ1^EZhT#+Ed8q8Wo z1pTmIBxv14-{l&QVKxAyQF#8Q@NeJwWdKk>?cpiJLkJr+aZ!Me+Cfp!?FWSRf^j2k z73BRR{WSKaMkJ>1Nbx5dan5hg^_}O{Tj6u%iV%#QGz0Q@j{R^Ik)Z*+(YvY2ziBG)?AmJa|JV%4UT$k`hcOg5r9R?5>?o~JzK zJCrj&{i#hG>N7!B4kNX(%igb%kDj0fOQThC-8mtfap82PNRXr1D>lbgg)dYTQ(kbx z`Ee5kXG~Bh+BHQBf|kJEy6(ga%WfhvdQNDuOfQoe377l#ht&DrMGeIsI5C<&ai zWG$|hop2@@q5YDa)_-A?B02W;#fH!%k`daQLEItaJJ8Yf1L%8x;kg?)k)00P-lH+w z)5$QNV6r2$YtnV(4o=0^3{kmaXn*Dm0F*fU(@o)yVVjk|ln8ea6BMy%vZAhW9|wvA z8RoDkVoMEz1d>|5(k0Nw>22ZT){V<3$^C-cN+|~hKt2)){+l-?3m@-$c?-dlzQ)q- zZ)j%n^gerV{|+t}9m1_&&Ly!9$rtG4XX|WQ8`xYzGC~U@nYh~g(z9)bdAl#xH)xd5a=@|qql z|FzEil{P5(@gy!4ek05i$>`E^G~{;pnf6ftpLh$h#W?^#4UkPfa;;?bsIe&kz!+40 zI|6`F2n020)-r`pFaZ38F!S-lJM-o&inOw|66=GMeP@xQU5ghQH{~5Uh~TMTd;I9` z>YhVB`e^EVj*S7JF39ZgNf}A-0DwOcTT63ydN$I3b?yBQtUI*_fae~kPvzoD$zjX3 zoqBe#>12im4WzZ=f^4+u=!lA|#r%1`WB0-6*3BL#at`47#ebPpR|D1b)3BjT34nYY z%Ds%d?5$|{LgOIaRO{{oC&RK`O91$fqwM0(C_TALcozu*fWHb%%q&p-q{_8*2Zsi^ zh1ZCnr^UYa;4vQEtHk{~zi>wwMC5o{S=$P0X681y`SXwFH?Ewn{x-MOZynmc)JT5v zuHLwh;tLfxRrr%|k370}GofLl7thg>ACWWY&msqaVu&ry+`7+Ss>NL^%T1|z{IGMA zW-SKl=V-^{(f!Kf^#3(|T2W47d(%JVCI4JgRrT1pNz>+ietmFToNv^`gzC@&O-)+i zPQ~RwK8%C_vf%;%e>NyTp~dM5;!C|N0Q^6|CEb7Bw=Vz~$1#FA;Z*?mKSC)Hl-20s t8QyHj(g6VK0RYbl8UjE)0O0w=e*@m04r>stuEhWV002ovPDHLkV1hl;dM*F} literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/doxygen.svg b/doxygen/doc/html/doxygen.svg new file mode 100644 index 0000000..d42dad5 --- /dev/null +++ b/doxygen/doc/html/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doxygen/doc/html/dynsections.js b/doxygen/doc/html/dynsections.js new file mode 100644 index 0000000..88f2c27 --- /dev/null +++ b/doxygen/doc/html/dynsections.js @@ -0,0 +1,128 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + 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 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. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +karma: File List + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+
[detail level 12345]
+ + + + + + + + + + + + + + + + + + + + + + + + + +
  src
  karmaLearn
 main.cpp
  karmaManager
  include
  iCub
 module.h
 utils.h
  src
 main.cpp
 module.cpp
 utils.cpp
  karmaMotor
 main.cpp
  karmaToolFinder
 main.cpp
  karmaToolProjection
  include
  iCub
 module.h
 utils.h
  src
 main.cpp
 module.cpp
 utils.cpp
+
+
+ + + + diff --git a/doxygen/doc/html/folderclosed.png b/doxygen/doc/html/folderclosed.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66 GIT binary patch literal 616 zcmV-u0+;=XP)a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6` zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM zlFX`g{k$X}yIe%$N)cn1LNu=q9_CS)*>A zsX_mM4L@`(cSNQKMFc$RtYbx{79#j-J7hk*>*+ZZhM4Hw?I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000IqP)X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e= zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2 zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+! zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z( zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa( z0QgYgTWqf1qN++Gqp z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/form_0.png b/doxygen/doc/html/form_0.png new file mode 100644 index 0000000000000000000000000000000000000000..d13a5eea090a85dea31849f3ea8619c4df8cde74 GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^{6NgZ!3-q3=7?VdQU(D&A+A80BoJjU!wu9RP!i-9 z%%JBHo8QnsZ_Uo5m+rp&@_$wOhW9|Z5KkA!kP61Pa|4AM6gXVOU4^@L{Lc+uwq>6c zqp{BChE{Ec1NoaIPwTBtj23@>a$egM_RZxNx8C>5o3{Vkb&EHPgb(L+6>f1iU4LNV g%YW`Ji>FvrF!stYuCQ@sc@1)`r>mdKI;Vst0EVnWv;Y7A literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/formula.repository b/doxygen/doc/html/formula.repository new file mode 100644 index 0000000..e2278f8 --- /dev/null +++ b/doxygen/doc/html/formula.repository @@ -0,0 +1 @@ +\_form#0:$ R $ diff --git a/doxygen/doc/html/group__karmaLearn.html b/doxygen/doc/html/group__karmaLearn.html new file mode 100644 index 0000000..b45be4e --- /dev/null +++ b/doxygen/doc/html/group__karmaLearn.html @@ -0,0 +1,128 @@ + + + + + + + +karma: Learning module of the KARMA Experiment + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Learning module of the KARMA Experiment
+
+
+ +

Machine Learning Module that allows the robot to learn online and predict a one-to-one map. +

+

Machine Learning Module that allows the robot to learn online and predict a one-to-one map.

+

+Description

+

This module belongs to the suite of KARMA software and is responsible for learning a generic map from $ R $ to $ R $.

+

+Libraries

+
    +
  • YARP libraries.
  • +
  • learningMachine library.
  • +
+

+Parameters

+

–context context

    +
  • To specify the module's context.
  • +
+

–from file

    +
  • To specify the module's configuration file.
  • +
+

+Ports Created

+
    +
  • /karmaLearn/rpc remote procedure call.
    + Recognized remote commands:
      +
    • [train] "item" <in> <out>: issue the module to train internal machines with the input-output pair for the given item. The reply is [nack]/[ack].
    • +
    • [predict] "item" <in>: retrieve the predicted output for the specified input. The reply is [nack]/[ack] <out> <variance>, where the variance is meaningful only if not negative. In case the input command is of the form [predict] "item" (<in0> <in1> ...), the prediction is returned for the values contained in the list and the reply will look like ack (<variance0> <variance1> ...).
    • +
    • [span] "item" <step>: retrieve the predicted output for a given range of input specified by the parameter step. The reply is [nack]/ack (<variance0> <variance1> ...). The second parameter can be omitted and an internal default step size is used.
    • +
    • [optimize] "item" [<step>]|[(<val0> <val1> ...)]: for the specified item a search with the given step, or alternatively over the given list of input values, is performed in order to find out the input that elicits the maximum output. The reply is [nack]/[ack] <in> <out>. The second parameter can be omitted and an internal default step size is used.
    • +
    • [items]: retrieve the name of the items currently handled by the module.
    • +
    • [machine] "item": retrieve the content of the machine contained within the database that serves to represent the input-output relation of the given item.
    • +
    • [clear] "item": remove the item from the internal machines database. If no argument is given, clean up the whole database content. The reply is [nack]/[ack].
    • +
    • [save]: save the content of the internal machines database within the configuration file. The reply is [ack].
    • +
    • [plot] "item" <step>: stream out a yarp image displaying the map learned for the specified item as computed over the domain explored with the given step.
    • +
    +
  • +
+

/karmaLearn/plot:o streams out images containing the learned maps.

+

+Configuration Files

+

The configuration file passed through the option –from looks like as follows:

+
[general]
+
name karmaLearn // the module's stem-name
+
num_items 0 // the number of items
+
in_lb 0.0 // scaler lower bound in
+
in_ub 360.0 // scaler upper bound in
+
out_lb 0.0 // scaler lower bound out
+
out_ub 2.0 // scaler upper bound out
+

Moreover, once some learning has been carried out, the configuration file will be filled with the sections corresponding to the items.

+

+Tested OS

+

Windows, Linux

+
Author
Ugo Pattacini
+
+ + + + diff --git a/doxygen/doc/html/group__karmaMotor.html b/doxygen/doc/html/group__karmaMotor.html new file mode 100644 index 0000000..722072f --- /dev/null +++ b/doxygen/doc/html/group__karmaMotor.html @@ -0,0 +1,132 @@ + + + + + + + +karma: Motor Part of the KARMA Experiment + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Motor Part of the KARMA Experiment
+
+
+ +

Motor Control Module that allows the robot to push/draw the object and explore a tool. +

+

Motor Control Module that allows the robot to push/draw the object and explore a tool.

+

+Description

+

This module aims to control the robot hands in order to properly execute the push and the draw actions of an object within the KARMA experiment to then learn the corresponding affordance.
+ It also enable the tool exploration.

+

+Libraries

+
    +
  • YARP libraries.
  • +
+

+Parameters

+

–robot robot

    +
  • Select the robot to connect to.
  • +
+

–name name

    +
  • Select the stem-name of the module used to open up ports. By default name is karmaMotor.
  • +
+

–elbow_set (<height> <weight>)

    +
  • To specify how to weigh the task to keep the elbow high.
  • +
+

+Ports Accessed

+

Assume that iCubInterface (with ICartesianControl interface implemented) is running.

+

+Ports Created

+
    +
  • /karmaMotor/rpc receives the information to execute the motor action as a Bottle. It manages the following commands:
      +
    1. Push: [push] cx cy cz theta radius.
      + The coordinates (cx,cy,cz) represent in meters the position of the object's centroid to be pushed; theta, given in degrees, and radius, specified in meters, account for the point from which push the object, that is located onto the circle centered in (cx,cy,cz) and contained in the x-y plane.
      + The reply [ack] is returned as soon as the push is accomplished.
    2. +
    3. Draw: [draw] cx cy cz theta radius dist.
      + The coordinates (cx,cy,cz) represent in meters the position of the object's centroid to be drawn closer; theta, given in degrees, and radius, specified in meters, account for the point from which draw the object, that is located onto the circle centered in (cx,cy,cz) and contained in the x-y plane. The parameter dist specifies the length in meters of the draw action.
      + The reply [ack] is returned as soon as the draw is accomplished.
    4. +
    5. Virtual draw: [vdraw] cx cy cz theta radius dist.
      + Simulate the draw without performing any movement in order to test the quality of the action.
      + The reply [ack] val is returned at the end of the simulation, where val accounts for the quality of the action: the lower it is the better the action is.
    6. +
    7. Tool-attach: [tool] [attach] arm x y z.
      + Attach a tool to the given arm whose dimensions are specified in the frame attached to the hand. The subsequent action will make use of this tool.
    8. +
    9. Tool-get: [tool] [get].
      + Retrieve tool information as [ack] arm x y z.
    10. +
    11. Tool-remove: [tool] [remove].
      + Remove the attached tool.
    12. +
    13. Find: [find] arm eye.
      + An exploration is performed which aims at finding the tool dimension. It is possible to select the arm for executing the movement as well as the eye from which the motion is observed. The reply [ack] x y z returns the tool's dimensions with respect to reference frame attached to the robot hand.
    14. +
    +
  • +
  • /karmaMotor/stop:i receives request for immediate stop of any ongoing processing.
  • +
  • /karmaMotor/vision:i receives the information about the pixel corresponding to the tool tip during the tool exploration phase.
  • +
  • /karmaMotor/finder:rpc communicates with the module in charge of solving for the tool's dimensions.
  • +
+

+Tested OS

+

Windows, Linux

+
Author
Ugo Pattacini
+
+ + + + diff --git a/doxygen/doc/html/group__karmaToolFinder.html b/doxygen/doc/html/group__karmaToolFinder.html new file mode 100644 index 0000000..ed7b5b5 --- /dev/null +++ b/doxygen/doc/html/group__karmaToolFinder.html @@ -0,0 +1,139 @@ + + + + + + + +karma: Tool Solver Part of the KARMA Experiment + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Tool Solver Part of the KARMA Experiment
+
+
+ +

This module finds the tool dimension employing nonlinear optimization. +

+

This module finds the tool dimension employing nonlinear optimization.

+

+Description

+

Through an active exploration of the tool held in the robot hand a set of relevant data is collected, including hand position in 3D space, eye's frame and pixels of the tool tip as acquired by vision algorithms. A nonlinear optimization is then exploited to find out the best estimate of the tool dimensions with respect to the hand reference frame.

+

+Libraries

+
    +
  • YARP libraries.
  • +
  • IPOPT library.
  • +
  • OpenCV library.
    +
  • +
+

+Parameters

+

–robot robot

    +
  • Select the robot to connect to.
  • +
+

–name name

    +
  • Select the stem-name of the module used to open up ports. By default name is karmaToolFinder.
  • +
+

–arm type

    +
  • Select the default arm ("left" or "right") used for the data acquisition.
  • +
+

–eye type

    +
  • Select the default eye ("left" or "right") used for the data acquisition.
  • +
+

+Ports Accessed

+

Assume that iCubInterface (with ICartesianControl interface implemented) is running.

+

+Ports Created

+
    +
  • /karmaToolFinder/rpc receives the information to manage the data acquisition and optimization phase:
      +
    1. Enable: [enable].
      + Start the data acquisition phase.
    2. +
    3. Disable: [disable].
      + Terminate the data acquisition phase.
    4. +
    5. Num: [num].
      + Retrieve the current number of input-output pairs used for the optimization. The reply is [ack] num.
    6. +
    7. Clear: [clear].
      + Clear the current content of input-output pairs database.
    8. +
    9. Select: [select] arm eye.
      + Select the robot sources in terms of arm and eye used during the data acquisition.
    10. +
    11. Find: [find].
      + Execute the optimization over the current database of input-output pairs. The reply is [ack] x y z including the tool dimensions given wrt hand reference frame.
    12. +
    13. Show: [show] x y z.
      + Enable the visualization of a tool with the dimensions specified by the user. The reply is [ack] or [nack].
    14. +
    15. Tip: [tip].
      + Retrieve the tool tip as projected in the image plane. The reply is [ack] u v or [nack].
    16. +
    +
  • +
  • /karmaToolFinder/in receives the position of the tool tip in the image plane.
      +
    • /karmaToolFinder/img:i receives images from the camera.
    • +
    • /karmaToolFinder/img:o streams out images with superimposed information on the tool.
    • +
    • /karmaToolFinder/log:o streams out a complete set of data used during the acquisition.
    • +
    +
  • +
+

+Tested OS

+

Windows, Linux

+
Author
Ugo Pattacini
+
+ + + + diff --git a/doxygen/doc/html/group__karmaToolProjection.html b/doxygen/doc/html/group__karmaToolProjection.html new file mode 100644 index 0000000..17858f3 --- /dev/null +++ b/doxygen/doc/html/group__karmaToolProjection.html @@ -0,0 +1,102 @@ + + + + + + + +karma: Tool Projection Part of the KARMA Experiment + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Tool Projection Part of the KARMA Experiment
+
+
+ +

This module finds the tooltip using motionCUT. +

+

This module finds the tooltip using motionCUT.

+

+Description

+

Through an active exploration of the tool held in the robot hand this module extract a set of points for the tooltip location in the image.

+

+Libraries

+
    +
  • YARP libraries.
  • +
  • OpenCV library.
  • +
+

+Parameters

+

none

+

+Ports Created

+
    +
  • /karmaToolFinder/rpc not responding to anything.
  • +
  • /karmaToolProjection/motionFilter:i receives the data blobs from the motionCUT module
  • +
  • /karmaToolProjection/target:o streams the X and Y target points of the tooltip
  • +
  • /karmaToolProjection/img:o streams the image with the image analysis
  • +
+

+Tested OS

+

Windows, Linux, MacOS

+
Author
Vadim Tikhanoff
+
+ + + + diff --git a/doxygen/doc/html/index.html b/doxygen/doc/html/index.html new file mode 100644 index 0000000..732e8e8 --- /dev/null +++ b/doxygen/doc/html/index.html @@ -0,0 +1,74 @@ + + + + + + + +karma: Main Page + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
karma Documentation
+
+
+
+ + + + diff --git a/doxygen/doc/html/jquery.js b/doxygen/doc/html/jquery.js new file mode 100644 index 0000000..103c32d --- /dev/null +++ b/doxygen/doc/html/jquery.js @@ -0,0 +1,35 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/doxygen/doc/html/karmaLearn_2main_8cpp_source.html b/doxygen/doc/html/karmaLearn_2main_8cpp_source.html new file mode 100644 index 0000000..0c53223 --- /dev/null +++ b/doxygen/doc/html/karmaLearn_2main_8cpp_source.html @@ -0,0 +1,723 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaLearn/main.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
main.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2012 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Ugo Pattacini
+
4  * email: ugo.pattacini@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
106 #include <cstdio>
+
107 #include <mutex>
+
108 #include <fstream>
+
109 #include <sstream>
+
110 #include <string>
+
111 #include <map>
+
112 #include <algorithm>
+
113 
+
114 #include <opencv2/opencv.hpp>
+
115 
+
116 #include <yarp/os/all.h>
+
117 #include <yarp/sig/all.h>
+
118 #include <yarp/cv/Cv.h>
+
119 
+
120 #include <iCub/learningMachine/FixedRangeScaler.h>
+
121 #include <iCub/learningMachine/IMachineLearner.h>
+
122 #include <iCub/learningMachine/LSSVMLearner.h>
+
123 
+
124 #define DEFAULT_STEP 1.0
+
125 
+
126 using namespace std;
+
127 using namespace yarp::os;
+
128 using namespace yarp::sig;
+
129 using namespace yarp::cv;
+
130 using namespace iCub::learningmachine;
+
131 
+
132 
+
133 /************************************************************************/
+
134 class KarmaLearn: public RFModule
+
135 {
+
136 protected:
+
137  FixedRangeScaler scalerIn;
+
138  FixedRangeScaler scalerOut;
+
139  map<string,IMachineLearner*> machines;
+
140 
+
141  string name;
+
142  string configFileName;
+
143 
+
144  string plotItem;
+
145  double plotStep;
+
146 
+
147  mutex mtx;
+
148  RpcServer rpcPort;
+
149  BufferedPort<ImageOf<PixelMono> > plotPort;
+
150 
+
151  /************************************************************************/
+
152  IMachineLearner *createLearner()
+
153  {
+
154  IMachineLearner *learner=new LSSVMLearner;
+
155  LSSVMLearner *lssvm=dynamic_cast<LSSVMLearner*>(learner);
+
156  lssvm->setDomainSize(1);
+
157  lssvm->setCoDomainSize(1);
+
158  lssvm->setC(100.0);
+
159  lssvm->getKernel()->setGamma(10.0);
+
160 
+
161  return learner;
+
162  }
+
163 
+
164  /************************************************************************/
+
165  void extractMinMax(const Bottle &b, double &min, double &max)
+
166  {
+
167  min=scalerOut.getUpperBoundIn();
+
168  max=scalerOut.getLowerBoundIn();
+
169 
+
170  for (int i=0; i<b.size(); i++)
+
171  {
+
172  double bi=b.get(i).asDouble();
+
173 
+
174  if (max<bi)
+
175  max=bi;
+
176 
+
177  if (min>bi)
+
178  min=bi;
+
179  }
+
180  }
+
181 
+
182  /************************************************************************/
+
183  void train(const string &item, const double input, const double output)
+
184  {
+
185  IMachineLearner *learner;
+
186  map<string,IMachineLearner*>::const_iterator itr=machines.find(item);
+
187  if (itr==machines.end())
+
188  {
+
189  learner=createLearner();
+
190  machines[item]=learner;
+
191  }
+
192  else
+
193  learner=itr->second;
+
194 
+
195  Vector in(1,input),out(1,output);
+
196  out[0]=std::min(out[0],scalerOut.getUpperBoundIn());
+
197 
+
198  in[0]=scalerIn.transform(in[0]);
+
199  out[0]=scalerOut.transform(out[0]);
+
200 
+
201  learner->feedSample(in,out);
+
202  learner->train();
+
203  }
+
204 
+
205  /************************************************************************/
+
206  bool predict(const string &item, const Bottle &input, Bottle &output,
+
207  Bottle &variance)
+
208  {
+
209  map<string,IMachineLearner*>::const_iterator itr=machines.find(item);
+
210  if (itr!=machines.end())
+
211  {
+
212  output.clear();
+
213  variance.clear();
+
214  for (int i=0; i<input.size(); i++)
+
215  {
+
216  Vector in(1,input.get(i).asDouble());
+
217  in[0]=scalerIn.transform(in[0]);
+
218 
+
219  IMachineLearner *learner=itr->second;
+
220  Prediction prediction=learner->predict(in);
+
221 
+
222  Vector v=prediction.getPrediction();
+
223  output.addDouble(scalerOut.unTransform(v[0]));
+
224 
+
225  if (prediction.hasVariance())
+
226  {
+
227  Vector v=prediction.getVariance();
+
228  variance.addDouble(v[0]);
+
229  }
+
230  else
+
231  variance.addDouble(-1.0);
+
232  }
+
233 
+
234  return true;
+
235  }
+
236  else
+
237  return false;
+
238  }
+
239 
+
240  /************************************************************************/
+
241  bool optimize(const string &item, const Bottle &searchDomain, double &input,
+
242  double &output)
+
243  {
+
244  map<string,IMachineLearner*>::const_iterator itr=machines.find(item);
+
245  if (itr!=machines.end())
+
246  {
+
247  IMachineLearner *learner=itr->second;
+
248 
+
249  input=scalerIn.getLowerBoundIn();
+
250  double maxOut=scalerOut.getLowerBoundOut();
+
251 
+
252  Bottle bin,bout,bdummy;
+
253  bin.addDouble(input);
+
254  predict(item,bin,bout,bdummy);
+
255  output=bout.get(0).asDouble();
+
256 
+
257  for (int i=0; i<searchDomain.size(); i++)
+
258  {
+
259  double val=searchDomain.get(i).asDouble();
+
260  Vector in(1,scalerIn.transform(val));
+
261  Prediction prediction=learner->predict(in);
+
262  Vector v=prediction.getPrediction();
+
263 
+
264  if (v[0]>maxOut)
+
265  {
+
266  input=val;
+
267  output=scalerOut.unTransform(v[0]);
+
268  maxOut=v[0];
+
269  }
+
270  }
+
271 
+
272  return true;
+
273  }
+
274  else
+
275  return false;
+
276  }
+
277 
+
278  /************************************************************************/
+
279  Bottle items()
+
280  {
+
281  Bottle ret;
+
282  for (map<string,IMachineLearner*>::const_iterator itr=machines.begin(); itr!=machines.end(); itr++)
+
283  ret.addString(itr->first);
+
284 
+
285  return ret;
+
286  }
+
287 
+
288  /************************************************************************/
+
289  bool machineContent(const string &item, string &content)
+
290  {
+
291  map<string,IMachineLearner*>::iterator itr=machines.find(item);
+
292  if (itr!=machines.end())
+
293  {
+
294  content=itr->second->toString();
+
295  return true;
+
296  }
+
297  else
+
298  return false;
+
299  }
+
300 
+
301  /************************************************************************/
+
302  void clear()
+
303  {
+
304  for (map<string,IMachineLearner*>::const_iterator itr=machines.begin(); itr!=machines.end(); itr++)
+
305  delete itr->second;
+
306 
+
307  machines.clear();
+
308  plotItem="";
+
309  }
+
310 
+
311  /************************************************************************/
+
312  bool clear(const string &item)
+
313  {
+
314  map<string,IMachineLearner*>::iterator itr=machines.find(item);
+
315  if (itr!=machines.end())
+
316  {
+
317  delete itr->second;
+
318  machines.erase(itr);
+
319 
+
320  if (plotItem==item)
+
321  plotItem="";
+
322 
+
323  return true;
+
324  }
+
325  else
+
326  return false;
+
327  }
+
328 
+
329  /************************************************************************/
+
330  void save()
+
331  {
+
332  ofstream fout(configFileName.c_str());
+
333 
+
334  fout<<"[general]"<<endl;
+
335  fout<<"name "<<name<<endl;
+
336  fout<<"num_items "<<machines.size()<<endl;
+
337  fout<<"in_lb "<<scalerIn.getLowerBoundIn()<<endl;
+
338  fout<<"in_ub "<<scalerIn.getUpperBoundIn()<<endl;
+
339  fout<<"out_lb "<<scalerOut.getLowerBoundIn()<<endl;
+
340  fout<<"out_ub "<<scalerOut.getUpperBoundIn()<<endl;
+
341  fout<<endl;
+
342 
+
343  int i=0;
+
344  for (map<string,IMachineLearner*>::const_iterator itr=machines.begin(); itr!=machines.end(); itr++, i++)
+
345  {
+
346  fout<<"[item_"<<i<<"]"<<endl;
+
347  fout<<"name "<<itr->first<<endl;
+
348  fout<<"learner "<<"("+itr->second->toString()+")"<<endl;
+
349  fout<<endl;
+
350  }
+
351 
+
352  fout.close();
+
353  }
+
354 
+
355  /************************************************************************/
+
356  void plot()
+
357  {
+
358  if ((plotItem!="") && (plotPort.getOutputCount()>0))
+
359  {
+
360  Bottle input,output,variance;
+
361  for (double d=scalerIn.getLowerBoundIn(); d<scalerIn.getUpperBoundIn(); d+=plotStep)
+
362  input.addDouble(d);
+
363 
+
364  if (predict(plotItem,input,output,variance))
+
365  {
+
366  ImageOf<PixelMono> &img=plotPort.prepare();
+
367  img.resize(320,240);
+
368  cv::Mat imgMat=toCvMat(img);
+
369  imgMat.setTo(cv::Scalar(255));
+
370 
+
371  cv::putText(imgMat,plotItem,cv::Point(250,20),cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0));
+
372 
+
373  double x_min=scalerIn.getLowerBoundIn();
+
374  double x_max=scalerIn.getUpperBoundIn();
+
375  double x_range=x_max-x_min;
+
376 
+
377  double y_min,y_max;
+
378  extractMinMax(output,y_min,y_max);
+
379  y_min*=(y_min>0.0?0.8:1.2);
+
380  y_max*=(y_max>0.0?1.2:0.8);
+
381  double y_range=y_max-y_min;
+
382 
+
383  {
+
384  ostringstream tag; tag.precision(3);
+
385  tag<<x_min;
+
386  cv::putText(imgMat,tag.str(),cv::Point(10,230),cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0));
+
387  }
+
388 
+
389  {
+
390  ostringstream tag; tag.precision(3);
+
391  tag<<x_max;
+
392  cv::putText(imgMat,tag.str(),cv::Point(280,230),cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0));
+
393  }
+
394 
+
395  {
+
396  ostringstream tag; tag.precision(3);
+
397  tag<<y_min;
+
398  cv::putText(imgMat,tag.str(),cv::Point(10,215),cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0));
+
399  }
+
400 
+
401  {
+
402  ostringstream tag; tag.precision(3);
+
403  tag<<y_max;
+
404  cv::putText(imgMat,tag.str(),cv::Point(10,20),cv::FONT_HERSHEY_SIMPLEX,0.5,cv::Scalar(0));
+
405  }
+
406 
+
407  cv::Point pold;
+
408  for (int i=0; i<input.size(); i++)
+
409  {
+
410  cv::Point p;
+
411  p.x=int((img.width()/x_range)*(input.get(i).asDouble()-x_min));
+
412  p.y=img.height()-int((img.height()/y_range)*(output.get(i).asDouble()-y_min));
+
413 
+
414  if (i>0)
+
415  cv::line(imgMat,p,pold,cv::Scalar(0),2);
+
416 
+
417  pold=p;
+
418  }
+
419 
+
420  plotPort.write();
+
421  }
+
422  }
+
423  }
+
424 
+
425  /************************************************************************/
+
426  bool respond(const Bottle &command, Bottle &reply)
+
427  {
+
428  lock_guard<mutex> lg(mtx);
+
429  if (command.size()>=1)
+
430  {
+
431  int header=command.get(0).asVocab();
+
432  Bottle payload=command.tail();
+
433  if (header==Vocab::encode("train"))
+
434  {
+
435  if (payload.size()>=3)
+
436  {
+
437  string item=payload.get(0).asString();
+
438  double input=payload.get(1).asDouble();
+
439  double output=payload.get(2).asDouble();
+
440 
+
441  train(item,input,output);
+
442  reply.addVocab(Vocab::encode("ack"));
+
443 
+
444  // trigger a change for the "plot"
+
445  plotItem=item;
+
446  }
+
447  else
+
448  reply.addVocab(Vocab::encode("nack"));
+
449  }
+
450  else if (header==Vocab::encode("predict"))
+
451  {
+
452  if (payload.size()>=2)
+
453  {
+
454  Bottle output,variance;
+
455  string item=payload.get(0).asString();
+
456  if (payload.get(1).isDouble())
+
457  {
+
458  Bottle input; input.addDouble(payload.get(1).asDouble());
+
459  if (predict(item,input,output,variance))
+
460  {
+
461  reply.addVocab(Vocab::encode("ack"));
+
462  reply.addDouble(output.get(0).asDouble());
+
463  reply.addDouble(variance.get(0).asDouble());
+
464  }
+
465  else
+
466  reply.addVocab(Vocab::encode("nack"));
+
467  }
+
468  else if (payload.get(1).isList())
+
469  {
+
470  if (predict(item,*payload.get(1).asList(),output,variance))
+
471  {
+
472  reply.addVocab(Vocab::encode("ack"));
+
473  reply.addList().append(output);
+
474  reply.addList().append(variance);
+
475  }
+
476  else
+
477  reply.addVocab(Vocab::encode("nack"));
+
478  }
+
479  else
+
480  reply.addVocab(Vocab::encode("nack"));
+
481  }
+
482  else
+
483  reply.addVocab(Vocab::encode("nack"));
+
484  }
+
485  else if (header==Vocab::encode("span"))
+
486  {
+
487  if (payload.size()>=1)
+
488  {
+
489  double step=DEFAULT_STEP;
+
490  string item=payload.get(0).asString();
+
491  if (payload.size()>=2)
+
492  step=payload.get(1).asDouble();
+
493 
+
494  Bottle input,output,variance;
+
495  for (double d=scalerIn.getLowerBoundIn(); d<scalerIn.getUpperBoundIn(); d+=step)
+
496  input.addDouble(d);
+
497 
+
498  if (predict(item,input,output,variance))
+
499  {
+
500  reply.addVocab(Vocab::encode("ack"));
+
501  reply.addList().append(output);
+
502  reply.addList().append(variance);
+
503  }
+
504  else
+
505  reply.addVocab(Vocab::encode("nack"));
+
506  }
+
507  else
+
508  reply.addVocab(Vocab::encode("nack"));
+
509  }
+
510  else if (header==Vocab::encode("optimize"))
+
511  {
+
512  if (payload.size()>=1)
+
513  {
+
514  Bottle searchDomain;
+
515  double step=DEFAULT_STEP;
+
516 
+
517  string item=payload.get(0).asString();
+
518  if (payload.size()>=2)
+
519  {
+
520  if (payload.get(1).isDouble())
+
521  step=payload.get(1).asDouble();
+
522  else if (payload.get(1).isList())
+
523  searchDomain=*payload.get(1).asList();
+
524  }
+
525 
+
526  if (searchDomain.size()==0)
+
527  for (double d=scalerIn.getLowerBoundIn(); d<scalerIn.getUpperBoundIn(); d+=step)
+
528  searchDomain.addDouble(d);
+
529 
+
530  double input,output;
+
531  if (optimize(item,searchDomain,input,output))
+
532  {
+
533  reply.addVocab(Vocab::encode("ack"));
+
534  reply.addDouble(input);
+
535  reply.addDouble(output);
+
536  }
+
537  else
+
538  reply.addVocab(Vocab::encode("nack"));
+
539  }
+
540  else
+
541  reply.addVocab(Vocab::encode("nack"));
+
542  }
+
543  else if (header==Vocab::encode("items"))
+
544  {
+
545  reply.addVocab(Vocab::encode("ack"));
+
546  reply.append(items());
+
547  }
+
548  else if (header==Vocab::encode("machine"))
+
549  {
+
550  if (payload.size()>=1)
+
551  {
+
552  string item=payload.get(0).asString();
+
553  string content;
+
554  if (machineContent(item,content))
+
555  {
+
556  reply.addVocab(Vocab::encode("ack"));
+
557  reply.addString(content);
+
558  }
+
559  else
+
560  reply.addVocab(Vocab::encode("nack"));
+
561  }
+
562  else
+
563  reply.addVocab(Vocab::encode("nack"));
+
564  }
+
565  else if (header==Vocab::encode("clear"))
+
566  {
+
567  if (payload.size()>=1)
+
568  {
+
569  string item=payload.get(0).asString();
+
570  if (clear(item))
+
571  reply.addVocab(Vocab::encode("ack"));
+
572  else
+
573  reply.addVocab(Vocab::encode("nack"));
+
574  }
+
575  else
+
576  {
+
577  clear();
+
578  reply.addVocab(Vocab::encode("ack"));
+
579  }
+
580  }
+
581  else if (header==Vocab::encode("save"))
+
582  {
+
583  save();
+
584  reply.addVocab(Vocab::encode("ack"));
+
585  }
+
586  else if (header==Vocab::encode("plot"))
+
587  {
+
588  if (payload.size()>=1)
+
589  {
+
590  string item=payload.get(0).asString();
+
591  if (payload.size()>=2)
+
592  plotStep=payload.get(1).asDouble();
+
593 
+
594  if (machines.find(item)!=machines.end())
+
595  {
+
596  plotItem=item;
+
597  reply.addVocab(Vocab::encode("ack"));
+
598  }
+
599  else
+
600  reply.addVocab(Vocab::encode("nack"));
+
601  }
+
602  else
+
603  reply.addVocab(Vocab::encode("nack"));
+
604  }
+
605  else
+
606  reply.addVocab(Vocab::encode("nack"));
+
607  }
+
608  else
+
609  reply.addVocab(Vocab::encode("nack"));
+
610 
+
611  return true;
+
612  }
+
613 
+
614 public:
+
615  /************************************************************************/
+
616  bool configure(ResourceFinder &rf)
+
617  {
+
618  // default values
+
619  name="karmaLearn";
+
620  int nItems=0;
+
621 
+
622  double in_lb=0.0;
+
623  double in_ub=360.0;
+
624  double out_lb=0.0;
+
625  double out_ub=2.0;
+
626 
+
627  Bottle &generalGroup=rf.findGroup("general");
+
628  if (!generalGroup.isNull())
+
629  {
+
630  name=generalGroup.check("name",Value("karmaLearn")).asString();
+
631  nItems=generalGroup.check("num_items",Value(0)).asInt();
+
632  in_lb=generalGroup.check("in_lb",Value(0.0)).asDouble();
+
633  in_ub=generalGroup.check("in_ub",Value(360.0)).asDouble();
+
634  out_lb=generalGroup.check("out_lb",Value(0.0)).asDouble();
+
635  out_ub=generalGroup.check("out_ub",Value(2.0)).asDouble();
+
636  }
+
637 
+
638  scalerIn.setLowerBoundIn(in_lb);
+
639  scalerIn.setUpperBoundIn(in_ub);
+
640  scalerIn.setLowerBoundOut(0.0);
+
641  scalerIn.setUpperBoundOut(1.0);
+
642 
+
643  scalerOut.setLowerBoundIn(out_lb);
+
644  scalerOut.setUpperBoundIn(out_ub);
+
645  scalerOut.setLowerBoundOut(0.0);
+
646  scalerOut.setUpperBoundOut(1.0);
+
647 
+
648  // retrieve machines for each item
+
649  for (int i=0; i<nItems; i++)
+
650  {
+
651  ostringstream item; item<<"item_"<<i;
+
652  Bottle &itemGroup=rf.findGroup(item.str());
+
653  if (!itemGroup.isNull())
+
654  {
+
655  if (!itemGroup.check("name"))
+
656  continue;
+
657 
+
658  IMachineLearner *learner=createLearner();
+
659  if (itemGroup.check("learner"))
+
660  learner->fromString(itemGroup.find("learner").asList()->toString());
+
661 
+
662  machines[itemGroup.find("name").asString()]=learner;
+
663  }
+
664  }
+
665 
+
666  // save the file name
+
667  configFileName=rf.findPath("from");
+
668 
+
669  plotItem="";
+
670  plotStep=1.0;
+
671 
+
672  plotPort.open("/"+name+"/plot:o");
+
673  rpcPort.open("/"+name+"/rpc");
+
674  attach(rpcPort);
+
675 
+
676  return true;
+
677  }
+
678 
+
679  /************************************************************************/
+
680  bool interruptModule()
+
681  {
+
682  plotPort.interrupt();
+
683  rpcPort.interrupt();
+
684  return true;
+
685  }
+
686 
+
687  /************************************************************************/
+
688  bool close()
+
689  {
+
690  save();
+
691  clear();
+
692  plotPort.close();
+
693  rpcPort.close();
+
694  return true;
+
695  }
+
696 
+
697  /************************************************************************/
+
698  double getPeriod()
+
699  {
+
700  return 0.25;
+
701  }
+
702 
+
703  /************************************************************************/
+
704  bool updateModule()
+
705  {
+
706  lock_guard<mutex> lg(mtx);
+
707  plot();
+
708  return true;
+
709  }
+
710 };
+
711 
+
712 
+
713 /************************************************************************/
+
714 int main(int argc, char *argv[])
+
715 {
+
716  Network yarp;
+
717  if (!yarp.checkNetwork())
+
718  {
+
719  printf("YARP server not available!\n");
+
720  return 1;
+
721  }
+
722 
+
723  ResourceFinder rf;
+
724  rf.setDefaultContext("karma");
+
725  rf.setDefaultConfigFile("karmaLearn.ini");
+
726  rf.configure(argc,argv);
+
727 
+
728  KarmaLearn karmaLearn;
+
729  return karmaLearn.runModule(rf);
+
730 }
+
731 
+
732 
+
733 
+
+ + + + diff --git a/doxygen/doc/html/karmaManager_2include_2iCub_2module_8h_source.html b/doxygen/doc/html/karmaManager_2include_2iCub_2module_8h_source.html new file mode 100644 index 0000000..8b5e846 --- /dev/null +++ b/doxygen/doc/html/karmaManager_2include_2iCub_2module_8h_source.html @@ -0,0 +1,220 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/include/iCub/module.h Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
module.h
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #ifndef __MODULE_H__
+
19 #define __MODULE_H__
+
20 
+
21 #include <string>
+
22 #include <map>
+
23 
+
24 #include <yarp/os/Time.h>
+
25 #include <yarp/os/RFModule.h>
+
26 #include <yarp/os/RpcServer.h>
+
27 #include <yarp/os/RpcClient.h>
+
28 #include <yarp/os/BufferedPort.h>
+
29 #include <yarp/os/Port.h>
+
30 #include <yarp/sig/Image.h>
+
31 #include <yarp/sig/Vector.h>
+
32 
+
33 #include <opencv2/opencv.hpp>
+
34 
+
35 #include "iCub/utils.h"
+
36 
+
37 #define LEFTARM 0
+
38 #define RIGHTARM 1
+
39 
+
40 /**********************************************************/
+
41 struct blobsData
+
42 {
+
43  int index;
+
44  double lenght;
+
45  double vdrawError;
+
46  cv::Point posistion;
+
47  double bestDistance;
+
48  double bestAngle;
+
49  std::string name;
+
50 };
+
51 /**********************************************************/
+
52 class Manager : public yarp::os::RFModule
+
53 {
+
54 protected:
+
55 
+
56  std::string name; //name of the module
+
57  std::string hand; //name of the module
+
58  std::string camera; //name of the camera
+
59  yarp::os::Port rpcHuman; //human rpc port (receive commands via rpc)
+
60  yarp::os::RpcClient rpcMotorAre; //rpc motor port ARE
+
61  yarp::os::RpcClient rpcMotorKarma; //rpc motor port KARMA
+
62  yarp::os::RpcClient iolStateMachine; //rpc to iol state machine
+
63  yarp::os::RpcClient rpcMIL; //rpc mil port
+
64  yarp::os::RpcClient rpcKarmaLearn; //rpc mil port
+
65  yarp::os::RpcClient rpcReconstruct; //rpc reconstruct
+
66  yarp::os::RpcClient rpcGraspEstimate; //rpc graspEstimate
+
67  yarp::os::RpcClient rpcOPC; //rpc graspEstimate
+
68 
+
69  ParticleFilter particleFilter; //class to receive positions from the templateTracker module
+
70  SegmentationPoint segmentPoint; //class to request segmentation from activeSegmentation module
+
71  PointedLocation pointedLoc; //port class to receive pointed locations
+
72 
+
73  yarp::os::BufferedPort<yarp::os::Bottle> blobExtractor;
+
74  yarp::os::BufferedPort<yarp::os::Bottle> particleTracks;
+
75 
+
76  std::mutex mutexResources; //mutex for ressources
+
77  bool pointGood; //boolean for if got a point location
+
78  cv::Point pointLocation; //x and y of the pointed location
+
79  bool init;
+
80  yarp::os::Bottle lastBlobs;
+
81  yarp::os::Bottle lastTool;
+
82  yarp::sig::Vector objectPos;
+
83  yarp::sig::Vector toolSmall, toolBig;
+
84 
+
85  std::string obj;
+
86  double userTheta;
+
87  blobsData *blobsDetails;
+
88 
+
89  std::map<int, double> randActions;
+
90 
+
91  yarp::os::Bottle getBlobs();
+
92  cv::Point getBlobCOG(const yarp::os::Bottle &blobs, const int i);
+
93  double getBlobLenght(const yarp::os::Bottle &blobs, const int i);
+
94 
+
95  bool get3DPosition(const cv::Point &point, yarp::sig::Vector &x);
+
96  yarp::os::Bottle findClosestBlob(const yarp::os::Bottle &blobs, const cv::Point &loc);
+
97  int processHumanCmd(const yarp::os::Bottle &cmd, yarp::os::Bottle &b);
+
98  int executeOnLoc(bool shouldTrain);
+
99  int executeToolOnLoc();
+
100  yarp::os::Bottle executeToolLearning();
+
101  int executeToolSearchOnLoc( const std::string &objName );
+
102  yarp::os::Bottle executeBlobRecog( const std::string &objName );
+
103 
+
104  bool executeCloseHand(int ARM);
+
105  bool executeDropAway(int ARM);
+
106  bool executeGiveAction(int ARM);
+
107  bool executeSpeech( const std::string &speech );
+
108  double executeVirtualDraw(blobsData &blobsDetails);
+
109  double executeToolDrawNear(blobsData &blobsDetails);
+
110  int executeToolAttach(const yarp::sig::Vector &tool);
+
111  yarp::os::Bottle executeKarmaOptimize( const yarp::sig::Vector &tool, const std::string &objName);
+
112  yarp::os::Bottle classifyThem();
+
113 
+
114  yarp::os::Bottle findBlobLoc();
+
115  yarp::os::Bottle blobLoc;
+
116  yarp::os::Bottle blobList;
+
117 
+
118  bool executePCLGrasp( const std::string &objName );
+
119  double latchTimer, idleTmo;
+
120 
+
121  void takeMotionARE();
+
122  void segmentAndTrack( int x, int y );
+
123 
+
124  yarp::os::Bottle getOffset(yarp::os::Bottle &closestBlob, double actionOrient, yarp::sig::Vector &initPos);
+
125 
+
126  void getPraticleTracks();
+
127  void goHome();
+
128  void goHomeArmsHead();
+
129  double wrapAng (const double ang);
+
130 
+
131  yarp::os::Bottle classify(const yarp::os::Bottle &blobs, int index);
+
132  yarp::os::Bottle getType(const yarp::os::Bottle *mils, int index);
+
133 
+
134 public:
+
135  bool configure(yarp::os::ResourceFinder &rf);
+
136  bool interruptModule();
+
137  bool close();
+
138  bool updateModule();
+
139  double getPeriod();
+
140 };
+
141 #endif
+
142 
+
+ + + + diff --git a/doxygen/doc/html/karmaManager_2include_2iCub_2utils_8h_source.html b/doxygen/doc/html/karmaManager_2include_2iCub_2utils_8h_source.html new file mode 100644 index 0000000..d86e553 --- /dev/null +++ b/doxygen/doc/html/karmaManager_2include_2iCub_2utils_8h_source.html @@ -0,0 +1,141 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/include/iCub/utils.h Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
utils.h
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #ifndef __UTILS_H__
+
19 #define __UTILS_H__
+
20 
+
21 #include <string>
+
22 
+
23 #include <yarp/os/Bottle.h>
+
24 #include <yarp/os/BufferedPort.h>
+
25 #include <yarp/os/PeriodicThread.h>
+
26 #include <yarp/os/PortReport.h>
+
27 
+
28 #include <opencv2/opencv.hpp>
+
29 
+
30 class Manager; //forward declaration
+
31 
+
32 /**********************************************************/
+
33 class ParticleFilter : public yarp::os::BufferedPort<yarp::os::Bottle>
+
34 {
+
35 protected:
+
36  cv::Point loc;
+
37  void onRead(yarp::os::Bottle &b);
+
38 public:
+
39  ParticleFilter();
+
40  bool getTraker(cv::Point &loc);
+
41 };
+
42 /**********************************************************/
+
43 class SegmentationPoint : public yarp::os::Port
+
44 {
+
45 public:
+
46  void segment(yarp::os::Bottle &b);
+
47 };
+
48 /**********************************************************/
+
49 class PointedLocation : public yarp::os::BufferedPort<yarp::os::Bottle>
+
50 {
+
51 protected:
+
52  cv::Point loc;
+
53  double rxTime;
+
54  double timeout;
+
55 
+
56  void onRead(yarp::os::Bottle &b);
+
57 
+
58 public:
+
59  PointedLocation();
+
60  bool getLoc(cv::Point &loc);
+
61 };
+
62 
+
63 #endif
+
+ + + + diff --git a/doxygen/doc/html/karmaManager_2src_2main_8cpp_source.html b/doxygen/doc/html/karmaManager_2src_2main_8cpp_source.html new file mode 100644 index 0000000..5697b69 --- /dev/null +++ b/doxygen/doc/html/karmaManager_2src_2main_8cpp_source.html @@ -0,0 +1,121 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/src/main.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
main.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #include <yarp/os/Network.h>
+
19 #include "iCub/module.h"
+
20 
+
21 using namespace yarp::os;
+
22 
+
23 
+
24 /**********************************************************/
+
25 int main(int argc, char *argv[])
+
26 {
+
27  Network yarp;
+
28  if (!yarp.checkNetwork())
+
29  return 1;
+
30 
+
31  ResourceFinder rf;
+
32  rf.setDefault("name","karmaManager");
+
33  rf.setDefaultContext("karma");
+
34  rf.setDefaultConfigFile("karmaManager.ini");
+
35  rf.setDefault("tracking_period","30");
+
36  rf.configure(argc,argv);
+
37 
+
38  Manager manager;
+
39  return manager.runModule(rf);
+
40 }
+
41 
+
42 
+
43 
+
+ + + + diff --git a/doxygen/doc/html/karmaManager_2src_2module_8cpp_source.html b/doxygen/doc/html/karmaManager_2src_2module_8cpp_source.html new file mode 100644 index 0000000..37a5f89 --- /dev/null +++ b/doxygen/doc/html/karmaManager_2src_2module_8cpp_source.html @@ -0,0 +1,1771 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/src/module.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
module.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #include <cmath>
+
19 #include <sstream>
+
20 #include <cstdio>
+
21 #include <limits>
+
22 
+
23 #include <yarp/math/Rand.h>
+
24 #include <yarp/math/Math.h>
+
25 
+
26 #include "iCub/module.h"
+
27 
+
28 using namespace std;
+
29 using namespace yarp::os;
+
30 using namespace yarp::sig;
+
31 using namespace yarp::math;
+
32 
+
33 #define RET_INVALID -1
+
34 
+
35 #define CMD_TRAIN yarp::os::createVocab('t','r','a','i')
+
36 #define CMD_EXECUTE yarp::os::createVocab('e','x','e','c')
+
37 #define CMD_TOOLEXTEND yarp::os::createVocab('e','x','t','d')
+
38 
+
39 /**********************************************************/
+
40 bool Manager::configure(ResourceFinder &rf)
+
41 {
+
42  name=rf.find("name").asString();
+
43  camera=rf.find("camera").asString();
+
44  if ((camera!="left") && (camera!="right"))
+
45  camera="left";
+
46 
+
47  hand=rf.find("hand").asString();
+
48  if ((hand!="left") && (hand!="right"))
+
49  hand="left";
+
50 
+
51  //incoming
+
52  particleFilter.open("/"+name+"/particle:i");
+
53  pointedLoc.open("/"+name+"/point:i");
+
54  blobExtractor.open("/"+name+"/blobs:i");
+
55 
+
56  //outgoing
+
57  segmentPoint.open("/"+name+"/segmentTarget:o"); //port to send off target Points to segmentator
+
58  iolStateMachine.open("/"+name+"/iolState:o");
+
59 
+
60  //rpc
+
61  rpcMIL.open("/"+name+"/mil:rpc"); //rpc client to query mil classifications
+
62  rpcHuman.open("/"+name+"/human:rpc"); //rpc server to interact with the italkManager
+
63  rpcMotorAre.open("/"+name+"/are:rpc"); //rpc server to query ARE
+
64  rpcMotorKarma.open("/"+name+"/karma:rpc"); //rpc server to query Karma
+
65  rpcKarmaLearn.open("/"+name+"/learn:rpc");
+
66  rpcReconstruct.open("/"+name+"/reconstruct:rpc");
+
67  rpcGraspEstimate.open("/"+name+"/graspestimate:rpc");
+
68  rpcOPC.open("/"+name+"/opc:rpc");
+
69 
+
70  Rand::init();
+
71 
+
72  randActions[0] = 0.0;
+
73  randActions[1] = 30.0;
+
74  randActions[2] = 150.0;
+
75  randActions[3] = 180.0;
+
76  randActions[4] = 225.0;
+
77  //randActions[5] = 270.0;
+
78  randActions[5] = 315.0;
+
79 
+
80  pointGood=false;
+
81  init=false;
+
82 
+
83  idleTmo = 60.0;
+
84  toolSmall.resize(3);
+
85  toolBig.resize(3);
+
86 
+
87  toolSmall[0] = 0.18;
+
88  toolSmall[1] = -0.17;
+
89  toolSmall[2] = -0.04;
+
90 
+
91  toolBig[0] = 0.29;
+
92  toolBig[1] = -0.26;
+
93  toolBig[2] = -0.05;
+
94 
+
95  //attach(rpcHuman);
+
96  return true;
+
97 }
+
98 
+
99 /**********************************************************/
+
100 bool Manager::interruptModule()
+
101 {
+
102  segmentPoint.interrupt();
+
103  blobExtractor.interrupt();
+
104  rpcHuman.interrupt();
+
105  rpcMotorAre.interrupt();
+
106  rpcMotorKarma.interrupt();
+
107  particleFilter.interrupt();
+
108  pointedLoc.interrupt();
+
109  iolStateMachine.interrupt();
+
110  rpcMIL.interrupt();
+
111  rpcKarmaLearn.interrupt();
+
112  rpcReconstruct.interrupt();
+
113  rpcGraspEstimate.interrupt();
+
114  rpcOPC.interrupt();
+
115 
+
116  return true;
+
117 }
+
118 /**********************************************************/
+
119 bool Manager::close()
+
120 {
+
121  segmentPoint.close();
+
122  blobExtractor.close();
+
123  rpcHuman.close();
+
124  rpcMotorAre.close();
+
125  rpcMotorKarma.close();
+
126  particleFilter.close();
+
127  pointedLoc.close();
+
128  iolStateMachine.close();
+
129  rpcMIL.close();
+
130  rpcKarmaLearn.close();
+
131  rpcReconstruct.close();
+
132  rpcGraspEstimate.close();
+
133  rpcOPC.close();
+
134 
+
135  return true;
+
136 }
+
137 /**********************************************************/
+
138 int Manager::processHumanCmd(const Bottle &cmd, Bottle &b)
+
139 {
+
140  int ret=Vocab::encode(cmd.get(0).asString());
+
141  b.clear();
+
142  if (cmd.size()>1)
+
143  {
+
144  if (cmd.get(1).isList())
+
145  b=*cmd.get(1).asList();
+
146  else
+
147  b=cmd.tail();
+
148  }
+
149  return ret;
+
150 }
+
151 /**********************************************************/
+
152 bool Manager::updateModule()
+
153 {
+
154  if (isStopping())
+
155  return false;
+
156 
+
157  //init = true;//bypass for now
+
158 
+
159  while (!init)
+
160  {
+
161  Time::delay(0.5);
+
162  fprintf(stdout, "waiting for connection from iolStateMachineHandler\n");
+
163  if (iolStateMachine.getOutputCount() > 0)
+
164  {
+
165  fprintf(stdout, "sending home \n");
+
166  Bottle cmdIol, replyIol;
+
167  cmdIol.addString("home");
+
168  iolStateMachine.write(cmdIol,replyIol);
+
169  fprintf(stdout,"%s\n", replyIol.toString().c_str());
+
170  fprintf(stdout,"stopping attention...\n");
+
171  cmdIol.clear();
+
172  replyIol.clear();
+
173  cmdIol.addString("attention");
+
174  cmdIol.addString("stop");
+
175  iolStateMachine.write(cmdIol,replyIol);
+
176  fprintf(stdout,"%s\n", replyIol.toString().c_str());
+
177  init = true;
+
178  fprintf(stdout, "have successfully initialize it all\n");
+
179 
+
180  executeSpeech ("ok I am ready");
+
181  }
+
182  }
+
183 
+
184  Bottle cmd, val, reply;
+
185  rpcHuman.read(cmd, true);
+
186 
+
187  int rxCmd=processHumanCmd(cmd,val);
+
188  if (rxCmd==Vocab::encode("train"))
+
189  {
+
190  obj=cmd.get(1).asString();
+
191 
+
192  if (cmd.size() > 2)
+
193  {
+
194  fprintf(stdout,"with user data\n");
+
195  userTheta=cmd.get(2).asDouble();
+
196  }
+
197  else
+
198  {
+
199  fprintf(stdout,"no user data\n");
+
200  userTheta = -1.0;
+
201  }
+
202  //pointGood = pointedLoc.getLoc(pointLocation);
+
203  //Time::delay(1.5);
+
204  executeOnLoc(true);
+
205  reply.addString("ack");
+
206  rpcHuman.reply(reply);
+
207  pointGood = false;
+
208  }
+
209  if (rxCmd==Vocab::encode("test"))
+
210  {
+
211  obj=cmd.get(1).asString();
+
212 
+
213  //pointGood = pointedLoc.getLoc(pointLocation);
+
214  //Time::delay(1.5);
+
215  executeOnLoc(false);
+
216  reply.addString("ack");
+
217  rpcHuman.reply(reply);
+
218  pointGood = false;
+
219  }
+
220  if (rxCmd==Vocab::encode("handle"))
+
221  {
+
222  takeMotionARE();
+
223  reply.addString("ack");
+
224  rpcHuman.reply(reply);
+
225  }
+
226 
+
227  if (rxCmd==Vocab::encode("extend"))
+
228  {
+
229  if (cmd.size() > 2)
+
230  {
+
231  fprintf(stdout, "Will now use user selected arm and camera \n");
+
232  hand = cmd.get(1).asString();
+
233  camera = cmd.get(2).asString();
+
234  }
+
235  else
+
236  {
+
237  fprintf(stdout, "Will now use default arm and cam \n");
+
238  }
+
239 
+
240  lastTool.clear();
+
241  lastTool = executeToolLearning();
+
242  reply.addString("ack");
+
243  rpcHuman.reply(reply);
+
244 
+
245  fprintf(stdout, "GOT TOOL at %s, \n",lastTool.toString().c_str());
+
246  goHomeArmsHead();
+
247  }
+
248  if (rxCmd==Vocab::encode("tooltip"))
+
249  {
+
250  Bottle toSend;
+
251  toSend.clear();
+
252  toSend.addDouble(lastTool.get(0).asDouble());
+
253  toSend.addDouble(lastTool.get(1).asDouble());
+
254  toSend.addDouble(lastTool.get(2).asDouble());
+
255  //reply.addString("ack");
+
256  rpcHuman.reply(toSend);
+
257 
+
258  fprintf(stdout, "Replied with %s, \n",toSend.toString().c_str());
+
259  //goHomeArmsHead();
+
260  }
+
261  if (rxCmd==Vocab::encode("grasp"))
+
262  {
+
263  obj=cmd.get(1).asString();
+
264  if ( executePCLGrasp(obj) )
+
265  reply.addString("ack");
+
266  else
+
267  reply.addString("nack");
+
268  }
+
269  if (rxCmd==Vocab::encode("blobLoc"))
+
270  {
+
271  blobLoc.clear();
+
272  blobLoc = findBlobLoc();
+
273  if (blobLoc.size()<1)
+
274  {
+
275  reply.addString("nack");
+
276  rpcHuman.reply(reply);
+
277  }
+
278  else
+
279  rpcHuman.reply(blobLoc);
+
280  }
+
281 
+
282  if (rxCmd==Vocab::encode("objRecog"))
+
283  {
+
284  blobList.clear();
+
285  obj=cmd.get(1).asString();
+
286  blobLoc = executeBlobRecog(obj);
+
287 
+
288  if (blobLoc.size()<1)
+
289  {
+
290  reply.addString("nack");
+
291  rpcHuman.reply(reply);
+
292  }
+
293  else
+
294  rpcHuman.reply(blobLoc);
+
295  }
+
296  if (rxCmd==Vocab::encode("close"))
+
297  {
+
298  int arm=cmd.get(1).asInt();
+
299  executeCloseHand(arm);
+
300  reply.addString("ack");
+
301  rpcHuman.reply(reply);
+
302  }
+
303  if (rxCmd==Vocab::encode("give"))
+
304  {
+
305  int arm=cmd.get(1).asInt();
+
306  executeGiveAction(arm);
+
307  reply.addString("ack");
+
308  rpcHuman.reply(reply);
+
309  }
+
310  if (rxCmd==Vocab::encode("class"))
+
311  {
+
312  reply = classifyThem();
+
313  rpcHuman.reply(reply);
+
314  }
+
315 
+
316  Bottle result;
+
317  result.clear();
+
318 
+
319  return true;
+
320 }
+
321 
+
322 /**********************************************************/
+
323 Bottle Manager::classifyThem()
+
324 {
+
325  Bottle cmdIol;
+
326  Bottle replyIol;
+
327  cmdIol.clear(), replyIol.clear();
+
328  cmdIol.addString("class");
+
329  iolStateMachine.write(cmdIol,replyIol);
+
330  fprintf(stdout,"%s\n", replyIol.toString().c_str());
+
331 
+
332  return replyIol;
+
333 }
+
334 /**********************************************************/
+
335 void Manager::segmentAndTrack( int x, int y )
+
336 {
+
337  Bottle toSegment;
+
338  toSegment.clear();
+
339 
+
340  toSegment.addInt(x); //(closestBlob.get(0).asInt());
+
341  toSegment.addInt(y); //(closestBlob.get(1).asInt());
+
342  toSegment.addInt(80);
+
343  toSegment.addInt(80);
+
344  fprintf(stdout, "segmenting cmd is %s\n",toSegment.toString().c_str());
+
345  segmentPoint.write(toSegment);
+
346 
+
347  Bottle cmdAre, replyAre;
+
348  cmdAre.addString("track");
+
349  cmdAre.addString("track");
+
350  cmdAre.addString("no_sacc");
+
351  rpcMotorAre.write(cmdAre,replyAre);
+
352  fprintf(stdout,"tracking started%s:\n",replyAre.toString().c_str());
+
353 }
+
354 /**********************************************************/
+
355 void Manager::goHomeArmsHead()
+
356 {
+
357  Bottle cmdAre, replyAre;
+
358  cmdAre.clear();
+
359  replyAre.clear();
+
360  cmdAre.addString("home");
+
361  cmdAre.addString("arms");
+
362  cmdAre.addString("head");
+
363  rpcMotorAre.write(cmdAre,replyAre);
+
364  fprintf(stdout,"gone home %s:\n",replyAre.toString().c_str());
+
365 }
+
366 /**********************************************************/
+
367 void Manager::goHome()
+
368 {
+
369  Bottle cmdAre, replyAre;
+
370  cmdAre.clear();
+
371  replyAre.clear();
+
372  cmdAre.addString("home");
+
373  cmdAre.addString("all");
+
374  rpcMotorAre.write(cmdAre,replyAre);
+
375  fprintf(stdout,"gone home %s:\n",replyAre.toString().c_str());
+
376 }
+
377 /**********************************************************/
+
378 void Manager::takeMotionARE()
+
379 {
+
380  //to fill with data for karmaMotor
+
381  fprintf(stdout,"Will now start take motion proceedure:\n");
+
382  Bottle cmdAre,replyAre;
+
383  cmdAre.clear();
+
384  replyAre.clear();
+
385  cmdAre.addString("take");
+
386  cmdAre.addString("motion");
+
387  fprintf(stdout,"%s\n",cmdAre.toString().c_str());
+
388  rpcMotorAre.write(cmdAre, replyAre);
+
389  fprintf(stdout,"action is %s:\n",replyAre.toString().c_str());
+
390 }
+
391 
+
392 /**********************************************************/
+
393 Bottle Manager::executeToolLearning()
+
394 {
+
395  //to fill with data for karmaMotor
+
396  fprintf(stdout,"Will now start the tool learn proceedure:\n");
+
397  Bottle karmaMotor,KarmaReply;
+
398  karmaMotor.clear();
+
399  KarmaReply.clear();
+
400  karmaMotor.addString("find");
+
401  karmaMotor.addString(hand);
+
402  karmaMotor.addString(camera);
+
403  fprintf(stdout,"%s\n",karmaMotor.toString().c_str());
+
404  rpcMotorKarma.write(karmaMotor, KarmaReply);
+
405  fprintf(stdout,"action is %s:\n",KarmaReply.toString().c_str());
+
406 
+
407  Bottle toReturn;
+
408  toReturn.clear();
+
409  toReturn.addDouble( KarmaReply.get(1).asDouble() );
+
410  toReturn.addDouble( KarmaReply.get(2).asDouble() );
+
411  toReturn.addDouble( KarmaReply.get(3).asDouble() );
+
412  return toReturn;
+
413 }
+
414 /**********************************************************/
+
415 Bottle Manager::executeBlobRecog(const string &objName)
+
416 {
+
417  Bottle loc;
+
418  loc.clear();
+
419  fprintf(stdout, "\n\n\nexecuteBlobRecog****************************************************************************\n\n" );
+
420 
+
421  Bottle blobs;
+
422  blobs.clear();
+
423  bool invalid = false;
+
424 
+
425  // grab the blobs
+
426  blobs=getBlobs();
+
427  // failure handling
+
428  if (blobs.size()==0)
+
429  {
+
430  fprintf (stdout,"INVALID BLOB SIZE\n");
+
431  invalid = true;
+
432  }
+
433  latchTimer = 0.0;
+
434 
+
435  if ( !invalid )
+
436  {
+
437  Bottle classResults = classifyThem();
+
438 
+
439  for (int x=0; x < blobs.size(); x++)
+
440  {
+
441  pointLocation = getBlobCOG(blobs,x);
+
442  fprintf (stdout,"point is %d %d \n", pointLocation.x, pointLocation.y);
+
443  Bottle closestBlob;
+
444  mutexResources.lock();
+
445  closestBlob=findClosestBlob(blobs,pointLocation);
+
446  mutexResources.unlock();
+
447 
+
448  cv::Point cog;
+
449  cog.x = closestBlob.get(0).asInt();
+
450  cog.y = closestBlob.get(1).asInt();
+
451 
+
452  int index = 0;
+
453  index = closestBlob.get(2).asInt();
+
454 
+
455  fprintf(stdout, "closest blob is x:%d y:%d with index %d\n\n",cog.x, cog.y, index);
+
456 
+
457  //classify the blob
+
458  //Bottle mil;
+
459  //fprintf(stdout,"ask to classify\n");
+
460  //mil=classify(blobs, index);
+
461  //fprintf(stdout,"done classifying\n");
+
462  //get the type of the blob
+
463  //Bottle type;
+
464  //fprintf(stdout,"ask to get type\n");
+
465  //type=getType(&mil, index);
+
466 
+
467  fprintf(stdout, "The type is: %s and object name requested is: %s\n\n", classResults.get(x).asString().c_str(), objName.c_str() );
+
468 
+
469  if (classResults.get(x).asString() == objName)
+
470  {
+
471 
+
472  pointLocation = getBlobCOG(blobs,index);
+
473  fprintf (stdout,"point is %d %d \n", pointLocation.x, pointLocation.y);
+
474  fprintf(stdout,"I have found the requested object %s, at: %d %d\n",objName.c_str(), pointLocation.x, pointLocation.y );
+
475  loc.addInt (pointLocation.x);
+
476  loc.addInt (pointLocation.y);
+
477  }
+
478  }
+
479  }
+
480 
+
481  return loc;
+
482 }
+
483 
+
484 /**********************************************************/
+
485 int Manager::executeToolOnLoc()
+
486 {
+
487  fprintf(stdout, "\n\n\n****************************************************************************\n\n" );
+
488  Bottle blobs;
+
489  blobs.clear();
+
490  // grab the blobs
+
491  blobs=getBlobs();
+
492  // failure handling
+
493  if (blobs.size()==0)
+
494  return RET_INVALID;
+
495 
+
496  if (blobs.size()<2)
+
497  {
+
498  pointLocation = getBlobCOG(blobs,0);
+
499  fprintf (stdout,"point is %d %d \n", pointLocation.x, pointLocation.y);
+
500  pointGood = true;
+
501  }
+
502  else
+
503  {
+
504  fprintf (stdout,"I see more than two blobs\n");
+
505  pointGood = false;
+
506  }
+
507  if (pointGood)
+
508  {
+
509  Bottle closestBlob;
+
510  mutexResources.lock();
+
511  closestBlob=findClosestBlob(blobs,pointLocation);
+
512  mutexResources.unlock();
+
513 
+
514  cv::Point cog;
+
515  cog.x = closestBlob.get(0).asInt();
+
516  cog.y = closestBlob.get(1).asInt();
+
517 
+
518  /*
+
519  * segment the object
+
520  */
+
521  segmentAndTrack(cog.x, cog.y);
+
522 
+
523  int index = 0;
+
524  index = closestBlob.get(2).asInt();
+
525 
+
526 
+
527  fprintf(stdout, "closest blob is x:%d y:%d with index %d\n\n", cog.x, cog.y, index);
+
528  }
+
529  return 0;
+
530 }
+
531 /**********************************************************/
+
532 Bottle Manager::findBlobLoc()
+
533 {
+
534  Bottle loc;
+
535  loc.clear();
+
536  fprintf(stdout, "\n\n\nfindBlobLoc****************************************************************************\n\n" );
+
537  Bottle blobs;
+
538  blobs.clear();
+
539  bool invalid = false;
+
540  // grab the blobs
+
541  blobs=getBlobs();
+
542  // failure handling
+
543  if (blobs.size()==0)
+
544  {
+
545  fprintf (stdout,"INVALID BLOB SIZE\n");
+
546  invalid = true;
+
547  }
+
548 
+
549  latchTimer = 0.0;
+
550 
+
551  if (blobs.size()<2 && !invalid)
+
552  {
+
553  pointLocation = getBlobCOG(blobs,0);
+
554  fprintf (stdout,"point is %d %d \n", pointLocation.x, pointLocation.y);
+
555  pointGood = true;
+
556  }
+
557  else
+
558  {
+
559  fprintf (stdout,"I either see more than two blobs or nothing at all\n");
+
560  pointGood = false;
+
561  }
+
562  if (pointGood)
+
563  {
+
564  Bottle closestBlob;
+
565  mutexResources.lock();
+
566  closestBlob=findClosestBlob(blobs,pointLocation);
+
567  mutexResources.unlock();
+
568 
+
569  cv::Point cog;
+
570  cog.x = closestBlob.get(0).asInt();
+
571  cog.y = closestBlob.get(1).asInt();
+
572 
+
573  /*
+
574  * segment the object
+
575  */
+
576  //segmentAndTrack(cog.x, cog.y);
+
577 
+
578  int index = 0;
+
579  index = closestBlob.get(2).asInt();
+
580 
+
581  fprintf(stdout, "closest blob is x:%d y:%d with index %d\n\n", cog.x, cog.y, index);
+
582 
+
583  Vector initPos;
+
584  if (get3DPosition(cog,initPos))
+
585  {
+
586  loc.addDouble(initPos[0]);
+
587  loc.addDouble(initPos[1]);
+
588  loc.addDouble(initPos[2]);
+
589  fprintf(stdout,"Got a 3D point at %lf %lf %lf \n", initPos[0], initPos[1],initPos[2]);
+
590  }
+
591  }
+
592  return loc;
+
593 }
+
594 
+
595 /**********************************************************/
+
596 bool Manager::executePCLGrasp( const string &objName )
+
597 {
+
598  fprintf(stdout, "\n\n\nexecutePCLGrasp****************************************************************************\n\n" );
+
599  executeSpeech ("ok, will now try to grasp the "+ objName);
+
600  Bottle blobs;
+
601  blobs.clear();
+
602  bool invalid = false;
+
603  bool isGrasped = false;
+
604  cv::Point locObj;
+
605  Bottle result;
+
606  result.clear();
+
607 
+
608  fprintf(stdout, "releasing head\n");
+
609  //here put head in bind 5.0 and in idle
+
610  Bottle cmdAre, replyAre;
+
611  cmdAre.clear();
+
612  replyAre.clear();
+
613  cmdAre.addString("release");
+
614  rpcMotorAre.write(cmdAre,replyAre);
+
615  fprintf(stdout, "the reply is: %s \n",replyAre.toString().c_str());
+
616 
+
617  Time::delay(3.0);
+
618  // grab the blobs
+
619  blobs=getBlobs();
+
620  // failure handling
+
621  if (blobs.size()==0)
+
622  {
+
623  invalid = true;
+
624  return false;
+
625  }
+
626  latchTimer = 0.0;
+
627 
+
628  if ( !invalid )
+
629  {
+
630  result = executeBlobRecog(objName);
+
631  locObj.x = result.get(0).asInt();
+
632  locObj.y = result.get(1).asInt();
+
633 
+
634  fprintf (stdout,"point is %d %d \n", locObj.x, locObj.y);
+
635  pointGood = true;
+
636  }
+
637  else
+
638  {
+
639  fprintf (stdout,"I have an issue spotting the %s\n",objName.c_str());
+
640  executeSpeech ("I can't seem to find the "+ objName);
+
641  pointGood = false;
+
642  }
+
643  if (pointGood)
+
644  {
+
645  objectPos.clear();
+
646  if (get3DPosition(locObj,objectPos))
+
647  {
+
648  fprintf(stdout,"Got a 3D point at %lf %lf %lf \n", objectPos[0], objectPos[1],objectPos[2]);
+
649  //check 3D point
+
650 
+
651  if (objectPos[0] < -0.47 )
+
652  {
+
653  executeSpeech ("I cannot safely reach for the "+ objName + ", will try to find a solution");
+
654  fprintf(stdout, "I cannot reach for this object, will find a solution\n");
+
655  Bottle cmdHome, cmdReply;
+
656  cmdHome.clear();
+
657  cmdReply.clear();
+
658  cmdHome.addString("home");
+
659  cmdHome.addString("all");
+
660  rpcMotorAre.write(cmdHome,cmdReply);
+
661  Time::delay(2.0);
+
662  executeToolSearchOnLoc( objName );
+
663  }
+
664  else
+
665  {
+
666  //should figure out if the 3D position is close enough to grasp or need tool to reach it
+
667  fprintf(stdout,"Will now send the blob to graphsegmentation:\n");
+
668  Bottle segCmd, segReply;
+
669  segCmd.clear();
+
670  segReply.clear();
+
671  segCmd.addInt(locObj.x);
+
672  segCmd.addInt(locObj.y);
+
673  fprintf(stdout, "the cmd is: %s \n",segCmd.toString().c_str());
+
674  rpcReconstruct.write(segCmd, segReply);
+
675  fprintf(stdout, "the reply is: %s \n",segReply.toString().c_str());
+
676 
+
677  fprintf(stdout,"Will now ask for 3Dreconstruction:\n");
+
678  segCmd.clear();
+
679  segReply.clear();
+
680  segCmd.addString("3Drec");
+
681  segCmd.addString(objName);
+
682 
+
683  fprintf(stdout, "the cmd is: %s \n", segCmd.toString().c_str());
+
684  rpcReconstruct.write(segCmd, segReply);
+
685  fprintf(stdout, "the reply is: %s \n",segReply.toString().c_str());
+
686 
+
687  //should now ask if the grasp action has been accomplished
+
688  Bottle cmd, reply;
+
689  latchTimer=Time::now();
+
690 
+
691  while (!isGrasped)
+
692  {
+
693  cmd.clear();
+
694  reply.clear();
+
695  cmd.addString("isGrasped");
+
696  fprintf(stdout, "the cmd is: %s \n", cmd.toString().c_str());
+
697  rpcGraspEstimate.write(cmd,reply);
+
698  string rep=reply.toString().c_str();
+
699  rep.erase (rep.begin());
+
700  rep.erase (rep.begin()+4);
+
701 
+
702  if (rep == "true")
+
703  isGrasped = true;
+
704 
+
705  Time::delay(0.5);
+
706  if ((Time::now()-latchTimer)>idleTmo)
+
707  {
+
708  fprintf(stdout,"--- Timeout elapsed ---\n");
+
709  break;
+
710  }
+
711  }
+
712 
+
713  if (isGrasped)
+
714  {
+
715  fprintf(stdout, "Grasped finished\n");
+
716  Time::delay(3.0);
+
717  fprintf(stdout, "Now Releasing...\n");
+
718 
+
719  cmd.clear();
+
720  reply.clear();
+
721  cmd.addString("release");
+
722  fprintf(stdout, "the cmd is: %s \n", cmd.toString().c_str());
+
723  rpcGraspEstimate.write(cmd,reply);
+
724  fprintf(stdout, "the reply is: %s \n",reply.toString().c_str());
+
725  Time::delay(3.0);
+
726  }
+
727  else
+
728  {
+
729  Bottle cmd, rep;
+
730  cmd.clear();
+
731  rep.clear();
+
732  cmd.addString("home");
+
733  cmd.addString("all");
+
734  rpcMotorAre.write(cmd,rep);
+
735 
+
736  Bottle cmdAre, replyAre;
+
737  cmdAre.clear();
+
738  replyAre.clear();
+
739  cmdAre.addString("release");
+
740  rpcMotorAre.write(cmdAre,replyAre);
+
741  fprintf(stdout, "the reply is: %s \n",replyAre.toString().c_str());
+
742 
+
743  executeSpeech ("sorry I could not figure out how to do this");
+
744  fprintf(stdout, "did not seem to be able to grasp correctly or has been aborted\n");
+
745  }
+
746  }
+
747  }
+
748  fprintf(stdout, "Finished the grasping sequence \n");
+
749 
+
750  Bottle cmd, rep;
+
751  cmd.clear();
+
752  rep.clear();
+
753  cmd.addString("home");
+
754  cmd.addString("all");
+
755  rpcMotorAre.write(cmd,rep);
+
756 
+
757  }
+
758  return isGrasped;
+
759 }
+
760 
+
761 /**********************************************************/
+
762 
+
763 int Manager::executeToolSearchOnLoc( const string &objName )
+
764 {
+
765  fprintf(stdout, "\n\n\nexecuteToolSearchOnLoc****************************************************************************\n\n" );
+
766  Bottle blobs;
+
767  blobs.clear();
+
768  // grab the blobs
+
769  blobs=getBlobs();
+
770  // failure handling
+
771  Bottle result;
+
772  cv::Point objLoc;
+
773 
+
774  int objIndex = 0;
+
775 
+
776  if (blobs.size()==0)
+
777  return RET_INVALID;
+
778 
+
779  result = executeBlobRecog(objName);
+
780  objLoc.x = result.get(0).asInt();
+
781  objLoc.y = result.get(1).asInt();
+
782 
+
783  blobsDetails = new blobsData[blobs.size()];
+
784 
+
785  Bottle memCmd, memRep;
+
786  memCmd.clear(); memRep.clear();
+
787  memCmd.addVocab(Vocab::encode("ask"));
+
788  Bottle &tmp=memCmd.addList();
+
789  tmp.addString ("all");
+
790  rpcOPC.write(memCmd,memRep);
+
791 
+
792  fprintf(stdout, "THE REPLY IS %s \n",memRep.toString().c_str());
+
793 
+
794  int sizeInMem =0;
+
795 
+
796  if (memRep.get(0).asVocab()==Vocab::encode("ack"))
+
797  {
+
798  if (Bottle *idField = memRep.get(1).asList())
+
799  {
+
800  if (Bottle *idVals = idField->get(1).asList())
+
801  {
+
802  sizeInMem = idVals->size();
+
803  sizeInMem = sizeInMem - 1; //remove the table
+
804  fprintf (stdout,"******************************************size is %d \n", sizeInMem);
+
805  }
+
806  }
+
807  }
+
808 
+
809 
+
810 
+
811  bool valid = false;
+
812  if (blobs.size() == sizeInMem)
+
813  valid = true;
+
814  else
+
815  executeSpeech ("sorry Something is wrong with the objects");
+
816 
+
817 
+
818  Bottle classResults = classifyThem();
+
819 
+
820  if (valid)
+
821  {
+
822  //figure out how many blobs are available
+
823  for (int x=0; x < blobs.size(); x++)
+
824  {
+
825  pointLocation = getBlobCOG(blobs,x);
+
826  fprintf (stdout,"point is %d %d \n", pointLocation.x, pointLocation.y);
+
827  fprintf (stdout,"object is %d %d \n", objLoc.x, objLoc.y);
+
828 
+
829  Bottle closestBlob;
+
830  mutexResources.lock();
+
831  closestBlob=findClosestBlob(blobs,pointLocation);
+
832  mutexResources.unlock();
+
833 
+
834  fprintf(stdout, "checkin if objDiff x %d objDiff y %d \n",abs( objLoc.x - pointLocation.x), abs( objLoc.y - pointLocation.y));
+
835 
+
836  if ( abs( objLoc.x - pointLocation.x) < 5 && abs( objLoc.y - pointLocation.y) < 5)
+
837  {
+
838  objIndex = x;
+
839  fprintf(stdout, "I have found the object of interest and not considering it.\n");
+
840  }
+
841  else
+
842  {
+
843  fprintf(stdout, "\n\n\n\nI AM IN SETTING UP BLOBS with blob size = %d and x= %d\n\n\n\n",blobs.size(), x);
+
844  Bottle blobs;
+
845  blobs.clear();
+
846  // grab the blobs
+
847  blobs=getBlobs();
+
848 
+
849  blobsDetails[x].posistion.x = (int) closestBlob.get(0).asDouble();
+
850  blobsDetails[x].posistion.y = (int) closestBlob.get(1).asDouble();
+
851  blobsDetails[x].index = closestBlob.get(2).asInt();
+
852  blobsDetails[x].lenght = 0.0;
+
853  blobsDetails[x].lenght = getBlobLenght(blobs, x);
+
854  blobsDetails[x].vdrawError = 0.0;
+
855 
+
856  //Bottle mil;
+
857  //mil.clear();
+
858  //fprintf(stdout,"ask to classify \n ");
+
859  //mil=classify(blobs, x);
+
860  //fprintf(stdout,"done classifying\n");
+
861  //Bottle type;
+
862  //type.clear();
+
863  //fprintf(stdout,"ask to get type\n");
+
864  //type=getType(&mil, x);
+
865  blobsDetails[x].name = classResults.get(x).asString();
+
866 
+
867  fprintf(stdout, "SO: name is: %s x is %d u is %d index is %d\n",blobsDetails[x].name.c_str(),blobsDetails[x].posistion.x, blobsDetails[x].posistion.y, blobsDetails[x].index);
+
868 
+
869  //should look at x y
+
870  /*Bottle cmdAre, replyAre;
+
871  cmdAre.clear();
+
872  replyAre.clear();
+
873  cmdAre.addString("look");
+
874  Bottle &tmp=cmdAre.addList();
+
875  tmp.addInt (blobsDetails[x].posistion.x);
+
876  tmp.addInt (blobsDetails[x].posistion.y);
+
877  rpcMotorAre.write(cmdAre,replyAre);
+
878  fprintf(stdout,"looking started %s:\n",replyAre.toString().c_str());*/
+
879  }
+
880  }
+
881  fprintf(stdout, "\n\n\n\nI AM OUT SETTING UP BLOBS \n\n\n\n");
+
882  Bottle homeAfterLookCmd, homeAfterLookReply;
+
883  homeAfterLookCmd.clear();
+
884  homeAfterLookReply.clear();
+
885  homeAfterLookCmd.addString("home");
+
886  homeAfterLookCmd.addString("head");
+
887  rpcMotorAre.write(homeAfterLookCmd,homeAfterLookReply);
+
888 
+
889  int toolLenght = 1000;
+
890  int smallIndex = -1;
+
891  int bigIndex = -1;
+
892  fprintf(stdout,"\n\n");
+
893  for (int x=0; x < blobs.size(); x++)
+
894  {
+
895  if ( x!=objIndex)
+
896  {
+
897  fprintf(stdout,"The lenght is %lf, with index %d\n",blobsDetails[x].lenght, x);
+
898  // figure out if using small or big tool
+
899  if (blobsDetails[x].lenght < toolLenght )
+
900  {
+
901  toolLenght=(int)blobsDetails[x].lenght;
+
902  smallIndex = x;
+
903  }
+
904  }
+
905  }
+
906  for (int x=0; x < blobs.size(); x++)
+
907  {
+
908  if ( x!=objIndex && x!=smallIndex)
+
909  bigIndex = x;
+
910  }
+
911 
+
912  //this needs to be changed and filled in by milClassifier
+
913 
+
914  fprintf(stdout,"The small tool is the blob index %d \n",smallIndex);
+
915  blobsDetails[smallIndex].name = "small";
+
916 
+
917  fprintf(stdout,"The big tool is the blob index %d \n", bigIndex);
+
918  blobsDetails[bigIndex].name = "big";
+
919 
+
920  fprintf(stdout,"\n\n");
+
921 
+
922  Bottle small, big;
+
923 
+
924  small.clear();
+
925  small = executeKarmaOptimize(toolSmall, blobsDetails[smallIndex].name);
+
926  blobsDetails[smallIndex].bestAngle = small.get(1).asDouble();
+
927  blobsDetails[smallIndex].bestDistance = small.get(2).asDouble();
+
928 
+
929  big.clear();
+
930  big = executeKarmaOptimize(toolBig, blobsDetails[bigIndex].name);
+
931  blobsDetails[bigIndex].bestAngle = big.get(1).asDouble();
+
932  blobsDetails[bigIndex].bestDistance = big.get(2).asDouble();
+
933 
+
934  fprintf(stdout,"\n\n");
+
935 
+
936  //Attach the tool
+
937  executeToolAttach(toolSmall);
+
938  double virtualtmp = 0.01;
+
939 
+
940  //setup all parameters to get the best possible configuration
+
941  while (virtualtmp > 0.0 && virtualtmp < 0.08 )
+
942  {
+
943  virtualtmp = executeVirtualDraw(blobsDetails[smallIndex]);
+
944  if (virtualtmp > 0.1)
+
945  blobsDetails[smallIndex].bestDistance -= 0.005;
+
946  else if (virtualtmp > 1.0)
+
947  blobsDetails[smallIndex].bestDistance -= 0.1;
+
948  else
+
949  blobsDetails[smallIndex].bestDistance += 0.005;
+
950 
+
951  fprintf(stdout, "the reply is: %lf \n",virtualtmp);
+
952  }
+
953 
+
954  //do it one last time to get the correct confidence
+
955  blobsDetails[smallIndex].vdrawError = executeVirtualDraw(blobsDetails[smallIndex]);
+
956  fprintf (stdout, "\n\nTHE BEST ANGLE IS %lf WITH DISTANCE %lf with confidence %lf\n\n",blobsDetails[smallIndex].bestAngle, blobsDetails[smallIndex].bestDistance, blobsDetails[smallIndex].vdrawError );
+
957 
+
958  //Attach the tool
+
959  executeToolAttach(toolBig);
+
960  virtualtmp = 0.01;
+
961  //setup all parameters to get the best possible configuration
+
962  while (virtualtmp > 0.0 && virtualtmp < 0.08 )
+
963  {
+
964  virtualtmp = executeVirtualDraw(blobsDetails[bigIndex]);
+
965  if (virtualtmp > 0.1)
+
966  blobsDetails[bigIndex].bestDistance -= 0.005;
+
967  else if (virtualtmp > 1.0)
+
968  blobsDetails[bigIndex].bestDistance -= 0.1;
+
969  else
+
970  blobsDetails[bigIndex].bestDistance += 0.005;
+
971 
+
972  fprintf(stdout, "the reply is: %lf \n",virtualtmp);
+
973  }
+
974 
+
975  //do it one last time to get the correct confidence
+
976  blobsDetails[bigIndex].vdrawError = executeVirtualDraw(blobsDetails[bigIndex]);
+
977  fprintf (stdout, "\n\nTHE BEST ANGLE IS %lf WITH DISTANCE %lf and confidence %lf\n\n",blobsDetails[bigIndex].bestAngle, blobsDetails[bigIndex].bestDistance, blobsDetails[bigIndex].vdrawError );
+
978 
+
979  int whichArm = 0;
+
980  Bottle cmdHome, cmdReply;
+
981  cmdHome.clear();
+
982  cmdReply.clear();
+
983  cmdHome.addString("home");
+
984  cmdHome.addString("head");
+
985  rpcMotorAre.write(cmdHome,cmdReply);
+
986 
+
987  //once blobs and vdraw has been determined compare them
+
988  double bestChoice = 1000.0;
+
989  int bestIndex = -1;
+
990  double bestDistance = -1;
+
991  for (int x=0; x < blobs.size(); x++)
+
992  {
+
993  if (blobsDetails[x].vdrawError < bestChoice && blobsDetails[x].bestDistance > bestDistance && x != objIndex)
+
994  //if ( blobsDetails[x].bestDistance > bestDistance && x != objIndex)
+
995  {
+
996  bestDistance = blobsDetails[x].bestDistance;
+
997  //bestChoice = blobsDetails[x].vdrawError;
+
998  bestIndex = x;
+
999  }
+
1000  }
+
1001 
+
1002  //HERE DO MAXIMUM DISTANCE CHECK... -0.40 -0.33
+
1003  string tmpObjName = blobsDetails[bestIndex].name;
+
1004  executeSpeech ("can you give me the " + tmpObjName + "please?");
+
1005 
+
1006  //objectPos[0] has the oject position -0.43 is the maximum distance
+
1007 
+
1008  //blobsDetails[bestIndex].bestDistance = blobsDetails[bestIndex].bestDistance - 0.05;
+
1009  //figure out best distance fro subsequent grasp
+
1010 
+
1011  double max = -0.35;
+
1012  blobsDetails[bestIndex].bestDistance = fabs(objectPos[0]) - fabs( max );
+
1013 
+
1014  fprintf(stdout, "*********************************************************************************\n");
+
1015  fprintf(stdout, "THE MAX DISTANCE I WILL DO IS %lf\n,",blobsDetails[bestIndex].bestDistance);
+
1016  fprintf(stdout, "*********************************************************************************\n");
+
1017 
+
1018  //blobsDetails[bestIndex].bestDistance = blobsDetails[bestIndex].bestDistance - 0.01;
+
1019 
+
1020  Bottle cmdAre, replyAre;
+
1021  cmdAre.clear();
+
1022  replyAre.clear();
+
1023  cmdAre.addString("point");
+
1024  Bottle &tmp=cmdAre.addList();
+
1025  tmp.addInt (blobsDetails[bestIndex].posistion.x);
+
1026  tmp.addInt (blobsDetails[bestIndex].posistion.y);
+
1027 
+
1028  bool sendAction = true;
+
1029  if (blobsDetails[bestIndex].posistion.x > 0 && blobsDetails[bestIndex].posistion.x < 160 )
+
1030  {
+
1031  whichArm = 0;
+
1032  cmdAre.addString("left");
+
1033  }
+
1034  else if (blobsDetails[bestIndex].posistion.x > 160 && blobsDetails[bestIndex].posistion.x < 320 )
+
1035  {
+
1036  whichArm = 1;
+
1037  cmdAre.addString("right");
+
1038  }
+
1039  else
+
1040  {
+
1041  executeSpeech ("oh my...I seemed to got confused...sorry");
+
1042  fprintf(stdout, "something is wrong with the action:\n");
+
1043  sendAction = false;
+
1044  }
+
1045 
+
1046  fprintf(stdout, "the cmd is: %s \n",cmdAre.toString().c_str());
+
1047  if (sendAction)
+
1048  {
+
1049  rpcMotorAre.write(cmdAre,replyAre);
+
1050  fprintf(stdout, "the reply is: %s \n",replyAre.toString().c_str());
+
1051  }
+
1052 
+
1053 
+
1054  if (sendAction)
+
1055  {
+
1056  executeGiveAction(whichArm);
+
1057  Time::delay(5.0);
+
1058  }
+
1059  if (sendAction)
+
1060  {
+
1061  executeCloseHand(whichArm);
+
1062  Time::delay(5.0);
+
1063  }
+
1064 
+
1065  Bottle homeCmd, homeReply;
+
1066  homeCmd.clear();
+
1067  homeReply.clear();
+
1068  homeCmd.addString("home");
+
1069  homeCmd.addString("arms");
+
1070  homeCmd.addString("head");
+
1071  rpcMotorAre.write(homeCmd,homeReply);
+
1072 
+
1073  if (tmpObjName == "small")
+
1074  executeToolAttach(toolSmall);
+
1075  else
+
1076  executeToolAttach(toolBig);
+
1077 
+
1078  if (sendAction)
+
1079  executeToolDrawNear(blobsDetails[bestIndex]);
+
1080 
+
1081  Bottle homeToolcmd, homeToolrep;
+
1082  homeToolcmd.clear();
+
1083  homeToolrep.clear();
+
1084  homeToolcmd.addString("home");
+
1085  homeToolcmd.addString("arms");
+
1086  homeToolcmd.addString("head");
+
1087  rpcMotorAre.write(homeToolcmd,homeToolrep);
+
1088 
+
1089  executeSpeech ("Ok, thank you");
+
1090 
+
1091  if (sendAction)
+
1092  executeDropAway(whichArm);
+
1093 
+
1094  if (sendAction)
+
1095  executePCLGrasp( objName );
+
1096  }
+
1097 
+
1098  return 0;
+
1099 }
+
1100 /**********************************************************/
+
1101 bool Manager::executeDropAway(int ARM)
+
1102 {
+
1103  Bottle cmdAre, replyAre;
+
1104  cmdAre.clear();
+
1105  replyAre.clear();
+
1106  cmdAre.addString("drop");
+
1107  cmdAre.addString("away");
+
1108  if (ARM == LEFTARM)
+
1109  cmdAre.addString("left");
+
1110  else
+
1111  cmdAre.addString("right");
+
1112 
+
1113  rpcMotorAre.write(cmdAre,replyAre);
+
1114 
+
1115  printf("done deploying\n");
+
1116  return true;
+
1117 }
+
1118 /**********************************************************/
+
1119 int Manager::executeToolAttach(const Vector &tool)
+
1120 {
+
1121  fprintf(stdout,"Will now send to karmaMotor:\n");
+
1122  Bottle karmaMotor,KarmaReply;
+
1123  karmaMotor.addString("tool");
+
1124  karmaMotor.addString("remove");
+
1125  rpcMotorKarma.write(karmaMotor, KarmaReply);
+
1126 
+
1127  karmaMotor.clear();KarmaReply.clear();
+
1128  karmaMotor.addString("tool");
+
1129  karmaMotor.addString("attach");
+
1130  karmaMotor.addString("right");
+
1131  karmaMotor.addDouble(tool[0]);
+
1132  karmaMotor.addDouble(tool[1]);
+
1133  karmaMotor.addDouble(tool[2]);
+
1134  fprintf(stdout,"%s\n",karmaMotor.toString().c_str());
+
1135  rpcMotorKarma.write(karmaMotor, KarmaReply);
+
1136  fprintf(stdout,"reply is %s:\n",KarmaReply.toString().c_str());
+
1137  return 1;
+
1138 }
+
1139 /**********************************************************/
+
1140 Bottle Manager::executeKarmaOptimize(const Vector &tool, const string &name)
+
1141 {
+
1142  Bottle cmdLearn, cmdReply;
+
1143  cmdLearn.clear();
+
1144  cmdReply.clear();
+
1145  cmdLearn.addString("optimize");
+
1146  cmdLearn.addString(name);
+
1147  fprintf(stdout, "the cmd is: %s \n",cmdLearn.toString().c_str());
+
1148  rpcKarmaLearn.write(cmdLearn, cmdReply);
+
1149  fprintf(stdout, "the reply is: %s \n",cmdReply.toString().c_str());
+
1150 
+
1151  double optAng = cmdReply.get(1).asDouble();
+
1152  double optDisp = cmdReply.get(2).asDouble();
+
1153 
+
1154  fprintf(stdout, "the optimum angle is %lf with optimum disp %lf\n ",optAng , optDisp);
+
1155  return cmdReply;
+
1156 }
+
1157 /**********************************************************/
+
1158 double Manager::executeToolDrawNear(blobsData &blobsDetails)
+
1159 {
+
1160  double result = 0.0;
+
1161  //for (int tools = 0; tools < blobs.size(); tools++)
+
1162  fprintf(stdout,"Will now send to karmaMotor using %s as a tool:\n", blobsDetails.name.c_str());
+
1163  Bottle karmaMotor,KarmaReply;
+
1164  karmaMotor.addString("draw");
+
1165  karmaMotor.addDouble(objectPos[0]);
+
1166  karmaMotor.addDouble(objectPos[1]);
+
1167  karmaMotor.addDouble(objectPos[2]);
+
1168  karmaMotor.addDouble(blobsDetails.bestAngle);
+
1169  karmaMotor.addDouble(0.12); //10 cm
+
1170  karmaMotor.addDouble(blobsDetails.bestDistance);
+
1171  fprintf(stdout,"%s\n",karmaMotor.toString().c_str());
+
1172  rpcMotorKarma.write(karmaMotor, KarmaReply);
+
1173  fprintf(stdout,"vdraw is %s:\n",KarmaReply.toString().c_str());
+
1174  result = KarmaReply.get(1).asDouble();
+
1175  return result;
+
1176 }
+
1177 /**********************************************************/
+
1178 double Manager::executeVirtualDraw(blobsData &blobsDetails)
+
1179 {
+
1180  double result = 0.0;
+
1181  //for (int tools = 0; tools < blobs.size(); tools++)
+
1182  fprintf(stdout,"Will now send to karmaMotor:\n");
+
1183  Bottle karmaMotor,KarmaReply;
+
1184  karmaMotor.addString("vdraw");
+
1185  karmaMotor.addDouble(objectPos[0]);
+
1186  karmaMotor.addDouble(objectPos[1]);
+
1187  karmaMotor.addDouble(objectPos[2]);
+
1188  karmaMotor.addDouble(blobsDetails.bestAngle);
+
1189  karmaMotor.addDouble(0.1); //10 cm
+
1190  karmaMotor.addDouble(blobsDetails.bestDistance);
+
1191 
+
1192 
+
1193  fprintf(stdout,"%s\n",karmaMotor.toString().c_str());
+
1194  rpcMotorKarma.write(karmaMotor, KarmaReply);
+
1195  fprintf(stdout,"vdraw is %s:\n",KarmaReply.toString().c_str());
+
1196  result = KarmaReply.get(1).asDouble();
+
1197  return result;
+
1198 }
+
1199 /**********************************************************/
+
1200 bool Manager::executeGiveAction(int ARM)
+
1201 {
+
1202 
+
1203  Bottle cmdAre, replyAre;
+
1204  cmdAre.clear();
+
1205  replyAre.clear();
+
1206  cmdAre.addString("tato");
+
1207  if (ARM == LEFTARM)
+
1208  cmdAre.addString("left");
+
1209  else
+
1210  cmdAre.addString("right");
+
1211 
+
1212  rpcMotorAre.write(cmdAre,replyAre);
+
1213 
+
1214  return true;
+
1215 }
+
1216 /**********************************************************/
+
1217 bool Manager::executeCloseHand (int ARM)
+
1218 {
+
1219 
+
1220  Bottle cmdAre, replyAre;
+
1221  cmdAre.clear();
+
1222  replyAre.clear();
+
1223  cmdAre.addString("close");
+
1224  if (ARM == LEFTARM)
+
1225  cmdAre.addString("left");
+
1226  else
+
1227  cmdAre.addString("right");
+
1228 
+
1229  rpcMotorAre.write(cmdAre,replyAre);
+
1230 
+
1231  printf("done closing\n");
+
1232  return true;
+
1233 }
+
1234 
+
1235 /**********************************************************/
+
1236 bool Manager::executeSpeech (const string &speech)
+
1237 {
+
1238  Bottle cmdIol;
+
1239  Bottle replyIol;
+
1240  cmdIol.clear(), replyIol.clear();
+
1241  cmdIol.addString("say");
+
1242  cmdIol.addString(speech);
+
1243  iolStateMachine.write(cmdIol,replyIol);
+
1244  fprintf(stdout,"%s\n", replyIol.toString().c_str());
+
1245  return true;
+
1246 }
+
1247 
+
1248 /**********************************************************/
+
1249 int Manager::executeOnLoc(bool shouldTrain)
+
1250 {
+
1251  fprintf(stdout, "\n\n\n****************************************************************************\n\n" );
+
1252  Bottle blobs;
+
1253  blobs.clear();
+
1254  // grab the blobs
+
1255  blobs=getBlobs();
+
1256  // failure handling
+
1257 
+
1258  if (blobs.size()==0)
+
1259  return RET_INVALID;
+
1260 
+
1261  if (blobs.size()<2)
+
1262  {
+
1263  pointLocation = getBlobCOG(blobs,0);
+
1264  fprintf (stdout,"point is %d %d \n", pointLocation.x, pointLocation.y);
+
1265  pointGood = true;
+
1266  }
+
1267  else
+
1268  {
+
1269  fprintf (stdout,"I see more than two blobs\n");
+
1270  pointGood = false;
+
1271  }
+
1272  if (pointGood)
+
1273  {
+
1274  Bottle closestBlob;
+
1275  mutexResources.lock();
+
1276  closestBlob=findClosestBlob(blobs,pointLocation);
+
1277  mutexResources.unlock();
+
1278 
+
1279  cv::Point cog;
+
1280  cog.x = closestBlob.get(0).asInt();
+
1281  cog.y = closestBlob.get(1).asInt();
+
1282 
+
1283  /*
+
1284  * segment the object
+
1285  */
+
1286  segmentAndTrack(cog.x, cog.y);
+
1287 
+
1288  int index = 0;
+
1289  index = closestBlob.get(2).asInt();
+
1290 
+
1291  fprintf(stdout, "closest blob is x:%d y:%d with index %d\n\n",cog.x, cog.y, index);
+
1292 
+
1293  //classify the blob
+
1294  Bottle mil;
+
1295  mil=classify(blobs, index);
+
1296  //get the type of the blob
+
1297  Bottle type;
+
1298  type=getType(&mil, index);
+
1299 
+
1300  double actionOrient = 0.0;
+
1301  int guessAction=(int)Rand::scalar(0,randActions.size());
+
1302  fprintf(stdout, "the guess action is %d chosen from size %d\n", guessAction, (int)randActions.size());
+
1303 
+
1304  double orient = 0.0;
+
1305  orient = closestBlob.get(3).asDouble();
+
1306 
+
1307  if (!shouldTrain)
+
1308  {
+
1309  fprintf(stdout,"SHOULD BE IN TEST MODE!\n");
+
1310  Bottle cmdLearn, cmdReply;
+
1311  cmdLearn.clear();
+
1312  cmdReply.clear();
+
1313  cmdLearn.addString("optimize");
+
1314  cmdLearn.addString(obj);
+
1315  /*Bottle &angles = cmdLearn.addList();
+
1316  for (int i = 0; i< randActions.size(); i++)
+
1317  {
+
1318  angles.addDouble(randActions[i]);
+
1319  }*/
+
1320  fprintf(stdout, "the cmd is: %s \n",cmdLearn.toString().c_str());
+
1321  rpcKarmaLearn.write(cmdLearn, cmdReply);
+
1322  fprintf(stdout, "the reply is: %s \n",cmdReply.toString().c_str());
+
1323 
+
1324  double optAng = cmdReply.get(1).asDouble();
+
1325  double optDisp = cmdReply.get(2).asDouble();
+
1326 
+
1327  fprintf(stdout, "the optimum angle is %lf with optimum disp %lf\n ",optAng , optDisp);
+
1328 
+
1329  Vector initPos;
+
1330  actionOrient = 0.0;
+
1331  actionOrient = optAng + orient;
+
1332 
+
1333  if (actionOrient > 360.0)
+
1334  actionOrient -= 360.0;
+
1335 
+
1336  if (actionOrient > 45.0 && actionOrient < 135.0)
+
1337  actionOrient += 180.0;
+
1338 
+
1339  fprintf(stdout, "\n\nthe FINAL angle is %lf \n\n",actionOrient);
+
1340  }
+
1341  else
+
1342  {
+
1343  fprintf(stdout,"SHOULD BE IN TRAIN MODE!\n");
+
1344  if (userTheta >= 0.0)
+
1345  actionOrient = userTheta;
+
1346  else
+
1347  actionOrient = Rand::scalar(-210.0,30.0);//randActions[guessAction];
+
1348  }
+
1349 
+
1350  Vector initPos;
+
1351  double finalOrient;
+
1352  if (get3DPosition(cog,initPos))
+
1353  {
+
1354  Bottle results;
+
1355  double offset = 0.0;
+
1356  results = getOffset(closestBlob, actionOrient, initPos);
+
1357  offset = results.get(0).asDouble();
+
1358  finalOrient = results.get(1).asDouble();
+
1359 
+
1360  fprintf(stdout,"Will now send to karmaMotor:\n");
+
1361  Bottle karmaMotor,KarmaReply;
+
1362  karmaMotor.addString("push");
+
1363  karmaMotor.addDouble(initPos[0]);
+
1364  karmaMotor.addDouble(initPos[1]);
+
1365  karmaMotor.addDouble(initPos[2] + 0.05);
+
1366  karmaMotor.addDouble(actionOrient);
+
1367  karmaMotor.addDouble( offset );// + 0.06 );
+
1368 
+
1369  fprintf(stdout,"%s\n",karmaMotor.toString().c_str());
+
1370  rpcMotorKarma.write(karmaMotor, KarmaReply);
+
1371  fprintf(stdout,"action is %s:\n",KarmaReply.toString().c_str());
+
1372 
+
1373  cv::Point finalPoint;
+
1374  if (particleFilter.getTraker(finalPoint))
+
1375  {
+
1376  while(finalPoint.x <1 && finalPoint.x >320 && finalPoint.y <1 && finalPoint.y >240)
+
1377  {
+
1378  fprintf(stdout, "\n\n\ndid not get a correct final point from particle filter..retrying...\n\n\n");
+
1379  particleFilter.getTraker(finalPoint);
+
1380  }
+
1381  Vector finalPos;
+
1382  if (get3DPosition(finalPoint,finalPos))
+
1383  {
+
1384  fprintf(stdout,"The Final 3Dpos is %lf %lf %lf \n",finalPos[0], finalPos[1], finalPos[2]);
+
1385 
+
1386  //original orientation
+
1387  //send it all
+
1388  double disp = 0.0;
+
1389  disp = norm(finalPos - initPos);
+
1390 
+
1391  if (shouldTrain)
+
1392  {
+
1393  Bottle cmdLearn, replyLearn;
+
1394  cmdLearn.clear();
+
1395  replyLearn.clear();
+
1396  cmdLearn.addString("train");
+
1397  cmdLearn.addString(obj);
+
1398 
+
1399  double wrappedAng = 0.0;
+
1400  wrappedAng = wrapAng ( finalOrient );
+
1401 
+
1402  cmdLearn.addDouble( wrappedAng );
+
1403  cmdLearn.addDouble( disp );
+
1404 
+
1405  fprintf(stdout, "the cmd is: %s \n",cmdLearn.toString().c_str());
+
1406  rpcKarmaLearn.write(cmdLearn, replyLearn);
+
1407  fprintf(stdout, "the reply is: %s \n",replyLearn.toString().c_str());
+
1408  }
+
1409  }
+
1410  }
+
1411  goHome();
+
1412  }
+
1413  }
+
1414  return 0;
+
1415 }
+
1416 /**********************************************************/
+
1417 double Manager::getBlobLenght(const Bottle &blobs, const int i)
+
1418 {
+
1419 
+
1420  double dist = 0;
+
1421  if ((i>=0) && (i<blobs.size()))
+
1422  {
+
1423  cv::Point tl,br;
+
1424  Bottle *item=blobs.get(i).asList();
+
1425  if (item==NULL)
+
1426  return dist;
+
1427 
+
1428  tl.x=(int)item->get(0).asDouble();
+
1429  tl.y=(int)item->get(1).asDouble();
+
1430  br.x=(int)item->get(2).asDouble();
+
1431  br.y=(int)item->get(3).asDouble();
+
1432 
+
1433 
+
1434  int dx = abs(tl.x - br.x);
+
1435  int dy = abs(tl.y - br.y);
+
1436 
+
1437  fprintf(stdout, "%d %d \n", dx, dy);
+
1438 
+
1439  dist = sqrt ( (double)((dx*dx) + (dy*dy)) );
+
1440 
+
1441  }
+
1442  return dist;
+
1443 }
+
1444 
+
1445 /**********************************************************/
+
1446 double Manager::wrapAng ( const double ang )
+
1447 {
+
1448  if ((ang<0.0) || (ang>=360.0))
+
1449  {
+
1450  double theta=(M_PI/180.0)*ang;
+
1451  theta=(180.0/M_PI)*atan2(sin(theta),cos(theta));
+
1452  if (theta<0.0)
+
1453  theta+=360.0;
+
1454  return theta;
+
1455  }
+
1456  else
+
1457  return ang;
+
1458 }
+
1459 /**********************************************************/
+
1460 Bottle Manager::getOffset( Bottle &closestBlob, double actionOrient, Vector &initPos )
+
1461 {
+
1462  double orient = 0.0;
+
1463  orient = closestBlob.get(3).asDouble();
+
1464 
+
1465  int axe1 = 0;
+
1466  int axe2 = 0;
+
1467  cv::Point cog;
+
1468  cog.x = closestBlob.get(0).asInt();
+
1469  cog.y = closestBlob.get(1).asInt();
+
1470 
+
1471  axe1 = closestBlob.get(4).asInt();
+
1472  axe2 = closestBlob.get(5).asInt();
+
1473  double finalOrient=actionOrient;
+
1474  fprintf(stdout ,"INITIAL orientation is: %lf \n", orient);
+
1475  if (abs(axe1-axe2) < 5)
+
1476  {
+
1477  fprintf(stdout,"seem a round object to me...sending theta2\n");
+
1478  }
+
1479  else
+
1480  {
+
1481  fprintf(stdout,"sending theta2 - theta1 <-> axis diff is %d\n", abs(axe1-axe2));
+
1482  finalOrient -= orient;
+
1483  }
+
1484 
+
1485  cv::Point pxls;
+
1486  Vector offPos;
+
1487  fprintf(stdout,"The 3Dpos is %lf %lf %lf \n",initPos[0], initPos[1], initPos[2]);
+
1488 
+
1489  double alpha = finalOrient * M_PI/180; //radians
+
1490  pxls.x = int(cog.x + (axe1 * 1.2 ) * cos(alpha));
+
1491  pxls.y = int(cog.y - (axe2 * 1.2 ) * sin(alpha));
+
1492 
+
1493  get3DPosition(pxls,offPos);
+
1494  fprintf(stdout,"The 3Dpos off point is %lf %lf %lf \n",offPos[0], offPos[1], offPos[2]);
+
1495  double offset= norm (initPos-offPos);
+
1496  fprintf(stdout,"The offset is %lf \n",offset);
+
1497 
+
1498  Bottle ret;
+
1499  ret.addDouble(offset);
+
1500  ret.addDouble(finalOrient);
+
1501  return ret;
+
1502 }
+
1503 
+
1504 /**********************************************************/
+
1505 Bottle Manager::classify(const Bottle &blobs, int index)
+
1506 {
+
1507  //grab resources
+
1508  mutexResources.lock();
+
1509  Bottle mils;
+
1510  mils.clear();
+
1511 
+
1512  Bottle gotMils;
+
1513  gotMils.clear();
+
1514 
+
1515  Bottle cmd,reply;
+
1516  cmd.addVocab(Vocab::encode("classify"));
+
1517 
+
1518  Bottle &options=cmd.addList();
+
1519  ostringstream tag;
+
1520  tag<<"blob_"<<index;
+
1521  Bottle &item=options.addList();
+
1522  item.addString(tag.str());
+
1523  item.addList()=*blobs.get(index).asList();
+
1524 
+
1525  printf("Sending classification request: %s\n",cmd.toString().c_str());
+
1526  rpcMIL.write(cmd,reply);
+
1527  printf("Received reply: %s\n",reply.toString().c_str());
+
1528  mutexResources.unlock();
+
1529  //Bottle &toReturn = gotMils.addList();
+
1530 
+
1531  cv::Point cog;
+
1532  cog=getBlobCOG(blobs,index);
+
1533  Bottle &tmpLine = gotMils.addList();
+
1534  Bottle &tmpMils = tmpLine.addList();
+
1535  tmpMils.addDouble(cog.x);
+
1536  tmpMils.addDouble(cog.y);
+
1537  tmpLine.addList()=*reply.get(0).asList()->get(1).asList();
+
1538 
+
1539  mils.clear();
+
1540  mils.addList()=gotMils;
+
1541  //release resources
+
1542  return mils;
+
1543 }
+
1544 /**********************************************************/
+
1545 Bottle Manager::getType(const yarp::os::Bottle *scores, int index)
+
1546 {
+
1547  ostringstream tag;
+
1548  tag<<"blob_"<<index;
+
1549  if (scores!=NULL)
+
1550  {
+
1551  double max_score=0.0;
+
1552  string max_label="unknown";
+
1553  if (scores->get(0).asList()->size() > 0)
+
1554  {
+
1555  Bottle *tmp_scores=scores->get(0).asList()->get(0).asList()->get(1).asList();
+
1556 
+
1557  fprintf(stdout,"bottle is: %s \n",tmp_scores->toString().c_str());
+
1558 
+
1559  for(int s=0; s<tmp_scores->size(); s++)
+
1560  {
+
1561  if(tmp_scores->get(s).asList()->get(1).asDouble()>max_score)
+
1562  {
+
1563  max_score=tmp_scores->get(s).asList()->get(1).asDouble();
+
1564  max_label=tmp_scores->get(s).asList()->get(0).asString();
+
1565  }
+
1566  }
+
1567  }
+
1568  //fprintf(stdout, "the prob is %lf ", scores->get(0).asList()->get(j).asList()->get(1).asList()->get(1).asDouble());
+
1569  //fprintf(stdout,"\n");
+
1570  tag.str("");
+
1571  tag.clear();
+
1572  tag<<max_label;
+
1573  Bottle type;
+
1574  type.clear();
+
1575  type.addString(max_label);
+
1576  return type;
+
1577  }
+
1578  Bottle type;
+
1579  type.clear();
+
1580  type.addString("error");
+
1581  return type;
+
1582 }
+
1583 /**********************************************************/
+
1584 double Manager::getPeriod()
+
1585 {
+
1586  return 0.1;
+
1587 }
+
1588 
+
1589 /**********************************************************/
+
1590 bool Manager::get3DPosition(const cv::Point &point, Vector &x)
+
1591 {
+
1592  Bottle cmdMotor,replyMotor;
+
1593  cmdMotor.addVocab(Vocab::encode("get"));
+
1594  cmdMotor.addVocab(Vocab::encode("s2c"));
+
1595  Bottle &options=cmdMotor.addList();
+
1596  options.addString(camera);
+
1597  options.addInt(point.x);
+
1598  options.addInt(point.y);
+
1599  printf("Sending motor query: %s\n",cmdMotor.toString().c_str());
+
1600  rpcMotorAre.write(cmdMotor,replyMotor);
+
1601  printf("Received blob cartesian coordinates: %s\n",replyMotor.toString().c_str());
+
1602 
+
1603  if (replyMotor.size()>=3)
+
1604  {
+
1605  x.resize(3);
+
1606  x[0]=replyMotor.get(0).asDouble();
+
1607  x[1]=replyMotor.get(1).asDouble();
+
1608  x[2]=replyMotor.get(2).asDouble();
+
1609  return true;
+
1610  }
+
1611  else
+
1612  return false;
+
1613 }
+
1614 /**********************************************************/
+
1615 Bottle Manager::getBlobs()
+
1616 {
+
1617  // grab resources
+
1618  mutexResources.lock();
+
1619 
+
1620  if (Bottle *pBlobs=blobExtractor.read(false))
+
1621  {
+
1622  lastBlobs=*pBlobs;
+
1623  printf("Received blobs list: %s\n",lastBlobs.toString().c_str());
+
1624 
+
1625  if (lastBlobs.size()==1)
+
1626  {
+
1627  if (lastBlobs.get(0).asVocab()==Vocab::encode("empty"))
+
1628  lastBlobs.clear();
+
1629  }
+
1630  }
+
1631  // release resources
+
1632  mutexResources.unlock();
+
1633 
+
1634  return lastBlobs;
+
1635 }
+
1636 /**********************************************************/
+
1637 cv::Point Manager::getBlobCOG(const Bottle &blobs, const int i)
+
1638 {
+
1639  cv::Point cog=cv::Point(RET_INVALID,RET_INVALID);
+
1640  if ((i>=0) && (i<blobs.size()))
+
1641  {
+
1642  cv::Point tl,br;
+
1643  Bottle *item=blobs.get(i).asList();
+
1644  if (item==NULL)
+
1645  return cog;
+
1646 
+
1647  tl.x=(int)item->get(0).asDouble();
+
1648  tl.y=(int)item->get(1).asDouble();
+
1649  br.x=(int)item->get(2).asDouble();
+
1650  br.y=(int)item->get(3).asDouble();
+
1651 
+
1652  cog.x=(tl.x+br.x)>>1;
+
1653  cog.y=(tl.y+br.y)>>1;
+
1654  }
+
1655  return cog;
+
1656 }
+
1657 /**********************************************************/
+
1658 Bottle Manager::findClosestBlob(const Bottle &blobs, const cv::Point &loc)
+
1659 {
+
1660  int ret=RET_INVALID;
+
1661  double min_d2=std::numeric_limits<double>::max();
+
1662  Bottle pointReturn;
+
1663  pointReturn.clear();
+
1664  for (int i=0; i<blobs.size(); i++)
+
1665  {
+
1666  cv::Point cog=getBlobCOG(blobs,i);
+
1667  if ((cog.x==RET_INVALID) || (cog.y==RET_INVALID))
+
1668  continue;
+
1669 
+
1670  double dx=loc.x-cog.x;
+
1671  double dy=loc.y-cog.y;
+
1672  double d2=dx*dx+dy*dy;
+
1673 
+
1674  if (d2<min_d2)
+
1675  {
+
1676  min_d2=d2;
+
1677  ret=i;
+
1678  }
+
1679  }
+
1680  cv::Point cog=getBlobCOG( blobs, ret );
+
1681  pointReturn.addDouble(cog.x); //cog x
+
1682  pointReturn.addDouble(cog.y); //cog y
+
1683  pointReturn.addInt(ret); //index of blob
+
1684  Bottle *item=blobs.get(ret).asList();
+
1685  double orient = (double)item->get(4).asDouble();
+
1686  int axe1 = item->get(5).asInt();
+
1687  int axe2 = item->get(6).asInt();
+
1688  pointReturn.addDouble(orient);
+
1689  pointReturn.addInt(axe1);
+
1690  pointReturn.addInt(axe2);
+
1691  return pointReturn;
+
1692 }
+
1693 /**********************************************************/
+
+ + + + diff --git a/doxygen/doc/html/karmaManager_2src_2utils_8cpp_source.html b/doxygen/doc/html/karmaManager_2src_2utils_8cpp_source.html new file mode 100644 index 0000000..f378d99 --- /dev/null +++ b/doxygen/doc/html/karmaManager_2src_2utils_8cpp_source.html @@ -0,0 +1,177 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaManager/src/utils.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
utils.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #include <yarp/os/Time.h>
+
19 
+
20 #include "iCub/utils.h"
+
21 #include "iCub/module.h"
+
22 
+
23 using namespace std;
+
24 using namespace yarp::os;
+
25 
+
26 /**********************************************************/
+
27 ParticleFilter::ParticleFilter()
+
28 {
+
29  useCallback();
+
30 }
+
31 /**********************************************************/
+
32 void ParticleFilter::onRead(Bottle &target)
+
33 {
+
34  //CvPoint trackLoc;
+
35  if (target.size()>1)
+
36  {
+
37  loc.x=(int)target.get(0).asDouble();
+
38  loc.y=(int)target.get(1).asDouble();
+
39  //fprintf( stdout, "particle something: %s \n\n",target.toString().c_str() );
+
40  }
+
41 }
+
42 /**********************************************************/
+
43 bool ParticleFilter::getTraker(cv::Point &loc)
+
44 {
+
45  loc=this->loc;
+
46  return true;
+
47 }
+
48 /**********************************************************/
+
49 void SegmentationPoint::segment(Bottle &b)
+
50 {
+
51  if (getOutputCount()>0)
+
52  {
+
53  //send 2D x y coordinates to segmentator
+
54  Bottle request;
+
55  request.addDouble(b.get(0).asDouble());
+
56  request.addDouble(b.get(1).asDouble());
+
57  write(request);
+
58  }
+
59 }
+
60 /**********************************************************/
+
61 void PointedLocation::onRead(Bottle &b)
+
62 {
+
63  fprintf(stdout, "got read from points size %d \n",b.size());
+
64  if (b.size()>1)
+
65  {
+
66  loc.x=(int)b.get(0).asDouble();
+
67  loc.y=(int)b.get(1).asDouble();
+
68  rxTime=Time::now();
+
69  }
+
70 }
+
71 /**********************************************************/
+
72 PointedLocation::PointedLocation()
+
73 {
+
74  useCallback();
+
75  rxTime=-1.0;
+
76  timeout=2.0;
+
77 }
+
78 /**********************************************************/
+
79 bool PointedLocation::getLoc(cv::Point &loc)
+
80 {
+
81  double t0=Time::now();
+
82 
+
83  if ((rxTime>0.0) && (t0-rxTime<timeout))
+
84  {
+
85  loc=this->loc;
+
86  return true;
+
87  }
+
88 
+
89  while (Time::now()-t0<timeout)
+
90  {
+
91  if ((rxTime>0.0) && (Time::now()-rxTime<timeout))
+
92  {
+
93  loc=this->loc;
+
94  return true;
+
95  }
+
96  Time::delay(0.1);
+
97  }
+
98  return false;
+
99 }
+
+ + + + diff --git a/doxygen/doc/html/karmaMotor_2main_8cpp_source.html b/doxygen/doc/html/karmaMotor_2main_8cpp_source.html new file mode 100644 index 0000000..1d704a9 --- /dev/null +++ b/doxygen/doc/html/karmaMotor_2main_8cpp_source.html @@ -0,0 +1,1165 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaMotor/main.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
main.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2012 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Ugo Pattacini
+
4  * email: ugo.pattacini@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
107 #include <cstdio>
+
108 #include <string>
+
109 #include <algorithm>
+
110 
+
111 #include <yarp/os/all.h>
+
112 #include <yarp/dev/all.h>
+
113 #include <yarp/sig/all.h>
+
114 #include <yarp/math/Math.h>
+
115 
+
116 #include <iCub/ctrl/math.h>
+
117 
+
118 using namespace std;
+
119 using namespace yarp::os;
+
120 using namespace yarp::sig;
+
121 using namespace yarp::dev;
+
122 using namespace yarp::math;
+
123 using namespace iCub::ctrl;
+
124 
+
125 
+
126 /************************************************************************/
+
127 class KarmaMotor: public RFModule, public PortReader
+
128 {
+
129 protected:
+
130  PolyDriver driverG;
+
131  PolyDriver driverL;
+
132  PolyDriver driverR;
+
133  PolyDriver driverHL;
+
134  PolyDriver driverHR;
+
135 
+
136  IGazeControl *iGaze;
+
137  ICartesianControl *iCartCtrlL;
+
138  ICartesianControl *iCartCtrlR;
+
139  ICartesianControl *iCartCtrl;
+
140 
+
141  string pushHand;
+
142  Matrix toolFrame;
+
143 
+
144  string handUsed;
+
145  bool interrupting;
+
146  double flip_hand;
+
147  int shake_joint;
+
148 
+
149  bool elbow_set;
+
150  double elbow_height,elbow_weight;
+
151 
+
152  BufferedPort<Bottle> visionPort;
+
153  RpcClient finderPort;
+
154  RpcServer rpcPort;
+
155  Port stopPort;
+
156 
+
157  /************************************************************************/
+
158  double dist(const Matrix &M)
+
159  {
+
160  double ret=0.0;
+
161  for (int r=0; r<M.rows(); r++)
+
162  for (int c=0; c<M.cols(); c++)
+
163  ret+=M(r,c)*M(r,c);
+
164 
+
165  return sqrt(ret);
+
166  }
+
167 
+
168  /************************************************************************/
+
169  bool read(ConnectionReader &connection)
+
170  {
+
171  Bottle cmd; cmd.read(connection);
+
172  interruptModule();
+
173  return true;
+
174  }
+
175 
+
176  /************************************************************************/
+
177  bool respond(const Bottle &command, Bottle &reply)
+
178  {
+
179  int ack=Vocab::encode("ack");
+
180  int nack=Vocab::encode("nack");
+
181 
+
182  int cmd=command.get(0).asVocab();
+
183  switch (cmd)
+
184  {
+
185  //-----------------
+
186  case createVocab('p','u','s','h'):
+
187  {
+
188  Bottle payload=command.tail();
+
189  if (payload.size()>=5)
+
190  {
+
191  Vector c(3);
+
192  double theta;
+
193  double radius;
+
194 
+
195  c[0]=payload.get(0).asDouble();
+
196  c[1]=payload.get(1).asDouble();
+
197  c[2]=payload.get(2).asDouble();
+
198  theta=payload.get(3).asDouble();
+
199  radius=payload.get(4).asDouble();
+
200 
+
201  push(c,theta,radius,pushHand,toolFrame);
+
202  reply.addVocab(ack);
+
203  }
+
204 
+
205  break;
+
206  }
+
207 
+
208  //-----------------
+
209  case createVocab('d','r','a','w'):
+
210  case createVocab('v','d','r','a'):
+
211  {
+
212  Bottle payload=command.tail();
+
213  if (payload.size()>=6)
+
214  {
+
215  Vector c(3);
+
216  double theta;
+
217  double radius;
+
218  double dist;
+
219 
+
220  c[0]=payload.get(0).asDouble();
+
221  c[1]=payload.get(1).asDouble();
+
222  c[2]=payload.get(2).asDouble();
+
223  theta=payload.get(3).asDouble();
+
224  radius=payload.get(4).asDouble();
+
225  dist=payload.get(5).asDouble();
+
226 
+
227  double res=draw(cmd==createVocab('v','d','r','a'),c,theta,
+
228  radius,dist,pushHand,toolFrame);
+
229 
+
230  reply.addVocab(ack);
+
231  if (cmd==createVocab('v','d','r','a'))
+
232  reply.addDouble(res);
+
233  }
+
234 
+
235  break;
+
236  }
+
237 
+
238  //-----------------
+
239  case createVocab('f','i','n','d'):
+
240  {
+
241  Bottle payload=command.tail();
+
242  if (payload.size()>=2)
+
243  {
+
244  string arm=payload.get(0).asString();
+
245  string eye=payload.get(1).asString();
+
246  Bottle solution;
+
247 
+
248  if (findToolTip(arm,eye,solution))
+
249  {
+
250  reply.addVocab(ack);
+
251  reply.append(solution.tail());
+
252  }
+
253  else
+
254  reply.addVocab(nack);
+
255  }
+
256 
+
257  break;
+
258  }
+
259 
+
260  //-----------------
+
261  case createVocab('t','o','o','l'):
+
262  {
+
263  if (command.size()>1)
+
264  {
+
265  Bottle subcommand=command.tail();
+
266  int tag=subcommand.get(0).asVocab();
+
267  if (tag==Vocab::encode("attach"))
+
268  {
+
269  Bottle payload=subcommand.tail();
+
270  if (payload.size()>=4)
+
271  {
+
272  pushHand=payload.get(0).asString();
+
273 
+
274  Vector point(4);
+
275  point[0]=payload.get(1).asDouble();
+
276  point[1]=payload.get(2).asDouble();
+
277  point[2]=payload.get(3).asDouble();
+
278  point[3]=1.0;
+
279 
+
280  Vector r(4,0.0);
+
281  r[2]=-1.0;
+
282  r[3]=atan2(-point[1],point[0]);
+
283  toolFrame=axis2dcm(r);
+
284  toolFrame.setCol(3,point);
+
285 
+
286  reply.addVocab(ack);
+
287  }
+
288  }
+
289  else if (tag==Vocab::encode("get"))
+
290  {
+
291  reply.addVocab(ack);
+
292  reply.addString(pushHand);
+
293  reply.addDouble(toolFrame(0,3));
+
294  reply.addDouble(toolFrame(1,3));
+
295  reply.addDouble(toolFrame(2,3));
+
296  }
+
297  else if (tag==Vocab::encode("remove"))
+
298  {
+
299  pushHand="selectable";
+
300  toolFrame=eye(4,4);
+
301 
+
302  reply.addVocab(ack);
+
303  }
+
304  }
+
305 
+
306  break;
+
307  }
+
308 
+
309  //-----------------
+
310  default:
+
311  interrupting=false;
+
312  return RFModule::respond(command,reply);
+
313  }
+
314 
+
315  interrupting=false;
+
316  return true;
+
317  }
+
318 
+
319  /***************************************************************/
+
320  void changeElbowHeight()
+
321  {
+
322  if (elbow_set)
+
323  {
+
324  Bottle tweakOptions;
+
325  Bottle &optTask2=tweakOptions.addList();
+
326  optTask2.addString("task_2");
+
327  Bottle &plTask2=optTask2.addList();
+
328  plTask2.addInt(6);
+
329  Bottle &posPart=plTask2.addList();
+
330  posPart.addDouble(0.0);
+
331  posPart.addDouble(0.0);
+
332  posPart.addDouble(elbow_height);
+
333  Bottle &weightsPart=plTask2.addList();
+
334  weightsPart.addDouble(0.0);
+
335  weightsPart.addDouble(0.0);
+
336  weightsPart.addDouble(elbow_weight);
+
337  iCartCtrl->tweakSet(tweakOptions);
+
338  }
+
339  }
+
340 
+
341  /************************************************************************/
+
342  void push(const Vector &c, const double theta, const double radius,
+
343  const string &armType="selectable", const Matrix &frame=eye(4,4))
+
344  {
+
345  // wrt root frame: frame centered at c with x-axis pointing rightward,
+
346  // y-axis pointing forward and z-axis pointing upward
+
347  Matrix H0(4,4); H0.zero();
+
348  H0(1,0)=1.0;
+
349  H0(0,1)=-1.0;
+
350  H0(2,2)=1.0;
+
351  H0(0,3)=c[0]; H0(1,3)=c[1]; H0(2,3)=c[2]; H0(3,3)=1.0;
+
352 
+
353  double theta_rad=CTRL_DEG2RAD*theta;
+
354  double _c=cos(theta_rad);
+
355  double _s=sin(theta_rad);
+
356  double _theta=CTRL_RAD2DEG*atan2(_s,_c); // to have theta in [-180.0,180.0]
+
357  double epsilon=0.05;
+
358 
+
359  // wrt H0 frame: frame centered at R*[_c,_s] with z-axis pointing inward
+
360  // and x-axis tangential
+
361  Matrix H1(4,4); H1.zero();
+
362  H1(0,0)=-_s; H1(1,0)=_c;
+
363  H1(2,1)=-1.0;
+
364  H1(0,2)=-_c; H1(1,2)=-_s;
+
365  H1(0,3)=radius*_c; H1(1,3)=radius*_s; H1(3,3)=1.0;
+
366 
+
367  // wrt H0 frame: frame centered at R*[_c,_s] with z-axis pointing outward
+
368  // and x-axis tangential
+
369  Matrix H2(4,4); H2.zero();
+
370  H2(0,0)=_s; H2(1,0)=-_c;
+
371  H2(2,1)=-1.0;
+
372  H2(0,2)=_c; H2(1,2)=_s;
+
373  H2(0,3)=radius*_c; H2(1,3)=radius*_s; H2(3,3)=1.0;
+
374 
+
375  // matrices that serve to account for pushing with the back of the hand
+
376  Matrix H1eps=H1; Matrix H2eps=H2;
+
377  H1eps(0,3)+=epsilon*_c; H1eps(1,3)+=epsilon*_s;
+
378  H2eps(0,3)+=epsilon*_c; H2eps(1,3)+=epsilon*_s;
+
379 
+
380  // go back into root frame and apply tool (if any)
+
381  Matrix invFrame=SE3inv(frame);
+
382  H1=H0*H1*invFrame;
+
383  H2=H0*H2*invFrame;
+
384  H1eps=H0*H1eps*invFrame;
+
385  H2eps=H0*H2eps*invFrame;
+
386 
+
387  Vector xd1=H1.getCol(3).subVector(0,2);
+
388  Vector od1=dcm2axis(H1);
+
389 
+
390  Vector xd2=H2.getCol(3).subVector(0,2);
+
391  Vector od2=dcm2axis(H2);
+
392 
+
393  Vector xd1eps=H1eps.getCol(3).subVector(0,2);
+
394  Vector od1eps=dcm2axis(H1eps);
+
395 
+
396  Vector xd2eps=H2eps.getCol(3).subVector(0,2);
+
397  Vector od2eps=dcm2axis(H2eps);
+
398 
+
399  printf("identified locations...\n");
+
400  printf("xd1=(%s) od1=(%s)\n",xd1.toString(3,3).c_str(),od1.toString(3,3).c_str());
+
401  printf("xd2=(%s) od2=(%s)\n",xd2.toString(3,3).c_str(),od2.toString(3,3).c_str());
+
402 
+
403  // choose the arm
+
404  if (armType=="selectable")
+
405  {
+
406  if (xd1[1]>=0.0)
+
407  iCartCtrl=iCartCtrlR;
+
408  else
+
409  iCartCtrl=iCartCtrlL;
+
410  }
+
411  else if (armType=="left")
+
412  iCartCtrl=iCartCtrlL;
+
413  else
+
414  iCartCtrl=iCartCtrlR;
+
415 
+
416  // deal with the arm context
+
417  int context;
+
418  iCartCtrl->storeContext(&context);
+
419 
+
420  Bottle options;
+
421  Bottle &straightOpt=options.addList();
+
422  straightOpt.addString("straightness");
+
423  straightOpt.addDouble(10.0);
+
424  iCartCtrl->tweakSet(options);
+
425  changeElbowHeight();
+
426 
+
427  Vector dof;
+
428  iCartCtrl->getDOF(dof);
+
429 
+
430  dof=1.0; dof[1]=0.0;
+
431  iCartCtrl->setDOF(dof,dof);
+
432 
+
433  Vector xdhat1,odhat1,xdhat2,odhat2;
+
434  Vector dummy;
+
435 
+
436  // try out different poses
+
437  iCartCtrl->askForPose(xd1,od1,xdhat1,odhat1,dummy);
+
438  iCartCtrl->askForPose(xd2,od2,xdhat2,odhat2,dummy);
+
439 
+
440  Matrix Hhat1=axis2dcm(odhat1); Hhat1(0,3)=xdhat1[0]; Hhat1(1,3)=xdhat1[1]; Hhat1(2,3)=xdhat1[2];
+
441  Matrix Hhat2=axis2dcm(odhat2); Hhat2(0,3)=xdhat2[0]; Hhat2(1,3)=xdhat2[1]; Hhat2(2,3)=xdhat2[2];
+
442 
+
443  double d1=dist(H1-Hhat1);
+
444  double d2=dist(H2-Hhat2);
+
445 
+
446  printf("solutions...\n");
+
447  printf("#1: xdhat1=(%s) odhat1=(%s); e=%.3f\n",xdhat1.toString(3,3).c_str(),odhat1.toString(3,3).c_str(),d1);
+
448  printf("#2: xdhat2=(%s) odhat2=(%s); e=%.3f\n",xdhat2.toString(3,3).c_str(),odhat2.toString(3,3).c_str(),d2);
+
449  printf("selection: ");
+
450 
+
451  // compare solutions and choose the best
+
452  Vector *xd,*od;
+
453  if (fabs(_theta-90.0)<45.0)
+
454  {
+
455  printf("(detected singularity) ");
+
456  if (iCartCtrl==iCartCtrlR)
+
457  {
+
458  xd=&xd1;
+
459  od=&od1;
+
460  }
+
461  else
+
462  {
+
463  xd=&xd2;
+
464  od=&od2;
+
465  }
+
466  }
+
467  else if (fabs(_theta+90.0)<45.0)
+
468  {
+
469  printf("(detected singularity) ");
+
470  if (iCartCtrl==iCartCtrlR)
+
471  {
+
472  xd=&xd2;
+
473  od=&od2;
+
474  }
+
475  else
+
476  {
+
477  xd=&xd1;
+
478  od=&od1;
+
479  }
+
480  }
+
481  else if (d1<d2)
+
482  {
+
483  xd=&xd1;
+
484  od=&od1;
+
485  }
+
486  else
+
487  {
+
488  xd=&xd2;
+
489  od=&od2;
+
490  }
+
491 
+
492  if (xd==&xd1)
+
493  printf("#1 ");
+
494  else
+
495  printf("#2 ");
+
496 
+
497  if ((iCartCtrl==iCartCtrlR) && (_theta<0.0) && (xd==&xd2))
+
498  {
+
499  printf("(increased radius)");
+
500  xd=&xd2eps;
+
501  od=&od2eps;
+
502  }
+
503  else if ((iCartCtrl==iCartCtrlL) && (_theta<0.0) && (xd==&xd1))
+
504  {
+
505  printf("(increased radius)");
+
506  xd=&xd1eps;
+
507  od=&od1eps;
+
508  }
+
509 
+
510  printf(": xd=(%s); od=(%s)\n",xd->toString(3,3).c_str(),od->toString(3,3).c_str());
+
511 
+
512  // execute the movement
+
513  Vector offs(3,0.0); offs[2]=0.1;
+
514  if (!interrupting)
+
515  {
+
516  Vector x=*xd+offs;
+
517 
+
518  printf("moving to: x=(%s); o=(%s)\n",x.toString(3,3).c_str(),od->toString(3,3).c_str());
+
519  iCartCtrl->goToPoseSync(x,*od,1.0);
+
520  iCartCtrl->waitMotionDone(0.1,4.0);
+
521  }
+
522 
+
523  if (!interrupting)
+
524  {
+
525  printf("moving to: x=(%s); o=(%s)\n",xd->toString(3,3).c_str(),od->toString(3,3).c_str());
+
526  iCartCtrl->goToPoseSync(*xd,*od,1.0);
+
527  iCartCtrl->waitMotionDone(0.1,4.0);
+
528  }
+
529 
+
530  double rmin,rmax,tmin,tmax;
+
531  if (((fabs(theta)<10.0) || (fabs(theta-180.0)<10.0)))
+
532  {
+
533  rmin=0.04; rmax=0.18;
+
534  tmin=0.40; tmax=0.60;
+
535  }
+
536  else
+
537  {
+
538  rmin=0.04; rmax=0.18;
+
539  tmin=0.50; tmax=0.80;
+
540  }
+
541 
+
542  // safe guard for using the tool
+
543  if (armType!="selectable")
+
544  {
+
545  tmin*=1.3;
+
546  tmax*=1.3;
+
547  }
+
548 
+
549  double trajTime=tmin+((tmax-tmin)/(rmax-rmin))*(radius-rmin);
+
550  trajTime=std::max(std::min(tmax,trajTime),tmin);
+
551 
+
552  if (!interrupting)
+
553  {
+
554  Matrix H=axis2dcm(*od);
+
555  Vector center=c; center.push_back(1.0);
+
556  H.setCol(3,center);
+
557  Vector x=-1.0*frame.getCol(3); x[3]=1.0;
+
558  x=H*x; x.pop_back();
+
559 
+
560  printf("moving to: x=(%s); o=(%s)\n",x.toString(3,3).c_str(),od->toString(3,3).c_str());
+
561  iCartCtrl->goToPoseSync(x,*od,trajTime);
+
562  iCartCtrl->waitMotionDone(0.1,3.0);
+
563  }
+
564 
+
565  if (!interrupting)
+
566  {
+
567  printf("moving to: x=(%s); o=(%s)\n",xd->toString(3,3).c_str(),od->toString(3,3).c_str());
+
568  iCartCtrl->goToPoseSync(*xd,*od,1.0);
+
569  iCartCtrl->waitMotionDone(0.1,2.0);
+
570  }
+
571 
+
572  iCartCtrl->restoreContext(context);
+
573  iCartCtrl->deleteContext(context);
+
574  }
+
575 
+
576  /************************************************************************/
+
577  double draw(bool simulation, const Vector &c, const double theta, const double radius,
+
578  const double dist, const string &armType, const Matrix &frame=eye(4,4))
+
579  {
+
580  // c0 is the projection of c on the sagittal plane
+
581  Vector c_sag=c;
+
582  c_sag[1]=0.0;
+
583 
+
584  // wrt root frame: frame centered at c_sag with x-axis pointing rightward,
+
585  // y-axis pointing forward and z-axis pointing upward
+
586  Matrix H0(4,4); H0.zero();
+
587  H0(1,0)=1.0;
+
588  H0(0,1)=-1.0;
+
589  H0(2,2)=1.0;
+
590  H0(0,3)=c_sag[0]; H0(1,3)=c_sag[1]; H0(2,3)=c_sag[2]; H0(3,3)=1.0;
+
591 
+
592  double theta_rad=CTRL_DEG2RAD*theta;
+
593  double _c=cos(theta_rad);
+
594  double _s=sin(theta_rad);
+
595 
+
596  // wrt H0 frame: frame translated in R*[_c,_s]
+
597  Matrix H1=eye(4,4);
+
598  H1(0,3)=radius*_c; H1(1,3)=radius*_s;
+
599 
+
600  // wrt H1 frame: frame translated in [0,-dist]
+
601  Matrix H2=eye(4,4);
+
602  H2(1,3)=-dist;
+
603 
+
604  // go back into root frame
+
605  H2=H0*H1*H2;
+
606  H1=H0*H1;
+
607 
+
608  // apply final axes
+
609  Matrix R(3,3); R.zero();
+
610  R(0,0)=-1.0;
+
611  R(2,1)=-1.0;
+
612  R(1,2)=-1.0;
+
613 
+
614  H1.setSubmatrix(R,0,0);
+
615  H2.setSubmatrix(R,0,0);
+
616 
+
617  Vector xd1=H1.getCol(3).subVector(0,2);
+
618  Vector od1=dcm2axis(H1);
+
619 
+
620  Vector xd2=H2.getCol(3).subVector(0,2);
+
621  Vector od2=dcm2axis(H2);
+
622 
+
623  printf("identified locations on the sagittal plane...\n");
+
624  printf("xd1=(%s) od1=(%s)\n",xd1.toString(3,3).c_str(),od1.toString(3,3).c_str());
+
625  printf("xd2=(%s) od2=(%s)\n",xd2.toString(3,3).c_str(),od2.toString(3,3).c_str());
+
626 
+
627  // choose the arm
+
628  if (armType=="selectable")
+
629  {
+
630  if (xd1[1]>=0.0)
+
631  iCartCtrl=iCartCtrlR;
+
632  else
+
633  iCartCtrl=iCartCtrlL;
+
634  }
+
635  else if (armType=="left")
+
636  iCartCtrl=iCartCtrlL;
+
637  else
+
638  iCartCtrl=iCartCtrlR;
+
639 
+
640  // recover the original place: do translation and rotation
+
641  if (c[1]!=0.0)
+
642  {
+
643  Vector r(4,0.0);
+
644  r[2]=-1.0;
+
645  r[3]=atan2(c[1],fabs(c[0]));
+
646  Matrix H=axis2dcm(r);
+
647 
+
648  H(0,3)=H1(0,3);
+
649  H(1,3)=H1(1,3)+c[1];
+
650  H(2,3)=H1(2,3);
+
651  H1(0,3)=H1(1,3)=H1(2,3)=0.0;
+
652  H1=H*H1;
+
653 
+
654  H(0,3)=H2(0,3);
+
655  H(1,3)=H2(1,3)+c[1];
+
656  H(2,3)=H2(2,3);
+
657  H2(0,3)=H2(1,3)=H2(2,3)=0.0;
+
658  H2=H*H2;
+
659 
+
660  xd1=H1.getCol(3).subVector(0,2);
+
661  od1=dcm2axis(H1);
+
662 
+
663  xd2=H2.getCol(3).subVector(0,2);
+
664  od2=dcm2axis(H2);
+
665  }
+
666 
+
667  printf("in-place locations...\n");
+
668  printf("xd1=(%s) od1=(%s)\n",xd1.toString(3,3).c_str(),od1.toString(3,3).c_str());
+
669  printf("xd2=(%s) od2=(%s)\n",xd2.toString(3,3).c_str(),od2.toString(3,3).c_str());
+
670 
+
671  // apply tool (if any)
+
672  Matrix invFrame=SE3inv(frame);
+
673  H1=H1*invFrame;
+
674  H2=H2*invFrame;
+
675 
+
676  xd1=H1.getCol(3).subVector(0,2);
+
677  od1=dcm2axis(H1);
+
678 
+
679  xd2=H2.getCol(3).subVector(0,2);
+
680  od2=dcm2axis(H2);
+
681 
+
682  printf("apply tool (if any)...\n");
+
683  printf("xd1=(%s) od1=(%s)\n",xd1.toString(3,3).c_str(),od1.toString(3,3).c_str());
+
684  printf("xd2=(%s) od2=(%s)\n",xd2.toString(3,3).c_str(),od2.toString(3,3).c_str());
+
685 
+
686  // deal with the arm context
+
687  int context;
+
688  iCartCtrl->storeContext(&context);
+
689 
+
690  Bottle options;
+
691  Bottle &straightOpt=options.addList();
+
692  straightOpt.addString("straightness");
+
693  straightOpt.addDouble(30.0);
+
694  iCartCtrl->tweakSet(options);
+
695  changeElbowHeight();
+
696 
+
697  Vector dof;
+
698  iCartCtrl->getDOF(dof);
+
699 
+
700  dof=1.0; dof[1]=0.0;
+
701  iCartCtrl->setDOF(dof,dof);
+
702 
+
703  double res=0.0;
+
704 
+
705  // simulate the movements
+
706  if (simulation)
+
707  {
+
708  Vector xdhat1,odhat1,xdhat2,odhat2,qdhat;
+
709  iCartCtrl->askForPose(xd1,od1,xdhat1,odhat1,qdhat);
+
710  iCartCtrl->askForPose(qdhat,xd2,od2,xdhat2,odhat2,qdhat);
+
711 
+
712  double e_x1=norm(xd1-xdhat1);
+
713  double e_o1=norm(od1-odhat1);
+
714  printf("testing x=(%s); o=(%s) => xhat=(%s); ohat=(%s) ... |e_x|=%g; |e_o|=%g\n",
+
715  xd1.toString(3,3).c_str(),od1.toString(3,3).c_str(),
+
716  xdhat1.toString(3,3).c_str(),odhat1.toString(3,3).c_str(),
+
717  e_x1,e_o1);
+
718 
+
719  double e_x2=norm(xd2-xdhat2);
+
720  double e_o2=norm(od2-odhat2);
+
721  printf("testing x=(%s); o=(%s) => xhat=(%s); ohat=(%s) ... |e_x|=%g; |e_o|=%g\n",
+
722  xd2.toString(3,3).c_str(),od2.toString(3,3).c_str(),
+
723  xdhat2.toString(3,3).c_str(),odhat2.toString(3,3).c_str(),
+
724  e_x2,e_o2);
+
725 
+
726  double nearness_penalty=((norm(xdhat1)<0.15)||(norm(xdhat2)<0.15)?10.0:0.0);
+
727  printf("nearness penalty=%g\n",nearness_penalty);
+
728  res=e_x1+e_o1+e_x2+e_o2+nearness_penalty;
+
729  printf("final quality=%g\n",res);
+
730  }
+
731  // execute the movements
+
732  else
+
733  {
+
734  Vector offs(3,0.0); offs[2]=0.05;
+
735  if (!interrupting)
+
736  {
+
737  Vector x=xd1+offs;
+
738 
+
739  printf("moving to: x=(%s); o=(%s)\n",x.toString(3,3).c_str(),od1.toString(3,3).c_str());
+
740  iCartCtrl->goToPoseSync(x,od1,2.0);
+
741  iCartCtrl->waitMotionDone(0.1,5.0);
+
742  }
+
743 
+
744  if (!interrupting)
+
745  {
+
746  printf("moving to: x=(%s); o=(%s)\n",xd1.toString(3,3).c_str(),od1.toString(3,3).c_str());
+
747  iCartCtrl->goToPoseSync(xd1,od1,1.5);
+
748  iCartCtrl->waitMotionDone(0.1,5.0);
+
749  }
+
750 
+
751  if (!interrupting)
+
752  {
+
753  printf("moving to: x=(%s); o=(%s)\n",xd2.toString(3,3).c_str(),od2.toString(3,3).c_str());
+
754  iCartCtrl->goToPoseSync(xd2,od2,3.5);
+
755  iCartCtrl->waitMotionDone(0.1,5.0);
+
756  }
+
757  }
+
758 
+
759  iCartCtrl->restoreContext(context);
+
760  iCartCtrl->deleteContext(context);
+
761 
+
762  return res;
+
763  }
+
764 
+
765  /************************************************************************/
+
766  void shakeHand()
+
767  {
+
768  IEncoders *ienc;
+
769  IVelocityControl *ivel;
+
770 
+
771  if (handUsed=="left")
+
772  {
+
773  driverHL.view(ienc);
+
774  driverHL.view(ivel);
+
775  }
+
776  else
+
777  {
+
778  driverHR.view(ienc);
+
779  driverHR.view(ivel);
+
780  }
+
781 
+
782  double pos;
+
783  ienc->getEncoder(shake_joint,&pos);
+
784 
+
785  double e=flip_hand-pos;
+
786  if ((flip_hand>0.0) && (e<0.0) ||
+
787  (flip_hand<0.0) && (e>0.0))
+
788  {
+
789  flip_hand=-flip_hand;
+
790  e=flip_hand-pos;
+
791  }
+
792 
+
793  ivel->velocityMove(shake_joint,120.0*sign(e));
+
794  }
+
795 
+
796  /************************************************************************/
+
797  void stopHand(const string &hand)
+
798  {
+
799  IVelocityControl *ivel;
+
800  if (hand=="left")
+
801  driverHL.view(ivel);
+
802  else
+
803  driverHR.view(ivel);
+
804 
+
805  ivel->stop(4);
+
806  }
+
807 
+
808  /************************************************************************/
+
809  void moveTool(const string &arm, const string &eye, const Vector &xd, const Vector &od,
+
810  const Vector &xOffset, const int maxItems)
+
811  {
+
812  iGaze->restoreContext(0);
+
813 
+
814  if (!interrupting)
+
815  {
+
816  iGaze->setTrackingMode(true);
+
817  iGaze->lookAtFixationPoint(xd+xOffset);
+
818  iCartCtrl->goToPoseSync(xd,od,1.0);
+
819  iCartCtrl->waitMotionDone(0.1);
+
820  }
+
821 
+
822  iGaze->setSaccadesMode(false);
+
823  iGaze->setNeckTrajTime(2.5);
+
824  iGaze->setEyesTrajTime(1.5);
+
825 
+
826  // put the shaking joint in velocity mode
+
827  IControlMode *imode;
+
828  if (arm=="left")
+
829  driverHL.view(imode);
+
830  else
+
831  driverHR.view(imode);
+
832  imode->setControlMode(shake_joint,VOCAB_CM_VELOCITY);
+
833  handUsed=arm; // this triggers the hand shaking
+
834 
+
835  // gaze robustly at the tool tip
+
836  Vector pxCum(2,0.0);
+
837  int cnt=0; bool done=false;
+
838  double t0=Time::now();
+
839  while (!interrupting && !done)
+
840  {
+
841  double t1=Time::now();
+
842  if (Bottle *target=visionPort.read(false))
+
843  {
+
844  if (target->size()>=2)
+
845  {
+
846  Vector px(2);
+
847  px[0]=target->get(0).asDouble();
+
848  px[1]=target->get(1).asDouble()+50.0;
+
849  iGaze->lookAtMonoPixel(eye=="left"?0:1,px);
+
850 
+
851  pxCum+=px;
+
852  cnt++;
+
853  }
+
854  }
+
855 
+
856  if (t1-t0>=3.0)
+
857  {
+
858  if (cnt>20)
+
859  done=fabs(pxCum[1]/cnt-120)<30.0;
+
860 
+
861  pxCum=0.0;
+
862  cnt=0;
+
863  t0=t1;
+
864  }
+
865 
+
866  Time::delay(0.02);
+
867  }
+
868 
+
869  // gather sufficient information
+
870  Bottle command,reply;
+
871  command.addVocab(Vocab::encode("enable"));
+
872  finderPort.write(command,reply);
+
873 
+
874  command.clear();
+
875  command.addVocab(Vocab::encode("num"));
+
876  finderPort.write(command,reply);
+
877  int curItems=reply.get(1).asInt();
+
878 
+
879  int nItems=0;
+
880  while (!interrupting && (nItems<curItems+maxItems))
+
881  {
+
882  finderPort.write(command,reply);
+
883  nItems=reply.get(1).asInt();
+
884 
+
885  if (Bottle *target=visionPort.read(false))
+
886  {
+
887  if (target->size()>=2)
+
888  {
+
889  Vector px(2);
+
890  px[0]=target->get(0).asDouble();
+
891  px[1]=target->get(1).asDouble()+50.0;
+
892  iGaze->lookAtMonoPixel(eye=="left"?0:1,px);
+
893  }
+
894  }
+
895 
+
896  Time::delay(0.1);
+
897  }
+
898 
+
899  command.clear();
+
900  command.addVocab(Vocab::encode("disable"));
+
901  finderPort.write(command,reply);
+
902 
+
903  handUsed="null";
+
904  stopHand(arm);
+
905  }
+
906 
+
907  /************************************************************************/
+
908  bool findToolTip(const string &arm, const string &eye, Bottle &reply)
+
909  {
+
910  if (arm=="left")
+
911  iCartCtrl=iCartCtrlL;
+
912  else if (arm=="right")
+
913  iCartCtrl=iCartCtrlR;
+
914  else
+
915  return false;
+
916 
+
917  int context_arm,context_gaze;
+
918  iCartCtrl->storeContext(&context_arm);
+
919  iGaze->storeContext(&context_gaze);
+
920 
+
921  Vector dof;
+
922  iCartCtrl->getDOF(dof);
+
923  dof=1.0; dof[0]=dof[1]=0.0;
+
924  iCartCtrl->setDOF(dof,dof);
+
925 
+
926  Bottle command;
+
927  command.addVocab(Vocab::encode("clear"));
+
928  finderPort.write(command,reply);
+
929 
+
930  // solving
+
931  command.clear();
+
932  command.addVocab(Vocab::encode("select"));
+
933  command.addString(arm);
+
934  command.addString(eye);
+
935  finderPort.write(command,reply);
+
936 
+
937  Matrix R(4,4);
+
938  R(0,0)=-1.0;
+
939  R(2,1)=-1.0;
+
940  R(1,2)=-1.0;
+
941  R(3,3)=+1.0;
+
942  Vector r(4,0.0); r[0]=-1.0;
+
943  Vector xd(3,0.0),od;
+
944  Vector offset(3,0.0); offset[2]=0.1;
+
945 
+
946  // point 1
+
947  r[3]=0.0;
+
948  od=dcm2axis(axis2dcm(r)*R);
+
949  xd[0]=-0.35;
+
950  shake_joint=4;
+
951  moveTool(arm,eye,xd,od,offset,25);
+
952 
+
953  // point 2
+
954  r[3]=CTRL_DEG2RAD*(arm=="left"?30.0:-30.0);
+
955  od=dcm2axis(axis2dcm(r)*R);
+
956  xd[1]=(arm=="left")?-0.15:0.15;
+
957  offset[1]=(arm=="left")?0.1:-0.1;
+
958  moveTool(arm,eye,xd,od,offset,25);
+
959 
+
960  // point 3
+
961  r[3]=CTRL_DEG2RAD*(arm=="left"?20.0:-20.0);
+
962  od=dcm2axis(axis2dcm(r)*R);
+
963  xd[2]=0.15;
+
964  offset[1]=(arm=="left")?0.2:-0.2;
+
965  offset[2]=0.1;
+
966  moveTool(arm,eye,xd,od,offset,25);
+
967 
+
968  // point 4
+
969  r[3]=CTRL_DEG2RAD*(arm=="left"?10.0:-10.0);
+
970  od=dcm2axis(axis2dcm(r)*R);
+
971  xd[0]=-0.3;
+
972  xd[1]=(arm=="left")?-0.05:0.05;
+
973  xd[2]=-0.05;
+
974  moveTool(arm,eye,xd,od,offset,25);
+
975 
+
976  // point 5
+
977  r[3]=CTRL_DEG2RAD*(arm=="left"?45.0:-45.0);
+
978  od=dcm2axis(axis2dcm(r)*R);
+
979  xd[0]=-0.35;
+
980  xd[1]=(arm=="left")?-0.05:0.05;
+
981  xd[2]=0.1;
+
982  offset[1]=(arm=="left")?0.1:-0.1;
+
983  moveTool(arm,eye,xd,od,offset,25);
+
984 
+
985  // point 6
+
986  xd[0]=-0.35;
+
987  xd[1]=(arm=="left")?-0.1:0.1;
+
988  xd[2]=0.0;
+
989  Vector r1(4,0.0); r1[2]=(arm=="left")?-1.0:1.0; r1[3]=CTRL_DEG2RAD*45.0;
+
990  Vector r2(4,0.0); r2[0]=(arm=="left")?1.0:-1.0; r2[3]=CTRL_DEG2RAD*45.0;
+
991  od=dcm2axis(axis2dcm(r2)*axis2dcm(r1)*R);
+
992  offset[0]=0;
+
993  offset[1]=(arm=="left")?-0.05:0.05;
+
994  offset[2]=0.1;
+
995  shake_joint=6;
+
996  moveTool(arm,eye,xd,od,offset,50);
+
997 
+
998  // solving
+
999  command.clear();
+
1000  command.addVocab(Vocab::encode("find"));
+
1001  finderPort.write(command,reply);
+
1002 
+
1003  iCartCtrl->restoreContext(context_arm);
+
1004  iCartCtrl->deleteContext(context_arm);
+
1005 
+
1006  iGaze->restoreContext(context_gaze);
+
1007  iGaze->deleteContext(context_gaze);
+
1008 
+
1009  return true;
+
1010  }
+
1011 
+
1012 public:
+
1013  /************************************************************************/
+
1014  bool configure(ResourceFinder &rf)
+
1015  {
+
1016  string name=rf.check("name",Value("karmaMotor")).asString();
+
1017  string robot=rf.check("robot",Value("icub")).asString();
+
1018  elbow_set=rf.check("elbow_set");
+
1019  if (elbow_set)
+
1020  {
+
1021  if (Bottle *pB=rf.find("elbow_set").asList())
+
1022  {
+
1023  elbow_height=pB->get(0).asDouble();
+
1024  elbow_weight=pB->get(1).asDouble();
+
1025  }
+
1026  else
+
1027  {
+
1028  elbow_height=0.4;
+
1029  elbow_weight=30.0;
+
1030  }
+
1031  }
+
1032 
+
1033  Property optionG("(device gazecontrollerclient)");
+
1034  optionG.put("remote","/iKinGazeCtrl");
+
1035  optionG.put("local","/"+name+"/gaze_ctrl");
+
1036 
+
1037  Property optionL("(device cartesiancontrollerclient)");
+
1038  optionL.put("remote","/"+robot+"/cartesianController/left_arm");
+
1039  optionL.put("local","/"+name+"/cart_ctrl/left_arm");
+
1040 
+
1041  Property optionR("(device cartesiancontrollerclient)");
+
1042  optionR.put("remote","/"+robot+"/cartesianController/right_arm");
+
1043  optionR.put("local","/"+name+"/cart_ctrl/right_arm");
+
1044 
+
1045  Property optionHL("(device remote_controlboard)");
+
1046  optionHL.put("remote","/"+robot+"/left_arm");
+
1047  optionHL.put("local","/"+name+"/hand_ctrl/left_arm");
+
1048 
+
1049  Property optionHR("(device remote_controlboard)");
+
1050  optionHR.put("remote","/"+robot+"/right_arm");
+
1051  optionHR.put("local","/"+name+"/hand_ctrl/right_arm");
+
1052 
+
1053  if (!driverG.open(optionG))
+
1054  return false;
+
1055 
+
1056  if (!driverL.open(optionL))
+
1057  {
+
1058  driverG.close();
+
1059  return false;
+
1060  }
+
1061 
+
1062  if (!driverR.open(optionR))
+
1063  {
+
1064  driverG.close();
+
1065  driverL.close();
+
1066  return false;
+
1067  }
+
1068 
+
1069  if (!driverHL.open(optionHL))
+
1070  {
+
1071  driverG.close();
+
1072  driverL.close();
+
1073  driverR.close();
+
1074  return false;
+
1075  }
+
1076 
+
1077  if (!driverHR.open(optionHR))
+
1078  {
+
1079  driverG.close();
+
1080  driverL.close();
+
1081  driverR.close();
+
1082  driverHL.close();
+
1083  return false;
+
1084  }
+
1085 
+
1086  driverG.view(iGaze);
+
1087  driverL.view(iCartCtrlL);
+
1088  driverR.view(iCartCtrlR);
+
1089 
+
1090  visionPort.open("/"+name+"/vision:i");
+
1091  finderPort.open("/"+name+"/finder:rpc");
+
1092  rpcPort.open("/"+name+"/rpc");
+
1093  stopPort.open("/"+name+"/stop:i");
+
1094  attach(rpcPort);
+
1095  stopPort.setReader(*this);
+
1096 
+
1097  interrupting=false;
+
1098  handUsed="null";
+
1099  flip_hand=6.0;
+
1100 
+
1101  pushHand="selectable";
+
1102  toolFrame=eye(4,4);
+
1103 
+
1104  return true;
+
1105  }
+
1106 
+
1107  /************************************************************************/
+
1108  bool interruptModule()
+
1109  {
+
1110  interrupting=true;
+
1111 
+
1112  iGaze->stopControl();
+
1113  iCartCtrlL->stopControl();
+
1114  iCartCtrlR->stopControl();
+
1115 
+
1116  if (handUsed!="null")
+
1117  {
+
1118  stopHand("left");
+
1119  stopHand("right");
+
1120  }
+
1121 
+
1122  return true;
+
1123  }
+
1124 
+
1125  /************************************************************************/
+
1126  bool close()
+
1127  {
+
1128  visionPort.close();
+
1129  finderPort.close();
+
1130  rpcPort.close();
+
1131  stopPort.close(); // close prior to shutting down motor-interfaces
+
1132 
+
1133  driverG.close();
+
1134  driverL.close();
+
1135  driverR.close();
+
1136  driverHL.close();
+
1137  driverHR.close();
+
1138  return true;
+
1139  }
+
1140 
+
1141  /************************************************************************/
+
1142  double getPeriod()
+
1143  {
+
1144  return 0.02;
+
1145  }
+
1146 
+
1147  /************************************************************************/
+
1148  bool updateModule()
+
1149  {
+
1150  if (!interrupting && (handUsed!="null"))
+
1151  shakeHand();
+
1152 
+
1153  return true;
+
1154  }
+
1155 };
+
1156 
+
1157 
+
1158 /************************************************************************/
+
1159 int main(int argc, char *argv[])
+
1160 {
+
1161  Network yarp;
+
1162  if (!yarp.checkNetwork())
+
1163  {
+
1164  printf("YARP server not available!\n");
+
1165  return 1;
+
1166  }
+
1167 
+
1168  ResourceFinder rf;
+
1169  rf.configure(argc,argv);
+
1170 
+
1171  KarmaMotor karmaMotor;
+
1172  return karmaMotor.runModule(rf);
+
1173 }
+
1174 
+
1175 
+
1176 
+
+ + + + diff --git a/doxygen/doc/html/karmaToolFinder_2main_8cpp_source.html b/doxygen/doc/html/karmaToolFinder_2main_8cpp_source.html new file mode 100644 index 0000000..0208567 --- /dev/null +++ b/doxygen/doc/html/karmaToolFinder_2main_8cpp_source.html @@ -0,0 +1,872 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolFinder/main.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
main.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2012 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Ugo Pattacini
+
4  * email: ugo.pattacini@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
101 #include <cstdio>
+
102 #include <mutex>
+
103 #include <algorithm>
+
104 #include <string>
+
105 #include <deque>
+
106 
+
107 #include <yarp/os/all.h>
+
108 #include <yarp/sig/all.h>
+
109 #include <yarp/dev/all.h>
+
110 #include <yarp/math/Math.h>
+
111 #include <yarp/cv/Cv.h>
+
112 
+
113 #include <IpTNLP.hpp>
+
114 #include <IpIpoptApplication.hpp>
+
115 
+
116 #include <opencv2/opencv.hpp>
+
117 
+
118 using namespace std;
+
119 using namespace yarp::os;
+
120 using namespace yarp::dev;
+
121 using namespace yarp::sig;
+
122 using namespace yarp::math;
+
123 using namespace yarp::cv;
+
124 
+
125 
+
126 /****************************************************************/
+
127 class FindToolTipNLP : public Ipopt::TNLP
+
128 {
+
129 protected:
+
130  const deque<Vector> &p;
+
131  const deque<Matrix> &H;
+
132 
+
133  Vector min;
+
134  Vector max;
+
135  Vector x0;
+
136  Vector x;
+
137 
+
138 public:
+
139  /****************************************************************/
+
140  FindToolTipNLP(const deque<Vector> &_p,
+
141  const deque<Matrix> &_H,
+
142  const Vector &_min, const Vector &_max) :
+
143  p(_p), H(_H)
+
144  {
+
145  min=_min;
+
146  max=_max;
+
147  x0=0.5*(min+max);
+
148  }
+
149 
+
150  /****************************************************************/
+
151  void set_x0(const Vector &x0)
+
152  {
+
153  size_t len=std::min(this->x0.length(),x0.length());
+
154  for (size_t i=0; i<len; i++)
+
155  this->x0[i]=x0[i];
+
156  }
+
157 
+
158  /****************************************************************/
+
159  Vector get_result() const
+
160  {
+
161  return x;
+
162  }
+
163 
+
164  /****************************************************************/
+
165  bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g,
+
166  Ipopt::Index &nnz_h_lag, IndexStyleEnum &index_style)
+
167  {
+
168  n=3;
+
169  m=nnz_jac_g=nnz_h_lag=0;
+
170  index_style=TNLP::C_STYLE;
+
171 
+
172  return true;
+
173  }
+
174 
+
175  /****************************************************************/
+
176  bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u,
+
177  Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
+
178  {
+
179  for (Ipopt::Index i=0; i<n; i++)
+
180  {
+
181  x_l[i]=min[i];
+
182  x_u[i]=max[i];
+
183  }
+
184 
+
185  return true;
+
186  }
+
187 
+
188  /****************************************************************/
+
189  bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x,
+
190  bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U,
+
191  Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
+
192  {
+
193  for (Ipopt::Index i=0; i<n; i++)
+
194  x[i]=x0[i];
+
195 
+
196  return true;
+
197  }
+
198 
+
199  /****************************************************************/
+
200  bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x,
+
201  Ipopt::Number &obj_value)
+
202  {
+
203  obj_value=0.0;
+
204  if (p.size()>0)
+
205  {
+
206  Vector _x(4);
+
207  _x[0]=x[0];
+
208  _x[1]=x[1];
+
209  _x[2]=x[2];
+
210  _x[3]=1.0;
+
211 
+
212  for (size_t i=0; i<p.size(); i++)
+
213  {
+
214  Vector pi=H[i]*_x;
+
215  pi=pi/pi[2];
+
216  pi.pop_back();
+
217 
+
218  obj_value+=norm2(p[i]-pi);
+
219  }
+
220 
+
221  obj_value/=p.size();
+
222  }
+
223 
+
224  return true;
+
225  }
+
226 
+
227  /****************************************************************/
+
228  bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
+
229  Ipopt::Number *grad_f)
+
230  {
+
231  Vector _x(4);
+
232  _x[0]=x[0];
+
233  _x[1]=x[1];
+
234  _x[2]=x[2];
+
235  _x[3]=1.0;
+
236 
+
237  grad_f[0]=grad_f[1]=grad_f[2]=0.0;
+
238  if (p.size()>0)
+
239  {
+
240  for (size_t i=0; i<p.size(); i++)
+
241  {
+
242  Vector pi=H[i]*_x;
+
243  pi=pi/pi[2];
+
244  pi.pop_back();
+
245 
+
246  Vector d=p[i]-pi;
+
247 
+
248  double u_num=dot(H[i].getRow(0),_x);
+
249  double v_num=dot(H[i].getRow(1),_x);
+
250 
+
251  double lambda=dot(H[i].getRow(2),_x);
+
252  double lambda2=lambda*lambda;
+
253 
+
254  Vector dp_dx1(2);
+
255  dp_dx1[0]=(H[i](0,0)*lambda-H[i](2,0)*u_num)/lambda2;
+
256  dp_dx1[1]=(H[i](1,0)*lambda-H[i](2,0)*v_num)/lambda2;
+
257 
+
258  Vector dp_dx2(2);
+
259  dp_dx2[0]=(H[i](0,1)*lambda-H[i](2,1)*u_num)/lambda2;
+
260  dp_dx2[1]=(H[i](1,1)*lambda-H[i](2,1)*v_num)/lambda2;
+
261 
+
262  Vector dp_dx3(2);
+
263  dp_dx3[0]=(H[i](0,2)*lambda-H[i](2,2)*u_num)/lambda2;
+
264  dp_dx3[1]=(H[i](1,2)*lambda-H[i](2,2)*v_num)/lambda2;
+
265 
+
266  grad_f[0]-=2.0*dot(d,dp_dx1);
+
267  grad_f[1]-=2.0*dot(d,dp_dx2);
+
268  grad_f[2]-=2.0*dot(d,dp_dx3);
+
269  }
+
270 
+
271  for (Ipopt::Index i=0; i<n; i++)
+
272  grad_f[i]/=p.size();
+
273  }
+
274 
+
275  return true;
+
276  }
+
277 
+
278  /****************************************************************/
+
279  bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x,
+
280  Ipopt::Index m, Ipopt::Number *g)
+
281  {
+
282  return true;
+
283  }
+
284 
+
285  /****************************************************************/
+
286  bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x,
+
287  Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow,
+
288  Ipopt::Index *jCol, Ipopt::Number *values)
+
289  {
+
290  return true;
+
291  }
+
292 
+
293 
+
294  /****************************************************************/
+
295  bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x,
+
296  Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda,
+
297  bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow,
+
298  Ipopt::Index *jCol, Ipopt::Number *values)
+
299  {
+
300  return true;
+
301  }
+
302 
+
303 
+
304  /****************************************************************/
+
305  void finalize_solution(Ipopt::SolverReturn status, Ipopt::Index n,
+
306  const Ipopt::Number *x, const Ipopt::Number *z_L,
+
307  const Ipopt::Number *z_U, Ipopt::Index m,
+
308  const Ipopt::Number *g, const Ipopt::Number *lambda,
+
309  Ipopt::Number obj_value, const Ipopt::IpoptData *ip_data,
+
310  Ipopt::IpoptCalculatedQuantities *ip_cq)
+
311  {
+
312  this->x.resize(n);
+
313  for (Ipopt::Index i=0; i<n; i++)
+
314  this->x[i]=x[i];
+
315  }
+
316 };
+
317 
+
318 
+
319 
+
320 /****************************************************************/
+
321 class FindToolTip
+
322 {
+
323 protected:
+
324  Vector min;
+
325  Vector max;
+
326  Vector x0;
+
327 
+
328  deque<Vector> p;
+
329  deque<Matrix> H;
+
330 
+
331  /****************************************************************/
+
332  double evalError(const Vector &x)
+
333  {
+
334  double error=0.0;
+
335  if (p.size()>0)
+
336  {
+
337  Vector _x=x;
+
338  if (_x.length()<4)
+
339  _x.push_back(1.0);
+
340 
+
341  for (size_t i=0; i<p.size(); i++)
+
342  {
+
343  Vector pi=H[i]*_x;
+
344  pi=pi/pi[2];
+
345  pi.pop_back();
+
346 
+
347  error+=norm(p[i]-pi);
+
348  }
+
349 
+
350  error/=p.size();
+
351  }
+
352 
+
353  return error;
+
354  }
+
355 
+
356 public:
+
357  /****************************************************************/
+
358  FindToolTip()
+
359  {
+
360  min.resize(3); max.resize(3);
+
361  min[0]=-1.0; max[0]=1.0;
+
362  min[1]=-1.0; max[1]=1.0;
+
363  min[2]=-1.0; max[2]=1.0;
+
364 
+
365  x0=0.5*(min+max);
+
366  }
+
367 
+
368  /****************************************************************/
+
369  void setBounds(const Vector &min, const Vector &max)
+
370  {
+
371  size_t len_min=std::min(this->min.length(),min.length());
+
372  size_t len_max=std::min(this->max.length(),max.length());
+
373 
+
374  for (size_t i=0; i<len_min; i++)
+
375  this->min[i]=min[i];
+
376 
+
377  for (size_t i=0; i<len_max; i++)
+
378  this->max[i]=max[i];
+
379  }
+
380 
+
381  /****************************************************************/
+
382  bool addItem(const Vector &pi, const Matrix &Hi)
+
383  {
+
384  if ((pi.length()>=2) && (Hi.rows()>=3) && (Hi.cols()>=4))
+
385  {
+
386  Vector _pi=pi.subVector(0,1);
+
387  Matrix _Hi=Hi.submatrix(0,2,0,3);
+
388 
+
389  p.push_back(_pi);
+
390  H.push_back(_Hi);
+
391 
+
392  return true;
+
393  }
+
394  else
+
395  return false;
+
396  }
+
397 
+
398  /****************************************************************/
+
399  void clearItems()
+
400  {
+
401  p.clear();
+
402  H.clear();
+
403  }
+
404 
+
405  /****************************************************************/
+
406  size_t getNumItems() const
+
407  {
+
408  return p.size();
+
409  }
+
410 
+
411  /****************************************************************/
+
412  bool setInitialGuess(const Vector &x0)
+
413  {
+
414  size_t len=std::min(x0.length(),this->x0.length());
+
415  for (size_t i=0; i<len; i++)
+
416  this->x0[i]=x0[i];
+
417 
+
418  return true;
+
419  }
+
420 
+
421  /****************************************************************/
+
422  bool solve(Vector &x, double &error)
+
423  {
+
424  if (p.size()>0)
+
425  {
+
426  Ipopt::SmartPtr<Ipopt::IpoptApplication> app=new Ipopt::IpoptApplication;
+
427  app->Options()->SetNumericValue("tol",1e-8);
+
428  app->Options()->SetIntegerValue("acceptable_iter",0);
+
429  app->Options()->SetStringValue("mu_strategy","adaptive");
+
430  app->Options()->SetIntegerValue("max_iter",300);
+
431  app->Options()->SetStringValue("nlp_scaling_method","gradient-based");
+
432  app->Options()->SetStringValue("hessian_approximation","limited-memory");
+
433  app->Options()->SetIntegerValue("print_level",0);
+
434  app->Options()->SetStringValue("derivative_test","none");
+
435  app->Initialize();
+
436 
+
437  Ipopt::SmartPtr<FindToolTipNLP> nlp=new FindToolTipNLP(p,H,min,max);
+
438 
+
439  nlp->set_x0(x0);
+
440  Ipopt::ApplicationReturnStatus status=app->OptimizeTNLP(GetRawPtr(nlp));
+
441 
+
442  x=nlp->get_result();
+
443  error=evalError(x);
+
444 
+
445  return (status==Ipopt::Solve_Succeeded);
+
446  }
+
447  else
+
448  return false;
+
449  }
+
450 };
+
451 
+
452 
+
453 
+
454 /************************************************************************/
+
455 class FinderModule: public RFModule, public PortReader
+
456 {
+
457 protected:
+
458  PolyDriver drvArmL;
+
459  PolyDriver drvArmR;
+
460  PolyDriver drvGaze;
+
461  ICartesianControl *iarm;
+
462  IGazeControl *igaze;
+
463  RpcServer rpcPort;
+
464  Matrix Prj;
+
465  mutex mtx;
+
466  FindToolTip solver;
+
467  Vector solution;
+
468  Bottle tip;
+
469  string arm;
+
470  string eye;
+
471  bool enabled;
+
472 
+
473  BufferedPort<ImageOf<PixelBgr> > imgInPort;
+
474  BufferedPort<ImageOf<PixelBgr> > imgOutPort;
+
475  Port dataInPort;
+
476  BufferedPort<Vector> logPort;
+
477 
+
478  /************************************************************************/
+
479  bool read(ConnectionReader &connection)
+
480  {
+
481  Bottle data;
+
482  data.read(connection);
+
483  if ((data.size()>=2) && enabled)
+
484  {
+
485  Vector xa,oa;
+
486  iarm->getPose(xa,oa);
+
487 
+
488  Vector xe,oe;
+
489  if (eye=="left")
+
490  igaze->getLeftEyePose(xe,oe);
+
491  else
+
492  igaze->getRightEyePose(xe,oe);
+
493 
+
494  Matrix Ha=axis2dcm(oa);
+
495  Ha.setSubcol(xa,0,3);
+
496 
+
497  Matrix He=axis2dcm(oe);
+
498  He.setSubcol(xe,0,3);
+
499 
+
500  Matrix H=Prj*SE3inv(He)*Ha;
+
501  Vector p(2);
+
502  p[0]=data.get(0).asDouble();
+
503  p[1]=data.get(1).asDouble();
+
504 
+
505  if (logPort.getOutputCount()>0)
+
506  {
+
507  Vector &log=logPort.prepare();
+
508 
+
509  log=p;
+
510  for (int i=0; i<H.rows(); i++)
+
511  log=cat(log,H.getRow(i));
+
512  for (int i=0; i<Prj.rows(); i++)
+
513  log=cat(log,Prj.getRow(i));
+
514  for (int i=0; i<Ha.rows(); i++)
+
515  log=cat(log,Ha.getRow(i));
+
516  for (int i=0; i<He.rows(); i++)
+
517  log=cat(log,He.getRow(i));
+
518 
+
519  logPort.write();
+
520  }
+
521 
+
522  mtx.lock();
+
523  solver.addItem(p,H);
+
524  mtx.unlock();
+
525  }
+
526 
+
527  return true;
+
528  }
+
529 
+
530 public:
+
531  /************************************************************************/
+
532  bool configure(ResourceFinder &rf)
+
533  {
+
534  string robot=rf.check("robot",Value("icub")).asString();
+
535  string name=rf.check("name",Value("karmaToolFinder")).asString();
+
536  arm=rf.check("arm",Value("right")).asString();
+
537  eye=rf.check("eye",Value("left")).asString();
+
538 
+
539  if ((arm!="left") && (arm!="right"))
+
540  {
+
541  printf("Invalid arm requested!\n");
+
542  return false;
+
543  }
+
544 
+
545  if ((eye!="left") && (eye!="right"))
+
546  {
+
547  printf("Invalid eye requested!\n");
+
548  return false;
+
549  }
+
550 
+
551  Property optionArmL("(device cartesiancontrollerclient)");
+
552  optionArmL.put("remote","/"+robot+"/cartesianController/left_arm");
+
553  optionArmL.put("local","/"+name+"/left_arm");
+
554  if (!drvArmL.open(optionArmL))
+
555  {
+
556  printf("Cartesian left_arm controller not available!\n");
+
557  terminate();
+
558  return false;
+
559  }
+
560 
+
561  Property optionArmR("(device cartesiancontrollerclient)");
+
562  optionArmR.put("remote","/"+robot+"/cartesianController/right_arm");
+
563  optionArmR.put("local","/"+name+"/right_arm");
+
564  if (!drvArmR.open(optionArmR))
+
565  {
+
566  printf("Cartesian right_arm controller not available!\n");
+
567  terminate();
+
568  return false;
+
569  }
+
570 
+
571  if (arm=="left")
+
572  drvArmL.view(iarm);
+
573  else
+
574  drvArmR.view(iarm);
+
575 
+
576  Property optionGaze("(device gazecontrollerclient)");
+
577  optionGaze.put("remote","/iKinGazeCtrl");
+
578  optionGaze.put("local","/"+name+"/gaze");
+
579  if (drvGaze.open(optionGaze))
+
580  drvGaze.view(igaze);
+
581  else
+
582  {
+
583  printf("Gaze controller not available!\n");
+
584  terminate();
+
585  return false;
+
586  }
+
587 
+
588  Bottle info;
+
589  igaze->getInfo(info);
+
590  if (Bottle *pB=info.find("camera_intrinsics_"+eye).asList())
+
591  {
+
592  int cnt=0;
+
593  Prj.resize(3,4);
+
594  for (int r=0; r<Prj.rows(); r++)
+
595  for (int c=0; c<Prj.cols(); c++)
+
596  Prj(r,c)=pB->get(cnt++).asDouble();
+
597  }
+
598  else
+
599  {
+
600  printf("Camera intrinsic parameters not available!\n");
+
601  terminate();
+
602  return false;
+
603  }
+
604 
+
605  imgInPort.open("/"+name+"/img:i");
+
606  imgOutPort.open("/"+name+"/img:o");
+
607  dataInPort.open("/"+name+"/in");
+
608  logPort.open("/"+name+"/log:o");
+
609  rpcPort.open("/"+name+"/rpc");
+
610  attach(rpcPort);
+
611 
+
612  Vector min(3),max(3);
+
613  min[0]=-1.0; max[0]=1.0;
+
614  min[1]=-1.0; max[1]=1.0;
+
615  min[2]=-1.0; max[2]=1.0;
+
616  solver.setBounds(min,max);
+
617  solution.resize(3,0.0);
+
618 
+
619  enabled=false;
+
620  dataInPort.setReader(*this);
+
621 
+
622  return true;
+
623  }
+
624 
+
625  /************************************************************************/
+
626  bool respond(const Bottle &command, Bottle &reply)
+
627  {
+
628  int ack=Vocab::encode("ack");
+
629  int nack=Vocab::encode("nack");
+
630 
+
631  if (command.size()>0)
+
632  {
+
633  switch (command.get(0).asVocab())
+
634  {
+
635  //-----------------
+
636  case createVocab('c','l','e','a'):
+
637  {
+
638  lock_guard<mutex> lg(mtx);
+
639  solver.clearItems();
+
640  solution=0.0;
+
641  reply.addVocab(ack);
+
642  return true;
+
643  }
+
644 
+
645  //-----------------
+
646  case createVocab('s','e','l','e'):
+
647  {
+
648  if (command.size()>=3)
+
649  {
+
650  string arm=command.get(1).asString();
+
651  string eye=command.get(2).asString();
+
652 
+
653  if ((arm=="left") || (arm=="right"))
+
654  this->arm=arm;
+
655 
+
656  if ((eye=="left") || (eye=="right"))
+
657  this->eye=eye;
+
658 
+
659  if (this->arm=="left")
+
660  drvArmL.view(iarm);
+
661  else
+
662  drvArmR.view(iarm);
+
663 
+
664  reply.addVocab(ack);
+
665  }
+
666  else
+
667  reply.addVocab(nack);
+
668 
+
669  return true;
+
670  }
+
671 
+
672  //-----------------
+
673  case createVocab('n','u','m'):
+
674  {
+
675  reply.addVocab(ack);
+
676 
+
677  lock_guard<mutex> lg(mtx);
+
678  reply.addInt((int)solver.getNumItems());
+
679  return true;
+
680  }
+
681 
+
682  //-----------------
+
683  case createVocab('f','i','n','d'):
+
684  {
+
685  double error;
+
686 
+
687  mtx.lock();
+
688  bool ok=solver.solve(solution,error);
+
689  mtx.unlock();
+
690 
+
691  if (ok)
+
692  {
+
693  reply.addVocab(ack);
+
694  for (size_t i=0; i<solution.length(); i++)
+
695  reply.addDouble(solution[i]);
+
696  }
+
697  else
+
698  reply.addVocab(nack);
+
699 
+
700  return true;
+
701  }
+
702 
+
703  //-----------------
+
704  case createVocab('s','h','o','w'):
+
705  {
+
706  if (command.size()>=4)
+
707  {
+
708  solution[0]=command.get(1).asDouble();
+
709  solution[1]=command.get(2).asDouble();
+
710  solution[2]=command.get(3).asDouble();
+
711 
+
712  reply.addVocab(ack);
+
713  }
+
714  else
+
715  reply.addVocab(nack);
+
716 
+
717  return true;
+
718  }
+
719 
+
720  //-----------------
+
721  case createVocab('t','i','p'):
+
722  {
+
723  if (tip.size()>=2)
+
724  {
+
725  reply.addVocab(ack);
+
726  reply.append(tip);
+
727  }
+
728  else
+
729  reply.addVocab(nack);
+
730 
+
731  return true;
+
732  }
+
733 
+
734  //-----------------
+
735  case createVocab('e','n','a','b'):
+
736  {
+
737  enabled=true;
+
738  reply.addVocab(ack);
+
739  return true;
+
740  }
+
741 
+
742  //-----------------
+
743  case createVocab('d','i','s','a'):
+
744  {
+
745  enabled=false;
+
746  reply.addVocab(ack);
+
747  return true;
+
748  }
+
749 
+
750  //-----------------
+
751  default:
+
752  return RFModule::respond(command,reply);
+
753  }
+
754  }
+
755 
+
756  reply.addVocab(nack);
+
757  return true;
+
758  }
+
759 
+
760  /************************************************************************/
+
761  double getPeriod()
+
762  {
+
763  return 0.03;
+
764  }
+
765 
+
766  /************************************************************************/
+
767  bool updateModule()
+
768  {
+
769  if (imgOutPort.getOutputCount()>0)
+
770  {
+
771  if (ImageOf<PixelBgr> *pImgBgrIn=imgInPort.read(false))
+
772  {
+
773  Vector xa,oa;
+
774  iarm->getPose(xa,oa);
+
775 
+
776  Matrix Ha=axis2dcm(oa);
+
777  Ha.setSubcol(xa,0,3);
+
778 
+
779  Vector v(4,0.0); v[3]=1.0;
+
780  Vector c=Ha*v;
+
781 
+
782  v=0.0; v[0]=0.05; v[3]=1.0;
+
783  Vector x=Ha*v;
+
784 
+
785  v=0.0; v[1]=0.05; v[3]=1.0;
+
786  Vector y=Ha*v;
+
787 
+
788  v=0.0; v[2]=0.05; v[3]=1.0;
+
789  Vector z=Ha*v;
+
790 
+
791  v=solution; v.push_back(1.0);
+
792  Vector t=Ha*v;
+
793 
+
794  Vector pc,px,py,pz,pt;
+
795  int camSel=(eye=="left")?0:1;
+
796  igaze->get2DPixel(camSel,c,pc);
+
797  igaze->get2DPixel(camSel,x,px);
+
798  igaze->get2DPixel(camSel,y,py);
+
799  igaze->get2DPixel(camSel,z,pz);
+
800  igaze->get2DPixel(camSel,t,pt);
+
801 
+
802  cv::Point point_c((int)pc[0],(int)pc[1]);
+
803  cv::Point point_x((int)px[0],(int)px[1]);
+
804  cv::Point point_y((int)py[0],(int)py[1]);
+
805  cv::Point point_z((int)pz[0],(int)pz[1]);
+
806  cv::Point point_t((int)pt[0],(int)pt[1]);
+
807 
+
808  cv::Mat imgMat=toCvMat(*pImgBgrIn);
+
809 
+
810  cv::circle(imgMat,point_c,4,cv::Scalar(0,255,0),4);
+
811  cv::circle(imgMat,point_t,4,cv::Scalar(255,0,0),4);
+
812 
+
813  cv::line(imgMat,point_c,point_x,cv::Scalar(0,0,255),2);
+
814  cv::line(imgMat,point_c,point_y,cv::Scalar(0,255,0),2);
+
815  cv::line(imgMat,point_c,point_z,cv::Scalar(255,0,0),2);
+
816  cv::line(imgMat,point_c,point_t,cv::Scalar(255,255,255),2);
+
817 
+
818  tip.clear();
+
819  tip.addInt(point_t.x);
+
820  tip.addInt(point_t.y);
+
821 
+
822  imgOutPort.prepare()=*pImgBgrIn;
+
823  imgOutPort.write();
+
824  }
+
825  }
+
826 
+
827  return true;
+
828  }
+
829 
+
830  /************************************************************************/
+
831  void terminate()
+
832  {
+
833 
+
834  imgInPort.close();
+
835  imgOutPort.close();
+
836  dataInPort.close(); // close prior to shutting down motor-interfaces
+
837  logPort.close();
+
838  rpcPort.close();
+
839 
+
840  if (drvArmL.isValid())
+
841  drvArmL.close();
+
842 
+
843  if (drvArmR.isValid())
+
844  drvArmR.close();
+
845 
+
846  if (drvGaze.isValid())
+
847  drvGaze.close();
+
848  }
+
849 
+
850  /************************************************************************/
+
851  bool close()
+
852  {
+
853  terminate();
+
854  return true;
+
855  }
+
856 };
+
857 
+
858 
+
859 
+
860 /****************************************************************/
+
861 int main(int argc, char *argv[])
+
862 {
+
863  Network yarp;
+
864  if (!yarp.checkNetwork())
+
865  {
+
866  printf("YARP server not available!\n");
+
867  return 1;
+
868  }
+
869 
+
870  ResourceFinder rf;
+
871  rf.configure(argc,argv);
+
872 
+
873  FinderModule mod;
+
874  return mod.runModule(rf);
+
875 }
+
876 
+
877 
+
+ + + + diff --git a/doxygen/doc/html/karmaToolProjection_2include_2iCub_2module_8h_source.html b/doxygen/doc/html/karmaToolProjection_2include_2iCub_2module_8h_source.html new file mode 100644 index 0000000..9212672 --- /dev/null +++ b/doxygen/doc/html/karmaToolProjection_2include_2iCub_2module_8h_source.html @@ -0,0 +1,152 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/include/iCub/module.h Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
module.h
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #ifndef __MODULE_H__
+
19 #define __MODULE_H__
+
20 
+
21 #include <string>
+
22 
+
23 #include "opencv2/opencv.hpp"
+
24 
+
25 #include <yarp/os/Time.h>
+
26 #include <yarp/os/RFModule.h>
+
27 #include <yarp/os/RpcServer.h>
+
28 #include <yarp/os/RpcClient.h>
+
29 #include <yarp/os/BufferedPort.h>
+
30 #include <yarp/os/Port.h>
+
31 #include <yarp/sig/Image.h>
+
32 #include <yarp/sig/Vector.h>
+
33 
+
34 #include "iCub/utils.h"
+
35 
+
36 /**********************************************************/
+
37 struct lineData
+
38 {
+
39  double gradient;
+
40  double intercept;
+
41 };
+
42 
+
43 /**********************************************************/
+
44 class Manager : public yarp::os::RFModule
+
45 {
+
46 protected:
+
47  std::string name; //name of the module
+
48  yarp::os::Port rpcHuman; //human rpc port (receive commands via rpc)
+
49 
+
50  yarp::os::Port motionFilter; //port that receives an image containing blobs from motion
+
51  yarp::os::Port toolPoint; //port that receives an image containing blobs from motion
+
52  yarp::os::BufferedPort<yarp::sig::ImageOf<yarp::sig::PixelRgb> > imgOutPort; //port that sends out img
+
53 
+
54  MotionFeatures motionFeatures; //class to receive points from motionFilter
+
55 
+
56  lineData *lineDetails;
+
57 
+
58  int processHumanCmd(const yarp::os::Bottle &cmd, yarp::os::Bottle &b);
+
59  void processBlobs(yarp::os::Bottle &b, cv::Mat &dest, lineData *lineDetails);
+
60  void processMotionPoints(yarp::os::Bottle &b);
+
61  yarp::os::Bottle processImage(yarp::os::Bottle &b, cv::Mat &dest, cv::Mat &clean, lineData *lineDetails);
+
62  void getIntersection(cv::Mat &dest, lineData *lineDetails );
+
63 
+
64  friend class MotionFeatures;
+
65 
+
66 public:
+
67  bool configure(yarp::os::ResourceFinder &rf);
+
68  bool interruptModule();
+
69  bool close();
+
70  bool updateModule();
+
71  double getPeriod();
+
72 };
+
73 
+
74 #endif
+
+ + + + diff --git a/doxygen/doc/html/karmaToolProjection_2include_2iCub_2utils_8h_source.html b/doxygen/doc/html/karmaToolProjection_2include_2iCub_2utils_8h_source.html new file mode 100644 index 0000000..e801d75 --- /dev/null +++ b/doxygen/doc/html/karmaToolProjection_2include_2iCub_2utils_8h_source.html @@ -0,0 +1,138 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/include/iCub/utils.h Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
utils.h
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #ifndef __UTILS_H__
+
19 #define __UTILS_H__
+
20 
+
21 #include <string>
+
22 
+
23 #include <opencv2/opencv.hpp>
+
24 
+
25 #include <yarp/os/Bottle.h>
+
26 #include <yarp/os/BufferedPort.h>
+
27 #include <yarp/os/PeriodicThread.h>
+
28 #include <yarp/os/PortReport.h>
+
29 
+
30 class Manager; //forward declaration
+
31 
+
32 /**********************************************************/
+
33 class MotionFeatures : public yarp::os::BufferedPort<yarp::os::Bottle>
+
34 {
+
35 protected:
+
36  Manager *manager;
+
37  void onRead(yarp::os::Bottle &b);
+
38 public:
+
39  MotionFeatures();
+
40  void setManager(Manager *manager);
+
41  bool getFeatures();
+
42 };
+
43 /**********************************************************/
+
44 class ParticleFilter : public yarp::os::BufferedPort<yarp::os::Bottle>
+
45 {
+
46 protected:
+
47  cv::Point loc;
+
48  void onRead(yarp::os::Bottle &b);
+
49 public:
+
50  ParticleFilter();
+
51  bool getTraker(cv::Point &loc);
+
52 };
+
53 /**********************************************************/
+
54 class SegmentationPoint : public yarp::os::Port
+
55 {
+
56 public:
+
57  void segment(yarp::os::Bottle &b);
+
58 };
+
59 /**********************************************************/
+
60 #endif
+
+ + + + diff --git a/doxygen/doc/html/karmaToolProjection_2src_2main_8cpp_source.html b/doxygen/doc/html/karmaToolProjection_2src_2main_8cpp_source.html new file mode 100644 index 0000000..811735d --- /dev/null +++ b/doxygen/doc/html/karmaToolProjection_2src_2main_8cpp_source.html @@ -0,0 +1,116 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/src/main.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
main.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
52 #include <yarp/os/Network.h>
+
53 #include "iCub/module.h"
+
54 
+
55 using namespace yarp::os;
+
56 
+
57 /**********************************************************/
+
58 int main(int argc, char *argv[])
+
59 {
+
60  Network yarp;
+
61  if (!yarp.checkNetwork())
+
62  return 1;
+
63 
+
64  ResourceFinder rf;
+
65  rf.setDefault("name","karmaToolProjection");
+
66  rf.setDefault("tracking_period","30");
+
67  rf.configure(argc,argv);
+
68 
+
69  Manager manager;
+
70  return manager.runModule(rf);
+
71 }
+
72 
+
+ + + + diff --git a/doxygen/doc/html/karmaToolProjection_2src_2module_8cpp_source.html b/doxygen/doc/html/karmaToolProjection_2src_2module_8cpp_source.html new file mode 100644 index 0000000..1cf02ad --- /dev/null +++ b/doxygen/doc/html/karmaToolProjection_2src_2module_8cpp_source.html @@ -0,0 +1,402 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/src/module.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
module.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 #include <sstream>
+
18 #include <cstdio>
+
19 
+
20 #include <yarp/math/Rand.h>
+
21 #include <yarp/math/Math.h>
+
22 #include <yarp/cv/Cv.h>
+
23 #include "iCub/module.h"
+
24 
+
25 using namespace cv;
+
26 using namespace std;
+
27 using namespace yarp::os;
+
28 using namespace yarp::sig;
+
29 using namespace yarp::math;
+
30 using namespace yarp::cv;
+
31 
+
32 
+
33 /**********************************************************/
+
34 bool Manager::configure(ResourceFinder &rf)
+
35 {
+
36  name=rf.find("name").asString();
+
37 
+
38  //incoming
+
39  motionFeatures.open("/"+name+"/motionFilter:i"); //port for incoming blobs from motionCut
+
40 
+
41  //outgoing
+
42  toolPoint.open("/"+name+"/target:o"); //port to send off target Points to segmentator
+
43  imgOutPort.open("/"+name+"/img:o"); //port to send off target Points to segmentator
+
44 
+
45  //rpc
+
46  rpcHuman.open("/"+name+"/human:rpc"); //rpc server to interact with the user
+
47 
+
48  motionFeatures.setManager(this);
+
49  lineDetails = new lineData [10];
+
50  //attach(rpcHuman);
+
51  return true;
+
52 }
+
53 /**********************************************************/
+
54 bool Manager::interruptModule()
+
55 {
+
56  motionFeatures.interrupt();
+
57  toolPoint.interrupt();
+
58  imgOutPort.interrupt();
+
59  rpcHuman.interrupt();
+
60  return true;
+
61 }
+
62 /**********************************************************/
+
63 bool Manager::close()
+
64 {
+
65  delete[] lineDetails;
+
66  motionFeatures.close();
+
67  toolPoint.close();
+
68  imgOutPort.close();
+
69  rpcHuman.close();
+
70  return true;
+
71 }
+
72 /**********************************************************/
+
73 int Manager::processHumanCmd(const Bottle &cmd, Bottle &b)
+
74 {
+
75  int ret=Vocab::encode(cmd.get(0).asString());
+
76  b.clear();
+
77  if (cmd.size()>1)
+
78  {
+
79  if (cmd.get(1).isList())
+
80  b=*cmd.get(1).asList();
+
81  else
+
82  b=cmd.tail();
+
83  }
+
84  return ret;
+
85 }
+
86 /**********************************************************/
+
87 bool Manager::updateModule()
+
88 {
+
89  if (isStopping())
+
90  return false;
+
91 
+
92  Bottle cmd, val, reply;
+
93  rpcHuman.read(cmd, true);
+
94  int rxCmd=processHumanCmd(cmd,val);
+
95  if (rxCmd==Vocab::encode("action"))
+
96  {
+
97  reply.addString("ack");
+
98  rpcHuman.reply(reply);
+
99  }
+
100  return true;
+
101 }
+
102 /**********************************************************/
+
103 double Manager::getPeriod()
+
104 {
+
105  return 0.1;
+
106 }
+
107 
+
108 /**********************************************************/
+
109 void Manager::processMotionPoints(Bottle &b)
+
110 {
+
111  //create MAT image
+
112  cv::Mat imgMat(Size(320,240),CV_8UC3);
+
113  cv::Mat imgClean(Size(320,240),CV_8UC3);
+
114  imgMat = Scalar::all(0);
+
115  imgClean = Scalar::all(255);
+
116 
+
117  for (int x=1; x<b.size(); x++)
+
118  {
+
119  Point pt;
+
120  pt.x = b.get(x).asList()->get(0).asInt();
+
121  pt.y = b.get(x).asList()->get(1).asInt();
+
122  imgMat.at<cv::Vec3b>(pt.y,pt.x)[0] = 255 ;
+
123  imgMat.at<cv::Vec3b>(pt.y,pt.x)[1] = 0 ;
+
124  imgMat.at<cv::Vec3b>(pt.y,pt.x)[2] = 0 ;
+
125  imgClean.at<cv::Vec3b>(pt.y,pt.x)[0] = 255 ;
+
126  imgClean.at<cv::Vec3b>(pt.y,pt.x)[1] = 0 ;
+
127  imgClean.at<cv::Vec3b>(pt.y,pt.x)[2] = 0 ;
+
128  }
+
129 
+
130  int n = 10;
+
131  int an = n > 0 ? n : -n;
+
132  int element_shape = MORPH_RECT;
+
133  Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
+
134  morphologyEx(imgMat, imgMat, CV_MOP_CLOSE, element);
+
135 
+
136  Bottle data;
+
137  data = processImage(b, imgMat, imgClean, lineDetails); //image analysis and bottle cleaning
+
138 
+
139  if (data.size() > 0)
+
140  processBlobs(data, imgClean, lineDetails); // kmeans
+
141 
+
142  ImageOf<PixelRgb> &outImg = imgOutPort.prepare();
+
143  outImg.resize( imgClean.cols, imgClean.rows );
+
144  imgClean.copyTo(toCvMat(outImg));
+
145  imgOutPort.write();
+
146 }
+
147 
+
148 /**********************************************************/
+
149 void Manager::processBlobs(Bottle &b, cv::Mat &dest, lineData *lineDetails)
+
150 {
+
151  int sampleCount = b.size();
+
152  int dimensions = 2;
+
153  int clusterCount = 2;
+
154  Mat points(sampleCount, dimensions, CV_32F);
+
155  Mat labels;
+
156  Mat centers(clusterCount, dimensions, points.type());
+
157  for(int i = 0; i<sampleCount;i++)
+
158  {
+
159  points.at<float>(i,0) = (float) b.get(i).asList()->get(0).asInt();
+
160  points.at<float>(i,1) = (float) b.get(i).asList()->get(1).asInt();
+
161  }
+
162 
+
163  if (sampleCount<clusterCount)
+
164  {
+
165  printf("sampleCount < clusterCount!\n");
+
166  return;
+
167  }
+
168 
+
169  kmeans(points, clusterCount, labels, TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), 3, KMEANS_PP_CENTERS, centers);
+
170 
+
171  Point pts[10];
+
172  for (int i = 0; i < clusterCount; i++)
+
173  {
+
174  int clusterIdx = labels.at<int>(i);
+
175  Point ipt;
+
176  ipt.x = (int) centers.at<float>(i,0);
+
177  ipt.y = (int) centers.at<float>(i,1);
+
178 
+
179  pts[i] = ipt;
+
180  circle( dest, ipt, 5, CV_RGB(255,255,255), cv::FILLED, cv::LINE_AA );
+
181  }
+
182  double gradient = 0;
+
183  double intercept = 0;
+
184 
+
185  if (pts[1].y < pts[0].y )
+
186  {
+
187  double pow1 = pow( fabs((double)pts[0].x - (double)pts[1].x),2);
+
188  double pow2 = pow( fabs((double)pts[0].y - (double)pts[1].y),2);
+
189  double lenAB = sqrt( pow1 + pow2 );
+
190  Point endPoint;
+
191  endPoint.x = (int)(pts[1].x + (double)(pts[1].x - pts[0].x) / lenAB * 50);
+
192  endPoint.y = (int)(pts[1].y + (double) (pts[1].y - pts[0].y) / lenAB * 50);
+
193  line(dest, pts[0], endPoint, Scalar(0,0,0), 2, cv::LINE_AA);
+
194  gradient = (double)( endPoint.y - pts[0].y ) / (double)( endPoint.x - pts[0].x );
+
195  intercept = (double)( pts[0].y - (double)(pts[0].x * gradient) );
+
196  lineDetails[1].gradient = gradient;
+
197  lineDetails[1].intercept = intercept;
+
198  }
+
199  else
+
200  {
+
201  double pow1 = pow( fabs((double)pts[1].x - (double)pts[0].x), 2);
+
202  double pow2 = pow( fabs((double)pts[1].y - (double)pts[0].y), 2);
+
203  double lenAB = sqrt( pow1 + pow2 );
+
204  Point endPoint;
+
205  endPoint.x = (int)(pts[0].x + (double)(pts[0].x - pts[1].x) / lenAB * 50);
+
206  endPoint.y = (int)(pts[0].y + (double)(pts[0].y - pts[1].y) / lenAB * 50);
+
207  line(dest, pts[1], endPoint, Scalar(0,0,0), 2, cv::LINE_AA);
+
208 
+
209  gradient = (double)( endPoint.y - pts[1].y) / (double)(endPoint.x - pts[1].x);
+
210  intercept = (double)( endPoint.y - (double)(endPoint.x * gradient) );
+
211  lineDetails[1].gradient = gradient;
+
212  lineDetails[1].intercept = intercept;
+
213  }
+
214  //find
+
215  getIntersection(dest, lineDetails);
+
216 }
+
217 /**********************************************************/
+
218 void Manager::getIntersection(cv::Mat &dest, lineData *lineDetails)
+
219 {
+
220  int thickness = -1;
+
221  int lineType = 8;
+
222  Point intersect;
+
223 
+
224  intersect.x = (int)( (lineDetails[1].intercept - lineDetails[0].intercept) / (lineDetails[0].gradient-lineDetails[1].gradient));
+
225  intersect.y = (int)( (lineDetails[0].gradient * intersect.x) + lineDetails[0].intercept);
+
226 
+
227  if (intersect.x > 0 && intersect.y >0 && intersect.x < dest.cols && intersect.y < dest.rows)
+
228  {
+
229  circle( dest, intersect, dest.rows/(int)32.0, Scalar( 255, 0, 0 ), thickness, lineType );
+
230  Bottle output;
+
231  output.clear();
+
232  output.addInt(intersect.x);
+
233  output.addInt(intersect.y);
+
234  toolPoint.write(output);
+
235  }
+
236 }
+
237 
+
238 /**********************************************************/
+
239 Bottle Manager::processImage(Bottle &b, cv::Mat &dest, cv::Mat &clean, lineData *lineDetails)
+
240 {
+
241  Bottle botListDel, botPointsDel;
+
242  Bottle correctList, correctElements;
+
243  vector<vector<Point> > contours;
+
244  cv::Mat imgGray(Size(320,240),CV_8UC1);
+
245  cv::cvtColor( dest, imgGray, CV_RGB2GRAY);
+
246  double gradient = 0;
+
247  double intercept = 0;
+
248  findContours(imgGray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
+
249  for(size_t i = 0; i < contours.size(); i++)
+
250  {
+
251  size_t count = contours[i].size();
+
252  if( count < 6 )
+
253  continue;
+
254 
+
255  Mat pointsf;
+
256  Mat(contours[i]).convertTo(pointsf, CV_32F);
+
257  RotatedRect box = fitEllipse(pointsf);
+
258 
+
259  if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 )
+
260  continue;
+
261 
+
262  double area = contourArea( Mat(contours[i]) );
+
263  if ( area > 10 && area < 4000)
+
264  {
+
265  for (int x = (int)box.center.x - (int)box.size.width; x < (int)box.center.x + (int)box.size.width; x++){
+
266  for (int y = (int)box.center.y - (int)box.size.height; y < (int)box.center.y + (int)box.size.height; y++)
+
267  {
+
268  if (y< imgGray.rows-1 && x< imgGray.cols-1 && y > 0 && x > 0)
+
269  {
+
270  if( dest.at<cv::Vec3b>(y,x)[0] == 255 )
+
271  {
+
272  dest.at<cv::Vec3b>(y,x)[0] = 0;
+
273  botPointsDel.clear();
+
274  botPointsDel.addInt(x);
+
275  botPointsDel.addInt(y);
+
276  botListDel.addList() = botPointsDel;
+
277  }
+
278  }
+
279  }
+
280  }
+
281  }
+
282  else
+
283  {
+
284  for (int v = 1; v<b.size(); v++)
+
285  {
+
286  bool found=false;
+
287  for (int w = 0; w<botListDel.size(); w++)
+
288  {
+
289  if ( ((float) b.get(v).asList()->get(0).asInt() == botListDel.get(w).asList()->get(0).asInt() ) &&
+
290  ((float) b.get(v).asList()->get(1).asInt() == botListDel.get(w).asList()->get(1).asInt() ) )
+
291  {
+
292  found=true;
+
293  break;
+
294  }
+
295  }
+
296  if(!found)
+
297  correctList.addList() = *b.get(v).asList();
+
298  }
+
299  drawContours(dest, contours, (int)i, Scalar::all(255), 1, 8);
+
300  Point2f vtx[4];
+
301  box.points(vtx);
+
302 
+
303  int j = 0;
+
304  if ( vtx[1].y < vtx[3].y )
+
305  {
+
306  j = 1;
+
307  fprintf(stdout,"3 < 0 %lf smaller than %lf \n", vtx[3].y, vtx[1].y);
+
308  }
+
309  else
+
310  {
+
311  j = 3;
+
312  fprintf(stdout,"0 < 3 %lf smaller than %lf \n", vtx[1].y, vtx[3].y);
+
313  }
+
314 
+
315  line(clean, vtx[j], vtx[(j+1)%4], Scalar(0,0,0), 2, cv::LINE_AA);
+
316  gradient = ( vtx[(j+1)%4].y - vtx[j].y) / (vtx[(j+1)%4].x - vtx[j].x);
+
317  intercept = ( vtx[j].y - (vtx[j].x *gradient) );
+
318 
+
319  lineDetails[0].gradient = gradient;
+
320  lineDetails[0].intercept = intercept;
+
321  }
+
322  }
+
323  return correctList;
+
324 }
+
+ + + + diff --git a/doxygen/doc/html/karmaToolProjection_2src_2utils_8cpp_source.html b/doxygen/doc/html/karmaToolProjection_2src_2utils_8cpp_source.html new file mode 100644 index 0000000..7c78865 --- /dev/null +++ b/doxygen/doc/html/karmaToolProjection_2src_2utils_8cpp_source.html @@ -0,0 +1,124 @@ + + + + + + + +karma: /home/runner/work/karma/karma/gh-pages/src/karmaToolProjection/src/utils.cpp Source File + + + + + + + + + +
+
+ + + + + + +
+
karma +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
utils.cpp
+
+
+
1 /*
+
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
+
3  * Author: Vadim Tikhanoff Ugo Pattacini
+
4  * email: vadim.tikhanoff@iit.it
+
5  * Permission is granted to copy, distribute, and/or modify this program
+
6  * under the terms of the GNU General Public License, version 2 or any
+
7  * later version published by the Free Software Foundation.
+
8  *
+
9  * A copy of the license can be found at
+
10  * http://www.robotcub.org/icub/license/gpl.txt
+
11  *
+
12  * This program is distributed in the hope that it will be useful, but
+
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
+
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+
15  * Public License for more details
+
16 */
+
17 
+
18 #include <yarp/os/Time.h>
+
19 
+
20 #include "iCub/utils.h"
+
21 #include "iCub/module.h"
+
22 
+
23 using namespace std;
+
24 using namespace yarp::os;
+
25 
+
26 /**********************************************************/
+
27 MotionFeatures::MotionFeatures()
+
28 {
+
29  manager=NULL;
+
30  useCallback();
+
31 }
+
32 void MotionFeatures::setManager(Manager *manager)
+
33 {
+
34  this->manager=manager;
+
35 }
+
36 /**********************************************************/
+
37 void MotionFeatures::onRead(Bottle &target)
+
38 {
+
39  if (target.size()>1)
+
40  {
+
41  //fprintf( stdout, "got something throught the port with size: %d\n",target.size() );
+
42  manager->processMotionPoints(target);
+
43  //manager->processBlobs(target);
+
44  }
+
45 }
+
46 
+
+ + + + diff --git a/doxygen/doc/html/menu.js b/doxygen/doc/html/menu.js new file mode 100644 index 0000000..2fe2214 --- /dev/null +++ b/doxygen/doc/html/menu.js @@ -0,0 +1,51 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + 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 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. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+=''; + } + return result; + } + + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchEnabled) { + if (serverSide) { + $('#main-menu').append('
  • '); + } else { + $('#main-menu').append('
  • '); + } + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/doxygen/doc/html/menudata.js b/doxygen/doc/html/menudata.js new file mode 100644 index 0000000..9b3d21d --- /dev/null +++ b/doxygen/doc/html/menudata.js @@ -0,0 +1,29 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + 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 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. + + @licend The above is the entire license notice for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Modules",url:"modules.html"}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}]}]} diff --git a/doxygen/doc/html/modules.html b/doxygen/doc/html/modules.html new file mode 100644 index 0000000..20ed435 --- /dev/null +++ b/doxygen/doc/html/modules.html @@ -0,0 +1,82 @@ + + + + + + + +karma: Modules + + + + + + + + + +
    +
    + + + + + + +
    +
    karma +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Modules
    +
    +
    +
    Here is a list of all modules:
    + + + + + +
     Learning module of the KARMA ExperimentMachine Learning Module that allows the robot to learn online and predict a one-to-one map
     Motor Part of the KARMA ExperimentMotor Control Module that allows the robot to push/draw the object and explore a tool
     Tool Solver Part of the KARMA ExperimentThis module finds the tool dimension employing nonlinear optimization
     Tool Projection Part of the KARMA ExperimentThis module finds the tooltip using motionCUT
    +
    +
    + + + + diff --git a/doxygen/doc/html/nav_f.png b/doxygen/doc/html/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc) zn!W8uqtnIQ>_z8U literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/nav_g.png b/doxygen/doc/html/nav_g.png new file mode 100644 index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE tr?otc=hd~V+ws&_A@j8Fiv!KF$B+ufw|5=67#uj90@pIL wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&vFVdQ&MBb@0HFXL1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/doxygen/doc/html/search/all_0.js b/doxygen/doc/html/search/all_0.js new file mode 100644 index 0000000..b71fe61 --- /dev/null +++ b/doxygen/doc/html/search/all_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['learning_20module_20of_20the_20karma_20experiment_0',['Learning module of the KARMA Experiment',['../group__karmaLearn.html',1,'']]] +]; diff --git a/doxygen/doc/html/search/all_1.html b/doxygen/doc/html/search/all_1.html new file mode 100644 index 0000000..9f80e90 --- /dev/null +++ b/doxygen/doc/html/search/all_1.html @@ -0,0 +1,37 @@ + + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/doxygen/doc/html/search/all_1.js b/doxygen/doc/html/search/all_1.js new file mode 100644 index 0000000..37ac6e0 --- /dev/null +++ b/doxygen/doc/html/search/all_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['motor_20part_20of_20the_20karma_20experiment_1',['Motor Part of the KARMA Experiment',['../group__karmaMotor.html',1,'']]] +]; diff --git a/doxygen/doc/html/search/all_2.html b/doxygen/doc/html/search/all_2.html new file mode 100644 index 0000000..02cfffc --- /dev/null +++ b/doxygen/doc/html/search/all_2.html @@ -0,0 +1,37 @@ + + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/doxygen/doc/html/search/all_2.js b/doxygen/doc/html/search/all_2.js new file mode 100644 index 0000000..189e885 --- /dev/null +++ b/doxygen/doc/html/search/all_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['tool_20projection_20part_20of_20the_20karma_20experiment_2',['Tool Projection Part of the KARMA Experiment',['../group__karmaToolProjection.html',1,'']]], + ['tool_20solver_20part_20of_20the_20karma_20experiment_3',['Tool Solver Part of the KARMA Experiment',['../group__karmaToolFinder.html',1,'']]] +]; diff --git a/doxygen/doc/html/search/close.png b/doxygen/doc/html/search/close.png new file mode 100644 index 0000000000000000000000000000000000000000..9342d3dfeea7b7c4ee610987e717804b5a42ceb9 GIT binary patch literal 273 zcmV+s0q*{ZP)4(RlMby96)VwnbG{ zbe&}^BDn7x>$<{ck4zAK-=nT;=hHG)kmplIF${xqm8db3oX6wT3bvp`TE@m0cg;b) zBuSL}5?N7O(iZLdAlz@)b)Rd~DnSsSX&P5qC`XwuFwcAYLC+d2>+1(8on;wpt8QIC X2MT$R4iQDd00000NkvXXu0mjfia~GN literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/search/close.svg b/doxygen/doc/html/search/close.svg new file mode 100644 index 0000000..a933eea --- /dev/null +++ b/doxygen/doc/html/search/close.svg @@ -0,0 +1,31 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/doxygen/doc/html/search/groups_0.html b/doxygen/doc/html/search/groups_0.html new file mode 100644 index 0000000..c600b49 --- /dev/null +++ b/doxygen/doc/html/search/groups_0.html @@ -0,0 +1,37 @@ + + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/doxygen/doc/html/search/groups_0.js b/doxygen/doc/html/search/groups_0.js new file mode 100644 index 0000000..a860283 --- /dev/null +++ b/doxygen/doc/html/search/groups_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['learning_20module_20of_20the_20karma_20experiment_4',['Learning module of the KARMA Experiment',['../group__karmaLearn.html',1,'']]] +]; diff --git a/doxygen/doc/html/search/groups_1.html b/doxygen/doc/html/search/groups_1.html new file mode 100644 index 0000000..2eb3550 --- /dev/null +++ b/doxygen/doc/html/search/groups_1.html @@ -0,0 +1,37 @@ + + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/doxygen/doc/html/search/groups_1.js b/doxygen/doc/html/search/groups_1.js new file mode 100644 index 0000000..a32af20 --- /dev/null +++ b/doxygen/doc/html/search/groups_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['motor_20part_20of_20the_20karma_20experiment_5',['Motor Part of the KARMA Experiment',['../group__karmaMotor.html',1,'']]] +]; diff --git a/doxygen/doc/html/search/groups_2.html b/doxygen/doc/html/search/groups_2.html new file mode 100644 index 0000000..12f4af7 --- /dev/null +++ b/doxygen/doc/html/search/groups_2.html @@ -0,0 +1,37 @@ + + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/doxygen/doc/html/search/groups_2.js b/doxygen/doc/html/search/groups_2.js new file mode 100644 index 0000000..6c3fe81 --- /dev/null +++ b/doxygen/doc/html/search/groups_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['tool_20projection_20part_20of_20the_20karma_20experiment_6',['Tool Projection Part of the KARMA Experiment',['../group__karmaToolProjection.html',1,'']]], + ['tool_20solver_20part_20of_20the_20karma_20experiment_7',['Tool Solver Part of the KARMA Experiment',['../group__karmaToolFinder.html',1,'']]] +]; diff --git a/doxygen/doc/html/search/mag_sel.png b/doxygen/doc/html/search/mag_sel.png new file mode 100644 index 0000000000000000000000000000000000000000..39c0ed52a25dd9d080ee0d42ae6c6042bdfa04d7 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz6!2%?$TA$hhDVB6cUq=Rpjs4tz5?O(Kg=CK) zUj~NU84L`?eGCi_EEpJ?t}-xGu`@87+QPtK?83kxQ`TapwHK(CDaqU2h2ejD|C#+j z9%q3^WHAE+w=f7ZGR&GI0Tg5}@$_|Nf5gMiEhFgvHvB$N=!mC_V~EE2vzPXI9ZnEo zd+1zHor@dYLod2Y{ z@R$7$Z!PXTbY$|@#T!bMzm?`b<(R`cbw(gxJHzu zB$lLFB^RXvDF!10LknF)BV7aY5JN*NBMU1-b8Q0yD+2>vd*|CI8glbfGSez?Ylunu RoetE%;OXk;vd$@?2>>CYplSdB literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/search/mag_sel.svg b/doxygen/doc/html/search/mag_sel.svg new file mode 100644 index 0000000..03626f6 --- /dev/null +++ b/doxygen/doc/html/search/mag_sel.svg @@ -0,0 +1,74 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/doxygen/doc/html/search/nomatches.html b/doxygen/doc/html/search/nomatches.html new file mode 100644 index 0000000..2b9360b --- /dev/null +++ b/doxygen/doc/html/search/nomatches.html @@ -0,0 +1,13 @@ + + + + + + + + +
    +
    No Matches
    +
    + + diff --git a/doxygen/doc/html/search/search.css b/doxygen/doc/html/search/search.css new file mode 100644 index 0000000..9074198 --- /dev/null +++ b/doxygen/doc/html/search/search.css @@ -0,0 +1,257 @@ +/*---------------- Search Box */ + +#MSearchBox { + white-space : nowrap; + background: white; + border-radius: 0.65em; + box-shadow: inset 0.5px 0.5px 3px 0px #555; + z-index: 102; +} + +#MSearchBox .left { + display: inline-block; + vertical-align: middle; + height: 1.4em; +} + +#MSearchSelect { + display: inline-block; + vertical-align: middle; + height: 1.4em; + padding: 0 0 0 0.3em; + margin: 0; +} + +#MSearchField { + display: inline-block; + vertical-align: middle; + width: 7.5em; + height: 1.1em; + margin: 0 0.15em; + padding: 0; + line-height: 1em; + border:none; + color: #909090; + outline: none; + font-family: Arial, Verdana, sans-serif; + -webkit-border-radius: 0px; + border-radius: 0px; + background: none; +} + + +#MSearchBox .right { + display: inline-block; + vertical-align: middle; + width: 1.4em; + height: 1.4em; +} + +#MSearchClose { + display: none; + font-size: inherit; + background : none; + border: none; + margin: 0; + padding: 0; + outline: none; + +} + +#MSearchCloseImg { + height: 1.4em; + padding: 0.3em; + margin: 0; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +#main-menu > li:last-child { + /* This
  • object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; + z-index:10000; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; + font-family: Arial, Verdana, sans-serif; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; + font-family: Arial, Verdana, sans-serif; +} + +.SRResult { + display: none; +} + +div.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/doxygen/doc/html/search/search.js b/doxygen/doc/html/search/search.js new file mode 100644 index 0000000..fb226f7 --- /dev/null +++ b/doxygen/doc/html/search/search.js @@ -0,0 +1,816 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + 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 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. + + @licend The above is the entire license notice for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches' + this.extension; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline-block'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e(R!W8j_r#qQ#gnr4kAxdU#F0+OBry$Z+ z_0PMi;P|#{d%mw(dnw=jM%@$onTJa%@6Nm3`;2S#nwtVFJI#`U@2Q@@JCCctagvF- z8H=anvo~dTmJ2YA%wA6IHRv%{vxvUm|R)kgZeo zmX%Zb;mpflGZdXCTAgit`||AFzkI#z&(3d4(htA?U2FOL4WF6wY&TB#n3n*I4+hl| z*NBpo#FA92vEu822WQ%mvv4FO#qs` BFGc_W literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/search/search_r.png b/doxygen/doc/html/search/search_r.png new file mode 100644 index 0000000000000000000000000000000000000000..1af5d21ee13e070d7600f1c4657fde843b953a69 GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9c!2%@BXHTsJQY`6?zK#qG8~eHcB(ehe3dtTp zz6=bxGZ+|(`xqD=STHa&U1eaXVrO7DwS|Gf*oA>XrmV$GYcEhOQT(QLuS{~ooZ2P@v=Xc@RKW@Irliv8_;wroU0*)0O?temdsA~70jrdux+`@W7 z-N(<(C)L?hOO?KV{>8(jC{hpKsws)#Fh zvsO>IB+gb@b+rGWaO&!a9Z{!U+fV*s7TS>fdt&j$L%^U@Epd$~Nl7e8wMs5Z1yT$~ z28I^8hDN#u<{^fLRz?<9hUVG^237_Jy7tbuQ8eV{r(~v8;?@w8^gA7>fx*+&&t;uc GLK6VEQpiUD literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/search/searchdata.js b/doxygen/doc/html/search/searchdata.js new file mode 100644 index 0000000..0299ee2 --- /dev/null +++ b/doxygen/doc/html/search/searchdata.js @@ -0,0 +1,18 @@ +var indexSectionsWithContent = +{ + 0: "lmt", + 1: "lmt" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "groups" +}; + +var indexSectionLabels = +{ + 0: "All", + 1: "Modules" +}; + diff --git a/doxygen/doc/html/splitbar.png b/doxygen/doc/html/splitbar.png new file mode 100644 index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc> z_*`QK&+BH@jWrYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|EEGLnJsniYK!2U1 Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/sync_off.png b/doxygen/doc/html/sync_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc GIT binary patch literal 853 zcmV-b1FHOqP)oT|#XixUYy%lpuf3i8{fX!o zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py; zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK& z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sTxLGlJY5nc&Re zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j* literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/sync_on.png b/doxygen/doc/html/sync_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76 GIT binary patch literal 845 zcmV-T1G4;yP)Y;xxyHF2B5Wzm| zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I_))aP?*T)ow&n59{}X4$3Goat zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F={P0Y^?$4t z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU# z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+ z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$Mj4Uq05 X8=0q~qBNan00000NkvXXu0mjfptF>5 literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/tab_a.png b/doxygen/doc/html/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247 GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD# z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4 literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/tab_b.png b/doxygen/doc/html/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^ literal 0 HcmV?d00001 diff --git a/doxygen/doc/html/tabs.css b/doxygen/doc/html/tabs.css new file mode 100644 index 0000000..7d45d36 --- /dev/null +++ b/doxygen/doc/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} diff --git a/doxygen/doc/latex/Makefile b/doxygen/doc/latex/Makefile new file mode 100644 index 0000000..9d67151 --- /dev/null +++ b/doxygen/doc/latex/Makefile @@ -0,0 +1,43 @@ +LATEX_CMD=latex + +all: refman.dvi + +ps: refman.ps + +pdf: refman.pdf + +ps_2on1: refman_2on1.ps + +pdf_2on1: refman_2on1.pdf + +refman.ps: refman.dvi + dvips -o refman.ps refman.dvi + +refman.pdf: refman.ps + ps2pdf refman.ps refman.pdf + +refman.dvi: clean refman.tex doxygen.sty + echo "Running latex..." + $(LATEX_CMD) refman.tex + echo "Running makeindex..." + makeindex refman.idx + echo "Rerunning latex...." + $(LATEX_CMD) refman.tex + latex_count=8 ; \ + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\ + do \ + echo "Rerunning latex...." ;\ + $(LATEX_CMD) refman.tex ; \ + latex_count=`expr $$latex_count - 1` ;\ + done + makeindex refman.idx + $(LATEX_CMD) refman.tex + +refman_2on1.ps: refman.ps + psnup -2 refman.ps >refman_2on1.ps + +refman_2on1.pdf: refman_2on1.ps + ps2pdf refman_2on1.ps refman_2on1.pdf + +clean: + rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf diff --git a/doxygen/doc/latex/dir_0485f0c3e5fc27f1b21a0a793d715761.tex b/doxygen/doc/latex/dir_0485f0c3e5fc27f1b21a0a793d715761.tex new file mode 100644 index 0000000..e7dd39e --- /dev/null +++ b/doxygen/doc/latex/dir_0485f0c3e5fc27f1b21a0a793d715761.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/include/i\+Cub Directory Reference} +\label{dir_0485f0c3e5fc27f1b21a0a793d715761}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/include/i\+Cub Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/include/i\+Cub Directory Reference}} diff --git a/doxygen/doc/latex/dir_29c9db2f94dd348f3d685c9fccd668c5.tex b/doxygen/doc/latex/dir_29c9db2f94dd348f3d685c9fccd668c5.tex new file mode 100644 index 0000000..14b0227 --- /dev/null +++ b/doxygen/doc/latex/dir_29c9db2f94dd348f3d685c9fccd668c5.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Finder Directory Reference} +\label{dir_29c9db2f94dd348f3d685c9fccd668c5}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Finder Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Finder Directory Reference}} diff --git a/doxygen/doc/latex/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.tex b/doxygen/doc/latex/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.tex new file mode 100644 index 0000000..378a908 --- /dev/null +++ b/doxygen/doc/latex/dir_2c4c692e0e93e67fe6dacb9253ee9a1d.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/include/i\+Cub Directory Reference} +\label{dir_2c4c692e0e93e67fe6dacb9253ee9a1d}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/include/i\+Cub Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/include/i\+Cub Directory Reference}} diff --git a/doxygen/doc/latex/dir_41f00478989b00c299e09b5f630aa3f5.tex b/doxygen/doc/latex/dir_41f00478989b00c299e09b5f630aa3f5.tex new file mode 100644 index 0000000..be51b1b --- /dev/null +++ b/doxygen/doc/latex/dir_41f00478989b00c299e09b5f630aa3f5.tex @@ -0,0 +1,7 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection Directory Reference} +\label{dir_41f00478989b00c299e09b5f630aa3f5}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection Directory Reference}} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\item +directory \hyperlink{dir_fe78f95ef73225985cbb37ca6fe2b4d3}{include} +\end{DoxyCompactItemize} diff --git a/doxygen/doc/latex/dir_68267d1309a1af8e8297ef4c3efbcdba.tex b/doxygen/doc/latex/dir_68267d1309a1af8e8297ef4c3efbcdba.tex new file mode 100644 index 0000000..94b4506 --- /dev/null +++ b/doxygen/doc/latex/dir_68267d1309a1af8e8297ef4c3efbcdba.tex @@ -0,0 +1,9 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src Directory Reference} +\label{dir_68267d1309a1af8e8297ef4c3efbcdba}\index{/home/runner/work/karma/karma/gh-\/pages/src Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src Directory Reference}} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\item +directory \hyperlink{dir_d5fc9e74ecd446ba07279cb903928e76}{karma\+Manager} +\item +directory \hyperlink{dir_41f00478989b00c299e09b5f630aa3f5}{karma\+Tool\+Projection} +\end{DoxyCompactItemize} diff --git a/doxygen/doc/latex/dir_7487e53a8124ea55fc67b4fc4eb7b40c.tex b/doxygen/doc/latex/dir_7487e53a8124ea55fc67b4fc4eb7b40c.tex new file mode 100644 index 0000000..a1e328d --- /dev/null +++ b/doxygen/doc/latex/dir_7487e53a8124ea55fc67b4fc4eb7b40c.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/src Directory Reference} +\label{dir_7487e53a8124ea55fc67b4fc4eb7b40c}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/src Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/src Directory Reference}} diff --git a/doxygen/doc/latex/dir_a61e44ac46e7253a0943cfd762c184f9.tex b/doxygen/doc/latex/dir_a61e44ac46e7253a0943cfd762c184f9.tex new file mode 100644 index 0000000..0120059 --- /dev/null +++ b/doxygen/doc/latex/dir_a61e44ac46e7253a0943cfd762c184f9.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Motor Directory Reference} +\label{dir_a61e44ac46e7253a0943cfd762c184f9}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Motor Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Motor Directory Reference}} diff --git a/doxygen/doc/latex/dir_d5fc9e74ecd446ba07279cb903928e76.tex b/doxygen/doc/latex/dir_d5fc9e74ecd446ba07279cb903928e76.tex new file mode 100644 index 0000000..b797e78 --- /dev/null +++ b/doxygen/doc/latex/dir_d5fc9e74ecd446ba07279cb903928e76.tex @@ -0,0 +1,7 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager Directory Reference} +\label{dir_d5fc9e74ecd446ba07279cb903928e76}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager Directory Reference}} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\item +directory \hyperlink{dir_db5aab25642573dc60c61c7a424e232a}{include} +\end{DoxyCompactItemize} diff --git a/doxygen/doc/latex/dir_db5aab25642573dc60c61c7a424e232a.tex b/doxygen/doc/latex/dir_db5aab25642573dc60c61c7a424e232a.tex new file mode 100644 index 0000000..4efcef3 --- /dev/null +++ b/doxygen/doc/latex/dir_db5aab25642573dc60c61c7a424e232a.tex @@ -0,0 +1,5 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/include Directory Reference} +\label{dir_db5aab25642573dc60c61c7a424e232a}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/include Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Manager/include Directory Reference}} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\end{DoxyCompactItemize} diff --git a/doxygen/doc/latex/dir_f234616accb428072e31fe708f34c8ab.tex b/doxygen/doc/latex/dir_f234616accb428072e31fe708f34c8ab.tex new file mode 100644 index 0000000..c2382ec --- /dev/null +++ b/doxygen/doc/latex/dir_f234616accb428072e31fe708f34c8ab.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Learn Directory Reference} +\label{dir_f234616accb428072e31fe708f34c8ab}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Learn Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Learn Directory Reference}} diff --git a/doxygen/doc/latex/dir_fc03fb402f9f2a4202506acbbf0a4b9a.tex b/doxygen/doc/latex/dir_fc03fb402f9f2a4202506acbbf0a4b9a.tex new file mode 100644 index 0000000..424d9c7 --- /dev/null +++ b/doxygen/doc/latex/dir_fc03fb402f9f2a4202506acbbf0a4b9a.tex @@ -0,0 +1,2 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/src Directory Reference} +\label{dir_fc03fb402f9f2a4202506acbbf0a4b9a}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/src Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/src Directory Reference}} diff --git a/doxygen/doc/latex/dir_fe78f95ef73225985cbb37ca6fe2b4d3.tex b/doxygen/doc/latex/dir_fe78f95ef73225985cbb37ca6fe2b4d3.tex new file mode 100644 index 0000000..a650b05 --- /dev/null +++ b/doxygen/doc/latex/dir_fe78f95ef73225985cbb37ca6fe2b4d3.tex @@ -0,0 +1,5 @@ +\section{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/include Directory Reference} +\label{dir_fe78f95ef73225985cbb37ca6fe2b4d3}\index{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/include Directory Reference@{/home/runner/work/karma/karma/gh-\/pages/src/karma\+Tool\+Projection/include Directory Reference}} +\subsection*{Directories} +\begin{DoxyCompactItemize} +\end{DoxyCompactItemize} diff --git a/doxygen/doc/latex/doxygen.sty b/doxygen/doc/latex/doxygen.sty new file mode 100644 index 0000000..8f59bcc --- /dev/null +++ b/doxygen/doc/latex/doxygen.sty @@ -0,0 +1,576 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} + +% Packages used by this style file +\RequirePackage{alltt} +%%\RequirePackage{array} %% moved to refman.tex due to workaround for LaTex 2019 version and unmaintained tabu package +\RequirePackage{calc} +\RequirePackage{float} +%%\RequirePackage{ifthen} %% moved to refman.tex due to workaround for LaTex 2019 version and unmaintained tabu package +\RequirePackage{verbatim} +\RequirePackage[table]{xcolor} +\RequirePackage{longtable_doxygen} +\RequirePackage{tabu_doxygen} +\RequirePackage{fancyvrb} +\RequirePackage{tabularx} +\RequirePackage{multicol} +\RequirePackage{multirow} +\RequirePackage{hanging} +\RequirePackage{ifpdf} +\RequirePackage{adjustbox} +\RequirePackage{amssymb} +\RequirePackage{stackengine} +\RequirePackage[normalem]{ulem} % for strikeout, but don't modify emphasis + +%---------- Internal commands used in this style file ---------------- + +\newcommand{\ensurespace}[1]{% + \begingroup% + \setlength{\dimen@}{#1}% + \vskip\z@\@plus\dimen@% + \penalty -100\vskip\z@\@plus -\dimen@% + \vskip\dimen@% + \penalty 9999% + \vskip -\dimen@% + \vskip\z@skip% hide the previous |\vskip| from |\addvspace| + \endgroup% +} + +\newcommand{\DoxyHorRuler}[1]{% + \setlength{\parskip}{0ex plus 0ex minus 0ex}% + \ifthenelse{#1=0}% + {% + \hrule% + }% + {% + \hrulefilll% + }% +} +\newcommand{\DoxyLabelFont}{} +\newcommand{\entrylabel}[1]{% + {% + \parbox[b]{\labelwidth-4pt}{% + \makebox[0pt][l]{\DoxyLabelFont#1}% + \vspace{1.5\baselineskip}% + }% + }% +} + +\newenvironment{DoxyDesc}[1]{% + \ensurespace{4\baselineskip}% + \begin{list}{}{% + \settowidth{\labelwidth}{20pt}% + %\setlength{\parsep}{0pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% + \renewcommand{\makelabel}{\entrylabel}% + }% + \item[#1]% +}{% + \end{list}% +} + +\newsavebox{\xrefbox} +\newlength{\xreflength} +\newcommand{\xreflabel}[1]{% + \sbox{\xrefbox}{#1}% + \setlength{\xreflength}{\wd\xrefbox}% + \ifthenelse{\xreflength>\labelwidth}{% + \begin{minipage}{\textwidth}% + \setlength{\parindent}{0pt}% + \hangindent=15pt\bfseries #1\vspace{1.2\itemsep}% + \end{minipage}% + }{% + \parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}% + }% +} + +%---------- Commands used by doxygen LaTeX output generator ---------- + +% Used by
     ... 
    +\newenvironment{DoxyPre}{% + \small% + \begin{alltt}% +}{% + \end{alltt}% + \normalsize% +} +% Necessary for redefining not defined characters, i.e. "Replacement Character" in tex output. +\newlength{\CodeWidthChar} +\newlength{\CodeHeightChar} +\settowidth{\CodeWidthChar}{?} +\settoheight{\CodeHeightChar}{?} +% Necessary for hanging indent +\newlength{\DoxyCodeWidth} + +\newcommand\DoxyCodeLine[1]{\hangpara{\DoxyCodeWidth}{1}{#1}\par} + +\newcommand\NiceSpace{% + \discretionary{}{\kern\fontdimen2\font}{\kern\fontdimen2\font}% +} + +% Used by @code ... @endcode +\newenvironment{DoxyCode}[1]{% + \par% + \scriptsize% + \normalfont\ttfamily% + \rightskip0pt plus 1fil% + \settowidth{\DoxyCodeWidth}{000000}% + \settowidth{\CodeWidthChar}{?}% + \settoheight{\CodeHeightChar}{?}% + \setlength{\parskip}{0ex plus 0ex minus 0ex}% + \ifthenelse{\equal{#1}{0}} + { + {\lccode`~32 \lowercase{\global\let~}\NiceSpace}\obeyspaces% + } + { + {\lccode`~32 \lowercase{\global\let~}}\obeyspaces% + } + +}{% + \normalfont% + \normalsize% + \settowidth{\CodeWidthChar}{?}% + \settoheight{\CodeHeightChar}{?}% +} + +% Redefining not defined characters, i.e. "Replacement Character" in tex output. +\def\ucr{\adjustbox{width=\CodeWidthChar,height=\CodeHeightChar}{\stackinset{c}{}{c}{-.2pt}{% + \textcolor{white}{\sffamily\bfseries\small ?}}{% + \rotatebox{45}{$\blacksquare$}}}} + +% Used by @example, @include, @includelineno and @dontinclude +\newenvironment{DoxyCodeInclude}[1]{% + \DoxyCode{#1}% +}{% + \endDoxyCode% +} + +% Used by @verbatim ... @endverbatim +\newenvironment{DoxyVerb}{% + \footnotesize% + \verbatim% +}{% + \endverbatim% + \normalsize% +} + +% Used by @verbinclude +\newenvironment{DoxyVerbInclude}{% + \DoxyVerb% +}{% + \endDoxyVerb% +} + +% Used by numbered lists (using '-#' or
      ...
    ) +\newenvironment{DoxyEnumerate}{% + \enumerate% +}{% + \endenumerate% +} + +% Used by bullet lists (using '-', @li, @arg, or
      ...
    ) +\newenvironment{DoxyItemize}{% + \itemize% +}{% + \enditemize% +} + +% Used by description lists (using
    ...
    ) +\newenvironment{DoxyDescription}{% + \description% +}{% + \enddescription% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if caption is specified) +\newenvironment{DoxyImage}{% + \begin{figure}[H]% + \centering% +}{% + \end{figure}% +} + +% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc +% (only if no caption is specified) +\newenvironment{DoxyImageNoCaption}{% + \begin{center}% +}{% + \end{center}% +} + +% Used by @image +% (only if inline is specified) +\newenvironment{DoxyInlineImage}{% +}{% +} + +% Used by @attention +\newenvironment{DoxyAttention}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @author and @authors +\newenvironment{DoxyAuthor}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @date +\newenvironment{DoxyDate}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @invariant +\newenvironment{DoxyInvariant}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @note +\newenvironment{DoxyNote}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @post +\newenvironment{DoxyPostcond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @pre +\newenvironment{DoxyPrecond}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @copyright +\newenvironment{DoxyCopyright}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @remark +\newenvironment{DoxyRemark}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @return and @returns +\newenvironment{DoxyReturn}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @since +\newenvironment{DoxySince}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @see +\newenvironment{DoxySeeAlso}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @version +\newenvironment{DoxyVersion}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @warning +\newenvironment{DoxyWarning}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by @internal +\newenvironment{DoxyInternal}[1]{% + \paragraph*{#1}% +}{% +} + +% Used by @par and @paragraph +\newenvironment{DoxyParagraph}[1]{% + \begin{DoxyDesc}{#1}% +}{% + \end{DoxyDesc}% +} + +% Used by parameter lists +\newenvironment{DoxyParams}[2][]{% + \tabulinesep=1mm% + \par% + \ifthenelse{\equal{#1}{}}% + {\begin{longtabu*}spread 0pt [l]{|X[-1,l]|X[-1,l]|}}% name + description + {\ifthenelse{\equal{#1}{1}}% + {\begin{longtabu*}spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + name + desc + {\begin{longtabu*}spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + type + name + desc + } + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for fields of simple structs +\newenvironment{DoxyFields}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|X[-1,l]|}% + \multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for fields simple class style enums +\newenvironment{DoxyEnumFields}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for parameters within a detailed function description +\newenvironment{DoxyParamCaption}{% + \renewcommand{\item}[2][]{\\ \hspace*{2.0cm} ##1 {\em ##2}}% +}{% +} + +% Used by return value lists +\newenvironment{DoxyRetVals}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used by exception lists +\newenvironment{DoxyExceptions}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used by template parameter lists +\newenvironment{DoxyTemplParams}[1]{% + \tabulinesep=1mm% + \par% + \begin{longtabu*}spread 0pt [l]{|X[-1,r]|X[-1,l]|}% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endfirsthead% + \multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]% + \hline% + \endhead% +}{% + \end{longtabu*}% + \vspace{6pt}% +} + +% Used for member lists +\newenvironment{DoxyCompactItemize}{% + \begin{itemize}% + \setlength{\itemsep}{-3pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \setlength{\partopsep}{0pt}% +}{% + \end{itemize}% +} + +% Used for member descriptions +\newenvironment{DoxyCompactList}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + \setlength{\itemsep}{0pt}% + \setlength{\parsep}{0pt}% + \setlength{\topsep}{0pt}% + \renewcommand{\makelabel}{\hfill}% + }% +}{% + \end{list}% +} + +% Used for reference lists (@bug, @deprecated, @todo, etc.) +\newenvironment{DoxyRefList}{% + \begin{list}{}{% + \setlength{\labelwidth}{10pt}% + \setlength{\leftmargin}{\labelwidth}% + \addtolength{\leftmargin}{\labelsep}% + \renewcommand{\makelabel}{\xreflabel}% + }% +}{% + \end{list}% +} + +% Used by @bug, @deprecated, @todo, etc. +\newenvironment{DoxyRefDesc}[1]{% + \begin{list}{}{% + \renewcommand\makelabel[1]{\textbf{##1}}% + \settowidth\labelwidth{\makelabel{#1}}% + \setlength\leftmargin{\labelwidth+\labelsep}% + }% +}{% + \end{list}% +} + +% Used by parameter lists and simple sections +\newenvironment{Desc} +{\begin{list}{}{% + \settowidth{\labelwidth}{20pt}% + \setlength{\parsep}{0pt}% + \setlength{\itemsep}{0pt}% + \setlength{\leftmargin}{\labelwidth+\labelsep}% + \renewcommand{\makelabel}{\entrylabel}% + } +}{% + \end{list}% +} + +% Used by tables +\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}% +\newenvironment{TabularC}[1]% +{\tabulinesep=1mm +\begin{longtabu*}spread 0pt [c]{*#1{|X[-1]}|}}% +{\end{longtabu*}\par}% + +\newenvironment{TabularNC}[1]% +{\begin{tabu}spread 0pt [l]{*#1{|X[-1]}|}}% +{\end{tabu}\par}% + +% Used for member group headers +\newenvironment{Indent}{% + \begin{list}{}{% + \setlength{\leftmargin}{0.5cm}% + }% + \item[]\ignorespaces% +}{% + \unskip% + \end{list}% +} + +% Used when hyperlinks are turned off +\newcommand{\doxyref}[3]{% + \textbf{#1} (\textnormal{#2}\,\pageref{#3})% +} + +% Used to link to a table when hyperlinks are turned on +\newcommand{\doxytablelink}[2]{% + \ref{#1}% +} + +% Used to link to a table when hyperlinks are turned off +\newcommand{\doxytableref}[3]{% + \ref{#3}% +} + +% Used by @addindex +\newcommand{\lcurly}{\{} +\newcommand{\rcurly}{\}} + +% Colors used for syntax highlighting +\definecolor{comment}{rgb}{0.5,0.0,0.0} +\definecolor{keyword}{rgb}{0.0,0.5,0.0} +\definecolor{keywordtype}{rgb}{0.38,0.25,0.125} +\definecolor{keywordflow}{rgb}{0.88,0.5,0.0} +\definecolor{preprocessor}{rgb}{0.5,0.38,0.125} +\definecolor{stringliteral}{rgb}{0.0,0.125,0.25} +\definecolor{charliteral}{rgb}{0.0,0.5,0.5} +\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0} +\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43} +\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0} +\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0} + +% Color used for table heading +\newcommand{\tableheadbgcolor}{lightgray}% + +% Version of hypertarget with correct landing location +\newcommand{\Hypertarget}[1]{\Hy@raisedlink{\hypertarget{#1}{}}} + +% possibility to have sections etc. be within the margins +% unfortunately had to copy part of book.cls and add \raggedright +\makeatletter +\newcommand\doxysection{\@startsection {section}{1}{\z@}% + {-3.5ex \@plus -1ex \@minus -.2ex}% + {2.3ex \@plus.2ex}% + {\raggedright\normalfont\Large\bfseries}} +\newcommand\doxysubsection{\@startsection{subsection}{2}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\raggedright\normalfont\large\bfseries}} +\newcommand\doxysubsubsection{\@startsection{subsubsection}{3}{\z@}% + {-3.25ex\@plus -1ex \@minus -.2ex}% + {1.5ex \@plus .2ex}% + {\raggedright\normalfont\normalsize\bfseries}} +\newcommand\doxyparagraph{\@startsection{paragraph}{4}{\z@}% + {3.25ex \@plus1ex \@minus.2ex}% + {-1em}% + {\raggedright\normalfont\normalsize\bfseries}} +\newcommand\doxysubparagraph{\@startsection{subparagraph}{5}{\parindent}% + {3.25ex \@plus1ex \@minus .2ex}% + {-1em}% + {\raggedright\normalfont\normalsize\bfseries}} +\makeatother +% Define caption that is also suitable in a table +\makeatletter +\def\doxyfigcaption{% +\H@refstepcounter{figure}% +\@dblarg{\@caption{figure}}} +\makeatother diff --git a/doxygen/doc/latex/group__karmaLearn.tex b/doxygen/doc/latex/group__karmaLearn.tex new file mode 100644 index 0000000..8d18551 --- /dev/null +++ b/doxygen/doc/latex/group__karmaLearn.tex @@ -0,0 +1,64 @@ +\doxysection{Learning module of the KARMA Experiment} +\label{group__karmaLearn}\index{Learning module of the KARMA Experiment@{Learning module of the KARMA Experiment}} + + +Machine Learning Module that allows the robot to learn online and predict a one-\/to-\/one map. + + +Machine Learning Module that allows the robot to learn online and predict a one-\/to-\/one map. + +\hypertarget{group__karmaToolProjection_intro_sec}{}\doxysubsection{Description}\label{group__karmaToolProjection_intro_sec} +This module belongs to the suite of KARMA software and is responsible for learning a generic map from $ R $ to $ R $.\hypertarget{group__karmaToolProjection_lib_sec}{}\doxysubsection{Libraries}\label{group__karmaToolProjection_lib_sec} + +\begin{DoxyItemize} +\item YARP libraries. +\item learning\+Machine library. +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_parameters_sec}{}\doxysubsection{Parameters}\label{group__karmaToolProjection_parameters_sec} +--context {\itshape context} +\begin{DoxyItemize} +\item To specify the module\textquotesingle{}s context. +\end{DoxyItemize} + +--from {\itshape file} +\begin{DoxyItemize} +\item To specify the module\textquotesingle{}s configuration file. +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_portsc_sec}{}\doxysubsection{Ports Created}\label{group__karmaToolProjection_portsc_sec} + +\begin{DoxyItemize} +\item {\itshape /karma\+Learn/rpc} remote procedure call. ~\newline + Recognized remote commands\+: +\begin{DoxyItemize} +\item \mbox{[}train\mbox{]} \char`\"{}item\char`\"{} $<$in$>$ $<$out$>$\+: issue the module to train internal machines with the input-\/output pair for the given item. The reply is \mbox{[}nack\mbox{]}/\mbox{[}ack\mbox{]}. +\item \mbox{[}predict\mbox{]} \char`\"{}item\char`\"{} $<$in$>$\+: retrieve the predicted output for the specified input. The reply is \mbox{[}nack\mbox{]}/\mbox{[}ack\mbox{]} $<$out$>$ $<$variance$>$, where the variance is meaningful only if not negative. In case the input command is of the form \mbox{[}predict\mbox{]} \char`\"{}item\char`\"{} ($<$in0$>$ $<$in1$>$ ...), the prediction is returned for the values contained in the list and the reply will look like \href{out0> ...}{\texttt{ ack}} ($<$variance0$>$ $<$variance1$>$ ...). +\item \mbox{[}span\mbox{]} \char`\"{}item\char`\"{} $<$step$>$\+: retrieve the predicted output for a given range of input specified by the parameter step. The reply is \mbox{[}nack\mbox{]}/\href{out0> ...}{\texttt{ ack}} ($<$variance0$>$ $<$variance1$>$ ...). The second parameter can be omitted and an internal default step size is used. +\item \mbox{[}optimize\mbox{]} \char`\"{}item\char`\"{} \mbox{[}$<$step$>$\mbox{]}$\vert$\mbox{[}($<$val0$>$ $<$val1$>$ ...)\mbox{]}\+: for the specified item a search with the given step, or alternatively over the given list of input values, is performed in order to find out the input that elicits the maximum output. The reply is \mbox{[}nack\mbox{]}/\mbox{[}ack\mbox{]} $<$in$>$ $<$out$>$. The second parameter can be omitted and an internal default step size is used. +\item \mbox{[}items\mbox{]}\+: retrieve the name of the items currently handled by the module. +\item \mbox{[}machine\mbox{]} \char`\"{}item\char`\"{}\+: retrieve the content of the machine contained within the database that serves to represent the input-\/output relation of the given item. +\item \mbox{[}clear\mbox{]} \char`\"{}item\char`\"{}\+: remove the item from the internal machines database. If no argument is given, clean up the whole database content. The reply is \mbox{[}nack\mbox{]}/\mbox{[}ack\mbox{]}. +\item \mbox{[}save\mbox{]}\+: save the content of the internal machines database within the configuration file. The reply is \mbox{[}ack\mbox{]}. +\item \mbox{[}plot\mbox{]} \char`\"{}item\char`\"{} $<$step$>$\+: stream out a yarp image displaying the map learned for the specified item as computed over the domain explored with the given step. +\end{DoxyItemize} +\end{DoxyItemize} + +{\itshape /karma\+Learn/plot}\+:o streams out images containing the learned maps.\hypertarget{group__karmaLearn_conf_file_sec}{}\doxysubsection{Configuration Files}\label{group__karmaLearn_conf_file_sec} +The configuration file passed through the option {\itshape --from} looks like as follows\+: + + +\begin{DoxyCode}{0} +\DoxyCodeLine{[general]} +\DoxyCodeLine{name karmaLearn \textcolor{comment}{// the module's stem-\/name}} +\DoxyCodeLine{num\_items 0 \textcolor{comment}{// the number of items }} +\DoxyCodeLine{in\_lb 0.0 \textcolor{comment}{// scaler lower bound in}} +\DoxyCodeLine{in\_ub 360.0 \textcolor{comment}{// scaler upper bound in }} +\DoxyCodeLine{out\_lb 0.0 \textcolor{comment}{// scaler lower bound out}} +\DoxyCodeLine{out\_ub 2.0 \textcolor{comment}{// scaler upper bound out}} + +\end{DoxyCode} + + +Moreover, once some learning has been carried out, the configuration file will be filled with the sections corresponding to the items.\hypertarget{group__karmaToolProjection_tested_os_sec}{}\doxysubsection{Tested OS}\label{group__karmaToolProjection_tested_os_sec} +Windows, Linux + +\begin{DoxyAuthor}{Author} +Ugo Pattacini +\end{DoxyAuthor} diff --git a/doxygen/doc/latex/group__karmaMotor.tex b/doxygen/doc/latex/group__karmaMotor.tex new file mode 100644 index 0000000..7614fb3 --- /dev/null +++ b/doxygen/doc/latex/group__karmaMotor.tex @@ -0,0 +1,62 @@ +\doxysection{Motor Part of the KARMA Experiment} +\label{group__karmaMotor}\index{Motor Part of the KARMA Experiment@{Motor Part of the KARMA Experiment}} + + +Motor Control Module that allows the robot to push/draw the object and explore a tool. + + +Motor Control Module that allows the robot to push/draw the object and explore a tool. + +\hypertarget{group__karmaToolProjection_intro_sec}{}\doxysubsection{Description}\label{group__karmaToolProjection_intro_sec} +This module aims to control the robot hands in order to properly execute the push and the draw actions of an object within the KARMA experiment to then learn the corresponding affordance. ~\newline + It also enable the tool exploration.\hypertarget{group__karmaToolProjection_lib_sec}{}\doxysubsection{Libraries}\label{group__karmaToolProjection_lib_sec} + +\begin{DoxyItemize} +\item YARP libraries. +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_parameters_sec}{}\doxysubsection{Parameters}\label{group__karmaToolProjection_parameters_sec} +--robot {\itshape robot} +\begin{DoxyItemize} +\item Select the robot to connect to. +\end{DoxyItemize} + +--name {\itshape name} +\begin{DoxyItemize} +\item Select the stem-\/name of the module used to open up ports. By default {\itshape name} is {\itshape karma\+Motor}. +\end{DoxyItemize} + +--elbow\+\_\+set {\itshape ($<$height$>$ $<$weight$>$)} +\begin{DoxyItemize} +\item To specify how to weigh the task to keep the elbow high. +\end{DoxyItemize}\hypertarget{group__karmaToolFinder_portsa_sec}{}\doxysubsection{Ports Accessed}\label{group__karmaToolFinder_portsa_sec} +Assume that i\+Cub\+Interface (with ICartesian\+Control interface implemented) is running.\hypertarget{group__karmaToolProjection_portsc_sec}{}\doxysubsection{Ports Created}\label{group__karmaToolProjection_portsc_sec} + +\begin{DoxyItemize} +\item {\itshape /karma\+Motor/rpc} receives the information to execute the motor action as a Bottle. It manages the following commands\+: +\begin{DoxyEnumerate} +\item {\bfseries{Push}}\+: {\itshape \mbox{[}push\mbox{]} cx cy cz theta radius}. ~\newline + The coordinates {\itshape (cx,cy,cz)} represent in meters the position of the object\textquotesingle{}s centroid to be pushed; {\itshape theta}, given in degrees, and {\itshape radius}, specified in meters, account for the point from which push the object, that is located onto the circle centered in {\itshape (cx,cy,cz)} and contained in the x-\/y plane. ~\newline + The reply {\itshape \mbox{[}ack\mbox{]}} is returned as soon as the push is accomplished. +\item {\bfseries{Draw}}\+: {\itshape \mbox{[}draw\mbox{]} cx cy cz theta radius dist}. ~\newline + The coordinates {\itshape (cx,cy,cz)} represent in meters the position of the object\textquotesingle{}s centroid to be drawn closer; {\itshape theta}, given in degrees, and {\itshape radius}, specified in meters, account for the point from which draw the object, that is located onto the circle centered in {\itshape (cx,cy,cz)} and contained in the x-\/y plane. The parameter {\itshape dist} specifies the length in meters of the draw action. ~\newline + The reply {\itshape \mbox{[}ack\mbox{]}} is returned as soon as the draw is accomplished. +\item {\bfseries{Virtual draw}}\+: {\itshape \mbox{[}vdraw\mbox{]} cx cy cz theta radius dist}. ~\newline + Simulate the draw without performing any movement in order to test the quality of the action. ~\newline + The reply {\itshape \mbox{[}ack\mbox{]} val} is returned at the end of the simulation, where {\itshape val} accounts for the quality of the action\+: the lower it is the better the action is. +\item {\bfseries{Tool-\/attach}}\+: {\itshape \mbox{[}tool\mbox{]} \mbox{[}attach\mbox{]} arm x y z}. ~\newline + Attach a tool to the given arm whose dimensions are specified in the frame attached to the hand. The subsequent action will make use of this tool. +\item {\bfseries{Tool-\/get}}\+: {\itshape \mbox{[}tool\mbox{]} \mbox{[}get\mbox{]}}. ~\newline + Retrieve tool information as {\itshape \mbox{[}ack\mbox{]} arm x y z}. +\item {\bfseries{Tool-\/remove}}\+: {\itshape \mbox{[}tool\mbox{]} \mbox{[}remove\mbox{]}}. ~\newline + Remove the attached tool. +\item {\bfseries{Find}}\+: {\itshape \mbox{[}find\mbox{]} arm eye}. ~\newline + An exploration is performed which aims at finding the tool dimension. It is possible to select the arm for executing the movement as well as the eye from which the motion is observed. The reply {\itshape \mbox{[}ack\mbox{]} x y z} returns the tool\textquotesingle{}s dimensions with respect to reference frame attached to the robot hand. +\end{DoxyEnumerate} +\item {\itshape /karma\+Motor/stop}\+:i receives request for immediate stop of any ongoing processing. +\item {\itshape /karma\+Motor/vision}\+:i receives the information about the pixel corresponding to the tool tip during the tool exploration phase. +\item {\itshape /karma\+Motor/finder}\+:rpc communicates with the module in charge of solving for the tool\textquotesingle{}s dimensions. +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_tested_os_sec}{}\doxysubsection{Tested OS}\label{group__karmaToolProjection_tested_os_sec} +Windows, Linux + +\begin{DoxyAuthor}{Author} +Ugo Pattacini +\end{DoxyAuthor} diff --git a/doxygen/doc/latex/group__karmaToolFinder.tex b/doxygen/doc/latex/group__karmaToolFinder.tex new file mode 100644 index 0000000..762bb8c --- /dev/null +++ b/doxygen/doc/latex/group__karmaToolFinder.tex @@ -0,0 +1,71 @@ +\doxysection{Tool Solver Part of the KARMA Experiment} +\label{group__karmaToolFinder}\index{Tool Solver Part of the KARMA Experiment@{Tool Solver Part of the KARMA Experiment}} + + +This module finds the tool dimension employing nonlinear optimization. + + +This module finds the tool dimension employing nonlinear optimization. + +\hypertarget{group__karmaToolProjection_intro_sec}{}\doxysubsection{Description}\label{group__karmaToolProjection_intro_sec} +Through an active exploration of the tool held in the robot hand a set of relevant data is collected, including hand position in 3D space, eye\textquotesingle{}s frame and pixels of the tool tip as acquired by vision algorithms. A nonlinear optimization is then exploited to find out the best estimate of the tool dimensions with respect to the hand reference frame.\hypertarget{group__karmaToolProjection_lib_sec}{}\doxysubsection{Libraries}\label{group__karmaToolProjection_lib_sec} + +\begin{DoxyItemize} +\item YARP libraries. +\item IPOPT library. +\item Open\+CV library. ~\newline + +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_parameters_sec}{}\doxysubsection{Parameters}\label{group__karmaToolProjection_parameters_sec} +--robot {\itshape robot} +\begin{DoxyItemize} +\item Select the robot to connect to. +\end{DoxyItemize} + +--name {\itshape name} +\begin{DoxyItemize} +\item Select the stem-\/name of the module used to open up ports. By default {\itshape name} is {\itshape karma\+Tool\+Finder}. +\end{DoxyItemize} + +--arm {\itshape type} +\begin{DoxyItemize} +\item Select the default arm (\char`\"{}left\char`\"{} or \char`\"{}right\char`\"{}) used for the data acquisition. +\end{DoxyItemize} + +--eye {\itshape type} +\begin{DoxyItemize} +\item Select the default eye (\char`\"{}left\char`\"{} or \char`\"{}right\char`\"{}) used for the data acquisition. +\end{DoxyItemize}\hypertarget{group__karmaToolFinder_portsa_sec}{}\doxysubsection{Ports Accessed}\label{group__karmaToolFinder_portsa_sec} +Assume that i\+Cub\+Interface (with ICartesian\+Control interface implemented) is running.\hypertarget{group__karmaToolProjection_portsc_sec}{}\doxysubsection{Ports Created}\label{group__karmaToolProjection_portsc_sec} + +\begin{DoxyItemize} +\item {\itshape /karma\+Tool\+Finder/rpc} receives the information to manage the data acquisition and optimization phase\+: +\begin{DoxyEnumerate} +\item {\bfseries{Enable}}\+: {\itshape \mbox{[}enable\mbox{]}}. ~\newline + Start the data acquisition phase. +\item {\bfseries{Disable}}\+: {\itshape \mbox{[}disable\mbox{]}}. ~\newline + Terminate the data acquisition phase. +\item {\bfseries{Num}}\+: {\itshape \mbox{[}num\mbox{]}}. ~\newline + Retrieve the current number of input-\/output pairs used for the optimization. The reply is {\itshape \mbox{[}ack\mbox{]} num}. +\item {\bfseries{Clear}}\+: {\itshape \mbox{[}clear\mbox{]}}. ~\newline + Clear the current content of input-\/output pairs database. +\item {\bfseries{Select}}\+: {\itshape \mbox{[}select\mbox{]} arm eye}. ~\newline + Select the robot sources in terms of arm and eye used during the data acquisition. +\item {\bfseries{Find}}\+: {\itshape \mbox{[}find\mbox{]}}. ~\newline + Execute the optimization over the current database of input-\/output pairs. The reply is {\itshape \mbox{[}ack\mbox{]} x y z} including the tool dimensions given wrt hand reference frame. +\item {\bfseries{Show}}\+: {\itshape \mbox{[}show\mbox{]} x y z}. ~\newline + Enable the visualization of a tool with the dimensions specified by the user. The reply is {\itshape \mbox{[}ack\mbox{]}} or {\itshape \mbox{[}nack\mbox{]}}. +\item {\bfseries{Tip}}\+: {\itshape \mbox{[}tip\mbox{]}}. ~\newline + Retrieve the tool tip as projected in the image plane. The reply is {\itshape \mbox{[}ack\mbox{]} u v} or {\itshape \mbox{[}nack\mbox{]}}. +\end{DoxyEnumerate} +\item {\itshape /karma\+Tool\+Finder/in} receives the position of the tool tip in the image plane. +\begin{DoxyItemize} +\item {\itshape /karma\+Tool\+Finder/img}\+:i receives images from the camera. +\item {\itshape /karma\+Tool\+Finder/img}\+:o streams out images with superimposed information on the tool. +\item {\itshape /karma\+Tool\+Finder/log}\+:o streams out a complete set of data used during the acquisition. +\end{DoxyItemize} +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_tested_os_sec}{}\doxysubsection{Tested OS}\label{group__karmaToolProjection_tested_os_sec} +Windows, Linux + +\begin{DoxyAuthor}{Author} +Ugo Pattacini +\end{DoxyAuthor} diff --git a/doxygen/doc/latex/group__karmaToolProjection.tex b/doxygen/doc/latex/group__karmaToolProjection.tex new file mode 100644 index 0000000..8b34a5f --- /dev/null +++ b/doxygen/doc/latex/group__karmaToolProjection.tex @@ -0,0 +1,29 @@ +\doxysection{Tool Projection Part of the KARMA Experiment} +\label{group__karmaToolProjection}\index{Tool Projection Part of the KARMA Experiment@{Tool Projection Part of the KARMA Experiment}} + + +This module finds the tooltip using motion\+CUT. + + +This module finds the tooltip using motion\+CUT. + +\hypertarget{group__karmaToolProjection_intro_sec}{}\doxysubsection{Description}\label{group__karmaToolProjection_intro_sec} +Through an active exploration of the tool held in the robot hand this module extract a set of points for the tooltip location in the image.\hypertarget{group__karmaToolProjection_lib_sec}{}\doxysubsection{Libraries}\label{group__karmaToolProjection_lib_sec} + +\begin{DoxyItemize} +\item YARP libraries. +\item Open\+CV library. +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_parameters_sec}{}\doxysubsection{Parameters}\label{group__karmaToolProjection_parameters_sec} +none\hypertarget{group__karmaToolProjection_portsc_sec}{}\doxysubsection{Ports Created}\label{group__karmaToolProjection_portsc_sec} + +\begin{DoxyItemize} +\item {\itshape /karma\+Tool\+Finder/rpc} not responding to anything. +\item {\itshape /karma\+Tool\+Projection/motion\+Filter}\+:i receives the data blobs from the motion\+CUT module +\item {\itshape /karma\+Tool\+Projection/target}\+:o streams the X and Y target points of the tooltip +\item {\itshape /karma\+Tool\+Projection/img}\+:o streams the image with the image analysis +\end{DoxyItemize}\hypertarget{group__karmaToolProjection_tested_os_sec}{}\doxysubsection{Tested OS}\label{group__karmaToolProjection_tested_os_sec} +Windows, Linux, Mac\+OS + +\begin{DoxyAuthor}{Author} +Vadim Tikhanoff +\end{DoxyAuthor} diff --git a/doxygen/doc/latex/longtable_doxygen.sty b/doxygen/doc/latex/longtable_doxygen.sty new file mode 100644 index 0000000..a0eb314 --- /dev/null +++ b/doxygen/doc/latex/longtable_doxygen.sty @@ -0,0 +1,448 @@ +%% +%% This is file `longtable.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% longtable.dtx (with options: `package') +%% +%% This is a generated file. +%% +%% The source is maintained by the LaTeX Project team and bug +%% reports for it can be opened at http://latex-project.org/bugs.html +%% (but please observe conditions on bug reports sent to that address!) +%% +%% Copyright 1993-2016 +%% The LaTeX3 Project and any individual authors listed elsewhere +%% in this file. +%% +%% This file was generated from file(s) of the Standard LaTeX `Tools Bundle'. +%% -------------------------------------------------------------------------- +%% +%% It may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3c +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This file may only be distributed together with a copy of the LaTeX +%% `Tools Bundle'. You may however distribute the LaTeX `Tools Bundle' +%% without such generated files. +%% +%% The list of all files belonging to the LaTeX `Tools Bundle' is +%% given in the file `manifest.txt'. +%% +%% File: longtable.dtx Copyright (C) 1990-2001 David Carlisle +\NeedsTeXFormat{LaTeX2e}[1995/06/01] +\ProvidesPackage{longtable_doxygen} + [2014/10/28 v4.11 Multi-page Table package (DPC) - frozen version for doxygen] +\def\LT@err{\PackageError{longtable}} +\def\LT@warn{\PackageWarning{longtable}} +\def\LT@final@warn{% + \AtEndDocument{% + \LT@warn{Table \@width s have changed. Rerun LaTeX.\@gobbletwo}}% + \global\let\LT@final@warn\relax} +\DeclareOption{errorshow}{% + \def\LT@warn{\PackageInfo{longtable}}} +\DeclareOption{pausing}{% + \def\LT@warn#1{% + \LT@err{#1}{This is not really an error}}} +\DeclareOption{set}{} +\DeclareOption{final}{} +\ProcessOptions +\newskip\LTleft \LTleft=\fill +\newskip\LTright \LTright=\fill +\newskip\LTpre \LTpre=\bigskipamount +\newskip\LTpost \LTpost=\bigskipamount +\newcount\LTchunksize \LTchunksize=20 +\let\c@LTchunksize\LTchunksize +\newdimen\LTcapwidth \LTcapwidth=4in +\newbox\LT@head +\newbox\LT@firsthead +\newbox\LT@foot +\newbox\LT@lastfoot +\newcount\LT@cols +\newcount\LT@rows +\newcounter{LT@tables} +\newcounter{LT@chunks}[LT@tables] +\ifx\c@table\undefined + \newcounter{table} + \def\fnum@table{\tablename~\thetable} +\fi +\ifx\tablename\undefined + \def\tablename{Table} +\fi +\newtoks\LT@p@ftn +\mathchardef\LT@end@pen=30000 +\def\longtable{% + \par + \ifx\multicols\@undefined + \else + \ifnum\col@number>\@ne + \@twocolumntrue + \fi + \fi + \if@twocolumn + \LT@err{longtable not in 1-column mode}\@ehc + \fi + \begingroup + \@ifnextchar[\LT@array{\LT@array[x]}} +\def\LT@array[#1]#2{% + \refstepcounter{table}\stepcounter{LT@tables}% + \if l#1% + \LTleft\z@ \LTright\fill + \else\if r#1% + \LTleft\fill \LTright\z@ + \else\if c#1% + \LTleft\fill \LTright\fill + \fi\fi\fi + \let\LT@mcol\multicolumn + \let\LT@@tabarray\@tabarray + \let\LT@@hl\hline + \def\@tabarray{% + \let\hline\LT@@hl + \LT@@tabarray}% + \let\\\LT@tabularcr\let\tabularnewline\\% + \def\newpage{\noalign{\break}}% + \def\pagebreak{\noalign{\ifnum`}=0\fi\@testopt{\LT@no@pgbk-}4}% + \def\nopagebreak{\noalign{\ifnum`}=0\fi\@testopt\LT@no@pgbk4}% + \let\hline\LT@hline \let\kill\LT@kill\let\caption\LT@caption + \@tempdima\ht\strutbox + \let\@endpbox\LT@endpbox + \ifx\extrarowheight\@undefined + \let\@acol\@tabacol + \let\@classz\@tabclassz \let\@classiv\@tabclassiv + \def\@startpbox{\vtop\LT@startpbox}% + \let\@@startpbox\@startpbox + \let\@@endpbox\@endpbox + \let\LT@LL@FM@cr\@tabularcr + \else + \advance\@tempdima\extrarowheight + \col@sep\tabcolsep + \let\@startpbox\LT@startpbox\let\LT@LL@FM@cr\@arraycr + \fi + \setbox\@arstrutbox\hbox{\vrule + \@height \arraystretch \@tempdima + \@depth \arraystretch \dp \strutbox + \@width \z@}% + \let\@sharp##\let\protect\relax + \begingroup + \@mkpream{#2}% + \xdef\LT@bchunk{% + \global\advance\c@LT@chunks\@ne + \global\LT@rows\z@\setbox\z@\vbox\bgroup + \LT@setprevdepth + \tabskip\LTleft \noexpand\halign to\hsize\bgroup + \tabskip\z@ \@arstrut \@preamble \tabskip\LTright \cr}% + \endgroup + \expandafter\LT@nofcols\LT@bchunk&\LT@nofcols + \LT@make@row + \m@th\let\par\@empty + \everycr{}\lineskip\z@\baselineskip\z@ + \LT@bchunk} +\def\LT@no@pgbk#1[#2]{\penalty #1\@getpen{#2}\ifnum`{=0\fi}} +\def\LT@start{% + \let\LT@start\endgraf + \endgraf\penalty\z@\vskip\LTpre + \dimen@\pagetotal + \advance\dimen@ \ht\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi + \advance\dimen@ \dp\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi + \advance\dimen@ \ht\LT@foot + \dimen@ii\vfuzz + \vfuzz\maxdimen + \setbox\tw@\copy\z@ + \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox + \setbox\tw@\vbox{\unvbox\tw@}% + \vfuzz\dimen@ii + \advance\dimen@ \ht + \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi + \advance\dimen@\dp + \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi + \advance\dimen@ -\pagegoal + \ifdim \dimen@>\z@\vfil\break\fi + \global\@colroom\@colht + \ifvoid\LT@foot\else + \advance\vsize-\ht\LT@foot + \global\advance\@colroom-\ht\LT@foot + \dimen@\pagegoal\advance\dimen@-\ht\LT@foot\pagegoal\dimen@ + \maxdepth\z@ + \fi + \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak + \output{\LT@output}} +\def\endlongtable{% + \crcr + \noalign{% + \let\LT@entry\LT@entry@chop + \xdef\LT@save@row{\LT@save@row}}% + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \if@filesw + {\let\LT@entry\LT@entry@write\immediate\write\@auxout{% + \gdef\expandafter\noexpand + \csname LT@\romannumeral\c@LT@tables\endcsname + {\LT@save@row}}}% + \fi + \ifx\LT@save@row\LT@@save@row + \else + \LT@warn{Column \@width s have changed\MessageBreak + in table \thetable}% + \LT@final@warn + \fi + \endgraf\penalty -\LT@end@pen + \endgroup + \global\@mparbottom\z@ + \pagegoal\vsize + \endgraf\penalty\z@\addvspace\LTpost + \ifvoid\footins\else\insert\footins{}\fi} +\def\LT@nofcols#1&{% + \futurelet\@let@token\LT@n@fcols} +\def\LT@n@fcols{% + \advance\LT@cols\@ne + \ifx\@let@token\LT@nofcols + \expandafter\@gobble + \else + \expandafter\LT@nofcols + \fi} +\def\LT@tabularcr{% + \relax\iffalse{\fi\ifnum0=`}\fi + \@ifstar + {\def\crcr{\LT@crcr\noalign{\nobreak}}\let\cr\crcr + \LT@t@bularcr}% + {\LT@t@bularcr}} +\let\LT@crcr\crcr +\let\LT@setprevdepth\relax +\def\LT@t@bularcr{% + \global\advance\LT@rows\@ne + \ifnum\LT@rows=\LTchunksize + \gdef\LT@setprevdepth{% + \prevdepth\z@\global + \global\let\LT@setprevdepth\relax}% + \expandafter\LT@xtabularcr + \else + \ifnum0=`{}\fi + \expandafter\LT@LL@FM@cr + \fi} +\def\LT@xtabularcr{% + \@ifnextchar[\LT@argtabularcr\LT@ntabularcr} +\def\LT@ntabularcr{% + \ifnum0=`{}\fi + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \LT@bchunk} +\def\LT@argtabularcr[#1]{% + \ifnum0=`{}\fi + \ifdim #1>\z@ + \unskip\@xargarraycr{#1}% + \else + \@yargarraycr{#1}% + \fi + \LT@echunk + \LT@start + \unvbox\z@ + \LT@get@widths + \LT@bchunk} +\def\LT@echunk{% + \crcr\LT@save@row\cr\egroup + \global\setbox\@ne\lastbox + \unskip + \egroup} +\def\LT@entry#1#2{% + \ifhmode\@firstofone{&}\fi\omit + \ifnum#1=\c@LT@chunks + \else + \kern#2\relax + \fi} +\def\LT@entry@chop#1#2{% + \noexpand\LT@entry + {\ifnum#1>\c@LT@chunks + 1}{0pt% + \else + #1}{#2% + \fi}} +\def\LT@entry@write{% + \noexpand\LT@entry^^J% + \@spaces} +\def\LT@kill{% + \LT@echunk + \LT@get@widths + \expandafter\LT@rebox\LT@bchunk} +\def\LT@rebox#1\bgroup{% + #1\bgroup + \unvbox\z@ + \unskip + \setbox\z@\lastbox} +\def\LT@blank@row{% + \xdef\LT@save@row{\expandafter\LT@build@blank + \romannumeral\number\LT@cols 001 }} +\def\LT@build@blank#1{% + \if#1m% + \noexpand\LT@entry{1}{0pt}% + \expandafter\LT@build@blank + \fi} +\def\LT@make@row{% + \global\expandafter\let\expandafter\LT@save@row + \csname LT@\romannumeral\c@LT@tables\endcsname + \ifx\LT@save@row\relax + \LT@blank@row + \else + {\let\LT@entry\or + \if!% + \ifcase\expandafter\expandafter\expandafter\LT@cols + \expandafter\@gobble\LT@save@row + \or + \else + \relax + \fi + !% + \else + \aftergroup\LT@blank@row + \fi}% + \fi} +\let\setlongtables\relax +\def\LT@get@widths{% + \setbox\tw@\hbox{% + \unhbox\@ne + \let\LT@old@row\LT@save@row + \global\let\LT@save@row\@empty + \count@\LT@cols + \loop + \unskip + \setbox\tw@\lastbox + \ifhbox\tw@ + \LT@def@row + \advance\count@\m@ne + \repeat}% + \ifx\LT@@save@row\@undefined + \let\LT@@save@row\LT@save@row + \fi} +\def\LT@def@row{% + \let\LT@entry\or + \edef\@tempa{% + \ifcase\expandafter\count@\LT@old@row + \else + {1}{0pt}% + \fi}% + \let\LT@entry\relax + \xdef\LT@save@row{% + \LT@entry + \expandafter\LT@max@sel\@tempa + \LT@save@row}} +\def\LT@max@sel#1#2{% + {\ifdim#2=\wd\tw@ + #1% + \else + \number\c@LT@chunks + \fi}% + {\the\wd\tw@}} +\def\LT@hline{% + \noalign{\ifnum0=`}\fi + \penalty\@M + \futurelet\@let@token\LT@@hline} +\def\LT@@hline{% + \ifx\@let@token\hline + \global\let\@gtempa\@gobble + \gdef\LT@sep{\penalty-\@medpenalty\vskip\doublerulesep}% + \else + \global\let\@gtempa\@empty + \gdef\LT@sep{\penalty-\@lowpenalty\vskip-\arrayrulewidth}% + \fi + \ifnum0=`{\fi}% + \multispan\LT@cols + \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr + \noalign{\LT@sep}% + \multispan\LT@cols + \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr + \noalign{\penalty\@M}% + \@gtempa} +\def\LT@caption{% + \noalign\bgroup + \@ifnextchar[{\egroup\LT@c@ption\@firstofone}\LT@capti@n} +\def\LT@c@ption#1[#2]#3{% + \LT@makecaption#1\fnum@table{#3}% + \def\@tempa{#2}% + \ifx\@tempa\@empty\else + {\let\\\space + \addcontentsline{lot}{table}{\protect\numberline{\thetable}{#2}}}% + \fi} +\def\LT@capti@n{% + \@ifstar + {\egroup\LT@c@ption\@gobble[]}% + {\egroup\@xdblarg{\LT@c@ption\@firstofone}}} +\def\LT@makecaption#1#2#3{% + \LT@mcol\LT@cols c{\hbox to\z@{\hss\parbox[t]\LTcapwidth{% + \sbox\@tempboxa{#1{#2: }#3}% + \ifdim\wd\@tempboxa>\hsize + #1{#2: }#3% + \else + \hbox to\hsize{\hfil\box\@tempboxa\hfil}% + \fi + \endgraf\vskip\baselineskip}% + \hss}}} +\def\LT@output{% + \ifnum\outputpenalty <-\@Mi + \ifnum\outputpenalty > -\LT@end@pen + \LT@err{floats and marginpars not allowed in a longtable}\@ehc + \else + \setbox\z@\vbox{\unvbox\@cclv}% + \ifdim \ht\LT@lastfoot>\ht\LT@foot + \dimen@\pagegoal + \advance\dimen@-\ht\LT@lastfoot + \ifdim\dimen@<\ht\z@ + \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}% + \@makecol + \@outputpage + \setbox\z@\vbox{\box\LT@head}% + \fi + \fi + \global\@colroom\@colht + \global\vsize\@colht + \vbox + {\unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi}% + \fi + \else + \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% + \@makecol + \@outputpage + \global\vsize\@colroom + \copy\LT@head\nobreak + \fi} +\def\LT@end@hd@ft#1{% + \LT@echunk + \ifx\LT@start\endgraf + \LT@err + {Longtable head or foot not at start of table}% + {Increase LTchunksize}% + \fi + \setbox#1\box\z@ + \LT@get@widths + \LT@bchunk} +\def\endfirsthead{\LT@end@hd@ft\LT@firsthead} +\def\endhead{\LT@end@hd@ft\LT@head} +\def\endfoot{\LT@end@hd@ft\LT@foot} +\def\endlastfoot{\LT@end@hd@ft\LT@lastfoot} +\def\LT@startpbox#1{% + \bgroup + \let\@footnotetext\LT@p@ftntext + \setlength\hsize{#1}% + \@arrayparboxrestore + \vrule \@height \ht\@arstrutbox \@width \z@} +\def\LT@endpbox{% + \@finalstrut\@arstrutbox + \egroup + \the\LT@p@ftn + \global\LT@p@ftn{}% + \hfil} +\def\LT@p@ftntext#1{% + \edef\@tempa{\the\LT@p@ftn\noexpand\footnotetext[\the\c@footnote]}% + \global\LT@p@ftn\expandafter{\@tempa{#1}}}% + +\@namedef{ver@longtable.sty}{2014/10/28 v4.11 Multi-page Table package (DPC) - frozen version for doxygen} +\endinput +%% +%% End of file `longtable.sty'. diff --git a/doxygen/doc/latex/make.bat b/doxygen/doc/latex/make.bat new file mode 100644 index 0000000..e1e5546 --- /dev/null +++ b/doxygen/doc/latex/make.bat @@ -0,0 +1,28 @@ +set Dir_Old=%cd% +cd /D %~dp0 + +del /s /f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf + +set LATEX_CMD=latex +%LATEX_CMD% refman.tex +echo ---- +makeindex refman.idx +setlocal enabledelayedexpansion +set count=8 +:repeat +set content=X +for /F "tokens=*" %%T in ( 'findstr /C:"Rerun LaTeX" refman.log' ) do set content="%%~T" +if !content! == X for /F "tokens=*" %%T in ( 'findstr /C:"Rerun to get cross-references right" refman.log' ) do set content="%%~T" +if !content! == X goto :skip +set /a count-=1 +if !count! EQU 0 goto :skip + +echo ---- +%LATEX_CMD% refman.tex +goto :repeat +:skip +endlocal +makeindex refman.idx +%LATEX_CMD% refman.tex +dvips -o refman.ps refman.dvi +gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=refman.pdf -c save pop -f refman.ps diff --git a/doxygen/doc/latex/modules.tex b/doxygen/doc/latex/modules.tex new file mode 100644 index 0000000..d88de2b --- /dev/null +++ b/doxygen/doc/latex/modules.tex @@ -0,0 +1,7 @@ +\doxysection{Modules} +Here is a list of all modules\+:\begin{DoxyCompactList} +\item \contentsline{section}{Learning module of the KARMA Experiment}{\pageref{group__karmaLearn}}{} +\item \contentsline{section}{Motor Part of the KARMA Experiment}{\pageref{group__karmaMotor}}{} +\item \contentsline{section}{Tool Solver Part of the KARMA Experiment}{\pageref{group__karmaToolFinder}}{} +\item \contentsline{section}{Tool Projection Part of the KARMA Experiment}{\pageref{group__karmaToolProjection}}{} +\end{DoxyCompactList} diff --git a/doxygen/doc/latex/refman.tex b/doxygen/doc/latex/refman.tex new file mode 100644 index 0000000..d1b3c80 --- /dev/null +++ b/doxygen/doc/latex/refman.tex @@ -0,0 +1,186 @@ +\let\mypdfximage\pdfximage\def\pdfximage{\immediate\mypdfximage}\documentclass[twoside]{book} + +%% moved from doxygen.sty due to workaround for LaTex 2019 version and unmaintained tabu package +\usepackage{ifthen} +\ifx\requestedLaTeXdate\undefined +\usepackage{array} +\else +\usepackage{array}[=2016-10-06] +\fi +%% +% Packages required by doxygen +\usepackage{fixltx2e} +\usepackage{doxygen} +\usepackage{graphicx} +\usepackage[utf8]{inputenc} +\usepackage{makeidx} +\PassOptionsToPackage{warn}{textcomp} +\usepackage{textcomp} +\usepackage[nointegrals]{wasysym} +\usepackage{ifxetex} + +% Font selection +\usepackage[T1]{fontenc} +\usepackage[scaled=.90]{helvet} +\usepackage{courier} +\renewcommand{\familydefault}{\sfdefault} +\usepackage{sectsty} +\allsectionsfont{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} +\renewcommand{\DoxyLabelFont}{% + \fontseries{bc}\selectfont% + \color{darkgray}% +} +\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}} + +% Arguments of doxygenemoji: +% 1) '::' form of the emoji, already "LaTeX"-escaped +% 2) file with the name of the emoji without the .png extension +% in case image exist use this otherwise use the '::' form +\newcommand{\doxygenemoji}[2]{% + \IfFileExists{./#2.png}{\raisebox{-0.1em}{\includegraphics[height=0.9em]{./#2.png}}}{#1}% +} +% Page & text layout +\usepackage{geometry} +\geometry{% + a4paper,% + top=2.5cm,% + bottom=2.5cm,% + left=2.5cm,% + right=2.5cm% +} +\tolerance=750 +\hfuzz=15pt +\hbadness=750 +\setlength{\emergencystretch}{15pt} +\setlength{\parindent}{0cm} +\newcommand{\doxynormalparskip}{\setlength{\parskip}{3ex plus 2ex minus 2ex}} +\newcommand{\doxytocparskip}{\setlength{\parskip}{1ex plus 0ex minus 0ex}} +\doxynormalparskip +\makeatletter +\renewcommand{\paragraph}{% + \@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@parafont% + }% +} +\renewcommand{\subparagraph}{% + \@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{% + \normalfont\normalsize\bfseries\SS@subparafont% + }% +} +\makeatother + +\makeatletter +\newcommand\hrulefilll{\leavevmode\leaders\hrule\hskip 0pt plus 1filll\kern\z@} +\makeatother + +% Headers & footers +\usepackage{fancyhdr} +\pagestyle{fancyplain} +\renewcommand{\footrulewidth}{0.4pt} +% +\fancypagestyle{fancyplain}{ +\fancyhf{} +\fancyhead[LE, RO]{\bfseries\thepage} +\fancyhead[LO]{\bfseries\rightmark} +\fancyhead[RE]{\bfseries\leftmark} +\fancyfoot[LO, RE]{\bfseries\scriptsize Generated by Doxygen } +} +% +\fancypagestyle{plain}{ +\fancyhf{} +\fancyfoot[LO, RE]{\bfseries\scriptsize Generated by Doxygen } +\renewcommand{\headrulewidth}{0pt}} +% +\pagestyle{fancyplain} +% +\renewcommand{\chaptermark}[1]{% + \markboth{#1}{}% +} +\renewcommand{\sectionmark}[1]{% + \markright{\thesection\ #1}% +} + +% Indices & bibliography +\usepackage{natbib} +\usepackage[titles]{tocloft} +\setcounter{tocdepth}{3} +\setcounter{secnumdepth}{5} +\makeindex + +\usepackage{newunicodechar} + \newunicodechar{⁻}{${}^{-}$}% Superscript minus + \newunicodechar{²}{${}^{2}$}% Superscript two + \newunicodechar{³}{${}^{3}$}% Superscript three + +% Hyperlinks (required, but should be loaded last) +\ifpdf + \usepackage[pdftex,pagebackref=true]{hyperref} +\else + \ifxetex + \usepackage[pagebackref=true]{hyperref} + \else + \usepackage[ps2pdf,pagebackref=true]{hyperref} + \fi +\fi + +\hypersetup{% + colorlinks=true,% + linkcolor=blue,% + citecolor=blue,% + unicode% +} + +% Custom commands +\newcommand{\clearemptydoublepage}{% + \newpage{\pagestyle{empty}\cleardoublepage}% +} + +\usepackage{caption} +\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top} + +\usepackage{etoc} +\etocsettocstyle{\doxytocparskip}{\doxynormalparskip} +\renewcommand{\numberline}[1]{#1~} +%===== C O N T E N T S ===== + +\begin{document} +\raggedbottom + +% Titlepage & ToC +\pagenumbering{alph} +\begin{titlepage} +\vspace*{7cm} +\begin{center}% +{\Large karma }\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.9.1}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} + +%--- Begin generated contents --- +\chapter{Module Index} +\input{modules} +\chapter{Module Documentation} +\input{group__karmaLearn} +\input{group__karmaMotor} +\input{group__karmaToolFinder} +\input{group__karmaToolProjection} +%--- End generated contents --- + +% Index +\backmatter +\newpage +\phantomsection +\clearemptydoublepage +\addcontentsline{toc}{chapter}{\indexname} +\printindex + +\end{document} diff --git a/doxygen/doc/latex/tabu_doxygen.sty b/doxygen/doc/latex/tabu_doxygen.sty new file mode 100644 index 0000000..60fd7e8 --- /dev/null +++ b/doxygen/doc/latex/tabu_doxygen.sty @@ -0,0 +1,2557 @@ +%% +%% This is file `tabu.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% tabu.dtx (with options: `package') +%% +%% This is a generated file. +%% Copyright (FC) 2010-2011 - lppl +%% +%% tabu : 2011/02/26 v2.8 - tabu : Flexible LaTeX tabulars +%% +%% ********************************************************************************************** +%% \begin{tabu} { preamble } => default target: \linewidth or \linegoal +%% \begin{tabu} to { preamble } => target specified +%% \begin{tabu} spread { preamble } => target relative to the ``natural width'' +%% +%% tabu works in text and in math modes. +%% +%% X columns: automatic width adjustment + horizontal and vertical alignment +%% \begin{tabu} { X[4c] X[1c] X[-2ml] } +%% +%% Horizontal lines and / or leaders: +%% \hline\hline => double horizontal line +%% \firsthline\hline => for nested tabulars +%% \lasthline\hline => for nested tabulars +%% \tabucline[line spec]{column-column} => ``funny'' lines (dash/leader) +%% Automatic lines / leaders : +%% \everyrow{\hline\hline} +%% +%% Vertical lines and / or leaders: +%% \begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt blue] } +%% \begin{tabu} { |[3pt red] X[4c] X[1c] X[-2ml] |[3pt on 2pt off 4pt blue] } +%% +%% Fixed vertical spacing adjustment: +%% \extrarowheight= \extrarowdepth= +%% or: \extrarowsep= => may be prefixed by \global +%% +%% Dynamic vertical spacing adjustment: +%% \abovetabulinesep= \belowtabulinesep= +%% or: \tabulinesep= => may be prefixed by \global +%% +%% delarray.sty shortcuts: in math and text modes +%% \begin{tabu} .... \({ preamble }\) +%% +%% Algorithms reports: +%% \tracingtabu=1 \tracingtabu=2 +%% +%% ********************************************************************************************** +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% +%% This work consists of the main source file tabu.dtx +%% and the derived files +%% tabu.sty, tabu.pdf, tabu.ins +%% +%% tabu : Flexible LaTeX tabulars +%% lppl copyright 2010-2011 by FC +%% + +\NeedsTeXFormat{LaTeX2e}[2005/12/01] +\ProvidesPackage{tabu_doxygen}[2011/02/26 v2.8 - flexible LaTeX tabulars (FC), frozen version for doxygen] +\RequirePackage{array}[2008/09/09] +\RequirePackage{varwidth}[2009/03/30] +\AtEndOfPackage{\tabu@AtEnd \let\tabu@AtEnd \@undefined} +\let\tabu@AtEnd\@empty +\def\TMP@EnsureCode#1={% + \edef\tabu@AtEnd{\tabu@AtEnd + \catcode#1 \the\catcode#1}% + \catcode#1=% +}% \TMP@EnsureCode +\TMP@EnsureCode 33 = 12 % ! +\TMP@EnsureCode 58 = 12 % : (for siunitx) +\TMP@EnsureCode124 = 12 % | +\TMP@EnsureCode 36 = 3 % $ = math shift +\TMP@EnsureCode 38 = 4 % & = tab alignment character +\TMP@EnsureCode 32 = 10 % space +\TMP@EnsureCode 94 = 7 % ^ +\TMP@EnsureCode 95 = 8 % _ +%% Constants -------------------------------------------------------- +\newcount \c@taburow \def\thetaburow {\number\c@taburow} +\newcount \tabu@nbcols +\newcount \tabu@cnt +\newcount \tabu@Xcol +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcount \tabu@alloc \tabu@alloc=\m@ne +\newcount \tabu@nested +\def\tabu@alloc@{\global\advance\tabu@alloc \@ne \tabu@nested\tabu@alloc} +\newdimen \tabu@target +\newdimen \tabu@spreadtarget +\newdimen \tabu@naturalX +\newdimen \tabucolX +\let\tabu@DELTA \@tempdimc +\let\tabu@thick \@tempdima +\let\tabu@on \@tempdimb +\let\tabu@off \@tempdimc +\newdimen \tabu@Xsum +\newdimen \extrarowdepth +\newdimen \abovetabulinesep +\newdimen \belowtabulinesep +\newdimen \tabustrutrule \tabustrutrule \z@ +\newtoks \tabu@thebody +\newtoks \tabu@footnotes +\newsavebox \tabu@box +\newsavebox \tabu@arstrutbox +\newsavebox \tabu@hleads +\newsavebox \tabu@vleads +\newif \iftabu@colortbl +\newif \iftabu@siunitx +\newif \iftabu@measuring +\newif \iftabu@spread +\newif \iftabu@negcoef +\newif \iftabu@everyrow +\def\tabu@everyrowtrue {\global\let\iftabu@everyrow \iftrue} +\def\tabu@everyrowfalse{\global\let\iftabu@everyrow \iffalse} +\newif \iftabu@long +\newif \iftabuscantokens +\def\tabu@rescan {\tabu@verbatim \scantokens } +%% Utilities (for internal usage) ----------------------------------- +\def\tabu@gobblespace #1 {#1} +\def\tabu@gobbletoken #1#2{#1} +\def\tabu@gobbleX{\futurelet\@let@token \tabu@gobblex} +\def\tabu@gobblex{\if ^^J\noexpand\@let@token \expandafter\@gobble + \else\ifx \@sptoken\@let@token + \expandafter\tabu@gobblespace\expandafter\tabu@gobbleX + \fi\fi +}% \tabu@gobblex +\def\tabu@X{^^J} +{\obeyspaces +\global\let\tabu@spxiii= % saves an active space (for \ifx) +\gdef\tabu@@spxiii{ }} +\def\tabu@ifenvir {% only for \multicolumn + \expandafter\tabu@if@nvir\csname\@currenvir\endcsname +}% \tabu@ifenvir +\def\tabu@if@nvir #1{\csname @\ifx\tabu#1first\else + \ifx\longtabu#1first\else + second\fi\fi oftwo\endcsname +}% \tabu@ifenvir +\def\tabu@modulo #1#2{\numexpr\ifnum\numexpr#1=\z@ 0\else #1-(#1-(#2-1)/2)/(#2)*(#2)\fi} +{\catcode`\&=3 +\gdef\tabu@strtrim #1{% #1 = control sequence to trim + \ifodd 1\ifx #1\@empty \else \ifx #1\space \else 0\fi \fi + \let\tabu@c@l@r \@empty \let#1\@empty + \else \expandafter \tabu@trimspaces #1\@nnil + \fi +}% \tabu@strtrim +\gdef\tabu@trimspaces #1\@nnil{\let\tabu@c@l@r=#2\tabu@firstspace .#1& }% +\gdef\tabu@firstspace #1#2#3 &{\tabu@lastspace #2#3&} +\gdef\tabu@lastspace #1{\def #3{#1}% + \ifx #3\tabu@c@l@r \def\tabu@c@l@r{\protect\color{#1}}\expandafter\remove@to@nnil \fi + \tabu@trimspaces #1\@nnil} +}% \catcode +\def\tabu@sanitizearg #1#2{{% + \csname \ifcsname if@safe@actives\endcsname % + @safe@activestrue\else + relax\fi \endcsname + \edef#2{#1}\tabu@strtrim#2\@onelevel@sanitize#2% + \expandafter}\expandafter\def\expandafter#2\expandafter{#2}% +}% \tabu@sanitizearg +\def\tabu@textbar #1{\begingroup \endlinechar\m@ne \scantokens{\def\:{|}}% + \expandafter\endgroup \expandafter#1\:% !!! semi simple group !!! +}% \tabu@textbar +\def\tabu@everyrow@bgroup{\iftabu@everyrow \begingroup \else \noalign{\ifnum0=`}\fi \fi} +\def\tabu@everyrow@egroup{% + \iftabu@everyrow \expandafter \endgroup \the\toks@ + \else \ifnum0=`{\fi}% + \fi +}% \tabu@everyrow@egroup +\def\tabu@arstrut {\global\setbox\@arstrutbox \hbox{\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \z@}% +}% \tabu@arstrut +\def\tabu@rearstrut {% + \@tempdima \arraystretch\dimexpr\ht\strutbox+\extrarowheight \relax + \@tempdimb \arraystretch\dimexpr\dp\strutbox+\extrarowdepth \relax + \ifodd 1\ifdim \ht\@arstrutbox=\@tempdima + \ifdim \dp\@arstrutbox=\@tempdimb 0 \fi\fi + \tabu@mkarstrut + \fi +}% \tabu@rearstrut +\def\tabu@@DBG #1{\ifdim\tabustrutrule>\z@ \color{#1}\fi} +\def\tabu@DBG@arstrut {\global\setbox\@arstrutbox + \hbox to\z@{\hbox to\z@{\hss + {\tabu@DBG{cyan}\vrule + height \arraystretch \dimexpr\ht\strutbox+\extrarowheight + depth \z@ + width \tabustrutrule}\kern-\tabustrutrule + {\tabu@DBG{pink}\vrule + height \z@ + depth \arraystretch \dimexpr\dp\strutbox+\extrarowdepth + width \tabustrutrule}}}% +}% \tabu@DBG@arstrut +\def\tabu@save@decl{\toks\count@ \expandafter{\the\toks\expandafter\count@ + \@nextchar}}% +\def\tabu@savedecl{\ifcat$\d@llarend\else + \let\save@decl \tabu@save@decl \fi % no inversion of tokens in text mode +}% \tabu@savedecl +\def\tabu@finalstrut #1{\unskip\ifhmode\nobreak\fi\vrule height\z@ depth\z@ width\z@} +\newcommand*\tabuDisableCommands {\g@addto@macro\tabu@trialh@@k } +\let\tabu@trialh@@k \@empty +\def\tabu@nowrite #1#{{\afterassignment}\toks@} +\let\tabu@write\write +\let\tabu@immediate\immediate +\def\tabu@WRITE{\begingroup + \def\immediate\write{\aftergroup\endgroup + \tabu@immediate\tabu@write}% +}% \tabu@WRITE +\expandafter\def\expandafter\tabu@GenericError\expandafter{% + \expandafter\tabu@WRITE\GenericError} +\def\tabu@warn{\tabu@WRITE\PackageWarning{tabu}} +\def\tabu@noxfootnote [#1]{\@gobble} +\def\tabu@nocolor #1#{\@gobble} +\newcommand*\tabu@norowcolor[2][]{} +\def\tabu@maybesiunitx #1{\def\tabu@temp{#1}% + \futurelet\@let@token \tabu@m@ybesiunitx} +\def\tabu@m@ybesiunitx #1{\def\tabu@m@ybesiunitx {% + \ifx #1\@let@token \let\tabu@cellleft \@empty \let\tabu@cellright \@empty \fi + \tabu@temp}% \tabu@m@ybesiunitx +}\expandafter\tabu@m@ybesiunitx \csname siunitx_table_collect_begin:Nn\endcsname +\def\tabu@celllalign@def #1{\def\tabu@celllalign{\tabu@maybesiunitx{#1}}}% +%% Fixed vertical spacing adjustment: \extrarowsep ------------------ +\newcommand*\extrarowsep{\edef\tabu@C@extra{\the\numexpr\tabu@C@extra+1}% + \iftabu@everyrow \aftergroup\tabu@Gextra + \else \aftergroup\tabu@n@Gextra + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@extra} \tabu@extra +}% \extrarowsep +\def\tabu@extra {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setextrasep \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extra +\def\tabu@setextra #1#2{\def\tabu@temp{\tabu@extr@#1#2}\afterassignment\tabu@temp#2} +\def\tabu@extr@ #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setextra\extrarowdepth \extrarowheight}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setextra\extrarowheight \extrarowdepth}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth + \fi \tabu@temp}% +}% \tabu@extr@ +\def\tabu@setextrasep {\extrarowheight=\extrarowdepth + \tabu@Gsave \tabu@G@extra \tabu@C@extra \extrarowheight \extrarowdepth +}% \tabu@setextrasep +\def\tabu@Gextra{\ifx \tabu@G@extra\@empty \else {\tabu@Rextra}\fi} +\def\tabu@n@Gextra{\ifx \tabu@G@extra\@empty \else \noalign{\tabu@Rextra}\fi} +\def\tabu@Rextra{\tabu@Grestore \tabu@G@extra \tabu@C@extra} +\let\tabu@C@extra \z@ +\let\tabu@G@extra \@empty +%% Dynamic vertical spacing adjustment: \tabulinesep ---------------- +\newcommand*\tabulinesep{\edef\tabu@C@linesep{\the\numexpr\tabu@C@linesep+1}% + \iftabu@everyrow \aftergroup\tabu@Glinesep + \else \aftergroup\tabu@n@Glinesep + \fi + \@ifnextchar={\tabu@gobbletoken\tabu@linesep} \tabu@linesep +}% \tabulinesep +\def\tabu@linesep {\@ifnextchar_% + {\tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}} + {\ifx ^\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}}% + \else \let\tabu@temp \@empty + \afterassignment \tabu@setlinesep \abovetabulinesep + \fi \tabu@temp}% +}% \tabu@linesep +\def\tabu@setsep #1#2{\def\tabu@temp{\tabu@sets@p#1#2}\afterassignment\tabu@temp#2} +\def\tabu@sets@p #1#2{\@ifnextchar^% + {\tabu@gobbletoken{\tabu@setsep\belowtabulinesep \abovetabulinesep}} + {\ifx _\@let@token \def\tabu@temp{% + \tabu@gobbletoken{\tabu@setsep\abovetabulinesep \belowtabulinesep}}% + \else \let\tabu@temp \@empty + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep + \fi \tabu@temp}% +}% \tabu@sets@p +\def\tabu@setlinesep {\belowtabulinesep=\abovetabulinesep + \tabu@Gsave \tabu@G@linesep \tabu@C@linesep \abovetabulinesep \belowtabulinesep +}% \tabu@setlinesep +\def\tabu@Glinesep{\ifx \tabu@G@linesep\@empty \else {\tabu@Rlinesep}\fi} +\def\tabu@n@Glinesep{\ifx \tabu@G@linesep\@empty \else \noalign{\tabu@Rlinesep}\fi} +\def\tabu@Rlinesep{\tabu@Grestore \tabu@G@linesep \tabu@C@linesep} +\let\tabu@C@linesep \z@ +\let\tabu@G@linesep \@empty +%% \global\extrarowsep and \global\tabulinesep ------------------- +\def\tabu@Gsave #1#2#3#4{\xdef#1{#1% + \toks#2{\toks\the\currentgrouplevel{\global#3\the#3\global#4\the#4}}}% +}% \tabu@Gsave +\def\tabu@Grestore#1#2{% + \toks#2{}#1\toks\currentgrouplevel\expandafter{\expandafter}\the\toks#2\relax + \ifcat$\the\toks\currentgrouplevel$\else + \global\let#1\@empty \global\let#2\z@ + \the\toks\currentgrouplevel + \fi +}% \tabu@Grestore +%% Setting code for every row --------------------------------------- +\newcommand*\everyrow{\tabu@everyrow@bgroup + \tabu@start \z@ \tabu@stop \z@ \tabu@evrstartstop +}% \everyrow +\def\tabu@evrstartstop {\@ifnextchar^% + {\afterassignment \tabu@evrstartstop \tabu@stop=}% + {\ifx ^\@let@token + \afterassignment\tabu@evrstartstop \tabu@start=% + \else \afterassignment\tabu@everyr@w \toks@ + \fi}% +}% \tabu@evrstartstop +\def\tabu@everyr@w {% + \xdef\tabu@everyrow{% + \noexpand\tabu@everyrowfalse + \let\noalign \relax + \noexpand\tabu@rowfontreset + \iftabu@colortbl \noexpand\tabu@rc@ \fi % \taburowcolors + \let\noexpand\tabu@docline \noexpand\tabu@docline@evr + \the\toks@ + \noexpand\tabu@evrh@@k + \noexpand\tabu@rearstrut + \global\advance\c@taburow \@ne}% + \iftabu@everyrow \toks@\expandafter + {\expandafter\def\expandafter\tabu@evr@L\expandafter{\the\toks@}\ignorespaces}% + \else \xdef\tabu@evr@G{\the\toks@}% + \fi + \tabu@everyrow@egroup +}% \tabu@everyr@w +\def\tabu@evr {\def\tabu@evrh@@k} % for internal use only +\tabu@evr{} +%% line style and leaders ------------------------------------------- +\newcommand*\newtabulinestyle [1]{% + {\@for \@tempa :=#1\do{\expandafter\tabu@newlinestyle \@tempa==\@nil}}% +}% \newtabulinestyle +\def\tabu@newlinestyle #1=#2=#3\@nil{\tabu@getline {#2}% + \tabu@sanitizearg {#1}\@tempa + \ifodd 1\ifx \@tempa\@empty \ifdefined\tabu@linestyle@ 0 \fi\fi + \global\expandafter\let + \csname tabu@linestyle@\@tempa \endcsname =\tabu@thestyle \fi +}% \tabu@newlinestyle +\newcommand*\tabulinestyle [1]{\tabu@everyrow@bgroup \tabu@getline{#1}% + \iftabu@everyrow + \toks@\expandafter{\expandafter \def \expandafter + \tabu@ls@L\expandafter{\tabu@thestyle}\ignorespaces}% + \gdef\tabu@ls@{\tabu@ls@L}% + \else + \global\let\tabu@ls@G \tabu@thestyle + \gdef\tabu@ls@{\tabu@ls@G}% + \fi + \tabu@everyrow@egroup +}% \tabulinestyle +\newcommand*\taburulecolor{\tabu@everyrow@bgroup \tabu@textbar \tabu@rulecolor} +\def\tabu@rulecolor #1{\toks@{}% + \def\tabu@temp #1##1#1{\tabu@ruledrsc{##1}}\@ifnextchar #1% + \tabu@temp + \tabu@rulearc +}% \tabu@rulecolor +\def\tabu@ruledrsc #1{\edef\tabu@temp{#1}\tabu@strtrim\tabu@temp + \ifx \tabu@temp\@empty \def\tabu@temp{\tabu@rule@drsc@ {}{}}% + \else \edef\tabu@temp{\noexpand\tabu@rule@drsc@ {}{\tabu@temp}}% + \fi + \tabu@temp +}% \tabu@ruledrsc@ +\def\tabu@ruledrsc@ #1#{\tabu@rule@drsc@ {#1}} +\def\tabu@rule@drsc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@{\let\CT@drsc@ \relax}% + \else \toks@{\def\CT@drsc@{\color #1{#2}}}% + \fi + \else + \ifx \\#1#2\\\global\let\CT@drsc@ \relax + \else \gdef\CT@drsc@{\color #1{#2}}% + \fi + \fi + \tabu@rulearc +}% \tabu@rule@drsc@ +\def\tabu@rulearc #1#{\tabu@rule@arc@ {#1}} +\def\tabu@rule@arc@ #1#2{% + \iftabu@everyrow + \ifx \\#1#2\\\toks@\expandafter{\the\toks@ \def\CT@arc@{}}% + \else \toks@\expandafter{\the\toks@ \def\CT@arc@{\color #1{#2}}}% + \fi + \toks@\expandafter{\the\toks@ + \let\tabu@arc@L \CT@arc@ + \let\tabu@drsc@L \CT@drsc@ + \ignorespaces}% + \else + \ifx \\#1#2\\\gdef\CT@arc@{}% + \else \gdef\CT@arc@{\color #1{#2}}% + \fi + \global\let\tabu@arc@G \CT@arc@ + \global\let\tabu@drsc@G \CT@drsc@ + \fi + \tabu@everyrow@egroup +}% \tabu@rule@arc@ +\def\taburowcolors {\tabu@everyrow@bgroup \@testopt \tabu@rowcolors 1} +\def\tabu@rowcolors [#1]#2#{\tabu@rowc@lors{#1}{#2}} +\def\tabu@rowc@lors #1#2#3{% + \toks@{}\@defaultunits \count@ =\number0#2\relax \@nnil + \@defaultunits \tabu@start =\number0#1\relax \@nnil + \ifnum \count@<\tw@ \count@=\tw@ \fi + \advance\tabu@start \m@ne + \ifnum \tabu@start<\z@ \tabu@start \z@ \fi + \tabu@rowcolorseries #3\in@..\in@ \@nnil +}% \tabu@rowcolors +\def\tabu@rowcolorseries #1..#2\in@ #3\@nnil {% + \ifx \in@#1\relax + \iftabu@everyrow \toks@{\def\tabu@rc@{}\let\tabu@rc@L \tabu@rc@}% + \else \gdef\tabu@rc@{}\global\let\tabu@rc@G \tabu@rc@ + \fi + \else + \ifx \\#2\\\tabu@rowcolorserieserror \fi + \tabu@sanitizearg{#1}\tabu@temp + \tabu@sanitizearg{#2}\@tempa + \advance\count@ \m@ne + \iftabu@everyrow + \def\tabu@rc@ ##1##2##3##4{\def\tabu@rc@{% + \ifnum ##2=\c@taburow + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{##3}{##4}\fi + \ifnum \c@taburow<##2 \else + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\z@ + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}\fi}% + }\edef\x{\noexpand\tabu@rc@ {\the\count@} + {\the\tabu@start} + {\tabu@temp} + {\@tempa}% + }\x + \toks@\expandafter{\expandafter\def\expandafter\tabu@rc@\expandafter{\tabu@rc@}}% + \toks@\expandafter{\the\toks@ \let\tabu@rc@L \tabu@rc@ \ignorespaces}% + \else % inside \noalign + \definecolorseries{tabu@rcseries@\the\tabu@nested}{rgb}{last}{\tabu@temp}{\@tempa}% + \expandafter\resetcolorseries\expandafter[\the\count@]{tabu@rcseries@\the\tabu@nested}% + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \let\noalign \relax \rowcolor{tabu@rc@\the\tabu@nested}% + \def\tabu@rc@ ##1##2{\gdef\tabu@rc@{% + \ifnum \tabu@modulo {\c@taburow-##2}{##1+1}=\@ne + \resetcolorseries[{##1}]{tabu@rcseries@\the\tabu@nested}\fi + \xglobal\colorlet{tabu@rc@\the\tabu@nested}{tabu@rcseries@\the\tabu@nested!!+}% + \rowcolor{tabu@rc@\the\tabu@nested}}% + }\edef\x{\noexpand\tabu@rc@{\the\count@}{\the\c@taburow}}\x + \global\let\tabu@rc@G \tabu@rc@ + \fi + \fi + \tabu@everyrow@egroup +}% \tabu@rowcolorseries +\tabuDisableCommands {\let\tabu@rc@ \@empty } +\def\tabu@rowcolorserieserror {\PackageError{tabu} + {Invalid syntax for \string\taburowcolors + \MessageBreak Please look at the documentation!}\@ehd +}% \tabu@rowcolorserieserror +\newcommand*\tabureset {% + \tabulinesep=\z@ \extrarowsep=\z@ \extratabsurround=\z@ + \tabulinestyle{}\everyrow{}\taburulecolor||{}\taburowcolors{}% +}% \tabureset +%% Parsing the line styles ------------------------------------------ +\def\tabu@getline #1{\begingroup + \csname \ifcsname if@safe@actives\endcsname % + @safe@activestrue\else + relax\fi \endcsname + \edef\tabu@temp{#1}\tabu@sanitizearg{#1}\@tempa + \let\tabu@thestyle \relax + \ifcsname tabu@linestyle@\@tempa \endcsname + \edef\tabu@thestyle{\endgroup + \def\tabu@thestyle{\expandafter\noexpand + \csname tabu@linestyle@\@tempa\endcsname}% + }\tabu@thestyle + \else \expandafter\tabu@definestyle \tabu@temp \@nil + \fi +}% \tabu@getline +\def\tabu@definestyle #1#2\@nil {\endlinechar \m@ne \makeatletter + \tabu@thick \maxdimen \tabu@on \maxdimen \tabu@off \maxdimen + \let\tabu@c@lon \@undefined \let\tabu@c@loff \@undefined + \ifodd 1\ifcat .#1\else\ifcat\relax #1\else 0\fi\fi % catcode 12 or non expandable cs + \def\tabu@temp{\tabu@getparam{thick}}% + \else \def\tabu@temp{\tabu@getparam{thick}\maxdimen}% + \fi + {% + \let\tabu@ \relax + \def\:{\obeyspaces \tabu@oXIII \tabu@commaXIII \edef\:}% (space active \: happy ;-)) + \scantokens{\:{\tabu@temp #1#2 \tabu@\tabu@}}% + \expandafter}\expandafter + \def\expandafter\:\expandafter{\:}% line spec rewritten now ;-) + \def\;{\def\:}% + \scantokens\expandafter{\expandafter\;\expandafter{\:}}% space is now inactive (catcode 10) + \let\tabu@ \tabu@getcolor \:% all arguments are ready now ;-) + \ifdefined\tabu@c@lon \else \let\tabu@c@lon\@empty \fi + \ifx \tabu@c@lon\@empty \def\tabu@c@lon{\CT@arc@}\fi + \ifdefined\tabu@c@loff \else \let\tabu@c@loff \@empty \fi + \ifdim \tabu@on=\maxdimen \ifdim \tabu@off<\maxdimen + \tabu@on \tabulineon \fi\fi + \ifdim \tabu@off=\maxdimen \ifdim \tabu@on<\maxdimen + \tabu@off \tabulineoff \fi\fi + \ifodd 1\ifdim \tabu@off=\maxdimen \ifdim \tabu@on=\maxdimen 0 \fi\fi + \in@true % + \else \in@false % + \fi + \ifdim\tabu@thick=\maxdimen \def\tabu@thick{\arrayrulewidth}% + \else \edef\tabu@thick{\the\tabu@thick}% + \fi + \edef \tabu@thestyle ##1##2{\endgroup + \def\tabu@thestyle{% + \ifin@ \noexpand\tabu@leadersstyle {\tabu@thick} + {\the\tabu@on}{##1} + {\the\tabu@off}{##2}% + \else \noexpand\tabu@rulesstyle + {##1\vrule width \tabu@thick}% + {##1\leaders \hrule height \tabu@thick \hfil}% + \fi}% + }\expandafter \expandafter + \expandafter \tabu@thestyle \expandafter + \expandafter \expandafter + {\expandafter\tabu@c@lon\expandafter}\expandafter{\tabu@c@loff}% +}% \tabu@definestyle +{\catcode`\O=\active \lccode`\O=`\o \catcode`\,=\active + \lowercase{\gdef\tabu@oXIII {\catcode`\o=\active \let O=\tabu@oxiii}} + \gdef\tabu@commaXIII {\catcode`\,=\active \let ,=\space} +}% \catcode +\def\tabu@oxiii #1{% + \ifcase \ifx n#1\z@ \else + \ifx f#1\@ne\else + \tw@ \fi\fi + \expandafter\tabu@onxiii + \or \expandafter\tabu@ofxiii + \else o% + \fi#1}% +\def\tabu@onxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx \tabu@spxiii#2\@ne\else + \tw@ \fi\fi\fi + \tabu@getparam{on}#2\expandafter\@gobble + \or \expandafter\tabu@onxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}}% +\def\tabu@ofxiii #1#2{% + \ifx #2f\expandafter\tabu@offxiii + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@offxiii #1#2{% + \ifcase \ifx !#2\tw@ \else + \ifcat.\noexpand#2\z@ \else + \ifx\tabu@spxiii#2\@ne \else + \tw@ \fi\fi\fi + \tabu@getparam{off}#2\expandafter\@gobble + \or \expandafter\tabu@offxiii % (space is active) + \else o\expandafter\@firstofone + \fi{#1#2}} +\def\tabu@getparam #1{\tabu@ \csname tabu@#1\endcsname=} +\def\tabu@getcolor #1{% \tabu@ <- \tabu@getcolor after \edef + \ifx \tabu@#1\else % no more spec + \let\tabu@theparam=#1\afterassignment \tabu@getc@l@r #1\fi +}% \tabu@getcolor +\def\tabu@getc@l@r #1\tabu@ {% + \def\tabu@temp{#1}\tabu@strtrim \tabu@temp + \ifx \tabu@temp\@empty + \else%\ifcsname \string\color@\tabu@temp \endcsname % if the color exists + \ifx \tabu@theparam \tabu@off \let\tabu@c@loff \tabu@c@l@r + \else \let\tabu@c@lon \tabu@c@l@r + \fi + %\else \tabu@warncolour{\tabu@temp}% + \fi%\fi + \tabu@ % next spec +}% \tabu@getc@l@r +\def\tabu@warncolour #1{\PackageWarning{tabu} + {Color #1 is not defined. Default color used}% +}% \tabu@warncolour +\def\tabu@leadersstyle #1#2#3#4#5{\def\tabu@leaders{{#1}{#2}{#3}{#4}{#5}}% + \ifx \tabu@leaders\tabu@leaders@G \else + \tabu@LEADERS{#1}{#2}{#3}{#4}{#5}\fi +}% \tabu@leadersstyle +\def\tabu@rulesstyle #1#2{\let\tabu@leaders \@undefined + \gdef\tabu@thevrule{#1}\gdef\tabu@thehrule{#2}% +}% \tabu@rulesstyle +%% The leaders boxes ------------------------------------------------ +\def\tabu@LEADERS #1#2#3#4#5{%% width, dash, dash color, gap, gap color + {\let\color \tabu@color % => during trials -> \color = \tabu@nocolor + {% % but the leaders boxes should have colors ! + \def\@therule{\vrule}\def\@thick{height}\def\@length{width}% + \def\@box{\hbox}\def\@unbox{\unhbox}\def\@elt{\wd}% + \def\@skip{\hskip}\def\@ss{\hss}\def\tabu@leads{\tabu@hleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thehleaders \tabu@theleaders + }% + {% + \def\@therule{\hrule}\def\@thick{width}\def\@length{height}% + \def\@box{\vbox}\def\@unbox{\unvbox}\def\@elt{\ht}% + \def\@skip{\vskip}\def\@ss{\vss}\def\tabu@leads{\tabu@vleads}% + \tabu@l@@d@rs {#1}{#2}{#3}{#4}{#5}% + \global\let\tabu@thevleaders \tabu@theleaders + }% + \gdef\tabu@leaders@G{{#1}{#2}{#3}{#4}{#5}}% + }% +}% \tabu@LEADERS +\def\tabu@therule #1#2{\@therule \@thick#1\@length\dimexpr#2/2 \@depth\z@} +\def\tabu@l@@d@rs #1#2#3#4#5{%% width, dash, dash color, gap, gap color + \global\setbox \tabu@leads=\@box{% + {#3\tabu@therule{#1}{#2}}% + \ifx\\#5\\\@skip#4\else{#5\tabu@therule{#1}{#4*2}}\fi + {#3\tabu@therule{#1}{#2}}}% + \global\setbox\tabu@leads=\@box to\@elt\tabu@leads{\@ss + {#3\tabu@therule{#1}{#2}}\@unbox\tabu@leads}% + \edef\tabu@theleaders ##1{\def\noexpand\tabu@theleaders {% + {##1\tabu@therule{#1}{#2}}% + \xleaders \copy\tabu@leads \@ss + \tabu@therule{0pt}{-#2}{##1\tabu@therule{#1}{#2}}}% + }\tabu@theleaders{#3}% +}% \tabu@l@@d@rs +%% \tabu \endtabu \tabu* \longtabu \endlongtabu \longtabu* ---------- +\newcommand*\tabu {\tabu@longfalse + \ifmmode \def\tabu@ {\array}\def\endtabu {\endarray}% + \else \def\tabu@ {\tabu@tabular}\def\endtabu {\endtabular}\fi + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endtabu*\endcsname{\endtabu}% + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {tabu} +\let\tabu@tabular \tabular % +\expandafter\def\csname tabu*\endcsname{\tabuscantokenstrue \tabu} +\newcommand*\longtabu {\tabu@longtrue + \ifmmode\PackageError{tabu}{longtabu not allowed in math mode}\fi + \def\tabu@{\longtable}\def\endlongtabu{\endlongtable}% + \LTchunksize=\@M + \expandafter\let\csname tabu*\endcsname \tabu + \expandafter\def\csname endlongtabu*\endcsname{\endlongtabu}% + \let\LT@startpbox \tabu@LT@startpbox % \everypar{ array struts } + \tabu@spreadfalse \tabu@negcoeffalse \tabu@settarget +}% {longtabu} +\expandafter\def\csname longtabu*\endcsname{\tabuscantokenstrue \longtabu} +\def\tabu@nolongtabu{\PackageError{tabu} + {longtabu requires the longtable package}\@ehd} +%% Read the target and then : \tabular or \@array ------------------ +\def\tabu@settarget {\futurelet\@let@token \tabu@sett@rget } +\def\tabu@sett@rget {\tabu@target \z@ + \ifcase \ifx \bgroup\@let@token \z@ \else + \ifx \@sptoken\@let@token \@ne \else + \if t\@let@token \tw@ \else + \if s\@let@token \thr@@\else + \z@\fi\fi\fi\fi + \expandafter\tabu@begin + \or \expandafter\tabu@gobblespace\expandafter\tabu@settarget + \or \expandafter\tabu@to + \or \expandafter\tabu@spread + \fi +}% \tabu@sett@rget +\def\tabu@to to{\def\tabu@halignto{to}\tabu@gettarget} +\def\tabu@spread spread{\tabu@spreadtrue\def\tabu@halignto{spread}\tabu@gettarget} +\def\tabu@gettarget {\afterassignment\tabu@linegoaltarget \tabu@target } +\def\tabu@linegoaltarget {\futurelet\tabu@temp \tabu@linegoalt@rget } +\def\tabu@linegoalt@rget {% + \ifx \tabu@temp\LNGL@setlinegoal + \LNGL@setlinegoal \expandafter \@firstoftwo \fi % @gobbles \LNGL@setlinegoal + \tabu@begin +}% \tabu@linegoalt@rget +\def\tabu@begin #1#{% + \iftabu@measuring \expandafter\tabu@nestedmeasure \fi + \ifdim \tabu@target=\z@ \let\tabu@halignto \@empty + \else \edef\tabu@halignto{\tabu@halignto\the\tabu@target}% + \fi + \@testopt \tabu@tabu@ \tabu@aligndefault #1\@nil +}% \tabu@begin +\long\def\tabu@tabu@ [#1]#2\@nil #3{\tabu@setup + \def\tabu@align {#1}\def\tabu@savedpream{\NC@find #3}% + \tabu@ [\tabu@align ]#2{#3\tabu@rewritefirst }% +}% \tabu@tabu@ +\def\tabu@nestedmeasure {% + \ifodd 1\iftabu@spread \else \ifdim\tabu@target=\z@ \else 0 \fi\fi\relax + \tabu@spreadtrue + \else \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}% + \expandafter\tabu@collectbody\expandafter\tabu@quickrule + \expandafter\endgroup + \fi +}% \tabu@nestedmeasure +\def\tabu@quickrule {\indent\vrule height\z@ depth\z@ width\tabu@target} +%% \tabu@setup \tabu@init \tabu@indent +\def\tabu@setup{\tabu@alloc@ + \ifcase \tabu@nested + \ifmmode \else \iftabu@spread\else \ifdim\tabu@target=\z@ + \let\tabu@afterendpar \par + \fi\fi\fi + \def\tabu@aligndefault{c}\tabu@init \tabu@indent + \else % + \def\tabu@aligndefault{t}\let\tabudefaulttarget \linewidth + \fi + \let\tabu@thetarget \tabudefaulttarget \let\tabu@restored \@undefined + \edef\tabu@NC@list{\the\NC@list}\NC@list{\NC@do \tabu@rewritefirst}% + \everycr{}\let\@startpbox \tabu@startpbox % for nested tabu inside longtabu... + \let\@endpbox \tabu@endpbox % idem " " " " " " + \let\@tabarray \tabu@tabarray % idem " " " " " " + \tabu@setcleanup \tabu@setreset +}% \tabu@setup +\def\tabu@init{\tabu@starttimer \tabu@measuringfalse + \edef\tabu@hfuzz {\the\dimexpr\hfuzz+1sp}\global\tabu@footnotes{}% + \let\firsthline \tabu@firsthline \let\lasthline \tabu@lasthline + \let\firstline \tabu@firstline \let\lastline \tabu@lastline + \let\hline \tabu@hline \let\@xhline \tabu@xhline + \let\color \tabu@color \let\@arstrutbox \tabu@arstrutbox + \iftabu@colortbl\else\let\LT@@hline \tabu@LT@@hline \fi + \tabu@trivlist % + \let\@footnotetext \tabu@footnotetext \let\@xfootnotetext \tabu@xfootnotetext + \let\@xfootnote \tabu@xfootnote \let\centering \tabu@centering + \let\raggedright \tabu@raggedright \let\raggedleft \tabu@raggedleft + \let\tabudecimal \tabu@tabudecimal \let\Centering \tabu@Centering + \let\RaggedRight \tabu@RaggedRight \let\RaggedLeft \tabu@RaggedLeft + \let\justifying \tabu@justifying \let\rowfont \tabu@rowfont + \let\fbox \tabu@fbox \let\color@b@x \tabu@color@b@x + \let\tabu@@everycr \everycr \let\tabu@@everypar \everypar + \let\tabu@prepnext@tokORI \prepnext@tok\let\prepnext@tok \tabu@prepnext@tok + \let\tabu@multicolumnORI\multicolumn \let\multicolumn \tabu@multicolumn + \let\tabu@startpbox \@startpbox % for nested tabu inside longtabu pfff !!! + \let\tabu@endpbox \@endpbox % idem " " " " " " " + \let\tabu@tabarray \@tabarray % idem " " " " " " " + \tabu@adl@fix \let\endarray \tabu@endarray % colortbl & arydshln (delarray) + \iftabu@colortbl\CT@everycr\expandafter{\expandafter\iftabu@everyrow \the\CT@everycr \fi}\fi +}% \tabu@init +\def\tabu@indent{% correction for indentation + \ifdim \parindent>\z@\ifx \linewidth\tabudefaulttarget + \everypar\expandafter{% + \the\everypar\everypar\expandafter{\the\everypar}% + \setbox\z@=\lastbox + \ifdim\wd\z@>\z@ \edef\tabu@thetarget + {\the\dimexpr -\wd\z@+\tabudefaulttarget}\fi + \box\z@}% + \fi\fi +}% \tabu@indent +\def\tabu@setcleanup {% saves last global assignments + \ifodd 1\ifmmode \else \iftabu@long \else 0\fi\fi\relax + \def\tabu@aftergroupcleanup{% + \def\tabu@aftergroupcleanup{\aftergroup\tabu@cleanup}}% + \else + \def\tabu@aftergroupcleanup{% + \aftergroup\aftergroup\aftergroup\tabu@cleanup + \let\tabu@aftergroupcleanup \relax}% + \fi + \let\tabu@arc@Gsave \tabu@arc@G + \let\tabu@arc@G \tabu@arc@L % + \let\tabu@drsc@Gsave \tabu@drsc@G + \let\tabu@drsc@G \tabu@drsc@L % + \let\tabu@ls@Gsave \tabu@ls@G + \let\tabu@ls@G \tabu@ls@L % + \let\tabu@rc@Gsave \tabu@rc@G + \let\tabu@rc@G \tabu@rc@L % + \let\tabu@evr@Gsave \tabu@evr@G + \let\tabu@evr@G \tabu@evr@L % + \let\tabu@celllalign@save \tabu@celllalign + \let\tabu@cellralign@save \tabu@cellralign + \let\tabu@cellleft@save \tabu@cellleft + \let\tabu@cellright@save \tabu@cellright + \let\tabu@@celllalign@save \tabu@@celllalign + \let\tabu@@cellralign@save \tabu@@cellralign + \let\tabu@@cellleft@save \tabu@@cellleft + \let\tabu@@cellright@save \tabu@@cellright + \let\tabu@rowfontreset@save \tabu@rowfontreset + \let\tabu@@rowfontreset@save\tabu@@rowfontreset + \let\tabu@rowfontreset \@empty + \edef\tabu@alloc@save {\the\tabu@alloc}% restore at \tabu@reset + \edef\c@taburow@save {\the\c@taburow}% + \edef\tabu@naturalX@save {\the\tabu@naturalX}% + \let\tabu@naturalXmin@save \tabu@naturalXmin + \let\tabu@naturalXmax@save \tabu@naturalXmax + \let\tabu@mkarstrut@save \tabu@mkarstrut + \edef\tabu@clarstrut{% + \extrarowheight \the\dimexpr \ht\@arstrutbox-\ht\strutbox \relax + \extrarowdepth \the\dimexpr \dp\@arstrutbox-\dp\strutbox \relax + \let\noexpand\@arraystretch \@ne \noexpand\tabu@rearstrut}% +}% \tabu@setcleanup +\def\tabu@cleanup {\begingroup + \globaldefs\@ne \tabu@everyrowtrue + \let\tabu@arc@G \tabu@arc@Gsave + \let\CT@arc@ \tabu@arc@G + \let\tabu@drsc@G \tabu@drsc@Gsave + \let\CT@drsc@ \tabu@drsc@G + \let\tabu@ls@G \tabu@ls@Gsave + \let\tabu@ls@ \tabu@ls@G + \let\tabu@rc@G \tabu@rc@Gsave + \let\tabu@rc@ \tabu@rc@G + \let\CT@do@color \relax + \let\tabu@evr@G \tabu@evr@Gsave + \let\tabu@celllalign \tabu@celllalign@save + \let\tabu@cellralign \tabu@cellralign@save + \let\tabu@cellleft \tabu@cellleft@save + \let\tabu@cellright \tabu@cellright@save + \let\tabu@@celllalign \tabu@@celllalign@save + \let\tabu@@cellralign \tabu@@cellralign@save + \let\tabu@@cellleft \tabu@@cellleft@save + \let\tabu@@cellright \tabu@@cellright@save + \let\tabu@rowfontreset \tabu@rowfontreset@save + \let\tabu@@rowfontreset \tabu@@rowfontreset@save + \tabu@naturalX =\tabu@naturalX@save + \let\tabu@naturalXmax \tabu@naturalXmax@save + \let\tabu@naturalXmin \tabu@naturalXmin@save + \let\tabu@mkarstrut \tabu@mkarstrut@save + \c@taburow =\c@taburow@save + \ifcase \tabu@nested \tabu@alloc \m@ne\fi + \endgroup % + \ifcase \tabu@nested + \the\tabu@footnotes \global\tabu@footnotes{}% + \tabu@afterendpar \tabu@elapsedtime + \fi + \tabu@clarstrut + \everyrow\expandafter {\tabu@evr@G}% +}% \tabu@cleanup +\let\tabu@afterendpar \relax +\def\tabu@setreset {% + \edef\tabu@savedparams {% \relax for \tabu@message@save + \ifmmode \col@sep \the\arraycolsep + \else \col@sep \the\tabcolsep \fi \relax + \arrayrulewidth \the\arrayrulewidth \relax + \doublerulesep \the\doublerulesep \relax + \extratabsurround \the\extratabsurround \relax + \extrarowheight \the\extrarowheight \relax + \extrarowdepth \the\extrarowdepth \relax + \abovetabulinesep \the\abovetabulinesep \relax + \belowtabulinesep \the\belowtabulinesep \relax + \def\noexpand\arraystretch{\arraystretch}% + \ifdefined\minrowclearance \minrowclearance\the\minrowclearance\relax\fi}% + \begingroup + \@temptokena\expandafter{\tabu@savedparams}% => only for \savetabu / \usetabu + \ifx \tabu@arc@L\relax \else \tabu@setsave \tabu@arc@L \fi + \ifx \tabu@drsc@L\relax \else \tabu@setsave \tabu@drsc@L \fi + \tabu@setsave \tabu@ls@L \tabu@setsave \tabu@evr@L + \expandafter \endgroup \expandafter + \def\expandafter\tabu@saved@ \expandafter{\the\@temptokena + \let\tabu@arc@G \tabu@arc@L + \let\tabu@drsc@G \tabu@drsc@L + \let\tabu@ls@G \tabu@ls@L + \let\tabu@rc@G \tabu@rc@L + \let\tabu@evr@G \tabu@evr@L}% + \def\tabu@reset{\tabu@savedparams + \tabu@everyrowtrue \c@taburow \z@ + \let\CT@arc@ \tabu@arc@L + \let\CT@drsc@ \tabu@drsc@L + \let\tabu@ls@ \tabu@ls@L + \let\tabu@rc@ \tabu@rc@L + \global\tabu@alloc \tabu@alloc@save + \everyrow\expandafter{\tabu@evr@L}}% +}% \tabu@reset +\def\tabu@setsave #1{\expandafter\tabu@sets@ve #1\@nil{#1}} +\long\def\tabu@sets@ve #1\@nil #2{\@temptokena\expandafter{\the\@temptokena \def#2{#1}}} +%% The Rewriting Process ------------------------------------------- +\def\tabu@newcolumntype #1{% + \expandafter\tabu@new@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@newcolumntype +\def\tabu@new@columntype #1#2#3{% + \def#1##1#3{\NC@{##1}}% + \let#2\relax \newcommand*#2% +}% \tabu@new@columntype +\def\tabu@privatecolumntype #1{% + \expandafter\tabu@private@columntype + \csname NC@find@\string#1\expandafter\endcsname + \csname NC@rewrite@\string#1\expandafter\endcsname + \csname tabu@NC@find@\string#1\expandafter\endcsname + \csname tabu@NC@rewrite@\string#1\endcsname + {#1}% +}% \tabu@privatecolumntype +\def\tabu@private@columntype#1#2#3#4{% + \g@addto@macro\tabu@privatecolumns{\let#1#3\let#2#4}% + \tabu@new@columntype#3#4% +}% \tabu@private@columntype +\let\tabu@privatecolumns \@empty +\newcommand*\tabucolumn [1]{\expandafter \def \expandafter + \tabu@highprioritycolumns\expandafter{\tabu@highprioritycolumns + \NC@do #1}}% +\let\tabu@highprioritycolumns \@empty +%% The | ``column'' : rewriting process -------------------------- +\tabu@privatecolumntype |{\tabu@rewritevline} +\newcommand*\tabu@rewritevline[1][]{\tabu@vlinearg{#1}% + \expandafter \NC@find \tabu@rewritten} +\def\tabu@lines #1{% + \ifx|#1\else \tabu@privatecolumntype #1{\tabu@rewritevline}\fi + \NC@list\expandafter{\the\NC@list \NC@do #1}% +}% \tabu@lines@ +\def\tabu@vlinearg #1{% + \ifx\\#1\\\def\tabu@thestyle {\tabu@ls@}% + \else\tabu@getline {#1}% + \fi + \def\tabu@rewritten ##1{\def\tabu@rewritten{!{##1\tabu@thevline}}% + }\expandafter\tabu@rewritten\expandafter{\tabu@thestyle}% + \expandafter \tabu@keepls \tabu@thestyle \@nil +}% \tabu@vlinearg +\def\tabu@keepls #1\@nil{% + \ifcat $\@cdr #1\@nil $% + \ifx \relax#1\else + \ifx \tabu@ls@#1\else + \let#1\relax + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@savels\noexpand#1}\fi\fi\fi +}% \tabu@keepls +\def\tabu@thevline {\begingroup + \ifdefined\tabu@leaders + \setbox\@tempboxa=\vtop to\dimexpr + \ht\@arstrutbox+\dp\@arstrutbox{{\tabu@thevleaders}}% + \ht\@tempboxa=\ht\@arstrutbox \dp\@tempboxa=\dp\@arstrutbox + \box\@tempboxa + \else + \tabu@thevrule + \fi \endgroup +}% \tabu@thevline +\def\tabu@savels #1{% + \expandafter\let\csname\string#1\endcsname #1% + \expandafter\def\expandafter\tabu@reset\expandafter{\tabu@reset + \tabu@resetls#1}}% +\def\tabu@resetls #1{\expandafter\let\expandafter#1\csname\string#1\endcsname}% +%% \multicolumn inside tabu environment ----------------------------- +\tabu@newcolumntype \tabu@rewritemulticolumn{% + \aftergroup \tabu@endrewritemulticolumn % after \@mkpream group + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \tabu@savedecl + \tabu@privatecolumns + \NC@list\expandafter{\the\expandafter\NC@list \tabu@NC@list}% + \let\tabu@savels \relax + \NC@find +}% \tabu@rewritemulticolumn +\def\tabu@endrewritemulticolumn{\gdef\tabu@mkpreambuffer{}\endgroup} +\def\tabu@multicolumn{\tabu@ifenvir \tabu@multic@lumn \tabu@multicolumnORI} +\long\def\tabu@multic@lumn #1#2#3{\multispan{#1}\begingroup + \tabu@everyrowtrue + \NC@list{\NC@do \tabu@rewritemulticolumn}% + \expandafter\@gobbletwo % gobbles \multispan{#1} + \tabu@multicolumnORI{#1}{\tabu@rewritemulticolumn #2}% + {\iftabuscantokens \tabu@rescan \else \expandafter\@firstofone \fi + {#3}}% +}% \tabu@multic@lumn +%% The X column(s): rewriting process ----------------------------- +\tabu@privatecolumntype X[1][]{\begingroup \tabu@siunitx{\endgroup \tabu@rewriteX {#1}}} +\def\tabu@nosiunitx #1{#1{}{}\expandafter \NC@find \tabu@rewritten } +\def\tabu@siunitx #1{\@ifnextchar \bgroup + {\tabu@rewriteX@Ss{#1}} + {\tabu@nosiunitx{#1}}} +\def\tabu@rewriteX@Ss #1#2{\@temptokena{}% + \@defaultunits \let\tabu@temp =#2\relax\@nnil + \ifodd 1\ifx S\tabu@temp \else \ifx s\tabu@temp \else 0 \fi\fi + \def\NC@find{\def\NC@find >####1####2<####3\relax{#1 {####1}{####3}% + }\expandafter\NC@find \the\@temptokena \relax + }\expandafter\NC@rewrite@S \@gobble #2\relax + \else \tabu@siunitxerror + \fi + \expandafter \NC@find \tabu@rewritten +}% \tabu@rewriteX@Ss +\def\tabu@siunitxerror {\PackageError{tabu}{Not a S nor s column ! + \MessageBreak X column can only embed siunitx S or s columns}\@ehd +}% \tabu@siunitxerror +\def\tabu@rewriteX #1#2#3{\tabu@Xarg {#1}{#2}{#3}% + \iftabu@measuring + \else \tabu@measuringtrue % first X column found in the preamble + \let\@halignto \relax \let\tabu@halignto \relax + \iftabu@spread \tabu@spreadtarget \tabu@target \tabu@target \z@ + \else \tabu@spreadtarget \z@ \fi + \ifdim \tabu@target=\z@ + \setlength\tabu@target \tabu@thetarget + \tabu@message{\tabu@message@defaulttarget}% + \else \tabu@message{\tabu@message@target}\fi + \fi +}% \tabu@rewriteX +\def\tabu@rewriteXrestore #1#2#3{\let\@halignto \relax + \def\tabu@rewritten{l}} +\def\tabu@Xarg #1#2#3{% + \advance\tabu@Xcol \@ne \let\tabu@Xlcr \@empty + \let\tabu@Xdisp \@empty \let\tabu@Xmath \@empty + \ifx\\#1\\% + \def\tabu@rewritten{p}\tabucolX \p@ % + \else + \let\tabu@rewritten \@empty \let\tabu@temp \@empty \tabucolX \z@ + \tabu@Xparse {}#1\relax + \fi + \tabu@Xrewritten{#2}{#3}% +}% \tabu@Xarg +\def\tabu@Xparse #1{\futurelet\@let@token \tabu@Xtest} +\expandafter\def\expandafter\tabu@Xparsespace\space{\tabu@Xparse{}} +\def\tabu@Xtest{% + \ifcase \ifx \relax\@let@token \z@ \else + \if ,\@let@token \m@ne\else + \if p\@let@token 1\else + \if m\@let@token 2\else + \if b\@let@token 3\else + \if l\@let@token 4\else + \if c\@let@token 5\else + \if r\@let@token 6\else + \if j\@let@token 7\else + \if L\@let@token 8\else + \if C\@let@token 9\else + \if R\@let@token 10\else + \if J\@let@token 11\else + \ifx \@sptoken\@let@token 12\else + \if .\@let@token 13\else + \if -\@let@token 13\else + \ifcat $\@let@token 14\else + 15\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \or \tabu@Xtype {p}% + \or \tabu@Xtype {m}% + \or \tabu@Xtype {b}% + \or \tabu@Xalign \raggedright\relax + \or \tabu@Xalign \centering\relax + \or \tabu@Xalign \raggedleft\relax + \or \tabu@Xalign \tabu@justify\relax + \or \tabu@Xalign \RaggedRight\raggedright + \or \tabu@Xalign \Centering\centering + \or \tabu@Xalign \RaggedLeft\raggedleft + \or \tabu@Xalign \justifying\tabu@justify + \or \expandafter \tabu@Xparsespace + \or \expandafter \tabu@Xcoef + \or \expandafter \tabu@Xm@th + \or \tabu@Xcoef{}% + \else\expandafter \tabu@Xparse + \fi +}% \tabu@Xtest +\def\tabu@Xalign #1#2{% + \ifx \tabu@Xlcr\@empty \else \PackageWarning{tabu} + {Duplicate horizontal alignment specification}\fi + \ifdefined#1\def\tabu@Xlcr{#1}\let#1\relax + \else \def\tabu@Xlcr{#2}\let#2\relax\fi + \expandafter\tabu@Xparse +}% \tabu@Xalign +\def\tabu@Xtype #1{% + \ifx \tabu@rewritten\@empty \else \PackageWarning{tabu} + {Duplicate vertical alignment specification}\fi + \def\tabu@rewritten{#1}\expandafter\tabu@Xparse +}% \tabu@Xtype +\def\tabu@Xcoef#1{\edef\tabu@temp{\tabu@temp#1}% + \afterassignment\tabu@Xc@ef \tabu@cnt\number\if-#10\fi +}% \tabu@Xcoef +\def\tabu@Xc@ef{\advance\tabucolX \tabu@temp\the\tabu@cnt\p@ + \tabu@Xparse{}% +}% \tabu@Xc@ef +\def\tabu@Xm@th #1{\futurelet \@let@token \tabu@Xd@sp} +\def\tabu@Xd@sp{\let\tabu@Xmath=$% + \ifx $\@let@token \def\tabu@Xdisp{\displaystyle}% + \expandafter\tabu@Xparse + \else \expandafter\tabu@Xparse\expandafter{\expandafter}% + \fi +}% \tabu@Xd@sp +\def\tabu@Xrewritten {% + \ifx \tabu@rewritten\@empty \def\tabu@rewritten{p}\fi + \ifdim \tabucolX<\z@ \tabu@negcoeftrue + \else\ifdim \tabucolX=\z@ \tabucolX \p@ + \fi\fi + \edef\tabu@temp{{\the\tabu@Xcol}{\tabu@strippt\tabucolX}}% + \edef\tabu@Xcoefs{\tabu@Xcoefs \tabu@ \tabu@temp}% + \edef\tabu@rewritten ##1##2{\def\noexpand\tabu@rewritten{% + >{\tabu@Xlcr \ifx$\tabu@Xmath$\tabu@Xdisp\fi ##1}% + \tabu@rewritten {\tabu@hsize \tabu@temp}% + <{##2\ifx$\tabu@Xmath$\fi}}% + }\tabu@rewritten +}% \tabu@Xrewritten +\def\tabu@hsize #1#2{% + \ifdim #2\p@<\z@ + \ifdim \tabucolX=\maxdimen \tabu@wd{#1}\else + \ifdim \tabu@wd{#1}<-#2\tabucolX \tabu@wd{#1}\else -#2\tabucolX\fi + \fi + \else #2\tabucolX + \fi +}% \tabu@hsize +%% \usetabu and \preamble: rewriting process --------------------- +\tabu@privatecolumntype \usetabu [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\let\tabu@rewriteX \tabu@rewriteXrestore + \csname tabu@saved@\string#1\expandafter\endcsname\expandafter\@ne}% + \fi +}% \NC@rewrite@\usetabu +\tabu@privatecolumntype \preamble [1]{% + \ifx\\#1\\\tabu@saveerr{}\else + \@ifundefined{tabu@saved@\string#1} + {\tabu@saveerr{#1}} + {\csname tabu@saved@\string#1\expandafter\endcsname\expandafter\z@}% + \fi +}% \NC@rewrite@\preamble +%% Controlling the rewriting process ------------------------------- +\tabu@newcolumntype \tabu@rewritefirst{% + \iftabu@long \aftergroup \tabu@longpream % + \else \aftergroup \tabu@pream + \fi + \let\tabu@ \relax \let\tabu@hsize \relax + \let\tabu@Xcoefs \@empty \let\tabu@savels \relax + \tabu@Xcol \z@ \tabu@cnt \tw@ + \gdef\tabu@mkpreambuffer{\tabu@{}}\tabu@measuringfalse + \global\setbox\@arstrutbox \box\@arstrutbox + \NC@list{\NC@do *}\tabu@textbar \tabu@lines + \NC@list\expandafter{\the\NC@list \NC@do X}% + \iftabu@siunitx % + \NC@list\expandafter{\the\NC@list \NC@do S\NC@do s}\fi + \NC@list\expandafter{\the\expandafter\NC@list \tabu@highprioritycolumns}% + \expandafter\def\expandafter\tabu@NC@list\expandafter{% + \the\expandafter\NC@list \tabu@NC@list}% % * | X S + \NC@list\expandafter{\expandafter \NC@do \expandafter\usetabu + \expandafter \NC@do \expandafter\preamble + \the\NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \tabu@savedecl + \tabu@privatecolumns + \edef\tabu@prev{\the\@temptokena}\NC@find \tabu@rewritemiddle +}% NC@rewrite@\tabu@rewritefirst +\tabu@newcolumntype \tabu@rewritemiddle{% + \edef\tabu@temp{\the\@temptokena}\NC@find \tabu@rewritelast +}% \NC@rewrite@\tabu@rewritemiddle +\tabu@newcolumntype \tabu@rewritelast{% + \ifx \tabu@temp\tabu@prev \advance\tabu@cnt \m@ne + \NC@list\expandafter{\tabu@NC@list \NC@do \tabu@rewritemiddle + \NC@do \tabu@rewritelast}% + \else \let\tabu@prev\tabu@temp + \fi + \ifcase \tabu@cnt \expandafter\tabu@endrewrite + \else \expandafter\NC@find \expandafter\tabu@rewritemiddle + \fi +}% \NC@rewrite@\tabu@rewritelast +%% Choosing the strategy -------------------------------------------- +\def\tabu@endrewrite {% + \let\tabu@temp \NC@find + \ifx \@arrayright\relax \let\@arrayright \@empty \fi + \count@=% + \ifx \@finalstrut\tabu@finalstrut \z@ % outer in mode 0 print + \iftabu@measuring + \xdef\tabu@mkpreambuffer{\tabu@mkpreambuffer + \tabu@target \csname tabu@\the\tabu@nested.T\endcsname + \tabucolX \csname tabu@\the\tabu@nested.X\endcsname + \edef\@halignto {\ifx\@arrayright\@empty to\tabu@target\fi}}% + \fi + \else\iftabu@measuring 4 % X columns + \xdef\tabu@mkpreambuffer{\tabu@{\tabu@mkpreambuffer + \tabu@target \the\tabu@target + \tabu@spreadtarget \the\tabu@spreadtarget}% + \def\noexpand\tabu@Xcoefs{\tabu@Xcoefs}% + \edef\tabu@halignto{\ifx \@arrayright\@empty to\tabu@target\fi}}% + \let\tabu@Xcoefs \relax + \else\ifcase\tabu@nested \thr@@ % outer, no X + \global\let\tabu@afterendpar \relax + \else \@ne % inner, no X, outer in mode 1 or 2 + \fi + \ifdefined\tabu@usetabu + \else \ifdim\tabu@target=\z@ + \else \let\tabu@temp \tabu@extracolsep + \fi\fi + \fi + \fi + \xdef\tabu@mkpreambuffer{\count@ \the\count@ \tabu@mkpreambuffer}% + \tabu@temp +}% \tabu@endrewrite +\def\tabu@extracolsep{\@defaultunits \expandafter\let + \expandafter\tabu@temp \expandafter=\the\@temptokena \relax\@nnil + \ifx \tabu@temp\@sptoken + \expandafter\tabu@gobblespace \expandafter\tabu@extracolsep + \else + \edef\tabu@temp{\noexpand\NC@find + \if |\noexpand\tabu@temp @% + \else\if !\noexpand\tabu@temp @% + \else !% + \fi\fi + {\noexpand\extracolsep\noexpand\@flushglue}}% + \fi + \tabu@temp +}% \tabu@extrac@lsep +%% Implementing the strategy ---------------------------------------- +\long\def\tabu@pream #1\@preamble {% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \ifdefined\tabu@usetabu \tabu@usetabu \tabu@target \z@ \fi + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\tabu@aftergroupcleanup}% + \tabu@thebody =\expandafter{\the\expandafter\tabu@thebody + \@preamble}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@pream +\long\def\tabu@longpream #1\LT@bchunk #2\LT@bchunk{% + \let\tabu@ \tabu@@ \tabu@mkpreambuffer \tabu@aftergroupcleanup + \NC@list\expandafter {\tabu@NC@list}% in case of nesting... + \let\tabu@savedpreamble \@preamble + \global\let\tabu@elapsedtime \relax + \tabu@thebody ={#1\LT@bchunk #2\tabu@aftergroupcleanup \LT@bchunk}% + \edef\tabuthepreamble {\the\tabu@thebody}% ( no @ allowed for \scantokens ) + \tabu@select +}% \tabu@longpream +\def\tabu@select {% + \ifnum\tabu@nested>\z@ \tabuscantokensfalse \fi + \ifnum \count@=\@ne \iftabu@measuring \count@=\tw@ \fi\fi + \ifcase \count@ + \global\let\tabu@elapsedtime \relax + \tabu@seteverycr + \expandafter \tabuthepreamble % vertical adjustment (inherited from outer) + \or % exit in vertical measure + struts per cell because no X and outer in mode 3 + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \tabu@seteverycr + \expandafter \tabuthepreamble + \or % exit without measure because no X and outer in mode 4 + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@seteverycr + \expandafter \tabuthepreamble + \else % needs trials + \tabu@evr{}\tabu@celllalign@def{}\let\tabu@cellralign \@empty + \tabu@savecounters + \expandafter \tabu@setstrategy + \fi +}% \tabu@select +\def\tabu@@ {\gdef\tabu@mkpreambuffer} +%% Protections to set up before trials ------------------------------ +\def\tabu@setstrategy {\begingroup % + \tabu@trialh@@k \tabu@cnt \z@ % number of trials + \hbadness \@M \let\hbadness \@tempcnta + \hfuzz \maxdimen \let\hfuzz \@tempdima + \let\write \tabu@nowrite\let\GenericError \tabu@GenericError + \let\savetabu \@gobble \let\tabudefaulttarget \linewidth + \let\@footnotetext \@gobble \let\@xfootnote \tabu@xfootnote + \let\color \tabu@nocolor\let\rowcolor \tabu@norowcolor + \let\tabu@aftergroupcleanup \relax % only after the last trial + \tabu@mkpreambuffer + \ifnum \count@>\thr@@ \let\@halignto \@empty \tabucolX@init + \def\tabu@lasttry{\m@ne\p@}\fi + \begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\iftabuscantokens \endlinechar=10 \obeyspaces \fi % + \tabu@collectbody \tabu@strategy % +}% \tabu@setstrategy +\def\tabu@savecounters{% + \def\@elt ##1{\csname c@##1\endcsname\the\csname c@##1\endcsname}% + \edef\tabu@clckpt {\begingroup \globaldefs=\@ne \cl@@ckpt \endgroup}\let\@elt \relax +}% \tabu@savecounters +\def\tabucolX@init {% \tabucolX <= \tabu@target / (sum coefs > 0) + \dimen@ \z@ \tabu@Xsum \z@ \tabucolX \z@ \let\tabu@ \tabu@Xinit \tabu@Xcoefs + \ifdim \dimen@>\z@ + \@tempdima \dimexpr \tabu@target *\p@/\dimen@ + \tabu@hfuzz\relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \fi +}% \tabucolX@init +\def\tabu@Xinit #1#2{\tabu@Xcol #1 \advance \tabu@Xsum + \ifdim #2\p@>\z@ #2\p@ \advance\dimen@ #2\p@ + \else -#2\p@ \tabu@negcoeftrue + \@tempdima \dimexpr \tabu@target*\p@/\dimexpr-#2\p@\relax \relax + \ifdim \tabucolX<\@tempdima \tabucolX \@tempdima \fi + \tabu@wddef{#1}{0pt}% + \fi +}% \tabu@Xinit +%% Collecting the environment body ---------------------------------- +\long\def\tabu@collectbody #1#2\end #3{% + \edef\tabu@stack{\tabu@pushbegins #2\begin\end\expandafter\@gobble\tabu@stack}% + \ifx \tabu@stack\@empty + \toks@\expandafter{\expandafter\tabu@thebody\expandafter{\the\toks@ #2}% + \def\tabu@end@envir{\end{#3}}% + \iftabuscantokens + \iftabu@long \def\tabu@endenvir {\end{#3}\tabu@gobbleX}% + \else \def\tabu@endenvir {\let\endarray \@empty + \end{#3}\tabu@gobbleX}% + \fi + \else \def\tabu@endenvir {\end{#3}}\fi}% + \let\tabu@collectbody \tabu@endofcollect + \else\def\tabu@temp{#3}% + \ifx \tabu@temp\@empty \toks@\expandafter{\the\toks@ #2\end }% + \else \ifx\tabu@temp\tabu@@spxiii \toks@\expandafter{\the\toks@ #2\end #3}% + \else \ifx\tabu@temp\tabu@X \toks@\expandafter{\the\toks@ #2\end #3}% + \else \toks@\expandafter{\the\toks@ #2\end{#3}}% + \fi\fi\fi + \fi + \tabu@collectbody{#1}% +}% \tabu@collectbody +\long\def\tabu@pushbegins#1\begin#2{\ifx\end#2\else b\expandafter\tabu@pushbegins\fi}% +\def\tabu@endofcollect #1{\ifnum0=`{}\fi + \expandafter\endgroup \the\toks@ #1% +}% \tabu@endofcollect +%% The trials: switching between strategies ------------------------- +\def\tabu@strategy {\relax % stops \count@ assignment ! + \ifcase\count@ % case 0 = print with vertical adjustment (outer is finished) + \expandafter \tabu@endoftrials + \or % case 1 = exit in vertical measure (outer in mode 3) + \expandafter\xdef\csname tabu@\the\tabu@nested.T\endcsname{\the\tabu@target}% + \expandafter\xdef\csname tabu@\the\tabu@nested.X\endcsname{\the\tabucolX}% + \expandafter \tabu@endoftrials + \or % case 2 = exit with a rule replacing the table (outer in mode 4) + \expandafter \tabu@quickend + \or % case 3 = outer is in mode 3 because of no X + \begingroup + \tabu@evr{\tabu@verticalinit}\tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \expandafter \tabu@measuring + \else % case 4 = horizontal measure + \begingroup + \global\let\tabu@elapsedtime \tabu@message@etime + \long\def\multicolumn##1##2##3{\multispan{##1}}% + \let\tabu@startpboxORI \@startpbox + \iftabu@spread + \def\tabu@naturalXmax {\z@}% + \let\tabu@naturalXmin \tabu@naturalXmax + \tabu@evr{\global\tabu@naturalX \z@}% + \let\@startpbox \tabu@startpboxmeasure + \else\iftabu@negcoef + \let\@startpbox \tabu@startpboxmeasure + \else \let\@startpbox \tabu@startpboxquick + \fi\fi + \expandafter \tabu@measuring + \fi +}% \tabu@strategy +\def\tabu@measuring{\expandafter \tabu@trial \expandafter + \count@ \the\count@ \tabu@endtrial +}% \tabu@measuring +\def\tabu@trial{\iftabu@long \tabu@longtrial \else \tabu@shorttrial \fi} +\def\tabu@shorttrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + $\iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \csname tabu@adl@endtrial\endcsname + \endarray}$\egroup % got \tabu@box +}% \tabu@shorttrial +\def\tabu@longtrial {\setbox\tabu@box \hbox\bgroup \tabu@seteverycr + \ifx \tabu@savecounters\relax \else + \let\tabu@savecounters \relax \tabu@clckpt \fi + \iftabuscantokens \tabu@rescan \else \expandafter\@secondoftwo \fi + \expandafter{\expandafter \tabuthepreamble + \the\tabu@thebody + \tabuendlongtrial}\egroup % got \tabu@box +}% \tabu@longtrial +\def\tabuendlongtrial{% no @ allowed for \scantokens + \LT@echunk \global\setbox\@ne \hbox{\unhbox\@ne}\kern\wd\@ne + \LT@get@widths +}% \tabuendlongtrial +\def\tabu@adl@endtrial{% + \crcr \noalign{\global\adl@ncol \tabu@nbcols}}% anything global is crap, junky and fails ! +\def\tabu@seteverycr {\tabu@reset + \everycr \expandafter{\the\everycr \tabu@everycr}% + \let\everycr \tabu@noeverycr % +}% \tabu@seteverycr +\def\tabu@noeverycr{{\aftergroup\tabu@restoreeverycr \afterassignment}\toks@} +\def\tabu@restoreeverycr {\let\everycr \tabu@@everycr} +\def\tabu@everycr {\iftabu@everyrow \noalign{\tabu@everyrow}\fi} +\def\tabu@endoftrials {% + \iftabuscantokens \expandafter\@firstoftwo + \else \expandafter\@secondoftwo + \fi + {\expandafter \tabu@closetrialsgroup \expandafter + \tabu@rescan \expandafter{% + \expandafter\tabuthepreamble + \the\expandafter\tabu@thebody + \iftabu@long \else \endarray \fi}} + {\expandafter\tabu@closetrialsgroup \expandafter + \tabuthepreamble + \the\tabu@thebody}% + \tabu@endenvir % Finish ! +}% \tabu@endoftrials +\def\tabu@closetrialsgroup {% + \toks@\expandafter{\tabu@endenvir}% + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target + \tabu@cnt \the\tabu@cnt + \def\noexpand\tabu@endenvir{\the\toks@}% + %Quid de \@halignto = \tabu@halignto ?? + }% \tabu@bufferX + \tabu@bufferX + \ifcase\tabu@nested % print out (outer in mode 0) + \global\tabu@cnt \tabu@cnt + \tabu@evr{\tabu@verticaldynamicadjustment}% + \tabu@celllalign@def{\everypar{}}\let\tabu@cellralign \@empty + \let\@finalstrut \tabu@finalstrut + \else % vertical measure of nested tabu + \tabu@evr{\tabu@verticalinit}% + \tabu@celllalign@def{\tabu@verticalmeasure}% + \def\tabu@cellralign{\tabu@verticalspacing}% + \fi + \tabu@clckpt \let\@halignto \tabu@halignto + \let\@halignto \@empty + \tabu@seteverycr + \ifdim \tabustrutrule>\z@ \ifnum\tabu@nested=\z@ + \setbox\@arstrutbox \box\voidb@x % force \@arstrutbox to be rebuilt (visible struts) + \fi\fi +}% \tabu@closetrialsgroup +\def\tabu@quickend {\expandafter \endgroup \expandafter + \tabu@target \the\tabu@target \tabu@quickrule + \let\endarray \relax \tabu@endenvir +}% \tabu@quickend +\def\tabu@endtrial {\relax % stops \count@ assignment ! + \ifcase \count@ \tabu@err % case 0 = impossible here + \or \tabu@err % case 1 = impossible here + \or \tabu@err % case 2 = impossible here + \or % case 3 = outer goes into mode 0 + \def\tabu@bufferX{\endgroup}\count@ \z@ + \else % case 4 = outer goes into mode 3 + \iftabu@spread \tabu@spreadarith % inner into mode 1 (outer in mode 3) + \else \tabu@arith % or 2 (outer in mode 4) + \fi + \count@=% + \ifcase\tabu@nested \thr@@ % outer goes into mode 3 + \else\iftabu@measuring \tw@ % outer is in mode 4 + \else \@ne % outer is in mode 3 + \fi\fi + \edef\tabu@bufferX{\endgroup + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% + \fi + \expandafter \tabu@bufferX \expandafter + \count@ \the\count@ \tabu@strategy +}% \tabu@endtrial +\def\tabu@err{\errmessage{(tabu) Internal impossible error! (\count@=\the\count@)}} +%% The algorithms: compute the widths / stop or go on --------------- +\def\tabu@arithnegcoef {% + \@tempdima \z@ \dimen@ \z@ \let\tabu@ \tabu@arith@negcoef \tabu@Xcoefs +}% \tabu@arithnegcoef +\def\tabu@arith@negcoef #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ % saturated by definition + \advance\@tempdima #2\tabucolX + \else + \ifdim -#2\tabucolX <\tabu@wd{#1}% c_i X < natural width <= \tabu@target-> saturated + \advance\dimen@ -#2\p@ + \advance\@tempdima -#2\tabucolX + \else + \advance\@tempdima \tabu@wd{#1}% natural width <= c_i X => neutralised + \ifdim \tabu@wd{#1}<\tabu@target \else % neutralised + \advance\dimen@ -#2\p@ % saturated (natural width = tabu@target) + \fi + \fi + \fi +}% \tabu@arith@negcoef +\def\tabu@givespace #1#2{% here \tabu@DELTA < \z@ + \ifdim \@tempdima=\z@ + \tabu@wddef{#1}{\the\dimexpr -\tabu@DELTA*\p@/\tabu@Xsum}% + \else + \tabu@wddef{#1}{\the\dimexpr \tabu@hsize{#1}{#2} + *(\p@ -\tabu@DELTA*\p@/\@tempdima)/\p@\relax}% + \fi +}% \tabu@givespace +\def\tabu@arith {\advance\tabu@cnt \@ne + \ifnum \tabu@cnt=\@ne \tabu@message{\tabu@titles}\fi + \tabu@arithnegcoef + \@tempdimb \dimexpr \wd\tabu@box -\@tempdima \relax % + \tabu@DELTA = \dimexpr \wd\tabu@box - \tabu@target \relax + \tabu@message{\tabu@message@arith}% + \ifdim \tabu@DELTA <\tabu@hfuzz + \ifdim \tabu@DELTA<\z@ % wd (tabu)<\tabu@target ? + \let\tabu@ \tabu@givespace \tabu@Xcoefs + \advance\@tempdima \@tempdimb \advance\@tempdima -\tabu@DELTA % for message + \else % already converged: nothing to do but nearly impossible... + \fi + \tabucolX \maxdimen + \tabu@measuringfalse + \else % need for narrower X columns + \tabucolX =\dimexpr (\@tempdima -\tabu@DELTA) *\p@/\tabu@Xsum \relax + \tabu@measuringtrue + \@whilesw \iftabu@measuring\fi {% + \advance\tabu@cnt \@ne + \tabu@arithnegcoef + \tabu@DELTA =\dimexpr \@tempdima+\@tempdimb -\tabu@target \relax % always < 0 here + \tabu@message{\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \@tempdima+\@tempdimb { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim -\tabu@DELTA<\tabu@hfuzz \tabu@spaces target ok\else + \tabu@msgalign \dimexpr -\tabu@DELTA *\p@/\dimen@ {}{}{}{}{}\@@ + \fi}% + \ifdim -\tabu@DELTA<\tabu@hfuzz + \advance\@tempdima \@tempdimb % for message + \tabu@measuringfalse + \else + \advance\tabucolX \dimexpr -\tabu@DELTA *\p@/\dimen@ \relax + \fi + }% + \fi + \tabu@message{\tabu@message@reached}% + \edef\tabu@bufferX{\endgroup \tabu@cnt \the\tabu@cnt + \tabucolX \the\tabucolX + \tabu@target \the\tabu@target}% +}% \tabu@arith +\def\tabu@spreadarith {% + \dimen@ \z@ \@tempdima \tabu@naturalXmax \let\tabu@ \tabu@spread@arith \tabu@Xcoefs + \edef\tabu@naturalXmin {\the\dimexpr\tabu@naturalXmin*\dimen@/\p@}% + \@tempdimc =\dimexpr \wd\tabu@box -\tabu@naturalXmax+\tabu@naturalXmin \relax + \iftabu@measuring + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \edef\tabu@bufferX{\endgroup \tabucolX \the\tabucolX \tabu@target\the\tabu@target}% + \else + \tabu@message{\tabu@message@spreadarith}% + \ifdim \dimexpr \@tempdimc+\tabu@spreadtarget >\tabu@target + \tabu@message{(tabu) spread + \ifdim \@tempdimc>\tabu@target useless here: default target used% + \else too large: reduced to fit default target\fi.}% + \else + \tabu@target =\dimexpr \@tempdimc+\tabu@spreadtarget \relax + \tabu@message{(tabu) spread: New target set to \the\tabu@target^^J}% + \fi + \begingroup \let\tabu@wddef \@gobbletwo + \@tempdimb \@tempdima + \tabucolX@init + \tabu@arithnegcoef + \wd\tabu@box =\dimexpr \wd\tabu@box +\@tempdima-\@tempdimb \relax + \expandafter\endgroup \expandafter\tabucolX \the\tabucolX + \tabu@arith + \fi +}% \tabu@spreadarith +\def\tabu@spread@arith #1#2{% + \ifdim #2\p@>\z@ \advance\dimen@ #2\p@ + \else \advance\@tempdima \tabu@wd{#1}\relax + \fi +}% \tabu@spread@arith +%% Reporting in the .log file --------------------------------------- +\def\tabu@message@defaulttarget{% + \ifnum\tabu@nested=\z@^^J(tabu) Default target: + \ifx\tabudefaulttarget\linewidth \string\linewidth + \ifdim \tabu@thetarget=\linewidth \else + -\the\dimexpr\linewidth-\tabu@thetarget\fi = + \else\ifx\tabudefaulttarget\linegoal\string\linegoal= + \fi\fi + \else (tabu) Default target (nested): \fi + \the\tabu@target \on@line + \ifnum\tabu@nested=\z@ , page \the\c@page\fi} +\def\tabu@message@target {^^J(tabu) Target specified: + \the\tabu@target \on@line, page \the\c@page} +\def\tabu@message@arith {\tabu@header + \tabu@msgalign \tabucolX { }{ }{ }{ }{ }\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{ }\@@ + \tabu@msgalign \tabu@target { }{ }{ }{ }{ }\@@ + \tabu@msgalign@PT \dimen@ { }{}{}{}{}{}{}\@@ + \ifdim \tabu@DELTA<\tabu@hfuzz giving space\else + \tabu@msgalign \dimexpr (\@tempdima-\tabu@DELTA) *\p@/\tabu@Xsum -\tabucolX {}{}{}{}{}\@@ + \fi +}% \tabu@message@arith +\def\tabu@message@spreadarith {\tabu@spreadheader + \tabu@msgalign \tabu@spreadtarget { }{ }{ }{ }{}\@@ + \tabu@msgalign \wd\tabu@box { }{ }{ }{ }{}\@@ + \tabu@msgalign -\tabu@naturalXmax { }{}{}{}{}\@@ + \tabu@msgalign \tabu@naturalXmin { }{ }{ }{ }{}\@@ + \tabu@msgalign \ifdim \dimexpr\@tempdimc>\tabu@target \tabu@target + \else \@tempdimc+\tabu@spreadtarget \fi + {}{}{}{}{}\@@} +\def\tabu@message@negcoef #1#2{ + \tabu@spaces\tabu@spaces\space * #1. X[\rem@pt#2]: + \space width = \tabu@wd {#1} + \expandafter\string\csname tabu@\the\tabu@nested.W\number#1\endcsname + \ifdim -\tabu@pt#2\tabucolX<\tabu@target + < \number-\rem@pt#2 X + = \the\dimexpr -\tabu@pt#2\tabucolX \relax + \else + <= \the\tabu@target\space < \number-\rem@pt#2 X\fi} +\def\tabu@message@reached{\tabu@header + ******* Reached Target: + hfuzz = \tabu@hfuzz\on@line\space *******} +\def\tabu@message@etime{\edef\tabu@stoptime{\the\pdfelapsedtime}% + \tabu@message{(tabu)\tabu@spaces Time elapsed during measure: + \the\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax sec + \the\numexpr\numexpr(\tabu@stoptime-\tabu@starttime) + -\numexpr(\tabu@stoptime-\tabu@starttime-32767)/65536\relax*65536\relax + *1000/65536\relax ms \tabu@spaces(\the\tabu@cnt\space + cycle\ifnum\tabu@cnt>\@ne s\fi)^^J^^J}} +\def\tabu@message@verticalsp {% + \ifdim \@tempdima>\tabu@ht + \ifdim \@tempdimb>\tabu@dp + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@ + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J% + \else + \expandafter\expandafter\expandafter\string\tabu@ht = + \tabu@msgalign \@tempdima { }{ }{ }{ }{ }\@@^^J% + \fi + \else\ifdim \@tempdimb>\tabu@dp + \tabu@spaces\tabu@spaces\tabu@spaces + \expandafter\expandafter\expandafter\string\tabu@dp = + \tabu@msgalign \@tempdimb { }{ }{ }{ }{ }\@@^^J\fi + \fi +}% \tabu@message@verticalsp +\edef\tabu@spaces{\@spaces} +\def\tabu@strippt{\expandafter\tabu@pt\the} +{\@makeother\P \@makeother\T\lowercase{\gdef\tabu@pt #1PT{#1}}} +\def\tabu@msgalign{\expandafter\tabu@msg@align\the\dimexpr} +\def\tabu@msgalign@PT{\expandafter\tabu@msg@align\romannumeral-`\0\tabu@strippt} +\def\do #1{% + \def\tabu@msg@align##1.##2##3##4##5##6##7##8##9\@@{% + \ifnum##1<10 #1 #1\else + \ifnum##1<100 #1 \else + \ifnum##1<\@m #1\fi\fi\fi + ##1.##2##3##4##5##6##7##8#1}% + \def\tabu@header{(tabu) \ifnum\tabu@cnt<10 #1\fi\the\tabu@cnt) }% + \def\tabu@titles{\ifnum \tabu@nested=\z@ + (tabu) Try#1 #1 tabu X #1 #1 #1tabu Width #1 #1 Target + #1 #1 #1 Coefs #1 #1 #1 Update^^J\fi}% + \def\tabu@spreadheader{% + (tabu) Try#1 #1 Spread #1 #1 tabu Width #1 #1 #1 Nat. X #1 #1 #1 #1Nat. Min. + #1 New Target^^J% + (tabu) sprd} + \def\tabu@message@save {\begingroup + \def\x ####1{\tabu@msg@align ####1{ }{ }{ }{ }{}\@@} + \def\z ####1{\expandafter\x\expandafter{\romannumeral-`\0\tabu@strippt + \dimexpr####1\p@{ }{ }}}% + \let\color \relax \def\tabu@rulesstyle ####1####2{\detokenize{####1}}% + \let\CT@arc@ \relax \let\@preamble \@gobble + \let\tabu@savedpream \@firstofone + \let\tabu@savedparams \@firstofone + \def\tabu@target ####1\relax {(tabu) target #1 #1 #1 #1 #1 = \x{####1}^^J}% + \def\tabucolX ####1\relax {(tabu) X columns width#1 = \x{####1}^^J}% + \def\tabu@nbcols ####1\relax {(tabu) Number of columns: \z{####1}^^J}% + \def\tabu@aligndefault ####1{(tabu) Default alignment: #1 #1 ####1^^J}% + \def\col@sep ####1\relax {(tabu) column sep #1 #1 #1 = \x{####1}^^J}% + \def\arrayrulewidth ####1\relax{(tabu) arrayrulewidth #1 = \x{####1}}% + \def\doublerulesep ####1\relax { doublerulesep = \x{####1}^^J}% + \def\extratabsurround####1\relax{(tabu) extratabsurround = \x{####1}^^J}% + \def\extrarowheight ####1\relax{(tabu) extrarowheight #1 = \x{####1}}% + \def\extrarowdepth ####1\relax {extrarowdepth = \x{####1}^^J}% + \def\abovetabulinesep####1\relax{(tabu) abovetabulinesep=\x{####1} }% + \def\belowtabulinesep####1\relax{ belowtabulinesep=\x{####1}^^J}% + \def\arraystretch ####1{(tabu) arraystretch #1 #1 = \z{####1}^^J}% + \def\minrowclearance####1\relax{(tabu) minrowclearance #1 = \x{####1}^^J}% + \def\tabu@arc@L ####1{(tabu) taburulecolor #1 #1 = ####1^^J}% + \def\tabu@drsc@L ####1{(tabu) tabudoublerulecolor= ####1^^J}% + \def\tabu@evr@L ####1{(tabu) everyrow #1 #1 #1 #1 = \detokenize{####1}^^J}% + \def\tabu@ls@L ####1{(tabu) line style = \detokenize{####1}^^J}% + \def\NC@find ####1\@nil{(tabu) tabu preamble#1 #1 = \detokenize{####1}^^J}% + \def\tabu@wddef####1####2{(tabu) Natural width ####1 = \x{####2}^^J}% + \let\edef \@gobbletwo \let\def \@empty \let\let \@gobbletwo + \tabu@message{% + (tabu) \string\savetabu{\tabu@temp}: \on@line^^J% + \tabu@usetabu \@nil^^J}% + \endgroup} +}\do{ } +%% Measuring the natural width (varwidth) - store the results ------- +\def\tabu@startpboxmeasure #1{\bgroup % entering \vtop + \edef\tabu@temp{\expandafter\@secondoftwo \ifx\tabu@hsize #1\else\relax\fi}% + \ifodd 1\ifx \tabu@temp\@empty 0 \else % starts with \tabu@hsize ? + \iftabu@spread \else % if spread -> measure + \ifdim \tabu@temp\p@>\z@ 0 \fi\fi\fi% if coef>0 -> do not measure + \let\@startpbox \tabu@startpboxORI % restore immediately (nesting) + \tabu@measuringtrue % for the quick option... + \tabu@Xcol =\expandafter\@firstoftwo\ifx\tabu@hsize #1\fi + \ifdim \tabu@temp\p@>\z@ \ifdim \tabu@temp\tabucolX<\tabu@target + \tabu@target=\tabu@temp\tabucolX \fi\fi + \setbox\tabu@box \hbox \bgroup + \begin{varwidth}\tabu@target + \let\FV@ListProcessLine \tabu@FV@ListProcessLine % \hbox to natural width... + \narrowragged \arraybackslash \parfillskip \@flushglue + \ifdefined\pdfadjustspacing \pdfadjustspacing\z@ \fi + \bgroup \aftergroup\tabu@endpboxmeasure + \ifdefined \cellspacetoplimit \tabu@cellspacepatch \fi + \else \expandafter\@gobble + \tabu@startpboxquick{#1}% \@gobble \bgroup + \fi +}% \tabu@startpboxmeasure +\def\tabu@cellspacepatch{\def\bcolumn##1\@nil{}\let\ecolumn\@empty + \bgroup\color@begingroup} +\def\tabu@endpboxmeasure {% + \@finalstrut \@arstrutbox + \end{varwidth}\egroup % + \ifdim \tabu@temp\p@ <\z@ % neg coef + \ifdim \tabu@wd\tabu@Xcol <\wd\tabu@box + \tabu@wddef\tabu@Xcol {\the\wd\tabu@box}% + \tabu@debug{\tabu@message@endpboxmeasure}% + \fi + \else % spread coef>0 + \global\advance \tabu@naturalX \wd\tabu@box + \@tempdima =\dimexpr \wd\tabu@box *\p@/\dimexpr \tabu@temp\p@\relax \relax + \ifdim \tabu@naturalXmax <\tabu@naturalX + \xdef\tabu@naturalXmax {\the\tabu@naturalX}\fi + \ifdim \tabu@naturalXmin <\@tempdima + \xdef\tabu@naturalXmin {\the\@tempdima}\fi + \fi + \box\tabu@box \egroup % end of \vtop (measure) restore \tabu@target +}% \tabu@endpboxmeasure +\def\tabu@wddef #1{\expandafter\xdef + \csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@wd #1{\csname tabu@\the\tabu@nested.W\number#1\endcsname} +\def\tabu@message@endpboxmeasure{\tabu@spaces\tabu@spaces<-> % <-> save natural wd + \the\tabu@Xcol. X[\tabu@temp]: + target = \the\tabucolX \space + \expandafter\expandafter\expandafter\string\tabu@wd\tabu@Xcol + =\tabu@wd\tabu@Xcol +}% \tabu@message@endpboxmeasure +\def\tabu@startpboxquick {\bgroup + \let\@startpbox \tabu@startpboxORI % restore immediately + \let\tabu \tabu@quick % \begin is expanded before... + \expandafter\@gobble \@startpbox % gobbles \bgroup +}% \tabu@startpboxquick +\def\tabu@quick {\begingroup \iffalse{\fi \ifnum0=`}\fi + \toks@{}\def\tabu@stack{b}\tabu@collectbody \tabu@endquick +}% \tabu@quick +\def\tabu@endquick {% + \ifodd 1\ifx\tabu@end@envir\tabu@endtabu \else + \ifx\tabu@end@envir\tabu@endtabus \else 0\fi\fi\relax + \endgroup + \else \let\endtabu \relax + \tabu@end@envir + \fi +}% \tabu@quick +\def\tabu@endtabu {\end{tabu}} +\def\tabu@endtabus {\end{tabu*}} +%% Measuring the heights and depths - store the results ------------- +\def\tabu@verticalmeasure{\everypar{}% + \ifnum \currentgrouptype>12 % 14=semi-simple, 15=math shift group + \setbox\tabu@box =\hbox\bgroup + \let\tabu@verticalspacing \tabu@verticalsp@lcr + \d@llarbegin % after \hbox ... + \else + \edef\tabu@temp{\ifnum\currentgrouptype=5\vtop + \else\ifnum\currentgrouptype=12\vcenter + \else\vbox\fi\fi}% + \setbox\tabu@box \hbox\bgroup$\tabu@temp \bgroup + \let\tabu@verticalspacing \tabu@verticalsp@pmb + \fi +}% \tabu@verticalmeasure +\def\tabu@verticalsp@lcr{% + \d@llarend \egroup % + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \noindent\vrule height\@tempdima depth\@tempdimb +}% \tabu@verticalsp@lcr +\def\tabu@verticalsp@pmb{% inserts struts as needed + \par \expandafter\egroup + \expandafter$\expandafter + \egroup \expandafter + \@tempdimc \the\prevdepth + \@tempdima \dimexpr \ht\tabu@box+\abovetabulinesep + \@tempdimb \dimexpr \dp\tabu@box+\belowtabulinesep \relax + \ifdim\tabustrutrule>\z@ \tabu@debug{\tabu@message@verticalsp}\fi + \ifdim \tabu@ht<\@tempdima \tabu@htdef{\the\@tempdima}\fi + \ifdim \tabu@dp<\@tempdimb \tabu@dpdef{\the\@tempdimb}\fi + \let\@finalstrut \@gobble + \hrule height\@tempdima depth\@tempdimb width\hsize +%% \box\tabu@box +}% \tabu@verticalsp@pmb + +\def\tabu@verticalinit{% + \ifnum \c@taburow=\z@ \tabu@rearstrut \fi % after \tabu@reset ! + \advance\c@taburow \@ne + \tabu@htdef{\the\ht\@arstrutbox}\tabu@dpdef{\the\dp\@arstrutbox}% + \advance\c@taburow \m@ne +}% \tabu@verticalinit +\def\tabu@htdef {\expandafter\xdef \csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@ht {\csname tabu@\the\tabu@nested.H\the\c@taburow\endcsname} +\def\tabu@dpdef {\expandafter\xdef \csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@dp {\csname tabu@\the\tabu@nested.D\the\c@taburow\endcsname} +\def\tabu@verticaldynamicadjustment {% + \advance\c@taburow \@ne + \extrarowheight \dimexpr\tabu@ht - \ht\strutbox + \extrarowdepth \dimexpr\tabu@dp - \dp\strutbox + \let\arraystretch \@empty + \advance\c@taburow \m@ne +}% \tabu@verticaldynamicadjustment +\def\tabuphantomline{\crcr \noalign{% + {\globaldefs \@ne + \setbox\@arstrutbox \box\voidb@x + \let\tabu@@celllalign \tabu@celllalign + \let\tabu@@cellralign \tabu@cellralign + \let\tabu@@cellleft \tabu@cellleft + \let\tabu@@cellright \tabu@cellright + \let\tabu@@thevline \tabu@thevline + \let\tabu@celllalign \@empty + \let\tabu@cellralign \@empty + \let\tabu@cellright \@empty + \let\tabu@cellleft \@empty + \let\tabu@thevline \relax}% + \edef\tabu@temp{\tabu@multispan \tabu@nbcols{\noindent &}}% + \toks@\expandafter{\tabu@temp \noindent\tabu@everyrowfalse \cr + \noalign{\tabu@rearstrut + {\globaldefs\@ne + \let\tabu@celllalign \tabu@@celllalign + \let\tabu@cellralign \tabu@@cellralign + \let\tabu@cellleft \tabu@@cellleft + \let\tabu@cellright \tabu@@cellright + \let\tabu@thevline \tabu@@thevline}}}% + \expandafter}\the\toks@ +}% \tabuphantomline +%% \firsthline and \lasthline corrections --------------------------- +\def\tabu@firstline {\tabu@hlineAZ \tabu@firsthlinecorrection {}} +\def\tabu@firsthline{\tabu@hlineAZ \tabu@firsthlinecorrection \hline} +\def\tabu@lastline {\tabu@hlineAZ \tabu@lasthlinecorrection {}} +\def\tabu@lasthline {\tabu@hlineAZ \tabu@lasthlinecorrection \hline} +\def\tabu@hline {% replaces \hline if no colortbl (see \AtBeginDocument) + \noalign{\ifnum0=`}\fi + {\CT@arc@\hrule height\arrayrulewidth}% + \futurelet \tabu@temp \tabu@xhline +}% \tabu@hline +\def\tabu@xhline{% + \ifx \tabu@temp \hline + {\ifx \CT@drsc@\relax \vskip + \else\ifx \CT@drsc@\@empty \vskip + \else \CT@drsc@\hrule height + \fi\fi + \doublerulesep}% + \fi + \ifnum0=`{\fi}% +}% \tabu@xhline +\def\tabu@hlineAZ #1#2{\noalign{\ifnum0=`}\fi \dimen@ \z@ \count@ \z@ + \toks@{}\def\tabu@hlinecorrection{#1}\def\tabu@temp{#2}% + \tabu@hlineAZsurround +}% \tabu@hlineAZ +\newcommand*\tabu@hlineAZsurround[1][\extratabsurround]{% + \extratabsurround #1\let\tabucline \tabucline@scan + \let\hline \tabu@hlinescan \let\firsthline \hline + \let\cline \tabu@clinescan \let\lasthline \hline + \expandafter \futurelet \expandafter \tabu@temp + \expandafter \tabu@nexthlineAZ \tabu@temp +}% \tabu@hlineAZsurround +\def\tabu@hlinescan {\tabu@thick \arrayrulewidth \tabu@xhlineAZ \hline} +\def\tabu@clinescan #1{\tabu@thick \arrayrulewidth \tabu@xhlineAZ {\cline{#1}}} +\def\tabucline@scan{\@testopt \tabucline@sc@n {}} +\def\tabucline@sc@n #1[#2]{\tabu@xhlineAZ {\tabucline[{#1}]{#2}}} +\def\tabu@nexthlineAZ{% + \ifx \tabu@temp\hline \else + \ifx \tabu@temp\cline \else + \ifx \tabu@temp\tabucline \else + \tabu@hlinecorrection + \fi\fi\fi +}% \tabu@nexthlineAZ +\def\tabu@xhlineAZ #1{% + \toks@\expandafter{\the\toks@ #1}% + \@tempdimc \tabu@thick % The last line width + \ifcase\count@ \@tempdimb \tabu@thick % The first line width + \else \advance\dimen@ \dimexpr \tabu@thick+\doublerulesep \relax + \fi + \advance\count@ \@ne \futurelet \tabu@temp \tabu@nexthlineAZ +}% \tabu@xhlineAZ +\def\tabu@firsthlinecorrection{% \count@ = number of \hline -1 + \@tempdima \dimexpr \ht\@arstrutbox+\dimen@ + \edef\firsthline{% + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + height \the\dimexpr\@tempdima+\extratabsurround + depth \dp\@arstrutbox + width \tabustrutrule}\hss}\cr + \noalign{\vskip -\the\dimexpr \@tempdima+\@tempdimb + +\dp\@arstrutbox \relax}% + \the\toks@ + }\ifnum0=`{\fi + \expandafter}\firsthline % we are then ! +}% \tabu@firsthlinecorrection +\def\tabu@lasthlinecorrection{% + \@tempdima \dimexpr \dp\@arstrutbox+\dimen@+\@tempdimb+\@tempdimc + \edef\lasthline{% + \the\toks@ + \noalign{\vskip -\the\dimexpr\dimen@+\@tempdimb+\dp\@arstrutbox}% + \omit \hbox to\z@{\hss{\noexpand\tabu@DBG{yellow}\vrule + depth \the\dimexpr \dp\@arstrutbox+\@tempdimb+\dimen@ + +\extratabsurround-\@tempdimc + height \z@ + width \tabustrutrule}\hss}\cr + }\ifnum0=`{\fi + \expandafter}\lasthline % we are then ! +}% \tabu@lasthlinecorrection +\def\tabu@LT@@hline{% + \ifx\LT@next\hline + \global\let\LT@next \@gobble + \ifx \CT@drsc@\relax + \gdef\CT@LT@sep{% + \noalign{\penalty-\@medpenalty\vskip\doublerulesep}}% + \else + \gdef\CT@LT@sep{% + \multispan\LT@cols{% + \CT@drsc@\leaders\hrule\@height\doublerulesep\hfill}\cr}% + \fi + \else + \global\let\LT@next\empty + \gdef\CT@LT@sep{% + \noalign{\penalty-\@lowpenalty\vskip-\arrayrulewidth}}% + \fi + \ifnum0=`{\fi}% + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \CT@LT@sep + \multispan\LT@cols + {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr + \noalign{\penalty\@M}% + \LT@next +}% \tabu@LT@@hline +%% Horizontal lines : \tabucline ------------------------------------ +\let\tabu@start \@tempcnta +\let\tabu@stop \@tempcntb +\newcommand*\tabucline{\noalign{\ifnum0=`}\fi \tabu@cline} +\newcommand*\tabu@cline[2][]{\tabu@startstop{#2}% + \ifnum \tabu@stop<\z@ \toks@{}% + \else \tabu@clinearg{#1}\tabu@thestyle + \edef\tabucline{\toks@{% + \ifnum \tabu@start>\z@ \omit + \tabu@multispan\tabu@start {\span\omit}&\fi + \omit \tabu@multispan\tabu@stop {\span\omit}% + \tabu@thehline\cr + }}\tabucline + \tabu@tracinglines{(tabu:tabucline) Style: #1^^J\the\toks@^^J^^J}% + \fi + \futurelet \tabu@temp \tabu@xcline +}% \tabu@cline +\def\tabu@clinearg #1{% + \ifx\\#1\\\let\tabu@thestyle \tabu@ls@ + \else \@defaultunits \expandafter\let\expandafter\@tempa + \romannumeral-`\0#1\relax \@nnil + \ifx \hbox\@tempa \tabu@clinebox{#1}% + \else\ifx \box\@tempa \tabu@clinebox{#1}% + \else\ifx \vbox\@tempa \tabu@clinebox{#1}% + \else\ifx \vtop\@tempa \tabu@clinebox{#1}% + \else\ifx \copy\@tempa \tabu@clinebox{#1}% + \else\ifx \leaders\@tempa \tabu@clineleads{#1}% + \else\ifx \cleaders\@tempa \tabu@clineleads{#1}% + \else\ifx \xleaders\@tempa \tabu@clineleads{#1}% + \else\tabu@getline {#1}% + \fi\fi\fi\fi\fi\fi\fi\fi + \fi +}% \tabu@clinearg +\def\tabu@clinebox #1{\tabu@clineleads{\xleaders#1\hss}} +\def\tabu@clineleads #1{% + \let\tabu@thestyle \relax \let\tabu@leaders \@undefined + \gdef\tabu@thehrule{#1}} +\def\tabu@thehline{\begingroup + \ifdefined\tabu@leaders + \noexpand\tabu@thehleaders + \else \noexpand\tabu@thehrule + \fi \endgroup +}% \tabu@thehline +\def\tabu@xcline{% + \ifx \tabu@temp\tabucline + \toks@\expandafter{\the\toks@ \noalign + {\ifx\CT@drsc@\relax \vskip + \else \CT@drsc@\hrule height + \fi + \doublerulesep}}% + \fi + \tabu@docline +}% \tabu@xcline +\def\tabu@docline {\ifnum0=`{\fi \expandafter}\the\toks@} +\def\tabu@docline@evr {\xdef\tabu@doclineafter{\the\toks@}% + \ifnum0=`{\fi}\aftergroup\tabu@doclineafter} +\def\tabu@multispan #1#2{% + \ifnum\numexpr#1>\@ne #2\expandafter\tabu@multispan + \else \expandafter\@gobbletwo + \fi {#1-1}{#2}% +}% \tabu@multispan +\def\tabu@startstop #1{\tabu@start@stop #1\relax 1-\tabu@nbcols \@nnil} +\def\tabu@start@stop #1-#2\@nnil{% + \@defaultunits \tabu@start\number 0#1\relax \@nnil + \@defaultunits \tabu@stop \number 0#2\relax \@nnil + \tabu@stop \ifnum \tabu@start>\tabu@nbcols \m@ne + \else\ifnum \tabu@stop=\z@ \tabu@nbcols + \else\ifnum \tabu@stop>\tabu@nbcols \tabu@nbcols + \else \tabu@stop + \fi\fi\fi + \advance\tabu@start \m@ne + \ifnum \tabu@start>\z@ \advance\tabu@stop -\tabu@start \fi +}% \tabu@start@stop +%% Numbers: siunitx S columns (and \tabudecimal) ------------------- +\def\tabu@tabudecimal #1{% + \def\tabu@decimal{#1}\@temptokena{}% + \let\tabu@getdecimal@ \tabu@getdecimal@ignorespaces + \tabu@scandecimal +}% \tabu@tabudecimal +\def\tabu@scandecimal{\futurelet \tabu@temp \tabu@getdecimal@} +\def\tabu@skipdecimal#1{#1\tabu@scandecimal} +\def\tabu@getdecimal@ignorespaces{% + \ifcase 0\ifx\tabu@temp\ignorespaces\else + \ifx\tabu@temp\@sptoken1\else + 2\fi\fi\relax + \let\tabu@getdecimal@ \tabu@getdecimal + \expandafter\tabu@skipdecimal + \or \expandafter\tabu@gobblespace\expandafter\tabu@scandecimal + \else \expandafter\tabu@skipdecimal + \fi +}% \tabu@getdecimal@ignorespaces +\def\tabu@get@decimal#1{\@temptokena\expandafter{\the\@temptokena #1}% + \tabu@scandecimal} +\def\do#1{% + \def\tabu@get@decimalspace#1{% + \@temptokena\expandafter{\the\@temptokena #1}\tabu@scandecimal}% +}\do{ } +\let\tabu@@tabudecimal \tabu@tabudecimal +\def\tabu@getdecimal{% + \ifcase 0\ifx 0\tabu@temp\else + \ifx 1\tabu@temp\else + \ifx 2\tabu@temp\else + \ifx 3\tabu@temp\else + \ifx 4\tabu@temp\else + \ifx 5\tabu@temp\else + \ifx 6\tabu@temp\else + \ifx 7\tabu@temp\else + \ifx 8\tabu@temp\else + \ifx 9\tabu@temp\else + \ifx .\tabu@temp\else + \ifx ,\tabu@temp\else + \ifx -\tabu@temp\else + \ifx +\tabu@temp\else + \ifx e\tabu@temp\else + \ifx E\tabu@temp\else + \ifx\tabu@cellleft\tabu@temp1\else + \ifx\ignorespaces\tabu@temp1\else + \ifx\@sptoken\tabu@temp2\else + 3\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\relax + \expandafter\tabu@get@decimal + \or \expandafter\tabu@skipdecimal + \or \expandafter\tabu@get@decimalspace + \else\expandafter\tabu@printdecimal + \fi +}% \tabu@getdecimal +\def\tabu@printdecimal{% + \edef\tabu@temp{\the\@temptokena}% + \ifx\tabu@temp\@empty\else + \ifx\tabu@temp\space\else + \expandafter\tabu@decimal\expandafter{\the\@temptokena}% + \fi\fi +}% \tabu@printdecimal +%% Verbatim inside X columns ---------------------------------------- +\def\tabu@verbatim{% + \let\verb \tabu@verb + \let\FV@DefineCheckEnd \tabu@FV@DefineCheckEnd +}% \tabu@verbatim +\let\tabu@ltx@verb \verb +\def\tabu@verb{\@ifstar {\tabu@ltx@verb*} \tabu@ltx@verb} +\def\tabu@fancyvrb {% + \def\tabu@FV@DefineCheckEnd ##1{% + \def\tabu@FV@DefineCheckEnd{% + ##1% + \let\FV@CheckEnd \tabu@FV@CheckEnd + \let\FV@@CheckEnd \tabu@FV@@CheckEnd + \let\FV@@@CheckEnd \tabu@FV@@@CheckEnd + \edef\FV@EndScanning{% + \def\noexpand\next{\noexpand\end{\FV@EnvironName}}% + \global\let\noexpand\FV@EnvironName\relax + \noexpand\next}% + \xdef\FV@EnvironName{\detokenize\expandafter{\FV@EnvironName}}}% + }\expandafter\tabu@FV@DefineCheckEnd\expandafter{\FV@DefineCheckEnd} +}% \tabu@fancyvrb +\def\tabu@FV@CheckEnd #1{\expandafter\FV@@CheckEnd \detokenize{#1\end{}}\@nil} +\edef\tabu@FV@@@CheckEnd {\detokenize{\end{}}} +\begingroup +\catcode`\[1 \catcode`\]2 +\@makeother\{ \@makeother\} + \edef\x[\endgroup + \def\noexpand\tabu@FV@@CheckEnd ##1\detokenize[\end{]##2\detokenize[}]##3% + ]\x \@nil{\def\@tempa{#2}\def\@tempb{#3}} +\def\tabu@FV@ListProcessLine #1{% + \hbox {%to \hsize{% + \kern\leftmargin + \hbox {%to \linewidth{% + \FV@LeftListNumber + \FV@LeftListFrame + \FancyVerbFormatLine{#1}\hss +%% DG/SR modification begin - Jan. 28, 1998 (for numbers=right add-on) +%% \FV@RightListFrame}% + \FV@RightListFrame + \FV@RightListNumber}% +%% DG/SR modification end + \hss}} +%% \savetabu -------------------------------------------------------- +\newcommand*\savetabu[1]{\noalign{% + \tabu@sanitizearg{#1}\tabu@temp + \ifx \tabu@temp\@empty \tabu@savewarn{}{The tabu will not be saved}\else + \@ifundefined{tabu@saved@\tabu@temp}{}{\tabu@savewarn{#1}{Overwriting}}% + \ifdefined\tabu@restored \expandafter\let + \csname tabu@saved@\tabu@temp \endcsname \tabu@restored + \else {\tabu@save}% + \fi + \fi}% +}% \savetabu +\def\tabu@save {% + \toks0\expandafter{\tabu@saved@}% + \iftabu@negcoef + \let\tabu@wddef \relax \let\tabu@ \tabu@savewd \edef\tabu@savewd{\tabu@Xcoefs}% + \toks0\expandafter{\the\toks\expandafter0\tabu@savewd}\fi + \toks1\expandafter{\tabu@savedpream}% + \toks2\expandafter{\tabu@savedpreamble}% + \let\@preamble \relax + \let\tabu@savedpream \relax \let\tabu@savedparams \relax + \edef\tabu@preamble{% + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \edef\tabu@usetabu{% + \def\@preamble {\noexpand\the\toks2}% + \tabu@target \the\tabu@target \relax + \tabucolX \the\tabucolX \relax + \tabu@nbcols \the\tabu@nbcols \relax + \def\noexpand\tabu@aligndefault{\tabu@align}% + \def\tabu@savedparams {\noexpand\the\toks0}% + \def\tabu@savedpream {\noexpand\the\toks1}}% + \let\tabu@aligndefault \relax \let\@sharp \relax + \edef\@tempa{\noexpand\tabu@s@ved + {\tabu@usetabu} + {\tabu@preamble} + {\the\toks1}}\@tempa + \tabu@message@save +}% \tabu@save +\long\def\tabu@s@ved #1#2#3{% + \def\tabu@usetabu{#1}% + \expandafter\gdef\csname tabu@saved@\tabu@temp\endcsname ##1{% + \ifodd ##1% \usetabu + \tabu@measuringfalse \tabu@spreadfalse % Just in case... + \gdef\tabu@usetabu {% + \ifdim \tabu@target>\z@ \tabu@warn@usetabu \fi + \global\let\tabu@usetabu \@undefined + \def\@halignto {to\tabu@target}% + #1% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \else % \preamble + \gdef\tabu@preamble {% + \global\let\tabu@preamble \@undefined + #2% + \ifx \tabu@align\tabu@aligndefault@text + \ifnum \tabu@nested=\z@ + \let\tabu@align \tabu@aligndefault \fi\fi}% + \fi + #3}% +}% \tabu@s@ved +\def\tabu@aligndefault@text {\tabu@aligndefault}% +\def\tabu@warn@usetabu {\PackageWarning{tabu} + {Specifying a target with \string\usetabu\space is useless + \MessageBreak The target cannot be changed!}} +\def\tabu@savewd #1#2{\ifdim #2\p@<\z@ \tabu@wddef{#1}{\tabu@wd{#1}}\fi} +\def\tabu@savewarn#1#2{\PackageInfo{tabu} + {User-name `#1' already used for \string\savetabu + \MessageBreak #2}}% +\def\tabu@saveerr#1{\PackageError{tabu} + {User-name `#1' is unknown for \string\usetabu + \MessageBreak I cannot restore an unknown preamble!}\@ehd} +%% \rowfont --------------------------------------------------------- +\newskip \tabu@cellskip +\def\tabu@rowfont{\ifdim \baselineskip=\z@\noalign\fi + {\ifnum0=`}\fi \tabu@row@font} +\newcommand*\tabu@row@font[2][]{% + \ifnum7=\currentgrouptype + \global\let\tabu@@cellleft \tabu@cellleft + \global\let\tabu@@cellright \tabu@cellright + \global\let\tabu@@celllalign \tabu@celllalign + \global\let\tabu@@cellralign \tabu@cellralign + \global\let\tabu@@rowfontreset\tabu@rowfontreset + \fi + \global\let\tabu@rowfontreset \tabu@rowfont@reset + \expandafter\gdef\expandafter\tabu@cellleft\expandafter{\tabu@cellleft #2}% + \ifcsname tabu@cell@#1\endcsname % row alignment + \csname tabu@cell@#1\endcsname \fi + \ifnum0=`{\fi}% end of group / noalign group +}% \rowfont +\def\tabu@ifcolorleavevmode #1{\let\color \tabu@leavevmodecolor #1\let\color\tabu@color}% +\def\tabu@rowfont@reset{% + \global\let\tabu@rowfontreset \tabu@@rowfontreset + \global\let\tabu@cellleft \tabu@@cellleft + \global\let\tabu@cellright \tabu@@cellright + \global\let\tabu@cellfont \@empty + \global\let\tabu@celllalign \tabu@@celllalign + \global\let\tabu@cellralign \tabu@@cellralign +}% \tabu@@rowfontreset +\let\tabu@rowfontreset \@empty % overwritten \AtBeginDocument if colortbl +%% \tabu@prepnext@tok ----------------------------------------------- +\newif \iftabu@cellright +\def\tabu@prepnext@tok{% + \ifnum \count@<\z@ % + \@tempcnta \@M % + \tabu@nbcols\z@ + \let\tabu@fornoopORI \@fornoop + \tabu@cellrightfalse + \else + \ifcase \numexpr \count@-\@tempcnta \relax % (case 0): prev. token is left + \advance \tabu@nbcols \@ne + \iftabu@cellright % before-previous token is right and is finished + \tabu@cellrightfalse % + \tabu@righttok + \fi + \tabu@lefttok + \or % (case 1) previous token is right + \tabu@cellrighttrue \let\@fornoop \tabu@lastnoop + \else % special column: do not change the token + \iftabu@cellright % before-previous token is right + \tabu@cellrightfalse + \tabu@righttok + \fi + \fi % \ifcase + \fi + \tabu@prepnext@tokORI +}% \tabu@prepnext@tok +\long\def\tabu@lastnoop#1\@@#2#3{\tabu@lastn@@p #2\@nextchar \in@\in@@} +\def\tabu@lastn@@p #1\@nextchar #2#3\in@@{% + \ifx \in@#2\else + \let\@fornoop \tabu@fornoopORI + \xdef\tabu@mkpreambuffer{\tabu@nbcols\the\tabu@nbcols \tabu@mkpreambuffer}% + \toks0\expandafter{\expandafter\tabu@everyrowtrue \the\toks0}% + \expandafter\prepnext@tok + \fi +}% \tabu@lastnoop +\def\tabu@righttok{% + \advance \count@ \m@ne + \toks\count@\expandafter {\the\toks\count@ \tabu@cellright \tabu@cellralign}% + \advance \count@ \@ne +}% \tabu@righttok +\def\tabu@lefttok{\toks\count@\expandafter{\expandafter\tabu@celllalign + \the\toks\count@ \tabu@cellleft}% after because of $ +}% \tabu@lefttok +%% Neutralisation of glues ------------------------------------------ +\let\tabu@cellleft \@empty +\let\tabu@cellright \@empty +\tabu@celllalign@def{\tabu@cellleft}% +\let\tabu@cellralign \@empty +\def\tabu@cell@align #1#2#3{% + \let\tabu@maybesiunitx \toks@ \tabu@celllalign + \global \expandafter \tabu@celllalign@def \expandafter {\the\toks@ #1}% + \toks@\expandafter{\tabu@cellralign #2}% + \xdef\tabu@cellralign{\the\toks@}% + \toks@\expandafter{\tabu@cellleft #3}% + \xdef\tabu@cellleft{\the\toks@}% +}% \tabu@cell@align +\def\tabu@cell@l{% force alignment to left + \tabu@cell@align + {\tabu@removehfil \raggedright \tabu@cellleft}% left + {\tabu@flush1\tabu@ignorehfil}% right + \raggedright +}% \tabu@cell@l +\def\tabu@cell@c{% force alignment to center + \tabu@cell@align + {\tabu@removehfil \centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \centering +}% \tabu@cell@c +\def\tabu@cell@r{% force alignment to right + \tabu@cell@align + {\tabu@removehfil \raggedleft \tabu@flush1\tabu@cellleft} + \tabu@ignorehfil + \raggedleft +}% \tabu@cell@r +\def\tabu@cell@j{% force justification (for p, m, b columns) + \tabu@cell@align + {\tabu@justify\tabu@cellleft} + {} + \tabu@justify +}% \tabu@cell@j +\def\tabu@justify{% + \leftskip\z@skip \@rightskip\leftskip \rightskip\@rightskip + \parfillskip\@flushglue +}% \tabu@justify +%% ragged2e settings +\def\tabu@cell@L{% force alignment to left (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedRight \tabu@cellleft} + {\tabu@flush 1\tabu@ignorehfil} + \RaggedRight +}% \tabu@cell@L +\def\tabu@cell@C{% force alignment to center (ragged2e) + \tabu@cell@align + {\tabu@removehfil \Centering \tabu@flush{.5}\tabu@cellleft} + {\tabu@flush{.5}\tabu@ignorehfil} + \Centering +}% \tabu@cell@C +\def\tabu@cell@R{% force alignment to right (ragged2e) + \tabu@cell@align + {\tabu@removehfil \RaggedLeft \tabu@flush 1\tabu@cellleft} + \tabu@ignorehfil + \RaggedLeft +}% \tabu@cell@R +\def\tabu@cell@J{% force justification (ragged2e) + \tabu@cell@align + {\justifying \tabu@cellleft} + {} + \justifying +}% \tabu@cell@J +\def\tabu@flush#1{% + \iftabu@colortbl % colortbl uses \hfill rather than \hfil + \hskip \ifnum13<\currentgrouptype \stretch{#1}% + \else \ifdim#1pt<\p@ \tabu@cellskip + \else \stretch{#1} + \fi\fi \relax + \else % array.sty + \ifnum 13<\currentgrouptype + \hfil \hskip1sp \relax \fi + \fi +}% \tabu@flush +\let\tabu@hfil \hfil +\let\tabu@hfill \hfill +\let\tabu@hskip \hskip +\def\tabu@removehfil{% + \iftabu@colortbl + \unkern \tabu@cellskip =\lastskip + \ifnum\gluestretchorder\tabu@cellskip =\tw@ \hskip-\tabu@cellskip + \else \tabu@cellskip \z@skip + \fi + \else + \ifdim\lastskip=1sp\unskip\fi + \ifnum\gluestretchorder\lastskip =\@ne + \hfilneg % \hfilneg for array.sty but not for colortbl... + \fi + \fi +}% \tabu@removehfil +\def\tabu@ignorehfil{\aftergroup \tabu@nohfil} +\def\tabu@nohfil{% \hfil -> do nothing + restore original \hfil + \def\hfil{\let\hfil \tabu@hfil}% local to (alignment template) group +}% \tabu@nohfil +\def\tabu@colortblalignments {% if colortbl + \def\tabu@nohfil{% + \def\hfil {\let\hfil \tabu@hfil}% local to (alignment template) group + \def\hfill {\let\hfill \tabu@hfill}% (colortbl uses \hfill) pfff... + \def\hskip ####1\relax{\let\hskip \tabu@hskip}}% local +}% \tabu@colortblalignments +%% Taking care of footnotes and hyperfootnotes ---------------------- +\long\def\tabu@footnotetext #1{% + \edef\@tempa{\the\tabu@footnotes + \noexpand\footnotetext [\the\csname c@\@mpfn\endcsname]}% + \global\tabu@footnotes\expandafter{\@tempa {#1}}}% +\long\def\tabu@xfootnotetext [#1]#2{% + \global\tabu@footnotes\expandafter{\the\tabu@footnotes + \footnotetext [{#1}]{#2}}} +\let\tabu@xfootnote \@xfootnote +\long\def\tabu@Hy@ftntext{\tabu@Hy@ftntxt {\the \c@footnote }} +\long\def\tabu@Hy@xfootnote [#1]{% + \begingroup + \value\@mpfn #1\relax + \protected@xdef \@thefnmark {\thempfn}% + \endgroup + \@footnotemark \tabu@Hy@ftntxt {#1}% +}% \tabu@Hy@xfootnote +\long\def\tabu@Hy@ftntxt #1#2{% + \edef\@tempa{% + \the\tabu@footnotes + \begingroup + \value\@mpfn #1\relax + \noexpand\protected@xdef\noexpand\@thefnmark {\noexpand\thempfn}% + \expandafter \noexpand \expandafter + \tabu@Hy@footnotetext \expandafter{\Hy@footnote@currentHref}% + }% + \global\tabu@footnotes\expandafter{\@tempa {#2}% + \endgroup}% +}% \tabu@Hy@ftntxt +\long\def\tabu@Hy@footnotetext #1#2{% + \H@@footnotetext{% + \ifHy@nesting + \hyper@@anchor {#1}{#2}% + \else + \Hy@raisedlink{% + \hyper@@anchor {#1}{\relax}% + }% + \def\@currentHref {#1}% + \let\@currentlabelname \@empty + #2% + \fi + }% +}% \tabu@Hy@footnotetext +%% No need for \arraybackslash ! ------------------------------------ +\def\tabu@latextwoe {% +\def\tabu@temp##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@centering \centering \arraybackslash +\tabu@temp \tabu@raggedleft \raggedleft \arraybackslash +\tabu@temp \tabu@raggedright \raggedright \arraybackslash +}% \tabu@latextwoe +\def\tabu@raggedtwoe {% +\def\tabu@temp ##1##2##3{{\toks@\expandafter{##2##3}\xdef##1{\the\toks@}}} +\tabu@temp \tabu@Centering \Centering \arraybackslash +\tabu@temp \tabu@RaggedLeft \RaggedLeft \arraybackslash +\tabu@temp \tabu@RaggedRight \RaggedRight \arraybackslash +\tabu@temp \tabu@justifying \justifying \arraybackslash +}% \tabu@raggedtwoe +\def\tabu@normalcrbackslash{\let\\\@normalcr} +\def\tabu@trivlist{\expandafter\def\expandafter\@trivlist\expandafter{% + \expandafter\tabu@normalcrbackslash \@trivlist}} +%% Utilities: \fbox \fcolorbox and \tabudecimal ------------------- +\def\tabu@fbox {\leavevmode\afterassignment\tabu@beginfbox \setbox\@tempboxa\hbox} +\def\tabu@beginfbox {\bgroup \kern\fboxsep + \bgroup\aftergroup\tabu@endfbox} +\def\tabu@endfbox {\kern\fboxsep\egroup\egroup + \@frameb@x\relax} +\def\tabu@color@b@x #1#2{\leavevmode \bgroup + \def\tabu@docolor@b@x{#1{#2\color@block{\wd\z@}{\ht\z@}{\dp\z@}\box\z@}}% + \afterassignment\tabu@begincolor@b@x \setbox\z@ \hbox +}% \tabu@color@b@x +\def\tabu@begincolor@b@x {\kern\fboxsep \bgroup + \aftergroup\tabu@endcolor@b@x \set@color} +\def\tabu@endcolor@b@x {\kern\fboxsep \egroup + \dimen@\ht\z@ \advance\dimen@ \fboxsep \ht\z@ \dimen@ + \dimen@\dp\z@ \advance\dimen@ \fboxsep \dp\z@ \dimen@ + \tabu@docolor@b@x \egroup +}% \tabu@endcolor@b@x +%% Corrections (arydshln, delarray, colortbl) ----------------------- +\def\tabu@fix@arrayright {%% \@arrayright is missing from \endarray + \iftabu@colortbl + \ifdefined\adl@array % + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \CT@end \egroup % + \@arrayright % + \gdef\@preamble{}}% + \else % + \def\tabu@endarray{% + \crcr \egroup \egroup % + \@arrayright % + \gdef\@preamble{}\CT@end}% + \fi + \else + \ifdefined\adl@array % + \def\tabu@endarray{% + \adl@endarray \egroup \adl@arrayrestore \egroup % + \@arrayright % + \gdef\@preamble{}}% + \else % + \PackageWarning{tabu} + {\string\@arrayright\space is missing from the + \MessageBreak definition of \string\endarray. + \MessageBreak Compatibility with delarray.sty is broken.}% + \fi\fi +}% \tabu@fix@arrayright +\def\tabu@adl@xarraydashrule #1#2#3{% + \ifnum\@lastchclass=\adl@class@start\else + \ifnum\@lastchclass=\@ne\else + \ifnum\@lastchclass=5 \else % @-arg (class 5) and !-arg (class 1) + \adl@leftrulefalse \fi\fi % must be treated the same + \fi + \ifadl@zwvrule\else \ifadl@inactive\else + \@addtopreamble{\vrule\@width\arrayrulewidth + \@height\z@ \@depth\z@}\fi \fi + \ifadl@leftrule + \@addtopreamble{\adl@vlineL{\CT@arc@}{\adl@dashgapcolor}% + {\number#1}#3}% + \else \@addtopreamble{\adl@vlineR{\CT@arc@}{\adl@dashgapcolor}% + {\number#2}#3} + \fi +}% \tabu@adl@xarraydashrule +\def\tabu@adl@act@endpbox {% + \unskip \ifhmode \nobreak \fi \@finalstrut \@arstrutbox + \egroup \egroup + \adl@colhtdp \box\adl@box \hfil +}% \tabu@adl@act@endpbox +\def\tabu@adl@fix {% + \let\adl@xarraydashrule \tabu@adl@xarraydashrule % arydshln + \let\adl@act@endpbox \tabu@adl@act@endpbox % arydshln + \let\adl@act@@endpbox \tabu@adl@act@endpbox % arydshln + \let\@preamerror \@preamerr % arydshln +}% \tabu@adl@fix +%% Correction for longtable' \@startbox definition ------------------ +%% => \everypar is ``missing'' : TeX should be in vertical mode +\def\tabu@LT@startpbox #1{% + \bgroup + \let\@footnotetext\LT@p@ftntext + \setlength\hsize{#1}% + \@arrayparboxrestore + \everypar{% + \vrule \@height \ht\@arstrutbox \@width \z@ + \everypar{}}% +}% \tabu@LT@startpbox +%% \tracingtabu and the package options ------------------ +\DeclareOption{delarray}{\AtEndOfPackage{\RequirePackage{delarray}}} +\DeclareOption{linegoal}{% + \AtEndOfPackage{% + \RequirePackage{linegoal}[2010/12/07]% + \let\tabudefaulttarget \linegoal% \linegoal is \linewidth if not pdfTeX +}} +\DeclareOption{scantokens}{\tabuscantokenstrue} +\DeclareOption{debugshow}{\AtEndOfPackage{\tracingtabu=\tw@}} +\def\tracingtabu {\begingroup\@ifnextchar=% + {\afterassignment\tabu@tracing\count@} + {\afterassignment\tabu@tracing\count@1\relax}} +\def\tabu@tracing{\expandafter\endgroup + \expandafter\tabu@tr@cing \the\count@ \relax +}% \tabu@tracing +\def\tabu@tr@cing #1\relax {% + \ifnum#1>\thr@@ \let\tabu@tracinglines\message + \else \let\tabu@tracinglines\@gobble + \fi + \ifnum#1>\tw@ \let\tabu@DBG \tabu@@DBG + \def\tabu@mkarstrut {\tabu@DBG@arstrut}% + \tabustrutrule 1.5\p@ + \else \let\tabu@DBG \@gobble + \def\tabu@mkarstrut {\tabu@arstrut}% + \tabustrutrule \z@ + \fi + \ifnum#1>\@ne \let\tabu@debug \message + \else \let\tabu@debug \@gobble + \fi + \ifnum#1>\z@ + \let\tabu@message \message + \let\tabu@tracing@save \tabu@message@save + \let\tabu@starttimer \tabu@pdftimer + \else + \let\tabu@message \@gobble + \let\tabu@tracing@save \@gobble + \let\tabu@starttimer \relax + \fi +}% \tabu@tr@cing +%% Setup \AtBeginDocument +\AtBeginDocument{\tabu@AtBeginDocument} +\def\tabu@AtBeginDocument{\let\tabu@AtBeginDocument \@undefined + \ifdefined\arrayrulecolor \tabu@colortbltrue % + \tabu@colortblalignments % different glues are used + \else \tabu@colortblfalse \fi + \ifdefined\CT@arc@ \else \let\CT@arc@ \relax \fi + \ifdefined\CT@drsc@\else \let\CT@drsc@ \relax \fi + \let\tabu@arc@L \CT@arc@ \let\tabu@drsc@L \CT@drsc@ + \ifodd 1\ifcsname siunitx_table_collect_begin:Nn\endcsname % + \expandafter\ifx + \csname siunitx_table_collect_begin:Nn\endcsname\relax 0\fi\fi\relax + \tabu@siunitxtrue + \else \let\tabu@maybesiunitx \@firstofone % + \let\tabu@siunitx \tabu@nosiunitx + \tabu@siunitxfalse + \fi + \ifdefined\adl@array % + \else \let\tabu@adl@fix \relax + \let\tabu@adl@endtrial \@empty \fi + \ifdefined\longtable % + \else \let\longtabu \tabu@nolongtabu \fi + \ifdefined\cellspacetoplimit \tabu@warn@cellspace\fi + \csname\ifcsname ifHy@hyperfootnotes\endcsname % + ifHy@hyperfootnotes\else iffalse\fi\endcsname + \let\tabu@footnotetext \tabu@Hy@ftntext + \let\tabu@xfootnote \tabu@Hy@xfootnote \fi + \ifdefined\FV@DefineCheckEnd% + \tabu@fancyvrb \fi + \ifdefined\color % + \let\tabu@color \color + \def\tabu@leavevmodecolor ##1{% + \def\tabu@leavevmodecolor {\leavevmode ##1}% + }\expandafter\tabu@leavevmodecolor\expandafter{\color}% + \else + \let\tabu@color \tabu@nocolor + \let\tabu@leavevmodecolor \@firstofone \fi + \tabu@latextwoe + \ifdefined\@raggedtwoe@everyselectfont % + \tabu@raggedtwoe + \else + \let\tabu@cell@L \tabu@cell@l + \let\tabu@cell@R \tabu@cell@r + \let\tabu@cell@C \tabu@cell@c + \let\tabu@cell@J \tabu@cell@j \fi + \expandafter\in@ \expandafter\@arrayright \expandafter{\endarray}% + \ifin@ \let\tabu@endarray \endarray + \else \tabu@fix@arrayright \fi% + \everyrow{}% +}% \tabu@AtBeginDocument +\def\tabu@warn@cellspace{% + \PackageWarning{tabu}{% + Package cellspace has some limitations + \MessageBreak And redefines some macros of array.sty. + \MessageBreak Please use \string\tabulinesep\space to control + \MessageBreak vertical spacing of lines inside tabu environment}% +}% \tabu@warn@cellspace +%% tabu Package initialisation +\tabuscantokensfalse +\let\tabu@arc@G \relax +\let\tabu@drsc@G \relax +\let\tabu@evr@G \@empty +\let\tabu@rc@G \@empty +\def\tabu@ls@G {\tabu@linestyle@}% +\let\tabu@@rowfontreset \@empty % +\let\tabu@@celllalign \@empty +\let\tabu@@cellralign \@empty +\let\tabu@@cellleft \@empty +\let\tabu@@cellright \@empty +\def\tabu@naturalXmin {\z@} +\def\tabu@naturalXmax {\z@} +\let\tabu@rowfontreset \@empty +\def\tabulineon {4pt}\let\tabulineoff \tabulineon +\tabu@everyrowtrue +\ifdefined\pdfelapsedtime % + \def\tabu@pdftimer {\xdef\tabu@starttime{\the\pdfelapsedtime}}% +\else \let\tabu@pdftimer \relax \let\tabu@message@etime \relax +\fi +\tracingtabu=\z@ +\newtabulinestyle {=\maxdimen}% creates the 'factory' settings \tabu@linestyle@ +\tabulinestyle{} +\taburowcolors{} +\let\tabudefaulttarget \linewidth +\ProcessOptions* % \ProcessOptions* is quicker ! +\endinput +%% +%% End of file `tabu.sty'. diff --git a/doxygen/generate.txt b/doxygen/generate.txt new file mode 100644 index 0000000..597e703 --- /dev/null +++ b/doxygen/generate.txt @@ -0,0 +1,1257 @@ +# Doxyfile 1.5.1 + +# 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 = karma + +# 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 = doc + +# 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: +# Afrikaans, Arabic, 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, Lithuanian, 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 = YES + +# 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 = YES + +# 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 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 = 4 + +# 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 + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# 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 + +# 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 = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# 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 = NO + +# 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 = YES + +# 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 = YES + +# 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. The default is NO. + +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 , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program 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 = ../src + + +# 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 *.py + +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. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +# armSimple... contains too much stuff +# firmware contains a lot of stuff too +# .svn useless directory. Not sure they are parsed by doxygen, but ... just in case +EXCLUDE_PATTERNS = /*.svn/* +# */firmware/* /*armSimpleAnticollisionFilter/* /*primateVision/* + +# 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 , where +# is the value of the INPUT_FILTER tag, and 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 = YES + +# 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 REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# 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 = NO + +# 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 = YES + +# 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_DEFINED 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 = NO + +# 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 = NO + +# 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 = NO + +# 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 = NO + +# 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 CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller 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 caller graphs for selected +# functions only using the \callergraph command. + +CALLER_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 = NO + +# 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 = NO + +# 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 = YES diff --git a/index.html b/index.html new file mode 100644 index 0000000..b30750b --- /dev/null +++ b/index.html @@ -0,0 +1,15 @@ + + + + + + + Page Redirection + + + If you are not redirected automatically, follow the link to the documentation + + +