38 #include <boost/scoped_ptr.hpp> 39 #include <boost/thread/condition.hpp> 42 #include <geometry_msgs/PoseStamped.h> 43 #include <geometry_msgs/PointStamped.h> 44 #include <geometry_msgs/Twist.h> 46 #include <kdl/chainfksolver.hpp> 47 #include <kdl/chain.hpp> 48 #include <kdl/chainjnttojacsolver.hpp> 49 #include <kdl/frames.hpp> 50 #include "kdl/chainfksolverpos_recursive.hpp" 59 #include <sensor_msgs/JointState.h> 60 #include <std_msgs/Float32MultiArray.h> 61 #include <std_msgs/Int32.h> 65 #include <trajectory_msgs/JointTrajectory.h> 66 #include <pr2_controllers_msgs/PointHeadAction.h> 67 #include <pr2_controllers_msgs/QueryTrajectoryState.h> 68 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h> 73 printf(
"%s % 7.3f % 7.3f % 7.3f\n", label, v.
x(), v.
y(), v.
z() );
122 , action_name_(
"point_head_action")
125 , action_server_(nh_, action_name_.c_str(),
128 , has_active_goal_(false)
130 pnh_.
param(
"pan_link", pan_link_, std::string(
"head_pan_link"));
131 pnh_.
param(
"default_pointing_frame", default_pointing_frame_, std::string(
"head_tilt_link"));
132 pnh_.
param(
"success_angle_threshold", success_angle_threshold_, 0.1);
134 if(pan_link_[0] ==
'/') pan_link_.erase(0, 1);
135 if(default_pointing_frame_[0] ==
'/') default_pointing_frame_.erase(0, 1);
138 pub_controller_command_ =
139 nh_.
advertise<trajectory_msgs::JointTrajectory>(
"command", 2);
140 sub_controller_state_ =
143 nh_.
serviceClient<pr2_controllers_msgs::QueryTrajectoryState>(
"/head_traj_controller/query_state");
148 std::string robot_desc_string;
149 nh_.
param(
"/robot_description", robot_desc_string, std::string());
150 ROS_DEBUG(
"Reading tree from robot_description...");
152 ROS_ERROR(
"Failed to construct kdl tree");
155 if (!urdf_model_.
initString(robot_desc_string)){
156 ROS_ERROR(
"Failed to parse urdf string for urdf::Model.");
163 action_server_.
start();
173 for (
int i = 0; i < 10; ++i)
184 ROS_ERROR(
"Could not get parent of %s in the TF tree", pan_link_.c_str());
189 if(root_[0] ==
'/') root_.erase(0, 1);
194 const geometry_msgs::PointStamped &target = gh.getGoal()->target;
195 pointing_frame_ = gh.getGoal()->pointing_frame;
196 if(pointing_frame_.length() == 0)
198 ROS_WARN(
"Pointing frame not specified, using %s [1, 0, 0] by default.", default_pointing_frame_.c_str());
204 if(pointing_frame_[0] ==
'/') pointing_frame_.erase(0, 1);
208 std::string error_msg;
209 ret1 = tfl_.
waitForTransform(pan_link_, pointing_frame_, target.header.stamp,
213 if(pointing_axis_.
length() < 0.1)
215 size_t found = pointing_frame_.find(
"optical_frame");
216 if (found != std::string::npos)
218 ROS_WARN(
"Pointing axis appears to be zero-length. Using [0, 0, 1] as default for an optical frame.");
223 ROS_WARN(
"Pointing axis appears to be zero-length. Using [1, 0, 0] as default for a non-optical frame.");
234 ROS_ERROR(
"Transform failure (%d): %s", ret1, ex.what());
244 std::string error_msg;
245 ret1 = tfl_.
waitForTransform(root_.c_str(), target.header.frame_id, target.header.stamp,
248 geometry_msgs::PointStamped target_in_root_msg;
254 ROS_ERROR(
"Transform failure (%d): %s", ret1, ex.what());
259 if( tip_.compare(pointing_frame_) != 0 )
261 bool success = tree_.
getChain(root_.c_str(), pointing_frame_.c_str(),
chain_);
264 ROS_ERROR(
"Couldn't create chain from %s to %s.", root_.c_str(), pointing_frame_.c_str());
289 pr2_controllers_msgs::QueryTrajectoryState traj_state;
291 if (!cli_query_traj_.
call(traj_state))
293 ROS_ERROR(
"Service call to query controller trajectory failed.");
297 if(traj_state.response.name.size() != joints)
299 ROS_ERROR(
"Number of joints mismatch: urdf chain vs. trajectory controller state.");
303 std::vector<urdf::JointLimits> limits_(joints);
306 for(
unsigned int i = 0; i < joints; i++)
308 joint_names_[i] = traj_state.response.name[i];
309 limits_[i] = *(urdf_model_.joints_[joint_names_[i].c_str()]->limits);
310 ROS_DEBUG(
"Joint %d %s: %f, limits: %f %f", i, traj_state.response.name[i].c_str(), traj_state.response.position[i], limits_[i].lower, limits_[i].upper);
317 float correction_angle = 2*M_PI;
318 float correction_delta = 2*M_PI;
319 while(
ros::ok() && fabs(correction_delta) > 0.001)
323 pose_solver_->JntToCart(jnt_pos, pose);
324 jac_solver_->JntToJac(jnt_pos, jacobian);
332 float prev_correction = correction_angle;
333 correction_angle = current_in_frame.
angle(axis_in_frame);
334 correction_delta = correction_angle - prev_correction;
335 ROS_DEBUG(
"At step %d, joint poses are %.4f and %.4f, angle error is %f", count, jnt_pos(0), jnt_pos(1), correction_angle);
336 if(correction_angle < 0.5*success_angle_threshold_)
break;
347 for (
unsigned int i=0; i<6; i++)
348 wrench_desi(i) = -1.0*twist(i);
351 for (
unsigned int i = 0; i < joints; i++)
354 for (
unsigned int j=0; j<6; j++)
355 jnt_eff(i) += (jacobian(j,i) * wrench_desi(j));
356 jnt_pos(i) += jnt_eff(i);
360 if(jnt_pos(0) < limits_[0].lower && limit_flips++ == 0){ jnt_pos(0) += 1.5*M_PI; }
361 if(jnt_pos(0) > limits_[0].upper && limit_flips++ == 0){ jnt_pos(0) -= 1.5*M_PI; }
363 jnt_pos(1) = std::max(limits_[1].lower, jnt_pos(1));
364 jnt_pos(1) = std::min(limits_[1].upper, jnt_pos(1));
369 ROS_ERROR(
"Goal is out of joint limits, trying to point there anyway... \n");
373 ROS_DEBUG(
"Iterative solver took %d steps", count);
375 std::vector<double> q_goal(joints);
377 for(
unsigned int i = 0; i < joints; i++)
379 jnt_pos(i) = std::max(limits_[i].lower, jnt_pos(i));
380 jnt_pos(i) = std::min(limits_[i].upper, jnt_pos(i));
381 q_goal[i] = jnt_pos(i);
382 ROS_DEBUG(
"Joint %d %s: %f", i, joint_names_[i].c_str(), jnt_pos(i));
385 if (has_active_goal_)
387 active_goal_.setCanceled();
388 has_active_goal_ =
false;
393 has_active_goal_ =
true;
399 if (gh.getGoal()->min_duration > min_duration)
400 min_duration = gh.getGoal()->min_duration;
403 if (gh.getGoal()->max_velocity > 0)
406 double dist =
sqrt(
pow(q_goal[0] - traj_state.response.position[0], 2) +
407 pow(q_goal[1] - traj_state.response.position[1], 2));
408 ros::Duration limit_from_velocity(dist / gh.getGoal()->max_velocity);
409 if (limit_from_velocity > min_duration)
410 min_duration = limit_from_velocity;
415 trajectory_msgs::JointTrajectory traj;
416 traj.header.stamp = traj_state.request.time;
418 traj.joint_names.push_back(traj_state.response.name[0]);
419 traj.joint_names.push_back(traj_state.response.name[1]);
421 traj.points.resize(2);
422 traj.points[0].positions = traj_state.response.position;
423 traj.points[0].velocities = traj_state.response.velocity;
425 traj.points[1].positions = q_goal;
426 traj.points[1].velocities.push_back(0);
427 traj.points[1].velocities.push_back(0);
428 traj.points[1].time_from_start =
ros::Duration(min_duration);
430 pub_controller_command_.
publish(traj);
439 if (has_active_goal_)
441 bool should_abort =
false;
445 ROS_WARN(
"Aborting goal because we have never heard a controller state message.");
450 ROS_WARN(
"Aborting goal because we haven't heard from the controller in %.3lf seconds",
457 trajectory_msgs::JointTrajectory empty;
459 pub_controller_command_.
publish(empty);
462 active_goal_.setAborted();
463 has_active_goal_ =
false;
471 if (active_goal_ == gh)
474 trajectory_msgs::JointTrajectory empty;
476 pub_controller_command_.
publish(empty);
479 active_goal_.setCanceled();
480 has_active_goal_ =
false;
487 last_controller_state_ = msg;
490 if (!has_active_goal_)
497 for(
unsigned int i = 0; i < msg->joint_names.size(); i++)
498 jnt_pos(i) = msg->actual.positions[i];
501 pose_solver_->JntToCart(jnt_pos, pose);
512 pr2_controllers_msgs::PointHeadFeedback feedback;
513 feedback.pointing_angle_error = current_in_frame.
angle(axis_in_frame);
514 active_goal_.publishFeedback(feedback);
516 if (feedback.pointing_angle_error < success_angle_threshold_)
518 active_goal_.setSucceeded();
519 has_active_goal_ =
false;
524 ROS_ERROR(
"Could not transform: %s", ex.what());
531 int main(
int argc,
char** argv)
533 ros::init(argc, argv,
"point_head_action");
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
std::vector< std::string > joint_names_
std::string default_pointing_frame_
static void pointMsgToTF(const geometry_msgs::Point &msg_v, Point &bt_v)
void publish(const boost::shared_ptr< M > &message) const
URDF_EXPORT bool initString(const std::string &xmlstring)
ServerGoalHandle< pr2_controllers_msgs::PointHeadAction > GoalHandle
std::string pointing_frame_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
tf::Stamped< tf::Point > target_in_pan_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
bool call(MReq &req, MRes &res)
std::string getName(void *handle)
void printVector3(const char *label, tf::Vector3 v)
double success_angle_threshold_
tf::Vector3 pointing_axis_
Matrix3x3 inverse() const
TFSIMD_FORCE_INLINE tfScalar angle(const Vector3 &v) const
pr2_controllers_msgs::JointTrajectoryControllerStateConstPtr last_controller_state_
TFSIMD_FORCE_INLINE Vector3 cross(const Vector3 &v) const
void controllerStateCB(const pr2_controllers_msgs::JointTrajectoryControllerStateConstPtr &msg)
ROSCPP_DECL void spin(Spinner &spinner)
ros::Subscriber command_sub_
ros::Publisher pub_controller_command_
boost::scoped_ptr< KDL::ChainJntToJacSolver > jac_solver_
TFSIMD_FORCE_INLINE const tfScalar & x() const
TFSIMD_FORCE_INLINE Vector3 normalized() const
actionlib::ActionServer< pr2_controllers_msgs::PointHeadAction > PHAS
static void vector3MsgToTF(const geometry_msgs::Vector3 &msg_v, Vector3 &bt_v)
TFSIMD_FORCE_INLINE const tfScalar & z() const
void poseKDLToTF(const KDL::Frame &k, tf::Pose &t)
void transformTFToKDL(const tf::Transform &t, KDL::Frame &k)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
TFSIMD_FORCE_INLINE Vector3 normalized() const
TFSIMD_FORCE_INLINE const tfScalar & y() const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
ControlHead(const ros::NodeHandle &node)
void goalCB(GoalHandle gh)
void watchdog(const ros::TimerEvent &e)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
unsigned int getNrOfJoints() const
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
KDL_PARSER_PUBLIC bool treeFromString(const std::string &xml, KDL::Tree &tree)
tf::Point target_in_root_
TFSIMD_FORCE_INLINE Vector3 & normalize()
int main(int argc, char **argv)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
tf::TransformListener tfl_
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) const
geometry_msgs::PointStamped target_
unsigned int getNrOfSegments() const
void cancelCB(GoalHandle gh)
ros::Subscriber sub_controller_state_
ros::Timer watchdog_timer_
PHAS::GoalHandle GoalHandle
unsigned int getNrOfJoints() const
ros::ServiceClient cli_query_traj_
boost::scoped_ptr< KDL::ChainFkSolverPos > pose_solver_
TFSIMD_FORCE_INLINE tfScalar length() const