如何使用wxpython中的GUI在pybullet中启动物理模拟

如何使用wxpython中的GUI在pybullet中启动物理模拟,wxpython,eventhandler,bullet,mainloop,Wxpython,Eventhandler,Bullet,Mainloop,我试图通过按钮事件在wxpython中打开一个带有GUI的Python项目。Python项目是一个物理模拟,它使用pybullet。下面的代码显示了一个最小的示例,向您展示我的问题。 第一个代码是wxpython应用程序的示例。 我导入模拟项目,并使用sim.start()函数通过按钮事件初始化pybullet模拟 import wx import Sim as sim #This is the physics simulation class MainFrame(wx.Frame):

我试图通过按钮事件在wxpython中打开一个带有GUI的Python项目。Python项目是一个物理模拟,它使用pybullet。下面的代码显示了一个最小的示例,向您展示我的问题。 第一个代码是wxpython应用程序的示例。 我导入模拟项目,并使用
sim.start()
函数通过按钮事件初始化pybullet模拟

import wx
import Sim as sim #This is the physics simulation


class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Digitaler Zwilling", size=(800, 600))

        self.panel = Panel(self)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.panel, 0, wx.EXPAND, 0)
        self.SetSizer(self.sizer)


class Panel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent = parent)

        # ____Buttons_____#
        start_btn = wx.Button(self, -1, label = "Start", pos = (635, 450), size = (95, 55))
        start_btn.Bind(wx.EVT_BUTTON, self.start)

    def start(self, event):
       sim.start   


if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()
作为pybullet项目,我从互联网上选择了一个例子:

import pybullet as p
import pybullet_data as pd
import time

def start():
    p.connect(p.GUI)
    p.setAdditionalSearchPath(pd.getDataPath())

    plane = p.loadURDF("plane.urdf")
    p.setGravity(0, 0, -9.8)
    p.setTimeStep(1./500)
    # p.setDefaultContactERP(0)
    # urdfFlags = p.URDF_USE_SELF_COLLISION+p.URDF_USE_SELF_COLLISION_EXCLUDE_ALL_PARENTS
    urdfFlags = p.URDF_USE_SELF_COLLISION
    quadruped = p.loadURDF("laikago/laikago_toes.urdf", [0, 0, .5], [0, 0.5, 0.5, 0],
                           flags = urdfFlags,
                           useFixedBase = False)

    # enable collision between lower legs

    for j in range(p.getNumJoints(quadruped)):
        print(p.getJointInfo(quadruped, j))

    # 2,5,8 and 11 are the lower legs
    lower_legs = [2, 5, 8, 11]
    for l0 in lower_legs:
        for l1 in lower_legs:
            if (l1 > l0):
                enableCollision = 1
                print("collision for pair", l0, l1,
                      p.getJointInfo(quadruped, l0) [12],
                      p.getJointInfo(quadruped, l1) [12], "enabled=", enableCollision)
                p.setCollisionFilterPair(quadruped, quadruped, 2, 5, enableCollision)

    jointIds = []
    paramIds = []
    jointOffsets = []
    jointDirections = [-1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1]
    jointAngles = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    for i in range(4):
        jointOffsets.append(0)
        jointOffsets.append(-0.7)
        jointOffsets.append(0.7)

    maxForceId = p.addUserDebugParameter("maxForce", 0, 100, 20)

    for j in range(p.getNumJoints(quadruped)):
        p.changeDynamics(quadruped, j, linearDamping = 0, angularDamping = 0)
        info = p.getJointInfo(quadruped, j)
        # print(info)
        jointName = info [1]
        jointType = info [2]
        if (jointType == p.JOINT_PRISMATIC or jointType == p.JOINT_REVOLUTE):
            jointIds.append(j)

    p.getCameraImage(480, 320)
    p.setRealTimeSimulation(0)

    joints = []

    with open(pd.getDataPath() + "/laikago/data1.txt", "r") as filestream:
        for line in filestream:
            print("line=", line)
            maxForce = p.readUserDebugParameter(maxForceId)
            currentline = line.split(",")
            # print (currentline)
            # print("-----")
            frame = currentline [0]
            t = currentline [1]
            # print("frame[",frame,"]")
            joints = currentline [2:14]
            # print("joints=",joints)
            for j in range(12):
                targetPos = float(joints [j])
                p.setJointMotorControl2(quadruped,
                                        jointIds [j],
                                        p.POSITION_CONTROL,
                                        jointDirections [j]*targetPos + jointOffsets [j],
                                        force = maxForce)
            p.stepSimulation()
            for lower_leg in lower_legs:
                # print("points for ", quadruped, " link: ", lower_leg)
                pts = p.getContactPoints(quadruped, -1, lower_leg)
                # print("num points=",len(pts))
                # for pt in pts:
                # print(pt[9])
            time.sleep(1./500.)

    index = 0
    for j in range(p.getNumJoints(quadruped)):
        p.changeDynamics(quadruped, j, linearDamping = 0, angularDamping = 0)
        info = p.getJointInfo(quadruped, j)
        js = p.getJointState(quadruped, j)
        # print(info)
        jointName = info [1]
        jointType = info [2]
        if (jointType == p.JOINT_PRISMATIC or jointType == p.JOINT_REVOLUTE):
            paramIds.append(p.addUserDebugParameter(jointName.decode("utf-8"), -4, 4,
                                                    (js [0] - jointOffsets [index])/jointDirections [index]))
            index = index + 1

    p.setRealTimeSimulation(1)

    while (1):

        for i in range(len(paramIds)):
            c = paramIds [i]
            targetPos = p.readUserDebugParameter(c)
            maxForce = p.readUserDebugParameter(maxForceId)
            p.setJointMotorControl2(quadruped,
                                    jointIds [i],
                                    p.POSITION_CONTROL,
                                    jointDirections [i]*targetPos + jointOffsets [i],
                                    force = maxForce)
pybullet GUI打开,模拟将启动,但随后它被卡住(查看屏幕截图)

我认为问题可能在于,我使用wxpython中的按钮事件启动pybullet模拟,该事件只能通过
app.MainLoop()
触发。但实际上我不确定

我试过:

  • 在开始模拟之前退出主回路
  • 要使用新线程启动模拟,请执行以下操作:
有人知道如何使用wxpythongui启动pybullet模拟,而不卡住模拟吗?或者我能告诉别人,我做错了什么

def start(self, event):
    self.create_thread(sim.start)

def create_thread(self, target):
    thread = threading.Thread(target=target)
    thread.daemon = True
    thread.start()