00001 #include "wam_ik_kdl.h"
00002 using namespace Eigen;
00003 using namespace std;
00004
00005 WamIkKdl::WamIkKdl() {
00006
00007
00008
00009 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ), KDL::Frame::DH(0.0,0.0,0.0,0.0) ));
00010 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotY), KDL::Frame::DH(0.0,0.0,0.0,0.0) ));
00011 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ), KDL::Frame::DH(0.045,0.0,0.5500,0.0) ));
00012 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotY), KDL::Frame::DH(-0.045,0.0,0.0,0.0) ));
00013 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ), KDL::Frame::DH(0.0,0.0,0.300,0.0) ));
00014 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotY), KDL::Frame::DH(0.0,0.0,0.0,0.0) ));
00015 this->wam63_.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ), KDL::Frame::DH(0.0,0.0,0.0609,0.0) ));
00016
00017 this->num_joints_ = this->wam63_.getNrOfJoints();
00018
00019 this->currentjoints.resize(this->num_joints_);
00020
00021
00022 std::string port_name;
00023
00024
00025
00026
00027 port_name = ros::names::append(ros::this_node::getName(), "joint_states");
00028 this->joint_states_subscriber = this->nh_.subscribe(port_name, 5, &WamIkKdl::joint_states_callback, this);
00029
00030
00031 port_name = ros::names::append(ros::this_node::getName(), "move_in_xyzquat");
00032 this->move_in_xyzquat_server = this->nh_.advertiseService(port_name, &WamIkKdl::move_in_xyzquat_Callback, this);
00033
00034 port_name = ros::names::append(ros::this_node::getName(), "print_ik_xyzquat");
00035 this->print_ik_xyzquat_server = this->nh_.advertiseService(port_name, &WamIkKdl::print_ik_xyzquat_Callback, this);
00036
00037
00038 port_name = ros::names::append(ros::this_node::getName(), "move_in_joints");
00039 move_in_joints_client = this->nh_.serviceClient<iri_wam_common_msgs::joints_move>(port_name);
00040
00041
00042
00043
00044 }
00045
00046
00047 void WamIkKdl::joint_states_callback(const sensor_msgs::JointState::ConstPtr& msg) {
00048
00049 for(unsigned int i=0;i<this->num_joints_;i++)
00050 currentjoints[i] = msg->position[i];
00051
00052 }
00053
00054
00055 bool WamIkKdl::move_in_xyzquat_Callback(iri_wam_common_msgs::pose_move::Request &req, iri_wam_common_msgs::pose_move::Response &res)
00056 {
00057
00058 bool result;
00059 Quaternion<float> quat( req.pose.orientation.w, req.pose.orientation.x, req.pose.orientation.y, req.pose.orientation.z);
00060 Matrix3f mat = quat.toRotationMatrix();
00061 ROS_INFO("Received Quat: %f %f %f %f %f %f %f\n",
00062 req.pose.position.x, req.pose.position.y, req.pose.position.z,
00063 req.pose.orientation.x, req.pose.orientation.y, req.pose.orientation.z, req.pose.orientation.w);
00064
00065 std::vector <double> pose(16,0);
00066 std::vector <double> joints(7,0);
00067
00068 pose[3] = req.pose.position.x;
00069 pose[7] = req.pose.position.y;
00070 pose[11] = req.pose.position.z;
00071 pose[15] = 1;
00072 for(unsigned int i=0; i<12; i++){
00073 if(i%4 != 3){
00074 pose[i] = mat(i/4,i%4);
00075 }
00076 }
00077 ROS_INFO("move_in_xyzquat Service Received Pose:\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n",
00078 pose[0],pose[1],pose[2],pose[3],
00079 pose[4],pose[5],pose[6],pose[7],
00080 pose[8],pose[9],pose[10],pose[11],
00081 pose[12],pose[13],pose[14],pose[15]);
00082
00083 if(!WamIkKdl::ik(pose, currentjoints, joints)){
00084 ROS_ERROR("IK solution not found");
00085 result = false;
00086 } else {
00087
00088 ROS_INFO("move_in_xyzquat Service computed joints:\n %f %f %f %f %f %f %f\n",
00089 joints.at(0), joints.at(1), joints.at(2), joints.at(3), joints.at(4), joints.at(5), joints.at(6));
00090
00091 move_in_joints_srv.request.joints.resize(7);
00092 for(unsigned int ii=0; ii < this->num_joints_; ii++)
00093 move_in_joints_srv.request.joints[ii] = joints.at(ii);
00094
00095 if (this->move_in_joints_client.call(move_in_joints_srv)) {
00096 ROS_INFO(" %d\n",move_in_joints_srv.response.success);
00097 result = true;
00098 } else {
00099 ROS_ERROR("Failed to call service move_in_joints");
00100 result = false;
00101 }
00102 }
00103 res.success = result;
00104 return result;
00105 }
00106
00107 bool WamIkKdl::print_ik_xyzquat_Callback(iri_wam_common_msgs::wamInverseKinematics::Request &req, iri_wam_common_msgs::wamInverseKinematics::Response &res){
00108
00109 bool result;
00110 Quaternion<float> quat(req.pose.orientation.x, req.pose.orientation.y, req.pose.orientation.z, req.pose.orientation.w);
00111 Matrix3f mat = quat.toRotationMatrix();
00112
00113 std::vector <double> pose(16,0);
00114 std::vector <double> joints(this->num_joints_,0);
00115
00116 pose[3] = req.pose.position.x;
00117 pose[7] = req.pose.position.y;
00118 pose[11] = req.pose.position.z;
00119 pose[15] = 1;
00120
00121 for(unsigned int ii=0; ii < 12; ii++){
00122 if(ii%4 != 3){
00123 pose[ii] = mat(ii/4,ii%4);
00124 }
00125 }
00126
00127 ROS_INFO("print_ik_xyzquat Service Received Pose:\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n",
00128 pose[0],pose[1],pose[2],pose[3],
00129 pose[4],pose[5],pose[6],pose[7],
00130 pose[8],pose[9],pose[10],pose[11],
00131 pose[12],pose[13],pose[14],pose[15]);
00132
00133 if(!WamIkKdl::ik(pose, currentjoints, joints)){
00134
00135 ROS_ERROR("IK solution not found");
00136 result = false;
00137
00138 }else{
00139
00140 ROS_INFO("print_ik_xyzquat Service computed joints:\n %f %f %f %f %f %f %f\n",
00141 joints.at(0), joints.at(1), joints.at(2), joints.at(3), joints.at(4), joints.at(5), joints.at(6));
00142 res.joints.position.resize(this->num_joints_);
00143 for(unsigned int ii=0; ii < this->num_joints_; ii++)
00144 res.joints.position[ii] = joints.at(ii);
00145 result = true;
00146
00147 }
00148 return result;
00149 }
00150
00151
00152
00153
00154
00155 bool WamIkKdl::ik(vector<double> goal_in_cartesian, vector<double> currentjoints, vector<double>& goal_in_joints){
00156
00157
00158 KDL::ChainFkSolverPos_recursive fksolver(KDL::ChainFkSolverPos_recursive(this->wam63_));
00159
00160
00161 KDL::JntArray setpointJP = KDL::JntArray(this->num_joints_);
00162 KDL::JntArray max = KDL::JntArray(this->num_joints_);
00163 KDL::JntArray min = KDL::JntArray(this->num_joints_);
00164
00165 double minjp[7] = {-2.6,-2.0,-2.8,-0.9,-4.76,-1.6,-3.0};
00166 double maxjp[7] = { 2.6, 2.0, 2.8, 3.2, 1.24, 1.6, 3.0};
00167
00168 for(unsigned int ii=0; ii < this->num_joints_; ii++){
00169 max(ii) = maxjp[ii];
00170 min(ii) = minjp[ii];
00171 }
00172
00173
00174 KDL::ChainIkSolverVel_pinv_givens iksolverv = KDL::ChainIkSolverVel_pinv_givens(this->wam63_);
00175
00176
00177
00178 KDL::ChainIkSolverPos_NR_JL iksolver = KDL::ChainIkSolverPos_NR_JL(this->wam63_, min, max, fksolver, iksolverv, 2000, 1e-6);
00179
00180 KDL::Frame cartpos;
00181 KDL::JntArray jointpos = KDL::JntArray(this->num_joints_);
00182 KDL::JntArray currentJP = KDL::JntArray(this->num_joints_);
00183
00184
00185 cartpos.p(0) = goal_in_cartesian.at(3);
00186 cartpos.p(1) = goal_in_cartesian.at(7);
00187 cartpos.p(2) = goal_in_cartesian.at(11);
00188
00189
00190 cartpos.M(0,0) = goal_in_cartesian.at(0);
00191 cartpos.M(0,1) = goal_in_cartesian.at(1);
00192 cartpos.M(0,2) = goal_in_cartesian.at(2);
00193 cartpos.M(1,0) = goal_in_cartesian.at(4);
00194 cartpos.M(1,1) = goal_in_cartesian.at(5);
00195 cartpos.M(1,2) = goal_in_cartesian.at(6);
00196 cartpos.M(2,0) = goal_in_cartesian.at(8);
00197 cartpos.M(2,1) = goal_in_cartesian.at(9);
00198 cartpos.M(2,2) = goal_in_cartesian.at(10);
00199
00200 for(unsigned int ii=0; ii < this->num_joints_; ii++)
00201 currentJP(ii) = currentjoints.at(ii);
00202
00203
00204 int ret = iksolver.CartToJnt(currentJP, cartpos, jointpos);
00205
00206 if (ret >= 0) {
00207
00208 std::cout << " Current Joint Position: [";
00209 for(unsigned int ii=0; ii < this->num_joints_; ii++)
00210 std::cout << currentJP(ii) << " ";
00211 std::cout << "]"<< std::endl;
00212
00213 std::cout << "Cartesian Position " << cartpos << std::endl;
00214
00215 std::cout << "IK result Joint Position: [";
00216 for(unsigned int ii=0; ii < this->num_joints_; ii++)
00217 std::cout << jointpos(ii) << " ";
00218 std::cout << "]"<< std::endl;
00219
00220 goal_in_joints.clear();
00221 goal_in_joints.resize(this->num_joints_);
00222 for(unsigned int ii=0; ii < this->num_joints_; ii++)
00223 goal_in_joints[ii] = jointpos(ii);
00224
00225 } else {
00226
00227 std::cout << "Error: could not calculate inverse kinematics :(" << std::endl;
00228 return false;
00229
00230 }
00231
00232 return true;
00233 }
00234
00235 int main(int argc, char** argv) {
00236 ros::init(argc, argv, "wam_ik_kdl");
00237 WamIkKdl wam_ik_kdl;
00238 ros::spin();
00239 }