| import numpy as np |
| from tf_agents.policies import py_policy |
| from tf_agents.trajectories import policy_step |
| from tf_agents.trajectories import time_step as ts |
|
|
|
|
| class SpreadOracle(py_policy.PyPolicy): |
| def __init__(self, env): |
| super(SpreadOracle, self).__init__( |
| env.time_step_spec(), env.action_spec() |
| ) |
| self._env = env |
|
|
| def _action(self, time_step, policy_state=()): |
| obs = time_step.observation |
| |
| other_dist1 = np.linalg.norm(self._env.world.landmarks[0].state.p_pos - obs[2:4]) |
| other_dist2 = np.linalg.norm(self._env.world.landmarks[1].state.p_pos - obs[2:4]) |
| ego_dist1 = np.linalg.norm(self._env.world.landmarks[0].state.p_pos - obs[:2]) |
| ego_dist2 = np.linalg.norm(self._env.world.landmarks[1].state.p_pos - obs[:2]) |
| if ego_dist1 < other_dist1 - 0.1: |
| |
| goal = self._env.world.landmarks[0].state.p_pos |
| elif ego_dist2 < other_dist2 - 0.1: |
| |
| goal = self._env.world.landmarks[1].state.p_pos |
| else: |
| goal = self._env.world.landmarks[1 - self._env.other_agent_idx].state.p_pos |
| action = goal - obs[:2] |
|
|
| |
| other_agent_pos = obs[2:4] |
| delta_pos = other_agent_pos - obs[:2] |
| if np.linalg.norm(delta_pos) < 0.4: |
| |
| |
| action = 0.1 * action - 2 * delta_pos |
|
|
| |
| if np.linalg.norm(action) > 1: |
| action /= np.linalg.norm(action) |
| elif np.linalg.norm(action) < 0.5: |
| action = action / np.linalg.norm(action) * 0.5 |
|
|
| action += np.random.normal(0, 0.1, size=2) |
|
|
| if np.linalg.norm(action) > 1: |
| action /= np.linalg.norm(action) |
| elif np.linalg.norm(action) < 0.5: |
| action = action / np.linalg.norm(action) * 0.5 |
|
|
| return policy_step.PolicyStep(action, policy_state) |
|
|
| def reset(self): |
| pass |
|
|