Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
servoSimuSphere2DCamVelocityDisplay.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 on a sphere.
32 */
33
42
43#include <stdio.h>
44#include <stdlib.h>
45
46#include <visp3/core/vpConfig.h>
47#include <visp3/core/vpHomogeneousMatrix.h>
48#include <visp3/core/vpMath.h>
49#include <visp3/core/vpSphere.h>
50#include <visp3/gui/vpDisplayFactory.h>
51#include <visp3/io/vpParseArgv.h>
52#include <visp3/robot/vpSimulatorCamera.h>
53#include <visp3/visual_features/vpFeatureBuilder.h>
54#include <visp3/visual_features/vpFeatureEllipse.h>
55#include <visp3/vs/vpServo.h>
56#include <visp3/vs/vpServoDisplay.h>
57
58// List of allowed command line options
59#define GETOPTARGS "cdh"
60
61#ifdef ENABLE_VISP_NAMESPACE
62using namespace VISP_NAMESPACE_NAME;
63#endif
64
65void usage(const char *name, const char *badparam);
66bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
67
76void usage(const char *name, const char *badparam)
77{
78 fprintf(stdout, "\n\
79Simulation of a 2D visual servoing on a sphere:\n\
80- eye-in-hand control law,\n\
81- velocity computed in the camera frame,\n\
82- display the camera view.\n\
83 \n\
84SYNOPSIS\n\
85 %s [-c] [-d] [-h]\n",
86 name);
87
88 fprintf(stdout, "\n\
89OPTIONS: Default\n\
90 \n\
91 -c\n\
92 Disable the mouse click. Useful to automate the \n\
93 execution of this program without human intervention.\n\
94 \n\
95 -d \n\
96 Turn off the display.\n\
97 \n\
98 -h\n\
99 Print the help.\n");
100
101 if (badparam)
102 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
103}
104
117bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
118{
119 const char *optarg_;
120 int c;
121 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
122
123 switch (c) {
124 case 'c':
125 click_allowed = false;
126 break;
127 case 'd':
128 display = false;
129 break;
130 case 'h':
131 usage(argv[0], nullptr);
132 return false;
133
134 default:
135 usage(argv[0], optarg_);
136 return false;
137 }
138 }
139
140 if ((c == 1) || (c == -1)) {
141 // standalone param or error
142 usage(argv[0], nullptr);
143 std::cerr << "ERROR: " << std::endl;
144 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
145 return false;
146 }
147
148 return true;
149}
150
151int main(int argc, const char **argv)
152{
153#if (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
154#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
155 std::shared_ptr<vpDisplay> display;
156#else
157 vpDisplay *display = nullptr;
158#endif
159 try {
160 bool opt_display = true;
161 bool opt_click_allowed = true;
162
163 // Read the command line options
164 if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
165 return (EXIT_FAILURE);
166 }
167
168 vpImage<unsigned char> I(512, 512, 0);
169
170 if (opt_display) {
171#if defined(VISP_HAVE_DISPLAY)
172 // Display size is automatically defined by the image (I) size
173#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
174 display = vpDisplayFactory::createDisplay(I, 100, 100, "Camera view...");
175#else
176 display = vpDisplayFactory::allocateDisplay(I, 100, 100, "Camera view...");
177#endif
178#endif
179 // Display the image
180 // The image class has a member that specify a pointer toward
181 // the display that has been initialized in the display declaration
182 // therefore is is no longer necessary to make a reference to the
183 // display variable.
186 }
187
188 double px = 600, py = 600;
189 double u0 = I.getWidth() / 2., v0 = I.getHeight() / 2.;
190
191 vpCameraParameters cam(px, py, u0, v0);
192
194 vpSimulatorCamera robot;
195
196 // sets the initial camera location
198 cMo[0][3] = 0.1;
199 cMo[1][3] = 0.2;
200 cMo[2][3] = 2;
201 // Compute the position of the object in the world frame
202 vpHomogeneousMatrix wMc, wMo;
203 robot.getPosition(wMc);
204 wMo = wMc * cMo;
205
207 cMod[0][3] = 0;
208 cMod[1][3] = 0;
209 cMod[2][3] = 1;
210
211 // sets the sphere coordinates in the world frame
212 vpSphere sphere;
213 sphere.setWorldCoordinates(0, 0, 0, 0.1);
214
215 // sets the desired position of the visual feature
217 sphere.track(cMod);
218 vpFeatureBuilder::create(pd, sphere);
219
220 // computes the sphere coordinates in the camera frame and its 2D
221 // coordinates sets the current position of the visual feature
223 sphere.track(cMo);
224 vpFeatureBuilder::create(p, sphere);
225
226 // define the task
227 // - we want an eye-in-hand control law
228 // - robot is controlled in the camera frame
230
231 // we want to see a sphere on a sphere
232 task.addFeature(p, pd);
233
234 // set the gain
235 task.setLambda(1);
236
237 // Display task information
238 task.print();
239
240 unsigned int iter = 0;
241 // loop
242 while (iter++ < 200) {
243 std::cout << "---------------------------------------------" << iter << std::endl;
245
246 // get the robot position
247 robot.getPosition(wMc);
248 // Compute the position of the object frame in the camera frame
249 cMo = wMc.inverse() * wMo;
250
251 // new sphere position: retrieve x,y and Z of the vpSphere structure
252 sphere.track(cMo);
253 vpFeatureBuilder::create(p, sphere);
254
255 if (opt_display) {
257 vpServoDisplay::display(task, cam, I);
259 }
260
261 // compute the control law
262 v = task.computeControlLaw();
263
264 std::cout << "Task rank: " << task.getTaskRank() << std::endl;
265 // send the camera velocity to the controller
266 robot.setVelocity(vpRobot::CAMERA_FRAME, v);
267
268 std::cout << "|| s - s* || = " << (task.getError()).sumSquare() << std::endl;
269 }
270
271 if (opt_display && opt_click_allowed) {
272 vpDisplay::displayText(I, 20, 20, "Click to quit...", vpColor::white);
275 }
276
277 // Display task information
278 task.print();
279#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
280 if (display != nullptr) {
281 delete display;
282 }
283#endif
284 return EXIT_SUCCESS;
285 }
286 catch (const vpException &e) {
287 std::cout << "Catch a ViSP exception: " << e << std::endl;
288#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
289 if (display != nullptr) {
290 delete display;
291 }
292#endif
293 return EXIT_FAILURE;
294 }
295#else
296 (void)argc;
297 (void)argv;
298 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
299 return EXIT_SUCCESS;
300#endif
301}
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
static const vpColor white
Definition vpColor.h:193
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 2D ellipse visual feature.
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 bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
@ 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_CAMERA
Definition vpServo.h:176
Class that defines the simplest robot: a free flying camera.
Class that defines a 3D sphere in the object frame and allows forward projection of a 3D sphere in th...
Definition vpSphere.h:80
void setWorldCoordinates(const vpColVector &oP) VP_OVERRIDE
Definition vpSphere.cpp:60
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.