What is a better approach to have realtime loop and non realtime function at the same time

1.6k views Asked by At

Sorry for the bad title, I really don't know how to describe that in short...

My scenario is that for a robotic application, we need a realtime loop to control the motor every 1ms. While at the same time we may want to do something that does not have realtime requirement such as path planning, image processing, object recognition, etc. Furthermore, some of the result from the non-realtime task would be sent to the realtime motor control loop to control the robot.

For the realtime part, I use Ubuntu with RT-Preempt Patch. Therefore, I can run the realtime control loop in the while loop just like the sample code here.

However, I have no idea for the non-realtime part. In my humble opinion, I would new a thread in the same process and run the non-realtime task in that thread.

Since I'm very new to realtime programming, I don't know what would be the problem for my design. Besides, I wonder if there are any paradigm for designing such kind of program?

---EDIT---

Some more details about my application.

The robot, to be more specific, is a robot arm.

For the realtime part, it calculate the forward kinematics, inverse kinematics, and jacobian. And then calculate the proper output command using a simple PID controller. At last, send the motor command using EtherCAT to each motor.

For the non-realtime part, for example, may take the PointCloud stream from kinect, do some preprocessing, calculate the pose of the object in the scene, determine a good grasp pose for the robot arm, and at last send the goal of each motor to the realtime part so that the robot arm will actually move to the goal and grasp the object. The whole process may take 10 sec or so. However at the same time the realtime loop should keep running and send the proper force command or position command to make the robot arm hold its original pose and stand still.

As for communication between these two parts, for most of the occasion, the command is generated by a novel algorithm from the non-realtime part and send it to the realtime part to make the robot arm move. However, sometimes the algorithm in the non-realtime part will need to know, for example, the current pose of the end effector. Therefore, the none-realtime part will need to get the information from the forward kinematics, which resides in the realtime part.

2

There are 2 answers

3
Basile Starynkevitch On

What is the real-time loop doing exactly? I am guessing (since you mentioned "every 1 millisecond do some motor control") do some very short computations, and output a few bytes to the motor device.

What is the non-realtime part doing? I imagine some user-interface???

What kind of robot?

Path planning may require strong real time, in particular if the robot is moving fast. A cruise missile or a Google Car is not the same as a small robot for the robocup. Losing a few milliseconds of communication may kill humans on a cruise missile or a Google Car, but is acceptable on the Robocup - you'll loose only a game and perhaps harm slightly your robot.

At 40 m/s (144 km/hour, which is slighty above the 130km/h highway road speed limit in France), two milliseconds mean 8 cm, and if that 8 cm is human flesh, it may mean killing someone.

How the two parts are interacting? Is the real-time part sending some information to the other part?

Perhaps the two parts could be some different processes (not threads) with some communication? Perhaps using shared memory with semaphores for synchronization. Then look at sem_overview(7) and shm_overview(7).

Notice that at the interface between the real-time and "non-real time" part the non-real time part might actually becomes "real-time" also.

The main point is to define the conceptual interface between the two (real-time vs non real-time) parts, and decide if you can afford losing some data and some synchronization (communicating between the two parts) or not.

If the role of the non-real time part is simply to display or set the speed (i.e. some low and high threshold) you probably might afford sometimes losing some data or synchronization. But the evil is in the details (if the robot is a real autonomous automobile driving on some highway à la Google Car, you probably should not afford losing some exchanges, and then both parts become real-time!).

10
superdesk On

How you divide your overall system into the real time vs regular parts is very important, as stressed by @Basile Starynkevitch.

When it comes to the implementation in RT-Linux, the parts of your system with real time requirements will be made into real time threads, which run inside of the kernel. This allows them to run unpreempted, but has one giant drawback: there are no protections that one has come to expect in user-space. A real time thread crash means the system has crashed. For this reason (and others) you should limit the real time components as much as possible.

The non-real time components of your system will run as regular Linux processes. They can chug along with whatever expensive planning algorithms you want and the real time threads will preempt them and run as needed. The tricky part is communication, for which there are two mechanisms provided: FIFOs and shared memory.

FIFOs are the easiest, and allow unidirectional communication (use two if you want bidirectional). They are character devices and you don't have to worry about reading / writing overlaps. More from tldp.org.

For passing large amounts of data, shared memory is preferable. With it, two processes map the same section into memory. But you have to coordinate between the processes / threads to ensure that one does not read in middle of another one writing and vice versa. This is actually slightly easier to do when one of the parties is a real-time thread, because you know that the real-time thread will not be preempted. More from drdobbs.com.

You also need to be aware of priority inversion (when a high priority thread must wait for a low priority one to release a shared resource, for example).