00001
00002
00003 #include "ObjectContactTurnaroundDetectorBase.h"
00004
00005 #include <stdio.h>
00006 #include <cstdio>
00007 #include <iostream>
00008 #include <vector>
00009
00010 class testObjectContactTurnaroundDetectorBase
00011 {
00012 protected:
00013 double dt;
00014 ObjectContactTurnaroundDetectorBase octd;
00015 bool use_gnuplot;
00016 std::vector<std::vector<hrp::Vector3> > forces_vec, moments_vec, hpos_vec;
00017 double detect_time, true_turnaround_time;
00018 std::vector<double> time_vec;
00019 void gen_pattern_and_plot ()
00020 {
00021 parse_params();
00022 octd.printParams();
00023 std::string fname("/tmp/plot-octd.dat");
00024 FILE* fp = fopen(fname.c_str(), "w");
00025 bool detected = false;
00026 double max_f = -1e10, min_f = 1e10;
00027 for (size_t i = 0; i < time_vec.size();i++) {
00028 bool tmp_detected = octd.checkDetection(forces_vec[i], moments_vec[i], hpos_vec[i]);
00029 if (tmp_detected && !detected) {
00030 detect_time = time_vec[i];
00031 detected = true;
00032 }
00033 hrp::dvector log_data = octd.getDataForLogger();
00034 fprintf(fp, "%f %f %f %f\n", time_vec[i], log_data[1], log_data[2], log_data[3], detected);
00035 max_f = std::max(max_f, log_data[1]);
00036 min_f = std::min(min_f, log_data[1]);
00037 }
00038 fclose(fp);
00039 if (use_gnuplot) {
00040
00041 std::string titles[2] = {"Wrench", "Dwrench"};
00042
00043 FILE* gp = popen("gnuplot", "w");
00044 fprintf(gp, "set multiplot layout 2, 1 title 'Results'\n");
00045 fprintf(gp, "set xlabel 'Time [s]'\n");
00046 fprintf(gp, "set ylabel 'Wrench'\n");
00047 fprintf(gp, "set arrow from %f,%f to %f,%f\n", detect_time, min_f, detect_time, max_f);
00048 fprintf(gp, "plot '/tmp/plot-octd.dat' using 1:2 with lines title 'Wrench' lw 4, '/tmp/plot-octd.dat' using 1:3 with lines title 'FilteredWrench' lw 4\n");
00049 fprintf(gp, "unset arrow\n");
00050 fprintf(gp, "set xlabel 'Time [s]'\n");
00051 fprintf(gp, "set ylabel 'Dwrench'\n");
00052 fprintf(gp, "plot '/tmp/plot-octd.dat' using 1:4 with lines title 'Dwrench' lw 4\n");
00053 fflush(gp);
00054 double tmp;
00055 std::cin >> tmp;
00056 pclose(gp);
00057 }
00058 };
00059 public:
00060 std::vector<std::string> arg_strs;
00061 testObjectContactTurnaroundDetectorBase (const double _dt = 0.004) : dt(_dt), octd(_dt), use_gnuplot(true), detect_time(1e10), true_turnaround_time(1e10)
00062 {
00063
00064 octd.setWrenchCutoffFreq(5.0);
00065 octd.setDwrenchCutoffFreq(5.0);
00066 octd.setAxis(hrp::Vector3::UnitZ());
00067
00068
00069 };
00070 void gen_forces_moments (const std::vector<double>& force_vec, const hrp::Vector3& force_dir = hrp::Vector3::UnitZ())
00071 {
00072 for (size_t i = 0; i < force_vec.size();i++) {
00073 std::vector<hrp::Vector3> tmpv(1, hrp::Vector3::Zero());
00074 moments_vec.push_back(tmpv);
00075 hpos_vec.push_back(tmpv);
00076 tmpv[0] = force_vec[i] * force_dir;
00077 forces_vec.push_back(tmpv);
00078 }
00079 };
00080 hrp::dvector6 get_ccm1_by_index (size_t idx, bool is_positive = true)
00081 {
00082 hrp::dvector6 ccm1(hrp::dvector6::Zero());
00083 ccm1(idx) = (is_positive?1.0:-1.0);
00084 return ccm1;
00085 }
00086
00087 double get_a_coeff_by_index (const double df, const hrp::dvector6& ccm1, const hrp::Vector3& fdir)
00088 {
00089 hrp::Vector3 fpos(0.2, 0.0, 0.7);
00090 hrp::Vector3 tmp(fdir);
00091 hrp::dvector6 resultant_wrench_direction_vector;
00092 for (size_t i = 0; i < 3; i++) resultant_wrench_direction_vector(i) = tmp(i);
00093 tmp = fpos.cross(fdir);
00094 for (size_t i = 0; i < 3; i++) resultant_wrench_direction_vector(i+3) = tmp(i);
00095 return -1*ccm1.dot(resultant_wrench_direction_vector) * df;
00096 }
00097
00098 double gen_forces_moments_for_saturation (const double total_tm, const double start_tm, const double turnaround_tm,
00099 const double start_resultant_force, const double turnaround_resultant_force,
00100 const hrp::Vector3& force_dir = hrp::Vector3::UnitZ())
00101 {
00102 std::vector<double> phi_vec;
00103 double dphi = (turnaround_resultant_force-start_resultant_force)/(turnaround_tm-start_tm);
00104 true_turnaround_time = turnaround_tm;
00105 for (size_t i = 0; i < static_cast<size_t>(total_tm/dt);i++) {
00106 double current_tm = i*dt;
00107 time_vec.push_back(current_tm);
00108 if (current_tm < start_tm) {
00109 phi_vec.push_back(start_resultant_force);
00110 } else if (current_tm < turnaround_tm) {
00111 phi_vec.push_back(start_resultant_force+dphi*(current_tm-start_tm));
00112 } else {
00113 phi_vec.push_back(turnaround_resultant_force);
00114 }
00115 }
00116 gen_forces_moments(phi_vec, force_dir);
00117 return dphi;
00118 };
00119 double gen_forces_moments_for_inverting (const double total_tm, const double start_tm, const double turnaround_tm,
00120 const double start_resultant_force, const double turnaround_resultant_force,
00121 const hrp::Vector3& force_dir = hrp::Vector3::UnitZ())
00122 {
00123 std::vector<double> phi_vec;
00124 double dphi = (turnaround_resultant_force-start_resultant_force)/(turnaround_tm-start_tm);
00125 true_turnaround_time = turnaround_tm;
00126 for (size_t i = 0; i < static_cast<size_t>(total_tm/dt);i++) {
00127 double current_tm = i*dt;
00128 time_vec.push_back(current_tm);
00129 if (current_tm < start_tm) {
00130 phi_vec.push_back(start_resultant_force);
00131 } else if (current_tm < turnaround_tm) {
00132 phi_vec.push_back(start_resultant_force+dphi*(current_tm-start_tm));
00133 } else {
00134 phi_vec.push_back(turnaround_resultant_force+(current_tm-turnaround_tm)*-2*dphi );
00135 }
00136 }
00137 gen_forces_moments(phi_vec, force_dir);
00138 return dphi;
00139 };
00140 void test0 ()
00141 {
00142 std::cerr << "test0 : Increasing->saturation (TOTAL_FORCE)" << std::endl;
00143 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = 40.0, dphi;
00144 dphi = gen_forces_moments_for_saturation(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force);
00145 octd.startDetection (dphi, total_tm);
00146 gen_pattern_and_plot ();
00147 };
00148 void test1 ()
00149 {
00150 std::cerr << "test1 : Increasing->decreasing (TOTAL_FORCE)" << std::endl;
00151 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = 40.0, dphi;
00152 dphi = gen_forces_moments_for_inverting(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force);
00153 octd.startDetection (dphi, total_tm);
00154 gen_pattern_and_plot ();
00155 };
00156 void test2 ()
00157 {
00158 std::cerr << "test2 : Deacreasing->saturation (TOTAL_FORCE)" << std::endl;
00159 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = -40.0, dphi;
00160 dphi = gen_forces_moments_for_saturation(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force);
00161 octd.startDetection (dphi, total_tm);
00162 gen_pattern_and_plot ();
00163 };
00164 void test3 ()
00165 {
00166 std::cerr << "test3 : Decreasing->increasing (TOTAL_FORCE)" << std::endl;
00167 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = -40.0, dphi;
00168 dphi = gen_forces_moments_for_inverting(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force);
00169 octd.startDetection (dphi, total_tm);
00170 gen_pattern_and_plot ();
00171 };
00172 void test4 ()
00173 {
00174 std::cerr << "test4 : Lift up (GENERALIZED_WRENCH)" << std::endl;
00175 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = -40.0, dphi;
00176 dphi = std::fabs(gen_forces_moments_for_saturation(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force));
00177 octd.setDetectorTotalWrench(ObjectContactTurnaroundDetectorBase::GENERALIZED_WRENCH);
00178 std::vector<hrp::dvector6> ccm1(1, get_ccm1_by_index(2));
00179 double ref_dwrench = get_a_coeff_by_index(dphi, ccm1[0], hrp::Vector3::UnitZ());
00180 octd.setConstraintConversionMatricesRefDwrench(ccm1,
00181 std::vector<hrp::dvector6>(1, hrp::dvector6::Zero()),
00182 std::vector<double>(1, ref_dwrench));
00183 octd.setMaxTime(total_tm);
00184 octd.startDetectionForGeneralizedWrench();
00185 gen_pattern_and_plot ();
00186 };
00187 void test5 ()
00188 {
00189 std::cerr << "test5 : Push fwd (GENERALIZED_WRENCH)" << std::endl;
00190 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = -40.0, dphi;
00191 dphi = std::fabs(gen_forces_moments_for_saturation(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force, hrp::Vector3::UnitX()));
00192 octd.setDetectorTotalWrench(ObjectContactTurnaroundDetectorBase::GENERALIZED_WRENCH);
00193 std::vector<hrp::dvector6> ccm1(1, get_ccm1_by_index(0));
00194 double ref_dwrench = get_a_coeff_by_index(dphi, ccm1[0], hrp::Vector3::UnitX());
00195 octd.setConstraintConversionMatricesRefDwrench(ccm1,
00196 std::vector<hrp::dvector6>(1, hrp::dvector6::Zero()),
00197 std::vector<double>(1, ref_dwrench));
00198 octd.setMaxTime(total_tm);
00199 octd.startDetectionForGeneralizedWrench();
00200 gen_pattern_and_plot ();
00201 };
00202 void test6 ()
00203 {
00204 std::cerr << "test6 : Push bwd (GENERALIZED_WRENCH)" << std::endl;
00205 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = 40.0, dphi;
00206 dphi = std::fabs(gen_forces_moments_for_saturation(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force, hrp::Vector3::UnitX()));
00207 octd.setDetectorTotalWrench(ObjectContactTurnaroundDetectorBase::GENERALIZED_WRENCH);
00208 std::vector<hrp::dvector6> ccm1(1, get_ccm1_by_index(0, false));
00209 double ref_dwrench = get_a_coeff_by_index(dphi, ccm1[0], -1*hrp::Vector3::UnitX());
00210 octd.setConstraintConversionMatricesRefDwrench(ccm1,
00211 std::vector<hrp::dvector6>(1, hrp::dvector6::Zero()),
00212 std::vector<double>(1, ref_dwrench));
00213 octd.setMaxTime(total_tm);
00214 octd.startDetectionForGeneralizedWrench();
00215 gen_pattern_and_plot ();
00216 };
00217 void test7 ()
00218 {
00219 std::cerr << "test7 : Tilt upward (GENERALIZED_WRENCH)" << std::endl;
00220 double total_tm = 4.0, start_tm = total_tm*0.1, turnaround_tm = total_tm*0.4, start_resultant_force = 0.0, turnaround_resultant_force = -40.0, dphi;
00221 dphi = std::fabs(gen_forces_moments_for_saturation(total_tm, start_tm, turnaround_tm, start_resultant_force, turnaround_resultant_force));
00222 octd.setDetectorTotalWrench(ObjectContactTurnaroundDetectorBase::GENERALIZED_WRENCH);
00223 std::vector<hrp::dvector6> ccm1(1, hrp::dvector6::Zero());
00224 ccm1[0](2) = 0.9; ccm1[0](4) = 1.0;
00225 double ref_dwrench = get_a_coeff_by_index(dphi, ccm1[0], hrp::Vector3::UnitZ());
00226 octd.setConstraintConversionMatricesRefDwrench(ccm1,
00227 std::vector<hrp::dvector6>(1, hrp::dvector6::Zero()),
00228 std::vector<double>(1, ref_dwrench));
00229 octd.setMaxTime(total_tm);
00230 octd.startDetectionForGeneralizedWrench();
00231 gen_pattern_and_plot ();
00232 };
00233 bool check_detection_time_validity (const double time_thre = 1.0)
00234 {
00235 return true_turnaround_time < detect_time && (detect_time-true_turnaround_time) < time_thre;
00236 };
00237 bool check_all_results ()
00238 {
00239 std::cerr << "Results:" << std::endl;
00240 std::cerr << " Detected? : " << (octd.isDetected()?"true":"false") << std::endl;
00241 std::cerr << " Detection time : " << (check_detection_time_validity()?"true":"false") << ", detect_time = " << detect_time << "[s], true_turnaround_time = " << true_turnaround_time << "[s]" << std::endl;
00242 return octd.isDetected() && check_detection_time_validity();
00243 };
00244 void parse_params ()
00245 {
00246 for (unsigned int i = 0; i < arg_strs.size(); ++ i) {
00247 if ( arg_strs[i]== "--use-gnuplot" ) {
00248 if (++i < arg_strs.size()) use_gnuplot = (arg_strs[i]=="true");
00249 }
00250 }
00251 };
00252 };
00253
00254 void print_usage ()
00255 {
00256 std::cerr << "Usage : testObjectContactTurnaroundDetectorBase [option]" << std::endl;
00257 std::cerr << " [option] should be:" << std::endl;
00258 std::cerr << " --test0 : Increasing->saturation (TOTAL_FORCE)" << std::endl;
00259 std::cerr << " --test1 : Increasing->saturation (GENERALIZED_WRENCH)" << std::endl;
00260 std::cerr << " --test2 : Increasing->decreasing (GENERALIZED_WRENCH)" << std::endl;
00261 std::cerr << " --test3 : Decreasing->saturation (GENERALIZED_WRENCH)" << std::endl;
00262 std::cerr << " --test4 : Decreasing->increasing (GENERALIZED_WRENCH)" << std::endl;
00263 };
00264
00265 int main(int argc, char* argv[])
00266 {
00267 int ret = 0;
00268 if (argc >= 2) {
00269 testObjectContactTurnaroundDetectorBase toctd;
00270 for (int i = 1; i < argc; ++ i) {
00271 toctd.arg_strs.push_back(std::string(argv[i]));
00272 }
00273 if (std::string(argv[1]) == "--test0") {
00274 toctd.test0();
00275 } else if (std::string(argv[1]) == "--test1") {
00276 toctd.test1();
00277 } else if (std::string(argv[1]) == "--test2") {
00278 toctd.test2();
00279 } else if (std::string(argv[1]) == "--test3") {
00280 toctd.test3();
00281 } else if (std::string(argv[1]) == "--test4") {
00282 toctd.test4();
00283 } else if (std::string(argv[1]) == "--test5") {
00284 toctd.test5();
00285 } else if (std::string(argv[1]) == "--test6") {
00286 toctd.test6();
00287 } else if (std::string(argv[1]) == "--test7") {
00288 toctd.test7();
00289 } else {
00290 print_usage();
00291 ret = 1;
00292 }
00293 ret = (toctd.check_all_results()?0:2);
00294 } else {
00295 print_usage();
00296 ret = 1;
00297 }
00298 return ret;
00299 }
00300