or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

collision-detection.mdconnection-simulation.mdindex.mdinverse-kinematics-dynamics.mdjoint-motor-control.mdmathematical-utilities.mdobject-loading.mdphysics-configuration.mdrendering-visualization.mdstate-management-logging.mdvr-input-handling.md

state-management-logging.mddocs/

0

# State Management and Logging

1

2

Save and restore simulation states, log data for analysis, and manage user-defined data attachments. Essential for reproducible experiments, data collection, and simulation checkpointing.

3

4

## Capabilities

5

6

### State Management

7

8

```python { .api }

9

def saveState(physicsClientId=0):

10

"""

11

Save complete world state to memory.

12

13

Args:

14

physicsClientId (int, optional): Physics client ID

15

16

Returns:

17

int: State unique ID for later restoration

18

"""

19

20

def restoreState(stateId, fileName=None, physicsClientId=0):

21

"""

22

Restore world state from saved state ID or file.

23

24

Args:

25

stateId (int): State unique ID (if restoring from memory)

26

fileName (str, optional): File name (if restoring from file)

27

physicsClientId (int, optional): Physics client ID

28

"""

29

30

def removeState(stateId, physicsClientId=0):

31

"""

32

Remove saved state from memory.

33

34

Args:

35

stateId (int): State unique ID to remove

36

physicsClientId (int, optional): Physics client ID

37

"""

38

39

def loadBullet(bulletFileName, physicsClientId=0):

40

"""

41

Load world state from .bullet file.

42

43

Args:

44

bulletFileName (str): Path to .bullet file

45

physicsClientId (int, optional): Physics client ID

46

47

Returns:

48

list: List of loaded object IDs

49

"""

50

51

def saveBullet(bulletFileName, physicsClientId=0):

52

"""

53

Save complete world state to .bullet file.

54

55

Args:

56

bulletFileName (str): Output .bullet file path

57

physicsClientId (int, optional): Physics client ID

58

"""

59

60

def saveWorld(worldFileName, physicsClientId=0):

61

"""

62

Save world as approximate Python script.

63

64

Args:

65

worldFileName (str): Output Python file path

66

physicsClientId (int, optional): Physics client ID

67

"""

68

```

69

70

### Data Logging

71

72

```python { .api }

73

def startStateLogging(loggingType, fileName, objectUniqueIds=None, maxLogDof=None, bodyUniqueIdA=None, bodyUniqueIdB=None, linkIndexA=None, linkIndexB=None, physicsClientId=0):

74

"""

75

Start logging simulation data to file.

76

77

Args:

78

loggingType (int): Type of logging (STATE_LOGGING_VIDEO_MP4, etc.)

79

fileName (str): Output file name

80

objectUniqueIds (list, optional): Objects to log

81

maxLogDof (int, optional): Maximum degrees of freedom to log

82

83

Returns:

84

int: Logging unique ID

85

"""

86

87

def stopStateLogging(loggingUniqueId, physicsClientId=0):

88

"""

89

Stop data logging.

90

91

Args:

92

loggingUniqueId (int): Logging unique ID from startStateLogging

93

physicsClientId (int, optional): Physics client ID

94

"""

95

```

96

97

### User Data Management

98

99

```python { .api }

100

def addUserData(bodyUniqueId, key, value, linkIndex=-1, visualShapeIndex=-1, physicsClientId=0):

101

"""

102

Add or update user data entry for object.

103

104

Args:

105

bodyUniqueId (int): Object unique ID

106

key (str): Data key identifier

107

value (str): Data value

108

linkIndex (int, optional): Link index (-1 for base)

109

visualShapeIndex (int, optional): Visual shape index

110

physicsClientId (int, optional): Physics client ID

111

112

Returns:

113

int: User data unique ID

114

"""

115

116

def getUserData(userDataId, physicsClientId=0):

117

"""

118

Get user data value by ID.

119

120

Args:

121

userDataId (int): User data unique ID

122

physicsClientId (int, optional): Physics client ID

123

124

Returns:

125

str: User data value

126

"""

127

128

def getUserDataId(bodyUniqueId, key, linkIndex=-1, visualShapeIndex=-1, physicsClientId=0):

129

"""

130

Get user data ID by key.

131

132

Args:

133

bodyUniqueId (int): Object unique ID

134

key (str): Data key identifier

135

linkIndex (int, optional): Link index

136

visualShapeIndex (int, optional): Visual shape index

137

physicsClientId (int, optional): Physics client ID

138

139

Returns:

140

int: User data unique ID

141

"""

142

143

def removeUserData(userDataId, physicsClientId=0):

144

"""

145

Remove user data entry.

146

147

Args:

148

userDataId (int): User data unique ID

149

physicsClientId (int, optional): Physics client ID

150

"""

151

152

def getNumUserData(bodyUniqueId, physicsClientId=0):

153

"""

154

Get number of user data entries for object.

155

156

Args:

157

bodyUniqueId (int): Object unique ID

158

physicsClientId (int, optional): Physics client ID

159

160

Returns:

161

int: Number of user data entries

162

"""

163

164

def getUserDataInfo(bodyUniqueId, userDataIndex, physicsClientId=0):

165

"""

166

Get user data information by index.

167

168

Args:

169

bodyUniqueId (int): Object unique ID

170

userDataIndex (int): User data index (0 to getNumUserData-1)

171

physicsClientId (int, optional): Physics client ID

172

173

Returns:

174

tuple: (userDataId, key, bodyUniqueId, linkIndex, visualShapeIndex)

175

"""

176

177

def syncUserData(bodyUniqueIds=None, physicsClientId=0):

178

"""

179

Synchronize user data from server.

180

181

Args:

182

bodyUniqueIds (list, optional): Specific objects to sync

183

physicsClientId (int, optional): Physics client ID

184

"""

185

```

186

187

## Usage Examples

188

189

### State Save and Restore

190

191

```python

192

import pybullet as p

193

import time

194

195

p.connect(p.GUI)

196

p.setGravity(0, 0, -9.81)

197

198

# Set up initial scene

199

p.loadURDF("plane.urdf")

200

cube_id = p.loadURDF("cube_small.urdf", [0, 0, 1])

201

robot_id = p.loadURDF("r2d2.urdf", [1, 0, 1])

202

203

# Simulate for a while

204

for i in range(100):

205

p.stepSimulation()

206

time.sleep(1./240.)

207

208

# Save current state

209

state_id = p.saveState()

210

print(f"Saved state with ID: {state_id}")

211

212

# Continue simulation and make changes

213

p.applyExternalForce(cube_id, -1, [10, 0, 0], [0, 0, 0], p.WORLD_FRAME)

214

for i in range(100):

215

p.stepSimulation()

216

time.sleep(1./240.)

217

218

cube_pos, _ = p.getBasePositionAndOrientation(cube_id)

219

print(f"Cube position after force: {cube_pos}")

220

221

# Restore to saved state

222

p.restoreState(state_id)

223

224

# Verify restoration

225

cube_pos_restored, _ = p.getBasePositionAndOrientation(cube_id)

226

print(f"Cube position after restore: {cube_pos_restored}")

227

228

# Clean up

229

p.removeState(state_id)

230

```

231

232

### File-based State Management

233

234

```python

235

import pybullet as p

236

237

p.connect(p.GUI)

238

p.setGravity(0, 0, -9.81)

239

240

# Create scene

241

plane_id = p.loadURDF("plane.urdf")

242

cube_id = p.loadURDF("cube_small.urdf", [0, 0, 1])

243

244

# Save to file

245

p.saveBullet("my_simulation.bullet")

246

print("Saved simulation to bullet file")

247

248

# Save as Python script (approximate)

249

p.saveWorld("recreate_simulation.py")

250

print("Saved world recreation script")

251

252

# Reset and load from file

253

p.resetSimulation()

254

loaded_objects = p.loadBullet("my_simulation.bullet")

255

print(f"Loaded objects: {loaded_objects}")

256

```

257

258

### Data Logging

259

260

```python

261

import pybullet as p

262

import time

263

264

p.connect(p.GUI)

265

p.setGravity(0, 0, -9.81)

266

267

# Set up scene

268

plane_id = p.loadURDF("plane.urdf")

269

robot_id = p.loadURDF("r2d2.urdf", [0, 0, 1])

270

271

# Start video logging

272

video_log = p.startStateLogging(

273

loggingType=p.STATE_LOGGING_VIDEO_MP4,

274

fileName="simulation_video.mp4"

275

)

276

277

# Start generic robot state logging

278

robot_log = p.startStateLogging(

279

loggingType=p.STATE_LOGGING_GENERIC_ROBOT,

280

fileName="robot_states.txt",

281

objectUniqueIds=[robot_id],

282

maxLogDof=7

283

)

284

285

# Run simulation with logging

286

num_joints = p.getNumJoints(robot_id)

287

joint_indices = list(range(num_joints))

288

289

for step in range(500):

290

# Apply some control

291

if num_joints > 0:

292

target_positions = [0.1 * step * ((-1) ** i) for i in range(num_joints)]

293

p.setJointMotorControlArray(

294

robot_id, joint_indices, p.POSITION_CONTROL,

295

targetPositions=target_positions

296

)

297

298

p.stepSimulation()

299

time.sleep(1./240.)

300

301

# Stop logging

302

p.stopStateLogging(video_log)

303

p.stopStateLogging(robot_log)

304

print("Logging completed")

305

```

306

307

### User Data Management

308

309

```python

310

import pybullet as p

311

312

p.connect(p.GUI)

313

plane_id = p.loadURDF("plane.urdf")

314

robot_id = p.loadURDF("r2d2.urdf", [0, 0, 1])

315

316

# Add user data to robot

317

metadata_id = p.addUserData(robot_id, "robot_type", "R2-D2")

318

config_id = p.addUserData(robot_id, "max_speed", "2.5")

319

author_id = p.addUserData(robot_id, "created_by", "Luke Skywalker")

320

321

# Retrieve user data

322

robot_type = p.getUserData(metadata_id)

323

max_speed = p.getUserData(config_id)

324

print(f"Robot type: {robot_type}, Max speed: {max_speed}")

325

326

# Find user data by key

327

speed_id = p.getUserDataId(robot_id, "max_speed")

328

speed_value = p.getUserData(speed_id)

329

print(f"Found max_speed: {speed_value}")

330

331

# List all user data

332

num_data = p.getNumUserData(robot_id)

333

print(f"Robot has {num_data} user data entries:")

334

335

for i in range(num_data):

336

data_info = p.getUserDataInfo(robot_id, i)

337

data_id, key, body_id, link_idx, shape_idx = data_info

338

value = p.getUserData(data_id)

339

print(f" {key}: {value}")

340

341

# Remove user data

342

p.removeUserData(config_id)

343

print(f"Removed max_speed data, now has {p.getNumUserData(robot_id)} entries")

344

345

# Sync user data (useful in multi-client scenarios)

346

p.syncUserData([robot_id])

347

```

348

349

## Logging Types and Constants

350

351

```python

352

# State logging types

353

p.STATE_LOGGING_VIDEO_MP4 # MP4 video recording

354

p.STATE_LOGGING_GENERIC_ROBOT # Robot state data

355

p.STATE_LOGGING_CONTACT_POINTS # Contact point information

356

p.STATE_LOGGING_VR_CONTROLLERS # VR controller states

357

p.STATE_LOGGING_MINITAUR # Minitaur-specific logging

358

```

359

360

## Best Practices

361

362

1. **Memory Management** - Remove unused saved states to prevent memory leaks

363

2. **File Organization** - Use descriptive names for saved files and organize by experiment

364

3. **Logging Efficiency** - Only log necessary data to minimize file sizes and performance impact

365

4. **State Validation** - Verify state restoration worked correctly before continuing simulation

366

5. **User Data Structure** - Use consistent key naming conventions for user data

367

6. **Backup Strategy** - Save critical states to files for permanent storage

368

7. **Multi-client Sync** - Use sync functions when multiple clients modify the same simulation