GCC Code Coverage Report


Directory: ./
File: python/collision.cc
Date: 2025-04-01 09:23:31
Exec Total Coverage
Lines: 112 129 86.8%
Branches: 96 192 50.0%

Line Branch Exec Source
1 //
2 // Software License Agreement (BSD License)
3 //
4 // Copyright (c) 2019-2021 CNRS-LAAS, INRIA
5 // Author: Joseph Mirabel
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following
16 // disclaimer in the documentation and/or other materials provided
17 // with the distribution.
18 // * Neither the name of CNRS-LAAS. nor the names of its
19 // contributors may be used to endorse or promote products derived
20 // from this software without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 // POSSIBILITY OF SUCH DAMAGE.
34
35 #include <eigenpy/eigenpy.hpp>
36
37 #include "coal/fwd.hh"
38 COAL_COMPILER_DIAGNOSTIC_PUSH
39 COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
40 #include "coal/collision.h"
41 #include "coal/serialization/collision_data.h"
42 COAL_COMPILER_DIAGNOSTIC_POP
43
44 #include "coal.hh"
45 #include "deprecation.hh"
46 #include "serializable.hh"
47
48 #ifdef COAL_HAS_DOXYGEN_AUTODOC
49 #include "doxygen_autodoc/functions.h"
50 #include "doxygen_autodoc/coal/collision_data.h"
51 #endif
52
53 #include "../doc/python/doxygen.hh"
54 #include "../doc/python/doxygen-boost.hh"
55
56 using namespace boost::python;
57 using namespace coal;
58 using namespace coal::python;
59
60 namespace dv = doxygen::visitor;
61
62 template <int index>
63 const CollisionGeometry* geto(const Contact& c) {
64 return index == 1 ? c.o1 : c.o2;
65 }
66
67 struct ContactWrapper {
68 static Vec3s getNearestPoint1(const Contact& contact) {
69 return contact.nearest_points[0];
70 }
71 static Vec3s getNearestPoint2(const Contact& contact) {
72 return contact.nearest_points[1];
73 }
74 };
75
76 5 void exposeCollisionAPI() {
77 5 if (!eigenpy::register_symbolic_link_to_registered_type<
78
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 CollisionRequestFlag>()) {
79 10 enum_<CollisionRequestFlag>("CollisionRequestFlag")
80
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .value("CONTACT", CONTACT)
81
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .value("DISTANCE_LOWER_BOUND", DISTANCE_LOWER_BOUND)
82
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .value("NO_REQUEST", NO_REQUEST)
83
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .export_values();
84 }
85
86
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (!eigenpy::register_symbolic_link_to_registered_type<CPUTimes>()) {
87 10 class_<CPUTimes>("CPUTimes", no_init)
88
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def_readonly("wall", &CPUTimes::wall,
89 "wall time in micro seconds (us)")
90
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def_readonly("user", &CPUTimes::user,
91 "user time in micro seconds (us)")
92
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def_readonly("system", &CPUTimes::system,
93 "system time in micro seconds (us)")
94
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 .def("clear", &CPUTimes::clear, arg("self"), "Reset the time values.");
95 }
96
97 COAL_COMPILER_DIAGNOSTIC_PUSH
98 COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
99
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (!eigenpy::register_symbolic_link_to_registered_type<QueryRequest>()) {
100 10 class_<QueryRequest>("QueryRequest", doxygen::class_doc<QueryRequest>(),
101 no_init)
102
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_tolerance)
103
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_max_iterations)
104
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_variant)
105
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_convergence_criterion)
106
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_convergence_criterion_type)
107
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, gjk_initial_guess)
108
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, enable_cached_gjk_guess)
109
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 .add_property(
110 "enable_cached_gjk_guess",
111
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 bp::make_function(
112 +[](QueryRequest& self) -> bool {
113 return self.enable_cached_gjk_guess;
114 },
115
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
10 deprecated_warning_policy<>(
116 "enable_cached_gjk_guess has been marked as deprecated and "
117 "will be removed in a future release.\n"
118 "Please use gjk_initial_guess instead.")),
119
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 bp::make_function(
120 +[](QueryRequest& self, const bool value) -> void {
121 self.enable_cached_gjk_guess = value;
122 },
123
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
10 deprecated_warning_policy<>(
124 "enable_cached_gjk_guess has been marked as deprecated and "
125 "will be removed in a future release.\n"
126 "Please use gjk_initial_guess instead.")),
127 doxygen::class_attrib_doc<QueryRequest>("enable_cached_gjk_guess"))
128
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, cached_gjk_guess)
129
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, cached_support_func_guess)
130
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, epa_max_iterations)
131
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, epa_tolerance)
132
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryRequest, enable_timings)
133
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 .DEF_CLASS_FUNC(QueryRequest, updateGuess);
134 }
135 COAL_COMPILER_DIAGNOSTIC_POP
136
137 COAL_COMPILER_DIAGNOSTIC_PUSH
138 COAL_COMPILER_DIAGNOSTIC_IGNORED_DEPRECECATED_DECLARATIONS
139
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (!eigenpy::register_symbolic_link_to_registered_type<CollisionRequest>()) {
140 10 class_<CollisionRequest, bases<QueryRequest> >(
141 "CollisionRequest", doxygen::class_doc<CollisionRequest>(), no_init)
142
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .def(dv::init<CollisionRequest>())
143
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .def(dv::init<CollisionRequest, const CollisionRequestFlag, size_t>())
144
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(CollisionRequest, num_max_contacts)
145
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(CollisionRequest, enable_contact)
146
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 .add_property(
147 "enable_distance_lower_bound",
148
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 bp::make_function(
149 +[](CollisionRequest& self) -> bool {
150 return self.enable_distance_lower_bound;
151 },
152
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
10 deprecated_warning_policy<>(
153 "enable_distance_lower_bound has been marked as "
154 "deprecated. "
155 "A lower bound on distance is always computed.\n")),
156
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 bp::make_function(
157 +[](CollisionRequest& self, const bool value) -> void {
158 self.enable_distance_lower_bound = value;
159 },
160
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
10 deprecated_warning_policy<>(
161 "enable_distance_lower_bound has been marked as "
162 "deprecated. "
163 "A lower bound on distance is always computed.\n")),
164 doxygen::class_attrib_doc<CollisionRequest>(
165 "enable_distance_lower_bound"))
166
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(CollisionRequest, security_margin)
167
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(CollisionRequest, break_distance)
168
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(CollisionRequest, distance_upper_bound)
169
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(SerializableVisitor<CollisionRequest>());
170 }
171
172 5 if (!eigenpy::register_symbolic_link_to_registered_type<
173
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 std::vector<CollisionRequest> >()) {
174 10 class_<std::vector<CollisionRequest> >("StdVec_CollisionRequest")
175
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(vector_indexing_suite<std::vector<CollisionRequest> >());
176 }
177 COAL_COMPILER_DIAGNOSTIC_POP
178
179
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (!eigenpy::register_symbolic_link_to_registered_type<Contact>()) {
180
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 class_<Contact>("Contact", doxygen::class_doc<Contact>(),
181
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 init<>(arg("self"), "Default constructor"))
182
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(dv::init<Contact, const CollisionGeometry*,
183 5 const CollisionGeometry*, int, int>())
184
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(dv::init<Contact, const CollisionGeometry*,
185 const CollisionGeometry*, int, int, const Vec3s&,
186 5 const Vec3s&, Scalar>())
187
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 .add_property(
188 "o1",
189
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 make_function(&geto<1>,
190 5 return_value_policy<reference_existing_object>()),
191 doxygen::class_attrib_doc<Contact>("o1"))
192
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 .add_property(
193 "o2",
194
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 make_function(&geto<2>,
195 5 return_value_policy<reference_existing_object>()),
196 doxygen::class_attrib_doc<Contact>("o2"))
197 10 .def("getNearestPoint1", &ContactWrapper::getNearestPoint1,
198
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 doxygen::class_attrib_doc<Contact>("nearest_points"))
199 10 .def("getNearestPoint2", &ContactWrapper::getNearestPoint2,
200
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 doxygen::class_attrib_doc<Contact>("nearest_points"))
201
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(Contact, b1)
202
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(Contact, b2)
203
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(Contact, normal)
204
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(Contact, nearest_points)
205
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(Contact, pos)
206
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(Contact, penetration_depth)
207
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .def(self == self)
208
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .def(self != self);
209 }
210
211 5 if (!eigenpy::register_symbolic_link_to_registered_type<
212
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 std::vector<Contact> >()) {
213 10 class_<std::vector<Contact> >("StdVec_Contact")
214
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(vector_indexing_suite<std::vector<Contact> >());
215 }
216
217
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (!eigenpy::register_symbolic_link_to_registered_type<QueryResult>()) {
218 10 class_<QueryResult>("QueryResult", doxygen::class_doc<QueryResult>(),
219 no_init)
220
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryResult, cached_gjk_guess)
221
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryResult, cached_support_func_guess)
222
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_RW_CLASS_ATTRIB(QueryResult, timings);
223 }
224
225
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (!eigenpy::register_symbolic_link_to_registered_type<CollisionResult>()) {
226 10 class_<CollisionResult, bases<QueryResult> >(
227 "CollisionResult", doxygen::class_doc<CollisionResult>(), no_init)
228
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .def(dv::init<CollisionResult>())
229
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 .DEF_CLASS_FUNC(CollisionResult, isCollision)
230
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 .DEF_CLASS_FUNC(CollisionResult, numContacts)
231
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 .DEF_CLASS_FUNC(CollisionResult, addContact)
232
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 .DEF_CLASS_FUNC(CollisionResult, clear)
233
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 .DEF_CLASS_FUNC2(CollisionResult, getContact,
234 return_value_policy<copy_const_reference>())
235
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(dv::member_func(
236 "getContacts",
237
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 static_cast<void (CollisionResult::*)(std::vector<Contact>&) const>(
238 &CollisionResult::getContacts)))
239 10 .def("getContacts",
240 static_cast<const std::vector<Contact>& (CollisionResult::*)()
241 const>(&CollisionResult::getContacts),
242 5 doxygen::member_func_doc(
243 static_cast<const std::vector<Contact>& (CollisionResult::*)()
244 const>(&CollisionResult::getContacts)),
245 return_internal_reference<>())
246
247
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
5 .DEF_RW_CLASS_ATTRIB(CollisionResult, distance_lower_bound)
248
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(SerializableVisitor<CollisionResult>());
249 }
250
251 5 if (!eigenpy::register_symbolic_link_to_registered_type<
252
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 std::vector<CollisionResult> >()) {
253 10 class_<std::vector<CollisionResult> >("StdVec_CollisionResult")
254
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(vector_indexing_suite<std::vector<CollisionResult> >());
255 }
256
257 5 doxygen::def("collide",
258 static_cast<std::size_t (*)(
259 const CollisionObject*, const CollisionObject*,
260 const CollisionRequest&, CollisionResult&)>(&collide));
261 5 doxygen::def(
262 "collide",
263 static_cast<std::size_t (*)(const CollisionGeometry*, const Transform3s&,
264 const CollisionGeometry*, const Transform3s&,
265 const CollisionRequest&, CollisionResult&)>(
266 &collide));
267
268 5 class_<ComputeCollision>("ComputeCollision",
269 doxygen::class_doc<ComputeCollision>(), no_init)
270
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def(dv::init<ComputeCollision, const CollisionGeometry*,
271 10 const CollisionGeometry*>())
272
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 .def("__call__",
273 static_cast<std::size_t (ComputeCollision::*)(
274 const Transform3s&, const Transform3s&, const CollisionRequest&,
275 CollisionResult&) const>(&ComputeCollision::operator()));
276 5 }
277