Merge pull request #624 from erwincoumans/master
Allow to compile pybullet on Windows, using CMake
This commit is contained in:
@@ -192,9 +192,15 @@ ENDIF()
|
|||||||
|
|
||||||
OPTION(BUILD_BULLET3 "Set when you want to build Bullet 3" ON)
|
OPTION(BUILD_BULLET3 "Set when you want to build Bullet 3" ON)
|
||||||
OPTION(BUILD_PYBULLET "Set when you want to build pybullet (experimental Python bindings for Bullet)" OFF)
|
OPTION(BUILD_PYBULLET "Set when you want to build pybullet (experimental Python bindings for Bullet)" OFF)
|
||||||
|
|
||||||
IF(BUILD_PYBULLET)
|
IF(BUILD_PYBULLET)
|
||||||
FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
|
IF(WIN32)
|
||||||
SET(BUILD_SHARED_LIBS ON CACHE BOOL "Shared Libs" FORCE)
|
FIND_PACKAGE(PythonLibs 3.4 REQUIRED)
|
||||||
|
SET(BUILD_SHARED_LIBS OFF CACHE BOOL "Shared Libs" FORCE)
|
||||||
|
ELSE(WIN32)
|
||||||
|
FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
|
||||||
|
SET(BUILD_SHARED_LIBS ON CACHE BOOL "Shared Libs" FORCE)
|
||||||
|
ENDIF(WIN32)
|
||||||
ENDIF(BUILD_PYBULLET)
|
ENDIF(BUILD_PYBULLET)
|
||||||
|
|
||||||
IF(BUILD_BULLET3)
|
IF(BUILD_BULLET3)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
IF (BUILD_SHARED_LIBS)
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||||
@@ -12,13 +11,19 @@ SET(pybullet_SRCS
|
|||||||
../../examples/ExampleBrowser/ExampleEntries.cpp
|
../../examples/ExampleBrowser/ExampleEntries.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
IF(WIN32)
|
||||||
|
LINK_LIBRARIES(
|
||||||
|
${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
ADD_LIBRARY(pybullet ${pybullet_SRCS})
|
ENDIF(WIN32)
|
||||||
|
|
||||||
|
ADD_LIBRARY(pybullet SHARED ${pybullet_SRCS})
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(pybullet PROPERTIES VERSION ${BULLET_VERSION})
|
SET_TARGET_PROPERTIES(pybullet PROPERTIES VERSION ${BULLET_VERSION})
|
||||||
SET_TARGET_PROPERTIES(pybullet PROPERTIES SOVERSION ${BULLET_VERSION})
|
SET_TARGET_PROPERTIES(pybullet PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen Bullet3Common ${PYTHON_LIBRARIES})
|
TARGET_LINK_LIBRARIES(pybullet BulletExampleBrowserLib BulletSoftBody BulletDynamics BulletCollision BulletInverseDynamicsUtils BulletInverseDynamics LinearMath OpenGLWindow gwen Bullet3Common ${PYTHON_LIBRARIES})
|
||||||
ENDIF (BUILD_SHARED_LIBS)
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
|
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
|
||||||
#include "../SharedMemory/PhysicsClientC_API.h"
|
#include "../SharedMemory/PhysicsClientC_API.h"
|
||||||
|
#include "../SharedMemory/PhysicsDirectC_API.h"
|
||||||
|
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <Python/Python.h>
|
#include <Python/Python.h>
|
||||||
@@ -7,6 +10,13 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum eCONNECT_METHOD
|
||||||
|
{
|
||||||
|
eCONNECT_GUI=1,
|
||||||
|
eCONNECT_DIRECT=2,
|
||||||
|
eCONNECT_SHARED_MEMORY=3,
|
||||||
|
};
|
||||||
|
|
||||||
static PyObject *SpamError;
|
static PyObject *SpamError;
|
||||||
static b3PhysicsClientHandle sm=0;
|
static b3PhysicsClientHandle sm=0;
|
||||||
|
|
||||||
@@ -20,18 +30,19 @@ pybullet_stepSimulation(PyObject *self, PyObject *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
b3SharedMemoryStatusHandle statusHandle;
|
||||||
|
int statusType;
|
||||||
|
|
||||||
|
if (b3CanSubmitCommand(sm))
|
||||||
{
|
{
|
||||||
b3SharedMemoryStatusHandle statusHandle;
|
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm));
|
||||||
int statusType;
|
statusType = b3GetStatusType(statusHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (b3CanSubmitCommand(sm))
|
Py_INCREF(Py_None);
|
||||||
{
|
return Py_None;
|
||||||
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm));
|
|
||||||
statusType = b3GetStatusType(statusHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyLong_FromLong(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@@ -44,10 +55,51 @@ pybullet_connectPhysicsServer(PyObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY);
|
int method=eCONNECT_GUI;
|
||||||
|
if (!PyArg_ParseTuple(args, "i", &method))
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "connectPhysicsServer expected argument eCONNECT_GUI, eCONNECT_DIRECT or eCONNECT_SHARED_MEMORY");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case eCONNECT_GUI:
|
||||||
|
{
|
||||||
|
int argc=0;
|
||||||
|
char* argv[1]={0};
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
sm = b3CreateInProcessPhysicsServerAndConnectMainThread(argc, argv);
|
||||||
|
#else
|
||||||
|
sm = b3CreateInProcessPhysicsServerAndConnect(argc, argv);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eCONNECT_DIRECT:
|
||||||
|
{
|
||||||
|
sm = b3ConnectPhysicsDirect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case eCONNECT_SHARED_MEMORY:
|
||||||
|
{
|
||||||
|
sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "connectPhysicsServer unexpected argument");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyLong_FromLong(1);
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@@ -63,18 +115,15 @@ pybullet_disconnectPhysicsServer(PyObject *self, PyObject *args)
|
|||||||
sm = 0;
|
sm = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyLong_FromLong(1);
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
pybullet_loadURDF(PyObject* self, PyObject* args)
|
pybullet_loadURDF(PyObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
if (0==sm)
|
|
||||||
{
|
|
||||||
PyErr_SetString(SpamError, "Not connected to physics server.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int size= PySequence_Size(args);
|
int size= PySequence_Size(args);
|
||||||
|
|
||||||
int bodyIndex = -1;
|
int bodyIndex = -1;
|
||||||
@@ -87,6 +136,11 @@ pybullet_loadURDF(PyObject* self, PyObject* args)
|
|||||||
float startOrnZ = 0;
|
float startOrnZ = 0;
|
||||||
float startOwnW = 1;
|
float startOwnW = 1;
|
||||||
printf("size=%d\n", size);
|
printf("size=%d\n", size);
|
||||||
|
if (0==sm)
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "Not connected to physics server.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (size==1)
|
if (size==1)
|
||||||
{
|
{
|
||||||
if (!PyArg_ParseTuple(args, "s", &urdfFileName))
|
if (!PyArg_ParseTuple(args, "s", &urdfFileName))
|
||||||
@@ -106,11 +160,11 @@ pybullet_loadURDF(PyObject* self, PyObject* args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
printf("urdf filename = %s\n", urdfFileName);
|
|
||||||
b3SharedMemoryStatusHandle statusHandle;
|
b3SharedMemoryStatusHandle statusHandle;
|
||||||
int statusType;
|
int statusType;
|
||||||
b3SharedMemoryCommandHandle command = b3LoadUrdfCommandInit(sm, urdfFileName);
|
b3SharedMemoryCommandHandle command = b3LoadUrdfCommandInit(sm, urdfFileName);
|
||||||
|
printf("urdf filename = %s\n", urdfFileName);
|
||||||
//setting the initial position, orientation and other arguments are optional
|
//setting the initial position, orientation and other arguments are optional
|
||||||
b3LoadUrdfCommandSetStartPosition(command, startPosX,startPosY,startPosZ);
|
b3LoadUrdfCommandSetStartPosition(command, startPosX,startPosY,startPosZ);
|
||||||
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command);
|
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command);
|
||||||
@@ -136,43 +190,157 @@ pybullet_resetSimulation(PyObject* self, PyObject* args)
|
|||||||
{
|
{
|
||||||
b3SharedMemoryStatusHandle statusHandle;
|
b3SharedMemoryStatusHandle statusHandle;
|
||||||
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitResetSimulationCommand(sm));
|
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitResetSimulationCommand(sm));
|
||||||
// ASSERT_EQ(b3GetStatusType(statusHandle), CMD_RESET_SIMULATION_COMPLETED);
|
|
||||||
}
|
}
|
||||||
return PyLong_FromLong(1);
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pybullet_setGravity(PyObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
if (0==sm)
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "Not connected to physics server.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
float gravX=0;
|
||||||
|
float gravY=0;
|
||||||
|
float gravZ=-10;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand(sm);
|
||||||
|
b3SharedMemoryStatusHandle statusHandle;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "fff", &gravX,&gravY,&gravZ))
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "setGravity expected (x,y,z) values.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = b3PhysicsParamSetGravity(command, gravX,gravY, gravZ);
|
||||||
|
//ret = b3PhysicsParamSetTimeStep(command, timeStep);
|
||||||
|
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command);
|
||||||
|
//ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1)
|
||||||
|
{
|
||||||
|
PyObject *pylist;
|
||||||
|
PyObject *item;
|
||||||
|
int i;
|
||||||
|
int num=3;
|
||||||
|
pylist = PyTuple_New(num);
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
item = PyFloat_FromDouble(i);
|
||||||
|
PyTuple_SetItem(pylist, i, item);
|
||||||
|
}
|
||||||
|
return pylist;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pybullet_getNumJoints(PyObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
if (0==sm)
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "Not connected to physics server.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int bodyIndex = -1;
|
||||||
|
int numJoints=0;
|
||||||
|
if (!PyArg_ParseTuple(args, "i", &bodyIndex ))
|
||||||
|
{
|
||||||
|
PyErr_SetString(SpamError, "Expected a body index (integer).");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
numJoints = b3GetNumJoints(sm,bodyIndex);
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
return PyLong_FromLong(numJoints);
|
||||||
|
#else
|
||||||
|
return PyInt_FromLong(numJoints);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef SpamMethods[] = {
|
static PyMethodDef SpamMethods[] = {
|
||||||
{"loadURDF", pybullet_loadURDF, METH_VARARGS,
|
{"loadURDF", pybullet_loadURDF, METH_VARARGS,
|
||||||
"Create a multibody by loading a URDF file."},
|
"Create a multibody by loading a URDF file."},
|
||||||
|
|
||||||
{"connect", pybullet_connectPhysicsServer, METH_VARARGS,
|
{"connect", pybullet_connectPhysicsServer, METH_VARARGS,
|
||||||
"Connect to an existing physics server (using shared memory by default)."},
|
"Connect to an existing physics server (using shared memory by default)."},
|
||||||
|
|
||||||
{"disconnect", pybullet_disconnectPhysicsServer, METH_VARARGS,
|
{"disconnect", pybullet_disconnectPhysicsServer, METH_VARARGS,
|
||||||
"Disconnect from the physics server."},
|
"Disconnect from the physics server."},
|
||||||
|
|
||||||
{"resetSimulation", pybullet_resetSimulation, METH_VARARGS,
|
{"resetSimulation", pybullet_resetSimulation, METH_VARARGS,
|
||||||
"Reset the simulation: remove all objects and start from an empty world."},
|
"Reset the simulation: remove all objects and start from an empty world."},
|
||||||
|
|
||||||
{"stepSimulation", pybullet_stepSimulation, METH_VARARGS,
|
{"stepSimulation", pybullet_stepSimulation, METH_VARARGS,
|
||||||
"Step the simulation using forward dynamics."},
|
"Step the simulation using forward dynamics."},
|
||||||
|
|
||||||
|
{"setGravity", pybullet_setGravity, METH_VARARGS,
|
||||||
|
"Set the gravity acceleration (x,y,z)."},
|
||||||
|
|
||||||
|
{"getNumsetGravity", pybullet_setGravity, METH_VARARGS,
|
||||||
|
"Set the gravity acceleration (x,y,z)."},
|
||||||
|
{
|
||||||
|
"getNumJoints", pybullet_getNumJoints, METH_VARARGS,
|
||||||
|
"Get the number of joints for an object."},
|
||||||
|
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
static struct PyModuleDef moduledef = {
|
||||||
|
PyModuleDef_HEAD_INIT,
|
||||||
|
"pybullet", /* m_name */
|
||||||
|
"Python bindings for Bullet", /* m_doc */
|
||||||
|
-1, /* m_size */
|
||||||
|
SpamMethods, /* m_methods */
|
||||||
|
NULL, /* m_reload */
|
||||||
|
NULL, /* m_traverse */
|
||||||
|
NULL, /* m_clear */
|
||||||
|
NULL, /* m_free */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
PyInit_pybullet(void)
|
||||||
|
#else
|
||||||
initpybullet(void)
|
initpybullet(void)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
m = Py_InitModule("pybullet", SpamMethods);
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
m = PyModule_Create(&moduledef);
|
||||||
|
#else
|
||||||
|
m = Py_InitModule3("pybullet",
|
||||||
|
SpamMethods, "Python bindings for Bullet");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return;
|
return m;
|
||||||
|
|
||||||
|
PyModule_AddIntConstant (m, "SHARED_MEMORY", eCONNECT_SHARED_MEMORY); // user read
|
||||||
|
PyModule_AddIntConstant (m, "DIRECT", eCONNECT_DIRECT); // user read
|
||||||
|
PyModule_AddIntConstant (m, "GUI", eCONNECT_GUI); // user read
|
||||||
|
|
||||||
SpamError = PyErr_NewException("pybullet.error", NULL, NULL);
|
SpamError = PyErr_NewException("pybullet.error", NULL, NULL);
|
||||||
Py_INCREF(SpamError);
|
Py_INCREF(SpamError);
|
||||||
PyModule_AddObject(m, "error", SpamError);
|
PyModule_AddObject(m, "error", SpamError);
|
||||||
|
#if PY_MAJOR_VERSION >= 3
|
||||||
|
return m;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,30 @@
|
|||||||
import pybullet
|
import pybullet
|
||||||
pybullet.loadURDF('r2d2.urdf')
|
import time
|
||||||
pybullet.loadURDF('kuka_lwr/kuka.urdf',3,0,0)
|
|
||||||
|
#choose connection method: GUI, DIRECT, SHARED_MEMORY
|
||||||
|
pybullet.connect(pybullet.GUI)
|
||||||
|
|
||||||
|
#load URDF, given a relative or absolute file+path
|
||||||
|
obj = pybullet.loadURDF("C:/develop/bullet3/data/r2d2.urdf")
|
||||||
|
|
||||||
|
#query the number of joints of the object
|
||||||
|
numJoints = pybullet.getNumJoints(obj)
|
||||||
|
|
||||||
|
print (numJoints)
|
||||||
|
|
||||||
|
#set the gravity acceleration
|
||||||
|
pybullet.setGravity(0,0,-0.01)
|
||||||
|
|
||||||
|
#step the simulation for 5 seconds
|
||||||
|
t_end = time.time() + 5
|
||||||
|
while time.time() < t_end:
|
||||||
|
pybullet.stepSimulation()
|
||||||
|
|
||||||
|
print ("finished")
|
||||||
|
#remove all objects
|
||||||
|
pybullet.resetSimulation()
|
||||||
|
|
||||||
|
#disconnect from the physics server
|
||||||
|
pybullet.disconnect()
|
||||||
|
|
||||||
for x in range(0, 1000000):
|
|
||||||
pybullet.step()
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user