0

我正在尝试使用 Nao 的红球检测 API 做一些事情。我想一步一步做所有事情。我在回调的开头写了 callbackMutex every 。我在 if 语句的回调中取消订阅事件。

函数可以工作,但有时会出现“信息:达到线程限制”错误或取消订阅事件错误。

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 语句是否行走或停止。我没有使用任何东西来启动或停止线程。

4

2 回答 2

0

这里有技巧:

  • 你应该检查你的回调永远不会卡得太久,所以调用 async walk 方法是一件好事。

  • walk 方法需要时间,你不应该太频繁地调用它:~400ms 是最小值

  • 到达您的回调时,不要等待之前的回调完成,只需离开,因为下次会收到更新的信息。我的意思是,在收到新信息时,过去的信息是没有意义的,所以不要被卡住。

于 2014-06-02T15:26:10.010 回答
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 中。

于 2017-08-18T10:20:26.677 回答