48 #include <visp/vpTime.h>
50 #include <visp/vpConfig.h>
52 #ifdef VISP_HAVE_BICLOPS
54 #include <visp/vpBiclops.h>
55 #include <visp/vpRobotBiclops.h>
56 #include <visp/vpRobotException.h>
57 #include <visp/vpExponentialMap.h>
61 #include <visp/vpDebug.h>
67 bool vpRobotBiclops::robotAlreadyCreated =
false;
70 static pthread_mutex_t vpEndThread_mutex;
71 static pthread_mutex_t vpShm_mutex;
72 static pthread_mutex_t vpMeasure_mutex;
122 vpRobotBiclops::robotAlreadyCreated =
false;
123 controlThreadCreated =
false;
127 pthread_mutex_init (&vpShm_mutex, NULL);
128 pthread_mutex_init (&vpEndThread_mutex, NULL);
129 pthread_mutex_init (&vpMeasure_mutex, NULL);
171 vpRobotBiclops::robotAlreadyCreated =
false;
172 controlThreadCreated =
false;
176 pthread_mutex_init (&vpShm_mutex, NULL);
177 pthread_mutex_init (&vpEndThread_mutex, NULL);
178 pthread_mutex_init (&vpMeasure_mutex
196 vpDEBUG_TRACE(12,
"Start vpRobotBiclops::~vpRobotBiclops()");
200 pthread_mutex_unlock(&vpEndThread_mutex);
206 if (controlThreadCreated ==
true) {
207 code = pthread_join(control_thread, NULL);
209 vpCERROR <<
"Cannot terminate the control thread: " << code
210 <<
" strErr=" << strerror(errno)
211 <<
" strCode=" << strerror(code)
216 pthread_mutex_destroy (&vpShm_mutex);
217 pthread_mutex_destroy (&vpEndThread_mutex);
218 pthread_mutex_destroy (&vpMeasure_mutex);
220 vpRobotBiclops::robotAlreadyCreated =
false;
239 sprintf(configfile,
"%s", filename);
255 FILE *fd = fopen(configfile,
"r");
257 vpCERROR <<
"Cannot open biclops config file: " << configfile << std::endl;
259 "Cannot open connexion with biclops");
264 controller.
init(configfile);
276 vpRobotBiclops::robotAlreadyCreated =
true;
284 controlThreadCreated =
false;
314 vpRobotBiclopsController::shmType shm;
338 pthread_mutex_lock(&vpShm_mutex);
343 pthread_mutex_unlock(&vpShm_mutex);
346 prev_q_dot [i] = shm.q_dot[i];
347 new_q_dot [i] =
false;
348 change_dir [i] =
false;
349 force_halt [i] =
false;
350 enable_limit[i] =
true;
358 pthread_mutex_lock(&vpShm_mutex);
363 shm.actual_q[i] = mes_q[i];
364 shm.actual_q_dot[i] = mes_q_dot[i];
370 pthread_mutex_unlock(&vpShm_mutex);
373 pthread_mutex_unlock(&vpMeasure_mutex);
382 pthread_mutex_lock(&vpShm_mutex);
389 shm.actual_q[i] = mes_q[i];
390 shm.actual_q_dot[i] = mes_q_dot[i];
408 if (mes_q[i] < -softLimit[i]) {
411 shm.jointLimit[i] =
true;
413 else if (mes_q[i] > softLimit[i]) {
416 shm.jointLimit[i] =
true;
420 shm.jointLimit[i] =
false;
425 if (std::fabs(shm.q_dot[i] - prev_q_dot[i]) > std::fabs(
vpMath::maximum(shm.q_dot[i],prev_q_dot[i]))*std::numeric_limits<double>::epsilon())
428 new_q_dot[i] =
false;
431 if ((shm.q_dot[i] * prev_q_dot[i]) < 0.)
432 change_dir[i] =
true;
434 change_dir[i] =
false;
437 vpDEBUG_TRACE(13,
"status : %d %d", shm.status[0], shm.status[1]);
438 vpDEBUG_TRACE(13,
"joint : %d %d", shm.jointLimit[0], shm.jointLimit[1]);
439 vpDEBUG_TRACE(13,
"new q_dot : %d %d", new_q_dot[0], new_q_dot[1]);
440 vpDEBUG_TRACE(13,
"new dir : %d %d", change_dir[0], change_dir[1]);
441 vpDEBUG_TRACE(13,
"force halt : %d %d", force_halt[0], force_halt[1]);
442 vpDEBUG_TRACE(13,
"enable limit: %d %d", enable_limit[0], enable_limit[1]);
445 bool updateVelocity =
false;
452 if (change_dir[i] ==
false) {
455 if (enable_limit[i] ==
true) {
458 if (force_halt[i] ==
false) {
460 force_halt[i] =
true;
461 updateVelocity =
true;
467 q_dot[i] = shm.q_dot[i];
469 force_halt[i] =
false;
470 updateVelocity =
true;
475 if (enable_limit[i] ==
true) {
477 q_dot[i] = shm.q_dot[i];
479 force_halt[i] =
false;
480 enable_limit[i] =
false;
481 updateVelocity =
true;
486 if (force_halt[i] ==
false) {
488 force_halt[i] =
true;
489 enable_limit[i] =
true;
490 updateVelocity =
true;
499 q_dot[i] = shm.q_dot[i];
501 enable_limit[i] =
true;
502 updateVelocity =
true;
509 if (enable_limit[i] ==
true) {
512 if (force_halt[i] ==
false) {
515 force_halt[i] =
true;
516 updateVelocity =
true;
522 enable_limit[i] =
true;
530 pthread_mutex_unlock(&vpShm_mutex);
532 if (updateVelocity) {
544 prev_q_dot[i] = shm.q_dot[i];
565 vpDEBUG_TRACE(10,
"End of the control thread: stop the robot");
570 delete [] change_dir;
571 delete [] force_halt;
572 delete [] enable_limit;
574 pthread_mutex_unlock(&vpEndThread_mutex);
618 pthread_mutex_lock(&vpEndThread_mutex);
622 code = pthread_create(&control_thread, NULL,
626 vpCERROR <<
"Cannot create speed biclops control thread: " << code
627 <<
" strErr=" << strerror(errno)
628 <<
" strCode=" << strerror(code)
632 controlThreadCreated =
true;
759 if (velocity < 0 || velocity > 100) {
762 "Bad positionning velocity");
765 positioningVelocity = velocity;
777 return positioningVelocity;
804 "Modification of the robot state");
814 "Cannot move the robot in camera frame: "
821 "Cannot move the robot in reference frame: "
828 "Cannot move the robot in mixt frame: "
844 pthread_mutex_lock(&vpEndThread_mutex);
847 pthread_mutex_unlock(&vpEndThread_mutex);
868 const double &q1,
const double &q2)
904 "Cannot get biclops position from file");
931 vpERROR_TRACE (
"Cannot get position in camera frame: not implemented");
933 "Cannot get position in camera frame: "
940 "Cannot get position in reference frame: "
947 "Cannot get position in mixt frame: "
969 pthread_mutex_lock(&vpMeasure_mutex);
971 vpRobotBiclopsController::shmType shm;
974 pthread_mutex_lock(&vpShm_mutex);
979 pthread_mutex_unlock(&vpShm_mutex);
982 q[i] = shm.actual_q[i];
985 vpCDEBUG(11) <<
"++++++++ Measure actuals: " << q.
t();
988 pthread_mutex_unlock(&vpMeasure_mutex);
1029 "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1031 "Cannot send a velocity to the robot "
1032 "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1040 "in the camera frame: "
1041 "functionality not implemented");
1043 "Cannot send a velocity to the robot "
1044 "in the camera frame:"
1045 "functionality not implemented");
1051 vpERROR_TRACE (
"Bad dimension fo speed vector in articular frame");
1053 "Bad dimension for speed vector "
1054 "in articular frame");
1061 "in the reference frame: "
1062 "functionality not implemented");
1064 "Cannot send a velocity to the robot "
1065 "in the reference frame:"
1066 "functionality not implemented");
1072 "in the mixt frame: "
1073 "functionality not implemented");
1075 "Cannot send a velocity to the robot "
1076 "in the mixt frame:"
1077 "functionality not implemented");
1083 "Case not taken in account.");
1085 "Cannot send a velocity to the robot ");
1101 if (fabs (q_dot[i]) > max)
1104 max = fabs (q_dot[i]);
1112 q_dot_sat = q_dot * max;
1115 vpCDEBUG(12) <<
"send velocity: " << q_dot_sat.
t() << std::endl;
1117 vpRobotBiclopsController::shmType shm;
1120 pthread_mutex_lock(&vpShm_mutex);
1125 shm.q_dot[i] = q_dot[i];
1130 pthread_mutex_unlock(&vpShm_mutex);
1159 vpERROR_TRACE (
"Cannot get position in camera frame: not implemented");
1161 "Cannot get position in camera frame: "
1168 "Cannot get position in reference frame: "
1175 "Cannot get position in mixt frame: "
1197 pthread_mutex_lock(&vpMeasure_mutex);
1199 vpRobotBiclopsController::shmType shm;
1202 pthread_mutex_lock(&vpShm_mutex);
1207 pthread_mutex_unlock(&vpShm_mutex);
1210 q_dot[i] = shm.actual_q_dot[i];
1213 vpCDEBUG(11) <<
"++++++++ Velocity actuals: " << q_dot.
t();
1216 pthread_mutex_unlock(&vpMeasure_mutex);
1267 pt_f = fopen(filename,
"r") ;
1270 vpERROR_TRACE (
"Can not open biclops position file %s", filename);
1274 char line[FILENAME_MAX];
1280 if (fgets (line, 100, pt_f) != NULL) {
1281 if ( strncmp (line,
"#", 1) != 0) {
1283 if ( fscanf (pt_f,
"%s", line) != EOF) {
1284 if ( strcmp (line, head) == 0)
1296 while ( end !=
true );
1300 if (fscanf(pt_f,
"%lf %lf", &q1, &q2) == EOF) {
1301 std::cout <<
"Cannot read joint positions." << std::endl;
1326 vpRobotBiclops::getCameraDisplacement(
vpColVector &d)
1342 void vpRobotBiclops::getArticularDisplacement(
vpColVector &d)
1382 d = q_current - q_previous;
1394 c_previousMc_current = fMc_previous.
inverse() * fMc_current;
1402 vpERROR_TRACE (
"Cannot get a velocity in the reference frame: "
1403 "functionality not implemented");
1405 "Cannot get a velocity in the reference frame:"
1406 "functionality not implemented");
1410 "functionality not implemented");
1412 "Cannot get a velocity in the mixt frame:"
1413 "functionality not implemented");
1418 q_previous = q_current;
static vpColVector inverse(const vpHomogeneousMatrix &M)
Definition of the vpMatrix class.
void setVelocity(const vpColVector &q_dot)
void stopRequest(bool stop)
void get_eJe(const vpColVector &q, vpMatrix &eJe)
vpColVector getPosition()
Error that can be emited by the vpRobot class and its derivates.
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &q_dot)
void getPosition(const vpRobot::vpControlFrameType frame, vpColVector &q)
static const unsigned int ndof
void get_eJe(vpMatrix &_eJe)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
static const float tiltJointLimit
void getVelocity(const vpRobot::vpControlFrameType frame, vpColVector &q_dot)
static const float speedLimit
virtual vpRobotStateType getRobotState(void)
Initialize the position controller.
class that defines a generic virtual robot
void get_fJe(vpMatrix &_fJe)
static const double defaultPositioningVelocity
static int wait(double t0, double t)
vpColVector getActualVelocity()
void writeShm(shmType &shm)
virtual ~vpRobotBiclops(void)
virtual vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
vpRobot::vpRobotStateType setRobotState(const vpRobot::vpRobotStateType newState)
static Type maximum(const Type &a, const Type &b)
static const float panJointLimit
void get_cVe(vpVelocityTwistMatrix &_cVe)
vpColVector getVelocity()
void get_fMc(const vpColVector &q, vpHomogeneousMatrix &fMc)
Initialize the velocity controller.
Initialize the acceleration controller.
vpVelocityTwistMatrix buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
void init(const char *configfile)
void setPosition(const vpColVector &q, const double percentVelocity)
void get_fJe(const vpColVector &q, vpMatrix &fJe)
bool readPositionFile(const char *filename, vpColVector &q)
vpRowVector t() const
transpose of Vector
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
static double rad(double deg)
static double deg(double rad)
void setConfigFile(const char *filename="/usr/share/BiclopsDefault.cfg")
Class that provides a data structure for the column vectors as well as a set of operations on these v...
void getDisplacement(const vpRobot::vpControlFrameType frame, vpColVector &d)
vpHomogeneousMatrix inverse() const
Interface to Biclops, pan, tilt, verge head for computer vision applications.
double getPositioningVelocity(void)
void setPosition(const vpRobot::vpControlFrameType frame, const vpColVector &q)
vpColVector getActualPosition()
unsigned int getRows() const
Return the number of rows of the matrix.
static void * vpRobotBiclopsSpeedControlLoop(void *arg)
vpHomogeneousMatrix get_cMe() const
void setPositioningVelocity(const double velocity)
void resize(const unsigned int i, const bool flagNullify=true)