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)
12 using json = nlohmann::json;
14 #if defined(ENABLE_VISP_NAMESPACE)
18 #ifndef DOXYGEN_SHOULD_SKIP_THIS
20 enum vpInteractionMatrixTypeSubset
29 NLOHMANN_JSON_SERIALIZE_ENUM(vpInteractionMatrixTypeSubset, {
43 lambda(0.5), cdMo(0, 0, 0.75, 0, 0, 0),
45 samplingTime(0.04), errorThreshold(0.0001), interactionMatrixType(CURRENT)
50 switch (interactionMatrixType) {
67 double errorThreshold;
68 vpInteractionMatrixTypeSubset interactionMatrixType;
75 void from_json(
const json &j, Arguments &a)
77 #ifdef ENABLE_VISP_NAMESPACE
78 using VISP_NAMESPACE_ADDRESSING from_json;
80 a.lambda = j.value(
"lambda", a.lambda);
85 a.cMo = j.value(
"cMo", a.cMo);
86 a.cdMo = j.value(
"cdMo", a.cdMo);
88 a.samplingTime = j.value(
"samplingTime", a.samplingTime);
89 if (a.samplingTime <= 0) {
93 a.errorThreshold = j.value(
"errorThreshold", a.errorThreshold);
94 if (a.errorThreshold <= 0) {
98 a.interactionMatrixType = j.value(
"interactionMatrix", a.interactionMatrixType);
99 if (a.interactionMatrixType == UNKNOWN) {
104 void to_json(json &j,
const Arguments &a)
106 #ifdef ENABLE_VISP_NAMESPACE
107 using VISP_NAMESPACE_ADDRESSING to_json;
110 {
"lambda", a.lambda},
113 {
"errorThreshold", a.errorThreshold},
114 {
"samplingTime", a.samplingTime} ,
115 {
"interactionMatrix", a.interactionMatrixType}
121 Arguments readArguments(
const std::string &path)
126 std::ifstream file(path);
128 std::stringstream ss;
129 ss <<
"Problem opening file " << path <<
". Make sure it exists and is readable" << std::endl;
134 j = json::parse(file);
136 catch (json::parse_error &e) {
137 std::stringstream msg;
138 msg <<
"Could not parse JSON file : \n";
140 msg << e.what() << std::endl;
141 msg <<
"Byte position of error: " << e.byte;
148 std::cout <<
"Using default arguments. Try using a JSON file to set the arguments of the visual servoing." << std::endl;
155 #ifdef ENABLE_VISP_NAMESPACE
173 class ServoingExperimentData
176 ServoingExperimentData(
const Arguments &arguments,
const std::vector<vpFeaturePoint> &desiredFeatures) :
177 m_arguments(arguments), m_desiredFeatures(desiredFeatures)
180 void onIter(
const vpHomogeneousMatrix &cMo,
const double errorNorm,
const std::vector<vpFeaturePoint> &points,
184 m_trajectory.push_back(r);
185 m_errorNorms.push_back(errorNorm);
186 m_points3D.push_back(points);
187 m_velocities.push_back(velocity);
188 m_interactionMatrices.push_back(interactionMatrix);
192 Arguments m_arguments;
193 std::vector<vpFeaturePoint> m_desiredFeatures;
194 std::vector<vpPoseVector> m_trajectory;
195 std::vector<double> m_errorNorms;
196 std::vector<std::vector<vpFeaturePoint> > m_points3D;
197 std::vector<vpColVector> m_velocities;
198 std::vector<vpMatrix> m_interactionMatrices;
199 friend void to_json(json &j,
const ServoingExperimentData &res);
202 void to_json(json &j,
const ServoingExperimentData &res)
204 #ifdef ENABLE_VISP_NAMESPACE
205 using VISP_NAMESPACE_ADDRESSING to_json;
208 {
"parameters", res.m_arguments},
209 {
"trajectory", res.m_trajectory},
210 {
"errorNorm", res.m_errorNorms},
211 {
"features", res.m_points3D},
212 {
"desiredFeatures", res.m_desiredFeatures},
213 {
"velocities", res.m_velocities},
214 {
"interactionMatrices", res.m_interactionMatrices}
220 void saveResults(
const ServoingExperimentData &results,
const std::string &path)
222 std::ofstream file(path);
223 const json j = results;
230 int main(
int argc,
char *argv[])
233 std::string arguments_path =
"";
234 std::string output_path =
"";
235 for (
int i = 1; i < argc; ++i) {
236 if (std::string(argv[i]) ==
"--settings" && i + 1 < argc) {
237 arguments_path = std::string(argv[i + 1]);
239 else if (std::string(argv[i]) ==
"--output" && i + 1 < argc) {
240 output_path = std::string(argv[i + 1]);
244 if (output_path.empty()) {
245 std::cerr <<
"JSON output path must be specified" << std::endl;
248 const Arguments args = readArguments(arguments_path);
254 std::cout << cdMo << std::endl;
268 std::vector<vpFeaturePoint> features;
270 for (
unsigned int i = 0; i < 4; i++) {
271 point[i].
track(cdMo);
279 ServoingExperimentData results(args, features);
284 robot.setSamplingTime(args.samplingTime);
285 robot.getPosition(wMc);
288 unsigned int iter = 0;
290 std::cout <<
"Starting visual-servoing loop until convergence..." << std::endl;
293 robot.getPosition(wMc);
295 for (
unsigned int i = 0; i < 4; i++) {
308 if (errorNorm < args.errorThreshold) {
315 std::cout <<
"Convergence in " << iter <<
" iterations" << std::endl;
317 saveResults(results, output_path);
321 std::cout <<
"Caught an exception: " << e << std::endl;
327 std::cerr <<
"Cannot run tutorial: ViSP is not built with JSON integration. Install the JSON library and recompile ViSP" << std::endl;
Implementation of column vector and the associated operations.
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 vpImagePoint &t)
Class that defines a 2D point visual feature which is composed by two parameters that are the cartes...
void track(const vpHomogeneousMatrix &cMo)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
Provides simple mathematics computation tools that are not available in the C mathematics library (ma...
Implementation of a matrix and operations on matrices.
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
void setWorldCoordinates(double oX, double oY, double oZ)
Implementation of a pose vector and operations on poses.
void setVelocity(const vpRobot::vpControlFrameType frame, const vpColVector &vel) VP_OVERRIDE
vpMatrix getInteractionMatrix() const
void setInteractionMatrixType(const vpServoIteractionMatrixType &interactionMatrixType, const vpServoInversionType &interactionMatrixInversion=PSEUDO_INVERSE)
void addFeature(vpBasicFeature &s_cur, vpBasicFeature &s_star, unsigned int select=vpBasicFeature::FEATURE_ALL)
void setServo(const vpServoType &servo_type)
vpColVector getError() const
vpColVector computeControlLaw()
vpServoIteractionMatrixType
Class that defines the simplest robot: a free flying camera.
VISP_EXPORT int wait(double t0, double t)