continual-foragax 0.11.0__py3-none-any.whl → 0.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {continual_foragax-0.11.0.dist-info → continual_foragax-0.13.0.dist-info}/METADATA +1 -1
- {continual_foragax-0.11.0.dist-info → continual_foragax-0.13.0.dist-info}/RECORD +8 -8
- foragax/env.py +38 -7
- foragax/objects.py +12 -3
- foragax/registry.py +36 -1
- {continual_foragax-0.11.0.dist-info → continual_foragax-0.13.0.dist-info}/WHEEL +0 -0
- {continual_foragax-0.11.0.dist-info → continual_foragax-0.13.0.dist-info}/entry_points.txt +0 -0
- {continual_foragax-0.11.0.dist-info → continual_foragax-0.13.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
foragax/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
foragax/colors.py,sha256=rqNPiywP4Nvr0POhsGpasRk-nMMTS3DOwFRUgperlUk,2065
|
3
|
-
foragax/env.py,sha256=
|
4
|
-
foragax/objects.py,sha256
|
5
|
-
foragax/registry.py,sha256=
|
3
|
+
foragax/env.py,sha256=EyT6KY0d0mXNh6yw10V-8SJVAdyPAGKtRdFV4wXq-JM,19836
|
4
|
+
foragax/objects.py,sha256=-XkuZVbbSTFNJ02f6HsH4GbxZ6YrUetiY39r9Zw4UWE,6967
|
5
|
+
foragax/registry.py,sha256=j2-KgcquYePklXMxpmDtGUdbjA6mvAO5XGNcwj0FByA,4486
|
6
6
|
foragax/rendering.py,sha256=bms7wvBZTofoR-K-2QD2Ggeed7Viw8uwAEiEpEM3eSo,2768
|
7
7
|
foragax/weather.py,sha256=KNAiwuFz8V__6G75vZIWQKPocLzXqxXn-Vt4TbHIpcA,1258
|
8
8
|
foragax/data/ECA_non-blended_custom/TG_SOUID100897.txt,sha256=N7URbX6VlCZvCboUogYjMzy1I-0cfNPOn0QTLSHHfQ0,1776751
|
@@ -128,8 +128,8 @@ foragax/data/ECA_non-blended_custom/TG_SOUID156887.txt,sha256=juzTPgJoJxfqmZkorL
|
|
128
128
|
foragax/data/ECA_non-blended_custom/elements.txt,sha256=OtcUBoDAHxuln79BPKGu0tsQxG_5G2BfAX3Ck130kEA,4507
|
129
129
|
foragax/data/ECA_non-blended_custom/metadata.txt,sha256=nudnmOCy5cPJfSXt_IjyX0S5-T7NkCZREICZSimqeqc,48260
|
130
130
|
foragax/data/ECA_non-blended_custom/sources.txt,sha256=1j3lSmINAoCMqPqFrHfZJriOz6sTYZNOhXzUwvTLas0,20857
|
131
|
-
continual_foragax-0.
|
132
|
-
continual_foragax-0.
|
133
|
-
continual_foragax-0.
|
134
|
-
continual_foragax-0.
|
135
|
-
continual_foragax-0.
|
131
|
+
continual_foragax-0.13.0.dist-info/METADATA,sha256=L_kwRE8vRK-qfcH5AyrS3U_Rz_LZqM3svgC7ojGA738,4897
|
132
|
+
continual_foragax-0.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
133
|
+
continual_foragax-0.13.0.dist-info/entry_points.txt,sha256=Qiu6iE_XudrDO_bVAMeA435h4PO9ourt8huvSHiuMPc,41
|
134
|
+
continual_foragax-0.13.0.dist-info/top_level.txt,sha256=-z3SDK6RfLIcLI24n8rdbeFzlVY3hunChzlu-v1Fncs,8
|
135
|
+
continual_foragax-0.13.0.dist-info/RECORD,,
|
foragax/env.py
CHANGED
@@ -13,7 +13,13 @@ import jax.numpy as jnp
|
|
13
13
|
from flax import struct
|
14
14
|
from gymnax.environments import environment, spaces
|
15
15
|
|
16
|
-
from foragax.objects import
|
16
|
+
from foragax.objects import (
|
17
|
+
AGENT,
|
18
|
+
EMPTY,
|
19
|
+
PADDING,
|
20
|
+
BaseForagaxObject,
|
21
|
+
WeatherObject,
|
22
|
+
)
|
17
23
|
from foragax.rendering import apply_true_borders
|
18
24
|
from foragax.weather import get_temperature
|
19
25
|
|
@@ -64,6 +70,7 @@ class ForagaxEnv(environment.Environment):
|
|
64
70
|
aperture_size: Union[Tuple[int, int], int] = (5, 5),
|
65
71
|
objects: Tuple[BaseForagaxObject, ...] = (),
|
66
72
|
biomes: Tuple[Biome, ...] = (Biome(object_frequencies=()),),
|
73
|
+
nowrap: bool = False,
|
67
74
|
):
|
68
75
|
super().__init__()
|
69
76
|
if isinstance(size, int):
|
@@ -73,7 +80,10 @@ class ForagaxEnv(environment.Environment):
|
|
73
80
|
if isinstance(aperture_size, int):
|
74
81
|
aperture_size = (aperture_size, aperture_size)
|
75
82
|
self.aperture_size = aperture_size
|
83
|
+
self.nowrap = nowrap
|
76
84
|
objects = (EMPTY,) + objects
|
85
|
+
if self.nowrap:
|
86
|
+
objects = objects + (PADDING,)
|
77
87
|
self.objects = objects
|
78
88
|
self.weather_object = None
|
79
89
|
for o in objects:
|
@@ -122,8 +132,12 @@ class ForagaxEnv(environment.Environment):
|
|
122
132
|
direction = DIRECTIONS[action]
|
123
133
|
new_pos = state.pos + direction
|
124
134
|
|
125
|
-
|
126
|
-
|
135
|
+
if self.nowrap:
|
136
|
+
in_bounds = jnp.all((new_pos >= 0) & (new_pos < jnp.array(self.size)))
|
137
|
+
new_pos = jnp.where(in_bounds, new_pos, state.pos)
|
138
|
+
else:
|
139
|
+
# Wrap around boundaries
|
140
|
+
new_pos = jnp.mod(new_pos, jnp.array(self.size))
|
127
141
|
|
128
142
|
# Check for blocking objects
|
129
143
|
obj_at_new_pos = current_objects[new_pos[1], new_pos[0]]
|
@@ -288,10 +302,26 @@ class ForagaxEnv(environment.Environment):
|
|
288
302
|
|
289
303
|
y_offsets = jnp.arange(ap_h)
|
290
304
|
x_offsets = jnp.arange(ap_w)
|
291
|
-
y_coords =
|
292
|
-
x_coords =
|
305
|
+
y_coords = start_y + y_offsets[:, None]
|
306
|
+
x_coords = start_x + x_offsets
|
307
|
+
|
308
|
+
if self.nowrap:
|
309
|
+
# Clamp coordinates to bounds
|
310
|
+
y_coords_clamped = jnp.clip(y_coords, 0, self.size[1] - 1)
|
311
|
+
x_coords_clamped = jnp.clip(x_coords, 0, self.size[0] - 1)
|
312
|
+
values = object_grid[y_coords_clamped, x_coords_clamped]
|
313
|
+
# Mark out-of-bounds positions with -1
|
314
|
+
y_out = (y_coords < 0) | (y_coords >= self.size[1])
|
315
|
+
x_out = (x_coords < 0) | (x_coords >= self.size[0])
|
316
|
+
out_of_bounds = y_out | x_out
|
317
|
+
padding_index = self.object_ids[-1]
|
318
|
+
aperture = jnp.where(out_of_bounds, padding_index, values)
|
319
|
+
else:
|
320
|
+
y_coords_mod = jnp.mod(y_coords, self.size[1])
|
321
|
+
x_coords_mod = jnp.mod(x_coords, self.size[0])
|
322
|
+
aperture = object_grid[y_coords_mod, x_coords_mod]
|
293
323
|
|
294
|
-
return
|
324
|
+
return aperture
|
295
325
|
|
296
326
|
@partial(jax.jit, static_argnames=("self", "render_mode"))
|
297
327
|
def render(self, state: EnvState, params: EnvParams, render_mode: str = "world"):
|
@@ -404,8 +434,9 @@ class ForagaxObjectEnv(ForagaxEnv):
|
|
404
434
|
aperture_size: Union[Tuple[int, int], int] = (5, 5),
|
405
435
|
objects: Tuple[BaseForagaxObject, ...] = (),
|
406
436
|
biomes: Tuple[Biome, ...] = (Biome(object_frequencies=()),),
|
437
|
+
nowrap: bool = False,
|
407
438
|
):
|
408
|
-
super().__init__(size, aperture_size, objects, biomes)
|
439
|
+
super().__init__(size, aperture_size, objects, biomes, nowrap)
|
409
440
|
|
410
441
|
# Compute unique colors and mapping for partial observability
|
411
442
|
# Exclude EMPTY (index 0) from color channels
|
foragax/objects.py
CHANGED
@@ -179,6 +179,8 @@ DEATHCAP = DefaultForagaxObject(
|
|
179
179
|
)
|
180
180
|
AGENT = DefaultForagaxObject(name="agent", blocking=True, color=(0, 0, 255))
|
181
181
|
|
182
|
+
PADDING = DefaultForagaxObject(name="padding", blocking=True, color=(0, 0, 0))
|
183
|
+
|
182
184
|
BROWN_MOREL = NormalRegenForagaxObject(
|
183
185
|
name="brown_morel",
|
184
186
|
reward=30.0,
|
@@ -212,7 +214,10 @@ GREEN_FAKE = DefaultForagaxObject(
|
|
212
214
|
|
213
215
|
|
214
216
|
def create_weather_objects(
|
215
|
-
file_index: int = 0,
|
217
|
+
file_index: int = 0,
|
218
|
+
repeat: int = 500,
|
219
|
+
multiplier: float = 1.0,
|
220
|
+
same_color: bool = False,
|
216
221
|
):
|
217
222
|
"""Create HOT and COLD WeatherObject instances using the specified file.
|
218
223
|
|
@@ -220,6 +225,7 @@ def create_weather_objects(
|
|
220
225
|
file_index: Index into `FILE_PATHS` to select the temperature file.
|
221
226
|
repeat: How many steps each temperature value repeats for.
|
222
227
|
multiplier: Base multiplier applied to HOT; COLD will use -multiplier.
|
228
|
+
same_color: If True, both HOT and COLD use the same color.
|
223
229
|
|
224
230
|
Returns:
|
225
231
|
A tuple (HOT, COLD) of WeatherObject instances.
|
@@ -232,20 +238,23 @@ def create_weather_objects(
|
|
232
238
|
|
233
239
|
rewards = load_data(FILE_PATHS[file_index])
|
234
240
|
|
241
|
+
hot_color = (63, 30, 25) if same_color else (255, 0, 255)
|
242
|
+
|
235
243
|
hot = WeatherObject(
|
236
244
|
name="hot",
|
237
245
|
rewards=rewards,
|
238
246
|
repeat=repeat,
|
239
247
|
multiplier=multiplier,
|
240
|
-
color=
|
248
|
+
color=hot_color,
|
241
249
|
)
|
242
250
|
|
251
|
+
cold_color = hot_color if same_color else (0, 255, 255)
|
243
252
|
cold = WeatherObject(
|
244
253
|
name="cold",
|
245
254
|
rewards=rewards,
|
246
255
|
repeat=repeat,
|
247
256
|
multiplier=-multiplier,
|
248
|
-
color=
|
257
|
+
color=cold_color,
|
249
258
|
)
|
250
259
|
|
251
260
|
return hot, cold
|
foragax/registry.py
CHANGED
@@ -31,6 +31,19 @@ ENV_CONFIGS: Dict[str, Dict[str, Any]] = {
|
|
31
31
|
# Cold biome
|
32
32
|
Biome(start=(0, 10), stop=(15, 12), object_frequencies=(0.0, 0.5)),
|
33
33
|
),
|
34
|
+
"nowrap": False,
|
35
|
+
},
|
36
|
+
"ForagaxWeather-v2": {
|
37
|
+
"size": (15, 15),
|
38
|
+
"aperture_size": None,
|
39
|
+
"objects": None,
|
40
|
+
"biomes": (
|
41
|
+
# Hot biome
|
42
|
+
Biome(start=(0, 3), stop=(15, 5), object_frequencies=(0.5, 0.0)),
|
43
|
+
# Cold biome
|
44
|
+
Biome(start=(0, 10), stop=(15, 12), object_frequencies=(0.0, 0.5)),
|
45
|
+
),
|
46
|
+
"nowrap": True,
|
34
47
|
},
|
35
48
|
"ForagaxTwoBiome-v1": {
|
36
49
|
"size": (15, 15),
|
@@ -44,6 +57,7 @@ ENV_CONFIGS: Dict[str, Dict[str, Any]] = {
|
|
44
57
|
start=(10, 0), stop=(12, 15), object_frequencies=(0.0, 0.5, 0.0, 0.25)
|
45
58
|
),
|
46
59
|
),
|
60
|
+
"nowrap": False,
|
47
61
|
},
|
48
62
|
"ForagaxTwoBiomeSmall-v1": {
|
49
63
|
"size": (16, 8),
|
@@ -55,6 +69,7 @@ ENV_CONFIGS: Dict[str, Dict[str, Any]] = {
|
|
55
69
|
# Oyster biome
|
56
70
|
Biome(start=(10, 2), stop=(14, 6), object_frequencies=(0.0, 1.0)),
|
57
71
|
),
|
72
|
+
"nowrap": False,
|
58
73
|
},
|
59
74
|
"ForagaxTwoBiomeSmall-v2": {
|
60
75
|
"size": (16, 8),
|
@@ -66,6 +81,19 @@ ENV_CONFIGS: Dict[str, Dict[str, Any]] = {
|
|
66
81
|
# Oyster biome
|
67
82
|
Biome(start=(11, 3), stop=(14, 6), object_frequencies=(0.0, 1.0)),
|
68
83
|
),
|
84
|
+
"nowrap": False,
|
85
|
+
},
|
86
|
+
"ForagaxTwoBiomeSmall-v3": {
|
87
|
+
"size": (16, 8),
|
88
|
+
"aperture_size": None,
|
89
|
+
"objects": (MEDIUM_MOREL, LARGE_OYSTER),
|
90
|
+
"biomes": (
|
91
|
+
# Morel biome
|
92
|
+
Biome(start=(3, 3), stop=(6, 6), object_frequencies=(1.0, 0.0)),
|
93
|
+
# Oyster biome
|
94
|
+
Biome(start=(11, 3), stop=(14, 6), object_frequencies=(0.0, 1.0)),
|
95
|
+
),
|
96
|
+
"nowrap": True,
|
69
97
|
},
|
70
98
|
}
|
71
99
|
|
@@ -75,6 +103,7 @@ def make(
|
|
75
103
|
observation_type: str = "object",
|
76
104
|
aperture_size: Optional[Tuple[int, int]] = (5, 5),
|
77
105
|
file_index: int = 0,
|
106
|
+
nowrap: Optional[bool] = None,
|
78
107
|
) -> ForagaxEnv:
|
79
108
|
"""Create a Foragax environment.
|
80
109
|
|
@@ -83,6 +112,9 @@ def make(
|
|
83
112
|
observation_type: The type of observation to use. One of "object", "rgb", or "world".
|
84
113
|
aperture_size: The size of the agent's observation aperture. If None, the default
|
85
114
|
for the environment is used.
|
115
|
+
file_index: File index for weather objects. nowrap: If True, disables
|
116
|
+
wrapping around environment boundaries. If None, uses defaults per
|
117
|
+
environment.
|
86
118
|
|
87
119
|
Returns:
|
88
120
|
A Foragax environment instance.
|
@@ -93,9 +125,12 @@ def make(
|
|
93
125
|
config = ENV_CONFIGS[env_id].copy()
|
94
126
|
|
95
127
|
config["aperture_size"] = aperture_size
|
128
|
+
if nowrap is not None:
|
129
|
+
config["nowrap"] = nowrap
|
96
130
|
|
97
131
|
if env_id.startswith("ForagaxWeather"):
|
98
|
-
|
132
|
+
same_color = env_id == "ForagaxWeather-v2"
|
133
|
+
hot, cold = create_weather_objects(file_index=file_index, same_color=same_color)
|
99
134
|
config["objects"] = (hot, cold)
|
100
135
|
|
101
136
|
env_class_map = {
|
File without changes
|
File without changes
|
File without changes
|