Crocoddyl
Loading...
Searching...
No Matches
contact-cop-position.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2020-2026, University of Duisburg-Essen,
5// University of Edinburgh, Heriot-Watt University
6// Copyright note valid unless otherwise stated in individual files.
7// All rights reserved.
9
10#ifndef CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_COP_POSITION_HPP_
11#define CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_COP_POSITION_HPP_
12
13#include "crocoddyl/core/residual-base.hpp"
14#include "crocoddyl/core/utils/conversions.hpp"
15#include "crocoddyl/multibody/contact-base.hpp"
16#include "crocoddyl/multibody/contacts/contact-3d.hpp"
17#include "crocoddyl/multibody/contacts/contact-6d.hpp"
18#include "crocoddyl/multibody/contacts/multiple-contacts.hpp"
19#include "crocoddyl/multibody/cop-support.hpp"
20#include "crocoddyl/multibody/data/contacts.hpp"
21#include "crocoddyl/multibody/data/impulses.hpp"
22#include "crocoddyl/multibody/fwd.hpp"
23#include "crocoddyl/multibody/impulse-base.hpp"
24#include "crocoddyl/multibody/impulses/impulse-3d.hpp"
25#include "crocoddyl/multibody/impulses/impulse-6d.hpp"
26#include "crocoddyl/multibody/impulses/multiple-impulses.hpp"
27#include "crocoddyl/multibody/states/multibody.hpp"
28
29namespace crocoddyl {
30
67template <typename _Scalar>
69 : public ResidualModelAbstractTpl<_Scalar> {
70 public:
71 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
73
74 typedef _Scalar Scalar;
75 typedef MathBaseTpl<Scalar> MathBase;
78 typedef StateMultibodyTpl<Scalar> StateMultibody;
79 typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract;
80 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
81 typedef CoPSupportTpl<Scalar> CoPSupport;
82 typedef typename MathBase::VectorXs VectorXs;
83 typedef typename MathBase::MatrixXs MatrixXs;
84 typedef typename MathBase::Matrix46s Matrix46;
85
99 ResidualModelContactCoPPositionTpl(std::shared_ptr<StateMultibody> state,
100 const pinocchio::FrameIndex id,
101 const CoPSupport& cref,
102 const std::size_t nu,
103 const bool fwddyn = true);
104
115 ResidualModelContactCoPPositionTpl(std::shared_ptr<StateMultibody> state,
116 const pinocchio::FrameIndex id,
117 const CoPSupport& cref);
118 virtual ~ResidualModelContactCoPPositionTpl() = default;
119
132 virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data,
133 const Eigen::Ref<const VectorXs>& x,
134 const Eigen::Ref<const VectorXs>& u) override;
135
146 virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data,
147 const Eigen::Ref<const VectorXs>& x) override;
148
161 virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data,
162 const Eigen::Ref<const VectorXs>& x,
163 const Eigen::Ref<const VectorXs>& u) override;
164
176 virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data,
177 const Eigen::Ref<const VectorXs>& x) override;
178
189 virtual std::shared_ptr<ResidualDataAbstract> createData(
190 DataCollectorAbstract* const data) override;
191
197 void updateJacobians(const std::shared_ptr<ResidualDataAbstract>& data);
198
209 template <typename NewScalar>
211
216 bool is_fwddyn() const;
217
221 pinocchio::FrameIndex get_id() const;
222
226 const CoPSupport& get_reference() const;
227
231 DEPRECATED("Do not use set_id, instead create a new model",
232 void set_id(pinocchio::FrameIndex id);)
233
237 void set_reference(const CoPSupport& reference);
238
244 virtual void print(std::ostream& os) const override;
245
246 protected:
247 using Base::nu_;
248 using Base::state_;
249
250 private:
251 bool fwddyn_;
253 bool update_jacobians_;
255 pinocchio::FrameIndex id_;
256 CoPSupport cref_;
257};
258
259template <typename _Scalar>
260struct ResidualDataContactCoPPositionTpl
261 : public ResidualDataAbstractTpl<_Scalar> {
262 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
263
264 typedef _Scalar Scalar;
265 typedef MathBaseTpl<Scalar> MathBase;
266 typedef ResidualDataAbstractTpl<Scalar> Base;
267 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
268 typedef StateMultibodyTpl<Scalar> StateMultibody;
269 typedef typename MathBase::MatrixXs MatrixXs;
270
271 template <template <typename Scalar> class Model>
272 ResidualDataContactCoPPositionTpl(Model<Scalar>* const model,
273 DataCollectorAbstract* const data)
274 : Base(model, data) {
275 // Check that proper shared data has been passed
276 bool is_contact = true;
281 if (d1 == NULL && d2 == NULL) {
282 throw_pretty(
283 "Invalid argument: the shared data should be derived from "
284 "DataCollectorContact or DataCollectorImpulse");
285 }
286 if (d2 != NULL) {
287 is_contact = false;
288 }
289
290 // Avoids data casting at runtime
291 const pinocchio::FrameIndex id = model->get_id();
292 const std::shared_ptr<StateMultibody>& state =
293 std::static_pointer_cast<StateMultibody>(model->get_state());
294 std::string frame_name = state->get_pinocchio()->frames[id].name;
295 bool found_contact = false;
296 if (is_contact) {
297 for (typename ContactModelMultipleTpl<
298 Scalar>::ContactDataContainer::iterator it =
299 d1->contacts->contacts.begin();
300 it != d1->contacts->contacts.end(); ++it) {
301 if (it->second->frame == id) {
303 dynamic_cast<ContactData3DTpl<Scalar>*>(it->second.get());
304 if (d3d != NULL) {
305 found_contact = true;
306 contact = it->second;
307 throw_pretty(
308 "Domain error: there isn't defined at least a 6d contact for " +
309 frame_name);
310 break;
311 }
313 dynamic_cast<ContactData6DTpl<Scalar>*>(it->second.get());
314 if (d6d != NULL) {
315 found_contact = true;
316 contact = it->second;
317 break;
318 }
319 throw_pretty(
320 "Domain error: there isn't defined at least a 6d contact for " +
321 frame_name);
322 break;
323 }
324 }
325 } else {
326 for (typename ImpulseModelMultipleTpl<
327 Scalar>::ImpulseDataContainer::iterator it =
328 d2->impulses->impulses.begin();
329 it != d2->impulses->impulses.end(); ++it) {
330 if (it->second->frame == id) {
332 dynamic_cast<ImpulseData3DTpl<Scalar>*>(it->second.get());
333 if (d3d != NULL) {
334 found_contact = true;
335 contact = it->second;
336 throw_pretty(
337 "Domain error: there isn't defined at least a 6d contact for " +
338 frame_name);
339 break;
340 }
342 dynamic_cast<ImpulseData6DTpl<Scalar>*>(it->second.get());
343 if (d6d != NULL) {
344 found_contact = true;
345 contact = it->second;
346 break;
347 }
348 throw_pretty(
349 "Domain error: there isn't defined at least a 6d contact for " +
350 frame_name);
351 break;
352 }
353 }
354 }
355 if (!found_contact) {
356 throw_pretty("Domain error: there isn't defined contact data for " +
357 frame_name);
358 }
359 }
360 virtual ~ResidualDataContactCoPPositionTpl() = default;
361
362 pinocchio::DataTpl<Scalar>* pinocchio;
363 std::shared_ptr<ForceDataAbstractTpl<Scalar> > contact;
364 using Base::r;
365 using Base::Ru;
366 using Base::Rx;
367 using Base::shared;
368};
369
370} // namespace crocoddyl
371
372/* --- Details -------------------------------------------------------------- */
373/* --- Details -------------------------------------------------------------- */
374/* --- Details -------------------------------------------------------------- */
375#include "crocoddyl/multibody/residuals/contact-cop-position.hxx"
376
377CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(
379CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(
381
382#endif // CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_COP_POSITION_HPP_
This class encapsulates a center of pressure support of a 6d contact.
Define a stack of contact models.
Define a stack of impulse models.
std::shared_ptr< StateAbstract > state_
ResidualModelAbstractTpl(std::shared_ptr< StateAbstract > state, const std::size_t nr, const std::size_t nu, const bool q_dependent=true, const bool v_dependent=true, const bool u_dependent=true)
Initialize the residual model.
Center of pressure residual function.
DEPRECATED("Do not use set_id, instead create a new model", void set_id(pinocchio::FrameIndex id);) void set_reference(const CoPSupport &reference)
Modify the reference frame id.
ResidualModelContactCoPPositionTpl(std::shared_ptr< StateMultibody > state, const pinocchio::FrameIndex id, const CoPSupport &cref)
Initialize the contact CoP residual model.
ResidualModelContactCoPPositionTpl(std::shared_ptr< StateMultibody > state, const pinocchio::FrameIndex id, const CoPSupport &cref, const std::size_t nu, const bool fwddyn=true)
Initialize the contact CoP residual model.
ResidualModelContactCoPPositionTpl< NewScalar > cast() const
Cast the contact-cop-position residual model to a different scalar type.
bool is_fwddyn() const
Indicates if we are using the forward-dynamics (true) or inverse-dynamics (false).
virtual void calc(const std::shared_ptr< ResidualDataAbstract > &data, const Eigen::Ref< const VectorXs > &x) override
Compute the residual vector for nodes that depends only on the state.
virtual void calcDiff(const std::shared_ptr< ResidualDataAbstract > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u) override
Compute the Jacobians of the contact CoP residual.
const CoPSupport & get_reference() const
Return the reference support region of CoP.
virtual std::shared_ptr< ResidualDataAbstract > createData(DataCollectorAbstract *const data) override
Create the contact CoP residual data.
pinocchio::FrameIndex get_id() const
Return the reference frame id.
void updateJacobians(const std::shared_ptr< ResidualDataAbstract > &data)
Update the Jacobians of the contact friction cone residual.
virtual void calc(const std::shared_ptr< ResidualDataAbstract > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u) override
Compute the contact CoP residual.
virtual void print(std::ostream &os) const override
Print relevant information of the cop-position residual.
virtual void calcDiff(const std::shared_ptr< ResidualDataAbstract > &data, const Eigen::Ref< const VectorXs > &x) override
Compute the Jacobian of the residual functions with respect to the state only.
State multibody representation.
Definition multibody.hpp:34
std::shared_ptr< ForceDataAbstractTpl< Scalar > > contact
Contact force.
DataCollectorAbstract * shared
Shared data allocated by the action model.