Source code for symforce.opt.objectives.prior_value_objective

# ----------------------------------------------------------------------------
# SymForce - Copyright 2022, Skydio, Inc.
# This source code is under the Apache 2.0 license found in the LICENSE file.
# ----------------------------------------------------------------------------
from __future__ import annotations

from dataclasses import dataclass

import symforce.symbolic as sf
from symforce import typing as T
from symforce.ops import LieGroupOps
from symforce.opt import noise_models
from symforce.opt import objective
from symforce.opt.residual_block import ResidualBlock


[docs]class PriorValueObjective(objective.TimestepObjective):
[docs] @dataclass class ExtraValues: """ Attributes: unwhitened_residual: The tangent-space error between ``actual`` and ``desired``. """ unwhitened_residual: sf.Matrix
[docs] @staticmethod def residual_at_timestep( actual: T.Element, desired: T.Element, information_diag: T.Sequence[sf.Scalar], epsilon: sf.Scalar, cost_scaling: sf.Scalar = 1, ) -> ResidualBlock: """ Returns the residual block for the given timestep, where the residual is computed as the weighted tangent-space difference between ``actual`` and ``desired``. Args: actual: Typically an element to be optimized in the optimization problem. desired: The desired value of the element to be optimized, or equivalently the prior we have on ``actual``. information_diag: List of scalars defining how each element of the tangent-space vector representing the transform between ``actual`` and ``desired`` is weighted. For example, if ``actual`` and ``desired`` are 3D positions represented by sf.V3 objects, the first, second, and third elements of ``information_diag`` represent how the x, y, and z errors are weighted. epsilon: A small number used to avoid singularities. cost_scaling: Optional scaling parameter. Corresponds to multiplying the cost in the overall optimization problem by a constant. """ unwhitened_residual = sf.Matrix(LieGroupOps.local_coordinates(desired, actual, epsilon)) noise_model = noise_models.DiagonalNoiseModel( information_diag=[cost_scaling * c for c in information_diag] ) whitened_residual = noise_model.whiten(unwhitened_residual) return ResidualBlock( residual=whitened_residual, extra_values=PriorValueObjective.ExtraValues(unwhitened_residual=unwhitened_residual), )