Skip to content

fix: use full-range field maps and field-aware kickoff positioning - #1064

Draft
jaagut wants to merge 2 commits into
mainfrom
fix/full-range-field-maps
Draft

fix: use full-range field maps and field-aware kickoff positioning#1064
jaagut wants to merge 2 commits into
mainfrom
fix/full-range-field-maps

Conversation

@jaagut

@jaagut jaagut commented Sep 6, 2026

Copy link
Copy Markdown
Member

Field maps previously encoded grayscale values in 0–100. This migrates all nine localization maps to 0–255 and updates localization to normalize inverted byte intensities correctly. OccupancyGrid output remains 0–100, out-of-field score parameters retain their percentage semantics, and measurement marker colors use the normalized score directly.

Adds field.markings.center_circle.diameter to every field config. During opponent kickoff preparation (READY/SET), the central offense player uses circle radius + kickoff_striker_circle_margin as its distance behind the center. The margin defaults to 0.4 m. This applies only to normal/extra-time kickoff preparation with no other set play active. Other role positions and formation/set-play clearance retain their existing behavior.

Maps with saved generator inputs were regenerated as distance maps. Legacy maps without inputs were rescaled to preserve raster geometry; demo has no map. Every map retains its dimensions and exact zero-valued line mask. Existing goal-depth overrides remain intact. Circle diameters come from saved inputs or legacy raster geometry; demo declares no circle. The regeneration recipe is provided in this PR comment, rather than shipped as a tool.

Related upstream drafts:

Validation through Pixi:

  • Built bitbots_localization, bitbots_parameter_blackboard, bitbots_blackboard, and bitbots_body_behavior for the map migration.
  • Localization CTest passed for every byte intensity, occupancy-grid bounds/rounding, and unchanged out-of-map scoring.
  • Revised behavior/blackboard package tests cover DSD parsing, mypy, and 17 kickoff regression cases: circle sizes, READY/SET, other roles, own kickoff, normal play, other set plays, and penalty shootout.
  • All maps passed range/dimension/line-mask checks and reproduced byte-for-byte with the regeneration recipe.
  • Changed Python files formatted and linted.

No robot or simulator runtime validation was performed.

@jaagut

jaagut commented Sep 6, 2026

Copy link
Copy Markdown
Member Author

Regeneration recipe (kept here rather than shipped in the repository):

Run this from the repository root through pixi run -e default python /tmp/regenerate_field_maps.py, with the generator package built or its source on PYTHONPATH.

"""Regenerate distance maps from saved generator inputs.

Run through Pixi with the soccer_field_map_generator package on PYTHONPATH.
Legacy fields without generator inputs retain their existing map geometry.
"""

from pathlib import Path

import cv2
import numpy as np
import yaml
from soccer_field_map_generator.generator import generate_map_image

ROOT = Path("src/bitbots_misc/bitbots_parameter_blackboard/config/fields")


def main():
    for directory in sorted(ROOT.iterdir()):
        source = directory / "gui-config.yaml"
        if directory.name == "hsl_kid":
            source = directory / "hsl_kid.yaml"
        output = directory / "lines.png"
        if source.exists():
            parameters = yaml.safe_load(source.read_text())["parameters"]
            image = generate_map_image(parameters)
        elif output.exists():
            image = cv2.imread(str(output), cv2.IMREAD_UNCHANGED)
            if image.max() == 100:
                image = np.rint(image.astype(float) * 255 / 100).astype(np.uint8)
        else:
            continue
        if not cv2.imwrite(str(output), image):
            raise OSError(f"Could not write {output}")


if __name__ == "__main__":
    main()

Fields with saved generator inputs are regenerated; legacy maps are rescaled without changing geometry. Demo has no map. The full-range auxiliary binary images were already correctly encoded. Existing blackboard goal-depth overrides are preserved.

@jaagut jaagut changed the title fix: use full-range field maps and field-aware striker clearance fix: use full-range field maps and field-aware kickoff positioning Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🆕 New

Development

Successfully merging this pull request may close these issues.

1 participant