Робот Webots не разговаривает, пытаясь использовать его с внешним Kinect

Я пытаюсь создать симуляцию Webots, в которой я хочу, чтобы мой робот говорил, когда камера Kinect обнаруживает человека.

У меня есть Kinect V2, подключенный к USB-порту, и он может самостоятельно обнаруживать человека, запустив мой код Python с использованием PyKinect2 и pygame.

В качестве следующего шага я поместил этот код в среду Webots и добавил робота, который будет разговаривать с пользователем, когда Kinect их обнаруживает. Однако, когда Kinect начинает работать и появляется окно, часы Webots перестают тикать, и робот ничего не делает. После закрытия окна Kinect робот произносит сообщение, но этот код должен был быть выполнен внутри кода Kinect, как указано ниже.

Я считаю, что это может быть проблема синхронизации из-за того, что Kinect и Webots имеют собственные часы, но я не уверен. Даже если это так, я не знаю, что делать дальше. Любые советы приветствуются.

Вот соответствующие части моего кода, при необходимости я могу предоставить полный код. Обнаружение тела Kinect - это слегка измененная версия этого примера :

class BodyGameRuntime(object):

    # ----- other functions here -----

    def run(self):
        # -------- Main Program Loop -----------
        while not self._done:

            # --- frame and window resize logic here

            # --- Draw skeletons to _frame_surface
            if self._bodies is not None:

                # ---------- Body Found ----------
                speaker.speak("User detected!", volume=1.0) # Speak to the user

                for i in range(0, self._kinect.max_body_count):
                    body = self._bodies.bodies[i]
                    if not body.is_tracked: 
                        continue

                    joints = body.joints
                    # convert joint coordinates to color space 
                    joint_points = self._kinect.body_joints_to_color_space(joints)
                    self.draw_body(joints, joint_points, SKELETON_COLORS[i])

            # --- copy back buffer logic here

            # --- Update the screen with what we've drawn.
            pygame.display.update()
            pygame.display.flip()

            # --- Limit to 30 frames per second
            self._clock.tick(30)

        # Close our Kinect sensor, close the window and quit.
        self._kinect.close()
        pygame.quit()

robot = Robot()
speaker = Speaker("Speaker")
#timestep = int(robot.getBasicTimeStep())

__main__ = "Kinect"
game = BodyGameRuntime()
game.run()

person tankucukoglu    schedule 01.12.2017    source источник
comment
Похоже, у робота есть собственный основной цикл программы, который вызывает ваш игровой цикл и блокирует его до тех пор, пока он не вернется.   -  person TemporalWolf    schedule 02.12.2017
comment
@TemporalWolf Я тоже заметил это. Но я не совсем уверен, как решить эту проблему. Любые идеи?   -  person tankucukoglu    schedule 02.12.2017
comment
возможно использовать потоки.   -  person furas    schedule 02.12.2017
comment
@furas попытался запустить код Kinect как отдельный поток, но Kinect вообще не ответил, и цикл робота все еще завис. Хотите, чтобы я отредактировал вопрос с обновленным кодом?   -  person tankucukoglu    schedule 02.12.2017
comment
вы можете добавить код с потоком. Может, вы ошиблись.   -  person furas    schedule 02.12.2017


Ответы (1)


Webots необходимо, чтобы вы вызывали функцию robot.step (timeStep) на регулярной основе, чтобы продвигаться по времени моделирования, иначе он просто остановит моделирование и дождется следующего вызова robot.step (timeStep). Я бы просто добавил вызов robot.step (timeStep) в ваш основной цикл прямо перед self._clock.tick (30) и раскомментировал инициализацию timeStep в вашей основной программе.

Обратите внимание, что если ваше моделирование Webots выполняется в реальном времени, вызов robot.step (X) будет длиться примерно X миллисекунд. Поэтому вам, вероятно, следует установить WorldInfo.basicTimeStep на 30 миллисекунд в вашем файле мира и избавиться от вызова self._clock.tick (30).

person Olivier Michel    schedule 04.12.2017
comment
Это было частью решения. Мне также пришлось сделать так, чтобы класс BodyGameRuntime() унаследовал класс Webots Robot следующим образом: BodyGameRuntime(Robot). Я также изменил WorldInfo.FPS на 30 с 60, так как в моей среде Kinect установлено значение 30 FPS. Наконец, я установил WorldInfo.basicTimeStep на 33, поскольку 30 кадров в секунду переводятся примерно в 1 кадр за 33 миллисекунды. - person tankucukoglu; 04.12.2017