|
14 | 14 | "3. From both poses, the robot observes three landmarks (`L(1)`, `L(2)`, `L(3)`) with a stereo camera.\n", |
15 | 15 | "\n", |
16 | 16 | "We will:\n", |
17 | | - "* Define camera calibration and noise models.\n", |
18 | | - "* Create a factor graph representing the problem.\n", |
19 | | - "* Provide initial estimates for poses and landmark positions.\n", |
20 | | - "* Optimize the graph using Levenberg-Marquardt to find the most probable configuration.\n" |
| 17 | + "- Define camera calibration and noise models.\n", |
| 18 | + "- Create a factor graph representing the problem.\n", |
| 19 | + "- Provide initial estimates for poses and landmark positions.\n", |
| 20 | + "- Optimize the graph using Levenberg-Marquardt to find the most probable configuration.\n", |
| 21 | + "\n", |
| 22 | + "**Note:** This example is also available in C++. If you're interested in the C++ implementation, refer to `StereoVOExample.cpp` in the [GTSAM examples directory](https://github.com/borglab/gtsam/tree/develop/examples)." |
21 | 23 | ] |
22 | 24 | }, |
23 | 25 | { |
24 | 26 | "cell_type": "markdown", |
25 | 27 | "id": "e33e553a", |
26 | | - "metadata": {}, |
| 28 | + "metadata": { |
| 29 | + "tags": [ |
| 30 | + "hide-cell" |
| 31 | + ] |
| 32 | + }, |
27 | 33 | "source": [ |
28 | 34 | "GTSAM Copyright 2010-2025, Georgia Tech Research Corporation,\n", |
29 | 35 | "Atlanta, Georgia 30332-0415\n", |
|
39 | 45 | "id": "6af0f339", |
40 | 46 | "metadata": {}, |
41 | 47 | "source": [ |
42 | | - "<a href=\"https://colab.research.google.com/github/gtsam-project/gtsam-examples/blob/main/python/StereoVOExample_py.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" |
| 48 | + "<a href=\"https://colab.research.google.com/github/borglab/gtsam/blob/develop/python/gtsam/examples/StereoVOExample.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" |
43 | 49 | ] |
44 | 50 | }, |
45 | 51 | { |
46 | 52 | "cell_type": "code", |
47 | 53 | "execution_count": null, |
48 | 54 | "id": "43bbbfe4", |
49 | | - "metadata": {}, |
50 | | - "outputs": [], |
| 55 | + "metadata": { |
| 56 | + "tags": [ |
| 57 | + "hide-cell" |
| 58 | + ] |
| 59 | + }, |
| 60 | + "outputs": [ |
| 61 | + { |
| 62 | + "name": "stdout", |
| 63 | + "output_type": "stream", |
| 64 | + "text": [ |
| 65 | + "Not running in Google Colab.\n" |
| 66 | + ] |
| 67 | + } |
| 68 | + ], |
51 | 69 | "source": [ |
52 | | - "# Install necessary libraries\n", |
53 | | - "%pip install -q gtsam-develop\n", |
54 | | - "%pip install -q numpy" |
| 70 | + "try:\n", |
| 71 | + " import google.colab\n", |
| 72 | + " print(\"Running in Google Colab, installing necessary libraries...\")\n", |
| 73 | + " %pip install --quiet gtsam-develop\n", |
| 74 | + " print(\"Done!\")\n", |
| 75 | + "except ImportError:\n", |
| 76 | + " print(\"Not running in Google Colab. Please install necessary libraries as needed.\")\n", |
| 77 | + " pass" |
55 | 78 | ] |
56 | 79 | }, |
57 | 80 | { |
58 | 81 | "cell_type": "code", |
59 | | - "execution_count": null, |
| 82 | + "execution_count": 2, |
60 | 83 | "id": "ac25f0ee", |
61 | 84 | "metadata": {}, |
62 | 85 | "outputs": [], |
63 | 86 | "source": [ |
64 | 87 | "import gtsam\n", |
65 | | - "import numpy as np\n", |
66 | 88 | "\n", |
67 | 89 | "# For shorthand for common GTSAM types (like X for poses, L for landmarks)\n", |
68 | | - "from gtsam.symbol_shorthand import X, L\n" |
| 90 | + "from gtsam.symbol_shorthand import X, L" |
69 | 91 | ] |
70 | 92 | }, |
71 | 93 | { |
|
82 | 104 | }, |
83 | 105 | { |
84 | 106 | "cell_type": "code", |
85 | | - "execution_count": null, |
| 107 | + "execution_count": 3, |
86 | 108 | "id": "342a585f", |
87 | 109 | "metadata": {}, |
88 | | - "outputs": [], |
| 110 | + "outputs": [ |
| 111 | + { |
| 112 | + "name": "stdout", |
| 113 | + "output_type": "stream", |
| 114 | + "text": [ |
| 115 | + "Graph size after adding prior: 1\n" |
| 116 | + ] |
| 117 | + } |
| 118 | + ], |
89 | 119 | "source": [ |
90 | 120 | "# Create an empty nonlinear factor graph\n", |
91 | 121 | "graph = gtsam.NonlinearFactorGraph()\n", |
|
118 | 148 | }, |
119 | 149 | { |
120 | 150 | "cell_type": "code", |
121 | | - "execution_count": null, |
| 151 | + "execution_count": 4, |
122 | 152 | "id": "e04b26c7", |
123 | 153 | "metadata": {}, |
124 | | - "outputs": [], |
| 154 | + "outputs": [ |
| 155 | + { |
| 156 | + "name": "stdout", |
| 157 | + "output_type": "stream", |
| 158 | + "text": [ |
| 159 | + "K: 1000 0 320\n", |
| 160 | + " 0 1000 240\n", |
| 161 | + " 0 0 1\n", |
| 162 | + "Baseline: 0.2\n", |
| 163 | + "\n" |
| 164 | + ] |
| 165 | + } |
| 166 | + ], |
125 | 167 | "source": [ |
126 | 168 | "# Create stereo camera calibration object\n", |
127 | 169 | "K = gtsam.Cal3_S2Stereo(1000, 1000, 0, 320, 240, 0.2)\n", |
|
153 | 195 | }, |
154 | 196 | { |
155 | 197 | "cell_type": "code", |
156 | | - "execution_count": null, |
| 198 | + "execution_count": 5, |
157 | 199 | "id": "e9778bec", |
158 | 200 | "metadata": {}, |
159 | | - "outputs": [], |
| 201 | + "outputs": [ |
| 202 | + { |
| 203 | + "name": "stdout", |
| 204 | + "output_type": "stream", |
| 205 | + "text": [ |
| 206 | + "Graph size after adding X(1) factors: 4\n" |
| 207 | + ] |
| 208 | + } |
| 209 | + ], |
160 | 210 | "source": [ |
161 | 211 | "# Factors from X(1) to landmarks\n", |
162 | 212 | "# StereoPoint2(uL, uR, v)\n", |
|
183 | 233 | }, |
184 | 234 | { |
185 | 235 | "cell_type": "code", |
186 | | - "execution_count": null, |
| 236 | + "execution_count": 6, |
187 | 237 | "id": "495fc44f", |
188 | 238 | "metadata": {}, |
189 | | - "outputs": [], |
| 239 | + "outputs": [ |
| 240 | + { |
| 241 | + "name": "stdout", |
| 242 | + "output_type": "stream", |
| 243 | + "text": [ |
| 244 | + "Graph size after adding all factors: 7\n" |
| 245 | + ] |
| 246 | + } |
| 247 | + ], |
190 | 248 | "source": [ |
191 | 249 | "# Factors from X(2) to landmarks\n", |
192 | 250 | "graph.add(gtsam.GenericStereoFactor3D(\n", |
|
219 | 277 | }, |
220 | 278 | { |
221 | 279 | "cell_type": "code", |
222 | | - "execution_count": null, |
| 280 | + "execution_count": 7, |
223 | 281 | "id": "b4be6ab2", |
224 | 282 | "metadata": {}, |
225 | 283 | "outputs": [], |
|
253 | 311 | }, |
254 | 312 | { |
255 | 313 | "cell_type": "code", |
256 | | - "execution_count": null, |
| 314 | + "execution_count": 8, |
257 | 315 | "id": "d0c3a87b", |
258 | 316 | "metadata": {}, |
259 | 317 | "outputs": [], |
|
283 | 341 | }, |
284 | 342 | { |
285 | 343 | "cell_type": "code", |
286 | | - "execution_count": null, |
| 344 | + "execution_count": 9, |
287 | 345 | "id": "093fe3dc", |
288 | 346 | "metadata": {}, |
289 | | - "outputs": [], |
| 347 | + "outputs": [ |
| 348 | + { |
| 349 | + "name": "stdout", |
| 350 | + "output_type": "stream", |
| 351 | + "text": [ |
| 352 | + "Initial Error: 3434.6236\n", |
| 353 | + "Final Error : 0.0000\n", |
| 354 | + "\n", |
| 355 | + "Optimized Pose X(1):\n", |
| 356 | + " R: [\n", |
| 357 | + "\t1, 0, 0;\n", |
| 358 | + "\t0, 1, 0;\n", |
| 359 | + "\t0, 0, 1\n", |
| 360 | + "]\n", |
| 361 | + "t: 0 0 0\n", |
| 362 | + "\n", |
| 363 | + "\n", |
| 364 | + "Optimized Pose X(2):\n", |
| 365 | + " R: [\n", |
| 366 | + "\t1, -3.03422e-17, -2.0943e-16;\n", |
| 367 | + "\t3.03422e-17, 1, 1.30264e-15;\n", |
| 368 | + "\t2.0943e-16, -1.30264e-15, 1\n", |
| 369 | + "]\n", |
| 370 | + "t: 6.11092e-13 -6.15462e-13 1\n", |
| 371 | + "\n", |
| 372 | + "Translation component of X(2): [ 6.11092279e-13 -6.15461900e-13 1.00000000e+00]\n", |
| 373 | + "\n", |
| 374 | + "Optimized Landmark (L(1)):\n", |
| 375 | + " [1. 1. 5.]\n", |
| 376 | + "\n", |
| 377 | + "Optimized Landmark (L(2)):\n", |
| 378 | + " [-1. 1. 5.]\n", |
| 379 | + "\n", |
| 380 | + "Optimized Landmark (L(3)):\n", |
| 381 | + " [-1.21564099e-16 -5.00000000e-01 5.00000000e+00]\n" |
| 382 | + ] |
| 383 | + } |
| 384 | + ], |
290 | 385 | "source": [ |
291 | 386 | "# print(result)\n", |
292 | 387 | "print(f\"Initial Error: {graph.error(initial_estimate):.4f}\")\n", |
|
0 commit comments