37 #include <boost/scoped_ptr.hpp> 40 #include <kdl/tree.hpp> 41 #include <kdl/chainjnttojacsolver.hpp> 44 #include <geometry_msgs/WrenchStamped.h> 45 #include <sensor_msgs/JointState.h> 48 #include <Eigen/Geometry> 79 wrench_stamped_pub_ = n.
advertise<geometry_msgs::WrenchStamped>(
"wrench", 1);
83 n_tilde.
param(
"publish_frequency", publish_freq, 50.0);
84 publish_interval_ =
ros::Duration(1.0/std::max(publish_freq,1.0));
87 n_tilde.
param(
"time_constant", t_const_, 0.3);
89 n_tilde.
param(
"root", root, std::string(
"torso_lift_link"));
90 n_tilde.
param(
"tip", tip, std::string(
"l_gripper_tool_frame"));
94 robot_model.
initParam(
"robot_description");
98 kdl_tree.
getChain(root, tip, chain_);
114 std::map<std::string, double> joint_name_position;
115 if (state->name.size() != state->position.size()){
116 ROS_ERROR(
"Robot state publisher received an invalid joint state vector");
122 for (
unsigned int i=0; i<state->name.size(); i++) {
123 ros::Time t = last_publish_time_[state->name[i]];
124 last_published = (t < last_published) ? t : last_published;
127 if (state->header.stamp >= last_published + publish_interval_){
129 std::map<std::string, double> joint_positions;
130 std::map<std::string, double> joint_efforts;
131 for (
unsigned int i=0; i<state->name.size(); i++) {
132 joint_positions.insert(make_pair(state->name[i], state->position[i]));
133 joint_efforts.insert(make_pair(state->name[i], state->effort[i]));
138 Eigen::Matrix<double,Eigen::Dynamic,6> jac_t;
139 Eigen::Matrix<double,6,Eigen::Dynamic> jac_t_pseudo_inv;
154 if ( joint_positions.find(joint_name) == joint_positions.end() ) {
155 ROS_ERROR(
"Joint '%s' is not found in joint state vector", joint_name.c_str());
159 jnt_pos_(j) = joint_positions[joint_name];
160 tau(j) = joint_efforts[joint_name];
164 jnt_to_jac_solver_->JntToJac(jnt_pos_, jacobian_);
165 jac_t = jacobian_.
data.transpose();
167 jac_t_pseudo_inv =(jac_t.transpose() * jac_t).
inverse() * jac_t.transpose();
169 jac_t_pseudo_inv =jac_t.transpose() * ( jac_t * jac_t.transpose() ).
inverse();
174 Eigen::Matrix<double,6,6> mat_i = mat_i = jac_t_pseudo_inv * jac_t;
175 for (
unsigned int i = 0; i < 6; i++) {
176 std::stringstream ss;
177 for (
unsigned int j=0; j<6; j++)
178 ss << std::fixed << std::setw(8) << std::setprecision(4) << mat_i(j,i) <<
" ";
184 for (
unsigned int j=0; j<6; j++)
187 for (
unsigned int i = 0; i < jnt_pos_.
rows(); i++)
189 F(j) += -1 * jac_t_pseudo_inv(j, i) * tau(i);
194 F += (F_pre_ - F) *
exp(-1.0 / t_const_);
195 for (
unsigned int j=0; j<6; j++){
205 listener_.
lookupTransform( tip, root, state->header.stamp , transform);
211 for (
unsigned int j=0; j<3; j++){
216 geometry_msgs::WrenchStamped msg;
217 msg.header.stamp = state->header.stamp;
218 msg.header.frame_id =
tip;
221 msg.wrench.force.x = F_pub.
force[0];
222 msg.wrench.force.
y = F_pub.
force[1];
223 msg.wrench.force.
z = F_pub.
force[2];
224 msg.wrench.torque.
x = F_pub.
torque[0];
225 msg.wrench.torque.
y = F_pub.
torque[1];
226 msg.wrench.torque.
z = F_pub.
torque[2];
227 wrench_stamped_pub_.
publish(msg);
231 for (
unsigned int i = 0; i < jnt_pos_.
rows(); i++) {
232 std::stringstream ss;
233 for (
unsigned int j=0; j<6; j++)
234 ss << std::fixed << std::setw(8) << std::setprecision(4) <<
jacobian_(j,i) <<
" ";
238 std::stringstream sstau;
239 for (
unsigned int i = 0; i < tau.
rows(); i++) {
240 sstau << std::fixed << std::setw(8) << std::setprecision(4) << tau(i) <<
" ";
243 ROS_INFO(
"force : ");
244 std::stringstream ssf;
245 for (
unsigned int j = 0; j < 6; j++) {
246 ssf << std::fixed << std::setw(8) << std::setprecision(4) << F(j) <<
" ";
252 for (
unsigned int i=0; i<state->name.size(); i++)
253 last_publish_time_[state->name[i]] = state->header.stamp;
261 int main (
int argc,
char ** argv) {
264 ros::init(argc, argv,
"virtual_force_publisher");
ros::Duration publish_interval_
boost::shared_ptr< sensor_msgs::JointState const > JointStateConstPtr
const Segment & getSegment(unsigned int nr) const
void publish(const boost::shared_ptr< M > &message) const
bool treeFromUrdfModel(const urdf::ModelInterface &robot_model, KDL::Tree &tree)
unsigned int rows() const
void resize(unsigned int newNrOfColumns)
void vectorKDLToTF(const KDL::Vector &k, tf::Vector3 &t)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
unsigned int getNrOfSegments() const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
boost::scoped_ptr< KDL::ChainJntToJacSolver > jnt_to_jac_solver_
ROSCPP_DECL void spin(Spinner &spinner)
unsigned int columns() const
void callbackJointState(const JointStateConstPtr &state)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Matrix< double, 6, Eigen::Dynamic > data
const std::string & getName() const
std::map< std::string, ros::Time > last_publish_time_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
TFSIMD_FORCE_INLINE Quaternion inverse(const Quaternion &q)
ros::Publisher wrench_stamped_pub_
int main(int argc, char **argv)
const Joint & getJoint() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
unsigned int getNrOfJoints() const
bool initParam(const std::string ¶m)
tf::TransformListener listener_
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
void resize(unsigned int newSize)
bool getChain(const std::string &chain_root, const std::string &chain_tip, Chain &chain) const
#define ROS_INFO_STREAM(args)
ros::Subscriber joint_state_sub_
unsigned int rows() const
const JointType & getType() const