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
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #include <trajectory_execution_monitor/trajectory_execution_monitor.h>
00038 #include <trajectory_execution_monitor/trajectory_stats.h>
00039
00040 using namespace trajectory_execution_monitor;
00041
00042 TrajectoryExecutionRequest::TrajectoryExecutionRequest() :
00043 monitor_overshoot_(false),
00044 max_overshoot_velocity_epsilon_(20),
00045 min_overshoot_time_(ros::Duration(0.5)),
00046 max_overshoot_time_(ros::Duration(0.01)),
00047 failure_ok_(false),
00048 test_for_close_enough_(false),
00049 max_joint_distance_(0.01),
00050 failure_time_factor_(1.5)
00051 {}
00052
00053 void TrajectoryExecutionMonitor::addTrajectoryRecorder(boost::shared_ptr<TrajectoryRecorder>& trajectory_recorder) {
00054 trajectory_recorder_map_[trajectory_recorder->getName()] = trajectory_recorder;
00055 }
00056
00057 void TrajectoryExecutionMonitor::addTrajectoryControllerHandler(boost::shared_ptr<TrajectoryControllerHandler>& trajectory_controller_handler) {
00058 trajectory_controller_handler_map_[trajectory_controller_handler->getGroupControllerComboName()] =
00059 trajectory_controller_handler;
00060 }
00061
00062 void TrajectoryExecutionMonitor::executeTrajectories(const std::vector<TrajectoryExecutionRequest>& to_execute,
00063 const boost::function<bool(TrajectoryExecutionDataVector)>& done_callback) {
00064
00065 execution_data_ = &to_execute;
00066 execution_result_vector_.reset();
00067 result_callback_ = done_callback;
00068
00069 current_trajectory_index_ = 0;
00070
00071 if(!sendTrajectory((*execution_data_)[current_trajectory_index_])) {
00072 result_callback_(execution_result_vector_);
00073 }
00074 };
00075
00076 bool TrajectoryExecutionMonitor::sendTrajectory(const TrajectoryExecutionRequest& ter) {
00077
00078 execution_result_vector_.resize(execution_result_vector_.size()+1);
00079
00080 std::string recorder_name = ter.recorder_name_;
00081 if(trajectory_recorder_map_.size() == 1) {
00082 recorder_name = trajectory_recorder_map_.begin()->second->getName();
00083 }
00084
00085 if(trajectory_recorder_map_.find(ter.recorder_name_) == trajectory_recorder_map_.end() &&
00086 trajectory_recorder_map_.size() > 1) {
00087 execution_result_vector_.back().result_ = NO_RECORDER;
00088 return false;
00089 }
00090
00091 std::string combo_name = TrajectoryControllerHandler::combineGroupAndControllerNames(ter.group_name_,
00092 ter.controller_name_);
00093
00094 if(trajectory_controller_handler_map_.find(combo_name) == trajectory_controller_handler_map_.end()) {
00095 execution_result_vector_.back().result_ = NO_HANDLER;
00096 return false;
00097 }
00098
00099 boost::shared_ptr<TrajectoryRecorder>& requested_recorder = trajectory_recorder_map_.find(recorder_name)->second;
00100 last_requested_handler_ = trajectory_controller_handler_map_.find(combo_name)->second;
00101
00102
00103 if(ter.monitor_overshoot_)
00104 {
00105 last_requested_handler_->enableOvershoot(ter.max_overshoot_velocity_epsilon_, ter.min_overshoot_time_, ter.max_overshoot_time_);
00106 }
00107 else
00108 {
00109 last_requested_handler_->disableOvershoot();
00110 }
00111
00112
00113 trajectory_msgs::JointTrajectory traj = ter.trajectory_;
00114 ros::Duration traj_dur = TrajectoryStats::getDuration(traj);
00115 if( traj_dur > ros::Duration(0.1) )
00116 {
00117 last_requested_handler_->setMaximumExecutionTime(traj_dur * ter.failure_time_factor_);
00118 }
00119
00120 traj.header.stamp = ros::Time::now();
00121 if(!last_requested_handler_->executeTrajectory(
00122 traj,
00123 requested_recorder,
00124 boost::bind(&TrajectoryExecutionMonitor::trajectoryFinishedCallbackFunction, this, _1))
00125 )
00126 {
00127 execution_result_vector_.back().result_ = HANDLER_FAILED_ENTIRELY;
00128 }
00129 return true;
00130 }
00131
00132 void TrajectoryExecutionMonitor::trajectoryFinishedCallbackFunction(
00133 TrajectoryControllerState controller_state )
00134 {
00135
00136 execution_result_vector_.back().recorded_trajectory_ = last_requested_handler_->getLastRecordedTrajectory();
00137 execution_result_vector_.back().overshoot_trajectory_ = last_requested_handler_->getLastOvershootTrajectory();
00138
00139 const TrajectoryExecutionRequest& req = (*execution_data_)[current_trajectory_index_];
00140 bool ok = ( controller_state==TrajectoryControllerStates::SUCCESS ||
00141 controller_state==TrajectoryControllerStates::OVERSHOOT_TIMEOUT);
00142 bool continue_execution =
00143 ok ||
00144 req.failure_ok_ ||
00145 ( req.test_for_close_enough_ && closeEnough(req,execution_result_vector_.back()));
00146
00147 if( continue_execution )
00148 {
00149 ROS_INFO_STREAM("Trajectory finished");
00150
00151
00152 TrajectoryExecutionData & data = execution_result_vector_.back();
00153 data.time_ = TrajectoryStats::getDuration(data.recorded_trajectory_);
00154 data.overshoot_time_ = TrajectoryStats::getDuration(data.overshoot_trajectory_);
00155 data.angular_distance_ = TrajectoryStats::getAngularDistance(data.recorded_trajectory_);
00156
00157 if(!ok) {
00158 if(req.failure_ok_) {
00159 execution_result_vector_.back().result_ = HANDLER_REPORTS_FAILURE_BUT_OK;
00160 } else {
00161 execution_result_vector_.back().result_ = HANDLER_REPORTS_FAILURE_BUT_CLOSE_ENOUGH;
00162 }
00163 } else {
00164 execution_result_vector_.back().result_ = SUCCEEDED;
00165 }
00166 if(req.callback_function_) {
00167 req.callback_function_(req.group_name_);
00168 }
00169
00170 current_trajectory_index_++;
00171 if(current_trajectory_index_ >= execution_data_->size()) {
00172 result_callback_(execution_result_vector_);
00173 return;
00174 }
00175 for(int i = (int)current_trajectory_index_-1; i >= 0; i--) {
00176 if((*execution_data_)[i].group_name_ == (*execution_data_)[current_trajectory_index_].group_name_) {
00177 ROS_INFO_STREAM("Last index is " << i << " current is " << current_trajectory_index_);
00178 compareLastRecordedToStart((*execution_data_)[i],
00179 (*execution_data_)[current_trajectory_index_],
00180 execution_result_vector_[i]);
00181 break;
00182 }
00183 }
00184
00185
00186 if(!sendTrajectory((*execution_data_)[current_trajectory_index_])) {
00187 result_callback_(execution_result_vector_);
00188 }
00189 } else {
00190 ROS_ERROR_STREAM( "Trajectory finished with failure. controller_state=" << controller_state <<
00191 ". Stopping the remaining trajectories" << std::endl );
00192 execution_result_vector_.back().result_ = HANDLER_REPORTS_FAILURE;
00193 result_callback_(execution_result_vector_);
00194 }
00195 };
00196
00197 bool TrajectoryExecutionMonitor::closeEnough(const TrajectoryExecutionRequest& ter,
00198 const TrajectoryExecutionData& ted) {
00199 if(ted.recorded_trajectory_.points.size() == 0) {
00200 ROS_WARN_STREAM("No points in recorded trajectory");
00201 return false;
00202 }
00203 ROS_WARN_STREAM("Comparing trajectories trajectory");
00204 double total_distance = TrajectoryStats::distance(ter.trajectory_.points.back(),ted.recorded_trajectory_.points.back());
00205 if(total_distance < ter.max_joint_distance_) {
00206 ROS_INFO_STREAM("Allowing because max distance low " << total_distance);
00207 return true;
00208 }
00209 for(unsigned int i = 0; i < ter.trajectory_.points.back().positions.size(); i++) {
00210 ROS_INFO_STREAM("Distance for " << ter.trajectory_.joint_names[i] << " is " << fabs(ter.trajectory_.points.back().positions[i]-ted.recorded_trajectory_.points.back().positions[i]));
00211 }
00212
00213 ROS_INFO_STREAM("Not allowing because max distance high " << total_distance);
00214 return false;
00215 }
00216
00217 void TrajectoryExecutionMonitor::compareLastRecordedToStart(const TrajectoryExecutionRequest& last_ter,
00218 const TrajectoryExecutionRequest& next_ter,
00219 const TrajectoryExecutionData& ted)
00220 {
00221 if(ted.recorded_trajectory_.points.size() == 0) {
00222 ROS_WARN_STREAM("No points in recorded trajectory for comparison");
00223 return;
00224 }
00225
00226 planning_models::KinematicState last_recorded_state(cm_.getKinematicModel());
00227 planning_models::KinematicState last_requested_state(cm_.getKinematicModel());
00228 planning_models::KinematicState next_requested_state(cm_.getKinematicModel());
00229
00230 last_recorded_state.setKinematicStateToDefault();
00231 last_requested_state.setKinematicStateToDefault();
00232 next_requested_state.setKinematicStateToDefault();
00233
00234 std::map<std::string, double> last_recorded_values;
00235 for(unsigned int i = 0; i < ted.recorded_trajectory_.points.back().positions.size(); i++) {
00236 ROS_INFO_STREAM("Last recorded " << ted.recorded_trajectory_.joint_names[i] << " value " << ted.recorded_trajectory_.points.back().positions[i]);
00237 last_recorded_values[ted.recorded_trajectory_.joint_names[i]] = ted.recorded_trajectory_.points.back().positions[i];
00238 }
00239
00240 std::map<std::string, double> last_requested_values;
00241 for(unsigned int i = 0; i < last_ter.trajectory_.points.front().positions.size(); i++) {
00242 ROS_INFO_STREAM("Last requested " << last_ter.trajectory_.joint_names[i] << " value " << last_ter.trajectory_.points.back().positions[i]);
00243 last_requested_values[last_ter.trajectory_.joint_names[i]] = last_ter.trajectory_.points.back().positions[i];
00244 }
00245
00246 std::map<std::string, double> next_requested_values;
00247 for(unsigned int i = 0; i < next_ter.trajectory_.points.front().positions.size(); i++) {
00248 ROS_INFO_STREAM("Next requested " << next_ter.trajectory_.joint_names[i] << " value " << next_ter.trajectory_.points.front().positions[i]);
00249 next_requested_values[next_ter.trajectory_.joint_names[i]] = next_ter.trajectory_.points.front().positions[i];
00250 }
00251
00252 last_recorded_state.setKinematicState(last_recorded_values);
00253 last_requested_state.setKinematicState(last_requested_values);
00254 next_requested_state.setKinematicState(next_requested_values);
00255
00256 tf::Transform recorded_pose = last_recorded_state.getLinkState("r_wrist_roll_link")->getGlobalLinkTransform();
00257 tf::Transform last_requested_pose = last_requested_state.getLinkState("r_wrist_roll_link")->getGlobalLinkTransform();
00258 tf::Transform next_requested_pose = next_requested_state.getLinkState("r_wrist_roll_link")->getGlobalLinkTransform();
00259
00260 ROS_INFO_STREAM("Diff in last requested versus recorded is "
00261 << fabs(recorded_pose.getOrigin().x()-last_requested_pose.getOrigin().x()) << " "
00262 << fabs(recorded_pose.getOrigin().y()-last_requested_pose.getOrigin().y()) << " "
00263 << fabs(recorded_pose.getOrigin().z()-last_requested_pose.getOrigin().z()));
00264
00265 ROS_INFO_STREAM("Diff is last requested versus next requested "
00266 << fabs(last_requested_pose.getOrigin().x()-next_requested_pose.getOrigin().x()) << " "
00267 << fabs(last_requested_pose.getOrigin().y()-next_requested_pose.getOrigin().y()) << " "
00268 << fabs(last_requested_pose.getOrigin().z()-next_requested_pose.getOrigin().z()));
00269
00270 ROS_INFO_STREAM("Diff is last recorded versus next requested "
00271 << fabs(recorded_pose.getOrigin().x()-next_requested_pose.getOrigin().x()) << " "
00272 << fabs(recorded_pose.getOrigin().y()-next_requested_pose.getOrigin().y()) << " "
00273 << fabs(recorded_pose.getOrigin().z()-next_requested_pose.getOrigin().z()));
00274 }