-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New tem2 #2
base: master
Are you sure you want to change the base?
Conversation
5c5233a
to
426d575
Compare
If a vector of trajectories is pushed in continuous mode, the trajectories will be executed in sequential mode only, not simultaneously. Additionally, if one trajectory fails, subsequent trajectories will be aborted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some first comments
@@ -989,6 +1046,12 @@ void TrajectoryExecutionManager::execute(const ExecutionCompleteCallback& callba | |||
void TrajectoryExecutionManager::execute(const ExecutionCompleteCallback& callback, | |||
const PathSegmentCompleteCallback& part_callback, bool auto_clear) | |||
{ | |||
if (allow_continuous_execution_) | |||
{ | |||
ROS_WARN_NAMED(LOGNAME, "Calls to execute() are not allowed when using continuous execution."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe reformulate a bit more positive. "In continous execution mode push()ed trajectories are started automatically. Ignoring call to execute()."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay!
execution_thread_ = std::make_unique<boost::thread>(&TrajectoryExecutionManager::executeThread, this, callback, | ||
part_callback, auto_clear); | ||
execution_thread_ = | ||
std::make_unique<boost::thread>([this](const ExecutionCompleteCallback& c, const PathSegmentCompleteCallback& pc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::make_unique<boost::thread>([this](const ExecutionCompleteCallback& c, const PathSegmentCompleteCallback& pc, | |
std::make_unique<std::thread>([this](const ExecutionCompleteCallback& c, const PathSegmentCompleteCallback& pc, |
this way it fits into one line in github diff view 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will replace boost with standard libraries on all occurrences
trajectories_.clear(); | ||
} | ||
else | ||
ROS_ERROR_NAMED(LOGNAME, "Cannot push a new trajectory while another is being executed"); | ||
} | ||
|
||
void TrajectoryExecutionManager::executeThread( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment explaining which overload is which
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay!
if (jointTrajPointToRobotState(active_trajectory.joint_trajectory, i, start_state)) | ||
{ | ||
robotStateToRobotStateMsg(start_state, start_state_msg); | ||
if (!ps->isPathValid(start_state_msg, new_trajectory, new_trajectory.group_name, true)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to add a todo to add interpolation here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do want to improve that later so I will add it
const moveit_msgs::RobotTrajectory& active_trajectory) | ||
{ | ||
// Before we start checking collisions, ensure that we have the latest robot state received... | ||
planning_scene_monitor_->waitForCurrentRobotState(ros::Time::now()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if new_trajectory and active_trajectory cover all joints we could skip waiting for the updated robot state
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do they cover all joints?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No not generally, but in case they do this could be optimized ... but that's not a high priority
{ | ||
ROS_DEBUG_STREAM_NAMED( | ||
LOGNAME, | ||
"Collision found between trajectory with (group_name, duration): " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Collision found between trajectory with (group_name, duration): " | |
"Collision found between incoming trajectory with (group_name, duration): " |
or similar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay!
return true; | ||
} | ||
|
||
bool TrajectoryExecutionManager::checkCollisionsWithCurrentState(const moveit_msgs::RobotTrajectory& trajectory) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this redundant with the other check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, but if there are no active trajectories then the other check wouldn't happen. But this could be done more efficiently
const TrajectoryExecutionContext& context, std::set<moveit_controller_manager::MoveItControllerHandlePtr>& handles) | ||
{ | ||
// compute the expected duration of the trajectory and find the part of the trajectory that takes longest to execute | ||
ros::Time current_time = ros::Time::now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ros::Time current_time = ros::Time::now(); | |
ros::Time start_time = ros::Time::now(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay!
{ | ||
if (execution_duration_monitoring_) | ||
{ | ||
if (!handle->waitForExecution(expected_trajectory_duration)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't this potentially wait handles.size()*(expected_trajectory_duration - epsilon) if the first handle finishes just in time, the second takes 2 * duration and so on. I know it's contrived but ...
if (!handle->waitForExecution(expected_trajectory_duration)) | |
if (!handle->waitForExecution(expected_trajectory_duration - (ros::Time::now() - current_time)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this actually does not makes much sense to me either. It technically waits for the expected trajectory duration
time for each handle
std::make_unique<boost::thread>([this](const ExecutionCompleteCallback& c, const PathSegmentCompleteCallback& pc, | ||
bool ac) { executeThread(c, pc, ac); }, | ||
callback, part_callback, auto_clear); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::make_unique<boost::thread>([this](const ExecutionCompleteCallback& c, const PathSegmentCompleteCallback& pc, | |
bool ac) { executeThread(c, pc, ac); }, | |
callback, part_callback, auto_clear); | |
std::make_unique<std::thread>([&]() { executeThread(callback, part_callback, auto_clear);}); |
or similar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was necessary to explicitly declare which overloaded method to use. But I think that won't be necessary anymore
} | ||
else | ||
{ | ||
ROS_DEBUG_NAMED(LOGNAME, "Execution stopped before starting"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can end up here with eg the second trajectory of a bundle of 3. Then this message would be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will change it
This does not yet include the "backlog" right? Is that by design or do you intend to add it in this PR as well? I'm starting to understand @v4hn rationale of maybe implementing the "backlog" in higher levels and outside the TEM so it might make sense to finish this PR first? Rejecting trajectories that are temporarily in collision could allow users to change plans and modify trajectories or reorder tasks/goals |
|
||
if (allow_continuous_execution_) | ||
{ | ||
ROS_INFO_NAMED(LOGNAME, "Creating thread"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if the validation should happen here already and basically the push being rejected (return false) if the trajectory cannot currently be executed?
Continuous trajectory execution feature proposal
Each new request
push()
-ed to the trajectory execution manager would spawn a new thread for its execution.The thread would validate and if valid execute the trajectory:
I wanted to overload theexecuteThread
method but I get an error when attempting that.