Skip to content

Commit b63718d

Browse files
Merge branch 'main' into fix/collision-monitoring-attached-objects-not-updating
2 parents 99bdd41 + 9922704 commit b63718d

File tree

3 files changed

+154
-10
lines changed

3 files changed

+154
-10
lines changed

moveit_ros/planning/trajectory_execution_manager/include/moveit/trajectory_execution_manager/trajectory_execution_manager.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ class MOVEIT_TRAJECTORY_EXECUTION_MANAGER_EXPORT TrajectoryExecutionManager
292292

293293
void loadControllerParams();
294294

295+
double getAllowedStartToleranceJoint(const std::string& joint_name) const;
296+
void setAllowedStartToleranceJoint(const std::string& joint_name, double joint_start_tolerance);
297+
void initializeAllowedStartToleranceJoints();
298+
295299
// Name of this class for logging
296300
const std::string name_ = "trajectory_execution_manager";
297301

@@ -340,6 +344,8 @@ class MOVEIT_TRAJECTORY_EXECUTION_MANAGER_EXPORT TrajectoryExecutionManager
340344
std::map<std::string, double> controller_allowed_goal_duration_margin_;
341345

342346
double allowed_start_tolerance_; // joint tolerance for validate(): radians for revolute joints
347+
// tolerance per joint, overrides global allowed_start_tolerance_.
348+
std::map<std::string, double> allowed_start_tolerance_joints_;
343349
double execution_velocity_scaling_;
344350
bool wait_for_trajectory_completion_;
345351

moveit_ros/planning/trajectory_execution_manager/src/trajectory_execution_manager.cpp

+96-8
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ void TrajectoryExecutionManager::initialize()
9999
execution_duration_monitoring_ = true;
100100
execution_velocity_scaling_ = 1.0;
101101
allowed_start_tolerance_ = 0.01;
102+
allowed_start_tolerance_joints_.clear();
102103
wait_for_trajectory_completion_ = true;
103104
control_multi_dof_joint_variables_ = DEFAULT_CONTROL_MULTI_DOF_JOINT_VARIABLES;
104105

@@ -210,6 +211,8 @@ void TrajectoryExecutionManager::initialize()
210211
controller_mgr_node_->get_parameter("trajectory_execution.control_multi_dof_joint_variables",
211212
control_multi_dof_joint_variables_);
212213

214+
initializeAllowedStartToleranceJoints();
215+
213216
if (manage_controllers_)
214217
{
215218
RCLCPP_INFO(logger_, "Trajectory execution is managing controllers");
@@ -245,6 +248,10 @@ void TrajectoryExecutionManager::initialize()
245248
{
246249
setAllowedStartTolerance(parameter.as_double());
247250
}
251+
else if (name.find("trajectory_execution.allowed_start_tolerance_joints.") == 0)
252+
{
253+
setAllowedStartToleranceJoint(name, parameter.as_double());
254+
}
248255
else if (name == "trajectory_execution.wait_for_trajectory_completion")
249256
{
250257
setWaitForTrajectoryCompletion(parameter.as_bool());
@@ -914,10 +921,26 @@ bool TrajectoryExecutionManager::distributeTrajectory(const moveit_msgs::msg::Ro
914921

915922
bool TrajectoryExecutionManager::validate(const TrajectoryExecutionContext& context) const
916923
{
917-
if (allowed_start_tolerance_ == 0) // skip validation on this magic number
924+
if (allowed_start_tolerance_ == 0 && allowed_start_tolerance_joints_.empty()) // skip validation on this magic number
918925
return true;
919926

920-
RCLCPP_INFO(logger_, "Validating trajectory with allowed_start_tolerance %g", allowed_start_tolerance_);
927+
if (allowed_start_tolerance_joints_.empty())
928+
{
929+
RCLCPP_INFO_STREAM(logger_, "Validating trajectory with allowed_start_tolerance " << allowed_start_tolerance_);
930+
}
931+
else
932+
{
933+
std::ostringstream ss;
934+
for (const auto& [joint_name, joint_start_tolerance] : allowed_start_tolerance_joints_)
935+
{
936+
if (ss.tellp() > 1)
937+
ss << ", "; // skip the comma at the end
938+
ss << joint_name << ": " << joint_start_tolerance;
939+
}
940+
RCLCPP_INFO_STREAM(logger_, "Validating trajectory with allowed_start_tolerance "
941+
<< allowed_start_tolerance_ << " and allowed_start_tolerance_joints {" << ss.str()
942+
<< "}");
943+
}
921944

922945
moveit::core::RobotStatePtr current_state;
923946
if (!csm_->waitForCurrentState(node_->now()) || !(current_state = csm_->getCurrentState()))
@@ -960,14 +983,15 @@ bool TrajectoryExecutionManager::validate(const TrajectoryExecutionContext& cont
960983

961984
for (const auto joint : joints)
962985
{
986+
const double joint_start_tolerance = getAllowedStartToleranceJoint(joint->getName());
963987
reference_state.enforcePositionBounds(joint);
964988
current_state->enforcePositionBounds(joint);
965-
if (reference_state.distance(*current_state, joint) > allowed_start_tolerance_)
989+
if (joint_start_tolerance != 0 && reference_state.distance(*current_state, joint) > joint_start_tolerance)
966990
{
967991
RCLCPP_ERROR(logger_,
968992
"Invalid Trajectory: start point deviates from current robot state more than %g at joint '%s'."
969993
"\nEnable DEBUG for detailed state info.",
970-
allowed_start_tolerance_, joint->getName().c_str());
994+
joint_start_tolerance, joint->getName().c_str());
971995
RCLCPP_DEBUG(logger_, "| Joint | Expected | Current |");
972996
for (const auto& joint_name : joint_names)
973997
{
@@ -1012,10 +1036,12 @@ bool TrajectoryExecutionManager::validate(const TrajectoryExecutionContext& cont
10121036
Eigen::Vector3d offset = cur_transform.translation() - start_transform.translation();
10131037
Eigen::AngleAxisd rotation;
10141038
rotation.fromRotationMatrix(cur_transform.linear().transpose() * start_transform.linear());
1015-
if ((offset.array() > allowed_start_tolerance_).any() || rotation.angle() > allowed_start_tolerance_)
1039+
const double joint_start_tolerance = getAllowedStartToleranceJoint(joint_names[i]);
1040+
if (joint_start_tolerance != 0 &&
1041+
((offset.array() > joint_start_tolerance).any() || rotation.angle() > joint_start_tolerance))
10161042
{
10171043
RCLCPP_ERROR_STREAM(logger_, "\nInvalid Trajectory: start point deviates from current robot state more than "
1018-
<< allowed_start_tolerance_ << "\nmulti-dof joint '" << joint_names[i]
1044+
<< joint_start_tolerance << "\nmulti-dof joint '" << joint_names[i]
10191045
<< "': pos delta: " << offset.transpose()
10201046
<< " rot delta: " << rotation.angle());
10211047
return false;
@@ -1568,7 +1594,7 @@ bool TrajectoryExecutionManager::executePart(std::size_t part_index)
15681594
bool TrajectoryExecutionManager::waitForRobotToStop(const TrajectoryExecutionContext& context, double wait_time)
15691595
{
15701596
// skip waiting for convergence?
1571-
if (allowed_start_tolerance_ == 0 || !wait_for_trajectory_completion_)
1597+
if ((allowed_start_tolerance_ == 0 && allowed_start_tolerance_joints_.empty()) || !wait_for_trajectory_completion_)
15721598
{
15731599
RCLCPP_INFO(logger_, "Not waiting for trajectory completion");
15741600
return true;
@@ -1607,8 +1633,9 @@ bool TrajectoryExecutionManager::waitForRobotToStop(const TrajectoryExecutionCon
16071633
if (!jm)
16081634
continue; // joint vanished from robot state (shouldn't happen), but we don't care
16091635

1636+
const double joint_start_tolerance = getAllowedStartToleranceJoint(joint_names[i]);
16101637
if (fabs(jm->distance(cur_state->getJointPositions(jm), prev_state->getJointPositions(jm))) >
1611-
allowed_start_tolerance_)
1638+
joint_start_tolerance)
16121639
{
16131640
moved = true;
16141641
no_motion_count = 0;
@@ -1834,4 +1861,65 @@ void TrajectoryExecutionManager::loadControllerParams()
18341861
// }
18351862
// }
18361863
}
1864+
1865+
double TrajectoryExecutionManager::getAllowedStartToleranceJoint(const std::string& joint_name) const
1866+
{
1867+
auto start_tolerance_it = allowed_start_tolerance_joints_.find(joint_name);
1868+
return start_tolerance_it != allowed_start_tolerance_joints_.end() ? start_tolerance_it->second :
1869+
allowed_start_tolerance_;
1870+
}
1871+
1872+
void TrajectoryExecutionManager::setAllowedStartToleranceJoint(const std::string& parameter_name,
1873+
double joint_start_tolerance)
1874+
{
1875+
if (joint_start_tolerance < 0)
1876+
{
1877+
RCLCPP_WARN(logger_, "%s has a negative value. The start tolerance value for that joint was not updated.",
1878+
parameter_name.c_str());
1879+
return;
1880+
}
1881+
1882+
// get the joint name by removing the parameter prefix if necessary
1883+
std::string joint_name = parameter_name;
1884+
const std::string parameter_prefix = "trajectory_execution.allowed_start_tolerance_joints.";
1885+
if (parameter_name.find(parameter_prefix) == 0)
1886+
joint_name = joint_name.substr(parameter_prefix.length()); // remove prefix
1887+
1888+
if (!robot_model_->hasJointModel(joint_name))
1889+
{
1890+
RCLCPP_WARN(logger_,
1891+
"Joint '%s' was not found in the robot model. "
1892+
"The start tolerance value for that joint was not updated.",
1893+
joint_name.c_str());
1894+
return;
1895+
}
1896+
1897+
allowed_start_tolerance_joints_.insert_or_assign(joint_name, joint_start_tolerance);
1898+
}
1899+
1900+
void TrajectoryExecutionManager::initializeAllowedStartToleranceJoints()
1901+
{
1902+
allowed_start_tolerance_joints_.clear();
1903+
1904+
// retrieve all parameters under "trajectory_execution.allowed_start_tolerance_joints"
1905+
// that correspond to existing joints in the robot model
1906+
for (const auto& joint_name : robot_model_->getJointModelNames())
1907+
{
1908+
double joint_start_tolerance;
1909+
const std::string parameter_name = "trajectory_execution.allowed_start_tolerance_joints." + joint_name;
1910+
if (node_->get_parameter(parameter_name, joint_start_tolerance))
1911+
{
1912+
if (joint_start_tolerance < 0)
1913+
{
1914+
RCLCPP_WARN(logger_,
1915+
"%s has a negative value. The start tolerance value for that joint "
1916+
"will default to allowed_start_tolerance.",
1917+
parameter_name.c_str());
1918+
continue;
1919+
}
1920+
allowed_start_tolerance_joints_.insert({ joint_name, joint_start_tolerance });
1921+
}
1922+
}
1923+
}
1924+
18371925
} // namespace trajectory_execution_manager

moveit_ros/planning/trajectory_execution_manager/test/test_execution_manager.cpp

+52-2
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,21 @@ class MoveItCppTest : public ::testing::Test
6060
trajectory_execution_manager_ptr = moveit_cpp_ptr->getTrajectoryExecutionManagerNonConst();
6161

6262
traj1.joint_trajectory.joint_names.push_back("panda_joint1");
63-
traj1.joint_trajectory.points.resize(1);
63+
traj1.joint_trajectory.points.resize(2);
6464
traj1.joint_trajectory.points[0].positions.push_back(0.0);
65+
traj1.joint_trajectory.points[1].positions.push_back(0.5);
66+
traj1.joint_trajectory.points[1].time_from_start.fromSec(0.5);
6567

6668
traj2 = traj1;
6769
traj2.joint_trajectory.joint_names.push_back("panda_joint2");
6870
traj2.joint_trajectory.points[0].positions.push_back(1.0);
71+
traj2.joint_trajectory.points[1].positions.push_back(1.5);
6972
traj2.multi_dof_joint_trajectory.joint_names.push_back("panda_joint3");
70-
traj2.multi_dof_joint_trajectory.points.resize(1);
73+
traj2.multi_dof_joint_trajectory.points.resize(2);
7174
traj2.multi_dof_joint_trajectory.points[0].transforms.resize(1);
75+
traj2.multi_dof_joint_trajectory.points[1].transforms.resize(1);
76+
77+
ros::param::del("~/trajectory_execution/allowed_start_tolerance_joints");
7278
}
7379

7480
protected:
@@ -108,6 +114,50 @@ TEST_F(MoveItCppTest, PushExecuteAndWaitTest)
108114
ASSERT_EQ(last_execution_status, moveit_controller_manager::ExecutionStatus::SUCCEEDED);
109115
}
110116

117+
TEST_F(MoveItCppTest, RejectTooFarFromStart)
118+
{
119+
moveit_msgs::RobotTrajectory traj = traj1;
120+
traj.joint_trajectory.points[0].positions[0] = 0.3;
121+
122+
trajectory_execution_manager_ptr->setAllowedStartTolerance(0.01);
123+
ASSERT_TRUE(trajectory_execution_manager_ptr->push(traj));
124+
auto last_execution_status = trajectory_execution_manager_ptr->executeAndWait();
125+
ASSERT_EQ(last_execution_status, moveit_controller_manager::ExecutionStatus::ABORTED);
126+
}
127+
128+
TEST_F(MoveItCppTest, AcceptAllowedJointStartTolerance)
129+
{
130+
moveit_msgs::RobotTrajectory traj = traj1;
131+
traj.joint_trajectory.points[0].positions[0] = 0.3;
132+
133+
trajectory_execution_manager_ptr->setAllowedStartTolerance(0.01);
134+
ros::param::set("~/trajectory_execution/allowed_start_tolerance_joints/panda_joint1", 0.5);
135+
ASSERT_TRUE(trajectory_execution_manager_ptr->push(traj));
136+
auto last_execution_status = trajectory_execution_manager_ptr->executeAndWait();
137+
ASSERT_EQ(last_execution_status, moveit_controller_manager::ExecutionStatus::SUCCEEDED);
138+
}
139+
140+
TEST_F(MoveItCppTest, DoNotValidateJointStartToleranceZero)
141+
{
142+
moveit_msgs::RobotTrajectory traj = traj1;
143+
traj.joint_trajectory.points[0].positions[0] = 0.3;
144+
145+
trajectory_execution_manager_ptr->setAllowedStartTolerance(0);
146+
ASSERT_TRUE(trajectory_execution_manager_ptr->push(traj));
147+
auto last_execution_status = trajectory_execution_manager_ptr->executeAndWait();
148+
ASSERT_EQ(last_execution_status, moveit_controller_manager::ExecutionStatus::SUCCEEDED);
149+
150+
trajectory_execution_manager_ptr->setAllowedStartTolerance(0.1);
151+
ASSERT_TRUE(trajectory_execution_manager_ptr->push(traj));
152+
last_execution_status = trajectory_execution_manager_ptr->executeAndWait();
153+
ASSERT_EQ(last_execution_status, moveit_controller_manager::ExecutionStatus::ABORTED);
154+
155+
ros::param::set("~/trajectory_execution/allowed_start_tolerance_joints/panda_joint1", 0);
156+
ASSERT_TRUE(trajectory_execution_manager_ptr->push(traj));
157+
last_execution_status = trajectory_execution_manager_ptr->executeAndWait();
158+
ASSERT_EQ(last_execution_status, moveit_controller_manager::ExecutionStatus::SUCCEEDED);
159+
}
160+
111161
} // namespace moveit_cpp
112162

113163
int main(int argc, char** argv)

0 commit comments

Comments
 (0)