我正在尝试使用Nao的红球检测API。我想一步一步做好每件事。我在回调开始时写了callbackMutex。我在if语句的回调中取消订阅事件。
函数可以工作,但有时会出现“INFO:达到线程限制”错误或取消订阅事件错误。
Nao总是看到红球,但创造了许多线程(我认为)。我怎样才能只使用一个线程?
我用c ++写作。
我赞成这样:
memory.subscribeToEvent("redBallDetected", "moduleName", "fuctionName");
然后当Nao看到球时,这个函数叫做。
void moduleName::functionName()
{
ALCriticalSection section(callbackMutex);
//create some proxies and declare some variables
try
{
//do movements
}
catch(const ALError& e) {
qiLogError("module.name") << e.what() << std::endl;
}
}
我使用setWalkTargetVelocity来走动机器人并检查if语句是否走路或停止。我没有使用任何东西来启动或停止一个线程。
答案 0 :(得分:0)
这里的伎俩:
你应该检查你的回调中是否永远不会被卡住, 所以调用异步行走方法是件好事。
步行方法需要时间,你不应该经常调用它:约400毫秒是
到达你的回叫时,不要等待之前的回调完成,只需离开,因为下次会收到更新的信息。我的意思是,过去的信息在收到新信息时没有意义,所以不要被卡住。
答案 1 :(得分:0)
您可以使用qi::Strand对调用进行排队,以便不需要创建额外的线程。结合现代订阅ALMemory事件,它看起来像这样:
qi::Strand strand; // Store the strand anywhere, but keep it alive.
qi::AnyObject redBallSubscriber; // You must also keep alive this object to keep the subscription
redBallSubscriber = memory.subscriber("redBallDetected");
redBallSubscriber.connect("signal", strand.schedulerFor([]
{
// The strand guarantees only one thread will enter this function
// at a time, you don't need to use a mutex here.
try
{
//do movements
}
catch(const std::exception& e) {
qiLogError("module.name") << e.what();
}
}));
注意:如果lambda不起作用,请尝试将其包装在boost :: function中。