summaryrefslogtreecommitdiff
path: root/configs/sim/axis/simtcl/twopass_demo.tcl
blob: c841165f2ad8ebb345f29080f47c4298a47a3611 (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
# twopass_demo: demo using tcl configuration file for hal

# (derived from core_sim.hal,axis_manualtoolchange.hal,simlated_home.hal)
#    test use of both
#        "loadrt module names=" format  (ddt,or2,scale)
#    and
#        "loadrt module count=" format  (hypot,comp,flipflop)
#    test alias command
#    test loadrt usage in pass1 (second pass)
#    all addf calls are organized in one place
#    convention herein: signal names (net) begin with a capital letter

proc axis_manualtoolchange {} {
  loadusr -W hal_manualtoolchange

  unlinkp tchange     ;# in case already linked
  unlinkp tchanged    ;# in case already linked

  net Tool-change      hal_manualtoolchange.change  tchange
  net Tool-changed     hal_manualtoolchange.changed tchanged
  net Tool-prep-number hal_manualtoolchange.number  tprep_no
} ;# axis_manualtoolchange

proc simulated_home {axes} {
  foreach A $axes {
    loadrt comp names=${A}_comp
    net ${A}_homeswpos => ${A}_comp.in0
    switch $A {
      X {sets ${A}_homeswpos 1.0}
      Y {sets ${A}_homeswpos 0.5}
      Z {sets ${A}_homeswpos 2.0}
    }
    net  ${A}_pos => ${A}_comp.in1
    setp ${A}_comp.hyst .02
    net  ${A}_homesw <= ${A}_comp.out
  }

  net Y_homesw => yhome_sw_in

  loadrt or2  names=or2a
  net X_homesw => or2a.in0
  net Z_homesw => or2a.in1
  net XZ_homesw or2a.out => xhome_sw_in zhome_sw_in
} ;# simulated_home

proc make_ddts {axes} {
  loadrt hypot names=hyp_xy,hyp_xyz

  foreach A $axes {
    set al [string tolower $A]
    loadrt ddt names=${A}_vel,${A}_accel
    net ${A}_pos ${al}pos_cmd => ${al}pos_fb ${A}_vel.in

    net ${A}_vel ${A}_vel.out => ${A}_accel.in
    net ${A}_acc <= ${A}_accel.out
    switch $A {
      X {net ${A}_vel => hyp_xy.in0}
      Y {net ${A}_vel => hyp_xy.in1}
      Z {net ${A}_vel => hyp_xyz.in0
         net XY_vel   => hyp_xy.out => hyp_xyz.in1
         net XYZ_vel  <= hyp_xyz.out
        }
    }
  }
} ;# make_ddts

proc core_sim {} {
  loadrt trivkins

  loadrt $::EMCMOT(EMCMOT) \
         base_period_nsec=$::EMCMOT(BASE_PERIOD) \
         servo_period_nsec=$::EMCMOT(SERVO_PERIOD) \
         num_joints=$::TRAJ(AXES)

  alias pin iocontrol.0.tool-change      tchange
  alias pin iocontrol.0.tool-changed     tchanged
  alias pin iocontrol.0.tool-prepare     tprepare
  alias pin iocontrol.0.tool-prepared    tprepared
  alias pin iocontrol.0.user-enable-out  enable_out
  alias pin iocontrol.0.emc-enable-in    enable_in
  alias pin iocontrol.0.tool-prep-number tprep_no

  alias pin axis.0.motor-pos-cmd  xpos_cmd
  alias pin axis.0.motor-pos-fb   xpos_fb
  alias pin axis.1.motor-pos-cmd  ypos_cmd
  alias pin axis.1.motor-pos-fb   ypos_fb
  alias pin axis.2.motor-pos-cmd  zpos_cmd
  alias pin axis.2.motor-pos-fb   zpos_fb

  alias pin axis.0.home-sw-in xhome_sw_in
  alias pin axis.1.home-sw-in yhome_sw_in
  alias pin axis.2.home-sw-in zhome_sw_in

  net Estop-loop enable_out => enable_in

  net Tool-prep-loop tprepare tprepared
  net Tool-change-loop tchange tchanged
} ;# core_sim

# note: ini items ::SECTION(ITEM) are a list for each
#       line item (even one) so use eval set $::SECTION(ITEM)
eval set axes $::TRAJ(COORDINATES)
core_sim
make_ddts $axes
axis_manualtoolchange
simulated_home $axes

# addf calls are done in second pass, arrange sequence here:
foreach A $axes {
  addf ${A}_comp servo-thread
  addf ${A}_vel servo-thread
  addf ${A}_accel servo-thread
}
addf or2a servo-thread
addf hyp_xy  servo-thread
addf hyp_xyz servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread

#-----------------------------------------------------------------------
# below: tests
# test: use of loadrt count=...
loadrt not count=2
loadrt not count=3

# test: loading on second pass for components that don't exist should work
#       not sure why you would want to though
if [::tp::passnumber] {
  loadrt scale    names=scalea,scaleb
  loadrt flipflop count=1
}

# test: ::tp::no_puts
if [::tp::passnumber] {
  puts "[file tail $::argv0]:\
        The tcl \"puts\" command is enabled here in pass[::tp::passnumber]"
} else {
  ::tp::no_puts
    # this should not print:
    puts "[file tail $::argv0]:\
        The tcl \"puts\" command is disabled here in pass[::tp::passnumber]"
  ::tp::restore_puts
}