GCC Code Coverage Report


Directory: ./
File: bindings/python/crocoddyl/multibody/contact-base.cpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 30 32 93.8%
Branches: 68 136 50.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2025, LAAS-CNRS, University of Edinburgh,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "python/crocoddyl/multibody/contact-base.hpp"
11
12 #include "python/crocoddyl/multibody/multibody.hpp"
13
14 namespace crocoddyl {
15 namespace python {
16
17 template <typename Model>
18 struct ContactModelAbstractVisitor
19 : public bp::def_visitor<ContactModelAbstractVisitor<Model>> {
20 template <class PyClass>
21 40 void visit(PyClass& cl) const {
22
2/4
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
40 cl.def("calc", pure_virtual(&Model::calc), bp::args("self", "data", "x"),
23 "Compute the contact Jacobian and drift.\n\n"
24 "The rigid contact model throught acceleration-base holonomic "
25 "constraint of the contact frame placement.\n"
26 ":param data: contact data\n"
27 ":param x: state point (dim. state.nx)")
28
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
80 .def("calcDiff", pure_virtual(&Model::calcDiff),
29 bp::args("self", "data", "x"),
30 "Compute the derivatives of contact holonomic constraint.\n\n"
31 "The rigid contact model throught acceleration-base holonomic "
32 "constraint of the contact frame placement. It assumes that calc "
33 "has been run first.\n"
34 ":param data: contact data\n"
35 ":param x: state point (dim. state.nx)")
36
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
80 .def("updateForce", pure_virtual(&Model::updateForce),
37 bp::args("self", "data", "force"),
38 "Convert the force into a stack of spatial forces.\n\n"
39 ":param data: contact data\n"
40 ":param force: force vector (dimension nc)")
41
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
80 .def("updateForceDiff", &Model::updateForceDiff,
42 bp::args("self", "data", "df_dx", "df_du"),
43 "Update the Jacobians of the force.\n\n"
44 ":param data: contact data\n"
45 ":param df_dx: Jacobian of the force with respect to the state\n"
46 ":param df_du: Jacobian of the force with respect to the control")
47
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("setZeroForce", &Model::setZeroForce, bp::args("self", "data"),
48 "Set zero the spatial force.\n\n"
49 ":param data: contact data")
50
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("setZeroForceDiff", &Model::setZeroForceDiff,
51 bp::args("self", "data"),
52 "Set zero the derivatives of the spatial force.\n\n"
53 ":param data: contact data")
54
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("createData", &Model::createData,
55 bp::with_custodian_and_ward_postcall<0, 2>(),
56 bp::args("self", "data"),
57 "Create the contact data.\n\n"
58 "Each contact model has its own data that needs to be allocated. "
59 "This function returns the allocated data for a predefined "
60 "contact.\n"
61 ":param data: Pinocchio data\n"
62 ":return contact data.")
63
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 .def("createData", &Model::default_createData,
64 bp::with_custodian_and_ward_postcall<0, 2>())
65
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
40 .add_property(
66 "state",
67 bp::make_function(&Model::get_state,
68 40 bp::return_value_policy<bp::return_by_value>()),
69 "state of the multibody system")
70
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .add_property("nc", bp::make_function(&Model::get_nc),
71 "dimension of contact")
72
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .add_property("nu", bp::make_function(&Model::get_nu),
73 "dimension of control")
74 80 .add_property("id", &Model::get_id, &Model::set_id,
75 "reference frame id")
76
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
40 .add_property("type", bp::make_function(&Model::get_type),
77 &Model::set_type, "type of contact");
78 40 }
79 };
80
81 template <typename Data>
82 struct ContactDataAbstractVisitor
83 : public bp::def_visitor<ContactDataAbstractVisitor<Data>> {
84 template <class PyClass>
85 40 void visit(PyClass& cl) const {
86
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
40 cl.add_property(
87 40 "fXj", bp::make_getter(&Data::fXj, bp::return_internal_reference<>()),
88 bp::make_setter(&Data::fXj),
89 "action matrix from contact to local frames")
90
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
80 .add_property(
91 40 "a0", bp::make_getter(&Data::a0, bp::return_internal_reference<>()),
92 bp::make_setter(&Data::a0), "desired contact acceleration")
93
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
80 .add_property(
94 "da0_dx",
95 40 bp::make_getter(&Data::da0_dx, bp::return_internal_reference<>()),
96 bp::make_setter(&Data::da0_dx),
97 "Jacobian of the desired contact acceleration")
98
3/6
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
80 .add_property(
99 "dtau_dq",
100 40 bp::make_getter(&Data::dtau_dq, bp::return_internal_reference<>()),
101 bp::make_setter(&Data::dtau_dq), "Force contribution to dtau_dq");
102 40 }
103 };
104
105 #define CROCODDYL_CONTACT_MODEL_ABSTRACT_PYTHON_BINDINGS(Scalar) \
106 typedef ContactModelAbstractTpl<Scalar> Model; \
107 typedef ContactModelAbstractTpl_wrap<Scalar> Model_wrap; \
108 typedef Model::StateMultibody State; \
109 bp::register_ptr_to_python<std::shared_ptr<Model>>(); \
110 bp::class_<Model_wrap, boost::noncopyable>( \
111 "ContactModelAbstract", \
112 "Abstract rigid contact model.\n\n" \
113 "It defines a template for rigid contact models based on " \
114 "acceleration-based holonomic constraints. The calc and calcDiff " \
115 "functions compute the contact Jacobian and drift (holonomic " \
116 "constraint) or the derivatives of the holonomic constraint, " \
117 "respectively.", \
118 bp::init<std::shared_ptr<State>, pinocchio::ReferenceFrame, std::size_t, \
119 bp::optional<std::size_t>>( \
120 bp::args("self", "state", "type", "nc", "nu"), \
121 "Initialize the contact model.\n\n" \
122 ":param state: state of the multibody system\n" \
123 ":param type: type of contact\n" \
124 ":param nc: dimension of contact model\n" \
125 ":param nu: dimension of the control vector (default state.nv)")) \
126 .def(ContactModelAbstractVisitor<Model_wrap>()) \
127 .def(PrintableVisitor<Model_wrap>()) \
128 .def(CopyableVisitor<Model_wrap>());
129
130 #define CROCODDYL_CONTACT_DATA_ABSTRACT_PYTHON_BINDINGS(Scalar) \
131 typedef ContactDataAbstractTpl<Scalar> Data; \
132 typedef ContactModelAbstractTpl<Scalar> Model; \
133 typedef ForceDataAbstractTpl<Scalar> ForceData; \
134 typedef pinocchio::DataTpl<Scalar> PinocchioData; \
135 bp::register_ptr_to_python<std::shared_ptr<Data>>(); \
136 bp::class_<Data, bp::bases<ForceData>>( \
137 "ContactDataAbstract", "Abstract class for contact datas.\n\n", \
138 bp::init<Model*, PinocchioData*>( \
139 bp::args("self", "model", "data"), \
140 "Create common data shared between contact models.\n\n" \
141 ":param model: contact model\n" \
142 ":param data: Pinocchio data")[bp::with_custodian_and_ward< \
143 1, 2, bp::with_custodian_and_ward<1, 3>>()]) \
144 .def(ContactDataAbstractVisitor<Data>()) \
145 .def(CopyableVisitor<Data>());
146
147 10 void exposeContactAbstract() {
148
15/30
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 10 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 10 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 10 times.
✗ Branch 16 not taken.
✓ Branch 21 taken 10 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 10 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 10 times.
✗ Branch 28 not taken.
✓ Branch 32 taken 10 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 10 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 10 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 10 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 10 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 10 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 10 times.
✗ Branch 51 not taken.
20 CROCODDYL_PYTHON_SCALARS(CROCODDYL_CONTACT_MODEL_ABSTRACT_PYTHON_BINDINGS)
149
15/30
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 10 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 10 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 10 times.
✗ Branch 16 not taken.
✓ Branch 21 taken 10 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 10 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 10 times.
✗ Branch 28 not taken.
✓ Branch 32 taken 10 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 10 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 10 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 10 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 10 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 10 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 10 times.
✗ Branch 51 not taken.
20 CROCODDYL_PYTHON_SCALARS(CROCODDYL_CONTACT_DATA_ABSTRACT_PYTHON_BINDINGS)
150 10 }
151
152 } // namespace python
153 } // namespace crocoddyl
154