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);
173 vpRobotBiclops::robotAlreadyCreated =
false;
174 controlThreadCreated =
false;
178 pthread_mutex_init (&vpShm_mutex, NULL);
179 pthread_mutex_init (&vpEndThread_mutex, NULL);
180 pthread_mutex_init (&vpMeasure_mutex, NULL);
199 vpDEBUG_TRACE(12,
"Start vpRobotBiclops::~vpRobotBiclops()");
203 pthread_mutex_unlock(&vpEndThread_mutex);
209 if (controlThreadCreated ==
true) {
210 code = pthread_join(control_thread, NULL);
212 vpCERROR <<
"Cannot terminate the control thread: " << code
213 <<
" strErr=" << strerror(errno)
214 <<
" strCode=" << strerror(code)
219 pthread_mutex_destroy (&vpShm_mutex);
220 pthread_mutex_destroy (&vpEndThread_mutex);
221 pthread_mutex_destroy (&vpMeasure_mutex);
223 vpRobotBiclops::robotAlreadyCreated =
false;
242 sprintf(configfile,
"%s", filename);
258 FILE *fd = fopen(configfile,
"r");
260 vpCERROR <<
"Cannot open biclops config file: " << configfile << std::endl;
262 "Cannot open connexion with biclops");
267 controller.
init(configfile);
279 vpRobotBiclops::robotAlreadyCreated =
true;
285 controlThreadCreated =
false;
315 vpRobotBiclopsController::shmType shm;
339 pthread_mutex_lock(&vpShm_mutex);
344 pthread_mutex_unlock(&vpShm_mutex);
347 prev_q_dot [i] = shm.q_dot[i];
348 new_q_dot [i] =
false;
349 change_dir [i] =
false;
350 force_halt [i] =
false;
351 enable_limit[i] =
true;
359 pthread_mutex_lock(&vpShm_mutex);
364 shm.actual_q[i] = mes_q[i];
365 shm.actual_q_dot[i] = mes_q_dot[i];
371 pthread_mutex_unlock(&vpShm_mutex);
374 pthread_mutex_unlock(&vpMeasure_mutex);
383 pthread_mutex_lock(&vpShm_mutex);
390 shm.actual_q[i] = mes_q[i];
391 shm.actual_q_dot[i] = mes_q_dot[i];
409 if (mes_q[i] < -softLimit[i]) {
412 shm.jointLimit[i] =
true;
414 else if (mes_q[i] > softLimit[i]) {
417 shm.jointLimit[i] =
true;
421 shm.jointLimit[i] =
false;
426 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())
429 new_q_dot[i] =
false;
432 if ((shm.q_dot[i] * prev_q_dot[i]) < 0.)
433 change_dir[i] =
true;
435 change_dir[i] =
false;
438 vpDEBUG_TRACE(13,
"status : %d %d", shm.status[0], shm.status[1]);
439 vpDEBUG_TRACE(13,
"joint : %d %d", shm.jointLimit[0], shm.jointLimit[1]);
440 vpDEBUG_TRACE(13,
"new q_dot : %d %d", new_q_dot[0], new_q_dot[1]);
441 vpDEBUG_TRACE(13,
"new dir : %d %d", change_dir[0], change_dir[1]);
442 vpDEBUG_TRACE(13,
"force halt : %d %d", force_halt[0], force_halt[1]);
443 vpDEBUG_TRACE(13,
"enable limit: %d %d", enable_limit[0], enable_limit[1]);
446 bool updateVelocity =
false;
453 if (change_dir[i] ==
false) {
456 if (enable_limit[i] ==
true) {
459 if (force_halt[i] ==
false) {
461 force_halt[i] =
true;
462 updateVelocity =
true;
468 q_dot[i] = shm.q_dot[i];
470 force_halt[i] =
false;
471 updateVelocity =
true;
476 if (enable_limit[i] ==
true) {
478 q_dot[i] = shm.q_dot[i];
480 force_halt[i] =
false;
481 enable_limit[i] =
false;
482 updateVelocity =
true;
487 if (force_halt[i] ==
false) {
489 force_halt[i] =
true;
490 enable_limit[i] =
true;
491 updateVelocity =
true;
500 q_dot[i] = shm.q_dot[i];
502 enable_limit[i] =
true;
503 updateVelocity =
true;
510 if (enable_limit[i] ==
true) {
513 if (force_halt[i] ==
false) {
516 force_halt[i] =
true;
517 updateVelocity =
true;
523 enable_limit[i] =
true;
531 pthread_mutex_unlock(&vpShm_mutex);
533 if (updateVelocity) {
545 prev_q_dot[i] = shm.q_dot[i];
566 vpDEBUG_TRACE(10,
"End of the control thread: stop the robot");
571 delete [] change_dir;
572 delete [] force_halt;
573 delete [] enable_limit;
575 pthread_mutex_unlock(&vpEndThread_mutex);
619 pthread_mutex_lock(&vpEndThread_mutex);
623 code = pthread_create(&control_thread, NULL,
627 vpCERROR <<
"Cannot create speed biclops control thread: " << code
628 <<
" strErr=" << strerror(errno)
629 <<
" strCode=" << strerror(code)
633 controlThreadCreated =
true;
760 if (velocity < 0 || velocity > 100) {
763 "Bad positionning velocity");
766 positioningVelocity = velocity;
778 return positioningVelocity;
805 "Modification of the robot state");
815 "Cannot move the robot in camera frame: "
822 "Cannot move the robot in reference frame: "
829 "Cannot move the robot in mixt frame: "
845 pthread_mutex_lock(&vpEndThread_mutex);
848 pthread_mutex_unlock(&vpEndThread_mutex);
869 const double &q1,
const double &q2)
905 "Cannot get biclops position from file");
932 vpERROR_TRACE (
"Cannot get position in camera frame: not implemented");
934 "Cannot get position in camera frame: "
941 "Cannot get position in reference frame: "
948 "Cannot get position in mixt frame: "
970 pthread_mutex_lock(&vpMeasure_mutex);
972 vpRobotBiclopsController::shmType shm;
975 pthread_mutex_lock(&vpShm_mutex);
980 pthread_mutex_unlock(&vpShm_mutex);
983 q[i] = shm.actual_q[i];
986 vpCDEBUG(11) <<
"++++++++ Measure actuals: " << q.
t();
989 pthread_mutex_unlock(&vpMeasure_mutex);
1030 "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1032 "Cannot send a velocity to the robot "
1033 "use setRobotState(vpRobot::STATE_VELOCITY_CONTROL) first) ");
1041 "in the camera frame: "
1042 "functionality not implemented");
1044 "Cannot send a velocity to the robot "
1045 "in the camera frame:"
1046 "functionality not implemented");
1052 vpERROR_TRACE (
"Bad dimension fo speed vector in articular frame");
1054 "Bad dimension for speed vector "
1055 "in articular frame");
1062 "in the reference frame: "
1063 "functionality not implemented");
1065 "Cannot send a velocity to the robot "
1066 "in the reference frame:"
1067 "functionality not implemented");
1073 "in the mixt frame: "
1074 "functionality not implemented");
1076 "Cannot send a velocity to the robot "
1077 "in the mixt frame:"
1078 "functionality not implemented");
1084 "Case not taken in account.");
1086 "Cannot send a velocity to the robot ");
1102 if (fabs (q_dot[i]) > max)
1105 max = fabs (q_dot[i]);
1113 q_dot_sat = q_dot * max;
1116 vpCDEBUG(12) <<
"send velocity: " << q_dot_sat.
t() << std::endl;
1118 vpRobotBiclopsController::shmType shm;
1121 pthread_mutex_lock(&vpShm_mutex);
1126 shm.q_dot[i] = q_dot[i];
1131 pthread_mutex_unlock(&vpShm_mutex);
1160 vpERROR_TRACE (
"Cannot get position in camera frame: not implemented");
1162 "Cannot get position in camera frame: "
1169 "Cannot get position in reference frame: "
1176 "Cannot get position in mixt frame: "
1198 pthread_mutex_lock(&vpMeasure_mutex);
1200 vpRobotBiclopsController::shmType shm;
1203 pthread_mutex_lock(&vpShm_mutex);
1208 pthread_mutex_unlock(&vpShm_mutex);
1211 q_dot[i] = shm.actual_q_dot[i];
1214 vpCDEBUG(11) <<
"++++++++ Velocity actuals: " << q_dot.
t();
1217 pthread_mutex_unlock(&vpMeasure_mutex);
1268 pt_f = fopen(filename,
"r") ;
1271 vpERROR_TRACE (
"Can not open biclops position file %s", filename);
1275 char line[FILENAME_MAX];
1281 if (fgets (line, 100, pt_f) != NULL) {
1282 if ( strncmp (line,
"#", 1) != 0) {
1284 if ( fscanf (pt_f,
"%s", line) != EOF) {
1285 if ( strcmp (line, head) == 0)
1300 while ( end !=
true );
1304 if (fscanf(pt_f,
"%lf %lf", &q1, &q2) == EOF) {
1306 std::cout <<
"Cannot read joint positions." << std::endl;
1331 vpRobotBiclops::getCameraDisplacement(
vpColVector &d)
1347 void vpRobotBiclops::getArticularDisplacement(
vpColVector &d)
1387 d = q_current - q_previous;
1399 c_previousMc_current = fMc_previous.
inverse() * fMc_current;
1407 vpERROR_TRACE (
"Cannot get a velocity in the reference frame: "
1408 "functionality not implemented");
1410 "Cannot get a velocity in the reference frame:"
1411 "functionality not implemented");
1415 "functionality not implemented");
1417 "Cannot get a velocity in the mixt frame:"
1418 "functionality not implemented");
1423 q_previous = q_current;
void get_cVe(vpVelocityTwistMatrix &_cVe) const
static vpColVector inverse(const vpHomogeneousMatrix &M)
Definition of the vpMatrix class.
void setVelocity(const vpColVector &q_dot)
void stopRequest(bool stop)
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
Initialize the position controller.
class that defines a generic virtual robot
void get_fJe(vpMatrix &_fJe)
void get_fMc(const vpColVector &q, vpHomogeneousMatrix &fMc) const
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
vpColVector getVelocity()
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)
bool readPositionFile(const char *filename, vpColVector &q)
vpRowVector t() const
Transpose of a vector.
Class that consider the particular case of twist transformation matrix that allows to transform a vel...
static double rad(double deg)
void get_fJe(const vpColVector &q, vpMatrix &fJe) const
void get_eJe(const vpColVector &q, vpMatrix &eJe) const
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
virtual vpRobotStateType getRobotState(void) 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)