calibrate_engine.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import io
  2. class CalibrateEngine:
  3. def __init__(self):
  4. pass
  5. def generate_latency_calibration(self, settings):
  6. """
  7. Génère un G-Code de test de latence compatible Mach4.
  8. Prend en compte la résolution Max du contrôleur.
  9. """
  10. buf = io.StringIO()
  11. # --- EXTRACTION ET CALCULS ---
  12. # On récupère la puissance choisie et la résolution max configurée
  13. pwr = settings.get("power", 100)
  14. max_res = settings.get("max_value", 1000)
  15. # Sécurité : on s'assure de ne pas dépasser la valeur max configurée
  16. pwr = min(float(pwr), float(max_res))
  17. feed = settings.get("feedrate", 3000)
  18. use_s = settings.get("use_s_mode", True)
  19. e_num = settings.get("e_num", 0)
  20. latency_ms = settings.get("latency", 0.0)
  21. # Calcul du décalage (vitesse mm/min -> mm/ms)
  22. dist_offset = (feed * latency_ms) / 60000.0
  23. def write_move(x=None, y=None, power_val=None, is_g1=True):
  24. cmd = "G1" if is_g1 else "G0"
  25. coords = ""
  26. if x is not None: coords += f" X{x:.3f}"
  27. if y is not None: coords += f" Y{y:.3f}"
  28. if not coords:
  29. if power_val is not None:
  30. if use_s:
  31. buf.write(f"S{power_val:.2f}\n")
  32. else:
  33. buf.write(f"M67 E{e_num} Q{power_val:.2f}\n")
  34. return
  35. if power_val is not None:
  36. if use_s:
  37. buf.write(f"{cmd}{coords} S{power_val:.2f}\n")
  38. else:
  39. buf.write(f"M67 E{e_num} Q{power_val:.2f} {cmd}{coords}\n")
  40. else:
  41. buf.write(f"{cmd}{coords}\n")
  42. # --- DEBUT G-CODE ---
  43. buf.write(f"( --- ALIG LATENCY TEST --- )\n")
  44. buf.write(f"( Power: {pwr} )\n")
  45. buf.write(f"( Feedrate: {feed} mm-min | Offset: {dist_offset:.4f}mm )\n")
  46. buf.write("G21 G90 G17 G94\n")
  47. # On remplace le header par un S0 initial sécurisé
  48. buf.write("M3 S0\n")
  49. buf.write(f"G1 F{feed}\n\n")
  50. # 1. TRAIT VERTICAL CENTRAL
  51. buf.write("( Central Reference Line )\n")
  52. write_move(x=0, y=-2, is_g1=False)
  53. buf.write("G4 P0.5\n") # Petite pause pour marquer le début
  54. write_move(y=12, power_val=pwr)
  55. write_move(power_val=0)
  56. # 2. ÉTAGE ALLER (Gauche -> Droite)
  57. corr_fwd = -dist_offset
  58. buf.write(f"\n( Stage 1: Left to Center - Corr: {corr_fwd:.3f} )\n")
  59. for y_off in range(0, 51, 10):
  60. y_pos = y_off / 10.0
  61. write_move(x=-25, y=y_pos, is_g1=False)
  62. write_move(x=-10, power_val=0)
  63. write_move(x=(0.0 + corr_fwd), power_val=pwr)
  64. write_move(x=0.5 + corr_fwd, power_val=0)
  65. write_move(x=5, power_val=0)
  66. # 3. ÉTAGE RETOUR (Droite -> Gauche)
  67. corr_rev = dist_offset
  68. buf.write(f"\n( Stage 2: Right to Center - Corr: {corr_rev:.3f} )\n")
  69. for y_off in range(60, 111, 10):
  70. y_pos = y_off / 10.0
  71. write_move(x=25, y=y_pos, is_g1=False)
  72. write_move(x=10, power_val=0)
  73. write_move(x=(0.0 + corr_rev), power_val=pwr)
  74. write_move(x=-0.5 + corr_rev, power_val=0)
  75. write_move(x=-5, power_val=0)
  76. # --- FIN G-CODE ---
  77. buf.write("\n( Cleanup )\n")
  78. buf.write("M5\n")
  79. if not use_s: buf.write(f"M67 E{e_num} Q0\n")
  80. else: buf.write("S0\n")
  81. buf.write("M30\n")
  82. return buf.getvalue()
  83. def generate_linestep_calibration(self, settings):
  84. buf = io.StringIO()
  85. # --- Paramètres ---
  86. pwr = float(settings.get("power", 10))
  87. feed = float(settings.get("feedrate", 1000))
  88. min_step = float(settings.get("min_step", 0.05))
  89. central_mult = float(settings.get("multiplier", 2.0))
  90. latency_ms = float(settings.get("latency", 0.0))
  91. scan_mode = settings.get("scan_mode", "Horizontal").lower()
  92. use_s = settings.get("use_s_mode", True)
  93. e_num = settings.get("e_num", 0)
  94. # M3 ou M4 selon le réglage machine (firing_mode = "M3/M5" ou "M4/M5")
  95. firing_mode = settings.get("firing_mode", "M3/M5")
  96. firing_cmd = firing_mode.split("/")[0] # "M3" ou "M4"
  97. dist_offset = (feed * latency_ms) / 60000.0
  98. multipliers = [max(0.01, central_mult + i * 0.5) for i in range(-2, 3)]
  99. def write_move(x, y, power, is_g1=True):
  100. cmd = "G1" if is_g1 else "G0"
  101. if use_s:
  102. buf.write(f"{cmd} X{x:.3f} Y{y:.3f} S{power:.2f}\n")
  103. else:
  104. buf.write(f"M67 E{e_num} Q{power:.2f} {cmd} X{x:.3f} Y{y:.3f}\n")
  105. # --- Entête ---
  106. buf.write(f"( --- ALIG LINESTEP : {scan_mode.upper()} --- )\n")
  107. buf.write("G21 G90 G17 G94\n")
  108. buf.write(f"G1 F{feed}\n")
  109. # Allumage laser une seule fois avant tous les blocs
  110. if use_s:
  111. buf.write(f"{firing_cmd} S0\n")
  112. else:
  113. buf.write(f"{firing_cmd}\n")
  114. buf.write(f"M67 E{e_num} Q0.00\n")
  115. offset_base = 0.0
  116. for m in multipliers:
  117. step = min_step * m
  118. buf.write(f"\n( Block Mult x{m:.2f} - Step {step:.3f}mm )\n")
  119. if "horizontal" in scan_mode:
  120. y = 0.0
  121. while y <= 4.0:
  122. # Aller (gauche → droite)
  123. buf.write(f"G0 X-2 Y{offset_base + y:.4f}\n")
  124. write_move(0.0 - dist_offset, offset_base + y, 0)
  125. write_move(10.0 - dist_offset, offset_base + y, pwr)
  126. write_move(12.0, offset_base + y, 0)
  127. y += step
  128. if y > 4.0:
  129. break
  130. # Retour (droite → gauche)
  131. buf.write(f"G0 X12 Y{offset_base + y:.4f}\n")
  132. write_move(10.0 + dist_offset, offset_base + y, 0)
  133. write_move(0.0 + dist_offset, offset_base + y, pwr)
  134. write_move(-2.0, offset_base + y, 0)
  135. y += step
  136. offset_base += 6.0
  137. elif "vertical" in scan_mode:
  138. x = 0.0
  139. while x <= 10.0:
  140. # Monter
  141. buf.write(f"G0 X{offset_base + x:.4f} Y-2\n")
  142. write_move(offset_base + x, 0.0 - dist_offset, 0)
  143. write_move(offset_base + x, 4.0 - dist_offset, pwr)
  144. write_move(offset_base + x, 6.0, 0)
  145. x += step
  146. if x > 10.0:
  147. break
  148. # Descendre
  149. buf.write(f"G0 X{offset_base + x:.4f} Y6\n")
  150. write_move(offset_base + x, 4.0 + dist_offset, 0)
  151. write_move(offset_base + x, 0.0 + dist_offset, pwr)
  152. write_move(offset_base + x, -2.0, 0)
  153. x += step
  154. offset_base += 12.0
  155. # Extinction laser une seule fois après tous les blocs
  156. buf.write("\nM5\n")
  157. if not use_s:
  158. buf.write(f"M67 E{e_num} Q0.00\n")
  159. buf.write("M30\n")
  160. return buf.getvalue()