Skip to content

Commit f3e5ba7

Browse files
committed
Fix MarlGrid matrix observation contract
1 parent be83e2b commit f3e5ba7

7 files changed

Lines changed: 260 additions & 272 deletions

File tree

.dockerignore

Lines changed: 0 additions & 151 deletions
This file was deleted.

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.gitignore

docs/env/marlgrid.rst

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,40 @@ Options
3434
* ``prestige_beta (float)``: per-step prestige decay factor, default to
3535
``0.95``;
3636
* ``prestige_scale (float)``: reward-history scale used when mapping prestige
37-
to color, default to ``2.0``.
37+
to color, default to ``2.0``;
38+
* ``observation_format (str)``: observation representation. ``"pixels"``
39+
(default) returns the existing RGB partial view, ``"matrix"`` returns an
40+
egocentric semantic partial view, and ``"full_matrix"`` returns the
41+
world-oriented semantic grid.
3842

3943

4044
Observation Space
4145
-----------------
4246

43-
MarlGrid returns one RGB partial-view image per player. The default registered
44-
tasks use ``view_tile_size=8`` and expose ``obs`` as a uint8 tensor with shape
45-
``(view_tile_size * view_size, view_tile_size * view_size, 3)`` per player.
47+
MarlGrid returns one uint8 observation per player. Its shape depends on
48+
``observation_format``:
49+
50+
* ``pixels``: ``(view_tile_size * view_size, view_tile_size * view_size, 3)``.
51+
This is the existing RGB partial view. The default registered tasks use
52+
``view_tile_size=8``;
53+
* ``matrix``: ``(view_size, view_size, 13)``. This is the agent's egocentric
54+
partial view. Occluded cells and every cell for an inactive player are all
55+
zero;
56+
* ``full_matrix``: ``(grid_size, grid_size, 13)``. This is the global grid in
57+
world coordinates. Every cell for an inactive player is zero.
58+
59+
For both matrix formats, channels are:
60+
61+
* ``0``--``4``: one-hot empty, wall, goal, bonus, and lava base tiles;
62+
* ``5``: agent presence;
63+
* ``6``--``8``: agent red, green, and blue values. These contain the prestige
64+
color when ``prestige_coloring=True``;
65+
* ``9``--``12``: one-hot agent direction: right, down, left, and up.
66+
67+
One visible base-tile channel and every active one-hot channel use value
68+
``255``. An agent can occupy a base object, so base-tile and agent channels may
69+
both be set. Directions in ``matrix`` use the rotated egocentric coordinates;
70+
directions in ``full_matrix`` use world coordinates.
4671

4772
Player metadata is returned under ``info["players"]``:
4873

envpool/marlgrid/marlgrid.h

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,17 @@ enum class MatrixObsChannel : std::uint8_t {
7272
kAgentRed = 6,
7373
kAgentGreen = 7,
7474
kAgentBlue = 8,
75+
kAgentDirRight = 9,
76+
kAgentDirDown = 10,
77+
kAgentDirLeft = 11,
78+
kAgentDirUp = 12,
7579
};
7680

7781
using Rgb = std::array<std::uint8_t, 3>;
7882

7983
inline constexpr int kTilePixels = 32;
8084
inline constexpr int kTileSubdivs = 3;
81-
inline constexpr int kMatrixObsChannels = 9;
85+
inline constexpr int kMatrixObsChannels = 13;
8286
inline constexpr double kPi = 3.14159265358979323846;
8387
inline constexpr Rgb kShadowColor = {35, 25, 30};
8488
inline constexpr Rgb kWorstColor = {74, 65, 42};
@@ -402,16 +406,15 @@ class MarlGridEnvFns {
402406
"MarlGrid observation_format must be 'pixels', 'matrix', or "
403407
"'full_matrix'");
404408
}
405-
const bool matrix_observation = observation_format == "matrix";
406-
const bool full_matrix_observation = observation_format == "full_matrix";
407-
int obs_size = full_matrix_observation
408-
? conf["grid_size"_]
409-
: (matrix_observation
410-
? conf["view_size"_]
411-
: conf["view_size"_] * conf["view_tile_size"_]);
412-
int obs_channels = (matrix_observation || full_matrix_observation)
413-
? detail::kMatrixObsChannels
414-
: 3;
409+
int obs_size = conf["view_size"_] * conf["view_tile_size"_];
410+
int obs_channels = 3;
411+
if (observation_format == "matrix") {
412+
obs_size = conf["view_size"_];
413+
obs_channels = detail::kMatrixObsChannels;
414+
} else if (observation_format == "full_matrix") {
415+
obs_size = conf["grid_size"_];
416+
obs_channels = detail::kMatrixObsChannels;
417+
}
415418
int bound = conf["grid_size"_];
416419
return MakeDict(
417420
"obs"_.Bind(Spec<std::uint8_t>({-1, obs_size, obs_size, obs_channels},
@@ -1018,7 +1021,7 @@ class MarlGridEnv : public Env<MarlGridEnvSpec>, public RenderableEnv {
10181021
}
10191022

10201023
void WriteMatrixAgentTile(int chosen_agent, int x, int y, int obs_size,
1021-
std::uint8_t* output) const {
1024+
int orientation, std::uint8_t* output) const {
10221025
if (chosen_agent < 0) {
10231026
return;
10241027
}
@@ -1039,24 +1042,22 @@ class MarlGridEnv : public Env<MarlGridEnvSpec>, public RenderableEnv {
10391042
output[MatrixObsOffset(
10401043
x, y, static_cast<int>(detail::MatrixObsChannel::kAgentBlue),
10411044
obs_size)] = color[2];
1045+
int direction = (agents_[chosen_agent].dir + orientation) % 4;
1046+
output[MatrixObsOffset(
1047+
x, y,
1048+
static_cast<int>(detail::MatrixObsChannel::kAgentDirRight) + direction,
1049+
obs_size)] = 255;
10421050
}
10431051

10441052
void WriteAgentMatrixObs(int agent_id, std::uint8_t* output) const {
10451053
int obs_values = view_size_ * view_size_ * detail::kMatrixObsChannels;
10461054
std::fill(output, output + obs_values, 0);
1047-
for (int y = 0; y < view_size_; ++y) {
1048-
for (int x = 0; x < view_size_; ++x) {
1049-
output[MatrixObsOffset(
1050-
x, y, static_cast<int>(detail::MatrixObsChannel::kEmpty),
1051-
view_size_)] = 255;
1052-
}
1053-
}
1054-
10551055
const detail::Agent& agent = agents_[agent_id];
10561056
if (!agent.active) {
10571057
return;
10581058
}
10591059
int rot_k = (agent.dir + 1) % 4;
1060+
int orientation = (4 - rot_k) % 4;
10601061
auto [top_x, top_y] = ViewTopLeft(agent);
10611062
std::vector<const detail::Cell*> view_cells(view_size_ * view_size_,
10621063
nullptr);
@@ -1080,25 +1081,25 @@ class MarlGridEnv : public Env<MarlGridEnvSpec>, public RenderableEnv {
10801081
continue;
10811082
}
10821083
const detail::Cell* cell = view_cells[detail::Offset(x, y, view_size_)];
1083-
for (int channel = 0; channel < 5; ++channel) {
1084-
output[MatrixObsOffset(x, y, channel, view_size_)] = 0;
1085-
}
10861084
WriteMatrixBaseTile(cell, x, y, view_size_, output);
10871085
WriteMatrixAgentTile(TopAgentForCell(cell, agent_id), x, y, view_size_,
1088-
output);
1086+
orientation, output);
10891087
}
10901088
}
10911089
}
10921090

10931091
void WriteAgentFullMatrixObs(int agent_id, std::uint8_t* output) const {
10941092
int obs_values = grid_size_ * grid_size_ * detail::kMatrixObsChannels;
10951093
std::fill(output, output + obs_values, 0);
1094+
if (!agents_[agent_id].active) {
1095+
return;
1096+
}
10961097
for (int y = 0; y < grid_size_; ++y) {
10971098
for (int x = 0; x < grid_size_; ++x) {
10981099
const detail::Cell& cell = CellAt(x, y);
10991100
WriteMatrixBaseTile(&cell, x, y, grid_size_, output);
11001101
WriteMatrixAgentTile(TopAgentForCell(&cell, agent_id), x, y, grid_size_,
1101-
output);
1102+
0, output);
11021103
}
11031104
}
11041105
}

0 commit comments

Comments
 (0)