Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <actionlib/server/simple_action_server.h>
00003 #include <cob_lookat_action/LookAtAction.h>
00004 #include <actionlib/client/simple_action_client.h>
00005 #include <actionlib/client/terminal_state.h>
00006 #include <control_msgs/FollowJointTrajectoryAction.h>
00007 #include <trajectory_msgs/JointTrajectory.h>
00008 #include <trajectory_msgs/JointTrajectoryPoint.h>
00009 #include <geometry_msgs/PoseStamped.h>
00010 #include <moveit_msgs/GetPositionIK.h>
00011
00012 #include <tf/transform_datatypes.h>
00013 #include <math.h>
00014
00015
00016 class CobLookAtAction
00017 {
00018 protected:
00019
00020 ros::NodeHandle nh;
00021
00022 ros::ServiceClient ik_client;
00023 actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction> *torso_ac;
00024 actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction> *head_ac;
00025
00026
00027 actionlib::SimpleActionServer<cob_lookat_action::LookAtAction> *lookat_as;
00028 std::string lookat_action_name;
00029
00030
00031 cob_lookat_action::LookAtFeedback lookat_fb;
00032 cob_lookat_action::LookAtResult lookat_res;
00033
00034 bool torso_available;
00035 bool head_available;
00036 std::vector<std::string> torso_joints;
00037 std::vector<std::string> head_joints;
00038 std::vector<std::string> lookat_joints;
00039
00040 public:
00041
00042 CobLookAtAction(std::string action_name) :
00043 lookat_action_name(action_name) {}
00044
00045 ~CobLookAtAction(void) {}
00046
00047 bool init()
00048 {
00049 torso_available = false;
00050 head_available = false;
00051
00052 torso_ac = new actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction>(nh, "/torso_controller/follow_joint_trajectory", true);
00053 head_ac = new actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction>(nh,"/head_controller/follow_joint_trajectory", true);
00054
00055 ROS_WARN("Waiting for Torso-AS");
00056 torso_available = torso_ac->waitForServer(ros::Duration(10.0));
00057 ROS_WARN("Waiting for Head-AS");
00058 head_available = head_ac->waitForServer(ros::Duration(10.0));
00059
00060 if(torso_available)
00061 {
00062 XmlRpc::XmlRpcValue tj;
00063 nh.getParam("/torso_controller/joint_names", tj);
00064 ROS_ASSERT(tj.getType() == XmlRpc::XmlRpcValue::TypeArray);
00065
00066 for (int32_t i = 0; i < tj.size(); ++i)
00067 {
00068 ROS_ASSERT(tj[i].getType() == XmlRpc::XmlRpcValue::TypeString);
00069 torso_joints.push_back(tj[i]);
00070 }
00071
00072 if(head_available)
00073 {
00074 XmlRpc::XmlRpcValue hj;
00075 nh.getParam("/head_controller/JointName", hj);
00076 ROS_ASSERT(hj.getType() == XmlRpc::XmlRpcValue::TypeString);
00077 head_joints.push_back(hj);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 }
00088
00089
00090 lookat_joints.clear();
00091 lookat_joints = torso_joints;
00092 lookat_joints.push_back("lookat_lin_joint");
00093 lookat_joints.push_back("lookat_x_joint");
00094 lookat_joints.push_back("lookat_y_joint");
00095 lookat_joints.push_back("lookat_z_joint");
00096
00097 ROS_INFO("Starting up...");
00098 ik_client = nh.serviceClient<moveit_msgs::GetPositionIK>("/compute_ik");
00099
00100 if(head_available)
00101 lookat_as = new actionlib::SimpleActionServer<cob_lookat_action::LookAtAction>(nh, lookat_action_name, boost::bind(&CobLookAtAction::goalCB, this, _1), false);
00102 else
00103 lookat_as = new actionlib::SimpleActionServer<cob_lookat_action::LookAtAction>(nh, lookat_action_name, boost::bind(&CobLookAtAction::goalCB_torso, this, _1), false);
00104
00105 lookat_as->start();
00106
00107 return true;
00108 }
00109
00110 ROS_ERROR("No torso_controller loaded!");
00111 return false;
00112 }
00113
00114 void goalCB(const cob_lookat_action::LookAtGoalConstPtr &goal)
00115 {
00116
00117 bool success = false;
00118
00119
00120
00121
00122 moveit_msgs::GetPositionIK srv;
00123 srv.request.ik_request.group_name = "lookat";
00124 srv.request.ik_request.ik_link_name = "lookat_focus_frame";
00125 srv.request.ik_request.timeout = ros::Duration(0.1);
00126 srv.request.ik_request.attempts = 1;
00127 srv.request.ik_request.pose_stamped = goal->target;
00128
00129 std::vector<double> joint_seed (lookat_joints.size(), 0.0);
00130
00131 moveit_msgs::RobotState seed;
00132 seed.joint_state.header = goal->target.header;
00133 seed.joint_state.name = lookat_joints;
00134 seed.joint_state.position = joint_seed;
00135 srv.request.ik_request.robot_state = seed;
00136
00137 if (ik_client.call(srv))
00138 {
00139
00140 if(srv.response.error_code.val == 1)
00141 {
00142 ROS_INFO("IK Solution found");
00143 success = true;
00144 }
00145 else
00146 {
00147 ROS_ERROR("No IK Solution found");
00148 success = false;
00149
00151
00152
00153 }
00154 }
00155 else
00156 {
00157 ROS_ERROR("IK-Call failed");
00158 success = false;
00159 lookat_res.success = success;
00160
00161 lookat_as->setAborted(lookat_res);
00162 return;
00163 }
00164
00165 std::vector<double> torso_config;
00166 torso_config.resize(torso_joints.size());
00167
00168 std::vector<double> head_config;
00169 head_config.resize(head_joints.size());
00170
00171 if(success)
00172 {
00173 for(unsigned int i=0, j=0; i<srv.response.solution.joint_state.name.size(); i++)
00174 {
00175
00176 if(j<torso_joints.size() && srv.response.solution.joint_state.name[i]==torso_joints[j])
00177 {
00178 torso_config[j] = srv.response.solution.joint_state.position[i];
00179 j++;
00180 }
00181 if(srv.response.solution.joint_state.name[i] == "lookat_lin_joint")
00182 if(srv.response.solution.joint_state.position[i] >= 0)
00183 head_config[0] = 0.0;
00184 else
00185 head_config[0] = -3.1415926;
00186 }
00187 }
00188
00189
00190 control_msgs::FollowJointTrajectoryGoal torso_goal;
00191 torso_goal.trajectory.header.stamp = ros::Time::now();
00192 torso_goal.trajectory.header.frame_id = "base_link";
00193 torso_goal.trajectory.joint_names = torso_joints;
00194 trajectory_msgs::JointTrajectoryPoint torso_point;
00195 torso_point.positions = torso_config;
00196 torso_point.time_from_start = ros::Duration(1.0);
00197 torso_goal.trajectory.points.push_back(torso_point);
00198
00199 control_msgs::FollowJointTrajectoryGoal head_goal;
00200 head_goal.trajectory.header.stamp = ros::Time::now();
00201 head_goal.trajectory.header.frame_id = "base_link";
00202 head_goal.trajectory.joint_names = head_joints;
00203 trajectory_msgs::JointTrajectoryPoint head_point;
00204 head_point.positions = head_config;
00205 head_point.time_from_start = ros::Duration(1.0);
00206 head_goal.trajectory.points.push_back(head_point);
00207
00208 torso_ac->sendGoal(torso_goal);
00209 head_ac->sendGoal(head_goal);
00210
00211 bool finished_before_timeout = torso_ac->waitForResult(ros::Duration(5.0)) && head_ac->waitForResult(ros::Duration(5.0));
00212
00213 if (finished_before_timeout)
00214 {
00215 ROS_INFO("Both Actions finished");
00216 success = true;
00217 }
00218 else
00219 {
00220 ROS_INFO("At leas one Action did not finish before timeout.");
00221 success = false;
00222 }
00223
00224
00225 if(success)
00226 {
00227
00228 lookat_res.success = success;
00229
00230
00231 lookat_as->setSucceeded(lookat_res);
00232 }
00233 else
00234 {
00235
00236 lookat_res.success = success;
00237
00238
00239 lookat_as->setAborted(lookat_res);
00240 }
00241 }
00242
00243 void goalCB_torso(const cob_lookat_action::LookAtGoalConstPtr &goal)
00244 {
00245
00246 bool success = false;
00247
00248
00249
00250
00251 moveit_msgs::GetPositionIK srv;
00252 srv.request.ik_request.group_name = "lookat";
00253 srv.request.ik_request.ik_link_name = "lookat_focus_frame";
00254 srv.request.ik_request.timeout = ros::Duration(0.1);
00255 srv.request.ik_request.attempts = 1;
00256 srv.request.ik_request.pose_stamped = goal->target;
00257
00258 std::vector<double> joint_seed (lookat_joints.size(), 0.0);
00259
00260 moveit_msgs::RobotState seed;
00261 seed.joint_state.header = goal->target.header;
00262 seed.joint_state.name = lookat_joints;
00263 seed.joint_state.position = joint_seed;
00264 srv.request.ik_request.robot_state = seed;
00265
00266 if (ik_client.call(srv))
00267 {
00268
00269 if(srv.response.error_code.val == 1)
00270 {
00271 ROS_INFO("IK Solution found");
00272 success = true;
00273 }
00274 else
00275 {
00276 ROS_ERROR("No IK Solution found");
00277 success = false;
00278
00280
00281
00282 }
00283 }
00284 else
00285 {
00286 ROS_ERROR("IK-Call failed");
00287 success = false;
00288 lookat_res.success = success;
00289
00290 lookat_as->setAborted(lookat_res);
00291 return;
00292 }
00293
00294 std::vector<double> torso_config;
00295 torso_config.resize(torso_joints.size());
00296
00297 if(success)
00298 {
00299 for(unsigned int i=0, j=0; i<srv.response.solution.joint_state.name.size(); i++)
00300 {
00301
00302 if(j<torso_joints.size() && srv.response.solution.joint_state.name[i]==torso_joints[j])
00303 {
00304 torso_config[j] = srv.response.solution.joint_state.position[i];
00305 j++;
00306 }
00307 }
00308 }
00309
00310
00311 control_msgs::FollowJointTrajectoryGoal torso_goal;
00312 torso_goal.trajectory.header.stamp = ros::Time::now();
00313 torso_goal.trajectory.header.frame_id = "base_link";
00314 torso_goal.trajectory.joint_names = torso_joints;
00315 trajectory_msgs::JointTrajectoryPoint torso_point;
00316 torso_point.positions = torso_config;
00317 torso_point.time_from_start = ros::Duration(1.0);
00318 torso_goal.trajectory.points.push_back(torso_point);
00319
00320 torso_ac->sendGoal(torso_goal);
00321
00322 bool finished_before_timeout = torso_ac->waitForResult(ros::Duration(5.0));
00323
00324 if (finished_before_timeout)
00325 {
00326 ROS_INFO("Action finished");
00327 success = true;
00328 }
00329 else
00330 {
00331 ROS_INFO("Action did not finish before timeout.");
00332 success = false;
00333 }
00334
00335
00336 if(success)
00337 {
00338 ROS_INFO("%s: Succeeded", lookat_action_name.c_str());
00339 lookat_res.success = success;
00340
00341
00342 lookat_as->setSucceeded(lookat_res);
00343 }
00344 else
00345 {
00346 ROS_INFO("%s: Failed to execute", lookat_action_name.c_str());
00347 lookat_res.success = success;
00348
00349
00350 lookat_as->setAborted(lookat_res);
00351 }
00352 }
00353
00354 };
00355
00356
00357 int main(int argc, char** argv)
00358 {
00359 ros::init(argc, argv, "cob_lookat_action");
00360
00361 CobLookAtAction *lookat = new CobLookAtAction("lookat_action");
00362 if(lookat->init())
00363 ros::spin();
00364
00365 return 0;
00366 }