5 #include <visp3/core/vpImageConvert.h>
6 #include <visp3/core/vpMutex.h>
7 #include <visp3/core/vpThread.h>
8 #include <visp3/core/vpTime.h>
9 #include <visp3/gui/vpDisplayX.h>
10 #include <visp3/gui/vpPlot.h>
11 #include <visp3/robot/vpRobotViper850.h>
12 #include <visp3/sensor/vpV4l2Grabber.h>
14 #include <visp3/ustk_core/usImagePostScan2D.h>
15 #include <visp3/ustk_core/usPixelMeterConversion.h>
17 #include <visp3/ustk_template_tracking/usDenseTracker2D.h>
19 #if defined(VISP_HAVE_V4L2) && defined(VISP_HAVE_PTHREAD) && defined(VISP_HAVE_VIPER850)
22 typedef enum { capture_waiting, capture_started, capture_stopped } t_CaptureState;
23 t_CaptureState s_capture_state = capture_waiting;
24 vpImage<unsigned char> s_frame;
25 vpMutex s_mutex_capture;
27 bool s_robotIsRunning;
28 vpMutex s_mutex_control_velocity;
29 vpColVector s_controlVelocity(6, 0.);
34 vpThread::Return captureFunction(vpThread::Args args)
36 vpV4l2Grabber cap = *((vpV4l2Grabber *)args);
37 vpImage<unsigned char> frame_;
38 bool stop_capture_ =
false;
42 vpRect roi(vpImagePoint(55, 70), vpImagePoint(410, 555));
44 while (!stop_capture_) {
46 cap.acquire(frame_, roi);
50 vpMutex::vpScopedLock lock(s_mutex_capture);
51 if (s_capture_state == capture_stopped)
54 s_capture_state = capture_started;
60 vpMutex::vpScopedLock lock(s_mutex_capture);
61 s_capture_state = capture_stopped;
63 std::cout <<
"End of capture thread" << std::endl;
69 vpThread::Return displayFunction(vpThread::Args args)
74 vpRectOriented rectangle;
85 t_CaptureState capture_state_;
86 bool display_initialized_ =
false;
88 #if defined(VISP_HAVE_X11)
89 vpDisplayX *dpost_scan_ = NULL;
95 plot.initRange(0, 0, 10, -0.01, 0.01);
96 plot.setTitle(0,
"X target error");
97 plot.setUnitY(0,
"error(meters)");
98 plot.setLegend(0, 0,
"time");
103 bool firstLoopCycle =
true;
105 double startTime = vpTime::measureTimeMs();
108 s_mutex_capture.lock();
109 capture_state_ = s_capture_state;
110 s_mutex_capture.unlock();
113 if (capture_state_ == capture_started) {
116 vpMutex::vpScopedLock lock(s_mutex_capture);
120 postScan_.getHeight());
123 postScan_.getHeight());
127 if (firstLoopCycle) {
128 rectangle.setCenter(vpImagePoint(postScan_.getHeight() / 2, postScan_.getWidth() / 2));
129 rectangle.setSize(50, 30);
130 rectangle.setOrientation(0);
131 tracker.
init(postScan_, rectangle);
134 tracker.
update(postScan_);
142 std::cout <<
"Center i = " << rectangle.getCenter().get_i() <<
", j = " << rectangle.getCenter().get_j()
144 std::cout <<
"xtarget = " << xtarget <<
", ytarget = " << ytarget << std::endl;
146 double time = (vpTime::measureTimeMs() - startTime) / 1000.0;
148 plot.plot(0, 0, time, xtarget);
151 vpMutex::vpScopedLock lock(s_mutex_capture);
152 s_controlVelocity = 0.0;
153 s_controlVelocity[1] = -1 * xtarget;
156 if (!display_initialized_) {
158 #if defined(VISP_HAVE_X11)
159 unsigned int xpos = 10;
160 dpost_scan_ =
new vpDisplayX(postScan_, xpos, 10,
"post-scan");
161 display_initialized_ =
true;
166 vpDisplay::display(postScan_);
168 vpDisplay::displayLine(postScan_,
static_cast<int>(rectangle.getTopLeft().get_i()),
169 static_cast<int>(rectangle.getTopLeft().get_j()),
170 static_cast<int>(rectangle.getBottomLeft().get_i()),
171 static_cast<int>(rectangle.getBottomLeft().get_j()), vpColor::red);
172 vpDisplay::displayLine(postScan_,
static_cast<int>(rectangle.getBottomLeft().get_i()),
173 static_cast<int>(rectangle.getBottomLeft().get_j()),
174 static_cast<int>(rectangle.getBottomRight().get_i()),
175 static_cast<int>(rectangle.getBottomRight().get_j()), vpColor::red);
176 vpDisplay::displayLine(postScan_,
static_cast<int>(rectangle.getBottomRight().get_i()),
177 static_cast<int>(rectangle.getBottomRight().get_j()),
178 static_cast<int>(rectangle.getTopRight().get_i()),
179 static_cast<int>(rectangle.getTopRight().get_j()), vpColor::red);
180 vpDisplay::displayLine(postScan_,
static_cast<int>(rectangle.getTopRight().get_i()),
181 static_cast<int>(rectangle.getTopRight().get_j()),
182 static_cast<int>(rectangle.getTopLeft().get_i()),
183 static_cast<int>(rectangle.getTopLeft().get_j()), vpColor::red);
186 vpDisplay::displayText(postScan_, 10, 10,
"Click to exit...", vpColor::red);
187 if (vpDisplay::getClick(postScan_,
false)) {
188 vpMutex::vpScopedLock lock(s_mutex_capture);
189 s_capture_state = capture_stopped;
193 vpDisplay::flush(postScan_);
194 firstLoopCycle =
false;
198 }
while (capture_state_ != capture_stopped);
200 #if defined(VISP_HAVE_X11)
204 std::cout <<
"End of display thread" << std::endl;
209 vpThread::Return controlFunction(vpThread::Args args)
212 vpRobotViper850 robot;
219 vpHomogeneousMatrix eMs;
224 vpHomogeneousMatrix sMp;
227 vpHomogeneousMatrix sMe;
232 vpVelocityTwistMatrix sVe;
236 vpColVector sHs_star(6);
237 vpColVector pHp_star(6);
239 vpMatrix lambda(6, 6);
241 vpTranslationVector stg;
242 vpColVector sHs_bias(6);
248 vpColVector q_dot(6);
252 for (
int i = 0; i < 3; i++)
253 lambda[i][i] = 0.02 / 6;
255 for (
int i = 3; i < 6; i++)
256 lambda[i][i] = 1. / 2;
268 gHg[2] = -(0.696 + 0.476) * 9.81;
275 vpRotationMatrix sRp;
277 vpTranslationVector stp;
280 vpHomogeneousMatrix eMp = eMs * sMp;
281 vpVelocityTwistMatrix eVp(eMp);
285 vpHomogeneousMatrix fMe;
286 vpHomogeneousMatrix fMs;
287 vpRotationMatrix sRf;
288 robot.getPosition(vpRobot::ARTICULAR_FRAME, q);
289 robot.get_fMe(q, fMe);
292 vpHomogeneousMatrix sMf;
298 vpForceTwistMatrix sFg(sMf);
300 for (
int i = 0; i < 3; i++)
301 for (
int j = 0; j < 3; j++)
302 sFg[i + 3][j] = (stg.skew() * sRf)[i][j];
306 vpForceTwistMatrix sFp(sMp);
309 std::cout <<
"\nBias the force/torque sensor...\n " << std::endl;
310 robot.biasForceTorqueSensor();
313 robot.setRobotState(vpRobot::STATE_VELOCITY_CONTROL);
316 t_CaptureState capture_state_;
318 std::cout <<
"Starting control loop..." << std::endl;
320 s_mutex_capture.lock();
321 capture_state_ = s_capture_state;
322 s_mutex_capture.unlock();
325 if (capture_state_ == capture_started) {
328 sHs = robot.getForceTorque();
335 robot.getPosition(vpRobot::ARTICULAR_FRAME, q);
336 robot.get_fMe(q, fMe);
346 for (
int i = 0; i < 3; i++)
347 for (
int j = 0; j < 3; j++)
348 sFg[i + 3][j] = (stg.skew() * sRf)[i][j];
351 sHs_bias = sHs - sFg * gHg;
357 vpMutex::vpScopedLock lock(s_mutex_capture);
358 v_p = s_controlVelocity;
368 v_s = lambda * (sFp * pHp_star - (sHs - sFg * gHg - sHs_bias));
376 vpVelocityTwistMatrix eVs;
379 vpColVector v_e = eVs * v_s + eVp * v_p;
385 q_dot = eJe.pseudoInverse() * v_e;
388 robot.setVelocity(vpRobot::ARTICULAR_FRAME, q_dot);
393 }
while (capture_state_ != capture_stopped);
395 std::cout <<
"End of control thread" << std::endl;
400 int main(
int argc,
const char *argv[])
402 unsigned int opt_input = 1;
405 for (
int i = 0; i < argc; i++) {
406 if (std::string(argv[i]) ==
"--input")
407 opt_input = (
unsigned int)atoi(argv[i + 1]);
408 else if (std::string(argv[i]) ==
"--help") {
409 std::cout <<
"Usage: " << argv[0] <<
" [--input <number>] [--help]" << std::endl;
417 g.setInput(opt_input);
421 s_robotIsRunning =
false;
422 s_controlVelocity = vpColVector(6, 0);
425 vpThread thread_capture((vpThread::Fn)captureFunction, (vpThread::Args)&g);
426 vpThread thread_display((vpThread::Fn)displayFunction);
427 vpThread thread_control((vpThread::Fn)controlFunction);
430 thread_capture.join();
431 thread_display.join();
432 thread_control.join();
441 #ifndef VISP_HAVE_V4L2
442 std::cout <<
"You should enable V4L2 to make this example working..." << std::endl;
443 #elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
444 std::cout <<
"You should enable pthread usage and rebuild ViSP..." << std::endl;
446 std::cout <<
"Multi-threading seems not supported on this platform" << std::endl;
448 #ifndef VISP_HAVE_VIPER850
449 std::cout <<
"You need viper 850 robot to run this example" << std::endl;
void update(const vpImage< unsigned char > &I)
Tracking method, to call at every new frame to track.
void init(const vpImage< unsigned char > &I, const vpRectOriented &R)
Initialisation of the tracker : to call to set the region to track (R) in the image (I) before starti...
vpRectOriented getTarget() const
To call after update() at each new frame, to get the position of the ROI in the last acquired frame.
void setHeightResolution(double heightResolution)
void setData(const vpImage< Type > &image)
double getHeightResolution() const
void setWidthResolution(double widthResolution)
double getWidthResolution() const
static void convert(const usImagePostScan2D< unsigned char > &image, const double &u, const double &v, double &x, double &y)
Conversion for 2D post-scan images.
void setFieldOfView(double fieldOfView)
void setTransducerConvexity(const bool isTransducerConvex)
double getFieldOfView() const
void setDepth(double depth)
void setProbeName(std::string probeName)
void setTransducerRadius(const double transducerRadius)
double getTransducerRadius() const
void setScanLineNumber(unsigned int scanLineNumber)