-
Notifications
You must be signed in to change notification settings - Fork 146
/
csm_manual.html
675 lines (442 loc) · 30.1 KB
/
csm_manual.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns:svg='http://www.w3.org/2000/svg' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
<head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>The C(anonical) Scan Matcher</title><link href='style.css' rel='stylesheet' type='text/css' />
</head>
<body><style>
body { padding-left: 3em;}
body p, body ul { max-width: 35em;}
pre { margin-left: 2em; background-color: #bbf; border: solid 1px black;
padding: 10px;}
code { background-color: #ddf; padding: 3px; color: #008;}
pre code { background-color: #bbf;}
p, pre { max-width: 40em; }
h2 {
border-left: solid 2px #b00;
border-top: solid 2px #b00;
margin-top: 4em;
padding: 1em; margin-left: -1em;}
</style>
<h1 id='the_canonical_scan_matcher'>The C(anonical) Scan Matcher</h1>
<div class='maruku_toc'><ul style='list-style: none;'><li><span class='maruku_section_number'>1. </span><a href='#introduction'>Introduction</a></li><li><span class='maruku_section_number'>2. </span><a href='#content_of_this_package'>Content of this package</a><ul style='list-style: none;'><li><span class='maruku_section_number'>2.1. </span><a href='#stable_things_c_scan_matching_library'>Stable things: C scan matching library</a></li><li><span class='maruku_section_number'>2.2. </span><a href='#stable_things_applications'>Stable things: applications</a></li><li><span class='maruku_section_number'>2.3. </span><a href='#unstable_things_scripts'>Unstable things: scripts</a></li><li><span class='maruku_section_number'>2.4. </span><a href='#unstable_things_ruby_and_matlab_implementations'>Unstable things: Ruby and Matlab implementations</a></li></ul></li><li><span class='maruku_section_number'>3. </span><a href='#installation'>Installation</a><ul style='list-style: none;'><li><span class='maruku_section_number'>3.1. </span><a href='#required_software_dependencies'>Required software dependencies</a></li><li><span class='maruku_section_number'>3.2. </span><a href='#compiling'>Compiling</a></li><li><span class='maruku_section_number'>3.3. </span><a href='#getting_started'>Getting started</a></li><li><span class='maruku_section_number'>3.4. </span><a href='#installing_ruby_libraries_and_wrapper_optional'>Installing Ruby libraries and wrapper (optional)</a></li></ul></li><li><span class='maruku_section_number'>4. </span><a href='#the__data_structure'>The <code>laser_data</code> data structure</a></li><li><span class='maruku_section_number'>5. </span><a href='#input_and_output_formats'>Input and output formats</a><ul style='list-style: none;'><li><span class='maruku_section_number'>5.1. </span><a href='#the_json_log_format'>The JSON log format</a></li><li><span class='maruku_section_number'>5.2. </span><a href='#the_carmen_log_format'>The Carmen log format</a><ul style='list-style: none;'><li><span class='maruku_section_number'>5.2.1. </span><a href='#regarding_the_timestamp'>Regarding the timestamp</a></li></ul></li></ul></li><li><span class='maruku_section_number'>6. </span><a href='#examples'>Examples</a><ul style='list-style: none;'><li><span class='maruku_section_number'>6.1. </span><a href='#simple_scan_matching'>Simple scan matching</a></li><li><span class='maruku_section_number'>6.2. </span><a href='#creating_a_pdf'>Creating a PDF</a></li><li><span class='maruku_section_number'>6.3. </span><a href='#examining_one_particular_matching_video'>Examining one particular matching (video)</a></li><li><span class='maruku_section_number'>6.4. </span><a href='#help_icp_doesnt_work'>Help! ICP doesn’t work</a></li></ul></li><li><span class='maruku_section_number'>7. </span><a href='#embedding_csm_in_your_programs'>Embedding CSM in your programs</a><ul style='list-style: none;'><li><span class='maruku_section_number'>7.1. </span><a href='#linking_to_csm'>Linking to CSM</a></li><li><span class='maruku_section_number'>7.2. </span><a href='#accessing_csm_functions_from_your_applications'>Accessing CSM functions from your applications</a></li><li><span class='maruku_section_number'>7.3. </span><a href='#orienting_oneself_in_the_source_code'>Orienting oneself in the source code</a></li></ul></li></ul></div>
<h2 id='introduction'><span class='maruku_section_number'>1. </span>Introduction</h2>
<p>I created this package:</p>
<ul>
<li>
<p>To have a well-documented reference implementation of <a href='http://purl.org/censi/2007/plicp'>PL-ICP</a>. If you are only interested in the core algorithm of PL-ICP, a <a href='http://purl.org/censi/2007/plicp'>separate concise implementation in C/Matlab/Ruby</a> is available.</p>
</li>
<li>
<p>To have a <strong>trustworthy</strong> scan matcher to be used in the experiments for some papers on <a href='http://purl.org/censi/2006/icpcov'>ICP covariance</a>, <a href='http://purl.org/censi/2006/accuracy'>the Cramer-Rao bound for range finders</a>, and <a href='http://purl.org/censi/2007/calib'>robot calibration</a>. For batch experiments, it’s also useful that it’s pretty fast.</p>
</li>
<li>
<p>To have a collection of utilies for command line (UNIX-style) manipulation of laser data, and creating beautiful maps and animations.</p>
</li>
</ul>
<h2 id='content_of_this_package'><span class='maruku_section_number'>2. </span>Content of this package</h2>
<p>The core content is the C scan matching library which is quite polished, but this package contains a lot of software, only some of that in an usable state. In general, I am not ashamed of the prototypical code I write.</p>
<h3 id='stable_things_c_scan_matching_library'><span class='maruku_section_number'>2.1. </span>Stable things: C scan matching library</h3>
<p>The directory <code>sm/csm</code> contains a scan matcher written in C, plus associated tools and apps. This is stable and reasonably bug-free.</p>
<p>There are many libraries in the <code>sm/lib</code> directory:</p>
<ul>
<li>
<p>Directory <code>egsl</code>: a light wrapper for GSL that makes manipulating matrices easy and efficient. This is documented in another file: see <code>sm/lib/egsl/docs</code>.</p>
</li>
<li>
<p>Directory <code>options</code>: for processing command-line arguments and configuration files.</p>
</li>
<li>
<p>Directory <code>json-c</code>: a library for JSON input/output. This is a slightly modified version of the original <a href='http://www.json.org'><code>json-c</code></a> library released under the <a href='http://en.wikipedia.org/wiki/MIT_License'>MIT license</a>.</p>
</li>
</ul>
<h3 id='stable_things_applications'><span class='maruku_section_number'>2.2. </span>Stable things: applications</h3>
<p>There are many applications in the <code>sm/apps</code> directory:</p>
<ul>
<li>
<p>Application <code>sm2</code>: standard scan-matching. Reads a log, runs ICP, and writes the scan-matched output. Input can be both Carmen and JSON.</p>
</li>
<li>
<p>Application <code>sm3</code>: like sm2, but instead of actual output it measures the performance. This is the application that produced the stats found in the paper submitted to ICRA’08.</p>
</li>
<li>
<p>Application <code>sm1</code>: useful for running experiments. Reads scans from two different files, and outputs statistics.</p>
</li>
</ul>
<p>Visualization apps:</p>
<ul>
<li>
<p>Application <code>log2pdf</code>: converts a laser log to a PDF map. To build this application, it is needed to install the <a href='http://cairographics.org'>Cairo</a> graphics library.</p>
</li>
<li>
<p>Application <code>sm_animate</code>: creates an animation for the ICP process, displaying the correspondences, etc. This application reads the output created by <code>sm2</code> with the <code>-file_jj</code> option. To build this application, it is needed to install the <a href='http://cairographics.org'>Cairo</a> graphics library.</p>
</li>
</ul>
<p>Miscellaneous Unix-style processing for laser data:</p>
<ul>
<li>
<p>Application <code>carmen2json</code>: converts a Carmen log to the JSON format.</p>
</li>
<li>
<p>Application <code>ld_fisher</code>: computes the Fisher’s information matrix. See <a href='http://purl.org/censi/2006/accuracy'>http://purl.org/censi/2006/accuracy</a> for details.</p>
</li>
<li>
<p>Application <code>json_extract</code>: extract the n-th object from a JSON stream.</p>
</li>
<li>
<p>Application <code>ld_slip</code>: adds some noise to the odometry field.</p>
</li>
<li>
<p>Application <code>ld_smooth</code>: smooths the readings data.</p>
</li>
<li>
<p>Application <code>ld_noise</code>: adds sensor noise.</p>
</li>
<li>
<p>Application <code>ld_cluster_curv</code>: clusterize the rays based on the analysis of the curvature.</p>
</li>
<li>
<p>Application <code>ld_linearize</code>: fits a line to each cluster (data must have been previously clustered, for example by <code>ld_cluster_curv</code>).</p>
</li>
</ul>
<p>GUI apps:</p>
<ul>
<li><code>apps/gtk_viewer</code> contains the prototype of a viewer using GTK. It does not work yet.</li>
</ul>
<h3 id='unstable_things_scripts'><span class='maruku_section_number'>2.3. </span>Unstable things: scripts</h3>
<p>In the <code>scripts/</code> directory you can find:</p>
<ul>
<li>
<p>Script <code>json2matlab.rb</code>: converts a JSON object in a Matlab scripts. This is the holy grail of data exchange.</p>
<p>Warning: at the moment, this script relies on some patches to the Ruby JSON library. Without them, it is limited to only 1 JSON object in each file.</p>
</li>
<li>
<p>Script <code>fig2pics.rb</code>: used for converting FIG files to PDF. It has many more options than <a href='http://www.xfig.org'><code>fig2dev</code></a> (that is being used internally), including the ability to use a LaTeX preamble and to change the resulting bounding box.</p>
</li>
<li>
<p>Script <code>create_video.rb</code>: displays the scan-matching process. This reads the journal files written by applications <code>sm1</code> and <code>sm2</code>. <strong>Made obsolete by <code>sm_animate</code></strong></p>
</li>
</ul>
<h3 id='unstable_things_ruby_and_matlab_implementations'><span class='maruku_section_number'>2.4. </span>Unstable things: Ruby and Matlab implementations</h3>
<p>Unstable things include:</p>
<ul>
<li>
<p>Directory <code>sm_ruby_wrapper/</code>: a ruby wrapper for the <code>sm</code> C library. This wrapper is used for running some of the experiments. It is not documented and it needs tidying a little.</p>
</li>
<li>
<p>Directory <code>rsm/</code>: a Ruby implementation of the same algorithms used in the <code>sm</code> library. Some times ago, the C and Matlab implementation were perfectly in sync. Now they differ a little. However, in the future I will try to get them back in sync, as the only way of having a good chance of making a bug-free implementation, is to make it twice.</p>
</li>
<li>
<p>Directory <code>matlab/</code> and <code>matlab_new/</code>. The Matlab scripts are a mess that needs tidying. There’s a lot in there. They are kept here because they are used for creating some of the figures in the submitted papers. Also, the first PLICP implementation was written in Matlab and is buried there, somewhere.</p>
<p>Also, I occasionally tried to make sure that the scripts run fine in <a href='http://www.octave.org'>Octave</a>. They do, except for the plotting.</p>
</li>
</ul>
<h2 id='installation'><span class='maruku_section_number'>3. </span>Installation</h2>
<!--
### Downloading ###
Download with SVN, using the following:
$ svn checkout --username ANTANI svn://net143-184.mclink.it/csm
where `ANTANI` is your surname (you should have received a password).
This will checkout both the source code
and some files used for experiments, that might be slightly slow to download.
If you are only interested in the source code, use:
$ svn checkout --username ANTANI svn://net143-184.mclink.it/csm/csm
-->
<h3 id='required_software_dependencies'><span class='maruku_section_number'>3.1. </span>Required software dependencies</h3>
<p>This software has been tested on Mac OS X, Linux, and Windows XP (using Cygwin). It compiles with GCC (3.3 or 4.x) and the Intel C++ Compiler (ICC).</p>
<p>Required software:</p>
<ul>
<li>The build system is based on <code>cmake</code>, which is available at <a href='http://www.cmake.org/'>http://www.cmake.org/</a>.</li>
<li>The GSL, Gnu Scientific Library, available at <a href='http://www.gnu.org/software/gsl/'>http://www.gnu.org/software/gsl/</a>.</li>
<li>(optional) For <code>log2pdf</code> and other visualization applications, you will need the Cairo graphics library, available at <a href='http://cairographics.org'>http://cairographics.org</a>. The recommended version is the stable 1.4.12.</li>
</ul>
<p><strong>Linux</strong>. CMake, Cairo, and GSL are probably already packaged for your Linux distribution. For example, in Ubuntu, you can simply enter this command to install all dependencies:</p>
<pre><code>$ sudo apt-get install build-essential cmake libgsl0-dev libcairo2-dev </code></pre>
<p><strong>OS X</strong>. You can install GSL using <a href='http://finkproject.org/'>Fink</a>. You have to install Cairo manually.</p>
<p><strong>Windows XP, using Cygwin</strong>. CSM runs fine on Cygwin, but very slow compared to Linux/OS X. Make sure you install the Cygwin packages <code>cairo</code>, <code>gsl</code>, <code>gsl-apps</code>, <code>gsl-devel</code>.</p>
<p><strong>Windows XP, using Visual Studio</strong>. CSM doesn’t compile yet on this platform. CMake can theoretically create Visual Studio projects, but I could not manage to do it. Also, some CMake code is probably Unix-specific.</p>
<h3 id='compiling'><span class='maruku_section_number'>3.2. </span>Compiling</h3>
<p>If you are lucky, this should be it:</p>
<pre><code>$ cmake .
$ make</code></pre>
<p>If you want to install this library system-wide, you could use:</p>
<pre><code>$ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/local .
$ make
$ make install</code></pre>
<p>as the first step.</p>
<p>For installing the Ruby wrapper, refer to the separate instructions. If you want to use the Ruby wrapper, I suggest to install the source code in a <code>deploy</code> sub-directory of <code>csm</code>:</p>
<pre><code>csm/
docs/
csm/
rsm/
deploy/ <--- here</code></pre>
<p>To do this, use:</p>
<pre><code>$ cmake -DCMAKE_INSTALL_PREFIX:PATH=`pwd`/deploy .
$ make
$ make install</code></pre>
<p>(you have to give a complete path to <code>-DCMAKE_INSTALL_PREFIX:PATH</code>).</p>
<p>Later, remember to set your <code>PATH</code> variable to <code>csm/deploy/bin</code>.</p>
<h3 id='getting_started'><span class='maruku_section_number'>3.3. </span>Getting started</h3>
<p>You might get started by doing this:</p>
<pre><code>$ sm2 < in.log > out.log</code></pre>
<p>where <code>in.log</code> is a Carmen-format log file.</p>
<p>You can find one in the top-level <code>experiments</code> directory: it is called <code>laserazosSM3.log</code>. So, if you installed the Cairo library, you can see the result with:</p>
<pre><code>$ sm2 < in.log > out.log
$ log2pdf -use odometry -in out.log -out out-odometry.pdf
$ log2pdf -use estimate -in out.log -out out-estimate.pdf</code></pre>
<h3 id='installing_ruby_libraries_and_wrapper_optional'><span class='maruku_section_number'>3.4. </span>Installing Ruby libraries and wrapper (optional)</h3>
<p>This step-by-step guide is written by me, for me.</p>
<p>Installing with cmake:</p>
<pre><code>$ cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr/local</code></pre>
<p>First, set up some directories</p>
<pre><code>$ export SMLIB=
$ cd $SMLIB
$ ls
...................</code></pre>
<p>Create installation directory:</p>
<pre><code>$ mkdir deploy
$ mkdir deploy/bin
$ export PATH=$PATH $SMLIB/deploy/bin</code></pre>
<p>Create a new ruby installation</p>
<pre><code>$ mkdir my_ruby
$ cd my_ruby</code></pre>
<p>Download ruby:</p>
<pre><code>$ wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5.tar.gz
$ tar xvzf ruby-1.8.5.tar.gz
$ ./configure --prefix=$SMLIB/deploy
$ make
$ make install</code></pre>
<p>Now you should be able to use the new ruby installation</p>
<pre><code>$ which ruby
<SMLIB>/deploy/bin/ruby
$ ruby --version
ruby 1.8.5 (2006-08-25)</code></pre>
<p>Instructions for installing rb-gsl:</p>
<ol>
<li>Get and install GSL. Make sure the command “gsl-config” is in command search path.</li>
<li>Download Ruby/GSL, ungzip and untar the archive rb-gsl-xxx.tar.gz.</li>
<li>Use: % cd rb-gsl-xxx/ % ruby setup.rb config % ruby setup.rb setup % ruby setup.rb install (as root)</li>
</ol>
<p>Download rubygems:</p>
<pre><code>$ cd $SMLIB/my_ruby
$ wget http://rubyforge.org/frs/download.php/11289/rubygems-0.9.0.tgz
$ tar xvzf rubygems-0.9.0.tgz
$ cd rubygems-0.9.0
$ ruby setup.rb</code></pre>
<p>Now you should have the “gem” command installed:</p>
<pre><code>$ which gem
<SMLIB>/deploy/bin/gem</code></pre>
<!--
/path/to/cmake . -DCMAKE_INSTALL_PREFIX:PATH=/path/to/install/to/scribuscmake/
#export PKG_CONFIG_PATH=/Users/andrea/06MELANIA/censi-2006/Matlab-yasmine/deploy/lib/pkgconfig/
-->
<h2 id='the__data_structure'><span class='maruku_section_number'>4. </span>The <code>laser_data</code> data structure</h2>
<p>Laser data is passed around in a structure which is quite rich and in some ways redundant to achieve ease of use.</p>
<p>In C, the structure’s name is <code>struct laser_data</code>. In Ruby, it is <code>class LaserData</code>. In Matlab, it’s a generic structure.</p>
<p>A description of the fields follows (assume the structure is called <code>ld</code>).</p>
<p>Regarding the pose of the robot:</p>
<dl>
<dt><code>ld.true_pose</code></dt>
<dd>Pose of the robot (m,m,rad), in world coordinates.</dd>
<dt><code>ld.odometry</code></dt>
<dd>Odometry (<code>true_pose</code> corrupted by noise).</dd>
<dt><code>ld.estimate</code></dt>
<dd>Estimate of <code>true_pose</code>.</dd>
</dl>
<p>Regarding the rays:</p>
<dl>
<dt><code>ld.nrays</code></dt>
<dd>
<p>Number of rays.</p>
</dd>
<dt><code>ld.min_theta</code> and <code>ld.max_theta</code></dt>
<dd>
<p>Minimum and maximum theta (radians).</p>
</dd>
<dt><code>ld.theta[i]</code></dt>
<dd>
<p>Direction of i-th ray with respect to the robot (radians).</p>
</dd>
<dt><code>ld.readings[i]</code></dt>
<dd>
<p>Sensor reading (meters). If the reading is not valid, then <code>ld.readings(i) == NAN</code>.</p>
</dd>
<dt><code>ld.valid[i]</code></dt>
<dd>
<p>In C, it assumes values <code>0</code> and <code>1</code>. In Ruby, it assumes values <code>true</code> or <code>false</code>. (<strong>TODO</strong>: choose how to serialize).</p>
<p>This field is true if this ray is valid, and, in particular, <code>ld.readings[i]</code> is valid. Invalid rays occur when the obstacle is farther than the sensor horizon.</p>
</dd>
<dt><code>ld.true_alpha[i]</code></dt>
<dd>
<p>Orientation of the normal of the surface (radians, relative to robot). It is <code>NAN</code> if not valid.</p>
</dd>
<dt><code>ld.alpha[i]</code></dt>
<dd>
<p>Estimated orientation of the surface (radians, relative to robot). It is an estimate of <code>ld.true_alpha[i]</code>.</p>
</dd>
<dt><code>ld.alpha_valid[i]</code></dt>
<dd>
<p>True if previous field is valid.</p>
</dd>
<dt><code>ld.cov_alpha[i]</code></dt>
<dd>
<p>Estimated covariance of <code>ld.alpha[i]</code>.</p>
</dd>
</dl>
<p>Additional fields used during the computation:</p>
<dl>
<dt><code>ld.cluster[i]</code></dt>
<dd>Cluster to which point i belongs. This is used for computing the orientation (at the moment a really dumb algorithm is used for clustering). If <code>cluster[i] == -1</code>, the point does not belong to any cluster.</dd>
<dt><code>ld.points[i].p</code></dt>
<dd>Point coordinates (cartesian). Computed from the polar coordinates <code>theta[i]</code> and <code>readings[i]</code>.</dd>
<dt><code>ld.points_w[i].p</code></dt>
<dd>Point coordinates (cartesian) in a “world” reference frame. Computed with the function <code>ld_compute_world_coords(LDP, double pose[3])</code>.</dd>
<dt><code>ld.hostname</code></dt>
<dd>This is parsed from the Carmen data field.</dd>
<dt><code>ld.tv</code></dt>
<dd>This is a <code>struct timeval</code> field giving a timestamp for the laser scan. Please see the section on parsing to learn how this is parsed from the Carmen log.</dd>
</dl>
<h2 id='input_and_output_formats'><span class='maruku_section_number'>5. </span>Input and output formats</h2>
<p>The library understands two formats: a rich JSON format, and the old good Carmen format.</p>
<h3 id='the_json_log_format'><span class='maruku_section_number'>5.1. </span>The JSON log format</h3>
<p>See this site: <a href='http://www.json.org'>http://www.json.org</a> for general information about JSON.</p>
<p>This is a sample laser data structure. It has only 5 rays (which all happen to be invalid), and it has no <code>alpha</code>, <code>true_alpha</code>, <code>cluster</code> fields:</p>
<pre><code>{
"nrays": 5,
"min_theta": null,
"max_theta": null,
"theta": [ null, null, null, null, null ],
"readings": [ null, null, null, null, null],
"valid": [ 0, 0, 0, 0, 0],
"odometry": [ null, null, null ],
"estimate": [ null, null, null ],
"true_pose": [ null, null, null ]
}</code></pre>
<p>Note that <code>NAN</code> is represented with <code>null</code> in the JSON format.</p>
<h3 id='the_carmen_log_format'><span class='maruku_section_number'>5.2. </span>The Carmen log format</h3>
<p>The 6 pose values in the log are interpreted as follows:</p>
<pre><code>estimate.x estimate.y estimate.theta ....
odometry.x odometry.y odometry.theta </code></pre>
<!--diego:
quindi tu alla fine
leggi il secondo campo
e scrivi il secondo campo
(e scrivi, per sicurezza, il primo campo)-->
<h4 id='regarding_the_timestamp'><span class='maruku_section_number'>5.2.1. </span>Regarding the timestamp</h4>
<p>Regarding the timestamp “fields”. The last three fields in a Carmen log can be:</p>
<pre><code>integer string integer</code></pre>
<p>This is interpreted as seconds, hostname, microseconds. This is good if you want to write a <code>timeval</code> struct to the log and <em>be sure</em> it won’t be modified by precision problems when writing, and parsing, as a <code>double</code>.</p>
<p>If it doesn’t look like a timestamp, then it is assumed that the fields are:</p>
<pre><code>double string double</code></pre>
<p>In this case, the first double is interpreted as the timestamp in seconds, while the second double is discarded.</p>
<p>The library will warn the user about these decisions by writing on the console this message:</p>
<pre><code>sm2:inf: Reading timestamp as 'sec hostname usec'.</code></pre>
<p>or this one:</p>
<pre><code>sm2:inf: Reading timestamp as doubles (discarding second one).</code></pre>
<h2 id='examples'><span class='maruku_section_number'>6. </span>Examples</h2>
<h3 id='simple_scan_matching'><span class='maruku_section_number'>6.1. </span>Simple scan matching</h3>
<p>Simple scan-matching:</p>
<pre><code>$ sm2 < in.log > out.log</code></pre>
<p>where <code>in.log</code> may be in either Carmen or JSON format.</p>
<h3 id='creating_a_pdf'><span class='maruku_section_number'>6.2. </span>Creating a PDF</h3>
<p>Creating a PDF:</p>
<pre><code>$ log2pdf -use odometry -in in.log -out out_odometry.pdf
$ log2pdf -use estimate -in in.log -out out_estimate.pdf</code></pre>
<h3 id='examining_one_particular_matching_video'><span class='maruku_section_number'>6.3. </span>Examining one particular matching (video)</h3>
<p>To zoom on one particular matching, write a “journal” using the <code>-file_jj</code> option of <code>sm2</code>:</p>
<pre><code>$ sm2 -file_jj journal.txt < in.log > out.log</code></pre>
<p>Extract what you are interested in from the journal. In this example, the 13th matching:</p>
<pre><code>$ json_extract -nth 13 < journal.txt > matching13.txt</code></pre>
<p>Create the animation:</p>
<pre><code>$ sm_animate -in matching13.txt</code></pre>
<h3 id='help_icp_doesnt_work'><span class='maruku_section_number'>6.4. </span>Help! ICP doesn’t work</h3>
<p>Actually, there are a million reasons for which it shouldn’t work. If it gives strange results, try the following:</p>
<ol>
<li>
<p>Plot the data! Plot the input and plot the output using <code>log2pdf</code>.</p>
</li>
<li>
<p>Plot the animation! Use the procedure above and inspect the resulting videos.</p>
</li>
<li>
<p>Double-check the parameters you are using. Note that there are some like <code>max_correspondence_dist</code> which depend on the scale of your data. A value of 2m might work for a big robot making large movements, but not for a little Khepera.</p>
</li>
<li>
<p>Smooth your data – if your sensor is very noisy, like an Hokuyo, it’s worth to do simple low-pass filtering. Especially for PLICP which uses the orientation information.</p>
</li>
</ol>
<h2 id='embedding_csm_in_your_programs'><span class='maruku_section_number'>7. </span>Embedding CSM in your programs</h2>
<h3 id='linking_to_csm'><span class='maruku_section_number'>7.1. </span>Linking to CSM</h3>
<p>When CSM is installed, a <a href='http://pkg-config.freedesktop.org/wiki/'>pkgconfig</a> <code>csm.pc</code> file is installed as well. This makes it easy to link to CSM.</p>
<p>For example, on my system, after installing CSM, I can run <code>pkgconfig</code> to get the C preprocessors and linker flags.</p>
<p>This is what I get on my system (on yours, paths will be different, of course).</p>
<pre><code> $ pkg-config --cflags csm
-I/sw/include -I/Users/andrea/svn/cds/csm/deploy/include/cairo
-I/Users/andrea/svn/cds/csm/deploy/include
$ pkg-config --libs csm
-L/sw/lib -L/Users/andrea/svn/cds/csm/deploy/lib
-lcsm-static -lgsl -lgslcblas -lm</code></pre>
<p>If you use GNU Make, a basic Makefile for your program linking to CSM would be something like:</p>
<pre><code>CSM_FLAGS=`pkg-config --libs --cflags csm`
myprogram: myprogram.c
gcc $(CSM_FLAGS) -o myprogram myprogram.c</code></pre>
<p>You can download the sources for this example in the repository (directory <code>docs/example-linking-make</code>).</p>
<p>If you use <a href='http://www.cmake.org/'>CMake</a> — and you should! — it is reccomended that you use something like the following in your <code>CMakeLists.txt</code>.</p>
<pre><code>cmake_minimum_required(VERSION 2.4)
project(myproject)
# Require we have pkgconfig installed
find_package(PkgConfig REQUIRED)
# Tell pkgconfig to look for CSM
pkg_check_modules(CSM REQUIRED csm)
IF(${CSM_FOUND})
MESSAGE("CSM_LIBRARY_DIRS: ${CSM_LIBRARY_DIRS}")
MESSAGE("CSM_LIBRARIES: ${CSM_LIBRARIES}")
MESSAGE("CSM_INCLUDE_DIRS: ${CSM_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(${CSM_INCLUDE_DIRS}) # important!
LINK_DIRECTORIES(${CSM_LIBRARY_DIRS}) # important!
ELSE(${CSM_FOUND})
MESSAGE(FATAL_ERROR "CSM not found. Check that the environment \
variable PKG_CONFIG_PATH includes the path containing the file 'csm.pc'.")
ENDIF(${CSM_FOUND})
add_executable(myprogram myprogram.c)
target_link_libraries(myprogram ${CSM_LIBRARIES}) # important! </code></pre>
<p>You can download the sources for this example in the repository (directory <code>docs/example-linking-cmake</code>).</p>
<h3 id='accessing_csm_functions_from_your_applications'><span class='maruku_section_number'>7.2. </span>Accessing CSM functions from your applications</h3>
<p>All functions that you would be interested in using are accessible by including one header:</p>
<pre><code>#include <csm/csm_all.h></code></pre>
<p>If you are linking from C++, as opposed to C, all functions are enclosed in the <code>CSM</code> namespace. Therefore, you need something like the following.</p>
<pre><code>#include <csm/csm_all.h>
using namespace CSM;</code></pre>
<h3 id='orienting_oneself_in_the_source_code'><span class='maruku_section_number'>7.3. </span>Orienting oneself in the source code</h3>
<p>The main function to call is the following:</p>
<pre><code>void sm_icp(struct sm_params*params, struct sm_result*result);</code></pre>
<p>This implements matching between two laser scans. All the applications discussed above (<code>sm1</code>, <code>sm2</code>, etc.) are essentially wrapper of <code>sm_icp</code>: they fill in the <code>params</code> structure, and read from the <code>result</code> structure.</p>
<p>The <code>sm_params</code> structure is described in the <code><csm/algos.h></code> header file. It contains parameters for both ICP and other algorithms (like HSM; however, only (PL)ICP is considered stable in CSM)</p>
<p>Note that many of the parameters greatly influence the behavior of PLICP, so it is worth reading them all. If you run <code>sm2 -help</code> you will see the default values, which are reasonable as a starting point.</p>
<p>We now briefly discuss the main parameters.</p>
<ul>
<li><code>params->laser_ref</code>: pointer of a structure of type <code>laser_data</code> (described before in this document) representing the “ref”erence scan (first scan).</li>
<li><code>params->laser_sens</code>: pointer of a structure of type <code>laser_data</code> representing the second scan.</li>
<li><code>params->first_guess</code>: first guess (x,y,theta).</li>
<li><code>use_point_to_line_distance</code>: 1 for PLICP, 0 for ICP.</li>
<li><code>use_corr_tricks</code>: use the tricks described in the PLICP paper.</li>
</ul>
<p>Parameters that influence stopping and restarting:</p>
<ul>
<li><code>max_iterations</code>: maximum number of iterations</li>
<li><code>epsilon_xy</code>, <code>epsilon_theta</code>: stop if change below these thresholds</li>
<li><code>restart*</code>: whether to add some noise and restart if the match is not satisfactory. Useful for getting out of local minima but expensive.</li>
</ul>
<p>Parameters that influence correspondence establishment:</p>
<ul>
<li><code>max_angular_correction_deg</code>, <code>max_linear_correction</code>.</li>
<li><code>max_correspondence_dist</code></li>
</ul>
<p>Parameters that influence correspondence pruning:</p>
<ul>
<li><code>outliers_maxPerc</code></li>
<li><code>outliers_adaptive_*</code></li>
<li><code>outliers_remove_doubles</code></li>
</ul>
<p>See the file <code><csm/algos.h></code> for a description of the above parameters, and the other minor parameters.</p>
</body></html>