Skip to content
This repository was archived by the owner on Nov 13, 2017. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions planning_scene/include/moveit/planning_scene/planning_scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class PlanningScene : private boost::noncopyable,
collision_detection::WorldPtr world = collision_detection::WorldPtr(new collision_detection::World()));

static const std::string OCTOMAP_NS;
static const std::string OCTOMAP_MSG_TYPE;
static const std::string OCTOMAP_DIFF_MSG_TYPE;
static const std::string DEFAULT_SCENE_NAME;

~PlanningScene();
Expand Down Expand Up @@ -692,6 +694,8 @@ class PlanningScene : private boost::noncopyable,

void processOctomapMsg(const octomap_msgs::OctomapWithPose &map);
void processOctomapMsg(const octomap_msgs::Octomap &map);
void processOctomapMsg(const octomap_msgs::Octomap &map, const Eigen::Affine3d &t);
void processOctomapMsgDiff(const octomap_msgs::Octomap &map, boost::shared_ptr<octomap::OcTree> octree);
void processOctomapPtr(const boost::shared_ptr<const octomap::OcTree> &octree, const Eigen::Affine3d &t);

/**
Expand Down Expand Up @@ -890,6 +894,7 @@ class PlanningScene : private boost::noncopyable,
void getPlanningSceneMsgCollisionObject(moveit_msgs::PlanningScene &scene, const std::string &ns) const;
void getPlanningSceneMsgCollisionObjects(moveit_msgs::PlanningScene &scene) const;
void getPlanningSceneMsgOctomap(moveit_msgs::PlanningScene &scene) const;
bool getPlanningSceneMsgOctomapDiff(boost::shared_ptr<const octomap::OcTree> octree, octomap_msgs::Octomap &msg) const;
void getPlanningSceneMsgObjectColors(moveit_msgs::PlanningScene &scene_msg) const;

struct CollisionDetector;
Expand Down
159 changes: 124 additions & 35 deletions planning_scene/src/planning_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
namespace planning_scene
{
const std::string PlanningScene::OCTOMAP_NS = "<octomap>";
const std::string PlanningScene::OCTOMAP_MSG_TYPE = "OcTree";
const std::string PlanningScene::OCTOMAP_DIFF_MSG_TYPE = "diff(OcTree)";
const std::string PlanningScene::DEFAULT_SCENE_NAME = "(noname)";

class SceneTransforms : public robot_state::Transforms
Expand Down Expand Up @@ -853,14 +855,63 @@ void planning_scene::PlanningScene::getPlanningSceneMsgOctomap(moveit_msgs::Plan
if (map->shapes_.size() == 1)
{
const shapes::OcTree *o = static_cast<const shapes::OcTree*>(map->shapes_[0].get());
octomap_msgs::fullMapToMsg(*o->octree, scene_msg.world.octomap.octomap);
boost::shared_ptr<const octomap::OcTree> octree = o->octree;
if (scene_msg.is_diff == true && octree->isChangeDetectionEnabled())
{
int expected_size_diff = sizeof(int)+octree->numChangesDetected()*((3*sizeof(unsigned short int))+sizeof(float));
int expected_size_tree = octree->size()*(sizeof(float)+sizeof(char));
if (expected_size_diff > expected_size_tree)
{
logInform("Cheaper to send tree instead of diff by %i bytes with %i changes", expected_size_diff-expected_size_tree, octree->numChangesDetected());
octomap_msgs::fullMapToMsg(*octree, scene_msg.world.octomap.octomap);
}
else
{
getPlanningSceneMsgOctomapDiff(octree, scene_msg.world.octomap.octomap);
}
}
else
octomap_msgs::fullMapToMsg(*octree, scene_msg.world.octomap.octomap);
tf::poseEigenToMsg(map->shape_poses_[0], scene_msg.world.octomap.origin);
}
else
logError("Unexpected number of shapes in octomap collision object. Not including '%s' object", OCTOMAP_NS.c_str());
}
}

bool planning_scene::PlanningScene::getPlanningSceneMsgOctomapDiff(boost::shared_ptr<const octomap::OcTree> octree, octomap_msgs::Octomap &msg) const
{
msg.id = OCTOMAP_DIFF_MSG_TYPE;
msg.resolution = octree->getResolution();
msg.binary = false;
std::stringstream datastream;

int num_changes = octree->numChangesDetected();
datastream.write((const char*) &num_changes, sizeof(int));
//logInform("Octomap diff has %i changes", num_changes);

for (octomap::KeyBoolMap::const_iterator it = octree->changedKeysBegin();
it != octree->changedKeysEnd() && !(!datastream); ++it)
{
octomap::OcTreeKey key = it->first;
for (int j=0; j<3; j++)
{
datastream.write((const char*) &key[j], sizeof(unsigned short int));
}
float value = octree->search(key)->getLogOdds();
datastream.write((const char*) &value, sizeof(int));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be sizeof(float) instead.

}

if (!datastream)
{
logError("Error while writing Octomap diff message");
return false;
}
std::string datastring = datastream.str();
msg.data = std::vector<int8_t>(datastring.begin(), datastring.end());
return true;
}

void planning_scene::PlanningScene::getPlanningSceneMsg(moveit_msgs::PlanningScene &scene_msg) const
{
scene_msg.name = name_;
Expand Down Expand Up @@ -1239,60 +1290,98 @@ void planning_scene::PlanningScene::usePlanningSceneMsg(const moveit_msgs::Plann
setPlanningSceneMsg(scene_msg);
}

void planning_scene::PlanningScene::processOctomapMsg(const octomap_msgs::Octomap &map)
void planning_scene::PlanningScene::removeAllCollisionObjects()
{
// each octomap replaces any previous one
world_->removeObject(OCTOMAP_NS);
const std::vector<std::string> &object_ids = world_->getObjectIds();
for (std::size_t i = 0; i < object_ids.size(); ++i)
if (object_ids[i] != OCTOMAP_NS)
world_->removeObject(object_ids[i]);
}

if (map.data.empty())
return;
void planning_scene::PlanningScene::processOctomapMsg(const octomap_msgs::OctomapWithPose &msg)
{
const Eigen::Affine3d &t = getTransforms().getTransform(msg.header.frame_id);
Eigen::Affine3d p;
tf::poseMsgToEigen(msg.origin, p);
p = t * p;
processOctomapMsg(msg.octomap, p);
}

if (map.id != "OcTree")
void planning_scene::PlanningScene::processOctomapMsg(const octomap_msgs::Octomap &msg)
{
if (!msg.header.frame_id.empty())
{
logError("Received ocomap is of type '%s' but type 'OcTree' is expected.", map.id.c_str());
return;
const Eigen::Affine3d &t = getTransforms().getTransform(msg.header.frame_id);
processOctomapMsg(msg, t);
}
else
{
processOctomapMsg(msg, Eigen::Affine3d::Identity());
}
}

boost::shared_ptr<octomap::OcTree> om(static_cast<octomap::OcTree*>(octomap_msgs::msgToMap(map)));
if (!map.header.frame_id.empty())
void planning_scene::PlanningScene::processOctomapMsg(const octomap_msgs::Octomap &msg, const Eigen::Affine3d &t)
{
if (msg.id.empty())
{
world_->removeObject(OCTOMAP_NS);
}
else if (msg.id == OCTOMAP_DIFF_MSG_TYPE)
{
const Eigen::Affine3d &t = getTransforms().getTransform(map.header.frame_id);
collision_detection::CollisionWorld::ObjectConstPtr map = world_->getObject(OCTOMAP_NS);
if (map && map->shapes_.size() == 1)
{
if (msg.data.empty())
return;
const shapes::OcTree *o = static_cast<const shapes::OcTree*>(map->shapes_[0].get());
boost::shared_ptr<const octomap::OcTree> octree = o->octree;
boost::shared_ptr<octomap::OcTree> nc_octree = boost::const_pointer_cast<octomap::OcTree>(octree);
processOctomapMsgDiff(msg, nc_octree);
processOctomapPtr(octree, t);
}
}
else if (msg.id == OCTOMAP_MSG_TYPE)
{
world_->removeObject(OCTOMAP_NS); // Octomap replaces any previous one
if (msg.data.empty())
return;
boost::shared_ptr<octomap::OcTree> om(static_cast<octomap::OcTree*>(octomap_msgs::msgToMap(msg)));
world_->addToObject(OCTOMAP_NS, shapes::ShapeConstPtr(new shapes::OcTree(om)), t);
}
else
{
world_->addToObject(OCTOMAP_NS, shapes::ShapeConstPtr(new shapes::OcTree(om)), Eigen::Affine3d::Identity());
logError("Received Octomap is of unknown type '%s'", msg.id.c_str());
}
}

void planning_scene::PlanningScene::removeAllCollisionObjects()
void planning_scene::PlanningScene::processOctomapMsgDiff(const octomap_msgs::Octomap &msg, boost::shared_ptr<octomap::OcTree> octree)
{
const std::vector<std::string> &object_ids = world_->getObjectIds();
for (std::size_t i = 0; i < object_ids.size(); ++i)
if (object_ids[i] != OCTOMAP_NS)
world_->removeObject(object_ids[i]);
}

void planning_scene::PlanningScene::processOctomapMsg(const octomap_msgs::OctomapWithPose &map)
{
// each octomap replaces any previous one
world_->removeObject(OCTOMAP_NS);
std::stringstream datastream;
datastream.write((const char*) &msg.data[0], msg.data.size());

if (map.octomap.data.empty())
return;

if (map.octomap.id != "OcTree")
int num_changes;
datastream.read((char*) &num_changes, sizeof(int));
//logInform("Octomap diff has %i changes", num_changes);
int expected_size = sizeof(int)+num_changes*((3*sizeof(unsigned short int))+sizeof(float));
if (expected_size > msg.data.size())
{
logError("Received ocomap is of type '%s' but type 'OcTree' is expected.", map.octomap.id.c_str());
logError("Did not receive enough data for specified diff size: %i bytes expected, %i received", expected_size, msg.data.size());
return;
}

boost::shared_ptr<octomap::OcTree> om(static_cast<octomap::OcTree*>(octomap_msgs::msgToMap(map.octomap)));
const Eigen::Affine3d &t = getTransforms().getTransform(map.header.frame_id);
Eigen::Affine3d p;
tf::poseMsgToEigen(map.origin, p);
p = t * p;
world_->addToObject(OCTOMAP_NS, shapes::ShapeConstPtr(new shapes::OcTree(om)), p);
for (int i=0; i<num_changes && !(!datastream); ++i)
{
octomap::OcTreeKey key;
for (int j=0; j<3; j++)
{
datastream.read((char*) &key[j], sizeof(unsigned short int));
}
float value;
datastream.read((char*) &value, sizeof(float));
octree->setNodeValue(key, value);
}
if (!datastream)
logError("Error while reading Octomap diff message");
}

void planning_scene::PlanningScene::processOctomapPtr(const boost::shared_ptr<const octomap::OcTree> &octree, const Eigen::Affine3d &t)
Expand Down