Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <cob_trajectory_controller/genericArmCtrl.h>
00019 #include <fstream>
00020 #include <cob_trajectory_controller/RefValJS_PTP_Trajectory.h>
00021 #include <cob_trajectory_controller/RefValJS_PTP.h>
00022
00023
00024
00025
00026
00027
00028
00029
00030 #define STD_CHECK_PROCEDURE() \
00031 if ( isMoving ) \
00032 { \
00033 ROS_WARN("Manipulator still in motion, call stop first!"); \
00034 return false; \
00035 } \
00036 if (m_pRefVals != NULL) { \
00037 delete m_pRefVals; \
00038 m_pRefVals = NULL; \
00039 }
00040
00041
00042 #define START_CTRL_JOB(info) \
00043 if ( m_cThread.startJob(m_pRefVals) == false ) { \
00044 m_ErrorMsg.assign("Internal Error: Unable to start movement, other control Job still active."); \
00045 return false; \
00046 } else { \s \
00047 return true; \
00048 }
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 genericArmCtrl::genericArmCtrl(int DOF, double PTPvel, double PTPacc, double maxError)
00059 {
00060
00061 m_DOF = DOF;
00062
00063 m_pRefVals = NULL;
00064
00065 isMoving = false;
00066
00067
00068 SetPTPvel(PTPvel);
00069 SetPTPacc(PTPacc);
00070
00071
00072 m_P = 4.0;
00073 m_Vorsteuer = 0.9;
00074 m_AllowedError = maxError;
00075 m_CurrentError = 0.0;
00076 m_TargetError = 0.02;
00077 overlap_time = 0.4;
00078 m_ExtraTime = 3;
00079
00080 }
00081
00082
00083 genericArmCtrl::~genericArmCtrl()
00084 {
00085 if (m_pRefVals != NULL)
00086 delete m_pRefVals;
00087 }
00088
00089
00090
00091
00092
00093 std::vector<double> genericArmCtrl::GetPTPvel() const
00094 { return m_vel_js; }
00095
00096 std::vector<double> genericArmCtrl::GetPTPacc() const
00097 { return m_acc_js; }
00098
00099
00100
00101
00102
00103
00104
00105
00106 void genericArmCtrl::SetPTPvel(double vel)
00107 {
00108 m_vel_js.resize(m_DOF);
00109 for (int i = 0; i < m_DOF; i++)
00110 m_vel_js.at(i) = vel;
00111 }
00112
00113 void genericArmCtrl::SetPTPacc(double acc)
00114 {
00115 m_acc_js.resize(m_DOF);
00116 for (int i = 0; i < m_DOF; i++)
00117 m_acc_js.at(i) = acc;
00118 }
00119
00120
00121
00122
00123
00125 bool genericArmCtrl::moveThetas(std::vector<double> conf_goal, std::vector<double> conf_current)
00126 {
00127
00128 STD_CHECK_PROCEDURE()
00129
00130
00131 double vel = 10000;
00132 for (unsigned int i = 0; i<m_vel_js.size(); i++)
00133 {
00134 if(m_vel_js.at(i) < vel)
00135 vel = m_vel_js.at(i);
00136 }
00137 double acc = 10000;
00138 for (unsigned int i = 0; i<m_acc_js.size(); i++)
00139 {
00140 if(m_acc_js.at(i) < acc)
00141 acc = m_acc_js.at(i);
00142 }
00143
00144 ;
00145 m_pRefVals = new RefValJS_PTP(conf_current, conf_goal, vel, acc);
00146 startTime_.SetNow();
00147 isMoving = true;
00148 TotalTime_ = m_pRefVals->getTotalTime();
00149 ROS_INFO("Starting control of trajectory: %f s long", TotalTime_);
00150
00151 return true;
00152 }
00153
00154 bool genericArmCtrl::moveTrajectory(trajectory_msgs::JointTrajectory pfad, std::vector<double> conf_current)
00155 {
00156
00157 if (pfad.points.size() == 2)
00158 {
00159 return moveThetas(pfad.points[1].positions, conf_current);
00160 }
00161 for(unsigned int i = 0; i < pfad.points.front().positions.size(); i++ )
00162 {
00163 if((pfad.points.front().positions.at(i) - conf_current.at(i)) > 0.25)
00164 {
00165 ROS_ERROR("Cannot start trajectory motion, manipulator not in trajectory start position.");
00166 return false;
00167 }
00168 }
00169
00170
00171 STD_CHECK_PROCEDURE()
00172
00173
00174 double vel = m_vel_js.at(0);
00175 for (unsigned int i = 0; i<m_vel_js.size(); i++)
00176 {
00177 if(m_vel_js.at(i) < vel)
00178 vel = m_vel_js.at(i);
00179 }
00180 double acc = m_acc_js.at(0);
00181 for (unsigned int i = 0; i<m_acc_js.size(); i++)
00182 {
00183 if(m_acc_js.at(i) < acc)
00184 acc = m_acc_js.at(i);
00185 }
00186 m_pRefVals = new RefValJS_PTP_Trajectory(pfad, vel, acc, true);
00187
00188
00189 startTime_.SetNow();
00190 isMoving = true;
00191 TotalTime_ = m_pRefVals->getTotalTime();
00192 ROS_INFO("Starting control of trajectory: %f s long", TotalTime_);
00193
00194
00195 return true;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 bool genericArmCtrl::step(std::vector<double> current_pos, std::vector<double> & desired_vel)
00222 {
00223 if(isMoving)
00224 {
00225 TimeStamp timeNow_;
00226 timeNow_.SetNow();
00227
00228 if ( m_pRefVals == NULL )
00229 return false;
00230 double t = timeNow_ - startTime_;
00231 std::vector<double> m_qsoll = m_pRefVals->r_t( t );
00232 std::vector<double> m_vsoll = m_pRefVals->dr_dt(t);
00233
00234 if(t < TotalTime_)
00235 {
00236 if(t < overlap_time)
00237 {
00238 last_q = m_pRefVals->r_t( 0.0 );
00239 last_q1 = m_pRefVals->r_t( 0.0 );
00240 last_q2 = m_pRefVals->r_t( 0.0 );
00241 last_q3 = m_pRefVals->r_t( 0.0 );
00242 }
00243 else
00244 {
00245 last_q = m_pRefVals->r_t( t - overlap_time );
00246 last_q1 = m_pRefVals->r_t( t - (3.0*overlap_time/4.0) );
00247 last_q2 = m_pRefVals->r_t( t - (overlap_time/2.0) );
00248 last_q3 = m_pRefVals->r_t( t - (overlap_time/4.0) );
00249 }
00250 }
00251
00252 double len = 0;
00253 for(int i = 0; i < m_DOF; i++)
00254 {
00255 len += (m_qsoll.at(i) - current_pos.at(i)) * (m_qsoll.at(i) - current_pos.at(i));
00256 }
00257 m_CurrentError = sqrt(len);
00258 if ( m_pRefVals != NULL && t < TotalTime_ + m_ExtraTime && (m_CurrentError > m_TargetError || t < TotalTime_) )
00259 {
00260 if ( m_CurrentError >= m_AllowedError )
00261 {
00262 ROS_ERROR("Current control error exceeds limit: %f >= %f", m_CurrentError, m_AllowedError);
00263
00264
00265
00266 isMoving = false;
00267 return false;
00268 }
00269 desired_vel.resize(m_DOF);
00270
00271 for(int i = 0; i < m_DOF; i++)
00272 {
00273 desired_vel.at(i) = m_vsoll.at(i) * m_Vorsteuer + ( m_qsoll.at(i) - current_pos.at(i) ) * m_P;
00274 }
00275
00276 return true;
00277 }
00278 else
00279 {
00280 ROS_INFO("Probably finished trajectory");
00281 isMoving = false;
00282 desired_vel.resize(m_DOF);
00283 for(int i = 0; i < m_DOF; i++)
00284 {
00285 desired_vel.at(i) = 0.0;
00286 }
00287 return true;
00288 }
00289 }
00290 return false;
00291 }
00292
00293
00294
00295