| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812 |
- #include "PhysicsServerCommandProcessor.h"
- #include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
- #include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
- #include "../Importers/ImportURDFDemo/URDF2Bullet.h"
- #include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h"
- #include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
- #include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h"
- #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
- #include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h"
- #include "../CommonInterfaces/CommonRenderInterface.h"
- #include "btBulletDynamicsCommon.h"
- #include "LinearMath/btTransform.h"
- #include "../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h"
- #include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h"
- #include "LinearMath/btSerializer.h"
- #include "Bullet3Common/b3Logging.h"
- #include "../CommonInterfaces/CommonGUIHelperInterface.h"
- #include "SharedMemoryCommands.h"
- struct UrdfLinkNameMapUtil
- {
- btMultiBody* m_mb;
- btDefaultSerializer* m_memSerializer;
- UrdfLinkNameMapUtil():m_mb(0),m_memSerializer(0)
- {
- }
- };
- struct SharedMemoryDebugDrawer : public btIDebugDraw
- {
- int m_debugMode;
- btAlignedObjectArray<SharedMemLines> m_lines2;
- SharedMemoryDebugDrawer ()
- :m_debugMode(0)
- {
- }
- virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
- {
- }
- virtual void reportErrorWarning(const char* warningString)
- {
- }
- virtual void draw3dText(const btVector3& location,const char* textString)
- {
- }
-
- virtual void setDebugMode(int debugMode)
- {
- m_debugMode = debugMode;
- }
-
- virtual int getDebugMode() const
- {
- return m_debugMode;
- }
- virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
- {
- SharedMemLines line;
- line.m_from = from;
- line.m_to = to;
- line.m_color = color;
- m_lines2.push_back(line);
- }
- };
- struct InteralBodyData
- {
- btMultiBody* m_multiBody;
- btRigidBody* m_rigidBody;
- int m_testData;
- btTransform m_rootLocalInertialFrame;
- InteralBodyData()
- :m_multiBody(0),
- m_rigidBody(0),
- m_testData(0)
- {
- m_rootLocalInertialFrame.setIdentity();
- }
- };
- ///todo: templatize this
- struct InternalBodyHandle : public InteralBodyData
- {
- BT_DECLARE_ALIGNED_ALLOCATOR();
- int m_nextFreeHandle;
- void SetNextFree(int next)
- {
- m_nextFreeHandle = next;
- }
- int GetNextFree() const
- {
- return m_nextFreeHandle;
- }
- };
- class btCommandChunk
- {
- public:
- int m_chunkCode;
- int m_length;
- void *m_oldPtr;
- int m_dna_nr;
- int m_number;
- };
- class bCommandChunkPtr4
- {
- public:
- bCommandChunkPtr4(){}
- int code;
- int len;
- union
- {
- int m_uniqueInt;
- };
- int dna_nr;
- int nr;
- };
- // ----------------------------------------------------- //
- class bCommandChunkPtr8
- {
- public:
- bCommandChunkPtr8(){}
- int code, len;
- union
- {
- int m_uniqueInts[2];
- };
- int dna_nr, nr;
- };
- struct CommandLogger
- {
- FILE* m_file;
-
- void writeHeader(unsigned char* buffer) const
- {
- #ifdef BT_USE_DOUBLE_PRECISION
- memcpy(buffer, "BT3CMDd", 7);
- #else
- memcpy(buffer, "BT3CMDf", 7);
- #endif //BT_USE_DOUBLE_PRECISION
- int littleEndian= 1;
- littleEndian= ((char*)&littleEndian)[0];
- if (sizeof(void*)==8)
- {
- buffer[7] = '-';
- } else
- {
- buffer[7] = '_';
- }
- if (littleEndian)
- {
- buffer[8]='v';
- } else
- {
- buffer[8]='V';
- }
- buffer[9] = 0;
- buffer[10] = 0;
- buffer[11] = 0;
-
- int ver = btGetVersion();
- if (ver>=0 && ver<999)
- {
- sprintf((char*)&buffer[9],"%d",ver);
- }
-
- }
-
- void logCommand(const SharedMemoryCommand& command)
- {
- btCommandChunk chunk;
- chunk.m_chunkCode = command.m_type;
- chunk.m_oldPtr = 0;
- chunk.m_dna_nr = 0;
- chunk.m_length = sizeof(SharedMemoryCommand);
- chunk.m_number = 1;
- fwrite((const char*)&chunk,sizeof(btCommandChunk), 1,m_file);
- fwrite((const char*)&command,sizeof(SharedMemoryCommand),1,m_file);
- }
- CommandLogger(const char* fileName)
- {
- m_file = fopen(fileName,"wb");
- unsigned char buf[15];
- buf[12] = 12;
- buf[13] = 13;
- buf[14] = 14;
- writeHeader(buf);
- fwrite(buf,12,1,m_file);
- }
- virtual ~CommandLogger()
- {
- fclose(m_file);
- }
- };
- struct CommandLogPlayback
- {
- unsigned char m_header[12];
- FILE* m_file;
- bool m_bitsVary;
- bool m_fileIs64bit;
- CommandLogPlayback(const char* fileName)
- {
- m_file = fopen(fileName,"rb");
- if (m_file)
- {
- fread(m_header,12,1,m_file);
- }
- unsigned char c = m_header[7];
- m_fileIs64bit = (c=='-');
-
- const bool VOID_IS_8 = ((sizeof(void*)==8));
- m_bitsVary = (VOID_IS_8 != m_fileIs64bit);
-
- }
- virtual ~CommandLogPlayback()
- {
- if (m_file)
- {
- fclose(m_file);
- m_file=0;
- }
- }
- bool processNextCommand(SharedMemoryCommand* cmd)
- {
- if (m_file)
- {
- size_t s = 0;
-
- if (m_fileIs64bit)
- {
- bCommandChunkPtr8 chunk8;
- s = fread((void*)&chunk8,sizeof(bCommandChunkPtr8),1,m_file);
- } else
- {
- bCommandChunkPtr4 chunk4;
- s = fread((void*)&chunk4,sizeof(bCommandChunkPtr4),1,m_file);
- }
-
- if (s==1)
- {
- s = fread(cmd,sizeof(SharedMemoryCommand),1,m_file);
- return (s==1);
- }
- }
- return false;
- }
- };
- struct PhysicsServerCommandProcessorInternalData
- {
- ///handle management
- btAlignedObjectArray<InternalBodyHandle> m_bodyHandles;
- int m_numUsedHandles; // number of active handles
-
- int m_firstFreeHandle; // free handles list
- InternalBodyHandle* getHandle(int handle)
- {
- btAssert(handle>=0);
- btAssert(handle<m_bodyHandles.size());
- if ((handle<0) || (handle>=m_bodyHandles.size()))
- {
- return 0;
- }
- return &m_bodyHandles[handle];
- }
- const InternalBodyHandle* getHandle(int handle) const
- {
- return &m_bodyHandles[handle];
- }
- void increaseHandleCapacity(int extraCapacity)
- {
- int curCapacity = m_bodyHandles.size();
- btAssert(curCapacity == m_numUsedHandles);
- int newCapacity = curCapacity + extraCapacity;
- m_bodyHandles.resize(newCapacity);
- {
- for (int i = curCapacity; i < newCapacity; i++)
- m_bodyHandles[i].SetNextFree(i + 1);
- m_bodyHandles[newCapacity - 1].SetNextFree(-1);
- }
- m_firstFreeHandle = curCapacity;
- }
- void initHandles()
- {
- m_numUsedHandles = 0;
- m_firstFreeHandle = -1;
-
- increaseHandleCapacity(1);
- }
- void exitHandles()
- {
- m_bodyHandles.resize(0);
- m_firstFreeHandle = -1;
- m_numUsedHandles = 0;
- }
- int allocHandle()
- {
- btAssert(m_firstFreeHandle>=0);
- int handle = m_firstFreeHandle;
- m_firstFreeHandle = getHandle(handle)->GetNextFree();
- m_numUsedHandles++;
- if (m_firstFreeHandle<0)
- {
- int curCapacity = m_bodyHandles.size();
- int additionalCapacity= m_bodyHandles.size();
- increaseHandleCapacity(additionalCapacity);
-
- getHandle(handle)->SetNextFree(m_firstFreeHandle);
- }
-
- return handle;
- }
- void freeHandle(int handle)
- {
- btAssert(handle >= 0);
- getHandle(handle)->SetNextFree(m_firstFreeHandle);
- m_firstFreeHandle = handle;
- m_numUsedHandles--;
- }
- ///end handle management
-
-
- CommandLogger* m_commandLogger;
- CommandLogPlayback* m_logPlayback;
-
- btScalar m_physicsDeltaTime;
- btAlignedObjectArray<btMultiBodyJointFeedback*> m_multiBodyJointFeedbacks;
-
- btAlignedObjectArray<btBulletWorldImporter*> m_worldImporters;
- btAlignedObjectArray<UrdfLinkNameMapUtil*> m_urdfLinkNameMapper;
- btHashMap<btHashInt, btMultiBodyJointMotor*> m_multiBodyJointMotorMap;
- btAlignedObjectArray<std::string*> m_strings;
- btAlignedObjectArray<btCollisionShape*> m_collisionShapes;
- btBroadphaseInterface* m_broadphase;
- btCollisionDispatcher* m_dispatcher;
- btMultiBodyConstraintSolver* m_solver;
- btDefaultCollisionConfiguration* m_collisionConfiguration;
- btMultiBodyDynamicsWorld* m_dynamicsWorld;
- SharedMemoryDebugDrawer* m_remoteDebugDrawer;
-
-
-
- struct GUIHelperInterface* m_guiHelper;
- int m_sharedMemoryKey;
- bool m_verboseOutput;
-
-
- //data for picking objects
- class btRigidBody* m_pickedBody;
- class btTypedConstraint* m_pickedConstraint;
- class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point;
- btVector3 m_oldPickingPos;
- btVector3 m_hitPos;
- btScalar m_oldPickingDist;
- bool m_prevCanSleep;
- PhysicsServerCommandProcessorInternalData()
- :
- m_commandLogger(0),
- m_logPlayback(0),
- m_physicsDeltaTime(1./240.),
- m_dynamicsWorld(0),
- m_remoteDebugDrawer(0),
- m_guiHelper(0),
- m_sharedMemoryKey(SHARED_MEMORY_KEY),
- m_verboseOutput(false),
- m_pickedBody(0),
- m_pickedConstraint(0),
- m_pickingMultiBodyPoint2Point(0)
- {
-
- initHandles();
- #if 0
- btAlignedObjectArray<int> bla;
- for (int i=0;i<1024;i++)
- {
- int handle = allocHandle();
- bla.push_back(handle);
- InternalBodyHandle* body = getHandle(handle);
- InteralBodyData* body2 = body;
- }
- for (int i=0;i<bla.size();i++)
- {
- freeHandle(bla[i]);
- }
- bla.resize(0);
- for (int i=0;i<1024;i++)
- {
- int handle = allocHandle();
- bla.push_back(handle);
- InternalBodyHandle* body = getHandle(handle);
- InteralBodyData* body2 = body;
- }
- for (int i=0;i<bla.size();i++)
- {
- freeHandle(bla[i]);
- }
- bla.resize(0);
- for (int i=0;i<1024;i++)
- {
- int handle = allocHandle();
- bla.push_back(handle);
- InternalBodyHandle* body = getHandle(handle);
- InteralBodyData* body2 = body;
- }
- for (int i=0;i<bla.size();i++)
- {
- freeHandle(bla[i]);
- }
- #endif
- }
- };
- void PhysicsServerCommandProcessor::setGuiHelper(struct GUIHelperInterface* guiHelper)
- {
-
- if (guiHelper)
- {
-
- guiHelper->createPhysicsDebugDrawer(m_data->m_dynamicsWorld);
- } else
- {
- if (m_data->m_guiHelper && m_data->m_dynamicsWorld && m_data->m_dynamicsWorld->getDebugDrawer())
- {
-
- m_data->m_dynamicsWorld->setDebugDrawer(0);
- }
- }
- m_data->m_guiHelper = guiHelper;
- }
- PhysicsServerCommandProcessor::PhysicsServerCommandProcessor()
- {
- m_data = new PhysicsServerCommandProcessorInternalData();
- createEmptyDynamicsWorld();
- }
- PhysicsServerCommandProcessor::~PhysicsServerCommandProcessor()
- {
- deleteDynamicsWorld();
- if (m_data->m_commandLogger)
- {
- delete m_data->m_commandLogger;
- m_data->m_commandLogger = 0;
- }
- delete m_data;
- }
- void PhysicsServerCommandProcessor::createEmptyDynamicsWorld()
- {
- ///collision configuration contains default setup for memory, collision setup
- m_data->m_collisionConfiguration = new btDefaultCollisionConfiguration();
- //m_collisionConfiguration->setConvexConvexMultipointIterations();
-
- ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
- m_data->m_dispatcher = new btCollisionDispatcher(m_data->m_collisionConfiguration);
-
- m_data->m_broadphase = new btDbvtBroadphase();
-
- m_data->m_solver = new btMultiBodyConstraintSolver;
-
- m_data->m_dynamicsWorld = new btMultiBodyDynamicsWorld(m_data->m_dispatcher, m_data->m_broadphase, m_data->m_solver, m_data->m_collisionConfiguration);
- m_data->m_remoteDebugDrawer = new SharedMemoryDebugDrawer();
-
-
- m_data->m_dynamicsWorld->setGravity(btVector3(0, 0, 0));
- }
- void PhysicsServerCommandProcessor::deleteDynamicsWorld()
- {
-
- for (int i=0;i<m_data->m_multiBodyJointFeedbacks.size();i++)
- {
- delete m_data->m_multiBodyJointFeedbacks[i];
- }
- m_data->m_multiBodyJointFeedbacks.clear();
-
-
- for (int i=0;i<m_data->m_worldImporters.size();i++)
- {
- delete m_data->m_worldImporters[i];
- }
- m_data->m_worldImporters.clear();
-
- for (int i=0;i<m_data->m_urdfLinkNameMapper.size();i++)
- {
- delete m_data->m_urdfLinkNameMapper[i];
- }
- m_data->m_urdfLinkNameMapper.clear();
-
- m_data->m_multiBodyJointMotorMap.clear();
-
- for (int i=0;i<m_data->m_strings.size();i++)
- {
- delete m_data->m_strings[i];
- }
- m_data->m_strings.clear();
-
- if (m_data->m_dynamicsWorld)
- {
-
- int i;
- for (i = m_data->m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--)
- {
- m_data->m_dynamicsWorld->removeConstraint(m_data->m_dynamicsWorld->getConstraint(i));
- }
- for (i = m_data->m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
- {
- btCollisionObject* obj = m_data->m_dynamicsWorld->getCollisionObjectArray()[i];
- btRigidBody* body = btRigidBody::upcast(obj);
- if (body && body->getMotionState())
- {
- delete body->getMotionState();
- }
- m_data->m_dynamicsWorld->removeCollisionObject(obj);
- delete obj;
- }
- }
- //delete collision shapes
- for (int j = 0; j<m_data->m_collisionShapes.size(); j++)
- {
- btCollisionShape* shape = m_data->m_collisionShapes[j];
- delete shape;
- }
- m_data->m_collisionShapes.clear();
- delete m_data->m_dynamicsWorld;
- m_data->m_dynamicsWorld=0;
- delete m_data->m_remoteDebugDrawer;
- m_data->m_remoteDebugDrawer =0;
- delete m_data->m_solver;
- m_data->m_solver=0;
- delete m_data->m_broadphase;
- m_data->m_broadphase=0;
- delete m_data->m_dispatcher;
- m_data->m_dispatcher=0;
- delete m_data->m_collisionConfiguration;
- m_data->m_collisionConfiguration=0;
- }
- bool PhysicsServerCommandProcessor::supportsJointMotor(btMultiBody* mb, int mbLinkIndex)
- {
- bool canHaveMotor = (mb->getLink(mbLinkIndex).m_jointType==btMultibodyLink::eRevolute
- ||mb->getLink(mbLinkIndex).m_jointType==btMultibodyLink::ePrismatic);
- return canHaveMotor;
- }
- //for testing, create joint motors for revolute and prismatic joints
- void PhysicsServerCommandProcessor::createJointMotors(btMultiBody* mb)
- {
- int numLinks = mb->getNumLinks();
- for (int i=0;i<numLinks;i++)
- {
- int mbLinkIndex = i;
-
- if (supportsJointMotor(mb,mbLinkIndex))
- {
- float maxMotorImpulse = 0.f;
- int dof = 0;
- btScalar desiredVelocity = 0.f;
- btMultiBodyJointMotor* motor = new btMultiBodyJointMotor(mb,mbLinkIndex,dof,desiredVelocity,maxMotorImpulse);
- //motor->setMaxAppliedImpulse(0);
- m_data->m_multiBodyJointMotorMap.insert(mbLinkIndex,motor);
- m_data->m_dynamicsWorld->addMultiBodyConstraint(motor);
- }
- }
- }
- bool PhysicsServerCommandProcessor::loadUrdf(const char* fileName, const btVector3& pos, const btQuaternion& orn,
- bool useMultiBody, bool useFixedBase, int* bodyUniqueIdPtr, char* bufferServerToClient, int bufferSizeInBytes)
- {
- btAssert(m_data->m_dynamicsWorld);
- if (!m_data->m_dynamicsWorld)
- {
- b3Error("loadUrdf: No valid m_dynamicsWorld");
- return false;
- }
- BulletURDFImporter u2b(m_data->m_guiHelper);
-
- bool loadOk = u2b.loadURDF(fileName, useFixedBase);
- if (loadOk)
- {
- //get a body index
- int bodyUniqueId = m_data->allocHandle();
- if (bodyUniqueIdPtr)
- *bodyUniqueIdPtr= bodyUniqueId;
- InternalBodyHandle* bodyHandle = m_data->getHandle(bodyUniqueId);
- {
- btScalar mass = 0;
- bodyHandle->m_rootLocalInertialFrame.setIdentity();
- btVector3 localInertiaDiagonal(0,0,0);
- int urdfLinkIndex = u2b.getRootLinkIndex();
- u2b.getMassAndInertia(urdfLinkIndex, mass,localInertiaDiagonal,bodyHandle->m_rootLocalInertialFrame);
- }
- if (m_data->m_verboseOutput)
- {
- b3Printf("loaded %s OK!", fileName);
- }
-
- btTransform tr;
- tr.setIdentity();
- tr.setOrigin(pos);
- tr.setRotation(orn);
- //int rootLinkIndex = u2b.getRootLinkIndex();
- // printf("urdf root link index = %d\n",rootLinkIndex);
- MyMultiBodyCreator creation(m_data->m_guiHelper);
-
- ConvertURDF2Bullet(u2b,creation, tr,m_data->m_dynamicsWorld,useMultiBody,u2b.getPathPrefix());
- btMultiBody* mb = creation.getBulletMultiBody();
- if (useMultiBody)
- {
- if (mb)
- {
- bodyHandle->m_multiBody = mb;
- createJointMotors(mb);
- //serialize the btMultiBody and send the data to the client. This is one way to get the link/joint names across the (shared memory) wire
- UrdfLinkNameMapUtil* util = new UrdfLinkNameMapUtil;
- m_data->m_urdfLinkNameMapper.push_back(util);
- util->m_mb = mb;
- util->m_memSerializer = new btDefaultSerializer(bufferSizeInBytes ,(unsigned char*)bufferServerToClient);
- //disable serialization of the collision objects (they are too big, and the client likely doesn't need them);
- util->m_memSerializer->m_skipPointers.insert(mb->getBaseCollider(),0);
- for (int i=0;i<mb->getNumLinks();i++)
- {
- //disable serialization of the collision objects
- util->m_memSerializer->m_skipPointers.insert(mb->getLink(i).m_collider,0);
- int urdfLinkIndex = creation.m_mb2urdfLink[i];
- std::string* linkName = new std::string(u2b.getLinkName(urdfLinkIndex).c_str());
- m_data->m_strings.push_back(linkName);
- util->m_memSerializer->registerNameForPointer(linkName->c_str(),linkName->c_str());
- mb->getLink(i).m_linkName = linkName->c_str();
- std::string* jointName = new std::string(u2b.getJointName(urdfLinkIndex).c_str());
- m_data->m_strings.push_back(jointName);
- util->m_memSerializer->registerNameForPointer(jointName->c_str(),jointName->c_str());
- mb->getLink(i).m_jointName = jointName->c_str();
- }
-
- std::string* baseName = new std::string(u2b.getLinkName(u2b.getRootLinkIndex()));
- m_data->m_strings.push_back(baseName);
-
- util->m_memSerializer->registerNameForPointer(baseName->c_str(),baseName->c_str());
- mb->setBaseName(baseName->c_str());
-
-
- util->m_memSerializer->insertHeader();
-
- int len = mb->calculateSerializeBufferSize();
- btChunk* chunk = util->m_memSerializer->allocate(len,1);
- const char* structType = mb->serialize(chunk->m_oldPtr, util->m_memSerializer);
- util->m_memSerializer->finalizeChunk(chunk,structType,BT_MULTIBODY_CODE,mb);
- return true;
- } else
- {
- b3Warning("No multibody loaded from URDF. Could add btRigidBody+btTypedConstraint solution later.");
- return false;
- }
- } else
- {
- btAssert(0);
-
- return true;
- }
-
- }
-
- return false;
- }
- bool PhysicsServerCommandProcessor::processCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes )
- {
- bool hasStatus = false;
- {
- #if 0
- if (m_data->m_logPlayback)
- {
- if (m_data->m_testBlock1->m_numServerCommands>m_data->m_testBlock1->m_numProcessedServerCommands)
- {
- m_data->m_testBlock1->m_numProcessedServerCommands++;
- }
- //push a command from log file
- bool hasCommand = m_data->m_logPlayback->processNextCommand(&m_data->m_testBlock1->m_clientCommands[0]);
- if (hasCommand)
- {
- m_data->m_testBlock1->m_numClientCommands++;
- }
- }
- #endif
- ///we ignore overflow of integer for now
-
- {
-
- //until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands
-
-
- //const SharedMemoryCommand& clientCmd =m_data->m_testBlock1->m_clientCommands[0];
- #if 0
- if (m_data->m_commandLogger)
- {
- m_data->m_commandLogger->logCommand(m_data->m_testBlock1);
- }
- #endif
- //m_data->m_testBlock1->m_numProcessedClientCommands++;
-
- //no timestamp yet
- int timeStamp = 0;
- //consume the command
- switch (clientCmd.m_type)
- {
- #if 0
- case CMD_SEND_BULLET_DATA_STREAM:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Processed CMD_SEND_BULLET_DATA_STREAM length %d",clientCmd.m_dataStreamArguments.m_streamChunkLength);
- }
-
- btBulletWorldImporter* worldImporter = new btBulletWorldImporter(m_data->m_dynamicsWorld);
- m_data->m_worldImporters.push_back(worldImporter);
- bool completedOk = worldImporter->loadFileFromMemory(m_data->m_testBlock1->m_bulletStreamDataClientToServer,clientCmd.m_dataStreamArguments.m_streamChunkLength);
-
- if (completedOk)
- {
- SharedMemoryStatus& status = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp);
- m_data->m_guiHelper->autogenerateGraphicsObjects(this->m_data->m_dynamicsWorld);
- m_data->submitServerStatus(status);
- } else
- {
- SharedMemoryStatus& status = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_FAILED,clientCmd.m_sequenceNumber,timeStamp);
- m_data->submitServerStatus(status);
- }
-
- break;
- }
- #endif
- case CMD_REQUEST_DEBUG_LINES:
- {
- int curFlags =m_data->m_remoteDebugDrawer->getDebugMode();
-
- int debugMode = clientCmd.m_requestDebugLinesArguments.m_debugMode;//clientCmd.btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb;
- int startingLineIndex = clientCmd.m_requestDebugLinesArguments.m_startingLineIndex;
- if (startingLineIndex<0)
- {
- b3Warning("startingLineIndex should be non-negative");
- startingLineIndex = 0;
- }
-
- if (clientCmd.m_requestDebugLinesArguments.m_startingLineIndex==0)
- {
- m_data->m_remoteDebugDrawer->m_lines2.resize(0);
- //|btIDebugDraw::DBG_DrawAabb|
- // btIDebugDraw::DBG_DrawConstraints |btIDebugDraw::DBG_DrawConstraintLimits ;
- m_data->m_remoteDebugDrawer->setDebugMode(debugMode);
- btIDebugDraw* oldDebugDrawer = m_data->m_dynamicsWorld->getDebugDrawer();
- m_data->m_dynamicsWorld->setDebugDrawer(m_data->m_remoteDebugDrawer);
- m_data->m_dynamicsWorld->debugDrawWorld();
- m_data->m_dynamicsWorld->setDebugDrawer(oldDebugDrawer);
- m_data->m_remoteDebugDrawer->setDebugMode(curFlags);
- }
- //9 floats per line: 3 floats for 'from', 3 floats for 'to' and 3 floats for 'color'
- int maxNumLines = bufferSizeInBytes/(sizeof(float)*9)-1;
- if (startingLineIndex >m_data->m_remoteDebugDrawer->m_lines2.size())
- {
- b3Warning("m_startingLineIndex exceeds total number of debug lines");
- startingLineIndex =m_data->m_remoteDebugDrawer->m_lines2.size();
- }
-
- int numLines = btMin(maxNumLines,m_data->m_remoteDebugDrawer->m_lines2.size()-startingLineIndex);
-
- if (numLines)
- {
- float* linesFrom = (float*)bufferServerToClient;
- float* linesTo = (float*)(bufferServerToClient+numLines*3*sizeof(float));
- float* linesColor = (float*)(bufferServerToClient+2*numLines*3*sizeof(float));
- for (int i=0;i<numLines;i++)
- {
- linesFrom[i*3] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_from.x();
- linesTo[i*3] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_to.x();
- linesColor[i*3] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_color.x();
- linesFrom[i*3+1] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_from.y();
- linesTo[i*3+1] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_to.y();
- linesColor[i*3+1] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_color.y();
- linesFrom[i*3+2] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_from.z();
- linesTo[i*3+2] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_to.z();
- linesColor[i*3+2] = m_data->m_remoteDebugDrawer->m_lines2[i+startingLineIndex].m_color.z();
- }
- }
-
- serverStatusOut.m_type = CMD_DEBUG_LINES_COMPLETED;
- serverStatusOut.m_sendDebugLinesArgs.m_numDebugLines = numLines;
- serverStatusOut.m_sendDebugLinesArgs.m_startingLineIndex = startingLineIndex;
- serverStatusOut.m_sendDebugLinesArgs.m_numRemainingDebugLines = m_data->m_remoteDebugDrawer->m_lines2.size()-(startingLineIndex+numLines);
- hasStatus = true;
-
- break;
- }
- case CMD_LOAD_URDF:
- {
-
- const UrdfArgs& urdfArgs = clientCmd.m_urdfArguments;
- if (m_data->m_verboseOutput)
- {
- b3Printf("Processed CMD_LOAD_URDF:%s", urdfArgs.m_urdfFileName);
- }
- btAssert((clientCmd.m_updateFlags&URDF_ARGS_FILE_NAME) !=0);
- btAssert(urdfArgs.m_urdfFileName);
- btVector3 initialPos(0,0,0);
- btQuaternion initialOrn(0,0,0,1);
- if (clientCmd.m_updateFlags & URDF_ARGS_INITIAL_POSITION)
- {
- initialPos[0] = urdfArgs.m_initialPosition[0];
- initialPos[1] = urdfArgs.m_initialPosition[1];
- initialPos[2] = urdfArgs.m_initialPosition[2];
- }
- if (clientCmd.m_updateFlags & URDF_ARGS_INITIAL_ORIENTATION)
- {
- initialOrn[0] = urdfArgs.m_initialOrientation[0];
- initialOrn[1] = urdfArgs.m_initialOrientation[1];
- initialOrn[2] = urdfArgs.m_initialOrientation[2];
- initialOrn[3] = urdfArgs.m_initialOrientation[3];
- }
- bool useMultiBody=(clientCmd.m_updateFlags & URDF_ARGS_USE_MULTIBODY) ? urdfArgs.m_useMultiBody : true;
- bool useFixedBase = (clientCmd.m_updateFlags & URDF_ARGS_USE_FIXED_BASE) ? urdfArgs.m_useFixedBase: false;
- int bodyUniqueId;
- //load the actual URDF and send a report: completed or failed
- bool completedOk = loadUrdf(urdfArgs.m_urdfFileName,
- initialPos,initialOrn,
- useMultiBody, useFixedBase,&bodyUniqueId, bufferServerToClient, bufferSizeInBytes);
-
-
- if (completedOk)
- {
-
- m_data->m_guiHelper->autogenerateGraphicsObjects(this->m_data->m_dynamicsWorld);
-
- serverStatusOut.m_type = CMD_URDF_LOADING_COMPLETED;
- if (m_data->m_urdfLinkNameMapper.size())
- {
- serverStatusOut.m_dataStreamArguments.m_streamChunkLength = m_data->m_urdfLinkNameMapper.at(m_data->m_urdfLinkNameMapper.size()-1)->m_memSerializer->getCurrentBufferSize();
- }
- serverStatusOut.m_dataStreamArguments.m_bodyUniqueId = bodyUniqueId;
- hasStatus = true;
-
- } else
- {
- serverStatusOut.m_type = CMD_URDF_LOADING_FAILED;
- hasStatus = true;
- }
-
-
-
- break;
- }
- case CMD_CREATE_SENSOR:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Processed CMD_CREATE_SENSOR");
- }
- int bodyUniqueId = clientCmd.m_createSensorArguments.m_bodyUniqueId;
- InteralBodyData* body = m_data->getHandle(bodyUniqueId);
- if (body && body->m_multiBody)
- {
- btMultiBody* mb = body->m_multiBody;
- btAssert(mb);
- for (int i=0;i<clientCmd.m_createSensorArguments.m_numJointSensorChanges;i++)
- {
- int jointIndex = clientCmd.m_createSensorArguments.m_jointIndex[i];
- if (clientCmd.m_createSensorArguments.m_enableJointForceSensor[i])
- {
- if (mb->getLink(jointIndex).m_jointFeedback)
- {
- b3Warning("CMD_CREATE_SENSOR: sensor for joint [%d] already enabled", jointIndex);
- } else
- {
- btMultiBodyJointFeedback* fb = new btMultiBodyJointFeedback();
- fb->m_reactionForces.setZero();
- mb->getLink(jointIndex).m_jointFeedback = fb;
- m_data->m_multiBodyJointFeedbacks.push_back(fb);
- };
-
- } else
- {
- if (mb->getLink(jointIndex).m_jointFeedback)
- {
- m_data->m_multiBodyJointFeedbacks.remove(mb->getLink(jointIndex).m_jointFeedback);
- delete mb->getLink(jointIndex).m_jointFeedback;
- mb->getLink(jointIndex).m_jointFeedback=0;
- } else
- {
- b3Warning("CMD_CREATE_SENSOR: cannot perform sensor removal request, no sensor on joint [%d]", jointIndex);
- };
- }
- }
-
- } else
- {
- b3Warning("No btMultiBody in the world. btRigidBody/btTypedConstraint sensor not hooked up yet");
- }
- #if 0
- //todo(erwincoumans) here is some sample code to hook up a force/torque sensor for btTypedConstraint/btRigidBody
- /*
- for (int i=0;i<m_data->m_dynamicsWorld->getNumConstraints();i++)
- {
- btTypedConstraint* c = m_data->m_dynamicsWorld->getConstraint(i);
- btJointFeedback* fb = new btJointFeedback();
- m_data->m_jointFeedbacks.push_back(fb);
- c->setJointFeedback(fb);
-
-
- }
- */
- #endif
-
- serverStatusOut.m_type = CMD_CLIENT_COMMAND_COMPLETED;
- hasStatus = true;
-
- break;
- }
- case CMD_SEND_DESIRED_STATE:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Processed CMD_SEND_DESIRED_STATE");
- }
-
- int bodyUniqueId = clientCmd.m_sendDesiredStateCommandArgument.m_bodyUniqueId;
- InteralBodyData* body = m_data->getHandle(bodyUniqueId);
- if (body && body->m_multiBody)
- {
- btMultiBody* mb = body->m_multiBody;
- btAssert(mb);
-
- switch (clientCmd.m_sendDesiredStateCommandArgument.m_controlMode)
- {
- case CONTROL_MODE_TORQUE:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Using CONTROL_MODE_TORQUE");
- }
- mb->clearForcesAndTorques();
-
- int torqueIndex = 0;
- btVector3 f(clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[0],
- clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[1],
- clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[2]);
- btVector3 t(clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[3],
- clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[4],
- clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[5]);
- torqueIndex+=6;
- mb->addBaseForce(f);
- mb->addBaseTorque(t);
- for (int link=0;link<mb->getNumLinks();link++)
- {
-
- for (int dof=0;dof<mb->getLink(link).m_dofCount;dof++)
- {
- double torque = clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[torqueIndex];
- mb->addJointTorqueMultiDof(link,dof,torque);
- torqueIndex++;
- }
- }
- break;
- }
- case CONTROL_MODE_VELOCITY:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Using CONTROL_MODE_VELOCITY");
- }
-
- int numMotors = 0;
- //find the joint motors and apply the desired velocity and maximum force/torque
- {
- int dofIndex = 6;//skip the 3 linear + 3 angular degree of freedom entries of the base
- for (int link=0;link<mb->getNumLinks();link++)
- {
- if (supportsJointMotor(mb,link))
- {
-
- btMultiBodyJointMotor** motorPtr = m_data->m_multiBodyJointMotorMap[link];
- if (motorPtr)
- {
- btMultiBodyJointMotor* motor = *motorPtr;
- btScalar desiredVelocity = clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateQdot[dofIndex];
- motor->setVelocityTarget(desiredVelocity);
- btScalar maxImp = clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[dofIndex]*m_data->m_physicsDeltaTime;
- motor->setMaxAppliedImpulse(maxImp);
- numMotors++;
- }
- }
- dofIndex += mb->getLink(link).m_dofCount;
- }
- }
- break;
- }
- case CONTROL_MODE_POSITION_VELOCITY_PD:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Using CONTROL_MODE_POSITION_VELOCITY_PD");
- }
- //compute the force base on PD control
- mb->clearForcesAndTorques();
- int numMotors = 0;
- //find the joint motors and apply the desired velocity and maximum force/torque
- {
- int velIndex = 6;//skip the 3 linear + 3 angular degree of freedom velocity entries of the base
- int posIndex = 7;//skip 3 positional and 4 orientation (quaternion) positional degrees of freedom of the base
- for (int link=0;link<mb->getNumLinks();link++)
- {
- if (supportsJointMotor(mb,link))
- {
-
- btMultiBodyJointMotor** motorPtr = m_data->m_multiBodyJointMotorMap[link];
- if (motorPtr)
- {
- btMultiBodyJointMotor* motor = *motorPtr;
-
- btScalar desiredVelocity = clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateQdot[velIndex];
- btScalar desiredPosition = clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateQ[posIndex];
-
- btScalar kp = clientCmd.m_sendDesiredStateCommandArgument.m_Kp[velIndex];
- btScalar kd = clientCmd.m_sendDesiredStateCommandArgument.m_Kd[velIndex];
- int dof1 = 0;
- btScalar currentPosition = mb->getJointPosMultiDof(link)[dof1];
- btScalar currentVelocity = mb->getJointVelMultiDof(link)[dof1];
- btScalar positionStabiliationTerm = (desiredPosition-currentPosition)/m_data->m_physicsDeltaTime;
- btScalar velocityError = (desiredVelocity - currentVelocity);
-
- desiredVelocity = kp * positionStabiliationTerm +
- kd * velocityError;
-
- motor->setVelocityTarget(desiredVelocity);
-
- btScalar maxImp = clientCmd.m_sendDesiredStateCommandArgument.m_desiredStateForceTorque[velIndex]*m_data->m_physicsDeltaTime;
-
- motor->setMaxAppliedImpulse(1000);//maxImp);
- numMotors++;
- }
- }
- velIndex += mb->getLink(link).m_dofCount;
- posIndex += mb->getLink(link).m_posVarCount;
- }
- }
- break;
- }
- default:
- {
- b3Warning("m_controlMode not implemented yet");
- break;
- }
-
- }
- }
-
- serverStatusOut.m_type = CMD_DESIRED_STATE_RECEIVED_COMPLETED;
- hasStatus = true;
- break;
- }
- case CMD_REQUEST_ACTUAL_STATE:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Sending the actual state (Q,U)");
- }
- int bodyUniqueId = clientCmd.m_requestActualStateInformationCommandArgument.m_bodyUniqueId;
- InteralBodyData* body = m_data->getHandle(bodyUniqueId);
-
- if (body && body->m_multiBody)
- {
- btMultiBody* mb = body->m_multiBody;
- SharedMemoryStatus& serverCmd = serverStatusOut;
- serverStatusOut.m_type = CMD_ACTUAL_STATE_UPDATE_COMPLETED;
- serverCmd.m_sendActualStateArgs.m_bodyUniqueId = bodyUniqueId;
- int totalDegreeOfFreedomQ = 0;
- int totalDegreeOfFreedomU = 0;
-
-
- //always add the base, even for static (non-moving objects)
- //so that we can easily move the 'fixed' base when needed
- //do we don't use this conditional "if (!mb->hasFixedBase())"
- {
- btTransform tr;
- tr.setOrigin(mb->getBasePos());
- tr.setRotation(mb->getWorldToBaseRot().inverse());
-
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[0] =
- body->m_rootLocalInertialFrame.getOrigin()[0];
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[1] =
- body->m_rootLocalInertialFrame.getOrigin()[1];
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[2] =
- body->m_rootLocalInertialFrame.getOrigin()[2];
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[3] =
- body->m_rootLocalInertialFrame.getRotation()[0];
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[4] =
- body->m_rootLocalInertialFrame.getRotation()[1];
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[5] =
- body->m_rootLocalInertialFrame.getRotation()[2];
- serverCmd.m_sendActualStateArgs.m_rootLocalInertialFrame[6] =
- body->m_rootLocalInertialFrame.getRotation()[3];
-
- //base position in world space, carthesian
- serverCmd.m_sendActualStateArgs.m_actualStateQ[0] = tr.getOrigin()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[1] = tr.getOrigin()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[2] = tr.getOrigin()[2];
- //base orientation, quaternion x,y,z,w, in world space, carthesian
- serverCmd.m_sendActualStateArgs.m_actualStateQ[3] = tr.getRotation()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[4] = tr.getRotation()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[5] = tr.getRotation()[2];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[6] = tr.getRotation()[3];
- totalDegreeOfFreedomQ +=7;//pos + quaternion
- //base linear velocity (in world space, carthesian)
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[0] = mb->getBaseVel()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[1] = mb->getBaseVel()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[2] = mb->getBaseVel()[2];
-
- //base angular velocity (in world space, carthesian)
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[3] = mb->getBaseOmega()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[4] = mb->getBaseOmega()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[5] = mb->getBaseOmega()[2];
- totalDegreeOfFreedomU += 6;//3 linear and 3 angular DOF
- }
- for (int l=0;l<mb->getNumLinks();l++)
- {
- for (int d=0;d<mb->getLink(l).m_posVarCount;d++)
- {
- serverCmd.m_sendActualStateArgs.m_actualStateQ[totalDegreeOfFreedomQ++] = mb->getJointPosMultiDof(l)[d];
- }
- for (int d=0;d<mb->getLink(l).m_dofCount;d++)
- {
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[totalDegreeOfFreedomU++] = mb->getJointVelMultiDof(l)[d];
- }
-
- if (0 == mb->getLink(l).m_jointFeedback)
- {
- for (int d=0;d<6;d++)
- {
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+d]=0;
- }
- } else
- {
- btVector3 sensedForce = mb->getLink(l).m_jointFeedback->m_reactionForces.getLinear();
- btVector3 sensedTorque = mb->getLink(l).m_jointFeedback->m_reactionForces.getAngular();
-
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+0] = sensedForce[0];
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+1] = sensedForce[1];
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+2] = sensedForce[2];
-
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+3] = sensedTorque[0];
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+4] = sensedTorque[1];
- serverCmd.m_sendActualStateArgs.m_jointReactionForces[l*6+5] = sensedTorque[2];
- }
- }
- serverCmd.m_sendActualStateArgs.m_numDegreeOfFreedomQ = totalDegreeOfFreedomQ;
- serverCmd.m_sendActualStateArgs.m_numDegreeOfFreedomU = totalDegreeOfFreedomU;
-
- hasStatus = true;
-
- } else
- {
- if (body && body->m_rigidBody)
- {
- btRigidBody* rb = body->m_rigidBody;
- SharedMemoryStatus& serverCmd = serverStatusOut;
- serverCmd.m_type = CMD_ACTUAL_STATE_UPDATE_COMPLETED;
- serverCmd.m_sendActualStateArgs.m_bodyUniqueId = bodyUniqueId;
- int totalDegreeOfFreedomQ = 0;
- int totalDegreeOfFreedomU = 0;
- btTransform tr = rb->getWorldTransform();
- //base position in world space, carthesian
- serverCmd.m_sendActualStateArgs.m_actualStateQ[0] = tr.getOrigin()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[1] = tr.getOrigin()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[2] = tr.getOrigin()[2];
- //base orientation, quaternion x,y,z,w, in world space, carthesian
- serverCmd.m_sendActualStateArgs.m_actualStateQ[3] = tr.getRotation()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[4] = tr.getRotation()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[5] = tr.getRotation()[2];
- serverCmd.m_sendActualStateArgs.m_actualStateQ[6] = tr.getRotation()[3];
- totalDegreeOfFreedomQ +=7;//pos + quaternion
- //base linear velocity (in world space, carthesian)
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[0] = rb->getLinearVelocity()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[1] = rb->getLinearVelocity()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[2] = rb->getLinearVelocity()[2];
-
- //base angular velocity (in world space, carthesian)
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[3] = rb->getAngularVelocity()[0];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[4] = rb->getAngularVelocity()[1];
- serverCmd.m_sendActualStateArgs.m_actualStateQdot[5] = rb->getAngularVelocity()[2];
- totalDegreeOfFreedomU += 6;//3 linear and 3 angular DOF
- serverCmd.m_sendActualStateArgs.m_numDegreeOfFreedomQ = totalDegreeOfFreedomQ;
- serverCmd.m_sendActualStateArgs.m_numDegreeOfFreedomU = totalDegreeOfFreedomU;
- hasStatus = true;
- } else
- {
- b3Warning("Request state but no multibody or rigid body available");
- SharedMemoryStatus& serverCmd = serverStatusOut;
- serverCmd.m_type = CMD_ACTUAL_STATE_UPDATE_FAILED;
- hasStatus = true;
- }
- }
- break;
- }
- case CMD_STEP_FORWARD_SIMULATION:
- {
-
- if (m_data->m_verboseOutput)
- {
- b3Printf("Step simulation request");
- }
- m_data->m_dynamicsWorld->stepSimulation(m_data->m_physicsDeltaTime,0);
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_STEP_FORWARD_SIMULATION_COMPLETED;
- hasStatus = true;
- break;
- }
-
- case CMD_SEND_PHYSICS_SIMULATION_PARAMETERS:
- {
- if (clientCmd.m_updateFlags&SIM_PARAM_UPDATE_DELTA_TIME)
- {
- m_data->m_physicsDeltaTime = clientCmd.m_physSimParamArgs.m_deltaTime;
- }
- if (clientCmd.m_updateFlags&SIM_PARAM_UPDATE_GRAVITY)
- {
- btVector3 grav(clientCmd.m_physSimParamArgs.m_gravityAcceleration[0],
- clientCmd.m_physSimParamArgs.m_gravityAcceleration[1],
- clientCmd.m_physSimParamArgs.m_gravityAcceleration[2]);
- this->m_data->m_dynamicsWorld->setGravity(grav);
- if (m_data->m_verboseOutput)
- {
- b3Printf("Updated Gravity: %f,%f,%f",grav[0],grav[1],grav[2]);
- }
- }
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_CLIENT_COMMAND_COMPLETED;
- hasStatus = true;
- break;
-
- };
- case CMD_INIT_POSE:
- {
- if (m_data->m_verboseOutput)
- {
- b3Printf("Server Init Pose not implemented yet");
- }
- int bodyUniqueId = clientCmd.m_initPoseArgs.m_bodyUniqueId;
- InteralBodyData* body = m_data->getHandle(bodyUniqueId);
- if (body && body->m_multiBody)
- {
- btMultiBody* mb = body->m_multiBody;
- if (clientCmd.m_updateFlags & INIT_POSE_HAS_INITIAL_POSITION)
- {
- btVector3 zero(0,0,0);
- mb->setBaseVel(zero);
- mb->setBasePos(btVector3(
- clientCmd.m_initPoseArgs.m_initialStateQ[0],
- clientCmd.m_initPoseArgs.m_initialStateQ[1],
- clientCmd.m_initPoseArgs.m_initialStateQ[2]));
- }
- if (clientCmd.m_updateFlags & INIT_POSE_HAS_INITIAL_ORIENTATION)
- {
- mb->setBaseOmega(btVector3(0,0,0));
- mb->setWorldToBaseRot(btQuaternion(
- clientCmd.m_initPoseArgs.m_initialStateQ[3],
- clientCmd.m_initPoseArgs.m_initialStateQ[4],
- clientCmd.m_initPoseArgs.m_initialStateQ[5],
- clientCmd.m_initPoseArgs.m_initialStateQ[6]));
- }
- if (clientCmd.m_updateFlags & INIT_POSE_HAS_JOINT_STATE)
- {
- int dofIndex = 7;
- for (int i=0;i<mb->getNumLinks();i++)
- {
- if (mb->getLink(i).m_dofCount==1)
- {
-
- mb->setJointPos(i,clientCmd.m_initPoseArgs.m_initialStateQ[dofIndex]);
- mb->setJointVel(i,0);
- }
- dofIndex += mb->getLink(i).m_dofCount;
- }
- }
- }
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_CLIENT_COMMAND_COMPLETED;
- hasStatus = true;
- break;
- }
-
- case CMD_RESET_SIMULATION:
- {
- //clean up all data
- if (m_data && m_data->m_guiHelper && m_data->m_guiHelper->getRenderInterface())
- {
- m_data->m_guiHelper->getRenderInterface()->removeAllInstances();
- }
- deleteDynamicsWorld();
- createEmptyDynamicsWorld();
- m_data->exitHandles();
- m_data->initHandles();
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_RESET_SIMULATION_COMPLETED;
- hasStatus = true;
- break;
- }
- case CMD_CREATE_RIGID_BODY:
- case CMD_CREATE_BOX_COLLISION_SHAPE:
- {
- btVector3 halfExtents(1,1,1);
- if (clientCmd.m_updateFlags & BOX_SHAPE_HAS_HALF_EXTENTS)
- {
- halfExtents = btVector3(
- clientCmd.m_createBoxShapeArguments.m_halfExtentsX,
- clientCmd.m_createBoxShapeArguments.m_halfExtentsY,
- clientCmd.m_createBoxShapeArguments.m_halfExtentsZ);
- }
- btTransform startTrans;
- startTrans.setIdentity();
- if (clientCmd.m_updateFlags & BOX_SHAPE_HAS_INITIAL_POSITION)
- {
- startTrans.setOrigin(btVector3(
- clientCmd.m_createBoxShapeArguments.m_initialPosition[0],
- clientCmd.m_createBoxShapeArguments.m_initialPosition[1],
- clientCmd.m_createBoxShapeArguments.m_initialPosition[2]));
- }
- if (clientCmd.m_updateFlags & BOX_SHAPE_HAS_INITIAL_ORIENTATION)
- {
-
- startTrans.setRotation(btQuaternion(
- clientCmd.m_createBoxShapeArguments.m_initialOrientation[0],
- clientCmd.m_createBoxShapeArguments.m_initialOrientation[1],
- clientCmd.m_createBoxShapeArguments.m_initialOrientation[2],
- clientCmd.m_createBoxShapeArguments.m_initialOrientation[3]));
- }
- btScalar mass = 0.f;
- if (clientCmd.m_updateFlags & BOX_SHAPE_HAS_MASS)
- {
- mass = clientCmd.m_createBoxShapeArguments.m_mass;
- }
- int shapeType = COLLISION_SHAPE_TYPE_BOX;
- if (clientCmd.m_updateFlags & BOX_SHAPE_HAS_COLLISION_SHAPE_TYPE)
- {
- shapeType = clientCmd.m_createBoxShapeArguments.m_collisionShapeType;
- }
- btBulletWorldImporter* worldImporter = new btBulletWorldImporter(m_data->m_dynamicsWorld);
- m_data->m_worldImporters.push_back(worldImporter);
- btCollisionShape* shape = 0;
-
- switch (shapeType)
- {
- case COLLISION_SHAPE_TYPE_CYLINDER_X:
- {
- btScalar radius = halfExtents[1];
- btScalar height = halfExtents[0];
- shape = worldImporter->createCylinderShapeX(radius,height);
- break;
- }
- case COLLISION_SHAPE_TYPE_CYLINDER_Y:
- {
- btScalar radius = halfExtents[0];
- btScalar height = halfExtents[1];
- shape = worldImporter->createCylinderShapeY(radius,height);
- break;
- }
- case COLLISION_SHAPE_TYPE_CYLINDER_Z:
- {
- btScalar radius = halfExtents[1];
- btScalar height = halfExtents[2];
- shape = worldImporter->createCylinderShapeZ(radius,height);
- break;
- }
- case COLLISION_SHAPE_TYPE_CAPSULE_X:
- {
- btScalar radius = halfExtents[1];
- btScalar height = halfExtents[0];
- shape = worldImporter->createCapsuleShapeX(radius,height);
- break;
- }
- case COLLISION_SHAPE_TYPE_CAPSULE_Y:
- {
- btScalar radius = halfExtents[0];
- btScalar height = halfExtents[1];
- shape = worldImporter->createCapsuleShapeY(radius,height);
- break;
- }
- case COLLISION_SHAPE_TYPE_CAPSULE_Z:
- {
- btScalar radius = halfExtents[1];
- btScalar height = halfExtents[2];
- shape = worldImporter->createCapsuleShapeZ(radius,height);
- break;
- }
- case COLLISION_SHAPE_TYPE_SPHERE:
- {
- btScalar radius = halfExtents[0];
- shape = worldImporter->createSphereShape(radius);
- break;
- }
- case COLLISION_SHAPE_TYPE_BOX:
- default:
- {
- shape = worldImporter->createBoxShape(halfExtents);
- }
- }
-
-
- bool isDynamic = (mass>0);
- btRigidBody* rb = worldImporter->createRigidBody(isDynamic,mass,startTrans,shape,0);
- rb->setRollingFriction(0.2);
- //m_data->m_guiHelper->autogenerateGraphicsObjects(this->m_data->m_dynamicsWorld);
- btVector4 colorRGBA(1,0,0,1);
- if (clientCmd.m_updateFlags & BOX_SHAPE_HAS_COLOR)
- {
- colorRGBA[0] = clientCmd.m_createBoxShapeArguments.m_colorRGBA[0];
- colorRGBA[1] = clientCmd.m_createBoxShapeArguments.m_colorRGBA[1];
- colorRGBA[2] = clientCmd.m_createBoxShapeArguments.m_colorRGBA[2];
- colorRGBA[3] = clientCmd.m_createBoxShapeArguments.m_colorRGBA[3];
- }
- m_data->m_guiHelper->createCollisionShapeGraphicsObject(rb->getCollisionShape());
- m_data->m_guiHelper->createCollisionObjectGraphicsObject(rb,colorRGBA);
-
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_RIGID_BODY_CREATION_COMPLETED;
-
- int bodyUniqueId = m_data->allocHandle();
- InternalBodyHandle* bodyHandle = m_data->getHandle(bodyUniqueId);
- serverCmd.m_rigidBodyCreateArgs.m_bodyUniqueId = bodyUniqueId;
- bodyHandle->m_rootLocalInertialFrame.setIdentity();
- bodyHandle->m_rigidBody = rb;
- hasStatus = true;
- break;
- }
- case CMD_PICK_BODY:
- {
- pickBody(btVector3(clientCmd.m_pickBodyArguments.m_rayFromWorld[0],
- clientCmd.m_pickBodyArguments.m_rayFromWorld[1],
- clientCmd.m_pickBodyArguments.m_rayFromWorld[2]),
- btVector3(clientCmd.m_pickBodyArguments.m_rayToWorld[0],
- clientCmd.m_pickBodyArguments.m_rayToWorld[1],
- clientCmd.m_pickBodyArguments.m_rayToWorld[2]));
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_CLIENT_COMMAND_COMPLETED;
- hasStatus = true;
- break;
- }
- case CMD_MOVE_PICKED_BODY:
- {
- movePickedBody(btVector3(clientCmd.m_pickBodyArguments.m_rayFromWorld[0],
- clientCmd.m_pickBodyArguments.m_rayFromWorld[1],
- clientCmd.m_pickBodyArguments.m_rayFromWorld[2]),
- btVector3(clientCmd.m_pickBodyArguments.m_rayToWorld[0],
- clientCmd.m_pickBodyArguments.m_rayToWorld[1],
- clientCmd.m_pickBodyArguments.m_rayToWorld[2]));
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_CLIENT_COMMAND_COMPLETED;
- hasStatus = true;
- break;
- }
- case CMD_REMOVE_PICKING_CONSTRAINT_BODY:
- {
- removePickingConstraint();
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_CLIENT_COMMAND_COMPLETED;
- hasStatus = true;
- break;
- }
- default:
- {
- b3Error("Unknown command encountered");
-
- SharedMemoryStatus& serverCmd =serverStatusOut;
- serverCmd.m_type = CMD_UNKNOWN_COMMAND_FLUSHED;
- hasStatus = true;
- }
- };
-
- }
- }
- return hasStatus;
- }
- void PhysicsServerCommandProcessor::renderScene()
- {
- if (m_data->m_guiHelper)
- {
- m_data->m_guiHelper->syncPhysicsToGraphics(m_data->m_dynamicsWorld);
-
- m_data->m_guiHelper->render(m_data->m_dynamicsWorld);
- }
-
- }
- void PhysicsServerCommandProcessor::physicsDebugDraw(int debugDrawFlags)
- {
- if (m_data->m_dynamicsWorld)
- {
- if (m_data->m_dynamicsWorld->getDebugDrawer())
- {
- m_data->m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags);
- m_data->m_dynamicsWorld->debugDrawWorld();
- }
- }
- }
- bool PhysicsServerCommandProcessor::pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
- {
- if (m_data->m_dynamicsWorld==0)
- return false;
- btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);
- m_data->m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
- if (rayCallback.hasHit())
- {
- btVector3 pickPos = rayCallback.m_hitPointWorld;
- btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
- if (body)
- {
- //other exclusions?
- if (!(body->isStaticObject() || body->isKinematicObject()))
- {
- m_data->m_pickedBody = body;
- m_data->m_pickedBody->setActivationState(DISABLE_DEACTIVATION);
- //printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
- btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
- btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body, localPivot);
- m_data->m_dynamicsWorld->addConstraint(p2p, true);
- m_data->m_pickedConstraint = p2p;
- btScalar mousePickClamping = 30.f;
- p2p->m_setting.m_impulseClamp = mousePickClamping;
- //very weak constraint for picking
- p2p->m_setting.m_tau = 0.001f;
- }
- } else
- {
- btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject);
- if (multiCol && multiCol->m_multiBody)
- {
-
- m_data->m_prevCanSleep = multiCol->m_multiBody->getCanSleep();
- multiCol->m_multiBody->setCanSleep(false);
- btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos);
- btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody,multiCol->m_link,0,pivotInA,pickPos);
- //if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
- //see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
- //so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
- //it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)
- btScalar scaling=1;
- p2p->setMaxAppliedImpulse(2*scaling);
-
- btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_data->m_dynamicsWorld;
- world->addMultiBodyConstraint(p2p);
- m_data->m_pickingMultiBodyPoint2Point =p2p;
- }
- }
- // pickObject(pickPos, rayCallback.m_collisionObject);
- m_data->m_oldPickingPos = rayToWorld;
- m_data->m_hitPos = pickPos;
- m_data->m_oldPickingDist = (pickPos - rayFromWorld).length();
- // printf("hit !\n");
- //add p2p
- }
- return false;
- }
- bool PhysicsServerCommandProcessor::movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld)
- {
- if (m_data->m_pickedBody && m_data->m_pickedConstraint)
- {
- btPoint2PointConstraint* pickCon = static_cast<btPoint2PointConstraint*>(m_data->m_pickedConstraint);
- if (pickCon)
- {
- //keep it at the same picking distance
-
- btVector3 dir = rayToWorld-rayFromWorld;
- dir.normalize();
- dir *= m_data->m_oldPickingDist;
- btVector3 newPivotB = rayFromWorld + dir;
- pickCon->setPivotB(newPivotB);
- }
- }
-
- if (m_data->m_pickingMultiBodyPoint2Point)
- {
- //keep it at the same picking distance
-
- btVector3 dir = rayToWorld-rayFromWorld;
- dir.normalize();
- dir *= m_data->m_oldPickingDist;
- btVector3 newPivotB = rayFromWorld + dir;
-
- m_data->m_pickingMultiBodyPoint2Point->setPivotInB(newPivotB);
- }
-
- return false;
- }
- void PhysicsServerCommandProcessor::removePickingConstraint()
- {
- if (m_data->m_pickedConstraint)
- {
- m_data->m_dynamicsWorld->removeConstraint(m_data->m_pickedConstraint);
- delete m_data->m_pickedConstraint;
- m_data->m_pickedConstraint = 0;
- m_data->m_pickedBody = 0;
- }
- if (m_data->m_pickingMultiBodyPoint2Point)
- {
- m_data->m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(m_data->m_prevCanSleep);
- btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_data->m_dynamicsWorld;
- world->removeMultiBodyConstraint(m_data->m_pickingMultiBodyPoint2Point);
- delete m_data->m_pickingMultiBodyPoint2Point;
- m_data->m_pickingMultiBodyPoint2Point = 0;
- }
- }
- void PhysicsServerCommandProcessor::enableCommandLogging(bool enable, const char* fileName)
- {
- if (enable)
- {
- if (0==m_data->m_commandLogger)
- {
- m_data->m_commandLogger = new CommandLogger(fileName);
- }
- } else
- {
- if (0!=m_data->m_commandLogger)
- {
- delete m_data->m_commandLogger;
- m_data->m_commandLogger = 0;
- }
- }
- }
- void PhysicsServerCommandProcessor::replayFromLogFile(const char* fileName)
- {
- CommandLogPlayback* pb = new CommandLogPlayback(fileName);
- m_data->m_logPlayback = pb;
- }
|