GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/task/gain-adaptive.cpp Lines: 36 54 66.7 %
Date: 2023-03-13 12:09:37 Branches: 40 112 35.7 %

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
3
      "    \n";
53

3
  addCommand("setConstant",
54
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
3
      "    \n";
65

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
3
      "    \n";
75

3
  addCommand(
76
      "setByPoint",
77
3
      makeCommandVoid4(*this, &GainAdaptive::initFromPassingPoint, docstring));
78
3
}
79
80
2
GainAdaptive::GainAdaptive(const std::string &name)
81




2
    : __SOT_GAIN_ADAPTATIVE_INIT {
82
  sotDEBUG(15) << "New gain <" << name << ">" << std::endl;
83
2
  init();
84

2
  Entity::signalRegistration(gainSOUT << errorSIN);
85
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




1
    : __SOT_GAIN_ADAPTATIVE_INIT {
98
1
  init(valueAt0, valueAtInfty, tanAt0);
99

1
  Entity::signalRegistration(gainSOUT);
100
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
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
}