Contribute! Which weakness have you detected in RTT?

INTRODUCTION

You can edit this page to post your contribution to OrocosRTT 2.0. Please, keep your comment concise and clear: if you want to launch a long debate, you can still use the Developers Forum! Short examples can help other people understanding what you mean.


A) According to the section 4. of the Orocos Component Builder's Manual, the callback of a synchronous event is executed inside the thread of the event's emitter. Imagine that TaskA emits an event, and TaskB, who subscribes synchronously to it, has an handle with a infinite loop: the behavior of TaskA would be jeopardize. Keep in mind that:
  • TaskA hasn't any clue to know what will happen inside the callback of TaskB.
  • It can't prevent TaskB from connecting synchronously.
  • Once blocked, there is nothing it can do.

B) What would happen if a TaskContext is attached to a PeriodicActivity, but internally it was designed to run as a NonPeriodicActivity. What would happen if a sensor with a refresh rate of 10 Hz is read from a Component deployed at 1000 Hz? May be the Activity of the TC should be defined by the TC itself, even if this would mean to have it is hard-coded in the TC.
C) Because of single thread serialization, we can have that a sleep in 1 Task, affect other tasks which are not aware and are not responsible of it. See the source code in the sub page.

Problems with single thread serialization

Because of single thread serialization, something unexpected for the programmer happens.

1) You expect TaskA to be independent from TaskB, but it isn't. If you think it is a problem of resources of the computer, change the activity frequency of 1 of the two tasks.

Suggestion: A) let the programmer choose if single thread serialization is used or not. B) keep 1 thread for 1 activity policy for default. It will help less experienced user to avoid common errors. Experienced user can decide to "unleash" the power of STS if they want to.

2) after the "block" for 0.5 seconds, the "lost cycles" are executed all at once. In other words, updateHook is called 5 times in a row. This may have very umpredictable results. It could be desirable for some applications (filter with data buffer) or catastrophic in other applications (motion control loop).

Suggestion: C) let the user decide if the "lost cycles" or the PeriodicActivity need to be executed later or are defenitively lost.

using namespace std;
using namespace RTT;
using namespace Orocos;
 
TimeService::ticks _timestamp;
double getTime() { return TimeService::Instance()->getSeconds(_timestamp); }
 
class TaskA
    : public TaskContext
{
protected:
     PeriodicActivity act1;
public:
 
    TaskA(std::string name)
    : TaskContext(name),
      act1(1, 0.10, this->engine() )
    {
     //Start the component's activity:
    this->start();
    }  
    void updateHook()
    {
    printf("TaskA  [%.2f] Loop\n", getTime());
    }
};
 
class TaskB
    : public TaskContext
{
protected:
    int num_cycles;
    PeriodicActivity act2;
public:
     TaskB(std::string name)
    : TaskContext(name),
      act2(2, 0.10, this->engine() )
    {
    num_cycles = 0;            
    //Start the component's activity:
    this->start();
    }   
    void updateHook()
    {
    num_cycles++;
    printf("TaskB  [%.2f] Loop\n", getTime());
 
    // once every 20 cycles (2 seconds), a long calculation is done
    if(num_cycles%20 == 0)
    {
        printf("TaskB  [%.2f] before calling long calculation\n", getTime());
 
        // calculation takes longer than expected (0.5 seconds). 
        // it could be something "unexpected", desired or even a bug... 
        // it would not be relevant for this example.
        for(int i=0; i<500; i++) usleep(1000);
 
        printf("TaskB  [%.2f] after calling long calculation\n", getTime());
    }
    }
};
 
int ORO_main(int argc, char** argv)
{
    TaskA    tA("TaskA");
    TaskB    tB("TaskB");
 
    // notice: the task has not been connected. there isn't any relationship between them.
    // In the mind of the programmer, any of them is independent, because they have their own activity.
 
    // if one of the two frequency of the PeriodicActivities is changed, there isn't any problem, since they go on 2 separate threads.  
    getchar();
    return 0;
}