3#include <visp3/core/vpConfig.h>
5#ifdef VISP_HAVE_NLOHMANN_JSON
6#include <visp3/robot/vpSimulatorCamera.h>
7#include <visp3/visual_features/vpFeatureBuilder.h>
8#include <visp3/vs/vpServo.h>
11#include VISP_NLOHMANN_JSON(json.hpp)
12using json = nlohmann::json;
14#if defined(ENABLE_VISP_NAMESPACE)
18#ifndef DOXYGEN_SHOULD_SKIP_THIS
20enum vpInteractionMatrixTypeSubset
32# pragma clang diagnostic push
33# pragma clang diagnostic ignored "-Wexit-time-destructors"
37NLOHMANN_JSON_SERIALIZE_ENUM(vpInteractionMatrixTypeSubset, {
46# pragma clang diagnostic pop
55 lambda(0.5), cdMo(0, 0, 0.75, 0, 0, 0),
56 cMo(0.15, -0.1, 1., vpMath::rad(10), vpMath::rad(-10), vpMath::rad(50)),
57 samplingTime(0.04), errorThreshold(0.0001), interactionMatrixType(CURRENT)
62 switch (interactionMatrixType) {
76 vpHomogeneousMatrix cdMo;
77 vpHomogeneousMatrix
cMo;
79 double errorThreshold;
80 vpInteractionMatrixTypeSubset interactionMatrixType;
87void from_json(
const json &j, Arguments &a)
89#ifdef ENABLE_VISP_NAMESPACE
90 using VISP_NAMESPACE_ADDRESSING from_json;
92 a.lambda =
j.value(
"lambda", a.lambda);
97 a.cMo =
j.value(
"cMo", a.cMo);
98 a.cdMo =
j.value(
"cdMo", a.cdMo);
100 a.samplingTime =
j.value(
"samplingTime", a.samplingTime);
101 if (a.samplingTime <= 0) {
105 a.errorThreshold =
j.value(
"errorThreshold", a.errorThreshold);
106 if (a.errorThreshold <= 0) {
110 a.interactionMatrixType =
j.value(
"interactionMatrix", a.interactionMatrixType);
111 if (a.interactionMatrixType == UNKNOWN) {
116void to_json(json &j,
const Arguments &a)
118#ifdef ENABLE_VISP_NAMESPACE
119 using VISP_NAMESPACE_ADDRESSING to_json;
122 {
"lambda", a.lambda},
125 {
"errorThreshold", a.errorThreshold},
126 {
"samplingTime", a.samplingTime} ,
127 {
"interactionMatrix", a.interactionMatrixType}
133Arguments readArguments(
const std::string &path)
138 std::ifstream file(path);
140 std::stringstream ss;
141 ss <<
"Problem opening file " << path <<
". Make sure it exists and is readable" << std::endl;
146 j = json::parse(file);
148 catch (json::parse_error &e) {
149 std::stringstream msg;
150 msg <<
"Could not parse JSON file : \n";
152 msg <<
e.what() << std::endl;
153 msg <<
"Byte position of error: " <<
e.byte;
160 std::cout <<
"Using default arguments. Try using a JSON file to set the arguments of the visual servoing." << std::endl;
167#ifdef ENABLE_VISP_NAMESPACE
172void to_json(json &j,
const vpFeaturePoint &p)
185class ServoingExperimentData
188 ServoingExperimentData(
const Arguments &arguments,
const std::vector<vpFeaturePoint> &desiredFeatures) :
189 m_arguments(arguments), m_desiredFeatures(desiredFeatures)
192 void onIter(
const vpHomogeneousMatrix &cMo,
const double errorNorm,
const std::vector<vpFeaturePoint> &points,
193 const vpColVector &velocity,
const vpMatrix &interactionMatrix)
196 m_trajectory.push_back(r);
197 m_errorNorms.push_back(errorNorm);
198 m_points3D.push_back(points);
199 m_velocities.push_back(velocity);
200 m_interactionMatrices.push_back(interactionMatrix);
204 Arguments m_arguments;
205 std::vector<vpFeaturePoint> m_desiredFeatures;
206 std::vector<vpPoseVector> m_trajectory;
207 std::vector<double> m_errorNorms;
208 std::vector<std::vector<vpFeaturePoint> > m_points3D;
209 std::vector<vpColVector> m_velocities;
210 std::vector<vpMatrix> m_interactionMatrices;
211 friend void to_json(json &j,
const ServoingExperimentData &res);
214void to_json(json &j,
const ServoingExperimentData &res)
216#ifdef ENABLE_VISP_NAMESPACE
217 using VISP_NAMESPACE_ADDRESSING to_json;
220 {
"parameters", res.m_arguments},
221 {
"trajectory", res.m_trajectory},
222 {
"errorNorm", res.m_errorNorms},
223 {
"features", res.m_points3D},
224 {
"desiredFeatures", res.m_desiredFeatures},
225 {
"velocities", res.m_velocities},
226 {
"interactionMatrices", res.m_interactionMatrices}
232void saveResults(
const ServoingExperimentData &results,
const std::string &path)
234 std::ofstream file(path);
242int main(
int argc,
char *argv[])
245 std::string arguments_path =
"";
246 std::string output_path =
"";
247 for (
int i = 1;
i < argc; ++
i) {
248 if (std::string(argv[i]) ==
"--settings" && i + 1 < argc) {
249 arguments_path = std::string(argv[i + 1]);
251 else if (std::string(argv[i]) ==
"--output" && i + 1 < argc) {
252 output_path = std::string(argv[i + 1]);
256 if (output_path.empty()) {
257 std::cerr <<
"JSON output path must be specified" << std::endl;
260 const Arguments
args = readArguments(arguments_path);
264 vpHomogeneousMatrix cdMo =
args.cdMo;
265 vpHomogeneousMatrix
cMo =
args.cMo;
266 std::cout << cdMo << std::endl;
276 task.setInteractionMatrixType(
args.getInteractionMatrixType());
279 vpFeaturePoint
p[4], pd[4];
280 std::vector<vpFeaturePoint> features;
282 for (
unsigned int i = 0;
i < 4;
i++) {
287 task.addFeature(p[i], pd[i]);
291 ServoingExperimentData
results(args, features);
294 vpHomogeneousMatrix wMc, wMo;
295 vpSimulatorCamera robot;
296 robot.setSamplingTime(
args.samplingTime);
297 robot.getPosition(wMc);
300 unsigned int iter = 0;
302 std::cout <<
"Starting visual-servoing loop until convergence..." << std::endl;
305 robot.getPosition(wMc);
307 for (
unsigned int i = 0;
i < 4;
i++) {
312 const vpColVector
v =
task.computeControlLaw();
314 const double errorNorm =
task.getError().sumSquare();
317 results.onIter(cMo, errorNorm, features, v,
task.getInteractionMatrix());
320 if (errorNorm <
args.errorThreshold) {
327 std::cout <<
"Convergence in " <<
iter <<
" iterations" << std::endl;
329 saveResults(results, output_path);
332 catch (
const vpException &e) {
333 std::cout <<
"Caught an exception: " <<
e << std::endl;
339 std::cerr <<
"Cannot run tutorial: ViSP is not built with JSON integration. Install the JSON library and recompile ViSP" << std::endl;
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)