00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <math.h>
00019 #include <algorithm>
00020 #include <string>
00021 #include <boost/lexical_cast.hpp>
00022
00023 #include <ros/ros.h>
00024 #include <std_srvs/Trigger.h>
00025 #include <cob_srvs/SetString.h>
00026
00027 #include <cob_cartesian_controller/cartesian_controller.h>
00028
00029 bool CartesianController::initialize()
00030 {
00031 ros::NodeHandle nh_private("~");
00032
00033 if (!nh_.getParam("chain_tip_link", chain_tip_link_))
00034 {
00035 ROS_ERROR("Parameter 'chain_tip_link' not set");
00036 return false;
00037 }
00038
00039 if (!nh_.getParam("root_frame", root_frame_))
00040 {
00041 ROS_ERROR("Parameter 'reference_frame' not set");
00042 return false;
00043 }
00044
00045 if (!nh_.getParam("update_rate", update_rate_))
00046 {
00047 update_rate_ = 50.0;
00048 }
00049
00051 if (!nh_private.getParam("target_frame", target_frame_))
00052 {
00053 ROS_WARN("Parameter 'target_frame' not set. Using default 'cartesian_target'");
00054 target_frame_ = DEFAULT_CARTESIAN_TARGET;
00055 }
00056
00057 ROS_WARN("Waiting for Services...");
00058 start_tracking_ = nh_.serviceClient<cob_srvs::SetString>("frame_tracker/start_tracking");
00059 stop_tracking_ = nh_.serviceClient<std_srvs::Trigger>("frame_tracker/stop");
00060 start_tracking_.waitForExistence();
00061 stop_tracking_.waitForExistence();
00062 tracking_ = false;
00063
00064 trajectory_interpolator_.reset(new TrajectoryInterpolator(root_frame_, update_rate_));
00065
00066 action_name_ = "cartesian_trajectory_action";
00067 as_.reset(new SAS_CartesianControllerAction_t(nh_, action_name_, false));
00068 as_->registerGoalCallback(boost::bind(&CartesianController::goalCallback, this));
00069 as_->registerPreemptCallback(boost::bind(&CartesianController::preemptCallback, this));
00070 as_->start();
00071
00072 ROS_INFO("Cartesian Controller running");
00073 return true;
00074 }
00075
00076
00077 bool CartesianController::startTracking()
00078 {
00079 bool success = false;
00080 cob_srvs::SetString start;
00081 start.request.data = target_frame_;
00082 if (!tracking_)
00083 {
00084 success = start_tracking_.call(start);
00085
00086 if (success)
00087 {
00088 success = start.response.success;
00089 if (success)
00090 {
00091 ROS_INFO("Response 'start_tracking': succeded");
00092 tracking_ = true;
00093 }
00094 else
00095 {
00096 ROS_ERROR("Response 'start_tracking': failed");
00097 }
00098 }
00099 else
00100 {
00101 ROS_ERROR("Failed to call service 'start_tracking'");
00102 }
00103 }
00104 else
00105 {
00106 ROS_WARN("Already tracking");
00107 }
00108
00109 return success;
00110 }
00111
00112
00113 bool CartesianController::stopTracking()
00114 {
00115 bool success = false;
00116 std_srvs::Trigger stop;
00117 if (tracking_)
00118 {
00119 success = stop_tracking_.call(stop);
00120
00121 if (success)
00122 {
00123 ROS_INFO("Service 'stop' succeded!");
00124 tracking_ = false;
00125 }
00126 else
00127 {
00128 ROS_ERROR("Failed to call service 'stop_tracking'");
00129 }
00130 }
00131 else
00132 {
00133 ROS_WARN("Have not been tracking");
00134 }
00135
00136 return success;
00137 }
00138
00139
00140 bool CartesianController::posePathBroadcaster(const geometry_msgs::PoseArray& cartesian_path)
00141 {
00142 bool success = true;
00143 ros::Rate rate(update_rate_);
00144 tf::Transform transform;
00145
00146 for (unsigned int i = 0; i < cartesian_path.poses.size(); i++)
00147 {
00148 if (!as_->isActive())
00149 {
00150 success = false;
00151 break;
00152 }
00153
00154
00155 transform.setOrigin(tf::Vector3(cartesian_path.poses.at(i).position.x,
00156 cartesian_path.poses.at(i).position.y,
00157 cartesian_path.poses.at(i).position.z));
00158 transform.setRotation(tf::Quaternion(cartesian_path.poses.at(i).orientation.x,
00159 cartesian_path.poses.at(i).orientation.y,
00160 cartesian_path.poses.at(i).orientation.z,
00161 cartesian_path.poses.at(i).orientation.w));
00162
00163 tf_broadcaster_.sendTransform(tf::StampedTransform(transform, ros::Time::now(), cartesian_path.header.frame_id, target_frame_));
00164
00165 ros::spinOnce();
00166 rate.sleep();
00167 }
00168
00169 return success;
00170 }
00171
00172
00173 void CartesianController::goalCallback()
00174 {
00175 geometry_msgs::PoseArray cartesian_path;
00176 cob_cartesian_controller::CartesianActionStruct action_struct;
00177
00178 action_struct = acceptGoal(as_->acceptNewGoal());
00179
00180 if (action_struct.move_type == cob_cartesian_controller::CartesianControllerGoal::LIN)
00181 {
00182
00183 if (!trajectory_interpolator_->linearInterpolation(cartesian_path, action_struct))
00184 {
00185 actionAbort(false, "Failed to do interpolation for 'move_lin'");
00186 return;
00187 }
00188
00189
00190 utils_.previewPath(cartesian_path);
00191
00192
00193 tf::Transform identity = tf::Transform();
00194 identity.setIdentity();
00195 tf_broadcaster_.sendTransform(tf::StampedTransform(identity, ros::Time::now(), chain_tip_link_, target_frame_));
00196
00197
00198 if (!startTracking())
00199 {
00200 actionAbort(false, "Failed to start tracking");
00201 return;
00202 }
00203
00204
00205 if (!posePathBroadcaster(cartesian_path))
00206 {
00207 actionAbort(false, "Failed to execute path for 'move_lin'");
00208 return;
00209 }
00210
00211
00212 if (!stopTracking())
00213 {
00214 actionAbort(false, "Failed to stop tracking");
00215 return;
00216 }
00217
00218 actionSuccess(true, "move_lin succeeded!");
00219 }
00220 else if (action_struct.move_type == cob_cartesian_controller::CartesianControllerGoal::CIRC)
00221 {
00222 if (!trajectory_interpolator_->circularInterpolation(cartesian_path, action_struct))
00223 {
00224 actionAbort(false, "Failed to do interpolation for 'move_circ'");
00225 return;
00226 }
00227
00228
00229 utils_.previewPath(cartesian_path);
00230
00231
00232 if (!startTracking())
00233 {
00234 actionAbort(false, "Failed to start tracking");
00235 return;
00236 }
00237
00238
00239 if (!posePathBroadcaster(cartesian_path))
00240 {
00241 actionAbort(false, "Failed to execute path for 'move_circ'");
00242 return;
00243 }
00244
00245
00246 if (!stopTracking())
00247 {
00248 actionAbort(false, "Failed to stop tracking");
00249 return;
00250 }
00251
00252 actionSuccess(true, "move_circ succeeded!");
00253 }
00254 else
00255 {
00256 actionAbort(false, "Unknown trajectory action");
00257 return;
00258 }
00259 }
00260
00261 cob_cartesian_controller::MoveLinStruct CartesianController::convertMoveLin(const cob_cartesian_controller::MoveLin& move_lin_msg)
00262 {
00263 geometry_msgs::Pose start, end;
00264 start = utils_.getPose(root_frame_, chain_tip_link_);
00265 utils_.transformPose(move_lin_msg.frame_id, root_frame_, move_lin_msg.pose_goal, end);
00266
00267 cob_cartesian_controller::MoveLinStruct move_lin;
00268
00269 move_lin.start = start;
00270 move_lin.end = end;
00271
00272 return move_lin;
00273 }
00274
00275 cob_cartesian_controller::MoveCircStruct CartesianController::convertMoveCirc(const cob_cartesian_controller::MoveCirc& move_circ_msg)
00276 {
00277 geometry_msgs::Pose center;
00278 utils_.transformPose(move_circ_msg.frame_id, root_frame_, move_circ_msg.pose_center, center);
00279
00280 cob_cartesian_controller::MoveCircStruct move_circ;
00281 move_circ.start_angle = move_circ_msg.start_angle;
00282 move_circ.end_angle = move_circ_msg.end_angle;
00283 move_circ.radius = move_circ_msg.radius;
00284
00285 move_circ.pose_center = center;
00286
00287 return move_circ;
00288 }
00289
00290 cob_cartesian_controller::CartesianActionStruct CartesianController::acceptGoal(boost::shared_ptr<const cob_cartesian_controller::CartesianControllerGoal> goal)
00291 {
00292 cob_cartesian_controller::CartesianActionStruct action_struct;
00293 action_struct.move_type = goal->move_type;
00294
00295 action_struct.profile.vel = goal->profile.vel;
00296 action_struct.profile.accl = goal->profile.accl;
00297 action_struct.profile.profile_type = goal->profile.profile_type;
00298 action_struct.profile.t_ipo = 1/update_rate_;
00299
00300
00301 if (action_struct.move_type == cob_cartesian_controller::CartesianControllerGoal::LIN)
00302 {
00303 action_struct.move_lin = convertMoveLin(goal->move_lin);
00304 }
00305 else if (action_struct.move_type == cob_cartesian_controller::CartesianControllerGoal::CIRC)
00306 {
00307 action_struct.move_circ = convertMoveCirc(goal->move_circ);
00308 }
00309 else
00310 {
00311 actionAbort(false, "Unknown trajectory action " + boost::lexical_cast<std::string>(action_struct.move_type));
00312 }
00313
00314 return action_struct;
00315 }
00316
00317 void CartesianController::preemptCallback()
00318 {
00319
00320 stopTracking();
00321 actionPreempt(true, "action preempted!");
00322 }
00323
00324 void CartesianController::actionSuccess(const bool success, const std::string& message)
00325 {
00326 ROS_INFO_STREAM("Goal succeeded: " << message);
00327 action_result_.success = success;
00328 action_result_.message = message;
00329 as_->setSucceeded(action_result_, action_result_.message);
00330 }
00331
00332 void CartesianController::actionPreempt(const bool success, const std::string& message)
00333 {
00334 ROS_WARN_STREAM("Goal preempted: " << message);
00335 action_result_.success = success;
00336 action_result_.message = message;
00337 as_->setPreempted(action_result_, action_result_.message);
00338 }
00339
00340 void CartesianController::actionAbort(const bool success, const std::string& message)
00341 {
00342 ROS_ERROR_STREAM("Goal aborted: " << message);
00343 action_result_.success = success;
00344 action_result_.message = message;
00345 as_->setAborted(action_result_, action_result_.message);
00346 stopTracking();
00347 }