00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <moveit/planning_scene_monitor/current_state_monitor.h>
00038 #include <tf_conversions/tf_eigen.h>
00039 #include <limits>
00040
00041 planning_scene_monitor::CurrentStateMonitor::CurrentStateMonitor(const robot_model::RobotModelConstPtr &kmodel, const boost::shared_ptr<tf::Transformer> &tf) :
00042 tf_(tf), kmodel_(kmodel), kstate_(kmodel), root_(kstate_.getJointState(kmodel->getRoot()->getName())), state_monitor_started_(false), error_(std::numeric_limits<float>::epsilon())
00043 {
00044 kstate_.setToDefaultValues();
00045 }
00046
00047 planning_scene_monitor::CurrentStateMonitor::~CurrentStateMonitor()
00048 {
00049 stopStateMonitor();
00050 }
00051
00052 robot_state::RobotStatePtr planning_scene_monitor::CurrentStateMonitor::getCurrentState() const
00053 {
00054 boost::mutex::scoped_lock slock(state_update_lock_);
00055 robot_state::RobotState *result = new robot_state::RobotState(kstate_);
00056 return robot_state::RobotStatePtr(result);
00057 }
00058
00059 ros::Time planning_scene_monitor::CurrentStateMonitor::getCurrentStateTime() const
00060 {
00061 boost::mutex::scoped_lock slock(state_update_lock_);
00062 return current_state_time_;
00063 }
00064
00065 std::pair<robot_state::RobotStatePtr, ros::Time> planning_scene_monitor::CurrentStateMonitor::getCurrentStateAndTime() const
00066 {
00067 boost::mutex::scoped_lock slock(state_update_lock_);
00068 robot_state::RobotState *result = new robot_state::RobotState(kstate_);
00069 return std::make_pair(robot_state::RobotStatePtr(result), current_state_time_);
00070 }
00071
00072 std::map<std::string, double> planning_scene_monitor::CurrentStateMonitor::getCurrentStateValues() const
00073 {
00074 std::map<std::string, double> m;
00075 boost::mutex::scoped_lock slock(state_update_lock_);
00076 kstate_.getStateValues(m);
00077 return m;
00078 }
00079
00080 void planning_scene_monitor::CurrentStateMonitor::addUpdateCallback(const JointStateUpdateCallback &fn)
00081 {
00082 if (fn)
00083 update_callbacks_.push_back(fn);
00084 }
00085
00086 void planning_scene_monitor::CurrentStateMonitor::clearUpdateCallbacks()
00087 {
00088 update_callbacks_.clear();
00089 }
00090
00091 void planning_scene_monitor::CurrentStateMonitor::startStateMonitor(const std::string &joint_states_topic)
00092 {
00093 if (!state_monitor_started_ && kmodel_)
00094 {
00095 joint_time_.clear();
00096 if (joint_states_topic.empty())
00097 ROS_ERROR("The joint states topic cannot be an empty string");
00098 else
00099 joint_state_subscriber_ = nh_.subscribe(joint_states_topic, 25, &CurrentStateMonitor::jointStateCallback, this);
00100 state_monitor_started_ = true;
00101 monitor_start_time_ = ros::Time::now();
00102 ROS_DEBUG("Listening to joint states on topic '%s'", joint_states_topic.c_str());
00103 }
00104 }
00105
00106 bool planning_scene_monitor::CurrentStateMonitor::isActive() const
00107 {
00108 return state_monitor_started_;
00109 }
00110
00111 void planning_scene_monitor::CurrentStateMonitor::stopStateMonitor()
00112 {
00113 if (state_monitor_started_)
00114 {
00115 joint_state_subscriber_.shutdown();
00116 ROS_DEBUG("No longer listening o joint states");
00117 state_monitor_started_ = false;
00118 }
00119 }
00120
00121 std::string planning_scene_monitor::CurrentStateMonitor::getMonitoredTopic() const
00122 {
00123 if (joint_state_subscriber_)
00124 return joint_state_subscriber_.getTopic();
00125 else
00126 return "";
00127 }
00128
00129 bool planning_scene_monitor::CurrentStateMonitor::isPassiveDOF(const std::string &dof) const
00130 {
00131 if (kmodel_->hasJointModel(dof))
00132 {
00133 if (kmodel_->getJointModel(dof)->isPassive())
00134 return true;
00135 }
00136 else
00137 {
00138
00139 std::size_t slash = dof.find_last_of("/");
00140 if (slash != std::string::npos)
00141 {
00142 std::string joint_name = dof.substr(0, slash);
00143 if (kmodel_->hasJointModel(joint_name))
00144 if (kmodel_->getJointModel(joint_name)->isPassive())
00145 return true;
00146 }
00147 }
00148 return false;
00149 }
00150
00151 bool planning_scene_monitor::CurrentStateMonitor::haveCompleteState() const
00152 {
00153 bool result = true;
00154 const std::vector<std::string> &dof = kmodel_->getVariableNames();
00155 boost::mutex::scoped_lock slock(state_update_lock_);
00156 for (std::size_t i = 0 ; i < dof.size() ; ++i)
00157 if (joint_time_.find(dof[i]) == joint_time_.end())
00158 {
00159 if (!isPassiveDOF(dof[i]))
00160 {
00161 ROS_DEBUG("Joint variable '%s' has never been updated", dof[i].c_str());
00162 result = false;
00163 }
00164 }
00165 return result;
00166 }
00167
00168 bool planning_scene_monitor::CurrentStateMonitor::haveCompleteState(std::vector<std::string> &missing_states) const
00169 {
00170 bool result = true;
00171 const std::vector<std::string> &dof = kmodel_->getVariableNames();
00172 boost::mutex::scoped_lock slock(state_update_lock_);
00173 for (std::size_t i = 0 ; i < dof.size() ; ++i)
00174 if (joint_time_.find(dof[i]) == joint_time_.end())
00175 if (!isPassiveDOF(dof[i]))
00176 {
00177 ROS_DEBUG("Joint variable '%s' has never been updated", dof[i].c_str());
00178 missing_states.push_back(dof[i]);
00179 result = false;
00180 }
00181 return result;
00182 }
00183
00184 bool planning_scene_monitor::CurrentStateMonitor::haveCompleteState(const ros::Duration &age) const
00185 {
00186 bool result = true;
00187 const std::vector<std::string> &dof = kmodel_->getVariableNames();
00188 ros::Time now = ros::Time::now();
00189 ros::Time old = now - age;
00190 boost::mutex::scoped_lock slock(state_update_lock_);
00191 for (std::size_t i = 0 ; i < dof.size() ; ++i)
00192 {
00193 if (isPassiveDOF(dof[i]))
00194 continue;
00195 std::map<std::string, ros::Time>::const_iterator it = joint_time_.find(dof[i]);
00196 if (it == joint_time_.end())
00197 {
00198 ROS_DEBUG("Joint variable '%s' has never been updated", dof[i].c_str());
00199 result = false;
00200 }
00201 else
00202 if (it->second < old)
00203 {
00204 ROS_DEBUG("Joint variable '%s' was last updated %0.3lf seconds ago (older than the allowed %0.3lf seconds)",
00205 dof[i].c_str(), (now - it->second).toSec(), age.toSec());
00206 result = false;
00207 }
00208 }
00209 return result;
00210 }
00211
00212 bool planning_scene_monitor::CurrentStateMonitor::haveCompleteState(const ros::Duration &age,
00213 std::vector<std::string> &missing_states) const
00214 {
00215 bool result = true;
00216 const std::vector<std::string> &dof = kmodel_->getVariableNames();
00217 ros::Time now = ros::Time::now();
00218 ros::Time old = now - age;
00219 boost::mutex::scoped_lock slock(state_update_lock_);
00220 for (std::size_t i = 0 ; i < dof.size() ; ++i)
00221 {
00222 if (isPassiveDOF(dof[i]))
00223 continue;
00224 std::map<std::string, ros::Time>::const_iterator it = joint_time_.find(dof[i]);
00225 if (it == joint_time_.end())
00226 {
00227 ROS_DEBUG("Joint variable '%s' has never been updated", dof[i].c_str());
00228 missing_states.push_back(dof[i]);
00229 result = false;
00230 }
00231 else
00232 if (it->second < old)
00233 {
00234 ROS_DEBUG("Joint variable '%s' was last updated %0.3lf seconds ago (older than the allowed %0.3lf seconds)",
00235 dof[i].c_str(), (now - it->second).toSec(), age.toSec());
00236 missing_states.push_back(dof[i]);
00237 result = false;
00238 }
00239 }
00240 return result;
00241 }
00242
00243 bool planning_scene_monitor::CurrentStateMonitor::waitForCurrentState(double wait_time) const
00244 {
00245 double slept_time = 0.0;
00246 double sleep_step_s = std::min(0.05, wait_time / 10.0);
00247 ros::Duration sleep_step(sleep_step_s);
00248 while (!haveCompleteState() && slept_time < wait_time)
00249 {
00250 sleep_step.sleep();
00251 slept_time += sleep_step_s;
00252 }
00253 return haveCompleteState();
00254 }
00255
00256 bool planning_scene_monitor::CurrentStateMonitor::waitForCurrentState(const std::string &group, double wait_time) const
00257 {
00258 if (waitForCurrentState(wait_time))
00259 return true;
00260 bool ok = true;
00261
00262
00263 std::vector<std::string> missing_joints;
00264 if (!haveCompleteState(missing_joints))
00265 {
00266 const robot_model::JointModelGroup *jmg = kmodel_->getJointModelGroup(group);
00267 if (jmg)
00268 {
00269 std::set<std::string> mj;
00270 mj.insert(missing_joints.begin(), missing_joints.end());
00271 const std::vector<std::string> &names= jmg->getJointModelNames();
00272 bool ok = true;
00273 for (std::size_t i = 0 ; ok && i < names.size() ; ++i)
00274 if (mj.find(names[i]) != mj.end())
00275 ok = false;
00276 }
00277 else
00278 ok = false;
00279 }
00280 return ok;
00281 }
00282
00283 void planning_scene_monitor::CurrentStateMonitor::jointStateCallback(const sensor_msgs::JointStateConstPtr &joint_state)
00284 {
00285 if (joint_state->name.size() != joint_state->position.size())
00286 {
00287 ROS_ERROR_THROTTLE(1, "State monitor received invalid joint state");
00288 return;
00289 }
00290
00291
00292 std::size_t n = joint_state->name.size();
00293 std::map<std::string, double> joint_state_map;
00294 const std::map<std::string, std::pair<double, double> > &bounds = kmodel_->getAllVariableBounds();
00295 for (std::size_t i = 0 ; i < n ; ++i)
00296 {
00297 joint_state_map[joint_state->name[i]] = joint_state->position[i];
00298 joint_time_[joint_state->name[i]] = joint_state->header.stamp;
00299
00300
00301 const robot_model::JointModel* jm = kmodel_->getJointModel(joint_state->name[i]);
00302 if (jm && jm->getType() == robot_model::JointModel::REVOLUTE)
00303 if (static_cast<const robot_model::RevoluteJointModel*>(jm)->isContinuous())
00304 continue;
00305
00306 std::map<std::string, std::pair<double, double> >::const_iterator bi = bounds.find(joint_state->name[i]);
00307
00308 if (bi != bounds.end())
00309 {
00310 if (joint_state->position[i] < bi->second.first && joint_state->position[i] >= bi->second.first - error_)
00311 joint_state_map[joint_state->name[i]] = bi->second.first;
00312 else
00313 if (joint_state->position[i] > bi->second.second && joint_state->position[i] <= bi->second.second + error_)
00314 joint_state_map[joint_state->name[i]] = bi->second.second;
00315 }
00316 }
00317 bool set_map_values = true;
00318
00319
00320 if (tf_ && (root_->getType() == robot_model::JointModel::PLANAR ||
00321 root_->getType() == robot_model::JointModel::FLOATING))
00322 {
00323 const std::string &child_frame = root_->getJointModel()->getChildLinkModel()->getName();
00324 const std::string &parent_frame = kmodel_->getModelFrame();
00325
00326 std::string err;
00327 ros::Time tm;
00328 tf::StampedTransform transf;
00329 bool ok = false;
00330 if (tf_->getLatestCommonTime(parent_frame, child_frame, tm, &err) == tf::NO_ERROR)
00331 {
00332 try
00333 {
00334 tf_->lookupTransform(parent_frame, child_frame, tm, transf);
00335 ok = true;
00336 }
00337 catch(tf::TransformException& ex)
00338 {
00339 ROS_ERROR_THROTTLE(1, "Unable to lookup transform from %s to %s. Exception: %s", parent_frame.c_str(), child_frame.c_str(), ex.what());
00340 }
00341 }
00342 else
00343 ROS_DEBUG_THROTTLE(1, "Unable to lookup transform from %s to %s: no common time.", parent_frame.c_str(), child_frame.c_str());
00344 if (ok)
00345 {
00346 const std::vector<std::string> &vars = root_->getJointModel()->getVariableNames();
00347 for (std::size_t j = 0; j < vars.size() ; ++j)
00348 joint_time_[vars[j]] = tm;
00349 set_map_values = false;
00350 Eigen::Affine3d eigen_transf;
00351 tf::transformTFToEigen(transf, eigen_transf);
00352 boost::mutex::scoped_lock slock(state_update_lock_);
00353 root_->setVariableValues(eigen_transf);
00354 kstate_.setStateValues(joint_state_map);
00355 current_state_time_ = joint_state->header.stamp;
00356 }
00357 }
00358
00359 if (set_map_values)
00360 {
00361 boost::mutex::scoped_lock slock(state_update_lock_);
00362 kstate_.setStateValues(joint_state_map);
00363 current_state_time_ = joint_state->header.stamp;
00364 }
00365
00366
00367 for (std::size_t i = 0 ; i < update_callbacks_.size() ; ++i)
00368 update_callbacks_[i](joint_state);
00369 }