2016-04-30 18:18:54 +00:00
# include "../SharedMemory/PhysicsClientC_API.h"
2016-05-10 07:57:54 +00:00
# include "../SharedMemory/PhysicsDirectC_API.h"
2016-06-17 01:46:34 +00:00
# include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
2016-11-04 20:15:10 +00:00
# ifdef BT_ENABLE_ENET
# include "../SharedMemory/PhysicsClientUDP_C_API.h"
# endif //BT_ENABLE_ENET
2016-09-11 10:09:51 +00:00
2016-04-30 18:18:54 +00:00
# ifdef __APPLE__
# include <Python/Python.h>
# else
# include <Python.h>
# endif
2016-09-11 10:09:51 +00:00
# ifdef PYBULLET_USE_NUMPY
# include <numpy/arrayobject.h>
# endif
2016-06-23 05:10:00 +00:00
# if PY_MAJOR_VERSION >= 3
# define PyInt_FromLong PyLong_FromLong
# define PyString_FromString PyBytes_FromString
2016-09-08 18:12:58 +00:00
# endif
2016-06-23 05:10:00 +00:00
2016-09-08 18:12:58 +00:00
enum eCONNECT_METHOD {
eCONNECT_GUI = 1 ,
eCONNECT_DIRECT = 2 ,
eCONNECT_SHARED_MEMORY = 3 ,
2016-11-04 20:15:10 +00:00
eCONNECT_UDP = 4 ,
2016-05-10 07:57:54 +00:00
} ;
2016-09-08 18:12:58 +00:00
static PyObject * SpamError ;
static b3PhysicsClientHandle sm = 0 ;
2016-05-03 19:59:21 +00:00
2016-11-28 23:11:34 +00:00
static double pybullet_internalGetFloatFromSequence ( PyObject * seq , int index ) {
double v = 0.0 ;
PyObject * item ;
if ( PyList_Check ( seq ) ) {
item = PyList_GET_ITEM ( seq , index ) ;
v = PyFloat_AsDouble ( item ) ;
}
else {
item = PyTuple_GET_ITEM ( seq , index ) ;
v = PyFloat_AsDouble ( item ) ;
}
return v ;
}
// internal function to set a float matrix[16]
// used to initialize camera position with
// a view and projection matrix in renderImage()
//
// // Args:
// matrix - float[16] which will be set by values from objMat
static int pybullet_internalSetMatrix ( PyObject * objMat , float matrix [ 16 ] ) {
int i , len ;
PyObject * seq ;
seq = PySequence_Fast ( objMat , " expected a sequence " ) ;
if ( seq )
{
len = PySequence_Size ( objMat ) ;
if ( len = = 16 ) {
for ( i = 0 ; i < len ; i + + ) {
matrix [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
Py_DECREF ( seq ) ;
return 1 ;
}
Py_DECREF ( seq ) ;
}
return 0 ;
}
// internal function to set a float vector[3]
// used to initialize camera position with
// a view and projection matrix in renderImage()
//
// // Args:
// vector - float[3] which will be set by values from objMat
static int pybullet_internalSetVector ( PyObject * objVec , float vector [ 3 ] ) {
int i , len ;
PyObject * seq = 0 ;
if ( objVec = = NULL )
return 0 ;
seq = PySequence_Fast ( objVec , " expected a sequence " ) ;
if ( seq )
{
len = PySequence_Size ( objVec ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < len ; i + + ) {
vector [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
Py_DECREF ( seq ) ;
return 1 ;
}
Py_DECREF ( seq ) ;
}
return 0 ;
}
// vector - double[3] which will be set by values from obVec
static int pybullet_internalSetVectord ( PyObject * obVec , double vector [ 3 ] ) {
int i , len ;
PyObject * seq ;
if ( obVec = = NULL )
return 0 ;
seq = PySequence_Fast ( obVec , " expected a sequence " ) ;
if ( seq )
{
len = PySequence_Size ( obVec ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < len ; i + + ) {
vector [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
Py_DECREF ( seq ) ;
return 1 ;
}
Py_DECREF ( seq ) ;
}
return 0 ;
}
// vector - double[3] which will be set by values from obVec
static int pybullet_internalSetVector4d ( PyObject * obVec , double vector [ 4 ] ) {
int i , len ;
PyObject * seq ;
if ( obVec = = NULL )
return 0 ;
seq = PySequence_Fast ( obVec , " expected a sequence " ) ;
len = PySequence_Size ( obVec ) ;
if ( len = = 4 ) {
for ( i = 0 ; i < len ; i + + ) {
vector [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
Py_DECREF ( seq ) ;
return 1 ;
}
Py_DECREF ( seq ) ;
return 0 ;
}
2016-06-10 22:07:41 +00:00
// Step through one timestep of the simulation
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_stepSimulation ( PyObject * self , PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-04-30 18:18:54 +00:00
2016-09-08 18:12:58 +00:00
{
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
2016-05-10 07:57:54 +00:00
2016-09-08 18:12:58 +00:00
if ( b3CanSubmitCommand ( sm ) ) {
statusHandle = b3SubmitClientCommandAndWaitStatus (
sm , b3InitStepSimulationCommand ( sm ) ) ;
statusType = b3GetStatusType ( statusHandle ) ;
2016-05-10 07:57:54 +00:00
}
2016-09-08 18:12:58 +00:00
}
2016-04-30 18:18:54 +00:00
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-04-30 18:18:54 +00:00
}
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_connectPhysicsServer ( PyObject * self , PyObject * args ) {
if ( 0 ! = sm ) {
PyErr_SetString ( SpamError ,
" Already connected to physics server, disconnect first. " ) ;
return NULL ;
}
{
int method = eCONNECT_GUI ;
2016-11-05 00:06:55 +00:00
int key = SHARED_MEMORY_KEY ;
int port = 1234 ;
const char * hostName = " localhost " ;
int size = PySequence_Size ( args ) ;
if ( size = = 1 )
{
if ( ! PyArg_ParseTuple ( args , " i " , & method ) ) {
PyErr_SetString ( SpamError ,
" connectPhysicsServer expected argument GUI, "
" DIRECT, SHARED_MEMORY or UDP " ) ;
return NULL ;
}
}
if ( size = = 2 )
{
if ( ! PyArg_ParseTuple ( args , " ii " , & method , & key ) )
{
if ( ! PyArg_ParseTuple ( args , " is " , & method , & hostName ) )
{
PyErr_SetString ( SpamError ,
" connectPhysicsServer cannot parse second argument (either integer or string) " ) ;
return NULL ;
}
}
}
if ( size = = 3 )
{
if ( ! PyArg_ParseTuple ( args , " isi " , & method , & hostName , & port ) )
{
PyErr_SetString ( SpamError ,
" connectPhysicsServer 3 arguments: method, hostname, port " ) ;
return NULL ;
}
}
2016-09-08 18:12:58 +00:00
switch ( method ) {
case eCONNECT_GUI : {
int argc = 0 ;
char * argv [ 1 ] = { 0 } ;
2016-05-10 07:57:54 +00:00
# ifdef __APPLE__
2016-09-08 18:12:58 +00:00
sm = b3CreateInProcessPhysicsServerAndConnectMainThread ( argc , argv ) ;
2016-05-10 07:57:54 +00:00
# else
2016-09-08 18:12:58 +00:00
sm = b3CreateInProcessPhysicsServerAndConnect ( argc , argv ) ;
2016-05-10 07:57:54 +00:00
# endif
2016-09-08 18:12:58 +00:00
break ;
}
case eCONNECT_DIRECT : {
sm = b3ConnectPhysicsDirect ( ) ;
break ;
}
case eCONNECT_SHARED_MEMORY : {
2016-11-05 00:06:55 +00:00
sm = b3ConnectSharedMemory ( key ) ;
2016-09-08 18:12:58 +00:00
break ;
}
2016-11-04 20:15:10 +00:00
case eCONNECT_UDP :
{
# ifdef BT_ENABLE_ENET
2016-11-05 00:06:55 +00:00
sm = b3ConnectPhysicsUDP ( hostName , port ) ;
2016-11-04 20:15:10 +00:00
# else
PyErr_SetString ( SpamError , " UDP is not enabled in this pybullet build " ) ;
return NULL ;
# endif //BT_ENABLE_ENET
break ;
}
2016-05-03 19:59:21 +00:00
2016-09-08 18:12:58 +00:00
default : {
PyErr_SetString ( SpamError , " connectPhysicsServer unexpected argument " ) ;
2016-05-03 19:59:21 +00:00
return NULL ;
2016-09-08 18:12:58 +00:00
}
} ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
static PyObject * pybullet_disconnectPhysicsServer ( PyObject * self ,
PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
b3DisconnectSharedMemory ( sm ) ;
sm = 0 ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-05-03 19:59:21 +00:00
}
2016-10-13 06:03:36 +00:00
static PyObject * pybullet_saveWorld ( PyObject * self , PyObject * args ) {
int size = PySequence_Size ( args ) ;
const char * worldFileName = " " ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( size = = 1 ) {
if ( ! PyArg_ParseTuple ( args , " s " , & worldFileName ) )
{
return NULL ;
}
else
{
b3SharedMemoryCommandHandle command ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
command = b3SaveWorldCommandInit ( sm , worldFileName ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType ! = CMD_SAVE_WORLD_COMPLETED ) {
PyErr_SetString ( SpamError , " saveWorld command execution failed. " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
}
PyErr_SetString ( SpamError , " Cannot execute saveWorld command. " ) ;
return NULL ;
2016-11-11 22:44:50 +00:00
}
2016-11-14 15:39:34 +00:00
# define MAX_SDF_BODIES 512
2016-11-11 22:44:50 +00:00
static PyObject * pybullet_loadBullet ( PyObject * self , PyObject * args )
{
int size = PySequence_Size ( args ) ;
const char * bulletFileName = " " ;
2016-11-12 02:07:42 +00:00
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
b3SharedMemoryCommandHandle command ;
2016-11-14 15:39:34 +00:00
int i , numBodies ;
int bodyIndicesOut [ MAX_SDF_BODIES ] ;
PyObject * pylist = 0 ;
2016-11-11 22:44:50 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
2016-11-12 02:07:42 +00:00
return NULL ;
2016-10-13 06:03:36 +00:00
}
2016-11-11 22:44:50 +00:00
if ( size = = 1 ) {
if ( ! PyArg_ParseTuple ( args , " s " , & bulletFileName ) ) return NULL ;
}
2016-11-12 02:07:42 +00:00
command = b3LoadBulletCommandInit ( sm , bulletFileName ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType ! = CMD_BULLET_LOADING_COMPLETED )
{
PyErr_SetString ( SpamError , " Couldn't load .bullet file. " ) ;
return NULL ;
}
2016-11-14 15:39:34 +00:00
numBodies =
b3GetStatusBodyIndices ( statusHandle , bodyIndicesOut , MAX_SDF_BODIES ) ;
if ( numBodies > MAX_SDF_BODIES ) {
PyErr_SetString ( SpamError , " loadBullet exceeds body capacity " ) ;
return NULL ;
}
pylist = PyTuple_New ( numBodies ) ;
if ( numBodies > 0 & & numBodies < = MAX_SDF_BODIES ) {
for ( i = 0 ; i < numBodies ; i + + ) {
PyTuple_SetItem ( pylist , i , PyInt_FromLong ( bodyIndicesOut [ i ] ) ) ;
}
}
return pylist ;
2016-11-11 22:44:50 +00:00
}
static PyObject * pybullet_saveBullet ( PyObject * self , PyObject * args )
{
int size = PySequence_Size ( args ) ;
const char * bulletFileName = " " ;
2016-11-12 02:07:42 +00:00
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
b3SharedMemoryCommandHandle command ;
2016-11-11 22:44:50 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( size = = 1 ) {
if ( ! PyArg_ParseTuple ( args , " s " , & bulletFileName ) ) return NULL ;
}
2016-11-12 02:07:42 +00:00
command = b3SaveBulletCommandInit ( sm , bulletFileName ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
2016-11-14 22:08:05 +00:00
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType ! = CMD_BULLET_SAVING_COMPLETED )
2016-11-12 02:07:42 +00:00
{
PyErr_SetString ( SpamError , " Couldn't save .bullet file. " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-11-11 22:44:50 +00:00
}
2016-10-13 06:03:36 +00:00
2016-11-11 22:44:50 +00:00
static PyObject * pybullet_loadMJCF ( PyObject * self , PyObject * args )
{
int size = PySequence_Size ( args ) ;
const char * mjcfjFileName = " " ;
2016-11-12 02:07:42 +00:00
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
b3SharedMemoryCommandHandle command ;
2016-11-11 22:44:50 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( size = = 1 ) {
if ( ! PyArg_ParseTuple ( args , " s " , & mjcfjFileName ) ) return NULL ;
}
2016-11-12 02:07:42 +00:00
command = b3LoadMJCFCommandInit ( sm , mjcfjFileName ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
2016-11-14 22:08:05 +00:00
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType ! = CMD_MJCF_LOADING_COMPLETED )
2016-11-12 02:07:42 +00:00
{
PyErr_SetString ( SpamError , " Couldn't load .mjcf file. " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-11-11 22:44:50 +00:00
}
2016-12-01 06:24:20 +00:00
static PyObject * pybullet_setPhysicsEngineParameter ( PyObject * self , PyObject * args , PyObject * keywds )
{
double fixedTimeStep = - 1 ;
int numSolverIterations = - 1 ;
int useSplitImpulse = - 1 ;
double splitImpulsePenetrationThreshold = - 1 ;
2016-12-02 01:54:52 +00:00
int numSubSteps = - 1 ;
2016-12-01 06:24:20 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-12-05 19:54:56 +00:00
static char * kwlist [ ] = { " fixedTimeStep " , " numSolverIterations " , " useSplitImpulse " , " splitImpulsePenetrationThreshold " , " numSubSteps " , NULL } ;
2016-12-01 06:24:20 +00:00
2016-12-02 01:54:52 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " |diidi " , kwlist , & fixedTimeStep , & numSolverIterations , & useSplitImpulse , & splitImpulsePenetrationThreshold , & numSubSteps ) )
2016-12-01 06:24:20 +00:00
{
return NULL ;
}
{
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand ( sm ) ;
b3SharedMemoryStatusHandle statusHandle ;
if ( numSolverIterations > = 0 )
{
b3PhysicsParamSetNumSolverIterations ( command , numSolverIterations ) ;
}
2016-12-05 19:54:56 +00:00
if ( numSubSteps > = 0 )
{
b3PhysicsParamSetNumSubSteps ( command , numSubSteps ) ;
}
2016-12-01 06:24:20 +00:00
if ( fixedTimeStep > = 0 )
{
b3PhysicsParamSetTimeStep ( command , fixedTimeStep ) ;
}
if ( useSplitImpulse > = 0 )
{
b3PhysicsParamSetUseSplitImpulse ( command , useSplitImpulse ) ;
}
if ( splitImpulsePenetrationThreshold > = 0 )
{
b3PhysicsParamSetSplitImpulsePenetrationThreshold ( command , splitImpulsePenetrationThreshold ) ;
}
//ret = b3PhysicsParamSetRealTimeSimulation(command, enableRealTimeSimulation);
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
}
#if 0
b3SharedMemoryCommandHandle b3InitPhysicsParamCommand ( b3PhysicsClientHandle physClient ) ;
int b3PhysicsParamSetGravity ( b3SharedMemoryCommandHandle commandHandle , double gravx , double gravy , double gravz ) ;
int b3PhysicsParamSetTimeStep ( b3SharedMemoryCommandHandle commandHandle , double timeStep ) ;
int b3PhysicsParamSetDefaultContactERP ( b3SharedMemoryCommandHandle commandHandle , double defaultContactERP ) ;
int b3PhysicsParamSetNumSubSteps ( b3SharedMemoryCommandHandle commandHandle , int numSubSteps ) ;
int b3PhysicsParamSetRealTimeSimulation ( b3SharedMemoryCommandHandle commandHandle , int enableRealTimeSimulation ) ;
int b3PhysicsParamSetNumSolverIterations ( b3SharedMemoryCommandHandle commandHandle , int numSolverIterations ) ;
# endif
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-11 22:44:50 +00:00
// Load a robot from a URDF file (universal robot description format)
2016-06-10 22:07:41 +00:00
// function can be called without arguments and will default
// to position (0,0,1) with orientation(0,0,0,1)
2016-06-15 21:21:04 +00:00
// els(x,y,z) or
2016-06-10 22:07:41 +00:00
// loadURDF(pos_x, pos_y, pos_z, orn_x, orn_y, orn_z, orn_w)
2016-12-01 06:24:20 +00:00
static PyObject * pybullet_loadURDF ( PyObject * self , PyObject * args , PyObject * keywds )
{
2016-09-08 18:12:58 +00:00
int size = PySequence_Size ( args ) ;
2016-12-01 06:24:20 +00:00
static char * kwlist [ ] = { " fileName " , " basePosition " , " baseOrientation " , " useMaximalCoordinates " , " useFixedBase " , NULL } ;
2016-12-01 17:51:28 +00:00
static char * kwlistBackwardCompatible4 [ ] = { " fileName " , " startPosX " , " startPosY " , " startPosZ " , NULL } ;
static char * kwlistBackwardCompatible8 [ ] = { " fileName " , " startPosX " , " startPosY " , " startPosZ " , " startOrnX " , " startOrnY " , " startOrnZ " , " startOrnW " , NULL } ;
2016-12-01 06:24:20 +00:00
2016-06-10 22:07:41 +00:00
2016-09-08 18:12:58 +00:00
int bodyIndex = - 1 ;
const char * urdfFileName = " " ;
2016-06-10 22:07:41 +00:00
2016-09-08 18:12:58 +00:00
double startPosX = 0.0 ;
double startPosY = 0.0 ;
double startPosZ = 0.0 ;
double startOrnX = 0.0 ;
double startOrnY = 0.0 ;
double startOrnZ = 0.0 ;
double startOrnW = 1.0 ;
2016-12-01 06:24:20 +00:00
int useMaximalCoordinates = 0 ;
int useFixedBase = 0 ;
int backwardsCompatibilityArgs = 0 ;
2016-09-08 18:12:58 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-12-01 06:24:20 +00:00
if ( PyArg_ParseTupleAndKeywords ( args , keywds , " sddd " , kwlistBackwardCompatible4 , & urdfFileName , & startPosX ,
& startPosY , & startPosZ ) )
{
backwardsCompatibilityArgs = 1 ;
2016-09-08 18:12:58 +00:00
}
2016-12-01 06:24:20 +00:00
else
{
PyErr_Clear ( ) ;
2016-09-08 18:12:58 +00:00
}
2016-12-01 06:24:20 +00:00
if ( PyArg_ParseTupleAndKeywords ( args , keywds , " sddddddd " , kwlistBackwardCompatible8 , & urdfFileName , & startPosX ,
& startPosY , & startPosZ , & startOrnX , & startOrnY , & startOrnZ , & startOrnW ) )
{
backwardsCompatibilityArgs = 1 ;
}
else
{
PyErr_Clear ( ) ;
}
if ( ! backwardsCompatibilityArgs )
{
PyObject * basePosObj = 0 ;
PyObject * baseOrnObj = 0 ;
double basePos [ 3 ] ;
double baseOrn [ 4 ] ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " s|OOii " , kwlist , & urdfFileName , & basePosObj , & baseOrnObj , & useMaximalCoordinates , & useFixedBase ) )
{
return NULL ;
}
else
{
if ( basePosObj )
{
if ( ! pybullet_internalSetVectord ( basePosObj , basePos ) )
{
PyErr_SetString ( SpamError , " Cannot convert basePosition. " ) ;
return NULL ;
}
startPosX = basePos [ 0 ] ;
startPosY = basePos [ 1 ] ;
startPosZ = basePos [ 2 ] ;
}
if ( baseOrnObj )
{
if ( ! pybullet_internalSetVector4d ( baseOrnObj , baseOrn ) )
{
PyErr_SetString ( SpamError , " Cannot convert baseOrientation. " ) ;
return NULL ;
}
startOrnX = baseOrn [ 0 ] ;
startOrnY = baseOrn [ 1 ] ;
startOrnZ = baseOrn [ 2 ] ;
startOrnW = baseOrn [ 3 ] ;
}
}
2016-09-08 18:12:58 +00:00
}
if ( strlen ( urdfFileName ) ) {
// printf("(%f, %f, %f) (%f, %f, %f, %f)\n",
// startPosX,startPosY,startPosZ,startOrnX, startOrnY,startOrnZ, startOrnW);
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
b3SharedMemoryCommandHandle command =
b3LoadUrdfCommandInit ( sm , urdfFileName ) ;
// setting the initial position, orientation and other arguments are
// optional
b3LoadUrdfCommandSetStartPosition ( command , startPosX , startPosY , startPosZ ) ;
b3LoadUrdfCommandSetStartOrientation ( command , startOrnX , startOrnY ,
startOrnZ , startOrnW ) ;
2016-12-01 06:24:20 +00:00
if ( useMaximalCoordinates )
{
b3LoadUrdfCommandSetUseMultiBody ( command , 0 ) ;
}
if ( useFixedBase )
{
b3LoadUrdfCommandSetUseFixedBase ( command , 1 ) ;
}
2016-09-08 18:12:58 +00:00
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType ! = CMD_URDF_LOADING_COMPLETED ) {
PyErr_SetString ( SpamError , " Cannot load URDF file. " ) ;
return NULL ;
2016-06-17 01:46:34 +00:00
}
2016-09-08 18:12:58 +00:00
bodyIndex = b3GetStatusBodyIndex ( statusHandle ) ;
} else {
PyErr_SetString ( SpamError ,
" Empty filename, method expects 1, 4 or 8 arguments. " ) ;
return NULL ;
}
return PyLong_FromLong ( bodyIndex ) ;
2016-06-17 01:46:34 +00:00
}
2016-11-14 15:39:34 +00:00
2016-06-13 17:11:28 +00:00
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_loadSDF ( PyObject * self , PyObject * args ) {
const char * sdfFileName = " " ;
int size = PySequence_Size ( args ) ;
int numBodies = 0 ;
int i ;
int bodyIndicesOut [ MAX_SDF_BODIES ] ;
PyObject * pylist = 0 ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
b3SharedMemoryCommandHandle commandHandle ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( size = = 1 ) {
if ( ! PyArg_ParseTuple ( args , " s " , & sdfFileName ) ) return NULL ;
}
commandHandle = b3LoadSdfCommandInit ( sm , sdfFileName ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType ! = CMD_SDF_LOADING_COMPLETED ) {
PyErr_SetString ( SpamError , " Cannot load SDF file. " ) ;
return NULL ;
}
numBodies =
b3GetStatusBodyIndices ( statusHandle , bodyIndicesOut , MAX_SDF_BODIES ) ;
if ( numBodies > MAX_SDF_BODIES ) {
PyErr_SetString ( SpamError , " SDF exceeds body capacity " ) ;
return NULL ;
}
pylist = PyTuple_New ( numBodies ) ;
if ( numBodies > 0 & & numBodies < = MAX_SDF_BODIES ) {
for ( i = 0 ; i < numBodies ; i + + ) {
PyTuple_SetItem ( pylist , i , PyInt_FromLong ( bodyIndicesOut [ i ] ) ) ;
}
}
return pylist ;
2016-06-13 17:11:28 +00:00
}
2016-06-10 22:07:41 +00:00
// Reset the simulation to remove all loaded objects
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_resetSimulation ( PyObject * self , PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-05-03 19:59:21 +00:00
2016-09-08 18:12:58 +00:00
{
b3SharedMemoryStatusHandle statusHandle ;
statusHandle = b3SubmitClientCommandAndWaitStatus (
sm , b3InitResetSimulationCommand ( sm ) ) ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-05-10 07:57:54 +00:00
}
2016-05-04 06:34:48 +00:00
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_setJointMotorControl ( PyObject * self , PyObject * args ) {
int size ;
int bodyIndex , jointIndex , controlMode ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
double targetPosition = 0.0 ;
double targetVelocity = 0.0 ;
double maxForce = 100000.0 ;
double appliedForce = 0.0 ;
double kp = 0.1 ;
double kd = 1.0 ;
int valid = 0 ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
size = PySequence_Size ( args ) ;
if ( size = = 4 ) {
double targetValue = 0.0 ;
// see switch statement below for convertsions dependent on controlMode
if ( ! PyArg_ParseTuple ( args , " iiid " , & bodyIndex , & jointIndex , & controlMode ,
& targetValue ) ) {
PyErr_SetString ( SpamError , " Error parsing arguments " ) ;
return NULL ;
2016-06-17 01:46:34 +00:00
}
2016-09-08 18:12:58 +00:00
valid = 1 ;
switch ( controlMode ) {
case CONTROL_MODE_POSITION_VELOCITY_PD : {
targetPosition = targetValue ;
break ;
}
case CONTROL_MODE_VELOCITY : {
targetVelocity = targetValue ;
break ;
}
case CONTROL_MODE_TORQUE : {
appliedForce = targetValue ;
break ;
}
default : { valid = 0 ; }
2016-06-17 01:46:34 +00:00
}
2016-09-08 18:12:58 +00:00
}
if ( size = = 5 ) {
double targetValue = 0.0 ;
// See switch statement for conversions
if ( ! PyArg_ParseTuple ( args , " iiidd " , & bodyIndex , & jointIndex , & controlMode ,
& targetValue , & maxForce ) ) {
PyErr_SetString ( SpamError , " Error parsing arguments " ) ;
return NULL ;
}
valid = 1 ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
switch ( controlMode ) {
case CONTROL_MODE_POSITION_VELOCITY_PD : {
targetPosition = targetValue ;
break ;
}
case CONTROL_MODE_VELOCITY : {
targetVelocity = targetValue ;
break ;
}
case CONTROL_MODE_TORQUE : {
valid = 0 ;
break ;
}
default : { valid = 0 ; }
2016-06-24 18:06:56 +00:00
}
2016-09-08 18:12:58 +00:00
}
if ( size = = 6 ) {
double gain = 0.0 ;
double targetValue = 0.0 ;
if ( ! PyArg_ParseTuple ( args , " iiiddd " , & bodyIndex , & jointIndex , & controlMode ,
& targetValue , & maxForce , & gain ) ) {
PyErr_SetString ( SpamError , " Error parsing arguments " ) ;
return NULL ;
2016-06-24 18:06:56 +00:00
}
2016-09-08 18:12:58 +00:00
valid = 1 ;
switch ( controlMode ) {
case CONTROL_MODE_POSITION_VELOCITY_PD : {
targetPosition = targetValue ;
kp = gain ;
break ;
}
case CONTROL_MODE_VELOCITY : {
targetVelocity = targetValue ;
kd = gain ;
break ;
}
case CONTROL_MODE_TORQUE : {
valid = 0 ;
break ;
}
default : { valid = 0 ; }
2016-07-26 18:36:34 +00:00
}
2016-09-08 18:12:58 +00:00
}
if ( size = = 8 ) {
// only applicable for CONTROL_MODE_POSITION_VELOCITY_PD.
if ( ! PyArg_ParseTuple ( args , " iiiddddd " , & bodyIndex , & jointIndex ,
& controlMode , & targetPosition , & targetVelocity ,
& maxForce , & kp , & kd ) ) {
PyErr_SetString ( SpamError , " Error parsing arguments " ) ;
return NULL ;
2016-06-24 18:06:56 +00:00
}
2016-09-08 18:12:58 +00:00
valid = 1 ;
}
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
if ( valid ) {
int numJoints ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
struct b3JointInfo info ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
numJoints = b3GetNumJoints ( sm , bodyIndex ) ;
if ( ( jointIndex > = numJoints ) | | ( jointIndex < 0 ) ) {
PyErr_SetString ( SpamError , " Joint index out-of-range. " ) ;
return NULL ;
}
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
if ( ( controlMode ! = CONTROL_MODE_VELOCITY ) & &
( controlMode ! = CONTROL_MODE_TORQUE ) & &
( controlMode ! = CONTROL_MODE_POSITION_VELOCITY_PD ) ) {
PyErr_SetString ( SpamError , " Illegral control mode. " ) ;
return NULL ;
}
2016-06-24 14:31:17 +00:00
2016-09-08 18:12:58 +00:00
commandHandle = b3JointControlCommandInit2 ( sm , bodyIndex , controlMode ) ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
b3GetJointInfo ( sm , bodyIndex , jointIndex , & info ) ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
switch ( controlMode ) {
case CONTROL_MODE_VELOCITY : {
b3JointControlSetDesiredVelocity ( commandHandle , info . m_uIndex ,
targetVelocity ) ;
b3JointControlSetKd ( commandHandle , info . m_uIndex , kd ) ;
b3JointControlSetMaximumForce ( commandHandle , info . m_uIndex , maxForce ) ;
break ;
}
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
case CONTROL_MODE_TORQUE : {
b3JointControlSetDesiredForceTorque ( commandHandle , info . m_uIndex ,
appliedForce ) ;
break ;
}
2016-06-24 18:06:56 +00:00
2016-09-08 18:12:58 +00:00
case CONTROL_MODE_POSITION_VELOCITY_PD : {
b3JointControlSetDesiredPosition ( commandHandle , info . m_qIndex ,
targetPosition ) ;
b3JointControlSetKp ( commandHandle , info . m_uIndex , kp ) ;
b3JointControlSetDesiredVelocity ( commandHandle , info . m_uIndex ,
targetVelocity ) ;
b3JointControlSetKd ( commandHandle , info . m_uIndex , kd ) ;
b3JointControlSetMaximumForce ( commandHandle , info . m_uIndex , maxForce ) ;
break ;
}
default : { }
} ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
PyErr_SetString ( SpamError , " Error parsing arguments in setJointControl. " ) ;
return NULL ;
}
2016-07-26 18:09:12 +00:00
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_setRealTimeSimulation ( PyObject * self ,
PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
2016-06-17 01:46:34 +00:00
return NULL ;
2016-09-08 18:12:58 +00:00
}
2016-06-17 01:46:34 +00:00
2016-09-08 18:12:58 +00:00
{
int enableRealTimeSimulation = 0 ;
int ret ;
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand ( sm ) ;
b3SharedMemoryStatusHandle statusHandle ;
2016-07-18 06:50:11 +00:00
2016-09-08 18:12:58 +00:00
if ( ! PyArg_ParseTuple ( args , " i " , & enableRealTimeSimulation ) ) {
PyErr_SetString (
SpamError ,
" setRealTimeSimulation expected a single value (integer). " ) ;
return NULL ;
2016-06-17 01:46:34 +00:00
}
2016-09-08 18:12:58 +00:00
ret =
b3PhysicsParamSetRealTimeSimulation ( command , enableRealTimeSimulation ) ;
2016-07-18 06:50:11 +00:00
2016-09-08 18:12:58 +00:00
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
// ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED);
}
2016-07-18 06:50:11 +00:00
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-07-18 06:50:11 +00:00
}
2016-10-23 14:14:50 +00:00
static PyObject * pybullet_setInternalSimFlags ( PyObject * self ,
PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int enableRealTimeSimulation = 0 ;
int ret ;
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand ( sm ) ;
b3SharedMemoryStatusHandle statusHandle ;
if ( ! PyArg_ParseTuple ( args , " i " , & enableRealTimeSimulation ) ) {
PyErr_SetString (
SpamError ,
" setInternalSimFlags expected a single value (integer). " ) ;
return NULL ;
}
ret =
b3PhysicsParamSetInternalSimFlags ( command , enableRealTimeSimulation ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
// ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED);
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-06-10 22:07:41 +00:00
// Set the gravity of the world with (x, y, z) arguments
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_setGravity ( PyObject * self , PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-05-10 07:57:54 +00:00
2016-09-08 18:12:58 +00:00
{
double gravX = 0.0 ;
double gravY = 0.0 ;
double gravZ = - 10.0 ;
int ret ;
2016-05-24 22:29:26 +00:00
2016-09-08 18:12:58 +00:00
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand ( sm ) ;
b3SharedMemoryStatusHandle statusHandle ;
2016-07-18 06:50:11 +00:00
2016-09-08 18:12:58 +00:00
if ( ! PyArg_ParseTuple ( args , " ddd " , & gravX , & gravY , & gravZ ) ) {
PyErr_SetString ( SpamError , " setGravity expected (x,y,z) values. " ) ;
return NULL ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
ret = b3PhysicsParamSetGravity ( command , gravX , gravY , gravZ ) ;
// ret = b3PhysicsParamSetTimeStep(command, timeStep);
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
// ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED);
}
2016-05-10 07:57:54 +00:00
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-05-24 22:29:26 +00:00
}
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_setTimeStep ( PyObject * self , PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
double timeStep = 0.001 ;
int ret ;
2016-06-27 01:18:30 +00:00
2016-09-08 22:22:41 +00:00
2016-09-08 18:12:58 +00:00
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand ( sm ) ;
b3SharedMemoryStatusHandle statusHandle ;
2016-05-24 22:29:26 +00:00
2016-09-08 18:12:58 +00:00
if ( ! PyArg_ParseTuple ( args , " d " , & timeStep ) ) {
PyErr_SetString ( SpamError ,
" setTimeStep expected a single value (double). " ) ;
return NULL ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
ret = b3PhysicsParamSetTimeStep ( command , timeStep ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
// ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED);
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 22:15:58 +00:00
static PyObject *
pybullet_setDefaultContactERP ( PyObject * self , PyObject * args )
{
if ( 0 = = sm )
{
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
double defaultContactERP = 0.005 ;
int ret ;
b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand ( sm ) ;
b3SharedMemoryStatusHandle statusHandle ;
if ( ! PyArg_ParseTuple ( args , " d " , & defaultContactERP ) )
{
PyErr_SetString ( SpamError , " default Contact ERP expected a single value (double). " ) ;
return NULL ;
}
ret = b3PhysicsParamSetDefaultContactERP ( command , defaultContactERP ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-28 23:11:34 +00:00
static int pybullet_internalGetBaseVelocity (
int bodyIndex , double baseLinearVelocity [ 3 ] , double baseAngularVelocity [ 3 ] ) {
baseLinearVelocity [ 0 ] = 0. ;
baseLinearVelocity [ 1 ] = 0. ;
baseLinearVelocity [ 2 ] = 0. ;
baseAngularVelocity [ 0 ] = 0. ;
baseAngularVelocity [ 1 ] = 0. ;
baseAngularVelocity [ 2 ] = 0. ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return 0 ;
}
{
{
b3SharedMemoryCommandHandle cmd_handle =
b3RequestActualStateCommandInit ( sm , bodyIndex ) ;
b3SharedMemoryStatusHandle status_handle =
b3SubmitClientCommandAndWaitStatus ( sm , cmd_handle ) ;
const int status_type = b3GetStatusType ( status_handle ) ;
const double * actualStateQdot ;
// const double* jointReactionForces[];
if ( status_type ! = CMD_ACTUAL_STATE_UPDATE_COMPLETED ) {
PyErr_SetString ( SpamError , " getBaseVelocity failed. " ) ;
return 0 ;
}
b3GetStatusActualState (
status_handle , 0 /* body_unique_id */ ,
0 /* num_degree_of_freedom_q */ , 0 /* num_degree_of_freedom_u */ ,
0 /*root_local_inertial_frame*/ , 0 ,
& actualStateQdot , 0 /* joint_reaction_forces */ ) ;
// printf("joint reaction forces=");
// for (i=0; i < (sizeof(jointReactionForces)/sizeof(double)); i++) {
// printf("%f ", jointReactionForces[i]);
// }
// now, position x,y,z = actualStateQ[0],actualStateQ[1],actualStateQ[2]
// and orientation x,y,z,w =
// actualStateQ[3],actualStateQ[4],actualStateQ[5],actualStateQ[6]
baseLinearVelocity [ 0 ] = actualStateQdot [ 0 ] ;
baseLinearVelocity [ 1 ] = actualStateQdot [ 1 ] ;
baseLinearVelocity [ 2 ] = actualStateQdot [ 2 ] ;
baseAngularVelocity [ 0 ] = actualStateQdot [ 3 ] ;
baseAngularVelocity [ 1 ] = actualStateQdot [ 4 ] ;
baseAngularVelocity [ 2 ] = actualStateQdot [ 5 ] ;
}
}
return 1 ;
}
2016-05-24 22:29:26 +00:00
2016-06-10 22:07:41 +00:00
// Internal function used to get the base position and orientation
// Orientation is returned in quaternions
2016-09-08 18:12:58 +00:00
static int pybullet_internalGetBasePositionAndOrientation (
2016-11-28 23:11:34 +00:00
int bodyIndex , double basePosition [ 3 ] , double baseOrientation [ 4 ] ) {
2016-09-08 18:12:58 +00:00
basePosition [ 0 ] = 0. ;
basePosition [ 1 ] = 0. ;
basePosition [ 2 ] = 0. ;
baseOrientation [ 0 ] = 0. ;
baseOrientation [ 1 ] = 0. ;
baseOrientation [ 2 ] = 0. ;
baseOrientation [ 3 ] = 1. ;
2016-11-10 05:01:04 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
2016-11-10 19:22:22 +00:00
return 0 ;
2016-11-10 05:01:04 +00:00
}
2016-09-08 18:12:58 +00:00
{
{
b3SharedMemoryCommandHandle cmd_handle =
b3RequestActualStateCommandInit ( sm , bodyIndex ) ;
b3SharedMemoryStatusHandle status_handle =
b3SubmitClientCommandAndWaitStatus ( sm , cmd_handle ) ;
const int status_type = b3GetStatusType ( status_handle ) ;
const double * actualStateQ ;
// const double* jointReactionForces[];
2016-09-27 19:13:45 +00:00
2016-09-08 18:12:58 +00:00
if ( status_type ! = CMD_ACTUAL_STATE_UPDATE_COMPLETED ) {
PyErr_SetString ( SpamError , " getBasePositionAndOrientation failed. " ) ;
return 0 ;
}
b3GetStatusActualState (
status_handle , 0 /* body_unique_id */ ,
0 /* num_degree_of_freedom_q */ , 0 /* num_degree_of_freedom_u */ ,
0 /*root_local_inertial_frame*/ , & actualStateQ ,
0 /* actual_state_q_dot */ , 0 /* joint_reaction_forces */ ) ;
// printf("joint reaction forces=");
// for (i=0; i < (sizeof(jointReactionForces)/sizeof(double)); i++) {
// printf("%f ", jointReactionForces[i]);
// }
// now, position x,y,z = actualStateQ[0],actualStateQ[1],actualStateQ[2]
// and orientation x,y,z,w =
// actualStateQ[3],actualStateQ[4],actualStateQ[5],actualStateQ[6]
basePosition [ 0 ] = actualStateQ [ 0 ] ;
basePosition [ 1 ] = actualStateQ [ 1 ] ;
basePosition [ 2 ] = actualStateQ [ 2 ] ;
baseOrientation [ 0 ] = actualStateQ [ 3 ] ;
baseOrientation [ 1 ] = actualStateQ [ 4 ] ;
baseOrientation [ 2 ] = actualStateQ [ 5 ] ;
baseOrientation [ 3 ] = actualStateQ [ 6 ] ;
}
}
return 1 ;
2016-05-24 22:29:26 +00:00
}
2016-05-10 07:57:54 +00:00
2016-06-10 22:07:41 +00:00
// Get the positions (x,y,z) and orientation (x,y,z,w) in quaternion
// values for the base link of your object
// Object is retrieved based on body index, which is the order
// the object was loaded into the simulation (0-based)
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_getBasePositionAndOrientation ( PyObject * self ,
PyObject * args ) {
int bodyIndex = - 1 ;
double basePosition [ 3 ] ;
double baseOrientation [ 4 ] ;
PyObject * pylistPos ;
PyObject * pylistOrientation ;
2016-06-13 17:11:28 +00:00
2016-09-08 18:12:58 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-06-14 21:08:24 +00:00
2016-09-08 18:12:58 +00:00
if ( ! PyArg_ParseTuple ( args , " i " , & bodyIndex ) ) {
PyErr_SetString ( SpamError , " Expected a body index (integer). " ) ;
return NULL ;
}
2016-06-13 17:11:28 +00:00
2016-09-08 18:12:58 +00:00
if ( 0 = = pybullet_internalGetBasePositionAndOrientation (
bodyIndex , basePosition , baseOrientation ) ) {
PyErr_SetString ( SpamError ,
2016-11-28 23:11:34 +00:00
" GetBasePositionAndOrientation failed. " ) ;
2016-09-08 18:12:58 +00:00
return NULL ;
}
{
PyObject * item ;
int i ;
int num = 3 ;
pylistPos = PyTuple_New ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
item = PyFloat_FromDouble ( basePosition [ i ] ) ;
PyTuple_SetItem ( pylistPos , i , item ) ;
2016-05-24 22:29:26 +00:00
}
2016-09-08 18:12:58 +00:00
}
{
PyObject * item ;
int i ;
int num = 4 ;
pylistOrientation = PyTuple_New ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
item = PyFloat_FromDouble ( baseOrientation [ i ] ) ;
PyTuple_SetItem ( pylistOrientation , i , item ) ;
2016-05-24 22:29:26 +00:00
}
2016-09-08 18:12:58 +00:00
}
{
PyObject * pylist ;
pylist = PyTuple_New ( 2 ) ;
PyTuple_SetItem ( pylist , 0 , pylistPos ) ;
PyTuple_SetItem ( pylist , 1 , pylistOrientation ) ;
return pylist ;
}
2016-05-03 19:59:21 +00:00
}
2016-04-30 18:18:54 +00:00
2016-11-28 23:11:34 +00:00
static PyObject * pybullet_getBaseVelocity ( PyObject * self ,
PyObject * args ) {
int bodyIndex = - 1 ;
double baseLinearVelocity [ 3 ] ;
double baseAngularVelocity [ 3 ] ;
PyObject * pylistLinVel = 0 ;
PyObject * pylistAngVel = 0 ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTuple ( args , " i " , & bodyIndex ) ) {
PyErr_SetString ( SpamError , " Expected a body index (integer). " ) ;
return NULL ;
}
if ( 0 = = pybullet_internalGetBaseVelocity (
bodyIndex , baseLinearVelocity , baseAngularVelocity ) ) {
PyErr_SetString ( SpamError ,
" getBaseVelocity failed. " ) ;
return NULL ;
}
{
PyObject * item ;
int i ;
int num = 3 ;
pylistLinVel = PyTuple_New ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
item = PyFloat_FromDouble ( baseLinearVelocity [ i ] ) ;
PyTuple_SetItem ( pylistLinVel , i , item ) ;
}
}
{
PyObject * item ;
int i ;
int num = 3 ;
pylistAngVel = PyTuple_New ( num ) ;
for ( i = 0 ; i < num ; i + + ) {
item = PyFloat_FromDouble ( baseAngularVelocity [ i ] ) ;
PyTuple_SetItem ( pylistAngVel , i , item ) ;
}
}
{
PyObject * pylist ;
pylist = PyTuple_New ( 2 ) ;
PyTuple_SetItem ( pylist , 0 , pylistLinVel ) ;
PyTuple_SetItem ( pylist , 1 , pylistAngVel ) ;
return pylist ;
}
}
2016-09-27 19:13:45 +00:00
static PyObject * pybullet_getNumBodies ( PyObject * self , PyObject * args )
{
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int numBodies = b3GetNumBodies ( sm ) ;
# if PY_MAJOR_VERSION >= 3
return PyLong_FromLong ( numBodies ) ;
# else
return PyInt_FromLong ( numBodies ) ;
# endif
}
}
static PyObject * pybullet_getBodyUniqueId ( PyObject * self , PyObject * args )
{
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int serialIndex = - 1 ;
int bodyUniqueId = - 1 ;
if ( ! PyArg_ParseTuple ( args , " i " , & serialIndex ) ) {
PyErr_SetString ( SpamError , " Expected a serialIndex in range [0..number of bodies). " ) ;
return NULL ;
}
bodyUniqueId = b3GetBodyUniqueId ( sm , serialIndex ) ;
# if PY_MAJOR_VERSION >= 3
return PyLong_FromLong ( bodyUniqueId ) ;
# else
return PyInt_FromLong ( bodyUniqueId ) ;
# endif
}
}
static PyObject * pybullet_getBodyInfo ( PyObject * self , PyObject * args )
{
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int bodyUniqueId = - 1 ;
int numJoints = 0 ;
if ( ! PyArg_ParseTuple ( args , " i " , & bodyUniqueId ) )
{
PyErr_SetString ( SpamError , " Expected a body unique id (integer). " ) ;
return NULL ;
}
{
struct b3BodyInfo info ;
if ( b3GetBodyInfo ( sm , bodyUniqueId , & info ) )
{
PyObject * pyListJointInfo = PyTuple_New ( 1 ) ;
PyTuple_SetItem ( pyListJointInfo , 0 , PyString_FromString ( info . m_baseName ) ) ;
return pyListJointInfo ;
} else
{
PyErr_SetString ( SpamError , " Couldn't get body info " ) ;
return NULL ;
}
}
}
PyErr_SetString ( SpamError , " error in getBodyInfo. " ) ;
return NULL ;
}
2016-06-10 22:07:41 +00:00
// Return the number of joints in an object based on
// body index; body index is based on order of sequence
// the object is loaded into simulation
2016-09-27 19:13:45 +00:00
static PyObject * pybullet_getNumJoints ( PyObject * self , PyObject * args )
{
2016-09-08 18:12:58 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-05-10 07:57:54 +00:00
2016-09-08 18:12:58 +00:00
{
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 ) ;
2016-05-10 07:57:54 +00:00
# if PY_MAJOR_VERSION >= 3
2016-09-08 18:12:58 +00:00
return PyLong_FromLong ( numJoints ) ;
2016-05-10 07:57:54 +00:00
# else
2016-09-08 18:12:58 +00:00
return PyInt_FromLong ( numJoints ) ;
2016-05-10 07:57:54 +00:00
# endif
2016-09-08 18:12:58 +00:00
}
2016-05-10 07:57:54 +00:00
}
2016-06-14 21:58:36 +00:00
// Initalize all joint positions given a list of values
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_resetJointState ( PyObject * self , PyObject * args ) {
int size ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-06-23 06:21:47 +00:00
2016-09-08 18:12:58 +00:00
size = PySequence_Size ( args ) ;
2016-06-23 06:21:47 +00:00
2016-09-08 18:12:58 +00:00
if ( size = = 3 ) {
int bodyIndex ;
int jointIndex ;
double targetValue ;
2016-06-23 06:21:47 +00:00
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " iid " , & bodyIndex , & jointIndex , & targetValue ) ) {
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int numJoints ;
2016-06-14 21:58:36 +00:00
2016-09-08 18:12:58 +00:00
numJoints = b3GetNumJoints ( sm , bodyIndex ) ;
if ( ( jointIndex > = numJoints ) | | ( jointIndex < 0 ) ) {
PyErr_SetString ( SpamError , " Joint index out-of-range. " ) ;
2016-06-15 21:21:04 +00:00
return NULL ;
2016-09-08 18:12:58 +00:00
}
commandHandle = b3CreatePoseCommandInit ( sm , bodyIndex ) ;
b3CreatePoseCommandSetJointPosition ( sm , commandHandle , jointIndex ,
targetValue ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-06-15 21:21:04 +00:00
}
2016-09-08 18:12:58 +00:00
}
PyErr_SetString ( SpamError , " error in resetJointState. " ) ;
return NULL ;
}
2016-06-15 21:21:04 +00:00
2016-11-28 23:11:34 +00:00
static PyObject * pybullet_resetBaseVelocity ( PyObject * self , PyObject * args , PyObject * keywds )
{
static char * kwlist [ ] = { " objectUniqueId " , " linearVelocity " , " angularVelocity " , NULL } ;
if ( 0 = = sm )
{
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int bodyIndex = 0 ;
PyObject * linVelObj = 0 ;
PyObject * angVelObj = 0 ;
double linVel [ 3 ] = { 0 , 0 , 0 } ;
double angVel [ 3 ] = { 0 , 0 , 0 } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " i|OO " , kwlist , & bodyIndex , & linVelObj , & angVelObj ) )
{
return NULL ;
}
if ( linVelObj | | angVelObj )
{
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
commandHandle = b3CreatePoseCommandInit ( sm , bodyIndex ) ;
if ( linVelObj )
{
pybullet_internalSetVectord ( linVelObj , linVel ) ;
b3CreatePoseCommandSetBaseLinearVelocity ( commandHandle , linVel ) ;
}
if ( angVelObj )
{
pybullet_internalSetVectord ( angVelObj , angVel ) ;
b3CreatePoseCommandSetBaseAngularVelocity ( commandHandle , angVel ) ;
}
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
else
{
PyErr_SetString ( SpamError , " expected at least linearVelocity and/or angularVelocity. " ) ;
return NULL ;
}
}
PyErr_SetString ( SpamError , " error in resetJointState. " ) ;
return NULL ;
}
2016-09-08 18:12:58 +00:00
// Reset the position and orientation of the base/root link, position [x,y,z]
// and orientation quaternion [x,y,z,w]
static PyObject * pybullet_resetBasePositionAndOrientation ( PyObject * self ,
PyObject * args ) {
int size ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
size = PySequence_Size ( args ) ;
if ( size = = 3 ) {
int bodyIndex ;
PyObject * posObj ;
PyObject * ornObj ;
double pos [ 3 ] ;
double orn [ 4 ] ; // as a quaternion
if ( PyArg_ParseTuple ( args , " iOO " , & bodyIndex , & posObj , & ornObj ) ) {
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
{
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( posObj , " expected a sequence " ) ;
len = PySequence_Size ( posObj ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < 3 ; i + + ) {
pos [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
} else {
PyErr_SetString ( SpamError , " position needs a 3 coordinates [x,y,z]. " ) ;
Py_DECREF ( seq ) ;
return NULL ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
Py_DECREF ( seq ) ;
}
{
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( ornObj , " expected a sequence " ) ;
len = PySequence_Size ( ornObj ) ;
if ( len = = 4 ) {
for ( i = 0 ; i < 4 ; i + + ) {
orn [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
} else {
PyErr_SetString (
SpamError ,
" orientation needs a 4 coordinates, quaternion [x,y,z,w]. " ) ;
Py_DECREF ( seq ) ;
return NULL ;
}
Py_DECREF ( seq ) ;
}
commandHandle = b3CreatePoseCommandInit ( sm , bodyIndex ) ;
b3CreatePoseCommandSetBasePosition ( commandHandle , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
b3CreatePoseCommandSetBaseOrientation ( commandHandle , orn [ 0 ] , orn [ 1 ] ,
orn [ 2 ] , orn [ 3 ] ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-06-15 21:21:04 +00:00
}
2016-09-08 18:12:58 +00:00
}
PyErr_SetString ( SpamError , " error in resetJointState. " ) ;
return NULL ;
2016-06-14 21:08:24 +00:00
}
2016-06-27 01:18:30 +00:00
2016-06-14 21:58:36 +00:00
// Get the a single joint info for a specific bodyIndex
//
2016-06-15 21:21:04 +00:00
// Args:
// bodyIndex - integer indicating body in simulation
// jointIndex - integer indicating joint for a specific body
//
2016-06-14 21:58:36 +00:00
// Joint information includes:
// index, name, type, q-index, u-index,
// flags, joint damping, joint friction
//
2016-09-08 18:12:58 +00:00
// The format of the returned list is
2016-06-14 21:58:36 +00:00
// [int, str, int, int, int, int, float, float]
//
2016-06-14 21:08:24 +00:00
// TODO(hellojas): get joint positions for a body
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_getJointInfo ( PyObject * self , PyObject * args ) {
PyObject * pyListJointInfo ;
2016-06-14 21:35:45 +00:00
struct b3JointInfo info ;
2016-09-08 18:12:58 +00:00
2016-06-14 21:35:45 +00:00
int bodyIndex = - 1 ;
int jointIndex = - 1 ;
2016-09-08 18:12:58 +00:00
int jointInfoSize = 8 ; // size of struct b3JointInfo
2016-06-24 14:31:17 +00:00
2016-09-08 18:12:58 +00:00
int size = PySequence_Size ( args ) ;
2016-06-24 14:31:17 +00:00
2016-09-08 18:12:58 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-06-24 14:31:17 +00:00
2016-09-08 18:12:58 +00:00
if ( size = = 2 ) // get body index and joint index
2016-06-14 21:35:45 +00:00
{
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " ii " , & bodyIndex , & jointIndex ) ) {
2016-06-14 21:35:45 +00:00
// printf("body index = %d, joint index =%d\n", bodyIndex, jointIndex);
2016-09-08 18:12:58 +00:00
pyListJointInfo = PyTuple_New ( jointInfoSize ) ;
if ( b3GetJointInfo ( sm , bodyIndex , jointIndex , & info ) ) {
// printf("Joint%d %s, type %d, at q-index %d and u-index %d\n",
// info.m_jointIndex,
// info.m_jointName,
// info.m_jointType,
// info.m_qIndex,
// info.m_uIndex);
// printf(" flags=%d jointDamping=%f jointFriction=%f\n",
// info.m_flags,
// info.m_jointDamping,
// info.m_jointFriction);
PyTuple_SetItem ( pyListJointInfo , 0 , PyInt_FromLong ( info . m_jointIndex ) ) ;
PyTuple_SetItem ( pyListJointInfo , 1 ,
PyString_FromString ( info . m_jointName ) ) ;
PyTuple_SetItem ( pyListJointInfo , 2 , PyInt_FromLong ( info . m_jointType ) ) ;
PyTuple_SetItem ( pyListJointInfo , 3 , PyInt_FromLong ( info . m_qIndex ) ) ;
PyTuple_SetItem ( pyListJointInfo , 4 , PyInt_FromLong ( info . m_uIndex ) ) ;
PyTuple_SetItem ( pyListJointInfo , 5 , PyInt_FromLong ( info . m_flags ) ) ;
PyTuple_SetItem ( pyListJointInfo , 6 ,
PyFloat_FromDouble ( info . m_jointDamping ) ) ;
PyTuple_SetItem ( pyListJointInfo , 7 ,
PyFloat_FromDouble ( info . m_jointFriction ) ) ;
return pyListJointInfo ;
} else {
PyErr_SetString ( SpamError , " GetJointInfo failed. " ) ;
return NULL ;
}
2016-06-14 21:35:45 +00:00
}
}
2016-06-14 21:08:24 +00:00
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-06-14 21:08:24 +00:00
// Returns the state of a specific joint in a given bodyIndex
2016-06-15 21:21:04 +00:00
//
// Args:
// bodyIndex - integer indicating body in simulation
// jointIndex - integer indicating joint for a specific body
//
2016-06-14 21:08:24 +00:00
// The state of a joint includes the following:
// position, velocity, force torque (6 values), and motor torque
// The returned pylist is an array of [float, float, float[6], float]
2016-09-08 18:12:58 +00:00
// TODO(hellojas): check accuracy of position and velocity
2016-06-14 21:08:24 +00:00
// TODO(hellojas): check force torque values
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_getJointState ( PyObject * self , PyObject * args ) {
PyObject * pyListJointForceTorque ;
PyObject * pyListJointState ;
2016-09-27 19:13:45 +00:00
2016-06-14 21:08:24 +00:00
struct b3JointSensorState sensorState ;
2016-09-08 18:12:58 +00:00
2016-06-14 21:08:24 +00:00
int bodyIndex = - 1 ;
int jointIndex = - 1 ;
2016-09-08 18:12:58 +00:00
int sensorStateSize = 4 ; // size of struct b3JointSensorState
int forceTorqueSize = 6 ; // size of force torque list from b3JointSensorState
2016-09-27 19:13:45 +00:00
int j ;
2016-06-14 21:08:24 +00:00
2016-09-08 18:12:58 +00:00
int size = PySequence_Size ( args ) ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-06-24 14:31:17 +00:00
2016-09-08 18:12:58 +00:00
if ( size = = 2 ) // get body index and joint index
2016-06-14 21:08:24 +00:00
{
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " ii " , & bodyIndex , & jointIndex ) ) {
2016-09-24 18:25:05 +00:00
int status_type = 0 ;
b3SharedMemoryCommandHandle cmd_handle ;
b3SharedMemoryStatusHandle status_handle ;
2016-09-23 22:57:35 +00:00
if ( bodyIndex < 0 ) {
PyErr_SetString ( SpamError , " getJointState failed; invalid bodyIndex " ) ;
return NULL ;
}
if ( jointIndex < 0 ) {
PyErr_SetString ( SpamError , " getJointState failed; invalid jointIndex " ) ;
return NULL ;
}
2016-09-24 18:25:05 +00:00
cmd_handle =
2016-06-14 21:08:24 +00:00
b3RequestActualStateCommandInit ( sm , bodyIndex ) ;
2016-09-24 18:25:05 +00:00
status_handle =
2016-09-08 18:12:58 +00:00
b3SubmitClientCommandAndWaitStatus ( sm , cmd_handle ) ;
2016-06-14 21:08:24 +00:00
2016-09-08 18:12:58 +00:00
status_type = b3GetStatusType ( status_handle ) ;
if ( status_type ! = CMD_ACTUAL_STATE_UPDATE_COMPLETED ) {
2016-09-23 22:57:35 +00:00
PyErr_SetString ( SpamError , " getJointState failed. " ) ;
2016-09-08 18:12:58 +00:00
return NULL ;
}
pyListJointState = PyTuple_New ( sensorStateSize ) ;
pyListJointForceTorque = PyTuple_New ( forceTorqueSize ) ;
b3GetJointState ( sm , status_handle , jointIndex , & sensorState ) ;
PyTuple_SetItem ( pyListJointState , 0 ,
PyFloat_FromDouble ( sensorState . m_jointPosition ) ) ;
PyTuple_SetItem ( pyListJointState , 1 ,
PyFloat_FromDouble ( sensorState . m_jointVelocity ) ) ;
for ( j = 0 ; j < forceTorqueSize ; j + + ) {
PyTuple_SetItem ( pyListJointForceTorque , j ,
PyFloat_FromDouble ( sensorState . m_jointForceTorque [ j ] ) ) ;
}
PyTuple_SetItem ( pyListJointState , 2 , pyListJointForceTorque ) ;
PyTuple_SetItem ( pyListJointState , 3 ,
PyFloat_FromDouble ( sensorState . m_jointMotorTorque ) ) ;
return pyListJointState ;
2016-06-14 21:08:24 +00:00
}
2016-09-08 18:12:58 +00:00
} else {
PyErr_SetString (
SpamError ,
" getJointState expects 2 arguments (objectUniqueId and joint index). " ) ;
return NULL ;
2016-06-14 21:08:24 +00:00
}
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-06-17 01:46:34 +00:00
2016-09-23 22:57:35 +00:00
static PyObject * pybullet_getLinkState ( PyObject * self , PyObject * args ) {
PyObject * pyLinkState ;
PyObject * pyLinkStateWorldPosition ;
PyObject * pyLinkStateWorldOrientation ;
PyObject * pyLinkStateLocalInertialPosition ;
PyObject * pyLinkStateLocalInertialOrientation ;
struct b3LinkState linkState ;
int bodyIndex = - 1 ;
int linkIndex = - 1 ;
int i ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( PySequence_Size ( args ) = = 2 ) // body index and link index
{
if ( PyArg_ParseTuple ( args , " ii " , & bodyIndex , & linkIndex ) ) {
2016-09-24 18:25:05 +00:00
int status_type = 0 ;
b3SharedMemoryCommandHandle cmd_handle ;
b3SharedMemoryStatusHandle status_handle ;
2016-09-23 22:57:35 +00:00
if ( bodyIndex < 0 ) {
PyErr_SetString ( SpamError , " getLinkState failed; invalid bodyIndex " ) ;
return NULL ;
}
if ( linkIndex < 0 ) {
PyErr_SetString ( SpamError , " getLinkState failed; invalid jointIndex " ) ;
return NULL ;
}
2016-09-24 18:25:05 +00:00
cmd_handle =
2016-09-23 22:57:35 +00:00
b3RequestActualStateCommandInit ( sm , bodyIndex ) ;
2016-09-24 18:25:05 +00:00
status_handle =
2016-09-23 22:57:35 +00:00
b3SubmitClientCommandAndWaitStatus ( sm , cmd_handle ) ;
status_type = b3GetStatusType ( status_handle ) ;
if ( status_type ! = CMD_ACTUAL_STATE_UPDATE_COMPLETED ) {
PyErr_SetString ( SpamError , " getLinkState failed. " ) ;
return NULL ;
}
b3GetLinkState ( sm , status_handle , linkIndex , & linkState ) ;
pyLinkStateWorldPosition = PyTuple_New ( 3 ) ;
for ( i = 0 ; i < 3 ; + + i ) {
PyTuple_SetItem ( pyLinkStateWorldPosition , i ,
PyFloat_FromDouble ( linkState . m_worldPosition [ i ] ) ) ;
}
pyLinkStateWorldOrientation = PyTuple_New ( 4 ) ;
for ( i = 0 ; i < 4 ; + + i ) {
PyTuple_SetItem ( pyLinkStateWorldOrientation , i ,
PyFloat_FromDouble ( linkState . m_worldOrientation [ i ] ) ) ;
}
pyLinkStateLocalInertialPosition = PyTuple_New ( 3 ) ;
for ( i = 0 ; i < 3 ; + + i ) {
PyTuple_SetItem ( pyLinkStateLocalInertialPosition , i ,
PyFloat_FromDouble ( linkState . m_localInertialPosition [ i ] ) ) ;
}
pyLinkStateLocalInertialOrientation = PyTuple_New ( 4 ) ;
for ( i = 0 ; i < 4 ; + + i ) {
PyTuple_SetItem ( pyLinkStateLocalInertialOrientation , i ,
PyFloat_FromDouble ( linkState . m_localInertialOrientation [ i ] ) ) ;
}
pyLinkState = PyTuple_New ( 4 ) ;
PyTuple_SetItem ( pyLinkState , 0 , pyLinkStateWorldPosition ) ;
PyTuple_SetItem ( pyLinkState , 1 , pyLinkStateWorldOrientation ) ;
PyTuple_SetItem ( pyLinkState , 2 , pyLinkStateLocalInertialPosition ) ;
PyTuple_SetItem ( pyLinkState , 3 , pyLinkStateLocalInertialOrientation ) ;
return pyLinkState ;
}
} else {
PyErr_SetString (
SpamError ,
" getLinkState expects 2 arguments (objectUniqueId and link index). " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-14 15:39:34 +00:00
static PyObject * pybullet_addUserDebugText ( PyObject * self , PyObject * args , PyObject * keywds )
{
int size = PySequence_Size ( args ) ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
int res = 0 ;
PyObject * pyResultList = 0 ;
char * text ;
double posXYZ [ 3 ] ;
double colorRGB [ 3 ] = { 1 , 1 , 1 } ;
PyObject * textPositionObj = 0 ;
PyObject * textColorRGBObj = 0 ;
double textSize = 1.f ;
double lifeTime = 0.f ;
static char * kwlist [ ] = { " text " , " textPosition " , " textColorRGB " , " textSize " , " lifeTime " , NULL } ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " sO|Odd " , kwlist , & text , & textPositionObj , & textColorRGBObj , & textSize , & lifeTime ) )
{
return NULL ;
}
res = pybullet_internalSetVectord ( textPositionObj , posXYZ ) ;
if ( ! res )
{
2016-11-20 01:13:56 +00:00
PyErr_SetString ( SpamError , " Error converting textPositionObj[3] " ) ;
2016-11-14 15:39:34 +00:00
return NULL ;
}
if ( textColorRGBObj )
{
res = pybullet_internalSetVectord ( textColorRGBObj , colorRGB ) ;
if ( ! res )
{
2016-11-20 01:13:56 +00:00
PyErr_SetString ( SpamError , " Error converting textColorRGBObj[3] " ) ;
2016-11-14 15:39:34 +00:00
return NULL ;
}
}
commandHandle = b3InitUserDebugDrawAddText3D ( sm , text , posXYZ , colorRGB , textSize , lifeTime ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_USER_DEBUG_DRAW_COMPLETED )
{
int debugItemUniqueId = b3GetDebugItemUniqueId ( statusHandle ) ;
PyObject * item = PyInt_FromLong ( debugItemUniqueId ) ;
return item ;
}
PyErr_SetString ( SpamError , " Error in addUserDebugText. " ) ;
return NULL ;
}
static PyObject * pybullet_addUserDebugLine ( PyObject * self , PyObject * args , PyObject * keywds )
{
int size = PySequence_Size ( args ) ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
int res = 0 ;
PyObject * pyResultList = 0 ;
double fromXYZ [ 3 ] ;
double toXYZ [ 3 ] ;
double colorRGB [ 3 ] = { 1 , 1 , 1 } ;
PyObject * lineFromObj = 0 ;
PyObject * lineToObj = 0 ;
PyObject * lineColorRGBObj = 0 ;
double lineWidth = 1.f ;
double lifeTime = 0.f ;
static char * kwlist [ ] = { " lineFromXYZ " , " lineToXYZ " , " lineColorRGB " , " lineWidth " , " lifeTime " , NULL } ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " OO|Odd " , kwlist , & lineFromObj , & lineToObj , & lineColorRGBObj , & lineWidth , & lifeTime ) )
{
return NULL ;
}
res = pybullet_internalSetVectord ( lineFromObj , fromXYZ ) ;
if ( ! res )
{
PyErr_SetString ( SpamError , " Error converting lineFrom[3] " ) ;
return NULL ;
}
res = pybullet_internalSetVectord ( lineToObj , toXYZ ) ;
if ( ! res )
{
PyErr_SetString ( SpamError , " Error converting lineTo[3] " ) ;
return NULL ;
}
if ( lineColorRGBObj )
{
res = pybullet_internalSetVectord ( lineColorRGBObj , colorRGB ) ;
}
commandHandle = b3InitUserDebugDrawAddLine3D ( sm , fromXYZ , toXYZ , colorRGB , lineWidth , lifeTime ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_USER_DEBUG_DRAW_COMPLETED )
{
int debugItemUniqueId = b3GetDebugItemUniqueId ( statusHandle ) ;
PyObject * item = PyInt_FromLong ( debugItemUniqueId ) ;
return item ;
}
PyErr_SetString ( SpamError , " Error in addUserDebugLine. " ) ;
return NULL ;
}
static PyObject * pybullet_removeUserDebugItem ( PyObject * self , PyObject * args , PyObject * keywds )
{
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
int itemUniqueId ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTuple ( args , " i " , & itemUniqueId ) ) {
PyErr_SetString ( SpamError , " Error parsing user debug item unique id " ) ;
return NULL ;
}
commandHandle = b3InitUserDebugDrawRemove ( sm , itemUniqueId ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
static PyObject * pybullet_removeAllUserDebugItems ( PyObject * self , PyObject * args , PyObject * keywds )
{
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
commandHandle = b3InitUserDebugDrawRemoveAll ( sm ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-21 15:42:11 +00:00
static PyObject * pybullet_setDebugObjectColor ( PyObject * self , PyObject * args , PyObject * keywds )
{
PyObject * objectColorRGBObj = 0 ;
double objectColorRGB [ 3 ] ;
int objectUniqueId = - 1 ;
int linkIndex = - 2 ;
static char * kwlist [ ] = { " objectUniqueId " , " linkIndex " , " objectDebugColorRGB " , NULL } ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " ii|O " , kwlist ,
& objectUniqueId , & linkIndex , & objectColorRGBObj ) )
return NULL ;
if ( objectColorRGBObj )
{
if ( pybullet_internalSetVectord ( objectColorRGBObj , objectColorRGB ) )
{
b3SharedMemoryCommandHandle commandHandle = b3InitDebugDrawingCommand ( sm ) ;
b3SetDebugObjectColor ( commandHandle , objectUniqueId , linkIndex , objectColorRGB ) ;
b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
}
}
else
{
b3SharedMemoryCommandHandle commandHandle = b3InitDebugDrawingCommand ( sm ) ;
b3RemoveDebugObjectColor ( commandHandle , objectUniqueId , linkIndex ) ;
b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-14 15:39:34 +00:00
2016-10-19 05:05:28 +00:00
static PyObject * pybullet_getVisualShapeData ( PyObject * self , PyObject * args )
{
int size = PySequence_Size ( args ) ;
int objectUniqueId = - 1 ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
struct b3VisualShapeInformation visualShapeInfo ;
int statusType ;
2016-10-19 14:42:55 +00:00
int i ;
2016-10-19 05:05:28 +00:00
PyObject * pyResultList = 0 ;
2016-11-10 05:01:04 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-10-19 05:05:28 +00:00
if ( size = = 1 )
{
if ( ! PyArg_ParseTuple ( args , " i " , & objectUniqueId ) ) {
PyErr_SetString ( SpamError , " Error parsing object unique id " ) ;
return NULL ;
}
commandHandle = b3InitRequestVisualShapeInformation ( sm , objectUniqueId ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_VISUAL_SHAPE_INFO_COMPLETED )
{
b3GetVisualShapeInformation ( sm , & visualShapeInfo ) ;
pyResultList = PyTuple_New ( visualShapeInfo . m_numVisualShapes ) ;
2016-10-19 14:42:55 +00:00
for ( i = 0 ; i < visualShapeInfo . m_numVisualShapes ; i + + )
2016-10-19 05:05:28 +00:00
{
PyObject * visualShapeObList = PyTuple_New ( 7 ) ;
PyObject * item ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_objectUniqueId ) ;
PyTuple_SetItem ( visualShapeObList , 0 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_linkIndex ) ;
PyTuple_SetItem ( visualShapeObList , 1 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_visualGeometryType ) ;
PyTuple_SetItem ( visualShapeObList , 2 , item ) ;
{
PyObject * vec = PyTuple_New ( 3 ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_dimensions [ 0 ] ) ;
PyTuple_SetItem ( vec , 0 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_dimensions [ 1 ] ) ;
PyTuple_SetItem ( vec , 1 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_dimensions [ 2 ] ) ;
PyTuple_SetItem ( vec , 2 , item ) ;
PyTuple_SetItem ( visualShapeObList , 3 , vec ) ;
}
item = PyString_FromString ( visualShapeInfo . m_visualShapeData [ i ] . m_meshAssetFileName ) ;
PyTuple_SetItem ( visualShapeObList , 4 , item ) ;
{
PyObject * vec = PyTuple_New ( 3 ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 0 ] ) ;
PyTuple_SetItem ( vec , 0 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 1 ] ) ;
PyTuple_SetItem ( vec , 1 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 2 ] ) ;
PyTuple_SetItem ( vec , 2 , item ) ;
PyTuple_SetItem ( visualShapeObList , 5 , vec ) ;
}
{
PyObject * vec = PyTuple_New ( 4 ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 3 ] ) ;
PyTuple_SetItem ( vec , 0 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 4 ] ) ;
PyTuple_SetItem ( vec , 1 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 5 ] ) ;
PyTuple_SetItem ( vec , 2 , item ) ;
item = PyInt_FromLong ( visualShapeInfo . m_visualShapeData [ i ] . m_localInertiaFrame [ 6 ] ) ;
PyTuple_SetItem ( vec , 3 , item ) ;
PyTuple_SetItem ( visualShapeObList , 6 , vec ) ;
}
2016-11-14 15:39:34 +00:00
visualShapeInfo . m_visualShapeData [ 0 ] . m_rgbaColor [ 0 ] ;
2016-10-19 05:05:28 +00:00
PyTuple_SetItem ( pyResultList , i , visualShapeObList ) ;
}
return pyResultList ;
}
else
{
PyErr_SetString ( SpamError , " Error receiving visual shape info " ) ;
return NULL ;
}
}
else
{
PyErr_SetString ( SpamError , " getVisualShapeData requires 1 argument (object unique id) " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-10-22 00:48:06 +00:00
static PyObject * pybullet_resetVisualShapeData ( PyObject * self , PyObject * args )
{
int size = PySequence_Size ( args ) ;
int objectUniqueId = - 1 ;
int jointIndex = - 1 ;
int shapeIndex = - 1 ;
int textureUniqueId = - 1 ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
2016-11-10 05:01:04 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-10-22 00:48:06 +00:00
if ( size = = 4 )
{
if ( ! PyArg_ParseTuple ( args , " iiii " , & objectUniqueId , & jointIndex , & shapeIndex , & textureUniqueId ) ) {
PyErr_SetString ( SpamError , " Error parsing object unique id, or joint index, or shape index, or texture unique id " ) ;
return NULL ;
}
commandHandle = b3InitUpdateVisualShape ( sm , objectUniqueId , jointIndex , shapeIndex , textureUniqueId ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_VISUAL_SHAPE_UPDATE_COMPLETED )
{
}
else
{
PyErr_SetString ( SpamError , " Error resetting visual shape info " ) ;
return NULL ;
}
}
else
{
PyErr_SetString ( SpamError , " setVisualShapeData requires 4 argument " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-10-19 05:05:28 +00:00
2016-10-22 00:48:06 +00:00
static PyObject * pybullet_loadTexture ( PyObject * self , PyObject * args )
{
int size = PySequence_Size ( args ) ;
2016-11-09 20:22:05 +00:00
const char * filename = 0 ;
2016-10-22 00:48:06 +00:00
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
2016-11-10 05:01:04 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-10-22 00:48:06 +00:00
if ( size = = 1 )
{
if ( ! PyArg_ParseTuple ( args , " s " , & filename ) ) {
PyErr_SetString ( SpamError , " Error parsing file name " ) ;
return NULL ;
}
commandHandle = b3InitLoadTexture ( sm , filename ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_LOAD_TEXTURE_COMPLETED )
{
}
else
{
PyErr_SetString ( SpamError , " Error loading texture " ) ;
return NULL ;
}
}
else
{
PyErr_SetString ( SpamError , " loadTexture requires 1 argument " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-10-19 05:05:28 +00:00
2016-09-02 01:28:39 +00:00
2016-11-10 05:01:04 +00:00
static PyObject * MyConvertContactPoint ( struct b3ContactInformation * contactPointPtr )
{
/*
2016-09-08 18:12:58 +00:00
0 int m_contactFlags ;
1 int m_bodyUniqueIdA ;
2 int m_bodyUniqueIdB ;
3 int m_linkIndexA ;
4 int m_linkIndexB ;
2016-11-20 01:13:56 +00:00
5 double m_positionOnAInWS [ 3 ] ; //contact point location on object A,
2016-09-08 18:12:58 +00:00
in world space coordinates
2016-11-20 01:13:56 +00:00
6 double m_positionOnBInWS [ 3 ] ; //contact point location on object
2016-09-08 18:12:58 +00:00
A , in world space coordinates
2016-11-20 01:13:56 +00:00
7 double m_contactNormalOnBInWS [ 3 ] ; //the separating contact
2016-09-08 18:12:58 +00:00
normal , pointing from object B towards object A
2016-11-20 01:13:56 +00:00
8 double m_contactDistance ; //negative number is penetration, positive
2016-09-08 18:12:58 +00:00
is distance .
2016-11-20 01:13:56 +00:00
9 double m_normalForce ;
2016-09-08 18:12:58 +00:00
*/
2016-11-10 05:01:04 +00:00
int i ;
PyObject * pyResultList = PyTuple_New ( contactPointPtr - > m_numContactPoints ) ;
for ( i = 0 ; i < contactPointPtr - > m_numContactPoints ; i + + ) {
2016-11-20 01:13:56 +00:00
PyObject * contactObList = PyTuple_New ( 10 ) ; // see above 10 fields
2016-09-08 18:12:58 +00:00
PyObject * item ;
item =
2016-11-10 05:01:04 +00:00
PyInt_FromLong ( contactPointPtr - > m_contactPointData [ i ] . m_contactFlags ) ;
2016-09-08 18:12:58 +00:00
PyTuple_SetItem ( contactObList , 0 , item ) ;
item = PyInt_FromLong (
2016-11-10 05:01:04 +00:00
contactPointPtr - > m_contactPointData [ i ] . m_bodyUniqueIdA ) ;
2016-09-08 18:12:58 +00:00
PyTuple_SetItem ( contactObList , 1 , item ) ;
item = PyInt_FromLong (
2016-11-10 05:01:04 +00:00
contactPointPtr - > m_contactPointData [ i ] . m_bodyUniqueIdB ) ;
2016-09-08 18:12:58 +00:00
PyTuple_SetItem ( contactObList , 2 , item ) ;
item =
2016-11-10 05:01:04 +00:00
PyInt_FromLong ( contactPointPtr - > m_contactPointData [ i ] . m_linkIndexA ) ;
2016-09-08 18:12:58 +00:00
PyTuple_SetItem ( contactObList , 3 , item ) ;
item =
2016-11-10 05:01:04 +00:00
PyInt_FromLong ( contactPointPtr - > m_contactPointData [ i ] . m_linkIndexB ) ;
2016-09-08 18:12:58 +00:00
PyTuple_SetItem ( contactObList , 4 , item ) ;
2016-11-20 01:13:56 +00:00
{
PyObject * posAObj = PyTuple_New ( 3 ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_positionOnAInWS [ 0 ] ) ;
PyTuple_SetItem ( posAObj , 0 , item ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_positionOnAInWS [ 1 ] ) ;
PyTuple_SetItem ( posAObj , 1 , item ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_positionOnAInWS [ 2 ] ) ;
PyTuple_SetItem ( posAObj , 2 , item ) ;
PyTuple_SetItem ( contactObList , 5 , posAObj ) ;
}
2016-09-08 18:12:58 +00:00
2016-11-20 01:13:56 +00:00
{
PyObject * posBObj = PyTuple_New ( 3 ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_positionOnBInWS [ 0 ] ) ;
PyTuple_SetItem ( posBObj , 0 , item ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_positionOnBInWS [ 1 ] ) ;
PyTuple_SetItem ( posBObj , 1 , item ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_positionOnBInWS [ 2 ] ) ;
PyTuple_SetItem ( posBObj , 2 , item ) ;
PyTuple_SetItem ( contactObList , 6 , posBObj ) ;
}
{
PyObject * normalOnB = PyTuple_New ( 3 ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_contactNormalOnBInWS [ 0 ] ) ;
PyTuple_SetItem ( normalOnB , 0 , item ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_contactNormalOnBInWS [ 1 ] ) ;
PyTuple_SetItem ( normalOnB , 1 , item ) ;
item = PyFloat_FromDouble (
contactPointPtr - > m_contactPointData [ i ] . m_contactNormalOnBInWS [ 2 ] ) ;
PyTuple_SetItem ( normalOnB , 2 , item ) ;
PyTuple_SetItem ( contactObList , 7 , normalOnB ) ;
}
2016-09-08 18:12:58 +00:00
item = PyFloat_FromDouble (
2016-11-10 05:01:04 +00:00
contactPointPtr - > m_contactPointData [ i ] . m_contactDistance ) ;
2016-11-20 01:13:56 +00:00
PyTuple_SetItem ( contactObList , 8 , item ) ;
2016-09-08 18:12:58 +00:00
item = PyFloat_FromDouble (
2016-11-10 05:01:04 +00:00
contactPointPtr - > m_contactPointData [ i ] . m_normalForce ) ;
2016-11-20 01:13:56 +00:00
PyTuple_SetItem ( contactObList , 9 , item ) ;
2016-09-08 18:12:58 +00:00
PyTuple_SetItem ( pyResultList , i , contactObList ) ;
}
return pyResultList ;
2016-11-10 05:01:04 +00:00
}
static PyObject * pybullet_getOverlappingObjects ( PyObject * self , PyObject * args , PyObject * keywds )
{
PyObject * aabbMinOb = 0 , * aabbMaxOb = 0 ;
double aabbMin [ 3 ] ;
double aabbMax [ 3 ] ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
struct b3AABBOverlapData overlapData ;
2016-11-10 19:22:22 +00:00
int i ;
2016-11-10 05:01:04 +00:00
static char * kwlist [ ] = { " aabbMin " , " aabbMax " , NULL } ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " OO " , kwlist ,
& aabbMinOb , & aabbMaxOb ) )
return NULL ;
pybullet_internalSetVectord ( aabbMinOb , aabbMin ) ;
pybullet_internalSetVectord ( aabbMaxOb , aabbMax ) ;
commandHandle = b3InitAABBOverlapQuery ( sm , aabbMin , aabbMax ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
b3GetAABBOverlapResults ( sm , & overlapData ) ;
2016-11-10 19:22:22 +00:00
if ( overlapData . m_numOverlappingObjects )
{
PyObject * pyResultList = PyTuple_New ( overlapData . m_numOverlappingObjects ) ;
//For huge amount of overlap, we could use numpy instead (see camera pixel data)
//What would Python do with huge amount of data? Pass it onto TensorFlow!
for ( i = 0 ; i < overlapData . m_numOverlappingObjects ; i + + ) {
PyObject * overlap = PyTuple_New ( 2 ) ; //body unique id and link index
PyObject * item ;
item =
PyInt_FromLong ( overlapData . m_overlappingObjects [ i ] . m_objectUniqueId ) ;
PyTuple_SetItem ( overlap , 0 , item ) ;
item =
PyInt_FromLong ( overlapData . m_overlappingObjects [ i ] . m_linkIndex ) ;
PyTuple_SetItem ( overlap , 1 , item ) ;
PyTuple_SetItem ( pyResultList , i , overlap ) ;
}
return pyResultList ;
}
2016-11-10 05:01:04 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
static PyObject * pybullet_getClosestPointData ( PyObject * self , PyObject * args , PyObject * keywds )
{
int size = PySequence_Size ( args ) ;
int bodyUniqueIdA = - 1 ;
int bodyUniqueIdB = - 1 ;
2016-11-20 01:13:56 +00:00
int linkIndexA = - 2 ;
int linkIndexB = - 2 ;
2016-11-10 05:01:04 +00:00
double distanceThreshold = 0.f ;
b3SharedMemoryCommandHandle commandHandle ;
struct b3ContactInformation contactPointData ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
PyObject * pyResultList = 0 ;
2016-11-20 01:13:56 +00:00
static char * kwlist [ ] = { " bodyA " , " bodyB " , " distance " , " linkIndexA " , " linkIndexB " , NULL } ;
2016-11-10 05:01:04 +00:00
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
2016-11-20 01:13:56 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " iid|ii " , kwlist ,
& bodyUniqueIdA , & bodyUniqueIdB , & distanceThreshold , & linkIndexA , & linkIndexB ) )
2016-11-10 05:01:04 +00:00
return NULL ;
commandHandle = b3InitClosestDistanceQuery ( sm ) ;
b3SetClosestDistanceFilterBodyA ( commandHandle , bodyUniqueIdA ) ;
b3SetClosestDistanceFilterBodyB ( commandHandle , bodyUniqueIdB ) ;
b3SetClosestDistanceThreshold ( commandHandle , distanceThreshold ) ;
2016-11-20 01:13:56 +00:00
if ( linkIndexA > = - 1 )
{
b3SetClosestDistanceFilterLinkA ( commandHandle , linkIndexA ) ;
}
if ( linkIndexB > = - 1 )
{
b3SetClosestDistanceFilterLinkB ( commandHandle , linkIndexB ) ;
}
2016-11-10 05:01:04 +00:00
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_CONTACT_POINT_INFORMATION_COMPLETED ) {
b3GetContactPointInformation ( sm , & contactPointData ) ;
return MyConvertContactPoint ( & contactPointData ) ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-14 22:08:05 +00:00
static PyObject * pybullet_removeUserConstraint ( PyObject * self , PyObject * args , PyObject * keywds )
{
static char * kwlist [ ] = { " userConstraintUniqueId " , NULL } ;
int userConstraintUniqueId = - 1 ;
b3SharedMemoryCommandHandle commandHandle ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
if ( 0 = = sm )
{
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " i " , kwlist , & userConstraintUniqueId ) )
{
return NULL ;
}
commandHandle = b3InitRemoveUserConstraintCommand ( sm , userConstraintUniqueId ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
Py_INCREF ( Py_None ) ;
return Py_None ;
} ;
/*
static PyObject * pybullet_updateUserConstraint ( PyObject * self , PyObject * args , PyObject * keywds )
{
return NULL ;
}
*/
static PyObject * pybullet_createUserConstraint ( PyObject * self , PyObject * args , PyObject * keywds )
{
int size = PySequence_Size ( args ) ;
int bodyUniqueIdA = - 1 ;
int bodyUniqueIdB = - 1 ;
b3SharedMemoryCommandHandle commandHandle ;
int parentBodyUniqueId = - 1 ;
int parentLinkIndex = - 1 ;
int childBodyUniqueId = - 1 ;
int childLinkIndex = - 1 ;
int jointType = ePoint2PointType ;
PyObject * jointAxisObj = 0 ;
double jointAxis [ 3 ] = { 0 , 0 , 0 } ;
PyObject * parentFramePositionObj = 0 ;
double parentFramePosition [ 3 ] = { 0 , 0 , 0 } ;
PyObject * childFramePositionObj = 0 ;
double childFramePosition [ 3 ] = { 0 , 0 , 0 } ;
PyObject * parentFrameOrientationObj = 0 ;
double parentFrameOrientation [ 4 ] = { 0 , 0 , 0 , 1 } ;
PyObject * childFrameOrientationObj = 0 ;
double childFrameOrientation [ 4 ] = { 0 , 0 , 0 , 1 } ;
struct b3JointInfo jointInfo ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
PyObject * pyResultList = 0 ;
static char * kwlist [ ] = { " parentBodyUniqueId " , " parentLinkIndex " ,
" childBodyUniqueId " , " childLinkIndex " ,
" jointType " ,
" jointAxis " ,
" parentFramePosition " ,
" childFramePosition " ,
" parentFrameOrientation " ,
" childFrameOrientation " ,
NULL } ;
if ( 0 = = sm )
{
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " iiiiiOOO|OO " , kwlist , & parentBodyUniqueId , & parentLinkIndex ,
& childBodyUniqueId , & childLinkIndex ,
& jointType , & jointAxisObj ,
& parentFramePositionObj ,
& childFramePositionObj ,
& parentFrameOrientationObj ,
& childFrameOrientationObj
) )
{
return NULL ;
}
pybullet_internalSetVectord ( jointAxisObj , jointAxis ) ;
pybullet_internalSetVectord ( parentFramePositionObj , parentFramePosition ) ;
pybullet_internalSetVectord ( childFramePositionObj , childFramePosition ) ;
pybullet_internalSetVector4d ( parentFrameOrientationObj , parentFrameOrientation ) ;
pybullet_internalSetVector4d ( childFrameOrientationObj , childFrameOrientation ) ;
jointInfo . m_jointType = jointType ;
jointInfo . m_parentFrame [ 0 ] = parentFramePosition [ 0 ] ;
jointInfo . m_parentFrame [ 1 ] = parentFramePosition [ 1 ] ;
jointInfo . m_parentFrame [ 2 ] = parentFramePosition [ 2 ] ;
jointInfo . m_parentFrame [ 3 ] = parentFrameOrientation [ 0 ] ;
jointInfo . m_parentFrame [ 4 ] = parentFrameOrientation [ 1 ] ;
jointInfo . m_parentFrame [ 5 ] = parentFrameOrientation [ 2 ] ;
jointInfo . m_parentFrame [ 6 ] = parentFrameOrientation [ 3 ] ;
jointInfo . m_childFrame [ 0 ] = childFramePosition [ 0 ] ;
jointInfo . m_childFrame [ 1 ] = childFramePosition [ 1 ] ;
jointInfo . m_childFrame [ 2 ] = childFramePosition [ 2 ] ;
jointInfo . m_childFrame [ 3 ] = childFrameOrientation [ 0 ] ;
jointInfo . m_childFrame [ 4 ] = childFrameOrientation [ 1 ] ;
jointInfo . m_childFrame [ 5 ] = childFrameOrientation [ 2 ] ;
jointInfo . m_childFrame [ 6 ] = childFrameOrientation [ 3 ] ;
jointInfo . m_jointAxis [ 0 ] = jointAxis [ 0 ] ;
jointInfo . m_jointAxis [ 1 ] = jointAxis [ 1 ] ;
jointInfo . m_jointAxis [ 2 ] = jointAxis [ 2 ] ;
commandHandle = b3InitCreateUserConstraintCommand ( sm , parentBodyUniqueId , parentLinkIndex , childBodyUniqueId , childLinkIndex , & jointInfo ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_USER_CONSTRAINT_COMPLETED )
{
int userConstraintUid = b3GetStatusUserConstraintUniqueId ( statusHandle ) ;
PyObject * ob = PyLong_FromLong ( userConstraintUid ) ;
return ob ;
} else
{
PyErr_SetString ( SpamError , " createConstraint failed. " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-11-10 05:01:04 +00:00
static PyObject * pybullet_getContactPointData ( PyObject * self , PyObject * args , PyObject * keywds ) {
int size = PySequence_Size ( args ) ;
int bodyUniqueIdA = - 1 ;
int bodyUniqueIdB = - 1 ;
b3SharedMemoryCommandHandle commandHandle ;
struct b3ContactInformation contactPointData ;
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
PyObject * pyResultList = 0 ;
static char * kwlist [ ] = { " bodyA " , " bodyB " , NULL } ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " |ii " , kwlist ,
& bodyUniqueIdA , & bodyUniqueIdB ) )
return NULL ;
commandHandle = b3InitRequestContactPointInformation ( sm ) ;
b3SetContactFilterBodyA ( commandHandle , bodyUniqueIdA ) ;
b3SetContactFilterBodyB ( commandHandle , bodyUniqueIdB ) ;
//b3SetContactQueryMode(commandHandle, mode);
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_CONTACT_POINT_INFORMATION_COMPLETED ) {
b3GetContactPointInformation ( sm , & contactPointData ) ;
return MyConvertContactPoint ( & contactPointData ) ;
2016-09-08 18:12:58 +00:00
}
2016-09-02 01:28:39 +00:00
2016-09-08 18:12:58 +00:00
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-09-02 01:28:39 +00:00
2016-11-17 23:15:52 +00:00
/// Render an image from the current timestep of the simulation, width, height are required, other args are optional
2016-12-06 23:38:09 +00:00
// getCameraImage(w, h, view[16], projection[16], lightDir[3], lightColor[3], lightDist, hasShadow, lightAmbientCoeff, lightDiffuseCoeff, lightSpecularCoeff)
2016-11-17 23:15:52 +00:00
static PyObject * pybullet_getCameraImage ( PyObject * self , PyObject * args , PyObject * keywds )
{
/// request an image from a simulated camera, using a software renderer.
struct b3CameraImageData imageData ;
2016-11-20 21:14:18 +00:00
PyObject * objViewMat = 0 , * objProjMat = 0 , * lightDirObj = 0 , * lightColorObj = 0 ;
2016-11-17 23:15:52 +00:00
int width , height ;
int size = PySequence_Size ( args ) ;
float viewMatrix [ 16 ] ;
float projectionMatrix [ 16 ] ;
float lightDir [ 3 ] ;
2016-11-20 21:14:18 +00:00
float lightColor [ 3 ] ;
2016-11-29 22:10:07 +00:00
float lightDist = 10.0 ;
int hasShadow = 0 ;
2016-12-06 23:38:09 +00:00
float lightAmbientCoeff = 0.6 ;
float lightDiffuseCoeff = 0.35 ;
float lightSpecularCoeff = 0.05 ;
2016-11-17 23:15:52 +00:00
// inialize cmd
b3SharedMemoryCommandHandle command ;
if ( 0 = = sm )
{
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
command = b3InitRequestCameraImage ( sm ) ;
2016-11-29 22:10:07 +00:00
// set camera resolution, optionally view, projection matrix, light direction, light color, light distance, shadow
2016-12-06 23:38:09 +00:00
static char * kwlist [ ] = { " width " , " height " , " viewMatrix " , " projectionMatrix " , " lightDirection " , " lightColor " , " lightDistance " , " shadow " , " lightAmbientCoeff " , " lightDiffuseCoeff " , " lightSpecularCoeff " , NULL } ;
2016-11-17 23:15:52 +00:00
2016-12-06 23:38:09 +00:00
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " ii|OOOOfifff " , kwlist , & width , & height , & objViewMat , & objProjMat , & lightDirObj , & lightColorObj , & lightDist , & hasShadow , & lightAmbientCoeff , & lightDiffuseCoeff , & lightSpecularCoeff ) )
2016-11-17 23:15:52 +00:00
{
return NULL ;
}
b3RequestCameraImageSetPixelResolution ( command , width , height ) ;
// set camera matrices only if set matrix function succeeds
if ( pybullet_internalSetMatrix ( objViewMat , viewMatrix ) & & ( pybullet_internalSetMatrix ( objProjMat , projectionMatrix ) ) )
{
b3RequestCameraImageSetCameraMatrices ( command , viewMatrix , projectionMatrix ) ;
}
2016-11-20 21:14:18 +00:00
//set light direction only if function succeeds
2016-11-17 23:15:52 +00:00
if ( pybullet_internalSetVector ( lightDirObj , lightDir ) )
{
b3RequestCameraImageSetLightDirection ( command , lightDir ) ;
}
2016-11-20 21:14:18 +00:00
//set light color only if function succeeds
if ( pybullet_internalSetVector ( lightColorObj , lightColor ) )
{
b3RequestCameraImageSetLightColor ( command , lightColor ) ;
}
2016-11-17 23:15:52 +00:00
2016-11-29 22:10:07 +00:00
b3RequestCameraImageSetLightDistance ( command , lightDist ) ;
b3RequestCameraImageSetShadow ( command , hasShadow ) ;
2016-12-06 23:38:09 +00:00
b3RequestCameraImageSetLightAmbientCoeff ( command , lightAmbientCoeff ) ;
b3RequestCameraImageSetLightDiffuseCoeff ( command , lightDiffuseCoeff ) ;
b3RequestCameraImageSetLightSpecularCoeff ( command , lightSpecularCoeff ) ;
2016-11-17 23:15:52 +00:00
if ( b3CanSubmitCommand ( sm ) )
{
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
// b3RequestCameraImageSelectRenderer(command,ER_BULLET_HARDWARE_OPENGL);
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_CAMERA_IMAGE_COMPLETED ) {
PyObject * item2 ;
PyObject * pyResultList ; // store 4 elements in this result: width,
// height, rgbData, depth
# ifdef PYBULLET_USE_NUMPY
PyObject * pyRGB ;
PyObject * pyDep ;
PyObject * pySeg ;
int i , j , p ;
b3GetCameraImageData ( sm , & imageData ) ;
// TODO(hellojas): error handling if image size is 0
pyResultList = PyTuple_New ( 5 ) ;
PyTuple_SetItem ( pyResultList , 0 , PyInt_FromLong ( imageData . m_pixelWidth ) ) ;
PyTuple_SetItem ( pyResultList , 1 , PyInt_FromLong ( imageData . m_pixelHeight ) ) ;
int bytesPerPixel = 4 ; // Red, Green, Blue, and Alpha each 8 bit values
npy_intp rgb_dims [ 3 ] = { imageData . m_pixelHeight , imageData . m_pixelWidth ,
bytesPerPixel } ;
npy_intp dep_dims [ 2 ] = { imageData . m_pixelHeight , imageData . m_pixelWidth } ;
npy_intp seg_dims [ 2 ] = { imageData . m_pixelHeight , imageData . m_pixelWidth } ;
pyRGB = PyArray_SimpleNew ( 3 , rgb_dims , NPY_UINT8 ) ;
pyDep = PyArray_SimpleNew ( 2 , dep_dims , NPY_FLOAT32 ) ;
pySeg = PyArray_SimpleNew ( 2 , seg_dims , NPY_INT32 ) ;
memcpy ( PyArray_DATA ( pyRGB ) , imageData . m_rgbColorData ,
imageData . m_pixelHeight * imageData . m_pixelWidth * bytesPerPixel ) ;
memcpy ( PyArray_DATA ( pyDep ) , imageData . m_depthValues ,
imageData . m_pixelHeight * imageData . m_pixelWidth ) ;
memcpy ( PyArray_DATA ( pySeg ) , imageData . m_segmentationMaskValues ,
imageData . m_pixelHeight * imageData . m_pixelWidth ) ;
PyTuple_SetItem ( pyResultList , 2 , pyRGB ) ;
PyTuple_SetItem ( pyResultList , 3 , pyDep ) ;
PyTuple_SetItem ( pyResultList , 4 , pySeg ) ;
# else //PYBULLET_USE_NUMPY
PyObject * pylistRGB ;
PyObject * pylistDep ;
PyObject * pylistSeg ;
int i , j , p ;
b3GetCameraImageData ( sm , & imageData ) ;
// TODO(hellojas): error handling if image size is 0
pyResultList = PyTuple_New ( 5 ) ;
PyTuple_SetItem ( pyResultList , 0 , PyInt_FromLong ( imageData . m_pixelWidth ) ) ;
PyTuple_SetItem ( pyResultList , 1 , PyInt_FromLong ( imageData . m_pixelHeight ) ) ;
{
PyObject * item ;
int bytesPerPixel = 4 ; // Red, Green, Blue, and Alpha each 8 bit values
int num =
bytesPerPixel * imageData . m_pixelWidth * imageData . m_pixelHeight ;
pylistRGB = PyTuple_New ( num ) ;
pylistDep =
PyTuple_New ( imageData . m_pixelWidth * imageData . m_pixelHeight ) ;
pylistSeg =
PyTuple_New ( imageData . m_pixelWidth * imageData . m_pixelHeight ) ;
for ( i = 0 ; i < imageData . m_pixelWidth ; i + + ) {
for ( j = 0 ; j < imageData . m_pixelHeight ; j + + ) {
// TODO(hellojas): validate depth values make sense
int depIndex = i + j * imageData . m_pixelWidth ;
{
item = PyFloat_FromDouble ( imageData . m_depthValues [ depIndex ] ) ;
PyTuple_SetItem ( pylistDep , depIndex , item ) ;
}
{
item2 =
PyLong_FromLong ( imageData . m_segmentationMaskValues [ depIndex ] ) ;
PyTuple_SetItem ( pylistSeg , depIndex , item2 ) ;
}
for ( p = 0 ; p < bytesPerPixel ; p + + ) {
int pixelIndex =
bytesPerPixel * ( i + j * imageData . m_pixelWidth ) + p ;
item = PyInt_FromLong ( imageData . m_rgbColorData [ pixelIndex ] ) ;
PyTuple_SetItem ( pylistRGB , pixelIndex , item ) ;
}
}
}
}
PyTuple_SetItem ( pyResultList , 2 , pylistRGB ) ;
PyTuple_SetItem ( pyResultList , 3 , pylistDep ) ;
PyTuple_SetItem ( pyResultList , 4 , pylistSeg ) ;
return pyResultList ;
# endif //PYBULLET_USE_NUMPY
return pyResultList ;
}
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
static PyObject * pybullet_computeViewMatrix ( PyObject * self , PyObject * args , PyObject * keywds )
{
PyObject * camEyeObj = 0 ;
PyObject * camTargetPositionObj = 0 ;
PyObject * camUpVectorObj = 0 ;
float camEye [ 3 ] ;
float camTargetPosition [ 3 ] ;
float camUpVector [ 3 ] ;
// set camera resolution, optionally view, projection matrix, light position
static char * kwlist [ ] = { " cameraEyePosition " , " cameraTargetPosition " , " cameraUpVector " , NULL } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " OOO " , kwlist , & camEyeObj , & camTargetPositionObj , & camUpVectorObj ) )
{
return NULL ;
}
if ( pybullet_internalSetVector ( camEyeObj , camEye ) & &
pybullet_internalSetVector ( camTargetPositionObj , camTargetPosition ) & &
pybullet_internalSetVector ( camUpVectorObj , camUpVector ) )
{
float viewMatrix [ 16 ] ;
PyObject * pyResultList = 0 ;
int i ;
b3ComputeViewMatrixFromPositions ( camEye , camTargetPosition , camUpVector , viewMatrix ) ;
pyResultList = PyTuple_New ( 16 ) ;
for ( i = 0 ; i < 16 ; i + + )
{
PyObject * item = PyFloat_FromDouble ( viewMatrix [ i ] ) ;
PyTuple_SetItem ( pyResultList , i , item ) ;
}
return pyResultList ;
}
PyErr_SetString ( SpamError , " Error in computeViewMatrix. " ) ;
return NULL ;
}
///compute a view matrix, helper function for b3RequestCameraImageSetCameraMatrices
static PyObject * pybullet_computeViewMatrixFromYawPitchRoll ( PyObject * self , PyObject * args , PyObject * keywds )
{
PyObject * cameraTargetPositionObj = 0 ;
float cameraTargetPosition [ 3 ] ;
float distance , yaw , pitch , roll ;
int upAxisIndex ;
float viewMatrix [ 16 ] ;
PyObject * pyResultList = 0 ;
int i ;
// set camera resolution, optionally view, projection matrix, light position
static char * kwlist [ ] = { " cameraTargetPosition " , " distance " , " yaw " , " pitch " , " roll " , " upAxisIndex " , NULL } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " Offffi " , kwlist , & cameraTargetPositionObj , & distance , & yaw , & pitch , & roll , & upAxisIndex ) )
{
return NULL ;
}
if ( ! pybullet_internalSetVector ( cameraTargetPositionObj , cameraTargetPosition ) )
{
PyErr_SetString ( SpamError , " Cannot convert cameraTargetPosition. " ) ;
return NULL ;
}
b3ComputeViewMatrixFromYawPitchRoll ( cameraTargetPosition , distance , yaw , pitch , roll , upAxisIndex , viewMatrix ) ;
pyResultList = PyTuple_New ( 16 ) ;
for ( i = 0 ; i < 16 ; i + + )
{
PyObject * item = PyFloat_FromDouble ( viewMatrix [ i ] ) ;
PyTuple_SetItem ( pyResultList , i , item ) ;
}
return pyResultList ;
}
///compute a projection matrix, helper function for b3RequestCameraImageSetCameraMatrices
static PyObject * pybullet_computeProjectionMatrix ( PyObject * self , PyObject * args , PyObject * keywds )
{
PyObject * pyResultList = 0 ;
float left ;
float right ;
float bottom ;
float top ;
float nearVal ;
float farVal ;
float projectionMatrix [ 16 ] ;
int i ;
// set camera resolution, optionally view, projection matrix, light position
static char * kwlist [ ] = { " left " , " right " , " bottom " , " top " , " nearVal " , " farVal " , NULL } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " ffffff " , kwlist , & left , & right , & bottom , & top , & nearVal , & farVal ) )
{
return NULL ;
}
b3ComputeProjectionMatrix ( left , right , bottom , top , nearVal , farVal , projectionMatrix ) ;
pyResultList = PyTuple_New ( 16 ) ;
for ( i = 0 ; i < 16 ; i + + )
{
PyObject * item = PyFloat_FromDouble ( projectionMatrix [ i ] ) ;
PyTuple_SetItem ( pyResultList , i , item ) ;
}
return pyResultList ;
}
static PyObject * pybullet_computeProjectionMatrixFOV ( PyObject * self , PyObject * args , PyObject * keywds )
{
float fov , aspect , nearVal , farVal ;
PyObject * pyResultList = 0 ;
float projectionMatrix [ 16 ] ;
int i ;
static char * kwlist [ ] = { " fov " , " aspect " , " nearVal " , " farVal " , NULL } ;
if ( ! PyArg_ParseTupleAndKeywords ( args , keywds , " ffff " , kwlist , & fov , & aspect , & nearVal , & farVal ) )
{
return NULL ;
}
b3ComputeProjectionMatrixFOV ( fov , aspect , nearVal , farVal , projectionMatrix ) ;
pyResultList = PyTuple_New ( 16 ) ;
for ( i = 0 ; i < 16 ; i + + )
{
PyObject * item = PyFloat_FromDouble ( projectionMatrix [ i ] ) ;
PyTuple_SetItem ( pyResultList , i , item ) ;
}
return pyResultList ;
}
2016-06-10 22:07:41 +00:00
// Render an image from the current timestep of the simulation
//
// Examples:
// renderImage() - default image resolution and camera position
// renderImage(w, h) - image resolution of (w,h), default camera
// renderImage(w, h, view[16], projection[16]) - set both resolution
// and initialize camera to the view and projection values
2016-07-08 21:29:58 +00:00
// renderImage(w, h, cameraPos, targetPos, cameraUp, nearVal, farVal) - set
// resolution and initialize camera based on camera position, target
// position, camera up and fulstrum near/far values.
// renderImage(w, h, cameraPos, targetPos, cameraUp, nearVal, farVal, fov) -
// set resolution and initialize camera based on camera position, target
// position, camera up, fulstrum near/far values and camera field of view.
2016-09-08 18:12:58 +00:00
// renderImage(w, h, targetPos, distance, yaw, pitch, upAxisIndex, nearVal,
// farVal, fov)
2016-08-02 18:12:23 +00:00
2016-06-10 22:07:41 +00:00
//
// Note if the (w,h) is too small, the objects may not appear based on
// where the camera has been set
//
// TODO(hellojas): fix image is cut off at head
// TODO(hellojas): should we add check to give minimum image resolution
// to see object based on camera position?
2016-11-17 23:15:52 +00:00
static PyObject * pybullet_renderImageObsolete ( PyObject * self , PyObject * args ) {
2016-09-08 18:12:58 +00:00
/// request an image from a simulated camera, using a software renderer.
2016-06-10 22:07:41 +00:00
struct b3CameraImageData imageData ;
2016-09-08 18:12:58 +00:00
PyObject * objViewMat , * objProjMat ;
PyObject * objCameraPos , * objTargetPos , * objCameraUp ;
2016-06-24 22:30:43 +00:00
int width , height ;
2016-09-08 18:12:58 +00:00
int size = PySequence_Size ( args ) ;
2016-06-10 22:07:41 +00:00
float viewMatrix [ 16 ] ;
float projectionMatrix [ 16 ] ;
2016-09-08 18:12:58 +00:00
2016-06-24 22:30:43 +00:00
float cameraPos [ 3 ] ;
float targetPos [ 3 ] ;
float cameraUp [ 3 ] ;
float left , right , bottom , top , aspect ;
2016-06-27 18:19:57 +00:00
float nearVal , farVal ;
2016-07-08 21:29:58 +00:00
float fov ;
2016-06-10 22:07:41 +00:00
// inialize cmd
b3SharedMemoryCommandHandle command ;
2016-06-13 17:11:28 +00:00
2016-09-08 18:12:58 +00:00
if ( 0 = = sm ) {
2016-07-08 21:29:58 +00:00
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
2016-06-13 17:11:28 +00:00
}
2016-06-10 22:07:41 +00:00
command = b3InitRequestCameraImage ( sm ) ;
2016-09-08 18:12:58 +00:00
if ( size = = 2 ) // only set camera resolution
2016-06-10 22:07:41 +00:00
{
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " ii " , & width , & height ) ) {
b3RequestCameraImageSetPixelResolution ( command , width , height ) ;
2016-07-08 21:29:58 +00:00
}
2016-09-08 18:12:58 +00:00
} else if ( size = = 4 ) // set camera resolution and view and projection matrix
2016-06-10 22:07:41 +00:00
{
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " iiOO " , & width , & height , & objViewMat ,
& objProjMat ) ) {
b3RequestCameraImageSetPixelResolution ( command , width , height ) ;
2016-06-10 22:07:41 +00:00
// set camera matrices only if set matrix function succeeds
2016-07-08 21:29:58 +00:00
if ( pybullet_internalSetMatrix ( objViewMat , viewMatrix ) & &
2016-09-08 18:12:58 +00:00
( pybullet_internalSetMatrix ( objProjMat , projectionMatrix ) ) ) {
b3RequestCameraImageSetCameraMatrices ( command , viewMatrix ,
projectionMatrix ) ;
} else {
2016-07-08 21:29:58 +00:00
PyErr_SetString ( SpamError , " Error parsing view or projection matrix. " ) ;
return NULL ;
}
}
2016-09-08 18:12:58 +00:00
} else if ( size = = 7 ) // set camera resolution, camera positions and
// calculate projection using near/far values.
2016-07-08 21:29:58 +00:00
{
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " iiOOOff " , & width , & height , & objCameraPos ,
& objTargetPos , & objCameraUp , & nearVal , & farVal ) ) {
b3RequestCameraImageSetPixelResolution ( command , width , height ) ;
2016-07-08 21:29:58 +00:00
if ( pybullet_internalSetVector ( objCameraPos , cameraPos ) & &
pybullet_internalSetVector ( objTargetPos , targetPos ) & &
2016-11-17 23:15:52 +00:00
pybullet_internalSetVector ( objCameraUp , cameraUp ) )
{
2016-09-08 18:12:58 +00:00
b3RequestCameraImageSetViewMatrix ( command , cameraPos , targetPos ,
cameraUp ) ;
} else {
PyErr_SetString ( SpamError ,
" Error parsing camera position, target or up. " ) ;
2016-07-08 21:29:58 +00:00
return NULL ;
}
2016-06-24 22:30:43 +00:00
2016-09-08 18:12:58 +00:00
aspect = width / height ;
2016-07-08 21:29:58 +00:00
left = - aspect * nearVal ;
right = aspect * nearVal ;
bottom = - nearVal ;
top = nearVal ;
2016-09-08 18:12:58 +00:00
b3RequestCameraImageSetProjectionMatrix ( command , left , right , bottom , top ,
nearVal , farVal ) ;
2016-07-08 21:29:58 +00:00
}
2016-09-08 18:12:58 +00:00
} else if ( size = = 8 ) // set camera resolution, camera positions and
// calculate projection using near/far values & field
// of view
2016-07-08 21:29:58 +00:00
{
2016-09-08 18:12:58 +00:00
if ( PyArg_ParseTuple ( args , " iiOOOfff " , & width , & height , & objCameraPos ,
& objTargetPos , & objCameraUp , & nearVal , & farVal ,
& fov ) ) {
b3RequestCameraImageSetPixelResolution ( command , width , height ) ;
2016-07-08 21:29:58 +00:00
if ( pybullet_internalSetVector ( objCameraPos , cameraPos ) & &
pybullet_internalSetVector ( objTargetPos , targetPos ) & &
2016-09-08 18:12:58 +00:00
pybullet_internalSetVector ( objCameraUp , cameraUp ) ) {
b3RequestCameraImageSetViewMatrix ( command , cameraPos , targetPos ,
cameraUp ) ;
} else {
PyErr_SetString ( SpamError ,
" Error parsing camera position, target or up. " ) ;
2016-07-08 21:29:58 +00:00
return NULL ;
2016-06-24 22:30:43 +00:00
}
2016-07-08 21:29:58 +00:00
2016-09-08 18:12:58 +00:00
aspect = width / height ;
b3RequestCameraImageSetFOVProjectionMatrix ( command , fov , aspect , nearVal ,
farVal ) ;
2016-06-24 22:30:43 +00:00
}
2016-09-08 18:12:58 +00:00
} else if ( size = = 11 ) {
int upAxisIndex = 1 ;
float camDistance , yaw , pitch , roll ;
// sometimes more arguments are better :-)
if ( PyArg_ParseTuple ( args , " iiOffffifff " , & width , & height , & objTargetPos ,
& camDistance , & yaw , & pitch , & roll , & upAxisIndex ,
& nearVal , & farVal , & fov ) ) {
b3RequestCameraImageSetPixelResolution ( command , width , height ) ;
if ( pybullet_internalSetVector ( objTargetPos , targetPos ) ) {
// printf("width = %d, height = %d, targetPos = %f,%f,%f, distance = %f,
// yaw = %f, pitch = %f, upAxisIndex = %d, near=%f, far=%f,
// fov=%f\n",width,height,targetPos[0],targetPos[1],targetPos[2],camDistance,yaw,pitch,upAxisIndex,nearVal,farVal,fov);
b3RequestCameraImageSetViewMatrix2 ( command , targetPos , camDistance , yaw ,
pitch , roll , upAxisIndex ) ;
aspect = width / height ;
b3RequestCameraImageSetFOVProjectionMatrix ( command , fov , aspect ,
nearVal , farVal ) ;
} else {
PyErr_SetString ( SpamError , " Error parsing camera target pos " ) ;
}
} else {
PyErr_SetString ( SpamError , " Error parsing arguments " ) ;
}
} else {
2016-07-08 21:29:58 +00:00
PyErr_SetString ( SpamError , " Invalid number of args passed to renderImage. " ) ;
return NULL ;
}
2016-09-08 18:12:58 +00:00
if ( b3CanSubmitCommand ( sm ) ) {
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
2016-05-10 07:57:54 +00:00
2016-09-08 18:12:58 +00:00
// b3RequestCameraImageSelectRenderer(command,ER_BULLET_HARDWARE_OPENGL);
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_CAMERA_IMAGE_COMPLETED ) {
PyObject * item2 ;
PyObject * pyResultList ; // store 4 elements in this result: width,
// height, rgbData, depth
2016-09-11 10:09:51 +00:00
# ifdef PYBULLET_USE_NUMPY
PyObject * pyRGB ;
PyObject * pyDep ;
PyObject * pySeg ;
int i , j , p ;
b3GetCameraImageData ( sm , & imageData ) ;
// TODO(hellojas): error handling if image size is 0
pyResultList = PyTuple_New ( 5 ) ;
PyTuple_SetItem ( pyResultList , 0 , PyInt_FromLong ( imageData . m_pixelWidth ) ) ;
PyTuple_SetItem ( pyResultList , 1 , PyInt_FromLong ( imageData . m_pixelHeight ) ) ;
int bytesPerPixel = 4 ; // Red, Green, Blue, and Alpha each 8 bit values
npy_intp rgb_dims [ 3 ] = { imageData . m_pixelHeight , imageData . m_pixelWidth ,
bytesPerPixel } ;
npy_intp dep_dims [ 2 ] = { imageData . m_pixelHeight , imageData . m_pixelWidth } ;
npy_intp seg_dims [ 2 ] = { imageData . m_pixelHeight , imageData . m_pixelWidth } ;
pyRGB = PyArray_SimpleNew ( 3 , rgb_dims , NPY_UINT8 ) ;
pyDep = PyArray_SimpleNew ( 2 , dep_dims , NPY_FLOAT32 ) ;
pySeg = PyArray_SimpleNew ( 2 , seg_dims , NPY_INT32 ) ;
memcpy ( PyArray_DATA ( pyRGB ) , imageData . m_rgbColorData ,
imageData . m_pixelHeight * imageData . m_pixelWidth * bytesPerPixel ) ;
memcpy ( PyArray_DATA ( pyDep ) , imageData . m_depthValues ,
imageData . m_pixelHeight * imageData . m_pixelWidth ) ;
memcpy ( PyArray_DATA ( pySeg ) , imageData . m_segmentationMaskValues ,
imageData . m_pixelHeight * imageData . m_pixelWidth ) ;
PyTuple_SetItem ( pyResultList , 2 , pyRGB ) ;
PyTuple_SetItem ( pyResultList , 3 , pyDep ) ;
PyTuple_SetItem ( pyResultList , 4 , pySeg ) ;
# else //PYBULLET_USE_NUMPY
PyObject * pylistRGB ;
2016-09-08 18:12:58 +00:00
PyObject * pylistDep ;
PyObject * pylistSeg ;
int i , j , p ;
b3GetCameraImageData ( sm , & imageData ) ;
// TODO(hellojas): error handling if image size is 0
pyResultList = PyTuple_New ( 5 ) ;
PyTuple_SetItem ( pyResultList , 0 , PyInt_FromLong ( imageData . m_pixelWidth ) ) ;
PyTuple_SetItem ( pyResultList , 1 , PyInt_FromLong ( imageData . m_pixelHeight ) ) ;
{
PyObject * item ;
int bytesPerPixel = 4 ; // Red, Green, Blue, and Alpha each 8 bit values
int num =
bytesPerPixel * imageData . m_pixelWidth * imageData . m_pixelHeight ;
pylistRGB = PyTuple_New ( num ) ;
pylistDep =
PyTuple_New ( imageData . m_pixelWidth * imageData . m_pixelHeight ) ;
pylistSeg =
PyTuple_New ( imageData . m_pixelWidth * imageData . m_pixelHeight ) ;
for ( i = 0 ; i < imageData . m_pixelWidth ; i + + ) {
for ( j = 0 ; j < imageData . m_pixelHeight ; j + + ) {
// TODO(hellojas): validate depth values make sense
int depIndex = i + j * imageData . m_pixelWidth ;
2016-06-27 01:18:30 +00:00
{
2016-09-08 18:12:58 +00:00
item = PyFloat_FromDouble ( imageData . m_depthValues [ depIndex ] ) ;
PyTuple_SetItem ( pylistDep , depIndex , item ) ;
2016-06-27 01:18:30 +00:00
}
{
2016-09-08 18:12:58 +00:00
item2 =
PyLong_FromLong ( imageData . m_segmentationMaskValues [ depIndex ] ) ;
PyTuple_SetItem ( pylistSeg , depIndex , item2 ) ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
for ( p = 0 ; p < bytesPerPixel ; p + + ) {
int pixelIndex =
bytesPerPixel * ( i + j * imageData . m_pixelWidth ) + p ;
item = PyInt_FromLong ( imageData . m_rgbColorData [ pixelIndex ] ) ;
PyTuple_SetItem ( pylistRGB , pixelIndex , item ) ;
}
}
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
}
PyTuple_SetItem ( pyResultList , 2 , pylistRGB ) ;
PyTuple_SetItem ( pyResultList , 3 , pylistDep ) ;
PyTuple_SetItem ( pyResultList , 4 , pylistSeg ) ;
2016-09-11 10:09:51 +00:00
return pyResultList ;
# endif //PYBULLET_USE_NUMPY
2016-09-08 18:12:58 +00:00
return pyResultList ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_applyExternalForce ( PyObject * self , PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int objectUniqueId , linkIndex , flags ;
double force [ 3 ] ;
double position [ 3 ] = { 0.0 , 0.0 , 0.0 } ;
PyObject * forceObj , * posObj ;
b3SharedMemoryCommandHandle command ;
b3SharedMemoryStatusHandle statusHandle ;
int size = PySequence_Size ( args ) ;
if ( size = = 5 ) {
if ( ! PyArg_ParseTuple ( args , " iiOOi " , & objectUniqueId , & linkIndex ,
& forceObj , & posObj , & flags ) ) {
PyErr_SetString ( SpamError , " applyBaseForce couldn't parse arguments " ) ;
2016-06-27 01:18:30 +00:00
return NULL ;
2016-09-08 18:12:58 +00:00
}
} else {
PyErr_SetString ( SpamError ,
" applyBaseForce needs 5 arguments: objectUniqueId, "
" linkIndex (-1 for base/root link), force [x,y,z], "
" position [x,y,z], flags " ) ;
2016-06-27 01:18:30 +00:00
2016-09-08 18:12:58 +00:00
return NULL ;
2016-06-27 01:18:30 +00:00
}
{
2016-09-08 18:12:58 +00:00
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( forceObj , " expected a sequence " ) ;
len = PySequence_Size ( forceObj ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < 3 ; i + + ) {
force [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
} else {
PyErr_SetString ( SpamError , " force needs a 3 coordinates [x,y,z]. " ) ;
2016-06-27 01:18:30 +00:00
Py_DECREF ( seq ) ;
return NULL ;
2016-09-08 18:12:58 +00:00
}
Py_DECREF ( seq ) ;
2016-06-27 01:18:30 +00:00
}
{
2016-09-08 18:12:58 +00:00
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( posObj , " expected a sequence " ) ;
len = PySequence_Size ( posObj ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < 3 ; i + + ) {
position [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
} else {
PyErr_SetString ( SpamError , " position needs a 3 coordinates [x,y,z]. " ) ;
Py_DECREF ( seq ) ;
return NULL ;
}
Py_DECREF ( seq ) ;
}
if ( ( flags ! = EF_WORLD_FRAME ) & & ( flags ! = EF_LINK_FRAME ) ) {
PyErr_SetString ( SpamError ,
" flag has to be either WORLD_FRAME or LINK_FRAME " ) ;
return NULL ;
}
command = b3ApplyExternalForceCommandInit ( sm ) ;
b3ApplyExternalForce ( command , objectUniqueId , linkIndex , force , position ,
flags ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
static PyObject * pybullet_applyExternalTorque ( PyObject * self , PyObject * args ) {
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
{
int objectUniqueId , linkIndex , flags ;
double torque [ 3 ] ;
PyObject * torqueObj ;
if ( PyArg_ParseTuple ( args , " iiOi " , & objectUniqueId , & linkIndex , & torqueObj ,
& flags ) ) {
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( torqueObj , " expected a sequence " ) ;
len = PySequence_Size ( torqueObj ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < 3 ; i + + ) {
torque [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
} else {
PyErr_SetString ( SpamError , " torque needs a 3 coordinates [x,y,z]. " ) ;
2016-06-27 01:18:30 +00:00
Py_DECREF ( seq ) ;
return NULL ;
2016-09-08 18:12:58 +00:00
}
Py_DECREF ( seq ) ;
if ( linkIndex < - 1 ) {
PyErr_SetString ( SpamError ,
" Invalid link index, has to be -1 or larger " ) ;
return NULL ;
}
if ( ( flags ! = EF_WORLD_FRAME ) & & ( flags ! = EF_LINK_FRAME ) ) {
PyErr_SetString ( SpamError ,
" flag has to be either WORLD_FRAME or LINK_FRAME " ) ;
return NULL ;
}
{
b3SharedMemoryStatusHandle statusHandle ;
b3SharedMemoryCommandHandle command =
b3ApplyExternalForceCommandInit ( sm ) ;
b3ApplyExternalTorque ( command , objectUniqueId , - 1 , torque , flags ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
}
}
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
static PyObject * pybullet_getQuaternionFromEuler ( PyObject * self ,
PyObject * args ) {
double rpy [ 3 ] ;
PyObject * eulerObj ;
if ( PyArg_ParseTuple ( args , " O " , & eulerObj ) ) {
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( eulerObj , " expected a sequence " ) ;
len = PySequence_Size ( eulerObj ) ;
if ( len = = 3 ) {
for ( i = 0 ; i < 3 ; i + + ) {
rpy [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
} else {
PyErr_SetString ( SpamError ,
" Euler angles need a 3 coordinates [roll, pitch, yaw]. " ) ;
Py_DECREF ( seq ) ;
return NULL ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
Py_DECREF ( seq ) ;
} else {
PyErr_SetString ( SpamError ,
" Euler angles need a 3 coordinates [roll, pitch, yaw]. " ) ;
return NULL ;
}
2016-06-27 01:18:30 +00:00
2016-09-08 18:12:58 +00:00
{
double phi , the , psi ;
double roll = rpy [ 0 ] ;
double pitch = rpy [ 1 ] ;
double yaw = rpy [ 2 ] ;
phi = roll / 2.0 ;
the = pitch / 2.0 ;
psi = yaw / 2.0 ;
2016-06-27 01:18:30 +00:00
{
2016-09-08 18:12:58 +00:00
double quat [ 4 ] = {
sin ( phi ) * cos ( the ) * cos ( psi ) - cos ( phi ) * sin ( the ) * sin ( psi ) ,
cos ( phi ) * sin ( the ) * cos ( psi ) + sin ( phi ) * cos ( the ) * sin ( psi ) ,
cos ( phi ) * cos ( the ) * sin ( psi ) - sin ( phi ) * sin ( the ) * cos ( psi ) ,
cos ( phi ) * cos ( the ) * cos ( psi ) + sin ( phi ) * sin ( the ) * sin ( psi ) } ;
// normalize the quaternion
double len = sqrt ( quat [ 0 ] * quat [ 0 ] + quat [ 1 ] * quat [ 1 ] +
quat [ 2 ] * quat [ 2 ] + quat [ 3 ] * quat [ 3 ] ) ;
quat [ 0 ] / = len ;
quat [ 1 ] / = len ;
quat [ 2 ] / = len ;
quat [ 3 ] / = len ;
{
PyObject * pylist ;
int i ;
pylist = PyTuple_New ( 4 ) ;
for ( i = 0 ; i < 4 ; i + + )
PyTuple_SetItem ( pylist , i , PyFloat_FromDouble ( quat [ i ] ) ) ;
return pylist ;
}
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-06-27 01:18:30 +00:00
}
2016-09-08 18:12:58 +00:00
/// quaternion <-> euler yaw/pitch/roll convention from URDF/SDF, see Gazebo
/// https://github.com/arpg/Gazebo/blob/master/gazebo/math/Quaternion.cc
static PyObject * pybullet_getEulerFromQuaternion ( PyObject * self ,
PyObject * args ) {
double squ ;
double sqx ;
double sqy ;
double sqz ;
2016-06-27 01:18:30 +00:00
2016-09-08 18:12:58 +00:00
double quat [ 4 ] ;
PyObject * quatObj ;
if ( PyArg_ParseTuple ( args , " O " , & quatObj ) ) {
PyObject * seq ;
int len , i ;
seq = PySequence_Fast ( quatObj , " expected a sequence " ) ;
len = PySequence_Size ( quatObj ) ;
if ( len = = 4 ) {
for ( i = 0 ; i < 4 ; i + + ) {
quat [ i ] = pybullet_internalGetFloatFromSequence ( seq , i ) ;
}
} else {
PyErr_SetString ( SpamError , " Quaternion need a 4 components [x,y,z,w]. " ) ;
Py_DECREF ( seq ) ;
return NULL ;
}
Py_DECREF ( seq ) ;
} else {
PyErr_SetString ( SpamError , " Quaternion need a 4 components [x,y,z,w]. " ) ;
return NULL ;
}
{
double rpy [ 3 ] ;
double sarg ;
sqx = quat [ 0 ] * quat [ 0 ] ;
sqy = quat [ 1 ] * quat [ 1 ] ;
sqz = quat [ 2 ] * quat [ 2 ] ;
squ = quat [ 3 ] * quat [ 3 ] ;
rpy [ 0 ] = atan2 ( 2 * ( quat [ 1 ] * quat [ 2 ] + quat [ 3 ] * quat [ 0 ] ) ,
squ - sqx - sqy + sqz ) ;
sarg = - 2 * ( quat [ 0 ] * quat [ 2 ] - quat [ 3 ] * quat [ 1 ] ) ;
rpy [ 1 ] = sarg < = - 1.0 ? - 0.5 * 3.141592538
: ( sarg > = 1.0 ? 0.5 * 3.141592538 : asin ( sarg ) ) ;
rpy [ 2 ] = atan2 ( 2 * ( quat [ 0 ] * quat [ 1 ] + quat [ 3 ] * quat [ 2 ] ) ,
squ + sqx - sqy - sqz ) ;
{
PyObject * pylist ;
int i ;
pylist = PyTuple_New ( 3 ) ;
for ( i = 0 ; i < 3 ; i + + )
PyTuple_SetItem ( pylist , i , PyFloat_FromDouble ( rpy [ i ] ) ) ;
return pylist ;
}
}
Py_INCREF ( Py_None ) ;
return Py_None ;
2016-08-10 01:40:12 +00:00
}
2016-09-13 22:37:46 +00:00
///Experimental Inverse Kinematics binding ,7-dof KUKA IIWA only
static PyObject * pybullet_calculateInverseKinematicsKuka ( PyObject * self ,
PyObject * args ) {
int size ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
size = PySequence_Size ( args ) ;
if ( size = = 2 )
{
int bodyIndex ;
2016-09-22 20:27:09 +00:00
int endEffectorLinkIndex ;
2016-09-13 22:37:46 +00:00
PyObject * targetPosObj ;
2016-09-22 20:27:09 +00:00
PyObject * targetOrnObj ;
if ( PyArg_ParseTuple ( args , " iiOO " , & bodyIndex , & endEffectorLinkIndex , & targetPosObj , & targetOrnObj ) )
2016-09-13 22:37:46 +00:00
{
double pos [ 3 ] ;
2016-09-20 18:10:13 +00:00
double ori [ 4 ] = { 0 , 1.0 , 0 , 0 } ;
2016-09-13 22:37:46 +00:00
2016-11-14 22:08:05 +00:00
if ( pybullet_internalSetVectord ( targetPosObj , pos ) & & pybullet_internalSetVector4d ( targetOrnObj , ori ) )
2016-09-13 22:37:46 +00:00
{
b3SharedMemoryStatusHandle statusHandle ;
int numPos = 0 ;
int resultBodyIndex ;
int result ;
2016-09-22 20:27:09 +00:00
b3SharedMemoryCommandHandle command = b3CalculateInverseKinematicsCommandInit ( sm , bodyIndex ) ;
b3CalculateInverseKinematicsAddTargetPositionWithOrientation ( command , 6 , pos , ori ) ;
2016-09-13 22:37:46 +00:00
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , command ) ;
result = b3GetStatusInverseKinematicsJointPositions ( statusHandle ,
& resultBodyIndex ,
& numPos ,
0 ) ;
if ( result & & numPos )
{
int i ;
PyObject * pylist ;
double * ikOutPutJointPos = ( double * ) malloc ( numPos * sizeof ( double ) ) ;
result = b3GetStatusInverseKinematicsJointPositions ( statusHandle ,
& resultBodyIndex ,
& numPos ,
ikOutPutJointPos ) ;
pylist = PyTuple_New ( numPos ) ;
for ( i = 0 ; i < numPos ; i + + )
{
PyTuple_SetItem ( pylist , i ,
PyFloat_FromDouble ( ikOutPutJointPos [ i ] ) ) ;
}
free ( ikOutPutJointPos ) ;
return pylist ;
}
else
{
PyErr_SetString ( SpamError ,
" Error in calculateInverseKinematics " ) ;
return NULL ;
}
} else
{
PyErr_SetString ( SpamError ,
" calculateInverseKinematics couldn't extract position vector3 " ) ;
return NULL ;
}
}
} else
{
PyErr_SetString ( SpamError ,
" calculateInverseKinematics expects 2 arguments, body index, "
" and target position for end effector " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-09-08 18:12:58 +00:00
/// Given an object id, joint positions, joint velocities and joint
/// accelerations,
/// compute the joint forces using Inverse Dynamics
static PyObject * pybullet_calculateInverseDynamics ( PyObject * self ,
PyObject * args ) {
int size ;
if ( 0 = = sm ) {
PyErr_SetString ( SpamError , " Not connected to physics server. " ) ;
return NULL ;
}
size = PySequence_Size ( args ) ;
if ( size = = 4 ) {
int bodyIndex ;
PyObject * objPositionsQ ;
PyObject * objVelocitiesQdot ;
PyObject * objAccelerations ;
if ( PyArg_ParseTuple ( args , " iOOO " , & bodyIndex , & objPositionsQ ,
& objVelocitiesQdot , & objAccelerations ) ) {
int szObPos = PySequence_Size ( objPositionsQ ) ;
int szObVel = PySequence_Size ( objVelocitiesQdot ) ;
int szObAcc = PySequence_Size ( objAccelerations ) ;
int numJoints = b3GetNumJoints ( sm , bodyIndex ) ;
if ( numJoints & & ( szObPos = = numJoints ) & & ( szObVel = = numJoints ) & &
( szObAcc = = numJoints ) ) {
int szInBytes = sizeof ( double ) * numJoints ;
int i ;
PyObject * pylist = 0 ;
double * jointPositionsQ = ( double * ) malloc ( szInBytes ) ;
double * jointVelocitiesQdot = ( double * ) malloc ( szInBytes ) ;
double * jointAccelerations = ( double * ) malloc ( szInBytes ) ;
double * jointForcesOutput = ( double * ) malloc ( szInBytes ) ;
for ( i = 0 ; i < numJoints ; i + + ) {
jointPositionsQ [ i ] =
pybullet_internalGetFloatFromSequence ( objPositionsQ , i ) ;
jointVelocitiesQdot [ i ] =
pybullet_internalGetFloatFromSequence ( objVelocitiesQdot , i ) ;
jointAccelerations [ i ] =
pybullet_internalGetFloatFromSequence ( objAccelerations , i ) ;
}
{
b3SharedMemoryStatusHandle statusHandle ;
int statusType ;
b3SharedMemoryCommandHandle commandHandle =
b3CalculateInverseDynamicsCommandInit (
sm , bodyIndex , jointPositionsQ , jointVelocitiesQdot ,
jointAccelerations ) ;
statusHandle = b3SubmitClientCommandAndWaitStatus ( sm , commandHandle ) ;
statusType = b3GetStatusType ( statusHandle ) ;
if ( statusType = = CMD_CALCULATED_INVERSE_DYNAMICS_COMPLETED ) {
int bodyUniqueId ;
int dofCount ;
b3GetStatusInverseDynamicsJointForces ( statusHandle , & bodyUniqueId ,
& dofCount , 0 ) ;
if ( dofCount ) {
b3GetStatusInverseDynamicsJointForces ( statusHandle , 0 , 0 ,
jointForcesOutput ) ;
{
{
int i ;
pylist = PyTuple_New ( dofCount ) ;
for ( i = 0 ; i < dofCount ; i + + )
PyTuple_SetItem ( pylist , i ,
PyFloat_FromDouble ( jointForcesOutput [ i ] ) ) ;
}
}
}
2016-08-10 01:40:12 +00:00
2016-09-08 18:12:58 +00:00
} else {
PyErr_SetString ( SpamError ,
" Internal error in calculateInverseDynamics " ) ;
}
}
free ( jointPositionsQ ) ;
free ( jointVelocitiesQdot ) ;
free ( jointAccelerations ) ;
free ( jointForcesOutput ) ;
if ( pylist ) return pylist ;
} else {
PyErr_SetString ( SpamError ,
" calculateInverseDynamics numJoints needs to be "
" positive and [joint positions], [joint velocities], "
" [joint accelerations] need to match the number of "
" joints. " ) ;
return NULL ;
}
2016-08-10 01:40:12 +00:00
2016-09-08 18:12:58 +00:00
} else {
PyErr_SetString ( SpamError ,
" calculateInverseDynamics expects 4 arguments, body "
" index, [joint positions], [joint velocities], [joint "
" accelerations]. " ) ;
return NULL ;
}
} else {
PyErr_SetString ( SpamError ,
" calculateInverseDynamics expects 4 arguments, body index, "
" [joint positions], [joint velocities], [joint "
" accelerations]. " ) ;
return NULL ;
}
Py_INCREF ( Py_None ) ;
return Py_None ;
}
2016-06-10 22:07:41 +00:00
2016-04-30 18:18:54 +00:00
static PyMethodDef SpamMethods [ ] = {
2016-06-10 22:07:41 +00:00
2016-09-08 18:12:58 +00:00
{ " connect " , pybullet_connectPhysicsServer , METH_VARARGS ,
" Connect to an existing physics server (using shared memory by default). " } ,
{ " disconnect " , pybullet_disconnectPhysicsServer , METH_VARARGS ,
" Disconnect from the physics server. " } ,
{ " resetSimulation " , pybullet_resetSimulation , METH_VARARGS ,
" Reset the simulation: remove all objects and start from an empty world. " } ,
2016-06-10 22:07:41 +00:00
2016-09-08 18:12:58 +00:00
{ " stepSimulation " , pybullet_stepSimulation , METH_VARARGS ,
" Step the simulation using forward dynamics. " } ,
2016-05-03 19:59:21 +00:00
2016-09-08 18:12:58 +00:00
{ " setGravity " , pybullet_setGravity , METH_VARARGS ,
" Set the gravity acceleration (x,y,z). " } ,
2016-05-10 07:57:54 +00:00
2016-09-08 18:12:58 +00:00
{ " setTimeStep " , pybullet_setTimeStep , METH_VARARGS ,
" Set the amount of time to proceed at each call to stepSimulation. (unit "
" is seconds, typically range is 0.01 or 0.001) " } ,
2016-05-10 07:57:54 +00:00
2016-12-01 06:24:20 +00:00
2016-09-08 22:15:58 +00:00
{ " setDefaultContactERP " , pybullet_setDefaultContactERP , METH_VARARGS ,
2016-09-08 22:22:41 +00:00
" Set the amount of contact penetration Error Recovery Paramater "
" (ERP) in each time step. \
This is an tuning parameter to control resting contact stability . "
" This value depends on the time step. " } ,
2016-06-27 01:18:30 +00:00
2016-07-18 06:50:11 +00:00
{ " setRealTimeSimulation " , pybullet_setRealTimeSimulation , METH_VARARGS ,
2016-09-08 22:22:41 +00:00
" Enable or disable real time simulation (using the real time clock, "
" RTC) in the physics server. Expects one integer argument, 0 or 1 " } ,
2016-07-18 06:50:11 +00:00
2016-12-01 06:24:20 +00:00
{ " setPhysicsEngineParameter " , ( PyCFunction ) pybullet_setPhysicsEngineParameter , METH_VARARGS | METH_KEYWORDS ,
" Set some internal physics engine parameter, such as cfm or erp etc. " } ,
2016-10-23 14:14:50 +00:00
{ " setInternalSimFlags " , pybullet_setInternalSimFlags , METH_VARARGS ,
" This is for experimental purposes, use at own risk, magic may or not happen " } ,
2016-12-01 06:24:20 +00:00
{ " loadURDF " , ( PyCFunction ) pybullet_loadURDF , METH_VARARGS | METH_KEYWORDS ,
2016-09-08 18:12:58 +00:00
" Create a multibody by loading a URDF file. " } ,
2016-06-15 21:21:04 +00:00
2016-09-08 18:12:58 +00:00
{ " loadSDF " , pybullet_loadSDF , METH_VARARGS ,
" Load multibodies from an SDF file. " } ,
2016-06-24 14:31:17 +00:00
2016-11-11 22:44:50 +00:00
{ " loadBullet " , pybullet_loadBullet , METH_VARARGS ,
" Restore the full state of the world from a .bullet file. " } ,
{ " saveBullet " , pybullet_saveBullet , METH_VARARGS ,
" Save the full state of the world to a .bullet file. " } ,
{ " loadMJCF " , pybullet_loadMJCF , METH_VARARGS ,
" Load multibodies from an MJCF file. " } ,
2016-11-14 22:08:05 +00:00
{ " createConstraint " , ( PyCFunction ) pybullet_createUserConstraint , METH_VARARGS | METH_KEYWORDS ,
" Create a constraint between two bodies. Returns a (int) unique id, if successfull. "
} ,
{ " removeConstraint " , ( PyCFunction ) pybullet_removeUserConstraint , METH_VARARGS | METH_KEYWORDS ,
" Remove a constraint using its unique id. "
} ,
2016-10-13 06:03:36 +00:00
{ " saveWorld " , pybullet_saveWorld , METH_VARARGS ,
2016-11-11 22:44:50 +00:00
" Save a approximate Python file to reproduce the current state of the world: saveWorld "
2016-10-13 06:03:36 +00:00
" (filename). (very preliminary and approximately) " } ,
2016-09-27 19:13:45 +00:00
{ " getNumBodies " , pybullet_getNumBodies , METH_VARARGS ,
" Get the number of bodies in the simulation. " } ,
{ " getBodyUniqueId " , pybullet_getBodyUniqueId , METH_VARARGS ,
" Get the unique id of the body, given a integer serial index in range [0.. number of bodies). " } ,
{ " getBodyInfo " , pybullet_getBodyInfo , METH_VARARGS ,
" Get the body info, given a body unique id. " } ,
2016-09-08 18:12:58 +00:00
{ " getBasePositionAndOrientation " , pybullet_getBasePositionAndOrientation ,
METH_VARARGS ,
" Get the world position and orientation of the base of the object. "
" (x,y,z) position vector and (x,y,z,w) quaternion orientation. " } ,
2016-06-15 21:21:04 +00:00
2016-09-08 18:12:58 +00:00
{ " resetBasePositionAndOrientation " ,
pybullet_resetBasePositionAndOrientation , METH_VARARGS ,
" Reset the world position and orientation of the base of the object "
" instantaneously, not through physics simulation. (x,y,z) position vector "
" and (x,y,z,w) quaternion orientation. " } ,
2016-06-24 14:31:17 +00:00
2016-11-28 23:11:34 +00:00
{ " getBaseVelocity " , pybullet_getBaseVelocity ,
METH_VARARGS ,
" Get the linear and angular velocity of the base of the object "
" in world space coordinates. "
" (x,y,z) linear velocity vector and (x,y,z) angular velocity vector. " } ,
{ " resetBaseVelocity " , ( PyCFunction ) pybullet_resetBaseVelocity , METH_VARARGS | METH_KEYWORDS ,
" Reset the linear and/or angular velocity of the base of the object "
" in world space coordinates. "
" linearVelocity (x,y,z) and angularVelocity (x,y,z). " } ,
2016-09-08 18:12:58 +00:00
{ " getNumJoints " , pybullet_getNumJoints , METH_VARARGS ,
" Get the number of joints for an object. " } ,
2016-06-24 14:31:17 +00:00
{ " getJointInfo " , pybullet_getJointInfo , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" Get the name and type info for a joint on a body. " } ,
2016-06-24 14:31:17 +00:00
{ " getJointState " , pybullet_getJointState , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" Get the state (position, velocity etc) for a joint on a body. " } ,
2016-09-23 22:57:35 +00:00
{ " getLinkState " , pybullet_getLinkState , METH_VARARGS ,
" Provides extra information such as the Cartesian world coordinates "
" center of mass (COM) of the link, relative to the world reference "
" frame. " } ,
2016-09-08 18:12:58 +00:00
{ " resetJointState " , pybullet_resetJointState , METH_VARARGS ,
" Reset the state (position, velocity etc) for a joint on a body "
" instantaneously, not through physics simulation. " } ,
2016-06-24 14:31:17 +00:00
{ " setJointMotorControl " , pybullet_setJointMotorControl , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" Set a single joint motor control mode and desired target value. There is "
" no immediate state change, stepSimulation will process the motors. " } ,
2016-06-27 01:18:30 +00:00
{ " applyExternalForce " , pybullet_applyExternalForce , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" for objectUniqueId, linkIndex (-1 for base/root link), apply a force "
" [x,y,z] at the a position [x,y,z], flag to select FORCE_IN_LINK_FRAME or "
" FORCE_IN_WORLD_FRAME coordinates " } ,
2016-06-27 01:18:30 +00:00
{ " applyExternalTorque " , pybullet_applyExternalTorque , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" for objectUniqueId, linkIndex (-1 for base/root link) apply a torque "
" [x,y,z] in Cartesian coordinates, flag to select TORQUE_IN_LINK_FRAME or "
" TORQUE_IN_WORLD_FRAME coordinates " } ,
2016-11-17 23:15:52 +00:00
{ " renderImage " , pybullet_renderImageObsolete , METH_VARARGS ,
" obsolete, please use getCameraImage and getViewProjectionMatrices instead "
} ,
{ " getCameraImage " , ( PyCFunction ) pybullet_getCameraImage , METH_VARARGS | METH_KEYWORDS ,
" Render an image (given the pixel resolution width, height, camera viewMatrix "
2016-12-06 23:38:09 +00:00
" , projectionMatrix, lightDirection, lightColor, lightDistance, shadow, lightAmbientCoeff, lightDiffuseCoeff, and lightSpecularCoeff), and return the "
2016-11-17 23:15:52 +00:00
" 8-8-8bit RGB pixel data and floating point depth values "
2016-09-11 10:35:12 +00:00
# ifdef PYBULLET_USE_NUMPY
2016-11-17 23:15:52 +00:00
" as NumPy arrays "
2016-09-11 10:35:12 +00:00
# endif
2016-11-17 23:15:52 +00:00
} ,
{ " computeViewMatrix " , ( PyCFunction ) pybullet_computeViewMatrix , METH_VARARGS | METH_KEYWORDS ,
" Compute a camera viewmatrix from camera eye, target position and up vector "
} ,
{ " computeViewMatrixFromYawPitchRoll " , ( PyCFunction ) pybullet_computeViewMatrixFromYawPitchRoll , METH_VARARGS | METH_KEYWORDS ,
" Compute a camera viewmatrix from camera eye, target position and up vector "
} ,
{ " computeProjectionMatrix " , ( PyCFunction ) pybullet_computeProjectionMatrix , METH_VARARGS | METH_KEYWORDS ,
" Compute a camera projection matrix from screen left/right/bottom/top/near/far values "
} ,
{ " computeProjectionMatrixFOV " , ( PyCFunction ) pybullet_computeProjectionMatrixFOV , METH_VARARGS | METH_KEYWORDS ,
" Compute a camera projection matrix from fov, aspect ratio, near, far values "
} ,
2016-06-27 01:18:30 +00:00
2016-11-11 00:18:20 +00:00
{ " getContactPoints " , ( PyCFunction ) pybullet_getContactPointData , METH_VARARGS | METH_KEYWORDS ,
2016-11-10 05:01:04 +00:00
" Return existing contact points after the stepSimulation command. "
" Optional arguments one or two object unique "
2016-09-08 18:12:58 +00:00
" ids, that need to be involved in the contact. " } ,
2016-11-11 00:18:20 +00:00
{ " getClosestPoints " , ( PyCFunction ) pybullet_getClosestPointData , METH_VARARGS | METH_KEYWORDS ,
2016-11-10 05:01:04 +00:00
" Compute the closest points between two objects, if the distance is below a given threshold. "
" Input is two objects unique ids and distance threshold. "
} ,
2016-11-11 00:18:20 +00:00
{ " getOverlappingObjects " , ( PyCFunction ) pybullet_getOverlappingObjects , METH_VARARGS | METH_KEYWORDS ,
2016-11-10 05:01:04 +00:00
" Return all the objects that have overlap with a given "
" axis-aligned bounding box volume (AABB). "
" Input are two vectors defining the AABB in world space [min_x,min_y,min_z],[max_x,max_y,max_z]. "
} ,
2016-11-14 15:39:34 +00:00
{ " addUserDebugLine " , ( PyCFunction ) pybullet_addUserDebugLine , METH_VARARGS | METH_KEYWORDS ,
" Add a user debug draw line with lineFrom[3], lineTo[3], lineColorRGB[3], lineWidth, lifeTime. "
" A lifeTime of 0 means permanent until removed. Returns a unique id for the user debug item. "
} ,
{ " addUserDebugText " , ( PyCFunction ) pybullet_addUserDebugText , METH_VARARGS | METH_KEYWORDS ,
" Add a user debug draw line with text, textPosition[3], textSize and lifeTime in seconds "
" A lifeTime of 0 means permanent until removed. Returns a unique id for the user debug item. "
} ,
{ " removeUserDebugItem " , ( PyCFunction ) pybullet_removeUserDebugItem , METH_VARARGS | METH_KEYWORDS ,
" remove a user debug draw item, giving its unique id "
} ,
{ " removeAllUserDebugItems " , ( PyCFunction ) pybullet_removeAllUserDebugItems , METH_VARARGS | METH_KEYWORDS ,
" remove all user debug draw items "
} ,
2016-11-21 15:42:11 +00:00
{ " setDebugObjectColor " , ( PyCFunction ) pybullet_setDebugObjectColor , METH_VARARGS | METH_KEYWORDS ,
" Override the wireframe debug drawing color for a particular object unique id / link index. "
" If you ommit the color, the custom color will be removed. "
} ,
2016-11-14 15:39:34 +00:00
2016-10-22 00:48:06 +00:00
{ " getVisualShapeData " , pybullet_getVisualShapeData , METH_VARARGS ,
2016-10-19 05:05:28 +00:00
" Return the visual shape information for one object. " } ,
2016-10-22 00:48:06 +00:00
{ " resetVisualShapeData " , pybullet_resetVisualShapeData , METH_VARARGS ,
" Reset part of the visual shape information for one object. " } ,
{ " loadTexture " , pybullet_loadTexture , METH_VARARGS ,
" Load texture file. " } ,
2016-06-27 01:18:30 +00:00
{ " getQuaternionFromEuler " , pybullet_getQuaternionFromEuler , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" Convert Euler [roll, pitch, yaw] as in URDF/SDF convention, to "
" quaternion [x,y,z,w] " } ,
2016-06-27 01:18:30 +00:00
{ " getEulerFromQuaternion " , pybullet_getEulerFromQuaternion , METH_VARARGS ,
2016-09-08 18:12:58 +00:00
" Convert quaternion [x,y,z,w] to Euler [roll, pitch, yaw] as in URDF/SDF "
" convention " } ,
{ " calculateInverseDynamics " , pybullet_calculateInverseDynamics ,
METH_VARARGS ,
" Given an object id, joint positions, joint velocities and joint "
" accelerations, compute the joint forces using Inverse Dynamics " } ,
2016-09-13 22:37:46 +00:00
{ " calculateInverseKinematicsKuka " , pybullet_calculateInverseKinematicsKuka ,
METH_VARARGS ,
" Experimental, KUKA IIWA only: Given an object id, "
" current joint positions and target position "
" for the end effector, "
" compute the inverse kinematics and return the new joint state " } ,
2016-09-08 18:12:58 +00:00
// todo(erwincoumans)
// saveSnapshot
// loadSnapshot
// raycast info
2016-09-13 22:37:46 +00:00
// object names
2016-11-10 05:01:04 +00:00
// collision query
2016-09-08 18:12:58 +00:00
{ NULL , NULL , 0 , NULL } /* Sentinel */
2016-04-30 18:18:54 +00:00
} ;
2016-05-10 07:57:54 +00:00
# if PY_MAJOR_VERSION >= 3
2016-09-08 18:12:58 +00:00
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT , " pybullet " , /* m_name */
" Python bindings for Bullet Physics Robotics API (also known as Shared "
" Memory API) " , /* m_doc */
- 1 , /* m_size */
SpamMethods , /* m_methods */
NULL , /* m_reload */
NULL , /* m_traverse */
NULL , /* m_clear */
NULL , /* m_free */
} ;
2016-05-10 07:57:54 +00:00
# endif
2016-04-30 18:18:54 +00:00
PyMODINIT_FUNC
2016-05-10 07:57:54 +00:00
# if PY_MAJOR_VERSION >= 3
PyInit_pybullet ( void )
# else
2016-04-30 18:18:54 +00:00
initpybullet ( void )
2016-05-10 07:57:54 +00:00
# endif
2016-04-30 18:18:54 +00:00
{
2016-09-08 18:12:58 +00:00
PyObject * m ;
2016-05-10 07:57:54 +00:00
# if PY_MAJOR_VERSION >= 3
2016-09-08 18:12:58 +00:00
m = PyModule_Create ( & moduledef ) ;
2016-05-10 07:57:54 +00:00
# else
2016-09-08 18:12:58 +00:00
m = Py_InitModule3 ( " pybullet " , SpamMethods , " Python bindings for Bullet " ) ;
2016-05-10 07:57:54 +00:00
# endif
2016-05-18 22:07:42 +00:00
# if PY_MAJOR_VERSION >= 3
2016-09-08 18:12:58 +00:00
if ( m = = NULL ) return m ;
2016-05-18 22:07:42 +00:00
# else
2016-09-08 18:12:58 +00:00
if ( m = = NULL ) return ;
2016-05-18 22:07:42 +00:00
# endif
2016-09-08 18:12:58 +00:00
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
2016-11-04 20:15:10 +00:00
PyModule_AddIntConstant ( m , " UDP " , eCONNECT_UDP ) ; // user read
2016-09-08 18:12:58 +00:00
PyModule_AddIntConstant ( m , " TORQUE_CONTROL " , CONTROL_MODE_TORQUE ) ;
PyModule_AddIntConstant ( m , " VELOCITY_CONTROL " ,
CONTROL_MODE_VELOCITY ) ; // user read
PyModule_AddIntConstant ( m , " POSITION_CONTROL " ,
CONTROL_MODE_POSITION_VELOCITY_PD ) ; // user read
PyModule_AddIntConstant ( m , " LINK_FRAME " , EF_LINK_FRAME ) ;
PyModule_AddIntConstant ( m , " WORLD_FRAME " , EF_WORLD_FRAME ) ;
2016-11-10 05:01:04 +00:00
PyModule_AddIntConstant ( m , " CONTACT_REPORT_EXISTING " , CONTACT_QUERY_MODE_REPORT_EXISTING_CONTACT_POINTS ) ;
PyModule_AddIntConstant ( m , " CONTACT_RECOMPUTE_CLOSEST " , CONTACT_QUERY_MODE_COMPUTE_CLOSEST_POINTS ) ;
2016-09-08 18:12:58 +00:00
SpamError = PyErr_NewException ( " pybullet.error " , NULL , NULL ) ;
Py_INCREF ( SpamError ) ;
PyModule_AddObject ( m , " error " , SpamError ) ;
2016-09-11 10:09:51 +00:00
# ifdef PYBULLET_USE_NUMPY
// Initialize numpy array.
import_array ( ) ;
# endif //PYBULLET_USE_NUMPY
2016-05-10 07:57:54 +00:00
# if PY_MAJOR_VERSION >= 3
2016-09-08 18:12:58 +00:00
return m ;
2016-05-10 07:57:54 +00:00
# endif
2016-04-30 18:18:54 +00:00
}