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
00035
00036
00037 #include <pr2_doors_common/door_functions.h>
00038 #include <geometry_msgs/PoseStamped.h>
00039 #include "pr2_doors_actions/action_push_door.h"
00040
00041 using namespace tf;
00042 using namespace KDL;
00043 using namespace ros;
00044 using namespace std;
00045 using namespace door_handle_detector;
00046 using namespace pr2_doors_common;
00047 using namespace actionlib;
00048
00049 static const string fixed_frame = "odom_combined";
00050 static const double push_dist = 0.65;
00051 static const double push_vel = 10.0 * M_PI/180.0;
00052
00053
00054
00055 PushDoorAction::PushDoorAction(tf::TransformListener& tf) :
00056 tf_(tf),
00057 action_server_(ros::NodeHandle(),
00058 "push_door",
00059 boost::bind(&PushDoorAction::execute, this, _1))
00060 {
00061 pose_pub_ = node_.advertise<geometry_msgs::PoseStamped>("r_arm_constraint_cartesian_pose_controller/command",20);
00062 };
00063
00064
00065 PushDoorAction::~PushDoorAction()
00066 {};
00067
00068
00069
00070 void PushDoorAction::execute(const door_msgs::DoorGoalConstPtr& goal)
00071 {
00072 ROS_INFO("PushDoorAction: execute");
00073
00074
00075 door_msgs::Door goal_tr;
00076 if (!transformTo(tf_, fixed_frame, goal->door, goal_tr, fixed_frame)){
00077 ROS_ERROR("Could not tranform door message from '%s' to '%s' at time %f",
00078 goal->door.header.frame_id.c_str(), fixed_frame.c_str(), goal->door.header.stamp.toSec());
00079 action_server_.setPreempted();
00080 return;
00081 }
00082
00083
00084 pose_state_received_ = false;
00085 Subscriber sub = node_.subscribe("r_arm_constraint_cartesian_pose_controller/state/pose", 1, &PushDoorAction::poseCallback, this);
00086 Duration timeout = Duration().fromSec(3.0);
00087 Duration poll = Duration().fromSec(0.1);
00088 Time start_time = ros::Time::now();
00089 while (!pose_state_received_){
00090 if (start_time + timeout < ros::Time::now()){
00091 ROS_ERROR("failed to receive pose state");
00092 action_server_.setPreempted();
00093 return;
00094 }
00095 poll.sleep();
00096 }
00097
00098
00099 Duration sleep_time(0.01);
00100 double angle_step = 0;
00101 StampedTransform shoulder_pose; tf_.lookupTransform(goal_tr.header.frame_id, "r_shoulder_pan_link", Time(), shoulder_pose);
00102 if (goal_tr.rot_dir == door_msgs::Door::ROT_DIR_CLOCKWISE)
00103 angle_step = -push_vel*sleep_time.toSec();
00104 else if (goal_tr.rot_dir == door_msgs::Door::ROT_DIR_COUNTERCLOCKWISE)
00105 angle_step = push_vel*sleep_time.toSec();
00106 else{
00107 ROS_ERROR("door rotation direction not specified");
00108 action_server_.setPreempted();
00109 return;
00110 }
00111
00112
00113 Stamped<Pose> gripper_pose;
00114 geometry_msgs::PoseStamped gripper_pose_msg;
00115 double angle = getNearestDoorAngle(shoulder_pose, goal_tr, 0.75, push_dist);
00116 while (!action_server_.isPreemptRequested()){
00117 sleep_time.sleep();
00118
00119
00120 gripper_pose = getGripperPose(goal_tr, angle, push_dist);
00121 gripper_pose.stamp_ = Time::now();
00122 poseStampedTFToMsg(gripper_pose, gripper_pose_msg);
00123 pose_pub_.publish(gripper_pose_msg);
00124
00125
00126 boost::mutex::scoped_lock lock(pose_mutex_);
00127 if (fabs(angle) < M_PI/2.0)
00128 angle += angle_step;
00129 }
00130 ROS_ERROR("PushDoorAction: preempted");
00131 action_server_.setPreempted();
00132 }
00133
00134
00135 void PushDoorAction::poseCallback(const PoseConstPtr& pose)
00136 {
00137 boost::mutex::scoped_lock lock(pose_mutex_);
00138 poseStampedMsgToTF(*pose, pose_state_);
00139 pose_state_received_ = true;
00140 }
00141