Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpForceTorqueAtiSensor.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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  * ATI Force torque interface.
32  *
33  * Authors:
34  * Fabien Spindler
35  *
36  *****************************************************************************/
37 
38 #include <visp3/core/vpConfig.h>
39 
40 #if defined(VISP_HAVE_ATIDAQ) && defined(VISP_HAVE_COMEDI)
41 
42 #include <ftconfig.h> // atidaq private library
43 
44 #include <visp3/core/vpException.h>
45 #include <visp3/sensor/vpForceTorqueAtiSensor.h>
46 
47 static Calibration *s_calibinfo = NULL;
48 
49 
54  : m_calibfile(""), m_index(1), m_num_axes(6), m_num_channels(6), m_sample_bias()
55 {
56 }
57 
63 {
64  // Open access to device
67 }
68 
74 {
75  open();
76 
77  // Get FT from device
79 
81  throw vpException(vpException::fatalError, "Physical data size (%d) and number of channels (%d) doesn't match", m_sample_bias.size(), m_num_channels);
82 
83  float *sample_bias = new float [m_num_channels];
84  for(unsigned int i=0; i<m_num_channels; i++)
85  sample_bias[i] = m_sample_bias[i];
86 
87  Bias(s_calibinfo, sample_bias);
88 
89  delete [] sample_bias;
90 }
91 
97 {
98  open();
99 
100  // Get FT from device
102 
103  // Reset sample bias
104  m_sample_bias = 0;
105 
107  throw vpException(vpException::fatalError, "Physical data size (%d) and number of channels (%d) doesn't match", m_sample_bias.size(), m_num_channels);
108 
109  float *sample_bias = new float [m_num_channels];
110  for(unsigned int i=0; i<m_num_channels; i++)
111  sample_bias[i] = m_sample_bias[i];
112 
113  Bias(s_calibinfo, sample_bias);
114 
115  delete [] sample_bias;
116 }
117 
122 {
123  if(s_calibinfo != NULL) {
124  // free memory allocated to calibration structure
125  destroyCalibration(s_calibinfo);
126  s_calibinfo = NULL;
127  }
128  vpComedi::close();
129 }
130 
139 {
140  vpColVector phydata = vpComedi::getPhyData();
141 
142  if (phydata.size() != m_num_channels)
143  throw vpException(vpException::fatalError, "Physical data size (%d) and number of channels (%d) doesn't match",
144  phydata.size(), m_num_channels);
145 
146  float *voltage = new float [m_num_channels];
147  float *ft = new float [m_num_axes];
148 
149  for(unsigned int i=0; i<m_num_channels; i++) {
150  voltage[i] = phydata[i];
151  }
152 
153  // convert a loaded measurement into forces and torques
154  ConvertToFT(s_calibinfo, voltage, ft);
155 
156  vpColVector sample(m_num_axes);
157  for(unsigned int i=0; i<m_num_axes; i++)
158  sample[i] = ft[i];
159 
160  delete [] voltage;
161  delete [] ft;
162 
163  return sample;
164 }
165 
170 {
171  std::string units(s_calibinfo->ForceUnits);
172  return units;
173 }
178 {
179  std::string units(s_calibinfo->TorqueUnits);
180  return units;
181 }
182 
187 {
188  close();
189 }
190 
197 void vpForceTorqueAtiSensor::setCalibrationFile(const std::string &calibfile, unsigned short index)
198 {
199  m_calibfile = calibfile;
200  m_index = index;
201 
202  if (s_calibinfo)
203  destroyCalibration(s_calibinfo);
204 
205  char file[FILENAME_MAX];
206  sprintf(file, "%s", m_calibfile.c_str());
207 
208  // Create calibration struct
209  s_calibinfo = createCalibration(file, m_index);
210  if (s_calibinfo==NULL) {
211  throw vpException(vpException::fatalError, "Calibration file %s couldn't be loaded", m_calibfile.c_str());
212  }
213 
214  m_num_channels = s_calibinfo->rt.NumChannels;
215  m_num_axes = s_calibinfo->rt.NumAxes;
216 }
217 
237 std::ostream & operator<<(std::ostream &os, const vpForceTorqueAtiSensor &ati)
238 {
239  if (s_calibinfo==NULL) {
240  os << "Calibration Information is not available" << std::endl;
241  return os;
242  }
243 
244  // display info from calibration file
245  os << "Calibration Information for " << ati.m_calibfile << ", index #" << ati.m_index << ":" << std::endl;
246  os << " Serial: " << s_calibinfo->Serial << std::endl;
247  os << " Body Style: " << s_calibinfo->BodyStyle << std::endl;
248  os << " Calibration: " << s_calibinfo->PartNumber << std::endl;
249  os << " Calibration Date: " << s_calibinfo->CalDate << std::endl;
250  os << " Family: " << s_calibinfo->Family << std::endl;
251  os << " # Channels: " << s_calibinfo->rt.NumChannels << std::endl;
252  os << " # Axes: " << s_calibinfo->rt.NumAxes << std::endl;
253  os << " Force Units: " << s_calibinfo->ForceUnits << std::endl;
254  os << " Torque Units: " << s_calibinfo->TorqueUnits << std::endl;
255  os << "Temperature Compensation: " << (s_calibinfo->TempCompAvailable ? "Yes" : "No") << std::endl;
256 
257  // print maximum loads of axes
258  os << "\nRated Loads:" << std::endl;
259  for (unsigned short i=0;i<s_calibinfo->rt.NumAxes;i++) {
260  char *units;
261  if ((s_calibinfo->AxisNames[i])[0]=='F') {
262  units=s_calibinfo->ForceUnits;
263  } else units=s_calibinfo->TorqueUnits;
264  os << s_calibinfo->AxisNames[i] << ": " << s_calibinfo->MaxLoads[i] << " " << units << std::endl;
265  }
266 
267  // print temperature compensation information, if available
268  if (s_calibinfo->TempCompAvailable) {
269  os << "\nTemperature Compensation Information:" << std::endl;
270  os << "BS: ";
271  for (unsigned short i=0;i<s_calibinfo->rt.NumChannels-1;i++) {
272  os << s_calibinfo->rt.bias_slopes[i] << " ";
273  }
274  os << "\nGS: ";
275  for (unsigned short i=0;i<s_calibinfo->rt.NumChannels-1;i++) {
276  os << s_calibinfo->rt.gain_slopes[i] << " ";
277  }
278  os << "\nTherm: " << s_calibinfo->rt.thermistor << std::endl;
279  }
280 
281  return os;
282 }
283 
284 
285 #elif !defined(VISP_BUILD_SHARED_LIBS)
286 // Work arround to avoid warning: libvisp_sensor.a(vpForceTorqueAtiSensor.cpp.o) has no symbols
287 void dummy_vpForceTorqueAtiSensor() {};
288 #endif
void open()
Definition: vpComedi.cpp:68
void setChannelNumbers(const unsigned int &nchannel)
Definition: vpComedi.h:156
unsigned short m_index
Index of calibration in file (default: 1)
vpColVector getForceTorque() const
error that can be emited by ViSP classes.
Definition: vpException.h:73
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:156
std::string m_calibfile
ATI calibration file FT*.cal.
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Definition: vpArray2D.h:267
vpColVector m_sample_bias
Sample value used for bias.
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
std::string getForceUnits() const
void setCalibrationFile(const std::string &calibfile, unsigned short index=1)
unsigned short m_num_axes
Number of axis or gages available from the sensor.
unsigned short m_num_channels
Number of channels available from the sensor.
vpColVector getPhyData() const
Definition: vpComedi.cpp:133
std::string getTorqueUnits() const
void close()
Definition: vpComedi.cpp:95