在Nao机器人中使用多线程

时间:2014-05-29 20:22:22

标签: c++ multithreading robotics nao-robot

我正在尝试使用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语句是否走路或停止。我没有使用任何东西来启动或停止一个线程。

2 个答案:

答案 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中。