00001
00002
00003
00004
00005
00006
00007
00008 #include <rtt/Component.hpp>
00009
00010 #include "CartWrench.h"
00011 #include <tf_conversions/tf_kdl.h>
00012
00013 namespace lwr {
00014
00015 CartWrench::CartWrench(const std::string& name) : TaskContext(name, PreOperational) {
00016
00017 this->addPort("CartesianWrenchCommand", port_cartesian_wrench_command);
00018 this->addPort("CartesianImpedanceCommand", port_cartesian_impedance_command);
00019 this->addPort("CartesianPositionCommand", port_cartesian_position_command);
00020
00021 this->addPort("DesiredCartesianPosition", port_desired_cartesian_position);
00022 this->addPort("ToolFrame", port_tool_frame);
00023
00024 this->addEventPort("CommandPeriod", port_command_period);
00025
00026
00027 this->addPort("Jacobian", port_jacobian);
00028 this->addPort("CartesianPosition", port_cart_pos_msr);
00029 this->addPort("JointPosition", port_jnt_pos_msr);
00030 this->addPort("MassMatrix", port_mass_matrix);
00031
00032
00033 this->addPort("JointEffortCommand", port_jnt_trq_cmd);
00034 this->addPort("FriJointImpedance", port_joint_impedance_command);
00035 this->addPort("JointPositionCommand", port_joint_position_command);
00036 this->addPort("NullspaceEffortCommand", port_nullspace_torque_command);
00037
00038 }
00039
00040 CartWrench::~CartWrench() {
00041
00042 }
00043
00044 bool CartWrench::configureHook() {
00045 return true;
00046 }
00047
00048 void CartWrench::cleanupHook() {
00049
00050 }
00051
00052 bool CartWrench::startHook() {
00053
00054 jnt_trq_cmd.resize(7);
00055 jnt_pos.resize(7);
00056 null_trq_cmd.resize(7);
00057
00058
00059 cartesian_impedance_command.stiffness.force.x = 1000.0;
00060 cartesian_impedance_command.stiffness.force.y = 1000.0;
00061 cartesian_impedance_command.stiffness.force.z = 1000.0;
00062
00063 cartesian_impedance_command.stiffness.torque.x = 100.0;
00064 cartesian_impedance_command.stiffness.torque.y = 100.0;
00065 cartesian_impedance_command.stiffness.torque.z = 100.0;
00066
00067 cartesian_impedance_command.damping.force.x = 0.7;
00068 cartesian_impedance_command.damping.force.y = 0.7;
00069 cartesian_impedance_command.damping.force.z = 0.7;
00070
00071 cartesian_impedance_command.damping.torque.x = 0.7;
00072 cartesian_impedance_command.damping.torque.y = 0.7;
00073 cartesian_impedance_command.damping.torque.z = 0.7;
00074
00075
00076 cartesian_wrench_command.force.x = 0.0;
00077 cartesian_wrench_command.force.y = 0.0;
00078 cartesian_wrench_command.force.z = 0.0;
00079 cartesian_wrench_command.torque.x = 0.0;
00080 cartesian_wrench_command.torque.y = 0.0;
00081 cartesian_wrench_command.torque.z = 0.0;
00082
00083 if(port_cart_pos_msr.read(cart_pos_msr) == RTT::NoData) {
00084 RTT::Logger::log(RTT::Logger::Error) << "No position data " << RTT::endlog();
00085 return false;
00086 }
00087
00088 if(port_command_period.read(dt) == RTT::NoData) {
00089 RTT::Logger::log(RTT::Logger::Error) << "No comand period data " << RTT::endlog();
00090 return false;
00091 }
00092 geometry_msgs::Pose tool_frame_msg;
00093
00094 if(port_tool_frame.read(tool_frame_msg) == RTT::NoData) {
00095 RTT::Logger::log(RTT::Logger::Error) << "No tool data " << RTT::endlog();
00096 tool_frame = KDL::Frame::Identity();
00097 } else {
00098 tf::PoseMsgToKDL(tool_frame_msg, tool_frame);
00099 }
00100 tf::PoseMsgToKDL(cart_pos_msr, cart_pos_ref);
00101
00102 cart_pos_old = cart_pos_ref;
00103
00104 for(size_t i = 0; i < 7; i++) {
00105 imp.stiffness[i] = 0.0;
00106 imp.damping[i] = 0.0;
00107 null_trq_cmd[i] = 0;
00108 }
00109
00110 return true;
00111 }
00112
00113 void CartWrench::stopHook() {
00114
00115 port_jnt_pos_msr.read(jnt_pos);
00116 port_joint_position_command.write(jnt_pos);
00117
00118 for(size_t i = 0; i < 7; i++) {
00119 imp.stiffness[i] = 200.0;
00120 imp.damping[i] = 0.8;
00121 }
00122
00123 port_joint_impedance_command.write(imp);
00124 }
00125
00126 double jointLimitTrq(double hl, double ll, double ls, double r_max, double q) {
00127
00128 if(q > (hl - ls)) {
00129 return -1 * ((q - hl + ls)/ls) * ((q - hl + ls)/ls) * r_max;
00130 } else if(q < (ll + ls)) {
00131 return ((ll + ls - q)/ls) * ((ll + ls - q)/ls) * r_max;
00132 } else {
00133 return 0.0;
00134 }
00135
00136 }
00137
00138 void CartWrench::updateHook() {
00139
00140 Matrix77d Kj, Dj;
00141 Vector6d Kc, Dxi, v, K0;
00142 Matrix77d M, Mi, N, N3;
00143 Matrix76d Ji, jT;
00144 Vector7d r0;
00145 Matrix66d A ,A1, Kc1, Dc, Q;
00146
00147 port_joint_impedance_command.write(imp);
00148 port_command_period.read(dt);
00149 port_jacobian.read(jacobian);
00150 port_cartesian_impedance_command.read(cartesian_impedance_command);
00151 port_cartesian_wrench_command.read(cartesian_wrench_command);
00152 port_jnt_pos_msr.read(jnt_pos);
00153 port_mass_matrix.read(M);
00154
00155 if(port_cartesian_position_command.read(cart_pos_cmd) == RTT::NewData){
00156 tf::PoseMsgToKDL(cart_pos_cmd, cart_pos_ref);
00157 }
00158
00159 if(port_nullspace_torque_command.read(null_trq_cmd) == RTT::NewData) {
00160 for(size_t i = 0; i<7; i++)
00161 r0(i) = null_trq_cmd[i];
00162 }
00163
00164 port_cart_pos_msr.read(cart_pos_msr);
00165
00166
00167
00168 KDL::Frame pos_msr, spring;
00169
00170 tf::PoseMsgToKDL(cart_pos_msr, pos_msr);
00171
00172
00173
00174 Kc(0) = cartesian_impedance_command.stiffness.force.x;
00175 Kc(1) = cartesian_impedance_command.stiffness.force.y;
00176 Kc(2) = cartesian_impedance_command.stiffness.force.z;
00177
00178 Kc(3) = cartesian_impedance_command.stiffness.torque.x;
00179 Kc(4) = cartesian_impedance_command.stiffness.torque.y;
00180 Kc(5) = cartesian_impedance_command.stiffness.torque.z;
00181
00182 Dxi(0) = cartesian_impedance_command.damping.force.x;
00183 Dxi(1) = cartesian_impedance_command.damping.force.y;
00184 Dxi(2) = cartesian_impedance_command.damping.force.z;
00185
00186 Dxi(3) = cartesian_impedance_command.damping.torque.x;
00187 Dxi(4) = cartesian_impedance_command.damping.torque.y;
00188 Dxi(5) = cartesian_impedance_command.damping.torque.z;
00189
00190 jT = jacobian.data.transpose();
00191
00192 Mi = M.inverse();
00193
00194
00195
00196 A = (jacobian.data * Mi * jT).inverse();
00197 N3 = (Matrix77d::Identity() - jT * A * jacobian.data * Mi);
00198
00199 es.compute(Kc.asDiagonal(), A);
00200 K0 = es.eigenvalues();
00201 Q = es.eigenvectors().inverse();
00202
00203 Dc = Q.transpose() * Dxi.asDiagonal() * K0.cwiseSqrt().asDiagonal() * Q;
00204
00205
00206
00207 spring = pos_msr.Inverse() * cart_pos_ref;
00208
00209 KDL::Twist tw = KDL::diff(KDL::Frame::Identity(), spring);
00210
00211 Eigen::VectorXd trq(7);
00212 Eigen::VectorXd wrench2(6);
00213
00214 KDL::Wrench wrench;
00215
00216 wrench2(0) = tw.vel.x() * cartesian_impedance_command.stiffness.force.x;
00217 wrench2(1) = tw.vel.y() * cartesian_impedance_command.stiffness.force.y;
00218 wrench2(2) = tw.vel.z() * cartesian_impedance_command.stiffness.force.z;
00219 wrench2(3) = tw.rot.x() * cartesian_impedance_command.stiffness.torque.x;
00220 wrench2(4) = tw.rot.y() * cartesian_impedance_command.stiffness.torque.y;
00221 wrench2(5) = tw.rot.z() * cartesian_impedance_command.stiffness.torque.z;
00222
00223
00224 KDL::Frame cart_pos_diff = cart_pos_old.Inverse() * pos_msr;
00225 cart_pos_old = pos_msr;
00226
00227 KDL::Twist vel = KDL::diff(KDL::Frame::Identity(), cart_pos_diff);
00228
00229 v(0) = ((vel.vel.x() / dt));
00230 v(1) = ((vel.vel.y() / dt));
00231 v(2) = ((vel.vel.z() / dt));
00232 v(3) = ((vel.rot.x() / dt));
00233 v(4) = ((vel.rot.y() / dt));
00234 v(5) = ((vel.rot.z() / dt));
00235
00236 wrench2(0) -= Dc.diagonal()(0) * v(0);
00237 wrench2(1) -= Dc.diagonal()(1) * v(1);
00238 wrench2(2) -= Dc.diagonal()(2) * v(2);
00239 wrench2(3) -= Dc.diagonal()(3) * v(3);
00240 wrench2(4) -= Dc.diagonal()(4) * v(4);
00241 wrench2(5) -= Dc.diagonal()(5) * v(5);
00242
00243
00244 wrench2(0) += cartesian_wrench_command.force.x;
00245 wrench2(1) += cartesian_wrench_command.force.y;
00246 wrench2(2) += cartesian_wrench_command.force.z;
00247 wrench2(3) += cartesian_wrench_command.torque.x;
00248 wrench2(4) += cartesian_wrench_command.torque.y;
00249 wrench2(5) += cartesian_wrench_command.torque.z;
00250
00251 r0(0) = jointLimitTrq(2.96, -2.96, 0.26, 10.0, jnt_pos[0]);
00252 r0(1) = jointLimitTrq(2.09, -2.09, 0.26, 10.0, jnt_pos[1]);
00253 r0(2) = jointLimitTrq(2.96, -2.96, 0.26, 10.0, jnt_pos[2]);
00254 r0(3) = jointLimitTrq(2.09, -2.09, 0.26, 10.0, jnt_pos[3]);
00255 r0(4) = jointLimitTrq(2.96, -2.96, 0.26, 10.0, jnt_pos[4]);
00256 r0(5) = jointLimitTrq(2.09, -2.09, 0.26, 10.0, jnt_pos[5]);
00257 r0(6) = jointLimitTrq(2.96, -2.96, 0.26, 10.0, jnt_pos[6]);
00258
00259 trq = jT * wrench2 + N3 * r0;
00260
00261 for(size_t i = 0; i < 7; i++)
00262 jnt_trq_cmd[i] = trq(i);
00263
00264
00265 Kj = jT * Kc.asDiagonal() * jacobian.data;
00266
00267
00268
00269 for(size_t i = 0; i < 7; i++) {
00270 imp.stiffness[i] = Kj(i, i);
00271 imp.damping[i] = 0.0;
00272 }
00273
00274 port_joint_position_command.write(jnt_pos);
00275 port_joint_impedance_command.write(imp);
00276 port_jnt_trq_cmd.write(jnt_trq_cmd);
00277
00278 geometry_msgs::Pose desired_pos;
00279
00280 tf::PoseKDLToMsg(cart_pos_ref, desired_pos);
00281 port_desired_cartesian_position.write(desired_pos);
00282
00283 }
00284
00285 }
00286 ORO_CREATE_COMPONENT(lwr::CartWrench)