From 3d6e2fc81ca1bac9c322e31a5917b1db77e97d5c Mon Sep 17 00:00:00 2001 From: Clark Taylor Date: Fri, 1 Sep 2023 14:12:47 -0400 Subject: [PATCH 1/4] Update CustomFactors.md to more clearly specify types required --- python/CustomFactors.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/CustomFactors.md b/python/CustomFactors.md index a6ffa2f360..079bcaa85e 100644 --- a/python/CustomFactors.md +++ b/python/CustomFactors.md @@ -11,7 +11,7 @@ import gtsam import numpy as np from typing import List -def error_func(this: gtsam.CustomFactor, v: gtsam.Values, H: List[np.ndarray]): +def error_func(this: gtsam.CustomFactor, v: gtsam.Values, H: List[np.ndarray]) -> np.ndarray: ... ``` @@ -21,7 +21,7 @@ def error_func(this: gtsam.CustomFactor, v: gtsam.Values, H: List[np.ndarray]): If `H` is `None`, it means the current factor evaluation does not need Jacobians. For example, the `error` method on a factor does not need Jacobians, so we don't evaluate them to save CPU. If `H` is not `None`, -each entry of `H` can be assigned a `numpy` array, as the Jacobian for the corresponding variable. +each entry of `H` can be assigned a (2D) `numpy` array, as the Jacobian for the corresponding variable. After defining `error_func`, one can create a `CustomFactor` just like any other factor in GTSAM: @@ -42,7 +42,7 @@ from typing import List expected = Pose2(2, 2, np.pi / 2) -def error_func(this: CustomFactor, v: gtsam.Values, H: List[np.ndarray]): +def error_func(this: CustomFactor, v: gtsam.Values, H: List[np.ndarray]) -> np.ndarray: """ Error function that mimics a BetweenFactor :param this: reference to the current CustomFactor being evaluated From 8ee9f205378b1082ab4201b5723e3848b0f155a3 Mon Sep 17 00:00:00 2001 From: Clark Taylor Date: Fri, 1 Sep 2023 14:15:39 -0400 Subject: [PATCH 2/4] Update CustomFactorExample.py to correctly document return types --- python/gtsam/examples/CustomFactorExample.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/gtsam/examples/CustomFactorExample.py b/python/gtsam/examples/CustomFactorExample.py index c7ae8ad21d..1a8d1a61d3 100644 --- a/python/gtsam/examples/CustomFactorExample.py +++ b/python/gtsam/examples/CustomFactorExample.py @@ -30,7 +30,7 @@ def simulate_car() -> List[float]: def error_gps(measurement: np.ndarray, this: gtsam.CustomFactor, values: gtsam.Values, - jacobians: Optional[List[np.ndarray]]) -> float: + jacobians: Optional[List[np.ndarray]]) -> np.ndarray: """GPS Factor error function :param measurement: GPS measurement, to be filled with `partial` :param this: gtsam.CustomFactor handle @@ -49,7 +49,7 @@ def error_gps(measurement: np.ndarray, this: gtsam.CustomFactor, def error_odom(measurement: np.ndarray, this: gtsam.CustomFactor, values: gtsam.Values, - jacobians: Optional[List[np.ndarray]]) -> float: + jacobians: Optional[List[np.ndarray]]) -> np.ndarray: """Odometry Factor error function :param measurement: Odometry measurement, to be filled with `partial` :param this: gtsam.CustomFactor handle @@ -70,7 +70,7 @@ def error_odom(measurement: np.ndarray, this: gtsam.CustomFactor, def error_lm(measurement: np.ndarray, this: gtsam.CustomFactor, values: gtsam.Values, - jacobians: Optional[List[np.ndarray]]) -> float: + jacobians: Optional[List[np.ndarray]]) -> np.ndarray: """Landmark Factor error function :param measurement: Landmark measurement, to be filled with `partial` :param this: gtsam.CustomFactor handle From 8611aec3fb31698483f5afa5e2519de2ce61ddd0 Mon Sep 17 00:00:00 2001 From: Clark Taylor Date: Fri, 1 Sep 2023 14:17:04 -0400 Subject: [PATCH 3/4] Update CustomFactors.md to document return type. --- python/CustomFactors.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/CustomFactors.md b/python/CustomFactors.md index 079bcaa85e..39a840e349 100644 --- a/python/CustomFactors.md +++ b/python/CustomFactors.md @@ -17,7 +17,8 @@ def error_func(this: gtsam.CustomFactor, v: gtsam.Values, H: List[np.ndarray]) - `this` is a reference to the `CustomFactor` object. This is required because one can reuse the same `error_func` for multiple factors. `v` is a reference to the current set of values, and `H` is a list of -**references** to the list of required Jacobians (see the corresponding C++ documentation). +**references** to the list of required Jacobians (see the corresponding C++ documentation). Note that +the error returned must be a 1D numpy array. If `H` is `None`, it means the current factor evaluation does not need Jacobians. For example, the `error` method on a factor does not need Jacobians, so we don't evaluate them to save CPU. If `H` is not `None`, From 039f5cf7110daefe0299688b44ee7a9b604f06ca Mon Sep 17 00:00:00 2001 From: Clark Taylor Date: Fri, 1 Sep 2023 14:18:45 -0400 Subject: [PATCH 4/4] Update CustomFactorExample.py with comments to explain typing --- python/gtsam/examples/CustomFactorExample.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/gtsam/examples/CustomFactorExample.py b/python/gtsam/examples/CustomFactorExample.py index 1a8d1a61d3..a78562ecb7 100644 --- a/python/gtsam/examples/CustomFactorExample.py +++ b/python/gtsam/examples/CustomFactorExample.py @@ -15,7 +15,7 @@ import gtsam import numpy as np -I = np.eye(1) +I = np.eye(1) # Creates a 1-element, 2D array def simulate_car() -> List[float]: @@ -44,7 +44,7 @@ def error_gps(measurement: np.ndarray, this: gtsam.CustomFactor, if jacobians is not None: jacobians[0] = I - return error + return error # with input types this is a 1D np.ndarray def error_odom(measurement: np.ndarray, this: gtsam.CustomFactor,