0

我们是一支由本科生组成的团队,目前致力于打造一个有腿的机器人。目前,我们与机器人的接口是使用我们正在使用的主板上的 sdk 用 python 编写的。

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

为了让我们能够定期发送任务,我们将 rt-preempt 补丁应用于我们的 linux 内核。(Ubuntu LTS 20.04,内核 5.10.27-rt36)

我们对编写实时应用程序非常陌生,并且遇到了一些问题,我们的任务有时会比指定的时间步长小得多。在下图中,我们绘制了命令发送到 sdk 的 while 循环的每个循环的时间。(x 轴是以秒为单位的时间,y 轴是以秒为单位的迭代的经过时间)如图所示,一个步骤比其他步骤小得多。每次我们运行脚本时,这似乎都发生在同一个确切的时间标记上。

循环任务绘图

我们使用以下方法设置整个脚本的优先级:

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

4

1 回答 1

0
    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
于 2021-04-16T17:33:32.640 回答