joint_state_listener.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 /* Author: Wim Meeussen */
36 
37 #include <algorithm>
38 #include <map>
39 #include <string>
40 
41 #include <ros/ros.h>
42 #include <urdf/model.h>
43 #include <kdl/tree.hpp>
45 
48 
49 using namespace robot_state_publisher;
50 
52 {
53 }
54 
55 JointStateListener::JointStateListener(const KDL::Tree& tree, const MimicMap& m, const urdf::Model& model)
56  : JointStateListener(std::make_shared<RobotStatePublisher>(tree, model), m)
57 {
58 }
59 
60 JointStateListener::JointStateListener(const std::shared_ptr<RobotStatePublisher>& rsp, const MimicMap& m)
61  : state_publisher_(rsp), mimic_(m)
62 {
63  ros::NodeHandle n_tilde("~");
65 
66  // set publish frequency
67  double publish_freq;
68  n_tilde.param("publish_frequency", publish_freq, 50.0);
69  // set whether to use the /tf_static latched static transform broadcaster
70  n_tilde.param("use_tf_static", use_tf_static_, true);
71  // ignore_timestamp_ == true, joins_states messages are accepted, no matter their timestamp
72  n_tilde.param("ignore_timestamp", ignore_timestamp_, false);
73  // get the tf_prefix parameter from the closest namespace
74  publish_interval_ = ros::Duration(1.0/std::max(publish_freq, 1.0));
75 
76  // Setting tcpNoNelay tells the subscriber to ask publishers that connect
77  // to set TCP_NODELAY on their side. This prevents some joint_state messages
78  // from being bundled together, increasing the latency of one of the messages.
79  ros::TransportHints transport_hints;
80  transport_hints.tcpNoDelay(true);
81  // subscribe to joint state
82  joint_state_sub_ = n.subscribe("joint_states", 1, &JointStateListener::callbackJointState, this, transport_hints);
83 
84  // trigger to publish fixed joints
85  // if using static transform broadcaster, this will be a oneshot trigger and only run once
87 }
88 
89 
91 {}
92 
94 {
95  ros::NodeHandle n_tilde("~");
96  std::string tf_prefix;
97 
98  // get the tf_prefix parameter from the closest namespace
99  std::string tf_prefix_key;
100  n_tilde.searchParam("tf_prefix", tf_prefix_key);
101  n_tilde.param(tf_prefix_key, tf_prefix, std::string(""));
102 
103  return tf_prefix;
104 }
105 
107 {
108  (void)e;
109  state_publisher_->publishFixedTransforms(getTFPrefix(), use_tf_static_);
110 }
111 
113 {
114  if (state->name.size() != state->position.size()){
115  if (state->position.empty()){
116  const int throttleSeconds = 300;
117  ROS_WARN_THROTTLE(throttleSeconds,
118  "Robot state publisher ignored a JointState message about joint(s) "
119  "\"%s\"(,...) whose position member was empty. This message will "
120  "not reappear for %d seconds.", state->name[0].c_str(),
121  throttleSeconds);
122  } else {
123  ROS_ERROR("Robot state publisher ignored an invalid JointState message");
124  }
125  return;
126  }
127 
128  // check if we moved backwards in time (e.g. when playing a bag file)
129  ros::Time now = ros::Time::now();
130  if (last_callback_time_ > now) {
131  // force re-publish of joint transforms
132  ROS_WARN("Moved backwards in time (probably because ROS clock was reset), re-publishing joint transforms!");
133  last_publish_time_.clear();
134  }
135  ros::Duration warning_threshold(30.0);
136  if ((state->header.stamp + warning_threshold) < now) {
137  ROS_WARN_THROTTLE(10, "Received JointState is %f seconds old.", (now - state->header.stamp).toSec());
138  }
139  last_callback_time_ = now;
140 
141  // determine least recently published joint
142  ros::Time last_published = now;
143  for (size_t i = 0; i < state->name.size(); ++i) {
144  ros::Time t = last_publish_time_[state->name[i]];
145  last_published = (t < last_published) ? t : last_published;
146  }
147  // note: if a joint was seen for the first time,
148  // then last_published is zero.
149 
150  // check if we need to publish
151  if (ignore_timestamp_ || state->header.stamp >= last_published + publish_interval_) {
152  // get joint positions from state message
153  std::map<std::string, double> joint_positions;
154  for (size_t i = 0; i < state->name.size(); ++i) {
155  joint_positions.insert(make_pair(state->name[i], state->position[i]));
156  }
157 
158  for (MimicMap::iterator i = mimic_.begin(); i != mimic_.end(); i++) {
159  if(joint_positions.find(i->second->joint_name) != joint_positions.end()) {
160  double pos = joint_positions[i->second->joint_name] * i->second->multiplier + i->second->offset;
161  joint_positions.insert(make_pair(i->first, pos));
162  }
163  }
164 
165  state_publisher_->publishTransforms(joint_positions, state->header.stamp, getTFPrefix());
166 
167  // store publish time in joint map
168  for (size_t i = 0; i<state->name.size(); ++i) {
169  last_publish_time_[state->name[i]] = state->header.stamp;
170  }
171  }
172 }
robot_state_publisher::JointStateListener::joint_state_sub_
ros::Subscriber joint_state_sub_
Definition: joint_state_listener.h:115
boost::shared_ptr
ROS_WARN_THROTTLE
#define ROS_WARN_THROTTLE(period,...)
ros.h
robot_state_publisher::JointStateListener::mimic_
MimicMap mimic_
Definition: joint_state_listener.h:119
ros::TransportHints
robot_state_publisher::JointStateListener
Definition: joint_state_listener.h:89
joint_state_listener.h
robot_state_publisher::RobotStatePublisher
Definition: robot_state_publisher.h:96
urdf::Model
robot_state_publisher::JointStateListener::getTFPrefix
std::string getTFPrefix()
Definition: joint_state_listener.cpp:93
ros::TransportHints::tcpNoDelay
TransportHints & tcpNoDelay(bool nodelay=true)
robot_state_publisher::JointStateListener::use_tf_static_
bool use_tf_static_
Definition: joint_state_listener.h:120
robot_state_publisher::JointStateListener::last_publish_time_
std::map< std::string, ros::Time > last_publish_time_
Definition: joint_state_listener.h:118
robot_state_publisher::JointStateListener::callbackJointState
virtual void callbackJointState(const JointStateConstPtr &state)
Definition: joint_state_listener.cpp:112
model.h
ros::NodeHandle::searchParam
bool searchParam(const std::string &key, std::string &result) const
ROS_ERROR
#define ROS_ERROR(...)
ROS_WARN
#define ROS_WARN(...)
ros::NodeHandle::subscribe
Subscriber subscribe(const std::string &topic, uint32_t queue_size, const boost::function< void(C)> &callback, const VoidConstPtr &tracked_object=VoidConstPtr(), const TransportHints &transport_hints=TransportHints())
robot_state_publisher
Definition: joint_state_listener.h:52
ros::TimerEvent
robot_state_publisher.h
robot_state_publisher::JointStateListener::publish_interval_
ros::Duration publish_interval_
Definition: joint_state_listener.h:113
kdl_parser.hpp
robot_state_publisher::JointStateListener::last_callback_time_
ros::Time last_callback_time_
Definition: joint_state_listener.h:117
robot_state_publisher::MimicMap
std::map< std::string, urdf::JointMimicSharedPtr > MimicMap
Definition: joint_state_listener.h:87
robot_state_publisher::JointStateListener::JointStateListener
JointStateListener()
Definition: joint_state_listener.cpp:51
ros::Time
robot_state_publisher::JointStateListener::state_publisher_
std::shared_ptr< RobotStatePublisher > state_publisher_
Definition: joint_state_listener.h:114
robot_state_publisher::JointStateListener::~JointStateListener
~JointStateListener()
Destructor.
Definition: joint_state_listener.cpp:90
std
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
robot_state_publisher::JointStateListener::timer_
ros::Timer timer_
Definition: joint_state_listener.h:116
ros::NodeHandle::createTimer
Timer createTimer(Duration period, const TimerCallback &callback, bool oneshot=false, bool autostart=true) const
ros::Duration
robot_state_publisher::JointStateListener::ignore_timestamp_
bool ignore_timestamp_
Definition: joint_state_listener.h:121
robot_state_publisher::JointStateListener::callbackFixedJoint
virtual void callbackFixedJoint(const ros::TimerEvent &e)
Definition: joint_state_listener.cpp:106
ros::NodeHandle
ros::Time::now
static Time now()


robot_state_publisher
Author(s): Ioan Sucan , Jackie Kay , Wim Meeussen
autogenerated on Fri Nov 3 2023 02:08:42