Compare commits

..

4 Commits

Author SHA1 Message Date
cb6e12386f refaktor za pomoca gemini 2025-12-29 08:25:34 +01:00
7a3ff420e7 dodalem pozycjonowanie relatawne. wszystko dziala 2025-12-28 20:08:27 +01:00
3b540c1189 dodalem sidebar z przyciskami
czesc relative jeszcze nie dziala
2025-12-28 18:54:46 +01:00
063aa596be usunalem atc z ini 2025-12-28 18:53:55 +01:00
3 changed files with 622 additions and 8 deletions

View File

@@ -59,16 +59,16 @@ PROGRAM_EXTENSION = .png,.gif,.jpg Greyscale Depth Image
gif = image-to-gcode gif = image-to-gcode
jpg = image-to-gcode jpg = image-to-gcode
[ATC] #[ATC]
# Carousel images are available for 8, 10, 12, 14, 16, 18, 20, 21, 24 pocket changers # Carousel images are available for 8, 10, 12, 14, 16, 18, 20, 21, 24 pocket changers
POCKETS = 12 #POCKETS = 12
# The Z height your spindle needs to be at to clamp/unclamp a tool from the ATC platter # The Z height your spindle needs to be at to clamp/unclamp a tool from the ATC platter
Z_TOOL_CHANGE_HEIGHT = -3.1900 #Z_TOOL_CHANGE_HEIGHT = -3.1900
# The Z clearance height in machine coordinates your spindle needs to be at to clear the tools during carousel rotation # The Z clearance height in machine coordinates your spindle needs to be at to clear the tools during carousel rotation
Z_TOOL_CLEARANCE_HEIGHT = 0.0000 #Z_TOOL_CLEARANCE_HEIGHT = 0.0000
# Step Time should be set to the approximate time it takes your ATC to rotate from one pocket to the next entry is in milliseconds(1 second = 1000ms) # Step Time should be set to the approximate time it takes your ATC to rotate from one pocket to the next entry is in milliseconds(1 second = 1000ms)
# This just adjust the speed of the ATC tab Carousel GFX rotation (default if omitted is 1000ms) # This just adjust the speed of the ATC tab Carousel GFX rotation (default if omitted is 1000ms)
STEP_TIME = 500 #STEP_TIME = 500
[PYTHON] [PYTHON]
TOPLEVEL = ./python/toplevel.py TOPLEVEL = ./python/toplevel.py

View File

@@ -1,12 +1,15 @@
import os import os
import linuxcnc import linuxcnc
from enum import Enum
from qtpy import uic from qtpy import uic
from qtpy.QtCore import Qt from qtpy.QtCore import Qt
from qtpy.QtWidgets import QWidget from qtpy.QtWidgets import QWidget, QPushButton
from qtpyvcp.actions import machine_actions
from qtpyvcp.plugins import getPlugin from qtpyvcp.plugins import getPlugin
from qtpyvcp.utilities import logger from qtpyvcp.utilities import logger
from widgets.conversational.float_line_edit import FloatLineEdit
LOG = logger.getLogger(__name__) LOG = logger.getLogger(__name__)
@@ -14,10 +17,135 @@ STATUS = getPlugin('status')
TOOL_TABLE = getPlugin('tooltable') TOOL_TABLE = getPlugin('tooltable')
INI_FILE = linuxcnc.ini(os.getenv('INI_FILE_NAME')) INI_FILE = linuxcnc.ini(os.getenv('INI_FILE_NAME'))
CMD = linuxcnc.command()
class MoveMode(Enum):
"""Defines the available movement modes (absolute, work coordinate system, relative)."""
ABS = 1
WCS = 2
REL = 3
class UserTab(QWidget): class UserTab(QWidget):
"""A sidebar widget for controlling machine axis movements."""
def __init__(self, parent=None): def __init__(self, parent=None):
super(UserTab, self).__init__(parent) super(UserTab, self).__init__(parent)
ui_file = os.path.splitext(os.path.basename(__file__))[0] + ".ui" ui_file = os.path.splitext(os.path.basename(__file__))[0] + ".ui"
uic.loadUi(os.path.join(os.path.dirname(__file__), ui_file), self) uic.loadUi(os.path.join(os.path.dirname(__file__), ui_file), self)
self.position_inputs: list[FloatLineEdit] = self.findChildren(FloatLineEdit)
self.move_buttons: list[QPushButton] = self.findChildren(QPushButton)
self._connect_signals()
self.update_wcs_label()
def _connect_signals(self):
"""Connects widget signals to corresponding slots."""
STATUS.on.notify(self._update_control_states)
STATUS.all_axes_homed.notify(self._update_control_states)
STATUS.g5x_index.notify(self.update_wcs_label)
for line_edit in self.position_inputs:
line_edit.setEnabled(False)
line_edit.editingFinished.connect(self._format_sender_float_value)
for button in self.move_buttons:
button.setEnabled(False)
button.clicked.connect(self._on_move_button_clicked)
def _format_sender_float_value(self):
"""Formats the text of the sending FloatLineEdit to its specified format."""
sender_widget = self.sender()
if not isinstance(sender_widget, FloatLineEdit):
return
LOG.debug(f"Formatting float for {sender_widget.objectName()}")
value = sender_widget.value()
formatted_value = sender_widget.format_string.format(value)
sender_widget.setText(formatted_value)
def update_wcs_label(self, *args):
"""Updates the WCS status label with the current coordinate system."""
wcs_index = STATUS.g5x_index
self.wcs_status_label.setText(f"WCS {wcs_index}")
def _on_move_button_clicked(self):
"""Handles clicks on any of the move buttons."""
sender = self.sender()
if not isinstance(sender, QPushButton):
return
button_name = sender.objectName()
LOG.debug(f"Move button clicked: {button_name}")
try:
_, mode_str, axes_str = button_name.replace('_button', '').split('_')
except ValueError:
LOG.error(f"Could not parse button name: {button_name}")
return
move_configs = {
'abs': (MoveMode.ABS, self.abs_x_input, self.abs_y_input, self.abs_z_input),
'wcs': (MoveMode.WCS, self.wcs_x_input, self.wcs_y_input, self.wcs_z_input),
'rel': (MoveMode.REL, self.rel_x_input, self.rel_y_input, self.rel_z_input)
}
if mode_str not in move_configs:
LOG.error(f"Unknown move mode '{mode_str}' in button name: {button_name}")
return
mode, x_input, y_input, z_input = move_configs[mode_str]
x, y, z = None, None, None
if 'x' in axes_str or 'all' in axes_str:
x = x_input.value()
if 'y' in axes_str or 'all' in axes_str:
y = y_input.value()
if 'z' in axes_str or 'all' in axes_str:
z = z_input.value()
self._execute_move_command(mode, x, y, z)
LOG.debug(f"Executed move: {mode.name}, X={x}, Y={y}, Z={z}")
def _execute_move_command(self, mode: MoveMode, x=None, y=None, z=None):
"""Builds and sends an MDI command for the specified movement."""
mdi_command = ""
match mode:
case MoveMode.ABS:
mdi_command = "G53 G0"
case MoveMode.WCS:
mdi_command = "G0"
case MoveMode.REL:
mdi_command = "G91 G0"
if x is not None:
mdi_command += f" X{x}"
if y is not None:
mdi_command += f" Y{y}"
if z is not None:
mdi_command += f" Z{z}"
if mode == MoveMode.REL:
mdi_command += " ;G90"
LOG.debug(f"Sending MDI command: {mdi_command}")
machine_actions.issue_mdi(mdi_command)
def _is_machine_ready(self) -> bool:
"""Checks if the machine is on and all axes are homed."""
is_ready = STATUS.on() and STATUS.all_axes_homed()
LOG.debug(f"Machine ready check: on={STATUS.on()}, homed={STATUS.all_axes_homed()} -> {is_ready}")
return is_ready
def _update_control_states(self, *args):
"""Enables or disables UI controls based on the machine's ready state."""
is_ready = self._is_machine_ready()
LOG.debug(f"Updating control states. Machine ready: {is_ready}")
for button in self.move_buttons:
button.setEnabled(is_ready)
for line_edit in self.position_inputs:
line_edit.setEnabled(is_ready)

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>USER</class> <class>Move</class>
<widget class="QWidget" name="USER"> <widget class="QWidget" name="Move">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@@ -22,7 +22,493 @@
<property name="sidebar" stdset="0"> <property name="sidebar" stdset="0">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_abs">
<property name="styleSheet">
<string notr="true">QLabel{
color: rgb(238, 238, 236);
font: 16pt &quot;Bebas Kai&quot;;
}</string>
</property>
<property name="text">
<string>ABSOLUTE</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="FloatLineEdit" name="abs_x_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="security" stdset="0">
<number>0</number>
</property>
<property name="rules" stdset="0">
<string>[{&quot;name&quot;: &quot;postion_x&quot;, &quot;property&quot;: &quot;Text&quot;, &quot;expression&quot;: &quot;ch[0]&quot;, &quot;channels&quot;: [{&quot;url&quot;: &quot;position:abs?string&amp;axis=x&quot;, &quot;trigger&quot;: true}]}]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_abs_x_button">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO X</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="FloatLineEdit" name="abs_y_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="rules" stdset="0">
<string>[{&quot;name&quot;: &quot;position_y&quot;, &quot;property&quot;: &quot;Text&quot;, &quot;expression&quot;: &quot;ch[0]&quot;, &quot;channels&quot;: [{&quot;url&quot;: &quot;position:abs?string&amp;axis=y&quot;, &quot;trigger&quot;: true}]}]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_abs_y_button">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO Y</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="FloatLineEdit" name="abs_z_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="rules" stdset="0">
<string>[{&quot;name&quot;: &quot;position_z&quot;, &quot;property&quot;: &quot;Text&quot;, &quot;expression&quot;: &quot;ch[0]&quot;, &quot;channels&quot;: [{&quot;url&quot;: &quot;position:abs?string&amp;axis=z&quot;, &quot;trigger&quot;: true}]}]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_abs_z_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO Z</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="move_abs_all_button">
<property name="text">
<string>GO XYZ</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="StatusLabel" name="wcs_status_label">
<property name="styleSheet">
<string notr="true">QLabel{
color: rgb(238, 238, 236);
font: 16pt &quot;Bebas Kai&quot;;
}</string>
</property>
<property name="rules" stdset="0">
<string>[]</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="FloatLineEdit" name="wcs_x_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="security" stdset="0">
<number>0</number>
</property>
<property name="rules" stdset="0">
<string>[{&quot;name&quot;: &quot;postion_x&quot;, &quot;property&quot;: &quot;Text&quot;, &quot;expression&quot;: &quot;ch[0]&quot;, &quot;channels&quot;: [{&quot;url&quot;: &quot;position:Relative?string&amp;axis=x&quot;, &quot;trigger&quot;: true}]}]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_wcs_x_button">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="FloatLineEdit" name="wcs_y_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="rules" stdset="0">
<string>[{&quot;name&quot;: &quot;position_y&quot;, &quot;property&quot;: &quot;Text&quot;, &quot;expression&quot;: &quot;ch[0]&quot;, &quot;channels&quot;: [{&quot;url&quot;: &quot;position:Relative?string&amp;axis=y&quot;, &quot;trigger&quot;: true}]}]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_wcs_y_button">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO Y</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="FloatLineEdit" name="wcs_z_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="rules" stdset="0">
<string>[{&quot;name&quot;: &quot;position_z&quot;, &quot;property&quot;: &quot;Text&quot;, &quot;expression&quot;: &quot;ch[0]&quot;, &quot;channels&quot;: [{&quot;url&quot;: &quot;position:Relative?string&amp;axis=z&quot;, &quot;trigger&quot;: true}]}]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_wcs_z_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO Z</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="move_wcs_all_button">
<property name="text">
<string>GO XYZ</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_rel">
<property name="styleSheet">
<string notr="true">QLabel{
color: rgb(238, 238, 236);
font: 16pt &quot;Bebas Kai&quot;;
}</string>
</property>
<property name="text">
<string>RELATIVE</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="FloatLineEdit" name="rel_x_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="security" stdset="0">
<number>0</number>
</property>
<property name="rules" stdset="0">
<string>[]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_rel_x_button">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO X</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="FloatLineEdit" name="rel_y_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="rules" stdset="0">
<string>[]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_rel_y_button">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO Y</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="FloatLineEdit" name="rel_z_input">
<property name="text">
<string> 0.0000</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="rules" stdset="0">
<string>[]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="move_rel_z_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>GO Z</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="move_rel_all_button">
<property name="text">
<string>GO XYZ</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>StatusLabel</class>
<extends>QLabel</extends>
<header>qtpyvcp.widgets.display_widgets.status_label</header>
</customwidget>
<customwidget>
<class>VCPLineEdit</class>
<extends>QLineEdit</extends>
<header>qtpyvcp.widgets.input_widgets.line_edit</header>
</customwidget>
<customwidget>
<class>FloatLineEdit</class>
<extends>VCPLineEdit</extends>
<header>widgets.conversational.float_line_edit</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>