symforce-org / symforce

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

Questions about `from_rotation_matrix()` for the `Rot2` class #403

Closed zhanghua7099 closed 4 weeks ago

zhanghua7099 commented 1 month ago

Hi! I found that in Rot3 class, it has the method from_rotation_matrix(): https://github.com/symforce-org/symforce/blob/04ccac19aa25bf657c1f312539fc6964fd402128/symforce/geo/rot3.py#L190

This enables converting a $3\times 3$ numpy matrix to symforce.

However, for Rot2 class, it seems only support convert from_angle() or from_tangent().

Could you please give me some suggestions about how to convert a SO(2) matrix to symforce?

Thank you very much!

aaron-skydio commented 1 month ago

to_rotation_matrix for Rot2 is this: https://github.com/symforce-org/symforce/blob/04ccac19aa25bf657c1f312539fc6964fd402128/symforce/geo/rot2.py#L148-L152

So to invert this, you could do:

def to_rotation_matrix(m: sf.M22) -> sf.Rot2:
    return sf.Rot2(sf.Complex(real=M[0, 0], imag=M[1, 0]))

There's should be a way of looking at all of the elements to give a Rot2 that's optimal e.g. by Frobenius norm when m is not exactly a rotation matrix, but I don't know the solution for that off the top of my head

zhanghua7099 commented 4 weeks ago

Thanks for your help! I assume the input matrix $R\in SO(2)$. In this situation, I found the method from_storage() possible to convert an SO(2) matrix to symforce. https://github.com/symforce-org/symforce/blob/04ccac19aa25bf657c1f312539fc6964fd402128/symforce/geo/rot2.py#L50

This is a simple demo. The input matrix W_init must in SO(2).

import sym
import numpy as np

W_init = np.eye(2)
W_sym = sym.rot2.Rot2.from_storage(W_init[:,0])

The first column of W_init will be the input of sym.rot2.Rot2.from_storage().