class_docstr: A wrapper for reward shaping, note this wrapper must be the first wrapper 
class_docstr_tok: ["A","wrapper","for","reward","shaping",",","note","this","wrapper","must","be","the","first","wrapper"]
code: def step(self, action, **kwargs):
      self.step_count += 1
      obs, r, done, info = self.env.step(action, **kwargs)
      info = self.reward_shaping(obs, r, done, action)
      # logger.info('Step {}: target_vel: {}'.format(self.step_count, obs['target_vel']))
      delta = 0
      if self.last_target_vel is not None:
          delta = np.absolute(
              np.array(self.last_target_vel)
              - np.array(obs["target_vel"])
          )
      if (self.last_target_vel is None) or np.all(delta < 1e-5):
          info["target_changed"] = False
      else:
          info["target_changed"] = True
          logger.info(
              "[env_wrapper] target_changed, vx:{}   vz:{}".format(
                  obs["target_vel"][0], obs["target_vel"][2]
              )
          )
          self.last_target_change_step = self.step_count
          self.target_change_times += 1
      info["target_change_times"] = self.target_change_times
      self.last_target_vel = obs["target_vel"]
  
      assert "shaping_reward" in info
      timeout = False
      if self.step_count >= MAXTIME_LIMIT:
          timeout = True
  
      info["timeout"] = timeout
      self.pre_state_desc = obs
      return obs, r, done, info
  
imports: import abc
  import gym
  import math
  import numpy
  import random
  from collections import OrderedDict
  from osim.env import ProstheticsEnv
  from parl.utils import logger
  from tqdm import tqdm
label_desc: Use image node_id 3 for calling the RewardShaping obj's underlying member method code with example usage: obj.step(action) and returns: obs,  r,  done,  info