code: def run(self):
      observation = self.env.reset(project=False, stage=args.stage)
      reward = 0
      done = False
      info = {"shaping_reward": 0.0}
      info["first"] = True
      with grpc.insecure_channel(self.address) as channel:
          stub = simulator_pb2_grpc.SimulatorStub(channel)
          while True:
              response = stub.Send(
                  simulator_pb2.Request(
                      observation=observation,
                      reward=reward,
                      done=done,
                      info=json.dumps(info),
                      id=self.worker_id,
                  )
              )
  
              extra = json.loads(response.extra)
  
              if "reset" in extra and extra["reset"]:
                  logger.info("Server require to reset!")
                  observation = self.env.reset(
                      project=False, stage=args.stage
                  )
                  reward = 0
                  done = False
                  info = {"shaping_reward": 0.0}
                  continue
  
              if "shutdown" in extra and extra["shutdown"]:
                  break
  
              action = np.array(response.action)
              next_observation, reward, done, info = self.env.step(
                  action, project=False
              )
  
              # debug info
              if args.debug:
                  logger.info(
                      "dim:{} obs:{}   act:{}   reward:{}  done:{}  info:{}".format(
                          len(observation),
                          np.sum(observation),
                          np.sum(action),
                          reward,
                          done,
                          info,
                      )
                  )
              observation = next_observation
              if done:
                  observation = self.env.reset(
                      project=False, stage=args.stage
                  )
  
                  # the last observation should be used to compute append_value in simulator_server
                  info["last_obs"] = next_observation.tolist()
  
file_path: PARL/examples/NeurIPS2018-AI-for-Prosthetics-Challenge/simulator_client.py
imports: import grpc
  import json
  import numpy
  import simulator_pb2
  import simulator_pb2_grpc
  from args import get_client_args
  from env_wrapper import FrameSkip, ActionScale, PelvisBasedObs, MAXTIME_LIMIT, CustomR2Env, RunFastestReward, FixedTargetSpeedReward, Round2Reward
  from osim.env import ProstheticsEnv
  from parl.utils import logger
label_desc: Use image node_id 2 for calling the Worker obj's underlying member method code with example usage: obj.run() without return types