Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMocapQualisys.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 * Motion capture using Qualisys device.
32 */
33
34#include <visp3/core/vpConfig.h>
35
36#ifdef VISP_HAVE_QUALISYS
37
38#include <cmath>
39#include <iostream>
40
41#include <visp3/core/vpTime.h>
42#include <visp3/sensor/vpMocapQualisys.h>
43
44#include <qualisys_cpp_sdk/RTPacket.h>
45#include <qualisys_cpp_sdk/RTProtocol.h>
46
48#ifndef DOXYGEN_SHOULD_SKIP_THIS
49class vpMocapQualisys::vpMocapQualisysImpl
50{
51public:
52 vpMocapQualisysImpl()
53 : m_rtProtocol(), m_basePort(22222), m_udpPort(6734), m_majorVersion(1), m_minorVersion(19), m_bigEndian(false),
54 m_dataAvailable(false), m_streamFrames(false), m_verbose(false), m_serverAddr()
55 { }
56
57 virtual ~vpMocapQualisysImpl() { close(); }
58
59 void close()
60 {
61 m_rtProtocol.StopCapture();
62 m_rtProtocol.Disconnect();
63 }
64
65 bool connect()
66 {
67 int n_attempt = 2;
68 for (auto i = 0; i < n_attempt; i++) {
69 if (!m_rtProtocol.Connected()) {
70 if (!m_rtProtocol.Connect(m_serverAddr.c_str(), m_basePort, &m_udpPort, m_majorVersion, m_minorVersion,
71 m_bigEndian)) {
72 std::cout << "Qualisys connection error: " << m_rtProtocol.GetErrorString() << std::endl;
73
74 vpTime::sleepMs(1000);
75 }
76 }
77 else {
78 if (m_verbose) {
79 std::cout << "Qualisys connected" << std::endl;
80 }
81 return verifyDataStreamed();
82 }
83 }
84
85 std::cout << "Qualisys connection timeout" << std::endl;
86
87 return false;
88 }
89
90 bool verifyDataStreamed()
91 {
92 bool readSettingsOK = false;
93
94 for (auto i = 0; i < 6; i++) {
95 if (!m_dataAvailable) {
96 if (!m_rtProtocol.Read6DOFSettings(m_dataAvailable)) {
97 if (m_verbose) {
98 std::cout << "Reading 6DOF settings error: " << m_rtProtocol.GetErrorString() << std::endl;
99 }
100
101 vpTime::sleepMs(1000);
102 }
103 }
104 else {
105 if (m_verbose && !readSettingsOK) {
106 std::cout << "Reading 6DOF settings succeded." << std::endl;
107 }
108 readSettingsOK = true;
109 }
110 }
111
112 if (!readSettingsOK) {
113 if (m_verbose) {
114 std::cout << "Reading 6DOF settings timeout: " << std::endl;
115 }
116 return false;
117 }
118 else {
119 for (auto i = 0; i < 6; i++) {
120 if (!m_streamFrames) {
121#if (VP_VERSION_INT(MAJOR_VERSION, MINOR_VERSION, 0) >= VP_VERSION_INT(1, 27, 0))
122 if (!m_rtProtocol.StreamFrames(CRTProtocol::EStreamRate::RateAllFrames, 0, m_udpPort, nullptr, CRTProtocol::cComponent6d))
123#else
124 if (!m_rtProtocol.StreamFrames(CRTProtocol::RateAllFrames, 0, m_udpPort, nullptr, CRTProtocol::cComponent6d))
125#endif
126 {
127 if (m_verbose) {
128 std::cout << "Streaming frames error: " << m_rtProtocol.GetErrorString() << std::endl;
129 }
130
131 vpTime::sleepMs(1000);
132 }
133 m_streamFrames = true;
134 }
135 else {
136 if (m_verbose) {
137 std::cout << "Starting to stream 6DOF data" << std::endl;
138 }
139 return true;
140 }
141 }
142
143 std::cout << "Streaming frames timeout: " << std::endl;
144
145 return false;
146 }
147 }
148
149 bool getBodyPose(int iBody, std::string &name, vpHomogeneousMatrix &M, CRTPacket *rtPacket)
150 {
151 float fX, fY, fZ;
152 float rotationMatrix[9];
153
154 if (rtPacket->Get6DOFBody(iBody, fX, fY, fZ, rotationMatrix)) {
155 const char *pTmpStr = m_rtProtocol.Get6DOFBodyName(iBody);
156 if (pTmpStr) {
157 name = std::string(pTmpStr);
158 }
159 else {
160 if (m_verbose) {
161 std::cout << "Unknown body" << std::endl;
162 }
163 return false;
164 }
165
166 M[0][3] = fX / 1000.;
167 M[1][3] = fY / 1000.;
168 M[2][3] = fZ / 1000.;
169 M[3][3] = 1.;
170 unsigned int k = 0;
171 for (unsigned int j = 0; j < 3; j++) {
172 for (unsigned int i = 0; i < 3; i++) {
173 M[i][j] = rotationMatrix[k++];
174 }
175 }
176
177 return true;
178 }
179 else {
180 return false;
181 }
182 }
183
184 bool getBodiesPose(std::map<std::string, vpHomogeneousMatrix> &bodies_pose, bool all_bodies)
185 {
186 CRTPacket::EPacketType packetType;
187
188 if (m_rtProtocol.Receive(packetType, true) == CNetwork::ResponseType::success) {
189 if (packetType == CRTPacket::PacketData) {
190 CRTPacket *rtPacket = m_rtProtocol.GetRTPacket();
191 for (unsigned int iBody = 0; iBody < rtPacket->Get6DOFBodyCount(); iBody++) {
192 std::string bodyName;
193
194 vpHomogeneousMatrix bodyPose;
195 if (!getBodyPose(iBody, bodyName, bodyPose, rtPacket)) {
196 std::cout << "Error : Could not get pose from body n°" << iBody << std::endl;
197
198 return false;
199 }
200 if (all_bodies) {
201 bodies_pose[bodyName] = bodyPose;
202 }
203 else if (bodyPose.isValid()) {
204 bodies_pose[bodyName] = bodyPose;
205 }
206 }
207 return true;
208 }
209 }
210 return false;
211 }
212
213 bool getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
214 {
215 std::map<std::string, vpHomogeneousMatrix> bodies_pose;
216 if (getBodiesPose(bodies_pose, true)) {
217 if (bodies_pose.find(body_name) != bodies_pose.end()) {
218 body_pose = bodies_pose[body_name];
219 if (m_verbose) {
220 std::cout << "I found bodyName" << body_name << std::endl;
221 }
222 return true;
223 }
224 else {
225 std::cout << "The body " << body_name << " was not found in Qualisys. Please check the name you typed."
226 << std::endl;
227
228 return false;
229 }
230 }
231 else {
232 std::cout << "Error : could not process data from Qualisys" << std::endl;
233
234 return false;
235 }
236 }
237
238 void setServerAddress(const std::string &serverAddr) { m_serverAddr = serverAddr; }
239
240 void setVerbose(bool verbose) { m_verbose = verbose; }
241
242private:
243 CRTProtocol m_rtProtocol;
244 unsigned short m_basePort;
245 unsigned short m_udpPort;
246 int m_majorVersion;
247 int m_minorVersion;
248 bool m_bigEndian;
249 bool m_dataAvailable;
250 bool m_streamFrames;
251 bool m_verbose;
252 std::string m_serverAddr;
253};
254#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
255
256/*
257 **********************************************************************************************
258 */
259
263vpMocapQualisys::vpMocapQualisys() : m_impl(new vpMocapQualisysImpl()) { }
264
269
273void vpMocapQualisys::close() { m_impl->close(); }
274
280bool vpMocapQualisys::connect() { return m_impl->connect(); }
281
289bool vpMocapQualisys::getBodiesPose(std::map<std::string, vpHomogeneousMatrix> &bodies_pose, bool all_bodies)
290{
291 return m_impl->getBodiesPose(bodies_pose, all_bodies);
292}
293
300bool vpMocapQualisys::getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
301{
302 return m_impl->getSpecificBodyPose(body_name, body_pose);
303}
304
310void vpMocapQualisys::setServerAddress(const std::string &serverAddr) { m_impl->setServerAddress(serverAddr); }
311
316void vpMocapQualisys::setVerbose(bool verbose) { m_impl->setVerbose(verbose); }
317END_VISP_NAMESPACE
318#else
319// Work around to avoid warning:
320// libvisp_sensor.a(vpMocapQualisys.cpp.o) has no symbols
321void dummy_vpMocapQualisys() { }
322#endif
Implementation of an homogeneous matrix and operations on such kind of matrices.
void setServerAddress(const std::string &serverAddr)
bool getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
void setVerbose(bool verbose)
bool getBodiesPose(std::map< std::string, vpHomogeneousMatrix > &bodies_pose, bool all_bodies=false)
VISP_EXPORT void sleepMs(double t)