GCC Code Coverage Report


Directory: ./
File: bindings/python/crocoddyl/core/optctrl/shooting.cpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 29 29 100.0%
Branches: 55 110 50.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2025, LAAS-CNRS, University of Edinburgh,
5 // University of Oxford, Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "crocoddyl/core/optctrl/shooting.hpp"
11
12 #include <memory>
13
14 #include "python/crocoddyl/core/core.hpp"
15
16 namespace crocoddyl {
17 namespace python {
18
19 template <typename Problem>
20 struct ShootingProblemVisitor
21 : public bp::def_visitor<ShootingProblemVisitor<Problem>> {
22 typedef typename Problem::ActionModelAbstract ActionModel;
23 typedef typename Problem::ActionDataAbstract ActionData;
24 typedef typename Problem::VectorXs VectorXs;
25 template <class PyClass>
26 40 void visit(PyClass& cl) const {
27
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<VectorXs, std::vector<std::shared_ptr<ActionModel>>,
28 std::shared_ptr<ActionModel>,
29 std::vector<std::shared_ptr<ActionData>>,
30 std::shared_ptr<ActionData>>(
31 bp::args("self", "x0", "runningModels", "terminalModel",
32 "runningDatas", "terminalData"),
33 "Initialize the shooting problem (models and datas).\n\n"
34 ":param x0: initial state\n"
35 ":param runningModels: running action models (size T)\n"
36 ":param terminalModel: terminal action model\n"
37 ":param runningDatas: running action datas (size T)\n"
38 ":param terminalData: terminal action data"))
39
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
80 .def("calc", &Problem::calc, bp::args("self", "xs", "us"),
40 "Compute the cost and the next states.\n\n"
41 "For each node k, and along the state xs and control us "
42 "trajectories, it computes the next state x_{k+1} and cost l_k.\n"
43 ":param xs: time-discrete state trajectory (size T+1)\n"
44 ":param us: time-discrete control sequence (size T)\n"
45 ":returns the total cost value")
46
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("calcDiff", &Problem::calcDiff, bp::args("self", "xs", "us"),
47 "Compute the derivatives of the cost and dynamics.\n\n"
48 "For each node k, and along the state x_s and control u_s "
49 "trajectories, it computes the derivatives of the cost (lx, lu, "
50 "lxx, lxu, luu) and dynamics (fx, fu).\n"
51 ":param xs: time-discrete state trajectory (size T+1)\n"
52 ":param us: time-discrete control sequence (size T)\n"
53 ":returns the total cost value")
54
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("rollout", &Problem::rollout_us, bp::args("self", "us"),
55 "Integrate the dynamics given a control sequence.\n\n"
56 "Rollout the dynamics give a sequence of control commands\n"
57 ":param us: time-discrete control sequence (size T)")
58
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("quasiStatic", &Problem::quasiStatic_xs, bp::args("self", "xs"),
59 "Compute the quasi static commands given a state trajectory.\n\n"
60 "Generally speaking, it uses Newton-Raphson method for computing "
61 "the quasi static commands.\n"
62 ":param xs: time-discrete state trajectory (size T)")
63
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("circularAppend",
64 static_cast<void (Problem::*)(std::shared_ptr<ActionModel>,
65 std::shared_ptr<ActionData>)>(
66 &Problem::circularAppend),
67 bp::args("self", "model", "data"),
68 bp::args("self", "model", "data"),
69 "Circular append the model and data onto the end running node.\n\n"
70 "Once we update the end running node, the first running mode is "
71 "removed as in a circular buffer.\n"
72 ":param model: new model\n"
73 ":param data: new data")
74
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("circularAppend",
75 static_cast<void (Problem::*)(std::shared_ptr<ActionModel>)>(
76 &Problem::circularAppend),
77 bp::args("self", "model"),
78 "Circular append the model and data onto the end running node.\n\n"
79 "Once we update the end running node, the first running mode is "
80 "removed as in a circular buffer. Note that this method allocates "
81 "new data for the end running node.\n"
82 ":param model: new model")
83
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("updateNode", &Problem::updateNode,
84 bp::args("self", "i", "model", "data"),
85 "Update the model and data for a specific node.\n\n"
86 ":param i: index of the node (0 <= i <= T + 1)\n"
87 ":param model: new model\n"
88 ":param data: new data")
89
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .def("updateModel", &Problem::updateModel,
90 bp::args("self", "i", "model"),
91 "Update a model and allocated new data for a specific node.\n\n"
92 ":param i: index of the node (0 <= i <= T + 1)\n"
93 ":param model: new model")
94
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("T", bp::make_function(&Problem::get_T),
95 "number of running nodes")
96
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 .add_property("x0",
97 bp::make_function(&Problem::get_x0,
98 40 bp::return_internal_reference<>()),
99 &Problem::set_x0, "initial state")
100
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .add_property(
101 "runningModels",
102 bp::make_function(&Problem::get_runningModels,
103 40 bp::return_value_policy<bp::return_by_value>()),
104 &Problem::set_runningModels, "running models")
105
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .add_property(
106 "terminalModel",
107 bp::make_function(&Problem::get_terminalModel,
108 40 bp::return_value_policy<bp::return_by_value>()),
109 &Problem::set_terminalModel, "terminal model")
110
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(
111 "runningDatas",
112 bp::make_function(&Problem::get_runningDatas,
113 40 bp::return_value_policy<bp::return_by_value>()),
114 "running datas")
115
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
40 .add_property(
116 "terminalData",
117 bp::make_function(&Problem::get_terminalData,
118 40 bp::return_value_policy<bp::return_by_value>()),
119 "terminal data")
120
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(
121 "nthreads", bp::make_function(&Problem::get_nthreads),
122 bp::make_function(&Problem::set_nthreads),
123 "number of threads launch by the multi-threading support (if you "
124 "set nthreads <= 1, then nthreads=CROCODDYL_WITH_NTHREADS)")
125
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .add_property("nx", bp::make_function(&Problem::get_nx),
126 "dimension of state tuple")
127
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
80 .add_property("ndx", bp::make_function(&Problem::get_ndx),
128 "dimension of the tangent space of the state manifold")
129
2/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
40 .add_property("is_updated", bp::make_function(&Problem::is_updated),
130 "Returns True if the shooting problem has been updated, "
131 "otherwise False");
132 40 }
133 };
134
135 #define CROCODDYL_SHOOTING_PROBLEM_PYTHON_BINDINGS(Scalar) \
136 typedef ShootingProblemTpl<Scalar> Problem; \
137 typedef ActionModelAbstractTpl<Scalar> ActionModel; \
138 typedef typename Problem::VectorXs VectorXs; \
139 bp::register_ptr_to_python<std::shared_ptr<Problem>>(); \
140 bp::class_<Problem>( \
141 "ShootingProblem", \
142 "Declare a shooting problem.\n\n" \
143 "A shooting problem declares the initial state, a set of running " \
144 "action models and a terminal action model. It has three main methods " \
145 "- calc, calcDiff and rollout. The first computes the set of next " \
146 "states and cost values per each action model. calcDiff updates the " \
147 "derivatives of all action models. The last rollouts the stacks of " \
148 "actions models.", \
149 bp::init<VectorXs, std::vector<std::shared_ptr<ActionModel>>, \
150 std::shared_ptr<ActionModel>>( \
151 bp::args("self", "x0", "runningModels", "terminalModel"), \
152 "Initialize the shooting problem and allocate its data.\n\n" \
153 ":param x0: initial state\n" \
154 ":param runningModels: running action models (size T)\n" \
155 ":param terminalModel: terminal action model")) \
156 .def(ShootingProblemVisitor<Problem>()) \
157 .def(PrintableVisitor<Problem>()) \
158 .def(CopyableVisitor<Problem>());
159
160 10 void exposeShootingProblem() {
161
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_SHOOTING_PROBLEM_PYTHON_BINDINGS)
162 10 }
163
164 } // namespace python
165 } // namespace crocoddyl
166