@@ -99,6 +99,7 @@ void TrajectoryExecutionManager::initialize()
99
99
execution_duration_monitoring_ = true ;
100
100
execution_velocity_scaling_ = 1.0 ;
101
101
allowed_start_tolerance_ = 0.01 ;
102
+ allowed_start_tolerance_joints_.clear ();
102
103
wait_for_trajectory_completion_ = true ;
103
104
control_multi_dof_joint_variables_ = DEFAULT_CONTROL_MULTI_DOF_JOINT_VARIABLES;
104
105
@@ -210,6 +211,8 @@ void TrajectoryExecutionManager::initialize()
210
211
controller_mgr_node_->get_parameter (" trajectory_execution.control_multi_dof_joint_variables" ,
211
212
control_multi_dof_joint_variables_);
212
213
214
+ initializeAllowedStartToleranceJoints ();
215
+
213
216
if (manage_controllers_)
214
217
{
215
218
RCLCPP_INFO (logger_, " Trajectory execution is managing controllers" );
@@ -245,6 +248,10 @@ void TrajectoryExecutionManager::initialize()
245
248
{
246
249
setAllowedStartTolerance (parameter.as_double ());
247
250
}
251
+ else if (name.find (" trajectory_execution.allowed_start_tolerance_joints." ) == 0 )
252
+ {
253
+ setAllowedStartToleranceJoint (name, parameter.as_double ());
254
+ }
248
255
else if (name == " trajectory_execution.wait_for_trajectory_completion" )
249
256
{
250
257
setWaitForTrajectoryCompletion (parameter.as_bool ());
@@ -914,10 +921,26 @@ bool TrajectoryExecutionManager::distributeTrajectory(const moveit_msgs::msg::Ro
914
921
915
922
bool TrajectoryExecutionManager::validate (const TrajectoryExecutionContext& context) const
916
923
{
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
918
925
return true ;
919
926
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
+ }
921
944
922
945
moveit::core::RobotStatePtr current_state;
923
946
if (!csm_->waitForCurrentState (node_->now ()) || !(current_state = csm_->getCurrentState ()))
@@ -960,14 +983,15 @@ bool TrajectoryExecutionManager::validate(const TrajectoryExecutionContext& cont
960
983
961
984
for (const auto joint : joints)
962
985
{
986
+ const double joint_start_tolerance = getAllowedStartToleranceJoint (joint->getName ());
963
987
reference_state.enforcePositionBounds (joint);
964
988
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 )
966
990
{
967
991
RCLCPP_ERROR (logger_,
968
992
" Invalid Trajectory: start point deviates from current robot state more than %g at joint '%s'."
969
993
" \n Enable DEBUG for detailed state info." ,
970
- allowed_start_tolerance_ , joint->getName ().c_str ());
994
+ joint_start_tolerance , joint->getName ().c_str ());
971
995
RCLCPP_DEBUG (logger_, " | Joint | Expected | Current |" );
972
996
for (const auto & joint_name : joint_names)
973
997
{
@@ -1012,10 +1036,12 @@ bool TrajectoryExecutionManager::validate(const TrajectoryExecutionContext& cont
1012
1036
Eigen::Vector3d offset = cur_transform.translation () - start_transform.translation ();
1013
1037
Eigen::AngleAxisd rotation;
1014
1038
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))
1016
1042
{
1017
1043
RCLCPP_ERROR_STREAM (logger_, " \n Invalid Trajectory: start point deviates from current robot state more than "
1018
- << allowed_start_tolerance_ << " \n multi-dof joint '" << joint_names[i]
1044
+ << joint_start_tolerance << " \n multi-dof joint '" << joint_names[i]
1019
1045
<< " ': pos delta: " << offset.transpose ()
1020
1046
<< " rot delta: " << rotation.angle ());
1021
1047
return false ;
@@ -1568,7 +1594,7 @@ bool TrajectoryExecutionManager::executePart(std::size_t part_index)
1568
1594
bool TrajectoryExecutionManager::waitForRobotToStop (const TrajectoryExecutionContext& context, double wait_time)
1569
1595
{
1570
1596
// 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_)
1572
1598
{
1573
1599
RCLCPP_INFO (logger_, " Not waiting for trajectory completion" );
1574
1600
return true ;
@@ -1607,8 +1633,9 @@ bool TrajectoryExecutionManager::waitForRobotToStop(const TrajectoryExecutionCon
1607
1633
if (!jm)
1608
1634
continue ; // joint vanished from robot state (shouldn't happen), but we don't care
1609
1635
1636
+ const double joint_start_tolerance = getAllowedStartToleranceJoint (joint_names[i]);
1610
1637
if (fabs (jm->distance (cur_state->getJointPositions (jm), prev_state->getJointPositions (jm))) >
1611
- allowed_start_tolerance_ )
1638
+ joint_start_tolerance )
1612
1639
{
1613
1640
moved = true ;
1614
1641
no_motion_count = 0 ;
@@ -1834,4 +1861,65 @@ void TrajectoryExecutionManager::loadControllerParams()
1834
1861
// }
1835
1862
// }
1836
1863
}
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
+
1837
1925
} // namespace trajectory_execution_manager
0 commit comments