Использование многопоточности в роботе Nao

Я пытаюсь что-то сделать с помощью API обнаружения красных шаров Нао. Я хочу сделать все шаг за шагом. Я написал callbackMutex каждый в начале обратных вызовов. Я отписываю событие в обратном вызове в заявлении if.

Функции работают, но иногда выдают ошибку «INFO: Предел потока достигнут» или событие отказа от подписки.

Нао всегда видит красный шар, но создает много ниток (я думаю). Как я могу использовать только один поток?

Я писал на c ++.

Я подписываюсь так:

memory.subscribeToEvent("redBallDetected", "moduleName", "fuctionName");

затем, когда Нао видит мяч, вызывается эта функция.

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, чтобы пройти робота и проверить, если заявление, если он идет или останавливается. Я не использовал ничего, чтобы запустить или остановить поток.

0

Решение

Вот трюки:

  • Вы должны убедиться, что вы никогда не застряли слишком долго в обратном вызове,
    так что вызов метода асинхронной прогулки — это хорошо.

  • Метод прогулки занимает время, его не следует вызывать слишком часто: минимум 400 мс

  • когда вы прибываете в вашем обратном вызове, не ждите завершения предыдущего обратного вызова, просто выйдите, так как более свежая информация будет получена в следующий раз. Я имею в виду, что прошлая информация не представляет интереса при получении новой, так что не застревайте.

0

Другие решения

Ты можешь использовать Ци :: 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();
}
}));

Примечание: если лямбда не работает, попробуйте обернуть ее в boost :: function.

0

По вопросам рекламы [email protected]