GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/control/admittance-control-op-point.cpp Lines: 75 96 78.1 %
Date: 2023-03-13 12:09:37 Branches: 173 410 42.2 %

Line Branch Exec Source
1
/*
2
 * Copyright 2019
3
 *
4
 * LAAS-CNRS
5
 *
6
 * Noƫlie Ramuzat
7
 * This file is part of sot-core.
8
 * See license file.
9
 */
10
11
#include "sot/core/admittance-control-op-point.hh"
12
13
#include <dynamic-graph/all-commands.h>
14
#include <dynamic-graph/factory.h>
15
16
#include <sot/core/debug.hh>
17
#include <sot/core/stop-watch.hh>
18
19
namespace dynamicgraph {
20
namespace sot {
21
namespace core {
22
namespace dg = ::dynamicgraph;
23
using namespace dg;
24
using namespace pinocchio;
25
using namespace dg::command;
26
27
#define PROFILE_ADMITTANCECONTROLOPPOINT_WFORCE_COMPUTATION \
28
  "AdmittanceControlOpPoint: w_force computation   "
29
30
#define PROFILE_ADMITTANCECONTROLOPPOINT_WDQ_COMPUTATION \
31
  "AdmittanceControlOpPoint: w_dq computation      "
32
33
#define PROFILE_ADMITTANCECONTROLOPPOINT_DQ_COMPUTATION \
34
  "AdmittanceControlOpPoint: dq computation        "
35
36
#define INPUT_SIGNALS                                                      \
37
  m_KpSIN << m_KdSIN << m_dqSaturationSIN << m_forceSIN << m_w_forceDesSIN \
38
          << m_opPoseSIN << m_sensorPoseSIN
39
40
#define INNER_SIGNALS m_w_forceSINNER << m_w_dqSINNER
41
42
#define OUTPUT_SIGNALS m_dqSOUT
43
44
/// Define EntityClassName here rather than in the header file
45
/// so that it can be used by the macros DEFINE_SIGNAL_**_FUNCTION.
46
typedef AdmittanceControlOpPoint EntityClassName;
47
48
/* --- DG FACTORY ---------------------------------------------------- */
49
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(AdmittanceControlOpPoint,
50
                                   "AdmittanceControlOpPoint");
51
52
/* ------------------------------------------------------------------- */
53
/* --- CONSTRUCTION -------------------------------------------------- */
54
/* ------------------------------------------------------------------- */
55
1
AdmittanceControlOpPoint::AdmittanceControlOpPoint(const std::string &name)
56
    : Entity(name),
57



2
      CONSTRUCT_SIGNAL_IN(Kp, dynamicgraph::Vector),
58



2
      CONSTRUCT_SIGNAL_IN(Kd, dynamicgraph::Vector),
59



2
      CONSTRUCT_SIGNAL_IN(dqSaturation, dynamicgraph::Vector),
60



2
      CONSTRUCT_SIGNAL_IN(force, dynamicgraph::Vector),
61



2
      CONSTRUCT_SIGNAL_IN(w_forceDes, dynamicgraph::Vector),
62



2
      CONSTRUCT_SIGNAL_IN(opPose, dynamicgraph::sot::MatrixHomogeneous),
63



2
      CONSTRUCT_SIGNAL_IN(sensorPose, dynamicgraph::sot::MatrixHomogeneous),
64



2
      CONSTRUCT_SIGNAL_INNER(w_force, dynamicgraph::Vector, m_forceSIN),
65






2
      CONSTRUCT_SIGNAL_INNER(w_dq, dynamicgraph::Vector,
66
                             INPUT_SIGNALS << m_w_forceSINNER),
67



2
      CONSTRUCT_SIGNAL_OUT(dq, dynamicgraph::Vector, m_w_dqSINNER),
68









21
      m_initSucceeded(false) {
69





1
  Entity::signalRegistration(INPUT_SIGNALS << INNER_SIGNALS << OUTPUT_SIGNALS);
70
71
  /* Commands. */
72

1
  addCommand("init", makeCommandVoid1(*this, &AdmittanceControlOpPoint::init,
73

2
                                      docCommandVoid1("Initialize the entity.",
74
                                                      "time step")));
75

1
  addCommand("resetDq",
76
1
             makeCommandVoid0(*this, &AdmittanceControlOpPoint::resetDq,
77

2
                              docCommandVoid0("resetDq")));
78
1
}
79
80
1
void AdmittanceControlOpPoint::init(const double &dt) {
81
1
  if (!m_dqSaturationSIN.isPlugged())
82
    return SEND_MSG("Init failed: signal dqSaturation is not plugged",
83
                    MSG_TYPE_ERROR);
84
1
  if (!m_KpSIN.isPlugged())
85
    return SEND_MSG("Init failed: signal Kp is not plugged", MSG_TYPE_ERROR);
86
1
  if (!m_KdSIN.isPlugged())
87
    return SEND_MSG("Init failed: signal Kd is not plugged", MSG_TYPE_ERROR);
88
1
  if (!m_forceSIN.isPlugged())
89
    return SEND_MSG("Init failed: signal force is not plugged", MSG_TYPE_ERROR);
90
1
  if (!m_w_forceDesSIN.isPlugged())
91
    return SEND_MSG("Init failed: signal w_forceDes is not plugged",
92
                    MSG_TYPE_ERROR);
93
1
  if (!m_opPoseSIN.isPlugged())
94
    return SEND_MSG("Init failed: signal opPose is not plugged",
95
                    MSG_TYPE_ERROR);
96
1
  if (!m_sensorPoseSIN.isPlugged())
97
    return SEND_MSG("Init failed: signal sensorPose is not plugged",
98
                    MSG_TYPE_ERROR);
99
100
1
  m_n = 6;
101
1
  m_dt = dt;
102
1
  m_w_dq.setZero(m_n);
103
1
  m_initSucceeded = true;
104
}
105
106
void AdmittanceControlOpPoint::resetDq() {
107
  m_w_dq.setZero(m_n);
108
  return;
109
}
110
111
/* ------------------------------------------------------------------- */
112
/* --- SIGNALS ------------------------------------------------------- */
113
/* ------------------------------------------------------------------- */
114
1
DEFINE_SIGNAL_INNER_FUNCTION(w_force, dynamicgraph::Vector) {
115
1
  if (!m_initSucceeded) {
116
    SEND_WARNING_STREAM_MSG(
117
        "Cannot compute signal w_force before initialization!");
118
    return s;
119
  }
120

1
  if (s.size() != 6) s.resize(6);
121
122

1
  getProfiler().start(PROFILE_ADMITTANCECONTROLOPPOINT_WFORCE_COMPUTATION);
123
124
1
  const Vector &force = m_forceSIN(iter);
125
1
  const MatrixHomogeneous &sensorPose = m_sensorPoseSIN(iter);
126

1
  assert(force.size() == m_n && "Unexpected size of signal force");
127
  pinocchio::SE3 sensorPlacement(
128
1
      sensorPose.matrix());  // homogeneous matrix to SE3
129


1
  s = sensorPlacement.act(pinocchio::Force(force)).toVector();
130
131

1
  getProfiler().stop(PROFILE_ADMITTANCECONTROLOPPOINT_WFORCE_COMPUTATION);
132
133
1
  return s;
134
}
135
136
1
DEFINE_SIGNAL_INNER_FUNCTION(w_dq, dynamicgraph::Vector) {
137
1
  if (!m_initSucceeded) {
138
    SEND_WARNING_STREAM_MSG(
139
        "Cannot compute signal w_dq before initialization!");
140
    return s;
141
  }
142
1
  if (s.size() != 6) s.resize(6);
143
144

1
  getProfiler().start(PROFILE_ADMITTANCECONTROLOPPOINT_WDQ_COMPUTATION);
145
146
1
  const Vector &w_forceDes = m_w_forceDesSIN(iter);
147
1
  const Vector &w_force = m_w_forceSINNER(iter);
148
1
  const Vector &Kp = m_KpSIN(iter);
149
1
  const Vector &Kd = m_KdSIN(iter);
150
1
  const Vector &dqSaturation = m_dqSaturationSIN(iter);
151
1
  assert(w_force.size() == m_n && "Unexpected size of signal force");
152
1
  assert(w_forceDes.size() == m_n && "Unexpected size of signal w_forceDes");
153
1
  assert(Kp.size() == m_n && "Unexpected size of signal Kp");
154
1
  assert(Kd.size() == m_n && "Unexpected size of signal Kd");
155
1
  assert(dqSaturation.size() == m_n &&
156
         "Unexpected size of signal dqSaturation");
157
158


1
  m_w_dq = m_w_dq + m_dt * (Kp.cwiseProduct(w_forceDes - w_force)) -
159
2
           Kd.cwiseProduct(m_w_dq);
160
161
7
  for (int i = 0; i < m_n; i++) {
162
6
    if (m_w_dq[i] > dqSaturation[i]) m_w_dq[i] = dqSaturation[i];
163
6
    if (m_w_dq[i] < -dqSaturation[i]) m_w_dq[i] = -dqSaturation[i];
164
  }
165
166
1
  s = m_w_dq;
167
168

1
  getProfiler().stop(PROFILE_ADMITTANCECONTROLOPPOINT_WDQ_COMPUTATION);
169
170
1
  return s;
171
}
172
173
1
DEFINE_SIGNAL_OUT_FUNCTION(dq, dynamicgraph::Vector) {
174
1
  if (!m_initSucceeded) {
175
    SEND_WARNING_STREAM_MSG("Cannot compute signal dq before initialization!");
176
    return s;
177
  }
178

1
  if (s.size() != 6) s.resize(6);
179
180

1
  getProfiler().start(PROFILE_ADMITTANCECONTROLOPPOINT_DQ_COMPUTATION);
181
182
1
  const Vector &w_dq = m_w_dqSINNER(iter);
183
1
  const MatrixHomogeneous &opPose = m_opPoseSIN(iter);
184

1
  assert(w_dq.size() == m_n && "Unexpected size of signal w_dq");
185
  pinocchio::SE3 opPointPlacement(
186
1
      opPose.matrix());  // homogeneous matrix to SE3
187


1
  s = opPointPlacement.actInv(pinocchio::Motion(w_dq)).toVector();
188
189

1
  getProfiler().stop(PROFILE_ADMITTANCECONTROLOPPOINT_DQ_COMPUTATION);
190
191
1
  return s;
192
}
193
194
/* --- COMMANDS ---------------------------------------------------------- */
195
196
/* ------------------------------------------------------------------- */
197
/* --- ENTITY -------------------------------------------------------- */
198
/* ------------------------------------------------------------------- */
199
void AdmittanceControlOpPoint::display(std::ostream &os) const {
200
  os << "AdmittanceControlOpPoint " << getName();
201
  try {
202
    getProfiler().report_all(3, os);
203
  } catch (ExceptionSignal e) {
204
  }
205
}
206
}  // namespace core
207
}  // namespace sot
208
}  // namespace dynamicgraph