GCC Code Coverage Report


Directory: ./
File: src/task/gain-adaptive.cpp
Date: 2024-12-13 12:22:33
Exec Total Coverage
Lines: 36 54 66.7%
Branches: 40 114 35.1%

Line Branch Exec Source
1 /*
2 * Copyright 2010,
3 * François Bleibel,
4 * Olivier Stasse,
5 *
6 * CNRS/AIST
7 *
8 */
9
10 /* SOT */
11 #include <sot/core/gain-adaptive.hh>
12
13 /* --------------------------------------------------------------------- */
14 /* --------------------------------------------------------------------- */
15 /* --------------------------------------------------------------------- */
16 #include <dynamic-graph/command-bind.h>
17
18 #include <sot/core/debug.hh>
19 #include <sot/core/exception-signal.hh>
20 #include <sot/core/factory.hh>
21
22 using namespace dynamicgraph::sot;
23 using namespace dynamicgraph;
24
25 DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(GainAdaptive, "GainAdaptive");
26
27 const double GainAdaptive::ZERO_DEFAULT = .1;
28 const double GainAdaptive::INFTY_DEFAULT = .1;
29 const double GainAdaptive::TAN_DEFAULT = 1;
30
31 /* --------------------------------------------------------------------- */
32 /* --------------------------------------------------------------------- */
33 /* --------------------------------------------------------------------- */
34
35 #define __SOT_GAIN_ADAPTATIVE_INIT \
36 Entity(name), coeff_a(0), coeff_b(0), coeff_c(0), \
37 errorSIN(NULL, "sotGainAdaptive(" + name + ")::input(vector)::error"), \
38 gainSOUT(boost::bind(&GainAdaptive::computeGain, this, _1, _2), \
39 errorSIN, \
40 "sotGainAdaptive(" + name + ")::output(double)::gain")
41
42 3 void GainAdaptive::addCommands() {
43 using namespace ::dynamicgraph::command;
44 3 std::string docstring;
45 // Command SetConstant
46 docstring =
47 " \n"
48 " setConstant\n"
49 " Input:\n"
50 " floating point value: value at 0. Other values are set to"
51 "default.\n"
52
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 " \n";
53
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 addCommand("setConstant",
54
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 makeCommandVoid1(*this, &GainAdaptive::init, docstring));
55
56 // Command Set
57 docstring =
58 " \n"
59 " set\n"
60 " Input:\n"
61 " floating point value: value at 0,\n"
62 " floating point value: value at infinity,\n"
63 " floating point value: value at slope,\n"
64
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 " \n";
65
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
3 addCommand("set", makeCommandVoid3(*this, &GainAdaptive::init, docstring));
66 docstring =
67 " \n"
68 " set from value at 0 and infinity, with a passing point\n"
69 " Input:\n"
70 " floating point value: value at 0,\n"
71 " floating point value: value at infinity,\n"
72 " floating point value: reference point,\n"
73 " floating point value: percentage at ref point.\n"
74
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 " \n";
75
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 addCommand(
76 "setByPoint",
77
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 makeCommandVoid4(*this, &GainAdaptive::initFromPassingPoint, docstring));
78 3 }
79
80 2 GainAdaptive::GainAdaptive(const std::string &name)
81
9/18
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 2 times.
✗ Branch 29 not taken.
2 : __SOT_GAIN_ADAPTATIVE_INIT {
82 sotDEBUG(15) << "New gain <" << name << ">" << std::endl;
83
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 init();
84
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 Entity::signalRegistration(gainSOUT << errorSIN);
85
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 addCommands();
86 2 }
87
88 GainAdaptive::GainAdaptive(const std::string &name, const double &lambda)
89 : __SOT_GAIN_ADAPTATIVE_INIT {
90 init(lambda);
91 Entity::signalRegistration(gainSOUT);
92 addCommands();
93 }
94
95 1 GainAdaptive::GainAdaptive(const std::string &name, const double &valueAt0,
96 1 const double &valueAtInfty, const double &tanAt0)
97
9/18
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
1 : __SOT_GAIN_ADAPTATIVE_INIT {
98
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 init(valueAt0, valueAtInfty, tanAt0);
99
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Entity::signalRegistration(gainSOUT);
100
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addCommands();
101 1 }
102
103 3 void GainAdaptive::init(const double &valueAt0, const double &valueAtInfty,
104 const double &tanAt0) {
105 3 coeff_a = valueAt0 - valueAtInfty;
106
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (0 == coeff_a) {
107 2 coeff_b = 0;
108 } else {
109 1 coeff_b = tanAt0 / coeff_a;
110 }
111 3 coeff_c = valueAtInfty;
112
113 3 return;
114 }
115
116 /*
117 * The idea is to fix value at 0 and infinity. Now, we are looking for a smart
118 * way to chose the slope at 0 or the coeff B (it is more or less the same).
119 * I can imagine to way of using a passing point:
120 * - first, imposing a value gref at position xref: g(xref)=gref.
121 * In that case, B=-1/xref*log((gref-C)/A):
122 * gnuplot> A=1; C=.1; xref=.1; gref=.4; B=1/xref*log((gref-C)/A)
123 * gnuplot> plot [0:(A+C)/B*10][C-.1*(A-C):A+C+.1*(A-C)] A*exp(-B*x)+C,
124 * A+C-B*x
125 * - second solution: imposing to reach a percentage of raise at a given point.
126 * It is more or less the same as before, but with gref := C+p*A, for a given p.
127 * In that case, B=-1/xref*log(p) gnuplot> A=1; C=.1; xref=.1; p=.1;
128 * B=1/xref*log(p) gnuplot> plot [0:(A+C)/B*10][C-.1*(A-C):A+C+.1*(A-C)]
129 * A*exp(-B*x)+C, A+C-B*x
130 *
131 * The second solution is tried in the following.
132 */
133 void GainAdaptive::initFromPassingPoint(const double &valueAt0,
134 const double &valueAtInfty,
135 const double &xref,
136 const double &p) // gref )
137 {
138 coeff_c = valueAtInfty;
139 coeff_a = valueAt0 - valueAtInfty;
140 if (0 == coeff_a) {
141 coeff_b = 0;
142 } else {
143 // coeff_b = -1/xref*log( (gref-coeff_c)/coeff_a );
144 coeff_b = -1 / xref * log(p);
145 }
146 }
147
148 void GainAdaptive::forceConstant(void) { coeff_a = 0; }
149
150 /* --------------------------------------------------------------------- */
151 /* --------------------------------------------------------------------- */
152 /* --------------------------------------------------------------------- */
153
154 void GainAdaptive::display(std::ostream &os) const {
155 os << "Gain Adaptative " << getName();
156 try {
157 os << " = " << double(gainSOUT.accessCopy());
158 } catch (ExceptionSignal e) {
159 }
160 os << " (" << coeff_a << ";" << coeff_b << ";" << coeff_c << ") ";
161 }
162
163 /* --------------------------------------------------------------------- */
164 /* --------------------------------------------------------------------- */
165 /* --------------------------------------------------------------------- */
166 1 double &GainAdaptive::computeGain(double &res, int t) {
167 sotDEBUGIN(15);
168 1 const dynamicgraph::Vector &error = errorSIN(t);
169 1 const double norm = error.norm();
170 1 res = coeff_a * exp(-coeff_b * norm) + coeff_c;
171
172 sotDEBUGOUT(15);
173 1 return res;
174 }
175