#include "drake/multibody/inverse_kinematics/distance_constraint.h" #include #include #include #include "drake/multibody/inverse_kinematics/distance_constraint_utilities.h" #include "drake/multibody/inverse_kinematics/kinematic_evaluator_utilities.h" namespace drake { namespace multibody { using internal::RefFromPtrOrThrow; DistanceConstraint::DistanceConstraint( const multibody::MultibodyPlant* const plant, SortedPair geometry_pair, systems::Context* plant_context, double distance_lower, double distance_upper) : solvers::Constraint(1, RefFromPtrOrThrow(plant).num_positions(), Vector1d(distance_lower), Vector1d(distance_upper)), plant_double_{plant}, plant_context_double_{plant_context}, geometry_pair_{std::move(geometry_pair)}, plant_autodiff_{nullptr}, plant_context_autodiff_{nullptr} { CheckPlantIsConnectedToSceneGraph(*plant_double_, *plant_context_double_); } DistanceConstraint::DistanceConstraint( const multibody::MultibodyPlant* const plant, SortedPair geometry_pair, systems::Context* plant_context, double distance_lower, double distance_upper) : solvers::Constraint(1, RefFromPtrOrThrow(plant).num_positions(), Vector1d(distance_lower), Vector1d(distance_upper)), plant_double_{nullptr}, plant_context_double_{nullptr}, geometry_pair_{std::move(geometry_pair)}, plant_autodiff_{plant}, plant_context_autodiff_{plant_context} { CheckPlantIsConnectedToSceneGraph(*plant_autodiff_, *plant_context_autodiff_); } template void EvalDistance(const MultibodyPlant& plant, const SortedPair& geometry_pair, systems::Context* context, const Eigen::Ref>& x, VectorX* y) { y->resize(1); internal::UpdateContextConfiguration(context, plant, x); const auto& query_port = plant.get_geometry_query_input_port(); const auto& query_object = query_port.template Eval>(*context); const geometry::SignedDistancePair signed_distance_pair = query_object.ComputeSignedDistancePairClosestPoints( geometry_pair.first(), geometry_pair.second()); const geometry::SceneGraphInspector& inspector = query_object.inspector(); const geometry::FrameId frame_A_id = inspector.GetFrameId(signed_distance_pair.id_A); const geometry::FrameId frame_B_id = inspector.GetFrameId(signed_distance_pair.id_B); const Frame& frameA = plant.GetBodyFromFrameId(frame_A_id)->body_frame(); const Frame& frameB = plant.GetBodyFromFrameId(frame_B_id)->body_frame(); internal::CalcDistanceDerivatives( plant, *context, frameA, frameB, // GetPoseInFrame() returns RigidTransform -- we can't // multiply across heterogeneous scalar types; so we cast the double // to T. inspector.GetPoseInFrame(signed_distance_pair.id_A).template cast() * signed_distance_pair.p_ACa, signed_distance_pair.distance, signed_distance_pair.nhat_BA_W, x, y->data()); } template void DistanceConstraint::DoEvalGeneric(const Eigen::Ref>& x, VectorX* y) const { if (use_autodiff()) { EvalDistance(*plant_autodiff_, geometry_pair_, plant_context_autodiff_, x, y); } else { EvalDistance(*plant_double_, geometry_pair_, plant_context_double_, x, y); } } void DistanceConstraint::DoEval(const Eigen::Ref& x, Eigen::VectorXd* y) const { DoEvalGeneric(x, y); } void DistanceConstraint::DoEval(const Eigen::Ref& x, AutoDiffVecXd* y) const { DoEvalGeneric(x, y); } } // namespace multibody } // namespace drake