GCC Code Coverage Report


Directory: ./
File: bindings/python/crocoddyl/core/costs/residual.cpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 13 13 100.0%
Branches: 42 84 50.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2021-2025, University of Edinburgh, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #include "crocoddyl/core/costs/residual.hpp"
10
11 #include "python/crocoddyl/core/core.hpp"
12
13 namespace crocoddyl {
14 namespace python {
15
16 template <typename Model>
17 struct CostModelResidualVisitor
18 : public bp::def_visitor<CostModelResidualVisitor<Model>> {
19 typedef typename Model::CostDataAbstract Data;
20 typedef typename Model::Base ModelBase;
21 typedef typename Model::StateAbstract State;
22 typedef typename Model::ResidualModelAbstract ResidualModel;
23 typedef typename Model::VectorXs VectorXs;
24 template <class PyClass>
25 40 void visit(PyClass& cl) const {
26
2/4
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
40 cl.def(bp::init<std::shared_ptr<State>, std::shared_ptr<ResidualModel>>(
27 bp::args("self", "state", "residual"),
28 "Initialize the residual cost model.\n\n"
29 ":param state: state description\n"
30 ":param residual: residual model"))
31
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
80 .def(
32 "calc",
33 static_cast<void (Model::*)(
34 const std::shared_ptr<Data>&, const Eigen::Ref<const VectorXs>&,
35 const Eigen::Ref<const VectorXs>&)>(&Model::calc),
36 bp::args("self", "data", "x", "u"),
37 "Compute the residual cost.\n\n"
38 ":param data: cost residual data\n"
39 ":param x: state point (dim. state.nx)\n"
40 ":param u: control input (dim. nu)")
41
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("calc",
42 static_cast<void (Model::*)(const std::shared_ptr<Data>&,
43 const Eigen::Ref<const VectorXs>&)>(
44 &Model::calc),
45 bp::args("self", "data", "x"),
46 "Compute the residual cost based on state only.\n\n"
47 "It updates the total cost based on the state only. This function "
48 "is used in the terminal nodes of an optimal control problem.\n"
49 ":param data: cost data\n"
50 ":param x: state point (dim. state.nx)")
51
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def(
52 "calcDiff",
53 static_cast<void (Model::*)(
54 const std::shared_ptr<Data>&, const Eigen::Ref<const VectorXs>&,
55 const Eigen::Ref<const VectorXs>&)>(&Model::calcDiff),
56 bp::args("self", "data", "x", "u"),
57 "Compute the derivatives of the residual cost.\n\n"
58 "It assumes that calc has been run first.\n"
59 ":param data: cost residual data\n"
60 ":param x: state point (dim. state.nx)\n"
61 ":param u: control input (dim. nu)")
62
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("calcDiff",
63 static_cast<void (Model::*)(const std::shared_ptr<Data>&,
64 const Eigen::Ref<const VectorXs>&)>(
65 &Model::calcDiff),
66 bp::args("self", "data", "x"),
67 "Compute the derivatives of the residual cost with respect to the "
68 "state only.\n\n"
69 "It updates the Jacobian and Hessian of the cost function based "
70 "on the state only. This function is used in the terminal nodes "
71 "of an optimal control problem.\n"
72 ":param data: cost residual data\n"
73 ":param x: state point (dim. state.nx)")
74
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("createData", &Model::createData,
75 40 bp::with_custodian_and_ward_postcall<0, 2>(),
76 bp::args("self", "data"),
77 "Create the residual cost data.\n\n"
78 "Each cost model has its own data that needs to be allocated. "
79 "This function returns the allocated data for a predefined cost.\n"
80 ":param data: shared data\n"
81 ":return cost data.");
82 40 }
83 };
84
85 #define CROCODDYL_COST_MODEL_RESIDUAL_PYTHON_BINDINGS(Scalar) \
86 typedef CostModelResidualTpl<Scalar> Model; \
87 typedef CostModelAbstractTpl<Scalar> ModelBase; \
88 typedef typename ModelBase::StateAbstract State; \
89 typedef typename ModelBase::ActivationModelAbstract ActivationModel; \
90 typedef typename ModelBase::ResidualModelAbstract ResidualModel; \
91 bp::register_ptr_to_python<std::shared_ptr<Model>>(); \
92 bp::class_<Model, bp::bases<ModelBase>>( \
93 "CostModelResidual", \
94 "This cost function uses a residual vector with a Gauss-Newton " \
95 "assumption to define a cost term.", \
96 bp::init<std::shared_ptr<State>, std::shared_ptr<ActivationModel>, \
97 std::shared_ptr<ResidualModel>>( \
98 bp::args("self", "state", "activation", "residual"), \
99 "Initialize the residual cost model.\n\n" \
100 ":param state: state description\n" \
101 ":param activation: activation model\n" \
102 ":param residual: residual model")) \
103 .def(CostModelResidualVisitor<Model>()) \
104 .def(CastVisitor<Model>()) \
105 .def(PrintableVisitor<Model>()) \
106 .def(CopyableVisitor<Model>());
107
108 #define CROCODDYL_COST_DATA_RESIDUAL_PYTHON_BINDINGS(Scalar) \
109 typedef CostDataResidualTpl<Scalar> Data; \
110 typedef CostDataAbstractTpl<Scalar> DataBase; \
111 typedef CostModelResidualTpl<Scalar> Model; \
112 typedef Model::DataCollectorAbstract DataCollector; \
113 bp::register_ptr_to_python<std::shared_ptr<Data>>(); \
114 bp::class_<Data, bp::bases<DataBase>>( \
115 "CostDataResidual", "Data for residual cost.\n\n", \
116 bp::init<Model*, DataCollector*>( \
117 bp::args("self", "model", "data"), \
118 "Create residual cost data.\n\n" \
119 ":param model: residual cost model\n" \
120 ":param data: shared data")[bp::with_custodian_and_ward< \
121 1, 2, bp::with_custodian_and_ward<1, 3>>()]) \
122 .def(CopyableVisitor<Data>());
123
124 10 void exposeCostResidual() {
125
17/34
✓ 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 18 taken 10 times.
✗ Branch 19 not taken.
✓ Branch 24 taken 10 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 10 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 10 times.
✗ Branch 31 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.
✓ Branch 53 taken 10 times.
✗ Branch 54 not taken.
✓ Branch 56 taken 10 times.
✗ Branch 57 not taken.
20 CROCODDYL_PYTHON_SCALARS(CROCODDYL_COST_MODEL_RESIDUAL_PYTHON_BINDINGS)
126
13/26
✓ 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 18 taken 10 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 10 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 10 times.
✗ Branch 25 not taken.
✓ Branch 29 taken 10 times.
✗ Branch 30 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.
20 CROCODDYL_PYTHON_SCALARS(CROCODDYL_COST_DATA_RESIDUAL_PYTHON_BINDINGS)
127 10 }
128
129 } // namespace python
130 } // namespace crocoddyl
131