Skip to content

Commit

Permalink
Introduces alternative API for inverse dynamics
Browse files Browse the repository at this point in the history
  • Loading branch information
amcastro-tri committed Sep 5, 2018
1 parent 8706338 commit 0acaf41
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
19 changes: 19 additions & 0 deletions multibody/multibody_tree/multibody_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,25 @@ void MultibodyTree<T>::CalcAccelerationKinematicsCache(
CalcSpatialAccelerationsFromVdot(context, pc, vc, known_vdot, &A_WB_array);
}

template <typename T>
VectorX<T> MultibodyTree<T>::CalcInverseDynamics(
const systems::Context<T>& context,
const VectorX<T>& known_vdot,
const MultibodyForces<T>& external_forces) const {
// Temporary storage used in the computation of inverse dynamics.
std::vector<SpatialAcceleration<T>> A_WB(num_bodies());
std::vector<SpatialForce<T>> F_BMo_W(num_bodies());

const auto& pc = EvalPositionKinematics(context);
const auto& vc = EvalVelocityKinematics(context);
VectorX<T> tau(num_velocities());
CalcInverseDynamics(
context, pc, vc, known_vdot,
external_forces.body_forces(), external_forces.generalized_forces(),
&A_WB, &F_BMo_W, &tau);
return tau;
}

template <typename T>
void MultibodyTree<T>::CalcInverseDynamics(
const systems::Context<T>& context,
Expand Down
44 changes: 44 additions & 0 deletions multibody/multibody_tree/multibody_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "drake/common/autodiff.h"
#include "drake/common/drake_copyable.h"
#include "drake/common/drake_deprecated.h"
#include "drake/common/drake_optional.h"
#include "drake/multibody/multibody_tree/acceleration_kinematics_cache.h"
#include "drake/multibody/multibody_tree/body.h"
Expand Down Expand Up @@ -1840,6 +1841,49 @@ class MultibodyTree {

/// Given the state of `this` %MultibodyTree in `context` and a known vector
/// of generalized accelerations `vdot`, this method computes the
/// set of generalized forces `tau` that would need to be applied in order to
/// attain the specified generalized accelerations.
/// Mathematically, this method computes: <pre>
/// tau = M(q)v̇ + C(q, v)v - tau_app - ∑ J_WBᵀ(q) Fapp_Bo_W
/// </pre>
/// where `M(q)` is the %MultibodyTree mass matrix, `C(q, v)v` is the bias
/// term containing Coriolis and gyroscopic effects and `tau_app` consists
/// of a vector applied generalized forces. The last term is a summation over
/// all bodies in the model where `Fapp_Bo_W` is an applied spatial force on
/// body B at `Bo` which gets projected into the space of generalized forces
/// with the geometric Jacobian `J_WB(q)` which maps generalized velocities
/// into body B spatial velocity as `V_WB = J_WB(q)v`.
/// This method does not compute explicit expressions for the mass matrix nor
/// for the bias term, which would be of at least `O(n²)` complexity, but it
/// implements an `O(n)` Newton-Euler recursive algorithm, where n is the
/// number of bodies in the %MultibodyTree. The explicit formation of the
/// mass matrix `M(q)` would require the calculation of `O(n²)` entries while
/// explicitly forming the product `C(q, v) * v` could require up to `O(n³)`
/// operations (see [Featherstone 1987, §4]), depending on the implementation.
/// The recursive Newton-Euler algorithm is the most efficient currently known
/// general method for solving inverse dynamics [Featherstone 2008].
///
/// @param[in] context
/// The context containing the state of the model.
/// @param[in] known_vdot
/// A vector with the known generalized accelerations `vdot` for the full
/// %MultibodyTree model. Use the provided Joint APIs in order to access
/// entries into this array.
/// @param[in] external_forces
/// A set of forces to be applied to the system either as body spatial
/// forces `Fapp_Bo_W` or generalized forces `tau_app`, see MultibodyForces
/// for details.
///
/// @returns the vector of generalized forces that would need to be applied to
/// the mechanical system in order to achieve the desired acceleration given
/// by `known_vdot`.
VectorX<T> CalcInverseDynamics(
const systems::Context<T>& context,
const VectorX<T>& known_vdot,
const MultibodyForces<T>& external_forces) const;

/// (Advanced) Given the state of `this` %MultibodyTree in `context` and a
/// known vector of generalized accelerations `vdot`, this method computes the
/// set of generalized forces `tau` that would need to be applied at each
/// Mobilizer in order to attain the specified generalized accelerations.
/// Mathematically, this method computes: <pre>
Expand Down
6 changes: 6 additions & 0 deletions multibody/multibody_tree/test/tree_from_joints_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ class PendulumTests : public ::testing::Test {

EXPECT_TRUE(CompareMatrices(
tau, rhs, kTolerance, MatrixCompareType::relative));

// Verify alternative APIs for inverse dynamics.
const VectorX<double> tau_id2 =
tree_->CalcInverseDynamics(*context_, vdot, forces);
EXPECT_TRUE(CompareMatrices(
tau_id2, rhs, kTolerance, MatrixCompareType::relative));
}

protected:
Expand Down

0 comments on commit 0acaf41

Please sign in to comment.