Skip to content

Commit 38e48c3

Browse files
author
Tim Schneider
committed
Fixed broken Robot::joinMotion function
1 parent 45f5d76 commit 38e48c3

File tree

2 files changed

+26
-29
lines changed

2 files changed

+26
-29
lines changed

include/franky/robot.hpp

+12-16
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,16 @@ class Robot : public franka::Robot {
183183
franka::RobotState current_state_;
184184
std::mutex state_mutex_;
185185
std::mutex control_mutex_;
186-
std::optional<std::shared_future<std::exception_ptr>> control_future_;
186+
std::condition_variable control_finished_condition_;
187+
std::exception_ptr control_exception_;
188+
std::thread control_thread_;
187189
MotionGeneratorVariant motion_generator_{std::nullopt};
188190
bool motion_generator_running_{false};
189191

190192
[[nodiscard]] bool is_in_control_unsafe() const;
191193

194+
void joinMotionUnsafe(std::unique_lock<std::mutex> &lock);
195+
192196
template<typename ControlSignalType>
193197
void moveInternal(
194198
const std::shared_ptr<Motion<ControlSignalType>> &motion,
@@ -204,13 +208,7 @@ class Robot : public franka::Robot {
204208
std::get<MotionGenerator<ControlSignalType>>(motion_generator_).updateMotion(motion);
205209
}
206210
} else {
207-
if (control_future_.has_value()) {
208-
control_future_->wait();
209-
auto control_exception = control_future_->get();
210-
if (control_exception != nullptr)
211-
std::rethrow_exception(control_exception);
212-
control_future_ = std::nullopt;
213-
}
211+
joinMotionUnsafe(lock);
214212

215213
motion_generator_.emplace<MotionGenerator<ControlSignalType>>(this, motion);
216214
auto motion_generator = &std::get<MotionGenerator<ControlSignalType>>(motion_generator_);
@@ -220,8 +218,7 @@ class Robot : public franka::Robot {
220218
current_state_ = robot_state;
221219
});
222220
motion_generator_running_ = true;
223-
control_future_ = std::async(
224-
std::launch::async,
221+
control_thread_ = std::thread(
225222
[this, control_func_executor, motion_generator]() {
226223
try {
227224
bool done = false;
@@ -240,16 +237,15 @@ class Robot : public franka::Robot {
240237
} else {
241238
done = true;
242239
motion_generator_running_ = false;
240+
control_finished_condition_.notify_all();
243241
}
244242
}
245243
} catch (...) {
246-
{
247-
std::unique_lock<std::mutex> lock(control_mutex_);
248-
motion_generator_running_ = false;
249-
}
250-
return std::current_exception();
244+
std::unique_lock<std::mutex> lock(control_mutex_);
245+
control_exception_ = std::current_exception();
246+
motion_generator_running_ = false;
247+
control_finished_condition_.notify_all();
251248
}
252-
return std::exception_ptr{nullptr};
253249
}
254250
);
255251
}

src/robot.cpp

+14-13
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ void Robot::setCollisionBehavior(
110110
}
111111

112112
bool Robot::is_in_control_unsafe() const {
113-
return control_future_.has_value()
114-
&& control_future_->wait_for(std::chrono::seconds(0)) != std::future_status::ready;
113+
return motion_generator_running_;
115114
}
116115

117116
bool Robot::is_in_control() {
@@ -124,18 +123,20 @@ std::string Robot::fci_hostname() const {
124123
}
125124

126125
void Robot::joinMotion() {
127-
// This is to ensure the control thread safety of this operation. Otherwise, it is possible that the control_thread
128-
// pointer gets overwritten at the exact moment we try to join the control_thread.
129-
std::optional<std::shared_future<std::exception_ptr>> control_future;
130-
{
131-
std::unique_lock<std::mutex> lock(control_mutex_);
132-
control_future = control_future_;
133-
}
134-
if (control_future.has_value())
135-
control_future->wait();
136-
auto control_exception = control_future->get();
137-
if (control_exception != nullptr)
126+
std::unique_lock<std::mutex> lock(control_mutex_);
127+
joinMotionUnsafe(lock);
128+
}
129+
130+
void Robot::joinMotionUnsafe(std::unique_lock<std::mutex> &lock) {
131+
if (motion_generator_running_)
132+
control_finished_condition_.wait(lock);
133+
if (control_thread_.joinable())
134+
control_thread_.join();
135+
if (control_exception_ != nullptr) {
136+
auto control_exception = control_exception_;
137+
control_exception_ = nullptr;
138138
std::rethrow_exception(control_exception);
139+
}
139140
}
140141

141142
std::optional<ControlSignalType> Robot::current_control_signal_type() {

0 commit comments

Comments
 (0)