42#include <visp3/core/vpException.h>
43#include <visp3/core/vpDebug.h>
44#include <visp3/vs/vpServo.h>
48 :
L(),
error(),
J1(),
J1p(),
s(),
sStar(),
e1(),
e(),
q_dot(),
v(),
servoType(
vpServo::
NONE),
rankJ1(0),
53 WpW(),
I_WpW(),
P(),
sv(),
mu(4.),
e1_initial(),
iscJcIdentity(true),
cJc(6, 6),
m_first_iteration(true),
60 :
L(),
error(),
J1(),
J1p(),
s(),
sStar(),
e1(),
e(),
q_dot(),
v(),
servoType(servo_type),
rankJ1(0),
featureList(),
157 if (dof.
size() == 6) {
159 for (
unsigned int i = 0; i < 6; i++) {
160 if (std::fabs(dof[i]) > std::numeric_limits<double>::epsilon()) {
173 switch (displayLevel) {
175 os <<
"Visual servoing task: " << std::endl;
177 os <<
"Type of control law " << std::endl;
180 os <<
"Type of task have not been chosen yet ! " << std::endl;
183 os <<
"Eye-in-hand configuration " << std::endl;
184 os <<
"Control in the camera frame " << std::endl;
187 os <<
"Eye-in-hand configuration " << std::endl;
188 os <<
"Control in the articular frame " << std::endl;
191 os <<
"Eye-to-hand configuration " << std::endl;
192 os <<
"s_dot = _L_cVe_eJe q_dot " << std::endl;
195 os <<
"Eye-to-hand configuration " << std::endl;
196 os <<
"s_dot = _L_cVe_fVe_eJe q_dot " << std::endl;
199 os <<
"Eye-to-hand configuration " << std::endl;
200 os <<
"s_dot = _L_cVf_fJe q_dot " << std::endl;
204 os <<
"List of visual features : s" << std::endl;
205 std::list<vpBasicFeature *>::const_iterator it_s;
206 std::list<vpBasicFeature *>::const_iterator it_s_star;
207 std::list<unsigned int>::const_iterator it_select;
210 ++it_s, ++it_select) {
212 (*it_s)->print((*it_select));
215 os <<
"List of desired visual features : s*" << std::endl;
219 (*it_s_star)->print((*it_select));
222 os <<
"Interaction Matrix Ls " << std::endl;
224 os <<
L << std::endl;
227 os <<
"not yet computed " << std::endl;
230 os <<
"Error vector (s-s*) " << std::endl;
232 os <<
error.t() << std::endl;
235 os <<
"not yet computed " << std::endl;
238 os <<
"Gain : " <<
lambda << std::endl;
244 os <<
"Type of control law " << std::endl;
247 os <<
"Type of task have not been chosen yet ! " << std::endl;
250 os <<
"Eye-in-hand configuration " << std::endl;
251 os <<
"Control in the camera frame " << std::endl;
254 os <<
"Eye-in-hand configuration " << std::endl;
255 os <<
"Control in the articular frame " << std::endl;
258 os <<
"Eye-to-hand configuration " << std::endl;
259 os <<
"s_dot = _L_cVe_eJe q_dot " << std::endl;
262 os <<
"Eye-to-hand configuration " << std::endl;
263 os <<
"s_dot = _L_cVe_fVe_eJe q_dot " << std::endl;
266 os <<
"Eye-to-hand configuration " << std::endl;
267 os <<
"s_dot = _L_cVf_fJe q_dot " << std::endl;
274 os <<
"List of visual features : s" << std::endl;
276 std::list<vpBasicFeature *>::const_iterator it_s;
277 std::list<unsigned int>::const_iterator it_select;
280 ++it_s, ++it_select) {
282 (*it_s)->print((*it_select));
287 os <<
"List of desired visual features : s*" << std::endl;
289 std::list<vpBasicFeature *>::const_iterator it_s_star;
290 std::list<unsigned int>::const_iterator it_select;
295 (*it_s_star)->print((*it_select));
300 os <<
"Gain : " <<
lambda << std::endl;
304 os <<
"Interaction Matrix Ls " << std::endl;
306 os <<
L << std::endl;
309 os <<
"not yet computed " << std::endl;
318 os <<
"Error vector (s-s*) " << std::endl;
320 os <<
error.t() << std::endl;
323 os <<
"not yet computed " << std::endl;
368 unsigned int dim = 0;
369 std::list<vpBasicFeature *>::const_iterator it_s;
370 std::list<unsigned int>::const_iterator it_select;
373 ++it_s, ++it_select) {
374 dim += (*it_s)->getDimension(*it_select);
387static void computeInteractionMatrixFromList(
const std::list<vpBasicFeature *> &featureList,
388 const std::list<unsigned int> &featureSelectionList,
vpMatrix &L)
390 if (featureList.empty()) {
407 unsigned int rowL = L.getRows();
408 const unsigned int colL = 6;
411 L.resize(rowL, colL);
421 unsigned int cursorL = 0;
423 std::list<vpBasicFeature *>::const_iterator it;
424 std::list<unsigned int>::const_iterator it_select;
426 for (it = featureList.begin(), it_select = featureSelectionList.begin(); it != featureList.end(); ++it, ++it_select) {
428 matrixTmp = (*it)->interaction(*it_select);
429 unsigned int rowMatrixTmp = matrixTmp.
getRows();
430 unsigned int colMatrixTmp = matrixTmp.
getCols();
433 while (rowMatrixTmp + cursorL > rowL) {
435 L.resize(rowL, colL,
false);
440 for (
unsigned int k = 0; k < rowMatrixTmp; ++k, ++cursorL) {
441 for (
unsigned int j = 0;
j < colMatrixTmp; ++
j) {
442 L[cursorL][
j] = matrixTmp[k][
j];
447 L.
resize(cursorL, colL,
false);
459 computeInteractionMatrixFromList(this->featureList, this->featureSelectionList,
L);
485 computeInteractionMatrixFromList(this->featureList, this->featureSelectionList,
L);
486 computeInteractionMatrixFromList(this->
desiredFeatureList, this->featureSelectionList, Lstar);
538 unsigned int dimError =
error.getRows();
539 unsigned int dimS =
s.getRows();
540 unsigned int dimSStar =
sStar.getRows();
543 error.resize(dimError);
551 sStar.resize(dimSStar);
561 unsigned int cursorS = 0;
562 unsigned int cursorSStar = 0;
563 unsigned int cursorError = 0;
566 std::list<vpBasicFeature *>::const_iterator it_s;
567 std::list<vpBasicFeature *>::const_iterator it_s_star;
568 std::list<unsigned int>::const_iterator it_select;
571 it_s !=
featureList.end(); ++it_s, ++it_s_star, ++it_select) {
573 desired_s = (*it_s_star);
574 unsigned int select = (*it_select);
577 vectTmp = current_s->
get_s(select);
578 unsigned int dimVectTmp = vectTmp.
getRows();
579 while (dimVectTmp + cursorS > dimS) {
581 s.resize(dimS,
false);
584 for (
unsigned int k = 0; k < dimVectTmp; ++k) {
585 s[cursorS++] = vectTmp[k];
589 vectTmp = desired_s->
get_s(select);
590 dimVectTmp = vectTmp.
getRows();
591 while (dimVectTmp + cursorSStar > dimSStar) {
593 sStar.resize(dimSStar,
false);
595 for (
unsigned int k = 0; k < dimVectTmp; ++k) {
596 sStar[cursorSStar++] = vectTmp[k];
600 vectTmp = current_s->
error(*desired_s, select);
601 dimVectTmp = vectTmp.
getRows();
602 while (dimVectTmp + cursorError > dimError) {
604 error.resize(dimError,
false);
606 for (
unsigned int k = 0; k < dimVectTmp; ++k) {
607 error[cursorError++] = vectTmp[k];
612 s.resize(cursorS,
false);
613 sStar.resize(cursorSStar,
false);
614 error.resize(cursorError,
false);
706 vpERROR_TRACE(
"All the matrices are not correctly initialized");
708 "All the matrices are not correctly"
761 bool imageComputed =
false;
766 imageComputed =
true;
777 WpW.eye(
J1.getCols(),
J1.getCols());
780 if (imageComputed !=
true) {
789 std::cout <<
"rank J1: " <<
rankJ1 << std::endl;
790 imJ1t.
print(std::cout, 10,
"imJ1t");
791 imJ1.
print(std::cout, 10,
"imJ1");
793 WpW.print(std::cout, 10,
"WpW");
794 J1.print(std::cout, 10,
"J1");
795 J1p.print(std::cout, 10,
"J1p");
817 vpERROR_TRACE(
"All the matrices are not correctly initialized");
819 "All the matrices are not correctly"
870 bool imageComputed =
false;
875 imageComputed =
true;
886 WpW.eye(
J1.getCols());
889 if (imageComputed !=
true) {
898 std::cout <<
"rank J1 " <<
rankJ1 << std::endl;
899 std::cout <<
"imJ1t" << std::endl << imJ1t;
900 std::cout <<
"imJ1" << std::endl << imJ1;
902 std::cout <<
"WpW" << std::endl <<
WpW;
903 std::cout <<
"J1" << std::endl <<
J1;
904 std::cout <<
"J1p" << std::endl <<
J1p;
911 if (
m_first_iteration || std::fabs(t) < std::numeric_limits<double>::epsilon()) {
937 vpERROR_TRACE(
"All the matrices are not correctly initialized");
939 "All the matrices are not correctly"
989 bool imageComputed =
false;
994 imageComputed =
true;
1005 WpW.eye(
J1.getCols());
1008 if (imageComputed !=
true) {
1017 std::cout <<
"rank J1 " <<
rankJ1 << std::endl;
1018 std::cout <<
"imJ1t" << std::endl << imJ1t;
1019 std::cout <<
"imJ1" << std::endl << imJ1;
1021 std::cout <<
"WpW" << std::endl <<
WpW;
1022 std::cout <<
"J1" << std::endl <<
J1;
1023 std::cout <<
"J1p" << std::endl <<
J1p;
1030 if (
m_first_iteration || std::fabs(t) < std::numeric_limits<double>::epsilon()) {
1040 I.eye(
J1.getCols());
1053 unsigned int n = J1_.
getCols();
1065 else if (e0_ <= norm_e && norm_e <= e1_)
1066 sig = 1.0 / (1.0 + exp(-12.0 * ((norm_e - e0_) / ((e1_ - e0_))) + 6.0));
1072 double pp = eT_J_JT_e[0][0];
1076 P_ = sig * P_norm_e + (1 - sig) * I_WpW_;
1085 if (!useLargeProjectionOperator) {
1087 vpERROR_TRACE(
"no degree of freedom is free, cannot use secondary task");
1095 I.resize(
J1.getCols(),
J1.getCols());
1100 sec =
I_WpW * de2dt;
1114 const bool &useLargeProjectionOperator)
1118 if (!useLargeProjectionOperator) {
1120 vpERROR_TRACE(
"no degree of freedom is free, cannot use secondary task");
1129 I.resize(
J1.getCols(),
J1.getCols());
1151 const double &rho,
const double &rho1,
const double &lambda_tune)
1153 unsigned int const n =
J1.getCols();
1155 if (qmin.
size() != n || qmax.
size() != n) {
1156 std::stringstream msg;
1157 msg <<
"Dimension vector qmin (" << qmin.
size()
1158 <<
") or qmax () does not correspond to the number of jacobian "
1160 msg <<
"qmin size: " << qmin.
size() << std::endl;
1163 if (q.
size() != n || dq.
size() != n) {
1164 vpERROR_TRACE(
"Dimension vector q or dq does not correspont to the "
1165 "number of jacobian columns");
1167 "the number of jacobian columns"));
1170 double lambda_l = 0.0;
1185 for (
unsigned int i = 0; i < n; i++) {
1186 q_l0_min[i] = qmin[i] + rho * (qmax[i] - qmin[i]);
1187 q_l0_max[i] = qmax[i] - rho * (qmax[i] - qmin[i]);
1189 q_l1_min[i] = q_l0_min[i] - rho * rho1 * (qmax[i] - qmin[i]);
1190 q_l1_max[i] = q_l0_max[i] + rho * rho1 * (qmax[i] - qmin[i]);
1192 if (q[i] < q_l0_min[i])
1194 else if (q[i] > q_l0_max[i])
1200 for (
unsigned int i = 0; i < n; i++) {
1201 if (q[i] > q_l0_min[i] && q[i] < q_l0_max[i])
1212 if (q[i] < q_l1_min[i] || q[i] > q_l1_max[i])
1213 q2_i = -(1 + lambda_tune) * b * Pg_i;
1216 if (q[i] >= q_l0_max[i] && q[i] <= q_l1_max[i])
1217 lambda_l = 1 / (1 + exp(-12 * ((q[i] - q_l0_max[i]) / (q_l1_max[i] - q_l0_max[i])) + 6));
1219 else if (q[i] >= q_l1_min[i] && q[i] <= q_l0_min[i])
1220 lambda_l = 1 / (1 + exp(-12 * ((q[i] - q_l0_min[i]) / (q_l1_min[i] - q_l0_min[i])) + 6));
1222 q2_i = -lambda_l * (1 + lambda_tune) * b * Pg_i;
unsigned int getCols() const
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
unsigned int size() const
Return the number of elements of the 2D array.
unsigned int getRows() const
class that defines what is a visual feature
virtual vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL)
void setDeallocate(vpBasicFeatureDeallocatorType d)
vpColVector get_s(unsigned int select=FEATURE_ALL) const
Get the feature vector .
virtual vpBasicFeature * duplicate() const =0
Implementation of column vector and the associated operations.
double frobeniusNorm() const
@ dimensionError
Bad dimension.
static Type abs(const Type &x)
Implementation of a matrix and operations on matrices.
int print(std::ostream &s, unsigned int length, const std::string &intro="") const
vpColVector getCol(unsigned int j) const
Error that can be emitted by the vpServo class and its derivatives.
@ servoError
Other exception.
@ noDofFree
No degree of freedom is available to achieve the secondary task.
@ noFeatureError
Current or desired feature list is empty.
vpColVector q_dot
Articular velocity.
unsigned int rankJ1
Rank of the task Jacobian.
vpMatrix eJe
Jacobian expressed in the end-effector frame (e).
int signInteractionMatrix
vpMatrix WpW
Projection operators .
vpVelocityTwistMatrix cVf
Twist transformation matrix between camera frame (c) and robot base frame (f).
vpMatrix J1
Task Jacobian .
void setCameraDoF(const vpColVector &dof)
bool errorComputed
true if the error has been computed.
vpMatrix fJe
Jacobian expressed in the robot base frame (f).
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
@ EYETOHAND_L_cVf_fVe_eJe
unsigned int getDimension() const
vpVelocityTwistMatrix cVe
void addFeature(vpBasicFeature &s_cur, vpBasicFeature &s_star, unsigned int select=vpBasicFeature::FEATURE_ALL)
void set_cVe(const vpVelocityTwistMatrix &cVe_)
vpColVector e1
Primary task .
bool forceInteractionMatrixComputation
Force the interaction matrix computation even if it is already done.
vpColVector secondaryTaskJointLimitAvoidance(const vpColVector &q, const vpColVector &dq, const vpColVector &qmin, const vpColVector &qmax, const double &rho=0.1, const double &rho1=0.3, const double &lambda_tune=0.7)
void print(const vpServo::vpServoPrintType display_level=ALL, std::ostream &os=std::cout)
vpVelocityTwistMatrix fVe
void set_eJe(const vpMatrix &eJe_)
vpColVector secondaryTask(const vpColVector &de2dt, const bool &useLargeProjectionOperator=false)
bool taskWasKilled
Flag to indicate if the task was killed.
bool testInitialization()
void setServo(const vpServoType &servo_type)
std::list< vpBasicFeature * > featureList
List of current visual features .
bool iscJcIdentity
Boolean to know if cJc is identity (for fast computation).
vpMatrix I_WpW
Projection operators .
vpColVector v
Camera velocity.
vpMatrix computeInteractionMatrix()
vpMatrix J1p
Pseudo inverse of the task Jacobian.
vpMatrix I
Identity matrix.
void computeProjectionOperators(const vpMatrix &J1_, const vpMatrix &I_, const vpMatrix &I_WpW_, const vpColVector &error_, vpMatrix &P_) const
std::list< vpBasicFeature * > desiredFeatureList
List of desired visual features .
bool m_first_iteration
True until first call of computeControlLaw() is achieved.
vpMatrix L
Interaction matrix.
vpServoType servoType
Chosen visual servoing control law.
vpServoIteractionMatrixType interactionMatrixType
Type of the interaction matrix (current, mean, desired, user).
double m_pseudo_inverse_threshold
Threshold used in the pseudo inverse.
std::list< unsigned int > featureSelectionList
vpColVector computeControlLaw()
@ ALL
Print all the task information.
@ CONTROLLER
Print the type of controller law.
@ ERROR_VECTOR
Print the error vector .
@ FEATURE_CURRENT
Print the current features .
@ FEATURE_DESIRED
Print the desired features .
@ MINIMUM
Same as vpServo::vpServoPrintType::ERROR_VECTOR.
@ INTERACTION_MATRIX
Print the interaction matrix.
vpServo(const vpServo &)=delete
vpColVector sv
Singular values from the pseudo inverse.
vpServoIteractionMatrixType
bool interactionMatrixComputed
true if the interaction matrix has been computed.
vpColVector computeError()
unsigned int dim_task
Dimension of the task updated during computeControlLaw().
vpServoInversionType inversionType
vpAdaptiveGain lambda
Gain used in the control law.