Skip to content

Commit e7d3639

Browse files
Fixed deadlock introduced in 8c3c91d
1 parent f625cee commit e7d3639

File tree

1 file changed

+49
-47
lines changed

1 file changed

+49
-47
lines changed

include/franky/robot.hpp

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -478,57 +478,59 @@ class Robot : public franka::Robot {
478478
if (motion == nullptr) {
479479
throw std::invalid_argument("The motion must not be null.");
480480
}
481-
std::unique_lock lock(*control_mutex_);
482-
if (is_in_control_unsafe() && motion_generator_running_) {
483-
if (!std::holds_alternative<MotionGenerator<ControlSignalType>>(motion_generator_)) {
484-
throw InvalidMotionTypeException("The type of motion cannot change during runtime. Please ensure that the "
485-
"previous motion finished before using a new type of motion.");
481+
{ // Do not remove brace, it is needed to scope the lock
482+
std::unique_lock lock(*control_mutex_);
483+
if (is_in_control_unsafe() && motion_generator_running_) {
484+
if (!std::holds_alternative<MotionGenerator<ControlSignalType>>(motion_generator_)) {
485+
throw InvalidMotionTypeException("The type of motion cannot change during runtime. Please ensure that the "
486+
"previous motion finished before using a new type of motion.");
487+
} else {
488+
std::get<MotionGenerator<ControlSignalType>>(motion_generator_).updateMotion(motion);
489+
}
486490
} else {
487-
std::get<MotionGenerator<ControlSignalType>>(motion_generator_).updateMotion(motion);
488-
}
489-
} else {
490-
joinMotionUnsafe(lock);
491-
492-
motion_generator_.emplace<MotionGenerator<ControlSignalType>>(this, motion);
493-
auto motion_generator = &std::get<MotionGenerator<ControlSignalType>>(motion_generator_);
494-
motion_generator->registerUpdateCallback(
495-
[this](const franka::RobotState &robot_state,
496-
franka::Duration duration,
497-
franka::Duration time) {
498-
std::lock_guard lock(state_mutex_);
499-
current_state_ = robot_state;
500-
});
501-
motion_generator_running_ = true;
502-
control_thread_ = std::thread(
503-
[this, control_func_executor, motion_generator]() {
504-
try {
505-
bool done = false;
506-
while (!done) {
507-
control_func_executor(
508-
[motion_generator](const franka::RobotState &rs, franka::Duration d) {
509-
return (*motion_generator)(rs, d);
510-
});
511-
std::unique_lock lock(*control_mutex_);
512-
513-
// This code is just for the case that a new motion is set just after the old one terminates. If this
514-
// happens, we need to continue with this motion, unless an exception occurs.
515-
done = !motion_generator->has_new_motion();
516-
if (motion_generator->has_new_motion()) {
517-
motion_generator->resetTimeUnsafe();
518-
} else {
519-
done = true;
520-
motion_generator_running_ = false;
521-
control_finished_condition_.notify_all();
491+
joinMotionUnsafe(lock);
492+
493+
motion_generator_.emplace<MotionGenerator<ControlSignalType>>(this, motion);
494+
auto motion_generator = &std::get<MotionGenerator<ControlSignalType>>(motion_generator_);
495+
motion_generator->registerUpdateCallback(
496+
[this](const franka::RobotState &robot_state,
497+
franka::Duration duration,
498+
franka::Duration time) {
499+
std::lock_guard lock(state_mutex_);
500+
current_state_ = robot_state;
501+
});
502+
motion_generator_running_ = true;
503+
control_thread_ = std::thread(
504+
[this, control_func_executor, motion_generator]() {
505+
try {
506+
bool done = false;
507+
while (!done) {
508+
control_func_executor(
509+
[motion_generator](const franka::RobotState &rs, franka::Duration d) {
510+
return (*motion_generator)(rs, d);
511+
});
512+
std::unique_lock lock(*control_mutex_);
513+
514+
// This code is just for the case that a new motion is set just after the old one terminates. If this
515+
// happens, we need to continue with this motion, unless an exception occurs.
516+
done = !motion_generator->has_new_motion();
517+
if (motion_generator->has_new_motion()) {
518+
motion_generator->resetTimeUnsafe();
519+
} else {
520+
done = true;
521+
motion_generator_running_ = false;
522+
control_finished_condition_.notify_all();
523+
}
522524
}
525+
} catch (...) {
526+
std::unique_lock lock(*control_mutex_);
527+
control_exception_ = std::current_exception();
528+
motion_generator_running_ = false;
529+
control_finished_condition_.notify_all();
523530
}
524-
} catch (...) {
525-
std::unique_lock lock(*control_mutex_);
526-
control_exception_ = std::current_exception();
527-
motion_generator_running_ = false;
528-
control_finished_condition_.notify_all();
529531
}
530-
}
531-
);
532+
);
533+
}
532534
}
533535
if (!async)
534536
joinMotion();

0 commit comments

Comments
 (0)