00001 #include "ros/ros.h"
00002 #include <geometry_msgs/Twist.h>
00003 #include <sensor_msgs/JointState.h>
00004 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h>
00005 #include <actionlib/server/simple_action_server.h>
00006 #include <pr2_controllers_msgs/JointTrajectoryAction.h>
00007 #include <kdl/chain.hpp>
00008 #include <kdl/chainfksolver.hpp>
00009 #include <kdl/chainfksolverpos_recursive.hpp>
00010 #include <kdl_parser/kdl_parser.hpp>
00011
00012
00013 #define HZ 10
00014
00015 class trajectory_manager
00016 {
00017 private:
00018 ros::NodeHandle n_;
00019 ros::Publisher cart_vel_pub_;
00020 ros::Publisher joint_pos_pub_;
00021 ros::Subscriber controller_state_;
00022 actionlib::SimpleActionServer<pr2_controllers_msgs::JointTrajectoryAction> as_;
00023 std::string action_name_;
00024 bool executing_;
00025 trajectory_msgs::JointTrajectory traj_;
00026 double traj_time_;
00027 int current_point_;
00028 KDL::ChainFkSolverPos_recursive * fksolver1_;
00029 KDL::Chain chain_;
00030 KDL::JntArray q_current;
00031 KDL::JntArray startposition_;
00032 public:
00033 trajectory_manager():as_(n_, "TrajectoryManager", boost::bind(&trajectory_manager::executeTrajectory, this, _1)),
00034 action_name_("TrajectoryManager")
00035 {
00036 cart_vel_pub_ = n_.advertise<geometry_msgs::Twist>("cart_twist", 1);
00037 joint_pos_pub_ = n_.advertise<sensor_msgs::JointState>("target_joint_pos", 1);
00038 controller_state_ = n_.subscribe("state", 1, &trajectory_manager::state_callback, this);
00039 traj_time_ = 0.0;
00040 current_point_ = 0;
00041 executing_ = false;
00042 KDL::Tree my_tree;
00043 std::string robot_desc_string;
00044 n_.param("/robot_description", robot_desc_string, std::string());
00045 if (!kdl_parser::treeFromString(robot_desc_string, my_tree))
00046 {
00047 ROS_ERROR("Failed to construct kdl tree");
00048 }
00049 my_tree.getChain("base_link","arm_7_link", chain_);
00050 fksolver1_ = new KDL::ChainFkSolverPos_recursive(chain_);
00051 q_current = KDL::JntArray(7);
00052 }
00053
00054 void state_callback(const pr2_controllers_msgs::JointTrajectoryControllerStatePtr& message)
00055 {
00056 std::vector<double> positions = message->actual.positions;
00057 for(unsigned int i = 0; i < positions.size(); i++)
00058 {
00059 q_current(i) = positions[i];
00060 }
00061 }
00062 void executeTrajectory(const pr2_controllers_msgs::JointTrajectoryGoalConstPtr &goal)
00063 {
00064 ROS_INFO("Received new goal trajectory with %d points",goal->trajectory.points.size());
00065 if(!executing_)
00066 {
00067 traj_ = goal->trajectory;
00068 traj_time_ = 0.0;
00069 current_point_ = 0;
00070 executing_ = true;
00071 startposition_ = q_current;
00072 }
00073 else
00074 {
00075 }
00076 }
00077
00078 void run()
00079 {
00080 if(executing_)
00081 {
00082 if(traj_time_ >= traj_.points[current_point_].time_from_start.toSec())
00083 {
00084 if(current_point_ == traj_.points.size())
00085 {
00086 ROS_INFO("Trajecory finished");
00087 executing_ = false;
00088 return;
00089 }
00090 else
00091 {
00092 current_point_ +=1;
00093 }
00094 }
00095
00096 KDL::Frame F_ist;
00097 fksolver1_->JntToCart(q_current, F_ist);
00098
00099 KDL::Frame F_target;
00100 KDL::JntArray q_target(traj_.points[current_point_].positions.size());
00101 for (unsigned int i = 0; i < traj_.points[current_point_].positions.size(); i += 1)
00102 {
00103 q_target(i) = traj_.points[current_point_].positions[i];
00104 }
00105 fksolver1_->JntToCart(q_target, F_target);
00106
00107 double delta_time = 0.0;
00108 if(current_point_ != 0)
00109 delta_time = traj_.points[current_point_].time_from_start.toSec() - traj_.points[current_point_-1].time_from_start.toSec();
00110 geometry_msgs::Twist trajectory_twist;
00111
00112
00113 sensor_msgs::JointState target_joint_position;
00114 for (unsigned int i = 0; i < traj_.points[current_point_].positions.size(); i += 1)
00115 {
00116
00117 target_joint_position.position[i] = traj_time_ * (traj_.points[current_point_].positions[i] - startposition_(i))/delta_time;
00118 if(current_point_ != 0)
00119 {
00120 target_joint_position.position[i] = (traj_time_ - traj_.points[current_point_-1].time_from_start.toSec()) * (traj_.points[current_point_].positions[i] - traj_.points[current_point_-1].positions[i])/delta_time;
00121 }
00122 }
00123
00124 cart_vel_pub_.publish(trajectory_twist);
00125 joint_pos_pub_.publish(target_joint_position);
00126
00127 traj_time_ += 1./HZ;
00128 }
00129
00130 }
00131
00132 };
00133
00134
00135
00136 int main(int argc, char ** argv)
00137 {
00138 ros::init(argc, argv, "trajectory_manager");
00139 trajectory_manager tm;
00140 ros::Rate loop_rate(HZ);
00141 while (ros::ok())
00142 {
00143 tm.run();
00144 ros::spinOnce();
00145 loop_rate.sleep();
00146 }
00147
00148 }
00149
00150
00151
00152
00153
00154