Disconnecting HAL Signals Using Python

More
17 Aug 2017 14:54 #97635 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. :)

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.

More
17 Aug 2017 15:20 #97644 by andypugh
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")
The following user(s) said Thank You: mjohnston

Please Log in or Create an account to join the conversation.

More
17 Aug 2017 16:02 #97653 by mjohnston
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!

Please Log in or Create an account to join the conversation.

More
17 Aug 2017 16:09 #97654 by andypugh

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.

More
08 Sep 2017 21:27 - 08 Sep 2017 21:30 #98712 by mjohnston
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.
        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.156 seconds
Powered by Kunena Forum