Source code for flatland.core.grid.grid8

from enum import IntEnum

import numpy as np

from flatland.core.transitions import Transitions


[docs]class Grid8TransitionsEnum(IntEnum): NORTH = 0 NORTH_EAST = 1 EAST = 2 SOUTH_EAST = 3 SOUTH = 4 SOUTH_WEST = 5 WEST = 6 NORTH_WEST = 7
[docs]class Grid8Transitions(Transitions): """ Grid8Transitions class derived from Transitions. Special case of `Transitions` over a 2D-grid (FlatLand). Transitions are possible to neighboring cells on the grid if allowed. GridTransitions keeps track of valid transitions supplied as `transitions` list, each represented as a bitmap of 64 bits. 0=North, 1=North-East, etc. """ def __init__(self, transitions): self.transitions = transitions
[docs] def get_type(self): return np.uint64
[docs] def get_transitions(self, cell_transition, orientation): """ Get the 8 possible transitions. Parameters ---------- cell_transition : int 64 bits used to encode the valid transitions for a cell. orientation : int Orientation of the agent inside the cell. Returns ------- tuple List of the validity of transitions in the cell. """ bits = (np.uint64(cell_transition) >> np.uint64((7 - orientation) * 8)) cell_transition = ( (bits >> np.uint64(7)) & np.uint64(1), (bits >> np.uint64(6)) & np.uint64(1), (bits >> np.uint64(5)) & np.uint64(1), (bits >> np.uint64(4)) & np.uint64(1), (bits >> np.uint64(3)) & np.uint64(1), (bits >> np.uint64(2)) & np.uint64(1), (bits >> np.uint64(1)) & np.uint64(1), bits & np.uint64(1)) return cell_transition
[docs] def set_transitions(self, cell_transition, orientation, new_transitions): """ Set the possible transitions. Parameters ---------- cell_transition : int 64 bits used to encode the valid transitions for a cell. orientation : int Orientation of the agent inside the cell. new_transitions : tuple Tuple of new transitions validitiy for the cell. Returns ------- int An updated bitmap that replaces the original transitions validity of `cell_transition' with `new_transitions`, for the appropriate `orientation`. """ mask = (1 << ((8 - orientation) * 8)) - (1 << ((7 - orientation) * 8)) negmask = ~mask new_transitions = \ (int(new_transitions[0]) & 1) << 7 | \ (int(new_transitions[1]) & 1) << 6 | \ (int(new_transitions[2]) & 1) << 5 | \ (int(new_transitions[3]) & 1) << 4 | \ (int(new_transitions[4]) & 1) << 3 | \ (int(new_transitions[5]) & 1) << 2 | \ (int(new_transitions[6]) & 1) << 1 | \ (int(new_transitions[7]) & 1) cell_transition = (int(cell_transition) & negmask) | (new_transitions << ((7 - orientation) * 8)) return cell_transition
[docs] def get_transition(self, cell_transition, orientation, direction): """ Get the transition bit (1 value) that determines whether an agent oriented in direction `orientation` and inside a cell with transitions `cell_transition' can move to the cell in direction `direction` relative to the current cell. Parameters ---------- cell_transition : int 64 bits used to encode the valid transitions for a cell. orientation : int Orientation of the agent inside the cell. direction : int Direction of movement whose validity is to be tested. Returns ------- int Validity of the requested transition: 0/1 allowed/not allowed. """ return ((cell_transition >> ((8 - 1 - orientation) * 8)) >> (8 - 1 - direction)) & 1
[docs] def set_transition(self, cell_transition, orientation, direction, new_transition, remove_deadends=False): """ Set the transition bit (1 value) that determines whether an agent oriented in direction `orientation` and inside a cell with transitions `cell_transition' can move to the cell in direction `direction` relative to the current cell. Parameters ---------- cell_transition : int 64 bits used to encode the valid transitions for a cell. orientation : int Orientation of the agent inside the cell. direction : int Direction of movement whose validity is to be tested. new_transition : int Validity of the requested transition: 0/1 allowed/not allowed. Returns ------- int An updated bitmap that replaces the original transitions validity of `cell_transition' with `new_transitions`, for the appropriate `orientation`. """ if new_transition: cell_transition |= (1 << ((8 - 1 - orientation) * 8 + (8 - 1 - direction))) else: cell_transition &= ~(1 << ((8 - 1 - orientation) * 8 + (8 - 1 - direction))) return cell_transition
[docs] def rotate_transition(self, cell_transition, rotation=0): """ Clockwise-rotate a 64-bit transition bitmap by rotation={0, 45, 90, 135, 180, 225, 270, 315} degrees. Parameters ---------- cell_transition : int 64 bits used to encode the valid transitions for a cell. rotation : int Angle by which to clock-wise rotate the transition bits in `cell_transition` by. I.e., rotation={0, 45, 90, 135, 180, 225, 270, 315} degrees. Returns ------- int An updated bitmap that replaces the original transitions bits with the equivalent bitmap after rotation. """ # TODO: WARNING: this part of the function has never been tested! # Rotate the individual bits in each block value = cell_transition rotation = rotation // 45 for i in range(8): block_tuple = self.get_transitions(value, i) block_tuple = block_tuple[rotation:] + block_tuple[:rotation] value = self.set_transitions(value, i, block_tuple) # Rotate the 8bits blocks value = ((value & (2 ** (rotation * 8) - 1)) << ((8 - rotation) * 8)) | (value >> (rotation * 8)) cell_transition = value return cell_transition
[docs] def get_direction_enum(self) -> IntEnum: return Grid8TransitionsEnum