{"record":{"id":"9df0952325384c10","repo":"AtsushiSakai/PythonRobotics","slug":"number-of-obstacles-is-greater-than-grid-size","errorCode":null,"errorMessage":"Number of obstacles is greater than grid size!","messagePattern":"Number of obstacles is greater than grid size!","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"PathPlanning/TimeBasedPathPlanning/GridWithDynamicObstacles.py","lineNumber":62,"sourceCode":"\n    # Logging control\n    verbose = False\n\n    def __init__(\n        self,\n        grid_size: np.ndarray,\n        num_obstacles: int = 40,\n        obstacle_avoid_points: list[Position] = [],\n        obstacle_arrangement: ObstacleArrangement = ObstacleArrangement.RANDOM,\n        time_limit: int = 100,\n    ):\n        self.obstacle_avoid_points = obstacle_avoid_points\n        self.time_limit = time_limit\n        self.grid_size = grid_size\n        self.reservation_matrix = np.zeros((grid_size[0], grid_size[1], self.time_limit))\n\n        if num_obstacles > self.grid_size[0] * self.grid_size[1]:\n            raise Exception(\"Number of obstacles is greater than grid size!\")\n\n        if obstacle_arrangement == ObstacleArrangement.RANDOM:\n            self.obstacle_paths = self.generate_dynamic_obstacles(num_obstacles)\n        elif obstacle_arrangement == ObstacleArrangement.ARRANGEMENT1:\n            self.obstacle_paths = self.obstacle_arrangement_1(num_obstacles)\n        elif obstacle_arrangement == ObstacleArrangement.NARROW_CORRIDOR:\n            self.obstacle_paths = self.generate_narrow_corridor_obstacles(num_obstacles)\n\n        for i, path in enumerate(self.obstacle_paths):\n            obs_idx = i + 1  # avoid using 0 - that indicates free space in the grid\n            for t, position in enumerate(path):\n                # Reserve old & new position at this time step\n                if t > 0:\n                    self.reservation_matrix[path[t - 1].x, path[t - 1].y, t] = obs_idx\n                self.reservation_matrix[position.x, position.y, t] = obs_idx\n\n    \"\"\"\n    Generate dynamic obstacles that move around the grid. Initial positions and movements are random","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/AtsushiSakai/PythonRobotics/blob/1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d/PathPlanning/TimeBasedPathPlanning/GridWithDynamicObstacles.py#L44-L80","documentation":"Raised in GridWithDynamicObstacles.__init__ when num_obstacles exceeds the total number of cells in the grid (grid_size[0] * grid_size[1]). The grid cannot physically hold more obstacles than it has cells, so construction fails fast rather than generating an invalid scenario.","triggerScenarios":"Constructing GridWithDynamicObstacles with num_obstacles greater than grid_size[0]*grid_size[1], e.g. a 10x10 grid (100 cells) with num_obstacles=150.","commonSituations":"Scaling up obstacle counts for stress tests without scaling grid_size; reading num_obstacles from a config/CLI arg without clamping; randomly generated scenarios with unbounded obstacle counts.","solutions":["Reduce num_obstacles to at most grid_size[0] * grid_size[1]","Or increase grid_size dimensions to accommodate the obstacle count","Add validation/clamping at the call site (e.g. num_obstacles = min(num_obstacles, grid_size[0]*grid_size[1])) before constructing the grid"],"exampleFix":"# before\ngrid = GridWithDynamicObstacles(grid_size=(10, 10), num_obstacles=150, ...)\n\n# after\ngrid = GridWithDynamicObstacles(grid_size=(10, 10), num_obstacles=min(150, 10*10), ...)","handlingStrategy":"validation","validationCode":"max_cells = grid_size[0] * grid_size[1]\nassert num_obstacles <= max_cells, f\"num_obstacles ({num_obstacles}) must be <= {max_cells}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive num_obstacles from grid_size programmatically (e.g. int(0.2 * w * h)) instead of hardcoding","Validate scenario parameters in one place before constructing the grid"],"tags":["path-planning","grid","obstacles","validation","constructor"],"backgroundTag":"invalid-argument-range","analyzedSha":"1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d","analyzedAt":"2026-08-28T13:23:33.733Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}