我试图使用一个用c++编写的基于模板的控制器类来控制一个机器人.本质上,我有一个UDP连接设置与机器人,以接收机器人的状态,并发送新的扭矩命令给机器人。我接收到更高频率的新观测(比如2000 the ),我的控制器大约需要1ms (1000 The)来计算向机器人发送新的扭矩命令。我面临的问题是,我不希望我的主要代码等待发送旧的扭矩命令,而我的控制器仍在计算新的命令发送。据我所知,我可以在realtime内核中使用Ubuntu,多线程代码,以便我的getTorques()方法在一个不同的线程中运行,为进程设置优先级,并使用互斥和锁来避免两个线程之间的数据竞争,但我希望了解为这样一个问题编写硬实时代码的最佳策略是什么。
// main.cpp
#include "CONTROLLER.h"
#include "llapi.h"
void main{
...
CONTROLLERclass obj;
...
double new_observation;
double u;
...
while(communicating){
get_newObs(new_observation); // Get new state of the robot (2000Hz)
obj.getTorques(new_observation, u); // Takes about 1ms to calculate new torques
send_newCommands(u); // Send the new torque commands to the robot
}
...
}提前感谢!
发布于 2022-11-02 06:53:36
好的,首先,在我看来,你需要处理的事实是,你在2 KHz接收到输入,但只能在1 KHz左右计算结果。
基于此,您显然需要丢弃大约一半的输入,或者以某种方式(以对您的应用程序有意义的方式)快速组合自上次处理输入以来到达的输入。
但是,由于代码现在是结构化的,您将获取和处理旧的和旧的输入,所以即使您在1 KHz上产生输出,这些输出仍然是基于旧的和旧的数据。
现在,让我们假设您希望尽可能快地接收输入,当您准备这样做时,您将处理最近收到的输入,根据该输入生成一个输出,然后重复。
在这种情况下,您可能会以这样的一般顺序结束(暂时使用C++线程和原子):
std::atomic<double> new_observation;
std::thread receiver = [&] {
double d;
get_newObs(d);
new_observation = d;
};
std::thread sender = [&] {
auto input = new_observation;
auto u = get_torques(input);
send_newCommands(u);
};我假设您接收输入的速度总是快于您所能使用的速度,因此处理线程总是可以处理等待中的任何输入,而不会收到任何指示输入自上次处理以来已经更新的信息。如果这是错误的,事情会变得更加复杂,但我现在不打算去处理这个问题,因为这听起来似乎是不必要的。
就代码本身而言,唯一可能不明显的事情是,我没有将对new_input的引用传递给任何现有函数,而是将new_input读入线程局部变量中,然后传递对该函数的引用。
https://stackoverflow.com/questions/74284444
复制相似问题