Go to the documentation of this file.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
00037 #include "planning_environment/monitors/kinematic_model_state_monitor.h"
00038 #include "planning_environment/util/construct_object.h"
00039 #include "planning_environment/models/model_utils.h"
00040 #include <angles/angles.h>
00041 #include <sstream>
00042
00043 void planning_environment::KinematicModelStateMonitor::setupRSM(void)
00044 {
00045 state_monitor_started_ = false;
00046 on_state_update_callback_ = NULL;
00047 have_pose_ = have_joint_state_ = false;
00048
00049 printed_out_of_date_ = false;
00050 if (rm_->loadedModels())
00051 {
00052 kmodel_ = rm_->getKinematicModel();
00053 robot_frame_ = rm_->getRobotFrameId();
00054 ROS_INFO("Robot frame is '%s'", robot_frame_.c_str());
00055 startStateMonitor();
00056 } else {
00057 ROS_INFO("Can't start state monitor yet");
00058 }
00059
00060 nh_.param<double>("joint_state_cache_time", joint_state_cache_time_, 2.0);
00061 nh_.param<double>("joint_state_cache_allowed_difference", joint_state_cache_allowed_difference_, .25);
00062
00063 }
00064
00065 void planning_environment::KinematicModelStateMonitor::startStateMonitor(void)
00066 {
00067 if (state_monitor_started_)
00068 return;
00069
00070 if (rm_->loadedModels())
00071 {
00072 joint_state_subscriber_ = root_handle_.subscribe("joint_states", 25, &KinematicModelStateMonitor::jointStateCallback, this);
00073 ROS_DEBUG("Listening to joint states");
00074
00075 }
00076 state_monitor_started_ = true;
00077 }
00078
00079 void planning_environment::KinematicModelStateMonitor::stopStateMonitor(void)
00080 {
00081 if (!state_monitor_started_)
00082 return;
00083
00084 joint_state_subscriber_.shutdown();
00085
00086 joint_state_map_cache_.clear();
00087
00088 ROS_DEBUG("Kinematic state is no longer being monitored");
00089
00090 state_monitor_started_ = false;
00091 }
00092
00093 void planning_environment::KinematicModelStateMonitor::jointStateCallback(const sensor_msgs::JointStateConstPtr &joint_state)
00094 {
00095
00096
00097 planning_models::KinematicState state(kmodel_);
00098
00099 current_joint_values_lock_.lock();
00100
00101 state.setKinematicState(current_joint_state_map_);
00102
00103 static bool first_time = true;
00104
00105 unsigned int n = joint_state->name.size();
00106 if (joint_state->name.size() != joint_state->position.size())
00107 {
00108 ROS_ERROR("Planning environment received invalid joint state");
00109 current_joint_values_lock_.unlock();
00110 return;
00111 }
00112
00113 std::map<std::string, double> joint_state_map;
00114 for (unsigned int i = 0 ; i < n ; ++i)
00115 {
00116 joint_state_map[joint_state->name[i]] = joint_state->position[i];
00117 }
00118
00119 std::vector<planning_models::KinematicState::JointState*>& joint_state_vector = state.getJointStateVector();
00120
00121 for(std::vector<planning_models::KinematicState::JointState*>::iterator it = joint_state_vector.begin();
00122 it != joint_state_vector.end();
00123 it++) {
00124 bool tfSets = false;
00125 bool joint_state_sets = false;
00126
00127 std::string parent_frame_id = (*it)->getParentFrameId();
00128 std::string child_frame_id = (*it)->getChildFrameId();
00129 if(!parent_frame_id.empty() && !child_frame_id.empty()) {
00130 std::string err;
00131 ros::Time tm;
00132 tf::StampedTransform transf;
00133 bool ok = false;
00134 if (tf_->getLatestCommonTime(parent_frame_id, child_frame_id, tm, &err) == tf::NO_ERROR) {
00135 ok = true;
00136 try
00137 {
00138 tf_->lookupTransform(parent_frame_id, child_frame_id, tm, transf);
00139 }
00140 catch(tf::TransformException& ex)
00141 {
00142 ROS_ERROR("Unable to lookup transform from %s to %s. Exception: %s", parent_frame_id.c_str(), child_frame_id.c_str(), ex.what());
00143 ok = false;
00144 }
00145 } else {
00146 ROS_DEBUG("Unable to lookup transform from %s to %s: no common time.", parent_frame_id.c_str(), child_frame_id.c_str());
00147 ok = false;
00148 }
00149 if(ok) {
00150 tfSets = (*it)->setJointStateValues(transf);
00151 if(tfSets) {
00152 const std::vector<std::string>& joint_state_names = (*it)->getJointStateNameOrder();
00153 for(std::vector<std::string>::const_iterator it = joint_state_names.begin();
00154 it != joint_state_names.end();
00155 it++) {
00156 last_joint_update_[*it] = tm;
00157 }
00158 }
00159
00160
00161
00162
00163 have_pose_ = tfSets;
00164 last_pose_update_ = tm;
00165 }
00166 }
00167
00168 joint_state_sets = (*it)->setJointStateValues(joint_state_map);
00169 if(joint_state_sets) {
00170 const std::vector<std::string>& joint_state_names = (*it)->getJointStateNameOrder();
00171 for(std::vector<std::string>::const_iterator it = joint_state_names.begin();
00172 it != joint_state_names.end();
00173 it++) {
00174 last_joint_update_[*it] = joint_state->header.stamp;
00175 }
00176 }
00177 }
00178
00179 state.updateKinematicLinks();
00180 state.getKinematicStateValues(current_joint_state_map_);
00181
00182 if(allJointsUpdated()) {
00183 have_joint_state_ = true;
00184 last_joint_state_update_ = joint_state->header.stamp;
00185
00186 if(!joint_state_map_cache_.empty()) {
00187 if(joint_state->header.stamp-joint_state_map_cache_.back().first > ros::Duration(joint_state_cache_allowed_difference_)) {
00188 ROS_DEBUG_STREAM("Introducing joint state cache sparsity time of " << (joint_state->header.stamp-joint_state_map_cache_.back().first).toSec());
00189 }
00190 }
00191
00192 joint_state_map_cache_.push_back(std::pair<ros::Time, std::map<std::string, double> >(joint_state->header.stamp,
00193 current_joint_state_map_));
00194 }
00195
00196 if(have_joint_state_) {
00197 while(1) {
00198 if(joint_state_map_cache_.empty()) {
00199 ROS_WARN("Empty joint state map cache");
00200 break;
00201 }
00202 if((ros::Time::now()-joint_state_map_cache_.front().first) > ros::Duration(joint_state_cache_time_)) {
00203 joint_state_map_cache_.pop_front();
00204 } else {
00205 break;
00206 }
00207 }
00208 }
00209
00210 first_time = false;
00211
00212 if(!allJointsUpdated(ros::Duration(1.0))) {
00213 if(!printed_out_of_date_) {
00214 ROS_WARN_STREAM("Got joint state update but did not update some joints for more than 1 second. Turn on DEBUG for more info");
00215 printed_out_of_date_ = true;
00216 }
00217 } else {
00218 printed_out_of_date_ = false;
00219 }
00220 if(on_state_update_callback_ != NULL) {
00221 on_state_update_callback_(joint_state);
00222 }
00223 current_joint_values_lock_.unlock();
00224 }
00225
00226 bool planning_environment::KinematicModelStateMonitor::allJointsUpdated(ros::Duration allowed_dur) const {
00227 current_joint_values_lock_.lock();
00228 bool ret = true;
00229 for(std::map<std::string, double>::const_iterator it = current_joint_state_map_.begin();
00230 it != current_joint_state_map_.end();
00231 it++) {
00232 if(last_joint_update_.find(it->first) == last_joint_update_.end()) {
00233 ROS_DEBUG_STREAM("Joint " << it->first << " not yet updated");
00234 ret = false;
00235 continue;
00236 }
00237 if(allowed_dur != ros::Duration()) {
00238 ros::Duration dur = ros::Time::now()-last_joint_update_.find(it->first)->second;
00239 if(dur > allowed_dur) {
00240 ROS_DEBUG_STREAM("Joint " << it->first << " last updated " << dur.toSec() << " where allowed duration is " << allowed_dur.toSec());
00241 ret = false;
00242 continue;
00243 }
00244 }
00245 }
00246 current_joint_values_lock_.unlock();
00247 return ret;
00248 }
00249
00250 void planning_environment::KinematicModelStateMonitor::setStateValuesFromCurrentValues(planning_models::KinematicState& state) const
00251 {
00252 current_joint_values_lock_.lock();
00253 state.setKinematicState(current_joint_state_map_);
00254 current_joint_values_lock_.unlock();
00255 }
00256
00257
00258 bool planning_environment::KinematicModelStateMonitor::getCurrentRobotState(arm_navigation_msgs::RobotState& robot_state) const
00259 {
00260 planning_models::KinematicState state(kmodel_);
00261 setStateValuesFromCurrentValues(state);
00262 convertKinematicStateToRobotState(state, last_joint_state_update_, rm_->getWorldFrameId(), robot_state);
00263 return true;
00264 }
00265
00266 bool planning_environment::KinematicModelStateMonitor::setKinematicStateToTime(const ros::Time& time,
00267 planning_models::KinematicState& state) const
00268 {
00269 std::map<std::string, double> joint_value_map;
00270 if(!getCachedJointStateValues(time, joint_value_map)) {
00271 return false;
00272 }
00273 state.setKinematicState(joint_value_map);
00274 return true;
00275 }
00276
00277 bool planning_environment::KinematicModelStateMonitor::getCachedJointStateValues(const ros::Time& time, std::map<std::string, double>& ret_map) const {
00278
00279 current_joint_values_lock_.lock();
00280
00281
00282 if(time-ros::Duration(joint_state_cache_allowed_difference_) > joint_state_map_cache_.back().first) {
00283 ROS_WARN("Asking for time substantially newer than that contained in cache");
00284 current_joint_values_lock_.unlock();
00285 return false;
00286 }
00287 if(time+ros::Duration(joint_state_cache_allowed_difference_) < joint_state_map_cache_.front().first) {
00288 ROS_WARN_STREAM("Asking for time substantially older than that contained in cache " << time.toSec() << " " << joint_state_map_cache_.front().first.toSec());
00289 current_joint_values_lock_.unlock();
00290 return false;
00291 }
00292
00293
00294 if(time < joint_state_map_cache_.front().first) {
00295 ret_map = joint_state_map_cache_.front().second;
00296 } else if (time > joint_state_map_cache_.back().first) {
00297 ret_map = joint_state_map_cache_.back().second;
00298 } else {
00299 std::list<std::pair<ros::Time, std::map<std::string, double> > >::const_reverse_iterator next = ++joint_state_map_cache_.rbegin();
00300 std::list<std::pair<ros::Time, std::map<std::string, double> > >::const_reverse_iterator cur = joint_state_map_cache_.rbegin();
00301 while(next != joint_state_map_cache_.rbegin()) {
00302 if(time < cur->first && time > next->first) {
00303 ros::Duration ear_diff = time - next->first;
00304 ros::Duration lat_diff = cur->first - time;
00305 if(ear_diff > ros::Duration(joint_state_cache_allowed_difference_) &&
00306 lat_diff > ros::Duration(joint_state_cache_allowed_difference_)) {
00307 ROS_WARN("Asking for time in joint state area that's too sparse");
00308 current_joint_values_lock_.unlock();
00309 return false;
00310 } else {
00311 if(ear_diff > lat_diff) {
00312 ROS_DEBUG_STREAM("Got time later within " << lat_diff.toSec());
00313 ret_map = cur->second;
00314 break;
00315 } else {
00316 ROS_DEBUG_STREAM("Got time earlier within " << ear_diff.toSec());
00317 ret_map = next->second;
00318 break;
00319 }
00320 }
00321 }
00322 next++;
00323 cur++;
00324 }
00325 }
00326 current_joint_values_lock_.unlock();
00327 return true;
00328 }
00329
00330 void planning_environment::KinematicModelStateMonitor::waitForState(void) const
00331 {
00332 int s = 0;
00333 while (nh_.ok() && !haveState())
00334 {
00335 if (s == 0)
00336 {
00337 ROS_INFO("Waiting for robot state ...");
00338 if (!have_joint_state_)
00339 ROS_INFO("Waiting for joint state ...");
00340 }
00341 s = (s + 1) % 40;
00342 ros::spinOnce();
00343 ros::Duration().fromSec(0.05).sleep();
00344 }
00345 if (haveState())
00346 ROS_INFO("Robot state received!");
00347 }
00348
00349 bool planning_environment::KinematicModelStateMonitor::isJointStateUpdated(double sec) const
00350 {
00351
00352
00353
00354
00355 if(sec < 1e-5)
00356 {
00357 return false;
00358 }
00359
00360
00361
00362
00363 if(sec > 1e-5 && last_joint_state_update_ > ros::TIME_MIN && ros::Time::now() < ros::Time(sec))
00364 {
00365 return true;
00366 }
00367
00368 ROS_DEBUG("Last joint update %g interval begins %g", last_joint_state_update_.toSec(), (ros::Time::now()-ros::Duration(sec)).toSec());
00369
00370
00371 if (last_joint_state_update_ < ros::Time::now()-ros::Duration(sec))
00372 {
00373 return false;
00374 }
00375
00376 return true;
00377 }
00378
00379 bool planning_environment::KinematicModelStateMonitor::isPoseUpdated(double sec) const
00380 {
00381
00382 if(sec < 1e-5)
00383 {
00384 return false;
00385 }
00386
00387
00388 if(last_pose_update_ > ros::TIME_MIN && ros::Time::now() < ros::Time(sec))
00389 {
00390 return true;
00391 }
00392
00393
00394 if (last_pose_update_ < ros::Time::now()-ros::Duration(sec))
00395 {
00396 return false;
00397 }
00398
00399 return true;
00400 }