Я пытаюсь что-то сделать с помощью 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, чтобы пройти робота и проверить, если заявление, если он идет или останавливается. Я не использовал ничего, чтобы запустить или остановить поток.
Вот трюки:
Вы должны убедиться, что вы никогда не застряли слишком долго в обратном вызове,
так что вызов метода асинхронной прогулки — это хорошо.
Метод прогулки занимает время, его не следует вызывать слишком часто: минимум 400 мс
когда вы прибываете в вашем обратном вызове, не ждите завершения предыдущего обратного вызова, просто выйдите, так как более свежая информация будет получена в следующий раз. Я имею в виду, что прошлая информация не представляет интереса при получении новой, так что не застревайте.
Ты можешь использовать Ци :: 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.