00001 #include <wpi_jaco_wrapper/jaco_kinematics.h>
00002
00003 using namespace std;
00004
00005 JacoKinematics::JacoKinematics(void)
00006 {
00007 loadParameters(n);
00008
00009
00010 double AA, CA, SA, C2A, S2A, D4B, D5B, D6B;
00011
00012 if (arm_name_ == "jaco2")
00013 AA = 30.0 * PI / 180.0;
00014 else
00015 AA = 11.0 * PI / 72.0;
00016
00017
00018 CA = cos(AA);
00019 SA = sin(AA);
00020 C2A = cos(2 * AA);
00021 S2A = sin(2 * AA);
00022
00023 if (arm_name_ == "jaco2")
00024 {
00025
00026 D4B = J2D3 + SA / S2A * J2D4;
00027 D5B = SA / S2A * J2D4 + SA / S2A * J2D5;
00028 D6B = SA / S2A * J2D5 + J2D6;
00029 }
00030 else
00031 {
00032
00033 D4B = D3 + SA / S2A * D4;
00034 D5B = SA / S2A * D4 + SA / S2A * D5;
00035 D6B = SA / S2A * D5 + D6;
00036 }
00037
00038
00039 ds.resize(6);
00040 if (arm_name_ == "jaco2")
00041 {
00042 ds[0] = J2D1;
00043 ds[2] = -J2E2;
00044 }
00045 else
00046 {
00047 ds[0] = D1;
00048 ds[2] = -E2;
00049 }
00050 ds[1] = 0;
00051 ds[3] = -D4B;
00052 ds[4] = -D5B;
00053 ds[5] = -D6B;
00054
00055 as.resize(6);
00056 for (unsigned int i = 0; i < 6; i++)
00057 {
00058 as[i] = 0;
00059 }
00060 if (arm_name_ == "jaco2")
00061 as[1] = J2D2;
00062 else
00063 as[1] = D2;
00064
00065 alphas.resize(6);
00066 alphas[0] = PI / 2.0;
00067 alphas[1] = PI;
00068 alphas[2] = PI / 2.0;
00069 alphas[3] = 2 * AA;
00070 alphas[4] = 2 * AA;
00071 alphas[5] = PI;
00072
00073
00074 fkServer = n.advertiseService(topic_prefix_ + "_arm/kinematics/fk", &JacoKinematics::callFK, this);
00075 }
00076
00077 bool JacoKinematics::callFK(wpi_jaco_msgs::JacoFK::Request &req, wpi_jaco_msgs::JacoFK::Response &res)
00078 {
00079 if (req.joints.size() < 6)
00080 {
00081 ROS_INFO("Not enough joints specified, could not calculate forward kinematics");
00082 return false;
00083 }
00084
00085 res.handPose = calculateFK(req.joints);
00086
00087 return true;
00088 }
00089
00090 geometry_msgs::PoseStamped JacoKinematics::calculateFK(vector<float> joints)
00091 {
00092 tf::Transform transform;
00093 tf::Transform tb1, t12, t23, t34, t45, t56, t6e;
00094 tf::Quaternion rotQuat(0, 0, 0, 0);
00095 tf::Matrix3x3 rotMat(1, 0, 0, 0, 1, 0, 0, 0, 1);
00096 tf::Vector3 trans(0, 0, 0);
00097
00098
00099 rotMat.getRotation(rotQuat);
00100 transform.setRotation(rotQuat);
00101 transform.setOrigin(trans);
00102
00103
00104 vector<float> thetas;
00105 thetas.resize(6);
00106 thetas[0] = -joints[0];
00107 thetas[1] = joints[1] - PI / 2.0;
00108 thetas[2] = joints[2] + PI / 2.0;
00109 thetas[3] = joints[3];
00110 thetas[4] = joints[4] - PI;
00111 if (arm_name_ == "jaco2")
00112 thetas[5] = joints[5] + PI / 2.0;
00113 else
00114 thetas[5] = joints[5] + 5.0 * PI / 9.0;
00115
00116
00117 for (unsigned int i = 0; i < joints.size(); i++)
00118 {
00119 transform = transform * generateTransform(thetas[i], ds[i], as[i], alphas[i]);
00120 }
00121
00122
00123 geometry_msgs::PoseStamped handPose;
00124 handPose.header.frame_id = arm_name_ + "_link_base";
00125 handPose.pose.position.x = transform.getOrigin().x();
00126 handPose.pose.position.y = transform.getOrigin().y();
00127 handPose.pose.position.z = transform.getOrigin().z();
00128 handPose.pose.orientation.x = transform.getRotation().x();
00129 handPose.pose.orientation.y = transform.getRotation().y();
00130 handPose.pose.orientation.z = transform.getRotation().z();
00131 handPose.pose.orientation.w = transform.getRotation().w();
00132
00133 return handPose;
00134 }
00135
00136 tf::Transform JacoKinematics::generateTransform(float theta, float d, float a, float alpha)
00137 {
00138 tf::Transform transform;
00139 tf::Quaternion rotQuat(0, 0, 0, 0);
00140 tf::Matrix3x3 rotMat(0, 0, 0, 0, 0, 0, 0, 0, 0);
00141 tf::Vector3 trans(0, 0, 0);
00142
00143
00144 rotMat.setValue(cos(theta), -sin(theta) * cos(alpha), sin(theta) * sin(alpha), sin(theta), cos(theta) * cos(alpha),
00145 -cos(theta) * sin(alpha), 0, sin(alpha), cos(alpha));
00146
00147
00148 trans.setValue(a * cos(theta), a * sin(theta), d);
00149
00150
00151 rotMat.getRotation(rotQuat);
00152
00153
00154 transform.setRotation(rotQuat);
00155 transform.setOrigin(trans);
00156
00157 return transform;
00158 }
00159
00160 bool JacoKinematics::loadParameters(const ros::NodeHandle n)
00161 {
00162 n.param("wpi_jaco/arm_name", arm_name_, std::string("jaco"));
00163
00164
00165 if (arm_name_ == "jaco2")
00166 topic_prefix_ = "jaco";
00167 else
00168 topic_prefix_ = arm_name_;
00169
00171 return true;
00172 }
00173
00174 int main(int argc, char **argv)
00175 {
00176 ros::init(argc, argv, "jaco_kinematics");
00177
00178 JacoKinematics jk;
00179
00180 ros::spin();
00181 }
00182