48#include <visp3/core/vpConfig.h>
50#if defined(VISP_HAVE_REALSENSE2) && defined(VISP_HAVE_AFMA6)
52#include <visp3/core/vpImage.h>
53#include <visp3/gui/vpDisplayFactory.h>
54#include <visp3/io/vpImageIo.h>
55#include <visp3/sensor/vpRealSense2.h>
56#include <visp3/core/vpCylinder.h>
57#include <visp3/core/vpHomogeneousMatrix.h>
58#include <visp3/core/vpMath.h>
59#include <visp3/me/vpMeLine.h>
60#include <visp3/visual_features/vpFeatureBuilder.h>
61#include <visp3/visual_features/vpFeatureLine.h>
62#include <visp3/robot/vpRobotAfma6.h>
63#include <visp3/vs/vpServoDisplay.h>
64#include <visp3/vs/vpServo.h>
66#ifdef ENABLE_VISP_NAMESPACE
76 double rho1 = s_line1.
getRho();
78 double rho2 = s_line2.
getRho();
80 double rhoi = s_line_di.
getRho();
81 double thetai = s_line_di.
getTheta();
82 double rhoj = s_line_dj.
getRho();
83 double thetaj = s_line_dj.
getTheta();
87 double err_min = 1.e6;
89 double er_theta1 = theta1-thetai;
90 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
91 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
92 double er_theta2 = theta2-thetaj;
93 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
94 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
96 err = (rho1-rhoi)*(rho1-rhoi) + er_theta1*er_theta1
97 + (rho2-rhoj)*(rho2-rhoj) + er_theta2*er_theta2;
102 std::cout <<
"Test 1 (1,2) <-> (i,j), err = " << err << std::endl;
104 er_theta1 = theta1-thetai;
105 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
106 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
107 er_theta2 = theta2-thetaj-M_PI;
108 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
109 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
111 err = (rho1-rhoi)*(rho1-rhoi) + er_theta1*er_theta1
112 + (rho2+rhoj)*(rho2+rhoj) + er_theta2*er_theta2;
117 std::cout <<
"Test 2 (1,2) <-> (i,-j), err = " << err << std::endl;
119 er_theta1 = theta1-thetai-M_PI;
120 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
121 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
122 er_theta2 = theta2-thetaj;
123 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
124 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
126 err = (rho1+rhoi)*(rho1+rhoi) + er_theta1*er_theta1
127 + (rho2-rhoj)*(rho2-rhoj) + er_theta2*er_theta2;
132 std::cout <<
"Test 3 (1,2) <-> (-i,j), err = " << err << std::endl;
134 er_theta1 = theta1-thetai-M_PI;
135 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
136 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
137 er_theta2 = theta2-thetaj-M_PI;
138 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
139 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
141 err = (rho1+rhoi)*(rho1+rhoi) + er_theta1*er_theta1
142 + (rho2+rhoj)*(rho2+rhoj) + er_theta2*er_theta2;
147 std::cout <<
"Test 4 (1,2) <-> (-i,-j), err = " << err << std::endl;
149 er_theta1 = theta1-thetaj;
150 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
151 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
152 er_theta2 = theta2-thetai;
153 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
154 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
156 err = (rho1-rhoj)*(rho1-rhoj) + er_theta1*er_theta1
157 + (rho2-rhoi)*(rho2-rhoi) + er_theta2*er_theta2;
162 std::cout <<
"Test 5 (1,2) <-> (j,i), err = " << err << std::endl;
164 er_theta1 = theta1-thetaj-M_PI;
165 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
166 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
167 er_theta2 = theta2-thetai;
168 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
169 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
171 err = (rho1+rhoj)*(rho1+rhoj) + er_theta1*er_theta1
172 + (rho2-rhoi)*(rho2-rhoi) + er_theta2*er_theta2;
177 std::cout <<
"Test 6 (1,2) <-> (-j,i), err = " << err << std::endl;
179 er_theta1 = theta1-thetaj;
180 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
181 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
182 er_theta2 = theta2-thetai-M_PI;
183 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
184 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
186 err = (rho1-rhoj)*(rho1-rhoj) + er_theta1*er_theta1
187 + (rho2+rhoi)*(rho2+rhoi) + er_theta2*er_theta2;
192 std::cout <<
"Test 7 (1,2) <-> (j,-i), err = " << err << std::endl;
194 er_theta1 = theta1-thetaj-M_PI;
195 if (er_theta1 > M_PI) er_theta1 -= 2.0*M_PI;
196 else if (er_theta1 < -M_PI) er_theta1 += 2.0*M_PI;
197 er_theta2 = theta2-thetai-M_PI;
198 if (er_theta2 > M_PI) er_theta2 -= 2.0*M_PI;
199 else if (er_theta2 < -M_PI) er_theta2 += 2.0*M_PI;
201 err = (rho1+rhoj)*(rho1+rhoj) + er_theta1*er_theta1
202 + (rho2+rhoi)*(rho2+rhoi) + er_theta2*er_theta2;
207 std::cout <<
"Test 8 (1,2) <-> (-j,-i), err = " << err << std::endl;
208 std::cout <<
"Test choisi = " <<
config << std::endl;
214 else if (config == 3) {
217 else if (config == 4) {
221 else if (config == 5) {
225 else if (config == 6) {
229 else if (config == 7) {
233 else if (config == 8) {
247int main(
int argc,
char **argv)
249 bool opt_verbose =
false;
250 bool opt_adaptive_gain =
false;
252 for (
int i = 1;
i < argc; ++
i) {
253 if (std::string(argv[i]) ==
"--verbose") {
256 else if (std::string(argv[i]) ==
"--adaptive-gain") {
257 opt_adaptive_gain =
true;
259 else if ((std::string(argv[i]) ==
"--help") || (std::string(argv[i]) ==
"-h")) {
262 <<
" [--adaptive-gain]"
277#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
278 std::shared_ptr<vpDisplay> display;
284 std::cout <<
"WARNING: This example will move the robot! "
285 <<
"Please make sure to have the user stop button at hand!" << std::endl
286 <<
"Press Enter to continue..." << std::endl;
292 config.enable_stream(RS2_STREAM_COLOR, width, height, RS2_FORMAT_RGBA8, fps);
293 config.enable_stream(RS2_STREAM_DEPTH, width, height, RS2_FORMAT_Z16, fps);
294 config.enable_stream(RS2_STREAM_INFRARED, width, height, RS2_FORMAT_Y8, fps);
299 for (
size_t i = 0;
i < 10; ++
i) {
303#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
312 std::vector<vpMeLine> line(nblines);
322 for (
int i = 0;
i < nblines; ++
i) {
326 line[
i].initTracking(I);
333 robot.getCameraParameters(cam, I);
334 std::cout <<
"cam:\n" <<
cam << std::endl;
337 std::vector<vpFeatureLine> s_line(nblines);
338 for (
int i = 0;
i < nblines; ++
i) {
347 cylinder.project(c_M_o);
349 std::vector<vpFeatureLine> s_line_d(nblines);
354 std::cout <<
"Measured features: " << std::endl;
355 std::cout <<
" - line 1: rho: " << s_line[0].getRho() <<
" theta: " <<
vpMath::deg(s_line[0].getTheta()) <<
"deg" << std::endl;
356 std::cout <<
" - line 2: rho: " << s_line[1].getRho() <<
" theta: " <<
vpMath::deg(s_line[1].getTheta()) <<
"deg" << std::endl;
357 std::cout <<
"Desired features: " << std::endl;
358 std::cout <<
" - line 1: rho: " << s_line_d[0].getRho() <<
" theta: " <<
vpMath::deg(s_line_d[0].getTheta()) <<
"deg" << std::endl;
359 std::cout <<
" - line 2: rho: " << s_line_d[1].getRho() <<
" theta: " <<
vpMath::deg(s_line_d[1].getTheta()) <<
"deg" << std::endl;
362 match(s_line[0], s_line[1], s_line_d[0], s_line_d[1]);
365 std::cout <<
"Modified desired features: " << std::endl;
366 std::cout <<
" - line 1: rho: " << s_line_d[0].getRho() <<
" theta: " <<
vpMath::deg(s_line_d[0].getTheta()) <<
"deg" << std::endl;
367 std::cout <<
" - line 2: rho: " << s_line_d[1].getRho() <<
" theta: " <<
vpMath::deg(s_line_d[1].getTheta()) <<
"deg" << std::endl;
376 for (
int i = 0;
i < nblines; ++
i) {
377 task.addFeature(s_line[i], s_line_d[i]);
381 if (opt_adaptive_gain) {
383 task.setLambda(lambda);
394 bool final_quit =
false;
395 bool send_velocities =
false;
397 while (!final_quit) {
403 std::stringstream ss;
404 ss <<
"Left click to " << (send_velocities ?
"stop the robot" :
"servo the robot") <<
", right click to quit.";
408 for (
int i = 0;
i < nblines; ++
i) {
419 v_c =
task.computeControlLaw();
422 std::cout <<
"v: " << v_c.t() << std::endl;
423 std::cout <<
"\t\t || s - s* || = " <<
task.getError().sumSquare() << std::endl;
426 if (!send_velocities) {
441 send_velocities = !send_velocities;
454 std::cout <<
"Stop the robot " << std::endl;
458 while (!final_quit) {
475 std::cout <<
"ViSP exception: " <<
e.what() << std::endl;
476 std::cout <<
"Stop the robot " << std::endl;
478#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
479 if (display !=
nullptr) {
486#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
487 if (display !=
nullptr) {
497 std::cout <<
"You do not have an afma6 robot connected to your computer..." << std::endl;
Adaptive gain computation.
Generic class defining intrinsic camera parameters.
vpCameraParametersProjType
@ perspectiveProjWithDistortion
Perspective projection with distortion model.
Implementation of column vector and the associated operations.
static const vpColor green
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 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.
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 ,...
void setRhoTheta(double rho, double theta)
Implementation of an homogeneous matrix and operations on such kind of matrices.
Definition of the vpImage class member functions.
static double rad(double deg)
static double deg(double rad)
void setPointsToTrack(const int &points_to_track)
void setRange(const unsigned int &range)
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
void setThreshold(const double &threshold)
void setSampleStep(const double &sample_step)
void acquire(vpImage< unsigned char > &grey, double *ts=nullptr)
bool open(const rs2::config &cfg=rs2::config())
Control of Irisa's gantry robot named Afma6.
@ STATE_VELOCITY_CONTROL
Initialize the velocity controller.
@ STATE_STOP
Stops robot motion especially in velocity and acceleration control.
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()