42#include <visp3/core/vpCameraParameters.h>
43#include <visp3/core/vpCylinder.h>
44#include <visp3/core/vpHomogeneousMatrix.h>
45#include <visp3/core/vpImage.h>
46#include <visp3/core/vpIoTools.h>
47#include <visp3/core/vpMath.h>
48#include <visp3/core/vpTime.h>
49#include <visp3/core/vpVelocityTwistMatrix.h>
50#include <visp3/gui/vpDisplayFactory.h>
51#include <visp3/gui/vpPlot.h>
52#include <visp3/io/vpImageIo.h>
53#include <visp3/io/vpParseArgv.h>
54#include <visp3/robot/vpSimulatorCamera.h>
55#include <visp3/robot/vpWireFrameSimulator.h>
56#include <visp3/visual_features/vpFeatureBuilder.h>
57#include <visp3/vs/vpServo.h>
59#define GETOPTARGS "dhp"
61#if defined(VISP_HAVE_DISPLAY) && (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
63#if defined(ENABLE_VISP_NAMESPACE)
75void usage(
const char *name,
const char *badparam)
78Demonstration of the wireframe simulator with a simple visual servoing.\n\
80The visual servoing consists in bringing the camera at a desired position\n\
83The visual features used to compute the pose of the camera and \n\
84thus the control law are two lines. These features are computed thanks \n\
85to the equation of a cylinder.\n\
87This demonstration explains also how to move the object around a world \n\
88reference frame. Here, the movment is a rotation around the x and y axis \n\
89at a given distance from the world frame. In fact the object trajectory \n\
90is on a sphere whose center is the origin of the world frame.\n\
99 Turn off the display.\n\
102 Turn off the plotter.\n\
108 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
123bool getOptions(
int argc,
const char **argv,
bool &display,
bool &plot)
137 usage(argv[0],
nullptr);
141 usage(argv[0], optarg_);
146 if ((c == 1) || (c == -1)) {
148 usage(argv[0],
nullptr);
149 std::cerr <<
"ERROR: " << std::endl;
150 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
157int main(
int argc,
const char **argv)
159 const unsigned int NB_DISPLAYS = 2;
160#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
161 std::shared_ptr<vpDisplay> display[NB_DISPLAYS];
162 for (
unsigned int i = 0;
i < NB_DISPLAYS; ++
i) {
167 for (
unsigned int i = 0;
i < NB_DISPLAYS; ++
i) {
171 unsigned int exit_status = EXIT_SUCCESS;
174 bool opt_display =
true;
175 bool opt_plot =
true;
178 if (getOptions(argc, argv, opt_display, opt_plot) ==
false) {
187 display[0]->init(Iint, 100, 100,
"The internal view");
188 display[1]->init(Iext, 100, 100,
"The first external view");
201 float sampling_time = 0.020f;
212 wMc = wMo *
cMo.inverse();
226 cylinder.track(cdMo);
243 for (
int i = 0;
i < 2;
i++)
244 task.addFeature(l[i], ld[i]);
247 plotter =
new vpPlot(2, 480, 640, 750, 550,
"Real time curves plotter");
248 plotter->setTitle(0,
"Visual features error");
249 plotter->setTitle(1,
"Camera velocities");
252 plotter->setLegend(0, 0,
"error_feat_l1_rho");
253 plotter->setLegend(0, 1,
"error_feat_l1_theta");
254 plotter->setLegend(0, 2,
"error_feat_l2_rho");
255 plotter->setLegend(0, 3,
"error_feat_l2_theta");
256 plotter->setLegend(1, 0,
"vc_x");
257 plotter->setLegend(1, 1,
"vc_y");
258 plotter->setLegend(1, 2,
"vc_z");
259 plotter->setLegend(1, 3,
"wc_x");
260 plotter->setLegend(1, 4,
"wc_y");
261 plotter->setLegend(1, 5,
"wc_z");
309 std::cout <<
"Click on a display" << std::endl;
314 robot.setPosition(wMc);
329 double vitesse = 0.3;
334 while (iter++ < max_iter && !stop) {
346 wMc = robot.getPosition();
353 v =
task.computeControlLaw();
356 if (iter % tempo < 200 && iter % tempo >= 0) {
358 e1[0] = -fabs(vitesse);
359 proj_e1 =
task.secondaryTask(e1,
true);
360 rapport = -vitesse / proj_e1[0];
365 else if (iter % tempo < 300 && iter % tempo >= 200) {
367 e2[1] = -fabs(vitesse);
368 proj_e2 =
task.secondaryTask(e2,
true);
369 rapport = -vitesse / proj_e2[1];
374 else if (iter % tempo < 500 && iter % tempo >= 300) {
376 e1[0] = -fabs(vitesse);
377 proj_e1 =
task.secondaryTask(e1,
true);
378 rapport = vitesse / proj_e1[0];
383 else if (iter % tempo < 600 && iter % tempo >= 500) {
385 e2[1] = -fabs(vitesse);
386 proj_e2 =
task.secondaryTask(e2,
true);
387 rapport = vitesse / proj_e2[1];
422 std::stringstream ss;
423 ss <<
"Loop time: " <<
t - t_prev <<
" ms";
436 std::cout <<
"|| s - s* || = " << (
task.getError()).sumSquare() << std::endl;
439 if (opt_plot && plotter !=
nullptr) {
455 exit_status = EXIT_SUCCESS;
458 std::cout <<
"Catch an exception: " <<
e << std::endl;
459 exit_status = EXIT_FAILURE;
461#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
462 for (
unsigned int i = 0;
i < NB_DISPLAYS; ++
i) {
468#elif !(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
471 std::cout <<
"Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
477 std::cout <<
"You do not have X11, or GDI (Graphical Device Interface), or GTK functionalities to display images..."
479 std::cout <<
"Tip if you are on a unix-like system:" << std::endl;
480 std::cout <<
"- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
481 std::cout <<
"Tip if you are on a windows-like system:" << std::endl;
482 std::cout <<
"- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
static const vpColor none
Class that defines a 3D cylinder in the object frame and allows forward projection of a 3D cylinder i...
Class that defines generic functionalities for display.
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
static void flush(const vpImage< unsigned char > &I)
static void setWindowPosition(const vpImage< unsigned char > &I, int winx, int winy)
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.
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Class that defines a 2D line visual feature which is composed by two parameters that are and ,...
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
Definition of the vpImage class member functions.
static double rad(double deg)
Implementation of a matrix and operations on matrices.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
This class enables real time drawing of 2D or 3D graphics. An instance of the class open a window whi...
virtual void setSamplingTime(const double &delta_t)
Class that defines the simplest robot: a free flying camera.
Implementation of a wire frame simulator. Compared to the vpSimulator class, it does not require thir...
vpHomogeneousMatrix getExternalCameraPosition() const
void setCameraPositionRelObj(const vpHomogeneousMatrix &cMo_)
void getInternalImage(vpImage< unsigned char > &I)
void initScene(const vpSceneObject &obj, const vpSceneDesiredObject &desiredObject)
void setExternalCameraPosition(const vpHomogeneousMatrix &cam_Mf)
void set_fMo(const vpHomogeneousMatrix &fMo_)
vpHomogeneousMatrix get_fMo() const
void setDesiredCameraPosition(const vpHomogeneousMatrix &cdMo_)
void setInternalCameraParameters(const vpCameraParameters &cam)
void setExternalCameraParameters(const vpCameraParameters &cam)
@ CYLINDER
A cylinder of 80cm length and 10cm radius.
void getExternalImage(vpImage< unsigned char > &I)
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.
VISP_EXPORT double measureTimeMs()
VISP_EXPORT int wait(double t0, double t)