GenericFeature

class GenericFeature(self, dim: int)

Bases: BasicFeature

Class that enables to define a feature or a set of features which are not implemented in ViSP as a specific class. It is indeed possible to create its own features, to use the corresponding interaction matrix, and to compute an error between the current and the desired feature. Moreover the created features can be mixed with features already implemented.

The following example shows how to use the vpGenericFeature class to create and use the feature \(log(Z)\) where Z corresponds to the depth of a point whose 2D coordinates in the camera frame are \(x\) and \(y\) . The interaction matrix corresponding to this feature is

\[L = \left[\begin{array}{cccccc} 0 & 0 & -1/Z & -y & x & 0 \end{array}\right]\]

.

#include <visp3/core/vpGenericFeature.h>
#include <visp3/vs/vpServo.h>

int main()
{
  vpServo task; // Visual servoing task

  //First we have to define the desired feature log(Z*) corresponding to the desired point.
  double xd = 0; //The x coordinate of the desired point.
  double yd = 0; //The y coordinate of the desired point.
  double Zd = 1; //The depth of the desired point.
  vpGenericFeature logZd(1); //The dimension of the feature is 1.
  logZd.set_s( log(Zd) );

  //Then we have to define the current feature log(Z) corresponding to the current point.
  double x = 1; //The x coordinate of the current point.
  double y = 1; //The y coordinate of the current point.
  double Z = 2; //The depth of the current point.
  vpGenericFeature logZ(1); //The dimension of the feature is 1.
  logZ.set_s( log(Z) );

  // Set eye-in-hand control law.
  // The computed velocities will be expressed in the camera frame
  task.setServo(vpServo::EYEINHAND_CAMERA);
  // Interaction matrix is computed with the current visual features sd
  task.setInteractionMatrixType(vpServo::CURRENT);

  // Add the point feature to the task
  task.addFeature(logZ, logZd);

  // Control loop
  for ( ; ; ) {
    // The new parameters x, y and Z must be computed here.

    // Update the current point visual feature
    logZ.set_s( log(Z) ) ;

    // We have to compute the interaction matrix corresponding to the feature.
    vpMatrix LlogZ(1,6) ;
    LlogZ[0][0] = LlogZ[0][1] = LlogZ[0][5] = 0 ;
    LlogZ[0][2] = -1/Z;
    LlogZ[0][3] = -y;
    LlogZ[0][4] =  x;
    logZ.setInteractionMatrix(LlogZ) ;

    // compute the control law
    vpColVector v = task.computeControlLaw(); // camera velocity
  }
  return 0;
}

The second example shows how to create and use a feature whose specificity is to have a desired feature fixed to zero. It is the case for the feature \(log( \frac{Z}{Z^*})\) .

#include <visp3/core/vpGenericFeature.h>
#include <visp3/vs/vpServo.h>

int main()
{
  vpServo task; // Visual servoing task

  //First we have to define the desired feature log(Z*) corresponding to the desired point.
  double xd = 0; //The x coordinate of the desired point.
  double yd = 0; //The y coordinate of the desired point.
  double Zd = 1; //The depth of the desired point.

  //Then we have to define the current feature log(Z) corresponding to the current point.
  double x = 1; //The x coordinate of the current point.
  double y = 1; //The y coordinate of the current point.
  double Z = 2; //The depth of the current point.
  vpGenericFeature logZ(1); //The dimension of the feature is 1.
  logZ.set_s( log(Z/Zd) );

  // Set eye-in-hand control law.
  // The computed velocities will be expressed in the camera frame
  task.setServo(vpServo::EYEINHAND_CAMERA);
  // Interaction matrix is computed with the current visual features sd
  task.setInteractionMatrixType(vpServo::CURRENT);

  // Add the point feature to the task
  task.addFeature(logZ);

  // Control loop
  for ( ; ; ) {
    // The new parameters x, y and Z must be computed here.

    // Update the current point visual feature
    logZ.set_s( log(Z/Zd) ) ;

    // We have to compute the interaction matrix corresponding to the feature.
    vpMatrix LlogZ(1,6) ;
    LlogZ[0][0] = LlogZ[0][1] = LlogZ[0][5] = 0 ;
    LlogZ[0][2] = -1/Z;
    LlogZ[0][3] = -y;
    LlogZ[0][4] =  x;
    logZ.setInteractionMatrix(LlogZ) ;

    // compute the control law
    vpColVector v = task.computeControlLaw(); // camera velocity
  }
  return 0;
}

If the feature needs to be use with other features, the example servoSimuPoint2DhalfCamVelocity2.cpp shows how to do it.

Constructor of the class you have to use. The feature table is initilialized with the good dimension.

Methods

__init__

Constructor of the class you have to use.

display

Overloaded function.

error

Overloaded function.

getInteractionMatrix

get_s

Overloaded function.

init

interaction

Compute and return the interaction matrix \(L\) for the whole features or a part of them.

print

Print to stdout the values of the current visual feature \(s\) .

setError

Set the error vector \((s-s*)\) .

setInteractionMatrix

set the value of the interaction matrix.

set_s

Overloaded function.

Inherited Methods

user

BasicFeatureSelect

Indicates who should deallocate the feature.

setFlags

Set feature flags to true to prevent warning when re-computing the interaction matrix without having updated the feature.

FEATURE_ALL

getDimension

Get the feature vector dimension.

getDeallocate

dimension_s

Return the dimension of the feature vector \(\bf s\) .

setDeallocate

selectAll

Select all the features.

BasicFeatureDeallocatorType

Indicates who should deallocate the feature.

vpServo

Operators

__doc__

__init__

Constructor of the class you have to use.

__module__

Attributes

FEATURE_ALL

__annotations__

user

vpServo

class BasicFeatureDeallocatorType(self, value: int)

Bases: pybind11_object

Indicates who should deallocate the feature.

Values:

  • user

  • vpServo

__and__(self, other: object) object
__eq__(self, other: object) bool
__ge__(self, other: object) bool
__getstate__(self) int
__gt__(self, other: object) bool
__hash__(self) int
__index__(self) int
__init__(self, value: int)
__int__(self) int
__invert__(self) object
__le__(self, other: object) bool
__lt__(self, other: object) bool
__ne__(self, other: object) bool
__or__(self, other: object) object
__rand__(self, other: object) object
__ror__(self, other: object) object
__rxor__(self, other: object) object
__setstate__(self, state: int) None
__xor__(self, other: object) object
property name : str
class BasicFeatureSelect(self, value: int)

Bases: pybind11_object

Indicates who should deallocate the feature.

Values:

  • user

  • vpServo

__and__(self, other: object) object
__eq__(self, other: object) bool
__ge__(self, other: object) bool
__getstate__(self) int
__gt__(self, other: object) bool
__hash__(self) int
__index__(self) int
__init__(self, value: int)
__int__(self) int
__invert__(self) object
__le__(self, other: object) bool
__lt__(self, other: object) bool
__ne__(self, other: object) bool
__or__(self, other: object) object
__rand__(self, other: object) object
__ror__(self, other: object) object
__rxor__(self, other: object) object
__setstate__(self, state: int) None
__xor__(self, other: object) object
property name : str
__init__(self, dim: int)

Constructor of the class you have to use. The feature table is initilialized with the good dimension.

dimension_s(self) int

Return the dimension of the feature vector \(\bf s\) .

display(*args, **kwargs)

Overloaded function.

  1. display(self: visp._visp.visual_features.GenericFeature, cam: visp._visp.core.CameraParameters, I: visp._visp.core.ImageGray, color: visp._visp.core.Color = vpColor::green, thickness: int = 1) -> None

Not implemented.

  1. display(self: visp._visp.visual_features.GenericFeature, cam: visp._visp.core.CameraParameters, I: visp._visp.core.ImageRGBa, color: visp._visp.core.Color = vpColor::green, thickness: int = 1) -> None

Not implemented.

error(*args, **kwargs)

Overloaded function.

  1. error(self: visp._visp.visual_features.GenericFeature, s_star: visp._visp.visual_features.BasicFeature, select: int = FEATURE_ALL) -> visp._visp.core.ColVector

Compute the error \((s-s^*)\) between the current and the desired visual features from a subset of the possible features.

obviously if vpGenericFeature::setError is not used then s_star is considered and this warning is meaningless.

The code below shows how to use this method to manipulate the two visual features over three:

// Creation of the current feature s
vpGenericFeature s(3);
s.set_s(0, 0, 0);

// Creation of the desired feature s*
vpGenericFeature s_star(3);
s_star.set_s(1, 1, 1);

// Here you have to compute the interaction matrix L
s.setInteractionMatrix(L);

// Compute the error vector (s-s*) for the two first features
s.error(s_star, vpBasicFeature::FEATURE_LINE[0] | vpBasicFeature::FEATURE_LINE[1]);
Parameters:
s_star

Desired visual feature.

select

The error can be computed for a selection of a subset of the possible features.

  • To compute the error for all the features use vpBasicFeature::FEATURE_ALL . In that case the error vector column vector whose dimension is equal to the number of features.

  • To compute the error for only one of the component feature you have to say which one you want to take into account. If it is the first one set select to vpBasicFeature::FEATURE_LINE [0], if it is the second one set select to vpBasicFeature::FEATURE_LINE [1], and so on. In that case the error vector is a 1 dimension column vector.

  • To compute the error for only two of the component feature you have to say which ones you want to take into account. If it is the first one and the second one set select to vpBasicFeature::FEATURE_LINE [0] | vpBasicFeature::FEATURE_LINE [1]. In that case the error vector is a 2 dimension column vector.

Returns:

The error \((s-s^*)\) between the current and the desired visual feature.

  1. error(self: visp._visp.visual_features.GenericFeature, select: int = FEATURE_ALL) -> visp._visp.core.ColVector

Compute the error \((s-s^*)\) between the current and the desired visual features from a subset of the possible features. But in this case the desired feature is considered as set to 0.

The code below shows how to use this method to manipulate the two visual features over three:

// Creation of the current feature s
vpGenericFeature s(3);
s.set_s(0, 0, 0);

// Here you have to compute the interaction matrix L
s.setInteractionMatrix(L);

// Compute the error vector (s-s*) for the two first features
s.error(vpBasicFeature::FEATURE_LINE[0] | vpBasicFeature::FEATURE_LINE[1]);
Parameters:
select

The error can be computed for a selection of a subset of the possible features.

  • To compute the error for all the features use vpBasicFeature::FEATURE_ALL . In that case the error vector column vector whose dimension is equal to the number of features.

  • To compute the error for only one of the component feature you have to say which one you want to take into account. If it is the first one set select to vpBasicFeature::FEATURE_LINE [0], if it is the second one set select to vpBasicFeature::FEATURE_LINE [1], and so on. In that case the error vector is a 1 dimension column vector.

  • To compute the error for only two of the component feature you have to say which ones you want to take into account. If it is the first one and the second one set select to vpBasicFeature::FEATURE_LINE [0] | vpBasicFeature::FEATURE_LINE [1]. In that case the error vector is a 2 dimension column vector.

Returns:

The error \((s-s^*)\) between the current and the desired visual feature which is automatically set to zero.

  1. error(self: visp._visp.visual_features.BasicFeature, s_star: visp._visp.visual_features.BasicFeature, select: int = FEATURE_ALL) -> visp._visp.core.ColVector

Compute the error between two visual features from a subset of the possible features.

getDeallocate(self) visp._visp.visual_features.BasicFeature.BasicFeatureDeallocatorType
getDimension(self, select: int = FEATURE_ALL) int

Get the feature vector dimension.

getInteractionMatrix(self) visp._visp.core.Matrix
get_s(*args, **kwargs)

Overloaded function.

  1. get_s(self: visp._visp.visual_features.GenericFeature, s: visp._visp.core.ColVector) -> None

get the value of all the features.

  1. get_s(self: visp._visp.visual_features.BasicFeature, select: int = FEATURE_ALL) -> visp._visp.core.ColVector

Get the feature vector \(\bf s\) .

init(self) None
interaction(self, select: int = FEATURE_ALL) visp._visp.core.Matrix

Compute and return the interaction matrix \(L\) for the whole features or a part of them.

The code below shows how to compute the interaction matrix associated to the first visual feature.

// Creation of the current feature s
vpGenericFeature s(3);
s.set_s(0, 0, 0);

// Here you have to compute the interaction matrix L for all the three
features s.setInteractionMatrix(L);

vpMatrix L_x = s.interaction( vpBasicFeature::FEATURE_LINE[0] );

The code below shows how to compute the interaction matrix associated to two visual features over three.

// Creation of the current feature s
vpGenericFeature s(3);
s.set_s(0, 0, 0);

// Here you have to compute the interaction matrix L
s.setInteractionMatrix(L);

vpMatrix L_x = s.interaction( vpBasicFeature::FEATURE_LINE[0]|vpBasicFeature::FEATURE_LINE[1] );
Parameters:
select: int = FEATURE_ALL

Selection of a subset of the possible features.

  • To compute the interaction matrix for all the features use vpBasicFeature::FEATURE_ALL . In that case the dimension of the interaction matrix is \([number of features \times 6]\)

  • To compute the interaction matrix for only one of the component feature you have to say which one you want to take into account. If it is the first one set select to vpBasicFeature::FEATURE_LINE [0], if it is the second one set select to vpBasicFeature::FEATURE_LINE [1], and so on. In that case the returned interaction matrix is \([1 \times 6]\) dimension.

  • To compute the interaction matrix for only two of the component features you have to say which ones you want to take into account. If it is the first one and the second one set select to vpBasicFeature::FEATURE_LINE [0] | vpBasicFeature::FEATURE_LINE [1]. In that case the returned interaction matrix is \([2 \times 6]\) dimension.

Returns:

The interaction matrix computed from the features.

print(self, select: int = FEATURE_ALL) None

Print to stdout the values of the current visual feature \(s\) .

vpGenericFeature s; // Current visual feature s

// Creation of the current feature s
s.set_s(0, 0, 0);

s.print(); // print all components of the feature
s.print(vpBasicFeature::FEATURE_ALL);  // same behavior then previous line
s.print(vpBasicFeature::FEATURE_LINE[0]); // print only the first component
Parameters:
select: int = FEATURE_ALL

Selection of a subset of the possible features.

  • To print all the features use vpBasicFeature::FEATURE_ALL .

  • To print only one of the component features you have to say which one you want to take into account. If it is the first one set select to vpBasicFeature::FEATURE_LINE [0], if it is the second one set select to vpBasicFeature::FEATURE_LINE [1], and so on.

static selectAll() int

Select all the features.

setDeallocate(self, d: visp._visp.visual_features.BasicFeature.BasicFeatureDeallocatorType) None
setError(self, error_vector: visp._visp.core.ColVector) None

Set the error vector \((s-s*)\) .

Parameters:
error_vector: visp._visp.core.ColVector

Error vector \((s-s*)\) .

setFlags(self) None

Set feature flags to true to prevent warning when re-computing the interaction matrix without having updated the feature.

setInteractionMatrix(self, L: visp._visp.core.Matrix) None

set the value of the interaction matrix.

set_s(*args, **kwargs)

Overloaded function.

  1. set_s(self: visp._visp.visual_features.GenericFeature, s: visp._visp.core.ColVector) -> None

set the value of all the features.

  1. set_s(self: visp._visp.visual_features.GenericFeature, s0: float) -> None

set the value of one feature if the number of feature is equal to 1.

Parameters:
s0

value of the visual feature

  1. set_s(self: visp._visp.visual_features.GenericFeature, s0: float, s1: float) -> None

set the value of two features if the number of feature is equal to 2.

Parameters:
s0

value of the first visual feature

s1

value of the second visual feature

  1. set_s(self: visp._visp.visual_features.GenericFeature, s0: float, s1: float, s2: float) -> None

set the value of three features if the number of feature is equal to 3.

Parameters:
s0

value of the first visual feature

s1

value of the second visual feature

s2

value of the third visual feature