text: import os
  import inspect
  currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
  parentdir = os.path.dirname(os.path.dirname(currentdir))
  os.sys.path.insert(0, parentdir)
  
  from pybullet_utils import bullet_client
  from pybullet_envs.examples import panda_sim
  
  
  import time
  
  useGUI = False
  timeStep = 1./60.
  
  # Importing the libraries
  import os
  import time
  import multiprocessing as mp
  from multiprocessing import Process, Pipe
  
  pandaEndEffectorIndex = 11 #8
  pandaNumDofs = 7
  
  
  _RESET = 1
  _CLOSE = 2
  _EXPLORE = 3
  
  
  def ExploreWorker(rank, num_processes, childPipe, args):
    print("hi:",rank, " out of ", num_processes)  
    import pybullet as op1
    import pybullet_data as pd
    logName=""
    p1=0
    n = 0
    space = 2 
    simulations=[]
    sims_per_worker = 10
    
    offsetY = rank*space
    while True:
      n += 1
      try:
        # Only block for short times to have keyboard exceptions be raised.
        if not childPipe.poll(0.0001):
          continue
        message, payload = childPipe.recv()
      except (EOFError, KeyboardInterrupt):
        break
      if message == _RESET:
        if (useGUI):
          p1 = bullet_client.BulletClient(op1.GUI)
        else:
          p1 = bullet_client.BulletClient(op1.DIRECT)
        p1.setTimeStep(timeStep)
        
        p1.setPhysicsEngineParameter(numSolverIterations=8)
        p1.setPhysicsEngineParameter(minimumSolverIslandSize=100)
        p1.configureDebugVisualizer(p1.COV_ENABLE_Y_AXIS_UP,1)
        p1.configureDebugVisualizer(p1.COV_ENABLE_RENDERING,0)
        p1.setAdditionalSearchPath(pd.getDataPath())
        p1.setGravity(0,-9.8,0)
        logName = str("batchsim")+str(rank)
        for j in range (3):
          offsetX = 0#-sims_per_worker/2.0*space
          for i in range (sims_per_worker):
            offset=[offsetX,0, offsetY]
            sim = panda_sim.PandaSim(p1, offset)
            simulations.append(sim)
            offsetX += space 
          offsetY += space 
        childPipe.send(["reset ok"])
        p1.configureDebugVisualizer(p1.COV_ENABLE_RENDERING,1)
        for i in range (100):
          p1.stepSimulation()
        
        logId = p1.startStateLogging(op1.STATE_LOGGING_PROFILE_TIMINGS,logName)
        continue
      if message == _EXPLORE:
        sum_rewards=rank
        
        if useGUI:
          numSteps = int(20000)
        else:
          numSteps = int(5)
        for i in range (numSteps):
          for s in simulations:
            s.step()
          p1.stepSimulation()
        #print("logId=",logId)
        #print("numSteps=",numSteps)
  
        childPipe.send([sum_rewards])
        continue
      if message == _CLOSE:
        p1.stopStateLogging(logId)
        childPipe.send(["close ok"])
        break
    childPipe.close()
    
  
  if __name__ == "__main__":
    mp.freeze_support()
    if useGUI:
      num_processes = 1
    else:
      num_processes = 12
    processes = []
    args=[0]*num_processes
    
    childPipes = []
    parentPipes = []
  
    for pr in range(num_processes):
      parentPipe, childPipe = Pipe()
      parentPipes.append(parentPipe)
      childPipes.append(childPipe)
  
    for rank in range(num_processes):
      p = mp.Process(target=ExploreWorker, args=(rank, num_processes, childPipes[rank],  args))
      p.start()
      processes.append(p)
        
    
    for parentPipe in parentPipes:
      parentPipe.send([_RESET, "blaat"])
    
    positive_rewards = [0]*num_processes
    for k in range(num_processes):
      #print("reset msg=",parentPipes[k].recv()[0])
      msg = parentPipes[k].recv()[0]
    
    for parentPipe in parentPipes:
      parentPipe.send([_EXPLORE, "blaat"])
    
    positive_rewards = [0]*num_processes
    for k in range(num_processes):
      positive_rewards[k] = parentPipes[k].recv()[0]
      #print("positive_rewards=",positive_rewards[k])
  
    
    for parentPipe in parentPipes:
      parentPipe.send([_EXPLORE, "blaat"])
    
    positive_rewards = [0]*num_processes
    for k in range(num_processes):
      positive_rewards[k] = parentPipes[k].recv()[0]
      #print("positive_rewards=",positive_rewards[k])
      msg = positive_rewards[k]
  
    for parentPipe in parentPipes:
      parentPipe.send([_EXPLORE, "blaat"])
    
    positive_rewards = [0]*num_processes
    for k in range(num_processes):
      positive_rewards[k] = parentPipes[k].recv()[0]
      #print("positive_rewards=",positive_rewards[k])
  
    
    for parentPipe in parentPipes:
      parentPipe.send([_CLOSE, "pay2"])
    
    for p in processes:
      p.join()
    
    #now we merge the separate json files into a single one
    fnameout = 'batchsim.json'
    count = 0
    outfile = open(fnameout, "w+")
    outfile.writelines(["{\"traceEvents\":[\n"])
    numFiles = num_processes
    for num in range(numFiles):
      print("num=",num)
      fname = 'batchsim%d_0.json' % (num)
      with open(fname) as infile:
          for line in infile:
            if "pid" in line:
              line = line.replace('\"pid\":1', '\"pid\":'+str(num))
              if num < (numFiles-1) and not "{}}," in line:
                line = line.replace('{}}', '{}},')
                print("line[",count,"]=",line)
              outfile.write(line)
            count += 1
    print ("count=",count)
    outfile.writelines(["],\n"])
    outfile.writelines(["\"displayTimeUnit\": \"ns\"}\n"])
    outfile.close()
  