This repository has been archived by the owner on Nov 29, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Naive implementation First approach
Olivier Stasse edited this page Jul 28, 2014
·
8 revisions
Let us first define a robot joint with the following macro:
# define JOINT_REVOLUTE(classname) \
class classname \
{ \
public: \
enum { NBDOF = 1 }; \
static const std::string name; \
static const int label; \
static const int positionInConf; \
static const Spatial::Transform Xt; \
static Spatial::Transform sXp; \
static Spatial::Transform Xj; \
static Spatial::Motion cj; \
static Spatial::Motion vj; \
static const vector6d S; \
static const vector6d dotS; \
static Spatial::Force f; \
static vector1d torque; \
static vector6d F; \
\
static void jcalc(const vector1d & qi,\
const vector1d & dqi); \
};
A similar kind of macro may be used to declare a body. To specify the joint, the parameters are declared in the following way:
INITIALIZE_JOINT_REVOLUTE(RLEG_HIP_R);
const std::string RLEG_HIP_R::name =
"RLEG_HIP_R";
const int RLEG_HIP_R::label = 25;
const int RLEG_HIP_R::positionInConf = 6;
const Spatial::Transform RLEG_HIP_R::Xt =
Spatial::Transform(
matrix3dMaker(1, 0, 0,
0, 1, 0,
0, 0, 1),
vector3d(0, -0.09, 0));
Again a similar initialization procedure can be used for the bodies. When the elements are declared and specified, to build the kinematic tree, one can use a Node defined as follows :
// Class Node. Contains a Body,
// a Joint, and up to 3 Node children.
// Non-existant children make use
// of the NC class (No-Child).
template< typename B, // Body
typename J, // Joint
typename C1 = NC, // Children nodes
typename C2 = NC,
typename C3 = NC >
class Node
{
public:
typedef B Body;
typedef J Joint;
typedef C1 Child1;
typedef C2 Child2;
typedef C3 Child3;
};
Then the kinematic tree is defined recursively like this:
// Model of the robot.
// Contains data at the global robot level
// and the tree/ of Body/Joint
class METAPOD_DLLEXPORT Robot
{
public:
// Global constants or
// variable of the robot
enum { NBDOF = 35 };
static Eigen::
Matrix< FloatType,
NBDOF, NBDOF > H;
typedef Eigen::
Matrix< FloatType, NBDOF, 1 >
confVector;
// Definition of the multibody
// tree as a type.
typedef
Node< WAIST_LINK0,
WAIST,
Node< WAIST_LINK1,
WAIST_P,
Node< WAIST_LINK2,
WAIST_R,
Node< WAIST_LINK3,
CHEST,
Node< LARM_LINK1,
// ...
>,
Node< RARM_LINK1,
// ...
> > > >,
Node< LLEG_LINK1,
LLEG_HIP_R,
Node< LLEG_LINK2,
LLEG_HIP_P,
Node< LLEG_LINK3,
LLEG_HIP_Y,
Node< LLEG_LINK4,
LLEG_KNEE,
Node< LLEG_LINK5,
LLEG_ANKLE_P,
Node< LLEG_LINK6,
LLEG_ANKLE_R >
> > > > >,
Node< RLEG_LINK1,
RLEG_HIP_R,
Node< RLEG_LINK2,
RLEG_HIP_P,
Node< RLEG_LINK3,
RLEG_HIP_Y,
Node< RLEG_LINK4,
RLEG_KNEE,
Node< RLEG_LINK5,
RLEG_ANKLE_P,
Node< RLEG_LINK6,
RLEG_ANKLE_R >
> > > > > > Tree;
};
} // end of namespace simple_humanoid
The clear disadvantage with this approach is that the structure is storing the data directly in the class itself and not in an instance of this class. In the current version of metapod this is fixed by using boost::fusion.