Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpForceTorqueAtiNetFTSensor.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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 * ATI Force torque interface.
32 */
33
34#include <stdint.h>
35
36#include <visp3/core/vpConfig.h>
37#include <visp3/core/vpException.h>
38#include <visp3/core/vpTime.h>
39#include <visp3/sensor/vpForceTorqueAtiNetFTSensor.h>
40
41// Make vpForceTorqueAtiNetFTSensor available only if inet_ntop() used to
42// communicate by UDP with the sensor through vpUDPClient is available; inet_ntop()
43// is not supported on win XP
44#ifdef VISP_HAVE_FUNC_INET_NTOP
45
46#ifndef DOXYGEN_SHOULD_SKIP_THIS
47typedef struct response_struct
48{
49 uint32_t rdt_sequence;
50 uint32_t ft_sequence;
51 uint32_t status;
52 int32_t FTData[6];
53} RESPONSE;
54#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
55
67
74 : vpUDPClient(hostname, port), m_counts_per_force(1000000), m_counts_per_torque(1000000000), m_scaling_factor(1),
76{ }
77
83{
84 if (!m_is_init) {
85 throw(vpException(vpException::notInitialized, "Cannot start streaming: UDP client is not initialized"));
86 }
87
89 throw(vpException(vpException::notInitialized, "Streaming is already started"));
90 }
91
92 // Since UDP packet could be lost, retry startup 10 times before giving up
93 for (unsigned int i = 0; i < 10; ++i) {
94 int len = 8;
95 unsigned char request[8]; // The request data sent to the Net F/T
96 uint16_t val1 = htons(0x1234); // Standard header
97 uint16_t val2 = htons(0x0002); // Start high-speed streaming (see table 10.1 in Net F/T user manual)
98 uint32_t val3 = htons(0); // Infinite sample (see section 10.1 in Net F/T user manual
99 memcpy(&request[0], &val1, sizeof(val1));
100 memcpy(&request[2], &val2, sizeof(val2));
101 memcpy(&request[4], &val3, sizeof(val3));
102
103 // Send start stream
104 if (send(request, len) != len) {
105 throw(vpException(vpException::notInitialized, "UDP client is not initialized"));
106 }
107 std::cout << "wait: " << i << std::endl;
108
110 if (waitForNewData()) {
111 return true;
112 }
113 }
115 return false;
116}
117
122{
123 if (!m_is_init) {
124 throw(vpException(vpException::notInitialized, "Cannot stop streaming: UDP client is not initialized"));
125 }
126
128 throw(vpException(vpException::notInitialized, "Cannot stop streaming: streaming was not started"));
129 }
130
131 int len = 8;
132 unsigned char request[8]; // The request data sent to the Net F/T
133 uint16_t val1 = htons(0x1234); // Standard header
134 uint16_t val2 = htons(0x0002); // Start high-speed streaming (see table 10.1 in Net F/T user manual)
135 uint32_t val3 = htons(0); // Infinite sample (see section 10.1 in Net F/T user manual
136 memcpy(&request[0], &val1, sizeof(val1));
137 memcpy(&request[2], &val2, sizeof(val2));
138 memcpy(&request[4], &val3, sizeof(val3));
139
140 // Send start stream
141 if (send(request, len) != len) {
142 throw(vpException(vpException::notInitialized, "Cannot stop streaming"));
143 }
144
146}
147
159
167void vpForceTorqueAtiNetFTSensor::bias(unsigned int n_counts)
168{
169 if (!m_is_init) {
170 throw(vpException(vpException::notInitialized, "Cannot bias: UDP client is not initialized"));
171 }
172
174 throw(vpException(vpException::notInitialized, "Cannot bias: streaming was not started"));
175 }
176
177 vpColVector ft_bias_tmp(6, 0);
178 m_ft_bias = 0;
179
180 if (n_counts == 0) {
182 }
183 else {
184 for (unsigned int i = 0; i < n_counts; i++) {
185 ft_bias_tmp += getForceTorque();
187 }
188 m_ft_bias = ft_bias_tmp / n_counts;
189 }
190}
191
198
210{
211 if (!m_is_init) {
212 throw(vpException(vpException::notInitialized, "Cannot get F/T: UDP client is not initialized"));
213 }
214
216 throw(vpException(vpException::notInitialized, "Cannot get F/T: streaming was not started"));
217 }
218
220 throw(vpException(vpException::notInitialized, "Cannot get F/T: no new data available"));
221 }
222
223 return m_ft;
224}
225
232{
233 if (!m_is_init) {
234 throw(vpException(vpException::notInitialized, "Cannot wait for new data: UDP client is not initialized"));
235 }
236
238 throw(vpException(vpException::notInitialized, "Cannot wait for new data: streaming was not started"));
239 }
240
241 double t = vpTime::measureTimeMs();
243 while (vpTime::measureTimeMs() - t < static_cast<double>(timeout)) {
244 unsigned char response[36];
245 RESPONSE resp;
246 if (receive((void *)response, 36)) {
247 uint32_t resp1, resp2, resp3;
248 memcpy(&resp1, &response[0], sizeof(uint32_t));
249 memcpy(&resp2, &response[4], sizeof(uint32_t));
250 memcpy(&resp3, &response[8], sizeof(uint32_t));
251 resp.rdt_sequence = ntohl(resp1);
252 resp.ft_sequence = ntohl(resp2);
253 resp.status = ntohl(resp3);
254
255 for (int i = 0; i < 6; i++) {
256 int32_t resp4;
257 memcpy(&resp4, &response[12 + i * 4], sizeof(int32_t));
258 resp.FTData[i] = ntohl(resp4);
259 }
260 // Output the response data.
261 if (resp.status) {
262 throw(vpException(vpException::notInitialized, "Cannot wait for new data: status 0x%08x is not 0x00000000",
263 resp.status));
264 }
265 double force_factor = static_cast<double>(m_scaling_factor) / static_cast<double>(m_counts_per_force);
266 double torque_factor = static_cast<double>(m_scaling_factor) / static_cast<double>(m_counts_per_torque);
267 for (int i = 0; i < 3; i++) {
268 m_ft[i] = resp.FTData[i] * force_factor;
269 }
270 for (int i = 3; i < 6; i++) {
271 m_ft[i] = resp.FTData[i] * torque_factor;
272 }
273 // Consider bias
274 m_ft -= m_ft_bias;
275
276 m_data_count++;
277 }
278
280 return true;
281 }
283 }
284
285 return false;
286}
287END_VISP_NAMESPACE
288#endif
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition vpException.h:74
void bias(unsigned int n_counts=50)
bool waitForNewData(unsigned int timeout=50)
int receive(std::string &msg, int timeoutMs=0)
int send(const std::string &msg)
VISP_EXPORT double measureTimeMs()
VISP_EXPORT void sleepMs(double t)