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