Skip to content

Commit fb34bff

Browse files
riv-ljamesriv-tnobleriv-mjohnson
authored
Adds multi (joint) state validation service (#3426)
Co-authored-by: Tom Noble <[email protected]> Co-authored-by: Mark Johnson <[email protected]>
1 parent 4088c0c commit fb34bff

File tree

7 files changed

+129
-27
lines changed

7 files changed

+129
-27
lines changed

moveit_ros/move_group/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ add_library(
5252
src/default_capabilities/query_planners_service_capability.cpp
5353
src/default_capabilities/save_geometry_to_file_service_capability.cpp
5454
src/default_capabilities/state_validation_service_capability.cpp
55+
src/default_capabilities/multi_state_validation_service_capability.cpp
5556
src/default_capabilities/tf_publisher_capability.cpp)
5657
target_include_directories(
5758
moveit_move_group_default_capabilities

moveit_ros/move_group/default_capabilities_plugin_description.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@
4848
</description>
4949
</class>
5050

51+
<class name="move_group/MoveGroupMultiStateValidationService" type="move_group::MoveGroupMultiStateValidationService" base_class_type="move_group::MoveGroupCapability">
52+
<description>
53+
Provide a ROS service that allows for testing multiple joint states validity
54+
</description>
55+
</class>
56+
5157
<class name="move_group/MoveGroupGetPlanningSceneService" type="move_group::MoveGroupGetPlanningSceneService" base_class_type="move_group::MoveGroupCapability">
5258
<description>
5359
Provide a ROS service that allows for querying the planning scene

moveit_ros/move_group/include/moveit/move_group/capability_names.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ static const std::string IK_SERVICE_NAME = "compute_ik"; // name of ik service
5454
static const std::string FK_SERVICE_NAME = "compute_fk"; // name of fk service
5555
static const std::string STATE_VALIDITY_SERVICE_NAME =
5656
"check_state_validity"; // name of the service that validates states
57+
static const std::string MULTI_STATE_VALIDITY_SERVICE_NAME =
58+
"check_multi_state_validity"; // name of the service that validates multiple joint states
5759
static const std::string CARTESIAN_PATH_SERVICE_NAME =
5860
"compute_cartesian_path"; // name of the service that computes cartesian paths
5961
static const std::string GET_PLANNING_SCENE_SERVICE_NAME =
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include "multi_state_validation_service_capability.hpp"
2+
#include <moveit/collision_detection/collision_tools.hpp>
3+
#include <moveit/move_group/capability_names.hpp>
4+
#include <moveit/moveit_cpp/moveit_cpp.hpp>
5+
#include <moveit/robot_state/conversions.hpp>
6+
#include <moveit/utils/message_checks.hpp>
7+
8+
namespace move_group
9+
{
10+
11+
void MoveGroupMultiStateValidationService::initialize()
12+
{
13+
validity_service_ = context_->moveit_cpp_->getNode()->create_service<moveit_msgs::srv::GetMultiStateValidity>(
14+
MULTI_STATE_VALIDITY_SERVICE_NAME,
15+
[this](const std::shared_ptr<rmw_request_id_t>& request_header,
16+
const std::shared_ptr<moveit_msgs::srv::GetMultiStateValidity::Request>& req,
17+
const std::shared_ptr<moveit_msgs::srv::GetMultiStateValidity::Response>& res) {
18+
return computeService(request_header, req, res);
19+
});
20+
}
21+
22+
bool MoveGroupMultiStateValidationService::computeService(
23+
const std::shared_ptr<rmw_request_id_t>& /* unused */,
24+
const std::shared_ptr<moveit_msgs::srv::GetMultiStateValidity::Request>& req,
25+
const std::shared_ptr<moveit_msgs::srv::GetMultiStateValidity::Response>& res)
26+
{
27+
planning_scene_monitor::LockedPlanningSceneRO ls(context_->planning_scene_monitor_);
28+
moveit::core::RobotState rs = ls->getCurrentState();
29+
moveit::core::robotStateMsgToRobotState(req->robot_state, rs);
30+
for (size_t i = 0; i < req->joint_states.size(); ++i)
31+
{
32+
// Update robot state with next set of joint states
33+
rs.setVariableValues(req->joint_states[i]);
34+
35+
// Check validity of given joint state
36+
res->valid = isStateValid(ls, rs, req->group_name, req->constraints, res->contacts, res->cost_sources,
37+
res->constraint_result);
38+
39+
// This service only checks up to the first invalid joint state,
40+
// with the result then holding the information about the first invalid
41+
// state
42+
if (!res->valid)
43+
{
44+
break;
45+
}
46+
}
47+
return true;
48+
}
49+
} // namespace move_group
50+
51+
#include <pluginlib/class_list_macros.hpp>
52+
53+
PLUGINLIB_EXPORT_CLASS(move_group::MoveGroupMultiStateValidationService, move_group::MoveGroupCapability)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include "state_validation_service_capability.hpp"
4+
#include <moveit_msgs/srv/get_multi_state_validity.hpp>
5+
6+
namespace move_group
7+
{
8+
class MoveGroupMultiStateValidationService : public MoveGroupStateValidationService
9+
{
10+
public:
11+
void initialize() override;
12+
13+
private:
14+
bool computeService(const std::shared_ptr<rmw_request_id_t>& request_header,
15+
const std::shared_ptr<moveit_msgs::srv::GetMultiStateValidity::Request>& req,
16+
const std::shared_ptr<moveit_msgs::srv::GetMultiStateValidity::Response>& res);
17+
18+
rclcpp::Service<moveit_msgs::srv::GetMultiStateValidity>::SharedPtr validity_service_;
19+
};
20+
} // namespace move_group

moveit_ros/move_group/src/default_capabilities/state_validation_service_capability.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@
3535
/* Author: Ioan Sucan */
3636

3737
#include "state_validation_service_capability.hpp"
38+
#include <moveit/collision_detection/collision_tools.hpp>
39+
#include <moveit/move_group/capability_names.hpp>
3840
#include <moveit/moveit_cpp/moveit_cpp.hpp>
3941
#include <moveit/robot_state/conversions.hpp>
4042
#include <moveit/utils/message_checks.hpp>
41-
#include <moveit/collision_detection/collision_tools.hpp>
42-
#include <moveit/move_group/capability_names.hpp>
4343

4444
namespace move_group
4545
{
@@ -57,20 +57,18 @@ void MoveGroupStateValidationService::initialize()
5757
});
5858
}
5959

60-
bool MoveGroupStateValidationService::computeService(
61-
const std::shared_ptr<rmw_request_id_t>& /* unused */,
62-
const std::shared_ptr<moveit_msgs::srv::GetStateValidity::Request>& req,
63-
const std::shared_ptr<moveit_msgs::srv::GetStateValidity::Response>& res)
60+
bool MoveGroupStateValidationService::isStateValid(
61+
const planning_scene_monitor::LockedPlanningSceneRO& ls, const moveit::core::RobotState& rs,
62+
const std::string& group_name, const moveit_msgs::msg::Constraints& constraints,
63+
std::vector<moveit_msgs::msg::ContactInformation>& contacts,
64+
std::vector<moveit_msgs::msg::CostSource>& cost_sources,
65+
std::vector<moveit_msgs::msg::ConstraintEvalResult>& constraint_result)
6466
{
65-
planning_scene_monitor::LockedPlanningSceneRO ls(context_->planning_scene_monitor_);
66-
moveit::core::RobotState rs = ls->getCurrentState();
67-
moveit::core::robotStateMsgToRobotState(req->robot_state, rs);
68-
69-
res->valid = true;
67+
bool valid = true;
7068

7169
// configure collision request
7270
collision_detection::CollisionRequest creq;
73-
creq.group_name = req->group_name;
71+
creq.group_name = group_name;
7472
creq.cost = true;
7573
creq.contacts = true;
7674
creq.max_contacts = ls->getWorld()->size() + ls->getRobotModel()->getLinkModelsWithCollisionGeometry().size();
@@ -85,48 +83,63 @@ bool MoveGroupStateValidationService::computeService(
8583
if (cres.collision)
8684
{
8785
rclcpp::Time time_now = context_->moveit_cpp_->getNode()->get_clock()->now();
88-
res->contacts.reserve(cres.contact_count);
89-
res->valid = false;
86+
contacts.reserve(cres.contact_count);
87+
valid = false;
9088
for (collision_detection::CollisionResult::ContactMap::const_iterator it = cres.contacts.begin();
9189
it != cres.contacts.end(); ++it)
9290
{
9391
for (const collision_detection::Contact& contact : it->second)
9492
{
95-
res->contacts.resize(res->contacts.size() + 1);
96-
collision_detection::contactToMsg(contact, res->contacts.back());
97-
res->contacts.back().header.frame_id = ls->getPlanningFrame();
98-
res->contacts.back().header.stamp = time_now;
93+
contacts.resize(contacts.size() + 1);
94+
collision_detection::contactToMsg(contact, contacts.back());
95+
contacts.back().header.frame_id = ls->getPlanningFrame();
96+
contacts.back().header.stamp = time_now;
9997
}
10098
}
10199
}
102100

103101
// copy cost sources
104-
res->cost_sources.reserve(cres.cost_sources.size());
102+
cost_sources.reserve(cres.cost_sources.size());
105103
for (const collision_detection::CostSource& cost_source : cres.cost_sources)
106104
{
107-
res->cost_sources.resize(res->cost_sources.size() + 1);
108-
collision_detection::costSourceToMsg(cost_source, res->cost_sources.back());
105+
cost_sources.resize(cost_sources.size() + 1);
106+
collision_detection::costSourceToMsg(cost_source, cost_sources.back());
109107
}
110108

111109
// evaluate constraints
112-
if (!moveit::core::isEmpty(req->constraints))
110+
if (!moveit::core::isEmpty(constraints))
113111
{
114112
kinematic_constraints::KinematicConstraintSet kset(ls->getRobotModel());
115-
kset.add(req->constraints, ls->getTransforms());
113+
kset.add(constraints, ls->getTransforms());
116114
std::vector<kinematic_constraints::ConstraintEvaluationResult> kres;
117115
kinematic_constraints::ConstraintEvaluationResult total_result = kset.decide(rs, kres);
118116
if (!total_result.satisfied)
119-
res->valid = false;
117+
{
118+
valid = false;
119+
}
120120

121121
// copy constraint results
122-
res->constraint_result.resize(kres.size());
122+
constraint_result.resize(kres.size());
123123
for (std::size_t k = 0; k < kres.size(); ++k)
124124
{
125-
res->constraint_result[k].result = kres[k].satisfied;
126-
res->constraint_result[k].distance = kres[k].distance;
125+
constraint_result[k].result = kres[k].satisfied;
126+
constraint_result[k].distance = kres[k].distance;
127127
}
128128
}
129129

130+
return valid;
131+
}
132+
133+
bool MoveGroupStateValidationService::computeService(
134+
const std::shared_ptr<rmw_request_id_t>& /* unused */,
135+
const std::shared_ptr<moveit_msgs::srv::GetStateValidity::Request>& req,
136+
const std::shared_ptr<moveit_msgs::srv::GetStateValidity::Response>& res)
137+
{
138+
planning_scene_monitor::LockedPlanningSceneRO ls(context_->planning_scene_monitor_);
139+
moveit::core::RobotState rs = ls->getCurrentState();
140+
moveit::core::robotStateMsgToRobotState(req->robot_state, rs);
141+
res->valid =
142+
isStateValid(ls, rs, req->group_name, req->constraints, res->contacts, res->cost_sources, res->constraint_result);
130143
return true;
131144
}
132145
} // namespace move_group

moveit_ros/move_group/src/default_capabilities/state_validation_service_capability.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ class MoveGroupStateValidationService : public MoveGroupCapability
4848

4949
void initialize() override;
5050

51+
protected:
52+
bool isStateValid(const planning_scene_monitor::LockedPlanningSceneRO& ls, const moveit::core::RobotState& rs,
53+
const std::string& group_name, const moveit_msgs::msg::Constraints& constraints,
54+
std::vector<moveit_msgs::msg::ContactInformation>& contacts,
55+
std::vector<moveit_msgs::msg::CostSource>& cost_sources,
56+
std::vector<moveit_msgs::msg::ConstraintEvalResult>& constraint_result);
57+
5158
private:
5259
bool computeService(const std::shared_ptr<rmw_request_id_t>& request_header,
5360
const std::shared_ptr<moveit_msgs::srv::GetStateValidity::Request>& req,

0 commit comments

Comments
 (0)