Crocoddyl
Loading...
Searching...
No Matches
contact-force.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2019-2026, LAAS-CNRS, University of Edinburgh
5// Heriot-Watt University
6// Copyright note valid unless otherwise stated in individual files.
7// All rights reserved.
9
10#ifndef CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_FORCE_HPP_
11#define CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_FORCE_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-1d.hpp"
17#include "crocoddyl/multibody/contacts/contact-3d.hpp"
18#include "crocoddyl/multibody/contacts/contact-6d.hpp"
19#include "crocoddyl/multibody/contacts/multiple-contacts.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
56template <typename _Scalar>
58 public:
59 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
61
62 typedef _Scalar Scalar;
63 typedef MathBaseTpl<Scalar> MathBase;
66 typedef StateMultibodyTpl<Scalar> StateMultibody;
67 typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract;
68 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
69 typedef pinocchio::ForceTpl<Scalar> Force;
70 typedef typename MathBase::VectorXs VectorXs;
71 typedef typename MathBase::MatrixXs MatrixXs;
72
88 ResidualModelContactForceTpl(std::shared_ptr<StateMultibody> state,
89 const pinocchio::FrameIndex id,
90 const Force& fref, const std::size_t nc,
91 const std::size_t nu, const bool fwddyn = true);
92
105 ResidualModelContactForceTpl(std::shared_ptr<StateMultibody> state,
106 const pinocchio::FrameIndex id,
107 const Force& fref, const std::size_t nc);
108 virtual ~ResidualModelContactForceTpl() = default;
109
122 virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data,
123 const Eigen::Ref<const VectorXs>& x,
124 const Eigen::Ref<const VectorXs>& u) override;
125
136 virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data,
137 const Eigen::Ref<const VectorXs>& x) override;
138
151 virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data,
152 const Eigen::Ref<const VectorXs>& x,
153 const Eigen::Ref<const VectorXs>& u) override;
154
166 virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data,
167 const Eigen::Ref<const VectorXs>& x) override;
168
175 virtual std::shared_ptr<ResidualDataAbstract> createData(
176 DataCollectorAbstract* const data) override;
177
183 void updateJacobians(const std::shared_ptr<ResidualDataAbstract>& data);
184
194 template <typename NewScalar>
196
201 bool is_fwddyn() const;
202
206 pinocchio::FrameIndex get_id() const;
207
212 const Force& get_reference() const;
213
217 DEPRECATED("Do not use set_id, instead create a new model",
218 void set_id(const pinocchio::FrameIndex id);)
219
224 void set_reference(const Force& reference);
225
231 virtual void print(std::ostream& os) const override;
232
233 protected:
234 using Base::nr_;
235 using Base::nu_;
236 using Base::state_;
237
238 private:
239 bool fwddyn_;
241 bool update_jacobians_;
243 pinocchio::FrameIndex id_;
244 Force fref_;
245};
246
247template <typename _Scalar>
248struct ResidualDataContactForceTpl : public ResidualDataAbstractTpl<_Scalar> {
249 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
250
251 typedef _Scalar Scalar;
252 typedef MathBaseTpl<Scalar> MathBase;
253 typedef ResidualDataAbstractTpl<Scalar> Base;
254 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
255 typedef ContactModelMultipleTpl<Scalar> ContactModelMultiple;
256 typedef ImpulseModelMultipleTpl<Scalar> ImpulseModelMultiple;
257 typedef pinocchio::ForceTpl<Scalar> Force;
258 typedef StateMultibodyTpl<Scalar> StateMultibody;
259 typedef typename MathBase::MatrixXs MatrixXs;
260
261 template <template <typename Scalar> class Model>
262 ResidualDataContactForceTpl(Model<Scalar>* const model,
263 DataCollectorAbstract* const data)
264 : Base(model, data) {
265 contact_type = ContactUndefined;
266
267 // Check that proper shared data has been passed
268 bool is_contact = true;
273 if (d1 == NULL && d2 == NULL) {
274 throw_pretty(
275 "Invalid argument: the shared data should be derived from "
276 "DataCollectorContact or DataCollectorImpulse");
277 }
278 if (d2 != NULL) {
279 is_contact = false;
280 }
281
282 // Avoids data casting at runtime
283 const pinocchio::FrameIndex id = model->get_id();
284 const std::shared_ptr<StateMultibody>& state =
285 std::static_pointer_cast<StateMultibody>(model->get_state());
286 std::string frame_name = state->get_pinocchio()->frames[id].name;
287 bool found_contact = false;
288 if (is_contact) {
289 for (typename ContactModelMultiple::ContactDataContainer::iterator it =
290 d1->contacts->contacts.begin();
291 it != d1->contacts->contacts.end(); ++it) {
292 if (it->second->frame == id) {
294 dynamic_cast<ContactData1DTpl<Scalar>*>(it->second.get());
295 if (d1d != NULL) {
296 contact_type = Contact1D;
297 found_contact = true;
298 contact = it->second;
299 break;
300 }
302 dynamic_cast<ContactData3DTpl<Scalar>*>(it->second.get());
303 if (d3d != NULL) {
304 contact_type = Contact3D;
305 found_contact = true;
306 contact = it->second;
307 break;
308 }
310 dynamic_cast<ContactData6DTpl<Scalar>*>(it->second.get());
311 if (d6d != NULL) {
312 contact_type = Contact6D;
313 found_contact = true;
314 contact = it->second;
315 break;
316 }
317 throw_pretty(
318 "Domain error: there isn't defined at least a 3d contact for " +
319 frame_name);
320 break;
321 }
322 }
323 } else {
324 for (typename ImpulseModelMultiple::ImpulseDataContainer::iterator it =
325 d2->impulses->impulses.begin();
326 it != d2->impulses->impulses.end(); ++it) {
327 if (it->second->frame == id) {
329 dynamic_cast<ImpulseData3DTpl<Scalar>*>(it->second.get());
330 if (d3d != NULL) {
331 contact_type = Contact3D;
332 found_contact = true;
333 contact = it->second;
334 break;
335 }
337 dynamic_cast<ImpulseData6DTpl<Scalar>*>(it->second.get());
338 if (d6d != NULL) {
339 contact_type = Contact6D;
340 found_contact = true;
341 contact = it->second;
342 break;
343 }
344 throw_pretty(
345 "Domain error: there isn't defined at least a 3d impulse for " +
346 frame_name);
347 break;
348 }
349 }
350 }
351 if (!found_contact) {
352 throw_pretty(
353 "Domain error: there isn't defined contact/impulse data for " +
354 frame_name);
355 }
356 }
357 virtual ~ResidualDataContactForceTpl() = default;
358
359 std::shared_ptr<ForceDataAbstractTpl<Scalar> >
361 ContactType contact_type;
362 using Base::r;
363 using Base::Ru;
364 using Base::Rx;
365 using Base::shared;
366};
367
368} // namespace crocoddyl
369
370/* --- Details -------------------------------------------------------------- */
371/* --- Details -------------------------------------------------------------- */
372/* --- Details -------------------------------------------------------------- */
373#include "crocoddyl/multibody/residuals/contact-force.hxx"
374
375CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(crocoddyl::ResidualModelContactForceTpl)
376CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(crocoddyl::ResidualDataContactForceTpl)
377
378#endif // CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_FORCE_HPP_
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.
Define a contact force residual function.
const Force & get_reference() const
Return the reference spatial contact force in the contact coordinates.
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.
ResidualModelContactForceTpl(std::shared_ptr< StateMultibody > state, const pinocchio::FrameIndex id, const Force &fref, const std::size_t nc)
Initialize the contact force residual model.
ResidualModelContactForceTpl(std::shared_ptr< StateMultibody > state, const pinocchio::FrameIndex id, const Force &fref, const std::size_t nc, const std::size_t nu, const bool fwddyn=true)
Initialize the contact force residual model.
virtual void calcDiff(const std::shared_ptr< ResidualDataAbstract > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u) override
Compute the derivatives of the contact force residual.
virtual std::shared_ptr< ResidualDataAbstract > createData(DataCollectorAbstract *const data) override
Create the contact force residual data.
pinocchio::FrameIndex get_id() const
Return the reference frame id.
ResidualModelContactForceTpl< NewScalar > cast() const
Cast the contact-force residual model to a different scalar type.
void updateJacobians(const std::shared_ptr< ResidualDataAbstract > &data)
Update the Jacobians of the contact friction cone residual.
DEPRECATED("Do not use set_id, instead create a new model", void set_id(const pinocchio::FrameIndex id);) void set_reference(const Force &reference)
Modify the reference frame id.
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 force residual.
virtual void print(std::ostream &os) const override
Print relevant information of the contact-force 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 data.
DataCollectorAbstract * shared
Shared data allocated by the action model.
ContactType contact_type
Type of contact (3D / 6D).