summaryrefslogtreecommitdiff
path: root/configs/sim/axis/xhc-hb04/xhc-hb04.tcl
blob: a90b38e5d1e14d75b53b96997c6d29fd446dffdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# xhc-hb04.tcl: HALFILE for xhc-hb04 pendant

# Usage:
# In ini file, include:
#   [HAL]
#   HALFILE = existing halfiles
#   ...
#   HALFILE = xhc-hb04.tcl
#
#   [XHC-HB04_CONFIG]
#   layout = 2       (required: 1|2 are supported)
#   coords = x y z a (any unique four of xyzabcuvw)
#   coefs  = 1 1 1 1 (optional, filter coefs, 0 < coef < 1, not usually reqd)
#   scales = 1 1 1 1 (optional)
#   threadname = servo-thread (optional)
#   sequence = 1     (optional: 1|2)
#   jogmode = normal (optional: normal|vnormal|plus-minus)
#   require_pendant = yes (optional: yes|no)

#   [XHC-HB04_BUTTONS]
#   name = pin  (connect button to hal pin)
#   name = ""   (no connect button)
#   special cases:
#   start-pause = std_start_pause  (for usual behavior)
#   step = xhc-hb04.stepsize-up    (for usual behavior)
#   (see ini files for more exanples)

# Notes:
#    1) the 'start-pause' pin can be set to "std_start_pause" to
#       implement default behavior
#    2) the 'step' pin is normally connected to xhc-hb04.stepsize-up
#    3) non-root access to the usb device requires an additional
#       udev rule.  Typically, create /etc/udev/rules.d/90-xhc.rules:
#       SYSFS{idProduct}=="eb70", SYSFS{idVendor}=="10ce", MODE="666", OWNER="root", GROUP="users"
#       or (for ubuntu12 and up):
#       ATTR{idProduct}=="eb70",  ATTR{idVendor}=="10ce",  MODE="666", OWNER="root", GROUP="users"
#    4) For jogmode==vnormal (man motion -- see axis.N.jog-vel-mode),
#       the max movement is limited by the machine velocity and acceleration limits
#       such that delta_x = 0.5 * vmax**2/accelmx
#       so for sim example:
#       inch: vmax= 1.2   accelmax= 20  delta_x=0.036
#       mm:   vmax=30.48  acclemax=508  delta_x=0.9144
#       Typically:
#         (-s1) sequence 1 (1,10,100,1000) is ok for mm-based machines
#         (-s2) sequence 2 (1,5,10,20)     is ok for inch-based machines
#    4) jogmode==plus-minus implements halui plus-minus jogging which
#       seems to work in both joint and world modes
#       (tested on git master branch before integration of joints_axesN branch)
#
#    5) 19feb2014 notes for future work
#       jogging non-trivkins machines in world mode
#
#       jogmode==plus-minus-increment reserved for halui plus-minus-increment jogging
#       incremental, world-mode jogging is not working in current git master
#       (at this date, current git master has not merged a joint_axesN branch)
#
#       see:
#       http://www.linuxcnc.org/docs/html/man/man9/gantrykins.9.html
#       Joint-mode (aka Free mode) supports continuous and incremental jogging.
#       World-mode (aka Teleop mode) only supports continuous jogging.

#-----------------------------------------------------------------------
# Copyright: 2014
# Author:    Dewey Garrett <dgarrett@panix.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#-----------------------------------------------------------------------

proc is_uniq {list_name} {
  set tmp(xxxxxxxx) "" ;# make an array first
  foreach item $list_name {
    if {[array names tmp $item] == $item} {
      return 0 ;# not unique
    }
    set tmp($item) $item
  }
  return 1 ;# unique
} ;# is_uniq

proc pin_exists {name} {
  set line [lindex [split [show pin $name] \n] 2]
  if {"$line" == ""} {
    return 0 ;# fail
  }
  if [catch {scan $line "%d %s %s %s%s" owner type dir value pinname} msg] {
     return 0 ;# fail
  } else {
     #puts stderr "OK:$owner $type $dir $value $pinname"
     return 1 ;# ok
  }
} ;# pin_exists

proc connect_pins {} {
  foreach bname [lsort [array names ::XHC_HB04_BUTTONS]] {
    set thepin $::XHC_HB04_BUTTONS($bname)
    set thepin [lindex $thepin 0]

    if {"$thepin" == "\"\""} {
      #puts stderr "$::progname: no pin defined for <$bname>"
      continue
    }
    # this pin is can specify std behavior
    if {   ([string tolower $bname] == "start-pause")
        && ([string tolower $thepin] == "std_start_pause")
       } {
      std_start_pause_button
      puts stderr "$::progname: using std_start_pause_button"
      continue
    }
    # these are warnings in the ini file examples but aren't real pins
    if {[string tolower "$thepin"] == "caution"} {
      puts stderr "$::progname: skipping button $bname marked <$thepin>"
      continue
    }
    set fullbname xhc-hb04.button-$bname
    if ![pin_exists $fullbname] {
      puts stderr "$::progname: !!! <$fullbname> pin does not exist, continuing"
      continue
    }
    if ![pin_exists $thepin] {
      puts stderr "$::progname: !!! <$thepin> target pin does not exist, continuing"
      continue
    }

    net pendant:$bname $fullbname => $thepin
  }
} ;# connect_pins

proc wheel_setup {jogmode} {
  # defaults if not in inifile:
  set ::XHC_HB04_CONFIG(coef,0) 1.0
  set ::XHC_HB04_CONFIG(coef,1) 1.0
  set ::XHC_HB04_CONFIG(coef,2) 1.0
  set ::XHC_HB04_CONFIG(coef,3) 1.0
  if [info exists ::XHC_HB04_CONFIG(coefs)] {
    set idx 0
    foreach g $::XHC_HB04_CONFIG(coefs) {
      set g1 $g
      if {$g < 0} {
         set g [expr -1 * $g]
         puts stderr "$::progname: coef #$idx must be positive was:$g1, is:$g"
      }
      if {$g > 1} {
         set g .5
         puts stderr "$::progname: coef #$idx must < 1 coef was:$g1, is:$g"
      }
      set ::XHC_HB04_CONFIG(coef,$idx) $g
      incr idx
    }
  }
  # defaults if not in inifile:
  set ::XHC_HB04_CONFIG(scale,0) 1.0
  set ::XHC_HB04_CONFIG(scale,1) 1.0
  set ::XHC_HB04_CONFIG(scale,2) 1.0
  set ::XHC_HB04_CONFIG(scale,3) 1.0
  if [info exists ::XHC_HB04_CONFIG(scales)] {
    set idx 0
    foreach g $::XHC_HB04_CONFIG(scales) {
      set ::XHC_HB04_CONFIG(scale,$idx) $g
      incr idx
    }
  }

  net pendant:jog-scale      <= xhc-hb04.jog.scale
  net pendant:jog-counts     <= xhc-hb04.jog.counts
  net pendant:jog-counts-neg <= xhc-hb04.jog.counts-neg

  set anames {x y z a}
  # xhc-hb04.cc hardcodes pin names as: x y z a
  # herein: Use names in order of the [XHC_HB04_CONFIG]coords
  #         specification in the inifile.
  #         These pin names will be a little confusing when
  #         using alternate axis sequences but the signal
  #         names will align correctly.
  #         With this method, any coord (xyzabcuvw) can be
  #         controlled by the wheel (providing it exists)
  #
  set idx 0
  foreach coord $::XHC_HB04_CONFIG(coords) {
    set axno $::XHC_HB04_CONFIG($coord,axno)

    setp pendant_util.coef$idx  $::XHC_HB04_CONFIG(coef,$idx)
    setp pendant_util.scale$idx $::XHC_HB04_CONFIG(scale,$idx)

    set acoord [lindex $anames $idx]
    net pendant:pos-$coord    halui.axis.$axno.pos-feedback \
                           => xhc-hb04.$acoord.pos-absolute
    net pendant:pos-rel-$coord    halui.axis.$axno.pos-relative \
                               => xhc-hb04.$acoord.pos-relative

    net pendant:jog-scale => axis.$axno.jog-scale

    net pendant:jog-counts                 => pendant_util.in$idx
    net pendant:jog-counts-$coord-filtered <= pendant_util.out$idx \
                                           => axis.$axno.jog-counts

    switch $jogmode {
      normal - vnormal {
        net pendant:jog-$coord    xhc-hb04.jog.enable-$acoord \
                               => axis.$axno.jog-enable
      }
      plus-minus {
        # connect halui plus,minus pins
        net pendant:jog-plus-$coord     xhc-hb04.jog.plus-$acoord  \
                                     => halui.jog.$axno.plus
        net pendant:jog-minus-$coord    xhc-hb04.jog.minus-$acoord \
                                     => halui.jog.$axno.minus
      }
    }
    switch $jogmode {
      vnormal {
        setp axis.$axno.jog-vel-mode 1
      }
    }

    incr idx
  }

  switch $jogmode {
    normal - vnormal {
      net pendant:jog-speed <= halui.max-velocity.value
      # not used: xhc-hb04.jog.velocity
      # not used: xhc-hb04.jog.max-velocity
    }
    plus-minus {
      # Note: the xhc-hb04 driver manages xhc-hb04.jog.velocity
      net pendant:jog-max-velocity <= halui.max-velocity.value
      net pendant:jog-max-velocity => xhc-hb04.jog.max-velocity
      net pendant:jog-speed        <= xhc-hb04.jog.velocity
      net pendant:jog-speed        => halui.jog-speed
    }
  }

  setp halui.feed-override.scale 0.01
  net pendant:jog-counts  => halui.feed-override.counts

  setp halui.spindle-override.scale 0.01
  net pendant:jog-counts  => halui.spindle-override.counts


  net pendant:jog-feed      halui.feed-override.count-enable \
                         <= xhc-hb04.jog.enable-feed-override
  net pendant:jog-feed2     halui.feed-override.value \
                         => xhc-hb04.feed-override

  net pendant:jog-spindle   halui.spindle-override.count-enable
  net pendant:jog-spindle   <= xhc-hb04.jog.enable-spindle-override
  net pendant:jog-spindle2  halui.spindle-override.value \
                         => xhc-hb04.spindle-override
  net pendant:spindle-rps   motion.spindle-speed-cmd-rps \
                         => xhc-hb04.spindle-rps
} ;# wheel_setup

proc std_start_pause_button {} {
  # hardcoded setup for button-start-pause
  net    pendant:start-or-pause <= xhc-hb04.button-start-pause \
                                => pendant_util.start-or-pause

  net    pendant:is-idle    <= halui.program.is-idle \
                            => pendant_util.is-idle
  net    pendant:is-paused  <= halui.program.is-paused \
                            => pendant_util.is-paused
  net    pendant:is-running <= halui.program.is-running \
                            => pendant_util.is-running

  net    pendant:program-resume pendant_util.resume => halui.program.resume
  net    pendant:program-pause  pendant_util.pause => halui.program.pause
  net    pendant:program-run    pendant_util.run => halui.program.run
  net    pendant:program-run                     => halui.mode.auto
} ;# std_start_pause_button

proc popup_msg {msg} {
  puts stderr "$msg"
  if [catch {package require Tk
             wm withdraw .
             tk_messageBox \
                 -title "$::progname: loadusr" \
                 -type ok \
                 -message "$msg"
             destroy .
            } msg] {
     puts stderr "$msg"
  }
} ;# popup_msg

proc err_exit {msg} {
  puts stderr "\n$::progname: $msg\n"
  exit 1
} ;# err_exit

# begin------------------------------------------------------------------------
set ::progname "xhc-hb04.tcl"
set cfg xhc-hb04-layout2.cfg ;# default

foreach name [array names ::XHC_HB04_CONFIG] {
  set ::XHC_HB04_CONFIG($name) [string trim $::XHC_HB04_CONFIG($name) "{}"]
}

if [info exists ::XHC_HB04_CONFIG(layout)] {
  switch ${::XHC_HB04_CONFIG(layout)} {
    1 {set cfg xhc-hb04-layout1.cfg}
    2 {set cfg xhc-hb04-layout2.cfg}
    default {
      set msg "Unknown layout:<$::XHC_HB04_CONFIG(layout)>"
      set msg "$msg\ntrying: $cfg"
      popup_msg "$msg"
      # keep going
    }
  }
}

if ![file exists $cfg] {
  set msg "Cannot find file: <$cfg>\nCannot configure pendant\n"
  set msg "$msg\nContinuing without xhc-hb04"
  popup_msg "$msg"
  return ;# not an exit
}

# require_pendant==yes: use -x, dont create pins unless connected
# require_pendant==no:          create pins if not connected
if ![info exists ::XHC_HB04_CONFIG(require_pendant)] {
  set ::XHC_HB04_CONFIG(require_pendant) yes ;# default
}
set dashx -x
switch $::XHC_HB04_CONFIG(require_pendant) {
  no      {set dashx ""}
}

if [info exists ::XHC_HB04_CONFIG(sequence)] {
  set dashs "-s $::XHC_HB04_CONFIG(sequence)"
} else {
  set dashs ""
}

set cmd "loadusr -W xhc-hb04 $dashx $dashs -I $cfg -H"
if [catch {eval $cmd} msg] {
  set msg "\n$::progname: loadusr xhc-hb04:\n<$msg>\n\n"
  set msg "$msg Is it plugged in?\n\n"
  set msg "$msg Are permissions correct?\n\n"
  set msg "$msg Continuing without xhc-hb04\n"
  set msg "$msg \nFailing cmd:\n$cmd"
  popup_msg "$msg"
  return ;# not an exit
}

# jogmodes:
#   normal: use motion pins:
#               axis.N.jog-counts
#               axis.N.jog-enable
#               axis.N.jog-scale  (machine units per count)

#   plus-minus: use halui pins:
#               halui.jog.N.plus  (jog in + dir at jog-speed)
#               halui.jog.N.minus (jog in - dir at jog-speed)
#               halui.jog-speed   (applies to plus-minus jogging only)
#
if ![info exists ::XHC_HB04_CONFIG(jogmode)] {
  set ::XHC_HB04_CONFIG(jogmode) normal ;# default
}

set jogmode $::XHC_HB04_CONFIG(jogmode)
switch $jogmode {
  normal {}
  vnormal {}
  plus-minus {}
  default {
    set ::XHC_HB04_CONFIG(jogmode) normal
    set msg "Unkknown jogmode <$jogmode>"
    set msg "$msg  Using $::XHC_HB04_CONFIG(jogmode)"
    popup_msg "$msg"
  }
}

set ct 0; foreach coord {x y z a b c u v w} {
  set ::XHC_HB04_CONFIG($coord,axno) $ct;  incr ct
}

if [info exists ::XHC_HB04_CONFIG(coords)] {
  if ![is_uniq $::XHC_HB04_CONFIG(coords)] {
    err_exit "coords must be unique, not: <$::XHC_HB04_CONFIG(coords)>"
  }
} else {
  set ::XHC_HB04_CONFIG(coords) {x y z a} ;# default
}

if ![info exists ::XHC_HB04_CONFIG(threadname)] {
  set ::XHC_HB04_CONFIG(threadname) "servo-thread" ;# default
}
loadrt xhc_hb04_util names=pendant_util
addf   pendant_util $::XHC_HB04_CONFIG(threadname)

connect_pins    ;# per ini file items: [XHC_HB04_BUTTONS]buttonname=pin
wheel_setup  $::XHC_HB04_CONFIG(jogmode)
                 # jog wheel per ini file items:
                 #     [XHC_HB04_CONFIG]coords,coefs,scales
#parray ::XHC_HB04_CONFIG