Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute the whole-body-inertia and the average-angular-velocity. #75

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
60051c1
[New function] to compute the cetroidal inertia and average centroida…
wyqsnddd Aug 17, 2020
c521fa7
More comments on the centroidal inertia computation.
wyqsnddd Aug 17, 2020
fad794a
[Minor] Use Eigen::Vector6d instead of sva::ForceVecd
wyqsnddd Aug 19, 2020
c99d108
[clang-format]
wyqsnddd Aug 21, 2020
c56ddf7
[cmake] Restore submodule to current RBDyn master
gergondet Aug 22, 2020
b076d81
[comment-fix] according to issue: #75.
wyqsnddd Aug 22, 2020
e639239
[Improvement] matrix inversion and the for-loop for computing centroi…
wyqsnddd Aug 24, 2020
e8e4218
[Improvement] matrix inversion and the for-loop for computing centroi…
wyqsnddd Aug 24, 2020
0f4c318
Fix the commit message to link to #75
wyqsnddd Aug 24, 2020
4dd27a9
[New function] to compute the cetroidal inertia and average centroida…
wyqsnddd Aug 17, 2020
08893b4
More comments on the centroidal inertia computation.
wyqsnddd Aug 17, 2020
b8f80d9
[Minor] Use Eigen::Vector6d instead of sva::ForceVecd
wyqsnddd Aug 19, 2020
8263384
[clang-format]
wyqsnddd Aug 21, 2020
eaad080
[cmake] Restore submodule to current RBDyn master
gergondet Aug 22, 2020
0737a19
[comment-fix] according to issue: #75.
wyqsnddd Aug 22, 2020
ecf3faf
[Improvement] matrix inversion and the for-loop for computing centroi…
wyqsnddd Aug 24, 2020
5da5f10
Fix warning
gergondet Aug 27, 2020
456756d
Add a test for computeCentroidalInertia
gergondet Aug 27, 2020
22d4cf0
Merge branch 'whole-body-inertia' of github.com:wyqsnddd/RBDyn into w…
wyqsnddd Oct 24, 2020
e0f18aa
[WIP] [Medium] Tried to implement the improved CMM matrix computation…
wyqsnddd Dec 1, 2020
7d98488
[Minor]
wyqsnddd Jan 19, 2022
1315f28
[Unknown modifications]
wyqsnddd Jan 19, 2022
f7cb24f
Merge branch 'whole-body-inertia' of github.com:wyqsnddd/RBDyn into w…
wyqsnddd Jan 19, 2022
8d0613b
Merge branch 'master' into whole-body-inertia
wyqsnddd Jan 19, 2022
7cdee58
[Debug] see #75
ywang-robotics Sep 28, 2022
e3f71b9
Fixed the alpha calculation.
ywang-robotics Oct 3, 2022
0625ae6
Update submodule cmake
ywang-robotics Jun 12, 2024
fab9934
Merge branch 'master' into whole-body-inertia
ywang-robotics Jun 12, 2024
3ba4ae8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake
Submodule cmake updated 56 files
+1 −1 .github/workflows/cmake.yml
+2 −0 .gitignore
+56 −53 .pre-commit-config.yaml
+127 −0 CMakeLists.txt
+5 −1 Config.cmake.in
+0 −5 GNUInstallDirs.cmake
+7 −3 README.md
+25 −0 _unittests/catkin/CMakeLists.txt
+1 −1 _unittests/cpp/CMakeLists.txt
+1 −1 _unittests/dependency/CMakeLists.txt
+1 −1 _unittests/python/CMakeLists.txt
+31 −1 _unittests/run_unit_tests.sh
+0 −1 _unittests/test_pkg-config.cmake
+13 −29 base.cmake
+0 −5 boost/FindBoost.cmake
+2 −3 cmake_reinstall.cmake.in
+7 −8 cmake_uninstall.cmake.in
+128 −39 compiler.cmake
+28 −2 config.hh.cmake
+9 −0 cxx-standard.cmake
+6 −42 cxx11.cmake
+1 −1 cython/python/FindPython/Support.cmake
+22 −4 doxygen.cmake
+35 −0 find-external/Accelerate/FindAccelerate.cmake
+13 −0 find-external/CDD/FindCDD.cmake
+121 −0 find-external/CHOLMOD/FindCHOLMOD.cmake
+13 −0 find-external/CLP/FindCLP.cmake
+60 −0 find-external/CoinUtils/FindCoinUtils.cmake
+9 −2 find-external/GMP/FindGMP.cmake
+9 −2 find-external/MPFR/FindMPFR.cmake
+0 −7 find-external/OpenMP/FindOpenMP.cmake
+94 −0 find-external/TinyXML/FindTinyXML2.cmake
+124 −98 find-external/assimp/Findassimp.cmake
+14 −0 find-external/glpk/Findglpk.cmake
+19 −0 find-external/qpOASES/FindqpOASES.cmake
+17 −6 git-archive-all.sh
+1 −1 gtest/CMakeLists.txt.in
+59 −14 header.cmake
+2 −2 ide.cmake
+1 −5 logging.cmake
+39 −0 memorycheck_unit_test.cmake.in
+0 −4 msvc-specific.cmake
+5 −2 package-config.cmake
+21 −0 package.xml
+30 −0 pixi.py
+0 −1 pkg-config.cmake
+85 −51 python.cmake
+0 −171 python/FindPythonInterp.cmake
+0 −399 python/FindPythonLibs.cmake
+88 −37 release.cmake
+1 −1 stubgen/CMakeLists.txt.in
+30 −6 stubs.cmake
+101 −21 test.cmake
+29 −6 uninstall.cmake
+0 −3 version-script.cmake
+5 −1 version.cmake
94 changes: 93 additions & 1 deletion src/RBDyn/Momentum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

// associated header
#include "RBDyn/Momentum.h"

// includes
// RBDyn
#include "RBDyn/Jacobian.h"
Expand All @@ -13,6 +12,99 @@

namespace rbd
{
void computeCentroidalInertia(const MultiBodyConfig & mbc,
const Eigen::MatrixXd & massMatrix,
const Eigen::VectorXd & nMatrix,
const Eigen::Vector3d & com,
Eigen::Matrix6d & cmm,
Eigen::Vector6d & cmmdqd)
{

using namespace Eigen;

Eigen::MatrixXd selection;

selection.resize(6, massMatrix.cols());
selection.block<6, 6>(0, 0).setIdentity();

// Force transform from the floating-base frame to the centroidal frame

sva::PTransformd X_fb_0 = mbc.bodyPosW[0].inv();

sva::PTransformd X_G_0(Vector3d(-com));

// Eigen::Matrix6d phi_tran_inv = (X_G_0.matrix().transpose()).inverse();

sva::PTransformd phi_inv = X_G_0.inv();

sva::PTransformd X_fb_G = X_G_0.inv() * X_fb_0;

cmm = X_fb_G.matrix().transpose() * phi_inv.matrix().transpose() * selection * massMatrix;
// cmm = X_fb_G.dualMatrix() * phi_inv.matrix().transpose() * selection * massMatrix;
// cmm = X_fb_G.dualMatrix() * phi_tran_inv * selection * massMatrix;
cmmdqd = X_fb_G.matrix().transpose() * phi_inv.matrix().transpose() * selection * nMatrix;
// cmmdqd = X_fb_G.dualMatrix() * phi_inv.matrix().transpose() * selection * nMatrix;
// cmmdqd = X_fb_G.dualMatrix() * phi_tran_inv * selection * nMatrix;
}

void computeCentroidalInertia(const Eigen::MatrixXd & massMatrix, const Eigen::Vector3d & com, Eigen::Matrix6d & ci)
{

using namespace Eigen;

sva::PTransformd X_com_0(Vector3d(-com));

ci = X_com_0.matrix().transpose() * massMatrix.block<6, 6>(0, 0) * X_com_0.matrix();
}

void computeCentroidalInertia(const MultiBody & mb,
const MultiBodyConfig & mbc,
const Eigen::Vector3d & com,
Eigen::Matrix6d & ci,
Eigen::Vector6d & av)
{

using namespace Eigen;

const std::vector<Body> & bodies = mb.bodies();
av = Vector6d::Zero();

ci = Matrix6d::Identity();

// Inertial frame's origin in the COM frame
sva::PTransformd X_com_0(Vector3d(-com));
sva::PTransformd g_0_com(Vector3d(com));
size_t nrBodies = static_cast<size_t>(mb.nrBodies());
for(size_t i = 0; i < nrBodies; ++i)
{
// body momentum in body coordinate
sva::ForceVecd hi = bodies[i].inertia() * mbc.bodyVelB[i];

// X_com_i = X_i_0 * X_com_0
auto X_com_i = mbc.bodyPosW[i] * X_com_0;

// Momentum at CoM for link i : {}^iX_{com}^T {}^iI_i {}^iV_i
// av += X_com_i.transMul(hi).vector();
av += X_com_i.matrix().transpose() * hi.vector();

// Sum: X^T_com_i*I_i*X_com_i
ci += X_com_i.matrix().transpose() * bodies[i].inertia().matrix() * X_com_i.matrix();
}

ci.llt().solveInPlace(av);
}

void computeCentroidalInertia(const MultiBody & mb,
const MultiBodyConfig & mbc,
const Eigen::Vector3d & com,
Eigen::Matrix6d & ci,
Eigen::Vector6d & cm,
Eigen::Vector6d & av)
{
computeCentroidalInertia(mb, mbc, com, ci, av);
// Compute the centroidal momentum := inertia * average velocity
cm = ci * av;
}

sva::ForceVecd computeCentroidalMomentum(const MultiBody & mb, const MultiBodyConfig & mbc, const Eigen::Vector3d & com)
{
Expand Down
62 changes: 62 additions & 0 deletions src/RBDyn/RBDyn/Momentum.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,68 @@ struct Block;
using Blocks = std::vector<Block>;
class Jacobian;

/**
* Compute the centroidal inertia (ci) following the
* paper by [Wensing and Orin, IJHR, 2016].
* @param massMatrix.
* @param nMatrix coriolios and gravity: C * qDot.
* @param com CoM position.
* @param cmm The centroidal momentum matrix.
* @param cmmd The derivative of the centroidal momentum matrix.
*/
RBDYN_DLLAPI void computeCentroidalInertia(const MultiBodyConfig & mbc,
const Eigen::MatrixXd & massMatrix,
const Eigen::VectorXd & nMatrix,
const Eigen::Vector3d & com,
Eigen::Matrix6d & cmm,
Eigen::Vector6d & cmmdqd);

/**
* Compute the centroidal inertia (ci) following the
* paper by [Wensing and Orin, IJHR, 2016].
* @param massMatrix .
* @param com CoM position.
* @param ci Centroidal inertia at the Centroidal frame.
*/
RBDYN_DLLAPI void computeCentroidalInertia(const Eigen::MatrixXd & massMatrix,
const Eigen::Vector3d & com,
Eigen::Matrix6d & ci);

/**
* Compute the centroidal inertia (ci), centroidal momentum (cm),
* and the average velocity (av = ci^-1*cm)
* at the CoM frame as describe in [Orin and Gosawami 2008].
* @param mb MultiBody used has model.
* @param mbc Use bodyPosW, bodyVelB.
* @param com CoM position.
* @param ci Centroidal inertia at the Centroidal frame.
* @param cm centroidal momentum at the Centroidal frame.
* @param av Average velocity is: av = ci.inverse()*cm
*/
RBDYN_DLLAPI void computeCentroidalInertia(const MultiBody & mb,
const MultiBodyConfig & mbc,
const Eigen::Vector3d & com,
Eigen::Matrix6d & ci,
Eigen::Vector6d & cm,
Eigen::Vector6d & av);
/**
* Compute the centroidal inertia (ci), centroidal momentum (cm),
* and the average velocity (av = ci^-1*cm)
* at the CoM frame as describe in [Orin and Gosawami 2008].
* @param mb MultiBody used has model.
* @param mbc Use bodyPosW, bodyVelB.
* @param com CoM position.
* @param ci Centroidal inertia at the Centroidal frame.
* @param av Average velocity is inverse(centroidalInertia)*centroidalMomentum
gergondet marked this conversation as resolved.
Show resolved Hide resolved
*
* If the Centroidal Momentum is needed, we can easily compute it as: cm = ci*av.
*/
RBDYN_DLLAPI void computeCentroidalInertia(const MultiBody & mb,
const MultiBodyConfig & mbc,
const Eigen::Vector3d & com,
Eigen::Matrix6d & ci,
Eigen::Vector6d & av);

/**
* Compute the centroidal momentum at the CoM frame
* as describe in [Orin and Gosawami 2008].
Expand Down
129 changes: 128 additions & 1 deletion tests/MomentumTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

// includes
// std
#include <SpaceVecAlg/SpaceVecAlg>

#include <iostream>

// boost
Expand All @@ -13,6 +15,7 @@
// RBDyn
#include "RBDyn/CoM.h"
#include "RBDyn/FA.h"
#include "RBDyn/FD.h"
#include "RBDyn/FK.h"
#include "RBDyn/FV.h"
#include "RBDyn/Momentum.h"
Expand Down Expand Up @@ -75,7 +78,6 @@ BOOST_AUTO_TEST_CASE(centroidalMomentum)

BOOST_CHECK_SMALL((momentum - momentumM).vector().norm(), TOL);
}

// test J·q against CentroidalMomentumMatrix::momentum
for(int i = 0; i < 50; ++i)
{
Expand Down Expand Up @@ -212,3 +214,128 @@ BOOST_AUTO_TEST_CASE(centroidalMomentumDot)
BOOST_CHECK_SMALL((normalMomentumDot2 - normalMomentumDotM).vector().norm(), TOL);
}
}

BOOST_AUTO_TEST_CASE(centroidalInertia)
{
rbd::MultiBody mb;
rbd::MultiBodyConfig mbc;
rbd::MultiBodyGraph mbg;
std::tie(mb, mbc, mbg) = makeXYZSarm();

Eigen::VectorXd q(mb.nrParams());
Eigen::VectorXd alpha(mb.nrDof());

Eigen::Matrix6d ci;
Eigen::Vector6d cm;
Eigen::Vector6d av;

Eigen::Matrix6d ci_improved;

rbd::CentroidalMomentumMatrix cmm(mb);
rbd::ForwardDynamics fd(mb);

// Test two Composite-rigid-body inertia against each other
// for(int i = 0; i < 100; ++i)
//{
// q.setRandom();
// q.segment<4>(mb.jointPosInParam(mb.jointIndexByName("j3"))).normalize();
// alpha.setRandom();
// rbd::vectorToParam(q, mbc.q);
// rbd::vectorToParam(alpha, mbc.alpha);

// rbd::forwardKinematics(mb, mbc);
// rbd::forwardVelocity(mb, mbc);
// rbd::forwardAcceleration(mb, mbc);

// fd.forwardDynamics(mb, mbc);

// Eigen::Vector3d com = rbd::computeCoM(mb, mbc);
// rbd::computeCentroidalInertia(mb, mbc, com, ci, cm, av);
// rbd::computeCentroidalInertia(fd.H(), com, ci_improved);

// //std::cout<<"The improved Centroidal Inertia is: "<<std::endl<<ci_improved<<std::endl;
// //std::cout<<"The Centroidal Inertia is: "<<std::endl<<ci<<std::endl;

// // Compute the mass:
// double mass = 0.0;
// for (auto & body:mb.bodies())
// {
// mass+=body.inertia().mass();
// }

// //std::cout<<"The robot mass is: "<<std::endl<<mass<<std::endl;

// //Eigen::Vector6d ci_diag = ci.diagonal();
// //Eigen::Vector6d ci_improved_diag = ci_improved.diagonal();

// //BOOST_CHECK_SMALL((ci_improved_diag.tail(3) - ci_diag.tail(3)).norm(), TOL);
// //BOOST_CHECK_SMALL((ci_improved_diag.head<3>() - ci_diag.head<3>()).norm(), TOL);

// cmm.computeMatrix(mb, mbc, com);

// Eigen::Matrix6d cmmMatrix;
// Eigen::Vector6d cmmMatrixdqd;

// computeCentroidalInertia(
// mbc,
// fd.H(),
// fd.C(),
// com,
// cmmMatrix,
// cmmMatrixdqd
// );

// // BOOST_CHECK_SMALL((cmmMatrix - cmm.matrix()).norm(), TOL);

// sva::ForceVecd momentumM(cmm.matrix() * alpha);
// sva::ForceVecd improved_momentumM(cmmMatrix * alpha);

// // BOOST_CHECK_SMALL((improved_momentumM- momentumM).vector().norm(), TOL);

//}

for(int i = 0; i < 100; ++i)
{
q.setRandom();
q.segment<4>(mb.jointPosInParam(mb.jointIndexByName("j3"))).normalize();
alpha.setRandom();
rbd::vectorToParam(q, mbc.q);
rbd::vectorToParam(alpha, mbc.alpha);

rbd::forwardKinematics(mb, mbc);
rbd::forwardVelocity(mb, mbc);

Eigen::Vector3d com = rbd::computeCoM(mb, mbc);
Eigen::Vector3d comVelocity = rbd::computeCoMVelocity(mb, mbc);
rbd::computeCentroidalInertia(mb, mbc, com, ci, av);

cmm.computeMatrix(mb, mbc, com);

Eigen::MatrixXd cmmMatrix = cmm.matrix();

// Eigen::VectorXd alpha(mb.nrDof());
Eigen::Vector6d hc = cmmMatrix * alpha;

std::cout << "trial: " << i << " ===========================" << std::endl;

std::cout << "hc: " << hc.transpose() << std::endl;

std::cout << " Momemtum diff is: " << ((cmmMatrix * alpha).tail(3) - 6 * comVelocity).transpose() << std::endl;

std::cout << "Momentum by ci * av is: " << (ci * av).transpose() << std::endl;
// std::cout<<"cmm com vel is: "<<(hc.head(3) / 6.0).transpose()<<std::endl;
std::cout << "cmm com vel is: " << (hc.tail(3) / 6.0).transpose() << std::endl;
std::cout << "com vel is: " << comVelocity.transpose() << std::endl;
std::cout << "av linear vel is: " << av.tail(3).transpose() << std::endl;
std::cout << "ci is: " << std::endl << ci.matrix() << std::endl;
// std::cout<<"av angular vel is: "<<av.head(3).transpose()<<std::endl;

sva::ForceVecd cm = rbd::computeCentroidalMomentum(mb, mbc, com);

// std::cout<<"ci * av - rbd::cm is: "<< <<std::endl;
BOOST_CHECK_SMALL((ci * av - cm.vector()).norm(), TOL);

// BOOST_CHECK_SMALL((av.tail(3) - comVelocity).norm(), TOL);
BOOST_CHECK_SMALL((av.tail(3) - comVelocity).norm(), 1.0);
}
}
Loading