carlosferrazza / humanoid-bench

Other
291 stars 27 forks source link

[Bug] ObservationWrapper.observation_space.proprio_space.shape != v.shape #14

Closed Xianqi-Zhang closed 19 hours ago

Xianqi-Zhang commented 1 week ago

Hi, Thanks for your sharing. I would like to report a bug.

To get visual observation, the parser is set as below.

# * humanoid_bench.test_env.py
parser.add_argument('--obs_wrapper', default='True')
parser.add_argument('--sensors', default='image')
# * Command
python -m humanoid_bench.test_env --env h1hand-kitchen-v0  

Error message:

AssertionError: (139,) != (138,)

I think this is caused by the defination of proprio_space in ObservationWrapper. The dim of proprio returned from get_obs() is 139, but proprio_space.shape is 138. https://github.com/carlosferrazza/humanoid-bench/blob/3951d65bc85e16a562d091a7f4820150c20ed91f/humanoid_bench/wrappers.py#L441-L447 https://github.com/carlosferrazza/humanoid-bench/blob/3951d65bc85e16a562d091a7f4820150c20ed91f/humanoid_bench/wrappers.py#L485-L488

Going further, it's related to the function joint_angles and joint_velocities defined in robots.py. https://github.com/carlosferrazza/humanoid-bench/blob/3951d65bc85e16a562d091a7f4820150c20ed91f/humanoid_bench/robots.py#L39-L46 For a task (.xml in dir assets.tasks), if does not define any freejoints, it works well, but if any freejoints in .xml, it break down. self._env.data.qvel.shape + 1 == self._env.data.qpos.shape If no additional freejoints, self.dof == self._env.data.qpos.shape == self._env.data.qvel.shape + 1 , so joint_angles and joint_velocities return same dimensions, i.e., self.dof - 7 and self.dof - 1 - 6. So shape should be self.dof * 2 - 14. But if has additional freejoints, self.dof < self._env.data.qpos.shape, so joints_angles return's dimension is self.dof-7 and joint_velocities return's dimension is self.dof-6. So shape should be self.dof * 2 - 13.

Possible solution:

  1. Directly change joint_velocities(), self.dof -> self.dof - 1

    def joint_velocities(self):
        """Returns the joint velocities."""
        return self._env.data.qvel[6: self.dof-1].copy()
  2. Or you can set different shape for different tasks.

    class ObservationWrapper(BaseWrapper):
    def __init__(self, task, **kwargs):
        super().__init__(task)
        ...
    
        task_name = {
            'HighBarSimple', 'HighBarHard', 'Maze', 'Pole', 'Reach',
            # * Locomotion.
            'Walk', 'Stand', 'Run', 'Crawl', 'ClimbingUpwards', 'Stair', 'Slide',
            'Hurdle', 'Sit', 'SitHard'
        }
        if task.__class__.__name__ in task_name:
            self.proprio_space_shape = (self.task._env.robot.dof * 2 - 1 - 13,)
        else:
            self.proprio_space_shape = (self.task._env.robot.dof * 2 - 13,)
    
    @property
    def observation_space(self):
        proprio_space = Box(
            low=-np.inf,
            high=np.inf,
            shape=self.proprio_space_shape,
            dtype=np.float64,
        )

For tasks have additional freejoints:

basketball
bookshelf
cabinet
cube
door
insert
kitchen
package
powerlift
push
room
spoon
trunk
window

For envs that do not have freejoints:

highbar
maze
pole
reach
locomotions

Best regards.


P.S. It would be better if the author add more comments or supplement some documentation.

carlosferrazza commented 2 days ago

This should be solved with the new updates too, could you confirm whether that is the case? Thanks!

Xianqi-Zhang commented 21 hours ago

Hi, Thanks for your reply. I noticed that joint_velocities() has changed and this problem has been solved. https://github.com/carlosferrazza/humanoid-bench/blob/b917f7aa0890682e98ba5aa3f635fcd781d84936/humanoid_bench/robots.py#L46

But it seems there is another bug need to fix. Test code:

# * test_env.py
    parser.add_argument('--obs_wrapper', default='True')
    parser.add_argument('--sensors', default='image')

Command: python -m humanoid_bench.test_env --env h1hand-kitchen-v0

Error:

  File "/media/zhangxq/Data/ing/humanoid-bench-main/humanoid_bench/env.py", line 211, in __init__
    assert self.robot.dof + self.task.dof == len(data.qpos), (
AssertionError: (76, 0, 97)

I think this is because you delated self.dof = task.dof in BaseWrapper.__init__(), so the task.dof is Task.dof = 0 due to the inheritance ObservationWrapper -> BaseWrapper -> Task.

Best regards.

Xianqi-Zhang commented 21 hours ago

Hi, A small advice is that some code may be shorter, since the maximum number of characters per line in Python is 79, or 99 if agreed by the team, e.g., https://github.com/carlosferrazza/humanoid-bench/blob/b917f7aa0890682e98ba5aa3f635fcd781d84936/humanoid_bench/wrappers.py#L84

        assert task.unwrapped.robot.__class__.__name__ in {"H1Hand", "H1", "H1Touch"}, \
            "DoubleReachWrapper only works with H1 robot"

And I would be grateful if you could add more code comments.

Best regards.

carlosferrazza commented 19 hours ago

Hi, Thanks for your reply. I noticed that joint_velocities() has changed and this problem has been solved.

https://github.com/carlosferrazza/humanoid-bench/blob/b917f7aa0890682e98ba5aa3f635fcd781d84936/humanoid_bench/robots.py#L46

But it seems there is another bug need to fix. Test code:

# * test_env.py
    parser.add_argument('--obs_wrapper', default='True')
    parser.add_argument('--sensors', default='image')

Command: python -m humanoid_bench.test_env --env h1hand-kitchen-v0

Error:

  File "/media/zhangxq/Data/ing/humanoid-bench-main/humanoid_bench/env.py", line 211, in __init__
    assert self.robot.dof + self.task.dof == len(data.qpos), (
AssertionError: (76, 0, 97)

I think this is because you delated self.dof = task.dof in BaseWrapper.__init__(), so the task.dof is Task.dof = 0 due to the inheritance ObservationWrapper -> BaseWrapper -> Task.

Best regards.

Good catch, I hadn't properly pushed last commit!