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/planning_monitor.h"
00038
00039 #include <boost/scoped_ptr.hpp>
00040
00041 #include "planning_environment/models/model_utils.h"
00042
00043 void planning_environment::PlanningMonitor::loadParams(void)
00044 {
00045 }
00046
00047 bool planning_environment::PlanningMonitor::getCompletePlanningScene(const arm_navigation_msgs::PlanningScene& planning_diff,
00048 const arm_navigation_msgs::OrderedCollisionOperations& ordered_collision_operations,
00049 arm_navigation_msgs::PlanningScene& planning_scene) const{
00050 {
00051
00052
00053 planning_models::KinematicState set_state(getKinematicModel());
00054
00055 setStateValuesFromCurrentValues(set_state);
00056
00057 setRobotStateAndComputeTransforms(planning_diff.robot_state, set_state);
00058
00059
00060 convertKinematicStateToRobotState(set_state,
00061 last_joint_state_update_,
00062 cm_->getWorldFrameId(),
00063 planning_scene.robot_state);
00064 }
00065
00066
00067 getAllFixedFrameTransforms(planning_scene.fixed_frame_transforms);
00068
00069
00070 collision_space::EnvironmentModel::AllowedCollisionMatrix acm = cm_->getCollisionSpace()->getDefaultAllowedCollisionMatrix();
00071 if(planning_diff.allowed_collision_matrix.link_names.size() > 0) {
00072 acm = convertFromACMMsgToACM(planning_diff.allowed_collision_matrix);
00073 }
00074
00075
00076 cm_->getCollisionSpaceCollisionObjects(planning_scene.collision_objects);
00077
00078 for(unsigned int i = 0; i < planning_scene.collision_objects.size(); i++) {
00079 if(!acm.hasEntry(planning_scene.collision_objects[i].id)) {
00080 ROS_ERROR_STREAM("Sanity check failing - no entry in acm for collision space object " << planning_scene.collision_objects[i].id);
00081 }
00082 }
00083
00084 cm_->getLastCollisionMap(planning_scene.collision_map);
00085
00086
00087 if(planning_scene.collision_map.boxes.size() > 0 && !acm.hasEntry(COLLISION_MAP_NAME)) {
00088 ROS_INFO_STREAM("Adding entry for collision map");
00089 acm.addEntry(COLLISION_MAP_NAME, false);
00090 }
00091
00092
00093 cm_->getCollisionSpaceAttachedCollisionObjects(planning_scene.attached_collision_objects);
00094
00095 for(unsigned int i = 0; i < planning_scene.attached_collision_objects.size(); i++) {
00096 if(!acm.hasEntry(planning_scene.attached_collision_objects[i].object.id)) {
00097 ROS_ERROR_STREAM("Sanity check failing - no entry in acm for attached collision space object " << planning_scene.attached_collision_objects[i].object.id);
00098 }
00099 }
00100
00101 std::map<std::string, double> cur_link_padding = cm_->getCollisionSpace()->getCurrentLinkPaddingMap();
00102
00103 for(unsigned int i = 0; i < planning_diff.collision_objects.size(); i++) {
00104 std::string object_name = planning_diff.collision_objects[i].id;
00105 if(object_name == "all") {
00106 if(planning_diff.collision_objects[i].operation.operation == arm_navigation_msgs::CollisionObjectOperation::REMOVE) {
00107 for(unsigned int j = 0; j < planning_scene.collision_objects.size(); i++) {
00108 acm.removeEntry(planning_scene.collision_objects[j].id);
00109 }
00110 planning_scene.collision_objects.clear();
00111 continue;
00112 } else {
00113 ROS_WARN_STREAM("No other operation than remove permitted for all");
00114 return false;
00115 }
00116 }
00117 bool already_have = false;
00118 std::vector<arm_navigation_msgs::CollisionObject>::iterator it = planning_scene.collision_objects.begin();
00119 while(it != planning_scene.collision_objects.end()) {
00120 if((*it).id == object_name) {
00121 already_have = true;
00122 break;
00123 }
00124 it++;
00125 }
00126 if(planning_diff.collision_objects[i].operation.operation == arm_navigation_msgs::CollisionObjectOperation::REMOVE) {
00127 if(!already_have) {
00128 ROS_WARN_STREAM("Diff remove specified for object " << object_name << " which we don't seem to have");
00129 continue;
00130 }
00131 acm.removeEntry(object_name);
00132 planning_scene.collision_objects.erase(it);
00133 } else {
00134
00135 if(already_have) {
00136
00137 planning_scene.collision_objects.erase(it);
00138 } else {
00139 acm.addEntry(object_name, false);
00140 }
00141 planning_scene.collision_objects.push_back(planning_diff.collision_objects[i]);
00142 }
00143 }
00144
00145
00146 for(unsigned int i = 0; i < planning_diff.attached_collision_objects.size(); i++) {
00147 std::string link_name = planning_diff.attached_collision_objects[i].link_name;
00148 std::string object_name = planning_diff.attached_collision_objects[i].object.id;
00149 if(planning_diff.attached_collision_objects[i].object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::DETACH_AND_ADD_AS_OBJECT ||
00150 planning_diff.attached_collision_objects[i].object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::ATTACH_AND_REMOVE_AS_OBJECT) {
00151 ROS_WARN_STREAM("Object replacement not supported during diff");
00152 }
00153 if(link_name == "all") {
00154 if(planning_diff.attached_collision_objects[i].object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::REMOVE) {
00155 for(unsigned int j = 0; j < planning_scene.attached_collision_objects.size(); i++) {
00156 acm.removeEntry(planning_scene.attached_collision_objects[j].object.id);
00157 }
00158 planning_scene.attached_collision_objects.clear();
00159 continue;
00160 } else {
00161 ROS_WARN_STREAM("No other operation than remove permitted for all");
00162 return false;
00163 }
00164 } else {
00165 if(object_name == "all") {
00166 if(planning_diff.attached_collision_objects[i].object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::REMOVE) {
00167 std::vector<arm_navigation_msgs::AttachedCollisionObject>::iterator it = planning_scene.attached_collision_objects.begin();
00168 while(it != planning_scene.attached_collision_objects.end()) {
00169 if((*it).link_name == link_name) {
00170 acm.removeEntry((*it).object.id);
00171 it == planning_scene.attached_collision_objects.erase(it);
00172 } else {
00173 it++;
00174 }
00175 }
00176 } else {
00177 ROS_WARN_STREAM("No other operation than remove permitted for all");
00178 return false;
00179 }
00180 continue;
00181 }
00182 bool already_have = false;
00183 std::vector<arm_navigation_msgs::AttachedCollisionObject>::iterator it = planning_scene.attached_collision_objects.begin();
00184 while(it != planning_scene.attached_collision_objects.end()) {
00185 if((*it).link_name == link_name) {
00186 if((*it).object.id == object_name) {
00187 already_have = true;
00188 break;
00189 }
00190 }
00191 it++;
00192 }
00193 if(planning_diff.attached_collision_objects[i].object.operation.operation == arm_navigation_msgs::CollisionObjectOperation::REMOVE) {
00194 if(!already_have) {
00195 ROS_WARN_STREAM("Diff remove specified for object " << object_name << " which we don't seem to have");
00196 return false;
00197 }
00198 acm.removeEntry((*it).object.id);
00199 planning_scene.attached_collision_objects.erase(it);
00200 } else {
00201
00202 if(already_have) {
00203 planning_scene.attached_collision_objects.erase(it);
00204 } else {
00205 acm.addEntry(planning_diff.attached_collision_objects[i].object.id, false);
00206 }
00207 acm.changeEntry(planning_diff.attached_collision_objects[i].object.id, planning_diff.attached_collision_objects[i].link_name, true);
00208 std::vector<std::string> modded_touch_links;
00209 for(unsigned int j = 0; j < planning_diff.attached_collision_objects[i].touch_links.size(); j++) {
00210 if(cm_->getKinematicModel()->getModelGroup(planning_diff.attached_collision_objects[i].touch_links[j])) {
00211 std::vector<std::string> links = cm_->getKinematicModel()->getModelGroup(planning_diff.attached_collision_objects[i].touch_links[j])->getGroupLinkNames();
00212 modded_touch_links.insert(modded_touch_links.end(), links.begin(), links.end());
00213 } else {
00214 modded_touch_links.push_back(planning_diff.attached_collision_objects[i].touch_links[j]);
00215 }
00216 }
00217 for(unsigned int j = 0; j < modded_touch_links.size(); j++) {
00218 acm.changeEntry(planning_diff.attached_collision_objects[i].object.id, modded_touch_links[j], true);
00219 }
00220 planning_scene.attached_collision_objects.push_back(planning_diff.attached_collision_objects[i]);
00221 }
00222 }
00223 }
00224
00225 for(unsigned int i = 0; i < planning_diff.link_padding.size(); i++) {
00226
00227 cur_link_padding[planning_diff.link_padding[i].link_name] = planning_diff.link_padding[i].padding;
00228 }
00229 convertFromLinkPaddingMapToLinkPaddingVector(cur_link_padding, planning_scene.link_padding);
00230
00231
00232 std::vector<std::string> o_strings;
00233 for(unsigned int i = 0; i < planning_scene.collision_objects.size(); i++) {
00234 o_strings.push_back(planning_scene.collision_objects[i].id);
00235 }
00236
00237 std::vector<std::string> a_strings;
00238 for(unsigned int i = 0; i < planning_scene.attached_collision_objects.size(); i++) {
00239 a_strings.push_back(planning_scene.attached_collision_objects[i].object.id);
00240 }
00241
00242 applyOrderedCollisionOperationsListToACM(ordered_collision_operations,
00243 o_strings,
00244 a_strings,
00245 cm_->getKinematicModel(),
00246 acm);
00247
00248 convertFromACMToACMMsg(acm, planning_scene.allowed_collision_matrix);
00249
00250 planning_scene.allowed_contacts = planning_diff.allowed_contacts;
00251
00252 return true;
00253 }
00254
00255 void planning_environment::PlanningMonitor::getAllFixedFrameTransforms(std::vector<geometry_msgs::TransformStamped>& transform_vec) const
00256 {
00257 transform_vec.clear();
00258
00259 std::vector<std::string> all_frame_names;
00260 tf_->getFrameStrings(all_frame_names);
00261
00262
00263 for(unsigned int i = 0; i < all_frame_names.size(); i++) {
00264 if(!all_frame_names[i].empty() && all_frame_names[i][0] == '/') {
00265 all_frame_names[i].erase(all_frame_names[i].begin());
00266 }
00267 }
00268
00269
00270
00271 for(unsigned int i = 0; i < all_frame_names.size(); i++) {
00272 if(all_frame_names[i] != cm_->getWorldFrameId() &&
00273 !cm_->getKinematicModel()->hasLinkModel(all_frame_names[i])) {
00274 ROS_DEBUG_STREAM("Adding fixed frame transform for frame " << all_frame_names[i]);
00275 geometry_msgs::PoseStamped ident_pose;
00276 ident_pose.header.frame_id = cm_->getWorldFrameId();
00277 ident_pose.pose.orientation.w = 1.0;
00278 std::string err_string;
00279 if (tf_->getLatestCommonTime(cm_->getWorldFrameId(), all_frame_names[i], ident_pose.header.stamp, &err_string) != tf::NO_ERROR) {
00280 ROS_WARN_STREAM("No transform whatsoever available between " << all_frame_names[i] << " and fixed frame" << cm_->getWorldFrameId());
00281 continue;
00282 }
00283 geometry_msgs::PoseStamped trans_pose;
00284 try {
00285 tf_->transformPose(all_frame_names[i], ident_pose, trans_pose);
00286 } catch(tf::TransformException& ex) {
00287
00288
00289
00290 continue;
00291 }
00292 geometry_msgs::TransformStamped f;
00293 f.header = ident_pose.header;
00294 f.child_frame_id = all_frame_names[i];
00295 f.transform.translation.x = trans_pose.pose.position.x;
00296 f.transform.translation.y = trans_pose.pose.position.y;
00297 f.transform.translation.z = trans_pose.pose.position.z;
00298 f.transform.rotation = trans_pose.pose.orientation;
00299 transform_vec.push_back(f);
00300 }
00301 }
00302 }