Skip to content

Commit 174955d

Browse files
committed
Fixed auto reconnection to the RTDE server.
When reconnecting to RTDE it requires you to set the input and output recipes again, this is now done properly.
1 parent 269b377 commit 174955d

File tree

7 files changed

+274
-118
lines changed

7 files changed

+274
-118
lines changed

include/ur_client_library/comm/pipeline.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ class Pipeline
299299
, queue_{ 32 }
300300
, running_{ false }
301301
, producer_fifo_scheduling_(producer_fifo_scheduling)
302+
, threads_stopped_(true)
302303
{
303304
}
304305
/*!
@@ -318,6 +319,7 @@ class Pipeline
318319
, queue_{ 32 }
319320
, running_{ false }
320321
, producer_fifo_scheduling_(producer_fifo_scheduling)
322+
, threads_stopped_(true)
321323
{
322324
}
323325

@@ -354,6 +356,7 @@ class Pipeline
354356
return;
355357

356358
running_ = true;
359+
threads_stopped_ = false;
357360
producer_.startProducer();
358361
pThread_ = std::thread(&Pipeline::runProducer, this);
359362
if (consumer_ != nullptr)
@@ -366,13 +369,13 @@ class Pipeline
366369
*/
367370
void stop()
368371
{
369-
if (!running_)
372+
if (threads_stopped_)
370373
return;
371374

372375
URCL_LOG_DEBUG("Stopping pipeline! <%s>", name_.c_str());
373376

374377
running_ = false;
375-
378+
threads_stopped_ = true;
376379
producer_.stopProducer();
377380
if (pThread_.joinable())
378381
{
@@ -417,6 +420,7 @@ class Pipeline
417420
std::atomic<bool> running_;
418421
std::thread pThread_, cThread_;
419422
bool producer_fifo_scheduling_;
423+
bool threads_stopped_;
420424

421425
void runProducer()
422426
{

include/ur_client_library/comm/producer.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class URProducer : public IProducer<T>
4343
URStream<T>& stream_;
4444
Parser<T>& parser_;
4545
std::chrono::seconds timeout_;
46+
std::function<void()> on_rtde_reconnect_cb_;
4647

4748
bool running_;
4849

@@ -124,9 +125,28 @@ class URProducer : public IProducer<T>
124125
if (!running_)
125126
return true;
126127

128+
if (stream_.getState() == SocketState::Connected)
129+
{
130+
continue;
131+
}
132+
127133
if (stream_.closed())
128134
return false;
129135

136+
if (stream_.getStreamType() == URStreamType::RTDE)
137+
{
138+
if (on_rtde_reconnect_cb_)
139+
{
140+
URCL_LOG_WARN("Failed to read from RTDE stream, invoking on reconnect callback and stopping the producer");
141+
on_rtde_reconnect_cb_();
142+
}
143+
else
144+
{
145+
URCL_LOG_ERROR("Failed to read from RTDE stream without a reconnect handler stopping the producer");
146+
}
147+
return false;
148+
}
149+
130150
URCL_LOG_WARN("Failed to read from stream, reconnecting in %ld seconds...", timeout_.count());
131151
std::this_thread::sleep_for(timeout_);
132152

@@ -140,6 +160,17 @@ class URProducer : public IProducer<T>
140160

141161
return false;
142162
}
163+
164+
/*!
165+
* \brief Sets the RTDE reconnection callback. RTDE requires setting up the communication again upon reconnection
166+
* it is not enough to just reconnect to the stream.
167+
*
168+
* \param on_rtde_reconnect_cb Callback to be invoked when connection is lost to the RTDE stream.
169+
*/
170+
void setRTDEReconnectionCallback(std::function<void()> on_rtde_reconnect_cb)
171+
{
172+
on_rtde_reconnect_cb_ = on_rtde_reconnect_cb;
173+
}
143174
};
144175
} // namespace comm
145176
} // namespace urcl

include/ur_client_library/comm/stream.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ namespace urcl
3030
{
3131
namespace comm
3232
{
33+
34+
/*!
35+
* \brief Different types of UR streams
36+
*/
37+
enum class URStreamType
38+
{
39+
Primary = 30001, ///< Stream connected to the primary interface
40+
Secondary = 30002, ///< Stream connected to the secondary interface
41+
RTDE = 30004, ///< Stream connected to the RTDE interface
42+
UNKNOWN = -1, ///< Stream type is fetched from the port, this is to handle unknown ports
43+
};
44+
3345
/*!
3446
* \brief The stream is an abstraction of the TCPSocket that offers reading a full UR data package
3547
* out of the socket. This means, it has to have some knowledge about the package structure to
@@ -117,6 +129,26 @@ class URStream : public TCPSocket
117129
return host_;
118130
}
119131

132+
/*!
133+
* \brief Get the stream type
134+
*
135+
* \returns The stream type
136+
*/
137+
URStreamType getStreamType()
138+
{
139+
switch (port_)
140+
{
141+
case static_cast<int>(URStreamType::Primary):
142+
return URStreamType::Primary;
143+
case static_cast<int>(URStreamType::Secondary):
144+
return URStreamType::Secondary;
145+
case static_cast<int>(URStreamType::RTDE):
146+
return URStreamType::RTDE;
147+
default:
148+
return URStreamType::UNKNOWN;
149+
}
150+
}
151+
120152
private:
121153
std::string host_;
122154
int port_;

include/ur_client_library/rtde/rtde_client.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ class RTDEClient
231231
comm::INotifier notifier_;
232232
std::unique_ptr<comm::Pipeline<RTDEPackage>> pipeline_;
233233
RTDEWriter writer_;
234+
bool reconnecting_;
235+
std::mutex reconnect_mutex_;
236+
std::thread reconnecting_thread_;
234237

235238
VersionInformation urcontrol_version_;
236239

@@ -249,12 +252,13 @@ class RTDEClient
249252
// the robot is booted.
250253
std::vector<std::string> ensureTimestampIsPresent(const std::vector<std::string>& output_recipe) const;
251254

252-
void setupCommunication(const size_t max_num_tries = 0,
253-
const std::chrono::milliseconds reconnection_time = std::chrono::seconds(10));
255+
bool setupCommunication();
256+
uint16_t setProtocolVersion();
254257
bool negotiateProtocolVersion(const uint16_t protocol_version);
255-
void queryURControlVersion();
256-
void setupOutputs(const uint16_t protocol_version);
257-
void setupInputs();
258+
bool queryURControlVersion();
259+
bool setTargetFrequency();
260+
bool setupOutputs(const uint16_t protocol_version);
261+
bool setupInputs();
258262
void disconnect();
259263

260264
/*!
@@ -288,6 +292,12 @@ class RTDEClient
288292
* \returns A vector of variable variable_names
289293
*/
290294
std::vector<std::string> splitVariableTypes(const std::string& variable_types) const;
295+
296+
/*!
297+
* \brief Reconnects to the RTDE interface and set the input and output recipes again.
298+
*/
299+
void reconnect();
300+
void reconnectCallback();
291301
};
292302

293303
} // namespace rtde_interface

include/ur_client_library/rtde/rtde_writer.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ class RTDEWriter
6161

6262
~RTDEWriter()
6363
{
64-
running_ = false;
65-
if (writer_thread_.joinable())
66-
{
67-
writer_thread_.join();
68-
}
64+
stop();
6965
}
7066
/*!
7167
* \brief Starts the writer thread, which periodically clears the queue to write packages to the
@@ -79,6 +75,11 @@ class RTDEWriter
7975
*/
8076
void run();
8177

78+
/*!
79+
* \brief Stops the writer thread loop.
80+
*/
81+
void stop();
82+
8283
/*!
8384
* \brief Creates a package to request setting a new value for the speed slider.
8485
*

0 commit comments

Comments
 (0)