【问题标题】:Eventloop stuck: NAO C++ SDK OnFaceDetection ExampleEventloop 卡住:NAO C++ SDK OnFaceDetection 示例
【发布时间】:2018-10-16 07:10:36
【问题描述】:

我在我的 MAC 上安装了 NAOqi C++ SDK,并尝试了 SDK 中的一些示例。 HelloWorld-Example 运行良好,但使用 OnFaceDetection-Example 在 NAO 检测到我的脸后,我会收到带有 qi.eventloopError/Warning .

Narongsones-MacBook-Pro:bin Narongsone$ ./onfacedetection --pip 192.168.1.138
[I] 1295 core.common.toolsmain: ..::: starting onfacedetection :::..

[I] 1295 core.common.toolsmain: Connecting to 192.168.1.138:9559...

[I] 1295 qimessaging.session: Session listener created on tcp://0.0.0.0:0
[I] 1295 qimessaging.transportserver: TransportServer will listen on:    tcp://192.168.1.136:64881
[I] 1295 qimessaging.transportserver: TransportServer will listen on: tcp://127.0.0.1:64881
[I] 1295 core.common.toolsmain: Connection with 192.168.1.138:9559 established

[I] 1295 module.example: No face detected

[I] 1295 core.common.toolsmain: onfacedetection is ready... Press CTRL^C to quit

[I] 3843 module.name: 1 face(s) detected.

[I] 4355 qi.eventloop: eventloop: Spawning more threads (5)

[I] 4355 qi.eventloop: eventloop: Spawning more threads (6)

[I] 4355 qi.eventloop: eventloop: Spawning more threads (7)

[I] 4355 qi.eventloop: eventloop: Spawning more threads (8)

[I] 4355 qi.eventloop: eventloop: Spawning more threads (9)

[I] 4355 qi.eventloop: eventloop: Spawning more threads (10)

如果您对问题所在有任何想法,请帮助我。谢谢!

我的回调函数:

void OnFaceDetection::callback() {
  /** Use a mutex to make it all thread safe. */
  AL::ALCriticalSection section(fCallbackMutex);

  try {
    /** Retrieve the data raised by the event. */
    fFaces = fMemoryProxy.getData("FaceDetected");
    /** Check that there are faces effectively detected. */
    if (fFaces.getSize() < 2 ) {
      if (fFacesCount != 0) {
        qiLogInfo("module.example") << "No face detected" << std::endl;
        fTtsProxy.say("No face detected.");
        fFacesCount = 0;
      }
      return;
    }
    /** Check the number of faces from the FaceInfo field, and check that it has
    * changed from the last event.*/
    if (fFaces[1].getSize() - 1 != fFacesCount) {
      qiLogInfo("module.name") << fFaces[1].getSize() - 1 << " face(s) detected." << std::endl;
      char buffer[50];

      sprintf(buffer, "%d faces detected.", fFaces[1].getSize() - 1);
      fTtsProxy.say(std::string(buffer));

      /** Update the current number of detected faces. */
      fFacesCount = fFaces[1].getSize() - 1;
    }

  }
  catch (const AL::ALError& e) {
    qiLogError("module.name") << e.what() << std::endl;
  }
}

【问题讨论】:

  • 当您创建新线程并且从不退出它们时,通常会出现这种错误。所以看看你在回调中做了什么,并检查你是否在一段时间后退出它......祝你好运
  • @AlexandreMazel 我编辑了我的帖子并添加了我的回调函数。我还不知道,我该如何解决它。你能给我一些建议吗?
  • 我认为错误是面部检测以 10fps 的速度运行,并且对于任何回调,您都需要 2 秒来调用说话动作。因此,您正在堆积大量等待“tts.say”调用的线程。我的建议是仅在统计数据发生变化时发言,并防止发言过多。就像如果 time.time() - self.lastTimeSpoken > 5.0 然后 self.lastTimeSpoken = time.time() 和说话。
  • @AlexandreMazel 这就是问题所在。我评论了“tts.say”调用,错误不再出现。那么如果 time.time()... in 我应该把代码放在哪里呢?
  • 用上面的代码修改 tts.say

标签: c++ multithreading event-loop nao-robot qi


【解决方案1】:

正如@AlexandreMazel 所提到的,此错误只是在向您解释系统正在创建太多新线程,因为该函数被非常频繁地调用(高达 10x/s),但由于有演讲需要几秒钟才能执行在里面。

您可能需要一个标志或一个非阻塞互斥体来防止函数多次运行。

【讨论】:

  • 感谢您的回答。但什么是旗帜?以及如何在我的代码中添加非阻塞互斥锁?有什么例子吗?
  • 一个标志只是一个全局布尔“is_running”,您在方法开始时设置为 True,在方法结束时设置为 False。这样你就可以测试而不是同时运行两次:“if is_running: return”
【解决方案2】:

关于更改 tts.say,这里有一个例子:

通过处理所有文本命令的方法更改 tts.say

tts.say(txt)

变成:

if time.time() - self.lastSaidTime > 5.0 or txt != self.lastSaidText:
    self.lastSaidTime = time.time()
    self.lastSaidText = txt
    tts.say(txt)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2017-02-22
    相关资源
    最近更新 更多