00001 #include <rtt/TaskContext.hpp>
00002 #include <rtt/Port.hpp>
00003 #include <rtt/Component.hpp>
00004
00005
00006 #include <kdl/frames.hpp>
00007 #include <kdl/jntarray.hpp>
00008 #include <kdl/jacobian.hpp>
00009
00010 #include <kuka_lwr_fri/friComm.h>
00011
00012 #include <lwr_fri/CartesianImpedance.h>
00013 #include <lwr_fri/FriJointImpedance.h>
00014 #include <geometry_msgs/Pose.h>
00015 #include <geometry_msgs/Wrench.h>
00016 #include <geometry_msgs/Twist.h>
00017 #include <std_msgs/Int32.h>
00018
00019 #include <tf_conversions/tf_kdl.h>
00020
00021 #include <Eigen/Dense>
00022
00023 #include <vector>
00024
00025 #include <sys/socket.h>
00026 #include <arpa/inet.h>
00027 #include <netinet/in.h>
00028 #include <sys/types.h>
00029 #include <errno.h>
00030 #include <fcntl.h>
00031 #include <arpa/inet.h>
00032
00033 #ifndef HAVE_RTNET
00034
00035 #define rt_dev_socket socket
00036 #define rt_dev_setsockopt setsockopt
00037 #define rt_dev_bind bind
00038 #define rt_dev_recvfrom recvfrom
00039 #define rt_dev_sendto sendto
00040 #define rt_dev_close close
00041
00042 #else
00043 #include <rtdm/rtdm.h>
00044 #endif
00045
00046 typedef Eigen::Matrix<double, 7, 7> Matrix77d;
00047
00048
00049 class FRIComponent : public RTT::TaskContext {
00050 public:
00051 FRIComponent(const std::string & name) : TaskContext(name) {
00052
00053 prop_fri_port = 49938;
00054
00055 this->addProperty("fri_port", prop_fri_port);
00056
00057 this->ports()->addPort("CartesianImpedanceCommand", port_CartesianImpedanceCommand).doc("");
00058 this->ports()->addPort("CartesianWrenchCommand", port_CartesianWrenchCommand).doc("");
00059 this->ports()->addPort("CartesianPositionCommand", port_CartesianPositionCommand).doc("");
00060 this->ports()->addPort("JointImpedanceCommand", port_JointImpedanceCommand).doc("");
00061 this->ports()->addPort("JointPositionCommand", port_JointPositionCommand).doc("");
00062 this->ports()->addPort("JointTorqueCommand", port_JointTorqueCommand).doc("");
00063 this->ports()->addPort("KRL_CMD", port_KRL_CMD).doc("");
00064
00065 this->ports()->addPort("CartesianWrench", port_CartesianWrench).doc("");
00066 this->ports()->addPort("RobotState", port_RobotState).doc("");
00067 this->ports()->addPort("FRIState", port_FRIState).doc("");
00068 this->ports()->addPort("JointVelocity", port_JointVelocity).doc("");
00069 this->ports()->addPort("CartesianVelocity", port_CartesianVelocity).doc("");
00070 this->ports()->addPort("CartesianPosition", port_CartesianPosition).doc("");
00071 this->ports()->addPort("MassMatrix", port_MassMatrix).doc("");
00072 this->ports()->addPort("Jacobian", port_Jacobian).doc("");
00073 this->ports()->addPort("JointTorque", port_JointTorque).doc("");
00074 this->ports()->addPort("GravityTorque", port_GravityTorque);
00075 this->ports()->addPort("JointPosition", port_JointPosition).doc("");
00076 }
00077
00078 ~FRIComponent(){
00079 }
00080
00081 bool configureHook() {
00082
00083 jnt_pos_.resize(LBR_MNJ);
00084 jnt_pos_old_.resize(LBR_MNJ);
00085 jnt_vel_.resize(LBR_MNJ);
00086 jnt_trq_.resize(LBR_MNJ);
00087 grav_trq_.resize(LBR_MNJ);
00088 jnt_pos_cmd_.resize(LBR_MNJ);
00089 jnt_trq_cmd_.resize(LBR_MNJ);
00090 jac_.resize(LBR_MNJ);
00091
00092 port_JointPosition.setDataSample(jnt_pos_);
00093 port_JointVelocity.setDataSample(jnt_vel_);
00094 port_JointTorque.setDataSample(jnt_trq_);
00095 port_GravityTorque.setDataSample(grav_trq_);
00096 port_Jacobian.setDataSample(jac_);
00097
00098 if (fri_create_socket() != 0)
00099 return false;
00100
00101 return true;
00102 }
00103
00104 bool startHook() {
00105
00106
00107 return true;
00108 }
00109
00110 void stopHook() {
00111
00112
00113 }
00114
00115 void updateHook() {
00116 if( true) {
00117 doComm();
00118 }
00119 }
00120
00121 private:
00122
00123 void doComm() {
00124
00125
00126 geometry_msgs::Pose cart_pos, cart_pos_cmd;
00127 geometry_msgs::Wrench cart_wrench, cart_wrench_cmd;
00128 geometry_msgs::Twist cart_twist;
00129 Matrix77d mass;
00130 lwr_fri::FriJointImpedance jnt_imp_cmd;
00131 lwr_fri::CartesianImpedance cart_imp_cmd;
00132
00133
00134 if (fri_recv() == 0) {
00135
00136 KDL::Frame baseFrame(
00137 KDL::Rotation::RPY(m_msr_data.krl.realData[3] * M_PI / 180.0,
00138 m_msr_data.krl.realData[4] * M_PI / 180.0,
00139 m_msr_data.krl.realData[5] * M_PI / 180.0),
00140 KDL::Vector(m_msr_data.krl.realData[0] / 1000.0,
00141 m_msr_data.krl.realData[1] / 1000.0,
00142 m_msr_data.krl.realData[2] / 1000.0));
00143
00144
00145 for (unsigned int i = 0; i < LBR_MNJ; i++) {
00146 grav_trq_[i] = m_msr_data.data.gravity[i];
00147 jnt_trq_[i] = m_msr_data.data.estExtJntTrq[i];
00148 jnt_pos_[i] = m_msr_data.data.msrJntPos[i];
00149 jnt_vel_[i] = (jnt_pos_[i] - jnt_pos_old_[i]) / m_msr_data.intf.desiredMsrSampleTime;
00150 jnt_pos_old_[i] = jnt_pos_[i];
00151 }
00152
00153 geometry_msgs::Quaternion quat;
00154 KDL::Frame cartPos;
00155 cartPos.M = KDL::Rotation(m_msr_data.data.msrCartPos[0],
00156 m_msr_data.data.msrCartPos[1], m_msr_data.data.msrCartPos[2],
00157 m_msr_data.data.msrCartPos[4], m_msr_data.data.msrCartPos[5],
00158 m_msr_data.data.msrCartPos[6], m_msr_data.data.msrCartPos[8],
00159 m_msr_data.data.msrCartPos[9], m_msr_data.data.msrCartPos[10]);
00160 cartPos.p.x(m_msr_data.data.msrCartPos[3]);
00161 cartPos.p.y(m_msr_data.data.msrCartPos[7]);
00162 cartPos.p.z(m_msr_data.data.msrCartPos[11]);
00163 cartPos = baseFrame * cartPos;
00164 tf::PoseKDLToMsg(cartPos, cart_pos);
00165
00166 KDL::Twist v = KDL::diff(T_old, cartPos, m_msr_data.intf.desiredMsrSampleTime);
00167 v = cartPos.M.Inverse() * v;
00168 T_old = cartPos;
00169 tf::TwistKDLToMsg(v, cart_twist);
00170
00171 cart_wrench.force.x = m_msr_data.data.estExtTcpFT[0];
00172 cart_wrench.force.y = m_msr_data.data.estExtTcpFT[1];
00173 cart_wrench.force.z = m_msr_data.data.estExtTcpFT[2];
00174 cart_wrench.torque.x = m_msr_data.data.estExtTcpFT[5];
00175 cart_wrench.torque.y = m_msr_data.data.estExtTcpFT[4];
00176 cart_wrench.torque.z = m_msr_data.data.estExtTcpFT[3];
00177
00178 for (int i = 0; i < FRI_CART_VEC; i++)
00179 for (int j = 0; j < LBR_MNJ; j++)
00180 jac_(i, j) = m_msr_data.data.jacobian[i * LBR_MNJ + j];
00181
00182 jac_.data.row(3).swap(jac_.data.row(5));
00183
00184 for (unsigned int i = 0; i < LBR_MNJ; i++) {
00185 for (unsigned int j = 0; j < LBR_MNJ; j++) {
00186 mass(i, j) = m_msr_data.data.massMatrix[LBR_MNJ * i + j];
00187 }
00188 }
00189
00190
00191 m_cmd_data.head.datagramId = FRI_DATAGRAM_ID_CMD;
00192 m_cmd_data.head.packetSize = sizeof(tFriCmdData);
00193 m_cmd_data.head.sendSeqCount = ++counter;
00194 m_cmd_data.head.reflSeqCount = m_msr_data.head.sendSeqCount;
00195
00196
00197
00198 if (!(m_msr_data.krl.boolData & (1 << 0))) {
00199 std_msgs::Int32 x;
00200 if (port_KRL_CMD.read(x) == RTT::NewData) {
00201 m_cmd_data.krl.intData[0] = x.data;
00202 m_cmd_data.krl.boolData |= (1 << 0);
00203 }
00204 } else {
00205 m_cmd_data.krl.boolData &= ~(1 << 0);
00206 }
00207
00208 if (!isPowerOn()) {
00209
00210 for (int i = 0; i < LBR_MNJ; i++) {
00211 m_cmd_data.cmd.jntPos[i] = m_msr_data.data.cmdJntPos[i]
00212 + m_msr_data.data.cmdJntPosFriOffset[i];
00213 }
00214 }
00215 if (m_msr_data.intf.state == FRI_STATE_MON || !isPowerOn()) {
00216
00217 if (m_msr_data.robot.control == FRI_CTRL_POSITION
00218 || m_msr_data.robot.control == FRI_CTRL_JNT_IMP) {
00219 m_cmd_data.cmd.cmdFlags = FRI_CMD_JNTPOS;
00220 for (unsigned int i = 0; i < LBR_MNJ; i++) {
00221
00222
00223
00224
00225 m_cmd_data.cmd.jntPos[i] = m_msr_data.data.cmdJntPos[i]
00226 + m_msr_data.data.cmdJntPosFriOffset[i];
00227 }
00228 }
00229
00230 if (m_msr_data.robot.control == FRI_CTRL_JNT_IMP) {
00231 m_cmd_data.cmd.cmdFlags |= FRI_CMD_JNTTRQ;
00232 m_cmd_data.cmd.cmdFlags |= FRI_CMD_JNTSTIFF | FRI_CMD_JNTDAMP;
00233 for (unsigned int i = 0; i < LBR_MNJ; i++) {
00234 m_cmd_data.cmd.addJntTrq[i] = 0.0;
00235 m_cmd_data.cmd.jntStiffness[i] = 0;
00236 m_cmd_data.cmd.jntDamping[i] = 0.7;
00237 }
00238 }
00239 if (m_msr_data.robot.control == FRI_CTRL_CART_IMP) {
00240 m_cmd_data.cmd.cmdFlags = FRI_CMD_CARTPOS | FRI_CMD_TCPFT;
00241 m_cmd_data.cmd.cmdFlags |= FRI_CMD_CARTSTIFF | FRI_CMD_CARTDAMP;
00242 for (unsigned int i = 0; i < FRI_CART_FRM_DIM; i++)
00243 m_cmd_data.cmd.cartPos[i] = m_msr_data.data.msrCartPos[i];
00244 for (unsigned int i = 0; i < FRI_CART_VEC; i++)
00245 m_cmd_data.cmd.addTcpFT[i] = 0.0;
00246 for (unsigned int i = 0; i < FRI_CART_VEC / 2; i++) {
00247
00248 m_cmd_data.cmd.cartStiffness[i] = 0;
00249 m_cmd_data.cmd.cartDamping[i] = 0.7;
00250
00251 m_cmd_data.cmd.cartStiffness[i + FRI_CART_VEC / 2] = 0;
00252 m_cmd_data.cmd.cartDamping[i + FRI_CART_VEC / 2] = 0.7;
00253 }
00254 }
00255 }
00256
00257 if ((m_msr_data.intf.state == FRI_STATE_CMD) && isPowerOn()) {
00258
00259 if (m_msr_data.robot.control == FRI_CTRL_POSITION
00260 || m_msr_data.robot.control == FRI_CTRL_JNT_IMP) {
00261
00262 if (port_JointPositionCommand.read(jnt_pos_cmd_) == RTT::NewData) {
00263 if (jnt_pos_cmd_.size() == LBR_MNJ) {
00264 for (unsigned int i = 0; i < LBR_MNJ; i++)
00265 m_cmd_data.cmd.jntPos[i] = jnt_pos_cmd_[i];
00266 } else
00267 RTT::log(RTT::Warning) << "Size of " << port_JointPositionCommand.getName()
00268 << " not equal to " << LBR_MNJ << RTT::endlog();
00269
00270 }
00271 }
00272
00273 if (m_msr_data.robot.control == FRI_CTRL_JNT_IMP) {
00274
00275 if (port_JointTorqueCommand.read(jnt_trq_cmd_)
00276 == RTT::NewData) {
00277
00278 if (jnt_trq_cmd_.size() == LBR_MNJ) {
00279 for (unsigned int i = 0; i < LBR_MNJ; i++)
00280 m_cmd_data.cmd.addJntTrq[i] = jnt_trq_cmd_[i];
00281 } else
00282 RTT::log(RTT::Warning) << "Size of " << port_JointTorqueCommand.getName()
00283 << " not equal to " << LBR_MNJ << RTT::endlog();
00284
00285 }
00286
00287 if (port_JointImpedanceCommand.read(jnt_imp_cmd) == RTT::NewData) {
00288 for (unsigned int i = 0; i < LBR_MNJ; i++) {
00289 m_cmd_data.cmd.jntStiffness[i] =
00290 jnt_imp_cmd.stiffness[i];
00291 m_cmd_data.cmd.jntDamping[i] = jnt_imp_cmd.damping[i];
00292 }
00293 }
00294 } else if (m_msr_data.robot.control == FRI_CTRL_CART_IMP) {
00295 if (port_CartesianPositionCommand.read(cart_pos_cmd) == RTT::NewData) {
00296 KDL::Rotation rot = KDL::Rotation::Quaternion(
00297 cart_pos_cmd.orientation.x, cart_pos_cmd.orientation.y,
00298 cart_pos_cmd.orientation.z, cart_pos_cmd.orientation.w);
00299 m_cmd_data.cmd.cartPos[0] = rot.data[0];
00300 m_cmd_data.cmd.cartPos[1] = rot.data[1];
00301 m_cmd_data.cmd.cartPos[2] = rot.data[2];
00302 m_cmd_data.cmd.cartPos[4] = rot.data[3];
00303 m_cmd_data.cmd.cartPos[5] = rot.data[4];
00304 m_cmd_data.cmd.cartPos[6] = rot.data[5];
00305 m_cmd_data.cmd.cartPos[8] = rot.data[6];
00306 m_cmd_data.cmd.cartPos[9] = rot.data[7];
00307 m_cmd_data.cmd.cartPos[10] = rot.data[8];
00308
00309 m_cmd_data.cmd.cartPos[3] = cart_pos_cmd.position.x;
00310 m_cmd_data.cmd.cartPos[7] = cart_pos_cmd.position.y;
00311 m_cmd_data.cmd.cartPos[11] = cart_pos_cmd.position.z;
00312 }
00313
00314 if (port_CartesianWrenchCommand.read(cart_wrench_cmd) == RTT::NewData) {
00315 m_cmd_data.cmd.addTcpFT[0] = cart_wrench_cmd.force.x;
00316 m_cmd_data.cmd.addTcpFT[1] = cart_wrench_cmd.force.y;
00317 m_cmd_data.cmd.addTcpFT[2] = cart_wrench_cmd.force.z;
00318 m_cmd_data.cmd.addTcpFT[3] = cart_wrench_cmd.torque.z;
00319 m_cmd_data.cmd.addTcpFT[4] = cart_wrench_cmd.torque.y;
00320 m_cmd_data.cmd.addTcpFT[5] = cart_wrench_cmd.torque.x;
00321 }
00322
00323 if (port_CartesianImpedanceCommand.read(cart_imp_cmd) == RTT::NewData) {
00324 m_cmd_data.cmd.cartStiffness[0] = cart_imp_cmd.stiffness.linear.x;
00325 m_cmd_data.cmd.cartStiffness[1] = cart_imp_cmd.stiffness.linear.y;
00326 m_cmd_data.cmd.cartStiffness[2] = cart_imp_cmd.stiffness.linear.z;
00327 m_cmd_data.cmd.cartStiffness[5] = cart_imp_cmd.stiffness.angular.x;
00328 m_cmd_data.cmd.cartStiffness[4] = cart_imp_cmd.stiffness.angular.y;
00329 m_cmd_data.cmd.cartStiffness[3] = cart_imp_cmd.stiffness.angular.z;
00330 m_cmd_data.cmd.cartDamping[0] = cart_imp_cmd.damping.linear.x;
00331 m_cmd_data.cmd.cartDamping[1] = cart_imp_cmd.damping.linear.y;
00332 m_cmd_data.cmd.cartDamping[2] = cart_imp_cmd.damping.linear.z;
00333 m_cmd_data.cmd.cartDamping[5] = cart_imp_cmd.damping.angular.x;
00334 m_cmd_data.cmd.cartDamping[4] = cart_imp_cmd.damping.angular.y;
00335 m_cmd_data.cmd.cartDamping[3] = cart_imp_cmd.damping.angular.z;
00336 }
00337 } else if (m_msr_data.robot.control == FRI_CTRL_OTHER) {
00338 this->error();
00339 }
00340 }
00341
00342
00343 port_RobotState.write(m_msr_data.robot);
00344 port_FRIState.write(m_msr_data.intf);
00345
00346 port_JointPosition.write(jnt_pos_);
00347 port_JointVelocity.write(jnt_vel_);
00348 port_JointTorque.write(jnt_trq_);
00349 port_GravityTorque.write(grav_trq_);
00350
00351 port_CartesianPosition.write(cart_pos);
00352 port_CartesianVelocity.write(cart_twist);
00353 port_CartesianWrench.write(cart_wrench);
00354
00355 port_Jacobian.write(jac_);
00356 port_MassMatrix.write(mass);
00357
00358 fri_send();
00359 }
00360
00361 this->trigger();
00362
00363 }
00364
00365
00366 RTT::InputPort<lwr_fri::CartesianImpedance > port_CartesianImpedanceCommand;
00367 RTT::InputPort<geometry_msgs::Wrench > port_CartesianWrenchCommand;
00368 RTT::InputPort<geometry_msgs::Pose > port_CartesianPositionCommand;
00369 RTT::InputPort<lwr_fri::FriJointImpedance > port_JointImpedanceCommand;
00370 RTT::InputPort<Eigen::VectorXd > port_JointPositionCommand;
00371 RTT::InputPort<Eigen::VectorXd > port_JointTorqueCommand;
00372 RTT::InputPort<std_msgs::Int32 > port_KRL_CMD;
00373
00374 RTT::OutputPort<geometry_msgs::Wrench > port_CartesianWrench;
00375 RTT::OutputPort<tFriRobotState > port_RobotState;
00376 RTT::OutputPort<tFriIntfState > port_FRIState;
00377 RTT::OutputPort<Eigen::VectorXd > port_JointVelocity;
00378 RTT::OutputPort<geometry_msgs::Twist > port_CartesianVelocity;
00379 RTT::OutputPort<geometry_msgs::Pose > port_CartesianPosition;
00380 RTT::OutputPort<Matrix77d > port_MassMatrix;
00381 RTT::OutputPort<KDL::Jacobian > port_Jacobian;
00382 RTT::OutputPort<Eigen::VectorXd > port_JointTorque;
00383 RTT::OutputPort<Eigen::VectorXd > port_GravityTorque;
00384 RTT::OutputPort<Eigen::VectorXd > port_JointPosition;
00385
00386 int prop_fri_port;
00387
00388
00389
00390 Eigen::VectorXd jnt_pos_;
00391 Eigen::VectorXd jnt_pos_old_;
00392 Eigen::VectorXd jnt_trq_;
00393 Eigen::VectorXd grav_trq_;
00394 Eigen::VectorXd jnt_vel_;
00395
00396 Eigen::VectorXd jnt_pos_cmd_;
00397 Eigen::VectorXd jnt_trq_cmd_;
00398
00399 KDL::Jacobian jac_;
00400
00401 KDL::Frame T_old;
00402
00403 int m_socket, m_remote_port, m_control_mode;
00404 std::string joint_names_prefix;
00405 uint16_t counter, fri_state_last;
00406 struct sockaddr_in m_remote_addr;
00407 socklen_t m_sock_addr_len;
00408
00409 tFriMsrData m_msr_data;
00410 tFriCmdData m_cmd_data;
00411
00412 int fri_recv() {
00413 int n = rt_dev_recvfrom(m_socket, (void*) &m_msr_data, sizeof(m_msr_data),
00414 0, (sockaddr*) &m_remote_addr, &m_sock_addr_len);
00415 if (sizeof(tFriMsrData) != n) {
00416 RTT::log(RTT::Error) << "bad packet length: " << n << ", expected: "
00417 << sizeof(tFriMsrData) << RTT::endlog();
00418 return -1;
00419 }
00420 return 0;
00421 }
00422
00423 int fri_send() {
00424 if (0
00425 > rt_dev_sendto(m_socket, (void*) &m_cmd_data, sizeof(m_cmd_data), 0,
00426 (sockaddr*) &m_remote_addr, m_sock_addr_len)) {
00427 RTT::log(RTT::Error) << "Sending datagram failed."
00428 << ntohs(m_remote_addr.sin_port) << RTT::endlog();
00429 return -1;
00430 }
00431 return 0;
00432 }
00433
00434 bool isPowerOn() { return m_msr_data.robot.power!=0; }
00435
00436 int fri_create_socket() {
00437
00438 if (m_socket != 0)
00439 rt_dev_close(m_socket);
00440 m_socket = rt_dev_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
00441 rt_dev_setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, 0, 0);
00442
00443 struct sockaddr_in local_addr;
00444 bzero((char *) &local_addr, sizeof(local_addr));
00445 local_addr.sin_family = AF_INET;
00446 local_addr.sin_addr.s_addr = INADDR_ANY;
00447 local_addr.sin_port = htons(prop_fri_port);
00448
00449 if (rt_dev_bind(m_socket, (sockaddr*) &local_addr, sizeof(sockaddr_in)) < 0) {
00450 RTT::log(RTT::Error) << "Binding of port failed with errno " << errno << RTT::endlog();
00451 return -1;
00452 }
00453
00454 return 0;
00455 }
00456
00457
00458 };
00459
00460 ORO_CREATE_COMPONENT(FRIComponent)
00461