Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/SonarSource/sonarc…
Browse files Browse the repository at this point in the history
…loud-github-c-cpp-3
  • Loading branch information
sjahr authored Aug 2, 2024
2 parents dbbe119 + 955f308 commit 509a135
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,24 @@ TYPED_TEST_P(CollisionDetectorPandaTest, RobotWorldCollision_1)
ASSERT_TRUE(res.collision);
res.clear();

pos1.translation().z() = 0.25;
this->cenv_->getWorld()->moveObject("box", pos1);
this->cenv_->checkRobotCollision(req, res, *this->robot_state_, *this->acm_);
ASSERT_FALSE(res.collision);
res.clear();

pos1.translation().z() = 0.05;
this->cenv_->getWorld()->moveObject("box", pos1);
this->cenv_->checkRobotCollision(req, res, *this->robot_state_, *this->acm_);
ASSERT_TRUE(res.collision);
res.clear();

pos1.translation().z() = 0.25;
this->cenv_->getWorld()->moveObject("box", pos1);
this->cenv_->checkRobotCollision(req, res, *this->robot_state_, *this->acm_);
ASSERT_FALSE(res.collision);
res.clear();

this->cenv_->getWorld()->moveObject("box", pos1);
ASSERT_FALSE(res.collision);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ class World
bool moveShapeInObject(const std::string& object_id, const shapes::ShapeConstPtr& shape,
const Eigen::Isometry3d& shape_pose);

/** \brief Update the pose of all shapes in an object. Shape size is verified. Returns true on success. */
bool moveShapesInObject(const std::string& object_id, const EigenSTL::vector_Isometry3d& shape_poses);

/** \brief Move the object pose (thus moving all shapes and subframes in the object)
* according to the given transform specified in world frame.
* The transform is relative to and changes the object pose. It does not replace it.
Expand Down
20 changes: 20 additions & 0 deletions moveit_core/collision_detection/src/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,26 @@ bool World::moveShapeInObject(const std::string& object_id, const shapes::ShapeC
return false;
}

bool World::moveShapesInObject(const std::string& object_id, const EigenSTL::vector_Isometry3d& shape_poses)
{
auto it = objects_.find(object_id);
if (it != objects_.end())
{
if (shape_poses.size() == it->second->shapes_.size())
{
for (std::size_t i = 0; i < shape_poses.size(); ++i)
{
ASSERT_ISOMETRY(shape_poses[i]) // unsanitized input, could contain a non-isometry
it->second->shape_poses_[i] = shape_poses[i];
it->second->global_shape_poses_[i] = it->second->pose_ * shape_poses[i];
}
notify(it->second, MOVE_SHAPE);
return true;
}
}
return false;
}

bool World::moveObject(const std::string& object_id, const Eigen::Isometry3d& transform)
{
const auto it = objects_.find(object_id);
Expand Down
32 changes: 32 additions & 0 deletions moveit_core/collision_detection_fcl/src/collision_env_fcl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,38 @@ void CollisionEnvFCL::notifyObjectChange(const ObjectConstPtr& obj, World::Actio
}
cleanCollisionGeometryCache();
}
else if (action == World::MOVE_SHAPE)
{
auto it = fcl_objs_.find(obj->id_);
if (it == fcl_objs_.end())
{
RCLCPP_ERROR(getLogger(), "Cannot move shapes of unknown FCL object: '%s'", obj->id_.c_str());
return;
}

if (obj->global_shape_poses_.size() != it->second.collision_objects_.size())
{
RCLCPP_ERROR(getLogger(),
"Cannot move shapes, shape size mismatch between FCL object and world object: '%s'. Respectively "
"%zu and %zu.",
obj->id_.c_str(), it->second.collision_objects_.size(), it->second.collision_objects_.size());
return;
}

for (std::size_t i = 0; i < it->second.collision_objects_.size(); ++i)
{
it->second.collision_objects_[i]->setTransform(transform2fcl(obj->global_shape_poses_[i]));

// compute AABB, order matters
it->second.collision_geometry_[i]->collision_geometry_->computeLocalAABB();
it->second.collision_objects_[i]->computeAABB();
}

// update AABB in the FCL broadphase manager tree
// see https://github.com/moveit/moveit/pull/3601 for benchmarks
it->second.unregisterFrom(manager_.get());
it->second.registerTo(manager_.get());
}
else
{
updateFCLObject(obj->id_);
Expand Down
69 changes: 59 additions & 10 deletions moveit_core/planning_scene/src/planning_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,14 @@ void PlanningScene::getPlanningSceneDiffMsg(moveit_msgs::msg::PlanningScene& sce
{
if (it.first == OCTOMAP_NS)
{
do_omap = true;
if (it.second == collision_detection::World::DESTROY)
{
scene_msg.world.octomap.octomap.id = "cleared"; // indicate cleared octomap
}
else
{
do_omap = true;
}
}
else if (it.second == collision_detection::World::DESTROY)
{
Expand Down Expand Up @@ -1260,7 +1267,7 @@ bool PlanningScene::setPlanningSceneDiffMsg(const moveit_msgs::msg::PlanningScen
result &= processCollisionObjectMsg(collision_object);

// if an octomap was specified, replace the one we have with that one
if (!scene_msg.world.octomap.octomap.data.empty())
if (!scene_msg.world.octomap.octomap.id.empty())
processOctomapMsg(scene_msg.world.octomap);

return result;
Expand Down Expand Up @@ -1723,16 +1730,16 @@ bool PlanningScene::shapesAndPosesFromCollisionObjectMessage(const moveit_msgs::
shapes.reserve(num_shapes);
shape_poses.reserve(num_shapes);

utilities::poseMsgToEigen(object.pose, object_pose);

bool switch_object_pose_and_shape_pose = false;
if (num_shapes == 1)
if (num_shapes == 1 && moveit::core::isEmpty(object.pose))
{
if (moveit::core::isEmpty(object.pose))
{
switch_object_pose_and_shape_pose = true; // If the object pose is not set but the shape pose is,
// use the shape's pose as the object pose.
}
// If the object pose is not set but the shape pose is, use the shape's pose as the object pose.
switch_object_pose_and_shape_pose = true;
object_pose.setIdentity();
}
else
{
utilities::poseMsgToEigen(object.pose, object_pose);
}

auto append = [&object_pose, &shapes, &shape_poses,
Expand Down Expand Up @@ -1854,6 +1861,7 @@ bool PlanningScene::processCollisionObjectMove(const moveit_msgs::msg::Collision
{
if (world_->hasObject(object.id))
{
// update object pose
if (!object.primitives.empty() || !object.meshes.empty() || !object.planes.empty())
{
RCLCPP_WARN(getLogger(), "Move operation for object '%s' ignores the geometry specified in the message.",
Expand All @@ -1867,6 +1875,47 @@ bool PlanningScene::processCollisionObjectMove(const moveit_msgs::msg::Collision

const Eigen::Isometry3d object_frame_transform = world_to_object_header_transform * header_to_pose_transform;
world_->setObjectPose(object.id, object_frame_transform);

// update shape poses
if (!object.primitive_poses.empty() || !object.mesh_poses.empty() || !object.plane_poses.empty())
{
auto world_object = world_->getObject(object.id); // object exists, checked earlier

std::size_t shape_size = object.primitive_poses.size() + object.mesh_poses.size() + object.plane_poses.size();
if (shape_size != world_object->shape_poses_.size())
{
RCLCPP_ERROR(getLogger(),
"Move operation for object '%s' must have same number of geometry poses. Cannot move.",
object.id.c_str());
return false;
}

// order matters -> primitive, mesh and plane
EigenSTL::vector_Isometry3d shape_poses;
for (const auto& shape_pose : object.primitive_poses)
{
shape_poses.emplace_back();
utilities::poseMsgToEigen(shape_pose, shape_poses.back());
}
for (const auto& shape_pose : object.mesh_poses)
{
shape_poses.emplace_back();
utilities::poseMsgToEigen(shape_pose, shape_poses.back());
}
for (const auto& shape_pose : object.plane_poses)
{
shape_poses.emplace_back();
utilities::poseMsgToEigen(shape_pose, shape_poses.back());
}

if (!world_->moveShapesInObject(object.id, shape_poses))
{
RCLCPP_ERROR(getLogger(), "Move operation for object '%s' internal world error. Cannot move.",
object.id.c_str());
return false;
}
}

return true;
}

Expand Down
55 changes: 55 additions & 0 deletions moveit_core/planning_scene/test/test_planning_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include <sstream>
#include <string>
#include <tf2_eigen/tf2_eigen.hpp>
#include <octomap_msgs/conversions.h>
#include <octomap/octomap.h>

#include <moveit/collision_detection/collision_common.h>
#include <moveit/collision_detection/collision_plugin_cache.h>
Expand Down Expand Up @@ -89,6 +91,59 @@ TEST(PlanningScene, LoadRestore)
EXPECT_EQ(ps.getRobotModel()->getName(), ps_msg.robot_model_name);
}

TEST(PlanningScene, LoadOctomap)
{
urdf::ModelInterfaceSharedPtr urdf_model = moveit::core::loadModelInterface("pr2");
srdf::ModelSharedPtr srdf_model(new srdf::Model());
planning_scene::PlanningScene ps(urdf_model, srdf_model);

{ // check octomap before doing any operations on it
octomap_msgs::msg::OctomapWithPose msg;
ps.getOctomapMsg(msg);
EXPECT_TRUE(msg.octomap.id.empty());
EXPECT_TRUE(msg.octomap.data.empty());
}

{ // fill PlanningScene's octomap
octomap::OcTree octomap(0.1);
octomap::point3d origin(0, 0, 0);
octomap::point3d end(0, 1, 2);
octomap.insertRay(origin, end);

// populate PlanningScene with octomap
moveit_msgs::msg::PlanningScene msg;
msg.is_diff = true;
octomap_msgs::fullMapToMsg(octomap, msg.world.octomap.octomap);
ps.setPlanningSceneDiffMsg(msg);

// validate octomap message
octomap_msgs::msg::OctomapWithPose octomap_msg;
ps.getOctomapMsg(octomap_msg);
EXPECT_EQ(octomap_msg.octomap.id, "OcTree");
EXPECT_EQ(octomap_msg.octomap.data.size(), msg.world.octomap.octomap.data.size());
}

{ // verify that a PlanningScene msg with an empty octomap id does not modify the octomap
// create planning scene
moveit_msgs::msg::PlanningScene msg;
msg.is_diff = true;
ps.setPlanningSceneDiffMsg(msg);

octomap_msgs::msg::OctomapWithPose octomap_msg;
ps.getOctomapMsg(octomap_msg);
EXPECT_EQ(octomap_msg.octomap.id, "OcTree");
EXPECT_FALSE(octomap_msg.octomap.data.empty());
}

{ // check that a non-empty octomap id, but empty octomap will clear the octomap
moveit_msgs::msg::PlanningScene msg;
msg.is_diff = true;
msg.world.octomap.octomap.id = "xxx";
ps.setPlanningSceneDiffMsg(msg);
EXPECT_FALSE(static_cast<bool>(ps.getWorld()->getObject(planning_scene::PlanningScene::OCTOMAP_NS)));
}
}

TEST(PlanningScene, LoadRestoreDiff)
{
urdf::ModelInterfaceSharedPtr urdf_model = moveit::core::loadModelInterface("pr2");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,17 @@ class RobotTrajectory

void swap(robot_trajectory::RobotTrajectory& other) noexcept;

/**
* \brief Remove a point from the trajectory
* \param index - the index to remove
*/
RobotTrajectory& removeWayPoint(std::size_t index)
{
waypoints_.erase(waypoints_.begin() + index);
duration_from_previous_.erase(duration_from_previous_.begin() + index);
return *this;
}

RobotTrajectory& clear()
{
waypoints_.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

#include <geometry_msgs/msg/pose.hpp>
#include <geometry_msgs/msg/twist.hpp>
#include <geometry_msgs/msg/twist.hpp>

namespace pilz_industrial_motion_planner
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,26 @@ RobotTrajCont CommandListManager::solve(const planning_scene::PlanningSceneConst
// therefore: "i-1".
(i > 0 ? radii.at(i - 1) : 0.));
}
return plan_comp_builder_.build();

const auto res_vec = plan_comp_builder_.build();

// De-duplicate trajectory points with the same time value.
// This is necessary since some controllers do not allow times that are not monotonically increasing.
// TODO: Ideally, we would not need this code if the trajectory segments were created without
// duplicate time points in the first place. Leaving this note to revisit this with a more principled fix.
for (const auto& traj : res_vec)
{
for (size_t i = 0; i < traj->size() - 1; ++i)
{
if (traj->getWayPointDurationFromStart(i) == traj->getWayPointDurationFromStart(i + 1))
{
RCLCPP_WARN(getLogger(), "Removed duplicate point at time=%f", traj->getWayPointDurationFromStart(i));
traj->removeWayPoint(i + 1);
}
}
}

return res_vec;
}

bool CommandListManager::checkRadiiForOverlap(const robot_trajectory::RobotTrajectory& traj_A, const double radii_A,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,19 @@ class MOVEIT_MOVE_GROUP_INTERFACE_EXPORT MoveGroupInterface
If the value is greater than 1, it is set to 1.0. */
void setMaxVelocityScalingFactor(double max_velocity_scaling_factor);

/** \brief Get the max velocity scaling factor set by setMaxVelocityScalingFactor(). */
double getMaxVelocityScalingFactor() const;

/** \brief Set a scaling factor for optionally reducing the maximum joint acceleration.
Allowed values are in (0,1]. The maximum joint acceleration specified
in the robot model is multiplied by the factor. If the value is 0, it is set to
the default value, which is defined in joint_limits.yaml of the moveit_config.
If the value is greater than 1, it is set to 1.0. */
void setMaxAccelerationScalingFactor(double max_acceleration_scaling_factor);

/** \brief Get the max acceleration scaling factor set by setMaxAccelerationScalingFactor(). */
double getMaxAccelerationScalingFactor() const;

/** \brief Get the number of seconds set by setPlanningTime() */
double getPlanningTime() const;

Expand Down Expand Up @@ -796,6 +802,14 @@ class MOVEIT_MOVE_GROUP_INTERFACE_EXPORT MoveGroupInterface
/** \brief How often is the system allowed to move the camera to update environment model when looking */
void setLookAroundAttempts(int32_t attempts);

/** \brief Build a RobotState message for use with plan() or computeCartesianPath()
* If the move_group has a custom set start state, this method will use that as the robot state.
*
* Otherwise, the robot state will be with `is_diff` set to true, causing it to be an offset from the current state
* of the robot at time of the state's use.
*/
void constructRobotState(moveit_msgs::msg::RobotState& state);

/** \brief Build the MotionPlanRequest that would be sent to the move_group action with plan() or move() and store it
in \e request */
void constructMotionPlanRequest(moveit_msgs::msg::MotionPlanRequest& request);
Expand Down
Loading

0 comments on commit 509a135

Please sign in to comment.