Disconnecting HAL Signals Using Python
17 Aug 2017 14:54 #97635
by mjohnston
Disconnecting HAL Signals Using Python was created by mjohnston
Hi all, first post here. First off, thanks for all of you that answer people's questions on here, you've been a great help to me already with other aspects of my project. ![:) :)](/media/kunena/emoticons/smile.png)
Now, on to my question: Does anyone know if there's a way to disconnect HAL pins/signals on the fly using the Python libraries? (Or any other way of doing it - I'm not opposed to trying something new if it can do what I want.)
Some background: I'm working on a hot-wire cutting machine for foam. The machine has two X motors and two Y motors, one of each on either side of the machine moving one end of the wire. (It's a little confusing, but the Y axis is actually vertical here, so the wire is held parallel to the ground.) There are two use cases: the simple one in which the X's and Y's are slaved together, and the complex one in which all four axes are independent (they would be named X, Y, U, and V in this case).
I know I can create two different machine configurations for these two cases, but that makes more work having to close and open LinuxCNC each time I want to switch configurations. I'm already making a custom frontend using Python and Glade, and it would be really nice to be able to switch between the two use cases with the click of a button. I could use a machine configuration with all four axes defined independently and then use the hal.connect function to connect the appropriate HAL signals to slave the axes together, but in order to switch back to independent axes I would need to be able to disconnect them again.
Thanks for any help!
![:) :)](/media/kunena/emoticons/smile.png)
Now, on to my question: Does anyone know if there's a way to disconnect HAL pins/signals on the fly using the Python libraries? (Or any other way of doing it - I'm not opposed to trying something new if it can do what I want.)
Some background: I'm working on a hot-wire cutting machine for foam. The machine has two X motors and two Y motors, one of each on either side of the machine moving one end of the wire. (It's a little confusing, but the Y axis is actually vertical here, so the wire is held parallel to the ground.) There are two use cases: the simple one in which the X's and Y's are slaved together, and the complex one in which all four axes are independent (they would be named X, Y, U, and V in this case).
I know I can create two different machine configurations for these two cases, but that makes more work having to close and open LinuxCNC each time I want to switch configurations. I'm already making a custom frontend using Python and Glade, and it would be really nice to be able to switch between the two use cases with the click of a button. I could use a machine configuration with all four axes defined independently and then use the hal.connect function to connect the appropriate HAL signals to slave the axes together, but in order to switch back to independent axes I would need to be able to disconnect them again.
Thanks for any help!
Please Log in or Create an account to join the conversation.
17 Aug 2017 15:20 #97644
by andypugh
Replied by andypugh on topic Disconnecting HAL Signals Using Python
I don't think that this would be as easy to achieve as you think. When you change the stepgen(?) from one command to the other you will get an instant following error.
Might I suggest the alternative of an input filter that scans the G-code for U an W and if it does not find them it creates them to mirror X and Y.
I don't see anything in the code that defines a delsig or unlinkp function:
github.com/LinuxCNC/linuxcnc/blob/fbe32a...al/halmodule.cc#L531
But I don't fully understand PyObject either.
This isn't elegant but should work
from subprocess import call
call("halcmd unlinkp iocontrol.0.coolant.flood")
Might I suggest the alternative of an input filter that scans the G-code for U an W and if it does not find them it creates them to mirror X and Y.
I don't see anything in the code that defines a delsig or unlinkp function:
github.com/LinuxCNC/linuxcnc/blob/fbe32a...al/halmodule.cc#L531
But I don't fully understand PyObject either.
This isn't elegant but should work
from subprocess import call
call("halcmd unlinkp iocontrol.0.coolant.flood")
The following user(s) said Thank You: mjohnston
Please Log in or Create an account to join the conversation.
17 Aug 2017 16:02 #97653
by mjohnston
Replied by mjohnston on topic Disconnecting HAL Signals Using Python
Thanks for the reply, andy.
Good point about causing following errors. I would most likely only allow the button to work when the machine is not enabled, but I'm not sure if that would avoid causing a following error.
Yes, I didn't see anything in the source either (I had to go digging around in it earlier to figure out how hal.connect works, couldn't find much in the way of examples). I suppose I could try defining my own Python method for delsig or unlinkp, but I've never played with the Python-to-C layer of things before (plus it would get overwritten with updates to linuxcnc unless I put it somewhere else anyway).
Both of your suggested solutions could certainly work. The G-Code scanner might be very time consuming (this machine will get used with some CAM-generated programs which could have several thousand lines or more), so I'll probably try the subprocess route first. I don't see any reason why it wouldn't work, as long as I'm careful with pin names. The rest of my frontend should be complete enough to try it out in the next few days, I'll report back with how it goes.
Thanks!
Good point about causing following errors. I would most likely only allow the button to work when the machine is not enabled, but I'm not sure if that would avoid causing a following error.
Yes, I didn't see anything in the source either (I had to go digging around in it earlier to figure out how hal.connect works, couldn't find much in the way of examples). I suppose I could try defining my own Python method for delsig or unlinkp, but I've never played with the Python-to-C layer of things before (plus it would get overwritten with updates to linuxcnc unless I put it somewhere else anyway).
Both of your suggested solutions could certainly work. The G-Code scanner might be very time consuming (this machine will get used with some CAM-generated programs which could have several thousand lines or more), so I'll probably try the subprocess route first. I don't see any reason why it wouldn't work, as long as I'm careful with pin names. The rest of my frontend should be complete enough to try it out in the next few days, I'll report back with how it goes.
Thanks!
Please Log in or Create an account to join the conversation.
17 Aug 2017 16:09 #97654
by andypugh
I doubt that it would take much time, even with a very big file.
(Even very large G-code files are tiny compared with some other file types that computers routinely process).
Replied by andypugh on topic Disconnecting HAL Signals Using Python
Both of your suggested solutions could certainly work. The G-Code scanner might be very time consuming (this machine will get used with some CAM-generated programs which could have several thousand lines or more)
I doubt that it would take much time, even with a very big file.
(Even very large G-code files are tiny compared with some other file types that computers routinely process).
Please Log in or Create an account to join the conversation.
08 Sep 2017 21:27 - 08 Sep 2017 21:30 #98712
by mjohnston
Replied by mjohnston on topic Disconnecting HAL Signals Using Python
Update: I got it working!
As Andy warned, it was a bit more involved than I thought. I wrote the two functions below, which my GUI calls when the appropriate buttons are clicked. The buttons are disabled when the machine is enabled, so linking/unlinking can only be done in the disabled state. This, combined with configuring the axes as volatile home (which they are mechanically anyway), essentially eliminates errors which could be caused by linking axes which are in different positions.
Thanks again for the pointers, Andy!
For anyone else trying to do something like this, I found it very handy to use halcmd manually to test unlinking pins and connecting them to different signals. Then you just need to keep track of which commands you ran, and translate that into your Python code.
As Andy warned, it was a bit more involved than I thought. I wrote the two functions below, which my GUI calls when the appropriate buttons are clicked. The buttons are disabled when the machine is enabled, so linking/unlinking can only be done in the disabled state. This, combined with configuring the axes as volatile home (which they are mechanically anyway), essentially eliminates errors which could be caused by linking axes which are in different positions.
def link_axes(self):
self.axes_linked = True
# Break link between U axis and its independent controls
print "Breaking link between U and its controls"
call(["halcmd", "unlinkp", "pid.u.index-enable"])
call(["halcmd", "unlinkp", "pid.u.enable"])
call(["halcmd", "unlinkp", "pid.u.command"])
call(["halcmd", "unlinkp", "pid.u.command-deriv"])
call(["halcmd", "unlinkp", "pid.u.feedback"])
call(["halcmd", "unlinkp", "axis.6.motor-pos-fb"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.07.velocity-cmd"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.07.enable"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.07.position-fb"])
call(["halcmd", "unlinkp", "axis.6.jog-counts"])
call(["halcmd", "unlinkp", "axis.6.jog-enable"])
call(["halcmd", "unlinkp", "axis.6.jog-scale"])
# Break link between V axis and its independent controls
print "Breaking link between V and its controls"
call(["halcmd", "unlinkp", "pid.v.index-enable"])
call(["halcmd", "unlinkp", "pid.v.enable"])
call(["halcmd", "unlinkp", "pid.v.command"])
call(["halcmd", "unlinkp", "pid.v.command-deriv"])
call(["halcmd", "unlinkp", "pid.v.feedback"])
call(["halcmd", "unlinkp", "axis.7.motor-pos-fb"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.08.velocity-cmd"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.08.enable"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.08.position-fb"])
call(["halcmd", "unlinkp", "axis.7.jog-counts"])
call(["halcmd", "unlinkp", "axis.7.jog-enable"])
call(["halcmd", "unlinkp", "axis.7.jog-scale"])
# Connect U axis to X axis controls
print "Connecting U to X"
hal.connect("pid.u.index-enable", "x-index-enable")
hal.connect("pid.u.enable", "x-enable")
hal.connect("pid.u.command", "x-pos-cmd")
hal.connect("pid.u.command-deriv", "x-vel-cmd")
hal.connect("pid.u.feedback", "x-pos-fb")
hal.connect("hm2_5i25.0.stepgen.07.velocity-cmd", "x-output")
hal.connect("hm2_5i25.0.stepgen.07.enable", "x-enable")
# Connect V axis to Y axis controls
print "Connecting V to Y"
hal.connect("pid.v.index-enable", "y-index-enable")
hal.connect("pid.v.enable", "y-enable")
hal.connect("pid.v.command", "y-pos-cmd")
hal.connect("pid.v.command-deriv", "y-vel-cmd")
hal.connect("pid.v.feedback", "y-pos-fb")
hal.connect("hm2_5i25.0.stepgen.08.velocity-cmd", "y-output")
hal.connect("hm2_5i25.0.stepgen.08.enable", "y-enable")
def unlink_axes(self):
self.axes_linked = False
# Break link between U axis and X
print "Breaking link between U and X"
call(["halcmd", "unlinkp", "pid.u.index-enable"])
call(["halcmd", "unlinkp", "pid.u.enable"])
call(["halcmd", "unlinkp", "pid.u.command"])
call(["halcmd", "unlinkp", "pid.u.command-deriv"])
call(["halcmd", "unlinkp", "pid.u.feedback"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.07.velocity-cmd"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.07.enable"])
# Break link between V axis and Y
print "Breaking link between V and Y"
call(["halcmd", "unlinkp", "pid.v.index-enable"])
call(["halcmd", "unlinkp", "pid.v.enable"])
call(["halcmd", "unlinkp", "pid.v.command"])
call(["halcmd", "unlinkp", "pid.v.command-deriv"])
call(["halcmd", "unlinkp", "pid.v.feedback"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.08.velocity-cmd"])
call(["halcmd", "unlinkp", "hm2_5i25.0.stepgen.08.enable"])
# Connect U axis to independent controls
print "Connecting U to its independent controls"
hal.connect("pid.u.index-enable", "u-index-enable")
hal.connect("pid.u.enable", "u-enable")
hal.connect("pid.u.command", "u-pos-cmd")
hal.connect("pid.u.command-deriv", "u-vel-cmd")
hal.connect("pid.u.feedback", "u-pos-fb")
hal.connect("axis.6.motor-pos-fb", "u-pos-fb")
hal.connect("hm2_5i25.0.stepgen.07.velocity-cmd", "u-output")
hal.connect("hm2_5i25.0.stepgen.07.enable", "u-enable")
hal.connect("hm2_5i25.0.stepgen.07.position-fb", "u-pos-fb")
hal.connect("axis.6.jog-counts", "pendant:wheel-counts-x-filtered")
hal.connect("axis.6.jog-enable", "pendant:jog-x")
hal.connect("axis.6.jog-scale", "pendant:jog-scale")
# Connect V axis to independent controls
print "Connecting V to its independent controls"
hal.connect("pid.v.index-enable", "v-index-enable")
hal.connect("pid.v.enable", "v-enable")
hal.connect("pid.v.command", "v-pos-cmd")
hal.connect("pid.v.command-deriv", "v-vel-cmd")
hal.connect("pid.v.feedback", "v-pos-fb")
hal.connect("axis.7.motor-pos-fb", "v-pos-fb")
hal.connect("hm2_5i25.0.stepgen.08.velocity-cmd", "v-output")
hal.connect("hm2_5i25.0.stepgen.08.enable", "v-enable")
hal.connect("hm2_5i25.0.stepgen.08.position-fb", "v-pos-fb")
hal.connect("axis.7.jog-counts", "pendant:wheel-counts-y-filtered")
hal.connect("axis.7.jog-enable", "pendant:jog-y")
hal.connect("axis.7.jog-scale", "pendant:jog-scale")
Thanks again for the pointers, Andy!
For anyone else trying to do something like this, I found it very handy to use halcmd manually to test unlinking pins and connecting them to different signals. Then you just need to keep track of which commands you ran, and translate that into your Python code.
Last edit: 08 Sep 2017 21:30 by mjohnston.
Please Log in or Create an account to join the conversation.
Time to create page: 0.234 seconds