Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMocapVicon.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 Vicon device.
32 */
33
34#include <visp3/core/vpConfig.h>
35
36#ifdef VISP_HAVE_VICON
37
38#include <cmath>
39#include <iostream>
40
41#include <visp3/core/vpTime.h>
42#include <visp3/sensor/vpMocapVicon.h>
43
44#include <DataStreamClient.h>
45#include <IDataStreamClientBase.h>
46
47using namespace ViconDataStreamSDK::CPP;
48
50#ifndef DOXYGEN_SHOULD_SKIP_THIS
51class vpMocapVicon::vpMocapViconImpl
52{
53public:
54 vpMocapViconImpl() : m_DirectClient(), m_verbose(false), m_serverAddr() { }
55 virtual ~vpMocapViconImpl() { close(); }
56
57 void close()
58 {
59 m_DirectClient.DisableSegmentData();
60 m_DirectClient.DisableMarkerData();
61 m_DirectClient.DisableUnlabeledMarkerData();
62 m_DirectClient.DisableDeviceData();
63 if (m_verbose) {
64 std::cout << "Disconnecting..." << std::endl;
65 }
66 m_DirectClient.Disconnect();
67 }
68
69 bool connect()
70 {
71 int n_attempt = 2;
72 for (auto i = 0; i < n_attempt; i++) {
73 if (!m_DirectClient.IsConnected().Connected) {
74 // Direct connection
75
76 const Output_Connect ConnectResult = m_DirectClient.Connect(m_serverAddr);
77 const bool ok = (ConnectResult.Result == Result::Success);
78
79 if (!ok) {
80 if (m_verbose) {
81 std::cout << "Warning - connection failed... ";
82 switch (ConnectResult.Result) {
83 case Result::ClientAlreadyConnected:
84 std::cout << "Client Already Connected" << std::endl;
85 break;
86 case Result::InvalidHostName:
87 std::cout << "Invalid Host Name" << std::endl;
88 break;
89 case Result::ClientConnectionFailed:
90 std::cout << "Client Connection Failed" << std::endl;
91 break;
92 default:
93 std::cout << "Unrecognized Error: " << ConnectResult.Result << std::endl;
94 break;
95 }
96 }
97 vpTime::sleepMs(1000);
98 }
99 if (ok) {
100 if (m_verbose) {
101 std::cout << "Successful connection to : " << m_serverAddr << std::endl;
102 }
103 return setupDataStreamed();
104 }
105 }
106 }
107
108 if (m_verbose) {
109 std::cout << "Vicon connection timeout" << std::endl;
110 }
111 return false;
112 }
113
114 bool getBodiesPose(std::map<std::string, vpHomogeneousMatrix> &bodies_pose, bool all_bodies = false)
115 {
116 if (m_DirectClient.GetFrame().Result == Result::Success) {
117 for (unsigned int iBody = 0; iBody < m_DirectClient.GetSubjectCount().SubjectCount; iBody++) {
118 std::string bodyName = m_DirectClient.GetSubjectName(iBody).SubjectName;
119 std::string rootSegment = m_DirectClient.GetSubjectRootSegmentName(bodyName).SegmentName;
120 bool data_extraction_success = (m_DirectClient.GetSegmentGlobalRotationMatrix(bodyName, rootSegment).Result &&
121 m_DirectClient.GetSegmentGlobalTranslation(bodyName, rootSegment).Result);
122 vpHomogeneousMatrix bodyPose;
123
124 if (!data_extraction_success) {
125 std::cout << "Error : Could not get pose from body n°" << iBody << std::endl;
126
127 return false;
128 }
129 else {
130 bodyPose[0][3] = m_DirectClient.GetSegmentGlobalTranslation(bodyName, rootSegment).Translation[0] / 1000.0;
131 bodyPose[1][3] = m_DirectClient.GetSegmentGlobalTranslation(bodyName, rootSegment).Translation[1] / 1000.0;
132 bodyPose[2][3] = m_DirectClient.GetSegmentGlobalTranslation(bodyName, rootSegment).Translation[2] / 1000.0;
133 bodyPose[3][3] = 1.0;
134
135 // Vicon is row major
136 unsigned int k = 0;
137 for (unsigned int i = 0; i < 3; i++) {
138 for (unsigned int j = 0; j < 3; j++) {
139 bodyPose[i][j] = m_DirectClient.GetSegmentGlobalRotationMatrix(bodyName, rootSegment).Rotation[k++];
140 }
141 }
142 }
143 if (all_bodies) {
144 bodies_pose[bodyName] = bodyPose;
145 }
146 else if (bodyPose.isValid()) {
147 bodies_pose[bodyName] = bodyPose;
148 }
149 }
150 return true;
151 }
152 return false;
153 }
154
155 bool getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
156 {
157 std::map<std::string, vpHomogeneousMatrix> bodies_pose;
158 if (getBodiesPose(bodies_pose, true)) {
159 if (bodies_pose.find(body_name) != bodies_pose.end()) {
160 body_pose = bodies_pose[body_name];
161 return true;
162 }
163 else {
164 std::cout << "The body " << body_name << " was not found in Vicon. Please check the name you typed."
165 << std::endl;
166
167 return false;
168 }
169 }
170 else {
171 std::cout << "Error : could not process data from Vicon" << std::endl;
172
173 return false;
174 }
175 }
176
177 void setServerAddress(const std::string &serverAddr) { m_serverAddr = serverAddr; }
178
179 void setVerbose(bool verbose) { m_verbose = verbose; }
180
181 bool setupDataStreamed()
182 {
183 // We set up the kind of data we get.
184 m_DirectClient.EnableSegmentData();
185 m_DirectClient.EnableMarkerData();
186 m_DirectClient.EnableUnlabeledMarkerData();
187 m_DirectClient.EnableMarkerRayData();
188 m_DirectClient.EnableDeviceData();
189 m_DirectClient.EnableDebugData();
190 // We set up which kind of connectiion we want.
191 m_DirectClient.SetStreamMode(ViconDataStreamSDK::CPP::StreamMode::ServerPush);
192
193 // Set the global up axis
194 m_DirectClient.SetAxisMapping(Direction::Forward, Direction::Left,
195 Direction::Up); // Z-up
196
197 return true;
198 }
199
200private:
201 ViconDataStreamSDK::CPP::Client m_DirectClient;
202 bool m_verbose;
203 std::string m_serverAddr;
204};
205#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
206
207/*
208 **********************************************************************************************
209 */
210
214vpMocapVicon::vpMocapVicon() : m_impl(new vpMocapViconImpl()) { }
215
219vpMocapVicon::~vpMocapVicon() { delete m_impl; }
220
224void vpMocapVicon::close() { m_impl->close(); }
225
231bool vpMocapVicon::connect() { return m_impl->connect(); }
232
240bool vpMocapVicon::getBodiesPose(std::map<std::string, vpHomogeneousMatrix> &bodies_pose, bool all_bodies)
241{
242 return m_impl->getBodiesPose(bodies_pose, all_bodies);
243}
244
251bool vpMocapVicon::getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
252{
253 return m_impl->getSpecificBodyPose(body_name, body_pose);
254}
255
262void vpMocapVicon::setServerAddress(const std::string &serverAddr) { m_impl->setServerAddress(serverAddr); }
263
268void vpMocapVicon::setVerbose(bool verbose) { m_impl->setVerbose(verbose); }
269END_VISP_NAMESPACE
270#else
271// Work around to avoid warning:
272// libvisp_sensor.a(vpMocapVicon.cpp.o) has no symbols
273void dummy_vpMocapVicon() { }
274#endif
Implementation of an homogeneous matrix and operations on such kind of matrices.
bool getBodiesPose(std::map< std::string, vpHomogeneousMatrix > &bodies_pose, bool all_bodies=false)
void setVerbose(bool verbose)
virtual ~vpMocapVicon()
void setServerAddress(const std::string &serverAddr)
bool getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
VISP_EXPORT void sleepMs(double t)