adding files
This commit is contained in:
45
my-emco/Misc/kopplingar.txt
Normal file
45
my-emco/Misc/kopplingar.txt
Normal file
@@ -0,0 +1,45 @@
|
||||
Märkning I/O Beskrivning
|
||||
----------------------------------------------------------------------------
|
||||
P1
|
||||
P2 X step
|
||||
P3 X dir
|
||||
P4 Y step
|
||||
P5 Y dir
|
||||
P6 Z step
|
||||
P7 Z dir
|
||||
|
||||
R1 P8 (i/o-kort) Relä spindel CW
|
||||
R2 P9 -"- Relä oljepump, spindel
|
||||
M2 P14 -"- MOS-FET tryckluftsventil dimsmörjning
|
||||
P16 -"- PWM spindel
|
||||
M1 P17 -"- MOS-FET tryckluftsventil, spindel
|
||||
|
||||
|
||||
P1 P10 -"- Z proximity sensor, home position
|
||||
P2 P11 -"- Y proximity sensor, home and max position
|
||||
P3 P12 -"- X proximity sensor, home and max position
|
||||
P13
|
||||
P15
|
||||
|
||||
brun/PHASE1(A) encoder phaseA+
|
||||
grå/PHASE2(B) encoder phaseB+
|
||||
röd/PHASE3(Z) encoder phaseZ+, index pulse
|
||||
blå 5V supply encoder
|
||||
2st vit GND encoder
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#P4 X rotations sensor, per ledstångsvarvvarv
|
||||
#P5 Y rotations sensor, per ledstångsvarvvarv
|
||||
#P6 Z rotations sensor, per ledstångsvarvvarv
|
||||
|
||||
#COL1 P12 (i/o-kort) collector transistor1, downsampled phaseA
|
||||
#COL2 P13 (i/o-kort) collector transistor2, downsampled phaseB
|
||||
#COL3 P15 (i/o-kort) collector transistor3, pulse stretched phaseZ index
|
||||
|
||||
#BASE1 D3 (arduino) base transistor1, downsampled phaseA
|
||||
#BASE2 D5 (arduino) base transistor2, downsampled phaseB
|
||||
#BASE3 D7 (arduino) base transistor3, downsampled phaseZ index
|
||||
BIN
my-emco/Misc/pid-tuning.ods
Normal file
BIN
my-emco/Misc/pid-tuning.ods
Normal file
Binary file not shown.
137
my-emco/comms.py
Normal file
137
my-emco/comms.py
Normal file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python
|
||||
# list available ports with 'python -m serial.tools.list_ports'
|
||||
import serial
|
||||
import watchdog
|
||||
|
||||
## Default values ##
|
||||
BAUDRATE = 38400
|
||||
"""Default value for the baudrate in Baud (int)."""
|
||||
|
||||
PARITY = 'N' #serial.PARITY_NONE
|
||||
"""Default value for the parity. See the pySerial module for documentation. Defaults to serial.PARITY_NONE"""
|
||||
|
||||
BYTESIZE = 8
|
||||
"""Default value for the bytesize (int)."""
|
||||
|
||||
STOPBITS = 1
|
||||
"""Default value for the number of stopbits (int)."""
|
||||
|
||||
TIMEOUT = 0.05
|
||||
"""Default value for the timeout value in seconds (float)."""
|
||||
|
||||
CLOSE_PORT_AFTER_EACH_CALL = False
|
||||
"""Default value for port closure setting."""
|
||||
|
||||
|
||||
class Message:
|
||||
"""'container for messages. keeps two strings <message> and <value>"""
|
||||
def __init__(self, name = '', data = ''):
|
||||
self.name = name
|
||||
self.data = data
|
||||
|
||||
def __repr__(self):
|
||||
return 'msg: ' + self.name + ' val: ' + self.data
|
||||
|
||||
def copy(self, msg):
|
||||
self.name = msg.name
|
||||
self.data = msg.data
|
||||
|
||||
class instrument:
|
||||
"""rs232 port"""
|
||||
|
||||
def __init__(self,
|
||||
port,
|
||||
msg_handler,
|
||||
watchdog_enabled = False,
|
||||
watchdog_timeout = 2,
|
||||
watchdog_periodicity = 0.5):
|
||||
self.serial = serial.Serial()
|
||||
self.serial.port = port
|
||||
self.serial.baudrate = BAUDRATE
|
||||
self.serial.parity = PARITY
|
||||
self.serial.bytesize = BYTESIZE
|
||||
self.serial.stopbits = STOPBITS
|
||||
self.serial.xonxoff = False # disable software flow control
|
||||
self.serial.timeout = TIMEOUT
|
||||
self.portOpened = False
|
||||
self.msg_hdlr = msg_handler
|
||||
|
||||
self.watchdog_daemon = watchdog.WatchDogDaemon(watchdog_timeout,
|
||||
watchdog_timeout,
|
||||
watchdog_enabled)
|
||||
self.watchdog_daemon.reset = self._watchdogClose #register watchdog reset function
|
||||
self.closed_by_watchdog = False
|
||||
|
||||
self.open()
|
||||
|
||||
def open(self):
|
||||
try:
|
||||
self.serial.open()
|
||||
self.portOpened = True
|
||||
print 'comms::opening port'
|
||||
except serial.SerialException:
|
||||
self.portOpened = False
|
||||
print 'unable to open port...'
|
||||
|
||||
def close(self):
|
||||
self.serial.close()
|
||||
self.portOpened = False
|
||||
print 'comms::closeing port'
|
||||
|
||||
def dataReady(self):
|
||||
if self.portOpened:
|
||||
return self.serial.in_waiting
|
||||
else:
|
||||
return False
|
||||
|
||||
def readMessages(self):
|
||||
"""reads serial port. creates an array of events
|
||||
output: array of events:
|
||||
"""
|
||||
if self.closed_by_watchdog:
|
||||
self.closed_by_watchdog = False
|
||||
self.open()
|
||||
|
||||
while self.dataReady():
|
||||
msg_str = self._read().split('_', 1)
|
||||
|
||||
if msg_str[0] != '':
|
||||
self.msg_hdlr(Message(*msg_str))
|
||||
self.watchdog_daemon.ping()
|
||||
|
||||
def generateEvent(self, name, data = ''):
|
||||
self.writeMessage(Message(name, data))
|
||||
|
||||
def writeMessage(self, m):
|
||||
self._write(m.name)
|
||||
if m.data != '':
|
||||
self._write('_' + str(m.data))
|
||||
self._write('\n')
|
||||
|
||||
def enableWatchdog(self, enable):
|
||||
self.watchdog_daemon.setEnabled(enable)
|
||||
|
||||
def _write(self, str):
|
||||
if self.portOpened == True:
|
||||
#serial expects a byte-array and not a string
|
||||
self.serial.write(''.join(str).encode('utf-8', 'ignore'))
|
||||
|
||||
def _read(self):
|
||||
""" returns string read from serial port """
|
||||
b = ''
|
||||
if self.portOpened == True:
|
||||
b = self.serial.read_until() #blocks until '\n' received or timeout
|
||||
|
||||
return b.decode('utf-8', 'ignore') #convert byte array to string
|
||||
|
||||
def _watchdogClose(self):
|
||||
self.closed_by_watchdog = True
|
||||
self.close()
|
||||
|
||||
def _is_number(self, s):
|
||||
""" helper function to evaluate if input text represents an integer or not """
|
||||
try:
|
||||
int(s)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
4
my-emco/custom-m-codes/M101
Normal file
4
my-emco/custom-m-codes/M101
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
# file to turn on parport pin 17 to open the spindle air valve
|
||||
halcmd setp parport.0.pin-17-out True
|
||||
exit 0
|
||||
4
my-emco/custom-m-codes/M102
Normal file
4
my-emco/custom-m-codes/M102
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
# file to turn off parport pin 17 to open the spindle air valve
|
||||
halcmd setp parport.0.pin-17-out False
|
||||
exit 0
|
||||
4
my-emco/custom-m-codes/M103
Normal file
4
my-emco/custom-m-codes/M103
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
# axis reload after
|
||||
axis-remote --reload
|
||||
exit 0
|
||||
19
my-emco/custom-m-codes/mychange.ngc
Normal file
19
my-emco/custom-m-codes/mychange.ngc
Normal file
@@ -0,0 +1,19 @@
|
||||
o<mychange> sub
|
||||
o10 if [#<_current_tool> NE #<_selected_tool>]
|
||||
;(DEBUG, current tool: #<_current_tool>, selected_tool: #<_selected_tool>)
|
||||
#<saved_z> = [#<_z>] ; save position
|
||||
#4999 = #<_selected_tool> ; store selected tool to use M61 at start-up
|
||||
G53 G0 Z87 ; rapid to tool change location
|
||||
M6
|
||||
;G53 G0 Z50
|
||||
;M101 ; engage spindle air blower
|
||||
;G53 G0 Z35
|
||||
;M102 ; disengage spindle air blower
|
||||
;(DEBUG, saved-z: #<saved_z>)
|
||||
G43
|
||||
G0 Z[#<saved_z>] ; restore position
|
||||
o10 else
|
||||
(DEBUG, tool #<_selected_tool> already in spindle)
|
||||
o10 endif
|
||||
o<mychange> endsub
|
||||
M2
|
||||
9
my-emco/custom-m-codes/myspindlestart.ngc
Normal file
9
my-emco/custom-m-codes/myspindlestart.ngc
Normal file
@@ -0,0 +1,9 @@
|
||||
o<myspindlestart> sub
|
||||
o10 if [#<_spindle_on> EQ 1]
|
||||
M5
|
||||
o10 else
|
||||
S800
|
||||
M3
|
||||
o10 endif
|
||||
o<myspindlestart> endsub
|
||||
M2
|
||||
30
my-emco/custom-m-codes/mytouch.ngc
Normal file
30
my-emco/custom-m-codes/mytouch.ngc
Normal file
@@ -0,0 +1,30 @@
|
||||
o<mytouch> sub
|
||||
o10 if [EXISTS[#<_hal[jog-axis-sel]>]]
|
||||
#<selected-axis> = #<_hal[jog-axis-sel]>
|
||||
;(DEBUG, my-mpg.axis-selector: #<selected-axis>)
|
||||
|
||||
(touch off z axis)
|
||||
o20 if [#<selected-axis> EQ 0]
|
||||
G10 L20 P0 Z0
|
||||
M103
|
||||
(MSG, touch off z axis)
|
||||
o20 endif
|
||||
|
||||
(touch off y axis)
|
||||
o30 if [#<selected-axis> EQ 1]
|
||||
G10 L20 P0 Y0
|
||||
M103
|
||||
(MSG, touch off y axis)
|
||||
o30 endif
|
||||
|
||||
(touch off x axis)
|
||||
o40 if [#<selected-axis> EQ 2]
|
||||
G10 L20 P0 X0
|
||||
M103
|
||||
(MSG, touch off x axis)
|
||||
o40 endif
|
||||
o10 else
|
||||
(DEBUG, didn't exist)
|
||||
o10 endif
|
||||
o<mytouch> endsub
|
||||
M2
|
||||
140
my-emco/custom.hal
Normal file
140
my-emco/custom.hal
Normal file
@@ -0,0 +1,140 @@
|
||||
# Include your customized HAL commands here
|
||||
# This file will not be overwritten when you run stepconf again
|
||||
|
||||
loadrt scale count=2 # 0 used to convert spindle rps-to-rpm, 1 used to scale jog-scale output from classicladder
|
||||
loadrt near names=spindle-at-speed
|
||||
loadrt pid names=spindle-speed-ctrl
|
||||
loadrt limit2 names=spindle-ramp
|
||||
loadrt not count=1 # used for ramping spindle speed
|
||||
loadrt and2 count=3 # and2.0 used for MPG run-button, and2.1 for e-stop-chain, and2.2 for setting tool after homeing
|
||||
loadrt classicladder_rt
|
||||
loadrt conv_float_u32 # user in postgui for converting analog signal to integer
|
||||
|
||||
loadusr -Wn my-mpg python serialEventHandler.py --port=/dev/ttyUSB0 -c my-mpg mpg.xml
|
||||
loadusr -Wn my-encoder python fake_encoder.py --port=/dev/ttyS0 -c my-encoder
|
||||
loadusr classicladder test_ladder.clp --nogui
|
||||
|
||||
addf scale.0 servo-thread
|
||||
addf scale.1 servo-thread
|
||||
addf spindle-at-speed servo-thread
|
||||
addf spindle-speed-ctrl.do-pid-calcs servo-thread
|
||||
addf spindle-ramp servo-thread
|
||||
addf not.0 servo-thread
|
||||
addf and2.0 servo-thread
|
||||
addf and2.1 servo-thread
|
||||
addf and2.2 servo-thread
|
||||
addf classicladder.0.refresh servo-thread
|
||||
addf conv-float-u32.0 servo-thread
|
||||
|
||||
### spindel speed ramping
|
||||
setp spindle-ramp.maxv 500
|
||||
net spindle-cmd-rpm => spindle-ramp.in
|
||||
net spindle-ramped <= spindle-ramp.out => pwmgen.0.value
|
||||
net spindle-on not.0.in
|
||||
net spindle-off not.0.out
|
||||
net spindle-off spindle-ramp.load
|
||||
net spindle-ramped => spindle-at-speed.in2
|
||||
|
||||
### spindle at speed monitoring ###
|
||||
setp spindle-at-speed.scale 0.98
|
||||
setp spindle-at-speed.difference 10
|
||||
setp scale.0.gain 60 # rps to rpm
|
||||
setp scale.0.offset 0
|
||||
|
||||
net spindle-velocity-rpm <= scale.0.out
|
||||
net spindle-cmd-rpm => spindle-at-speed.in1
|
||||
#net spindle-velocity-rpm => spindle-at-speed.in2
|
||||
net spindle-ramped => spindle-at-speed.in2
|
||||
net spindle-ready <= spindle-at-speed.out => spindle.0.at-speed
|
||||
|
||||
### encoder ###
|
||||
net spindle-position my-encoder.position => spindle.0.revs
|
||||
net spindle-velocity-rps my-encoder.velocity
|
||||
net spindle-velocity-rps => spindle.0.speed-in
|
||||
net spindle-velocity-rps => scale.0.in
|
||||
net spindle-index-enable my-encoder.index-enable <=> spindle.0.index-enable
|
||||
net watchdog-enable my-encoder.watchdog-enable # connected to checkbox in postgui
|
||||
|
||||
### PID ctrl ###
|
||||
net spindle-cmd-rpm => spindle-speed-ctrl.command
|
||||
setp spindle-speed-ctrl.Pgain 2.5
|
||||
setp spindle-speed-ctrl.Igain 3
|
||||
setp spindle-speed-ctrl.Dgain 2.3
|
||||
setp spindle-speed-ctrl.FF0 0
|
||||
setp spindle-speed-ctrl.FF1 1.5
|
||||
setp spindle-speed-ctrl.maxoutput 4500
|
||||
setp spindle-speed-ctrl.deadband 25
|
||||
#setp spindle-speed-ctrl.maxerror 1000
|
||||
setp spindle-speed-ctrl.enable 0
|
||||
|
||||
net spindle-velocity-rpm => spindle-speed-ctrl.feedback
|
||||
#net spindle-speed-ctrl-out spindle-speed-ctrl.output => pwmgen.0.value
|
||||
net spindle-on => spindle-speed-ctrl.enable #from spindle.0.on
|
||||
net spindle-index-enable => spindle-speed-ctrl.index-enable
|
||||
|
||||
### mist coolant ctrl ###
|
||||
net mist-cmd iocontrol.0.coolant-mist => parport.0.pin-14-out
|
||||
|
||||
### e-stop chain ###
|
||||
net estop-internal <= iocontrol.0.user-enable-out
|
||||
net estop-external <= parport.0.pin-13-in-not
|
||||
|
||||
net estop-internal => and2.1.in0
|
||||
net estop-external => and2.1.in1
|
||||
net estop-chain and2.1.out => iocontrol.0.emc-enable-in
|
||||
|
||||
## restoring tool after homing #################################################
|
||||
# note, logic assumes z-axis homed first, when x and y axis' are
|
||||
# homed, all axis are done
|
||||
net x-homed halui.joint.0.is-homed and2.2.in0
|
||||
net y-homed halui.joint.1.is-homed and2.2.in1
|
||||
net xy-homed and2.2.out
|
||||
net xy-homed halui.mdi-command-02
|
||||
net xy-homed halui.mdi-command-03
|
||||
|
||||
### pendant ##########################################
|
||||
# jog wheel connects to x, y, z axis
|
||||
net mpg-jog-counts joint.0.jog-counts axis.x.jog-counts <= my-mpg.jog-counts
|
||||
net mpg-jog-counts joint.1.jog-counts axis.y.jog-counts
|
||||
net mpg-jog-counts joint.2.jog-counts axis.z.jog-counts
|
||||
|
||||
# axis selector connects to x, y, z axis enable
|
||||
net jog-axis-sel classicladder.0.s32in-00
|
||||
net jog-x-enable classicladder.0.out-00
|
||||
net jog-y-enable classicladder.0.out-01
|
||||
net jog-z-enable classicladder.0.out-02
|
||||
|
||||
net jog-axis-sel my-mpg.axis-selector
|
||||
net jog-x-enable axis.x.jog-enable
|
||||
net jog-y-enable axis.y.jog-enable
|
||||
net jog-z-enable axis.z.jog-enable
|
||||
|
||||
# jog scale selector connects to x, y, z axis jog scale and jog velocity mode
|
||||
setp scale.1.gain 0.01
|
||||
setp scale.1.offset 0
|
||||
net jog-scale-100 classicladder.0.floatout-00 scale.1.in
|
||||
net jog-scale-sel classicladder.0.s32in-01
|
||||
net jog-scale scale.1.out
|
||||
|
||||
net jog-scale-sel my-mpg.scale-selector
|
||||
net jog-scale joint.0.jog-scale axis.x.jog-scale
|
||||
net jog-scale joint.1.jog-scale axis.y.jog-scale
|
||||
net jog-scale joint.2.jog-scale axis.z.jog-scale
|
||||
|
||||
net vel-mode-sel classicladder.0.out-03
|
||||
net vel-mode-sel joint.0.jog-vel-mode axis.x.jog-vel-mode
|
||||
net vel-mode-sel joint.1.jog-vel-mode axis.y.jog-vel-mode
|
||||
net vel-mode-sel joint.2.jog-vel-mode axis.z.jog-vel-mode
|
||||
|
||||
### connect the buttons
|
||||
# connect Func-button
|
||||
net func-button my-mpg.func-btn #connected to gladevcp-component in postgui
|
||||
|
||||
# connect Run button
|
||||
net run-button halui.mode.auto and2.0.in0 <= my-mpg.prog-run-btn
|
||||
net program-run-ok and2.0.in1 <= halui.mode.is-auto
|
||||
net remote-program-run halui.program.run <= and2.0.out
|
||||
|
||||
# connect E-Stop button
|
||||
net estop-button halui.estop.activate <= my-mpg.estop-btn
|
||||
|
||||
38
my-emco/custom_postgui.hal
Normal file
38
my-emco/custom_postgui.hal
Normal file
@@ -0,0 +1,38 @@
|
||||
# Include your customized HAL commands here
|
||||
# The commands in this file are run after the AXIS GUI (including PyVCP panel) starts
|
||||
|
||||
### virtual panel ##############################################################
|
||||
|
||||
## connect the frame-enable-signals
|
||||
net xy-homed gladevcp.commands
|
||||
net xy-homed gladevcp.tool
|
||||
net xy-homed gladevcp.mpg
|
||||
setp gladevcp.lube 1
|
||||
|
||||
## connect spindle frame
|
||||
net spindle-cmd-rpm => gladevcp.spindle-ref-rpm
|
||||
net spindle-velocity-rpm => gladevcp.spindle-curr-rpm
|
||||
net spindle-velocity-rpm => gladevcp.spindle-rpm-hbar
|
||||
#net spindle-duty pwmgen.0.curr-dc => pyvcp.spindle-pwm-duty
|
||||
net spindle-ready => gladevcp.led-spindle-at-speed
|
||||
net watchdog-enable gladevcp.wd-chkbtn
|
||||
|
||||
## connect command frame
|
||||
net tc-pos halui.mdi-command-01 <= gladevcp.tc-button
|
||||
net panel-rth-button halui.mdi-command-00 <= gladevcp.rth-button
|
||||
|
||||
## connect the current tool bumber
|
||||
net current-tool-number iocontrol.0.tool-number => gladevcp.current-tool
|
||||
|
||||
#set the gladevcp-tool-combo to show current tool at start
|
||||
net set-start-tool motion.analog-out-00 conv-float-u32.0.in
|
||||
net start-tool-pin conv-float-u32.0.out gladevcp.saved-tool-pin
|
||||
|
||||
## connect the mpg frame
|
||||
net func-button gladevcp.trigger_pin
|
||||
|
||||
## connect the luber frame
|
||||
net luber-acc-dist gladevcp.acc-distance
|
||||
net luber-cmd gladevcp.lube-cmd
|
||||
net luber-ext-req gladevcp.lube-cmd-btn
|
||||
net luber-reset gladevcp.lube-reset-btn
|
||||
158
my-emco/emco-buttons.xml
Normal file
158
my-emco/emco-buttons.xml
Normal file
@@ -0,0 +1,158 @@
|
||||
<pyvcp>
|
||||
<labelframe text="EMCO VCM100">
|
||||
<font>("Helvetica",16)</font>
|
||||
|
||||
<!-- buttons -->
|
||||
<vbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>3</bd>
|
||||
<button>
|
||||
<halpin>"rth-button"</halpin>
|
||||
<text>"Rapid to Home"</text>
|
||||
</button>
|
||||
<button>
|
||||
<halpin>"tc-button"</halpin>
|
||||
<text>"Tool Change Pos"</text>
|
||||
</button>
|
||||
<button>
|
||||
<halpin>"lube-on"</halpin>
|
||||
<text>"Lube"</text>
|
||||
</button>
|
||||
</vbox>
|
||||
|
||||
<vbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>3</bd>
|
||||
<hbox>
|
||||
<label>
|
||||
<text>"Tool 1 "</text>
|
||||
</label>
|
||||
<button>
|
||||
<halpin>"change-tool1"</halpin>
|
||||
<text>"Change"</text>
|
||||
</button>
|
||||
</hbox>
|
||||
|
||||
<hbox>
|
||||
<label>
|
||||
<text>"Tool 2 "</text>
|
||||
</label>
|
||||
<button>
|
||||
<halpin>"change-tool2"</halpin>
|
||||
<text>"Change"</text>
|
||||
</button>
|
||||
</hbox>
|
||||
|
||||
<hbox>
|
||||
<label>
|
||||
<text>"Tool 3 "</text>
|
||||
</label>
|
||||
<button>
|
||||
<halpin>"change-tool3"</halpin>
|
||||
<text>"Change"</text>
|
||||
</button>
|
||||
</hbox>
|
||||
|
||||
<hbox>
|
||||
<label>
|
||||
<text>"Tool 4 "</text>
|
||||
</label>
|
||||
<button>
|
||||
<halpin>"change-tool4"</halpin>
|
||||
<text>"Change"</text>
|
||||
</button>
|
||||
</hbox>
|
||||
|
||||
<hbox>
|
||||
<label>
|
||||
<text>"Tool 5 "</text>
|
||||
</label>
|
||||
<button>
|
||||
<halpin>"change-tool5"</halpin>
|
||||
<text>"Change"</text>
|
||||
</button>
|
||||
</hbox>
|
||||
|
||||
<hbox>
|
||||
<label>
|
||||
<text>"Tool 6 "</text>
|
||||
</label>
|
||||
<button>
|
||||
<halpin>"change-tool6"</halpin>
|
||||
<text>"Change"</text>
|
||||
</button>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<vbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>3</bd>
|
||||
<hbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>2</bd>
|
||||
<label>
|
||||
<text>"Spindle cmd RPM"</text>
|
||||
</label>
|
||||
<number>
|
||||
<halpin>"spindle-ref-rpm"</halpin>
|
||||
<format>"+4.2f"</format>
|
||||
</number>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>2</bd>
|
||||
<label>
|
||||
<text>"Spindle actual RPM"</text>
|
||||
</label>
|
||||
<number>
|
||||
<halpin>"spindle-curr-rpm"</halpin>
|
||||
<format>"+4.2f"</format>
|
||||
</number>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>2</bd>
|
||||
<label>
|
||||
<text>"Spindle PWM Duty"</text>
|
||||
</label>
|
||||
<number>
|
||||
<halpin>"spindle-pwm-duty"</halpin>
|
||||
<format>"+4.2f"</format>
|
||||
</number>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>2</bd>
|
||||
<label>
|
||||
<text>"spindle at speed"</text>
|
||||
</label>
|
||||
<led>
|
||||
<halpin>"led-spindle-at-speed"</halpin>
|
||||
<on_color>"green"</on_color>
|
||||
<off_color>"red"</off_color>
|
||||
</led>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<relief>RIDGE</relief>
|
||||
<bd>2</bd>
|
||||
<label>
|
||||
<text>"Current Tool"</text>
|
||||
</label>
|
||||
<s32>
|
||||
<halpin>"current-tool"</halpin>
|
||||
<format>"2d"</format>
|
||||
</s32>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<vbox>
|
||||
<label>
|
||||
<text>"Spindle Feedback"</text>
|
||||
</label>
|
||||
<checkbutton>
|
||||
<halpin>"wd-chkbtn"</halpin>
|
||||
<text>"Watchdog Enable "</text>
|
||||
<initval>1</initval>
|
||||
</checkbutton>
|
||||
</vbox>
|
||||
</labelframe>
|
||||
</pyvcp>
|
||||
126
my-emco/fake_encoder.py
Normal file
126
my-emco/fake_encoder.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
import sys
|
||||
import comms
|
||||
import hal
|
||||
import getopt
|
||||
import time
|
||||
|
||||
class FakeEncoder:
|
||||
def __init__(self, dT, scale):
|
||||
self._position = 0 # scaled value from count
|
||||
self._velocity = 0 # units per sec, i.e. rps
|
||||
self._dT = dT # delta time between samples [s]
|
||||
self._scale = scale # nbr of pulses / rev
|
||||
|
||||
def clear(self):
|
||||
self._position = 0
|
||||
print 'FakeEncoder::clearing position data'
|
||||
|
||||
def handleEvent(self, event):
|
||||
if (event.name == 'pos'):
|
||||
self._velocity = float(event.data)/(self._scale*self._dT) #pos per dT to rps
|
||||
self._position += float(event.data)/self._scale
|
||||
|
||||
def getVelocity(self):
|
||||
return self._velocity
|
||||
|
||||
def getPosition(self):
|
||||
return self._position
|
||||
|
||||
|
||||
class HalAdapter:
|
||||
def __init__(self, name, clear_cb):
|
||||
self.h = hal.component(name)
|
||||
self.clearCallback = clear_cb
|
||||
|
||||
self.h.newpin("velocity", hal.HAL_FLOAT, hal.HAL_OUT)
|
||||
self.h.newpin("position", hal.HAL_FLOAT, hal.HAL_OUT)
|
||||
self.h.newpin("index-enable", hal.HAL_BIT, hal.HAL_IO)
|
||||
self.h.newpin("watchdog-enable", hal.HAL_BIT, hal.HAL_IN)
|
||||
self.h.ready()
|
||||
|
||||
def update(self, vel, pos):
|
||||
self.h['velocity'] = vel
|
||||
self.h['position'] = pos
|
||||
|
||||
if self.h['index-enable'] == 1:
|
||||
self.clearCallback()
|
||||
self.h['position'] = 0
|
||||
self.h['index-enable'] = 0
|
||||
|
||||
def isWatchdogEnabled(self):
|
||||
return self.h['watchdog-enable']
|
||||
|
||||
class OptParser:
|
||||
def __init__(self, argv):
|
||||
self.name = 'my-encoder' # default name of component in HAL
|
||||
self.port = '/dev/ttyUSB1' # default serial port to use
|
||||
|
||||
self._getOptions(argv)
|
||||
|
||||
def __repr__(self):
|
||||
return 'name: ' + self.name + '\tport: ' + self.port
|
||||
|
||||
def _getOptions(self, argv):
|
||||
if argv != []:
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, "hp:c:", ["port="])
|
||||
except getopt.GetoptError as err:
|
||||
# print help information and exit:
|
||||
print(err) # will print something like "option -a not recognized"
|
||||
sys.exit(2)
|
||||
|
||||
### parse input command line
|
||||
for o, a in opts:
|
||||
if o == "-h":
|
||||
self._usage()
|
||||
sys.exit()
|
||||
if o == "-c":
|
||||
self.name = a
|
||||
elif o in ("-p", "--port"):
|
||||
self.port = a
|
||||
else:
|
||||
print o, a
|
||||
assert False, "unhandled option"
|
||||
|
||||
|
||||
def getName(self):
|
||||
return self.name
|
||||
|
||||
def getPort(self):
|
||||
return self.port
|
||||
|
||||
def _usage(self):
|
||||
""" print command line options """
|
||||
print "usage serial_mpg.py -h -c <name> -p/--port= <serial port>\n"\
|
||||
"-c <name> # name of component in HAL. 'mpg' default\n"\
|
||||
"-p/--port= <serial port> # default serial port to use. '/dev/ttyS2' default\n"\
|
||||
"-h # print this test"
|
||||
|
||||
|
||||
def main():
|
||||
optParser = OptParser(sys.argv[1:])
|
||||
componentName = optParser.getName()
|
||||
portName = optParser.getPort()
|
||||
|
||||
print optParser
|
||||
|
||||
fakeEncoder = FakeEncoder(0.05, 500)
|
||||
speedCounter = comms.instrument(portName, fakeEncoder.handleEvent, False) #serial adaptor, watchdog disabled
|
||||
halAdapter = HalAdapter(componentName, fakeEncoder.clear)
|
||||
|
||||
try:
|
||||
while 1:
|
||||
speedCounter.enableWatchdog(halAdapter.isWatchdogEnabled())
|
||||
speedCounter.readMessages()
|
||||
|
||||
halAdapter.update(fakeEncoder.getVelocity(), fakeEncoder.getPosition())
|
||||
|
||||
time.sleep(0.05)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
6
my-emco/func-btn.xml
Normal file
6
my-emco/func-btn.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<mpg>
|
||||
<function>Touch off selected axis<gcode>O<mytouch>call</gcode></function>
|
||||
<function>Spindle Start/Stop<gcode>O<myspindlestart>call</gcode></function>
|
||||
<function>Return to safe Z<gcode>G53 G0 Z0</gcode></function>
|
||||
<function>Return to home<gcode>G53 G0 X0 Y0 Z0</gcode></function>
|
||||
</mpg>
|
||||
138
my-emco/gladevcp-handler.py
Normal file
138
my-emco/gladevcp-handler.py
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/ python
|
||||
|
||||
import gtk
|
||||
import gobject
|
||||
import linuxcnc
|
||||
import hal
|
||||
import hal_glib
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
debug = 0
|
||||
|
||||
class ToolTableParser:
|
||||
def __init__(self, f):
|
||||
self.f = open(f, 'r')
|
||||
self.list = gtk.ListStore(int, str, str)
|
||||
self._parse_file()
|
||||
self.f.close()
|
||||
|
||||
def __repr__(self):
|
||||
ret_str = ''
|
||||
for l in self.list:
|
||||
ret_str += str(l) + '\n'
|
||||
return ret_str
|
||||
|
||||
def get_parsed_data(self):
|
||||
return self.list
|
||||
|
||||
def _parse_file(self):
|
||||
lines = self.f.readlines()
|
||||
|
||||
i = 0
|
||||
for line in lines:
|
||||
tool_nbr = line.split(' ')[0]
|
||||
tool_descr = tool_nbr + ' ' + line.split(';')[1]
|
||||
self.list.append([i, tool_descr, tool_nbr])
|
||||
i = i+1
|
||||
|
||||
class XmlParser:
|
||||
def __init__(self, f):
|
||||
self.tree = []
|
||||
self.list = gtk.ListStore(int, str, str)
|
||||
|
||||
self._parse_file(f)
|
||||
|
||||
def get_parsed_data(self):
|
||||
return self.list
|
||||
|
||||
def _parse_file(self, f):
|
||||
self.tree = ET.parse(f)
|
||||
root = self.tree.getroot()
|
||||
|
||||
i = 0
|
||||
for func in root.iter('function'):
|
||||
gcode = func.find('gcode')
|
||||
|
||||
# create the LinuxCNC hal pin and create mapping dictionary binding incomming events with data and the hal pins
|
||||
if gcode is not None:
|
||||
self.list.append([i, func.text, gcode.text])
|
||||
i = i+1
|
||||
|
||||
class HandlerClass:
|
||||
|
||||
def on_destroy(self,obj,data=None):
|
||||
print "on_destroy, combobox active=%d" %(self.combo.get_active())
|
||||
self.halcomp.exit() # avoid lingering HAL component
|
||||
gtk.main_quit()
|
||||
|
||||
def on_changed(self, combobox, data=None):
|
||||
if self.tool_combo_initiated:
|
||||
model = combobox.get_model()
|
||||
tool_change_cmd = 'M6' + ' ' + model[combobox.get_active()][2] + ' ' + 'G43'
|
||||
self._send_mdi(tool_change_cmd)
|
||||
print tool_change_cmd
|
||||
|
||||
def __init__(self, halcomp, builder, useropts):
|
||||
self.linuxcnc_status = linuxcnc.stat()
|
||||
self.linuxcnc_cmd = linuxcnc.command()
|
||||
self.halcomp = halcomp
|
||||
self.builder = builder
|
||||
self.useropts = useropts
|
||||
|
||||
self.trigger1 = hal_glib.GPin(halcomp.newpin('trigger_pin', hal.HAL_BIT, hal.HAL_IN))
|
||||
self.trigger1.connect('value-changed', self._trigger_change)
|
||||
|
||||
self.trigger2 = hal_glib.GPin(halcomp.newpin('saved-tool-pin', hal.HAL_U32, hal.HAL_IN))
|
||||
self.trigger2.connect('value-changed', self._init_tool_combo)
|
||||
|
||||
func_list = XmlParser('func-btn.xml').get_parsed_data()
|
||||
self.func_combo = self.builder.get_object('func-btn-combo')
|
||||
self.func_combo.set_model(func_list)
|
||||
self.func_combo.set_entry_text_column(1)
|
||||
self.func_combo.set_active(0)
|
||||
|
||||
tool_list = ToolTableParser('tool.tbl').get_parsed_data()
|
||||
self.tool_combo = self.builder.get_object('tool-combo')
|
||||
self.tool_combo.set_model(tool_list)
|
||||
self.tool_combo.set_entry_text_column(2)
|
||||
self.tool_combo.set_active(0)
|
||||
|
||||
renderer_text = gtk.CellRendererText()
|
||||
self.func_combo.pack_start(renderer_text, True)
|
||||
self.tool_combo.pack_start(renderer_text, True)
|
||||
self.tool_combo_initiated = False
|
||||
|
||||
def _trigger_change(self, pin, userdata = None):
|
||||
#setp gladevcp.trigger_pin 1
|
||||
#print "pin value changed to: " + str(pin.get())
|
||||
#print "pin name= " + pin.get_name()
|
||||
#print "pin type= " + str(pin.get_type())
|
||||
#print "active " + str(self.combo.get_active())
|
||||
if pin.get() is True:
|
||||
model = self.func_combo.get_model()
|
||||
self._send_mdi(model[self.func_combo.get_active()][2])
|
||||
|
||||
def _init_tool_combo(self, pin, userdata = None):
|
||||
#setp gladevcp.saved_tool_pin 2
|
||||
self.tool_combo.set_active(pin.get())
|
||||
self.tool_combo_initiated = True
|
||||
|
||||
|
||||
def _ok_for_mdi(self):
|
||||
self.linuxcnc_status.poll()
|
||||
return not self.linuxcnc_status.estop and self.linuxcnc_status.enabled and (self.linuxcnc_status.homed.count(1) == self.linuxcnc_status.joints) and (self.linuxcnc_status.interp_state == linuxcnc.INTERP_IDLE)
|
||||
|
||||
def _send_mdi(self, mdi_cmd_str):
|
||||
if self._ok_for_mdi():
|
||||
self.linuxcnc_cmd.mode(linuxcnc.MODE_MDI)
|
||||
self.linuxcnc_cmd.wait_complete() # wait until mode switch executed
|
||||
self.linuxcnc_cmd.mdi(mdi_cmd_str)
|
||||
|
||||
def get_handlers(halcomp, builder, useropts):
|
||||
|
||||
global debug
|
||||
for cmd in useropts:
|
||||
exec cmd in globals()
|
||||
|
||||
return [HandlerClass(halcomp, builder, useropts)]
|
||||
|
||||
120
my-emco/linuxcnc.var
Normal file
120
my-emco/linuxcnc.var
Normal file
@@ -0,0 +1,120 @@
|
||||
4999 7.000000
|
||||
5161 0.000000
|
||||
5162 0.000000
|
||||
5163 0.000000
|
||||
5164 0.000000
|
||||
5165 0.000000
|
||||
5166 0.000000
|
||||
5167 0.000000
|
||||
5168 0.000000
|
||||
5169 0.000000
|
||||
5181 0.000000
|
||||
5182 0.000000
|
||||
5183 0.000000
|
||||
5184 0.000000
|
||||
5185 0.000000
|
||||
5186 0.000000
|
||||
5187 0.000000
|
||||
5188 0.000000
|
||||
5189 0.000000
|
||||
5210 0.000000
|
||||
5211 0.000000
|
||||
5212 0.000000
|
||||
5213 0.000000
|
||||
5214 0.000000
|
||||
5215 0.000000
|
||||
5216 0.000000
|
||||
5217 0.000000
|
||||
5218 0.000000
|
||||
5219 0.000000
|
||||
5220 1.000000
|
||||
5221 23.092490
|
||||
5222 -2.040103
|
||||
5223 -105.797929
|
||||
5224 0.000000
|
||||
5225 0.000000
|
||||
5226 0.000000
|
||||
5227 0.000000
|
||||
5228 0.000000
|
||||
5229 0.000000
|
||||
5230 0.000000
|
||||
5241 -6.758898
|
||||
5242 32.897192
|
||||
5243 -21.519200
|
||||
5244 0.000000
|
||||
5245 0.000000
|
||||
5246 0.000000
|
||||
5247 0.000000
|
||||
5248 0.000000
|
||||
5249 0.000000
|
||||
5250 0.000000
|
||||
5261 25.241102
|
||||
5262 32.897192
|
||||
5263 -21.519200
|
||||
5264 0.000000
|
||||
5265 0.000000
|
||||
5266 0.000000
|
||||
5267 0.000000
|
||||
5268 0.000000
|
||||
5269 0.000000
|
||||
5270 0.000000
|
||||
5281 57.241102
|
||||
5282 32.897192
|
||||
5283 -21.519200
|
||||
5284 0.000000
|
||||
5285 0.000000
|
||||
5286 0.000000
|
||||
5287 0.000000
|
||||
5288 0.000000
|
||||
5289 0.000000
|
||||
5290 0.000000
|
||||
5301 0.000000
|
||||
5302 0.000000
|
||||
5303 0.000000
|
||||
5304 0.000000
|
||||
5305 0.000000
|
||||
5306 0.000000
|
||||
5307 0.000000
|
||||
5308 0.000000
|
||||
5309 0.000000
|
||||
5310 0.000000
|
||||
5321 0.000000
|
||||
5322 0.000000
|
||||
5323 0.000000
|
||||
5324 0.000000
|
||||
5325 0.000000
|
||||
5326 0.000000
|
||||
5327 0.000000
|
||||
5328 0.000000
|
||||
5329 0.000000
|
||||
5330 0.000000
|
||||
5341 0.000000
|
||||
5342 0.000000
|
||||
5343 0.000000
|
||||
5344 0.000000
|
||||
5345 0.000000
|
||||
5346 0.000000
|
||||
5347 0.000000
|
||||
5348 0.000000
|
||||
5349 0.000000
|
||||
5350 0.000000
|
||||
5361 0.000000
|
||||
5362 0.000000
|
||||
5363 0.000000
|
||||
5364 0.000000
|
||||
5365 0.000000
|
||||
5366 0.000000
|
||||
5367 0.000000
|
||||
5368 0.000000
|
||||
5369 0.000000
|
||||
5370 0.000000
|
||||
5381 0.000000
|
||||
5382 0.000000
|
||||
5383 0.000000
|
||||
5384 0.000000
|
||||
5385 0.000000
|
||||
5386 0.000000
|
||||
5387 0.000000
|
||||
5388 0.000000
|
||||
5389 0.000000
|
||||
5390 0.000000
|
||||
16
my-emco/luber.hal
Normal file
16
my-emco/luber.hal
Normal file
@@ -0,0 +1,16 @@
|
||||
loadusr -Wn my-luber python luber.py -c my-luber luber.xml
|
||||
|
||||
net x-vel joint.0.vel-cmd => my-luber.x-vel
|
||||
net y-vel joint.1.vel-cmd => my-luber.y-vel
|
||||
net z-vel joint.2.vel-cmd => my-luber.z-vel
|
||||
|
||||
setp my-luber.lube-level-ok 1
|
||||
net iocontrol.0.lube-level <= my-luber.lube-level-alarm
|
||||
|
||||
net luber-reset my-luber.reset
|
||||
net luber-cmd my-luber.lube-cmd => parport.0.pin-09-out
|
||||
|
||||
## create the gui signals
|
||||
net luber-acc-dist my-luber.accumulated-distance
|
||||
net luber-ext-req my-luber.lube-ext-req
|
||||
net luber-reset my-luber.reset
|
||||
234
my-emco/luber.py
Normal file
234
my-emco/luber.py
Normal file
@@ -0,0 +1,234 @@
|
||||
#! /usr/bin/python
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
import xml.etree.ElementTree as ET
|
||||
import hal
|
||||
import time
|
||||
from collections import namedtuple
|
||||
|
||||
class Pin:
|
||||
""" Representation of a Pin and it's data"""
|
||||
def __init__(self, type, dir):
|
||||
self.val = 0 # current value of pin, e.g. 1 - on, 0 - off
|
||||
self.type = type # type (string read from xml)
|
||||
self.dir = dir
|
||||
|
||||
def __repr__(self):
|
||||
return 'val: ' + str(self.val) + '\ttype: ' + self.type + '\tdir: ' + self.dir
|
||||
|
||||
class HalAdapter:
|
||||
def __init__(self, name):
|
||||
self.h = hal.component(name)
|
||||
self.h.newpin("velocity", hal.HAL_FLOAT, hal.HAL_OUT)
|
||||
self.h.newpin('x-vel', hal.HAL_FLOAT, hal.HAL_IN)
|
||||
self.h.newpin('y-vel', hal.HAL_FLOAT, hal.HAL_IN)
|
||||
self.h.newpin('z-vel', hal.HAL_FLOAT, hal.HAL_IN)
|
||||
self.h.newpin('lube-level-ok',hal.HAL_BIT, hal.HAL_IN)
|
||||
self.h.newpin('reset', hal.HAL_BIT, hal.HAL_IN)
|
||||
self.h.newpin('lube-ext-req', hal.HAL_BIT, hal.HAL_IN)
|
||||
self.h.newpin('lube-cmd', hal.HAL_BIT, hal.HAL_OUT)
|
||||
self.h.newpin('lube-level-alarm', hal.HAL_BIT, hal.HAL_OUT)
|
||||
self.h.newpin('accumulated-distance', hal.HAL_FLOAT, hal.HAL_OUT)
|
||||
self.h.ready()
|
||||
|
||||
def __repr__(self):
|
||||
tmp_str = ''
|
||||
return tmp_str
|
||||
|
||||
def is_lube_level_ok(self):
|
||||
return self.h['lube-level-ok']
|
||||
|
||||
def is_reset(self):
|
||||
return self.h['reset']
|
||||
|
||||
def is_lube_ext_req(self):
|
||||
return self.h['lube-ext-req']
|
||||
|
||||
def get_velocities(self):
|
||||
velocities = namedtuple("velocities", ["x", "y", "z"])
|
||||
return velocities(
|
||||
self.h['x-vel'],
|
||||
self.h['y-vel'],
|
||||
self.h['z-vel'])
|
||||
|
||||
def set_lube_on(self, request):
|
||||
if request >= 1:
|
||||
self.h['lube-cmd'] = 1
|
||||
else:
|
||||
self.h['lube-cmd'] = 0
|
||||
|
||||
def set_lube_level_alarm(self, level_ok):
|
||||
if level_ok >= 1:
|
||||
self.h['lube-level-alarm'] = 1
|
||||
else:
|
||||
self.h['lube-level-alarm'] = 0
|
||||
|
||||
def set_accumulated_distance(self, d):
|
||||
self.h['accumulated-distance'] = d
|
||||
|
||||
class parameterContainer:
|
||||
def __init__(self, xml_file):
|
||||
self.paramDict = {}
|
||||
self._xmlFile = xml_file
|
||||
|
||||
self.tree = ET.parse(self._xmlFile)
|
||||
self._parse()
|
||||
|
||||
def _parse(self):
|
||||
root = self.tree.getroot()
|
||||
for param in root.iter('parameter'):
|
||||
#print param.attrib['name'], param.attrib['value']
|
||||
self.paramDict[param.attrib['name']] = float(param.attrib['value'])
|
||||
|
||||
def getParam(self, name):
|
||||
if name in self.paramDict:
|
||||
return self.paramDict[name]
|
||||
else:
|
||||
return None
|
||||
|
||||
def getParams(self):
|
||||
return self.paramDict
|
||||
|
||||
def writeToFile(self):
|
||||
for parName in self.paramDict:
|
||||
self._writeToTree(parName, self.paramDict[parName])
|
||||
|
||||
self.tree.write(self._xmlFile)
|
||||
|
||||
def writeParam(self, parName, value):
|
||||
if parName in self.paramDict:
|
||||
self.paramDict[parName] = value
|
||||
|
||||
def _writeToTree(self, parName, value):
|
||||
"""update parameter in xml-tree"""
|
||||
root = self.tree.getroot()
|
||||
|
||||
for param in root.iter('parameter'):
|
||||
if param.attrib['name'] == parName:
|
||||
param.attrib['value'] = str(round(value, 2))
|
||||
break
|
||||
|
||||
|
||||
class LubeControl:
|
||||
def __init__(self, lube_on_time, accumulated_distance, distance_threshold, number_of_lubings):
|
||||
self.lubeOnTime = lube_on_time # [sec]
|
||||
self.total_distance = accumulated_distance # [mm]
|
||||
self.distance_threshold = distance_threshold # [mm]
|
||||
self.numberOfLubings = number_of_lubings
|
||||
|
||||
self.state = 'OFF'
|
||||
self.lubeLevelOkOut = True
|
||||
self._lubeLevelOkIn = True
|
||||
self.prev_time = time.time()
|
||||
|
||||
def calc_dist_from_vel(self, v_x, v_y, v_z):
|
||||
current_time = time.time()
|
||||
time_delta = current_time - self.prev_time
|
||||
|
||||
self.total_distance += abs(v_x) * time_delta
|
||||
self.total_distance += abs(v_y) * time_delta
|
||||
self.total_distance += abs(v_z) * time_delta
|
||||
|
||||
self.prev_time = current_time
|
||||
|
||||
|
||||
def runStateMachine(self, ext_req):
|
||||
currentTime = time.time()
|
||||
if self.total_distance >= self.distance_threshold or ext_req == True:
|
||||
self.state = 'ON'
|
||||
self.timeout = self.lubeOnTime + currentTime
|
||||
self.total_distance = 0
|
||||
self.numberOfLubings += 1
|
||||
|
||||
if self.state == 'ON':
|
||||
if currentTime > self.timeout:
|
||||
#check lube pressure sensor
|
||||
self.lubeLevelOkOut = self._lubeLevelOkIn
|
||||
|
||||
self.state = 'OFF'
|
||||
|
||||
|
||||
def setLubeLevelOK(self, levelOk):
|
||||
self._lubeLevelOkIn = levelOk
|
||||
|
||||
def reset(self):
|
||||
self.total_distance = 0
|
||||
self.state = 'OFF'
|
||||
self.lubeLevelOkOut = True
|
||||
|
||||
def _usage():
|
||||
""" print command line options """
|
||||
print "usage luber.py -h -c<name> <path/>in_file.xml\n"\
|
||||
"in_file # input xml-file describing what knobs and/or button are on the pendant\n"\
|
||||
"-c <name> # name of component in HAL. 'my-luber' default\n"\
|
||||
"-h # Help test"
|
||||
|
||||
def main():
|
||||
xmlFile = 'luber.xml'
|
||||
#xmlFile = ''
|
||||
name = 'my-luber' # default name of component in HAL
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hc:", ["input="])
|
||||
except getopt.GetoptError as err:
|
||||
# print help information and exit:
|
||||
print(err) # will print something like "option -a not recognized"
|
||||
sys.exit(2)
|
||||
|
||||
for o, a in opts:
|
||||
if o == "-h":
|
||||
_usage()
|
||||
sys.exit()
|
||||
elif o == "-c":
|
||||
name = a
|
||||
elif o == "--input":
|
||||
xmlFile = a
|
||||
else:
|
||||
print o
|
||||
assert False, "unhandled option"
|
||||
|
||||
if xmlFile == '':
|
||||
if len(sys.argv) < 2:
|
||||
_usage()
|
||||
sys.exit(2)
|
||||
else:
|
||||
xmlFile = sys.argv[-1]
|
||||
|
||||
p = parameterContainer(xmlFile)
|
||||
|
||||
h = HalAdapter(name)
|
||||
|
||||
totalDistance = p.getParam('totalDistance')
|
||||
distanceThreshold = p.getParam('distanceThreshold')
|
||||
lubeOnTime = p.getParam('lubePulseTime')
|
||||
nbrOfLubings = p.getParam('numberOfLubings')
|
||||
|
||||
lubeCtrl = LubeControl(lubeOnTime, totalDistance, distanceThreshold, nbrOfLubings)
|
||||
|
||||
try:
|
||||
while 1:
|
||||
if h.is_reset():
|
||||
lubeCtrl.reset()
|
||||
|
||||
lubeCtrl.setLubeLevelOK(h.is_lube_level_ok())
|
||||
v = h.get_velocities()
|
||||
lubing_external_request = h.is_lube_ext_req()
|
||||
lubeCtrl.calc_dist_from_vel(v.x, v.y, v.z)
|
||||
|
||||
lubeCtrl.runStateMachine(lubing_external_request)
|
||||
|
||||
h.set_lube_on(lubeCtrl.state == 'ON')
|
||||
h.set_lube_level_alarm(lubeCtrl.lubeLevelOkOut)
|
||||
h.set_accumulated_distance(lubeCtrl.total_distance)
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
p.writeParam('totalDistance', lubeCtrl.total_distance)
|
||||
p.writeParam('numberOfLubings', lubeCtrl.numberOfLubings)
|
||||
p.writeToFile()
|
||||
raise SystemExit
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
6
my-emco/luber.xml
Normal file
6
my-emco/luber.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<luber>
|
||||
<parameter name="lubePulseTime" value="5.0" />
|
||||
<parameter name="totalDistance" value="8621.49" />
|
||||
<parameter name="distanceThreshold" value="10000.0" />
|
||||
<parameter name="numberOfLubings" value="113.0" />
|
||||
</luber>
|
||||
8
my-emco/mpg.xml
Normal file
8
my-emco/mpg.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<mpg>
|
||||
<halpin>"jog-counts"<event>jog</event><type>s32</type></halpin>
|
||||
<halpin>"axis-selector"<event>sela</event><type>s32</type></halpin>
|
||||
<halpin>"scale-selector"<event>sels</event><type>s32</type></halpin>
|
||||
<halpin>"func-btn"<event>func</event><type>bit</type></halpin>
|
||||
<halpin>"prog-run-btn"<event>run</event><type>bit</type></halpin>
|
||||
<halpin>"estop-btn"<event>est</event><type>bit</type></halpin>
|
||||
</mpg>
|
||||
110
my-emco/my-emco.hal
Normal file
110
my-emco/my-emco.hal
Normal file
@@ -0,0 +1,110 @@
|
||||
# Generated by stepconf 1.1 at Mon Nov 4 14:01:20 2019
|
||||
# If you make changes to this file, they will be
|
||||
# overwritten when you run stepconf again
|
||||
loadrt [KINS]KINEMATICS
|
||||
#autoconverted trivkins
|
||||
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=[KINS]JOINTS
|
||||
loadrt hal_parport cfg="0 out"
|
||||
setp parport.0.reset-time 5000
|
||||
loadrt stepgen step_type=0,0,0
|
||||
loadrt pwmgen output_type=0
|
||||
|
||||
addf parport.0.read base-thread
|
||||
addf stepgen.make-pulses base-thread
|
||||
addf pwmgen.make-pulses base-thread
|
||||
addf parport.0.write base-thread
|
||||
addf parport.0.reset base-thread
|
||||
|
||||
addf stepgen.capture-position servo-thread
|
||||
addf motion-command-handler servo-thread
|
||||
addf motion-controller servo-thread
|
||||
addf stepgen.update-freq servo-thread
|
||||
addf pwmgen.update servo-thread
|
||||
|
||||
net spindle-cmd-rpm <= spindle.0.speed-out
|
||||
#net spindle-cmd-rpm pwmgen.0.value <= spindle.0.speed-out
|
||||
net spindle-on <= spindle.0.on => pwmgen.0.enable
|
||||
net spindle-pwm <= pwmgen.0.pwm
|
||||
|
||||
setp pwmgen.0.pwm-freq 100.0
|
||||
setp pwmgen.0.scale 4500 #duty_cycle = (value/scale) + offset, with 1.0 meaning 100%
|
||||
#setp pwmgen.0.offset 0.02
|
||||
|
||||
setp pwmgen.0.dither-pwm true
|
||||
|
||||
net spindle-cmd-rpm-abs <= spindle.0.speed-out-abs
|
||||
net spindle-cmd-rps <= spindle.0.speed-out-rps
|
||||
net spindle-cmd-rps-abs <= spindle.0.speed-out-rps-abs
|
||||
net spindle-cw <= spindle.0.forward
|
||||
|
||||
net spindle-pwm => parport.0.pin-16-out
|
||||
net xstep => parport.0.pin-02-out
|
||||
setp parport.0.pin-02-out-reset 1
|
||||
setp parport.0.pin-03-out-invert 1
|
||||
net xdir => parport.0.pin-03-out
|
||||
net ystep => parport.0.pin-04-out
|
||||
setp parport.0.pin-04-out-reset 1
|
||||
net ydir => parport.0.pin-05-out
|
||||
net zstep => parport.0.pin-06-out
|
||||
setp parport.0.pin-06-out-reset 1
|
||||
setp parport.0.pin-07-out-invert 1
|
||||
net zdir => parport.0.pin-07-out
|
||||
net spindle-cw => parport.0.pin-08-out
|
||||
net home-z <= parport.0.pin-10-in-not
|
||||
net home-y <= parport.0.pin-11-in-not
|
||||
net home-x <= parport.0.pin-12-in-not
|
||||
#net max-home-y <= parport.0.pin-11-in-not
|
||||
#net max-home-x <= parport.0.pin-12-in-not
|
||||
|
||||
setp stepgen.0.position-scale [JOINT_0]SCALE
|
||||
setp stepgen.0.steplen 1
|
||||
setp stepgen.0.stepspace 0
|
||||
setp stepgen.0.dirhold 35000
|
||||
setp stepgen.0.dirsetup 35000
|
||||
setp stepgen.0.maxaccel [JOINT_0]STEPGEN_MAXACCEL
|
||||
net xpos-cmd joint.0.motor-pos-cmd => stepgen.0.position-cmd
|
||||
net xpos-fb stepgen.0.position-fb => joint.0.motor-pos-fb
|
||||
net xstep <= stepgen.0.step
|
||||
net xdir <= stepgen.0.dir
|
||||
net xenable joint.0.amp-enable-out => stepgen.0.enable
|
||||
#net max-home-x => joint.0.home-sw-in
|
||||
#net max-home-x => joint.0.pos-lim-sw-in
|
||||
net home-x => joint.0.home-sw-in
|
||||
|
||||
setp stepgen.1.position-scale [JOINT_1]SCALE
|
||||
setp stepgen.1.steplen 1
|
||||
setp stepgen.1.stepspace 0
|
||||
setp stepgen.1.dirhold 35000
|
||||
setp stepgen.1.dirsetup 35000
|
||||
setp stepgen.1.maxaccel [JOINT_1]STEPGEN_MAXACCEL
|
||||
net ypos-cmd joint.1.motor-pos-cmd => stepgen.1.position-cmd
|
||||
net ypos-fb stepgen.1.position-fb => joint.1.motor-pos-fb
|
||||
net ystep <= stepgen.1.step
|
||||
net ydir <= stepgen.1.dir
|
||||
net yenable joint.1.amp-enable-out => stepgen.1.enable
|
||||
#net max-home-y => joint.1.home-sw-in
|
||||
#net max-home-y => joint.1.pos-lim-sw-in
|
||||
net home-y => joint.1.home-sw-in
|
||||
|
||||
setp stepgen.2.position-scale [JOINT_2]SCALE
|
||||
setp stepgen.2.steplen 1
|
||||
setp stepgen.2.stepspace 0
|
||||
setp stepgen.2.dirhold 35000
|
||||
setp stepgen.2.dirsetup 35000
|
||||
setp stepgen.2.maxaccel [JOINT_2]STEPGEN_MAXACCEL
|
||||
net zpos-cmd joint.2.motor-pos-cmd => stepgen.2.position-cmd
|
||||
net zpos-fb stepgen.2.position-fb => joint.2.motor-pos-fb
|
||||
net zstep <= stepgen.2.step
|
||||
net zdir <= stepgen.2.dir
|
||||
net zenable joint.2.amp-enable-out => stepgen.2.enable
|
||||
net home-z => joint.2.home-sw-in
|
||||
|
||||
# moved to custom.hal
|
||||
#net estop-out <= iocontrol.0.user-enable-out
|
||||
#net estop-out => iocontrol.0.emc-enable-in
|
||||
|
||||
loadusr -W hal_manualtoolchange
|
||||
net tool-change iocontrol.0.tool-change => hal_manualtoolchange.change
|
||||
net tool-changed iocontrol.0.tool-changed <= hal_manualtoolchange.changed
|
||||
net tool-number iocontrol.0.tool-prep-number => hal_manualtoolchange.number
|
||||
net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared
|
||||
169
my-emco/my-emco.ini
Normal file
169
my-emco/my-emco.ini
Normal file
@@ -0,0 +1,169 @@
|
||||
# This config file was created 2021-03-08 20:17:44.282043 by the update_ini script
|
||||
# The original config files may be found in the /home/johan/linuxcnc/configs/my-emco/my-emco.old directory
|
||||
|
||||
# Generated by stepconf 1.1 at Mon Nov 4 14:01:20 2019
|
||||
# If you make changes to this file, they will be
|
||||
# overwritten when you run stepconf again
|
||||
|
||||
[EMC]
|
||||
# The version string for this INI file.
|
||||
VERSION = 1.1
|
||||
|
||||
MACHINE = my-emco
|
||||
DEBUG = 0
|
||||
|
||||
[DISPLAY]
|
||||
DISPLAY = axis
|
||||
EDITOR = gedit
|
||||
POSITION_OFFSET = RELATIVE
|
||||
POSITION_FEEDBACK = ACTUAL
|
||||
ARCDIVISION = 64
|
||||
GRIDS = 10mm 20mm 50mm 100mm
|
||||
MAX_FEED_OVERRIDE = 1.2
|
||||
MIN_SPINDLE_OVERRIDE = 0.5
|
||||
MAX_SPINDLE_OVERRIDE = 1.2
|
||||
DEFAULT_LINEAR_VELOCITY = 25.0
|
||||
MIN_LINEAR_VELOCITY = 0
|
||||
MAX_LINEAR_VELOCITY = 25.00
|
||||
INTRO_GRAPHIC = linuxcnc.gif
|
||||
INTRO_TIME = 5
|
||||
PROGRAM_PREFIX = /home/johan/linuxcnc/nc_files
|
||||
INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm
|
||||
GLADEVCP= -u ./gladevcp-handler.py ./my-emco.ui
|
||||
|
||||
[FILTER]
|
||||
PROGRAM_EXTENSION = .png,.gif,.jpg Greyscale Depth Image
|
||||
PROGRAM_EXTENSION = .py Python Script
|
||||
png = image-to-gcode
|
||||
gif = image-to-gcode
|
||||
jpg = image-to-gcode
|
||||
py = python
|
||||
|
||||
[RS274NGC]
|
||||
PARAMETER_FILE=linuxcnc.var
|
||||
SUBROUTINE_PATH=custom-m-codes
|
||||
USER_M_PATH=custom-m-codes
|
||||
REMAP=M6 modalgroup=6 ngc=mychange
|
||||
|
||||
[EMCMOT]
|
||||
EMCMOT = motmod
|
||||
COMM_TIMEOUT = 1.0
|
||||
BASE_PERIOD = 35000
|
||||
SERVO_PERIOD = 1000000
|
||||
|
||||
[TASK]
|
||||
TASK = milltask
|
||||
CYCLE_TIME = 0.010
|
||||
|
||||
[HAL]
|
||||
HALUI = halui
|
||||
HALFILE = my-emco.hal
|
||||
HALFILE = custom.hal
|
||||
HALFILE = luber.hal
|
||||
POSTGUI_HALFILE = custom_postgui.hal
|
||||
|
||||
[HALUI]
|
||||
# add halui MDI commands here (max 64)
|
||||
MDI_COMMAND = G53 G0 X0 Y0 Z0 ;cmd 0 "return to home" used by MPG
|
||||
MDI_COMMAND = G53 G0 Z88 ;cmd 1 "tool change position"
|
||||
MDI_COMMAND = M61 Q#4999 G43 ;cmd 2 called after homing to set tool saved at last tool change
|
||||
MDI_COMMAND = M68 E0 Q#4999 ;cmd 3 called after homing to output current tool on analog signal
|
||||
|
||||
[TRAJ]
|
||||
COORDINATES = XYZ
|
||||
LINEAR_UNITS = mm
|
||||
ANGULAR_UNITS = degree
|
||||
DEFAULT_LINEAR_VELOCITY = 25.0
|
||||
MAX_LINEAR_VELOCITY = 25.00
|
||||
DEFAULT_LINEAR_ACCELERATION = 150.0
|
||||
MAX_LINEAR_ACCELERATION = 250.0
|
||||
JOINTS = 3
|
||||
HOME = 0 0 0
|
||||
|
||||
[EMCIO]
|
||||
EMCIO = io
|
||||
CYCLE_TIME = 0.100
|
||||
TOOL_TABLE = tool.tbl
|
||||
|
||||
[KINS]
|
||||
KINEMATICS = trivkins coordinates=XYZ
|
||||
#This is a best-guess at the number of joints, it should be checked
|
||||
JOINTS = 3
|
||||
|
||||
[AXIS_X]
|
||||
MIN_LIMIT = -85.0
|
||||
MAX_LIMIT = 92.0
|
||||
MAX_VELOCITY = 23.75
|
||||
MAX_ACCELERATION = 250.0
|
||||
# vi testar att sänka MAX_ACCELERATION = 750.0
|
||||
|
||||
[JOINT_0]
|
||||
TYPE = LINEAR
|
||||
HOME = 0.0
|
||||
MAX_VELOCITY = 23.75
|
||||
MAX_ACCELERATION = 250.0
|
||||
STEPGEN_MAXACCEL = 300
|
||||
#MAX_ACCELERATION = 750.0
|
||||
#STEPGEN_MAXACCEL = 937.5
|
||||
SCALE = 1000.0
|
||||
FERROR = 1
|
||||
MIN_FERROR = .25
|
||||
MIN_LIMIT = -85.0
|
||||
MAX_LIMIT = 92.0
|
||||
HOME_OFFSET = 93.000000
|
||||
HOME_SEARCH_VEL = 5.500000
|
||||
HOME_LATCH_VEL = 0.500000
|
||||
HOME_IGNORE_LIMITS = YES
|
||||
HOME_SEQUENCE = 1
|
||||
|
||||
[AXIS_Y]
|
||||
#tog bort givarna som ändlägesstopp, används bara vid homing
|
||||
#kunde lägga till lite på pos-y...
|
||||
#MIN_LIMIT = -45.0
|
||||
#MAX_LIMIT = 45.0
|
||||
MIN_LIMIT = -43.0
|
||||
MAX_LIMIT = 61.0
|
||||
MAX_VELOCITY = 23.75
|
||||
#MAX_ACCELERATION = 750.0
|
||||
MAX_ACCELERATION = 250.0
|
||||
|
||||
[JOINT_1]
|
||||
TYPE = LINEAR
|
||||
HOME = 0.0
|
||||
MAX_VELOCITY = 23.75
|
||||
MAX_ACCELERATION = 250.0
|
||||
STEPGEN_MAXACCEL = 300
|
||||
#MAX_ACCELERATION = 750.0
|
||||
#STEPGEN_MAXACCEL = 937.5
|
||||
SCALE = 1000.0
|
||||
FERROR = 1
|
||||
MIN_FERROR = 0.25
|
||||
MIN_LIMIT = -43.0
|
||||
MAX_LIMIT = 61.0
|
||||
HOME_OFFSET = 46.000000
|
||||
HOME_SEARCH_VEL = 5.500000
|
||||
HOME_LATCH_VEL = 0.500000
|
||||
HOME_IGNORE_LIMITS = YES
|
||||
HOME_SEQUENCE = 1
|
||||
|
||||
[AXIS_Z]
|
||||
MIN_LIMIT = -112.0
|
||||
MAX_LIMIT = 88.0
|
||||
MAX_VELOCITY = 5.0
|
||||
MAX_ACCELERATION = 25.0
|
||||
|
||||
[JOINT_2]
|
||||
TYPE = LINEAR
|
||||
HOME = 0.0
|
||||
MAX_VELOCITY = 5.0
|
||||
MAX_ACCELERATION = 25.0
|
||||
STEPGEN_MAXACCEL = 31.25
|
||||
SCALE = 1000.0
|
||||
FERROR = 1
|
||||
MIN_FERROR = .25
|
||||
MIN_LIMIT = -112.0
|
||||
MAX_LIMIT = 88.0
|
||||
HOME_OFFSET = 0.0
|
||||
HOME_SEARCH_VEL = 2.500000
|
||||
HOME_LATCH_VEL = 0.500000
|
||||
HOME_SEQUENCE = 0
|
||||
508
my-emco/my-emco.ui
Normal file
508
my-emco/my-emco.ui
Normal file
@@ -0,0 +1,508 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gladevcp 0.0 -->
|
||||
<!-- interface-requires gtk+ 2.12 -->
|
||||
<!-- interface-naming-policy project-wide -->
|
||||
<object class="EMC_Action_MDI" id="hal_action_mdi1">
|
||||
<property name="label" translatable="yes">Goto Machine Zero</property>
|
||||
<property name="command">G53 G0 X0 Y0 Z0</property>
|
||||
</object>
|
||||
<object class="EMC_Action_MDI" id="hal_action_mdi2">
|
||||
<property name="command">G53 G0 Z88</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">5</property>
|
||||
<property name="bottom_padding">5</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="HAL_HBar" id="spindle-rpm-hbar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="bg_color">#bebebebebebe</property>
|
||||
<property name="max">6000</property>
|
||||
<property name="target_width">1</property>
|
||||
<property name="value">0.019999999552965164</property>
|
||||
<property name="z0_border">0.69999998807907104</property>
|
||||
<property name="z0_color">#0000ffff0000</property>
|
||||
<property name="z1_border">0.89999997615814209</property>
|
||||
<property name="z1_color">#ffffffff0000</property>
|
||||
<property name="z2_color">#ffff00000000</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTable" id="table2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="spindle-cm">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Spindle cmd:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Label" id="spindle-ref-rpm">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="label_pin_type">1</property>
|
||||
<property name="text_template">%.1f rpm</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="spindle-actua">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Spindle actual:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Label" id="spindle-curr-rpm">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="label_pin_type">1</property>
|
||||
<property name="text_template">%.1f rpm</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="spindle-at-speed">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Spindle at Speed:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_LED" id="led-spindle-at-speed">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="led_blink_rate">0</property>
|
||||
<property name="pick_color_off">#ffff00000000</property>
|
||||
<property name="pick_color_on">#0000ffff0000</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_CheckButton" id="wd-chkbtn">
|
||||
<property name="label" translatable="yes">Spindle Feedback Watchdog Enable</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1text">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Spindle</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">5</property>
|
||||
<property name="bottom_padding">5</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<object class="HAL_Table" id="tool">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="current-tool-lable">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Current Tool:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Label" id="current-tool">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="set-tool">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Set Tool:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_ComboBox" id="tool-combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="active">0</property>
|
||||
<property name="button_sensitivity">on</property>
|
||||
<property name="column">0</property>
|
||||
<signal name="changed" handler="on_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext2"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label2text">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Tool</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">5</property>
|
||||
<property name="bottom_padding">5</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<object class="HAL_HBox" id="commands">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">20</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="HAL_Button" id="rth-button">
|
||||
<property name="label" translatable="yes">Goto Machine Zero</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Button" id="tc-button">
|
||||
<property name="label" translatable="yes">Goto Tool Change Position</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label4text">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Commands</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">5</property>
|
||||
<property name="bottom_padding">5</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<object class="HAL_Table" id="mpg">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="mpg-func-btn">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Func Button:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_ComboBox" id="func-btn-combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="active">0</property>
|
||||
<property name="column">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="cellrenderertext1"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>MPG</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame5">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="top_padding">5</property>
|
||||
<property name="bottom_padding">5</property>
|
||||
<property name="left_padding">12</property>
|
||||
<property name="right_padding">12</property>
|
||||
<child>
|
||||
<object class="HAL_Table" id="lube">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">20</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="accumulated-distance">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Accumulated Distance:</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lube-cmd-lable">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Lube Pump:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Button" id="lube-reset-btn">
|
||||
<property name="label" translatable="yes">Reset Saved Data</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Label" id="acc-distance">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">label</property>
|
||||
<property name="label_pin_type">1</property>
|
||||
<property name="text_template">%.2f mm</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_LED" id="lube-cmd">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="led_blink_rate">0</property>
|
||||
<property name="pick_color_off">#ffff00000000</property>
|
||||
<property name="pick_color_on">#0000ffff0000</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="HAL_Button" id="lube-cmd-btn">
|
||||
<property name="label" translatable="yes">Lube</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label1text1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes"><b>Lube</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
4
my-emco/postgui_backup.hal
Normal file
4
my-emco/postgui_backup.hal
Normal file
@@ -0,0 +1,4 @@
|
||||
# Include your customized HAL commands here
|
||||
# The commands in this file are run after the AXIS GUI (including PyVCP panel) starts
|
||||
|
||||
sets spindle-at-speed true
|
||||
281
my-emco/serialEventHandler.py
Normal file
281
my-emco/serialEventHandler.py
Normal file
@@ -0,0 +1,281 @@
|
||||
#! /usr/bin/python
|
||||
"""usage serialEventHanlder.py -h -c <name> -d/--debug= <level> -p/--port= <serial port> <path/>in_file.xml
|
||||
in_file - input xml-file describing what knobs and/or button are on the pendant
|
||||
-c <name> # name of component in HAL. 'my-mpg' default
|
||||
-d/--debug= <level> # debug level, default 0
|
||||
-p/--port= <serial port> # serial port to use. '/dev/ttyUSB0' default
|
||||
-h # Help
|
||||
python serialEventHandler.py -w mpg_pendant/config/mpg.xml
|
||||
"""
|
||||
|
||||
### https://docs.python.org/2/library/xml.etree.elementtree.html
|
||||
|
||||
import time
|
||||
import getopt
|
||||
import sys
|
||||
import comms
|
||||
import xml.etree.ElementTree as ET
|
||||
import hal
|
||||
|
||||
class Pin:
|
||||
""" Representation of a Pin and it's data"""
|
||||
def __init__(self, name, type):
|
||||
self.name = name # HAL pin name
|
||||
self.val = 0 # current value of pin, e.g. 1 - on, 0 - off
|
||||
self.type = type # type (string read from xml)
|
||||
|
||||
def __repr__(self):
|
||||
return 'pin name: ' + self.name + '\tval: ' + str(self.val) + '\ttype: ' + self.type
|
||||
|
||||
class ComponentWrapper:
|
||||
def __init__(self, name):
|
||||
self.pin_dict = {} # dictionary used to map event to pin
|
||||
self.hal = hal.component(name) # instanciate the HAL-component
|
||||
|
||||
def __repr__(self):
|
||||
tmp_str = ''
|
||||
for k in self.pin_dict:
|
||||
tmp_str += 'event: ' + k + '\t' + str(self.pin_dict[k]) + '\n'
|
||||
return tmp_str
|
||||
|
||||
def __getitem__(self, name):
|
||||
if name in self.pin_dict:
|
||||
return self.pin_dict[name].val
|
||||
|
||||
def __setitem__(self, name, val):
|
||||
self.set_pin(name, val)
|
||||
|
||||
def add_pin(self, name, hal_name, type):
|
||||
self.pin_dict[name] = Pin(hal_name, type)
|
||||
self._add_hal_pin(hal_name, type)
|
||||
|
||||
def event_set_pin(self, event):
|
||||
""" updates pin value with new data
|
||||
input: pin name, set value'
|
||||
output: nothing. """
|
||||
if event.name in self.pin_dict:
|
||||
try:
|
||||
self.pin_dict[event.name].val = self._type_saturate(self.pin_dict[event.name].type, int(event.data))
|
||||
except ValueError:
|
||||
print 'bad event'
|
||||
|
||||
|
||||
def set_pin(self, name, value):
|
||||
""" updates pin value with new data
|
||||
input: pin name, set value'
|
||||
output: nothing. """
|
||||
if name in self.pin_dict:
|
||||
try:
|
||||
self.pin_dict[name].val = self._type_saturate(self.pin_dict[name].type, int(value))
|
||||
except ValueError:
|
||||
print 'bad event'
|
||||
|
||||
def setReady(self):
|
||||
self.hal.ready()
|
||||
|
||||
def update_hal(self):
|
||||
for key in self.pin_dict:
|
||||
self.hal[self.pin_dict[key].name] = self.pin_dict[key].val
|
||||
|
||||
def _add_hal_pin(self, hal_name, type):
|
||||
self.hal.newpin(hal_name, self._get_hal_type(type), hal.HAL_OUT) # create the user space HAL-pin
|
||||
|
||||
def _type_saturate(self, type, val):
|
||||
""" helper function to convert type read from xml to HAL-type """
|
||||
retVal = 0
|
||||
|
||||
if type == 'bit':
|
||||
if val >= 1:
|
||||
retVal = 1
|
||||
|
||||
if type == 'float':
|
||||
retVal = val
|
||||
|
||||
if type == 's32':
|
||||
retVal = val
|
||||
|
||||
if type == 'u32':
|
||||
retVal = val
|
||||
|
||||
return retVal
|
||||
|
||||
def _get_hal_type(self, str):
|
||||
""" helper function to convert type read from xml to HAL-type """
|
||||
retVal = ''
|
||||
|
||||
if str == 'bit':
|
||||
retVal = hal.HAL_BIT
|
||||
|
||||
if str == 'float':
|
||||
retVal = hal.HAL_FLOAT
|
||||
|
||||
if str == 's32':
|
||||
retVal = hal.HAL_S32
|
||||
|
||||
if str == 'u32':
|
||||
retVal = hal.HAL_U32
|
||||
return retVal
|
||||
|
||||
class OptParser:
|
||||
def __init__(self, argv):
|
||||
self.xml_file = '' # input xml-file describing what knobs and/or button are on the pendant
|
||||
self.name = 'my-mpg' # default name of component in HAL
|
||||
self.port = '/dev/ttyUSB0' # default serial port to use
|
||||
self.watchdog_reset = False
|
||||
|
||||
self._get_options(argv)
|
||||
|
||||
def __repr__(self):
|
||||
return 'xml_file: ' + self.xml_file + '\tname: ' + self.name + '\tport: ' + self.port
|
||||
|
||||
def _get_options(self, argv):
|
||||
try:
|
||||
opts, args = getopt.getopt(argv, "hwp:c:", ["input=", "port="])
|
||||
except getopt.GetoptError as err:
|
||||
# print help information and exit:
|
||||
print(err) # will print something like "option -a not recognized"
|
||||
sys.exit(2)
|
||||
|
||||
### parse input command line
|
||||
for o, a in opts:
|
||||
if o == "-h":
|
||||
self._usage()
|
||||
sys.exit()
|
||||
if o == "-c":
|
||||
self.name = a
|
||||
elif o == "--input":
|
||||
self.xml_file = a
|
||||
elif o in ("-p", "--port"):
|
||||
self.port = a
|
||||
elif o == "-w":
|
||||
self.watchdog_reset = True
|
||||
else:
|
||||
print o, a
|
||||
assert False, "unhandled option"
|
||||
|
||||
if self.xml_file == '':
|
||||
if len(sys.argv) < 2:
|
||||
self._usage()
|
||||
sys.exit(2)
|
||||
else:
|
||||
self.xml_file = argv[-1]
|
||||
|
||||
def get_name(self):
|
||||
return self.name
|
||||
|
||||
def get_port(self):
|
||||
return self.port
|
||||
|
||||
def get_XML_file(self):
|
||||
return self.xml_file
|
||||
|
||||
def get_watchdog_reset(self):
|
||||
return self.watchdog_reset
|
||||
|
||||
def _usage(self):
|
||||
""" print command line options """
|
||||
print "usage serialEventHandler.py -h -c <name> -d/--debug=<level> -p/--port= <serial port> <path/>in_file.xml\n"\
|
||||
"in_file - input xml-file describing what knobs and/or button are on the pendant\n"\
|
||||
"-c <name> # name of component in HAL. 'mpg' default\n"\
|
||||
"-p/--port= <serial port> # default serial port to use. '/dev/ttyS2' default\n"\
|
||||
"-w # start watchdog deamon" \
|
||||
"-h # Help test"
|
||||
|
||||
class XmlParser:
|
||||
def __init__(self, f):
|
||||
self.tree = []
|
||||
self.pin_dict = {}
|
||||
|
||||
self._parse_file(f)
|
||||
|
||||
def __repr__(self):
|
||||
tmp_str = ''
|
||||
|
||||
for k in self.pin_dict:
|
||||
tmp_str += 'event: ' + k + '\t' + str(self.pin_dict[k]) + '\n'
|
||||
return tmp_str
|
||||
|
||||
def get_parsed_data(self):
|
||||
return self.pin_dict
|
||||
|
||||
def _parse_file(self, f):
|
||||
self.tree = ET.parse(f)
|
||||
root = self.tree.getroot()
|
||||
|
||||
for halpin in root.iter('halpin'):
|
||||
type = halpin.find('type')
|
||||
event = halpin.find('event')
|
||||
|
||||
# create the LinuxCNC hal pin and create mapping dictionary binding incomming events with data and the hal pins
|
||||
if type is not None and event is not None:
|
||||
if self._check_supported_HAL_type(type.text) == True:
|
||||
self.pin_dict[event.text] = Pin(halpin.text.strip('"'), type.text)
|
||||
|
||||
def _check_supported_HAL_type(self, str):
|
||||
""" helper function to check if type is supported """
|
||||
retVal = False
|
||||
|
||||
if str == 'bit' or str == 'float' or str == 's32' or str == 'u32':
|
||||
retVal = True
|
||||
|
||||
return retVal
|
||||
|
||||
class BrokeeContainer:
|
||||
def __init__(self, handler, args):
|
||||
self.handler = handler
|
||||
self.args = args
|
||||
|
||||
class EventBroker:
|
||||
def __init__(self):
|
||||
self.brokee_dict = {}
|
||||
self.received_event = comms.Message('')
|
||||
|
||||
def attach_handler(self, event_name, handler, args = ()):
|
||||
self.brokee_dict[event_name] = BrokeeContainer(handler, args)
|
||||
|
||||
def handle_event(self, event):
|
||||
self.received_event.copy(event)
|
||||
|
||||
if event.name in self.brokee_dict:
|
||||
self.brokee_dict[event.name].handler(*self.brokee_dict[event.name].args)
|
||||
|
||||
################################################
|
||||
def main():
|
||||
optParser = OptParser(sys.argv[1:])
|
||||
componentName = optParser.get_name()
|
||||
portName = optParser.get_port()
|
||||
xmlFile = optParser.get_XML_file()
|
||||
print optParser
|
||||
|
||||
xmlParser = XmlParser(xmlFile)
|
||||
|
||||
c = ComponentWrapper(componentName) #HAL adaptor
|
||||
eventBroker = EventBroker() #maps incomming events to the correct handler
|
||||
serialEventGenerator = comms.instrument(portName, eventBroker.handle_event, True, 5, 1) #serial adaptor
|
||||
|
||||
# add/create the HAL-pins from parsed xml and attach them to the adaptor event handler
|
||||
parsedXmlDict = xmlParser.get_parsed_data()
|
||||
for key in parsedXmlDict:
|
||||
c.add_pin(key, parsedXmlDict[key].name, parsedXmlDict[key].type)
|
||||
eventBroker.attach_handler(key, c.event_set_pin, args = (eventBroker.received_event,))
|
||||
# TODO eventBroker.attach_handler(key, c.set_pin, args = (eventBroker.received_event.name, eventBroker.received_event.data))
|
||||
|
||||
print c
|
||||
|
||||
# ready signal to HAL, component and it's pins are ready created
|
||||
c.setReady()
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
try:
|
||||
while 1:
|
||||
serialEventGenerator.readMessages() #blocks until '\n' received or timeout
|
||||
c.update_hal()
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
301
my-emco/test_ladder.clp
Normal file
301
my-emco/test_ladder.clp
Normal file
@@ -0,0 +1,301 @@
|
||||
_FILES_CLASSICLADDER
|
||||
_FILE-rung_1.csv
|
||||
#VER=2.0
|
||||
#LABEL=
|
||||
#COMMENT=
|
||||
#PREVRUNG=2
|
||||
#NEXTRUNG=2
|
||||
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/2 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 50-0-60/0
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/3 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 50-0-60/1
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/4 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 50-0-60/2
|
||||
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
|
||||
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0
|
||||
_/FILE-rung_1.csv
|
||||
_FILE-sections.csv
|
||||
#VER=1.0
|
||||
#NAME000=Prog1
|
||||
000,0,-1,1,2,0
|
||||
_/FILE-sections.csv
|
||||
_FILE-counters.csv
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
_/FILE-counters.csv
|
||||
_FILE-arithmetic_expressions.csv
|
||||
#VER=2.0
|
||||
0000,@310/0@=100
|
||||
0002,@270/0@=2
|
||||
0003,@270/0@=1
|
||||
0004,@270/0@=0
|
||||
0005,@270/1@=1
|
||||
0006,@270/1@=2
|
||||
0007,@270/1@=3
|
||||
0008,@310/0@=100
|
||||
0009,@310/0@=10
|
||||
0010,@270/1@=0
|
||||
0011,@310/0@=1
|
||||
_/FILE-arithmetic_expressions.csv
|
||||
_FILE-timers.csv
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
_/FILE-timers.csv
|
||||
_FILE-monostables.csv
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
1,0
|
||||
_/FILE-monostables.csv
|
||||
_FILE-ioconf.csv
|
||||
#VER=1.0
|
||||
_/FILE-ioconf.csv
|
||||
_FILE-modbusioconf.csv
|
||||
#VER=1.0
|
||||
_/FILE-modbusioconf.csv
|
||||
_FILE-sequential.csv
|
||||
#VER=1.0
|
||||
_/FILE-sequential.csv
|
||||
_FILE-symbols.csv
|
||||
#VER=1.0
|
||||
%I0,%func-btn,no signal connected
|
||||
%I1,%f-disabl,
|
||||
%I2,%f-enable,
|
||||
%I3,%f-move1,
|
||||
%I4,%f-move2,
|
||||
%I5,%I5,
|
||||
%I6,%I6,
|
||||
%I7,%I7,
|
||||
%I8,%I8,
|
||||
%I9,%I9,
|
||||
%I10,%I10,
|
||||
%I11,%I11,
|
||||
%I12,%I12,
|
||||
%I13,%I13,
|
||||
%I14,%I14,
|
||||
%Q0,%x-axis,
|
||||
%Q1,%y-axis,
|
||||
%Q2,%z-axis,
|
||||
%Q3,%vel-mode,
|
||||
%Q4,%Q4,
|
||||
%Q5,%Q5,
|
||||
%Q6,%Q6,
|
||||
%Q7,%Q7,
|
||||
%Q8,%Q8,
|
||||
%Q9,%Q9,
|
||||
%Q10,%Q10,
|
||||
%Q11,%Q11,
|
||||
%Q12,%Q12,
|
||||
%Q13,%Q13,
|
||||
%Q14,%Q14,
|
||||
%B0,%B0,
|
||||
%B1,%B1,
|
||||
%B2,%B2,
|
||||
%B3,%B3,
|
||||
%B4,%B4,
|
||||
%B5,%B5,
|
||||
%B6,%B6,
|
||||
%B7,%B7,
|
||||
%B8,%B8,
|
||||
%B9,%B9,
|
||||
%B10,%B10,
|
||||
%B11,%B11,
|
||||
%B12,%B12,
|
||||
%B13,%B13,
|
||||
%B14,%B14,
|
||||
%B15,%B15,
|
||||
%B16,%B16,
|
||||
%B17,%B17,
|
||||
%B18,%B18,
|
||||
%B19,%B19,
|
||||
%W0,%W0,
|
||||
%W1,%W1,
|
||||
%W2,%W2,
|
||||
%W3,%W3,
|
||||
%W4,%W4,
|
||||
%W5,%W5,
|
||||
%W6,%W6,
|
||||
%W7,%W7,
|
||||
%W8,%W8,
|
||||
%W9,%W9,
|
||||
%W10,%W10,
|
||||
%W11,%W11,
|
||||
%W12,%W12,
|
||||
%W13,%W13,
|
||||
%W14,%W14,
|
||||
%W15,%W15,
|
||||
%W16,%W16,
|
||||
%W17,%W17,
|
||||
%W18,%W18,
|
||||
%W19,%W19,
|
||||
%IW0,%sel-a,
|
||||
%IW1,%sel-s,
|
||||
%IW2,%IW2,
|
||||
%IW3,%IW3,
|
||||
%IW4,%IW4,
|
||||
%IW5,%IW5,
|
||||
%IW6,%IW6,
|
||||
%IW7,%IW7,
|
||||
%IW8,%IW8,
|
||||
%IW9,%IW9,
|
||||
%QW0,%QW0,
|
||||
%QW1,%QW1,
|
||||
%QW2,%QW2,
|
||||
%QW3,%QW3,
|
||||
%QW4,%QW4,
|
||||
%QW5,%QW5,
|
||||
%QW6,%QW6,
|
||||
%QW7,%QW7,
|
||||
%QW8,%QW8,
|
||||
%QW9,%QW9,
|
||||
%IF0,%IF0,
|
||||
%IF1,%IF1,
|
||||
%IF2,%IF2,
|
||||
%IF3,%IF3,
|
||||
%IF4,%IF4,
|
||||
%IF5,%IF5,
|
||||
%IF6,%IF6,
|
||||
%IF7,%IF7,
|
||||
%IF8,%IF8,
|
||||
%IF9,%IF9,
|
||||
%QF0,%scale,
|
||||
%QF1,%QF1,
|
||||
%QF2,%QF2,
|
||||
%QF3,%QF3,
|
||||
%QF4,%QF4,
|
||||
%QF5,%QF5,
|
||||
%QF6,%QF6,
|
||||
%QF7,%QF7,
|
||||
%QF8,%QF8,
|
||||
%QF9,%QF9,
|
||||
%T0,%T0,Old Timer
|
||||
%T1,%T1,Old Timer
|
||||
%T2,%T2,Old Timer
|
||||
%T3,%T3,Old Timer
|
||||
%T4,%T4,Old Timer
|
||||
%T5,%T5,Old Timer
|
||||
%T6,%T6,Old Timer
|
||||
%T7,%T7,Old Timer
|
||||
%T8,%T8,Old Timer
|
||||
%T9,%T9,Old Timer
|
||||
%TM0,%TM0,New Timer
|
||||
%TM1,%TM1,New Timer
|
||||
%TM2,%TM2,New Timer
|
||||
%TM3,%TM3,New Timer
|
||||
%TM4,%TM4,New Timer
|
||||
%TM5,%TM5,New Timer
|
||||
%TM6,%TM6,New Timer
|
||||
%TM7,%TM7,New Timer
|
||||
%TM8,%TM8,New Timer
|
||||
%TM9,%TM9,New Timer
|
||||
%M0,%M0,One-shot
|
||||
%M1,%M1,One-shot
|
||||
%M2,%M2,One-shot
|
||||
%M3,%M3,One-shot
|
||||
%M4,%M4,One-shot
|
||||
%M5,%M5,One-shot
|
||||
%M6,%M6,One-shot
|
||||
%M7,%M7,One-shot
|
||||
%M8,%M8,One-shot
|
||||
%M9,%M9,One-shot
|
||||
%C0,%C0,Counter
|
||||
%C1,%C1,Counter
|
||||
%C2,%C2,Counter
|
||||
%C3,%C3,Counter
|
||||
%C4,%C4,Counter
|
||||
%C5,%C5,Counter
|
||||
%C6,%C6,Counter
|
||||
%C7,%C7,Counter
|
||||
%C8,%C8,Counter
|
||||
%C9,%C9,Counter
|
||||
%E0,%E0,Error Flag Bit
|
||||
%E1,%E1,Error Flag Bit
|
||||
%E2,%E2,Error Flag Bit
|
||||
%E3,%E3,Error Flag Bit
|
||||
%E4,%E4,Error Flag Bit
|
||||
%E5,%E5,Error Flag Bit
|
||||
%E6,%E6,Error Flag Bit
|
||||
%E7,%E7,Error Flag Bit
|
||||
%E8,%E8,Error Flag Bit
|
||||
%E9,%E9,Error Flag Bit
|
||||
_/FILE-symbols.csv
|
||||
_FILE-general.txt
|
||||
PERIODIC_REFRESH=1
|
||||
SIZE_NBR_RUNGS=100
|
||||
SIZE_NBR_BITS=20
|
||||
SIZE_NBR_WORDS=20
|
||||
SIZE_NBR_TIMERS=10
|
||||
SIZE_NBR_MONOSTABLES=10
|
||||
SIZE_NBR_COUNTERS=10
|
||||
SIZE_NBR_TIMERS_IEC=10
|
||||
SIZE_NBR_PHYS_INPUTS=15
|
||||
SIZE_NBR_PHYS_OUTPUTS=15
|
||||
SIZE_NBR_ARITHM_EXPR=100
|
||||
SIZE_NBR_SECTIONS=10
|
||||
SIZE_NBR_SYMBOLS=160
|
||||
_/FILE-general.txt
|
||||
_FILE-com_params.txt
|
||||
MODBUS_MASTER_SERIAL_PORT=
|
||||
MODBUS_MASTER_SERIAL_SPEED=9600
|
||||
MODBUS_MASTER_SERIAL_DATABITS=8
|
||||
MODBUS_MASTER_SERIAL_STOPBITS=1
|
||||
MODBUS_MASTER_SERIAL_PARITY=0
|
||||
MODBUS_ELEMENT_OFFSET=0
|
||||
MODBUS_MASTER_SERIAL_USE_RTS_TO_SEND=0
|
||||
MODBUS_MASTER_TIME_INTER_FRAME=100
|
||||
MODBUS_MASTER_TIME_OUT_RECEIPT=500
|
||||
MODBUS_MASTER_TIME_AFTER_TRANSMIT=0
|
||||
MODBUS_DEBUG_LEVEL=0
|
||||
MODBUS_MAP_COIL_READ=0
|
||||
MODBUS_MAP_COIL_WRITE=0
|
||||
MODBUS_MAP_INPUT=0
|
||||
MODBUS_MAP_HOLDING=0
|
||||
MODBUS_MAP_REGISTER_READ=0
|
||||
MODBUS_MAP_REGISTER_WRITE=0
|
||||
_/FILE-com_params.txt
|
||||
_FILE-rung_2.csv
|
||||
#VER=2.0
|
||||
#LABEL=
|
||||
#COMMENT=
|
||||
#PREVRUNG=1
|
||||
#NEXTRUNG=-1
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/5 , 9-0-0/5 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 99-0-0/0 , 99-0-0/0 , 60-0-0/8
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/6 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 99-0-0/0 , 99-0-0/0 , 60-0-0/9
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/7 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 99-0-0/0 , 99-0-0/0 , 60-0-0/11
|
||||
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/10
|
||||
99-0-0/0 , 99-0-0/0 , 20-0-0/10 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 9-0-0/0 , 50-0-60/3
|
||||
0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 0-0-0/0 , 99-1-0/0 , 99-0-0/0 , 60-0-0/0
|
||||
_/FILE-rung_2.csv
|
||||
_FILE-timers_iec.csv
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
1,0,0
|
||||
_/FILE-timers_iec.csv
|
||||
_/FILES_CLASSICLADDER
|
||||
9
my-emco/tool.tbl
Normal file
9
my-emco/tool.tbl
Normal file
@@ -0,0 +1,9 @@
|
||||
T1 P1 Z-8.28607 D12 ;12mm end mill, 4 flutes
|
||||
T2 P2 Z-13.3224 D6 ;6mm end mill alu, 3 flutes
|
||||
T3 P3 Z-18.0309 D2.5 ;2.5mm dubhole drill
|
||||
T4 P4 Z-4.83769 D1 ;1mm end mill
|
||||
T5 P5 Z-11.5912 D2 ;2mm end mill, 3 flutes
|
||||
T6 P6 Z0 D10 ;10mm end mill alu, 3 flutes
|
||||
T8 P8 Z0 D3 ;engraver
|
||||
T10 P10 Z0 D10 ;10 mm 4 flutes 20230820
|
||||
T7 P7 Z0 D4 ;4mm alu
|
||||
94
my-emco/watchdog.py
Normal file
94
my-emco/watchdog.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#! /usr/bin/python
|
||||
import time
|
||||
import threading
|
||||
import sys
|
||||
|
||||
class WatchDog():
|
||||
def __init__(self, timeout):
|
||||
self.timeout = timeout
|
||||
self.last_ping_time = time.time()
|
||||
|
||||
def ping(self):
|
||||
self.last_ping_time = time.time()
|
||||
|
||||
def check(self):
|
||||
if time.time() - self.last_ping_time > self.timeout:
|
||||
self.last_ping_time = time.time() #reset tick time
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def insideMargin(self):
|
||||
if time.time() - self.last_ping_time <= self.timeout:
|
||||
return True
|
||||
else:
|
||||
self.last_ping_time = time.time() #reset tick time
|
||||
return False
|
||||
|
||||
|
||||
class WatchDogDaemon(threading.Thread):
|
||||
def __init__(self, timeout, periodicity, enable = True):
|
||||
self.wd = WatchDog(timeout)
|
||||
self.periodicity = periodicity
|
||||
self.enabled = enable
|
||||
self._start()
|
||||
|
||||
def _start(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.daemon = True
|
||||
self.start()
|
||||
|
||||
def ping(self):
|
||||
self.wd.ping()
|
||||
|
||||
def run(self):
|
||||
print "Starting watchdog deamon..."
|
||||
while(self.enabled):
|
||||
time.sleep(self.periodicity)
|
||||
|
||||
if not self.wd.insideMargin():
|
||||
print "Watchdog outside margin"
|
||||
self.reset()
|
||||
|
||||
print "stopping watchdog deamon..."
|
||||
|
||||
def setEnabled(self, enabled):
|
||||
if self.enabled == False and enabled == True:
|
||||
self.enabled = True
|
||||
self.wd.ping() # reset tick time
|
||||
self._start()
|
||||
|
||||
if enabled == False:
|
||||
self.enabled = False
|
||||
|
||||
def reset(self):
|
||||
"""to be overriden by client"""
|
||||
pass
|
||||
|
||||
|
||||
def reset():
|
||||
print 'reset'
|
||||
|
||||
def main():
|
||||
i = 0
|
||||
wdd = WatchDogDaemon(2, 0.5, False)
|
||||
wdd.reset = reset
|
||||
try:
|
||||
while 1:
|
||||
time.sleep(1)
|
||||
print 'main_' + str(i)
|
||||
print wdd.is_alive()
|
||||
i = i+1
|
||||
|
||||
if i == 5 or i == 15:
|
||||
wdd.setEnabled(True)
|
||||
if i == 10:
|
||||
wdd.setEnabled(False)
|
||||
|
||||
wdd.ping()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
raise SystemExit
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user