symforce-org / symforce

Fast symbolic computation, code generation, and nonlinear optimization for robotics
https://symforce.org
Apache License 2.0
1.41k stars 145 forks source link

Robot 2d localization example fails with RuntimeError #308

Closed johhat closed 1 year ago

johhat commented 1 year ago

Describe the bug With symforce release 0.8.0 the robot_2d_localization.py example fails with the following runtime error

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/symforce/examples/robot_2d_localization/robot_2d_localization.py", line 213, in <module>
    main()
  File "/usr/local/lib/python3.8/site-packages/symforce/examples/robot_2d_localization/robot_2d_localization.py", line 122, in main
    result = optimizer.optimize(initial_values)
  File "/usr/local/lib/python3.8/site-packages/symforce/opt/optimizer.py", line 250, in optimize
    stats = self._cc_optimizer.optimize(cc_values)
RuntimeError: SYM_ASSERT: linearized_factor->index.tangent_dim == linearized_factor->jacobian.cols()
    --> void sym::Factor<ScalarType>::Linearize(const sym::Values<Scalar>&, sym::Factor<ScalarType>::LinearizedDenseFactor*, const std::vector<sym::index_entry_t>*) const [with ScalarType = double; sym::Factor<ScalarType>::LinearizedDenseFactor = sym::linearized_dense_factor_t]
    --> /project/symforce/opt/factor.cc:102

To Reproduce Run the robot 2d localization example with release 0.8.0.

Environment A container generated with the following Dockerfile

FROM python:3.8.16
RUN pip3 install symforce==0.8.0 # Runs successfully if version is changed to 0.7.0
RUN pip3 install matplotlib
CMD ["python", "/usr/local/lib/python3.8/site-packages/symforce/examples/robot_2d_localization/robot_2d_localization.py"]

Additional context I first encountered the error when testing a scalar residual as a function of sf.Pose3. Dummy example to reproduce the error is included in the collapsed section below.

Example

```python import symforce symforce.set_epsilon_to_symbol("epsilon") import sym import symforce.symbolic as sf from symforce.opt.factor import Factor from symforce.opt.optimizer import Optimizer from symforce.values import Values def dummy_residual(pose: sf.Pose3) -> sf.V1: return sf.V1(pose.t[2]) def main(): values = Values( { "pose": sym.Pose3(t=[0, 0, 1]), } ) optimizer = Optimizer( factors=[ Factor( residual=dummy_residual, keys=["pose"], ) ], optimized_keys=["pose"], ) # Fails here with symforce===0.8.0, works with symforce==0.7.0 result = optimizer.optimize(values) if __name__ == "__main__": main() ```

aaron-skydio commented 1 year ago

Thanks - this is a bug in Factor.to_numeric_factor where we're generating a function that returns the jacobian as the wrong shape. Have a fix, will get it merged shortly

VineetTambe commented 1 year ago

Hey, I am facing the same issue - can you let me know what the fix was so that I can get it running on my end?

Additionally, when I run the robot 2d localisation example as provided in the symforce readme in the python notebook - I get the following error:

Cell In[8], line 1
----> 1 result = optimizer.optimize(initial_values)

File [~/symForce/env/lib/python3.10/site-packages/symforce/opt/optimizer.py:250](https://file+.vscode-resource.vscode-cdn.net/home/vrex/symForce/symforce_ws/pose_graph_opt/src/~/symForce/env/lib/python3.10/site-packages/symforce/opt/optimizer.py:250), in Optimizer.optimize(self, initial_guess)
    247 cc_values = self._cc_values(initial_guess)
    249 try:
--> 250     stats = self._cc_optimizer.optimize(cc_values)
    251 except ZeroDivisionError as ex:
    252     raise ZeroDivisionError("ERROR: Division by zero - check your use of epsilon!") from ex

RuntimeError: SYM_ASSERT: linearized_factor->index.tangent_dim == linearized_factor->jacobian.cols()
    --> void sym::Factor::Linearize(const sym::Values&, sym::Factor::LinearizedDenseFactor*, const std::vector*) const [with ScalarType = double; sym::Factor::LinearizedDenseFactor = sym::linearized_dense_factor_t]
    --> /project/symforce/opt/factor.cc:102

Am I missing some initialisation somewhere? I verified that I am passing symforce.numerical_epsilon as my epsilon value


I am using the following versions of sym packages: symforce 0.8.0 symforce-sym 0.8.0 sympy 1.11.1 python 3.10.6 ubuntu 22.04

aaron-skydio commented 1 year ago

Yeah the fix is this: https://github.com/symforce-org/symforce/commit/d8056975aeb14bcaf4aa64350a6e76ee7e4af5bb (it's unfortunate that GitHub doesn't link these properly).

That commit isn't in a release yet, so you'll want to install latest symforce instead. You can either install the latest wheels, which you can find in the symforce-wheels download in the Artifacts section here, or you can build SymForce from source (or you could apply that commit to your install manually).

VineetTambe commented 1 year ago

Okay, thanks!

pickles976 commented 1 year ago

I am still getting this error in symforce v0.8.0, when following along with the 3D optimizer tutorial.

ryan-brott-skydio commented 1 year ago

The fix @aaron-skydio mentioned is not in v0.8.0, so you'll need to follow the instructions in his comment to get the latest symforce.