Directory: | ./ |
---|---|
File: | include/multicontact-api/scenario/contact-patch.hpp |
Date: | 2025-03-10 16:17:01 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 36 | 38 | 94.7% |
Branches: | 14 | 28 | 50.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | |||
2 | #ifndef __multicontact_api_scenario_contact_patch_hpp__ | ||
3 | #define __multicontact_api_scenario_contact_patch_hpp__ | ||
4 | |||
5 | #include <pinocchio/spatial/se3.hpp> | ||
6 | |||
7 | #include "multicontact-api/scenario/contact-model.hpp" | ||
8 | #include "multicontact-api/scenario/fwd.hpp" | ||
9 | #include "multicontact-api/serialization/archive.hpp" | ||
10 | #include "multicontact-api/serialization/spatial.hpp" | ||
11 | |||
12 | namespace multicontact_api { | ||
13 | namespace scenario { | ||
14 | |||
15 | template <typename _Scalar> | ||
16 | struct ContactPatchTpl | ||
17 | : public serialization::Serializable<ContactPatchTpl<_Scalar> > { | ||
18 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
19 | |||
20 | typedef _Scalar Scalar; | ||
21 | typedef ContactModelTpl<_Scalar> ContactModel; | ||
22 | typedef pinocchio::SE3Tpl<Scalar, 0> SE3; | ||
23 | |||
24 | /// \brief Default constructor. | ||
25 |
1/2✓ Branch 2 taken 176 times.
✗ Branch 3 not taken.
|
176 | ContactPatchTpl() : m_contact_model(), m_placement(SE3::Identity()) {} |
26 | |||
27 | /// \brief Init contact patch from a given placement. | ||
28 | 93 | explicit ContactPatchTpl(const SE3& placement) | |
29 |
1/2✓ Branch 2 taken 93 times.
✗ Branch 3 not taken.
|
93 | : m_contact_model(), m_placement(placement) {} |
30 | |||
31 | /// \brief Init contact patch from a given placement and a friction | ||
32 | /// coefficient | ||
33 | 151 | ContactPatchTpl(const SE3& placement, const Scalar mu) | |
34 |
1/2✓ Branch 2 taken 151 times.
✗ Branch 3 not taken.
|
151 | : m_contact_model(mu), m_placement(placement) {} |
35 | |||
36 | /// \brief Init contact patch from a given placement and a contact model | ||
37 | 2 | ContactPatchTpl(const SE3& placement, const ContactModel contact_model) | |
38 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | : m_contact_model(contact_model), m_placement(placement) {} |
39 | |||
40 | /// \brief Copy constructor | ||
41 | 1237 | ContactPatchTpl(const ContactPatchTpl& other) | |
42 | 1237 | : m_contact_model(other.m_contact_model), | |
43 |
1/2✓ Branch 1 taken 1237 times.
✗ Branch 2 not taken.
|
1237 | m_placement(other.m_placement) {} |
44 | |||
45 | 32 | const SE3& placement() const { return m_placement; } | |
46 | 48 | SE3& placement() { return m_placement; } | |
47 | |||
48 | const Scalar& friction() const { return m_contact_model.m_mu; } | ||
49 | 29 | Scalar& friction() { return m_contact_model.m_mu; } | |
50 | |||
51 | template <typename S2> | ||
52 | 460 | bool operator==(const ContactPatchTpl<S2>& other) const { | |
53 |
2/2✓ Branch 1 taken 451 times.
✓ Branch 2 taken 9 times.
|
911 | return m_placement == other.m_placement && |
54 |
2/2✓ Branch 1 taken 444 times.
✓ Branch 2 taken 7 times.
|
911 | m_contact_model == other.m_contact_model; |
55 | } | ||
56 | |||
57 | template <typename S2> | ||
58 | 15 | bool operator!=(const ContactPatchTpl<S2>& other) const { | |
59 | 15 | return !(*this == other); | |
60 | } | ||
61 | |||
62 | 4 | void disp(std::ostream& os) const { | |
63 | 4 | os << "Placement:\n" | |
64 | 4 | << m_placement << std::endl | |
65 | 4 | << "ContactModel : " << m_contact_model << std::endl; | |
66 | 4 | } | |
67 | |||
68 | template <typename S2> | ||
69 | 4 | friend std::ostream& operator<<(std::ostream& os, | |
70 | const ContactPatchTpl<S2>& cp) { | ||
71 | 4 | cp.disp(os); | |
72 | 4 | return os; | |
73 | } | ||
74 | |||
75 | /// \brief Contact model of this contact | ||
76 | ContactModel m_contact_model; | ||
77 | |||
78 | protected: | ||
79 | /// \brief Placement of the contact patch | ||
80 | SE3 m_placement; | ||
81 | |||
82 | private: | ||
83 | // Serialization of the class | ||
84 | friend class boost::serialization::access; | ||
85 | |||
86 | template <class Archive> | ||
87 | 330 | void save(Archive& ar, const unsigned int /*version*/) const { | |
88 |
1/2✓ Branch 2 taken 165 times.
✗ Branch 3 not taken.
|
330 | ar& boost::serialization::make_nvp("placement", m_placement); |
89 |
1/2✓ Branch 2 taken 165 times.
✗ Branch 3 not taken.
|
330 | ar& boost::serialization::make_nvp("contact_model", m_contact_model); |
90 | 330 | } | |
91 | |||
92 | template <class Archive> | ||
93 | 330 | void load(Archive& ar, const unsigned int version) { | |
94 |
1/2✓ Branch 2 taken 165 times.
✗ Branch 3 not taken.
|
330 | ar >> boost::serialization::make_nvp("placement", m_placement); |
95 |
1/2✓ Branch 0 taken 165 times.
✗ Branch 1 not taken.
|
330 | if (version >= 1) { |
96 |
1/2✓ Branch 2 taken 165 times.
✗ Branch 3 not taken.
|
330 | ar >> boost::serialization::make_nvp("contact_model", m_contact_model); |
97 | } else { | ||
98 | double mu; | ||
99 | ✗ | ar >> boost::serialization::make_nvp("mu", mu); | |
100 | ✗ | m_contact_model = ContactModel(mu); | |
101 | } | ||
102 | 330 | } | |
103 | |||
104 | 660 | BOOST_SERIALIZATION_SPLIT_MEMBER() // why is it required ? using only | |
105 | // serialize() lead to compilation error, | ||
106 | // probably because of the SE3 | ||
107 | |||
108 | }; // struct ContactPatchTpl | ||
109 | } // namespace scenario | ||
110 | } // namespace multicontact_api | ||
111 | |||
112 | MULTICONTACT_API_DEFINE_CLASS_TEMPLATE_VERSION( | ||
113 | typename Scalar, multicontact_api::scenario::ContactPatchTpl<Scalar>) | ||
114 | |||
115 | #endif // __multicontact_api_scenario_contact_patch_hpp__ | ||
116 |