cob_lookat_action_server.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
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     //tf::transformMsgToKDL(goal->pointing_offset, offset);
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 }


cob_lookat_action
Author(s): Felix Messmer
autogenerated on Thu Jun 6 2019 21:22:57