You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/drake-master/multibody/inverse_kinematics/minimum_distance_constraint.h

154 lines
6.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include <memory>
#include <vector>
#include "drake/multibody/plant/multibody_plant.h"
#include "drake/solvers/constraint.h"
#include "drake/solvers/minimum_value_constraint.h"
#include "drake/systems/framework/context.h"
namespace drake {
namespace multibody {
/** Computes the penalty function φ(x) and its derivatives dφ(x)/dx. Valid
penalty functions must meet the following criteria:
1. φ(x) ≥ 0 ∀ x ∈ .
2. dφ(x)/dx ≤ 0 ∀ x ∈ .
3. φ(x) = 0 ∀ x ≥ 0.
4. dφ(x)/dx < 0 ∀ x < 0. */
using MinimumDistancePenaltyFunction = solvers::MinimumValuePenaltyFunction;
/** A hinge loss function smoothed by exponential function. This loss
function is differentiable everywhere. The formulation is described in
section II.C of [2].
The penalty is
<pre>
⎧ 0 if x ≥ 0
φ(x) = ⎨
⎩ -x exp(1/x) if x < 0.
</pre>
[2] "Whole-body Motion Planning with Centroidal Dynamics and Full
Kinematics" by Hongkai Dai, Andres Valenzuela and Russ Tedrake, IEEE-RAS
International Conference on Humanoid Robots, 2014. */
using solvers::ExponentiallySmoothedHingeLoss;
/** A linear hinge loss, smoothed with a quadratic loss near the origin. The
formulation is in equation (6) of [1].
The penalty is
<pre>
⎧ 0 if x ≥ 0
φ(x) = ⎨ x²/2 if -1 < x < 0
⎩ -0.5 - x if x ≤ -1.
</pre>
[1] "Loss Functions for Preference Levels: Regression with Discrete Ordered
Labels." by Jason Rennie and Nathan Srebro, Proceedings of IJCAI
multidisciplinary workshop on Advances in Preference Handling. */
using solvers::QuadraticallySmoothedHingeLoss;
/** Constrain the signed distance between all candidate pairs of geometries
(according to the logic of SceneGraphInspector::GetCollisionCandidates()) to be
no smaller than a specified minimum distance. This constraint should be bound
to decision variables corresponding to the configuration vector, q, of the
associate MultibodyPlant.
The formulation of the constraint is
0 ≤ SmoothMax( φ((dᵢ(q) - d_influence)/(d_influence - dₘᵢₙ)) / φ(-1) ) ≤ 1
where dᵢ(q) is the signed distance of the i-th pair, dₘᵢₙ is the minimum
allowable distance, d_influence is the "influence distance" (the distance below
which a pair of geometries influences the constraint), φ is a
multibody::MinimumDistancePenaltyFunction, and SmoothMax(d) is smooth
approximation of max(d). We require that dₘᵢₙ < d_influence. The input scaling
(dᵢ(q) - d_influence)/(d_influence - dₘᵢₙ) ensures that at the boundary of the
feasible set (when dᵢ(q) == dₘᵢₙ), we evaluate the penalty function at -1,
where it is required to have a non-zero gradient.
@ingroup solver_evaluators
*/
class MinimumDistanceConstraint final : public solvers::Constraint {
public:
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(MinimumDistanceConstraint)
/** Constructs a MinimumDistanceConstraint.
@param plant The multibody system on which the constraint will be evaluated.
@param minimum_distance The minimum allowed value, dₘᵢₙ, of the signed
distance between any candidate pair of geometries.
@param penalty_function The penalty function formulation.
@default QuadraticallySmoothedHinge
@param influence_distance_offset The difference (in meters) between the
influence distance, d_influence, and the minimum distance, dₘᵢₙ (see class
documentation). This value must be finite and strictly positive, as it is used
to scale the signed distances between pairs of geometries. Smaller values may
improve performance, as fewer pairs of geometries need to be considered in
each constraint evaluation. @default 1 meter
@throws std::exception if `plant` has not registered its geometry with
a SceneGraph object.
@throws std::exception if influence_distance_offset = ∞.
@throws std::exception if influence_distance_offset ≤ 0.
@pydrake_mkdoc_identifier{double}
*/
MinimumDistanceConstraint(
const multibody::MultibodyPlant<double>* const plant,
double minimum_distance, systems::Context<double>* plant_context,
MinimumDistancePenaltyFunction penalty_function = {},
double influence_distance_offset = 1);
/**
Overloaded constructor.
Constructs the constraint using MultibodyPlant<AutoDiffXd>.
@pydrake_mkdoc_identifier{autodiff}
*/
MinimumDistanceConstraint(
const multibody::MultibodyPlant<AutoDiffXd>* const plant,
double minimum_distance, systems::Context<AutoDiffXd>* plant_context,
MinimumDistancePenaltyFunction penalty_function = {},
double influence_distance_offset = 1);
~MinimumDistanceConstraint() override {}
/** Getter for the minimum distance. */
double minimum_distance() const {
return minimum_value_constraint_->minimum_value();
}
/** Getter for the influence distance. */
double influence_distance() const {
return minimum_value_constraint_->influence_value();
}
private:
void DoEval(const Eigen::Ref<const Eigen::VectorXd>& x,
Eigen::VectorXd* y) const override;
void DoEval(const Eigen::Ref<const AutoDiffVecXd>& x,
AutoDiffVecXd* y) const override;
void DoEval(const Eigen::Ref<const VectorX<symbolic::Variable>>&,
VectorX<symbolic::Expression>*) const override {
throw std::logic_error(
"MinimumDistanceConstraint::DoEval() does not work for symbolic "
"variables.");
}
template <typename T>
void DoEvalGeneric(const Eigen::Ref<const VectorX<T>>& x,
VectorX<T>* y) const;
template <typename T>
void Initialize(const MultibodyPlant<T>& plant,
systems::Context<T>* plant_context, double minimum_distance,
double influence_distance_offset,
MinimumDistancePenaltyFunction penalty_function);
const multibody::MultibodyPlant<double>* const plant_double_;
systems::Context<double>* const plant_context_double_;
std::unique_ptr<solvers::MinimumValueConstraint> minimum_value_constraint_;
const multibody::MultibodyPlant<AutoDiffXd>* const plant_autodiff_;
systems::Context<AutoDiffXd>* const plant_context_autodiff_;
};
} // namespace multibody
} // namespace drake