39 #include <boost/algorithm/string/join.hpp>
44 constexpr
char LOGNAME[] =
"current_state_monitor";
49 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer)
55 const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
const ros::NodeHandle& nh)
58 , robot_model_(robot_model)
59 , robot_state_(robot_model)
60 , state_monitor_started_(false)
61 , copy_dynamics_(false)
62 , error_(
std::numeric_limits<double>::
epsilon())
76 return moveit::core::RobotStatePtr(result);
81 const std::vector<const moveit::core::JointModel*>* active_joints = &
robot_model_->getActiveJointModels();
105 if (!oldest_state_time.isZero())
107 oldest_state_time = std::min(oldest_state_time, it->second);
111 oldest_state_time = it->second;
115 return oldest_state_time;
124 std::pair<moveit::core::RobotStatePtr, ros::Time>
134 std::map<std::string, double> m;
138 for (std::size_t i = 0; i < names.size(); ++i)
139 m[names[i]] = pos[i];
184 if (joint_states_topic.empty())
191 std::make_shared<TFConnection>(
tf_buffer_->_addTransformsChangedListener([
this] { tfCallback(); }));
228 std::vector<std::string>* missing_joints,
229 const std::string& group)
const
231 const std::vector<const moveit::core::JointModel*>* active_joints = &
robot_model_->getActiveJointModels();
242 << std::quoted(group)
243 <<
". All joints of the group are considered to be missing!");
245 *missing_joints =
robot_model_->getActiveJointModelNames();
252 std::map<const moveit::core::JointModel*, ros::Time>::const_iterator it =
joint_time_.find(joint);
257 else if (it->second < oldest_allowed_update_time)
260 joint->getName().c_str(), (oldest_allowed_update_time - it->second).toSec());
265 missing_joints->push_back(joint->getName());
269 return (missing_joints ==
nullptr) || missing_joints->empty();
282 if (elapsed > timeout)
285 "Didn't receive robot state (joint angles) with recent timestamp within "
286 << wait_time <<
" seconds.\n"
287 <<
"Check clock synchronization if your are running ROS across multiple machines!");
296 double slept_time = 0.0;
297 double sleep_step_s = std::min(0.05, wait_time / 10.0);
302 slept_time += sleep_step_s;
309 double slept_time = 0.0;
310 double sleep_step_s = std::min(0.05, wait_time / 10.0);
315 slept_time += sleep_step_s;
317 std::vector<std::string> missing_joints;
328 if (joint_state->name.size() != joint_state->position.size())
332 "State monitor received invalid joint state (number of joint names does not match number of "
341 std::size_t n = joint_state->name.size();
342 for (std::size_t i = 0; i < n; ++i)
351 if (
auto& joint_time{
joint_time_[jm] }; joint_time < joint_state->header.stamp)
353 joint_time = joint_state->header.stamp;
359 <<
"' is not newer than the previous state. Assuming your rosbag looped.");
389 if (joint_state->name.size() == joint_state->velocity.size() &&
397 if (joint_state->name.size() == joint_state->effort.size() &&
410 update_callback(joint_state);
419 const std::vector<const moveit::core::JointModel*>& multi_dof_joints =
robot_model_->getMultiDOFJointModels();
422 bool changes =
false;
428 const std::string& child_frame = joint->getChildLinkModel()->getName();
429 const std::string& parent_frame =
430 joint->getParentLinkModel() ? joint->getParentLinkModel()->getName() :
robot_model_->getModelFrame();
433 geometry_msgs::TransformStamped transf;
437 latest_common_time = transf.header.stamp;
442 << joint->getName() <<
"': Failure to lookup transform between '"
443 << parent_frame.c_str() <<
"' and '" << child_frame.c_str()
444 <<
"' with TF exception: " << ex.what());
453 std::vector<double> new_values(joint->getStateSpaceDimension());
476 sensor_msgs::JointStatePtr joint_state(
new sensor_msgs::JointState);
478 update_callback(joint_state);