Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gala_kinematic] non-visual observations #838

57 changes: 50 additions & 7 deletions habitat/core/batched_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ def __init__(

include_depth = "DEPTH_SENSOR" in config.SENSORS
include_rgb = "RGB_SENSOR" in config.SENSORS

self.include_point_goal_gps_compass = "POINTGOAL_WITH_GPS_COMPASS_SENSOR" in config.SENSORS
# This key is a hard_coded_string. Will not work with any value:
# see this line : https://github.com/eundersander/habitat-lab/blob/eundersander/gala_kinematic/habitat_baselines/rl/ppo/policy.py#L206
self.gps_compass_key = "pointgoal_with_gps_compass"
gps_compass_sensor_shape= 4
self.include_ee_pos = "EE_POS_SENSOR" in config.SENSORS
self.ee_pos_key = "ee_pos"
ee_pos_shape = 3


assert include_depth or include_rgb

self._num_envs = config.NUM_ENVIRONMENTS
Expand All @@ -72,7 +83,7 @@ def __init__(
bsim_config.sensor0.width = sensor_width
bsim_config.sensor0.height = sensor_height
bsim_config.sensor0.hfov = 60.0
bsim_config.force_random_actions = True
bsim_config.force_random_actions = False
bsim_config.do_async_physics_step = self._config.OVERLAP_PHYSICS
bsim_config.num_physics_substeps = self._config.NUM_PHYSICS_SUBSTEPS
bsim_config.do_procedural_episode_set = True
Expand Down Expand Up @@ -107,10 +118,13 @@ def __init__(
else:
observations["rgb"] = torch.rand([self._num_envs, sensor_height, sensor_width, 3], dtype=torch.float32) * 255
observations["depth"] = torch.rand([self._num_envs, sensor_height, sensor_width, 1], dtype=torch.float32) * 255
if self.include_point_goal_gps_compass:
observations[self.gps_compass_key] = torch.empty([self._num_envs, gps_compass_sensor_shape], dtype=torch.float32)
if self.include_ee_pos:
observations[self.ee_pos_key] = torch.empty([self._num_envs, ee_pos_shape], dtype=torch.float32)

self._observations = observations

# print('observations["rgb"].shape: ', observations["rgb"].shape)

self._is_closed = False

num_other_actions = 1 # doAttemptGrip/doAttemptDrop
Expand Down Expand Up @@ -145,6 +159,20 @@ def __init__(
dtype=np.float32,
)
obs_dict["depth"] = depth_obs
if self.include_point_goal_gps_compass:
obs_dict[self.gps_compass_key] = spaces.Box(
low=-np.inf,
high=np.inf, # todo: investigate depth min/max
shape=(gps_compass_sensor_shape,),
dtype=np.float32,
)
if self.include_ee_pos:
obs_dict[self.ee_pos_key] = spaces.Box(
low=-np.inf,
high=np.inf, # todo: investigate depth min/max
shape=(ee_pos_shape,),
dtype=np.float32,
)

self.observation_spaces = [obs_dict] * 1 # config.NUM_ENVIRONMENTS # note we only ever read element #0 of this array

Expand All @@ -157,6 +185,7 @@ def __init__(
# self.number_of_episodes = []
self._paused: List[int] = []


@property
def num_envs(self):
r"""number of individual environments."""
Expand Down Expand Up @@ -184,10 +213,20 @@ def get_metrics(self):
return results

def get_nonpixel_observations(self, env_states, observations):
for state in env_states:
robot_pos = state.robot_position
robot_yaw = state.robot_yaw
# todo: update observations here
# TODO: update observations here
for (b, state) in enumerate(env_states):
if self.include_point_goal_gps_compass:
robot_pos = state.robot_position
robot_yaw = state.robot_yaw

observations[self.gps_compass_key] [b, 0] = robot_pos[0]
observations[self.gps_compass_key] [b, 1] = robot_pos[1]
observations[self.gps_compass_key] [b, 2] = robot_pos[2]
observations[self.gps_compass_key] [b, 3] = robot_yaw
if self.include_ee_pos:
for i in range(3):
observations[self.ee_pos_key][b, i] = state.ee_pos[i]



def get_dones_rewards_resets(self, env_states, actions):
Expand Down Expand Up @@ -236,8 +275,11 @@ def async_step(
self._bsim.wait_step_physics_or_reset()
self._bsim.start_render()
env_states = self._bsim.get_environment_states()

self.get_nonpixel_observations(env_states, self._observations)
self.get_dones_rewards_resets(env_states, actions_flat_list)
self._bsim.start_step_physics_or_reset(actions_flat_list, self.resets)

else:
# note: this path is untested
self._bsim.start_step_physics_or_reset(actions_flat_list, self.resets)
Expand All @@ -256,6 +298,7 @@ def wait_step(self) -> List[Any]:
# perf todo: ensure we're getting here before rendering finishes (issue a warning otherwise)
self._bsim.wait_render()


# these are "one frame behind" like the observations (i.e. computed from
# the same earlier env state).
rewards = self.rewards
Expand Down
2 changes: 1 addition & 1 deletion habitat_baselines/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
_C.RL.POLICY.action_distribution_type = "categorical" # or 'gaussian'
# For gaussian action distribution:
_C.RL.POLICY.ACTION_DIST = CN()
_C.RL.POLICY.ACTION_DIST.use_log_std = False
_C.RL.POLICY.ACTION_DIST.use_log_std = True
_C.RL.POLICY.ACTION_DIST.use_softplus = False
_C.RL.POLICY.ACTION_DIST.min_std = 1e-6
_C.RL.POLICY.ACTION_DIST.max_std = 1
Expand Down
2 changes: 1 addition & 1 deletion habitat_baselines/config/rearrange/gala_kinematic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ NUM_PHYSICS_SUBSTEPS: 1
SAVE_VIDEOS_INTERVAL: -1
NUM_UPDATES: 60
NUM_ENVIRONMENTS: 512
SENSORS: ["DEPTH_SENSOR", "RGB_SENSOR"]
# SENSORS: ["DEPTH_SENSOR", "RGB_SENSOR", "POINTGOAL_WITH_GPS_COMPASS_SENSOR"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed since it is in habitat_baselines/config/rearrange/gala_kinematic_ddppo.yaml

SIMULATOR:
AGENTS: ['AGENT_0']
AGENT_0:
Expand Down
3 changes: 2 additions & 1 deletion habitat_baselines/config/rearrange/gala_kinematic_ddppo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ NUM_CHECKPOINTS: 0
BATCHED_ENV: True
OVERLAP_PHYSICS: True
SAVE_VIDEOS_INTERVAL: 500
NUM_UPDATES: 61
NUM_UPDATES: 6100
NUM_ENVIRONMENTS: 512
SENSORS: ["DEPTH_SENSOR", "RGB_SENSOR", "POINTGOAL_WITH_GPS_COMPASS_SENSOR", "EE_POS_SENSOR"]
SIMULATOR:
AGENTS: ['AGENT_0']
AGENT_0:
Expand Down
93 changes: 54 additions & 39 deletions habitat_baselines/rl/ppo/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
import abc
from re import X

import torch
from gym import spaces
Expand Down Expand Up @@ -202,34 +203,41 @@ def __init__(
):
super().__init__()

if (
IntegratedPointGoalGPSAndCompassSensor.cls_uuid
in observation_space.spaces
):
self._n_input_goal = observation_space.spaces[
IntegratedPointGoalGPSAndCompassSensor.cls_uuid
].shape[0]
elif PointGoalSensor.cls_uuid in observation_space.spaces:
self._n_input_goal = observation_space.spaces[
PointGoalSensor.cls_uuid
].shape[0]
elif ImageGoalSensor.cls_uuid in observation_space.spaces:
goal_observation_space = spaces.Dict(
{"rgb": observation_space.spaces[ImageGoalSensor.cls_uuid]}
)
self.goal_visual_encoder = SimpleCNN(
goal_observation_space, hidden_size
)
self._n_input_goal = hidden_size
else:
self._n_input_goal = 0
#### [gala_kinematic] Manually adding sensors in there
self.observation_space = observation_space
self._n_state = 0
if "pointgoal_with_gps_compass" in self.observation_space.spaces:
self._n_state += 4
if "ee_pos" in self.observation_space.spaces:
self._n_state += 3

# if (
# IntegratedPointGoalGPSAndCompassSensor.cls_uuid
# in observation_space.spaces
# ):
# self._n_input_goal = observation_space.spaces[
# IntegratedPointGoalGPSAndCompassSensor.cls_uuid
# ].shape[0]
# elif PointGoalSensor.cls_uuid in observation_space.spaces:
# self._n_input_goal = observation_space.spaces[
# PointGoalSensor.cls_uuid
# ].shape[0]
# elif ImageGoalSensor.cls_uuid in observation_space.spaces:
# goal_observation_space = spaces.Dict(
# {"rgb": observation_space.spaces[ImageGoalSensor.cls_uuid]}
# )
# self.goal_visual_encoder = SimpleCNN(
# goal_observation_space, hidden_size
# )
# self._n_input_goal = hidden_size
#### [gala_kinematic] End of manually adding sensors in there

self._hidden_size = hidden_size

self.visual_encoder = SimpleCNN(observation_space, hidden_size)

self.state_encoder = build_rnn_state_encoder(
(0 if self.is_blind else self._hidden_size) + self._n_input_goal,
(0 if self.is_blind else self._hidden_size) + self._n_state,
self._hidden_size,
)

Expand All @@ -248,24 +256,31 @@ def num_recurrent_layers(self):
return self.state_encoder.num_recurrent_layers

def forward(self, observations, rnn_hidden_states, prev_actions, masks):
if IntegratedPointGoalGPSAndCompassSensor.cls_uuid in observations:
target_encoding = observations[
IntegratedPointGoalGPSAndCompassSensor.cls_uuid
]

elif PointGoalSensor.cls_uuid in observations:
target_encoding = observations[PointGoalSensor.cls_uuid]
elif ImageGoalSensor.cls_uuid in observations:
image_goal = observations[ImageGoalSensor.cls_uuid]
target_encoding = self.goal_visual_encoder({"rgb": image_goal})
else:
target_encoding = None
#### [gala_kinematic] Manually adding sensors in there
x = [self.visual_encoder(observations)]
if "pointgoal_with_gps_compass" in self.observation_space.spaces:
x += [observations["pointgoal_with_gps_compass"]]
if "ee_pos" in self.observation_space.spaces:
x += [observations["ee_pos"]]
# if IntegratedPointGoalGPSAndCompassSensor.cls_uuid in observations:
# target_encoding = observations[
# IntegratedPointGoalGPSAndCompassSensor.cls_uuid
# ]

# elif PointGoalSensor.cls_uuid in observations:
# target_encoding = observations[PointGoalSensor.cls_uuid]
# elif ImageGoalSensor.cls_uuid in observations:
# image_goal = observations[ImageGoalSensor.cls_uuid]
# target_encoding = self.goal_visual_encoder({"rgb": image_goal})
# else:
# target_encoding = None
# if not self.is_blind:
# perception_embed = self.visual_encoder(observations)
# x = [perception_embed]
# if target_encoding is not None:
# x += [target_encoding]
#### [gala_kinematic] End of manually adding sensors in there

if not self.is_blind:
perception_embed = self.visual_encoder(observations)
x = [perception_embed]
if target_encoding:
x += [target_encoding]

x_out = torch.cat(x, dim=1)
x_out, rnn_hidden_states = self.state_encoder(
Expand Down