Go to the documentation of this file.00001 #include "kelsey_sandbox/impulse_filter.h"
00002 #include <pluginlib/class_list_macros.h>
00003
00004 namespace kelsey_sandbox {
00005
00006 ImpulseFilter::ImpulseFilter() : pr2_controller_interface::Controller(),
00007 cur_torque(Joints),
00008 cur_force(6),
00009 integ_force(6),
00010 delay_integ(6) {
00011 }
00012
00014 bool ImpulseFilter::init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n) {
00015 rosrt::init();
00016 node_ = n;
00017 robot_state_ = robot;
00018
00019 std_msgs::Float64 float_temp;
00020 pub_val_.initialize(n, "/blah", 10, 10, float_temp);
00021
00022 geometry_msgs::Wrench wrench_temp;
00023 pub_impulse_.initialize(n, "/impulse", 10, 10, wrench_temp);
00024
00025 kelsey_sandbox::ImpulseState state_temp;
00026 state_temp.q.resize(Joints);
00027 state_temp.q_dot.resize(Joints);
00028 state_temp.effort.resize(Joints);
00029 state_temp.jacobian.data.resize(6*Joints);
00030 state_temp.jacobian.layout.dim.resize(2);
00031 state_temp.inertia.data.resize(Joints*Joints);
00032 state_temp.inertia.layout.dim.resize(2);
00033 state_temp.cart_inertia.data.resize(6*6);
00034 state_temp.cart_inertia.layout.dim.resize(2);
00035 pub_state_.initialize(n, "/impulse_state", 10, 10, state_temp);
00036
00037 mean_force_filter_.reset(new filters::MultiChannelFilterChain<double>("double"));
00038 delay_force_filter_.reset(new filters::MultiChannelFilterChain<double>("double"));
00039 if(!mean_force_filter_->configure(6, "/impulse/mean_force_filter"))
00040 return false;
00041 if(!delay_force_filter_->configure(6, "/impulse/delay_force_filter"))
00042 return false;
00043
00044
00045 if(!chain_.init(robot, "torso_lift_link", "r_gripper_tool_frame"))
00046 return false;
00047
00048 chain_.toKDL(kdl_chain_);
00049 kin_.reset(new Kin<Joints>(kdl_chain_));
00050 loop_count = 0;
00051
00052 joint_vel_filter_ = 0.2;
00053
00054 return true;
00055 }
00056
00057
00059 void ImpulseFilter::starting() {
00060
00061 cd_filter_ = 0.0;
00062 cd_integral_ = 0.0;
00063
00064 }
00065
00066
00068 void ImpulseFilter::update() {
00069 JointVec q;
00070 chain_.getPositions(q);
00071
00072 JointVec qdot_raw;
00073 chain_.getVelocities(qdot_raw);
00074 for (int i = 0; i < Joints; ++i)
00075 qdot_filtered_[i] += joint_vel_filter_ * (qdot_raw[i] - qdot_filtered_[i]);
00076 JointVec qdot = qdot_filtered_;
00077 qdot = qdot_raw;
00078
00079 Eigen::eigen2_Transform3d x;
00080 kin_->fk(q, x);
00081
00082 Jacobian J;
00083 kin_->jac(q, J);
00084
00085 CartVec x_dot = J * qdot;
00086
00087 KDL::JntArray kdl_tau;
00088 kdl_tau.resize(Joints);
00089 chain_.getEfforts(kdl_tau);
00090 Eigen::MatrixXd tau = Eigen::MatrixXd::Zero(Joints, 1);
00091 for(int i=0;i<Joints;i++) {
00092 tau(i) = kdl_tau(i);
00093 cur_torque[i] = kdl_tau(i);
00094 }
00095 Eigen::MatrixXd cur_force_eig, JT;
00096 JT = J.transpose();
00097 cur_force_eig = JT.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(tau);
00098 for(int i=0;i<6;i++)
00099 cur_force[i] = cur_force_eig(i);
00100
00101 mean_force_filter_->update(cur_force, integ_force);
00102 delay_force_filter_->update(integ_force, delay_integ);
00103 CartVec impulse;
00104 for(int i=0;i<6;i++)
00105 impulse(i) = integ_force[i] - delay_integ[i];
00106
00107 InertiaMat M;
00108 kin_->inertia(q, M);
00109
00110 Eigen::MatrixXd JMinvJT = J * M.inverse() * J.transpose();
00111 Eigen::MatrixXd M_cart = JMinvJT.inverse();
00112
00113 ros::Duration dt = robot_state_->getTime() - last_cycle_time_;
00114 last_cycle_time_ = robot_state_->getTime();
00115
00116 double E = 0.5 * qdot.transpose() * M * qdot + 0.1 * qdot.norm();
00117 cd_filter_ = 50.0 * (E - cd_integral_);
00118
00119 ros::Time now_time = robot_state_->getTime();
00120 kelsey_sandbox::ImpulseState::Ptr state_msg;
00121 if (state_msg = pub_state_.allocate()) {
00122 state_msg->header.stamp = now_time;
00123 state_msg->header.frame_id = "torso_lift_link";
00124 for (int i = 0; i < Joints; ++i) {
00125 state_msg->q[i] = q(i);
00126 state_msg->q_dot[i] = qdot(i);
00127 state_msg->effort[i] = tau(i);
00128 }
00129 state_msg->x.header.stamp = now_time;
00130 state_msg->x.header.frame_id = "torso_lift_link";
00131 tf::poseEigenToMsg(x, state_msg->x.pose);
00132 tf::twistEigenToMsg(x_dot, state_msg->x_dot);
00133 tf::wrenchEigenToMsg(cur_force_eig, state_msg->f_effort);
00134 tf::matrixEigenToMsg(J, state_msg->jacobian);
00135 tf::matrixEigenToMsg(M, state_msg->inertia);
00136 tf::matrixEigenToMsg(M_cart, state_msg->cart_inertia);
00137 pub_state_.publish(state_msg);
00138 }
00139
00140 if(loop_count % 10 == 0) {
00141 std_msgs::Float64::Ptr val_msg;
00142 if (val_msg = pub_val_.allocate()) {
00143 val_msg->data = impulse(0);
00144 pub_val_.publish(val_msg);
00145 }
00146 geometry_msgs::Wrench::Ptr impulse_msg;
00147 if (impulse_msg = pub_impulse_.allocate()) {
00148 impulse_msg->force.x = impulse(0);
00149 impulse_msg->force.y = impulse(1);
00150 impulse_msg->force.z = impulse(2);
00151 impulse_msg->torque.x = impulse(3);
00152 impulse_msg->torque.y = impulse(4);
00153 impulse_msg->torque.z = impulse(5);
00154 pub_impulse_.publish(impulse_msg);
00155 }
00156 }
00157 loop_count++;
00158 }
00159
00160
00162 void ImpulseFilter::stopping() {}
00163 }
00164
00166 PLUGINLIB_DECLARE_CLASS(kelsey_sandbox,ImpulseFilter,
00167 kelsey_sandbox::ImpulseFilter,
00168 pr2_controller_interface::Controller)