Giter Site home page Giter Site logo

symforce-org / symforce Goto Github PK

View Code? Open in Web Editor NEW
1.3K 1.3K 143.0 11.72 MB

Fast symbolic computation, code generation, and nonlinear optimization for robotics

Home Page: https://symforce.org

License: Apache License 2.0

CMake 0.61% Makefile 0.11% Python 27.82% Shell 0.01% Jupyter Notebook 2.92% Jinja 3.55% C++ 63.59% C 0.03% Cuda 1.36%
autonomous-vehicles code-generation computer-vision cpp motion-planning optimization python robotics slam structure-from-motion symbolic-computation

symforce's People

Contributors

aaron-skydio avatar amiller27 avatar bradley-solliday-skydio avatar brian-kubisiak-skydio avatar chao-qu-skydio avatar danny-skydio avatar david-hug-skydio avatar dominic-skydio avatar eric-skydio avatar gareth-cross avatar harrison-skydio avatar hayk-skydio avatar jerry-skydio avatar jmackay2 avatar nathan-skydio avatar nlbucki avatar peter-skydio avatar roy-vorster-skydio avatar ryan-brott-skydio avatar ryan-skydio avatar samuel-wang-skydio avatar simutisernestas avatar vincent-lecrubier-skydio avatar vineettambe avatar william-almy-skydio avatar william-smith-skydio avatar xipeng-wang-skydio avatar xipengwang avatar zachary-teed-skydio avatar zhiqwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

symforce's Issues

Sparse matrices in Python

Generated python functions should support sparse matrix outputs (with scipy.sparse.csc_matrix). We should be able to generate factors with opt.Factor with sparse hessians, and linearize them into a wrapped linearized_sparse_factor_t

Docs cleanup

Make a pass over the docs to clean them up.

Components:

  • Update everything to current best practices and APIs
  • Add cross-references
  • Make sure things are formatted nicely
  • Make sure all doc comments in the code show up

Some kind of check that epsilons are provided

Something that dynamically either lets you use a default epsilon of 0 (for playing around in notebooks/tutorials), or guarantee that it's either a symbol or explicitly set to 0 (for avoiding bugs in actual generated code)

Assume symbol is sm.symbol('epsilon')

Have custom Symbol subclass where evalf() == 0

Add heuristics for tangent_jacobians

For example, if a and b are geo.Rot3s, then tangent_jacobians(a * b, [b])[0] should be the identity matrix, but our current answer doesn't yield that.

Find ways to get expressions for jacobians with fewer ops than we currently use (using things like unit norm constraints and whatnot).

Fail on generating LCM types with eigen_lcm.Vector10d+ etc

This should fail at generation time, currently fails to find the expected bindings at compile time

We currently also don’t handle 2d matrices at all really. We generate all matrices as 1d storage vectors. eigen_lcm also only has square matrices and vectors, so if we want to generate matrices and not just storage, we’ll have to fail on non-square matrices.

Docs CD

Regenerate docs automatically from symforce master

Reverse lookup of generated sym::Keys

Maybe constexpr function?

constexpr const char* KeyToSymbol(const sym::Key& key) {
  if (key == Var::VAR1) {
  } else {
    return "INVALID";
  }
}

Add function to sym::Values to take this and print with the symbol names

cam in Python

Generate all the cam stuff in Python like it is in C++

METIS CMake deprecation warning

CMake deprecation warnings from gklib and metis

CMake Deprecation Warning at build/_deps/gklib-src/CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


CMake Deprecation Warning at build/_deps/metis-src/CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.

PyPI deploy

Deploy automatically to PyPI (or set up tooling to do this manually in a way that's documented and straightforward)

Get docs hosted

Get symforce docs set up hosted somewhere that's publicly visible

Fix float equality in symengine

In [1]: import sympy as sm

In [2]: sm.S(0) == 0
Out[2]: True

In [3]: sm.S(0) == 0.0
Out[3]: True

In [4]: import symengine as sm

In [5]: sm.S(0) == 0
Out[5]: True

In [6]: sm.S(0) == 0.0
Out[6]: False

Cameras, especially PosedCamera, in C++ Values

Multiple people have requested this

Thoughts:

Store in Values

Don't want Retract for spherical, but want to store in Values

Nice to have generic "retract using data as a vector space"

VectorSpaceLieGroupOps to inherit from or something?

For image_size:

Make retract preserve image size

Probably doesn't work for from_tangent, but that should be fine (just set -1)

Can not implement compose, but custom implementation of retract to preserve not optimized stuff

Specify first n of storage vector which are optimized, rest are copied

pip install .

Run the entire build, including CMake, through setup.py, so that users can install from source with just pip install .. Useful reference might be the symenginepy build

Segfault in METIS

segfault in metis for exactly five optimized variables 🤯

best example I have currently, just dealing with two-vectors. the commented out jacobians/hessians look fine to me. any other chain length seems to work fine

import functools
import numpy as np

from symforce import geo
from symforce import sympy as sm
from symforce.opt.factor import Factor
from symforce.opt.optimizer import Optimizer
from symforce.values import Values

import sym


def between(x: geo.V2, y: geo.V2) -> geo.V2:
    return x - y


# if this is 4 or 6 or any other number I tried so far, it works
num_samples = 5
x_keys = [f"x{i}" for i in range(num_samples)]


values = Values()
for i in range(num_samples):
    values[x_keys[i]] = np.array([1, 2])
print(values)

factors = []

for i in range(num_samples - 1):
    factor = Factor(keys=[x_keys[i], x_keys[i + 1]], residual=between)
    factors.append(factor)

    # factor._generate_python_function(optimized_keys=factor.keys)
    # res, jac, hes, rhs = factor.generated_residual(values[x_keys[i]], values[x_keys[i + 1]])
    # print(jac)
    # import ipdb; ipdb.set_trace()

x_prior = geo.V2(1, 0)
prior_factor = Factor(
    keys=[x_keys[0]], name="prior", residual=functools.partial(between, y=x_prior)
)
factors.append(prior_factor)

# prior_factor._generate_python_function(prior_factor.keys)
# res, jac, hes, rhs = prior_factor.generated_residual(values[xs[0]])
# print(jac)

optimizer = Optimizer(factors=factors, optimized_keys=values.keys(), params=Optimizer.Params())

# segfault here in metis computing ordering
result = optimizer.optimize(values)

print(f"x_prior: {x_prior.T}")
print(result.initial_values)
print(result.optimized_values)
print(f"num iters: {len(result.iteration_stats)}")
print(f"final error: {result.error()}")

I added a print in SparseCholeskySolver<MatrixType, UpLo>::ComputePermutationMatrix, just before the failing line to ordering_(A_selfadjoint, inv_permutation_) to convert to dense and print:

Dense A_selfadjoint:
 1  0 -1  0  0  0  0  0  0  0
 0  1  0 -1  0  0  0  0  0  0
-1  0  1  0 -1  0  0  0  0  0
 0 -1  0  1  0 -1  0  0  0  0
 0  0 -1  0  1  0 -1  0  0  0
 0  0  0 -1  0  1  0 -1  0  0
 0  0  0  0 -1  0  1  0 -1  0
 0  0  0  0  0 -1  0  1  0 -1
 0  0  0  0  0  0 -1  0  1  0
 0  0  0  0  0  0  0 -1  0  1

with num_samples = 6, structure is the same

Dense A_selfadjoint:
 1  0 -1  0  0  0  0  0  0  0  0  0
 0  1  0 -1  0  0  0  0  0  0  0  0
-1  0  1  0 -1  0  0  0  0  0  0  0
 0 -1  0  1  0 -1  0  0  0  0  0  0
 0  0 -1  0  1  0 -1  0  0  0  0  0
 0  0  0 -1  0  1  0 -1  0  0  0  0
 0  0  0  0 -1  0  1  0 -1  0  0  0
 0  0  0  0  0 -1  0  1  0 -1  0  0
 0  0  0  0  0  0 -1  0  1  0 -1  0
 0  0  0  0  0  0  0 -1  0  1  0 -1
 0  0  0  0  0  0  0  0 -1  0  1  0
 0  0  0  0  0  0  0  0  0 -1  0  1

GDB backtrace shows the segfault in libmetis__genmmd

Generate C++ from Factor

First generate C++ from factor

Also be able to compile that factor from python and pass to python optimizer

std::bind-like option for Factor creation

std::bind(&sym::BetweenRot3<double>, /* a */ _1, /* b */ _2,
                  /* between_a_b */ geo::Rot3d::Identity(),
                  /* sigmas */ Eigen::Vector3d::Constant(between_sigma), epsilon, /* res */ _3,
                  /* jac */ _4),

sym::Bind(

Separate Manifold and LieGroup

We might want to have a Manifold spec for things that are differentiable manifolds that we might want to optimize over (e.g. camera calibrations) but that aren't Lie groups, and then have LieGroup be a Group and a Manifold

pip install symforce

Make it possible to pip install symforce from PyPI; this may not include making it easy to repeatedly do so, see #29

Generated `__init__.py` with multiple functions takes the last

A minimal example:

from symforce import codegen
from symforce import typing as T

def a(x: T.Scalar):
        return x + 1

def b(x: T.Scalar):
        return x + 2

output_dir = "<something>"
codegen.Codegen.function(a, config=codegen.PythonConfig()).generate_function(output_dir=output_dir)
codegen.Codegen.function(b, config=codegen.PythonConfig()).generate_function(output_dir=output_dir)

Then output_dir/python/symforce/sym/__init__.py will contain:

# -----------------------------------------------------------------------------
# This file was autogenerated by symforce from template:
#     python_templates/function/__init__.py.jinja
# Do NOT modify by hand.
# -----------------------------------------------------------------------------

from .b import b

Fix SymEngine Max derivative

This seems wrong:

sm.Max(x, y).diff(x).subs({x:y})

evaluates to 1/2

Also check in on derivatives of other things we added

Faster interactive python workflow

Need to make this better, and then split out remaining items into additional TODOs

P1: The interactive workflow is too slow. The following 10 rotation chain takes 4.8 seconds to generate

image

2.9 seconds is rendering template, of which 2 seconds is calling black (lol), .8 seconds is calling string join inside of the template, and a small fraction is actually rendering
image

  • We’re calling black.format_str 38 times. we should probably disable this for interactive use - flag in the language args of codegen?
    • I made an option to LanguageArgs to not autoformat. Perhaps controversial, but I’d propose to turn it off for the python Factor by default.
  • Now str join is taking all the time of render template. What’s up with that?
  • Why 38 times? We have 19 factors, so must be twice per factor.
    • What’s the second python file per factor? An __init__.py file from symforce/symforce/codegen/python_templates/function/__init__.py.jinja. Gross.
    • All prior and between factors should be the same expression. Can we only generate two?
  • 2 seconds is in codegen_util.print_code. Seems like a lot of subs operations and list comprehensions, as well as some time in the sympy printer tree. Probably lots to optimize.

image

  • A ton of time is being spent in subs in codegen_util.perform_cse, basically all initialization._get_subs_dict_flatten_storage_type_subs → mostly python_util.scalar_like. We should work on reducing the calls to these or making them faster.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.