如何安排实时循环任务



我们是一个本科生团队,目前正在建造一个有腿的机器人。目前,我们与机器人的接口是用python编写的,使用的是我们正在使用的主板上的sdk。

为了与主板sdk进行通信,我们需要每毫秒发送一个命令。

为了允许我们定期发送任务,我们在linux内核中应用了rt preempt补丁。(Ubuntu LTS 20.04,内核5.10.27-rt36(

我们对编写实时应用程序非常陌生,并且遇到了一些问题,我们的任务有时会比指定的时间步长小得多。在下图中,我们绘制了while循环的每个周期的时间,其中命令被发送到sdk。(x轴是以秒为单位的时间,y轴是迭代的经过时间,也以秒为单元(从情节中可以看出,一个步骤比其他步骤小得多。这似乎发生在每次运行脚本的同一时间点。

cyclic_task_plot

我们使用设置整个脚本的优先级

pid = os.getpid()
sched = os.SCHED_FIFO
param = os.sched_param(98)
os.sched_setscheduler(pid, sched, param)

我们的循环任务如下:

dt设置为0.001

while(_running):
if direction:
q = q + 0.0025
if (q > np.pi/2).any():
direction = False
else:
q = q - 0.0025
if (q < -np.pi/2).any():
direction = True
master_board.track_reference(q, q_prime)

#Terminate if duration has passed
if (time.perf_counter() - program_start > duration):
_running = False
cycle_time = time.perf_counter() - cycle_start
time.sleep(dt - cycle_time)
cycle_start = time.perf_counter()
timestep_end = time.perf_counter()
time_per_timestep_array.append(timestep_end - timestep_start)
timestep_start = time.perf_counter()

我们怀疑这个问题与我们定义睡眠量的方式有关。Cycle_time是指上面time.sleep((的计算所花费的时间,因此:睡眠时间+循环时间=1ms。然而,我们不确定如何正确地做到这一点,我们正在努力寻找有关这一主题的资源。

应该如何为实时应用程序正确定义这样的任务?

我们有相当宽松的要求(几毫秒(,但对我们来说,它是确定性的,这一点非常重要,因为这是我们论文的一部分,我们需要了解发生了什么

我们非常感谢您对我们的问题或相关资源的任何回答。

完整代码的链接:https://drive.google.com/drive/folders/12KE0EBaLc2rkTZK2FuX_goMF4MgWtknS?usp=sharing

timestep_end = time.perf_counter()
time_per_timestep_array.append(timestep_end - timestep_start)
timestep_start = time.perf_counter()

您正在记录上一个周期的timestep_start和当前周期的timestep_end之间的时间。这个间隔不能准确地表示循环时间步长(即使我们假设没有发生任务抢占(;它排除了数组追加函数所消耗的时间。由于每次运行脚本时,异常值似乎都发生在同一个确切的时间标记上,因此我们可能怀疑此时数组超过了一定的大小,必须进行昂贵的内存重新分配。不管真正的原因是什么,你都应该通过记录周期开始之间的时间来消除这种时间不准确:

timestep_end = cycle_start
time_per_timestep_array.append(timestep_end - timestep_start)
timestep_start = cycle_start

最新更新