[Documentation] [TitleIndex] [WordIndex

Teer Documententation

Teer and ROS

The teer_ros package patches parts of teer to add support for ROS' time and protect condition variables when being accessed from other threads. This is transparent, and to use teer with ros you just have to add teer_ros as a dependency in your manifest and do an import teer_ros in your script.

Concepts

Task (coroutine)

A task in Teer is a coroutine, an instantiation of the continuation concept. In teer tasks are implemented using the yield Python keyword, originally designed for generators, but that works well to implement generic coroutines. Tasks are controlled by the scheduler (see below).

Scheduler

The scheduler is responsible for managing tasks and running them using a round-robin policy. In ROS, the scheduler protects access to tasks using a threading.Condition. This section introduces the methods to create, pause, resume, and kill tasks. In general, helper methods are available for groups of tasks, we let the reader refer to the docstring for these. A task can retrieve a reference to the scheduler by calling yield GetScheduler().

Creating and running a scheduler

Your scheduler should be a subclass of Scheduler and it should hold your condition variables as ConditionVariable (see below). Then, you can run it after initialising your node using the run() method.

Getting task identifiers

The list_all_tids() method returns the list of all task identifiers, while the get_current_tid() method returns the identifier of the current task.

Creating a new task

Tasks are created by the new_task() method that takes the function to execute in the task and returns the task identifier (tid).

Killing a task

Tasks can be killed by the kill_task() method that takes the tid of the task to kill and returns whether the operation was a success.

Pausing a task

Tasks can be paused by the pause_task() method that takes the tid of the task to pause and returns whether the operation was a success.

Resuming a task

Tasks can be resumed by the resume_task() method that takes the tid of the task to resume and returns whether the operation was a success.

Debug print

A debug print that shows the task identifier along with a message is available through the printd() method.

Getting time

The current_time() method returns the current time, with ROS it uses ros' time.

Condition variable

A condition variable looks like a normal variable, excepted that when it is assigned, the scheduler checks tasks that wait on conditions referring to this variable, and if true, schedule these tasks. Condition variables are implemented using Python's descriptor mechanism and a bit of introspection voodoo. Therefore, condition variables must be members of a subclass of Scheduler.

Execution flow

As the coroutine mechanism of teer is a cooperative-multitasking model, a task runs until it passes the hand to another one. A task does this through the yield keyword, followed by the action to perform.

Switch to another task

To simply switch to another task, do:

yield Pass()

Waiting a certain duration

To wait for a certain duration in seconds, do:

yield WaitDuration(duration)

The task will continue after duration seconds, excepted if at that time it is paused, in case it will continue when resumed.

An alternative way to run loops at certain frequencies is to create a Rate object, by calling create_rate() on the scheduler and passing the rate in Hz. Then, a task can wait the remaining duration of the period by doing:

yield Sleep(rate)

Waiting a condition to become true

To wait on a condition, do:

yield WaitCondition(condition_function)

The task will continue when condition_function evaluates to true, excepted if it is paused, in case it will continue when resumed and the condition is true. Note that condition_function will typically be a lambda involving one or more condition variables, for instance:

yield WaitCondition(lambda: sched.variable > value)

where sched is the scheduler and variable a certain condition variable.

Waiting for a task to finish

To wait for a task to finish, do

yield WaitTask(tid)

The task will continue when task tid has finished, excepted if this task is paused, in case it will continue when resumed and tid finished. It is also possible to wait until a group of tasks has finished, either until the have all finished, with WaitAllTasks, or until any has finished, with WaitAnyTasks.


2024-03-23 12:34