Skip to content

Commit e6d735d

Browse files
committed
Specifically set RTDE pipeline producer to FIFO scheduling
Regardless of the actual kernel used, setting the producer thread to FIFO scheduling seems to improve robustness.
1 parent 2e69bc1 commit e6d735d

File tree

3 files changed

+25
-54
lines changed

3 files changed

+25
-54
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_library(urcl SHARED
4646
src/rtde/rtde_writer.cpp
4747
src/default_log_handler.cpp
4848
src/log.cpp
49+
src/helpers.cpp
4950
)
5051
add_library(ur_client_library::urcl ALIAS urcl)
5152
target_compile_options(urcl PRIVATE -Wall -Wextra -Wno-unused-parameter)

include/ur_client_library/comm/pipeline.h

Lines changed: 23 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "ur_client_library/comm/package.h"
2424
#include "ur_client_library/log.h"
25+
#include "ur_client_library/helpers.h"
2526
#include "ur_client_library/queue/readerwriterqueue.h"
2627
#include <atomic>
2728
#include <chrono>
@@ -245,8 +246,15 @@ class Pipeline
245246
* \param name The pipeline's name
246247
* \param notifier The notifier to use
247248
*/
248-
Pipeline(IProducer<T>& producer, IConsumer<T>* consumer, std::string name, INotifier& notifier)
249-
: producer_(producer), consumer_(consumer), name_(name), notifier_(notifier), queue_{ 32 }, running_{ false }
249+
Pipeline(IProducer<T>& producer, IConsumer<T>* consumer, std::string name, INotifier& notifier,
250+
const bool producer_fifo_scheduling = false)
251+
: producer_(producer)
252+
, consumer_(consumer)
253+
, name_(name)
254+
, notifier_(notifier)
255+
, queue_{ 32 }
256+
, running_{ false }
257+
, producer_fifo_scheduling_(producer_fifo_scheduling)
250258
{
251259
}
252260
/*!
@@ -257,8 +265,14 @@ class Pipeline
257265
* \param name The pipeline's name
258266
* \param notifier The notifier to use
259267
*/
260-
Pipeline(IProducer<T>& producer, std::string name, INotifier& notifier)
261-
: producer_(producer), consumer_(nullptr), name_(name), notifier_(notifier), queue_{ 32 }, running_{ false }
268+
Pipeline(IProducer<T>& producer, std::string name, INotifier& notifier, const bool producer_fifo_scheduling = false)
269+
: producer_(producer)
270+
, consumer_(nullptr)
271+
, name_(name)
272+
, notifier_(notifier)
273+
, queue_{ 32 }
274+
, running_{ false }
275+
, producer_fifo_scheduling_(producer_fifo_scheduling)
262276
{
263277
}
264278

@@ -349,62 +363,18 @@ class Pipeline
349363
moodycamel::BlockingReaderWriterQueue<std::unique_ptr<T>> queue_;
350364
std::atomic<bool> running_;
351365
std::thread pThread_, cThread_;
366+
bool producer_fifo_scheduling_;
352367

353368
void runProducer()
354369
{
355370
URCL_LOG_DEBUG("Starting up producer");
356-
std::ifstream realtime_file("/sys/kernel/realtime", std::ios::in);
357-
bool has_realtime;
358-
realtime_file >> has_realtime;
359-
if (has_realtime)
371+
if (producer_fifo_scheduling_)
360372
{
373+
pthread_t this_thread = pthread_self();
361374
const int max_thread_priority = sched_get_priority_max(SCHED_FIFO);
362-
if (max_thread_priority != -1)
363-
{
364-
// We'll operate on the currently running thread.
365-
pthread_t this_thread = pthread_self();
366-
367-
// struct sched_param is used to store the scheduling priority
368-
struct sched_param params;
369-
370-
// We'll set the priority to the maximum.
371-
params.sched_priority = max_thread_priority;
372-
373-
int ret = pthread_setschedparam(this_thread, SCHED_FIFO, &params);
374-
if (ret != 0)
375-
{
376-
URCL_LOG_ERROR("Unsuccessful in setting producer thread realtime priority. Error code: %d", ret);
377-
}
378-
// Now verify the change in thread priority
379-
int policy = 0;
380-
ret = pthread_getschedparam(this_thread, &policy, &params);
381-
if (ret != 0)
382-
{
383-
std::cout << "Couldn't retrieve real-time scheduling paramers" << std::endl;
384-
}
385-
386-
// Check the correct policy was applied
387-
if (policy != SCHED_FIFO)
388-
{
389-
URCL_LOG_ERROR("Producer thread: Scheduling is NOT SCHED_FIFO!");
390-
}
391-
else
392-
{
393-
URCL_LOG_INFO("Producer thread: SCHED_FIFO OK");
394-
}
395-
396-
// Print thread scheduling priority
397-
URCL_LOG_INFO("Thread priority is %d", params.sched_priority);
398-
}
399-
else
400-
{
401-
URCL_LOG_ERROR("Could not get maximum thread priority for producer thread");
402-
}
403-
}
404-
else
405-
{
406-
URCL_LOG_WARN("No realtime capabilities found. Consider using a realtime system for better performance");
375+
setFiFoScheduling(this_thread, max_thread_priority);
407376
}
377+
std::ifstream realtime_file("/sys/kernel/realtime", std::ios::in);
408378
std::vector<std::unique_ptr<T>> products;
409379
while (running_)
410380
{

src/rtde/rtde_client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ RTDEClient::RTDEClient(std::string robot_ip, comm::INotifier& notifier, const st
4141
, input_recipe_(readRecipe(input_recipe_file))
4242
, parser_(output_recipe_)
4343
, prod_(stream_, parser_)
44-
, pipeline_(prod_, PIPELINE_NAME, notifier)
44+
, pipeline_(prod_, PIPELINE_NAME, notifier, true)
4545
, writer_(&stream_, input_recipe_)
4646
, max_frequency_(URE_MAX_FREQUENCY)
4747
, target_frequency_(target_frequency)

0 commit comments

Comments
 (0)