diff --git a/CMakeLists.txt b/CMakeLists.txt index b0f67f6b5ddf374ac1116c777d40e7cce4a01966..05134485475e4e92fcd831738c3736f488384b69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ SET(${PROJECT_NAME}_HEADERS multibody/model.hpp multibody/visitor.hpp tools/timer.hpp + algorithm/rnea.hpp ) MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio") @@ -53,6 +54,7 @@ MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/spatial") MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/multibody") MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/multibody/joint") MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/tools") +MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/pinocchio/algorithm") FOREACH(header ${${PROJECT_NAME}_HEADERS}) GET_FILENAME_COMPONENT(headerName ${header} NAME) diff --git a/src/algorithm/rnea.hpp b/src/algorithm/rnea.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4288093ce28c7f66d60f69aa8db7a7a0154700fb --- /dev/null +++ b/src/algorithm/rnea.hpp @@ -0,0 +1,113 @@ +#ifndef __se3_rne_hpp__ +#define __se3_rne_hpp__ + +#include "pinocchio/multibody/visitor.hpp" +#include "pinocchio/multibody/model.hpp" + +namespace se3 +{ + inline const Eigen::VectorXd& + rnea(const Model & model, Data& data, + const Eigen::VectorXd & q, + const Eigen::VectorXd & v, + const Eigen::VectorXd & a); + +} // namespace se3 + +/* --- Details -------------------------------------------------------------------- */ +namespace se3 +{ + struct RneaForwardStep : public fusion::JointVisitor<RneaForwardStep> + { + typedef boost::fusion::vector< const se3::Model&, + se3::Data&, + const int&, + const Eigen::VectorXd &, + const Eigen::VectorXd &, + const Eigen::VectorXd & + > ArgsType; + + JOINT_VISITOR_INIT(RneaForwardStep); + + template<typename JointModel> + static int algo(const se3::JointModelBase<JointModel> & jmodel, + se3::JointDataBase<typename JointModel::JointData> & jdata, + const se3::Model& model, + se3::Data& data, + const int &i, + const Eigen::VectorXd & q, + const Eigen::VectorXd & v, + const Eigen::VectorXd & a) + { + using namespace Eigen; + using namespace se3; + + jmodel.calc(jdata.derived(),q,v); + + const Model::Index & parent = model.parents[i]; + data.liMi[i] = model.jointPlacements[i]*jdata.M(); + + if(parent>0) data.oMi[i] = data.oMi[parent]*data.liMi[i]; + else data.oMi[i] = data.liMi[i]; + + data.v[i] = jdata.v(); + if(parent>0) data.v[i] += data.liMi[i].actInv(data.v[parent]); + + jmodel.jointMotion(a); + data.a[i] = jdata.S()*jmodel.jointMotion(a) + jdata.c() + (data.v[i] ^ jdata.v()) ; + if(parent>0) data.a[i] += data.liMi[i].actInv(data.a[parent]); + + data.f[i] = model.inertias[i]*data.a[i] + model.inertias[i].vxiv(data.v[i]); // -f_ext + return 0; + } + + }; + + struct RneaBackwardStep : public fusion::JointVisitor<RneaBackwardStep> + { + typedef boost::fusion::vector<const Model&, + Data&, + const int &> ArgsType; + + JOINT_VISITOR_INIT(RneaBackwardStep); + + template<typename JointModel> + static void algo(const JointModelBase<JointModel> & jmodel, + JointDataBase<typename JointModel::JointData> & jdata, + const Model& model, + Data& data, + int i) + { + const Model::Index & parent = model.parents[i]; + jmodel.jointForce(data.tau) = jdata.S().transpose()*data.f[i]; + if(parent>0) data.f[parent] += data.liMi[i].act(data.f[i]); + } + }; + + inline const Eigen::VectorXd& + rnea(const Model & model, Data& data, + const Eigen::VectorXd & q, + const Eigen::VectorXd & v, + const Eigen::VectorXd & a) + { + data.v[0] = Motion::Zero(); + data.a[0] = -model.gravity; + + for( int i=1;i<model.nbody;++i ) + { + RneaForwardStep::run(model.joints[i],data.joints[i], + RneaForwardStep::ArgsType(model,data,i,q,v,a)); + } + + for( int i=model.nbody-1;i>0;--i ) + { + RneaBackwardStep::run(model.joints[i],data.joints[i], + RneaBackwardStep::ArgsType(model,data,i)); + } + + return data.tau; + } +} // namespace se3 + +#endif // ifndef __se3_rne_hpp__ + diff --git a/unittest/rnea.cpp b/unittest/rnea.cpp index 94eaccc59d00856ab86cf287ce6daa50ff223b80..522f49c9de530899adb88ce212c012cfd45cd298 100644 --- a/unittest/rnea.cpp +++ b/unittest/rnea.cpp @@ -3,85 +3,12 @@ #include "pinocchio/multibody/joint.hpp" #include "pinocchio/multibody/visitor.hpp" #include "pinocchio/multibody/model.hpp" +#include "pinocchio/algorithm/rnea.hpp" #include <iostream> #include "pinocchio/tools/timer.hpp" - - -namespace se3 -{ - - struct RneaForwardStep : public fusion::JointVisitor<RneaForwardStep> - { - typedef boost::fusion::vector< const se3::Model&, - se3::Data&, - const int&, - const Eigen::VectorXd &, - const Eigen::VectorXd &, - const Eigen::VectorXd & - > ArgsType; - - JOINT_VISITOR_INIT(RneaForwardStep); - - template<typename JointModel> - static int algo(const se3::JointModelBase<JointModel> & jmodel, - se3::JointDataBase<typename JointModel::JointData> & jdata, - const se3::Model& model, - se3::Data& data, - const int &i, - const Eigen::VectorXd & q, - const Eigen::VectorXd & v, - const Eigen::VectorXd & a) - { - using namespace Eigen; - using namespace se3; - - jmodel.calc(jdata.derived(),q,v); - - const Model::Index & parent = model.parents[i]; - data.liMi[i] = model.jointPlacements[i]*jdata.M(); - - if(parent>0) data.oMi[i] = data.oMi[parent]*data.liMi[i]; - else data.oMi[i] = data.liMi[i]; - - data.v[i] = jdata.v(); - if(parent>0) data.v[i] += data.liMi[i].actInv(data.v[parent]); - - jmodel.jointMotion(a); - data.a[i] = jdata.S()*jmodel.jointMotion(a) + jdata.c() + (data.v[i] ^ jdata.v()) ; - if(parent>0) data.a[i] += data.liMi[i].actInv(data.a[parent]); - - data.f[i] = model.inertias[i]*data.a[i] + model.inertias[i].vxiv(data.v[i]); // -f_ext - return 0; - } - - }; - - - struct RneaBackwardStep : public fusion::JointVisitor<RneaBackwardStep> - { - typedef boost::fusion::vector<const Model&, - Data&, - const int &> ArgsType; - - JOINT_VISITOR_INIT(RneaBackwardStep); - - template<typename JointModel> - static void algo(const JointModelBase<JointModel> & jmodel, - JointDataBase<typename JointModel::JointData> & jdata, - const Model& model, - Data& data, - int i) - { - const Model::Index & parent = model.parents[i]; - jmodel.jointForce(data.tau) = jdata.S().transpose()*data.f[i]; - if(parent>0) data.f[parent] += data.liMi[i].act(data.f[i]); - } - }; - -} // namespace se3 //#define __SSE3__ #include <fenv.h> @@ -141,28 +68,17 @@ int main() model.addBody(model.getBodyId("larm6"),JointModelRX(),SE3::Random(),Inertia::Random(),"lgrip"); se3::Data data(model); + data.v[0] = Motion::Zero(); + data.a[0] = -model.gravity; VectorXd q = VectorXd::Random(model.nq); VectorXd v = VectorXd::Random(model.nv); VectorXd a = VectorXd::Random(model.nv); - - data.v[0] = Motion::Zero(); - data.a[0] = -model.gravity; StackTicToc timer(StackTicToc::US); timer.tic(); SMOOTH(1000) { - for( int i=1;i<model.nbody;++i ) - { - RneaForwardStep::run(model.joints[i],data.joints[i], - RneaForwardStep::ArgsType(model,data,i,q,v,a)); - } - - for( int i=model.nbody-1;i>0;--i ) - { - RneaBackwardStep::run(model.joints[i],data.joints[i], - RneaBackwardStep::ArgsType(model,data,i)); - } + rnea(model,data,q,v,a); } timer.toc(std::cout,1000);