Visual Servoing Platform  version 3.6.1 under development (2024-03-29)
vpQbSoftHand.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Interface for the qb robotics devices.
33  *
34 *****************************************************************************/
35 
36 #include <visp3/core/vpConfig.h>
37 #if defined(VISP_HAVE_QBDEVICE) && defined(VISP_HAVE_THREADS)
38 
39 #include <regex>
40 
41 #include <visp3/robot/vpQbSoftHand.h>
42 
48 
54 void vpQbSoftHand::getCurrent(vpColVector &current, const int &id)
55 {
56  if (!m_init_done) {
57  init(id);
58  }
59 
60  current.resize(1);
61  if (!isInConnectedSet(id)) {
62  throw(vpException(vpException::fatalError, "Cannot get current, Qb device is not connected"));
63  }
64 
65  std::vector<short int> currents(2);
66  int failures = getCurrents(id, m_max_repeats, currents); // blocks while reading
67 
68  if (!isReliable(failures, m_max_repeats)) {
70  "Cannot get current, communication error with Qb device after %d attempts", m_max_repeats));
71  }
72  current[0] = static_cast<double>(currents[0]);
73 }
74 
81 void vpQbSoftHand::getPosition(vpColVector &position, const int &id)
82 {
83  if (!m_init_done) {
84  init(id);
85  }
86 
87  position.resize(1);
88  if (!isInConnectedSet(id)) {
89  throw(vpException(vpException::fatalError, "Cannot get position, Qb device is not connected"));
90  }
91 
92  std::vector<short int> positions;
93  int failures = getPositions(id, m_max_repeats, positions); // blocks while reading
94 
95  position[0] = static_cast<double>(positions[0]) / static_cast<double>(getPositionLimits()[1]);
96 
97  if (!isReliable(failures, m_max_repeats)) {
99  "Cannot get position, communication error with Qb device after %d attempts", m_max_repeats));
100  }
101 }
102 
109 void vpQbSoftHand::setPosition(const vpColVector &position, const int &id)
110 {
111  if (!m_init_done) {
112  init(id);
113  }
114 
115  std::vector<short int> commands(2);
116  if (position.size() != 1) {
117  throw(vpException(vpException::fatalError, "Command vector size %d is not equal to 2", position.size()));
118  }
119 
120  std::vector<short int> position_limits = getPositionLimits();
121 
122  commands[0] = static_cast<short int>(position[0] * position_limits[1]);
123 
124  if (commands[0] < position_limits[0]) {
125  commands[0] = position_limits[0];
126  }
127  else if (commands[0] > position_limits[1]) {
128  commands[0] = position_limits[1];
129  }
130 
131  if (!isInConnectedSet(id)) {
132  throw(vpException(vpException::fatalError, "Cannot set position, Qb device is not connected"));
133  }
134 
135  // int failures = setCommandsAndWait(id, m_max_repeats, commands); // FS: doesn't work
136  int failures = setCommandsAsync(id, commands);
137 
138  if (!isReliable(failures, m_max_repeats)) {
140  "Cannot set position, communication error with Qb device after %d attempts", m_max_repeats));
141  }
142 }
143 
154 void vpQbSoftHand::setPosition(const vpColVector &position, double speed_factor, double stiffness, const int &id)
155 {
156  vpColVector q_mes(1), q(1), current;
157  getPosition(q_mes, id);
158  double current_max = getCurrentMax();
159 
160  double max_delta_q = 1; // 0 opened, 1 closed
161  double min_delta_t = 2.0; // number of [sec] to open or close with the max velocity
162  double precision = 0.05;
163  double delta_t = 40; // [ms]
164  double max_slope = max_delta_q / min_delta_t;
165  double sign = (position[0] > q_mes[0]) ? 1.0 : -1.0;
166  double vel = speed_factor;
167  if (vel < 0.01) {
168  vel = 0.01;
169  }
170  else if (vel > 1.) {
171  vel = 1.0;
172  }
173  double current_factor = stiffness;
174  if (current_factor < 0.0) {
175  current_factor = 0.0;
176  }
177  else if (current_factor > 1.) {
178  current_factor = 1.0;
179  }
180  double slope = sign * max_slope * vel;
181 
182  unsigned int i = 0;
183  int current_failures = 0;
184  do {
185  double t0 = vpTime::measureTimeMs();
186  q[0] = q_mes[0] + slope * delta_t / 1000.0 * i;
187  if (q[0] < getPositionLimits()[0]) {
188  q[0] = getPositionLimits()[0];
189  }
190  else if (q[0] > getPositionLimits()[1]) {
191  q[0] = getPositionLimits()[1];
192  }
193  setPosition(q, id);
194  getCurrent(current, id);
195  i++;
196 
197  if (std::fabs(current[0]) > current_factor * current_max) {
198  current_failures++;
199  }
200  else {
201  current_failures = 0;
202  }
203 
204  vpTime::wait(t0, delta_t);
205  } while (!vpMath::equal(q[0], position[0], precision) && !(current_failures > 1));
206 }
207 #endif
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:286
Implementation of column vector and the associated operations.
Definition: vpColVector.h:163
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1056
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ fatalError
Fatal error.
Definition: vpException.h:84
static bool equal(double x, double y, double threshold=0.001)
Definition: vpMath.h:449
bool isReliable(int const &failures, int const &max_repeats)
Definition: vpQbDevice.cpp:690
double getCurrentMax() const
Definition: vpQbDevice.cpp:528
virtual bool isInConnectedSet(const int &id)
Definition: vpQbDevice.cpp:674
virtual bool init(const int &id)
Definition: vpQbDevice.cpp:638
int m_max_repeats
Max number of trials to send a command.
Definition: vpQbDevice.h:112
virtual int getCurrents(const int &id, const int &max_repeats, std::vector< short int > &currents)
Definition: vpQbDevice.cpp:540
std::vector< short int > getPositionLimits() const
Definition: vpQbDevice.cpp:598
virtual int getPositions(const int &id, const int &max_repeats, std::vector< short int > &positions)
Definition: vpQbDevice.cpp:611
virtual int setCommandsAsync(const int &id, std::vector< short int > &commands)
Definition: vpQbDevice.cpp:726
bool m_init_done
Flag used to indicate if the device is initialized.
Definition: vpQbDevice.h:113
void getCurrent(vpColVector &current, const int &id=1)
void setPosition(const vpColVector &position, const int &id=1)
void getPosition(vpColVector &position, const int &id=1)
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMs()