Skip to content

DRAFT: ZMQ messages from HALUI to GUIs - #3580

Open
c-morley wants to merge 66 commits into
masterfrom
python_halui
Open

DRAFT: ZMQ messages from HALUI to GUIs#3580
c-morley wants to merge 66 commits into
masterfrom
python_halui

Conversation

@c-morley

@c-morley c-morley commented Oct 5, 2025

Copy link
Copy Markdown
Collaborator

This is the on going work started here:
#3528
This generalizes the idea for messages.

There are three proof of concept sims:
axis_halui_test.ini
gmoccapy_halui_test.ini
qtdragon_halui_test.ini

They will load the respective gui and a separate simulated control panel.
You can notice the jograte slider on the control panel changes the jog rate on the gui.
I would love it if someone could test these rough changes.

@zz912

zz912 commented Oct 5, 2025

Copy link
Copy Markdown
Contributor

Hello,

I made basic manual tests for:
axis_halui_test.ini
gmoccapy_halui_test.ini
qtdragon_halui_test.ini

Everything works as I would expect. I was able to make it go into unexpected states by accidentally clicking on it, but I don't think this panel would be expected to be robust enough for regular CNC operation. These unexpected states were not related to the zmq technology. I would rather say that the external control would need to include more of the functions provided by the GUI, or more Panel-GUI cooperation.

I don't understand what "dialog control" is for.
Panel

I tested it in all GUIs, but it doesn't do anything.
In AXIS it just prints it in the terminal:

GUI OK command called
Write Msg called
[HAL bridge][DEBUG]  Sending ZMQ Message:STATUSREQUEST {"FUNCTION": "request_ok", "ARGS": true} (bridge.py:142)
[DEFAULT.COMMON.HAL_GLIB][DEBUG]  REQUESTED:{'FUNCTION': 'request_ok', 'ARGS': True} (hal_glib.py:410)
dialog control <hal_glib.GStat object at 0x7f2ce4cefbc0 (common+hal_glib+GStat at 0xaaf3980)> 1

@zz912

zz912 commented Oct 5, 2025

Copy link
Copy Markdown
Contributor

I understand that you want to unify different GUIs with zmq technology. That's why I don't understand why you copied panel.ui to all GUIs?
halui-panel-ui

I think it would be appropriate to rename panel.ui to panel_halui.ui.
The name of the main window "QTvcp-Panel-panel" is strange. I suggest renaming it to "HALUI control"

However, I have no idea what your plans are for this panel in the future.

Comment thread src/emc/usr_intf/halui.cc Outdated
FIELD(hal_bit_t,program_is_running) /* pin for notifying user that program is running */ \
FIELD(hal_bit_t,halui_mdi_is_running) /* pin for notifying user that halui MDI commands is running */ \
FIELD(hal_bit_t,program_is_paused) /* pin for notifying user that program is paused */ \
FIELD(hal_bit_t,cycle_start) /* pin for running program */ \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/* pin for running program */
I think, this is ctrl+c ctrl+v bug.
What is different between cycle and program?

@zz912

zz912 commented Oct 5, 2025

Copy link
Copy Markdown
Contributor

What is the "HALBRIDGE = hal_bridge" command in an ini file good for?

In some ini files you use it, in some you don't, and in some it is commented out.
I mean the ini files in this PR.

@zz912

zz912 commented Oct 5, 2025

Copy link
Copy Markdown
Contributor

Feel free to tell me what I should focus on in testing.

@zz912 zz912 mentioned this pull request Oct 5, 2025
@c-morley

c-morley commented Oct 9, 2025

Copy link
Copy Markdown
Collaborator Author

Thank you for testing - I will try to answer your questions.

Yes the control panel was just for basic testing, it would be nice to come up with a list of 'standard' buttons that each GUI would be expected to support. each GUI requires some code work to fully integrate.

Dialog control is for the popup dialogs such as tool change or warnings. I believe I only coded Qtdragon to respond for manual tool changes and warnings when unpausing the spindle when the spindle is auto lifted.

Panel.ui is just for testing the basic code - I have put no thought into final naming and most likely would build a gladevcp based panel for gmoccapy. I just copied and pasted for speed.

program_run starts the program thru linuxcnc's command channel (so bypasses the GUI).
cycle_start requests the GUI to start the program, allowing the GUI to do other things such as pre-checks.
cycle_pause is similar. Qtdragon uses it to start the spindle and lower the spindle (when in spindle lift mode).

I would be interested if HALUI INI MDI commands work better when they are a 'request' form HALUI for the GUI to run them. As I remember, you had some timing problems in Gmoccapy.
I will check to see if I finished the Gmoccapy INI MDI test code.

@c-morley

c-morley commented Oct 9, 2025

Copy link
Copy Markdown
Collaborator Author

I see the MDI buttons work in the gmoccapy test panel. Can you simulate the problem you had with HALUI MDI commands?

@zz912

zz912 commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

I had three problems:
First problem wasnt caused by MDI_commands. I had T6 in MDI_commands. I did not know, where was problem. That is why I wrote aboat problematic MDI comnands. Problem was: T6 in Gmoccapy caused running another command (G43). Now it is solved by removing automatic G43.
The second problem is, that Halui during MDI_commands switching modes. So GUI must be preapered for this situation. Like this #3441
The third problem is probably interesting for you.
I will test it in weekend. https://forum.linuxcnc.org/38-general-linuxcnc-questions/49445-python-command-wait-complete-does-not-wait-for-c-halui-commands

@c-morley

Copy link
Copy Markdown
Collaborator Author

I think both problems are improved by using this halui technique.
HALUI just asked the GUI to run the MDI (using ZMQ messages)
In this way the GUI can decide about mode switching and display changes.

I'll be interested in what you find.

@zz912

zz912 commented Oct 11, 2025

Copy link
Copy Markdown
Contributor

Hi,

I need to explain more what is the goal of implementing ZMQ?
Can you draw a block diagram of how ZMQ should work?
Just draw it with a pencil on paper and take a picture.

I studied the codes of this PR today. I am even more confused.

Previously, there were halui.mdi_commands in halui. These commands were triggered by the hal signal. The halui.cc file switched modes and triggered MDI commands. That was it.

Now there is halui.gui.mdi-command-MACRO0. These commands are triggered by the hal signal as well.
These commands are in the files:
halui.cc
gmoccapy.py
bridge.py
gtk_action.py
I didn't understand why it is in so many places, nor how it works there.

@c-morley

Copy link
Copy Markdown
Collaborator Author

zmq_block_diagram

@c-morley

c-morley commented Oct 12, 2025

Copy link
Copy Markdown
Collaborator Author

The HALUI pin halui.gui.mdi-command-MACRO0 uses ZMQ messages to request the GUI to run the commands it's self.

The best place to make sure mode changes and widget changes that are in sync with the MDI commands is the GUI.

HALUI is probably the most common way to connect a panel to the GUI, but because it thinks it's the only UI, some things like MDI and jogging do not work so well.

HALUI and bridge are really the same program. Bridge is a python library pulled into HALUI.
Bridge looks in the INI to see what macro pins need to be made.
It also reads/sends the ZMQ messages to ask Gmoccapy to run the INI macro command
It does similar things for jog rate and axis selection.

Gmoccapy use the library qtk_action to run the INI macro command.

The key here is that Gmoccapy is the one that runs the INI macro command, so it can be programed to set appropriate widgets and modes without having to worry about what HALUI is doing.

@zz912

zz912 commented Oct 12, 2025

Copy link
Copy Markdown
Contributor

Gmoccapy use the library qtk_action to run the INI macro command.

Not gtk_action.py?

@zz912

zz912 commented Oct 12, 2025

Copy link
Copy Markdown
Contributor

Thank you for picture. Right now, I can only be your rubber duck until I understand the whole thing.

The best place to make sure mode changes and widget changes that are in sync with the MDI commands is the GUI.

@Sigma1912 made something similar #3504
My problems with halui.mdi_commands will be solved here: #3441
So I still don't see the benefits of this PR.
ZMQ is realtime technology, but GUI, halui, bridge are userspace component. It is wierd combination for me now.

Why is bridge just a library?
What else will it be used for?
If bridge were a replacement for halui, it would be easier to maintain.

Could you describe to me better how MACRO0 works when using Gmoccapy?
zmq-001
The communication between the control panel and the halui is clear to me.
For MACRO0 HAL2 and HAL3 and NML1 it is not used. Is that right?

MOTION CONTROLLER is still some kind of abstract thing for me. Which specific files are these?
Let's limit ourselves to just running MACRO0, let's not make the pictures complicated.

gtk_action.py / qtk_action.py should be in the GUI image.
What does gtk_action.py / qtk_action.py do? Does it work with NML4 and HAL3?

@c-morley

Copy link
Copy Markdown
Collaborator Author

Gmoccapy use the library qtk_action to run the INI macro command.

Not gtk_action.py?

I miss spelled gtk_action

@c-morley

Copy link
Copy Markdown
Collaborator Author

ZMQ is not realtime.
For a macro call:

  1. HAL is used from control panel to HALUI
  2. ZMQ is used between HALUI and GUI
  3. NML is used between the GUI and the MOTION CONTROLLER (aka Linuxcnc Gcode motion controller)

gtk_action is just a library of python functions for doing GUI related chores such as sending MDI commands defined in the INI.

bridge is part of HALUI, it extends HALUI to do the new functions. It can not work without HALUI.

While there are other ways to work around these problems, I believe this is better and also it covers all the GUIs (when it;s finished) and a consistent interface for users.

To summarize:
This code extends HALUI to request the GUI to run INI defined MDI commands and sync axis selection and jograte between HALUI and the GUI.
Having the GUI run the INI MDI commands (rather then HALUI) eliminates any mode state problems and allows the GUI to decide how to react to the request.
Having Jograte and axis selection in sync allows better integration of a control panel and screen controls.
Right now GUI screen jog controls are completely separate from HALUI jog controls.
Finally, having the interface the same between all GUIs makes it easier for users to set up.

@c-morley

Copy link
Copy Markdown
Collaborator Author

zmq_block_diagram2
Here is a better diagram (The other was slightly wrong with the HAL connections to the motion controller from HALUI

@zz912

zz912 commented Oct 12, 2025

Copy link
Copy Markdown
Contributor

ZMQ is not realtime.

Is NML realtime?

@c-morley

Copy link
Copy Markdown
Collaborator Author

@zz912

zz912 commented Oct 12, 2025

Copy link
Copy Markdown
Contributor

Do you think that HAL between GUI and HALUI should be replaced by ZMQ in the future?
In an ideal world.

@c-morley

Copy link
Copy Markdown
Collaborator Author

Possibly but certainly not necessarily. I think the things that are very standard (say jogging, axis selection) are better done in standard way (in this case I chose HALUI) that does not require connecting HAL pins.

I would bet that non standard things would still be added using HAL pins - it's easy to do

@c-morley

Copy link
Copy Markdown
Collaborator Author

Well I said without connecting HAL pins, but I meant not connecting HAL pins from the GUI to HALUI, you still connect some HAL pins in HALUI, say for a control panel.
It just makes things standard and easier, while still allowing much customization.

@zz912

zz912 commented Oct 12, 2025

Copy link
Copy Markdown
Contributor

I always wondered why we need NML or ZMQ when theoretically we could be done via HAL?

@c-morley

Copy link
Copy Markdown
Collaborator Author

Outside my cone of hard knowledge, but as I under stand it, NML is a Neutral Message Layer for networking. I believer the idea was the GUI, IO controller and motion controller could be on different computers. Certainly the GUI side could be networked at one time.
HAL uses shared memory scheme, so can not directly be networked.

@zz912

zz912 commented Oct 13, 2025

Copy link
Copy Markdown
Contributor

What advantages does ZMQ have over HAL?

@c-morley

Copy link
Copy Markdown
Collaborator Author

In this case, zmq automically connects the gui to halui and any other program that registers to it. This creates consistent information in the system and a consistent connection path for doing jogging or axis selection.

@zz912

zz912 commented Oct 13, 2025

Copy link
Copy Markdown
Contributor

Thank you for explaining your thoughts.

Now I can get back to testing.

My test procedure:
1 ) Run gmoccapy_halui_test.ini
2 ) Turn off E-stop
3 ) Turn on machine
4 ) Home machine

Test number 1:
5 ) In the control panel press Manual
6 ) In the control panel press 0
You will see an ugly mode switch.
(If you don't see it, you have a very powerful PC and you should add G4 P10 to gui_mdi_commands)
This ugly mode switch also happens when using the classic mdi_commands too. I created a fix for it #3441 .

Test number 2:
7 ) In the control panel press MDI
8 ) In the control panel press 0
There is no problem

Test number 3:
9 ) In the control panel press AUTO
10 ) In the control panel press 0
Result:
Gmoccapy-run_gui_command-001

@zz912

zz912 commented Oct 13, 2025

Copy link
Copy Markdown
Contributor

For another test:

You must modify in INI file:
MDI_COMMAND_MACRO0 = G91; G1 Z-10

You must modify in gmoccapy.py

# =========================================================
# Coolant an mist coolant button
    def on_tbtn_flood_toggled(self, widget, data=None):
            self.command.wait_complete(30)
            self.command.mode(linuxcnc.MODE_MDI)
            self.command.wait_complete(30)
            self.command.mdi("G91 G1 X10 F200")
            self.command.wait_complete(30)
            self.command.mdi("G91 G1 Y10 F200")
            self.command.wait_complete(30)           
            self.command.mode(linuxcnc.MODE_MANUAL)
            self.command.wait_complete()

My test procedure:
1 ) Run gmoccapy_halui_test.ini
2 ) Turn off E-stop
3 ) Turn on machine
4 ) Home machine
5) go to 0 position => g90 => g0 x0z0y0
6 ) In the control panel press 0 and wait
Result:
Gmoccapy-run_gui_command-002
Everything is OK now.
7 ) In the control panel press 0 and immediately press cooling and wait for a few seconds.
Result:
Gmoccapy-run_gui_command-003
You are not in position Z-20 , because self.command.wait_complete(30) doesn't wait for gui_mdi_commands

Old mdi_commands make errors:
https://forum.linuxcnc.org/38-general-linuxcnc-questions/49445-python-command-wait-complete-does-not-wait-for-c-halui-commands

New gui_mdi_commands can be broken by another python command without any message.

@c-morley

Copy link
Copy Markdown
Collaborator Author

Ok Excellent notes. Thank you for testing!
I'll digest the information and probably ask follow up questions.

scroll the gcode if in auto and not running
otherwise zoom the gcode display.
Only if the MPG is enabled from HALUI
gmoccapy -add a 4 axis halui test config
to confirm angular jograte works
axis -add softkey, exit and reload actions
axis -allow MPG scrolling of gcode
axis -add mdi/macro calls from halui
@zz912

zz912 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Hello Chriss,

  1. I'm very happy that you are building a unified system for controlling GUIs through the HAL layer.

  2. I think we should start by removing the original HAL pins. For example, with gmoccapy.v-button.button-N and gmoccapy.h-button.button-N

halui_control

Disadvantages of double pins:

  • more complicated maintenance
  • more complicated testing
  • more complicated finding bugs in real applications
  • more complicated migration from Gmoccapy to QT Dragon, for example
  1. I would like to ask for @gmoccapy and @hansu opinion on removing duplicate pins from Gmoccapy

@c-morley

c-morley commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

In principle I agree with removing dual HAL pins. But...

First I'd like to have the code used in the wild without breaking everyone's systems.
If there is no unsolvable problems, then we could depreciate the pins.

@c-morley

c-morley commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@zz912
Looks like you tested latest....any feedback?

@zz912

zz912 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

I recommend removing gmoccapy_halui_test.ini and leaving only gmoccapy_halui_test_4_axis.ini . Having two configurations doesn't add anything, it just means more work for testing.

Short answer:
The buttons work.

Recommendations for Gmoccapy redesign:
If the program is paused, restarting it is done in Gmoccapy again using the pause button.
If the program is paused, restarting it is done in your panel using the start button.
This should be unified. I prefer modify Gmoccapy.

Long answer:
From the beginning I was against the partial addition of ZMQ technology. Now I am happy that ZMQ technology could be added completely. In the current Gmoccapy without ZMQ I am able to find bugs in more complex setups on machines (custom panel hardware, embed panel virtual. handwheel, ATC, ...) Some bugs I can't even replicate in offline sim and they only exist on real machine. As long as there are both HALUI pins and Gmoccapy pins, I don't want to get into much testing because we won't know where the bugs are.

I would like to ask you to reconsider the philosophy of macros:
Currently we have 3 ways to create a macro:

[HALUI]
MDI_COMMAND = o<m61-current> call
[MDI_COMMAND_LIST]
MDI_COMMAND_MACRO0 = G0 Z1;X0 Y0;Z0, Goto\nUser\nZero
[MACROS]
MACRO = go_to_position x-pos y-pos z-pos

I would like to have only one way to create macros. I would like each macro to have multiple parameters. For example like this:

[MACROS]
MACRO_NUMBER = 10
MACRO_COMMNAD = G53 G0 X0 Y0 Z0,
MACRO_GUI = YES
MACRO_HAL = NO
MACRO_PICTURE = ./macros/macro_10.png
MACRO_TOOLTIP = Go to home position
MACRO_SWITCH_MODE = YES

MACRO_NUMBER = 20
MACRO_COMMNAD = M6 T4,
MACRO_GUI = YES
MACRO_HAL = YES
MACRO_PICTURE = ./macros/macro_20.png
MACRO_TOOLTIP = Select T4 tool
MACRO_SWITCH_MODE = YES

MACRO_NUMBER = 30
MACRO_COMMNAD = G43,
MACRO_GUI = NO
MACRO_HAL = YES
MACRO_PICTURE = none
MACRO_TOOLTIP = none
MACRO_SWITCH_MODE = NO

Description parameters:
MACRO_NUMBER - automatic numbering is not good, so I made parameter for hand numbering
MACRO_COMMNAD - mdi_command
MACRO_GUI - if YES GUI create button for this macro
MACRO_HAL - if YES HALUI create HAL PIN for this macro
MACRO_PICTURE - source of picture for GUI button. If none button have text MACRO <MACRO_NUMBER>
MACRO_TOOLTIP = tooltip text for GUI button
MACRO_SWITCH_MODE - This option is important for Gmoccapy and short commands. When starting an MDI command, the "Manual mode => MDI mode => Manual mode" switch occurs. If the command is long and lasts for several seconds, then the windows in Gmoccapy will logically switch. If the command is short, for example just "G43", then two states can occur. The windows will flash quickly and it is just ugly. Gmoccapy will only capture part of the "Manual mode => MDI mode => Manual mode" process and behave unpredictably.

I took this way of writing multiple parameters for one thing from embedded tab:

[DISPLAY]
DISPLAY = gmoccapy

EMBED_TAB_NAME = Spindle_load
EMBED_TAB_LOCATION = box_custom_4
EMBED_TAB_COMMAND = gladevcp -x {XID} -H ./glade/spindle_load.hal ./glade/spindle_load.glade

EMBED_TAB_NAME = ATC
EMBED_TAB_LOCATION = ntb_preview 
EMBED_TAB_COMMAND = gladevcp -x {XID} -H ./glade/atc_panel.hal ./glade/atc_panel.glade

EMBED_TAB_NAME = Diagnostika
EMBED_TAB_LOCATION = ntb_preview 
EMBED_TAB_COMMAND = gladevcp -x {XID} -H ./glade/diagnostika.hal ./glade/diagnostika.glade

EMBED_TAB_NAME = some_name
EMBED_TAB_LOCATION = hbox_jog
EMBED_TAB_COMMAND = hide

Comment on lines +34 to +39
MACRO = i_am_lost
MACRO = halo_world
MACRO = jog_around
MACRO = increment xinc yinc
MACRO = go_to_position X-pos Y-pos Z-pos

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not belong in [DISPLAY]

Comment on lines +187 to +192
if self.type_linear_jog:
print('linear jograte ->>',self.type_linear_jog)
self._status.connect('jograte-changed', lambda w, data: self.set_value(data))
elif self.type_angular_jog:
print('Angular jograte ->>',self.type_angular_jog)
self._status.connect('jograte-angular-changed', lambda w, data: self.set_value(data))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug prints...

Suggested change
if self.type_linear_jog:
print('linear jograte ->>',self.type_linear_jog)
self._status.connect('jograte-changed', lambda w, data: self.set_value(data))
elif self.type_angular_jog:
print('Angular jograte ->>',self.type_angular_jog)
self._status.connect('jograte-angular-changed', lambda w, data: self.set_value(data))
if self.type_linear_jog:
self._status.connect('jograte-changed', lambda w, data: self.set_value(data))
elif self.type_angular_jog:
self._status.connect('jograte-angular-changed', lambda w, data: self.set_value(data))

@hansu

hansu commented Aug 9, 2026

Copy link
Copy Markdown
Member

I tested a bit 😄

It's really cool that the cycle start/pause is now working also in MDI-mode. I Love it!
But I would pull abort into this name-group:
halui.gui.abort --> halui.gui.cycle.abort
I would even prefer:

halui.gui.cycle-abort
halui.gui.cycle-pause
halui.gui.cycle-start

The MACRO pins

It's a bit confusing to have two kinds of macros now.
Are the new inline macros really needed?

Currently the halui.gui.mdi-command-NN pin does not call the corresponding macro which would be executed by the GUI button

halui.gui.mdi-command-0
halui.gui.mdi-command-1
halui.gui.mdi-command-2
halui.gui.mdi-command-3
halui.gui.mdi-command-4
halui.gui.mdi-command-MACRO0
halui.gui.mdi-command-MACRO1
halui.gui.mdi-command-MACRO2
halui.gui.mdi-command-MACRO3
halui.gui.mdi-command-MACRO4

Further I would group it with a dot:

halui.gui.mdi-command.0
halui.gui.mdi-command.1
halui.gui.mdi-command.2
halui.gui.mdi-command.3
halui.gui.mdi-command.4
halui.gui.mdi-command.MACRO0
halui.gui.mdi-command.MACRO1
halui.gui.mdi-command.MACRO2
halui.gui.mdi-command.MACRO3
halui.gui.mdi-command.MACRO4

Same for the softkeys:

halui.gui.softkey-00 --> halui.gui.softkey.00 and so on

  • 'halui.gui.reload-display' (bit, in) - pin for reloading the screen plot

It clears the plot actually

  • 'halui.gui.mpg-select.0' (bit, in) - pin for selecting MPG based control of the screen, such as scrolling

The naming could be made more clear. Maybe halui.gui.mpg-enable-scroll

Does it have the same function in axis?

  • 'halui.gui.shutdown' (bit, in) - pin for shutting down linuxcnc or system

I would not execute a system shutdown via halui. But if you really want this, you should decide whether to shutdown linuxcnc OR system.

  1. Naming of dialog pins
    I would suggest:
    'halui.gui.cancel' --> 'halui.gui.dialog-cancel'
    'halui.gui.ok' --> 'halui.gui.dialog-ok'

Maybe also further:

reload-display --> reload-plot or reload-preview ?

  1. Jogging units

I am not sure if it's a good idea to have unnormalized values for the jog speeds.
I think it's more handy to have a value from 0.0 to 1.0 where 1.0 is the maximum speed.

  1. Introduced bugs in tool table in conjunction with dialogs:
zmq-bug-1.mp4
zmq-bug-2.mp4
  1. Debug outputs

9.1 The log level should be the same like from the GUI - here it floods the console with debug messages.
Even for debug there are two line too many for one jograte-change:

[HAL bridge][DEBUG]  Sending ZMQ Message:STATUSREQUEST {"FUNCTION": "set_jograte", "ARGS": 400.0} (bridge.py:142)
[HAL bridge][DEBUG]  jograte-changed -> [400.0] -> 400.0 (bridge.py:103)
[HAL bridge][DEBUG]  jograte-changed -> [400.0] -> 400.0 (bridge.py:103)
JogRate value = 400.000000

9.2 I think this was also introduced here:

type 0
type 1
type -1
type -1
type -1

9.3 The INIINFO log level setting worked before, now also debug messages here:

[Gmoccapy.COMMON.INIINFO][DEBUG]  INI Path: /home/cnc/linuxcnc-master/configs/sim/gmoccapy/gmoccapy.ini (iniinfo.py:36)
[Gmoccapy.COMMON.INIINFO][DEBUG]  Linuxcnc Run-In-Place (RIP) flag true (iniinfo.py:1040)
[Gmoccapy.COMMON.INIINFO][DEBUG]  Machine is METRIC based. unit Conversion constant=0.03937007874015748 (iniinfo.py:145)
[Gmoccapy.COMMON.INIINFO][DEBUG]  TRAJ COORDINATES: XYZ (iniinfo.py:166)
[Gmoccapy.COMMON.INIINFO][DEBUG]  DEFAULT_LINEAR_VELOCITY = 2100.0 (iniinfo.py:349)
[Gmoccapy.COMMON.INIINFO][DEBUG]  MIN_LINEAR_VELOCITY = 0.0 (iniinfo.py:350)
[Gmoccapy.COMMON.INIINFO][DEBUG]  MAX_LINEAR_VELOCITY = 14040.0 (iniinfo.py:351)
[Gmoccapy.COMMON.INIINFO][DEBUG]  DEFAULT_ANGULAR_VELOCITY = 360 (iniinfo.py:356)
[Gmoccapy.COMMON.INIINFO][DEBUG]  MIN_ANGULAR_VELOCITY = 0 (iniinfo.py:357)
[Gmoccapy.COMMON.INIINFO][DEBUG]  MAX_ANGULAR_VELOCITY = 3600 (iniinfo.py:358)


  1. Axis
  • Why is USER_COMMAND_FILE=gstatmessages.py neccessary that halui operates with axis?
  • I think we should have a common folder for the macros instead of copying them for each GUI.

@hansu

hansu commented Aug 9, 2026

Copy link
Copy Markdown
Member

[zz912]

I would like to ask for @gmoccapy and @hansu opinion on removing duplicate pins from Gmoccapy

I agree on Chris that there is no hurry removing the pins now. That can be done later.

I would like to have only one way to create macros.

Agree.

I would like to have only one way to create macros. I would like each macro to have multiple parameters. For example like this:

[MACROS]
MACRO_NUMBER = 10
MACRO_COMMNAD = G53 G0 X0 Y0 Z0,
MACRO_GUI = YES
MACRO_HAL = NO
MACRO_PICTURE = ./macros/macro_10.png
MACRO_TOOLTIP = Go to home position
MACRO_SWITCH_MODE = YES

What speaks against the current implementation with a ngc file for each macro? This allos parameters and an image.

MACRO_SWITCH_MODE

This is a bigger issue I guess ...

@zz912

zz912 commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

I would like to have only one way to create macros. I would like each macro to have multiple parameters. For example like this:

[MACROS]
MACRO_NUMBER = 10
MACRO_COMMNAD = G53 G0 X0 Y0 Z0,
MACRO_GUI = YES
MACRO_HAL = NO
MACRO_PICTURE = ./macros/macro_10.png
MACRO_TOOLTIP = Go to home position
MACRO_SWITCH_MODE = YES

What speaks against the current implementation with a ngc file for each macro? This allos parameters and an image.

My intention is not only to replace the current Gmoccapy macro syntax. The new [MACROS] mechanism combines the current Gmoccapy MACRO functionality with the HALUI MDI_COMMAND functionality, so that the same macro can be triggered both from the GUI and through a HAL signal.

Now:

Gmoccapy
└── its own MACRO mechanism

HALUI
└── its own MDI_COMMAND mechanism

Qt GUI
└── yet another mechanism

My suggestion:


                    LinuxCNC macro
                         │
              ┌──────────┴──────────┐
              │                     │
             GUI                   HAL
              │                     │
         button/action          HAL signal

MACRO_SWITCH_MODE

This is a bigger issue I guess ...

Regarding MACRO_SWITCH_MODE, I agree that the mode-switching issue is a separate issue and should not be addressed in this PR. The parameter was only a proposal for how this could potentially be handled, not something I consider essential to this PR.

@c-morley

Copy link
Copy Markdown
Collaborator Author

Thanks for the thorough testing. Here is some responses.

  1. There is no gui.abort pin. there is halui.abort which does not go thru the gui.
    Any pin with halui.gui in it means the gui actually does the request. I can't see a reason to modify an abort in the gui.
    I changed the dots to hyphens

  2. yes, this is because qt does MDI commands and gmoccapy does Macro files.
    It's an early attempt to support both. Ideally we can find away to combine both styles into one INI entry
    Fix the -nn commands
    changed the dash to dot
    same for softkeys

  3. it reloads and clears the screen. change to gui.reload-preview

  4. I am open to a better name but don't really want scroll in that name as it can be used for anything in the gui, ie zoom
    The function depends on the gui. In AXIS it scrolls the gcode

  5. It depends on the gui. for example on qt it pops a dialog that allows a user to close the screen or system. We could add a separate pin for exit of screen?

  6. again I didn't want to restrict the use of the pins by adding 'dialog'. It also closes error messages which I guess you could call a dialog. I could be convinced either way I guess

  7. looks like I have a bit more work to do here. hal_glib expects the jog rate to always be in native machine units - so sort of normalized. I don't think speedcontrol honours that yet. changing everything to 0-1.0 is too big a change at least right now.

  8. ok great I will look into those.

  9. I forced the bridge log level for debugging purposes - changed back now
    type printout fix
    I also forced the iniinfo log level for testing -fixed now

  10. It was easier to test AXIS by using the user command file for mods.
    It needs to be properly integrated and needs dialog work.
    I just wanted to show a demonstration for feedback.

  11. we copy macros because it you use a common folder, when the sample is copied somewhere it breaks all the links and causes user questions. The file path search for linuxcnc gives little clue of what is going on. I have a branch somewhere that helps that...

Thanks I'll do some work and bug you again :)

@c-morley

Copy link
Copy Markdown
Collaborator Author

@zz912
The three INI mdi command types are not ideal, but each has it's purpose.
Using mutiline INI entries is certainly possible but then that gets to be a lot of code for the integrator/user to enter in the INI and get everything right.
Qt style gets a lot of information in a one line entry, (for instance the colon means wait for each command before running the next) but doesn't understand macro files and macro entries.
This is why for now there are two styles.
The original HALUI style was left to not break current users system.

Mode switching is a problem that can't really be fixed until linuxcnc doesn't require mode changes. You can mask it in the gui and that is why the halui.gui. mdi commands should be better then having halui do the command while the gui has no idea till it sees the mode switch.

@zz912

zz912 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

I think we all agree on the main goal: we want to unify the current macro mechanisms. The current situation, where we have several different ways of doing this, is not ideal.

Maybe we should therefore first define what we expect from a common Macro mechanism, and only then discuss the specific syntax and implementation.

                MACRO
                  │
      ┌───────────┴───────────┐
      │                       │
     GUI                     HAL
      │                       │
    button                 HAL signal

From my point of view, a Macro should have approximately the following properties:

Macro
├── name / number
├── command / ngc file
├── parameters – existing Gmoccapy functionality
├── GUI availability
├── HAL availability
├── image
├── tooltip
└── macro_is_running
  • name / number – identification of the macro
  • command / ngc file – the macro can be defined by g-code command or its own .ngc file
  • parameters – the ability to pass parameters to the macro
    for example: go_to_position X Y Z
  • GUI availability – the ability to run the macro from the GUI
  • HAL availability – the ability to run the same macro through HAL
  • image – an image for the GUI
  • tooltip – a description of the macro for the GUI
  • macro_is_running – information about whether the macro is currently running

I consider the last point important. If the Macro is to be a truly common mechanism for both GUI and HAL, the GUI should be able to determine the state of the macro — whether it is currently running or not. I am not suggesting any specific implementation for this information at this point; that can be addressed later, for example as part of the communication between LinuxCNC and the GUI.

Regarding the specific INI syntax, as an integrator I originally liked the multiline approach using an embedded tab. If a Macro has multiple properties, I find it clearer to have them structured on separate lines rather than having a large amount of information packed into a single line.

However, I am not fixed on this particular syntax. If we have the same understanding of the properties and behavior of a common Macro mechanism, I am open to other ways of representing them in the INI.

Maybe it is therefore better to first reach agreement on this model and then work together on how to implement it best.

@zz912

zz912 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

I have been thinking about how we could move forward with the macro unification without making this PR much larger than originally intended.

I realize that implementing the common Macro mechanism we are discussing would be a significant amount of additional work. Since the original purpose of this PR is mainly the ZMQ/HALUI-to-GUI integration, perhaps we don't need to implement the whole Macro unification here.

What if we first agree on the rules and semantics of the common Macro mechanism and document them in the GUI Development Reference?

The rules could define what a Macro should provide and how it should behave, while leaving the actual implementation for separate future work. This would also allow the implementation to be done gradually and by different developers.

If we can agree on the basic rules, I would be happy to prepare a PR for updating the GUI Development Reference with them.

I think this could give us a clear target for future implementation without requiring all of the work to be done as part of this PR. And of course, I understand that we are all doing this in our free time, so I would prefer a solution that doesn't unnecessarily increase the scope of this PR.

@c-morley

Copy link
Copy Markdown
Collaborator Author

I agree @zz912 we can discuss mdi/macro unification later and document it in gui development docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants