Skip to content

Commit 769a797

Browse files
authored
Merge pull request #361 from SimonRohou/codac2_dev
[doc] some changes in Lesson E
2 parents a6db3aa + 3306cd2 commit 769a797

5 files changed

Lines changed: 286 additions & 81 deletions

File tree

doc/manual/tuto/cp_robotics/lesson_e_tiles.rst

Lines changed: 83 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Lesson E: Tile-based localization
55

66
Main authors: `Simon Rohou <https://www.simon-rohou.fr/research/>`_, `Maël Godard <https://godardma.github.io>`_
77

8-
This lesson addresses a state-estimation problem arising in indoor mobile robotics. A differential-drive robot evolves on a floor covered with square tiles of known width :math:`L`. Unlike range-based localization, we do not rely on external landmarks. Instead, the floor itself provides sparse exteroceptive information: each time the passive support caster crosses a grout line between two tiles, a shock appears in the accelerometer signal and can be detected after a simple filtering stage.
8+
This lesson addresses a state-estimation problem arising in indoor mobile robotics. A differential-drive robot evolves on a floor covered with square tiles of known width :math:`L`. Unlike range-based localization, we do not rely on external landmarks. Instead, the floor itself provides sparse exteroceptive information: each time the passive support caster crosses a grout line between two tiles, a shock appears in the gyroscope data and can be detected after a simple filtering stage.
99

1010
The platform considered here is a `TurtleBot Burger <https://emanual.robotis.com/docs/en/platform/turtlebot3/overview/>`_-like robot with two motorized wheels and one passive caster. Wheel odometers provide two signals :math:`u[0](\cdot)` and :math:`u[1](\cdot)`, from which the signed longitudinal speed can be reconstructed.
1111
In addition, we assume that a heading sensor provides bounded measurements. The tile-crossing instants are already extracted from accelerometers data and provided in a ``txt`` file. The objective is to combine these data in order to re-estimate the robot position over time.
@@ -58,7 +58,7 @@ The wheel odometers provide two wheel-angle trajectories :math:`u[0](\cdot)` and
5858
\qquad
5959
\dot x_3(t)=\frac{R_1}{R_2}\Big(\dot u[1](t)-\dot u[0](t)\Big).
6060
61-
In practice, the heading is measured directly and these measurements will be preferred to the one obtained by integrating :math:`\dot x_3`, in order to avoid drift. The planar kinematics of the axle midpoint is therefore modeled by
61+
In practice, the heading is provided and these measurements will be preferred to the one obtained by integrating :math:`\dot x_3`, in order to avoid drift. The planar kinematics of the axle midpoint is therefore modeled by
6262

6363
.. math::
6464
:label: eq-tile-f
@@ -67,6 +67,10 @@ In practice, the heading is measured directly and these measurements will be pre
6767
\qquad
6868
\dot x_2(t)=x_4(t)\sin\big(x_3(t)\big).
6969
70+
71+
The passive caster (support wheel)
72+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
73+
7074
The passive caster is located on the longitudinal axis of the robot, behind the axle in the robot frame. Its position in the world frame is thus
7175

7276
.. math::
@@ -90,27 +94,35 @@ The passive caster is located on the longitudinal axis of the robot, behind the
9094
9195
A useful practical remark is that the robot crosses tile joints more sharply when driving backward. In that case, the passive caster becomes the leading contact point with respect to the direction of motion, so the shock induced by a grout line is generally more pronounced and easier to detect. In this dataset, the integration is therefore performed with a reverse speed, i.e. :math:`x_4(t)` is mostly negative. This does not change the geometry of the robot: the caster is still given by Eq. :eq:`eq-tile-caster`, but it becomes the first element of the robot to meet the joint along the direction of motion.
9296

97+
98+
The tile floor
99+
^^^^^^^^^^^^^^
100+
93101
The floor is modeled as an infinite square tiling of width :math:`L`. The set of grout lines is the union of vertical lines :math:`x=kL` and horizontal lines :math:`y=kL`, for all :math:`k\in\mathbb{Z}`. If :math:`t_i` is one of the extracted detection times, the caster position must satisfy
94102

95103
.. math::
96104
:label: eq-tile-obs-set
97105
98-
b_1(t_i) \in L\mathbb{Z} + [-\varepsilon_L,\varepsilon_L]
106+
b_1(t_i) \in L\mathbb{Z} + [-\frac{\varepsilon_L}{2},\frac{\varepsilon_L}{2}]
99107
\quad \text{or} \quad
100-
b_2(t_i) \in L\mathbb{Z} + [-\varepsilon_L,\varepsilon_L],
108+
b_2(t_i) \in L\mathbb{Z} + [-\frac{\varepsilon_L}{2},\frac{\varepsilon_L}{2}],
101109
102110
where :math:`\varepsilon_L>0` accounts for tile and grout imperfections, as well as small geometric mismatches between the ideal square grid model and the actual floor.
103111

112+
113+
Tile-crossing events
114+
^^^^^^^^^^^^^^^^^^^^
115+
104116
The fact that the filtered shock is detected slightly after the physical crossing is treated separately at the temporal level: in practice, the contraction will be applied at a time slightly before :math:`t_i`.
105117

106118
A convenient implicit formulation uses the modulo operator:
107119

108120
.. math::
109121
:label: eq-tile-mod
110122
111-
\operatorname{mod}\big(b_1(t_i),L\big)\in[-\varepsilon_L,\varepsilon_L]
123+
\operatorname{mod}\big(b_1(t_i^-),L\big)\in[-\varepsilon_L,\varepsilon_L]
112124
\quad \text{or} \quad
113-
\operatorname{mod}\big(b_2(t_i),L\big)\in[-\varepsilon_L,\varepsilon_L].
125+
\operatorname{mod}\big(b_2(t_i^-),L\big)\in[-\varepsilon_L,\varepsilon_L].
114126
115127
This is the observation model we will encode with a contractor.
116128

@@ -153,15 +165,13 @@ Initialization and data loading
153165
> Name: codac
154166
Version: 2.0.0.dev28
155167
156-
The required version for this tutorial is 2.0.0.dev28 or later.
157-
158-
The following instructions are given in Python, but feel free to use C++ or Matlab if you prefer.
168+
The required version for this tutorial is ``2.0.0.dev28`` or later.
159169

160170

161171
.. admonition:: Exercise
162172

163-
**E.1. Imports and data paths.**
164-
Start with the imports below. We explicitly import ``builtins`` because ``from codac import *`` shadows Python's ``min`` and ``max``.
173+
**E.1. Imports.**
174+
Start with the imports below.
165175

166176
.. tabs::
167177

@@ -179,7 +189,7 @@ The following instructions are given in Python, but feel free to use C++ or Matl
179189
:language: c++
180190
:start-after: [E-q1-beg]
181191
:end-before: [E-q1-end]
182-
:dedent: 2
192+
:dedent: 0
183193

184194
.. group-tab:: Matlab
185195

@@ -190,7 +200,7 @@ The following instructions are given in Python, but feel free to use C++ or Matl
190200
:dedent: 0
191201

192202
**E.2. Loading sampled trajectories.**
193-
Load the binary ``.cdc`` files into sampled trajectories. We resample the wheel odometry on the same temporal support as ``pos``.
203+
Load the binary ``.cdc`` files into sampled trajectories. We further resample the wheel odometry on the same temporal support as ``pos``.
194204

195205
.. tabs::
196206

@@ -238,7 +248,7 @@ The following instructions are given in Python, but feel free to use C++ or Matl
238248
:language: c++
239249
:start-after: [E-q3-beg]
240250
:end-before: [E-q3-end]
241-
:dedent: 2
251+
:dedent: 0
242252

243253
.. group-tab:: Matlab
244254

@@ -248,9 +258,61 @@ The following instructions are given in Python, but feel free to use C++ or Matl
248258
:end-before: [E-q3-end]
249259
:dedent: 0
250260

261+
.. tabs::
262+
263+
.. group-tab:: Python
264+
265+
.. literalinclude:: src/lesson_E.py
266+
:language: py
267+
:start-after: [E-q3b-beg]
268+
:end-before: [E-q3b-end]
269+
:dedent: 0
270+
271+
.. group-tab:: C++
272+
273+
.. literalinclude:: src/lesson_E.cpp
274+
:language: c++
275+
:start-after: [E-q3b-beg]
276+
:end-before: [E-q3b-end]
277+
:dedent: 2
278+
279+
.. group-tab:: Matlab
280+
281+
.. literalinclude:: src/lesson_E.m
282+
:language: matlab
283+
:start-after: [E-q3b-beg]
284+
:end-before: [E-q3b-end]
285+
:dedent: 0
286+
251287

252288
**E.4. Drawing the map.**
253-
Write a function ``draw_map(X, L)`` that draws the infinite grid, clipped to a bounding box ``X``. As in the reference example, two tiles are highlighted in green.
289+
Write a function ``draw_map(X,L)`` that draws the infinite grid, clipped to a bounding box ``X``. As in the reference example, two tiles are highlighted in green.
290+
291+
.. tabs::
292+
293+
.. group-tab:: Python
294+
295+
.. literalinclude:: src/lesson_E.py
296+
:language: py
297+
:start-after: [E-q4b-beg]
298+
:end-before: [E-q4b-end]
299+
:dedent: 0
300+
301+
.. group-tab:: C++
302+
303+
.. literalinclude:: src/lesson_E.cpp
304+
:language: c++
305+
:start-after: [E-q4b-beg]
306+
:end-before: [E-q4b-end]
307+
:dedent: 2
308+
309+
.. group-tab:: Matlab
310+
311+
.. literalinclude:: src/lesson_E.m
312+
:language: matlab
313+
:start-after: [E-q4b-beg]
314+
:end-before: [E-q4b-end]
315+
:dedent: 0
254316

255317
.. tabs::
256318

@@ -268,7 +330,7 @@ The following instructions are given in Python, but feel free to use C++ or Matl
268330
:language: c++
269331
:start-after: [E-q4-beg]
270332
:end-before: [E-q4-end]
271-
:dedent: 2
333+
:dedent: 0
272334

273335
.. group-tab:: Matlab
274336

@@ -284,9 +346,9 @@ The following instructions are given in Python, but feel free to use C++ or Matl
284346

285347
.. math::
286348
287-
\operatorname{mod}(b_1,L)\in[-\varepsilon_L,\varepsilon_L]
288-
\quad \lor \quad
289-
\operatorname{mod}(b_2,L)\in[-\varepsilon_L,\varepsilon_L].
349+
\left(\operatorname{mod}(b_1+\frac{\varepsilon_L}{2},L)\in[0,\varepsilon_L]
350+
\enspace \lor \enspace
351+
\operatorname{mod}(b_2+\frac{\varepsilon_L}{2},L)\in[0,\varepsilon_L]\right).
290352
291353
You may introduce one analytic function for the first coordinate and one for the second one, as in the previous lessons, and then combine :ref:`the corresponding contractors <sec-ctc-analytic-ctcinverse>` with a union. A union of contractors is represented by the ``CtcUnion`` class, and can be called directly using the operator ``|``.
292354

@@ -458,7 +520,7 @@ The recorded heading and wheel-odometry trajectories are loaded from the files i
458520
459521
[\mathbf{x}_{12}](0):=\left(x_1(0),x_2(0)\right)^\intercal + [-L/3,L/3]^2,
460522
461-
then integrate the velocity tube.
523+
then we integrate the velocity tube.
462524

463525
.. tabs::
464526

@@ -634,12 +696,7 @@ After solving the full localization problem, it is convenient to define a helper
634696

635697

636698
**E.16. Verify a double passage through a box.**
637-
We know from the experiment that the robot passes twice through the box
638-
639-
.. math::
640-
641-
[[-2.4,-2.1],[2.4,2.7]].
642-
699+
We know from the experiment that the robot passes twice through the box :math:`[[-2.4,-2.1],[2.4,2.7]]`.
643700
This box is already drawn (from E.4). Check visually that the contracted position tube also passes through it twice.
644701

645702

doc/manual/tuto/cp_robotics/src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
message(STATUS "You are running Codac in fast release mode. (option -DCMAKE_BUILD_TYPE=Release is required)")
3535
endif()
3636

37-
add_executable(${PROJECT_NAME} lesson_C.cpp
37+
add_executable(${PROJECT_NAME} lesson_E.cpp
3838
)
3939
target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS})
4040
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS})

0 commit comments

Comments
 (0)