Re: TCL/TK XEMC
Posted by
Fred Proctor
on 1999-09-28 08:18:03 UTC
Dave (daveland@...) wrote regarding Tcl/Tk GUIs:
mind for conversational programming.
You suggested:
code is split into two parts: Tcl/Tk script code (tkemc.tcl) that
manages presentation of the controller data and interaction with the
user, and a C++ interface to the EMC (autoemc.cc). You can muck with the
GUI without recompiling anything, presuming that autoemc.cc contains
definitions of all the Tcl words you need. These are emc_estop {on,
off}, emc_mode {manual, auto, mdi}, etc. I intend to complete autoemc.cc
so that there is a Tcl word for every command supported by the EMC and
every element of status data.
The advantage of this is noted by your suggestion:
Messaging Language (NML). This is just what autoemc.cc adds. NML
supports run-time selection of which protocol you want to use to connect
to the EMC. This is specified in the emc.nml file. By default it's
shared memory, which is fast but requires that the GUI and EMC be on the
same machine. NML also supports efficient conversion between byte
formats of Wintel and Unix machines automatically, and a bunch of other
features that we don't need but are being used, for example, by a
project that is networking a bunch of autonomous Humvees running VxWorks
on VME boards through radio ethernet.
You can easily separate the EMC and its GUI by doing this:
1. Edit emc.nml so that you specify the actual machine name for the
top-level EMC buffers. By default the machine is "localhost"; you'd put
the actual hostname, e.g., mymachine, or mymachine.mydomain.com, e.g.,
# Top-level buffers to EMC
B emcCommand SHMEM mymachine 8192 0 0 1 12 1001 TCP=5005 xdr
B emcStatus SHMEM mymachine 8192 0 0 2 12 1002 TCP=5005 xdr
B emcError SHMEM mymachine 8192 0 0 3 12 1003 TCP=5005 xdr queue
2. Edit emc.nml again so that the xemc process connects to these buffers
does it remotely, by changing LOCAL to REMOTE, e.g.,
P xemc emcCommand REMOTE localhost W 0 10.0 0 10
P xemc emcStatus REMOTE localhost R 0 10.0 0 10
P xemc emcError REMOTE localhost R 0 10.0 0 10
P xemc toolCmd REMOTE localhost W 0 10.0 0 10
P xemc toolSts REMOTE localhost R 0 10.0 0 10
3. Run a proxy server to handle the TCP/IP requests and do the actual
reads/writes of the EMC buffers. The proxy server is
/usr/local/nist/emc/plat/linux_2_0_36/bin/emcsvr. You can put this in
your script, just before the xemc runs, e.g.,
plat/linux_2_0_36/bin/emcsvr -nml <your .nml file, probably emc.nml> &
Note that there is a newer simpler version of the NML file format, so
these instructions will change somewhat. I'll also put the running of
the emcsvr proxy server in the .run script as an option, with some
corresponding INI file variables, like I did for the other processes.
There is no need to do this, unless you want to. It is intended to allow
you to run a GUI on a Windows machine in your office to monitor the
controller while it executes on the filthy noisy shop floor.
And, you volunteered:
can do this independently, I believe. The idea is that a Tcl/Tk script
would be executed in another window, and guide the user through either a
simple form fill-in or a graphical construction of the machining
operation, like pocket milling. Clicking the "Generate" button on the
bottom would either create a file with the G codes, or pop up a text
widget with the code inside, or something like that. The user could run
that code, paste in at the end of a program, or something else. Here's a
simple concept that you can run with "wish pocket.tcl", or, if you make
it executable, with just "./pocket.tcl":
-----pocket.tcl-----
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# This writes directly into the main toplevel widget. A real script
would
# create its own and pop it up with "toplevel".
label .msg -wraplength 4i -justify left -text "This script generates NC
code for rectangular pocket milling. Enter the coordinates of two
opposing corners and the stepover distance."
pack .msg -side top
# globals that hold contents of entry widgets
set xi 0
set yi 0
set xf 1
set yf 2
set sd 0.5
proc generate {} {
global xi yi xf yf sd
set up 0
for {set i $xi} {$i <= $xf} {set i [expr $i+$sd]} {
if {$up == 1} {
puts stdout "X$i Y$yf"
puts stdout "X$i Y$yi"
set up 0
} else {
puts stdout "X$i Y$yi"
puts stdout "X$i Y$yf"
set up 1
}
}
}
frame .buttons
pack .buttons -side bottom -fill x -pady 2m
button .buttons.generate -text "Generate" -command "generate"
button .buttons.cancel -text "Cancel" -command "destroy ."
pack .buttons.generate .buttons.cancel -side left -expand 1
foreach i {f1 f2 f3 f4 f5} {
frame .$i -bd 2
entry .$i.entry -relief sunken -width 40
label .$i.label
pack .$i.entry -side right
pack .$i.label -side left
}
.f1.label config -text "Starting X:"
.f1.entry config -textvariable xi
.f2.label config -text "Starting Y:"
.f2.entry config -textvariable yi
.f3.label config -text "Ending X:"
.f3.entry config -textvariable xf
.f4.label config -text "Ending Y:"
.f4.entry config -textvariable yf
.f5.label config -text "Stepover distance:"
.f5.entry config -textvariable sd
pack .msg .f1 .f2 .f3 .f4 .f5 -side top -fill x
bind . <Return> "destroy ."
focus .f1.entry
--------------------
Comments?
--Fred
> A few months ago I posted my own TCL/TK GUI for CNC that I wasThis is pretty cool, especially the part viewer. This is what I had in
> writing. IT is on my web page at:
>
> http://users.nni.com/daveland/metal.htm
mind for conversational programming.
You suggested:
> 1) Write the interface in interpreted TCL/TK NOT in "C" withThis is what I did. The C code only adds EMC command support to Tk. The
> TCL/TK embeded . This allows more users to mucK with it more
> easily since no compling is needed.
code is split into two parts: Tcl/Tk script code (tkemc.tcl) that
manages presentation of the controller data and interaction with the
user, and a C++ interface to the EMC (autoemc.cc). You can muck with the
GUI without recompiling anything, presuming that autoemc.cc contains
definitions of all the Tcl words you need. These are emc_estop {on,
off}, emc_mode {manual, auto, mdi}, etc. I intend to complete autoemc.cc
so that there is a Tcl word for every command supported by the EMC and
every element of status data.
The advantage of this is noted by your suggestion:
> 2) Develope a "socket" interface to emcmot so that the TCL/TKWe do have a socket interface to EMC, accomplished via the Neutral
> GUI comunicates to the motors/interpreter via a network socket.
> Data rate here is low, so it is very easy and portable. The
> side benefit is that the GUI can run on any machine ( or more
> than one at the same time) on a network. The motor control
> then runs on a box that need not run X!!!
Messaging Language (NML). This is just what autoemc.cc adds. NML
supports run-time selection of which protocol you want to use to connect
to the EMC. This is specified in the emc.nml file. By default it's
shared memory, which is fast but requires that the GUI and EMC be on the
same machine. NML also supports efficient conversion between byte
formats of Wintel and Unix machines automatically, and a bunch of other
features that we don't need but are being used, for example, by a
project that is networking a bunch of autonomous Humvees running VxWorks
on VME boards through radio ethernet.
You can easily separate the EMC and its GUI by doing this:
1. Edit emc.nml so that you specify the actual machine name for the
top-level EMC buffers. By default the machine is "localhost"; you'd put
the actual hostname, e.g., mymachine, or mymachine.mydomain.com, e.g.,
# Top-level buffers to EMC
B emcCommand SHMEM mymachine 8192 0 0 1 12 1001 TCP=5005 xdr
B emcStatus SHMEM mymachine 8192 0 0 2 12 1002 TCP=5005 xdr
B emcError SHMEM mymachine 8192 0 0 3 12 1003 TCP=5005 xdr queue
2. Edit emc.nml again so that the xemc process connects to these buffers
does it remotely, by changing LOCAL to REMOTE, e.g.,
P xemc emcCommand REMOTE localhost W 0 10.0 0 10
P xemc emcStatus REMOTE localhost R 0 10.0 0 10
P xemc emcError REMOTE localhost R 0 10.0 0 10
P xemc toolCmd REMOTE localhost W 0 10.0 0 10
P xemc toolSts REMOTE localhost R 0 10.0 0 10
3. Run a proxy server to handle the TCP/IP requests and do the actual
reads/writes of the EMC buffers. The proxy server is
/usr/local/nist/emc/plat/linux_2_0_36/bin/emcsvr. You can put this in
your script, just before the xemc runs, e.g.,
plat/linux_2_0_36/bin/emcsvr -nml <your .nml file, probably emc.nml> &
Note that there is a newer simpler version of the NML file format, so
these instructions will change somewhat. I'll also put the running of
the emcsvr proxy server in the .run script as an option, with some
corresponding INI file variables, like I did for the other processes.
There is no need to do this, unless you want to. It is intended to allow
you to run a GUI on a Windows machine in your office to monitor the
controller while it executes on the filthy noisy shop floor.
And, you volunteered:
> I would be interested in contributing code... What do you need?Conversational scripts that can be invoked from a menu in the TkEMC. You
can do this independently, I believe. The idea is that a Tcl/Tk script
would be executed in another window, and guide the user through either a
simple form fill-in or a graphical construction of the machining
operation, like pocket milling. Clicking the "Generate" button on the
bottom would either create a file with the G codes, or pop up a text
widget with the code inside, or something like that. The user could run
that code, paste in at the end of a program, or something else. Here's a
simple concept that you can run with "wish pocket.tcl", or, if you make
it executable, with just "./pocket.tcl":
-----pocket.tcl-----
#!/bin/sh
# the next line restarts using wish \
exec wish "$0" "$@"
# This writes directly into the main toplevel widget. A real script
would
# create its own and pop it up with "toplevel".
label .msg -wraplength 4i -justify left -text "This script generates NC
code for rectangular pocket milling. Enter the coordinates of two
opposing corners and the stepover distance."
pack .msg -side top
# globals that hold contents of entry widgets
set xi 0
set yi 0
set xf 1
set yf 2
set sd 0.5
proc generate {} {
global xi yi xf yf sd
set up 0
for {set i $xi} {$i <= $xf} {set i [expr $i+$sd]} {
if {$up == 1} {
puts stdout "X$i Y$yf"
puts stdout "X$i Y$yi"
set up 0
} else {
puts stdout "X$i Y$yi"
puts stdout "X$i Y$yf"
set up 1
}
}
}
frame .buttons
pack .buttons -side bottom -fill x -pady 2m
button .buttons.generate -text "Generate" -command "generate"
button .buttons.cancel -text "Cancel" -command "destroy ."
pack .buttons.generate .buttons.cancel -side left -expand 1
foreach i {f1 f2 f3 f4 f5} {
frame .$i -bd 2
entry .$i.entry -relief sunken -width 40
label .$i.label
pack .$i.entry -side right
pack .$i.label -side left
}
.f1.label config -text "Starting X:"
.f1.entry config -textvariable xi
.f2.label config -text "Starting Y:"
.f2.entry config -textvariable yi
.f3.label config -text "Ending X:"
.f3.entry config -textvariable xf
.f4.label config -text "Ending Y:"
.f4.entry config -textvariable yf
.f5.label config -text "Stepover distance:"
.f5.entry config -textvariable sd
pack .msg .f1 .f2 .f3 .f4 .f5 -side top -fill x
bind . <Return> "destroy ."
focus .f1.entry
--------------------
Comments?
--Fred
Discussion Thread
daveland@x...
1999-09-28 06:24:01 UTC
TCL/TK XEMC
Fred Proctor
1999-09-28 08:18:03 UTC
Re: TCL/TK XEMC