Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
testMocapVicon.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 Vicon Motion Capture System.
32  */
33 
38 #include <visp3/sensor/vpMocapVicon.h>
39 
40 #include <iostream>
41 
42 #if defined(VISP_HAVE_VICON) && defined(VISP_HAVE_THREADS)
43 
44 #include <mutex>
45 #include <signal.h>
46 #include <thread>
47 
48 #include <visp3/sensor/vpMocapVicon.h>
49 
50 #include <visp3/core/vpTime.h>
51 
52 #ifdef ENABLE_VISP_NAMESPACE
53 using namespace VISP_NAMESPACE_NAME;
54 #endif
55 
56 bool g_quit = false;
57 
62 void quitHandler(int sig)
63 {
64  std::cout << std::endl << "TERMINATING AT USER REQUEST" << std::endl << std::endl;
65 
66  g_quit = true;
67  (void)sig;
68 }
69 
70 void usage(const char *argv[], int error)
71 {
72  std::cout << "SYNOPSIS" << std::endl
73  << " " << argv[0] << " [--server-address <address>]"
74  << " [--only-body]"
75  << " [--all-bodies]"
76  << " [--verbose] [-v]"
77  << " [--help] [-h]" << std::endl
78  << std::endl;
79  std::cout << "DESCRIPTION" << std::endl
80  << " --server-address <address>" << std::endl
81  << " Server address." << std::endl
82  << " Default: 192.168.30.1." << std::endl
83  << std::endl
84  << " --only-body <name>" << std::endl
85  << " Name of the specific body you want to be displayed." << std::endl
86  << " Default: ''" << std::endl
87  << std::endl
88  << " --all-bodies" << std::endl
89  << " When used, get all bodies pose including non visible bodies." << std::endl
90  << std::endl
91  << " --verbose, -v" << std::endl
92  << " Enable verbose mode." << std::endl
93  << std::endl
94  << " --help, -h" << std::endl
95  << " Print this helper message." << std::endl
96  << std::endl;
97  std::cout << "USAGE" << std::endl
98  << " Example to test Vicon connection:" << std::endl
99  << " " << argv[0] << " --server-address 127.0.0.1 --verbose" << std::endl
100  << std::endl;
101 
102  if (error) {
103  std::cout << "Error" << std::endl
104  << " "
105  << "Unsupported parameter " << argv[error] << std::endl;
106  }
107 }
108 
109 void mocap_loop(std::mutex &lock, bool opt_verbose, bool opt_all_bodies, std::string &opt_serverAddress,
110  std::string &opt_onlyBody, std::map<std::string, vpHomogeneousMatrix> &current_bodies_pose)
111 {
112  vpMocapVicon vicon;
113  vicon.setVerbose(opt_verbose);
114  vicon.setServerAddress(opt_serverAddress);
115  vicon.connect();
116  while (!g_quit) {
117  std::map<std::string, vpHomogeneousMatrix> bodies_pose;
118 
119  if (opt_onlyBody == "") {
120  vicon.getBodiesPose(bodies_pose, opt_all_bodies);
121  }
122  else {
123  vpHomogeneousMatrix pose;
124  vicon.getSpecificBodyPose(opt_onlyBody, pose);
125  bodies_pose[opt_onlyBody] = pose;
126  }
127 
128  lock.lock();
129  current_bodies_pose = bodies_pose;
130  lock.unlock();
131 
132  vpTime::sleepMs(5);
133  }
134 }
135 
136 void display_loop(std::mutex &lock, const std::map<std::string, vpHomogeneousMatrix> &current_bodies_pose, bool verbose)
137 {
138  std::map<std::string, vpHomogeneousMatrix> bodies_pose;
139 
140  while (!g_quit) {
141 
142  lock.lock();
143  bodies_pose = current_bodies_pose;
144  lock.unlock();
145  for (std::map<std::string, vpHomogeneousMatrix>::iterator it = bodies_pose.begin(); it != bodies_pose.end(); ++it) {
146  vpRxyzVector rxyz(it->second.getRotationMatrix());
147  std::cout << "Found body: " << it->first << std::endl;
148  if (verbose) {
149  std::cout << " Translation [m]: " << it->second.getTranslationVector().t() << std::endl
150  << " Quaternion: " << vpQuaternionVector(it->second.getRotationMatrix()).t() << std::endl;
151  std::cout << " Roll/pitch/yaw [deg]: ";
152  for (unsigned int i = 0; i < 3; i++) {
153  std::cout << vpMath::deg(rxyz[i]) << " ";
154  }
155  std::cout << std::endl;
156  }
157  }
158 
159  vpTime::sleepMs(200);
160  }
161 }
162 
163 int main(int argc, const char *argv[])
164 {
165  bool opt_verbose = false;
166  std::string opt_serverAddress = "192.168.30.1";
167  std::string opt_onlyBody = "";
168  bool opt_all_bodies = false;
169 
170  // Map containig all the current poses of the drones
171  std::map<std::string, vpHomogeneousMatrix> current_bodies_pose;
172 
173  signal(SIGINT, quitHandler);
174 
175  for (int i = 1; i < argc; i++) {
176  if (std::string(argv[i]) == "--verbose" || std::string(argv[i]) == "-v") {
177  opt_verbose = true;
178  }
179  else if (std::string(argv[i]) == "--server-address") {
180  opt_serverAddress = std::string(argv[i + 1]);
181  i++;
182  }
183  else if (std::string(argv[i]) == "--only-body") {
184  opt_onlyBody = std::string(argv[i + 1]);
185  i++;
186  }
187  else if (std::string(argv[i]) == "--all-bodies") {
188  opt_all_bodies = true;
189  }
190  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
191  usage(argv, 0);
192  return EXIT_SUCCESS;
193  }
194  else {
195  usage(argv, i);
196  return EXIT_FAILURE;
197  }
198  }
199 
200  std::mutex lock;
201  std::thread mocap_thread(
202  [&lock, &opt_verbose, &opt_all_bodies, &opt_serverAddress, &opt_onlyBody, &current_bodies_pose]() {
203  mocap_loop(lock, opt_verbose, opt_all_bodies, opt_serverAddress, opt_onlyBody, current_bodies_pose);
204  });
205  std::thread display_thread(
206  [&lock, &current_bodies_pose, &opt_verbose]() { display_loop(lock, current_bodies_pose, opt_verbose); });
207 
208  mocap_thread.join();
209  display_thread.join();
210 
211  return EXIT_SUCCESS;
212 }
213 #else
214 int main()
215 {
216  std::cout << "Install Vicon Datastream SDK to be able to test Vicon Mocap System using ViSP" << std::endl;
217 
218  return EXIT_SUCCESS;
219 }
220 #endif
Implementation of an homogeneous matrix and operations on such kind of matrices.
static double deg(double rad)
Definition: vpMath.h:119
bool getBodiesPose(std::map< std::string, vpHomogeneousMatrix > &bodies_pose, bool all_bodies=false)
void setVerbose(bool verbose)
void setServerAddress(const std::string &serverAddr)
bool getSpecificBodyPose(const std::string &body_name, vpHomogeneousMatrix &body_pose)
Implementation of a rotation vector as quaternion angle minimal representation.
vpRowVector t() const
Implementation of a rotation vector as Euler angle minimal representation.
Definition: vpRxyzVector.h:183
VISP_EXPORT void sleepMs(double t)