{"record":{"id":"16f3691dc4fb9c24","repo":"AtsushiSakai/PythonRobotics","slug":"self-moving-direction-is-invalid","errorCode":null,"errorMessage":"self.moving direction is invalid ","messagePattern":"self\\.moving direction is invalid ","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"PathPlanning/GridBasedSweepCPP/grid_based_sweep_coverage_path_planner.py","lineNumber":117,"sourceCode":"        self.moving_direction *= -1\n        self.update_turning_window()\n\n    def search_start_grid(self, grid_map):\n        x_inds = []\n        y_ind = 0\n        if self.sweep_direction == self.SweepDirection.DOWN:\n            x_inds, y_ind = search_free_grid_index_at_edge_y(\n                grid_map, from_upper=True)\n        elif self.sweep_direction == self.SweepDirection.UP:\n            x_inds, y_ind = search_free_grid_index_at_edge_y(\n                grid_map, from_upper=False)\n\n        if self.moving_direction == self.MovingDirection.RIGHT:\n            return min(x_inds), y_ind\n        elif self.moving_direction == self.MovingDirection.LEFT:\n            return max(x_inds), y_ind\n\n        raise ValueError(\"self.moving direction is invalid \")\n\n\ndef find_sweep_direction_and_start_position(ox, oy):\n    # find sweep_direction\n    max_dist = 0.0\n    vec = [0.0, 0.0]\n    sweep_start_pos = [0.0, 0.0]\n    for i in range(len(ox) - 1):\n        dx = ox[i + 1] - ox[i]\n        dy = oy[i + 1] - oy[i]\n        d = np.hypot(dx, dy)\n\n        if d > max_dist:\n            max_dist = d\n            vec = [dx, dy]\n            sweep_start_pos = [ox[i], oy[i]]\n\n    return vec, sweep_start_pos","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/AtsushiSakai/PythonRobotics/blob/1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d/PathPlanning/GridBasedSweepCPP/grid_based_sweep_coverage_path_planner.py#L99-L135","documentation":"Raised by search_start_grid when moving_direction is neither MovingDirection.RIGHT nor MovingDirection.LEFT. The sweep planner needs a lateral direction to pick the starting grid cell and treats any other value as a configuration error.","triggerScenarios":"Constructing the coverage planner with moving_direction set to a string, int, or an enum member of a different type (e.g. sweeping direction enum), then calling sweep_path_search.","commonSituations":"Confusing moving_direction with sweep_direction, or assigning a raw string 'right' instead of MovingDirection.RIGHT when building the planner.","solutions":["Set moving_direction to MovingDirection.RIGHT or MovingDirection.LEFT explicitly.","If reading config from file, map strings to the enum: MovingDirection[value.upper()].","Double-check you are not passing the sweep direction (an angle/vector) into the moving_direction parameter."],"exampleFix":"# before\nplanner = GridBasedSweepCPP(..., moving_direction='right')\n\n# after\nplanner = GridBasedSweepCPP(..., moving_direction=MovingDirection.RIGHT)","handlingStrategy":"type-guard","validationCode":"assert planner.moving_direction in (MovingDirection.RIGHT, MovingDirection.LEFT)","typeGuard":"from PathPlanning.GridBasedSweepCPP.grid_based_sweep_coverage_path_planner import MovingDirection\n\ndef to_moving_direction(v):\n    if isinstance(v, MovingDirection):\n        return v\n    try:\n        return MovingDirection[v.upper()]\n    except KeyError:\n        raise ValueError(f'invalid moving direction: {v}')","tryCatchPattern":null,"preventionTips":["Always pass MovingDirection enum members, not strings.","Don't conflate moving_direction (lateral) with sweep_direction (angle)."],"tags":["coverage-planning","enum","config","validation"],"backgroundTag":"invalid-enum-config-value","analyzedSha":"1fe4fb980f6a12fe21c3c33d2b4da97a52c9154d","analyzedAt":"2026-08-28T13:23:33.733Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}