Visual Servoing Platform  version 3.6.1 under development (2024-04-19)
testRobotFlirPtu.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See https://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Test FLIR PTU interface.
33  *
34 *****************************************************************************/
35 
42 #include <iostream>
43 
44 #include <visp3/core/vpConfig.h>
45 
46 #ifdef VISP_HAVE_FLIR_PTU_SDK
47 
48 #include <visp3/robot/vpRobotFlirPtu.h>
49 
50 int main(int argc, char **argv)
51 {
52  std::string opt_portname;
53  int opt_baudrate = 9600;
54  bool opt_network = false;
55  bool opt_reset = false;
56 
57  if (argc == 1) {
58  std::cout << "To see how to use this test, run: " << argv[0] << " --help" << std::endl;
59  return EXIT_SUCCESS;
60  }
61 
62  for (int i = 1; i < argc; i++) {
63  if ((std::string(argv[i]) == "--portname" || std::string(argv[i]) == "-p") && (i + 1 < argc)) {
64  opt_portname = std::string(argv[i + 1]);
65  }
66  else if ((std::string(argv[i]) == "--baudrate" || std::string(argv[i]) == "-b") && (i + 1 < argc)) {
67  opt_baudrate = std::atoi(argv[i + 1]);
68  }
69  else if ((std::string(argv[i]) == "--network" || std::string(argv[i]) == "-n")) {
70  opt_network = true;
71  }
72  else if ((std::string(argv[i]) == "--reset" || std::string(argv[i]) == "-r")) {
73  opt_reset = true;
74  }
75  else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
76  std::cout << "SYNOPSIS" << std::endl
77  << " " << argv[0] << " [--portname <portname>] [--baudrate <rate>] [--network] [--reset] [--help] [-h]"
78  << std::endl
79  << std::endl
80  << "DESCRIPTION" << std::endl
81  << " --portname, -p <portname>" << std::endl
82  << " Set serial or tcp port name." << std::endl
83  << std::endl
84  << " --baudrate, -b <rate>" << std::endl
85  << " Set serial communication baud rate. Default: " << opt_baudrate << "." << std::endl
86  << std::endl
87  << " --network, -n" << std::endl
88  << " Get PTU network information (Hostname, IP, Gateway) and exit. " << std::endl
89  << std::endl
90  << " --reset, -r" << std::endl
91  << " Reset PTU axis and exit. " << std::endl
92  << std::endl
93  << " --help, -h" << std::endl
94  << " Print this helper message. " << std::endl
95  << std::endl
96  << "EXAMPLE" << std::endl
97  << " - How to get network IP" << std::endl
98 #ifdef _WIN32
99  << " $ " << argv[0] << " -p /dev/ttyUSB0 --network" << std::endl
100 #else
101  << " $ " << argv[0] << " --portname COM1 --network" << std::endl
102 #endif
103  << " Try to connect FLIR PTU to port: /dev/ttyUSB0 with baudrate: 9600" << std::endl
104  << " PTU HostName: PTU-5" << std::endl
105  << " PTU IP : 169.254.110.254" << std::endl
106  << " PTU Gateway : 0.0.0.0" << std::endl
107  << " - How to run this binary using serial communication" << std::endl
108 #ifdef _WIN32
109  << " $ " << argv[0] << " --portname COM1" << std::endl
110 #else
111  << " $ " << argv[0] << " --portname /dev/ttyUSB0" << std::endl
112 #endif
113  << " - How to run this binary using network communication" << std::endl
114  << " $ " << argv[0] << " --portname tcp:169.254.110.254" << std::endl;
115 
116  return EXIT_SUCCESS;
117  }
118  }
119 
120  if (opt_portname.empty()) {
121  std::cout << "Error, portname unspecified. Run " << argv[0] << " --help" << std::endl;
122  return EXIT_SUCCESS;
123  }
124 
125  vpRobotFlirPtu robot;
126 
127  try {
128  vpColVector q(2), q_mes;
129  int answer;
130 
131  std::cout << "Try to connect FLIR PTU to port: " << opt_portname << " with baudrate: " << opt_baudrate << std::endl;
132  robot.connect(opt_portname, opt_baudrate);
133 
134  if (opt_network) {
135  std::cout << "PTU HostName: " << robot.getNetworkHostName() << std::endl;
136  std::cout << "PTU IP : " << robot.getNetworkIP() << std::endl;
137  std::cout << "PTU Gateway : " << robot.getNetworkGateway() << std::endl;
138  return EXIT_SUCCESS;
139  }
140 
141  if (opt_reset) {
142  std::cout << "Reset PTU axis" << std::endl;
143  robot.reset();
144  return EXIT_SUCCESS;
145  }
146 
147  {
148  std::cout << "** Test limits getter" << std::endl;
149 
150  std::cout << "Pan pos min/max [deg]: " << vpMath::deg(robot.getPanPosLimits()[0]) << " "
151  << vpMath::deg(robot.getPanPosLimits()[1]) << std::endl;
152  std::cout << "Tilt pos min/max [deg]: " << vpMath::deg(robot.getTiltPosLimits()[0]) << " "
153  << vpMath::deg(robot.getTiltPosLimits()[1]) << std::endl;
154  std::cout << "Pan/tilt vel max [deg/s]: " << vpMath::deg(robot.getPanTiltVelMax()[0]) << " "
155  << vpMath::deg(robot.getPanTiltVelMax()[1]) << std::endl
156  << std::endl;
157  }
158 
159  {
160  std::cout << "** Test limits setter" << std::endl;
161  // Reduce pan/tilt position limits wrt factory settings
162  vpColVector pan_pos_limits(2), tilt_pos_limits(2);
163  pan_pos_limits[0] = vpMath::rad(-90);
164  pan_pos_limits[1] = vpMath::rad(90);
165  tilt_pos_limits[0] = vpMath::rad(-20);
166  tilt_pos_limits[1] = vpMath::rad(20);
167 
168  robot.setPanPosLimits(pan_pos_limits);
169  robot.setTiltPosLimits(tilt_pos_limits);
170 
171  std::cout << "Modified user min/max limits: " << std::endl;
172  std::cout << "Pan pos min/max [deg]: " << vpMath::deg(robot.getPanPosLimits()[0]) << " "
173  << vpMath::deg(robot.getPanPosLimits()[1]) << std::endl;
174  std::cout << "Tilt pos min/max [deg]: " << vpMath::deg(robot.getTiltPosLimits()[0]) << " "
175  << vpMath::deg(robot.getTiltPosLimits()[1]) << std::endl;
176  std::cout << "Pan/tilt vel max [deg/s]: " << vpMath::deg(robot.getPanTiltVelMax()[0]) << " "
177  << vpMath::deg(robot.getPanTiltVelMax()[1]) << std::endl
178  << std::endl;
179  }
180 
181  {
182  std::cout << "** Test position getter" << std::endl;
183  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
184  std::cout << "Current position [deg]: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << std::endl;
185 
186  std::cout << "Initialisation done." << std::endl << std::endl;
187  }
188 
189  {
190  std::cout << "** Test joint positioning" << std::endl;
192  robot.setMaxRotationVelocity(std::min<double>(robot.getPanTiltVelMax()[0], robot.getPanTiltVelMax()[1]) /
193  2.); // 50% of the slowest axis
194 
195  q = 0;
196  std::cout << "Set joint position [deg]: " << vpMath::deg(q[0]) << " " << vpMath::deg(q[1]) << std::endl;
197  std::cout << "Enter a caracter to apply" << std::endl;
198  scanf("%d", &answer);
199 
200  robot.setPositioningVelocity(50);
201  robot.setPosition(vpRobot::JOINT_STATE, q);
202  robot.getPosition(vpRobot::JOINT_STATE, q_mes);
203 
204  std::cout << "Position reached [deg]: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << std::endl
205  << std::endl;
206  }
207 
208  {
209  std::cout << "** Test joint positioning" << std::endl;
210  q[0] = vpMath::rad(10); // Pan position in rad
211  q[1] = vpMath::rad(20); // Tilt position in rad
212 
213  std::cout << "Set joint position: " << vpMath::deg(q[0]) << " " << vpMath::deg(q[1]) << "[deg]" << std::endl;
214  std::cout << "Enter a caracter to apply" << std::endl;
215  scanf("%d", &answer);
216 
217  robot.setPosition(vpRobot::ARTICULAR_FRAME, q);
218  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
219 
220  std::cout << "Position reached [deg]: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << std::endl
221  << std::endl;
222  }
223 
224  {
225  std::cout << "** Test joint velocity" << std::endl;
226 
227  vpColVector qdot(2);
228  qdot[0] = vpMath::rad(-10); // Pan velocity in rad/s
229  qdot[1] = vpMath::rad(0); // Tilt velocity in rad/s
230 
231  std::cout << "Set velocity for 4s: " << vpMath::deg(qdot[0]) << " " << vpMath::deg(qdot[1]) << " [deg/s]"
232  << std::endl;
233  std::cout << "Enter a caracter to apply" << std::endl;
234  scanf("%d", &answer);
235 
237 
238  double t_start = vpTime::measureTimeMs();
239  do {
240  robot.setVelocity(vpRobot::JOINT_STATE, qdot);
241  vpTime::sleepMs(40);
242  } while (vpTime::measureTimeMs() - t_start < 4000);
243 
245  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
246  std::cout << "Position reached: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << " [deg]"
247  << std::endl
248  << std::endl;
249  }
250 
251  {
252  std::cout << "** Test cartesian velocity with robot Jacobien eJe" << std::endl;
253 
254  vpColVector v_e(6, 0);
255  v_e[4] = vpMath::rad(5); // wy_e
256  v_e[5] = vpMath::rad(5); // wz_e
257 
258  std::cout << "Set cartesian velocity in end-effector frame for 4s: " << v_e[0] << " " << v_e[1] << " " << v_e[2]
259  << " [m/s] " << vpMath::deg(v_e[3]) << " " << vpMath::deg(v_e[4]) << " " << vpMath::deg(v_e[5])
260  << " [deg/s]" << std::endl;
261  std::cout << "Enter a caracter to apply" << std::endl;
262  scanf("%d", &answer);
263 
265 
266  double t_start = vpTime::measureTimeMs();
267  do {
268  vpColVector qdot = robot.get_eJe().pseudoInverse() * v_e;
269  robot.setVelocity(vpRobot::JOINT_STATE, qdot);
270  vpTime::sleepMs(40);
271  } while (vpTime::measureTimeMs() - t_start < 4000);
272 
274  robot.getPosition(vpRobot::ARTICULAR_FRAME, q_mes);
275  std::cout << "Position reached: " << vpMath::deg(q_mes[0]) << " " << vpMath::deg(q_mes[1]) << " [deg]"
276  << std::endl
277  << std::endl;
278  }
279 
280  std::cout << "** The end" << std::endl;
281  }
282  catch (const vpRobotException &e) {
283  std::cout << "Catch Flir Ptu signal exception: " << e.getMessage() << std::endl;
285  }
286  catch (const vpException &e) {
287  std::cout << "Catch Flir Ptu exception: " << e.getMessage() << std::endl;
289  }
290  return EXIT_SUCCESS;
291 }
292 #else
293 int main()
294 {
295  std::cout << "You do not have an Flir Ptu robot connected to your computer..." << std::endl;
296  return EXIT_SUCCESS;
297 }
298 
299 #endif
Implementation of column vector and the associated operations.
Definition: vpColVector.h:163
error that can be emitted by ViSP classes.
Definition: vpException.h:59
const char * getMessage() const
Definition: vpException.cpp:64
static double rad(double deg)
Definition: vpMath.h:127
static double deg(double rad)
Definition: vpMath.h:117
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:78
@ JOINT_STATE
Definition: vpRobot.h:80
@ STATE_POSITION_CONTROL
Initialize the position controller.
Definition: vpRobot.h:66
@ STATE_VELOCITY_CONTROL
Initialize the velocity controller.
Definition: vpRobot.h:65
@ STATE_STOP
Stops robot motion especially in velocity and acceleration control.
Definition: vpRobot.h:64
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
Definition: vpRobot.cpp:198
void setMaxRotationVelocity(double maxVr)
Definition: vpRobot.cpp:257
VISP_EXPORT void sleepMs(double t)
VISP_EXPORT double measureTimeMs()