Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
servoSimuFourPoints2DCamVelocityDisplay.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 * Simulation of a 2D visual servoing using 4 points as visual feature.
32 */
33
49
50#include <iostream>
51
52#include <visp3/core/vpConfig.h>
53
54#if defined(VISP_HAVE_DISPLAY) && \
55 (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
56
57#include <stdio.h>
58#include <stdlib.h>
59
60#include <visp3/core/vpCameraParameters.h>
61#include <visp3/core/vpHomogeneousMatrix.h>
62#include <visp3/core/vpImage.h>
63#include <visp3/core/vpMath.h>
64#include <visp3/gui/vpDisplayFactory.h>
65#include <visp3/gui/vpProjectionDisplay.h>
66#include <visp3/io/vpParseArgv.h>
67#include <visp3/robot/vpSimulatorCamera.h>
68#include <visp3/visual_features/vpFeatureBuilder.h>
69#include <visp3/visual_features/vpFeaturePoint.h>
70#include <visp3/vs/vpServo.h>
71#include <visp3/vs/vpServoDisplay.h>
72
73// List of allowed command line options
74#define GETOPTARGS "cdh"
75
76#ifdef ENABLE_VISP_NAMESPACE
77using namespace VISP_NAMESPACE_NAME;
78#endif
79
80void usage(const char *name, const char *badparam);
81bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
82
91void usage(const char *name, const char *badparam)
92{
93 fprintf(stdout, "\n\
94Tests a control law with the following characteristics:\n\
95- eye-in-hand control\n\
96- articular velocity are computed\n\
97- servo on 4 points,\n\
98- internal and external camera view displays.\n\
99 \n\
100SYNOPSIS\n\
101 %s [-c] [-d] [-h]\n",
102 name);
103
104 fprintf(stdout, "\n\
105OPTIONS: Default\n\
106 -c\n\
107 Disable the mouse click. Useful to automate the \n\
108 execution of this program without human intervention.\n\
109 \n\
110 -d \n\
111 Turn off the display.\n\
112 \n\
113 -h\n\
114 Print the help.\n");
115
116 if (badparam)
117 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
118}
131bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
132{
133 const char *optarg_;
134 int c;
135 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
136
137 switch (c) {
138 case 'c':
139 click_allowed = false;
140 break;
141 case 'd':
142 display = false;
143 break;
144 case 'h':
145 usage(argv[0], nullptr);
146 return false;
147
148 default:
149 usage(argv[0], optarg_);
150 return false;
151 }
152 }
153
154 if ((c == 1) || (c == -1)) {
155 // standalone param or error
156 usage(argv[0], nullptr);
157 std::cerr << "ERROR: " << std::endl;
158 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
159 return false;
160 }
161
162 return true;
163}
164
165int main(int argc, const char **argv)
166{
167 // We declare the windows variables to be able to free the memory in the catch sections if needed
168#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
169 std::shared_ptr<vpDisplay> displayInt;
170 std::shared_ptr<vpDisplay> displayExt;
171#else
172 vpDisplay *displayInt = nullptr;
173 vpDisplay *displayExt = nullptr;
174#endif
175
176 try {
177 bool opt_click_allowed = true;
178 bool opt_display = true;
179
180 // Read the command line options
181 if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
182 return EXIT_FAILURE;
183 }
184 // open a display for the visualization
185
186 vpImage<unsigned char> Iint(300, 300, 0);
187 vpImage<unsigned char> Iext(300, 300, 0);
188
189 if (opt_display) {
190 // We open two displays, one for the internal camera view, the other one for
191 // the external view
192 // Display size is automatically defined by the image (Iint) and
193 // (Iext) size
194#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
195 displayInt = vpDisplayFactory::createDisplay(Iint, 0, 0, "Internal view");
196 displayExt = vpDisplayFactory::createDisplay(Iext, 330, 000, "External view");
197#else
198 displayInt = vpDisplayFactory::allocateDisplay(Iint, 0, 0, "Internal view");
199 displayExt = vpDisplayFactory::allocateDisplay(Iext, 330, 000, "External view");
200#endif
201 }
202 vpProjectionDisplay externalview;
203
204 double px = 500, py = 500;
205 double u0 = 150, v0 = 160;
206
207 vpCameraParameters cam(px, py, u0, v0);
208
210 vpSimulatorCamera robot;
211
212 std::cout << std::endl;
213 std::cout << "----------------------------------------------" << std::endl;
214 std::cout << " Test program for vpServo " << std::endl;
215 std::cout << " Eye-in-hand task control, articular velocity are computed" << std::endl;
216 std::cout << " Simulation " << std::endl;
217 std::cout << " task : servo 4 points " << std::endl;
218 std::cout << "----------------------------------------------" << std::endl;
219 std::cout << std::endl;
220
221 // sets the initial camera location
222 vpHomogeneousMatrix cMo(-0.1, -0.1, 1, vpMath::rad(40), vpMath::rad(10), vpMath::rad(60));
223
224 // Compute the position of the object in the world frame
225 vpHomogeneousMatrix wMc, wMo;
226 robot.getPosition(wMc);
227 wMo = wMc * cMo;
228
229 vpHomogeneousMatrix cextMo(0, 0, 2, 0, 0, 0); // vpMath::rad(40), vpMath::rad(10), vpMath::rad(60));
230
231 // sets the point coordinates in the object frame
232 vpPoint point[4];
233 point[0].setWorldCoordinates(-0.1, -0.1, 0);
234 point[1].setWorldCoordinates(0.1, -0.1, 0);
235 point[2].setWorldCoordinates(0.1, 0.1, 0);
236 point[3].setWorldCoordinates(-0.1, 0.1, 0);
237
238 for (unsigned i = 0; i < 4; i++)
239 externalview.insert(point[i]);
240
241 // computes the point coordinates in the camera frame and its 2D
242 // coordinates
243 for (unsigned i = 0; i < 4; i++)
244 point[i].track(cMo);
245
246 // sets the desired position of the point
247 vpFeaturePoint p[4];
248 for (unsigned i = 0; i < 4; i++)
249 vpFeatureBuilder::create(p[i], point[i]); // retrieve x,y and Z of the vpPoint structure
250
251 // sets the desired position of the feature point s*
252 vpFeaturePoint pd[4];
253
254 pd[0].buildFrom(-0.1, -0.1, 1);
255 pd[1].buildFrom(0.1, -0.1, 1);
256 pd[2].buildFrom(0.1, 0.1, 1);
257 pd[3].buildFrom(-0.1, 0.1, 1);
258
259 // define the task
260 // - we want an eye-in-hand control law
261 // - articular velocity are computed
263 task.setInteractionMatrixType(vpServo::MEAN);
264
265 // Set the position of the end-effector frame in the camera frame as identity
267 vpVelocityTwistMatrix cVe(cMe);
268 task.set_cVe(cVe);
269
270 // Set the Jacobian (expressed in the end-effector frame
271 vpMatrix eJe;
272 robot.get_eJe(eJe);
273 task.set_eJe(eJe);
274
275 // we want to see a point on a point
276 for (unsigned i = 0; i < 4; i++)
277 task.addFeature(p[i], pd[i]);
278
279 // set the gain
280 task.setLambda(1);
281
282 // Display task information
283 task.print();
284
285 unsigned int iter = 0;
286 // loop
287 while (iter++ < 200) {
288 std::cout << "---------------------------------------------" << iter << std::endl;
290
291 // Set the Jacobian (expressed in the end-effector frame)
292 // since q is modified eJe is modified
293 robot.get_eJe(eJe);
294 task.set_eJe(eJe);
295
296 // get the robot position
297 robot.getPosition(wMc);
298 // Compute the position of the object frame in the camera frame
299 cMo = wMc.inverse() * wMo;
300
301 // update new point position and corresponding features
302 for (unsigned i = 0; i < 4; i++) {
303 point[i].track(cMo);
304 // retrieve x,y and Z of the vpPoint structure
305 vpFeatureBuilder::create(p[i], point[i]);
306 }
307 // since vpServo::MEAN interaction matrix is used, we need also to
308 // update the desired features at each iteration
309 pd[0].buildFrom(-0.1, -0.1, 1);
310 pd[1].buildFrom(0.1, -0.1, 1);
311 pd[2].buildFrom(0.1, 0.1, 1);
312 pd[3].buildFrom(-0.1, 0.1, 1);
313
314 if (opt_display) {
315 vpDisplay::display(Iint);
316 vpDisplay::display(Iext);
317 vpServoDisplay::display(task, cam, Iint);
318 externalview.display(Iext, cextMo, cMo, cam, vpColor::green);
319 vpDisplay::flush(Iint);
320 vpDisplay::flush(Iext);
321 }
322
323 // compute the control law
324 v = task.computeControlLaw();
325
326 // send the camera velocity to the controller
327 robot.setVelocity(vpRobot::CAMERA_FRAME, v);
328
329 std::cout << "|| s - s* || = " << (task.getError()).sumSquare() << std::endl;
330 }
331
332 // Display task information
333 task.print();
334
335 std::cout << "Final robot position with respect to the object frame:\n";
336 cMo.print();
337
338 if (opt_display && opt_click_allowed) {
339 vpDisplay::displayText(Iint, 20, 20, "Click to quit...", vpColor::white);
340 vpDisplay::flush(Iint);
342 }
343#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
344 if (displayInt != nullptr) {
345 delete displayInt;
346 }
347 if (displayExt != nullptr) {
348 delete displayExt;
349 }
350#endif
351 return EXIT_SUCCESS;
352 }
353 catch (const vpException &e) {
354 std::cout << "Catch a ViSP exception: " << e << std::endl;
355#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
356 if (displayInt != nullptr) {
357 delete displayInt;
358 }
359 if (displayExt != nullptr) {
360 delete displayExt;
361 }
362#endif
363 return EXIT_FAILURE;
364 }
365}
366#elif !(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
367int main()
368{
369 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
370 return EXIT_SUCCESS;
371}
372#else
373int main()
374{
375 std::cout << "You do not have X11, or GTK, or GDI (Graphical Device Interface) functionalities to display images..."
376 << std::endl;
377 std::cout << "Tip if you are on a unix-like system:" << std::endl;
378 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
379 std::cout << "Tip if you are on a windows-like system:" << std::endl;
380 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
381 return EXIT_SUCCESS;
382}
383#endif
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
static const vpColor white
Definition vpColor.h:193
static const vpColor green
Definition vpColor.h:201
Class that defines generic functionalities for display.
Definition vpDisplay.h:171
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
Definition vpException.h:60
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Class that defines a 2D point visual feature which is composed by two parameters that are the cartes...
vpFeaturePoint & buildFrom(const double &x, const double &y, const double &Z)
void track(const vpHomogeneousMatrix &cMo)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
Definition of the vpImage class member functions.
Definition vpImage.h:131
static double rad(double deg)
Definition vpMath.h:129
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
void setWorldCoordinates(double oX, double oY, double oZ)
Definition vpPoint.cpp:116
interface with the image for feature display
void insert(vpForwardProjection &fp)
void display(vpImage< unsigned char > &I, const vpHomogeneousMatrix &cextMo, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &color, const bool &displayTraj=false, unsigned int thickness=1)
@ CAMERA_FRAME
Definition vpRobot.h:81
static void display(const vpServo &s, const vpCameraParameters &cam, const vpImage< unsigned char > &I, vpColor currentColor=vpColor::green, vpColor desiredColor=vpColor::red, unsigned int thickness=1)
@ EYEINHAND_L_cVe_eJe
Definition vpServo.h:183
Class that defines the simplest robot: a free flying camera.
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.