Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
servoAfma6Segment2DCamVelocity.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 * tests the control law
32 * eye-in-hand control
33 * velocity computed in the camera frame
34 */
35
43
44#include <stdlib.h>
45#include <vector>
46#include <visp3/core/vpConfig.h>
47#include <visp3/core/vpDebug.h> // Debug trace
48#if (defined(VISP_HAVE_AFMA6) && defined(VISP_HAVE_REALSENSE2))
49
50#include <visp3/blob/vpDot.h>
51#include <visp3/core/vpDisplay.h>
52#include <visp3/core/vpException.h>
53#include <visp3/core/vpHomogeneousMatrix.h>
54#include <visp3/core/vpImage.h>
55#include <visp3/core/vpImagePoint.h>
56#include <visp3/core/vpIoTools.h>
57#include <visp3/core/vpMath.h>
58#include <visp3/core/vpPoint.h>
59#include <visp3/gui/vpDisplayFactory.h>
60#include <visp3/robot/vpRobotAfma6.h>
61#include <visp3/sensor/vpRealSense2.h>
62#include <visp3/visual_features/vpFeatureBuilder.h>
63#include <visp3/visual_features/vpFeatureSegment.h>
64#include <visp3/vs/vpServo.h>
65#include <visp3/vs/vpServoDisplay.h>
66
67int main()
68{
69#ifdef ENABLE_VISP_NAMESPACE
70 using namespace VISP_NAMESPACE_NAME;
71#endif
72
73 // Log file creation in /tmp/$USERNAME/log.dat
74 // This file contains by line:
75 // - the 6 computed cam velocities (m/s, rad/s) to achieve the task
76 // - the 6 measured joint velocities (m/s, rad/s)
77 // - the 6 measured joint positions (m, rad)
78 // - the 2 values of s - s*
79 std::string username;
80 // Get the user login name
81 vpIoTools::getUserName(username);
82
83 // Create a log filename to save velocities...
84 std::string logdirname;
85 logdirname = "/tmp/" + username;
86
87 // Test if the output path exist. If no try to create it
88 if (vpIoTools::checkDirectory(logdirname) == false) {
89 try {
90 // Create the dirname
91 vpIoTools::makeDirectory(logdirname);
92 }
93 catch (...) {
94 std::cerr << std::endl << "ERROR:" << std::endl;
95 std::cerr << " Cannot create " << logdirname << std::endl;
96 return EXIT_FAILURE;
97 }
98 }
99 std::string logfilename;
100 logfilename = logdirname + "/log.dat";
101
102 // Open the log file name
103 std::ofstream flog(logfilename.c_str());
104
105#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
106 std::shared_ptr<vpDisplay> display;
107#else
108 vpDisplay *display = nullptr;
109#endif
110 try {
112
114
115 vpRealSense2 rs;
116 rs2::config config;
117 unsigned int width = 640, height = 480, fps = 60;
118 config.enable_stream(RS2_STREAM_COLOR, width, height, RS2_FORMAT_RGBA8, fps);
119 config.enable_stream(RS2_STREAM_DEPTH, width, height, RS2_FORMAT_Z16, fps);
120 config.enable_stream(RS2_STREAM_INFRARED, width, height, RS2_FORMAT_Y8, fps);
121 rs.open(config);
122
123 // Warm up camera
124 for (size_t i = 0; i < 10; ++i) {
125 rs.acquire(I);
126 }
127
128#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
129 display = vpDisplayFactory::createDisplay(I, 100, 100, "Current image");
130#else
131 display = vpDisplayFactory::allocateDisplay(I, 100, 100, "Current image");
132#endif
133
136
137 std::vector<vpDot> dot_d(2), dot(2);
138 vpFeatureSegment seg_d, seg;
139 vpImagePoint cog;
140 vpRobotAfma6 robot;
142
143 // Get camera intrinsics
145 robot.getCameraParameters(cam, I);
146
147 std::cout << "Define the initial segment" << std::endl;
148
149 for (std::vector<vpDot>::iterator i = dot.begin(); i != dot.end(); ++i) {
150 std::cout << "Click on a dot..." << std::endl;
151 i->initTracking(I);
152 cog = i->getCog();
155 }
156 vpFeatureBuilder::create(seg, cam, dot[0], dot[1]);
157 seg.display(cam, I, vpColor::red);
159 std::cout << "define the destination segment" << std::endl;
160 for (std::vector<vpDot>::iterator i = dot_d.begin(); i != dot_d.end(); ++i) {
161 vpImagePoint ip;
162 vpDisplay::getClick(I, ip);
163 *i = vpDot(ip);
165 }
166 vpFeatureBuilder::create(seg_d, cam, dot_d[0], dot_d[1]);
167 seg_d.setZ1(1.);
168 seg_d.setZ2(1.);
169
170 seg_d.display(cam, I);
172 // define the task
173 // - we want an eye-in-hand control law
174 // - robot is controlled in the camera frame
176 task.setInteractionMatrixType(vpServo::DESIRED);
177
178 // - we want to see both segments
179 task.addFeature(seg, seg_d);
180
181 // - set the constant gain
182 task.setLambda(0.8);
183
184 // Display task information
185 task.print();
186
187 // Now the robot will be controlled in velocity
188 robot.setRobotState(vpRobot::STATE_VELOCITY_CONTROL);
189
190 std::cout << "\nHit CTRL-C to stop the loop...\n" << std::flush;
191 bool quit = false;
192 while (!quit) {
193 // Acquire a new image from the camera
194 rs.acquire(I);
195
196 // Display this image
198
199 // Achieve the tracking of the dot in the image
200 for (std::vector<vpDot>::iterator i = dot.begin(); i != dot.end(); ++i) {
201 i->track(I);
202 }
203
204 // Update the segment feature from the dot locations
205 vpFeatureBuilder::create(seg, cam, dot[0], dot[1]);
206
208 // Compute the visual servoing skew vector
209 v = task.computeControlLaw();
210
211 // Display the current and desired feature segments in the image display
212 vpServoDisplay::display(task, cam, I);
213
214 // Apply the computed joint velocities to the robot
215 robot.setVelocity(vpRobot::CAMERA_FRAME, v);
216
217 // Save feature error (s-s*) for the feature segment. For this feature
218 // segments, we have 4 errors (Xc,Yc,l,alpha).
219 flog << (task.getError()).t() << std::endl;
220
221 vpDisplay::displayText(I, 20, 20, "Click to quit...", vpColor::red);
222 if (vpDisplay::getClick(I, false)) {
223 quit = true;
224 }
225 // Flush the display
227 }
228
229 // Close the log file
230 flog.close();
231
232 // Display task information
233 task.print();
234
235#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
236 if (display != nullptr) {
237 delete display;
238 }
239#endif
240 return EXIT_SUCCESS;
241 }
242 catch (const vpException &e) {
243 // Close the log file
244 flog.close();
245 std::cout << "Visual servo failed with exception: " << e << std::endl;
246#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
247 if (display != nullptr) {
248 delete display;
249 }
250#endif
251 return EXIT_FAILURE;
252 }
253}
254
255#else
256int main()
257{
258 std::cout << "You do not have an afma6 robot connected to your computer..." << std::endl;
259 return EXIT_SUCCESS;
260}
261#endif
@ TOOL_INTEL_D435_CAMERA
Definition vpAfma6.h:129
Generic class defining intrinsic camera parameters.
@ perspectiveProjWithoutDistortion
Perspective projection without distortion model.
Implementation of column vector and the associated operations.
static const vpColor red
Definition vpColor.h:198
static const vpColor blue
Definition vpColor.h:204
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 displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
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)
This tracker is meant to track a dot (connected pixels with same gray level) on a vpImage.
Definition vpDot.h:123
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 segment visual features. This class allow to consider two sets of visual feat...
void display(const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1) const VP_OVERRIDE
void setZ2(double val)
void setZ1(double val)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
Definition vpImage.h:131
static bool checkDirectory(const std::string &dirname)
static std::string getUserName()
static void makeDirectory(const std::string &dirname)
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.
void init(void)
@ CAMERA_FRAME
Definition vpRobot.h:81
@ STATE_VELOCITY_CONTROL
Initialize the velocity controller.
Definition vpRobot.h:64
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
@ DESIRED
Definition vpServo.h:223
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.