Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
testRobotFlirPtu.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 FLIR PTU interface.
32  */
33 
40 #include <iostream>
41 
42 #include <visp3/core/vpConfig.h>
43 
44 #ifdef VISP_HAVE_FLIR_PTU_SDK
45 
46 #include <visp3/robot/vpRobotFlirPtu.h>
47 
48 int main(int argc, char **argv)
49 {
50 #ifdef ENABLE_VISP_NAMESPACE
51  using namespace VISP_NAMESPACE_NAME;
52 #endif
53  std::string opt_portname;
54  int opt_baudrate = 9600;
55  bool opt_network = false;
56  bool opt_reset = false;
57 
58  if (argc == 1) {
59  std::cout << "To see how to use this test, run: " << argv[0] << " --help" << std::endl;
60  return EXIT_SUCCESS;
61  }
62 
63  for (int i = 1; i < argc; i++) {
64  if ((std::string(argv[i]) == "--portname" || std::string(argv[i]) == "-p") && (i + 1 < argc)) {
65  opt_portname = std::string(argv[i + 1]);
66  }
67  else if ((std::string(argv[i]) == "--baudrate" || std::string(argv[i]) == "-b") && (i + 1 < argc)) {
68  opt_baudrate = std::atoi(argv[i + 1]);
69  }
70  else if ((std::string(argv[i]) == "--network" || std::string(argv[i]) == "-n")) {
71  opt_network = true;
72  }
73  else if ((std::string(argv[i]) == "--reset" || std::string(argv[i]) == "-r")) {
74  opt_reset = true;
75  }
76  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
77  std::cout << "SYNOPSIS" << std::endl
78  << " " << argv[0] << " [--portname <portname>] [--baudrate <rate>] [--network] [--reset] [--help] [-h]"
79  << std::endl
80  << std::endl
81  << "DESCRIPTION" << std::endl
82  << " --portname, -p <portname>" << std::endl
83  << " Set serial or tcp port name." << std::endl
84  << std::endl
85  << " --baudrate, -b <rate>" << std::endl
86  << " Set serial communication baud rate. Default: " << opt_baudrate << "." << std::endl
87  << std::endl
88  << " --network, -n" << std::endl
89  << " Get PTU network information (Hostname, IP, Gateway) and exit. " << std::endl
90  << std::endl
91  << " --reset, -r" << std::endl
92  << " Reset PTU axis and exit. " << std::endl
93  << std::endl
94  << " --help, -h" << std::endl
95  << " Print this helper message. " << std::endl
96  << std::endl
97  << "EXAMPLE" << std::endl
98  << " - How to get network IP" << std::endl
99 #ifdef _WIN32
100  << " $ " << argv[0] << " -p /dev/ttyUSB0 --network" << std::endl
101 #else
102  << " $ " << argv[0] << " --portname COM1 --network" << std::endl
103 #endif
104  << " Try to connect FLIR PTU to port: /dev/ttyUSB0 with baudrate: 9600" << std::endl
105  << " PTU HostName: PTU-5" << std::endl
106  << " PTU IP : 169.254.110.254" << std::endl
107  << " PTU Gateway : 0.0.0.0" << std::endl
108  << " - How to run this binary using serial communication" << std::endl
109 #ifdef _WIN32
110  << " $ " << argv[0] << " --portname COM1" << std::endl
111 #else
112  << " $ " << argv[0] << " --portname /dev/ttyUSB0" << std::endl
113 #endif
114  << " - How to run this binary using network communication" << std::endl
115  << " $ " << argv[0] << " --portname tcp:169.254.110.254" << std::endl;
116 
117  return EXIT_SUCCESS;
118  }
119  }
120 
121  if (opt_portname.empty()) {
122  std::cout << "Error, portname unspecified. Run " << argv[0] << " --help" << std::endl;
123  return EXIT_SUCCESS;
124  }
125 
126  vpRobotFlirPtu robot;
127 
128  try {
129  vpColVector q(2), q_mes;
130  int answer;
131 
132  std::cout << "Try to connect FLIR PTU to port: " << opt_portname << " with baudrate: " << opt_baudrate << std::endl;
133  robot.connect(opt_portname, opt_baudrate);
134 
135  if (opt_network) {
136  std::cout << "PTU HostName: " << robot.getNetworkHostName() << std::endl;
137  std::cout << "PTU IP : " << robot.getNetworkIP() << std::endl;
138  std::cout << "PTU Gateway : " << robot.getNetworkGateway() << std::endl;
139  return EXIT_SUCCESS;
140  }
141 
142  if (opt_reset) {
143  std::cout << "Reset PTU axis" << std::endl;
144  robot.reset();
145  return EXIT_SUCCESS;
146  }
147 
148  {
149  std::cout << "** Test limits getter" << std::endl;
150 
151  std::cout << "Pan pos min/max [deg]: " << vpMath::deg(robot.getPanPosLimits()[0]) << " "
152  << vpMath::deg(robot.getPanPosLimits()[1]) << std::endl;
153  std::cout << "Tilt pos min/max [deg]: " << vpMath::deg(robot.getTiltPosLimits()[0]) << " "
154  << vpMath::deg(robot.getTiltPosLimits()[1]) << std::endl;
155  std::cout << "Pan/tilt vel max [deg/s]: " << vpMath::deg(robot.getPanTiltVelMax()[0]) << " "
156  << vpMath::deg(robot.getPanTiltVelMax()[1]) << std::endl
157  << std::endl;
158  }
159 
160  {
161  std::cout << "** Test limits setter" << std::endl;
162  // Reduce pan/tilt position limits wrt factory settings
163  vpColVector pan_pos_limits(2), tilt_pos_limits(2);
164  pan_pos_limits[0] = vpMath::rad(-90);
165  pan_pos_limits[1] = vpMath::rad(90);
166  tilt_pos_limits[0] = vpMath::rad(-20);
167  tilt_pos_limits[1] = vpMath::rad(20);
168 
169  robot.setPanPosLimits(pan_pos_limits);
170  robot.setTiltPosLimits(tilt_pos_limits);
171 
172  std::cout << "Modified user min/max limits: " << std::endl;
173  std::cout << "Pan pos min/max [deg]: " << vpMath::deg(robot.getPanPosLimits()[0]) << " "
174  << vpMath::deg(robot.getPanPosLimits()[1]) << std::endl;
175  std::cout << "Tilt pos min/max [deg]: " << vpMath::deg(robot.getTiltPosLimits()[0]) << " "
176  << vpMath::deg(robot.getTiltPosLimits()[1]) << std::endl;
177  std::cout << "Pan/tilt vel max [deg/s]: " << vpMath::deg(robot.getPanTiltVelMax()[0]) << " "
178  << vpMath::deg(robot.getPanTiltVelMax()[1]) << std::endl
179  << std::endl;
180  }
181 
182  {
183  std::cout << "** Test position getter" << std::endl;
184  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
185  std::cout << "Current position [deg]: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << std::endl;
186 
187  std::cout << "Initialisation done." << std::endl << std::endl;
188  }
189 
190  {
191  std::cout << "** Test joint positioning" << std::endl;
193  robot.setMaxRotationVelocity(std::min<double>(robot.getPanTiltVelMax()[0], robot.getPanTiltVelMax()[1]) /
194  2.); // 50% of the slowest axis
195 
196  q = 0;
197  std::cout << "Set joint position [deg]: " << vpMath::deg(q[0]) << " " << vpMath::deg(q[1]) << std::endl;
198  std::cout << "Enter a caracter to apply" << std::endl;
199  scanf("%d", &answer);
200 
201  robot.setPositioningVelocity(50);
202  robot.setPosition(vpRobot::JOINT_STATE, q);
203  robot.getPosition(vpRobot::JOINT_STATE, q_mes);
204 
205  std::cout << "Position reached [deg]: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << std::endl
206  << std::endl;
207  }
208 
209  {
210  std::cout << "** Test joint positioning" << std::endl;
211  q[0] = vpMath::rad(10); // Pan position in rad
212  q[1] = vpMath::rad(20); // Tilt position in rad
213 
214  std::cout << "Set joint position: " << vpMath::deg(q[0]) << " " << vpMath::deg(q[1]) << "[deg]" << std::endl;
215  std::cout << "Enter a caracter to apply" << std::endl;
216  scanf("%d", &answer);
217 
218  robot.setPosition(vpRobot::ARTICULAR_FRAME, q);
219  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
220 
221  std::cout << "Position reached [deg]: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << std::endl
222  << std::endl;
223  }
224 
225  {
226  std::cout << "** Test joint velocity" << std::endl;
227 
228  vpColVector qdot(2);
229  qdot[0] = vpMath::rad(-10); // Pan velocity in rad/s
230  qdot[1] = vpMath::rad(0); // Tilt velocity in rad/s
231 
232  std::cout << "Set velocity for 4s: " << vpMath::deg(qdot[0]) << " " << vpMath::deg(qdot[1]) << " [deg/s]"
233  << std::endl;
234  std::cout << "Enter a caracter to apply" << std::endl;
235  scanf("%d", &answer);
236 
238 
239  double t_start = vpTime::measureTimeMs();
240  do {
241  robot.setVelocity(vpRobot::JOINT_STATE, qdot);
242  vpTime::sleepMs(40);
243  } while (vpTime::measureTimeMs() - t_start < 4000);
244 
246  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
247  std::cout << "Position reached: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << " [deg]"
248  << std::endl
249  << std::endl;
250  }
251 
252  {
253  std::cout << "** Test cartesian velocity with robot Jacobien eJe" << std::endl;
254 
255  vpColVector v_e(6, 0);
256  v_e[4] = vpMath::rad(5); // wy_e
257  v_e[5] = vpMath::rad(5); // wz_e
258 
259  std::cout << "Set cartesian velocity in end-effector frame for 4s: " << v_e[0] << " " << v_e[1] << " " << v_e[2]
260  << " [m/s] " << vpMath::deg(v_e[3]) << " " << vpMath::deg(v_e[4]) << " " << vpMath::deg(v_e[5])
261  << " [deg/s]" << std::endl;
262  std::cout << "Enter a caracter to apply" << std::endl;
263  scanf("%d", &answer);
264 
266 
267  double t_start = vpTime::measureTimeMs();
268  do {
269  vpColVector qdot = robot.get_eJe().pseudoInverse() * v_e;
270  robot.setVelocity(vpRobot::JOINT_STATE, qdot);
271  vpTime::sleepMs(40);
272  } while (vpTime::measureTimeMs() - t_start < 4000);
273 
275  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
276  std::cout << "Position reached: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << " [deg]"
277  << std::endl
278  << std::endl;
279  }
280 
281  std::cout << "** The end" << std::endl;
282  }
283  catch (const vpRobotException &e) {
284  std::cout << "Catch Flir Ptu signal exception: " << e.getMessage() << std::endl;
286  }
287  catch (const vpException &e) {
288  std::cout << "Catch Flir Ptu exception: " << e.getMessage() << std::endl;
290  }
291  return EXIT_SUCCESS;
292 }
293 #else
294 int main()
295 {
296  std::cout << "You do not have an Flir Ptu robot connected to your computer..." << std::endl;
297  return EXIT_SUCCESS;
298 }
299 
300 #endif
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
const char * getMessage() const
Definition: vpException.cpp:65
static double rad(double deg)
Definition: vpMath.h:129
static double deg(double rad)
Definition: vpMath.h:119
Error that can be emitted by the vpRobot class and its derivatives.
void get_eJe(vpMatrix &eJe) VP_OVERRIDE
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &vel) VP_OVERRIDE
@ ARTICULAR_FRAME
Definition: vpRobot.h:80
@ JOINT_STATE
Definition: vpRobot.h:82
@ STATE_POSITION_CONTROL
Initialize the position controller.
Definition: vpRobot.h:68
@ STATE_VELOCITY_CONTROL
Initialize the velocity controller.
Definition: vpRobot.h:67
@ STATE_STOP
Stops robot motion especially in velocity and acceleration control.
Definition: vpRobot.h:66
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:202
void setMaxRotationVelocity(double maxVr)
Definition: vpRobot.cpp:261
VISP_EXPORT void sleepMs(double t)
VISP_EXPORT double measureTimeMs()