Skip to content

Commit 7967284

Browse files
authored
Add possibility to register multiple callbacks to ReverseInterface and TrajectoryPointInterface (#359)
1 parent 1b0be72 commit 7967284

10 files changed

+309
-31
lines changed

include/ur_client_library/control/reverse_interface.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <cstring>
3939
#include <endian.h>
4040
#include <condition_variable>
41+
#include <list>
4142

4243
namespace urcl
4344
{
@@ -156,9 +157,31 @@ class ReverseInterface
156157
"commands.")]] virtual void
157158
setKeepaliveCount(const uint32_t count);
158159

159-
void registerDisconnectionCallback(std::function<void(const int)> disconnection_fun)
160+
/*!
161+
* \brief Register a callback for the robot-based disconnection.
162+
*
163+
* The callback will be called when the robot disconnects from the reverse interface.
164+
*
165+
* \param disconnection_fun The function to be called on disconnection.
166+
*
167+
* \returns A unique handler ID for the registered callback. This can be used to unregister the
168+
* callback later.
169+
*/
170+
uint32_t registerDisconnectionCallback(std::function<void(const int)> disconnection_fun)
171+
{
172+
disconnect_callbacks_.push_back({ next_disconnect_callback_id_, disconnection_fun });
173+
return next_disconnect_callback_id_++;
174+
}
175+
176+
/*! \brief Unregisters a disconnection callback.
177+
*
178+
* \param handler_id The ID of the handler to be unregistered as obtained from
179+
* registerDisconnectionCallback.
180+
*/
181+
void unregisterDisconnectionCallback(const uint32_t handler_id)
160182
{
161-
disconnection_callback_ = disconnection_fun;
183+
disconnect_callbacks_.remove_if(
184+
[handler_id](const HandlerFunction<void(const int)>& h) { return h.id == handler_id; });
162185
}
163186

164187
/*!
@@ -178,7 +201,8 @@ class ReverseInterface
178201

179202
virtual void messageCallback(const socket_t filedescriptor, char* buffer, int nbytesrecv);
180203

181-
std::function<void(const int)> disconnection_callback_ = nullptr;
204+
std::list<HandlerFunction<void(const int)>> disconnect_callbacks_;
205+
uint32_t next_disconnect_callback_id_ = 0;
182206
socket_t client_fd_;
183207
comm::TCPServer server_;
184208

include/ur_client_library/control/trajectory_point_interface.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#ifndef UR_CLIENT_LIBRARY_TRAJECTORY_INTERFACE_H_INCLUDED
3030
#define UR_CLIENT_LIBRARY_TRAJECTORY_INTERFACE_H_INCLUDED
3131

32+
#include <list>
3233
#include <optional>
3334

3435
#include "ur_client_library/control/motion_primitives.h"
@@ -133,10 +134,11 @@ class TrajectoryPointInterface : public ReverseInterface
133134
*/
134135
bool writeMotionPrimitive(const std::shared_ptr<control::MotionPrimitive> primitive);
135136

136-
void setTrajectoryEndCallback(std::function<void(TrajectoryResult)> callback)
137-
{
138-
handle_trajectory_end_ = callback;
139-
}
137+
void setTrajectoryEndCallback(std::function<void(TrajectoryResult)> callback);
138+
139+
uint32_t addTrajectoryEndCallback(const std::function<void(TrajectoryResult)>& callback);
140+
141+
void removeTrajectoryEndCallback(const uint32_t callback_id);
140142

141143
protected:
142144
virtual void connectionCallback(const socket_t filedescriptor) override;
@@ -146,7 +148,8 @@ class TrajectoryPointInterface : public ReverseInterface
146148
virtual void messageCallback(const socket_t filedescriptor, char* buffer, int nbytesrecv) override;
147149

148150
private:
149-
std::function<void(TrajectoryResult)> handle_trajectory_end_;
151+
std::list<HandlerFunction<void(TrajectoryResult)>> trajectory_end_callbacks_;
152+
uint32_t next_done_callback_id_ = 0;
150153
};
151154

152155
} // namespace control

include/ur_client_library/types.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222

2323
#include <inttypes.h>
2424
#include <array>
25+
#include <functional>
2526
#include <iostream>
27+
#include "ur_client_library/log.h"
2628

2729
namespace urcl
2830
{
@@ -81,4 +83,20 @@ constexpr typename std::underlying_type<E>::type toUnderlying(const E e) noexcep
8183
{
8284
return static_cast<typename std::underlying_type<E>::type>(e);
8385
}
84-
} // namespace urcl
86+
87+
template <typename FunctionT>
88+
struct HandlerFunction
89+
{
90+
uint32_t id;
91+
std::function<FunctionT> function;
92+
93+
HandlerFunction(uint32_t id, std::function<FunctionT> function) : id(id), function(function)
94+
{
95+
}
96+
97+
bool operator==(const HandlerFunction& other) const
98+
{
99+
return id == other.id;
100+
}
101+
};
102+
} // namespace urcl

include/ur_client_library/ur/instruction_executor.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ class InstructionExecutor
4242
InstructionExecutor() = delete;
4343
InstructionExecutor(std::shared_ptr<urcl::UrDriver> driver) : driver_(driver)
4444
{
45-
driver_->registerTrajectoryDoneCallback(
45+
traj_done_callback_handler_id_ = driver_->registerTrajectoryDoneCallback(
4646
std::bind(&InstructionExecutor::trajDoneCallback, this, std::placeholders::_1));
47-
driver_->registerTrajectoryInterfaceDisconnectedCallback(
47+
disconnected_handler_id_ = driver_->registerTrajectoryInterfaceDisconnectedCallback(
4848
std::bind(&InstructionExecutor::trajDisconnectCallback, this, std::placeholders::_1));
4949
}
5050

5151
~InstructionExecutor()
5252
{
53-
driver_->registerTrajectoryDoneCallback(nullptr);
54-
driver_->registerTrajectoryInterfaceDisconnectedCallback(nullptr);
53+
driver_->unregisterTrajectoryDoneCallback(traj_done_callback_handler_id_);
54+
driver_->unregisterTrajectoryInterfaceDisconnectedCallback(disconnected_handler_id_);
5555
}
5656

5757
/**
@@ -187,10 +187,13 @@ class InstructionExecutor
187187
return trajectory_running_;
188188
}
189189

190-
private:
190+
protected:
191191
void trajDoneCallback(const urcl::control::TrajectoryResult& result);
192192
void trajDisconnectCallback(const int filedescriptor);
193193

194+
uint32_t traj_done_callback_handler_id_;
195+
uint32_t disconnected_handler_id_;
196+
194197
std::shared_ptr<urcl::UrDriver> driver_;
195198
std::atomic<bool> trajectory_running_ = false;
196199
std::atomic<bool> cancel_requested_ = false;

include/ur_client_library/ur/ur_driver.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -823,10 +823,17 @@ class UrDriver
823823
*
824824
* \param trajectory_done_cb Callback function that will be triggered in the event of finishing
825825
* a trajectory execution
826+
*
827+
* \returns The ID of the callback that can be used to unregister the callback later.
826828
*/
827-
void registerTrajectoryDoneCallback(std::function<void(control::TrajectoryResult)> trajectory_done_cb)
829+
uint32_t registerTrajectoryDoneCallback(std::function<void(control::TrajectoryResult)> trajectory_done_cb)
830+
{
831+
return trajectory_interface_->addTrajectoryEndCallback(trajectory_done_cb);
832+
}
833+
834+
void unregisterTrajectoryDoneCallback(const uint32_t handler_id)
828835
{
829-
trajectory_interface_->setTrajectoryEndCallback(trajectory_done_cb);
836+
trajectory_interface_->removeTrajectoryEndCallback(handler_id);
830837
}
831838

832839
/*!
@@ -887,9 +894,32 @@ class UrDriver
887894
primary_client_->stop();
888895
}
889896

890-
void registerTrajectoryInterfaceDisconnectedCallback(std::function<void(const int)> fun)
897+
/*!
898+
* \brief Register a callback for the trajectory interface disconnection.
899+
*
900+
* This callback will be called when the trajectory interface is disconnected.
901+
*
902+
* \param fun Callback function that will be triggered in the event of disconnection
903+
*
904+
* \returns The ID of the callback that can be used to unregister the callback later.
905+
*/
906+
uint32_t registerTrajectoryInterfaceDisconnectedCallback(std::function<void(const int)> fun)
907+
{
908+
return trajectory_interface_->registerDisconnectionCallback(fun);
909+
}
910+
911+
/*!
912+
* \brief Unregister a callback for the trajectory interface disconnection.
913+
*
914+
* This will remove the callback that was registered with
915+
* registerTrajectoryInterfaceDisconnectedCallback.
916+
*
917+
* \param handler_id The ID of the callback to be removed as obtained from
918+
* registerTrajectoryInterfaceDisconnectedCallback.
919+
*/
920+
void unregisterTrajectoryInterfaceDisconnectedCallback(const uint32_t handler_id)
891921
{
892-
trajectory_interface_->registerDisconnectionCallback(fun);
922+
trajectory_interface_->unregisterDisconnectionCallback(handler_id);
893923
}
894924

895925
/*!

src/control/reverse_interface.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ void ReverseInterface::disconnectionCallback(const socket_t filedescriptor)
238238
URCL_LOG_INFO("Connection to reverse interface dropped.", filedescriptor);
239239
client_fd_ = INVALID_SOCKET;
240240
handle_program_state_(false);
241+
for (auto handler : disconnect_callbacks_)
242+
{
243+
handler.function(filedescriptor);
244+
}
241245
}
242246

243247
void ReverseInterface::messageCallback(const socket_t filedescriptor, char* buffer, int nbytesrecv)

src/control/trajectory_point_interface.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ void TrajectoryPointInterface::connectionCallback(const socket_t filedescriptor)
274274
void TrajectoryPointInterface::disconnectionCallback(const socket_t filedescriptor)
275275
{
276276
URCL_LOG_DEBUG("Connection to trajectory interface dropped.");
277-
if (disconnection_callback_ != nullptr)
277+
for (auto handler : disconnect_callbacks_)
278278
{
279-
disconnection_callback_(filedescriptor);
279+
handler.function(filedescriptor);
280280
}
281281
client_fd_ = INVALID_SOCKET;
282282
}
@@ -288,9 +288,12 @@ void TrajectoryPointInterface::messageCallback(const socket_t filedescriptor, ch
288288
int32_t* status = reinterpret_cast<int*>(buffer);
289289
URCL_LOG_DEBUG("Received message %d on TrajectoryPointInterface", be32toh(*status));
290290

291-
if (handle_trajectory_end_)
291+
if (!trajectory_end_callbacks_.empty())
292292
{
293-
handle_trajectory_end_(static_cast<TrajectoryResult>(be32toh(*status)));
293+
for (auto handler : trajectory_end_callbacks_)
294+
{
295+
handler.function(static_cast<TrajectoryResult>(be32toh(*status)));
296+
}
294297
}
295298
else
296299
{
@@ -303,5 +306,23 @@ void TrajectoryPointInterface::messageCallback(const socket_t filedescriptor, ch
303306
nbytesrecv);
304307
}
305308
}
309+
310+
void TrajectoryPointInterface::setTrajectoryEndCallback(std::function<void(TrajectoryResult)> callback)
311+
{
312+
addTrajectoryEndCallback(callback);
313+
}
314+
315+
uint32_t TrajectoryPointInterface::addTrajectoryEndCallback(const std::function<void(TrajectoryResult)>& callback)
316+
{
317+
trajectory_end_callbacks_.push_back({ next_done_callback_id_, callback });
318+
return next_done_callback_id_++;
319+
}
320+
321+
void TrajectoryPointInterface::removeTrajectoryEndCallback(const uint32_t handler_id)
322+
{
323+
trajectory_end_callbacks_.remove_if(
324+
[handler_id](const HandlerFunction<void(TrajectoryResult)>& h) { return h.id == handler_id; });
325+
}
326+
306327
} // namespace control
307328
} // namespace urcl

src/ur/instruction_executor.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@
3636
void urcl::InstructionExecutor::trajDoneCallback(const urcl::control::TrajectoryResult& result)
3737
{
3838
URCL_LOG_DEBUG("Trajectory result received: %s", control::trajectoryResultToString(result).c_str());
39-
std::unique_lock<std::mutex> lock(trajectory_result_mutex_);
40-
trajectory_done_cv_.notify_all();
41-
trajectory_result_ = result;
42-
trajectory_running_ = false;
39+
if (trajectory_running_)
40+
{
41+
std::unique_lock<std::mutex> lock(trajectory_result_mutex_);
42+
trajectory_done_cv_.notify_all();
43+
trajectory_result_ = result;
44+
trajectory_running_ = false;
45+
}
4346
}
4447
void urcl::InstructionExecutor::trajDisconnectCallback(const int filedescriptor)
4548
{

0 commit comments

Comments
 (0)