#include <iostream>
#include <visp3/core/vpConfig.h>
#ifdef VISP_HAVE_NLOHMANN_JSON
#include <visp3/robot/vpSimulatorCamera.h>
#include <visp3/visual_features/vpFeatureBuilder.h>
#include <visp3/vs/vpServo.h>
#include VISP_NLOHMANN_JSON(json.hpp)
using json = nlohmann::json;
#if defined(ENABLE_VISP_NAMESPACE)
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
enum vpInteractionMatrixTypeSubset
{
UNKNOWN = -1,
CURRENT,
DESIRED,
MEAN
};
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wexit-time-destructors"
#endif
NLOHMANN_JSON_SERIALIZE_ENUM(vpInteractionMatrixTypeSubset, {
{UNKNOWN, nullptr},
{CURRENT, "current"},
{DESIRED, "desired"},
{MEAN, "mean"} }
);
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
class Arguments
{
public:
Arguments() :
lambda(0.5), cdMo(0, 0, 0.75, 0, 0, 0),
cMo(0.15, -0.1, 1., vpMath::rad(10), vpMath::rad(-10), vpMath::rad(50)),
samplingTime(0.04), errorThreshold(0.0001), interactionMatrixType(CURRENT)
{ }
{
switch (interactionMatrixType) {
case CURRENT:
case DESIRED:
case MEAN:
default:
}
}
double lambda;
vpHomogeneousMatrix cdMo;
double samplingTime;
double errorThreshold;
vpInteractionMatrixTypeSubset interactionMatrixType;
};
void from_json(const json &j, Arguments &a)
{
#ifdef ENABLE_VISP_NAMESPACE
using VISP_NAMESPACE_ADDRESSING from_json;
#endif
a.lambda =
j.value(
"lambda", a.lambda);
if (a.lambda <= 0) {
}
a.cMo =
j.value(
"cMo", a.cMo);
a.cdMo =
j.value(
"cdMo", a.cdMo);
a.samplingTime =
j.value(
"samplingTime", a.samplingTime);
if (a.samplingTime <= 0) {
}
a.errorThreshold =
j.value(
"errorThreshold", a.errorThreshold);
if (a.errorThreshold <= 0) {
}
a.interactionMatrixType =
j.value(
"interactionMatrix", a.interactionMatrixType);
if (a.interactionMatrixType == UNKNOWN) {
}
}
void to_json(json &j, const Arguments &a)
{
#ifdef ENABLE_VISP_NAMESPACE
using VISP_NAMESPACE_ADDRESSING to_json;
#endif
{"lambda", a.lambda},
{"cMo", a.cMo},
{"cdMo", a.cdMo},
{"errorThreshold", a.errorThreshold},
{"samplingTime", a.samplingTime} ,
{"interactionMatrix", a.interactionMatrixType}
};
}
Arguments readArguments(const std::string &path)
{
Arguments a;
if (!path.empty()) {
std::ifstream file(path);
if (!file.good()) {
std::stringstream ss;
ss << "Problem opening file " << path << ". Make sure it exists and is readable" << std::endl;
}
try {
}
catch (json::parse_error &e) {
std::stringstream msg;
msg << "Could not parse JSON file : \n";
msg <<
e.what() << std::endl;
msg <<
"Byte position of error: " <<
e.byte;
}
file.close();
}
else {
std::cout << "Using default arguments. Try using a JSON file to set the arguments of the visual servoing." << std::endl;
}
return a;
}
#ifdef ENABLE_VISP_NAMESPACE
{
#endif
void to_json(json &j, const vpFeaturePoint &p)
{
};
}
END_VISP_NAMESPACE
class ServoingExperimentData
{
public:
ServoingExperimentData(const Arguments &arguments, const std::vector<vpFeaturePoint> &desiredFeatures) :
m_arguments(arguments), m_desiredFeatures(desiredFeatures)
{ }
void onIter(const vpHomogeneousMatrix &cMo, const double errorNorm, const std::vector<vpFeaturePoint> &points,
const vpColVector &velocity, const vpMatrix &interactionMatrix)
{
m_trajectory.push_back(r);
m_errorNorms.push_back(errorNorm);
m_points3D.push_back(points);
m_velocities.push_back(velocity);
m_interactionMatrices.push_back(interactionMatrix);
}
private:
Arguments m_arguments;
std::vector<vpFeaturePoint> m_desiredFeatures;
std::vector<vpPoseVector> m_trajectory;
std::vector<double> m_errorNorms;
std::vector<std::vector<vpFeaturePoint> > m_points3D;
std::vector<vpColVector> m_velocities;
std::vector<vpMatrix> m_interactionMatrices;
friend void to_json(json &j, const ServoingExperimentData &res);
};
void to_json(json &j, const ServoingExperimentData &res)
{
#ifdef ENABLE_VISP_NAMESPACE
using VISP_NAMESPACE_ADDRESSING to_json;
#endif
{"parameters", res.m_arguments},
{"trajectory", res.m_trajectory},
{"errorNorm", res.m_errorNorms},
{"features", res.m_points3D},
{"desiredFeatures", res.m_desiredFeatures},
{"velocities", res.m_velocities},
{"interactionMatrices", res.m_interactionMatrices}
};
}
void saveResults(const ServoingExperimentData &results, const std::string &path)
{
std::ofstream file(path);
file.close();
}
#endif
int main(
int argc,
char *argv[])
{
std::string arguments_path = "";
std::string output_path = "";
for (
int i = 1;
i < argc; ++
i) {
if (std::string(argv[i]) == "--settings" && i + 1 < argc) {
arguments_path = std::string(argv[i + 1]);
}
else if (std::string(argv[i]) == "--output" && i + 1 < argc) {
output_path = std::string(argv[i + 1]);
}
}
if (output_path.empty()) {
std::cerr << "JSON output path must be specified" << std::endl;
return EXIT_FAILURE;
}
const Arguments
args = readArguments(arguments_path);
try {
vpHomogeneousMatrix cdMo =
args.cdMo;
vpHomogeneousMatrix
cMo =
args.cMo;
std::cout << cdMo << std::endl;
vpPoint point[4];
task.setInteractionMatrixType(
args.getInteractionMatrixType());
vpFeaturePoint
p[4], pd[4];
std::vector<vpFeaturePoint> features;
features.resize(4);
for (
unsigned int i = 0;
i < 4;
i++) {
task.addFeature(p[i], pd[i]);
}
ServoingExperimentData
results(args, features);
vpHomogeneousMatrix wMc, wMo;
vpSimulatorCamera robot;
robot.setSamplingTime(
args.samplingTime);
bool end = false;
std::cout << "Starting visual-servoing loop until convergence..." << std::endl;
while (!end) {
robot.getPosition(wMc);
for (
unsigned int i = 0;
i < 4;
i++) {
}
const vpColVector
v =
task.computeControlLaw();
const double errorNorm =
task.getError().sumSquare();
results.onIter(cMo, errorNorm, features, v,
task.getInteractionMatrix());
if (errorNorm <
args.errorThreshold) {
end = true;
}
}
std::cout <<
"Convergence in " <<
iter <<
" iterations" << std::endl;
saveResults(results, output_path);
}
catch (const vpException &e) {
std::cout <<
"Caught an exception: " <<
e << std::endl;
}
}
#else
{
std::cerr << "Cannot run tutorial: ViSP is not built with JSON integration. Install the JSON library and recompile ViSP" << std::endl;
}
#endif
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
void track(const vpHomogeneousMatrix &cMo)
vpHomogeneousMatrix inverse() const
void setWorldCoordinates(double oX, double oY, double oZ)
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &vel) VP_OVERRIDE
vpServoIteractionMatrixType
VISP_EXPORT int wait(double t0, double t)