00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ros/ros.h>
00019 #include <cob_lookat_action/cob_lookat_action_server.h>
00020
00021
00022 bool CobLookAtAction::init()
00023 {
00025 if (!nh_.getParam("joint_names", joint_names_))
00026 {
00027 ROS_ERROR("Parameter 'joint_names' not set");
00028 return false;
00029 }
00030
00031 if (!nh_.getParam("chain_base_link", chain_base_link_))
00032 {
00033 ROS_ERROR("Parameter 'chain_base_link' not set");
00034 return false;
00035 }
00036
00037 if (!nh_.getParam("chain_tip_link", chain_tip_link_))
00038 {
00039 ROS_ERROR("Parameter 'chain_tip_link' not set");
00040 return false;
00041 }
00042
00044 KDL::Tree tree;
00045 if (!kdl_parser::treeFromParam("/robot_description", tree))
00046 {
00047 ROS_ERROR("Failed to construct kdl tree");
00048 return false;
00049 }
00050
00051 tree.getChain(chain_base_link_, chain_tip_link_, chain_main_);
00052 if (chain_main_.getNrOfJoints() == 0)
00053 {
00054 ROS_ERROR("Failed to initialize kinematic chain");
00055 return false;
00056 }
00057
00058
00059 ROS_WARN_STREAM("Waiting for ActionServer: " << fjt_name_);
00060 fjt_ac_ = new actionlib::SimpleActionClient<control_msgs::FollowJointTrajectoryAction>(nh_, fjt_name_, true);
00061 fjt_ac_->waitForServer(ros::Duration(10.0));
00062
00063 lookat_as_ = new actionlib::SimpleActionServer<cob_lookat_action::LookAtAction>(nh_, lookat_name_, boost::bind(&CobLookAtAction::goalCB, this, _1), false);
00064 lookat_as_->start();
00065
00066 return true;
00067 }
00068
00069
00070 void CobLookAtAction::goalCB(const cob_lookat_action::LookAtGoalConstPtr &goal)
00071 {
00072 bool success = true;
00073 std::string message;
00074
00076 KDL::Chain chain_lookat, chain_full;
00077 KDL::Vector lookat_lin_axis(0.0, 0.0, 0.0);
00078 switch (goal->pointing_axis_type)
00079 {
00080 case cob_lookat_action::LookAtGoal::X_POSITIVE:
00081 lookat_lin_axis.x(1.0);
00082 break;
00083 case cob_lookat_action::LookAtGoal::Y_POSITIVE:
00084 lookat_lin_axis.y(1.0);
00085 break;
00086 case cob_lookat_action::LookAtGoal::Z_POSITIVE:
00087 lookat_lin_axis.z(1.0);
00088 break;
00089 case cob_lookat_action::LookAtGoal::X_NEGATIVE:
00090 lookat_lin_axis.x(-1.0);
00091 break;
00092 case cob_lookat_action::LookAtGoal::Y_NEGATIVE:
00093 lookat_lin_axis.y(-1.0);
00094 break;
00095 case cob_lookat_action::LookAtGoal::Z_NEGATIVE:
00096 lookat_lin_axis.z(-1.0);
00097 break;
00098 default:
00099 ROS_ERROR("PointingAxisType %d not defined! Using default: 'X_POSITIVE'!", goal->pointing_axis_type);
00100 lookat_lin_axis.x(1.0);
00101 break;
00102 }
00103 KDL::Joint lookat_lin_joint("lookat_lin_joint", KDL::Vector(), lookat_lin_axis, KDL::Joint::TransAxis);
00104
00106 KDL::Frame offset;
00107 tf::StampedTransform offset_transform;
00108 bool transformed = false;
00109
00110 do
00111 {
00112 try
00113 {
00114 ros::Time now = ros::Time::now();
00115 tf_listener_.waitForTransform(chain_tip_link_, goal->pointing_frame, now, ros::Duration(0.1));
00116 tf_listener_.lookupTransform(chain_tip_link_, goal->pointing_frame, now, offset_transform);
00117 transformed = true;
00118 }
00119 catch (tf::TransformException& ex)
00120 {
00121 ROS_ERROR("LookatAction: %s", ex.what());
00122 ros::Duration(0.1).sleep();
00123 }
00124 } while (!transformed && ros::ok());
00125
00126 tf::transformTFToKDL(offset_transform, offset);
00127
00128
00129 KDL::Segment lookat_rotx_link("lookat_rotx_link", lookat_lin_joint, offset);
00130 chain_lookat.addSegment(lookat_rotx_link);
00131
00132 KDL::Vector lookat_rotx_axis(1.0, 0.0, 0.0);
00133 KDL::Joint lookat_rotx_joint("lookat_rotx_joint", KDL::Vector(), lookat_rotx_axis, KDL::Joint::RotAxis);
00134 KDL::Segment lookat_roty_link("lookat_roty_link", lookat_rotx_joint);
00135 chain_lookat.addSegment(lookat_roty_link);
00136
00137 KDL::Vector lookat_roty_axis(0.0, 1.0, 0.0);
00138 KDL::Joint lookat_roty_joint("lookat_roty_joint", KDL::Vector(), lookat_roty_axis, KDL::Joint::RotAxis);
00139 KDL::Segment lookat_rotz_link("lookat_rotz_link", lookat_roty_joint);
00140 chain_lookat.addSegment(lookat_rotz_link);
00141
00142 KDL::Vector lookat_rotz_axis(0.0, 0.0, 1.0);
00143 KDL::Joint lookat_rotz_joint("lookat_rotz_joint", KDL::Vector(), lookat_rotz_axis, KDL::Joint::RotAxis);
00144 KDL::Segment lookat_focus_frame("lookat_focus_frame", lookat_rotz_joint);
00145 chain_lookat.addSegment(lookat_focus_frame);
00146
00147 chain_full = chain_main_;
00148 chain_full.addChain(chain_lookat);
00149
00151 fk_solver_pos_.reset(new KDL::ChainFkSolverPos_recursive(chain_full));
00152 ik_solver_vel_.reset(new KDL::ChainIkSolverVel_pinv(chain_full));
00153 ik_solver_pos_.reset(new KDL::ChainIkSolverPos_NR(chain_full, *fk_solver_pos_, *ik_solver_vel_));
00154
00156 KDL::Frame p_in;
00157 tf::StampedTransform transform_in;
00158 transformed = false;
00159
00160 do
00161 {
00162 try
00163 {
00164 ros::Time now = ros::Time::now();
00165 tf_listener_.waitForTransform(chain_base_link_, goal->target_frame, now, ros::Duration(0.1));
00166 tf_listener_.lookupTransform(chain_base_link_, goal->target_frame, now, transform_in);
00167 transformed = true;
00168 }
00169 catch (tf::TransformException& ex)
00170 {
00171 ROS_ERROR("LookatAction: %s", ex.what());
00172 ros::Duration(0.1).sleep();
00173 }
00174 } while (!transformed && ros::ok());
00175
00176 tf::transformTFToKDL(transform_in, p_in);
00177 KDL::JntArray q_init(chain_full.getNrOfJoints());
00178 KDL::JntArray q_out(chain_full.getNrOfJoints());
00179 int result = ik_solver_pos_->CartToJnt(q_init, p_in, q_out);
00180
00182 if (result != KDL::SolverI::E_NOERROR)
00183 {
00184 success = false;
00185 message = "Failed to find solution";
00186 ROS_ERROR_STREAM(lookat_name_ << ": " << message);
00187 lookat_res_.success = success;
00188 lookat_res_.message = message;
00189 lookat_as_->setAborted(lookat_res_);
00190 return;
00191 }
00192
00194 control_msgs::FollowJointTrajectoryGoal lookat_traj;
00195 lookat_traj.trajectory.header.stamp = ros::Time::now();
00196 lookat_traj.trajectory.header.frame_id = chain_base_link_;
00197 lookat_traj.trajectory.joint_names = joint_names_;
00198 trajectory_msgs::JointTrajectoryPoint traj_point;
00199 for(unsigned int i = 0; i < chain_main_.getNrOfJoints(); i++)
00200 {
00201 traj_point.positions.push_back(q_out(i));
00202 }
00203 traj_point.time_from_start = ros::Duration(3.0);
00204 lookat_traj.trajectory.points.push_back(traj_point);
00205
00206 fjt_ac_->sendGoal(lookat_traj);
00207
00208 bool finished_before_timeout = fjt_ac_->waitForResult(ros::Duration(5.0));
00209
00211 if (finished_before_timeout)
00212 {
00213 actionlib::SimpleClientGoalState state = fjt_ac_->getState();
00214 if(state != actionlib::SimpleClientGoalState::SUCCEEDED)
00215 {
00216 success = false;
00217 message = "FJT finished: " + state.toString();
00218 ROS_ERROR_STREAM(lookat_name_ << ": " << message);
00219 lookat_res_.success = success;
00220 lookat_res_.message = message;
00221 lookat_as_->setAborted(lookat_res_);
00222 return;
00223 }
00224 }
00225 else
00226 {
00227 success = false;
00228 message = "FJT did not finish before the time out.";
00229 ROS_ERROR_STREAM(lookat_name_ << ": " << message);
00230 lookat_res_.success = success;
00231 lookat_res_.message = message;
00232 lookat_as_->setAborted(lookat_res_);
00233 return;
00234 }
00235
00236
00238 success = true;
00239 message = "Lookat finished successful.";
00240 ROS_ERROR_STREAM(lookat_name_ << ": " << message);
00241 lookat_res_.success = success;
00242 lookat_res_.message = message;
00243 lookat_as_->setSucceeded(lookat_res_);
00244 return;
00245 }