implement PyBullet removeState command. Fixes Issue #2163

https://github.com/bulletphysics/bullet3/issues/2163
This commit is contained in:
erwincoumans
2019-04-03 20:06:40 -07:00
parent c033c8b22f
commit 6951aaf26a
9 changed files with 132 additions and 7 deletions

View File

@@ -108,6 +108,25 @@ B3_SHARED_API b3SharedMemoryCommandHandle b3LoadStateCommandInit(b3PhysicsClient
return 0; return 0;
} }
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveStateCommand(b3PhysicsClientHandle physClient, int stateId)
{
PhysicsClient* cl = (PhysicsClient*)physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
if (cl->canSubmitCommand())
{
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type = CMD_REMOVE_STATE;
command->m_updateFlags = 0;
command->m_loadStateArguments.m_fileName[0] = 0;
command->m_loadStateArguments.m_stateId = stateId;
return (b3SharedMemoryCommandHandle)command;
}
return 0;
}
B3_SHARED_API int b3LoadStateSetStateId(b3SharedMemoryCommandHandle commandHandle, int stateId) B3_SHARED_API int b3LoadStateSetStateId(b3SharedMemoryCommandHandle commandHandle, int stateId)
{ {
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle; struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;

View File

@@ -375,6 +375,7 @@ extern "C"
B3_SHARED_API int b3LoadUrdfCommandSetGlobalScaling(b3SharedMemoryCommandHandle commandHandle, double globalScaling); B3_SHARED_API int b3LoadUrdfCommandSetGlobalScaling(b3SharedMemoryCommandHandle commandHandle, double globalScaling);
B3_SHARED_API b3SharedMemoryCommandHandle b3SaveStateCommandInit(b3PhysicsClientHandle physClient); B3_SHARED_API b3SharedMemoryCommandHandle b3SaveStateCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRemoveStateCommand(b3PhysicsClientHandle physClient, int stateId);
B3_SHARED_API int b3GetStatusGetStateId(b3SharedMemoryStatusHandle statusHandle); B3_SHARED_API int b3GetStatusGetStateId(b3SharedMemoryStatusHandle statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadStateCommandInit(b3PhysicsClientHandle physClient); B3_SHARED_API b3SharedMemoryCommandHandle b3LoadStateCommandInit(b3PhysicsClientHandle physClient);

View File

@@ -1429,6 +1429,8 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus()
case CMD_SYNC_USER_DATA_COMPLETED: case CMD_SYNC_USER_DATA_COMPLETED:
case CMD_REMOVE_USER_DATA_COMPLETED: case CMD_REMOVE_USER_DATA_COMPLETED:
case CMD_ADD_USER_DATA_COMPLETED: case CMD_ADD_USER_DATA_COMPLETED:
case CMD_REMOVE_STATE_FAILED:
case CMD_REMOVE_STATE_COMPLETED:
{ {
break; break;
} }

View File

@@ -1159,6 +1159,14 @@ void PhysicsDirect::postProcessStatus(const struct SharedMemoryStatus& serverCmd
} }
break; break;
} }
case CMD_REMOVE_STATE_FAILED:
{
break;
}
case CMD_REMOVE_STATE_COMPLETED:
{
break;
}
default: default:
{ {
//b3Warning("Unknown server status type"); //b3Warning("Unknown server status type");

View File

@@ -10777,7 +10777,7 @@ bool PhysicsServerCommandProcessor::processLoadTextureCommand(const struct Share
bool PhysicsServerCommandProcessor::processSaveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) bool PhysicsServerCommandProcessor::processSaveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{ {
BT_PROFILE("CMD_RESTORE_STATE"); BT_PROFILE("CMD_SAVE_STATE");
bool hasStatus = true; bool hasStatus = true;
SharedMemoryStatus& serverCmd = serverStatusOut; SharedMemoryStatus& serverCmd = serverStatusOut;
serverCmd.m_type = CMD_SAVE_STATE_FAILED; serverCmd.m_type = CMD_SAVE_STATE_FAILED;
@@ -10791,15 +10791,57 @@ bool PhysicsServerCommandProcessor::processSaveStateCommand(const struct SharedM
if (bulletFile->ok()) if (bulletFile->ok())
{ {
serverCmd.m_type = CMD_SAVE_STATE_COMPLETED; serverCmd.m_type = CMD_SAVE_STATE_COMPLETED;
serverCmd.m_saveStateResultArgs.m_stateId = m_data->m_savedStates.size(); //re-use state if available
int reuseStateId = -1;
for (int i = 0; i < m_data->m_savedStates.size(); i++)
{
if (m_data->m_savedStates[i].m_bulletFile == 0)
{
reuseStateId = i;
break;
}
}
SaveStateData sd; SaveStateData sd;
sd.m_bulletFile = bulletFile; sd.m_bulletFile = bulletFile;
sd.m_serializer = ser; sd.m_serializer = ser;
if (reuseStateId >= 0)
{
serverCmd.m_saveStateResultArgs.m_stateId = reuseStateId;
m_data->m_savedStates[reuseStateId] = sd;
}
else
{
serverCmd.m_saveStateResultArgs.m_stateId = m_data->m_savedStates.size();
m_data->m_savedStates.push_back(sd); m_data->m_savedStates.push_back(sd);
} }
}
return hasStatus; return hasStatus;
} }
bool PhysicsServerCommandProcessor::processRemoveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{
BT_PROFILE("CMD_REMOVE_STATE");
bool hasStatus = true;
SharedMemoryStatus& serverCmd = serverStatusOut;
serverCmd.m_type = CMD_REMOVE_STATE_FAILED;
if (clientCmd.m_loadStateArguments.m_stateId >= 0)
{
if (clientCmd.m_loadStateArguments.m_stateId < m_data->m_savedStates.size())
{
SaveStateData& sd = m_data->m_savedStates[clientCmd.m_loadStateArguments.m_stateId];
delete sd.m_bulletFile;
delete sd.m_serializer;
sd.m_bulletFile = 0;
sd.m_serializer = 0;
serverCmd.m_type = CMD_REMOVE_STATE_COMPLETED;
}
}
return hasStatus;
}
bool PhysicsServerCommandProcessor::processRestoreStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes) bool PhysicsServerCommandProcessor::processRestoreStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
{ {
BT_PROFILE("CMD_RESTORE_STATE"); BT_PROFILE("CMD_RESTORE_STATE");
@@ -10817,9 +10859,12 @@ bool PhysicsServerCommandProcessor::processRestoreStateCommand(const struct Shar
if (clientCmd.m_loadStateArguments.m_stateId < m_data->m_savedStates.size()) if (clientCmd.m_loadStateArguments.m_stateId < m_data->m_savedStates.size())
{ {
bParse::btBulletFile* bulletFile = m_data->m_savedStates[clientCmd.m_loadStateArguments.m_stateId].m_bulletFile; bParse::btBulletFile* bulletFile = m_data->m_savedStates[clientCmd.m_loadStateArguments.m_stateId].m_bulletFile;
if (bulletFile)
{
ok = importer->convertAllObjects(bulletFile); ok = importer->convertAllObjects(bulletFile);
} }
} }
}
else else
{ {
bool found = false; bool found = false;
@@ -11328,6 +11373,11 @@ bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryComm
hasStatus = processSaveStateCommand(clientCmd, serverStatusOut, bufferServerToClient, bufferSizeInBytes); hasStatus = processSaveStateCommand(clientCmd, serverStatusOut, bufferServerToClient, bufferSizeInBytes);
break; break;
} }
case CMD_REMOVE_STATE:
{
hasStatus = processRemoveStateCommand(clientCmd, serverStatusOut, bufferServerToClient, bufferSizeInBytes);
break;
}
case CMD_LOAD_BULLET: case CMD_LOAD_BULLET:
{ {

View File

@@ -81,6 +81,7 @@ protected:
bool processLoadMJCFCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); bool processLoadMJCFCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRestoreStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); bool processRestoreStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSaveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); bool processSaveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRemoveStateCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processSyncUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); bool processSyncUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); bool processRequestUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processAddUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes); bool processAddUserDataCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);

View File

@@ -7,8 +7,8 @@
//Please don't replace an existing magic number: //Please don't replace an existing magic number:
//instead, only ADD a new one at the top, comment-out previous one //instead, only ADD a new one at the top, comment-out previous one
#define SHARED_MEMORY_MAGIC_NUMBER 201904030
#define SHARED_MEMORY_MAGIC_NUMBER 201902120 //#define SHARED_MEMORY_MAGIC_NUMBER 201902120
//#define SHARED_MEMORY_MAGIC_NUMBER 201811260 //#define SHARED_MEMORY_MAGIC_NUMBER 201811260
//#define SHARED_MEMORY_MAGIC_NUMBER 201810250 //#define SHARED_MEMORY_MAGIC_NUMBER 201810250
//#define SHARED_MEMORY_MAGIC_NUMBER 201809030 //#define SHARED_MEMORY_MAGIC_NUMBER 201809030
@@ -93,6 +93,7 @@ enum EnumSharedMemoryClientCommand
CMD_REQUEST_PHYSICS_SIMULATION_PARAMETERS, CMD_REQUEST_PHYSICS_SIMULATION_PARAMETERS,
CMD_SAVE_STATE, CMD_SAVE_STATE,
CMD_RESTORE_STATE, CMD_RESTORE_STATE,
CMD_REMOVE_STATE,
CMD_REQUEST_COLLISION_SHAPE_INFO, CMD_REQUEST_COLLISION_SHAPE_INFO,
CMD_SYNC_USER_DATA, CMD_SYNC_USER_DATA,
@@ -218,6 +219,8 @@ enum EnumSharedMemoryServerStatus
CMD_ADD_USER_DATA_FAILED, CMD_ADD_USER_DATA_FAILED,
CMD_REMOVE_USER_DATA_COMPLETED, CMD_REMOVE_USER_DATA_COMPLETED,
CMD_REMOVE_USER_DATA_FAILED, CMD_REMOVE_USER_DATA_FAILED,
CMD_REMOVE_STATE_COMPLETED,
CMD_REMOVE_STATE_FAILED,
//don't go beyond 'CMD_MAX_SERVER_COMMANDS! //don't go beyond 'CMD_MAX_SERVER_COMMANDS!
CMD_MAX_SERVER_COMMANDS CMD_MAX_SERVER_COMMANDS
}; };

View File

@@ -80,6 +80,10 @@ setupWorld()
#both restore from file or from in-memory state should work #both restore from file or from in-memory state should work
p.restoreState(fileName="state.bullet") p.restoreState(fileName="state.bullet")
stateId = p.saveState() stateId = p.saveState()
print("stateId=",stateId)
p.removeState(stateId)
stateId = p.saveState()
print("stateId=",stateId)
if verbose: if verbose:
p.setInternalSimFlags(1) p.setInternalSimFlags(1)

View File

@@ -1160,6 +1160,40 @@ static PyObject* pybullet_saveState(PyObject* self, PyObject* args, PyObject* ke
return PyInt_FromLong(stateId); return PyInt_FromLong(stateId);
} }
static PyObject* pybullet_removeState(PyObject* self, PyObject* args, PyObject* keywds)
{
{
int stateUniqueId = -1;
b3PhysicsClientHandle sm = 0;
int physicsClientId = 0;
static char* kwlist[] = { "stateUniqueId", "physicsClientId", NULL };
if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|i", kwlist, &stateUniqueId, &physicsClientId))
{
return NULL;
}
sm = getPhysicsClient(physicsClientId);
if (sm == 0)
{
PyErr_SetString(SpamError, "Not connected to physics server.");
return NULL;
}
if (stateUniqueId >= 0)
{
b3SharedMemoryStatusHandle statusHandle;
int statusType;
if (b3CanSubmitCommand(sm))
{
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitRemoveStateCommand(sm, stateUniqueId));
statusType = b3GetStatusType(statusHandle);
}
}
}
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* pybullet_loadMJCF(PyObject* self, PyObject* args, PyObject* keywds) static PyObject* pybullet_loadMJCF(PyObject* self, PyObject* args, PyObject* keywds)
{ {
const char* mjcfFileName = ""; const char* mjcfFileName = "";
@@ -10329,6 +10363,9 @@ static PyMethodDef SpamMethods[] = {
{"saveState", (PyCFunction)pybullet_saveState, METH_VARARGS | METH_KEYWORDS, {"saveState", (PyCFunction)pybullet_saveState, METH_VARARGS | METH_KEYWORDS,
"Save the full state of the world to memory."}, "Save the full state of the world to memory."},
{ "removeState", (PyCFunction)pybullet_removeState, METH_VARARGS | METH_KEYWORDS,
"Remove a state created using saveState by its state unique id." },
{"loadMJCF", (PyCFunction)pybullet_loadMJCF, METH_VARARGS | METH_KEYWORDS, {"loadMJCF", (PyCFunction)pybullet_loadMJCF, METH_VARARGS | METH_KEYWORDS,
"Load multibodies from an MJCF file."}, "Load multibodies from an MJCF file."},