Example that shows how to control the Pioneer mobile robot by IBVS visual servoing with respect to a segment. The segment consists in two horizontal dots. The current visual features that are used are . The desired one are , with:
The depth of the points is estimated from the surface of the blob.
#include <iostream>
#include <visp/vpConfig.h>
#include <visp/vpRobotPioneer.h>
#include <visp/vpRobotBiclops.h>
#include <visp/vpCameraParameters.h>
#include <visp/vpDisplayGDI.h>
#include <visp/vpDisplayX.h>
#include <visp/vpDot2.h>
#include <visp/vpFeatureBuilder.h>
#include <visp/vpFeatureSegment.h>
#include <visp/vpHomogeneousMatrix.h>
#include <visp/vpImage.h>
#include <visp/vp1394TwoGrabber.h>
#include <visp/vp1394CMUGrabber.h>
#include <visp/vpV4l2Grabber.h>
#include <visp/vpPioneerPan.h>
#include <visp/vpPlot.h>
#include <visp/vpServo.h>
#include <visp/vpVelocityTwistMatrix.h>
#define USE_REAL_ROBOT
#define USE_PLOTTER
#undef VISP_HAVE_V4L2 // To use a firewire camera
#if defined(VISP_HAVE_PIONEER) && defined(VISP_HAVE_BICLOPS)
int main(int argc, char **argv)
{
#if defined(VISP_HAVE_DC1394_2) || defined(VISP_HAVE_V4L2) || defined(VISP_HAVE_CMU1394)
#if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI)
try {
double lambda = 0.1;
double coef = 1.2/13.0;
double L = 0.21;
double Z_d = 0.8;
bool normalized = true;
double Y_d = -.11;
qm = 0;
double qm_pan = 0;
#ifdef USE_REAL_ROBOT
q=0;
qm_pan = qm[0];
ArArgumentParser parser(&argc, argv);
parser.loadDefaultArguments();
ArRobotConnector robotConnector(&parser, &pioneer);
if(!robotConnector.connectRobot())
{
ArLog::log(ArLog::Terse, "Could not connect to the pioneer robot.");
if(parser.checkHelpAndWarnUnparsed())
{
Aria::logOptions();
Aria::exit(1);
}
}
if (!Aria::parseArgs())
{
Aria::logOptions();
Aria::shutdown();
return false;
}
sleep(3);
std::cout << "Pioneer robot connected" << std::endl;
#endif
#if defined(VISP_HAVE_V4L2)
#elif defined(VISP_HAVE_DC1394_2)
#elif defined(VISP_HAVE_CMU1394)
#endif
#if defined(VISP_HAVE_X11)
#elif defined(VISP_HAVE_GDI)
#endif
for (int i=0; i <2; i++)
{
}
std::cout << "cVe: \n" << cVe << std::endl;
std::cout << "eJe: \n" << eJe << std::endl;
for (int i=0; i <2; i++)
{
}
double surface[2];
double Z[2];
for (int i=0; i<2; i++)
{
surface[i] = 1./sqrt(dot[i].m00/(cam.
get_px()*cam.
get_py()));
Z[i] = coef * surface[i] ;
}
s_segment.setZ1(Z[0]);
s_segment.setZ2(Z[1]);
s_segment.setZ1( P[0].get_Z() );
s_segment.setZ2( P[1].get_Z() );
#ifdef USE_PLOTTER
vpPlot graph(2, 500, 500, 700, 10,
"Curves...");
#endif
unsigned int iter = 0;
try
{
while(1)
{
#ifdef USE_REAL_ROBOT
#endif
qm_pan = qm[0];
for (int i=0; i<2; i++)
for (int i=0; i<2; i++)
dot[i].track(I);
for (int i=0; i<2; i++)
{
surface[i] = 1./sqrt(dot[i].m00/(cam.
get_px()*cam.
get_py()));
Z[i] = coef * surface[i] ;
}
s_segment.setZ1(Z[0]);
s_segment.setZ2(Z[1]);
std::cout <<
"Warning: task is of rank " << task.
getTaskRank() << std::endl;
#ifdef USE_PLOTTER
#endif
#ifdef USE_REAL_ROBOT
v_pioneer[0] = v[0];
v_pioneer[1] = v[1];
v_biclops[0] = v[2];
v_biclops[1] = 0;
std::cout << "Send velocity to the pionner: " << v_pioneer[0] << " m/s "
std::cout <<
"Send velocity to the biclops head: " <<
vpMath::deg(v_biclops[0]) <<
" deg/s" << std::endl;
#endif
break;
iter ++;
}
}
catch(...)
{
}
#ifdef USE_REAL_ROBOT
std::cout << "Ending robot thread..." << std::endl;
pioneer.stopRunning();
pioneer.waitForRunExit();
#endif
}
std::cout << "Catch an exception: " << e << std::endl;
return 1;
}
#endif
#endif
}
#else
int main()
{
std::cout << "ViSP is not able to control the Pioneer robot" << std::endl;
return 0;
}
#endif