Re: [eigen] Eigen and rigid body simulation

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]



We keep the initial concept map approach, and to ease the writing of
algorithms we add a trivial and generic LieWrapper<>  class allowing to
temporarily use a Lie element with a nicer API:

template<class G>
struct LieWrapper {
    typedef Lie<G>  L;

    G inverse() const { return L::inverse(m_element); }
    G operator*(const G&  other) const { return
L::comp(m_element,other.element()); }

    G exp() const { return L::exp()(m_element); }

    // ...

   protected:
     G&  m_element;
};


After trying to implement this, it seems we don't need both a concept map and
a wrapper since one is going to copy the other anyway. So only the wrapper
seems fine. It's quite convenient to use so far.

Also I came across a (minor) problem with this approach: what if you need to
modify the wrapped element ?

We cannot only wrap lvalues, so we have to have two flavours of LieWrapper
depending on constness and well, this gets complicated. Or am I missing
something ?

If not, this means we can only specialize for Lie groups when parameters are
const (otherwise we need a G&  reference). Does not look like a big deal to me.

Best regards,



max.


Hi,

Excuse me for the pause, but I didn't have enough time to work on the Lie module since last month and I'm a bit rusty :)

My main concern about the concept map and the wrapper is that we have to use three classes to handle an element of a Lie group, the concept map class, the wrapper class and the wrapped class. Maxime had tried an implementation only with a wrapper but he couldn't wrap lvalues (btw, I'm interesting in seeing this implementation). In any cases, a final user have to use, at least two classes, the wrapper and the wrapped class, since the wrapper return an instance of the wrapped class.

I think it's two complicated in my case, mainly beacause of my end users :) . I aim to have only one class, let's say for an element of SE(3), something like LieGroup<Matrix<double, 1, 7> > which I could typedef with a name more approriate for physic simulation. I also don't want to use staitc function so a s to keep writing a=b*c.

Just to resume, Maxime concerns were :
1/ not modifying base classes
2/ building new groups from a existing ones (through pairs, tuple, etc.)

So, I try the following design, where the Wrapper own not an reference but an instance of G. I use only LieGroup<G> in order to perform operation on the group.

template<class G> struct LieGroup{
  LieGroup<G> inverse() const { return LieGroup<G> m_element.inverse()); }
template<class H> LieGroup<G> operator*(const LieGroup<H>& other) const { return LieGroup<G>(m_element* other.get()); }

  template<class H> LieGroup& operator=(const LieGroup<H>& other){
    m_element = other.get();
    return *this;
  }
  template<class H> LieGroup(const H& el) : m_element(el){};
  LieGroup(const double* data) : m_element(data){};
  LieGroup(){};

protected:
  G m_element;
};

the templated method, such as operator*, allows operation between LieGroup<G> and LieGroup<Map<G>> classes. Thus, I can interface my code with other libraries returning array of double. This first proposal has to be refined, for example the constructors are different for LieGroup<G> and LieGroup<Map<G>>, I am working on these issues.

I think that with these implementation we can achieve both Maxime and my requirements.

I can now define new type to ease the notation in my field of interest :

typedef LieGroup<Quaterniond> Rotation3D;
typedef LieGroup<Map<Quaterniond, 0> > Rotation3DMapd;
typedef LieGroup<Matrix<double,1,7> > Displacement;
etc.

I can then write something like  :

double data[4] = {1,3,4,5};

Rotd d, dr;
RotMapd dm(data);
dr = d *dm;

--
Mathieu



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/