Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
testVirtuoseJointLimits.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Test for Virtuose SDK wrapper.
32  */
33 
42 #include <visp3/core/vpTime.h>
43 #include <visp3/robot/vpVirtuose.h>
44 
45 #if defined(VISP_HAVE_VIRTUOSE)
46 
47 #ifdef ENABLE_VISP_NAMESPACE
48 using namespace VISP_NAMESPACE_NAME;
49 #endif
50 
51 void CallBackVirtuose(VirtContext VC, void *ptr)
52 {
53  (void)VC;
54  vpVirtuose *p_virtuose = (vpVirtuose *)ptr;
55 
56  float maxQ[6] = { 0.7811045051f, -0.07668215036f, 2.481732368f, 2.819076777f, 1.044736624f, 2.687076807f };
57  float minQ[6] = { -0.8011951447f, -1.648244739f, 0.7439950705f, -3.022218227f, -1.260564089f, -2.054088593f };
58  unsigned int numJoint = 6;
59 
60  vpColVector feedbackRegion(numJoint, 0);
61  vpColVector forceFeedback(numJoint, 0);
62 
63  int feedbackRegionFactor = 10;
64  float saturationForce[6] = { 5, 5, 5, 2.5, 2.5, 2.5 };
65 
66  for (unsigned int iter = 0; iter < numJoint; iter++)
67  feedbackRegion[iter] = (maxQ[iter] - minQ[iter]) / feedbackRegionFactor;
68 
69  vpColVector currentQ = p_virtuose->getArticularPosition();
70 
71  // force feedback definition
72  for (unsigned int iter = 0; iter < numJoint; iter++) {
73  if (currentQ[iter] >= (maxQ[iter] - feedbackRegion[iter])) {
74  forceFeedback[iter] =
75  -saturationForce[iter] * pow((currentQ[iter] - maxQ[iter] + feedbackRegion[iter]) / feedbackRegion[iter], 2);
76  std::cout << "WARNING! Getting close to the maximum joint limit. Joint #" << iter + 1 << std::endl;
77  }
78  else if (currentQ[iter] <= (minQ[iter] + feedbackRegion[iter])) {
79  forceFeedback[iter] =
80  saturationForce[iter] * pow((minQ[iter] + feedbackRegion[iter] - currentQ[iter]) / feedbackRegion[iter], 2);
81  std::cout << "WARNING! Getting close to the minimum joint limit. Joint #" << iter + 1 << std::endl;
82  }
83  else {
84  forceFeedback[iter] = 0;
85  std::cout << "Safe zone" << std::endl;
86  }
87  }
88 
89  // Printing force feedback
90  // std::cout << "Force feedback: " << forceFeedback.t() << std::endl;
91 
92  // Set force feedback
93  p_virtuose->setArticularForce(forceFeedback);
94 
95  return;
96 }
97 
98 int main(int argc, char **argv)
99 {
100  std::string opt_ip = "localhost";
101  int opt_port = 5000;
102  for (int i = 0; i < argc; i++) {
103  if (std::string(argv[i]) == "--ip")
104  opt_ip = std::string(argv[i + 1]);
105  else if (std::string(argv[i]) == "--port")
106  opt_port = std::atoi(argv[i + 1]);
107  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
108  std::cout << "\nUsage: " << argv[0]
109  << " [--ip <localhost>] [--port <port>]"
110  " [--help] [-h]\n"
111  << std::endl
112  << "Description: " << std::endl
113  << " --ip <localhost>" << std::endl
114  << "\tHost IP address. Default value: \"localhost\"." << std::endl
115  << std::endl
116  << " --port <port>" << std::endl
117  << "\tCommunication port. Default value: 5000." << std::endl
118  << "\tSuggested values: " << std::endl
119  << "\t- 5000 to communicate with the Virtuose." << std::endl
120  << "\t- 53210 to communicate with the Virtuose equipped with the Glove." << std::endl
121  << std::endl;
122  return EXIT_SUCCESS;
123  ;
124  }
125  }
126 
127  try {
128  float period = 0.001f;
129  vpVirtuose virtuose;
130  virtuose.setTimeStep(period);
131  std::cout << "Try to connect to " << opt_ip << " port " << opt_port << std::endl;
132  virtuose.setIpAddressAndPort(opt_ip, opt_port);
133  virtuose.setVerbose(true);
134  virtuose.setPowerOn();
135 
136  // setArticularForce only works in COMMAND_TYPE_ARTICULAR_IMPEDANCE.
137  virtuose.setCommandType(COMMAND_TYPE_ARTICULAR_IMPEDANCE);
138 
139  // -----------------------------------------------------------
140  // Code to obtain (experimentally) the Virtuose joint limits
141  // -----------------------------------------------------------
142 
143  /*
144  // Move the Virtuose in all its workspace while running this code
145 
146  vpColVector joints(6);
147  vpColVector max_joint(6,-1000);
148  vpColVector min_joint(6,1000);
149 
150  for(unsigned int iter=0; iter<10000; iter++) {
151  virtuose.getArticularPosition(joints);
152  for(unsigned int i=0; i<6; i++) {
153  if (joints[i] > max_joint[i])
154  max_joint[i] = joints[i];
155  if (joints[i] < min_joint[i])
156  min_joint[i] = joints[i];
157  }
158  // Printing joint values
159  std::cout << "Joint values: " << joints.t() << std::endl;
160  vpTime::wait(10);
161  }
162 
163  std::cout << "Max Joint values: " << max_joint.t() << std::endl;
164  std::cout << "Min Joint values: " << min_joint.t() << std::endl;
165 
166  // Best Result (small errors are to be expected)
167  // Max Joint values: 0.7811045051 -0.07668215036 2.481732368
168  2.819076777 1.044736624 2.687076807
169  // Min Joint values: -0.8011951447 -1.648244739 0.7439950705
170  -3.022218227 -1.260564089 -2.054088593
171 */
172 
173  virtuose.setPeriodicFunction(CallBackVirtuose);
174  virtuose.startPeriodicFunction();
175 
176  int counter = 0;
177  bool swtch = true;
178 
179  while (swtch) {
180  if (counter >= 10) {
181  virtuose.stopPeriodicFunction();
182  virtuose.setPowerOff();
183  swtch = false;
184  }
185  counter++;
186  vpTime::sleepMs(1000);
187  }
188 
189  std::cout << "The end" << std::endl;
190  }
191  catch (const vpException &e) {
192  std::cout << "Catch an exception: " << e.getStringMessage() << std::endl;
193  return EXIT_FAILURE;
194  }
195  return EXIT_SUCCESS;
196 }
197 
198 #else
199 int main()
200 {
201  std::cout << "You should install Virtuose API to use this binary..." << std::endl;
202  return EXIT_SUCCESS;
203 }
204 #endif
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
const std::string & getStringMessage() const
Definition: vpException.cpp:67
vpColVector getArticularPosition() const
Definition: vpVirtuose.cpp:134
void setIpAddressAndPort(const std::string &ip, int port)
Definition: vpVirtuose.cpp:81
void setPowerOff()
Definition: vpVirtuose.cpp:925
void setTimeStep(const float &timeStep)
Definition: vpVirtuose.cpp:968
void setCommandType(const VirtCommandType &type)
Definition: vpVirtuose.cpp:729
void setPeriodicFunction(VirtPeriodicFunction CallBackVirt)
Definition: vpVirtuose.cpp:885
void stopPeriodicFunction()
void setPowerOn()
Definition: vpVirtuose.cpp:938
void setVerbose(bool mode)
Definition: vpVirtuose.h:196
void setArticularForce(const vpColVector &articularForce)
Definition: vpVirtuose.cpp:606
void startPeriodicFunction()
VISP_EXPORT void sleepMs(double t)