PhysicsClientSharedMemory.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. #include "PhysicsClientSharedMemory.h"
  2. #include "PosixSharedMemory.h"
  3. #include "Win32SharedMemory.h"
  4. #include "LinearMath/btAlignedObjectArray.h"
  5. #include "LinearMath/btVector3.h"
  6. #include <string.h>
  7. #include "Bullet3Common/b3Logging.h"
  8. #include "../Utils/b3ResourcePath.h"
  9. #include "../../Extras/Serialize/BulletFileLoader/btBulletFile.h"
  10. #include "../../Extras/Serialize/BulletFileLoader/autogenerated/bullet.h"
  11. #include "SharedMemoryBlock.h"
  12. #include "BodyJointInfoUtility.h"
  13. struct BodyJointInfoCache
  14. {
  15. btAlignedObjectArray<b3JointInfo> m_jointInfo;
  16. };
  17. struct PhysicsClientSharedMemoryInternalData {
  18. SharedMemoryInterface* m_sharedMemory;
  19. SharedMemoryBlock* m_testBlock1;
  20. btHashMap<btHashInt,BodyJointInfoCache*> m_bodyJointMap;
  21. btAlignedObjectArray<TmpFloat3> m_debugLinesFrom;
  22. btAlignedObjectArray<TmpFloat3> m_debugLinesTo;
  23. btAlignedObjectArray<TmpFloat3> m_debugLinesColor;
  24. SharedMemoryStatus m_lastServerStatus;
  25. int m_counter;
  26. bool m_serverLoadUrdfOK;
  27. bool m_isConnected;
  28. bool m_waitingForServer;
  29. bool m_hasLastServerStatus;
  30. int m_sharedMemoryKey;
  31. bool m_verboseOutput;
  32. PhysicsClientSharedMemoryInternalData()
  33. : m_sharedMemory(0),
  34. m_testBlock1(0),
  35. m_counter(0),
  36. m_serverLoadUrdfOK(false),
  37. m_isConnected(false),
  38. m_waitingForServer(false),
  39. m_hasLastServerStatus(false),
  40. m_sharedMemoryKey(SHARED_MEMORY_KEY),
  41. m_verboseOutput(false) {}
  42. void processServerStatus();
  43. bool canSubmitCommand() const;
  44. };
  45. int PhysicsClientSharedMemory::getNumJoints(int bodyIndex) const
  46. {
  47. BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
  48. if (bodyJointsPtr && *bodyJointsPtr)
  49. {
  50. BodyJointInfoCache* bodyJoints = *bodyJointsPtr;
  51. return bodyJoints->m_jointInfo.size();
  52. }
  53. btAssert(0);
  54. return 0;
  55. }
  56. void PhysicsClientSharedMemory::getJointInfo(int bodyIndex, int jointIndex, b3JointInfo& info) const
  57. {
  58. BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap[bodyIndex];
  59. if (bodyJointsPtr && *bodyJointsPtr)
  60. {
  61. BodyJointInfoCache* bodyJoints = *bodyJointsPtr;
  62. info = bodyJoints->m_jointInfo[jointIndex];
  63. }
  64. }
  65. PhysicsClientSharedMemory::PhysicsClientSharedMemory()
  66. {
  67. m_data = new PhysicsClientSharedMemoryInternalData;
  68. #ifdef _WIN32
  69. m_data->m_sharedMemory = new Win32SharedMemoryClient();
  70. #else
  71. m_data->m_sharedMemory = new PosixSharedMemory();
  72. #endif
  73. }
  74. PhysicsClientSharedMemory::~PhysicsClientSharedMemory() {
  75. if (m_data->m_isConnected) {
  76. disconnectSharedMemory();
  77. }
  78. delete m_data->m_sharedMemory;
  79. delete m_data;
  80. }
  81. void PhysicsClientSharedMemory::setSharedMemoryKey(int key) { m_data->m_sharedMemoryKey = key; }
  82. void PhysicsClientSharedMemory::disconnectSharedMemory() {
  83. if (m_data->m_isConnected) {
  84. m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
  85. m_data->m_isConnected = false;
  86. }
  87. }
  88. bool PhysicsClientSharedMemory::isConnected() const { return m_data->m_isConnected; }
  89. bool PhysicsClientSharedMemory::connect() {
  90. /// server always has to create and initialize shared memory
  91. bool allowCreation = false;
  92. m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(
  93. m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE, allowCreation);
  94. if (m_data->m_testBlock1) {
  95. if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER) {
  96. b3Error("Error: please start server before client\n");
  97. m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey,
  98. SHARED_MEMORY_SIZE);
  99. m_data->m_testBlock1 = 0;
  100. return false;
  101. } else {
  102. if (m_data->m_verboseOutput) {
  103. b3Printf("Connected to existing shared memory, status OK.\n");
  104. }
  105. m_data->m_isConnected = true;
  106. }
  107. } else {
  108. b3Error("Cannot connect to shared memory");
  109. return false;
  110. }
  111. return true;
  112. }
  113. const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
  114. SharedMemoryStatus* stat = 0;
  115. if (!m_data->m_testBlock1) {
  116. return 0;
  117. }
  118. if (!m_data->m_waitingForServer) {
  119. return 0;
  120. }
  121. if (m_data->m_testBlock1->m_numServerCommands >
  122. m_data->m_testBlock1->m_numProcessedServerCommands) {
  123. btAssert(m_data->m_testBlock1->m_numServerCommands ==
  124. m_data->m_testBlock1->m_numProcessedServerCommands + 1);
  125. const SharedMemoryStatus& serverCmd = m_data->m_testBlock1->m_serverCommands[0];
  126. m_data->m_lastServerStatus = serverCmd;
  127. EnumSharedMemoryServerStatus s = (EnumSharedMemoryServerStatus)serverCmd.m_type;
  128. // consume the command
  129. switch (serverCmd.m_type) {
  130. case CMD_CLIENT_COMMAND_COMPLETED: {
  131. if (m_data->m_verboseOutput) {
  132. b3Printf("Server completed command");
  133. }
  134. break;
  135. }
  136. case CMD_URDF_LOADING_COMPLETED: {
  137. m_data->m_serverLoadUrdfOK = true;
  138. if (m_data->m_verboseOutput) {
  139. b3Printf("Server loading the URDF OK\n");
  140. }
  141. if (serverCmd.m_dataStreamArguments.m_streamChunkLength > 0) {
  142. bParse::btBulletFile bf(
  143. this->m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor,
  144. serverCmd.m_dataStreamArguments.m_streamChunkLength);
  145. bf.setFileDNAisMemoryDNA();
  146. bf.parse(false);
  147. int bodyIndex = serverCmd.m_dataStreamArguments.m_bodyUniqueId;
  148. BodyJointInfoCache* bodyJoints = new BodyJointInfoCache;
  149. m_data->m_bodyJointMap.insert(bodyIndex,bodyJoints);
  150. for (int i = 0; i < bf.m_multiBodies.size(); i++) {
  151. int flag = bf.getFlags();
  152. if ((flag & bParse::FD_DOUBLE_PRECISION) != 0) {
  153. Bullet::btMultiBodyDoubleData* mb =
  154. (Bullet::btMultiBodyDoubleData*)bf.m_multiBodies[i];
  155. addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
  156. } else
  157. {
  158. Bullet::btMultiBodyFloatData* mb =
  159. (Bullet::btMultiBodyFloatData*)bf.m_multiBodies[i];
  160. addJointInfoFromMultiBodyData(mb,bodyJoints, m_data->m_verboseOutput);
  161. }
  162. }
  163. if (bf.ok()) {
  164. if (m_data->m_verboseOutput) {
  165. b3Printf("Received robot description ok!\n");
  166. }
  167. } else {
  168. b3Warning("Robot description not received");
  169. }
  170. }
  171. break;
  172. }
  173. case CMD_DESIRED_STATE_RECEIVED_COMPLETED: {
  174. if (m_data->m_verboseOutput) {
  175. b3Printf("Server received desired state");
  176. }
  177. break;
  178. }
  179. case CMD_STEP_FORWARD_SIMULATION_COMPLETED: {
  180. if (m_data->m_verboseOutput) {
  181. b3Printf("Server completed step simulation");
  182. }
  183. break;
  184. }
  185. case CMD_URDF_LOADING_FAILED: {
  186. if (m_data->m_verboseOutput) {
  187. b3Printf("Server failed loading the URDF...\n");
  188. }
  189. m_data->m_serverLoadUrdfOK = false;
  190. break;
  191. }
  192. case CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED: {
  193. if (m_data->m_verboseOutput) {
  194. b3Printf("Server received bullet data stream OK\n");
  195. }
  196. break;
  197. }
  198. case CMD_BULLET_DATA_STREAM_RECEIVED_FAILED: {
  199. if (m_data->m_verboseOutput) {
  200. b3Printf("Server failed receiving bullet data stream\n");
  201. }
  202. break;
  203. }
  204. case CMD_ACTUAL_STATE_UPDATE_COMPLETED: {
  205. if (m_data->m_verboseOutput) {
  206. b3Printf("Received actual state\n");
  207. }
  208. SharedMemoryStatus& command = m_data->m_testBlock1->m_serverCommands[0];
  209. int numQ = command.m_sendActualStateArgs.m_numDegreeOfFreedomQ;
  210. int numU = command.m_sendActualStateArgs.m_numDegreeOfFreedomU;
  211. if (m_data->m_verboseOutput) {
  212. b3Printf("size Q = %d, size U = %d\n", numQ, numU);
  213. }
  214. char msg[1024];
  215. {
  216. sprintf(msg, "Q=[");
  217. for (int i = 0; i < numQ; i++) {
  218. if (i < numQ - 1) {
  219. sprintf(msg, "%s%f,", msg,
  220. command.m_sendActualStateArgs.m_actualStateQ[i]);
  221. } else {
  222. sprintf(msg, "%s%f", msg,
  223. command.m_sendActualStateArgs.m_actualStateQ[i]);
  224. }
  225. }
  226. sprintf(msg, "%s]", msg);
  227. }
  228. if (m_data->m_verboseOutput) {
  229. b3Printf(msg);
  230. }
  231. {
  232. sprintf(msg, "U=[");
  233. for (int i = 0; i < numU; i++) {
  234. if (i < numU - 1) {
  235. sprintf(msg, "%s%f,", msg,
  236. command.m_sendActualStateArgs.m_actualStateQdot[i]);
  237. } else {
  238. sprintf(msg, "%s%f", msg,
  239. command.m_sendActualStateArgs.m_actualStateQdot[i]);
  240. }
  241. }
  242. sprintf(msg, "%s]", msg);
  243. }
  244. if (m_data->m_verboseOutput) {
  245. b3Printf(msg);
  246. }
  247. if (m_data->m_verboseOutput) {
  248. b3Printf("\n");
  249. }
  250. break;
  251. }
  252. case CMD_RESET_SIMULATION_COMPLETED: {
  253. if (m_data->m_verboseOutput) {
  254. b3Printf("CMD_RESET_SIMULATION_COMPLETED clean data\n");
  255. }
  256. m_data->m_debugLinesFrom.clear();
  257. m_data->m_debugLinesTo.clear();
  258. m_data->m_debugLinesColor.clear();
  259. for (int i=0;i<m_data->m_bodyJointMap.size();i++)
  260. {
  261. BodyJointInfoCache** bodyJointsPtr = m_data->m_bodyJointMap.getAtIndex(i);
  262. if (bodyJointsPtr && *bodyJointsPtr)
  263. {
  264. BodyJointInfoCache* bodyJoints = *bodyJointsPtr;
  265. for (int j=0;j<bodyJoints->m_jointInfo.size();j++) {
  266. if (bodyJoints->m_jointInfo[j].m_jointName)
  267. {
  268. free(bodyJoints->m_jointInfo[j].m_jointName);
  269. }
  270. if (bodyJoints->m_jointInfo[j].m_linkName)
  271. {
  272. free(bodyJoints->m_jointInfo[j].m_linkName);
  273. }
  274. }
  275. delete (*bodyJointsPtr);
  276. }
  277. }
  278. m_data->m_bodyJointMap.clear();
  279. break;
  280. }
  281. case CMD_DEBUG_LINES_COMPLETED: {
  282. if (m_data->m_verboseOutput) {
  283. b3Printf("Success receiving %d debug lines",
  284. serverCmd.m_sendDebugLinesArgs.m_numDebugLines);
  285. }
  286. int numLines = serverCmd.m_sendDebugLinesArgs.m_numDebugLines;
  287. float* linesFrom =
  288. (float*)&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0];
  289. float* linesTo =
  290. (float*)(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0] +
  291. numLines * 3 * sizeof(float));
  292. float* linesColor =
  293. (float*)(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0] +
  294. 2 * numLines * 3 * sizeof(float));
  295. m_data->m_debugLinesFrom.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
  296. numLines);
  297. m_data->m_debugLinesTo.resize(serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
  298. numLines);
  299. m_data->m_debugLinesColor.resize(
  300. serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + numLines);
  301. for (int i = 0; i < numLines; i++) {
  302. TmpFloat3 from = CreateTmpFloat3(linesFrom[i * 3], linesFrom[i * 3 + 1],
  303. linesFrom[i * 3 + 2]);
  304. TmpFloat3 to =
  305. CreateTmpFloat3(linesTo[i * 3], linesTo[i * 3 + 1], linesTo[i * 3 + 2]);
  306. TmpFloat3 color = CreateTmpFloat3(linesColor[i * 3], linesColor[i * 3 + 1],
  307. linesColor[i * 3 + 2]);
  308. m_data
  309. ->m_debugLinesFrom[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + i] =
  310. from;
  311. m_data->m_debugLinesTo[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex + i] =
  312. to;
  313. m_data->m_debugLinesColor[serverCmd.m_sendDebugLinesArgs.m_startingLineIndex +
  314. i] = color;
  315. }
  316. break;
  317. }
  318. case CMD_RIGID_BODY_CREATION_COMPLETED:
  319. {
  320. break;
  321. }
  322. case CMD_DEBUG_LINES_OVERFLOW_FAILED: {
  323. b3Warning("Error receiving debug lines");
  324. m_data->m_debugLinesFrom.resize(0);
  325. m_data->m_debugLinesTo.resize(0);
  326. m_data->m_debugLinesColor.resize(0);
  327. break;
  328. }
  329. default: {
  330. b3Error("Unknown server status\n");
  331. btAssert(0);
  332. }
  333. };
  334. m_data->m_testBlock1->m_numProcessedServerCommands++;
  335. // we don't have more than 1 command outstanding (in total, either server or client)
  336. btAssert(m_data->m_testBlock1->m_numProcessedServerCommands ==
  337. m_data->m_testBlock1->m_numServerCommands);
  338. if (m_data->m_testBlock1->m_numServerCommands ==
  339. m_data->m_testBlock1->m_numProcessedServerCommands) {
  340. m_data->m_waitingForServer = false;
  341. } else {
  342. m_data->m_waitingForServer = true;
  343. }
  344. if ((serverCmd.m_type == CMD_DEBUG_LINES_COMPLETED) &&
  345. (serverCmd.m_sendDebugLinesArgs.m_numRemainingDebugLines > 0)) {
  346. SharedMemoryCommand& command = m_data->m_testBlock1->m_clientCommands[0];
  347. // continue requesting debug lines for drawing
  348. command.m_type = CMD_REQUEST_DEBUG_LINES;
  349. command.m_requestDebugLinesArguments.m_startingLineIndex =
  350. serverCmd.m_sendDebugLinesArgs.m_numDebugLines +
  351. serverCmd.m_sendDebugLinesArgs.m_startingLineIndex;
  352. submitClientCommand(command);
  353. return 0;
  354. }
  355. return &m_data->m_lastServerStatus;
  356. } else {
  357. if (m_data->m_verboseOutput) {
  358. b3Printf("m_numServerStatus = %d, processed = %d\n",
  359. m_data->m_testBlock1->m_numServerCommands,
  360. m_data->m_testBlock1->m_numProcessedServerCommands);
  361. }
  362. }
  363. return 0;
  364. }
  365. bool PhysicsClientSharedMemory::canSubmitCommand() const {
  366. return (m_data->m_isConnected && !m_data->m_waitingForServer);
  367. }
  368. struct SharedMemoryCommand* PhysicsClientSharedMemory::getAvailableSharedMemoryCommand() {
  369. return &m_data->m_testBlock1->m_clientCommands[0];
  370. }
  371. bool PhysicsClientSharedMemory::submitClientCommand(const SharedMemoryCommand& command) {
  372. /// at the moment we allow a maximum of 1 outstanding command, so we check for this
  373. // once the server processed the command and returns a status, we clear the flag
  374. // "m_data->m_waitingForServer" and allow submitting the next command
  375. btAssert(!m_data->m_waitingForServer);
  376. if (!m_data->m_waitingForServer) {
  377. if (&m_data->m_testBlock1->m_clientCommands[0] != &command) {
  378. m_data->m_testBlock1->m_clientCommands[0] = command;
  379. }
  380. m_data->m_testBlock1->m_numClientCommands++;
  381. m_data->m_waitingForServer = true;
  382. return true;
  383. }
  384. return false;
  385. }
  386. void PhysicsClientSharedMemory::uploadBulletFileToSharedMemory(const char* data, int len) {
  387. btAssert(len < SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  388. if (len >= SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE) {
  389. b3Warning("uploadBulletFileToSharedMemory %d exceeds max size %d\n", len,
  390. SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
  391. } else {
  392. for (int i = 0; i < len; i++) {
  393. m_data->m_testBlock1->m_bulletStreamDataClientToServer[i] = data[i];
  394. }
  395. }
  396. }
  397. const float* PhysicsClientSharedMemory::getDebugLinesFrom() const {
  398. if (m_data->m_debugLinesFrom.size()) {
  399. return &m_data->m_debugLinesFrom[0].m_x;
  400. }
  401. return 0;
  402. }
  403. const float* PhysicsClientSharedMemory::getDebugLinesTo() const {
  404. if (m_data->m_debugLinesTo.size()) {
  405. return &m_data->m_debugLinesTo[0].m_x;
  406. }
  407. return 0;
  408. }
  409. const float* PhysicsClientSharedMemory::getDebugLinesColor() const {
  410. if (m_data->m_debugLinesColor.size()) {
  411. return &m_data->m_debugLinesColor[0].m_x;
  412. }
  413. return 0;
  414. }
  415. int PhysicsClientSharedMemory::getNumDebugLines() const { return m_data->m_debugLinesFrom.size(); }