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

Add keypoints mode, and fix order of operations in add_tee #13

Merged
merged 10 commits into from
Jul 4, 2024

Conversation

alexander-soare
Copy link
Collaborator

@alexander-soare alexander-soare commented Jul 4, 2024

This PR does two mostly disconnected things:

  1. Adds an observation mode where keypoints and agent position are returned, as an alternative to pixels_agent_pos which returns an image and the agent position. This sort of keypoints-only environment allows us to circumvent using image encoders in the policy, which makes for a more agile experimentation setting.

  2. Fixes the order of angle and position setting in add_tee.

You visualize the keypoints with this script:

import cv2
import gymnasium as gym
import numpy as np

import gym_pusht

env = gym.make(
    "gym_pusht/PushT-v0",
    render_mode="rgb_array",
    obs_type="environment_state_agent_pos",
)
observation, info = env.reset()

for _ in range(1000):
    action = env.action_space.sample()
    observation, reward, terminated, truncated, info = env.step(action)
    image = env.render()
    if terminated or truncated:
        observation, info = env.reset()

    for kp in observation["environment_state"].reshape(8, 2):
        kp = np.round(kp / 512 * 680).astype(int)
        cv2.circle(image, tuple(kp), radius=4, color=(0, 0, 255), thickness=-1)
    cv2.imshow("window", image)
    k = cv2.waitKey(100)
    if k == ord("q"):
        break

env.close()

The reason 2 (fix order of ops in add_tee) is here, is because when generating the keypoints-only dataset using this script I found out that the keypoints weren't aligned with the tee. In fact, I also discovered that the reward calculation was incorrect, for the same reason. By switching the order of ops, I was able to rectify both issues.

Comment on lines -485 to +515
body.position = position
body.angle = angle
body.position = position
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Although I have empirically determined that this is correct, I'd much rather understand it and add a comment explaining what's going on before merging this PR.

Copy link
Member

Choose a reason for hiding this comment

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

If I remember correctly, the rotation is made around a point that is different from the one used for the position. Therefore, rotating the object changes its position. Having the code in this order makes more sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Okay. I did some testing and it seemed that setting the position moves the bodies in the object frame, whereas setting the angle rotates the object frame in the world frame (consistent with you explanation). But, it was really weird... because I couldn't always get it to work that way.
I'm not sure I have the appetite to fully resolve this right now though... but if someone else has problems in the future, they will have to figure it out.

@qgallouedec
Copy link
Member

qgallouedec commented Jul 4, 2024

is get_keypoints meant to be accessed outside the env?
Starting from gymnasium 1.0, you'll need to set env.unwrapped.my_func if you want to access a custom method that is part of your env. See https://github.com/Farama-Foundation/Gymnasium/blob/81b87efb9f011e975f3b646bab6b7871c522e15e/gymnasium/core.py#L312
It probably won't affect this PR but good to keep in mind.

@qgallouedec
Copy link
Member

Copy link
Collaborator

@Cadene Cadene left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines +521 to +534
def get_keypoints(block_shapes):
"""Get a (8, 2) numpy array with the T keypoints.

The T is composed of two rectangles each with 4 keypoints.

0───────────1
│ │
3───4───5───2
│ │
│ │
│ │
│ │
7───6
"""
Copy link
Collaborator

Choose a reason for hiding this comment

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

what an artist 🧑‍🎨

@alexander-soare
Copy link
Collaborator Author

is get_keypoints meant to be accessed outside the env? Starting from gymnasium 1.0, you'll need to set env.unwrapped.my_func if you want to access a custom method that is part of your env. See https://github.com/Farama-Foundation/Gymnasium/blob/81b87efb9f011e975f3b646bab6b7871c522e15e/gymnasium/core.py#L312 It probably won't affect this PR but good to keep in mind.

@qgallouedec Thanks. Yeah it is accessed in our dataset conversion script where we have to reconstruct the environment in order to access reward and now the keypoints. Since some prior methods are exposed and accessed for the same reason, I'm happy to leave it out of this PR if you are.

I'd also add a test here: https://github.com/alexander-soare/gym-pusht/blob/9d19f907f2c63328df75850920982be1b0cf7e95/tests/test_env.py#L13

Done.

@qgallouedec
Copy link
Member

Sure! Gym v1 is alpha anyway, we still have plenty of time to migrate

@alexander-soare alexander-soare merged commit ff76b74 into huggingface:main Jul 4, 2024
3 checks passed
@alexander-soare alexander-soare deleted the add_keypoints_mode branch July 4, 2024 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants