void PosterReader::softmotionPlotTraj() { if( _softmotionPoster == NULL ) { cout << "softmotion : NULL Poster" << endl; return; } //_softmotionPoster->update(); SM_TRAJ smTraj; if(_softmotionPoster->getPosterStuct((char *)(&_softmotionPosterStruct)) == false) { cout << " PosterReader::softmotionPlotTraj() ERROR " << endl; } smTraj.importFromSM_TRAJ_STR(&_softmotionPosterStruct); if( smTraj.getDuration() <= 0) { // QMessageBox toto(QMessageBox::Information, ,QMessageBox::Close, NULL,Qt::Dialog); QMessageBox::about (NULL, QString("SoftMotion info"), QString("Trajectory is empty")); return; } cout << "duration " << smTraj.getDuration() << endl; smTraj.plot(); return; }
int executeCB(const soft_move_base::SoftMoveBaseGoalConstPtr &goal) { ROS_INFO("Received new trajectory"); SM_TRAJ tmpTraj; ros::Rate _loop_rate(1/_dt); _timeFromStart= 0; _tmpTimeFromStart= 0; _timer = 0; loadNewTraj(goal->traj); double duration = 0.0; duration = _newTraj.getDuration(); limits.clear(); for(int i=0; i<6; ++i) { limit.maxJerk = _newTraj.jmax[i] * 1.1; limit.maxAcc = _newTraj.amax[i] * 1.1; limit.maxVel = _newTraj.vmax[i] * 1.1; limits.push_back(limit); } //double t = 0; //FILE* file; //file = fopen("baseExperiment.dat", "w"); bool cont = true; do { // end if goal canceled if( as_.isPreemptRequested()) break; getNextRobotCond(_timeFromStart + _dt); //printCond(_nextRobotCond_w); getPoseInRobotFrame(_nextRobotCond_w); //printCond(_nextRobotCond_r); _currRobotCond_r[0].x = 0; _currRobotCond_r[0].v = _lastVel[0]; _currRobotCond_r[0].a = _lastAcc[0]; _currRobotCond_r[1].x = 0; _currRobotCond_r[1].v = _lastVel[1]; _currRobotCond_r[1].a = _lastAcc[1]; _currRobotCond_r[5].x = 0; _currRobotCond_r[5].v = _lastVel[5]; _currRobotCond_r[5].a = _lastAcc[5]; //printCond(_currRobotCond_r); ROS_INFO("TMP TIME:%f", _tmpTimeFromStart); if( _timeFromStart == 0.0) { //correction tmpTraj.clear(); boundsCond(_currRobotCond_r); boundsCond(_nextRobotCond_r); tmpTraj.computeTraj(_currRobotCond_r, _nextRobotCond_r, limits, SM_TRAJ::SM_INDEPENDANT); _tmpTimeFromStart = _dt; //printCond( _newRobotCond_r); } else if(_timer - 0.5 >= 0.0001 || _tmpTimeFromStart > tmpTraj.getDuration()) { _timer = 0; //correction tmpTraj.clear(); tmpTraj.computeTraj(_currRobotCond_r, _nextRobotCond_r, limits, SM_TRAJ::SM_INDEPENDANT); _tmpTimeFromStart = _dt; } tmpTraj.getMotionCond(_tmpTimeFromStart,_newRobotCond_r); _lastVel[0]= _newRobotCond_r[0].v; _lastVel[1]= _newRobotCond_r[1].v; _lastVel[5]= _newRobotCond_r[5].v; _lastAcc[0]= _newRobotCond_r[0].a; _lastAcc[1]= _newRobotCond_r[1].a; _lastAcc[5]= _newRobotCond_r[5].a; //printCond(_newRobotCond_r); publishNewCond(_newRobotCond_r); _timeFromStart += _dt; _tmpTimeFromStart += _dt; _timer += _dt; if(_timeFromStart > _newTraj.getDuration()) _timeFromStart = _newTraj.getDuration(); _loop_rate.sleep(); if(_timeFromStart >= _newTraj.getDuration()) { cont = fabs(_newRobotCond_r[0].x) > _tolerance[0] || fabs(_newRobotCond_r[1].x) > _tolerance[1] || fabs(_newRobotCond_r[5].x) > _tolerance[2]; } ros::spinOnce(); } while(cont); soft_move_base::SoftMoveBaseResult result; result.result = true; as_.setSucceeded(result); return 0; }
int Sm_Approx::approximate(Sm_Curve &curv, double SampTime, double ErrPosMax, double ErrVelMax, int ExpTime, bool flagExport, std::string fileName, SM_TRAJ &smTraj) { std::string str2; FILE *fp_segMotion = NULL; _sampling = SampTime; _errMax = ErrPosMax; _timeStep = ExpTime; _flag_haus_actif = 0; _fileName = fileName; _nbAxis = curv.traj[0].Pos.size() ; SM_OUTPUT tempo_motion; double tu, ts; /* set limits that are only used to compute the error in velocity on overall the trajectory */ _lim.maxJerk = 6*fabs(ErrVelMax); _lim.maxAcc = 2*fabs(ErrVelMax); _lim.maxVel = fabs(ErrVelMax); initializeApproxVariables(); // dans l'attribut _curve il y aura deux courbes, la premiere _curve[0] est la traj ideale // la second _curve[1] = (_curve.back()) sera la traj approximee // les suites de cubiques de la traj approxime sont stockées dans _result // _result.size() est la nombre de segment de cubique (c'est la meme pour tout les axes) // SAUVE LA TRAJCTOIRE IDEALE (sous la forme d'un tableau) if(flagExport==true) { str2.clear(); str2 += "SmIdealTraj.dat"; saveTraj(str2, curv.traj); SM_LOG(SM_LOG_INFO, "Sm_Approx::approximate Ideal Trajectory Already Computed and Saved"); } /* Handle the path */ _curve.push_back(curv); ChronoOn(); ChronoTimes(&tu, &ts); /// CALCUL DE L'APPROXIMATION // computeTraj(); SM_LOG(SM_LOG_INFO, "Sm_Approx::approximate Computation Duration : "); ChronoPrint(""); std::cout << std::endl; ChronoTimes(&tu, &ts); ChronoOff(); if(flagExport==true) { // SAUVE LA TRAJCTOIRE APPROXIMEE (sous la forme d'un tableau) saveTraj("SmApproxTraj.dat", (_curve.back()).traj); SM_LOG(SM_LOG_INFO, "Sm_Approx::approximate Approximated Trajectory Saved"); } SM_LOG(SM_LOG_INFO, "Sm_Approx::approximate Error Max Pos " << (_curve.back()).errorMaxVal); /* fill result */ for (unsigned int i = 1; i < _result.size(); i++){ for (unsigned int j = 0; j < _result.size()-i ; j++){ if (_result[j].premier_point > _result[j+1].premier_point){ tempo_motion = _result[j]; _result[j] = _result[j+1]; _result[j+1] = tempo_motion; } } } _result[0].IC.resize(_result[0].Time.size()); for(unsigned int i=0; i<_result[0].Time.size(); i++) { _result[0].IC[i].x = curv.traj[0].Pos[i]; } if(flagExport==true) { //printf("approximate: There are %f axes and %f segments\n", (double)_result[0].Time.size(), (double)_result.size()); fp_segMotion = fopen("SmSegMotion.dat", "w"); if(fp_segMotion==NULL) { SM_LOG(SM_LOG_ERROR, " cannot open file to write the trajectory"); return 1; } for (unsigned int i = 0; i < _result.size(); i++){ fprintf(fp_segMotion, "%d %lf ",_result[i].premier_point, (_result[i].premier_point + 1) * _sampling); for(unsigned int k=0; k<_result[i].Time.size(); k++) { fprintf(fp_segMotion, "%lf %lf ",_result[i].Time[k],_result[i].Jerk[k]); } fprintf(fp_segMotion, "\n"); } fclose(fp_segMotion); //cout << "motion file exported" << endl; //printf("approximate: There are %f axes and %f segments\n", (double)_result[0].Time.size(), (double)_result.size()); } // importe le resultat _result dans une classe de type SM_TRAJ Attention on recalcule tte les conditions initiales // de chaque segment dans cette fonction ainsi que la duree totale de la trajectoire a partir des couples (Ti, Ji) smTraj.importFromSM_OUTPUT(36, _sampling, _result); //cout << " ... Approximated Trajectory Computed --" << endl; if(flagExport==true) { smTraj.save((char*)"SmApproxTraj_Seg.traj"); SM_LOG(SM_LOG_INFO, "Sm_Approx::approximate Series of cubics Trajectory Saved"); } /* compare end point */ /* verification du point final atteint par smTraj par rapport a IdealTraj */ std::vector< SM_COND> cond; smTraj.getMotionCond(smTraj.getDuration(), cond); double errMax =0; for(unsigned int i=0; i<cond.size(); i++) { double err = fabs(cond[i].x - (_curve.back()).traj[ (_curve.back()).traj.size()-1].Pos[i] ); if( err > 0.001) { SM_LOG(SM_LOG_WARNING, "Sm_Approx::approximate: final pose on axis " << i << ", err=" << err); } if(err > errMax){ errMax = err; } } if(errMax < 0.001) { SM_LOG(SM_LOG_INFO, "Sm_Approx::approximate runs successfully ... Algo Written by Xavier BROQUERE (Feb 2011)"); } //printf("Final Conditions of the Ideal trajectory\n"); //for(unsigned int i=0; i<cond.size(); i++) { // printf("%f ",(_curve.back()).traj[ (_curve.back()).traj.size()-1].Pos[i] ); //} //printf("\n"); //printf("Final Conditions of the smTraj trajectory\n"); //for(unsigned int i=0; i<cond.size(); i++) { // printf("%f ",cond[i].x); //} //printf("\n"); return 0; }