update bullet so it actually works

Moved the addSourceDirectory for physics/Bullet into the Engine/Source/CMakeLists.txt file that way it can actually appear where we expect it to in the solution explorer.
This commit is contained in:
marauder2k7 2026-06-03 15:08:51 +01:00
parent c7be48130a
commit 13fa178cf6
5986 changed files with 1811270 additions and 453803 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
#ifndef BT_CONVERT_GRPC_BULLET_H
#define BT_CONVERT_GRPC_BULLET_H
#include "../PhysicsClientC_API.h"
namespace pybullet_grpc
{
class PyBulletCommand;
class PyBulletStatus;
}; // namespace pybullet_grpc
struct SharedMemoryCommand* convertGRPCToBulletCommand(const pybullet_grpc::PyBulletCommand& grpcCommand, struct SharedMemoryCommand& cmd);
pybullet_grpc::PyBulletCommand* convertBulletToGRPCCommand(const struct SharedMemoryCommand& clientCmd, pybullet_grpc::PyBulletCommand& grpcCommand);
bool convertGRPCToStatus(const pybullet_grpc::PyBulletStatus& grpcReply, struct SharedMemoryStatus& serverStatus, char* bufferServerToClient, int bufferSizeInBytes);
bool convertStatusToGRPC(const struct SharedMemoryStatus& serverStatus, char* bufferServerToClient, int bufferSizeInBytes, pybullet_grpc::PyBulletStatus& grpcReply);
#endif //BT_CONVERT_GRPC_BULLET_H

View file

@ -0,0 +1,298 @@
///PyBullet / BulletRobotics GRPC server.
///works as standalone GRPC server as as a GRPC server bridge,
///connecting to a local physics server using shared memory
#include <stdio.h>
#include "../../CommonInterfaces/CommonGUIHelperInterface.h"
#include "Bullet3Common/b3CommandLineArgs.h"
#include "PhysicsClientC_API.h"
#ifdef NO_SHARED_MEMORY
#include "PhysicsServerCommandProcessor.h"
typedef PhysicsServerCommandProcessor MyCommandProcessor;
#else
#include "SharedMemoryCommandProcessor.h"
typedef SharedMemoryCommandProcessor MyCommandProcessor;
#endif //NO_SHARED_MEMORY
#include "SharedMemoryCommands.h"
#include "Bullet3Common/b3AlignedObjectArray.h"
#include "PhysicsServerCommandProcessor.h"
#include "../Utils/b3Clock.h"
#include <memory>
#include <iostream>
#include <string>
#include <thread>
#include <grpc++/grpc++.h>
#include <grpc/support/log.h>
#include "SharedMemory/grpc/proto/pybullet.grpc.pb.h"
using grpc::Server;
using grpc::ServerAsyncResponseWriter;
using grpc::ServerBuilder;
using grpc::ServerCompletionQueue;
using grpc::ServerContext;
using grpc::Status;
using pybullet_grpc::PyBulletAPI;
using pybullet_grpc::PyBulletCommand;
using pybullet_grpc::PyBulletStatus;
bool gVerboseNetworkMessagesServer = true;
#include "ConvertGRPCBullet.h"
class ServerImpl final
{
public:
~ServerImpl()
{
server_->Shutdown();
// Always shutdown the completion queue after the server.
cq_->Shutdown();
}
void Run(MyCommandProcessor* comProc, const std::string& hostNamePort)
{
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(hostNamePort, grpc::InsecureServerCredentials());
// Register "service_" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *asynchronous* service.
builder.RegisterService(&service_);
// Get hold of the completion queue used for the asynchronous communication
// with the gRPC runtime.
cq_ = builder.AddCompletionQueue();
// Finally assemble the server.
server_ = builder.BuildAndStart();
std::cout << "Standalone Bullet Physics GRPC server listening on " << hostNamePort << std::endl;
// Proceed to the server's main loop.
HandleRpcs(comProc);
}
private:
// Class encompasing the state and logic needed to serve a request.
class CallData
{
public:
// Take in the "service" instance (in this case representing an asynchronous
// server) and the completion queue "cq" used for asynchronous communication
// with the gRPC runtime.
CallData(PyBulletAPI::AsyncService* service, ServerCompletionQueue* cq, MyCommandProcessor* comProc)
: service_(service), cq_(cq), responder_(&ctx_), status_(CREATE), m_finished(false), m_comProc(comProc)
{
// Invoke the serving logic right away.
Proceed();
}
enum CallStatus
{
CREATE,
PROCESS,
FINISH,
TERMINATE
};
CallStatus Proceed()
{
if (status_ == CREATE)
{
// Make this instance progress to the PROCESS state.
status_ = PROCESS;
// As part of the initial CREATE state, we *request* that the system
// start processing SayHello requests. In this request, "this" acts are
// the tag uniquely identifying the request (so that different CallData
// instances can serve different requests concurrently), in this case
// the memory address of this CallData instance.
service_->RequestSubmitCommand(&ctx_, &m_command, &responder_, cq_, cq_,
this);
}
else if (status_ == PROCESS)
{
// Spawn a new CallData instance to serve new clients while we process
// the one for this CallData. The instance will deallocate itself as
// part of its FINISH state.
new CallData(service_, cq_, m_comProc);
status_ = FINISH;
std::string replyString;
// The actual processing.
SharedMemoryStatus serverStatus;
b3AlignedObjectArray<char> buffer;
buffer.resize(SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
SharedMemoryCommand cmd;
SharedMemoryCommand* cmdPtr = 0;
m_status.set_statustype(CMD_UNKNOWN_COMMAND_FLUSHED);
if (m_command.has_checkversioncommand())
{
m_status.set_statustype(CMD_CLIENT_COMMAND_COMPLETED);
m_status.mutable_checkversionstatus()->set_serverversion(SHARED_MEMORY_MAGIC_NUMBER);
}
else
{
cmdPtr = convertGRPCToBulletCommand(m_command, cmd);
if (cmdPtr)
{
bool hasStatus = m_comProc->processCommand(*cmdPtr, serverStatus, &buffer[0], buffer.size());
m_comProc->reportNotifications();
double timeOutInSeconds = 10;
b3Clock clock;
double startTimeSeconds = clock.getTimeInSeconds();
double curTimeSeconds = clock.getTimeInSeconds();
while ((!hasStatus) && ((curTimeSeconds - startTimeSeconds) < timeOutInSeconds))
{
hasStatus = m_comProc->receiveStatus(serverStatus, &buffer[0], buffer.size());
curTimeSeconds = clock.getTimeInSeconds();
}
if (gVerboseNetworkMessagesServer)
{
//printf("buffer.size = %d\n", buffer.size());
printf("serverStatus.m_numDataStreamBytes = %d\n", serverStatus.m_numDataStreamBytes);
}
if (hasStatus)
{
b3AlignedObjectArray<unsigned char> packetData;
unsigned char* statBytes = (unsigned char*)&serverStatus;
convertStatusToGRPC(serverStatus, &buffer[0], buffer.size(), m_status);
}
}
if (m_command.has_terminateservercommand())
{
status_ = TERMINATE;
}
}
// And we are done! Let the gRPC runtime know we've finished, using the
// memory address of this instance as the uniquely identifying tag for
// the event.
responder_.Finish(m_status, Status::OK, this);
}
else
{
GPR_ASSERT(status_ == FINISH);
// Once in the FINISH state, deallocate ourselves (CallData).
delete this;
}
return status_;
}
private:
// The means of communication with the gRPC runtime for an asynchronous
// server.
PyBulletAPI::AsyncService* service_;
// The producer-consumer queue where for asynchronous server notifications.
ServerCompletionQueue* cq_;
// Context for the rpc, allowing to tweak aspects of it such as the use
// of compression, authentication, as well as to send metadata back to the
// client.
ServerContext ctx_;
// What we get from the client.
PyBulletCommand m_command;
// What we send back to the client.
PyBulletStatus m_status;
// The means to get back to the client.
ServerAsyncResponseWriter<PyBulletStatus> responder_;
// Let's implement a tiny state machine with the following states.
CallStatus status_; // The current serving state.
bool m_finished;
MyCommandProcessor* m_comProc; //physics server command processor
};
// This can be run in multiple threads if needed.
void HandleRpcs(MyCommandProcessor* comProc)
{
// Spawn a new CallData instance to serve new clients.
new CallData(&service_, cq_.get(), comProc);
void* tag; // uniquely identifies a request.
bool ok;
bool finished = false;
CallData::CallStatus status = CallData::CallStatus::CREATE;
while (status != CallData::CallStatus::TERMINATE)
{
// Block waiting to read the next event from the completion queue. The
// event is uniquely identified by its tag, which in this case is the
// memory address of a CallData instance.
// The return value of Next should always be checked. This return value
// tells us whether there is any kind of event or cq_ is shutting down.
grpc::CompletionQueue::NextStatus nextStatus = cq_->AsyncNext(&tag, &ok, gpr_now(GPR_CLOCK_MONOTONIC));
if (nextStatus == grpc::CompletionQueue::NextStatus::GOT_EVENT)
{
//GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
status = static_cast<CallData*>(tag)->Proceed();
}
}
}
std::unique_ptr<ServerCompletionQueue> cq_;
PyBulletAPI::AsyncService service_;
std::unique_ptr<Server> server_;
};
int main(int argc, char** argv)
{
b3CommandLineArgs parseArgs(argc, argv);
b3Clock clock;
double timeOutInSeconds = 10;
DummyGUIHelper guiHelper;
MyCommandProcessor* sm = new MyCommandProcessor;
sm->setGuiHelper(&guiHelper);
int port = 6667;
parseArgs.GetCmdLineArgument("port", port);
std::string hostName = "localhost";
std::string hostNamePort = hostName;
if (port >= 0)
{
hostNamePort += ":" + std::to_string(port);
}
gVerboseNetworkMessagesServer = parseArgs.CheckCmdLineFlag("verbose");
#ifndef NO_SHARED_MEMORY
int key = 0;
if (parseArgs.GetCmdLineArgument("sharedMemoryKey", key))
{
sm->setSharedMemoryKey(key);
}
#endif //NO_SHARED_MEMORY
bool isPhysicsClientConnected = sm->connect();
bool exitRequested = false;
if (isPhysicsClientConnected)
{
ServerImpl server;
server.Run(sm, hostNamePort);
}
else
{
printf("Couldn't connect to physics server\n");
}
delete sm;
return 0;
}

View file

@ -0,0 +1,128 @@
project ("App_PhysicsServerSharedMemoryBridgeGRPC")
language "C++"
kind "ConsoleApp"
includedirs {"../../../src",".."}
initGRPC()
links {
"BulletFileLoader",
"Bullet3Common",
"LinearMath"
}
files {
"main.cpp",
"../PhysicsClient.cpp",
"../PhysicsClient.h",
"../PhysicsDirect.cpp",
"../PhysicsDirect.h",
"../PhysicsCommandProcessorInterface.h",
"../SharedMemoryCommandProcessor.cpp",
"../SharedMemoryCommandProcessor.h",
"../PhysicsClientC_API.cpp",
"../PhysicsClientC_API.h",
"../Win32SharedMemory.cpp",
"../Win32SharedMemory.h",
"../PosixSharedMemory.cpp",
"../PosixSharedMemory.h",
"../../Utils/b3ResourcePath.cpp",
"../../Utils/b3ResourcePath.h",
"../../Utils/b3Clock.cpp",
"../../Utils/b3Clock.h",
}
project "App_PhysicsServerGRPC"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
defines { "NO_SHARED_MEMORY" }
includedirs {"..","../../../src", "../../ThirdPartyLibs","../../ThirdPartyLibs/clsocket/src"}
links {
"clsocket","Bullet3Common","BulletInverseDynamicsUtils", "BulletInverseDynamics", "BulletSoftBody", "BulletDynamics","BulletCollision", "LinearMath", "BussIK"
}
initGRPC()
language "C++"
myfiles =
{
"../IKTrajectoryHelper.cpp",
"../IKTrajectoryHelper.h",
"../SharedMemoryCommands.h",
"../SharedMemoryPublic.h",
"../PhysicsServerCommandProcessor.cpp",
"../PhysicsServerCommandProcessor.h",
"../b3PluginManager.cpp",
"../PhysicsDirect.cpp",
"../PhysicsClientC_API.cpp",
"../PhysicsClient.cpp",
"../plugins/collisionFilterPlugin/collisionFilterPlugin.cpp",
"../plugins/pdControlPlugin/pdControlPlugin.cpp",
"../plugins/pdControlPlugin/pdControlPlugin.h",
"../b3RobotSimulatorClientAPI_NoDirect.cpp",
"../b3RobotSimulatorClientAPI_NoDirect.h",
"../plugins/tinyRendererPlugin/tinyRendererPlugin.cpp",
"../plugins/tinyRendererPlugin/TinyRendererVisualShapeConverter.cpp",
"../../TinyRenderer/geometry.cpp",
"../../TinyRenderer/model.cpp",
"../../TinyRenderer/tgaimage.cpp",
"../../TinyRenderer/our_gl.cpp",
"../../TinyRenderer/TinyRenderer.cpp",
"../../OpenGLWindow/SimpleCamera.cpp",
"../../OpenGLWindow/SimpleCamera.h",
"../../Importers/ImportURDFDemo/ConvertRigidBodies2MultiBody.h",
"../../Importers/ImportURDFDemo/MultiBodyCreationInterface.h",
"../../Importers/ImportURDFDemo/MyMultiBodyCreator.cpp",
"../../Importers/ImportURDFDemo/MyMultiBodyCreator.h",
"../../Importers/ImportMJCFDemo/BulletMJCFImporter.cpp",
"../../Importers/ImportMJCFDemo/BulletMJCFImporter.h",
"../../Importers/ImportURDFDemo/BulletUrdfImporter.cpp",
"../../Importers/ImportURDFDemo/BulletUrdfImporter.h",
"../../Importers/ImportURDFDemo/UrdfParser.cpp",
"../../Importers/ImportURDFDemo/urdfStringSplit.cpp",
"../../Importers/ImportURDFDemo/UrdfParser.cpp",
"../../Importers/ImportURDFDemo/UrdfParser.h",
"../../Importers/ImportURDFDemo/URDF2Bullet.cpp",
"../../Importers/ImportURDFDemo/URDF2Bullet.h",
"../../Utils/b3ResourcePath.cpp",
"../../Utils/b3Clock.cpp",
"../../Utils/ChromeTraceUtil.cpp",
"../../Utils/ChromeTraceUtil.h",
"../../Utils/RobotLoggingUtil.cpp",
"../../Utils/RobotLoggingUtil.h",
"../../../Extras/Serialize/BulletWorldImporter/*",
"../../../Extras/Serialize/BulletFileLoader/*",
"../../Importers/ImportURDFDemo/URDFImporterInterface.h",
"../../Importers/ImportURDFDemo/URDFJointTypes.h",
"../../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp",
"../../Importers/ImportObjDemo/LoadMeshFromObj.cpp",
"../../Importers/ImportSTLDemo/ImportSTLSetup.h",
"../../Importers/ImportSTLDemo/LoadMeshFromSTL.h",
"../../Importers/ImportColladaDemo/LoadMeshFromCollada.cpp",
"../../Importers/ImportColladaDemo/ColladaGraphicsInstance.h",
"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.cpp",
"../../ThirdPartyLibs/tinyxml2/tinyxml2.cpp",
"../../Importers/ImportMeshUtility/b3ImportMeshUtility.cpp",
"../../ThirdPartyLibs/stb_image/stb_image.cpp",
}
files {
myfiles,
"main.cpp",
}

View file

@ -0,0 +1,16 @@
del pybullet.pb.cpp
del pybullet.pb.h
del pybullet.grpc.pb.cpp
del pybullet.grpc.pb.h
..\..\..\ThirdPartyLibs\grpc\lib\win32\protoc --proto_path=. --cpp_out=. pybullet.proto
..\..\..\ThirdPartyLibs\grpc\lib\win32\protoc.exe --plugin=protoc-gen-grpc="..\..\..\ThirdPartyLibs\grpc\lib\win32\grpc_cpp_plugin.exe" --grpc_out=. pybullet.proto
rename pybullet.grpc.pb.cc pybullet.grpc.pb.cpp
rename pybullet.pb.cc pybullet.pb.cpp
del pybullet_pb2.py
del pybullet_pb2_grpc.py
..\..\..\ThirdPartyLibs\grpc\lib\win32\protoc --proto_path=. --python_out=. pybullet.proto
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. pybullet.proto

View file

@ -0,0 +1,15 @@
rm pybullet.pb.cpp
rm pybullet.pb.h
rm pybullet.grpc.pb.cpp
rm pybullet.grpc.pb.h
protoc --proto_path=. --cpp_out=. pybullet.proto
protoc --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` --grpc_out=. pybullet.proto
mv pybullet.grpc.pb.cc pybullet.grpc.pb.cpp
mv pybullet.pb.cc pybullet.pb.cpp
rm pybullet_pb2.py
rm pybullet_pb2_grpc.py
protoc --proto_path=. --python_out=. pybullet.proto
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. pybullet.proto

View file

@ -0,0 +1,467 @@
syntax = "proto3";
//for why oneof everywhere, see the sad decision here:
//https://github.com/protocolbuffers/protobuf/issues/1606
option java_multiple_files = true;
option java_package = "io.grpc.pybullet_grpc";
option java_outer_classname = "PyBulletProto";
option objc_class_prefix = "PBG";
package pybullet_grpc;
service PyBulletAPI {
// Sends a greeting
rpc SubmitCommand (PyBulletCommand) returns (PyBulletStatus) {}
}
message vec3
{
double x=1;
double y=2;
double z=3;
};
message quat4
{
double x=1;
double y=2;
double z=3;
double w=4;
};
message vec4
{
double x=1;
double y=2;
double z=3;
double w=4;
};
message transform
{
vec3 origin=1;
quat4 orientation=2;
};
message matrix4x4
{
//assume 16 elements, with translation in 12,13,14,
//'right' vector is elements 0,1,3 and 4
repeated double elems=1;
};
message CheckVersionCommand
{
int32 clientVersion=1;
};
message CheckVersionStatus
{
int32 serverVersion=1;
};
message TerminateServerCommand
{
string exitReason=1;
};
message StepSimulationCommand
{
};
message SyncBodiesCommand
{
};
message SyncBodiesStatus
{
repeated int32 bodyUniqueIds=1;
repeated int32 userConstraintUniqueIds=2;
};
message RequestBodyInfoCommand
{
int32 bodyUniqueId=1;
};
message RequestBodyInfoStatus
{
int32 bodyUniqueId=1;
string bodyName=2;
};
message LoadUrdfCommand {
string fileName=1;
vec3 initialPosition=2;
quat4 initialOrientation=3;
//for why oneof here, see the sad decision here:
//https://github.com/protocolbuffers/protobuf/issues/1606
oneof hasUseMultiBody { int32 useMultiBody=4; }
oneof hasUseFixedBase{ bool useFixedBase=5; }
int32 flags=6;
oneof hasGlobalScaling { double globalScaling=7;
}
};
message LoadUrdfStatus {
int32 bodyUniqueId=1;
string bodyName=2;
string fileName=3;
}
message LoadSdfCommand {
string fileName=1;
oneof hasUseMultiBody { int32 useMultiBody=2; }
oneof hasGlobalScaling { double globalScaling=3;
}
};
message SdfLoadedStatus
{
repeated int32 bodyUniqueIds=2;
}
message LoadMjcfCommand {
string fileName=1;
int32 flags=2;
};
message MjcfLoadedStatus
{
repeated int32 bodyUniqueIds=2;
}
message ChangeDynamicsCommand
{
int32 bodyUniqueId=1;
int32 linkIndex=2;
oneof hasMass { double mass=3;}
oneof hasLateralFriction { double lateralFriction=5;}
oneof hasSpinningFriction {double spinningFriction=6;}
oneof hasRollingFriction {double rollingFriction=7;}
oneof hasRestitution { double restitution=8;}
oneof haslinearDamping { double linearDamping=9;}
oneof hasangularDamping { double angularDamping=10;}
oneof hasContactStiffness { double contactStiffness=11;}
oneof hasContactDamping { double contactDamping=12;}
oneof hasLocalInertiaDiagonal { vec3 localInertiaDiagonal=13;}
oneof hasFrictionAnchor { int32 frictionAnchor=14;}
oneof hasccdSweptSphereRadius { double ccdSweptSphereRadius=15;}
oneof hasContactProcessingThreshold { double contactProcessingThreshold=16;}
oneof hasActivationState { int32 activationState=17;}
};
message GetDynamicsCommand
{
int32 bodyUniqueId=1;
int32 linkIndex=2;
};
message GetDynamicsStatus
{
double mass=3;
double lateralFriction=5;
double spinningFriction=6;
double rollingFriction=7;
double restitution=8;
double linearDamping=9;
double angularDamping=10;
double contactStiffness=11;
double contactDamping=12;
vec3 localInertiaDiagonal=13;
int32 frictionAnchor=14;
double ccdSweptSphereRadius=15;
double contactProcessingThreshold=16;
int32 activationState=17;
};
message InitPoseCommand
{
int32 bodyUniqueId=1;
int32 updateflags=2;
repeated int32 hasInitialStateQ=3;
repeated double initialStateQ=4;
repeated int32 hasInitialStateQdot=5;
repeated double initialStateQdot=6;
};
message RequestActualStateCommand
{
int32 bodyUniqueId=1;
bool computeForwardKinematics=2;
bool computeLinkVelocities=3;
};
message SendActualStateStatus
{
int32 bodyUniqueId=1;
int32 numLinks=2;
int32 numDegreeOfFreedomQ=3;
int32 numDegreeOfFreedomU=4;
repeated double rootLocalInertialFrame=5;
//actual state is only written by the server, read-only access by client is expected
repeated double actualStateQ=6;
repeated double actualStateQdot=7;
//measured 6DOF force/torque sensors: force[x,y,z] and torque[x,y,z]
repeated double jointReactionForces=8;
repeated double jointMotorForce=9;
repeated double linkState=10;
repeated double linkWorldVelocities=11;//linear velocity and angular velocity in world space (x/y/z each).
repeated double linkLocalInertialFrames=12;
};
message ConfigureOpenGLVisualizerCommand
{
int32 updateFlags=1;
double cameraDistance=2;
double cameraPitch=3;
double cameraYaw=4;
vec3 cameraTargetPosition=5;
int32 setFlag=6;
int32 setEnabled=7;
};
message PhysicsSimulationParameters
{
double deltaTime=1;
vec3 gravityAcceleration=2;
int32 numSimulationSubSteps=3;
int32 numSolverIterations=4;
int32 useRealTimeSimulation=5;
int32 useSplitImpulse=6;
double splitImpulsePenetrationThreshold=7;
double contactBreakingThreshold=8;
int32 internalSimFlags=9;
double defaultContactERP=10;
int32 collisionFilterMode=11;
int32 enableFileCaching=12;
double restitutionVelocityThreshold=13;
double defaultNonContactERP=14;
double frictionERP=15;
double defaultGlobalCFM=16;
double frictionCFM=17;
int32 enableConeFriction=18;
int32 deterministicOverlappingPairs=19;
double allowedCcdPenetration=20;
int32 jointFeedbackMode=21;
double solverResidualThreshold=22;
double contactSlop=23;
int32 enableSAT=24;
int32 constraintSolverType=25;
int32 minimumSolverIslandSize=26;
};
message PhysicsSimulationParametersCommand
{
int32 updateFlags=1;
PhysicsSimulationParameters params=2;
};
message JointMotorControlCommand
{
int32 bodyUniqueId=1;
int32 controlMode=2;
int32 updateFlags=3;
//PD parameters in case controlMode == CONTROL_MODE_POSITION_VELOCITY_PD
repeated double Kp=4;//indexed by degree of freedom, 6 for base, and then the dofs for each link
repeated double Kd=5;//indexed by degree of freedom, 6 for base, and then the dofs for each link
repeated double maxVelocity=6;
repeated int32 hasDesiredStateFlags=7;
//desired state is only written by the client, read-only access by server is expected
//desiredStateQ is indexed by position variables,
//starting with 3 base position variables, 4 base orientation variables (quaternion), then link position variables
repeated double desiredStateQ=8;
//desiredStateQdot is index by velocity degrees of freedom, 3 linear and 3 angular variables for the base and then link velocity variables
repeated double desiredStateQdot=9;
//desiredStateForceTorque is either the actual applied force/torque (in CONTROL_MODE_TORQUE) or
//or the maximum applied force/torque for the PD/motor/constraint to reach the desired velocity in CONTROL_MODE_VELOCITY and CONTROL_MODE_POSITION_VELOCITY_PD mode
//indexed by degree of freedom, 6 dof base, and then dofs for each link
repeated double desiredStateForceTorque=10;
};
message UserConstraintCommand
{
int32 parentBodyIndex=1;
int32 parentJointIndex=2;
int32 childBodyIndex=3;
int32 childJointIndex=4;
transform parentFrame=5;
transform childFrame=6;
vec3 jointAxis=7;
int32 jointType=8;
double maxAppliedForce=9;
int32 userConstraintUniqueId=10;
double gearRatio=11;
int32 gearAuxLink=12;
double relativePositionTarget=13;
double erp=14;
int32 updateFlags=15;
};
message UserConstraintStatus
{
double maxAppliedForce=9;
int32 userConstraintUniqueId=10;
};
message UserConstraintStateStatus
{
vec3 appliedConstraintForcesLinear=1;
vec3 appliedConstraintForcesAngular=2;
int32 numDofs=3;
};
message RequestKeyboardEventsCommand
{
};
message KeyboardEvent
{
int32 keyCode=1;//ascii
int32 keyState=2;// see b3VRButtonInfo
};
message KeyboardEventsStatus
{
repeated KeyboardEvent keyboardEvents=1;
};
message RequestCameraImageCommand
{
int32 updateFlags=1;
int32 cameraFlags=2;
matrix4x4 viewMatrix=3;
matrix4x4 projectionMatrix=4;
int32 startPixelIndex=5;
int32 pixelWidth=6;
int32 pixelHeight=7;
vec3 lightDirection=8;
vec3 lightColor=9;
double lightDistance=10;
double lightAmbientCoeff=11;
double lightDiffuseCoeff=12;
double lightSpecularCoeff=13;
int32 hasShadow=14;
matrix4x4 projectiveTextureViewMatrix=15;
matrix4x4 projectiveTextureProjectionMatrix=16;
};
message RequestCameraImageStatus
{
int32 imageWidth=1;
int32 imageHeight=2;
int32 startingPixelIndex=3;
int32 numPixelsCopied=4;
int32 numRemainingPixels=5;
};
message ResetSimulationCommand
{
};
// The request message containing the command
message PyBulletCommand {
int32 commandType=1;
repeated bytes binaryBlob=2;
repeated bytes unknownCommandBinaryBlob=3;
oneof commands {
LoadUrdfCommand loadUrdfCommand = 4;
TerminateServerCommand terminateServerCommand=5;
StepSimulationCommand stepSimulationCommand= 6;
LoadSdfCommand loadSdfCommand=7;
LoadMjcfCommand loadMjcfCommand=8;
ChangeDynamicsCommand changeDynamicsCommand=9;
GetDynamicsCommand getDynamicsCommand=10;
InitPoseCommand initPoseCommand=11;
RequestActualStateCommand requestActualStateCommand=12;
ConfigureOpenGLVisualizerCommand configureOpenGLVisualizerCommand =13;
SyncBodiesCommand syncBodiesCommand=14;
RequestBodyInfoCommand requestBodyInfoCommand=15;
PhysicsSimulationParametersCommand setPhysicsSimulationParametersCommand=16;
JointMotorControlCommand jointMotorControlCommand=17;
UserConstraintCommand userConstraintCommand=18;
CheckVersionCommand checkVersionCommand=19;
RequestKeyboardEventsCommand requestKeyboardEventsCommand=20;
RequestCameraImageCommand requestCameraImageCommand=21;
ResetSimulationCommand resetSimulationCommand=22;
}
}
// The response message containing the status
message PyBulletStatus {
int32 statusType=1;
repeated bytes binaryBlob=2;
repeated bytes unknownStatusBinaryBlob=3;
oneof status
{
LoadUrdfStatus urdfStatus = 4;
SdfLoadedStatus sdfStatus = 5;
MjcfLoadedStatus mjcfStatus = 6;
GetDynamicsStatus getDynamicsStatus = 7;
SendActualStateStatus actualStateStatus = 8;
SyncBodiesStatus syncBodiesStatus=9;
RequestBodyInfoStatus requestBodyInfoStatus = 10;
PhysicsSimulationParameters requestPhysicsSimulationParametersStatus=11;
CheckVersionStatus checkVersionStatus=12;
UserConstraintStatus userConstraintStatus=13;
UserConstraintStateStatus userConstraintStateStatus=14;
KeyboardEventsStatus keyboardEventsStatus=15;
RequestCameraImageStatus requestCameraImageStatus=16;
}
}

View file

@ -0,0 +1,95 @@
"""The Python implementation of the PyBullet GRPC client."""
from __future__ import print_function
import grpc
import pybullet_pb2
import pybullet_pb2_grpc
#todo: how to add this?
MJCF_COLORS_FROM_FILE = 512
def run():
print("grpc.insecure_channel")
channel = grpc.insecure_channel('localhost:6667')
print("pybullet_pb2_grpc.PyBulletAPIStub")
stub = pybullet_pb2_grpc.PyBulletAPIStub(channel)
response = 0
print("submit CheckVersionCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(checkVersionCommand=pybullet_pb2.CheckVersionCommand(
clientVersion=123)))
print("PyBullet client received: ", response)
print("submit_ResetSimulationCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(resetSimulationCommand=pybullet_pb2.ResetSimulationCommand()))
print("PyBullet client received: ", response)
print("submit LoadUrdfCommand ")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(loadUrdfCommand=pybullet_pb2.LoadUrdfCommand(
fileName="door.urdf",
initialPosition=pybullet_pb2.vec3(x=0, y=0, z=0),
useMultiBody=True,
useFixedBase=True,
globalScaling=2,
flags=1)))
print("PyBullet client received: ", response)
bodyUniqueId = response.urdfStatus.bodyUniqueId
print("submit LoadSdfCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(loadSdfCommand=pybullet_pb2.LoadSdfCommand(
fileName="two_cubes.sdf", useMultiBody=True, globalScaling=2)))
print("PyBullet client received: ", response)
print("submit LoadMjcfCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(loadMjcfCommand=pybullet_pb2.LoadMjcfCommand(
fileName="mjcf/humanoid.xml", flags=MJCF_COLORS_FROM_FILE)))
print("PyBullet client received: ", response)
print("submit ChangeDynamicsCommand ")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(changeDynamicsCommand=pybullet_pb2.ChangeDynamicsCommand(
bodyUniqueId=bodyUniqueId, linkIndex=-1, mass=10)))
print("PyBullet client received: ", response)
print("submit GetDynamicsCommand ")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(getDynamicsCommand=pybullet_pb2.GetDynamicsCommand(
bodyUniqueId=bodyUniqueId, linkIndex=-1)))
print("PyBullet client received: ", response)
print("submit InitPoseCommand")
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(initPoseCommand=pybullet_pb2.InitPoseCommand(
bodyUniqueId=bodyUniqueId, initialStateQ=[1, 2, 3], hasInitialStateQ=[1, 1, 1])))
print("PyBullet client received: ", response)
print("submit RequestActualStateCommand")
response = stub.SubmitCommand(
pybullet_pb2.
PyBulletCommand(requestActualStateCommand=pybullet_pb2.RequestActualStateCommand(
bodyUniqueId=bodyUniqueId, computeForwardKinematics=True, computeLinkVelocities=True)))
print("PyBullet client received: ", response)
i = 0
while (True):
i = i + 1
print("submit StepSimulationCommand: ", i)
response = stub.SubmitCommand(
pybullet_pb2.PyBulletCommand(stepSimulationCommand=pybullet_pb2.StepSimulationCommand()))
print("PyBullet client received: ", response.statusType)
#print("TerminateServerCommand")
#response = stub.SubmitCommand(pybullet_pb2.PyBulletCommand(terminateServerCommand=pybullet_pb2.TerminateServerCommand()))
#print("PyBullet client received: " , response.statusType)
if __name__ == '__main__':
run()