-
Notifications
You must be signed in to change notification settings - Fork 22
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
Major refactoring gymnasium et al #88
Conversation
- Add timer RAM state - Remove deprecated obs visualizations - Add VScode pytest integration - Update engine_mock to use timer - Add timer to wrappers options script
- Remove interface with protobuf and use its native datastructure - Unify 1P and 2P step method - New settings `role` and `n_players` instead of `player` refactoring - Update and refactor episode recording and dataset loading - Implement snake_case for keys and refactor accordingly - Add frame compression (encoding) to episode recording - Align tests with new refactoring for recording - Add tests for examples and dataloader - Add manual test for engine mock, centralize engine mocking, fixed engine mock bug - Update obs wrappers for frame warping, fixed random tests
- Use new gymnasium interface - Update setup.py accordingly: - Remove gym, add gymnasium - Remove setuptools pin - Update version for diambra-engine - Unify observation wrapper frame stack including dilation - Manage random values directly from python - Manage change of options at restart - Refactor tests and examples accordingly
6ad98da
to
b182ccc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, I think this is all in all a big improvement also code quality wise!
One general thing: Dunno how well that is supported with python, but making a interface for the wrapper so you can only pass in classes that have the required methods (e.g step etc) would make this even more robust. This is what chatgpt suggests:
In Python, you can achieve this using abstract base classes (ABCs) provided by the abc
module. The idea is to create an abstract base class that defines the step
method as an abstract method. Then, any concrete class that inherits from this abstract base class must provide an implementation of the step
method.
Here's how you can do it:
- Define the abstract base class:
from abc import ABC, abstractmethod
class StepInterface(ABC):
@abstractmethod
def step(self):
pass
- Create concrete classes that implement the
step
method:
class ClassA(StepInterface):
def step(self):
print("ClassA step")
class ClassB(StepInterface):
def step(self):
print("ClassB step")
If you try to create an instance of a class that inherits from StepInterface
but doesn't implement the step
method, you'll get a TypeError
.
- You can then create a list of these class instances and ensure they all have the
step
method:
objects = [ClassA(), ClassB()]
for obj in objects:
obj.step()
This will ensure that all classes in the list have a step
method. If a class doesn't implement the method, you'll find out when you try to create an instance of the class (not when you try to call the method), which can be a helpful way to catch errors early.
This suggestion is regarding the list of wrappers class to be provided as wrapper setting? If so, I see your point and it is interesting. There is a subtle thing though, in particular you can have different types of wrappers classes you can apply, like Observation Wrappers, Reward Wrappers or the more generic Gym Wrapper. Not all of them have the same method (e.g. the obs wrapper does not have any method of those at all, but only the What I can do though, is to add a sanity check and make sure that all the classes in the list provided by the user are one of the gym wrappers class, what do you thing? |
Now I'm thinking more about this, an wrapper basically wraps the whole env, so it takes an env and returns a new env, right? So we could possibly type additional_wrappers_list with That being said, now I'm wondering why we have additional_wrappers_list at all. Why not create a diambra env and then add a wrapper like this: env = arena.make("doapp"...)
wrapped = Wrapper(env, ...) |
I follow you and I see your points and I understand your question. In fact, it is possible to do exactly what you suggest in your code, applying wrappers after the environment has been created. The use of the See as an example this:
Since SB wraps the env in their own specific wrappers/classes, we want to have a way to insert custom wrappers in addition to the standard ones we provide after we apply ours (i.e. after our It is true that you can build the wrapping sequence for SB on your own, and thus use the wrapping sequence you prefer, but that is considered an advanced use case.
Let me know your thoughts! |
…se keys for ram states, rename wrappers list key
- Acquire engine RAM states refactoring and PB enum usage - Acquire Role as Enum modification - Rework base observation space keeping P1 and P2 as in engine - Use wrapper to add action to obs space - Keep discrete and multi discrete action type in observation space - Optimize actions related wrappers - Add role-relative obs wrapper
c3829da
to
4a3b27a
Compare
32120db
to
b1e24d2
Compare
No description provided.