Fix malformed coords, stronger repetition penalty, better validation
Browse files
app.py
CHANGED
|
@@ -349,6 +349,15 @@ def get_model():
|
|
| 349 |
# GCODE PROCESSING
|
| 350 |
# ============================================================================
|
| 351 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
def clean_gcode(gcode: str) -> str:
|
| 353 |
"""Clean up generated gcode - fix formatting, remove garbage."""
|
| 354 |
|
|
@@ -380,22 +389,32 @@ def clean_gcode(gcode: str) -> str:
|
|
| 380 |
continue
|
| 381 |
if line.startswith("Workarea:") or line.startswith("Algorithm:"):
|
| 382 |
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
| 383 |
|
| 384 |
-
# Fix
|
| 385 |
-
line = re.sub(r'X
|
| 386 |
-
line = re.sub(r'
|
| 387 |
-
line = re.sub(r'X-\d+\.X-', 'X-', line)
|
| 388 |
-
line = re.sub(r'Y-Y-Y-', 'Y-', line)
|
| 389 |
-
line = re.sub(r'Y-Y-', 'Y-', line)
|
| 390 |
-
line = re.sub(r'Y-\d+\.Y-', 'Y-', line)
|
| 391 |
|
| 392 |
# Fix missing spaces: G1X -> G1 X
|
| 393 |
line = re.sub(r'(G[01])X', r'\1 X', line)
|
| 394 |
line = re.sub(r'(G[01])Y', r'\1 Y', line)
|
| 395 |
|
| 396 |
-
#
|
| 397 |
x_match = re.search(r'X([-\d.]+)', line)
|
| 398 |
y_match = re.search(r'Y([-\d.]+)', line)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 399 |
if x_match and y_match:
|
| 400 |
try:
|
| 401 |
coord = (round(float(x_match.group(1)), 1), round(float(y_match.group(1)), 1))
|
|
@@ -423,7 +442,7 @@ def center_and_scale_gcode(gcode: str) -> str:
|
|
| 423 |
"""Center the drawing on the workplane and scale to fill 80% of it."""
|
| 424 |
lines = gcode.split("\n")
|
| 425 |
|
| 426 |
-
# Extract all coordinates
|
| 427 |
coords = []
|
| 428 |
for line in lines:
|
| 429 |
x_match = re.search(r"X([-\d.]+)", line, re.IGNORECASE)
|
|
@@ -432,7 +451,9 @@ def center_and_scale_gcode(gcode: str) -> str:
|
|
| 432 |
try:
|
| 433 |
x = float(x_match.group(1))
|
| 434 |
y = float(y_match.group(1))
|
| 435 |
-
|
|
|
|
|
|
|
| 436 |
except ValueError:
|
| 437 |
pass
|
| 438 |
|
|
@@ -731,10 +752,10 @@ def generate(prompt: str, temperature: float, max_tokens: int, num_steps: int, g
|
|
| 731 |
next_logits[:, pad_id] = float('-inf')
|
| 732 |
next_logits[:, 1] = float('-inf') # <unk>
|
| 733 |
|
| 734 |
-
# Repetition penalty
|
| 735 |
if recent_tokens:
|
| 736 |
-
for token_id in set(recent_tokens[-
|
| 737 |
-
next_logits[:, token_id] *= 0.
|
| 738 |
|
| 739 |
# Top-k + Top-p sampling
|
| 740 |
top_k = 50
|
|
|
|
| 349 |
# GCODE PROCESSING
|
| 350 |
# ============================================================================
|
| 351 |
|
| 352 |
+
def is_valid_coord(s: str) -> bool:
|
| 353 |
+
"""Check if a string is a valid coordinate number."""
|
| 354 |
+
try:
|
| 355 |
+
v = float(s)
|
| 356 |
+
return -1000 < v < 1000 # Reasonable bounds
|
| 357 |
+
except (ValueError, TypeError):
|
| 358 |
+
return False
|
| 359 |
+
|
| 360 |
+
|
| 361 |
def clean_gcode(gcode: str) -> str:
|
| 362 |
"""Clean up generated gcode - fix formatting, remove garbage."""
|
| 363 |
|
|
|
|
| 389 |
continue
|
| 390 |
if line.startswith("Workarea:") or line.startswith("Algorithm:"):
|
| 391 |
continue
|
| 392 |
+
|
| 393 |
+
# Skip lines with mixed axis prefixes: Y-X-288 or X-Y-100
|
| 394 |
+
if re.search(r'X-Y-|Y-X-|X-X-|Y-Y-', line):
|
| 395 |
+
continue
|
| 396 |
|
| 397 |
+
# Fix double negatives: X--411 -> X-411
|
| 398 |
+
line = re.sub(r'X--(\d)', r'X-\1', line)
|
| 399 |
+
line = re.sub(r'Y--(\d)', r'Y-\1', line)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
|
| 401 |
# Fix missing spaces: G1X -> G1 X
|
| 402 |
line = re.sub(r'(G[01])X', r'\1 X', line)
|
| 403 |
line = re.sub(r'(G[01])Y', r'\1 Y', line)
|
| 404 |
|
| 405 |
+
# Validate coordinates - extract and check
|
| 406 |
x_match = re.search(r'X([-\d.]+)', line)
|
| 407 |
y_match = re.search(r'Y([-\d.]+)', line)
|
| 408 |
+
|
| 409 |
+
# If line has X or Y, validate them
|
| 410 |
+
if x_match:
|
| 411 |
+
if not is_valid_coord(x_match.group(1)):
|
| 412 |
+
continue # Skip malformed line
|
| 413 |
+
if y_match:
|
| 414 |
+
if not is_valid_coord(y_match.group(1)):
|
| 415 |
+
continue # Skip malformed line
|
| 416 |
+
|
| 417 |
+
# Check for stuck coordinates (repeated positions)
|
| 418 |
if x_match and y_match:
|
| 419 |
try:
|
| 420 |
coord = (round(float(x_match.group(1)), 1), round(float(y_match.group(1)), 1))
|
|
|
|
| 442 |
"""Center the drawing on the workplane and scale to fill 80% of it."""
|
| 443 |
lines = gcode.split("\n")
|
| 444 |
|
| 445 |
+
# Extract all valid coordinates (filter outliers)
|
| 446 |
coords = []
|
| 447 |
for line in lines:
|
| 448 |
x_match = re.search(r"X([-\d.]+)", line, re.IGNORECASE)
|
|
|
|
| 451 |
try:
|
| 452 |
x = float(x_match.group(1))
|
| 453 |
y = float(y_match.group(1))
|
| 454 |
+
# Only include reasonable coordinates
|
| 455 |
+
if -1000 < x < 1000 and -1000 < y < 1000:
|
| 456 |
+
coords.append((x, y))
|
| 457 |
except ValueError:
|
| 458 |
pass
|
| 459 |
|
|
|
|
| 752 |
next_logits[:, pad_id] = float('-inf')
|
| 753 |
next_logits[:, 1] = float('-inf') # <unk>
|
| 754 |
|
| 755 |
+
# Repetition penalty - stronger to prevent garbage
|
| 756 |
if recent_tokens:
|
| 757 |
+
for token_id in set(recent_tokens[-50:]):
|
| 758 |
+
next_logits[:, token_id] *= 0.5 # Stronger penalty
|
| 759 |
|
| 760 |
# Top-k + Top-p sampling
|
| 761 |
top_k = 50
|