softbankrobotics-research / qibullet

Bullet simulation for SoftBank Robotics robots

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Laser subscribe thread block "move" function

tunchunairarko opened this issue · comments

I am testing manual controlling of Pepper using pynput and qibullet.
After I subscribe to the "Laser", it blocks other threads from pynput from executing.
I even tried a multithreading approach (you can ignore that approach because regardless of it the robot doesn't move)
Here is my code so far:

import cv2
import time
from qibullet import SimulationManager
from qibullet import PepperVirtual
from qibullet import Camera
from pynput import keyboard
import pybullet
import pybullet_data
import threading


class PepperSim:
    def __init__(self):
        self.keyEvents=[]
        self.simulation_manager = SimulationManager()
        self.client = self.simulation_manager.launchSimulation(gui=True)
        self.pepper = self.simulation_manager.spawnPepper(self.client, spawn_ground_plane=True)
        
        
        pybullet.setAdditionalSearchPath(pybullet_data.getDataPath())
        pybullet.loadURDF(
            "block.urdf",
            basePosition=[6, 0, 0.5],
            globalScaling=10.0,
            physicsClientId=self.client)
        
        
        self.startLaser()
        self.pepper.showLaser(True)
        laser_thread=threading.Thread(target=self.pepper.subscribeLaser())
        laser_thread.start()       
        

        self.pepper.goToPosture("Crouch", 0.6)
        time.sleep(1)
        self.pepper.goToPosture("Stand", 0.6)
        time.sleep(1)
        
        with keyboard.Listener(
                on_press=self.on_press,
                on_release=self.on_release) as self.listener:
            self.listener.join()

    

    def detectObject(self):
        laser_list = self.pepper.getRightLaserValue()
        laser_list.extend(self.pepper.getFrontLaserValue())
        laser_list.extend(self.pepper.getLeftLaserValue())
        
        if all(laser == 3.0 for laser in laser_list):
            print('0') 
            print(laser_list)
            # self.pepper.unsubscribeLaser()         
            return False
        else:
            print(laser_list)
            print('1') 
            # self.pepper.unsubscribeLaser()   
            return True    
        
    def on_press(self,key):
        if(key==keyboard.Key.up):
            if not(self.detectObject()):
                self.pepper.move(1,0,0)
        elif(key==keyboard.Key.left):
            if not(self.detectObject()):
                self.pepper.move(0,1,0)
        elif(key==keyboard.Key.right):
            if not(self.detectObject()):
                self.pepper.move(0,-1,0)
        elif(key==keyboard.Key.shift_r):
            if not(self.detectObject()):
                self.pepper.move(0,0,-1.0)
        elif(key==keyboard.Key.shift_l):
            if not(self.detectObject()):
                self.pepper.move(0,0,1.0)
        
    def on_release(self,key):
        self.pepper.stopMove()
        if (key == keyboard.Key.esc):
            # Stop listener
            pybullet.disconnect()
            self.simulation_manager.stopSimulation(self.client)
            

def main():
    PepperSim()

if __name__ == "__main__":
    main()

I tried your code, the robot is moving on my end... (after commenting self.startLaser()). The following implementation allows you to correctly clean up the simulation when you press escape:

import cv2
import time
from qibullet import SimulationManager
from qibullet import PepperVirtual
from qibullet import Camera
from pynput import keyboard
import pybullet
import pybullet_data
import threading


class PepperSim:
    def __init__(self):
        self.keyEvents = []
        self.simulation_manager = SimulationManager()
        self.client = self.simulation_manager.launchSimulation(gui=True)
        self.pepper = self.simulation_manager.spawnPepper(
            self.client,
            spawn_ground_plane=True)

        pybullet.setAdditionalSearchPath(pybullet_data.getDataPath())
        pybullet.loadURDF(
            "block.urdf",
            basePosition=[6, 0, 0.5],
            globalScaling=10.0,
            physicsClientId=self.client)

        self.pepper.goToPosture("Stand", 0.6)
        time.sleep(1)

        self.pepper.subscribeLaser()
        self.pepper.showLaser(True)

        with keyboard.Listener(
                on_press=self.on_press,
                on_release=self.on_release) as self.listener:
            self.listener.join()

        self.pepper.unsubscribeLaser()
        self.simulation_manager.stopSimulation(self.client)

    def detectObject(self):
        laser_list = self.pepper.getRightLaserValue()
        laser_list.extend(self.pepper.getFrontLaserValue())
        laser_list.extend(self.pepper.getLeftLaserValue())

        return not all(laser == 3.0 for laser in laser_list)

    def on_press(self, key):
        if key == keyboard.Key.up:
            if not self.detectObject():
                self.pepper.move(1, 0, 0)
        elif key == keyboard.Key.left:
            if not self.detectObject():
                self.pepper.move(0, 1, 0)
        elif key == keyboard.Key.right:
            if not self.detectObject():
                self.pepper.move(0, -1, 0)
        elif key == keyboard.Key.shift_r:
            if not self.detectObject():
                self.pepper.move(0, 0, -1.0)
        elif key == keyboard.Key.shift_l:
            if not self.detectObject():
                self.pepper.move(0, 0, 1.0)

    def on_release(self, key):
        self.pepper.stopMove()

        # Stop if escape is pressed
        if (key == keyboard.Key.esc):
            self.listener.stop()


def main():
    PepperSim()


if __name__ == "__main__":
    main()

But again, you should be able to see the robot moving when pressing keys

Thank you for your update.
Initially, your implementation did not work.
However, I was curious regarding the fact that it worked in your case. I was running this code in my Windows OS. Later, I switched to my Ubuntu VM and it worked perfectly with navigation.

I assume there can be a conflict of the pynput library with qibullet in Windows environment.

I used Windows to run my implementation, everything runs smoothly... Are you using the latest version of qiBullet (1.4.3) ? Are you using Python 2 or 3 ? I assume that you are using Windows 10 ?

Hi,

These are the following configurations (for my Windows environment):

  • Windows 10
  • Python 3.9.1
  • qibullet==1.4.3
  • pybullet==3.0.8

Hi, thanks for the details. I have the same setup (except for Python, 3.7.7) and can't reproduce this blocking behaviour... If I have some time I will eventually try to test that with Python 3.9, but it shouldn't make much of a difference.

In any case, that issue is really specific to the usage of pynput, I will close it for now. I will eventually re-open it if I can reproduce what you experienced with Python 3.9 and if the controller thread of Pepper is responsible for that